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/ssb/ssb.h>
15e7300d04SMaxime Bizon #include <asm/addrspace.h>
16e7300d04SMaxime Bizon #include <bcm63xx_board.h>
17e7300d04SMaxime Bizon #include <bcm63xx_cpu.h>
18524ef29cSMaxime Bizon #include <bcm63xx_dev_uart.h>
19e7300d04SMaxime Bizon #include <bcm63xx_regs.h>
20e7300d04SMaxime Bizon #include <bcm63xx_io.h>
21e7300d04SMaxime Bizon #include <bcm63xx_dev_pci.h>
22e7300d04SMaxime Bizon #include <bcm63xx_dev_enet.h>
23e7300d04SMaxime Bizon #include <bcm63xx_dev_dsp.h>
244b897d54SJonas Gorski #include <bcm63xx_dev_flash.h>
25553d6d5fSMaxime Bizon #include <bcm63xx_dev_pcmcia.h>
2676ca4e14SFlorian Fainelli #include <bcm63xx_dev_spi.h>
27e7300d04SMaxime Bizon #include <board_bcm963xx.h>
28e7300d04SMaxime Bizon 
29e7300d04SMaxime Bizon #define PFX	"board_bcm963xx: "
30e7300d04SMaxime Bizon 
31e7300d04SMaxime Bizon static struct bcm963xx_nvram nvram;
32e7300d04SMaxime Bizon static unsigned int mac_addr_used;
33e7300d04SMaxime Bizon static struct board_info board;
34e7300d04SMaxime Bizon 
35e7300d04SMaxime Bizon /*
362f74b770SJonas Gorski  * known 6328 boards
372f74b770SJonas Gorski  */
382f74b770SJonas Gorski #ifdef CONFIG_BCM63XX_CPU_6328
392f74b770SJonas Gorski static struct board_info __initdata board_96328avng = {
402f74b770SJonas Gorski 	.name				= "96328avng",
412f74b770SJonas Gorski 	.expected_cpu_id		= 0x6328,
422f74b770SJonas Gorski 
432f74b770SJonas Gorski 	.has_uart0			= 1,
442f74b770SJonas Gorski 	.has_pci			= 1,
452f74b770SJonas Gorski 
462f74b770SJonas Gorski 	.leds = {
472f74b770SJonas Gorski 		{
482f74b770SJonas Gorski 			.name		= "96328avng::ppp-fail",
492f74b770SJonas Gorski 			.gpio		= 2,
502f74b770SJonas Gorski 			.active_low	= 1,
512f74b770SJonas Gorski 		},
522f74b770SJonas Gorski 		{
532f74b770SJonas Gorski 			.name		= "96328avng::power",
542f74b770SJonas Gorski 			.gpio		= 4,
552f74b770SJonas Gorski 			.active_low	= 1,
562f74b770SJonas Gorski 			.default_trigger = "default-on",
572f74b770SJonas Gorski 		},
582f74b770SJonas Gorski 		{
592f74b770SJonas Gorski 			.name		= "96328avng::power-fail",
602f74b770SJonas Gorski 			.gpio		= 8,
612f74b770SJonas Gorski 			.active_low	= 1,
622f74b770SJonas Gorski 		},
632f74b770SJonas Gorski 		{
642f74b770SJonas Gorski 			.name		= "96328avng::wps",
652f74b770SJonas Gorski 			.gpio		= 9,
662f74b770SJonas Gorski 			.active_low	= 1,
672f74b770SJonas Gorski 		},
682f74b770SJonas Gorski 		{
692f74b770SJonas Gorski 			.name		= "96328avng::ppp",
702f74b770SJonas Gorski 			.gpio		= 11,
712f74b770SJonas Gorski 			.active_low	= 1,
722f74b770SJonas Gorski 		},
732f74b770SJonas Gorski 	},
742f74b770SJonas Gorski };
752f74b770SJonas Gorski #endif
762f74b770SJonas Gorski 
772f74b770SJonas Gorski /*
78e7300d04SMaxime Bizon  * known 6338 boards
79e7300d04SMaxime Bizon  */
80e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6338
81e7300d04SMaxime Bizon static struct board_info __initdata board_96338gw = {
82e7300d04SMaxime Bizon 	.name				= "96338GW",
83e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6338,
84e7300d04SMaxime Bizon 
85524ef29cSMaxime Bizon 	.has_uart0			= 1,
86e7300d04SMaxime Bizon 	.has_enet0			= 1,
87e7300d04SMaxime Bizon 	.enet0 = {
88e7300d04SMaxime Bizon 		.force_speed_100	= 1,
89e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
90e7300d04SMaxime Bizon 	},
91e7300d04SMaxime Bizon 
92e7300d04SMaxime Bizon 	.has_ohci0			= 1,
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 
124e7300d04SMaxime Bizon static struct board_info __initdata board_96338w = {
125e7300d04SMaxime Bizon 	.name				= "96338W",
126e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6338,
127e7300d04SMaxime Bizon 
128524ef29cSMaxime Bizon 	.has_uart0			= 1,
129e7300d04SMaxime Bizon 	.has_enet0			= 1,
130e7300d04SMaxime Bizon 	.enet0 = {
131e7300d04SMaxime Bizon 		.force_speed_100	= 1,
132e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
133e7300d04SMaxime Bizon 	},
134e7300d04SMaxime Bizon 
135e7300d04SMaxime Bizon 	.leds = {
136e7300d04SMaxime Bizon 		{
137e7300d04SMaxime Bizon 			.name		= "adsl",
138e7300d04SMaxime Bizon 			.gpio		= 3,
139e7300d04SMaxime Bizon 			.active_low	= 1,
140e7300d04SMaxime Bizon 		},
141e7300d04SMaxime Bizon 		{
142e7300d04SMaxime Bizon 			.name		= "ses",
143e7300d04SMaxime Bizon 			.gpio		= 5,
144e7300d04SMaxime Bizon 			.active_low	= 1,
145e7300d04SMaxime Bizon 		},
146e7300d04SMaxime Bizon 		{
147e7300d04SMaxime Bizon 			.name		= "ppp-fail",
148e7300d04SMaxime Bizon 			.gpio		= 4,
149e7300d04SMaxime Bizon 			.active_low	= 1,
150e7300d04SMaxime Bizon 		},
151e7300d04SMaxime Bizon 		{
152e7300d04SMaxime Bizon 			.name		= "power",
153e7300d04SMaxime Bizon 			.gpio		= 0,
154e7300d04SMaxime Bizon 			.active_low	= 1,
155e7300d04SMaxime Bizon 			.default_trigger = "default-on",
156e7300d04SMaxime Bizon 		},
157e7300d04SMaxime Bizon 		{
158e7300d04SMaxime Bizon 			.name		= "stop",
159e7300d04SMaxime Bizon 			.gpio		= 1,
160e7300d04SMaxime Bizon 			.active_low	= 1,
161e7300d04SMaxime Bizon 		},
162e7300d04SMaxime Bizon 	},
163e7300d04SMaxime Bizon };
164e7300d04SMaxime Bizon #endif
165e7300d04SMaxime Bizon 
166e7300d04SMaxime Bizon /*
167e7300d04SMaxime Bizon  * known 6345 boards
168e7300d04SMaxime Bizon  */
169e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6345
170e7300d04SMaxime Bizon static struct board_info __initdata board_96345gw2 = {
171e7300d04SMaxime Bizon 	.name				= "96345GW2",
172e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6345,
173524ef29cSMaxime Bizon 
174524ef29cSMaxime Bizon 	.has_uart0			= 1,
175e7300d04SMaxime Bizon };
176e7300d04SMaxime Bizon #endif
177e7300d04SMaxime Bizon 
178e7300d04SMaxime Bizon /*
179e7300d04SMaxime Bizon  * known 6348 boards
180e7300d04SMaxime Bizon  */
181e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6348
182e7300d04SMaxime Bizon static struct board_info __initdata board_96348r = {
183e7300d04SMaxime Bizon 	.name				= "96348R",
184e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
185e7300d04SMaxime Bizon 
186524ef29cSMaxime Bizon 	.has_uart0			= 1,
187e7300d04SMaxime Bizon 	.has_enet0			= 1,
188e7300d04SMaxime Bizon 	.has_pci			= 1,
189e7300d04SMaxime Bizon 
190e7300d04SMaxime Bizon 	.enet0 = {
191e7300d04SMaxime Bizon 		.has_phy		= 1,
192e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
193e7300d04SMaxime Bizon 	},
194e7300d04SMaxime Bizon 
195e7300d04SMaxime Bizon 	.leds = {
196e7300d04SMaxime Bizon 		{
197e7300d04SMaxime Bizon 			.name		= "adsl-fail",
198e7300d04SMaxime Bizon 			.gpio		= 2,
199e7300d04SMaxime Bizon 			.active_low	= 1,
200e7300d04SMaxime Bizon 		},
201e7300d04SMaxime Bizon 		{
202e7300d04SMaxime Bizon 			.name		= "ppp",
203e7300d04SMaxime Bizon 			.gpio		= 3,
204e7300d04SMaxime Bizon 			.active_low	= 1,
205e7300d04SMaxime Bizon 		},
206e7300d04SMaxime Bizon 		{
207e7300d04SMaxime Bizon 			.name		= "ppp-fail",
208e7300d04SMaxime Bizon 			.gpio		= 4,
209e7300d04SMaxime Bizon 			.active_low	= 1,
210e7300d04SMaxime Bizon 		},
211e7300d04SMaxime Bizon 		{
212e7300d04SMaxime Bizon 			.name		= "power",
213e7300d04SMaxime Bizon 			.gpio		= 0,
214e7300d04SMaxime Bizon 			.active_low	= 1,
215e7300d04SMaxime Bizon 			.default_trigger = "default-on",
216e7300d04SMaxime Bizon 
217e7300d04SMaxime Bizon 		},
218e7300d04SMaxime Bizon 		{
219e7300d04SMaxime Bizon 			.name		= "stop",
220e7300d04SMaxime Bizon 			.gpio		= 1,
221e7300d04SMaxime Bizon 			.active_low	= 1,
222e7300d04SMaxime Bizon 		},
223e7300d04SMaxime Bizon 	},
224e7300d04SMaxime Bizon };
225e7300d04SMaxime Bizon 
226e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_10 = {
227e7300d04SMaxime Bizon 	.name				= "96348GW-10",
228e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
229e7300d04SMaxime Bizon 
230524ef29cSMaxime Bizon 	.has_uart0			= 1,
231e7300d04SMaxime Bizon 	.has_enet0			= 1,
232e7300d04SMaxime Bizon 	.has_enet1			= 1,
233e7300d04SMaxime Bizon 	.has_pci			= 1,
234e7300d04SMaxime Bizon 
235e7300d04SMaxime Bizon 	.enet0 = {
236e7300d04SMaxime Bizon 		.has_phy		= 1,
237e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
238e7300d04SMaxime Bizon 	},
239e7300d04SMaxime Bizon 	.enet1 = {
240e7300d04SMaxime Bizon 		.force_speed_100	= 1,
241e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
242e7300d04SMaxime Bizon 	},
243e7300d04SMaxime Bizon 
244e7300d04SMaxime Bizon 	.has_ohci0			= 1,
245e7300d04SMaxime Bizon 	.has_pccard			= 1,
246e7300d04SMaxime Bizon 	.has_ehci0			= 1,
247e7300d04SMaxime Bizon 
248e7300d04SMaxime Bizon 	.has_dsp			= 1,
249e7300d04SMaxime Bizon 	.dsp = {
250e7300d04SMaxime Bizon 		.gpio_rst		= 6,
251e7300d04SMaxime Bizon 		.gpio_int		= 34,
252e7300d04SMaxime Bizon 		.cs			= 2,
253e7300d04SMaxime Bizon 		.ext_irq		= 2,
254e7300d04SMaxime Bizon 	},
255e7300d04SMaxime Bizon 
256e7300d04SMaxime Bizon 	.leds = {
257e7300d04SMaxime Bizon 		{
258e7300d04SMaxime Bizon 			.name		= "adsl-fail",
259e7300d04SMaxime Bizon 			.gpio		= 2,
260e7300d04SMaxime Bizon 			.active_low	= 1,
261e7300d04SMaxime Bizon 		},
262e7300d04SMaxime Bizon 		{
263e7300d04SMaxime Bizon 			.name		= "ppp",
264e7300d04SMaxime Bizon 			.gpio		= 3,
265e7300d04SMaxime Bizon 			.active_low	= 1,
266e7300d04SMaxime Bizon 		},
267e7300d04SMaxime Bizon 		{
268e7300d04SMaxime Bizon 			.name		= "ppp-fail",
269e7300d04SMaxime Bizon 			.gpio		= 4,
270e7300d04SMaxime Bizon 			.active_low	= 1,
271e7300d04SMaxime Bizon 		},
272e7300d04SMaxime Bizon 		{
273e7300d04SMaxime Bizon 			.name		= "power",
274e7300d04SMaxime Bizon 			.gpio		= 0,
275e7300d04SMaxime Bizon 			.active_low	= 1,
276e7300d04SMaxime Bizon 			.default_trigger = "default-on",
277e7300d04SMaxime Bizon 		},
278e7300d04SMaxime Bizon 		{
279e7300d04SMaxime Bizon 			.name		= "stop",
280e7300d04SMaxime Bizon 			.gpio		= 1,
281e7300d04SMaxime Bizon 			.active_low	= 1,
282e7300d04SMaxime Bizon 		},
283e7300d04SMaxime Bizon 	},
284e7300d04SMaxime Bizon };
285e7300d04SMaxime Bizon 
286e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_11 = {
287e7300d04SMaxime Bizon 	.name				= "96348GW-11",
288e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
289e7300d04SMaxime Bizon 
290524ef29cSMaxime Bizon 	.has_uart0			= 1,
291e7300d04SMaxime Bizon 	.has_enet0			= 1,
292e7300d04SMaxime Bizon 	.has_enet1			= 1,
293e7300d04SMaxime Bizon 	.has_pci			= 1,
294e7300d04SMaxime Bizon 
295e7300d04SMaxime Bizon 	.enet0 = {
296e7300d04SMaxime Bizon 		.has_phy		= 1,
297e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
298e7300d04SMaxime Bizon 	},
299e7300d04SMaxime Bizon 
300e7300d04SMaxime Bizon 	.enet1 = {
301e7300d04SMaxime Bizon 		.force_speed_100	= 1,
302e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
303e7300d04SMaxime Bizon 	},
304e7300d04SMaxime Bizon 
305e7300d04SMaxime Bizon 
306e7300d04SMaxime Bizon 	.has_ohci0 = 1,
307e7300d04SMaxime Bizon 	.has_pccard = 1,
308e7300d04SMaxime Bizon 	.has_ehci0 = 1,
309e7300d04SMaxime Bizon 
310e7300d04SMaxime Bizon 	.leds = {
311e7300d04SMaxime Bizon 		{
312e7300d04SMaxime Bizon 			.name		= "adsl-fail",
313e7300d04SMaxime Bizon 			.gpio		= 2,
314e7300d04SMaxime Bizon 			.active_low	= 1,
315e7300d04SMaxime Bizon 		},
316e7300d04SMaxime Bizon 		{
317e7300d04SMaxime Bizon 			.name		= "ppp",
318e7300d04SMaxime Bizon 			.gpio		= 3,
319e7300d04SMaxime Bizon 			.active_low	= 1,
320e7300d04SMaxime Bizon 		},
321e7300d04SMaxime Bizon 		{
322e7300d04SMaxime Bizon 			.name		= "ppp-fail",
323e7300d04SMaxime Bizon 			.gpio		= 4,
324e7300d04SMaxime Bizon 			.active_low	= 1,
325e7300d04SMaxime Bizon 		},
326e7300d04SMaxime Bizon 		{
327e7300d04SMaxime Bizon 			.name		= "power",
328e7300d04SMaxime Bizon 			.gpio		= 0,
329e7300d04SMaxime Bizon 			.active_low	= 1,
330e7300d04SMaxime Bizon 			.default_trigger = "default-on",
331e7300d04SMaxime Bizon 		},
332e7300d04SMaxime Bizon 		{
333e7300d04SMaxime Bizon 			.name		= "stop",
334e7300d04SMaxime Bizon 			.gpio		= 1,
335e7300d04SMaxime Bizon 			.active_low	= 1,
336e7300d04SMaxime Bizon 		},
337e7300d04SMaxime Bizon 	},
338e7300d04SMaxime Bizon };
339e7300d04SMaxime Bizon 
340e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw = {
341e7300d04SMaxime Bizon 	.name				= "96348GW",
342e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
343e7300d04SMaxime Bizon 
344524ef29cSMaxime Bizon 	.has_uart0			= 1,
345e7300d04SMaxime Bizon 	.has_enet0			= 1,
346e7300d04SMaxime Bizon 	.has_enet1			= 1,
347e7300d04SMaxime Bizon 	.has_pci			= 1,
348e7300d04SMaxime Bizon 
349e7300d04SMaxime Bizon 	.enet0 = {
350e7300d04SMaxime Bizon 		.has_phy		= 1,
351e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
352e7300d04SMaxime Bizon 	},
353e7300d04SMaxime Bizon 	.enet1 = {
354e7300d04SMaxime Bizon 		.force_speed_100	= 1,
355e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
356e7300d04SMaxime Bizon 	},
357e7300d04SMaxime Bizon 
358e7300d04SMaxime Bizon 	.has_ohci0 = 1,
359e7300d04SMaxime Bizon 
360e7300d04SMaxime Bizon 	.has_dsp			= 1,
361e7300d04SMaxime Bizon 	.dsp = {
362e7300d04SMaxime Bizon 		.gpio_rst		= 6,
363e7300d04SMaxime Bizon 		.gpio_int		= 34,
364e7300d04SMaxime Bizon 		.ext_irq		= 2,
365e7300d04SMaxime Bizon 		.cs			= 2,
366e7300d04SMaxime Bizon 	},
367e7300d04SMaxime Bizon 
368e7300d04SMaxime Bizon 	.leds = {
369e7300d04SMaxime Bizon 		{
370e7300d04SMaxime Bizon 			.name		= "adsl-fail",
371e7300d04SMaxime Bizon 			.gpio		= 2,
372e7300d04SMaxime Bizon 			.active_low	= 1,
373e7300d04SMaxime Bizon 		},
374e7300d04SMaxime Bizon 		{
375e7300d04SMaxime Bizon 			.name		= "ppp",
376e7300d04SMaxime Bizon 			.gpio		= 3,
377e7300d04SMaxime Bizon 			.active_low	= 1,
378e7300d04SMaxime Bizon 		},
379e7300d04SMaxime Bizon 		{
380e7300d04SMaxime Bizon 			.name		= "ppp-fail",
381e7300d04SMaxime Bizon 			.gpio		= 4,
382e7300d04SMaxime Bizon 			.active_low	= 1,
383e7300d04SMaxime Bizon 		},
384e7300d04SMaxime Bizon 		{
385e7300d04SMaxime Bizon 			.name		= "power",
386e7300d04SMaxime Bizon 			.gpio		= 0,
387e7300d04SMaxime Bizon 			.active_low	= 1,
388e7300d04SMaxime Bizon 			.default_trigger = "default-on",
389e7300d04SMaxime Bizon 		},
390e7300d04SMaxime Bizon 		{
391e7300d04SMaxime Bizon 			.name		= "stop",
392e7300d04SMaxime Bizon 			.gpio		= 1,
393e7300d04SMaxime Bizon 			.active_low	= 1,
394e7300d04SMaxime Bizon 		},
395e7300d04SMaxime Bizon 	},
396e7300d04SMaxime Bizon };
397e7300d04SMaxime Bizon 
398e7300d04SMaxime Bizon static struct board_info __initdata board_FAST2404 = {
399e7300d04SMaxime Bizon 	.name				= "F@ST2404",
400e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
401e7300d04SMaxime Bizon 
402524ef29cSMaxime Bizon 	.has_uart0			= 1,
403e7300d04SMaxime Bizon         .has_enet0			= 1,
404e7300d04SMaxime Bizon         .has_enet1			= 1,
405e7300d04SMaxime Bizon         .has_pci			= 1,
406e7300d04SMaxime Bizon 
407e7300d04SMaxime Bizon 	.enet0 = {
408e7300d04SMaxime Bizon 		.has_phy		= 1,
409e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
410e7300d04SMaxime Bizon 	},
411e7300d04SMaxime Bizon 
412e7300d04SMaxime Bizon 	.enet1 = {
413e7300d04SMaxime Bizon 		.force_speed_100	= 1,
414e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
415e7300d04SMaxime Bizon 	},
416e7300d04SMaxime Bizon 
417e7300d04SMaxime Bizon 	.has_ohci0			= 1,
418e7300d04SMaxime Bizon 	.has_pccard			= 1,
419e7300d04SMaxime Bizon 	.has_ehci0			= 1,
420e7300d04SMaxime Bizon };
421e7300d04SMaxime Bizon 
4222e6ad9a9SFlorian Fainelli static struct board_info __initdata board_rta1025w_16 = {
4232e6ad9a9SFlorian Fainelli 	.name				= "RTA1025W_16",
4242e6ad9a9SFlorian Fainelli 	.expected_cpu_id		= 0x6348,
4252e6ad9a9SFlorian Fainelli 
4262e6ad9a9SFlorian Fainelli 	.has_enet0			= 1,
4272e6ad9a9SFlorian Fainelli 	.has_enet1			= 1,
4282e6ad9a9SFlorian Fainelli 	.has_pci			= 1,
4292e6ad9a9SFlorian Fainelli 
4302e6ad9a9SFlorian Fainelli 	.enet0 = {
4312e6ad9a9SFlorian Fainelli 		.has_phy		= 1,
4322e6ad9a9SFlorian Fainelli 		.use_internal_phy	= 1,
4332e6ad9a9SFlorian Fainelli 	},
4342e6ad9a9SFlorian Fainelli 	.enet1 = {
4352e6ad9a9SFlorian Fainelli 		.force_speed_100	= 1,
4362e6ad9a9SFlorian Fainelli 		.force_duplex_full	= 1,
4372e6ad9a9SFlorian Fainelli 	},
4382e6ad9a9SFlorian Fainelli };
4392e6ad9a9SFlorian Fainelli 
4402e6ad9a9SFlorian Fainelli 
441e7300d04SMaxime Bizon static struct board_info __initdata board_DV201AMR = {
442e7300d04SMaxime Bizon 	.name				= "DV201AMR",
443e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
444e7300d04SMaxime Bizon 
445524ef29cSMaxime Bizon 	.has_uart0			= 1,
446e7300d04SMaxime Bizon 	.has_pci			= 1,
447e7300d04SMaxime Bizon 	.has_ohci0			= 1,
448e7300d04SMaxime Bizon 
449e7300d04SMaxime Bizon 	.has_enet0			= 1,
450e7300d04SMaxime Bizon 	.has_enet1			= 1,
451e7300d04SMaxime Bizon 	.enet0 = {
452e7300d04SMaxime Bizon 		.has_phy		= 1,
453e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
454e7300d04SMaxime Bizon 	},
455e7300d04SMaxime Bizon 	.enet1 = {
456e7300d04SMaxime Bizon 		.force_speed_100	= 1,
457e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
458e7300d04SMaxime Bizon 	},
459e7300d04SMaxime Bizon };
460e7300d04SMaxime Bizon 
461e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_a = {
462e7300d04SMaxime Bizon 	.name				= "96348GW-A",
463e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
464e7300d04SMaxime Bizon 
465524ef29cSMaxime Bizon 	.has_uart0			= 1,
466e7300d04SMaxime Bizon 	.has_enet0			= 1,
467e7300d04SMaxime Bizon 	.has_enet1			= 1,
468e7300d04SMaxime Bizon 	.has_pci			= 1,
469e7300d04SMaxime Bizon 
470e7300d04SMaxime Bizon 	.enet0 = {
471e7300d04SMaxime Bizon 		.has_phy		= 1,
472e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
473e7300d04SMaxime Bizon 	},
474e7300d04SMaxime Bizon 	.enet1 = {
475e7300d04SMaxime Bizon 		.force_speed_100	= 1,
476e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
477e7300d04SMaxime Bizon 	},
478e7300d04SMaxime Bizon 
479e7300d04SMaxime Bizon 	.has_ohci0 = 1,
480e7300d04SMaxime Bizon };
481e7300d04SMaxime Bizon #endif
482e7300d04SMaxime Bizon 
483e7300d04SMaxime Bizon /*
484e7300d04SMaxime Bizon  * known 6358 boards
485e7300d04SMaxime Bizon  */
486e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6358
487e7300d04SMaxime Bizon static struct board_info __initdata board_96358vw = {
488e7300d04SMaxime Bizon 	.name				= "96358VW",
489e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6358,
490e7300d04SMaxime Bizon 
491524ef29cSMaxime Bizon 	.has_uart0			= 1,
492e7300d04SMaxime Bizon 	.has_enet0			= 1,
493e7300d04SMaxime Bizon 	.has_enet1			= 1,
494e7300d04SMaxime Bizon 	.has_pci			= 1,
495e7300d04SMaxime Bizon 
496e7300d04SMaxime Bizon 	.enet0 = {
497e7300d04SMaxime Bizon 		.has_phy		= 1,
498e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
499e7300d04SMaxime Bizon 	},
500e7300d04SMaxime Bizon 
501e7300d04SMaxime Bizon 	.enet1 = {
502e7300d04SMaxime Bizon 		.force_speed_100	= 1,
503e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
504e7300d04SMaxime Bizon 	},
505e7300d04SMaxime Bizon 
506e7300d04SMaxime Bizon 
507e7300d04SMaxime Bizon 	.has_ohci0 = 1,
508e7300d04SMaxime Bizon 	.has_pccard = 1,
509e7300d04SMaxime Bizon 	.has_ehci0 = 1,
510e7300d04SMaxime Bizon 
511e7300d04SMaxime Bizon 	.leds = {
512e7300d04SMaxime Bizon 		{
513e7300d04SMaxime Bizon 			.name		= "adsl-fail",
514e7300d04SMaxime Bizon 			.gpio		= 15,
515e7300d04SMaxime Bizon 			.active_low	= 1,
516e7300d04SMaxime Bizon 		},
517e7300d04SMaxime Bizon 		{
518e7300d04SMaxime Bizon 			.name		= "ppp",
519e7300d04SMaxime Bizon 			.gpio		= 22,
520e7300d04SMaxime Bizon 			.active_low	= 1,
521e7300d04SMaxime Bizon 		},
522e7300d04SMaxime Bizon 		{
523e7300d04SMaxime Bizon 			.name		= "ppp-fail",
524e7300d04SMaxime Bizon 			.gpio		= 23,
525e7300d04SMaxime Bizon 			.active_low	= 1,
526e7300d04SMaxime Bizon 		},
527e7300d04SMaxime Bizon 		{
528e7300d04SMaxime Bizon 			.name		= "power",
529e7300d04SMaxime Bizon 			.gpio		= 4,
530e7300d04SMaxime Bizon 			.default_trigger = "default-on",
531e7300d04SMaxime Bizon 		},
532e7300d04SMaxime Bizon 		{
533e7300d04SMaxime Bizon 			.name		= "stop",
534e7300d04SMaxime Bizon 			.gpio		= 5,
535e7300d04SMaxime Bizon 		},
536e7300d04SMaxime Bizon 	},
537e7300d04SMaxime Bizon };
538e7300d04SMaxime Bizon 
539e7300d04SMaxime Bizon static struct board_info __initdata board_96358vw2 = {
540e7300d04SMaxime Bizon 	.name				= "96358VW2",
541e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6358,
542e7300d04SMaxime Bizon 
543524ef29cSMaxime Bizon 	.has_uart0			= 1,
544e7300d04SMaxime Bizon 	.has_enet0			= 1,
545e7300d04SMaxime Bizon 	.has_enet1			= 1,
546e7300d04SMaxime Bizon 	.has_pci			= 1,
547e7300d04SMaxime Bizon 
548e7300d04SMaxime Bizon 	.enet0 = {
549e7300d04SMaxime Bizon 		.has_phy		= 1,
550e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
551e7300d04SMaxime Bizon 	},
552e7300d04SMaxime Bizon 
553e7300d04SMaxime Bizon 	.enet1 = {
554e7300d04SMaxime Bizon 		.force_speed_100	= 1,
555e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
556e7300d04SMaxime Bizon 	},
557e7300d04SMaxime Bizon 
558e7300d04SMaxime Bizon 
559e7300d04SMaxime Bizon 	.has_ohci0 = 1,
560e7300d04SMaxime Bizon 	.has_pccard = 1,
561e7300d04SMaxime Bizon 	.has_ehci0 = 1,
562e7300d04SMaxime Bizon 
563e7300d04SMaxime Bizon 	.leds = {
564e7300d04SMaxime Bizon 		{
565e7300d04SMaxime Bizon 			.name		= "adsl",
566e7300d04SMaxime Bizon 			.gpio		= 22,
567e7300d04SMaxime Bizon 			.active_low	= 1,
568e7300d04SMaxime Bizon 		},
569e7300d04SMaxime Bizon 		{
570e7300d04SMaxime Bizon 			.name		= "ppp-fail",
571e7300d04SMaxime Bizon 			.gpio		= 23,
572e7300d04SMaxime Bizon 		},
573e7300d04SMaxime Bizon 		{
574e7300d04SMaxime Bizon 			.name		= "power",
575e7300d04SMaxime Bizon 			.gpio		= 5,
576e7300d04SMaxime Bizon 			.active_low	= 1,
577e7300d04SMaxime Bizon 			.default_trigger = "default-on",
578e7300d04SMaxime Bizon 		},
579e7300d04SMaxime Bizon 		{
580e7300d04SMaxime Bizon 			.name		= "stop",
581e7300d04SMaxime Bizon 			.gpio		= 4,
582e7300d04SMaxime Bizon 			.active_low	= 1,
583e7300d04SMaxime Bizon 		},
584e7300d04SMaxime Bizon 	},
585e7300d04SMaxime Bizon };
586e7300d04SMaxime Bizon 
587e7300d04SMaxime Bizon static struct board_info __initdata board_AGPFS0 = {
588e7300d04SMaxime Bizon 	.name                           = "AGPF-S0",
589e7300d04SMaxime Bizon 	.expected_cpu_id                = 0x6358,
590e7300d04SMaxime Bizon 
591524ef29cSMaxime Bizon 	.has_uart0			= 1,
592e7300d04SMaxime Bizon 	.has_enet0                      = 1,
593e7300d04SMaxime Bizon 	.has_enet1                      = 1,
594e7300d04SMaxime Bizon 	.has_pci                        = 1,
595e7300d04SMaxime Bizon 
596e7300d04SMaxime Bizon 	.enet0 = {
597e7300d04SMaxime Bizon 		.has_phy                = 1,
598e7300d04SMaxime Bizon 		.use_internal_phy       = 1,
599e7300d04SMaxime Bizon 	},
600e7300d04SMaxime Bizon 
601e7300d04SMaxime Bizon 	.enet1 = {
602e7300d04SMaxime Bizon 		.force_speed_100        = 1,
603e7300d04SMaxime Bizon 		.force_duplex_full      = 1,
604e7300d04SMaxime Bizon 	},
605e7300d04SMaxime Bizon 
606e7300d04SMaxime Bizon 	.has_ohci0 = 1,
607e7300d04SMaxime Bizon 	.has_ehci0 = 1,
608e7300d04SMaxime Bizon };
609f29b7cacSFlorian Fainelli 
610f29b7cacSFlorian Fainelli static struct board_info __initdata board_DWVS0 = {
611f29b7cacSFlorian Fainelli 	.name				= "DWV-S0",
612f29b7cacSFlorian Fainelli 	.expected_cpu_id		= 0x6358,
613f29b7cacSFlorian Fainelli 
614f29b7cacSFlorian Fainelli 	.has_enet0			= 1,
615f29b7cacSFlorian Fainelli 	.has_enet1			= 1,
616f29b7cacSFlorian Fainelli 	.has_pci			= 1,
617f29b7cacSFlorian Fainelli 
618f29b7cacSFlorian Fainelli 	.enet0 = {
619f29b7cacSFlorian Fainelli 		.has_phy		= 1,
620f29b7cacSFlorian Fainelli 		.use_internal_phy	= 1,
621f29b7cacSFlorian Fainelli 	},
622f29b7cacSFlorian Fainelli 
623f29b7cacSFlorian Fainelli 	.enet1 = {
624f29b7cacSFlorian Fainelli 		.force_speed_100	= 1,
625f29b7cacSFlorian Fainelli 		.force_duplex_full	= 1,
626f29b7cacSFlorian Fainelli 	},
627f29b7cacSFlorian Fainelli 
628f29b7cacSFlorian Fainelli 	.has_ohci0			= 1,
629f29b7cacSFlorian Fainelli };
630e7300d04SMaxime Bizon #endif
631e7300d04SMaxime Bizon 
632e7300d04SMaxime Bizon /*
633e7300d04SMaxime Bizon  * all boards
634e7300d04SMaxime Bizon  */
635e7300d04SMaxime Bizon static const struct board_info __initdata *bcm963xx_boards[] = {
6362f74b770SJonas Gorski #ifdef CONFIG_BCM63XX_CPU_6328
6372f74b770SJonas Gorski 	&board_96328avng,
6382f74b770SJonas Gorski #endif
639e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6338
640e7300d04SMaxime Bizon 	&board_96338gw,
641e7300d04SMaxime Bizon 	&board_96338w,
642e7300d04SMaxime Bizon #endif
643e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6345
644e7300d04SMaxime Bizon 	&board_96345gw2,
645e7300d04SMaxime Bizon #endif
646e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6348
647e7300d04SMaxime Bizon 	&board_96348r,
648e7300d04SMaxime Bizon 	&board_96348gw,
649e7300d04SMaxime Bizon 	&board_96348gw_10,
650e7300d04SMaxime Bizon 	&board_96348gw_11,
651e7300d04SMaxime Bizon 	&board_FAST2404,
652e7300d04SMaxime Bizon 	&board_DV201AMR,
653e7300d04SMaxime Bizon 	&board_96348gw_a,
6542e6ad9a9SFlorian Fainelli 	&board_rta1025w_16,
655e7300d04SMaxime Bizon #endif
656e7300d04SMaxime Bizon 
657e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6358
658e7300d04SMaxime Bizon 	&board_96358vw,
659e7300d04SMaxime Bizon 	&board_96358vw2,
660e7300d04SMaxime Bizon 	&board_AGPFS0,
661f29b7cacSFlorian Fainelli 	&board_DWVS0,
662e7300d04SMaxime Bizon #endif
663e7300d04SMaxime Bizon };
664e7300d04SMaxime Bizon 
665e7300d04SMaxime Bizon /*
6665e3644a9SFlorian Fainelli  * Register a sane SPROMv2 to make the on-board
6675e3644a9SFlorian Fainelli  * bcm4318 WLAN work
6685e3644a9SFlorian Fainelli  */
6695e3644a9SFlorian Fainelli #ifdef CONFIG_SSB_PCIHOST
6705e3644a9SFlorian Fainelli static struct ssb_sprom bcm63xx_sprom = {
6715e3644a9SFlorian Fainelli 	.revision		= 0x02,
6725e3644a9SFlorian Fainelli 	.board_rev		= 0x17,
6735e3644a9SFlorian Fainelli 	.country_code		= 0x0,
6745e3644a9SFlorian Fainelli 	.ant_available_bg 	= 0x3,
6755e3644a9SFlorian Fainelli 	.pa0b0			= 0x15ae,
6765e3644a9SFlorian Fainelli 	.pa0b1			= 0xfa85,
6775e3644a9SFlorian Fainelli 	.pa0b2			= 0xfe8d,
6785e3644a9SFlorian Fainelli 	.pa1b0			= 0xffff,
6795e3644a9SFlorian Fainelli 	.pa1b1			= 0xffff,
6805e3644a9SFlorian Fainelli 	.pa1b2			= 0xffff,
6815e3644a9SFlorian Fainelli 	.gpio0			= 0xff,
6825e3644a9SFlorian Fainelli 	.gpio1			= 0xff,
6835e3644a9SFlorian Fainelli 	.gpio2			= 0xff,
6845e3644a9SFlorian Fainelli 	.gpio3			= 0xff,
6855e3644a9SFlorian Fainelli 	.maxpwr_bg		= 0x004c,
6865e3644a9SFlorian Fainelli 	.itssi_bg		= 0x00,
6875e3644a9SFlorian Fainelli 	.boardflags_lo		= 0x2848,
6885e3644a9SFlorian Fainelli 	.boardflags_hi		= 0x0000,
6895e3644a9SFlorian Fainelli };
690b3ae52b6SHauke Mehrtens 
691b3ae52b6SHauke Mehrtens int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
692b3ae52b6SHauke Mehrtens {
693b3ae52b6SHauke Mehrtens 	if (bus->bustype == SSB_BUSTYPE_PCI) {
694b3ae52b6SHauke Mehrtens 		memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
695b3ae52b6SHauke Mehrtens 		return 0;
696b3ae52b6SHauke Mehrtens 	} else {
697b3ae52b6SHauke Mehrtens 		printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
698b3ae52b6SHauke Mehrtens 		return -EINVAL;
699b3ae52b6SHauke Mehrtens 	}
700b3ae52b6SHauke Mehrtens }
7015e3644a9SFlorian Fainelli #endif
7025e3644a9SFlorian Fainelli 
7035e3644a9SFlorian Fainelli /*
7045e3644a9SFlorian Fainelli  * return board name for /proc/cpuinfo
7055e3644a9SFlorian Fainelli  */
7065e3644a9SFlorian Fainelli const char *board_get_name(void)
7075e3644a9SFlorian Fainelli {
7085e3644a9SFlorian Fainelli 	return board.name;
7095e3644a9SFlorian Fainelli }
7105e3644a9SFlorian Fainelli 
7115e3644a9SFlorian Fainelli /*
7125e3644a9SFlorian Fainelli  * register & return a new board mac address
7135e3644a9SFlorian Fainelli  */
7145e3644a9SFlorian Fainelli static int board_get_mac_address(u8 *mac)
7155e3644a9SFlorian Fainelli {
7165e3644a9SFlorian Fainelli 	u8 *p;
7175e3644a9SFlorian Fainelli 	int count;
7185e3644a9SFlorian Fainelli 
7195e3644a9SFlorian Fainelli 	if (mac_addr_used >= nvram.mac_addr_count) {
7205e3644a9SFlorian Fainelli 		printk(KERN_ERR PFX "not enough mac address\n");
7215e3644a9SFlorian Fainelli 		return -ENODEV;
7225e3644a9SFlorian Fainelli 	}
7235e3644a9SFlorian Fainelli 
7245e3644a9SFlorian Fainelli 	memcpy(mac, nvram.mac_addr_base, ETH_ALEN);
7255e3644a9SFlorian Fainelli 	p = mac + ETH_ALEN - 1;
7265e3644a9SFlorian Fainelli 	count = mac_addr_used;
7275e3644a9SFlorian Fainelli 
7285e3644a9SFlorian Fainelli 	while (count--) {
7295e3644a9SFlorian Fainelli 		do {
7305e3644a9SFlorian Fainelli 			(*p)++;
7315e3644a9SFlorian Fainelli 			if (*p != 0)
7325e3644a9SFlorian Fainelli 				break;
7335e3644a9SFlorian Fainelli 			p--;
7345e3644a9SFlorian Fainelli 		} while (p != mac);
7355e3644a9SFlorian Fainelli 	}
7365e3644a9SFlorian Fainelli 
7375e3644a9SFlorian Fainelli 	if (p == mac) {
7385e3644a9SFlorian Fainelli 		printk(KERN_ERR PFX "unable to fetch mac address\n");
7395e3644a9SFlorian Fainelli 		return -ENODEV;
7405e3644a9SFlorian Fainelli 	}
7415e3644a9SFlorian Fainelli 
7425e3644a9SFlorian Fainelli 	mac_addr_used++;
7435e3644a9SFlorian Fainelli 	return 0;
7445e3644a9SFlorian Fainelli }
7455e3644a9SFlorian Fainelli 
7465e3644a9SFlorian Fainelli /*
747e7300d04SMaxime Bizon  * early init callback, read nvram data from flash and checksum it
748e7300d04SMaxime Bizon  */
749e7300d04SMaxime Bizon void __init board_prom_init(void)
750e7300d04SMaxime Bizon {
751e7300d04SMaxime Bizon 	unsigned int check_len, i;
752e7300d04SMaxime Bizon 	u8 *boot_addr, *cfe, *p;
753e7300d04SMaxime Bizon 	char cfe_version[32];
754e7300d04SMaxime Bizon 	u32 val;
755e7300d04SMaxime Bizon 
756e5766aeaSJonas Gorski 	/* read base address of boot chip select (0)
757e5766aeaSJonas Gorski 	 * 6328 does not have MPI but boots from a fixed address
758e5766aeaSJonas Gorski 	 */
759e5766aeaSJonas Gorski 	if (BCMCPU_IS_6328())
760e5766aeaSJonas Gorski 		val = 0x18000000;
761e5766aeaSJonas Gorski 	else {
762e7300d04SMaxime Bizon 		val = bcm_mpi_readl(MPI_CSBASE_REG(0));
763e7300d04SMaxime Bizon 		val &= MPI_CSBASE_BASE_MASK;
764e5766aeaSJonas Gorski 	}
765e7300d04SMaxime Bizon 	boot_addr = (u8 *)KSEG1ADDR(val);
766e7300d04SMaxime Bizon 
767e7300d04SMaxime Bizon 	/* dump cfe version */
768e7300d04SMaxime Bizon 	cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
769e7300d04SMaxime Bizon 	if (!memcmp(cfe, "cfe-v", 5))
770e7300d04SMaxime Bizon 		snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u",
771e7300d04SMaxime Bizon 			 cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]);
772e7300d04SMaxime Bizon 	else
773e7300d04SMaxime Bizon 		strcpy(cfe_version, "unknown");
774e7300d04SMaxime Bizon 	printk(KERN_INFO PFX "CFE version: %s\n", cfe_version);
775e7300d04SMaxime Bizon 
776e7300d04SMaxime Bizon 	/* extract nvram data */
777e7300d04SMaxime Bizon 	memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
778e7300d04SMaxime Bizon 
779e7300d04SMaxime Bizon 	/* check checksum before using data */
780e7300d04SMaxime Bizon 	if (nvram.version <= 4)
781e7300d04SMaxime Bizon 		check_len = offsetof(struct bcm963xx_nvram, checksum_old);
782e7300d04SMaxime Bizon 	else
783e7300d04SMaxime Bizon 		check_len = sizeof(nvram);
784e7300d04SMaxime Bizon 	val = 0;
785e7300d04SMaxime Bizon 	p = (u8 *)&nvram;
786e7300d04SMaxime Bizon 	while (check_len--)
787e7300d04SMaxime Bizon 		val += *p;
788e7300d04SMaxime Bizon 	if (val) {
789e7300d04SMaxime Bizon 		printk(KERN_ERR PFX "invalid nvram checksum\n");
790e7300d04SMaxime Bizon 		return;
791e7300d04SMaxime Bizon 	}
792e7300d04SMaxime Bizon 
793e7300d04SMaxime Bizon 	/* find board by name */
794e7300d04SMaxime Bizon 	for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
795e7300d04SMaxime Bizon 		if (strncmp(nvram.name, bcm963xx_boards[i]->name,
796e7300d04SMaxime Bizon 			    sizeof(nvram.name)))
797e7300d04SMaxime Bizon 			continue;
798e7300d04SMaxime Bizon 		/* copy, board desc array is marked initdata */
799e7300d04SMaxime Bizon 		memcpy(&board, bcm963xx_boards[i], sizeof(board));
800e7300d04SMaxime Bizon 		break;
801e7300d04SMaxime Bizon 	}
802e7300d04SMaxime Bizon 
803e7300d04SMaxime Bizon 	/* bail out if board is not found, will complain later */
804e7300d04SMaxime Bizon 	if (!board.name[0]) {
805e7300d04SMaxime Bizon 		char name[17];
806e7300d04SMaxime Bizon 		memcpy(name, nvram.name, 16);
807e7300d04SMaxime Bizon 		name[16] = 0;
808e7300d04SMaxime Bizon 		printk(KERN_ERR PFX "unknown bcm963xx board: %s\n",
809e7300d04SMaxime Bizon 		       name);
810e7300d04SMaxime Bizon 		return;
811e7300d04SMaxime Bizon 	}
812e7300d04SMaxime Bizon 
813e7300d04SMaxime Bizon 	/* setup pin multiplexing depending on board enabled device,
814e7300d04SMaxime Bizon 	 * this has to be done this early since PCI init is done
815e7300d04SMaxime Bizon 	 * inside arch_initcall */
816e7300d04SMaxime Bizon 	val = 0;
817e7300d04SMaxime Bizon 
818e7300d04SMaxime Bizon #ifdef CONFIG_PCI
819e7300d04SMaxime Bizon 	if (board.has_pci) {
820e7300d04SMaxime Bizon 		bcm63xx_pci_enabled = 1;
821e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
822e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G2_PCI;
823e7300d04SMaxime Bizon 	}
824e7300d04SMaxime Bizon #endif
825e7300d04SMaxime Bizon 
826e7300d04SMaxime Bizon 	if (board.has_pccard) {
827e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
828e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G1_MII_PCCARD;
829e7300d04SMaxime Bizon 	}
830e7300d04SMaxime Bizon 
831e7300d04SMaxime Bizon 	if (board.has_enet0 && !board.enet0.use_internal_phy) {
832e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
833e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G3_EXT_MII |
834e7300d04SMaxime Bizon 				GPIO_MODE_6348_G0_EXT_MII;
835e7300d04SMaxime Bizon 	}
836e7300d04SMaxime Bizon 
837e7300d04SMaxime Bizon 	if (board.has_enet1 && !board.enet1.use_internal_phy) {
838e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
839e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G3_EXT_MII |
840e7300d04SMaxime Bizon 				GPIO_MODE_6348_G0_EXT_MII;
841e7300d04SMaxime Bizon 	}
842e7300d04SMaxime Bizon 
843e7300d04SMaxime Bizon 	bcm_gpio_writel(val, GPIO_MODE_REG);
844e7300d04SMaxime Bizon }
845e7300d04SMaxime Bizon 
846e7300d04SMaxime Bizon /*
847e7300d04SMaxime Bizon  * second stage init callback, good time to panic if we couldn't
848e7300d04SMaxime Bizon  * identify on which board we're running since early printk is working
849e7300d04SMaxime Bizon  */
850e7300d04SMaxime Bizon void __init board_setup(void)
851e7300d04SMaxime Bizon {
852e7300d04SMaxime Bizon 	if (!board.name[0])
853e7300d04SMaxime Bizon 		panic("unable to detect bcm963xx board");
854e7300d04SMaxime Bizon 	printk(KERN_INFO PFX "board name: %s\n", board.name);
855e7300d04SMaxime Bizon 
856e7300d04SMaxime Bizon 	/* make sure we're running on expected cpu */
857e7300d04SMaxime Bizon 	if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
858e7300d04SMaxime Bizon 		panic("unexpected CPU for bcm963xx board");
859e7300d04SMaxime Bizon }
860e7300d04SMaxime Bizon 
861e7300d04SMaxime Bizon static struct gpio_led_platform_data bcm63xx_led_data;
862e7300d04SMaxime Bizon 
863e7300d04SMaxime Bizon static struct platform_device bcm63xx_gpio_leds = {
864e7300d04SMaxime Bizon 	.name			= "leds-gpio",
865e7300d04SMaxime Bizon 	.id			= 0,
866e7300d04SMaxime Bizon 	.dev.platform_data	= &bcm63xx_led_data,
867e7300d04SMaxime Bizon };
868e7300d04SMaxime Bizon 
869e7300d04SMaxime Bizon /*
870e7300d04SMaxime Bizon  * third stage init callback, register all board devices.
871e7300d04SMaxime Bizon  */
872e7300d04SMaxime Bizon int __init board_register_devices(void)
873e7300d04SMaxime Bizon {
874524ef29cSMaxime Bizon 	if (board.has_uart0)
875524ef29cSMaxime Bizon 		bcm63xx_uart_register(0);
876524ef29cSMaxime Bizon 
877524ef29cSMaxime Bizon 	if (board.has_uart1)
878524ef29cSMaxime Bizon 		bcm63xx_uart_register(1);
879524ef29cSMaxime Bizon 
880553d6d5fSMaxime Bizon 	if (board.has_pccard)
881553d6d5fSMaxime Bizon 		bcm63xx_pcmcia_register();
882553d6d5fSMaxime Bizon 
883e7300d04SMaxime Bizon 	if (board.has_enet0 &&
884e7300d04SMaxime Bizon 	    !board_get_mac_address(board.enet0.mac_addr))
885e7300d04SMaxime Bizon 		bcm63xx_enet_register(0, &board.enet0);
886e7300d04SMaxime Bizon 
887e7300d04SMaxime Bizon 	if (board.has_enet1 &&
888e7300d04SMaxime Bizon 	    !board_get_mac_address(board.enet1.mac_addr))
889e7300d04SMaxime Bizon 		bcm63xx_enet_register(1, &board.enet1);
890e7300d04SMaxime Bizon 
891e7300d04SMaxime Bizon 	if (board.has_dsp)
892e7300d04SMaxime Bizon 		bcm63xx_dsp_register(&board.dsp);
893e7300d04SMaxime Bizon 
894b15a6d62SFlorian Fainelli 	/* Generate MAC address for WLAN and register our SPROM,
895b15a6d62SFlorian Fainelli 	 * do this after registering enet devices
896b15a6d62SFlorian Fainelli 	 */
897b15a6d62SFlorian Fainelli #ifdef CONFIG_SSB_PCIHOST
898b15a6d62SFlorian Fainelli 	if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
899b15a6d62SFlorian Fainelli 		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
900b15a6d62SFlorian Fainelli 		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
901b15a6d62SFlorian Fainelli 		if (ssb_arch_register_fallback_sprom(
902b15a6d62SFlorian Fainelli 				&bcm63xx_get_fallback_sprom) < 0)
903b15a6d62SFlorian Fainelli 			pr_err(PFX "failed to register fallback SPROM\n");
904b15a6d62SFlorian Fainelli 	}
905b15a6d62SFlorian Fainelli #endif
906b15a6d62SFlorian Fainelli 
90776ca4e14SFlorian Fainelli 	bcm63xx_spi_register();
90876ca4e14SFlorian Fainelli 
9094b897d54SJonas Gorski 	bcm63xx_flash_register();
910e7300d04SMaxime Bizon 
911e7300d04SMaxime Bizon 	bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
912e7300d04SMaxime Bizon 	bcm63xx_led_data.leds = board.leds;
913e7300d04SMaxime Bizon 
914e7300d04SMaxime Bizon 	platform_device_register(&bcm63xx_gpio_leds);
915e7300d04SMaxime Bizon 
916e7300d04SMaxime Bizon 	return 0;
917e7300d04SMaxime Bizon }
918