sunxi: Add basic PSCI support to enable SMP on the A80's first cluster
Subsystems (3)
cover sunxi: Add basic PSCI support to enable SMP on the A80's first cluster
Hi everyone,
This series adds basic PSCI support for the A80 to enable SMP on the first cluster. This at least allows people to use more than one core. The term "basic" is used because the series does not add support for multi-cluster cache and power management.
The PSCI code is based on existing code for all the single cluster SoCs, and the kernel patches for MCPM SMP I did some time ago.
Unfortunately only SMP works at this time. The last patch does not actually work. While the system is indeed booted non-secure, tested by trying to write to secure SRAM and the results not sticking, reads from the GIC CPU interface shows that it's still returning the secure copy of registers, and since we use a secure monitor FIQ to do core power down, the FIQ gets passed to the kernel. The patch is included so people with in-depth ARM knowledge could probably help work out what is wrong.
Regards
ChenYu
Chen-Yu Tsai (10):
ARM: PSCI: Set ARMV7_PSCI_NR_CPUS default to 8 for sun9i/A80
sunxi: Add CCI-400 and CPUCFG registers base address for sun9i/A80
sunxi: Add base address of secure SRAM B for sun9i/A80
sunxi: Use secure SRAM B for secure RAM for sun9i/A80
sunxi: Add PRCM register definition for sun9i/A80
sunxi: Add CPUCFG register definitions for sun9i/A80
sunxi: Add support for TZPC on sun9i/A80
sunxi: Add basic PSCI implementation for A80
sunxi: Enable PSCI on sun9i/A80
sunxi: Add PSCI core power off support for A80's first cluster
arch/arm/cpu/armv7/Kconfig | 1 + arch/arm/cpu/armv7/sunxi/Makefile | 5 + arch/arm/cpu/armv7/sunxi/psci-mcpm.c | 322 +++++++++++++++++++++++++ arch/arm/cpu/armv7/sunxi/tzpc.c | 6 + arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 5 + arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h | 51 ++++ arch/arm/include/asm/arch-sunxi/prcm_sun9i.h | 55 +++++ arch/arm/include/asm/arch-sunxi/tzpc.h | 4 + arch/arm/mach-sunxi/board.c | 3 +- board/sunxi/Kconfig | 4 + include/configs/sun9i.h | 4 + 11 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/sunxi/psci-mcpm.c create mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h create mode 100644 arch/arm/include/asm/arch-sunxi/prcm_sun9i.h
Signature · 1 line
2.10.2
PATCH 1/10 ARM: PSCI: Set ARMV7_PSCI_NR_CPUS default to 8 for sun9i/A80
The A80 is a big.LITTLE SoC with 4x Cortex-A7 in cluster 0 and 4x Cortex-A15 in cluster 1.
--- arch/arm/cpu/armv7/Kconfig | 1 + 1 file changed, 1 insertion(+)
arch/arm/cpu/armv7/Kconfig +1 -0
@@ -44,6 +44,7 @@ config ARMV7_PSCI config ARMV7_PSCI_NR_CPUS int "Maximum supported CPUs for PSCI" depends on ARMV7_NONSEC + default 8 if MACH_SUN9I default 4 help The maximum number of CPUs supported in the PSCI firmware.
Signature · 1 line
2.10.2
PATCH 1/10 ARM: PSCI: Set ARMV7_PSCI_NR_CPUS default to 8 for sun9i/A80
Hi,
Quoted 4 lines · Chen-Yu Tsai
The A80 is a big.LITTLE SoC with 4x Cortex-A7 in cluster 0 and 4x Cortex-A15 in cluster 1.
Signed-off-by Chen-Yu Tsai <[email protected]>
LGTM:
Regards,
Hans
Quoted 17 lines
--- arch/arm/cpu/armv7/Kconfig | 1 + 1 file changed, 1 insertion(+)arch/arm/cpu/armv7/Kconfig +1
-0@@ -44,6 +44,7 @@ config ARMV7_PSCI config ARMV7_PSCI_NR_CPUS int "Maximum supported CPUs for PSCI" depends on ARMV7_NONSEC + default 8 if MACH_SUN9I default 4 help The maximum number of CPUs supported in the PSCI firmware.
PATCH 2/10 sunxi: Add CCI-400 and CPUCFG registers base address for sun9i/A80
In reply to Chen-Yu TsaiThe A80, having 2 clusters of 4 cores each, has an ARM CCI-400 hardware block for cache coherency.
Add the base address for CCI-400, and also add the base address for CPUCFG.
--- arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 3 +++ 1 file changed, 3 insertions(+)
arch/arm/include/asm/arch-sunxi/cpu_sun9i.h +3 -0
@@ -17,6 +17,9 @@#define REGS_APB1_BASE 0x07000000#define REGS_RCPUS_BASE 0x08000000 +#define SUNXI_CPUCFG_BASE 0x01700000 +#define SUNXI_CCI400_BASE 0x01790000 +#define SUNXI_SRAM_D_BASE 0x08100000/* AHB0 Module */
Signature · 1 line
2.10.2
PATCH 2/10 sunxi: Add CCI-400 and CPUCFG registers base address for sun9i/A80
Hi,
Quoted 6 lines · Chen-Yu Tsai
The A80, having 2 clusters of 4 cores each, has an ARM CCI-400 hardware block for cache coherency.
Add the base address for CCI-400, and also add the base address for CPUCFG.
Signed-off-by Chen-Yu Tsai <[email protected]>
LGTM:
Regards,
Hans
Quoted 19 lines
--- arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 3 +++ 1 file changed, 3 insertions(+)arch/arm/include/asm/arch-sunxi/cpu_sun9i.h +3
-0@@ -17,6 +17,9 @@#define REGS_APB1_BASE 0x07000000#define REGS_RCPUS_BASE 0x08000000 +#define SUNXI_CPUCFG_BASE 0x01700000 +#define SUNXI_CCI400_BASE 0x01790000 +#define SUNXI_SRAM_D_BASE 0x08100000/* AHB0 Module */
PATCH 3/10 sunxi: Add base address of secure SRAM B for sun9i/A80
In reply to Chen-Yu TsaiThe A80 has a 256 kiB secure SRAM. However the first 4 kiB are reserved for CPU0 hotplug flags.
--- arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 1 + 1 file changed, 1 insertion(+)
arch/arm/include/asm/arch-sunxi/cpu_sun9i.h +1 -0
@@ -20,6 +20,7 @@#define SUNXI_CPUCFG_BASE 0x01700000#define SUNXI_CCI400_BASE 0x01790000 +#define SUNXI_SRAM_B_BASE 0x00020000#define SUNXI_SRAM_D_BASE 0x08100000/* AHB0 Module */
Signature · 1 line
2.10.2
PATCH 3/10 sunxi: Add base address of secure SRAM B for sun9i/A80
Hi,
Quoted 4 lines · Chen-Yu Tsai
The A80 has a 256 kiB secure SRAM. However the first 4 kiB are reserved for CPU0 hotplug flags.
Signed-off-by Chen-Yu Tsai <[email protected]>
LGTM:
Regards,
Hans
Quoted 17 lines
--- arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 1 + 1 file changed, 1 insertion(+)arch/arm/include/asm/arch-sunxi/cpu_sun9i.h +1
-0@@ -20,6 +20,7 @@#define SUNXI_CPUCFG_BASE 0x01700000#define SUNXI_CCI400_BASE 0x01790000 +#define SUNXI_SRAM_B_BASE 0x00020000#define SUNXI_SRAM_D_BASE 0x08100000/* AHB0 Module */
PATCH 4/10 sunxi: Use secure SRAM B for secure RAM for sun9i/A80
In reply to Chen-Yu TsaiThe A80 has a 256 kiB secure SRAM. However the first 4 kiB are reserved for CPU0 hotplug flags.
--- include/configs/sun9i.h | 4 ++++ 1 file changed, 4 insertions(+)
include/configs/sun9i.h +4 -0
@@ -13,6 +13,10 @@* A80 specific configuration */ +/* First 4 kiB is reserved for CPU0 hotplug flags */ +#define CONFIG_ARMV7_SECURE_BASE (SUNXI_SRAM_B_BASE + 4 * 1024) +#define CONFIG_ARMV7_SECURE_MAX_SIZE (252 * 1024)/* 252 KB */ +/* * Include common sunxi configuration where most the settings are */
Signature · 1 line
2.10.2
PATCH 4/10 sunxi: Use secure SRAM B for secure RAM for sun9i/A80
Hi,
Quoted 4 lines · Chen-Yu Tsai
The A80 has a 256 kiB secure SRAM. However the first 4 kiB are reserved for CPU0 hotplug flags.
Signed-off-by Chen-Yu Tsai <[email protected]>
LGTM:
Regards,
Hans
Quoted 20 lines
--- include/configs/sun9i.h | 4 ++++ 1 file changed, 4 insertions(+)include/configs/sun9i.h +4
-0@@ -13,6 +13,10 @@* A80 specific configuration */ +/* First 4 kiB is reserved for CPU0 hotplug flags */ +#define CONFIG_ARMV7_SECURE_BASE (SUNXI_SRAM_B_BASE + 4 * 1024) +#define CONFIG_ARMV7_SECURE_MAX_SIZE (252 * 1024)/* 252 KB */ +/* * Include common sunxi configuration where most the settings are */
PATCH 5/10 sunxi: Add PRCM register definition for sun9i/A80
In reply to Chen-Yu TsaiThe A80 has a different PRCM register layout.
--- arch/arm/include/asm/arch-sunxi/prcm_sun9i.h | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 arch/arm/include/asm/arch-sunxi/prcm_sun9i.h
arch/arm/include/asm/arch-sunxi/prcm_sun9i.h new file +55 -0
@@ -0,0 +1,55 @@ +/* +* Sunxi A80 Power Reset and Clock Module register definition +* +* (C) Copyright 2016 Chen-Yu Tsai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _SUNXI_PRCM_SUN9I_H +#define _SUNXI_PRCM_SUN9I_H + +struct __packed sunxi_prcm_reg { +u32 cpus_rst;/* 0x000 */ +u32 cpu_rst[2 ];/* 0x004 */ +u8 res0[0x4 ];/* 0x00c */ +u32 cpus_cfg;/* 0x010 */ +u8 res1[0x8 ];/* 0x014 */ +u32 apbs_ratio;/* 0x01c */ +u8 res2[0x8 ];/* 0x020 */ +u32 apbs_gate;/* 0x028 */ +u8 res3[0x18 ];/* 0x02c */ +u32 pll_ctrl1;/* 0x044 */ +u8 res4[0xc ];/* 0x048 */ +u32 clk_cir;/* 0x054 */ +u32 clk_i2s0;/* 0x058 */ +u32 clk_i2s1;/* 0x05c */ +u8 res5[0x50 ];/* 0x060 */ +u32 apb0_reset;/* 0x0b0 */ +u8 res6[0x4c ];/* 0x0b4 */ +u32 cpu_pwroff[2 ];/* 0x100 */ +u8 res7[0x8 ];/* 0x108 */ +u32 vdd_sys_pwroff;/* 0x110 */ +u8 res8[0x4 ];/* 0x114 */ +u32 gpu_pwroff;/* 0x118 */ +u8 res9[0x4 ];/* 0x11c */ +u32 vdd_sys_rst;/* 0x120 */ +u8 res10[0x1c ];/* 0x124 */ +u32 cpu_pwr_clamp[2 ][4 ];/* 0x140 */ +u32 super_standby_flag;/* 0x160 */ +u32 cpu_soft_entry;/* 0x164 */ +u32 super_standby_entry;/* 0x168 */ +u8 res11[0x34 ];/* 0x16c */ +u32 nmi_irq_ctrl;/* 0x1a0 */ +u32 nmi_irq_en;/* 0x1a4 */ +u32 nmi_irq_status;/* 0x1a8 */ +u8 res12[0x14 ];/* 0x1ac */ +u32 pll_audio_ctrl;/* 0x1c0 */ +u32 pll_audio_bias;/* 0x1c4 */ +u32 pll_audio_pat_cfg;/* 0x1c8 */ +u32 pll_audio_ctrl_sw;/* 0x1cc */ +u8 res13[0x20 ];/* 0x1d0 */ +u32 osc24m_ctrl;/* 0x1f0 */ +}; + +#endif /* _SUNXI_PRCM_SUN9I_H */
Signature · 1 line
2.10.2
PATCH 5/10 sunxi: Add PRCM register definition for sun9i/A80
Hi,
Quoted 3 lines · Chen-Yu Tsai
The A80 has a different PRCM register layout.
Signed-off-by Chen-Yu Tsai <[email protected]>
LGTM:
Regards,
Hans
Quoted 67 lines
--- arch/arm/include/asm/arch-sunxi/prcm_sun9i.h | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 arch/arm/include/asm/arch-sunxi/prcm_sun9i.harch/arm/include/asm/arch-sunxi/prcm_sun9i.h new file +55
-0@@ -0,0 +1,55 @@ +/* +* Sunxi A80 Power Reset and Clock Module register definition +* +* (C) Copyright 2016 Chen-Yu Tsai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _SUNXI_PRCM_SUN9I_H +#define _SUNXI_PRCM_SUN9I_H + +struct __packed sunxi_prcm_reg { +u32 cpus_rst;/* 0x000 */ +u32 cpu_rst[2 ];/* 0x004 */ +u8 res0[0x4 ];/* 0x00c */ +u32 cpus_cfg;/* 0x010 */ +u8 res1[0x8 ];/* 0x014 */ +u32 apbs_ratio;/* 0x01c */ +u8 res2[0x8 ];/* 0x020 */ +u32 apbs_gate;/* 0x028 */ +u8 res3[0x18 ];/* 0x02c */ +u32 pll_ctrl1;/* 0x044 */ +u8 res4[0xc ];/* 0x048 */ +u32 clk_cir;/* 0x054 */ +u32 clk_i2s0;/* 0x058 */ +u32 clk_i2s1;/* 0x05c */ +u8 res5[0x50 ];/* 0x060 */ +u32 apb0_reset;/* 0x0b0 */ +u8 res6[0x4c ];/* 0x0b4 */ +u32 cpu_pwroff[2 ];/* 0x100 */ +u8 res7[0x8 ];/* 0x108 */ +u32 vdd_sys_pwroff;/* 0x110 */ +u8 res8[0x4 ];/* 0x114 */ +u32 gpu_pwroff;/* 0x118 */ +u8 res9[0x4 ];/* 0x11c */ +u32 vdd_sys_rst;/* 0x120 */ +u8 res10[0x1c ];/* 0x124 */ +u32 cpu_pwr_clamp[2 ][4 ];/* 0x140 */ +u32 super_standby_flag;/* 0x160 */ +u32 cpu_soft_entry;/* 0x164 */ +u32 super_standby_entry;/* 0x168 */ +u8 res11[0x34 ];/* 0x16c */ +u32 nmi_irq_ctrl;/* 0x1a0 */ +u32 nmi_irq_en;/* 0x1a4 */ +u32 nmi_irq_status;/* 0x1a8 */ +u8 res12[0x14 ];/* 0x1ac */ +u32 pll_audio_ctrl;/* 0x1c0 */ +u32 pll_audio_bias;/* 0x1c4 */ +u32 pll_audio_pat_cfg;/* 0x1c8 */ +u32 pll_audio_ctrl_sw;/* 0x1cc */ +u8 res13[0x20 ];/* 0x1d0 */ +u32 osc24m_ctrl;/* 0x1f0 */ +}; + +#endif /* _SUNXI_PRCM_SUN9I_H */
PATCH 6/10 sunxi: Add CPUCFG register definitions for sun9i/A80
In reply to Chen-Yu TsaiThe A80 has a different CPUCFG register layout, likely due to having 2 clusters.
--- arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h
arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h new file +51 -0
@@ -0,0 +1,51 @@ +/* +* Sunxi A80 CPUCFG register definition. +* +* (C) Copyright 2016 Chen-Yu Tsai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _SUNXI_CPUCFG_SUN9I_H +#define _SUNXI_CPUCFG_SUN9I_H + +#include <linux/compiler.h> +#include <linux/types.h> + +#define CPUCFG_CX_CTRL0_L1_RST_DISABLE (core) BIT(core) + +#define CPUCFG_CX_STATUS_STANDBYWFI (core) BIT(16 + core) + +#define CPUCFG_CX_RST_CORE (core) BIT(core) +#define CPUCFG_CX_RST_NEON (core) BIT(4 + core)/* A15 only */ +#define CPUCFG_CX_RST_L2 BIT(8) +#define CPUCFG_CX_RST_HRESET BIT(12) +#define CPUCFG_CX_RST_DBG (core) BIT(16 + core) +#define CPUCFG_CX_RST_ETM (core) BIT(20 + core) +#define CPUCFG_CX_RST_SOC_DBG BIT(24) + +#ifndef __ASSEMBLY__ + +struct __packed sunxi_cpucfg_cluster { +u32 ctrl0;/* base + 0x0 */ +u32 ctrl1;/* base + 0x4 */ +u32 adb400_pwrdnreqn;/* base + 0x8 */ +u8 res[0x4 ];/* base + 0xc */ +}; + +struct __packed sunxi_cpucfg_reg { +struct sunxi_cpucfg_cluster cluster[2 ];/* 0x00 */ +u8 res0[0x8 ];/* 0x20 */ +u32 gen_ctrl0;/* 0x28 */ +u32 gen_ctrl1;/* 0x2c */ +u32 cluster_status[2 ];/* 0x30 */ +u8 res1[0x4 ];/* 0x38 */ +u32 irq_fiq_status;/* 0x3c */ +u32 irq_fiq_mask;/* 0x40 */ +u8 res2[0x3c ];/* 0x44 */ +u32 cluster_reset[2 ];/* 0x80 */ +u32 gic_jtag_reset;/* 0x88 */ +}; + +#endif /* __ASSEMBLY__ */ +#endif /* _SUNXI_CPUCFG_SUN9I_H */
Signature · 1 line
2.10.2
PATCH 6/10 sunxi: Add CPUCFG register definitions for sun9i/A80
Hi,
Quoted 4 lines · Chen-Yu Tsai
The A80 has a different CPUCFG register layout, likely due to having 2 clusters.
Signed-off-by Chen-Yu Tsai <[email protected]>
LGTM:
Regards,
Hans
Quoted 63 lines
--- arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.harch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h new file +51
-0@@ -0,0 +1,51 @@ +/* +* Sunxi A80 CPUCFG register definition. +* +* (C) Copyright 2016 Chen-Yu Tsai <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#ifndef _SUNXI_CPUCFG_SUN9I_H +#define _SUNXI_CPUCFG_SUN9I_H + +#include <linux/compiler.h> +#include <linux/types.h> + +#define CPUCFG_CX_CTRL0_L1_RST_DISABLE (core) BIT(core) + +#define CPUCFG_CX_STATUS_STANDBYWFI (core) BIT(16 + core) + +#define CPUCFG_CX_RST_CORE (core) BIT(core) +#define CPUCFG_CX_RST_NEON (core) BIT(4 + core)/* A15 only */ +#define CPUCFG_CX_RST_L2 BIT(8) +#define CPUCFG_CX_RST_HRESET BIT(12) +#define CPUCFG_CX_RST_DBG (core) BIT(16 + core) +#define CPUCFG_CX_RST_ETM (core) BIT(20 + core) +#define CPUCFG_CX_RST_SOC_DBG BIT(24) + +#ifndef __ASSEMBLY__ + +struct __packed sunxi_cpucfg_cluster { +u32 ctrl0;/* base + 0x0 */ +u32 ctrl1;/* base + 0x4 */ +u32 adb400_pwrdnreqn;/* base + 0x8 */ +u8 res[0x4 ];/* base + 0xc */ +}; + +struct __packed sunxi_cpucfg_reg { +struct sunxi_cpucfg_cluster cluster[2 ];/* 0x00 */ +u8 res0[0x8 ];/* 0x20 */ +u32 gen_ctrl0;/* 0x28 */ +u32 gen_ctrl1;/* 0x2c */ +u32 cluster_status[2 ];/* 0x30 */ +u8 res1[0x4 ];/* 0x38 */ +u32 irq_fiq_status;/* 0x3c */ +u32 irq_fiq_mask;/* 0x40 */ +u8 res2[0x3c ];/* 0x44 */ +u32 cluster_reset[2 ];/* 0x80 */ +u32 gic_jtag_reset;/* 0x88 */ +}; + +#endif /* __ASSEMBLY__ */ +#endif /* _SUNXI_CPUCFG_SUN9I_H */
PATCH 7/10 sunxi: Add support for TZPC on sun9i/A80
In reply to Chen-Yu TsaiThe A80 also has the TrustZone Protection Controller (TZPC), called the Secure Memory Touch Arbiter (SMTA).
Enable non-secure access to all the peripherals at boot time.
--- arch/arm/cpu/armv7/sunxi/Makefile | 1 + arch/arm/cpu/armv7/sunxi/tzpc.c | 6 ++++++ arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 1 + arch/arm/include/asm/arch-sunxi/tzpc.h | 4 ++++ arch/arm/mach-sunxi/board.c | 3 ++- 5 files changed, 14 insertions(+), 1 deletion(-)
arch/arm/cpu/armv7/sunxi/Makefile +1 -0
@@ -11,6 +11,7 @@ obj-y += timer.o obj-$(CONFIG_MACH_SUN6I) += tzpc.o obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o +obj-$(CONFIG_MACH_SUN9I) += tzpc.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_ARMV7_PSCI) += psci.o
arch/arm/cpu/armv7/sunxi/tzpc.c +6 -0
@@ -24,4 +24,10 @@ void tzpc_init(void)writel (SUN8I_H3_TZPC_DECPORT1_ALL , &tzpc->decport1_set);writel (SUN8I_H3_TZPC_DECPORT2_ALL , &tzpc->decport2_set);#endif + +#ifdef CONFIG_MACH_SUN9I +writel (SUN9I_TZPC_DECPORT0_ALL , &tzpc->decport0_set); +writel (SUN9I_TZPC_DECPORT1_ALL , &tzpc->decport1_set); +writel (SUN9I_TZPC_DECPORT2_ALL , &tzpc->decport2_set); +#endif }
arch/arm/include/asm/arch-sunxi/cpu_sun9i.h +1 -0
@@ -90,6 +90,7 @@#define SUNXI_TIMER_BASE (REGS_APB0_BASE + 0x0C00)#define SUNXI_PWM_BASE (REGS_APB0_BASE + 0x1400)#define SUNXI_LRADC_BASE (REGS_APB0_BASE + 0x1800) +#define SUNXI_TZPC_BASE (REGS_APB0_BASE + 0x3400)/* APB1 Module */ #define SUNXI_UART0_BASE (REGS_APB1_BASE + 0x0000)
arch/arm/include/asm/arch-sunxi/tzpc.h +4 -0
@@ -29,6 +29,10 @@ struct sunxi_tzpc {#define SUN8I_H3_TZPC_DECPORT1_ALL 0xff#define SUN8I_H3_TZPC_DECPORT2_ALL 0x7f +#define SUN9I_TZPC_DECPORT0_ALL 0xfe +#define SUN9I_TZPC_DECPORT1_ALL 0x7f +#define SUN9I_TZPC_DECPORT2_ALL 0x00 +void tzpc_init (void );#endif /* _SUNXI_TZPC_H */
arch/arm/mach-sunxi/board.c +2 -1
@@ -190,7 +190,8 @@ void s_init(void)"orr r0, r0, #1 << 6\n" "mcr p15, 0, r0, c1, c0, 1\n");#endif -#if definedCONFIG_MACH_SUN6I || definedCONFIG_MACH_SUN8I_H3 +#if definedCONFIG_MACH_SUN6I || definedCONFIG_MACH_SUN8I_H3 || \ + definedCONFIG_MACH_SUN9I /* Enable non-secure access to some peripherals */ tzpc_init ();#endif
Signature · 1 line
2.10.2
PATCH 7/10 sunxi: Add support for TZPC on sun9i/A80
Hi,
Quoted 6 lines · Chen-Yu Tsai
The A80 also has the TrustZone Protection Controller (TZPC), called the Secure Memory Touch Arbiter (SMTA).
Enable non-secure access to all the peripherals at boot time.
Signed-off-by Chen-Yu Tsai <[email protected]>
LGTM:
Regards,
Hans
Quoted 77 lines
--- arch/arm/cpu/armv7/sunxi/Makefile | 1 + arch/arm/cpu/armv7/sunxi/tzpc.c | 6 ++++++ arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 1 + arch/arm/include/asm/arch-sunxi/tzpc.h | 4 ++++ arch/arm/mach-sunxi/board.c | 3 ++- 5 files changed, 14 insertions(+), 1 deletion(-)arch/arm/cpu/armv7/sunxi/Makefile +1
-0@@ -11,6 +11,7 @@ obj-y += timer.o obj-$(CONFIG_MACH_SUN6I) += tzpc.o obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o +obj-$(CONFIG_MACH_SUN9I) += tzpc.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_ARMV7_PSCI) += psci.oarch/arm/cpu/armv7/sunxi/tzpc.c +6
-0@@ -24,4 +24,10 @@ void tzpc_init(void)writel (SUN8I_H3_TZPC_DECPORT1_ALL , &tzpc->decport1_set);writel (SUN8I_H3_TZPC_DECPORT2_ALL , &tzpc->decport2_set);#endif + +#ifdef CONFIG_MACH_SUN9I +writel (SUN9I_TZPC_DECPORT0_ALL , &tzpc->decport0_set); +writel (SUN9I_TZPC_DECPORT1_ALL , &tzpc->decport1_set); +writel (SUN9I_TZPC_DECPORT2_ALL , &tzpc->decport2_set); +#endif }arch/arm/include/asm/arch-sunxi/cpu_sun9i.h +1
-0@@ -90,6 +90,7 @@#define SUNXI_TIMER_BASE (REGS_APB0_BASE + 0x0C00)#define SUNXI_PWM_BASE (REGS_APB0_BASE + 0x1400)#define SUNXI_LRADC_BASE (REGS_APB0_BASE + 0x1800) +#define SUNXI_TZPC_BASE (REGS_APB0_BASE + 0x3400)/* APB1 Module */ #define SUNXI_UART0_BASE (REGS_APB1_BASE + 0x0000)arch/arm/include/asm/arch-sunxi/tzpc.h +4
-0@@ -29,6 +29,10 @@ struct sunxi_tzpc {#define SUN8I_H3_TZPC_DECPORT1_ALL 0xff#define SUN8I_H3_TZPC_DECPORT2_ALL 0x7f +#define SUN9I_TZPC_DECPORT0_ALL 0xfe +#define SUN9I_TZPC_DECPORT1_ALL 0x7f +#define SUN9I_TZPC_DECPORT2_ALL 0x00 +void tzpc_init (void );#endif /* _SUNXI_TZPC_H */ arch/arm/mach-sunxi/board.c +2
-1@@ -190,7 +190,8 @@ void s_init(void)"orr r0, r0, #1 << 6\n" "mcr p15, 0, r0, c1, c0, 1\n");#endif -#if definedCONFIG_MACH_SUN6I || definedCONFIG_MACH_SUN8I_H3 +#if definedCONFIG_MACH_SUN6I || definedCONFIG_MACH_SUN8I_H3 || \ + definedCONFIG_MACH_SUN9I /* Enable non-secure access to some peripherals */ tzpc_init ();#endif
PATCH 8/10 sunxi: Add basic PSCI implementation for A80
In reply to Chen-Yu TsaiThe A80 is a big.LITTLE multi-cluster SoC, with a different layout for the PRCM and CPUCFG registers. As such it needs a different PSCI implementation.
This patch adds a basic version that allows bringing up the four cores in the first cluster. The structure is based on existing sunxi PSCI code.
--- arch/arm/cpu/armv7/sunxi/Makefile | 4 + arch/arm/cpu/armv7/sunxi/psci-mcpm.c | 234 +++++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 arch/arm/cpu/armv7/sunxi/psci-mcpm.c
arch/arm/cpu/armv7/sunxi/Makefile +4 -0
@@ -14,8 +14,12 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o obj-$(CONFIG_MACH_SUN9I) += tzpc.o ifndef CONFIG_SPL_BUILD +ifdef CONFIG_MACH_SUN9I +obj-$(CONFIG_ARMV7_PSCI) += psci-mcpm.o +else obj-$(CONFIG_ARMV7_PSCI) += psci.o endif +endif ifdef CONFIG_SPL_BUILD obj-y += fel_utils.o
arch/arm/cpu/armv7/sunxi/psci-mcpm.c new file +234 -0
234 lines not on this page · raw message
Signature · 1 line
2.10.2
PATCH 8/10 sunxi: Add basic PSCI implementation for A80
Hi,
Quoted 8 lines · Chen-Yu Tsai
The A80 is a big.LITTLE multi-cluster SoC, with a different layout for the PRCM and CPUCFG registers. As such it needs a different PSCI implementation.
This patch adds a basic version that allows bringing up the four cores in the first cluster. The structure is based on existing sunxi PSCI code.
Signed-off-by Chen-Yu Tsai <[email protected]>
LGTM:
Regards,
Hans
Quoted 264 lines
--- arch/arm/cpu/armv7/sunxi/Makefile | 4 + arch/arm/cpu/armv7/sunxi/psci-mcpm.c | 234 +++++++++++++++++++++++++++++++++++ 2 files changed, 238 insertions(+) create mode 100644 arch/arm/cpu/armv7/sunxi/psci-mcpm.carch/arm/cpu/armv7/sunxi/Makefile +4
-0@@ -14,8 +14,12 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o obj-$(CONFIG_MACH_SUN9I) += tzpc.o ifndef CONFIG_SPL_BUILD +ifdef CONFIG_MACH_SUN9I +obj-$(CONFIG_ARMV7_PSCI) += psci-mcpm.o +else obj-$(CONFIG_ARMV7_PSCI) += psci.o endif +endif ifdef CONFIG_SPL_BUILD obj-y += fel_utils.oarch/arm/cpu/armv7/sunxi/psci-mcpm.c new file +234
-0@@ -0,0 +1,234 @@ +/* +* Copyright (C) 2016 +* Author: Chen-Yu Tsai <[email protected]> +* +* Based on assembly code by Marc Zyngier <[email protected]>, +* which was based on code by Carl van Schaik <[email protected]>. +* +* SPDX-License-Identifier: GPL-2.0 +*/ +#include <config.h> +#include <common.h> + +#include <asm/arch/cpu.h> +#include <asm/arch/cpucfg_sun9i.h> +#include <asm/arch/prcm_sun9i.h> +#include <asm/armv7.h> +#include <asm/io.h> +#include <asm/psci.h> +#include <asm/secure.h> + +#include <linux/bitops.h> + +/* +* NOTE dense CPU IDs (0~3 for first cluster of 4 cores, 4~7 for the +* second cluster) are used throughout the PSCI code. Any MPIDR style +* values must be converted. +*/ + +/* +* Provide a dense CPU ID for 2-cluster systems. This must be coded in +* assembly as it gets called from psci_stack_setup, when the stack isn't +* available yet. +* +* Only r0 and r3 is usable. r8 - r12 are available if this function is +* only called from psci_stack_setup, which we cannot guarantee. +*/ +u32 __secure __naked psci_get_cpu_id(void) +{ + asmvolatile ( +"mrc p15, 0, r3, c0, c0, 5 @ Get MPIDR\n" +"lsr r0, r3, #6\n" +"and r3, r3, #3\n" +"and r0, r0, #4\n" +"orr r0, r0, r3\n" +"bx lr\n" + ); + +/* +* The last five lines are the compiler generated assembly code for +* +* return (reg & 0x3) | (((reg >> 8) & 0x1) << 2); +* +* We can't guarantee that all compilers correctly use only r0 and +* r3, so we use inline assembly here. +*/ +} + +static void __secure cp15_write_cntp_tval(u32 tval) +{ + asmvolatile ("mcr p15, 0, %0, c14, c2, 0" : :"r" (tval)); +} + +static void __secure cp15_write_cntp_ctl(u32 val) +{ + asmvolatile ("mcr p15, 0, %0, c14, c2, 1" : :"r" (val)); +} + +static u32 __secure cp15_read_cntp_ctl(void) +{ +u32 val; + + asmvolatile ("mrc p15, 0, %0, c14, c2, 1" :"=r" (val)); + +return val; +} + +#define ONE_US (CONFIG_TIMER_CLK_FREQ / 1000000) + +/* Use a different name to avoid clashing with the non-secure function */ +static void __secure __udelay_sec(unsigned long us) +{ +u32 reg =ONE_US * us; + +cp15_write_cntp_tval (reg); +isb (); +cp15_write_cntp_ctl (3 ); + +do { +isb (); + reg =cp15_read_cntp_ctl (); + }while (!(reg &BIT (2 ))); + +cp15_write_cntp_ctl (0 ); +isb (); +} + +static void __secure clamp_release(u32 *clamp) +{ +writel (0xff , clamp); +__udelay_sec (10 ); +writel (0xfe , clamp); +__udelay_sec (10 ); +writel (0xf8 , clamp); +__udelay_sec (10 ); +writel (0xf0 , clamp); +__udelay_sec (10 ); +writel (0x00 , clamp); +} + +static void __secure clamp_set(u32 *clamp) +{ +writel (0xff , clamp); +} + +static void __secure sunxi_core_power_switch(u32 *clamp, u32 *pwroff, +bool on,int cpu) +{ +if (on) { +/* Release power clamp */ +clamp_release (clamp); + +__udelay_sec (20 ); + +/* Clear power gating */ +clrbits_le32 (pwroff,BIT (cpu)); + }else { +/* Set power gating */ +setbits_le32 (pwroff,BIT (cpu)); + +__udelay_sec (20 ); + +/* Activate power clamp */ +clamp_set (clamp); + } +} + +static void __secure sunxi_cpu_set_power(int cpu, bool on) +{ +struct sunxi_prcm_reg *prcm = + (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE ; +int cluster = (cpu >>2 ) &0x1 ; +int core = cpu &0x3 ; + +sunxi_core_power_switch (&prcm->cpu_pwr_clamp[cluster][core], + &prcm->cpu_pwroff[cluster], on, core); +} + +static u32 __secure cp15_read_scr(void) +{ +u32 scr; + + asmvolatile ("mrc p15, 0, %0, c1, c1, 0" :"=r" (scr)); + +return scr; +} + +static void __secure cp15_write_scr(u32 scr) +{ + asmvolatile ("mcr p15, 0, %0, c1, c1, 0" : :"r" (scr)); +isb (); +} + +int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc) +{ +struct sunxi_cpucfg_reg *cpucfg = + (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE ; +struct sunxi_prcm_reg *prcm = + (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE ; +u32 cluster = (mpidr >>8 ) &0x1 ; +u32 cpu = mpidr &0x3 ; +u32 cpuid = cpu | (cluster <<2 ); + +/* TODO We don't support multi-cluster yet */ +if (cluster >0 ) +return ARM_PSCI_RET_INVAL ; + +/* store target PC */ +psci_save_target_pc (cpuid, pc); + +/* Set secondary core power on PC */ +writel ((u32)&psci_cpu_entry, &prcm->cpu_soft_entry); + +/* Assert power-on reset on target CPU */ +clrbits_le32 (&prcm->cpu_rst[cluster],BIT (cpu)); + +/* Cortex-A7: hold L1 cache reset disable signal low */ +if (cluster ==0 ) +clrbits_le32 (&cpucfg->cluster[cluster].ctrl0, +CPUCFG_CX_CTRL0_L1_RST_DISABLE (cpu)); + +/* Lock CPU (Disable external debug access) */ +clrbits_le32 (&cpucfg->cluster_reset[cluster], +CPUCFG_CX_RST_DBG (cpu)); + +/* Cortex-A7: Assert ETM reset */ +if (cluster ==0 ) +clrbits_le32 (&cpucfg->cluster_reset[cluster], +CPUCFG_CX_RST_ETM (cpu)); + +/* +* Allwinner code also asserts resets for NEON on A15. According +* to ARM manuals, asserting power-on reset is sufficient. +*/ + +/* Power up target CPU */ +sunxi_cpu_set_power (cpu, true); + +/* De-assert power-on reset on target CPU */ +setbits_le32 (&prcm->cpu_rst[cluster],BIT (cpu)); + +/* De-assert core reset on target CPU */ +setbits_le32 (&cpucfg->cluster_reset[cluster], +CPUCFG_CX_RST_CORE (cpu)); + +/* Cortex-A7: De-assert ETM reset */ +if (cluster ==0 ) +setbits_le32 (&cpucfg->cluster_reset[cluster], +CPUCFG_CX_RST_ETM (cpu)); + +/* Unlock CPU (Disable external debug access) */ +setbits_le32 (&cpucfg->cluster_reset[cluster], +CPUCFG_CX_RST_DBG (cpu)); + +return ARM_PSCI_RET_SUCCESS ; +} + +void __secure psci_arch_init(void) +{ +u32 reg; + + reg =cp15_read_scr (); + reg &= ~BIT (0 );/* Secure mode */ +cp15_write_scr (reg); +}
PATCH 9/10 sunxi: Enable PSCI on sun9i/A80
In reply to Chen-Yu TsaiNow that we have a basic version of PSCI firmware, enable non-secure boot and PSCI on the A80.
--- board/sunxi/Kconfig | 4 ++++ 1 file changed, 4 insertions(+)
board/sunxi/Kconfig +4 -0
@@ -118,8 +118,12 @@ config MACH_SUN8I_H3 config MACH_SUN9I bool "sun9i (Allwinner A80)" select CPU_V7 + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT + select ARCH_SUPPORT_PSCI select SUNXI_GEN_SUN6I select SUPPORT_SPL + select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT config MACH_SUN50I bool "sun50i (Allwinner A64)"
Signature · 1 line
2.10.2
PATCH 9/10 sunxi: Enable PSCI on sun9i/A80
Hi,
Quoted 4 lines · Chen-Yu Tsai
Now that we have a basic version of PSCI firmware, enable non-secure boot and PSCI on the A80.
Signed-off-by Chen-Yu Tsai <[email protected]>
LGTM:
Regards,
Hans
Quoted 22 lines
--- board/sunxi/Kconfig | 4 ++++ 1 file changed, 4 insertions(+)board/sunxi/Kconfig +4
-0@@ -118,8 +118,12 @@ config MACH_SUN8I_H3 config MACH_SUN9I bool "sun9i (Allwinner A80)" select CPU_V7 + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT + select ARCH_SUPPORT_PSCI select SUNXI_GEN_SUN6I select SUPPORT_SPL + select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT config MACH_SUN50I bool "sun50i (Allwinner A64)"
PATCH 9/10 sunxi: Enable PSCI on sun9i/A80
In reply to Chen-Yu TsaiI this this series is already merged as with latest changes on tree, but still shows 'New' in patchwork, Can someone confirm then I will update the same?
Quoted 32 lines · Chen-Yu Tsai
Now that we have a basic version of PSCI firmware, enable non-secure boot and PSCI on the A80.
Signed-off-by Chen-Yu Tsai <[email protected]>--- board/sunxi/Kconfig | 4 ++++ 1 file changed, 4 insertions(+)board/sunxi/Kconfig +4
-1@@ -118,8 +118,12 @@ config MACH_SUN8I_H3 config MACH_SUN9I bool "sun9i (Allwinner A80)" select CPU_V7 + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT + select ARCH_SUPPORT_PSCI select SUNXI_GEN_SUN6I select SUPPORT_SPL + select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT config MACH_SUN50I bool "sun50i (Allwinner A64)" --2.10.2
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
Signature · 4 lines
Jagan Teki Free Software Engineer | www.openedev.com U-Boot, Linux | Upstream Maintainer Hyderabad, India.
PATCH 9/10 sunxi: Enable PSCI on sun9i/A80
Hi,
Quoted 3 lines · Jagan Teki
I this this series is already merged as with latest changes on tree, but still shows 'New' in patchwork, Can someone confirm then I will update the same?
The series is on hold, as it breaks Linux. I've identified the culprit (non-secure world access to the GIC is actually secure) but the fix is really nasty and I haven't tested it reliably yet.
ChenYu
Quoted 41 lines · Chen-Yu Tsai
Quoted 28 lines
Now that we have a basic version of PSCI firmware, enable non-secure boot and PSCI on the A80.
Signed-off-by Chen-Yu Tsai <[email protected]>--- board/sunxi/Kconfig | 4 ++++ 1 file changed, 4 insertions(+)board/sunxi/Kconfig +4
-1@@ -118,8 +118,12 @@ config MACH_SUN8I_H3 config MACH_SUN9I bool "sun9i (Allwinner A80)" select CPU_V7 + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT + select ARCH_SUPPORT_PSCI select SUNXI_GEN_SUN6I select SUPPORT_SPL + select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT config MACH_SUN50I bool "sun50i (Allwinner A64)" --2.10.2
Quoted 4 lines
_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot--
Jagan Teki
Free Software Engineer | www.openedev.com
U-Boot, Linux | Upstream Maintainer
Hyderabad, India.
PATCH 10/10 sunxi: Add PSCI core power off support for A80's first cluster
In reply to Chen-Yu TsaiThis patch adds the ability to power off cores in the first cluster of the A80 SoC. Following the single cluster sunxi PSCI implementation, the core being powered down signals core0 via secure monitor FIQ that it should be shut down, and enters WFI.
---
This does not actually work. While the system is indeed booted non-secure, tested by trying to write to secure SRAM and the results not sticking, reads from the GIC CPU interface shows that it's still returning the secure copy of registers, and since we use a secure monitor FIQ to do core power down, the FIQ gets passed to the kernel. The patch is included so people with in-depth ARM knowledge could probably help work out what is wrong.
Any thoughts on this is appreciated.
--- arch/arm/cpu/armv7/sunxi/psci-mcpm.c | 88 ++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+)
arch/arm/cpu/armv7/sunxi/psci-mcpm.c +88 -0
@@ -14,12 +14,19 @@#include <asm/arch/cpucfg_sun9i.h> #include <asm/arch/prcm_sun9i.h> #include <asm/armv7.h> +#include <asm/gic.h> #include <asm/io.h> #include <asm/psci.h> #include <asm/secure.h> +#include <asm/system.h> #include <linux/bitops.h> +#define __irq __attribute__ ((interrupt ("IRQ"))) + +#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET) +#define GICC_BASE (SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15) +/* * NOTE dense CPU IDs (0~3 for first cluster of 4 cores, 4~7 for the * second cluster) are used throughout the PSCI code. Any MPIDR style
@@ -145,6 +152,25 @@ static void __secure sunxi_cpu_set_power(int cpu, bool on) &prcm->cpu_pwroff[cluster], on, core); } +void __secure sunxi_cpu_power_off(u32 cpuid) +{ +struct sunxi_cpucfg_reg *cpucfg = + (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE ; +u32 cluster = (cpuid >>2 ) &0x1 ; +u32 core = cpuid &0x3 ; + +/* Wait for the core to enter WFI */ +while (1 ) { +if (readl (&cpucfg->cluster_status[cluster]) & +CPUCFG_CX_STATUS_STANDBYWFI (core)) +break ; +__udelay_sec (1000 ); + } + +/* Power down CPU */ +sunxi_cpu_set_power (cpuid, false); +} + static u32 __secure cp15_read_scr(void) {u32 scr;
@@ -160,6 +186,42 @@ static void __secure cp15_write_scr(u32 scr)isb (); } +/* +* Although this is an FIQ handler, the FIQ is processed in monitor mode, +* which means there's no FIQ banked registers. This is the same as IRQ +* mode, so use the IRQ attribute to ask the compiler to handler entry +* and return. +*/ +void __secure __irq psci_fiq_enter(void) +{ +u32 scr, reg, cpu; + +/* Switch to secure mode */ + scr =cp15_read_scr (); +cp15_write_scr (scr & ~BIT (0 )); + +/* Validate reason based on IAR and acknowledge */ + reg =readl (GICC_BASE +GICC_IAR ); + +/* Skip spurious interrupts 1022 and 1023 */ +if (reg ==1023 || reg ==1022 ) + goto out; + +/* End of interrupt */ +writel (reg,GICC_BASE +GICC_EOIR ); +dsb (); + +/* Get CPU number */ + cpu = (reg >>10 ) &0x7 ; + +/* Power off the CPU */ +sunxi_cpu_power_off (cpu); + +out: +/* Restore security level */ +cp15_write_scr (scr); +} + int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc) { struct sunxi_cpucfg_reg *cpucfg =
@@ -224,11 +286,37 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc)return ARM_PSCI_RET_SUCCESS ; } +void __secure psci_cpu_off(void) +{ +psci_cpu_off_common (); + +/* Ask CPU0 via SGI15 to pull the rug... */ +writel (BIT (16 ) |15 ,GICD_BASE +GICD_SGIR ); +dsb (); + +/* Wait to be turned off */ +while (1 ) +wfi (); +} + void __secure psci_arch_init(void) {u32 reg; +/* SGI15 as Group-0 */ +clrbits_le32 (GICD_BASE + GICD_IGROUPRn,BIT (15 )); + +/* Set SGI15 priority to 0 */ +writeb (0 ,GICD_BASE + GICD_IPRIORITYRn +15 ); + +/* Be cool with non-secure */ +writel (0xff ,GICC_BASE +GICC_PMR ); + +/* Switch FIQEn on */ +setbits_le32 (GICC_BASE +GICC_CTLR ,BIT (3 )); + reg =cp15_read_scr (); + reg |=BIT (2 );/* Enable FIQ in monitor mode */ reg &= ~BIT (0 );/* Secure mode */ cp15_write_scr (reg); }
Signature · 1 line
2.10.2
cover sunxi: Add basic PSCI support to enable SMP on the A80's first cluster
In reply to Chen-Yu TsaiHi,
Quoted 10 lines · Chen-Yu Tsai
Hi everyone,
This series adds basic PSCI support for the A80 to enable SMP on the first cluster. This at least allows people to use more than one core. The term "basic" is used because the series does not add support for multi-cluster cache and power management.
The PSCI code is based on existing code for all the single cluster SoCs, and the kernel patches for MCPM SMP I did some time ago.
Quoted 8 lines
Unfortunately only SMP works at this time. The last patch does not actually work. While the system is indeed booted non-secure, tested by trying to write to secure SRAM and the results not sticking, reads from the GIC CPU interface shows that it's still returning the secure copy of registers, and since we use a secure monitor FIQ to do core power down, the FIQ gets passed to the kernel. The patch is included so people with in-depth ARM knowledge could probably help work out what is wrong.
Cools stuff, when I find some time I will review and merge patches 1-9 to sunxi-next.
First a question though, do you see any chance that merging this might get in the way of enabling support for both clusters in the future?
Since the interface between u-boot and the kernel here is well defined (and outside our control) I guess in the worst case, we would need to revert some bits of this series from u-boot if they turn out to be non suitable, right?
Regards,
Hans
Quoted 33 lines
Regards
ChenYuChen-Yu Tsai (10):
ARM: PSCI: SetARMV7_PSCI_NR_CPUSdefault to 8 for sun9i/A80
sunxi: Add CCI-400 and CPUCFG registers base address for sun9i/A80
sunxi: Add base address of secure SRAM B for sun9i/A80
sunxi: Use secure SRAM B for secure RAM for sun9i/A80
sunxi: Add PRCM register definition for sun9i/A80
sunxi: Add CPUCFG register definitions for sun9i/A80
sunxi: Add support for TZPC on sun9i/A80
sunxi: Add basic PSCI implementation for A80
sunxi: Enable PSCI on sun9i/A80
sunxi: Add PSCI core power off support for A80's first clusterarch/arm/cpu/armv7/Kconfig | 1 + arch/arm/cpu/armv7/sunxi/Makefile | 5 + arch/arm/cpu/armv7/sunxi/psci-mcpm.c | 322 +++++++++++++++++++++++++ arch/arm/cpu/armv7/sunxi/tzpc.c | 6 + arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 5 + arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h | 51 ++++ arch/arm/include/asm/arch-sunxi/prcm_sun9i.h | 55 +++++ arch/arm/include/asm/arch-sunxi/tzpc.h | 4 + arch/arm/mach-sunxi/board.c | 3 +- board/sunxi/Kconfig | 4 + include/configs/sun9i.h | 4 + 11 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/sunxi/psci-mcpm.c create mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h create mode 100644 arch/arm/include/asm/arch-sunxi/prcm_sun9i.h
cover sunxi: Add basic PSCI support to enable SMP on the A80's first cluster
Quoted 27 lines · Hans de Goede
Hi,
Quoted 11 lines · Chen-Yu Tsai
Hi everyone,
This series adds basic PSCI support for the A80 to enable SMP on the first cluster. This at least allows people to use more than one core. The term "basic" is used because the series does not add support for multi-cluster cache and power management.
The PSCI code is based on existing code for all the single cluster SoCs, and the kernel patches for MCPM SMP I did some time ago.
Quoted 8 lines
Unfortunately only SMP works at this time. The last patch does not actually work. While the system is indeed booted non-secure, tested by trying to write to secure SRAM and the results not sticking, reads from the GIC CPU interface shows that it's still returning the secure copy of registers, and since we use a secure monitor FIQ to do core power down, the FIQ gets passed to the kernel. The patch is included so people with in-depth ARM knowledge could probably help work out what is wrong.
Cools stuff, when I find some time I will review and merge patches 1-9 to sunxi-next.
Quoted 7 lines
First a question though, do you see any chance that merging this might get in the way of enabling support for both clusters in the future?
Since the interface between u-boot and the kernel here is well defined (and outside our control) I guess in the worst case, we would need to revert some bits of this series from u-boot if they turn out to be non suitable, right?
AFAIK with PSCI the firmware is responsible for doing all the setup before handing the core to the kernel. For now I just return -EINVAL for the latter 4 cores.
Once we have all the multi cluster support in, such as cluster powering, synchronization, and CCI-400, instead of returning -EINVAL, we can have it actually give back a working core.
And Linux can't access CCI-400 in non-secure mode anyway. This has to be setup by the firmware.
In short, just merging the power on bits for the first cluster here should not block any attempts to merge any future progress.
Regards
ChenYu
Quoted 43 lines
Regards,
Hans
Quoted 34 lines
Regards
ChenYuChen-Yu Tsai (10):
ARM: PSCI: SetARMV7_PSCI_NR_CPUSdefault to 8 for sun9i/A80
sunxi: Add CCI-400 and CPUCFG registers base address for sun9i/A80
sunxi: Add base address of secure SRAM B for sun9i/A80
sunxi: Use secure SRAM B for secure RAM for sun9i/A80
sunxi: Add PRCM register definition for sun9i/A80
sunxi: Add CPUCFG register definitions for sun9i/A80
sunxi: Add support for TZPC on sun9i/A80
sunxi: Add basic PSCI implementation for A80
sunxi: Enable PSCI on sun9i/A80
sunxi: Add PSCI core power off support for A80's first clusterarch/arm/cpu/armv7/Kconfig | 1 + arch/arm/cpu/armv7/sunxi/Makefile | 5 + arch/arm/cpu/armv7/sunxi/psci-mcpm.c | 322 +++++++++++++++++++++++++ arch/arm/cpu/armv7/sunxi/tzpc.c | 6 + arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 5 + arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h | 51 ++++ arch/arm/include/asm/arch-sunxi/prcm_sun9i.h | 55 +++++ arch/arm/include/asm/arch-sunxi/tzpc.h | 4 + arch/arm/mach-sunxi/board.c | 3 +- board/sunxi/Kconfig | 4 + include/configs/sun9i.h | 4 + 11 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/sunxi/psci-mcpm.c create mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h create mode 100644 arch/arm/include/asm/arch-sunxi/prcm_sun9i.h
cover sunxi: Add basic PSCI support to enable SMP on the A80's first cluster
In reply to Hans de GoedeHi,
Quoted 27 lines · Hans de Goede
Hi,
Quoted 11 lines · Chen-Yu Tsai
Hi everyone,
This series adds basic PSCI support for the A80 to enable SMP on the first cluster. This at least allows people to use more than one core. The term "basic" is used because the series does not add support for multi-cluster cache and power management.
The PSCI code is based on existing code for all the single cluster SoCs, and the kernel patches for MCPM SMP I did some time ago.
Quoted 8 lines
Unfortunately only SMP works at this time. The last patch does not actually work. While the system is indeed booted non-secure, tested by trying to write to secure SRAM and the results not sticking, reads from the GIC CPU interface shows that it's still returning the secure copy of registers, and since we use a secure monitor FIQ to do core power down, the FIQ gets passed to the kernel. The patch is included so people with in-depth ARM knowledge could probably help work out what is wrong.
Cools stuff, when I find some time I will review and merge patches 1-9 to sunxi-next.
Quoted 7 lines
First a question though, do you see any chance that merging this might get in the way of enabling support for both clusters in the future?
Since the interface between u-boot and the kernel here is well defined (and outside our control) I guess in the worst case, we would need to revert some bits of this series from u-boot if they turn out to be non suitable, right?
So I started digging through why CPU power off is sending FIQs to the kernel. So it turns out that the GIC base address programmed in the CPU's CBAR is incorrect, so the GIC is not blocking secure interrupts, and when the interrupt returns the CPU seems to get switched to secure mode.
After hard-coding in the correct address, the system no longer boots. It hangs when it tries to bring up the second core. I'm not sure what's going on though. Need to add some more trace code.
I might have opened a can of worms...
ChenYu
Quoted 43 lines
Regards,
Hans
Quoted 34 lines
Regards
ChenYuChen-Yu Tsai (10):
ARM: PSCI: SetARMV7_PSCI_NR_CPUSdefault to 8 for sun9i/A80
sunxi: Add CCI-400 and CPUCFG registers base address for sun9i/A80
sunxi: Add base address of secure SRAM B for sun9i/A80
sunxi: Use secure SRAM B for secure RAM for sun9i/A80
sunxi: Add PRCM register definition for sun9i/A80
sunxi: Add CPUCFG register definitions for sun9i/A80
sunxi: Add support for TZPC on sun9i/A80
sunxi: Add basic PSCI implementation for A80
sunxi: Enable PSCI on sun9i/A80
sunxi: Add PSCI core power off support for A80's first clusterarch/arm/cpu/armv7/Kconfig | 1 + arch/arm/cpu/armv7/sunxi/Makefile | 5 + arch/arm/cpu/armv7/sunxi/psci-mcpm.c | 322 +++++++++++++++++++++++++ arch/arm/cpu/armv7/sunxi/tzpc.c | 6 + arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 5 + arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h | 51 ++++ arch/arm/include/asm/arch-sunxi/prcm_sun9i.h | 55 +++++ arch/arm/include/asm/arch-sunxi/tzpc.h | 4 + arch/arm/mach-sunxi/board.c | 3 +- board/sunxi/Kconfig | 4 + include/configs/sun9i.h | 4 + 11 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/sunxi/psci-mcpm.c create mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h create mode 100644 arch/arm/include/asm/arch-sunxi/prcm_sun9i.h
cover sunxi: Add basic PSCI support to enable SMP on the A80's first cluster
Hi everyone,
Quoted 44 lines · Chen-Yu Tsai
Hi,
Quoted 27 lines · Hans de Goede
Hi,
Quoted 11 lines · Chen-Yu Tsai
Hi everyone,
This series adds basic PSCI support for the A80 to enable SMP on the first cluster. This at least allows people to use more than one core. The term "basic" is used because the series does not add support for multi-cluster cache and power management.
The PSCI code is based on existing code for all the single cluster SoCs, and the kernel patches for MCPM SMP I did some time ago.
Quoted 8 lines
Unfortunately only SMP works at this time. The last patch does not actually work. While the system is indeed booted non-secure, tested by trying to write to secure SRAM and the results not sticking, reads from the GIC CPU interface shows that it's still returning the secure copy of registers, and since we use a secure monitor FIQ to do core power down, the FIQ gets passed to the kernel. The patch is included so people with in-depth ARM knowledge could probably help work out what is wrong.
Cools stuff, when I find some time I will review and merge patches 1-9 to sunxi-next.
Quoted 7 lines
First a question though, do you see any chance that merging this might get in the way of enabling support for both clusters in the future?
Since the interface between u-boot and the kernel here is well defined (and outside our control) I guess in the worst case, we would need to revert some bits of this series from u-boot if they turn out to be non suitable, right?
So I started digging through why CPU power off is sending FIQs to the kernel. So it turns out that the GIC base address programmed in the CPU's CBAR is incorrect, so the GIC is not blocking secure interrupts, and when the interrupt returns the CPU seems to get switched to secure mode.
Quoted 5 lines
After hard-coding in the correct address, the system no longer boots. It hangs when it tries to bring up the second core. I'm not sure what's going on though. Need to add some more trace code.
I might have opened a can of worms...
I got PSCI actually working today.
So the whole TrustZone implementation on the A80 is kind of broken, much like the A64. The TZPC doesn't actually do anything. All access to the GIC is "secure", regardless of the core's secure state. This means if we want separate groups of interrupts (secure and non-secure), which we do for the PSCI implementation for one core to tell another to shut it down, we have to use the aliased non-secure register fields, all the while making sure not to step on the secure interrupts the PSCI firmware needs.
This is doable, and it is actually what Allwinner's kernel does, but is really hackish. The released 3.4 kernel also has the same workarounds for A83T. So it's also possible the A83T has the same issues.
So, if there's still interest in getting a working PSCI environment for the A80/A83T, I'll look into doing a workaround patch for GIC-400. Otherwise I'm going to go back and revive my MCPM patches for in-kernel SMP support.
Regards
ChenYu
Quoted 46 lines
ChenYu
Quoted 43 lines
Regards,
Hans
Quoted 34 lines
Regards
ChenYuChen-Yu Tsai (10):
ARM: PSCI: SetARMV7_PSCI_NR_CPUSdefault to 8 for sun9i/A80
sunxi: Add CCI-400 and CPUCFG registers base address for sun9i/A80
sunxi: Add base address of secure SRAM B for sun9i/A80
sunxi: Use secure SRAM B for secure RAM for sun9i/A80
sunxi: Add PRCM register definition for sun9i/A80
sunxi: Add CPUCFG register definitions for sun9i/A80
sunxi: Add support for TZPC on sun9i/A80
sunxi: Add basic PSCI implementation for A80
sunxi: Enable PSCI on sun9i/A80
sunxi: Add PSCI core power off support for A80's first clusterarch/arm/cpu/armv7/Kconfig | 1 + arch/arm/cpu/armv7/sunxi/Makefile | 5 + arch/arm/cpu/armv7/sunxi/psci-mcpm.c | 322 +++++++++++++++++++++++++ arch/arm/cpu/armv7/sunxi/tzpc.c | 6 + arch/arm/include/asm/arch-sunxi/cpu_sun9i.h | 5 + arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h | 51 ++++ arch/arm/include/asm/arch-sunxi/prcm_sun9i.h | 55 +++++ arch/arm/include/asm/arch-sunxi/tzpc.h | 4 + arch/arm/mach-sunxi/board.c | 3 +- board/sunxi/Kconfig | 4 + include/configs/sun9i.h | 4 + 11 files changed, 459 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/sunxi/psci-mcpm.c create mode 100644 arch/arm/include/asm/arch-sunxi/cpucfg_sun9i.h create mode 100644 arch/arm/include/asm/arch-sunxi/prcm_sun9i.h
cover sunxi: Add basic PSCI support to enable SMP on the A80's first cluster
On Wed, Jan 25, 2017 at 06:40:38PM +0800, Chen-Yu Tsai wrote:
[hacking around the broken A80 TrustZone implementation]
Quoted 3 lines
This is doable, and it is actually what Allwinner's kernel does, but is really hackish. The released 3.4 kernel also has the same workarounds for A83T. So it's also possible the A83T has the same issues.
FWIW, the kernel that ships with my A80 based media player produces this:
[ 0.000000] Linux version 3.4.39+ (lzq at sunchip-CS24-TY) (gcc version 4.6.3 20120201 (prerelease) (crosstool-NG linaro-1.13.1-2012.02-20120222 - Linaro GCC 2012.02) ) #1 SMP PREEMPT Sat Nov 14 03:33:12 UTC 2015 ... [ 0.262230] CPU4: failed to boot: -22 [ 0.302298] CPU5: failed to boot: -22 [ 0.342350] CPU6: failed to boot: -22 [ 0.382421] CPU7: failed to boot: -22
So I guess you are not alone in having trouble getting PSCI to work on the A80. However, when trying out your patches, I also once or twice got a failure booting CPU2 although CPU3 and CPU4 came up fine.
Quoted 4 lines
So, if there's still interest in getting a working PSCI environment for the A80/A83T, I'll look into doing a workaround patch for GIC-400. Otherwise I'm going to go back and revive my MCPM patches for in-kernel SMP support.
I vote for whatever works. I'll also happily test it. Is there a git tree I should keep an eye on?
Signature · 1 line
Rask Ingemann Lambertsen
A message that is not in the archive (sent off-list or not yet received): CAD6G_RQ4KSH2HpwQKzv7U_1e1K72XNXJ3esMt+nhrU7Z_Ybg=Q@mail.gmail.com
cover sunxi: Add basic PSCI support to enable SMP on the A80's first cluster
Quoted 26 lines · Jagan Teki
Quoted 24 lines · Rask Ingemann Lambertsen
On Wed, Jan 25, 2017 at 06:40:38PM +0800, Chen-Yu Tsai wrote:
[hacking around the broken A80 TrustZone implementation]
Quoted 3 lines
This is doable, and it is actually what Allwinner's kernel does, but is really hackish. The released 3.4 kernel also has the same workarounds for A83T. So it's also possible the A83T has the same issues.
FWIW, the kernel that ships with my A80 based media player produces this:
[ 0.000000] Linux version 3.4.39+ (lzq at sunchip-CS24-TY) (gcc version 4.6.3 20120201 (prerelease) (crosstool-NG linaro-1.13.1-2012.02-20120222 - Linaro GCC 2012.02) ) #1 SMP PREEMPT Sat Nov 14 03:33:12 UTC 2015 ... [ 0.262230] CPU4: failed to boot: -22 [ 0.302298] CPU5: failed to boot: -22 [ 0.342350] CPU6: failed to boot: -22 [ 0.382421] CPU7: failed to boot: -22So I guess you are not alone in having trouble getting PSCI to work on the A80. However, when trying out your patches, I also once or twice got a failure booting CPU2 although CPU3 and CPU4 came up fine.
Quoted 4 lines
So, if there's still interest in getting a working PSCI environment for the A80/A83T, I'll look into doing a workaround patch for GIC-400. Otherwise I'm going to go back and revive my MCPM patches for in-kernel SMP support.
Quoted 7 lines
Quoted 2 lines
I vote for whatever works. I'll also happily test it. Is there a git tree I should keep an eye on?
Any further update on this series? I think there is an issue this wrt comment on "[U-Boot,09/10] sunxi: Enable PSCI on sun9i/A80" patch, Please send the next version on once resolved. Will mark this series as "Superseded"
+ U-Boot
cover sunxi: Add basic PSCI support to enable SMP on the A80's first cluster
Quoted 27 lines · Jagan Teki
Quoted 26 lines · Jagan Teki
Quoted 24 lines · Rask Ingemann Lambertsen
On Wed, Jan 25, 2017 at 06:40:38PM +0800, Chen-Yu Tsai wrote:
[hacking around the broken A80 TrustZone implementation]
Quoted 3 lines
This is doable, and it is actually what Allwinner's kernel does, but is really hackish. The released 3.4 kernel also has the same workarounds for A83T. So it's also possible the A83T has the same issues.
FWIW, the kernel that ships with my A80 based media player produces this:
[ 0.000000] Linux version 3.4.39+ (lzq at sunchip-CS24-TY) (gcc version 4.6.3 20120201 (prerelease) (crosstool-NG linaro-1.13.1-2012.02-20120222 - Linaro GCC 2012.02) ) #1 SMP PREEMPT Sat Nov 14 03:33:12 UTC 2015 ... [ 0.262230] CPU4: failed to boot: -22 [ 0.302298] CPU5: failed to boot: -22 [ 0.342350] CPU6: failed to boot: -22 [ 0.382421] CPU7: failed to boot: -22So I guess you are not alone in having trouble getting PSCI to work on the A80. However, when trying out your patches, I also once or twice got a failure booting CPU2 although CPU3 and CPU4 came up fine.
Quoted 4 lines
So, if there's still interest in getting a working PSCI environment for the A80/A83T, I'll look into doing a workaround patch for GIC-400. Otherwise I'm going to go back and revive my MCPM patches for in-kernel SMP support.
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines
I vote for whatever works. I'll also happily test it. Is there a git tree I should keep an eye on?
Any further update on this series? I think there is an issue this wrt comment on "[U-Boot,09/10] sunxi: Enable PSCI on sun9i/A80" patch, Please send the next version on once resolved. Will mark this series as "Superseded"
This needs some work on the kernel side before it will work properly, due to the A80's security features being somewhat broken. And the kernel side fix is really ugly. To be honest I'm not much for pursuing this right now. I'm hoping the A83T isn't broken in a similar fashion.
ChenYu