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 18#define SRAMC_SELF_FRESH_ACTIVE 0x01 19#define SRAMC_SELF_FRESH_EXIT 0x00 20 21pmc .req r0 22tmp1 .req r4 23tmp2 .req r5 24 25/* 26 * Wait until master clock is ready (after switching master clock source) 27 */ 28 .macro wait_mckrdy 291: ldr tmp1, [pmc, #AT91_PMC_SR] 30 tst tmp1, #AT91_PMC_MCKRDY 31 beq 1b 32 .endm 33 34/* 35 * Wait until master oscillator has stabilized. 36 */ 37 .macro wait_moscrdy 381: ldr tmp1, [pmc, #AT91_PMC_SR] 39 tst tmp1, #AT91_PMC_MOSCS 40 beq 1b 41 .endm 42 43/* 44 * Wait until PLLA has locked. 45 */ 46 .macro wait_pllalock 471: ldr tmp1, [pmc, #AT91_PMC_SR] 48 tst tmp1, #AT91_PMC_LOCKA 49 beq 1b 50 .endm 51 52/* 53 * Put the processor to enter the idle state 54 */ 55 .macro at91_cpu_idle 56 57#if defined(CONFIG_CPU_V7) 58 mov tmp1, #AT91_PMC_PCK 59 str tmp1, [pmc, #AT91_PMC_SCDR] 60 61 dsb 62 63 wfi @ Wait For Interrupt 64#else 65 mcr p15, 0, tmp1, c7, c0, 4 66#endif 67 68 .endm 69 70 .text 71 72 .arm 73 74/* 75 * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc, 76 * void __iomem *ramc1, int memctrl) 77 * @input param: 78 * @r0: base address of AT91_PMC 79 * @r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS) 80 * @r2: base address of second SDRAM Controller or 0 if not present 81 * @r3: pm information 82 */ 83ENTRY(at91_pm_suspend_in_sram) 84 /* Save registers on stack */ 85 stmfd sp!, {r4 - r12, lr} 86 87 /* Drain write buffer */ 88 mov tmp1, #0 89 mcr p15, 0, tmp1, c7, c10, 4 90 91 str r0, .pmc_base 92 str r1, .sramc_base 93 str r2, .sramc1_base 94 95 and r0, r3, #AT91_PM_MEMTYPE_MASK 96 str r0, .memtype 97 98 lsr r0, r3, #AT91_PM_MODE_OFFSET 99 and r0, r0, #AT91_PM_MODE_MASK 100 str r0, .pm_mode 101 102 /* Active the self-refresh mode */ 103 mov r0, #SRAMC_SELF_FRESH_ACTIVE 104 bl at91_sramc_self_refresh 105 106 ldr r0, .pm_mode 107 tst r0, #AT91_PM_SLOW_CLOCK 108 beq skip_disable_main_clock 109 110 ldr pmc, .pmc_base 111 112 /* Save Master clock setting */ 113 ldr tmp1, [pmc, #AT91_PMC_MCKR] 114 str tmp1, .saved_mckr 115 116 /* 117 * Set the Master clock source to slow clock 118 */ 119 bic tmp1, tmp1, #AT91_PMC_CSS 120 str tmp1, [pmc, #AT91_PMC_MCKR] 121 122 wait_mckrdy 123 124 /* Save PLLA setting and disable it */ 125 ldr tmp1, [pmc, #AT91_CKGR_PLLAR] 126 str tmp1, .saved_pllar 127 128 mov tmp1, #AT91_PMC_PLLCOUNT 129 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ 130 str tmp1, [pmc, #AT91_CKGR_PLLAR] 131 132 /* Turn off the main oscillator */ 133 ldr tmp1, [pmc, #AT91_CKGR_MOR] 134 bic tmp1, tmp1, #AT91_PMC_MOSCEN 135 orr tmp1, tmp1, #AT91_PMC_KEY 136 str tmp1, [pmc, #AT91_CKGR_MOR] 137 138skip_disable_main_clock: 139 ldr pmc, .pmc_base 140 141 /* Wait for interrupt */ 142 at91_cpu_idle 143 144 ldr r0, .pm_mode 145 tst r0, #AT91_PM_SLOW_CLOCK 146 beq skip_enable_main_clock 147 148 ldr pmc, .pmc_base 149 150 /* Turn on the main oscillator */ 151 ldr tmp1, [pmc, #AT91_CKGR_MOR] 152 orr tmp1, tmp1, #AT91_PMC_MOSCEN 153 orr tmp1, tmp1, #AT91_PMC_KEY 154 str tmp1, [pmc, #AT91_CKGR_MOR] 155 156 wait_moscrdy 157 158 /* Restore PLLA setting */ 159 ldr tmp1, .saved_pllar 160 str tmp1, [pmc, #AT91_CKGR_PLLAR] 161 162 tst tmp1, #(AT91_PMC_MUL & 0xff0000) 163 bne 3f 164 tst tmp1, #(AT91_PMC_MUL & ~0xff0000) 165 beq 4f 1663: 167 wait_pllalock 1684: 169 170 /* 171 * Restore master clock setting 172 */ 173 ldr tmp1, .saved_mckr 174 str tmp1, [pmc, #AT91_PMC_MCKR] 175 176 wait_mckrdy 177 178skip_enable_main_clock: 179 /* Exit the self-refresh mode */ 180 mov r0, #SRAMC_SELF_FRESH_EXIT 181 bl at91_sramc_self_refresh 182 183 /* Restore registers, and return */ 184 ldmfd sp!, {r4 - r12, pc} 185ENDPROC(at91_pm_suspend_in_sram) 186 187/* 188 * void at91_sramc_self_refresh(unsigned int is_active) 189 * 190 * @input param: 191 * @r0: 1 - active self-refresh mode 192 * 0 - exit self-refresh mode 193 * register usage: 194 * @r1: memory type 195 * @r2: base address of the sram controller 196 */ 197 198ENTRY(at91_sramc_self_refresh) 199 ldr r1, .memtype 200 ldr r2, .sramc_base 201 202 cmp r1, #AT91_MEMCTRL_MC 203 bne ddrc_sf 204 205 /* 206 * at91rm9200 Memory controller 207 */ 208 209 /* 210 * For exiting the self-refresh mode, do nothing, 211 * automatically exit the self-refresh mode. 212 */ 213 tst r0, #SRAMC_SELF_FRESH_ACTIVE 214 beq exit_sramc_sf 215 216 /* Active SDRAM self-refresh mode */ 217 mov r3, #1 218 str r3, [r2, #AT91_MC_SDRAMC_SRR] 219 b exit_sramc_sf 220 221ddrc_sf: 222 cmp r1, #AT91_MEMCTRL_DDRSDR 223 bne sdramc_sf 224 225 /* 226 * DDR Memory controller 227 */ 228 tst r0, #SRAMC_SELF_FRESH_ACTIVE 229 beq ddrc_exit_sf 230 231 /* LPDDR1 --> force DDR2 mode during self-refresh */ 232 ldr r3, [r2, #AT91_DDRSDRC_MDR] 233 str r3, .saved_sam9_mdr 234 bic r3, r3, #~AT91_DDRSDRC_MD 235 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 236 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 237 biceq r3, r3, #AT91_DDRSDRC_MD 238 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 239 streq r3, [r2, #AT91_DDRSDRC_MDR] 240 241 /* Active DDRC self-refresh mode */ 242 ldr r3, [r2, #AT91_DDRSDRC_LPR] 243 str r3, .saved_sam9_lpr 244 bic r3, r3, #AT91_DDRSDRC_LPCB 245 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 246 str r3, [r2, #AT91_DDRSDRC_LPR] 247 248 /* If using the 2nd ddr controller */ 249 ldr r2, .sramc1_base 250 cmp r2, #0 251 beq no_2nd_ddrc 252 253 ldr r3, [r2, #AT91_DDRSDRC_MDR] 254 str r3, .saved_sam9_mdr1 255 bic r3, r3, #~AT91_DDRSDRC_MD 256 cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR 257 ldreq r3, [r2, #AT91_DDRSDRC_MDR] 258 biceq r3, r3, #AT91_DDRSDRC_MD 259 orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 260 streq r3, [r2, #AT91_DDRSDRC_MDR] 261 262 /* Active DDRC self-refresh mode */ 263 ldr r3, [r2, #AT91_DDRSDRC_LPR] 264 str r3, .saved_sam9_lpr1 265 bic r3, r3, #AT91_DDRSDRC_LPCB 266 orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH 267 str r3, [r2, #AT91_DDRSDRC_LPR] 268 269no_2nd_ddrc: 270 b exit_sramc_sf 271 272ddrc_exit_sf: 273 /* Restore MDR in case of LPDDR1 */ 274 ldr r3, .saved_sam9_mdr 275 str r3, [r2, #AT91_DDRSDRC_MDR] 276 /* Restore LPR on AT91 with DDRAM */ 277 ldr r3, .saved_sam9_lpr 278 str r3, [r2, #AT91_DDRSDRC_LPR] 279 280 /* If using the 2nd ddr controller */ 281 ldr r2, .sramc1_base 282 cmp r2, #0 283 ldrne r3, .saved_sam9_mdr1 284 strne r3, [r2, #AT91_DDRSDRC_MDR] 285 ldrne r3, .saved_sam9_lpr1 286 strne r3, [r2, #AT91_DDRSDRC_LPR] 287 288 b exit_sramc_sf 289 290 /* 291 * SDRAMC Memory controller 292 */ 293sdramc_sf: 294 tst r0, #SRAMC_SELF_FRESH_ACTIVE 295 beq sdramc_exit_sf 296 297 /* Active SDRAMC self-refresh mode */ 298 ldr r3, [r2, #AT91_SDRAMC_LPR] 299 str r3, .saved_sam9_lpr 300 bic r3, r3, #AT91_SDRAMC_LPCB 301 orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH 302 str r3, [r2, #AT91_SDRAMC_LPR] 303 304sdramc_exit_sf: 305 ldr r3, .saved_sam9_lpr 306 str r3, [r2, #AT91_SDRAMC_LPR] 307 308exit_sramc_sf: 309 mov pc, lr 310ENDPROC(at91_sramc_self_refresh) 311 312.pmc_base: 313 .word 0 314.sramc_base: 315 .word 0 316.sramc1_base: 317 .word 0 318.memtype: 319 .word 0 320.pm_mode: 321 .word 0 322.saved_mckr: 323 .word 0 324.saved_pllar: 325 .word 0 326.saved_sam9_lpr: 327 .word 0 328.saved_sam9_lpr1: 329 .word 0 330.saved_sam9_mdr: 331 .word 0 332.saved_sam9_mdr1: 333 .word 0 334 335ENTRY(at91_pm_suspend_in_sram_sz) 336 .word .-at91_pm_suspend_in_sram 337