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