Search Linux Wireless

Re: SSB AI support code ([RFC9/11] SSB separate SB-specific code)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: George Kashperko <george@xxxxxxxxxxx>

Separate SB-specific code in single file.
Signed-off-by: George Kashperko <george@xxxxxxxxxxx>
---
 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@xxxxxxxxx>
+ *
+ * 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 */



--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux