From 06cc5c1d4d7313bc864e9aac1d1cbd63d8b9ca4c Mon Sep 17 00:00:00 2001 From: Haifeng Yan Date: Fri, 11 Apr 2014 11:54:11 +0800 Subject: ARM: hisi: enable hix5hd2 SoC Enable support for the Hisilicon HiX5HD2 SoC. This HiX5HD2 SoC series support both single and dual Cortex-A9 cores. Add ARCH_HIX5HD2 to distinguish HiX5HD2 from Hi3xxx. They are different in implementation such as SMP, IPs integarted and earlycon configure. Signed-off-by: Haifeng Yan Signed-off-by: Jiancheng Xue Signed-off-by: Haojian Zhuang Acked-by: Wei Xu Signed-off-by: Olof Johansson --- arch/arm/mach-hisi/hotplug.c | 58 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'arch/arm/mach-hisi/hotplug.c') diff --git a/arch/arm/mach-hisi/hotplug.c b/arch/arm/mach-hisi/hotplug.c index abd441b0c604..84e6919f68c7 100644 --- a/arch/arm/mach-hisi/hotplug.c +++ b/arch/arm/mach-hisi/hotplug.c @@ -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 -- cgit v1.2.3-55-g7522