aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-stm32mp/psci.c')
-rw-r--r--arch/arm/mach-stm32mp/psci.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/arch/arm/mach-stm32mp/psci.c b/arch/arm/mach-stm32mp/psci.c
index 6ed2482080..139bb09292 100644
--- a/arch/arm/mach-stm32mp/psci.c
+++ b/arch/arm/mach-stm32mp/psci.c
@@ -47,14 +47,14 @@ static u32 __secure stm32mp_get_gicd_base_address(void)
47 return (periphbase & CBAR_MASK) + GIC_DIST_OFFSET; 47 return (periphbase & CBAR_MASK) + GIC_DIST_OFFSET;
48} 48}
49 49
50static void __secure stm32mp_smp_kick_all_cpus(void) 50static void __secure stm32mp_raise_sgi0(int cpu)
51{ 51{
52 u32 gic_dist_addr; 52 u32 gic_dist_addr;
53 53
54 gic_dist_addr = stm32mp_get_gicd_base_address(); 54 gic_dist_addr = stm32mp_get_gicd_base_address();
55 55
56 /* kick all CPUs (except this one) by writing to GICD_SGIR */ 56 /* ask cpu with SGI0 */
57 writel(1U << 24, gic_dist_addr + GICD_SGIR); 57 writel((BIT(cpu) << 16), gic_dist_addr + GICD_SGIR);
58} 58}
59 59
60void __secure psci_arch_cpu_entry(void) 60void __secure psci_arch_cpu_entry(void)
@@ -62,6 +62,9 @@ void __secure psci_arch_cpu_entry(void)
62 u32 cpu = psci_get_cpu_id(); 62 u32 cpu = psci_get_cpu_id();
63 63
64 psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON); 64 psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON);
65
66 /* reset magic in TAMP register */
67 writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER);
65} 68}
66 69
67int __secure psci_features(u32 function_id, u32 psci_fid) 70int __secure psci_features(u32 function_id, u32 psci_fid)
@@ -103,7 +106,13 @@ int __secure psci_affinity_info(u32 function_id, u32 target_affinity,
103 106
104int __secure psci_migrate_info_type(u32 function_id) 107int __secure psci_migrate_info_type(u32 function_id)
105{ 108{
106 /* Trusted OS is either not present or does not require migration */ 109 /*
110 * in Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
111 * return 2 = Trusted OS is either not present or does not require
112 * migration, system of this type does not require the caller
113 * to use the MIGRATE function.
114 * MIGRATE function calls return NOT_SUPPORTED.
115 */
107 return 2; 116 return 2;
108} 117}
109 118
@@ -121,6 +130,16 @@ int __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc,
121 if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON) 130 if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON)
122 return ARM_PSCI_RET_ALREADY_ON; 131 return ARM_PSCI_RET_ALREADY_ON;
123 132
133 /* reset magic in TAMP register */
134 if (readl(TAMP_BACKUP_MAGIC_NUMBER))
135 writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER);
136 /*
137 * ROM code need a first SGI0 after core reset
138 * core is ready when magic is set to 0 in ROM code
139 */
140 while (readl(TAMP_BACKUP_MAGIC_NUMBER))
141 stm32mp_raise_sgi0(cpu);
142
124 /* store target PC and context id*/ 143 /* store target PC and context id*/
125 psci_save(cpu, pc, context_id); 144 psci_save(cpu, pc, context_id);
126 145
@@ -136,7 +155,8 @@ int __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc,
136 writel(BOOT_API_A7_CORE0_MAGIC_NUMBER, 155 writel(BOOT_API_A7_CORE0_MAGIC_NUMBER,
137 TAMP_BACKUP_MAGIC_NUMBER); 156 TAMP_BACKUP_MAGIC_NUMBER);
138 157
139 stm32mp_smp_kick_all_cpus(); 158 /* Generate an IT to start the core */
159 stm32mp_raise_sgi0(cpu);
140 160
141 return ARM_PSCI_RET_SUCCESS; 161 return ARM_PSCI_RET_SUCCESS;
142} 162}