brcm47xx: update bcma and ssb to master-2011-07-21
* add new patches for bcm4716 SoC * add support for serial flash on bcma bus SVN-Revision: 27723
This commit is contained in:
@@ -185,7 +185,7 @@
|
||||
{
|
||||
struct ssb_bus *bus = pc->dev->bus;
|
||||
u16 chipid_top;
|
||||
@@ -403,28 +408,129 @@ static int pcicore_is_in_hostmode(struct
|
||||
@@ -403,25 +408,133 @@ static int pcicore_is_in_hostmode(struct
|
||||
}
|
||||
#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
|
||||
|
||||
@@ -298,8 +298,17 @@
|
||||
-static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
|
||||
+static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
|
||||
{
|
||||
+ ssb_pcicore_fix_sprom_core_index(pc);
|
||||
+
|
||||
/* Disable PCI interrupts. */
|
||||
ssb_write32(pc->dev, SSB_INTVEC, 0);
|
||||
+
|
||||
+ /* Additional PCIe always once-executed workarounds */
|
||||
+ if (pc->dev->id.coreid == SSB_DEV_PCIE) {
|
||||
+ ssb_pcicore_serdes_workaround(pc);
|
||||
+ /* TODO: ASPM */
|
||||
+ /* TODO: Clock Request Update */
|
||||
+ }
|
||||
}
|
||||
|
||||
-void ssb_pcicore_init(struct ssb_pcicore *pc)
|
||||
@@ -314,25 +323,6 @@
|
||||
if (!ssb_device_is_enabled(dev))
|
||||
ssb_device_enable(dev, 0);
|
||||
|
||||
+ ssb_pcicore_fix_sprom_core_index(pc);
|
||||
+
|
||||
#ifdef CONFIG_SSB_PCICORE_HOSTMODE
|
||||
pc->hostmode = pcicore_is_in_hostmode(pc);
|
||||
if (pc->hostmode)
|
||||
@@ -432,6 +538,13 @@ void ssb_pcicore_init(struct ssb_pcicore
|
||||
#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
|
||||
if (!pc->hostmode)
|
||||
ssb_pcicore_init_clientmode(pc);
|
||||
+
|
||||
+ /* Additional PCIe always once-executed workarounds */
|
||||
+ if (dev->id.coreid == SSB_DEV_PCIE) {
|
||||
+ ssb_pcicore_serdes_workaround(pc);
|
||||
+ /* TODO: ASPM */
|
||||
+ /* TODO: Clock Request Update */
|
||||
+ }
|
||||
}
|
||||
|
||||
static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
|
||||
@@ -446,11 +559,35 @@ static void ssb_pcie_write(struct ssb_pc
|
||||
pcicore_write32(pc, 0x134, data);
|
||||
}
|
||||
@@ -629,7 +619,19 @@
|
||||
}
|
||||
|
||||
int ssb_device_is_enabled(struct ssb_device *dev)
|
||||
@@ -1309,20 +1309,20 @@ EXPORT_SYMBOL(ssb_bus_may_powerdown);
|
||||
@@ -1266,7 +1266,10 @@ u32 ssb_dma_translation(struct ssb_devic
|
||||
case SSB_BUSTYPE_SSB:
|
||||
return 0;
|
||||
case SSB_BUSTYPE_PCI:
|
||||
- return SSB_PCI_DMA;
|
||||
+ if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64)
|
||||
+ return SSB_PCIE_DMA_H32;
|
||||
+ else
|
||||
+ return SSB_PCI_DMA;
|
||||
default:
|
||||
__ssb_dma_not_implemented(dev);
|
||||
}
|
||||
@@ -1309,20 +1312,20 @@ EXPORT_SYMBOL(ssb_bus_may_powerdown);
|
||||
|
||||
int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
|
||||
{
|
||||
@@ -654,7 +656,7 @@
|
||||
return 0;
|
||||
error:
|
||||
ssb_printk(KERN_ERR PFX "Bus powerup failed\n");
|
||||
@@ -1330,6 +1330,37 @@ error:
|
||||
@@ -1330,6 +1333,37 @@ error:
|
||||
}
|
||||
EXPORT_SYMBOL(ssb_bus_powerup);
|
||||
|
||||
@@ -724,6 +726,22 @@
|
||||
err = 0;
|
||||
goto out_free;
|
||||
}
|
||||
@@ -728,12 +734,9 @@ out_free:
|
||||
static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
|
||||
struct ssb_boardinfo *bi)
|
||||
{
|
||||
- pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
|
||||
- &bi->vendor);
|
||||
- pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
|
||||
- &bi->type);
|
||||
- pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
|
||||
- &bi->rev);
|
||||
+ bi->vendor = bus->host_pci->subsystem_vendor;
|
||||
+ bi->type = bus->host_pci->subsystem_device;
|
||||
+ bi->rev = bus->host_pci->revision;
|
||||
}
|
||||
|
||||
int ssb_pci_get_invariants(struct ssb_bus *bus,
|
||||
--- a/drivers/ssb/pcihost_wrapper.c
|
||||
+++ b/drivers/ssb/pcihost_wrapper.c
|
||||
@@ -53,8 +53,8 @@ static int ssb_pcihost_resume(struct pci
|
||||
@@ -856,7 +874,25 @@
|
||||
/* core.c */
|
||||
--- a/include/linux/ssb/ssb.h
|
||||
+++ b/include/linux/ssb/ssb.h
|
||||
@@ -308,7 +308,7 @@ struct ssb_bus {
|
||||
@@ -27,6 +27,8 @@ struct ssb_sprom {
|
||||
u8 et1mdcport; /* MDIO for enet1 */
|
||||
u8 board_rev; /* Board revision number from SPROM. */
|
||||
u8 country_code; /* Country Code */
|
||||
+ u16 leddc_on_time; /* LED Powersave Duty Cycle On Count */
|
||||
+ u16 leddc_off_time; /* LED Powersave Duty Cycle Off Count */
|
||||
u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */
|
||||
u8 ant_available_bg; /* 5GHz antenna available bits (up to 4) */
|
||||
u16 pa0b0;
|
||||
@@ -99,7 +101,7 @@ struct ssb_sprom {
|
||||
struct ssb_boardinfo {
|
||||
u16 vendor;
|
||||
u16 type;
|
||||
- u16 rev;
|
||||
+ u8 rev;
|
||||
};
|
||||
|
||||
|
||||
@@ -308,7 +310,7 @@ struct ssb_bus {
|
||||
|
||||
/* ID information about the Chip. */
|
||||
u16 chip_id;
|
||||
@@ -865,7 +901,7 @@
|
||||
u16 sprom_offset;
|
||||
u16 sprom_size; /* number of words in sprom */
|
||||
u8 chip_package;
|
||||
@@ -404,7 +404,9 @@ extern bool ssb_is_sprom_available(struc
|
||||
@@ -404,7 +406,9 @@ extern bool ssb_is_sprom_available(struc
|
||||
|
||||
/* Set a fallback SPROM.
|
||||
* See kdoc at the function definition for complete documentation. */
|
||||
@@ -876,7 +912,7 @@
|
||||
|
||||
/* Suspend a SSB bus.
|
||||
* Call this from the parent bus suspend routine. */
|
||||
@@ -518,6 +520,7 @@ extern int ssb_bus_may_powerdown(struct
|
||||
@@ -518,6 +522,7 @@ extern int ssb_bus_may_powerdown(struct
|
||||
* Otherwise static always-on powercontrol will be used. */
|
||||
extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl);
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
obj-$(CONFIG_STAGING) += staging/
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/Kconfig
|
||||
@@ -0,0 +1,38 @@
|
||||
@@ -0,0 +1,44 @@
|
||||
+config BCMA_POSSIBLE
|
||||
+ bool
|
||||
+ depends on HAS_IOMEM && HAS_DMA
|
||||
@@ -101,6 +101,12 @@
|
||||
+ bool "Support for BCMA on PCI-host bus"
|
||||
+ depends on BCMA_HOST_PCI_POSSIBLE
|
||||
+
|
||||
+config BCMA_DRIVER_PCI_HOSTMODE
|
||||
+ bool "Driver for PCI core working in hostmode"
|
||||
+ depends on BCMA && MIPS
|
||||
+ help
|
||||
+ PCI core hostmode operation (external PCI bus).
|
||||
+
|
||||
+config BCMA_DEBUG
|
||||
+ bool "BCMA debugging"
|
||||
+ depends on BCMA
|
||||
@@ -112,10 +118,11 @@
|
||||
+endmenu
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/Makefile
|
||||
@@ -0,0 +1,7 @@
|
||||
@@ -0,0 +1,8 @@
|
||||
+bcma-y += main.o scan.o core.o sprom.o
|
||||
+bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
|
||||
+bcma-y += driver_pci.o
|
||||
+bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
|
||||
+bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
|
||||
+obj-$(CONFIG_BCMA) += bcma.o
|
||||
+
|
||||
@@ -150,7 +157,7 @@
|
||||
+- Create kernel Documentation (use info from README)
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/bcma_private.h
|
||||
@@ -0,0 +1,31 @@
|
||||
@@ -0,0 +1,35 @@
|
||||
+#ifndef LINUX_BCMA_PRIVATE_H_
|
||||
+#define LINUX_BCMA_PRIVATE_H_
|
||||
+
|
||||
@@ -181,10 +188,14 @@
|
||||
+extern void __exit bcma_host_pci_exit(void);
|
||||
+#endif /* CONFIG_BCMA_HOST_PCI */
|
||||
+
|
||||
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
|
||||
+void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
|
||||
+#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
|
||||
+
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/core.c
|
||||
@@ -0,0 +1,52 @@
|
||||
@@ -0,0 +1,124 @@
|
||||
+/*
|
||||
+ * Broadcom specific AMBA
|
||||
+ * Core ops
|
||||
@@ -237,9 +248,81 @@
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(bcma_core_enable);
|
||||
+
|
||||
+void bcma_core_set_clockmode(struct bcma_device *core,
|
||||
+ enum bcma_clkmode clkmode)
|
||||
+{
|
||||
+ u16 i;
|
||||
+
|
||||
+ WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
|
||||
+ core->id.id != BCMA_CORE_PCIE &&
|
||||
+ core->id.id != BCMA_CORE_80211);
|
||||
+
|
||||
+ switch (clkmode) {
|
||||
+ case BCMA_CLKMODE_FAST:
|
||||
+ bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
|
||||
+ udelay(64);
|
||||
+ for (i = 0; i < 1500; i++) {
|
||||
+ if (bcma_read32(core, BCMA_CLKCTLST) &
|
||||
+ BCMA_CLKCTLST_HAVEHT) {
|
||||
+ i = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ udelay(10);
|
||||
+ }
|
||||
+ if (i)
|
||||
+ pr_err("HT force timeout\n");
|
||||
+ break;
|
||||
+ case BCMA_CLKMODE_DYNAMIC:
|
||||
+ pr_warn("Dynamic clockmode not supported yet!\n");
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
|
||||
+
|
||||
+void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
|
||||
+{
|
||||
+ u16 i;
|
||||
+
|
||||
+ WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
|
||||
+ WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
|
||||
+
|
||||
+ if (on) {
|
||||
+ bcma_set32(core, BCMA_CLKCTLST, req);
|
||||
+ for (i = 0; i < 10000; i++) {
|
||||
+ if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
|
||||
+ status) {
|
||||
+ i = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ udelay(10);
|
||||
+ }
|
||||
+ if (i)
|
||||
+ pr_err("PLL enable timeout\n");
|
||||
+ } else {
|
||||
+ pr_warn("Disabling PLL not supported yet!\n");
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
|
||||
+
|
||||
+u32 bcma_core_dma_translation(struct bcma_device *core)
|
||||
+{
|
||||
+ switch (core->bus->hosttype) {
|
||||
+ case BCMA_HOSTTYPE_PCI:
|
||||
+ if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
|
||||
+ return BCMA_DMA_TRANSLATION_DMA64_CMT;
|
||||
+ else
|
||||
+ return BCMA_DMA_TRANSLATION_DMA32_CMT;
|
||||
+ default:
|
||||
+ pr_err("DMA translation unknown for host %d\n",
|
||||
+ core->bus->hosttype);
|
||||
+ }
|
||||
+ return BCMA_DMA_TRANSLATION_NONE;
|
||||
+}
|
||||
+EXPORT_SYMBOL(bcma_core_dma_translation);
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/driver_chipcommon.c
|
||||
@@ -0,0 +1,89 @@
|
||||
@@ -0,0 +1,103 @@
|
||||
+/*
|
||||
+ * Broadcom specific AMBA
|
||||
+ * ChipCommon core driver
|
||||
@@ -265,6 +348,9 @@
|
||||
+
|
||||
+void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
|
||||
+{
|
||||
+ u32 leddc_on = 10;
|
||||
+ u32 leddc_off = 90;
|
||||
+
|
||||
+ if (cc->core->id.rev >= 11)
|
||||
+ cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
|
||||
+ cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
|
||||
@@ -280,6 +366,17 @@
|
||||
+ bcma_pmu_init(cc);
|
||||
+ if (cc->capabilities & BCMA_CC_CAP_PCTL)
|
||||
+ pr_err("Power control not implemented!\n");
|
||||
+
|
||||
+ if (cc->core->id.rev >= 16) {
|
||||
+ if (cc->core->bus->sprom.leddc_on_time &&
|
||||
+ cc->core->bus->sprom.leddc_off_time) {
|
||||
+ leddc_on = cc->core->bus->sprom.leddc_on_time;
|
||||
+ leddc_off = cc->core->bus->sprom.leddc_off_time;
|
||||
+ }
|
||||
+ bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
|
||||
+ ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
|
||||
+ (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
|
||||
@@ -472,7 +569,7 @@
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/driver_pci.c
|
||||
@@ -0,0 +1,187 @@
|
||||
@@ -0,0 +1,223 @@
|
||||
+/*
|
||||
+ * Broadcom specific AMBA
|
||||
+ * PCI Core
|
||||
@@ -632,11 +729,47 @@
|
||||
+ * Init.
|
||||
+ **************************************************/
|
||||
+
|
||||
+void bcma_core_pci_init(struct bcma_drv_pci *pc)
|
||||
+static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
|
||||
+{
|
||||
+ bcma_pcicore_serdes_workaround(pc);
|
||||
+}
|
||||
+
|
||||
+static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
|
||||
+{
|
||||
+ struct bcma_bus *bus = pc->core->bus;
|
||||
+ u16 chipid_top;
|
||||
+
|
||||
+ chipid_top = (bus->chipinfo.id & 0xFF00);
|
||||
+ if (chipid_top != 0x4700 &&
|
||||
+ chipid_top != 0x5300)
|
||||
+ return false;
|
||||
+
|
||||
+ if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
|
||||
+ return false;
|
||||
+
|
||||
+#if 0
|
||||
+ /* TODO: on BCMA we use address from EROM instead of magic formula */
|
||||
+ u32 tmp;
|
||||
+ return !mips_busprobe32(tmp, (bus->mmio +
|
||||
+ (pc->core->core_index * BCMA_CORE_SIZE)));
|
||||
+#endif
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+void bcma_core_pci_init(struct bcma_drv_pci *pc)
|
||||
+{
|
||||
+ if (bcma_core_pci_is_in_hostmode(pc)) {
|
||||
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
|
||||
+ bcma_core_pci_hostmode_init(pc);
|
||||
+#else
|
||||
+ pr_err("Driver compiled without support for hostmode PCI\n");
|
||||
+#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
|
||||
+ } else {
|
||||
+ bcma_core_pci_clientmode_init(pc);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
|
||||
+ bool enable)
|
||||
+{
|
||||
@@ -916,7 +1049,7 @@
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/main.c
|
||||
@@ -0,0 +1,255 @@
|
||||
@@ -0,0 +1,257 @@
|
||||
+/*
|
||||
+ * Broadcom specific AMBA
|
||||
+ * Bus subsystem
|
||||
@@ -1068,7 +1201,9 @@
|
||||
+
|
||||
+ /* Try to get SPROM */
|
||||
+ err = bcma_sprom_get(bus);
|
||||
+ if (err) {
|
||||
+ if (err == -ENOENT) {
|
||||
+ pr_err("No SPROM available\n");
|
||||
+ } else if (err) {
|
||||
+ pr_err("Failed to get SPROM: %d\n", err);
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
@@ -1596,7 +1731,7 @@
|
||||
+#endif /* BCMA_SCAN_H_ */
|
||||
--- /dev/null
|
||||
+++ b/include/linux/bcma/bcma.h
|
||||
@@ -0,0 +1,250 @@
|
||||
@@ -0,0 +1,271 @@
|
||||
+#ifndef LINUX_BCMA_H_
|
||||
+#define LINUX_BCMA_H_
|
||||
+
|
||||
@@ -1624,6 +1759,11 @@
|
||||
+ u8 pkg;
|
||||
+};
|
||||
+
|
||||
+enum bcma_clkmode {
|
||||
+ BCMA_CLKMODE_FAST,
|
||||
+ BCMA_CLKMODE_DYNAMIC,
|
||||
+};
|
||||
+
|
||||
+struct bcma_host_ops {
|
||||
+ u8 (*read8)(struct bcma_device *core, u16 offset);
|
||||
+ u16 (*read16)(struct bcma_device *core, u16 offset);
|
||||
@@ -1842,14 +1982,30 @@
|
||||
+ core->bus->ops->awrite32(core, offset, value);
|
||||
+}
|
||||
+
|
||||
+#define bcma_mask32(cc, offset, mask) \
|
||||
+ bcma_write32(cc, offset, bcma_read32(cc, offset) & (mask))
|
||||
+#define bcma_set32(cc, offset, set) \
|
||||
+ bcma_write32(cc, offset, bcma_read32(cc, offset) | (set))
|
||||
+#define bcma_maskset32(cc, offset, mask, set) \
|
||||
+ bcma_write32(cc, offset, (bcma_read32(cc, offset) & (mask)) | (set))
|
||||
+
|
||||
+extern bool bcma_core_is_enabled(struct bcma_device *core);
|
||||
+extern void bcma_core_disable(struct bcma_device *core, u32 flags);
|
||||
+extern int bcma_core_enable(struct bcma_device *core, u32 flags);
|
||||
+extern void bcma_core_set_clockmode(struct bcma_device *core,
|
||||
+ enum bcma_clkmode clkmode);
|
||||
+extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
|
||||
+ bool on);
|
||||
+#define BCMA_DMA_TRANSLATION_MASK 0xC0000000
|
||||
+#define BCMA_DMA_TRANSLATION_NONE 0x00000000
|
||||
+#define BCMA_DMA_TRANSLATION_DMA32_CMT 0x40000000 /* Client Mode Translation for 32-bit DMA */
|
||||
+#define BCMA_DMA_TRANSLATION_DMA64_CMT 0x80000000 /* Client Mode Translation for 64-bit DMA */
|
||||
+extern u32 bcma_core_dma_translation(struct bcma_device *core);
|
||||
+
|
||||
+#endif /* LINUX_BCMA_H_ */
|
||||
--- /dev/null
|
||||
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
|
||||
@@ -0,0 +1,303 @@
|
||||
@@ -0,0 +1,296 @@
|
||||
+#ifndef LINUX_BCMA_DRIVER_CC_H_
|
||||
+#define LINUX_BCMA_DRIVER_CC_H_
|
||||
+
|
||||
@@ -2031,15 +2187,7 @@
|
||||
+#define BCMA_CC_PROG_WAITCNT 0x0124
|
||||
+#define BCMA_CC_FLASH_CFG 0x0128
|
||||
+#define BCMA_CC_FLASH_WAITCNT 0x012C
|
||||
+#define BCMA_CC_CLKCTLST 0x01E0 /* Clock control and status (rev >= 20) */
|
||||
+#define BCMA_CC_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
|
||||
+#define BCMA_CC_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
|
||||
+#define BCMA_CC_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
|
||||
+#define BCMA_CC_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
|
||||
+#define BCMA_CC_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
|
||||
+#define BCMA_CC_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
|
||||
+#define BCMA_CC_CLKCTLST_HAVEHT 0x00010000 /* HT available */
|
||||
+#define BCMA_CC_CLKCTLST_HAVEALP 0x00020000 /* APL available */
|
||||
+/* 0x1E0 is defined as shared BCMA_CLKCTLST */
|
||||
+#define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
|
||||
+#define BCMA_CC_UART0_DATA 0x0300
|
||||
+#define BCMA_CC_UART0_IMR 0x0304
|
||||
@@ -2096,7 +2244,8 @@
|
||||
+#define BCMA_CC_REGCTL_DATA 0x065C
|
||||
+#define BCMA_CC_PLLCTL_ADDR 0x0660
|
||||
+#define BCMA_CC_PLLCTL_DATA 0x0664
|
||||
+#define BCMA_CC_SPROM 0x0830 /* SPROM beginning */
|
||||
+#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
|
||||
+#define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */
|
||||
+
|
||||
+/* Data for the PMU, if available.
|
||||
+ * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
|
||||
@@ -2249,17 +2398,42 @@
|
||||
+#endif /* LINUX_BCMA_DRIVER_PCI_H_ */
|
||||
--- /dev/null
|
||||
+++ b/include/linux/bcma/bcma_regs.h
|
||||
@@ -0,0 +1,34 @@
|
||||
@@ -0,0 +1,59 @@
|
||||
+#ifndef LINUX_BCMA_REGS_H_
|
||||
+#define LINUX_BCMA_REGS_H_
|
||||
+
|
||||
+/* Some single registers are shared between many cores */
|
||||
+/* BCMA_CLKCTLST: ChipCommon (rev >= 20), PCIe, 80211 */
|
||||
+#define BCMA_CLKCTLST 0x01E0 /* Clock control and status */
|
||||
+#define BCMA_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
|
||||
+#define BCMA_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
|
||||
+#define BCMA_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
|
||||
+#define BCMA_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
|
||||
+#define BCMA_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
|
||||
+#define BCMA_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
|
||||
+#define BCMA_CLKCTLST_EXTRESREQ 0x00000700 /* Mask of external resource requests */
|
||||
+#define BCMA_CLKCTLST_HAVEALP 0x00010000 /* ALP available */
|
||||
+#define BCMA_CLKCTLST_HAVEHT 0x00020000 /* HT available */
|
||||
+#define BCMA_CLKCTLST_BP_ON_ALP 0x00040000 /* RO: running on ALP clock */
|
||||
+#define BCMA_CLKCTLST_BP_ON_HT 0x00080000 /* RO: running on HT clock */
|
||||
+#define BCMA_CLKCTLST_EXTRESST 0x07000000 /* Mask of external resource status */
|
||||
+/* Is there any BCM4328 on BCMA bus? */
|
||||
+#define BCMA_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */
|
||||
+#define BCMA_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */
|
||||
+
|
||||
+/* Agent registers (common for every core) */
|
||||
+#define BCMA_IOCTL 0x0408
|
||||
+#define BCMA_IOCTL 0x0408 /* IO control */
|
||||
+#define BCMA_IOCTL_CLK 0x0001
|
||||
+#define BCMA_IOCTL_FGC 0x0002
|
||||
+#define BCMA_IOCTL_CORE_BITS 0x3FFC
|
||||
+#define BCMA_IOCTL_PME_EN 0x4000
|
||||
+#define BCMA_IOCTL_BIST_EN 0x8000
|
||||
+#define BCMA_IOST 0x0500 /* IO status */
|
||||
+#define BCMA_IOST_CORE_BITS 0x0FFF
|
||||
+#define BCMA_IOST_DMA64 0x1000
|
||||
+#define BCMA_IOST_GATED_CLK 0x2000
|
||||
+#define BCMA_IOST_BIST_ERROR 0x4000
|
||||
+#define BCMA_IOST_BIST_DONE 0x8000
|
||||
+#define BCMA_RESET_CTL 0x0800
|
||||
+#define BCMA_RESET_CTL_RESET 0x0001
|
||||
+
|
||||
@@ -2350,7 +2524,7 @@
|
||||
sizeof(struct virtio_device_id), "virtio",
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/sprom.c
|
||||
@@ -0,0 +1,162 @@
|
||||
@@ -0,0 +1,171 @@
|
||||
+/*
|
||||
+ * Broadcom specific AMBA
|
||||
+ * SPROM reading
|
||||
@@ -2373,12 +2547,12 @@
|
||||
+ * R/W ops.
|
||||
+ **************************************************/
|
||||
+
|
||||
+static void bcma_sprom_read(struct bcma_bus *bus, u16 *sprom)
|
||||
+static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
|
||||
+ sprom[i] = bcma_read16(bus->drv_cc.core,
|
||||
+ BCMA_CC_SPROM + (i * 2));
|
||||
+ offset + (i * 2));
|
||||
+}
|
||||
+
|
||||
+/**************************************************
|
||||
@@ -2465,7 +2639,7 @@
|
||||
+ return err;
|
||||
+
|
||||
+ revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
|
||||
+ if (revision != 8) {
|
||||
+ if (revision != 8 && revision != 9) {
|
||||
+ pr_err("Unsupported SPROM revision: %d\n", revision);
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
@@ -2490,18 +2664,27 @@
|
||||
+
|
||||
+int bcma_sprom_get(struct bcma_bus *bus)
|
||||
+{
|
||||
+ u16 offset;
|
||||
+ u16 *sprom;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ if (!bus->drv_cc.core)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!sprom)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ bcma_sprom_read(bus, sprom);
|
||||
+ /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
|
||||
+ * According to brcm80211 this applies to cards with PCIe rev >= 6
|
||||
+ * TODO: understand this condition and use it */
|
||||
+ offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
|
||||
+ BCMA_CC_SPROM_PCIE6;
|
||||
+ bcma_sprom_read(bus, offset, sprom);
|
||||
+
|
||||
+ err = bcma_sprom_valid(sprom);
|
||||
+ if (err)
|
||||
@@ -2513,3 +2696,20 @@
|
||||
+ kfree(sprom);
|
||||
+ return err;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/driver_pci_host.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/*
|
||||
+ * Broadcom specific AMBA
|
||||
+ * PCI Core in hostmode
|
||||
+ *
|
||||
+ * Licensed under the GNU/GPL. See COPYING for details.
|
||||
+ */
|
||||
+
|
||||
+#include "bcma_private.h"
|
||||
+#include <linux/bcma/bcma.h>
|
||||
+
|
||||
+void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
|
||||
+{
|
||||
+ pr_err("No support for PCI core in hostmode yet\n");
|
||||
+}
|
||||
|
||||
@@ -409,7 +409,7 @@
|
||||
|
||||
static struct dentry *shmem_get_parent(struct dentry *child)
|
||||
{
|
||||
@@ -2402,8 +2606,10 @@ int shmem_fill_super(struct super_block
|
||||
@@ -2402,8 +2606,10 @@ int shmem_fill_super(struct super_block
|
||||
sb->s_magic = TMPFS_MAGIC;
|
||||
sb->s_op = &shmem_ops;
|
||||
sb->s_time_gran = 1;
|
||||
|
||||
@@ -17,3 +17,13 @@
|
||||
|
||||
config SSB_PCMCIAHOST_POSSIBLE
|
||||
bool
|
||||
--- a/drivers/bcma/Kconfig
|
||||
+++ b/drivers/bcma/Kconfig
|
||||
@@ -17,6 +17,7 @@ config BCMA
|
||||
config BCMA_BLOCKIO
|
||||
bool
|
||||
depends on BCMA
|
||||
+ default y
|
||||
|
||||
config BCMA_HOST_PCI_POSSIBLE
|
||||
bool
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
endif # BLOCK
|
||||
|
||||
@@ -177,6 +176,10 @@ source "fs/hfsplus/Kconfig"
|
||||
@@ -193,6 +192,10 @@ source "fs/hfsplus/Kconfig"
|
||||
source "fs/befs/Kconfig"
|
||||
source "fs/bfs/Kconfig"
|
||||
source "fs/efs/Kconfig"
|
||||
|
||||
@@ -179,6 +179,36 @@
|
||||
case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
|
||||
case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
|
||||
case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
|
||||
@@ -1265,7 +1266,10 @@ u32 ssb_dma_translation(struct ssb_devic
|
||||
case SSB_BUSTYPE_SSB:
|
||||
return 0;
|
||||
case SSB_BUSTYPE_PCI:
|
||||
- return SSB_PCI_DMA;
|
||||
+ if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64)
|
||||
+ return SSB_PCIE_DMA_H32;
|
||||
+ else
|
||||
+ return SSB_PCI_DMA;
|
||||
default:
|
||||
__ssb_dma_not_implemented(dev);
|
||||
}
|
||||
--- a/drivers/ssb/pci.c
|
||||
+++ b/drivers/ssb/pci.c
|
||||
@@ -734,12 +734,9 @@ out_free:
|
||||
static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
|
||||
struct ssb_boardinfo *bi)
|
||||
{
|
||||
- pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
|
||||
- &bi->vendor);
|
||||
- pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
|
||||
- &bi->type);
|
||||
- pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
|
||||
- &bi->rev);
|
||||
+ bi->vendor = bus->host_pci->subsystem_vendor;
|
||||
+ bi->type = bus->host_pci->subsystem_device;
|
||||
+ bi->rev = bus->host_pci->revision;
|
||||
}
|
||||
|
||||
int ssb_pci_get_invariants(struct ssb_bus *bus,
|
||||
--- a/drivers/ssb/pcihost_wrapper.c
|
||||
+++ b/drivers/ssb/pcihost_wrapper.c
|
||||
@@ -53,8 +53,8 @@ static int ssb_pcihost_resume(struct pci
|
||||
@@ -213,3 +243,23 @@
|
||||
bus->chip_package = 0;
|
||||
} else {
|
||||
bus->chip_id = 0x4710;
|
||||
--- a/include/linux/ssb/ssb.h
|
||||
+++ b/include/linux/ssb/ssb.h
|
||||
@@ -27,6 +27,8 @@ struct ssb_sprom {
|
||||
u8 et1mdcport; /* MDIO for enet1 */
|
||||
u8 board_rev; /* Board revision number from SPROM. */
|
||||
u8 country_code; /* Country Code */
|
||||
+ u16 leddc_on_time; /* LED Powersave Duty Cycle On Count */
|
||||
+ u16 leddc_off_time; /* LED Powersave Duty Cycle Off Count */
|
||||
u8 ant_available_a; /* 2GHz antenna available bits (up to 4) */
|
||||
u8 ant_available_bg; /* 5GHz antenna available bits (up to 4) */
|
||||
u16 pa0b0;
|
||||
@@ -99,7 +101,7 @@ struct ssb_sprom {
|
||||
struct ssb_boardinfo {
|
||||
u16 vendor;
|
||||
u16 type;
|
||||
- u16 rev;
|
||||
+ u8 rev;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -12,17 +12,33 @@
|
||||
config BCMA_HOST_PCI_POSSIBLE
|
||||
bool
|
||||
depends on BCMA && PCI = y
|
||||
@@ -22,6 +27,12 @@ config BCMA_HOST_PCI
|
||||
bool "Support for BCMA on PCI-host bus"
|
||||
depends on BCMA_HOST_PCI_POSSIBLE
|
||||
|
||||
+config BCMA_DRIVER_PCI_HOSTMODE
|
||||
+ bool "Driver for PCI core working in hostmode"
|
||||
+ depends on BCMA && MIPS
|
||||
+ help
|
||||
+ PCI core hostmode operation (external PCI bus).
|
||||
+
|
||||
config BCMA_DEBUG
|
||||
bool "BCMA debugging"
|
||||
depends on BCMA
|
||||
--- a/drivers/bcma/Makefile
|
||||
+++ b/drivers/bcma/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
@@ -1,6 +1,7 @@
|
||||
-bcma-y += main.o scan.o core.o
|
||||
+bcma-y += main.o scan.o core.o sprom.o
|
||||
bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
|
||||
bcma-y += driver_pci.o
|
||||
+bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
|
||||
bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
|
||||
obj-$(CONFIG_BCMA) += bcma.o
|
||||
|
||||
--- a/drivers/bcma/bcma_private.h
|
||||
+++ b/drivers/bcma/bcma_private.h
|
||||
@@ -13,12 +13,15 @@
|
||||
@@ -13,16 +13,23 @@
|
||||
struct bcma_bus;
|
||||
|
||||
/* main.c */
|
||||
@@ -40,6 +56,14 @@
|
||||
#ifdef CONFIG_BCMA_HOST_PCI
|
||||
/* host_pci.c */
|
||||
extern int __init bcma_host_pci_init(void);
|
||||
extern void __exit bcma_host_pci_exit(void);
|
||||
#endif /* CONFIG_BCMA_HOST_PCI */
|
||||
|
||||
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
|
||||
+void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
|
||||
+#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
|
||||
+
|
||||
#endif
|
||||
--- a/drivers/bcma/core.c
|
||||
+++ b/drivers/bcma/core.c
|
||||
@@ -19,7 +19,7 @@ bool bcma_core_is_enabled(struct bcma_de
|
||||
@@ -59,6 +83,82 @@
|
||||
|
||||
int bcma_core_enable(struct bcma_device *core, u32 flags)
|
||||
{
|
||||
@@ -49,3 +50,75 @@ int bcma_core_enable(struct bcma_device
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcma_core_enable);
|
||||
+
|
||||
+void bcma_core_set_clockmode(struct bcma_device *core,
|
||||
+ enum bcma_clkmode clkmode)
|
||||
+{
|
||||
+ u16 i;
|
||||
+
|
||||
+ WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
|
||||
+ core->id.id != BCMA_CORE_PCIE &&
|
||||
+ core->id.id != BCMA_CORE_80211);
|
||||
+
|
||||
+ switch (clkmode) {
|
||||
+ case BCMA_CLKMODE_FAST:
|
||||
+ bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
|
||||
+ udelay(64);
|
||||
+ for (i = 0; i < 1500; i++) {
|
||||
+ if (bcma_read32(core, BCMA_CLKCTLST) &
|
||||
+ BCMA_CLKCTLST_HAVEHT) {
|
||||
+ i = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ udelay(10);
|
||||
+ }
|
||||
+ if (i)
|
||||
+ pr_err("HT force timeout\n");
|
||||
+ break;
|
||||
+ case BCMA_CLKMODE_DYNAMIC:
|
||||
+ pr_warn("Dynamic clockmode not supported yet!\n");
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
|
||||
+
|
||||
+void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
|
||||
+{
|
||||
+ u16 i;
|
||||
+
|
||||
+ WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
|
||||
+ WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
|
||||
+
|
||||
+ if (on) {
|
||||
+ bcma_set32(core, BCMA_CLKCTLST, req);
|
||||
+ for (i = 0; i < 10000; i++) {
|
||||
+ if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
|
||||
+ status) {
|
||||
+ i = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+ udelay(10);
|
||||
+ }
|
||||
+ if (i)
|
||||
+ pr_err("PLL enable timeout\n");
|
||||
+ } else {
|
||||
+ pr_warn("Disabling PLL not supported yet!\n");
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
|
||||
+
|
||||
+u32 bcma_core_dma_translation(struct bcma_device *core)
|
||||
+{
|
||||
+ switch (core->bus->hosttype) {
|
||||
+ case BCMA_HOSTTYPE_PCI:
|
||||
+ if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
|
||||
+ return BCMA_DMA_TRANSLATION_DMA64_CMT;
|
||||
+ else
|
||||
+ return BCMA_DMA_TRANSLATION_DMA32_CMT;
|
||||
+ default:
|
||||
+ pr_err("DMA translation unknown for host %d\n",
|
||||
+ core->bus->hosttype);
|
||||
+ }
|
||||
+ return BCMA_DMA_TRANSLATION_NONE;
|
||||
+}
|
||||
+EXPORT_SYMBOL(bcma_core_dma_translation);
|
||||
--- a/drivers/bcma/driver_chipcommon_pmu.c
|
||||
+++ b/drivers/bcma/driver_chipcommon_pmu.c
|
||||
@@ -53,6 +53,7 @@ static void bcma_pmu_resources_init(stru
|
||||
@@ -94,11 +194,52 @@
|
||||
bus->chipinfo.id);
|
||||
--- a/drivers/bcma/driver_pci.c
|
||||
+++ b/drivers/bcma/driver_pci.c
|
||||
@@ -161,3 +161,27 @@ void bcma_core_pci_init(struct bcma_drv_
|
||||
@@ -157,7 +157,67 @@ static void bcma_pcicore_serdes_workarou
|
||||
* Init.
|
||||
**************************************************/
|
||||
|
||||
-void bcma_core_pci_init(struct bcma_drv_pci *pc)
|
||||
+static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
|
||||
{
|
||||
bcma_pcicore_serdes_workaround(pc);
|
||||
}
|
||||
+
|
||||
+static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
|
||||
+{
|
||||
+ struct bcma_bus *bus = pc->core->bus;
|
||||
+ u16 chipid_top;
|
||||
+
|
||||
+ chipid_top = (bus->chipinfo.id & 0xFF00);
|
||||
+ if (chipid_top != 0x4700 &&
|
||||
+ chipid_top != 0x5300)
|
||||
+ return false;
|
||||
+
|
||||
+ if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
|
||||
+ return false;
|
||||
+
|
||||
+#if 0
|
||||
+ /* TODO: on BCMA we use address from EROM instead of magic formula */
|
||||
+ u32 tmp;
|
||||
+ return !mips_busprobe32(tmp, (bus->mmio +
|
||||
+ (pc->core->core_index * BCMA_CORE_SIZE)));
|
||||
+#endif
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+void bcma_core_pci_init(struct bcma_drv_pci *pc)
|
||||
+{
|
||||
+ if (bcma_core_pci_is_in_hostmode(pc)) {
|
||||
+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
|
||||
+ bcma_core_pci_hostmode_init(pc);
|
||||
+#else
|
||||
+ pr_err("Driver compiled without support for hostmode PCI\n");
|
||||
+#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
|
||||
+ } else {
|
||||
+ bcma_core_pci_clientmode_init(pc);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
|
||||
+ bool enable)
|
||||
+{
|
||||
@@ -217,13 +358,15 @@
|
||||
break;
|
||||
case BCMA_HOSTTYPE_NONE:
|
||||
case BCMA_HOSTTYPE_SDIO:
|
||||
@@ -144,6 +147,13 @@ int bcma_bus_register(struct bcma_bus *b
|
||||
@@ -144,6 +147,15 @@ int bcma_bus_register(struct bcma_bus *b
|
||||
bcma_core_pci_init(&bus->drv_pci);
|
||||
}
|
||||
|
||||
+ /* Try to get SPROM */
|
||||
+ err = bcma_sprom_get(bus);
|
||||
+ if (err) {
|
||||
+ if (err == -ENOENT) {
|
||||
+ pr_err("No SPROM available\n");
|
||||
+ } else if (err) {
|
||||
+ pr_err("Failed to get SPROM: %d\n", err);
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
@@ -231,7 +374,7 @@
|
||||
/* Register found cores */
|
||||
bcma_register_cores(bus);
|
||||
|
||||
@@ -151,13 +161,11 @@ int bcma_bus_register(struct bcma_bus *b
|
||||
@@ -151,13 +163,11 @@ int bcma_bus_register(struct bcma_bus *b
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -247,7 +390,7 @@
|
||||
{
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/sprom.c
|
||||
@@ -0,0 +1,162 @@
|
||||
@@ -0,0 +1,171 @@
|
||||
+/*
|
||||
+ * Broadcom specific AMBA
|
||||
+ * SPROM reading
|
||||
@@ -270,12 +413,12 @@
|
||||
+ * R/W ops.
|
||||
+ **************************************************/
|
||||
+
|
||||
+static void bcma_sprom_read(struct bcma_bus *bus, u16 *sprom)
|
||||
+static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
|
||||
+ sprom[i] = bcma_read16(bus->drv_cc.core,
|
||||
+ BCMA_CC_SPROM + (i * 2));
|
||||
+ offset + (i * 2));
|
||||
+}
|
||||
+
|
||||
+/**************************************************
|
||||
@@ -362,7 +505,7 @@
|
||||
+ return err;
|
||||
+
|
||||
+ revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
|
||||
+ if (revision != 8) {
|
||||
+ if (revision != 8 && revision != 9) {
|
||||
+ pr_err("Unsupported SPROM revision: %d\n", revision);
|
||||
+ return -ENOENT;
|
||||
+ }
|
||||
@@ -387,18 +530,27 @@
|
||||
+
|
||||
+int bcma_sprom_get(struct bcma_bus *bus)
|
||||
+{
|
||||
+ u16 offset;
|
||||
+ u16 *sprom;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ if (!bus->drv_cc.core)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!sprom)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ bcma_sprom_read(bus, sprom);
|
||||
+ /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
|
||||
+ * According to brcm80211 this applies to cards with PCIe rev >= 6
|
||||
+ * TODO: understand this condition and use it */
|
||||
+ offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
|
||||
+ BCMA_CC_SPROM_PCIE6;
|
||||
+ bcma_sprom_read(bus, offset, sprom);
|
||||
+
|
||||
+ err = bcma_sprom_valid(sprom);
|
||||
+ if (err)
|
||||
@@ -420,7 +572,19 @@
|
||||
|
||||
#include "bcma_regs.h"
|
||||
|
||||
@@ -31,6 +32,12 @@ struct bcma_host_ops {
|
||||
@@ -24,6 +25,11 @@ struct bcma_chipinfo {
|
||||
u8 pkg;
|
||||
};
|
||||
|
||||
+enum bcma_clkmode {
|
||||
+ BCMA_CLKMODE_FAST,
|
||||
+ BCMA_CLKMODE_DYNAMIC,
|
||||
+};
|
||||
+
|
||||
struct bcma_host_ops {
|
||||
u8 (*read8)(struct bcma_device *core, u16 offset);
|
||||
u16 (*read16)(struct bcma_device *core, u16 offset);
|
||||
@@ -31,6 +37,12 @@ struct bcma_host_ops {
|
||||
void (*write8)(struct bcma_device *core, u16 offset, u8 value);
|
||||
void (*write16)(struct bcma_device *core, u16 offset, u16 value);
|
||||
void (*write32)(struct bcma_device *core, u16 offset, u32 value);
|
||||
@@ -433,7 +597,7 @@
|
||||
/* Agent ops */
|
||||
u32 (*aread32)(struct bcma_device *core, u16 offset);
|
||||
void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
|
||||
@@ -117,6 +124,8 @@ struct bcma_device {
|
||||
@@ -117,6 +129,8 @@ struct bcma_device {
|
||||
struct bcma_device_id id;
|
||||
|
||||
struct device dev;
|
||||
@@ -442,7 +606,7 @@
|
||||
bool dev_registered;
|
||||
|
||||
u8 core_index;
|
||||
@@ -179,6 +188,10 @@ struct bcma_bus {
|
||||
@@ -179,6 +193,10 @@ struct bcma_bus {
|
||||
|
||||
struct bcma_drv_cc drv_cc;
|
||||
struct bcma_drv_pci drv_pci;
|
||||
@@ -453,7 +617,7 @@
|
||||
};
|
||||
|
||||
extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
|
||||
@@ -208,6 +221,18 @@ void bcma_write32(struct bcma_device *co
|
||||
@@ -208,6 +226,18 @@ void bcma_write32(struct bcma_device *co
|
||||
{
|
||||
core->bus->ops->write32(core, offset, value);
|
||||
}
|
||||
@@ -472,21 +636,56 @@
|
||||
extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
|
||||
{
|
||||
return core->bus->ops->aread32(core, offset);
|
||||
@@ -219,6 +244,7 @@ void bcma_awrite32(struct bcma_device *c
|
||||
@@ -218,7 +248,24 @@ void bcma_awrite32(struct bcma_device *c
|
||||
core->bus->ops->awrite32(core, offset, value);
|
||||
}
|
||||
|
||||
+#define bcma_mask32(cc, offset, mask) \
|
||||
+ bcma_write32(cc, offset, bcma_read32(cc, offset) & (mask))
|
||||
+#define bcma_set32(cc, offset, set) \
|
||||
+ bcma_write32(cc, offset, bcma_read32(cc, offset) | (set))
|
||||
+#define bcma_maskset32(cc, offset, mask, set) \
|
||||
+ bcma_write32(cc, offset, (bcma_read32(cc, offset) & (mask)) | (set))
|
||||
+
|
||||
extern bool bcma_core_is_enabled(struct bcma_device *core);
|
||||
+extern void bcma_core_disable(struct bcma_device *core, u32 flags);
|
||||
extern int bcma_core_enable(struct bcma_device *core, u32 flags);
|
||||
+extern void bcma_core_set_clockmode(struct bcma_device *core,
|
||||
+ enum bcma_clkmode clkmode);
|
||||
+extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
|
||||
+ bool on);
|
||||
+#define BCMA_DMA_TRANSLATION_MASK 0xC0000000
|
||||
+#define BCMA_DMA_TRANSLATION_NONE 0x00000000
|
||||
+#define BCMA_DMA_TRANSLATION_DMA32_CMT 0x40000000 /* Client Mode Translation for 32-bit DMA */
|
||||
+#define BCMA_DMA_TRANSLATION_DMA64_CMT 0x80000000 /* Client Mode Translation for 64-bit DMA */
|
||||
+extern u32 bcma_core_dma_translation(struct bcma_device *core);
|
||||
|
||||
#endif /* LINUX_BCMA_H_ */
|
||||
--- a/include/linux/bcma/bcma_driver_chipcommon.h
|
||||
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
|
||||
@@ -244,6 +244,7 @@
|
||||
@@ -179,15 +179,7 @@
|
||||
#define BCMA_CC_PROG_WAITCNT 0x0124
|
||||
#define BCMA_CC_FLASH_CFG 0x0128
|
||||
#define BCMA_CC_FLASH_WAITCNT 0x012C
|
||||
-#define BCMA_CC_CLKCTLST 0x01E0 /* Clock control and status (rev >= 20) */
|
||||
-#define BCMA_CC_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
|
||||
-#define BCMA_CC_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
|
||||
-#define BCMA_CC_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
|
||||
-#define BCMA_CC_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
|
||||
-#define BCMA_CC_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
|
||||
-#define BCMA_CC_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
|
||||
-#define BCMA_CC_CLKCTLST_HAVEHT 0x00010000 /* HT available */
|
||||
-#define BCMA_CC_CLKCTLST_HAVEALP 0x00020000 /* APL available */
|
||||
+/* 0x1E0 is defined as shared BCMA_CLKCTLST */
|
||||
#define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
|
||||
#define BCMA_CC_UART0_DATA 0x0300
|
||||
#define BCMA_CC_UART0_IMR 0x0304
|
||||
@@ -244,6 +236,8 @@
|
||||
#define BCMA_CC_REGCTL_DATA 0x065C
|
||||
#define BCMA_CC_PLLCTL_ADDR 0x0660
|
||||
#define BCMA_CC_PLLCTL_DATA 0x0664
|
||||
+#define BCMA_CC_SPROM 0x0830 /* SPROM beginning */
|
||||
+#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
|
||||
+#define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */
|
||||
|
||||
/* Data for the PMU, if available.
|
||||
* Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
|
||||
@@ -500,3 +699,92 @@
|
||||
+ struct bcma_device *core, bool enable);
|
||||
|
||||
#endif /* LINUX_BCMA_DRIVER_PCI_H_ */
|
||||
--- a/drivers/bcma/driver_chipcommon.c
|
||||
+++ b/drivers/bcma/driver_chipcommon.c
|
||||
@@ -23,6 +23,9 @@ static inline u32 bcma_cc_write32_masked
|
||||
|
||||
void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
|
||||
{
|
||||
+ u32 leddc_on = 10;
|
||||
+ u32 leddc_off = 90;
|
||||
+
|
||||
if (cc->core->id.rev >= 11)
|
||||
cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
|
||||
cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
|
||||
@@ -38,6 +41,17 @@ void bcma_core_chipcommon_init(struct bc
|
||||
bcma_pmu_init(cc);
|
||||
if (cc->capabilities & BCMA_CC_CAP_PCTL)
|
||||
pr_err("Power control not implemented!\n");
|
||||
+
|
||||
+ if (cc->core->id.rev >= 16) {
|
||||
+ if (cc->core->bus->sprom.leddc_on_time &&
|
||||
+ cc->core->bus->sprom.leddc_off_time) {
|
||||
+ leddc_on = cc->core->bus->sprom.leddc_on_time;
|
||||
+ leddc_off = cc->core->bus->sprom.leddc_off_time;
|
||||
+ }
|
||||
+ bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
|
||||
+ ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
|
||||
+ (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
|
||||
--- /dev/null
|
||||
+++ b/drivers/bcma/driver_pci_host.c
|
||||
@@ -0,0 +1,14 @@
|
||||
+/*
|
||||
+ * Broadcom specific AMBA
|
||||
+ * PCI Core in hostmode
|
||||
+ *
|
||||
+ * Licensed under the GNU/GPL. See COPYING for details.
|
||||
+ */
|
||||
+
|
||||
+#include "bcma_private.h"
|
||||
+#include <linux/bcma/bcma.h>
|
||||
+
|
||||
+void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
|
||||
+{
|
||||
+ pr_err("No support for PCI core in hostmode yet\n");
|
||||
+}
|
||||
--- a/include/linux/bcma/bcma_regs.h
|
||||
+++ b/include/linux/bcma/bcma_regs.h
|
||||
@@ -1,13 +1,38 @@
|
||||
#ifndef LINUX_BCMA_REGS_H_
|
||||
#define LINUX_BCMA_REGS_H_
|
||||
|
||||
+/* Some single registers are shared between many cores */
|
||||
+/* BCMA_CLKCTLST: ChipCommon (rev >= 20), PCIe, 80211 */
|
||||
+#define BCMA_CLKCTLST 0x01E0 /* Clock control and status */
|
||||
+#define BCMA_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
|
||||
+#define BCMA_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
|
||||
+#define BCMA_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
|
||||
+#define BCMA_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
|
||||
+#define BCMA_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
|
||||
+#define BCMA_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
|
||||
+#define BCMA_CLKCTLST_EXTRESREQ 0x00000700 /* Mask of external resource requests */
|
||||
+#define BCMA_CLKCTLST_HAVEALP 0x00010000 /* ALP available */
|
||||
+#define BCMA_CLKCTLST_HAVEHT 0x00020000 /* HT available */
|
||||
+#define BCMA_CLKCTLST_BP_ON_ALP 0x00040000 /* RO: running on ALP clock */
|
||||
+#define BCMA_CLKCTLST_BP_ON_HT 0x00080000 /* RO: running on HT clock */
|
||||
+#define BCMA_CLKCTLST_EXTRESST 0x07000000 /* Mask of external resource status */
|
||||
+/* Is there any BCM4328 on BCMA bus? */
|
||||
+#define BCMA_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */
|
||||
+#define BCMA_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */
|
||||
+
|
||||
/* Agent registers (common for every core) */
|
||||
-#define BCMA_IOCTL 0x0408
|
||||
+#define BCMA_IOCTL 0x0408 /* IO control */
|
||||
#define BCMA_IOCTL_CLK 0x0001
|
||||
#define BCMA_IOCTL_FGC 0x0002
|
||||
#define BCMA_IOCTL_CORE_BITS 0x3FFC
|
||||
#define BCMA_IOCTL_PME_EN 0x4000
|
||||
#define BCMA_IOCTL_BIST_EN 0x8000
|
||||
+#define BCMA_IOST 0x0500 /* IO status */
|
||||
+#define BCMA_IOST_CORE_BITS 0x0FFF
|
||||
+#define BCMA_IOST_DMA64 0x1000
|
||||
+#define BCMA_IOST_GATED_CLK 0x2000
|
||||
+#define BCMA_IOST_BIST_ERROR 0x4000
|
||||
+#define BCMA_IOST_BIST_DONE 0x8000
|
||||
#define BCMA_RESET_CTL 0x0800
|
||||
#define BCMA_RESET_CTL_RESET 0x0001
|
||||
|
||||
|
||||
@@ -17,3 +17,13 @@
|
||||
|
||||
config SSB_PCMCIAHOST_POSSIBLE
|
||||
bool
|
||||
--- a/drivers/bcma/Kconfig
|
||||
+++ b/drivers/bcma/Kconfig
|
||||
@@ -17,6 +17,7 @@ config BCMA
|
||||
config BCMA_BLOCKIO
|
||||
bool
|
||||
depends on BCMA
|
||||
+ default y
|
||||
|
||||
config BCMA_HOST_PCI_POSSIBLE
|
||||
bool
|
||||
|
||||
Reference in New Issue
Block a user