|
@@ -57,6 +57,14 @@
|
|
|
#define CPU0_NEON_SRST_REQ_EN (1 << 4)
|
|
|
#define CPU0_SRST_REQ_EN (1 << 0)
|
|
|
|
|
|
+#define HIX5HD2_PERI_CRG20 0x50
|
|
|
+#define CRG20_CPU1_RESET (1 << 17)
|
|
|
+
|
|
|
+#define HIX5HD2_PERI_PMC0 0x1000
|
|
|
+#define PMC0_CPU1_WAIT_MTCOMS_ACK (1 << 8)
|
|
|
+#define PMC0_CPU1_PMC_ENABLE (1 << 7)
|
|
|
+#define PMC0_CPU1_POWERDOWN (1 << 3)
|
|
|
+
|
|
|
enum {
|
|
|
HI3620_CTRL,
|
|
|
ERROR_CTRL,
|
|
@@ -157,6 +165,50 @@ void hi3xxx_set_cpu(int cpu, bool enable)
|
|
|
set_cpu_hi3620(cpu, enable);
|
|
|
}
|
|
|
|
|
|
+static bool hix5hd2_hotplug_init(void)
|
|
|
+{
|
|
|
+ struct device_node *np;
|
|
|
+
|
|
|
+ np = of_find_compatible_node(NULL, NULL, "hisilicon,cpuctrl");
|
|
|
+ if (np) {
|
|
|
+ ctrl_base = of_iomap(np, 0);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+void hix5hd2_set_cpu(int cpu, bool enable)
|
|
|
+{
|
|
|
+ u32 val = 0;
|
|
|
+
|
|
|
+ if (!ctrl_base)
|
|
|
+ if (!hix5hd2_hotplug_init())
|
|
|
+ BUG();
|
|
|
+
|
|
|
+ if (enable) {
|
|
|
+ /* power on cpu1 */
|
|
|
+ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_PMC0);
|
|
|
+ val &= ~(PMC0_CPU1_WAIT_MTCOMS_ACK | PMC0_CPU1_POWERDOWN);
|
|
|
+ val |= PMC0_CPU1_PMC_ENABLE;
|
|
|
+ writel_relaxed(val, ctrl_base + HIX5HD2_PERI_PMC0);
|
|
|
+ /* unreset */
|
|
|
+ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_CRG20);
|
|
|
+ val &= ~CRG20_CPU1_RESET;
|
|
|
+ writel_relaxed(val, ctrl_base + HIX5HD2_PERI_CRG20);
|
|
|
+ } else {
|
|
|
+ /* power down cpu1 */
|
|
|
+ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_PMC0);
|
|
|
+ val |= PMC0_CPU1_PMC_ENABLE | PMC0_CPU1_POWERDOWN;
|
|
|
+ val &= ~PMC0_CPU1_WAIT_MTCOMS_ACK;
|
|
|
+ writel_relaxed(val, ctrl_base + HIX5HD2_PERI_PMC0);
|
|
|
+
|
|
|
+ /* reset */
|
|
|
+ val = readl_relaxed(ctrl_base + HIX5HD2_PERI_CRG20);
|
|
|
+ val |= CRG20_CPU1_RESET;
|
|
|
+ writel_relaxed(val, ctrl_base + HIX5HD2_PERI_CRG20);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static inline void cpu_enter_lowpower(void)
|
|
|
{
|
|
|
unsigned int v;
|
|
@@ -199,4 +251,10 @@ int hi3xxx_cpu_kill(unsigned int cpu)
|
|
|
hi3xxx_set_cpu(cpu, false);
|
|
|
return 1;
|
|
|
}
|
|
|
+
|
|
|
+void hix5hd2_cpu_die(unsigned int cpu)
|
|
|
+{
|
|
|
+ flush_cache_all();
|
|
|
+ hix5hd2_set_cpu(cpu, false);
|
|
|
+}
|
|
|
#endif
|