From 039af32693ebc987dc2602b137216b016404c63d Mon Sep 17 00:00:00 2001 From: Aravind Venkateswaran Date: Tue, 2 Feb 2016 17:39:03 -0800 Subject: [PATCH] msm: mdss: dsi: validate ULPS config requests In the current implementation, ULPS entry/exit requests are placed whenever DSI link clocks are disabled/enabled. However, certain optimizations can be done avoid unnecessary transitions such as for cases when clocks are turned off briefly prior to panel initialization/uninitialization, and then turned right back on to send the panel on/off commands. Add these optimizations and avoid ULPS configuration for such cases. CRs-Fixed: 961817 Change-Id: Ie6c666b91e86697c37e0a557f9ba47811392ae90 Signed-off-by: Aravind Venkateswaran --- drivers/video/fbdev/msm/msm_mdss_io_8974.c | 92 ++++++++++++++++++---- 1 file changed, 75 insertions(+), 17 deletions(-) diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index f01f8d8514d3..6135a81d94f6 100644 --- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c +++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c @@ -1502,6 +1502,67 @@ int mdss_dsi_clk_div_config(struct mdss_panel_info *panel_info, return 0; } +static bool mdss_dsi_is_ulps_req_valid(struct mdss_dsi_ctrl_pdata *ctrl, + int enable) +{ + struct mdss_dsi_ctrl_pdata *octrl = NULL; + struct mdss_panel_data *pdata = &ctrl->panel_data; + struct mdss_panel_info *pinfo = &pdata->panel_info; + + pr_debug("%s: checking ulps req validity for ctrl%d\n", + __func__, ctrl->ndx); + + if (!mdss_dsi_ulps_feature_enabled(pdata) && + !pinfo->ulps_suspend_enabled) { + pr_debug("%s: ULPS feature is not enabled\n", __func__); + return false; + } + + /* + * No need to enter ULPS when transitioning from splash screen to + * boot animation since it is expected that the clocks would be turned + * right back on. + */ + if (enable && pinfo->cont_splash_enabled) { + pr_debug("%s: skip ULPS config with splash screen enabled\n", + __func__); + return false; + } + + /* + * No need to enable ULPS if panel is not yet initialized. + * However, this should be allowed in following usecases: + * 1. If ULPS during suspend feature is enabled, where we + * configure the lanes in ULPS after turning off the panel. + * 2. When coming out of idle PC with clamps enabled, where we + * transition the controller HW state back to ULPS prior to + * disabling ULPS. + */ + if (enable && !ctrl->mmss_clamp && + !(ctrl->ctrl_state & CTRL_STATE_PANEL_INIT) && + !pdata->panel_info.ulps_suspend_enabled) { + pr_debug("%s: panel not yet initialized\n", __func__); + return false; + } + + /* + * For split-DSI usecase, wait till both controllers are initialized. + * The same exceptions as above are applicable here too. + */ + if (mdss_dsi_is_hw_config_split(ctrl->shared_data)) { + octrl = mdss_dsi_get_other_ctrl(ctrl); + if (enable && !ctrl->mmss_clamp && octrl && + !(octrl->ctrl_state & CTRL_STATE_PANEL_INIT) && + !pdata->panel_info.ulps_suspend_enabled) { + pr_debug("%s: split-DSI, other ctrl not ready yet\n", + __func__); + return false; + } + } + + return true; +} + /** * mdss_dsi_ulps_config() - Program DSI lanes to enter/exit ULPS mode * @ctrl: pointer to DSI controller structure @@ -1534,20 +1595,9 @@ static int mdss_dsi_ulps_config(struct mdss_dsi_ctrl_pdata *ctrl, pinfo = &pdata->panel_info; mipi = &pinfo->mipi; - if (!mdss_dsi_ulps_feature_enabled(pdata) && - !pinfo->ulps_suspend_enabled) { - pr_debug("%s: ULPS feature is not enabled\n", __func__); - return 0; - } - - /* - * No need to enter ULPS when transitioning from splash screen to - * boot animation since it is expected that the clocks would be turned - * right back on. - */ - if (pinfo->cont_splash_enabled) { - pr_debug("%s: skip ULPS config with splash screen enabled\n", - __func__); + if (!mdss_dsi_is_ulps_req_valid(ctrl, enable)) { + pr_debug("%s: skiping ULPS config for ctrl%d, enable=%d\n", + __func__, ctrl->ndx, enable); return 0; } @@ -1566,9 +1616,9 @@ static int mdss_dsi_ulps_config(struct mdss_dsi_ctrl_pdata *ctrl, if (mipi->data_lane3) active_lanes |= BIT(3); - pr_debug("%s: configuring ulps (%s) for ctrl%d, active lanes=0x%08x\n", + pr_debug("%s: configuring ulps (%s) for ctrl%d, active lanes=0x%08x,clamps=%s\n", __func__, (enable ? "on" : "off"), ctrl->ndx, - active_lanes); + active_lanes, ctrl->mmss_clamp ? "enabled" : "disabled"); if (enable && !ctrl->ulps) { /* @@ -1914,7 +1964,6 @@ int mdss_dsi_pre_clkoff_cb(void *priv, } if ((clk & MDSS_DSI_CORE_CLK) && (new_state == MDSS_DSI_CLK_OFF)) { - /* * Enable DSI clamps only if entering idle power collapse or * when ULPS during suspend is enabled. @@ -1925,6 +1974,15 @@ int mdss_dsi_pre_clkoff_cb(void *priv, if (rc) pr_err("%s: Failed to enable dsi clamps. rc=%d\n", __func__, rc); + } else { + /* + * Make sure that controller is not in ULPS state when + * the DSI link is not active. + */ + rc = mdss_dsi_ulps_config(ctrl, 0); + if (rc) + pr_err("%s: failed to disable ulps. rc=%d\n", + __func__, rc); } }