Path: blob/master/arch/mips/bcm63xx/boards/board_bcm963xx.c
26489 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* Copyright (C) 2008 Maxime Bizon <[email protected]>3* Copyright (C) 2008 Florian Fainelli <[email protected]>4*/56#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt78#include <linux/init.h>9#include <linux/kernel.h>10#include <linux/string.h>11#include <linux/platform_device.h>12#include <linux/ssb/ssb.h>13#include <asm/addrspace.h>14#include <bcm63xx_board.h>15#include <bcm63xx_cpu.h>16#include <bcm63xx_dev_uart.h>17#include <bcm63xx_regs.h>18#include <bcm63xx_io.h>19#include <bcm63xx_nvram.h>20#include <bcm63xx_dev_pci.h>21#include <bcm63xx_dev_enet.h>22#include <bcm63xx_dev_flash.h>23#include <bcm63xx_dev_hsspi.h>24#include <bcm63xx_dev_pcmcia.h>25#include <bcm63xx_dev_spi.h>26#include <bcm63xx_dev_usb_usbd.h>27#include <board_bcm963xx.h>2829#include <uapi/linux/bcm933xx_hcs.h>3031#define HCS_OFFSET_128K 0x200003233static struct board_info board;3435/*36* known 3368 boards37*/38#ifdef CONFIG_BCM63XX_CPU_336839static struct board_info __initdata board_cvg834g = {40.name = "CVG834G_E15R3921",41.expected_cpu_id = 0x3368,4243.ephy_reset_gpio = 36,44.ephy_reset_gpio_flags = GPIOF_OUT_INIT_HIGH,45.has_pci = 1,46.has_uart0 = 1,47.has_uart1 = 1,4849.has_enet0 = 1,50.enet0 = {51.has_phy = 1,52.use_internal_phy = 1,53},5455.leds = {56{57.name = "CVG834G:green:power",58.gpio = 37,59.default_trigger= "default-on",60},61},62};63#endif /* CONFIG_BCM63XX_CPU_3368 */6465/*66* known 6328 boards67*/68#ifdef CONFIG_BCM63XX_CPU_632869static struct board_info __initdata board_96328avng = {70.name = "96328avng",71.expected_cpu_id = 0x6328,7273.has_pci = 1,74.has_uart0 = 1,7576.has_usbd = 0,77.usbd = {78.use_fullspeed = 0,79.port_no = 0,80},8182.leds = {83{84.name = "96328avng::ppp-fail",85.gpio = 2,86.active_low = 1,87},88{89.name = "96328avng::power",90.gpio = 4,91.active_low = 1,92.default_trigger = "default-on",93},94{95.name = "96328avng::power-fail",96.gpio = 8,97.active_low = 1,98},99{100.name = "96328avng::wps",101.gpio = 9,102.active_low = 1,103},104{105.name = "96328avng::ppp",106.gpio = 11,107.active_low = 1,108},109},110};111#endif /* CONFIG_BCM63XX_CPU_6328 */112113/*114* known 6338 boards115*/116#ifdef CONFIG_BCM63XX_CPU_6338117static struct board_info __initdata board_96338gw = {118.name = "96338GW",119.expected_cpu_id = 0x6338,120121.has_ohci0 = 1,122.has_uart0 = 1,123124.has_enet0 = 1,125.enet0 = {126.force_speed_100 = 1,127.force_duplex_full = 1,128},129130.leds = {131{132.name = "adsl",133.gpio = 3,134.active_low = 1,135},136{137.name = "ses",138.gpio = 5,139.active_low = 1,140},141{142.name = "ppp-fail",143.gpio = 4,144.active_low = 1,145},146{147.name = "power",148.gpio = 0,149.active_low = 1,150.default_trigger = "default-on",151},152{153.name = "stop",154.gpio = 1,155.active_low = 1,156}157},158};159160static struct board_info __initdata board_96338w = {161.name = "96338W",162.expected_cpu_id = 0x6338,163164.has_uart0 = 1,165166.has_enet0 = 1,167.enet0 = {168.force_speed_100 = 1,169.force_duplex_full = 1,170},171172.leds = {173{174.name = "adsl",175.gpio = 3,176.active_low = 1,177},178{179.name = "ses",180.gpio = 5,181.active_low = 1,182},183{184.name = "ppp-fail",185.gpio = 4,186.active_low = 1,187},188{189.name = "power",190.gpio = 0,191.active_low = 1,192.default_trigger = "default-on",193},194{195.name = "stop",196.gpio = 1,197.active_low = 1,198},199},200};201#endif /* CONFIG_BCM63XX_CPU_6338 */202203/*204* known 6345 boards205*/206#ifdef CONFIG_BCM63XX_CPU_6345207static struct board_info __initdata board_96345gw2 = {208.name = "96345GW2",209.expected_cpu_id = 0x6345,210211.has_uart0 = 1,212};213#endif /* CONFIG_BCM63XX_CPU_6345 */214215/*216* known 6348 boards217*/218#ifdef CONFIG_BCM63XX_CPU_6348219static struct board_info __initdata board_96348r = {220.name = "96348R",221.expected_cpu_id = 0x6348,222223.has_pci = 1,224.has_uart0 = 1,225226.has_enet0 = 1,227.enet0 = {228.has_phy = 1,229.use_internal_phy = 1,230},231232.leds = {233{234.name = "adsl-fail",235.gpio = 2,236.active_low = 1,237},238{239.name = "ppp",240.gpio = 3,241.active_low = 1,242},243{244.name = "ppp-fail",245.gpio = 4,246.active_low = 1,247},248{249.name = "power",250.gpio = 0,251.active_low = 1,252.default_trigger = "default-on",253254},255{256.name = "stop",257.gpio = 1,258.active_low = 1,259},260},261};262263static struct board_info __initdata board_96348gw_10 = {264.name = "96348GW-10",265.expected_cpu_id = 0x6348,266267.has_ohci0 = 1,268.has_pccard = 1,269.has_pci = 1,270.has_uart0 = 1,271272.has_enet0 = 1,273.enet0 = {274.has_phy = 1,275.use_internal_phy = 1,276},277278.has_enet1 = 1,279.enet1 = {280.force_speed_100 = 1,281.force_duplex_full = 1,282},283284.leds = {285{286.name = "adsl-fail",287.gpio = 2,288.active_low = 1,289},290{291.name = "ppp",292.gpio = 3,293.active_low = 1,294},295{296.name = "ppp-fail",297.gpio = 4,298.active_low = 1,299},300{301.name = "power",302.gpio = 0,303.active_low = 1,304.default_trigger = "default-on",305},306{307.name = "stop",308.gpio = 1,309.active_low = 1,310},311},312};313314static struct board_info __initdata board_96348gw_11 = {315.name = "96348GW-11",316.expected_cpu_id = 0x6348,317318.has_ohci0 = 1,319.has_pccard = 1,320.has_pci = 1,321.has_uart0 = 1,322323.has_enet0 = 1,324.enet0 = {325.has_phy = 1,326.use_internal_phy = 1,327},328329.has_enet1 = 1,330.enet1 = {331.force_speed_100 = 1,332.force_duplex_full = 1,333},334335.leds = {336{337.name = "adsl-fail",338.gpio = 2,339.active_low = 1,340},341{342.name = "ppp",343.gpio = 3,344.active_low = 1,345},346{347.name = "ppp-fail",348.gpio = 4,349.active_low = 1,350},351{352.name = "power",353.gpio = 0,354.active_low = 1,355.default_trigger = "default-on",356},357{358.name = "stop",359.gpio = 1,360.active_low = 1,361},362},363};364365static struct board_info __initdata board_96348gw = {366.name = "96348GW",367.expected_cpu_id = 0x6348,368369.has_ohci0 = 1,370.has_pci = 1,371.has_uart0 = 1,372373.has_enet0 = 1,374.enet0 = {375.has_phy = 1,376.use_internal_phy = 1,377},378379.has_enet1 = 1,380.enet1 = {381.force_speed_100 = 1,382.force_duplex_full = 1,383},384385.leds = {386{387.name = "adsl-fail",388.gpio = 2,389.active_low = 1,390},391{392.name = "ppp",393.gpio = 3,394.active_low = 1,395},396{397.name = "ppp-fail",398.gpio = 4,399.active_low = 1,400},401{402.name = "power",403.gpio = 0,404.active_low = 1,405.default_trigger = "default-on",406},407{408.name = "stop",409.gpio = 1,410.active_low = 1,411},412},413};414415static struct board_info __initdata board_FAST2404 = {416.name = "F@ST2404",417.expected_cpu_id = 0x6348,418419.has_ohci0 = 1,420.has_pccard = 1,421.has_pci = 1,422.has_uart0 = 1,423424.has_enet0 = 1,425.enet0 = {426.has_phy = 1,427.use_internal_phy = 1,428},429430.has_enet1 = 1,431.enet1 = {432.force_speed_100 = 1,433.force_duplex_full = 1,434},435};436437static struct board_info __initdata board_rta1025w_16 = {438.name = "RTA1025W_16",439.expected_cpu_id = 0x6348,440441.has_pci = 1,442443.has_enet0 = 1,444.enet0 = {445.has_phy = 1,446.use_internal_phy = 1,447},448449.has_enet1 = 1,450.enet1 = {451.force_speed_100 = 1,452.force_duplex_full = 1,453},454};455456static struct board_info __initdata board_DV201AMR = {457.name = "DV201AMR",458.expected_cpu_id = 0x6348,459460.has_ohci0 = 1,461.has_pci = 1,462.has_uart0 = 1,463464.has_enet0 = 1,465.enet0 = {466.has_phy = 1,467.use_internal_phy = 1,468},469470.has_enet1 = 1,471.enet1 = {472.force_speed_100 = 1,473.force_duplex_full = 1,474},475};476477static struct board_info __initdata board_96348gw_a = {478.name = "96348GW-A",479.expected_cpu_id = 0x6348,480481.has_ohci0 = 1,482.has_pci = 1,483.has_uart0 = 1,484485.has_enet0 = 1,486.enet0 = {487.has_phy = 1,488.use_internal_phy = 1,489},490491.has_enet1 = 1,492.enet1 = {493.force_speed_100 = 1,494.force_duplex_full = 1,495},496};497#endif /* CONFIG_BCM63XX_CPU_6348 */498499/*500* known 6358 boards501*/502#ifdef CONFIG_BCM63XX_CPU_6358503static struct board_info __initdata board_96358vw = {504.name = "96358VW",505.expected_cpu_id = 0x6358,506507.has_ehci0 = 1,508.has_ohci0 = 1,509.has_pccard = 1,510.has_pci = 1,511.has_uart0 = 1,512513.has_enet0 = 1,514.enet0 = {515.has_phy = 1,516.use_internal_phy = 1,517},518519.has_enet1 = 1,520.enet1 = {521.force_speed_100 = 1,522.force_duplex_full = 1,523},524525.leds = {526{527.name = "adsl-fail",528.gpio = 15,529.active_low = 1,530},531{532.name = "ppp",533.gpio = 22,534.active_low = 1,535},536{537.name = "ppp-fail",538.gpio = 23,539.active_low = 1,540},541{542.name = "power",543.gpio = 4,544.default_trigger = "default-on",545},546{547.name = "stop",548.gpio = 5,549},550},551};552553static struct board_info __initdata board_96358vw2 = {554.name = "96358VW2",555.expected_cpu_id = 0x6358,556557.has_ehci0 = 1,558.has_ohci0 = 1,559.has_pccard = 1,560.has_pci = 1,561.has_uart0 = 1,562563.has_enet0 = 1,564.enet0 = {565.has_phy = 1,566.use_internal_phy = 1,567},568569.has_enet1 = 1,570.enet1 = {571.force_speed_100 = 1,572.force_duplex_full = 1,573},574575.leds = {576{577.name = "adsl",578.gpio = 22,579.active_low = 1,580},581{582.name = "ppp-fail",583.gpio = 23,584},585{586.name = "power",587.gpio = 5,588.active_low = 1,589.default_trigger = "default-on",590},591{592.name = "stop",593.gpio = 4,594.active_low = 1,595},596},597};598599static struct board_info __initdata board_AGPFS0 = {600.name = "AGPF-S0",601.expected_cpu_id = 0x6358,602603.has_ehci0 = 1,604.has_ohci0 = 1,605.has_pci = 1,606.has_uart0 = 1,607608.has_enet0 = 1,609.enet0 = {610.has_phy = 1,611.use_internal_phy = 1,612},613614.has_enet1 = 1,615.enet1 = {616.force_speed_100 = 1,617.force_duplex_full = 1,618},619};620621static struct board_info __initdata board_DWVS0 = {622.name = "DWV-S0",623.expected_cpu_id = 0x6358,624625.has_ehci0 = 1,626.has_ohci0 = 1,627.has_pci = 1,628629.has_enet0 = 1,630.enet0 = {631.has_phy = 1,632.use_internal_phy = 1,633},634635.has_enet1 = 1,636.enet1 = {637.force_speed_100 = 1,638.force_duplex_full = 1,639},640};641#endif /* CONFIG_BCM63XX_CPU_6358 */642643/*644* all boards645*/646static const struct board_info __initconst *bcm963xx_boards[] = {647#ifdef CONFIG_BCM63XX_CPU_3368648&board_cvg834g,649#endif /* CONFIG_BCM63XX_CPU_3368 */650#ifdef CONFIG_BCM63XX_CPU_6328651&board_96328avng,652#endif /* CONFIG_BCM63XX_CPU_6328 */653#ifdef CONFIG_BCM63XX_CPU_6338654&board_96338gw,655&board_96338w,656#endif /* CONFIG_BCM63XX_CPU_6338 */657#ifdef CONFIG_BCM63XX_CPU_6345658&board_96345gw2,659#endif /* CONFIG_BCM63XX_CPU_6345 */660#ifdef CONFIG_BCM63XX_CPU_6348661&board_96348r,662&board_96348gw,663&board_96348gw_10,664&board_96348gw_11,665&board_FAST2404,666&board_DV201AMR,667&board_96348gw_a,668&board_rta1025w_16,669#endif /* CONFIG_BCM63XX_CPU_6348 */670#ifdef CONFIG_BCM63XX_CPU_6358671&board_96358vw,672&board_96358vw2,673&board_AGPFS0,674&board_DWVS0,675#endif /* CONFIG_BCM63XX_CPU_6358 */676};677678/*679* Register a sane SPROMv2 to make the on-board680* bcm4318 WLAN work681*/682#ifdef CONFIG_SSB_PCIHOST683static struct ssb_sprom bcm63xx_sprom = {684.revision = 0x02,685.board_rev = 0x17,686.country_code = 0x0,687.ant_available_bg = 0x3,688.pa0b0 = 0x15ae,689.pa0b1 = 0xfa85,690.pa0b2 = 0xfe8d,691.pa1b0 = 0xffff,692.pa1b1 = 0xffff,693.pa1b2 = 0xffff,694.gpio0 = 0xff,695.gpio1 = 0xff,696.gpio2 = 0xff,697.gpio3 = 0xff,698.maxpwr_bg = 0x004c,699.itssi_bg = 0x00,700.boardflags_lo = 0x2848,701.boardflags_hi = 0x0000,702};703704static int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)705{706if (bus->bustype == SSB_BUSTYPE_PCI) {707memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));708return 0;709} else {710pr_err("unable to fill SPROM for given bustype\n");711return -EINVAL;712}713}714#endif /* CONFIG_SSB_PCIHOST */715716/*717* return board name for /proc/cpuinfo718*/719const char *board_get_name(void)720{721return board.name;722}723724/*725* early init callback, read nvram data from flash and checksum it726*/727void __init board_prom_init(void)728{729unsigned int i;730u8 *boot_addr, *cfe;731char cfe_version[32];732char *board_name = NULL;733u32 val;734struct bcm_hcs *hcs;735736/* read base address of boot chip select (0)737* 6328/6362 do not have MPI but boot from a fixed address738*/739if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) {740val = 0x18000000;741} else {742val = bcm_mpi_readl(MPI_CSBASE_REG(0));743val &= MPI_CSBASE_BASE_MASK;744}745boot_addr = (u8 *)KSEG1ADDR(val);746747/* dump cfe version */748cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET;749if (strstarts(cfe, "cfe-")) {750if(cfe[4] == 'v') {751if(cfe[5] == 'd')752snprintf(cfe_version, 11, "%s",753(char *) &cfe[5]);754else if (cfe[10] > 0)755snprintf(cfe_version, sizeof(cfe_version),756"%u.%u.%u-%u.%u-%u", cfe[5], cfe[6],757cfe[7], cfe[8], cfe[9], cfe[10]);758else759snprintf(cfe_version, sizeof(cfe_version),760"%u.%u.%u-%u.%u", cfe[5], cfe[6],761cfe[7], cfe[8], cfe[9]);762} else {763snprintf(cfe_version, 12, "%s", (char *) &cfe[4]);764}765} else {766strscpy(cfe_version, "unknown");767}768pr_info("CFE version: %s\n", cfe_version);769770bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET);771772if (BCMCPU_IS_3368()) {773hcs = (struct bcm_hcs *)boot_addr;774board_name = hcs->filename;775} else {776board_name = bcm63xx_nvram_get_name();777}778/* find board by name */779for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {780if (strncmp(board_name, bcm963xx_boards[i]->name, 16))781continue;782/* copy, board desc array is marked initdata */783memcpy(&board, bcm963xx_boards[i], sizeof(board));784break;785}786787/* bail out if board is not found, will complain later */788if (!board.name[0]) {789char name[17];790memcpy(name, board_name, 16);791name[16] = 0;792pr_err("unknown bcm963xx board: %s\n", name);793return;794}795796/* setup pin multiplexing depending on board enabled device,797* this has to be done this early since PCI init is done798* inside arch_initcall */799val = 0;800801#ifdef CONFIG_PCI802if (board.has_pci) {803bcm63xx_pci_enabled = 1;804if (BCMCPU_IS_6348())805val |= GPIO_MODE_6348_G2_PCI;806}807#endif /* CONFIG_PCI */808809if (board.has_pccard) {810if (BCMCPU_IS_6348())811val |= GPIO_MODE_6348_G1_MII_PCCARD;812}813814if (board.has_enet0 && !board.enet0.use_internal_phy) {815if (BCMCPU_IS_6348())816val |= GPIO_MODE_6348_G3_EXT_MII |817GPIO_MODE_6348_G0_EXT_MII;818}819820if (board.has_enet1 && !board.enet1.use_internal_phy) {821if (BCMCPU_IS_6348())822val |= GPIO_MODE_6348_G3_EXT_MII |823GPIO_MODE_6348_G0_EXT_MII;824}825826bcm_gpio_writel(val, GPIO_MODE_REG);827}828829/*830* second stage init callback, good time to panic if we couldn't831* identify on which board we're running since early printk is working832*/833void __init board_setup(void)834{835if (!board.name[0])836panic("unable to detect bcm963xx board");837pr_info("board name: %s\n", board.name);838839/* make sure we're running on expected cpu */840if (bcm63xx_get_cpu_id() != board.expected_cpu_id)841panic("unexpected CPU for bcm963xx board");842}843844static struct gpio_led_platform_data bcm63xx_led_data;845846static struct platform_device bcm63xx_gpio_leds = {847.name = "leds-gpio",848.id = 0,849.dev.platform_data = &bcm63xx_led_data,850};851852/*853* third stage init callback, register all board devices.854*/855int __init board_register_devices(void)856{857if (board.has_uart0)858bcm63xx_uart_register(0);859860if (board.has_uart1)861bcm63xx_uart_register(1);862863if (board.has_pccard)864bcm63xx_pcmcia_register();865866if (board.has_enet0 &&867!bcm63xx_nvram_get_mac_address(board.enet0.mac_addr))868bcm63xx_enet_register(0, &board.enet0);869870if (board.has_enet1 &&871!bcm63xx_nvram_get_mac_address(board.enet1.mac_addr))872bcm63xx_enet_register(1, &board.enet1);873874if (board.has_enetsw &&875!bcm63xx_nvram_get_mac_address(board.enetsw.mac_addr))876bcm63xx_enetsw_register(&board.enetsw);877878if (board.has_usbd)879bcm63xx_usbd_register(&board.usbd);880881/* Generate MAC address for WLAN and register our SPROM,882* do this after registering enet devices883*/884#ifdef CONFIG_SSB_PCIHOST885if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) {886memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);887memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);888if (ssb_arch_register_fallback_sprom(889&bcm63xx_get_fallback_sprom) < 0)890pr_err("failed to register fallback SPROM\n");891}892#endif /* CONFIG_SSB_PCIHOST */893894bcm63xx_spi_register();895896bcm63xx_hsspi_register();897898bcm63xx_flash_register();899900bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);901bcm63xx_led_data.leds = board.leds;902903platform_device_register(&bcm63xx_gpio_leds);904905if (board.ephy_reset_gpio && board.ephy_reset_gpio_flags)906gpio_request_one(board.ephy_reset_gpio,907board.ephy_reset_gpio_flags, "ephy-reset");908909return 0;910}911912913