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