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#ifdef CFG_SAMA7G5 14#include <drivers/sam/sama7-ddr.h> 15#else 16#include <drivers/sam/at91_ddr.h> 17#endif 18#include <generated/pm-defines.h> 19 20#include "at91_pm.h" 21 22#define SRAMC_SELF_FRESH_ACTIVE 0x01 23#define SRAMC_SELF_FRESH_EXIT 0x00 24 25pmc .req r0 26tmp1 .req r4 27tmp2 .req r5 28tmp3 .req r6 29 30/* 31 * Wait until master clock is ready (after switching master clock source) 32 * @r_mckid: register holding master clock identifier 33 * 34 * Side effects: overwrites tmp1 35 */ 36.macro wait_mckrdy r_mckid 37#ifdef CFG_SAMA7G5 38 cmp \r_mckid, #0 39 beq 1f 402: ldr tmp1, [pmc, #AT91_PMC_SR] 41 tst tmp1, #AT91_PMC_MCKXRDY 42 beq 2b 43 b 3f 44#endif 451: ldr tmp1, [pmc, #AT91_PMC_SR] 46 tst tmp1, #AT91_PMC_MCKRDY 47 beq 1b 483: 49.endm 50 51/* 52 * Wait until master oscillator has stabilized. 53 */ 54.macro wait_moscrdy 551: ldr tmp1, [pmc, #AT91_PMC_SR] 56 tst tmp1, #AT91_PMC_MOSCS 57 beq 1b 58.endm 59 60/* 61 * Wait for main oscillator selection is done 62 */ 63.macro wait_moscsels 641: ldr tmp1, [pmc, #AT91_PMC_SR] 65 tst tmp1, #AT91_PMC_MOSCSELS 66 beq 1b 67.endm 68 69/* 70 * Put the processor to enter the idle state 71 */ 72.macro at91_cpu_idle 73 74 mov tmp1, #AT91_PMC_PCK 75 str tmp1, [pmc, #AT91_PMC_SCDR] 76 77 dsb 78 79 wfi @ Wait For Interrupt 80 81.endm 82 83.section .text.psci.suspend 84 85.arm 86 87#ifdef CFG_SAMA7G5 88/* 89 * Enable self-refresh 90 * 91 * Side effects: overwrites tmp1, tmp2, tmp3 92 */ 93.macro at91_sramc_self_refresh_ena 94 dsb 95 96 ldr tmp2, .sramc_base 97 98 /* Disable all AXI ports. */ 99 ldr tmp1, [tmp2, #UDDRC_PCTRL_0] 100 bic tmp1, tmp1, #0x1 101 str tmp1, [tmp2, #UDDRC_PCTRL_0] 102 103 ldr tmp1, [tmp2, #UDDRC_PCTRL_1] 104 bic tmp1, tmp1, #0x1 105 str tmp1, [tmp2, #UDDRC_PCTRL_1] 106 107 ldr tmp1, [tmp2, #UDDRC_PCTRL_2] 108 bic tmp1, tmp1, #0x1 109 str tmp1, [tmp2, #UDDRC_PCTRL_2] 110 111 ldr tmp1, [tmp2, #UDDRC_PCTRL_3] 112 bic tmp1, tmp1, #0x1 113 str tmp1, [tmp2, #UDDRC_PCTRL_3] 114 115 ldr tmp1, [tmp2, #UDDRC_PCTRL_4] 116 bic tmp1, tmp1, #0x1 117 str tmp1, [tmp2, #UDDRC_PCTRL_4] 118 119sr_ena_1: 120 /* Wait for all ports to disable. */ 121 ldr tmp1, [tmp2, #UDDRC_PSTAT] 122 ldr tmp3, =UDDRC_PSTAT_ALL_PORTS 123 tst tmp1, tmp3 124 bne sr_ena_1 125 126 /* Switch to self-refresh. */ 127 ldr tmp1, [tmp2, #UDDRC_PWRCTL] 128 orr tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW 129 str tmp1, [tmp2, #UDDRC_PWRCTL] 130 131sr_ena_2: 132 /* Wait for self-refresh enter. */ 133 ldr tmp1, [tmp2, #UDDRC_STAT] 134 bic tmp1, tmp1, #~UDDRC_STAT_SELFREF_TYPE_MSK 135 cmp tmp1, #UDDRC_STAT_SELFREF_TYPE_SW 136 bne sr_ena_2 137 138 ldr tmp2, .sramc_phy_base 139 140 /* Disable DX DLLs for non-backup modes. */ 141 ldr tmp1, .pm_mode 142 cmp tmp1, #AT91_PM_BACKUP 143 beq sr_ena_3 144 145 /* Do not soft reset the AC DLL. */ 146 ldr tmp1, [tmp2, #DDR3PHY_ACDLLCR] 147 bic tmp1, tmp1, #DDR3PHY_ACDLLCR_DLLSRST 148 str tmp1, [tmp2, #DDR3PHY_ACDLLCR] 149 150 /* Disable DX DLLs. */ 151 ldr tmp1, [tmp2, #DDR3PHY_DX0DLLCR] 152 orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS 153 str tmp1, [tmp2, #DDR3PHY_DX0DLLCR] 154 155 ldr tmp1, [tmp2, #DDR3PHY_DX1DLLCR] 156 orr tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS 157 str tmp1, [tmp2, #DDR3PHY_DX1DLLCR] 158 159sr_ena_3: 160 /* Power down DDR PHY data receivers. */ 161 ldr tmp1, [tmp2, #DDR3PHY_DXCCR] 162 orr tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR 163 str tmp1, [tmp2, #DDR3PHY_DXCCR] 164 165 /* Power down ADDR/CMD IO. */ 166 ldr tmp1, [tmp2, #DDR3PHY_ACIOCR] 167 orr tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD 168 orr tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0 169 orr tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0 170 str tmp1, [tmp2, #DDR3PHY_ACIOCR] 171 172 /* Power down ODT. */ 173 ldr tmp1, [tmp2, #DDR3PHY_DSGCR] 174 orr tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0 175 str tmp1, [tmp2, #DDR3PHY_DSGCR] 176.endm 177 178/* 179 * Disable self-refresh 180 * 181 * Side effects: overwrites tmp1, tmp2 182 */ 183.macro at91_sramc_self_refresh_dis 184 ldr tmp2, .sramc_phy_base 185 186 /* Power up DDR PHY data receivers. */ 187 ldr tmp1, [tmp2, #DDR3PHY_DXCCR] 188 bic tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR 189 str tmp1, [tmp2, #DDR3PHY_DXCCR] 190 191 /* Power up the output of CK and CS pins. */ 192 ldr tmp1, [tmp2, #DDR3PHY_ACIOCR] 193 bic tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD 194 bic tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0 195 bic tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0 196 str tmp1, [tmp2, #DDR3PHY_ACIOCR] 197 198 /* Power up ODT. */ 199 ldr tmp1, [tmp2, #DDR3PHY_DSGCR] 200 bic tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0 201 str tmp1, [tmp2, #DDR3PHY_DSGCR] 202 203 /* Enable DX DLLs. */ 204 ldr tmp1, [tmp2, #DDR3PHY_DX0DLLCR] 205 bic tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS 206 str tmp1, [tmp2, #DDR3PHY_DX0DLLCR] 207 208 ldr tmp1, [tmp2, #DDR3PHY_DX1DLLCR] 209 bic tmp1, tmp1, #DDR3PHY_DXDLLCR_DLLDIS 210 str tmp1, [tmp2, #DDR3PHY_DX1DLLCR] 211 212 ldr tmp2, .sramc_base 213 214 /* Enable quasi-dynamic programming. */ 215 mov tmp1, #0 216 str tmp1, [tmp2, #UDDRC_SWCTRL] 217 218 /* De-assert SDRAM initialization. */ 219 ldr tmp1, [tmp2, #UDDRC_DFIMISC] 220 bic tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN 221 str tmp1, [tmp2, #UDDRC_DFIMISC] 222 223 /* Quasi-dynamic programming done. */ 224 mov tmp1, #UDDRC_SWCTRL_SW_DONE 225 str tmp1, [tmp2, #UDDRC_SWCTRL] 226 227sr_dis_1: 228 ldr tmp1, [tmp2, #UDDRC_SWSTAT] 229 tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK 230 beq sr_dis_1 231 232 ldr tmp2, .sramc_phy_base 233 234 /* DLL soft-reset + DLL lock wait + ITM reset */ 235 mov tmp1, #(DDR3PHY_PIR_INIT | DDR3PHY_PIR_DLLSRST | \ 236 DDR3PHY_PIR_DLLLOCK | DDR3PHY_PIR_ITMSRST) 237 str tmp1, [tmp2, #DDR3PHY_PIR] 238 239sr_dis_4: 240 /* Wait for it. */ 241 ldr tmp1, [tmp2, #DDR3PHY_PGSR] 242 tst tmp1, #DDR3PHY_PGSR_IDONE 243 beq sr_dis_4 244 245 ldr tmp2, .sramc_base 246 247 /* Enable quasi-dynamic programming. */ 248 mov tmp1, #0 249 str tmp1, [tmp2, #UDDRC_SWCTRL] 250 251 /* Assert PHY init complete enable signal. */ 252 ldr tmp1, [tmp2, #UDDRC_DFIMISC] 253 orr tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN 254 str tmp1, [tmp2, #UDDRC_DFIMISC] 255 256 /* Programming is done. Set sw_done. */ 257 mov tmp1, #UDDRC_SWCTRL_SW_DONE 258 str tmp1, [tmp2, #UDDRC_SWCTRL] 259 260sr_dis_5: 261 /* Wait for it. */ 262 ldr tmp1, [tmp2, #UDDRC_SWSTAT] 263 tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK 264 beq sr_dis_5 265 266 /* Trigger self-refresh exit. */ 267 ldr tmp1, [tmp2, #UDDRC_PWRCTL] 268 bic tmp1, tmp1, #UDDRC_PWRCTL_SELFREF_SW 269 str tmp1, [tmp2, #UDDRC_PWRCTL] 270 271sr_dis_6: 272 /* Wait for self-refresh exit done. */ 273 ldr tmp1, [tmp2, #UDDRC_STAT] 274 bic tmp1, tmp1, #~UDDRC_STAT_OPMODE_MSK 275 cmp tmp1, #UDDRC_STAT_OPMODE_NORMAL 276 bne sr_dis_6 277 278 /* Enable all AXI ports. */ 279 ldr tmp1, [tmp2, #UDDRC_PCTRL_0] 280 orr tmp1, tmp1, #0x1 281 str tmp1, [tmp2, #UDDRC_PCTRL_0] 282 283 ldr tmp1, [tmp2, #UDDRC_PCTRL_1] 284 orr tmp1, tmp1, #0x1 285 str tmp1, [tmp2, #UDDRC_PCTRL_1] 286 287 ldr tmp1, [tmp2, #UDDRC_PCTRL_2] 288 orr tmp1, tmp1, #0x1 289 str tmp1, [tmp2, #UDDRC_PCTRL_2] 290 291 ldr tmp1, [tmp2, #UDDRC_PCTRL_3] 292 orr tmp1, tmp1, #0x1 293 str tmp1, [tmp2, #UDDRC_PCTRL_3] 294 295 ldr tmp1, [tmp2, #UDDRC_PCTRL_4] 296 orr tmp1, tmp1, #0x1 297 str tmp1, [tmp2, #UDDRC_PCTRL_4] 298 299 dsb 300.endm 301#endif 302 303#define SUSPEND_FUNC(__name) \ 304__name: 305 306#define SUSPEND_END_FUNC(__name) \ 307 .size __name, .-__name 308 309.macro check_fit_in_sram since 310 .if (. - \since) > 0x10000 311 .error "Suspend assembly code exceeds dedicated SRAM size" 312 .endif 313.endm 314 315/* 316 * void at91_suspend_sram_fn(struct at91_pm_data*) 317 * @input param: 318 * @r0: base address of struct at91_pm_data 319 */ 320.align 3 321.global at91_pm_suspend_in_sram 322SUSPEND_FUNC(at91_pm_suspend_in_sram) 323 /* Save registers on stack */ 324 stmfd sp!, {r4 - r12, lr} 325 326 /* Drain write buffer */ 327 mov tmp1, #0 328 mcr p15, 0, tmp1, c7, c10, 4 329 330 ldr tmp1, [r0, #PM_DATA_PMC] 331 str tmp1, .pmc_base 332 ldr tmp1, [r0, #PM_DATA_RAMC0] 333 str tmp1, .sramc_base 334 ldr tmp1, [r0, #PM_DATA_RAMC_PHY] 335 str tmp1, .sramc_phy_base 336 ldr tmp1, [r0, #PM_DATA_MODE] 337 str tmp1, .pm_mode 338 /* Both ldrne below are here to preload their address in the TLB */ 339 ldr tmp1, [r0, #PM_DATA_SHDWC] 340 str tmp1, .shdwc 341 cmp tmp1, #0 342 ldrne tmp2, [tmp1, #0] 343 ldr tmp1, [r0, #PM_DATA_SFRBU] 344 str tmp1, .sfrbu 345 cmp tmp1, #0 346 ldrne tmp2, [tmp1, #0x10] 347 348 /* Active the self-refresh mode */ 349#ifdef CFG_SAMA5D2 350 mov r0, #SRAMC_SELF_FRESH_ACTIVE 351 bl at91_sramc_self_refresh 352#endif 353#ifdef CFG_SAMA7G5 354 at91_sramc_self_refresh_ena 355#endif 356 357 ldr r0, .pm_mode 358 cmp r0, #AT91_PM_STANDBY 359 beq standby 360 cmp r0, #AT91_PM_BACKUP 361 beq backup_mode 362 363 bl at91_ulp_mode 364 b exit_suspend 365 366standby: 367 /* Wait for interrupt */ 368 ldr pmc, .pmc_base 369 at91_cpu_idle 370 b exit_suspend 371 372backup_mode: 373 bl at91_backup_mode 374 b exit_suspend 375 376exit_suspend: 377 /* Exit the self-refresh mode */ 378#ifdef CFG_SAMA5D2 379 mov r0, #SRAMC_SELF_FRESH_EXIT 380 bl at91_sramc_self_refresh 381#endif 382#ifdef CFG_SAMA7G5 383 at91_sramc_self_refresh_dis 384#endif 385 386 /* Restore registers, and return */ 387 ldmfd sp!, {r4 - r12, pc} 388SUSPEND_END_FUNC(at91_pm_suspend_in_sram) 389 390SUSPEND_FUNC(at91_backup_mode) 391 /* Switch the master clock source to slow clock. */ 392 ldr pmc, .pmc_base 393 ldr tmp1, [pmc, #AT91_PMC_MCKR] 394 bic tmp1, tmp1, #AT91_PMC_CSS 395 str tmp1, [pmc, #AT91_PMC_MCKR] 396 397 mov tmp3, #0 398 wait_mckrdy tmp3 399 400 /*BUMEN*/ 401 ldr r0, .sfrbu 402 mov tmp1, #0x1 403 str tmp1, [r0, #0x10] 404 405 /* Shutdown */ 406 ldr r0, .shdwc 407 mov tmp1, #0xA5000000 408 add tmp1, tmp1, #0x1 409#ifdef CFG_SAMA7G5 410 /* LPM Pad Enable: The LPM pad is set high */ 411 orr tmp1, tmp1, #0x200000 412#endif 413 str tmp1, [r0, #0] 414SUSPEND_END_FUNC(at91_backup_mode) 415 416/* 417 * Set LPM 418 * @ena: 0 - disable LPM 419 * 1 - enable LPM 420 * 421 * Side effects: overwrites tmp1, tmp3 422 */ 423.macro at91_set_lpm ena 424#ifdef CFG_SAMA7G5 425 mov tmp1, #\ena 426 cmp tmp1, #1 427 movne tmp3, #0x400000 /* LPM Pad Disable: The LPM pad is set low */ 428 moveq tmp3, #0x200000 /* LPM Pad Enable: The LPM pad is set high */ 429 add tmp3, #0xA5000000 430 ldr tmp1, .shdwc 431 cmp tmp1, #0 432 strne tmp3, [tmp1] 433#endif 434.endm 435 436.macro at91_pm_ulp0_mode 437 ldr pmc, .pmc_base 438 ldr tmp2, .pm_mode 439 440 /* Check if ULP0 fast variant has been requested. */ 441 cmp tmp2, #AT91_PM_ULP0_FAST 442 bne 0f 443 444 /* Set highest prescaler for power saving */ 445 ldr tmp1, [pmc, #AT91_PMC_MCKR] 446 bic tmp1, tmp1, #AT91_PMC_PRES 447 orr tmp1, tmp1, #AT91_PMC_PRES_64 448 str tmp1, [pmc, #AT91_PMC_MCKR] 449 450 mov tmp3, #0 451 wait_mckrdy tmp3 452 b 1f 453 4540: 455 /* Turn off the crystal oscillator */ 456 ldr tmp1, [pmc, #AT91_CKGR_MOR] 457 bic tmp1, tmp1, #AT91_PMC_MOSCEN 458 orr tmp1, tmp1, #AT91_PMC_KEY 459 str tmp1, [pmc, #AT91_CKGR_MOR] 460 461 /* Save RC oscillator state */ 462 ldr tmp1, [pmc, #AT91_PMC_SR] 463 str tmp1, .saved_osc_status 464 tst tmp1, #AT91_PMC_MOSCRCS 465 bne 7f 466 467 /* Turn off RC oscillator */ 468 ldr tmp1, [pmc, #AT91_CKGR_MOR] 469 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 470 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 471 orr tmp1, tmp1, #AT91_PMC_KEY 472 str tmp1, [pmc, #AT91_CKGR_MOR] 473 474 /* Wait main RC disabled done */ 4752: ldr tmp1, [pmc, #AT91_PMC_SR] 476 tst tmp1, #AT91_PMC_MOSCRCS 477 bne 2b 478 479 /* Enable LPM. */ 4807: at91_set_lpm 1 481 482 /* Wait for interrupt */ 4831: at91_cpu_idle 484 485 /* Check if ULP0 fast variant has been requested. */ 486 cmp tmp2, #AT91_PM_ULP0_FAST 487 bne 8f 488 489 /* Set lowest prescaler for fast resume. */ 490 ldr tmp1, [pmc, #AT91_PMC_MCKR] 491 bic tmp1, tmp1, #AT91_PMC_PRES 492 str tmp1, [pmc, #AT91_PMC_MCKR] 493 494 mov tmp3, #0 495 wait_mckrdy tmp3 496 b 6f 497 4988: at91_set_lpm 0 499 5005: /* Restore RC oscillator state */ 501 ldr tmp1, .saved_osc_status 502 tst tmp1, #AT91_PMC_MOSCRCS 503 beq 4f 504 505 /* Turn on RC oscillator */ 506 ldr tmp1, [pmc, #AT91_CKGR_MOR] 507 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 508 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 509 orr tmp1, tmp1, #AT91_PMC_KEY 510 str tmp1, [pmc, #AT91_CKGR_MOR] 511 512 /* Wait main RC stabilization */ 5133: ldr tmp1, [pmc, #AT91_PMC_SR] 514 tst tmp1, #AT91_PMC_MOSCRCS 515 beq 3b 516 517 /* Turn on the crystal oscillator */ 5184: ldr tmp1, [pmc, #AT91_CKGR_MOR] 519 orr tmp1, tmp1, #AT91_PMC_MOSCEN 520 orr tmp1, tmp1, #AT91_PMC_KEY 521 str tmp1, [pmc, #AT91_CKGR_MOR] 522 523 wait_moscrdy 5246: 525.endm 526 527/** 528 * Note: This procedure only applies on the platform which uses 529 * the external crystal oscillator as a main clock source. 530 */ 531.macro at91_pm_ulp1_mode 532 ldr pmc, .pmc_base 533 534 /* Save RC oscillator state and check if it is enabled. */ 535 ldr tmp1, [pmc, #AT91_PMC_SR] 536 str tmp1, .saved_osc_status 537 tst tmp1, #AT91_PMC_MOSCRCS 538 bne 2f 539 540 /* Enable RC oscillator */ 541 ldr tmp1, [pmc, #AT91_CKGR_MOR] 542 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 543 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 544 orr tmp1, tmp1, #AT91_PMC_KEY 545 str tmp1, [pmc, #AT91_CKGR_MOR] 546 547 /* Wait main RC stabilization */ 5481: ldr tmp1, [pmc, #AT91_PMC_SR] 549 tst tmp1, #AT91_PMC_MOSCRCS 550 beq 1b 551 552 /* Switch the main clock source to 12-MHz RC oscillator */ 5532: ldr tmp1, [pmc, #AT91_CKGR_MOR] 554 bic tmp1, tmp1, #AT91_PMC_MOSCSEL 555 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 556 orr tmp1, tmp1, #AT91_PMC_KEY 557 str tmp1, [pmc, #AT91_CKGR_MOR] 558 559 wait_moscsels 560 561 /* Disable the crystal oscillator */ 562 ldr tmp1, [pmc, #AT91_CKGR_MOR] 563 bic tmp1, tmp1, #AT91_PMC_MOSCEN 564 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 565 orr tmp1, tmp1, #AT91_PMC_KEY 566 str tmp1, [pmc, #AT91_CKGR_MOR] 567 568 /* Switch the master clock source to main clock */ 569 ldr tmp1, [pmc, #AT91_PMC_MCKR] 570 bic tmp1, tmp1, #AT91_PMC_CSS 571 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 572 str tmp1, [pmc, #AT91_PMC_MCKR] 573 574 mov tmp3, #0 575 wait_mckrdy tmp3 576 577 /* Enable LPM */ 578 at91_set_lpm 1 579 580 /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */ 581 ldr tmp1, [pmc, #AT91_CKGR_MOR] 582 orr tmp1, tmp1, #AT91_PMC_WAITMODE 583 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 584 orr tmp1, tmp1, #AT91_PMC_KEY 585 str tmp1, [pmc, #AT91_CKGR_MOR] 586 587 /* Quirk for SAM9X60's PMC */ 588 nop 589 nop 590 591 mov tmp3, #0 592 wait_mckrdy tmp3 593 594 /* Disable LPM. */ 595 at91_set_lpm 0 596 597 /* Enable the crystal oscillator */ 598 ldr tmp1, [pmc, #AT91_CKGR_MOR] 599 orr tmp1, tmp1, #AT91_PMC_MOSCEN 600 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 601 orr tmp1, tmp1, #AT91_PMC_KEY 602 str tmp1, [pmc, #AT91_CKGR_MOR] 603 604 wait_moscrdy 605 606 /* Switch the master clock source to slow clock */ 607 ldr tmp1, [pmc, #AT91_PMC_MCKR] 608 bic tmp1, tmp1, #AT91_PMC_CSS 609 str tmp1, [pmc, #AT91_PMC_MCKR] 610 611 mov tmp3, #0 612 wait_mckrdy tmp3 613 614 /* Switch main clock source to crystal oscillator */ 615 ldr tmp1, [pmc, #AT91_CKGR_MOR] 616 orr tmp1, tmp1, #AT91_PMC_MOSCSEL 617 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 618 orr tmp1, tmp1, #AT91_PMC_KEY 619 str tmp1, [pmc, #AT91_CKGR_MOR] 620 621 wait_moscsels 622 623 /* Switch the master clock source to main clock */ 624 ldr tmp1, [pmc, #AT91_PMC_MCKR] 625 bic tmp1, tmp1, #AT91_PMC_CSS 626 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 627 str tmp1, [pmc, #AT91_PMC_MCKR] 628 629 wait_mckrdy tmp3 630 631 /* Restore RC oscillator state */ 632 ldr tmp1, .saved_osc_status 633 tst tmp1, #AT91_PMC_MOSCRCS 634 bne 3f 635 636 /* Disable RC oscillator */ 637 ldr tmp1, [pmc, #AT91_CKGR_MOR] 638 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 639 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 640 orr tmp1, tmp1, #AT91_PMC_KEY 641 str tmp1, [pmc, #AT91_CKGR_MOR] 642 643 /* Wait RC oscillator disable done */ 6444: ldr tmp1, [pmc, #AT91_PMC_SR] 645 tst tmp1, #AT91_PMC_MOSCRCS 646 bne 4b 647 6483: 649.endm 650 651/* 652 * Save PLLA setting and disable it 653 * 654 * Side effects: overwrites tmp1, tmp2 655 */ 656.macro at91_plla_disable 657#ifdef CFG_SAMA7G5 658 /* Save PLLA settings */ 659 ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT] 660 bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID 661 str tmp2, [pmc, #AT91_PMC_PLL_UPDT] 662 663 /* save div */ 664 mov tmp1, #0 665 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0] 666 bic tmp2, tmp2, #0xffffff00 667 orr tmp1, tmp1, tmp2 668 669 /* save mul */ 670 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1] 671 bic tmp2, tmp2, #0xffffff 672 orr tmp1, tmp1, tmp2 673 str tmp1, .saved_pllar 674 675 /* step 2 */ 676 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 677 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 678 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 679 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 680 681 /* step 3 */ 682 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 683 bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK 684 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 685 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 686 687 /* step 4 */ 688 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 689 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 690 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 691 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 692 693 /* step 5 */ 694 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 695 bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 696 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 697 698 /* step 6 */ 699 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 700 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 701 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 702 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 703#else 704 /* Save PLLA setting and disable it */ 705 ldr tmp1, [pmc, #AT91_CKGR_PLLAR] 706 str tmp1, .saved_pllar 707 708 /* Disable PLLA. */ 709 mov tmp1, #AT91_PMC_PLLCOUNT 710 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ 711 str tmp1, [pmc, #AT91_CKGR_PLLAR] 712#endif 7132: 714.endm 715 716/* 717 * Enable PLLA with the saved setting 718 * 719 * Side effects: overwrites tmp1, tmp2 720 */ 721.macro at91_plla_enable 722#ifdef CFG_SAMA7G5 723 /* step 1 */ 724 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 725 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 726 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 727 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 728 729 /* step 2 */ 730 ldr tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA 731 str tmp1, [pmc, #AT91_PMC_PLL_ACR] 732 733 /* step 3 */ 734 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1] 735 ldr tmp2, .saved_pllar 736 bic tmp2, tmp2, #0xffffff 737 orr tmp1, tmp1, tmp2 738 str tmp1, [pmc, #AT91_PMC_PLL_CTRL1] 739 740 /* step 4 */ 741 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 742 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 743 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 744 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 745 746 /* step 5 */ 747 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 748 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK 749 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 750 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK 751 bic tmp1, tmp1, #0xff 752 ldr tmp2, .saved_pllar 753 bic tmp2, tmp2, #0xffffff00 754 orr tmp1, tmp1, tmp2 755 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 756 757 /* step 6 */ 758 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 759 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 760 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 761 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 762 763 /* step 7 */ 7643: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0] 765 tst tmp1, #0x1 766 beq 3b 767#else 768 ldr tmp2, .saved_pllar 769 770 /* Restore PLLA setting */ 771 str tmp2, [pmc, #AT91_CKGR_PLLAR] 772 773 /* Enable PLLA. */ 774 tst tmp2, #(AT91_PMC_MUL & 0xff0000) 775 bne 1f 776 tst tmp2, #(AT91_PMC_MUL & ~0xff0000) 777 beq 2f 778 7791: ldr tmp1, [pmc, #AT91_PMC_SR] 780 tst tmp1, #AT91_PMC_LOCKA 781 beq 1b 7822: 783#endif 784.endm 785 786#ifdef CFG_SAMA7G5 787/* 788 * at91_mckx_ps_enable: save MCK1..4 settings and switch it to main clock 789 * 790 * Side effects: overwrites tmp1, tmp2, tmp3 791 */ 792.macro at91_mckx_ps_enable 793 ldr pmc, .pmc_base 794 795 /* There are 4 MCKs we need to handle: MCK1..4 */ 796 mov tmp1, #1 797e_loop: 798 /* Write MCK ID to retrieve the settings */ 799 str tmp1, [pmc, #AT91_PMC_MCR_V2] 800 ldr tmp2, [pmc, #AT91_PMC_MCR_V2] 801 802 cmp tmp1, #1 803 streq tmp2, .saved_mck1 804 cmp tmp1, #2 805 streq tmp2, .saved_mck2 806 cmp tmp1, #3 807 streq tmp2, .saved_mck3 808 cmp tmp1, #4 809 streq tmp2, .saved_mck4 810 811 /* Use CSS=MD_SLOW_CLK and DIV=64. */ 812 bic tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MASK 813 bic tmp2, tmp2, #AT91_PMC_MCR_V2_DIV_MASK 814 orr tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MD_SLCK 815 orr tmp2, tmp2, #AT91_PMC_MCR_V2_DIV64 816 orr tmp2, tmp2, #AT91_PMC_MCR_V2_CMD 817 str tmp2, [pmc, #AT91_PMC_MCR_V2] 818 819 mov tmp2, tmp1 820 wait_mckrdy tmp1 821 mov tmp1, tmp2 822 823 add tmp1, tmp1, #1 824 cmp tmp1, #5 825 bne e_loop 826.endm 827 828/* 829 * at91_mckx_ps_restore: restore MCK1..4 settings 830 * 831 * Side effects: overwrites tmp1, tmp2, tmp3 832 */ 833.macro at91_mckx_ps_restore 834 ldr pmc, .pmc_base 835 836 /* There are 4 MCKs we need to handle: MCK1..4 */ 837 mov tmp1, #1 838 ldr tmp2, .saved_mck1 839r_loop: 840 cmp tmp1, #2 841 ldreq tmp2, .saved_mck2 842 cmp tmp1, #3 843 ldreq tmp2, .saved_mck3 844 cmp tmp1, #4 845 ldreq tmp2, .saved_mck4 846 847 /* Write MCK ID to retrieve the settings */ 848 str tmp1, [pmc, #AT91_PMC_MCR_V2] 849 ldr tmp3, [pmc, #AT91_PMC_MCR_V2] 850 851 /* We need to restore CSS and DIV. */ 852 bic tmp3, tmp3, #AT91_PMC_MCR_V2_CSS_MASK 853 bic tmp3, tmp3, #AT91_PMC_MCR_V2_DIV_MASK 854 orr tmp3, tmp3, tmp2 855 bic tmp3, tmp3, #AT91_PMC_MCR_V2_ID_MASK 856 orr tmp3, tmp3, tmp1 857 orr tmp3, tmp3, #AT91_PMC_MCR_V2_CMD 858 str tmp3, [pmc, #AT91_PMC_MCR_V2] 859 860 mov tmp2, tmp1 861 wait_mckrdy tmp1 862 mov tmp1, tmp2 863 864 add tmp1, tmp1, #1 865 cmp tmp1, #5 866 bne r_loop 867.endm 868#endif 869 870SUSPEND_FUNC(at91_ulp_mode) 871#ifdef CFG_SAMA7G5 872 at91_mckx_ps_enable 873#endif 874 875 ldr pmc, .pmc_base 876 ldr tmp3, .pm_mode 877 878 /* Save Master clock setting */ 879 ldr tmp1, [pmc, #AT91_PMC_MCKR] 880 str tmp1, .saved_mckr 881 882 /* 883 * Set master clock source to: 884 * - MAINCK if using ULP0 fast variant 885 * - slow clock, otherwise 886 */ 887 bic tmp1, tmp1, #AT91_PMC_CSS 888 cmp tmp3, #AT91_PM_ULP0_FAST 889 bne save_mck 890 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 891save_mck: 892 str tmp1, [pmc, #AT91_PMC_MCKR] 893 894 mov tmp3, #0 895 wait_mckrdy tmp3 896 897 at91_plla_disable 898 899 ldr tmp3, .pm_mode 900 cmp tmp3, #AT91_PM_ULP1 901 beq ulp1_mode 902 903 at91_pm_ulp0_mode 904 b ulp_exit 905 906ulp1_mode: 907 at91_pm_ulp1_mode 908 b ulp_exit 909 910ulp_exit: 911 ldr pmc, .pmc_base 912 913 at91_plla_enable 914 915 /* 916 * Restore master clock setting 917 */ 918 ldr tmp2, .saved_mckr 919 str tmp2, [pmc, #AT91_PMC_MCKR] 920 921 mov tmp3, #0 922 wait_mckrdy tmp3 923 924#ifdef CFG_SAMA7G5 925 at91_mckx_ps_restore 926#endif 927 928 mov pc, lr 929SUSPEND_END_FUNC(at91_ulp_mode) 930 931#ifdef CFG_SAMA5D2 932/* 933 * void at91_sramc_self_refresh(unsigned int is_active) 934 * 935 * @input param: 936 * @r0: 1 - active self-refresh mode 937 * 0 - exit self-refresh mode 938 * register usage: 939 * @r2: base address of the sram controller 940 */ 941 942SUSPEND_FUNC(at91_sramc_self_refresh) 943 ldr r2, .sramc_base 944 945 /* 946 * DDR Memory controller 947 */ 948 tst r0, #SRAMC_SELF_FRESH_ACTIVE 949 beq ddrc_exit_sf 950 951 /* LPDDR1 --> force DDR2 mode during self-refresh */ 952 ldr r3, [r2, #AT91_DDRSDRC_MDR] 953 str r3, .saved_sam9_mdr 954 bic r3, r3, #~AT91_DDRSDRC_MD 955 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 956 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 957 biceq r3, r3, #AT91_DDRSDRC_MD 958 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 959 streq r3, [r2, #AT91_DDRSDRC_MDR] 960 961 /* Active DDRC self-refresh mode */ 962 ldr r3, [r2, #AT91_DDRSDRC_LPR] 963 str r3, .saved_sam9_lpr 964 bic r3, r3, #AT91_DDRSDRC_LPCB 965 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 966 str r3, [r2, #AT91_DDRSDRC_LPR] 967 968 b exit_sramc_sf 969 970ddrc_exit_sf: 971 /* Restore MDR in case of LPDDR1 */ 972 ldr r3, .saved_sam9_mdr 973 str r3, [r2, #AT91_DDRSDRC_MDR] 974 /* Restore LPR on AT91 with DDRAM */ 975 ldr r3, .saved_sam9_lpr 976 str r3, [r2, #AT91_DDRSDRC_LPR] 977 978exit_sramc_sf: 979 mov pc, lr 980SUSPEND_END_FUNC(at91_sramc_self_refresh) 981#endif 982 983.pmc_base: 984 .word 0 985.sramc_base: 986 .word 0 987.sramc_phy_base: 988 .word 0 989.shdwc: 990 .word 0 991.sfrbu: 992 .word 0 993.pm_mode: 994 .word 0 995.saved_mckr: 996 .word 0 997.saved_pllar: 998 .word 0 999.saved_sam9_lpr: 1000 .word 0 1001.saved_sam9_mdr: 1002 .word 0 1003.saved_osc_status: 1004 .word 0 1005#ifdef CFG_SAMA7G5 1006.saved_mck1: 1007 .word 0 1008.saved_mck2: 1009 .word 0 1010.saved_mck3: 1011 .word 0 1012.saved_mck4: 1013 .word 0 1014#endif 1015 1016.global at91_pm_suspend_in_sram_sz 1017at91_pm_suspend_in_sram_sz: 1018 .word .-at91_pm_suspend_in_sram 1019 1020check_fit_in_sram at91_pm_suspend_in_sram 1021