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 15#include <linux/linkage.h> 16#include <mach/hardware.h> 17#include <mach/at91_pmc.h> 18#include <mach/at91_ramc.h> 19 20 21#ifdef CONFIG_ARCH_AT91SAM9263 22/* 23 * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use; 24 * handle those cases both here and in the Suspend-To-RAM support. 25 */ 26#warning Assuming EB1 SDRAM controller is *NOT* used 27#endif 28 29/* 30 * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master 31 * clock during suspend by adjusting its prescalar and divisor. 32 * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there 33 * are errata regarding adjusting the prescalar and divisor. 34 */ 35#undef SLOWDOWN_MASTER_CLOCK 36 37#define MCKRDY_TIMEOUT 1000 38#define MOSCRDY_TIMEOUT 1000 39#define PLLALOCK_TIMEOUT 1000 40#define PLLBLOCK_TIMEOUT 1000 41 42pmc .req r0 43sdramc .req r1 44ramc1 .req r2 45memctrl .req r3 46tmp1 .req r4 47tmp2 .req r5 48 49/* 50 * Wait until master clock is ready (after switching master clock source) 51 */ 52 .macro wait_mckrdy 53 mov tmp2, #MCKRDY_TIMEOUT 541: sub tmp2, tmp2, #1 55 cmp tmp2, #0 56 beq 2f 57 ldr tmp1, [pmc, #AT91_PMC_SR] 58 tst tmp1, #AT91_PMC_MCKRDY 59 beq 1b 602: 61 .endm 62 63/* 64 * Wait until master oscillator has stabilized. 65 */ 66 .macro wait_moscrdy 67 mov tmp2, #MOSCRDY_TIMEOUT 681: sub tmp2, tmp2, #1 69 cmp tmp2, #0 70 beq 2f 71 ldr tmp1, [pmc, #AT91_PMC_SR] 72 tst tmp1, #AT91_PMC_MOSCS 73 beq 1b 742: 75 .endm 76 77/* 78 * Wait until PLLA has locked. 79 */ 80 .macro wait_pllalock 81 mov tmp2, #PLLALOCK_TIMEOUT 821: sub tmp2, tmp2, #1 83 cmp tmp2, #0 84 beq 2f 85 ldr tmp1, [pmc, #AT91_PMC_SR] 86 tst tmp1, #AT91_PMC_LOCKA 87 beq 1b 882: 89 .endm 90 91/* 92 * Wait until PLLB has locked. 93 */ 94 .macro wait_pllblock 95 mov tmp2, #PLLBLOCK_TIMEOUT 961: sub tmp2, tmp2, #1 97 cmp tmp2, #0 98 beq 2f 99 ldr tmp1, [pmc, #AT91_PMC_SR] 100 tst tmp1, #AT91_PMC_LOCKB 101 beq 1b 1022: 103 .endm 104 105 .text 106 107/* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, 108 * void __iomem *ramc1, int memctrl) 109 */ 110ENTRY(at91_slow_clock) 111 /* Save registers on stack */ 112 stmfd sp!, {r4 - r12, lr} 113 114 /* 115 * Register usage: 116 * R0 = Base address of AT91_PMC 117 * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS) 118 * R2 = Base address of second RAM Controller or 0 if not present 119 * R3 = Memory controller 120 * R4 = temporary register 121 * R5 = temporary register 122 */ 123 124 /* Drain write buffer */ 125 mov tmp1, #0 126 mcr p15, 0, tmp1, c7, c10, 4 127 128 cmp memctrl, #AT91_MEMCTRL_MC 129 bne ddr_sr_enable 130 131 /* 132 * at91rm9200 Memory controller 133 */ 134 /* Put SDRAM in self-refresh mode */ 135 mov tmp1, #1 136 str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR] 137 b sdr_sr_done 138 139 /* 140 * DDRSDR Memory controller 141 */ 142ddr_sr_enable: 143 cmp memctrl, #AT91_MEMCTRL_DDRSDR 144 bne sdr_sr_enable 145 146 /* prepare for DDRAM self-refresh mode */ 147 ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR] 148 str tmp1, .saved_sam9_lpr 149 bic tmp1, #AT91_DDRSDRC_LPCB 150 orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH 151 152 /* figure out if we use the second ram controller */ 153 cmp ramc1, #0 154 ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR] 155 strne tmp2, .saved_sam9_lpr1 156 bicne tmp2, #AT91_DDRSDRC_LPCB 157 orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH 158 159 /* Enable DDRAM self-refresh mode */ 160 str tmp1, [sdramc, #AT91_DDRSDRC_LPR] 161 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] 162 163 b sdr_sr_done 164 165 /* 166 * SDRAMC Memory controller 167 */ 168sdr_sr_enable: 169 /* Enable SDRAM self-refresh mode */ 170 ldr tmp1, [sdramc, #AT91_SDRAMC_LPR] 171 str tmp1, .saved_sam9_lpr 172 173 bic tmp1, #AT91_SDRAMC_LPCB 174 orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH 175 str tmp1, [sdramc, #AT91_SDRAMC_LPR] 176 177sdr_sr_done: 178 /* Save Master clock setting */ 179 ldr tmp1, [pmc, #AT91_PMC_MCKR] 180 str tmp1, .saved_mckr 181 182 /* 183 * Set the Master clock source to slow clock 184 */ 185 bic tmp1, tmp1, #AT91_PMC_CSS 186 str tmp1, [pmc, #AT91_PMC_MCKR] 187 188 wait_mckrdy 189 190#ifdef SLOWDOWN_MASTER_CLOCK 191 /* 192 * Set the Master Clock PRES and MDIV fields. 193 * 194 * See AT91RM9200 errata #27 and #28 for details. 195 */ 196 mov tmp1, #0 197 str tmp1, [pmc, #AT91_PMC_MCKR] 198 199 wait_mckrdy 200#endif 201 202 /* Save PLLA setting and disable it */ 203 ldr tmp1, [pmc, #AT91_CKGR_PLLAR] 204 str tmp1, .saved_pllar 205 206 mov tmp1, #AT91_PMC_PLLCOUNT 207 orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */ 208 str tmp1, [pmc, #AT91_CKGR_PLLAR] 209 210 /* Save PLLB setting and disable it */ 211 ldr tmp1, [pmc, #AT91_CKGR_PLLBR] 212 str tmp1, .saved_pllbr 213 214 mov tmp1, #AT91_PMC_PLLCOUNT 215 str tmp1, [pmc, #AT91_CKGR_PLLBR] 216 217 /* Turn off the main oscillator */ 218 ldr tmp1, [pmc, #AT91_CKGR_MOR] 219 bic tmp1, tmp1, #AT91_PMC_MOSCEN 220 str tmp1, [pmc, #AT91_CKGR_MOR] 221 222 /* Wait for interrupt */ 223 mcr p15, 0, tmp1, c7, c0, 4 224 225 /* Turn on the main oscillator */ 226 ldr tmp1, [pmc, #AT91_CKGR_MOR] 227 orr tmp1, tmp1, #AT91_PMC_MOSCEN 228 str tmp1, [pmc, #AT91_CKGR_MOR] 229 230 wait_moscrdy 231 232 /* Restore PLLB setting */ 233 ldr tmp1, .saved_pllbr 234 str tmp1, [pmc, #AT91_CKGR_PLLBR] 235 236 tst tmp1, #(AT91_PMC_MUL & 0xff0000) 237 bne 1f 238 tst tmp1, #(AT91_PMC_MUL & ~0xff0000) 239 beq 2f 2401: 241 wait_pllblock 2422: 243 244 /* Restore PLLA setting */ 245 ldr tmp1, .saved_pllar 246 str tmp1, [pmc, #AT91_CKGR_PLLAR] 247 248 tst tmp1, #(AT91_PMC_MUL & 0xff0000) 249 bne 3f 250 tst tmp1, #(AT91_PMC_MUL & ~0xff0000) 251 beq 4f 2523: 253 wait_pllalock 2544: 255 256#ifdef SLOWDOWN_MASTER_CLOCK 257 /* 258 * First set PRES if it was not 0, 259 * than set CSS and MDIV fields. 260 * 261 * See AT91RM9200 errata #27 and #28 for details. 262 */ 263 ldr tmp1, .saved_mckr 264 tst tmp1, #AT91_PMC_PRES 265 beq 2f 266 and tmp1, tmp1, #AT91_PMC_PRES 267 str tmp1, [pmc, #AT91_PMC_MCKR] 268 269 wait_mckrdy 270#endif 271 272 /* 273 * Restore master clock setting 274 */ 2752: ldr tmp1, .saved_mckr 276 str tmp1, [pmc, #AT91_PMC_MCKR] 277 278 wait_mckrdy 279 280 /* 281 * at91rm9200 Memory controller 282 * Do nothing - self-refresh is automatically disabled. 283 */ 284 cmp memctrl, #AT91_MEMCTRL_MC 285 beq ram_restored 286 287 /* 288 * DDRSDR Memory controller 289 */ 290 cmp memctrl, #AT91_MEMCTRL_DDRSDR 291 bne sdr_en_restore 292 /* Restore LPR on AT91 with DDRAM */ 293 ldr tmp1, .saved_sam9_lpr 294 str tmp1, [sdramc, #AT91_DDRSDRC_LPR] 295 296 /* if we use the second ram controller */ 297 cmp ramc1, #0 298 ldrne tmp2, .saved_sam9_lpr1 299 strne tmp2, [ramc1, #AT91_DDRSDRC_LPR] 300 301 b ram_restored 302 303 /* 304 * SDRAMC Memory controller 305 */ 306sdr_en_restore: 307 /* Restore LPR on AT91 with SDRAM */ 308 ldr tmp1, .saved_sam9_lpr 309 str tmp1, [sdramc, #AT91_SDRAMC_LPR] 310 311ram_restored: 312 /* Restore registers, and return */ 313 ldmfd sp!, {r4 - r12, pc} 314 315 316.saved_mckr: 317 .word 0 318 319.saved_pllar: 320 .word 0 321 322.saved_pllbr: 323 .word 0 324 325.saved_sam9_lpr: 326 .word 0 327 328.saved_sam9_lpr1: 329 .word 0 330 331ENTRY(at91_slow_clock_sz) 332 .word .-at91_slow_clock 333