diff options
author | Scott Williams <scwilliams@nvidia.com> | 2011-01-07 10:48:48 -0800 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:42:09 -0800 |
commit | 651f32b43330d536ada1db67cbca454e37e7816b (patch) | |
tree | eaabdd980e1d909f542f8ea07d3ac129ba64321b | |
parent | 0312253d179e4d65f7a4fc698a3cc843420111bf (diff) |
arm: tegra: Enable Tegra3 cluster control
Original-Change-Id: I162c061f8a1851394d6390bc1234910cdf0972b3
Reviewed-on: http://git-master/r/15269
Reviewed-by: Scott Williams <scwilliams@nvidia.com>
Tested-by: Scott Williams <scwilliams@nvidia.com>
Original-Change-Id: I0dc20ab81db7456c0faf3a81984f2821e7d565ae
Rebase-Id: R880097280de4f9691f689ab8ab25f08020e98e23
-rw-r--r-- | arch/arm/mach-tegra/platsmp.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pm-t3.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pm.c | 23 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pm.h | 14 | ||||
-rw-r--r-- | arch/arm/mach-tegra/sysfs-cluster.c | 24 |
5 files changed, 35 insertions, 38 deletions
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index cd375d38d67d..55b06b91a199 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c @@ -115,7 +115,7 @@ int boot_secondary(unsigned int cpu, struct task_struct *idle) CPU this will cause the flow controller to stop driving reset. The CPU will remain in reset because the clock and reset block is now driving reset. */ - flowctrl_writel(0, FLOW_CTRL_HALT_CPUx_EVENTS(cpu)); + flowctrl_writel(0, FLOW_CTRL_HALT_CPU(cpu)); /* enable cpu clock on cpu */ reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX); diff --git a/arch/arm/mach-tegra/pm-t3.c b/arch/arm/mach-tegra/pm-t3.c index 651053d5ce1a..e37e6985e698 100644 --- a/arch/arm/mach-tegra/pm-t3.c +++ b/arch/arm/mach-tegra/pm-t3.c @@ -94,8 +94,6 @@ #define FLOW_CTRL_CLUSTER_CONTROL \ (IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x2c) -#define FLOW_CTRL_CPUx_CSR(cpu) \ - (IO_ADDRESS(TEGRA_FLOW_CTRL_BASE + ((cpu)?(((cpu)-1)*8 + 0x18) : 0x8))) #define FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE (1<<3) #define FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER (1<<2) @@ -229,7 +227,7 @@ void tegra_cluster_switch_prolog(unsigned int flags) /* Read the flow controler CSR register and clear the CPU switch and immediate flags. If an actual CPU switch is to be performed, re-write the CSR register with the desired values. */ - reg = readl(FLOW_CTRL_CPUx_CSR(0)); + reg = readl(FLOW_CTRL_CPU_CSR(0)); reg &= ~(FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE | FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER); @@ -256,7 +254,7 @@ void tegra_cluster_switch_prolog(unsigned int flags) } done: - writel(reg, FLOW_CTRL_CPUx_CSR(0)); + writel(reg, FLOW_CTRL_CPU_CSR(0)); } static void cluster_switch_epilog_gic(void) @@ -290,10 +288,10 @@ void tegra_cluster_switch_epilog(unsigned int flags) /* Make sure the switch and immediate flags are cleared in the flow controller to prevent undesirable side-effects for future users of the flow controller. */ - reg = readl(FLOW_CTRL_CPUx_CSR(0)); + reg = readl(FLOW_CTRL_CPU_CSR(0)); reg &= ~(FLOW_CTRL_CPU_CSR_IMMEDIATE_WAKE | FLOW_CTRL_CPU_CSR_SWITCH_CLUSTER); - writel(reg, FLOW_CTRL_CPUx_CSR(0)); + writel(reg, FLOW_CTRL_CPU_CSR(0)); /* Perform post-switch clean-up of the interrupt distributor */ cluster_switch_epilog_gic(); diff --git a/arch/arm/mach-tegra/pm.c b/arch/arm/mach-tegra/pm.c index 5c0e9be6ee49..269286edc440 100644 --- a/arch/arm/mach-tegra/pm.c +++ b/arch/arm/mach-tegra/pm.c @@ -86,7 +86,6 @@ static void __iomem *iram_code = IO_ADDRESS(TEGRA_IRAM_CODE_AREA); static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); #ifdef CONFIG_PM static void __iomem *clk_rst = IO_ADDRESS(TEGRA_CLK_RESET_BASE); -static void __iomem *flow_ctrl = IO_ADDRESS(TEGRA_FLOW_CTRL_BASE); static void __iomem *evp_reset = IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100; #endif @@ -134,9 +133,6 @@ static void __iomem *evp_reset = #define CLK_RESET_CCLK_BURST_POLICY_PLLM 3 #define CLK_RESET_CCLK_BURST_POLICY_PLLX 8 -#define FLOW_CTRL_CPU_CSR(cpu) ((cpu) == 0 ? 0x8 : (0x18 + 8 * ((cpu) - 1))) -#define FLOW_CTRL_HALT_CPU(cpu) ((cpu) == 0 ? 0x0 : (0x4 + cpu * 0x10)) - #ifdef CONFIG_ARCH_TEGRA_2x_SOC #define FLOW_CTRL_CSR_WFE_CPU0 (1 << 4) #define FLOW_CTRL_CSR_WFE_BITMAP (3 << 4) @@ -270,7 +266,7 @@ static void tegra_wake_reset_cpu(int cpu) writel(reg, clk_rst + 0x344); /* unhalt the cpu */ - writel(0, flow_ctrl + 0x14); + flowctrl_writel(0, FLOW_CTRL_HALT_CPU(1)); } #ifdef CONFIG_PM @@ -330,14 +326,13 @@ static void restore_cpu_complex(void) /* do not power-gate the CPU when flow controlled */ for (i = 0; i < num_possible_cpus(); i++) { - reg = readl(flow_ctrl + FLOW_CTRL_CPU_CSR(i)); + reg = readl(FLOW_CTRL_CPU_CSR(i)); reg &= ~FLOW_CTRL_CSR_WFE_BITMAP; /* clear wfe bitmap */ reg &= ~FLOW_CTRL_CSR_WFI_BITMAP; /* clear wfi bitmap */ reg &= ~FLOW_CTRL_CSR_ENABLE; /* clear enable */ reg |= FLOW_CTRL_CSR_CLEAR_INTR; /* clear intr */ reg |= FLOW_CTRL_CSR_CLEAR_EVENT; /* clear event */ - writel(reg, flow_ctrl + FLOW_CTRL_CPU_CSR(i)); - wmb(); + flowctrl_writel(reg, FLOW_CTRL_CPU_CSR(i)); } } @@ -369,7 +364,7 @@ static void suspend_cpu_complex(void) tegra_sctx.pllp_misc = readl(clk_rst + CLK_RESET_PLLP_MISC); tegra_sctx.cclk_divider = readl(clk_rst + CLK_RESET_CCLK_DIVIDER); - reg = readl(flow_ctrl + FLOW_CTRL_CPU_CSR(cpu)); + reg = readl(FLOW_CTRL_CPU_CSR(cpu)); reg &= ~FLOW_CTRL_CSR_WFE_BITMAP; /* clear wfe bitmap */ reg &= ~FLOW_CTRL_CSR_WFI_BITMAP; /* clear wfi bitmap */ reg |= FLOW_CTRL_CSR_CLEAR_EVENT; /* clear event flag */ @@ -379,18 +374,16 @@ static void suspend_cpu_complex(void) reg |= FLOW_CTRL_CSR_WFI_CPU0 << cpu; /* enable power gating on wfi */ #endif reg |= FLOW_CTRL_CSR_ENABLE; /* enable power gating */ - writel(reg, flow_ctrl + FLOW_CTRL_CPU_CSR(cpu)); - wmb(); + flowctrl_writel(reg, FLOW_CTRL_CPU_CSR(cpu)); for (i = 0; i < num_possible_cpus(); i++) { if (i == cpu) continue; - reg = readl(flow_ctrl + FLOW_CTRL_CPU_CSR(i)); + reg = readl(FLOW_CTRL_CPU_CSR(i)); reg |= FLOW_CTRL_CSR_CLEAR_EVENT; reg |= FLOW_CTRL_CSR_CLEAR_INTR; - writel(reg, flow_ctrl + FLOW_CTRL_CPU_CSR(i)); - writel(0, flow_ctrl + FLOW_CTRL_HALT_CPU(i)); - wmb(); + flowctrl_writel(reg, FLOW_CTRL_CPU_CSR(i)); + flowctrl_writel(0, FLOW_CTRL_HALT_CPU(i)); } } diff --git a/arch/arm/mach-tegra/pm.h b/arch/arm/mach-tegra/pm.h index e8452cc39f2c..6be530c1f2fd 100644 --- a/arch/arm/mach-tegra/pm.h +++ b/arch/arm/mach-tegra/pm.h @@ -86,10 +86,18 @@ unsigned int is_lp_cluster(void); unsigned long tegra_get_lpcpu_max_rate(void); #endif -static inline void flowctrl_writel(unsigned long val, unsigned int offs) +#define FLOW_CTRL_HALT_CPU(cpu) (IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + \ + ((cpu) == 0 ? 0x8 : (0x18 + 8 * ((cpu) - 1)))) +#define FLOW_CTRL_CPU_CSR(cpu) (IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + \ + ((cpu) == 0 ? 0x0 : (0x4 + cpu * 0x10))) + +static inline void flowctrl_writel(unsigned long val, void __iomem *addr) { - __raw_writel(val, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + offs); - (void)__raw_readl(IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + offs); + writel(val, addr); +#ifdef CONFIG_ARCH_TEGRA_2x_SOC + wmb(); +#endif + (void)__raw_readl(addr); } #endif /* _MACH_TEGRA_SUSPEND_H_ */ diff --git a/arch/arm/mach-tegra/sysfs-cluster.c b/arch/arm/mach-tegra/sysfs-cluster.c index 50f9535cb4d9..72ca344493ff 100644 --- a/arch/arm/mach-tegra/sysfs-cluster.c +++ b/arch/arm/mach-tegra/sysfs-cluster.c @@ -90,7 +90,7 @@ #define SYSFS_CLUSTER_PRINTS 1 /* Nonzero: enable status prints */ #define SYSFS_CLUSTER_DEBUG_PRINTS 0 /* Nonzero: enable debug prints */ -#define SYSFS_CLUSTER_POWER_MODE 1 /* Nonzero: use power modes other than LP2*/ +#define SYSFS_CLUSTER_POWER_MODE 0 /* Nonzero: use power modes other than LP2*/ #if SYSFS_CLUSTER_DEBUG_PRINTS #define DEBUG_CLUSTER(x) printk x @@ -106,13 +106,10 @@ #define FLOW_CTRL_CLUSTER_CONTROL \ (IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x2c) -#define FLOW_CTRL_CPUx_CSR(cpu) \ - (IO_ADDRESS(TEGRA_FLOW_CTRL_BASE + ((cpu)?(((cpu)-1)*8 + 0x18) : 0x8))) static struct kobject *cluster_kobj; static spinlock_t cluster_lock; static unsigned int flags = 0; -static unsigned int power_mode = 2; static unsigned int wake_ms = 0; static ssize_t sysfscluster_show(struct kobject *kobj, @@ -137,8 +134,9 @@ static struct kobj_attribute cluster_force_attr = static struct kobj_attribute cluster_wake_ms_attr = __ATTR(wake_ms, 0640, sysfscluster_show, sysfscluster_store); -#if SYSFS_CLUSTER_POWER_MODE -/* LPx power mode to use when switching CPUs: 1, 2 */ +#if defined(CONFIG_PM) && SYSFS_CLUSTER_POWER_MODE +/* LPx power mode to use when switching CPUs: 1=LP1, 2=LP2 */ +static unsigned int power_mode = 2; static struct kobj_attribute cluster_powermode_attr = __ATTR(power_mode, 0640, sysfscluster_show, sysfscluster_store); #endif @@ -150,7 +148,7 @@ typedef enum ClusterAttr_Immediate, ClusterAttr_Force, ClusterAttr_WakeMs, -#if SYSFS_CLUSTER_POWER_MODE +#if defined(CONFIG_PM) && SYSFS_CLUSTER_POWER_MODE ClusterAttr_PowerMode #endif } ClusterAttr; @@ -165,7 +163,7 @@ static ClusterAttr GetClusterAttr(const char *name) return ClusterAttr_Force; if (!strcmp(name, "wake_ms")) return ClusterAttr_WakeMs; -#if SYSFS_CLUSTER_POWER_MODE +#if defined(CONFIG_PM) && SYSFS_CLUSTER_POWER_MODE if (!strcmp(name, "power_mode")) return ClusterAttr_PowerMode; #endif @@ -201,7 +199,7 @@ static ssize_t sysfscluster_show(struct kobject *kobj, len = sprintf(buf, "%d\n", wake_ms); break; -#if SYSFS_CLUSTER_POWER_MODE +#if defined(CONFIG_PM) && SYSFS_CLUSTER_POWER_MODE case ClusterAttr_PowerMode: len = sprintf(buf, "%d\n", power_mode); break; @@ -263,7 +261,7 @@ static ssize_t sysfscluster_store(struct kobject *kobj, (flags & TEGRA_POWER_CLUSTER_G) ? "G" : "LP")); request = flags; -#if SYSFS_CLUSTER_POWER_MODE +#if defined(CONFIG_PM) && SYSFS_CLUSTER_POWER_MODE if (power_mode == 1) { request |= TEGRA_POWER_SDRAM_SELFREFRESH; } @@ -319,7 +317,7 @@ static ssize_t sysfscluster_store(struct kobject *kobj, PRINT_CLUSTER(("cluster/wake_ms -> %d\n", wake_ms)); break; -#if SYSFS_CLUSTER_POWER_MODE +#if defined(CONFIG_PM) && SYSFS_CLUSTER_POWER_MODE case ClusterAttr_PowerMode: if ((count == 1) && (*buf == '2')) power_mode = 2; @@ -370,7 +368,7 @@ static int __init sysfscluster_init(void) CREATE_FILE(immediate); CREATE_FILE(force); CREATE_FILE(wake_ms); -#if SYSFS_CLUSTER_POWER_MODE +#if defined(CONFIG_PM) && SYSFS_CLUSTER_POWER_MODE CREATE_FILE(powermode); #endif @@ -392,7 +390,7 @@ fail: static void __exit sysfscluster_exit(void) { DEBUG_CLUSTER(("+sysfscluster_exit\n")); -#if SYSFS_CLUSTER_POWER_MODE +#if defined(CONFIG_PM) && SYSFS_CLUSTER_POWER_MODE REMOVE_FILE(powermode); #endif REMOVE_FILE(wake_ms); |