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:
Родитель
29d189e139
Коммит
7fda91e731
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче