• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/arch/avr32/mach-at32ap/
1/*
2 * Low-level Power Management code.
3 *
4 * Copyright (C) 2008 Atmel Corporation
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <asm/asm.h>
11#include <asm/asm-offsets.h>
12#include <asm/thread_info.h>
13#include <mach/pm.h>
14
15#include "pm.h"
16#include "sdramc.h"
17
18/* Same as 0xfff00000 but fits in a 21 bit signed immediate */
19#define PM_BASE	-0x100000
20
21	.section .bss, "wa", @nobits
22	.global	disable_idle_sleep
23	.type	disable_idle_sleep, @object
24disable_idle_sleep:
25	.int	4
26	.size	disable_idle_sleep, . - disable_idle_sleep
27
28	/* Keep this close to the irq handlers */
29	.section .irq.text, "ax", @progbits
30
31	.global	cpu_enter_idle
32	.type	cpu_enter_idle, @function
33cpu_enter_idle:
34	mask_interrupts
35	get_thread_info r8
36	ld.w	r9, r8[TI_flags]
37	bld	r9, TIF_NEED_RESCHED
38	brcs	.Lret_from_sleep
39	sbr	r9, TIF_CPU_GOING_TO_SLEEP
40	st.w	r8[TI_flags], r9
41	unmask_interrupts
42	sleep	CPU_SLEEP_IDLE
43	.size	cpu_idle_sleep, . - cpu_idle_sleep
44
45	/*
46	 * Common return path for PM functions that don't run from
47	 * SRAM.
48	 */
49	.global cpu_idle_skip_sleep
50	.type	cpu_idle_skip_sleep, @function
51cpu_idle_skip_sleep:
52	mask_interrupts
53	ld.w	r9, r8[TI_flags]
54	cbr	r9, TIF_CPU_GOING_TO_SLEEP
55	st.w	r8[TI_flags], r9
56.Lret_from_sleep:
57	unmask_interrupts
58	retal	r12
59	.size	cpu_idle_skip_sleep, . - cpu_idle_skip_sleep
60
61#ifdef CONFIG_PM
62	.section .init.text, "ax", @progbits
63
64	.global	pm_exception
65	.type	pm_exception, @function
66pm_exception:
67	/*
68	 * Exceptions are masked when we switch to this handler, so
69	 * we'll only get "unrecoverable" exceptions (offset 0.)
70	 */
71	sub	r12, pc, . - .Lpanic_msg
72	lddpc	pc, .Lpanic_addr
73
74	.align	2
75.Lpanic_addr:
76	.long	panic
77.Lpanic_msg:
78	.asciz	"Unrecoverable exception during suspend\n"
79	.size	pm_exception, . - pm_exception
80
81	.global	pm_irq0
82	.type	pm_irq0, @function
83pm_irq0:
84	/* Disable interrupts and return after the sleep instruction */
85	mfsr	r9, SYSREG_RSR_INT0
86	mtsr	SYSREG_RAR_INT0, r8
87	sbr	r9, SYSREG_GM_OFFSET
88	mtsr	SYSREG_RSR_INT0, r9
89	rete
90
91	/*
92	 * void cpu_enter_standby(unsigned long sdramc_base)
93	 *
94	 * Enter PM_SUSPEND_STANDBY mode. At this point, all drivers
95	 * are suspended and interrupts are disabled. Interrupts
96	 * marked as 'wakeup' event sources may still come along and
97	 * get us out of here.
98	 *
99	 * The SDRAM will be put into self-refresh mode (which does
100	 * not require a clock from the CPU), and the CPU will be put
101	 * into "frozen" mode (HSB bus stopped). The SDRAM controller
102	 * will automatically bring the SDRAM into normal mode on the
103	 * first access, and the power manager will automatically
104	 * start the HSB and CPU clocks upon a wakeup event.
105	 *
106	 * This code uses the same "skip sleep" technique as above.
107	 * It is very important that we jump directly to
108	 * cpu_after_sleep after the sleep instruction since that's
109	 * where we'll end up if the interrupt handler decides that we
110	 * need to skip the sleep instruction.
111	 */
112	.global	pm_standby
113	.type	pm_standby, @function
114pm_standby:
115	/*
116	 * interrupts are already masked at this point, and EVBA
117	 * points to pm_exception above.
118	 */
119	ld.w	r10, r12[SDRAMC_LPR]
120	sub	r8, pc, . - 1f		/* return address for irq handler */
121	mov	r11, SDRAMC_LPR_LPCB_SELF_RFR
122	bfins	r10, r11, 0, 2		/* LPCB <- self Refresh */
123	sync	0			/* flush write buffer */
124	st.w	r12[SDRAMC_LPR], r10	/* put SDRAM in self-refresh mode */
125	ld.w	r11, r12[SDRAMC_LPR]
126	unmask_interrupts
127	sleep	CPU_SLEEP_FROZEN
1281:	mask_interrupts
129	retal	r12
130	.size	pm_standby, . - pm_standby
131
132	.global	pm_suspend_to_ram
133	.type	pm_suspend_to_ram, @function
134pm_suspend_to_ram:
135	/*
136	 * interrupts are already masked at this point, and EVBA
137	 * points to pm_exception above.
138	 */
139	mov	r11, 0
140	cache	r11[2], 8		/* clean all dcache lines */
141	sync	0			/* flush write buffer */
142	ld.w	r10, r12[SDRAMC_LPR]
143	sub	r8, pc, . - 1f		/* return address for irq handler */
144	mov	r11, SDRAMC_LPR_LPCB_SELF_RFR
145	bfins	r10, r11, 0, 2		/* LPCB <- self refresh */
146	st.w	r12[SDRAMC_LPR], r10	/* put SDRAM in self-refresh mode */
147	ld.w	r11, r12[SDRAMC_LPR]
148
149	unmask_interrupts
150	sleep	CPU_SLEEP_STOP
1511:	mask_interrupts
152
153	retal	r12
154	.size	pm_suspend_to_ram, . - pm_suspend_to_ram
155
156	.global	pm_sram_end
157	.type	pm_sram_end, @function
158pm_sram_end:
159	.size	pm_sram_end, 0
160
161#endif /* CONFIG_PM */
162