diff options
author | Dan Liang <dan.liang@atmel.com> | 2011-03-10 13:08:55 -0500 |
---|---|---|
committer | Nicolas Ferre <nicolas.ferre@atmel.com> | 2012-02-03 09:36:40 -0500 |
commit | 2b9ccf3cc6326aeed1cecb02e4a312dd28a8322b (patch) | |
tree | 0a9e70c7d73a435c489d79868b353d6d715c304c /arch/arm/mach-at91 | |
parent | 9a3ee403df57ba4c8ba6bb5d422690143417b53d (diff) |
ARM: at91/at91sam9x5: SoC basic support
Add at91sam9x5.c SoC file: Define clock resources
and some initialization code.
Signed-off-by: Dan Liang <dan.liang@atmel.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'arch/arm/mach-at91')
-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/include/mach/hardware.h | 2 |
3 files changed, 376 insertions, 0 deletions
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/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 |