diff --git a/msm/dp/dp_catalog_v420.c b/msm/dp/dp_catalog_v420.c index c611f315..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; \ @@ -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; - 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; @@ -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]; 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 b29a789e..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 @@ -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(); 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