From 280c93b7290615d058a5b1817704826e3125e382 Mon Sep 17 00:00:00 2001 From: Vara Reddy Date: Sun, 30 Jan 2022 03:57:27 -0500 Subject: [PATCH 1/2] disp: msm: dp: PHY config update to align with kalama HPG Swing/Pre-emph, SSC, and CLKBUFLR values updated to match latest changes as per kalama HPG. Change-Id: Iae96b38f0f8c39280081ae43b41f73ea10f6ddb7 Signed-off-by: Sandeep Gangadharaiah Signed-off-by: Vara Reddy --- msm/dp/dp_catalog_v420.c | 14 +++++- msm/dp/dp_pll_4nm.c | 97 +++++++++++++++++++--------------------- 2 files changed, 60 insertions(+), 51 deletions(-) diff --git a/msm/dp/dp_catalog_v420.c b/msm/dp/dp_catalog_v420.c index c611f315..6cdb81c3 100644 --- a/msm/dp/dp_catalog_v420.c +++ b/msm/dp/dp_catalog_v420.c @@ -79,6 +79,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; @@ -269,6 +276,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 +287,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 +302,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]; diff --git a/msm/dp/dp_pll_4nm.c b/msm/dp/dp_pll_4nm.c index b29a789e..50c3e7c9 100644 --- a/msm/dp/dp_pll_4nm.c +++ b/msm/dp/dp_pll_4nm.c @@ -213,66 +213,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 +317,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 +347,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 +363,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 +390,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 +406,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(); From 7230476c9cd0f17a14cfc8e0998b8fdc2ac3455a Mon Sep 17 00:00:00 2001 From: Vara Reddy Date: Fri, 25 Feb 2022 14:32:12 -0800 Subject: [PATCH 2/2] disp: msm: dp: calculate mvid and nvid dividers with in DP driver Change removes the dependency of reading MVID and NVID settings from dispcc registers and calculates the values locally in displayport driver. Change-Id: I9ad66aea44a3cbc0f739060c49e23d389022a48a Signed-off-by: Vara Reddy --- msm/dp/dp_catalog_v420.c | 59 ++++++++++++++++++++-------------------- msm/dp/dp_pll.h | 2 ++ msm/dp/dp_pll_4nm.c | 1 - msm/dp/dp_pll_5nm.c | 1 - 4 files changed, 31 insertions(+), 32 deletions(-) diff --git a/msm/dp/dp_catalog_v420.c b/msm/dp/dp_catalog_v420.c index 6cdb81c3..9b5466d7 100644 --- a/msm/dp/dp_catalog_v420.c +++ b/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 #define dp_catalog_get_priv_v420(x) ({ \ struct dp_catalog *catalog; \ @@ -169,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"); @@ -192,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; - 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); + rational_best_approximation(rate_vco_div, (stream_rate_khz / 2), + (unsigned long)(1 << 16) - 1, + (unsigned long)(1 << 16) - 1, &den, &num); - mvid = (pixel_m & 0xFFFF) * 5; - nvid = (0xFFFF & (~pixel_n)) + (pixel_m & 0xFFFF); + den = ~(den - num); + den = den & 0xFFFF; + + mvid = (num & 0xFFFF) * 5; + nvid = (0xFFFF & (~den)) + (num & 0xFFFF); if (nvid < nvid_fixed) { u32 temp; diff --git a/msm/dp/dp_pll.h b/msm/dp/dp_pll.h index 46825cbd..e0cd6f34 100644 --- a/msm/dp/dp_pll.h +++ b/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 diff --git a/msm/dp/dp_pll_4nm.c b/msm/dp/dp_pll_4nm.c index 50c3e7c9..a708583f 100644 --- a/msm/dp/dp_pll_4nm.c +++ b/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 diff --git a/msm/dp/dp_pll_5nm.c b/msm/dp/dp_pll_5nm.c index 96a91291..fc36c95f 100644 --- a/msm/dp/dp_pll_5nm.c +++ b/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