diff options
author | Masahiro Yamada <yamada.masahiro@socionext.com> | 2016-04-21 14:43:18 +0900 |
---|---|---|
committer | Masahiro Yamada <yamada.masahiro@socionext.com> | 2016-04-24 09:54:08 +0900 |
commit | 9d0c2ceb35be7016977560a92fc67e3e704e5c9f (patch) | |
tree | 67f17e8bbc13a293b7d24f7789a3fb0692c1e284 /arch/arm/mach-uniphier/arm64 | |
parent | 881aa5a79a94a65500959428328f348a18d3d9fe (diff) |
ARM: uniphier: add PH1-LD20 SoC support
This is the first ARMv8 SoC from Socionext Inc.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to 'arch/arm/mach-uniphier/arm64')
-rw-r--r-- | arch/arm/mach-uniphier/arm64/Makefile | 10 | ||||
-rw-r--r-- | arch/arm/mach-uniphier/arm64/arm-cci500.c | 41 | ||||
-rw-r--r-- | arch/arm/mach-uniphier/arm64/mem_map.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-uniphier/arm64/smp.S | 19 | ||||
-rw-r--r-- | arch/arm/mach-uniphier/arm64/smp_kick_cpus.c | 31 | ||||
-rw-r--r-- | arch/arm/mach-uniphier/arm64/timer.c | 38 |
6 files changed, 167 insertions, 0 deletions
diff --git a/arch/arm/mach-uniphier/arm64/Makefile b/arch/arm/mach-uniphier/arm64/Makefile new file mode 100644 index 0000000000..5ed030ae40 --- /dev/null +++ b/arch/arm/mach-uniphier/arm64/Makefile @@ -0,0 +1,10 @@ +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifdef CONFIG_SPL_BUILD +obj-y += timer.o +else +obj-y += mem_map.o smp.o smp_kick_cpus.o +obj-$(CONFIG_ARCH_UNIPHIER_LD20) += arm-cci500.o +endif diff --git a/arch/arm/mach-uniphier/arm64/arm-cci500.c b/arch/arm/mach-uniphier/arm64/arm-cci500.c new file mode 100644 index 0000000000..607f96a58d --- /dev/null +++ b/arch/arm/mach-uniphier/arm64/arm-cci500.c @@ -0,0 +1,41 @@ +/* + * Initialization of ARM Corelink CCI-500 Cache Coherency Interconnect + * + * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <mapmem.h> +#include <linux/bitops.h> +#include <linux/io.h> +#include <linux/sizes.h> + +#define CCI500_BASE 0x5FD00000 +#define CCI500_SLAVE_OFFSET 0x1000 + +#define CCI500_SNOOP_CTRL +#define CCI500_SNOOP_CTRL_EN_DVM BIT(1) +#define CCI500_SNOOP_CTRL_EN_SNOOP BIT(0) + +void cci500_init(unsigned int nr_slaves) +{ + unsigned long slave_base = CCI500_BASE + CCI500_SLAVE_OFFSET; + int i; + + for (i = 0; i < nr_slaves; i++) { + void __iomem *base; + u32 tmp; + + base = map_sysmem(slave_base, SZ_4K); + + tmp = readl(base); + tmp |= CCI500_SNOOP_CTRL_EN_DVM | CCI500_SNOOP_CTRL_EN_SNOOP; + writel(tmp, base); + + unmap_sysmem(base); + + slave_base += CCI500_SLAVE_OFFSET; + } +} diff --git a/arch/arm/mach-uniphier/arm64/mem_map.c b/arch/arm/mach-uniphier/arm64/mem_map.c new file mode 100644 index 0000000000..74ef91984c --- /dev/null +++ b/arch/arm/mach-uniphier/arm64/mem_map.c @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/types.h> +#include <asm/armv8/mmu.h> + +static struct mm_region uniphier_mem_map[] = { + { + .base = 0x00000000, + .size = 0x80000000, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, + { + .base = 0x80000000, + .size = 0xc0000000, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, + { /* sentinel */ } +}; + +struct mm_region *mem_map = uniphier_mem_map; diff --git a/arch/arm/mach-uniphier/arm64/smp.S b/arch/arm/mach-uniphier/arm64/smp.S new file mode 100644 index 0000000000..9348ec97c4 --- /dev/null +++ b/arch/arm/mach-uniphier/arm64/smp.S @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <linux/linkage.h> + +ENTRY(uniphier_smp_setup) + mrs x0, s3_1_c15_c2_1 /* CPUECTLR_EL1 */ + orr x0, x0, #(1 << 6) /* SMPEN */ + msr s3_1_c15_c2_1, x0 + ret +ENDPROC(uniphier_smp_setup) + +ENTRY(uniphier_secondary_startup) + bl uniphier_smp_setup + b _start +ENDPROC(uniphier_secondary_startup) diff --git a/arch/arm/mach-uniphier/arm64/smp_kick_cpus.c b/arch/arm/mach-uniphier/arm64/smp_kick_cpus.c new file mode 100644 index 0000000000..64412e0ecc --- /dev/null +++ b/arch/arm/mach-uniphier/arm64/smp_kick_cpus.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <mapmem.h> +#include <linux/io.h> +#include <linux/sizes.h> + +#define UNIPHIER_SMPCTRL_ROM_RSV0 0x59801200 + +void uniphier_smp_setup(void); +void uniphier_secondary_startup(void); + +void uniphier_smp_kick_all_cpus(void) +{ + void __iomem *rom_boot_rsv0; + + rom_boot_rsv0 = map_sysmem(UNIPHIER_SMPCTRL_ROM_RSV0, SZ_8); + + writeq((u64)uniphier_secondary_startup, rom_boot_rsv0); + readq(rom_boot_rsv0); /* relax */ + + unmap_sysmem(rom_boot_rsv0); + + uniphier_smp_setup(); + + asm("sev"); /* Bring up all secondary CPUs from Boot ROM into U-Boot */ +} diff --git a/arch/arm/mach-uniphier/arm64/timer.c b/arch/arm/mach-uniphier/arm64/timer.c new file mode 100644 index 0000000000..4beab9dca8 --- /dev/null +++ b/arch/arm/mach-uniphier/arm64/timer.c @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <mapmem.h> +#include <linux/bitops.h> +#include <linux/io.h> +#include <linux/sizes.h> + +#define CNT_CONTROL_BASE 0x60E00000 + +#define CNTCR 0x000 +#define CNTCR_EN BIT(0) + +/* setup ARMv8 Generic Timer */ +int timer_init(void) +{ + void __iomem *base; + u32 tmp; + + base = map_sysmem(CNT_CONTROL_BASE, SZ_4K); + + /* + * Note: + * In a system that implements both Secure and Non-secure states, + * this register is only writable in Secure state. + */ + tmp = readl(base + CNTCR); + tmp |= CNTCR_EN; + writel(tmp, base + CNTCR); + + unmap_sysmem(base); + + return 0; +} |