diff options
Diffstat (limited to 'arch/m68k/platform/527x/config.c')
-rw-r--r-- | arch/m68k/platform/527x/config.c | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/arch/m68k/platform/527x/config.c b/arch/m68k/platform/527x/config.c new file mode 100644 index 000000000000..fa359593b613 --- /dev/null +++ b/arch/m68k/platform/527x/config.c | |||
@@ -0,0 +1,384 @@ | |||
1 | /***************************************************************************/ | ||
2 | |||
3 | /* | ||
4 | * linux/arch/m68knommu/platform/527x/config.c | ||
5 | * | ||
6 | * Sub-architcture dependant initialization code for the Freescale | ||
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 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/param.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/spi/spi.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <asm/machdep.h> | ||
22 | #include <asm/coldfire.h> | ||
23 | #include <asm/mcfsim.h> | ||
24 | #include <asm/mcfuart.h> | ||
25 | #include <asm/mcfqspi.h> | ||
26 | |||
27 | /***************************************************************************/ | ||
28 | |||
29 | static struct mcf_platform_uart m527x_uart_platform[] = { | ||
30 | { | ||
31 | .mapbase = MCFUART_BASE1, | ||
32 | .irq = MCFINT_VECBASE + MCFINT_UART0, | ||
33 | }, | ||
34 | { | ||
35 | .mapbase = MCFUART_BASE2, | ||
36 | .irq = MCFINT_VECBASE + MCFINT_UART1, | ||
37 | }, | ||
38 | { | ||
39 | .mapbase = MCFUART_BASE3, | ||
40 | .irq = MCFINT_VECBASE + MCFINT_UART2, | ||
41 | }, | ||
42 | { }, | ||
43 | }; | ||
44 | |||
45 | static struct platform_device m527x_uart = { | ||
46 | .name = "mcfuart", | ||
47 | .id = 0, | ||
48 | .dev.platform_data = m527x_uart_platform, | ||
49 | }; | ||
50 | |||
51 | static struct resource m527x_fec0_resources[] = { | ||
52 | { | ||
53 | .start = MCFFEC_BASE0, | ||
54 | .end = MCFFEC_BASE0 + MCFFEC_SIZE0 - 1, | ||
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 | { | ||
76 | .start = MCFFEC_BASE1, | ||
77 | .end = MCFFEC_BASE1 + MCFFEC_SIZE1 - 1, | ||
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 | |||
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 | |||
285 | static struct platform_device *m527x_devices[] __initdata = { | ||
286 | &m527x_uart, | ||
287 | &m527x_fec[0], | ||
288 | #ifdef CONFIG_FEC2 | ||
289 | &m527x_fec[1], | ||
290 | #endif | ||
291 | #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) | ||
292 | &m527x_qspi, | ||
293 | #endif | ||
294 | }; | ||
295 | |||
296 | /***************************************************************************/ | ||
297 | |||
298 | static void __init m527x_uart_init_line(int line, int irq) | ||
299 | { | ||
300 | u16 sepmask; | ||
301 | |||
302 | if ((line < 0) || (line > 2)) | ||
303 | return; | ||
304 | |||
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 | } | ||
326 | |||
327 | /***************************************************************************/ | ||
328 | |||
329 | static void __init m527x_fec_init(void) | ||
330 | { | ||
331 | u16 par; | ||
332 | u8 v; | ||
333 | |||
334 | /* Set multi-function pins to ethernet mode for fec0 */ | ||
335 | #if defined(CONFIG_M5271) | ||
336 | v = readb(MCF_IPSBAR + 0x100047); | ||
337 | writeb(v | 0xf0, MCF_IPSBAR + 0x100047); | ||
338 | #else | ||
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); | ||
343 | #endif | ||
344 | |||
345 | #ifdef CONFIG_FEC2 | ||
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 | |||
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 | |||
364 | void __init config_BSP(char *commandp, int size) | ||
365 | { | ||
366 | mach_reset = m527x_cpu_reset; | ||
367 | m527x_uarts_init(); | ||
368 | m527x_fec_init(); | ||
369 | #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) | ||
370 | m527x_qspi_init(); | ||
371 | #endif | ||
372 | } | ||
373 | |||
374 | /***************************************************************************/ | ||
375 | |||
376 | static int __init init_BSP(void) | ||
377 | { | ||
378 | platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices)); | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | arch_initcall(init_BSP); | ||
383 | |||
384 | /***************************************************************************/ | ||