From e51702e4ddecdfcabfbfcfcb9e9b40938b4f0644 Mon Sep 17 00:00:00 2001 From: Ingrid Gallardo Date: Thu, 12 Jan 2017 17:31:15 -0800 Subject: [PATCH 1/2] msm: mdss: fix for the mmss gdsc sequence Current Display driver sets to true the ram status variable shared with the RPM to prevent MMSS GDSC to go OFF only when we are about to disable the MDSS GDSC regulator for the Idle Screen scenario; The potential problem with this is that there is a 4-vsyncs period of time between the end of the display last transaction (ping pong done) and the release of the MDSS GDSC regulator (for Idle Screen) where the Display related clocks are already released and MDSS GDSC regulator is still on (so rpm variable is still false), causing that Xo shutdown (and therefore MMSS GDSC off) can happen while the MDSS GDSC is still active during this period of time. This change makes sure that any time that the MDSS GDSC regulator is enabled or when the MDSS GDSC regulator is disabled but the Display is still active but in Idle Screen, Display sets the flag to ensure that the MMSS GDSC regulator is not disabled by the RPM, flag is released once our MDSS regulator is disabled for Suspend. Also, re-arrange the sequence to make sure the change of the flag happens after we disabled the MDSS GDSC regulator, so we prevent that by any reason the MDSS GDSC could go off before the MMSS GDSC regulator. Change-Id: I141cb893c4e2a54f99e65383e69b4ce88ab4c761 Signed-off-by: Ingrid Gallardo --- drivers/video/fbdev/msm/mdss_mdp.c | 40 +++++++++++++++++++----------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index 58e0d9676736..ce56fb021d15 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -1,7 +1,7 @@ /* * MDSS MDP Interface (used by framebuffer core) * - * Copyright (c) 2007-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2007-2017, The Linux Foundation. All rights reserved. * Copyright (C) 2007 Google Incorporated * * This software is licensed under the terms of the GNU General Public @@ -4904,6 +4904,7 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on) { int ret; int active_cnt = 0; + bool footswitch_suspend = false; if (!mdata->fs) return; @@ -4920,6 +4921,15 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on) pr_err("venus failed to enable\n"); } + /* + * Advise RPM to not turn MMSS GDSC off, this will + * ensure that GDSC off is maintained during Active + * display and during Idle display + */ + if (mdss_has_quirk(mdata, + MDSS_QUIRK_MMSS_GDSC_COLLAPSE)) + mdss_rpm_set_msg_ram(true); + ret = regulator_enable(mdata->fs); if (ret) pr_warn("Footswitch failed to enable\n"); @@ -4936,13 +4946,6 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on) pr_debug("Disable MDP FS\n"); active_cnt = atomic_read(&mdata->active_intf_cnt); if (active_cnt != 0) { - /* - * Advise RPM to not turn MMSS GDSC off during - * idle case. - */ - if (mdss_has_quirk(mdata, - MDSS_QUIRK_MMSS_GDSC_COLLAPSE)) - mdss_rpm_set_msg_ram(true); /* * Turning off GDSC while overlays are still * active. @@ -4954,14 +4957,8 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on) pr_debug("idle pc. active overlays=%d\n", active_cnt); } else { - /* - * Advise RPM to turn MMSS GDSC off during - * suspend case - */ - if (mdss_has_quirk(mdata, - MDSS_QUIRK_MMSS_GDSC_COLLAPSE)) - mdss_rpm_set_msg_ram(false); + footswitch_suspend = true; mdss_mdp_cx_ctrl(mdata, false); mdss_mdp_batfet_ctrl(mdata, false); mdss_mdp_memory_retention_ctrl( @@ -4974,6 +4971,19 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on) regulator_disable(mdata->fs); if (mdata->venus) regulator_disable(mdata->venus); + + if (footswitch_suspend) { + /* + * Advise RPM to turn MMSS GDSC off during + * suspend case, do this after the MDSS GDSC + * regulator OFF, so we can ensure that MMSS + * GDSC will go OFF after the MDSS GDSC + * regulator + */ + if (mdss_has_quirk(mdata, + MDSS_QUIRK_MMSS_GDSC_COLLAPSE)) + mdss_rpm_set_msg_ram(false); + } } mdata->fs_ena = false; } From a1c43be00a3a56b3783e8fe2caa3349fa6b10457 Mon Sep 17 00:00:00 2001 From: Ingrid Gallardo Date: Mon, 23 Jan 2017 12:43:58 -0800 Subject: [PATCH 2/2] msm: mdss: enforce bimc smmu gdsc power sequence Fix the power on/off sequence based on the hw recommendation, where bimc smmu gdsc is powered off after mdss gdsc; and for the power on sequence the bimc smmu gdsc is enabled before the mdss gdsc. Change-Id: Iad005082bcdb07f5529cd5eafd6ecd9c250c9665 Signed-off-by: Ingrid Gallardo --- drivers/video/fbdev/msm/mdss.h | 4 ++-- drivers/video/fbdev/msm/mdss_mdp.c | 32 ++++++++++++++++-------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index 5a6d7bc3ff78..ecb04bb81337 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -281,7 +281,7 @@ struct mdss_data_type { u32 mdp_rev; struct clk *mdp_clk[MDSS_MAX_CLK]; struct regulator *fs; - struct regulator *venus; + struct regulator *core_gdsc; struct regulator *vdd_cx; u32 vdd_cx_min_uv; u32 vdd_cx_max_uv; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index ce56fb021d15..23e12aef12cf 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -1739,11 +1739,13 @@ static int mdss_mdp_irq_clk_setup(struct mdss_data_type *mdata) return -EINVAL; } - mdata->venus = devm_regulator_get_optional(&mdata->pdev->dev, - "gdsc-venus"); - if (IS_ERR_OR_NULL(mdata->venus)) { - mdata->venus = NULL; - pr_debug("unable to get venus gdsc regulator\n"); + mdata->core_gdsc = devm_regulator_get_optional(&mdata->pdev->dev, + "gdsc-core"); + if (IS_ERR_OR_NULL(mdata->core_gdsc)) { + mdata->core_gdsc = NULL; + pr_err("unable to get core gdsc regulator\n"); + } else { + pr_debug("core gdsc regulator found\n"); } mdata->fs_ena = false; @@ -2274,10 +2276,10 @@ void mdss_mdp_footswitch_ctrl_splash(int on) if (on) { mdata->handoff_pending = true; pr_debug("Enable MDP FS for splash.\n"); - if (mdata->venus) { - ret = regulator_enable(mdata->venus); + if (mdata->core_gdsc) { + ret = regulator_enable(mdata->core_gdsc); if (ret) - pr_err("venus failed to enable\n"); + pr_err("core_gdsc failed to enable\n"); } ret = regulator_enable(mdata->fs); @@ -2291,8 +2293,8 @@ void mdss_mdp_footswitch_ctrl_splash(int on) mdss_bus_bandwidth_ctrl(false); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF); regulator_disable(mdata->fs); - if (mdata->venus) - regulator_disable(mdata->venus); + if (mdata->core_gdsc) + regulator_disable(mdata->core_gdsc); mdata->handoff_pending = false; } } else { @@ -4915,10 +4917,10 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on) if (on) { if (!mdata->fs_ena) { pr_debug("Enable MDP FS\n"); - if (mdata->venus) { - ret = regulator_enable(mdata->venus); + if (mdata->core_gdsc) { + ret = regulator_enable(mdata->core_gdsc); if (ret) - pr_err("venus failed to enable\n"); + pr_err("core_gdsc failed to enable\n"); } /* @@ -4969,8 +4971,8 @@ static void mdss_mdp_footswitch_ctrl(struct mdss_data_type *mdata, int on) if (mdata->en_svs_high) mdss_mdp_config_cx_voltage(mdata, false); regulator_disable(mdata->fs); - if (mdata->venus) - regulator_disable(mdata->venus); + if (mdata->core_gdsc) + regulator_disable(mdata->core_gdsc); if (footswitch_suspend) { /*