1e7300d04SMaxime Bizon /*
2e7300d04SMaxime Bizon  * This file is subject to the terms and conditions of the GNU General Public
3e7300d04SMaxime Bizon  * License.  See the file "COPYING" in the main directory of this archive
4e7300d04SMaxime Bizon  * for more details.
5e7300d04SMaxime Bizon  *
6e7300d04SMaxime Bizon  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
7e7300d04SMaxime Bizon  * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
8e7300d04SMaxime Bizon  */
9e7300d04SMaxime Bizon 
10e7300d04SMaxime Bizon #include <linux/init.h>
11e7300d04SMaxime Bizon #include <linux/kernel.h>
12e7300d04SMaxime Bizon #include <linux/string.h>
13e7300d04SMaxime Bizon #include <linux/platform_device.h>
14e7300d04SMaxime Bizon #include <linux/mtd/mtd.h>
15e7300d04SMaxime Bizon #include <linux/mtd/partitions.h>
16e7300d04SMaxime Bizon #include <linux/mtd/physmap.h>
17e7300d04SMaxime Bizon #include <linux/ssb/ssb.h>
18e7300d04SMaxime Bizon #include <asm/addrspace.h>
19e7300d04SMaxime Bizon #include <bcm63xx_board.h>
20e7300d04SMaxime Bizon #include <bcm63xx_cpu.h>
21524ef29cSMaxime Bizon #include <bcm63xx_dev_uart.h>
22e7300d04SMaxime Bizon #include <bcm63xx_regs.h>
23e7300d04SMaxime Bizon #include <bcm63xx_io.h>
24e7300d04SMaxime Bizon #include <bcm63xx_dev_pci.h>
25e7300d04SMaxime Bizon #include <bcm63xx_dev_enet.h>
26e7300d04SMaxime Bizon #include <bcm63xx_dev_dsp.h>
27553d6d5fSMaxime Bizon #include <bcm63xx_dev_pcmcia.h>
28e7300d04SMaxime Bizon #include <board_bcm963xx.h>
29e7300d04SMaxime Bizon 
30e7300d04SMaxime Bizon #define PFX	"board_bcm963xx: "
31e7300d04SMaxime Bizon 
32e7300d04SMaxime Bizon static struct bcm963xx_nvram nvram;
33e7300d04SMaxime Bizon static unsigned int mac_addr_used;
34e7300d04SMaxime Bizon static struct board_info board;
35e7300d04SMaxime Bizon 
36e7300d04SMaxime Bizon /*
37e7300d04SMaxime Bizon  * known 6338 boards
38e7300d04SMaxime Bizon  */
39e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6338
40e7300d04SMaxime Bizon static struct board_info __initdata board_96338gw = {
41e7300d04SMaxime Bizon 	.name				= "96338GW",
42e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6338,
43e7300d04SMaxime Bizon 
44524ef29cSMaxime Bizon 	.has_uart0			= 1,
45e7300d04SMaxime Bizon 	.has_enet0			= 1,
46e7300d04SMaxime Bizon 	.enet0 = {
47e7300d04SMaxime Bizon 		.force_speed_100	= 1,
48e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
49e7300d04SMaxime Bizon 	},
50e7300d04SMaxime Bizon 
51e7300d04SMaxime Bizon 	.has_ohci0			= 1,
52e7300d04SMaxime Bizon 
53e7300d04SMaxime Bizon 	.leds = {
54e7300d04SMaxime Bizon 		{
55e7300d04SMaxime Bizon 			.name		= "adsl",
56e7300d04SMaxime Bizon 			.gpio		= 3,
57e7300d04SMaxime Bizon 			.active_low	= 1,
58e7300d04SMaxime Bizon 		},
59e7300d04SMaxime Bizon 		{
60e7300d04SMaxime Bizon 			.name		= "ses",
61e7300d04SMaxime Bizon 			.gpio		= 5,
62e7300d04SMaxime Bizon 			.active_low	= 1,
63e7300d04SMaxime Bizon 		},
64e7300d04SMaxime Bizon 		{
65e7300d04SMaxime Bizon 			.name		= "ppp-fail",
66e7300d04SMaxime Bizon 			.gpio		= 4,
67e7300d04SMaxime Bizon 			.active_low	= 1,
68e7300d04SMaxime Bizon 		},
69e7300d04SMaxime Bizon 		{
70e7300d04SMaxime Bizon 			.name		= "power",
71e7300d04SMaxime Bizon 			.gpio		= 0,
72e7300d04SMaxime Bizon 			.active_low	= 1,
73e7300d04SMaxime Bizon 			.default_trigger = "default-on",
74e7300d04SMaxime Bizon 		},
75e7300d04SMaxime Bizon 		{
76e7300d04SMaxime Bizon 			.name		= "stop",
77e7300d04SMaxime Bizon 			.gpio		= 1,
78e7300d04SMaxime Bizon 			.active_low	= 1,
79e7300d04SMaxime Bizon 		}
80e7300d04SMaxime Bizon 	},
81e7300d04SMaxime Bizon };
82e7300d04SMaxime Bizon 
83e7300d04SMaxime Bizon static struct board_info __initdata board_96338w = {
84e7300d04SMaxime Bizon 	.name				= "96338W",
85e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6338,
86e7300d04SMaxime Bizon 
87524ef29cSMaxime Bizon 	.has_uart0			= 1,
88e7300d04SMaxime Bizon 	.has_enet0			= 1,
89e7300d04SMaxime Bizon 	.enet0 = {
90e7300d04SMaxime Bizon 		.force_speed_100	= 1,
91e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
92e7300d04SMaxime Bizon 	},
93e7300d04SMaxime Bizon 
94e7300d04SMaxime Bizon 	.leds = {
95e7300d04SMaxime Bizon 		{
96e7300d04SMaxime Bizon 			.name		= "adsl",
97e7300d04SMaxime Bizon 			.gpio		= 3,
98e7300d04SMaxime Bizon 			.active_low	= 1,
99e7300d04SMaxime Bizon 		},
100e7300d04SMaxime Bizon 		{
101e7300d04SMaxime Bizon 			.name		= "ses",
102e7300d04SMaxime Bizon 			.gpio		= 5,
103e7300d04SMaxime Bizon 			.active_low	= 1,
104e7300d04SMaxime Bizon 		},
105e7300d04SMaxime Bizon 		{
106e7300d04SMaxime Bizon 			.name		= "ppp-fail",
107e7300d04SMaxime Bizon 			.gpio		= 4,
108e7300d04SMaxime Bizon 			.active_low	= 1,
109e7300d04SMaxime Bizon 		},
110e7300d04SMaxime Bizon 		{
111e7300d04SMaxime Bizon 			.name		= "power",
112e7300d04SMaxime Bizon 			.gpio		= 0,
113e7300d04SMaxime Bizon 			.active_low	= 1,
114e7300d04SMaxime Bizon 			.default_trigger = "default-on",
115e7300d04SMaxime Bizon 		},
116e7300d04SMaxime Bizon 		{
117e7300d04SMaxime Bizon 			.name		= "stop",
118e7300d04SMaxime Bizon 			.gpio		= 1,
119e7300d04SMaxime Bizon 			.active_low	= 1,
120e7300d04SMaxime Bizon 		},
121e7300d04SMaxime Bizon 	},
122e7300d04SMaxime Bizon };
123e7300d04SMaxime Bizon #endif
124e7300d04SMaxime Bizon 
125e7300d04SMaxime Bizon /*
126e7300d04SMaxime Bizon  * known 6345 boards
127e7300d04SMaxime Bizon  */
128e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6345
129e7300d04SMaxime Bizon static struct board_info __initdata board_96345gw2 = {
130e7300d04SMaxime Bizon 	.name				= "96345GW2",
131e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6345,
132524ef29cSMaxime Bizon 
133524ef29cSMaxime Bizon 	.has_uart0			= 1,
134e7300d04SMaxime Bizon };
135e7300d04SMaxime Bizon #endif
136e7300d04SMaxime Bizon 
137e7300d04SMaxime Bizon /*
138e7300d04SMaxime Bizon  * known 6348 boards
139e7300d04SMaxime Bizon  */
140e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6348
141e7300d04SMaxime Bizon static struct board_info __initdata board_96348r = {
142e7300d04SMaxime Bizon 	.name				= "96348R",
143e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
144e7300d04SMaxime Bizon 
145524ef29cSMaxime Bizon 	.has_uart0			= 1,
146e7300d04SMaxime Bizon 	.has_enet0			= 1,
147e7300d04SMaxime Bizon 	.has_pci			= 1,
148e7300d04SMaxime Bizon 
149e7300d04SMaxime Bizon 	.enet0 = {
150e7300d04SMaxime Bizon 		.has_phy		= 1,
151e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
152e7300d04SMaxime Bizon 	},
153e7300d04SMaxime Bizon 
154e7300d04SMaxime Bizon 	.leds = {
155e7300d04SMaxime Bizon 		{
156e7300d04SMaxime Bizon 			.name		= "adsl-fail",
157e7300d04SMaxime Bizon 			.gpio		= 2,
158e7300d04SMaxime Bizon 			.active_low	= 1,
159e7300d04SMaxime Bizon 		},
160e7300d04SMaxime Bizon 		{
161e7300d04SMaxime Bizon 			.name		= "ppp",
162e7300d04SMaxime Bizon 			.gpio		= 3,
163e7300d04SMaxime Bizon 			.active_low	= 1,
164e7300d04SMaxime Bizon 		},
165e7300d04SMaxime Bizon 		{
166e7300d04SMaxime Bizon 			.name		= "ppp-fail",
167e7300d04SMaxime Bizon 			.gpio		= 4,
168e7300d04SMaxime Bizon 			.active_low	= 1,
169e7300d04SMaxime Bizon 		},
170e7300d04SMaxime Bizon 		{
171e7300d04SMaxime Bizon 			.name		= "power",
172e7300d04SMaxime Bizon 			.gpio		= 0,
173e7300d04SMaxime Bizon 			.active_low	= 1,
174e7300d04SMaxime Bizon 			.default_trigger = "default-on",
175e7300d04SMaxime Bizon 
176e7300d04SMaxime Bizon 		},
177e7300d04SMaxime Bizon 		{
178e7300d04SMaxime Bizon 			.name		= "stop",
179e7300d04SMaxime Bizon 			.gpio		= 1,
180e7300d04SMaxime Bizon 			.active_low	= 1,
181e7300d04SMaxime Bizon 		},
182e7300d04SMaxime Bizon 	},
183e7300d04SMaxime Bizon };
184e7300d04SMaxime Bizon 
185e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_10 = {
186e7300d04SMaxime Bizon 	.name				= "96348GW-10",
187e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
188e7300d04SMaxime Bizon 
189524ef29cSMaxime Bizon 	.has_uart0			= 1,
190e7300d04SMaxime Bizon 	.has_enet0			= 1,
191e7300d04SMaxime Bizon 	.has_enet1			= 1,
192e7300d04SMaxime Bizon 	.has_pci			= 1,
193e7300d04SMaxime Bizon 
194e7300d04SMaxime Bizon 	.enet0 = {
195e7300d04SMaxime Bizon 		.has_phy		= 1,
196e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
197e7300d04SMaxime Bizon 	},
198e7300d04SMaxime Bizon 	.enet1 = {
199e7300d04SMaxime Bizon 		.force_speed_100	= 1,
200e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
201e7300d04SMaxime Bizon 	},
202e7300d04SMaxime Bizon 
203e7300d04SMaxime Bizon 	.has_ohci0			= 1,
204e7300d04SMaxime Bizon 	.has_pccard			= 1,
205e7300d04SMaxime Bizon 	.has_ehci0			= 1,
206e7300d04SMaxime Bizon 
207e7300d04SMaxime Bizon 	.has_dsp			= 1,
208e7300d04SMaxime Bizon 	.dsp = {
209e7300d04SMaxime Bizon 		.gpio_rst		= 6,
210e7300d04SMaxime Bizon 		.gpio_int		= 34,
211e7300d04SMaxime Bizon 		.cs			= 2,
212e7300d04SMaxime Bizon 		.ext_irq		= 2,
213e7300d04SMaxime Bizon 	},
214e7300d04SMaxime Bizon 
215e7300d04SMaxime Bizon 	.leds = {
216e7300d04SMaxime Bizon 		{
217e7300d04SMaxime Bizon 			.name		= "adsl-fail",
218e7300d04SMaxime Bizon 			.gpio		= 2,
219e7300d04SMaxime Bizon 			.active_low	= 1,
220e7300d04SMaxime Bizon 		},
221e7300d04SMaxime Bizon 		{
222e7300d04SMaxime Bizon 			.name		= "ppp",
223e7300d04SMaxime Bizon 			.gpio		= 3,
224e7300d04SMaxime Bizon 			.active_low	= 1,
225e7300d04SMaxime Bizon 		},
226e7300d04SMaxime Bizon 		{
227e7300d04SMaxime Bizon 			.name		= "ppp-fail",
228e7300d04SMaxime Bizon 			.gpio		= 4,
229e7300d04SMaxime Bizon 			.active_low	= 1,
230e7300d04SMaxime Bizon 		},
231e7300d04SMaxime Bizon 		{
232e7300d04SMaxime Bizon 			.name		= "power",
233e7300d04SMaxime Bizon 			.gpio		= 0,
234e7300d04SMaxime Bizon 			.active_low	= 1,
235e7300d04SMaxime Bizon 			.default_trigger = "default-on",
236e7300d04SMaxime Bizon 		},
237e7300d04SMaxime Bizon 		{
238e7300d04SMaxime Bizon 			.name		= "stop",
239e7300d04SMaxime Bizon 			.gpio		= 1,
240e7300d04SMaxime Bizon 			.active_low	= 1,
241e7300d04SMaxime Bizon 		},
242e7300d04SMaxime Bizon 	},
243e7300d04SMaxime Bizon };
244e7300d04SMaxime Bizon 
245e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_11 = {
246e7300d04SMaxime Bizon 	.name				= "96348GW-11",
247e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
248e7300d04SMaxime Bizon 
249524ef29cSMaxime Bizon 	.has_uart0			= 1,
250e7300d04SMaxime Bizon 	.has_enet0			= 1,
251e7300d04SMaxime Bizon 	.has_enet1			= 1,
252e7300d04SMaxime Bizon 	.has_pci			= 1,
253e7300d04SMaxime Bizon 
254e7300d04SMaxime Bizon 	.enet0 = {
255e7300d04SMaxime Bizon 		.has_phy		= 1,
256e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
257e7300d04SMaxime Bizon 	},
258e7300d04SMaxime Bizon 
259e7300d04SMaxime Bizon 	.enet1 = {
260e7300d04SMaxime Bizon 		.force_speed_100	= 1,
261e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
262e7300d04SMaxime Bizon 	},
263e7300d04SMaxime Bizon 
264e7300d04SMaxime Bizon 
265e7300d04SMaxime Bizon 	.has_ohci0 = 1,
266e7300d04SMaxime Bizon 	.has_pccard = 1,
267e7300d04SMaxime Bizon 	.has_ehci0 = 1,
268e7300d04SMaxime Bizon 
269e7300d04SMaxime Bizon 	.leds = {
270e7300d04SMaxime Bizon 		{
271e7300d04SMaxime Bizon 			.name		= "adsl-fail",
272e7300d04SMaxime Bizon 			.gpio		= 2,
273e7300d04SMaxime Bizon 			.active_low	= 1,
274e7300d04SMaxime Bizon 		},
275e7300d04SMaxime Bizon 		{
276e7300d04SMaxime Bizon 			.name		= "ppp",
277e7300d04SMaxime Bizon 			.gpio		= 3,
278e7300d04SMaxime Bizon 			.active_low	= 1,
279e7300d04SMaxime Bizon 		},
280e7300d04SMaxime Bizon 		{
281e7300d04SMaxime Bizon 			.name		= "ppp-fail",
282e7300d04SMaxime Bizon 			.gpio		= 4,
283e7300d04SMaxime Bizon 			.active_low	= 1,
284e7300d04SMaxime Bizon 		},
285e7300d04SMaxime Bizon 		{
286e7300d04SMaxime Bizon 			.name		= "power",
287e7300d04SMaxime Bizon 			.gpio		= 0,
288e7300d04SMaxime Bizon 			.active_low	= 1,
289e7300d04SMaxime Bizon 			.default_trigger = "default-on",
290e7300d04SMaxime Bizon 		},
291e7300d04SMaxime Bizon 		{
292e7300d04SMaxime Bizon 			.name		= "stop",
293e7300d04SMaxime Bizon 			.gpio		= 1,
294e7300d04SMaxime Bizon 			.active_low	= 1,
295e7300d04SMaxime Bizon 		},
296e7300d04SMaxime Bizon 	},
297e7300d04SMaxime Bizon };
298e7300d04SMaxime Bizon 
299e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw = {
300e7300d04SMaxime Bizon 	.name				= "96348GW",
301e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
302e7300d04SMaxime Bizon 
303524ef29cSMaxime Bizon 	.has_uart0			= 1,
304e7300d04SMaxime Bizon 	.has_enet0			= 1,
305e7300d04SMaxime Bizon 	.has_enet1			= 1,
306e7300d04SMaxime Bizon 	.has_pci			= 1,
307e7300d04SMaxime Bizon 
308e7300d04SMaxime Bizon 	.enet0 = {
309e7300d04SMaxime Bizon 		.has_phy		= 1,
310e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
311e7300d04SMaxime Bizon 	},
312e7300d04SMaxime Bizon 	.enet1 = {
313e7300d04SMaxime Bizon 		.force_speed_100	= 1,
314e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
315e7300d04SMaxime Bizon 	},
316e7300d04SMaxime Bizon 
317e7300d04SMaxime Bizon 	.has_ohci0 = 1,
318e7300d04SMaxime Bizon 
319e7300d04SMaxime Bizon 	.has_dsp			= 1,
320e7300d04SMaxime Bizon 	.dsp = {
321e7300d04SMaxime Bizon 		.gpio_rst		= 6,
322e7300d04SMaxime Bizon 		.gpio_int		= 34,
323e7300d04SMaxime Bizon 		.ext_irq		= 2,
324e7300d04SMaxime Bizon 		.cs			= 2,
325e7300d04SMaxime Bizon 	},
326e7300d04SMaxime Bizon 
327e7300d04SMaxime Bizon 	.leds = {
328e7300d04SMaxime Bizon 		{
329e7300d04SMaxime Bizon 			.name		= "adsl-fail",
330e7300d04SMaxime Bizon 			.gpio		= 2,
331e7300d04SMaxime Bizon 			.active_low	= 1,
332e7300d04SMaxime Bizon 		},
333e7300d04SMaxime Bizon 		{
334e7300d04SMaxime Bizon 			.name		= "ppp",
335e7300d04SMaxime Bizon 			.gpio		= 3,
336e7300d04SMaxime Bizon 			.active_low	= 1,
337e7300d04SMaxime Bizon 		},
338e7300d04SMaxime Bizon 		{
339e7300d04SMaxime Bizon 			.name		= "ppp-fail",
340e7300d04SMaxime Bizon 			.gpio		= 4,
341e7300d04SMaxime Bizon 			.active_low	= 1,
342e7300d04SMaxime Bizon 		},
343e7300d04SMaxime Bizon 		{
344e7300d04SMaxime Bizon 			.name		= "power",
345e7300d04SMaxime Bizon 			.gpio		= 0,
346e7300d04SMaxime Bizon 			.active_low	= 1,
347e7300d04SMaxime Bizon 			.default_trigger = "default-on",
348e7300d04SMaxime Bizon 		},
349e7300d04SMaxime Bizon 		{
350e7300d04SMaxime Bizon 			.name		= "stop",
351e7300d04SMaxime Bizon 			.gpio		= 1,
352e7300d04SMaxime Bizon 			.active_low	= 1,
353e7300d04SMaxime Bizon 		},
354e7300d04SMaxime Bizon 	},
355e7300d04SMaxime Bizon };
356e7300d04SMaxime Bizon 
357e7300d04SMaxime Bizon static struct board_info __initdata board_FAST2404 = {
358e7300d04SMaxime Bizon 	.name				= "F@ST2404",
359e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
360e7300d04SMaxime Bizon 
361524ef29cSMaxime Bizon 	.has_uart0			= 1,
362e7300d04SMaxime Bizon         .has_enet0			= 1,
363e7300d04SMaxime Bizon         .has_enet1			= 1,
364e7300d04SMaxime Bizon         .has_pci			= 1,
365e7300d04SMaxime Bizon 
366e7300d04SMaxime Bizon 	.enet0 = {
367e7300d04SMaxime Bizon 		.has_phy		= 1,
368e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
369e7300d04SMaxime Bizon 	},
370e7300d04SMaxime Bizon 
371e7300d04SMaxime Bizon 	.enet1 = {
372e7300d04SMaxime Bizon 		.force_speed_100	= 1,
373e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
374e7300d04SMaxime Bizon 	},
375e7300d04SMaxime Bizon 
376e7300d04SMaxime Bizon 	.has_ohci0			= 1,
377e7300d04SMaxime Bizon 	.has_pccard			= 1,
378e7300d04SMaxime Bizon 	.has_ehci0			= 1,
379e7300d04SMaxime Bizon };
380e7300d04SMaxime Bizon 
3812e6ad9a9SFlorian Fainelli static struct board_info __initdata board_rta1025w_16 = {
3822e6ad9a9SFlorian Fainelli 	.name				= "RTA1025W_16",
3832e6ad9a9SFlorian Fainelli 	.expected_cpu_id		= 0x6348,
3842e6ad9a9SFlorian Fainelli 
3852e6ad9a9SFlorian Fainelli 	.has_enet0			= 1,
3862e6ad9a9SFlorian Fainelli 	.has_enet1			= 1,
3872e6ad9a9SFlorian Fainelli 	.has_pci			= 1,
3882e6ad9a9SFlorian Fainelli 
3892e6ad9a9SFlorian Fainelli 	.enet0 = {
3902e6ad9a9SFlorian Fainelli 		.has_phy		= 1,
3912e6ad9a9SFlorian Fainelli 		.use_internal_phy	= 1,
3922e6ad9a9SFlorian Fainelli 	},
3932e6ad9a9SFlorian Fainelli 	.enet1 = {
3942e6ad9a9SFlorian Fainelli 		.force_speed_100	= 1,
3952e6ad9a9SFlorian Fainelli 		.force_duplex_full	= 1,
3962e6ad9a9SFlorian Fainelli 	},
3972e6ad9a9SFlorian Fainelli };
3982e6ad9a9SFlorian Fainelli 
3992e6ad9a9SFlorian Fainelli 
400e7300d04SMaxime Bizon static struct board_info __initdata board_DV201AMR = {
401e7300d04SMaxime Bizon 	.name				= "DV201AMR",
402e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
403e7300d04SMaxime Bizon 
404524ef29cSMaxime Bizon 	.has_uart0			= 1,
405e7300d04SMaxime Bizon 	.has_pci			= 1,
406e7300d04SMaxime Bizon 	.has_ohci0			= 1,
407e7300d04SMaxime Bizon 
408e7300d04SMaxime Bizon 	.has_enet0			= 1,
409e7300d04SMaxime Bizon 	.has_enet1			= 1,
410e7300d04SMaxime Bizon 	.enet0 = {
411e7300d04SMaxime Bizon 		.has_phy		= 1,
412e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
413e7300d04SMaxime Bizon 	},
414e7300d04SMaxime Bizon 	.enet1 = {
415e7300d04SMaxime Bizon 		.force_speed_100	= 1,
416e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
417e7300d04SMaxime Bizon 	},
418e7300d04SMaxime Bizon };
419e7300d04SMaxime Bizon 
420e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_a = {
421e7300d04SMaxime Bizon 	.name				= "96348GW-A",
422e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
423e7300d04SMaxime Bizon 
424524ef29cSMaxime Bizon 	.has_uart0			= 1,
425e7300d04SMaxime Bizon 	.has_enet0			= 1,
426e7300d04SMaxime Bizon 	.has_enet1			= 1,
427e7300d04SMaxime Bizon 	.has_pci			= 1,
428e7300d04SMaxime Bizon 
429e7300d04SMaxime Bizon 	.enet0 = {
430e7300d04SMaxime Bizon 		.has_phy		= 1,
431e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
432e7300d04SMaxime Bizon 	},
433e7300d04SMaxime Bizon 	.enet1 = {
434e7300d04SMaxime Bizon 		.force_speed_100	= 1,
435e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
436e7300d04SMaxime Bizon 	},
437e7300d04SMaxime Bizon 
438e7300d04SMaxime Bizon 	.has_ohci0 = 1,
439e7300d04SMaxime Bizon };
440e7300d04SMaxime Bizon #endif
441e7300d04SMaxime Bizon 
442e7300d04SMaxime Bizon /*
443e7300d04SMaxime Bizon  * known 6358 boards
444e7300d04SMaxime Bizon  */
445e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6358
446e7300d04SMaxime Bizon static struct board_info __initdata board_96358vw = {
447e7300d04SMaxime Bizon 	.name				= "96358VW",
448e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6358,
449e7300d04SMaxime Bizon 
450524ef29cSMaxime Bizon 	.has_uart0			= 1,
451e7300d04SMaxime Bizon 	.has_enet0			= 1,
452e7300d04SMaxime Bizon 	.has_enet1			= 1,
453e7300d04SMaxime Bizon 	.has_pci			= 1,
454e7300d04SMaxime Bizon 
455e7300d04SMaxime Bizon 	.enet0 = {
456e7300d04SMaxime Bizon 		.has_phy		= 1,
457e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
458e7300d04SMaxime Bizon 	},
459e7300d04SMaxime Bizon 
460e7300d04SMaxime Bizon 	.enet1 = {
461e7300d04SMaxime Bizon 		.force_speed_100	= 1,
462e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
463e7300d04SMaxime Bizon 	},
464e7300d04SMaxime Bizon 
465e7300d04SMaxime Bizon 
466e7300d04SMaxime Bizon 	.has_ohci0 = 1,
467e7300d04SMaxime Bizon 	.has_pccard = 1,
468e7300d04SMaxime Bizon 	.has_ehci0 = 1,
469e7300d04SMaxime Bizon 
470e7300d04SMaxime Bizon 	.leds = {
471e7300d04SMaxime Bizon 		{
472e7300d04SMaxime Bizon 			.name		= "adsl-fail",
473e7300d04SMaxime Bizon 			.gpio		= 15,
474e7300d04SMaxime Bizon 			.active_low	= 1,
475e7300d04SMaxime Bizon 		},
476e7300d04SMaxime Bizon 		{
477e7300d04SMaxime Bizon 			.name		= "ppp",
478e7300d04SMaxime Bizon 			.gpio		= 22,
479e7300d04SMaxime Bizon 			.active_low	= 1,
480e7300d04SMaxime Bizon 		},
481e7300d04SMaxime Bizon 		{
482e7300d04SMaxime Bizon 			.name		= "ppp-fail",
483e7300d04SMaxime Bizon 			.gpio		= 23,
484e7300d04SMaxime Bizon 			.active_low	= 1,
485e7300d04SMaxime Bizon 		},
486e7300d04SMaxime Bizon 		{
487e7300d04SMaxime Bizon 			.name		= "power",
488e7300d04SMaxime Bizon 			.gpio		= 4,
489e7300d04SMaxime Bizon 			.default_trigger = "default-on",
490e7300d04SMaxime Bizon 		},
491e7300d04SMaxime Bizon 		{
492e7300d04SMaxime Bizon 			.name		= "stop",
493e7300d04SMaxime Bizon 			.gpio		= 5,
494e7300d04SMaxime Bizon 		},
495e7300d04SMaxime Bizon 	},
496e7300d04SMaxime Bizon };
497e7300d04SMaxime Bizon 
498e7300d04SMaxime Bizon static struct board_info __initdata board_96358vw2 = {
499e7300d04SMaxime Bizon 	.name				= "96358VW2",
500e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6358,
501e7300d04SMaxime Bizon 
502524ef29cSMaxime Bizon 	.has_uart0			= 1,
503e7300d04SMaxime Bizon 	.has_enet0			= 1,
504e7300d04SMaxime Bizon 	.has_enet1			= 1,
505e7300d04SMaxime Bizon 	.has_pci			= 1,
506e7300d04SMaxime Bizon 
507e7300d04SMaxime Bizon 	.enet0 = {
508e7300d04SMaxime Bizon 		.has_phy		= 1,
509e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
510e7300d04SMaxime Bizon 	},
511e7300d04SMaxime Bizon 
512e7300d04SMaxime Bizon 	.enet1 = {
513e7300d04SMaxime Bizon 		.force_speed_100	= 1,
514e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
515e7300d04SMaxime Bizon 	},
516e7300d04SMaxime Bizon 
517e7300d04SMaxime Bizon 
518e7300d04SMaxime Bizon 	.has_ohci0 = 1,
519e7300d04SMaxime Bizon 	.has_pccard = 1,
520e7300d04SMaxime Bizon 	.has_ehci0 = 1,
521e7300d04SMaxime Bizon 
522e7300d04SMaxime Bizon 	.leds = {
523e7300d04SMaxime Bizon 		{
524e7300d04SMaxime Bizon 			.name		= "adsl",
525e7300d04SMaxime Bizon 			.gpio		= 22,
526e7300d04SMaxime Bizon 			.active_low	= 1,
527e7300d04SMaxime Bizon 		},
528e7300d04SMaxime Bizon 		{
529e7300d04SMaxime Bizon 			.name		= "ppp-fail",
530e7300d04SMaxime Bizon 			.gpio		= 23,
531e7300d04SMaxime Bizon 		},
532e7300d04SMaxime Bizon 		{
533e7300d04SMaxime Bizon 			.name		= "power",
534e7300d04SMaxime Bizon 			.gpio		= 5,
535e7300d04SMaxime Bizon 			.active_low	= 1,
536e7300d04SMaxime Bizon 			.default_trigger = "default-on",
537e7300d04SMaxime Bizon 		},
538e7300d04SMaxime Bizon 		{
539e7300d04SMaxime Bizon 			.name		= "stop",
540e7300d04SMaxime Bizon 			.gpio		= 4,
541e7300d04SMaxime Bizon 			.active_low	= 1,
542e7300d04SMaxime Bizon 		},
543e7300d04SMaxime Bizon 	},
544e7300d04SMaxime Bizon };
545e7300d04SMaxime Bizon 
546e7300d04SMaxime Bizon static struct board_info __initdata board_AGPFS0 = {
547e7300d04SMaxime Bizon 	.name                           = "AGPF-S0",
548e7300d04SMaxime Bizon 	.expected_cpu_id                = 0x6358,
549e7300d04SMaxime Bizon 
550524ef29cSMaxime Bizon 	.has_uart0			= 1,
551e7300d04SMaxime Bizon 	.has_enet0                      = 1,
552e7300d04SMaxime Bizon 	.has_enet1                      = 1,
553e7300d04SMaxime Bizon 	.has_pci                        = 1,
554e7300d04SMaxime Bizon 
555e7300d04SMaxime Bizon 	.enet0 = {
556e7300d04SMaxime Bizon 		.has_phy                = 1,
557e7300d04SMaxime Bizon 		.use_internal_phy       = 1,
558e7300d04SMaxime Bizon 	},
559e7300d04SMaxime Bizon 
560e7300d04SMaxime Bizon 	.enet1 = {
561e7300d04SMaxime Bizon 		.force_speed_100        = 1,
562e7300d04SMaxime Bizon 		.force_duplex_full      = 1,
563e7300d04SMaxime Bizon 	},
564e7300d04SMaxime Bizon 
565e7300d04SMaxime Bizon 	.has_ohci0 = 1,
566e7300d04SMaxime Bizon 	.has_ehci0 = 1,
567e7300d04SMaxime Bizon };
568f29b7cacSFlorian Fainelli 
569f29b7cacSFlorian Fainelli static struct board_info __initdata board_DWVS0 = {
570f29b7cacSFlorian Fainelli 	.name				= "DWV-S0",
571f29b7cacSFlorian Fainelli 	.expected_cpu_id		= 0x6358,
572f29b7cacSFlorian Fainelli 
573f29b7cacSFlorian Fainelli 	.has_enet0			= 1,
574f29b7cacSFlorian Fainelli 	.has_enet1			= 1,
575f29b7cacSFlorian Fainelli 	.has_pci			= 1,
576f29b7cacSFlorian Fainelli 
577f29b7cacSFlorian Fainelli 	.enet0 = {
578f29b7cacSFlorian Fainelli 		.has_phy		= 1,
579f29b7cacSFlorian Fainelli 		.use_internal_phy	= 1,
580f29b7cacSFlorian Fainelli 	},
581f29b7cacSFlorian Fainelli 
582f29b7cacSFlorian Fainelli 	.enet1 = {
583f29b7cacSFlorian Fainelli 		.force_speed_100	= 1,
584f29b7cacSFlorian Fainelli 		.force_duplex_full	= 1,
585f29b7cacSFlorian Fainelli 	},
586f29b7cacSFlorian Fainelli 
587f29b7cacSFlorian Fainelli 	.has_ohci0			= 1,
588f29b7cacSFlorian Fainelli };
589e7300d04SMaxime Bizon #endif
590e7300d04SMaxime Bizon 
591e7300d04SMaxime Bizon /*
592e7300d04SMaxime Bizon  * all boards
593e7300d04SMaxime Bizon  */
594e7300d04SMaxime Bizon static const struct board_info __initdata *bcm963xx_boards[] = {
595e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6338
596e7300d04SMaxime Bizon 	&board_96338gw,
597e7300d04SMaxime Bizon 	&board_96338w,
598e7300d04SMaxime Bizon #endif
599e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6345
600e7300d04SMaxime Bizon 	&board_96345gw2,
601e7300d04SMaxime Bizon #endif
602e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6348
603e7300d04SMaxime Bizon 	&board_96348r,
604e7300d04SMaxime Bizon 	&board_96348gw,
605e7300d04SMaxime Bizon 	&board_96348gw_10,
606e7300d04SMaxime Bizon 	&board_96348gw_11,
607e7300d04SMaxime Bizon 	&board_FAST2404,
608e7300d04SMaxime Bizon 	&board_DV201AMR,
609e7300d04SMaxime Bizon 	&board_96348gw_a,
6102e6ad9a9SFlorian Fainelli 	&board_rta1025w_16,
611e7300d04SMaxime Bizon #endif
612e7300d04SMaxime Bizon 
613e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6358
614e7300d04SMaxime Bizon 	&board_96358vw,
615e7300d04SMaxime Bizon 	&board_96358vw2,
616e7300d04SMaxime Bizon 	&board_AGPFS0,
617f29b7cacSFlorian Fainelli 	&board_DWVS0,
618e7300d04SMaxime Bizon #endif
619e7300d04SMaxime Bizon };
620e7300d04SMaxime Bizon 
621e7300d04SMaxime Bizon /*
6225e3644a9SFlorian Fainelli  * Register a sane SPROMv2 to make the on-board
6235e3644a9SFlorian Fainelli  * bcm4318 WLAN work
6245e3644a9SFlorian Fainelli  */
6255e3644a9SFlorian Fainelli #ifdef CONFIG_SSB_PCIHOST
6265e3644a9SFlorian Fainelli static struct ssb_sprom bcm63xx_sprom = {
6275e3644a9SFlorian Fainelli 	.revision		= 0x02,
6285e3644a9SFlorian Fainelli 	.board_rev		= 0x17,
6295e3644a9SFlorian Fainelli 	.country_code		= 0x0,
6305e3644a9SFlorian Fainelli 	.ant_available_bg 	= 0x3,
6315e3644a9SFlorian Fainelli 	.pa0b0			= 0x15ae,
6325e3644a9SFlorian Fainelli 	.pa0b1			= 0xfa85,
6335e3644a9SFlorian Fainelli 	.pa0b2			= 0xfe8d,
6345e3644a9SFlorian Fainelli 	.pa1b0			= 0xffff,
6355e3644a9SFlorian Fainelli 	.pa1b1			= 0xffff,
6365e3644a9SFlorian Fainelli 	.pa1b2			= 0xffff,
6375e3644a9SFlorian Fainelli 	.gpio0			= 0xff,
6385e3644a9SFlorian Fainelli 	.gpio1			= 0xff,
6395e3644a9SFlorian Fainelli 	.gpio2			= 0xff,
6405e3644a9SFlorian Fainelli 	.gpio3			= 0xff,
6415e3644a9SFlorian Fainelli 	.maxpwr_bg		= 0x004c,
6425e3644a9SFlorian Fainelli 	.itssi_bg		= 0x00,
6435e3644a9SFlorian Fainelli 	.boardflags_lo		= 0x2848,
6445e3644a9SFlorian Fainelli 	.boardflags_hi		= 0x0000,
6455e3644a9SFlorian Fainelli };
646b3ae52b6SHauke Mehrtens 
647b3ae52b6SHauke Mehrtens int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
648b3ae52b6SHauke Mehrtens {
649b3ae52b6SHauke Mehrtens 	if (bus->bustype == SSB_BUSTYPE_PCI) {
650b3ae52b6SHauke Mehrtens 		memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
651b3ae52b6SHauke Mehrtens 		return 0;
652b3ae52b6SHauke Mehrtens 	} else {
653b3ae52b6SHauke Mehrtens 		printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
654b3ae52b6SHauke Mehrtens 		return -EINVAL;
655b3ae52b6SHauke Mehrtens 	}
656b3ae52b6SHauke Mehrtens }
6575e3644a9SFlorian Fainelli #endif
6585e3644a9SFlorian Fainelli 
6595e3644a9SFlorian Fainelli /*
6605e3644a9SFlorian Fainelli  * return board name for /proc/cpuinfo
6615e3644a9SFlorian Fainelli  */
6625e3644a9SFlorian Fainelli const char *board_get_name(void)
6635e3644a9SFlorian Fainelli {
6645e3644a9SFlorian Fainelli 	return board.name;
6655e3644a9SFlorian Fainelli }
6665e3644a9SFlorian Fainelli 
6675e3644a9SFlorian Fainelli /*
6685e3644a9SFlorian Fainelli  * register & return a new board mac address
6695e3644a9SFlorian Fainelli  */
6705e3644a9SFlorian Fainelli static int board_get_mac_address(u8 *mac)
6715e3644a9SFlorian Fainelli {
6725e3644a9SFlorian Fainelli 	u8 *p;
6735e3644a9SFlorian Fainelli 	int count;
6745e3644a9SFlorian Fainelli 
6755e3644a9SFlorian Fainelli 	if (mac_addr_used >= nvram.mac_addr_count) {
6765e3644a9SFlorian Fainelli 		printk(KERN_ERR PFX "not enough mac address\n");
6775e3644a9SFlorian Fainelli 		return -ENODEV;
6785e3644a9SFlorian Fainelli 	}
6795e3644a9SFlorian Fainelli 
6805e3644a9SFlorian Fainelli 	memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
6815e3644a9SFlorian Fainelli 	p = mac + ETH_ALEN - 1;
6825e3644a9SFlorian Fainelli 	count = mac_addr_used;
6835e3644a9SFlorian Fainelli 
6845e3644a9SFlorian Fainelli 	while (count--) {
6855e3644a9SFlorian Fainelli 		do {
6865e3644a9SFlorian Fainelli 			(*p)++;
6875e3644a9SFlorian Fainelli 			if (*p != 0)
6885e3644a9SFlorian Fainelli 				break;
6895e3644a9SFlorian Fainelli 			p--;
6905e3644a9SFlorian Fainelli 		} while (p != mac);
6915e3644a9SFlorian Fainelli 	}
6925e3644a9SFlorian Fainelli 
6935e3644a9SFlorian Fainelli 	if (p == mac) {
6945e3644a9SFlorian Fainelli 		printk(KERN_ERR PFX "unable to fetch mac address\n");
6955e3644a9SFlorian Fainelli 		return -ENODEV;
6965e3644a9SFlorian Fainelli 	}
6975e3644a9SFlorian Fainelli 
6985e3644a9SFlorian Fainelli 	mac_addr_used++;
6995e3644a9SFlorian Fainelli 	return 0;
7005e3644a9SFlorian Fainelli }
7015e3644a9SFlorian Fainelli 
7025e3644a9SFlorian Fainelli /*
703e7300d04SMaxime Bizon  * early init callback, read nvram data from flash and checksum it
704e7300d04SMaxime Bizon  */
705e7300d04SMaxime Bizon void __init board_prom_init(void)
706e7300d04SMaxime Bizon {
707e7300d04SMaxime Bizon 	unsigned int check_len, i;
708e7300d04SMaxime Bizon 	u8 *boot_addr, *cfe, *p;
709e7300d04SMaxime Bizon 	char cfe_version[32];
710e7300d04SMaxime Bizon 	u32 val;
711e7300d04SMaxime Bizon 
712e7300d04SMaxime Bizon 	/* read base address of boot chip select (0)
713e7300d04SMaxime Bizon 	 * 6345 does not have MPI but boots from standard
714e7300d04SMaxime Bizon 	 * MIPS Flash address */
715e7300d04SMaxime Bizon 	if (BCMCPU_IS_6345())
716e7300d04SMaxime Bizon 		val = 0x1fc00000;
717e7300d04SMaxime Bizon 	else {
718e7300d04SMaxime Bizon 		val = bcm_mpi_readl(MPI_CSBASE_REG(0));
719e7300d04SMaxime Bizon 		val &= MPI_CSBASE_BASE_MASK;
720e7300d04SMaxime Bizon 	}
721e7300d04SMaxime Bizon 	boot_addr = (u8 *)KSEG1ADDR(val);
722e7300d04SMaxime Bizon 
723e7300d04SMaxime Bizon 	/* dump cfe version */
724e7300d04SMaxime Bizon 	cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
725e7300d04SMaxime Bizon 	if (!memcmp(cfe, "cfe-v", 5))
726e7300d04SMaxime Bizon 		snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u",
727e7300d04SMaxime Bizon 			 cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
728e7300d04SMaxime Bizon 	else
729e7300d04SMaxime Bizon 		strcpy(cfe_version, "unknown");
730e7300d04SMaxime Bizon 	printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
731e7300d04SMaxime Bizon 
732e7300d04SMaxime Bizon 	/* extract nvram data */
733e7300d04SMaxime Bizon 	memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
734e7300d04SMaxime Bizon 
735e7300d04SMaxime Bizon 	/* check checksum before using data */
736e7300d04SMaxime Bizon 	if (nvram.version <= 4)
737e7300d04SMaxime Bizon 		check_len = offsetof(struct bcm963xx_nvram, checksum_old);
738e7300d04SMaxime Bizon 	else
739e7300d04SMaxime Bizon 		check_len = sizeof(nvram);
740e7300d04SMaxime Bizon 	val = 0;
741e7300d04SMaxime Bizon 	p = (u8 *)&nvram;
742e7300d04SMaxime Bizon 	while (check_len--)
743e7300d04SMaxime Bizon 		val += *p;
744e7300d04SMaxime Bizon 	if (val) {
745e7300d04SMaxime Bizon 		printk(KERN_ERR PFX "invalid nvram checksum\n");
746e7300d04SMaxime Bizon 		return;
747e7300d04SMaxime Bizon 	}
748e7300d04SMaxime Bizon 
749e7300d04SMaxime Bizon 	/* find board by name */
750e7300d04SMaxime Bizon 	for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
751e7300d04SMaxime Bizon 		if (strncmp(nvram.name, bcm963xx_boards[i]->name,
752e7300d04SMaxime Bizon 			    sizeof(nvram.name)))
753e7300d04SMaxime Bizon 			continue;
754e7300d04SMaxime Bizon 		/* copy, board desc array is marked initdata */
755e7300d04SMaxime Bizon 		memcpy(&board, bcm963xx_boards[i], sizeof(board));
756e7300d04SMaxime Bizon 		break;
757e7300d04SMaxime Bizon 	}
758e7300d04SMaxime Bizon 
759e7300d04SMaxime Bizon 	/* bail out if board is not found, will complain later */
760e7300d04SMaxime Bizon 	if (!board.name[0]) {
761e7300d04SMaxime Bizon 		char name[17];
762e7300d04SMaxime Bizon 		memcpy(name, nvram.name, 16);
763e7300d04SMaxime Bizon 		name[16] = 0;
764e7300d04SMaxime Bizon 		printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
765e7300d04SMaxime Bizon 		       name);
766e7300d04SMaxime Bizon 		return;
767e7300d04SMaxime Bizon 	}
768e7300d04SMaxime Bizon 
769e7300d04SMaxime Bizon 	/* setup pin multiplexing depending on board enabled device,
770e7300d04SMaxime Bizon 	 * this has to be done this early since PCI init is done
771e7300d04SMaxime Bizon 	 * inside arch_initcall */
772e7300d04SMaxime Bizon 	val = 0;
773e7300d04SMaxime Bizon 
774e7300d04SMaxime Bizon #ifdef CONFIG_PCI
775e7300d04SMaxime Bizon 	if (board.has_pci) {
776e7300d04SMaxime Bizon 		bcm63xx_pci_enabled = 1;
777e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
778e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G2_PCI;
779e7300d04SMaxime Bizon 	}
780e7300d04SMaxime Bizon #endif
781e7300d04SMaxime Bizon 
782e7300d04SMaxime Bizon 	if (board.has_pccard) {
783e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
784e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G1_MII_PCCARD;
785e7300d04SMaxime Bizon 	}
786e7300d04SMaxime Bizon 
787e7300d04SMaxime Bizon 	if (board.has_enet0 && !board.enet0.use_internal_phy) {
788e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
789e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G3_EXT_MII |
790e7300d04SMaxime Bizon 				GPIO_MODE_6348_G0_EXT_MII;
791e7300d04SMaxime Bizon 	}
792e7300d04SMaxime Bizon 
793e7300d04SMaxime Bizon 	if (board.has_enet1 && !board.enet1.use_internal_phy) {
794e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
795e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G3_EXT_MII |
796e7300d04SMaxime Bizon 				GPIO_MODE_6348_G0_EXT_MII;
797e7300d04SMaxime Bizon 	}
798e7300d04SMaxime Bizon 
799e7300d04SMaxime Bizon 	bcm_gpio_writel(val, GPIO_MODE_REG);
800e23a90ebSFlorian Fainelli 
801e23a90ebSFlorian Fainelli 	/* Generate MAC address for WLAN and
802e23a90ebSFlorian Fainelli 	 * register our SPROM */
803e23a90ebSFlorian Fainelli #ifdef CONFIG_SSB_PCIHOST
804e23a90ebSFlorian Fainelli 	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
805e23a90ebSFlorian Fainelli 		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
806e23a90ebSFlorian Fainelli 		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
807b3ae52b6SHauke Mehrtens 		if (ssb_arch_register_fallback_sprom(
808b3ae52b6SHauke Mehrtens 				&bcm63xx_get_fallback_sprom) < 0)
809b3ae52b6SHauke Mehrtens 			printk(KERN_ERR PFX "failed to register fallback SPROM\n");
810e23a90ebSFlorian Fainelli 	}
811e23a90ebSFlorian Fainelli #endif
812e7300d04SMaxime Bizon }
813e7300d04SMaxime Bizon 
814e7300d04SMaxime Bizon /*
815e7300d04SMaxime Bizon  * second stage init callback, good time to panic if we couldn't
816e7300d04SMaxime Bizon  * identify on which board we're running since early printk is working
817e7300d04SMaxime Bizon  */
818e7300d04SMaxime Bizon void __init board_setup(void)
819e7300d04SMaxime Bizon {
820e7300d04SMaxime Bizon 	if (!board.name[0])
821e7300d04SMaxime Bizon 		panic("unable to detect bcm963xx board");
822e7300d04SMaxime Bizon 	printk(KERN_INFO PFX "board name: %s\n", board.name);
823e7300d04SMaxime Bizon 
824e7300d04SMaxime Bizon 	/* make sure we're running on expected cpu */
825e7300d04SMaxime Bizon 	if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
826e7300d04SMaxime Bizon 		panic("unexpected CPU for bcm963xx board");
827e7300d04SMaxime Bizon }
828e7300d04SMaxime Bizon 
829e7300d04SMaxime Bizon static struct mtd_partition mtd_partitions[] = {
830e7300d04SMaxime Bizon 	{
831e7300d04SMaxime Bizon 		.name		= "cfe",
832e7300d04SMaxime Bizon 		.offset		= 0x0,
833e7300d04SMaxime Bizon 		.size		= 0x40000,
834e7300d04SMaxime Bizon 	}
835e7300d04SMaxime Bizon };
836e7300d04SMaxime Bizon 
837e7300d04SMaxime Bizon static struct physmap_flash_data flash_data = {
838e7300d04SMaxime Bizon 	.width			= 2,
839e7300d04SMaxime Bizon 	.nr_parts		= ARRAY_SIZE(mtd_partitions),
840e7300d04SMaxime Bizon 	.parts			= mtd_partitions,
841e7300d04SMaxime Bizon };
842e7300d04SMaxime Bizon 
843e7300d04SMaxime Bizon static struct resource mtd_resources[] = {
844e7300d04SMaxime Bizon 	{
845e7300d04SMaxime Bizon 		.start		= 0,	/* filled at runtime */
846e7300d04SMaxime Bizon 		.end		= 0,	/* filled at runtime */
847e7300d04SMaxime Bizon 		.flags		= IORESOURCE_MEM,
848e7300d04SMaxime Bizon 	}
849e7300d04SMaxime Bizon };
850e7300d04SMaxime Bizon 
851e7300d04SMaxime Bizon static struct platform_device mtd_dev = {
852e7300d04SMaxime Bizon 	.name			= "physmap-flash",
853e7300d04SMaxime Bizon 	.resource		= mtd_resources,
854e7300d04SMaxime Bizon 	.num_resources		= ARRAY_SIZE(mtd_resources),
855e7300d04SMaxime Bizon 	.dev			= {
856e7300d04SMaxime Bizon 		.platform_data	= &flash_data,
857e7300d04SMaxime Bizon 	},
858e7300d04SMaxime Bizon };
859e7300d04SMaxime Bizon 
860e7300d04SMaxime Bizon static struct gpio_led_platform_data bcm63xx_led_data;
861e7300d04SMaxime Bizon 
862e7300d04SMaxime Bizon static struct platform_device bcm63xx_gpio_leds = {
863e7300d04SMaxime Bizon 	.name			= "leds-gpio",
864e7300d04SMaxime Bizon 	.id			= 0,
865e7300d04SMaxime Bizon 	.dev.platform_data	= &bcm63xx_led_data,
866e7300d04SMaxime Bizon };
867e7300d04SMaxime Bizon 
868e7300d04SMaxime Bizon /*
869e7300d04SMaxime Bizon  * third stage init callback, register all board devices.
870e7300d04SMaxime Bizon  */
871e7300d04SMaxime Bizon int __init board_register_devices(void)
872e7300d04SMaxime Bizon {
873e7300d04SMaxime Bizon 	u32 val;
874e7300d04SMaxime Bizon 
875524ef29cSMaxime Bizon 	if (board.has_uart0)
876524ef29cSMaxime Bizon 		bcm63xx_uart_register(0);
877524ef29cSMaxime Bizon 
878524ef29cSMaxime Bizon 	if (board.has_uart1)
879524ef29cSMaxime Bizon 		bcm63xx_uart_register(1);
880524ef29cSMaxime Bizon 
881553d6d5fSMaxime Bizon 	if (board.has_pccard)
882553d6d5fSMaxime Bizon 		bcm63xx_pcmcia_register();
883553d6d5fSMaxime Bizon 
884e7300d04SMaxime Bizon 	if (board.has_enet0 &&
885e7300d04SMaxime Bizon 	    !board_get_mac_address(board.enet0.mac_addr))
886e7300d04SMaxime Bizon 		bcm63xx_enet_register(0, &board.enet0);
887e7300d04SMaxime Bizon 
888e7300d04SMaxime Bizon 	if (board.has_enet1 &&
889e7300d04SMaxime Bizon 	    !board_get_mac_address(board.enet1.mac_addr))
890e7300d04SMaxime Bizon 		bcm63xx_enet_register(1, &board.enet1);
891e7300d04SMaxime Bizon 
892e7300d04SMaxime Bizon 	if (board.has_dsp)
893e7300d04SMaxime Bizon 		bcm63xx_dsp_register(&board.dsp);
894e7300d04SMaxime Bizon 
895e7300d04SMaxime Bizon 	/* read base address of boot chip select (0) */
896e7300d04SMaxime Bizon 	if (BCMCPU_IS_6345())
897e7300d04SMaxime Bizon 		val = 0x1fc00000;
898e7300d04SMaxime Bizon 	else {
899e7300d04SMaxime Bizon 		val = bcm_mpi_readl(MPI_CSBASE_REG(0));
900e7300d04SMaxime Bizon 		val &= MPI_CSBASE_BASE_MASK;
901e7300d04SMaxime Bizon 	}
902e7300d04SMaxime Bizon 	mtd_resources[0].start = val;
903e7300d04SMaxime Bizon 	mtd_resources[0].end = 0x1FFFFFFF;
904e7300d04SMaxime Bizon 
905e7300d04SMaxime Bizon 	platform_device_register(&mtd_dev);
906e7300d04SMaxime Bizon 
907e7300d04SMaxime Bizon 	bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
908e7300d04SMaxime Bizon 	bcm63xx_led_data.leds = board.leds;
909e7300d04SMaxime Bizon 
910e7300d04SMaxime Bizon 	platform_device_register(&bcm63xx_gpio_leds);
911e7300d04SMaxime Bizon 
912e7300d04SMaxime Bizon 	return 0;
913e7300d04SMaxime Bizon }
914