瀏覽代碼

disp: msm: dp: add pll params table for 4nm PHY pll settings

Because of changes to ref clock frequency, few of the pll
reg values are different for kalama compared to palima.
This change differentiates between these two 4nm versions,
based on pll revision and also introduces a pll reg table
to differentiate the values.

Change-Id: I016330ded10ab334012daa8cc288a8cd5c039f58
Signed-off-by: Sandeep Gangadharaiah <[email protected]>
Sandeep Gangadharaiah 3 年之前
父節點
當前提交
b5383dbae3
共有 4 個文件被更改,包括 158 次插入161 次删除
  1. 5 0
      msm/dp/dp_pll.c
  2. 31 12
      msm/dp/dp_pll.h
  3. 74 83
      msm/dp/dp_pll_4nm.c
  4. 48 66
      msm/dp/dp_pll_5nm.c

+ 5 - 0
msm/dp/dp_pll.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/err.h>
@@ -55,6 +56,7 @@ static int dp_pll_clock_register(struct dp_pll *pll)
 		rc = dp_pll_clock_register_5nm(pll);
 		break;
 	case DP_PLL_4NM_V1:
+	case DP_PLL_4NM_V1_1:
 		rc = dp_pll_clock_register_4nm(pll);
 		break;
 	default:
@@ -73,6 +75,7 @@ static void dp_pll_clock_unregister(struct dp_pll *pll)
 		dp_pll_clock_unregister_5nm(pll);
 		break;
 	case DP_PLL_4NM_V1:
+	case DP_PLL_4NM_V1_1:
 		dp_pll_clock_unregister_4nm(pll);
 		break;
 	default:
@@ -139,6 +142,8 @@ struct dp_pll *dp_pll_get(struct dp_pll_in *in)
 			pll->revision = DP_PLL_5NM_V2;
 		} else if (!strcmp(label, "4nm-v1")) {
 			pll->revision = DP_PLL_4NM_V1;
+		} else if (!strcmp(label, "4nm-v1.1")) {
+			pll->revision = DP_PLL_4NM_V1_1;
 		} else {
 			DP_ERR("Unsupported pll revision\n");
 			rc = -ENOTSUPP;

+ 31 - 12
msm/dp/dp_pll.h

@@ -37,6 +37,15 @@ enum dp_pll_revision {
 	DP_PLL_5NM_V1,
 	DP_PLL_5NM_V2,
 	DP_PLL_4NM_V1,
+	DP_PLL_4NM_V1_1,
+};
+
+enum hsclk_rate {
+	HSCLK_RATE_1620MHZ,
+	HSCLK_RATE_2700MHZ,
+	HSCLK_RATE_5400MHZ,
+	HSCLK_RATE_8100MHZ,
+	HSCLK_RATE_MAX,
 };
 
 static inline const char *dp_pll_get_revision(enum dp_pll_revision rev)
@@ -46,6 +55,7 @@ static inline const char *dp_pll_get_revision(enum dp_pll_revision rev)
 	case DP_PLL_5NM_V1:	return "DP_PLL_5NM_V1";
 	case DP_PLL_5NM_V2:	return "DP_PLL_5NM_V2";
 	case DP_PLL_4NM_V1:	return "DP_PLL_4NM_V1";
+	case DP_PLL_4NM_V1_1:	return "DP_PLL_4NM_V1_1";
 	default:		return "???";
 	}
 }
@@ -91,31 +101,40 @@ struct dp_pll {
 	int (*pll_unprepare)(struct dp_pll *pll);
 };
 
-struct dp_pll_db {
-	struct dp_pll *pll;
-
-	/* lane and orientation settings */
-	u8 lane_cnt;
-	u8 orientation;
-
+struct dp_pll_params {
 	/* COM PHY settings */
 	u32 hsclk_sel;
+	u32 integloop_gain0_mode0;
+	u32 integloop_gain1_mode0;
+	u32 lock_cmp_en;
+	/* PHY vco divider */
+	u32 phy_vco_div;
 	u32 dec_start_mode0;
 	u32 div_frac_start1_mode0;
 	u32 div_frac_start2_mode0;
 	u32 div_frac_start3_mode0;
-	u32 integloop_gain0_mode0;
-	u32 integloop_gain1_mode0;
 	u32 lock_cmp1_mode0;
 	u32 lock_cmp2_mode0;
-	u32 lock_cmp_en;
 	u32 ssc_step_size1_mode0;
 	u32 ssc_step_size2_mode0;
 	u32 ssc_per1;
+	u32 ssc_per2;
 	u32 cmp_code1_mode0;
 	u32 cmp_code2_mode0;
-	/* PHY vco divider */
-	u32 phy_vco_div;
+	u32 pll_ivco;
+	u32 bg_timer;
+	u32 core_clk_en;
+	u32 lane_offset_tx;
+	u32 lane_offset_rx;
+};
+
+struct dp_pll_db {
+	struct dp_pll *pll;
+	/* lane and orientation settings */
+	u8 lane_cnt;
+	u8 orientation;
+	u32 rate_idx;
+	const struct dp_pll_params *pll_params;
 };
 
 static inline struct dp_pll_vco_clk *to_dp_vco_hw(struct clk_hw *hw)

+ 74 - 83
msm/dp/dp_pll_4nm.c

@@ -128,6 +128,29 @@
 #define DP_4NM_PHY_READY	BIT(1)
 #define DP_4NM_TSYNC_DONE	BIT(0)
 
+static const struct dp_pll_params pll_params_v1[HSCLK_RATE_MAX] = {
+	{0x05, 0x3f, 0x00, 0x04, 0x01, 0x69, 0x00, 0x80, 0x07, 0x6f, 0x08, 0x45, 0x06, 0x36, 0x01,
+		0xe2, 0x18, 0x0f, 0x0e, 0x1f, 0x0a, 0x11},
+	{0x03, 0x3f, 0x00, 0x08, 0x01, 0x69, 0x00, 0x80, 0x07, 0x0f, 0x0e, 0x13, 0x06, 0x40, 0x01,
+		0xe2, 0x18, 0x0f, 0x0e, 0x1f, 0x0a, 0x11},
+	{0x01, 0x3f, 0x00, 0x08, 0x02, 0x8c, 0x00, 0x00, 0x0a, 0x1f, 0x1c, 0x1a, 0x08, 0x40, 0x01,
+		0x2e, 0x21, 0x0f, 0x0e, 0x1f, 0x0a, 0x11},
+	{0x00, 0x3f, 0x00, 0x08, 0x00, 0x69, 0x00, 0x80, 0x07, 0x2f, 0x2a, 0x13, 0x06, 0x40, 0x01,
+		0xe2, 0x18, 0x0f, 0x0e, 0x1f, 0x0a, 0x11},
+};
+
+static const struct dp_pll_params pll_params_v1_1[HSCLK_RATE_MAX] = {
+	{0x05, 0x3f, 0x00, 0x04, 0x01, 0x34, 0x00, 0xc0, 0x0b, 0x37, 0x04, 0x92, 0x01, 0x6b, 0x02,
+		0x71, 0x0c, 0x0f, 0x0a, 0x0f, 0x0c, 0x0c},
+	{0x03, 0x3f, 0x00, 0x08, 0x01, 0x34, 0x00, 0xc0, 0x0b, 0x07, 0x07, 0x92, 0x01, 0x6b, 0x02,
+		0x71, 0x0c, 0x0f, 0x0e, 0x0f, 0x0c, 0x0c},
+	{0x01, 0x3f, 0x00, 0x08, 0x02, 0x46, 0x00, 0x00, 0x05, 0x0f, 0x0e, 0x18, 0x02, 0x6b, 0x02,
+		0x97, 0x10, 0x0f, 0x0a, 0x0f, 0x0c, 0x0c},
+	{0x00, 0x3f, 0x00, 0x08, 0x00, 0x34, 0x00, 0xc0, 0x0b, 0x17, 0x15, 0x92, 0x01, 0x6b, 0x02,
+		0x71, 0x0c, 0x0f, 0x0a, 0x0f, 0x0c, 0x0c}
+
+};
+
 static int set_vco_div(struct dp_pll *pll, unsigned long rate)
 {
 	u32 div, val;
@@ -191,74 +214,22 @@ static int dp_vco_pll_init_db_4nm(struct dp_pll_db *pdb,
 	DP_DEBUG("spare_value=0x%x, ln_cnt=0x%x, orientation=0x%x\n",
 			spare_value, pdb->lane_cnt, pdb->orientation);
 
-	pdb->div_frac_start1_mode0 = 0x00;
-	pdb->integloop_gain0_mode0 = 0x3f;
-	pdb->integloop_gain1_mode0 = 0x00;
-
 	switch (rate) {
 	case DP_VCO_HSCLK_RATE_1620MHZDIV1000:
 		DP_DEBUG("VCO rate: %ld\n", DP_VCO_RATE_9720MHZDIV1000);
-		pdb->hsclk_sel = 0x05;
-		pdb->dec_start_mode0 = 0x34;
-		pdb->div_frac_start2_mode0 = 0xc0;
-		pdb->div_frac_start3_mode0 = 0x0b;
-		pdb->lock_cmp1_mode0 = 0x37;
-		pdb->lock_cmp2_mode0 = 0x04;
-		pdb->phy_vco_div = 0x1;
-		pdb->lock_cmp_en = 0x04;
-		pdb->ssc_step_size1_mode0 = 0x92;
-		pdb->ssc_step_size2_mode0 = 0x01;
-		pdb->ssc_per1 = 0x6B;
-		pdb->cmp_code1_mode0 = 0x71;
-		pdb->cmp_code2_mode0 = 0x0c;
+		pdb->rate_idx = HSCLK_RATE_1620MHZ;
 		break;
 	case DP_VCO_HSCLK_RATE_2700MHZDIV1000:
 		DP_DEBUG("VCO rate: %ld\n", DP_VCO_RATE_10800MHZDIV1000);
-		pdb->hsclk_sel = 0x03;
-		pdb->dec_start_mode0 = 0x34;
-		pdb->div_frac_start2_mode0 = 0xc0;
-		pdb->div_frac_start3_mode0 = 0x0b;
-		pdb->lock_cmp1_mode0 = 0x07;
-		pdb->lock_cmp2_mode0 = 0x07;
-		pdb->phy_vco_div = 0x1;
-		pdb->lock_cmp_en = 0x08;
-		pdb->ssc_step_size1_mode0 = 0x92;
-		pdb->ssc_step_size2_mode0 = 0x01;
-		pdb->ssc_per1 = 0x6B;
-		pdb->cmp_code1_mode0 = 0x71;
-		pdb->cmp_code2_mode0 = 0x0c;
+		pdb->rate_idx = HSCLK_RATE_2700MHZ;
 		break;
 	case DP_VCO_HSCLK_RATE_5400MHZDIV1000:
 		DP_DEBUG("VCO rate: %ld\n", DP_VCO_RATE_10800MHZDIV1000);
-		pdb->hsclk_sel = 0x01;
-		pdb->dec_start_mode0 = 0x46;
-		pdb->div_frac_start2_mode0 = 0x00;
-		pdb->div_frac_start3_mode0 = 0x05;
-		pdb->lock_cmp1_mode0 = 0x0f;
-		pdb->lock_cmp2_mode0 = 0x0e;
-		pdb->phy_vco_div = 0x2;
-		pdb->lock_cmp_en = 0x08;
-		pdb->ssc_step_size1_mode0 = 0x18;
-		pdb->ssc_step_size2_mode0 = 0x02;
-		pdb->ssc_per1 = 0x6B;
-		pdb->cmp_code1_mode0 = 0x97;
-		pdb->cmp_code2_mode0 = 0x10;
+		pdb->rate_idx = HSCLK_RATE_5400MHZ;
 		break;
 	case DP_VCO_HSCLK_RATE_8100MHZDIV1000:
 		DP_DEBUG("VCO rate: %ld\n", DP_VCO_RATE_8100MHZDIV1000);
-		pdb->hsclk_sel = 0x00;
-		pdb->dec_start_mode0 = 0x34;
-		pdb->div_frac_start2_mode0 = 0xc0;
-		pdb->div_frac_start3_mode0 = 0x0b;
-		pdb->lock_cmp1_mode0 = 0x17;
-		pdb->lock_cmp2_mode0 = 0x15;
-		pdb->phy_vco_div = 0x0;
-		pdb->lock_cmp_en = 0x08;
-		pdb->ssc_step_size1_mode0 = 0x92;
-		pdb->ssc_step_size2_mode0 = 0x01;
-		pdb->ssc_per1 = 0x6B;
-		pdb->cmp_code1_mode0 = 0x71;
-		pdb->cmp_code2_mode0 = 0x0c;
+		pdb->rate_idx = HSCLK_RATE_8100MHZ;
 		break;
 	default:
 		DP_ERR("unsupported rate %ld\n", rate);
@@ -272,6 +243,7 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll,
 {
 	int rc = 0;
 	struct dp_pll_db *pdb = (struct dp_pll_db *)pll->priv;
+	const struct dp_pll_params *params;
 
 	rc = dp_vco_pll_init_db_4nm(pdb, rate);
 	if (rc < 0) {
@@ -290,6 +262,13 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll,
 		dp_pll_write(dp_phy, DP_PHY_PD_CTL, 0x7d);
 	}
 
+	if (pdb->rate_idx < HSCLK_RATE_MAX) {
+		params = &pdb->pll_params[pdb->rate_idx];
+	} else {
+		DP_ERR("link rate not set\n");
+		return -EINVAL;
+	}
+
 	/* Make sure the PHY register writes are done */
 	wmb();
 
@@ -303,7 +282,7 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll,
 	wmb();
 
 	/* PLL Optimization */
-	dp_pll_write(dp_pll, QSERDES_COM_PLL_IVCO, 0x07);
+	dp_pll_write(dp_pll, QSERDES_COM_PLL_IVCO, params->pll_ivco);
 	dp_pll_write(dp_pll, QSERDES_COM_PLL_CCTRL_MODE0, 0x36);
 	dp_pll_write(dp_pll, QSERDES_COM_PLL_RCTRL_MODE0, 0x16);
 	dp_pll_write(dp_pll, QSERDES_COM_CP_CTRL_MODE0, 0x06);
@@ -311,49 +290,56 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll,
 	wmb();
 
 	/* link rate dependent params */
-	dp_pll_write(dp_pll, QSERDES_COM_HSCLK_SEL_1, pdb->hsclk_sel);
-	dp_pll_write(dp_pll, QSERDES_COM_DEC_START_MODE0, pdb->dec_start_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_HSCLK_SEL_1, params->hsclk_sel);
+	dp_pll_write(dp_pll, QSERDES_COM_DEC_START_MODE0, params->dec_start_mode0);
 	dp_pll_write(dp_pll,
-		QSERDES_COM_DIV_FRAC_START1_MODE0, pdb->div_frac_start1_mode0);
+		QSERDES_COM_DIV_FRAC_START1_MODE0, params->div_frac_start1_mode0);
 	dp_pll_write(dp_pll,
-		QSERDES_COM_DIV_FRAC_START2_MODE0, pdb->div_frac_start2_mode0);
+		QSERDES_COM_DIV_FRAC_START2_MODE0, params->div_frac_start2_mode0);
 	dp_pll_write(dp_pll,
-		QSERDES_COM_DIV_FRAC_START3_MODE0, pdb->div_frac_start3_mode0);
-	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP1_MODE0, pdb->lock_cmp1_mode0);
-	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP2_MODE0, pdb->lock_cmp2_mode0);
-	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP_EN, pdb->lock_cmp_en);
-	dp_pll_write(dp_phy, DP_PHY_VCO_DIV, pdb->phy_vco_div);
+		QSERDES_COM_DIV_FRAC_START3_MODE0, params->div_frac_start3_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP1_MODE0, params->lock_cmp1_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP2_MODE0, params->lock_cmp2_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP_EN, params->lock_cmp_en);
+	dp_pll_write(dp_phy, DP_PHY_VCO_DIV, params->phy_vco_div);
 	/* Make sure the PLL register writes are done */
 	wmb();
 
 	dp_pll_write(dp_pll, QSERDES_COM_CMN_CONFIG_1, 0x12);
-	dp_pll_write(dp_pll, QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x3f);
-	dp_pll_write(dp_pll, QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00);
+	dp_pll_write(dp_pll, QSERDES_COM_INTEGLOOP_GAIN0_MODE0,
+		params->integloop_gain0_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_INTEGLOOP_GAIN1_MODE0,
+		params->integloop_gain1_mode0);
 	dp_pll_write(dp_pll, QSERDES_COM_VCO_TUNE_MAP, 0x00);
 	/* Make sure the PHY register writes are done */
 	wmb();
 
-	dp_pll_write(dp_pll, QSERDES_COM_BG_TIMER, 0x0a);
+	dp_pll_write(dp_pll, QSERDES_COM_BG_TIMER, params->bg_timer);
 	dp_pll_write(dp_pll, QSERDES_COM_CORECLK_DIV_MODE0, 0x14);
 	dp_pll_write(dp_pll, QSERDES_COM_VCO_TUNE_CTRL, 0x00);
 
-	dp_pll_write(dp_pll, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1f);
+	if (pll->bonding_en)
+		dp_pll_write(dp_pll, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1f);
+	else
+		dp_pll_write(dp_pll, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x17);
 
-	dp_pll_write(dp_pll, QSERDES_COM_CORE_CLK_EN, 0x0f);
-	dp_pll_write(dp_pll, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0, pdb->cmp_code1_mode0);
-	dp_pll_write(dp_pll, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0, pdb->cmp_code2_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_CORE_CLK_EN, params->core_clk_en);
+	dp_pll_write(dp_pll, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0,
+		params->cmp_code1_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0,
+		params->cmp_code2_mode0);
 	/* Make sure the PHY register writes are done */
 	wmb();
 
 	if (pll->ssc_en) {
 		dp_pll_write(dp_pll, QSERDES_COM_SSC_EN_CENTER, 0x01);
 		dp_pll_write(dp_pll, QSERDES_COM_SSC_ADJ_PER1, 0x00);
-		dp_pll_write(dp_pll, QSERDES_COM_SSC_PER1, pdb->ssc_per1);
-		dp_pll_write(dp_pll, QSERDES_COM_SSC_PER2, 0x02);
+		dp_pll_write(dp_pll, QSERDES_COM_SSC_PER1, params->ssc_per1);
+		dp_pll_write(dp_pll, QSERDES_COM_SSC_PER2, params->ssc_per2);
 		dp_pll_write(dp_pll, QSERDES_COM_SSC_STEP_SIZE1_MODE0,
-				pdb->ssc_step_size1_mode0);
+				params->ssc_step_size1_mode0);
 		dp_pll_write(dp_pll, QSERDES_COM_SSC_STEP_SIZE2_MODE0,
-				pdb->ssc_step_size2_mode0);
+				params->ssc_step_size2_mode0);
 	}
 
 	if (pdb->orientation == ORIENTATION_CC2)
@@ -376,8 +362,8 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll,
 	dp_pll_write(dp_ln_tx0, DP_TRAN_DRVR_EMP_EN, 0xf);
 	dp_pll_write(dp_ln_tx0, TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00);
 	dp_pll_write(dp_ln_tx0, DP_TX_INTERFACE_MODE, 0x00);
-	dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_TX, 0x0A);
-	dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_RX, 0x11);
+	dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_TX, params->lane_offset_tx);
+	dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_RX, params->lane_offset_rx);
 	dp_pll_write(dp_ln_tx0, TXn_TX_BAND, 0x04);
 	/* Make sure the PLL register writes are done */
 	wmb();
@@ -392,8 +378,8 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll,
 	dp_pll_write(dp_ln_tx1, DP_TRAN_DRVR_EMP_EN, 0xf);
 	dp_pll_write(dp_ln_tx1, TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00);
 	dp_pll_write(dp_ln_tx1, DP_TX_INTERFACE_MODE, 0x00);
-	dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_TX, 0x11);
-	dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_RX, 0x11);
+	dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_TX, params->lane_offset_tx);
+	dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_RX, params->lane_offset_rx);
 	dp_pll_write(dp_ln_tx1, TXn_TX_BAND, 0x04);
 	/* Make sure the PHY register writes are done */
 	wmb();
@@ -629,7 +615,7 @@ static int dp_pll_prepare(struct dp_pll *pll)
 	 * link rate is 8.1Gbps. This will result in voting to place Mx rail in
 	 * turbo as required for V1 hardware PLL functionality.
 	 */
-	if (pll->revision == DP_PLL_4NM_V1 &&
+	if (pll->revision >= DP_PLL_4NM_V1 &&
 	    pll->vco_rate == DP_VCO_HSCLK_RATE_8100MHZDIV1000) {
 		rc = dp_regulator_enable_4nm(pll->parser, DP_PLL_PM, true);
 		if (rc < 0) {
@@ -654,7 +640,7 @@ static int dp_pll_unprepare(struct dp_pll *pll)
 		return -EINVAL;
 	}
 
-	if (pll->revision == DP_PLL_4NM_V1 &&
+	if (pll->revision >= DP_PLL_4NM_V1 &&
 			pll->vco_rate == DP_VCO_HSCLK_RATE_8100MHZDIV1000) {
 		rc = dp_regulator_enable_4nm(pll->parser, DP_PLL_PM, false);
 		if (rc < 0) {
@@ -878,6 +864,11 @@ int dp_pll_clock_register_4nm(struct dp_pll *pll)
 	pll->priv = &dp_pdb;
 	dp_pdb.pll = pll;
 
+	if (pll->revision == DP_PLL_4NM_V1_1)
+		dp_pdb.pll_params = pll_params_v1_1;
+	else
+		dp_pdb.pll_params = pll_params_v1;
+
 	pll->pll_cfg = dp_pll_configure;
 	pll->pll_prepare = dp_pll_prepare;
 	pll->pll_unprepare = dp_pll_unprepare;

+ 48 - 66
msm/dp/dp_pll_5nm.c

@@ -128,6 +128,17 @@
 #define DP_5NM_PHY_READY	BIT(1)
 #define DP_5NM_TSYNC_DONE	BIT(0)
 
+static const struct dp_pll_params pll_params[HSCLK_RATE_MAX] = {
+	{0x05, 0x3f, 0x00, 0x04, 0x01, 0x69, 0x00, 0x80, 0x07, 0x6f, 0x08, 0x45, 0x06, 0x36, 0x01,
+		0x00, 0x00, 0x0f, 0x0a, 0x1f, 0x0a, 0x11},
+	{0x03, 0x3f, 0x00, 0x08, 0x01, 0x69, 0x00, 0x80, 0x07, 0x0f, 0x0e, 0x45, 0x06, 0x36, 0x01,
+		0x00, 0x00, 0x0f, 0x0a, 0x1f, 0x0a, 0x11},
+	{0x01, 0x3f, 0x00, 0x08, 0x02, 0x8c, 0x00, 0x00, 0x0a, 0x1f, 0x1c, 0x5c, 0x08, 0x36, 0x01,
+		0x00, 0x00, 0x0f, 0x0a, 0x1f, 0x0a, 0x11},
+	{0x00, 0x3f, 0x00, 0x08, 0x00, 0x69, 0x00, 0x80, 0x07, 0x2f, 0x2a, 0x45, 0x06, 0x36, 0x01,
+		0x00, 0x00, 0x0f, 0x0a, 0x1f, 0x0a, 0x11},
+};
+
 static int set_vco_div(struct dp_pll *pll, unsigned long rate)
 {
 	u32 div, val;
@@ -191,62 +202,22 @@ static int dp_vco_pll_init_db_5nm(struct dp_pll_db *pdb,
 	DP_DEBUG("spare_value=0x%x, ln_cnt=0x%x, orientation=0x%x\n",
 			spare_value, pdb->lane_cnt, pdb->orientation);
 
-	pdb->div_frac_start1_mode0 = 0x00;
-	pdb->integloop_gain0_mode0 = 0x3f;
-	pdb->integloop_gain1_mode0 = 0x00;
-
 	switch (rate) {
 	case DP_VCO_HSCLK_RATE_1620MHZDIV1000:
 		DP_DEBUG("VCO rate: %ld\n", DP_VCO_RATE_9720MHZDIV1000);
-		pdb->hsclk_sel = 0x05;
-		pdb->dec_start_mode0 = 0x69;
-		pdb->div_frac_start2_mode0 = 0x80;
-		pdb->div_frac_start3_mode0 = 0x07;
-		pdb->lock_cmp1_mode0 = 0x6f;
-		pdb->lock_cmp2_mode0 = 0x08;
-		pdb->phy_vco_div = 0x1;
-		pdb->lock_cmp_en = 0x04;
-		pdb->ssc_step_size1_mode0 = 0x45;
-		pdb->ssc_step_size2_mode0 = 0x06;
+		pdb->rate_idx = HSCLK_RATE_1620MHZ;
 		break;
 	case DP_VCO_HSCLK_RATE_2700MHZDIV1000:
 		DP_DEBUG("VCO rate: %ld\n", DP_VCO_RATE_10800MHZDIV1000);
-		pdb->hsclk_sel = 0x03;
-		pdb->dec_start_mode0 = 0x69;
-		pdb->div_frac_start2_mode0 = 0x80;
-		pdb->div_frac_start3_mode0 = 0x07;
-		pdb->lock_cmp1_mode0 = 0x0f;
-		pdb->lock_cmp2_mode0 = 0x0e;
-		pdb->phy_vco_div = 0x1;
-		pdb->lock_cmp_en = 0x08;
-		pdb->ssc_step_size1_mode0 = 0x45;
-		pdb->ssc_step_size2_mode0 = 0x06;
+		pdb->rate_idx = HSCLK_RATE_2700MHZ;
 		break;
 	case DP_VCO_HSCLK_RATE_5400MHZDIV1000:
 		DP_DEBUG("VCO rate: %ld\n", DP_VCO_RATE_10800MHZDIV1000);
-		pdb->hsclk_sel = 0x01;
-		pdb->dec_start_mode0 = 0x8c;
-		pdb->div_frac_start2_mode0 = 0x00;
-		pdb->div_frac_start3_mode0 = 0x0a;
-		pdb->lock_cmp1_mode0 = 0x1f;
-		pdb->lock_cmp2_mode0 = 0x1c;
-		pdb->phy_vco_div = 0x2;
-		pdb->lock_cmp_en = 0x08;
-		pdb->ssc_step_size1_mode0 = 0x5c;
-		pdb->ssc_step_size2_mode0 = 0x08;
+		pdb->rate_idx = HSCLK_RATE_5400MHZ;
 		break;
 	case DP_VCO_HSCLK_RATE_8100MHZDIV1000:
 		DP_DEBUG("VCO rate: %ld\n", DP_VCO_RATE_8100MHZDIV1000);
-		pdb->hsclk_sel = 0x00;
-		pdb->dec_start_mode0 = 0x69;
-		pdb->div_frac_start2_mode0 = 0x80;
-		pdb->div_frac_start3_mode0 = 0x07;
-		pdb->lock_cmp1_mode0 = 0x2f;
-		pdb->lock_cmp2_mode0 = 0x2a;
-		pdb->phy_vco_div = 0x0;
-		pdb->lock_cmp_en = 0x08;
-		pdb->ssc_step_size1_mode0 = 0x45;
-		pdb->ssc_step_size2_mode0 = 0x06;
+		pdb->rate_idx = HSCLK_RATE_8100MHZ;
 		break;
 	default:
 		DP_ERR("unsupported rate %ld\n", rate);
@@ -260,6 +231,7 @@ static int dp_config_vco_rate_5nm(struct dp_pll *pll,
 {
 	int rc = 0;
 	struct dp_pll_db *pdb = (struct dp_pll_db *)pll->priv;
+	const struct dp_pll_params *params;
 
 	rc = dp_vco_pll_init_db_5nm(pdb, rate);
 	if (rc < 0) {
@@ -281,6 +253,13 @@ static int dp_config_vco_rate_5nm(struct dp_pll *pll,
 	/* Make sure the PHY register writes are done */
 	wmb();
 
+	if (pdb->rate_idx < HSCLK_RATE_MAX) {
+		params = &pdb->pll_params[pdb->rate_idx];
+	} else {
+		DP_ERR("link rate not set\n");
+		return -EINVAL;
+	}
+
 	dp_pll_write(dp_pll, QSERDES_COM_SVS_MODE_CLK_SEL, 0x05);
 	dp_pll_write(dp_pll, QSERDES_COM_SYSCLK_EN_SEL, 0x3b);
 	dp_pll_write(dp_pll, QSERDES_COM_SYS_CLK_CTRL, 0x02);
@@ -291,7 +270,7 @@ static int dp_config_vco_rate_5nm(struct dp_pll *pll,
 	wmb();
 
 	/* PLL Optimization */
-	dp_pll_write(dp_pll, QSERDES_COM_PLL_IVCO, 0x0f);
+	dp_pll_write(dp_pll, QSERDES_COM_PLL_IVCO, params->pll_ivco);
 	dp_pll_write(dp_pll, QSERDES_COM_PLL_CCTRL_MODE0, 0x36);
 	dp_pll_write(dp_pll, QSERDES_COM_PLL_RCTRL_MODE0, 0x16);
 	dp_pll_write(dp_pll, QSERDES_COM_CP_CTRL_MODE0, 0x06);
@@ -299,48 +278,50 @@ static int dp_config_vco_rate_5nm(struct dp_pll *pll,
 	wmb();
 
 	/* link rate dependent params */
-	dp_pll_write(dp_pll, QSERDES_COM_HSCLK_SEL, pdb->hsclk_sel);
-	dp_pll_write(dp_pll, QSERDES_COM_DEC_START_MODE0, pdb->dec_start_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_HSCLK_SEL, params->hsclk_sel);
+	dp_pll_write(dp_pll, QSERDES_COM_DEC_START_MODE0, params->dec_start_mode0);
 	dp_pll_write(dp_pll,
-		QSERDES_COM_DIV_FRAC_START1_MODE0, pdb->div_frac_start1_mode0);
+		QSERDES_COM_DIV_FRAC_START1_MODE0, params->div_frac_start1_mode0);
 	dp_pll_write(dp_pll,
-		QSERDES_COM_DIV_FRAC_START2_MODE0, pdb->div_frac_start2_mode0);
+		QSERDES_COM_DIV_FRAC_START2_MODE0, params->div_frac_start2_mode0);
 	dp_pll_write(dp_pll,
-		QSERDES_COM_DIV_FRAC_START3_MODE0, pdb->div_frac_start3_mode0);
-	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP1_MODE0, pdb->lock_cmp1_mode0);
-	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP2_MODE0, pdb->lock_cmp2_mode0);
-	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP_EN, pdb->lock_cmp_en);
-	dp_pll_write(dp_phy, DP_PHY_VCO_DIV, pdb->phy_vco_div);
+		QSERDES_COM_DIV_FRAC_START3_MODE0, params->div_frac_start3_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP1_MODE0, params->lock_cmp1_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP2_MODE0, params->lock_cmp2_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_LOCK_CMP_EN, params->lock_cmp_en);
+	dp_pll_write(dp_phy, DP_PHY_VCO_DIV, params->phy_vco_div);
 	/* Make sure the PLL register writes are done */
 	wmb();
 
 	dp_pll_write(dp_pll, QSERDES_COM_CMN_CONFIG, 0x02);
-	dp_pll_write(dp_pll, QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x3f);
-	dp_pll_write(dp_pll, QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00);
+	dp_pll_write(dp_pll, QSERDES_COM_INTEGLOOP_GAIN0_MODE0,
+		params->integloop_gain0_mode0);
+	dp_pll_write(dp_pll, QSERDES_COM_INTEGLOOP_GAIN1_MODE0,
+	params->integloop_gain1_mode0);
 	dp_pll_write(dp_pll, QSERDES_COM_VCO_TUNE_MAP, 0x00);
 	/* Make sure the PHY register writes are done */
 	wmb();
 
-	dp_pll_write(dp_pll, QSERDES_COM_BG_TIMER, 0x0a);
+	dp_pll_write(dp_pll, QSERDES_COM_BG_TIMER, params->bg_timer);
 	dp_pll_write(dp_pll, QSERDES_COM_CORECLK_DIV_MODE0, 0x0a);
 	dp_pll_write(dp_pll, QSERDES_COM_VCO_TUNE_CTRL, 0x00);
 	if (pll->bonding_en)
 		dp_pll_write(dp_pll, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1f);
 	else
 		dp_pll_write(dp_pll, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x17);
-	dp_pll_write(dp_pll, QSERDES_COM_CORE_CLK_EN, 0x1f);
+	dp_pll_write(dp_pll, QSERDES_COM_CORE_CLK_EN, params->core_clk_en);
 	/* Make sure the PHY register writes are done */
 	wmb();
 
 	if (pll->ssc_en) {
 		dp_pll_write(dp_pll, QSERDES_COM_SSC_EN_CENTER, 0x01);
 		dp_pll_write(dp_pll, QSERDES_COM_SSC_ADJ_PER1, 0x00);
-		dp_pll_write(dp_pll, QSERDES_COM_SSC_PER1, 0x36);
-		dp_pll_write(dp_pll, QSERDES_COM_SSC_PER2, 0x01);
+		dp_pll_write(dp_pll, QSERDES_COM_SSC_PER1, params->ssc_per1);
+		dp_pll_write(dp_pll, QSERDES_COM_SSC_PER2, params->ssc_per1);
 		dp_pll_write(dp_pll, QSERDES_COM_SSC_STEP_SIZE1_MODE0,
-				pdb->ssc_step_size1_mode0);
+				params->ssc_step_size1_mode0);
 		dp_pll_write(dp_pll, QSERDES_COM_SSC_STEP_SIZE2_MODE0,
-				pdb->ssc_step_size2_mode0);
+				params->ssc_step_size2_mode0);
 	}
 
 	if (pdb->orientation == ORIENTATION_CC2)
@@ -363,8 +344,8 @@ static int dp_config_vco_rate_5nm(struct dp_pll *pll,
 	dp_pll_write(dp_ln_tx0, DP_TRAN_DRVR_EMP_EN, 0xf);
 	dp_pll_write(dp_ln_tx0, TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00);
 	dp_pll_write(dp_ln_tx0, DP_TX_INTERFACE_MODE, 0x00);
-	dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_TX, 0x0A);
-	dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_RX, 0x11);
+	dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_TX, params->lane_offset_tx);
+	dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_RX, params->lane_offset_rx);
 	dp_pll_write(dp_ln_tx0, TXn_TX_BAND, 0x04);
 	/* Make sure the PLL register writes are done */
 	wmb();
@@ -379,8 +360,8 @@ static int dp_config_vco_rate_5nm(struct dp_pll *pll,
 	dp_pll_write(dp_ln_tx1, DP_TRAN_DRVR_EMP_EN, 0xf);
 	dp_pll_write(dp_ln_tx1, TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00);
 	dp_pll_write(dp_ln_tx1, DP_TX_INTERFACE_MODE, 0x00);
-	dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_TX, 0x0A);
-	dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_RX, 0x11);
+	dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_TX, params->lane_offset_tx);
+	dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_RX, params->lane_offset_rx);
 	dp_pll_write(dp_ln_tx1, TXn_TX_BAND, 0x04);
 	/* Make sure the PHY register writes are done */
 	wmb();
@@ -864,6 +845,7 @@ int dp_pll_clock_register_5nm(struct dp_pll *pll)
 	pll->clk_data->clk_num = DP_PLL_NUM_CLKS;
 	pll->priv = &dp_pdb;
 	dp_pdb.pll = pll;
+	dp_pdb.pll_params = pll_params;
 
 	pll->pll_cfg = dp_pll_configure;
 	pll->pll_prepare = dp_pll_prepare;