diff options
author | Prem Sasidharan <psasidharan@nvidia.com> | 2012-07-05 11:56:14 -0700 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-07-19 14:48:09 -0700 |
commit | 94e947b829c7922cbc2c413db708232dfc7cc4e9 (patch) | |
tree | ae443cd5367b9bd29fb27955951846cdd4f32025 | |
parent | 11d6553a1fa3fe9e0665fe77dd1c2288fe796566 (diff) |
arm: tegra: PLLX LP/G ports switching ON/OFF
Enable target PLLX port(LP/G) before cluster switch and disable
the previous PLLX port(LP/G) after cluster switch is finished.
Seeing a power improvement of ~10mW when core operates at
max. voltage and max. frequency.
Bug 997358
Signed-off-by: Prem Sasidharan <psasidharan@nvidia.com>
Change-Id: I9d05245977f9f63a8f4c53b1c6797118d2d8b903
Reviewed-on: http://git-master/r/113399
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/pm-t3.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/pm-t3.c b/arch/arm/mach-tegra/pm-t3.c index 32a260e2dd43..89f2bb5f0731 100644 --- a/arch/arm/mach-tegra/pm-t3.c +++ b/arch/arm/mach-tegra/pm-t3.c @@ -102,6 +102,12 @@ #define CPU_CLOCK(cpu) (0x1<<(8+cpu)) #define CPU_RESET(cpu) (0x1111ul<<(cpu)) +#define PLLX_FO_G (1<<28) +#define PLLX_FO_LP (1<<29) + +#define CLK_RST_CONTROLLER_PLLX_MISC_0 \ + (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0xE4) + static int cluster_switch_prolog_clock(unsigned int flags) { u32 reg; @@ -189,6 +195,20 @@ static int cluster_switch_prolog_clock(unsigned int flags) return 0; } +static inline void enable_pllx_cluster_port(void) +{ + u32 val = readl(CLK_RST_CONTROLLER_PLLX_MISC_0); + val &= (is_lp_cluster()?(~PLLX_FO_G):(~PLLX_FO_LP)); + writel(val, CLK_RST_CONTROLLER_PLLX_MISC_0); +} + +static inline void disable_pllx_cluster_port(void) +{ + u32 val = readl(CLK_RST_CONTROLLER_PLLX_MISC_0); + val |= (is_lp_cluster()?PLLX_FO_G:PLLX_FO_LP); + writel(val, CLK_RST_CONTROLLER_PLLX_MISC_0); +} + void tegra_cluster_switch_prolog(unsigned int flags) { unsigned int target_cluster = flags & TEGRA_POWER_CLUSTER_MASK; @@ -223,6 +243,9 @@ void tegra_cluster_switch_prolog(unsigned int flags) /* Set up the flow controller to switch CPUs. */ reg |= FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER; + + /* Enable target port of PLL_X */ + enable_pllx_cluster_port(); } } @@ -305,6 +328,9 @@ void tegra_cluster_switch_epilog(unsigned int flags) cluster_switch_epilog_gic(); } + /* Disable unused port of PLL_X */ + disable_pllx_cluster_port(); + #if DEBUG_CLUSTER_SWITCH { /* FIXME: clock functions below are taking mutex */ |