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 write_tlbiall 331 isb 332 333 /* 334 * ldrne below are here to preload their address in the TLB as access 335 * to RAM may be limited while in self-refresh. 336 */ 337 ldr tmp1, [r0, #PM_DATA_PMC] 338 str tmp1, .pmc_base 339 cmp tmp1, #0 340 ldrne tmp2, [tmp1, #0] 341 342 ldr tmp1, [r0, #PM_DATA_RAMC0] 343 str tmp1, .sramc_base 344 cmp tmp1, #0 345 ldrne tmp2, [tmp1, #0] 346 347 ldr tmp1, [r0, #PM_DATA_RAMC_PHY] 348 str tmp1, .sramc_phy_base 349 cmp tmp1, #0 350 ldrne tmp2, [tmp1, #0] 351 352 ldr tmp1, [r0, #PM_DATA_MODE] 353 str tmp1, .pm_mode 354 /* Both ldrne below are here to preload their address in the TLB */ 355 ldr tmp1, [r0, #PM_DATA_SHDWC] 356 str tmp1, .shdwc 357 cmp tmp1, #0 358 ldrne tmp2, [tmp1, #0] 359 ldr tmp1, [r0, #PM_DATA_SFRBU] 360 str tmp1, .sfrbu 361 cmp tmp1, #0 362 ldrne tmp2, [tmp1, #0x10] 363 364 /* Active the self-refresh mode */ 365#ifdef CFG_SAMA5D2 366 mov r0, #SRAMC_SELF_FRESH_ACTIVE 367 bl at91_sramc_self_refresh 368#endif 369#ifdef CFG_SAMA7G5 370 at91_sramc_self_refresh_ena 371#endif 372 373 ldr r0, .pm_mode 374 cmp r0, #AT91_PM_STANDBY 375 beq standby 376 cmp r0, #AT91_PM_BACKUP 377 beq backup_mode 378 379 bl at91_ulp_mode 380 b exit_suspend 381 382standby: 383 /* Wait for interrupt */ 384 ldr pmc, .pmc_base 385 at91_cpu_idle 386 b exit_suspend 387 388backup_mode: 389 bl at91_backup_mode 390 b exit_suspend 391 392exit_suspend: 393 /* Exit the self-refresh mode */ 394#ifdef CFG_SAMA5D2 395 mov r0, #SRAMC_SELF_FRESH_EXIT 396 bl at91_sramc_self_refresh 397#endif 398#ifdef CFG_SAMA7G5 399 at91_sramc_self_refresh_dis 400#endif 401 402 /* Restore registers, and return */ 403 ldmfd sp!, {r4 - r12, pc} 404SUSPEND_END_FUNC(at91_pm_suspend_in_sram) 405 406SUSPEND_FUNC(at91_backup_mode) 407 /* Switch the master clock source to slow clock. */ 408 ldr pmc, .pmc_base 409 ldr tmp1, [pmc, #AT91_PMC_MCKR] 410 bic tmp1, tmp1, #AT91_PMC_CSS 411 str tmp1, [pmc, #AT91_PMC_MCKR] 412 413 mov tmp3, #0 414 wait_mckrdy tmp3 415 416 /*BUMEN*/ 417 ldr r0, .sfrbu 418 mov tmp1, #0x1 419 str tmp1, [r0, #0x10] 420 421 /* Shutdown */ 422 ldr r0, .shdwc 423 mov tmp1, #0xA5000000 424 add tmp1, tmp1, #0x1 425#ifdef CFG_SAMA7G5 426 /* LPM Pad Enable: The LPM pad is set high */ 427 orr tmp1, tmp1, #0x200000 428#endif 429 str tmp1, [r0, #0] 430SUSPEND_END_FUNC(at91_backup_mode) 431 432/* 433 * Set LPM 434 * @ena: 0 - disable LPM 435 * 1 - enable LPM 436 * 437 * Side effects: overwrites tmp1, tmp3 438 */ 439.macro at91_set_lpm ena 440#ifdef CFG_SAMA7G5 441 mov tmp1, #\ena 442 cmp tmp1, #1 443 movne tmp3, #0x400000 /* LPM Pad Disable: The LPM pad is set low */ 444 moveq tmp3, #0x200000 /* LPM Pad Enable: The LPM pad is set high */ 445 add tmp3, #0xA5000000 446 ldr tmp1, .shdwc 447 cmp tmp1, #0 448 strne tmp3, [tmp1] 449#endif 450.endm 451 452.macro at91_pm_ulp0_mode 453 ldr pmc, .pmc_base 454 ldr tmp2, .pm_mode 455 456 /* Check if ULP0 fast variant has been requested. */ 457 cmp tmp2, #AT91_PM_ULP0_FAST 458 bne 0f 459 460 /* Set highest prescaler for power saving */ 461 ldr tmp1, [pmc, #AT91_PMC_MCKR] 462 bic tmp1, tmp1, #AT91_PMC_PRES 463 orr tmp1, tmp1, #AT91_PMC_PRES_64 464 str tmp1, [pmc, #AT91_PMC_MCKR] 465 466 mov tmp3, #0 467 wait_mckrdy tmp3 468 b 1f 469 4700: 471 /* Turn off the crystal oscillator */ 472 ldr tmp1, [pmc, #AT91_CKGR_MOR] 473 bic tmp1, tmp1, #AT91_PMC_MOSCEN 474 orr tmp1, tmp1, #AT91_PMC_KEY 475 str tmp1, [pmc, #AT91_CKGR_MOR] 476 477 /* Save RC oscillator state */ 478 ldr tmp1, [pmc, #AT91_PMC_SR] 479 str tmp1, .saved_osc_status 480 tst tmp1, #AT91_PMC_MOSCRCS 481 bne 7f 482 483 /* Turn off RC oscillator */ 484 ldr tmp1, [pmc, #AT91_CKGR_MOR] 485 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 486 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 487 orr tmp1, tmp1, #AT91_PMC_KEY 488 str tmp1, [pmc, #AT91_CKGR_MOR] 489 490 /* Wait main RC disabled done */ 4912: ldr tmp1, [pmc, #AT91_PMC_SR] 492 tst tmp1, #AT91_PMC_MOSCRCS 493 bne 2b 494 495 /* Enable LPM. */ 4967: at91_set_lpm 1 497 498 /* Wait for interrupt */ 4991: at91_cpu_idle 500 501 /* Check if ULP0 fast variant has been requested. */ 502 cmp tmp2, #AT91_PM_ULP0_FAST 503 bne 8f 504 505 /* Set lowest prescaler for fast resume. */ 506 ldr tmp1, [pmc, #AT91_PMC_MCKR] 507 bic tmp1, tmp1, #AT91_PMC_PRES 508 str tmp1, [pmc, #AT91_PMC_MCKR] 509 510 mov tmp3, #0 511 wait_mckrdy tmp3 512 b 6f 513 5148: at91_set_lpm 0 515 5165: /* Restore RC oscillator state */ 517 ldr tmp1, .saved_osc_status 518 tst tmp1, #AT91_PMC_MOSCRCS 519 beq 4f 520 521 /* Turn on RC oscillator */ 522 ldr tmp1, [pmc, #AT91_CKGR_MOR] 523 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 524 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 525 orr tmp1, tmp1, #AT91_PMC_KEY 526 str tmp1, [pmc, #AT91_CKGR_MOR] 527 528 /* Wait main RC stabilization */ 5293: ldr tmp1, [pmc, #AT91_PMC_SR] 530 tst tmp1, #AT91_PMC_MOSCRCS 531 beq 3b 532 533 /* Turn on the crystal oscillator */ 5344: ldr tmp1, [pmc, #AT91_CKGR_MOR] 535 orr tmp1, tmp1, #AT91_PMC_MOSCEN 536 orr tmp1, tmp1, #AT91_PMC_KEY 537 str tmp1, [pmc, #AT91_CKGR_MOR] 538 539 wait_moscrdy 5406: 541.endm 542 543/** 544 * Note: This procedure only applies on the platform which uses 545 * the external crystal oscillator as a main clock source. 546 */ 547.macro at91_pm_ulp1_mode 548 ldr pmc, .pmc_base 549 550 /* Save RC oscillator state and check if it is enabled. */ 551 ldr tmp1, [pmc, #AT91_PMC_SR] 552 str tmp1, .saved_osc_status 553 tst tmp1, #AT91_PMC_MOSCRCS 554 bne 2f 555 556 /* Enable RC oscillator */ 557 ldr tmp1, [pmc, #AT91_CKGR_MOR] 558 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 559 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 560 orr tmp1, tmp1, #AT91_PMC_KEY 561 str tmp1, [pmc, #AT91_CKGR_MOR] 562 563 /* Wait main RC stabilization */ 5641: ldr tmp1, [pmc, #AT91_PMC_SR] 565 tst tmp1, #AT91_PMC_MOSCRCS 566 beq 1b 567 568 /* Switch the main clock source to 12-MHz RC oscillator */ 5692: ldr tmp1, [pmc, #AT91_CKGR_MOR] 570 bic tmp1, tmp1, #AT91_PMC_MOSCSEL 571 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 572 orr tmp1, tmp1, #AT91_PMC_KEY 573 str tmp1, [pmc, #AT91_CKGR_MOR] 574 575 wait_moscsels 576 577 /* Disable the crystal oscillator */ 578 ldr tmp1, [pmc, #AT91_CKGR_MOR] 579 bic tmp1, tmp1, #AT91_PMC_MOSCEN 580 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 581 orr tmp1, tmp1, #AT91_PMC_KEY 582 str tmp1, [pmc, #AT91_CKGR_MOR] 583 584 /* Switch the master clock source to main clock */ 585 ldr tmp1, [pmc, #AT91_PMC_MCKR] 586 bic tmp1, tmp1, #AT91_PMC_CSS 587 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 588 str tmp1, [pmc, #AT91_PMC_MCKR] 589 590 mov tmp3, #0 591 wait_mckrdy tmp3 592 593 /* Enable LPM */ 594 at91_set_lpm 1 595 596 /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */ 597 ldr tmp1, [pmc, #AT91_CKGR_MOR] 598 orr tmp1, tmp1, #AT91_PMC_WAITMODE 599 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 600 orr tmp1, tmp1, #AT91_PMC_KEY 601 str tmp1, [pmc, #AT91_CKGR_MOR] 602 603 /* Quirk for SAM9X60's PMC */ 604 nop 605 nop 606 607 mov tmp3, #0 608 wait_mckrdy tmp3 609 610 /* Disable LPM. */ 611 at91_set_lpm 0 612 613 /* Enable the crystal oscillator */ 614 ldr tmp1, [pmc, #AT91_CKGR_MOR] 615 orr tmp1, tmp1, #AT91_PMC_MOSCEN 616 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 617 orr tmp1, tmp1, #AT91_PMC_KEY 618 str tmp1, [pmc, #AT91_CKGR_MOR] 619 620 wait_moscrdy 621 622 /* Switch the master clock source to slow clock */ 623 ldr tmp1, [pmc, #AT91_PMC_MCKR] 624 bic tmp1, tmp1, #AT91_PMC_CSS 625 str tmp1, [pmc, #AT91_PMC_MCKR] 626 627 mov tmp3, #0 628 wait_mckrdy tmp3 629 630 /* Switch main clock source to crystal oscillator */ 631 ldr tmp1, [pmc, #AT91_CKGR_MOR] 632 orr tmp1, tmp1, #AT91_PMC_MOSCSEL 633 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 634 orr tmp1, tmp1, #AT91_PMC_KEY 635 str tmp1, [pmc, #AT91_CKGR_MOR] 636 637 wait_moscsels 638 639 /* Switch the master clock source to main clock */ 640 ldr tmp1, [pmc, #AT91_PMC_MCKR] 641 bic tmp1, tmp1, #AT91_PMC_CSS 642 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 643 str tmp1, [pmc, #AT91_PMC_MCKR] 644 645 wait_mckrdy tmp3 646 647 /* Restore RC oscillator state */ 648 ldr tmp1, .saved_osc_status 649 tst tmp1, #AT91_PMC_MOSCRCS 650 bne 3f 651 652 /* Disable RC oscillator */ 653 ldr tmp1, [pmc, #AT91_CKGR_MOR] 654 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 655 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 656 orr tmp1, tmp1, #AT91_PMC_KEY 657 str tmp1, [pmc, #AT91_CKGR_MOR] 658 659 /* Wait RC oscillator disable done */ 6604: ldr tmp1, [pmc, #AT91_PMC_SR] 661 tst tmp1, #AT91_PMC_MOSCRCS 662 bne 4b 663 6643: 665.endm 666 667/* 668 * Save PLLA setting and disable it 669 * 670 * Side effects: overwrites tmp1, tmp2 671 */ 672.macro at91_plla_disable 673#ifdef CFG_SAMA7G5 674 /* Save PLLA settings */ 675 ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT] 676 bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID 677 str tmp2, [pmc, #AT91_PMC_PLL_UPDT] 678 679 /* save div */ 680 mov tmp1, #0 681 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL0] 682 bic tmp2, tmp2, #0xffffff00 683 orr tmp1, tmp1, tmp2 684 685 /* save mul */ 686 ldr tmp2, [pmc, #AT91_PMC_PLL_CTRL1] 687 bic tmp2, tmp2, #0xffffff 688 orr tmp1, tmp1, tmp2 689 str tmp1, .saved_pllar 690 691 /* step 2 */ 692 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 693 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 694 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 695 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 696 697 /* step 3 */ 698 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 699 bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK 700 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 701 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 702 703 /* step 4 */ 704 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 705 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 706 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 707 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 708 709 /* step 5 */ 710 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 711 bic tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 712 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 713 714 /* step 6 */ 715 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 716 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 717 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 718 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 719#else 720 /* Save PLLA setting and disable it */ 721 ldr tmp1, [pmc, #AT91_CKGR_PLLAR] 722 str tmp1, .saved_pllar 723 724 /* Disable PLLA. */ 725 mov tmp1, #AT91_PMC_PLLCOUNT 726 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ 727 str tmp1, [pmc, #AT91_CKGR_PLLAR] 728#endif 7292: 730.endm 731 732/* 733 * Enable PLLA with the saved setting 734 * 735 * Side effects: overwrites tmp1, tmp2 736 */ 737.macro at91_plla_enable 738#ifdef CFG_SAMA7G5 739 /* step 1 */ 740 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 741 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 742 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 743 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 744 745 /* step 2 */ 746 ldr tmp1, =AT91_PMC_PLL_ACR_DEFAULT_PLLA 747 str tmp1, [pmc, #AT91_PMC_PLL_ACR] 748 749 /* step 3 */ 750 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL1] 751 ldr tmp2, .saved_pllar 752 bic tmp2, tmp2, #0xffffff 753 orr tmp1, tmp1, tmp2 754 str tmp1, [pmc, #AT91_PMC_PLL_CTRL1] 755 756 /* step 4 */ 757 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 758 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 759 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 760 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 761 762 /* step 5 */ 763 ldr tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 764 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENLOCK 765 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLL 766 orr tmp1, tmp1, #AT91_PMC_PLL_CTRL0_ENPLLCK 767 bic tmp1, tmp1, #0xff 768 ldr tmp2, .saved_pllar 769 bic tmp2, tmp2, #0xffffff00 770 orr tmp1, tmp1, tmp2 771 str tmp1, [pmc, #AT91_PMC_PLL_CTRL0] 772 773 /* step 6 */ 774 ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] 775 orr tmp1, tmp1, #AT91_PMC_PLL_UPDT_UPDATE 776 bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID 777 str tmp1, [pmc, #AT91_PMC_PLL_UPDT] 778 779 /* step 7 */ 7803: ldr tmp1, [pmc, #AT91_PMC_PLL_ISR0] 781 tst tmp1, #0x1 782 beq 3b 783#else 784 ldr tmp2, .saved_pllar 785 786 /* Restore PLLA setting */ 787 str tmp2, [pmc, #AT91_CKGR_PLLAR] 788 789 /* Enable PLLA. */ 790 tst tmp2, #(AT91_PMC_MUL & 0xff0000) 791 bne 1f 792 tst tmp2, #(AT91_PMC_MUL & ~0xff0000) 793 beq 2f 794 7951: ldr tmp1, [pmc, #AT91_PMC_SR] 796 tst tmp1, #AT91_PMC_LOCKA 797 beq 1b 7982: 799#endif 800.endm 801 802#ifdef CFG_SAMA7G5 803/* 804 * at91_mckx_ps_enable: save MCK1..4 settings and switch it to main clock 805 * 806 * Side effects: overwrites tmp1, tmp2, tmp3 807 */ 808.macro at91_mckx_ps_enable 809 ldr pmc, .pmc_base 810 811 /* There are 4 MCKs we need to handle: MCK1..4 */ 812 mov tmp1, #1 813e_loop: 814 /* Write MCK ID to retrieve the settings */ 815 str tmp1, [pmc, #AT91_PMC_MCR_V2] 816 ldr tmp2, [pmc, #AT91_PMC_MCR_V2] 817 818 cmp tmp1, #1 819 streq tmp2, .saved_mck1 820 cmp tmp1, #2 821 streq tmp2, .saved_mck2 822 cmp tmp1, #3 823 streq tmp2, .saved_mck3 824 cmp tmp1, #4 825 streq tmp2, .saved_mck4 826 827 /* Use CSS=MD_SLOW_CLK and DIV=64. */ 828 bic tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MASK 829 bic tmp2, tmp2, #AT91_PMC_MCR_V2_DIV_MASK 830 orr tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MD_SLCK 831 orr tmp2, tmp2, #AT91_PMC_MCR_V2_DIV64 832 orr tmp2, tmp2, #AT91_PMC_MCR_V2_CMD 833 str tmp2, [pmc, #AT91_PMC_MCR_V2] 834 835 mov tmp2, tmp1 836 wait_mckrdy tmp1 837 mov tmp1, tmp2 838 839 add tmp1, tmp1, #1 840 cmp tmp1, #5 841 bne e_loop 842.endm 843 844/* 845 * at91_mckx_ps_restore: restore MCK1..4 settings 846 * 847 * Side effects: overwrites tmp1, tmp2, tmp3 848 */ 849.macro at91_mckx_ps_restore 850 ldr pmc, .pmc_base 851 852 /* There are 4 MCKs we need to handle: MCK1..4 */ 853 mov tmp1, #1 854 ldr tmp2, .saved_mck1 855r_loop: 856 cmp tmp1, #2 857 ldreq tmp2, .saved_mck2 858 cmp tmp1, #3 859 ldreq tmp2, .saved_mck3 860 cmp tmp1, #4 861 ldreq tmp2, .saved_mck4 862 863 /* Write MCK ID to retrieve the settings */ 864 str tmp1, [pmc, #AT91_PMC_MCR_V2] 865 ldr tmp3, [pmc, #AT91_PMC_MCR_V2] 866 867 /* We need to restore CSS and DIV. */ 868 bic tmp3, tmp3, #AT91_PMC_MCR_V2_CSS_MASK 869 bic tmp3, tmp3, #AT91_PMC_MCR_V2_DIV_MASK 870 orr tmp3, tmp3, tmp2 871 bic tmp3, tmp3, #AT91_PMC_MCR_V2_ID_MASK 872 orr tmp3, tmp3, tmp1 873 orr tmp3, tmp3, #AT91_PMC_MCR_V2_CMD 874 str tmp3, [pmc, #AT91_PMC_MCR_V2] 875 876 mov tmp2, tmp1 877 wait_mckrdy tmp1 878 mov tmp1, tmp2 879 880 add tmp1, tmp1, #1 881 cmp tmp1, #5 882 bne r_loop 883.endm 884#endif 885 886SUSPEND_FUNC(at91_ulp_mode) 887#ifdef CFG_SAMA7G5 888 at91_mckx_ps_enable 889#endif 890 891 ldr pmc, .pmc_base 892 ldr tmp3, .pm_mode 893 894 /* Save Master clock setting */ 895 ldr tmp1, [pmc, #AT91_PMC_MCKR] 896 str tmp1, .saved_mckr 897 898 /* 899 * Set master clock source to: 900 * - MAINCK if using ULP0 fast variant 901 * - slow clock, otherwise 902 */ 903 bic tmp1, tmp1, #AT91_PMC_CSS 904 cmp tmp3, #AT91_PM_ULP0_FAST 905 bne save_mck 906 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 907save_mck: 908 str tmp1, [pmc, #AT91_PMC_MCKR] 909 910 mov tmp3, #0 911 wait_mckrdy tmp3 912 913 at91_plla_disable 914 915 ldr tmp3, .pm_mode 916 cmp tmp3, #AT91_PM_ULP1 917 beq ulp1_mode 918 919 at91_pm_ulp0_mode 920 b ulp_exit 921 922ulp1_mode: 923 at91_pm_ulp1_mode 924 b ulp_exit 925 926ulp_exit: 927 ldr pmc, .pmc_base 928 929 at91_plla_enable 930 931 /* 932 * Restore master clock setting 933 */ 934 ldr tmp2, .saved_mckr 935 str tmp2, [pmc, #AT91_PMC_MCKR] 936 937 mov tmp3, #0 938 wait_mckrdy tmp3 939 940#ifdef CFG_SAMA7G5 941 at91_mckx_ps_restore 942#endif 943 944 mov pc, lr 945SUSPEND_END_FUNC(at91_ulp_mode) 946 947#ifdef CFG_SAMA5D2 948/* 949 * void at91_sramc_self_refresh(unsigned int is_active) 950 * 951 * @input param: 952 * @r0: 1 - active self-refresh mode 953 * 0 - exit self-refresh mode 954 * register usage: 955 * @r2: base address of the sram controller 956 */ 957 958SUSPEND_FUNC(at91_sramc_self_refresh) 959 ldr r2, .sramc_base 960 961 /* 962 * DDR Memory controller 963 */ 964 tst r0, #SRAMC_SELF_FRESH_ACTIVE 965 beq ddrc_exit_sf 966 967 /* LPDDR1 --> force DDR2 mode during self-refresh */ 968 ldr r3, [r2, #AT91_DDRSDRC_MDR] 969 str r3, .saved_sam9_mdr 970 bic r3, r3, #~AT91_DDRSDRC_MD 971 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 972 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 973 biceq r3, r3, #AT91_DDRSDRC_MD 974 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 975 streq r3, [r2, #AT91_DDRSDRC_MDR] 976 977 /* Active DDRC self-refresh mode */ 978 ldr r3, [r2, #AT91_DDRSDRC_LPR] 979 str r3, .saved_sam9_lpr 980 bic r3, r3, #AT91_DDRSDRC_LPCB 981 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 982 str r3, [r2, #AT91_DDRSDRC_LPR] 983 984 b exit_sramc_sf 985 986ddrc_exit_sf: 987 /* Restore MDR in case of LPDDR1 */ 988 ldr r3, .saved_sam9_mdr 989 str r3, [r2, #AT91_DDRSDRC_MDR] 990 /* Restore LPR on AT91 with DDRAM */ 991 ldr r3, .saved_sam9_lpr 992 str r3, [r2, #AT91_DDRSDRC_LPR] 993 994exit_sramc_sf: 995 mov pc, lr 996SUSPEND_END_FUNC(at91_sramc_self_refresh) 997#endif 998 999.pmc_base: 1000 .word 0 1001.sramc_base: 1002 .word 0 1003.sramc_phy_base: 1004 .word 0 1005.shdwc: 1006 .word 0 1007.sfrbu: 1008 .word 0 1009.pm_mode: 1010 .word 0 1011.saved_mckr: 1012 .word 0 1013.saved_pllar: 1014 .word 0 1015.saved_sam9_lpr: 1016 .word 0 1017.saved_sam9_mdr: 1018 .word 0 1019.saved_osc_status: 1020 .word 0 1021#ifdef CFG_SAMA7G5 1022.saved_mck1: 1023 .word 0 1024.saved_mck2: 1025 .word 0 1026.saved_mck3: 1027 .word 0 1028.saved_mck4: 1029 .word 0 1030#endif 1031 1032.global at91_pm_suspend_in_sram_sz 1033at91_pm_suspend_in_sram_sz: 1034 .word .-at91_pm_suspend_in_sram 1035 1036check_fit_in_sram at91_pm_suspend_in_sram 1037