blob: 1e69673e88b40cb22b2dba901f8a16c0ea24b9e6 [file] [log] [blame]
Patrick Delaunay41c79772018-04-16 10:13:24 +02001// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
2/*
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4 */
5
6#include <config.h>
7#include <common.h>
8#include <asm/armv7.h>
Simon Glass90526e92020-05-10 11:39:56 -06009#include <asm/cache.h>
Patrick Delaunay41c79772018-04-16 10:13:24 +020010#include <asm/gic.h>
11#include <asm/io.h>
12#include <asm/psci.h>
13#include <asm/secure.h>
Marek Vasutb4910532022-02-25 02:15:59 +010014#include <hang.h>
Simon Glasscd93d622020-05-10 11:40:13 -060015#include <linux/bitops.h>
Patrick Delaunay41c79772018-04-16 10:13:24 +020016
Marek Vasutb4910532022-02-25 02:15:59 +010017/* PWR */
18#define PWR_CR3 0x0c
19#define PWR_MPUCR 0x10
Patrick Delaunay41c79772018-04-16 10:13:24 +020020
Marek Vasutb4910532022-02-25 02:15:59 +010021#define PWR_CR3_DDRSREN BIT(10)
22#define PWR_CR3_DDRRETEN BIT(12)
Patrick Delaunay41c79772018-04-16 10:13:24 +020023
Marek Vasutb4910532022-02-25 02:15:59 +010024#define PWR_MPUCR_PDDS BIT(0)
25#define PWR_MPUCR_CSTDBYDIS BIT(3)
26#define PWR_MPUCR_CSSF BIT(9)
Patrick Delaunay41c79772018-04-16 10:13:24 +020027
Marek Vasutb4910532022-02-25 02:15:59 +010028/* RCC */
Marek Vasutd6ae1832022-04-26 16:38:05 +020029#define RCC_MSSCKSELR 0x48
Marek Vasutb4910532022-02-25 02:15:59 +010030#define RCC_DDRITFCR 0xd8
31
32#define RCC_DDRITFCR_DDRC1EN BIT(0)
33#define RCC_DDRITFCR_DDRC1LPEN BIT(1)
34#define RCC_DDRITFCR_DDRC2EN BIT(2)
35#define RCC_DDRITFCR_DDRC2LPEN BIT(3)
36#define RCC_DDRITFCR_DDRPHYCEN BIT(4)
37#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5)
38#define RCC_DDRITFCR_DDRCAPBEN BIT(6)
39#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7)
40#define RCC_DDRITFCR_AXIDCGEN BIT(8)
41#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9)
42#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10)
43#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20)
44#define RCC_DDRITFCR_GSKPCTRL BIT(24)
45
46#define RCC_MP_SREQSETR 0x104
47#define RCC_MP_SREQCLRR 0x108
48
49#define RCC_MP_CIER 0x414
50#define RCC_MP_CIFR 0x418
51#define RCC_MP_CIFR_WKUPF BIT(20)
52
Marek Vasutd6ae1832022-04-26 16:38:05 +020053#define RCC_MCUDIVR 0x830
54#define RCC_PLL3CR 0x880
55#define RCC_PLL4CR 0x894
56
Marek Vasutb4910532022-02-25 02:15:59 +010057/* SYSCFG */
58#define SYSCFG_CMPCR 0x20
59#define SYSCFG_CMPCR_SW_CTRL BIT(2)
60#define SYSCFG_CMPENSETR 0x24
61#define SYSCFG_CMPENCLRR 0x28
62#define SYSCFG_CMPENR_MPUEN BIT(0)
63
64/* DDR Controller registers offsets */
65#define DDRCTRL_STAT 0x004
66#define DDRCTRL_PWRCTL 0x030
67#define DDRCTRL_PWRTMG 0x034
68#define DDRCTRL_HWLPCTL 0x038
69#define DDRCTRL_DFIMISC 0x1b0
70#define DDRCTRL_SWCTL 0x320
71#define DDRCTRL_SWSTAT 0x324
72#define DDRCTRL_PSTAT 0x3fc
73#define DDRCTRL_PCTRL_0 0x490
74#define DDRCTRL_PCTRL_1 0x540
75
76/* DDR Controller Register fields */
77#define DDRCTRL_STAT_OPERATING_MODE_MASK GENMASK(2, 0)
78#define DDRCTRL_STAT_OPERATING_MODE_NORMAL 0x1
79#define DDRCTRL_STAT_OPERATING_MODE_SR 0x3
80#define DDRCTRL_STAT_SELFREF_TYPE_MASK GENMASK(5, 4)
81#define DDRCTRL_STAT_SELFREF_TYPE_ASR (0x3 << 4)
82#define DDRCTRL_STAT_SELFREF_TYPE_SR (0x2 << 4)
83
84#define DDRCTRL_PWRCTL_SELFREF_EN BIT(0)
85#define DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE BIT(3)
86#define DDRCTRL_PWRCTL_SELFREF_SW BIT(5)
87
88#define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK GENMASK(23, 16)
89#define DDRCTRL_PWRTMG_SELFREF_TO_X32_0 BIT(16)
90
91#define DDRCTRL_HWLPCTL_HW_LP_EN BIT(0)
92
93#define DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN BIT(0)
94
95#define DDRCTRL_SWCTL_SW_DONE BIT(0)
96
97#define DDRCTRL_SWSTAT_SW_DONE_ACK BIT(0)
98
99#define DDRCTRL_PSTAT_RD_PORT_BUSY_0 BIT(0)
100#define DDRCTRL_PSTAT_RD_PORT_BUSY_1 BIT(1)
101#define DDRCTRL_PSTAT_WR_PORT_BUSY_0 BIT(16)
102#define DDRCTRL_PSTAT_WR_PORT_BUSY_1 BIT(17)
103
104#define DDRCTRL_PCTRL_N_PORT_EN BIT(0)
105
106/* DDR PHY registers offsets */
107#define DDRPHYC_PIR 0x004
108#define DDRPHYC_PGSR 0x00c
109#define DDRPHYC_ACDLLCR 0x014
110#define DDRPHYC_ACIOCR 0x024
111#define DDRPHYC_DXCCR 0x028
112#define DDRPHYC_DSGCR 0x02c
113#define DDRPHYC_ZQ0CR0 0x180
114#define DDRPHYC_DX0DLLCR 0x1cc
115#define DDRPHYC_DX1DLLCR 0x20c
116#define DDRPHYC_DX2DLLCR 0x24c
117#define DDRPHYC_DX3DLLCR 0x28c
118
119/* DDR PHY Register fields */
120#define DDRPHYC_PIR_INIT BIT(0)
121#define DDRPHYC_PIR_DLLSRST BIT(1)
122#define DDRPHYC_PIR_DLLLOCK BIT(2)
123#define DDRPHYC_PIR_ITMSRST BIT(4)
124
125#define DDRPHYC_PGSR_IDONE BIT(0)
126
127#define DDRPHYC_ACDLLCR_DLLSRST BIT(30)
128#define DDRPHYC_ACDLLCR_DLLDIS BIT(31)
129
130#define DDRPHYC_ACIOCR_ACOE BIT(1)
131#define DDRPHYC_ACIOCR_ACPDD BIT(3)
132#define DDRPHYC_ACIOCR_ACPDR BIT(4)
133#define DDRPHYC_ACIOCR_CKPDD_MASK GENMASK(10, 8)
134#define DDRPHYC_ACIOCR_CKPDD_0 BIT(8)
135#define DDRPHYC_ACIOCR_CKPDR_MASK GENMASK(13, 11)
136#define DDRPHYC_ACIOCR_CKPDR_0 BIT(11)
137#define DDRPHYC_ACIOCR_CSPDD_MASK GENMASK(20, 18)
138#define DDRPHYC_ACIOCR_CSPDD_0 BIT(18)
139
140#define DDRPHYC_DXCCR_DXPDD BIT(2)
141#define DDRPHYC_DXCCR_DXPDR BIT(3)
142
143#define DDRPHYC_DSGCR_CKEPDD_MASK GENMASK(19, 16)
144#define DDRPHYC_DSGCR_CKEPDD_0 BIT(16)
145#define DDRPHYC_DSGCR_ODTPDD_MASK GENMASK(23, 20)
146#define DDRPHYC_DSGCR_ODTPDD_0 BIT(20)
147#define DDRPHYC_DSGCR_NL2PD BIT(24)
148#define DDRPHYC_DSGCR_CKOE BIT(28)
149
150#define DDRPHYC_ZQ0CRN_ZQPD BIT(31)
151
152#define DDRPHYC_DXNDLLCR_DLLDIS BIT(31)
153
154#define BOOT_API_A7_CORE0_MAGIC_NUMBER 0xca7face0
155#define BOOT_API_A7_CORE1_MAGIC_NUMBER 0xca7face1
156
157#define MPIDR_AFF0 GENMASK(7, 0)
158
159#define RCC_MP_GRSTCSETR (STM32_RCC_BASE + 0x0404)
160#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0)
161#define RCC_MP_GRSTCSETR_MPUP0RST BIT(4)
162#define RCC_MP_GRSTCSETR_MPUP1RST BIT(5)
163
164#define STM32MP1_PSCI_NR_CPUS 2
Patrick Delaunay41c79772018-04-16 10:13:24 +0200165#if STM32MP1_PSCI_NR_CPUS > CONFIG_ARMV7_PSCI_NR_CPUS
166#error "invalid value for CONFIG_ARMV7_PSCI_NR_CPUS"
167#endif
168
169u8 psci_state[STM32MP1_PSCI_NR_CPUS] __secure_data = {
170 PSCI_AFFINITY_LEVEL_ON,
171 PSCI_AFFINITY_LEVEL_OFF};
172
Ludovic Barre40e70ab2020-03-02 11:27:02 +0100173static u32 __secure_data cntfrq;
174
175static u32 __secure cp15_read_cntfrq(void)
176{
177 u32 frq;
178
179 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (frq));
180
181 return frq;
182}
183
184static void __secure cp15_write_cntfrq(u32 frq)
185{
186 asm volatile ("mcr p15, 0, %0, c14, c0, 0" : : "r" (frq));
187}
188
Patrick Delaunaye21e3ff2019-07-22 14:19:20 +0200189static inline void psci_set_state(int cpu, u8 state)
Patrick Delaunay41c79772018-04-16 10:13:24 +0200190{
191 psci_state[cpu] = state;
192 dsb();
193 isb();
194}
195
196static u32 __secure stm32mp_get_gicd_base_address(void)
197{
198 u32 periphbase;
199
200 /* get the GIC base address from the CBAR register */
201 asm("mrc p15, 4, %0, c15, c0, 0\n" : "=r" (periphbase));
202
203 return (periphbase & CBAR_MASK) + GIC_DIST_OFFSET;
204}
205
Patrick Delaunaybb7288e2019-04-18 17:32:40 +0200206static void __secure stm32mp_raise_sgi0(int cpu)
Patrick Delaunay41c79772018-04-16 10:13:24 +0200207{
208 u32 gic_dist_addr;
209
210 gic_dist_addr = stm32mp_get_gicd_base_address();
211
Patrick Delaunaybb7288e2019-04-18 17:32:40 +0200212 /* ask cpu with SGI0 */
213 writel((BIT(cpu) << 16), gic_dist_addr + GICD_SGIR);
Patrick Delaunay41c79772018-04-16 10:13:24 +0200214}
215
216void __secure psci_arch_cpu_entry(void)
217{
218 u32 cpu = psci_get_cpu_id();
219
220 psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON);
Patrick Delaunaybb7288e2019-04-18 17:32:40 +0200221
Ludovic Barre40e70ab2020-03-02 11:27:02 +0100222 /* write the saved cntfrq */
223 cp15_write_cntfrq(cntfrq);
224
Patrick Delaunaybb7288e2019-04-18 17:32:40 +0200225 /* reset magic in TAMP register */
226 writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER);
Patrick Delaunay41c79772018-04-16 10:13:24 +0200227}
228
Patrick Delaunaye21e3ff2019-07-22 14:19:20 +0200229s32 __secure psci_features(u32 function_id, u32 psci_fid)
Patrick Delaunay41c79772018-04-16 10:13:24 +0200230{
231 switch (psci_fid) {
232 case ARM_PSCI_0_2_FN_PSCI_VERSION:
233 case ARM_PSCI_0_2_FN_CPU_OFF:
234 case ARM_PSCI_0_2_FN_CPU_ON:
235 case ARM_PSCI_0_2_FN_AFFINITY_INFO:
236 case ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE:
237 case ARM_PSCI_0_2_FN_SYSTEM_OFF:
238 case ARM_PSCI_0_2_FN_SYSTEM_RESET:
Marek Vasutb4910532022-02-25 02:15:59 +0100239 case ARM_PSCI_1_0_FN_SYSTEM_SUSPEND:
Patrick Delaunay41c79772018-04-16 10:13:24 +0200240 return 0x0;
241 }
242 return ARM_PSCI_RET_NI;
243}
244
Patrick Delaunaye21e3ff2019-07-22 14:19:20 +0200245u32 __secure psci_version(void)
Patrick Delaunay41c79772018-04-16 10:13:24 +0200246{
247 return ARM_PSCI_VER_1_0;
248}
249
Patrick Delaunaye21e3ff2019-07-22 14:19:20 +0200250s32 __secure psci_affinity_info(u32 function_id, u32 target_affinity,
Patrick Delaunay41c79772018-04-16 10:13:24 +0200251 u32 lowest_affinity_level)
252{
253 u32 cpu = target_affinity & MPIDR_AFF0;
254
255 if (lowest_affinity_level > 0)
256 return ARM_PSCI_RET_INVAL;
257
258 if (target_affinity & ~MPIDR_AFF0)
259 return ARM_PSCI_RET_INVAL;
260
261 if (cpu >= STM32MP1_PSCI_NR_CPUS)
262 return ARM_PSCI_RET_INVAL;
263
264 return psci_state[cpu];
265}
266
Patrick Delaunaye21e3ff2019-07-22 14:19:20 +0200267u32 __secure psci_migrate_info_type(void)
Patrick Delaunay41c79772018-04-16 10:13:24 +0200268{
Patrick Delaunayb496eec2019-02-27 17:01:16 +0100269 /*
270 * in Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
271 * return 2 = Trusted OS is either not present or does not require
272 * migration, system of this type does not require the caller
273 * to use the MIGRATE function.
274 * MIGRATE function calls return NOT_SUPPORTED.
275 */
Patrick Delaunay41c79772018-04-16 10:13:24 +0200276 return 2;
277}
278
Patrick Delaunaye21e3ff2019-07-22 14:19:20 +0200279s32 __secure psci_cpu_on(u32 function_id, u32 target_cpu, u32 pc,
Patrick Delaunay41c79772018-04-16 10:13:24 +0200280 u32 context_id)
281{
282 u32 cpu = target_cpu & MPIDR_AFF0;
283
284 if (target_cpu & ~MPIDR_AFF0)
285 return ARM_PSCI_RET_INVAL;
286
287 if (cpu >= STM32MP1_PSCI_NR_CPUS)
288 return ARM_PSCI_RET_INVAL;
289
290 if (psci_state[cpu] == PSCI_AFFINITY_LEVEL_ON)
291 return ARM_PSCI_RET_ALREADY_ON;
292
Ludovic Barre40e70ab2020-03-02 11:27:02 +0100293 /* read and save cntfrq of current cpu to write on target cpu */
294 cntfrq = cp15_read_cntfrq();
295
Patrick Delaunaybb7288e2019-04-18 17:32:40 +0200296 /* reset magic in TAMP register */
297 if (readl(TAMP_BACKUP_MAGIC_NUMBER))
298 writel(0xFFFFFFFF, TAMP_BACKUP_MAGIC_NUMBER);
299 /*
300 * ROM code need a first SGI0 after core reset
301 * core is ready when magic is set to 0 in ROM code
302 */
303 while (readl(TAMP_BACKUP_MAGIC_NUMBER))
304 stm32mp_raise_sgi0(cpu);
305
Patrick Delaunay41c79772018-04-16 10:13:24 +0200306 /* store target PC and context id*/
307 psci_save(cpu, pc, context_id);
308
309 /* write entrypoint in backup RAM register */
310 writel((u32)&psci_cpu_entry, TAMP_BACKUP_BRANCH_ADDRESS);
311 psci_set_state(cpu, PSCI_AFFINITY_LEVEL_ON_PENDING);
312
313 /* write magic number in backup register */
314 if (cpu == 0x01)
315 writel(BOOT_API_A7_CORE1_MAGIC_NUMBER,
316 TAMP_BACKUP_MAGIC_NUMBER);
317 else
318 writel(BOOT_API_A7_CORE0_MAGIC_NUMBER,
319 TAMP_BACKUP_MAGIC_NUMBER);
320
Patrick Delaunaybb7288e2019-04-18 17:32:40 +0200321 /* Generate an IT to start the core */
322 stm32mp_raise_sgi0(cpu);
Patrick Delaunay41c79772018-04-16 10:13:24 +0200323
324 return ARM_PSCI_RET_SUCCESS;
325}
326
Patrick Delaunaye21e3ff2019-07-22 14:19:20 +0200327s32 __secure psci_cpu_off(void)
Patrick Delaunay41c79772018-04-16 10:13:24 +0200328{
329 u32 cpu;
330
331 cpu = psci_get_cpu_id();
332
333 psci_cpu_off_common();
334 psci_set_state(cpu, PSCI_AFFINITY_LEVEL_OFF);
335
336 /* reset core: wfi is managed by BootRom */
337 if (cpu == 0x01)
338 writel(RCC_MP_GRSTCSETR_MPUP1RST, RCC_MP_GRSTCSETR);
339 else
340 writel(RCC_MP_GRSTCSETR_MPUP0RST, RCC_MP_GRSTCSETR);
341
342 /* just waiting reset */
343 while (1)
344 wfi();
345}
346
Patrick Delaunaye21e3ff2019-07-22 14:19:20 +0200347void __secure psci_system_reset(void)
Patrick Delaunay41c79772018-04-16 10:13:24 +0200348{
349 /* System reset */
350 writel(RCC_MP_GRSTCSETR_MPSYSRST, RCC_MP_GRSTCSETR);
351 /* just waiting reset */
352 while (1)
353 wfi();
354}
355
Patrick Delaunaye21e3ff2019-07-22 14:19:20 +0200356void __secure psci_system_off(void)
Patrick Delaunay41c79772018-04-16 10:13:24 +0200357{
358 /* System Off is not managed, waiting user power off
359 * TODO: handle I2C write in PMIC Main Control register bit 0 = SWOFF
360 */
361 while (1)
362 wfi();
363}
Marek Vasutb4910532022-02-25 02:15:59 +0100364
365static void __secure secure_udelay(unsigned int delay)
366{
367 u32 freq = cp15_read_cntfrq() / 1000000;
368 u64 start, end;
369
370 delay *= freq;
371
372 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (start));
373 for (;;) {
374 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (end));
375 if ((end - start) > delay)
376 break;
377 }
378}
379
380static int __secure secure_waitbits(u32 reg, u32 mask, u32 val)
381{
382 u32 freq = cp15_read_cntfrq() / 1000000;
383 u32 delay = 500 * freq; /* 500 us */
384 u64 start, end;
385 u32 tmp;
386
387 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (start));
388 for (;;) {
389 tmp = readl(reg);
390 tmp &= mask;
391 if ((tmp & val) == val)
392 return 0;
393 asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (end));
394 if ((end - start) > delay)
395 return -ETIMEDOUT;
396 }
397}
398
399static void __secure ddr_sr_mode_ssr(u32 *saved_pwrctl)
400{
401 setbits_le32(STM32_RCC_BASE + RCC_DDRITFCR,
402 RCC_DDRITFCR_DDRC1LPEN | RCC_DDRITFCR_DDRC1EN |
403 RCC_DDRITFCR_DDRC2LPEN | RCC_DDRITFCR_DDRC2EN |
404 RCC_DDRITFCR_DDRCAPBLPEN | RCC_DDRITFCR_DDRPHYCAPBLPEN |
405 RCC_DDRITFCR_DDRCAPBEN | RCC_DDRITFCR_DDRPHYCAPBEN |
406 RCC_DDRITFCR_DDRPHYCEN);
407
408 clrbits_le32(STM32_RCC_BASE + RCC_DDRITFCR,
409 RCC_DDRITFCR_AXIDCGEN | RCC_DDRITFCR_DDRCKMOD_MASK);
410
411 /* Disable HW LP interface of uMCTL2 */
412 clrbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_HWLPCTL,
413 DDRCTRL_HWLPCTL_HW_LP_EN);
414
415 /* Configure Automatic LP modes of uMCTL2 */
416 clrsetbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PWRTMG,
417 DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK,
418 DDRCTRL_PWRTMG_SELFREF_TO_X32_0);
419
420 /* Save PWRCTL register to restart ASR after suspend (if applicable) */
421 *saved_pwrctl = readl(STM32_DDRCTRL_BASE + DDRCTRL_PWRCTL);
422
423 /*
424 * Disable Clock disable with LP modes
425 * (used in RUN mode for LPDDR2 with specific timing).
426 */
427 clrbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PWRCTL,
428 DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE);
429
430 /* Disable automatic Self-Refresh mode */
431 clrbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PWRCTL,
432 DDRCTRL_PWRCTL_SELFREF_EN);
433}
434
435static void __secure ddr_sr_mode_restore(u32 saved_pwrctl)
436{
437 saved_pwrctl &= DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE |
438 DDRCTRL_PWRCTL_SELFREF_EN;
439
440 /* Restore ASR mode in case it was enabled before suspend. */
441 setbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PWRCTL, saved_pwrctl);
442}
443
444static int __secure ddr_sw_self_refresh_in(void)
445{
446 int ret;
447
448 clrbits_le32(STM32_RCC_BASE + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN);
449
450 /* Blocks AXI ports from taking anymore transactions */
451 clrbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PCTRL_0,
452 DDRCTRL_PCTRL_N_PORT_EN);
453 clrbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PCTRL_1,
454 DDRCTRL_PCTRL_N_PORT_EN);
455
456 /*
457 * Waits unit all AXI ports are idle
458 * Poll PSTAT.rd_port_busy_n = 0
459 * Poll PSTAT.wr_port_busy_n = 0
460 */
461 ret = secure_waitbits(STM32_DDRCTRL_BASE + DDRCTRL_PSTAT,
462 DDRCTRL_PSTAT_RD_PORT_BUSY_0 |
463 DDRCTRL_PSTAT_RD_PORT_BUSY_1 |
464 DDRCTRL_PSTAT_WR_PORT_BUSY_0 |
465 DDRCTRL_PSTAT_WR_PORT_BUSY_1, 0);
466 if (ret)
467 goto pstat_failed;
468
469 /* SW Self-Refresh entry */
470 setbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_SW);
471
472 /*
473 * Wait operating mode change in self-refresh mode
474 * with STAT.operating_mode[1:0]==11.
475 * Ensure transition to self-refresh was due to software
476 * by checking also that STAT.selfref_type[1:0]=2.
477 */
478 ret = secure_waitbits(STM32_DDRCTRL_BASE + DDRCTRL_STAT,
479 DDRCTRL_STAT_OPERATING_MODE_MASK |
480 DDRCTRL_STAT_SELFREF_TYPE_MASK,
481 DDRCTRL_STAT_OPERATING_MODE_SR |
482 DDRCTRL_STAT_SELFREF_TYPE_SR);
483 if (ret)
484 goto selfref_sw_failed;
485
486 /* IOs powering down (PUBL registers) */
487 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDD);
488 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDR);
489
490 clrsetbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACIOCR,
491 DDRPHYC_ACIOCR_CKPDD_MASK,
492 DDRPHYC_ACIOCR_CKPDD_0);
493
494 clrsetbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACIOCR,
495 DDRPHYC_ACIOCR_CKPDR_MASK,
496 DDRPHYC_ACIOCR_CKPDR_0);
497
498 clrsetbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACIOCR,
499 DDRPHYC_ACIOCR_CSPDD_MASK,
500 DDRPHYC_ACIOCR_CSPDD_0);
501
502 /* Disable command/address output driver */
503 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACOE);
504
505 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDD);
506
507 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDR);
508
509 clrsetbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DSGCR,
510 DDRPHYC_DSGCR_ODTPDD_MASK,
511 DDRPHYC_DSGCR_ODTPDD_0);
512
513 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DSGCR, DDRPHYC_DSGCR_NL2PD);
514
515 clrsetbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DSGCR,
516 DDRPHYC_DSGCR_CKEPDD_MASK,
517 DDRPHYC_DSGCR_CKEPDD_0);
518
519 /* Disable PZQ cell (PUBL register) */
520 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ZQ0CR0, DDRPHYC_ZQ0CRN_ZQPD);
521
522 /* Set latch */
523 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DSGCR, DDRPHYC_DSGCR_CKOE);
524
525 /* Additional delay to avoid early latch */
526 secure_udelay(10);
527
528 /* Activate sw retention in PWRCTRL */
529 setbits_le32(STM32_PWR_BASE + PWR_CR3, PWR_CR3_DDRRETEN);
530
531 /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */
532 setbits_le32(STM32_RCC_BASE + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL);
533
534 /* Disable all DLLs: GLITCH window */
535 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACDLLCR, DDRPHYC_ACDLLCR_DLLDIS);
536
537 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DX0DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
538
539 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DX1DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
540
541 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DX2DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
542
543 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DX3DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
544
545 /* Switch controller clocks (uMCTL2/PUBL) to DLL output clock */
546 clrbits_le32(STM32_RCC_BASE + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL);
547
548 /* Deactivate all DDR clocks */
549 clrbits_le32(STM32_RCC_BASE + RCC_DDRITFCR,
550 RCC_DDRITFCR_DDRC1EN | RCC_DDRITFCR_DDRC2EN |
551 RCC_DDRITFCR_DDRCAPBEN | RCC_DDRITFCR_DDRPHYCAPBEN);
552
553 return 0;
554
555selfref_sw_failed:
556 /* This bit should be cleared to restore DDR in its previous state */
557 clrbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PWRCTL,
558 DDRCTRL_PWRCTL_SELFREF_SW);
559
560pstat_failed:
561 setbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PCTRL_0,
562 DDRCTRL_PCTRL_N_PORT_EN);
563 setbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PCTRL_1,
564 DDRCTRL_PCTRL_N_PORT_EN);
565
566 return -EINVAL;
567};
568
569static void __secure ddr_sw_self_refresh_exit(void)
570{
571 int ret;
572
573 /* Enable all clocks */
574 setbits_le32(STM32_RCC_BASE + RCC_DDRITFCR,
575 RCC_DDRITFCR_DDRC1EN | RCC_DDRITFCR_DDRC2EN |
576 RCC_DDRITFCR_DDRPHYCEN | RCC_DDRITFCR_DDRPHYCAPBEN |
577 RCC_DDRITFCR_DDRCAPBEN);
578
579 /* Handshake */
580 clrbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_SWCTL, DDRCTRL_SWCTL_SW_DONE);
581
582 /* Mask dfi_init_complete_en */
583 clrbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_DFIMISC,
584 DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
585
586 /* Ack */
587 setbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_SWCTL, DDRCTRL_SWCTL_SW_DONE);
588 ret = secure_waitbits(STM32_DDRCTRL_BASE + DDRCTRL_SWSTAT,
589 DDRCTRL_SWSTAT_SW_DONE_ACK,
590 DDRCTRL_SWSTAT_SW_DONE_ACK);
591 if (ret)
592 hang();
593
594 /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */
595 setbits_le32(STM32_RCC_BASE + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL);
596
597 /* Enable all DLLs: GLITCH window */
598 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACDLLCR,
599 DDRPHYC_ACDLLCR_DLLDIS);
600
601 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DX0DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
602
603 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DX1DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
604
605 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DX2DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
606
607 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DX3DLLCR, DDRPHYC_DXNDLLCR_DLLDIS);
608
609 /* Additional delay to avoid early DLL clock switch */
610 secure_udelay(50);
611
612 /* Switch controller clocks (uMCTL2/PUBL) to DLL ref clock */
613 clrbits_le32(STM32_RCC_BASE + RCC_DDRITFCR, RCC_DDRITFCR_GSKPCTRL);
614
615 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACDLLCR, DDRPHYC_ACDLLCR_DLLSRST);
616
617 secure_udelay(10);
618
619 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACDLLCR, DDRPHYC_ACDLLCR_DLLSRST);
620
621 /* PHY partial init: (DLL lock and ITM reset) */
622 writel(DDRPHYC_PIR_DLLSRST | DDRPHYC_PIR_DLLLOCK |
623 DDRPHYC_PIR_ITMSRST | DDRPHYC_PIR_INIT,
624 STM32_DDRPHYC_BASE + DDRPHYC_PIR);
625
626 /* Need to wait at least 10 clock cycles before accessing PGSR */
627 secure_udelay(1);
628
629 /* Pool end of init */
630 ret = secure_waitbits(STM32_DDRPHYC_BASE + DDRPHYC_PGSR,
631 DDRPHYC_PGSR_IDONE, DDRPHYC_PGSR_IDONE);
632 if (ret)
633 hang();
634
635 /* Handshake */
636 clrbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_SWCTL, DDRCTRL_SWCTL_SW_DONE);
637
638 /* Unmask dfi_init_complete_en to uMCTL2 */
639 setbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_DFIMISC, DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
640
641 /* Ack */
642 setbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_SWCTL, DDRCTRL_SWCTL_SW_DONE);
643 ret = secure_waitbits(STM32_DDRCTRL_BASE + DDRCTRL_SWSTAT,
644 DDRCTRL_SWSTAT_SW_DONE_ACK,
645 DDRCTRL_SWSTAT_SW_DONE_ACK);
646 if (ret)
647 hang();
648
649 /* Deactivate sw retention in PWR */
650 clrbits_le32(STM32_PWR_BASE + PWR_CR3, PWR_CR3_DDRRETEN);
651
652 /* Enable PZQ cell (PUBL register) */
653 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ZQ0CR0, DDRPHYC_ZQ0CRN_ZQPD);
654
655 /* Enable pad drivers */
656 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACPDD);
657
658 /* Enable command/address output driver */
659 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_ACOE);
660
661 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_CKPDD_MASK);
662
663 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_ACIOCR, DDRPHYC_ACIOCR_CSPDD_MASK);
664
665 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDD);
666
667 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DXCCR, DDRPHYC_DXCCR_DXPDR);
668
669 /* Release latch */
670 setbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DSGCR, DDRPHYC_DSGCR_CKOE);
671
672 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DSGCR, DDRPHYC_DSGCR_ODTPDD_MASK);
673
674 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DSGCR, DDRPHYC_DSGCR_NL2PD);
675
676 clrbits_le32(STM32_DDRPHYC_BASE + DDRPHYC_DSGCR, DDRPHYC_DSGCR_CKEPDD_MASK);
677
678 /* Remove selfrefresh */
679 clrbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PWRCTL, DDRCTRL_PWRCTL_SELFREF_SW);
680
681 /* Wait operating_mode == normal */
682 ret = secure_waitbits(STM32_DDRCTRL_BASE + DDRCTRL_STAT,
683 DDRCTRL_STAT_OPERATING_MODE_MASK,
684 DDRCTRL_STAT_OPERATING_MODE_NORMAL);
685 if (ret)
686 hang();
687
688 /* AXI ports are no longer blocked from taking transactions */
689 setbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PCTRL_0, DDRCTRL_PCTRL_N_PORT_EN);
690 setbits_le32(STM32_DDRCTRL_BASE + DDRCTRL_PCTRL_1, DDRCTRL_PCTRL_N_PORT_EN);
691
692 setbits_le32(STM32_RCC_BASE + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN);
693}
694
695void __secure psci_system_suspend(u32 __always_unused function_id,
696 u32 ep, u32 context_id)
697{
Marek Vasutd6ae1832022-04-26 16:38:05 +0200698 u32 saved_mcudivr, saved_pll3cr, saved_pll4cr, saved_mssckselr;
Marek Vasutb4910532022-02-25 02:15:59 +0100699 u32 saved_pwrctl, reg;
700
701 /* Disable IO compensation */
702
703 /* Place current APSRC/ANSRC into RAPSRC/RANSRC */
704 reg = readl(STM32_SYSCFG_BASE + SYSCFG_CMPCR);
705 reg >>= 8;
706 reg &= 0xff << 16;
707 reg |= SYSCFG_CMPCR_SW_CTRL;
708 writel(reg, STM32_SYSCFG_BASE + SYSCFG_CMPCR);
709 writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENCLRR);
710
711 writel(RCC_MP_CIFR_WKUPF, STM32_RCC_BASE + RCC_MP_CIFR);
712 setbits_le32(STM32_RCC_BASE + RCC_MP_CIER, RCC_MP_CIFR_WKUPF);
713
714 setbits_le32(STM32_PWR_BASE + PWR_MPUCR,
715 PWR_MPUCR_CSSF | PWR_MPUCR_CSTDBYDIS | PWR_MPUCR_PDDS);
716
Marek Vasutd6ae1832022-04-26 16:38:05 +0200717 saved_mcudivr = readl(STM32_RCC_BASE + RCC_MCUDIVR);
718 saved_pll3cr = readl(STM32_RCC_BASE + RCC_PLL3CR);
719 saved_pll4cr = readl(STM32_RCC_BASE + RCC_PLL4CR);
720 saved_mssckselr = readl(STM32_RCC_BASE + RCC_MSSCKSELR);
721
Marek Vasutb4910532022-02-25 02:15:59 +0100722 psci_v7_flush_dcache_all();
723 ddr_sr_mode_ssr(&saved_pwrctl);
724 ddr_sw_self_refresh_in();
725 setbits_le32(STM32_PWR_BASE + PWR_CR3, PWR_CR3_DDRSREN);
726 writel(0x3, STM32_RCC_BASE + RCC_MP_SREQSETR);
727
728 /* Zzz, enter stop mode */
729 asm volatile(
730 "isb\n"
731 "dsb\n"
732 "wfi\n");
733
734 writel(0x3, STM32_RCC_BASE + RCC_MP_SREQCLRR);
735 ddr_sw_self_refresh_exit();
736 ddr_sr_mode_restore(saved_pwrctl);
737
Marek Vasutd6ae1832022-04-26 16:38:05 +0200738 writel(saved_mcudivr, STM32_RCC_BASE + RCC_MCUDIVR);
739 writel(saved_pll3cr, STM32_RCC_BASE + RCC_PLL3CR);
740 writel(saved_pll4cr, STM32_RCC_BASE + RCC_PLL4CR);
741 writel(saved_mssckselr, STM32_RCC_BASE + RCC_MSSCKSELR);
742
Marek Vasutb4910532022-02-25 02:15:59 +0100743 writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR);
744 clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
745}