1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2025-04-21 12:27:27 +03:00

brcm47xx: update bcma and ssb to master-2011-07-21

* add new patches for bcm4716 SoC
* add support for serial flash on bcma bus


git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27723 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
hauke
2011-07-22 16:30:42 +00:00
parent 13a779d3f3
commit 31a40f97ef
42 changed files with 3314 additions and 767 deletions

View File

@@ -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");
+}