
Add minimal PSCI support for Linux.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
arch/arm/mach-stm32mp/Kconfig | 3 + arch/arm/mach-stm32mp/Makefile | 1 + arch/arm/mach-stm32mp/include/mach/stm32.h | 2 + arch/arm/mach-stm32mp/psci.c | 91 ++++++++++++++++++++++++++++++ include/configs/stm32mp1.h | 5 ++ 5 files changed, 102 insertions(+) create mode 100644 arch/arm/mach-stm32mp/psci.c
diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig index 9771af9..c1ad939 100644 --- a/arch/arm/mach-stm32mp/Kconfig +++ b/arch/arm/mach-stm32mp/Kconfig @@ -23,7 +23,10 @@ config SYS_SOC
config TARGET_STM32MP1 bool "Support stm32mp1xx" + select ARCH_SUPPORT_PSCI select CPU_V7 + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT select PINCTRL_STM32 select STM32_RESET help diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile index a495c53..f746691 100644 --- a/arch/arm/mach-stm32mp/Makefile +++ b/arch/arm/mach-stm32mp/Makefile @@ -9,3 +9,4 @@ obj-y += dram_init.o obj-y += syscon.o
obj-$(CONFIG_SPL_BUILD) += spl.o +obj-$(CONFIG_ARMV7_PSCI) += psci.o diff --git a/arch/arm/mach-stm32mp/include/mach/stm32.h b/arch/arm/mach-stm32mp/include/mach/stm32.h index c7a2789..d6f960f 100644 --- a/arch/arm/mach-stm32mp/include/mach/stm32.h +++ b/arch/arm/mach-stm32mp/include/mach/stm32.h @@ -74,6 +74,8 @@ enum boot_device {
/* TAMP registers */ #define TAMP_BACKUP_REGISTER(x) (STM32_TAMP_BASE + 0x100 + 4 * x) +#define TAMP_BACKUP_MAGIC_NUMBER TAMP_BACKUP_REGISTER(4) +#define TAMP_BACKUP_BRANCH_ADDRESS TAMP_BACKUP_REGISTER(5) #define TAMP_BOOT_CONTEXT TAMP_BACKUP_REGISTER(20)
#define TAMP_BOOT_MODE_MASK GENMASK(15, 8) diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c new file mode 100644 index 0000000..0912242 --- /dev/null +++ b/arch/arm/mach-stm32mp/psci.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2018, STMicroelectronics - All Rights Reserved + * + * SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause + */ + +#include <config.h> +#include <common.h> +#include <asm/armv7.h> +#include <asm/gic.h> +#include <asm/io.h> +#include <asm/psci.h> +#include <asm/secure.h> + +#define BOOT_API_A7_CORE1_MAGIC_NUMBER 0xCA7FACE1 + +#define RCC_MP_GRSTCSETR (STM32_RCC_BASE + 0x0404) +#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5) +#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0) + +static u32 __secure stm32mp_get_gicd_base_address(void) +{ + u32 periphbase; + + /* get the GIC base address from the CBAR register */ + asm("mrc p15, 4, %0, c15, c0, 0\n" : "=r" (periphbase)); + + return (periphbase & CBAR_MASK) + GIC_DIST_OFFSET; +} + +static void __secure stm32mp_smp_kick_all_cpus(void) +{ + u32 gic_dist_addr; + + gic_dist_addr = stm32mp_get_gicd_base_address(); + + /* kick all CPUs (except this one) by writing to GICD_SGIR */ + writel(1U << 24, gic_dist_addr + GICD_SGIR); +} + +int __secure psci_features(unsigned int psci_fid) +{ + switch (psci_fid) { + case ARM_PSCI_0_2_FN_PSCI_VERSION: + case ARM_PSCI_0_2_FN_CPU_ON: + case ARM_PSCI_0_2_FN_CPU_OFF: + case ARM_PSCI_0_2_FN_SYSTEM_RESET: + return 0x0; + } + return ARM_PSCI_RET_NI; +} + +unsigned int __secure psci_version(void) +{ + return ARM_PSCI_VER_1_0; +} + +int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc) +{ + u32 cpu = (mpidr & 0x3); + + /* store target PC */ + psci_save_target_pc(cpu, pc); + + /* write entrypoint in backup RAM register */ + writel((u32)&psci_cpu_entry, TAMP_BACKUP_BRANCH_ADDRESS); + + /* write magic number in backup register */ + writel(BOOT_API_A7_CORE1_MAGIC_NUMBER, TAMP_BACKUP_MAGIC_NUMBER); + stm32mp_smp_kick_all_cpus(); + + return ARM_PSCI_RET_SUCCESS; +} + +void __secure psci_cpu_off(void) +{ + /* reset core #1 : wfi is managed by BootRom */ + writel(RCC_MP_GRSTCSETR_MPUP1RST, RCC_MP_GRSTCSETR); + /* just waiting reset */ + while (1) + wfi(); +} + +void __secure psci_system_reset(u32 function_id) +{ + /* System reset */ + writel(RCC_MP_GRSTCSETR_MPSYSRST, RCC_MP_GRSTCSETR); + /* just waiting reset */ + while (1) + wfi(); +} diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h index da0e259..e0e7747 100644 --- a/include/configs/stm32mp1.h +++ b/include/configs/stm32mp1.h @@ -19,6 +19,11 @@ #define CONFIG_SYS_HZ 1000 #define CONFIG_SYS_ARCH_TIMER
+/* PSCI support */ +#define CONFIG_ARMV7_PSCI_1_0 +#define CONFIG_ARMV7_SECURE_BASE STM32_SYSRAM_BASE +#define CONFIG_ARMV7_SECURE_MAX_SIZE STM32_SYSRAM_SIZE + /* * malloc() pool size */