]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
phy: qcom: edp: Add PHY-specific LDO config for eDP low vdiff
authorYongxing Mou <yongxing.mou@oss.qualcomm.com>
Mon, 27 Apr 2026 06:35:23 +0000 (14:35 +0800)
committerVinod Koul <vkoul@kernel.org>
Sun, 3 May 2026 17:04:48 +0000 (22:34 +0530)
For eDP low vdiff, the LDO setting depends on the PHY version rather
than being a simple 0x0 or 0x1 value. Introduce a PHY callback to program
the correct LDO setting according to the HPG.

Since SC7280/SC8180X uses different LDO settings from SA8775P/SC8280XP,
introduce qcom_edp_phy_ops_v3 to keep the LDO setting correct.

Cc: stable@vger.kernel.org
Fixes: f199223cb490 ("phy: qcom: Introduce new eDP PHY driver")
Signed-off-by: Yongxing Mou <yongxing.mou@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Tested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> # SC8280XP X13s
Link: https://patch.msgid.link/20260427-edp_phy-v5-5-3bb876824475@oss.qualcomm.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/qualcomm/phy-qcom-edp.c

index 3a848f18a8d6083157db8d54482232872e03e7c2..a3c893f72908f4c7a8a8e103e5ab80d29876f74e 100644 (file)
@@ -81,6 +81,7 @@ struct phy_ver_ops {
        int (*com_clk_fwd_cfg)(const struct qcom_edp *edp);
        int (*com_configure_pll)(const struct qcom_edp *edp);
        int (*com_configure_ssc)(const struct qcom_edp *edp);
+       int (*com_ldo_config)(const struct qcom_edp *edp);
 };
 
 struct qcom_edp_phy_cfg {
@@ -352,7 +353,7 @@ static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configur
        const struct qcom_edp_swing_pre_emph_cfg *cfg;
        unsigned int v_level = 0;
        unsigned int p_level = 0;
-       u8 ldo_config;
+       int ret;
        u8 swing;
        u8 emph;
        int i;
@@ -378,13 +379,13 @@ static int qcom_edp_set_voltages(struct qcom_edp *edp, const struct phy_configur
        if (swing == 0xff || emph == 0xff)
                return -EINVAL;
 
-       ldo_config = edp->is_edp ? 0x0 : 0x1;
+       ret = edp->cfg->ver_ops->com_ldo_config(edp);
+       if (ret)
+               return ret;
 
-       writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
        writel(swing, edp->tx0 + TXn_TX_DRV_LVL);
        writel(emph, edp->tx0 + TXn_TX_EMP_POST1_LVL);
 
-       writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
        writel(swing, edp->tx1 + TXn_TX_DRV_LVL);
        writel(emph, edp->tx1 + TXn_TX_EMP_POST1_LVL);
 
@@ -608,6 +609,52 @@ static int qcom_edp_com_configure_pll_v4(const struct qcom_edp *edp)
        return 0;
 }
 
+static int qcom_edp_ldo_config_v3(const struct qcom_edp *edp)
+{
+       const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+       u32 ldo_config;
+
+       if (!edp->is_edp)
+               ldo_config = 0x0;
+       else if (dp_opts->link_rate <= 2700)
+               ldo_config = 0x81;
+       else
+               ldo_config = 0x41;
+
+       writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
+       writel(dp_opts->lanes > 2 ? ldo_config : 0x00, edp->tx1 + TXn_LDO_CONFIG);
+
+       return 0;
+}
+
+static int qcom_edp_ldo_config_v4(const struct qcom_edp *edp)
+{
+       const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+       u32 ldo_config;
+
+       if (!edp->is_edp)
+               ldo_config = 0x0;
+       else if (dp_opts->link_rate <= 2700)
+               ldo_config = 0xc1;
+       else
+               ldo_config = 0x81;
+
+       writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
+       writel(dp_opts->lanes > 2 ? ldo_config : 0x00, edp->tx1 + TXn_LDO_CONFIG);
+
+       return 0;
+}
+
+static const struct phy_ver_ops qcom_edp_phy_ops_v3 = {
+       .com_power_on           = qcom_edp_phy_power_on_v4,
+       .com_resetsm_cntrl      = qcom_edp_phy_com_resetsm_cntrl_v4,
+       .com_bias_en_clkbuflr   = qcom_edp_com_bias_en_clkbuflr_v4,
+       .com_clk_fwd_cfg        = qcom_edp_com_clk_fwd_cfg_v4,
+       .com_configure_pll      = qcom_edp_com_configure_pll_v4,
+       .com_configure_ssc      = qcom_edp_com_configure_ssc_v4,
+       .com_ldo_config         = qcom_edp_ldo_config_v3,
+};
+
 static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
        .com_power_on           = qcom_edp_phy_power_on_v4,
        .com_resetsm_cntrl      = qcom_edp_phy_com_resetsm_cntrl_v4,
@@ -615,6 +662,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = {
        .com_clk_fwd_cfg        = qcom_edp_com_clk_fwd_cfg_v4,
        .com_configure_pll      = qcom_edp_com_configure_pll_v4,
        .com_configure_ssc      = qcom_edp_com_configure_ssc_v4,
+       .com_ldo_config         = qcom_edp_ldo_config_v4,
 };
 
 static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = {
@@ -631,7 +679,7 @@ static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = {
        .vco_div_cfg = edp_phy_vco_div_cfg_v4,
        .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg,
        .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v3,
-       .ver_ops = &qcom_edp_phy_ops_v4,
+       .ver_ops = &qcom_edp_phy_ops_v3,
 };
 
 static const struct qcom_edp_phy_cfg sc8180x_dp_phy_cfg = {
@@ -639,7 +687,7 @@ static const struct qcom_edp_phy_cfg sc8180x_dp_phy_cfg = {
        .vco_div_cfg = edp_phy_vco_div_cfg_v4,
        .dp_swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg_v2,
        .edp_swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v2,
-       .ver_ops = &qcom_edp_phy_ops_v4,
+       .ver_ops = &qcom_edp_phy_ops_v3,
 };
 
 static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = {
@@ -824,6 +872,24 @@ static int qcom_edp_com_configure_pll_v6(const struct qcom_edp *edp)
        return 0;
 }
 
+static int qcom_edp_ldo_config_v6(const struct qcom_edp *edp)
+{
+       const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts;
+       u32 ldo_config;
+
+       if (!edp->is_edp)
+               ldo_config = 0x0;
+       else if (dp_opts->link_rate <= 2700)
+               ldo_config = 0x51;
+       else
+               ldo_config = 0x91;
+
+       writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
+       writel(dp_opts->lanes > 2 ? ldo_config : 0x00, edp->tx1 + TXn_LDO_CONFIG);
+
+       return 0;
+}
+
 static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
        .com_power_on           = qcom_edp_phy_power_on_v6,
        .com_resetsm_cntrl      = qcom_edp_phy_com_resetsm_cntrl_v6,
@@ -831,6 +897,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = {
        .com_clk_fwd_cfg        = qcom_edp_com_clk_fwd_cfg_v4,
        .com_configure_pll      = qcom_edp_com_configure_pll_v6,
        .com_configure_ssc      = qcom_edp_com_configure_ssc_v6,
+       .com_ldo_config         = qcom_edp_ldo_config_v6,
 };
 
 static struct qcom_edp_phy_cfg x1e80100_phy_cfg = {
@@ -1011,6 +1078,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v8 = {
        .com_clk_fwd_cfg        = qcom_edp_com_clk_fwd_cfg_v8,
        .com_configure_pll      = qcom_edp_com_configure_pll_v8,
        .com_configure_ssc      = qcom_edp_com_configure_ssc_v8,
+       .com_ldo_config         = qcom_edp_ldo_config_v6,
 };
 
 static struct qcom_edp_phy_cfg glymur_phy_cfg = {
@@ -1026,7 +1094,6 @@ static int qcom_edp_phy_power_on(struct phy *phy)
        const struct qcom_edp *edp = phy_get_drvdata(phy);
        u32 bias0_en, drvr0_en, bias1_en, drvr1_en;
        unsigned long pixel_freq;
-       u8 ldo_config = 0x0;
        int ret;
        u32 val;
        u8 cfg1;
@@ -1035,11 +1102,10 @@ static int qcom_edp_phy_power_on(struct phy *phy)
        if (ret)
                return ret;
 
-       if (edp->cfg->edp_swing_pre_emph_cfg && !edp->is_edp)
-               ldo_config = 0x1;
+       ret = edp->cfg->ver_ops->com_ldo_config(edp);
+       if (ret)
+               return ret;
 
-       writel(ldo_config, edp->tx0 + TXn_LDO_CONFIG);
-       writel(ldo_config, edp->tx1 + TXn_LDO_CONFIG);
        writel(0x00, edp->tx0 + TXn_LANE_MODE_1);
        writel(0x00, edp->tx1 + TXn_LANE_MODE_1);