Explorar o código

Merge "disp: msm: dp: calculate mvid and nvid dividers with in DP driver"

qctecmdr %!s(int64=3) %!d(string=hai) anos
pai
achega
61629fb92f
Modificáronse 4 ficheiros con 91 adicións e 83 borrados
  1. 42 31
      msm/dp/dp_catalog_v420.c
  2. 2 0
      msm/dp/dp_pll.h
  3. 47 51
      msm/dp/dp_pll_4nm.c
  4. 0 1
      msm/dp/dp_pll_5nm.c

+ 42 - 31
msm/dp/dp_catalog_v420.c

@@ -1,22 +1,15 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 
 #include "dp_catalog.h"
 #include "dp_reg.h"
 #include "dp_debug.h"
-
-#define MMSS_DP_PIXEL_BASE_V130			(0x1A8)
-#define MMSS_DP_PIXEL1_BASE_V130		(0x1C0)
-
-#define MMSS_DP_PIXEL_BASE_V140			(0x1BC)
-#define MMSS_DP_PIXEL1_BASE_V140		(0x1D4)
-
-#define MMSS_DP_M_OFF				(0x8)
-#define MMSS_DP_N_OFF				(0xC)
+#include "dp_pll.h"
+#include <linux/rational.h>
 
 #define dp_catalog_get_priv_v420(x) ({ \
 	struct dp_catalog *catalog; \
@@ -79,6 +72,13 @@ static u8 const dp_swing_hbr_rbr[MAX_VOLTAGE_LEVELS][MAX_PRE_EMP_LEVELS] = {
 	{0x1F, 0xFF, 0xFF, 0xFF}  /* sw1, 1.2v */
 };
 
+static const u8 dp_pre_emp_hbr_rbr_v600[MAX_VOLTAGE_LEVELS][MAX_PRE_EMP_LEVELS] = {
+	{0x00, 0x0D, 0x14, 0x1A}, /* pe0, 0 db */
+	{0x00, 0x0D, 0x15, 0xFF}, /* pe1, 3.5 db */
+	{0x00, 0x0E, 0xFF, 0xFF}, /* pe2, 6.0 db */
+	{0x04, 0xFF, 0xFF, 0xFF}  /* pe3, 9.5 db */
+};
+
 struct dp_catalog_private_v420 {
 	struct device *dev;
 	struct dp_catalog_sub sub;
@@ -162,15 +162,15 @@ static void dp_catalog_aux_clear_hw_int_v420(struct dp_catalog_aux *aux)
 static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel,
 					u32 rate, u32 stream_rate_khz)
 {
-	u32 pixel_m, pixel_n;
-	u32 mvid, nvid, reg_off = 0, mvid_off = 0, nvid_off = 0;
+	u32 mvid, nvid, mvid_off = 0, nvid_off = 0;
+	u32 div, pixel_div = 0, rate_vco_div = 0;
 	u32 const nvid_fixed = 0x8000;
 	u32 const link_rate_hbr2 = 540000;
 	u32 const link_rate_hbr3 = 810000;
 	struct dp_catalog *dp_catalog;
 	struct dp_catalog_private_v420 *catalog;
 	struct dp_io_data *io_data;
-	u32 version;
+	unsigned long num, den;
 
 	if (!panel || !rate) {
 		DP_ERR("invalid input\n");
@@ -185,28 +185,34 @@ static void dp_catalog_panel_config_msa_v420(struct dp_catalog_panel *panel,
 	dp_catalog = container_of(panel, struct dp_catalog, panel);
 	catalog = container_of(dp_catalog->sub, struct dp_catalog_private_v420, sub);
 
-	version = dp_catalog_get_dp_core_version(dp_catalog);
-	io_data = catalog->io->dp_mmss_cc;
+	io_data = catalog->io->dp_pll;
+	div = dp_read(DP_PHY_VCO_DIV);
 
-	if (version >= 0x10040000) {
-		if (panel->stream_id == DP_STREAM_1)
-			reg_off = MMSS_DP_PIXEL1_BASE_V140;
-		else
-			reg_off = MMSS_DP_PIXEL_BASE_V140;
-	} else {
-		if (panel->stream_id == DP_STREAM_1)
-			reg_off = MMSS_DP_PIXEL1_BASE_V130;
-		else
-			reg_off = MMSS_DP_PIXEL_BASE_V130;
+	div &= 0x03;
+
+	if (div == 0)
+		pixel_div = 6;
+	else if (div == 1)
+		pixel_div = 2;
+	else if (div == 2)
+		pixel_div = 4;
+
+	if (!pixel_div) {
+		DP_ERR("Invalid pixel mux divider, not setting software mvid and nvid\n");
+		return;
 	}
 
+	rate_vco_div = (rate * 10) / pixel_div;
+
+	rational_best_approximation(rate_vco_div, (stream_rate_khz / 2),
+			(unsigned long)(1 << 16) - 1,
+			(unsigned long)(1 << 16) - 1, &den, &num);
 
-	pixel_m = dp_read(reg_off + MMSS_DP_M_OFF);
-	pixel_n = dp_read(reg_off + MMSS_DP_N_OFF);
-	DP_DEBUG("pixel_m=0x%x, pixel_n=0x%x\n", pixel_m, pixel_n);
+	den = ~(den - num);
+	den = den & 0xFFFF;
 
-	mvid = (pixel_m & 0xFFFF) * 5;
-	nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF);
+	mvid = (num & 0xFFFF) * 5;
+	nvid = (0xFFFF & (~den)) + (num & 0xFFFF);
 
 	if (nvid < nvid_fixed) {
 		u32 temp;
@@ -269,6 +275,7 @@ static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,
 	struct dp_io_data *io_data;
 	u8 value0, value1;
 	u32 version;
+	u32 phy_version;
 
 	if (!ctrl || !((v_level < MAX_VOLTAGE_LEVELS)
 		&& (p_level < MAX_PRE_EMP_LEVELS))) {
@@ -279,6 +286,7 @@ static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,
 	DP_DEBUG("hw: v=%d p=%d, high=%d\n", v_level, p_level, high);
 
 	catalog = dp_catalog_get_priv_v420(ctrl);
+	phy_version = dp_catalog_get_dp_phy_version(catalog->dpc);
 
 	io_data = catalog->io->dp_ahb;
 	version = dp_read(DP_HW_VERSION);
@@ -293,7 +301,10 @@ static void dp_catalog_ctrl_update_vx_px_v420(struct dp_catalog_ctrl *ctrl,
 			value1 = dp_pre_emp_hbr2_hbr3[v_level][p_level];
 		} else {
 			value0 = dp_swing_hbr_rbr[v_level][p_level];
-			value1 = dp_pre_emp_hbr_rbr[v_level][p_level];
+			if (phy_version >= 0x60000000)
+				value1 = dp_pre_emp_hbr_rbr_v600[v_level][p_level];
+			else
+				value1 = dp_pre_emp_hbr_rbr[v_level][p_level];
 		}
 	} else {
 		value0 = vm_voltage_swing[v_level][p_level];

+ 2 - 0
msm/dp/dp_pll.h

@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -16,6 +17,7 @@
 #define DP_VCO_HSCLK_RATE_2700MHZDIV1000	2700000UL
 #define DP_VCO_HSCLK_RATE_5400MHZDIV1000	5400000UL
 #define DP_VCO_HSCLK_RATE_8100MHZDIV1000	8100000UL
+#define DP_PHY_VCO_DIV				0x0070
 
 #define dp_pll_get_base(x) pll->io.x->io.base
 

+ 47 - 51
msm/dp/dp_pll_4nm.c

@@ -36,7 +36,6 @@
 #define DP_PHY_AUX_CFG1				0x0024
 #define DP_PHY_AUX_CFG2				0x0028
 
-#define DP_PHY_VCO_DIV				0x0070
 #define DP_PHY_TX0_TX1_LANE_CTL			0x0078
 #define DP_PHY_TX2_TX3_LANE_CTL			0x009C
 
@@ -213,66 +212,66 @@ static int dp_vco_pll_init_db_4nm(struct dp_pll_db *pdb,
 	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->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 = 0x45;
-		pdb->ssc_step_size2_mode0 = 0x06;
-		pdb->ssc_per1 = 0x36;
-		pdb->cmp_code1_mode0 = 0xE2;
-		pdb->cmp_code2_mode0 = 0x18;
+		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;
 		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->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 = 0x45;
-		pdb->ssc_step_size2_mode0 = 0x06;
-		pdb->ssc_per1 = 0x36;
-		pdb->cmp_code1_mode0 = 0xE2;
-		pdb->cmp_code2_mode0 = 0x18;
+		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;
 		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->dec_start_mode0 = 0x46;
 		pdb->div_frac_start2_mode0 = 0x00;
-		pdb->div_frac_start3_mode0 = 0x0a;
-		pdb->lock_cmp1_mode0 = 0x1f;
-		pdb->lock_cmp2_mode0 = 0x1c;
+		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 = 0x5C;
-		pdb->ssc_step_size2_mode0 = 0x08;
-		pdb->ssc_per1 = 0x36;
-		pdb->cmp_code1_mode0 = 0x2E;
-		pdb->cmp_code2_mode0 = 0x21;
+		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;
 		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->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 = 0x45;
-		pdb->ssc_step_size2_mode0 = 0x06;
-		pdb->ssc_per1 = 0x36;
-		pdb->cmp_code1_mode0 = 0xE2;
-		pdb->cmp_code2_mode0 = 0x18;
+		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;
 		break;
 	default:
 		DP_ERR("unsupported rate %ld\n", rate);
@@ -317,7 +316,7 @@ static int dp_config_vco_rate_4nm(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, 0x07);
 	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);
@@ -347,14 +346,11 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll,
 	/* Make sure the PHY register writes are done */
 	wmb();
 
-	dp_pll_write(dp_pll, QSERDES_COM_BG_TIMER, 0x0e);
+	dp_pll_write(dp_pll, QSERDES_COM_BG_TIMER, 0x0a);
 	dp_pll_write(dp_pll, QSERDES_COM_CORECLK_DIV_MODE0, 0x14);
 	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_BIAS_EN_CLKBUFLR_EN, 0x1f);
 
 	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);
@@ -366,7 +362,7 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll,
 		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, 0x01);
+		dp_pll_write(dp_pll, QSERDES_COM_SSC_PER2, 0x02);
 		dp_pll_write(dp_pll, QSERDES_COM_SSC_STEP_SIZE1_MODE0,
 				pdb->ssc_step_size1_mode0);
 		dp_pll_write(dp_pll, QSERDES_COM_SSC_STEP_SIZE2_MODE0,
@@ -393,8 +389,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, 0x0C);
-	dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_RX, 0x0C);
+	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_TX_BAND, 0x04);
 	/* Make sure the PLL register writes are done */
 	wmb();
@@ -409,8 +405,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, 0x0C);
-	dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_RX, 0x0C);
+	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_TX_BAND, 0x04);
 	/* Make sure the PHY register writes are done */
 	wmb();

+ 0 - 1
msm/dp/dp_pll_5nm.c

@@ -37,7 +37,6 @@
 #define DP_PHY_AUX_CFG1				0x0024
 #define DP_PHY_AUX_CFG2				0x0028
 
-#define DP_PHY_VCO_DIV				0x0070
 #define DP_PHY_TX0_TX1_LANE_CTL			0x0078
 #define DP_PHY_TX2_TX3_LANE_CTL			0x009C