ARM: hisi: enable smp for HiP01

Enable smp for HiP01 board.

Signed-off-by: Wang Long <long.wanglong@huawei.com>
Signed-off-by: Wei Xu <xuwei5@hisilicon.com>
[olof: split off the dts change to a separate commit]
Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
Wang Long 2014-12-24 03:10:02 +00:00 committed by Olof Johansson
parent 29d189e139
commit 7fda91e731
3 changed files with 84 additions and 0 deletions

View File

@ -17,4 +17,7 @@ extern struct smp_operations hix5hd2_smp_ops;
extern void hix5hd2_set_cpu(int cpu, bool enable);
extern void hix5hd2_cpu_die(unsigned int cpu);
extern struct smp_operations hip01_smp_ops;
extern void hip01_set_cpu(int cpu, bool enable);
extern void hip01_cpu_die(unsigned int cpu);
#endif

View File

@ -65,6 +65,9 @@
#define PMC0_CPU1_PMC_ENABLE (1 << 7)
#define PMC0_CPU1_POWERDOWN (1 << 3)
#define HIP01_PERI9 0x50
#define PERI9_CPU1_RESET (1 << 1)
enum {
HI3620_CTRL,
ERROR_CTRL,
@ -209,6 +212,34 @@ void hix5hd2_set_cpu(int cpu, bool enable)
}
}
void hip01_set_cpu(int cpu, bool enable)
{
unsigned int temp;
struct device_node *np;
if (!ctrl_base) {
np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
if (np)
ctrl_base = of_iomap(np, 0);
else
BUG();
}
if (enable) {
/* reset on CPU1 */
temp = readl_relaxed(ctrl_base + HIP01_PERI9);
temp |= PERI9_CPU1_RESET;
writel_relaxed(temp, ctrl_base + HIP01_PERI9);
udelay(50);
/* unreset on CPU1 */
temp = readl_relaxed(ctrl_base + HIP01_PERI9);
temp &= ~PERI9_CPU1_RESET;
writel_relaxed(temp, ctrl_base + HIP01_PERI9);
}
}
static inline void cpu_enter_lowpower(void)
{
unsigned int v;

View File

@ -10,10 +10,12 @@
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/delay.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include <asm/smp_scu.h>
#include <asm/mach/map.h>
#include "core.h"
@ -132,5 +134,53 @@ struct smp_operations hix5hd2_smp_ops __initdata = {
#endif
};
#define SC_SCTL_REMAP_CLR 0x00000100
#define HIP01_BOOT_ADDRESS 0x80000000
#define REG_SC_CTRL 0x000
void hip01_set_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr)
{
void __iomem *virt;
virt = phys_to_virt(start_addr);
writel_relaxed(0xe51ff004, virt);
writel_relaxed(jump_addr, virt + 4);
}
static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
phys_addr_t jumpaddr;
unsigned int remap_reg_value = 0;
struct device_node *node;
jumpaddr = virt_to_phys(hisi_secondary_startup);
hip01_set_boot_addr(HIP01_BOOT_ADDRESS, jumpaddr);
node = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
if (WARN_ON(!node))
return -1;
ctrl_base = of_iomap(node, 0);
/* set the secondary core boot from DDR */
remap_reg_value = readl_relaxed(ctrl_base + REG_SC_CTRL);
barrier();
remap_reg_value |= SC_SCTL_REMAP_CLR;
barrier();
writel_relaxed(remap_reg_value, ctrl_base + REG_SC_CTRL);
hip01_set_cpu(cpu, true);
return 0;
}
struct smp_operations hip01_smp_ops __initdata = {
.smp_prepare_cpus = hisi_common_smp_prepare_cpus,
.smp_boot_secondary = hip01_boot_secondary,
};
CPU_METHOD_OF_DECLARE(hi3xxx_smp, "hisilicon,hi3620-smp", &hi3xxx_smp_ops);
CPU_METHOD_OF_DECLARE(hix5hd2_smp, "hisilicon,hix5hd2-smp", &hix5hd2_smp_ops);
CPU_METHOD_OF_DECLARE(hip01_smp, "hisilicon,hip01-smp", &hip01_smp_ops);