diff options
author | Nitin Agrawal <nitina@nvidia.com> | 2012-11-21 10:53:23 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 12:43:20 -0700 |
commit | 25b7ec63f5fad81e1ef17cbe8c816c501b045040 (patch) | |
tree | 24189958ecb58ae3431eed7daf1c3d3ba0c79e98 | |
parent | 08b33eecdb2b3d91e7cff3ed9fe87dde7bca53f0 (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.c | 54 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pm.h | 11 |
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_ */ |