ARM: rockchip: rk3288: enable cpu power down
author黄涛 <huangtao@rock-chips.com>
Thu, 27 Mar 2014 06:52:35 +0000 (14:52 +0800)
committer黄涛 <huangtao@rock-chips.com>
Thu, 27 Mar 2014 06:58:18 +0000 (14:58 +0800)
arch/arm/mach-rockchip/hotplug.c
arch/arm/mach-rockchip/rk3288.c
include/linux/rockchip/cru.h

index 1d00865e8f0e9e7c85a33ff9c0d9140a9e610da0..82612ff32fabb8997112efdc798768c704f7d1b6 100644 (file)
@@ -49,7 +49,7 @@ int rockchip_cpu_kill(unsigned int cpu)
  *
  * Called with IRQs disabled
  */
-void rockchip_cpu_die(unsigned int cpu)
+void rockchip_cpu_die_a9(unsigned int cpu)
 {
        unsigned int v;
 
@@ -86,6 +86,20 @@ void rockchip_cpu_die(unsigned int cpu)
        }
 }
 
+void rockchip_cpu_die(unsigned int cpu)
+{
+       /* notify platform_cpu_kill() that hardware shutdown is finished */
+       cpumask_set_cpu(cpu, &dead_cpus);
+       flush_cache_louis();
+
+       v7_exit_coherency_flush(louis);
+
+       while (1) {
+               dsb();
+               wfi();
+       }
+}
+
 int rockchip_cpu_disable(unsigned int cpu)
 {
        cpumask_clear_cpu(cpu, &dead_cpus);
index d2be731fc6e25db5663a8cc17bf481c0b9b5bb76..8f1566ca951f023b5aee28b3cb96a4fecf2c0095 100644 (file)
@@ -272,7 +272,8 @@ static int rk3288_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
                        SAVE_QOS(hevc_w_qos, HEVC_W);
                        rk3288_pmu_set_idle_request(IDLE_REQ_HEVC, true);
                } else if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
-                       goto out;
+                       writel_relaxed(0x20002 << (pd - PD_CPU_1), RK_CRU_VIRT + RK3288_CRU_SOFTRSTS_CON(0));
+                       dsb();
                }
        }
 
@@ -303,6 +304,8 @@ static int rk3288_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
                        RESTORE_QOS(hevc_r_qos, HEVC_R);
                        RESTORE_QOS(hevc_w_qos, HEVC_W);
                } else if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
+                       writel_relaxed(0x20000 << (pd - PD_CPU_1), RK_CRU_VIRT + RK3288_CRU_SOFTRSTS_CON(0));
+                       dsb();
                        udelay(10);
                        writel_relaxed(virt_to_phys(secondary_startup), RK3288_IMEM_VIRT + 8);
                        writel_relaxed(0xDEADBEAF, RK3288_IMEM_VIRT + 4);
index 11c87bff1e264a2fa34442ea2ce83950536a3012..1e25fcbd0f4b70f968c5bb471b4ece95f9ac15e9 100755 (executable)
@@ -98,6 +98,7 @@ enum rk3288_cru_clk_gate {
 
 #define RK3288_CRU_GLB_SRST_FST_VALUE   0x1b0
 #define RK3288_CRU_GLB_SRST_SND_VALUE   0x1b4
+#define RK3288_CRU_SOFTRST_CON          0x1b8
 #define RK3288_CRU_MISC_CON             0x1e8
 #define RK3288_CRU_GLB_CNT_TH           0x1ec
 #define RK3288_CRU_GLB_RST_CON          0x1f0
@@ -111,4 +112,7 @@ enum rk3288_cru_clk_gate {
 #define RK3288_CRU_EMMC_CON0            0x218
 #define RK3288_CRU_EMMC_CON1            0x21c
 
+#define RK3288_CRU_SOFTRSTS_CON_CNT    (12)
+#define RK3288_CRU_SOFTRSTS_CON(i)     (RK3288_CRU_SOFTRST_CON + ((i) * 4))
+
 #endif