Commit | Line | Data |
---|---|---|
2b9ccf3c DL |
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> | |
2b9ccf3c | 18 | |
43d2f532 | 19 | #include "board.h" |
2b9ccf3c DL |
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 | }; | |
5d449e4b MR |
123 | static struct clk adc_op_clk = { |
124 | .name = "adc_op_clk", | |
125 | .type = CLK_TYPE_PERIPHERAL, | |
126 | .rate_hz = 5000000, | |
127 | }; | |
2b9ccf3c DL |
128 | static struct clk dma0_clk = { |
129 | .name = "dma0_clk", | |
130 | .pmc_mask = 1 << AT91SAM9X5_ID_DMA0, | |
131 | .type = CLK_TYPE_PERIPHERAL, | |
132 | }; | |
133 | static struct clk dma1_clk = { | |
134 | .name = "dma1_clk", | |
135 | .pmc_mask = 1 << AT91SAM9X5_ID_DMA1, | |
136 | .type = CLK_TYPE_PERIPHERAL, | |
137 | }; | |
138 | static struct clk uhphs_clk = { | |
6a062459 | 139 | .name = "uhphs", |
2b9ccf3c DL |
140 | .pmc_mask = 1 << AT91SAM9X5_ID_UHPHS, |
141 | .type = CLK_TYPE_PERIPHERAL, | |
142 | }; | |
143 | static struct clk udphs_clk = { | |
144 | .name = "udphs_clk", | |
145 | .pmc_mask = 1 << AT91SAM9X5_ID_UDPHS, | |
146 | .type = CLK_TYPE_PERIPHERAL, | |
147 | }; | |
148 | /* emac0 clock - Only for sam9g25/sam9x25/sam9g35/sam9x35 */ | |
149 | static struct clk macb0_clk = { | |
150 | .name = "pclk", | |
151 | .pmc_mask = 1 << AT91SAM9X5_ID_EMAC0, | |
152 | .type = CLK_TYPE_PERIPHERAL, | |
153 | }; | |
154 | /* lcd clock - Only for sam9g15/sam9g35/sam9x35 */ | |
155 | static struct clk lcdc_clk = { | |
156 | .name = "lcdc_clk", | |
157 | .pmc_mask = 1 << AT91SAM9X5_ID_LCDC, | |
158 | .type = CLK_TYPE_PERIPHERAL, | |
159 | }; | |
160 | /* isi clock - Only for sam9g25 */ | |
161 | static struct clk isi_clk = { | |
162 | .name = "isi_clk", | |
163 | .pmc_mask = 1 << AT91SAM9X5_ID_ISI, | |
164 | .type = CLK_TYPE_PERIPHERAL, | |
165 | }; | |
166 | static struct clk mmc1_clk = { | |
167 | .name = "mci1_clk", | |
168 | .pmc_mask = 1 << AT91SAM9X5_ID_MCI1, | |
169 | .type = CLK_TYPE_PERIPHERAL, | |
170 | }; | |
171 | /* emac1 clock - Only for sam9x25 */ | |
172 | static struct clk macb1_clk = { | |
173 | .name = "pclk", | |
174 | .pmc_mask = 1 << AT91SAM9X5_ID_EMAC1, | |
175 | .type = CLK_TYPE_PERIPHERAL, | |
176 | }; | |
177 | static struct clk ssc_clk = { | |
178 | .name = "ssc_clk", | |
179 | .pmc_mask = 1 << AT91SAM9X5_ID_SSC, | |
180 | .type = CLK_TYPE_PERIPHERAL, | |
181 | }; | |
182 | /* can0 clock - Only for sam9x35 */ | |
183 | static struct clk can0_clk = { | |
184 | .name = "can0_clk", | |
185 | .pmc_mask = 1 << AT91SAM9X5_ID_CAN0, | |
186 | .type = CLK_TYPE_PERIPHERAL, | |
187 | }; | |
188 | /* can1 clock - Only for sam9x35 */ | |
189 | static struct clk can1_clk = { | |
190 | .name = "can1_clk", | |
191 | .pmc_mask = 1 << AT91SAM9X5_ID_CAN1, | |
192 | .type = CLK_TYPE_PERIPHERAL, | |
193 | }; | |
194 | ||
195 | static struct clk *periph_clocks[] __initdata = { | |
196 | &pioAB_clk, | |
197 | &pioCD_clk, | |
198 | &smd_clk, | |
199 | &usart0_clk, | |
200 | &usart1_clk, | |
201 | &usart2_clk, | |
202 | &twi0_clk, | |
203 | &twi1_clk, | |
204 | &twi2_clk, | |
205 | &mmc0_clk, | |
206 | &spi0_clk, | |
207 | &spi1_clk, | |
208 | &uart0_clk, | |
209 | &uart1_clk, | |
210 | &tcb0_clk, | |
211 | &pwm_clk, | |
212 | &adc_clk, | |
5d449e4b | 213 | &adc_op_clk, |
2b9ccf3c DL |
214 | &dma0_clk, |
215 | &dma1_clk, | |
216 | &uhphs_clk, | |
217 | &udphs_clk, | |
218 | &mmc1_clk, | |
219 | &ssc_clk, | |
220 | // irq0 | |
221 | }; | |
222 | ||
223 | static struct clk_lookup periph_clocks_lookups[] = { | |
224 | /* lookup table for DT entries */ | |
225 | CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck), | |
226 | CLKDEV_CON_DEV_ID("usart", "f801c000.serial", &usart0_clk), | |
227 | CLKDEV_CON_DEV_ID("usart", "f8020000.serial", &usart1_clk), | |
228 | CLKDEV_CON_DEV_ID("usart", "f8024000.serial", &usart2_clk), | |
229 | CLKDEV_CON_DEV_ID("usart", "f8028000.serial", &usart3_clk), | |
230 | CLKDEV_CON_DEV_ID("t0_clk", "f8008000.timer", &tcb0_clk), | |
231 | CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), | |
23e3b24f LD |
232 | CLKDEV_CON_DEV_ID("mci_clk", "f0008000.mmc", &mmc0_clk), |
233 | CLKDEV_CON_DEV_ID("mci_clk", "f000c000.mmc", &mmc1_clk), | |
7bd95239 NF |
234 | CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk), |
235 | CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk), | |
099343c6 | 236 | CLKDEV_CON_DEV_ID("pclk", "f0010000.ssc", &ssc_clk), |
f7d19b90 LD |
237 | CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), |
238 | CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), | |
239 | CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk), | |
5314ec8e JCPV |
240 | CLKDEV_CON_DEV_ID(NULL, "fffff400.gpio", &pioAB_clk), |
241 | CLKDEV_CON_DEV_ID(NULL, "fffff600.gpio", &pioAB_clk), | |
242 | CLKDEV_CON_DEV_ID(NULL, "fffff800.gpio", &pioCD_clk), | |
243 | CLKDEV_CON_DEV_ID(NULL, "fffffa00.gpio", &pioCD_clk), | |
2b9ccf3c DL |
244 | /* additional fake clock for macb_hclk */ |
245 | CLKDEV_CON_DEV_ID("hclk", "f802c000.ethernet", &macb0_clk), | |
246 | CLKDEV_CON_DEV_ID("hclk", "f8030000.ethernet", &macb1_clk), | |
6a062459 JCPV |
247 | CLKDEV_CON_DEV_ID("hclk", "600000.ohci", &uhphs_clk), |
248 | CLKDEV_CON_DEV_ID("ohci_clk", "600000.ohci", &uhphs_clk), | |
62c5553a | 249 | CLKDEV_CON_DEV_ID("ehci_clk", "700000.ehci", &uhphs_clk), |
2b9ccf3c DL |
250 | }; |
251 | ||
252 | /* | |
253 | * The two programmable clocks. | |
254 | * You must configure pin multiplexing to bring these signals out. | |
255 | */ | |
256 | static struct clk pck0 = { | |
257 | .name = "pck0", | |
258 | .pmc_mask = AT91_PMC_PCK0, | |
259 | .type = CLK_TYPE_PROGRAMMABLE, | |
260 | .id = 0, | |
261 | }; | |
262 | static struct clk pck1 = { | |
263 | .name = "pck1", | |
264 | .pmc_mask = AT91_PMC_PCK1, | |
265 | .type = CLK_TYPE_PROGRAMMABLE, | |
266 | .id = 1, | |
267 | }; | |
268 | ||
269 | static void __init at91sam9x5_register_clocks(void) | |
270 | { | |
271 | int i; | |
272 | ||
273 | for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) | |
274 | clk_register(periph_clocks[i]); | |
275 | ||
276 | clkdev_add_table(periph_clocks_lookups, | |
277 | ARRAY_SIZE(periph_clocks_lookups)); | |
278 | ||
279 | if (cpu_is_at91sam9g25() | |
280 | || cpu_is_at91sam9x25()) | |
281 | clk_register(&usart3_clk); | |
282 | ||
283 | if (cpu_is_at91sam9g25() | |
284 | || cpu_is_at91sam9x25() | |
285 | || cpu_is_at91sam9g35() | |
286 | || cpu_is_at91sam9x35()) | |
287 | clk_register(&macb0_clk); | |
288 | ||
289 | if (cpu_is_at91sam9g15() | |
290 | || cpu_is_at91sam9g35() | |
291 | || cpu_is_at91sam9x35()) | |
292 | clk_register(&lcdc_clk); | |
293 | ||
294 | if (cpu_is_at91sam9g25()) | |
295 | clk_register(&isi_clk); | |
296 | ||
297 | if (cpu_is_at91sam9x25()) | |
298 | clk_register(&macb1_clk); | |
299 | ||
300 | if (cpu_is_at91sam9x25() | |
301 | || cpu_is_at91sam9x35()) { | |
302 | clk_register(&can0_clk); | |
303 | clk_register(&can1_clk); | |
304 | } | |
305 | ||
306 | clk_register(&pck0); | |
307 | clk_register(&pck1); | |
308 | } | |
309 | ||
310 | /* -------------------------------------------------------------------- | |
311 | * AT91SAM9x5 processor initialization | |
312 | * -------------------------------------------------------------------- */ | |
313 | ||
314 | static void __init at91sam9x5_map_io(void) | |
315 | { | |
316 | at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE); | |
317 | } | |
318 | ||
2b9ccf3c DL |
319 | /* -------------------------------------------------------------------- |
320 | * Interrupt initialization | |
321 | * -------------------------------------------------------------------- */ | |
2b9ccf3c | 322 | |
8d39e0fd | 323 | AT91_SOC_START(sam9x5) |
2b9ccf3c | 324 | .map_io = at91sam9x5_map_io, |
2b9ccf3c | 325 | .register_clocks = at91sam9x5_register_clocks, |
8d39e0fd | 326 | AT91_SOC_END |