Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | ||
1da177e4 | 15 | #include <linux/kernel.h> |
1da177e4 LT |
16 | #include <linux/param.h> |
17 | #include <linux/init.h> | |
18 | #include <linux/interrupt.h> | |
e206da0b | 19 | #include <linux/io.h> |
1da177e4 LT |
20 | #include <asm/machdep.h> |
21 | #include <asm/coldfire.h> | |
22 | #include <asm/mcfsim.h> | |
e206da0b | 23 | #include <asm/mcfuart.h> |
1da177e4 LT |
24 | |
25 | /***************************************************************************/ | |
26 | ||
1da177e4 LT |
27 | void coldfire_reset(void); |
28 | ||
29 | /***************************************************************************/ | |
30 | ||
e206da0b GU |
31 | static struct mcf_platform_uart m527x_uart_platform[] = { |
32 | { | |
33 | .mapbase = MCF_MBAR + MCFUART_BASE1, | |
34 | .irq = MCFINT_VECBASE + MCFINT_UART0, | |
35 | }, | |
36 | { | |
37 | .mapbase = MCF_MBAR + MCFUART_BASE2, | |
38 | .irq = MCFINT_VECBASE + MCFINT_UART1, | |
39 | }, | |
40 | { | |
41 | .mapbase = MCF_MBAR + MCFUART_BASE3, | |
42 | .irq = MCFINT_VECBASE + MCFINT_UART2, | |
43 | }, | |
44 | { }, | |
1da177e4 LT |
45 | }; |
46 | ||
e206da0b GU |
47 | static struct platform_device m527x_uart = { |
48 | .name = "mcfuart", | |
49 | .id = 0, | |
50 | .dev.platform_data = m527x_uart_platform, | |
51 | }; | |
52 | ||
ffba3f48 GU |
53 | static struct resource m527x_fec0_resources[] = { |
54 | { | |
55 | .start = MCF_MBAR + 0x1000, | |
56 | .end = MCF_MBAR + 0x1000 + 0x7ff, | |
57 | .flags = IORESOURCE_MEM, | |
58 | }, | |
59 | { | |
60 | .start = 64 + 23, | |
61 | .end = 64 + 23, | |
62 | .flags = IORESOURCE_IRQ, | |
63 | }, | |
64 | { | |
65 | .start = 64 + 27, | |
66 | .end = 64 + 27, | |
67 | .flags = IORESOURCE_IRQ, | |
68 | }, | |
69 | { | |
70 | .start = 64 + 29, | |
71 | .end = 64 + 29, | |
72 | .flags = IORESOURCE_IRQ, | |
73 | }, | |
74 | }; | |
75 | ||
76 | static struct resource m527x_fec1_resources[] = { | |
77 | { | |
78 | .start = MCF_MBAR + 0x1800, | |
79 | .end = MCF_MBAR + 0x1800 + 0x7ff, | |
80 | .flags = IORESOURCE_MEM, | |
81 | }, | |
82 | { | |
83 | .start = 128 + 23, | |
84 | .end = 128 + 23, | |
85 | .flags = IORESOURCE_IRQ, | |
86 | }, | |
87 | { | |
88 | .start = 128 + 27, | |
89 | .end = 128 + 27, | |
90 | .flags = IORESOURCE_IRQ, | |
91 | }, | |
92 | { | |
93 | .start = 128 + 29, | |
94 | .end = 128 + 29, | |
95 | .flags = IORESOURCE_IRQ, | |
96 | }, | |
97 | }; | |
98 | ||
99 | static struct platform_device m527x_fec[] = { | |
100 | { | |
101 | .name = "fec", | |
102 | .id = 0, | |
103 | .num_resources = ARRAY_SIZE(m527x_fec0_resources), | |
104 | .resource = m527x_fec0_resources, | |
105 | }, | |
106 | { | |
107 | .name = "fec", | |
108 | .id = 1, | |
109 | .num_resources = ARRAY_SIZE(m527x_fec1_resources), | |
110 | .resource = m527x_fec1_resources, | |
111 | }, | |
112 | }; | |
113 | ||
e206da0b GU |
114 | static struct platform_device *m527x_devices[] __initdata = { |
115 | &m527x_uart, | |
ffba3f48 GU |
116 | &m527x_fec[0], |
117 | #ifdef CONFIG_FEC2 | |
118 | &m527x_fec[1], | |
119 | #endif | |
e206da0b GU |
120 | }; |
121 | ||
122 | /***************************************************************************/ | |
123 | ||
124 | #define INTC0 (MCF_MBAR + MCFICM_INTC0) | |
125 | ||
126 | static void __init m527x_uart_init_line(int line, int irq) | |
127 | { | |
128 | u16 sepmask; | |
129 | u32 imr; | |
130 | ||
131 | if ((line < 0) || (line > 2)) | |
132 | return; | |
133 | ||
134 | /* level 6, line based priority */ | |
135 | writeb(0x30+line, INTC0 + MCFINTC_ICR0 + MCFINT_UART0 + line); | |
136 | ||
137 | imr = readl(INTC0 + MCFINTC_IMRL); | |
138 | imr &= ~((1 << (irq - MCFINT_VECBASE)) | 1); | |
139 | writel(imr, INTC0 + MCFINTC_IMRL); | |
140 | ||
141 | /* | |
142 | * External Pin Mask Setting & Enable External Pin for Interface | |
143 | */ | |
144 | sepmask = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART); | |
145 | if (line == 0) | |
146 | sepmask |= UART0_ENABLE_MASK; | |
147 | else if (line == 1) | |
148 | sepmask |= UART1_ENABLE_MASK; | |
149 | else if (line == 2) | |
150 | sepmask |= UART2_ENABLE_MASK; | |
151 | writew(sepmask, MCF_IPSBAR + MCF_GPIO_PAR_UART); | |
152 | } | |
153 | ||
154 | static void __init m527x_uarts_init(void) | |
155 | { | |
156 | const int nrlines = ARRAY_SIZE(m527x_uart_platform); | |
157 | int line; | |
158 | ||
159 | for (line = 0; (line < nrlines); line++) | |
160 | m527x_uart_init_line(line, m527x_uart_platform[line].irq); | |
161 | } | |
1da177e4 LT |
162 | |
163 | /***************************************************************************/ | |
164 | ||
ffba3f48 GU |
165 | static void __init m527x_fec_irq_init(int nr) |
166 | { | |
167 | unsigned long base; | |
168 | u32 imr; | |
169 | ||
170 | base = MCF_IPSBAR + (nr ? MCFICM_INTC1 : MCFICM_INTC0); | |
171 | ||
172 | writeb(0x28, base + MCFINTC_ICR0 + 23); | |
173 | writeb(0x27, base + MCFINTC_ICR0 + 27); | |
174 | writeb(0x26, base + MCFINTC_ICR0 + 29); | |
175 | ||
176 | imr = readl(base + MCFINTC_IMRH); | |
177 | imr &= ~0xf; | |
178 | writel(imr, base + MCFINTC_IMRH); | |
179 | imr = readl(base + MCFINTC_IMRL); | |
180 | imr &= ~0xff800001; | |
181 | writel(imr, base + MCFINTC_IMRL); | |
182 | } | |
183 | ||
184 | static void __init m527x_fec_init(void) | |
185 | { | |
186 | u16 par; | |
187 | u8 v; | |
188 | ||
189 | m527x_fec_irq_init(0); | |
190 | ||
191 | /* Set multi-function pins to ethernet mode for fec0 */ | |
592578a1 RR |
192 | #if defined(CONFIG_M5271) |
193 | v = readb(MCF_IPSBAR + 0x100047); | |
194 | writeb(v | 0xf0, MCF_IPSBAR + 0x100047); | |
195 | #else | |
ffba3f48 GU |
196 | par = readw(MCF_IPSBAR + 0x100082); |
197 | writew(par | 0xf00, MCF_IPSBAR + 0x100082); | |
198 | v = readb(MCF_IPSBAR + 0x100078); | |
199 | writeb(v | 0xc0, MCF_IPSBAR + 0x100078); | |
592578a1 | 200 | #endif |
ffba3f48 GU |
201 | |
202 | #ifdef CONFIG_FEC2 | |
203 | m527x_fec_irq_init(1); | |
204 | ||
205 | /* Set multi-function pins to ethernet mode for fec1 */ | |
206 | par = readw(MCF_IPSBAR + 0x100082); | |
207 | writew(par | 0xa0, MCF_IPSBAR + 0x100082); | |
208 | v = readb(MCF_IPSBAR + 0x100079); | |
209 | writeb(v | 0xc0, MCF_IPSBAR + 0x100079); | |
210 | #endif | |
211 | } | |
212 | ||
213 | /***************************************************************************/ | |
214 | ||
1da177e4 LT |
215 | void mcf_disableall(void) |
216 | { | |
217 | *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRH)) = 0xffffffff; | |
218 | *((volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL)) = 0xffffffff; | |
219 | } | |
220 | ||
221 | /***************************************************************************/ | |
222 | ||
223 | void mcf_autovector(unsigned int vec) | |
224 | { | |
225 | /* Everything is auto-vectored on the 5272 */ | |
226 | } | |
227 | ||
228 | /***************************************************************************/ | |
229 | ||
e206da0b | 230 | void __init config_BSP(char *commandp, int size) |
1da177e4 LT |
231 | { |
232 | mcf_disableall(); | |
1da177e4 | 233 | mach_reset = coldfire_reset; |
ffba3f48 GU |
234 | m527x_uarts_init(); |
235 | m527x_fec_init(); | |
1da177e4 LT |
236 | } |
237 | ||
238 | /***************************************************************************/ | |
e206da0b GU |
239 | |
240 | static int __init init_BSP(void) | |
241 | { | |
e206da0b GU |
242 | platform_add_devices(m527x_devices, ARRAY_SIZE(m527x_devices)); |
243 | return 0; | |
244 | } | |
245 | ||
246 | arch_initcall(init_BSP); | |
247 | ||
248 | /***************************************************************************/ |