ssb: Look for SPROM at different offset on higher rev CC
authorRafał Miłecki <zajec5@gmail.com>
Wed, 31 Mar 2010 19:59:21 +0000 (21:59 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 26 Apr 2010 17:51:08 +0000 (13:51 -0400)
Our offset handling becomes even a little more hackish now. For some reason I
do not understand all offsets as inrelative. It assumes base offset is 0x1000
but it will work for now as we make offsets relative anyway by removing base
0x1000. Should be cleaner however.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/ssb/pci.c
include/linux/ssb/ssb.h
include/linux/ssb/ssb_regs.h

index a4b2b99f2c802d3d0e57ec92ee8f1d2731ae9b6b..5bb1278759c1dbcb7f88144d6dba51eaab39759d 100644 (file)
@@ -167,7 +167,7 @@ err_pci:
 }
 
 /* Get the word-offset for a SSB_SPROM_XXX define. */
-#define SPOFF(offset)  (((offset) - SSB_SPROM_BASE) / sizeof(u16))
+#define SPOFF(offset)  (((offset) - SSB_SPROM_BASE1) / sizeof(u16))
 /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
 #define SPEX16(_outvar, _offset, _mask, _shift)        \
        out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
@@ -253,7 +253,7 @@ static int sprom_do_read(struct ssb_bus *bus, u16 *sprom)
        int i;
 
        for (i = 0; i < bus->sprom_size; i++)
-               sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2));
+               sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2));
 
        return 0;
 }
@@ -284,7 +284,7 @@ static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
                        ssb_printk("75%%");
                else if (i % 2)
                        ssb_printk(".");
-               writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2));
+               writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
                mmiowb();
                msleep(20);
        }
@@ -625,6 +625,9 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
                return -ENODEV;
        }
 
+       bus->sprom_offset = (bus->chipco.dev->id.revision < 31) ?
+               SSB_SPROM_BASE1 : SSB_SPROM_BASE31;
+
        buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
        if (!buf)
                goto out;
index 3b4da233e31d474122d95143f31f3f7765f96d7b..a2608bff9c78a3a3c69544dbb6c187572535e902 100644 (file)
@@ -305,6 +305,7 @@ struct ssb_bus {
        /* ID information about the Chip. */
        u16 chip_id;
        u16 chip_rev;
+       u16 sprom_offset;
        u16 sprom_size;         /* number of words in sprom */
        u8 chip_package;
 
index 9ae9082eaeb46eb2f9d9573a2706d339ab8c06ab..b8be23ce191547126ea00f54fcf7a12a6b742fad 100644 (file)
 #define SSB_SPROMSIZE_WORDS_R4         220
 #define SSB_SPROMSIZE_BYTES_R123       (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16))
 #define SSB_SPROMSIZE_BYTES_R4         (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16))
-#define SSB_SPROM_BASE                 0x1000
+#define SSB_SPROM_BASE1                        0x1000
+#define SSB_SPROM_BASE31               0x0800
 #define SSB_SPROM_REVISION             0x107E
 #define  SSB_SPROM_REVISION_REV                0x00FF  /* SPROM Revision number */
 #define  SSB_SPROM_REVISION_CRC                0xFF00  /* SPROM CRC8 value */