diff options
| author | Sandeep Panda <spanda@codeaurora.org> | 2015-08-10 13:48:05 +0530 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:14:25 -0700 |
| commit | bf41ad71202dfe754902887335fef16a3731abc5 (patch) | |
| tree | 8f288a5d7f592d922639b30724a297f9485c8ddc /drivers/video/fbdev | |
| parent | 17ec5026ba7b6bc7e580246ff735fb13ee8d0e92 (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.c | 56 |
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 { |
