Commit b6338bdc8305b27688a7feb8689e4ccfd42f0292
Committed by
Russell King
1 parent
5756e9dd0d
Exists in
master
and in
4 other branches
ARM: 6649/1: omap: use fncpy to copy the PM code functions to SRAM
The new fncpy API is better suited* for copying some code to SRAM at runtime. This patch changes the ad-hoc code to the more generic fncpy API. *: 1. fncpy ensures that the thumb mode bit is propagated, 2. fncpy provides the security of type safety between the original function and the sram function pointer. Tested OK on OMAP3 in low power modes (RET/OFF) using omap2plus_defconfig with !CONFIG_THUMB2_KERNEL. Compile tested on OMAP1/2 using omap1_defconfig. Boot tested on OMAP1 & OMAP2 Tested OK with suspend/resume on OMAP2420/n810 Boots fine on osk5912 and n800 Signed-off-by: Jean Pihet <j-pihet@ti.com> Acked-by: Kevin Hilman <khilman@ti.com> Acked-by: Tony Lindgren <tony@atomide.com> Reviewed-by: Dave Martin <dave.martin@linaro.org> Tested-by: Kevin Hilman <khilman@ti.com> Tested-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Showing 11 changed files with 41 additions and 10 deletions Inline Diff
- arch/arm/mach-omap1/pm.h
- arch/arm/mach-omap1/sleep.S
- arch/arm/mach-omap1/sram.S
- arch/arm/mach-omap2/pm.h
- arch/arm/mach-omap2/sleep24xx.S
- arch/arm/mach-omap2/sleep34xx.S
- arch/arm/mach-omap2/sram242x.S
- arch/arm/mach-omap2/sram243x.S
- arch/arm/mach-omap2/sram34xx.S
- arch/arm/plat-omap/include/plat/sram.h
- arch/arm/plat-omap/sram.c
arch/arm/mach-omap1/pm.h
1 | /* | 1 | /* |
2 | * arch/arm/mach-omap1/pm.h | 2 | * arch/arm/mach-omap1/pm.h |
3 | * | 3 | * |
4 | * Header file for OMAP1 Power Management Routines | 4 | * Header file for OMAP1 Power Management Routines |
5 | * | 5 | * |
6 | * Author: MontaVista Software, Inc. | 6 | * Author: MontaVista Software, Inc. |
7 | * support@mvista.com | 7 | * support@mvista.com |
8 | * | 8 | * |
9 | * Copyright 2002 MontaVista Software Inc. | 9 | * Copyright 2002 MontaVista Software Inc. |
10 | * | 10 | * |
11 | * Cleanup 2004 for Linux 2.6 by Dirk Behme <dirk.behme@de.bosch.com> | 11 | * Cleanup 2004 for Linux 2.6 by Dirk Behme <dirk.behme@de.bosch.com> |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or modify it | 13 | * This program is free software; you can redistribute it and/or modify it |
14 | * under the terms of the GNU General Public License as published by the | 14 | * under the terms of the GNU General Public License as published by the |
15 | * Free Software Foundation; either version 2 of the License, or (at your | 15 | * Free Software Foundation; either version 2 of the License, or (at your |
16 | * option) any later version. | 16 | * option) any later version. |
17 | * | 17 | * |
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | 18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED |
19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | 19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | 20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN |
21 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 21 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
24 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | 24 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
25 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | * | 28 | * |
29 | * You should have received a copy of the GNU General Public License along | 29 | * You should have received a copy of the GNU General Public License along |
30 | * with this program; if not, write to the Free Software Foundation, Inc., | 30 | * with this program; if not, write to the Free Software Foundation, Inc., |
31 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 31 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #ifndef __ARCH_ARM_MACH_OMAP1_PM_H | 34 | #ifndef __ARCH_ARM_MACH_OMAP1_PM_H |
35 | #define __ARCH_ARM_MACH_OMAP1_PM_H | 35 | #define __ARCH_ARM_MACH_OMAP1_PM_H |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * ---------------------------------------------------------------------------- | 38 | * ---------------------------------------------------------------------------- |
39 | * Register and offset definitions to be used in PM assembler code | 39 | * Register and offset definitions to be used in PM assembler code |
40 | * ---------------------------------------------------------------------------- | 40 | * ---------------------------------------------------------------------------- |
41 | */ | 41 | */ |
42 | #define CLKGEN_REG_ASM_BASE OMAP1_IO_ADDRESS(0xfffece00) | 42 | #define CLKGEN_REG_ASM_BASE OMAP1_IO_ADDRESS(0xfffece00) |
43 | #define ARM_IDLECT1_ASM_OFFSET 0x04 | 43 | #define ARM_IDLECT1_ASM_OFFSET 0x04 |
44 | #define ARM_IDLECT2_ASM_OFFSET 0x08 | 44 | #define ARM_IDLECT2_ASM_OFFSET 0x08 |
45 | 45 | ||
46 | #define TCMIF_ASM_BASE OMAP1_IO_ADDRESS(0xfffecc00) | 46 | #define TCMIF_ASM_BASE OMAP1_IO_ADDRESS(0xfffecc00) |
47 | #define EMIFS_CONFIG_ASM_OFFSET 0x0c | 47 | #define EMIFS_CONFIG_ASM_OFFSET 0x0c |
48 | #define EMIFF_SDRAM_CONFIG_ASM_OFFSET 0x20 | 48 | #define EMIFF_SDRAM_CONFIG_ASM_OFFSET 0x20 |
49 | 49 | ||
50 | /* | 50 | /* |
51 | * ---------------------------------------------------------------------------- | 51 | * ---------------------------------------------------------------------------- |
52 | * Power management bitmasks | 52 | * Power management bitmasks |
53 | * ---------------------------------------------------------------------------- | 53 | * ---------------------------------------------------------------------------- |
54 | */ | 54 | */ |
55 | #define IDLE_WAIT_CYCLES 0x00000fff | 55 | #define IDLE_WAIT_CYCLES 0x00000fff |
56 | #define PERIPHERAL_ENABLE 0x2 | 56 | #define PERIPHERAL_ENABLE 0x2 |
57 | 57 | ||
58 | #define SELF_REFRESH_MODE 0x0c000001 | 58 | #define SELF_REFRESH_MODE 0x0c000001 |
59 | #define IDLE_EMIFS_REQUEST 0xc | 59 | #define IDLE_EMIFS_REQUEST 0xc |
60 | #define MODEM_32K_EN 0x1 | 60 | #define MODEM_32K_EN 0x1 |
61 | #define PER_EN 0x1 | 61 | #define PER_EN 0x1 |
62 | 62 | ||
63 | #define CPU_SUSPEND_SIZE 200 | 63 | #define CPU_SUSPEND_SIZE 200 |
64 | #define ULPD_LOW_PWR_EN 0x0001 | 64 | #define ULPD_LOW_PWR_EN 0x0001 |
65 | #define ULPD_DEEP_SLEEP_TRANSITION_EN 0x0010 | 65 | #define ULPD_DEEP_SLEEP_TRANSITION_EN 0x0010 |
66 | #define ULPD_SETUP_ANALOG_CELL_3_VAL 0 | 66 | #define ULPD_SETUP_ANALOG_CELL_3_VAL 0 |
67 | #define ULPD_POWER_CTRL_REG_VAL 0x0219 | 67 | #define ULPD_POWER_CTRL_REG_VAL 0x0219 |
68 | 68 | ||
69 | #define DSP_IDLE_DELAY 10 | 69 | #define DSP_IDLE_DELAY 10 |
70 | #define DSP_IDLE 0x0040 | 70 | #define DSP_IDLE 0x0040 |
71 | #define DSP_RST 0x0004 | 71 | #define DSP_RST 0x0004 |
72 | #define DSP_ENABLE 0x0002 | 72 | #define DSP_ENABLE 0x0002 |
73 | #define SUFFICIENT_DSP_RESET_TIME 1000 | 73 | #define SUFFICIENT_DSP_RESET_TIME 1000 |
74 | #define DEFAULT_MPUI_CONFIG 0x05cf | 74 | #define DEFAULT_MPUI_CONFIG 0x05cf |
75 | #define ENABLE_XORCLK 0x2 | 75 | #define ENABLE_XORCLK 0x2 |
76 | #define DSP_CLOCK_ENABLE 0x2000 | 76 | #define DSP_CLOCK_ENABLE 0x2000 |
77 | #define DSP_IDLE_MODE 0x2 | 77 | #define DSP_IDLE_MODE 0x2 |
78 | #define TC_IDLE_REQUEST (0x0000000c) | 78 | #define TC_IDLE_REQUEST (0x0000000c) |
79 | 79 | ||
80 | #define IRQ_LEVEL2 (1<<0) | 80 | #define IRQ_LEVEL2 (1<<0) |
81 | #define IRQ_KEYBOARD (1<<1) | 81 | #define IRQ_KEYBOARD (1<<1) |
82 | #define IRQ_UART2 (1<<15) | 82 | #define IRQ_UART2 (1<<15) |
83 | 83 | ||
84 | #define PDE_BIT 0x08 | 84 | #define PDE_BIT 0x08 |
85 | #define PWD_EN_BIT 0x04 | 85 | #define PWD_EN_BIT 0x04 |
86 | #define EN_PERCK_BIT 0x04 | 86 | #define EN_PERCK_BIT 0x04 |
87 | 87 | ||
88 | #define OMAP1510_DEEP_SLEEP_REQUEST 0x0ec7 | 88 | #define OMAP1510_DEEP_SLEEP_REQUEST 0x0ec7 |
89 | #define OMAP1510_BIG_SLEEP_REQUEST 0x0cc5 | 89 | #define OMAP1510_BIG_SLEEP_REQUEST 0x0cc5 |
90 | #define OMAP1510_IDLE_LOOP_REQUEST 0x0c00 | 90 | #define OMAP1510_IDLE_LOOP_REQUEST 0x0c00 |
91 | #define OMAP1510_IDLE_CLOCK_DOMAINS 0x2 | 91 | #define OMAP1510_IDLE_CLOCK_DOMAINS 0x2 |
92 | 92 | ||
93 | /* Both big sleep and deep sleep use same values. Difference is in ULPD. */ | 93 | /* Both big sleep and deep sleep use same values. Difference is in ULPD. */ |
94 | #define OMAP1610_IDLECT1_SLEEP_VAL 0x13c7 | 94 | #define OMAP1610_IDLECT1_SLEEP_VAL 0x13c7 |
95 | #define OMAP1610_IDLECT2_SLEEP_VAL 0x09c7 | 95 | #define OMAP1610_IDLECT2_SLEEP_VAL 0x09c7 |
96 | #define OMAP1610_IDLECT3_VAL 0x3f | 96 | #define OMAP1610_IDLECT3_VAL 0x3f |
97 | #define OMAP1610_IDLECT3_SLEEP_ORMASK 0x2c | 97 | #define OMAP1610_IDLECT3_SLEEP_ORMASK 0x2c |
98 | #define OMAP1610_IDLECT3 0xfffece24 | 98 | #define OMAP1610_IDLECT3 0xfffece24 |
99 | #define OMAP1610_IDLE_LOOP_REQUEST 0x0400 | 99 | #define OMAP1610_IDLE_LOOP_REQUEST 0x0400 |
100 | 100 | ||
101 | #define OMAP7XX_IDLECT1_SLEEP_VAL 0x16c7 | 101 | #define OMAP7XX_IDLECT1_SLEEP_VAL 0x16c7 |
102 | #define OMAP7XX_IDLECT2_SLEEP_VAL 0x09c7 | 102 | #define OMAP7XX_IDLECT2_SLEEP_VAL 0x09c7 |
103 | #define OMAP7XX_IDLECT3_VAL 0x3f | 103 | #define OMAP7XX_IDLECT3_VAL 0x3f |
104 | #define OMAP7XX_IDLECT3 0xfffece24 | 104 | #define OMAP7XX_IDLECT3 0xfffece24 |
105 | #define OMAP7XX_IDLE_LOOP_REQUEST 0x0C00 | 105 | #define OMAP7XX_IDLE_LOOP_REQUEST 0x0C00 |
106 | 106 | ||
107 | #if !defined(CONFIG_ARCH_OMAP730) && \ | 107 | #if !defined(CONFIG_ARCH_OMAP730) && \ |
108 | !defined(CONFIG_ARCH_OMAP850) && \ | 108 | !defined(CONFIG_ARCH_OMAP850) && \ |
109 | !defined(CONFIG_ARCH_OMAP15XX) && \ | 109 | !defined(CONFIG_ARCH_OMAP15XX) && \ |
110 | !defined(CONFIG_ARCH_OMAP16XX) | 110 | !defined(CONFIG_ARCH_OMAP16XX) |
111 | #warning "Power management for this processor not implemented yet" | 111 | #warning "Power management for this processor not implemented yet" |
112 | #endif | 112 | #endif |
113 | 113 | ||
114 | #ifndef __ASSEMBLER__ | 114 | #ifndef __ASSEMBLER__ |
115 | 115 | ||
116 | #include <linux/clk.h> | 116 | #include <linux/clk.h> |
117 | 117 | ||
118 | extern struct kset power_subsys; | 118 | extern struct kset power_subsys; |
119 | 119 | ||
120 | extern void prevent_idle_sleep(void); | 120 | extern void prevent_idle_sleep(void); |
121 | extern void allow_idle_sleep(void); | 121 | extern void allow_idle_sleep(void); |
122 | 122 | ||
123 | extern void omap1_pm_idle(void); | 123 | extern void omap1_pm_idle(void); |
124 | extern void omap1_pm_suspend(void); | 124 | extern void omap1_pm_suspend(void); |
125 | 125 | ||
126 | extern void omap7xx_cpu_suspend(unsigned short, unsigned short); | 126 | extern void omap7xx_cpu_suspend(unsigned long, unsigned long); |
127 | extern void omap1510_cpu_suspend(unsigned short, unsigned short); | 127 | extern void omap1510_cpu_suspend(unsigned long, unsigned long); |
128 | extern void omap1610_cpu_suspend(unsigned short, unsigned short); | 128 | extern void omap1610_cpu_suspend(unsigned long, unsigned long); |
129 | extern void omap7xx_idle_loop_suspend(void); | 129 | extern void omap7xx_idle_loop_suspend(void); |
130 | extern void omap1510_idle_loop_suspend(void); | 130 | extern void omap1510_idle_loop_suspend(void); |
131 | extern void omap1610_idle_loop_suspend(void); | 131 | extern void omap1610_idle_loop_suspend(void); |
132 | 132 | ||
133 | extern unsigned int omap7xx_cpu_suspend_sz; | 133 | extern unsigned int omap7xx_cpu_suspend_sz; |
134 | extern unsigned int omap1510_cpu_suspend_sz; | 134 | extern unsigned int omap1510_cpu_suspend_sz; |
135 | extern unsigned int omap1610_cpu_suspend_sz; | 135 | extern unsigned int omap1610_cpu_suspend_sz; |
136 | extern unsigned int omap7xx_idle_loop_suspend_sz; | 136 | extern unsigned int omap7xx_idle_loop_suspend_sz; |
137 | extern unsigned int omap1510_idle_loop_suspend_sz; | 137 | extern unsigned int omap1510_idle_loop_suspend_sz; |
138 | extern unsigned int omap1610_idle_loop_suspend_sz; | 138 | extern unsigned int omap1610_idle_loop_suspend_sz; |
139 | 139 | ||
140 | #ifdef CONFIG_OMAP_SERIAL_WAKE | 140 | #ifdef CONFIG_OMAP_SERIAL_WAKE |
141 | extern void omap_serial_wake_trigger(int enable); | 141 | extern void omap_serial_wake_trigger(int enable); |
142 | #else | 142 | #else |
143 | #define omap_serial_wakeup_init() {} | 143 | #define omap_serial_wakeup_init() {} |
144 | #define omap_serial_wake_trigger(x) {} | 144 | #define omap_serial_wake_trigger(x) {} |
145 | #endif /* CONFIG_OMAP_SERIAL_WAKE */ | 145 | #endif /* CONFIG_OMAP_SERIAL_WAKE */ |
146 | 146 | ||
147 | #define ARM_SAVE(x) arm_sleep_save[ARM_SLEEP_SAVE_##x] = omap_readl(x) | 147 | #define ARM_SAVE(x) arm_sleep_save[ARM_SLEEP_SAVE_##x] = omap_readl(x) |
148 | #define ARM_RESTORE(x) omap_writel((arm_sleep_save[ARM_SLEEP_SAVE_##x]), (x)) | 148 | #define ARM_RESTORE(x) omap_writel((arm_sleep_save[ARM_SLEEP_SAVE_##x]), (x)) |
149 | #define ARM_SHOW(x) arm_sleep_save[ARM_SLEEP_SAVE_##x] | 149 | #define ARM_SHOW(x) arm_sleep_save[ARM_SLEEP_SAVE_##x] |
150 | 150 | ||
151 | #define DSP_SAVE(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x] = __raw_readw(x) | 151 | #define DSP_SAVE(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x] = __raw_readw(x) |
152 | #define DSP_RESTORE(x) __raw_writew((dsp_sleep_save[DSP_SLEEP_SAVE_##x]), (x)) | 152 | #define DSP_RESTORE(x) __raw_writew((dsp_sleep_save[DSP_SLEEP_SAVE_##x]), (x)) |
153 | #define DSP_SHOW(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x] | 153 | #define DSP_SHOW(x) dsp_sleep_save[DSP_SLEEP_SAVE_##x] |
154 | 154 | ||
155 | #define ULPD_SAVE(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] = omap_readw(x) | 155 | #define ULPD_SAVE(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] = omap_readw(x) |
156 | #define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x)) | 156 | #define ULPD_RESTORE(x) omap_writew((ulpd_sleep_save[ULPD_SLEEP_SAVE_##x]), (x)) |
157 | #define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] | 157 | #define ULPD_SHOW(x) ulpd_sleep_save[ULPD_SLEEP_SAVE_##x] |
158 | 158 | ||
159 | #define MPUI7XX_SAVE(x) mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x] = omap_readl(x) | 159 | #define MPUI7XX_SAVE(x) mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x] = omap_readl(x) |
160 | #define MPUI7XX_RESTORE(x) omap_writel((mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x]), (x)) | 160 | #define MPUI7XX_RESTORE(x) omap_writel((mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x]), (x)) |
161 | #define MPUI7XX_SHOW(x) mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x] | 161 | #define MPUI7XX_SHOW(x) mpui7xx_sleep_save[MPUI7XX_SLEEP_SAVE_##x] |
162 | 162 | ||
163 | #define MPUI1510_SAVE(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] = omap_readl(x) | 163 | #define MPUI1510_SAVE(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] = omap_readl(x) |
164 | #define MPUI1510_RESTORE(x) omap_writel((mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]), (x)) | 164 | #define MPUI1510_RESTORE(x) omap_writel((mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x]), (x)) |
165 | #define MPUI1510_SHOW(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] | 165 | #define MPUI1510_SHOW(x) mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_##x] |
166 | 166 | ||
167 | #define MPUI1610_SAVE(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x] = omap_readl(x) | 167 | #define MPUI1610_SAVE(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x] = omap_readl(x) |
168 | #define MPUI1610_RESTORE(x) omap_writel((mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]), (x)) | 168 | #define MPUI1610_RESTORE(x) omap_writel((mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x]), (x)) |
169 | #define MPUI1610_SHOW(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x] | 169 | #define MPUI1610_SHOW(x) mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_##x] |
170 | 170 | ||
171 | /* | 171 | /* |
172 | * List of global OMAP registers to preserve. | 172 | * List of global OMAP registers to preserve. |
173 | * More ones like CP and general purpose register values are preserved | 173 | * More ones like CP and general purpose register values are preserved |
174 | * with the stack pointer in sleep.S. | 174 | * with the stack pointer in sleep.S. |
175 | */ | 175 | */ |
176 | 176 | ||
177 | enum arm_save_state { | 177 | enum arm_save_state { |
178 | ARM_SLEEP_SAVE_START = 0, | 178 | ARM_SLEEP_SAVE_START = 0, |
179 | /* | 179 | /* |
180 | * MPU control registers 32 bits | 180 | * MPU control registers 32 bits |
181 | */ | 181 | */ |
182 | ARM_SLEEP_SAVE_ARM_CKCTL, | 182 | ARM_SLEEP_SAVE_ARM_CKCTL, |
183 | ARM_SLEEP_SAVE_ARM_IDLECT1, | 183 | ARM_SLEEP_SAVE_ARM_IDLECT1, |
184 | ARM_SLEEP_SAVE_ARM_IDLECT2, | 184 | ARM_SLEEP_SAVE_ARM_IDLECT2, |
185 | ARM_SLEEP_SAVE_ARM_IDLECT3, | 185 | ARM_SLEEP_SAVE_ARM_IDLECT3, |
186 | ARM_SLEEP_SAVE_ARM_EWUPCT, | 186 | ARM_SLEEP_SAVE_ARM_EWUPCT, |
187 | ARM_SLEEP_SAVE_ARM_RSTCT1, | 187 | ARM_SLEEP_SAVE_ARM_RSTCT1, |
188 | ARM_SLEEP_SAVE_ARM_RSTCT2, | 188 | ARM_SLEEP_SAVE_ARM_RSTCT2, |
189 | ARM_SLEEP_SAVE_ARM_SYSST, | 189 | ARM_SLEEP_SAVE_ARM_SYSST, |
190 | ARM_SLEEP_SAVE_SIZE | 190 | ARM_SLEEP_SAVE_SIZE |
191 | }; | 191 | }; |
192 | 192 | ||
193 | enum dsp_save_state { | 193 | enum dsp_save_state { |
194 | DSP_SLEEP_SAVE_START = 0, | 194 | DSP_SLEEP_SAVE_START = 0, |
195 | /* | 195 | /* |
196 | * DSP registers 16 bits | 196 | * DSP registers 16 bits |
197 | */ | 197 | */ |
198 | DSP_SLEEP_SAVE_DSP_IDLECT2, | 198 | DSP_SLEEP_SAVE_DSP_IDLECT2, |
199 | DSP_SLEEP_SAVE_SIZE | 199 | DSP_SLEEP_SAVE_SIZE |
200 | }; | 200 | }; |
201 | 201 | ||
202 | enum ulpd_save_state { | 202 | enum ulpd_save_state { |
203 | ULPD_SLEEP_SAVE_START = 0, | 203 | ULPD_SLEEP_SAVE_START = 0, |
204 | /* | 204 | /* |
205 | * ULPD registers 16 bits | 205 | * ULPD registers 16 bits |
206 | */ | 206 | */ |
207 | ULPD_SLEEP_SAVE_ULPD_IT_STATUS, | 207 | ULPD_SLEEP_SAVE_ULPD_IT_STATUS, |
208 | ULPD_SLEEP_SAVE_ULPD_CLOCK_CTRL, | 208 | ULPD_SLEEP_SAVE_ULPD_CLOCK_CTRL, |
209 | ULPD_SLEEP_SAVE_ULPD_SOFT_REQ, | 209 | ULPD_SLEEP_SAVE_ULPD_SOFT_REQ, |
210 | ULPD_SLEEP_SAVE_ULPD_STATUS_REQ, | 210 | ULPD_SLEEP_SAVE_ULPD_STATUS_REQ, |
211 | ULPD_SLEEP_SAVE_ULPD_DPLL_CTRL, | 211 | ULPD_SLEEP_SAVE_ULPD_DPLL_CTRL, |
212 | ULPD_SLEEP_SAVE_ULPD_POWER_CTRL, | 212 | ULPD_SLEEP_SAVE_ULPD_POWER_CTRL, |
213 | ULPD_SLEEP_SAVE_SIZE | 213 | ULPD_SLEEP_SAVE_SIZE |
214 | }; | 214 | }; |
215 | 215 | ||
216 | enum mpui1510_save_state { | 216 | enum mpui1510_save_state { |
217 | MPUI1510_SLEEP_SAVE_START = 0, | 217 | MPUI1510_SLEEP_SAVE_START = 0, |
218 | /* | 218 | /* |
219 | * MPUI registers 32 bits | 219 | * MPUI registers 32 bits |
220 | */ | 220 | */ |
221 | MPUI1510_SLEEP_SAVE_MPUI_CTRL, | 221 | MPUI1510_SLEEP_SAVE_MPUI_CTRL, |
222 | MPUI1510_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG, | 222 | MPUI1510_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG, |
223 | MPUI1510_SLEEP_SAVE_MPUI_DSP_API_CONFIG, | 223 | MPUI1510_SLEEP_SAVE_MPUI_DSP_API_CONFIG, |
224 | MPUI1510_SLEEP_SAVE_MPUI_DSP_STATUS, | 224 | MPUI1510_SLEEP_SAVE_MPUI_DSP_STATUS, |
225 | MPUI1510_SLEEP_SAVE_EMIFF_SDRAM_CONFIG, | 225 | MPUI1510_SLEEP_SAVE_EMIFF_SDRAM_CONFIG, |
226 | MPUI1510_SLEEP_SAVE_EMIFS_CONFIG, | 226 | MPUI1510_SLEEP_SAVE_EMIFS_CONFIG, |
227 | MPUI1510_SLEEP_SAVE_OMAP_IH1_MIR, | 227 | MPUI1510_SLEEP_SAVE_OMAP_IH1_MIR, |
228 | MPUI1510_SLEEP_SAVE_OMAP_IH2_MIR, | 228 | MPUI1510_SLEEP_SAVE_OMAP_IH2_MIR, |
229 | #if defined(CONFIG_ARCH_OMAP15XX) | 229 | #if defined(CONFIG_ARCH_OMAP15XX) |
230 | MPUI1510_SLEEP_SAVE_SIZE | 230 | MPUI1510_SLEEP_SAVE_SIZE |
231 | #else | 231 | #else |
232 | MPUI1510_SLEEP_SAVE_SIZE = 0 | 232 | MPUI1510_SLEEP_SAVE_SIZE = 0 |
233 | #endif | 233 | #endif |
234 | }; | 234 | }; |
235 | 235 | ||
236 | enum mpui7xx_save_state { | 236 | enum mpui7xx_save_state { |
237 | MPUI7XX_SLEEP_SAVE_START = 0, | 237 | MPUI7XX_SLEEP_SAVE_START = 0, |
238 | /* | 238 | /* |
239 | * MPUI registers 32 bits | 239 | * MPUI registers 32 bits |
240 | */ | 240 | */ |
241 | MPUI7XX_SLEEP_SAVE_MPUI_CTRL, | 241 | MPUI7XX_SLEEP_SAVE_MPUI_CTRL, |
242 | MPUI7XX_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG, | 242 | MPUI7XX_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG, |
243 | MPUI7XX_SLEEP_SAVE_MPUI_DSP_API_CONFIG, | 243 | MPUI7XX_SLEEP_SAVE_MPUI_DSP_API_CONFIG, |
244 | MPUI7XX_SLEEP_SAVE_MPUI_DSP_STATUS, | 244 | MPUI7XX_SLEEP_SAVE_MPUI_DSP_STATUS, |
245 | MPUI7XX_SLEEP_SAVE_EMIFF_SDRAM_CONFIG, | 245 | MPUI7XX_SLEEP_SAVE_EMIFF_SDRAM_CONFIG, |
246 | MPUI7XX_SLEEP_SAVE_EMIFS_CONFIG, | 246 | MPUI7XX_SLEEP_SAVE_EMIFS_CONFIG, |
247 | MPUI7XX_SLEEP_SAVE_OMAP_IH1_MIR, | 247 | MPUI7XX_SLEEP_SAVE_OMAP_IH1_MIR, |
248 | MPUI7XX_SLEEP_SAVE_OMAP_IH2_0_MIR, | 248 | MPUI7XX_SLEEP_SAVE_OMAP_IH2_0_MIR, |
249 | MPUI7XX_SLEEP_SAVE_OMAP_IH2_1_MIR, | 249 | MPUI7XX_SLEEP_SAVE_OMAP_IH2_1_MIR, |
250 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | 250 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) |
251 | MPUI7XX_SLEEP_SAVE_SIZE | 251 | MPUI7XX_SLEEP_SAVE_SIZE |
252 | #else | 252 | #else |
253 | MPUI7XX_SLEEP_SAVE_SIZE = 0 | 253 | MPUI7XX_SLEEP_SAVE_SIZE = 0 |
254 | #endif | 254 | #endif |
255 | }; | 255 | }; |
256 | 256 | ||
257 | enum mpui1610_save_state { | 257 | enum mpui1610_save_state { |
258 | MPUI1610_SLEEP_SAVE_START = 0, | 258 | MPUI1610_SLEEP_SAVE_START = 0, |
259 | /* | 259 | /* |
260 | * MPUI registers 32 bits | 260 | * MPUI registers 32 bits |
261 | */ | 261 | */ |
262 | MPUI1610_SLEEP_SAVE_MPUI_CTRL, | 262 | MPUI1610_SLEEP_SAVE_MPUI_CTRL, |
263 | MPUI1610_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG, | 263 | MPUI1610_SLEEP_SAVE_MPUI_DSP_BOOT_CONFIG, |
264 | MPUI1610_SLEEP_SAVE_MPUI_DSP_API_CONFIG, | 264 | MPUI1610_SLEEP_SAVE_MPUI_DSP_API_CONFIG, |
265 | MPUI1610_SLEEP_SAVE_MPUI_DSP_STATUS, | 265 | MPUI1610_SLEEP_SAVE_MPUI_DSP_STATUS, |
266 | MPUI1610_SLEEP_SAVE_EMIFF_SDRAM_CONFIG, | 266 | MPUI1610_SLEEP_SAVE_EMIFF_SDRAM_CONFIG, |
267 | MPUI1610_SLEEP_SAVE_EMIFS_CONFIG, | 267 | MPUI1610_SLEEP_SAVE_EMIFS_CONFIG, |
268 | MPUI1610_SLEEP_SAVE_OMAP_IH1_MIR, | 268 | MPUI1610_SLEEP_SAVE_OMAP_IH1_MIR, |
269 | MPUI1610_SLEEP_SAVE_OMAP_IH2_0_MIR, | 269 | MPUI1610_SLEEP_SAVE_OMAP_IH2_0_MIR, |
270 | MPUI1610_SLEEP_SAVE_OMAP_IH2_1_MIR, | 270 | MPUI1610_SLEEP_SAVE_OMAP_IH2_1_MIR, |
271 | MPUI1610_SLEEP_SAVE_OMAP_IH2_2_MIR, | 271 | MPUI1610_SLEEP_SAVE_OMAP_IH2_2_MIR, |
272 | MPUI1610_SLEEP_SAVE_OMAP_IH2_3_MIR, | 272 | MPUI1610_SLEEP_SAVE_OMAP_IH2_3_MIR, |
273 | #if defined(CONFIG_ARCH_OMAP16XX) | 273 | #if defined(CONFIG_ARCH_OMAP16XX) |
274 | MPUI1610_SLEEP_SAVE_SIZE | 274 | MPUI1610_SLEEP_SAVE_SIZE |
275 | #else | 275 | #else |
276 | MPUI1610_SLEEP_SAVE_SIZE = 0 | 276 | MPUI1610_SLEEP_SAVE_SIZE = 0 |
277 | #endif | 277 | #endif |
278 | }; | 278 | }; |
279 | 279 | ||
280 | #endif /* ASSEMBLER */ | 280 | #endif /* ASSEMBLER */ |
281 | #endif /* __ASM_ARCH_OMAP_PM_H */ | 281 | #endif /* __ASM_ARCH_OMAP_PM_H */ |
282 | 282 |
arch/arm/mach-omap1/sleep.S
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-omap1/sleep.S | 2 | * linux/arch/arm/mach-omap1/sleep.S |
3 | * | 3 | * |
4 | * Low-level OMAP7XX/1510/1610 sleep/wakeUp support | 4 | * Low-level OMAP7XX/1510/1610 sleep/wakeUp support |
5 | * | 5 | * |
6 | * Initial SA1110 code: | 6 | * Initial SA1110 code: |
7 | * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> | 7 | * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com> |
8 | * | 8 | * |
9 | * Adapted for PXA by Nicolas Pitre: | 9 | * Adapted for PXA by Nicolas Pitre: |
10 | * Copyright (c) 2002 Monta Vista Software, Inc. | 10 | * Copyright (c) 2002 Monta Vista Software, Inc. |
11 | * | 11 | * |
12 | * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com> | 12 | * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com> |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or modify it | 14 | * This program is free software; you can redistribute it and/or modify it |
15 | * under the terms of the GNU General Public License as published by the | 15 | * under the terms of the GNU General Public License as published by the |
16 | * Free Software Foundation; either version 2 of the License, or (at your | 16 | * Free Software Foundation; either version 2 of the License, or (at your |
17 | * option) any later version. | 17 | * option) any later version. |
18 | * | 18 | * |
19 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | 19 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED |
20 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | 20 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | 21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN |
22 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 22 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | 24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
25 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | 25 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | * | 29 | * |
30 | * You should have received a copy of the GNU General Public License along | 30 | * You should have received a copy of the GNU General Public License along |
31 | * with this program; if not, write to the Free Software Foundation, Inc., | 31 | * with this program; if not, write to the Free Software Foundation, Inc., |
32 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 32 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <linux/linkage.h> | 35 | #include <linux/linkage.h> |
36 | #include <asm/assembler.h> | 36 | #include <asm/assembler.h> |
37 | #include <mach/io.h> | 37 | #include <mach/io.h> |
38 | #include "pm.h" | 38 | #include "pm.h" |
39 | 39 | ||
40 | .text | 40 | .text |
41 | 41 | ||
42 | 42 | ||
43 | /* | 43 | /* |
44 | * Forces OMAP into deep sleep state | 44 | * Forces OMAP into deep sleep state |
45 | * | 45 | * |
46 | * omapXXXX_cpu_suspend() | 46 | * omapXXXX_cpu_suspend() |
47 | * | 47 | * |
48 | * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed | 48 | * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed |
49 | * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1 | 49 | * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1 |
50 | * in register r1. | 50 | * in register r1. |
51 | * | 51 | * |
52 | * Note: This code get's copied to internal SRAM at boot. When the OMAP | 52 | * Note: This code get's copied to internal SRAM at boot. When the OMAP |
53 | * wakes up it continues execution at the point it went to sleep. | 53 | * wakes up it continues execution at the point it went to sleep. |
54 | * | 54 | * |
55 | * Note: Because of errata work arounds we have processor specific functions | 55 | * Note: Because of errata work arounds we have processor specific functions |
56 | * here. They are mostly the same, but slightly different. | 56 | * here. They are mostly the same, but slightly different. |
57 | * | 57 | * |
58 | */ | 58 | */ |
59 | 59 | ||
60 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) | 60 | #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) |
61 | .align 3 | ||
61 | ENTRY(omap7xx_cpu_suspend) | 62 | ENTRY(omap7xx_cpu_suspend) |
62 | 63 | ||
63 | @ save registers on stack | 64 | @ save registers on stack |
64 | stmfd sp!, {r0 - r12, lr} | 65 | stmfd sp!, {r0 - r12, lr} |
65 | 66 | ||
66 | @ Drain write cache | 67 | @ Drain write cache |
67 | mov r4, #0 | 68 | mov r4, #0 |
68 | mcr p15, 0, r0, c7, c10, 4 | 69 | mcr p15, 0, r0, c7, c10, 4 |
69 | nop | 70 | nop |
70 | 71 | ||
71 | @ load base address of Traffic Controller | 72 | @ load base address of Traffic Controller |
72 | mov r6, #TCMIF_ASM_BASE & 0xff000000 | 73 | mov r6, #TCMIF_ASM_BASE & 0xff000000 |
73 | orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 | 74 | orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 |
74 | orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 | 75 | orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 |
75 | 76 | ||
76 | @ prepare to put SDRAM into self-refresh manually | 77 | @ prepare to put SDRAM into self-refresh manually |
77 | ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 78 | ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
78 | orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 | 79 | orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 |
79 | orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff | 80 | orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff |
80 | str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 81 | str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
81 | 82 | ||
82 | @ prepare to put EMIFS to Sleep | 83 | @ prepare to put EMIFS to Sleep |
83 | ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 84 | ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
84 | orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff | 85 | orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff |
85 | str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 86 | str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
86 | 87 | ||
87 | @ load base address of ARM_IDLECT1 and ARM_IDLECT2 | 88 | @ load base address of ARM_IDLECT1 and ARM_IDLECT2 |
88 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 | 89 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 |
89 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 | 90 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 |
90 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 | 91 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 |
91 | 92 | ||
92 | @ turn off clock domains | 93 | @ turn off clock domains |
93 | @ do not disable PERCK (0x04) | 94 | @ do not disable PERCK (0x04) |
94 | mov r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff | 95 | mov r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff |
95 | orr r5, r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff00 | 96 | orr r5, r5, #OMAP7XX_IDLECT2_SLEEP_VAL & 0xff00 |
96 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 97 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
97 | 98 | ||
98 | @ request ARM idle | 99 | @ request ARM idle |
99 | mov r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff | 100 | mov r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff |
100 | orr r3, r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff00 | 101 | orr r3, r3, #OMAP7XX_IDLECT1_SLEEP_VAL & 0xff00 |
101 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 102 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
102 | 103 | ||
103 | @ disable instruction cache | 104 | @ disable instruction cache |
104 | mrc p15, 0, r9, c1, c0, 0 | 105 | mrc p15, 0, r9, c1, c0, 0 |
105 | bic r2, r9, #0x1000 | 106 | bic r2, r9, #0x1000 |
106 | mcr p15, 0, r2, c1, c0, 0 | 107 | mcr p15, 0, r2, c1, c0, 0 |
107 | nop | 108 | nop |
108 | 109 | ||
109 | /* | 110 | /* |
110 | * Let's wait for the next wake up event to wake us up. r0 can't be | 111 | * Let's wait for the next wake up event to wake us up. r0 can't be |
111 | * used here because r0 holds ARM_IDLECT1 | 112 | * used here because r0 holds ARM_IDLECT1 |
112 | */ | 113 | */ |
113 | mov r2, #0 | 114 | mov r2, #0 |
114 | mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt | 115 | mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt |
115 | /* | 116 | /* |
116 | * omap7xx_cpu_suspend()'s resume point. | 117 | * omap7xx_cpu_suspend()'s resume point. |
117 | * | 118 | * |
118 | * It will just start executing here, so we'll restore stuff from the | 119 | * It will just start executing here, so we'll restore stuff from the |
119 | * stack. | 120 | * stack. |
120 | */ | 121 | */ |
121 | @ re-enable Icache | 122 | @ re-enable Icache |
122 | mcr p15, 0, r9, c1, c0, 0 | 123 | mcr p15, 0, r9, c1, c0, 0 |
123 | 124 | ||
124 | @ reset the ARM_IDLECT1 and ARM_IDLECT2. | 125 | @ reset the ARM_IDLECT1 and ARM_IDLECT2. |
125 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 126 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
126 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 127 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
127 | 128 | ||
128 | @ Restore EMIFF controls | 129 | @ Restore EMIFF controls |
129 | str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 130 | str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
130 | str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 131 | str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
131 | 132 | ||
132 | @ restore regs and return | 133 | @ restore regs and return |
133 | ldmfd sp!, {r0 - r12, pc} | 134 | ldmfd sp!, {r0 - r12, pc} |
134 | 135 | ||
135 | ENTRY(omap7xx_cpu_suspend_sz) | 136 | ENTRY(omap7xx_cpu_suspend_sz) |
136 | .word . - omap7xx_cpu_suspend | 137 | .word . - omap7xx_cpu_suspend |
137 | #endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */ | 138 | #endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */ |
138 | 139 | ||
139 | #ifdef CONFIG_ARCH_OMAP15XX | 140 | #ifdef CONFIG_ARCH_OMAP15XX |
141 | .align 3 | ||
140 | ENTRY(omap1510_cpu_suspend) | 142 | ENTRY(omap1510_cpu_suspend) |
141 | 143 | ||
142 | @ save registers on stack | 144 | @ save registers on stack |
143 | stmfd sp!, {r0 - r12, lr} | 145 | stmfd sp!, {r0 - r12, lr} |
144 | 146 | ||
145 | @ load base address of Traffic Controller | 147 | @ load base address of Traffic Controller |
146 | mov r4, #TCMIF_ASM_BASE & 0xff000000 | 148 | mov r4, #TCMIF_ASM_BASE & 0xff000000 |
147 | orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000 | 149 | orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000 |
148 | orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00 | 150 | orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00 |
149 | 151 | ||
150 | @ work around errata of OMAP1510 PDE bit for TC shut down | 152 | @ work around errata of OMAP1510 PDE bit for TC shut down |
151 | @ clear PDE bit | 153 | @ clear PDE bit |
152 | ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 154 | ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
153 | bic r5, r5, #PDE_BIT & 0xff | 155 | bic r5, r5, #PDE_BIT & 0xff |
154 | str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 156 | str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
155 | 157 | ||
156 | @ set PWD_EN bit | 158 | @ set PWD_EN bit |
157 | and r5, r5, #PWD_EN_BIT & 0xff | 159 | and r5, r5, #PWD_EN_BIT & 0xff |
158 | str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 160 | str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
159 | 161 | ||
160 | @ prepare to put SDRAM into self-refresh manually | 162 | @ prepare to put SDRAM into self-refresh manually |
161 | ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 163 | ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
162 | orr r5, r5, #SELF_REFRESH_MODE & 0xff000000 | 164 | orr r5, r5, #SELF_REFRESH_MODE & 0xff000000 |
163 | orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff | 165 | orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff |
164 | str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 166 | str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
165 | 167 | ||
166 | @ prepare to put EMIFS to Sleep | 168 | @ prepare to put EMIFS to Sleep |
167 | ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 169 | ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
168 | orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff | 170 | orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff |
169 | str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 171 | str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
170 | 172 | ||
171 | @ load base address of ARM_IDLECT1 and ARM_IDLECT2 | 173 | @ load base address of ARM_IDLECT1 and ARM_IDLECT2 |
172 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 | 174 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 |
173 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 | 175 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 |
174 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 | 176 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 |
175 | 177 | ||
176 | @ turn off clock domains | 178 | @ turn off clock domains |
177 | mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff | 179 | mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff |
178 | orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 | 180 | orr r5, r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00 |
179 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 181 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
180 | 182 | ||
181 | @ request ARM idle | 183 | @ request ARM idle |
182 | mov r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff | 184 | mov r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff |
183 | orr r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00 | 185 | orr r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00 |
184 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 186 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
185 | 187 | ||
186 | mov r5, #IDLE_WAIT_CYCLES & 0xff | 188 | mov r5, #IDLE_WAIT_CYCLES & 0xff |
187 | orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 | 189 | orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00 |
188 | l_1510_2: | 190 | l_1510_2: |
189 | subs r5, r5, #1 | 191 | subs r5, r5, #1 |
190 | bne l_1510_2 | 192 | bne l_1510_2 |
191 | /* | 193 | /* |
192 | * Let's wait for the next wake up event to wake us up. r0 can't be | 194 | * Let's wait for the next wake up event to wake us up. r0 can't be |
193 | * used here because r0 holds ARM_IDLECT1 | 195 | * used here because r0 holds ARM_IDLECT1 |
194 | */ | 196 | */ |
195 | mov r2, #0 | 197 | mov r2, #0 |
196 | mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt | 198 | mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt |
197 | /* | 199 | /* |
198 | * omap1510_cpu_suspend()'s resume point. | 200 | * omap1510_cpu_suspend()'s resume point. |
199 | * | 201 | * |
200 | * It will just start executing here, so we'll restore stuff from the | 202 | * It will just start executing here, so we'll restore stuff from the |
201 | * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. | 203 | * stack, reset the ARM_IDLECT1 and ARM_IDLECT2. |
202 | */ | 204 | */ |
203 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 205 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
204 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 206 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
205 | 207 | ||
206 | @ restore regs and return | 208 | @ restore regs and return |
207 | ldmfd sp!, {r0 - r12, pc} | 209 | ldmfd sp!, {r0 - r12, pc} |
208 | 210 | ||
209 | ENTRY(omap1510_cpu_suspend_sz) | 211 | ENTRY(omap1510_cpu_suspend_sz) |
210 | .word . - omap1510_cpu_suspend | 212 | .word . - omap1510_cpu_suspend |
211 | #endif /* CONFIG_ARCH_OMAP15XX */ | 213 | #endif /* CONFIG_ARCH_OMAP15XX */ |
212 | 214 | ||
213 | #if defined(CONFIG_ARCH_OMAP16XX) | 215 | #if defined(CONFIG_ARCH_OMAP16XX) |
216 | .align 3 | ||
214 | ENTRY(omap1610_cpu_suspend) | 217 | ENTRY(omap1610_cpu_suspend) |
215 | 218 | ||
216 | @ save registers on stack | 219 | @ save registers on stack |
217 | stmfd sp!, {r0 - r12, lr} | 220 | stmfd sp!, {r0 - r12, lr} |
218 | 221 | ||
219 | @ Drain write cache | 222 | @ Drain write cache |
220 | mov r4, #0 | 223 | mov r4, #0 |
221 | mcr p15, 0, r0, c7, c10, 4 | 224 | mcr p15, 0, r0, c7, c10, 4 |
222 | nop | 225 | nop |
223 | 226 | ||
224 | @ Load base address of Traffic Controller | 227 | @ Load base address of Traffic Controller |
225 | mov r6, #TCMIF_ASM_BASE & 0xff000000 | 228 | mov r6, #TCMIF_ASM_BASE & 0xff000000 |
226 | orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 | 229 | orr r6, r6, #TCMIF_ASM_BASE & 0x00ff0000 |
227 | orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 | 230 | orr r6, r6, #TCMIF_ASM_BASE & 0x0000ff00 |
228 | 231 | ||
229 | @ Prepare to put SDRAM into self-refresh manually | 232 | @ Prepare to put SDRAM into self-refresh manually |
230 | ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 233 | ldr r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
231 | orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 | 234 | orr r9, r7, #SELF_REFRESH_MODE & 0xff000000 |
232 | orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff | 235 | orr r9, r9, #SELF_REFRESH_MODE & 0x000000ff |
233 | str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 236 | str r9, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
234 | 237 | ||
235 | @ Prepare to put EMIFS to Sleep | 238 | @ Prepare to put EMIFS to Sleep |
236 | ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 239 | ldr r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
237 | orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff | 240 | orr r9, r8, #IDLE_EMIFS_REQUEST & 0xff |
238 | str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 241 | str r9, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
239 | 242 | ||
240 | @ Load base address of ARM_IDLECT1 and ARM_IDLECT2 | 243 | @ Load base address of ARM_IDLECT1 and ARM_IDLECT2 |
241 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 | 244 | mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000 |
242 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 | 245 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000 |
243 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 | 246 | orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00 |
244 | 247 | ||
245 | @ Turn off clock domains | 248 | @ Turn off clock domains |
246 | @ Do not disable PERCK (0x04) | 249 | @ Do not disable PERCK (0x04) |
247 | mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff | 250 | mov r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff |
248 | orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00 | 251 | orr r5, r5, #OMAP1610_IDLECT2_SLEEP_VAL & 0xff00 |
249 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 252 | strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
250 | 253 | ||
251 | @ Request ARM idle | 254 | @ Request ARM idle |
252 | mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff | 255 | mov r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff |
253 | orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00 | 256 | orr r3, r3, #OMAP1610_IDLECT1_SLEEP_VAL & 0xff00 |
254 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 257 | strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
255 | 258 | ||
256 | /* | 259 | /* |
257 | * Let's wait for the next wake up event to wake us up. r0 can't be | 260 | * Let's wait for the next wake up event to wake us up. r0 can't be |
258 | * used here because r0 holds ARM_IDLECT1 | 261 | * used here because r0 holds ARM_IDLECT1 |
259 | */ | 262 | */ |
260 | mov r2, #0 | 263 | mov r2, #0 |
261 | mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt | 264 | mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt |
262 | 265 | ||
263 | @ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions | 266 | @ Errata (HEL3SU467, section 1.4.4) specifies nop-instructions |
264 | @ according to this formula: | 267 | @ according to this formula: |
265 | @ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV | 268 | @ 2 + (4*DPLL_MULT)/DPLL_DIV/ARMDIV |
266 | @ Max DPLL_MULT = 18 | 269 | @ Max DPLL_MULT = 18 |
267 | @ DPLL_DIV = 1 | 270 | @ DPLL_DIV = 1 |
268 | @ ARMDIV = 1 | 271 | @ ARMDIV = 1 |
269 | @ => 74 nop-instructions | 272 | @ => 74 nop-instructions |
270 | nop | 273 | nop |
271 | nop | 274 | nop |
272 | nop | 275 | nop |
273 | nop | 276 | nop |
274 | nop | 277 | nop |
275 | nop | 278 | nop |
276 | nop | 279 | nop |
277 | nop | 280 | nop |
278 | nop | 281 | nop |
279 | nop @10 | 282 | nop @10 |
280 | nop | 283 | nop |
281 | nop | 284 | nop |
282 | nop | 285 | nop |
283 | nop | 286 | nop |
284 | nop | 287 | nop |
285 | nop | 288 | nop |
286 | nop | 289 | nop |
287 | nop | 290 | nop |
288 | nop | 291 | nop |
289 | nop @20 | 292 | nop @20 |
290 | nop | 293 | nop |
291 | nop | 294 | nop |
292 | nop | 295 | nop |
293 | nop | 296 | nop |
294 | nop | 297 | nop |
295 | nop | 298 | nop |
296 | nop | 299 | nop |
297 | nop | 300 | nop |
298 | nop | 301 | nop |
299 | nop @30 | 302 | nop @30 |
300 | nop | 303 | nop |
301 | nop | 304 | nop |
302 | nop | 305 | nop |
303 | nop | 306 | nop |
304 | nop | 307 | nop |
305 | nop | 308 | nop |
306 | nop | 309 | nop |
307 | nop | 310 | nop |
308 | nop | 311 | nop |
309 | nop @40 | 312 | nop @40 |
310 | nop | 313 | nop |
311 | nop | 314 | nop |
312 | nop | 315 | nop |
313 | nop | 316 | nop |
314 | nop | 317 | nop |
315 | nop | 318 | nop |
316 | nop | 319 | nop |
317 | nop | 320 | nop |
318 | nop | 321 | nop |
319 | nop @50 | 322 | nop @50 |
320 | nop | 323 | nop |
321 | nop | 324 | nop |
322 | nop | 325 | nop |
323 | nop | 326 | nop |
324 | nop | 327 | nop |
325 | nop | 328 | nop |
326 | nop | 329 | nop |
327 | nop | 330 | nop |
328 | nop | 331 | nop |
329 | nop @60 | 332 | nop @60 |
330 | nop | 333 | nop |
331 | nop | 334 | nop |
332 | nop | 335 | nop |
333 | nop | 336 | nop |
334 | nop | 337 | nop |
335 | nop | 338 | nop |
336 | nop | 339 | nop |
337 | nop | 340 | nop |
338 | nop | 341 | nop |
339 | nop @70 | 342 | nop @70 |
340 | nop | 343 | nop |
341 | nop | 344 | nop |
342 | nop | 345 | nop |
343 | nop @74 | 346 | nop @74 |
344 | /* | 347 | /* |
345 | * omap1610_cpu_suspend()'s resume point. | 348 | * omap1610_cpu_suspend()'s resume point. |
346 | * | 349 | * |
347 | * It will just start executing here, so we'll restore stuff from the | 350 | * It will just start executing here, so we'll restore stuff from the |
348 | * stack. | 351 | * stack. |
349 | */ | 352 | */ |
350 | @ Restore the ARM_IDLECT1 and ARM_IDLECT2. | 353 | @ Restore the ARM_IDLECT1 and ARM_IDLECT2. |
351 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] | 354 | strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff] |
352 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] | 355 | strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff] |
353 | 356 | ||
354 | @ Restore EMIFF controls | 357 | @ Restore EMIFF controls |
355 | str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] | 358 | str r7, [r6, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff] |
356 | str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] | 359 | str r8, [r6, #EMIFS_CONFIG_ASM_OFFSET & 0xff] |
357 | 360 | ||
358 | @ Restore regs and return | 361 | @ Restore regs and return |
359 | ldmfd sp!, {r0 - r12, pc} | 362 | ldmfd sp!, {r0 - r12, pc} |
360 | 363 | ||
361 | ENTRY(omap1610_cpu_suspend_sz) | 364 | ENTRY(omap1610_cpu_suspend_sz) |
362 | .word . - omap1610_cpu_suspend | 365 | .word . - omap1610_cpu_suspend |
363 | #endif /* CONFIG_ARCH_OMAP16XX */ | 366 | #endif /* CONFIG_ARCH_OMAP16XX */ |
364 | 367 |
arch/arm/mach-omap1/sram.S
1 | /* | 1 | /* |
2 | * linux/arch/arm/plat-omap/sram-fn.S | 2 | * linux/arch/arm/plat-omap/sram-fn.S |
3 | * | 3 | * |
4 | * Functions that need to be run in internal SRAM | 4 | * Functions that need to be run in internal SRAM |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 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 | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/linkage.h> | 11 | #include <linux/linkage.h> |
12 | #include <asm/assembler.h> | 12 | #include <asm/assembler.h> |
13 | #include <mach/io.h> | 13 | #include <mach/io.h> |
14 | #include <mach/hardware.h> | 14 | #include <mach/hardware.h> |
15 | 15 | ||
16 | .text | 16 | .text |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * Reprograms ULPD and CKCTL. | 19 | * Reprograms ULPD and CKCTL. |
20 | */ | 20 | */ |
21 | .align 3 | ||
21 | ENTRY(omap1_sram_reprogram_clock) | 22 | ENTRY(omap1_sram_reprogram_clock) |
22 | stmfd sp!, {r0 - r12, lr} @ save registers on stack | 23 | stmfd sp!, {r0 - r12, lr} @ save registers on stack |
23 | 24 | ||
24 | mov r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0xff000000 | 25 | mov r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0xff000000 |
25 | orr r2, r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0x00ff0000 | 26 | orr r2, r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0x00ff0000 |
26 | orr r2, r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0x0000ff00 | 27 | orr r2, r2, #OMAP1_IO_ADDRESS(DPLL_CTL) & 0x0000ff00 |
27 | 28 | ||
28 | mov r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0xff000000 | 29 | mov r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0xff000000 |
29 | orr r3, r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0x00ff0000 | 30 | orr r3, r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0x00ff0000 |
30 | orr r3, r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0x0000ff00 | 31 | orr r3, r3, #OMAP1_IO_ADDRESS(ARM_CKCTL) & 0x0000ff00 |
31 | 32 | ||
32 | tst r0, #1 << 4 @ want lock mode? | 33 | tst r0, #1 << 4 @ want lock mode? |
33 | beq newck @ nope | 34 | beq newck @ nope |
34 | bic r0, r0, #1 << 4 @ else clear lock bit | 35 | bic r0, r0, #1 << 4 @ else clear lock bit |
35 | strh r0, [r2] @ set dpll into bypass mode | 36 | strh r0, [r2] @ set dpll into bypass mode |
36 | orr r0, r0, #1 << 4 @ set lock bit again | 37 | orr r0, r0, #1 << 4 @ set lock bit again |
37 | 38 | ||
38 | newck: | 39 | newck: |
39 | strh r1, [r3] @ write new ckctl value | 40 | strh r1, [r3] @ write new ckctl value |
40 | strh r0, [r2] @ write new dpll value | 41 | strh r0, [r2] @ write new dpll value |
41 | 42 | ||
42 | mov r4, #0x0700 @ let the clocks settle | 43 | mov r4, #0x0700 @ let the clocks settle |
43 | orr r4, r4, #0x00ff | 44 | orr r4, r4, #0x00ff |
44 | delay: sub r4, r4, #1 | 45 | delay: sub r4, r4, #1 |
45 | cmp r4, #0 | 46 | cmp r4, #0 |
46 | bne delay | 47 | bne delay |
47 | 48 | ||
48 | lock: ldrh r4, [r2], #0 @ read back dpll value | 49 | lock: ldrh r4, [r2], #0 @ read back dpll value |
49 | tst r0, #1 << 4 @ want lock mode? | 50 | tst r0, #1 << 4 @ want lock mode? |
50 | beq out @ nope | 51 | beq out @ nope |
51 | tst r4, #1 << 0 @ dpll rate locked? | 52 | tst r4, #1 << 0 @ dpll rate locked? |
52 | beq lock @ try again | 53 | beq lock @ try again |
53 | 54 | ||
54 | out: | 55 | out: |
55 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return | 56 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return |
56 | ENTRY(omap1_sram_reprogram_clock_sz) | 57 | ENTRY(omap1_sram_reprogram_clock_sz) |
57 | .word . - omap1_sram_reprogram_clock | 58 | .word . - omap1_sram_reprogram_clock |
58 | 59 |
arch/arm/mach-omap2/pm.h
1 | /* | 1 | /* |
2 | * OMAP2/3 Power Management Routines | 2 | * OMAP2/3 Power Management Routines |
3 | * | 3 | * |
4 | * Copyright (C) 2008 Nokia Corporation | 4 | * Copyright (C) 2008 Nokia Corporation |
5 | * Jouni Hogander | 5 | * Jouni Hogander |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | #ifndef __ARCH_ARM_MACH_OMAP2_PM_H | 11 | #ifndef __ARCH_ARM_MACH_OMAP2_PM_H |
12 | #define __ARCH_ARM_MACH_OMAP2_PM_H | 12 | #define __ARCH_ARM_MACH_OMAP2_PM_H |
13 | 13 | ||
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | 15 | ||
16 | #include "powerdomain.h" | 16 | #include "powerdomain.h" |
17 | 17 | ||
18 | extern void *omap3_secure_ram_storage; | 18 | extern void *omap3_secure_ram_storage; |
19 | extern void omap3_pm_off_mode_enable(int); | 19 | extern void omap3_pm_off_mode_enable(int); |
20 | extern void omap_sram_idle(void); | 20 | extern void omap_sram_idle(void); |
21 | extern int omap3_can_sleep(void); | 21 | extern int omap3_can_sleep(void); |
22 | extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); | 22 | extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); |
23 | extern int omap3_idle_init(void); | 23 | extern int omap3_idle_init(void); |
24 | 24 | ||
25 | #if defined(CONFIG_PM_OPP) | 25 | #if defined(CONFIG_PM_OPP) |
26 | extern int omap3_opp_init(void); | 26 | extern int omap3_opp_init(void); |
27 | extern int omap4_opp_init(void); | 27 | extern int omap4_opp_init(void); |
28 | #else | 28 | #else |
29 | static inline int omap3_opp_init(void) | 29 | static inline int omap3_opp_init(void) |
30 | { | 30 | { |
31 | return -EINVAL; | 31 | return -EINVAL; |
32 | } | 32 | } |
33 | static inline int omap4_opp_init(void) | 33 | static inline int omap4_opp_init(void) |
34 | { | 34 | { |
35 | return -EINVAL; | 35 | return -EINVAL; |
36 | } | 36 | } |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | struct cpuidle_params { | 39 | struct cpuidle_params { |
40 | u8 valid; | 40 | u8 valid; |
41 | u32 sleep_latency; | 41 | u32 sleep_latency; |
42 | u32 wake_latency; | 42 | u32 wake_latency; |
43 | u32 threshold; | 43 | u32 threshold; |
44 | }; | 44 | }; |
45 | 45 | ||
46 | #if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE) | 46 | #if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE) |
47 | extern void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params); | 47 | extern void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params); |
48 | #else | 48 | #else |
49 | static | 49 | static |
50 | inline void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) | 50 | inline void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params) |
51 | { | 51 | { |
52 | } | 52 | } |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); | 55 | extern int omap3_pm_get_suspend_state(struct powerdomain *pwrdm); |
56 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); | 56 | extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state); |
57 | 57 | ||
58 | extern u32 wakeup_timer_seconds; | 58 | extern u32 wakeup_timer_seconds; |
59 | extern u32 wakeup_timer_milliseconds; | 59 | extern u32 wakeup_timer_milliseconds; |
60 | extern struct omap_dm_timer *gptimer_wakeup; | 60 | extern struct omap_dm_timer *gptimer_wakeup; |
61 | 61 | ||
62 | #ifdef CONFIG_PM_DEBUG | 62 | #ifdef CONFIG_PM_DEBUG |
63 | extern void omap2_pm_dump(int mode, int resume, unsigned int us); | 63 | extern void omap2_pm_dump(int mode, int resume, unsigned int us); |
64 | extern void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds); | 64 | extern void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds); |
65 | extern int omap2_pm_debug; | 65 | extern int omap2_pm_debug; |
66 | extern u32 enable_off_mode; | 66 | extern u32 enable_off_mode; |
67 | extern u32 sleep_while_idle; | 67 | extern u32 sleep_while_idle; |
68 | #else | 68 | #else |
69 | #define omap2_pm_dump(mode, resume, us) do {} while (0); | 69 | #define omap2_pm_dump(mode, resume, us) do {} while (0); |
70 | #define omap2_pm_wakeup_on_timer(seconds, milliseconds) do {} while (0); | 70 | #define omap2_pm_wakeup_on_timer(seconds, milliseconds) do {} while (0); |
71 | #define omap2_pm_debug 0 | 71 | #define omap2_pm_debug 0 |
72 | #define enable_off_mode 0 | 72 | #define enable_off_mode 0 |
73 | #define sleep_while_idle 0 | 73 | #define sleep_while_idle 0 |
74 | #endif | 74 | #endif |
75 | 75 | ||
76 | #if defined(CONFIG_CPU_IDLE) | 76 | #if defined(CONFIG_CPU_IDLE) |
77 | extern void omap3_cpuidle_update_states(u32, u32); | 77 | extern void omap3_cpuidle_update_states(u32, u32); |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | #if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) | 80 | #if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS) |
81 | extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev); | 81 | extern void pm_dbg_update_time(struct powerdomain *pwrdm, int prev); |
82 | extern int pm_dbg_regset_save(int reg_set); | 82 | extern int pm_dbg_regset_save(int reg_set); |
83 | extern int pm_dbg_regset_init(int reg_set); | 83 | extern int pm_dbg_regset_init(int reg_set); |
84 | #else | 84 | #else |
85 | #define pm_dbg_update_time(pwrdm, prev) do {} while (0); | 85 | #define pm_dbg_update_time(pwrdm, prev) do {} while (0); |
86 | #define pm_dbg_regset_save(reg_set) do {} while (0); | 86 | #define pm_dbg_regset_save(reg_set) do {} while (0); |
87 | #define pm_dbg_regset_init(reg_set) do {} while (0); | 87 | #define pm_dbg_regset_init(reg_set) do {} while (0); |
88 | #endif /* CONFIG_PM_DEBUG */ | 88 | #endif /* CONFIG_PM_DEBUG */ |
89 | 89 | ||
90 | extern void omap24xx_idle_loop_suspend(void); | 90 | extern void omap24xx_idle_loop_suspend(void); |
91 | 91 | ||
92 | extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, | 92 | extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, |
93 | void __iomem *sdrc_power); | 93 | void __iomem *sdrc_power); |
94 | extern void omap34xx_cpu_suspend(u32 *addr, int save_state); | 94 | extern void omap34xx_cpu_suspend(u32 *addr, int save_state); |
95 | extern void save_secure_ram_context(u32 *addr); | 95 | extern int save_secure_ram_context(u32 *addr); |
96 | extern void omap3_save_scratchpad_contents(void); | 96 | extern void omap3_save_scratchpad_contents(void); |
97 | 97 | ||
98 | extern unsigned int omap24xx_idle_loop_suspend_sz; | 98 | extern unsigned int omap24xx_idle_loop_suspend_sz; |
99 | extern unsigned int save_secure_ram_context_sz; | 99 | extern unsigned int save_secure_ram_context_sz; |
100 | extern unsigned int omap24xx_cpu_suspend_sz; | 100 | extern unsigned int omap24xx_cpu_suspend_sz; |
101 | extern unsigned int omap34xx_cpu_suspend_sz; | 101 | extern unsigned int omap34xx_cpu_suspend_sz; |
102 | 102 | ||
103 | #define PM_RTA_ERRATUM_i608 (1 << 0) | 103 | #define PM_RTA_ERRATUM_i608 (1 << 0) |
104 | #define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1) | 104 | #define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1) |
105 | 105 | ||
106 | #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) | 106 | #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) |
107 | extern u16 pm34xx_errata; | 107 | extern u16 pm34xx_errata; |
108 | #define IS_PM34XX_ERRATUM(id) (pm34xx_errata & (id)) | 108 | #define IS_PM34XX_ERRATUM(id) (pm34xx_errata & (id)) |
109 | extern void enable_omap3630_toggle_l2_on_restore(void); | 109 | extern void enable_omap3630_toggle_l2_on_restore(void); |
110 | #else | 110 | #else |
111 | #define IS_PM34XX_ERRATUM(id) 0 | 111 | #define IS_PM34XX_ERRATUM(id) 0 |
112 | static inline void enable_omap3630_toggle_l2_on_restore(void) { } | 112 | static inline void enable_omap3630_toggle_l2_on_restore(void) { } |
113 | #endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ | 113 | #endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ |
114 | 114 | ||
115 | #ifdef CONFIG_OMAP_SMARTREFLEX | 115 | #ifdef CONFIG_OMAP_SMARTREFLEX |
116 | extern int omap_devinit_smartreflex(void); | 116 | extern int omap_devinit_smartreflex(void); |
117 | extern void omap_enable_smartreflex_on_init(void); | 117 | extern void omap_enable_smartreflex_on_init(void); |
118 | #else | 118 | #else |
119 | static inline int omap_devinit_smartreflex(void) | 119 | static inline int omap_devinit_smartreflex(void) |
120 | { | 120 | { |
121 | return -EINVAL; | 121 | return -EINVAL; |
122 | } | 122 | } |
123 | 123 | ||
124 | static inline void omap_enable_smartreflex_on_init(void) {} | 124 | static inline void omap_enable_smartreflex_on_init(void) {} |
125 | #endif | 125 | #endif |
126 | 126 | ||
127 | #ifdef CONFIG_TWL4030_CORE | 127 | #ifdef CONFIG_TWL4030_CORE |
128 | extern int omap3_twl_init(void); | 128 | extern int omap3_twl_init(void); |
129 | extern int omap4_twl_init(void); | 129 | extern int omap4_twl_init(void); |
130 | #else | 130 | #else |
131 | static inline int omap3_twl_init(void) | 131 | static inline int omap3_twl_init(void) |
132 | { | 132 | { |
133 | return -EINVAL; | 133 | return -EINVAL; |
134 | } | 134 | } |
135 | static inline int omap4_twl_init(void) | 135 | static inline int omap4_twl_init(void) |
136 | { | 136 | { |
137 | return -EINVAL; | 137 | return -EINVAL; |
138 | } | 138 | } |
139 | #endif | 139 | #endif |
140 | 140 | ||
141 | #endif | 141 | #endif |
142 | 142 |
arch/arm/mach-omap2/sleep24xx.S
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-omap2/sleep.S | 2 | * linux/arch/arm/mach-omap2/sleep.S |
3 | * | 3 | * |
4 | * (C) Copyright 2004 | 4 | * (C) Copyright 2004 |
5 | * Texas Instruments, <www.ti.com> | 5 | * Texas Instruments, <www.ti.com> |
6 | * Richard Woodruff <r-woodruff2@ti.com> | 6 | * Richard Woodruff <r-woodruff2@ti.com> |
7 | * | 7 | * |
8 | * (C) Copyright 2006 Nokia Corporation | 8 | * (C) Copyright 2006 Nokia Corporation |
9 | * Fixed idle loop sleep | 9 | * Fixed idle loop sleep |
10 | * Igor Stoppa <igor.stoppa@nokia.com> | 10 | * Igor Stoppa <igor.stoppa@nokia.com> |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or | 12 | * This program is free software; you can redistribute it and/or |
13 | * modify it under the terms of the GNU General Public License as | 13 | * modify it under the terms of the GNU General Public License as |
14 | * published by the Free Software Foundation; either version 2 of | 14 | * published by the Free Software Foundation; either version 2 of |
15 | * the License, or (at your option) any later version. | 15 | * the License, or (at your option) any later version. |
16 | * | 16 | * |
17 | * This program is distributed in the hope that it will be useful, | 17 | * This program is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the |
20 | * GNU General Public License for more details. | 20 | * GNU General Public License for more details. |
21 | * | 21 | * |
22 | * You should have received a copy of the GNU General Public License | 22 | * You should have received a copy of the GNU General Public License |
23 | * along with this program; if not, write to the Free Software | 23 | * along with this program; if not, write to the Free Software |
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
25 | * MA 02111-1307 USA | 25 | * MA 02111-1307 USA |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/linkage.h> | 28 | #include <linux/linkage.h> |
29 | #include <asm/assembler.h> | 29 | #include <asm/assembler.h> |
30 | #include <mach/io.h> | 30 | #include <mach/io.h> |
31 | 31 | ||
32 | #include <plat/omap24xx.h> | 32 | #include <plat/omap24xx.h> |
33 | 33 | ||
34 | #include "sdrc.h" | 34 | #include "sdrc.h" |
35 | 35 | ||
36 | /* First address of reserved address space? apparently valid for OMAP2 & 3 */ | 36 | /* First address of reserved address space? apparently valid for OMAP2 & 3 */ |
37 | #define A_SDRC0_V (0xC0000000) | 37 | #define A_SDRC0_V (0xC0000000) |
38 | 38 | ||
39 | .text | 39 | .text |
40 | 40 | ||
41 | /* | 41 | /* |
42 | * Forces OMAP into idle state | 42 | * Forces OMAP into idle state |
43 | * | 43 | * |
44 | * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI | 44 | * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI |
45 | * for normal idles. | 45 | * for normal idles. |
46 | * | 46 | * |
47 | * Note: This code get's copied to internal SRAM at boot. When the OMAP | 47 | * Note: This code get's copied to internal SRAM at boot. When the OMAP |
48 | * wakes up it continues execution at the point it went to sleep. | 48 | * wakes up it continues execution at the point it went to sleep. |
49 | */ | 49 | */ |
50 | .align 3 | ||
50 | ENTRY(omap24xx_idle_loop_suspend) | 51 | ENTRY(omap24xx_idle_loop_suspend) |
51 | stmfd sp!, {r0, lr} @ save registers on stack | 52 | stmfd sp!, {r0, lr} @ save registers on stack |
52 | mov r0, #0 @ clear for mcr setup | 53 | mov r0, #0 @ clear for mcr setup |
53 | mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt | 54 | mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt |
54 | ldmfd sp!, {r0, pc} @ restore regs and return | 55 | ldmfd sp!, {r0, pc} @ restore regs and return |
55 | 56 | ||
56 | ENTRY(omap24xx_idle_loop_suspend_sz) | 57 | ENTRY(omap24xx_idle_loop_suspend_sz) |
57 | .word . - omap24xx_idle_loop_suspend | 58 | .word . - omap24xx_idle_loop_suspend |
58 | 59 | ||
59 | /* | 60 | /* |
60 | * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing | 61 | * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing |
61 | * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore | 62 | * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore |
62 | * SDRC. | 63 | * SDRC. |
63 | * | 64 | * |
64 | * Input: | 65 | * Input: |
65 | * R0 : DLL ctrl value pre-Sleep | 66 | * R0 : DLL ctrl value pre-Sleep |
66 | * R1 : SDRC_DLLA_CTRL | 67 | * R1 : SDRC_DLLA_CTRL |
67 | * R2 : SDRC_POWER | 68 | * R2 : SDRC_POWER |
68 | * | 69 | * |
69 | * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on | 70 | * The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on |
70 | * when we get called, but the DLL probably isn't. We will wait a bit more in | 71 | * when we get called, but the DLL probably isn't. We will wait a bit more in |
71 | * case the DPLL isn't quite there yet. The code will wait on DLL for DDR even | 72 | * case the DPLL isn't quite there yet. The code will wait on DLL for DDR even |
72 | * if in unlocked mode. | 73 | * if in unlocked mode. |
73 | * | 74 | * |
74 | * For less than 242x-ES2.2 upon wake from a sleep mode where the external | 75 | * For less than 242x-ES2.2 upon wake from a sleep mode where the external |
75 | * oscillator was stopped, a timing bug exists where a non-stabilized 12MHz | 76 | * oscillator was stopped, a timing bug exists where a non-stabilized 12MHz |
76 | * clock can pass into the PRCM can cause problems at DSP and IVA. | 77 | * clock can pass into the PRCM can cause problems at DSP and IVA. |
77 | * To work around this the code will switch to the 32kHz source prior to sleep. | 78 | * To work around this the code will switch to the 32kHz source prior to sleep. |
78 | * Post sleep we will shift back to using the DPLL. Apparently, | 79 | * Post sleep we will shift back to using the DPLL. Apparently, |
79 | * CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait | 80 | * CM_IDLEST_CLKGEN does not reflect the full clock change so you need to wait |
80 | * 3x12MHz + 3x32kHz clocks for a full switch. | 81 | * 3x12MHz + 3x32kHz clocks for a full switch. |
81 | * | 82 | * |
82 | * The DLL load value is not kept in RETENTION or OFF. It needs to be restored | 83 | * The DLL load value is not kept in RETENTION or OFF. It needs to be restored |
83 | * at wake | 84 | * at wake |
84 | */ | 85 | */ |
86 | .align 3 | ||
85 | ENTRY(omap24xx_cpu_suspend) | 87 | ENTRY(omap24xx_cpu_suspend) |
86 | stmfd sp!, {r0 - r12, lr} @ save registers on stack | 88 | stmfd sp!, {r0 - r12, lr} @ save registers on stack |
87 | mov r3, #0x0 @ clear for mcr call | 89 | mov r3, #0x0 @ clear for mcr call |
88 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished | 90 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished |
89 | nop | 91 | nop |
90 | nop | 92 | nop |
91 | ldr r4, [r2] @ read SDRC_POWER | 93 | ldr r4, [r2] @ read SDRC_POWER |
92 | orr r4, r4, #0x40 @ enable self refresh on idle req | 94 | orr r4, r4, #0x40 @ enable self refresh on idle req |
93 | mov r5, #0x2000 @ set delay (DPLL relock + DLL relock) | 95 | mov r5, #0x2000 @ set delay (DPLL relock + DLL relock) |
94 | str r4, [r2] @ make it so | 96 | str r4, [r2] @ make it so |
95 | nop | 97 | nop |
96 | mcr p15, 0, r3, c7, c0, 4 @ wait for interrupt | 98 | mcr p15, 0, r3, c7, c0, 4 @ wait for interrupt |
97 | nop | 99 | nop |
98 | loop: | 100 | loop: |
99 | subs r5, r5, #0x1 @ awake, wait just a bit | 101 | subs r5, r5, #0x1 @ awake, wait just a bit |
100 | bne loop | 102 | bne loop |
101 | 103 | ||
102 | /* The DPLL has to be on before we take the DDR out of self refresh */ | 104 | /* The DPLL has to be on before we take the DDR out of self refresh */ |
103 | bic r4, r4, #0x40 @ now clear self refresh bit. | 105 | bic r4, r4, #0x40 @ now clear self refresh bit. |
104 | str r4, [r2] @ write to SDRC_POWER | 106 | str r4, [r2] @ write to SDRC_POWER |
105 | ldr r4, A_SDRC0 @ make a clock happen | 107 | ldr r4, A_SDRC0 @ make a clock happen |
106 | ldr r4, [r4] @ read A_SDRC0 | 108 | ldr r4, [r4] @ read A_SDRC0 |
107 | nop @ start auto refresh only after clk ok | 109 | nop @ start auto refresh only after clk ok |
108 | movs r0, r0 @ see if DDR or SDR | 110 | movs r0, r0 @ see if DDR or SDR |
109 | strne r0, [r1] @ rewrite DLLA to force DLL reload | 111 | strne r0, [r1] @ rewrite DLLA to force DLL reload |
110 | addne r1, r1, #0x8 @ move to DLLB | 112 | addne r1, r1, #0x8 @ move to DLLB |
111 | strne r0, [r1] @ rewrite DLLB to force DLL reload | 113 | strne r0, [r1] @ rewrite DLLB to force DLL reload |
112 | 114 | ||
113 | mov r5, #0x1000 | 115 | mov r5, #0x1000 |
114 | loop2: | 116 | loop2: |
115 | subs r5, r5, #0x1 | 117 | subs r5, r5, #0x1 |
116 | bne loop2 | 118 | bne loop2 |
117 | /* resume*/ | 119 | /* resume*/ |
118 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return | 120 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return |
119 | 121 | ||
120 | A_SDRC0: | 122 | A_SDRC0: |
121 | .word A_SDRC0_V | 123 | .word A_SDRC0_V |
122 | 124 | ||
123 | ENTRY(omap24xx_cpu_suspend_sz) | 125 | ENTRY(omap24xx_cpu_suspend_sz) |
124 | .word . - omap24xx_cpu_suspend | 126 | .word . - omap24xx_cpu_suspend |
125 | 127 |
arch/arm/mach-omap2/sleep34xx.S
1 | /* | 1 | /* |
2 | * (C) Copyright 2007 | 2 | * (C) Copyright 2007 |
3 | * Texas Instruments | 3 | * Texas Instruments |
4 | * Karthik Dasu <karthik-dp@ti.com> | 4 | * Karthik Dasu <karthik-dp@ti.com> |
5 | * | 5 | * |
6 | * (C) Copyright 2004 | 6 | * (C) Copyright 2004 |
7 | * Texas Instruments, <www.ti.com> | 7 | * Texas Instruments, <www.ti.com> |
8 | * Richard Woodruff <r-woodruff2@ti.com> | 8 | * Richard Woodruff <r-woodruff2@ti.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU General Public License as | 11 | * modify it under the terms of the GNU General Public License as |
12 | * published by the Free Software Foundation; either version 2 of | 12 | * published by the Free Software Foundation; either version 2 of |
13 | * the License, or (at your option) any later version. | 13 | * the License, or (at your option) any later version. |
14 | * | 14 | * |
15 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | * | 19 | * |
20 | * You should have received a copy of the GNU General Public License | 20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
23 | * MA 02111-1307 USA | 23 | * MA 02111-1307 USA |
24 | */ | 24 | */ |
25 | #include <linux/linkage.h> | 25 | #include <linux/linkage.h> |
26 | #include <asm/assembler.h> | 26 | #include <asm/assembler.h> |
27 | #include <plat/sram.h> | 27 | #include <plat/sram.h> |
28 | #include <mach/io.h> | 28 | #include <mach/io.h> |
29 | 29 | ||
30 | #include "cm2xxx_3xxx.h" | 30 | #include "cm2xxx_3xxx.h" |
31 | #include "prm2xxx_3xxx.h" | 31 | #include "prm2xxx_3xxx.h" |
32 | #include "sdrc.h" | 32 | #include "sdrc.h" |
33 | #include "control.h" | 33 | #include "control.h" |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * Registers access definitions | 36 | * Registers access definitions |
37 | */ | 37 | */ |
38 | #define SDRC_SCRATCHPAD_SEM_OFFS 0xc | 38 | #define SDRC_SCRATCHPAD_SEM_OFFS 0xc |
39 | #define SDRC_SCRATCHPAD_SEM_V OMAP343X_SCRATCHPAD_REGADDR\ | 39 | #define SDRC_SCRATCHPAD_SEM_V OMAP343X_SCRATCHPAD_REGADDR\ |
40 | (SDRC_SCRATCHPAD_SEM_OFFS) | 40 | (SDRC_SCRATCHPAD_SEM_OFFS) |
41 | #define PM_PREPWSTST_CORE_P OMAP3430_PRM_BASE + CORE_MOD +\ | 41 | #define PM_PREPWSTST_CORE_P OMAP3430_PRM_BASE + CORE_MOD +\ |
42 | OMAP3430_PM_PREPWSTST | 42 | OMAP3430_PM_PREPWSTST |
43 | #define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + OMAP2_PM_PWSTCTRL | 43 | #define PM_PWSTCTRL_MPU_P OMAP3430_PRM_BASE + MPU_MOD + OMAP2_PM_PWSTCTRL |
44 | #define CM_IDLEST1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1) | 44 | #define CM_IDLEST1_CORE_V OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST1) |
45 | #define CM_IDLEST_CKGEN_V OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST) | 45 | #define CM_IDLEST_CKGEN_V OMAP34XX_CM_REGADDR(PLL_MOD, CM_IDLEST) |
46 | #define SRAM_BASE_P OMAP3_SRAM_PA | 46 | #define SRAM_BASE_P OMAP3_SRAM_PA |
47 | #define CONTROL_STAT OMAP343X_CTRL_BASE + OMAP343X_CONTROL_STATUS | 47 | #define CONTROL_STAT OMAP343X_CTRL_BASE + OMAP343X_CONTROL_STATUS |
48 | #define CONTROL_MEM_RTA_CTRL (OMAP343X_CTRL_BASE +\ | 48 | #define CONTROL_MEM_RTA_CTRL (OMAP343X_CTRL_BASE +\ |
49 | OMAP36XX_CONTROL_MEM_RTA_CTRL) | 49 | OMAP36XX_CONTROL_MEM_RTA_CTRL) |
50 | 50 | ||
51 | /* Move this as correct place is available */ | 51 | /* Move this as correct place is available */ |
52 | #define SCRATCHPAD_MEM_OFFS 0x310 | 52 | #define SCRATCHPAD_MEM_OFFS 0x310 |
53 | #define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE +\ | 53 | #define SCRATCHPAD_BASE_P (OMAP343X_CTRL_BASE +\ |
54 | OMAP343X_CONTROL_MEM_WKUP +\ | 54 | OMAP343X_CONTROL_MEM_WKUP +\ |
55 | SCRATCHPAD_MEM_OFFS) | 55 | SCRATCHPAD_MEM_OFFS) |
56 | #define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER) | 56 | #define SDRC_POWER_V OMAP34XX_SDRC_REGADDR(SDRC_POWER) |
57 | #define SDRC_SYSCONFIG_P (OMAP343X_SDRC_BASE + SDRC_SYSCONFIG) | 57 | #define SDRC_SYSCONFIG_P (OMAP343X_SDRC_BASE + SDRC_SYSCONFIG) |
58 | #define SDRC_MR_0_P (OMAP343X_SDRC_BASE + SDRC_MR_0) | 58 | #define SDRC_MR_0_P (OMAP343X_SDRC_BASE + SDRC_MR_0) |
59 | #define SDRC_EMR2_0_P (OMAP343X_SDRC_BASE + SDRC_EMR2_0) | 59 | #define SDRC_EMR2_0_P (OMAP343X_SDRC_BASE + SDRC_EMR2_0) |
60 | #define SDRC_MANUAL_0_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_0) | 60 | #define SDRC_MANUAL_0_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_0) |
61 | #define SDRC_MR_1_P (OMAP343X_SDRC_BASE + SDRC_MR_1) | 61 | #define SDRC_MR_1_P (OMAP343X_SDRC_BASE + SDRC_MR_1) |
62 | #define SDRC_EMR2_1_P (OMAP343X_SDRC_BASE + SDRC_EMR2_1) | 62 | #define SDRC_EMR2_1_P (OMAP343X_SDRC_BASE + SDRC_EMR2_1) |
63 | #define SDRC_MANUAL_1_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_1) | 63 | #define SDRC_MANUAL_1_P (OMAP343X_SDRC_BASE + SDRC_MANUAL_1) |
64 | #define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) | 64 | #define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) |
65 | #define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) | 65 | #define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) |
66 | 66 | ||
67 | 67 | ||
68 | /* | 68 | /* |
69 | * API functions | 69 | * API functions |
70 | */ | 70 | */ |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * The "get_*restore_pointer" functions are used to provide a | 73 | * The "get_*restore_pointer" functions are used to provide a |
74 | * physical restore address where the ROM code jumps while waking | 74 | * physical restore address where the ROM code jumps while waking |
75 | * up from MPU OFF/OSWR state. | 75 | * up from MPU OFF/OSWR state. |
76 | * The restore pointer is stored into the scratchpad. | 76 | * The restore pointer is stored into the scratchpad. |
77 | */ | 77 | */ |
78 | 78 | ||
79 | .text | 79 | .text |
80 | /* Function call to get the restore pointer for resume from OFF */ | 80 | /* Function call to get the restore pointer for resume from OFF */ |
81 | ENTRY(get_restore_pointer) | 81 | ENTRY(get_restore_pointer) |
82 | stmfd sp!, {lr} @ save registers on stack | 82 | stmfd sp!, {lr} @ save registers on stack |
83 | adr r0, restore | 83 | adr r0, restore |
84 | ldmfd sp!, {pc} @ restore regs and return | 84 | ldmfd sp!, {pc} @ restore regs and return |
85 | ENTRY(get_restore_pointer_sz) | 85 | ENTRY(get_restore_pointer_sz) |
86 | .word . - get_restore_pointer | 86 | .word . - get_restore_pointer |
87 | 87 | ||
88 | .text | 88 | .text |
89 | /* Function call to get the restore pointer for 3630 resume from OFF */ | 89 | /* Function call to get the restore pointer for 3630 resume from OFF */ |
90 | ENTRY(get_omap3630_restore_pointer) | 90 | ENTRY(get_omap3630_restore_pointer) |
91 | stmfd sp!, {lr} @ save registers on stack | 91 | stmfd sp!, {lr} @ save registers on stack |
92 | adr r0, restore_3630 | 92 | adr r0, restore_3630 |
93 | ldmfd sp!, {pc} @ restore regs and return | 93 | ldmfd sp!, {pc} @ restore regs and return |
94 | ENTRY(get_omap3630_restore_pointer_sz) | 94 | ENTRY(get_omap3630_restore_pointer_sz) |
95 | .word . - get_omap3630_restore_pointer | 95 | .word . - get_omap3630_restore_pointer |
96 | 96 | ||
97 | .text | 97 | .text |
98 | /* Function call to get the restore pointer for ES3 to resume from OFF */ | 98 | /* Function call to get the restore pointer for ES3 to resume from OFF */ |
99 | ENTRY(get_es3_restore_pointer) | 99 | ENTRY(get_es3_restore_pointer) |
100 | stmfd sp!, {lr} @ save registers on stack | 100 | stmfd sp!, {lr} @ save registers on stack |
101 | adr r0, restore_es3 | 101 | adr r0, restore_es3 |
102 | ldmfd sp!, {pc} @ restore regs and return | 102 | ldmfd sp!, {pc} @ restore regs and return |
103 | ENTRY(get_es3_restore_pointer_sz) | 103 | ENTRY(get_es3_restore_pointer_sz) |
104 | .word . - get_es3_restore_pointer | 104 | .word . - get_es3_restore_pointer |
105 | 105 | ||
106 | .text | 106 | .text |
107 | /* | 107 | /* |
108 | * L2 cache needs to be toggled for stable OFF mode functionality on 3630. | 108 | * L2 cache needs to be toggled for stable OFF mode functionality on 3630. |
109 | * This function sets up a flag that will allow for this toggling to take | 109 | * This function sets up a flag that will allow for this toggling to take |
110 | * place on 3630. Hopefully some version in the future may not need this. | 110 | * place on 3630. Hopefully some version in the future may not need this. |
111 | */ | 111 | */ |
112 | ENTRY(enable_omap3630_toggle_l2_on_restore) | 112 | ENTRY(enable_omap3630_toggle_l2_on_restore) |
113 | stmfd sp!, {lr} @ save registers on stack | 113 | stmfd sp!, {lr} @ save registers on stack |
114 | /* Setup so that we will disable and enable l2 */ | 114 | /* Setup so that we will disable and enable l2 */ |
115 | mov r1, #0x1 | 115 | mov r1, #0x1 |
116 | str r1, l2dis_3630 | 116 | str r1, l2dis_3630 |
117 | ldmfd sp!, {pc} @ restore regs and return | 117 | ldmfd sp!, {pc} @ restore regs and return |
118 | 118 | ||
119 | .text | 119 | .text |
120 | /* Function to call rom code to save secure ram context */ | 120 | /* Function to call rom code to save secure ram context */ |
121 | .align 3 | ||
121 | ENTRY(save_secure_ram_context) | 122 | ENTRY(save_secure_ram_context) |
122 | stmfd sp!, {r1-r12, lr} @ save registers on stack | 123 | stmfd sp!, {r1-r12, lr} @ save registers on stack |
123 | adr r3, api_params @ r3 points to parameters | 124 | adr r3, api_params @ r3 points to parameters |
124 | str r0, [r3,#0x4] @ r0 has sdram address | 125 | str r0, [r3,#0x4] @ r0 has sdram address |
125 | ldr r12, high_mask | 126 | ldr r12, high_mask |
126 | and r3, r3, r12 | 127 | and r3, r3, r12 |
127 | ldr r12, sram_phy_addr_mask | 128 | ldr r12, sram_phy_addr_mask |
128 | orr r3, r3, r12 | 129 | orr r3, r3, r12 |
129 | mov r0, #25 @ set service ID for PPA | 130 | mov r0, #25 @ set service ID for PPA |
130 | mov r12, r0 @ copy secure service ID in r12 | 131 | mov r12, r0 @ copy secure service ID in r12 |
131 | mov r1, #0 @ set task id for ROM code in r1 | 132 | mov r1, #0 @ set task id for ROM code in r1 |
132 | mov r2, #4 @ set some flags in r2, r6 | 133 | mov r2, #4 @ set some flags in r2, r6 |
133 | mov r6, #0xff | 134 | mov r6, #0xff |
134 | mcr p15, 0, r0, c7, c10, 4 @ data write barrier | 135 | mcr p15, 0, r0, c7, c10, 4 @ data write barrier |
135 | mcr p15, 0, r0, c7, c10, 5 @ data memory barrier | 136 | mcr p15, 0, r0, c7, c10, 5 @ data memory barrier |
136 | .word 0xE1600071 @ call SMI monitor (smi #1) | 137 | .word 0xE1600071 @ call SMI monitor (smi #1) |
137 | nop | 138 | nop |
138 | nop | 139 | nop |
139 | nop | 140 | nop |
140 | nop | 141 | nop |
141 | ldmfd sp!, {r1-r12, pc} | 142 | ldmfd sp!, {r1-r12, pc} |
142 | sram_phy_addr_mask: | 143 | sram_phy_addr_mask: |
143 | .word SRAM_BASE_P | 144 | .word SRAM_BASE_P |
144 | high_mask: | 145 | high_mask: |
145 | .word 0xffff | 146 | .word 0xffff |
146 | api_params: | 147 | api_params: |
147 | .word 0x4, 0x0, 0x0, 0x1, 0x1 | 148 | .word 0x4, 0x0, 0x0, 0x1, 0x1 |
148 | ENTRY(save_secure_ram_context_sz) | 149 | ENTRY(save_secure_ram_context_sz) |
149 | .word . - save_secure_ram_context | 150 | .word . - save_secure_ram_context |
150 | 151 | ||
151 | /* | 152 | /* |
152 | * ====================== | 153 | * ====================== |
153 | * == Idle entry point == | 154 | * == Idle entry point == |
154 | * ====================== | 155 | * ====================== |
155 | */ | 156 | */ |
156 | 157 | ||
157 | /* | 158 | /* |
158 | * Forces OMAP into idle state | 159 | * Forces OMAP into idle state |
159 | * | 160 | * |
160 | * omap34xx_cpu_suspend() - This bit of code saves the CPU context if needed | 161 | * omap34xx_cpu_suspend() - This bit of code saves the CPU context if needed |
161 | * and executes the WFI instruction. Calling WFI effectively changes the | 162 | * and executes the WFI instruction. Calling WFI effectively changes the |
162 | * power domains states to the desired target power states. | 163 | * power domains states to the desired target power states. |
163 | * | 164 | * |
164 | * | 165 | * |
165 | * Notes: | 166 | * Notes: |
166 | * - this code gets copied to internal SRAM at boot and after wake-up | 167 | * - this code gets copied to internal SRAM at boot and after wake-up |
167 | * from OFF mode. The execution pointer in SRAM is _omap_sram_idle. | 168 | * from OFF mode. The execution pointer in SRAM is _omap_sram_idle. |
168 | * - when the OMAP wakes up it continues at different execution points | 169 | * - when the OMAP wakes up it continues at different execution points |
169 | * depending on the low power mode (non-OFF vs OFF modes), | 170 | * depending on the low power mode (non-OFF vs OFF modes), |
170 | * cf. 'Resume path for xxx mode' comments. | 171 | * cf. 'Resume path for xxx mode' comments. |
171 | */ | 172 | */ |
173 | .align 3 | ||
172 | ENTRY(omap34xx_cpu_suspend) | 174 | ENTRY(omap34xx_cpu_suspend) |
173 | stmfd sp!, {r0-r12, lr} @ save registers on stack | 175 | stmfd sp!, {r0-r12, lr} @ save registers on stack |
174 | 176 | ||
175 | /* | 177 | /* |
176 | * r0 contains restore pointer in sdram | 178 | * r0 contains restore pointer in sdram |
177 | * r1 contains information about saving context: | 179 | * r1 contains information about saving context: |
178 | * 0 - No context lost | 180 | * 0 - No context lost |
179 | * 1 - Only L1 and logic lost | 181 | * 1 - Only L1 and logic lost |
180 | * 2 - Only L2 lost | 182 | * 2 - Only L2 lost |
181 | * 3 - Both L1 and L2 lost | 183 | * 3 - Both L1 and L2 lost |
182 | */ | 184 | */ |
183 | 185 | ||
184 | /* Directly jump to WFI is the context save is not required */ | 186 | /* Directly jump to WFI is the context save is not required */ |
185 | cmp r1, #0x0 | 187 | cmp r1, #0x0 |
186 | beq omap3_do_wfi | 188 | beq omap3_do_wfi |
187 | 189 | ||
188 | /* Otherwise fall through to the save context code */ | 190 | /* Otherwise fall through to the save context code */ |
189 | save_context_wfi: | 191 | save_context_wfi: |
190 | mov r8, r0 @ Store SDRAM address in r8 | 192 | mov r8, r0 @ Store SDRAM address in r8 |
191 | mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register | 193 | mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register |
192 | mov r4, #0x1 @ Number of parameters for restore call | 194 | mov r4, #0x1 @ Number of parameters for restore call |
193 | stmia r8!, {r4-r5} @ Push parameters for restore call | 195 | stmia r8!, {r4-r5} @ Push parameters for restore call |
194 | mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register | 196 | mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register |
195 | stmia r8!, {r4-r5} @ Push parameters for restore call | 197 | stmia r8!, {r4-r5} @ Push parameters for restore call |
196 | 198 | ||
197 | /* Check what that target sleep state is from r1 */ | 199 | /* Check what that target sleep state is from r1 */ |
198 | cmp r1, #0x2 @ Only L2 lost, no need to save context | 200 | cmp r1, #0x2 @ Only L2 lost, no need to save context |
199 | beq clean_caches | 201 | beq clean_caches |
200 | 202 | ||
201 | l1_logic_lost: | 203 | l1_logic_lost: |
202 | /* Store sp and spsr to SDRAM */ | 204 | /* Store sp and spsr to SDRAM */ |
203 | mov r4, sp | 205 | mov r4, sp |
204 | mrs r5, spsr | 206 | mrs r5, spsr |
205 | mov r6, lr | 207 | mov r6, lr |
206 | stmia r8!, {r4-r6} | 208 | stmia r8!, {r4-r6} |
207 | /* Save all ARM registers */ | 209 | /* Save all ARM registers */ |
208 | /* Coprocessor access control register */ | 210 | /* Coprocessor access control register */ |
209 | mrc p15, 0, r6, c1, c0, 2 | 211 | mrc p15, 0, r6, c1, c0, 2 |
210 | stmia r8!, {r6} | 212 | stmia r8!, {r6} |
211 | /* TTBR0, TTBR1 and Translation table base control */ | 213 | /* TTBR0, TTBR1 and Translation table base control */ |
212 | mrc p15, 0, r4, c2, c0, 0 | 214 | mrc p15, 0, r4, c2, c0, 0 |
213 | mrc p15, 0, r5, c2, c0, 1 | 215 | mrc p15, 0, r5, c2, c0, 1 |
214 | mrc p15, 0, r6, c2, c0, 2 | 216 | mrc p15, 0, r6, c2, c0, 2 |
215 | stmia r8!, {r4-r6} | 217 | stmia r8!, {r4-r6} |
216 | /* | 218 | /* |
217 | * Domain access control register, data fault status register, | 219 | * Domain access control register, data fault status register, |
218 | * and instruction fault status register | 220 | * and instruction fault status register |
219 | */ | 221 | */ |
220 | mrc p15, 0, r4, c3, c0, 0 | 222 | mrc p15, 0, r4, c3, c0, 0 |
221 | mrc p15, 0, r5, c5, c0, 0 | 223 | mrc p15, 0, r5, c5, c0, 0 |
222 | mrc p15, 0, r6, c5, c0, 1 | 224 | mrc p15, 0, r6, c5, c0, 1 |
223 | stmia r8!, {r4-r6} | 225 | stmia r8!, {r4-r6} |
224 | /* | 226 | /* |
225 | * Data aux fault status register, instruction aux fault status, | 227 | * Data aux fault status register, instruction aux fault status, |
226 | * data fault address register and instruction fault address register | 228 | * data fault address register and instruction fault address register |
227 | */ | 229 | */ |
228 | mrc p15, 0, r4, c5, c1, 0 | 230 | mrc p15, 0, r4, c5, c1, 0 |
229 | mrc p15, 0, r5, c5, c1, 1 | 231 | mrc p15, 0, r5, c5, c1, 1 |
230 | mrc p15, 0, r6, c6, c0, 0 | 232 | mrc p15, 0, r6, c6, c0, 0 |
231 | mrc p15, 0, r7, c6, c0, 2 | 233 | mrc p15, 0, r7, c6, c0, 2 |
232 | stmia r8!, {r4-r7} | 234 | stmia r8!, {r4-r7} |
233 | /* | 235 | /* |
234 | * user r/w thread and process ID, user r/o thread and process ID, | 236 | * user r/w thread and process ID, user r/o thread and process ID, |
235 | * priv only thread and process ID, cache size selection | 237 | * priv only thread and process ID, cache size selection |
236 | */ | 238 | */ |
237 | mrc p15, 0, r4, c13, c0, 2 | 239 | mrc p15, 0, r4, c13, c0, 2 |
238 | mrc p15, 0, r5, c13, c0, 3 | 240 | mrc p15, 0, r5, c13, c0, 3 |
239 | mrc p15, 0, r6, c13, c0, 4 | 241 | mrc p15, 0, r6, c13, c0, 4 |
240 | mrc p15, 2, r7, c0, c0, 0 | 242 | mrc p15, 2, r7, c0, c0, 0 |
241 | stmia r8!, {r4-r7} | 243 | stmia r8!, {r4-r7} |
242 | /* Data TLB lockdown, instruction TLB lockdown registers */ | 244 | /* Data TLB lockdown, instruction TLB lockdown registers */ |
243 | mrc p15, 0, r5, c10, c0, 0 | 245 | mrc p15, 0, r5, c10, c0, 0 |
244 | mrc p15, 0, r6, c10, c0, 1 | 246 | mrc p15, 0, r6, c10, c0, 1 |
245 | stmia r8!, {r5-r6} | 247 | stmia r8!, {r5-r6} |
246 | /* Secure or non secure vector base address, FCSE PID, Context PID*/ | 248 | /* Secure or non secure vector base address, FCSE PID, Context PID*/ |
247 | mrc p15, 0, r4, c12, c0, 0 | 249 | mrc p15, 0, r4, c12, c0, 0 |
248 | mrc p15, 0, r5, c13, c0, 0 | 250 | mrc p15, 0, r5, c13, c0, 0 |
249 | mrc p15, 0, r6, c13, c0, 1 | 251 | mrc p15, 0, r6, c13, c0, 1 |
250 | stmia r8!, {r4-r6} | 252 | stmia r8!, {r4-r6} |
251 | /* Primary remap, normal remap registers */ | 253 | /* Primary remap, normal remap registers */ |
252 | mrc p15, 0, r4, c10, c2, 0 | 254 | mrc p15, 0, r4, c10, c2, 0 |
253 | mrc p15, 0, r5, c10, c2, 1 | 255 | mrc p15, 0, r5, c10, c2, 1 |
254 | stmia r8!,{r4-r5} | 256 | stmia r8!,{r4-r5} |
255 | 257 | ||
256 | /* Store current cpsr*/ | 258 | /* Store current cpsr*/ |
257 | mrs r2, cpsr | 259 | mrs r2, cpsr |
258 | stmia r8!, {r2} | 260 | stmia r8!, {r2} |
259 | 261 | ||
260 | mrc p15, 0, r4, c1, c0, 0 | 262 | mrc p15, 0, r4, c1, c0, 0 |
261 | /* save control register */ | 263 | /* save control register */ |
262 | stmia r8!, {r4} | 264 | stmia r8!, {r4} |
263 | 265 | ||
264 | clean_caches: | 266 | clean_caches: |
265 | /* | 267 | /* |
266 | * Clean Data or unified cache to POU | 268 | * Clean Data or unified cache to POU |
267 | * How to invalidate only L1 cache???? - #FIX_ME# | 269 | * How to invalidate only L1 cache???? - #FIX_ME# |
268 | * mcr p15, 0, r11, c7, c11, 1 | 270 | * mcr p15, 0, r11, c7, c11, 1 |
269 | */ | 271 | */ |
270 | cmp r1, #0x1 @ Check whether L2 inval is required | 272 | cmp r1, #0x1 @ Check whether L2 inval is required |
271 | beq omap3_do_wfi | 273 | beq omap3_do_wfi |
272 | 274 | ||
273 | clean_l2: | 275 | clean_l2: |
274 | /* | 276 | /* |
275 | * jump out to kernel flush routine | 277 | * jump out to kernel flush routine |
276 | * - reuse that code is better | 278 | * - reuse that code is better |
277 | * - it executes in a cached space so is faster than refetch per-block | 279 | * - it executes in a cached space so is faster than refetch per-block |
278 | * - should be faster and will change with kernel | 280 | * - should be faster and will change with kernel |
279 | * - 'might' have to copy address, load and jump to it | 281 | * - 'might' have to copy address, load and jump to it |
280 | */ | 282 | */ |
281 | ldr r1, kernel_flush | 283 | ldr r1, kernel_flush |
282 | mov lr, pc | 284 | mov lr, pc |
283 | bx r1 | 285 | bx r1 |
284 | 286 | ||
285 | omap3_do_wfi: | 287 | omap3_do_wfi: |
286 | ldr r4, sdrc_power @ read the SDRC_POWER register | 288 | ldr r4, sdrc_power @ read the SDRC_POWER register |
287 | ldr r5, [r4] @ read the contents of SDRC_POWER | 289 | ldr r5, [r4] @ read the contents of SDRC_POWER |
288 | orr r5, r5, #0x40 @ enable self refresh on idle req | 290 | orr r5, r5, #0x40 @ enable self refresh on idle req |
289 | str r5, [r4] @ write back to SDRC_POWER register | 291 | str r5, [r4] @ write back to SDRC_POWER register |
290 | 292 | ||
291 | /* Data memory barrier and Data sync barrier */ | 293 | /* Data memory barrier and Data sync barrier */ |
292 | mov r1, #0 | 294 | mov r1, #0 |
293 | mcr p15, 0, r1, c7, c10, 4 | 295 | mcr p15, 0, r1, c7, c10, 4 |
294 | mcr p15, 0, r1, c7, c10, 5 | 296 | mcr p15, 0, r1, c7, c10, 5 |
295 | 297 | ||
296 | /* | 298 | /* |
297 | * =================================== | 299 | * =================================== |
298 | * == WFI instruction => Enter idle == | 300 | * == WFI instruction => Enter idle == |
299 | * =================================== | 301 | * =================================== |
300 | */ | 302 | */ |
301 | wfi @ wait for interrupt | 303 | wfi @ wait for interrupt |
302 | 304 | ||
303 | /* | 305 | /* |
304 | * =================================== | 306 | * =================================== |
305 | * == Resume path for non-OFF modes == | 307 | * == Resume path for non-OFF modes == |
306 | * =================================== | 308 | * =================================== |
307 | */ | 309 | */ |
308 | nop | 310 | nop |
309 | nop | 311 | nop |
310 | nop | 312 | nop |
311 | nop | 313 | nop |
312 | nop | 314 | nop |
313 | nop | 315 | nop |
314 | nop | 316 | nop |
315 | nop | 317 | nop |
316 | nop | 318 | nop |
317 | nop | 319 | nop |
318 | bl wait_sdrc_ok | 320 | bl wait_sdrc_ok |
319 | 321 | ||
320 | /* | 322 | /* |
321 | * =================================== | 323 | * =================================== |
322 | * == Exit point from non-OFF modes == | 324 | * == Exit point from non-OFF modes == |
323 | * =================================== | 325 | * =================================== |
324 | */ | 326 | */ |
325 | ldmfd sp!, {r0-r12, pc} @ restore regs and return | 327 | ldmfd sp!, {r0-r12, pc} @ restore regs and return |
326 | 328 | ||
327 | 329 | ||
328 | /* | 330 | /* |
329 | * ============================== | 331 | * ============================== |
330 | * == Resume path for OFF mode == | 332 | * == Resume path for OFF mode == |
331 | * ============================== | 333 | * ============================== |
332 | */ | 334 | */ |
333 | 335 | ||
334 | /* | 336 | /* |
335 | * The restore_* functions are called by the ROM code | 337 | * The restore_* functions are called by the ROM code |
336 | * when back from WFI in OFF mode. | 338 | * when back from WFI in OFF mode. |
337 | * Cf. the get_*restore_pointer functions. | 339 | * Cf. the get_*restore_pointer functions. |
338 | * | 340 | * |
339 | * restore_es3: applies to 34xx >= ES3.0 | 341 | * restore_es3: applies to 34xx >= ES3.0 |
340 | * restore_3630: applies to 36xx | 342 | * restore_3630: applies to 36xx |
341 | * restore: common code for 3xxx | 343 | * restore: common code for 3xxx |
342 | */ | 344 | */ |
343 | restore_es3: | 345 | restore_es3: |
344 | ldr r5, pm_prepwstst_core_p | 346 | ldr r5, pm_prepwstst_core_p |
345 | ldr r4, [r5] | 347 | ldr r4, [r5] |
346 | and r4, r4, #0x3 | 348 | and r4, r4, #0x3 |
347 | cmp r4, #0x0 @ Check if previous power state of CORE is OFF | 349 | cmp r4, #0x0 @ Check if previous power state of CORE is OFF |
348 | bne restore | 350 | bne restore |
349 | adr r0, es3_sdrc_fix | 351 | adr r0, es3_sdrc_fix |
350 | ldr r1, sram_base | 352 | ldr r1, sram_base |
351 | ldr r2, es3_sdrc_fix_sz | 353 | ldr r2, es3_sdrc_fix_sz |
352 | mov r2, r2, ror #2 | 354 | mov r2, r2, ror #2 |
353 | copy_to_sram: | 355 | copy_to_sram: |
354 | ldmia r0!, {r3} @ val = *src | 356 | ldmia r0!, {r3} @ val = *src |
355 | stmia r1!, {r3} @ *dst = val | 357 | stmia r1!, {r3} @ *dst = val |
356 | subs r2, r2, #0x1 @ num_words-- | 358 | subs r2, r2, #0x1 @ num_words-- |
357 | bne copy_to_sram | 359 | bne copy_to_sram |
358 | ldr r1, sram_base | 360 | ldr r1, sram_base |
359 | blx r1 | 361 | blx r1 |
360 | b restore | 362 | b restore |
361 | 363 | ||
362 | restore_3630: | 364 | restore_3630: |
363 | ldr r1, pm_prepwstst_core_p | 365 | ldr r1, pm_prepwstst_core_p |
364 | ldr r2, [r1] | 366 | ldr r2, [r1] |
365 | and r2, r2, #0x3 | 367 | and r2, r2, #0x3 |
366 | cmp r2, #0x0 @ Check if previous power state of CORE is OFF | 368 | cmp r2, #0x0 @ Check if previous power state of CORE is OFF |
367 | bne restore | 369 | bne restore |
368 | /* Disable RTA before giving control */ | 370 | /* Disable RTA before giving control */ |
369 | ldr r1, control_mem_rta | 371 | ldr r1, control_mem_rta |
370 | mov r2, #OMAP36XX_RTA_DISABLE | 372 | mov r2, #OMAP36XX_RTA_DISABLE |
371 | str r2, [r1] | 373 | str r2, [r1] |
372 | 374 | ||
373 | /* Fall through to common code for the remaining logic */ | 375 | /* Fall through to common code for the remaining logic */ |
374 | 376 | ||
375 | restore: | 377 | restore: |
376 | /* | 378 | /* |
377 | * Check what was the reason for mpu reset and store the reason in r9: | 379 | * Check what was the reason for mpu reset and store the reason in r9: |
378 | * 0 - No context lost | 380 | * 0 - No context lost |
379 | * 1 - Only L1 and logic lost | 381 | * 1 - Only L1 and logic lost |
380 | * 2 - Only L2 lost - In this case, we wont be here | 382 | * 2 - Only L2 lost - In this case, we wont be here |
381 | * 3 - Both L1 and L2 lost | 383 | * 3 - Both L1 and L2 lost |
382 | */ | 384 | */ |
383 | ldr r1, pm_pwstctrl_mpu | 385 | ldr r1, pm_pwstctrl_mpu |
384 | ldr r2, [r1] | 386 | ldr r2, [r1] |
385 | and r2, r2, #0x3 | 387 | and r2, r2, #0x3 |
386 | cmp r2, #0x0 @ Check if target power state was OFF or RET | 388 | cmp r2, #0x0 @ Check if target power state was OFF or RET |
387 | moveq r9, #0x3 @ MPU OFF => L1 and L2 lost | 389 | moveq r9, #0x3 @ MPU OFF => L1 and L2 lost |
388 | movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation | 390 | movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation |
389 | bne logic_l1_restore | 391 | bne logic_l1_restore |
390 | 392 | ||
391 | ldr r0, l2dis_3630 | 393 | ldr r0, l2dis_3630 |
392 | cmp r0, #0x1 @ should we disable L2 on 3630? | 394 | cmp r0, #0x1 @ should we disable L2 on 3630? |
393 | bne skipl2dis | 395 | bne skipl2dis |
394 | mrc p15, 0, r0, c1, c0, 1 | 396 | mrc p15, 0, r0, c1, c0, 1 |
395 | bic r0, r0, #2 @ disable L2 cache | 397 | bic r0, r0, #2 @ disable L2 cache |
396 | mcr p15, 0, r0, c1, c0, 1 | 398 | mcr p15, 0, r0, c1, c0, 1 |
397 | skipl2dis: | 399 | skipl2dis: |
398 | ldr r0, control_stat | 400 | ldr r0, control_stat |
399 | ldr r1, [r0] | 401 | ldr r1, [r0] |
400 | and r1, #0x700 | 402 | and r1, #0x700 |
401 | cmp r1, #0x300 | 403 | cmp r1, #0x300 |
402 | beq l2_inv_gp | 404 | beq l2_inv_gp |
403 | mov r0, #40 @ set service ID for PPA | 405 | mov r0, #40 @ set service ID for PPA |
404 | mov r12, r0 @ copy secure Service ID in r12 | 406 | mov r12, r0 @ copy secure Service ID in r12 |
405 | mov r1, #0 @ set task id for ROM code in r1 | 407 | mov r1, #0 @ set task id for ROM code in r1 |
406 | mov r2, #4 @ set some flags in r2, r6 | 408 | mov r2, #4 @ set some flags in r2, r6 |
407 | mov r6, #0xff | 409 | mov r6, #0xff |
408 | adr r3, l2_inv_api_params @ r3 points to dummy parameters | 410 | adr r3, l2_inv_api_params @ r3 points to dummy parameters |
409 | mcr p15, 0, r0, c7, c10, 4 @ data write barrier | 411 | mcr p15, 0, r0, c7, c10, 4 @ data write barrier |
410 | mcr p15, 0, r0, c7, c10, 5 @ data memory barrier | 412 | mcr p15, 0, r0, c7, c10, 5 @ data memory barrier |
411 | .word 0xE1600071 @ call SMI monitor (smi #1) | 413 | .word 0xE1600071 @ call SMI monitor (smi #1) |
412 | /* Write to Aux control register to set some bits */ | 414 | /* Write to Aux control register to set some bits */ |
413 | mov r0, #42 @ set service ID for PPA | 415 | mov r0, #42 @ set service ID for PPA |
414 | mov r12, r0 @ copy secure Service ID in r12 | 416 | mov r12, r0 @ copy secure Service ID in r12 |
415 | mov r1, #0 @ set task id for ROM code in r1 | 417 | mov r1, #0 @ set task id for ROM code in r1 |
416 | mov r2, #4 @ set some flags in r2, r6 | 418 | mov r2, #4 @ set some flags in r2, r6 |
417 | mov r6, #0xff | 419 | mov r6, #0xff |
418 | ldr r4, scratchpad_base | 420 | ldr r4, scratchpad_base |
419 | ldr r3, [r4, #0xBC] @ r3 points to parameters | 421 | ldr r3, [r4, #0xBC] @ r3 points to parameters |
420 | mcr p15, 0, r0, c7, c10, 4 @ data write barrier | 422 | mcr p15, 0, r0, c7, c10, 4 @ data write barrier |
421 | mcr p15, 0, r0, c7, c10, 5 @ data memory barrier | 423 | mcr p15, 0, r0, c7, c10, 5 @ data memory barrier |
422 | .word 0xE1600071 @ call SMI monitor (smi #1) | 424 | .word 0xE1600071 @ call SMI monitor (smi #1) |
423 | 425 | ||
424 | #ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE | 426 | #ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE |
425 | /* Restore L2 aux control register */ | 427 | /* Restore L2 aux control register */ |
426 | @ set service ID for PPA | 428 | @ set service ID for PPA |
427 | mov r0, #CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID | 429 | mov r0, #CONFIG_OMAP3_L2_AUX_SECURE_SERVICE_SET_ID |
428 | mov r12, r0 @ copy service ID in r12 | 430 | mov r12, r0 @ copy service ID in r12 |
429 | mov r1, #0 @ set task ID for ROM code in r1 | 431 | mov r1, #0 @ set task ID for ROM code in r1 |
430 | mov r2, #4 @ set some flags in r2, r6 | 432 | mov r2, #4 @ set some flags in r2, r6 |
431 | mov r6, #0xff | 433 | mov r6, #0xff |
432 | ldr r4, scratchpad_base | 434 | ldr r4, scratchpad_base |
433 | ldr r3, [r4, #0xBC] | 435 | ldr r3, [r4, #0xBC] |
434 | adds r3, r3, #8 @ r3 points to parameters | 436 | adds r3, r3, #8 @ r3 points to parameters |
435 | mcr p15, 0, r0, c7, c10, 4 @ data write barrier | 437 | mcr p15, 0, r0, c7, c10, 4 @ data write barrier |
436 | mcr p15, 0, r0, c7, c10, 5 @ data memory barrier | 438 | mcr p15, 0, r0, c7, c10, 5 @ data memory barrier |
437 | .word 0xE1600071 @ call SMI monitor (smi #1) | 439 | .word 0xE1600071 @ call SMI monitor (smi #1) |
438 | #endif | 440 | #endif |
439 | b logic_l1_restore | 441 | b logic_l1_restore |
440 | 442 | ||
441 | l2_inv_api_params: | 443 | l2_inv_api_params: |
442 | .word 0x1, 0x00 | 444 | .word 0x1, 0x00 |
443 | l2_inv_gp: | 445 | l2_inv_gp: |
444 | /* Execute smi to invalidate L2 cache */ | 446 | /* Execute smi to invalidate L2 cache */ |
445 | mov r12, #0x1 @ set up to invalidate L2 | 447 | mov r12, #0x1 @ set up to invalidate L2 |
446 | .word 0xE1600070 @ Call SMI monitor (smieq) | 448 | .word 0xE1600070 @ Call SMI monitor (smieq) |
447 | /* Write to Aux control register to set some bits */ | 449 | /* Write to Aux control register to set some bits */ |
448 | ldr r4, scratchpad_base | 450 | ldr r4, scratchpad_base |
449 | ldr r3, [r4,#0xBC] | 451 | ldr r3, [r4,#0xBC] |
450 | ldr r0, [r3,#4] | 452 | ldr r0, [r3,#4] |
451 | mov r12, #0x3 | 453 | mov r12, #0x3 |
452 | .word 0xE1600070 @ Call SMI monitor (smieq) | 454 | .word 0xE1600070 @ Call SMI monitor (smieq) |
453 | ldr r4, scratchpad_base | 455 | ldr r4, scratchpad_base |
454 | ldr r3, [r4,#0xBC] | 456 | ldr r3, [r4,#0xBC] |
455 | ldr r0, [r3,#12] | 457 | ldr r0, [r3,#12] |
456 | mov r12, #0x2 | 458 | mov r12, #0x2 |
457 | .word 0xE1600070 @ Call SMI monitor (smieq) | 459 | .word 0xE1600070 @ Call SMI monitor (smieq) |
458 | logic_l1_restore: | 460 | logic_l1_restore: |
459 | ldr r1, l2dis_3630 | 461 | ldr r1, l2dis_3630 |
460 | cmp r1, #0x1 @ Test if L2 re-enable needed on 3630 | 462 | cmp r1, #0x1 @ Test if L2 re-enable needed on 3630 |
461 | bne skipl2reen | 463 | bne skipl2reen |
462 | mrc p15, 0, r1, c1, c0, 1 | 464 | mrc p15, 0, r1, c1, c0, 1 |
463 | orr r1, r1, #2 @ re-enable L2 cache | 465 | orr r1, r1, #2 @ re-enable L2 cache |
464 | mcr p15, 0, r1, c1, c0, 1 | 466 | mcr p15, 0, r1, c1, c0, 1 |
465 | skipl2reen: | 467 | skipl2reen: |
466 | mov r1, #0 | 468 | mov r1, #0 |
467 | /* | 469 | /* |
468 | * Invalidate all instruction caches to PoU | 470 | * Invalidate all instruction caches to PoU |
469 | * and flush branch target cache | 471 | * and flush branch target cache |
470 | */ | 472 | */ |
471 | mcr p15, 0, r1, c7, c5, 0 | 473 | mcr p15, 0, r1, c7, c5, 0 |
472 | 474 | ||
473 | ldr r4, scratchpad_base | 475 | ldr r4, scratchpad_base |
474 | ldr r3, [r4,#0xBC] | 476 | ldr r3, [r4,#0xBC] |
475 | adds r3, r3, #16 | 477 | adds r3, r3, #16 |
476 | ldmia r3!, {r4-r6} | 478 | ldmia r3!, {r4-r6} |
477 | mov sp, r4 | 479 | mov sp, r4 |
478 | msr spsr_cxsf, r5 | 480 | msr spsr_cxsf, r5 |
479 | mov lr, r6 | 481 | mov lr, r6 |
480 | 482 | ||
481 | ldmia r3!, {r4-r9} | 483 | ldmia r3!, {r4-r9} |
482 | /* Coprocessor access Control Register */ | 484 | /* Coprocessor access Control Register */ |
483 | mcr p15, 0, r4, c1, c0, 2 | 485 | mcr p15, 0, r4, c1, c0, 2 |
484 | 486 | ||
485 | /* TTBR0 */ | 487 | /* TTBR0 */ |
486 | MCR p15, 0, r5, c2, c0, 0 | 488 | MCR p15, 0, r5, c2, c0, 0 |
487 | /* TTBR1 */ | 489 | /* TTBR1 */ |
488 | MCR p15, 0, r6, c2, c0, 1 | 490 | MCR p15, 0, r6, c2, c0, 1 |
489 | /* Translation table base control register */ | 491 | /* Translation table base control register */ |
490 | MCR p15, 0, r7, c2, c0, 2 | 492 | MCR p15, 0, r7, c2, c0, 2 |
491 | /* Domain access Control Register */ | 493 | /* Domain access Control Register */ |
492 | MCR p15, 0, r8, c3, c0, 0 | 494 | MCR p15, 0, r8, c3, c0, 0 |
493 | /* Data fault status Register */ | 495 | /* Data fault status Register */ |
494 | MCR p15, 0, r9, c5, c0, 0 | 496 | MCR p15, 0, r9, c5, c0, 0 |
495 | 497 | ||
496 | ldmia r3!,{r4-r8} | 498 | ldmia r3!,{r4-r8} |
497 | /* Instruction fault status Register */ | 499 | /* Instruction fault status Register */ |
498 | MCR p15, 0, r4, c5, c0, 1 | 500 | MCR p15, 0, r4, c5, c0, 1 |
499 | /* Data Auxiliary Fault Status Register */ | 501 | /* Data Auxiliary Fault Status Register */ |
500 | MCR p15, 0, r5, c5, c1, 0 | 502 | MCR p15, 0, r5, c5, c1, 0 |
501 | /* Instruction Auxiliary Fault Status Register*/ | 503 | /* Instruction Auxiliary Fault Status Register*/ |
502 | MCR p15, 0, r6, c5, c1, 1 | 504 | MCR p15, 0, r6, c5, c1, 1 |
503 | /* Data Fault Address Register */ | 505 | /* Data Fault Address Register */ |
504 | MCR p15, 0, r7, c6, c0, 0 | 506 | MCR p15, 0, r7, c6, c0, 0 |
505 | /* Instruction Fault Address Register*/ | 507 | /* Instruction Fault Address Register*/ |
506 | MCR p15, 0, r8, c6, c0, 2 | 508 | MCR p15, 0, r8, c6, c0, 2 |
507 | ldmia r3!,{r4-r7} | 509 | ldmia r3!,{r4-r7} |
508 | 510 | ||
509 | /* User r/w thread and process ID */ | 511 | /* User r/w thread and process ID */ |
510 | MCR p15, 0, r4, c13, c0, 2 | 512 | MCR p15, 0, r4, c13, c0, 2 |
511 | /* User ro thread and process ID */ | 513 | /* User ro thread and process ID */ |
512 | MCR p15, 0, r5, c13, c0, 3 | 514 | MCR p15, 0, r5, c13, c0, 3 |
513 | /* Privileged only thread and process ID */ | 515 | /* Privileged only thread and process ID */ |
514 | MCR p15, 0, r6, c13, c0, 4 | 516 | MCR p15, 0, r6, c13, c0, 4 |
515 | /* Cache size selection */ | 517 | /* Cache size selection */ |
516 | MCR p15, 2, r7, c0, c0, 0 | 518 | MCR p15, 2, r7, c0, c0, 0 |
517 | ldmia r3!,{r4-r8} | 519 | ldmia r3!,{r4-r8} |
518 | /* Data TLB lockdown registers */ | 520 | /* Data TLB lockdown registers */ |
519 | MCR p15, 0, r4, c10, c0, 0 | 521 | MCR p15, 0, r4, c10, c0, 0 |
520 | /* Instruction TLB lockdown registers */ | 522 | /* Instruction TLB lockdown registers */ |
521 | MCR p15, 0, r5, c10, c0, 1 | 523 | MCR p15, 0, r5, c10, c0, 1 |
522 | /* Secure or Nonsecure Vector Base Address */ | 524 | /* Secure or Nonsecure Vector Base Address */ |
523 | MCR p15, 0, r6, c12, c0, 0 | 525 | MCR p15, 0, r6, c12, c0, 0 |
524 | /* FCSE PID */ | 526 | /* FCSE PID */ |
525 | MCR p15, 0, r7, c13, c0, 0 | 527 | MCR p15, 0, r7, c13, c0, 0 |
526 | /* Context PID */ | 528 | /* Context PID */ |
527 | MCR p15, 0, r8, c13, c0, 1 | 529 | MCR p15, 0, r8, c13, c0, 1 |
528 | 530 | ||
529 | ldmia r3!,{r4-r5} | 531 | ldmia r3!,{r4-r5} |
530 | /* Primary memory remap register */ | 532 | /* Primary memory remap register */ |
531 | MCR p15, 0, r4, c10, c2, 0 | 533 | MCR p15, 0, r4, c10, c2, 0 |
532 | /* Normal memory remap register */ | 534 | /* Normal memory remap register */ |
533 | MCR p15, 0, r5, c10, c2, 1 | 535 | MCR p15, 0, r5, c10, c2, 1 |
534 | 536 | ||
535 | /* Restore cpsr */ | 537 | /* Restore cpsr */ |
536 | ldmia r3!,{r4} @ load CPSR from SDRAM | 538 | ldmia r3!,{r4} @ load CPSR from SDRAM |
537 | msr cpsr, r4 @ store cpsr | 539 | msr cpsr, r4 @ store cpsr |
538 | 540 | ||
539 | /* Enabling MMU here */ | 541 | /* Enabling MMU here */ |
540 | mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl | 542 | mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl |
541 | /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */ | 543 | /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */ |
542 | and r7, #0x7 | 544 | and r7, #0x7 |
543 | cmp r7, #0x0 | 545 | cmp r7, #0x0 |
544 | beq usettbr0 | 546 | beq usettbr0 |
545 | ttbr_error: | 547 | ttbr_error: |
546 | /* | 548 | /* |
547 | * More work needs to be done to support N[0:2] value other than 0 | 549 | * More work needs to be done to support N[0:2] value other than 0 |
548 | * So looping here so that the error can be detected | 550 | * So looping here so that the error can be detected |
549 | */ | 551 | */ |
550 | b ttbr_error | 552 | b ttbr_error |
551 | usettbr0: | 553 | usettbr0: |
552 | mrc p15, 0, r2, c2, c0, 0 | 554 | mrc p15, 0, r2, c2, c0, 0 |
553 | ldr r5, ttbrbit_mask | 555 | ldr r5, ttbrbit_mask |
554 | and r2, r5 | 556 | and r2, r5 |
555 | mov r4, pc | 557 | mov r4, pc |
556 | ldr r5, table_index_mask | 558 | ldr r5, table_index_mask |
557 | and r4, r5 @ r4 = 31 to 20 bits of pc | 559 | and r4, r5 @ r4 = 31 to 20 bits of pc |
558 | /* Extract the value to be written to table entry */ | 560 | /* Extract the value to be written to table entry */ |
559 | ldr r1, table_entry | 561 | ldr r1, table_entry |
560 | /* r1 has the value to be written to table entry*/ | 562 | /* r1 has the value to be written to table entry*/ |
561 | add r1, r1, r4 | 563 | add r1, r1, r4 |
562 | /* Getting the address of table entry to modify */ | 564 | /* Getting the address of table entry to modify */ |
563 | lsr r4, #18 | 565 | lsr r4, #18 |
564 | /* r2 has the location which needs to be modified */ | 566 | /* r2 has the location which needs to be modified */ |
565 | add r2, r4 | 567 | add r2, r4 |
566 | /* Storing previous entry of location being modified */ | 568 | /* Storing previous entry of location being modified */ |
567 | ldr r5, scratchpad_base | 569 | ldr r5, scratchpad_base |
568 | ldr r4, [r2] | 570 | ldr r4, [r2] |
569 | str r4, [r5, #0xC0] | 571 | str r4, [r5, #0xC0] |
570 | /* Modify the table entry */ | 572 | /* Modify the table entry */ |
571 | str r1, [r2] | 573 | str r1, [r2] |
572 | /* | 574 | /* |
573 | * Storing address of entry being modified | 575 | * Storing address of entry being modified |
574 | * - will be restored after enabling MMU | 576 | * - will be restored after enabling MMU |
575 | */ | 577 | */ |
576 | ldr r5, scratchpad_base | 578 | ldr r5, scratchpad_base |
577 | str r2, [r5, #0xC4] | 579 | str r2, [r5, #0xC4] |
578 | 580 | ||
579 | mov r0, #0 | 581 | mov r0, #0 |
580 | mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer | 582 | mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer |
581 | mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array | 583 | mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array |
582 | mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB | 584 | mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB |
583 | mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB | 585 | mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB |
584 | /* | 586 | /* |
585 | * Restore control register. This enables the MMU. | 587 | * Restore control register. This enables the MMU. |
586 | * The caches and prediction are not enabled here, they | 588 | * The caches and prediction are not enabled here, they |
587 | * will be enabled after restoring the MMU table entry. | 589 | * will be enabled after restoring the MMU table entry. |
588 | */ | 590 | */ |
589 | ldmia r3!, {r4} | 591 | ldmia r3!, {r4} |
590 | /* Store previous value of control register in scratchpad */ | 592 | /* Store previous value of control register in scratchpad */ |
591 | str r4, [r5, #0xC8] | 593 | str r4, [r5, #0xC8] |
592 | ldr r2, cache_pred_disable_mask | 594 | ldr r2, cache_pred_disable_mask |
593 | and r4, r2 | 595 | and r4, r2 |
594 | mcr p15, 0, r4, c1, c0, 0 | 596 | mcr p15, 0, r4, c1, c0, 0 |
595 | 597 | ||
596 | /* | 598 | /* |
597 | * ============================== | 599 | * ============================== |
598 | * == Exit point from OFF mode == | 600 | * == Exit point from OFF mode == |
599 | * ============================== | 601 | * ============================== |
600 | */ | 602 | */ |
601 | ldmfd sp!, {r0-r12, pc} @ restore regs and return | 603 | ldmfd sp!, {r0-r12, pc} @ restore regs and return |
602 | 604 | ||
603 | 605 | ||
604 | /* | 606 | /* |
605 | * Internal functions | 607 | * Internal functions |
606 | */ | 608 | */ |
607 | 609 | ||
608 | /* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */ | 610 | /* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */ |
609 | .text | 611 | .text |
610 | ENTRY(es3_sdrc_fix) | 612 | ENTRY(es3_sdrc_fix) |
611 | ldr r4, sdrc_syscfg @ get config addr | 613 | ldr r4, sdrc_syscfg @ get config addr |
612 | ldr r5, [r4] @ get value | 614 | ldr r5, [r4] @ get value |
613 | tst r5, #0x100 @ is part access blocked | 615 | tst r5, #0x100 @ is part access blocked |
614 | it eq | 616 | it eq |
615 | biceq r5, r5, #0x100 @ clear bit if set | 617 | biceq r5, r5, #0x100 @ clear bit if set |
616 | str r5, [r4] @ write back change | 618 | str r5, [r4] @ write back change |
617 | ldr r4, sdrc_mr_0 @ get config addr | 619 | ldr r4, sdrc_mr_0 @ get config addr |
618 | ldr r5, [r4] @ get value | 620 | ldr r5, [r4] @ get value |
619 | str r5, [r4] @ write back change | 621 | str r5, [r4] @ write back change |
620 | ldr r4, sdrc_emr2_0 @ get config addr | 622 | ldr r4, sdrc_emr2_0 @ get config addr |
621 | ldr r5, [r4] @ get value | 623 | ldr r5, [r4] @ get value |
622 | str r5, [r4] @ write back change | 624 | str r5, [r4] @ write back change |
623 | ldr r4, sdrc_manual_0 @ get config addr | 625 | ldr r4, sdrc_manual_0 @ get config addr |
624 | mov r5, #0x2 @ autorefresh command | 626 | mov r5, #0x2 @ autorefresh command |
625 | str r5, [r4] @ kick off refreshes | 627 | str r5, [r4] @ kick off refreshes |
626 | ldr r4, sdrc_mr_1 @ get config addr | 628 | ldr r4, sdrc_mr_1 @ get config addr |
627 | ldr r5, [r4] @ get value | 629 | ldr r5, [r4] @ get value |
628 | str r5, [r4] @ write back change | 630 | str r5, [r4] @ write back change |
629 | ldr r4, sdrc_emr2_1 @ get config addr | 631 | ldr r4, sdrc_emr2_1 @ get config addr |
630 | ldr r5, [r4] @ get value | 632 | ldr r5, [r4] @ get value |
631 | str r5, [r4] @ write back change | 633 | str r5, [r4] @ write back change |
632 | ldr r4, sdrc_manual_1 @ get config addr | 634 | ldr r4, sdrc_manual_1 @ get config addr |
633 | mov r5, #0x2 @ autorefresh command | 635 | mov r5, #0x2 @ autorefresh command |
634 | str r5, [r4] @ kick off refreshes | 636 | str r5, [r4] @ kick off refreshes |
635 | bx lr | 637 | bx lr |
636 | 638 | ||
637 | sdrc_syscfg: | 639 | sdrc_syscfg: |
638 | .word SDRC_SYSCONFIG_P | 640 | .word SDRC_SYSCONFIG_P |
639 | sdrc_mr_0: | 641 | sdrc_mr_0: |
640 | .word SDRC_MR_0_P | 642 | .word SDRC_MR_0_P |
641 | sdrc_emr2_0: | 643 | sdrc_emr2_0: |
642 | .word SDRC_EMR2_0_P | 644 | .word SDRC_EMR2_0_P |
643 | sdrc_manual_0: | 645 | sdrc_manual_0: |
644 | .word SDRC_MANUAL_0_P | 646 | .word SDRC_MANUAL_0_P |
645 | sdrc_mr_1: | 647 | sdrc_mr_1: |
646 | .word SDRC_MR_1_P | 648 | .word SDRC_MR_1_P |
647 | sdrc_emr2_1: | 649 | sdrc_emr2_1: |
648 | .word SDRC_EMR2_1_P | 650 | .word SDRC_EMR2_1_P |
649 | sdrc_manual_1: | 651 | sdrc_manual_1: |
650 | .word SDRC_MANUAL_1_P | 652 | .word SDRC_MANUAL_1_P |
651 | ENTRY(es3_sdrc_fix_sz) | 653 | ENTRY(es3_sdrc_fix_sz) |
652 | .word . - es3_sdrc_fix | 654 | .word . - es3_sdrc_fix |
653 | 655 | ||
654 | /* | 656 | /* |
655 | * This function implements the erratum ID i581 WA: | 657 | * This function implements the erratum ID i581 WA: |
656 | * SDRC state restore before accessing the SDRAM | 658 | * SDRC state restore before accessing the SDRAM |
657 | * | 659 | * |
658 | * Only used at return from non-OFF mode. For OFF | 660 | * Only used at return from non-OFF mode. For OFF |
659 | * mode the ROM code configures the SDRC and | 661 | * mode the ROM code configures the SDRC and |
660 | * the DPLL before calling the restore code directly | 662 | * the DPLL before calling the restore code directly |
661 | * from DDR. | 663 | * from DDR. |
662 | */ | 664 | */ |
663 | 665 | ||
664 | /* Make sure SDRC accesses are ok */ | 666 | /* Make sure SDRC accesses are ok */ |
665 | wait_sdrc_ok: | 667 | wait_sdrc_ok: |
666 | 668 | ||
667 | /* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */ | 669 | /* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */ |
668 | ldr r4, cm_idlest_ckgen | 670 | ldr r4, cm_idlest_ckgen |
669 | wait_dpll3_lock: | 671 | wait_dpll3_lock: |
670 | ldr r5, [r4] | 672 | ldr r5, [r4] |
671 | tst r5, #1 | 673 | tst r5, #1 |
672 | beq wait_dpll3_lock | 674 | beq wait_dpll3_lock |
673 | 675 | ||
674 | ldr r4, cm_idlest1_core | 676 | ldr r4, cm_idlest1_core |
675 | wait_sdrc_ready: | 677 | wait_sdrc_ready: |
676 | ldr r5, [r4] | 678 | ldr r5, [r4] |
677 | tst r5, #0x2 | 679 | tst r5, #0x2 |
678 | bne wait_sdrc_ready | 680 | bne wait_sdrc_ready |
679 | /* allow DLL powerdown upon hw idle req */ | 681 | /* allow DLL powerdown upon hw idle req */ |
680 | ldr r4, sdrc_power | 682 | ldr r4, sdrc_power |
681 | ldr r5, [r4] | 683 | ldr r5, [r4] |
682 | bic r5, r5, #0x40 | 684 | bic r5, r5, #0x40 |
683 | str r5, [r4] | 685 | str r5, [r4] |
684 | 686 | ||
685 | is_dll_in_lock_mode: | 687 | is_dll_in_lock_mode: |
686 | /* Is dll in lock mode? */ | 688 | /* Is dll in lock mode? */ |
687 | ldr r4, sdrc_dlla_ctrl | 689 | ldr r4, sdrc_dlla_ctrl |
688 | ldr r5, [r4] | 690 | ldr r5, [r4] |
689 | tst r5, #0x4 | 691 | tst r5, #0x4 |
690 | bxne lr @ Return if locked | 692 | bxne lr @ Return if locked |
691 | /* wait till dll locks */ | 693 | /* wait till dll locks */ |
692 | wait_dll_lock_timed: | 694 | wait_dll_lock_timed: |
693 | ldr r4, wait_dll_lock_counter | 695 | ldr r4, wait_dll_lock_counter |
694 | add r4, r4, #1 | 696 | add r4, r4, #1 |
695 | str r4, wait_dll_lock_counter | 697 | str r4, wait_dll_lock_counter |
696 | ldr r4, sdrc_dlla_status | 698 | ldr r4, sdrc_dlla_status |
697 | /* Wait 20uS for lock */ | 699 | /* Wait 20uS for lock */ |
698 | mov r6, #8 | 700 | mov r6, #8 |
699 | wait_dll_lock: | 701 | wait_dll_lock: |
700 | subs r6, r6, #0x1 | 702 | subs r6, r6, #0x1 |
701 | beq kick_dll | 703 | beq kick_dll |
702 | ldr r5, [r4] | 704 | ldr r5, [r4] |
703 | and r5, r5, #0x4 | 705 | and r5, r5, #0x4 |
704 | cmp r5, #0x4 | 706 | cmp r5, #0x4 |
705 | bne wait_dll_lock | 707 | bne wait_dll_lock |
706 | bx lr @ Return when locked | 708 | bx lr @ Return when locked |
707 | 709 | ||
708 | /* disable/reenable DLL if not locked */ | 710 | /* disable/reenable DLL if not locked */ |
709 | kick_dll: | 711 | kick_dll: |
710 | ldr r4, sdrc_dlla_ctrl | 712 | ldr r4, sdrc_dlla_ctrl |
711 | ldr r5, [r4] | 713 | ldr r5, [r4] |
712 | mov r6, r5 | 714 | mov r6, r5 |
713 | bic r6, #(1<<3) @ disable dll | 715 | bic r6, #(1<<3) @ disable dll |
714 | str r6, [r4] | 716 | str r6, [r4] |
715 | dsb | 717 | dsb |
716 | orr r6, r6, #(1<<3) @ enable dll | 718 | orr r6, r6, #(1<<3) @ enable dll |
717 | str r6, [r4] | 719 | str r6, [r4] |
718 | dsb | 720 | dsb |
719 | ldr r4, kick_counter | 721 | ldr r4, kick_counter |
720 | add r4, r4, #1 | 722 | add r4, r4, #1 |
721 | str r4, kick_counter | 723 | str r4, kick_counter |
722 | b wait_dll_lock_timed | 724 | b wait_dll_lock_timed |
723 | 725 | ||
724 | cm_idlest1_core: | 726 | cm_idlest1_core: |
725 | .word CM_IDLEST1_CORE_V | 727 | .word CM_IDLEST1_CORE_V |
726 | cm_idlest_ckgen: | 728 | cm_idlest_ckgen: |
727 | .word CM_IDLEST_CKGEN_V | 729 | .word CM_IDLEST_CKGEN_V |
728 | sdrc_dlla_status: | 730 | sdrc_dlla_status: |
729 | .word SDRC_DLLA_STATUS_V | 731 | .word SDRC_DLLA_STATUS_V |
730 | sdrc_dlla_ctrl: | 732 | sdrc_dlla_ctrl: |
731 | .word SDRC_DLLA_CTRL_V | 733 | .word SDRC_DLLA_CTRL_V |
732 | pm_prepwstst_core_p: | 734 | pm_prepwstst_core_p: |
733 | .word PM_PREPWSTST_CORE_P | 735 | .word PM_PREPWSTST_CORE_P |
734 | pm_pwstctrl_mpu: | 736 | pm_pwstctrl_mpu: |
735 | .word PM_PWSTCTRL_MPU_P | 737 | .word PM_PWSTCTRL_MPU_P |
736 | scratchpad_base: | 738 | scratchpad_base: |
737 | .word SCRATCHPAD_BASE_P | 739 | .word SCRATCHPAD_BASE_P |
738 | sram_base: | 740 | sram_base: |
739 | .word SRAM_BASE_P + 0x8000 | 741 | .word SRAM_BASE_P + 0x8000 |
740 | sdrc_power: | 742 | sdrc_power: |
741 | .word SDRC_POWER_V | 743 | .word SDRC_POWER_V |
742 | ttbrbit_mask: | 744 | ttbrbit_mask: |
743 | .word 0xFFFFC000 | 745 | .word 0xFFFFC000 |
744 | table_index_mask: | 746 | table_index_mask: |
745 | .word 0xFFF00000 | 747 | .word 0xFFF00000 |
746 | table_entry: | 748 | table_entry: |
747 | .word 0x00000C02 | 749 | .word 0x00000C02 |
748 | cache_pred_disable_mask: | 750 | cache_pred_disable_mask: |
749 | .word 0xFFFFE7FB | 751 | .word 0xFFFFE7FB |
750 | control_stat: | 752 | control_stat: |
751 | .word CONTROL_STAT | 753 | .word CONTROL_STAT |
752 | control_mem_rta: | 754 | control_mem_rta: |
753 | .word CONTROL_MEM_RTA_CTRL | 755 | .word CONTROL_MEM_RTA_CTRL |
754 | kernel_flush: | 756 | kernel_flush: |
755 | .word v7_flush_dcache_all | 757 | .word v7_flush_dcache_all |
756 | l2dis_3630: | 758 | l2dis_3630: |
757 | .word 0 | 759 | .word 0 |
758 | /* | 760 | /* |
759 | * When exporting to userspace while the counters are in SRAM, | 761 | * When exporting to userspace while the counters are in SRAM, |
760 | * these 2 words need to be at the end to facilitate retrival! | 762 | * these 2 words need to be at the end to facilitate retrival! |
761 | */ | 763 | */ |
762 | kick_counter: | 764 | kick_counter: |
763 | .word 0 | 765 | .word 0 |
764 | wait_dll_lock_counter: | 766 | wait_dll_lock_counter: |
765 | .word 0 | 767 | .word 0 |
766 | 768 | ||
767 | ENTRY(omap34xx_cpu_suspend_sz) | 769 | ENTRY(omap34xx_cpu_suspend_sz) |
768 | .word . - omap34xx_cpu_suspend | 770 | .word . - omap34xx_cpu_suspend |
769 | 771 |
arch/arm/mach-omap2/sram242x.S
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-omap2/sram242x.S | 2 | * linux/arch/arm/mach-omap2/sram242x.S |
3 | * | 3 | * |
4 | * Omap2 specific functions that need to be run in internal SRAM | 4 | * Omap2 specific functions that need to be run in internal SRAM |
5 | * | 5 | * |
6 | * (C) Copyright 2004 | 6 | * (C) Copyright 2004 |
7 | * Texas Instruments, <www.ti.com> | 7 | * Texas Instruments, <www.ti.com> |
8 | * Richard Woodruff <r-woodruff2@ti.com> | 8 | * Richard Woodruff <r-woodruff2@ti.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU General Public License as | 11 | * modify it under the terms of the GNU General Public License as |
12 | * published by the Free Software Foundation; either version 2 of | 12 | * published by the Free Software Foundation; either version 2 of |
13 | * the License, or (at your option) any later version. | 13 | * the License, or (at your option) any later version. |
14 | * | 14 | * |
15 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | * | 19 | * |
20 | * You should have received a copy of the GNU General Public License | 20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
23 | * MA 02111-1307 USA | 23 | * MA 02111-1307 USA |
24 | * | 24 | * |
25 | * Richard Woodruff notes that any changes to this code must be carefully | 25 | * Richard Woodruff notes that any changes to this code must be carefully |
26 | * audited and tested to ensure that they don't cause a TLB miss while | 26 | * audited and tested to ensure that they don't cause a TLB miss while |
27 | * the SDRAM is inaccessible. Such a situation will crash the system | 27 | * the SDRAM is inaccessible. Such a situation will crash the system |
28 | * since it will cause the ARM MMU to attempt to walk the page tables. | 28 | * since it will cause the ARM MMU to attempt to walk the page tables. |
29 | * These crashes may be intermittent. | 29 | * These crashes may be intermittent. |
30 | */ | 30 | */ |
31 | #include <linux/linkage.h> | 31 | #include <linux/linkage.h> |
32 | #include <asm/assembler.h> | 32 | #include <asm/assembler.h> |
33 | #include <mach/io.h> | 33 | #include <mach/io.h> |
34 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
35 | 35 | ||
36 | #include "prm2xxx_3xxx.h" | 36 | #include "prm2xxx_3xxx.h" |
37 | #include "cm2xxx_3xxx.h" | 37 | #include "cm2xxx_3xxx.h" |
38 | #include "sdrc.h" | 38 | #include "sdrc.h" |
39 | 39 | ||
40 | .text | 40 | .text |
41 | 41 | ||
42 | .align 3 | ||
42 | ENTRY(omap242x_sram_ddr_init) | 43 | ENTRY(omap242x_sram_ddr_init) |
43 | stmfd sp!, {r0 - r12, lr} @ save registers on stack | 44 | stmfd sp!, {r0 - r12, lr} @ save registers on stack |
44 | 45 | ||
45 | mov r12, r2 @ capture CS1 vs CS0 | 46 | mov r12, r2 @ capture CS1 vs CS0 |
46 | mov r8, r3 @ capture force parameter | 47 | mov r8, r3 @ capture force parameter |
47 | 48 | ||
48 | /* frequency shift down */ | 49 | /* frequency shift down */ |
49 | ldr r2, omap242x_sdi_cm_clksel2_pll @ get address of dpllout reg | 50 | ldr r2, omap242x_sdi_cm_clksel2_pll @ get address of dpllout reg |
50 | mov r3, #0x1 @ value for 1x operation | 51 | mov r3, #0x1 @ value for 1x operation |
51 | str r3, [r2] @ go to L1-freq operation | 52 | str r3, [r2] @ go to L1-freq operation |
52 | 53 | ||
53 | /* voltage shift down */ | 54 | /* voltage shift down */ |
54 | mov r9, #0x1 @ set up for L1 voltage call | 55 | mov r9, #0x1 @ set up for L1 voltage call |
55 | bl voltage_shift @ go drop voltage | 56 | bl voltage_shift @ go drop voltage |
56 | 57 | ||
57 | /* dll lock mode */ | 58 | /* dll lock mode */ |
58 | ldr r11, omap242x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl | 59 | ldr r11, omap242x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl |
59 | ldr r10, [r11] @ get current val | 60 | ldr r10, [r11] @ get current val |
60 | cmp r12, #0x1 @ cs1 base (2422 es2.05/1) | 61 | cmp r12, #0x1 @ cs1 base (2422 es2.05/1) |
61 | addeq r11, r11, #0x8 @ if cs1 base, move to DLLB | 62 | addeq r11, r11, #0x8 @ if cs1 base, move to DLLB |
62 | mvn r9, #0x4 @ mask to get clear bit2 | 63 | mvn r9, #0x4 @ mask to get clear bit2 |
63 | and r10, r10, r9 @ clear bit2 for lock mode. | 64 | and r10, r10, r9 @ clear bit2 for lock mode. |
64 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) | 65 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) |
65 | orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz | 66 | orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz |
66 | str r10, [r11] @ commit to DLLA_CTRL | 67 | str r10, [r11] @ commit to DLLA_CTRL |
67 | bl i_dll_wait @ wait for dll to lock | 68 | bl i_dll_wait @ wait for dll to lock |
68 | 69 | ||
69 | /* get dll value */ | 70 | /* get dll value */ |
70 | add r11, r11, #0x4 @ get addr of status reg | 71 | add r11, r11, #0x4 @ get addr of status reg |
71 | ldr r10, [r11] @ get locked value | 72 | ldr r10, [r11] @ get locked value |
72 | 73 | ||
73 | /* voltage shift up */ | 74 | /* voltage shift up */ |
74 | mov r9, #0x0 @ shift back to L0-voltage | 75 | mov r9, #0x0 @ shift back to L0-voltage |
75 | bl voltage_shift @ go raise voltage | 76 | bl voltage_shift @ go raise voltage |
76 | 77 | ||
77 | /* frequency shift up */ | 78 | /* frequency shift up */ |
78 | mov r3, #0x2 @ value for 2x operation | 79 | mov r3, #0x2 @ value for 2x operation |
79 | str r3, [r2] @ go to L0-freq operation | 80 | str r3, [r2] @ go to L0-freq operation |
80 | 81 | ||
81 | /* reset entry mode for dllctrl */ | 82 | /* reset entry mode for dllctrl */ |
82 | sub r11, r11, #0x4 @ move from status to ctrl | 83 | sub r11, r11, #0x4 @ move from status to ctrl |
83 | cmp r12, #0x1 @ normalize if cs1 based | 84 | cmp r12, #0x1 @ normalize if cs1 based |
84 | subeq r11, r11, #0x8 @ possibly back to DLLA | 85 | subeq r11, r11, #0x8 @ possibly back to DLLA |
85 | cmp r8, #0x1 @ if forced unlock exit | 86 | cmp r8, #0x1 @ if forced unlock exit |
86 | orreq r1, r1, #0x4 @ make sure exit with unlocked value | 87 | orreq r1, r1, #0x4 @ make sure exit with unlocked value |
87 | str r1, [r11] @ restore DLLA_CTRL high value | 88 | str r1, [r11] @ restore DLLA_CTRL high value |
88 | add r11, r11, #0x8 @ move to DLLB_CTRL addr | 89 | add r11, r11, #0x8 @ move to DLLB_CTRL addr |
89 | str r1, [r11] @ set value DLLB_CTRL | 90 | str r1, [r11] @ set value DLLB_CTRL |
90 | bl i_dll_wait @ wait for possible lock | 91 | bl i_dll_wait @ wait for possible lock |
91 | 92 | ||
92 | /* set up for return, DDR should be good */ | 93 | /* set up for return, DDR should be good */ |
93 | str r10, [r0] @ write dll_status and return counter | 94 | str r10, [r0] @ write dll_status and return counter |
94 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return | 95 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return |
95 | 96 | ||
96 | /* ensure the DLL has relocked */ | 97 | /* ensure the DLL has relocked */ |
97 | i_dll_wait: | 98 | i_dll_wait: |
98 | mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks | 99 | mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks |
99 | i_dll_delay: | 100 | i_dll_delay: |
100 | subs r4, r4, #0x1 | 101 | subs r4, r4, #0x1 |
101 | bne i_dll_delay | 102 | bne i_dll_delay |
102 | mov pc, lr | 103 | mov pc, lr |
103 | 104 | ||
104 | /* | 105 | /* |
105 | * shift up or down voltage, use R9 as input to tell level. | 106 | * shift up or down voltage, use R9 as input to tell level. |
106 | * wait for it to finish, use 32k sync counter, 1tick=31uS. | 107 | * wait for it to finish, use 32k sync counter, 1tick=31uS. |
107 | */ | 108 | */ |
108 | voltage_shift: | 109 | voltage_shift: |
109 | ldr r4, omap242x_sdi_prcm_voltctrl @ get addr of volt ctrl. | 110 | ldr r4, omap242x_sdi_prcm_voltctrl @ get addr of volt ctrl. |
110 | ldr r5, [r4] @ get value. | 111 | ldr r5, [r4] @ get value. |
111 | ldr r6, prcm_mask_val @ get value of mask | 112 | ldr r6, prcm_mask_val @ get value of mask |
112 | and r5, r5, r6 @ apply mask to clear bits | 113 | and r5, r5, r6 @ apply mask to clear bits |
113 | orr r5, r5, r9 @ bulld value for L0/L1-volt operation. | 114 | orr r5, r5, r9 @ bulld value for L0/L1-volt operation. |
114 | str r5, [r4] @ set up for change. | 115 | str r5, [r4] @ set up for change. |
115 | mov r3, #0x4000 @ get val for force | 116 | mov r3, #0x4000 @ get val for force |
116 | orr r5, r5, r3 @ build value for force | 117 | orr r5, r5, r3 @ build value for force |
117 | str r5, [r4] @ Force transition to L1 | 118 | str r5, [r4] @ Force transition to L1 |
118 | 119 | ||
119 | ldr r3, omap242x_sdi_timer_32ksynct_cr @ get addr of counter | 120 | ldr r3, omap242x_sdi_timer_32ksynct_cr @ get addr of counter |
120 | ldr r5, [r3] @ get value | 121 | ldr r5, [r3] @ get value |
121 | add r5, r5, #0x3 @ give it at most 93uS | 122 | add r5, r5, #0x3 @ give it at most 93uS |
122 | volt_delay: | 123 | volt_delay: |
123 | ldr r7, [r3] @ get timer value | 124 | ldr r7, [r3] @ get timer value |
124 | cmp r5, r7 @ time up? | 125 | cmp r5, r7 @ time up? |
125 | bhi volt_delay @ not yet->branch | 126 | bhi volt_delay @ not yet->branch |
126 | mov pc, lr @ back to caller. | 127 | mov pc, lr @ back to caller. |
127 | 128 | ||
128 | omap242x_sdi_cm_clksel2_pll: | 129 | omap242x_sdi_cm_clksel2_pll: |
129 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) | 130 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) |
130 | omap242x_sdi_sdrc_dlla_ctrl: | 131 | omap242x_sdi_sdrc_dlla_ctrl: |
131 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) | 132 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) |
132 | omap242x_sdi_prcm_voltctrl: | 133 | omap242x_sdi_prcm_voltctrl: |
133 | .word OMAP2420_PRCM_VOLTCTRL | 134 | .word OMAP2420_PRCM_VOLTCTRL |
134 | prcm_mask_val: | 135 | prcm_mask_val: |
135 | .word 0xFFFF3FFC | 136 | .word 0xFFFF3FFC |
136 | omap242x_sdi_timer_32ksynct_cr: | 137 | omap242x_sdi_timer_32ksynct_cr: |
137 | .word OMAP2_L4_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) | 138 | .word OMAP2_L4_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) |
138 | ENTRY(omap242x_sram_ddr_init_sz) | 139 | ENTRY(omap242x_sram_ddr_init_sz) |
139 | .word . - omap242x_sram_ddr_init | 140 | .word . - omap242x_sram_ddr_init |
140 | 141 | ||
141 | /* | 142 | /* |
142 | * Reprograms memory timings. | 143 | * Reprograms memory timings. |
143 | * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] | 144 | * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] |
144 | * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 | 145 | * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 |
145 | */ | 146 | */ |
147 | .align 3 | ||
146 | ENTRY(omap242x_sram_reprogram_sdrc) | 148 | ENTRY(omap242x_sram_reprogram_sdrc) |
147 | stmfd sp!, {r0 - r10, lr} @ save registers on stack | 149 | stmfd sp!, {r0 - r10, lr} @ save registers on stack |
148 | mov r3, #0x0 @ clear for mrc call | 150 | mov r3, #0x0 @ clear for mrc call |
149 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR | 151 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR |
150 | nop | 152 | nop |
151 | nop | 153 | nop |
152 | ldr r6, omap242x_srs_sdrc_rfr_ctrl @ get addr of refresh reg | 154 | ldr r6, omap242x_srs_sdrc_rfr_ctrl @ get addr of refresh reg |
153 | ldr r5, [r6] @ get value | 155 | ldr r5, [r6] @ get value |
154 | mov r5, r5, lsr #8 @ isolate rfr field and drop burst | 156 | mov r5, r5, lsr #8 @ isolate rfr field and drop burst |
155 | 157 | ||
156 | cmp r0, #0x1 @ going to half speed? | 158 | cmp r0, #0x1 @ going to half speed? |
157 | movne r9, #0x0 @ if up set flag up for pre up, hi volt | 159 | movne r9, #0x0 @ if up set flag up for pre up, hi volt |
158 | 160 | ||
159 | blne voltage_shift_c @ adjust voltage | 161 | blne voltage_shift_c @ adjust voltage |
160 | 162 | ||
161 | cmp r0, #0x1 @ going to half speed (post branch link) | 163 | cmp r0, #0x1 @ going to half speed (post branch link) |
162 | moveq r5, r5, lsr #1 @ divide by 2 if to half | 164 | moveq r5, r5, lsr #1 @ divide by 2 if to half |
163 | movne r5, r5, lsl #1 @ mult by 2 if to full | 165 | movne r5, r5, lsl #1 @ mult by 2 if to full |
164 | mov r5, r5, lsl #8 @ put rfr field back into place | 166 | mov r5, r5, lsl #8 @ put rfr field back into place |
165 | add r5, r5, #0x1 @ turn on burst of 1 | 167 | add r5, r5, #0x1 @ turn on burst of 1 |
166 | ldr r4, omap242x_srs_cm_clksel2_pll @ get address of out reg | 168 | ldr r4, omap242x_srs_cm_clksel2_pll @ get address of out reg |
167 | ldr r3, [r4] @ get curr value | 169 | ldr r3, [r4] @ get curr value |
168 | orr r3, r3, #0x3 | 170 | orr r3, r3, #0x3 |
169 | bic r3, r3, #0x3 @ clear lower bits | 171 | bic r3, r3, #0x3 @ clear lower bits |
170 | orr r3, r3, r0 @ new state value | 172 | orr r3, r3, r0 @ new state value |
171 | str r3, [r4] @ set new state (pll/x, x=1 or 2) | 173 | str r3, [r4] @ set new state (pll/x, x=1 or 2) |
172 | nop | 174 | nop |
173 | nop | 175 | nop |
174 | 176 | ||
175 | moveq r9, #0x1 @ if speed down, post down, drop volt | 177 | moveq r9, #0x1 @ if speed down, post down, drop volt |
176 | bleq voltage_shift_c | 178 | bleq voltage_shift_c |
177 | 179 | ||
178 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier | 180 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier |
179 | str r5, [r6] @ set new RFR_1 value | 181 | str r5, [r6] @ set new RFR_1 value |
180 | add r6, r6, #0x30 @ get RFR_2 addr | 182 | add r6, r6, #0x30 @ get RFR_2 addr |
181 | str r5, [r6] @ set RFR_2 | 183 | str r5, [r6] @ set RFR_2 |
182 | nop | 184 | nop |
183 | cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL | 185 | cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL |
184 | bne freq_out @ leave if SDR, no DLL function | 186 | bne freq_out @ leave if SDR, no DLL function |
185 | 187 | ||
186 | /* With DDR, we need to take care of the DLL for the frequency change */ | 188 | /* With DDR, we need to take care of the DLL for the frequency change */ |
187 | ldr r2, omap242x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl | 189 | ldr r2, omap242x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl |
188 | str r1, [r2] @ write out new SDRC_DLLA_CTRL | 190 | str r1, [r2] @ write out new SDRC_DLLA_CTRL |
189 | add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL | 191 | add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL |
190 | str r1, [r2] @ commit to SDRC_DLLB_CTRL | 192 | str r1, [r2] @ commit to SDRC_DLLB_CTRL |
191 | mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks | 193 | mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks |
192 | dll_wait: | 194 | dll_wait: |
193 | subs r1, r1, #0x1 | 195 | subs r1, r1, #0x1 |
194 | bne dll_wait | 196 | bne dll_wait |
195 | freq_out: | 197 | freq_out: |
196 | ldmfd sp!, {r0 - r10, pc} @ restore regs and return | 198 | ldmfd sp!, {r0 - r10, pc} @ restore regs and return |
197 | 199 | ||
198 | /* | 200 | /* |
199 | * shift up or down voltage, use R9 as input to tell level. | 201 | * shift up or down voltage, use R9 as input to tell level. |
200 | * wait for it to finish, use 32k sync counter, 1tick=31uS. | 202 | * wait for it to finish, use 32k sync counter, 1tick=31uS. |
201 | */ | 203 | */ |
202 | voltage_shift_c: | 204 | voltage_shift_c: |
203 | ldr r10, omap242x_srs_prcm_voltctrl @ get addr of volt ctrl | 205 | ldr r10, omap242x_srs_prcm_voltctrl @ get addr of volt ctrl |
204 | ldr r8, [r10] @ get value | 206 | ldr r8, [r10] @ get value |
205 | ldr r7, ddr_prcm_mask_val @ get value of mask | 207 | ldr r7, ddr_prcm_mask_val @ get value of mask |
206 | and r8, r8, r7 @ apply mask to clear bits | 208 | and r8, r8, r7 @ apply mask to clear bits |
207 | orr r8, r8, r9 @ bulld value for L0/L1-volt operation. | 209 | orr r8, r8, r9 @ bulld value for L0/L1-volt operation. |
208 | str r8, [r10] @ set up for change. | 210 | str r8, [r10] @ set up for change. |
209 | mov r7, #0x4000 @ get val for force | 211 | mov r7, #0x4000 @ get val for force |
210 | orr r8, r8, r7 @ build value for force | 212 | orr r8, r8, r7 @ build value for force |
211 | str r8, [r10] @ Force transition to L1 | 213 | str r8, [r10] @ Force transition to L1 |
212 | 214 | ||
213 | ldr r10, omap242x_srs_timer_32ksynct @ get addr of counter | 215 | ldr r10, omap242x_srs_timer_32ksynct @ get addr of counter |
214 | ldr r8, [r10] @ get value | 216 | ldr r8, [r10] @ get value |
215 | add r8, r8, #0x2 @ give it at most 62uS (min 31+) | 217 | add r8, r8, #0x2 @ give it at most 62uS (min 31+) |
216 | volt_delay_c: | 218 | volt_delay_c: |
217 | ldr r7, [r10] @ get timer value | 219 | ldr r7, [r10] @ get timer value |
218 | cmp r8, r7 @ time up? | 220 | cmp r8, r7 @ time up? |
219 | bhi volt_delay_c @ not yet->branch | 221 | bhi volt_delay_c @ not yet->branch |
220 | mov pc, lr @ back to caller | 222 | mov pc, lr @ back to caller |
221 | 223 | ||
222 | omap242x_srs_cm_clksel2_pll: | 224 | omap242x_srs_cm_clksel2_pll: |
223 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) | 225 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL2) |
224 | omap242x_srs_sdrc_dlla_ctrl: | 226 | omap242x_srs_sdrc_dlla_ctrl: |
225 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) | 227 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) |
226 | omap242x_srs_sdrc_rfr_ctrl: | 228 | omap242x_srs_sdrc_rfr_ctrl: |
227 | .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) | 229 | .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) |
228 | omap242x_srs_prcm_voltctrl: | 230 | omap242x_srs_prcm_voltctrl: |
229 | .word OMAP2420_PRCM_VOLTCTRL | 231 | .word OMAP2420_PRCM_VOLTCTRL |
230 | ddr_prcm_mask_val: | 232 | ddr_prcm_mask_val: |
231 | .word 0xFFFF3FFC | 233 | .word 0xFFFF3FFC |
232 | omap242x_srs_timer_32ksynct: | 234 | omap242x_srs_timer_32ksynct: |
233 | .word OMAP2_L4_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) | 235 | .word OMAP2_L4_IO_ADDRESS(OMAP2420_32KSYNCT_BASE + 0x010) |
234 | 236 | ||
235 | ENTRY(omap242x_sram_reprogram_sdrc_sz) | 237 | ENTRY(omap242x_sram_reprogram_sdrc_sz) |
236 | .word . - omap242x_sram_reprogram_sdrc | 238 | .word . - omap242x_sram_reprogram_sdrc |
237 | 239 | ||
238 | /* | 240 | /* |
239 | * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. | 241 | * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. |
240 | */ | 242 | */ |
243 | .align 3 | ||
241 | ENTRY(omap242x_sram_set_prcm) | 244 | ENTRY(omap242x_sram_set_prcm) |
242 | stmfd sp!, {r0-r12, lr} @ regs to stack | 245 | stmfd sp!, {r0-r12, lr} @ regs to stack |
243 | adr r4, pbegin @ addr of preload start | 246 | adr r4, pbegin @ addr of preload start |
244 | adr r8, pend @ addr of preload end | 247 | adr r8, pend @ addr of preload end |
245 | mcrr p15, 1, r8, r4, c12 @ preload into icache | 248 | mcrr p15, 1, r8, r4, c12 @ preload into icache |
246 | pbegin: | 249 | pbegin: |
247 | /* move into fast relock bypass */ | 250 | /* move into fast relock bypass */ |
248 | ldr r8, omap242x_ssp_pll_ctl @ get addr | 251 | ldr r8, omap242x_ssp_pll_ctl @ get addr |
249 | ldr r5, [r8] @ get val | 252 | ldr r5, [r8] @ get val |
250 | mvn r6, #0x3 @ clear mask | 253 | mvn r6, #0x3 @ clear mask |
251 | and r5, r5, r6 @ clear field | 254 | and r5, r5, r6 @ clear field |
252 | orr r7, r5, #0x2 @ fast relock val | 255 | orr r7, r5, #0x2 @ fast relock val |
253 | str r7, [r8] @ go to fast relock | 256 | str r7, [r8] @ go to fast relock |
254 | ldr r4, omap242x_ssp_pll_stat @ addr of stat | 257 | ldr r4, omap242x_ssp_pll_stat @ addr of stat |
255 | block: | 258 | block: |
256 | /* wait for bypass */ | 259 | /* wait for bypass */ |
257 | ldr r8, [r4] @ stat value | 260 | ldr r8, [r4] @ stat value |
258 | and r8, r8, #0x3 @ mask for stat | 261 | and r8, r8, #0x3 @ mask for stat |
259 | cmp r8, #0x1 @ there yet | 262 | cmp r8, #0x1 @ there yet |
260 | bne block @ loop if not | 263 | bne block @ loop if not |
261 | 264 | ||
262 | /* set new dpll dividers _after_ in bypass */ | 265 | /* set new dpll dividers _after_ in bypass */ |
263 | ldr r4, omap242x_ssp_pll_div @ get addr | 266 | ldr r4, omap242x_ssp_pll_div @ get addr |
264 | str r0, [r4] @ set dpll ctrl val | 267 | str r0, [r4] @ set dpll ctrl val |
265 | 268 | ||
266 | ldr r4, omap242x_ssp_set_config @ get addr | 269 | ldr r4, omap242x_ssp_set_config @ get addr |
267 | mov r8, #1 @ valid cfg msk | 270 | mov r8, #1 @ valid cfg msk |
268 | str r8, [r4] @ make dividers take | 271 | str r8, [r4] @ make dividers take |
269 | 272 | ||
270 | mov r4, #100 @ dead spin a bit | 273 | mov r4, #100 @ dead spin a bit |
271 | wait_a_bit: | 274 | wait_a_bit: |
272 | subs r4, r4, #1 @ dec loop | 275 | subs r4, r4, #1 @ dec loop |
273 | bne wait_a_bit @ delay done? | 276 | bne wait_a_bit @ delay done? |
274 | 277 | ||
275 | /* check if staying in bypass */ | 278 | /* check if staying in bypass */ |
276 | cmp r2, #0x1 @ stay in bypass? | 279 | cmp r2, #0x1 @ stay in bypass? |
277 | beq pend @ jump over dpll relock | 280 | beq pend @ jump over dpll relock |
278 | 281 | ||
279 | /* relock DPLL with new vals */ | 282 | /* relock DPLL with new vals */ |
280 | ldr r5, omap242x_ssp_pll_stat @ get addr | 283 | ldr r5, omap242x_ssp_pll_stat @ get addr |
281 | ldr r4, omap242x_ssp_pll_ctl @ get addr | 284 | ldr r4, omap242x_ssp_pll_ctl @ get addr |
282 | orr r8, r7, #0x3 @ val for lock dpll | 285 | orr r8, r7, #0x3 @ val for lock dpll |
283 | str r8, [r4] @ set val | 286 | str r8, [r4] @ set val |
284 | mov r0, #1000 @ dead spin a bit | 287 | mov r0, #1000 @ dead spin a bit |
285 | wait_more: | 288 | wait_more: |
286 | subs r0, r0, #1 @ dec loop | 289 | subs r0, r0, #1 @ dec loop |
287 | bne wait_more @ delay done? | 290 | bne wait_more @ delay done? |
288 | wait_lock: | 291 | wait_lock: |
289 | ldr r8, [r5] @ get lock val | 292 | ldr r8, [r5] @ get lock val |
290 | and r8, r8, #3 @ isolate field | 293 | and r8, r8, #3 @ isolate field |
291 | cmp r8, #2 @ locked? | 294 | cmp r8, #2 @ locked? |
292 | bne wait_lock @ wait if not | 295 | bne wait_lock @ wait if not |
293 | pend: | 296 | pend: |
294 | /* update memory timings & briefly lock dll */ | 297 | /* update memory timings & briefly lock dll */ |
295 | ldr r4, omap242x_ssp_sdrc_rfr @ get addr | 298 | ldr r4, omap242x_ssp_sdrc_rfr @ get addr |
296 | str r1, [r4] @ update refresh timing | 299 | str r1, [r4] @ update refresh timing |
297 | ldr r11, omap242x_ssp_dlla_ctrl @ get addr of DLLA ctrl | 300 | ldr r11, omap242x_ssp_dlla_ctrl @ get addr of DLLA ctrl |
298 | ldr r10, [r11] @ get current val | 301 | ldr r10, [r11] @ get current val |
299 | mvn r9, #0x4 @ mask to get clear bit2 | 302 | mvn r9, #0x4 @ mask to get clear bit2 |
300 | and r10, r10, r9 @ clear bit2 for lock mode | 303 | and r10, r10, r9 @ clear bit2 for lock mode |
301 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) | 304 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) |
302 | str r10, [r11] @ commit to DLLA_CTRL | 305 | str r10, [r11] @ commit to DLLA_CTRL |
303 | add r11, r11, #0x8 @ move to dllb | 306 | add r11, r11, #0x8 @ move to dllb |
304 | str r10, [r11] @ hit DLLB also | 307 | str r10, [r11] @ hit DLLB also |
305 | 308 | ||
306 | mov r4, #0x800 @ relock time (min 0x400 L3 clocks) | 309 | mov r4, #0x800 @ relock time (min 0x400 L3 clocks) |
307 | wait_dll_lock: | 310 | wait_dll_lock: |
308 | subs r4, r4, #0x1 | 311 | subs r4, r4, #0x1 |
309 | bne wait_dll_lock | 312 | bne wait_dll_lock |
310 | nop | 313 | nop |
311 | ldmfd sp!, {r0-r12, pc} @ restore regs and return | 314 | ldmfd sp!, {r0-r12, pc} @ restore regs and return |
312 | 315 | ||
313 | omap242x_ssp_set_config: | 316 | omap242x_ssp_set_config: |
314 | .word OMAP2420_PRCM_CLKCFG_CTRL | 317 | .word OMAP2420_PRCM_CLKCFG_CTRL |
315 | omap242x_ssp_pll_ctl: | 318 | omap242x_ssp_pll_ctl: |
316 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKEN) | 319 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKEN) |
317 | omap242x_ssp_pll_stat: | 320 | omap242x_ssp_pll_stat: |
318 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST) | 321 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_IDLEST) |
319 | omap242x_ssp_pll_div: | 322 | omap242x_ssp_pll_div: |
320 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL1) | 323 | .word OMAP2420_CM_REGADDR(PLL_MOD, CM_CLKSEL1) |
321 | omap242x_ssp_sdrc_rfr: | 324 | omap242x_ssp_sdrc_rfr: |
322 | .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) | 325 | .word OMAP242X_SDRC_REGADDR(SDRC_RFR_CTRL_0) |
323 | omap242x_ssp_dlla_ctrl: | 326 | omap242x_ssp_dlla_ctrl: |
324 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) | 327 | .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL) |
325 | 328 | ||
326 | ENTRY(omap242x_sram_set_prcm_sz) | 329 | ENTRY(omap242x_sram_set_prcm_sz) |
327 | .word . - omap242x_sram_set_prcm | 330 | .word . - omap242x_sram_set_prcm |
328 | 331 |
arch/arm/mach-omap2/sram243x.S
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-omap2/sram243x.S | 2 | * linux/arch/arm/mach-omap2/sram243x.S |
3 | * | 3 | * |
4 | * Omap2 specific functions that need to be run in internal SRAM | 4 | * Omap2 specific functions that need to be run in internal SRAM |
5 | * | 5 | * |
6 | * (C) Copyright 2004 | 6 | * (C) Copyright 2004 |
7 | * Texas Instruments, <www.ti.com> | 7 | * Texas Instruments, <www.ti.com> |
8 | * Richard Woodruff <r-woodruff2@ti.com> | 8 | * Richard Woodruff <r-woodruff2@ti.com> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or | 10 | * This program is free software; you can redistribute it and/or |
11 | * modify it under the terms of the GNU General Public License as | 11 | * modify it under the terms of the GNU General Public License as |
12 | * published by the Free Software Foundation; either version 2 of | 12 | * published by the Free Software Foundation; either version 2 of |
13 | * the License, or (at your option) any later version. | 13 | * the License, or (at your option) any later version. |
14 | * | 14 | * |
15 | * This program is distributed in the hope that it will be useful, | 15 | * This program is distributed in the hope that it will be useful, |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the | 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the |
18 | * GNU General Public License for more details. | 18 | * GNU General Public License for more details. |
19 | * | 19 | * |
20 | * You should have received a copy of the GNU General Public License | 20 | * You should have received a copy of the GNU General Public License |
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
23 | * MA 02111-1307 USA | 23 | * MA 02111-1307 USA |
24 | * | 24 | * |
25 | * Richard Woodruff notes that any changes to this code must be carefully | 25 | * Richard Woodruff notes that any changes to this code must be carefully |
26 | * audited and tested to ensure that they don't cause a TLB miss while | 26 | * audited and tested to ensure that they don't cause a TLB miss while |
27 | * the SDRAM is inaccessible. Such a situation will crash the system | 27 | * the SDRAM is inaccessible. Such a situation will crash the system |
28 | * since it will cause the ARM MMU to attempt to walk the page tables. | 28 | * since it will cause the ARM MMU to attempt to walk the page tables. |
29 | * These crashes may be intermittent. | 29 | * These crashes may be intermittent. |
30 | */ | 30 | */ |
31 | #include <linux/linkage.h> | 31 | #include <linux/linkage.h> |
32 | #include <asm/assembler.h> | 32 | #include <asm/assembler.h> |
33 | #include <mach/io.h> | 33 | #include <mach/io.h> |
34 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
35 | 35 | ||
36 | #include "prm2xxx_3xxx.h" | 36 | #include "prm2xxx_3xxx.h" |
37 | #include "cm2xxx_3xxx.h" | 37 | #include "cm2xxx_3xxx.h" |
38 | #include "sdrc.h" | 38 | #include "sdrc.h" |
39 | 39 | ||
40 | .text | 40 | .text |
41 | 41 | ||
42 | .align 3 | ||
42 | ENTRY(omap243x_sram_ddr_init) | 43 | ENTRY(omap243x_sram_ddr_init) |
43 | stmfd sp!, {r0 - r12, lr} @ save registers on stack | 44 | stmfd sp!, {r0 - r12, lr} @ save registers on stack |
44 | 45 | ||
45 | mov r12, r2 @ capture CS1 vs CS0 | 46 | mov r12, r2 @ capture CS1 vs CS0 |
46 | mov r8, r3 @ capture force parameter | 47 | mov r8, r3 @ capture force parameter |
47 | 48 | ||
48 | /* frequency shift down */ | 49 | /* frequency shift down */ |
49 | ldr r2, omap243x_sdi_cm_clksel2_pll @ get address of dpllout reg | 50 | ldr r2, omap243x_sdi_cm_clksel2_pll @ get address of dpllout reg |
50 | mov r3, #0x1 @ value for 1x operation | 51 | mov r3, #0x1 @ value for 1x operation |
51 | str r3, [r2] @ go to L1-freq operation | 52 | str r3, [r2] @ go to L1-freq operation |
52 | 53 | ||
53 | /* voltage shift down */ | 54 | /* voltage shift down */ |
54 | mov r9, #0x1 @ set up for L1 voltage call | 55 | mov r9, #0x1 @ set up for L1 voltage call |
55 | bl voltage_shift @ go drop voltage | 56 | bl voltage_shift @ go drop voltage |
56 | 57 | ||
57 | /* dll lock mode */ | 58 | /* dll lock mode */ |
58 | ldr r11, omap243x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl | 59 | ldr r11, omap243x_sdi_sdrc_dlla_ctrl @ addr of dlla ctrl |
59 | ldr r10, [r11] @ get current val | 60 | ldr r10, [r11] @ get current val |
60 | cmp r12, #0x1 @ cs1 base (2422 es2.05/1) | 61 | cmp r12, #0x1 @ cs1 base (2422 es2.05/1) |
61 | addeq r11, r11, #0x8 @ if cs1 base, move to DLLB | 62 | addeq r11, r11, #0x8 @ if cs1 base, move to DLLB |
62 | mvn r9, #0x4 @ mask to get clear bit2 | 63 | mvn r9, #0x4 @ mask to get clear bit2 |
63 | and r10, r10, r9 @ clear bit2 for lock mode. | 64 | and r10, r10, r9 @ clear bit2 for lock mode. |
64 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) | 65 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) |
65 | orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz | 66 | orr r10, r10, #0x2 @ 90 degree phase for all below 133Mhz |
66 | str r10, [r11] @ commit to DLLA_CTRL | 67 | str r10, [r11] @ commit to DLLA_CTRL |
67 | bl i_dll_wait @ wait for dll to lock | 68 | bl i_dll_wait @ wait for dll to lock |
68 | 69 | ||
69 | /* get dll value */ | 70 | /* get dll value */ |
70 | add r11, r11, #0x4 @ get addr of status reg | 71 | add r11, r11, #0x4 @ get addr of status reg |
71 | ldr r10, [r11] @ get locked value | 72 | ldr r10, [r11] @ get locked value |
72 | 73 | ||
73 | /* voltage shift up */ | 74 | /* voltage shift up */ |
74 | mov r9, #0x0 @ shift back to L0-voltage | 75 | mov r9, #0x0 @ shift back to L0-voltage |
75 | bl voltage_shift @ go raise voltage | 76 | bl voltage_shift @ go raise voltage |
76 | 77 | ||
77 | /* frequency shift up */ | 78 | /* frequency shift up */ |
78 | mov r3, #0x2 @ value for 2x operation | 79 | mov r3, #0x2 @ value for 2x operation |
79 | str r3, [r2] @ go to L0-freq operation | 80 | str r3, [r2] @ go to L0-freq operation |
80 | 81 | ||
81 | /* reset entry mode for dllctrl */ | 82 | /* reset entry mode for dllctrl */ |
82 | sub r11, r11, #0x4 @ move from status to ctrl | 83 | sub r11, r11, #0x4 @ move from status to ctrl |
83 | cmp r12, #0x1 @ normalize if cs1 based | 84 | cmp r12, #0x1 @ normalize if cs1 based |
84 | subeq r11, r11, #0x8 @ possibly back to DLLA | 85 | subeq r11, r11, #0x8 @ possibly back to DLLA |
85 | cmp r8, #0x1 @ if forced unlock exit | 86 | cmp r8, #0x1 @ if forced unlock exit |
86 | orreq r1, r1, #0x4 @ make sure exit with unlocked value | 87 | orreq r1, r1, #0x4 @ make sure exit with unlocked value |
87 | str r1, [r11] @ restore DLLA_CTRL high value | 88 | str r1, [r11] @ restore DLLA_CTRL high value |
88 | add r11, r11, #0x8 @ move to DLLB_CTRL addr | 89 | add r11, r11, #0x8 @ move to DLLB_CTRL addr |
89 | str r1, [r11] @ set value DLLB_CTRL | 90 | str r1, [r11] @ set value DLLB_CTRL |
90 | bl i_dll_wait @ wait for possible lock | 91 | bl i_dll_wait @ wait for possible lock |
91 | 92 | ||
92 | /* set up for return, DDR should be good */ | 93 | /* set up for return, DDR should be good */ |
93 | str r10, [r0] @ write dll_status and return counter | 94 | str r10, [r0] @ write dll_status and return counter |
94 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return | 95 | ldmfd sp!, {r0 - r12, pc} @ restore regs and return |
95 | 96 | ||
96 | /* ensure the DLL has relocked */ | 97 | /* ensure the DLL has relocked */ |
97 | i_dll_wait: | 98 | i_dll_wait: |
98 | mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks | 99 | mov r4, #0x800 @ delay DLL relock, min 0x400 L3 clocks |
99 | i_dll_delay: | 100 | i_dll_delay: |
100 | subs r4, r4, #0x1 | 101 | subs r4, r4, #0x1 |
101 | bne i_dll_delay | 102 | bne i_dll_delay |
102 | mov pc, lr | 103 | mov pc, lr |
103 | 104 | ||
104 | /* | 105 | /* |
105 | * shift up or down voltage, use R9 as input to tell level. | 106 | * shift up or down voltage, use R9 as input to tell level. |
106 | * wait for it to finish, use 32k sync counter, 1tick=31uS. | 107 | * wait for it to finish, use 32k sync counter, 1tick=31uS. |
107 | */ | 108 | */ |
108 | voltage_shift: | 109 | voltage_shift: |
109 | ldr r4, omap243x_sdi_prcm_voltctrl @ get addr of volt ctrl. | 110 | ldr r4, omap243x_sdi_prcm_voltctrl @ get addr of volt ctrl. |
110 | ldr r5, [r4] @ get value. | 111 | ldr r5, [r4] @ get value. |
111 | ldr r6, prcm_mask_val @ get value of mask | 112 | ldr r6, prcm_mask_val @ get value of mask |
112 | and r5, r5, r6 @ apply mask to clear bits | 113 | and r5, r5, r6 @ apply mask to clear bits |
113 | orr r5, r5, r9 @ bulld value for L0/L1-volt operation. | 114 | orr r5, r5, r9 @ bulld value for L0/L1-volt operation. |
114 | str r5, [r4] @ set up for change. | 115 | str r5, [r4] @ set up for change. |
115 | mov r3, #0x4000 @ get val for force | 116 | mov r3, #0x4000 @ get val for force |
116 | orr r5, r5, r3 @ build value for force | 117 | orr r5, r5, r3 @ build value for force |
117 | str r5, [r4] @ Force transition to L1 | 118 | str r5, [r4] @ Force transition to L1 |
118 | 119 | ||
119 | ldr r3, omap243x_sdi_timer_32ksynct_cr @ get addr of counter | 120 | ldr r3, omap243x_sdi_timer_32ksynct_cr @ get addr of counter |
120 | ldr r5, [r3] @ get value | 121 | ldr r5, [r3] @ get value |
121 | add r5, r5, #0x3 @ give it at most 93uS | 122 | add r5, r5, #0x3 @ give it at most 93uS |
122 | volt_delay: | 123 | volt_delay: |
123 | ldr r7, [r3] @ get timer value | 124 | ldr r7, [r3] @ get timer value |
124 | cmp r5, r7 @ time up? | 125 | cmp r5, r7 @ time up? |
125 | bhi volt_delay @ not yet->branch | 126 | bhi volt_delay @ not yet->branch |
126 | mov pc, lr @ back to caller. | 127 | mov pc, lr @ back to caller. |
127 | 128 | ||
128 | omap243x_sdi_cm_clksel2_pll: | 129 | omap243x_sdi_cm_clksel2_pll: |
129 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2) | 130 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2) |
130 | omap243x_sdi_sdrc_dlla_ctrl: | 131 | omap243x_sdi_sdrc_dlla_ctrl: |
131 | .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) | 132 | .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) |
132 | omap243x_sdi_prcm_voltctrl: | 133 | omap243x_sdi_prcm_voltctrl: |
133 | .word OMAP2430_PRCM_VOLTCTRL | 134 | .word OMAP2430_PRCM_VOLTCTRL |
134 | prcm_mask_val: | 135 | prcm_mask_val: |
135 | .word 0xFFFF3FFC | 136 | .word 0xFFFF3FFC |
136 | omap243x_sdi_timer_32ksynct_cr: | 137 | omap243x_sdi_timer_32ksynct_cr: |
137 | .word OMAP2_L4_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010) | 138 | .word OMAP2_L4_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010) |
138 | ENTRY(omap243x_sram_ddr_init_sz) | 139 | ENTRY(omap243x_sram_ddr_init_sz) |
139 | .word . - omap243x_sram_ddr_init | 140 | .word . - omap243x_sram_ddr_init |
140 | 141 | ||
141 | /* | 142 | /* |
142 | * Reprograms memory timings. | 143 | * Reprograms memory timings. |
143 | * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] | 144 | * r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR] |
144 | * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 | 145 | * PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0 |
145 | */ | 146 | */ |
147 | .align 3 | ||
146 | ENTRY(omap243x_sram_reprogram_sdrc) | 148 | ENTRY(omap243x_sram_reprogram_sdrc) |
147 | stmfd sp!, {r0 - r10, lr} @ save registers on stack | 149 | stmfd sp!, {r0 - r10, lr} @ save registers on stack |
148 | mov r3, #0x0 @ clear for mrc call | 150 | mov r3, #0x0 @ clear for mrc call |
149 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR | 151 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier, finish ARM SDR/DDR |
150 | nop | 152 | nop |
151 | nop | 153 | nop |
152 | ldr r6, omap243x_srs_sdrc_rfr_ctrl @ get addr of refresh reg | 154 | ldr r6, omap243x_srs_sdrc_rfr_ctrl @ get addr of refresh reg |
153 | ldr r5, [r6] @ get value | 155 | ldr r5, [r6] @ get value |
154 | mov r5, r5, lsr #8 @ isolate rfr field and drop burst | 156 | mov r5, r5, lsr #8 @ isolate rfr field and drop burst |
155 | 157 | ||
156 | cmp r0, #0x1 @ going to half speed? | 158 | cmp r0, #0x1 @ going to half speed? |
157 | movne r9, #0x0 @ if up set flag up for pre up, hi volt | 159 | movne r9, #0x0 @ if up set flag up for pre up, hi volt |
158 | 160 | ||
159 | blne voltage_shift_c @ adjust voltage | 161 | blne voltage_shift_c @ adjust voltage |
160 | 162 | ||
161 | cmp r0, #0x1 @ going to half speed (post branch link) | 163 | cmp r0, #0x1 @ going to half speed (post branch link) |
162 | moveq r5, r5, lsr #1 @ divide by 2 if to half | 164 | moveq r5, r5, lsr #1 @ divide by 2 if to half |
163 | movne r5, r5, lsl #1 @ mult by 2 if to full | 165 | movne r5, r5, lsl #1 @ mult by 2 if to full |
164 | mov r5, r5, lsl #8 @ put rfr field back into place | 166 | mov r5, r5, lsl #8 @ put rfr field back into place |
165 | add r5, r5, #0x1 @ turn on burst of 1 | 167 | add r5, r5, #0x1 @ turn on burst of 1 |
166 | ldr r4, omap243x_srs_cm_clksel2_pll @ get address of out reg | 168 | ldr r4, omap243x_srs_cm_clksel2_pll @ get address of out reg |
167 | ldr r3, [r4] @ get curr value | 169 | ldr r3, [r4] @ get curr value |
168 | orr r3, r3, #0x3 | 170 | orr r3, r3, #0x3 |
169 | bic r3, r3, #0x3 @ clear lower bits | 171 | bic r3, r3, #0x3 @ clear lower bits |
170 | orr r3, r3, r0 @ new state value | 172 | orr r3, r3, r0 @ new state value |
171 | str r3, [r4] @ set new state (pll/x, x=1 or 2) | 173 | str r3, [r4] @ set new state (pll/x, x=1 or 2) |
172 | nop | 174 | nop |
173 | nop | 175 | nop |
174 | 176 | ||
175 | moveq r9, #0x1 @ if speed down, post down, drop volt | 177 | moveq r9, #0x1 @ if speed down, post down, drop volt |
176 | bleq voltage_shift_c | 178 | bleq voltage_shift_c |
177 | 179 | ||
178 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier | 180 | mcr p15, 0, r3, c7, c10, 4 @ memory barrier |
179 | str r5, [r6] @ set new RFR_1 value | 181 | str r5, [r6] @ set new RFR_1 value |
180 | add r6, r6, #0x30 @ get RFR_2 addr | 182 | add r6, r6, #0x30 @ get RFR_2 addr |
181 | str r5, [r6] @ set RFR_2 | 183 | str r5, [r6] @ set RFR_2 |
182 | nop | 184 | nop |
183 | cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL | 185 | cmp r2, #0x1 @ (SDR or DDR) do we need to adjust DLL |
184 | bne freq_out @ leave if SDR, no DLL function | 186 | bne freq_out @ leave if SDR, no DLL function |
185 | 187 | ||
186 | /* With DDR, we need to take care of the DLL for the frequency change */ | 188 | /* With DDR, we need to take care of the DLL for the frequency change */ |
187 | ldr r2, omap243x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl | 189 | ldr r2, omap243x_srs_sdrc_dlla_ctrl @ addr of dlla ctrl |
188 | str r1, [r2] @ write out new SDRC_DLLA_CTRL | 190 | str r1, [r2] @ write out new SDRC_DLLA_CTRL |
189 | add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL | 191 | add r2, r2, #0x8 @ addr to SDRC_DLLB_CTRL |
190 | str r1, [r2] @ commit to SDRC_DLLB_CTRL | 192 | str r1, [r2] @ commit to SDRC_DLLB_CTRL |
191 | mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks | 193 | mov r1, #0x2000 @ wait DLL relock, min 0x400 L3 clocks |
192 | dll_wait: | 194 | dll_wait: |
193 | subs r1, r1, #0x1 | 195 | subs r1, r1, #0x1 |
194 | bne dll_wait | 196 | bne dll_wait |
195 | freq_out: | 197 | freq_out: |
196 | ldmfd sp!, {r0 - r10, pc} @ restore regs and return | 198 | ldmfd sp!, {r0 - r10, pc} @ restore regs and return |
197 | 199 | ||
198 | /* | 200 | /* |
199 | * shift up or down voltage, use R9 as input to tell level. | 201 | * shift up or down voltage, use R9 as input to tell level. |
200 | * wait for it to finish, use 32k sync counter, 1tick=31uS. | 202 | * wait for it to finish, use 32k sync counter, 1tick=31uS. |
201 | */ | 203 | */ |
202 | voltage_shift_c: | 204 | voltage_shift_c: |
203 | ldr r10, omap243x_srs_prcm_voltctrl @ get addr of volt ctrl | 205 | ldr r10, omap243x_srs_prcm_voltctrl @ get addr of volt ctrl |
204 | ldr r8, [r10] @ get value | 206 | ldr r8, [r10] @ get value |
205 | ldr r7, ddr_prcm_mask_val @ get value of mask | 207 | ldr r7, ddr_prcm_mask_val @ get value of mask |
206 | and r8, r8, r7 @ apply mask to clear bits | 208 | and r8, r8, r7 @ apply mask to clear bits |
207 | orr r8, r8, r9 @ bulld value for L0/L1-volt operation. | 209 | orr r8, r8, r9 @ bulld value for L0/L1-volt operation. |
208 | str r8, [r10] @ set up for change. | 210 | str r8, [r10] @ set up for change. |
209 | mov r7, #0x4000 @ get val for force | 211 | mov r7, #0x4000 @ get val for force |
210 | orr r8, r8, r7 @ build value for force | 212 | orr r8, r8, r7 @ build value for force |
211 | str r8, [r10] @ Force transition to L1 | 213 | str r8, [r10] @ Force transition to L1 |
212 | 214 | ||
213 | ldr r10, omap243x_srs_timer_32ksynct @ get addr of counter | 215 | ldr r10, omap243x_srs_timer_32ksynct @ get addr of counter |
214 | ldr r8, [r10] @ get value | 216 | ldr r8, [r10] @ get value |
215 | add r8, r8, #0x2 @ give it at most 62uS (min 31+) | 217 | add r8, r8, #0x2 @ give it at most 62uS (min 31+) |
216 | volt_delay_c: | 218 | volt_delay_c: |
217 | ldr r7, [r10] @ get timer value | 219 | ldr r7, [r10] @ get timer value |
218 | cmp r8, r7 @ time up? | 220 | cmp r8, r7 @ time up? |
219 | bhi volt_delay_c @ not yet->branch | 221 | bhi volt_delay_c @ not yet->branch |
220 | mov pc, lr @ back to caller | 222 | mov pc, lr @ back to caller |
221 | 223 | ||
222 | omap243x_srs_cm_clksel2_pll: | 224 | omap243x_srs_cm_clksel2_pll: |
223 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2) | 225 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL2) |
224 | omap243x_srs_sdrc_dlla_ctrl: | 226 | omap243x_srs_sdrc_dlla_ctrl: |
225 | .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) | 227 | .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) |
226 | omap243x_srs_sdrc_rfr_ctrl: | 228 | omap243x_srs_sdrc_rfr_ctrl: |
227 | .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) | 229 | .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) |
228 | omap243x_srs_prcm_voltctrl: | 230 | omap243x_srs_prcm_voltctrl: |
229 | .word OMAP2430_PRCM_VOLTCTRL | 231 | .word OMAP2430_PRCM_VOLTCTRL |
230 | ddr_prcm_mask_val: | 232 | ddr_prcm_mask_val: |
231 | .word 0xFFFF3FFC | 233 | .word 0xFFFF3FFC |
232 | omap243x_srs_timer_32ksynct: | 234 | omap243x_srs_timer_32ksynct: |
233 | .word OMAP2_L4_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010) | 235 | .word OMAP2_L4_IO_ADDRESS(OMAP2430_32KSYNCT_BASE + 0x010) |
234 | 236 | ||
235 | ENTRY(omap243x_sram_reprogram_sdrc_sz) | 237 | ENTRY(omap243x_sram_reprogram_sdrc_sz) |
236 | .word . - omap243x_sram_reprogram_sdrc | 238 | .word . - omap243x_sram_reprogram_sdrc |
237 | 239 | ||
238 | /* | 240 | /* |
239 | * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. | 241 | * Set dividers and pll. Also recalculate DLL value for DDR and unlock mode. |
240 | */ | 242 | */ |
243 | .align 3 | ||
241 | ENTRY(omap243x_sram_set_prcm) | 244 | ENTRY(omap243x_sram_set_prcm) |
242 | stmfd sp!, {r0-r12, lr} @ regs to stack | 245 | stmfd sp!, {r0-r12, lr} @ regs to stack |
243 | adr r4, pbegin @ addr of preload start | 246 | adr r4, pbegin @ addr of preload start |
244 | adr r8, pend @ addr of preload end | 247 | adr r8, pend @ addr of preload end |
245 | mcrr p15, 1, r8, r4, c12 @ preload into icache | 248 | mcrr p15, 1, r8, r4, c12 @ preload into icache |
246 | pbegin: | 249 | pbegin: |
247 | /* move into fast relock bypass */ | 250 | /* move into fast relock bypass */ |
248 | ldr r8, omap243x_ssp_pll_ctl @ get addr | 251 | ldr r8, omap243x_ssp_pll_ctl @ get addr |
249 | ldr r5, [r8] @ get val | 252 | ldr r5, [r8] @ get val |
250 | mvn r6, #0x3 @ clear mask | 253 | mvn r6, #0x3 @ clear mask |
251 | and r5, r5, r6 @ clear field | 254 | and r5, r5, r6 @ clear field |
252 | orr r7, r5, #0x2 @ fast relock val | 255 | orr r7, r5, #0x2 @ fast relock val |
253 | str r7, [r8] @ go to fast relock | 256 | str r7, [r8] @ go to fast relock |
254 | ldr r4, omap243x_ssp_pll_stat @ addr of stat | 257 | ldr r4, omap243x_ssp_pll_stat @ addr of stat |
255 | block: | 258 | block: |
256 | /* wait for bypass */ | 259 | /* wait for bypass */ |
257 | ldr r8, [r4] @ stat value | 260 | ldr r8, [r4] @ stat value |
258 | and r8, r8, #0x3 @ mask for stat | 261 | and r8, r8, #0x3 @ mask for stat |
259 | cmp r8, #0x1 @ there yet | 262 | cmp r8, #0x1 @ there yet |
260 | bne block @ loop if not | 263 | bne block @ loop if not |
261 | 264 | ||
262 | /* set new dpll dividers _after_ in bypass */ | 265 | /* set new dpll dividers _after_ in bypass */ |
263 | ldr r4, omap243x_ssp_pll_div @ get addr | 266 | ldr r4, omap243x_ssp_pll_div @ get addr |
264 | str r0, [r4] @ set dpll ctrl val | 267 | str r0, [r4] @ set dpll ctrl val |
265 | 268 | ||
266 | ldr r4, omap243x_ssp_set_config @ get addr | 269 | ldr r4, omap243x_ssp_set_config @ get addr |
267 | mov r8, #1 @ valid cfg msk | 270 | mov r8, #1 @ valid cfg msk |
268 | str r8, [r4] @ make dividers take | 271 | str r8, [r4] @ make dividers take |
269 | 272 | ||
270 | mov r4, #100 @ dead spin a bit | 273 | mov r4, #100 @ dead spin a bit |
271 | wait_a_bit: | 274 | wait_a_bit: |
272 | subs r4, r4, #1 @ dec loop | 275 | subs r4, r4, #1 @ dec loop |
273 | bne wait_a_bit @ delay done? | 276 | bne wait_a_bit @ delay done? |
274 | 277 | ||
275 | /* check if staying in bypass */ | 278 | /* check if staying in bypass */ |
276 | cmp r2, #0x1 @ stay in bypass? | 279 | cmp r2, #0x1 @ stay in bypass? |
277 | beq pend @ jump over dpll relock | 280 | beq pend @ jump over dpll relock |
278 | 281 | ||
279 | /* relock DPLL with new vals */ | 282 | /* relock DPLL with new vals */ |
280 | ldr r5, omap243x_ssp_pll_stat @ get addr | 283 | ldr r5, omap243x_ssp_pll_stat @ get addr |
281 | ldr r4, omap243x_ssp_pll_ctl @ get addr | 284 | ldr r4, omap243x_ssp_pll_ctl @ get addr |
282 | orr r8, r7, #0x3 @ val for lock dpll | 285 | orr r8, r7, #0x3 @ val for lock dpll |
283 | str r8, [r4] @ set val | 286 | str r8, [r4] @ set val |
284 | mov r0, #1000 @ dead spin a bit | 287 | mov r0, #1000 @ dead spin a bit |
285 | wait_more: | 288 | wait_more: |
286 | subs r0, r0, #1 @ dec loop | 289 | subs r0, r0, #1 @ dec loop |
287 | bne wait_more @ delay done? | 290 | bne wait_more @ delay done? |
288 | wait_lock: | 291 | wait_lock: |
289 | ldr r8, [r5] @ get lock val | 292 | ldr r8, [r5] @ get lock val |
290 | and r8, r8, #3 @ isolate field | 293 | and r8, r8, #3 @ isolate field |
291 | cmp r8, #2 @ locked? | 294 | cmp r8, #2 @ locked? |
292 | bne wait_lock @ wait if not | 295 | bne wait_lock @ wait if not |
293 | pend: | 296 | pend: |
294 | /* update memory timings & briefly lock dll */ | 297 | /* update memory timings & briefly lock dll */ |
295 | ldr r4, omap243x_ssp_sdrc_rfr @ get addr | 298 | ldr r4, omap243x_ssp_sdrc_rfr @ get addr |
296 | str r1, [r4] @ update refresh timing | 299 | str r1, [r4] @ update refresh timing |
297 | ldr r11, omap243x_ssp_dlla_ctrl @ get addr of DLLA ctrl | 300 | ldr r11, omap243x_ssp_dlla_ctrl @ get addr of DLLA ctrl |
298 | ldr r10, [r11] @ get current val | 301 | ldr r10, [r11] @ get current val |
299 | mvn r9, #0x4 @ mask to get clear bit2 | 302 | mvn r9, #0x4 @ mask to get clear bit2 |
300 | and r10, r10, r9 @ clear bit2 for lock mode | 303 | and r10, r10, r9 @ clear bit2 for lock mode |
301 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) | 304 | orr r10, r10, #0x8 @ make sure DLL on (es2 bit pos) |
302 | str r10, [r11] @ commit to DLLA_CTRL | 305 | str r10, [r11] @ commit to DLLA_CTRL |
303 | add r11, r11, #0x8 @ move to dllb | 306 | add r11, r11, #0x8 @ move to dllb |
304 | str r10, [r11] @ hit DLLB also | 307 | str r10, [r11] @ hit DLLB also |
305 | 308 | ||
306 | mov r4, #0x800 @ relock time (min 0x400 L3 clocks) | 309 | mov r4, #0x800 @ relock time (min 0x400 L3 clocks) |
307 | wait_dll_lock: | 310 | wait_dll_lock: |
308 | subs r4, r4, #0x1 | 311 | subs r4, r4, #0x1 |
309 | bne wait_dll_lock | 312 | bne wait_dll_lock |
310 | nop | 313 | nop |
311 | ldmfd sp!, {r0-r12, pc} @ restore regs and return | 314 | ldmfd sp!, {r0-r12, pc} @ restore regs and return |
312 | 315 | ||
313 | omap243x_ssp_set_config: | 316 | omap243x_ssp_set_config: |
314 | .word OMAP2430_PRCM_CLKCFG_CTRL | 317 | .word OMAP2430_PRCM_CLKCFG_CTRL |
315 | omap243x_ssp_pll_ctl: | 318 | omap243x_ssp_pll_ctl: |
316 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKEN) | 319 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKEN) |
317 | omap243x_ssp_pll_stat: | 320 | omap243x_ssp_pll_stat: |
318 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_IDLEST) | 321 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_IDLEST) |
319 | omap243x_ssp_pll_div: | 322 | omap243x_ssp_pll_div: |
320 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL1) | 323 | .word OMAP2430_CM_REGADDR(PLL_MOD, CM_CLKSEL1) |
321 | omap243x_ssp_sdrc_rfr: | 324 | omap243x_ssp_sdrc_rfr: |
322 | .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) | 325 | .word OMAP243X_SDRC_REGADDR(SDRC_RFR_CTRL_0) |
323 | omap243x_ssp_dlla_ctrl: | 326 | omap243x_ssp_dlla_ctrl: |
324 | .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) | 327 | .word OMAP243X_SDRC_REGADDR(SDRC_DLLA_CTRL) |
325 | 328 | ||
326 | ENTRY(omap243x_sram_set_prcm_sz) | 329 | ENTRY(omap243x_sram_set_prcm_sz) |
327 | .word . - omap243x_sram_set_prcm | 330 | .word . - omap243x_sram_set_prcm |
328 | 331 |
arch/arm/mach-omap2/sram34xx.S
1 | /* | 1 | /* |
2 | * linux/arch/arm/mach-omap3/sram.S | 2 | * linux/arch/arm/mach-omap3/sram.S |
3 | * | 3 | * |
4 | * Omap3 specific functions that need to be run in internal SRAM | 4 | * Omap3 specific functions that need to be run in internal SRAM |
5 | * | 5 | * |
6 | * Copyright (C) 2004, 2007, 2008 Texas Instruments, Inc. | 6 | * Copyright (C) 2004, 2007, 2008 Texas Instruments, Inc. |
7 | * Copyright (C) 2008 Nokia Corporation | 7 | * Copyright (C) 2008 Nokia Corporation |
8 | * | 8 | * |
9 | * Rajendra Nayak <rnayak@ti.com> | 9 | * Rajendra Nayak <rnayak@ti.com> |
10 | * Richard Woodruff <r-woodruff2@ti.com> | 10 | * Richard Woodruff <r-woodruff2@ti.com> |
11 | * Paul Walmsley | 11 | * Paul Walmsley |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
14 | * modify it under the terms of the GNU General Public License as | 14 | * modify it under the terms of the GNU General Public License as |
15 | * published by the Free Software Foundation; either version 2 of | 15 | * published by the Free Software Foundation; either version 2 of |
16 | * the License, or (at your option) any later version. | 16 | * the License, or (at your option) any later version. |
17 | * | 17 | * |
18 | * This program is distributed in the hope that it will be useful, | 18 | * This program is distributed in the hope that it will be useful, |
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the | 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the |
21 | * GNU General Public License for more details. | 21 | * GNU General Public License for more details. |
22 | * | 22 | * |
23 | * You should have received a copy of the GNU General Public License | 23 | * You should have received a copy of the GNU General Public License |
24 | * along with this program; if not, write to the Free Software | 24 | * along with this program; if not, write to the Free Software |
25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
26 | * MA 02111-1307 USA | 26 | * MA 02111-1307 USA |
27 | */ | 27 | */ |
28 | #include <linux/linkage.h> | 28 | #include <linux/linkage.h> |
29 | #include <asm/assembler.h> | 29 | #include <asm/assembler.h> |
30 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
31 | 31 | ||
32 | #include <mach/io.h> | 32 | #include <mach/io.h> |
33 | 33 | ||
34 | #include "sdrc.h" | 34 | #include "sdrc.h" |
35 | #include "cm2xxx_3xxx.h" | 35 | #include "cm2xxx_3xxx.h" |
36 | 36 | ||
37 | .text | 37 | .text |
38 | 38 | ||
39 | /* r1 parameters */ | 39 | /* r1 parameters */ |
40 | #define SDRC_NO_UNLOCK_DLL 0x0 | 40 | #define SDRC_NO_UNLOCK_DLL 0x0 |
41 | #define SDRC_UNLOCK_DLL 0x1 | 41 | #define SDRC_UNLOCK_DLL 0x1 |
42 | 42 | ||
43 | /* SDRC_DLLA_CTRL bit settings */ | 43 | /* SDRC_DLLA_CTRL bit settings */ |
44 | #define FIXEDDELAY_SHIFT 24 | 44 | #define FIXEDDELAY_SHIFT 24 |
45 | #define FIXEDDELAY_MASK (0xff << FIXEDDELAY_SHIFT) | 45 | #define FIXEDDELAY_MASK (0xff << FIXEDDELAY_SHIFT) |
46 | #define DLLIDLE_MASK 0x4 | 46 | #define DLLIDLE_MASK 0x4 |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * SDRC_DLLA_CTRL default values: TI hardware team indicates that | 49 | * SDRC_DLLA_CTRL default values: TI hardware team indicates that |
50 | * FIXEDDELAY should be initialized to 0xf. This apparently was | 50 | * FIXEDDELAY should be initialized to 0xf. This apparently was |
51 | * empirically determined during process testing, so no derivation | 51 | * empirically determined during process testing, so no derivation |
52 | * was provided. | 52 | * was provided. |
53 | */ | 53 | */ |
54 | #define FIXEDDELAY_DEFAULT (0x0f << FIXEDDELAY_SHIFT) | 54 | #define FIXEDDELAY_DEFAULT (0x0f << FIXEDDELAY_SHIFT) |
55 | 55 | ||
56 | /* SDRC_DLLA_STATUS bit settings */ | 56 | /* SDRC_DLLA_STATUS bit settings */ |
57 | #define LOCKSTATUS_MASK 0x4 | 57 | #define LOCKSTATUS_MASK 0x4 |
58 | 58 | ||
59 | /* SDRC_POWER bit settings */ | 59 | /* SDRC_POWER bit settings */ |
60 | #define SRFRONIDLEREQ_MASK 0x40 | 60 | #define SRFRONIDLEREQ_MASK 0x40 |
61 | 61 | ||
62 | /* CM_IDLEST1_CORE bit settings */ | 62 | /* CM_IDLEST1_CORE bit settings */ |
63 | #define ST_SDRC_MASK 0x2 | 63 | #define ST_SDRC_MASK 0x2 |
64 | 64 | ||
65 | /* CM_ICLKEN1_CORE bit settings */ | 65 | /* CM_ICLKEN1_CORE bit settings */ |
66 | #define EN_SDRC_MASK 0x2 | 66 | #define EN_SDRC_MASK 0x2 |
67 | 67 | ||
68 | /* CM_CLKSEL1_PLL bit settings */ | 68 | /* CM_CLKSEL1_PLL bit settings */ |
69 | #define CORE_DPLL_CLKOUT_DIV_SHIFT 0x1b | 69 | #define CORE_DPLL_CLKOUT_DIV_SHIFT 0x1b |
70 | 70 | ||
71 | /* | 71 | /* |
72 | * omap3_sram_configure_core_dpll - change DPLL3 M2 divider | 72 | * omap3_sram_configure_core_dpll - change DPLL3 M2 divider |
73 | * | 73 | * |
74 | * Params passed in registers: | 74 | * Params passed in registers: |
75 | * r0 = new M2 divider setting (only 1 and 2 supported right now) | 75 | * r0 = new M2 divider setting (only 1 and 2 supported right now) |
76 | * r1 = unlock SDRC DLL? (1 = yes, 0 = no). Only unlock DLL for | 76 | * r1 = unlock SDRC DLL? (1 = yes, 0 = no). Only unlock DLL for |
77 | * SDRC rates < 83MHz | 77 | * SDRC rates < 83MHz |
78 | * r2 = number of MPU cycles to wait for SDRC to stabilize after | 78 | * r2 = number of MPU cycles to wait for SDRC to stabilize after |
79 | * reprogramming the SDRC when switching to a slower MPU speed | 79 | * reprogramming the SDRC when switching to a slower MPU speed |
80 | * r3 = increasing SDRC rate? (1 = yes, 0 = no) | 80 | * r3 = increasing SDRC rate? (1 = yes, 0 = no) |
81 | * | 81 | * |
82 | * Params passed via the stack. The needed params will be copied in SRAM | 82 | * Params passed via the stack. The needed params will be copied in SRAM |
83 | * before use by the code in SRAM (SDRAM is not accessible during SDRC | 83 | * before use by the code in SRAM (SDRAM is not accessible during SDRC |
84 | * reconfiguration): | 84 | * reconfiguration): |
85 | * new SDRC_RFR_CTRL_0 register contents | 85 | * new SDRC_RFR_CTRL_0 register contents |
86 | * new SDRC_ACTIM_CTRL_A_0 register contents | 86 | * new SDRC_ACTIM_CTRL_A_0 register contents |
87 | * new SDRC_ACTIM_CTRL_B_0 register contents | 87 | * new SDRC_ACTIM_CTRL_B_0 register contents |
88 | * new SDRC_MR_0 register value | 88 | * new SDRC_MR_0 register value |
89 | * new SDRC_RFR_CTRL_1 register contents | 89 | * new SDRC_RFR_CTRL_1 register contents |
90 | * new SDRC_ACTIM_CTRL_A_1 register contents | 90 | * new SDRC_ACTIM_CTRL_A_1 register contents |
91 | * new SDRC_ACTIM_CTRL_B_1 register contents | 91 | * new SDRC_ACTIM_CTRL_B_1 register contents |
92 | * new SDRC_MR_1 register value | 92 | * new SDRC_MR_1 register value |
93 | * | 93 | * |
94 | * If the param SDRC_RFR_CTRL_1 is 0, the parameters are not programmed into | 94 | * If the param SDRC_RFR_CTRL_1 is 0, the parameters are not programmed into |
95 | * the SDRC CS1 registers | 95 | * the SDRC CS1 registers |
96 | * | 96 | * |
97 | * NOTE: This code no longer attempts to program the SDRC AC timing and MR | 97 | * NOTE: This code no longer attempts to program the SDRC AC timing and MR |
98 | * registers. This is because the code currently cannot ensure that all | 98 | * registers. This is because the code currently cannot ensure that all |
99 | * L3 initiators (e.g., sDMA, IVA, DSS DISPC, etc.) are not accessing the | 99 | * L3 initiators (e.g., sDMA, IVA, DSS DISPC, etc.) are not accessing the |
100 | * SDRAM when the registers are written. If the registers are changed while | 100 | * SDRAM when the registers are written. If the registers are changed while |
101 | * an initiator is accessing SDRAM, memory can be corrupted and/or the SDRC | 101 | * an initiator is accessing SDRAM, memory can be corrupted and/or the SDRC |
102 | * may enter an unpredictable state. In the future, the intent is to | 102 | * may enter an unpredictable state. In the future, the intent is to |
103 | * re-enable this code in cases where we can ensure that no initiators are | 103 | * re-enable this code in cases where we can ensure that no initiators are |
104 | * touching the SDRAM. Until that time, users who know that their use case | 104 | * touching the SDRAM. Until that time, users who know that their use case |
105 | * can satisfy the above requirement can enable the CONFIG_OMAP3_SDRC_AC_TIMING | 105 | * can satisfy the above requirement can enable the CONFIG_OMAP3_SDRC_AC_TIMING |
106 | * option. | 106 | * option. |
107 | * | 107 | * |
108 | * Richard Woodruff notes that any changes to this code must be carefully | 108 | * Richard Woodruff notes that any changes to this code must be carefully |
109 | * audited and tested to ensure that they don't cause a TLB miss while | 109 | * audited and tested to ensure that they don't cause a TLB miss while |
110 | * the SDRAM is inaccessible. Such a situation will crash the system | 110 | * the SDRAM is inaccessible. Such a situation will crash the system |
111 | * since it will cause the ARM MMU to attempt to walk the page tables. | 111 | * since it will cause the ARM MMU to attempt to walk the page tables. |
112 | * These crashes may be intermittent. | 112 | * These crashes may be intermittent. |
113 | */ | 113 | */ |
114 | .align 3 | ||
114 | ENTRY(omap3_sram_configure_core_dpll) | 115 | ENTRY(omap3_sram_configure_core_dpll) |
115 | stmfd sp!, {r1-r12, lr} @ store regs to stack | 116 | stmfd sp!, {r1-r12, lr} @ store regs to stack |
116 | 117 | ||
117 | @ pull the extra args off the stack | 118 | @ pull the extra args off the stack |
118 | @ and store them in SRAM | 119 | @ and store them in SRAM |
119 | ldr r4, [sp, #52] | 120 | ldr r4, [sp, #52] |
120 | str r4, omap_sdrc_rfr_ctrl_0_val | 121 | str r4, omap_sdrc_rfr_ctrl_0_val |
121 | ldr r4, [sp, #56] | 122 | ldr r4, [sp, #56] |
122 | str r4, omap_sdrc_actim_ctrl_a_0_val | 123 | str r4, omap_sdrc_actim_ctrl_a_0_val |
123 | ldr r4, [sp, #60] | 124 | ldr r4, [sp, #60] |
124 | str r4, omap_sdrc_actim_ctrl_b_0_val | 125 | str r4, omap_sdrc_actim_ctrl_b_0_val |
125 | ldr r4, [sp, #64] | 126 | ldr r4, [sp, #64] |
126 | str r4, omap_sdrc_mr_0_val | 127 | str r4, omap_sdrc_mr_0_val |
127 | ldr r4, [sp, #68] | 128 | ldr r4, [sp, #68] |
128 | str r4, omap_sdrc_rfr_ctrl_1_val | 129 | str r4, omap_sdrc_rfr_ctrl_1_val |
129 | cmp r4, #0 @ if SDRC_RFR_CTRL_1 is 0, | 130 | cmp r4, #0 @ if SDRC_RFR_CTRL_1 is 0, |
130 | beq skip_cs1_params @ do not use cs1 params | 131 | beq skip_cs1_params @ do not use cs1 params |
131 | ldr r4, [sp, #72] | 132 | ldr r4, [sp, #72] |
132 | str r4, omap_sdrc_actim_ctrl_a_1_val | 133 | str r4, omap_sdrc_actim_ctrl_a_1_val |
133 | ldr r4, [sp, #76] | 134 | ldr r4, [sp, #76] |
134 | str r4, omap_sdrc_actim_ctrl_b_1_val | 135 | str r4, omap_sdrc_actim_ctrl_b_1_val |
135 | ldr r4, [sp, #80] | 136 | ldr r4, [sp, #80] |
136 | str r4, omap_sdrc_mr_1_val | 137 | str r4, omap_sdrc_mr_1_val |
137 | skip_cs1_params: | 138 | skip_cs1_params: |
138 | mrc p15, 0, r8, c1, c0, 0 @ read ctrl register | 139 | mrc p15, 0, r8, c1, c0, 0 @ read ctrl register |
139 | bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction | 140 | bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction |
140 | mcr p15, 0, r10, c1, c0, 0 @ write ctrl register | 141 | mcr p15, 0, r10, c1, c0, 0 @ write ctrl register |
141 | dsb @ flush buffered writes to interconnect | 142 | dsb @ flush buffered writes to interconnect |
142 | isb @ prevent speculative exec past here | 143 | isb @ prevent speculative exec past here |
143 | cmp r3, #1 @ if increasing SDRC clk rate, | 144 | cmp r3, #1 @ if increasing SDRC clk rate, |
144 | bleq configure_sdrc @ program the SDRC regs early (for RFR) | 145 | bleq configure_sdrc @ program the SDRC regs early (for RFR) |
145 | cmp r1, #SDRC_UNLOCK_DLL @ set the intended DLL state | 146 | cmp r1, #SDRC_UNLOCK_DLL @ set the intended DLL state |
146 | bleq unlock_dll | 147 | bleq unlock_dll |
147 | blne lock_dll | 148 | blne lock_dll |
148 | bl sdram_in_selfrefresh @ put SDRAM in self refresh, idle SDRC | 149 | bl sdram_in_selfrefresh @ put SDRAM in self refresh, idle SDRC |
149 | bl configure_core_dpll @ change the DPLL3 M2 divider | 150 | bl configure_core_dpll @ change the DPLL3 M2 divider |
150 | mov r12, r2 | 151 | mov r12, r2 |
151 | bl wait_clk_stable @ wait for SDRC to stabilize | 152 | bl wait_clk_stable @ wait for SDRC to stabilize |
152 | bl enable_sdrc @ take SDRC out of idle | 153 | bl enable_sdrc @ take SDRC out of idle |
153 | cmp r1, #SDRC_UNLOCK_DLL @ wait for DLL status to change | 154 | cmp r1, #SDRC_UNLOCK_DLL @ wait for DLL status to change |
154 | bleq wait_dll_unlock | 155 | bleq wait_dll_unlock |
155 | blne wait_dll_lock | 156 | blne wait_dll_lock |
156 | cmp r3, #1 @ if increasing SDRC clk rate, | 157 | cmp r3, #1 @ if increasing SDRC clk rate, |
157 | beq return_to_sdram @ return to SDRAM code, otherwise, | 158 | beq return_to_sdram @ return to SDRAM code, otherwise, |
158 | bl configure_sdrc @ reprogram SDRC regs now | 159 | bl configure_sdrc @ reprogram SDRC regs now |
159 | return_to_sdram: | 160 | return_to_sdram: |
160 | mcr p15, 0, r8, c1, c0, 0 @ restore ctrl register | 161 | mcr p15, 0, r8, c1, c0, 0 @ restore ctrl register |
161 | isb @ prevent speculative exec past here | 162 | isb @ prevent speculative exec past here |
162 | mov r0, #0 @ return value | 163 | mov r0, #0 @ return value |
163 | ldmfd sp!, {r1-r12, pc} @ restore regs and return | 164 | ldmfd sp!, {r1-r12, pc} @ restore regs and return |
164 | unlock_dll: | 165 | unlock_dll: |
165 | ldr r11, omap3_sdrc_dlla_ctrl | 166 | ldr r11, omap3_sdrc_dlla_ctrl |
166 | ldr r12, [r11] | 167 | ldr r12, [r11] |
167 | bic r12, r12, #FIXEDDELAY_MASK | 168 | bic r12, r12, #FIXEDDELAY_MASK |
168 | orr r12, r12, #FIXEDDELAY_DEFAULT | 169 | orr r12, r12, #FIXEDDELAY_DEFAULT |
169 | orr r12, r12, #DLLIDLE_MASK | 170 | orr r12, r12, #DLLIDLE_MASK |
170 | str r12, [r11] @ (no OCP barrier needed) | 171 | str r12, [r11] @ (no OCP barrier needed) |
171 | bx lr | 172 | bx lr |
172 | lock_dll: | 173 | lock_dll: |
173 | ldr r11, omap3_sdrc_dlla_ctrl | 174 | ldr r11, omap3_sdrc_dlla_ctrl |
174 | ldr r12, [r11] | 175 | ldr r12, [r11] |
175 | bic r12, r12, #DLLIDLE_MASK | 176 | bic r12, r12, #DLLIDLE_MASK |
176 | str r12, [r11] @ (no OCP barrier needed) | 177 | str r12, [r11] @ (no OCP barrier needed) |
177 | bx lr | 178 | bx lr |
178 | sdram_in_selfrefresh: | 179 | sdram_in_selfrefresh: |
179 | ldr r11, omap3_sdrc_power @ read the SDRC_POWER register | 180 | ldr r11, omap3_sdrc_power @ read the SDRC_POWER register |
180 | ldr r12, [r11] @ read the contents of SDRC_POWER | 181 | ldr r12, [r11] @ read the contents of SDRC_POWER |
181 | mov r9, r12 @ keep a copy of SDRC_POWER bits | 182 | mov r9, r12 @ keep a copy of SDRC_POWER bits |
182 | orr r12, r12, #SRFRONIDLEREQ_MASK @ enable self refresh on idle | 183 | orr r12, r12, #SRFRONIDLEREQ_MASK @ enable self refresh on idle |
183 | str r12, [r11] @ write back to SDRC_POWER register | 184 | str r12, [r11] @ write back to SDRC_POWER register |
184 | ldr r12, [r11] @ posted-write barrier for SDRC | 185 | ldr r12, [r11] @ posted-write barrier for SDRC |
185 | idle_sdrc: | 186 | idle_sdrc: |
186 | ldr r11, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg | 187 | ldr r11, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg |
187 | ldr r12, [r11] | 188 | ldr r12, [r11] |
188 | bic r12, r12, #EN_SDRC_MASK @ disable iclk bit for SDRC | 189 | bic r12, r12, #EN_SDRC_MASK @ disable iclk bit for SDRC |
189 | str r12, [r11] | 190 | str r12, [r11] |
190 | wait_sdrc_idle: | 191 | wait_sdrc_idle: |
191 | ldr r11, omap3_cm_idlest1_core | 192 | ldr r11, omap3_cm_idlest1_core |
192 | ldr r12, [r11] | 193 | ldr r12, [r11] |
193 | and r12, r12, #ST_SDRC_MASK @ check for SDRC idle | 194 | and r12, r12, #ST_SDRC_MASK @ check for SDRC idle |
194 | cmp r12, #ST_SDRC_MASK | 195 | cmp r12, #ST_SDRC_MASK |
195 | bne wait_sdrc_idle | 196 | bne wait_sdrc_idle |
196 | bx lr | 197 | bx lr |
197 | configure_core_dpll: | 198 | configure_core_dpll: |
198 | ldr r11, omap3_cm_clksel1_pll | 199 | ldr r11, omap3_cm_clksel1_pll |
199 | ldr r12, [r11] | 200 | ldr r12, [r11] |
200 | ldr r10, core_m2_mask_val @ modify m2 for core dpll | 201 | ldr r10, core_m2_mask_val @ modify m2 for core dpll |
201 | and r12, r12, r10 | 202 | and r12, r12, r10 |
202 | orr r12, r12, r0, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT | 203 | orr r12, r12, r0, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT |
203 | str r12, [r11] | 204 | str r12, [r11] |
204 | ldr r12, [r11] @ posted-write barrier for CM | 205 | ldr r12, [r11] @ posted-write barrier for CM |
205 | bx lr | 206 | bx lr |
206 | wait_clk_stable: | 207 | wait_clk_stable: |
207 | subs r12, r12, #1 | 208 | subs r12, r12, #1 |
208 | bne wait_clk_stable | 209 | bne wait_clk_stable |
209 | bx lr | 210 | bx lr |
210 | enable_sdrc: | 211 | enable_sdrc: |
211 | ldr r11, omap3_cm_iclken1_core | 212 | ldr r11, omap3_cm_iclken1_core |
212 | ldr r12, [r11] | 213 | ldr r12, [r11] |
213 | orr r12, r12, #EN_SDRC_MASK @ enable iclk bit for SDRC | 214 | orr r12, r12, #EN_SDRC_MASK @ enable iclk bit for SDRC |
214 | str r12, [r11] | 215 | str r12, [r11] |
215 | wait_sdrc_idle1: | 216 | wait_sdrc_idle1: |
216 | ldr r11, omap3_cm_idlest1_core | 217 | ldr r11, omap3_cm_idlest1_core |
217 | ldr r12, [r11] | 218 | ldr r12, [r11] |
218 | and r12, r12, #ST_SDRC_MASK | 219 | and r12, r12, #ST_SDRC_MASK |
219 | cmp r12, #0 | 220 | cmp r12, #0 |
220 | bne wait_sdrc_idle1 | 221 | bne wait_sdrc_idle1 |
221 | restore_sdrc_power_val: | 222 | restore_sdrc_power_val: |
222 | ldr r11, omap3_sdrc_power | 223 | ldr r11, omap3_sdrc_power |
223 | str r9, [r11] @ restore SDRC_POWER, no barrier needed | 224 | str r9, [r11] @ restore SDRC_POWER, no barrier needed |
224 | bx lr | 225 | bx lr |
225 | wait_dll_lock: | 226 | wait_dll_lock: |
226 | ldr r11, omap3_sdrc_dlla_status | 227 | ldr r11, omap3_sdrc_dlla_status |
227 | ldr r12, [r11] | 228 | ldr r12, [r11] |
228 | and r12, r12, #LOCKSTATUS_MASK | 229 | and r12, r12, #LOCKSTATUS_MASK |
229 | cmp r12, #LOCKSTATUS_MASK | 230 | cmp r12, #LOCKSTATUS_MASK |
230 | bne wait_dll_lock | 231 | bne wait_dll_lock |
231 | bx lr | 232 | bx lr |
232 | wait_dll_unlock: | 233 | wait_dll_unlock: |
233 | ldr r11, omap3_sdrc_dlla_status | 234 | ldr r11, omap3_sdrc_dlla_status |
234 | ldr r12, [r11] | 235 | ldr r12, [r11] |
235 | and r12, r12, #LOCKSTATUS_MASK | 236 | and r12, r12, #LOCKSTATUS_MASK |
236 | cmp r12, #0x0 | 237 | cmp r12, #0x0 |
237 | bne wait_dll_unlock | 238 | bne wait_dll_unlock |
238 | bx lr | 239 | bx lr |
239 | configure_sdrc: | 240 | configure_sdrc: |
240 | ldr r12, omap_sdrc_rfr_ctrl_0_val @ fetch value from SRAM | 241 | ldr r12, omap_sdrc_rfr_ctrl_0_val @ fetch value from SRAM |
241 | ldr r11, omap3_sdrc_rfr_ctrl_0 @ fetch addr from SRAM | 242 | ldr r11, omap3_sdrc_rfr_ctrl_0 @ fetch addr from SRAM |
242 | str r12, [r11] @ store | 243 | str r12, [r11] @ store |
243 | #ifdef CONFIG_OMAP3_SDRC_AC_TIMING | 244 | #ifdef CONFIG_OMAP3_SDRC_AC_TIMING |
244 | ldr r12, omap_sdrc_actim_ctrl_a_0_val | 245 | ldr r12, omap_sdrc_actim_ctrl_a_0_val |
245 | ldr r11, omap3_sdrc_actim_ctrl_a_0 | 246 | ldr r11, omap3_sdrc_actim_ctrl_a_0 |
246 | str r12, [r11] | 247 | str r12, [r11] |
247 | ldr r12, omap_sdrc_actim_ctrl_b_0_val | 248 | ldr r12, omap_sdrc_actim_ctrl_b_0_val |
248 | ldr r11, omap3_sdrc_actim_ctrl_b_0 | 249 | ldr r11, omap3_sdrc_actim_ctrl_b_0 |
249 | str r12, [r11] | 250 | str r12, [r11] |
250 | ldr r12, omap_sdrc_mr_0_val | 251 | ldr r12, omap_sdrc_mr_0_val |
251 | ldr r11, omap3_sdrc_mr_0 | 252 | ldr r11, omap3_sdrc_mr_0 |
252 | str r12, [r11] | 253 | str r12, [r11] |
253 | #endif | 254 | #endif |
254 | ldr r12, omap_sdrc_rfr_ctrl_1_val | 255 | ldr r12, omap_sdrc_rfr_ctrl_1_val |
255 | cmp r12, #0 @ if SDRC_RFR_CTRL_1 is 0, | 256 | cmp r12, #0 @ if SDRC_RFR_CTRL_1 is 0, |
256 | beq skip_cs1_prog @ do not program cs1 params | 257 | beq skip_cs1_prog @ do not program cs1 params |
257 | ldr r11, omap3_sdrc_rfr_ctrl_1 | 258 | ldr r11, omap3_sdrc_rfr_ctrl_1 |
258 | str r12, [r11] | 259 | str r12, [r11] |
259 | #ifdef CONFIG_OMAP3_SDRC_AC_TIMING | 260 | #ifdef CONFIG_OMAP3_SDRC_AC_TIMING |
260 | ldr r12, omap_sdrc_actim_ctrl_a_1_val | 261 | ldr r12, omap_sdrc_actim_ctrl_a_1_val |
261 | ldr r11, omap3_sdrc_actim_ctrl_a_1 | 262 | ldr r11, omap3_sdrc_actim_ctrl_a_1 |
262 | str r12, [r11] | 263 | str r12, [r11] |
263 | ldr r12, omap_sdrc_actim_ctrl_b_1_val | 264 | ldr r12, omap_sdrc_actim_ctrl_b_1_val |
264 | ldr r11, omap3_sdrc_actim_ctrl_b_1 | 265 | ldr r11, omap3_sdrc_actim_ctrl_b_1 |
265 | str r12, [r11] | 266 | str r12, [r11] |
266 | ldr r12, omap_sdrc_mr_1_val | 267 | ldr r12, omap_sdrc_mr_1_val |
267 | ldr r11, omap3_sdrc_mr_1 | 268 | ldr r11, omap3_sdrc_mr_1 |
268 | str r12, [r11] | 269 | str r12, [r11] |
269 | #endif | 270 | #endif |
270 | skip_cs1_prog: | 271 | skip_cs1_prog: |
271 | ldr r12, [r11] @ posted-write barrier for SDRC | 272 | ldr r12, [r11] @ posted-write barrier for SDRC |
272 | bx lr | 273 | bx lr |
273 | 274 | ||
274 | omap3_sdrc_power: | 275 | omap3_sdrc_power: |
275 | .word OMAP34XX_SDRC_REGADDR(SDRC_POWER) | 276 | .word OMAP34XX_SDRC_REGADDR(SDRC_POWER) |
276 | omap3_cm_clksel1_pll: | 277 | omap3_cm_clksel1_pll: |
277 | .word OMAP34XX_CM_REGADDR(PLL_MOD, CM_CLKSEL1) | 278 | .word OMAP34XX_CM_REGADDR(PLL_MOD, CM_CLKSEL1) |
278 | omap3_cm_idlest1_core: | 279 | omap3_cm_idlest1_core: |
279 | .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST) | 280 | .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST) |
280 | omap3_cm_iclken1_core: | 281 | omap3_cm_iclken1_core: |
281 | .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1) | 282 | .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1) |
282 | 283 | ||
283 | omap3_sdrc_rfr_ctrl_0: | 284 | omap3_sdrc_rfr_ctrl_0: |
284 | .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0) | 285 | .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0) |
285 | omap3_sdrc_rfr_ctrl_1: | 286 | omap3_sdrc_rfr_ctrl_1: |
286 | .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_1) | 287 | .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_1) |
287 | omap3_sdrc_actim_ctrl_a_0: | 288 | omap3_sdrc_actim_ctrl_a_0: |
288 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0) | 289 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0) |
289 | omap3_sdrc_actim_ctrl_a_1: | 290 | omap3_sdrc_actim_ctrl_a_1: |
290 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_1) | 291 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_1) |
291 | omap3_sdrc_actim_ctrl_b_0: | 292 | omap3_sdrc_actim_ctrl_b_0: |
292 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0) | 293 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0) |
293 | omap3_sdrc_actim_ctrl_b_1: | 294 | omap3_sdrc_actim_ctrl_b_1: |
294 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_1) | 295 | .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_1) |
295 | omap3_sdrc_mr_0: | 296 | omap3_sdrc_mr_0: |
296 | .word OMAP34XX_SDRC_REGADDR(SDRC_MR_0) | 297 | .word OMAP34XX_SDRC_REGADDR(SDRC_MR_0) |
297 | omap3_sdrc_mr_1: | 298 | omap3_sdrc_mr_1: |
298 | .word OMAP34XX_SDRC_REGADDR(SDRC_MR_1) | 299 | .word OMAP34XX_SDRC_REGADDR(SDRC_MR_1) |
299 | omap_sdrc_rfr_ctrl_0_val: | 300 | omap_sdrc_rfr_ctrl_0_val: |
300 | .word 0xDEADBEEF | 301 | .word 0xDEADBEEF |
301 | omap_sdrc_rfr_ctrl_1_val: | 302 | omap_sdrc_rfr_ctrl_1_val: |
302 | .word 0xDEADBEEF | 303 | .word 0xDEADBEEF |
303 | omap_sdrc_actim_ctrl_a_0_val: | 304 | omap_sdrc_actim_ctrl_a_0_val: |
304 | .word 0xDEADBEEF | 305 | .word 0xDEADBEEF |
305 | omap_sdrc_actim_ctrl_a_1_val: | 306 | omap_sdrc_actim_ctrl_a_1_val: |
306 | .word 0xDEADBEEF | 307 | .word 0xDEADBEEF |
307 | omap_sdrc_actim_ctrl_b_0_val: | 308 | omap_sdrc_actim_ctrl_b_0_val: |
308 | .word 0xDEADBEEF | 309 | .word 0xDEADBEEF |
309 | omap_sdrc_actim_ctrl_b_1_val: | 310 | omap_sdrc_actim_ctrl_b_1_val: |
310 | .word 0xDEADBEEF | 311 | .word 0xDEADBEEF |
311 | omap_sdrc_mr_0_val: | 312 | omap_sdrc_mr_0_val: |
312 | .word 0xDEADBEEF | 313 | .word 0xDEADBEEF |
313 | omap_sdrc_mr_1_val: | 314 | omap_sdrc_mr_1_val: |
314 | .word 0xDEADBEEF | 315 | .word 0xDEADBEEF |
315 | 316 | ||
316 | omap3_sdrc_dlla_status: | 317 | omap3_sdrc_dlla_status: |
317 | .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) | 318 | .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS) |
318 | omap3_sdrc_dlla_ctrl: | 319 | omap3_sdrc_dlla_ctrl: |
319 | .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) | 320 | .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL) |
320 | core_m2_mask_val: | 321 | core_m2_mask_val: |
321 | .word 0x07FFFFFF | 322 | .word 0x07FFFFFF |
322 | 323 | ||
323 | ENTRY(omap3_sram_configure_core_dpll_sz) | 324 | ENTRY(omap3_sram_configure_core_dpll_sz) |
324 | .word . - omap3_sram_configure_core_dpll | 325 | .word . - omap3_sram_configure_core_dpll |
325 | 326 | ||
326 | 327 |
arch/arm/plat-omap/include/plat/sram.h
1 | /* | 1 | /* |
2 | * arch/arm/plat-omap/include/mach/sram.h | 2 | * arch/arm/plat-omap/include/mach/sram.h |
3 | * | 3 | * |
4 | * Interface for functions that need to be run in internal SRAM | 4 | * Interface for functions that need to be run in internal SRAM |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 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 | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef __ARCH_ARM_OMAP_SRAM_H | 11 | #ifndef __ARCH_ARM_OMAP_SRAM_H |
12 | #define __ARCH_ARM_OMAP_SRAM_H | 12 | #define __ARCH_ARM_OMAP_SRAM_H |
13 | 13 | ||
14 | #ifndef __ASSEMBLY__ | 14 | #ifndef __ASSEMBLY__ |
15 | extern void * omap_sram_push(void * start, unsigned long size); | 15 | #include <asm/fncpy.h> |
16 | |||
17 | extern void *omap_sram_push_address(unsigned long size); | ||
18 | |||
19 | /* Macro to push a function to the internal SRAM, using the fncpy API */ | ||
20 | #define omap_sram_push(funcp, size) ({ \ | ||
21 | typeof(&(funcp)) _res = NULL; \ | ||
22 | void *_sram_address = omap_sram_push_address(size); \ | ||
23 | if (_sram_address) \ | ||
24 | _res = fncpy(_sram_address, &(funcp), size); \ | ||
25 | _res; \ | ||
26 | }) | ||
27 | |||
16 | extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); | 28 | extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl); |
17 | 29 | ||
18 | extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, | 30 | extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, |
19 | u32 base_cs, u32 force_unlock); | 31 | u32 base_cs, u32 force_unlock); |
20 | extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, | 32 | extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, |
21 | u32 mem_type); | 33 | u32 mem_type); |
22 | extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); | 34 | extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); |
23 | 35 | ||
24 | extern u32 omap3_configure_core_dpll( | 36 | extern u32 omap3_configure_core_dpll( |
25 | u32 m2, u32 unlock_dll, u32 f, u32 inc, | 37 | u32 m2, u32 unlock_dll, u32 f, u32 inc, |
26 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, | 38 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, |
27 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, | 39 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, |
28 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, | 40 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, |
29 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); | 41 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); |
30 | extern void omap3_sram_restore_context(void); | 42 | extern void omap3_sram_restore_context(void); |
31 | 43 | ||
32 | /* Do not use these */ | 44 | /* Do not use these */ |
33 | extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl); | 45 | extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl); |
34 | extern unsigned long omap1_sram_reprogram_clock_sz; | 46 | extern unsigned long omap1_sram_reprogram_clock_sz; |
35 | 47 | ||
36 | extern void omap24xx_sram_reprogram_clock(u32 ckctl, u32 dpllctl); | 48 | extern void omap24xx_sram_reprogram_clock(u32 ckctl, u32 dpllctl); |
37 | extern unsigned long omap24xx_sram_reprogram_clock_sz; | 49 | extern unsigned long omap24xx_sram_reprogram_clock_sz; |
38 | 50 | ||
39 | extern void omap242x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, | 51 | extern void omap242x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, |
40 | u32 base_cs, u32 force_unlock); | 52 | u32 base_cs, u32 force_unlock); |
41 | extern unsigned long omap242x_sram_ddr_init_sz; | 53 | extern unsigned long omap242x_sram_ddr_init_sz; |
42 | 54 | ||
43 | extern u32 omap242x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, | 55 | extern u32 omap242x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, |
44 | int bypass); | 56 | int bypass); |
45 | extern unsigned long omap242x_sram_set_prcm_sz; | 57 | extern unsigned long omap242x_sram_set_prcm_sz; |
46 | 58 | ||
47 | extern void omap242x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, | 59 | extern void omap242x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, |
48 | u32 mem_type); | 60 | u32 mem_type); |
49 | extern unsigned long omap242x_sram_reprogram_sdrc_sz; | 61 | extern unsigned long omap242x_sram_reprogram_sdrc_sz; |
50 | 62 | ||
51 | 63 | ||
52 | extern void omap243x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, | 64 | extern void omap243x_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, |
53 | u32 base_cs, u32 force_unlock); | 65 | u32 base_cs, u32 force_unlock); |
54 | extern unsigned long omap243x_sram_ddr_init_sz; | 66 | extern unsigned long omap243x_sram_ddr_init_sz; |
55 | 67 | ||
56 | extern u32 omap243x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, | 68 | extern u32 omap243x_sram_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, |
57 | int bypass); | 69 | int bypass); |
58 | extern unsigned long omap243x_sram_set_prcm_sz; | 70 | extern unsigned long omap243x_sram_set_prcm_sz; |
59 | 71 | ||
60 | extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, | 72 | extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, |
61 | u32 mem_type); | 73 | u32 mem_type); |
62 | extern unsigned long omap243x_sram_reprogram_sdrc_sz; | 74 | extern unsigned long omap243x_sram_reprogram_sdrc_sz; |
63 | 75 | ||
64 | extern u32 omap3_sram_configure_core_dpll( | 76 | extern u32 omap3_sram_configure_core_dpll( |
65 | u32 m2, u32 unlock_dll, u32 f, u32 inc, | 77 | u32 m2, u32 unlock_dll, u32 f, u32 inc, |
66 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, | 78 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, |
67 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, | 79 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, |
68 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, | 80 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, |
69 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); | 81 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); |
70 | extern unsigned long omap3_sram_configure_core_dpll_sz; | 82 | extern unsigned long omap3_sram_configure_core_dpll_sz; |
71 | 83 | ||
72 | #ifdef CONFIG_PM | 84 | #ifdef CONFIG_PM |
73 | extern void omap_push_sram_idle(void); | 85 | extern void omap_push_sram_idle(void); |
74 | #else | 86 | #else |
75 | static inline void omap_push_sram_idle(void) {} | 87 | static inline void omap_push_sram_idle(void) {} |
76 | #endif /* CONFIG_PM */ | 88 | #endif /* CONFIG_PM */ |
77 | 89 | ||
78 | #endif /* __ASSEMBLY__ */ | 90 | #endif /* __ASSEMBLY__ */ |
79 | 91 | ||
80 | /* | 92 | /* |
81 | * OMAP2+: define the SRAM PA addresses. | 93 | * OMAP2+: define the SRAM PA addresses. |
82 | * Used by the SRAM management code and the idle sleep code. | 94 | * Used by the SRAM management code and the idle sleep code. |
83 | */ | 95 | */ |
84 | #define OMAP2_SRAM_PA 0x40200000 | 96 | #define OMAP2_SRAM_PA 0x40200000 |
85 | #define OMAP3_SRAM_PA 0x40200000 | 97 | #define OMAP3_SRAM_PA 0x40200000 |
86 | #define OMAP4_SRAM_PA 0x40300000 | 98 | #define OMAP4_SRAM_PA 0x40300000 |
87 | 99 | ||
88 | #endif | 100 | #endif |
89 | 101 |
arch/arm/plat-omap/sram.c
1 | /* | 1 | /* |
2 | * linux/arch/arm/plat-omap/sram.c | 2 | * linux/arch/arm/plat-omap/sram.c |
3 | * | 3 | * |
4 | * OMAP SRAM detection and management | 4 | * OMAP SRAM detection and management |
5 | * | 5 | * |
6 | * Copyright (C) 2005 Nokia Corporation | 6 | * Copyright (C) 2005 Nokia Corporation |
7 | * Written by Tony Lindgren <tony@atomide.com> | 7 | * Written by Tony Lindgren <tony@atomide.com> |
8 | * | 8 | * |
9 | * Copyright (C) 2009 Texas Instruments | 9 | * Copyright (C) 2009 Texas Instruments |
10 | * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> | 10 | * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License version 2 as | 13 | * it under the terms of the GNU General Public License version 2 as |
14 | * published by the Free Software Foundation. | 14 | * published by the Free Software Foundation. |
15 | */ | 15 | */ |
16 | #undef DEBUG | 16 | #undef DEBUG |
17 | 17 | ||
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/omapfb.h> | 22 | #include <linux/omapfb.h> |
23 | 23 | ||
24 | #include <asm/tlb.h> | 24 | #include <asm/tlb.h> |
25 | #include <asm/cacheflush.h> | 25 | #include <asm/cacheflush.h> |
26 | 26 | ||
27 | #include <asm/mach/map.h> | 27 | #include <asm/mach/map.h> |
28 | 28 | ||
29 | #include <plat/sram.h> | 29 | #include <plat/sram.h> |
30 | #include <plat/board.h> | 30 | #include <plat/board.h> |
31 | #include <plat/cpu.h> | 31 | #include <plat/cpu.h> |
32 | #include <plat/vram.h> | 32 | #include <plat/vram.h> |
33 | 33 | ||
34 | #include "sram.h" | 34 | #include "sram.h" |
35 | #include "fb.h" | 35 | #include "fb.h" |
36 | 36 | ||
37 | /* XXX These "sideways" includes are a sign that something is wrong */ | 37 | /* XXX These "sideways" includes are a sign that something is wrong */ |
38 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | 38 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) |
39 | # include "../mach-omap2/prm2xxx_3xxx.h" | 39 | # include "../mach-omap2/prm2xxx_3xxx.h" |
40 | # include "../mach-omap2/sdrc.h" | 40 | # include "../mach-omap2/sdrc.h" |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #define OMAP1_SRAM_PA 0x20000000 | 43 | #define OMAP1_SRAM_PA 0x20000000 |
44 | #define OMAP1_SRAM_VA VMALLOC_END | 44 | #define OMAP1_SRAM_VA VMALLOC_END |
45 | #define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800) | 45 | #define OMAP2_SRAM_PUB_PA (OMAP2_SRAM_PA + 0xf800) |
46 | #define OMAP2_SRAM_VA 0xfe400000 | 46 | #define OMAP2_SRAM_VA 0xfe400000 |
47 | #define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800) | 47 | #define OMAP2_SRAM_PUB_VA (OMAP2_SRAM_VA + 0x800) |
48 | #define OMAP3_SRAM_VA 0xfe400000 | 48 | #define OMAP3_SRAM_VA 0xfe400000 |
49 | #define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000) | 49 | #define OMAP3_SRAM_PUB_PA (OMAP3_SRAM_PA + 0x8000) |
50 | #define OMAP3_SRAM_PUB_VA (OMAP3_SRAM_VA + 0x8000) | 50 | #define OMAP3_SRAM_PUB_VA (OMAP3_SRAM_VA + 0x8000) |
51 | #define OMAP4_SRAM_VA 0xfe400000 | 51 | #define OMAP4_SRAM_VA 0xfe400000 |
52 | #define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000) | 52 | #define OMAP4_SRAM_PUB_PA (OMAP4_SRAM_PA + 0x4000) |
53 | #define OMAP4_SRAM_PUB_VA (OMAP4_SRAM_VA + 0x4000) | 53 | #define OMAP4_SRAM_PUB_VA (OMAP4_SRAM_VA + 0x4000) |
54 | 54 | ||
55 | #if defined(CONFIG_ARCH_OMAP2PLUS) | 55 | #if defined(CONFIG_ARCH_OMAP2PLUS) |
56 | #define SRAM_BOOTLOADER_SZ 0x00 | 56 | #define SRAM_BOOTLOADER_SZ 0x00 |
57 | #else | 57 | #else |
58 | #define SRAM_BOOTLOADER_SZ 0x80 | 58 | #define SRAM_BOOTLOADER_SZ 0x80 |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #define OMAP24XX_VA_REQINFOPERM0 OMAP2_L3_IO_ADDRESS(0x68005048) | 61 | #define OMAP24XX_VA_REQINFOPERM0 OMAP2_L3_IO_ADDRESS(0x68005048) |
62 | #define OMAP24XX_VA_READPERM0 OMAP2_L3_IO_ADDRESS(0x68005050) | 62 | #define OMAP24XX_VA_READPERM0 OMAP2_L3_IO_ADDRESS(0x68005050) |
63 | #define OMAP24XX_VA_WRITEPERM0 OMAP2_L3_IO_ADDRESS(0x68005058) | 63 | #define OMAP24XX_VA_WRITEPERM0 OMAP2_L3_IO_ADDRESS(0x68005058) |
64 | 64 | ||
65 | #define OMAP34XX_VA_REQINFOPERM0 OMAP2_L3_IO_ADDRESS(0x68012848) | 65 | #define OMAP34XX_VA_REQINFOPERM0 OMAP2_L3_IO_ADDRESS(0x68012848) |
66 | #define OMAP34XX_VA_READPERM0 OMAP2_L3_IO_ADDRESS(0x68012850) | 66 | #define OMAP34XX_VA_READPERM0 OMAP2_L3_IO_ADDRESS(0x68012850) |
67 | #define OMAP34XX_VA_WRITEPERM0 OMAP2_L3_IO_ADDRESS(0x68012858) | 67 | #define OMAP34XX_VA_WRITEPERM0 OMAP2_L3_IO_ADDRESS(0x68012858) |
68 | #define OMAP34XX_VA_ADDR_MATCH2 OMAP2_L3_IO_ADDRESS(0x68012880) | 68 | #define OMAP34XX_VA_ADDR_MATCH2 OMAP2_L3_IO_ADDRESS(0x68012880) |
69 | #define OMAP34XX_VA_SMS_RG_ATT0 OMAP2_L3_IO_ADDRESS(0x6C000048) | 69 | #define OMAP34XX_VA_SMS_RG_ATT0 OMAP2_L3_IO_ADDRESS(0x6C000048) |
70 | 70 | ||
71 | #define GP_DEVICE 0x300 | 71 | #define GP_DEVICE 0x300 |
72 | 72 | ||
73 | #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) | 73 | #define ROUND_DOWN(value,boundary) ((value) & (~((boundary)-1))) |
74 | 74 | ||
75 | static unsigned long omap_sram_start; | 75 | static unsigned long omap_sram_start; |
76 | static unsigned long omap_sram_base; | 76 | static unsigned long omap_sram_base; |
77 | static unsigned long omap_sram_size; | 77 | static unsigned long omap_sram_size; |
78 | static unsigned long omap_sram_ceil; | 78 | static unsigned long omap_sram_ceil; |
79 | 79 | ||
80 | /* | 80 | /* |
81 | * Depending on the target RAMFS firewall setup, the public usable amount of | 81 | * Depending on the target RAMFS firewall setup, the public usable amount of |
82 | * SRAM varies. The default accessible size for all device types is 2k. A GP | 82 | * SRAM varies. The default accessible size for all device types is 2k. A GP |
83 | * device allows ARM11 but not other initiators for full size. This | 83 | * device allows ARM11 but not other initiators for full size. This |
84 | * functionality seems ok until some nice security API happens. | 84 | * functionality seems ok until some nice security API happens. |
85 | */ | 85 | */ |
86 | static int is_sram_locked(void) | 86 | static int is_sram_locked(void) |
87 | { | 87 | { |
88 | if (OMAP2_DEVICE_TYPE_GP == omap_type()) { | 88 | if (OMAP2_DEVICE_TYPE_GP == omap_type()) { |
89 | /* RAMFW: R/W access to all initiators for all qualifier sets */ | 89 | /* RAMFW: R/W access to all initiators for all qualifier sets */ |
90 | if (cpu_is_omap242x()) { | 90 | if (cpu_is_omap242x()) { |
91 | __raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */ | 91 | __raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */ |
92 | __raw_writel(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */ | 92 | __raw_writel(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */ |
93 | __raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */ | 93 | __raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */ |
94 | } | 94 | } |
95 | if (cpu_is_omap34xx()) { | 95 | if (cpu_is_omap34xx()) { |
96 | __raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */ | 96 | __raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */ |
97 | __raw_writel(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */ | 97 | __raw_writel(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */ |
98 | __raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */ | 98 | __raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */ |
99 | __raw_writel(0x0, OMAP34XX_VA_ADDR_MATCH2); | 99 | __raw_writel(0x0, OMAP34XX_VA_ADDR_MATCH2); |
100 | __raw_writel(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0); | 100 | __raw_writel(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0); |
101 | } | 101 | } |
102 | return 0; | 102 | return 0; |
103 | } else | 103 | } else |
104 | return 1; /* assume locked with no PPA or security driver */ | 104 | return 1; /* assume locked with no PPA or security driver */ |
105 | } | 105 | } |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * The amount of SRAM depends on the core type. | 108 | * The amount of SRAM depends on the core type. |
109 | * Note that we cannot try to test for SRAM here because writes | 109 | * Note that we cannot try to test for SRAM here because writes |
110 | * to secure SRAM will hang the system. Also the SRAM is not | 110 | * to secure SRAM will hang the system. Also the SRAM is not |
111 | * yet mapped at this point. | 111 | * yet mapped at this point. |
112 | */ | 112 | */ |
113 | static void __init omap_detect_sram(void) | 113 | static void __init omap_detect_sram(void) |
114 | { | 114 | { |
115 | unsigned long reserved; | 115 | unsigned long reserved; |
116 | 116 | ||
117 | if (cpu_class_is_omap2()) { | 117 | if (cpu_class_is_omap2()) { |
118 | if (is_sram_locked()) { | 118 | if (is_sram_locked()) { |
119 | if (cpu_is_omap34xx()) { | 119 | if (cpu_is_omap34xx()) { |
120 | omap_sram_base = OMAP3_SRAM_PUB_VA; | 120 | omap_sram_base = OMAP3_SRAM_PUB_VA; |
121 | omap_sram_start = OMAP3_SRAM_PUB_PA; | 121 | omap_sram_start = OMAP3_SRAM_PUB_PA; |
122 | if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) || | 122 | if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) || |
123 | (omap_type() == OMAP2_DEVICE_TYPE_SEC)) { | 123 | (omap_type() == OMAP2_DEVICE_TYPE_SEC)) { |
124 | omap_sram_size = 0x7000; /* 28K */ | 124 | omap_sram_size = 0x7000; /* 28K */ |
125 | } else { | 125 | } else { |
126 | omap_sram_size = 0x8000; /* 32K */ | 126 | omap_sram_size = 0x8000; /* 32K */ |
127 | } | 127 | } |
128 | } else if (cpu_is_omap44xx()) { | 128 | } else if (cpu_is_omap44xx()) { |
129 | omap_sram_base = OMAP4_SRAM_PUB_VA; | 129 | omap_sram_base = OMAP4_SRAM_PUB_VA; |
130 | omap_sram_start = OMAP4_SRAM_PUB_PA; | 130 | omap_sram_start = OMAP4_SRAM_PUB_PA; |
131 | omap_sram_size = 0xa000; /* 40K */ | 131 | omap_sram_size = 0xa000; /* 40K */ |
132 | } else { | 132 | } else { |
133 | omap_sram_base = OMAP2_SRAM_PUB_VA; | 133 | omap_sram_base = OMAP2_SRAM_PUB_VA; |
134 | omap_sram_start = OMAP2_SRAM_PUB_PA; | 134 | omap_sram_start = OMAP2_SRAM_PUB_PA; |
135 | omap_sram_size = 0x800; /* 2K */ | 135 | omap_sram_size = 0x800; /* 2K */ |
136 | } | 136 | } |
137 | } else { | 137 | } else { |
138 | if (cpu_is_omap34xx()) { | 138 | if (cpu_is_omap34xx()) { |
139 | omap_sram_base = OMAP3_SRAM_VA; | 139 | omap_sram_base = OMAP3_SRAM_VA; |
140 | omap_sram_start = OMAP3_SRAM_PA; | 140 | omap_sram_start = OMAP3_SRAM_PA; |
141 | omap_sram_size = 0x10000; /* 64K */ | 141 | omap_sram_size = 0x10000; /* 64K */ |
142 | } else if (cpu_is_omap44xx()) { | 142 | } else if (cpu_is_omap44xx()) { |
143 | omap_sram_base = OMAP4_SRAM_VA; | 143 | omap_sram_base = OMAP4_SRAM_VA; |
144 | omap_sram_start = OMAP4_SRAM_PA; | 144 | omap_sram_start = OMAP4_SRAM_PA; |
145 | omap_sram_size = 0xe000; /* 56K */ | 145 | omap_sram_size = 0xe000; /* 56K */ |
146 | } else { | 146 | } else { |
147 | omap_sram_base = OMAP2_SRAM_VA; | 147 | omap_sram_base = OMAP2_SRAM_VA; |
148 | omap_sram_start = OMAP2_SRAM_PA; | 148 | omap_sram_start = OMAP2_SRAM_PA; |
149 | if (cpu_is_omap242x()) | 149 | if (cpu_is_omap242x()) |
150 | omap_sram_size = 0xa0000; /* 640K */ | 150 | omap_sram_size = 0xa0000; /* 640K */ |
151 | else if (cpu_is_omap243x()) | 151 | else if (cpu_is_omap243x()) |
152 | omap_sram_size = 0x10000; /* 64K */ | 152 | omap_sram_size = 0x10000; /* 64K */ |
153 | } | 153 | } |
154 | } | 154 | } |
155 | } else { | 155 | } else { |
156 | omap_sram_base = OMAP1_SRAM_VA; | 156 | omap_sram_base = OMAP1_SRAM_VA; |
157 | omap_sram_start = OMAP1_SRAM_PA; | 157 | omap_sram_start = OMAP1_SRAM_PA; |
158 | 158 | ||
159 | if (cpu_is_omap7xx()) | 159 | if (cpu_is_omap7xx()) |
160 | omap_sram_size = 0x32000; /* 200K */ | 160 | omap_sram_size = 0x32000; /* 200K */ |
161 | else if (cpu_is_omap15xx()) | 161 | else if (cpu_is_omap15xx()) |
162 | omap_sram_size = 0x30000; /* 192K */ | 162 | omap_sram_size = 0x30000; /* 192K */ |
163 | else if (cpu_is_omap1610() || cpu_is_omap1621() || | 163 | else if (cpu_is_omap1610() || cpu_is_omap1621() || |
164 | cpu_is_omap1710()) | 164 | cpu_is_omap1710()) |
165 | omap_sram_size = 0x4000; /* 16K */ | 165 | omap_sram_size = 0x4000; /* 16K */ |
166 | else if (cpu_is_omap1611()) | 166 | else if (cpu_is_omap1611()) |
167 | omap_sram_size = SZ_256K; | 167 | omap_sram_size = SZ_256K; |
168 | else { | 168 | else { |
169 | printk(KERN_ERR "Could not detect SRAM size\n"); | 169 | printk(KERN_ERR "Could not detect SRAM size\n"); |
170 | omap_sram_size = 0x4000; | 170 | omap_sram_size = 0x4000; |
171 | } | 171 | } |
172 | } | 172 | } |
173 | reserved = omapfb_reserve_sram(omap_sram_start, omap_sram_base, | 173 | reserved = omapfb_reserve_sram(omap_sram_start, omap_sram_base, |
174 | omap_sram_size, | 174 | omap_sram_size, |
175 | omap_sram_start + SRAM_BOOTLOADER_SZ, | 175 | omap_sram_start + SRAM_BOOTLOADER_SZ, |
176 | omap_sram_size - SRAM_BOOTLOADER_SZ); | 176 | omap_sram_size - SRAM_BOOTLOADER_SZ); |
177 | omap_sram_size -= reserved; | 177 | omap_sram_size -= reserved; |
178 | 178 | ||
179 | reserved = omap_vram_reserve_sram(omap_sram_start, omap_sram_base, | 179 | reserved = omap_vram_reserve_sram(omap_sram_start, omap_sram_base, |
180 | omap_sram_size, | 180 | omap_sram_size, |
181 | omap_sram_start + SRAM_BOOTLOADER_SZ, | 181 | omap_sram_start + SRAM_BOOTLOADER_SZ, |
182 | omap_sram_size - SRAM_BOOTLOADER_SZ); | 182 | omap_sram_size - SRAM_BOOTLOADER_SZ); |
183 | omap_sram_size -= reserved; | 183 | omap_sram_size -= reserved; |
184 | 184 | ||
185 | omap_sram_ceil = omap_sram_base + omap_sram_size; | 185 | omap_sram_ceil = omap_sram_base + omap_sram_size; |
186 | } | 186 | } |
187 | 187 | ||
188 | static struct map_desc omap_sram_io_desc[] __initdata = { | 188 | static struct map_desc omap_sram_io_desc[] __initdata = { |
189 | { /* .length gets filled in at runtime */ | 189 | { /* .length gets filled in at runtime */ |
190 | .virtual = OMAP1_SRAM_VA, | 190 | .virtual = OMAP1_SRAM_VA, |
191 | .pfn = __phys_to_pfn(OMAP1_SRAM_PA), | 191 | .pfn = __phys_to_pfn(OMAP1_SRAM_PA), |
192 | .type = MT_MEMORY | 192 | .type = MT_MEMORY |
193 | } | 193 | } |
194 | }; | 194 | }; |
195 | 195 | ||
196 | /* | 196 | /* |
197 | * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early. | 197 | * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early. |
198 | */ | 198 | */ |
199 | static void __init omap_map_sram(void) | 199 | static void __init omap_map_sram(void) |
200 | { | 200 | { |
201 | unsigned long base; | 201 | unsigned long base; |
202 | 202 | ||
203 | if (omap_sram_size == 0) | 203 | if (omap_sram_size == 0) |
204 | return; | 204 | return; |
205 | 205 | ||
206 | if (cpu_is_omap34xx()) { | 206 | if (cpu_is_omap34xx()) { |
207 | /* | 207 | /* |
208 | * SRAM must be marked as non-cached on OMAP3 since the | 208 | * SRAM must be marked as non-cached on OMAP3 since the |
209 | * CORE DPLL M2 divider change code (in SRAM) runs with the | 209 | * CORE DPLL M2 divider change code (in SRAM) runs with the |
210 | * SDRAM controller disabled, and if it is marked cached, | 210 | * SDRAM controller disabled, and if it is marked cached, |
211 | * the ARM may attempt to write cache lines back to SDRAM | 211 | * the ARM may attempt to write cache lines back to SDRAM |
212 | * which will cause the system to hang. | 212 | * which will cause the system to hang. |
213 | */ | 213 | */ |
214 | omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED; | 214 | omap_sram_io_desc[0].type = MT_MEMORY_NONCACHED; |
215 | } | 215 | } |
216 | 216 | ||
217 | omap_sram_io_desc[0].virtual = omap_sram_base; | 217 | omap_sram_io_desc[0].virtual = omap_sram_base; |
218 | base = omap_sram_start; | 218 | base = omap_sram_start; |
219 | base = ROUND_DOWN(base, PAGE_SIZE); | 219 | base = ROUND_DOWN(base, PAGE_SIZE); |
220 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); | 220 | omap_sram_io_desc[0].pfn = __phys_to_pfn(base); |
221 | omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE); | 221 | omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE); |
222 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); | 222 | iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc)); |
223 | 223 | ||
224 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", | 224 | printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n", |
225 | __pfn_to_phys(omap_sram_io_desc[0].pfn), | 225 | __pfn_to_phys(omap_sram_io_desc[0].pfn), |
226 | omap_sram_io_desc[0].virtual, | 226 | omap_sram_io_desc[0].virtual, |
227 | omap_sram_io_desc[0].length); | 227 | omap_sram_io_desc[0].length); |
228 | 228 | ||
229 | /* | 229 | /* |
230 | * Normally devicemaps_init() would flush caches and tlb after | 230 | * Normally devicemaps_init() would flush caches and tlb after |
231 | * mdesc->map_io(), but since we're called from map_io(), we | 231 | * mdesc->map_io(), but since we're called from map_io(), we |
232 | * must do it here. | 232 | * must do it here. |
233 | */ | 233 | */ |
234 | local_flush_tlb_all(); | 234 | local_flush_tlb_all(); |
235 | flush_cache_all(); | 235 | flush_cache_all(); |
236 | 236 | ||
237 | /* | 237 | /* |
238 | * Looks like we need to preserve some bootloader code at the | 238 | * Looks like we need to preserve some bootloader code at the |
239 | * beginning of SRAM for jumping to flash for reboot to work... | 239 | * beginning of SRAM for jumping to flash for reboot to work... |
240 | */ | 240 | */ |
241 | memset((void *)omap_sram_base + SRAM_BOOTLOADER_SZ, 0, | 241 | memset((void *)omap_sram_base + SRAM_BOOTLOADER_SZ, 0, |
242 | omap_sram_size - SRAM_BOOTLOADER_SZ); | 242 | omap_sram_size - SRAM_BOOTLOADER_SZ); |
243 | } | 243 | } |
244 | 244 | ||
245 | void * omap_sram_push(void * start, unsigned long size) | 245 | /* |
246 | * Memory allocator for SRAM: calculates the new ceiling address | ||
247 | * for pushing a function using the fncpy API. | ||
248 | * | ||
249 | * Note that fncpy requires the returned address to be aligned | ||
250 | * to an 8-byte boundary. | ||
251 | */ | ||
252 | void *omap_sram_push_address(unsigned long size) | ||
246 | { | 253 | { |
247 | if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) { | 254 | if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) { |
248 | printk(KERN_ERR "Not enough space in SRAM\n"); | 255 | printk(KERN_ERR "Not enough space in SRAM\n"); |
249 | return NULL; | 256 | return NULL; |
250 | } | 257 | } |
251 | 258 | ||
252 | omap_sram_ceil -= size; | 259 | omap_sram_ceil -= size; |
253 | omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *)); | 260 | omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, FNCPY_ALIGN); |
254 | memcpy((void *)omap_sram_ceil, start, size); | ||
255 | flush_icache_range((unsigned long)omap_sram_ceil, | ||
256 | (unsigned long)(omap_sram_ceil + size)); | ||
257 | 261 | ||
258 | return (void *)omap_sram_ceil; | 262 | return (void *)omap_sram_ceil; |
259 | } | 263 | } |
260 | 264 | ||
261 | #ifdef CONFIG_ARCH_OMAP1 | 265 | #ifdef CONFIG_ARCH_OMAP1 |
262 | 266 | ||
263 | static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl); | 267 | static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl); |
264 | 268 | ||
265 | void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) | 269 | void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl) |
266 | { | 270 | { |
267 | BUG_ON(!_omap_sram_reprogram_clock); | 271 | BUG_ON(!_omap_sram_reprogram_clock); |
268 | _omap_sram_reprogram_clock(dpllctl, ckctl); | 272 | _omap_sram_reprogram_clock(dpllctl, ckctl); |
269 | } | 273 | } |
270 | 274 | ||
271 | static int __init omap1_sram_init(void) | 275 | static int __init omap1_sram_init(void) |
272 | { | 276 | { |
273 | _omap_sram_reprogram_clock = | 277 | _omap_sram_reprogram_clock = |
274 | omap_sram_push(omap1_sram_reprogram_clock, | 278 | omap_sram_push(omap1_sram_reprogram_clock, |
275 | omap1_sram_reprogram_clock_sz); | 279 | omap1_sram_reprogram_clock_sz); |
276 | 280 | ||
277 | return 0; | 281 | return 0; |
278 | } | 282 | } |
279 | 283 | ||
280 | #else | 284 | #else |
281 | #define omap1_sram_init() do {} while (0) | 285 | #define omap1_sram_init() do {} while (0) |
282 | #endif | 286 | #endif |
283 | 287 | ||
284 | #if defined(CONFIG_ARCH_OMAP2) | 288 | #if defined(CONFIG_ARCH_OMAP2) |
285 | 289 | ||
286 | static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, | 290 | static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, |
287 | u32 base_cs, u32 force_unlock); | 291 | u32 base_cs, u32 force_unlock); |
288 | 292 | ||
289 | void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, | 293 | void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, |
290 | u32 base_cs, u32 force_unlock) | 294 | u32 base_cs, u32 force_unlock) |
291 | { | 295 | { |
292 | BUG_ON(!_omap2_sram_ddr_init); | 296 | BUG_ON(!_omap2_sram_ddr_init); |
293 | _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl, | 297 | _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl, |
294 | base_cs, force_unlock); | 298 | base_cs, force_unlock); |
295 | } | 299 | } |
296 | 300 | ||
297 | static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val, | 301 | static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val, |
298 | u32 mem_type); | 302 | u32 mem_type); |
299 | 303 | ||
300 | void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type) | 304 | void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type) |
301 | { | 305 | { |
302 | BUG_ON(!_omap2_sram_reprogram_sdrc); | 306 | BUG_ON(!_omap2_sram_reprogram_sdrc); |
303 | _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type); | 307 | _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type); |
304 | } | 308 | } |
305 | 309 | ||
306 | static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); | 310 | static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass); |
307 | 311 | ||
308 | u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass) | 312 | u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass) |
309 | { | 313 | { |
310 | BUG_ON(!_omap2_set_prcm); | 314 | BUG_ON(!_omap2_set_prcm); |
311 | return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass); | 315 | return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass); |
312 | } | 316 | } |
313 | #endif | 317 | #endif |
314 | 318 | ||
315 | #ifdef CONFIG_ARCH_OMAP2420 | 319 | #ifdef CONFIG_ARCH_OMAP2420 |
316 | static int __init omap242x_sram_init(void) | 320 | static int __init omap242x_sram_init(void) |
317 | { | 321 | { |
318 | _omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init, | 322 | _omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init, |
319 | omap242x_sram_ddr_init_sz); | 323 | omap242x_sram_ddr_init_sz); |
320 | 324 | ||
321 | _omap2_sram_reprogram_sdrc = omap_sram_push(omap242x_sram_reprogram_sdrc, | 325 | _omap2_sram_reprogram_sdrc = omap_sram_push(omap242x_sram_reprogram_sdrc, |
322 | omap242x_sram_reprogram_sdrc_sz); | 326 | omap242x_sram_reprogram_sdrc_sz); |
323 | 327 | ||
324 | _omap2_set_prcm = omap_sram_push(omap242x_sram_set_prcm, | 328 | _omap2_set_prcm = omap_sram_push(omap242x_sram_set_prcm, |
325 | omap242x_sram_set_prcm_sz); | 329 | omap242x_sram_set_prcm_sz); |
326 | 330 | ||
327 | return 0; | 331 | return 0; |
328 | } | 332 | } |
329 | #else | 333 | #else |
330 | static inline int omap242x_sram_init(void) | 334 | static inline int omap242x_sram_init(void) |
331 | { | 335 | { |
332 | return 0; | 336 | return 0; |
333 | } | 337 | } |
334 | #endif | 338 | #endif |
335 | 339 | ||
336 | #ifdef CONFIG_ARCH_OMAP2430 | 340 | #ifdef CONFIG_ARCH_OMAP2430 |
337 | static int __init omap243x_sram_init(void) | 341 | static int __init omap243x_sram_init(void) |
338 | { | 342 | { |
339 | _omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init, | 343 | _omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init, |
340 | omap243x_sram_ddr_init_sz); | 344 | omap243x_sram_ddr_init_sz); |
341 | 345 | ||
342 | _omap2_sram_reprogram_sdrc = omap_sram_push(omap243x_sram_reprogram_sdrc, | 346 | _omap2_sram_reprogram_sdrc = omap_sram_push(omap243x_sram_reprogram_sdrc, |
343 | omap243x_sram_reprogram_sdrc_sz); | 347 | omap243x_sram_reprogram_sdrc_sz); |
344 | 348 | ||
345 | _omap2_set_prcm = omap_sram_push(omap243x_sram_set_prcm, | 349 | _omap2_set_prcm = omap_sram_push(omap243x_sram_set_prcm, |
346 | omap243x_sram_set_prcm_sz); | 350 | omap243x_sram_set_prcm_sz); |
347 | 351 | ||
348 | return 0; | 352 | return 0; |
349 | } | 353 | } |
350 | #else | 354 | #else |
351 | static inline int omap243x_sram_init(void) | 355 | static inline int omap243x_sram_init(void) |
352 | { | 356 | { |
353 | return 0; | 357 | return 0; |
354 | } | 358 | } |
355 | #endif | 359 | #endif |
356 | 360 | ||
357 | #ifdef CONFIG_ARCH_OMAP3 | 361 | #ifdef CONFIG_ARCH_OMAP3 |
358 | 362 | ||
359 | static u32 (*_omap3_sram_configure_core_dpll)( | 363 | static u32 (*_omap3_sram_configure_core_dpll)( |
360 | u32 m2, u32 unlock_dll, u32 f, u32 inc, | 364 | u32 m2, u32 unlock_dll, u32 f, u32 inc, |
361 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, | 365 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, |
362 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, | 366 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, |
363 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, | 367 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, |
364 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); | 368 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1); |
365 | 369 | ||
366 | u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc, | 370 | u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc, |
367 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, | 371 | u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0, |
368 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, | 372 | u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0, |
369 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, | 373 | u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1, |
370 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1) | 374 | u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1) |
371 | { | 375 | { |
372 | BUG_ON(!_omap3_sram_configure_core_dpll); | 376 | BUG_ON(!_omap3_sram_configure_core_dpll); |
373 | return _omap3_sram_configure_core_dpll( | 377 | return _omap3_sram_configure_core_dpll( |
374 | m2, unlock_dll, f, inc, | 378 | m2, unlock_dll, f, inc, |
375 | sdrc_rfr_ctrl_0, sdrc_actim_ctrl_a_0, | 379 | sdrc_rfr_ctrl_0, sdrc_actim_ctrl_a_0, |
376 | sdrc_actim_ctrl_b_0, sdrc_mr_0, | 380 | sdrc_actim_ctrl_b_0, sdrc_mr_0, |
377 | sdrc_rfr_ctrl_1, sdrc_actim_ctrl_a_1, | 381 | sdrc_rfr_ctrl_1, sdrc_actim_ctrl_a_1, |
378 | sdrc_actim_ctrl_b_1, sdrc_mr_1); | 382 | sdrc_actim_ctrl_b_1, sdrc_mr_1); |
379 | } | 383 | } |
380 | 384 | ||
381 | #ifdef CONFIG_PM | 385 | #ifdef CONFIG_PM |
382 | void omap3_sram_restore_context(void) | 386 | void omap3_sram_restore_context(void) |
383 | { | 387 | { |
384 | omap_sram_ceil = omap_sram_base + omap_sram_size; | 388 | omap_sram_ceil = omap_sram_base + omap_sram_size; |
385 | 389 | ||
386 | _omap3_sram_configure_core_dpll = | 390 | _omap3_sram_configure_core_dpll = |
387 | omap_sram_push(omap3_sram_configure_core_dpll, | 391 | omap_sram_push(omap3_sram_configure_core_dpll, |
388 | omap3_sram_configure_core_dpll_sz); | 392 | omap3_sram_configure_core_dpll_sz); |
389 | omap_push_sram_idle(); | 393 | omap_push_sram_idle(); |
390 | } | 394 | } |
391 | #endif /* CONFIG_PM */ | 395 | #endif /* CONFIG_PM */ |
392 | 396 | ||
393 | static int __init omap34xx_sram_init(void) | 397 | static int __init omap34xx_sram_init(void) |
394 | { | 398 | { |
395 | _omap3_sram_configure_core_dpll = | 399 | _omap3_sram_configure_core_dpll = |
396 | omap_sram_push(omap3_sram_configure_core_dpll, | 400 | omap_sram_push(omap3_sram_configure_core_dpll, |
397 | omap3_sram_configure_core_dpll_sz); | 401 | omap3_sram_configure_core_dpll_sz); |
398 | omap_push_sram_idle(); | 402 | omap_push_sram_idle(); |
399 | return 0; | 403 | return 0; |
400 | } | 404 | } |
401 | #else | 405 | #else |
402 | static inline int omap34xx_sram_init(void) | 406 | static inline int omap34xx_sram_init(void) |
403 | { | 407 | { |
404 | return 0; | 408 | return 0; |
405 | } | 409 | } |
406 | #endif | 410 | #endif |
407 | 411 | ||
408 | #ifdef CONFIG_ARCH_OMAP4 | 412 | #ifdef CONFIG_ARCH_OMAP4 |
409 | static int __init omap44xx_sram_init(void) | 413 | static int __init omap44xx_sram_init(void) |
410 | { | 414 | { |
411 | printk(KERN_ERR "FIXME: %s not implemented\n", __func__); | 415 | printk(KERN_ERR "FIXME: %s not implemented\n", __func__); |
412 | 416 | ||
413 | return -ENODEV; | 417 | return -ENODEV; |
414 | } | 418 | } |
415 | #else | 419 | #else |
416 | static inline int omap44xx_sram_init(void) | 420 | static inline int omap44xx_sram_init(void) |
417 | { | 421 | { |
418 | return 0; | 422 | return 0; |
419 | } | 423 | } |
420 | #endif | 424 | #endif |
421 | 425 | ||
422 | int __init omap_sram_init(void) | 426 | int __init omap_sram_init(void) |
423 | { | 427 | { |
424 | omap_detect_sram(); | 428 | omap_detect_sram(); |
425 | omap_map_sram(); | 429 | omap_map_sram(); |
426 | 430 | ||
427 | if (!(cpu_class_is_omap2())) | 431 | if (!(cpu_class_is_omap2())) |
428 | omap1_sram_init(); | 432 | omap1_sram_init(); |
429 | else if (cpu_is_omap242x()) | 433 | else if (cpu_is_omap242x()) |
430 | omap242x_sram_init(); | 434 | omap242x_sram_init(); |
431 | else if (cpu_is_omap2430()) | 435 | else if (cpu_is_omap2430()) |
432 | omap243x_sram_init(); | 436 | omap243x_sram_init(); |
433 | else if (cpu_is_omap34xx()) | 437 | else if (cpu_is_omap34xx()) |
434 | omap34xx_sram_init(); | 438 | omap34xx_sram_init(); |
435 | else if (cpu_is_omap44xx()) | 439 | else if (cpu_is_omap44xx()) |
436 | omap44xx_sram_init(); | 440 | omap44xx_sram_init(); |
437 | 441 |