
From: Wang Dongsheng dongsheng.wang@nxp.com
Add the PSCI v1.0 API to U-Boot: PSCI_VERSION, AFFINITY_INFO, MIGRATE_INFO_TYPE, MIGRATE_INFO_UP_CPU, SYSTEM_OFF, SYSTEM_RESET, PSCI_FEATURES, SYSTEM_SUSPEND.
In order to be compatible with PSCI v0.1 version, introduce CONFIG_ARMV7_PSCI_GTE_1_0 macro to add the PSCI v1.0 compatible to the dtb.
U-Boot currently uses the "arm,psci" compatible, which means PSCI v0.1. PSCI v1.0 imposes additional requirements, so the "arm,psci-1.0" property will only be added if the platform defines CONFIG_ARMV7_PSCI_GTE_1_0."
Signed-off-by: Wang Dongsheng dongsheng.wang@nxp.com --- arch/arm/cpu/armv7/psci.S | 36 +++++++++++++++++++++++++++++++++++ arch/arm/cpu/armv7/virt-dt.c | 45 +++++++++++++++++++++++++++++++++----------- arch/arm/include/asm/psci.h | 27 ++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 11 deletions(-)
diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index a83fa67..68304bf 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -53,8 +53,18 @@ ENTRY(psci_cpu_suspend) ENTRY(psci_cpu_off) ENTRY(psci_cpu_on) ENTRY(psci_migrate) +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 +ENTRY(psci_migrate_info_type) +ENTRY(psci_migrate_info_up_cpu) +ENTRY(psci_system_suspend) +#endif mov r0, #PSCI_RET_NOT_SUPPORTED @ Return -1 (Not Implemented) mov pc, lr +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 +ENDPROC(psci_system_suspend) +ENDPROC(psci_migrate_info_up_cpu) +ENDPROC(psci_migrate_info_type) +#endif ENDPROC(psci_migrate) ENDPROC(psci_cpu_on) ENDPROC(psci_cpu_off) @@ -63,8 +73,14 @@ ENDPROC(psci_cpu_suspend) .weak psci_cpu_off .weak psci_cpu_on .weak psci_migrate +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 +.weak psci_migrate_info_type +.weak psci_migrate_info_up_cpu +.weak psci_system_suspend +#endif
_psci_table: + /* PSCI v0.1 */ .word PSCI_FN_CPU_SUSPEND .word psci_cpu_suspend .word PSCI_FN_CPU_OFF @@ -73,6 +89,26 @@ _psci_table: .word psci_cpu_on_common .word PSCI_FN_MIGRATE .word psci_migrate +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 + /* PSCI v0.2 */ + .word PSCI_FN_PSCI_VERSION + .word psci_version + .word PSCI_FN_AFFINITY_INFO + .word psci_affinity_info + .word PSCI_FN_MIGRATE_INFO_TYPE + .word psci_migrate_info_type + .word PSCI_FN_MIGRATE_INFO_UP_CPU + .word psci_migrate_info_up_cpu + .word PSCI_FN_SYSTEM_OFF + .word psci_system_off + .word PSCI_FN_SYSTEM_RESET + .word psci_system_reset + /* PSCI v1.0 */ + .word PSCI_FN_PSCI_FEATURES + .word psci_features + .word PSCI_FN_SYSTEM_SUSPEND + .word psci_system_suspend +#endif .word 0 .word 0
diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c index 5ca353c..2865169 100644 --- a/arch/arm/cpu/armv7/virt-dt.c +++ b/arch/arm/cpu/armv7/virt-dt.c @@ -26,6 +26,35 @@ #include <asm/armv7.h> #include <asm/psci.h>
+#ifdef CONFIG_ARMV7_PSCI +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 +static int fdt_psci_gte_1_0_fixup(void *fdt, int nodeoff) +{ + return fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci-1.0"); +} +#endif + +static int fdt_psci_0_1_fixup(void *fdt, int nodeoff) +{ + int ret; + + ret = fdt_appendprop_string(fdt, nodeoff, "compatible", "arm,psci"); + if (ret) + return ret; + ret = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", PSCI_FN_CPU_SUSPEND); + if (ret) + return ret; + ret = fdt_setprop_u32(fdt, nodeoff, "cpu_off", PSCI_FN_CPU_OFF); + if (ret) + return ret; + ret = fdt_setprop_u32(fdt, nodeoff, "cpu_on", PSCI_FN_CPU_ON); + if (ret) + return ret; + + return fdt_setprop_u32(fdt, nodeoff, "migrate", PSCI_FN_MIGRATE); +} +#endif + static int fdt_psci(void *fdt) { #ifdef CONFIG_ARMV7_PSCI @@ -67,22 +96,16 @@ static int fdt_psci(void *fdt) return nodeoff; }
- tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci"); - if (tmp) - return tmp; tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc"); if (tmp) return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", PSCI_FN_CPU_SUSPEND); - if (tmp) - return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", PSCI_FN_CPU_OFF); - if (tmp) - return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", PSCI_FN_CPU_ON); + +#ifdef CONFIG_ARMV7_PSCI_GTE_1_0 + tmp = fdt_psci_gte_1_0_fixup(fdt, nodeoff); if (tmp) return tmp; - tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", PSCI_FN_MIGRATE); +#endif + tmp = fdt_psci_0_1_fixup(fdt, nodeoff); if (tmp) return tmp; #endif diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index 274dbda..71cd193 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -32,14 +32,41 @@ #define PSCI_FN_CPU_ON PSCI_FN_ID(3) #define PSCI_FN_MIGRATE PSCI_FN_ID(5)
+/* PSCI v0.2 interface */ +#define PSCI_FN_PSCI_VERSION PSCI_FN_ID(0) +#define PSCI_FN_AFFINITY_INFO PSCI_FN_ID(4) +#define PSCI_FN_MIGRATE_INFO_TYPE PSCI_FN_ID(6) +#define PSCI_FN_MIGRATE_INFO_UP_CPU PSCI_FN_ID(7) +#define PSCI_FN_SYSTEM_OFF PSCI_FN_ID(8) +#define PSCI_FN_SYSTEM_RESET PSCI_FN_ID(9) + +/* PSCI v1.0 interface */ +#define PSCI_FN_PSCI_FEATURES PSCI_FN_ID(10) +#define PSCI_FN_SYSTEM_SUSPEND PSCI_FN_ID(14) + + +/* PSCI features decoding (>=1.0) */ +#define PSCI_FEATURES_CPU_SUSPEND_PF_MASK 0x2 +#define PSCI_FEATURES_CPU_SUSPEND_OSIM_MASK 0x1 + /* * Original from Linux kernel: include/uapi/linux/psci.h */ +/* PSCI v0.2 affinity level state returned by AFFINITY_INFO */ +#define PSCI_AFFINITY_LEVEL_ON 0 +#define PSCI_AFFINITY_LEVEL_OFF 1 +#define PSCI_AFFINITY_LEVEL_ON_PENDING 2 + /* PSCI return values (inclusive of all PSCI versions) */ #define PSCI_RET_SUCCESS 0 #define PSCI_RET_NOT_SUPPORTED (-1) #define PSCI_RET_INVALID_PARAMS (-2) #define PSCI_RET_DENIED (-3) +#define PSCI_RET_ALREADY_ON (-4) +#define PSCI_RET_ON_PENDING (-5) +#define PSCI_RET_INTERNAL_FAILURE (-6) +#define PSCI_RET_NOT_PRESENT (-7) +#define PSCI_RET_DISABLED (-8)
#ifndef __ASSEMBLY__ int psci_update_dt(void *fdt);