summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorSandeep Panda <spanda@codeaurora.org>2015-08-10 13:48:05 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:14:25 -0700
commitbf41ad71202dfe754902887335fef16a3731abc5 (patch)
tree8f288a5d7f592d922639b30724a297f9485c8ddc /drivers/video/fbdev
parent17ec5026ba7b6bc7e580246ff735fb13ee8d0e92 (diff)
msm: mdss: properly handle dsi phy regulator for dual dsi case
In dual dsi case, if we do DSI PHY sw reset for one DSI controller then it will reset the DSI PHY regulator also. Since DSI PHY regulator is shared among both the DSI controllers, it might cause side effects on the other DSI controller if that is active. So only reset DSI PHY lane and PHY HW as when one of the DSI controller is still in active state. Also avoid reconfiguring DSI PHY regulator in dual dsi case if the other DSI controller is active. Change-Id: I5ad1251c89e8ad3f521c4e5c11607494e14143cf Signed-off-by: Sandeep Panda <spanda@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
-rw-r--r--drivers/video/fbdev/msm/msm_mdss_io_8974.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
index a30d73f328c9..5f0176da4f66 100644
--- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c
+++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c
@@ -428,6 +428,8 @@ void mdss_dsi_phy_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl)
{
struct mdss_dsi_ctrl_pdata *sctrl = NULL;
struct dsi_shared_data *sdata;
+ struct mdss_dsi_ctrl_pdata *octrl;
+ u32 reg_val = 0;
if (ctrl == NULL) {
pr_err("%s: Invalid input data\n", __func__);
@@ -435,11 +437,7 @@ void mdss_dsi_phy_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl)
}
sdata = ctrl->shared_data;
-
- if (ctrl == NULL) {
- pr_err("%s: Invalid input data\n", __func__);
- return;
- }
+ octrl = mdss_dsi_get_other_ctrl(ctrl);
if (ctrl->shared_data->phy_rev == DSI_PHY_REV_20) {
if (mdss_dsi_is_ctrl_clk_master(ctrl))
@@ -448,10 +446,41 @@ void mdss_dsi_phy_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl)
return;
}
- /* start phy sw reset */
- mdss_dsi_ctrl_phy_reset(ctrl);
- if (sctrl)
- mdss_dsi_ctrl_phy_reset(sctrl);
+ /*
+ * For dual dsi case if we do DSI PHY sw reset,
+ * this will reset DSI PHY regulators also.
+ * Since DSI PHY regulator is shared among both
+ * the DSI controllers, we should not do DSI PHY
+ * sw reset when the other DSI controller is still
+ * active.
+ */
+ mutex_lock(&sdata->phy_reg_lock);
+ if ((mdss_dsi_is_hw_config_dual(sdata) &&
+ (octrl && octrl->is_phyreg_enabled))) {
+ /* start phy lane and HW reset */
+ reg_val = MIPI_INP(ctrl->ctrl_base + 0x12c);
+ reg_val |= (BIT(16) | BIT(8));
+ MIPI_OUTP(ctrl->ctrl_base + 0x12c, reg_val);
+ /* wait for 1ms as per HW design */
+ usleep_range(1000, 2000);
+ /* ensure phy lane and HW reset starts */
+ wmb();
+ /* end phy lane and HW reset */
+ reg_val = MIPI_INP(ctrl->ctrl_base + 0x12c);
+ reg_val &= ~(BIT(16) | BIT(8));
+ MIPI_OUTP(ctrl->ctrl_base + 0x12c, reg_val);
+ /* wait for 100us as per HW design */
+ usleep_range(100, 200);
+ /* ensure phy lane and HW reset ends */
+ wmb();
+ } else {
+ /* start phy sw reset */
+ mdss_dsi_ctrl_phy_reset(ctrl);
+ if (sctrl)
+ mdss_dsi_ctrl_phy_reset(sctrl);
+
+ }
+ mutex_unlock(&sdata->phy_reg_lock);
if ((sdata->hw_rev == MDSS_DSI_HW_REV_103) &&
!mdss_dsi_is_hw_config_dual(sdata) &&
@@ -950,6 +979,7 @@ static void mdss_dsi_phy_regulator_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
}
sdata = ctrl->shared_data;
+ other_ctrl = mdss_dsi_get_other_ctrl(ctrl);
mutex_lock(&sdata->phy_reg_lock);
if (enable) {
@@ -961,6 +991,13 @@ static void mdss_dsi_phy_regulator_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
mdss_dsi_20nm_phy_regulator_enable(ctrl);
break;
default:
+ /*
+ * For dual dsi case, do not reconfigure dsi phy
+ * regulator if the other dsi controller is still
+ * active.
+ */
+ if (!mdss_dsi_is_hw_config_dual(sdata) ||
+ (other_ctrl && !other_ctrl->is_phyreg_enabled))
mdss_dsi_28nm_phy_regulator_enable(ctrl);
break;
}
@@ -974,7 +1011,6 @@ static void mdss_dsi_phy_regulator_ctrl(struct mdss_dsi_ctrl_pdata *ctrl,
*/
if (mdss_dsi_is_hw_config_split(ctrl->shared_data) ||
mdss_dsi_is_hw_config_dual(ctrl->shared_data)) {
- other_ctrl = mdss_dsi_get_other_ctrl(ctrl);
if (other_ctrl && !other_ctrl->is_phyreg_enabled)
mdss_dsi_phy_regulator_disable(ctrl);
} else {