diff options
Diffstat (limited to 'arch/arm/mach-at91')
-rw-r--r-- | arch/arm/mach-at91/Kconfig | 9 | ||||
-rw-r--r-- | arch/arm/mach-at91/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-at91/at91sam9x5.c | 373 | ||||
-rw-r--r-- | arch/arm/mach-at91/board-dt.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-at91/clock.c | 83 | ||||
-rw-r--r-- | arch/arm/mach-at91/cpuidle.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/at91_pmc.h | 60 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/at91sam9x5.h | 80 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h | 53 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/entry-macro.S | 6 | ||||
-rw-r--r-- | arch/arm/mach-at91/include/mach/hardware.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-at91/pm.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-at91/pm.h | 73 |
13 files changed, 682 insertions, 82 deletions
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 0284e66c47f9..e55cdcbd81fb 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -102,6 +102,15 @@ config ARCH_AT91SAM9G45 | |||
102 | select HAVE_AT91_DBGU1 | 102 | select HAVE_AT91_DBGU1 |
103 | select AT91_SAM9G45_RESET | 103 | select AT91_SAM9G45_RESET |
104 | 104 | ||
105 | config ARCH_AT91SAM9X5 | ||
106 | bool "AT91SAM9x5 family" | ||
107 | select CPU_ARM926T | ||
108 | select GENERIC_CLOCKEVENTS | ||
109 | select HAVE_FB_ATMEL | ||
110 | select HAVE_NET_MACB | ||
111 | select HAVE_AT91_DBGU0 | ||
112 | select AT91_SAM9G45_RESET | ||
113 | |||
105 | config ARCH_AT91X40 | 114 | config ARCH_AT91X40 |
106 | bool "AT91x40" | 115 | bool "AT91x40" |
107 | select ARCH_USES_GETTIMEOFFSET | 116 | select ARCH_USES_GETTIMEOFFSET |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index aeb76f1690d9..1b6518518d99 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_d | |||
20 | obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o | 20 | obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o |
21 | obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o | 21 | obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o |
22 | obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o | 22 | obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o |
23 | obj-$(CONFIG_ARCH_AT91SAM9X5) += at91sam9x5.o at91sam926x_time.o | ||
23 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o | 24 | obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o |
24 | 25 | ||
25 | # AT91RM9200 board-specific support | 26 | # AT91RM9200 board-specific support |
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c new file mode 100644 index 000000000000..1c3444d2ee0c --- /dev/null +++ b/arch/arm/mach-at91/at91sam9x5.c | |||
@@ -0,0 +1,373 @@ | |||
1 | /* | ||
2 | * Chip-specific setup code for the AT91SAM9x5 family | ||
3 | * | ||
4 | * Copyright (C) 2010-2012 Atmel Corporation. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/dma-mapping.h> | ||
11 | |||
12 | #include <asm/irq.h> | ||
13 | #include <asm/mach/arch.h> | ||
14 | #include <asm/mach/map.h> | ||
15 | #include <mach/at91sam9x5.h> | ||
16 | #include <mach/at91_pmc.h> | ||
17 | #include <mach/cpu.h> | ||
18 | #include <mach/board.h> | ||
19 | |||
20 | #include "soc.h" | ||
21 | #include "generic.h" | ||
22 | #include "clock.h" | ||
23 | #include "sam9_smc.h" | ||
24 | |||
25 | /* -------------------------------------------------------------------- | ||
26 | * Clocks | ||
27 | * -------------------------------------------------------------------- */ | ||
28 | |||
29 | /* | ||
30 | * The peripheral clocks. | ||
31 | */ | ||
32 | static struct clk pioAB_clk = { | ||
33 | .name = "pioAB_clk", | ||
34 | .pmc_mask = 1 << AT91SAM9X5_ID_PIOAB, | ||
35 | .type = CLK_TYPE_PERIPHERAL, | ||
36 | }; | ||
37 | static struct clk pioCD_clk = { | ||
38 | .name = "pioCD_clk", | ||
39 | .pmc_mask = 1 << AT91SAM9X5_ID_PIOCD, | ||
40 | .type = CLK_TYPE_PERIPHERAL, | ||
41 | }; | ||
42 | static struct clk smd_clk = { | ||
43 | .name = "smd_clk", | ||
44 | .pmc_mask = 1 << AT91SAM9X5_ID_SMD, | ||
45 | .type = CLK_TYPE_PERIPHERAL, | ||
46 | }; | ||
47 | static struct clk usart0_clk = { | ||
48 | .name = "usart0_clk", | ||
49 | .pmc_mask = 1 << AT91SAM9X5_ID_USART0, | ||
50 | .type = CLK_TYPE_PERIPHERAL, | ||
51 | }; | ||
52 | static struct clk usart1_clk = { | ||
53 | .name = "usart1_clk", | ||
54 | .pmc_mask = 1 << AT91SAM9X5_ID_USART1, | ||
55 | .type = CLK_TYPE_PERIPHERAL, | ||
56 | }; | ||
57 | static struct clk usart2_clk = { | ||
58 | .name = "usart2_clk", | ||
59 | .pmc_mask = 1 << AT91SAM9X5_ID_USART2, | ||
60 | .type = CLK_TYPE_PERIPHERAL, | ||
61 | }; | ||
62 | /* USART3 clock - Only for sam9g25/sam9x25 */ | ||
63 | static struct clk usart3_clk = { | ||
64 | .name = "usart3_clk", | ||
65 | .pmc_mask = 1 << AT91SAM9X5_ID_USART3, | ||
66 | .type = CLK_TYPE_PERIPHERAL, | ||
67 | }; | ||
68 | static struct clk twi0_clk = { | ||
69 | .name = "twi0_clk", | ||
70 | .pmc_mask = 1 << AT91SAM9X5_ID_TWI0, | ||
71 | .type = CLK_TYPE_PERIPHERAL, | ||
72 | }; | ||
73 | static struct clk twi1_clk = { | ||
74 | .name = "twi1_clk", | ||
75 | .pmc_mask = 1 << AT91SAM9X5_ID_TWI1, | ||
76 | .type = CLK_TYPE_PERIPHERAL, | ||
77 | }; | ||
78 | static struct clk twi2_clk = { | ||
79 | .name = "twi2_clk", | ||
80 | .pmc_mask = 1 << AT91SAM9X5_ID_TWI2, | ||
81 | .type = CLK_TYPE_PERIPHERAL, | ||
82 | }; | ||
83 | static struct clk mmc0_clk = { | ||
84 | .name = "mci0_clk", | ||
85 | .pmc_mask = 1 << AT91SAM9X5_ID_MCI0, | ||
86 | .type = CLK_TYPE_PERIPHERAL, | ||
87 | }; | ||
88 | static struct clk spi0_clk = { | ||
89 | .name = "spi0_clk", | ||
90 | .pmc_mask = 1 << AT91SAM9X5_ID_SPI0, | ||
91 | .type = CLK_TYPE_PERIPHERAL, | ||
92 | }; | ||
93 | static struct clk spi1_clk = { | ||
94 | .name = "spi1_clk", | ||
95 | .pmc_mask = 1 << AT91SAM9X5_ID_SPI1, | ||
96 | .type = CLK_TYPE_PERIPHERAL, | ||
97 | }; | ||
98 | static struct clk uart0_clk = { | ||
99 | .name = "uart0_clk", | ||
100 | .pmc_mask = 1 << AT91SAM9X5_ID_UART0, | ||
101 | .type = CLK_TYPE_PERIPHERAL, | ||
102 | }; | ||
103 | static struct clk uart1_clk = { | ||
104 | .name = "uart1_clk", | ||
105 | .pmc_mask = 1 << AT91SAM9X5_ID_UART1, | ||
106 | .type = CLK_TYPE_PERIPHERAL, | ||
107 | }; | ||
108 | static struct clk tcb0_clk = { | ||
109 | .name = "tcb0_clk", | ||
110 | .pmc_mask = 1 << AT91SAM9X5_ID_TCB, | ||
111 | .type = CLK_TYPE_PERIPHERAL, | ||
112 | }; | ||
113 | static struct clk pwm_clk = { | ||
114 | .name = "pwm_clk", | ||
115 | .pmc_mask = 1 << AT91SAM9X5_ID_PWM, | ||
116 | .type = CLK_TYPE_PERIPHERAL, | ||
117 | }; | ||
118 | static struct clk adc_clk = { | ||
119 | .name = "adc_clk", | ||
120 | .pmc_mask = 1 << AT91SAM9X5_ID_ADC, | ||
121 | .type = CLK_TYPE_PERIPHERAL, | ||
122 | }; | ||
123 | static struct clk dma0_clk = { | ||
124 | .name = "dma0_clk", | ||
125 | .pmc_mask = 1 << AT91SAM9X5_ID_DMA0, | ||
126 | .type = CLK_TYPE_PERIPHERAL, | ||
127 | }; | ||
128 | static struct clk dma1_clk = { | ||
129 | .name = "dma1_clk", | ||
130 | .pmc_mask = 1 << AT91SAM9X5_ID_DMA1, | ||
131 | .type = CLK_TYPE_PERIPHERAL, | ||
132 | }; | ||
133 | static struct clk uhphs_clk = { | ||
134 | .name = "uhphs_clk", | ||
135 | .pmc_mask = 1 << AT91SAM9X5_ID_UHPHS, | ||
136 | .type = CLK_TYPE_PERIPHERAL, | ||
137 | }; | ||
138 | static struct clk udphs_clk = { | ||
139 | .name = "udphs_clk", | ||
140 | .pmc_mask = 1 << AT91SAM9X5_ID_UDPHS, | ||
141 | .type = CLK_TYPE_PERIPHERAL, | ||
142 | }; | ||
143 | /* emac0 clock - Only for sam9g25/sam9x25/sam9g35/sam9x35 */ | ||
144 | static struct clk macb0_clk = { | ||
145 | .name = "pclk", | ||
146 | .pmc_mask = 1 << AT91SAM9X5_ID_EMAC0, | ||
147 | .type = CLK_TYPE_PERIPHERAL, | ||
148 | }; | ||
149 | /* lcd clock - Only for sam9g15/sam9g35/sam9x35 */ | ||
150 | static struct clk lcdc_clk = { | ||
151 | .name = "lcdc_clk", | ||
152 | .pmc_mask = 1 << AT91SAM9X5_ID_LCDC, | ||
153 | .type = CLK_TYPE_PERIPHERAL, | ||
154 | }; | ||
155 | /* isi clock - Only for sam9g25 */ | ||
156 | static struct clk isi_clk = { | ||
157 | .name = "isi_clk", | ||
158 | .pmc_mask = 1 << AT91SAM9X5_ID_ISI, | ||
159 | .type = CLK_TYPE_PERIPHERAL, | ||
160 | }; | ||
161 | static struct clk mmc1_clk = { | ||
162 | .name = "mci1_clk", | ||
163 | .pmc_mask = 1 << AT91SAM9X5_ID_MCI1, | ||
164 | .type = CLK_TYPE_PERIPHERAL, | ||
165 | }; | ||
166 | /* emac1 clock - Only for sam9x25 */ | ||
167 | static struct clk macb1_clk = { | ||
168 | .name = "pclk", | ||
169 | .pmc_mask = 1 << AT91SAM9X5_ID_EMAC1, | ||
170 | .type = CLK_TYPE_PERIPHERAL, | ||
171 | }; | ||
172 | static struct clk ssc_clk = { | ||
173 | .name = "ssc_clk", | ||
174 | .pmc_mask = 1 << AT91SAM9X5_ID_SSC, | ||
175 | .type = CLK_TYPE_PERIPHERAL, | ||
176 | }; | ||
177 | /* can0 clock - Only for sam9x35 */ | ||
178 | static struct clk can0_clk = { | ||
179 | .name = "can0_clk", | ||
180 | .pmc_mask = 1 << AT91SAM9X5_ID_CAN0, | ||
181 | .type = CLK_TYPE_PERIPHERAL, | ||
182 | }; | ||
183 | /* can1 clock - Only for sam9x35 */ | ||
184 | static struct clk can1_clk = { | ||
185 | .name = "can1_clk", | ||
186 | .pmc_mask = 1 << AT91SAM9X5_ID_CAN1, | ||
187 | .type = CLK_TYPE_PERIPHERAL, | ||
188 | }; | ||
189 | |||
190 | static struct clk *periph_clocks[] __initdata = { | ||
191 | &pioAB_clk, | ||
192 | &pioCD_clk, | ||
193 | &smd_clk, | ||
194 | &usart0_clk, | ||
195 | &usart1_clk, | ||
196 | &usart2_clk, | ||
197 | &twi0_clk, | ||
198 | &twi1_clk, | ||
199 | &twi2_clk, | ||
200 | &mmc0_clk, | ||
201 | &spi0_clk, | ||
202 | &spi1_clk, | ||
203 | &uart0_clk, | ||
204 | &uart1_clk, | ||
205 | &tcb0_clk, | ||
206 | &pwm_clk, | ||
207 | &adc_clk, | ||
208 | &dma0_clk, | ||
209 | &dma1_clk, | ||
210 | &uhphs_clk, | ||
211 | &udphs_clk, | ||
212 | &mmc1_clk, | ||
213 | &ssc_clk, | ||
214 | // irq0 | ||
215 | }; | ||
216 | |||
217 | static struct clk_lookup periph_clocks_lookups[] = { | ||
218 | /* lookup table for DT entries */ | ||
219 | CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), | ||
220 | CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk), | ||
221 | CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk), | ||
222 | CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk), | ||
223 | CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), | ||
224 | CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk), | ||
225 | CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), | ||
226 | CLKDEV_CON_ID("pioA", &pioAB_clk), | ||
227 | CLKDEV_CON_ID("pioB", &pioAB_clk), | ||
228 | CLKDEV_CON_ID("pioC", &pioCD_clk), | ||
229 | CLKDEV_CON_ID("pioD", &pioCD_clk), | ||
230 | /* additional fake clock for macb_hclk */ | ||
231 | CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk), | ||
232 | CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk), | ||
233 | }; | ||
234 | |||
235 | /* | ||
236 | * The two programmable clocks. | ||
237 | * You must configure pin multiplexing to bring these signals out. | ||
238 | */ | ||
239 | static struct clk pck0 = { | ||
240 | .name = "pck0", | ||
241 | .pmc_mask = AT91_PMC_PCK0, | ||
242 | .type = CLK_TYPE_PROGRAMMABLE, | ||
243 | .id = 0, | ||
244 | }; | ||
245 | static struct clk pck1 = { | ||
246 | .name = "pck1", | ||
247 | .pmc_mask = AT91_PMC_PCK1, | ||
248 | .type = CLK_TYPE_PROGRAMMABLE, | ||
249 | .id = 1, | ||
250 | }; | ||
251 | |||
252 | static void __init at91sam9x5_register_clocks(void) | ||
253 | { | ||
254 | int i; | ||
255 | |||
256 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | ||
257 | clk_register(periph_clocks[i]); | ||
258 | |||
259 | clkdev_add_table(periph_clocks_lookups, | ||
260 | ARRAY_SIZE(periph_clocks_lookups)); | ||
261 | |||
262 | if (cpu_is_at91sam9g25() | ||
263 | || cpu_is_at91sam9x25()) | ||
264 | clk_register(&usart3_clk); | ||
265 | |||
266 | if (cpu_is_at91sam9g25() | ||
267 | || cpu_is_at91sam9x25() | ||
268 | || cpu_is_at91sam9g35() | ||
269 | || cpu_is_at91sam9x35()) | ||
270 | clk_register(&macb0_clk); | ||
271 | |||
272 | if (cpu_is_at91sam9g15() | ||
273 | || cpu_is_at91sam9g35() | ||
274 | || cpu_is_at91sam9x35()) | ||
275 | clk_register(&lcdc_clk); | ||
276 | |||
277 | if (cpu_is_at91sam9g25()) | ||
278 | clk_register(&isi_clk); | ||
279 | |||
280 | if (cpu_is_at91sam9x25()) | ||
281 | clk_register(&macb1_clk); | ||
282 | |||
283 | if (cpu_is_at91sam9x25() | ||
284 | || cpu_is_at91sam9x35()) { | ||
285 | clk_register(&can0_clk); | ||
286 | clk_register(&can1_clk); | ||
287 | } | ||
288 | |||
289 | clk_register(&pck0); | ||
290 | clk_register(&pck1); | ||
291 | } | ||
292 | |||
293 | /* -------------------------------------------------------------------- | ||
294 | * AT91SAM9x5 processor initialization | ||
295 | * -------------------------------------------------------------------- */ | ||
296 | |||
297 | static void __init at91sam9x5_map_io(void) | ||
298 | { | ||
299 | at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE); | ||
300 | } | ||
301 | |||
302 | static void __init at91sam9x5_ioremap_registers(void) | ||
303 | { | ||
304 | if (of_at91sam926x_pit_init() < 0) | ||
305 | panic("Impossible to find PIT\n"); | ||
306 | } | ||
307 | |||
308 | void __init at91sam9x5_initialize(void) | ||
309 | { | ||
310 | arm_pm_restart = at91sam9g45_restart; | ||
311 | at91_extern_irq = (1 << AT91SAM9X5_ID_IRQ0); | ||
312 | |||
313 | /* Register GPIO subsystem (using DT) */ | ||
314 | at91_gpio_init(NULL, 0); | ||
315 | } | ||
316 | |||
317 | /* -------------------------------------------------------------------- | ||
318 | * AT91SAM9x5 devices (temporary before modification of code) | ||
319 | * -------------------------------------------------------------------- */ | ||
320 | void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} | ||
321 | void __init at91_set_serial_console(unsigned portnr) {} | ||
322 | struct platform_device *atmel_default_console_device = NULL; | ||
323 | |||
324 | void __init at91_add_device_nand(struct atmel_nand_data *data) {} | ||
325 | |||
326 | /* -------------------------------------------------------------------- | ||
327 | * Interrupt initialization | ||
328 | * -------------------------------------------------------------------- */ | ||
329 | /* | ||
330 | * The default interrupt priority levels (0 = lowest, 7 = highest). | ||
331 | */ | ||
332 | static unsigned int at91sam9x5_default_irq_priority[NR_AIC_IRQS] __initdata = { | ||
333 | 7, /* Advanced Interrupt Controller (FIQ) */ | ||
334 | 7, /* System Peripherals */ | ||
335 | 1, /* Parallel IO Controller A and B */ | ||
336 | 1, /* Parallel IO Controller C and D */ | ||
337 | 4, /* Soft Modem */ | ||
338 | 5, /* USART 0 */ | ||
339 | 5, /* USART 1 */ | ||
340 | 5, /* USART 2 */ | ||
341 | 5, /* USART 3 */ | ||
342 | 6, /* Two-Wire Interface 0 */ | ||
343 | 6, /* Two-Wire Interface 1 */ | ||
344 | 6, /* Two-Wire Interface 2 */ | ||
345 | 0, /* Multimedia Card Interface 0 */ | ||
346 | 5, /* Serial Peripheral Interface 0 */ | ||
347 | 5, /* Serial Peripheral Interface 1 */ | ||
348 | 5, /* UART 0 */ | ||
349 | 5, /* UART 1 */ | ||
350 | 0, /* Timer Counter 0, 1, 2, 3, 4 and 5 */ | ||
351 | 0, /* Pulse Width Modulation Controller */ | ||
352 | 0, /* ADC Controller */ | ||
353 | 0, /* DMA Controller 0 */ | ||
354 | 0, /* DMA Controller 1 */ | ||
355 | 2, /* USB Host High Speed port */ | ||
356 | 2, /* USB Device High speed port */ | ||
357 | 3, /* Ethernet MAC 0 */ | ||
358 | 3, /* LDC Controller or Image Sensor Interface */ | ||
359 | 0, /* Multimedia Card Interface 1 */ | ||
360 | 3, /* Ethernet MAC 1 */ | ||
361 | 4, /* Synchronous Serial Interface */ | ||
362 | 4, /* CAN Controller 0 */ | ||
363 | 4, /* CAN Controller 1 */ | ||
364 | 0, /* Advanced Interrupt Controller (IRQ0) */ | ||
365 | }; | ||
366 | |||
367 | struct at91_init_soc __initdata at91sam9x5_soc = { | ||
368 | .map_io = at91sam9x5_map_io, | ||
369 | .default_irq_priority = at91sam9x5_default_irq_priority, | ||
370 | .ioremap_registers = at91sam9x5_ioremap_registers, | ||
371 | .register_clocks = at91sam9x5_register_clocks, | ||
372 | .init = at91sam9x5_initialize, | ||
373 | }; | ||
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c index bb6b434ec0c1..05793156d178 100644 --- a/arch/arm/mach-at91/board-dt.c +++ b/arch/arm/mach-at91/board-dt.c | |||
@@ -109,6 +109,7 @@ static void __init at91_dt_device_init(void) | |||
109 | 109 | ||
110 | static const char *at91_dt_board_compat[] __initdata = { | 110 | static const char *at91_dt_board_compat[] __initdata = { |
111 | "atmel,at91sam9m10g45ek", | 111 | "atmel,at91sam9m10g45ek", |
112 | "atmel,at91sam9x5ek", | ||
112 | "calao,usb-a9g20", | 113 | "calao,usb-a9g20", |
113 | NULL | 114 | NULL |
114 | }; | 115 | }; |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index aa04e22a9da6..a5291e0e7004 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
@@ -48,24 +48,37 @@ | |||
48 | * Chips have some kind of clocks : group them by functionality | 48 | * Chips have some kind of clocks : group them by functionality |
49 | */ | 49 | */ |
50 | #define cpu_has_utmi() ( cpu_is_at91sam9rl() \ | 50 | #define cpu_has_utmi() ( cpu_is_at91sam9rl() \ |
51 | || cpu_is_at91sam9g45()) | 51 | || cpu_is_at91sam9g45() \ |
52 | || cpu_is_at91sam9x5()) | ||
52 | 53 | ||
53 | #define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ | 54 | #define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \ |
54 | || cpu_is_at91sam9g45()) | 55 | || cpu_is_at91sam9g45() \ |
56 | || cpu_is_at91sam9x5()) | ||
55 | 57 | ||
56 | #define cpu_has_300M_plla() (cpu_is_at91sam9g10()) | 58 | #define cpu_has_300M_plla() (cpu_is_at91sam9g10()) |
57 | 59 | ||
58 | #define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ | 60 | #define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ |
59 | || cpu_is_at91sam9g45())) | 61 | || cpu_is_at91sam9g45() \ |
62 | || cpu_is_at91sam9x5())) | ||
60 | 63 | ||
61 | #define cpu_has_upll() (cpu_is_at91sam9g45()) | 64 | #define cpu_has_upll() (cpu_is_at91sam9g45() \ |
65 | || cpu_is_at91sam9x5()) | ||
62 | 66 | ||
63 | /* USB host HS & FS */ | 67 | /* USB host HS & FS */ |
64 | #define cpu_has_uhp() (!cpu_is_at91sam9rl()) | 68 | #define cpu_has_uhp() (!cpu_is_at91sam9rl()) |
65 | 69 | ||
66 | /* USB device FS only */ | 70 | /* USB device FS only */ |
67 | #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ | 71 | #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ |
68 | || cpu_is_at91sam9g45())) | 72 | || cpu_is_at91sam9g45() \ |
73 | || cpu_is_at91sam9x5())) | ||
74 | |||
75 | #define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ | ||
76 | || cpu_is_at91sam9x5()) | ||
77 | |||
78 | #define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ | ||
79 | || cpu_is_at91sam9x5()) | ||
80 | |||
81 | #define cpu_has_alt_prescaler() (cpu_is_at91sam9x5()) | ||
69 | 82 | ||
70 | static LIST_HEAD(clocks); | 83 | static LIST_HEAD(clocks); |
71 | static DEFINE_SPINLOCK(clk_lock); | 84 | static DEFINE_SPINLOCK(clk_lock); |
@@ -138,13 +151,6 @@ static void pmc_uckr_mode(struct clk *clk, int is_on) | |||
138 | { | 151 | { |
139 | unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); | 152 | unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); |
140 | 153 | ||
141 | if (cpu_is_at91sam9g45()) { | ||
142 | if (is_on) | ||
143 | uckr |= AT91_PMC_BIASEN; | ||
144 | else | ||
145 | uckr &= ~AT91_PMC_BIASEN; | ||
146 | } | ||
147 | |||
148 | if (is_on) { | 154 | if (is_on) { |
149 | is_on = AT91_PMC_LOCKU; | 155 | is_on = AT91_PMC_LOCKU; |
150 | at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); | 156 | at91_sys_write(AT91_CKGR_UCKR, uckr | clk->pmc_mask); |
@@ -209,11 +215,24 @@ static struct clk __init *at91_css_to_clk(unsigned long css) | |||
209 | return &utmi_clk; | 215 | return &utmi_clk; |
210 | else if (cpu_has_pllb()) | 216 | else if (cpu_has_pllb()) |
211 | return &pllb; | 217 | return &pllb; |
218 | break; | ||
219 | /* alternate PMC: can use master clock */ | ||
220 | case AT91_PMC_CSS_MASTER: | ||
221 | return &mck; | ||
212 | } | 222 | } |
213 | 223 | ||
214 | return NULL; | 224 | return NULL; |
215 | } | 225 | } |
216 | 226 | ||
227 | static int pmc_prescaler_divider(u32 reg) | ||
228 | { | ||
229 | if (cpu_has_alt_prescaler()) { | ||
230 | return 1 << ((reg & AT91_PMC_ALT_PRES) >> PMC_ALT_PRES_OFFSET); | ||
231 | } else { | ||
232 | return 1 << ((reg & AT91_PMC_PRES) >> PMC_PRES_OFFSET); | ||
233 | } | ||
234 | } | ||
235 | |||
217 | static void __clk_enable(struct clk *clk) | 236 | static void __clk_enable(struct clk *clk) |
218 | { | 237 | { |
219 | if (clk->parent) | 238 | if (clk->parent) |
@@ -315,12 +334,22 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
315 | { | 334 | { |
316 | unsigned long flags; | 335 | unsigned long flags; |
317 | unsigned prescale; | 336 | unsigned prescale; |
337 | unsigned long prescale_offset, css_mask; | ||
318 | unsigned long actual; | 338 | unsigned long actual; |
319 | 339 | ||
320 | if (!clk_is_programmable(clk)) | 340 | if (!clk_is_programmable(clk)) |
321 | return -EINVAL; | 341 | return -EINVAL; |
322 | if (clk->users) | 342 | if (clk->users) |
323 | return -EBUSY; | 343 | return -EBUSY; |
344 | |||
345 | if (cpu_has_alt_prescaler()) { | ||
346 | prescale_offset = PMC_ALT_PRES_OFFSET; | ||
347 | css_mask = AT91_PMC_ALT_PCKR_CSS; | ||
348 | } else { | ||
349 | prescale_offset = PMC_PRES_OFFSET; | ||
350 | css_mask = AT91_PMC_CSS; | ||
351 | } | ||
352 | |||
324 | spin_lock_irqsave(&clk_lock, flags); | 353 | spin_lock_irqsave(&clk_lock, flags); |
325 | 354 | ||
326 | actual = clk->parent->rate_hz; | 355 | actual = clk->parent->rate_hz; |
@@ -329,8 +358,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
329 | u32 pckr; | 358 | u32 pckr; |
330 | 359 | ||
331 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); | 360 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); |
332 | pckr &= AT91_PMC_CSS; /* clock selection */ | 361 | pckr &= css_mask; /* keep clock selection */ |
333 | pckr |= prescale << 2; | 362 | pckr |= prescale << prescale_offset; |
334 | at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); | 363 | at91_sys_write(AT91_PMC_PCKR(clk->id), pckr); |
335 | clk->rate_hz = actual; | 364 | clk->rate_hz = actual; |
336 | break; | 365 | break; |
@@ -377,11 +406,17 @@ static void __init init_programmable_clock(struct clk *clk) | |||
377 | { | 406 | { |
378 | struct clk *parent; | 407 | struct clk *parent; |
379 | u32 pckr; | 408 | u32 pckr; |
409 | unsigned int css_mask; | ||
410 | |||
411 | if (cpu_has_alt_prescaler()) | ||
412 | css_mask = AT91_PMC_ALT_PCKR_CSS; | ||
413 | else | ||
414 | css_mask = AT91_PMC_CSS; | ||
380 | 415 | ||
381 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); | 416 | pckr = at91_sys_read(AT91_PMC_PCKR(clk->id)); |
382 | parent = at91_css_to_clk(pckr & AT91_PMC_CSS); | 417 | parent = at91_css_to_clk(pckr & css_mask); |
383 | clk->parent = parent; | 418 | clk->parent = parent; |
384 | clk->rate_hz = parent->rate_hz / (1 << ((pckr & AT91_PMC_PRES) >> 2)); | 419 | clk->rate_hz = parent->rate_hz / pmc_prescaler_divider(pckr); |
385 | } | 420 | } |
386 | 421 | ||
387 | #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ | 422 | #endif /* CONFIG_AT91_PROGRAMMABLE_CLOCKS */ |
@@ -663,7 +698,7 @@ int __init at91_clock_init(unsigned long main_clock) | |||
663 | if (pll_overclock) | 698 | if (pll_overclock) |
664 | pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); | 699 | pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); |
665 | 700 | ||
666 | if (cpu_is_at91sam9g45()) { | 701 | if (cpu_has_plladiv2()) { |
667 | mckr = at91_sys_read(AT91_PMC_MCKR); | 702 | mckr = at91_sys_read(AT91_PMC_MCKR); |
668 | plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */ | 703 | plla.rate_hz /= (1 << ((mckr & AT91_PMC_PLLADIV2) >> 12)); /* plla divisor by 2 */ |
669 | } | 704 | } |
@@ -685,6 +720,10 @@ int __init at91_clock_init(unsigned long main_clock) | |||
685 | * (obtain the USB High Speed 480 MHz when input is 12 MHz) | 720 | * (obtain the USB High Speed 480 MHz when input is 12 MHz) |
686 | */ | 721 | */ |
687 | utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz; | 722 | utmi_clk.rate_hz = 40 * utmi_clk.parent->rate_hz; |
723 | |||
724 | /* UTMI bias and PLL are managed at the same time */ | ||
725 | if (cpu_has_upll()) | ||
726 | utmi_clk.pmc_mask |= AT91_PMC_BIASEN; | ||
688 | } | 727 | } |
689 | 728 | ||
690 | /* | 729 | /* |
@@ -703,7 +742,7 @@ int __init at91_clock_init(unsigned long main_clock) | |||
703 | mckr = at91_sys_read(AT91_PMC_MCKR); | 742 | mckr = at91_sys_read(AT91_PMC_MCKR); |
704 | mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); | 743 | mck.parent = at91_css_to_clk(mckr & AT91_PMC_CSS); |
705 | freq = mck.parent->rate_hz; | 744 | freq = mck.parent->rate_hz; |
706 | freq /= (1 << ((mckr & AT91_PMC_PRES) >> 2)); /* prescale */ | 745 | freq /= pmc_prescaler_divider(mckr); /* prescale */ |
707 | if (cpu_is_at91rm9200()) { | 746 | if (cpu_is_at91rm9200()) { |
708 | mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ | 747 | mck.rate_hz = freq / (1 + ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ |
709 | } else if (cpu_is_at91sam9g20()) { | 748 | } else if (cpu_is_at91sam9g20()) { |
@@ -711,13 +750,19 @@ int __init at91_clock_init(unsigned long main_clock) | |||
711 | freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ | 750 | freq / ((mckr & AT91_PMC_MDIV) >> 7) : freq; /* mdiv ; (x >> 7) = ((x >> 8) * 2) */ |
712 | if (mckr & AT91_PMC_PDIV) | 751 | if (mckr & AT91_PMC_PDIV) |
713 | freq /= 2; /* processor clock division */ | 752 | freq /= 2; /* processor clock division */ |
714 | } else if (cpu_is_at91sam9g45()) { | 753 | } else if (cpu_has_mdiv3()) { |
715 | mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? | 754 | mck.rate_hz = (mckr & AT91_PMC_MDIV) == AT91SAM9_PMC_MDIV_3 ? |
716 | freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ | 755 | freq / 3 : freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ |
717 | } else { | 756 | } else { |
718 | mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ | 757 | mck.rate_hz = freq / (1 << ((mckr & AT91_PMC_MDIV) >> 8)); /* mdiv */ |
719 | } | 758 | } |
720 | 759 | ||
760 | if (cpu_has_alt_prescaler()) { | ||
761 | /* Programmable clocks can use MCK */ | ||
762 | mck.type |= CLK_TYPE_PRIMARY; | ||
763 | mck.id = 4; | ||
764 | } | ||
765 | |||
721 | /* Register the PMC's standard clocks */ | 766 | /* Register the PMC's standard clocks */ |
722 | for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) | 767 | for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++) |
723 | at91_clk_add(standard_pmc_clocks[i]); | 768 | at91_clk_add(standard_pmc_clocks[i]); |
diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c index a851e6c98421..555d956b3a57 100644 --- a/arch/arm/mach-at91/cpuidle.c +++ b/arch/arm/mach-at91/cpuidle.c | |||
@@ -39,20 +39,15 @@ static int at91_enter_idle(struct cpuidle_device *dev, | |||
39 | { | 39 | { |
40 | struct timeval before, after; | 40 | struct timeval before, after; |
41 | int idle_time; | 41 | int idle_time; |
42 | u32 saved_lpr; | ||
43 | 42 | ||
44 | local_irq_disable(); | 43 | local_irq_disable(); |
45 | do_gettimeofday(&before); | 44 | do_gettimeofday(&before); |
46 | if (index == 0) | 45 | if (index == 0) |
47 | /* Wait for interrupt state */ | 46 | /* Wait for interrupt state */ |
48 | cpu_do_idle(); | 47 | cpu_do_idle(); |
49 | else if (index == 1) { | 48 | else if (index == 1) |
50 | asm("b 1f; .align 5; 1:"); | 49 | at91_standby(); |
51 | asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ | 50 | |
52 | saved_lpr = sdram_selfrefresh_enable(); | ||
53 | cpu_do_idle(); | ||
54 | sdram_selfrefresh_disable(saved_lpr); | ||
55 | } | ||
56 | do_gettimeofday(&after); | 51 | do_gettimeofday(&after); |
57 | local_irq_enable(); | 52 | local_irq_enable(); |
58 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + | 53 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + |
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index dbdd6ae473d5..f9fdbbe0c53a 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h | |||
@@ -45,9 +45,13 @@ | |||
45 | #define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */ | 45 | #define AT91_PMC_BIASCOUNT (0xf << 28) /* UTMI BIAS Start-up Time */ |
46 | 46 | ||
47 | #define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */ | 47 | #define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */ |
48 | #define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ | 48 | #define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */ |
49 | #define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x] */ | 49 | #define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass */ |
50 | #define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ | 50 | #define AT91_PMC_MOSCRCEN (1 << 3) /* Main On-Chip RC Oscillator Enable [some SAM9] */ |
51 | #define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ | ||
52 | #define AT91_PMC_KEY (0x37 << 16) /* MOR Writing Key */ | ||
53 | #define AT91_PMC_MOSCSEL (1 << 24) /* Main Oscillator Selection [some SAM9] */ | ||
54 | #define AT91_PMC_CFDEN (1 << 25) /* Clock Failure Detector Enable [some SAM9] */ | ||
51 | 55 | ||
52 | #define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */ | 56 | #define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */ |
53 | #define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */ | 57 | #define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */ |
@@ -72,14 +76,24 @@ | |||
72 | #define AT91_PMC_CSS_PLLA (2 << 0) | 76 | #define AT91_PMC_CSS_PLLA (2 << 0) |
73 | #define AT91_PMC_CSS_PLLB (3 << 0) | 77 | #define AT91_PMC_CSS_PLLB (3 << 0) |
74 | #define AT91_PMC_CSS_UPLL (3 << 0) /* [some SAM9 only] */ | 78 | #define AT91_PMC_CSS_UPLL (3 << 0) /* [some SAM9 only] */ |
75 | #define AT91_PMC_PRES (7 << 2) /* Master Clock Prescaler */ | 79 | #define PMC_PRES_OFFSET 2 |
76 | #define AT91_PMC_PRES_1 (0 << 2) | 80 | #define AT91_PMC_PRES (7 << PMC_PRES_OFFSET) /* Master Clock Prescaler */ |
77 | #define AT91_PMC_PRES_2 (1 << 2) | 81 | #define AT91_PMC_PRES_1 (0 << PMC_PRES_OFFSET) |
78 | #define AT91_PMC_PRES_4 (2 << 2) | 82 | #define AT91_PMC_PRES_2 (1 << PMC_PRES_OFFSET) |
79 | #define AT91_PMC_PRES_8 (3 << 2) | 83 | #define AT91_PMC_PRES_4 (2 << PMC_PRES_OFFSET) |
80 | #define AT91_PMC_PRES_16 (4 << 2) | 84 | #define AT91_PMC_PRES_8 (3 << PMC_PRES_OFFSET) |
81 | #define AT91_PMC_PRES_32 (5 << 2) | 85 | #define AT91_PMC_PRES_16 (4 << PMC_PRES_OFFSET) |
82 | #define AT91_PMC_PRES_64 (6 << 2) | 86 | #define AT91_PMC_PRES_32 (5 << PMC_PRES_OFFSET) |
87 | #define AT91_PMC_PRES_64 (6 << PMC_PRES_OFFSET) | ||
88 | #define PMC_ALT_PRES_OFFSET 4 | ||
89 | #define AT91_PMC_ALT_PRES (7 << PMC_ALT_PRES_OFFSET) /* Master Clock Prescaler [alternate location] */ | ||
90 | #define AT91_PMC_ALT_PRES_1 (0 << PMC_ALT_PRES_OFFSET) | ||
91 | #define AT91_PMC_ALT_PRES_2 (1 << PMC_ALT_PRES_OFFSET) | ||
92 | #define AT91_PMC_ALT_PRES_4 (2 << PMC_ALT_PRES_OFFSET) | ||
93 | #define AT91_PMC_ALT_PRES_8 (3 << PMC_ALT_PRES_OFFSET) | ||
94 | #define AT91_PMC_ALT_PRES_16 (4 << PMC_ALT_PRES_OFFSET) | ||
95 | #define AT91_PMC_ALT_PRES_32 (5 << PMC_ALT_PRES_OFFSET) | ||
96 | #define AT91_PMC_ALT_PRES_64 (6 << PMC_ALT_PRES_OFFSET) | ||
83 | #define AT91_PMC_MDIV (3 << 8) /* Master Clock Division */ | 97 | #define AT91_PMC_MDIV (3 << 8) /* Master Clock Division */ |
84 | #define AT91RM9200_PMC_MDIV_1 (0 << 8) /* [AT91RM9200 only] */ | 98 | #define AT91RM9200_PMC_MDIV_1 (0 << 8) /* [AT91RM9200 only] */ |
85 | #define AT91RM9200_PMC_MDIV_2 (1 << 8) | 99 | #define AT91RM9200_PMC_MDIV_2 (1 << 8) |
@@ -103,7 +117,14 @@ | |||
103 | #define AT91_PMC_USBS_UPLL (1 << 0) | 117 | #define AT91_PMC_USBS_UPLL (1 << 0) |
104 | #define AT91_PMC_OHCIUSBDIV (0xF << 8) /* Divider for USB OHCI Clock */ | 118 | #define AT91_PMC_OHCIUSBDIV (0xF << 8) /* Divider for USB OHCI Clock */ |
105 | 119 | ||
120 | #define AT91_PMC_SMD (AT91_PMC + 0x3c) /* Soft Modem Clock Register [some SAM9 only] */ | ||
121 | #define AT91_PMC_SMDS (0x1 << 0) /* SMD input clock selection */ | ||
122 | #define AT91_PMC_SMD_DIV (0x1f << 8) /* SMD input clock divider */ | ||
123 | #define AT91_PMC_SMDDIV(n) (((n) << 8) & AT91_PMC_SMD_DIV) | ||
124 | |||
106 | #define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */ | 125 | #define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-N Registers */ |
126 | #define AT91_PMC_ALT_PCKR_CSS (0x7 << 0) /* Programmable Clock Source Selection [alternate length] */ | ||
127 | #define AT91_PMC_CSS_MASTER (4 << 0) /* [some SAM9 only] */ | ||
107 | #define AT91_PMC_CSSMCK (0x1 << 8) /* CSS or Master Clock Selection */ | 128 | #define AT91_PMC_CSSMCK (0x1 << 8) /* CSS or Master Clock Selection */ |
108 | #define AT91_PMC_CSSMCK_CSS (0 << 8) | 129 | #define AT91_PMC_CSSMCK_CSS (0 << 8) |
109 | #define AT91_PMC_CSSMCK_MCK (1 << 8) | 130 | #define AT91_PMC_CSSMCK_MCK (1 << 8) |
@@ -120,10 +141,25 @@ | |||
120 | #define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ | 141 | #define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */ |
121 | #define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */ | 142 | #define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */ |
122 | #define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */ | 143 | #define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */ |
144 | #define AT91_PMC_MOSCSELS (1 << 16) /* Main Oscillator Selection [some SAM9] */ | ||
145 | #define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */ | ||
146 | #define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */ | ||
123 | #define AT91_PMC_IMR (AT91_PMC + 0x6c) /* Interrupt Mask Register */ | 147 | #define AT91_PMC_IMR (AT91_PMC + 0x6c) /* Interrupt Mask Register */ |
124 | 148 | ||
125 | #define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Write Protect Mode Register [some SAM9] */ | 149 | #define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Write Protect Mode Register [some SAM9] */ |
126 | #define AT91_PMC_PROTKEY 0x504d4301 /* Activation Code */ | 150 | #define AT91_PMC_WPEN (0x1 << 0) /* Write Protect Enable */ |
151 | #define AT91_PMC_WPKEY (0xffffff << 8) /* Write Protect Key */ | ||
152 | #define AT91_PMC_PROTKEY (0x504d43 << 8) /* Activation Code */ | ||
153 | |||
154 | #define AT91_PMC_WPSR (AT91_PMC + 0xe8) /* Write Protect Status Register [some SAM9] */ | ||
155 | #define AT91_PMC_WPVS (0x1 << 0) /* Write Protect Violation Status */ | ||
156 | #define AT91_PMC_WPVSRC (0xffff << 8) /* Write Protect Violation Source */ | ||
127 | 157 | ||
158 | #define AT91_PMC_PCR (AT91_PMC + 0x10c) /* Peripheral Control Register [some SAM9] */ | ||
159 | #define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */ | ||
160 | #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command */ | ||
161 | #define AT91_PMC_PCR_DIV (0x3 << 16) /* Divisor Value */ | ||
162 | #define AT91_PMC_PCRDIV(n) (((n) << 16) & AT91_PMC_PCR_DIV) | ||
163 | #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ | ||
128 | 164 | ||
129 | #endif | 165 | #endif |
diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5.h b/arch/arm/mach-at91/include/mach/at91sam9x5.h new file mode 100644 index 000000000000..8476871a2f9f --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9x5.h | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * Chip-specific header file for the AT91SAM9x5 family | ||
3 | * | ||
4 | * Copyright (C) 2009-2012 Atmel Corporation. | ||
5 | * | ||
6 | * Common definitions. | ||
7 | * Based on AT91SAM9x5 datasheet. | ||
8 | * | ||
9 | * Licensed under GPLv2 or later. | ||
10 | */ | ||
11 | |||
12 | #ifndef AT91SAM9X5_H | ||
13 | #define AT91SAM9X5_H | ||
14 | |||
15 | /* | ||
16 | * Peripheral identifiers/interrupts. | ||
17 | */ | ||
18 | #define AT91SAM9X5_ID_PIOAB 2 /* Parallel I/O Controller A and B */ | ||
19 | #define AT91SAM9X5_ID_PIOCD 3 /* Parallel I/O Controller C and D */ | ||
20 | #define AT91SAM9X5_ID_SMD 4 /* SMD Soft Modem (SMD) */ | ||
21 | #define AT91SAM9X5_ID_USART0 5 /* USART 0 */ | ||
22 | #define AT91SAM9X5_ID_USART1 6 /* USART 1 */ | ||
23 | #define AT91SAM9X5_ID_USART2 7 /* USART 2 */ | ||
24 | #define AT91SAM9X5_ID_USART3 8 /* USART 3 */ | ||
25 | #define AT91SAM9X5_ID_TWI0 9 /* Two-Wire Interface 0 */ | ||
26 | #define AT91SAM9X5_ID_TWI1 10 /* Two-Wire Interface 1 */ | ||
27 | #define AT91SAM9X5_ID_TWI2 11 /* Two-Wire Interface 2 */ | ||
28 | #define AT91SAM9X5_ID_MCI0 12 /* High Speed Multimedia Card Interface 0 */ | ||
29 | #define AT91SAM9X5_ID_SPI0 13 /* Serial Peripheral Interface 0 */ | ||
30 | #define AT91SAM9X5_ID_SPI1 14 /* Serial Peripheral Interface 1 */ | ||
31 | #define AT91SAM9X5_ID_UART0 15 /* UART 0 */ | ||
32 | #define AT91SAM9X5_ID_UART1 16 /* UART 1 */ | ||
33 | #define AT91SAM9X5_ID_TCB 17 /* Timer Counter 0, 1, 2, 3, 4 and 5 */ | ||
34 | #define AT91SAM9X5_ID_PWM 18 /* Pulse Width Modulation Controller */ | ||
35 | #define AT91SAM9X5_ID_ADC 19 /* ADC Controller */ | ||
36 | #define AT91SAM9X5_ID_DMA0 20 /* DMA Controller 0 */ | ||
37 | #define AT91SAM9X5_ID_DMA1 21 /* DMA Controller 1 */ | ||
38 | #define AT91SAM9X5_ID_UHPHS 22 /* USB Host High Speed */ | ||
39 | #define AT91SAM9X5_ID_UDPHS 23 /* USB Device High Speed */ | ||
40 | #define AT91SAM9X5_ID_EMAC0 24 /* Ethernet MAC0 */ | ||
41 | #define AT91SAM9X5_ID_LCDC 25 /* LCD Controller */ | ||
42 | #define AT91SAM9X5_ID_ISI 25 /* Image Sensor Interface */ | ||
43 | #define AT91SAM9X5_ID_MCI1 26 /* High Speed Multimedia Card Interface 1 */ | ||
44 | #define AT91SAM9X5_ID_EMAC1 27 /* Ethernet MAC1 */ | ||
45 | #define AT91SAM9X5_ID_SSC 28 /* Synchronous Serial Controller */ | ||
46 | #define AT91SAM9X5_ID_CAN0 29 /* CAN Controller 0 */ | ||
47 | #define AT91SAM9X5_ID_CAN1 30 /* CAN Controller 1 */ | ||
48 | #define AT91SAM9X5_ID_IRQ0 31 /* Advanced Interrupt Controller */ | ||
49 | |||
50 | /* | ||
51 | * User Peripheral physical base addresses. | ||
52 | */ | ||
53 | #define AT91SAM9X5_BASE_USART0 0xf801c000 | ||
54 | #define AT91SAM9X5_BASE_USART1 0xf8020000 | ||
55 | #define AT91SAM9X5_BASE_USART2 0xf8024000 | ||
56 | |||
57 | /* | ||
58 | * System Peripherals (offset from AT91_BASE_SYS) | ||
59 | */ | ||
60 | #define AT91_DDRSDRC0 (0xffffe800 - AT91_BASE_SYS) | ||
61 | #define AT91_PMC (0xfffffc00 - AT91_BASE_SYS) | ||
62 | |||
63 | /* | ||
64 | * Base addresses for early serial code (uncompress.h) | ||
65 | */ | ||
66 | #define AT91_DBGU AT91_BASE_DBGU0 | ||
67 | #define AT91_USART0 AT91SAM9X5_BASE_USART0 | ||
68 | #define AT91_USART1 AT91SAM9X5_BASE_USART1 | ||
69 | #define AT91_USART2 AT91SAM9X5_BASE_USART2 | ||
70 | |||
71 | /* | ||
72 | * Internal Memory. | ||
73 | */ | ||
74 | #define AT91SAM9X5_SRAM_BASE 0x00300000 /* Internal SRAM base address */ | ||
75 | #define AT91SAM9X5_SRAM_SIZE SZ_32K /* Internal SRAM size (32Kb) */ | ||
76 | |||
77 | #define AT91SAM9X5_ROM_BASE 0x00400000 /* Internal ROM base address */ | ||
78 | #define AT91SAM9X5_ROM_SIZE SZ_64K /* Internal ROM size (64Kb) */ | ||
79 | |||
80 | #endif | ||
diff --git a/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h new file mode 100644 index 000000000000..a606d3966470 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91sam9x5_matrix.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Matrix-centric header file for the AT91SAM9x5 family | ||
3 | * | ||
4 | * Copyright (C) 2009-2012 Atmel Corporation. | ||
5 | * | ||
6 | * Only EBI related registers. | ||
7 | * Write Protect register definitions may be useful. | ||
8 | * | ||
9 | * Licensed under GPLv2 or later. | ||
10 | */ | ||
11 | |||
12 | #ifndef AT91SAM9X5_MATRIX_H | ||
13 | #define AT91SAM9X5_MATRIX_H | ||
14 | |||
15 | #define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */ | ||
16 | #define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */ | ||
17 | #define AT91_MATRIX_EBI_CS1A_SMC (0 << 1) | ||
18 | #define AT91_MATRIX_EBI_CS1A_SDRAMC (1 << 1) | ||
19 | #define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */ | ||
20 | #define AT91_MATRIX_EBI_CS3A_SMC (0 << 3) | ||
21 | #define AT91_MATRIX_EBI_CS3A_SMC_NANDFLASH (1 << 3) | ||
22 | #define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */ | ||
23 | #define AT91_MATRIX_EBI_DBPU_ON (0 << 8) | ||
24 | #define AT91_MATRIX_EBI_DBPU_OFF (1 << 8) | ||
25 | #define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */ | ||
26 | #define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16) | ||
27 | #define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16) | ||
28 | #define AT91_MATRIX_EBI_EBI_IOSR (1 << 17) /* EBI I/O slew rate selection */ | ||
29 | #define AT91_MATRIX_EBI_EBI_IOSR_REDUCED (0 << 17) | ||
30 | #define AT91_MATRIX_EBI_EBI_IOSR_NORMAL (1 << 17) | ||
31 | #define AT91_MATRIX_EBI_DDR_IOSR (1 << 18) /* DDR2 dedicated port I/O slew rate selection */ | ||
32 | #define AT91_MATRIX_EBI_DDR_IOSR_REDUCED (0 << 18) | ||
33 | #define AT91_MATRIX_EBI_DDR_IOSR_NORMAL (1 << 18) | ||
34 | #define AT91_MATRIX_NFD0_SELECT (1 << 24) /* NAND Flash Data Bus Selection */ | ||
35 | #define AT91_MATRIX_NFD0_ON_D0 (0 << 24) | ||
36 | #define AT91_MATRIX_NFD0_ON_D16 (1 << 24) | ||
37 | #define AT91_MATRIX_DDR_MP_EN (1 << 25) /* DDR Multi-port Enable */ | ||
38 | #define AT91_MATRIX_MP_OFF (0 << 25) | ||
39 | #define AT91_MATRIX_MP_ON (1 << 25) | ||
40 | |||
41 | #define AT91_MATRIX_WPMR (AT91_MATRIX + 0x1E4) /* Write Protect Mode Register */ | ||
42 | #define AT91_MATRIX_WPMR_WPEN (1 << 0) /* Write Protect ENable */ | ||
43 | #define AT91_MATRIX_WPMR_WP_WPDIS (0 << 0) | ||
44 | #define AT91_MATRIX_WPMR_WP_WPEN (1 << 0) | ||
45 | #define AT91_MATRIX_WPMR_WPKEY (0xFFFFFF << 8) /* Write Protect KEY */ | ||
46 | |||
47 | #define AT91_MATRIX_WPSR (AT91_MATRIX + 0x1E8) /* Write Protect Status Register */ | ||
48 | #define AT91_MATRIX_WPSR_WPVS (1 << 0) /* Write Protect Violation Status */ | ||
49 | #define AT91_MATRIX_WPSR_NO_WPV (0 << 0) | ||
50 | #define AT91_MATRIX_WPSR_WPV (1 << 0) | ||
51 | #define AT91_MATRIX_WPSR_WPVSRC (0xFFFF << 8) /* Write Protect Violation Source */ | ||
52 | |||
53 | #endif | ||
diff --git a/arch/arm/mach-at91/include/mach/entry-macro.S b/arch/arm/mach-at91/include/mach/entry-macro.S index 423eea0ed74c..903bf205a333 100644 --- a/arch/arm/mach-at91/include/mach/entry-macro.S +++ b/arch/arm/mach-at91/include/mach/entry-macro.S | |||
@@ -13,17 +13,11 @@ | |||
13 | #include <mach/hardware.h> | 13 | #include <mach/hardware.h> |
14 | #include <mach/at91_aic.h> | 14 | #include <mach/at91_aic.h> |
15 | 15 | ||
16 | .macro disable_fiq | ||
17 | .endm | ||
18 | |||
19 | .macro get_irqnr_preamble, base, tmp | 16 | .macro get_irqnr_preamble, base, tmp |
20 | ldr \base, =at91_aic_base @ base virtual address of AIC peripheral | 17 | ldr \base, =at91_aic_base @ base virtual address of AIC peripheral |
21 | ldr \base, [\base] | 18 | ldr \base, [\base] |
22 | .endm | 19 | .endm |
23 | 20 | ||
24 | .macro arch_ret_to_user, tmp1, tmp2 | ||
25 | .endm | ||
26 | |||
27 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | 21 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp |
28 | ldr \irqnr, [\base, #AT91_AIC_IVR] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) | 22 | ldr \irqnr, [\base, #AT91_AIC_IVR] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt) |
29 | ldr \irqstat, [\base, #AT91_AIC_ISR] @ read interrupt source number | 23 | ldr \irqstat, [\base, #AT91_AIC_ISR] @ read interrupt source number |
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index c213f28628c0..fd7dce4f7378 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <mach/at91sam9rl.h> | 34 | #include <mach/at91sam9rl.h> |
35 | #elif defined(CONFIG_ARCH_AT91SAM9G45) | 35 | #elif defined(CONFIG_ARCH_AT91SAM9G45) |
36 | #include <mach/at91sam9g45.h> | 36 | #include <mach/at91sam9g45.h> |
37 | #elif defined(CONFIG_ARCH_AT91SAM9X5) | ||
38 | #include <mach/at91sam9x5.h> | ||
37 | #elif defined(CONFIG_ARCH_AT91X40) | 39 | #elif defined(CONFIG_ARCH_AT91X40) |
38 | #include <mach/at91x40.h> | 40 | #include <mach/at91x40.h> |
39 | #else | 41 | #else |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 87be5aa18753..d554e6771b4e 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -198,7 +198,6 @@ extern u32 at91_slow_clock_sz; | |||
198 | 198 | ||
199 | static int at91_pm_enter(suspend_state_t state) | 199 | static int at91_pm_enter(suspend_state_t state) |
200 | { | 200 | { |
201 | u32 saved_lpr; | ||
202 | at91_gpio_suspend(); | 201 | at91_gpio_suspend(); |
203 | at91_irq_suspend(); | 202 | at91_irq_suspend(); |
204 | 203 | ||
@@ -254,16 +253,7 @@ static int at91_pm_enter(suspend_state_t state) | |||
254 | * For ARM 926 based chips, this requirement is weaker | 253 | * For ARM 926 based chips, this requirement is weaker |
255 | * as at91sam9 can access a RAM in self-refresh mode. | 254 | * as at91sam9 can access a RAM in self-refresh mode. |
256 | */ | 255 | */ |
257 | asm volatile ( "mov r0, #0\n\t" | 256 | at91_standby(); |
258 | "b 1f\n\t" | ||
259 | ".align 5\n\t" | ||
260 | "1: mcr p15, 0, r0, c7, c10, 4\n\t" | ||
261 | : /* no output */ | ||
262 | : /* no input */ | ||
263 | : "r0"); | ||
264 | saved_lpr = sdram_selfrefresh_enable(); | ||
265 | wait_for_interrupt_enable(); | ||
266 | sdram_selfrefresh_disable(saved_lpr); | ||
267 | break; | 257 | break; |
268 | 258 | ||
269 | case PM_SUSPEND_ON: | 259 | case PM_SUSPEND_ON: |
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index 218d816427c0..bba9ce1aaaec 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h | |||
@@ -1,3 +1,16 @@ | |||
1 | /* | ||
2 | * AT91 Power Management | ||
3 | * | ||
4 | * Copyright (C) 2005 David Brownell | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | #ifndef __ARCH_ARM_MACH_AT91_PM | ||
12 | #define __ARCH_ARM_MACH_AT91_PM | ||
13 | |||
1 | #ifdef CONFIG_ARCH_AT91RM9200 | 14 | #ifdef CONFIG_ARCH_AT91RM9200 |
2 | #include <mach/at91rm9200_mc.h> | 15 | #include <mach/at91rm9200_mc.h> |
3 | 16 | ||
@@ -11,18 +24,25 @@ | |||
11 | * still in self-refresh is "not recommended", but seems to work. | 24 | * still in self-refresh is "not recommended", but seems to work. |
12 | */ | 25 | */ |
13 | 26 | ||
14 | static inline u32 sdram_selfrefresh_enable(void) | 27 | static inline void at91rm9200_standby(void) |
15 | { | 28 | { |
16 | u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR); | 29 | u32 lpr = at91_sys_read(AT91_SDRAMC_LPR); |
17 | 30 | ||
18 | at91_sys_write(AT91_SDRAMC_LPR, 0); | 31 | asm volatile( |
19 | at91_sys_write(AT91_SDRAMC_SRR, 1); | 32 | "b 1f\n\t" |
20 | return saved_lpr; | 33 | ".align 5\n\t" |
34 | "1: mcr p15, 0, %0, c7, c10, 4\n\t" | ||
35 | " str %0, [%1, %2]\n\t" | ||
36 | " str %3, [%1, %4]\n\t" | ||
37 | " mcr p15, 0, %0, c7, c0, 4\n\t" | ||
38 | " str %5, [%1, %2]" | ||
39 | : | ||
40 | : "r" (0), "r" (AT91_BASE_SYS), "r" (AT91_SDRAMC_LPR), | ||
41 | "r" (1), "r" (AT91_SDRAMC_SRR), | ||
42 | "r" (lpr)); | ||
21 | } | 43 | } |
22 | 44 | ||
23 | #define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_SDRAMC_LPR, saved_lpr) | 45 | #define at91_standby at91rm9200_standby |
24 | #define wait_for_interrupt_enable() asm volatile ("mcr p15, 0, %0, c7, c0, 4" \ | ||
25 | : : "r" (0)) | ||
26 | 46 | ||
27 | #elif defined(CONFIG_ARCH_AT91SAM9G45) | 47 | #elif defined(CONFIG_ARCH_AT91SAM9G45) |
28 | #include <mach/at91sam9_ddrsdr.h> | 48 | #include <mach/at91sam9_ddrsdr.h> |
@@ -30,14 +50,12 @@ static inline u32 sdram_selfrefresh_enable(void) | |||
30 | /* We manage both DDRAM/SDRAM controllers, we need more than one value to | 50 | /* We manage both DDRAM/SDRAM controllers, we need more than one value to |
31 | * remember. | 51 | * remember. |
32 | */ | 52 | */ |
33 | static u32 saved_lpr1; | 53 | static inline void at91sam9g45_standby(void) |
34 | |||
35 | static inline u32 sdram_selfrefresh_enable(void) | ||
36 | { | 54 | { |
37 | /* Those tow values allow us to delay self-refresh activation | 55 | /* Those two values allow us to delay self-refresh activation |
38 | * to the maximum. */ | 56 | * to the maximum. */ |
39 | u32 lpr0, lpr1; | 57 | u32 lpr0, lpr1; |
40 | u32 saved_lpr0; | 58 | u32 saved_lpr0, saved_lpr1; |
41 | 59 | ||
42 | saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); | 60 | saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR); |
43 | lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; | 61 | lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB; |
@@ -51,15 +69,13 @@ static inline u32 sdram_selfrefresh_enable(void) | |||
51 | at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); | 69 | at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0); |
52 | at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); | 70 | at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1); |
53 | 71 | ||
54 | return saved_lpr0; | 72 | cpu_do_idle(); |
73 | |||
74 | at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); | ||
75 | at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); | ||
55 | } | 76 | } |
56 | 77 | ||
57 | #define sdram_selfrefresh_disable(saved_lpr0) \ | 78 | #define at91_standby at91sam9g45_standby |
58 | do { \ | ||
59 | at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \ | ||
60 | at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \ | ||
61 | } while (0) | ||
62 | #define wait_for_interrupt_enable() cpu_do_idle() | ||
63 | 79 | ||
64 | #else | 80 | #else |
65 | #include <mach/at91sam9_sdramc.h> | 81 | #include <mach/at91sam9_sdramc.h> |
@@ -72,18 +88,23 @@ static inline u32 sdram_selfrefresh_enable(void) | |||
72 | #warning Assuming EB1 SDRAM controller is *NOT* used | 88 | #warning Assuming EB1 SDRAM controller is *NOT* used |
73 | #endif | 89 | #endif |
74 | 90 | ||
75 | static inline u32 sdram_selfrefresh_enable(void) | 91 | static inline void at91sam9_standby(void) |
76 | { | 92 | { |
77 | u32 saved_lpr, lpr; | 93 | u32 saved_lpr, lpr; |
78 | 94 | ||
79 | saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR); | 95 | saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR); |
80 | 96 | ||
81 | lpr = saved_lpr & ~AT91_SDRAMC_LPCB; | 97 | lpr = saved_lpr & ~AT91_SDRAMC_LPCB; |
82 | at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH); | 98 | at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | |
83 | return saved_lpr; | 99 | AT91_SDRAMC_LPCB_SELF_REFRESH); |
100 | |||
101 | cpu_do_idle(); | ||
102 | |||
103 | at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr); | ||
84 | } | 104 | } |
85 | 105 | ||
86 | #define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr) | 106 | #define at91_standby at91sam9_standby |
87 | #define wait_for_interrupt_enable() cpu_do_idle() | 107 | |
108 | #endif | ||
88 | 109 | ||
89 | #endif | 110 | #endif |