arm: tegra: Enable Tegra3 cluster control
Scott Williams [Fri, 7 Jan 2011 18:48:48 +0000 (10:48 -0800)]
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

arch/arm/mach-tegra/platsmp.c
arch/arm/mach-tegra/pm-t3.c
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.h
arch/arm/mach-tegra/sysfs-cluster.c

index cd375d3..55b06b9 100644 (file)
@@ -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);
index 651053d..e37e698 100644 (file)
@@ -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();
index 5c0e9be..269286e 100644 (file)
@@ -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));
        }
 }
 
index e8452cc..6be530c 100644 (file)
@@ -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_ */
index 50f9535..72ca344 100644 (file)
@@ -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
 
 #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);