aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/dsi/dsi_manager.c
diff options
context:
space:
mode:
authorHai Li <hali@codeaurora.org>2015-07-03 10:09:46 -0400
committerRob Clark <robdclark@gmail.com>2015-08-15 18:27:18 -0400
commit328e1a633c9bc26c36ecd320246e4a9b2726e81a (patch)
tree662e05c96fd1cf2bf0d6e059a32479d374616ac3 /drivers/gpu/drm/msm/dsi/dsi_manager.c
parentda882cd1ee132ecbb4a4848a6b0797ea2ed4bee7 (diff)
drm/msm/dsi: Save/Restore PLL status across PHY reset
Reset DSI PHY silently changes its PLL registers to reset status, which will make cached status in clock driver invalid and result in wrong output rate of link clocks. The current restore mechanism in DSI PLL does not cover all the cases. This change is to recover PLL status after PHY reset to match HW status with cached status in clock driver. Signed-off-by: Hai Li <hali@codeaurora.org> Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/dsi/dsi_manager.c')
-rw-r--r--drivers/gpu/drm/msm/dsi/dsi_manager.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index bd247b7dbc44..ca4ff4ab663e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -611,12 +611,28 @@ int msm_dsi_manager_phy_enable(int id,
611 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 611 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
612 struct msm_dsi_phy *phy = msm_dsi->phy; 612 struct msm_dsi_phy *phy = msm_dsi->phy;
613 int src_pll_id = IS_DUAL_DSI() ? DSI_CLOCK_MASTER : id; 613 int src_pll_id = IS_DUAL_DSI() ? DSI_CLOCK_MASTER : id;
614 struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy);
614 int ret; 615 int ret;
615 616
616 ret = msm_dsi_phy_enable(phy, src_pll_id, bit_rate, esc_rate); 617 ret = msm_dsi_phy_enable(phy, src_pll_id, bit_rate, esc_rate);
617 if (ret) 618 if (ret)
618 return ret; 619 return ret;
619 620
621 /*
622 * Reset DSI PHY silently changes its PLL registers to reset status,
623 * which will confuse clock driver and result in wrong output rate of
624 * link clocks. Restore PLL status if its PLL is being used as clock
625 * source.
626 */
627 if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER)) {
628 ret = msm_dsi_pll_restore_state(pll);
629 if (ret) {
630 pr_err("%s: failed to restore pll state\n", __func__);
631 msm_dsi_phy_disable(phy);
632 return ret;
633 }
634 }
635
620 msm_dsi->phy_enabled = true; 636 msm_dsi->phy_enabled = true;
621 msm_dsi_phy_get_clk_pre_post(phy, clk_pre, clk_post); 637 msm_dsi_phy_get_clk_pre_post(phy, clk_pre, clk_post);
622 638
@@ -629,6 +645,11 @@ void msm_dsi_manager_phy_disable(int id)
629 struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER); 645 struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
630 struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE); 646 struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
631 struct msm_dsi_phy *phy = msm_dsi->phy; 647 struct msm_dsi_phy *phy = msm_dsi->phy;
648 struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy);
649
650 /* Save PLL status if it is a clock source */
651 if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER))
652 msm_dsi_pll_save_state(pll);
632 653
633 /* disable DSI phy 654 /* disable DSI phy
634 * In dual-dsi configuration, the phy should be disabled for the 655 * In dual-dsi configuration, the phy should be disabled for the