summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/platsmp.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-03-13 00:41:14 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:42:27 -0800
commit4f325a029dc651dd924002a456b039a7bc00385b (patch)
treefc46cbc51917b61184ba5392446916ef04423336 /arch/arm/mach-tegra/platsmp.c
parente630c3d716c0a883995c0b7a2938c35d5de25b72 (diff)
ARM: tegra: clock: Re-factor Tegra3 cpu clocks
Added second level virtualization (on top of virtual cpu rate control) to support different Tegra3 CPU power modes: low power (LP) mode and geared performance (G) mode. Virtual cpu complex (cpu_cmplx) clock is defined as a child with two parents: virtual cpu_lp and virtual cpu_g clocks for the respective modes. Mode switch sequence was integrated into cpu_cmplx set parent implementation. (Before this commit mode switch was triggered outside the clock framework, which created cpu clock/mode synchronization problems). Each mode clock is derived from its own super clock mux (cclk_lp and cclk_g) to statically match Tegra3 h/w layout. (Before this commit the code had to dynamically synchronize CPU mode and active mux selection). This change also allowed to support PLLX output divider for low power mode as fixed 1:2 divider with bypass control embedded into cclk_lp parent section. Updated auto and sysfs CPU mode switch calls to use new clock framework, and removed clock manipulation from the low level mode switch implementation. Original-Change-Id: Ibc3cc495b2ff29e2d3417eff2bfd45535cbd015b Reviewed-on: http://git-master/r/24734 Reviewed-by: Aleksandr Frid <afrid@nvidia.com> Tested-by: Aleksandr Frid <afrid@nvidia.com> Tested-by: Jin Qian <jqian@nvidia.com> Reviewed-by: Scott Williams <scwilliams@nvidia.com> Original-Change-Id: I23ae80edbf14fb22727a6fc317cd9e5baf8bd6be Rebase-Id: Rdcd4a2165ebd92bf4caa35d68ca81d19a3789351
Diffstat (limited to 'arch/arm/mach-tegra/platsmp.c')
-rw-r--r--arch/arm/mach-tegra/platsmp.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index e903da701bfb..74af22d64f2b 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -19,6 +19,7 @@
#include <linux/io.h>
#include <linux/smp.h>
#include <linux/delay.h>
+#include <linux/clk.h>
#include <asm/hardware/gic.h>
#include <asm/smp_scu.h>
@@ -27,6 +28,7 @@
#include <mach/powergate.h>
#include "pm.h"
+#include "clock.h"
#define EVP_CPU_RESET_VECTOR \
(IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
@@ -79,16 +81,25 @@ int boot_secondary(unsigned int cpu, struct task_struct *idle)
int status;
if (is_lp_cluster()) {
+ struct clk *cpu_clk, *cpu_g_clk;
+
/* The G CPU may not be available for a
variety of reasons. */
status = is_g_cluster_available(cpu);
if (status)
return status;
- /* Switch to the G CPU before continuing. */
- status = tegra_cluster_control(0,
- TEGRA_POWER_CLUSTER_G |
- TEGRA_POWER_CLUSTER_IMMEDIATE);
+ cpu_clk = tegra_get_clock_by_name("cpu");
+ cpu_g_clk = tegra_get_clock_by_name("cpu_g");
+
+ /* Switch to G CPU before continuing. */
+ if (!cpu_clk || !cpu_g_clk) {
+ /* Early boot, clock infrastructure is not initialized
+ - CPU mode switch is not allowed */
+ status = -EINVAL;
+ } else
+ status = clk_set_parent(cpu_clk, cpu_g_clk);
+
if (status)
return status;
}