diff options
| author | Benjamin Chan <bkchan@codeaurora.org> | 2017-02-10 13:14:06 -0500 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-02-17 07:31:38 -0800 |
| commit | 6bdad2d66250fb85cbf5a7ff3adf94194dbd2f4a (patch) | |
| tree | b5c44020c110e2ac1fdfb407b875bcb22cf84076 /drivers/video/fbdev | |
| parent | 7066afbbe98876327824a305c9d0737114136baa (diff) | |
msm: mdss: Fix clocks disable sequence
When disabling the clocks that MDP depends on during an ON to OFF
transition, it is necessary to reverse the clock enabling sequence.
Otherwise, the MDSS AHB clock will stuck in a halt state and cannot
be turned off.
CRs-Fixed: 2004996
Change-Id: I0da7df14e2084701c95fd08585b9a41e0a8cb653
Signed-off-by: Benjamin Chan <bkchan@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 109 |
1 files changed, 64 insertions, 45 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index d8d11f21f3b2..2cb9dd7c4282 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -1355,6 +1355,68 @@ static inline void __mdss_mdp_reg_access_clk_enable( } } +/* + * __mdss_mdp_clk_control - Overall MDSS clock control for power on/off + */ +static void __mdss_mdp_clk_control(struct mdss_data_type *mdata, bool enable) +{ + int rc = 0; + unsigned long flags; + + if (enable) { + pm_runtime_get_sync(&mdata->pdev->dev); + + mdss_update_reg_bus_vote(mdata->reg_bus_clt, + VOTE_INDEX_LOW); + + rc = mdss_iommu_ctrl(1); + if (IS_ERR_VALUE(rc)) + pr_err("IOMMU attach failed\n"); + + /* Active+Sleep */ + msm_bus_scale_client_update_context(mdata->bus_hdl, + false, mdata->curr_bw_uc_idx); + + spin_lock_irqsave(&mdp_lock, flags); + mdata->clk_ena = enable; + spin_unlock_irqrestore(&mdp_lock, flags); + + mdss_mdp_clk_update(MDSS_CLK_MNOC_AHB, 1); + mdss_mdp_clk_update(MDSS_CLK_AHB, 1); + mdss_mdp_clk_update(MDSS_CLK_AXI, 1); + mdss_mdp_clk_update(MDSS_CLK_MDP_CORE, 1); + mdss_mdp_clk_update(MDSS_CLK_MDP_LUT, 1); + if (mdata->vsync_ena) + mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, 1); + } else { + spin_lock_irqsave(&mdp_lock, flags); + mdata->clk_ena = enable; + spin_unlock_irqrestore(&mdp_lock, flags); + + if (mdata->vsync_ena) + mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, 0); + + mdss_mdp_clk_update(MDSS_CLK_MDP_LUT, 0); + mdss_mdp_clk_update(MDSS_CLK_MDP_CORE, 0); + mdss_mdp_clk_update(MDSS_CLK_AXI, 0); + mdss_mdp_clk_update(MDSS_CLK_AHB, 0); + mdss_mdp_clk_update(MDSS_CLK_MNOC_AHB, 0); + + /* release iommu control */ + mdss_iommu_ctrl(0); + + /* Active-Only */ + msm_bus_scale_client_update_context(mdata->bus_hdl, + true, mdata->ao_bw_uc_idx); + + mdss_update_reg_bus_vote(mdata->reg_bus_clt, + VOTE_INDEX_DISABLE); + + pm_runtime_mark_last_busy(&mdata->pdev->dev); + pm_runtime_put_autosuspend(&mdata->pdev->dev); + } +} + int __mdss_mdp_vbif_halt(struct mdss_data_type *mdata, bool is_nrt) { int rc = 0; @@ -1646,9 +1708,7 @@ void mdss_mdp_clk_ctrl(int enable) { struct mdss_data_type *mdata = mdss_mdp_get_mdata(); static int mdp_clk_cnt; - unsigned long flags; int changed = 0; - int rc = 0; mutex_lock(&mdp_clk_lock); if (enable) { @@ -1672,49 +1732,8 @@ void mdss_mdp_clk_ctrl(int enable) __builtin_return_address(0), current->group_leader->comm, mdata->bus_ref_cnt, changed, enable); - if (changed) { - if (enable) { - pm_runtime_get_sync(&mdata->pdev->dev); - - mdss_update_reg_bus_vote(mdata->reg_bus_clt, - VOTE_INDEX_LOW); - - rc = mdss_iommu_ctrl(1); - if (IS_ERR_VALUE(rc)) - pr_err("IOMMU attach failed\n"); - - /* Active+Sleep */ - msm_bus_scale_client_update_context(mdata->bus_hdl, - false, mdata->curr_bw_uc_idx); - } - - spin_lock_irqsave(&mdp_lock, flags); - mdata->clk_ena = enable; - spin_unlock_irqrestore(&mdp_lock, flags); - - mdss_mdp_clk_update(MDSS_CLK_MNOC_AHB, enable); - mdss_mdp_clk_update(MDSS_CLK_AHB, enable); - mdss_mdp_clk_update(MDSS_CLK_AXI, enable); - mdss_mdp_clk_update(MDSS_CLK_MDP_CORE, enable); - mdss_mdp_clk_update(MDSS_CLK_MDP_LUT, enable); - if (mdata->vsync_ena) - mdss_mdp_clk_update(MDSS_CLK_MDP_VSYNC, enable); - - if (!enable) { - /* release iommu control */ - mdss_iommu_ctrl(0); - - /* Active-Only */ - msm_bus_scale_client_update_context(mdata->bus_hdl, - true, mdata->ao_bw_uc_idx); - - mdss_update_reg_bus_vote(mdata->reg_bus_clt, - VOTE_INDEX_DISABLE); - - pm_runtime_mark_last_busy(&mdata->pdev->dev); - pm_runtime_put_autosuspend(&mdata->pdev->dev); - } - } + if (changed) + __mdss_mdp_clk_control(mdata, enable); if (enable && changed) mdss_mdp_idle_pc_restore(); |
