aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaojian Zhuang <haojian.zhuang@linaro.org>2014-07-01 14:05:52 +0800
committerHaojian Zhuang <haojian.zhuang@linaro.org>2014-07-01 14:05:52 +0800
commit76c246d0700f134c73d68da62d42d040bfbdbf82 (patch)
tree137e5bda813d35b16ac74ba37f6a96379509b54c
parent0a4cbd537875d9d90ab3d3754aa436d7f1b88571 (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.c165
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;
}