summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNitin Agrawal <nitina@nvidia.com>2012-11-21 10:53:23 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 12:43:20 -0700
commit25b7ec63f5fad81e1ef17cbe8c816c501b045040 (patch)
tree24189958ecb58ae3431eed7daf1c3d3ba0c79e98
parent08b33eecdb2b3d91e7cff3ed9fe87dde7bca53f0 (diff)
arm: tegra: API for cluster switching
API for doing cluster switching so that we can do cluster switching within the kernel from another process explictly. Bug 1058804 Reviewed-on: http://git-master/r/141961 (cherry picked from commit 96e05643a4b1ea2c566ab5cf07642645f4f935bb) Signed-off-by: Nitin Agrawal <nitina@nvidia.com> Change-Id: Ic4821fbd507327d7c951ab74ae7b1febc6f5bbe6 Reviewed-on: http://git-master/r/161869 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bob Johnston <bjohnston@nvidia.com> Reviewed-by: Sumeet Gupta <sumeetg@nvidia.com> Reviewed-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Nagaraj Kolur <nkolur@nvidia.com> Reviewed-by: Bo Yan <byan@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/pm-t3.c54
-rw-r--r--arch/arm/mach-tegra/pm.h11
2 files changed, 65 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/pm-t3.c b/arch/arm/mach-tegra/pm-t3.c
index 7222b763bb61..b6773f46a130 100644
--- a/arch/arm/mach-tegra/pm-t3.c
+++ b/arch/arm/mach-tegra/pm-t3.c
@@ -484,6 +484,60 @@ int tegra_cluster_control(unsigned int us, unsigned int flags)
return 0;
}
+
+int tegra_switch_to_lp_cluster()
+{
+ struct clk *cpu_clk = tegra_get_clock_by_name("cpu");
+ struct clk *cpu_lp_clk = tegra_get_clock_by_name("cpu_lp");
+ int rate = clk_get_rate(cpu_clk);
+ int e;
+
+ if (is_lp_cluster())
+ return 0;
+
+ /* Change the Clock Rate to desired LP CPU's clock rate */
+
+ if (rate > cpu_lp_clk->max_rate) {
+ e = clk_set_rate(cpu_clk, cpu_lp_clk->max_rate);
+ if (e) {
+ pr_err("cluster_swtich: Failed to set clock %d", e);
+ return e;
+ }
+ }
+
+ e = clk_set_parent(cpu_clk, cpu_lp_clk);
+ if (e) {
+ pr_err("cluster switching request failed (%d)\n", e);
+ return e;
+ }
+ return e;
+}
+
+int tegra_switch_to_g_cluster()
+{
+ struct clk *cpu_clk = tegra_get_clock_by_name("cpu");
+ struct clk *cpu_g_clk = tegra_get_clock_by_name("cpu_g");
+ int e;
+
+ if (!is_lp_cluster())
+ return 0;
+
+ e = clk_set_parent(cpu_clk, cpu_g_clk);
+ if (e) {
+ pr_err("cluster switching request failed (%d)\n", e);
+ return e;
+ }
+
+ /* Switch back to G Cluster Cpu Max Clock rate */
+
+ e = clk_set_rate(cpu_clk, cpu_g_clk->max_rate);
+ if (e) {
+ pr_err("cluster_swtich: Failed to increase the clock %d\n", e);
+ return e;
+ }
+ return e;
+}
+
#endif
#ifdef CONFIG_PM_SLEEP
diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h
index aebe2052ee52..b2c7bf820bf9 100644
--- a/arch/arm/mach-tegra/pm.h
+++ b/arch/arm/mach-tegra/pm.h
@@ -155,6 +155,8 @@ static inline unsigned int is_lp_cluster(void)
int tegra_cluster_control(unsigned int us, unsigned int flags);
void tegra_cluster_switch_prolog(unsigned int flags);
void tegra_cluster_switch_epilog(unsigned int flags);
+int tegra_switch_to_g_cluster(void);
+int tegra_switch_to_lp_cluster(void);
#else
#define INSTRUMENT_CLUSTER_SWITCH 0 /* Must be zero for ARCH_TEGRA_2x_SOC */
#define DEBUG_CLUSTER_SWITCH 0 /* Must be zero for ARCH_TEGRA_2x_SOC */
@@ -168,6 +170,14 @@ static inline int tegra_cluster_control(unsigned int us, unsigned int flags)
}
static inline void tegra_cluster_switch_prolog(unsigned int flags) {}
static inline void tegra_cluster_switch_epilog(unsigned int flags) {}
+static inline int tegra_switch_to_g_cluster(void)
+{
+ return -EPERM;
+}
+static inline int tegra_switch_to_lp_cluster(void)
+{
+ return -EPERM;
+}
#endif
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
@@ -260,4 +270,5 @@ extern struct clk *debug_uart_clk;
void tegra_console_uart_suspend(void);
void tegra_console_uart_resume(void);
+
#endif /* _MACH_TEGRA_PM_H_ */