[SCSI] tcm_loop: Add multi-fabric Linux/SCSI LLD fabric module
[pandora-kernel.git] / arch / m68knommu / platform / 527x / config.c
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 /***************************************************************************/