aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/alchemy/common/power.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/alchemy/common/power.c')
-rw-r--r--arch/mips/alchemy/common/power.c266
1 files changed, 151 insertions, 115 deletions
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
index 997dd56bcc5e..f08312b10d04 100644
--- a/arch/mips/alchemy/common/power.c
+++ b/arch/mips/alchemy/common/power.c
@@ -35,7 +35,6 @@
35#include <linux/jiffies.h> 35#include <linux/jiffies.h>
36 36
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
38#include <asm/cacheflush.h>
39#include <asm/mach-au1x00/au1000.h> 38#include <asm/mach-au1x00/au1000.h>
40 39
41#ifdef CONFIG_PM 40#ifdef CONFIG_PM
@@ -47,8 +46,6 @@
47#define DPRINTK(fmt, args...) 46#define DPRINTK(fmt, args...)
48#endif 47#endif
49 48
50static void au1000_calibrate_delay(void);
51
52extern unsigned long save_local_and_disable(int controller); 49extern unsigned long save_local_and_disable(int controller);
53extern void restore_local_and_enable(int controller, unsigned long mask); 50extern void restore_local_and_enable(int controller, unsigned long mask);
54 51
@@ -64,17 +61,15 @@ static DEFINE_SPINLOCK(pm_lock);
64 * We only have to save/restore registers that aren't otherwise 61 * We only have to save/restore registers that aren't otherwise
65 * done as part of a driver pm_* function. 62 * done as part of a driver pm_* function.
66 */ 63 */
67static unsigned int sleep_aux_pll_cntrl; 64static unsigned int sleep_uart0_inten;
68static unsigned int sleep_cpu_pll_cntrl; 65static unsigned int sleep_uart0_fifoctl;
69static unsigned int sleep_pin_function; 66static unsigned int sleep_uart0_linectl;
70static unsigned int sleep_uart0_inten; 67static unsigned int sleep_uart0_clkdiv;
71static unsigned int sleep_uart0_fifoctl; 68static unsigned int sleep_uart0_enable;
72static unsigned int sleep_uart0_linectl; 69static unsigned int sleep_usb[2];
73static unsigned int sleep_uart0_clkdiv; 70static unsigned int sleep_sys_clocks[5];
74static unsigned int sleep_uart0_enable; 71static unsigned int sleep_sys_pinfunc;
75static unsigned int sleep_usbhost_enable; 72static unsigned int sleep_static_memctlr[4][3];
76static unsigned int sleep_usbdev_enable;
77static unsigned int sleep_static_memctlr[4][3];
78 73
79/* 74/*
80 * Define this to cause the value you write to /proc/sys/pm/sleep to 75 * Define this to cause the value you write to /proc/sys/pm/sleep to
@@ -108,31 +103,45 @@ static void save_core_regs(void)
108 sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR); 103 sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR);
109 sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK); 104 sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
110 sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); 105 sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
106 au_sync();
111 107
108#ifndef CONFIG_SOC_AU1200
112 /* Shutdown USB host/device. */ 109 /* Shutdown USB host/device. */
113 sleep_usbhost_enable = au_readl(USB_HOST_CONFIG); 110 sleep_usb[0] = au_readl(USB_HOST_CONFIG);
114 111
115 /* There appears to be some undocumented reset register.... */ 112 /* There appears to be some undocumented reset register.... */
116 au_writel(0, 0xb0100004); au_sync(); 113 au_writel(0, 0xb0100004);
117 au_writel(0, USB_HOST_CONFIG); au_sync(); 114 au_sync();
115 au_writel(0, USB_HOST_CONFIG);
116 au_sync();
117
118 sleep_usb[1] = au_readl(USBD_ENABLE);
119 au_writel(0, USBD_ENABLE);
120 au_sync();
121
122#else /* AU1200 */
118 123
119 sleep_usbdev_enable = au_readl(USBD_ENABLE); 124 /* enable access to OTG mmio so we can save OTG CAP/MUX.
120 au_writel(0, USBD_ENABLE); au_sync(); 125 * FIXME: write an OTG driver and move this stuff there!
126 */
127 au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4);
128 au_sync();
129 sleep_usb[0] = au_readl(0xb4020020); /* OTG_CAP */
130 sleep_usb[1] = au_readl(0xb4020024); /* OTG_MUX */
131#endif
121 132
122 /* Save interrupt controller state. */ 133 /* Save interrupt controller state. */
123 save_au1xxx_intctl(); 134 save_au1xxx_intctl();
124 135
125 /* Clocks and PLLs. */ 136 /* Clocks and PLLs. */
126 sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL); 137 sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0);
138 sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1);
139 sleep_sys_clocks[2] = au_readl(SYS_CLKSRC);
140 sleep_sys_clocks[3] = au_readl(SYS_CPUPLL);
141 sleep_sys_clocks[4] = au_readl(SYS_AUXPLL);
127 142
128 /* 143 /* pin mux config */
129 * We don't really need to do this one, but unless we 144 sleep_sys_pinfunc = au_readl(SYS_PINFUNC);
130 * write it again it won't have a valid value if we
131 * happen to read it.
132 */
133 sleep_cpu_pll_cntrl = au_readl(SYS_CPUPLL);
134
135 sleep_pin_function = au_readl(SYS_PINFUNC);
136 145
137 /* Save the static memory controller configuration. */ 146 /* Save the static memory controller configuration. */
138 sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); 147 sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
@@ -151,12 +160,37 @@ static void save_core_regs(void)
151 160
152static void restore_core_regs(void) 161static void restore_core_regs(void)
153{ 162{
154 extern void restore_au1xxx_intctl(void); 163 /* restore clock configuration. Writing CPUPLL last will
155 extern void wakeup_counter0_adjust(void); 164 * stall a bit and stabilize other clocks (unless this is
165 * one of those Au1000 with a write-only PLL, where we dont
166 * have a valid value)
167 */
168 au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0);
169 au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1);
170 au_writel(sleep_sys_clocks[2], SYS_CLKSRC);
171 au_writel(sleep_sys_clocks[4], SYS_AUXPLL);
172 if (!au1xxx_cpu_has_pll_wo())
173 au_writel(sleep_sys_clocks[3], SYS_CPUPLL);
174 au_sync();
175
176 au_writel(sleep_sys_pinfunc, SYS_PINFUNC);
177 au_sync();
178
179#ifndef CONFIG_SOC_AU1200
180 au_writel(sleep_usb[0], USB_HOST_CONFIG);
181 au_writel(sleep_usb[1], USBD_ENABLE);
182 au_sync();
183#else
184 /* enable accces to OTG memory */
185 au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4);
186 au_sync();
156 187
157 au_writel(sleep_aux_pll_cntrl, SYS_AUXPLL); au_sync(); 188 /* restore OTG caps and port mux. */
158 au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync(); 189 au_writel(sleep_usb[0], 0xb4020020 + 0); /* OTG_CAP */
159 au_writel(sleep_pin_function, SYS_PINFUNC); au_sync(); 190 au_sync();
191 au_writel(sleep_usb[1], 0xb4020020 + 4); /* OTG_MUX */
192 au_sync();
193#endif
160 194
161 /* Restore the static memory controller configuration. */ 195 /* Restore the static memory controller configuration. */
162 au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); 196 au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
@@ -196,16 +230,45 @@ void wakeup_from_suspend(void)
196 suspend_mode = 0; 230 suspend_mode = 0;
197} 231}
198 232
199int au_sleep(void) 233void au_sleep(void)
234{
235 save_core_regs();
236 au1xxx_save_and_sleep();
237 restore_core_regs();
238}
239
240static int pm_do_sleep(ctl_table *ctl, int write, struct file *file,
241 void __user *buffer, size_t *len, loff_t *ppos)
200{ 242{
201 unsigned long wakeup, flags; 243 unsigned long wakeup, flags;
202 extern void save_and_sleep(void); 244 int ret;
245#ifdef SLEEP_TEST_TIMEOUT
246#define TMPBUFLEN2 16
247 char buf[TMPBUFLEN2], *p;
248#endif
203 249
204 spin_lock_irqsave(&pm_lock, flags); 250 spin_lock_irqsave(&pm_lock, flags);
205 251
206 save_core_regs(); 252 if (!write) {
253 *len = 0;
254 ret = 0;
255 goto out_unlock;
256 };
207 257
208 flush_cache_all(); 258#ifdef SLEEP_TEST_TIMEOUT
259 if (*len > TMPBUFLEN2 - 1) {
260 ret = -EFAULT;
261 goto out_unlock;
262 }
263 if (copy_from_user(buf, buffer, *len)) {
264 return -EFAULT;
265 goto out_unlock;
266 }
267 buf[*len] = 0;
268 p = buf;
269 sleep_ticks = simple_strtoul(p, &p, 0);
270 wakeup_counter0_set(sleep_ticks);
271#endif
209 272
210 /** 273 /**
211 ** The code below is all system dependent and we should probably 274 ** The code below is all system dependent and we should probably
@@ -223,9 +286,6 @@ int au_sleep(void)
223 wakeup |= 1 << 6; /* turn on GPIO 6 wakeup */ 286 wakeup |= 1 << 6; /* turn on GPIO 6 wakeup */
224#else 287#else
225 /* For testing, allow match20 to wake us up. */ 288 /* For testing, allow match20 to wake us up. */
226#ifdef SLEEP_TEST_TIMEOUT
227 wakeup_counter0_set(sleep_ticks);
228#endif
229 wakeup = 1 << 8; /* turn on match20 wakeup */ 289 wakeup = 1 << 8; /* turn on match20 wakeup */
230 wakeup = 0; 290 wakeup = 0;
231#endif 291#endif
@@ -234,41 +294,62 @@ int au_sleep(void)
234 au_writel(wakeup, SYS_WAKEMSK); 294 au_writel(wakeup, SYS_WAKEMSK);
235 au_sync(); 295 au_sync();
236 296
237 save_and_sleep(); 297 au_sleep();
298 ret = 0;
238 299
239 /* 300out_unlock:
240 * After a wakeup, the cpu vectors back to 0x1fc00000, so
241 * it's up to the boot code to get us back here.
242 */
243 restore_core_regs();
244 spin_unlock_irqrestore(&pm_lock, flags); 301 spin_unlock_irqrestore(&pm_lock, flags);
245 return 0; 302 return ret;
246} 303}
247 304
248static int pm_do_sleep(ctl_table *ctl, int write, struct file *file, 305#if !defined(CONFIG_SOC_AU1200) && !defined(CONFIG_SOC_AU1550)
249 void __user *buffer, size_t *len, loff_t *ppos) 306
307/*
308 * This is right out of init/main.c
309 */
310
311/*
312 * This is the number of bits of precision for the loops_per_jiffy.
313 * Each bit takes on average 1.5/HZ seconds. This (like the original)
314 * is a little better than 1%.
315 */
316#define LPS_PREC 8
317
318static void au1000_calibrate_delay(void)
250{ 319{
251#ifdef SLEEP_TEST_TIMEOUT 320 unsigned long ticks, loopbit;
252#define TMPBUFLEN2 16 321 int lps_precision = LPS_PREC;
253 char buf[TMPBUFLEN2], *p;
254#endif
255 322
256 if (!write) 323 loops_per_jiffy = 1 << 12;
257 *len = 0;
258 else {
259#ifdef SLEEP_TEST_TIMEOUT
260 if (*len > TMPBUFLEN2 - 1)
261 return -EFAULT;
262 if (copy_from_user(buf, buffer, *len))
263 return -EFAULT;
264 buf[*len] = 0;
265 p = buf;
266 sleep_ticks = simple_strtoul(p, &p, 0);
267#endif
268 324
269 au_sleep(); 325 while (loops_per_jiffy <<= 1) {
326 /* Wait for "start of" clock tick */
327 ticks = jiffies;
328 while (ticks == jiffies)
329 /* nothing */ ;
330 /* Go ... */
331 ticks = jiffies;
332 __delay(loops_per_jiffy);
333 ticks = jiffies - ticks;
334 if (ticks)
335 break;
336 }
337
338 /*
339 * Do a binary approximation to get loops_per_jiffy set to be equal
340 * one clock (up to lps_precision bits)
341 */
342 loops_per_jiffy >>= 1;
343 loopbit = loops_per_jiffy;
344 while (lps_precision-- && (loopbit >>= 1)) {
345 loops_per_jiffy |= loopbit;
346 ticks = jiffies;
347 while (ticks == jiffies);
348 ticks = jiffies;
349 __delay(loops_per_jiffy);
350 if (jiffies != ticks) /* longer than 1 tick */
351 loops_per_jiffy &= ~loopbit;
270 } 352 }
271 return 0;
272} 353}
273 354
274static int pm_do_freq(ctl_table *ctl, int write, struct file *file, 355static int pm_do_freq(ctl_table *ctl, int write, struct file *file,
@@ -377,7 +458,7 @@ static int pm_do_freq(ctl_table *ctl, int write, struct file *file,
377 458
378 return retval; 459 return retval;
379} 460}
380 461#endif
381 462
382static struct ctl_table pm_table[] = { 463static struct ctl_table pm_table[] = {
383 { 464 {
@@ -388,6 +469,7 @@ static struct ctl_table pm_table[] = {
388 .mode = 0600, 469 .mode = 0600,
389 .proc_handler = &pm_do_sleep 470 .proc_handler = &pm_do_sleep
390 }, 471 },
472#if !defined(CONFIG_SOC_AU1200) && !defined(CONFIG_SOC_AU1550)
391 { 473 {
392 .ctl_name = CTL_UNNUMBERED, 474 .ctl_name = CTL_UNNUMBERED,
393 .procname = "freq", 475 .procname = "freq",
@@ -396,6 +478,7 @@ static struct ctl_table pm_table[] = {
396 .mode = 0600, 478 .mode = 0600,
397 .proc_handler = &pm_do_freq 479 .proc_handler = &pm_do_freq
398 }, 480 },
481#endif
399 {} 482 {}
400}; 483};
401 484
@@ -429,51 +512,4 @@ static int __init pm_init(void)
429 512
430__initcall(pm_init); 513__initcall(pm_init);
431 514
432/*
433 * This is right out of init/main.c
434 */
435
436/*
437 * This is the number of bits of precision for the loops_per_jiffy.
438 * Each bit takes on average 1.5/HZ seconds. This (like the original)
439 * is a little better than 1%.
440 */
441#define LPS_PREC 8
442
443static void au1000_calibrate_delay(void)
444{
445 unsigned long ticks, loopbit;
446 int lps_precision = LPS_PREC;
447
448 loops_per_jiffy = 1 << 12;
449
450 while (loops_per_jiffy <<= 1) {
451 /* Wait for "start of" clock tick */
452 ticks = jiffies;
453 while (ticks == jiffies)
454 /* nothing */ ;
455 /* Go ... */
456 ticks = jiffies;
457 __delay(loops_per_jiffy);
458 ticks = jiffies - ticks;
459 if (ticks)
460 break;
461 }
462
463 /*
464 * Do a binary approximation to get loops_per_jiffy set to be equal
465 * one clock (up to lps_precision bits)
466 */
467 loops_per_jiffy >>= 1;
468 loopbit = loops_per_jiffy;
469 while (lps_precision-- && (loopbit >>= 1)) {
470 loops_per_jiffy |= loopbit;
471 ticks = jiffies;
472 while (ticks == jiffies);
473 ticks = jiffies;
474 __delay(loops_per_jiffy);
475 if (jiffies != ticks) /* longer than 1 tick */
476 loops_per_jiffy &= ~loopbit;
477 }
478}
479#endif /* CONFIG_PM */ 515#endif /* CONFIG_PM */