All of lore.kernel.org
 help / color / mirror / Atom feed
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 */




  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.