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