1/* SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) */ 2/* 3 * This file was imported from Linux arch/arm/mach-at91/pm_suspend.S and 4 * relicensed with dual GPL-2.0/BSD-2-Clause with Microchip agreement. 5 * 6 * Copyright (c) 2021, Microchip 7 */ 8 9#include <arm.h> 10#include <arm32_macros.S> 11#include <asm.S> 12#include <at91_pmc.h> 13#include <drivers/sam/at91_ddr.h> 14#include <generated/pm-defines.h> 15 16#include "at91_pm.h" 17 18#define SRAMC_SELF_FRESH_ACTIVE 0x01 19#define SRAMC_SELF_FRESH_EXIT 0x00 20 21pmc .req r0 22tmp1 .req r4 23tmp2 .req r5 24tmp3 .req r6 25 26/* 27 * Wait until master clock is ready (after switching master clock source) 28 */ 29.macro wait_mckrdy 301: ldr tmp1, [pmc, #AT91_PMC_SR] 31 tst tmp1, #AT91_PMC_MCKRDY 32 beq 1b 33.endm 34 35/* 36 * Wait until master oscillator has stabilized. 37 */ 38.macro wait_moscrdy 391: ldr tmp1, [pmc, #AT91_PMC_SR] 40 tst tmp1, #AT91_PMC_MOSCS 41 beq 1b 42.endm 43 44/* 45 * Wait for main oscillator selection is done 46 */ 47.macro wait_moscsels 481: ldr tmp1, [pmc, #AT91_PMC_SR] 49 tst tmp1, #AT91_PMC_MOSCSELS 50 beq 1b 51.endm 52 53/* 54 * Put the processor to enter the idle state 55 */ 56.macro at91_cpu_idle 57 58 mov tmp1, #AT91_PMC_PCK 59 str tmp1, [pmc, #AT91_PMC_SCDR] 60 61 dsb 62 63 wfi @ Wait For Interrupt 64 65.endm 66 67.section .text.psci.suspend 68 69.arm 70 71 72#define SUSPEND_FUNC(__name) \ 73__name: 74 75#define SUSPEND_END_FUNC(__name) \ 76 .size __name, .-__name 77 78.macro check_fit_in_sram since 79 .if (. - \since) > 0x10000 80 .error "Suspend assembly code exceeds dedicated SRAM size" 81 .endif 82.endm 83 84/* 85 * void at91_suspend_sram_fn(struct at91_pm_data*) 86 * @input param: 87 * @r0: base address of struct at91_pm_data 88 */ 89.align 3 90.global at91_pm_suspend_in_sram 91SUSPEND_FUNC(at91_pm_suspend_in_sram) 92 /* Save registers on stack */ 93 stmfd sp!, {r4 - r12, lr} 94 95 /* Drain write buffer */ 96 mov tmp1, #0 97 mcr p15, 0, tmp1, c7, c10, 4 98 99 ldr tmp1, [r0, #PM_DATA_PMC] 100 str tmp1, .pmc_base 101 ldr tmp1, [r0, #PM_DATA_RAMC0] 102 str tmp1, .sramc_base 103 ldr tmp1, [r0, #PM_DATA_MODE] 104 str tmp1, .pm_mode 105 /* Both ldrne below are here to preload their address in the TLB */ 106 ldr tmp1, [r0, #PM_DATA_SHDWC] 107 str tmp1, .shdwc 108 cmp tmp1, #0 109 ldrne tmp2, [tmp1, #0] 110 ldr tmp1, [r0, #PM_DATA_SFRBU] 111 str tmp1, .sfrbu 112 cmp tmp1, #0 113 ldrne tmp2, [tmp1, #0x10] 114 115 /* Active the self-refresh mode */ 116 mov r0, #SRAMC_SELF_FRESH_ACTIVE 117 bl at91_sramc_self_refresh 118 119 ldr r0, .pm_mode 120 cmp r0, #AT91_PM_STANDBY 121 beq standby 122 cmp r0, #AT91_PM_BACKUP 123 beq backup_mode 124 125 bl at91_ulp_mode 126 b exit_suspend 127 128standby: 129 /* Wait for interrupt */ 130 ldr pmc, .pmc_base 131 at91_cpu_idle 132 b exit_suspend 133 134backup_mode: 135 bl at91_backup_mode 136 b exit_suspend 137 138exit_suspend: 139 /* Exit the self-refresh mode */ 140 mov r0, #SRAMC_SELF_FRESH_EXIT 141 bl at91_sramc_self_refresh 142 143 /* Restore registers, and return */ 144 ldmfd sp!, {r4 - r12, pc} 145SUSPEND_END_FUNC(at91_pm_suspend_in_sram) 146 147SUSPEND_FUNC(at91_backup_mode) 148 /* Switch the master clock source to slow clock. */ 149 ldr pmc, .pmc_base 150 ldr tmp1, [pmc, #AT91_PMC_MCKR] 151 bic tmp1, tmp1, #AT91_PMC_CSS 152 str tmp1, [pmc, #AT91_PMC_MCKR] 153 154 wait_mckrdy 155 156 /*BUMEN*/ 157 ldr r0, .sfrbu 158 mov tmp1, #0x1 159 str tmp1, [r0, #0x10] 160 161 /* Shutdown */ 162 ldr r0, .shdwc 163 mov tmp1, #0xA5000000 164 add tmp1, tmp1, #0x1 165 str tmp1, [r0, #0] 166SUSPEND_END_FUNC(at91_backup_mode) 167 168.macro at91_pm_ulp0_mode 169 ldr pmc, .pmc_base 170 ldr tmp2, .pm_mode 171 172 /* Check if ULP0 fast variant has been requested. */ 173 cmp tmp2, #AT91_PM_ULP0_FAST 174 bne 0f 175 176 /* Set highest prescaler for power saving */ 177 ldr tmp1, [pmc, #AT91_PMC_MCKR] 178 bic tmp1, tmp1, #AT91_PMC_PRES 179 orr tmp1, tmp1, #AT91_PMC_PRES_64 180 str tmp1, [pmc, #AT91_PMC_MCKR] 181 wait_mckrdy 182 b 1f 183 1840: 185 /* Turn off the crystal oscillator */ 186 ldr tmp1, [pmc, #AT91_CKGR_MOR] 187 bic tmp1, tmp1, #AT91_PMC_MOSCEN 188 orr tmp1, tmp1, #AT91_PMC_KEY 189 str tmp1, [pmc, #AT91_CKGR_MOR] 190 191 /* Save RC oscillator state */ 192 ldr tmp1, [pmc, #AT91_PMC_SR] 193 str tmp1, .saved_osc_status 194 tst tmp1, #AT91_PMC_MOSCRCS 195 bne 1f 196 197 /* Turn off RC oscillator */ 198 ldr tmp1, [pmc, #AT91_CKGR_MOR] 199 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 200 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 201 orr tmp1, tmp1, #AT91_PMC_KEY 202 str tmp1, [pmc, #AT91_CKGR_MOR] 203 204 /* Wait main RC disabled done */ 2052: ldr tmp1, [pmc, #AT91_PMC_SR] 206 tst tmp1, #AT91_PMC_MOSCRCS 207 bne 2b 208 209 /* Wait for interrupt */ 2101: at91_cpu_idle 211 212 /* Check if ULP0 fast variant has been requested. */ 213 cmp tmp2, #AT91_PM_ULP0_FAST 214 bne 5f 215 216 /* Set lowest prescaler for fast resume. */ 217 ldr tmp1, [pmc, #AT91_PMC_MCKR] 218 bic tmp1, tmp1, #AT91_PMC_PRES 219 str tmp1, [pmc, #AT91_PMC_MCKR] 220 wait_mckrdy 221 b 6f 222 2235: /* Restore RC oscillator state */ 224 ldr tmp1, .saved_osc_status 225 tst tmp1, #AT91_PMC_MOSCRCS 226 beq 4f 227 228 /* Turn on RC oscillator */ 229 ldr tmp1, [pmc, #AT91_CKGR_MOR] 230 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 231 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 232 orr tmp1, tmp1, #AT91_PMC_KEY 233 str tmp1, [pmc, #AT91_CKGR_MOR] 234 235 /* Wait main RC stabilization */ 2363: ldr tmp1, [pmc, #AT91_PMC_SR] 237 tst tmp1, #AT91_PMC_MOSCRCS 238 beq 3b 239 240 /* Turn on the crystal oscillator */ 2414: ldr tmp1, [pmc, #AT91_CKGR_MOR] 242 orr tmp1, tmp1, #AT91_PMC_MOSCEN 243 orr tmp1, tmp1, #AT91_PMC_KEY 244 str tmp1, [pmc, #AT91_CKGR_MOR] 245 246 wait_moscrdy 2476: 248.endm 249 250/** 251 * Note: This procedure only applies on the platform which uses 252 * the external crystal oscillator as a main clock source. 253 */ 254.macro at91_pm_ulp1_mode 255 ldr pmc, .pmc_base 256 257 /* Save RC oscillator state and check if it is enabled. */ 258 ldr tmp1, [pmc, #AT91_PMC_SR] 259 str tmp1, .saved_osc_status 260 tst tmp1, #AT91_PMC_MOSCRCS 261 bne 2f 262 263 /* Enable RC oscillator */ 264 ldr tmp1, [pmc, #AT91_CKGR_MOR] 265 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 266 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 267 orr tmp1, tmp1, #AT91_PMC_KEY 268 str tmp1, [pmc, #AT91_CKGR_MOR] 269 270 /* Wait main RC stabilization */ 2711: ldr tmp1, [pmc, #AT91_PMC_SR] 272 tst tmp1, #AT91_PMC_MOSCRCS 273 beq 1b 274 275 /* Switch the main clock source to 12-MHz RC oscillator */ 2762: ldr tmp1, [pmc, #AT91_CKGR_MOR] 277 bic tmp1, tmp1, #AT91_PMC_MOSCSEL 278 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 279 orr tmp1, tmp1, #AT91_PMC_KEY 280 str tmp1, [pmc, #AT91_CKGR_MOR] 281 282 wait_moscsels 283 284 /* Disable the crystal oscillator */ 285 ldr tmp1, [pmc, #AT91_CKGR_MOR] 286 bic tmp1, tmp1, #AT91_PMC_MOSCEN 287 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 288 orr tmp1, tmp1, #AT91_PMC_KEY 289 str tmp1, [pmc, #AT91_CKGR_MOR] 290 291 /* Switch the master clock source to main clock */ 292 ldr tmp1, [pmc, #AT91_PMC_MCKR] 293 bic tmp1, tmp1, #AT91_PMC_CSS 294 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 295 str tmp1, [pmc, #AT91_PMC_MCKR] 296 297 wait_mckrdy 298 299 /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */ 300 ldr tmp1, [pmc, #AT91_CKGR_MOR] 301 orr tmp1, tmp1, #AT91_PMC_WAITMODE 302 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 303 orr tmp1, tmp1, #AT91_PMC_KEY 304 str tmp1, [pmc, #AT91_CKGR_MOR] 305 306 /* Quirk for SAM9X60's PMC */ 307 nop 308 nop 309 310 wait_mckrdy 311 312 /* Enable the crystal oscillator */ 313 ldr tmp1, [pmc, #AT91_CKGR_MOR] 314 orr tmp1, tmp1, #AT91_PMC_MOSCEN 315 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 316 orr tmp1, tmp1, #AT91_PMC_KEY 317 str tmp1, [pmc, #AT91_CKGR_MOR] 318 319 wait_moscrdy 320 321 /* Switch the master clock source to slow clock */ 322 ldr tmp1, [pmc, #AT91_PMC_MCKR] 323 bic tmp1, tmp1, #AT91_PMC_CSS 324 str tmp1, [pmc, #AT91_PMC_MCKR] 325 326 wait_mckrdy 327 328 /* Switch main clock source to crystal oscillator */ 329 ldr tmp1, [pmc, #AT91_CKGR_MOR] 330 orr tmp1, tmp1, #AT91_PMC_MOSCSEL 331 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 332 orr tmp1, tmp1, #AT91_PMC_KEY 333 str tmp1, [pmc, #AT91_CKGR_MOR] 334 335 wait_moscsels 336 337 /* Switch the master clock source to main clock */ 338 ldr tmp1, [pmc, #AT91_PMC_MCKR] 339 bic tmp1, tmp1, #AT91_PMC_CSS 340 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 341 str tmp1, [pmc, #AT91_PMC_MCKR] 342 343 wait_mckrdy 344 345 /* Restore RC oscillator state */ 346 ldr tmp1, .saved_osc_status 347 tst tmp1, #AT91_PMC_MOSCRCS 348 bne 3f 349 350 /* Disable RC oscillator */ 351 ldr tmp1, [pmc, #AT91_CKGR_MOR] 352 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 353 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 354 orr tmp1, tmp1, #AT91_PMC_KEY 355 str tmp1, [pmc, #AT91_CKGR_MOR] 356 357 /* Wait RC oscillator disable done */ 3584: ldr tmp1, [pmc, #AT91_PMC_SR] 359 tst tmp1, #AT91_PMC_MOSCRCS 360 bne 4b 361 3623: 363.endm 364 365.macro at91_plla_disable 366 /* Save PLLA setting and disable it */ 367 ldr tmp1, [pmc, #AT91_CKGR_PLLAR] 368 str tmp1, .saved_pllar 369 370 /* Disable PLLA. */ 371 mov tmp1, #AT91_PMC_PLLCOUNT 372 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ 373 str tmp1, [pmc, #AT91_CKGR_PLLAR] 3742: 375.endm 376 377.macro at91_plla_enable 378 ldr tmp2, .saved_pllar 379 380 /* Restore PLLA setting */ 381 str tmp2, [pmc, #AT91_CKGR_PLLAR] 382 383 /* Enable PLLA. */ 384 tst tmp2, #(AT91_PMC_MUL & 0xff0000) 385 bne 1f 386 tst tmp2, #(AT91_PMC_MUL & ~0xff0000) 387 beq 2f 388 3891: ldr tmp1, [pmc, #AT91_PMC_SR] 390 tst tmp1, #AT91_PMC_LOCKA 391 beq 1b 3922: 393.endm 394 395SUSPEND_FUNC(at91_ulp_mode) 396 ldr pmc, .pmc_base 397 ldr tmp3, .pm_mode 398 399 /* Save Master clock setting */ 400 ldr tmp1, [pmc, #AT91_PMC_MCKR] 401 str tmp1, .saved_mckr 402 403 /* 404 * Set master clock source to: 405 * - MAINCK if using ULP0 fast variant 406 * - slow clock, otherwise 407 */ 408 bic tmp1, tmp1, #AT91_PMC_CSS 409 cmp tmp3, #AT91_PM_ULP0_FAST 410 bne save_mck 411 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 412save_mck: 413 str tmp1, [pmc, #AT91_PMC_MCKR] 414 415 wait_mckrdy 416 417 at91_plla_disable 418 419 cmp tmp3, #AT91_PM_ULP1 420 beq ulp1_mode 421 422 at91_pm_ulp0_mode 423 b ulp_exit 424 425ulp1_mode: 426 at91_pm_ulp1_mode 427 b ulp_exit 428 429ulp_exit: 430 ldr pmc, .pmc_base 431 432 at91_plla_enable 433 434 /* 435 * Restore master clock setting 436 */ 437 ldr tmp2, .saved_mckr 438 str tmp2, [pmc, #AT91_PMC_MCKR] 439 440 wait_mckrdy 441 442 mov pc, lr 443SUSPEND_END_FUNC(at91_ulp_mode) 444 445/* 446 * void at91_sramc_self_refresh(unsigned int is_active) 447 * 448 * @input param: 449 * @r0: 1 - active self-refresh mode 450 * 0 - exit self-refresh mode 451 * register usage: 452 * @r2: base address of the sram controller 453 */ 454 455SUSPEND_FUNC(at91_sramc_self_refresh) 456 ldr r2, .sramc_base 457 458 /* 459 * DDR Memory controller 460 */ 461 tst r0, #SRAMC_SELF_FRESH_ACTIVE 462 beq ddrc_exit_sf 463 464 /* LPDDR1 --> force DDR2 mode during self-refresh */ 465 ldr r3, [r2, #AT91_DDRSDRC_MDR] 466 str r3, .saved_sam9_mdr 467 bic r3, r3, #~AT91_DDRSDRC_MD 468 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 469 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 470 biceq r3, r3, #AT91_DDRSDRC_MD 471 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 472 streq r3, [r2, #AT91_DDRSDRC_MDR] 473 474 /* Active DDRC self-refresh mode */ 475 ldr r3, [r2, #AT91_DDRSDRC_LPR] 476 str r3, .saved_sam9_lpr 477 bic r3, r3, #AT91_DDRSDRC_LPCB 478 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 479 str r3, [r2, #AT91_DDRSDRC_LPR] 480 481 b exit_sramc_sf 482 483ddrc_exit_sf: 484 /* Restore MDR in case of LPDDR1 */ 485 ldr r3, .saved_sam9_mdr 486 str r3, [r2, #AT91_DDRSDRC_MDR] 487 /* Restore LPR on AT91 with DDRAM */ 488 ldr r3, .saved_sam9_lpr 489 str r3, [r2, #AT91_DDRSDRC_LPR] 490 491exit_sramc_sf: 492 mov pc, lr 493SUSPEND_END_FUNC(at91_sramc_self_refresh) 494 495.pmc_base: 496 .word 0 497.sramc_base: 498 .word 0 499.shdwc: 500 .word 0 501.sfrbu: 502 .word 0 503.pm_mode: 504 .word 0 505.saved_mckr: 506 .word 0 507.saved_pllar: 508 .word 0 509.saved_sam9_lpr: 510 .word 0 511.saved_sam9_mdr: 512 .word 0 513.saved_osc_status: 514 .word 0 515 516.global at91_pm_suspend_in_sram_sz 517at91_pm_suspend_in_sram_sz: 518 .word .-at91_pm_suspend_in_sram 519 520check_fit_in_sram at91_pm_suspend_in_sram 521