]>
Commit | Line | Data |
---|---|---|
62c1660d | 1 | /* |
9d041268 | 2 | * arch/arm/mach-at91/at91sam9260.c |
62c1660d AV |
3 | * |
4 | * Copyright (C) 2006 SAN People | |
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 | */ | |
12 | ||
13 | #include <linux/module.h> | |
3ef2fb42 | 14 | #include <linux/pm.h> |
62c1660d AV |
15 | |
16 | #include <asm/mach/arch.h> | |
17 | #include <asm/mach/map.h> | |
f7eee89b | 18 | #include <asm/arch/cpu.h> |
62c1660d AV |
19 | #include <asm/arch/at91sam9260.h> |
20 | #include <asm/arch/at91_pmc.h> | |
e9d10a16 | 21 | #include <asm/arch/at91_rstc.h> |
3ef2fb42 | 22 | #include <asm/arch/at91_shdwc.h> |
62c1660d AV |
23 | |
24 | #include "generic.h" | |
25 | #include "clock.h" | |
26 | ||
27 | static struct map_desc at91sam9260_io_desc[] __initdata = { | |
28 | { | |
29 | .virtual = AT91_VA_BASE_SYS, | |
30 | .pfn = __phys_to_pfn(AT91_BASE_SYS), | |
31 | .length = SZ_16K, | |
32 | .type = MT_DEVICE, | |
f7eee89b AV |
33 | } |
34 | }; | |
35 | ||
36 | static struct map_desc at91sam9260_sram_desc[] __initdata = { | |
37 | { | |
62c1660d AV |
38 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE, |
39 | .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE), | |
40 | .length = AT91SAM9260_SRAM0_SIZE, | |
41 | .type = MT_DEVICE, | |
42 | }, { | |
43 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE - AT91SAM9260_SRAM1_SIZE, | |
44 | .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE), | |
45 | .length = AT91SAM9260_SRAM1_SIZE, | |
46 | .type = MT_DEVICE, | |
f7eee89b AV |
47 | } |
48 | }; | |
49 | ||
61352667 | 50 | static struct map_desc at91sam9g20_sram_desc[] __initdata = { |
51 | { | |
52 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE, | |
53 | .pfn = __phys_to_pfn(AT91SAM9G20_SRAM0_BASE), | |
54 | .length = AT91SAM9G20_SRAM0_SIZE, | |
55 | .type = MT_DEVICE, | |
56 | }, { | |
57 | .virtual = AT91_IO_VIRT_BASE - AT91SAM9G20_SRAM0_SIZE - AT91SAM9G20_SRAM1_SIZE, | |
58 | .pfn = __phys_to_pfn(AT91SAM9G20_SRAM1_BASE), | |
59 | .length = AT91SAM9G20_SRAM1_SIZE, | |
60 | .type = MT_DEVICE, | |
61 | } | |
62 | }; | |
63 | ||
f7eee89b AV |
64 | static struct map_desc at91sam9xe_sram_desc[] __initdata = { |
65 | { | |
66 | .pfn = __phys_to_pfn(AT91SAM9XE_SRAM_BASE), | |
67 | .type = MT_DEVICE, | |
68 | } | |
62c1660d AV |
69 | }; |
70 | ||
71 | /* -------------------------------------------------------------------- | |
72 | * Clocks | |
73 | * -------------------------------------------------------------------- */ | |
74 | ||
75 | /* | |
76 | * The peripheral clocks. | |
77 | */ | |
78 | static struct clk pioA_clk = { | |
79 | .name = "pioA_clk", | |
80 | .pmc_mask = 1 << AT91SAM9260_ID_PIOA, | |
81 | .type = CLK_TYPE_PERIPHERAL, | |
82 | }; | |
83 | static struct clk pioB_clk = { | |
84 | .name = "pioB_clk", | |
85 | .pmc_mask = 1 << AT91SAM9260_ID_PIOB, | |
86 | .type = CLK_TYPE_PERIPHERAL, | |
87 | }; | |
88 | static struct clk pioC_clk = { | |
89 | .name = "pioC_clk", | |
90 | .pmc_mask = 1 << AT91SAM9260_ID_PIOC, | |
91 | .type = CLK_TYPE_PERIPHERAL, | |
92 | }; | |
93 | static struct clk adc_clk = { | |
94 | .name = "adc_clk", | |
95 | .pmc_mask = 1 << AT91SAM9260_ID_ADC, | |
96 | .type = CLK_TYPE_PERIPHERAL, | |
97 | }; | |
98 | static struct clk usart0_clk = { | |
99 | .name = "usart0_clk", | |
100 | .pmc_mask = 1 << AT91SAM9260_ID_US0, | |
101 | .type = CLK_TYPE_PERIPHERAL, | |
102 | }; | |
103 | static struct clk usart1_clk = { | |
104 | .name = "usart1_clk", | |
105 | .pmc_mask = 1 << AT91SAM9260_ID_US1, | |
106 | .type = CLK_TYPE_PERIPHERAL, | |
107 | }; | |
108 | static struct clk usart2_clk = { | |
109 | .name = "usart2_clk", | |
110 | .pmc_mask = 1 << AT91SAM9260_ID_US2, | |
111 | .type = CLK_TYPE_PERIPHERAL, | |
112 | }; | |
113 | static struct clk mmc_clk = { | |
114 | .name = "mci_clk", | |
115 | .pmc_mask = 1 << AT91SAM9260_ID_MCI, | |
116 | .type = CLK_TYPE_PERIPHERAL, | |
117 | }; | |
118 | static struct clk udc_clk = { | |
119 | .name = "udc_clk", | |
120 | .pmc_mask = 1 << AT91SAM9260_ID_UDP, | |
121 | .type = CLK_TYPE_PERIPHERAL, | |
122 | }; | |
123 | static struct clk twi_clk = { | |
124 | .name = "twi_clk", | |
125 | .pmc_mask = 1 << AT91SAM9260_ID_TWI, | |
126 | .type = CLK_TYPE_PERIPHERAL, | |
127 | }; | |
128 | static struct clk spi0_clk = { | |
129 | .name = "spi0_clk", | |
130 | .pmc_mask = 1 << AT91SAM9260_ID_SPI0, | |
131 | .type = CLK_TYPE_PERIPHERAL, | |
132 | }; | |
133 | static struct clk spi1_clk = { | |
134 | .name = "spi1_clk", | |
135 | .pmc_mask = 1 << AT91SAM9260_ID_SPI1, | |
136 | .type = CLK_TYPE_PERIPHERAL, | |
137 | }; | |
e8788bab AV |
138 | static struct clk ssc_clk = { |
139 | .name = "ssc_clk", | |
140 | .pmc_mask = 1 << AT91SAM9260_ID_SSC, | |
141 | .type = CLK_TYPE_PERIPHERAL, | |
142 | }; | |
c177a1e7 AV |
143 | static struct clk tc0_clk = { |
144 | .name = "tc0_clk", | |
145 | .pmc_mask = 1 << AT91SAM9260_ID_TC0, | |
146 | .type = CLK_TYPE_PERIPHERAL, | |
147 | }; | |
148 | static struct clk tc1_clk = { | |
149 | .name = "tc1_clk", | |
150 | .pmc_mask = 1 << AT91SAM9260_ID_TC1, | |
151 | .type = CLK_TYPE_PERIPHERAL, | |
152 | }; | |
153 | static struct clk tc2_clk = { | |
154 | .name = "tc2_clk", | |
155 | .pmc_mask = 1 << AT91SAM9260_ID_TC2, | |
156 | .type = CLK_TYPE_PERIPHERAL, | |
157 | }; | |
62c1660d AV |
158 | static struct clk ohci_clk = { |
159 | .name = "ohci_clk", | |
160 | .pmc_mask = 1 << AT91SAM9260_ID_UHP, | |
161 | .type = CLK_TYPE_PERIPHERAL, | |
162 | }; | |
69b2e99c AV |
163 | static struct clk macb_clk = { |
164 | .name = "macb_clk", | |
62c1660d AV |
165 | .pmc_mask = 1 << AT91SAM9260_ID_EMAC, |
166 | .type = CLK_TYPE_PERIPHERAL, | |
167 | }; | |
168 | static struct clk isi_clk = { | |
169 | .name = "isi_clk", | |
170 | .pmc_mask = 1 << AT91SAM9260_ID_ISI, | |
171 | .type = CLK_TYPE_PERIPHERAL, | |
172 | }; | |
173 | static struct clk usart3_clk = { | |
174 | .name = "usart3_clk", | |
175 | .pmc_mask = 1 << AT91SAM9260_ID_US3, | |
176 | .type = CLK_TYPE_PERIPHERAL, | |
177 | }; | |
178 | static struct clk usart4_clk = { | |
179 | .name = "usart4_clk", | |
180 | .pmc_mask = 1 << AT91SAM9260_ID_US4, | |
181 | .type = CLK_TYPE_PERIPHERAL, | |
182 | }; | |
183 | static struct clk usart5_clk = { | |
184 | .name = "usart5_clk", | |
185 | .pmc_mask = 1 << AT91SAM9260_ID_US5, | |
186 | .type = CLK_TYPE_PERIPHERAL, | |
187 | }; | |
c177a1e7 AV |
188 | static struct clk tc3_clk = { |
189 | .name = "tc3_clk", | |
190 | .pmc_mask = 1 << AT91SAM9260_ID_TC3, | |
191 | .type = CLK_TYPE_PERIPHERAL, | |
192 | }; | |
193 | static struct clk tc4_clk = { | |
194 | .name = "tc4_clk", | |
195 | .pmc_mask = 1 << AT91SAM9260_ID_TC4, | |
196 | .type = CLK_TYPE_PERIPHERAL, | |
197 | }; | |
198 | static struct clk tc5_clk = { | |
199 | .name = "tc5_clk", | |
200 | .pmc_mask = 1 << AT91SAM9260_ID_TC5, | |
201 | .type = CLK_TYPE_PERIPHERAL, | |
202 | }; | |
62c1660d AV |
203 | |
204 | static struct clk *periph_clocks[] __initdata = { | |
205 | &pioA_clk, | |
206 | &pioB_clk, | |
207 | &pioC_clk, | |
208 | &adc_clk, | |
209 | &usart0_clk, | |
210 | &usart1_clk, | |
211 | &usart2_clk, | |
212 | &mmc_clk, | |
213 | &udc_clk, | |
214 | &twi_clk, | |
215 | &spi0_clk, | |
216 | &spi1_clk, | |
e8788bab | 217 | &ssc_clk, |
c177a1e7 AV |
218 | &tc0_clk, |
219 | &tc1_clk, | |
220 | &tc2_clk, | |
62c1660d | 221 | &ohci_clk, |
69b2e99c | 222 | &macb_clk, |
62c1660d AV |
223 | &isi_clk, |
224 | &usart3_clk, | |
225 | &usart4_clk, | |
226 | &usart5_clk, | |
c177a1e7 AV |
227 | &tc3_clk, |
228 | &tc4_clk, | |
229 | &tc5_clk, | |
62c1660d AV |
230 | // irq0 .. irq2 |
231 | }; | |
232 | ||
233 | /* | |
234 | * The two programmable clocks. | |
235 | * You must configure pin multiplexing to bring these signals out. | |
236 | */ | |
237 | static struct clk pck0 = { | |
238 | .name = "pck0", | |
239 | .pmc_mask = AT91_PMC_PCK0, | |
240 | .type = CLK_TYPE_PROGRAMMABLE, | |
241 | .id = 0, | |
242 | }; | |
243 | static struct clk pck1 = { | |
244 | .name = "pck1", | |
245 | .pmc_mask = AT91_PMC_PCK1, | |
246 | .type = CLK_TYPE_PROGRAMMABLE, | |
247 | .id = 1, | |
248 | }; | |
249 | ||
250 | static void __init at91sam9260_register_clocks(void) | |
251 | { | |
252 | int i; | |
253 | ||
254 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | |
255 | clk_register(periph_clocks[i]); | |
256 | ||
257 | clk_register(&pck0); | |
258 | clk_register(&pck1); | |
259 | } | |
260 | ||
261 | /* -------------------------------------------------------------------- | |
262 | * GPIO | |
263 | * -------------------------------------------------------------------- */ | |
264 | ||
265 | static struct at91_gpio_bank at91sam9260_gpio[] = { | |
266 | { | |
267 | .id = AT91SAM9260_ID_PIOA, | |
268 | .offset = AT91_PIOA, | |
269 | .clock = &pioA_clk, | |
270 | }, { | |
271 | .id = AT91SAM9260_ID_PIOB, | |
272 | .offset = AT91_PIOB, | |
273 | .clock = &pioB_clk, | |
274 | }, { | |
275 | .id = AT91SAM9260_ID_PIOC, | |
276 | .offset = AT91_PIOC, | |
277 | .clock = &pioC_clk, | |
278 | } | |
279 | }; | |
280 | ||
281 | static void at91sam9260_reset(void) | |
282 | { | |
dd1d2f44 | 283 | at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); |
62c1660d AV |
284 | } |
285 | ||
3ef2fb42 AV |
286 | static void at91sam9260_poweroff(void) |
287 | { | |
288 | at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); | |
289 | } | |
290 | ||
62c1660d AV |
291 | |
292 | /* -------------------------------------------------------------------- | |
293 | * AT91SAM9260 processor initialization | |
294 | * -------------------------------------------------------------------- */ | |
295 | ||
f7eee89b AV |
296 | static void __init at91sam9xe_initialize(void) |
297 | { | |
298 | unsigned long cidr, sram_size; | |
299 | ||
300 | cidr = at91_sys_read(AT91_DBGU_CIDR); | |
301 | ||
302 | switch (cidr & AT91_CIDR_SRAMSIZ) { | |
303 | case AT91_CIDR_SRAMSIZ_32K: | |
304 | sram_size = 2 * SZ_16K; | |
305 | break; | |
306 | case AT91_CIDR_SRAMSIZ_16K: | |
307 | default: | |
308 | sram_size = SZ_16K; | |
309 | } | |
310 | ||
311 | at91sam9xe_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size; | |
312 | at91sam9xe_sram_desc->length = sram_size; | |
313 | ||
314 | iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc)); | |
315 | } | |
316 | ||
62c1660d AV |
317 | void __init at91sam9260_initialize(unsigned long main_clock) |
318 | { | |
319 | /* Map peripherals */ | |
320 | iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); | |
321 | ||
f7eee89b AV |
322 | if (cpu_is_at91sam9xe()) |
323 | at91sam9xe_initialize(); | |
61352667 | 324 | else if (cpu_is_at91sam9g20()) |
325 | iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc)); | |
f7eee89b AV |
326 | else |
327 | iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc)); | |
328 | ||
62c1660d | 329 | at91_arch_reset = at91sam9260_reset; |
3ef2fb42 | 330 | pm_power_off = at91sam9260_poweroff; |
62c1660d AV |
331 | at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) |
332 | | (1 << AT91SAM9260_ID_IRQ2); | |
333 | ||
334 | /* Init clock subsystem */ | |
335 | at91_clock_init(main_clock); | |
336 | ||
337 | /* Register the processor-specific clocks */ | |
338 | at91sam9260_register_clocks(); | |
339 | ||
340 | /* Register GPIO subsystem */ | |
341 | at91_gpio_init(at91sam9260_gpio, 3); | |
342 | } | |
343 | ||
344 | /* -------------------------------------------------------------------- | |
345 | * Interrupt initialization | |
346 | * -------------------------------------------------------------------- */ | |
347 | ||
348 | /* | |
349 | * The default interrupt priority levels (0 = lowest, 7 = highest). | |
350 | */ | |
351 | static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = { | |
352 | 7, /* Advanced Interrupt Controller */ | |
353 | 7, /* System Peripherals */ | |
7cbed2b5 AV |
354 | 1, /* Parallel IO Controller A */ |
355 | 1, /* Parallel IO Controller B */ | |
356 | 1, /* Parallel IO Controller C */ | |
62c1660d | 357 | 0, /* Analog-to-Digital Converter */ |
7cbed2b5 AV |
358 | 5, /* USART 0 */ |
359 | 5, /* USART 1 */ | |
360 | 5, /* USART 2 */ | |
62c1660d | 361 | 0, /* Multimedia Card Interface */ |
7cbed2b5 AV |
362 | 2, /* USB Device Port */ |
363 | 6, /* Two-Wire Interface */ | |
364 | 5, /* Serial Peripheral Interface 0 */ | |
365 | 5, /* Serial Peripheral Interface 1 */ | |
62c1660d AV |
366 | 5, /* Serial Synchronous Controller */ |
367 | 0, | |
368 | 0, | |
369 | 0, /* Timer Counter 0 */ | |
370 | 0, /* Timer Counter 1 */ | |
371 | 0, /* Timer Counter 2 */ | |
7cbed2b5 | 372 | 2, /* USB Host port */ |
62c1660d AV |
373 | 3, /* Ethernet */ |
374 | 0, /* Image Sensor Interface */ | |
7cbed2b5 AV |
375 | 5, /* USART 3 */ |
376 | 5, /* USART 4 */ | |
377 | 5, /* USART 5 */ | |
62c1660d AV |
378 | 0, /* Timer Counter 3 */ |
379 | 0, /* Timer Counter 4 */ | |
380 | 0, /* Timer Counter 5 */ | |
381 | 0, /* Advanced Interrupt Controller */ | |
382 | 0, /* Advanced Interrupt Controller */ | |
383 | 0, /* Advanced Interrupt Controller */ | |
384 | }; | |
385 | ||
386 | void __init at91sam9260_init_interrupts(unsigned int priority[NR_AIC_IRQS]) | |
387 | { | |
388 | if (!priority) | |
389 | priority = at91sam9260_default_irq_priority; | |
390 | ||
391 | /* Initialize the AIC interrupt controller */ | |
392 | at91_aic_init(priority); | |
393 | ||
394 | /* Enable GPIO interrupts */ | |
395 | at91_gpio_irq_setup(); | |
396 | } |