From: George Kashperko <george@znau.edu.ua>
To: George Kashperko <george@znau.edu.ua>
Cc: linux-wireless <linux-wireless@vger.kernel.org>
Subject: Re: SSB AI support code ([RFC9/11] SSB separate SB-specific code)
Date: Wed, 09 Feb 2011 16:44:39 +0200 [thread overview]
Message-ID: <1297262679.18053.39.camel@dev.znau.edu.ua> (raw)
In-Reply-To: <1297258590.17400.37.camel@dev.znau.edu.ua>
From: George Kashperko <george@znau.edu.ua>
Separate SB-specific code in single file.
Signed-off-by: George Kashperko <george@znau.edu.ua>
---
drivers/ssb/Kconfig | 11 +
drivers/ssb/Makefile | 1
drivers/ssb/driver_mipscore.c | 10
drivers/ssb/main.c | 248 +---------------------
drivers/ssb/scan.c | 39 ---
drivers/ssb/ssb_private.h | 48 ++--
drivers/ssb/ssb_sb.c | 281 ++++++++++++++++++++++++++
drivers/ssb/ssb_sb.h | 28 ++
include/linux/ssb/ssb_driver_mips.h | 1
9 files changed, 360 insertions(+), 307 deletions(-)
--- linux-next-20110203.orig/drivers/ssb/driver_mipscore.c 2011-02-08 16:08:31.000000000 +0200
+++ linux-next-20110203/drivers/ssb/driver_mipscore.c 2011-02-08 16:08:22.000000000 +0200
@@ -47,16 +47,6 @@ static const u32 ipsflag_irq_shift[] = {
SSB_IPSFLAG_IRQ4_SHIFT,
};
-u32 ssb_irqflag_sb(struct ssb_device *dev)
-{
- u32 tpsflag = ssb_read32(dev, SSB_TPSFLAG);
- if (tpsflag)
- return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
- else
- /* not irq supported */
- return 0x3f;
-}
-
static struct ssb_device *find_device(struct ssb_device *rdev, int irqflag)
{
struct ssb_bus *bus = rdev->bus;
--- linux-next-20110203.orig/drivers/ssb/Kconfig 2011-02-08 16:08:31.000000000 +0200
+++ linux-next-20110203/drivers/ssb/Kconfig 2011-02-08 15:48:41.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-next-20110203.orig/drivers/ssb/main.c 2011-02-08 16:08:31.000000000 +0200
+++ linux-next-20110203/drivers/ssb/main.c 2011-02-08 15:48:41.000000000 +0200
@@ -49,8 +49,6 @@ static bool ssb_is_early_boot = 1;
static void ssb_buses_lock(void);
static void ssb_buses_unlock(void);
-static const struct ssb_bus_ops ssb_ssb_ops;
-
#ifdef CONFIG_SSB_PCIHOST
struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev)
@@ -593,7 +591,7 @@ error:
return err;
}
-static u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset)
+u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset)
{
struct ssb_bus *bus = dev->bus;
@@ -601,7 +599,7 @@ static u8 ssb_ssb_read8(struct ssb_devic
return readb(bus->mmio + offset);
}
-static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
+u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
{
struct ssb_bus *bus = dev->bus;
@@ -609,7 +607,7 @@ static u16 ssb_ssb_read16(struct ssb_dev
return readw(bus->mmio + offset);
}
-static u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset)
+u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset)
{
struct ssb_bus *bus = dev->bus;
@@ -618,8 +616,8 @@ static u32 ssb_ssb_read32(struct ssb_dev
}
#ifdef CONFIG_SSB_BLOCKIO
-static void ssb_ssb_block_read(struct ssb_device *dev, void *buffer,
- size_t count, u16 offset, u8 reg_width)
+void ssb_ssb_block_read(struct ssb_device *dev, void *buffer,
+ size_t count, u16 offset, u8 reg_width)
{
struct ssb_bus *bus = dev->bus;
void __iomem *addr;
@@ -666,7 +664,7 @@ static void ssb_ssb_block_read(struct ss
}
#endif /* CONFIG_SSB_BLOCKIO */
-static void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value)
+void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value)
{
struct ssb_bus *bus = dev->bus;
@@ -674,7 +672,7 @@ static void ssb_ssb_write8(struct ssb_de
writeb(value, bus->mmio + offset);
}
-static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
+void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
{
struct ssb_bus *bus = dev->bus;
@@ -682,7 +680,7 @@ static void ssb_ssb_write16(struct ssb_d
writew(value, bus->mmio + offset);
}
-static void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
+void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
{
struct ssb_bus *bus = dev->bus;
@@ -691,8 +689,8 @@ static void ssb_ssb_write32(struct ssb_d
}
#ifdef CONFIG_SSB_BLOCKIO
-static void ssb_ssb_block_write(struct ssb_device *dev, const void *buffer,
- size_t count, u16 offset, u8 reg_width)
+void ssb_ssb_block_write(struct ssb_device *dev, const void *buffer,
+ size_t count, u16 offset, u8 reg_width)
{
struct ssb_bus *bus = dev->bus;
void __iomem *addr;
@@ -928,7 +926,6 @@ int ssb_bus_ssbbus_register(struct ssb_b
int err;
bus->bustype = SSB_BUSTYPE_SSB;
- bus->ops = &ssb_ssb_ops;
err = ssb_bus_register(bus, get_invariants, baseaddr);
if (!err) {
@@ -1117,89 +1114,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;
@@ -1222,33 +1140,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) {
@@ -1319,121 +1210,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 void ssb_core_ctl_flags_sb(struct ssb_device *dev, u32 mask,
- u32 val, u32 *res)
-{
- u32 tmp;
-
- SSB_WARN_ON((mask | val) & 0xFFFF0000);
-
- if (mask || val) {
- tmp = (ssb_read32(dev, SSB_TMSLOW) &
- ~(mask << SSB_TMSLOW_FLAGS_SHIFT)) |
- (val << SSB_TMSLOW_FLAGS_SHIFT);
- ssb_write32(dev, SSB_TMSLOW, tmp);
- }
-
- /* readback */
- tmp = ssb_read32(dev, SSB_TMSLOW) >> SSB_TMSLOW_FLAGS_SHIFT;
- udelay(1);
-
- if (res)
- *res = tmp;
-}
-
-static u32 ssb_core_state_flags_sb(struct ssb_device *dev, u32 mask, u32 val)
-{
- u32 tmp;
-
- SSB_WARN_ON((mask | val) & 0xFFFF0000);
-
- if (mask || val) {
- tmp = (ssb_read32(dev, SSB_TMSHIGH) &
- ~(mask << SSB_TMSHIGH_FLAGS_SHIFT)) |
- (val << SSB_TMSHIGH_FLAGS_SHIFT);
- ssb_write32(dev, SSB_TMSHIGH, tmp);
- }
-
- /* readback */
- tmp = ssb_read32(dev, SSB_TMSHIGH) >> SSB_TMSHIGH_FLAGS_SHIFT;
- udelay(1);
-
- return tmp;
-}
-
-/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
-static const struct ssb_bus_ops ssb_ssb_ops = {
- .read8 = ssb_ssb_read8,
- .read16 = ssb_ssb_read16,
- .read32 = ssb_ssb_read32,
- .write8 = ssb_ssb_write8,
- .write16 = ssb_ssb_write16,
- .write32 = ssb_ssb_write32,
-#ifdef CONFIG_SSB_BLOCKIO
- .block_read = ssb_ssb_block_read,
- .block_write = ssb_ssb_block_write,
-#endif
- .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,
- .irqflag = ssb_irqflag_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-next-20110203.orig/drivers/ssb/Makefile 2011-02-08 16:08:31.000000000 +0200
+++ linux-next-20110203/drivers/ssb/Makefile 2011-02-08 15:48:41.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-next-20110203.orig/drivers/ssb/scan.c 2011-02-08 16:08:31.000000000 +0200
+++ linux-next-20110203/drivers/ssb/scan.c 2011-02-08 15:48:41.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,7 +183,7 @@ static u32 scan_read32(struct ssb_bus *b
return readl(bus->mmio + offset);
}
-static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
+int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
{
switch (bus->bustype) {
case SSB_BUSTYPE_SSB:
@@ -405,40 +404,6 @@ static int ssb_bus_detect(struct ssb_bus
return chiptype != SSB_CHIPCO_SB;
}
-int ssb_bus_scan_sb(struct ssb_bus *bus, unsigned long baseaddr)
-{
- int err;
- u32 idhi;
- int dev_i, i;
- struct ssb_device *dev;
- int nr_80211_cores = 0;
-
- /* 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;
-
- 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)
{
--- linux-next-20110203.orig/drivers/ssb/ssb_private.h 2011-02-08 16:08:31.000000000 +0200
+++ linux-next-20110203/drivers/ssb/ssb_private.h 2011-02-08 15:48:41.000000000 +0200
@@ -205,33 +205,35 @@ static inline void b43_pci_ssb_bridge_ex
}
#endif /* CONFIG_SSB_B43_PCI_BRIDGE */
+/* device mmio access helpers */
+extern u8 ssb_ssb_read8(struct ssb_device *dev, u16 offset);
+extern u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset);
+extern u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset);
+extern void ssb_ssb_write8(struct ssb_device *dev, u16 offset, u8 value);
+extern void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value);
+extern void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value);
+#ifdef CONFIG_SSB_BLOCKIO
+extern void ssb_ssb_block_read(struct ssb_device *dev, void *buffer,
+ size_t count, u16 offset, u8 reg_width);
+extern void ssb_ssb_block_write(struct ssb_device *dev, const void *buffer,
+ size_t count, u16 offset, u8 reg_width);
+#endif /* CONFIG_SSB_BLOCKIO */
+extern int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
+ int timeout, int set);
/* Search support routines */
+extern u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx, u16 offset);
+extern int scan_switchcore(struct ssb_bus *bus, u8 coreidx);
extern int ssb_bus_check_core(struct ssb_device *dev, int *nr_80211_cores,
int corenum);
-/* 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 */
+#ifdef CONFIG_SSB_BUS_SB
+extern int ssb_bus_scan_sb(struct ssb_bus *bus, unsigned long baseaddr);
+#else /* CONFIG_SSB_BUS_SB */
+static inline int ssb_bus_scan_sb(struct ssb_bus *bus, unsigned long baseaddr)
+{
+ return -ENODEV;
+}
+#endif /* CONFIG_SSB_BUS_SB */
#endif /* LINUX_SSB_PRIVATE_H_ */
--- linux-next-20110203.orig/drivers/ssb/ssb_sb.c 1970-01-01 03:00:00.000000000 +0300
+++ linux-next-20110203/drivers/ssb/ssb_sb.c 2011-02-08 16:08:43.000000000 +0200
@@ -0,0 +1,281 @@
+/*
+ * Sonics Silicon Backplane
+ * 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"
+#include "ssb_sb.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_irqflag_sb(struct ssb_device *dev)
+{
+ u32 tpsflag = ssb_read32(dev, SSB_TPSFLAG);
+ if (tpsflag)
+ return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
+ else
+ /* not irq supported */
+ return 0x3f;
+}
+
+static void ssb_core_ctl_flags_sb(struct ssb_device *dev, u32 mask,
+ u32 val, u32 *res)
+{
+ u32 tmp;
+
+ SSB_WARN_ON((mask | val) & 0xFFFF0000);
+
+ if (mask || val) {
+ tmp = (ssb_read32(dev, SSB_TMSLOW) &
+ ~(mask << SSB_TMSLOW_FLAGS_SHIFT)) |
+ (val << SSB_TMSLOW_FLAGS_SHIFT);
+ ssb_write32(dev, SSB_TMSLOW, tmp);
+ }
+
+ /* readback */
+ tmp = ssb_read32(dev, SSB_TMSLOW) >> SSB_TMSLOW_FLAGS_SHIFT;
+ udelay(1);
+
+ if (res)
+ *res = tmp;
+}
+
+static u32 ssb_core_state_flags_sb(struct ssb_device *dev, u32 mask, u32 val)
+{
+ u32 tmp;
+
+ SSB_WARN_ON((mask | val) & 0xFFFF0000);
+
+ if (mask || val) {
+ tmp = (ssb_read32(dev, SSB_TMSHIGH) &
+ ~(mask << SSB_TMSHIGH_FLAGS_SHIFT)) |
+ (val << SSB_TMSHIGH_FLAGS_SHIFT);
+ ssb_write32(dev, SSB_TMSHIGH, tmp);
+ }
+
+ /* readback */
+ tmp = ssb_read32(dev, SSB_TMSHIGH) >> SSB_TMSHIGH_FLAGS_SHIFT;
+ udelay(1);
+
+ return tmp;
+}
+
+/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
+static const struct ssb_bus_ops ssb_ssb_ops = {
+ .read8 = ssb_ssb_read8,
+ .read16 = ssb_ssb_read16,
+ .read32 = ssb_ssb_read32,
+ .write8 = ssb_ssb_write8,
+ .write16 = ssb_ssb_write16,
+ .write32 = ssb_ssb_write32,
+#ifdef CONFIG_SSB_BLOCKIO
+ .block_read = ssb_ssb_block_read,
+ .block_write = ssb_ssb_block_write,
+#endif
+ .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,
+ .irqflag = ssb_irqflag_sb,
+ .core_ctl_flags = ssb_core_ctl_flags_sb,
+ .core_state_flags = ssb_core_state_flags_sb,
+};
+
+int ssb_bus_scan_sb(struct ssb_bus *bus, unsigned long baseaddr)
+{
+ int err;
+ u32 idhi;
+ int dev_i, i;
+ struct ssb_device *dev;
+ int nr_80211_cores = 0;
+
+ /* 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;
+
+ if (ssb_bus_check_core(dev, &nr_80211_cores, i) < 0)
+ continue;
+
+ dev_i++;
+ }
+ bus->nr_devices = dev_i;
+ return 0;
+}
+
--- linux-next-20110203.orig/drivers/ssb/ssb_sb.h 1970-01-01 03:00:00.000000000 +0300
+++ linux-next-20110203/drivers/ssb/ssb_sb.h 2011-02-08 15:48:41.000000000 +0200
@@ -0,0 +1,28 @@
+#ifndef LINUX_SSB_SB_H_
+#define LINUX_SSB_SB_H_
+
+/* 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_SB_H_ */
--- linux-next-20110203.orig/include/linux/ssb/ssb_driver_mips.h 2011-02-08 16:08:31.000000000 +0200
+++ linux-next-20110203/include/linux/ssb/ssb_driver_mips.h 2011-02-08 15:48:41.000000000 +0200
@@ -29,7 +29,6 @@ extern void ssb_mipscore_init(struct ssb
extern u32 ssb_cpu_clock(struct ssb_mipscore *mcore);
extern unsigned int ssb_mips_irq(struct ssb_device *dev);
-extern u32 ssb_irqflag_sb(struct ssb_device *dev);
#else /* CONFIG_SSB_DRIVER_MIPS */
next prev parent reply other threads:[~2011-02-09 14:52 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-02-09 13:36 SSB AI support code George Kashperko
2011-02-09 14:29 ` SSB AI support code ([RFC1/11] SSB admatch redefine) George Kashperko
2011-02-09 14:31 ` SSB AI support code ([RFC2/11] SSB reintroduce handlers as device ops) George Kashperko
2011-02-09 14:32 ` SSB AI support code ([RFC3/11] SSB irqflag device op) George Kashperko
2011-02-09 16:19 ` Larry Finger
2011-02-09 17:10 ` George Kashperko
2011-02-09 17:48 ` Larry Finger
2011-02-09 18:23 ` George Kashperko
2011-02-09 19:19 ` Larry Finger
2011-02-09 19:26 ` George Kashperko
2011-02-09 19:42 ` Larry Finger
2011-02-09 14:34 ` SSB AI support code ([RFC4/11] SSB core control and state device ops) George Kashperko
2011-02-09 20:35 ` Rafał Miłecki
2011-02-09 21:01 ` Rafał Miłecki
2011-02-09 21:21 ` George Kashperko
2011-02-09 21:03 ` George Kashperko
2011-02-09 21:14 ` Michael Büsch
2011-02-09 21:55 ` Rafał Miłecki
2011-02-09 21:58 ` George Kashperko
2011-02-09 22:00 ` George Kashperko
2011-02-09 22:02 ` Michael Büsch
2011-02-09 22:22 ` George Kashperko
2011-02-09 14:36 ` SSB AI support code ([RFC5/11] SSB propagate core control and state ops usage) George Kashperko
2011-02-09 20:58 ` Rafał Miłecki
2011-02-09 21:12 ` Michael Büsch
2011-02-09 21:26 ` George Kashperko
2011-02-09 21:50 ` Rafał Miłecki
2011-02-09 21:55 ` George Kashperko
2011-02-09 14:37 ` SSB AI support code ([RFC6/11] SSB introduce bus_check_core routine) George Kashperko
2011-02-09 14:39 ` SSB AI support code ([RFC7/11] SSB introduce ssb_bus_detect routine) George Kashperko
2011-02-09 14:40 ` SSB AI support code ([RFC8/11] SSB separate SB-specific scanning) George Kashperko
2011-02-09 14:41 ` SSB AI support code ([RFC9/11] SSB modify irqflag treatment) George Kashperko
2011-02-09 16:23 ` Larry Finger
2011-02-09 16:53 ` George Kashperko
2011-02-09 14:44 ` George Kashperko [this message]
2011-02-09 14:45 ` SSB AI support code ([RFC10/11] " George Kashperko
2011-02-09 14:46 ` SSB AI support code ([RFC11/11] SSB add AI-bus support) George Kashperko
2011-02-09 16:25 ` Larry Finger
2011-02-09 18:33 ` George Kashperko
2011-02-09 16:49 ` Larry Finger
2011-02-09 21:35 ` SSB AI support code Rafał Miłecki
2011-02-09 21:41 ` George Kashperko
2011-02-09 21:51 ` Michael Büsch
2011-02-09 22:53 ` Rafał Miłecki
2011-02-09 23:10 ` Michael Büsch
2011-02-09 23:18 ` Larry Finger
2011-02-10 5:24 ` SSB AI support code ([RFC] v2) George Kashperko
2011-02-10 10:20 ` Michael Büsch
2011-02-10 17:40 ` George Kashperko
2011-02-10 18:11 ` Michael Büsch
[not found] ` <1297362251.15805.51.camel@dev.znau.edu.ua>
[not found] ` <1297363781.30218.37.camel@maggie>
2011-02-10 19:52 ` George Kashperko
2011-02-10 20:07 ` Michael Büsch
2011-02-15 14:50 ` Rafał Miłecki
2011-02-15 15:05 ` George Kashperko
2011-02-09 23:30 ` SSB AI support code George Kashperko
2011-02-15 14:48 ` Rafał Miłecki
2011-02-15 14:53 ` George Kashperko
2011-02-12 13:03 ` Hauke Mehrtens
2011-02-12 14:15 ` George Kashperko
2011-02-17 9:28 ` Roland Vossen
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=1297262679.18053.39.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.