config.c revision b7ce7f0d0efc1a95154fa6872d5d7c970d281c71
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#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
31static struct resource m528x_qspi_resources[] = {
32	{
33		.start		= MCFQSPI_IOBASE,
34		.end		= MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
35		.flags		= IORESOURCE_MEM,
36	},
37	{
38		.start		= MCFINT_VECBASE + MCFINT_QSPI,
39		.end		= MCFINT_VECBASE + MCFINT_QSPI,
40		.flags		= IORESOURCE_IRQ,
41	},
42};
43
44#define MCFQSPI_CS0    147
45#define MCFQSPI_CS1    148
46#define MCFQSPI_CS2    149
47#define MCFQSPI_CS3    150
48
49static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control)
50{
51	int status;
52
53	status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
54	if (status) {
55		pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
56		goto fail0;
57	}
58	status = gpio_direction_output(MCFQSPI_CS0, 1);
59	if (status) {
60		pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
61		goto fail1;
62	}
63
64	status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
65	if (status) {
66		pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
67		goto fail1;
68	}
69	status = gpio_direction_output(MCFQSPI_CS1, 1);
70	if (status) {
71		pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
72		goto fail2;
73	}
74
75	status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
76	if (status) {
77		pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
78		goto fail2;
79	}
80	status = gpio_direction_output(MCFQSPI_CS2, 1);
81	if (status) {
82		pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
83		goto fail3;
84	}
85
86	status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
87	if (status) {
88		pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
89		goto fail3;
90	}
91	status = gpio_direction_output(MCFQSPI_CS3, 1);
92	if (status) {
93		pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
94		goto fail4;
95	}
96
97	return 0;
98
99fail4:
100	gpio_free(MCFQSPI_CS3);
101fail3:
102	gpio_free(MCFQSPI_CS2);
103fail2:
104	gpio_free(MCFQSPI_CS1);
105fail1:
106	gpio_free(MCFQSPI_CS0);
107fail0:
108	return status;
109}
110
111static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control)
112{
113	gpio_free(MCFQSPI_CS3);
114	gpio_free(MCFQSPI_CS2);
115	gpio_free(MCFQSPI_CS1);
116	gpio_free(MCFQSPI_CS0);
117}
118
119static void m528x_cs_select(struct mcfqspi_cs_control *cs_control,
120			    u8 chip_select, bool cs_high)
121{
122	gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
123}
124
125static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control,
126			      u8 chip_select, bool cs_high)
127{
128	gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
129}
130
131static struct mcfqspi_cs_control m528x_cs_control = {
132	.setup                  = m528x_cs_setup,
133	.teardown               = m528x_cs_teardown,
134	.select                 = m528x_cs_select,
135	.deselect               = m528x_cs_deselect,
136};
137
138static struct mcfqspi_platform_data m528x_qspi_data = {
139	.bus_num		= 0,
140	.num_chipselect		= 4,
141	.cs_control		= &m528x_cs_control,
142};
143
144static struct platform_device m528x_qspi = {
145	.name			= "mcfqspi",
146	.id			= 0,
147	.num_resources		= ARRAY_SIZE(m528x_qspi_resources),
148	.resource		= m528x_qspi_resources,
149	.dev.platform_data	= &m528x_qspi_data,
150};
151
152static void __init m528x_qspi_init(void)
153{
154	/* setup Port QS for QSPI with gpio CS control */
155	__raw_writeb(0x07, MCFGPIO_PQSPAR);
156}
157#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
158
159static struct platform_device *m528x_devices[] __initdata = {
160#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
161	&m528x_qspi,
162#endif
163};
164
165/***************************************************************************/
166
167static void __init m528x_uarts_init(void)
168{
169	u8 port;
170
171	/* make sure PUAPAR is set for UART0 and UART1 */
172	port = readb(MCF5282_GPIO_PUAPAR);
173	port |= 0x03 | (0x03 << 2);
174	writeb(port, MCF5282_GPIO_PUAPAR);
175}
176
177/***************************************************************************/
178
179static void __init m528x_fec_init(void)
180{
181	u16 v16;
182
183	/* Set multi-function pins to ethernet mode for fec0 */
184	v16 = readw(MCF_IPSBAR + 0x100056);
185	writew(v16 | 0xf00, MCF_IPSBAR + 0x100056);
186	writeb(0xc0, MCF_IPSBAR + 0x100058);
187}
188
189/***************************************************************************/
190
191static void m528x_cpu_reset(void)
192{
193	local_irq_disable();
194	__raw_writeb(MCF_RCR_SWRESET, MCF_IPSBAR + MCF_RCR);
195}
196
197/***************************************************************************/
198
199#ifdef CONFIG_WILDFIRE
200void wildfire_halt(void)
201{
202	writeb(0, 0x30000007);
203	writeb(0x2, 0x30000007);
204}
205#endif
206
207#ifdef CONFIG_WILDFIREMOD
208void wildfiremod_halt(void)
209{
210	printk(KERN_INFO "WildFireMod hibernating...\n");
211
212	/* Set portE.5 to Digital IO */
213	MCF5282_GPIO_PEPAR &= ~(1 << (5 * 2));
214
215	/* Make portE.5 an output */
216	MCF5282_GPIO_DDRE |= (1 << 5);
217
218	/* Now toggle portE.5 from low to high */
219	MCF5282_GPIO_PORTE &= ~(1 << 5);
220	MCF5282_GPIO_PORTE |= (1 << 5);
221
222	printk(KERN_EMERG "Failed to hibernate. Halting!\n");
223}
224#endif
225
226void __init config_BSP(char *commandp, int size)
227{
228#ifdef CONFIG_WILDFIRE
229	mach_halt = wildfire_halt;
230#endif
231#ifdef CONFIG_WILDFIREMOD
232	mach_halt = wildfiremod_halt;
233#endif
234}
235
236/***************************************************************************/
237
238static int __init init_BSP(void)
239{
240	mach_reset = m528x_cpu_reset;
241	mach_sched_init = hw_timer_init;
242	m528x_uarts_init();
243	m528x_fec_init();
244#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
245	m528x_qspi_init();
246#endif
247	platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
248	return 0;
249}
250
251arch_initcall(init_BSP);
252
253/***************************************************************************/
254