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