summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Williams <scwilliams@nvidia.com>2011-01-07 10:48:48 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:42:09 -0800
commit651f32b43330d536ada1db67cbca454e37e7816b (patch)
treeeaabdd980e1d909f542f8ea07d3ac129ba64321b
parent0312253d179e4d65f7a4fc698a3cc843420111bf (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.c2
-rw-r--r--arch/arm/mach-tegra/pm-t3.c10
-rw-r--r--arch/arm/mach-tegra/pm.c23
-rw-r--r--arch/arm/mach-tegra/pm.h14
-rw-r--r--arch/arm/mach-tegra/sysfs-cluster.c24
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);