summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/qcom/msmcobalt.dtsi4
-rw-r--r--drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c376
-rw-r--r--drivers/clk/msm/mdss/mdss-dp-pll-cobalt.c153
-rw-r--r--drivers/clk/msm/mdss/mdss-dp-pll-cobalt.h12
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c8
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_util.c6
-rw-r--r--include/dt-bindings/clock/msm-clocks-cobalt.h7
7 files changed, 296 insertions, 270 deletions
diff --git a/arch/arm/boot/dts/qcom/msmcobalt.dtsi b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
index 9a5de9526c19..71a1608f09a9 100644
--- a/arch/arm/boot/dts/qcom/msmcobalt.dtsi
+++ b/arch/arm/boot/dts/qcom/msmcobalt.dtsi
@@ -755,8 +755,8 @@
<&mdss_dsi1_pll clk_dsi1pll_pclk_mux>,
<&mdss_dsi0_pll clk_dsi0pll_byteclk_mux>,
<&mdss_dsi1_pll clk_dsi1pll_byteclk_mux>,
- <&mdss_dp_pll clk_dp_link_2x_clk_mux>,
- <&mdss_dp_pll clk_vco_divided_clk_src>,
+ <&mdss_dp_pll clk_dp_link_2x_clk_divsel_five>,
+ <&mdss_dp_pll clk_vco_divided_clk_src_mux>,
<&mdss_hdmi_pll clk_hdmi_vco_clk>;
#clock-cells = <1>;
};
diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
index 123a5ae09fa8..c88a5089bd60 100644
--- a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
+++ b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt-util.c
@@ -49,13 +49,8 @@ int link2xclk_divsel_set_div(struct div_clk *clk, int div)
link2xclk_div_tx1 |= 0x4;
/*configure DP PHY MODE */
- phy_mode = 0x48;
+ phy_mode = 0x58;
- if (div == 10) {
- link2xclk_div_tx0 |= 1;
- link2xclk_div_tx1 |= 1;
- phy_mode |= 1;
- }
MDSS_PLL_REG_W(dp_res->phy_base,
QSERDES_TX0_OFFSET + TXn_TX_BAND,
link2xclk_div_tx0);
@@ -64,7 +59,8 @@ int link2xclk_divsel_set_div(struct div_clk *clk, int div)
link2xclk_div_tx1);
MDSS_PLL_REG_W(dp_res->phy_base,
DP_PHY_MODE, phy_mode);
-
+ /* Make sure the PHY register writes are done */
+ wmb();
pr_debug("%s: div=%d link2xclk_div_tx0=%x, link2xclk_div_tx1=%x\n",
__func__, div, link2xclk_div_tx0, link2xclk_div_tx1);
@@ -105,63 +101,6 @@ int link2xclk_divsel_get_div(struct div_clk *clk)
return div;
}
-int hsclk_divsel_set_div(struct div_clk *clk, int div)
-{
- int rc;
- u32 hsclk_div;
- struct mdss_pll_resources *dp_res = clk->priv;
-
- rc = mdss_pll_resource_enable(dp_res, true);
- if (rc) {
- pr_err("Failed to enable mdss DP PLL resources\n");
- return rc;
- }
-
- hsclk_div = MDSS_PLL_REG_R(dp_res->pll_base, QSERDES_COM_HSCLK_SEL);
- hsclk_div &= ~0x0f; /* bits 0 to 3 */
-
- if (div == 3)
- hsclk_div |= 4;
- else
- hsclk_div |= 0;
-
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_HSCLK_SEL, hsclk_div);
-
- pr_debug("%s: div=%d hsclk_div=%x\n", __func__, div, hsclk_div);
-
- mdss_pll_resource_enable(dp_res, false);
-
- return rc;
-}
-
-int hsclk_divsel_get_div(struct div_clk *clk)
-{
- int rc;
- u32 hsclk_div, div;
- struct mdss_pll_resources *dp_res = clk->priv;
-
- rc = mdss_pll_resource_enable(dp_res, true);
- if (rc) {
- pr_err("Failed to enable dp_res resources\n");
- return rc;
- }
-
- hsclk_div = MDSS_PLL_REG_R(dp_res->pll_base, QSERDES_COM_HSCLK_SEL);
- hsclk_div &= 0x0f;
-
- if (hsclk_div == 4)
- div = 3;
- else
- div = 2;
-
- mdss_pll_resource_enable(dp_res, false);
-
- pr_debug("%s: hsclk_div:%d, div=%d\n", __func__, hsclk_div, div);
-
- return div;
-}
-
int vco_divided_clk_set_div(struct div_clk *clk, int div)
{
int rc;
@@ -174,18 +113,18 @@ int vco_divided_clk_set_div(struct div_clk *clk, int div)
return rc;
}
- auxclk_div = MDSS_PLL_REG_R(dp_res->pll_base, DP_PHY_VCO_DIV);
+ auxclk_div = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_VCO_DIV);
auxclk_div &= ~0x03; /* bits 0 to 1 */
+
+ auxclk_div |= 1; /* Default divider */
+
if (div == 4)
auxclk_div |= 2;
- else if (div == 2)
- auxclk_div |= 1;
- else
- auxclk_div |= 2; /* Default divider */
- MDSS_PLL_REG_W(dp_res->pll_base,
+ MDSS_PLL_REG_W(dp_res->phy_base,
DP_PHY_VCO_DIV, auxclk_div);
-
+ /* Make sure the PHY registers writes are done */
+ wmb();
pr_debug("%s: div=%d auxclk_div=%x\n", __func__, div, auxclk_div);
mdss_pll_resource_enable(dp_res, false);
@@ -215,15 +154,12 @@ int vco_divided_clk_get_div(struct div_clk *clk)
return rc;
}
- auxclk_div = MDSS_PLL_REG_R(dp_res->pll_base, DP_PHY_VCO_DIV);
+ auxclk_div = MDSS_PLL_REG_R(dp_res->phy_base, DP_PHY_VCO_DIV);
auxclk_div &= 0x03;
+ div = 2; /* Default divider */
if (auxclk_div == 2)
div = 4;
- else if (auxclk_div == 1)
- div = 2;
- else
- div = 0;
mdss_pll_resource_enable(dp_res, false);
@@ -239,14 +175,12 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate)
MDSS_PLL_REG_W(dp_res->phy_base,
DP_PHY_PD_CTL, 0x3d);
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_PLL_IVCO, 0x0f);
+ /* Make sure the PHY register writes are done */
+ wmb();
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_SVS_MODE_CLK_SEL, 0x01);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_SYSCLK_EN_SEL, 0x37);
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_SYS_CLK_CTRL, 0x06);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_CLK_ENABLE1, 0x0e);
@@ -255,16 +189,16 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate)
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_CLK_SEL, 0x30);
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_LOCK_CMP_EN, 0x00);
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_PLL_CCTRL_MODE0, 0x34);
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_PLL_RCTRL_MODE0, 0x16);
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_CP_CTRL_MODE0, 0x08);
/* Different for each clock rates */
- if (rate == DP_VCO_RATE_8100MHz) {
+ if (rate == DP_VCO_HSCLK_RATE_1620MHz) {
+ pr_debug("%s: VCO rate: %lld\n", __func__,
+ DP_VCO_RATE_8100MHz);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_SYS_CLK_CTRL, 0x02);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_HSCLK_SEL, 0x2c);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_LOCK_CMP_EN, 0x04);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_DEC_START_MODE0, 0x69);
MDSS_PLL_REG_W(dp_res->pll_base,
@@ -273,58 +207,88 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate)
QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07);
- } else if (rate == DP_VCO_RATE_9720MHz) {
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_DEC_START_MODE0, 0x7e);
+ QSERDES_COM_CMN_CONFIG, 0x42);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00);
+ QSERDES_COM_LOCK_CMP1_MODE0, 0xbf);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00);
+ QSERDES_COM_LOCK_CMP2_MODE0, 0x21);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_DIV_FRAC_START3_MODE0, 0x09);
- } else if (rate == DP_VCO_RATE_10800MHz) {
+ QSERDES_COM_LOCK_CMP3_MODE0, 0x00);
+ } else if (rate == DP_VCO_HSCLK_RATE_2700MHz) {
+ pr_debug("%s: VCO rate: %lld\n", __func__,
+ DP_VCO_RATE_8100MHz);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_DEC_START_MODE0, 0x8c);
+ QSERDES_COM_SYS_CLK_CTRL, 0x06);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_HSCLK_SEL, 0x84);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_LOCK_CMP_EN, 0x08);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_DEC_START_MODE0, 0x69);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00);
+ QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_DIV_FRAC_START3_MODE0, 0x0a);
- } else {
- pr_err("%s: unsupported rate: %ld\n", __func__, rate);
- return -EINVAL;
- }
-
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x3f);
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00);
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_VCO_TUNE_MAP, 0x00);
-
- if (rate == DP_VCO_RATE_8100MHz) {
+ QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_CMN_CONFIG, 0x02);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_LOCK_CMP1_MODE0, 0x3f);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_LOCK_CMP2_MODE0, 0x38);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_LOCK_CMP3_MODE0, 0x00);
- } else if (rate == DP_VCO_RATE_9720MHz) {
+ } else if (rate == DP_VCO_HSCLK_RATE_5400MHz) {
+ pr_debug("%s: VCO rate: %lld\n", __func__,
+ DP_VCO_RATE_10800MHz);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_LOCK_CMP1_MODE0, 0x7f);
+ QSERDES_COM_SYS_CLK_CTRL, 0x06);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_LOCK_CMP2_MODE0, 0x43);
+ QSERDES_COM_HSCLK_SEL, 0x80);
MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_LOCK_CMP3_MODE0, 0x00);
- } else {
+ QSERDES_COM_LOCK_CMP_EN, 0x08);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_DEC_START_MODE0, 0x8c);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_DIV_FRAC_START3_MODE0, 0xa0);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_CMN_CONFIG, 0x12);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_LOCK_CMP1_MODE0, 0x7f);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_LOCK_CMP2_MODE0, 0x70);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_LOCK_CMP3_MODE0, 0x00);
+ } else {
+ pr_err("%s: unsupported rate: %ld\n", __func__, rate);
+ return -EINVAL;
+ }
+ /* Make sure the PLL register writes are done */
+ wmb();
+
+ if ((rate == DP_VCO_HSCLK_RATE_1620MHz)
+ || (rate == DP_VCO_HSCLK_RATE_2700MHz)) {
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ DP_PHY_VCO_DIV, 0x1);
+ } else {
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ DP_PHY_VCO_DIV, 0x2);
}
+ /* Make sure the PHY register writes are done */
+ wmb();
+
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x3f);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_VCO_TUNE_MAP, 0x00);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_BG_TIMER, 0x00);
@@ -335,58 +299,42 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate)
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_VCO_TUNE_CTRL, 0x00);
MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_CP_CTRL_MODE0, 0x06);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_PLL_CCTRL_MODE0, 0x36);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_PLL_RCTRL_MODE0, 0x16);
+ MDSS_PLL_REG_W(dp_res->pll_base,
+ QSERDES_COM_PLL_IVCO, 0x07);
+ MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x37);
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_CORE_CLK_EN, 0x0f);
- /* Different for each clock rate */
- if (rate == DP_VCO_RATE_8100MHz) {
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_CMN_CONFIG, 0x02);
- } else if (rate == DP_VCO_RATE_9720MHz) {
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_CMN_CONFIG, 0x02);
- } else {
- MDSS_PLL_REG_W(dp_res->pll_base,
- QSERDES_COM_CMN_CONFIG, 0x02);
- }
+ /* Make sure the PLL register writes are done */
+ wmb();
MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX0_OFFSET + TXn_TRANSCEIVER_BIAS_EN,
- 0x1a);
+ DP_PHY_MODE, 0x58);
MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX1_OFFSET + TXn_TRANSCEIVER_BIAS_EN,
- 0x1a);
- MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX0_OFFSET + TXn_HIGHZ_DRVR_EN,
- 0x00);
+ DP_PHY_TX0_TX1_LANE_CTL, 0x05);
MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX1_OFFSET + TXn_HIGHZ_DRVR_EN,
- 0x00);
+ DP_PHY_TX2_TX3_LANE_CTL, 0x05);
MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX0_OFFSET + TXn_TX_DRV_LVL,
- 0x38);
- MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX1_OFFSET + TXn_TX_DRV_LVL,
- 0x38);
- MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX0_OFFSET + TXn_TX_EMP_POST1_LVL,
- 0x2c);
+ QSERDES_TX0_OFFSET + TXn_TRANSCEIVER_BIAS_EN,
+ 0x1a);
MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX1_OFFSET + TXn_TX_EMP_POST1_LVL,
- 0x2c);
+ QSERDES_TX1_OFFSET + TXn_TRANSCEIVER_BIAS_EN,
+ 0x1a);
MDSS_PLL_REG_W(dp_res->phy_base,
- DP_PHY_TX0_TX1_LANE_CTL, 0x05);
- MDSS_PLL_REG_W(dp_res->phy_base,
- DP_PHY_TX2_TX3_LANE_CTL, 0x05);
- MDSS_PLL_REG_W(dp_res->phy_base,
QSERDES_TX0_OFFSET + TXn_VMODE_CTRL1,
0x40);
MDSS_PLL_REG_W(dp_res->phy_base,
QSERDES_TX1_OFFSET + TXn_VMODE_CTRL1,
0x40);
+
MDSS_PLL_REG_W(dp_res->phy_base,
QSERDES_TX0_OFFSET + TXn_PRE_STALL_LDO_BOOST_EN,
0x30);
@@ -429,6 +377,15 @@ int dp_config_vco_rate(struct dp_pll_vco_clk *vco, unsigned long rate)
MDSS_PLL_REG_W(dp_res->phy_base,
QSERDES_TX1_OFFSET + TXn_TX_INTERFACE_MODE,
0x00);
+
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX0_OFFSET + TXn_TX_BAND,
+ 0x4);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX1_OFFSET + TXn_TX_BAND,
+ 0x4);
+ /* Make sure the PHY register writes are done */
+ wmb();
return res;
}
@@ -479,9 +436,12 @@ static int dp_pll_enable(struct clk *c)
DP_PHY_CFG, 0x01);
MDSS_PLL_REG_W(dp_res->phy_base,
DP_PHY_CFG, 0x09);
+ /* Make sure the PHY register writes are done */
+ wmb();
MDSS_PLL_REG_W(dp_res->pll_base,
QSERDES_COM_RESETSM_CNTRL, 0x20);
-
+ /* Make sure the PLL register writes are done */
+ wmb();
/* poll for PLL ready status */
if (readl_poll_timeout_atomic((dp_res->pll_base +
QSERDES_COM_C_READY_STATUS),
@@ -497,7 +457,8 @@ static int dp_pll_enable(struct clk *c)
MDSS_PLL_REG_W(dp_res->phy_base,
DP_PHY_CFG, 0x19);
-
+ /* Make sure the PHY register writes are done */
+ wmb();
/* poll for PHY ready status */
if (readl_poll_timeout_atomic((dp_res->phy_base +
DP_PHY_STATUS),
@@ -514,16 +475,16 @@ static int dp_pll_enable(struct clk *c)
pr_debug("%s: PLL is locked\n", __func__);
MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX0_OFFSET + TXn_TRANSCEIVER_BIAS_EN,
- 0x3f);
- MDSS_PLL_REG_W(dp_res->phy_base,
QSERDES_TX1_OFFSET + TXn_TRANSCEIVER_BIAS_EN,
0x3f);
MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX0_OFFSET + TXn_HIGHZ_DRVR_EN,
+ QSERDES_TX1_OFFSET + TXn_HIGHZ_DRVR_EN,
0x10);
MDSS_PLL_REG_W(dp_res->phy_base,
- QSERDES_TX1_OFFSET + TXn_HIGHZ_DRVR_EN,
+ QSERDES_TX0_OFFSET + TXn_TRANSCEIVER_BIAS_EN,
+ 0x3f);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX0_OFFSET + TXn_HIGHZ_DRVR_EN,
0x10);
MDSS_PLL_REG_W(dp_res->phy_base,
QSERDES_TX0_OFFSET + TXn_TX_POL_INV,
@@ -533,6 +494,8 @@ static int dp_pll_enable(struct clk *c)
0x0a);
MDSS_PLL_REG_W(dp_res->phy_base,
DP_PHY_CFG, 0x18);
+ udelay(2000);
+
MDSS_PLL_REG_W(dp_res->phy_base,
DP_PHY_CFG, 0x19);
@@ -542,6 +505,77 @@ static int dp_pll_enable(struct clk *c)
*/
wmb();
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX0_OFFSET + TXn_LANE_MODE_1,
+ 0xf6);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX1_OFFSET + TXn_LANE_MODE_1,
+ 0xf6);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX0_OFFSET + TXn_CLKBUF_ENABLE,
+ 0x1f);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX1_OFFSET + TXn_CLKBUF_ENABLE,
+ 0x1f);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX0_OFFSET + TXn_CLKBUF_ENABLE,
+ 0x0f);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX1_OFFSET + TXn_CLKBUF_ENABLE,
+ 0x0f);
+ /*
+ * Make sure all the register writes are completed before
+ * doing any other operation
+ */
+ wmb();
+
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ DP_PHY_CFG, 0x09);
+ udelay(2000);
+
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ DP_PHY_CFG, 0x19);
+ udelay(2000);
+ /* poll for PHY ready status */
+ if (readl_poll_timeout_atomic((dp_res->phy_base +
+ DP_PHY_STATUS),
+ status,
+ ((status & BIT(1)) > 0),
+ DP_PLL_POLL_SLEEP_US,
+ DP_PLL_POLL_TIMEOUT_US)) {
+ pr_err("%s: Lane_mode: Phy_ready is not high. Status=%x\n",
+ __func__, status);
+ rc = -EINVAL;
+ goto lock_err;
+ }
+
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX0_OFFSET + TXn_TX_DRV_LVL,
+ 0x2a);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX1_OFFSET + TXn_TX_DRV_LVL,
+ 0x2a);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX0_OFFSET + TXn_TX_EMP_POST1_LVL,
+ 0x20);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX1_OFFSET + TXn_TX_EMP_POST1_LVL,
+ 0x20);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX0_OFFSET + TXn_RES_CODE_LANE_OFFSET_TX,
+ 0x11);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX1_OFFSET + TXn_RES_CODE_LANE_OFFSET_TX,
+ 0x11);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX0_OFFSET + TXn_RES_CODE_LANE_OFFSET_RX,
+ 0x11);
+ MDSS_PLL_REG_W(dp_res->phy_base,
+ QSERDES_TX1_OFFSET + TXn_RES_CODE_LANE_OFFSET_RX,
+ 0x11);
+ /* Make sure the PHY register writes are done */
+ wmb();
+
lock_err:
return rc;
}
@@ -554,7 +588,7 @@ static int dp_pll_disable(struct clk *c)
/* Assert DP PHY power down */
MDSS_PLL_REG_W(dp_res->phy_base,
- DP_PHY_PD_CTL, 0x3c);
+ DP_PHY_PD_CTL, 0x2);
/*
* Make sure all the register writes to disable PLL are
* completed before doing any other operation
@@ -655,14 +689,20 @@ unsigned long dp_vco_get_rate(struct clk *c)
div = MDSS_PLL_REG_R(pll->pll_base, QSERDES_COM_HSCLK_SEL);
div &= 0x0f;
- if (div == 4)
+ if (div == 12)
+ hsclk_div = 5; /* Default */
+ else if (div == 4)
hsclk_div = 3;
- else
+ else if (div == 0)
hsclk_div = 2;
+ else {
+ pr_debug("unknown divider. forcing to default\n");
+ hsclk_div = 5;
+ }
div = MDSS_PLL_REG_R(pll->phy_base, DP_PHY_MODE);
- if (div & 0x48)
+ if (div & 0x58)
pr_err("%s: DP PAR Rate not correct\n", __func__);
if ((div & 0x3) == 1)
@@ -673,12 +713,14 @@ unsigned long dp_vco_get_rate(struct clk *c)
pr_err("%s: unsupported div. Phy_mode: %d\n", __func__, div);
if (link2xclk_div == 10) {
- vco_rate = DP_VCO_RATE_9720MHz;
+ vco_rate = DP_VCO_HSCLK_RATE_2700MHz;
} else {
- if (hsclk_div == 3)
- vco_rate = DP_VCO_RATE_8100MHz;
+ if (hsclk_div == 5)
+ vco_rate = DP_VCO_HSCLK_RATE_1620MHz;
+ else if (hsclk_div == 3)
+ vco_rate = DP_VCO_HSCLK_RATE_2700MHz;
else
- vco_rate = DP_VCO_RATE_10800MHz;
+ vco_rate = DP_VCO_HSCLK_RATE_5400MHz;
}
pr_debug("returning vco rate = %lu\n", (unsigned long)vco_rate);
@@ -695,8 +737,8 @@ long dp_vco_round_rate(struct clk *c, unsigned long rate)
if (rate <= vco->min_rate)
rrate = vco->min_rate;
- else if (rate <= DP_VCO_RATE_9720MHz)
- rrate = DP_VCO_RATE_9720MHz;
+ else if (rate <= DP_VCO_HSCLK_RATE_2700MHz)
+ rrate = DP_VCO_HSCLK_RATE_2700MHz;
else
rrate = vco->max_rate;
diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.c b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.c
index 8b06f07b00ee..47b5bd7d7579 100644
--- a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.c
+++ b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.c
@@ -16,40 +16,37 @@
******** Display Port PLL driver block diagram for branch clocks **********
***************************************************************************
- +-------------------+
- | dp_vco_clk |
- | (DP PLL/VCO) |
- +---------+---------+
- |
- |
- v
- +----------+-----------+
- | hsclk_divsel_clk_src |
- +----------+-----------+
- |
+ +--------------------------+
+ | DP_VCO_CLK |
+ | |
+ | +-------------------+ |
+ | | (DP PLL/VCO) | |
+ | +---------+---------+ |
+ | v |
+ | +----------+-----------+ |
+ | | hsclk_divsel_clk_src | |
+ | +----------+-----------+ |
+ +--------------------------+
|
v
+------------<------------|------------>-------------+
| | |
- | | |
+----------v----------+ +----------v----------+ +----------v----------+
-|vco_divided_clk_src | | dp_link_2x_clk | | dp_link_2x_clk |
-| (aux_clk_ops) | | | | |
-v----------+----------v | divsel_five | | divsel_ten |
+| dp_link_2x_clk | | vco_divided_clk_src | | vco_divided_clk_src |
+| divsel_five | | | | |
+v----------+----------v | divsel_two | | divsel_four |
| +----------+----------+ +----------+----------+
| | |
v v v
- | +--------------------+ |
- Input to MMSSCC block | | | |
- for DP pixel clock +--> dp_link_2x_clk_mux <--+
- | |
- +----------+---------+
+ | +---------------------+ |
+ Input to MMSSCC block | | (aux_clk_ops) | |
+ for link clk, crypto clk +--> vco_divided_clk <-+
+ and interface clock | _src_mux |
+ +----------+----------+
|
v
Input to MMSSCC block
- for link clk, crypto clk
- and interface clock
-
+ for DP pixel clock
******************************************************************************
*/
@@ -68,14 +65,9 @@ v----------+----------v | divsel_five | | divsel_ten |
#include "mdss-dp-pll.h"
#include "mdss-dp-pll-cobalt.h"
-static struct clk_ops clk_ops_hsclk_divsel_clk_src_c;
static struct clk_ops clk_ops_vco_divided_clk_src_c;
static struct clk_ops clk_ops_link_2x_clk_div_c;
-
-static struct clk_div_ops hsclk_divsel_ops = {
- .set_div = hsclk_divsel_set_div,
- .get_div = hsclk_divsel_get_div,
-};
+static struct clk_ops clk_ops_gen_mux_dp;
static struct clk_div_ops link2xclk_divsel_ops = {
.set_div = link2xclk_divsel_set_div,
@@ -101,8 +93,8 @@ static struct clk_mux_ops mdss_mux_ops = {
};
static struct dp_pll_vco_clk dp_vco_clk = {
- .min_rate = DP_VCO_RATE_8100MHz,
- .max_rate = DP_VCO_RATE_10800MHz,
+ .min_rate = DP_VCO_HSCLK_RATE_1620MHz,
+ .max_rate = DP_VCO_HSCLK_RATE_5400MHz,
.c = {
.dbg_name = "dp_vco_clk",
.ops = &dp_cobalt_vco_clk_ops,
@@ -111,21 +103,6 @@ static struct dp_pll_vco_clk dp_vco_clk = {
},
};
-static struct div_clk hsclk_divsel_clk_src = {
- .data = {
- .min_div = 2,
- .max_div = 3,
- },
- .ops = &hsclk_divsel_ops,
- .c = {
- .parent = &dp_vco_clk.c,
- .dbg_name = "hsclk_divsel_clk_src",
- .ops = &clk_ops_hsclk_divsel_clk_src_c,
- .flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(hsclk_divsel_clk_src.c),
- },
-};
-
static struct div_clk dp_link_2x_clk_divsel_five = {
.data = {
.div = 5,
@@ -134,7 +111,7 @@ static struct div_clk dp_link_2x_clk_divsel_five = {
},
.ops = &link2xclk_divsel_ops,
.c = {
- .parent = &hsclk_divsel_clk_src.c,
+ .parent = &dp_vco_clk.c,
.dbg_name = "dp_link_2x_clk_divsel_five",
.ops = &clk_ops_link_2x_clk_div_c,
.flags = CLKFLAG_NO_RATE_CACHE,
@@ -142,61 +119,60 @@ static struct div_clk dp_link_2x_clk_divsel_five = {
},
};
-static struct div_clk dp_link_2x_clk_divsel_ten = {
+static struct div_clk vco_divsel_four_clk_src = {
.data = {
- .div = 10,
- .min_div = 10,
- .max_div = 10,
+ .div = 4,
+ .min_div = 4,
+ .max_div = 4,
},
- .ops = &link2xclk_divsel_ops,
+ .ops = &vco_divided_clk_ops,
.c = {
- .parent = &hsclk_divsel_clk_src.c,
- .dbg_name = "dp_link_2x_clk_divsel_ten",
- .ops = &clk_ops_link_2x_clk_div_c,
+ .parent = &dp_vco_clk.c,
+ .dbg_name = "vco_divsel_four_clk_src",
+ .ops = &clk_ops_vco_divided_clk_src_c,
.flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dp_link_2x_clk_divsel_ten.c),
+ CLK_INIT(vco_divsel_four_clk_src.c),
},
};
-static struct mux_clk dp_link_2x_clk_mux = {
- .num_parents = 2,
- .parents = (struct clk_src[]) {
- {&dp_link_2x_clk_divsel_five.c, 0},
- {&dp_link_2x_clk_divsel_ten.c, 1},
+static struct div_clk vco_divsel_two_clk_src = {
+ .data = {
+ .div = 2,
+ .min_div = 2,
+ .max_div = 2,
},
- .ops = &mdss_mux_ops,
+ .ops = &vco_divided_clk_ops,
.c = {
- .parent = &dp_link_2x_clk_divsel_five.c,
- .dbg_name = "dp_link_2x_clk_mux",
- .ops = &clk_ops_gen_mux,
+ .parent = &dp_vco_clk.c,
+ .dbg_name = "vco_divsel_two_clk_src",
+ .ops = &clk_ops_vco_divided_clk_src_c,
.flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(dp_link_2x_clk_mux.c),
- }
+ CLK_INIT(vco_divsel_two_clk_src.c),
+ },
};
-static struct div_clk vco_divided_clk_src = {
- .data = {
- .div = 4,
- .min_div = 4,
- .max_div = 4,
+static struct mux_clk vco_divided_clk_src_mux = {
+ .num_parents = 2,
+ .parents = (struct clk_src[]) {
+ {&vco_divsel_two_clk_src.c, 0},
+ {&vco_divsel_four_clk_src.c, 1},
},
- .ops = &vco_divided_clk_ops,
+ .ops = &mdss_mux_ops,
.c = {
- .parent = &hsclk_divsel_clk_src.c,
- .dbg_name = "vco_divided_clk",
- .ops = &clk_ops_vco_divided_clk_src_c,
+ .parent = &vco_divsel_two_clk_src.c,
+ .dbg_name = "vco_divided_clk_src_mux",
+ .ops = &clk_ops_gen_mux_dp,
.flags = CLKFLAG_NO_RATE_CACHE,
- CLK_INIT(vco_divided_clk_src.c),
- },
+ CLK_INIT(vco_divided_clk_src_mux.c),
+ }
};
static struct clk_lookup dp_pllcc_cobalt[] = {
CLK_LIST(dp_vco_clk),
- CLK_LIST(hsclk_divsel_clk_src),
CLK_LIST(dp_link_2x_clk_divsel_five),
- CLK_LIST(dp_link_2x_clk_divsel_ten),
- CLK_LIST(dp_link_2x_clk_mux),
- CLK_LIST(vco_divided_clk_src),
+ CLK_LIST(vco_divsel_four_clk_src),
+ CLK_LIST(vco_divsel_two_clk_src),
+ CLK_LIST(vco_divided_clk_src_mux),
};
int dp_pll_clock_register_cobalt(struct platform_device *pdev,
@@ -211,14 +187,10 @@ int dp_pll_clock_register_cobalt(struct platform_device *pdev,
/* Set client data for vco, mux and div clocks */
dp_vco_clk.priv = pll_res;
- hsclk_divsel_clk_src.priv = pll_res;
- dp_link_2x_clk_mux.priv = pll_res;
- vco_divided_clk_src.priv = pll_res;
+ vco_divided_clk_src_mux.priv = pll_res;
+ vco_divsel_two_clk_src.priv = pll_res;
+ vco_divsel_four_clk_src.priv = pll_res;
dp_link_2x_clk_divsel_five.priv = pll_res;
- dp_link_2x_clk_divsel_ten.priv = pll_res;
-
- clk_ops_hsclk_divsel_clk_src_c = clk_ops_div;
- clk_ops_hsclk_divsel_clk_src_c.prepare = mdss_pll_div_prepare;
clk_ops_link_2x_clk_div_c = clk_ops_div;
clk_ops_link_2x_clk_div_c.prepare = mdss_pll_div_prepare;
@@ -233,6 +205,9 @@ int dp_pll_clock_register_cobalt(struct platform_device *pdev,
clk_ops_vco_divided_clk_src_c.prepare = mdss_pll_div_prepare;
clk_ops_vco_divided_clk_src_c.handoff = vco_divided_clk_handoff;
+ clk_ops_gen_mux_dp = clk_ops_gen_mux;
+ clk_ops_gen_mux_dp.get_rate = parent_get_rate;
+
/* We can select different clock ops for future versions */
dp_vco_clk.c.ops = &dp_cobalt_vco_clk_ops;
diff --git a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.h b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.h
index 290933c0cbb4..d2b5d98a2d41 100644
--- a/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.h
+++ b/drivers/clk/msm/mdss/mdss-dp-pll-cobalt.h
@@ -59,12 +59,19 @@
#define TXn_SLEW_CNTL 0x0030
#define TXn_INTERFACE_SELECT 0x0034
+#define TXn_RES_CODE_LANE_TX 0x003C
+#define TXn_RES_CODE_LANE_RX 0x0040
+#define TXn_RES_CODE_LANE_OFFSET_TX 0x0044
+#define TXn_RES_CODE_LANE_OFFSET_RX 0x0048
+
#define TXn_DEBUG_BUS_SEL 0x0058
#define TXn_TRANSCEIVER_BIAS_EN 0x005C
#define TXn_HIGHZ_DRVR_EN 0x0060
#define TXn_TX_POL_INV 0x0064
#define TXn_PARRATE_REC_DETECT_IDLE_EN 0x0068
+#define TXn_LANE_MODE_1 0x008C
+
#define TXn_TRAN_DRVR_EMP_EN 0x00C0
#define TXn_TX_INTERFACE_MODE 0x00C4
@@ -149,9 +156,12 @@
#define DP_PLL_POLL_TIMEOUT_US 10000
#define DP_VCO_RATE_8100MHz 8100000000ULL
-#define DP_VCO_RATE_9720MHz 9720000000ULL
#define DP_VCO_RATE_10800MHz 10800000000ULL
+#define DP_VCO_HSCLK_RATE_1620MHz 1620000000ULL
+#define DP_VCO_HSCLK_RATE_2700MHz 2700000000ULL
+#define DP_VCO_HSCLK_RATE_5400MHz 5400000000ULL
+
int dp_vco_set_rate(struct clk *c, unsigned long rate);
unsigned long dp_vco_get_rate(struct clk *c);
long dp_vco_round_rate(struct clk *c, unsigned long rate);
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index fc24bb53a61c..0bbcd0c9041e 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -1109,16 +1109,16 @@ static void dp_host_train_set(struct mdss_dp_drv_pdata *ep, int train)
}
char vm_pre_emphasis[4][4] = {
- {0x03, 0x06, 0x09, 0x0C}, /* pe0, 0 db */
- {0x03, 0x06, 0x09, 0xFF}, /* pe1, 3.5 db */
+ {0x00, 0x06, 0x09, 0x0C}, /* pe0, 0 db */
+ {0x00, 0x06, 0x09, 0xFF}, /* pe1, 3.5 db */
{0x03, 0x06, 0xFF, 0xFF}, /* pe2, 6.0 db */
{0x03, 0xFF, 0xFF, 0xFF} /* pe3, 9.5 db */
};
/* voltage swing, 0.2v and 1.0v are not support */
char vm_voltage_swing[4][4] = {
- {0x14, 0x18, 0x1A, 0x1E}, /* sw0, 0.4v */
- {0x18, 0x1A, 0x1E, 0xFF}, /* sw1, 0.6 v */
+ {0x0a, 0x18, 0x1A, 0x1E}, /* sw0, 0.4v */
+ {0x07, 0x1A, 0x1E, 0xFF}, /* sw1, 0.6 v */
{0x1A, 0x1E, 0xFF, 0xFF}, /* sw1, 0.8 v */
{0x1E, 0xFF, 0xFF, 0xFF} /* sw1, 1.2 v, optional */
};
diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c
index c501ed3bcd9d..62b76199959c 100644
--- a/drivers/video/fbdev/msm/mdss_dp_util.c
+++ b/drivers/video/fbdev/msm/mdss_dp_util.c
@@ -246,13 +246,13 @@ void mdss_dp_ctrl_lane_mapping(struct dss_io_data *ctrl_io,
void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io)
{
writel_relaxed(0x3d, phy_io->base + DP_PHY_PD_CTL);
- writel_relaxed(0x03, phy_io->base + DP_PHY_AUX_CFG1);
- writel_relaxed(0x00, phy_io->base + DP_PHY_AUX_CFG3);
+ writel_relaxed(0x13, phy_io->base + DP_PHY_AUX_CFG1);
+ writel_relaxed(0x10, phy_io->base + DP_PHY_AUX_CFG3);
writel_relaxed(0x0a, phy_io->base + DP_PHY_AUX_CFG4);
writel_relaxed(0x26, phy_io->base + DP_PHY_AUX_CFG5);
writel_relaxed(0x0a, phy_io->base + DP_PHY_AUX_CFG6);
writel_relaxed(0x03, phy_io->base + DP_PHY_AUX_CFG7);
- writel_relaxed(0xbb, phy_io->base + DP_PHY_AUX_CFG8);
+ writel_relaxed(0x8b, phy_io->base + DP_PHY_AUX_CFG8);
writel_relaxed(0x03, phy_io->base + DP_PHY_AUX_CFG9);
writel_relaxed(0x1f, phy_io->base + DP_PHY_AUX_INTERRUPT_MASK);
}
diff --git a/include/dt-bindings/clock/msm-clocks-cobalt.h b/include/dt-bindings/clock/msm-clocks-cobalt.h
index efbc91093e40..69b6b60e1a6b 100644
--- a/include/dt-bindings/clock/msm-clocks-cobalt.h
+++ b/include/dt-bindings/clock/msm-clocks-cobalt.h
@@ -465,11 +465,10 @@
#define clk_dsi1pll_vco_clk 0x99797b50
#define clk_dp_vco_clk 0xfcaaeec7
-#define clk_hsclk_divsel_clk_src 0x0a325543
#define clk_dp_link_2x_clk_divsel_five 0xcfe3f5dd
-#define clk_dp_link_2x_clk_divsel_ten 0xfeb9924d
-#define clk_dp_link_2x_clk_mux 0xce4c4fc6
-#define clk_vco_divided_clk_src 0x3da6cb51
+#define clk_vco_divsel_four_clk_src 0xe0da19c0
+#define clk_vco_divsel_two_clk_src 0xb5cfc6a8
+#define clk_vco_divided_clk_src_mux 0x3f8197c2
#define clk_hdmi_vco_clk 0xbb7dc20d
/* clock_gpu controlled clocks*/