From: George Kashperko <george@znau.edu.ua>
To: linux-wireless <linux-wireless@vger.kernel.org>
Subject: Re: [RFC] AI support (11/14 ssb separate SB-specific code)
Date: Fri, 18 Feb 2011 00:27:31 +0200 [thread overview]
Message-ID: <1297981651.23381.32.camel@dev.znau.edu.ua> (raw)
In-Reply-To: <1297980093.13554.5.camel@maggie>
From: George Kashperko <george@znau.edu.ua>
Move SB-specific code to separate file.
Signed-off-by: George Kashperko <george@znau.edu.ua>
---
drivers/ssb/Kconfig | 11 +
drivers/ssb/Makefile | 1
drivers/ssb/driver_mipscore.c | 11 -
drivers/ssb/main.c | 188 --------------------
drivers/ssb/scan.c | 74 --------
drivers/ssb/ssb_private.h | 32 ---
drivers/ssb/ssb_sb.c | 289 ++++++++++++++++++++++++++++++++
drivers/ssb/ssb_sb.h | 52 +++++
8 files changed, 361 insertions(+), 297 deletions(-)
--- linux-wireless-testing.orig/drivers/ssb/driver_mipscore.c 2011-02-17 16:00:21.000000000 +0200
+++ linux-wireless-testing/drivers/ssb/driver_mipscore.c 2011-02-17 15:55:25.000000000 +0200
@@ -52,16 +52,6 @@ static inline u32 ssb_irqflag(struct ssb
return dev->bus->mipscore.irqflag(dev);
}
-static u32 ssb_irqflag_sb(struct ssb_device *dev)
-{
- u32 tpsflag = ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
- if (tpsflag && tpsflag != SSB_TPSFLAG_BPFLAG)
- return tpsflag;
- else
- /* not irq supported */
- return -1;
-}
-
static struct ssb_device *find_device(struct ssb_device *rdev, int irqflag)
{
struct ssb_bus *bus = rdev->bus;
@@ -246,7 +236,6 @@ void ssb_mipscore_init(struct ssb_mipsco
ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n");
bus = mcore->dev->bus;
- bus->mipscore.irqflag = ssb_irqflag_sb;
hz = ssb_clockspeed(bus);
if (!hz)
hz = 100000000;
--- linux-wireless-testing.orig/drivers/ssb/Kconfig 2011-02-17 16:00:21.000000000 +0200
+++ linux-wireless-testing/drivers/ssb/Kconfig 2011-02-17 16:00:43.000000000 +0200
@@ -9,6 +9,7 @@ menu "Sonics Silicon Backplane"
config SSB
tristate "Sonics Silicon Backplane support"
depends on SSB_POSSIBLE
+ select SSB_BUS_SB
help
Support for the Sonics Silicon Backplane bus.
You only need to enable this option, if you are
@@ -21,6 +22,16 @@ config SSB
If unsure, say N.
+config SSB_BUS_SB_POSSIBLE
+ bool
+ default y if SSB
+
+config SSB_BUS_SB
+ bool "SB style bus"
+ depends on SSB_BUS_SB_POSSIBLE
+ help
+ Sonics Silicon Backplane SB-style bus
+
# Common SPROM support routines
config SSB_SPROM
bool
--- linux-wireless-testing.orig/drivers/ssb/main.c 2011-02-17 16:00:21.000000000 +0200
+++ linux-wireless-testing/drivers/ssb/main.c 2011-02-17 16:00:43.000000000 +0200
@@ -1129,88 +1129,10 @@ u32 ssb_clockspeed(struct ssb_bus *bus)
}
EXPORT_SYMBOL(ssb_clockspeed);
-static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev)
-{
- u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV;
-
- /* The REJECT bit changed position in TMSLOW between
- * Backplane revisions. */
- switch (rev) {
- case SSB_IDLOW_SSBREV_22:
- return SSB_TMSLOW_REJECT_22;
- case SSB_IDLOW_SSBREV_23:
- return SSB_TMSLOW_REJECT_23;
- case SSB_IDLOW_SSBREV_24: /* TODO - find the proper REJECT bits */
- case SSB_IDLOW_SSBREV_25: /* same here */
- case SSB_IDLOW_SSBREV_26: /* same here */
- case SSB_IDLOW_SSBREV_27: /* same here */
- return SSB_TMSLOW_REJECT_23; /* this is a guess */
- default:
- printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
- WARN_ON(1);
- }
- return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);
-}
-
-static int ssb_device_is_enabled_sb(struct ssb_device *dev)
-{
- u32 val;
- u32 reject;
-
- reject = ssb_tmslow_reject_bitmask(dev);
- val = ssb_read32(dev, SSB_TMSLOW);
- val &= SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET | reject;
-
- return (val == SSB_TMSLOW_CLOCK);
-}
-
-static void ssb_flush_tmslow(struct ssb_device *dev)
-{
- /* Make _really_ sure the device has finished the TMSLOW
- * register write transaction, as we risk running into
- * a machine check exception otherwise.
- * Do this by reading the register back to commit the
- * PCI write and delay an additional usec for the device
- * to react to the change. */
- ssb_read32(dev, SSB_TMSLOW);
- udelay(1);
-}
-
-static void ssb_device_enable_sb(struct ssb_device *dev, u32 core_specific_flags)
-{
- u32 val;
-
- ssb_device_disable(dev, core_specific_flags);
- core_specific_flags <<= SSB_TMSLOW_FLAGS_SHIFT;
- ssb_write32(dev, SSB_TMSLOW,
- SSB_TMSLOW_RESET | SSB_TMSLOW_CLOCK |
- SSB_TMSLOW_FGC | core_specific_flags);
- ssb_flush_tmslow(dev);
-
- /* Clear SERR if set. This is a hw bug workaround. */
- if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_SERR)
- ssb_write32(dev, SSB_TMSHIGH, 0);
-
- val = ssb_read32(dev, SSB_IMSTATE);
- if (val & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
- val &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
- ssb_write32(dev, SSB_IMSTATE, val);
- }
-
- ssb_write32(dev, SSB_TMSLOW,
- SSB_TMSLOW_CLOCK | SSB_TMSLOW_FGC |
- core_specific_flags);
- ssb_flush_tmslow(dev);
-
- ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_CLOCK |
- core_specific_flags);
- ssb_flush_tmslow(dev);
-}
-
/* Wait for a bit in a register to get set or unset.
* timeout is in units of ten-microseconds */
-static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
- int timeout, int set)
+int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
+ int timeout, int set)
{
int i;
u32 val;
@@ -1233,32 +1155,6 @@ static int ssb_wait_bit(struct ssb_devic
return -ETIMEDOUT;
}
-static void ssb_device_disable_sb(struct ssb_device *dev, u32 core_specific_flags)
-{
- u32 reject;
-
- if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
- return;
-
- SSB_WARN_ON(core_specific_flags & 0xFFFF0000);
-
- core_specific_flags <<= SSB_TMSLOW_FLAGS_SHIFT;
- reject = ssb_tmslow_reject_bitmask(dev);
- ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
- ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1);
- ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
- ssb_write32(dev, SSB_TMSLOW,
- SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
- reject | SSB_TMSLOW_RESET |
- core_specific_flags);
- ssb_flush_tmslow(dev);
-
- ssb_write32(dev, SSB_TMSLOW,
- reject | SSB_TMSLOW_RESET |
- core_specific_flags);
- ssb_flush_tmslow(dev);
-}
-
u32 ssb_dma_translation(struct ssb_device *dev)
{
switch (dev->bus->bustype) {
@@ -1329,86 +1225,6 @@ error:
}
EXPORT_SYMBOL(ssb_bus_powerup);
-static u32 ssb_admatch_base_sb(struct ssb_device *dev, u32 adm)
-{
- u32 base = 0;
-
- adm = ssb_read32(dev, adm);
-
- switch (adm & SSB_ADM_TYPE) {
- case SSB_ADM_TYPE0:
- base = (adm & SSB_ADM_BASE0);
- break;
- case SSB_ADM_TYPE1:
- SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
- base = (adm & SSB_ADM_BASE1);
- break;
- case SSB_ADM_TYPE2:
- SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
- base = (adm & SSB_ADM_BASE2);
- break;
- default:
- SSB_WARN_ON(1);
- }
-
- return base;
-}
-
-static u32 ssb_admatch_size_sb(struct ssb_device *dev, u32 adm)
-{
- u32 size = 0;
-
- adm = ssb_read32(dev, adm);
-
- switch (adm & SSB_ADM_TYPE) {
- case SSB_ADM_TYPE0:
- size = ((adm & SSB_ADM_SZ0) >> SSB_ADM_SZ0_SHIFT);
- break;
- case SSB_ADM_TYPE1:
- SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
- size = ((adm & SSB_ADM_SZ1) >> SSB_ADM_SZ1_SHIFT);
- break;
- case SSB_ADM_TYPE2:
- SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
- size = ((adm & SSB_ADM_SZ2) >> SSB_ADM_SZ2_SHIFT);
- break;
- default:
- SSB_WARN_ON(1);
- }
- size = (1 << (size + 1));
-
- return size;
-}
-
-static u32 ssb_core_ctl_flags_sb(struct ssb_device *dev, u32 mask, u32 val)
-{
- mask = ~mask;
- SSB_WARN_ON((mask | val) & 0xFFFF0000);
- if (mask || val) {
- u32 tmp = (ssb_read32(dev, SSB_TMSLOW) &
- ~(mask << SSB_TMSLOW_FLAGS_SHIFT)) |
- (val << SSB_TMSLOW_FLAGS_SHIFT);
- ssb_write32(dev, SSB_TMSLOW, tmp);
- }
-
- return ssb_read32(dev, SSB_TMSLOW) >> SSB_TMSLOW_FLAGS_SHIFT;
-}
-
-static u32 ssb_core_state_flags_sb(struct ssb_device *dev)
-{
- return ssb_read32(dev, SSB_TMSHIGH) >> SSB_TMSHIGH_FLAGS_SHIFT;
-}
-
-const struct ssb_bus_helpers ssb_helpers_sb = {
- .device_is_enabled = ssb_device_is_enabled_sb,
- .device_enable = ssb_device_enable_sb,
- .device_disable = ssb_device_disable_sb,
- .admatch_base = ssb_admatch_base_sb,
- .admatch_size = ssb_admatch_size_sb,
- .core_ctl_flags = ssb_core_ctl_flags_sb,
- .core_state_flags = ssb_core_state_flags_sb,
-};
-
static int __init ssb_modinit(void)
{
int err;
--- linux-wireless-testing.orig/drivers/ssb/Makefile 2011-02-17 16:00:21.000000000 +0200
+++ linux-wireless-testing/drivers/ssb/Makefile 2011-02-17 16:00:43.000000000 +0200
@@ -1,5 +1,6 @@
# core
ssb-y += main.o scan.o
+ssb-$(CONFIG_SSB_BUS_SB) += ssb_sb.o
ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o
ssb-$(CONFIG_SSB_SPROM) += sprom.o
--- linux-wireless-testing.orig/drivers/ssb/scan.c 2011-02-17 16:00:21.000000000 +0200
+++ linux-wireless-testing/drivers/ssb/scan.c 2011-02-17 16:00:47.000000000 +0200
@@ -157,8 +157,7 @@ static u8 chipid_to_nrcores(u16 chipid)
return 1;
}
-static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
- u16 offset)
+u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx, u16 offset)
{
u32 lo, hi;
@@ -184,42 +183,6 @@ static u32 scan_read32(struct ssb_bus *b
return readl(bus->mmio + offset);
}
-static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
-{
- switch (bus->bustype) {
- case SSB_BUSTYPE_SSB:
- break;
- case SSB_BUSTYPE_PCI:
- return ssb_pci_switch_coreidx(bus, coreidx);
- case SSB_BUSTYPE_PCMCIA:
- return ssb_pcmcia_switch_coreidx(bus, coreidx);
- case SSB_BUSTYPE_SDIO:
- return ssb_sdio_scan_switch_coreidx(bus, coreidx);
- }
- return 0;
-}
-
-void ssb_iounmap_sb(struct ssb_bus *bus)
-{
- switch (bus->bustype) {
- case SSB_BUSTYPE_SSB:
- case SSB_BUSTYPE_PCMCIA:
- iounmap(bus->mmio);
- break;
- case SSB_BUSTYPE_PCI:
-#ifdef CONFIG_SSB_PCIHOST
- pci_iounmap(bus->host_pci, bus->mmio);
-#else
- SSB_BUG_ON(1); /* Can't reach this code. */
-#endif
- break;
- case SSB_BUSTYPE_SDIO:
- break;
- }
- bus->mmio = NULL;
- bus->mapped_device = NULL;
-}
-
static void __iomem *ssb_ioremap(struct ssb_bus *bus,
unsigned long baseaddr)
{
@@ -407,41 +370,6 @@ static int ssb_bus_detect(struct ssb_bus
return chiptype == SSB_CHIPCO_SB ? 0 : -ENODEV;
}
-static int ssb_bus_scan_sb(struct ssb_bus *bus, unsigned long baseaddr)
-{
- u32 idhi;
- int dev_i, i;
- struct ssb_device *dev;
- int nr_80211_cores = 0;
- int err;
-
- /* Fetch basic information about each core/device */
- for (i = 0, dev_i = 0; i < bus->nr_devices; i++) {
- err = scan_switchcore(bus, i);
- if (err)
- return err;
- dev = &(bus->devices[dev_i]);
-
- idhi = scan_read32(bus, i, SSB_IDHIGH);
- dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
- dev->id.revision = (idhi & SSB_IDHIGH_RCLO);
- dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >>
- SSB_IDHIGH_RCHI_SHIFT;
- dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT;
- dev->core_index = i;
- dev->bus = bus;
- dev->ops = bus->ops;
- dev->helpers = &ssb_helpers_sb;
-
- if (ssb_bus_check_core(dev, &nr_80211_cores, i) < 0)
- continue;
-
- dev_i++;
- }
- bus->nr_devices = dev_i;
- return 0;
-}
-
int ssb_bus_scan(struct ssb_bus *bus, unsigned long baseaddr)
{
int err = -ENOMEM;
--- linux-wireless-testing.orig/drivers/ssb/ssb_private.h 2011-02-17 16:00:21.000000000 +0200
+++ linux-wireless-testing/drivers/ssb/ssb_private.h 2011-02-17 16:00:43.000000000 +0200
@@ -3,6 +3,7 @@
#include <linux/ssb/ssb.h>
#include <linux/types.h>
+#include "ssb_sb.h"
#define PFX "ssb: "
@@ -29,6 +30,9 @@ static inline int __ssb_do_nothing(int x
# define SSB_BUG_ON(x) __ssb_do_nothing(unlikely(!!(x)))
#endif
+/* main.c */
+extern int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
+ int timeout, int set);
/* pci.c */
#ifdef CONFIG_SSB_PCIHOST
@@ -159,9 +163,9 @@ static inline int ssb_sdio_init(struct s
extern const char *ssb_core_name(u16 coreid);
extern int ssb_bus_scan(struct ssb_bus *bus,
unsigned long baseaddr);
-extern void ssb_iounmap_sb(struct ssb_bus *bus);
extern int ssb_bus_check_core(struct ssb_device *dev, int *nr_80211_cores,
int corenum);
+extern u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx, u16 offset);
static inline void ssb_iounmap(struct ssb_bus *bus)
{
ssb_iounmap_sb(bus);
@@ -212,30 +216,4 @@ static inline void b43_pci_ssb_bridge_ex
}
#endif /* CONFIG_SSB_B43_PCI_BRIDGE */
-extern const struct ssb_bus_helpers ssb_helpers_sb;
-
-/* SB-style bus core control and state registers */
-#define SSB_TMSLOW 0x0F98 /* SB Target State Low */
-#define SSB_TMSLOW_RESET 0x00000001 /* Reset */
-#define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */
-#define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */
-#define SSB_TMSLOW_PHYCLK 0x00000010 /* MAC PHY Clock Control Enable */
-#define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */
-#define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */
-#define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */
-#define SSB_TMSLOW_BE 0x80000000 /* BIST Enable */
-#define SSB_TMSLOW_FLAGS_SHIFT 16 /* Flags shift for TMSLOW
- * register of SB-style buses */
-#define SSB_TMSHIGH 0x0F9C /* SB Target State High */
-#define SSB_TMSHIGH_SERR 0x00000001 /* S-error */
-#define SSB_TMSHIGH_INT 0x00000002 /* Interrupt */
-#define SSB_TMSHIGH_BUSY 0x00000004 /* Busy */
-#define SSB_TMSHIGH_TO 0x00000020 /* Timeout. Backplane rev >= 2.3 only */
-#define SSB_TMSHIGH_DMA64 0x10000000 /* 64bit DMA supported */
-#define SSB_TMSHIGH_GCR 0x20000000 /* Gated Clock Request */
-#define SSB_TMSHIGH_BISTF 0x40000000 /* BIST Failed */
-#define SSB_TMSHIGH_BISTD 0x80000000 /* BIST Done */
-#define SSB_TMSHIGH_FLAGS_SHIFT 16 /* Flags shift for TMSHIGH
- * register of SB-style buses */
-
#endif /* LINUX_SSB_PRIVATE_H_ */
--- linux-wireless-testing.orig/drivers/ssb/ssb_sb.c 1970-01-01 03:00:00.000000000 +0300
+++ linux-wireless-testing/drivers/ssb/ssb_sb.c 2011-02-17 16:01:30.000000000 +0200
@@ -0,0 +1,289 @@
+/*
+ * Sonics Silicon Backplane
+ * SB-specific Subsystem core
+ *
+ * Copyright 2005, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include <linux/ssb/ssb.h>
+#include <linux/delay.h>
+
+#include "ssb_private.h"
+
+
+static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev)
+{
+ u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV;
+
+ /* The REJECT bit changed position in TMSLOW between
+ * Backplane revisions. */
+ switch (rev) {
+ case SSB_IDLOW_SSBREV_22:
+ return SSB_TMSLOW_REJECT_22;
+ case SSB_IDLOW_SSBREV_23:
+ return SSB_TMSLOW_REJECT_23;
+ case SSB_IDLOW_SSBREV_24: /* TODO - find the proper REJECT bits */
+ case SSB_IDLOW_SSBREV_25: /* same here */
+ case SSB_IDLOW_SSBREV_26: /* same here */
+ case SSB_IDLOW_SSBREV_27: /* same here */
+ return SSB_TMSLOW_REJECT_23; /* this is a guess */
+ default:
+ printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
+ WARN_ON(1);
+ }
+ return SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23;
+}
+
+static int ssb_device_is_enabled_sb(struct ssb_device *dev)
+{
+ u32 val;
+ u32 reject;
+
+ reject = ssb_tmslow_reject_bitmask(dev);
+ val = ssb_read32(dev, SSB_TMSLOW);
+ val &= SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET | reject;
+
+ return (val == SSB_TMSLOW_CLOCK);
+}
+
+static void ssb_flush_tmslow(struct ssb_device *dev)
+{
+ /* Make _really_ sure the device has finished the TMSLOW
+ * register write transaction, as we risk running into
+ * a machine check exception otherwise.
+ * Do this by reading the register back to commit the
+ * PCI write and delay an additional usec for the device
+ * to react to the change. */
+ ssb_read32(dev, SSB_TMSLOW);
+ udelay(1);
+}
+
+static void ssb_device_disable_sb(struct ssb_device *dev,
+ u32 core_specific_flags)
+{
+ u32 reject;
+
+ if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
+ return;
+
+ SSB_WARN_ON(core_specific_flags & 0xFFFF0000);
+
+ core_specific_flags <<= SSB_TMSLOW_FLAGS_SHIFT;
+ reject = ssb_tmslow_reject_bitmask(dev);
+ ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
+ ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1);
+ ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
+ ssb_write32(dev, SSB_TMSLOW,
+ SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
+ reject | SSB_TMSLOW_RESET |
+ core_specific_flags);
+ ssb_flush_tmslow(dev);
+
+ ssb_write32(dev, SSB_TMSLOW,
+ reject | SSB_TMSLOW_RESET |
+ core_specific_flags);
+ ssb_flush_tmslow(dev);
+}
+
+
+static void ssb_device_enable_sb(struct ssb_device *dev,
+ u32 core_specific_flags)
+{
+ u32 val;
+
+ ssb_device_disable_sb(dev, core_specific_flags);
+ core_specific_flags <<= SSB_TMSLOW_FLAGS_SHIFT;
+ ssb_write32(dev, SSB_TMSLOW,
+ SSB_TMSLOW_RESET | SSB_TMSLOW_CLOCK |
+ SSB_TMSLOW_FGC | core_specific_flags);
+ ssb_flush_tmslow(dev);
+
+ /* Clear SERR if set. This is a hw bug workaround. */
+ if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_SERR)
+ ssb_write32(dev, SSB_TMSHIGH, 0);
+
+ val = ssb_read32(dev, SSB_IMSTATE);
+ if (val & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
+ val &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
+ ssb_write32(dev, SSB_IMSTATE, val);
+ }
+
+ ssb_write32(dev, SSB_TMSLOW,
+ SSB_TMSLOW_CLOCK | SSB_TMSLOW_FGC |
+ core_specific_flags);
+ ssb_flush_tmslow(dev);
+
+ ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_CLOCK |
+ core_specific_flags);
+ ssb_flush_tmslow(dev);
+}
+
+static u32 ssb_admatch_base_sb(struct ssb_device *dev, u32 adm)
+{
+ u32 base = 0;
+
+ adm = ssb_read32(dev, adm);
+
+ switch (adm & SSB_ADM_TYPE) {
+ case SSB_ADM_TYPE0:
+ base = (adm & SSB_ADM_BASE0);
+ break;
+ case SSB_ADM_TYPE1:
+ SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
+ base = (adm & SSB_ADM_BASE1);
+ break;
+ case SSB_ADM_TYPE2:
+ SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
+ base = (adm & SSB_ADM_BASE2);
+ break;
+ default:
+ SSB_WARN_ON(1);
+ }
+
+ return base;
+}
+
+static u32 ssb_admatch_size_sb(struct ssb_device *dev, u32 adm)
+{
+ u32 size = 0;
+
+ adm = ssb_read32(dev, adm);
+
+ switch (adm & SSB_ADM_TYPE) {
+ case SSB_ADM_TYPE0:
+ size = ((adm & SSB_ADM_SZ0) >> SSB_ADM_SZ0_SHIFT);
+ break;
+ case SSB_ADM_TYPE1:
+ SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
+ size = ((adm & SSB_ADM_SZ1) >> SSB_ADM_SZ1_SHIFT);
+ break;
+ case SSB_ADM_TYPE2:
+ SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
+ size = ((adm & SSB_ADM_SZ2) >> SSB_ADM_SZ2_SHIFT);
+ break;
+ default:
+ SSB_WARN_ON(1);
+ }
+ size = (1 << (size + 1));
+
+ return size;
+}
+
+static u32 ssb_core_ctl_flags_sb(struct ssb_device *dev, u32 mask, u32 val)
+{
+ mask = ~mask;
+ SSB_WARN_ON((mask | val) & 0xFFFF0000);
+ if (mask || val) {
+ u32 tmp = (ssb_read32(dev, SSB_TMSLOW) &
+ ~(mask << SSB_TMSLOW_FLAGS_SHIFT)) |
+ (val << SSB_TMSLOW_FLAGS_SHIFT);
+ ssb_write32(dev, SSB_TMSLOW, tmp);
+ }
+
+ return ssb_read32(dev, SSB_TMSLOW) >> SSB_TMSLOW_FLAGS_SHIFT;
+}
+
+static u32 ssb_core_state_flags_sb(struct ssb_device *dev)
+{
+ return ssb_read32(dev, SSB_TMSHIGH) >> SSB_TMSHIGH_FLAGS_SHIFT;
+}
+
+const struct ssb_bus_helpers ssb_helpers_sb = {
+ .device_is_enabled = ssb_device_is_enabled_sb,
+ .device_enable = ssb_device_enable_sb,
+ .device_disable = ssb_device_disable_sb,
+ .admatch_base = ssb_admatch_base_sb,
+ .admatch_size = ssb_admatch_size_sb,
+ .core_ctl_flags = ssb_core_ctl_flags_sb,
+ .core_state_flags = ssb_core_state_flags_sb,
+};
+
+#ifdef CONFIG_SSB_DRIVER_MIPS
+static u32 ssb_irqflag_sb(struct ssb_device *dev)
+{
+ u32 tpsflag = ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
+ if (tpsflag && tpsflag != SSB_TPSFLAG_BPFLAG)
+ return tpsflag;
+ else
+ /* not irq supported */
+ return -1;
+}
+#endif /* CONFIG_SSB_DRIVER_MIPS */
+
+int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
+{
+ switch (bus->bustype) {
+ case SSB_BUSTYPE_SSB:
+ break;
+ case SSB_BUSTYPE_PCI:
+ return ssb_pci_switch_coreidx(bus, coreidx);
+ case SSB_BUSTYPE_PCMCIA:
+ return ssb_pcmcia_switch_coreidx(bus, coreidx);
+ case SSB_BUSTYPE_SDIO:
+ return ssb_sdio_scan_switch_coreidx(bus, coreidx);
+ }
+ return 0;
+}
+
+void ssb_iounmap_sb(struct ssb_bus *bus)
+{
+ switch (bus->bustype) {
+ case SSB_BUSTYPE_SSB:
+ case SSB_BUSTYPE_PCMCIA:
+ iounmap(bus->mmio);
+ break;
+#ifdef CONFIG_SSB_PCIHOST
+ case SSB_BUSTYPE_PCI:
+ pci_iounmap(bus->host_pci, bus->mmio);
+#else
+ SSB_BUG_ON(1); /* Can't reach this code. */
+#endif
+ break;
+ case SSB_BUSTYPE_SDIO:
+ break;
+ }
+ bus->mmio = NULL;
+ bus->mapped_device = NULL;
+}
+
+int ssb_bus_scan_sb(struct ssb_bus *bus, unsigned long baseaddr)
+{
+ u32 idhi;
+ int dev_i, i;
+ struct ssb_device *dev;
+ int nr_80211_cores = 0;
+ int err;
+
+#ifdef CONFIG_SSB_DRIVER_MIPS
+ bus->mipscore.irqflag = ssb_irqflag_sb;
+#endif /* CONFIG_SSB_DRIVER_MIPS */
+
+ /* Fetch basic information about each core/device */
+ for (i = 0, dev_i = 0; i < bus->nr_devices; i++) {
+ err = scan_switchcore(bus, i);
+ if (err)
+ return err;
+ dev = &(bus->devices[dev_i]);
+
+ idhi = scan_read32(bus, i, SSB_IDHIGH);
+ dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
+ dev->id.revision = (idhi & SSB_IDHIGH_RCLO);
+ dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >>
+ SSB_IDHIGH_RCHI_SHIFT;
+ dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT;
+ dev->core_index = i;
+ dev->bus = bus;
+ dev->ops = bus->ops;
+ dev->helpers = &ssb_helpers_sb;
+
+ if (ssb_bus_check_core(dev, &nr_80211_cores, i) < 0)
+ continue;
+
+ dev_i++;
+ }
+ bus->nr_devices = dev_i;
+ return 0;
+}
--- linux-wireless-testing.orig/drivers/ssb/ssb_sb.h 1970-01-01 03:00:00.000000000 +0300
+++ linux-wireless-testing/drivers/ssb/ssb_sb.h 2011-02-17 15:55:25.000000000 +0200
@@ -0,0 +1,52 @@
+#ifndef LINUX_SSB_SB_H_
+#define LINUX_SSB_SB_H_
+
+#ifdef CONFIG_SSB_BUS_SB
+
+/* SB-style bus core control and state registers */
+#define SSB_TMSLOW 0x0F98 /* SB Target State Low */
+#define SSB_TMSLOW_RESET 0x00000001 /* Reset */
+#define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */
+#define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */
+#define SSB_TMSLOW_PHYCLK 0x00000010 /* MAC PHY Clock Control Enable */
+#define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */
+#define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */
+#define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */
+#define SSB_TMSLOW_BE 0x80000000 /* BIST Enable */
+#define SSB_TMSLOW_FLAGS_SHIFT 16 /* Flags shift for TMSLOW
+ * register of SB-style buses */
+#define SSB_TMSHIGH 0x0F9C /* SB Target State High */
+#define SSB_TMSHIGH_SERR 0x00000001 /* S-error */
+#define SSB_TMSHIGH_INT 0x00000002 /* Interrupt */
+#define SSB_TMSHIGH_BUSY 0x00000004 /* Busy */
+#define SSB_TMSHIGH_TO 0x00000020 /* Timeout. Backplane rev >= 2.3 only */
+#define SSB_TMSHIGH_DMA64 0x10000000 /* 64bit DMA supported */
+#define SSB_TMSHIGH_GCR 0x20000000 /* Gated Clock Request */
+#define SSB_TMSHIGH_BISTF 0x40000000 /* BIST Failed */
+#define SSB_TMSHIGH_BISTD 0x80000000 /* BIST Done */
+#define SSB_TMSHIGH_FLAGS_SHIFT 16 /* Flags shift for TMSHIGH
+ * register of SB-style buses */
+
+extern int ssb_bus_scan_sb(struct ssb_bus *bus, unsigned long baseaddr);
+extern int scan_switchcore(struct ssb_bus *bus, u8 coreidx);
+extern void ssb_iounmap_sb(struct ssb_bus *bus);
+
+#else /* CONFIG_SSB_BUS_SB */
+
+static inline int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
+{
+ return 0;
+}
+
+static inline void ssb_iounmap_sb(struct ssb_bus *bus)
+{
+}
+
+static inline int ssb_bus_scan_sb(struct ssb_bus *bus, unsigned long baseaddr)
+{
+ return -ENODEV;
+}
+
+#endif /* CONFIG_SSB_BUS_SB */
+
+#endif /* !LINUX_SSB_SB_H_ */
next prev parent reply other threads:[~2011-02-17 22:35 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-17 15:58 [RFC] AI support George Kashperko
2011-02-17 22:01 ` Michael Büsch
2011-02-17 22:06 ` [RFC] AI support (1/14 ssb admatch redefine) George Kashperko
2011-02-17 22:08 ` [RFC] AI support (2/14 ssb helpers) George Kashperko
2011-02-18 22:29 ` Michael Büsch
2011-02-18 23:15 ` George Kashperko
2011-02-18 23:29 ` Michael Büsch
2011-02-18 23:27 ` George Kashperko
2011-02-17 22:10 ` [RFC] AI support (3/14 ssb irqflag mips core op) George Kashperko
2011-02-17 22:12 ` [RFC] AI support (4/14 ssb mips core irqflag treatment) George Kashperko
2011-02-17 22:14 ` [RFC] AI support (5/14 ssb core control and state helpers) George Kashperko
2011-02-17 22:16 ` [RFC] AI support (6/14 ssb propagate core control and state helpers usage) George Kashperko
2011-02-17 22:18 ` [RFC] AI support (7/14 ssb bus_check_core routine) George Kashperko
2011-02-17 22:20 ` [RFC] AI support (8/14 ssb ssb_bus_detect routine) George Kashperko
2011-02-18 22:35 ` Michael Büsch
2011-02-17 22:23 ` [RFC] AI support (9/14 ssb SB-specific bus scan routine) George Kashperko
2011-02-17 22:25 ` [RFC] AI support (10/14 ssb bus implementation-specific io unmap) George Kashperko
2011-02-17 22:27 ` George Kashperko [this message]
2011-02-17 22:29 ` [RFC] AI support (12/14 ssb mips74k core defs) George Kashperko
2011-02-17 22:31 ` [RFC] AI support (13/14 ssb add AI support) George Kashperko
2011-02-18 22:45 ` Michael Büsch
2011-02-18 23:07 ` George Kashperko
2011-02-18 23:27 ` Michael Büsch
2011-02-18 23:42 ` George Kashperko
2011-02-18 23:54 ` Michael Büsch
2011-02-18 23:51 ` George Kashperko
2011-02-18 23:46 ` Larry Finger
2011-02-18 23:47 ` George Kashperko
2011-02-19 0:06 ` Larry Finger
2011-02-19 0:08 ` George Kashperko
2011-02-19 0:22 ` Larry Finger
2011-02-17 22:35 ` [RFC] AI support (14/14 ssb AI on pci host (untested)) George Kashperko
2011-02-18 2:43 ` [RFC] AI support Henry Ptasinski
2011-02-18 7:39 ` George Kashperko
2011-02-18 11:53 ` Michael Büsch
2011-02-18 12:39 ` George Kashperko
2011-02-18 22:21 ` Michael Büsch
2011-02-18 22:52 ` George Kashperko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1297981651.23381.32.camel@dev.znau.edu.ua \
--to=george@znau.edu.ua \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).