1 /***************************************************************************/
2 
3 /*
4  *	linux/arch/m68knommu/platform/528x/config.c
5  *
6  *	Sub-architcture dependent initialization code for the Freescale
7  *	5280, 5281 and 5282 CPUs.
8  *
9  *	Copyright (C) 1999-2003, Greg Ungerer (gerg@snapgear.com)
10  *	Copyright (C) 2001-2003, 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/platform_device.h>
19 #include <linux/io.h>
20 #include <linux/spi/spi.h>
21 #include <linux/gpio.h>
22 #include <asm/machdep.h>
23 #include <asm/coldfire.h>
24 #include <asm/mcfsim.h>
25 #include <asm/mcfuart.h>
26 #include <asm/mcfqspi.h>
27 
28 /***************************************************************************/
29 
30 static struct mcf_platform_uart m528x_uart_platform[] = {
31 	{
32 		.mapbase	= MCFUART_BASE1,
33 		.irq		= MCFINT_VECBASE + MCFINT_UART0,
34 	},
35 	{
36 		.mapbase 	= MCFUART_BASE2,
37 		.irq		= MCFINT_VECBASE + MCFINT_UART0 + 1,
38 	},
39 	{
40 		.mapbase 	= MCFUART_BASE3,
41 		.irq		= MCFINT_VECBASE + MCFINT_UART0 + 2,
42 	},
43 	{ },
44 };
45 
46 static struct platform_device m528x_uart = {
47 	.name			= "mcfuart",
48 	.id			= 0,
49 	.dev.platform_data	= m528x_uart_platform,
50 };
51 
52 static struct resource m528x_fec_resources[] = {
53 	{
54 		.start		= MCFFEC_BASE,
55 		.end		= MCFFEC_BASE + MCFFEC_SIZE - 1,
56 		.flags		= IORESOURCE_MEM,
57 	},
58 	{
59 		.start		= 64 + 23,
60 		.end		= 64 + 23,
61 		.flags		= IORESOURCE_IRQ,
62 	},
63 	{
64 		.start		= 64 + 27,
65 		.end		= 64 + 27,
66 		.flags		= IORESOURCE_IRQ,
67 	},
68 	{
69 		.start		= 64 + 29,
70 		.end		= 64 + 29,
71 		.flags		= IORESOURCE_IRQ,
72 	},
73 };
74 
75 static struct platform_device m528x_fec = {
76 	.name			= "fec",
77 	.id			= 0,
78 	.num_resources		= ARRAY_SIZE(m528x_fec_resources),
79 	.resource		= m528x_fec_resources,
80 };
81 
82 #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
83 static struct resource m528x_qspi_resources[] = {
84 	{
85 		.start		= MCFQSPI_IOBASE,
86 		.end		= MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
87 		.flags		= IORESOURCE_MEM,
88 	},
89 	{
90 		.start		= MCFINT_VECBASE + MCFINT_QSPI,
91 		.end		= MCFINT_VECBASE + MCFINT_QSPI,
92 		.flags		= IORESOURCE_IRQ,
93 	},
94 };
95 
96 #define MCFQSPI_CS0    147
97 #define MCFQSPI_CS1    148
98 #define MCFQSPI_CS2    149
99 #define MCFQSPI_CS3    150
100 
m528x_cs_setup(struct mcfqspi_cs_control * cs_control)101 static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control)
102 {
103 	int status;
104 
105 	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
106 	if (status) {
107 		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
108 		goto fail0;
109 	}
110 	status = gpio_direction_output(MCFQSPI_CS0, 1);
111 	if (status) {
112 		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
113 		goto fail1;
114 	}
115 
116 	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
117 	if (status) {
118 		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
119 		goto fail1;
120 	}
121 	status = gpio_direction_output(MCFQSPI_CS1, 1);
122 	if (status) {
123 		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
124 		goto fail2;
125 	}
126 
127 	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
128 	if (status) {
129 		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
130 		goto fail2;
131 	}
132 	status = gpio_direction_output(MCFQSPI_CS2, 1);
133 	if (status) {
134 		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
135 		goto fail3;
136 	}
137 
138 	status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
139 	if (status) {
140 		pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
141 		goto fail3;
142 	}
143 	status = gpio_direction_output(MCFQSPI_CS3, 1);
144 	if (status) {
145 		pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
146 		goto fail4;
147 	}
148 
149 	return 0;
150 
151 fail4:
152 	gpio_free(MCFQSPI_CS3);
153 fail3:
154 	gpio_free(MCFQSPI_CS2);
155 fail2:
156 	gpio_free(MCFQSPI_CS1);
157 fail1:
158 	gpio_free(MCFQSPI_CS0);
159 fail0:
160 	return status;
161 }
162 
m528x_cs_teardown(struct mcfqspi_cs_control * cs_control)163 static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control)
164 {
165 	gpio_free(MCFQSPI_CS3);
166 	gpio_free(MCFQSPI_CS2);
167 	gpio_free(MCFQSPI_CS1);
168 	gpio_free(MCFQSPI_CS0);
169 }
170 
m528x_cs_select(struct mcfqspi_cs_control * cs_control,u8 chip_select,bool cs_high)171 static void m528x_cs_select(struct mcfqspi_cs_control *cs_control,
172 			    u8 chip_select, bool cs_high)
173 {
174 	gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
175 }
176 
m528x_cs_deselect(struct mcfqspi_cs_control * cs_control,u8 chip_select,bool cs_high)177 static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control,
178 			      u8 chip_select, bool cs_high)
179 {
180 	gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
181 }
182 
183 static struct mcfqspi_cs_control m528x_cs_control = {
184 	.setup                  = m528x_cs_setup,
185 	.teardown               = m528x_cs_teardown,
186 	.select                 = m528x_cs_select,
187 	.deselect               = m528x_cs_deselect,
188 };
189 
190 static struct mcfqspi_platform_data m528x_qspi_data = {
191 	.bus_num		= 0,
192 	.num_chipselect		= 4,
193 	.cs_control		= &m528x_cs_control,
194 };
195 
196 static struct platform_device m528x_qspi = {
197 	.name			= "mcfqspi",
198 	.id			= 0,
199 	.num_resources		= ARRAY_SIZE(m528x_qspi_resources),
200 	.resource		= m528x_qspi_resources,
201 	.dev.platform_data	= &m528x_qspi_data,
202 };
203 
m528x_qspi_init(void)204 static void __init m528x_qspi_init(void)
205 {
206 	/* setup Port QS for QSPI with gpio CS control */
207 	__raw_writeb(0x07, MCFGPIO_PQSPAR);
208 }
209 #endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
210 
211 static struct platform_device *m528x_devices[] __initdata = {
212 	&m528x_uart,
213 	&m528x_fec,
214 #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
215 	&m528x_qspi,
216 #endif
217 };
218 
219 /***************************************************************************/
220 
m528x_uart_init_line(int line,int irq)221 static void __init m528x_uart_init_line(int line, int irq)
222 {
223 	u8 port;
224 
225 	if ((line < 0) || (line > 2))
226 		return;
227 
228 	/* make sure PUAPAR is set for UART0 and UART1 */
229 	if (line < 2) {
230 		port = readb(MCF5282_GPIO_PUAPAR);
231 		port |= (0x03 << (line * 2));
232 		writeb(port, MCF5282_GPIO_PUAPAR);
233 	}
234 }
235 
m528x_uarts_init(void)236 static void __init m528x_uarts_init(void)
237 {
238 	const int nrlines = ARRAY_SIZE(m528x_uart_platform);
239 	int line;
240 
241 	for (line = 0; (line < nrlines); line++)
242 		m528x_uart_init_line(line, m528x_uart_platform[line].irq);
243 }
244 
245 /***************************************************************************/
246 
m528x_fec_init(void)247 static void __init m528x_fec_init(void)
248 {
249 	u16 v16;
250 
251 	/* Set multi-function pins to ethernet mode for fec0 */
252 	v16 = readw(MCF_IPSBAR + 0x100056);
253 	writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
254 	writeb(0xc0, MCF_IPSBAR + 0x100058);
255 }
256 
257 /***************************************************************************/
258 
m528x_cpu_reset(void)259 static void m528x_cpu_reset(void)
260 {
261 	local_irq_disable();
262 	__raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
263 }
264 
265 /***************************************************************************/
266 
267 #ifdef CONFIG_WILDFIRE
wildfire_halt(void)268 void wildfire_halt(void)
269 {
270 	writeb(0, 0x30000007);
271 	writeb(0x2, 0x30000007);
272 }
273 #endif
274 
275 #ifdef CONFIG_WILDFIREMOD
wildfiremod_halt(void)276 void wildfiremod_halt(void)
277 {
278 	printk(KERN_INFO "WildFireMod hibernating...\n");
279 
280 	/* Set portE.5 to Digital IO */
281 	MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2));
282 
283 	/* Make portE.5 an output */
284 	MCF5282_GPIO_DDRE |= (1 << 5);
285 
286 	/* Now toggle portE.5 from low to high */
287 	MCF5282_GPIO_PORTE &= ~(1 << 5);
288 	MCF5282_GPIO_PORTE |= (1 << 5);
289 
290 	printk(KERN_EMERG "Failed to hibernate. Halting!\n");
291 }
292 #endif
293 
config_BSP(char * commandp,int size)294 void __init config_BSP(char *commandp, int size)
295 {
296 #ifdef CONFIG_WILDFIRE
297 	mach_halt = wildfire_halt;
298 #endif
299 #ifdef CONFIG_WILDFIREMOD
300 	mach_halt = wildfiremod_halt;
301 #endif
302 }
303 
304 /***************************************************************************/
305 
init_BSP(void)306 static int __init init_BSP(void)
307 {
308 	mach_reset = m528x_cpu_reset;
309 	m528x_uarts_init();
310 	m528x_fec_init();
311 #if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
312 	m528x_qspi_init();
313 #endif
314 	platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
315 	return 0;
316 }
317 
318 arch_initcall(init_BSP);
319 
320 /***************************************************************************/
321