1/* 2 * arch/arm/mach-at91/pm_slow_clock.S 3 * 4 * Copyright (C) 2006 Savin Zlobec 5 * 6 * AT91SAM9 support: 7 * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 */ 14#include <linux/linkage.h> 15#include <linux/clk/at91_pmc.h> 16#include "pm.h" 17#include "generated/at91_pm_data-offsets.h" 18 19#define SRAMC_SELF_FRESH_ACTIVE 0x01 20#define SRAMC_SELF_FRESH_EXIT 0x00 21 22pmc .req r0 23tmp1 .req r4 24tmp2 .req r5 25 26/* 27 * Wait until master clock is ready (after switching master clock source) 28 */ 29 .macro wait_mckrdy 301: ldr tmp1, [pmc, #AT91_PMC_SR] 31 tst tmp1, #AT91_PMC_MCKRDY 32 beq 1b 33 .endm 34 35/* 36 * Wait until master oscillator has stabilized. 37 */ 38 .macro wait_moscrdy 391: ldr tmp1, [pmc, #AT91_PMC_SR] 40 tst tmp1, #AT91_PMC_MOSCS 41 beq 1b 42 .endm 43 44/* 45 * Wait for main oscillator selection is done 46 */ 47 .macro wait_moscsels 481: ldr tmp1, [pmc, #AT91_PMC_SR] 49 tst tmp1, #AT91_PMC_MOSCSELS 50 beq 1b 51 .endm 52 53/* 54 * Put the processor to enter the idle state 55 */ 56 .macro at91_cpu_idle 57 58#if defined(CONFIG_CPU_V7) 59 mov tmp1, #AT91_PMC_PCK 60 str tmp1, [pmc, #AT91_PMC_SCDR] 61 62 dsb 63 64 wfi @ Wait For Interrupt 65#else 66 mcr p15, 0, tmp1, c7, c0, 4 67#endif 68 69 .endm 70 71 .text 72 73 .arm 74 75/* 76 * void at91_suspend_sram_fn(struct at91_pm_data*) 77 * @input param: 78 * @r0: base address of struct at91_pm_data 79 */ 80/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */ 81 .align 3 82ENTRY(at91_pm_suspend_in_sram) 83 /* Save registers on stack */ 84 stmfd sp!, {r4 - r12, lr} 85 86 /* Drain write buffer */ 87 mov tmp1, #0 88 mcr p15, 0, tmp1, c7, c10, 4 89 90 ldr tmp1, [r0, #PM_DATA_PMC] 91 str tmp1, .pmc_base 92 ldr tmp1, [r0, #PM_DATA_RAMC0] 93 str tmp1, .sramc_base 94 ldr tmp1, [r0, #PM_DATA_RAMC1] 95 str tmp1, .sramc1_base 96 ldr tmp1, [r0, #PM_DATA_MEMCTRL] 97 str tmp1, .memtype 98 ldr tmp1, [r0, #PM_DATA_MODE] 99 str tmp1, .pm_mode 100 /* Both ldrne below are here to preload their address in the TLB */ 101 ldr tmp1, [r0, #PM_DATA_SHDWC] 102 str tmp1, .shdwc 103 cmp tmp1, #0 104 ldrne tmp2, [tmp1, #0] 105 ldr tmp1, [r0, #PM_DATA_SFRBU] 106 str tmp1, .sfr 107 cmp tmp1, #0 108 ldrne tmp2, [tmp1, #0x10] 109 110 /* Active the self-refresh mode */ 111 mov r0, #SRAMC_SELF_FRESH_ACTIVE 112 bl at91_sramc_self_refresh 113 114 ldr r0, .pm_mode 115 cmp r0, #AT91_PM_STANDBY 116 beq standby 117 cmp r0, #AT91_PM_BACKUP 118 beq backup_mode 119 120 bl at91_ulp_mode 121 b exit_suspend 122 123standby: 124 /* Wait for interrupt */ 125 ldr pmc, .pmc_base 126 at91_cpu_idle 127 b exit_suspend 128 129backup_mode: 130 bl at91_backup_mode 131 b exit_suspend 132 133exit_suspend: 134 /* Exit the self-refresh mode */ 135 mov r0, #SRAMC_SELF_FRESH_EXIT 136 bl at91_sramc_self_refresh 137 138 /* Restore registers, and return */ 139 ldmfd sp!, {r4 - r12, pc} 140ENDPROC(at91_pm_suspend_in_sram) 141 142ENTRY(at91_backup_mode) 143 /* Switch the master clock source to slow clock. */ 144 ldr pmc, .pmc_base 145 ldr tmp1, [pmc, #AT91_PMC_MCKR] 146 bic tmp1, tmp1, #AT91_PMC_CSS 147 str tmp1, [pmc, #AT91_PMC_MCKR] 148 149 wait_mckrdy 150 151 /*BUMEN*/ 152 ldr r0, .sfr 153 mov tmp1, #0x1 154 str tmp1, [r0, #0x10] 155 156 /* Shutdown */ 157 ldr r0, .shdwc 158 mov tmp1, #0xA5000000 159 add tmp1, tmp1, #0x1 160 str tmp1, [r0, #0] 161ENDPROC(at91_backup_mode) 162 163.macro at91_pm_ulp0_mode 164 ldr pmc, .pmc_base 165 166 /* Turn off the crystal oscillator */ 167 ldr tmp1, [pmc, #AT91_CKGR_MOR] 168 bic tmp1, tmp1, #AT91_PMC_MOSCEN 169 orr tmp1, tmp1, #AT91_PMC_KEY 170 str tmp1, [pmc, #AT91_CKGR_MOR] 171 172 /* Save RC oscillator state */ 173 ldr tmp1, [pmc, #AT91_PMC_SR] 174 str tmp1, .saved_osc_status 175 tst tmp1, #AT91_PMC_MOSCRCS 176 bne 1f 177 178 /* Turn off RC oscillator */ 179 ldr tmp1, [pmc, #AT91_CKGR_MOR] 180 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 181 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 182 orr tmp1, tmp1, #AT91_PMC_KEY 183 str tmp1, [pmc, #AT91_CKGR_MOR] 184 185 /* Wait main RC disabled done */ 1862: ldr tmp1, [pmc, #AT91_PMC_SR] 187 tst tmp1, #AT91_PMC_MOSCRCS 188 bne 2b 189 190 /* Wait for interrupt */ 1911: at91_cpu_idle 192 193 /* Restore RC oscillator state */ 194 ldr tmp1, .saved_osc_status 195 tst tmp1, #AT91_PMC_MOSCRCS 196 beq 4f 197 198 /* Turn on RC oscillator */ 199 ldr tmp1, [pmc, #AT91_CKGR_MOR] 200 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 201 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 202 orr tmp1, tmp1, #AT91_PMC_KEY 203 str tmp1, [pmc, #AT91_CKGR_MOR] 204 205 /* Wait main RC stabilization */ 2063: ldr tmp1, [pmc, #AT91_PMC_SR] 207 tst tmp1, #AT91_PMC_MOSCRCS 208 beq 3b 209 210 /* Turn on the crystal oscillator */ 2114: ldr tmp1, [pmc, #AT91_CKGR_MOR] 212 orr tmp1, tmp1, #AT91_PMC_MOSCEN 213 orr tmp1, tmp1, #AT91_PMC_KEY 214 str tmp1, [pmc, #AT91_CKGR_MOR] 215 216 wait_moscrdy 217.endm 218 219/** 220 * Note: This procedure only applies on the platform which uses 221 * the external crystal oscillator as a main clock source. 222 */ 223.macro at91_pm_ulp1_mode 224 ldr pmc, .pmc_base 225 226 /* Save RC oscillator state and check if it is enabled. */ 227 ldr tmp1, [pmc, #AT91_PMC_SR] 228 str tmp1, .saved_osc_status 229 tst tmp1, #AT91_PMC_MOSCRCS 230 bne 2f 231 232 /* Enable RC oscillator */ 233 ldr tmp1, [pmc, #AT91_CKGR_MOR] 234 orr tmp1, tmp1, #AT91_PMC_MOSCRCEN 235 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 236 orr tmp1, tmp1, #AT91_PMC_KEY 237 str tmp1, [pmc, #AT91_CKGR_MOR] 238 239 /* Wait main RC stabilization */ 2401: ldr tmp1, [pmc, #AT91_PMC_SR] 241 tst tmp1, #AT91_PMC_MOSCRCS 242 beq 1b 243 244 /* Switch the main clock source to 12-MHz RC oscillator */ 2452: ldr tmp1, [pmc, #AT91_CKGR_MOR] 246 bic tmp1, tmp1, #AT91_PMC_MOSCSEL 247 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 248 orr tmp1, tmp1, #AT91_PMC_KEY 249 str tmp1, [pmc, #AT91_CKGR_MOR] 250 251 wait_moscsels 252 253 /* Disable the crystal oscillator */ 254 ldr tmp1, [pmc, #AT91_CKGR_MOR] 255 bic tmp1, tmp1, #AT91_PMC_MOSCEN 256 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 257 orr tmp1, tmp1, #AT91_PMC_KEY 258 str tmp1, [pmc, #AT91_CKGR_MOR] 259 260 /* Switch the master clock source to main clock */ 261 ldr tmp1, [pmc, #AT91_PMC_MCKR] 262 bic tmp1, tmp1, #AT91_PMC_CSS 263 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 264 str tmp1, [pmc, #AT91_PMC_MCKR] 265 266 wait_mckrdy 267 268 /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */ 269 ldr tmp1, [pmc, #AT91_CKGR_MOR] 270 orr tmp1, tmp1, #AT91_PMC_WAITMODE 271 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 272 orr tmp1, tmp1, #AT91_PMC_KEY 273 str tmp1, [pmc, #AT91_CKGR_MOR] 274 275 wait_mckrdy 276 277 /* Enable the crystal oscillator */ 278 ldr tmp1, [pmc, #AT91_CKGR_MOR] 279 orr tmp1, tmp1, #AT91_PMC_MOSCEN 280 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 281 orr tmp1, tmp1, #AT91_PMC_KEY 282 str tmp1, [pmc, #AT91_CKGR_MOR] 283 284 wait_moscrdy 285 286 /* Switch the master clock source to slow clock */ 287 ldr tmp1, [pmc, #AT91_PMC_MCKR] 288 bic tmp1, tmp1, #AT91_PMC_CSS 289 str tmp1, [pmc, #AT91_PMC_MCKR] 290 291 wait_mckrdy 292 293 /* Switch main clock source to crystal oscillator */ 294 ldr tmp1, [pmc, #AT91_CKGR_MOR] 295 orr tmp1, tmp1, #AT91_PMC_MOSCSEL 296 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 297 orr tmp1, tmp1, #AT91_PMC_KEY 298 str tmp1, [pmc, #AT91_CKGR_MOR] 299 300 wait_moscsels 301 302 /* Switch the master clock source to main clock */ 303 ldr tmp1, [pmc, #AT91_PMC_MCKR] 304 bic tmp1, tmp1, #AT91_PMC_CSS 305 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 306 str tmp1, [pmc, #AT91_PMC_MCKR] 307 308 wait_mckrdy 309 310 /* Restore RC oscillator state */ 311 ldr tmp1, .saved_osc_status 312 tst tmp1, #AT91_PMC_MOSCRCS 313 bne 3f 314 315 /* Disable RC oscillator */ 316 ldr tmp1, [pmc, #AT91_CKGR_MOR] 317 bic tmp1, tmp1, #AT91_PMC_MOSCRCEN 318 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 319 orr tmp1, tmp1, #AT91_PMC_KEY 320 str tmp1, [pmc, #AT91_CKGR_MOR] 321 322 /* Wait RC oscillator disable done */ 3234: ldr tmp1, [pmc, #AT91_PMC_SR] 324 tst tmp1, #AT91_PMC_MOSCRCS 325 bne 4b 326 3273: 328.endm 329 330ENTRY(at91_ulp_mode) 331 ldr pmc, .pmc_base 332 333 /* Save Master clock setting */ 334 ldr tmp1, [pmc, #AT91_PMC_MCKR] 335 str tmp1, .saved_mckr 336 337 /* 338 * Set the Master clock source to slow clock 339 */ 340 bic tmp1, tmp1, #AT91_PMC_CSS 341 str tmp1, [pmc, #AT91_PMC_MCKR] 342 343 wait_mckrdy 344 345 ldr r0, .pm_mode 346 cmp r0, #AT91_PM_ULP1 347 beq ulp1_mode 348 349 at91_pm_ulp0_mode 350 b ulp_exit 351 352ulp1_mode: 353 at91_pm_ulp1_mode 354 b ulp_exit 355 356ulp_exit: 357 ldr pmc, .pmc_base 358 359 /* 360 * Restore master clock setting 361 */ 362 ldr tmp1, .saved_mckr 363 str tmp1, [pmc, #AT91_PMC_MCKR] 364 365 wait_mckrdy 366 367 mov pc, lr 368ENDPROC(at91_ulp_mode) 369 370/* 371 * void at91_sramc_self_refresh(unsigned int is_active) 372 * 373 * @input param: 374 * @r0: 1 - active self-refresh mode 375 * 0 - exit self-refresh mode 376 * register usage: 377 * @r1: memory type 378 * @r2: base address of the sram controller 379 */ 380 381ENTRY(at91_sramc_self_refresh) 382 ldr r1, .memtype 383 ldr r2, .sramc_base 384 385 cmp r1, #AT91_MEMCTRL_MC 386 bne ddrc_sf 387 388 /* 389 * at91rm9200 Memory controller 390 */ 391 392 /* 393 * For exiting the self-refresh mode, do nothing, 394 * automatically exit the self-refresh mode. 395 */ 396 tst r0, #SRAMC_SELF_FRESH_ACTIVE 397 beq exit_sramc_sf 398 399 /* Active SDRAM self-refresh mode */ 400 mov r3, #1 401 str r3, [r2, #AT91_MC_SDRAMC_SRR] 402 b exit_sramc_sf 403 404ddrc_sf: 405 cmp r1, #AT91_MEMCTRL_DDRSDR 406 bne sdramc_sf 407 408 /* 409 * DDR Memory controller 410 */ 411 tst r0, #SRAMC_SELF_FRESH_ACTIVE 412 beq ddrc_exit_sf 413 414 /* LPDDR1 --> force DDR2 mode during self-refresh */ 415 ldr r3, [r2, #AT91_DDRSDRC_MDR] 416 str r3, .saved_sam9_mdr 417 bic r3, r3, #~AT91_DDRSDRC_MD 418 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 419 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 420 biceq r3, r3, #AT91_DDRSDRC_MD 421 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 422 streq r3, [r2, #AT91_DDRSDRC_MDR] 423 424 /* Active DDRC self-refresh mode */ 425 ldr r3, [r2, #AT91_DDRSDRC_LPR] 426 str r3, .saved_sam9_lpr 427 bic r3, r3, #AT91_DDRSDRC_LPCB 428 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 429 str r3, [r2, #AT91_DDRSDRC_LPR] 430 431 /* If using the 2nd ddr controller */ 432 ldr r2, .sramc1_base 433 cmp r2, #0 434 beq no_2nd_ddrc 435 436 ldr r3, [r2, #AT91_DDRSDRC_MDR] 437 str r3, .saved_sam9_mdr1 438 bic r3, r3, #~AT91_DDRSDRC_MD 439 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 440 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 441 biceq r3, r3, #AT91_DDRSDRC_MD 442 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 443 streq r3, [r2, #AT91_DDRSDRC_MDR] 444 445 /* Active DDRC self-refresh mode */ 446 ldr r3, [r2, #AT91_DDRSDRC_LPR] 447 str r3, .saved_sam9_lpr1 448 bic r3, r3, #AT91_DDRSDRC_LPCB 449 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 450 str r3, [r2, #AT91_DDRSDRC_LPR] 451 452no_2nd_ddrc: 453 b exit_sramc_sf 454 455ddrc_exit_sf: 456 /* Restore MDR in case of LPDDR1 */ 457 ldr r3, .saved_sam9_mdr 458 str r3, [r2, #AT91_DDRSDRC_MDR] 459 /* Restore LPR on AT91 with DDRAM */ 460 ldr r3, .saved_sam9_lpr 461 str r3, [r2, #AT91_DDRSDRC_LPR] 462 463 /* If using the 2nd ddr controller */ 464 ldr r2, .sramc1_base 465 cmp r2, #0 466 ldrne r3, .saved_sam9_mdr1 467 strne r3, [r2, #AT91_DDRSDRC_MDR] 468 ldrne r3, .saved_sam9_lpr1 469 strne r3, [r2, #AT91_DDRSDRC_LPR] 470 471 b exit_sramc_sf 472 473 /* 474 * SDRAMC Memory controller 475 */ 476sdramc_sf: 477 tst r0, #SRAMC_SELF_FRESH_ACTIVE 478 beq sdramc_exit_sf 479 480 /* Active SDRAMC self-refresh mode */ 481 ldr r3, [r2, #AT91_SDRAMC_LPR] 482 str r3, .saved_sam9_lpr 483 bic r3, r3, #AT91_SDRAMC_LPCB 484 orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH 485 str r3, [r2, #AT91_SDRAMC_LPR] 486 487sdramc_exit_sf: 488 ldr r3, .saved_sam9_lpr 489 str r3, [r2, #AT91_SDRAMC_LPR] 490 491exit_sramc_sf: 492 mov pc, lr 493ENDPROC(at91_sramc_self_refresh) 494 495.pmc_base: 496 .word 0 497.sramc_base: 498 .word 0 499.sramc1_base: 500 .word 0 501.shdwc: 502 .word 0 503.sfr: 504 .word 0 505.memtype: 506 .word 0 507.pm_mode: 508 .word 0 509.saved_mckr: 510 .word 0 511.saved_sam9_lpr: 512 .word 0 513.saved_sam9_lpr1: 514 .word 0 515.saved_sam9_mdr: 516 .word 0 517.saved_sam9_mdr1: 518 .word 0 519.saved_osc_status: 520 .word 0 521 522ENTRY(at91_pm_suspend_in_sram_sz) 523 .word .-at91_pm_suspend_in_sram 524