drm/msm/dsi: Save/Restore PLL status across PHY reset
PATCH 1/1 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 <[email protected]>
--- drivers/gpu/drm/msm/dsi/dsi.h | 9 +++++++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 21 +++++++++++++++ drivers/gpu/drm/msm/dsi/pll/dsi_pll.c | 42 +++++++++++++++++------------- drivers/gpu/drm/msm/dsi/pll/dsi_pll.h | 1 + drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c | 31 +++++++++------------- 5 files changed, 68 insertions(+), 36 deletions(-)
drivers/gpu/drm/msm/dsi/dsi.h +9 -0
@@ -95,6 +95,8 @@ struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev,void msm_dsi_pll_destroy (struct msm_dsi_pll *pll);int msm_dsi_pll_get_clk_provider (struct msm_dsi_pll *pll,struct clk **byte_clk_provider,struct clk **pixel_clk_provider); +void msm_dsi_pll_save_state (struct msm_dsi_pll *pll); +int msm_dsi_pll_restore_state (struct msm_dsi_pll *pll);#else static inline struct msm_dsi_pll *msm_dsi_pll_init (struct platform_device *pdev,enum msm_dsi_phy_type type,int id) {
@@ -108,6 +110,13 @@ static inline int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll, {return -ENODEV ; } +static inline void msm_dsi_pll_save_state (struct msm_dsi_pll *pll) +{ +} +static inline int msm_dsi_pll_restore_state (struct msm_dsi_pll *pll) +{ +return 0 ; +}#endif /* dsi host */
drivers/gpu/drm/msm/dsi/dsi_manager.c +21 -0
@@ -611,12 +611,28 @@ int msm_dsi_manager_phy_enable(int id,struct msm_dsi *msm_dsi =dsi_mgr_get_dsi (id);struct msm_dsi_phy *phy = msm_dsi->phy;int src_pll_id =IS_DUAL_DSI () ?DSI_CLOCK_MASTER : id; +struct msm_dsi_pll *pll =msm_dsi_phy_get_pll (msm_dsi->phy);int ret; ret =msm_dsi_phy_enable (phy, src_pll_id, bit_rate, esc_rate);if (ret)return ret; +/* +* Reset DSI PHY silently changes its PLL registers to reset status, +* which will confuse clock driver and result in wrong output rate of +* link clocks. Restore PLL status if its PLL is being used as clock +* source. +*/ +if (!IS_DUAL_DSI () || (id ==DSI_CLOCK_MASTER )) { + ret =msm_dsi_pll_restore_state (pll); +if (ret) { +pr_err ("%s: failed to restore pll state\n" , __func__); +msm_dsi_phy_disable (phy); +return ret; + } + } + msm_dsi->phy_enabled = true;msm_dsi_phy_get_clk_pre_post (phy, clk_pre, clk_post);
@@ -629,6 +645,11 @@ void msm_dsi_manager_phy_disable(int id)struct msm_dsi *mdsi =dsi_mgr_get_dsi (DSI_CLOCK_MASTER );struct msm_dsi *sdsi =dsi_mgr_get_dsi (DSI_CLOCK_SLAVE );struct msm_dsi_phy *phy = msm_dsi->phy; +struct msm_dsi_pll *pll =msm_dsi_phy_get_pll (msm_dsi->phy); + +/* Save PLL status if it is a clock source */ +if (!IS_DUAL_DSI () || (id ==DSI_CLOCK_MASTER )) +msm_dsi_pll_save_state (pll);/* disable DSI phy * In dual-dsi configuration, the phy should be disabled for the
drivers/gpu/drm/msm/dsi/pll/dsi_pll.c +24 -18
61 lines not on this page · raw message
drivers/gpu/drm/msm/dsi/pll/dsi_pll.h +1 -0
@@ -27,6 +27,7 @@ struct msm_dsi_pll {struct clk_hw clk_hw;bool pll_on; +bool state_saved;unsigned long min_rate;unsigned long max_rate;
drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c +13 -18
@@ -465,26 +465,21 @@ static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll)void __iomem *base = pll_28nm->mmio;int ret; -if ((cached_state->vco_rate !=0 ) && - (cached_state->vco_rate ==__clk_get_rate (pll->clk_hw.clk))) { - ret =dsi_pll_28nm_clk_set_rate (&pll->clk_hw, - cached_state->vco_rate,0 ); -if (ret) { -dev_err (&pll_28nm->pdev->dev, -"restore vco rate failed. ret=%d\n" , ret); -return ret; - } - -pll_write (base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, - cached_state->postdiv3); -pll_write (base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, - cached_state->postdiv1); -pll_write (base + REG_DSI_28nm_PHY_PLL_VREG_CFG, - cached_state->byte_mux); - - cached_state->vco_rate =0 ; + ret =dsi_pll_28nm_clk_set_rate (&pll->clk_hw, + cached_state->vco_rate,0 ); +if (ret) { +dev_err (&pll_28nm->pdev->dev, +"restore vco rate failed. ret=%d\n" , ret); +return ret; } +pll_write (base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, + cached_state->postdiv3); +pll_write (base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, + cached_state->postdiv1); +pll_write (base + REG_DSI_28nm_PHY_PLL_VREG_CFG, + cached_state->byte_mux); +return 0 ; }
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation _______________________________________________ dri-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/dri-devel