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>
35 #include <linux/slab.h>
36 #include <linux/sysctl.h>
38 #include <asm/string.h>
39 #include <asm/uaccess.h>
41 #include <asm/system.h>
42 #include <asm/mach-au1x00/au1000.h>
48 # define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
50 # define DPRINTK(fmt, args...)
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! */
65 #define ACPI_S1_SLP_TYP 19
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
);
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
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();
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
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
);
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)
215 unsigned long wakeup
, flags
;
216 extern void save_and_sleep(void);
218 spin_lock_irqsave(&pm_lock
,flags
);
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
228 ** For testing, the TOY counter wakeup is useful.
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 */
239 /* For testing, allow match20 to wake us up.
241 #ifdef SLEEP_TEST_TIMEOUT
242 wakeup_counter0_set(sleep_ticks
);
244 wakeup
= 1 << 8; /* turn on match20 wakeup */
247 au_writel(1, SYS_WAKESRC
); /* clear cause */
249 au_writel(wakeup
, SYS_WAKEMSK
);
254 /* after a wakeup, the cpu vectors back to 0x1fc00000 so
255 * it's up to the boot code to get us back here.
258 spin_unlock_irqrestore(&pm_lock
, flags
);
262 static int pm_do_sleep(ctl_table
* ctl
, int write
, struct file
*file
,
263 void *buffer
, size_t * len
)
266 #ifdef SLEEP_TEST_TIMEOUT
267 #define TMPBUFLEN2 16
268 char buf
[TMPBUFLEN2
], *p
;
274 #ifdef SLEEP_TEST_TIMEOUT
275 if (*len
> TMPBUFLEN2
- 1) {
278 if (copy_from_user(buf
, buffer
, *len
)) {
283 sleep_ticks
= simple_strtoul(p
, &p
, 0);
285 retval
= pm_send_all(PM_SUSPEND
, (void *) 2);
291 retval
= pm_send_all(PM_RESUME
, (void *) 0);
296 static int pm_do_suspend(ctl_table
* ctl
, int write
, struct file
*file
,
297 void *buffer
, size_t * len
)
300 void au1k_wait(void);
305 retval
= pm_send_all(PM_SUSPEND
, (void *) 2);
310 retval
= pm_send_all(PM_RESUME
, (void *) 0);
316 static int pm_do_freq(ctl_table
* ctl
, int write
, struct file
*file
,
317 void *buffer
, size_t * len
)
320 unsigned long val
, pll
;
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
,
327 unsigned long new_baud_base
, new_cpu_freq
, new_clk
, new_refresh
;
329 spin_lock_irqsave(&pm_lock
, flags
);
333 /* Parse the new frequency */
334 if (*len
> TMPBUFLEN
- 1) {
335 spin_unlock_irqrestore(&pm_lock
, flags
);
338 if (copy_from_user(buf
, buffer
, *len
)) {
339 spin_unlock_irqrestore(&pm_lock
, flags
);
344 val
= simple_strtoul(p
, &p
, 0);
345 if (val
> MAX_CPU_FREQ
) {
346 spin_unlock_irqrestore(&pm_lock
, flags
);
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
);
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;
367 ((old_refresh
* new_cpu_freq
) /
368 old_cpu_freq
) | (au_readl(MEM_SDREFCFG
) & ~0x1ffffff);
370 au_writel(pll
, SYS_CPUPLL
);
372 au_writel(new_refresh
, MEM_SDREFCFG
);
375 for (i
= 0; i
< 4; i
++) {
377 (UART_BASE
+ UART_MOD_CNTRL
+
378 i
* 0x00100000) == 3) {
380 au_readl(UART_BASE
+ UART_CLK
+
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)
392 else if (baud_rate
> 50000)
394 else if (baud_rate
> 30000)
396 else if (baud_rate
> 17000)
400 // new_clk = new_baud_base/baud_rate
401 new_clk
= new_baud_base
/ baud_rate
;
403 UART_BASE
+ UART_CLK
+
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
);
420 restore_local_and_enable(0, intc0_mask
);
421 restore_local_and_enable(1, intc1_mask
);
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);
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
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 */
469 while (ticks
== jiffies
)
473 __delay(loops_per_jiffy
);
474 ticks
= jiffies
- ticks
;
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
;
486 while (ticks
== jiffies
);
488 __delay(loops_per_jiffy
);
489 if (jiffies
!= ticks
) /* longer than 1 tick */
490 loops_per_jiffy
&= ~loopbit
;
493 #endif /* CONFIG_PM */