diff options
author | Haojian Zhuang <haojian.zhuang@linaro.org> | 2014-07-01 14:05:52 +0800 |
---|---|---|
committer | Haojian Zhuang <haojian.zhuang@linaro.org> | 2014-07-01 14:05:52 +0800 |
commit | 76c246d0700f134c73d68da62d42d040bfbdbf82 (patch) | |
tree | 137e5bda813d35b16ac74ba37f6a96379509b54c | |
parent | 0a4cbd537875d9d90ab3d3754aa436d7f1b88571 (diff) |
ARM: hisi: update on platmcpm
Since all cores are bring up in UEFI, update it in mcpm code.
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
-rw-r--r-- | arch/arm/mach-hisi/platmcpm.c | 165 |
1 files changed, 28 insertions, 137 deletions
diff --git a/arch/arm/mach-hisi/platmcpm.c b/arch/arm/mach-hisi/platmcpm.c index 2bda12b936f9..143fcdf3fd9f 100644 --- a/arch/arm/mach-hisi/platmcpm.c +++ b/arch/arm/mach-hisi/platmcpm.c @@ -16,123 +16,57 @@ #include "core.h" -/* bits definition in SC_CPU_RESET_REQ[x]/SC_CPU_RESET_DREQ[x] - * 1 -- unreset; 0 -- reset - */ -#define CORE_RESET_BIT(x) (1 << x) -#define NEON_RESET_BIT(x) (1 << (x + 4)) -#define CORE_DEBUG_RESET_BIT(x) (1 << (x + 9)) -#define CLUSTER_L2_RESET_BIT (1 << 8) -#define CLUSTER_DEBUG_RESET_BIT (1 << 13) +#define SC_CPU_RESET_STATUS(x) (0x1520 + (x << 3)) /* * bits definition in SC_CPU_RESET_STATUS[x] * 1 -- reset status; 0 -- unreset status */ -#define CORE_RESET_STATUS(x) (1 << x) -#define NEON_RESET_STATUS(x) (1 << (x + 4)) -#define CORE_DEBUG_RESET_STATUS(x) (1 << (x + 9)) -#define CLUSTER_L2_RESET_STATUS (1 << 8) -#define CLUSTER_DEBUG_RESET_STATUS (1 << 13) #define CORE_WFI_STATUS(x) (1 << (x + 16)) -#define CORE_WFE_STATUS(x) (1 << (x + 20)) -#define CORE_DEBUG_ACK(x) (1 << (x + 24)) - -#define SC_CPU_RESET_REQ(x) (0x520 + (x << 3)) /* reset */ -#define SC_CPU_RESET_DREQ(x) (0x524 + (x << 3)) /* unreset */ -#define SC_CPU_RESET_STATUS(x) (0x1520 + (x << 3)) - -#define FAB_SF_MODE 0x0c -#define FAB_SF_INVLD 0x10 - -/* bits definition in FB_SF_INVLD */ -#define FB_SF_INVLD_START (1 << 8) #define HIP04_MAX_CLUSTERS 4 #define HIP04_MAX_CPUS_PER_CLUSTER 4 -#define POLL_MSEC 10 -#define TIMEOUT_MSEC 1000 +#define POLL_MSEC 10 +#define TIMEOUT_MSEC 1000 + +#define HIP04_CORE_PLUG_ON 0xa1 +#define HIP04_CORE_PLUG_OFF 0xa2 +#define HIP04_CORE_WAIT 0x5a struct hip04_secondary_cpu_data { - u32 bootwrapper_phys; - u32 bootwrapper_size; - u32 bootwrapper_magic; u32 relocation_entry; u32 relocation_size; }; -static void __iomem *relocation, *sysctrl, *fabric; +static void __iomem *relocation, *sysctrl; static int hip04_cpu_table[HIP04_MAX_CLUSTERS][HIP04_MAX_CPUS_PER_CLUSTER]; static DEFINE_SPINLOCK(boot_lock); static struct hip04_secondary_cpu_data hip04_boot; -static bool hip04_cluster_down(unsigned int cluster) -{ - int i; - - for (i = 0; i < HIP04_MAX_CPUS_PER_CLUSTER; i++) - if (hip04_cpu_table[cluster][i]) - return false; - return true; -} - -static void hip04_set_snoop_filter(unsigned int cluster, unsigned int on) -{ - unsigned long data; - - if (!fabric) - BUG(); - data = readl_relaxed(fabric + FAB_SF_MODE); - if (on) - data |= 1 << cluster; - else - data &= ~(1 << cluster); - writel_relaxed(data, fabric + FAB_SF_MODE); - while (1) { - if (data == readl_relaxed(fabric + FAB_SF_MODE)) - break; - } -} - static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) { - unsigned long data, mask; - - if (!relocation || !sysctrl) + if (!relocation) return -ENODEV; if (cluster >= HIP04_MAX_CLUSTERS || cpu >= HIP04_MAX_CPUS_PER_CLUSTER) return -EINVAL; spin_lock_irq(&boot_lock); - if (hip04_cpu_table[cluster][cpu]) { - hip04_cpu_table[cluster][cpu]++; - spin_unlock_irq(&boot_lock); - return 0; - } + if (hip04_cpu_table[cluster][cpu]) + goto out; - writel_relaxed(hip04_boot.bootwrapper_phys, relocation); - writel_relaxed(hip04_boot.bootwrapper_magic, relocation + 4); - writel_relaxed(virt_to_phys(mcpm_entry_point), relocation + 8); - writel_relaxed(0, relocation + 12); - - if (hip04_cluster_down(cluster)) { - data = CLUSTER_DEBUG_RESET_BIT; - writel_relaxed(data, sysctrl + SC_CPU_RESET_DREQ(cluster)); - do { - mask = CLUSTER_DEBUG_RESET_STATUS; - data = readl_relaxed(sysctrl + \ - SC_CPU_RESET_STATUS(cluster)); - } while (data & mask); - hip04_set_snoop_filter(cluster, 1); - } + /* + * Word 0: stage index for SMP boot protocol in HiP04 + * Word 1: Entry address of plug on (MCPM entry in kernel) + * Word 2/3: not used in kernel + * Word 4: Bootwrapper Entry (set in UEFI) + */ + writel_relaxed(HIP04_CORE_PLUG_ON, relocation); + writel_relaxed(virt_to_phys(mcpm_entry_point), relocation + 4); +out: hip04_cpu_table[cluster][cpu]++; - - data = CORE_RESET_BIT(cpu) | NEON_RESET_BIT(cpu) | \ - CORE_DEBUG_RESET_BIT(cpu); - writel_relaxed(data, sysctrl + SC_CPU_RESET_DREQ(cluster)); spin_unlock_irq(&boot_lock); return 0; @@ -140,8 +74,8 @@ static int hip04_mcpm_power_up(unsigned int cpu, unsigned int cluster) static void hip04_mcpm_power_down(void) { - unsigned int mpidr, cpu, cluster, data = 0; - bool skip_reset = false; + unsigned int mpidr, cpu, cluster; + bool skip_wfi = false; mpidr = read_cpuid_mpidr(); cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); @@ -154,7 +88,7 @@ static void hip04_mcpm_power_down(void) hip04_cpu_table[cluster][cpu]--; if (hip04_cpu_table[cluster][cpu] == 1) { /* A power_up request went ahead of us. */ - skip_reset = true; + skip_wfi = true; } else if (hip04_cpu_table[cluster][cpu] > 1) { pr_err("Cluster %d CPU%d boots multiple times\n", cluster, cpu); BUG(); @@ -165,11 +99,8 @@ static void hip04_mcpm_power_down(void) __mcpm_cpu_down(cpu, cluster); - if (!skip_reset) { - data = CORE_RESET_BIT(cpu) | NEON_RESET_BIT(cpu) | \ - CORE_DEBUG_RESET_BIT(cpu); - writel_relaxed(data, sysctrl + SC_CPU_RESET_REQ(cluster)); - } + if (!skip_wfi) + wfi(); } static int hip04_mcpm_wait_for_powerdown(unsigned int cpu, unsigned int cluster) @@ -181,7 +112,7 @@ static int hip04_mcpm_wait_for_powerdown(unsigned int cpu, unsigned int cluster) for (tries = 0; tries < TIMEOUT_MSEC / POLL_MSEC; tries++) { data = readl_relaxed(sysctrl + SC_CPU_RESET_STATUS(cluster)); - if (!(data & CORE_RESET_STATUS(cpu))) { + if (!(data & CORE_WFI_STATUS(cpu))) { msleep(POLL_MSEC); continue; } @@ -195,10 +126,8 @@ static void hip04_mcpm_powered_up(void) if (!relocation) return; spin_lock(&boot_lock); - writel_relaxed(0, relocation); + writel_relaxed(HIP04_CORE_WAIT, relocation); writel_relaxed(0, relocation + 4); - writel_relaxed(0, relocation + 8); - writel_relaxed(0, relocation + 12); spin_unlock(&boot_lock); } @@ -222,41 +151,19 @@ static bool __init hip04_cpu_table_init(void) pr_err("%s: boot CPU is out of bound!\n", __func__); return false; } - hip04_set_snoop_filter(cluster, 1); hip04_cpu_table[cluster][cpu] = 1; return true; } static int __init hip04_mcpm_init(void) { - struct device_node *np, *np_fab; + struct device_node *np; int ret = -ENODEV; np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl"); if (!np) goto err; - np_fab = of_find_compatible_node(NULL, NULL, "hisilicon,hip04-fabric"); - if (!np_fab) - goto err; - if (of_property_read_u32(np, "bootwrapper-phys", - &hip04_boot.bootwrapper_phys)) { - pr_err("failed to get bootwrapper-phys\n"); - ret = -EINVAL; - goto err; - } - if (of_property_read_u32(np, "bootwrapper-size", - &hip04_boot.bootwrapper_size)) { - pr_err("failed to get bootwrapper-size\n"); - ret = -EINVAL; - goto err; - } - if (of_property_read_u32(np, "bootwrapper-magic", - &hip04_boot.bootwrapper_magic)) { - pr_err("failed to get bootwrapper-magic\n"); - ret = -EINVAL; - goto err; - } if (of_property_read_u32(np, "relocation-entry", &hip04_boot.relocation_entry)) { pr_err("failed to get relocation-entry\n"); @@ -277,18 +184,6 @@ static int __init hip04_mcpm_init(void) ret = -ENOMEM; goto err; } - sysctrl = of_iomap(np, 0); - if (!sysctrl) { - pr_err("failed to get sysctrl base\n"); - ret = -ENOMEM; - goto err_sysctrl; - } - fabric = of_iomap(np_fab, 0); - if (!fabric) { - pr_err("failed to get fabric base\n"); - ret = -ENOMEM; - goto err_fabric; - } if (!hip04_cpu_table_init()) return -EINVAL; @@ -299,10 +194,6 @@ static int __init hip04_mcpm_init(void) } mcpm_smp_set_ops(); return ret; -err_fabric: - iounmap(sysctrl); -err_sysctrl: - iounmap(relocation); err: return ret; } |