[TG3]: Set minimal hw interrupt mitigation.
[linux-2.6/verdex.git] / arch / mips / au1000 / common / power.c
blobc40daccbb5b161c99b8f4762e5c84a484a14164a
1 /*
2 * BRIEF MODULE DESCRIPTION
3 * Au1000 Power Management routines.
5 * Copyright 2001 MontaVista Software Inc.
6 * Author: MontaVista Software, Inc.
7 * ppopov@mvista.com or source@mvista.com
9 * Some of the routines are right out of init/main.c, whose
10 * copyrights apply here.
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include <linux/config.h>
33 #include <linux/init.h>
34 #include <linux/pm.h>
35 #include <linux/slab.h>
36 #include <linux/sysctl.h>
38 #include <asm/string.h>
39 #include <asm/uaccess.h>
40 #include <asm/io.h>
41 #include <asm/system.h>
42 #include <asm/mach-au1x00/au1000.h>
44 #ifdef CONFIG_PM
46 #define DEBUG 1
47 #ifdef DEBUG
48 # define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
49 #else
50 # define DPRINTK(fmt, args...)
51 #endif
53 static void calibrate_delay(void);
55 extern void set_au1x00_speed(unsigned int new_freq);
56 extern unsigned int get_au1x00_speed(void);
57 extern unsigned long get_au1x00_uart_baud_base(void);
58 extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);
59 extern unsigned long save_local_and_disable(int controller);
60 extern void restore_local_and_enable(int controller, unsigned long mask);
61 extern void local_enable_irq(unsigned int irq_nr);
63 /* Quick acpi hack. This will have to change! */
64 #define CTL_ACPI 9999
65 #define ACPI_S1_SLP_TYP 19
66 #define ACPI_SLEEP 21
69 static DEFINE_SPINLOCK(pm_lock);
71 /* We need to save/restore a bunch of core registers that are
72 * either volatile or reset to some state across a processor sleep.
73 * If reading a register doesn't provide a proper result for a
74 * later restore, we have to provide a function for loading that
75 * register and save a copy.
77 * We only have to save/restore registers that aren't otherwise
78 * done as part of a driver pm_* function.
80 static uint sleep_aux_pll_cntrl;
81 static uint sleep_cpu_pll_cntrl;
82 static uint sleep_pin_function;
83 static uint sleep_uart0_inten;
84 static uint sleep_uart0_fifoctl;
85 static uint sleep_uart0_linectl;
86 static uint sleep_uart0_clkdiv;
87 static uint sleep_uart0_enable;
88 static uint sleep_usbhost_enable;
89 static uint sleep_usbdev_enable;
90 static uint sleep_static_memctlr[4][3];
92 /* Define this to cause the value you write to /proc/sys/pm/sleep to
93 * set the TOY timer for the amount of time you want to sleep.
94 * This is done mainly for testing, but may be useful in other cases.
95 * The value is number of 32KHz ticks to sleep.
97 #define SLEEP_TEST_TIMEOUT 1
98 #ifdef SLEEP_TEST_TIMEOUT
99 static int sleep_ticks;
100 void wakeup_counter0_set(int ticks);
101 #endif
103 static void
104 save_core_regs(void)
106 extern void save_au1xxx_intctl(void);
107 extern void pm_eth0_shutdown(void);
109 /* Do the serial ports.....these really should be a pm_*
110 * registered function by the driver......but of course the
111 * standard serial driver doesn't understand our Au1xxx
112 * unique registers.
114 sleep_uart0_inten = au_readl(UART0_ADDR + UART_IER);
115 sleep_uart0_fifoctl = au_readl(UART0_ADDR + UART_FCR);
116 sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR);
117 sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
118 sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
120 /* Shutdown USB host/device.
122 sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);
124 /* There appears to be some undocumented reset register....
126 au_writel(0, 0xb0100004); au_sync();
127 au_writel(0, USB_HOST_CONFIG); au_sync();
129 sleep_usbdev_enable = au_readl(USBD_ENABLE);
130 au_writel(0, USBD_ENABLE); au_sync();
132 /* Save interrupt controller state.
134 save_au1xxx_intctl();
136 /* Clocks and PLLs.
138 sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL);
140 /* We don't really need to do this one, but unless we
141 * write it again it won't have a valid value if we
142 * happen to read it.
144 sleep_cpu_pll_cntrl = au_readl(SYS_CPUPLL);
146 sleep_pin_function = au_readl(SYS_PINFUNC);
148 /* Save the static memory controller configuration.
150 sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
151 sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0);
152 sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);
153 sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1);
154 sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1);
155 sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1);
156 sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2);
157 sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2);
158 sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2);
159 sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3);
160 sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3);
161 sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
164 static void
165 restore_core_regs(void)
167 extern void restore_au1xxx_intctl(void);
168 extern void wakeup_counter0_adjust(void);
170 au_writel(sleep_aux_pll_cntrl, SYS_AUXPLL); au_sync();
171 au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync();
172 au_writel(sleep_pin_function, SYS_PINFUNC); au_sync();
174 /* Restore the static memory controller configuration.
176 au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
177 au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
178 au_writel(sleep_static_memctlr[0][2], MEM_STADDR0);
179 au_writel(sleep_static_memctlr[1][0], MEM_STCFG1);
180 au_writel(sleep_static_memctlr[1][1], MEM_STTIME1);
181 au_writel(sleep_static_memctlr[1][2], MEM_STADDR1);
182 au_writel(sleep_static_memctlr[2][0], MEM_STCFG2);
183 au_writel(sleep_static_memctlr[2][1], MEM_STTIME2);
184 au_writel(sleep_static_memctlr[2][2], MEM_STADDR2);
185 au_writel(sleep_static_memctlr[3][0], MEM_STCFG3);
186 au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
187 au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);
189 /* Enable the UART if it was enabled before sleep.
190 * I guess I should define module control bits........
192 if (sleep_uart0_enable & 0x02) {
193 au_writel(0, UART0_ADDR + UART_MOD_CNTRL); au_sync();
194 au_writel(1, UART0_ADDR + UART_MOD_CNTRL); au_sync();
195 au_writel(3, UART0_ADDR + UART_MOD_CNTRL); au_sync();
196 au_writel(sleep_uart0_inten, UART0_ADDR + UART_IER); au_sync();
197 au_writel(sleep_uart0_fifoctl, UART0_ADDR + UART_FCR); au_sync();
198 au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync();
199 au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync();
202 restore_au1xxx_intctl();
203 wakeup_counter0_adjust();
206 unsigned long suspend_mode;
208 void wakeup_from_suspend(void)
210 suspend_mode = 0;
213 int au_sleep(void)
215 unsigned long wakeup, flags;
216 extern void save_and_sleep(void);
218 spin_lock_irqsave(&pm_lock,flags);
220 save_core_regs();
222 flush_cache_all();
224 /** The code below is all system dependent and we should probably
225 ** have a function call out of here to set this up. You need
226 ** to configure the GPIO or timer interrupts that will bring
227 ** you out of sleep.
228 ** For testing, the TOY counter wakeup is useful.
231 #if 0
232 au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
234 /* gpio 6 can cause a wake up event */
235 wakeup = au_readl(SYS_WAKEMSK);
236 wakeup &= ~(1 << 8); /* turn off match20 wakeup */
237 wakeup |= 1 << 6; /* turn on gpio 6 wakeup */
238 #else
239 /* For testing, allow match20 to wake us up.
241 #ifdef SLEEP_TEST_TIMEOUT
242 wakeup_counter0_set(sleep_ticks);
243 #endif
244 wakeup = 1 << 8; /* turn on match20 wakeup */
245 wakeup = 0;
246 #endif
247 au_writel(1, SYS_WAKESRC); /* clear cause */
248 au_sync();
249 au_writel(wakeup, SYS_WAKEMSK);
250 au_sync();
252 save_and_sleep();
254 /* after a wakeup, the cpu vectors back to 0x1fc00000 so
255 * it's up to the boot code to get us back here.
257 restore_core_regs();
258 spin_unlock_irqrestore(&pm_lock, flags);
259 return 0;
262 static int pm_do_sleep(ctl_table * ctl, int write, struct file *file,
263 void *buffer, size_t * len)
265 int retval = 0;
266 #ifdef SLEEP_TEST_TIMEOUT
267 #define TMPBUFLEN2 16
268 char buf[TMPBUFLEN2], *p;
269 #endif
271 if (!write) {
272 *len = 0;
273 } else {
274 #ifdef SLEEP_TEST_TIMEOUT
275 if (*len > TMPBUFLEN2 - 1) {
276 return -EFAULT;
278 if (copy_from_user(buf, buffer, *len)) {
279 return -EFAULT;
281 buf[*len] = 0;
282 p = buf;
283 sleep_ticks = simple_strtoul(p, &p, 0);
284 #endif
285 retval = pm_send_all(PM_SUSPEND, (void *) 2);
287 if (retval)
288 return retval;
290 au_sleep();
291 retval = pm_send_all(PM_RESUME, (void *) 0);
293 return retval;
296 static int pm_do_suspend(ctl_table * ctl, int write, struct file *file,
297 void *buffer, size_t * len)
299 int retval = 0;
300 void au1k_wait(void);
302 if (!write) {
303 *len = 0;
304 } else {
305 retval = pm_send_all(PM_SUSPEND, (void *) 2);
306 if (retval)
307 return retval;
308 suspend_mode = 1;
309 au1k_wait();
310 retval = pm_send_all(PM_RESUME, (void *) 0);
312 return retval;
316 static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
317 void *buffer, size_t * len)
319 int retval = 0, i;
320 unsigned long val, pll;
321 #define TMPBUFLEN 64
322 #define MAX_CPU_FREQ 396
323 char buf[TMPBUFLEN], *p;
324 unsigned long flags, intc0_mask, intc1_mask;
325 unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
326 old_refresh;
327 unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
329 spin_lock_irqsave(&pm_lock, flags);
330 if (!write) {
331 *len = 0;
332 } else {
333 /* Parse the new frequency */
334 if (*len > TMPBUFLEN - 1) {
335 spin_unlock_irqrestore(&pm_lock, flags);
336 return -EFAULT;
338 if (copy_from_user(buf, buffer, *len)) {
339 spin_unlock_irqrestore(&pm_lock, flags);
340 return -EFAULT;
342 buf[*len] = 0;
343 p = buf;
344 val = simple_strtoul(p, &p, 0);
345 if (val > MAX_CPU_FREQ) {
346 spin_unlock_irqrestore(&pm_lock, flags);
347 return -EFAULT;
350 pll = val / 12;
351 if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */
352 /* revisit this for higher speed cpus */
353 spin_unlock_irqrestore(&pm_lock, flags);
354 return -EFAULT;
357 old_baud_base = get_au1x00_uart_baud_base();
358 old_cpu_freq = get_au1x00_speed();
360 new_cpu_freq = pll * 12 * 1000000;
361 new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
362 set_au1x00_speed(new_cpu_freq);
363 set_au1x00_uart_baud_base(new_baud_base);
365 old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
366 new_refresh =
367 ((old_refresh * new_cpu_freq) /
368 old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
370 au_writel(pll, SYS_CPUPLL);
371 au_sync_delay(1);
372 au_writel(new_refresh, MEM_SDREFCFG);
373 au_sync_delay(1);
375 for (i = 0; i < 4; i++) {
376 if (au_readl
377 (UART_BASE + UART_MOD_CNTRL +
378 i * 0x00100000) == 3) {
379 old_clk =
380 au_readl(UART_BASE + UART_CLK +
381 i * 0x00100000);
382 // baud_rate = baud_base/clk
383 baud_rate = old_baud_base / old_clk;
384 /* we won't get an exact baud rate and the error
385 * could be significant enough that our new
386 * calculation will result in a clock that will
387 * give us a baud rate that's too far off from
388 * what we really want.
390 if (baud_rate > 100000)
391 baud_rate = 115200;
392 else if (baud_rate > 50000)
393 baud_rate = 57600;
394 else if (baud_rate > 30000)
395 baud_rate = 38400;
396 else if (baud_rate > 17000)
397 baud_rate = 19200;
398 else
399 (baud_rate = 9600);
400 // new_clk = new_baud_base/baud_rate
401 new_clk = new_baud_base / baud_rate;
402 au_writel(new_clk,
403 UART_BASE + UART_CLK +
404 i * 0x00100000);
405 au_sync_delay(10);
411 /* We don't want _any_ interrupts other than
412 * match20. Otherwise our calibrate_delay()
413 * calculation will be off, potentially a lot.
415 intc0_mask = save_local_and_disable(0);
416 intc1_mask = save_local_and_disable(1);
417 local_enable_irq(AU1000_TOY_MATCH2_INT);
418 spin_unlock_irqrestore(&pm_lock, flags);
419 calibrate_delay();
420 restore_local_and_enable(0, intc0_mask);
421 restore_local_and_enable(1, intc1_mask);
422 return retval;
426 static struct ctl_table pm_table[] = {
427 {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, &pm_do_suspend},
428 {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &pm_do_sleep},
429 {CTL_ACPI, "freq", NULL, 0, 0600, NULL, &pm_do_freq},
433 static struct ctl_table pm_dir_table[] = {
434 {CTL_ACPI, "pm", NULL, 0, 0555, pm_table},
439 * Initialize power interface
441 static int __init pm_init(void)
443 register_sysctl_table(pm_dir_table, 1);
444 return 0;
447 __initcall(pm_init);
451 * This is right out of init/main.c
454 /* This is the number of bits of precision for the loops_per_jiffy. Each
455 bit takes on average 1.5/HZ seconds. This (like the original) is a little
456 better than 1% */
457 #define LPS_PREC 8
459 static void calibrate_delay(void)
461 unsigned long ticks, loopbit;
462 int lps_precision = LPS_PREC;
464 loops_per_jiffy = (1 << 12);
466 while (loops_per_jiffy <<= 1) {
467 /* wait for "start of" clock tick */
468 ticks = jiffies;
469 while (ticks == jiffies)
470 /* nothing */ ;
471 /* Go .. */
472 ticks = jiffies;
473 __delay(loops_per_jiffy);
474 ticks = jiffies - ticks;
475 if (ticks)
476 break;
479 /* Do a binary approximation to get loops_per_jiffy set to equal one clock
480 (up to lps_precision bits) */
481 loops_per_jiffy >>= 1;
482 loopbit = loops_per_jiffy;
483 while (lps_precision-- && (loopbit >>= 1)) {
484 loops_per_jiffy |= loopbit;
485 ticks = jiffies;
486 while (ticks == jiffies);
487 ticks = jiffies;
488 __delay(loops_per_jiffy);
489 if (jiffies != ticks) /* longer than 1 tick */
490 loops_per_jiffy &= ~loopbit;
493 #endif /* CONFIG_PM */