Commit 519a228e authored by Yongxing Mou's avatar Yongxing Mou Committed by Vinod Koul
Browse files

phy: qcom: edp: Add PHY-specific LDO config for eDP low vdiff



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: f199223c ("phy: qcom: Introduce new eDP PHY driver")
Signed-off-by: default avatarYongxing Mou <yongxing.mou@oss.qualcomm.com>
Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: default avatarKonrad 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: default avatarVinod Koul <vkoul@kernel.org>
parent bf237a9f
Loading
Loading
Loading
Loading
+77 −11
Original line number Diff line number Diff line
@@ -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);