Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /***************************************************************************/ |
2 | ||
3 | /* | |
4 | * linux/arch/m68knommu/platform/527x/config.c | |
5 | * | |
25985edc | 6 | * Sub-architcture dependent initialization code for the Freescale |
1da177e4 LT |
7 | * 5270/5271 CPUs. |
8 | * | |
9 | * Copyright (C) 1999-2004, Greg Ungerer (gerg@snapgear.com) | |
10 | * Copyright (C) 2001-2004, SnapGear Inc. (www.snapgear.com) | |
11 | */ | |
12 | ||
13 | /***************************************************************************/ | |
14 | ||
1da177e4 | 15 | #include <linux/kernel.h> |
1da177e4 LT |
16 | #include <linux/param.h> |
17 | #include <linux/init.h> | |
e206da0b | 18 | #include <linux/io.h> |
91d60417 SK |
19 | #include <linux/spi/spi.h> |
20 | #include <linux/gpio.h> | |
1da177e4 LT |
21 | #include <asm/machdep.h> |
22 | #include <asm/coldfire.h> | |
23 | #include <asm/mcfsim.h> | |
e206da0b | 24 | #include <asm/mcfuart.h> |
91d60417 | 25 | #include <asm/mcfqspi.h> |
1da177e4 LT |
26 | |
27 | /***************************************************************************/ | |
28 | ||
e206da0b GU |
29 | static struct mcf_platform_uart m527x_uart_platform[] = { |
30 | { | |
20e681fd GU |
31 | .mapbase = MCFUART_BASE0, |
32 | .irq = MCF_IRQ_UART0, | |
e206da0b GU |
33 | }, |
34 | { | |
20e681fd GU |
35 | .mapbase = MCFUART_BASE1, |
36 | .irq = MCF_IRQ_UART1, | |
e206da0b GU |
37 | }, |
38 | { | |
20e681fd GU |
39 | .mapbase = MCFUART_BASE2, |
40 | .irq = MCF_IRQ_UART2, | |
e206da0b GU |
41 | }, |
42 | { }, | |
1da177e4 LT |
43 | }; |
44 | ||
e206da0b GU |
45 | static struct platform_device m527x_uart = { |
46 | .name = "mcfuart", | |
47 | .id = 0, | |
48 | .dev.platform_data = m527x_uart_platform, | |
49 | }; | |
50 | ||
ffba3f48 GU |
51 | static struct resource m527x_fec0_resources[] = { |
52 | { | |
9a6b0c73 GU |
53 | .start = MCFFEC_BASE0, |
54 | .end = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1, | |
ffba3f48 GU |
55 | .flags = IORESOURCE_MEM, |
56 | }, | |
57 | { | |
58 | .start = 64 + 23, | |
59 | .end = 64 + 23, | |
60 | .flags = IORESOURCE_IRQ, | |
61 | }, | |
62 | { | |
63 | .start = 64 + 27, | |
64 | .end = 64 + 27, | |
65 | .flags = IORESOURCE_IRQ, | |
66 | }, | |
67 | { | |
68 | .start = 64 + 29, | |
69 | .end = 64 + 29, | |
70 | .flags = IORESOURCE_IRQ, | |
71 | }, | |
72 | }; | |
73 | ||
74 | static struct resource m527x_fec1_resources[] = { | |
75 | { | |
9a6b0c73 GU |
76 | .start = MCFFEC_BASE1, |
77 | .end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1, | |
ffba3f48 GU |
78 | .flags = IORESOURCE_MEM, |
79 | }, | |
80 | { | |
81 | .start = 128 + 23, | |
82 | .end = 128 + 23, | |
83 | .flags = IORESOURCE_IRQ, | |
84 | }, | |
85 | { | |
86 | .start = 128 + 27, | |
87 | .end = 128 + 27, | |
88 | .flags = IORESOURCE_IRQ, | |
89 | }, | |
90 | { | |
91 | .start = 128 + 29, | |
92 | .end = 128 + 29, | |
93 | .flags = IORESOURCE_IRQ, | |
94 | }, | |
95 | }; | |
96 | ||
97 | static struct platform_device m527x_fec[] = { | |
98 | { | |
99 | .name = "fec", | |
100 | .id = 0, | |
101 | .num_resources = ARRAY_SIZE(m527x_fec0_resources), | |
102 | .resource = m527x_fec0_resources, | |
103 | }, | |
104 | { | |
105 | .name = "fec", | |
106 | .id = 1, | |
107 | .num_resources = ARRAY_SIZE(m527x_fec1_resources), | |
108 | .resource = m527x_fec1_resources, | |
109 | }, | |
110 | }; | |
111 | ||
91d60417 SK |
112 | #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) |
113 | static struct resource m527x_qspi_resources[] = { | |
114 | { | |
115 | .start = MCFQSPI_IOBASE, | |
116 | .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, | |
117 | .flags = IORESOURCE_MEM, | |
118 | }, | |
119 | { | |
120 | .start = MCFINT_VECBASE + MCFINT_QSPI, | |
121 | .end = MCFINT_VECBASE + MCFINT_QSPI, | |
122 | .flags = IORESOURCE_IRQ, | |
123 | }, | |
124 | }; | |
125 | ||
126 | #if defined(CONFIG_M5271) | |
127 | #define MCFQSPI_CS0 91 | |
128 | #define MCFQSPI_CS1 92 | |
129 | #define MCFQSPI_CS2 99 | |
130 | #define MCFQSPI_CS3 103 | |
131 | #elif defined(CONFIG_M5275) | |
132 | #define MCFQSPI_CS0 59 | |
133 | #define MCFQSPI_CS1 60 | |
134 | #define MCFQSPI_CS2 61 | |
135 | #define MCFQSPI_CS3 62 | |
136 | #endif | |
137 | ||
138 | static int m527x_cs_setup(struct mcfqspi_cs_control *cs_control) | |
139 | { | |
140 | int status; | |
141 | ||
142 | status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); | |
143 | if (status) { | |
144 | pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); | |
145 | goto fail0; | |
146 | } | |
147 | status = gpio_direction_output(MCFQSPI_CS0, 1); | |
148 | if (status) { | |
149 | pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); | |
150 | goto fail1; | |
151 | } | |
152 | ||
153 | status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); | |
154 | if (status) { | |
155 | pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); | |
156 | goto fail1; | |
157 | } | |
158 | status = gpio_direction_output(MCFQSPI_CS1, 1); | |
159 | if (status) { | |
160 | pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); | |
161 | goto fail2; | |
162 | } | |
163 | ||
164 | status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); | |
165 | if (status) { | |
166 | pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); | |
167 | goto fail2; | |
168 | } | |
169 | status = gpio_direction_output(MCFQSPI_CS2, 1); | |
170 | if (status) { | |
171 | pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); | |
172 | goto fail3; | |
173 | } | |
174 | ||
175 | status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); | |
176 | if (status) { | |
177 | pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); | |
178 | goto fail3; | |
179 | } | |
180 | status = gpio_direction_output(MCFQSPI_CS3, 1); | |
181 | if (status) { | |
182 | pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); | |
183 | goto fail4; | |
184 | } | |
185 | ||
186 | return 0; | |
187 | ||
188 | fail4: | |
189 | gpio_free(MCFQSPI_CS3); | |
190 | fail3: | |
191 | gpio_free(MCFQSPI_CS2); | |
192 | fail2: | |
193 | gpio_free(MCFQSPI_CS1); | |
194 | fail1: | |
195 | gpio_free(MCFQSPI_CS0); | |
196 | fail0: | |
197 | return status; | |
198 | } | |
199 | ||
200 | static void m527x_cs_teardown(struct mcfqspi_cs_control *cs_control) | |
201 | { | |
202 | gpio_free(MCFQSPI_CS3); | |
203 | gpio_free(MCFQSPI_CS2); | |
204 | gpio_free(MCFQSPI_CS1); | |
205 | gpio_free(MCFQSPI_CS0); | |
206 | } | |
207 | ||
208 | static void m527x_cs_select(struct mcfqspi_cs_control *cs_control, | |
209 | u8 chip_select, bool cs_high) | |
210 | { | |
211 | switch (chip_select) { | |
212 | case 0: | |
213 | gpio_set_value(MCFQSPI_CS0, cs_high); | |
214 | break; | |
215 | case 1: | |
216 | gpio_set_value(MCFQSPI_CS1, cs_high); | |
217 | break; | |
218 | case 2: | |
219 | gpio_set_value(MCFQSPI_CS2, cs_high); | |
220 | break; | |
221 | case 3: | |
222 | gpio_set_value(MCFQSPI_CS3, cs_high); | |
223 | break; | |
224 | } | |
225 | } | |
226 | ||
227 | static void m527x_cs_deselect(struct mcfqspi_cs_control *cs_control, | |
228 | u8 chip_select, bool cs_high) | |
229 | { | |
230 | switch (chip_select) { | |
231 | case 0: | |
232 | gpio_set_value(MCFQSPI_CS0, !cs_high); | |
233 | break; | |
234 | case 1: | |
235 | gpio_set_value(MCFQSPI_CS1, !cs_high); | |
236 | break; | |
237 | case 2: | |
238 | gpio_set_value(MCFQSPI_CS2, !cs_high); | |
239 | break; | |
240 | case 3: | |
241 | gpio_set_value(MCFQSPI_CS3, !cs_high); | |
242 | break; | |
243 | } | |
244 | } | |
245 | ||
246 | static struct mcfqspi_cs_control m527x_cs_control = { | |
247 | .setup = m527x_cs_setup, | |
248 | .teardown = m527x_cs_teardown, | |
249 | .select = m527x_cs_select, | |
250 | .deselect = m527x_cs_deselect, | |
251 | }; | |
252 | ||
253 | static struct mcfqspi_platform_data m527x_qspi_data = { | |
254 | .bus_num = 0, | |
255 | .num_chipselect = 4, | |
256 | .cs_control = &m527x_cs_control, | |
257 | }; | |
258 | ||
259 | static struct platform_device m527x_qspi = { | |
260 | .name = "mcfqspi", | |
261 | .id = 0, | |
262 | .num_resources = ARRAY_SIZE(m527x_qspi_resources), | |
263 | .resource = m527x_qspi_resources, | |
264 | .dev.platform_data = &m527x_qspi_data, | |
265 | }; | |
266 | ||
267 | static void __init m527x_qspi_init(void) | |
268 | { | |
269 | #if defined(CONFIG_M5271) | |
270 | u16 par; | |
271 | ||
272 | /* setup QSPS pins for QSPI with gpio CS control */ | |
273 | writeb(0x1f, MCFGPIO_PAR_QSPI); | |
274 | /* and CS2 & CS3 as gpio */ | |
275 | par = readw(MCFGPIO_PAR_TIMER); | |
276 | par &= 0x3f3f; | |
277 | writew(par, MCFGPIO_PAR_TIMER); | |
278 | #elif defined(CONFIG_M5275) | |
279 | /* setup QSPS pins for QSPI with gpio CS control */ | |
280 | writew(0x003e, MCFGPIO_PAR_QSPI); | |
281 | #endif | |
282 | } | |
283 | #endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ | |
284 | ||
e206da0b GU |
285 | static struct platform_device *m527x_devices[] __initdata = { |
286 | &m527x_uart, | |
ffba3f48 GU |
287 | &m527x_fec[0], |
288 | #ifdef CONFIG_FEC2 | |
289 | &m527x_fec[1], | |
290 | #endif | |
91d60417 SK |
291 | #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) |
292 | &m527x_qspi, | |
293 | #endif | |
e206da0b GU |
294 | }; |
295 | ||
296 | /***************************************************************************/ | |
297 | ||
e206da0b GU |
298 | static void __init m527x_uart_init_line(int line, int irq) |
299 | { | |
300 | u16 sepmask; | |
e206da0b GU |
301 | |
302 | if ((line < 0) || (line > 2)) | |
303 | return; | |
304 | ||
e206da0b GU |
305 | /* |
306 | * External Pin Mask Setting & Enable External Pin for Interface | |
307 | */ | |
308 | sepmask = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); | |
309 | if (line == 0) | |
310 | sepmask |= UART0_ENABLE_MASK; | |
311 | else if (line == 1) | |
312 | sepmask |= UART1_ENABLE_MASK; | |
313 | else if (line == 2) | |
314 | sepmask |= UART2_ENABLE_MASK; | |
315 | writew(sepmask, MCF_IPSBAR + MCF_GPIO_PAR_UART); | |
316 | } | |
317 | ||
318 | static void __init m527x_uarts_init(void) | |
319 | { | |
320 | const int nrlines = ARRAY_SIZE(m527x_uart_platform); | |
321 | int line; | |
322 | ||
323 | for (line = 0; (line < nrlines); line++) | |
324 | m527x_uart_init_line(line, m527x_uart_platform[line].irq); | |
325 | } | |
1da177e4 LT |
326 | |
327 | /***************************************************************************/ | |
328 | ||
ffba3f48 GU |
329 | static void __init m527x_fec_init(void) |
330 | { | |
331 | u16 par; | |
332 | u8 v; | |
333 | ||
ffba3f48 | 334 | /* Set multi-function pins to ethernet mode for fec0 */ |
592578a1 RR |
335 | #if defined(CONFIG_M5271) |
336 | v = readb(MCF_IPSBAR + 0x100047); | |
337 | writeb(v | 0xf0, MCF_IPSBAR + 0x100047); | |
338 | #else | |
ffba3f48 GU |
339 | par = readw(MCF_IPSBAR + 0x100082); |
340 | writew(par | 0xf00, MCF_IPSBAR + 0x100082); | |
341 | v = readb(MCF_IPSBAR + 0x100078); | |
342 | writeb(v | 0xc0, MCF_IPSBAR + 0x100078); | |
592578a1 | 343 | #endif |
ffba3f48 GU |
344 | |
345 | #ifdef CONFIG_FEC2 | |
ffba3f48 GU |
346 | /* Set multi-function pins to ethernet mode for fec1 */ |
347 | par = readw(MCF_IPSBAR + 0x100082); | |
348 | writew(par | 0xa0, MCF_IPSBAR + 0x100082); | |
349 | v = readb(MCF_IPSBAR + 0x100079); | |
350 | writeb(v | 0xc0, MCF_IPSBAR + 0x100079); | |
351 | #endif | |
352 | } | |
353 | ||
354 | /***************************************************************************/ | |
355 | ||
4c0b008d GU |
356 | static void m527x_cpu_reset(void) |
357 | { | |
358 | local_irq_disable(); | |
359 | __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR); | |
360 | } | |
361 | ||
362 | /***************************************************************************/ | |
363 | ||
e206da0b | 364 | void __init config_BSP(char *commandp, int size) |
1da177e4 | 365 | { |
4c0b008d | 366 | mach_reset = m527x_cpu_reset; |
35aefb26 | 367 | mach_sched_init = hw_timer_init; |
ffba3f48 GU |
368 | m527x_uarts_init(); |
369 | m527x_fec_init(); | |
91d60417 SK |
370 | #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) |
371 | m527x_qspi_init(); | |
372 | #endif | |
1da177e4 LT |
373 | } |
374 | ||
375 | /***************************************************************************/ | |
e206da0b GU |
376 | |
377 | static int __init init_BSP(void) | |
378 | { | |
e206da0b GU |
379 | platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices)); |
380 | return 0; | |
381 | } | |
382 | ||
383 | arch_initcall(init_BSP); | |
384 | ||
385 | /***************************************************************************/ |