]>
Commit | Line | Data |
---|---|---|
b5aaf3f7 GU |
1 | /***************************************************************************/ |
2 | ||
3 | /* | |
4 | * linux/arch/m68knommu/platform/523x/config.c | |
5 | * | |
25985edc | 6 | * Sub-architcture dependent initialization code for the Freescale |
b5aaf3f7 GU |
7 | * 523x CPUs. |
8 | * | |
9 | * Copyright (C) 1999-2005, Greg Ungerer (gerg@snapgear.com) | |
10 | * Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com) | |
11 | */ | |
12 | ||
13 | /***************************************************************************/ | |
14 | ||
b5aaf3f7 | 15 | #include <linux/kernel.h> |
b5aaf3f7 GU |
16 | #include <linux/param.h> |
17 | #include <linux/init.h> | |
4b61a353 | 18 | #include <linux/io.h> |
91d60417 SK |
19 | #include <linux/spi/spi.h> |
20 | #include <linux/gpio.h> | |
b5aaf3f7 GU |
21 | #include <asm/machdep.h> |
22 | #include <asm/coldfire.h> | |
23 | #include <asm/mcfsim.h> | |
4b61a353 | 24 | #include <asm/mcfuart.h> |
91d60417 | 25 | #include <asm/mcfqspi.h> |
b5aaf3f7 GU |
26 | |
27 | /***************************************************************************/ | |
28 | ||
4b61a353 GU |
29 | static struct mcf_platform_uart m523x_uart_platform[] = { |
30 | { | |
b62384af | 31 | .mapbase = MCFUART_BASE1, |
4b61a353 GU |
32 | .irq = MCFINT_VECBASE + MCFINT_UART0, |
33 | }, | |
34 | { | |
b62384af | 35 | .mapbase = MCFUART_BASE2, |
4b61a353 GU |
36 | .irq = MCFINT_VECBASE + MCFINT_UART0 + 1, |
37 | }, | |
38 | { | |
b62384af | 39 | .mapbase = MCFUART_BASE3, |
4b61a353 GU |
40 | .irq = MCFINT_VECBASE + MCFINT_UART0 + 2, |
41 | }, | |
42 | { }, | |
43 | }; | |
44 | ||
45 | static struct platform_device m523x_uart = { | |
46 | .name = "mcfuart", | |
47 | .id = 0, | |
48 | .dev.platform_data = m523x_uart_platform, | |
49 | }; | |
50 | ||
ffba3f48 GU |
51 | static struct resource m523x_fec_resources[] = { |
52 | { | |
b62384af GU |
53 | .start = MCFFEC_BASE, |
54 | .end = MCFFEC_BASE + MCFFEC_SIZE - 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 platform_device m523x_fec = { | |
75 | .name = "fec", | |
76 | .id = 0, | |
77 | .num_resources = ARRAY_SIZE(m523x_fec_resources), | |
78 | .resource = m523x_fec_resources, | |
79 | }; | |
80 | ||
91d60417 SK |
81 | #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) |
82 | static struct resource m523x_qspi_resources[] = { | |
83 | { | |
84 | .start = MCFQSPI_IOBASE, | |
85 | .end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1, | |
86 | .flags = IORESOURCE_MEM, | |
87 | }, | |
88 | { | |
89 | .start = MCFINT_VECBASE + MCFINT_QSPI, | |
90 | .end = MCFINT_VECBASE + MCFINT_QSPI, | |
91 | .flags = IORESOURCE_IRQ, | |
92 | }, | |
93 | }; | |
94 | ||
95 | #define MCFQSPI_CS0 91 | |
96 | #define MCFQSPI_CS1 92 | |
97 | #define MCFQSPI_CS2 103 | |
98 | #define MCFQSPI_CS3 99 | |
99 | ||
100 | static int m523x_cs_setup(struct mcfqspi_cs_control *cs_control) | |
101 | { | |
102 | int status; | |
103 | ||
104 | status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0"); | |
105 | if (status) { | |
106 | pr_debug("gpio_request for MCFQSPI_CS0 failed\n"); | |
107 | goto fail0; | |
108 | } | |
109 | status = gpio_direction_output(MCFQSPI_CS0, 1); | |
110 | if (status) { | |
111 | pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n"); | |
112 | goto fail1; | |
113 | } | |
114 | ||
115 | status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1"); | |
116 | if (status) { | |
117 | pr_debug("gpio_request for MCFQSPI_CS1 failed\n"); | |
118 | goto fail1; | |
119 | } | |
120 | status = gpio_direction_output(MCFQSPI_CS1, 1); | |
121 | if (status) { | |
122 | pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n"); | |
123 | goto fail2; | |
124 | } | |
125 | ||
126 | status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2"); | |
127 | if (status) { | |
128 | pr_debug("gpio_request for MCFQSPI_CS2 failed\n"); | |
129 | goto fail2; | |
130 | } | |
131 | status = gpio_direction_output(MCFQSPI_CS2, 1); | |
132 | if (status) { | |
133 | pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n"); | |
134 | goto fail3; | |
135 | } | |
136 | ||
137 | status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3"); | |
138 | if (status) { | |
139 | pr_debug("gpio_request for MCFQSPI_CS3 failed\n"); | |
140 | goto fail3; | |
141 | } | |
142 | status = gpio_direction_output(MCFQSPI_CS3, 1); | |
143 | if (status) { | |
144 | pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n"); | |
145 | goto fail4; | |
146 | } | |
147 | ||
148 | return 0; | |
149 | ||
150 | fail4: | |
151 | gpio_free(MCFQSPI_CS3); | |
152 | fail3: | |
153 | gpio_free(MCFQSPI_CS2); | |
154 | fail2: | |
155 | gpio_free(MCFQSPI_CS1); | |
156 | fail1: | |
157 | gpio_free(MCFQSPI_CS0); | |
158 | fail0: | |
159 | return status; | |
160 | } | |
161 | ||
162 | static void m523x_cs_teardown(struct mcfqspi_cs_control *cs_control) | |
163 | { | |
164 | gpio_free(MCFQSPI_CS3); | |
165 | gpio_free(MCFQSPI_CS2); | |
166 | gpio_free(MCFQSPI_CS1); | |
167 | gpio_free(MCFQSPI_CS0); | |
168 | } | |
169 | ||
170 | static void m523x_cs_select(struct mcfqspi_cs_control *cs_control, | |
171 | u8 chip_select, bool cs_high) | |
172 | { | |
173 | switch (chip_select) { | |
174 | case 0: | |
175 | gpio_set_value(MCFQSPI_CS0, cs_high); | |
176 | break; | |
177 | case 1: | |
178 | gpio_set_value(MCFQSPI_CS1, cs_high); | |
179 | break; | |
180 | case 2: | |
181 | gpio_set_value(MCFQSPI_CS2, cs_high); | |
182 | break; | |
183 | case 3: | |
184 | gpio_set_value(MCFQSPI_CS3, cs_high); | |
185 | break; | |
186 | } | |
187 | } | |
188 | ||
189 | static void m523x_cs_deselect(struct mcfqspi_cs_control *cs_control, | |
190 | u8 chip_select, bool cs_high) | |
191 | { | |
192 | switch (chip_select) { | |
193 | case 0: | |
194 | gpio_set_value(MCFQSPI_CS0, !cs_high); | |
195 | break; | |
196 | case 1: | |
197 | gpio_set_value(MCFQSPI_CS1, !cs_high); | |
198 | break; | |
199 | case 2: | |
200 | gpio_set_value(MCFQSPI_CS2, !cs_high); | |
201 | break; | |
202 | case 3: | |
203 | gpio_set_value(MCFQSPI_CS3, !cs_high); | |
204 | break; | |
205 | } | |
206 | } | |
207 | ||
208 | static struct mcfqspi_cs_control m523x_cs_control = { | |
209 | .setup = m523x_cs_setup, | |
210 | .teardown = m523x_cs_teardown, | |
211 | .select = m523x_cs_select, | |
212 | .deselect = m523x_cs_deselect, | |
213 | }; | |
214 | ||
215 | static struct mcfqspi_platform_data m523x_qspi_data = { | |
216 | .bus_num = 0, | |
217 | .num_chipselect = 4, | |
218 | .cs_control = &m523x_cs_control, | |
219 | }; | |
220 | ||
221 | static struct platform_device m523x_qspi = { | |
222 | .name = "mcfqspi", | |
223 | .id = 0, | |
224 | .num_resources = ARRAY_SIZE(m523x_qspi_resources), | |
225 | .resource = m523x_qspi_resources, | |
226 | .dev.platform_data = &m523x_qspi_data, | |
227 | }; | |
228 | ||
229 | static void __init m523x_qspi_init(void) | |
230 | { | |
231 | u16 par; | |
232 | ||
233 | /* setup QSPS pins for QSPI with gpio CS control */ | |
234 | writeb(0x1f, MCFGPIO_PAR_QSPI); | |
235 | /* and CS2 & CS3 as gpio */ | |
236 | par = readw(MCFGPIO_PAR_TIMER); | |
237 | par &= 0x3f3f; | |
238 | writew(par, MCFGPIO_PAR_TIMER); | |
239 | } | |
240 | #endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */ | |
241 | ||
4b61a353 GU |
242 | static struct platform_device *m523x_devices[] __initdata = { |
243 | &m523x_uart, | |
ffba3f48 | 244 | &m523x_fec, |
91d60417 SK |
245 | #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) |
246 | &m523x_qspi, | |
247 | #endif | |
b5aaf3f7 GU |
248 | }; |
249 | ||
4b61a353 GU |
250 | /***************************************************************************/ |
251 | ||
14c16db3 GU |
252 | static void __init m523x_fec_init(void) |
253 | { | |
254 | u16 par; | |
255 | u8 v; | |
256 | ||
257 | /* Set multi-function pins to ethernet use */ | |
258 | par = readw(MCF_IPSBAR + 0x100082); | |
259 | writew(par | 0xf00, MCF_IPSBAR + 0x100082); | |
260 | v = readb(MCF_IPSBAR + 0x100078); | |
261 | writeb(v | 0xc0, MCF_IPSBAR + 0x100078); | |
262 | } | |
263 | ||
264 | /***************************************************************************/ | |
265 | ||
55b33f31 GU |
266 | static void m523x_cpu_reset(void) |
267 | { | |
268 | local_irq_disable(); | |
269 | __raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR); | |
270 | } | |
b5aaf3f7 GU |
271 | |
272 | /***************************************************************************/ | |
273 | ||
4b61a353 | 274 | void __init config_BSP(char *commandp, int size) |
b5aaf3f7 | 275 | { |
55b33f31 | 276 | mach_reset = m523x_cpu_reset; |
b5aaf3f7 GU |
277 | } |
278 | ||
279 | /***************************************************************************/ | |
4b61a353 GU |
280 | |
281 | static int __init init_BSP(void) | |
282 | { | |
14c16db3 | 283 | m523x_fec_init(); |
91d60417 SK |
284 | #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) |
285 | m523x_qspi_init(); | |
286 | #endif | |
4b61a353 GU |
287 | platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices)); |
288 | return 0; | |
289 | } | |
290 | ||
291 | arch_initcall(init_BSP); | |
292 | ||
293 | /***************************************************************************/ |