From 3ff78e8f7d4398c92091d704b50ee85be0eec018 Mon Sep 17 00:00:00 2001 From: Satya Rama Aditya Pinapala Date: Mon, 25 Jan 2021 10:58:42 -0800 Subject: [PATCH] disp: msm: dsi: set source to xo while turning off PLL HW recommendation is to park the DSI byte clock and pixel clock at XO before turning them off. The change parses XO from the DT and sets the clock source as XO while turning off the PLL. Change-Id: I788951d6341149300e80e8db4a5a3fd2c4eb3e03 Signed-off-by: Satya Rama Aditya Pinapala --- msm/dsi/dsi_ctrl.c | 9 ++++ msm/dsi/dsi_ctrl.h | 2 + msm/dsi/dsi_display.c | 106 +++++++++++++++++++----------------------- 3 files changed, 59 insertions(+), 58 deletions(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 375119282e..ed7a21c2bc 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -719,6 +719,7 @@ static int dsi_ctrl_clocks_init(struct platform_device *pdev, struct dsi_link_lp_clk_info *lp_link = &ctrl->clk_info.lp_link_clks; struct dsi_link_hs_clk_info *hs_link = &ctrl->clk_info.hs_link_clks; struct dsi_clk_link_set *rcg = &ctrl->clk_info.rcg_clks; + struct dsi_clk_link_set *xo = &ctrl->clk_info.xo_clk; core->mdp_core_clk = devm_clk_get(&pdev->dev, "mdp_core_clk"); if (IS_ERR(core->mdp_core_clk)) { @@ -792,6 +793,14 @@ static int dsi_ctrl_clocks_init(struct platform_device *pdev, goto fail; } + xo->byte_clk = devm_clk_get(&pdev->dev, "xo"); + if (IS_ERR(xo->byte_clk)) { + xo->byte_clk = NULL; + DSI_CTRL_DEBUG(ctrl, "failed to get xo clk, rc=%d\n", rc); + } + + xo->pixel_clk = xo->byte_clk; + return 0; fail: dsi_ctrl_clocks_deinit(ctrl); diff --git a/msm/dsi/dsi_ctrl.h b/msm/dsi/dsi_ctrl.h index 6df95a15c4..e9d3fa5fdb 100644 --- a/msm/dsi/dsi_ctrl.h +++ b/msm/dsi/dsi_ctrl.h @@ -119,6 +119,7 @@ struct dsi_ctrl_power_info { * output of the PLL is set as parent for these root * clocks. These clocks are specific to controller * instance. + * @xo_clk: XO clocks used to park the DSI PLL before turning off. * @mux_clks: Mux clocks used for Dynamic refresh feature. * @ext_clks: External byte/pixel clocks from the MMSS block. These * clocks are set as parent to rcg clocks. @@ -131,6 +132,7 @@ struct dsi_ctrl_clk_info { struct dsi_link_hs_clk_info hs_link_clks; struct dsi_link_lp_clk_info lp_link_clks; struct dsi_clk_link_set rcg_clks; + struct dsi_clk_link_set xo_clk; /* Clocks set by DSI Manager */ struct dsi_clk_link_set mux_clks; diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 288ea6182b..b6be9bfe66 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -2647,6 +2647,52 @@ error: return rc; } +static int dsi_display_set_clk_src(struct dsi_display *display, bool set_xo) +{ + int rc = 0; + int i; + struct dsi_display_ctrl *m_ctrl, *ctrl; + struct dsi_ctrl_clk_info *info; + + if (display->trusted_vm_env) + return 0; + /* + * In case of split DSI usecases, the clock for master controller should + * be enabled before the other controller. Master controller in the + * clock context refers to the controller that sources the clock. While turning off the + * clocks, the source is set to xo. + */ + m_ctrl = &display->ctrl[display->clk_master_idx]; + info = &m_ctrl->ctrl->clk_info; + + if (!set_xo) + rc = dsi_ctrl_set_clock_source(m_ctrl->ctrl, &display->clock_info.pll_clks); + else if ((info->xo_clk.byte_clk) && (info->xo_clk.pixel_clk)) + rc = dsi_ctrl_set_clock_source(m_ctrl->ctrl, &info->xo_clk); + if (rc) { + DSI_ERR("[%s] failed to set source clocks for master, rc=%d\n", display->name, rc); + return rc; + } + + /* Set source for the rest of the controllers */ + display_for_each_ctrl(i, display) { + ctrl = &display->ctrl[i]; + if (!ctrl->ctrl || (ctrl == m_ctrl)) + continue; + + info = &ctrl->ctrl->clk_info; + if (!set_xo) + rc = dsi_ctrl_set_clock_source(ctrl->ctrl, &display->clock_info.pll_clks); + else if ((info->xo_clk.byte_clk) && (info->xo_clk.pixel_clk)) + rc = dsi_ctrl_set_clock_source(ctrl->ctrl, &info->xo_clk); + if (rc) { + DSI_ERR("[%s] failed to set source clocks, rc=%d\n", display->name, rc); + return rc; + } + } + return 0; +} + int dsi_display_phy_pll_toggle(void *priv, bool prepare) { int rc = 0; @@ -2658,6 +2704,8 @@ int dsi_display_phy_pll_toggle(void *priv, bool prepare) return -EINVAL; } + 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); @@ -2703,44 +2751,6 @@ int dsi_display_phy_configure(void *priv, bool commit) return rc; } -static int dsi_display_set_clk_src(struct dsi_display *display) -{ - int rc = 0; - int i; - struct dsi_display_ctrl *m_ctrl, *ctrl; - - /* - * In case of split DSI usecases, the clock for master controller should - * be enabled before the other controller. Master controller in the - * clock context refers to the controller that sources the clock. - */ - m_ctrl = &display->ctrl[display->clk_master_idx]; - - rc = dsi_ctrl_set_clock_source(m_ctrl->ctrl, - &display->clock_info.pll_clks); - if (rc) { - DSI_ERR("[%s] failed to set source clocks for master, rc=%d\n", - display->name, rc); - return rc; - } - - /* Turn on rest of the controllers */ - display_for_each_ctrl(i, display) { - ctrl = &display->ctrl[i]; - if (!ctrl->ctrl || (ctrl == m_ctrl)) - continue; - - rc = dsi_ctrl_set_clock_source(ctrl->ctrl, - &display->clock_info.pll_clks); - if (rc) { - DSI_ERR("[%s] failed to set source clocks, rc=%d\n", - display->name, rc); - return rc; - } - } - return 0; -} - static int dsi_display_phy_reset_config(struct dsi_display *display, bool enable) { @@ -7241,16 +7251,6 @@ static int dsi_display_pre_switch(struct dsi_display *display) goto error_ctrl_clk_off; } - if (!display->trusted_vm_env) { - rc = dsi_display_set_clk_src(display); - if (rc) { - DSI_ERR( - "[%s] failed to set DSI link clock source, rc=%d\n", - display->name, rc); - goto error_ctrl_deinit; - } - } - rc = dsi_display_clk_ctrl(display->dsi_clk_handle, DSI_LINK_CLK, DSI_CLK_ON); if (rc) { @@ -7650,16 +7650,6 @@ int dsi_display_prepare(struct dsi_display *display) } } - if (!display->trusted_vm_env) { - rc = dsi_display_set_clk_src(display); - if (rc) { - DSI_ERR( - "[%s] failed to set DSI link clock source, rc=%d\n", - display->name, rc); - goto error_phy_disable; - } - } - rc = dsi_display_ctrl_init(display); if (rc) { DSI_ERR("[%s] failed to setup DSI controller, rc=%d\n",