From 6d9f602c728b3f41f24a965ef60db0f273f51cbe Mon Sep 17 00:00:00 2001 From: Abhijit Kulkarni Date: Thu, 16 Feb 2017 19:02:17 -0800 Subject: [PATCH] msm: dsi: Turn off supplies in low power state This change allows certain phy supplies to be turned off when display transtions to low power state. This change adds funtionality to check each supplies setting and accordingly turns off the the regulator if it is allowed in low power state. CRs-Fixed: 2009863 Change-Id: I764a8e65246b5de733f27e4f73d966b19039895d Signed-off-by: Abhijit Kulkarni --- .../devicetree/bindings/fb/mdss-dsi.txt | 2 ++ drivers/video/fbdev/msm/mdss_dsi.c | 10 ++++--- drivers/video/fbdev/msm/msm_mdss_io_8974.c | 26 ++++++++++++++++--- include/linux/mdss_io_util.h | 4 ++- 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/fb/mdss-dsi.txt b/Documentation/devicetree/bindings/fb/mdss-dsi.txt index 6c20d22f98b4..0d55389f3790 100644 --- a/Documentation/devicetree/bindings/fb/mdss-dsi.txt +++ b/Documentation/devicetree/bindings/fb/mdss-dsi.txt @@ -50,6 +50,8 @@ Optional properties: -- qcom,supply-post-on-sleep: time to sleep (ms) after turning on -- qcom,supply-pre-off-sleep: time to sleep (ms) before turning off -- qcom,supply-post-off-sleep: time to sleep (ms) after turning off + -- qcom,supply-lp-mode-disable-allowed: supply can be turned off in + low power state. - pll-src-config Specified the source PLL for the DSI link clocks: "PLL0" - Clocks sourced out of DSI PLL0 diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 17722eac3006..dbf302d76d7b 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -570,7 +570,11 @@ static int mdss_dsi_get_dt_vreg_data(struct device *dev, mp->vreg_config[i].post_off_sleep = tmp; } - pr_debug("%s: %s min=%d, max=%d, enable=%d, disable=%d, preonsleep=%d, postonsleep=%d, preoffsleep=%d, postoffsleep=%d\n", + mp->vreg_config[i].lp_disable_allowed = + of_property_read_bool(supply_node, + "qcom,supply-lp-mode-disable-allowed"); + + pr_debug("%s: %s min=%d, max=%d, enable=%d, disable=%d, preonsleep=%d, postonsleep=%d, preoffsleep=%d, postoffsleep=%d lp_disable_allowed=%d\n", __func__, mp->vreg_config[i].vreg_name, mp->vreg_config[i].min_voltage, @@ -580,8 +584,8 @@ static int mdss_dsi_get_dt_vreg_data(struct device *dev, mp->vreg_config[i].pre_on_sleep, mp->vreg_config[i].post_on_sleep, mp->vreg_config[i].pre_off_sleep, - mp->vreg_config[i].post_off_sleep - ); + mp->vreg_config[i].post_off_sleep, + mp->vreg_config[i].lp_disable_allowed); ++i; } diff --git a/drivers/video/fbdev/msm/msm_mdss_io_8974.c b/drivers/video/fbdev/msm/msm_mdss_io_8974.c index 03e78733d168..e232d98a7cf7 100644 --- a/drivers/video/fbdev/msm/msm_mdss_io_8974.c +++ b/drivers/video/fbdev/msm/msm_mdss_io_8974.c @@ -2419,9 +2419,16 @@ int mdss_dsi_post_clkoff_cb(void *priv, pdata = &ctrl->panel_data; for (i = DSI_MAX_PM - 1; i >= DSI_CORE_PM; i--) { - if ((ctrl->ctrl_state & CTRL_STATE_DSI_ACTIVE) && - (i != DSI_CORE_PM)) - continue; + /** + * If DSI_CTRL is active, proceed to turn off + * supplies which support turning off in low power + * state + */ + if (ctrl->ctrl_state & CTRL_STATE_DSI_ACTIVE) + if (!sdata->power_data[i].vreg_config + ->lp_disable_allowed) + continue; + rc = msm_dss_enable_vreg( sdata->power_data[i].vreg_config, sdata->power_data[i].num_vreg, 0); @@ -2431,6 +2438,12 @@ int mdss_dsi_post_clkoff_cb(void *priv, __mdss_dsi_pm_name(i)); rc = 0; } else { + pr_debug("%s: disabled vreg for %s panel_state %d\n", + __func__, + __mdss_dsi_pm_name(i), + pdata->panel_info.panel_power_state); + sdata->power_data[i].vreg_config->disabled = + true; ctrl->core_power = false; } } @@ -2470,7 +2483,7 @@ int mdss_dsi_pre_clkon_cb(void *priv, for (i = DSI_CORE_PM; i < DSI_MAX_PM; i++) { if ((ctrl->ctrl_state & CTRL_STATE_DSI_ACTIVE) && (!pdata->panel_info.cont_splash_enabled) && - (i != DSI_CORE_PM)) + (!sdata->power_data[i].vreg_config->disabled)) continue; rc = msm_dss_enable_vreg( sdata->power_data[i].vreg_config, @@ -2480,6 +2493,11 @@ int mdss_dsi_pre_clkon_cb(void *priv, __func__, __mdss_dsi_pm_name(i)); } else { + pr_debug("%s: enabled vregs for %s\n", + __func__, + __mdss_dsi_pm_name(i)); + sdata->power_data[i].vreg_config->disabled = + false; ctrl->core_power = true; } diff --git a/include/linux/mdss_io_util.h b/include/linux/mdss_io_util.h index 5b2587b28737..3cca007e618c 100644 --- a/include/linux/mdss_io_util.h +++ b/include/linux/mdss_io_util.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012, 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012, 2016-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -58,6 +58,8 @@ struct dss_vreg { int post_on_sleep; int pre_off_sleep; int post_off_sleep; + bool lp_disable_allowed; + bool disabled; }; struct dss_gpio {