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 str tmp1, [r0, #0] 179SUSPEND_END_FUNC(at91_backup_mode) 180 181.macro at91_pm_ulp0_mode 182 ldr pmc, .pmc_base 183 ldr tmp2, .pm_mode 184 185 /* Check if ULP0 fast variant has been requested. */ 186 cmp tmp2, #AT91_PM_ULP0_FAST 187 bne 0f 188 189 /* Set highest prescaler for power saving */ 190 ldr tmp1, [pmc, #AT91_PMC_MCKR] 191 bic tmp1, tmp1, #AT91_PMC_PRES 192 orr tmp1, tmp1, #AT91_PMC_PRES_64 193 str tmp1, [pmc, #AT91_PMC_MCKR] 194 195 mov tmp3, #0 196 wait_mckrdy tmp3 197 b 1f 198 1990: 200 /* Turn off the crystal oscillator */ 201 ldr tmp1, [pmc, #AT91_CKGR_MOR] 202 bic tmp1, tmp1, #AT91_PMC_MOSCEN 203 orr tmp1, tmp1, #AT91_PMC_KEY 204 str tmp1, [pmc, #AT91_CKGR_MOR] 205 206 /* Save RC oscillator state */ 207 ldr tmp1, [pmc, #AT91_PMC_SR] 208 str tmp1, .saved_osc_status 209 tst tmp1, #AT91_PMC_MOSCRCS 210 bne 1f 211 212 /* Turn off RC oscillator */ 213 ldr tmp1, [pmc, #AT91_CKGR_MOR] 214 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 215 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 216 orr tmp1, tmp1, #AT91_PMC_KEY 217 str tmp1, [pmc, #AT91_CKGR_MOR] 218 219 /* Wait main RC disabled done */ 2202: ldr tmp1, [pmc, #AT91_PMC_SR] 221 tst tmp1, #AT91_PMC_MOSCRCS 222 bne 2b 223 224 /* Wait for interrupt */ 2251: at91_cpu_idle 226 227 /* Check if ULP0 fast variant has been requested. */ 228 cmp tmp2, #AT91_PM_ULP0_FAST 229 bne 5f 230 231 /* Set lowest prescaler for fast resume. */ 232 ldr tmp1, [pmc, #AT91_PMC_MCKR] 233 bic tmp1, tmp1, #AT91_PMC_PRES 234 str tmp1, [pmc, #AT91_PMC_MCKR] 235 236 mov tmp3, #0 237 wait_mckrdy tmp3 238 b 6f 239 2405: /* Restore RC oscillator state */ 241 ldr tmp1, .saved_osc_status 242 tst tmp1, #AT91_PMC_MOSCRCS 243 beq 4f 244 245 /* Turn on RC oscillator */ 246 ldr tmp1, [pmc, #AT91_CKGR_MOR] 247 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 248 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 249 orr tmp1, tmp1, #AT91_PMC_KEY 250 str tmp1, [pmc, #AT91_CKGR_MOR] 251 252 /* Wait main RC stabilization */ 2533: ldr tmp1, [pmc, #AT91_PMC_SR] 254 tst tmp1, #AT91_PMC_MOSCRCS 255 beq 3b 256 257 /* Turn on the crystal oscillator */ 2584: ldr tmp1, [pmc, #AT91_CKGR_MOR] 259 orr tmp1, tmp1, #AT91_PMC_MOSCEN 260 orr tmp1, tmp1, #AT91_PMC_KEY 261 str tmp1, [pmc, #AT91_CKGR_MOR] 262 263 wait_moscrdy 2646: 265.endm 266 267/** 268 * Note: This procedure only applies on the platform which uses 269 * the external crystal oscillator as a main clock source. 270 */ 271.macro at91_pm_ulp1_mode 272 ldr pmc, .pmc_base 273 274 /* Save RC oscillator state and check if it is enabled. */ 275 ldr tmp1, [pmc, #AT91_PMC_SR] 276 str tmp1, .saved_osc_status 277 tst tmp1, #AT91_PMC_MOSCRCS 278 bne 2f 279 280 /* Enable RC oscillator */ 281 ldr tmp1, [pmc, #AT91_CKGR_MOR] 282 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 283 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 284 orr tmp1, tmp1, #AT91_PMC_KEY 285 str tmp1, [pmc, #AT91_CKGR_MOR] 286 287 /* Wait main RC stabilization */ 2881: ldr tmp1, [pmc, #AT91_PMC_SR] 289 tst tmp1, #AT91_PMC_MOSCRCS 290 beq 1b 291 292 /* Switch the main clock source to 12-MHz RC oscillator */ 2932: ldr tmp1, [pmc, #AT91_CKGR_MOR] 294 bic tmp1, tmp1, #AT91_PMC_MOSCSEL 295 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 296 orr tmp1, tmp1, #AT91_PMC_KEY 297 str tmp1, [pmc, #AT91_CKGR_MOR] 298 299 wait_moscsels 300 301 /* Disable the crystal oscillator */ 302 ldr tmp1, [pmc, #AT91_CKGR_MOR] 303 bic tmp1, tmp1, #AT91_PMC_MOSCEN 304 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 305 orr tmp1, tmp1, #AT91_PMC_KEY 306 str tmp1, [pmc, #AT91_CKGR_MOR] 307 308 /* Switch the master clock source to main clock */ 309 ldr tmp1, [pmc, #AT91_PMC_MCKR] 310 bic tmp1, tmp1, #AT91_PMC_CSS 311 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 312 str tmp1, [pmc, #AT91_PMC_MCKR] 313 314 mov tmp3, #0 315 wait_mckrdy tmp3 316 317 /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */ 318 ldr tmp1, [pmc, #AT91_CKGR_MOR] 319 orr tmp1, tmp1, #AT91_PMC_WAITMODE 320 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 321 orr tmp1, tmp1, #AT91_PMC_KEY 322 str tmp1, [pmc, #AT91_CKGR_MOR] 323 324 /* Quirk for SAM9X60's PMC */ 325 nop 326 nop 327 328 wait_mckrdy tmp3 329 330 /* Enable the crystal oscillator */ 331 ldr tmp1, [pmc, #AT91_CKGR_MOR] 332 orr 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 wait_moscrdy 338 339 /* Switch the master clock source to slow clock */ 340 ldr tmp1, [pmc, #AT91_PMC_MCKR] 341 bic tmp1, tmp1, #AT91_PMC_CSS 342 str tmp1, [pmc, #AT91_PMC_MCKR] 343 344 wait_mckrdy tmp3 345 346 /* Switch main clock source to crystal oscillator */ 347 ldr tmp1, [pmc, #AT91_CKGR_MOR] 348 orr tmp1, tmp1, #AT91_PMC_MOSCSEL 349 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 350 orr tmp1, tmp1, #AT91_PMC_KEY 351 str tmp1, [pmc, #AT91_CKGR_MOR] 352 353 wait_moscsels 354 355 /* Switch the master clock source to main clock */ 356 ldr tmp1, [pmc, #AT91_PMC_MCKR] 357 bic tmp1, tmp1, #AT91_PMC_CSS 358 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 359 str tmp1, [pmc, #AT91_PMC_MCKR] 360 361 wait_mckrdy tmp3 362 363 /* Restore RC oscillator state */ 364 ldr tmp1, .saved_osc_status 365 tst tmp1, #AT91_PMC_MOSCRCS 366 bne 3f 367 368 /* Disable RC oscillator */ 369 ldr tmp1, [pmc, #AT91_CKGR_MOR] 370 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 371 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 372 orr tmp1, tmp1, #AT91_PMC_KEY 373 str tmp1, [pmc, #AT91_CKGR_MOR] 374 375 /* Wait RC oscillator disable done */ 3764: ldr tmp1, [pmc, #AT91_PMC_SR] 377 tst tmp1, #AT91_PMC_MOSCRCS 378 bne 4b 379 3803: 381.endm 382 383/* 384 * Save PLLA setting and disable it 385 * 386 * Side effects: overwrites tmp1, tmp2 387 */ 388.macro at91_plla_disable 389#ifdef CFG_SAMA7G5 390 /* Save PLLA settings */ 391 ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT] 392 bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID 393 str tmp2, [pmc, #AT91_PMC_PLL_UPDT] 394 395 /* save div */ 396 mov tmp1, #0 397 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0] 398 bic tmp2, tmp2, #0xffffff00 399 orr tmp1, tmp1, tmp2 400 401 /* save mul */ 402 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1] 403 bic tmp2, tmp2, #0xffffff 404 orr tmp1, tmp1, tmp2 405 str tmp1, .saved_pllar 406 407 /* step 2 */ 408 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 409 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 410 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 411 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 412 413 /* step 3 */ 414 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 415 bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK 416 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 417 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 418 419 /* step 4 */ 420 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 421 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 422 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 423 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 424 425 /* step 5 */ 426 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 427 bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 428 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 429 430 /* step 6 */ 431 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 432 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 433 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 434 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 435#else 436 /* Save PLLA setting and disable it */ 437 ldr tmp1, [pmc, #AT91_CKGR_PLLAR] 438 str tmp1, .saved_pllar 439 440 /* Disable PLLA. */ 441 mov tmp1, #AT91_PMC_PLLCOUNT 442 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ 443 str tmp1, [pmc, #AT91_CKGR_PLLAR] 444#endif 4452: 446.endm 447 448/* 449 * Enable PLLA with the saved setting 450 * 451 * Side effects: overwrites tmp1, tmp2 452 */ 453.macro at91_plla_enable 454#ifdef CFG_SAMA7G5 455 /* step 1 */ 456 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 457 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 458 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 459 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 460 461 /* step 2 */ 462 ldr tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA 463 str tmp1, [pmc, #AT91_PMC_PLL_ACR] 464 465 /* step 3 */ 466 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1] 467 ldr tmp2, .saved_pllar 468 bic tmp2, tmp2, #0xffffff 469 orr tmp1, tmp1, tmp2 470 str tmp1, [pmc, #AT91_PMC_PLL_CTRL1] 471 472 /* step 4 */ 473 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 474 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 475 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 476 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 477 478 /* step 5 */ 479 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 480 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK 481 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 482 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK 483 bic tmp1, tmp1, #0xff 484 ldr tmp2, .saved_pllar 485 bic tmp2, tmp2, #0xffffff00 486 orr tmp1, tmp1, tmp2 487 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 488 489 /* step 6 */ 490 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 491 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 492 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 493 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 494 495 /* step 7 */ 4963: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0] 497 tst tmp1, #0x1 498 beq 3b 499#else 500 ldr tmp2, .saved_pllar 501 502 /* Restore PLLA setting */ 503 str tmp2, [pmc, #AT91_CKGR_PLLAR] 504 505 /* Enable PLLA. */ 506 tst tmp2, #(AT91_PMC_MUL & 0xff0000) 507 bne 1f 508 tst tmp2, #(AT91_PMC_MUL & ~0xff0000) 509 beq 2f 510 5111: ldr tmp1, [pmc, #AT91_PMC_SR] 512 tst tmp1, #AT91_PMC_LOCKA 513 beq 1b 5142: 515#endif 516.endm 517 518#ifdef CFG_SAMA7G5 519/* 520 * at91_mckx_ps_enable: save MCK1..4 settings and switch it to main clock 521 * 522 * Side effects: overwrites tmp1, tmp2, tmp3 523 */ 524.macro at91_mckx_ps_enable 525 ldr pmc, .pmc_base 526 527 /* There are 4 MCKs we need to handle: MCK1..4 */ 528 mov tmp1, #1 529e_loop: 530 /* Write MCK ID to retrieve the settings */ 531 str tmp1, [pmc, #AT91_PMC_MCR_V2] 532 ldr tmp2, [pmc, #AT91_PMC_MCR_V2] 533 534 cmp tmp1, #1 535 streq tmp2, .saved_mck1 536 cmp tmp1, #2 537 streq tmp2, .saved_mck2 538 cmp tmp1, #3 539 streq tmp2, .saved_mck3 540 cmp tmp1, #4 541 streq tmp2, .saved_mck4 542 543 /* Use CSS=MD_SLOW_CLK and DIV=64. */ 544 bic tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MASK 545 bic tmp2, tmp2, #AT91_PMC_MCR_V2_DIV_MASK 546 orr tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MD_SLCK 547 orr tmp2, tmp2, #AT91_PMC_MCR_V2_DIV64 548 orr tmp2, tmp2, #AT91_PMC_MCR_V2_CMD 549 str tmp2, [pmc, #AT91_PMC_MCR_V2] 550 551 mov tmp2, tmp1 552 wait_mckrdy tmp1 553 mov tmp1, tmp2 554 555 add tmp1, tmp1, #1 556 cmp tmp1, #5 557 bne e_loop 558.endm 559 560/* 561 * at91_mckx_ps_restore: restore MCK1..4 settings 562 * 563 * Side effects: overwrites tmp1, tmp2, tmp3 564 */ 565.macro at91_mckx_ps_restore 566 ldr pmc, .pmc_base 567 568 /* There are 4 MCKs we need to handle: MCK1..4 */ 569 mov tmp1, #1 570 ldr tmp2, .saved_mck1 571r_loop: 572 cmp tmp1, #2 573 ldreq tmp2, .saved_mck2 574 cmp tmp1, #3 575 ldreq tmp2, .saved_mck3 576 cmp tmp1, #4 577 ldreq tmp2, .saved_mck4 578 579 /* Write MCK ID to retrieve the settings */ 580 str tmp1, [pmc, #AT91_PMC_MCR_V2] 581 ldr tmp3, [pmc, #AT91_PMC_MCR_V2] 582 583 /* We need to restore CSS and DIV. */ 584 bic tmp3, tmp3, #AT91_PMC_MCR_V2_CSS_MASK 585 bic tmp3, tmp3, #AT91_PMC_MCR_V2_DIV_MASK 586 orr tmp3, tmp3, tmp2 587 bic tmp3, tmp3, #AT91_PMC_MCR_V2_ID_MASK 588 orr tmp3, tmp3, tmp1 589 orr tmp3, tmp3, #AT91_PMC_MCR_V2_CMD 590 str tmp3, [pmc, #AT91_PMC_MCR_V2] 591 592 mov tmp2, tmp1 593 wait_mckrdy tmp1 594 mov tmp1, tmp2 595 596 add tmp1, tmp1, #1 597 cmp tmp1, #5 598 bne r_loop 599.endm 600#endif 601 602SUSPEND_FUNC(at91_ulp_mode) 603#ifdef CFG_SAMA7G5 604 at91_mckx_ps_enable 605#endif 606 607 ldr pmc, .pmc_base 608 ldr tmp3, .pm_mode 609 610 /* Save Master clock setting */ 611 ldr tmp1, [pmc, #AT91_PMC_MCKR] 612 str tmp1, .saved_mckr 613 614 /* 615 * Set master clock source to: 616 * - MAINCK if using ULP0 fast variant 617 * - slow clock, otherwise 618 */ 619 bic tmp1, tmp1, #AT91_PMC_CSS 620 cmp tmp3, #AT91_PM_ULP0_FAST 621 bne save_mck 622 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 623save_mck: 624 str tmp1, [pmc, #AT91_PMC_MCKR] 625 626 mov tmp3, #0 627 wait_mckrdy tmp3 628 629 at91_plla_disable 630 631 ldr tmp3, .pm_mode 632 cmp tmp3, #AT91_PM_ULP1 633 beq ulp1_mode 634 635 at91_pm_ulp0_mode 636 b ulp_exit 637 638ulp1_mode: 639 at91_pm_ulp1_mode 640 b ulp_exit 641 642ulp_exit: 643 ldr pmc, .pmc_base 644 645 at91_plla_enable 646 647 /* 648 * Restore master clock setting 649 */ 650 ldr tmp2, .saved_mckr 651 str tmp2, [pmc, #AT91_PMC_MCKR] 652 653 mov tmp3, #0 654 wait_mckrdy tmp3 655 656#ifdef CFG_SAMA7G5 657 at91_mckx_ps_restore 658#endif 659 660 mov pc, lr 661SUSPEND_END_FUNC(at91_ulp_mode) 662 663/* 664 * void at91_sramc_self_refresh(unsigned int is_active) 665 * 666 * @input param: 667 * @r0: 1 - active self-refresh mode 668 * 0 - exit self-refresh mode 669 * register usage: 670 * @r2: base address of the sram controller 671 */ 672 673SUSPEND_FUNC(at91_sramc_self_refresh) 674 ldr r2, .sramc_base 675 676 /* 677 * DDR Memory controller 678 */ 679 tst r0, #SRAMC_SELF_FRESH_ACTIVE 680 beq ddrc_exit_sf 681 682 /* LPDDR1 --> force DDR2 mode during self-refresh */ 683 ldr r3, [r2, #AT91_DDRSDRC_MDR] 684 str r3, .saved_sam9_mdr 685 bic r3, r3, #~AT91_DDRSDRC_MD 686 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 687 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 688 biceq r3, r3, #AT91_DDRSDRC_MD 689 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 690 streq r3, [r2, #AT91_DDRSDRC_MDR] 691 692 /* Active DDRC self-refresh mode */ 693 ldr r3, [r2, #AT91_DDRSDRC_LPR] 694 str r3, .saved_sam9_lpr 695 bic r3, r3, #AT91_DDRSDRC_LPCB 696 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 697 str r3, [r2, #AT91_DDRSDRC_LPR] 698 699 b exit_sramc_sf 700 701ddrc_exit_sf: 702 /* Restore MDR in case of LPDDR1 */ 703 ldr r3, .saved_sam9_mdr 704 str r3, [r2, #AT91_DDRSDRC_MDR] 705 /* Restore LPR on AT91 with DDRAM */ 706 ldr r3, .saved_sam9_lpr 707 str r3, [r2, #AT91_DDRSDRC_LPR] 708 709exit_sramc_sf: 710 mov pc, lr 711SUSPEND_END_FUNC(at91_sramc_self_refresh) 712 713.pmc_base: 714 .word 0 715.sramc_base: 716 .word 0 717.shdwc: 718 .word 0 719.sfrbu: 720 .word 0 721.pm_mode: 722 .word 0 723.saved_mckr: 724 .word 0 725.saved_pllar: 726 .word 0 727.saved_sam9_lpr: 728 .word 0 729.saved_sam9_mdr: 730 .word 0 731.saved_osc_status: 732 .word 0 733#ifdef CFG_SAMA7G5 734.saved_mck1: 735 .word 0 736.saved_mck2: 737 .word 0 738.saved_mck3: 739 .word 0 740.saved_mck4: 741 .word 0 742#endif 743 744.global at91_pm_suspend_in_sram_sz 745at91_pm_suspend_in_sram_sz: 746 .word .-at91_pm_suspend_in_sram 747 748check_fit_in_sram at91_pm_suspend_in_sram 749