kernel: define RB_ID_HW_OPTIONS in include/linux/routerboot.h
[openwrt.git] / target / linux / generic / patches-3.10 / 025-bcma_backport.patch
index a4ae800..853d524 100644 (file)
@@ -8,6 +8,23 @@
  
  config BCMA_DRIVER_PCI_HOSTMODE
        bool "Driver for PCI core working in hostmode"
+@@ -34,8 +35,14 @@ config BCMA_DRIVER_PCI_HOSTMODE
+         PCI core hostmode operation (external PCI bus).
+ config BCMA_HOST_SOC
+-      bool
+-      depends on BCMA_DRIVER_MIPS
++      bool "Support for BCMA in a SoC"
++      depends on BCMA
++      help
++        Host interface for a Broadcom AIX bus directly mapped into
++        the memory. This only works with the Broadcom SoCs from the
++        BCM47XX line.
++
++        If unsure, say N
+ config BCMA_DRIVER_MIPS
+       bool "BCMA Broadcom MIPS core driver"
 --- a/drivers/bcma/bcma_private.h
 +++ b/drivers/bcma/bcma_private.h
 @@ -22,6 +22,8 @@
        switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
 --- a/drivers/bcma/host_pci.c
 +++ b/drivers/bcma/host_pci.c
-@@ -275,6 +275,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_
+@@ -188,8 +188,11 @@ static int bcma_host_pci_probe(struct pc
+               pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
+       /* SSB needed additional powering up, do we have any AMBA PCI cards? */
+-      if (!pci_is_pcie(dev))
+-              bcma_err(bus, "PCI card detected, report problems.\n");
++      if (!pci_is_pcie(dev)) {
++              bcma_err(bus, "PCI card detected, they are not supported.\n");
++              err = -ENXIO;
++              goto err_pci_release_regions;
++      }
+       /* Map MMIO */
+       err = -ENOMEM;
+@@ -269,12 +272,14 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bc
+ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
++      { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4313) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
  static void bcma_release_core_dev(struct device *dev)
  {
        struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+@@ -218,7 +237,7 @@ int bcma_bus_register(struct bcma_bus *b
+       err = bcma_bus_scan(bus);
+       if (err) {
+               bcma_err(bus, "Failed to scan: %d\n", err);
+-              return -1;
++              return err;
+       }
+       /* Early init CC core */
 --- a/drivers/bcma/sprom.c
 +++ b/drivers/bcma/sprom.c
 @@ -72,12 +72,12 @@ fail:
  }
 --- a/include/linux/bcma/bcma.h
 +++ b/include/linux/bcma/bcma.h
-@@ -144,6 +144,7 @@ struct bcma_host_ops {
+@@ -72,7 +72,19 @@ struct bcma_host_ops {
+ /* Core-ID values. */
+ #define BCMA_CORE_OOB_ROUTER          0x367   /* Out of band */
+ #define BCMA_CORE_4706_CHIPCOMMON     0x500
++#define BCMA_CORE_PCIEG2              0x501
++#define BCMA_CORE_DMA                 0x502
++#define BCMA_CORE_SDIO3                       0x503
++#define BCMA_CORE_USB20                       0x504
++#define BCMA_CORE_USB30                       0x505
++#define BCMA_CORE_A9JTAG              0x506
++#define BCMA_CORE_DDR23                       0x507
++#define BCMA_CORE_ROM                 0x508
++#define BCMA_CORE_NAND                        0x509
++#define BCMA_CORE_QSPI                        0x50A
++#define BCMA_CORE_CHIPCOMMON_B                0x50B
+ #define BCMA_CORE_4706_SOC_RAM                0x50E
++#define BCMA_CORE_ARMCA9              0x510
+ #define BCMA_CORE_4706_MAC_GBIT               0x52D
+ #define BCMA_CORE_AMEMC                       0x52E   /* DDR1/2 memory controller core */
+ #define BCMA_CORE_ALTA                        0x534   /* I2S core */
+@@ -144,6 +156,7 @@ struct bcma_host_ops {
  
  /* Chip IDs of PCIe devices */
  #define BCMA_CHIP_ID_BCM4313  0x4313
  #define BCMA_CHIP_ID_BCM43224 43224
  #define  BCMA_PKG_ID_BCM43224_FAB_CSM 0x8
  #define  BCMA_PKG_ID_BCM43224_FAB_SMIC        0xa
+@@ -176,6 +189,11 @@ struct bcma_host_ops {
+ #define  BCMA_PKG_ID_BCM5357  11
+ #define BCMA_CHIP_ID_BCM53572 53572
+ #define  BCMA_PKG_ID_BCM47188 9
++#define BCMA_CHIP_ID_BCM4707  53010
++#define  BCMA_PKG_ID_BCM4707  1
++#define  BCMA_PKG_ID_BCM4708  2
++#define  BCMA_PKG_ID_BCM4709  0
++#define BCMA_CHIP_ID_BCM53018 53018
+ /* Board types (on PCI usually equals to the subsystem dev id) */
+ /* BCM4313 */
 --- a/include/linux/bcma/bcma_driver_chipcommon.h
 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
 @@ -330,6 +330,8 @@
  /* Data for the PMU, if available.
   * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
   */
+--- a/drivers/bcma/driver_pci.c
++++ b/drivers/bcma/driver_pci.c
+@@ -31,7 +31,7 @@ static void bcma_pcie_write(struct bcma_
+       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
+ }
+-static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
++static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u16 phy)
+ {
+       u32 v;
+       int i;
+@@ -55,7 +55,7 @@ static void bcma_pcie_mdio_set_phy(struc
+       }
+ }
+-static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
++static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u16 device, u8 address)
+ {
+       int max_retries = 10;
+       u16 ret = 0;
+@@ -98,7 +98,7 @@ static u16 bcma_pcie_mdio_read(struct bc
+       return ret;
+ }
+-static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
++static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u16 device,
+                               u8 address, u16 data)
+ {
+       int max_retries = 10;
+@@ -137,6 +137,13 @@ static void bcma_pcie_mdio_write(struct
+       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
+ }
++static u16 bcma_pcie_mdio_writeread(struct bcma_drv_pci *pc, u16 device,
++                                  u8 address, u16 data)
++{
++      bcma_pcie_mdio_write(pc, device, address, data);
++      return bcma_pcie_mdio_read(pc, device, address);
++}
++
+ /**************************************************
+  * Workarounds.
+  **************************************************/
+@@ -229,6 +236,32 @@ void bcma_core_pci_init(struct bcma_drv_
+               bcma_core_pci_clientmode_init(pc);
+ }
++void bcma_core_pci_power_save(struct bcma_bus *bus, bool up)
++{
++      struct bcma_drv_pci *pc;
++      u16 data;
++
++      if (bus->hosttype != BCMA_HOSTTYPE_PCI)
++              return;
++
++      pc = &bus->drv_pci[0];
++
++      if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) {
++              data = up ? 0x74 : 0x7C;
++              bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
++                                       BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64);
++              bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
++                                       BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
++      } else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) {
++              data = up ? 0x75 : 0x7D;
++              bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
++                                       BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65);
++              bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
++                                       BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
++      }
++}
++EXPORT_SYMBOL_GPL(bcma_core_pci_power_save);
++
+ int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
+                         bool enable)
+ {
+@@ -262,7 +295,7 @@ out:
+ }
+ EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
+-void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
++static void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
+ {
+       u32 w;
+@@ -274,4 +307,29 @@ void bcma_core_pci_extend_L1timer(struct
+       bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
+       bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
+ }
+-EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
++
++void bcma_core_pci_up(struct bcma_bus *bus)
++{
++      struct bcma_drv_pci *pc;
++
++      if (bus->hosttype != BCMA_HOSTTYPE_PCI)
++              return;
++
++      pc = &bus->drv_pci[0];
++
++      bcma_core_pci_extend_L1timer(pc, true);
++}
++EXPORT_SYMBOL_GPL(bcma_core_pci_up);
++
++void bcma_core_pci_down(struct bcma_bus *bus)
++{
++      struct bcma_drv_pci *pc;
++
++      if (bus->hosttype != BCMA_HOSTTYPE_PCI)
++              return;
++
++      pc = &bus->drv_pci[0];
++
++      bcma_core_pci_extend_L1timer(pc, false);
++}
++EXPORT_SYMBOL_GPL(bcma_core_pci_down);
+--- a/drivers/bcma/driver_pci_host.c
++++ b/drivers/bcma/driver_pci_host.c
+@@ -581,6 +581,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI
+ int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
+ {
+       struct bcma_drv_pci_host *pc_host;
++      int readrq;
+       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
+               /* This is not a device on the PCI-core bridge. */
+@@ -595,6 +596,11 @@ int bcma_core_pci_plat_dev_init(struct p
+       dev->irq = bcma_core_irq(pc_host->pdev->core);
+       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
++      readrq = pcie_get_readrq(dev);
++      if (readrq > 128) {
++              pr_info("change PCIe max read request size from %i to 128\n", readrq);
++              pcie_set_readrq(dev, 128);
++      }
+       return 0;
+ }
+ EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
+--- a/drivers/bcma/scan.c
++++ b/drivers/bcma/scan.c
+@@ -32,6 +32,18 @@ static const struct bcma_device_id_name
+       { BCMA_CORE_4706_CHIPCOMMON, "BCM4706 ChipCommon" },
+       { BCMA_CORE_4706_SOC_RAM, "BCM4706 SOC RAM" },
+       { BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" },
++      { BCMA_CORE_PCIEG2, "PCIe Gen 2" },
++      { BCMA_CORE_DMA, "DMA" },
++      { BCMA_CORE_SDIO3, "SDIO3" },
++      { BCMA_CORE_USB20, "USB 2.0" },
++      { BCMA_CORE_USB30, "USB 3.0" },
++      { BCMA_CORE_A9JTAG, "ARM Cortex A9 JTAG" },
++      { BCMA_CORE_DDR23, "Denali DDR2/DDR3 memory controller" },
++      { BCMA_CORE_ROM, "ROM" },
++      { BCMA_CORE_NAND, "NAND flash controller" },
++      { BCMA_CORE_QSPI, "SPI flash controller" },
++      { BCMA_CORE_CHIPCOMMON_B, "Chipcommon B" },
++      { BCMA_CORE_ARMCA9, "ARM Cortex A9 core (ihost)" },
+       { BCMA_CORE_AMEMC, "AMEMC (DDR)" },
+       { BCMA_CORE_ALTA, "ALTA (I2S)" },
+       { BCMA_CORE_INVALID, "Invalid" },
+@@ -201,7 +213,7 @@ static s32 bcma_erom_get_mst_port(struct
+       return ent;
+ }
+-static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
++static u32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 __iomem **eromptr,
+                                 u32 type, u8 port)
+ {
+       u32 addrl, addrh, sizel, sizeh = 0;
+@@ -213,7 +225,7 @@ static s32 bcma_erom_get_addr_desc(struc
+           ((ent & SCAN_ADDR_TYPE) != type) ||
+           (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
+               bcma_erom_push_ent(eromptr);
+-              return -EINVAL;
++              return (u32)-EINVAL;
+       }
+       addrl = ent & SCAN_ADDR_ADDR;
+@@ -257,11 +269,13 @@ static struct bcma_device *bcma_find_cor
+       return NULL;
+ }
++#define IS_ERR_VALUE_U32(x) ((x) >= (u32)-MAX_ERRNO)
++
+ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
+                             struct bcma_device_id *match, int core_num,
+                             struct bcma_device *core)
+ {
+-      s32 tmp;
++      u32 tmp;
+       u8 i, j;
+       s32 cia, cib;
+       u8 ports[2], wrappers[2];
+@@ -339,11 +353,11 @@ static int bcma_get_next_core(struct bcm
+        * the main register space for the core
+        */
+       tmp = bcma_erom_get_addr_desc(bus, eromptr, SCAN_ADDR_TYPE_SLAVE, 0);
+-      if (tmp <= 0) {
++      if (tmp == 0 || IS_ERR_VALUE_U32(tmp)) {
+               /* Try again to see if it is a bridge */
+               tmp = bcma_erom_get_addr_desc(bus, eromptr,
+                                             SCAN_ADDR_TYPE_BRIDGE, 0);
+-              if (tmp <= 0) {
++              if (tmp == 0 || IS_ERR_VALUE_U32(tmp)) {
+                       return -EILSEQ;
+               } else {
+                       bcma_info(bus, "Bridge found\n");
+@@ -357,7 +371,7 @@ static int bcma_get_next_core(struct bcm
+               for (j = 0; ; j++) {
+                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
+                               SCAN_ADDR_TYPE_SLAVE, i);
+-                      if (tmp < 0) {
++                      if (IS_ERR_VALUE_U32(tmp)) {
+                               /* no more entries for port _i_ */
+                               /* pr_debug("erom: slave port %d "
+                                * "has %d descriptors\n", i, j); */
+@@ -374,7 +388,7 @@ static int bcma_get_next_core(struct bcm
+               for (j = 0; ; j++) {
+                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
+                               SCAN_ADDR_TYPE_MWRAP, i);
+-                      if (tmp < 0) {
++                      if (IS_ERR_VALUE_U32(tmp)) {
+                               /* no more entries for port _i_ */
+                               /* pr_debug("erom: master wrapper %d "
+                                * "has %d descriptors\n", i, j); */
+@@ -392,7 +406,7 @@ static int bcma_get_next_core(struct bcm
+               for (j = 0; ; j++) {
+                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
+                               SCAN_ADDR_TYPE_SWRAP, i + hack);
+-                      if (tmp < 0) {
++                      if (IS_ERR_VALUE_U32(tmp)) {
+                               /* no more entries for port _i_ */
+                               /* pr_debug("erom: master wrapper %d "
+                                * has %d descriptors\n", i, j); */
+--- a/include/linux/bcma/bcma_driver_pci.h
++++ b/include/linux/bcma/bcma_driver_pci.h
+@@ -181,10 +181,31 @@ struct pci_dev;
+ #define BCMA_CORE_PCI_CFG_DEVCTRL             0xd8
++#define BCMA_CORE_PCI_
++
++/* MDIO devices (SERDES modules) */
++#define BCMA_CORE_PCI_MDIO_IEEE0              0x000
++#define BCMA_CORE_PCI_MDIO_IEEE1              0x001
++#define BCMA_CORE_PCI_MDIO_BLK0                       0x800
++#define BCMA_CORE_PCI_MDIO_BLK1                       0x801
++#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT0                0x16
++#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT1                0x17
++#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT2                0x18
++#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT3                0x19
++#define  BCMA_CORE_PCI_MDIO_BLK1_MGMT4                0x1A
++#define BCMA_CORE_PCI_MDIO_BLK2                       0x802
++#define BCMA_CORE_PCI_MDIO_BLK3                       0x803
++#define BCMA_CORE_PCI_MDIO_BLK4                       0x804
++#define BCMA_CORE_PCI_MDIO_TXPLL              0x808   /* TXPLL register block idx */
++#define BCMA_CORE_PCI_MDIO_TXCTRL0            0x820
++#define BCMA_CORE_PCI_MDIO_SERDESID           0x831
++#define BCMA_CORE_PCI_MDIO_RXCTRL0            0x840
++
+ /* PCIE Root Capability Register bits (Host mode only) */
+ #define BCMA_CORE_PCI_RC_CRS_VISIBILITY               0x0001
+ struct bcma_drv_pci;
++struct bcma_bus;
+ #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
+ struct bcma_drv_pci_host {
+@@ -219,7 +240,9 @@ struct bcma_drv_pci {
+ extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
+ extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
+                                struct bcma_device *core, bool enable);
+-extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend);
++extern void bcma_core_pci_up(struct bcma_bus *bus);
++extern void bcma_core_pci_down(struct bcma_bus *bus);
++extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up);
+ extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
+ extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
+--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+@@ -679,27 +679,6 @@ bool ai_clkctl_cc(struct si_pub *sih, en
+       return mode == BCMA_CLKMODE_FAST;
+ }
+-void ai_pci_up(struct si_pub *sih)
+-{
+-      struct si_info *sii;
+-
+-      sii = container_of(sih, struct si_info, pub);
+-
+-      if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
+-              bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], true);
+-}
+-
+-/* Unconfigure and/or apply various WARs when going down */
+-void ai_pci_down(struct si_pub *sih)
+-{
+-      struct si_info *sii;
+-
+-      sii = container_of(sih, struct si_info, pub);
+-
+-      if (sii->icbus->hosttype == BCMA_HOSTTYPE_PCI)
+-              bcma_core_pci_extend_L1timer(&sii->icbus->drv_pci[0], false);
+-}
+-
+ /* Enable BT-COEX & Ex-PA for 4313 */
+ void ai_epa_4313war(struct si_pub *sih)
+ {
+--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
++++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
+@@ -183,9 +183,6 @@ extern u16 ai_clkctl_fast_pwrup_delay(st
+ extern bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode);
+ extern bool ai_deviceremoved(struct si_pub *sih);
+-extern void ai_pci_down(struct si_pub *sih);
+-extern void ai_pci_up(struct si_pub *sih);
+-
+ /* Enable Ex-PA for 4313 */
+ extern void ai_epa_4313war(struct si_pub *sih);
+--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
++++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
+@@ -4667,7 +4667,7 @@ static int brcms_b_attach(struct brcms_c
+       brcms_c_coredisable(wlc_hw);
+       /* Match driver "down" state */
+-      ai_pci_down(wlc_hw->sih);
++      bcma_core_pci_down(wlc_hw->d11core->bus);
+       /* turn off pll and xtal to match driver "down" state */
+       brcms_b_xtal(wlc_hw, OFF);
+@@ -5010,12 +5010,12 @@ static int brcms_b_up_prep(struct brcms_
+        */
+       if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
+               /* put SB PCI in down state again */
+-              ai_pci_down(wlc_hw->sih);
++              bcma_core_pci_down(wlc_hw->d11core->bus);
+               brcms_b_xtal(wlc_hw, OFF);
+               return -ENOMEDIUM;
+       }
+-      ai_pci_up(wlc_hw->sih);
++      bcma_core_pci_up(wlc_hw->d11core->bus);
+       /* reset the d11 core */
+       brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
+@@ -5212,7 +5212,7 @@ static int brcms_b_down_finish(struct br
+               /* turn off primary xtal and pll */
+               if (!wlc_hw->noreset) {
+-                      ai_pci_down(wlc_hw->sih);
++                      bcma_core_pci_down(wlc_hw->d11core->bus);
+                       brcms_b_xtal(wlc_hw, OFF);
+               }
+       }