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 * Wait until PLLA has locked. 55 */ 56 .macro wait_pllalock 571: ldr tmp1, [pmc, #AT91_PMC_SR] 58 tst tmp1, #AT91_PMC_LOCKA 59 beq 1b 60 .endm 61 62/* 63 * Put the processor to enter the idle state 64 */ 65 .macro at91_cpu_idle 66 67#if defined(CONFIG_CPU_V7) 68 mov tmp1, #AT91_PMC_PCK 69 str tmp1, [pmc, #AT91_PMC_SCDR] 70 71 dsb 72 73 wfi @ Wait For Interrupt 74#else 75 mcr p15, 0, tmp1, c7, c0, 4 76#endif 77 78 .endm 79 80 .text 81 82 .arm 83 84/* 85 * void at91_suspend_sram_fn(struct at91_pm_data*) 86 * @input param: 87 * @r0: base address of struct at91_pm_data 88 */ 89/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */ 90 .align 3 91ENTRY(at91_pm_suspend_in_sram) 92 /* Save registers on stack */ 93 stmfd sp!, {r4 - r12, lr} 94 95 /* Drain write buffer */ 96 mov tmp1, #0 97 mcr p15, 0, tmp1, c7, c10, 4 98 99 ldr tmp1, [r0, #PM_DATA_PMC] 100 str tmp1, .pmc_base 101 ldr tmp1, [r0, #PM_DATA_RAMC0] 102 str tmp1, .sramc_base 103 ldr tmp1, [r0, #PM_DATA_RAMC1] 104 str tmp1, .sramc1_base 105 ldr tmp1, [r0, #PM_DATA_MEMCTRL] 106 str tmp1, .memtype 107 ldr tmp1, [r0, #PM_DATA_MODE] 108 str tmp1, .pm_mode 109 /* Both ldrne below are here to preload their address in the TLB */ 110 ldr tmp1, [r0, #PM_DATA_SHDWC] 111 str tmp1, .shdwc 112 cmp tmp1, #0 113 ldrne tmp2, [tmp1, #0] 114 ldr tmp1, [r0, #PM_DATA_SFRBU] 115 str tmp1, .sfr 116 cmp tmp1, #0 117 ldrne tmp2, [tmp1, #0x10] 118 119 /* Active the self-refresh mode */ 120 mov r0, #SRAMC_SELF_FRESH_ACTIVE 121 bl at91_sramc_self_refresh 122 123 ldr r0, .pm_mode 124 cmp r0, #AT91_PM_STANDBY 125 beq standby 126 cmp r0, #AT91_PM_BACKUP 127 beq backup_mode 128 129 bl at91_ulp_mode 130 b exit_suspend 131 132standby: 133 /* Wait for interrupt */ 134 ldr pmc, .pmc_base 135 at91_cpu_idle 136 b exit_suspend 137 138backup_mode: 139 bl at91_backup_mode 140 b exit_suspend 141 142exit_suspend: 143 /* Exit the self-refresh mode */ 144 mov r0, #SRAMC_SELF_FRESH_EXIT 145 bl at91_sramc_self_refresh 146 147 /* Restore registers, and return */ 148 ldmfd sp!, {r4 - r12, pc} 149ENDPROC(at91_pm_suspend_in_sram) 150 151ENTRY(at91_backup_mode) 152 /* Switch the master clock source to slow clock. */ 153 ldr pmc, .pmc_base 154 ldr tmp1, [pmc, #AT91_PMC_MCKR] 155 bic tmp1, tmp1, #AT91_PMC_CSS 156 str tmp1, [pmc, #AT91_PMC_MCKR] 157 158 wait_mckrdy 159 160 /*BUMEN*/ 161 ldr r0, .sfr 162 mov tmp1, #0x1 163 str tmp1, [r0, #0x10] 164 165 /* Shutdown */ 166 ldr r0, .shdwc 167 mov tmp1, #0xA5000000 168 add tmp1, tmp1, #0x1 169 str tmp1, [r0, #0] 170ENDPROC(at91_backup_mode) 171 172.macro at91_pm_ulp0_mode 173 ldr pmc, .pmc_base 174 175 /* Turn off the crystal oscillator */ 176 ldr tmp1, [pmc, #AT91_CKGR_MOR] 177 bic tmp1, tmp1, #AT91_PMC_MOSCEN 178 orr tmp1, tmp1, #AT91_PMC_KEY 179 str tmp1, [pmc, #AT91_CKGR_MOR] 180 181 /* Wait for interrupt */ 182 at91_cpu_idle 183 184 /* Turn on the crystal oscillator */ 185 ldr tmp1, [pmc, #AT91_CKGR_MOR] 186 orr tmp1, tmp1, #AT91_PMC_MOSCEN 187 orr tmp1, tmp1, #AT91_PMC_KEY 188 str tmp1, [pmc, #AT91_CKGR_MOR] 189 190 wait_moscrdy 191.endm 192 193/** 194 * Note: This procedure only applies on the platform which uses 195 * the external crystal oscillator as a main clock source. 196 */ 197.macro at91_pm_ulp1_mode 198 ldr pmc, .pmc_base 199 200 /* Switch the main clock source to 12-MHz RC oscillator */ 201 ldr tmp1, [pmc, #AT91_CKGR_MOR] 202 bic tmp1, tmp1, #AT91_PMC_MOSCSEL 203 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 204 orr tmp1, tmp1, #AT91_PMC_KEY 205 str tmp1, [pmc, #AT91_CKGR_MOR] 206 207 wait_moscsels 208 209 /* Disable the crystal oscillator */ 210 ldr tmp1, [pmc, #AT91_CKGR_MOR] 211 bic tmp1, tmp1, #AT91_PMC_MOSCEN 212 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 213 orr tmp1, tmp1, #AT91_PMC_KEY 214 str tmp1, [pmc, #AT91_CKGR_MOR] 215 216 /* Switch the master clock source to main clock */ 217 ldr tmp1, [pmc, #AT91_PMC_MCKR] 218 bic tmp1, tmp1, #AT91_PMC_CSS 219 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 220 str tmp1, [pmc, #AT91_PMC_MCKR] 221 222 wait_mckrdy 223 224 /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */ 225 ldr tmp1, [pmc, #AT91_CKGR_MOR] 226 orr tmp1, tmp1, #AT91_PMC_WAITMODE 227 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 228 orr tmp1, tmp1, #AT91_PMC_KEY 229 str tmp1, [pmc, #AT91_CKGR_MOR] 230 231 wait_mckrdy 232 233 /* Enable the crystal oscillator */ 234 ldr tmp1, [pmc, #AT91_CKGR_MOR] 235 orr tmp1, tmp1, #AT91_PMC_MOSCEN 236 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 237 orr tmp1, tmp1, #AT91_PMC_KEY 238 str tmp1, [pmc, #AT91_CKGR_MOR] 239 240 wait_moscrdy 241 242 /* Switch the master clock source to slow clock */ 243 ldr tmp1, [pmc, #AT91_PMC_MCKR] 244 bic tmp1, tmp1, #AT91_PMC_CSS 245 str tmp1, [pmc, #AT91_PMC_MCKR] 246 247 wait_mckrdy 248 249 /* Switch main clock source to crystal oscillator */ 250 ldr tmp1, [pmc, #AT91_CKGR_MOR] 251 orr tmp1, tmp1, #AT91_PMC_MOSCSEL 252 bic tmp1, tmp1, #AT91_PMC_KEY_MASK 253 orr tmp1, tmp1, #AT91_PMC_KEY 254 str tmp1, [pmc, #AT91_CKGR_MOR] 255 256 wait_moscsels 257 258 /* Switch the master clock source to main clock */ 259 ldr tmp1, [pmc, #AT91_PMC_MCKR] 260 bic tmp1, tmp1, #AT91_PMC_CSS 261 orr tmp1, tmp1, #AT91_PMC_CSS_MAIN 262 str tmp1, [pmc, #AT91_PMC_MCKR] 263 264 wait_mckrdy 265.endm 266 267ENTRY(at91_ulp_mode) 268 ldr pmc, .pmc_base 269 270 /* Save Master clock setting */ 271 ldr tmp1, [pmc, #AT91_PMC_MCKR] 272 str tmp1, .saved_mckr 273 274 /* 275 * Set the Master clock source to slow clock 276 */ 277 bic tmp1, tmp1, #AT91_PMC_CSS 278 str tmp1, [pmc, #AT91_PMC_MCKR] 279 280 wait_mckrdy 281 282 /* Save PLLA setting and disable it */ 283 ldr tmp1, [pmc, #AT91_CKGR_PLLAR] 284 str tmp1, .saved_pllar 285 286 mov tmp1, #AT91_PMC_PLLCOUNT 287 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ 288 str tmp1, [pmc, #AT91_CKGR_PLLAR] 289 290 ldr r0, .pm_mode 291 cmp r0, #AT91_PM_ULP1 292 beq ulp1_mode 293 294 at91_pm_ulp0_mode 295 b ulp_exit 296 297ulp1_mode: 298 at91_pm_ulp1_mode 299 b ulp_exit 300 301ulp_exit: 302 ldr pmc, .pmc_base 303 304 /* Restore PLLA setting */ 305 ldr tmp1, .saved_pllar 306 str tmp1, [pmc, #AT91_CKGR_PLLAR] 307 308 tst tmp1, #(AT91_PMC_MUL & 0xff0000) 309 bne 3f 310 tst tmp1, #(AT91_PMC_MUL & ~0xff0000) 311 beq 4f 3123: 313 wait_pllalock 3144: 315 316 /* 317 * Restore master clock setting 318 */ 319 ldr tmp1, .saved_mckr 320 str tmp1, [pmc, #AT91_PMC_MCKR] 321 322 wait_mckrdy 323 324 mov pc, lr 325ENDPROC(at91_ulp_mode) 326 327/* 328 * void at91_sramc_self_refresh(unsigned int is_active) 329 * 330 * @input param: 331 * @r0: 1 - active self-refresh mode 332 * 0 - exit self-refresh mode 333 * register usage: 334 * @r1: memory type 335 * @r2: base address of the sram controller 336 */ 337 338ENTRY(at91_sramc_self_refresh) 339 ldr r1, .memtype 340 ldr r2, .sramc_base 341 342 cmp r1, #AT91_MEMCTRL_MC 343 bne ddrc_sf 344 345 /* 346 * at91rm9200 Memory controller 347 */ 348 349 /* 350 * For exiting the self-refresh mode, do nothing, 351 * automatically exit the self-refresh mode. 352 */ 353 tst r0, #SRAMC_SELF_FRESH_ACTIVE 354 beq exit_sramc_sf 355 356 /* Active SDRAM self-refresh mode */ 357 mov r3, #1 358 str r3, [r2, #AT91_MC_SDRAMC_SRR] 359 b exit_sramc_sf 360 361ddrc_sf: 362 cmp r1, #AT91_MEMCTRL_DDRSDR 363 bne sdramc_sf 364 365 /* 366 * DDR Memory controller 367 */ 368 tst r0, #SRAMC_SELF_FRESH_ACTIVE 369 beq ddrc_exit_sf 370 371 /* LPDDR1 --> force DDR2 mode during self-refresh */ 372 ldr r3, [r2, #AT91_DDRSDRC_MDR] 373 str r3, .saved_sam9_mdr 374 bic r3, r3, #~AT91_DDRSDRC_MD 375 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 376 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 377 biceq r3, r3, #AT91_DDRSDRC_MD 378 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 379 streq r3, [r2, #AT91_DDRSDRC_MDR] 380 381 /* Active DDRC self-refresh mode */ 382 ldr r3, [r2, #AT91_DDRSDRC_LPR] 383 str r3, .saved_sam9_lpr 384 bic r3, r3, #AT91_DDRSDRC_LPCB 385 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 386 str r3, [r2, #AT91_DDRSDRC_LPR] 387 388 /* If using the 2nd ddr controller */ 389 ldr r2, .sramc1_base 390 cmp r2, #0 391 beq no_2nd_ddrc 392 393 ldr r3, [r2, #AT91_DDRSDRC_MDR] 394 str r3, .saved_sam9_mdr1 395 bic r3, r3, #~AT91_DDRSDRC_MD 396 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 397 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 398 biceq r3, r3, #AT91_DDRSDRC_MD 399 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 400 streq r3, [r2, #AT91_DDRSDRC_MDR] 401 402 /* Active DDRC self-refresh mode */ 403 ldr r3, [r2, #AT91_DDRSDRC_LPR] 404 str r3, .saved_sam9_lpr1 405 bic r3, r3, #AT91_DDRSDRC_LPCB 406 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 407 str r3, [r2, #AT91_DDRSDRC_LPR] 408 409no_2nd_ddrc: 410 b exit_sramc_sf 411 412ddrc_exit_sf: 413 /* Restore MDR in case of LPDDR1 */ 414 ldr r3, .saved_sam9_mdr 415 str r3, [r2, #AT91_DDRSDRC_MDR] 416 /* Restore LPR on AT91 with DDRAM */ 417 ldr r3, .saved_sam9_lpr 418 str r3, [r2, #AT91_DDRSDRC_LPR] 419 420 /* If using the 2nd ddr controller */ 421 ldr r2, .sramc1_base 422 cmp r2, #0 423 ldrne r3, .saved_sam9_mdr1 424 strne r3, [r2, #AT91_DDRSDRC_MDR] 425 ldrne r3, .saved_sam9_lpr1 426 strne r3, [r2, #AT91_DDRSDRC_LPR] 427 428 b exit_sramc_sf 429 430 /* 431 * SDRAMC Memory controller 432 */ 433sdramc_sf: 434 tst r0, #SRAMC_SELF_FRESH_ACTIVE 435 beq sdramc_exit_sf 436 437 /* Active SDRAMC self-refresh mode */ 438 ldr r3, [r2, #AT91_SDRAMC_LPR] 439 str r3, .saved_sam9_lpr 440 bic r3, r3, #AT91_SDRAMC_LPCB 441 orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH 442 str r3, [r2, #AT91_SDRAMC_LPR] 443 444sdramc_exit_sf: 445 ldr r3, .saved_sam9_lpr 446 str r3, [r2, #AT91_SDRAMC_LPR] 447 448exit_sramc_sf: 449 mov pc, lr 450ENDPROC(at91_sramc_self_refresh) 451 452.pmc_base: 453 .word 0 454.sramc_base: 455 .word 0 456.sramc1_base: 457 .word 0 458.shdwc: 459 .word 0 460.sfr: 461 .word 0 462.memtype: 463 .word 0 464.pm_mode: 465 .word 0 466.saved_mckr: 467 .word 0 468.saved_pllar: 469 .word 0 470.saved_sam9_lpr: 471 .word 0 472.saved_sam9_lpr1: 473 .word 0 474.saved_sam9_mdr: 475 .word 0 476.saved_sam9_mdr1: 477 .word 0 478 479ENTRY(at91_pm_suspend_in_sram_sz) 480 .word .-at91_pm_suspend_in_sram 481