1 /* 2 * arch/arm/mach-at91/pm.c 3 * AT91 Power Management 4 * 5 * Copyright (C) 2005 David Brownell 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 */ 12 13 #include <linux/suspend.h> 14 #include <linux/sched.h> 15 #include <linux/proc_fs.h> 16 #include <linux/interrupt.h> 17 #include <linux/sysfs.h> 18 #include <linux/module.h> 19 #include <linux/platform_device.h> 20 #include <linux/io.h> 21 22 #include <asm/irq.h> 23 #include <linux/atomic.h> 24 #include <asm/mach/time.h> 25 #include <asm/mach/irq.h> 26 27 #include <mach/at91_pmc.h> 28 #include <mach/gpio.h> 29 #include <mach/cpu.h> 30 31 #include "generic.h" 32 #include "pm.h" 33 34 /* 35 * Show the reason for the previous system reset. 36 */ 37 #if defined(AT91_SHDWC) 38 39 #include <mach/at91_rstc.h> 40 #include <mach/at91_shdwc.h> 41 42 static void __init show_reset_status(void) 43 { 44 static char reset[] __initdata = "reset"; 45 46 static char general[] __initdata = "general"; 47 static char wakeup[] __initdata = "wakeup"; 48 static char watchdog[] __initdata = "watchdog"; 49 static char software[] __initdata = "software"; 50 static char user[] __initdata = "user"; 51 static char unknown[] __initdata = "unknown"; 52 53 static char signal[] __initdata = "signal"; 54 static char rtc[] __initdata = "rtc"; 55 static char rtt[] __initdata = "rtt"; 56 static char restore[] __initdata = "power-restored"; 57 58 char *reason, *r2 = reset; 59 u32 reset_type, wake_type; 60 61 reset_type = at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_RSTTYP; 62 wake_type = at91_sys_read(AT91_SHDW_SR); 63 64 switch (reset_type) { 65 case AT91_RSTC_RSTTYP_GENERAL: 66 reason = general; 67 break; 68 case AT91_RSTC_RSTTYP_WAKEUP: 69 /* board-specific code enabled the wakeup sources */ 70 reason = wakeup; 71 72 /* "wakeup signal" */ 73 if (wake_type & AT91_SHDW_WAKEUP0) 74 r2 = signal; 75 else { 76 r2 = reason; 77 if (wake_type & AT91_SHDW_RTTWK) /* rtt wakeup */ 78 reason = rtt; 79 else if (wake_type & AT91_SHDW_RTCWK) /* rtc wakeup */ 80 reason = rtc; 81 else if (wake_type == 0) /* power-restored wakeup */ 82 reason = restore; 83 else /* unknown wakeup */ 84 reason = unknown; 85 } 86 break; 87 case AT91_RSTC_RSTTYP_WATCHDOG: 88 reason = watchdog; 89 break; 90 case AT91_RSTC_RSTTYP_SOFTWARE: 91 reason = software; 92 break; 93 case AT91_RSTC_RSTTYP_USER: 94 reason = user; 95 break; 96 default: 97 reason = unknown; 98 break; 99 } 100 pr_info("AT91: Starting after %s %s\n", reason, r2); 101 } 102 #else 103 static void __init show_reset_status(void) {} 104 #endif 105 106 107 static int at91_pm_valid_state(suspend_state_t state) 108 { 109 switch (state) { 110 case PM_SUSPEND_ON: 111 case PM_SUSPEND_STANDBY: 112 case PM_SUSPEND_MEM: 113 return 1; 114 115 default: 116 return 0; 117 } 118 } 119 120 121 static suspend_state_t target_state; 122 123 /* 124 * Called after processes are frozen, but before we shutdown devices. 125 */ 126 static int at91_pm_begin(suspend_state_t state) 127 { 128 target_state = state; 129 return 0; 130 } 131 132 /* 133 * Verify that all the clocks are correct before entering 134 * slow-clock mode. 135 */ 136 static int at91_pm_verify_clocks(void) 137 { 138 unsigned long scsr; 139 int i; 140 141 scsr = at91_sys_read(AT91_PMC_SCSR); 142 143 /* USB must not be using PLLB */ 144 if (cpu_is_at91rm9200()) { 145 if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) { 146 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); 147 return 0; 148 } 149 } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263() 150 || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) { 151 if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) { 152 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); 153 return 0; 154 } 155 } else if (cpu_is_at91cap9()) { 156 if ((scsr & AT91CAP9_PMC_UHP) != 0) { 157 pr_err("AT91: PM - Suspend-to-RAM with USB still active\n"); 158 return 0; 159 } 160 } 161 162 #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS 163 /* PCK0..PCK3 must be disabled, or configured to use clk32k */ 164 for (i = 0; i < 4; i++) { 165 u32 css; 166 167 if ((scsr & (AT91_PMC_PCK0 << i)) == 0) 168 continue; 169 170 css = at91_sys_read(AT91_PMC_PCKR(i)) & AT91_PMC_CSS; 171 if (css != AT91_PMC_CSS_SLOW) { 172 pr_err("AT91: PM - Suspend-to-RAM with PCK%d src %d\n", i, css); 173 return 0; 174 } 175 } 176 #endif 177 178 return 1; 179 } 180 181 /* 182 * Call this from platform driver suspend() to see how deeply to suspend. 183 * For example, some controllers (like OHCI) need one of the PLL clocks 184 * in order to act as a wakeup source, and those are not available when 185 * going into slow clock mode. 186 * 187 * REVISIT: generalize as clk_will_be_available(clk)? Other platforms have 188 * the very same problem (but not using at91 main_clk), and it'd be better 189 * to add one generic API rather than lots of platform-specific ones. 190 */ 191 int at91_suspend_entering_slow_clock(void) 192 { 193 return (target_state == PM_SUSPEND_MEM); 194 } 195 EXPORT_SYMBOL(at91_suspend_entering_slow_clock); 196 197 198 static void (*slow_clock)(void); 199 200 #ifdef CONFIG_AT91_SLOW_CLOCK 201 extern void at91_slow_clock(void); 202 extern u32 at91_slow_clock_sz; 203 #endif 204 205 206 static int at91_pm_enter(suspend_state_t state) 207 { 208 u32 saved_lpr; 209 at91_gpio_suspend(); 210 at91_irq_suspend(); 211 212 pr_debug("AT91: PM - wake mask %08x, pm state %d\n", 213 /* remember all the always-wake irqs */ 214 (at91_sys_read(AT91_PMC_PCSR) 215 | (1 << AT91_ID_FIQ) 216 | (1 << AT91_ID_SYS) 217 | (at91_extern_irq)) 218 & at91_sys_read(AT91_AIC_IMR), 219 state); 220 221 switch (state) { 222 /* 223 * Suspend-to-RAM is like STANDBY plus slow clock mode, so 224 * drivers must suspend more deeply: only the master clock 225 * controller may be using the main oscillator. 226 */ 227 case PM_SUSPEND_MEM: 228 /* 229 * Ensure that clocks are in a valid state. 230 */ 231 if (!at91_pm_verify_clocks()) 232 goto error; 233 234 /* 235 * Enter slow clock mode by switching over to clk32k and 236 * turning off the main oscillator; reverse on wakeup. 237 */ 238 if (slow_clock) { 239 #ifdef CONFIG_AT91_SLOW_CLOCK 240 /* copy slow_clock handler to SRAM, and call it */ 241 memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz); 242 #endif 243 slow_clock(); 244 break; 245 } else { 246 pr_info("AT91: PM - no slow clock mode enabled ...\n"); 247 /* FALLTHROUGH leaving master clock alone */ 248 } 249 250 /* 251 * STANDBY mode has *all* drivers suspended; ignores irqs not 252 * marked as 'wakeup' event sources; and reduces DRAM power. 253 * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and 254 * nothing fancy done with main or cpu clocks. 255 */ 256 case PM_SUSPEND_STANDBY: 257 /* 258 * NOTE: the Wait-for-Interrupt instruction needs to be 259 * in icache so no SDRAM accesses are needed until the 260 * wakeup IRQ occurs and self-refresh is terminated. 261 * For ARM 926 based chips, this requirement is weaker 262 * as at91sam9 can access a RAM in self-refresh mode. 263 */ 264 asm volatile ( "mov r0, #0\n\t" 265 "b 1f\n\t" 266 ".align 5\n\t" 267 "1: mcr p15, 0, r0, c7, c10, 4\n\t" 268 : /* no output */ 269 : /* no input */ 270 : "r0"); 271 saved_lpr = sdram_selfrefresh_enable(); 272 wait_for_interrupt_enable(); 273 sdram_selfrefresh_disable(saved_lpr); 274 break; 275 276 case PM_SUSPEND_ON: 277 cpu_do_idle(); 278 break; 279 280 default: 281 pr_debug("AT91: PM - bogus suspend state %d\n", state); 282 goto error; 283 } 284 285 pr_debug("AT91: PM - wakeup %08x\n", 286 at91_sys_read(AT91_AIC_IPR) & at91_sys_read(AT91_AIC_IMR)); 287 288 error: 289 target_state = PM_SUSPEND_ON; 290 at91_irq_resume(); 291 at91_gpio_resume(); 292 return 0; 293 } 294 295 /* 296 * Called right prior to thawing processes. 297 */ 298 static void at91_pm_end(void) 299 { 300 target_state = PM_SUSPEND_ON; 301 } 302 303 304 static const struct platform_suspend_ops at91_pm_ops = { 305 .valid = at91_pm_valid_state, 306 .begin = at91_pm_begin, 307 .enter = at91_pm_enter, 308 .end = at91_pm_end, 309 }; 310 311 static int __init at91_pm_init(void) 312 { 313 #ifdef CONFIG_AT91_SLOW_CLOCK 314 slow_clock = (void *) (AT91_IO_VIRT_BASE - at91_slow_clock_sz); 315 #endif 316 317 pr_info("AT91: Power Management%s\n", (slow_clock ? " (with slow clock mode)" : "")); 318 319 #ifdef CONFIG_ARCH_AT91RM9200 320 /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */ 321 at91_sys_write(AT91_SDRAMC_LPR, 0); 322 #endif 323 324 suspend_set_ops(&at91_pm_ops); 325 326 show_reset_status(); 327 return 0; 328 } 329 arch_initcall(at91_pm_init); 330