]> Pileus Git - ~andy/linux/blob - arch/m68knommu/platform/5249/config.c
m68knommu: Coldfire QSPI platform support
[~andy/linux] / arch / m68knommu / platform / 5249 / config.c
1 /***************************************************************************/
2
3 /*
4  *      linux/arch/m68knommu/platform/5249/config.c
5  *
6  *      Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
7  */
8
9 /***************************************************************************/
10
11 #include <linux/kernel.h>
12 #include <linux/param.h>
13 #include <linux/init.h>
14 #include <linux/io.h>
15 #include <linux/spi/spi.h>
16 #include <linux/gpio.h>
17 #include <asm/machdep.h>
18 #include <asm/coldfire.h>
19 #include <asm/mcfsim.h>
20 #include <asm/mcfuart.h>
21 #include <asm/mcfqspi.h>
22
23 /***************************************************************************/
24
25 static struct mcf_platform_uart m5249_uart_platform[] = {
26         {
27                 .mapbase        = MCF_MBAR + MCFUART_BASE1,
28                 .irq            = 73,
29         },
30         {
31                 .mapbase        = MCF_MBAR + MCFUART_BASE2,
32                 .irq            = 74,
33         },
34         { },
35 };
36
37 static struct platform_device m5249_uart = {
38         .name                   = "mcfuart",
39         .id                     = 0,
40         .dev.platform_data      = m5249_uart_platform,
41 };
42
43 #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
44 static struct resource m5249_qspi_resources[] = {
45         {
46                 .start          = MCFQSPI_IOBASE,
47                 .end            = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
48                 .flags          = IORESOURCE_MEM,
49         },
50         {
51                 .start          = MCF_IRQ_QSPI,
52                 .end            = MCF_IRQ_QSPI,
53                 .flags          = IORESOURCE_IRQ,
54         },
55 };
56
57 #define MCFQSPI_CS0    29
58 #define MCFQSPI_CS1    24
59 #define MCFQSPI_CS2    21
60 #define MCFQSPI_CS3    22
61
62 static int m5249_cs_setup(struct mcfqspi_cs_control *cs_control)
63 {
64         int status;
65
66         status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
67         if (status) {
68                 pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
69                 goto fail0;
70         }
71         status = gpio_direction_output(MCFQSPI_CS0, 1);
72         if (status) {
73                 pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
74                 goto fail1;
75         }
76
77         status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
78         if (status) {
79                 pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
80                 goto fail1;
81         }
82         status = gpio_direction_output(MCFQSPI_CS1, 1);
83         if (status) {
84                 pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
85                 goto fail2;
86         }
87
88         status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
89         if (status) {
90                 pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
91                 goto fail2;
92         }
93         status = gpio_direction_output(MCFQSPI_CS2, 1);
94         if (status) {
95                 pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
96                 goto fail3;
97         }
98
99         status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
100         if (status) {
101                 pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
102                 goto fail3;
103         }
104         status = gpio_direction_output(MCFQSPI_CS3, 1);
105         if (status) {
106                 pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
107                 goto fail4;
108         }
109
110         return 0;
111
112 fail4:
113         gpio_free(MCFQSPI_CS3);
114 fail3:
115         gpio_free(MCFQSPI_CS2);
116 fail2:
117         gpio_free(MCFQSPI_CS1);
118 fail1:
119         gpio_free(MCFQSPI_CS0);
120 fail0:
121         return status;
122 }
123
124 static void m5249_cs_teardown(struct mcfqspi_cs_control *cs_control)
125 {
126         gpio_free(MCFQSPI_CS3);
127         gpio_free(MCFQSPI_CS2);
128         gpio_free(MCFQSPI_CS1);
129         gpio_free(MCFQSPI_CS0);
130 }
131
132 static void m5249_cs_select(struct mcfqspi_cs_control *cs_control,
133                             u8 chip_select, bool cs_high)
134 {
135         switch (chip_select) {
136         case 0:
137                 gpio_set_value(MCFQSPI_CS0, cs_high);
138                 break;
139         case 1:
140                 gpio_set_value(MCFQSPI_CS1, cs_high);
141                 break;
142         case 2:
143                 gpio_set_value(MCFQSPI_CS2, cs_high);
144                 break;
145         case 3:
146                 gpio_set_value(MCFQSPI_CS3, cs_high);
147                 break;
148         }
149 }
150
151 static void m5249_cs_deselect(struct mcfqspi_cs_control *cs_control,
152                               u8 chip_select, bool cs_high)
153 {
154         switch (chip_select) {
155         case 0:
156                 gpio_set_value(MCFQSPI_CS0, !cs_high);
157                 break;
158         case 1:
159                 gpio_set_value(MCFQSPI_CS1, !cs_high);
160                 break;
161         case 2:
162                 gpio_set_value(MCFQSPI_CS2, !cs_high);
163                 break;
164         case 3:
165                 gpio_set_value(MCFQSPI_CS3, !cs_high);
166                 break;
167         }
168 }
169
170 static struct mcfqspi_cs_control m5249_cs_control = {
171         .setup                  = m5249_cs_setup,
172         .teardown               = m5249_cs_teardown,
173         .select                 = m5249_cs_select,
174         .deselect               = m5249_cs_deselect,
175 };
176
177 static struct mcfqspi_platform_data m5249_qspi_data = {
178         .bus_num                = 0,
179         .num_chipselect         = 4,
180         .cs_control             = &m5249_cs_control,
181 };
182
183 static struct platform_device m5249_qspi = {
184         .name                   = "mcfqspi",
185         .id                     = 0,
186         .num_resources          = ARRAY_SIZE(m5249_qspi_resources),
187         .resource               = m5249_qspi_resources,
188         .dev.platform_data      = &m5249_qspi_data,
189 };
190
191 static void __init m5249_qspi_init(void)
192 {
193         /* QSPI irq setup */
194         writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0,
195                MCF_MBAR + MCFSIM_QSPIICR);
196         mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
197 }
198 #endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
199
200
201 static struct platform_device *m5249_devices[] __initdata = {
202         &m5249_uart,
203 #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
204         &m5249_qspi,
205 #endif
206 };
207
208 /***************************************************************************/
209
210 static void __init m5249_uart_init_line(int line, int irq)
211 {
212         if (line == 0) {
213                 writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1, MCF_MBAR + MCFSIM_UART1ICR);
214                 writeb(irq, MCF_MBAR + MCFUART_BASE1 + MCFUART_UIVR);
215                 mcf_mapirq2imr(irq, MCFINTC_UART0);
216         } else if (line == 1) {
217                 writeb(MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2, MCF_MBAR + MCFSIM_UART2ICR);
218                 writeb(irq, MCF_MBAR + MCFUART_BASE2 + MCFUART_UIVR);
219                 mcf_mapirq2imr(irq, MCFINTC_UART1);
220         }
221 }
222
223 static void __init m5249_uarts_init(void)
224 {
225         const int nrlines = ARRAY_SIZE(m5249_uart_platform);
226         int line;
227
228         for (line = 0; (line < nrlines); line++)
229                 m5249_uart_init_line(line, m5249_uart_platform[line].irq);
230 }
231
232 /***************************************************************************/
233
234 static void __init m5249_timers_init(void)
235 {
236         /* Timer1 is always used as system timer */
237         writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI3,
238                 MCF_MBAR + MCFSIM_TIMER1ICR);
239         mcf_mapirq2imr(MCF_IRQ_TIMER, MCFINTC_TIMER1);
240
241 #ifdef CONFIG_HIGHPROFILE
242         /* Timer2 is to be used as a high speed profile timer  */
243         writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL7 | MCFSIM_ICR_PRI3,
244                 MCF_MBAR + MCFSIM_TIMER2ICR);
245         mcf_mapirq2imr(MCF_IRQ_PROFILER, MCFINTC_TIMER2);
246 #endif
247 }
248
249 /***************************************************************************/
250
251 void m5249_cpu_reset(void)
252 {
253         local_irq_disable();
254         /* Set watchdog to soft reset, and enabled */
255         __raw_writeb(0xc0, MCF_MBAR + MCFSIM_SYPCR);
256         for (;;)
257                 /* wait for watchdog to timeout */;
258 }
259
260 /***************************************************************************/
261
262 void __init config_BSP(char *commandp, int size)
263 {
264         mach_reset = m5249_cpu_reset;
265         m5249_timers_init();
266         m5249_uarts_init();
267 #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
268         m5249_qspi_init();
269 #endif
270 }
271
272 /***************************************************************************/
273
274 static int __init init_BSP(void)
275 {
276         platform_add_devices(m5249_devices, ARRAY_SIZE(m5249_devices));
277         return 0;
278 }
279
280 arch_initcall(init_BSP);
281
282 /***************************************************************************/