diff mbox series

[v2] phy: qcom-qmp: add support for display port voltage and pre-emphasis swing

Message ID 1630098658-23149-1-git-send-email-khsieh@codeaurora.org
State New
Headers show
Series [v2] phy: qcom-qmp: add support for display port voltage and pre-emphasis swing | expand

Commit Message

Kuogee Hsieh Aug. 27, 2021, 9:10 p.m. UTC
Both voltage and pre-emphasis swing level are set during link training
negotiation between host and sink. There are totally four tables added.
A voltage swing table for both hbr and hbr1, a voltage table for both
hbr2 and hbr3, a pre-emphasis table for both hbr and hbr1 and a pre-emphasis
table for both hbr2 and hbr3. In addition, write 0x0a to TX_TX_POL_INV is
added to complete the sequence of configure dp phy base on HPG.

Chnages in v2:
-- revise commit test
-- add Fixes tag
-- replaced voltage_swing_cfg with voltage
-- replaced pre_emphasis_cfg with emphasis
-- delete drv_lvl_reg and emp_post_reg parameters from qcom_qmp_v4_phy_configure_dp_swing()
-- delete drv_lvl_reg and emp_post_reg parameters from qcom_qmp_phy_configure_dp_swing()

Fixes: aff188feb5e1 ("phy: qcom-qmp: add support for sm8250-usb3-dp phy")
Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 117 ++++++++++++++++++++++++++----------
 1 file changed, 85 insertions(+), 32 deletions(-)

Comments

Dmitry Baryshkov Sept. 3, 2021, 7:09 p.m. UTC | #1
On 28/08/2021 00:10, Kuogee Hsieh wrote:
> Both voltage and pre-emphasis swing level are set during link training

> negotiation between host and sink. There are totally four tables added.

> A voltage swing table for both hbr and hbr1, a voltage table for both

> hbr2 and hbr3, a pre-emphasis table for both hbr and hbr1 and a pre-emphasis

> table for both hbr2 and hbr3. In addition, write 0x0a to TX_TX_POL_INV is

> added to complete the sequence of configure dp phy base on HPG.

> 

> Chnages in v2:

> -- revise commit test

> -- add Fixes tag

> -- replaced voltage_swing_cfg with voltage

> -- replaced pre_emphasis_cfg with emphasis

> -- delete drv_lvl_reg and emp_post_reg parameters from qcom_qmp_v4_phy_configure_dp_swing()

> -- delete drv_lvl_reg and emp_post_reg parameters from qcom_qmp_phy_configure_dp_swing()

> 

> Fixes: aff188feb5e1 ("phy: qcom-qmp: add support for sm8250-usb3-dp phy")

> Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>

> ---

>   drivers/phy/qualcomm/phy-qcom-qmp.c | 117 ++++++++++++++++++++++++++----------

>   1 file changed, 85 insertions(+), 32 deletions(-)

> 

> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c

> index 31036aa..021cbb0 100644

> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c

> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c

> @@ -3546,12 +3546,11 @@ static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {

>   	{ 0x1f, 0xff, 0xff, 0xff }

>   };

>   

> -static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,

> -		unsigned int drv_lvl_reg, unsigned int emp_post_reg)

> +static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy)


As this becomes a v3-only function, could you please rename it to 
qcom_qmp_v3_phy_configure_dp_swing()

>   {

>   	const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;

>   	unsigned int v_level = 0, p_level = 0;

> -	u8 voltage_swing_cfg, pre_emphasis_cfg;

> +	u8 voltage, emphasis;

>   	int i;

>   

>   	for (i = 0; i < dp_opts->lanes; i++) {

> @@ -3560,26 +3559,25 @@ static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,

>   	}

>   

>   	if (dp_opts->link_rate <= 2700) {

> -		voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];

> -		pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];

> +		voltage = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];

> +		emphasis = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];

>   	} else {

> -		voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];

> -		pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];

> +		voltage = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];

> +		emphasis = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];

>   	}

>   

>   	/* TODO: Move check to config check */

> -	if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)

> +	if (voltage == 0xFF && emphasis == 0xFF)

>   		return -EINVAL;

>   

>   	/* Enable MUX to use Cursor values from these registers */

> -	voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;

> -	pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;

> -

> -	writel(voltage_swing_cfg, qphy->tx + drv_lvl_reg);

> -	writel(pre_emphasis_cfg, qphy->tx + emp_post_reg);

> -	writel(voltage_swing_cfg, qphy->tx2 + drv_lvl_reg);

> -	writel(pre_emphasis_cfg, qphy->tx2 + emp_post_reg);

> +	voltage |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;

> +	emphasis |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;

>   

> +	writel(voltage, qphy->tx + QSERDES_V3_TX_TX_DRV_LVL);

> +	writel(emphasis, qphy->tx + QSERDES_V3_TX_TX_EMP_POST1_LVL);

> +	writel(voltage, qphy->tx2 + QSERDES_V3_TX_TX_DRV_LVL);

> +	writel(emphasis, qphy->tx2 + QSERDES_V3_TX_TX_EMP_POST1_LVL);

>   	return 0;

>   }

>   

> @@ -3588,9 +3586,7 @@ static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)

>   	const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;

>   	u32 bias_en, drvr_en;

>   

> -	if (qcom_qmp_phy_configure_dp_swing(qphy,

> -				QSERDES_V3_TX_TX_DRV_LVL,

> -				QSERDES_V3_TX_TX_EMP_POST1_LVL) < 0)

> +	if (qcom_qmp_phy_configure_dp_swing(qphy) < 0)

>   		return;

>   

>   	if (dp_opts->lanes == 1) {

> @@ -3728,6 +3724,71 @@ static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy)

>   	return 0;

>   }

>   

> +/* The values in these tables are given without MUX_EN (0x20) bit set */

> +static const u8 qmp_dp_v4_pre_emphasis_hbr3_hbr2[4][4] = {

> +	{ 0x00, 0x0c, 0x15, 0x1b },

> +	{ 0x02, 0x0e, 0x16, 0xff },

> +	{ 0x02, 0x11, 0xff, 0xff },

> +	{ 0x04, 0xff, 0xff, 0xff }

> +};

> +

> +static const u8 qmp_dp_v4_voltage_swing_hbr3_hbr2[4][4] = {

> +	{ 0x02, 0x12, 0x16, 0x1a },

> +	{ 0x09, 0x19, 0x1f, 0xff },

> +	{ 0x10, 0x1f, 0xff, 0xff },

> +	{ 0x1f, 0xff, 0xff, 0xff }

> +};

> +

> +static const u8 qmp_dp_v4_pre_emphasis_hbr_rbr[4][4] = {

> +	{ 0x00, 0x0e, 0x15, 0x1b },

> +	{ 0x00, 0x0e, 0x15, 0xff },

> +	{ 0x00, 0x0e, 0xff, 0xff },

> +	{ 0x04, 0xff, 0xff, 0xff }

> +};

> +

> +static const u8 qmp_dp_v4_voltage_swing_hbr_rbr[4][4] = {

> +	{ 0x08, 0x0f, 0x16, 0x1f },

> +	{ 0x11, 0x1e, 0x1f, 0xff },

> +	{ 0x16, 0x1f, 0xff, 0xff },

> +	{ 0x1f, 0xff, 0xff, 0xff }

> +};

> +

> +static int qcom_qmp_v4_phy_configure_dp_swing(struct qmp_phy *qphy)

> +{

> +	const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;

> +	unsigned int v_level = 0, p_level = 0;

> +	u8 voltage, emphasis;

> +	int i;

> +

> +	for (i = 0; i < dp_opts->lanes; i++) {

> +		v_level = max(v_level, dp_opts->voltage[i]);

> +		p_level = max(p_level, dp_opts->pre[i]);

> +	}

> +

> +	if (dp_opts->link_rate <= 2700) {

> +		voltage = qmp_dp_v4_voltage_swing_hbr_rbr[v_level][p_level];

> +		emphasis = qmp_dp_v4_pre_emphasis_hbr_rbr[v_level][p_level];

> +	} else {

> +		voltage = qmp_dp_v4_voltage_swing_hbr3_hbr2[v_level][p_level];

> +		emphasis = qmp_dp_v4_pre_emphasis_hbr3_hbr2[v_level][p_level];

> +	}

> +

> +	/* TODO: Move check to config check */

> +	if (voltage == 0xFF && emphasis == 0xFF)

> +		return -EINVAL;

> +

> +	/* Enable MUX to use Cursor values from these registers */

> +	voltage |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;

> +	emphasis |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;

> +

> +	writel(voltage, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);

> +	writel(emphasis, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);

> +	writel(voltage, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);

> +	writel(emphasis, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);

> +

> +	return 0;

> +}

> +

>   static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)

>   {

>   	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |

> @@ -3757,16 +3818,7 @@ static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)

>   

>   static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy)

>   {

> -	/* Program default values before writing proper values */

> -	writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);

> -	writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);

> -

> -	writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);

> -	writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);

> -

> -	qcom_qmp_phy_configure_dp_swing(qphy,

> -			QSERDES_V4_TX_TX_DRV_LVL,

> -			QSERDES_V4_TX_TX_EMP_POST1_LVL);

> +	qcom_qmp_v4_phy_configure_dp_swing(qphy);

>   }

>   

>   static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)

> @@ -3885,6 +3937,9 @@ static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)

>   	writel(drvr1_en, qphy->tx2 + QSERDES_V4_TX_HIGHZ_DRVR_EN);

>   	writel(bias1_en, qphy->tx2 + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);

>   

> +	writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);

> +	writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);

> +

>   	writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);

>   	udelay(2000);

>   	writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);

> @@ -3896,11 +3951,9 @@ static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)

>   			10000))

>   		return -ETIMEDOUT;

>   

> -	writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);

> -	writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);

>   

> -	writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);

> -	writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);

> +	writel(0x22, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);

> +	writel(0x22, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);

>   

>   	writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);

>   	writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);

> 



-- 
With best wishes
Dmitry
Stephen Boyd Sept. 3, 2021, 7:16 p.m. UTC | #2
Quoting Dmitry Baryshkov (2021-09-03 12:09:14)
> On 28/08/2021 00:10, Kuogee Hsieh wrote:

> > Both voltage and pre-emphasis swing level are set during link training

> > negotiation between host and sink. There are totally four tables added.

> > A voltage swing table for both hbr and hbr1, a voltage table for both

> > hbr2 and hbr3, a pre-emphasis table for both hbr and hbr1 and a pre-emphasis

> > table for both hbr2 and hbr3. In addition, write 0x0a to TX_TX_POL_INV is

> > added to complete the sequence of configure dp phy base on HPG.

> >

> > Chnages in v2:

> > -- revise commit test

> > -- add Fixes tag

> > -- replaced voltage_swing_cfg with voltage

> > -- replaced pre_emphasis_cfg with emphasis

> > -- delete drv_lvl_reg and emp_post_reg parameters from qcom_qmp_v4_phy_configure_dp_swing()

> > -- delete drv_lvl_reg and emp_post_reg parameters from qcom_qmp_phy_configure_dp_swing()

> >

> > Fixes: aff188feb5e1 ("phy: qcom-qmp: add support for sm8250-usb3-dp phy")

> > Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>

> > ---

> >   drivers/phy/qualcomm/phy-qcom-qmp.c | 117 ++++++++++++++++++++++++++----------

> >   1 file changed, 85 insertions(+), 32 deletions(-)

> >

> > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c

> > index 31036aa..021cbb0 100644

> > --- a/drivers/phy/qualcomm/phy-qcom-qmp.c

> > +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c

> > @@ -3546,12 +3546,11 @@ static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {

> >       { 0x1f, 0xff, 0xff, 0xff }

> >   };

> >

> > -static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,

> > -             unsigned int drv_lvl_reg, unsigned int emp_post_reg)

> > +static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy)

>

> As this becomes a v3-only function, could you please rename it to

> qcom_qmp_v3_phy_configure_dp_swing()


Can it be combined with the v4 version instead? The code structure is
essentially the same, modulo the tables used and the register offset
written to.
diff mbox series

Patch

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 31036aa..021cbb0 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -3546,12 +3546,11 @@  static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
 	{ 0x1f, 0xff, 0xff, 0xff }
 };
 
-static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,
-		unsigned int drv_lvl_reg, unsigned int emp_post_reg)
+static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy)
 {
 	const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
 	unsigned int v_level = 0, p_level = 0;
-	u8 voltage_swing_cfg, pre_emphasis_cfg;
+	u8 voltage, emphasis;
 	int i;
 
 	for (i = 0; i < dp_opts->lanes; i++) {
@@ -3560,26 +3559,25 @@  static int qcom_qmp_phy_configure_dp_swing(struct qmp_phy *qphy,
 	}
 
 	if (dp_opts->link_rate <= 2700) {
-		voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
-		pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
+		voltage = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
+		emphasis = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
 	} else {
-		voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];
-		pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];
+		voltage = qmp_dp_v3_voltage_swing_hbr3_hbr2[v_level][p_level];
+		emphasis = qmp_dp_v3_pre_emphasis_hbr3_hbr2[v_level][p_level];
 	}
 
 	/* TODO: Move check to config check */
-	if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
+	if (voltage == 0xFF && emphasis == 0xFF)
 		return -EINVAL;
 
 	/* Enable MUX to use Cursor values from these registers */
-	voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
-	pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
-
-	writel(voltage_swing_cfg, qphy->tx + drv_lvl_reg);
-	writel(pre_emphasis_cfg, qphy->tx + emp_post_reg);
-	writel(voltage_swing_cfg, qphy->tx2 + drv_lvl_reg);
-	writel(pre_emphasis_cfg, qphy->tx2 + emp_post_reg);
+	voltage |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
+	emphasis |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
 
+	writel(voltage, qphy->tx + QSERDES_V3_TX_TX_DRV_LVL);
+	writel(emphasis, qphy->tx + QSERDES_V3_TX_TX_EMP_POST1_LVL);
+	writel(voltage, qphy->tx2 + QSERDES_V3_TX_TX_DRV_LVL);
+	writel(emphasis, qphy->tx2 + QSERDES_V3_TX_TX_EMP_POST1_LVL);
 	return 0;
 }
 
@@ -3588,9 +3586,7 @@  static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
 	const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
 	u32 bias_en, drvr_en;
 
-	if (qcom_qmp_phy_configure_dp_swing(qphy,
-				QSERDES_V3_TX_TX_DRV_LVL,
-				QSERDES_V3_TX_TX_EMP_POST1_LVL) < 0)
+	if (qcom_qmp_phy_configure_dp_swing(qphy) < 0)
 		return;
 
 	if (dp_opts->lanes == 1) {
@@ -3728,6 +3724,71 @@  static int qcom_qmp_v3_dp_phy_calibrate(struct qmp_phy *qphy)
 	return 0;
 }
 
+/* The values in these tables are given without MUX_EN (0x20) bit set */
+static const u8 qmp_dp_v4_pre_emphasis_hbr3_hbr2[4][4] = {
+	{ 0x00, 0x0c, 0x15, 0x1b },
+	{ 0x02, 0x0e, 0x16, 0xff },
+	{ 0x02, 0x11, 0xff, 0xff },
+	{ 0x04, 0xff, 0xff, 0xff }
+};
+
+static const u8 qmp_dp_v4_voltage_swing_hbr3_hbr2[4][4] = {
+	{ 0x02, 0x12, 0x16, 0x1a },
+	{ 0x09, 0x19, 0x1f, 0xff },
+	{ 0x10, 0x1f, 0xff, 0xff },
+	{ 0x1f, 0xff, 0xff, 0xff }
+};
+
+static const u8 qmp_dp_v4_pre_emphasis_hbr_rbr[4][4] = {
+	{ 0x00, 0x0e, 0x15, 0x1b },
+	{ 0x00, 0x0e, 0x15, 0xff },
+	{ 0x00, 0x0e, 0xff, 0xff },
+	{ 0x04, 0xff, 0xff, 0xff }
+};
+
+static const u8 qmp_dp_v4_voltage_swing_hbr_rbr[4][4] = {
+	{ 0x08, 0x0f, 0x16, 0x1f },
+	{ 0x11, 0x1e, 0x1f, 0xff },
+	{ 0x16, 0x1f, 0xff, 0xff },
+	{ 0x1f, 0xff, 0xff, 0xff }
+};
+
+static int qcom_qmp_v4_phy_configure_dp_swing(struct qmp_phy *qphy)
+{
+	const struct phy_configure_opts_dp *dp_opts = &qphy->dp_opts;
+	unsigned int v_level = 0, p_level = 0;
+	u8 voltage, emphasis;
+	int i;
+
+	for (i = 0; i < dp_opts->lanes; i++) {
+		v_level = max(v_level, dp_opts->voltage[i]);
+		p_level = max(p_level, dp_opts->pre[i]);
+	}
+
+	if (dp_opts->link_rate <= 2700) {
+		voltage = qmp_dp_v4_voltage_swing_hbr_rbr[v_level][p_level];
+		emphasis = qmp_dp_v4_pre_emphasis_hbr_rbr[v_level][p_level];
+	} else {
+		voltage = qmp_dp_v4_voltage_swing_hbr3_hbr2[v_level][p_level];
+		emphasis = qmp_dp_v4_pre_emphasis_hbr3_hbr2[v_level][p_level];
+	}
+
+	/* TODO: Move check to config check */
+	if (voltage == 0xFF && emphasis == 0xFF)
+		return -EINVAL;
+
+	/* Enable MUX to use Cursor values from these registers */
+	voltage |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
+	emphasis |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
+
+	writel(voltage, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
+	writel(emphasis, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
+	writel(voltage, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
+	writel(emphasis, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
+
+	return 0;
+}
+
 static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)
 {
 	writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
@@ -3757,16 +3818,7 @@  static void qcom_qmp_v4_phy_dp_aux_init(struct qmp_phy *qphy)
 
 static void qcom_qmp_v4_phy_configure_dp_tx(struct qmp_phy *qphy)
 {
-	/* Program default values before writing proper values */
-	writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
-	writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
-
-	writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
-	writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);
-
-	qcom_qmp_phy_configure_dp_swing(qphy,
-			QSERDES_V4_TX_TX_DRV_LVL,
-			QSERDES_V4_TX_TX_EMP_POST1_LVL);
+	qcom_qmp_v4_phy_configure_dp_swing(qphy);
 }
 
 static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)
@@ -3885,6 +3937,9 @@  static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)
 	writel(drvr1_en, qphy->tx2 + QSERDES_V4_TX_HIGHZ_DRVR_EN);
 	writel(bias1_en, qphy->tx2 + QSERDES_V4_TX_TRANSCEIVER_BIAS_EN);
 
+	writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);
+	writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);
+
 	writel(0x18, qphy->pcs + QSERDES_DP_PHY_CFG);
 	udelay(2000);
 	writel(0x19, qphy->pcs + QSERDES_DP_PHY_CFG);
@@ -3896,11 +3951,9 @@  static int qcom_qmp_v4_phy_configure_dp_phy(struct qmp_phy *qphy)
 			10000))
 		return -ETIMEDOUT;
 
-	writel(0x0a, qphy->tx + QSERDES_V4_TX_TX_POL_INV);
-	writel(0x0a, qphy->tx2 + QSERDES_V4_TX_TX_POL_INV);
 
-	writel(0x27, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
-	writel(0x27, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
+	writel(0x22, qphy->tx + QSERDES_V4_TX_TX_DRV_LVL);
+	writel(0x22, qphy->tx2 + QSERDES_V4_TX_TX_DRV_LVL);
 
 	writel(0x20, qphy->tx + QSERDES_V4_TX_TX_EMP_POST1_LVL);
 	writel(0x20, qphy->tx2 + QSERDES_V4_TX_TX_EMP_POST1_LVL);