a2edec371d55d37cd0fc2eccd197f843db396e3c
[openwrt/openwrt.git] / target / linux / at91 / patches-5.10 / 203-ARM-at91-pm-avoid-push-and-pop-on-stack-while-memory.patch
1 From 892f6d2fb9c42d4ac451236639599f533c37b507 Mon Sep 17 00:00:00 2001
2 From: Claudiu Beznea <claudiu.beznea@microchip.com>
3 Date: Thu, 15 Apr 2021 13:49:53 +0300
4 Subject: [PATCH 203/247] ARM: at91: pm: avoid push and pop on stack while
5 memory is in self-refersh
6
7 For the previous AT91 RAM controller and self-refresh procedure this
8 had no side effects. However, for SAMA7G5 the self-refresh procedure
9 doesn't allow this anymore as the RAM controller ports are closed
10 before switching it to self-refresh. This commits prepares the code
11 for the following ones adding self-refresh and PM support for SAMA7G5.
12
13 Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
14 Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
15 Link: https://lore.kernel.org/r/20210415105010.569620-8-claudiu.beznea@microchip.com
16 ---
17 arch/arm/mach-at91/pm_suspend.S | 397 +++++++++++++++++---------------
18 1 file changed, 205 insertions(+), 192 deletions(-)
19
20 --- a/arch/arm/mach-at91/pm_suspend.S
21 +++ b/arch/arm/mach-at91/pm_suspend.S
22 @@ -75,98 +75,147 @@ tmp3 .req r6
23
24 .arm
25
26 -/*
27 - * void at91_suspend_sram_fn(struct at91_pm_data*)
28 - * @input param:
29 - * @r0: base address of struct at91_pm_data
30 +/**
31 + * Enable self-refresh
32 + *
33 + * register usage:
34 + * @r1: memory type
35 + * @r2: base address of the sram controller
36 + * @r3: temporary
37 */
38 -/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
39 - .align 3
40 -ENTRY(at91_pm_suspend_in_sram)
41 - /* Save registers on stack */
42 - stmfd sp!, {r4 - r12, lr}
43 +.macro at91_sramc_self_refresh_ena
44 + ldr r1, .memtype
45 + ldr r2, .sramc_base
46
47 - /* Drain write buffer */
48 - mov tmp1, #0
49 - mcr p15, 0, tmp1, c7, c10, 4
50 + cmp r1, #AT91_MEMCTRL_MC
51 + bne sr_ena_ddrc_sf
52
53 - ldr tmp1, [r0, #PM_DATA_PMC]
54 - str tmp1, .pmc_base
55 - ldr tmp1, [r0, #PM_DATA_RAMC0]
56 - str tmp1, .sramc_base
57 - ldr tmp1, [r0, #PM_DATA_RAMC1]
58 - str tmp1, .sramc1_base
59 - ldr tmp1, [r0, #PM_DATA_MEMCTRL]
60 - str tmp1, .memtype
61 - ldr tmp1, [r0, #PM_DATA_MODE]
62 - str tmp1, .pm_mode
63 - ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
64 - str tmp1, .mckr_offset
65 - ldr tmp1, [r0, #PM_DATA_PMC_VERSION]
66 - str tmp1, .pmc_version
67 - /* Both ldrne below are here to preload their address in the TLB */
68 - ldr tmp1, [r0, #PM_DATA_SHDWC]
69 - str tmp1, .shdwc
70 - cmp tmp1, #0
71 - ldrne tmp2, [tmp1, #0]
72 - ldr tmp1, [r0, #PM_DATA_SFRBU]
73 - str tmp1, .sfrbu
74 - cmp tmp1, #0
75 - ldrne tmp2, [tmp1, #0x10]
76 + /* Active SDRAM self-refresh mode */
77 + mov r3, #1
78 + str r3, [r2, #AT91_MC_SDRAMC_SRR]
79 + b sr_ena_exit
80
81 - /* Active the self-refresh mode */
82 - mov r0, #SRAMC_SELF_FRESH_ACTIVE
83 - bl at91_sramc_self_refresh
84 +sr_ena_ddrc_sf:
85 + cmp r1, #AT91_MEMCTRL_DDRSDR
86 + bne sr_ena_sdramc_sf
87
88 - ldr r0, .pm_mode
89 - cmp r0, #AT91_PM_STANDBY
90 - beq standby
91 - cmp r0, #AT91_PM_BACKUP
92 - beq backup_mode
93 + /*
94 + * DDR Memory controller
95 + */
96
97 - bl at91_ulp_mode
98 - b exit_suspend
99 + /* LPDDR1 --> force DDR2 mode during self-refresh */
100 + ldr r3, [r2, #AT91_DDRSDRC_MDR]
101 + str r3, .saved_sam9_mdr
102 + bic r3, r3, #~AT91_DDRSDRC_MD
103 + cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
104 + ldreq r3, [r2, #AT91_DDRSDRC_MDR]
105 + biceq r3, r3, #AT91_DDRSDRC_MD
106 + orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
107 + streq r3, [r2, #AT91_DDRSDRC_MDR]
108
109 -standby:
110 - /* Wait for interrupt */
111 - ldr pmc, .pmc_base
112 - at91_cpu_idle
113 - b exit_suspend
114 + /* Active DDRC self-refresh mode */
115 + ldr r3, [r2, #AT91_DDRSDRC_LPR]
116 + str r3, .saved_sam9_lpr
117 + bic r3, r3, #AT91_DDRSDRC_LPCB
118 + orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
119 + str r3, [r2, #AT91_DDRSDRC_LPR]
120
121 -backup_mode:
122 - bl at91_backup_mode
123 - b exit_suspend
124 + /* If using the 2nd ddr controller */
125 + ldr r2, .sramc1_base
126 + cmp r2, #0
127 + beq sr_ena_no_2nd_ddrc
128
129 -exit_suspend:
130 - /* Exit the self-refresh mode */
131 - mov r0, #SRAMC_SELF_FRESH_EXIT
132 - bl at91_sramc_self_refresh
133 + ldr r3, [r2, #AT91_DDRSDRC_MDR]
134 + str r3, .saved_sam9_mdr1
135 + bic r3, r3, #~AT91_DDRSDRC_MD
136 + cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
137 + ldreq r3, [r2, #AT91_DDRSDRC_MDR]
138 + biceq r3, r3, #AT91_DDRSDRC_MD
139 + orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
140 + streq r3, [r2, #AT91_DDRSDRC_MDR]
141
142 - /* Restore registers, and return */
143 - ldmfd sp!, {r4 - r12, pc}
144 -ENDPROC(at91_pm_suspend_in_sram)
145 + /* Active DDRC self-refresh mode */
146 + ldr r3, [r2, #AT91_DDRSDRC_LPR]
147 + str r3, .saved_sam9_lpr1
148 + bic r3, r3, #AT91_DDRSDRC_LPCB
149 + orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
150 + str r3, [r2, #AT91_DDRSDRC_LPR]
151
152 -ENTRY(at91_backup_mode)
153 - /* Switch the master clock source to slow clock. */
154 - ldr pmc, .pmc_base
155 - ldr tmp2, .mckr_offset
156 - ldr tmp1, [pmc, tmp2]
157 - bic tmp1, tmp1, #AT91_PMC_CSS
158 - str tmp1, [pmc, tmp2]
159 +sr_ena_no_2nd_ddrc:
160 + b sr_ena_exit
161
162 - wait_mckrdy
163 + /*
164 + * SDRAMC Memory controller
165 + */
166 +sr_ena_sdramc_sf:
167 + /* Active SDRAMC self-refresh mode */
168 + ldr r3, [r2, #AT91_SDRAMC_LPR]
169 + str r3, .saved_sam9_lpr
170 + bic r3, r3, #AT91_SDRAMC_LPCB
171 + orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
172 + str r3, [r2, #AT91_SDRAMC_LPR]
173
174 - /*BUMEN*/
175 - ldr r0, .sfrbu
176 - mov tmp1, #0x1
177 - str tmp1, [r0, #0x10]
178 + ldr r3, .saved_sam9_lpr
179 + str r3, [r2, #AT91_SDRAMC_LPR]
180
181 - /* Shutdown */
182 - ldr r0, .shdwc
183 - mov tmp1, #0xA5000000
184 - add tmp1, tmp1, #0x1
185 - str tmp1, [r0, #0]
186 -ENDPROC(at91_backup_mode)
187 +sr_ena_exit:
188 +.endm
189 +
190 +/**
191 + * Disable self-refresh
192 + *
193 + * register usage:
194 + * @r1: memory type
195 + * @r2: base address of the sram controller
196 + * @r3: temporary
197 + */
198 +.macro at91_sramc_self_refresh_dis
199 + ldr r1, .memtype
200 + ldr r2, .sramc_base
201 +
202 + cmp r1, #AT91_MEMCTRL_MC
203 + bne sr_dis_ddrc_exit_sf
204 +
205 + /*
206 + * at91rm9200 Memory controller
207 + */
208 +
209 + /*
210 + * For exiting the self-refresh mode, do nothing,
211 + * automatically exit the self-refresh mode.
212 + */
213 + b sr_dis_exit
214 +
215 +sr_dis_ddrc_exit_sf:
216 + cmp r1, #AT91_MEMCTRL_DDRSDR
217 + bne sdramc_exit_sf
218 +
219 + /* DDR Memory controller */
220 +
221 + /* Restore MDR in case of LPDDR1 */
222 + ldr r3, .saved_sam9_mdr
223 + str r3, [r2, #AT91_DDRSDRC_MDR]
224 + /* Restore LPR on AT91 with DDRAM */
225 + ldr r3, .saved_sam9_lpr
226 + str r3, [r2, #AT91_DDRSDRC_LPR]
227 +
228 + /* If using the 2nd ddr controller */
229 + ldr r2, .sramc1_base
230 + cmp r2, #0
231 + ldrne r3, .saved_sam9_mdr1
232 + strne r3, [r2, #AT91_DDRSDRC_MDR]
233 + ldrne r3, .saved_sam9_lpr1
234 + strne r3, [r2, #AT91_DDRSDRC_LPR]
235 +
236 + b sr_dis_exit
237 +
238 +sdramc_exit_sf:
239 + /* SDRAMC Memory controller */
240 + ldr r3, .saved_sam9_lpr
241 + str r3, [r2, #AT91_SDRAMC_LPR]
242 +
243 +sr_dis_exit:
244 +.endm
245
246 .macro at91_pm_ulp0_mode
247 ldr pmc, .pmc_base
248 @@ -503,7 +552,7 @@ ENDPROC(at91_backup_mode)
249 2:
250 .endm
251
252 -ENTRY(at91_ulp_mode)
253 +.macro at91_ulp_mode
254 ldr pmc, .pmc_base
255 ldr tmp2, .mckr_offset
256 ldr tmp3, .pm_mode
257 @@ -552,133 +601,97 @@ ulp_exit:
258
259 wait_mckrdy
260
261 - mov pc, lr
262 -ENDPROC(at91_ulp_mode)
263 -
264 -/*
265 - * void at91_sramc_self_refresh(unsigned int is_active)
266 - *
267 - * @input param:
268 - * @r0: 1 - active self-refresh mode
269 - * 0 - exit self-refresh mode
270 - * register usage:
271 - * @r1: memory type
272 - * @r2: base address of the sram controller
273 - */
274 -
275 -ENTRY(at91_sramc_self_refresh)
276 - ldr r1, .memtype
277 - ldr r2, .sramc_base
278 -
279 - cmp r1, #AT91_MEMCTRL_MC
280 - bne ddrc_sf
281 -
282 - /*
283 - * at91rm9200 Memory controller
284 - */
285 -
286 - /*
287 - * For exiting the self-refresh mode, do nothing,
288 - * automatically exit the self-refresh mode.
289 - */
290 - tst r0, #SRAMC_SELF_FRESH_ACTIVE
291 - beq exit_sramc_sf
292 -
293 - /* Active SDRAM self-refresh mode */
294 - mov r3, #1
295 - str r3, [r2, #AT91_MC_SDRAMC_SRR]
296 - b exit_sramc_sf
297 -
298 -ddrc_sf:
299 - cmp r1, #AT91_MEMCTRL_DDRSDR
300 - bne sdramc_sf
301 +.endm
302
303 - /*
304 - * DDR Memory controller
305 - */
306 - tst r0, #SRAMC_SELF_FRESH_ACTIVE
307 - beq ddrc_exit_sf
308 +.macro at91_backup_mode
309 + /* Switch the master clock source to slow clock. */
310 + ldr pmc, .pmc_base
311 + ldr tmp2, .mckr_offset
312 + ldr tmp1, [pmc, tmp2]
313 + bic tmp1, tmp1, #AT91_PMC_CSS
314 + str tmp1, [pmc, tmp2]
315
316 - /* LPDDR1 --> force DDR2 mode during self-refresh */
317 - ldr r3, [r2, #AT91_DDRSDRC_MDR]
318 - str r3, .saved_sam9_mdr
319 - bic r3, r3, #~AT91_DDRSDRC_MD
320 - cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
321 - ldreq r3, [r2, #AT91_DDRSDRC_MDR]
322 - biceq r3, r3, #AT91_DDRSDRC_MD
323 - orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
324 - streq r3, [r2, #AT91_DDRSDRC_MDR]
325 + wait_mckrdy
326
327 - /* Active DDRC self-refresh mode */
328 - ldr r3, [r2, #AT91_DDRSDRC_LPR]
329 - str r3, .saved_sam9_lpr
330 - bic r3, r3, #AT91_DDRSDRC_LPCB
331 - orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
332 - str r3, [r2, #AT91_DDRSDRC_LPR]
333 + /*BUMEN*/
334 + ldr r0, .sfrbu
335 + mov tmp1, #0x1
336 + str tmp1, [r0, #0x10]
337
338 - /* If using the 2nd ddr controller */
339 - ldr r2, .sramc1_base
340 - cmp r2, #0
341 - beq no_2nd_ddrc
342 + /* Shutdown */
343 + ldr r0, .shdwc
344 + mov tmp1, #0xA5000000
345 + add tmp1, tmp1, #0x1
346 + str tmp1, [r0, #0]
347 +.endm
348
349 - ldr r3, [r2, #AT91_DDRSDRC_MDR]
350 - str r3, .saved_sam9_mdr1
351 - bic r3, r3, #~AT91_DDRSDRC_MD
352 - cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
353 - ldreq r3, [r2, #AT91_DDRSDRC_MDR]
354 - biceq r3, r3, #AT91_DDRSDRC_MD
355 - orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
356 - streq r3, [r2, #AT91_DDRSDRC_MDR]
357 +/*
358 + * void at91_suspend_sram_fn(struct at91_pm_data*)
359 + * @input param:
360 + * @r0: base address of struct at91_pm_data
361 + */
362 +/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
363 + .align 3
364 +ENTRY(at91_pm_suspend_in_sram)
365 + /* Save registers on stack */
366 + stmfd sp!, {r4 - r12, lr}
367
368 - /* Active DDRC self-refresh mode */
369 - ldr r3, [r2, #AT91_DDRSDRC_LPR]
370 - str r3, .saved_sam9_lpr1
371 - bic r3, r3, #AT91_DDRSDRC_LPCB
372 - orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
373 - str r3, [r2, #AT91_DDRSDRC_LPR]
374 + /* Drain write buffer */
375 + mov tmp1, #0
376 + mcr p15, 0, tmp1, c7, c10, 4
377
378 -no_2nd_ddrc:
379 - b exit_sramc_sf
380 + ldr tmp1, [r0, #PM_DATA_PMC]
381 + str tmp1, .pmc_base
382 + ldr tmp1, [r0, #PM_DATA_RAMC0]
383 + str tmp1, .sramc_base
384 + ldr tmp1, [r0, #PM_DATA_RAMC1]
385 + str tmp1, .sramc1_base
386 + ldr tmp1, [r0, #PM_DATA_MEMCTRL]
387 + str tmp1, .memtype
388 + ldr tmp1, [r0, #PM_DATA_MODE]
389 + str tmp1, .pm_mode
390 + ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET]
391 + str tmp1, .mckr_offset
392 + ldr tmp1, [r0, #PM_DATA_PMC_VERSION]
393 + str tmp1, .pmc_version
394 + /* Both ldrne below are here to preload their address in the TLB */
395 + ldr tmp1, [r0, #PM_DATA_SHDWC]
396 + str tmp1, .shdwc
397 + cmp tmp1, #0
398 + ldrne tmp2, [tmp1, #0]
399 + ldr tmp1, [r0, #PM_DATA_SFRBU]
400 + str tmp1, .sfrbu
401 + cmp tmp1, #0
402 + ldrne tmp2, [tmp1, #0x10]
403
404 -ddrc_exit_sf:
405 - /* Restore MDR in case of LPDDR1 */
406 - ldr r3, .saved_sam9_mdr
407 - str r3, [r2, #AT91_DDRSDRC_MDR]
408 - /* Restore LPR on AT91 with DDRAM */
409 - ldr r3, .saved_sam9_lpr
410 - str r3, [r2, #AT91_DDRSDRC_LPR]
411 + /* Active the self-refresh mode */
412 + at91_sramc_self_refresh_ena
413
414 - /* If using the 2nd ddr controller */
415 - ldr r2, .sramc1_base
416 - cmp r2, #0
417 - ldrne r3, .saved_sam9_mdr1
418 - strne r3, [r2, #AT91_DDRSDRC_MDR]
419 - ldrne r3, .saved_sam9_lpr1
420 - strne r3, [r2, #AT91_DDRSDRC_LPR]
421 + ldr r0, .pm_mode
422 + cmp r0, #AT91_PM_STANDBY
423 + beq standby
424 + cmp r0, #AT91_PM_BACKUP
425 + beq backup_mode
426
427 - b exit_sramc_sf
428 + at91_ulp_mode
429 + b exit_suspend
430
431 - /*
432 - * SDRAMC Memory controller
433 - */
434 -sdramc_sf:
435 - tst r0, #SRAMC_SELF_FRESH_ACTIVE
436 - beq sdramc_exit_sf
437 +standby:
438 + /* Wait for interrupt */
439 + ldr pmc, .pmc_base
440 + at91_cpu_idle
441 + b exit_suspend
442
443 - /* Active SDRAMC self-refresh mode */
444 - ldr r3, [r2, #AT91_SDRAMC_LPR]
445 - str r3, .saved_sam9_lpr
446 - bic r3, r3, #AT91_SDRAMC_LPCB
447 - orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
448 - str r3, [r2, #AT91_SDRAMC_LPR]
449 +backup_mode:
450 + at91_backup_mode
451
452 -sdramc_exit_sf:
453 - ldr r3, .saved_sam9_lpr
454 - str r3, [r2, #AT91_SDRAMC_LPR]
455 +exit_suspend:
456 + /* Exit the self-refresh mode */
457 + at91_sramc_self_refresh_dis
458
459 -exit_sramc_sf:
460 - mov pc, lr
461 -ENDPROC(at91_sramc_self_refresh)
462 + /* Restore registers, and return */
463 + ldmfd sp!, {r4 - r12, pc}
464 +ENDPROC(at91_pm_suspend_in_sram)
465
466 .pmc_base:
467 .word 0