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