arm: tegra14: bbc: update core suspend about EMC rate
Vinayak Pane [Thu, 6 Jun 2013 23:07:11 +0000 (16:07 -0700)]
Inform LP1BB entry part about the current BBC emc floor and
the corresponding voltage required. These EMC parameters can
be used by LP1 entry low power routine to set optimal values
before entering in LP1BB hw state. The EMC parameter should
also be used by lp1bb exit routine to set the required EMC
frequency and voltage to minimize suspend-resume latency.

Bug 1270116
Bug 1301005

Change-Id: I1a979ae92fd4d579cd5ecc293f5c40203b440e4d
Signed-off-by: Vinayak Pane <vpane@nvidia.com>
Reviewed-on: http://git-master/r/238239
(cherry picked from commit 6b083a4101c7d30dd14b391b2381ed91b938306f)
Reviewed-on: http://git-master/r/254495
Reviewed-by: Mandar Padmawar <mpadmawar@nvidia.com>
Tested-by: Mandar Padmawar <mpadmawar@nvidia.com>

arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.h
arch/arm/mach-tegra/tegra_bb.c

index 9ad2b8b..a188007 100644 (file)
@@ -218,7 +218,7 @@ extern int tegra_smmu_suspend(struct device *dev);
 static struct clk *tegra_dfll;
 #endif
 static struct clk *tegra_pclk;
-static const struct tegra_suspend_platform_data *pdata;
+static struct tegra_suspend_platform_data *pdata;
 static enum tegra_suspend_mode current_suspend_mode = TEGRA_SUSPEND_NONE;
 
 #if defined(CONFIG_TEGRA_CLUSTER_CONTROL) && INSTRUMENT_CLUSTER_SWITCH
@@ -1705,6 +1705,12 @@ fail:
        current_suspend_mode = plat->suspend_mode;
 }
 
+void tegra_lp1bb_suspend_emc_rate(unsigned long emc_min, unsigned long emc_max)
+{
+       pdata->lp1bb_emc_rate_min = emc_min;
+       pdata->lp1bb_emc_rate_max = emc_max;
+}
+
 unsigned long debug_uart_port_base = 0;
 EXPORT_SYMBOL(debug_uart_port_base);
 
index 2474883..7f605f9 100644 (file)
@@ -78,6 +78,9 @@ struct tegra_suspend_platform_data {
        unsigned int lp1_core_volt_low;
        unsigned int lp1_core_volt_high;
 #endif
+       unsigned int lp1bb_core_volt_min;
+       unsigned long lp1bb_emc_rate_min;
+       unsigned long lp1bb_emc_rate_max;
 #ifdef CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE
        unsigned long min_residency_vmin_fmin;
        unsigned long min_residency_ncpu_slow;
@@ -110,6 +113,7 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags);
 #ifdef CONFIG_TEGRA_LP1_LOW_COREVOLTAGE
 int tegra_is_lp1_suspend_mode(void);
 #endif
+void tegra_lp1bb_suspend_emc_rate(unsigned long emc_min, unsigned long emc_max);
 
 #ifdef CONFIG_ARCH_TEGRA_14x_SOC
 #define FLOW_CTRL_CLUSTER_CONTROL \
index de58207..54a37f5 100644 (file)
@@ -43,6 +43,7 @@
 #include "iomap.h"
 #include "sleep.h"
 #include "tegra_emc.h"
+#include "pm.h"
 
 /* BB mailbox offset */
 #define TEGRA_BB_REG_MAILBOX (0x0)
@@ -1050,16 +1051,18 @@ static int tegra_bb_pm_notifier_event(struct notifier_block *this,
 
        switch (event) {
        case PM_SUSPEND_PREPARE:
+               /* inform tegra_common_suspend about EMC requirement */
+               tegra_lp1bb_suspend_emc_rate(bb->emc_min_freq, BBC_MC_MIN_FREQ);
+
                /* prepare for possible LP1BB state */
-               if (sts) {
-                       pr_debug("prepare for lp1bb %lu\n", bb->emc_min_freq);
+               if (sts)
                        clk_set_rate(bb->emc_clk, BBC_MC_MIN_FREQ);
-               }
+
                return NOTIFY_OK;
 
        case PM_POST_SUSPEND:
                if (sts && !mem_req_soon) {
-                       pr_debug("bbc is inactive so remove floor\n");
+                       pr_debug("bbc is inactive, remove floor\n");
                        clk_set_rate(bb->emc_clk, 0);
                }
                /* else, wait for IRQs to do the job */