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 * @r_mckid: register holding master clock identifier 29 * 30 * Side effects: overwrites tmp1 31 */ 32.macro wait_mckrdy r_mckid 33#ifdef CFG_SAMA7G5 34 cmp \r_mckid, #0 35 beq 1f 362: ldr tmp1, [pmc, #AT91_PMC_SR] 37 tst tmp1, #AT91_PMC_MCKXRDY 38 beq 2b 39 b 3f 40#endif 411: ldr tmp1, [pmc, #AT91_PMC_SR] 42 tst tmp1, #AT91_PMC_MCKRDY 43 beq 1b 443: 45.endm 46 47/* 48 * Wait until master oscillator has stabilized. 49 */ 50.macro wait_moscrdy 511: ldr tmp1, [pmc, #AT91_PMC_SR] 52 tst tmp1, #AT91_PMC_MOSCS 53 beq 1b 54.endm 55 56/* 57 * Wait for main oscillator selection is done 58 */ 59.macro wait_moscsels 601: ldr tmp1, [pmc, #AT91_PMC_SR] 61 tst tmp1, #AT91_PMC_MOSCSELS 62 beq 1b 63.endm 64 65/* 66 * Put the processor to enter the idle state 67 */ 68.macro at91_cpu_idle 69 70 mov tmp1, #AT91_PMC_PCK 71 str tmp1, [pmc, #AT91_PMC_SCDR] 72 73 dsb 74 75 wfi @ Wait For Interrupt 76 77.endm 78 79.section .text.psci.suspend 80 81.arm 82 83 84#define SUSPEND_FUNC(__name) \ 85__name: 86 87#define SUSPEND_END_FUNC(__name) \ 88 .size __name, .-__name 89 90.macro check_fit_in_sram since 91 .if (. - \since) > 0x10000 92 .error "Suspend assembly code exceeds dedicated SRAM size" 93 .endif 94.endm 95 96/* 97 * void at91_suspend_sram_fn(struct at91_pm_data*) 98 * @input param: 99 * @r0: base address of struct at91_pm_data 100 */ 101.align 3 102.global at91_pm_suspend_in_sram 103SUSPEND_FUNC(at91_pm_suspend_in_sram) 104 /* Save registers on stack */ 105 stmfd sp!, {r4 - r12, lr} 106 107 /* Drain write buffer */ 108 mov tmp1, #0 109 mcr p15, 0, tmp1, c7, c10, 4 110 111 ldr tmp1, [r0, #PM_DATA_PMC] 112 str tmp1, .pmc_base 113 ldr tmp1, [r0, #PM_DATA_RAMC0] 114 str tmp1, .sramc_base 115 ldr tmp1, [r0, #PM_DATA_MODE] 116 str tmp1, .pm_mode 117 /* Both ldrne below are here to preload their address in the TLB */ 118 ldr tmp1, [r0, #PM_DATA_SHDWC] 119 str tmp1, .shdwc 120 cmp tmp1, #0 121 ldrne tmp2, [tmp1, #0] 122 ldr tmp1, [r0, #PM_DATA_SFRBU] 123 str tmp1, .sfrbu 124 cmp tmp1, #0 125 ldrne tmp2, [tmp1, #0x10] 126 127 /* Active the self-refresh mode */ 128 mov r0, #SRAMC_SELF_FRESH_ACTIVE 129 bl at91_sramc_self_refresh 130 131 ldr r0, .pm_mode 132 cmp r0, #AT91_PM_STANDBY 133 beq standby 134 cmp r0, #AT91_PM_BACKUP 135 beq backup_mode 136 137 bl at91_ulp_mode 138 b exit_suspend 139 140standby: 141 /* Wait for interrupt */ 142 ldr pmc, .pmc_base 143 at91_cpu_idle 144 b exit_suspend 145 146backup_mode: 147 bl at91_backup_mode 148 b exit_suspend 149 150exit_suspend: 151 /* Exit the self-refresh mode */ 152 mov r0, #SRAMC_SELF_FRESH_EXIT 153 bl at91_sramc_self_refresh 154 155 /* Restore registers, and return */ 156 ldmfd sp!, {r4 - r12, pc} 157SUSPEND_END_FUNC(at91_pm_suspend_in_sram) 158 159SUSPEND_FUNC(at91_backup_mode) 160 /* Switch the master clock source to slow clock. */ 161 ldr pmc, .pmc_base 162 ldr tmp1, [pmc, #AT91_PMC_MCKR] 163 bic tmp1, tmp1, #AT91_PMC_CSS 164 str tmp1, [pmc, #AT91_PMC_MCKR] 165 166 mov tmp3, #0 167 wait_mckrdy tmp3 168 169 /*BUMEN*/ 170 ldr r0, .sfrbu 171 mov tmp1, #0x1 172 str tmp1, [r0, #0x10] 173 174 /* Shutdown */ 175 ldr r0, .shdwc 176 mov tmp1, #0xA5000000 177 add tmp1, tmp1, #0x1 178#ifdef CFG_SAMA7G5 179 /* LPM Pad Enable: The LPM pad is set high */ 180 orr tmp1, tmp1, #0x200000 181#endif 182 str tmp1, [r0, #0] 183SUSPEND_END_FUNC(at91_backup_mode) 184 185/* 186 * Set LPM 187 * @ena: 0 - disable LPM 188 * 1 - enable LPM 189 * 190 * Side effects: overwrites tmp1, tmp3 191 */ 192.macro at91_set_lpm ena 193#ifdef CFG_SAMA7G5 194 mov tmp1, #\ena 195 cmp tmp1, #1 196 movne tmp3, #0x400000 /* LPM Pad Disable: The LPM pad is set low */ 197 moveq tmp3, #0x200000 /* LPM Pad Enable: The LPM pad is set high */ 198 add tmp3, #0xA5000000 199 ldr tmp1, .shdwc 200 cmp tmp1, #0 201 strne tmp3, [tmp1] 202#endif 203.endm 204 205.macro at91_pm_ulp0_mode 206 ldr pmc, .pmc_base 207 ldr tmp2, .pm_mode 208 209 /* Check if ULP0 fast variant has been requested. */ 210 cmp tmp2, #AT91_PM_ULP0_FAST 211 bne 0f 212 213 /* Set highest prescaler for power saving */ 214 ldr tmp1, [pmc, #AT91_PMC_MCKR] 215 bic tmp1, tmp1, #AT91_PMC_PRES 216 orr tmp1, tmp1, #AT91_PMC_PRES_64 217 str tmp1, [pmc, #AT91_PMC_MCKR] 218 219 mov tmp3, #0 220 wait_mckrdy tmp3 221 b 1f 222 2230: 224 /* Turn off the crystal oscillator */ 225 ldr tmp1, [pmc, #AT91_CKGR_MOR] 226 bic tmp1, tmp1, #AT91_PMC_MOSCEN 227 orr tmp1, tmp1, #AT91_PMC_KEY 228 str tmp1, [pmc, #AT91_CKGR_MOR] 229 230 /* Save RC oscillator state */ 231 ldr tmp1, [pmc, #AT91_PMC_SR] 232 str tmp1, .saved_osc_status 233 tst tmp1, #AT91_PMC_MOSCRCS 234 bne 7f 235 236 /* Turn off RC oscillator */ 237 ldr tmp1, [pmc, #AT91_CKGR_MOR] 238 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 239 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 240 orr tmp1, tmp1, #AT91_PMC_KEY 241 str tmp1, [pmc, #AT91_CKGR_MOR] 242 243 /* Wait main RC disabled done */ 2442: ldr tmp1, [pmc, #AT91_PMC_SR] 245 tst tmp1, #AT91_PMC_MOSCRCS 246 bne 2b 247 248 /* Enable LPM. */ 2497: at91_set_lpm 1 250 251 /* Wait for interrupt */ 2521: at91_cpu_idle 253 254 /* Check if ULP0 fast variant has been requested. */ 255 cmp tmp2, #AT91_PM_ULP0_FAST 256 bne 8f 257 258 /* Set lowest prescaler for fast resume. */ 259 ldr tmp1, [pmc, #AT91_PMC_MCKR] 260 bic tmp1, tmp1, #AT91_PMC_PRES 261 str tmp1, [pmc, #AT91_PMC_MCKR] 262 263 mov tmp3, #0 264 wait_mckrdy tmp3 265 b 6f 266 2678: at91_set_lpm 0 268 2695: /* Restore RC oscillator state */ 270 ldr tmp1, .saved_osc_status 271 tst tmp1, #AT91_PMC_MOSCRCS 272 beq 4f 273 274 /* Turn on RC oscillator */ 275 ldr tmp1, [pmc, #AT91_CKGR_MOR] 276 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 277 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 278 orr tmp1, tmp1, #AT91_PMC_KEY 279 str tmp1, [pmc, #AT91_CKGR_MOR] 280 281 /* Wait main RC stabilization */ 2823: ldr tmp1, [pmc, #AT91_PMC_SR] 283 tst tmp1, #AT91_PMC_MOSCRCS 284 beq 3b 285 286 /* Turn on the crystal oscillator */ 2874: ldr tmp1, [pmc, #AT91_CKGR_MOR] 288 orr tmp1, tmp1, #AT91_PMC_MOSCEN 289 orr tmp1, tmp1, #AT91_PMC_KEY 290 str tmp1, [pmc, #AT91_CKGR_MOR] 291 292 wait_moscrdy 2936: 294.endm 295 296/** 297 * Note: This procedure only applies on the platform which uses 298 * the external crystal oscillator as a main clock source. 299 */ 300.macro at91_pm_ulp1_mode 301 ldr pmc, .pmc_base 302 303 /* Save RC oscillator state and check if it is enabled. */ 304 ldr tmp1, [pmc, #AT91_PMC_SR] 305 str tmp1, .saved_osc_status 306 tst tmp1, #AT91_PMC_MOSCRCS 307 bne 2f 308 309 /* Enable RC oscillator */ 310 ldr tmp1, [pmc, #AT91_CKGR_MOR] 311 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 312 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 313 orr tmp1, tmp1, #AT91_PMC_KEY 314 str tmp1, [pmc, #AT91_CKGR_MOR] 315 316 /* Wait main RC stabilization */ 3171: ldr tmp1, [pmc, #AT91_PMC_SR] 318 tst tmp1, #AT91_PMC_MOSCRCS 319 beq 1b 320 321 /* Switch the main clock source to 12-MHz RC oscillator */ 3222: ldr tmp1, [pmc, #AT91_CKGR_MOR] 323 bic tmp1, tmp1, #AT91_PMC_MOSCSEL 324 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 325 orr tmp1, tmp1, #AT91_PMC_KEY 326 str tmp1, [pmc, #AT91_CKGR_MOR] 327 328 wait_moscsels 329 330 /* Disable the crystal oscillator */ 331 ldr tmp1, [pmc, #AT91_CKGR_MOR] 332 bic tmp1, tmp1, #AT91_PMC_MOSCEN 333 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 334 orr tmp1, tmp1, #AT91_PMC_KEY 335 str tmp1, [pmc, #AT91_CKGR_MOR] 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 mov tmp3, #0 344 wait_mckrdy tmp3 345 346 /* Enable LPM */ 347 at91_set_lpm 1 348 349 /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */ 350 ldr tmp1, [pmc, #AT91_CKGR_MOR] 351 orr tmp1, tmp1, #AT91_PMC_WAITMODE 352 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 353 orr tmp1, tmp1, #AT91_PMC_KEY 354 str tmp1, [pmc, #AT91_CKGR_MOR] 355 356 /* Quirk for SAM9X60's PMC */ 357 nop 358 nop 359 360 mov tmp3, #0 361 wait_mckrdy tmp3 362 363 /* Disable LPM. */ 364 at91_set_lpm 0 365 366 /* Enable the crystal oscillator */ 367 ldr tmp1, [pmc, #AT91_CKGR_MOR] 368 orr tmp1, tmp1, #AT91_PMC_MOSCEN 369 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 370 orr tmp1, tmp1, #AT91_PMC_KEY 371 str tmp1, [pmc, #AT91_CKGR_MOR] 372 373 wait_moscrdy 374 375 /* Switch the master clock source to slow clock */ 376 ldr tmp1, [pmc, #AT91_PMC_MCKR] 377 bic tmp1, tmp1, #AT91_PMC_CSS 378 str tmp1, [pmc, #AT91_PMC_MCKR] 379 380 mov tmp3, #0 381 wait_mckrdy tmp3 382 383 /* Switch main clock source to crystal oscillator */ 384 ldr tmp1, [pmc, #AT91_CKGR_MOR] 385 orr tmp1, tmp1, #AT91_PMC_MOSCSEL 386 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 387 orr tmp1, tmp1, #AT91_PMC_KEY 388 str tmp1, [pmc, #AT91_CKGR_MOR] 389 390 wait_moscsels 391 392 /* Switch the master clock source to main clock */ 393 ldr tmp1, [pmc, #AT91_PMC_MCKR] 394 bic tmp1, tmp1, #AT91_PMC_CSS 395 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 396 str tmp1, [pmc, #AT91_PMC_MCKR] 397 398 wait_mckrdy tmp3 399 400 /* Restore RC oscillator state */ 401 ldr tmp1, .saved_osc_status 402 tst tmp1, #AT91_PMC_MOSCRCS 403 bne 3f 404 405 /* Disable RC oscillator */ 406 ldr tmp1, [pmc, #AT91_CKGR_MOR] 407 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 408 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 409 orr tmp1, tmp1, #AT91_PMC_KEY 410 str tmp1, [pmc, #AT91_CKGR_MOR] 411 412 /* Wait RC oscillator disable done */ 4134: ldr tmp1, [pmc, #AT91_PMC_SR] 414 tst tmp1, #AT91_PMC_MOSCRCS 415 bne 4b 416 4173: 418.endm 419 420/* 421 * Save PLLA setting and disable it 422 * 423 * Side effects: overwrites tmp1, tmp2 424 */ 425.macro at91_plla_disable 426#ifdef CFG_SAMA7G5 427 /* Save PLLA settings */ 428 ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT] 429 bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID 430 str tmp2, [pmc, #AT91_PMC_PLL_UPDT] 431 432 /* save div */ 433 mov tmp1, #0 434 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0] 435 bic tmp2, tmp2, #0xffffff00 436 orr tmp1, tmp1, tmp2 437 438 /* save mul */ 439 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1] 440 bic tmp2, tmp2, #0xffffff 441 orr tmp1, tmp1, tmp2 442 str tmp1, .saved_pllar 443 444 /* step 2 */ 445 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 446 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 447 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 448 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 449 450 /* step 3 */ 451 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 452 bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK 453 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 454 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 455 456 /* step 4 */ 457 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 458 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 459 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 460 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 461 462 /* step 5 */ 463 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 464 bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 465 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 466 467 /* step 6 */ 468 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 469 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 470 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 471 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 472#else 473 /* Save PLLA setting and disable it */ 474 ldr tmp1, [pmc, #AT91_CKGR_PLLAR] 475 str tmp1, .saved_pllar 476 477 /* Disable PLLA. */ 478 mov tmp1, #AT91_PMC_PLLCOUNT 479 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ 480 str tmp1, [pmc, #AT91_CKGR_PLLAR] 481#endif 4822: 483.endm 484 485/* 486 * Enable PLLA with the saved setting 487 * 488 * Side effects: overwrites tmp1, tmp2 489 */ 490.macro at91_plla_enable 491#ifdef CFG_SAMA7G5 492 /* step 1 */ 493 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 494 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 495 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 496 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 497 498 /* step 2 */ 499 ldr tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA 500 str tmp1, [pmc, #AT91_PMC_PLL_ACR] 501 502 /* step 3 */ 503 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1] 504 ldr tmp2, .saved_pllar 505 bic tmp2, tmp2, #0xffffff 506 orr tmp1, tmp1, tmp2 507 str tmp1, [pmc, #AT91_PMC_PLL_CTRL1] 508 509 /* step 4 */ 510 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 511 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 512 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 513 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 514 515 /* step 5 */ 516 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 517 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK 518 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 519 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK 520 bic tmp1, tmp1, #0xff 521 ldr tmp2, .saved_pllar 522 bic tmp2, tmp2, #0xffffff00 523 orr tmp1, tmp1, tmp2 524 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 525 526 /* step 6 */ 527 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 528 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 529 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 530 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 531 532 /* step 7 */ 5333: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0] 534 tst tmp1, #0x1 535 beq 3b 536#else 537 ldr tmp2, .saved_pllar 538 539 /* Restore PLLA setting */ 540 str tmp2, [pmc, #AT91_CKGR_PLLAR] 541 542 /* Enable PLLA. */ 543 tst tmp2, #(AT91_PMC_MUL & 0xff0000) 544 bne 1f 545 tst tmp2, #(AT91_PMC_MUL & ~0xff0000) 546 beq 2f 547 5481: ldr tmp1, [pmc, #AT91_PMC_SR] 549 tst tmp1, #AT91_PMC_LOCKA 550 beq 1b 5512: 552#endif 553.endm 554 555#ifdef CFG_SAMA7G5 556/* 557 * at91_mckx_ps_enable: save MCK1..4 settings and switch it to main clock 558 * 559 * Side effects: overwrites tmp1, tmp2, tmp3 560 */ 561.macro at91_mckx_ps_enable 562 ldr pmc, .pmc_base 563 564 /* There are 4 MCKs we need to handle: MCK1..4 */ 565 mov tmp1, #1 566e_loop: 567 /* Write MCK ID to retrieve the settings */ 568 str tmp1, [pmc, #AT91_PMC_MCR_V2] 569 ldr tmp2, [pmc, #AT91_PMC_MCR_V2] 570 571 cmp tmp1, #1 572 streq tmp2, .saved_mck1 573 cmp tmp1, #2 574 streq tmp2, .saved_mck2 575 cmp tmp1, #3 576 streq tmp2, .saved_mck3 577 cmp tmp1, #4 578 streq tmp2, .saved_mck4 579 580 /* Use CSS=MD_SLOW_CLK and DIV=64. */ 581 bic tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MASK 582 bic tmp2, tmp2, #AT91_PMC_MCR_V2_DIV_MASK 583 orr tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MD_SLCK 584 orr tmp2, tmp2, #AT91_PMC_MCR_V2_DIV64 585 orr tmp2, tmp2, #AT91_PMC_MCR_V2_CMD 586 str tmp2, [pmc, #AT91_PMC_MCR_V2] 587 588 mov tmp2, tmp1 589 wait_mckrdy tmp1 590 mov tmp1, tmp2 591 592 add tmp1, tmp1, #1 593 cmp tmp1, #5 594 bne e_loop 595.endm 596 597/* 598 * at91_mckx_ps_restore: restore MCK1..4 settings 599 * 600 * Side effects: overwrites tmp1, tmp2, tmp3 601 */ 602.macro at91_mckx_ps_restore 603 ldr pmc, .pmc_base 604 605 /* There are 4 MCKs we need to handle: MCK1..4 */ 606 mov tmp1, #1 607 ldr tmp2, .saved_mck1 608r_loop: 609 cmp tmp1, #2 610 ldreq tmp2, .saved_mck2 611 cmp tmp1, #3 612 ldreq tmp2, .saved_mck3 613 cmp tmp1, #4 614 ldreq tmp2, .saved_mck4 615 616 /* Write MCK ID to retrieve the settings */ 617 str tmp1, [pmc, #AT91_PMC_MCR_V2] 618 ldr tmp3, [pmc, #AT91_PMC_MCR_V2] 619 620 /* We need to restore CSS and DIV. */ 621 bic tmp3, tmp3, #AT91_PMC_MCR_V2_CSS_MASK 622 bic tmp3, tmp3, #AT91_PMC_MCR_V2_DIV_MASK 623 orr tmp3, tmp3, tmp2 624 bic tmp3, tmp3, #AT91_PMC_MCR_V2_ID_MASK 625 orr tmp3, tmp3, tmp1 626 orr tmp3, tmp3, #AT91_PMC_MCR_V2_CMD 627 str tmp3, [pmc, #AT91_PMC_MCR_V2] 628 629 mov tmp2, tmp1 630 wait_mckrdy tmp1 631 mov tmp1, tmp2 632 633 add tmp1, tmp1, #1 634 cmp tmp1, #5 635 bne r_loop 636.endm 637#endif 638 639SUSPEND_FUNC(at91_ulp_mode) 640#ifdef CFG_SAMA7G5 641 at91_mckx_ps_enable 642#endif 643 644 ldr pmc, .pmc_base 645 ldr tmp3, .pm_mode 646 647 /* Save Master clock setting */ 648 ldr tmp1, [pmc, #AT91_PMC_MCKR] 649 str tmp1, .saved_mckr 650 651 /* 652 * Set master clock source to: 653 * - MAINCK if using ULP0 fast variant 654 * - slow clock, otherwise 655 */ 656 bic tmp1, tmp1, #AT91_PMC_CSS 657 cmp tmp3, #AT91_PM_ULP0_FAST 658 bne save_mck 659 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 660save_mck: 661 str tmp1, [pmc, #AT91_PMC_MCKR] 662 663 mov tmp3, #0 664 wait_mckrdy tmp3 665 666 at91_plla_disable 667 668 ldr tmp3, .pm_mode 669 cmp tmp3, #AT91_PM_ULP1 670 beq ulp1_mode 671 672 at91_pm_ulp0_mode 673 b ulp_exit 674 675ulp1_mode: 676 at91_pm_ulp1_mode 677 b ulp_exit 678 679ulp_exit: 680 ldr pmc, .pmc_base 681 682 at91_plla_enable 683 684 /* 685 * Restore master clock setting 686 */ 687 ldr tmp2, .saved_mckr 688 str tmp2, [pmc, #AT91_PMC_MCKR] 689 690 mov tmp3, #0 691 wait_mckrdy tmp3 692 693#ifdef CFG_SAMA7G5 694 at91_mckx_ps_restore 695#endif 696 697 mov pc, lr 698SUSPEND_END_FUNC(at91_ulp_mode) 699 700/* 701 * void at91_sramc_self_refresh(unsigned int is_active) 702 * 703 * @input param: 704 * @r0: 1 - active self-refresh mode 705 * 0 - exit self-refresh mode 706 * register usage: 707 * @r2: base address of the sram controller 708 */ 709 710SUSPEND_FUNC(at91_sramc_self_refresh) 711 ldr r2, .sramc_base 712 713 /* 714 * DDR Memory controller 715 */ 716 tst r0, #SRAMC_SELF_FRESH_ACTIVE 717 beq ddrc_exit_sf 718 719 /* LPDDR1 --> force DDR2 mode during self-refresh */ 720 ldr r3, [r2, #AT91_DDRSDRC_MDR] 721 str r3, .saved_sam9_mdr 722 bic r3, r3, #~AT91_DDRSDRC_MD 723 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 724 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 725 biceq r3, r3, #AT91_DDRSDRC_MD 726 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 727 streq r3, [r2, #AT91_DDRSDRC_MDR] 728 729 /* Active DDRC self-refresh mode */ 730 ldr r3, [r2, #AT91_DDRSDRC_LPR] 731 str r3, .saved_sam9_lpr 732 bic r3, r3, #AT91_DDRSDRC_LPCB 733 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 734 str r3, [r2, #AT91_DDRSDRC_LPR] 735 736 b exit_sramc_sf 737 738ddrc_exit_sf: 739 /* Restore MDR in case of LPDDR1 */ 740 ldr r3, .saved_sam9_mdr 741 str r3, [r2, #AT91_DDRSDRC_MDR] 742 /* Restore LPR on AT91 with DDRAM */ 743 ldr r3, .saved_sam9_lpr 744 str r3, [r2, #AT91_DDRSDRC_LPR] 745 746exit_sramc_sf: 747 mov pc, lr 748SUSPEND_END_FUNC(at91_sramc_self_refresh) 749 750.pmc_base: 751 .word 0 752.sramc_base: 753 .word 0 754.shdwc: 755 .word 0 756.sfrbu: 757 .word 0 758.pm_mode: 759 .word 0 760.saved_mckr: 761 .word 0 762.saved_pllar: 763 .word 0 764.saved_sam9_lpr: 765 .word 0 766.saved_sam9_mdr: 767 .word 0 768.saved_osc_status: 769 .word 0 770#ifdef CFG_SAMA7G5 771.saved_mck1: 772 .word 0 773.saved_mck2: 774 .word 0 775.saved_mck3: 776 .word 0 777.saved_mck4: 778 .word 0 779#endif 780 781.global at91_pm_suspend_in_sram_sz 782at91_pm_suspend_in_sram_sz: 783 .word .-at91_pm_suspend_in_sram 784 785check_fit_in_sram at91_pm_suspend_in_sram 786