From 7382d1782648e6e8e5be878e9b9a3cbfd1912001 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 10 Aug 2016 16:08:45 +0900 Subject: ARM: uniphier: move (and rename) CONFIG_UNIPHIER_L2CACHE_ON to Kconfig Move this option to Kconfig, renaming it into CONFIG_CACHE_UNIPHIER. The new option name makes sense enough, and the same as Linux has. Signed-off-by: Masahiro Yamada --- include/configs/uniphier.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index e485583f21d..2606e53eb91 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -27,9 +27,6 @@ #define CONFIG_SYS_CACHELINE_SIZE 32 -/* Comment out the following to disable L2 cache */ -#define CONFIG_UNIPHIER_L2CACHE_ON - #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO #define CONFIG_MISC_INIT_F -- cgit v1.3.1 From 8fca073271706f3d856c6554c2b5400ac9c83c10 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 10 Aug 2016 16:08:46 +0900 Subject: ARM: uniphier: fix CONFIG_SYS_CACHELINE_SIZE when outer cache is on The UniPhier outer cache (L2 cache on ARMv7 SoCs) has 128 byte line length and its tags are also managed per 128 byte line. Signed-off-by: Masahiro Yamada --- include/configs/uniphier.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 2606e53eb91..9ee125fb702 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -25,7 +25,11 @@ /* #define CONFIG_SYS_ICACHE_OFF */ /* #define CONFIG_SYS_DCACHE_OFF */ +#ifdef CONFIG_CACHE_UNIPHIER +#define CONFIG_SYS_CACHELINE_SIZE 128 +#else #define CONFIG_SYS_CACHELINE_SIZE 32 +#endif #define CONFIG_DISPLAY_CPUINFO #define CONFIG_DISPLAY_BOARDINFO -- cgit v1.3.1 From e8a9293295a1a54f6e43970bed2d3bfd124be02c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 10 Aug 2016 16:08:49 +0900 Subject: ARM: uniphier: add PSCI support for UniPhier ARMv7 SoCs Currently, only the CPU_ON function is supported. Signed-off-by: Masahiro Yamada --- arch/arm/mach-uniphier/Kconfig | 2 + arch/arm/mach-uniphier/arm32/Makefile | 1 + arch/arm/mach-uniphier/arm32/arm-mpcore.h | 3 + arch/arm/mach-uniphier/arm32/psci.c | 153 ++++++++++++++++++++++++++++++ arch/arm/mach-uniphier/arm32/psci_smp.S | 40 ++++++++ arch/arm/mach-uniphier/debug.h | 68 +++++++++++++ arch/arm/mach-uniphier/sbc/sbc-regs.h | 4 +- include/configs/uniphier.h | 7 +- 8 files changed, 275 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-uniphier/arm32/psci.c create mode 100644 arch/arm/mach-uniphier/arm32/psci_smp.S create mode 100644 arch/arm/mach-uniphier/debug.h (limited to 'include') diff --git a/arch/arm/mach-uniphier/Kconfig b/arch/arm/mach-uniphier/Kconfig index a5580730cf2..a8a0b90c39b 100644 --- a/arch/arm/mach-uniphier/Kconfig +++ b/arch/arm/mach-uniphier/Kconfig @@ -6,6 +6,8 @@ config SYS_CONFIG_NAME config ARCH_UNIPHIER_32BIT bool select CPU_V7 + select CPU_V7_HAS_NONSEC + select ARMV7_NONSEC config ARCH_UNIPHIER_64BIT bool diff --git a/arch/arm/mach-uniphier/arm32/Makefile b/arch/arm/mach-uniphier/arm32/Makefile index 5074ebda97a..6f05d727e02 100644 --- a/arch/arm/mach-uniphier/arm32/Makefile +++ b/arch/arm/mach-uniphier/arm32/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_DEBUG_LL) += debug_ll.o else obj-y += late_lowlevel_init.o obj-y += cache-uniphier.o +obj-$(CONFIG_ARMV7_PSCI) += psci.o psci_smp.o endif obj-y += timer.o diff --git a/arch/arm/mach-uniphier/arm32/arm-mpcore.h b/arch/arm/mach-uniphier/arm32/arm-mpcore.h index cf7cd46c10c..1a856641dec 100644 --- a/arch/arm/mach-uniphier/arm32/arm-mpcore.h +++ b/arch/arm/mach-uniphier/arm32/arm-mpcore.h @@ -12,6 +12,9 @@ /* SCU Control Register */ #define SCU_CTRL 0x00 +#define SCU_ENABLE (1 << 0) +#define SCU_STANDBY_ENABLE (1 << 5) + /* SCU Configuration Register */ #define SCU_CONF 0x04 /* SCU CPU Power Status Register */ diff --git a/arch/arm/mach-uniphier/arm32/psci.c b/arch/arm/mach-uniphier/arm32/psci.c new file mode 100644 index 00000000000..633a3e08402 --- /dev/null +++ b/arch/arm/mach-uniphier/arm32/psci.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../debug.h" +#include "../soc-info.h" +#include "arm-mpcore.h" +#include "cache-uniphier.h" + +#define UNIPHIER_SMPCTRL_ROM_RSV2 0x59801208 + +void uniphier_smp_trampoline(void); +void uniphier_smp_trampoline_end(void); +u32 uniphier_smp_booted[CONFIG_ARMV7_PSCI_NR_CPUS]; + +static int uniphier_get_nr_cpus(void) +{ + switch (uniphier_get_soc_type()) { + case SOC_UNIPHIER_SLD3: + case SOC_UNIPHIER_PRO4: + case SOC_UNIPHIER_PRO5: + return 2; + case SOC_UNIPHIER_PXS2: + case SOC_UNIPHIER_LD6B: + return 4; + default: + return 1; + } +} + +static void uniphier_smp_kick_all_cpus(void) +{ + const u32 target_ways = BIT(0); + size_t trmp_size; + u32 trmp_src = (unsigned long)uniphier_smp_trampoline; + u32 trmp_src_end = (unsigned long)uniphier_smp_trampoline_end; + u32 trmp_dest, trmp_dest_end; + int nr_cpus, i; + int timeout = 1000; + + nr_cpus = uniphier_get_nr_cpus(); + if (nr_cpus == 1) + return; + + for (i = 0; i < nr_cpus; i++) /* lock ways for all CPUs */ + uniphier_cache_set_active_ways(i, 0); + uniphier_cache_inv_way(target_ways); + uniphier_cache_enable(); + + /* copy trampoline code */ + uniphier_cache_prefetch_range(trmp_src, trmp_src_end, target_ways); + + trmp_size = trmp_src_end - trmp_src; + + trmp_dest = trmp_src & (SZ_64K - 1); + trmp_dest += SZ_1M - SZ_64K * 2; + + trmp_dest_end = trmp_dest + trmp_size; + + uniphier_cache_touch_range(trmp_dest, trmp_dest_end, target_ways); + + writel(trmp_dest, UNIPHIER_SMPCTRL_ROM_RSV2); + + asm("dsb ishst\n" /* Ensure the write to ROM_RSV2 is visible */ + "sev"); /* Bring up all secondary CPUs from Boot ROM into U-Boot */ + + while (--timeout) { + int all_booted = 1; + + for (i = 1; i < nr_cpus; i++) + if (!uniphier_smp_booted[i]) + all_booted = 0; + if (all_booted) + break; + udelay(1); + + /* barrier here because uniphier_smp_booted[] may be updated */ + cpu_relax(); + } + + if (!timeout) + printf("warning: some of secondary CPUs may not boot\n"); + + uniphier_cache_disable(); +} + +void psci_board_init(void) +{ + unsigned long scu_base; + u32 scu_ctrl, tmp; + + asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (scu_base)); + + scu_ctrl = readl(scu_base + 0x30); + if (!(scu_ctrl & 1)) + writel(scu_ctrl | 0x1, scu_base + 0x30); + + scu_ctrl = readl(scu_base + SCU_CTRL); + scu_ctrl |= SCU_ENABLE | SCU_STANDBY_ENABLE; + writel(scu_ctrl, scu_base + SCU_CTRL); + + tmp = readl(scu_base + SCU_SNSAC); + tmp |= 0xfff; + writel(tmp, scu_base + SCU_SNSAC); + + uniphier_smp_kick_all_cpus(); +} + +void psci_arch_init(void) +{ + u32 actlr; + + asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (actlr)); + actlr |= 0x41; /* set SMP and FW bits */ + asm("mcr p15, 0, %0, c1, c0, 1" : : "r" (actlr)); +} + +u32 uniphier_psci_holding_pen_release __secure_data = 0xffffffff; + +int __secure psci_cpu_on(u32 function_id, u32 cpuid, u32 entry_point) +{ + u32 cpu = cpuid & 0xff; + + debug_puts("[U-Boot PSCI] psci_cpu_on: cpuid="); + debug_puth(cpuid); + debug_puts(", entry_point="); + debug_puth(entry_point); + debug_puts("\n"); + + psci_save_target_pc(cpu, entry_point); + + /* We assume D-cache is off, so do not call flush_dcache() here */ + uniphier_psci_holding_pen_release = cpu; + + /* Send an event to wake up the secondary CPU. */ + asm("dsb ishst\n" + "sev"); + + return PSCI_RET_SUCCESS; +} diff --git a/arch/arm/mach-uniphier/arm32/psci_smp.S b/arch/arm/mach-uniphier/arm32/psci_smp.S new file mode 100644 index 00000000000..aa2fa5f3fc2 --- /dev/null +++ b/arch/arm/mach-uniphier/arm32/psci_smp.S @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include + + .section ._secure.text, "ax" + +ENTRY(uniphier_smp_trampoline) + ldr r0, 0f + mrc p15, 0, r1, c1, c0, 0 @ SCTLR (System Control Register) + orr r1, r1, #CR_I @ Enable ICache + bic r1, r1, #(CR_C | CR_M) @ Disable MMU and Dcache + mcr p15, 0, r1, c1, c0, 0 + + bx r0 +0: .word uniphier_secondary_startup + .globl uniphier_smp_trampoline_end +uniphier_smp_trampoline_end: +ENDPROC(uniphier_smp_trampoline) + +LENTRY(uniphier_secondary_startup) + mrc p15, 0, r1, c0, c0, 5 @ MPIDR (Multiprocessor Affinity Reg) + and r1, r1, #0xff + + ldr r2, =uniphier_smp_booted + mov r0, #1 + str r0, [r2, r1, lsl #2] + + ldr r2, =uniphier_psci_holding_pen_release +pen: ldr r0, [r2] + cmp r0, r1 + beq psci_cpu_entry + wfe + b pen +ENDPROC(uniphier_secondary_startup) diff --git a/arch/arm/mach-uniphier/debug.h b/arch/arm/mach-uniphier/debug.h new file mode 100644 index 00000000000..bc16f77b961 --- /dev/null +++ b/arch/arm/mach-uniphier/debug.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +#include +#include + +#define DEBUG_UART_BASE 0x54006800 +#define UART_SHIFT 2 + +#define UNIPHIER_UART_TX 0 +#define UNIPHIER_UART_LSR (5 * 4) + +/* All functions are inline so that they can be called from .secure section. */ + +#ifdef DEBUG +static inline void debug_putc(int c) +{ + void __iomem *base = (void __iomem *)DEBUG_UART_BASE; + + while (!(readl(base + UNIPHIER_UART_LSR) & UART_LSR_THRE)) + ; + + writel(c, base + UNIPHIER_UART_TX); +} + +static inline void debug_puts(const char *s) +{ + while (*s) { + if (*s == '\n') + debug_putc('\r'); + + debug_putc(*s++); + } +} + +static inline void debug_puth(unsigned long val) +{ + int i; + unsigned char c; + + for (i = 8; i--; ) { + c = ((val >> (i * 4)) & 0xf); + c += (c >= 10) ? 'a' - 10 : '0'; + debug_putc(c); + } +} +#else +static inline void debug_putc(int c) +{ +} + +static inline void debug_puts(const char *s) +{ +} + +static inline void debug_puth(unsigned long val) +{ +} +#endif + +#endif /* __DEBUG_H__ */ diff --git a/arch/arm/mach-uniphier/sbc/sbc-regs.h b/arch/arm/mach-uniphier/sbc/sbc-regs.h index a5dca74a55b..673fb75bcab 100644 --- a/arch/arm/mach-uniphier/sbc/sbc-regs.h +++ b/arch/arm/mach-uniphier/sbc/sbc-regs.h @@ -1,7 +1,8 @@ /* * UniPhier SBC (System Bus Controller) registers * - * Copyright (C) 2011-2015 Masahiro Yamada + * Copyright (C) 2011-2014 Panasonic Corporation + * Copyright (C) 2015-2016 Socionext Inc. * * SPDX-License-Identifier: GPL-2.0+ */ @@ -75,7 +76,6 @@ #define SBCTRL74 (SBCTRL_BASE + 0x170) #define PC0CTRL 0x598000c0 -#define ROM_BOOT_ROMRSV2 0x59801208 #ifndef __ASSEMBLY__ #include diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 9ee125fb702..950c5353d25 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -1,5 +1,7 @@ /* - * Copyright (C) 2012-2015 Masahiro Yamada + * Copyright (C) 2012-2015 Panasonic Corporation + * Copyright (C) 2015-2016 Socionext Inc. + * Author: Masahiro Yamada * * SPDX-License-Identifier: GPL-2.0+ */ @@ -9,6 +11,9 @@ #ifndef __CONFIG_UNIPHIER_COMMON_H__ #define __CONFIG_UNIPHIER_COMMON_H__ +#define CONFIG_ARMV7_PSCI +#define CONFIG_ARMV7_PSCI_NR_CPUS 4 + #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 10 #define CONFIG_SMC911X -- cgit v1.3.1