diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.c | 57 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/msm_mdss_io_8974.c | 119 |
2 files changed, 119 insertions, 57 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index cdc597bebf52..cacb89d7eac9 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -1082,6 +1082,58 @@ static void mdss_dsi_validate_debugfs_info( } } +/** + * mdss_dsi_clamp_phy_reset_config() - configure DSI phy reset mask + * @ctrl: pointer to DSI controller structure + * @enable: true to mask the reset signal, false to unmask + * + * Configure the register to mask/unmask the propagation of the mdss ahb + * clock reset signal to the DSI PHY. This would be necessary when the MDSS + * core is idle power collapsed with the DSI panel on. This function assumes + * that the mmss_misc_ahb clock is already on. + */ +static int mdss_dsi_clamp_phy_reset_config(struct mdss_dsi_ctrl_pdata *ctrl, + bool enable) +{ + u32 regval; + + if (!ctrl) { + pr_warn_ratelimited("%s: invalid input\n", __func__); + return -EINVAL; + } + + if (!ctrl->mmss_misc_io.base) { + pr_warn_ratelimited("%s: mmss_misc_io not mapped\n", __func__); + return -EINVAL; + } + + if ((ctrl->shared_data->hw_rev >= MDSS_DSI_HW_REV_104) && + (MDSS_GET_STEP(ctrl->shared_data->hw_rev) != + MDSS_DSI_HW_REV_STEP_2)) { + u32 clamp_reg_off = ctrl->shared_data->ulps_clamp_ctrl_off; + + regval = MIPI_INP(ctrl->mmss_misc_io.base + clamp_reg_off); + if (enable) + regval = regval | BIT(30); + else + regval = regval & ~BIT(30); + MIPI_OUTP(ctrl->mmss_misc_io.base + clamp_reg_off, regval); + } else { + u32 phyrst_reg_off = ctrl->shared_data->ulps_phyrst_ctrl_off; + + if (enable) + regval = BIT(0); + else + regval = 0; + MIPI_OUTP(ctrl->mmss_misc_io.base + phyrst_reg_off, regval); + } + + /* make sure that clamp ctrl is updated */ + wmb(); + + return 0; +} + static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state) { int ret = 0; @@ -1134,7 +1186,7 @@ static int mdss_dsi_off(struct mdss_panel_data *pdata, int power_state) mdss_dsi_phy_disable(ctrl_pdata); } ctrl_pdata->ctrl_state &= ~CTRL_STATE_DSI_ACTIVE; - + mdss_dsi_clamp_phy_reset_config(ctrl_pdata, false); mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle, MDSS_DSI_CORE_CLK, MDSS_DSI_CLK_OFF); @@ -1338,6 +1390,8 @@ int mdss_dsi_on(struct mdss_panel_data *pdata) } ctrl_pdata->ctrl_state |= CTRL_STATE_DSI_ACTIVE; + mdss_dsi_clamp_phy_reset_config(ctrl_pdata, true); + /* DSI link clocks need to be on prior to ctrl sw reset */ mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle, MDSS_DSI_LINK_CLK, MDSS_DSI_CLK_ON); @@ -2908,6 +2962,7 @@ static int mdss_dsi_cont_splash_config(struct mdss_panel_info *pinfo, ctrl_pdata->is_phyreg_enabled = 1; if (pinfo->type == MIPI_CMD_PANEL) mdss_dsi_set_burst_mode(ctrl_pdata); + mdss_dsi_clamp_phy_reset_config(ctrl_pdata, true); } else { /* Turn on the clocks to read the DSI and PHY revision */ mdss_dsi_clk_ctrl(ctrl_pdata, ctrl_pdata->dsi_clk_handle, diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index 6da526f647d9..fafc74d79ac1 100644 --- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c +++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c @@ -1934,22 +1934,21 @@ error: } /** - * mdss_dsi_clamp_ctrl() - Program DSI clamps for supporting power collapse + * mdss_dsi_clamp_ctrl_default() - Program DSI clamps * @ctrl: pointer to DSI controller structure - * @enable: 1 to enable clamps, 0 to disable clamps + * @enable: true to enable clamps, false to disable clamps * - * For idle-screen usecases with command mode panels, MDSS can be power - * collapsed. However, DSI phy needs to remain on. To avoid any mismatch - * between the DSI controller state, DSI phy needs to be clamped before - * power collapsing. This function executes the required programming - * sequence to configure these DSI clamps. This function should only be called - * when the DSI link clocks are disabled. + * Execute the required programming sequence to configure DSI clamps. This + * function would be called whenever there are no hardware version sepcific + * functions for programming the DSI clamps. This function assumes that the + * core clocks are already on. */ -static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable) +static int mdss_dsi_clamp_ctrl_default(struct mdss_dsi_ctrl_pdata *ctrl, + bool enable) { struct mipi_panel_info *mipi = NULL; u32 clamp_reg, regval = 0; - u32 clamp_reg_off, phyrst_reg_off; + u32 clamp_reg_off; if (!ctrl) { pr_err("%s: invalid input\n", __func__); @@ -1962,7 +1961,6 @@ static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable) } clamp_reg_off = ctrl->shared_data->ulps_clamp_ctrl_off; - phyrst_reg_off = ctrl->shared_data->ulps_phyrst_ctrl_off; mipi = &ctrl->panel_data.panel_info.mipi; /* clock lane will always be clamped */ @@ -1992,7 +1990,8 @@ static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable) } pr_debug("%s: called for ctrl%d, enable=%d, clamp_reg=0x%08x\n", __func__, ctrl->ndx, enable, clamp_reg); - if (enable && !ctrl->mmss_clamp) { + + if (enable) { regval = MIPI_INP(ctrl->mmss_misc_io.base + clamp_reg_off); /* Enable MMSS DSI Clamps */ if (ctrl->ndx == DSI_CTRL_0) { @@ -2006,47 +2005,7 @@ static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable) MIPI_OUTP(ctrl->mmss_misc_io.base + clamp_reg_off, regval | ((clamp_reg << 16) | BIT(31))); } - /* update clamp ctrl before setting phy reset disable */ - wmb(); - - /* - * This register write ensures that DSI PHY will not be - * reset when mdss ahb clock reset is asserted while coming - * out of power collapse - */ - if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->shared_data->hw_rev, - MDSS_DSI_HW_REV_104) && - (MDSS_GET_STEP(ctrl->shared_data->hw_rev) != - MDSS_DSI_HW_REV_STEP_2)) { - - regval = MIPI_INP(ctrl->mmss_misc_io.base + - clamp_reg_off); - MIPI_OUTP(ctrl->mmss_misc_io.base + clamp_reg_off, - regval | BIT(30)); - } else { - MIPI_OUTP(ctrl->mmss_misc_io.base + phyrst_reg_off, - 0x1); - } - /* make sure that clamp ctrl is updated before disable call */ - wmb(); - ctrl->mmss_clamp = true; - } else if (!enable && ctrl->mmss_clamp) { - if (IS_MDSS_MAJOR_MINOR_SAME(ctrl->shared_data->hw_rev, - MDSS_DSI_HW_REV_104) && - (MDSS_GET_STEP(ctrl->shared_data->hw_rev) != - MDSS_DSI_HW_REV_STEP_2)) { - - regval = MIPI_INP(ctrl->mmss_misc_io.base + - clamp_reg_off); - MIPI_OUTP(ctrl->mmss_misc_io.base + clamp_reg_off, - regval & ~BIT(30)); - } else { - MIPI_OUTP(ctrl->mmss_misc_io.base + phyrst_reg_off, - 0x0); - } - /* update clamp ctrl before unsetting phy reset disable */ - wmb(); - + } else { regval = MIPI_INP(ctrl->mmss_misc_io.base + clamp_reg_off); /* Disable MMSS DSI Clamps */ if (ctrl->ndx == DSI_CTRL_0) @@ -2055,8 +2014,51 @@ static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable) else if (ctrl->ndx == DSI_CTRL_1) MIPI_OUTP(ctrl->mmss_misc_io.base + clamp_reg_off, regval & ~((clamp_reg << 16) | BIT(31))); - /* make sure that clamp ctrl is updated before enable call */ - wmb(); + } + + /* make sure clamps are configured */ + wmb(); + + return 0; +} + +/** + * mdss_dsi_clamp_ctrl() - Program DSI clamps for supporting power collapse + * @ctrl: pointer to DSI controller structure + * @enable: 1 to enable clamps, 0 to disable clamps + * + * For idle-screen usecases with command mode panels, MDSS can be power + * collapsed. However, DSI phy needs to remain on. To avoid any mismatch + * between the DSI controller state, DSI phy needs to be clamped before + * power collapsing. This function executes the required programming + * sequence to configure these DSI clamps. This function should only be called + * when the DSI link clocks are disabled. + */ +static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable) +{ + int rc = 0; + + if (!ctrl) { + pr_err("%s: invalid input\n", __func__); + return -EINVAL; + } + + pr_debug("%s: called for ctrl%d, enable=%d\n", __func__, ctrl->ndx, + enable); + + if (enable && !ctrl->mmss_clamp) { + if (ctrl->shared_data->phy_rev < DSI_PHY_REV_30) { + rc = mdss_dsi_clamp_ctrl_default(ctrl, true); + if (rc) + goto error; + } + ctrl->mmss_clamp = true; + } else if (!enable && ctrl->mmss_clamp) { + if (ctrl->shared_data->phy_rev < DSI_PHY_REV_30) { + rc = mdss_dsi_clamp_ctrl_default(ctrl, false); + if (rc) + goto error; + } ctrl->mmss_clamp = false; } else { pr_debug("%s: No change requested: %s -> %s\n", __func__, @@ -2064,7 +2066,12 @@ static int mdss_dsi_clamp_ctrl(struct mdss_dsi_ctrl_pdata *ctrl, int enable) enable ? "enabled" : "disabled"); } - return 0; +error: + if (rc) + pr_err("%s: failed to %s clamps for ctrl%d\n", __func__, + enable ? "enable" : "disable", ctrl->ndx); + + return rc; } DEFINE_MUTEX(dsi_clk_mutex); |
