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 | 15 | |
80b02c17 | 16 | #include <asm/irq.h> |
62c1660d AV |
17 | #include <asm/mach/arch.h> |
18 | #include <asm/mach/map.h> | |
a09e64fb | 19 | #include <mach/cpu.h> |
8c3583b6 | 20 | #include <mach/at91_dbgu.h> |
a09e64fb RK |
21 | #include <mach/at91sam9260.h> |
22 | #include <mach/at91_pmc.h> | |
23 | #include <mach/at91_rstc.h> | |
24 | #include <mach/at91_shdwc.h> | |
62c1660d | 25 | |
21d08b9d | 26 | #include "soc.h" |
62c1660d AV |
27 | #include "generic.h" |
28 | #include "clock.h" | |
29 | ||
62c1660d AV |
30 | /* -------------------------------------------------------------------- |
31 | * Clocks | |
32 | * -------------------------------------------------------------------- */ | |
33 | ||
34 | /* | |
35 | * The peripheral clocks. | |
36 | */ | |
37 | static struct clk pioA_clk = { | |
38 | .name = "pioA_clk", | |
39 | .pmc_mask = 1 << AT91SAM9260_ID_PIOA, | |
40 | .type = CLK_TYPE_PERIPHERAL, | |
41 | }; | |
42 | static struct clk pioB_clk = { | |
43 | .name = "pioB_clk", | |
44 | .pmc_mask = 1 << AT91SAM9260_ID_PIOB, | |
45 | .type = CLK_TYPE_PERIPHERAL, | |
46 | }; | |
47 | static struct clk pioC_clk = { | |
48 | .name = "pioC_clk", | |
49 | .pmc_mask = 1 << AT91SAM9260_ID_PIOC, | |
50 | .type = CLK_TYPE_PERIPHERAL, | |
51 | }; | |
52 | static struct clk adc_clk = { | |
53 | .name = "adc_clk", | |
54 | .pmc_mask = 1 << AT91SAM9260_ID_ADC, | |
55 | .type = CLK_TYPE_PERIPHERAL, | |
56 | }; | |
57 | static struct clk usart0_clk = { | |
58 | .name = "usart0_clk", | |
59 | .pmc_mask = 1 << AT91SAM9260_ID_US0, | |
60 | .type = CLK_TYPE_PERIPHERAL, | |
61 | }; | |
62 | static struct clk usart1_clk = { | |
63 | .name = "usart1_clk", | |
64 | .pmc_mask = 1 << AT91SAM9260_ID_US1, | |
65 | .type = CLK_TYPE_PERIPHERAL, | |
66 | }; | |
67 | static struct clk usart2_clk = { | |
68 | .name = "usart2_clk", | |
69 | .pmc_mask = 1 << AT91SAM9260_ID_US2, | |
70 | .type = CLK_TYPE_PERIPHERAL, | |
71 | }; | |
72 | static struct clk mmc_clk = { | |
73 | .name = "mci_clk", | |
74 | .pmc_mask = 1 << AT91SAM9260_ID_MCI, | |
75 | .type = CLK_TYPE_PERIPHERAL, | |
76 | }; | |
77 | static struct clk udc_clk = { | |
78 | .name = "udc_clk", | |
79 | .pmc_mask = 1 << AT91SAM9260_ID_UDP, | |
80 | .type = CLK_TYPE_PERIPHERAL, | |
81 | }; | |
82 | static struct clk twi_clk = { | |
83 | .name = "twi_clk", | |
84 | .pmc_mask = 1 << AT91SAM9260_ID_TWI, | |
85 | .type = CLK_TYPE_PERIPHERAL, | |
86 | }; | |
87 | static struct clk spi0_clk = { | |
88 | .name = "spi0_clk", | |
89 | .pmc_mask = 1 << AT91SAM9260_ID_SPI0, | |
90 | .type = CLK_TYPE_PERIPHERAL, | |
91 | }; | |
92 | static struct clk spi1_clk = { | |
93 | .name = "spi1_clk", | |
94 | .pmc_mask = 1 << AT91SAM9260_ID_SPI1, | |
95 | .type = CLK_TYPE_PERIPHERAL, | |
96 | }; | |
e8788bab AV |
97 | static struct clk ssc_clk = { |
98 | .name = "ssc_clk", | |
99 | .pmc_mask = 1 << AT91SAM9260_ID_SSC, | |
100 | .type = CLK_TYPE_PERIPHERAL, | |
101 | }; | |
c177a1e7 AV |
102 | static struct clk tc0_clk = { |
103 | .name = "tc0_clk", | |
104 | .pmc_mask = 1 << AT91SAM9260_ID_TC0, | |
105 | .type = CLK_TYPE_PERIPHERAL, | |
106 | }; | |
107 | static struct clk tc1_clk = { | |
108 | .name = "tc1_clk", | |
109 | .pmc_mask = 1 << AT91SAM9260_ID_TC1, | |
110 | .type = CLK_TYPE_PERIPHERAL, | |
111 | }; | |
112 | static struct clk tc2_clk = { | |
113 | .name = "tc2_clk", | |
114 | .pmc_mask = 1 << AT91SAM9260_ID_TC2, | |
115 | .type = CLK_TYPE_PERIPHERAL, | |
116 | }; | |
62c1660d AV |
117 | static struct clk ohci_clk = { |
118 | .name = "ohci_clk", | |
119 | .pmc_mask = 1 << AT91SAM9260_ID_UHP, | |
120 | .type = CLK_TYPE_PERIPHERAL, | |
121 | }; | |
69b2e99c AV |
122 | static struct clk macb_clk = { |
123 | .name = "macb_clk", | |
62c1660d AV |
124 | .pmc_mask = 1 << AT91SAM9260_ID_EMAC, |
125 | .type = CLK_TYPE_PERIPHERAL, | |
126 | }; | |
127 | static struct clk isi_clk = { | |
128 | .name = "isi_clk", | |
129 | .pmc_mask = 1 << AT91SAM9260_ID_ISI, | |
130 | .type = CLK_TYPE_PERIPHERAL, | |
131 | }; | |
132 | static struct clk usart3_clk = { | |
133 | .name = "usart3_clk", | |
134 | .pmc_mask = 1 << AT91SAM9260_ID_US3, | |
135 | .type = CLK_TYPE_PERIPHERAL, | |
136 | }; | |
137 | static struct clk usart4_clk = { | |
138 | .name = "usart4_clk", | |
139 | .pmc_mask = 1 << AT91SAM9260_ID_US4, | |
140 | .type = CLK_TYPE_PERIPHERAL, | |
141 | }; | |
142 | static struct clk usart5_clk = { | |
143 | .name = "usart5_clk", | |
144 | .pmc_mask = 1 << AT91SAM9260_ID_US5, | |
145 | .type = CLK_TYPE_PERIPHERAL, | |
146 | }; | |
c177a1e7 AV |
147 | static struct clk tc3_clk = { |
148 | .name = "tc3_clk", | |
149 | .pmc_mask = 1 << AT91SAM9260_ID_TC3, | |
150 | .type = CLK_TYPE_PERIPHERAL, | |
151 | }; | |
152 | static struct clk tc4_clk = { | |
153 | .name = "tc4_clk", | |
154 | .pmc_mask = 1 << AT91SAM9260_ID_TC4, | |
155 | .type = CLK_TYPE_PERIPHERAL, | |
156 | }; | |
157 | static struct clk tc5_clk = { | |
158 | .name = "tc5_clk", | |
159 | .pmc_mask = 1 << AT91SAM9260_ID_TC5, | |
160 | .type = CLK_TYPE_PERIPHERAL, | |
161 | }; | |
62c1660d AV |
162 | |
163 | static struct clk *periph_clocks[] __initdata = { | |
164 | &pioA_clk, | |
165 | &pioB_clk, | |
166 | &pioC_clk, | |
167 | &adc_clk, | |
168 | &usart0_clk, | |
169 | &usart1_clk, | |
170 | &usart2_clk, | |
171 | &mmc_clk, | |
172 | &udc_clk, | |
173 | &twi_clk, | |
174 | &spi0_clk, | |
175 | &spi1_clk, | |
e8788bab | 176 | &ssc_clk, |
c177a1e7 AV |
177 | &tc0_clk, |
178 | &tc1_clk, | |
179 | &tc2_clk, | |
62c1660d | 180 | &ohci_clk, |
69b2e99c | 181 | &macb_clk, |
62c1660d AV |
182 | &isi_clk, |
183 | &usart3_clk, | |
184 | &usart4_clk, | |
185 | &usart5_clk, | |
c177a1e7 AV |
186 | &tc3_clk, |
187 | &tc4_clk, | |
188 | &tc5_clk, | |
62c1660d AV |
189 | // irq0 .. irq2 |
190 | }; | |
191 | ||
bd602995 JCPV |
192 | static struct clk_lookup periph_clocks_lookups[] = { |
193 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), | |
194 | CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), | |
195 | CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk), | |
196 | CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk), | |
197 | CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), | |
198 | CLKDEV_CON_DEV_ID("t3_clk", "atmel_tcb.1", &tc3_clk), | |
199 | CLKDEV_CON_DEV_ID("t4_clk", "atmel_tcb.1", &tc4_clk), | |
200 | CLKDEV_CON_DEV_ID("t5_clk", "atmel_tcb.1", &tc5_clk), | |
201 | CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk), | |
fea3158c JCPV |
202 | /* more usart lookup table for DT entries */ |
203 | CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), | |
204 | CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk), | |
205 | CLKDEV_CON_DEV_ID("usart", "fffb4000.serial", &usart1_clk), | |
206 | CLKDEV_CON_DEV_ID("usart", "fffb8000.serial", &usart2_clk), | |
207 | CLKDEV_CON_DEV_ID("usart", "fffd0000.serial", &usart3_clk), | |
208 | CLKDEV_CON_DEV_ID("usart", "fffd4000.serial", &usart4_clk), | |
209 | CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk), | |
0af4316b JCPV |
210 | /* fake hclk clock */ |
211 | CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), | |
bd602995 JCPV |
212 | }; |
213 | ||
214 | static struct clk_lookup usart_clocks_lookups[] = { | |
215 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), | |
216 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), | |
217 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), | |
218 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), | |
219 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk), | |
220 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.5", &usart4_clk), | |
221 | CLKDEV_CON_DEV_ID("usart", "atmel_usart.6", &usart5_clk), | |
222 | }; | |
223 | ||
62c1660d AV |
224 | /* |
225 | * The two programmable clocks. | |
226 | * You must configure pin multiplexing to bring these signals out. | |
227 | */ | |
228 | static struct clk pck0 = { | |
229 | .name = "pck0", | |
230 | .pmc_mask = AT91_PMC_PCK0, | |
231 | .type = CLK_TYPE_PROGRAMMABLE, | |
232 | .id = 0, | |
233 | }; | |
234 | static struct clk pck1 = { | |
235 | .name = "pck1", | |
236 | .pmc_mask = AT91_PMC_PCK1, | |
237 | .type = CLK_TYPE_PROGRAMMABLE, | |
238 | .id = 1, | |
239 | }; | |
240 | ||
241 | static void __init at91sam9260_register_clocks(void) | |
242 | { | |
243 | int i; | |
244 | ||
245 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | |
246 | clk_register(periph_clocks[i]); | |
247 | ||
bd602995 JCPV |
248 | clkdev_add_table(periph_clocks_lookups, |
249 | ARRAY_SIZE(periph_clocks_lookups)); | |
250 | clkdev_add_table(usart_clocks_lookups, | |
251 | ARRAY_SIZE(usart_clocks_lookups)); | |
252 | ||
62c1660d AV |
253 | clk_register(&pck0); |
254 | clk_register(&pck1); | |
255 | } | |
256 | ||
bd602995 JCPV |
257 | static struct clk_lookup console_clock_lookup; |
258 | ||
259 | void __init at91sam9260_set_console_clock(int id) | |
260 | { | |
261 | if (id >= ARRAY_SIZE(usart_clocks_lookups)) | |
262 | return; | |
263 | ||
264 | console_clock_lookup.con_id = "usart"; | |
265 | console_clock_lookup.clk = usart_clocks_lookups[id].clk; | |
266 | clkdev_add(&console_clock_lookup); | |
267 | } | |
268 | ||
62c1660d AV |
269 | /* -------------------------------------------------------------------- |
270 | * GPIO | |
271 | * -------------------------------------------------------------------- */ | |
272 | ||
273 | static struct at91_gpio_bank at91sam9260_gpio[] = { | |
274 | { | |
275 | .id = AT91SAM9260_ID_PIOA, | |
80e91cb8 | 276 | .regbase = AT91SAM9260_BASE_PIOA, |
62c1660d AV |
277 | .clock = &pioA_clk, |
278 | }, { | |
279 | .id = AT91SAM9260_ID_PIOB, | |
80e91cb8 | 280 | .regbase = AT91SAM9260_BASE_PIOB, |
62c1660d AV |
281 | .clock = &pioB_clk, |
282 | }, { | |
283 | .id = AT91SAM9260_ID_PIOC, | |
80e91cb8 | 284 | .regbase = AT91SAM9260_BASE_PIOC, |
62c1660d AV |
285 | .clock = &pioC_clk, |
286 | } | |
287 | }; | |
288 | ||
3ef2fb42 AV |
289 | static void at91sam9260_poweroff(void) |
290 | { | |
291 | at91_sys_write(AT91_SHDW_CR, AT91_SHDW_KEY | AT91_SHDW_SHDW); | |
292 | } | |
293 | ||
62c1660d AV |
294 | |
295 | /* -------------------------------------------------------------------- | |
296 | * AT91SAM9260 processor initialization | |
297 | * -------------------------------------------------------------------- */ | |
298 | ||
1b021a3b | 299 | static void __init at91sam9xe_map_io(void) |
f7eee89b | 300 | { |
8c3583b6 | 301 | unsigned long sram_size; |
f7eee89b | 302 | |
8c3583b6 | 303 | switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) { |
f7eee89b AV |
304 | case AT91_CIDR_SRAMSIZ_32K: |
305 | sram_size = 2 * SZ_16K; | |
306 | break; | |
307 | case AT91_CIDR_SRAMSIZ_16K: | |
308 | default: | |
309 | sram_size = SZ_16K; | |
310 | } | |
311 | ||
f0051d82 | 312 | at91_init_sram(0, AT91SAM9XE_SRAM_BASE, sram_size); |
f7eee89b AV |
313 | } |
314 | ||
21d08b9d | 315 | static void __init at91sam9260_map_io(void) |
62c1660d | 316 | { |
f0051d82 | 317 | if (cpu_is_at91sam9xe()) { |
1b021a3b | 318 | at91sam9xe_map_io(); |
f0051d82 JCPV |
319 | } else if (cpu_is_at91sam9g20()) { |
320 | at91_init_sram(0, AT91SAM9G20_SRAM0_BASE, AT91SAM9G20_SRAM0_SIZE); | |
321 | at91_init_sram(1, AT91SAM9G20_SRAM1_BASE, AT91SAM9G20_SRAM1_SIZE); | |
322 | } else { | |
323 | at91_init_sram(0, AT91SAM9260_SRAM0_BASE, AT91SAM9260_SRAM0_SIZE); | |
324 | at91_init_sram(1, AT91SAM9260_SRAM1_BASE, AT91SAM9260_SRAM1_SIZE); | |
325 | } | |
1b021a3b | 326 | } |
f7eee89b | 327 | |
cfa5a1fe JCPV |
328 | static void __init at91sam9260_ioremap_registers(void) |
329 | { | |
4ab0c599 | 330 | at91sam926x_ioremap_pit(AT91SAM9260_BASE_PIT); |
cfa5a1fe JCPV |
331 | } |
332 | ||
46539374 | 333 | static void __init at91sam9260_initialize(void) |
1b021a3b | 334 | { |
bb413db5 | 335 | at91_arch_reset = at91sam9_alt_reset; |
3ef2fb42 | 336 | pm_power_off = at91sam9260_poweroff; |
62c1660d AV |
337 | at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) |
338 | | (1 << AT91SAM9260_ID_IRQ2); | |
339 | ||
62c1660d AV |
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 | ||
8c3583b6 | 386 | struct at91_init_soc __initdata at91sam9260_soc = { |
21d08b9d | 387 | .map_io = at91sam9260_map_io, |
92100c12 | 388 | .default_irq_priority = at91sam9260_default_irq_priority, |
cfa5a1fe | 389 | .ioremap_registers = at91sam9260_ioremap_registers, |
51ddec76 | 390 | .register_clocks = at91sam9260_register_clocks, |
21d08b9d JCPV |
391 | .init = at91sam9260_initialize, |
392 | }; |