108b5666dSÁlvaro Fernández Rojas // SPDX-License-Identifier: GPL-2.0-only
2e7300d04SMaxime Bizon /*
3e7300d04SMaxime Bizon  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
4e7300d04SMaxime Bizon  * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
5e7300d04SMaxime Bizon  */
6e7300d04SMaxime Bizon 
763893ea5SGregory Fong #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
863893ea5SGregory Fong 
9e7300d04SMaxime Bizon #include <linux/init.h>
10e7300d04SMaxime Bizon #include <linux/kernel.h>
11e7300d04SMaxime Bizon #include <linux/string.h>
12e7300d04SMaxime Bizon #include <linux/platform_device.h>
13e7300d04SMaxime Bizon #include <linux/ssb/ssb.h>
14e7300d04SMaxime Bizon #include <asm/addrspace.h>
15e7300d04SMaxime Bizon #include <bcm63xx_board.h>
16e7300d04SMaxime Bizon #include <bcm63xx_cpu.h>
17524ef29cSMaxime Bizon #include <bcm63xx_dev_uart.h>
18e7300d04SMaxime Bizon #include <bcm63xx_regs.h>
19e7300d04SMaxime Bizon #include <bcm63xx_io.h>
20e7e333cbSJonas Gorski #include <bcm63xx_nvram.h>
21e7300d04SMaxime Bizon #include <bcm63xx_dev_pci.h>
22e7300d04SMaxime Bizon #include <bcm63xx_dev_enet.h>
234b897d54SJonas Gorski #include <bcm63xx_dev_flash.h>
2483bb90faSJonas Gorski #include <bcm63xx_dev_hsspi.h>
25553d6d5fSMaxime Bizon #include <bcm63xx_dev_pcmcia.h>
2676ca4e14SFlorian Fainelli #include <bcm63xx_dev_spi.h>
2722df90f6SKevin Cernekee #include <bcm63xx_dev_usb_usbd.h>
28e7300d04SMaxime Bizon #include <board_bcm963xx.h>
29e7300d04SMaxime Bizon 
30d753601aSFlorian Fainelli #include <uapi/linux/bcm933xx_hcs.h>
31d753601aSFlorian Fainelli 
32d753601aSFlorian Fainelli #define HCS_OFFSET_128K			0x20000
33d753601aSFlorian Fainelli 
34e7300d04SMaxime Bizon static struct board_info board;
35e7300d04SMaxime Bizon 
36e7300d04SMaxime Bizon /*
37450acb0bSFlorian Fainelli  * known 3368 boards
38450acb0bSFlorian Fainelli  */
39450acb0bSFlorian Fainelli #ifdef CONFIG_BCM63XX_CPU_3368
40450acb0bSFlorian Fainelli static struct board_info __initdata board_cvg834g = {
41450acb0bSFlorian Fainelli 	.name = "CVG834G_E15R3921",
42450acb0bSFlorian Fainelli 	.expected_cpu_id = 0x3368,
43450acb0bSFlorian Fainelli 
44a5fb3b45SÁlvaro Fernández Rojas 	.ephy_reset_gpio = 36,
45a5fb3b45SÁlvaro Fernández Rojas 	.ephy_reset_gpio_flags = GPIOF_INIT_HIGH,
46a5fb3b45SÁlvaro Fernández Rojas 	.has_pci = 1,
47450acb0bSFlorian Fainelli 	.has_uart0 = 1,
48450acb0bSFlorian Fainelli 	.has_uart1 = 1,
49450acb0bSFlorian Fainelli 
50450acb0bSFlorian Fainelli 	.has_enet0 = 1,
51450acb0bSFlorian Fainelli 	.enet0 = {
52450acb0bSFlorian Fainelli 		.has_phy = 1,
53450acb0bSFlorian Fainelli 		.use_internal_phy = 1,
54450acb0bSFlorian Fainelli 	},
55450acb0bSFlorian Fainelli 
56450acb0bSFlorian Fainelli 	.leds = {
57450acb0bSFlorian Fainelli 		{
58450acb0bSFlorian Fainelli 			.name = "CVG834G:green:power",
59450acb0bSFlorian Fainelli 			.gpio = 37,
60450acb0bSFlorian Fainelli 			.default_trigger= "default-on",
61450acb0bSFlorian Fainelli 		},
62450acb0bSFlorian Fainelli 	},
63450acb0bSFlorian Fainelli };
64c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_3368 */
65450acb0bSFlorian Fainelli 
66450acb0bSFlorian Fainelli /*
672f74b770SJonas Gorski  * known 6328 boards
682f74b770SJonas Gorski  */
692f74b770SJonas Gorski #ifdef CONFIG_BCM63XX_CPU_6328
702f74b770SJonas Gorski static struct board_info __initdata board_96328avng = {
712f74b770SJonas Gorski 	.name = "96328avng",
722f74b770SJonas Gorski 	.expected_cpu_id = 0x6328,
732f74b770SJonas Gorski 
742f74b770SJonas Gorski 	.has_pci = 1,
75a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
7622df90f6SKevin Cernekee 
77a5fb3b45SÁlvaro Fernández Rojas 	.has_usbd = 0,
7822df90f6SKevin Cernekee 	.usbd = {
7922df90f6SKevin Cernekee 		.use_fullspeed = 0,
8022df90f6SKevin Cernekee 		.port_no = 0,
8122df90f6SKevin Cernekee 	},
822f74b770SJonas Gorski 
832f74b770SJonas Gorski 	.leds = {
842f74b770SJonas Gorski 		{
852f74b770SJonas Gorski 			.name = "96328avng::ppp-fail",
862f74b770SJonas Gorski 			.gpio = 2,
872f74b770SJonas Gorski 			.active_low = 1,
882f74b770SJonas Gorski 		},
892f74b770SJonas Gorski 		{
902f74b770SJonas Gorski 			.name = "96328avng::power",
912f74b770SJonas Gorski 			.gpio = 4,
922f74b770SJonas Gorski 			.active_low = 1,
932f74b770SJonas Gorski 			.default_trigger = "default-on",
942f74b770SJonas Gorski 		},
952f74b770SJonas Gorski 		{
962f74b770SJonas Gorski 			.name = "96328avng::power-fail",
972f74b770SJonas Gorski 			.gpio = 8,
982f74b770SJonas Gorski 			.active_low = 1,
992f74b770SJonas Gorski 		},
1002f74b770SJonas Gorski 		{
1012f74b770SJonas Gorski 			.name = "96328avng::wps",
1022f74b770SJonas Gorski 			.gpio = 9,
1032f74b770SJonas Gorski 			.active_low = 1,
1042f74b770SJonas Gorski 		},
1052f74b770SJonas Gorski 		{
1062f74b770SJonas Gorski 			.name = "96328avng::ppp",
1072f74b770SJonas Gorski 			.gpio = 11,
1082f74b770SJonas Gorski 			.active_low = 1,
1092f74b770SJonas Gorski 		},
1102f74b770SJonas Gorski 	},
1112f74b770SJonas Gorski };
112c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6328 */
1132f74b770SJonas Gorski 
1142f74b770SJonas Gorski /*
115e7300d04SMaxime Bizon  * known 6338 boards
116e7300d04SMaxime Bizon  */
117e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6338
118e7300d04SMaxime Bizon static struct board_info __initdata board_96338gw = {
119e7300d04SMaxime Bizon 	.name = "96338GW",
120e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6338,
121e7300d04SMaxime Bizon 
122a5fb3b45SÁlvaro Fernández Rojas 	.has_ohci0 = 1,
123524ef29cSMaxime Bizon 	.has_uart0 = 1,
124a5fb3b45SÁlvaro Fernández Rojas 
125e7300d04SMaxime Bizon 	.has_enet0 = 1,
126e7300d04SMaxime Bizon 	.enet0 = {
127e7300d04SMaxime Bizon 		.force_speed_100 = 1,
128e7300d04SMaxime Bizon 		.force_duplex_full = 1,
129e7300d04SMaxime Bizon 	},
130e7300d04SMaxime Bizon 
131e7300d04SMaxime Bizon 	.leds = {
132e7300d04SMaxime Bizon 		{
133e7300d04SMaxime Bizon 			.name = "adsl",
134e7300d04SMaxime Bizon 			.gpio = 3,
135e7300d04SMaxime Bizon 			.active_low = 1,
136e7300d04SMaxime Bizon 		},
137e7300d04SMaxime Bizon 		{
138e7300d04SMaxime Bizon 			.name = "ses",
139e7300d04SMaxime Bizon 			.gpio = 5,
140e7300d04SMaxime Bizon 			.active_low = 1,
141e7300d04SMaxime Bizon 		},
142e7300d04SMaxime Bizon 		{
143e7300d04SMaxime Bizon 			.name = "ppp-fail",
144e7300d04SMaxime Bizon 			.gpio = 4,
145e7300d04SMaxime Bizon 			.active_low = 1,
146e7300d04SMaxime Bizon 		},
147e7300d04SMaxime Bizon 		{
148e7300d04SMaxime Bizon 			.name = "power",
149e7300d04SMaxime Bizon 			.gpio = 0,
150e7300d04SMaxime Bizon 			.active_low = 1,
151e7300d04SMaxime Bizon 			.default_trigger = "default-on",
152e7300d04SMaxime Bizon 		},
153e7300d04SMaxime Bizon 		{
154e7300d04SMaxime Bizon 			.name = "stop",
155e7300d04SMaxime Bizon 			.gpio = 1,
156e7300d04SMaxime Bizon 			.active_low = 1,
157e7300d04SMaxime Bizon 		}
158e7300d04SMaxime Bizon 	},
159e7300d04SMaxime Bizon };
160e7300d04SMaxime Bizon 
161e7300d04SMaxime Bizon static struct board_info __initdata board_96338w = {
162e7300d04SMaxime Bizon 	.name = "96338W",
163e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6338,
164e7300d04SMaxime Bizon 
165524ef29cSMaxime Bizon 	.has_uart0 = 1,
166a5fb3b45SÁlvaro Fernández Rojas 
167e7300d04SMaxime Bizon 	.has_enet0 = 1,
168e7300d04SMaxime Bizon 	.enet0 = {
169e7300d04SMaxime Bizon 		.force_speed_100 = 1,
170e7300d04SMaxime Bizon 		.force_duplex_full = 1,
171e7300d04SMaxime Bizon 	},
172e7300d04SMaxime Bizon 
173e7300d04SMaxime Bizon 	.leds = {
174e7300d04SMaxime Bizon 		{
175e7300d04SMaxime Bizon 			.name = "adsl",
176e7300d04SMaxime Bizon 			.gpio = 3,
177e7300d04SMaxime Bizon 			.active_low = 1,
178e7300d04SMaxime Bizon 		},
179e7300d04SMaxime Bizon 		{
180e7300d04SMaxime Bizon 			.name = "ses",
181e7300d04SMaxime Bizon 			.gpio = 5,
182e7300d04SMaxime Bizon 			.active_low = 1,
183e7300d04SMaxime Bizon 		},
184e7300d04SMaxime Bizon 		{
185e7300d04SMaxime Bizon 			.name = "ppp-fail",
186e7300d04SMaxime Bizon 			.gpio = 4,
187e7300d04SMaxime Bizon 			.active_low = 1,
188e7300d04SMaxime Bizon 		},
189e7300d04SMaxime Bizon 		{
190e7300d04SMaxime Bizon 			.name = "power",
191e7300d04SMaxime Bizon 			.gpio = 0,
192e7300d04SMaxime Bizon 			.active_low = 1,
193e7300d04SMaxime Bizon 			.default_trigger = "default-on",
194e7300d04SMaxime Bizon 		},
195e7300d04SMaxime Bizon 		{
196e7300d04SMaxime Bizon 			.name = "stop",
197e7300d04SMaxime Bizon 			.gpio = 1,
198e7300d04SMaxime Bizon 			.active_low = 1,
199e7300d04SMaxime Bizon 		},
200e7300d04SMaxime Bizon 	},
201e7300d04SMaxime Bizon };
202c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6338 */
203e7300d04SMaxime Bizon 
204e7300d04SMaxime Bizon /*
205e7300d04SMaxime Bizon  * known 6345 boards
206e7300d04SMaxime Bizon  */
207e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6345
208e7300d04SMaxime Bizon static struct board_info __initdata board_96345gw2 = {
209e7300d04SMaxime Bizon 	.name = "96345GW2",
210e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6345,
211524ef29cSMaxime Bizon 
212524ef29cSMaxime Bizon 	.has_uart0 = 1,
213e7300d04SMaxime Bizon };
214c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6345 */
215e7300d04SMaxime Bizon 
216e7300d04SMaxime Bizon /*
217e7300d04SMaxime Bizon  * known 6348 boards
218e7300d04SMaxime Bizon  */
219e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6348
220e7300d04SMaxime Bizon static struct board_info __initdata board_96348r = {
221e7300d04SMaxime Bizon 	.name = "96348R",
222e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6348,
223e7300d04SMaxime Bizon 
224e7300d04SMaxime Bizon 	.has_pci = 1,
225a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
226e7300d04SMaxime Bizon 
227a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
228e7300d04SMaxime Bizon 	.enet0 = {
229e7300d04SMaxime Bizon 		.has_phy = 1,
230e7300d04SMaxime Bizon 		.use_internal_phy = 1,
231e7300d04SMaxime Bizon 	},
232e7300d04SMaxime Bizon 
233e7300d04SMaxime Bizon 	.leds = {
234e7300d04SMaxime Bizon 		{
235e7300d04SMaxime Bizon 			.name = "adsl-fail",
236e7300d04SMaxime Bizon 			.gpio = 2,
237e7300d04SMaxime Bizon 			.active_low = 1,
238e7300d04SMaxime Bizon 		},
239e7300d04SMaxime Bizon 		{
240e7300d04SMaxime Bizon 			.name = "ppp",
241e7300d04SMaxime Bizon 			.gpio = 3,
242e7300d04SMaxime Bizon 			.active_low = 1,
243e7300d04SMaxime Bizon 		},
244e7300d04SMaxime Bizon 		{
245e7300d04SMaxime Bizon 			.name = "ppp-fail",
246e7300d04SMaxime Bizon 			.gpio = 4,
247e7300d04SMaxime Bizon 			.active_low = 1,
248e7300d04SMaxime Bizon 		},
249e7300d04SMaxime Bizon 		{
250e7300d04SMaxime Bizon 			.name = "power",
251e7300d04SMaxime Bizon 			.gpio = 0,
252e7300d04SMaxime Bizon 			.active_low = 1,
253e7300d04SMaxime Bizon 			.default_trigger = "default-on",
254e7300d04SMaxime Bizon 
255e7300d04SMaxime Bizon 		},
256e7300d04SMaxime Bizon 		{
257e7300d04SMaxime Bizon 			.name = "stop",
258e7300d04SMaxime Bizon 			.gpio = 1,
259e7300d04SMaxime Bizon 			.active_low = 1,
260e7300d04SMaxime Bizon 		},
261e7300d04SMaxime Bizon 	},
262e7300d04SMaxime Bizon };
263e7300d04SMaxime Bizon 
264e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_10 = {
265e7300d04SMaxime Bizon 	.name = "96348GW-10",
266e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6348,
267e7300d04SMaxime Bizon 
268a5fb3b45SÁlvaro Fernández Rojas 	.has_ohci0 = 1,
269a5fb3b45SÁlvaro Fernández Rojas 	.has_pccard = 1,
270e7300d04SMaxime Bizon 	.has_pci = 1,
271a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
272e7300d04SMaxime Bizon 
273a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
274e7300d04SMaxime Bizon 	.enet0 = {
275e7300d04SMaxime Bizon 		.has_phy = 1,
276e7300d04SMaxime Bizon 		.use_internal_phy = 1,
277e7300d04SMaxime Bizon 	},
278a5fb3b45SÁlvaro Fernández Rojas 
279a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
280e7300d04SMaxime Bizon 	.enet1 = {
281e7300d04SMaxime Bizon 		.force_speed_100 = 1,
282e7300d04SMaxime Bizon 		.force_duplex_full = 1,
283e7300d04SMaxime Bizon 	},
284e7300d04SMaxime Bizon 
285e7300d04SMaxime Bizon 	.leds = {
286e7300d04SMaxime Bizon 		{
287e7300d04SMaxime Bizon 			.name = "adsl-fail",
288e7300d04SMaxime Bizon 			.gpio = 2,
289e7300d04SMaxime Bizon 			.active_low = 1,
290e7300d04SMaxime Bizon 		},
291e7300d04SMaxime Bizon 		{
292e7300d04SMaxime Bizon 			.name = "ppp",
293e7300d04SMaxime Bizon 			.gpio = 3,
294e7300d04SMaxime Bizon 			.active_low = 1,
295e7300d04SMaxime Bizon 		},
296e7300d04SMaxime Bizon 		{
297e7300d04SMaxime Bizon 			.name = "ppp-fail",
298e7300d04SMaxime Bizon 			.gpio = 4,
299e7300d04SMaxime Bizon 			.active_low = 1,
300e7300d04SMaxime Bizon 		},
301e7300d04SMaxime Bizon 		{
302e7300d04SMaxime Bizon 			.name = "power",
303e7300d04SMaxime Bizon 			.gpio = 0,
304e7300d04SMaxime Bizon 			.active_low = 1,
305e7300d04SMaxime Bizon 			.default_trigger = "default-on",
306e7300d04SMaxime Bizon 		},
307e7300d04SMaxime Bizon 		{
308e7300d04SMaxime Bizon 			.name = "stop",
309e7300d04SMaxime Bizon 			.gpio = 1,
310e7300d04SMaxime Bizon 			.active_low = 1,
311e7300d04SMaxime Bizon 		},
312e7300d04SMaxime Bizon 	},
313e7300d04SMaxime Bizon };
314e7300d04SMaxime Bizon 
315e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_11 = {
316e7300d04SMaxime Bizon 	.name = "96348GW-11",
317e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6348,
318e7300d04SMaxime Bizon 
319a5fb3b45SÁlvaro Fernández Rojas 	.has_ohci0 = 1,
320a5fb3b45SÁlvaro Fernández Rojas 	.has_pccard = 1,
321e7300d04SMaxime Bizon 	.has_pci = 1,
322a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
323e7300d04SMaxime Bizon 
324a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
325e7300d04SMaxime Bizon 	.enet0 = {
326e7300d04SMaxime Bizon 		.has_phy = 1,
327e7300d04SMaxime Bizon 		.use_internal_phy = 1,
328e7300d04SMaxime Bizon 	},
329e7300d04SMaxime Bizon 
330a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
331e7300d04SMaxime Bizon 	.enet1 = {
332e7300d04SMaxime Bizon 		.force_speed_100 = 1,
333e7300d04SMaxime Bizon 		.force_duplex_full = 1,
334e7300d04SMaxime Bizon 	},
335e7300d04SMaxime Bizon 
336e7300d04SMaxime Bizon 	.leds = {
337e7300d04SMaxime Bizon 		{
338e7300d04SMaxime Bizon 			.name = "adsl-fail",
339e7300d04SMaxime Bizon 			.gpio = 2,
340e7300d04SMaxime Bizon 			.active_low = 1,
341e7300d04SMaxime Bizon 		},
342e7300d04SMaxime Bizon 		{
343e7300d04SMaxime Bizon 			.name = "ppp",
344e7300d04SMaxime Bizon 			.gpio = 3,
345e7300d04SMaxime Bizon 			.active_low = 1,
346e7300d04SMaxime Bizon 		},
347e7300d04SMaxime Bizon 		{
348e7300d04SMaxime Bizon 			.name = "ppp-fail",
349e7300d04SMaxime Bizon 			.gpio = 4,
350e7300d04SMaxime Bizon 			.active_low = 1,
351e7300d04SMaxime Bizon 		},
352e7300d04SMaxime Bizon 		{
353e7300d04SMaxime Bizon 			.name = "power",
354e7300d04SMaxime Bizon 			.gpio = 0,
355e7300d04SMaxime Bizon 			.active_low = 1,
356e7300d04SMaxime Bizon 			.default_trigger = "default-on",
357e7300d04SMaxime Bizon 		},
358e7300d04SMaxime Bizon 		{
359e7300d04SMaxime Bizon 			.name = "stop",
360e7300d04SMaxime Bizon 			.gpio = 1,
361e7300d04SMaxime Bizon 			.active_low = 1,
362e7300d04SMaxime Bizon 		},
363e7300d04SMaxime Bizon 	},
364e7300d04SMaxime Bizon };
365e7300d04SMaxime Bizon 
366e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw = {
367e7300d04SMaxime Bizon 	.name = "96348GW",
368e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6348,
369e7300d04SMaxime Bizon 
370a5fb3b45SÁlvaro Fernández Rojas 	.has_ohci0 = 1,
371e7300d04SMaxime Bizon 	.has_pci = 1,
372a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
373e7300d04SMaxime Bizon 
374a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
375e7300d04SMaxime Bizon 	.enet0 = {
376e7300d04SMaxime Bizon 		.has_phy = 1,
377e7300d04SMaxime Bizon 		.use_internal_phy = 1,
378e7300d04SMaxime Bizon 	},
379a5fb3b45SÁlvaro Fernández Rojas 
380a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
381e7300d04SMaxime Bizon 	.enet1 = {
382e7300d04SMaxime Bizon 		.force_speed_100 = 1,
383e7300d04SMaxime Bizon 		.force_duplex_full = 1,
384e7300d04SMaxime Bizon 	},
385e7300d04SMaxime Bizon 
386e7300d04SMaxime Bizon 	.leds = {
387e7300d04SMaxime Bizon 		{
388e7300d04SMaxime Bizon 			.name = "adsl-fail",
389e7300d04SMaxime Bizon 			.gpio = 2,
390e7300d04SMaxime Bizon 			.active_low = 1,
391e7300d04SMaxime Bizon 		},
392e7300d04SMaxime Bizon 		{
393e7300d04SMaxime Bizon 			.name = "ppp",
394e7300d04SMaxime Bizon 			.gpio = 3,
395e7300d04SMaxime Bizon 			.active_low = 1,
396e7300d04SMaxime Bizon 		},
397e7300d04SMaxime Bizon 		{
398e7300d04SMaxime Bizon 			.name = "ppp-fail",
399e7300d04SMaxime Bizon 			.gpio = 4,
400e7300d04SMaxime Bizon 			.active_low = 1,
401e7300d04SMaxime Bizon 		},
402e7300d04SMaxime Bizon 		{
403e7300d04SMaxime Bizon 			.name = "power",
404e7300d04SMaxime Bizon 			.gpio = 0,
405e7300d04SMaxime Bizon 			.active_low = 1,
406e7300d04SMaxime Bizon 			.default_trigger = "default-on",
407e7300d04SMaxime Bizon 		},
408e7300d04SMaxime Bizon 		{
409e7300d04SMaxime Bizon 			.name = "stop",
410e7300d04SMaxime Bizon 			.gpio = 1,
411e7300d04SMaxime Bizon 			.active_low = 1,
412e7300d04SMaxime Bizon 		},
413e7300d04SMaxime Bizon 	},
414e7300d04SMaxime Bizon };
415e7300d04SMaxime Bizon 
416e7300d04SMaxime Bizon static struct board_info __initdata board_FAST2404 = {
417e7300d04SMaxime Bizon 	.name = "F@ST2404",
418e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6348,
419e7300d04SMaxime Bizon 
420a5fb3b45SÁlvaro Fernández Rojas 	.has_ohci0 = 1,
421a5fb3b45SÁlvaro Fernández Rojas 	.has_pccard = 1,
422e7300d04SMaxime Bizon 	.has_pci = 1,
423a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
424e7300d04SMaxime Bizon 
425a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
426e7300d04SMaxime Bizon 	.enet0 = {
427e7300d04SMaxime Bizon 		.has_phy = 1,
428e7300d04SMaxime Bizon 		.use_internal_phy = 1,
429e7300d04SMaxime Bizon 	},
430e7300d04SMaxime Bizon 
431a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
432e7300d04SMaxime Bizon 	.enet1 = {
433e7300d04SMaxime Bizon 		.force_speed_100 = 1,
434e7300d04SMaxime Bizon 		.force_duplex_full = 1,
435e7300d04SMaxime Bizon 	},
436e7300d04SMaxime Bizon };
437e7300d04SMaxime Bizon 
4382e6ad9a9SFlorian Fainelli static struct board_info __initdata board_rta1025w_16 = {
4392e6ad9a9SFlorian Fainelli 	.name = "RTA1025W_16",
4402e6ad9a9SFlorian Fainelli 	.expected_cpu_id = 0x6348,
4412e6ad9a9SFlorian Fainelli 
4422e6ad9a9SFlorian Fainelli 	.has_pci = 1,
4432e6ad9a9SFlorian Fainelli 
444a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
4452e6ad9a9SFlorian Fainelli 	.enet0 = {
4462e6ad9a9SFlorian Fainelli 		.has_phy = 1,
4472e6ad9a9SFlorian Fainelli 		.use_internal_phy = 1,
4482e6ad9a9SFlorian Fainelli 	},
449a5fb3b45SÁlvaro Fernández Rojas 
450a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
4512e6ad9a9SFlorian Fainelli 	.enet1 = {
4522e6ad9a9SFlorian Fainelli 		.force_speed_100 = 1,
4532e6ad9a9SFlorian Fainelli 		.force_duplex_full = 1,
4542e6ad9a9SFlorian Fainelli 	},
4552e6ad9a9SFlorian Fainelli };
4562e6ad9a9SFlorian Fainelli 
457e7300d04SMaxime Bizon static struct board_info __initdata board_DV201AMR = {
458e7300d04SMaxime Bizon 	.name = "DV201AMR",
459e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6348,
460e7300d04SMaxime Bizon 
461e7300d04SMaxime Bizon 	.has_ohci0 = 1,
462a5fb3b45SÁlvaro Fernández Rojas 	.has_pci = 1,
463a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
464e7300d04SMaxime Bizon 
465e7300d04SMaxime Bizon 	.has_enet0 = 1,
466e7300d04SMaxime Bizon 	.enet0 = {
467e7300d04SMaxime Bizon 		.has_phy = 1,
468e7300d04SMaxime Bizon 		.use_internal_phy = 1,
469e7300d04SMaxime Bizon 	},
470a5fb3b45SÁlvaro Fernández Rojas 
471a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
472e7300d04SMaxime Bizon 	.enet1 = {
473e7300d04SMaxime Bizon 		.force_speed_100 = 1,
474e7300d04SMaxime Bizon 		.force_duplex_full = 1,
475e7300d04SMaxime Bizon 	},
476e7300d04SMaxime Bizon };
477e7300d04SMaxime Bizon 
478e7300d04SMaxime Bizon static struct board_info __initdata board_96348gw_a = {
479e7300d04SMaxime Bizon 	.name = "96348GW-A",
480e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6348,
481e7300d04SMaxime Bizon 
482a5fb3b45SÁlvaro Fernández Rojas 	.has_ohci0 = 1,
483e7300d04SMaxime Bizon 	.has_pci = 1,
484a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
485e7300d04SMaxime Bizon 
486a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
487e7300d04SMaxime Bizon 	.enet0 = {
488e7300d04SMaxime Bizon 		.has_phy = 1,
489e7300d04SMaxime Bizon 		.use_internal_phy = 1,
490e7300d04SMaxime Bizon 	},
491a5fb3b45SÁlvaro Fernández Rojas 
492a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
493e7300d04SMaxime Bizon 	.enet1 = {
494e7300d04SMaxime Bizon 		.force_speed_100 = 1,
495e7300d04SMaxime Bizon 		.force_duplex_full = 1,
496e7300d04SMaxime Bizon 	},
497e7300d04SMaxime Bizon };
498c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6348 */
499e7300d04SMaxime Bizon 
500e7300d04SMaxime Bizon /*
501e7300d04SMaxime Bizon  * known 6358 boards
502e7300d04SMaxime Bizon  */
503e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6358
504e7300d04SMaxime Bizon static struct board_info __initdata board_96358vw = {
505e7300d04SMaxime Bizon 	.name = "96358VW",
506e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6358,
507e7300d04SMaxime Bizon 
508a5fb3b45SÁlvaro Fernández Rojas 	.has_ehci0 = 1,
509a5fb3b45SÁlvaro Fernández Rojas 	.has_ohci0 = 1,
510a5fb3b45SÁlvaro Fernández Rojas 	.has_pccard = 1,
511e7300d04SMaxime Bizon 	.has_pci = 1,
512a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
513e7300d04SMaxime Bizon 
514a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
515e7300d04SMaxime Bizon 	.enet0 = {
516e7300d04SMaxime Bizon 		.has_phy = 1,
517e7300d04SMaxime Bizon 		.use_internal_phy = 1,
518e7300d04SMaxime Bizon 	},
519e7300d04SMaxime Bizon 
520a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
521e7300d04SMaxime Bizon 	.enet1 = {
522e7300d04SMaxime Bizon 		.force_speed_100 = 1,
523e7300d04SMaxime Bizon 		.force_duplex_full = 1,
524e7300d04SMaxime Bizon 	},
525e7300d04SMaxime Bizon 
526e7300d04SMaxime Bizon 	.leds = {
527e7300d04SMaxime Bizon 		{
528e7300d04SMaxime Bizon 			.name = "adsl-fail",
529e7300d04SMaxime Bizon 			.gpio = 15,
530e7300d04SMaxime Bizon 			.active_low = 1,
531e7300d04SMaxime Bizon 		},
532e7300d04SMaxime Bizon 		{
533e7300d04SMaxime Bizon 			.name = "ppp",
534e7300d04SMaxime Bizon 			.gpio = 22,
535e7300d04SMaxime Bizon 			.active_low = 1,
536e7300d04SMaxime Bizon 		},
537e7300d04SMaxime Bizon 		{
538e7300d04SMaxime Bizon 			.name = "ppp-fail",
539e7300d04SMaxime Bizon 			.gpio = 23,
540e7300d04SMaxime Bizon 			.active_low = 1,
541e7300d04SMaxime Bizon 		},
542e7300d04SMaxime Bizon 		{
543e7300d04SMaxime Bizon 			.name = "power",
544e7300d04SMaxime Bizon 			.gpio = 4,
545e7300d04SMaxime Bizon 			.default_trigger = "default-on",
546e7300d04SMaxime Bizon 		},
547e7300d04SMaxime Bizon 		{
548e7300d04SMaxime Bizon 			.name = "stop",
549e7300d04SMaxime Bizon 			.gpio = 5,
550e7300d04SMaxime Bizon 		},
551e7300d04SMaxime Bizon 	},
552e7300d04SMaxime Bizon };
553e7300d04SMaxime Bizon 
554e7300d04SMaxime Bizon static struct board_info __initdata board_96358vw2 = {
555e7300d04SMaxime Bizon 	.name = "96358VW2",
556e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6358,
557e7300d04SMaxime Bizon 
558a5fb3b45SÁlvaro Fernández Rojas 	.has_ehci0 = 1,
559a5fb3b45SÁlvaro Fernández Rojas 	.has_ohci0 = 1,
560a5fb3b45SÁlvaro Fernández Rojas 	.has_pccard = 1,
561e7300d04SMaxime Bizon 	.has_pci = 1,
562a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
563e7300d04SMaxime Bizon 
564a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
565e7300d04SMaxime Bizon 	.enet0 = {
566e7300d04SMaxime Bizon 		.has_phy = 1,
567e7300d04SMaxime Bizon 		.use_internal_phy = 1,
568e7300d04SMaxime Bizon 	},
569e7300d04SMaxime Bizon 
570a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
571e7300d04SMaxime Bizon 	.enet1 = {
572e7300d04SMaxime Bizon 		.force_speed_100 = 1,
573e7300d04SMaxime Bizon 		.force_duplex_full = 1,
574e7300d04SMaxime Bizon 	},
575e7300d04SMaxime Bizon 
576e7300d04SMaxime Bizon 	.leds = {
577e7300d04SMaxime Bizon 		{
578e7300d04SMaxime Bizon 			.name = "adsl",
579e7300d04SMaxime Bizon 			.gpio = 22,
580e7300d04SMaxime Bizon 			.active_low = 1,
581e7300d04SMaxime Bizon 		},
582e7300d04SMaxime Bizon 		{
583e7300d04SMaxime Bizon 			.name = "ppp-fail",
584e7300d04SMaxime Bizon 			.gpio = 23,
585e7300d04SMaxime Bizon 		},
586e7300d04SMaxime Bizon 		{
587e7300d04SMaxime Bizon 			.name = "power",
588e7300d04SMaxime Bizon 			.gpio = 5,
589e7300d04SMaxime Bizon 			.active_low = 1,
590e7300d04SMaxime Bizon 			.default_trigger = "default-on",
591e7300d04SMaxime Bizon 		},
592e7300d04SMaxime Bizon 		{
593e7300d04SMaxime Bizon 			.name = "stop",
594e7300d04SMaxime Bizon 			.gpio = 4,
595e7300d04SMaxime Bizon 			.active_low = 1,
596e7300d04SMaxime Bizon 		},
597e7300d04SMaxime Bizon 	},
598e7300d04SMaxime Bizon };
599e7300d04SMaxime Bizon 
600e7300d04SMaxime Bizon static struct board_info __initdata board_AGPFS0 = {
601e7300d04SMaxime Bizon 	.name = "AGPF-S0",
602e7300d04SMaxime Bizon 	.expected_cpu_id = 0x6358,
603e7300d04SMaxime Bizon 
604a5fb3b45SÁlvaro Fernández Rojas 	.has_ehci0 = 1,
605a5fb3b45SÁlvaro Fernández Rojas 	.has_ohci0 = 1,
606e7300d04SMaxime Bizon 	.has_pci = 1,
607a5fb3b45SÁlvaro Fernández Rojas 	.has_uart0 = 1,
608e7300d04SMaxime Bizon 
609a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
610e7300d04SMaxime Bizon 	.enet0 = {
611e7300d04SMaxime Bizon 		.has_phy = 1,
612e7300d04SMaxime Bizon 		.use_internal_phy = 1,
613e7300d04SMaxime Bizon 	},
614e7300d04SMaxime Bizon 
615a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
616e7300d04SMaxime Bizon 	.enet1 = {
617e7300d04SMaxime Bizon 		.force_speed_100 = 1,
618e7300d04SMaxime Bizon 		.force_duplex_full = 1,
619e7300d04SMaxime Bizon 	},
620e7300d04SMaxime Bizon };
621f29b7cacSFlorian Fainelli 
622f29b7cacSFlorian Fainelli static struct board_info __initdata board_DWVS0 = {
623f29b7cacSFlorian Fainelli 	.name = "DWV-S0",
624f29b7cacSFlorian Fainelli 	.expected_cpu_id = 0x6358,
625f29b7cacSFlorian Fainelli 
626a5fb3b45SÁlvaro Fernández Rojas 	.has_ehci0 = 1,
627a5fb3b45SÁlvaro Fernández Rojas 	.has_ohci0 = 1,
628f29b7cacSFlorian Fainelli 	.has_pci = 1,
629f29b7cacSFlorian Fainelli 
630a5fb3b45SÁlvaro Fernández Rojas 	.has_enet0 = 1,
631f29b7cacSFlorian Fainelli 	.enet0 = {
632f29b7cacSFlorian Fainelli 		.has_phy = 1,
633f29b7cacSFlorian Fainelli 		.use_internal_phy = 1,
634f29b7cacSFlorian Fainelli 	},
635f29b7cacSFlorian Fainelli 
636a5fb3b45SÁlvaro Fernández Rojas 	.has_enet1 = 1,
637f29b7cacSFlorian Fainelli 	.enet1 = {
638f29b7cacSFlorian Fainelli 		.force_speed_100 = 1,
639f29b7cacSFlorian Fainelli 		.force_duplex_full = 1,
640f29b7cacSFlorian Fainelli 	},
641f29b7cacSFlorian Fainelli };
642c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6358 */
643e7300d04SMaxime Bizon 
644e7300d04SMaxime Bizon /*
645e7300d04SMaxime Bizon  * all boards
646e7300d04SMaxime Bizon  */
6473cf5ae6eSAndi Kleen static const struct board_info __initconst *bcm963xx_boards[] = {
648450acb0bSFlorian Fainelli #ifdef CONFIG_BCM63XX_CPU_3368
649450acb0bSFlorian Fainelli 	&board_cvg834g,
650c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_3368 */
6512f74b770SJonas Gorski #ifdef CONFIG_BCM63XX_CPU_6328
6522f74b770SJonas Gorski 	&board_96328avng,
653c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6328 */
654e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6338
655e7300d04SMaxime Bizon 	&board_96338gw,
656e7300d04SMaxime Bizon 	&board_96338w,
657c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6338 */
658e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6345
659e7300d04SMaxime Bizon 	&board_96345gw2,
660c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6345 */
661e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6348
662e7300d04SMaxime Bizon 	&board_96348r,
663e7300d04SMaxime Bizon 	&board_96348gw,
664e7300d04SMaxime Bizon 	&board_96348gw_10,
665e7300d04SMaxime Bizon 	&board_96348gw_11,
666e7300d04SMaxime Bizon 	&board_FAST2404,
667e7300d04SMaxime Bizon 	&board_DV201AMR,
668e7300d04SMaxime Bizon 	&board_96348gw_a,
6692e6ad9a9SFlorian Fainelli 	&board_rta1025w_16,
670c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6348 */
671e7300d04SMaxime Bizon #ifdef CONFIG_BCM63XX_CPU_6358
672e7300d04SMaxime Bizon 	&board_96358vw,
673e7300d04SMaxime Bizon 	&board_96358vw2,
674e7300d04SMaxime Bizon 	&board_AGPFS0,
675f29b7cacSFlorian Fainelli 	&board_DWVS0,
676c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_BCM63XX_CPU_6358 */
677e7300d04SMaxime Bizon };
678e7300d04SMaxime Bizon 
679e7300d04SMaxime Bizon /*
6805e3644a9SFlorian Fainelli  * Register a sane SPROMv2 to make the on-board
6815e3644a9SFlorian Fainelli  * bcm4318 WLAN work
6825e3644a9SFlorian Fainelli  */
6835e3644a9SFlorian Fainelli #ifdef CONFIG_SSB_PCIHOST
6845e3644a9SFlorian Fainelli static struct ssb_sprom bcm63xx_sprom = {
6855e3644a9SFlorian Fainelli 	.revision		= 0x02,
6865e3644a9SFlorian Fainelli 	.board_rev		= 0x17,
6875e3644a9SFlorian Fainelli 	.country_code		= 0x0,
6885e3644a9SFlorian Fainelli 	.ant_available_bg	= 0x3,
6895e3644a9SFlorian Fainelli 	.pa0b0			= 0x15ae,
6905e3644a9SFlorian Fainelli 	.pa0b1			= 0xfa85,
6915e3644a9SFlorian Fainelli 	.pa0b2			= 0xfe8d,
6925e3644a9SFlorian Fainelli 	.pa1b0			= 0xffff,
6935e3644a9SFlorian Fainelli 	.pa1b1			= 0xffff,
6945e3644a9SFlorian Fainelli 	.pa1b2			= 0xffff,
6955e3644a9SFlorian Fainelli 	.gpio0			= 0xff,
6965e3644a9SFlorian Fainelli 	.gpio1			= 0xff,
6975e3644a9SFlorian Fainelli 	.gpio2			= 0xff,
6985e3644a9SFlorian Fainelli 	.gpio3			= 0xff,
6995e3644a9SFlorian Fainelli 	.maxpwr_bg		= 0x004c,
7005e3644a9SFlorian Fainelli 	.itssi_bg		= 0x00,
7015e3644a9SFlorian Fainelli 	.boardflags_lo		= 0x2848,
7025e3644a9SFlorian Fainelli 	.boardflags_hi		= 0x0000,
7035e3644a9SFlorian Fainelli };
704b3ae52b6SHauke Mehrtens 
bcm63xx_get_fallback_sprom(struct ssb_bus * bus,struct ssb_sprom * out)705b3ae52b6SHauke Mehrtens int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
706b3ae52b6SHauke Mehrtens {
707b3ae52b6SHauke Mehrtens 	if (bus->bustype == SSB_BUSTYPE_PCI) {
708b3ae52b6SHauke Mehrtens 		memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
709b3ae52b6SHauke Mehrtens 		return 0;
710b3ae52b6SHauke Mehrtens 	} else {
71163893ea5SGregory Fong 		pr_err("unable to fill SPROM for given bustype\n");
712b3ae52b6SHauke Mehrtens 		return -EINVAL;
713b3ae52b6SHauke Mehrtens 	}
714b3ae52b6SHauke Mehrtens }
715c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_SSB_PCIHOST */
7165e3644a9SFlorian Fainelli 
7175e3644a9SFlorian Fainelli /*
7185e3644a9SFlorian Fainelli  * return board name for /proc/cpuinfo
7195e3644a9SFlorian Fainelli  */
board_get_name(void)7205e3644a9SFlorian Fainelli const char *board_get_name(void)
7215e3644a9SFlorian Fainelli {
7225e3644a9SFlorian Fainelli 	return board.name;
7235e3644a9SFlorian Fainelli }
7245e3644a9SFlorian Fainelli 
7255e3644a9SFlorian Fainelli /*
726e7300d04SMaxime Bizon  * early init callback, read nvram data from flash and checksum it
727e7300d04SMaxime Bizon  */
board_prom_init(void)728e7300d04SMaxime Bizon void __init board_prom_init(void)
729e7300d04SMaxime Bizon {
730e7e333cbSJonas Gorski 	unsigned int i;
731e7e333cbSJonas Gorski 	u8 *boot_addr, *cfe;
732e7300d04SMaxime Bizon 	char cfe_version[32];
733d753601aSFlorian Fainelli 	char *board_name = NULL;
734e7300d04SMaxime Bizon 	u32 val;
735d753601aSFlorian Fainelli 	struct bcm_hcs *hcs;
736e7300d04SMaxime Bizon 
737e5766aeaSJonas Gorski 	/* read base address of boot chip select (0)
7382c8aaf71SJonas Gorski 	 * 6328/6362 do not have MPI but boot from a fixed address
739e5766aeaSJonas Gorski 	 */
7402c8aaf71SJonas Gorski 	if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) {
741e5766aeaSJonas Gorski 		val = 0x18000000;
7422c8aaf71SJonas Gorski 	} else {
743e7300d04SMaxime Bizon 		val = bcm_mpi_readl(MPI_CSBASE_REG(0));
744e7300d04SMaxime Bizon 		val &= MPI_CSBASE_BASE_MASK;
745e5766aeaSJonas Gorski 	}
746e7300d04SMaxime Bizon 	boot_addr = (u8 *)KSEG1ADDR(val);
747e7300d04SMaxime Bizon 
748e7300d04SMaxime Bizon 	/* dump cfe version */
749e7300d04SMaxime Bizon 	cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;
750e27e1cc9SÁlvaro Fernández Rojas 	if (strstarts(cfe, "cfe-")) {
751e27e1cc9SÁlvaro Fernández Rojas 		if(cfe[4] == 'v') {
752e27e1cc9SÁlvaro Fernández Rojas 			if(cfe[5] == 'd')
753e27e1cc9SÁlvaro Fernández Rojas 				snprintf(cfe_version, 11, "%s",
754e27e1cc9SÁlvaro Fernández Rojas 					 (char *) &cfe[5]);
755e27e1cc9SÁlvaro Fernández Rojas 			else if (cfe[10] > 0)
756e27e1cc9SÁlvaro Fernández Rojas 				snprintf(cfe_version, sizeof(cfe_version),
757e27e1cc9SÁlvaro Fernández Rojas 					 "%u.%u.%u-%u.%u-%u", cfe[5], cfe[6],
758e27e1cc9SÁlvaro Fernández Rojas 					 cfe[7], cfe[8], cfe[9], cfe[10]);
759e7300d04SMaxime Bizon 			else
760e27e1cc9SÁlvaro Fernández Rojas 				snprintf(cfe_version, sizeof(cfe_version),
761e27e1cc9SÁlvaro Fernández Rojas 					 "%u.%u.%u-%u.%u", cfe[5], cfe[6],
762e27e1cc9SÁlvaro Fernández Rojas 					 cfe[7], cfe[8], cfe[9]);
763e27e1cc9SÁlvaro Fernández Rojas 		} else {
764e27e1cc9SÁlvaro Fernández Rojas 			snprintf(cfe_version, 12, "%s", (char *) &cfe[4]);
765e27e1cc9SÁlvaro Fernández Rojas 		}
766e27e1cc9SÁlvaro Fernández Rojas 	} else {
767e7300d04SMaxime Bizon 		strcpy(cfe_version, "unknown");
768e27e1cc9SÁlvaro Fernández Rojas 	}
76963893ea5SGregory Fong 	pr_info("CFE version: %s\n", cfe_version);
770e7300d04SMaxime Bizon 
77197367519SJonas Gorski 	bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET);
772e7300d04SMaxime Bizon 
773d753601aSFlorian Fainelli 	if (BCMCPU_IS_3368()) {
774d753601aSFlorian Fainelli 		hcs = (struct bcm_hcs *)boot_addr;
775d753601aSFlorian Fainelli 		board_name = hcs->filename;
776d753601aSFlorian Fainelli 	} else {
777e7e333cbSJonas Gorski 		board_name = bcm63xx_nvram_get_name();
778d753601aSFlorian Fainelli 	}
779e7300d04SMaxime Bizon 	/* find board by name */
780e7300d04SMaxime Bizon 	for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
781e7e333cbSJonas Gorski 		if (strncmp(board_name, bcm963xx_boards[i]->name, 16))
782e7300d04SMaxime Bizon 			continue;
783e7300d04SMaxime Bizon 		/* copy, board desc array is marked initdata */
784e7300d04SMaxime Bizon 		memcpy(&board, bcm963xx_boards[i], sizeof(board));
785e7300d04SMaxime Bizon 		break;
786e7300d04SMaxime Bizon 	}
787e7300d04SMaxime Bizon 
788e7300d04SMaxime Bizon 	/* bail out if board is not found, will complain later */
789e7300d04SMaxime Bizon 	if (!board.name[0]) {
790e7300d04SMaxime Bizon 		char name[17];
791e7e333cbSJonas Gorski 		memcpy(name, board_name, 16);
792e7300d04SMaxime Bizon 		name[16] = 0;
79363893ea5SGregory Fong 		pr_err("unknown bcm963xx board: %s\n", name);
794e7300d04SMaxime Bizon 		return;
795e7300d04SMaxime Bizon 	}
796e7300d04SMaxime Bizon 
797e7300d04SMaxime Bizon 	/* setup pin multiplexing depending on board enabled device,
798e7300d04SMaxime Bizon 	 * this has to be done this early since PCI init is done
799e7300d04SMaxime Bizon 	 * inside arch_initcall */
800e7300d04SMaxime Bizon 	val = 0;
801e7300d04SMaxime Bizon 
802e7300d04SMaxime Bizon #ifdef CONFIG_PCI
803e7300d04SMaxime Bizon 	if (board.has_pci) {
804e7300d04SMaxime Bizon 		bcm63xx_pci_enabled = 1;
805e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
806e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G2_PCI;
807e7300d04SMaxime Bizon 	}
808c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_PCI */
809e7300d04SMaxime Bizon 
810e7300d04SMaxime Bizon 	if (board.has_pccard) {
811e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
812e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G1_MII_PCCARD;
813e7300d04SMaxime Bizon 	}
814e7300d04SMaxime Bizon 
815e7300d04SMaxime Bizon 	if (board.has_enet0 && !board.enet0.use_internal_phy) {
816e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
817e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G3_EXT_MII |
818e7300d04SMaxime Bizon 				GPIO_MODE_6348_G0_EXT_MII;
819e7300d04SMaxime Bizon 	}
820e7300d04SMaxime Bizon 
821e7300d04SMaxime Bizon 	if (board.has_enet1 && !board.enet1.use_internal_phy) {
822e7300d04SMaxime Bizon 		if (BCMCPU_IS_6348())
823e7300d04SMaxime Bizon 			val |= GPIO_MODE_6348_G3_EXT_MII |
824e7300d04SMaxime Bizon 				GPIO_MODE_6348_G0_EXT_MII;
825e7300d04SMaxime Bizon 	}
826e7300d04SMaxime Bizon 
827e7300d04SMaxime Bizon 	bcm_gpio_writel(val, GPIO_MODE_REG);
828e7300d04SMaxime Bizon }
829e7300d04SMaxime Bizon 
830e7300d04SMaxime Bizon /*
831e7300d04SMaxime Bizon  * second stage init callback, good time to panic if we couldn't
832e7300d04SMaxime Bizon  * identify on which board we're running since early printk is working
833e7300d04SMaxime Bizon  */
board_setup(void)834e7300d04SMaxime Bizon void __init board_setup(void)
835e7300d04SMaxime Bizon {
836e7300d04SMaxime Bizon 	if (!board.name[0])
837e7300d04SMaxime Bizon 		panic("unable to detect bcm963xx board");
83863893ea5SGregory Fong 	pr_info("board name: %s\n", board.name);
839e7300d04SMaxime Bizon 
840e7300d04SMaxime Bizon 	/* make sure we're running on expected cpu */
841e7300d04SMaxime Bizon 	if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
842e7300d04SMaxime Bizon 		panic("unexpected CPU for bcm963xx board");
843e7300d04SMaxime Bizon }
844e7300d04SMaxime Bizon 
845e7300d04SMaxime Bizon static struct gpio_led_platform_data bcm63xx_led_data;
846e7300d04SMaxime Bizon 
847e7300d04SMaxime Bizon static struct platform_device bcm63xx_gpio_leds = {
848e7300d04SMaxime Bizon 	.name			= "leds-gpio",
849e7300d04SMaxime Bizon 	.id			= 0,
850e7300d04SMaxime Bizon 	.dev.platform_data	= &bcm63xx_led_data,
851e7300d04SMaxime Bizon };
852e7300d04SMaxime Bizon 
853e7300d04SMaxime Bizon /*
854e7300d04SMaxime Bizon  * third stage init callback, register all board devices.
855e7300d04SMaxime Bizon  */
board_register_devices(void)856e7300d04SMaxime Bizon int __init board_register_devices(void)
857e7300d04SMaxime Bizon {
858524ef29cSMaxime Bizon 	if (board.has_uart0)
859524ef29cSMaxime Bizon 		bcm63xx_uart_register(0);
860524ef29cSMaxime Bizon 
861524ef29cSMaxime Bizon 	if (board.has_uart1)
862524ef29cSMaxime Bizon 		bcm63xx_uart_register(1);
863524ef29cSMaxime Bizon 
864553d6d5fSMaxime Bizon 	if (board.has_pccard)
865553d6d5fSMaxime Bizon 		bcm63xx_pcmcia_register();
866553d6d5fSMaxime Bizon 
867e7300d04SMaxime Bizon 	if (board.has_enet0 &&
868e7e333cbSJonas Gorski 	    !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr))
869e7300d04SMaxime Bizon 		bcm63xx_enet_register(0, &board.enet0);
870e7300d04SMaxime Bizon 
871e7300d04SMaxime Bizon 	if (board.has_enet1 &&
872e7e333cbSJonas Gorski 	    !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr))
873e7300d04SMaxime Bizon 		bcm63xx_enet_register(1, &board.enet1);
874e7300d04SMaxime Bizon 
8756f00a022SMaxime Bizon 	if (board.has_enetsw &&
8766f00a022SMaxime Bizon 	    !bcm63xx_nvram_get_mac_address(board.enetsw.mac_addr))
8776f00a022SMaxime Bizon 		bcm63xx_enetsw_register(&board.enetsw);
8786f00a022SMaxime Bizon 
87922df90f6SKevin Cernekee 	if (board.has_usbd)
88022df90f6SKevin Cernekee 		bcm63xx_usbd_register(&board.usbd);
88122df90f6SKevin Cernekee 
882b15a6d62SFlorian Fainelli 	/* Generate MAC address for WLAN and register our SPROM,
883b15a6d62SFlorian Fainelli 	 * do this after registering enet devices
884b15a6d62SFlorian Fainelli 	 */
885b15a6d62SFlorian Fainelli #ifdef CONFIG_SSB_PCIHOST
886e7e333cbSJonas Gorski 	if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) {
887b15a6d62SFlorian Fainelli 		memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
888b15a6d62SFlorian Fainelli 		memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
889b15a6d62SFlorian Fainelli 		if (ssb_arch_register_fallback_sprom(
890b15a6d62SFlorian Fainelli 				&bcm63xx_get_fallback_sprom) < 0)
89163893ea5SGregory Fong 			pr_err("failed to register fallback SPROM\n");
892b15a6d62SFlorian Fainelli 	}
893c425423aSÁlvaro Fernández Rojas #endif /* CONFIG_SSB_PCIHOST */
894b15a6d62SFlorian Fainelli 
89576ca4e14SFlorian Fainelli 	bcm63xx_spi_register();
89676ca4e14SFlorian Fainelli 
89783bb90faSJonas Gorski 	bcm63xx_hsspi_register();
89883bb90faSJonas Gorski 
8994b897d54SJonas Gorski 	bcm63xx_flash_register();
900e7300d04SMaxime Bizon 
901e7300d04SMaxime Bizon 	bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
902e7300d04SMaxime Bizon 	bcm63xx_led_data.leds = board.leds;
903e7300d04SMaxime Bizon 
904e7300d04SMaxime Bizon 	platform_device_register(&bcm63xx_gpio_leds);
905e7300d04SMaxime Bizon 
9060b35f0c5SFlorian Fainelli 	if (board.ephy_reset_gpio && board.ephy_reset_gpio_flags)
9070b35f0c5SFlorian Fainelli 		gpio_request_one(board.ephy_reset_gpio,
9080b35f0c5SFlorian Fainelli 				board.ephy_reset_gpio_flags, "ephy-reset");
9090b35f0c5SFlorian Fainelli 
910e7300d04SMaxime Bizon 	return 0;
911e7300d04SMaxime Bizon }
912