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