diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 1349bb7a51..f44c495124 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -2749,12 +2749,62 @@ static int dsi_display_set_clk_src(struct dsi_display *display, bool set_xo) return 0; } -int dsi_display_phy_pll_toggle(void *priv, bool prepare) +static int dsi_display_phy_pll_enable(struct dsi_display *display) { int rc = 0; - struct dsi_display *display = priv; struct dsi_display_ctrl *m_ctrl; + m_ctrl = &display->ctrl[display->clk_master_idx]; + if (!m_ctrl->phy) { + DSI_ERR("[%s] PHY not found\n", display->name); + return -EINVAL; + } + + /* + * It is recommended to turn on the PLL before switching parent + * of RCG to PLL because when RCG is on, both the old and new + * sources should be on while switching the RCG parent. + * + * Note: Branch clocks and in turn RCG might not get turned off + * during clock disable sequence if there is a vote from dispcc + * or any of its other consumers. + */ + + rc = dsi_phy_pll_toggle(m_ctrl->phy, true); + if (rc) + return rc; + + return dsi_display_set_clk_src(display, false); +} + +static int dsi_display_phy_pll_disable(struct dsi_display *display) +{ + int rc = 0; + struct dsi_display_ctrl *m_ctrl; + + /* + * It is recommended to turn off the PLL after switching parent + * of RCG to PLL because when RCG is on, both the old and new + * sources should be on while switching the RCG parent. + */ + + rc = dsi_display_set_clk_src(display, true); + if (rc) + return rc; + + m_ctrl = &display->ctrl[display->clk_master_idx]; + if (!m_ctrl->phy) { + DSI_ERR("[%s] PHY not found\n", display->name); + return -EINVAL; + } + + return dsi_phy_pll_toggle(m_ctrl->phy, false); +} + +int dsi_display_phy_pll_toggle(void *priv, bool prepare) +{ + struct dsi_display *display = priv; + if (!display) { DSI_ERR("invalid arguments\n"); return -EINVAL; @@ -2763,17 +2813,10 @@ int dsi_display_phy_pll_toggle(void *priv, bool prepare) if (is_skip_op_required(display)) return 0; - rc = dsi_display_set_clk_src(display, !prepare); - - m_ctrl = &display->ctrl[display->clk_master_idx]; - if (!m_ctrl->phy) { - DSI_ERR("[%s] PHY not found\n", display->name); - return -EINVAL; - } - - rc = dsi_phy_pll_toggle(m_ctrl->phy, prepare); - - return rc; + if (prepare) + return dsi_display_phy_pll_enable(display); + else + return dsi_display_phy_pll_disable(display); } int dsi_display_phy_configure(void *priv, bool commit)