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 
1063893ea5SGregory Fong #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1163893ea5SGregory Fong 
12e7300d04SMaxime Bizon #include <linux/init.h>
13e7300d04SMaxime Bizon #include <linux/kernel.h>
14e7300d04SMaxime Bizon #include <linux/string.h>
15e7300d04SMaxime Bizon #include <linux/platform_device.h>
16e7300d04SMaxime Bizon #include <linux/ssb/ssb.h>
17e7300d04SMaxime Bizon #include <asm/addrspace.h>
18e7300d04SMaxime Bizon #include <bcm63xx_board.h>
19e7300d04SMaxime Bizon #include <bcm63xx_cpu.h>
20524ef29cSMaxime Bizon #include <bcm63xx_dev_uart.h>
21e7300d04SMaxime Bizon #include <bcm63xx_regs.h>
22e7300d04SMaxime Bizon #include <bcm63xx_io.h>
23e7e333cbSJonas Gorski #include <bcm63xx_nvram.h>
24e7300d04SMaxime Bizon #include <bcm63xx_dev_pci.h>
25e7300d04SMaxime Bizon #include <bcm63xx_dev_enet.h>
264b897d54SJonas Gorski #include <bcm63xx_dev_flash.h>
2783bb90faSJonas Gorski #include <bcm63xx_dev_hsspi.h>
28553d6d5fSMaxime Bizon #include <bcm63xx_dev_pcmcia.h>
2976ca4e14SFlorian Fainelli #include <bcm63xx_dev_spi.h>
3022df90f6SKevin Cernekee #include <bcm63xx_dev_usb_usbd.h>
31e7300d04SMaxime Bizon #include <board_bcm963xx.h>
32e7300d04SMaxime Bizon 
33d753601aSFlorian Fainelli #include <uapi/linux/bcm933xx_hcs.h>
34d753601aSFlorian Fainelli 
35e7300d04SMaxime Bizon 
36d753601aSFlorian Fainelli #define HCS_OFFSET_128K			0x20000
37d753601aSFlorian Fainelli 
38e7300d04SMaxime Bizon static struct board_info board;
39e7300d04SMaxime Bizon 
40e7300d04SMaxime Bizon /*
41450acb0bSFlorian Fainelli  * known 3368 boards
42450acb0bSFlorian Fainelli  */
43450acb0bSFlorian Fainelli #ifdef CONFIG_BCM63XX_CPU_3368
44450acb0bSFlorian Fainelli static struct board_info __initdata board_cvg834g = {
45450acb0bSFlorian Fainelli 	.name				= "CVG834G_E15R3921",
46450acb0bSFlorian Fainelli 	.expected_cpu_id		= 0x3368,
47450acb0bSFlorian Fainelli 
48450acb0bSFlorian Fainelli 	.has_uart0			= 1,
49450acb0bSFlorian Fainelli 	.has_uart1			= 1,
50450acb0bSFlorian Fainelli 
51450acb0bSFlorian Fainelli 	.has_enet0			= 1,
52450acb0bSFlorian Fainelli 	.has_pci			= 1,
53450acb0bSFlorian Fainelli 
54450acb0bSFlorian Fainelli 	.enet0 = {
55450acb0bSFlorian Fainelli 		.has_phy		= 1,
56450acb0bSFlorian Fainelli 		.use_internal_phy	= 1,
57450acb0bSFlorian Fainelli 	},
58450acb0bSFlorian Fainelli 
59450acb0bSFlorian Fainelli 	.leds = {
60450acb0bSFlorian Fainelli 		{
61450acb0bSFlorian Fainelli 			.name		= "CVG834G:green:power",
62450acb0bSFlorian Fainelli 			.gpio		= 37,
63450acb0bSFlorian Fainelli 			.default_trigger= "default-on",
64450acb0bSFlorian Fainelli 		},
65450acb0bSFlorian Fainelli 	},
66450acb0bSFlorian Fainelli 
67450acb0bSFlorian Fainelli 	.ephy_reset_gpio		= 36,
68450acb0bSFlorian Fainelli 	.ephy_reset_gpio_flags		= GPIOF_INIT_HIGH,
69450acb0bSFlorian Fainelli };
70c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_3368 */
71450acb0bSFlorian Fainelli 
72450acb0bSFlorian Fainelli /*
732f74b770SJonas Gorski  * known 6328 boards
742f74b770SJonas Gorski  */
752f74b770SJonas Gorski #ifdef CONFIG_BCM63XX_CPU_6328
762f74b770SJonas Gorski static struct board_info __initdata board_96328avng = {
772f74b770SJonas Gorski 	.name				= "96328avng",
782f74b770SJonas Gorski 	.expected_cpu_id		= 0x6328,
792f74b770SJonas Gorski 
802f74b770SJonas Gorski 	.has_uart0			= 1,
812f74b770SJonas Gorski 	.has_pci			= 1,
8222df90f6SKevin Cernekee 	.has_usbd			= 0,
8322df90f6SKevin Cernekee 
8422df90f6SKevin Cernekee 	.usbd = {
8522df90f6SKevin Cernekee 		.use_fullspeed		= 0,
8622df90f6SKevin Cernekee 		.port_no		= 0,
8722df90f6SKevin Cernekee 	},
882f74b770SJonas Gorski 
892f74b770SJonas Gorski 	.leds = {
902f74b770SJonas Gorski 		{
912f74b770SJonas Gorski 			.name		= "96328avng::ppp-fail",
922f74b770SJonas Gorski 			.gpio		= 2,
932f74b770SJonas Gorski 			.active_low	= 1,
942f74b770SJonas Gorski 		},
952f74b770SJonas Gorski 		{
962f74b770SJonas Gorski 			.name		= "96328avng::power",
972f74b770SJonas Gorski 			.gpio		= 4,
982f74b770SJonas Gorski 			.active_low	= 1,
992f74b770SJonas Gorski 			.default_trigger = "default-on",
1002f74b770SJonas Gorski 		},
1012f74b770SJonas Gorski 		{
1022f74b770SJonas Gorski 			.name		= "96328avng::power-fail",
1032f74b770SJonas Gorski 			.gpio		= 8,
1042f74b770SJonas Gorski 			.active_low	= 1,
1052f74b770SJonas Gorski 		},
1062f74b770SJonas Gorski 		{
1072f74b770SJonas Gorski 			.name		= "96328avng::wps",
1082f74b770SJonas Gorski 			.gpio		= 9,
1092f74b770SJonas Gorski 			.active_low	= 1,
1102f74b770SJonas Gorski 		},
1112f74b770SJonas Gorski 		{
1122f74b770SJonas Gorski 			.name		= "96328avng::ppp",
1132f74b770SJonas Gorski 			.gpio		= 11,
1142f74b770SJonas Gorski 			.active_low	= 1,
1152f74b770SJonas Gorski 		},
1162f74b770SJonas Gorski 	},
1172f74b770SJonas Gorski };
118c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6328 */
1192f74b770SJonas Gorski 
1202f74b770SJonas Gorski /*
121e7300d04SMaxime Bizon  * known 6338 boards
122e7300d04SMaxime Bizon  */
123e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6338
124e7300d04SMaxime Bizon static struct board_info __initdata board_96338gw = {
125e7300d04SMaxime Bizon 	.name				= "96338GW",
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 	.has_ohci0			= 1,
136e7300d04SMaxime Bizon 
137e7300d04SMaxime Bizon 	.leds = {
138e7300d04SMaxime Bizon 		{
139e7300d04SMaxime Bizon 			.name		= "adsl",
140e7300d04SMaxime Bizon 			.gpio		= 3,
141e7300d04SMaxime Bizon 			.active_low	= 1,
142e7300d04SMaxime Bizon 		},
143e7300d04SMaxime Bizon 		{
144e7300d04SMaxime Bizon 			.name		= "ses",
145e7300d04SMaxime Bizon 			.gpio		= 5,
146e7300d04SMaxime Bizon 			.active_low	= 1,
147e7300d04SMaxime Bizon 		},
148e7300d04SMaxime Bizon 		{
149e7300d04SMaxime Bizon 			.name		= "ppp-fail",
150e7300d04SMaxime Bizon 			.gpio		= 4,
151e7300d04SMaxime Bizon 			.active_low	= 1,
152e7300d04SMaxime Bizon 		},
153e7300d04SMaxime Bizon 		{
154e7300d04SMaxime Bizon 			.name		= "power",
155e7300d04SMaxime Bizon 			.gpio		= 0,
156e7300d04SMaxime Bizon 			.active_low	= 1,
157e7300d04SMaxime Bizon 			.default_trigger = "default-on",
158e7300d04SMaxime Bizon 		},
159e7300d04SMaxime Bizon 		{
160e7300d04SMaxime Bizon 			.name		= "stop",
161e7300d04SMaxime Bizon 			.gpio		= 1,
162e7300d04SMaxime Bizon 			.active_low	= 1,
163e7300d04SMaxime Bizon 		}
164e7300d04SMaxime Bizon 	},
165e7300d04SMaxime Bizon };
166e7300d04SMaxime Bizon 
167e7300d04SMaxime Bizon static struct board_info __initdata board_96338w = {
168e7300d04SMaxime Bizon 	.name				= "96338W",
169e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6338,
170e7300d04SMaxime Bizon 
171524ef29cSMaxime Bizon 	.has_uart0			= 1,
172e7300d04SMaxime Bizon 	.has_enet0			= 1,
173e7300d04SMaxime Bizon 	.enet0 = {
174e7300d04SMaxime Bizon 		.force_speed_100	= 1,
175e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
176e7300d04SMaxime Bizon 	},
177e7300d04SMaxime Bizon 
178e7300d04SMaxime Bizon 	.leds = {
179e7300d04SMaxime Bizon 		{
180e7300d04SMaxime Bizon 			.name		= "adsl",
181e7300d04SMaxime Bizon 			.gpio		= 3,
182e7300d04SMaxime Bizon 			.active_low	= 1,
183e7300d04SMaxime Bizon 		},
184e7300d04SMaxime Bizon 		{
185e7300d04SMaxime Bizon 			.name		= "ses",
186e7300d04SMaxime Bizon 			.gpio		= 5,
187e7300d04SMaxime Bizon 			.active_low	= 1,
188e7300d04SMaxime Bizon 		},
189e7300d04SMaxime Bizon 		{
190e7300d04SMaxime Bizon 			.name		= "ppp-fail",
191e7300d04SMaxime Bizon 			.gpio		= 4,
192e7300d04SMaxime Bizon 			.active_low	= 1,
193e7300d04SMaxime Bizon 		},
194e7300d04SMaxime Bizon 		{
195e7300d04SMaxime Bizon 			.name		= "power",
196e7300d04SMaxime Bizon 			.gpio		= 0,
197e7300d04SMaxime Bizon 			.active_low	= 1,
198e7300d04SMaxime Bizon 			.default_trigger = "default-on",
199e7300d04SMaxime Bizon 		},
200e7300d04SMaxime Bizon 		{
201e7300d04SMaxime Bizon 			.name		= "stop",
202e7300d04SMaxime Bizon 			.gpio		= 1,
203e7300d04SMaxime Bizon 			.active_low	= 1,
204e7300d04SMaxime Bizon 		},
205e7300d04SMaxime Bizon 	},
206e7300d04SMaxime Bizon };
207c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6338 */
208e7300d04SMaxime Bizon 
209e7300d04SMaxime Bizon /*
210e7300d04SMaxime Bizon  * known 6345 boards
211e7300d04SMaxime Bizon  */
212e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6345
213e7300d04SMaxime Bizon static struct board_info __initdata board_96345gw2 = {
214e7300d04SMaxime Bizon 	.name				= "96345GW2",
215e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6345,
216524ef29cSMaxime Bizon 
217524ef29cSMaxime Bizon 	.has_uart0			= 1,
218e7300d04SMaxime Bizon };
219c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6345 */
220e7300d04SMaxime Bizon 
221e7300d04SMaxime Bizon /*
222e7300d04SMaxime Bizon  * known 6348 boards
223e7300d04SMaxime Bizon  */
224e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6348
225e7300d04SMaxime Bizon static struct board_info __initdata board_96348r = {
226e7300d04SMaxime Bizon 	.name				= "96348R",
227e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
228e7300d04SMaxime Bizon 
229524ef29cSMaxime Bizon 	.has_uart0			= 1,
230e7300d04SMaxime Bizon 	.has_enet0			= 1,
231e7300d04SMaxime Bizon 	.has_pci			= 1,
232e7300d04SMaxime Bizon 
233e7300d04SMaxime Bizon 	.enet0 = {
234e7300d04SMaxime Bizon 		.has_phy		= 1,
235e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
236e7300d04SMaxime Bizon 	},
237e7300d04SMaxime Bizon 
238e7300d04SMaxime Bizon 	.leds = {
239e7300d04SMaxime Bizon 		{
240e7300d04SMaxime Bizon 			.name		= "adsl-fail",
241e7300d04SMaxime Bizon 			.gpio		= 2,
242e7300d04SMaxime Bizon 			.active_low	= 1,
243e7300d04SMaxime Bizon 		},
244e7300d04SMaxime Bizon 		{
245e7300d04SMaxime Bizon 			.name		= "ppp",
246e7300d04SMaxime Bizon 			.gpio		= 3,
247e7300d04SMaxime Bizon 			.active_low	= 1,
248e7300d04SMaxime Bizon 		},
249e7300d04SMaxime Bizon 		{
250e7300d04SMaxime Bizon 			.name		= "ppp-fail",
251e7300d04SMaxime Bizon 			.gpio		= 4,
252e7300d04SMaxime Bizon 			.active_low	= 1,
253e7300d04SMaxime Bizon 		},
254e7300d04SMaxime Bizon 		{
255e7300d04SMaxime Bizon 			.name		= "power",
256e7300d04SMaxime Bizon 			.gpio		= 0,
257e7300d04SMaxime Bizon 			.active_low	= 1,
258e7300d04SMaxime Bizon 			.default_trigger = "default-on",
259e7300d04SMaxime Bizon 
260e7300d04SMaxime Bizon 		},
261e7300d04SMaxime Bizon 		{
262e7300d04SMaxime Bizon 			.name		= "stop",
263e7300d04SMaxime Bizon 			.gpio		= 1,
264e7300d04SMaxime Bizon 			.active_low	= 1,
265e7300d04SMaxime Bizon 		},
266e7300d04SMaxime Bizon 	},
267e7300d04SMaxime Bizon };
268e7300d04SMaxime Bizon 
269e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_10 = {
270e7300d04SMaxime Bizon 	.name				= "96348GW-10",
271e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
272e7300d04SMaxime Bizon 
273524ef29cSMaxime Bizon 	.has_uart0			= 1,
274e7300d04SMaxime Bizon 	.has_enet0			= 1,
275e7300d04SMaxime Bizon 	.has_enet1			= 1,
276e7300d04SMaxime Bizon 	.has_pci			= 1,
277e7300d04SMaxime Bizon 
278e7300d04SMaxime Bizon 	.enet0 = {
279e7300d04SMaxime Bizon 		.has_phy		= 1,
280e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
281e7300d04SMaxime Bizon 	},
282e7300d04SMaxime Bizon 	.enet1 = {
283e7300d04SMaxime Bizon 		.force_speed_100	= 1,
284e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
285e7300d04SMaxime Bizon 	},
286e7300d04SMaxime Bizon 
287e7300d04SMaxime Bizon 	.has_ohci0			= 1,
288e7300d04SMaxime Bizon 	.has_pccard			= 1,
289e7300d04SMaxime Bizon 	.has_ehci0			= 1,
290e7300d04SMaxime Bizon 
291e7300d04SMaxime Bizon 	.leds = {
292e7300d04SMaxime Bizon 		{
293e7300d04SMaxime Bizon 			.name		= "adsl-fail",
294e7300d04SMaxime Bizon 			.gpio		= 2,
295e7300d04SMaxime Bizon 			.active_low	= 1,
296e7300d04SMaxime Bizon 		},
297e7300d04SMaxime Bizon 		{
298e7300d04SMaxime Bizon 			.name		= "ppp",
299e7300d04SMaxime Bizon 			.gpio		= 3,
300e7300d04SMaxime Bizon 			.active_low	= 1,
301e7300d04SMaxime Bizon 		},
302e7300d04SMaxime Bizon 		{
303e7300d04SMaxime Bizon 			.name		= "ppp-fail",
304e7300d04SMaxime Bizon 			.gpio		= 4,
305e7300d04SMaxime Bizon 			.active_low	= 1,
306e7300d04SMaxime Bizon 		},
307e7300d04SMaxime Bizon 		{
308e7300d04SMaxime Bizon 			.name		= "power",
309e7300d04SMaxime Bizon 			.gpio		= 0,
310e7300d04SMaxime Bizon 			.active_low	= 1,
311e7300d04SMaxime Bizon 			.default_trigger = "default-on",
312e7300d04SMaxime Bizon 		},
313e7300d04SMaxime Bizon 		{
314e7300d04SMaxime Bizon 			.name		= "stop",
315e7300d04SMaxime Bizon 			.gpio		= 1,
316e7300d04SMaxime Bizon 			.active_low	= 1,
317e7300d04SMaxime Bizon 		},
318e7300d04SMaxime Bizon 	},
319e7300d04SMaxime Bizon };
320e7300d04SMaxime Bizon 
321e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_11 = {
322e7300d04SMaxime Bizon 	.name				= "96348GW-11",
323e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
324e7300d04SMaxime Bizon 
325524ef29cSMaxime Bizon 	.has_uart0			= 1,
326e7300d04SMaxime Bizon 	.has_enet0			= 1,
327e7300d04SMaxime Bizon 	.has_enet1			= 1,
328e7300d04SMaxime Bizon 	.has_pci			= 1,
329e7300d04SMaxime Bizon 
330e7300d04SMaxime Bizon 	.enet0 = {
331e7300d04SMaxime Bizon 		.has_phy		= 1,
332e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
333e7300d04SMaxime Bizon 	},
334e7300d04SMaxime Bizon 
335e7300d04SMaxime Bizon 	.enet1 = {
336e7300d04SMaxime Bizon 		.force_speed_100	= 1,
337e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
338e7300d04SMaxime Bizon 	},
339e7300d04SMaxime Bizon 
340e7300d04SMaxime Bizon 
341e7300d04SMaxime Bizon 	.has_ohci0 = 1,
342e7300d04SMaxime Bizon 	.has_pccard = 1,
343e7300d04SMaxime Bizon 	.has_ehci0 = 1,
344e7300d04SMaxime Bizon 
345e7300d04SMaxime Bizon 	.leds = {
346e7300d04SMaxime Bizon 		{
347e7300d04SMaxime Bizon 			.name		= "adsl-fail",
348e7300d04SMaxime Bizon 			.gpio		= 2,
349e7300d04SMaxime Bizon 			.active_low	= 1,
350e7300d04SMaxime Bizon 		},
351e7300d04SMaxime Bizon 		{
352e7300d04SMaxime Bizon 			.name		= "ppp",
353e7300d04SMaxime Bizon 			.gpio		= 3,
354e7300d04SMaxime Bizon 			.active_low	= 1,
355e7300d04SMaxime Bizon 		},
356e7300d04SMaxime Bizon 		{
357e7300d04SMaxime Bizon 			.name		= "ppp-fail",
358e7300d04SMaxime Bizon 			.gpio		= 4,
359e7300d04SMaxime Bizon 			.active_low	= 1,
360e7300d04SMaxime Bizon 		},
361e7300d04SMaxime Bizon 		{
362e7300d04SMaxime Bizon 			.name		= "power",
363e7300d04SMaxime Bizon 			.gpio		= 0,
364e7300d04SMaxime Bizon 			.active_low	= 1,
365e7300d04SMaxime Bizon 			.default_trigger = "default-on",
366e7300d04SMaxime Bizon 		},
367e7300d04SMaxime Bizon 		{
368e7300d04SMaxime Bizon 			.name		= "stop",
369e7300d04SMaxime Bizon 			.gpio		= 1,
370e7300d04SMaxime Bizon 			.active_low	= 1,
371e7300d04SMaxime Bizon 		},
372e7300d04SMaxime Bizon 	},
373e7300d04SMaxime Bizon };
374e7300d04SMaxime Bizon 
375e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw = {
376e7300d04SMaxime Bizon 	.name				= "96348GW",
377e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
378e7300d04SMaxime Bizon 
379524ef29cSMaxime Bizon 	.has_uart0			= 1,
380e7300d04SMaxime Bizon 	.has_enet0			= 1,
381e7300d04SMaxime Bizon 	.has_enet1			= 1,
382e7300d04SMaxime Bizon 	.has_pci			= 1,
383e7300d04SMaxime Bizon 
384e7300d04SMaxime Bizon 	.enet0 = {
385e7300d04SMaxime Bizon 		.has_phy		= 1,
386e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
387e7300d04SMaxime Bizon 	},
388e7300d04SMaxime Bizon 	.enet1 = {
389e7300d04SMaxime Bizon 		.force_speed_100	= 1,
390e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
391e7300d04SMaxime Bizon 	},
392e7300d04SMaxime Bizon 
393e7300d04SMaxime Bizon 	.has_ohci0 = 1,
394e7300d04SMaxime Bizon 
395e7300d04SMaxime Bizon 	.leds = {
396e7300d04SMaxime Bizon 		{
397e7300d04SMaxime Bizon 			.name		= "adsl-fail",
398e7300d04SMaxime Bizon 			.gpio		= 2,
399e7300d04SMaxime Bizon 			.active_low	= 1,
400e7300d04SMaxime Bizon 		},
401e7300d04SMaxime Bizon 		{
402e7300d04SMaxime Bizon 			.name		= "ppp",
403e7300d04SMaxime Bizon 			.gpio		= 3,
404e7300d04SMaxime Bizon 			.active_low	= 1,
405e7300d04SMaxime Bizon 		},
406e7300d04SMaxime Bizon 		{
407e7300d04SMaxime Bizon 			.name		= "ppp-fail",
408e7300d04SMaxime Bizon 			.gpio		= 4,
409e7300d04SMaxime Bizon 			.active_low	= 1,
410e7300d04SMaxime Bizon 		},
411e7300d04SMaxime Bizon 		{
412e7300d04SMaxime Bizon 			.name		= "power",
413e7300d04SMaxime Bizon 			.gpio		= 0,
414e7300d04SMaxime Bizon 			.active_low	= 1,
415e7300d04SMaxime Bizon 			.default_trigger = "default-on",
416e7300d04SMaxime Bizon 		},
417e7300d04SMaxime Bizon 		{
418e7300d04SMaxime Bizon 			.name		= "stop",
419e7300d04SMaxime Bizon 			.gpio		= 1,
420e7300d04SMaxime Bizon 			.active_low	= 1,
421e7300d04SMaxime Bizon 		},
422e7300d04SMaxime Bizon 	},
423e7300d04SMaxime Bizon };
424e7300d04SMaxime Bizon 
425e7300d04SMaxime Bizon static struct board_info __initdata board_FAST2404 = {
426e7300d04SMaxime Bizon 	.name				= "F@ST2404",
427e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
428e7300d04SMaxime Bizon 
429524ef29cSMaxime Bizon 	.has_uart0			= 1,
430e7300d04SMaxime Bizon 	.has_enet0			= 1,
431e7300d04SMaxime Bizon 	.has_enet1			= 1,
432e7300d04SMaxime Bizon 	.has_pci			= 1,
433e7300d04SMaxime Bizon 
434e7300d04SMaxime Bizon 	.enet0 = {
435e7300d04SMaxime Bizon 		.has_phy		= 1,
436e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
437e7300d04SMaxime Bizon 	},
438e7300d04SMaxime Bizon 
439e7300d04SMaxime Bizon 	.enet1 = {
440e7300d04SMaxime Bizon 		.force_speed_100	= 1,
441e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
442e7300d04SMaxime Bizon 	},
443e7300d04SMaxime Bizon 
444e7300d04SMaxime Bizon 	.has_ohci0			= 1,
445e7300d04SMaxime Bizon 	.has_pccard			= 1,
446e7300d04SMaxime Bizon 	.has_ehci0			= 1,
447e7300d04SMaxime Bizon };
448e7300d04SMaxime Bizon 
4492e6ad9a9SFlorian Fainelli static struct board_info __initdata board_rta1025w_16 = {
4502e6ad9a9SFlorian Fainelli 	.name				= "RTA1025W_16",
4512e6ad9a9SFlorian Fainelli 	.expected_cpu_id		= 0x6348,
4522e6ad9a9SFlorian Fainelli 
4532e6ad9a9SFlorian Fainelli 	.has_enet0			= 1,
4542e6ad9a9SFlorian Fainelli 	.has_enet1			= 1,
4552e6ad9a9SFlorian Fainelli 	.has_pci			= 1,
4562e6ad9a9SFlorian Fainelli 
4572e6ad9a9SFlorian Fainelli 	.enet0 = {
4582e6ad9a9SFlorian Fainelli 		.has_phy		= 1,
4592e6ad9a9SFlorian Fainelli 		.use_internal_phy	= 1,
4602e6ad9a9SFlorian Fainelli 	},
4612e6ad9a9SFlorian Fainelli 	.enet1 = {
4622e6ad9a9SFlorian Fainelli 		.force_speed_100	= 1,
4632e6ad9a9SFlorian Fainelli 		.force_duplex_full	= 1,
4642e6ad9a9SFlorian Fainelli 	},
4652e6ad9a9SFlorian Fainelli };
4662e6ad9a9SFlorian Fainelli 
467e7300d04SMaxime Bizon static struct board_info __initdata board_DV201AMR = {
468e7300d04SMaxime Bizon 	.name				= "DV201AMR",
469e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
470e7300d04SMaxime Bizon 
471524ef29cSMaxime Bizon 	.has_uart0			= 1,
472e7300d04SMaxime Bizon 	.has_pci			= 1,
473e7300d04SMaxime Bizon 	.has_ohci0			= 1,
474e7300d04SMaxime Bizon 
475e7300d04SMaxime Bizon 	.has_enet0			= 1,
476e7300d04SMaxime Bizon 	.has_enet1			= 1,
477e7300d04SMaxime Bizon 	.enet0 = {
478e7300d04SMaxime Bizon 		.has_phy		= 1,
479e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
480e7300d04SMaxime Bizon 	},
481e7300d04SMaxime Bizon 	.enet1 = {
482e7300d04SMaxime Bizon 		.force_speed_100	= 1,
483e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
484e7300d04SMaxime Bizon 	},
485e7300d04SMaxime Bizon };
486e7300d04SMaxime Bizon 
487e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_a = {
488e7300d04SMaxime Bizon 	.name				= "96348GW-A",
489e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6348,
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 	.enet1 = {
501e7300d04SMaxime Bizon 		.force_speed_100	= 1,
502e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
503e7300d04SMaxime Bizon 	},
504e7300d04SMaxime Bizon 
505e7300d04SMaxime Bizon 	.has_ohci0 = 1,
506e7300d04SMaxime Bizon };
507c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6348 */
508e7300d04SMaxime Bizon 
509e7300d04SMaxime Bizon /*
510e7300d04SMaxime Bizon  * known 6358 boards
511e7300d04SMaxime Bizon  */
512e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6358
513e7300d04SMaxime Bizon static struct board_info __initdata board_96358vw = {
514e7300d04SMaxime Bizon 	.name				= "96358VW",
515e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6358,
516e7300d04SMaxime Bizon 
517524ef29cSMaxime Bizon 	.has_uart0			= 1,
518e7300d04SMaxime Bizon 	.has_enet0			= 1,
519e7300d04SMaxime Bizon 	.has_enet1			= 1,
520e7300d04SMaxime Bizon 	.has_pci			= 1,
521e7300d04SMaxime Bizon 
522e7300d04SMaxime Bizon 	.enet0 = {
523e7300d04SMaxime Bizon 		.has_phy		= 1,
524e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
525e7300d04SMaxime Bizon 	},
526e7300d04SMaxime Bizon 
527e7300d04SMaxime Bizon 	.enet1 = {
528e7300d04SMaxime Bizon 		.force_speed_100	= 1,
529e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
530e7300d04SMaxime Bizon 	},
531e7300d04SMaxime Bizon 
532e7300d04SMaxime Bizon 	.has_ohci0 = 1,
533e7300d04SMaxime Bizon 	.has_pccard = 1,
534e7300d04SMaxime Bizon 	.has_ehci0 = 1,
535e7300d04SMaxime Bizon 
536e7300d04SMaxime Bizon 	.leds = {
537e7300d04SMaxime Bizon 		{
538e7300d04SMaxime Bizon 			.name		= "adsl-fail",
539e7300d04SMaxime Bizon 			.gpio		= 15,
540e7300d04SMaxime Bizon 			.active_low	= 1,
541e7300d04SMaxime Bizon 		},
542e7300d04SMaxime Bizon 		{
543e7300d04SMaxime Bizon 			.name		= "ppp",
544e7300d04SMaxime Bizon 			.gpio		= 22,
545e7300d04SMaxime Bizon 			.active_low	= 1,
546e7300d04SMaxime Bizon 		},
547e7300d04SMaxime Bizon 		{
548e7300d04SMaxime Bizon 			.name		= "ppp-fail",
549e7300d04SMaxime Bizon 			.gpio		= 23,
550e7300d04SMaxime Bizon 			.active_low	= 1,
551e7300d04SMaxime Bizon 		},
552e7300d04SMaxime Bizon 		{
553e7300d04SMaxime Bizon 			.name		= "power",
554e7300d04SMaxime Bizon 			.gpio		= 4,
555e7300d04SMaxime Bizon 			.default_trigger = "default-on",
556e7300d04SMaxime Bizon 		},
557e7300d04SMaxime Bizon 		{
558e7300d04SMaxime Bizon 			.name		= "stop",
559e7300d04SMaxime Bizon 			.gpio		= 5,
560e7300d04SMaxime Bizon 		},
561e7300d04SMaxime Bizon 	},
562e7300d04SMaxime Bizon };
563e7300d04SMaxime Bizon 
564e7300d04SMaxime Bizon static struct board_info __initdata board_96358vw2 = {
565e7300d04SMaxime Bizon 	.name				= "96358VW2",
566e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6358,
567e7300d04SMaxime Bizon 
568524ef29cSMaxime Bizon 	.has_uart0			= 1,
569e7300d04SMaxime Bizon 	.has_enet0			= 1,
570e7300d04SMaxime Bizon 	.has_enet1			= 1,
571e7300d04SMaxime Bizon 	.has_pci			= 1,
572e7300d04SMaxime Bizon 
573e7300d04SMaxime Bizon 	.enet0 = {
574e7300d04SMaxime Bizon 		.has_phy		= 1,
575e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
576e7300d04SMaxime Bizon 	},
577e7300d04SMaxime Bizon 
578e7300d04SMaxime Bizon 	.enet1 = {
579e7300d04SMaxime Bizon 		.force_speed_100	= 1,
580e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
581e7300d04SMaxime Bizon 	},
582e7300d04SMaxime Bizon 
583e7300d04SMaxime Bizon 
584e7300d04SMaxime Bizon 	.has_ohci0 = 1,
585e7300d04SMaxime Bizon 	.has_pccard = 1,
586e7300d04SMaxime Bizon 	.has_ehci0 = 1,
587e7300d04SMaxime Bizon 
588e7300d04SMaxime Bizon 	.leds = {
589e7300d04SMaxime Bizon 		{
590e7300d04SMaxime Bizon 			.name		= "adsl",
591e7300d04SMaxime Bizon 			.gpio		= 22,
592e7300d04SMaxime Bizon 			.active_low	= 1,
593e7300d04SMaxime Bizon 		},
594e7300d04SMaxime Bizon 		{
595e7300d04SMaxime Bizon 			.name		= "ppp-fail",
596e7300d04SMaxime Bizon 			.gpio		= 23,
597e7300d04SMaxime Bizon 		},
598e7300d04SMaxime Bizon 		{
599e7300d04SMaxime Bizon 			.name		= "power",
600e7300d04SMaxime Bizon 			.gpio		= 5,
601e7300d04SMaxime Bizon 			.active_low	= 1,
602e7300d04SMaxime Bizon 			.default_trigger = "default-on",
603e7300d04SMaxime Bizon 		},
604e7300d04SMaxime Bizon 		{
605e7300d04SMaxime Bizon 			.name		= "stop",
606e7300d04SMaxime Bizon 			.gpio		= 4,
607e7300d04SMaxime Bizon 			.active_low	= 1,
608e7300d04SMaxime Bizon 		},
609e7300d04SMaxime Bizon 	},
610e7300d04SMaxime Bizon };
611e7300d04SMaxime Bizon 
612e7300d04SMaxime Bizon static struct board_info __initdata board_AGPFS0 = {
613e7300d04SMaxime Bizon 	.name				= "AGPF-S0",
614e7300d04SMaxime Bizon 	.expected_cpu_id		= 0x6358,
615e7300d04SMaxime Bizon 
616524ef29cSMaxime Bizon 	.has_uart0			= 1,
617e7300d04SMaxime Bizon 	.has_enet0			= 1,
618e7300d04SMaxime Bizon 	.has_enet1			= 1,
619e7300d04SMaxime Bizon 	.has_pci			= 1,
620e7300d04SMaxime Bizon 
621e7300d04SMaxime Bizon 	.enet0 = {
622e7300d04SMaxime Bizon 		.has_phy		= 1,
623e7300d04SMaxime Bizon 		.use_internal_phy	= 1,
624e7300d04SMaxime Bizon 	},
625e7300d04SMaxime Bizon 
626e7300d04SMaxime Bizon 	.enet1 = {
627e7300d04SMaxime Bizon 		.force_speed_100	= 1,
628e7300d04SMaxime Bizon 		.force_duplex_full	= 1,
629e7300d04SMaxime Bizon 	},
630e7300d04SMaxime Bizon 
631e7300d04SMaxime Bizon 	.has_ohci0 = 1,
632e7300d04SMaxime Bizon 	.has_ehci0 = 1,
633e7300d04SMaxime Bizon };
634f29b7cacSFlorian Fainelli 
635f29b7cacSFlorian Fainelli static struct board_info __initdata board_DWVS0 = {
636f29b7cacSFlorian Fainelli 	.name				= "DWV-S0",
637f29b7cacSFlorian Fainelli 	.expected_cpu_id		= 0x6358,
638f29b7cacSFlorian Fainelli 
639f29b7cacSFlorian Fainelli 	.has_enet0			= 1,
640f29b7cacSFlorian Fainelli 	.has_enet1			= 1,
641f29b7cacSFlorian Fainelli 	.has_pci			= 1,
642f29b7cacSFlorian Fainelli 
643f29b7cacSFlorian Fainelli 	.enet0 = {
644f29b7cacSFlorian Fainelli 		.has_phy		= 1,
645f29b7cacSFlorian Fainelli 		.use_internal_phy	= 1,
646f29b7cacSFlorian Fainelli 	},
647f29b7cacSFlorian Fainelli 
648f29b7cacSFlorian Fainelli 	.enet1 = {
649f29b7cacSFlorian Fainelli 		.force_speed_100	= 1,
650f29b7cacSFlorian Fainelli 		.force_duplex_full	= 1,
651f29b7cacSFlorian Fainelli 	},
652f29b7cacSFlorian Fainelli 
653f29b7cacSFlorian Fainelli 	.has_ohci0			= 1,
654f29b7cacSFlorian Fainelli };
655c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6358 */
656e7300d04SMaxime Bizon 
657e7300d04SMaxime Bizon /*
658e7300d04SMaxime Bizon  * all boards
659e7300d04SMaxime Bizon  */
6603cf5ae6eSAndi Kleen static const struct board_info __initconst *bcm963xx_boards[] = {
661450acb0bSFlorian Fainelli #ifdef CONFIG_BCM63XX_CPU_3368
662450acb0bSFlorian Fainelli 	&board_cvg834g,
663c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_3368 */
6642f74b770SJonas Gorski #ifdef CONFIG_BCM63XX_CPU_6328
6652f74b770SJonas Gorski 	&board_96328avng,
666c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6328 */
667e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6338
668e7300d04SMaxime Bizon 	&board_96338gw,
669e7300d04SMaxime Bizon 	&board_96338w,
670c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6338 */
671e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6345
672e7300d04SMaxime Bizon 	&board_96345gw2,
673c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6345 */
674e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6348
675e7300d04SMaxime Bizon 	&board_96348r,
676e7300d04SMaxime Bizon 	&board_96348gw,
677e7300d04SMaxime Bizon 	&board_96348gw_10,
678e7300d04SMaxime Bizon 	&board_96348gw_11,
679e7300d04SMaxime Bizon 	&board_FAST2404,
680e7300d04SMaxime Bizon 	&board_DV201AMR,
681e7300d04SMaxime Bizon 	&board_96348gw_a,
6822e6ad9a9SFlorian Fainelli 	&board_rta1025w_16,
683c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6348 */
684e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6358
685e7300d04SMaxime Bizon 	&board_96358vw,
686e7300d04SMaxime Bizon 	&board_96358vw2,
687e7300d04SMaxime Bizon 	&board_AGPFS0,
688f29b7cacSFlorian Fainelli 	&board_DWVS0,
689c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6358 */
690e7300d04SMaxime Bizon };
691e7300d04SMaxime Bizon 
692e7300d04SMaxime Bizon /*
6935e3644a9SFlorian Fainelli  * Register a sane SPROMv2 to make the on-board
6945e3644a9SFlorian Fainelli  * bcm4318 WLAN work
6955e3644a9SFlorian Fainelli  */
6965e3644a9SFlorian Fainelli #ifdef CONFIG_SSB_PCIHOST
6975e3644a9SFlorian Fainelli static struct ssb_sprom bcm63xx_sprom = {
6985e3644a9SFlorian Fainelli 	.revision		= 0x02,
6995e3644a9SFlorian Fainelli 	.board_rev		= 0x17,
7005e3644a9SFlorian Fainelli 	.country_code		= 0x0,
7015e3644a9SFlorian Fainelli 	.ant_available_bg	= 0x3,
7025e3644a9SFlorian Fainelli 	.pa0b0			= 0x15ae,
7035e3644a9SFlorian Fainelli 	.pa0b1			= 0xfa85,
7045e3644a9SFlorian Fainelli 	.pa0b2			= 0xfe8d,
7055e3644a9SFlorian Fainelli 	.pa1b0			= 0xffff,
7065e3644a9SFlorian Fainelli 	.pa1b1			= 0xffff,
7075e3644a9SFlorian Fainelli 	.pa1b2			= 0xffff,
7085e3644a9SFlorian Fainelli 	.gpio0			= 0xff,
7095e3644a9SFlorian Fainelli 	.gpio1			= 0xff,
7105e3644a9SFlorian Fainelli 	.gpio2			= 0xff,
7115e3644a9SFlorian Fainelli 	.gpio3			= 0xff,
7125e3644a9SFlorian Fainelli 	.maxpwr_bg		= 0x004c,
7135e3644a9SFlorian Fainelli 	.itssi_bg		= 0x00,
7145e3644a9SFlorian Fainelli 	.boardflags_lo		= 0x2848,
7155e3644a9SFlorian Fainelli 	.boardflags_hi		= 0x0000,
7165e3644a9SFlorian Fainelli };
717b3ae52b6SHauke Mehrtens 
718b3ae52b6SHauke Mehrtens int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
719b3ae52b6SHauke Mehrtens {
720b3ae52b6SHauke Mehrtens 	if (bus->bustype == SSB_BUSTYPE_PCI) {
721b3ae52b6SHauke Mehrtens 		memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
722b3ae52b6SHauke Mehrtens 		return 0;
723b3ae52b6SHauke Mehrtens 	} else {
72463893ea5SGregory Fong 		pr_err("unable to fill SPROM for given bustype\n");
725b3ae52b6SHauke Mehrtens 		return -EINVAL;
726b3ae52b6SHauke Mehrtens 	}
727b3ae52b6SHauke Mehrtens }
728c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_SSB_PCIHOST */
7295e3644a9SFlorian Fainelli 
7305e3644a9SFlorian Fainelli /*
7315e3644a9SFlorian Fainelli  * return board name for /proc/cpuinfo
7325e3644a9SFlorian Fainelli  */
7335e3644a9SFlorian Fainelli const char *board_get_name(void)
7345e3644a9SFlorian Fainelli {
7355e3644a9SFlorian Fainelli 	return board.name;
7365e3644a9SFlorian Fainelli }
7375e3644a9SFlorian Fainelli 
7385e3644a9SFlorian Fainelli /*
739e7300d04SMaxime Bizon  * early init callback, read nvram data from flash and checksum it
740e7300d04SMaxime Bizon  */
741e7300d04SMaxime Bizon void __init board_prom_init(void)
742e7300d04SMaxime Bizon {
743e7e333cbSJonas Gorski 	unsigned int i;
744e7e333cbSJonas Gorski 	u8 *boot_addr, *cfe;
745e7300d04SMaxime Bizon 	char cfe_version[32];
746d753601aSFlorian Fainelli 	char *board_name = NULL;
747e7300d04SMaxime Bizon 	u32 val;
748d753601aSFlorian Fainelli 	struct bcm_hcs *hcs;
749e7300d04SMaxime Bizon 
750e5766aeaSJonas Gorski 	/* read base address of boot chip select (0)
7512c8aaf71SJonas Gorski 	 * 6328/6362 do not have MPI but boot from a fixed address
752e5766aeaSJonas Gorski 	 */
7532c8aaf71SJonas Gorski 	if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) {
754e5766aeaSJonas Gorski 		val = 0x18000000;
7552c8aaf71SJonas Gorski 	} else {
756e7300d04SMaxime Bizon 		val = bcm_mpi_readl(MPI_CSBASE_REG(0));
757e7300d04SMaxime Bizon 		val &= MPI_CSBASE_BASE_MASK;
758e5766aeaSJonas Gorski 	}
759e7300d04SMaxime Bizon 	boot_addr = (u8 *)KSEG1ADDR(val);
760e7300d04SMaxime Bizon 
761e7300d04SMaxime Bizon 	/* dump cfe version */
762e7300d04SMaxime Bizon 	cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
763e27e1cc9SÁlvaro Fernández Rojas 	if (strstarts(cfe, "cfe-")) {
764e27e1cc9SÁlvaro Fernández Rojas 		if(cfe[4] == 'v') {
765e27e1cc9SÁlvaro Fernández Rojas 			if(cfe[5] == 'd')
766e27e1cc9SÁlvaro Fernández Rojas 				snprintf(cfe_version, 11, "%s",
767e27e1cc9SÁlvaro Fernández Rojas 					 (char *) &cfe[5]);
768e27e1cc9SÁlvaro Fernández Rojas 			else if (cfe[10] > 0)
769e27e1cc9SÁlvaro Fernández Rojas 				snprintf(cfe_version, sizeof(cfe_version),
770e27e1cc9SÁlvaro Fernández Rojas 					 "%u.%u.%u-%u.%u-%u", cfe[5], cfe[6],
771e27e1cc9SÁlvaro Fernández Rojas 					 cfe[7], cfe[8], cfe[9], cfe[10]);
772e7300d04SMaxime Bizon 			else
773e27e1cc9SÁlvaro Fernández Rojas 				snprintf(cfe_version, sizeof(cfe_version),
774e27e1cc9SÁlvaro Fernández Rojas 					 "%u.%u.%u-%u.%u", cfe[5], cfe[6],
775e27e1cc9SÁlvaro Fernández Rojas 					 cfe[7], cfe[8], cfe[9]);
776e27e1cc9SÁlvaro Fernández Rojas 		} else {
777e27e1cc9SÁlvaro Fernández Rojas 			snprintf(cfe_version, 12, "%s", (char *) &cfe[4]);
778e27e1cc9SÁlvaro Fernández Rojas 		}
779e27e1cc9SÁlvaro Fernández Rojas 	} else {
780e7300d04SMaxime Bizon 		strcpy(cfe_version, "unknown");
781e27e1cc9SÁlvaro Fernández Rojas 	}
78263893ea5SGregory Fong 	pr_info("CFE version: %s\n", cfe_version);
783e7300d04SMaxime Bizon 
78497367519SJonas Gorski 	bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET);
785e7300d04SMaxime Bizon 
786d753601aSFlorian Fainelli 	if (BCMCPU_IS_3368()) {
787d753601aSFlorian Fainelli 		hcs = (struct bcm_hcs *)boot_addr;
788d753601aSFlorian Fainelli 		board_name = hcs->filename;
789d753601aSFlorian Fainelli 	} else {
790e7e333cbSJonas Gorski 		board_name = bcm63xx_nvram_get_name();
791d753601aSFlorian Fainelli 	}
792e7300d04SMaxime Bizon 	/* find board by name */
793e7300d04SMaxime Bizon 	for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
794e7e333cbSJonas Gorski 		if (strncmp(board_name, bcm963xx_boards[i]->name, 16))
795e7300d04SMaxime Bizon 			continue;
796e7300d04SMaxime Bizon 		/* copy, board desc array is marked initdata */
797e7300d04SMaxime Bizon 		memcpy(&board, bcm963xx_boards[i], sizeof(board));
798e7300d04SMaxime Bizon 		break;
799e7300d04SMaxime Bizon 	}
800e7300d04SMaxime Bizon 
801e7300d04SMaxime Bizon 	/* bail out if board is not found, will complain later */
802e7300d04SMaxime Bizon 	if (!board.name[0]) {
803e7300d04SMaxime Bizon 		char name[17];
804e7e333cbSJonas Gorski 		memcpy(name, board_name, 16);
805e7300d04SMaxime Bizon 		name[16] = 0;
80663893ea5SGregory Fong 		pr_err("unknown bcm963xx board: %s\n", name);
807e7300d04SMaxime Bizon 		return;
808e7300d04SMaxime Bizon 	}
809e7300d04SMaxime Bizon 
810e7300d04SMaxime Bizon 	/* setup pin multiplexing depending on board enabled device,
811e7300d04SMaxime Bizon 	 * this has to be done this early since PCI init is done
812e7300d04SMaxime Bizon 	 * inside arch_initcall */
813e7300d04SMaxime Bizon 	val = 0;
814e7300d04SMaxime Bizon 
815e7300d04SMaxime Bizon #ifdef CONFIG_PCI
816e7300d04SMaxime Bizon 	if (board.has_pci) {
817e7300d04SMaxime Bizon 		bcm63xx_pci_enabled = 1;
818e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
819e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G2_PCI;
820e7300d04SMaxime Bizon 	}
821c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_PCI */
822e7300d04SMaxime Bizon 
823e7300d04SMaxime Bizon 	if (board.has_pccard) {
824e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
825e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G1_MII_PCCARD;
826e7300d04SMaxime Bizon 	}
827e7300d04SMaxime Bizon 
828e7300d04SMaxime Bizon 	if (board.has_enet0 && !board.enet0.use_internal_phy) {
829e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
830e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G3_EXT_MII |
831e7300d04SMaxime Bizon 				GPIO_MODE_6348_G0_EXT_MII;
832e7300d04SMaxime Bizon 	}
833e7300d04SMaxime Bizon 
834e7300d04SMaxime Bizon 	if (board.has_enet1 && !board.enet1.use_internal_phy) {
835e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
836e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G3_EXT_MII |
837e7300d04SMaxime Bizon 				GPIO_MODE_6348_G0_EXT_MII;
838e7300d04SMaxime Bizon 	}
839e7300d04SMaxime Bizon 
840e7300d04SMaxime Bizon 	bcm_gpio_writel(val, GPIO_MODE_REG);
841e7300d04SMaxime Bizon }
842e7300d04SMaxime Bizon 
843e7300d04SMaxime Bizon /*
844e7300d04SMaxime Bizon  * second stage init callback, good time to panic if we couldn't
845e7300d04SMaxime Bizon  * identify on which board we're running since early printk is working
846e7300d04SMaxime Bizon  */
847e7300d04SMaxime Bizon void __init board_setup(void)
848e7300d04SMaxime Bizon {
849e7300d04SMaxime Bizon 	if (!board.name[0])
850e7300d04SMaxime Bizon 		panic("unable to detect bcm963xx board");
85163893ea5SGregory Fong 	pr_info("board name: %s\n", board.name);
852e7300d04SMaxime Bizon 
853e7300d04SMaxime Bizon 	/* make sure we're running on expected cpu */
854e7300d04SMaxime Bizon 	if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
855e7300d04SMaxime Bizon 		panic("unexpected CPU for bcm963xx board");
856e7300d04SMaxime Bizon }
857e7300d04SMaxime Bizon 
858e7300d04SMaxime Bizon static struct gpio_led_platform_data bcm63xx_led_data;
859e7300d04SMaxime Bizon 
860e7300d04SMaxime Bizon static struct platform_device bcm63xx_gpio_leds = {
861e7300d04SMaxime Bizon 	.name			= "leds-gpio",
862e7300d04SMaxime Bizon 	.id			= 0,
863e7300d04SMaxime Bizon 	.dev.platform_data	= &bcm63xx_led_data,
864e7300d04SMaxime Bizon };
865e7300d04SMaxime Bizon 
866e7300d04SMaxime Bizon /*
867e7300d04SMaxime Bizon  * third stage init callback, register all board devices.
868e7300d04SMaxime Bizon  */
869e7300d04SMaxime Bizon int __init board_register_devices(void)
870e7300d04SMaxime Bizon {
871524ef29cSMaxime Bizon 	if (board.has_uart0)
872524ef29cSMaxime Bizon 		bcm63xx_uart_register(0);
873524ef29cSMaxime Bizon 
874524ef29cSMaxime Bizon 	if (board.has_uart1)
875524ef29cSMaxime Bizon 		bcm63xx_uart_register(1);
876524ef29cSMaxime Bizon 
877553d6d5fSMaxime Bizon 	if (board.has_pccard)
878553d6d5fSMaxime Bizon 		bcm63xx_pcmcia_register();
879553d6d5fSMaxime Bizon 
880e7300d04SMaxime Bizon 	if (board.has_enet0 &&
881e7e333cbSJonas Gorski 	    !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr))
882e7300d04SMaxime Bizon 		bcm63xx_enet_register(0, &board.enet0);
883e7300d04SMaxime Bizon 
884e7300d04SMaxime Bizon 	if (board.has_enet1 &&
885e7e333cbSJonas Gorski 	    !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr))
886e7300d04SMaxime Bizon 		bcm63xx_enet_register(1, &board.enet1);
887e7300d04SMaxime Bizon 
8886f00a022SMaxime Bizon 	if (board.has_enetsw &&
8896f00a022SMaxime Bizon 	    !bcm63xx_nvram_get_mac_address(board.enetsw.mac_addr))
8906f00a022SMaxime Bizon 		bcm63xx_enetsw_register(&board.enetsw);
8916f00a022SMaxime Bizon 
89222df90f6SKevin Cernekee 	if (board.has_usbd)
89322df90f6SKevin Cernekee 		bcm63xx_usbd_register(&board.usbd);
89422df90f6SKevin Cernekee 
895b15a6d62SFlorian Fainelli 	/* Generate MAC address for WLAN and register our SPROM,
896b15a6d62SFlorian Fainelli 	 * do this after registering enet devices
897b15a6d62SFlorian Fainelli 	 */
898b15a6d62SFlorian Fainelli #ifdef CONFIG_SSB_PCIHOST
899e7e333cbSJonas Gorski 	if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) {
900b15a6d62SFlorian Fainelli 		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
901b15a6d62SFlorian Fainelli 		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
902b15a6d62SFlorian Fainelli 		if (ssb_arch_register_fallback_sprom(
903b15a6d62SFlorian Fainelli 				&bcm63xx_get_fallback_sprom) < 0)
90463893ea5SGregory Fong 			pr_err("failed to register fallback SPROM\n");
905b15a6d62SFlorian Fainelli 	}
906c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_SSB_PCIHOST */
907b15a6d62SFlorian Fainelli 
90876ca4e14SFlorian Fainelli 	bcm63xx_spi_register();
90976ca4e14SFlorian Fainelli 
91083bb90faSJonas Gorski 	bcm63xx_hsspi_register();
91183bb90faSJonas Gorski 
9124b897d54SJonas Gorski 	bcm63xx_flash_register();
913e7300d04SMaxime Bizon 
914e7300d04SMaxime Bizon 	bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
915e7300d04SMaxime Bizon 	bcm63xx_led_data.leds = board.leds;
916e7300d04SMaxime Bizon 
917e7300d04SMaxime Bizon 	platform_device_register(&bcm63xx_gpio_leds);
918e7300d04SMaxime Bizon 
9190b35f0c5SFlorian Fainelli 	if (board.ephy_reset_gpio && board.ephy_reset_gpio_flags)
9200b35f0c5SFlorian Fainelli 		gpio_request_one(board.ephy_reset_gpio,
9210b35f0c5SFlorian Fainelli 				board.ephy_reset_gpio_flags, "ephy-reset");
9220b35f0c5SFlorian Fainelli 
923e7300d04SMaxime Bizon 	return 0;
924e7300d04SMaxime Bizon }
925