Hello Thank you for tracking this down. Here are two new patches for the scan stuff, hopefully working now.
Bernhard Loos 2010/5/15 Hauke Mehrtens <ha...@hauke-m.de>: > Am 14.05.2010 00:25, schrieb Bernhard Loos: >> Hello >> Do you have any clue, what could produce b43? Because, after looking >> at the code, I'm kinda at a loss, where this comes from. And do you >> know, which patch exactly produces the problem? >> I will split the patch up, but it may take a day or two, until I have >> the time. Some of the other patches are possible also mixed up. >> Your patch unfortunetly doesn't work as a general solution, because >> the 4716 hangs, if any of the id registers is accessed. >> Thanks again, for looking at this. >> >> Bernhard >> >> 2010/5/13 Hauke Mehrtens <ha...@hauke-m.de>: >>> Am 13.05.2010 20:54, schrieb Hauke Mehrtens: >>>> Hi Bernhard, >>>> >>>> I have changed the code to do the same things it did before your changes >>>> at that position. My patch is attached. >>>> >>>> With this patch all ssb Cores are found, but I get a oops in b43 driver >>>> now. "Reserved instruction in kernel code" >>>> >>>> I have not activated symbols will do now. Here is the log for now: >>>> http://hauke-m.de/fileadmin/openwrt/brcm47xx-log/boot-not-working2.log >>>> >>>> Could you please split 952-ai-scan.patch into two patches. One just >>>> reorganizing the existing code without changing any functionality and >>>> one adding the ai scan. >>>> >>>> Hauke >>> Hi Bernhard, >>> >>> I get the following kernel oops with your patches: >>> >>> Reserved instruction in kernel code[#1]: >>> ... >>> Call Trace: >>> [<80cc4908>] b43info+0x560/0x2754 [b43] >>> [<8018a27c>] ssb_device_probe+0x44/0x80 >>> [<80167d24>] driver_probe_device+0x13c/0x28c >>> [<800e78ec>] sysfs_create_dir+0x44/0x68 >>> [<8012b83c>] kobject_get+0x1c/0x30 >>> [<80167e74>] __driver_attach+0x0/0xa4 >>> [<80167ee0>] __driver_attach+0x6c/0xa4 >>> [<8012bf2c>] kobject_add_varg+0x28/0x78 >>> [<801673dc>] bus_for_each_dev+0x64/0xb4 >>> [<8012bfbc>] kobject_init_and_add+0x40/0x58 >>> [<80166b2c>] bus_add_driver+0xd0/0x274 >>> [<80056d20>] load_module+0x1980/0x1b4c >>> [<80168290>] driver_register+0xe0/0x19c >>> [<80ce8000>] init_module+0x0/0x70 [b43] >>> [<80ce8020>] init_module+0x20/0x70 [b43] >>> [<8000d650>] do_one_initcall+0x70/0x1f4 >>> [<800437f0>] blocking_notifier_call_chain+0x14/0x20 >>> [<80057408>] sys_init_module+0xe0/0x224 >>> [<80092924>] sys_close+0x9c/0xe4 >>> [<80003230>] stack_done+0x20/0x3c >>> >>> Full log: >>> http://hauke-m.de/fileadmin/openwrt/brcm47xx-log/boot-not-working3.log >>> >>> Hauke >>> > Hi Bernhard, > > I found the cause of the problem. It was not in your patch series, but > the some other openwrt parts. While building b43 from compat-wireless > CONFIG_SSB_BLOCKIO was activated, when building ssb in the kernel is was > deactivated. This causes the struct ssb_bus_ops to be different in ssb > and b43. The Pointers to device_enable and so on are wrong. When they > were called it jumped to somewhere else in the code. > This problem is fixed in r21449 https://dev.openwrt.org/changeset/21449 > > Now everything works for me like before with your patches when also > adding the attached patch. > > In function ssb_bus_scan rev is not the same as bus->chip_rev. > > Hauke >
Index: target/linux/brcm47xx/patches-2.6.32/952-ssb-scan_rework.patch =================================================================== --- target/linux/brcm47xx/patches-2.6.32/952-ssb-scan_rework.patch (revision 0) +++ target/linux/brcm47xx/patches-2.6.32/952-ssb-scan_rework.patch (revision 0) @@ -0,0 +1,305 @@ +Index: linux-2.6.32.12/drivers/ssb/scan.c +=================================================================== +--- linux-2.6.32.12.orig/drivers/ssb/scan.c 2010-05-11 18:04:00.000000000 +0200 ++++ linux-2.6.32.12/drivers/ssb/scan.c 2010-05-11 18:14:32.810514610 +0200 +@@ -2,6 +2,7 @@ + * Sonics Silicon Backplane + * Bus scanning + * ++ * Copyright (C) 2010 Bernhard Loos <bernhardl...@googlemail.com> + * Copyright (C) 2005-2007 Michael Buesch <m...@bu3sch.de> + * Copyright (C) 2005 Martin Langer <martin-lan...@gmx.de> + * Copyright (C) 2005 Stefano Brivio <s...@riseup.net> +@@ -17,11 +18,6 @@ + #include <linux/pci.h> + #include <linux/io.h> + +-#include <pcmcia/cs_types.h> +-#include <pcmcia/cs.h> +-#include <pcmcia/cistpl.h> +-#include <pcmcia/ds.h> +- + #include "ssb_private.h" + + +@@ -276,15 +272,126 @@ + return 0; + } + ++/* returns 0 if the core is ok and -1 if the core should be ignored */ ++static int ssb_bus_check_core(struct ssb_device *dev, int *nr_80211_cores, int corenum) ++{ ++ struct ssb_bus *bus = dev->bus; ++ ++ printk(KERN_INFO PFX ++ "Core %d found: %s " ++ "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n", ++ corenum, ssb_core_name(dev->id.coreid), ++ dev->id.coreid, dev->id.revision, dev->id.vendor); ++ ++ switch (dev->id.coreid) { ++ case SSB_DEV_80211: ++ (*nr_80211_cores)++; ++ if (*nr_80211_cores > 1) { ++ if (!we_support_multiple_80211_cores(bus)) { ++ ssb_dprintk(KERN_INFO PFX "Ignoring additional " ++ "802.11 core\n"); ++ return -1; ++ } ++ } ++ break; ++ case SSB_DEV_EXTIF: ++#ifdef CONFIG_SSB_DRIVER_EXTIF ++ if (bus->extif.dev) { ++ ssb_printk(KERN_WARNING PFX ++ "WARNING: Multiple EXTIFs found\n"); ++ break; ++ } ++ bus->extif.dev = dev; ++#endif /* CONFIG_SSB_DRIVER_EXTIF */ ++ break; ++ case SSB_DEV_CHIPCOMMON: ++ if (bus->chipco.dev) { ++ ssb_printk(KERN_WARNING PFX ++ "WARNING: Multiple ChipCommon found\n"); ++ break; ++ } ++ bus->chipco.dev = dev; ++ break; ++ case SSB_DEV_MIPS: ++ case SSB_DEV_MIPS_3302: ++ case SSB_DEV_MIPS_74K: ++#ifdef CONFIG_SSB_DRIVER_MIPS ++ if (bus->mipscore.dev) { ++ ssb_printk(KERN_WARNING PFX ++ "WARNING: Multiple MIPS cores found\n"); ++ break; ++ } ++ bus->mipscore.dev = dev; ++#endif /* CONFIG_SSB_DRIVER_MIPS */ ++ break; ++ case SSB_DEV_PCI: ++ case SSB_DEV_PCIE: ++#ifdef CONFIG_SSB_DRIVER_PCICORE ++ if (bus->bustype == SSB_BUSTYPE_PCI) { ++ /* Ignore PCI cores on PCI-E cards. ++ * Ignore PCI-E cores on PCI cards. */ ++ if (dev->id.coreid == SSB_DEV_PCI) { ++ if (bus->host_pci->is_pcie) ++ return -1; ++ } else { ++ if (!bus->host_pci->is_pcie) ++ return -1; ++ } ++ } ++ if (bus->pcicore.dev) { ++ ssb_printk(KERN_WARNING PFX ++ "WARNING: Multiple PCI(E) cores found\n"); ++ break; ++ } ++ bus->pcicore.dev = dev; ++#endif /* CONFIG_SSB_DRIVER_PCICORE */ ++ break; ++ default: ++ break; ++ } ++ return 0; ++} ++ ++static int ssb_scan_sb(struct ssb_bus *bus) ++{ ++ int i, dev_i, err; ++ struct ssb_device *dev; ++ int nr_80211_cores = 0; ++ u32 idhi; ++ ++ /* 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) + { + int err = -ENOMEM; + void __iomem *mmio; +- u32 idhi, cc, rev, tmp; +- int dev_i, i; +- struct ssb_device *dev; +- int nr_80211_cores = 0; ++ u32 tmp; ++ bool have_chipcommon = true; + + mmio = ssb_ioremap(bus, baseaddr); + if (!mmio) +@@ -295,13 +402,11 @@ + if (err) + goto err_unmap; + +- idhi = scan_read32(bus, 0, SSB_IDHIGH); +- cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT; +- rev = (idhi & SSB_IDHIGH_RCLO); +- rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT; +- ++ if (SSB_DEV_CHIPCOMMON != (scan_read32(bus, 0, SSB_IDHIGH) & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT) ++ have_chipcommon = false; ++ + bus->nr_devices = 0; +- if (cc == SSB_DEV_CHIPCOMMON) { ++ if (have_chipcommon) { + tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID); + + bus->chip_id = (tmp & SSB_CHIPCO_IDMASK); +@@ -309,12 +414,9 @@ + SSB_CHIPCO_REVSHIFT; + bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >> + SSB_CHIPCO_PACKSHIFT; +- if (rev >= 4) { +- bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >> +- SSB_CHIPCO_NRCORESSHIFT; +- } +- tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP); +- bus->chipco.capabilities = tmp; ++ bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >> ++ SSB_CHIPCO_NRCORESSHIFT; ++ bus->chipco.capabilities = scan_read32(bus, 0, SSB_CHIPCO_CAP); + } else { + if (bus->bustype == SSB_BUSTYPE_PCI) { + bus->chip_id = pcidev_to_chipid(bus->host_pci); +@@ -339,7 +441,6 @@ + /* Now that we know the number of cores, + * remap the whole IO space for all cores. + */ +- err = -ENOMEM; + iounmap(mmio); + mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices); + if (!mmio) +@@ -347,102 +448,13 @@ + bus->mmio = mmio; + } + +- /* 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) +- goto err_unmap; +- 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; +- +- printk(KERN_DEBUG PFX +- "Core %d found: %s " +- "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n", +- i, ssb_core_name(dev->id.coreid), +- dev->id.coreid, dev->id.revision, dev->id.vendor); +- +- switch (dev->id.coreid) { +- case SSB_DEV_80211: +- nr_80211_cores++; +- if (nr_80211_cores > 1) { +- if (!we_support_multiple_80211_cores(bus)) { +- ssb_dprintk(KERN_INFO PFX "Ignoring additional " +- "802.11 core\n"); +- continue; +- } +- } +- break; +- case SSB_DEV_EXTIF: +-#ifdef CONFIG_SSB_DRIVER_EXTIF +- if (bus->extif.dev) { +- ssb_printk(KERN_WARNING PFX +- "WARNING: Multiple EXTIFs found\n"); +- break; +- } +- bus->extif.dev = dev; +-#endif /* CONFIG_SSB_DRIVER_EXTIF */ +- break; +- case SSB_DEV_CHIPCOMMON: +- if (bus->chipco.dev) { +- ssb_printk(KERN_WARNING PFX +- "WARNING: Multiple ChipCommon found\n"); +- break; +- } +- bus->chipco.dev = dev; +- break; +- case SSB_DEV_MIPS: +- case SSB_DEV_MIPS_3302: +-#ifdef CONFIG_SSB_DRIVER_MIPS +- if (bus->mipscore.dev) { +- ssb_printk(KERN_WARNING PFX +- "WARNING: Multiple MIPS cores found\n"); +- break; +- } +- bus->mipscore.dev = dev; +-#endif /* CONFIG_SSB_DRIVER_MIPS */ +- break; +- case SSB_DEV_PCI: +- case SSB_DEV_PCIE: +-#ifdef CONFIG_SSB_DRIVER_PCICORE +- if (bus->bustype == SSB_BUSTYPE_PCI) { +- /* Ignore PCI cores on PCI-E cards. +- * Ignore PCI-E cores on PCI cards. */ +- if (dev->id.coreid == SSB_DEV_PCI) { +- if (bus->host_pci->is_pcie) +- continue; +- } else { +- if (!bus->host_pci->is_pcie) +- continue; +- } +- } +- if (bus->pcicore.dev) { +- ssb_printk(KERN_WARNING PFX +- "WARNING: Multiple PCI(E) cores found\n"); +- break; +- } +- bus->pcicore.dev = dev; +-#endif /* CONFIG_SSB_DRIVER_PCICORE */ +- break; +- default: +- break; +- } ++ err = ssb_scan_sb(bus); + +- dev_i++; +- } +- bus->nr_devices = dev_i; ++ if (err == 0) ++ return 0; + +- err = 0; +-out: +- return err; + err_unmap: + ssb_iounmap(bus); +- goto out; ++out: ++ return err; + } Index: target/linux/brcm47xx/patches-2.6.32/953-ssb-ai_scan.patch =================================================================== --- target/linux/brcm47xx/patches-2.6.32/953-ssb-ai_scan.patch (revision 0) +++ target/linux/brcm47xx/patches-2.6.32/953-ssb-ai_scan.patch (revision 0) @@ -0,0 +1,296 @@ +Index: linux-2.6.32.12/drivers/ssb/scan.c +=================================================================== +--- linux-2.6.32.12.orig/drivers/ssb/scan.c 2010-05-11 18:35:20.052293905 +0200 ++++ linux-2.6.32.12/drivers/ssb/scan.c 2010-05-11 18:44:01.135401247 +0200 +@@ -212,6 +212,8 @@ + case SSB_BUSTYPE_SSB: + case SSB_BUSTYPE_PCMCIA: + iounmap(bus->mmio); ++ if (bus->ai_mmio) ++ iounmap(bus->ai_mmio); + break; + case SSB_BUSTYPE_PCI: + #ifdef CONFIG_SSB_PCIHOST +@@ -224,6 +226,7 @@ + break; + } + bus->mmio = NULL; ++ bus->ai_mmio = NULL; + bus->mapped_device = NULL; + } + +@@ -385,12 +388,162 @@ + return 0; + } + ++static u32 ++get_erom_ent(struct ssb_bus *bus, u32 **eromptr, u32 mask, u32 match) ++{ ++ u32 ent; ++ ++ while (1) { ++ ent = readl(*eromptr); ++ (*eromptr)++; ++ ++ if (mask == 0) ++ break; ++ ++ if ((ent & SSB_EROM_VALID) == 0) ++ continue; ++ ++ if (ent == (SSB_EROM_END | SSB_EROM_VALID)) ++ break; ++ ++ if ((ent & mask) == match) ++ break; ++ } ++ return ent; ++} ++ ++static u32 ++get_adress_space_descriptor(struct ssb_bus *bus, u32 **eromptr, uint st, u32 *addrl, u32 *sizel) ++{ ++ u32 asd, sz, szd, expect; ++ ++ expect = SSB_EROM_ASD | st; ++ if (st == SSB_EROM_ASD_ST_SWRAP) ++ expect |= 1 << SSB_EROM_ASD_SP_SHIFT; ++ ++ asd = get_erom_ent(bus, eromptr, SSB_EROM_ASD_SP_MASK | SSB_EROM_TAG | SSB_EROM_ASD_ST_MASK, expect); ++ ++ *addrl = asd & SSB_EROM_ASD_ADDR_MASK; ++ ++ /* *addrh = get_erom_ent(sih, eromptr, 0, 0); ++ 64bit addresses are not supported */ ++ BUG_ON(asd & SSB_EROM_ASD_AG32); ++ ++ sz = asd & SSB_EROM_ASD_SZ_MASK; ++ if (sz == SSB_EROM_ASD_SZ_SZD) { ++ szd = get_erom_ent(bus, eromptr, 0, 0); ++ *sizel = szd & SSB_EROM_ASD_SZ_MASK; ++ } else ++ *sizel = SSB_EROM_ASD_SZ_BASE << (sz >> SSB_EROM_ASD_SZ_SHIFT); ++ ++ return asd; ++} ++ ++static int ssb_scan_ai(struct ssb_bus *bus) ++{ ++ int dev_i = 0; ++ struct ssb_device *dev; ++ int nr_80211_cores = 0; ++ void __iomem *mmio; ++ u32 __iomem *eromptr; ++ u32 __iomem *eromend; ++ ++ mmio = ioremap(SSB_AI_BASE, SSB_CORE_SIZE * bus->nr_devices); ++ if (!mmio) ++ return -ENOMEM; ++ bus->ai_mmio = mmio; ++ ++ eromptr = ioremap(scan_read32(bus, 0, SSB_CHIPCO_EROM), SSB_CORE_SIZE); ++ if (!eromptr) ++ return -ENOMEM; ++ ++ eromend = eromptr + SSB_CORE_SIZE / sizeof(u32); ++ ++ while (eromptr < eromend) { ++ u32 cia, cib, asd, sizel, addrl, nmw, nsp; ++ ++ dev = &(bus->devices[dev_i]); ++ ++ ++ cia = get_erom_ent(bus, &eromptr, SSB_EROM_TAG, SSB_EROM_CI); ++ if (cia == (SSB_EROM_END | SSB_EROM_VALID)) { ++ ssb_dprintk(KERN_INFO PFX "Found END of erom after %d cores\n", dev_i); ++ if (dev_i != bus->nr_devices) { ++ ssb_printk(KERN_WARNING PFX "Expected %d cores but got %d\n", bus->nr_devices, dev_i); ++ } ++ break; ++ } ++ cib = get_erom_ent(bus, &eromptr, 0, 0); ++ if ((cib & SSB_EROM_TAG) != SSB_EROM_CI) { ++ ssb_printk(KERN_ERR PFX "CIA not followed by CIB\n"); ++ return -EIO; ++ } ++ ++ dev->id.coreid = SSB_EROM_CIA_CID(cia); ++ dev->id.vendor = SSB_EROM_CIA_MFG(cia); ++ dev->id.revision = SSB_EROM_CIB_REV(cib); ++ dev->core_index = dev_i; ++ dev->bus = bus; ++ dev->ops = bus->ops; ++ ++ nmw = SSB_EROM_CIB_NMW(cib); ++ nsp = SSB_EROM_CIB_NSP(cib); ++ ++ if (((dev->id.coreid == SSB_DEV_DEFAULT) && (dev->id.vendor == SSB_VENDOR_ARM)) || ++ (nmw == 0 && SSB_EROM_CIB_NSW(cib) == 0) || (nsp == 0)) { ++ continue; ++ } ++ ++ /* see if it is a bridge */ ++ if ((SSB_EROM_ASD_ST_MASK & get_erom_ent(bus, &eromptr, SSB_EROM_TAG, SSB_EROM_ASD)) == ++ SSB_EROM_ASD_ST_BRIDGE) ++ continue;/* don't record bridges */ ++ else ++ eromptr--; ++ ++ /* First Slave Address Descriptor should be port 0: ++ * the main register space for the core ++ */ ++ asd = get_adress_space_descriptor(bus, &eromptr, SSB_EROM_ASD_ST_SLAVE, &addrl, &sizel); ++ if (sizel != SSB_CORE_SIZE || addrl != SSB_ENUM_BASE + SSB_CORE_SIZE * dev_i) { ++ ssb_printk(KERN_ERR PFX "Malformed or unsupported register address space descriptor for core %d:\n" ++ "\texpected 0x%x, got 0x%x, size 0x%x\n", ++ dev_i, SSB_ENUM_BASE + SSB_CORE_SIZE * dev_i, addrl, sizel); ++ return -EIO; ++ } ++ ++ if (nmw) ++ asd = get_adress_space_descriptor(bus, &eromptr, SSB_EROM_ASD_ST_MWRAP, &addrl, &sizel); ++ else ++ asd = get_adress_space_descriptor(bus, &eromptr, SSB_EROM_ASD_ST_SWRAP, &addrl, &sizel); ++ ++ if (sizel != SSB_CORE_SIZE || addrl != SSB_AI_BASE + SSB_CORE_SIZE * dev_i) { ++ ssb_printk(KERN_ERR PFX "Malformed or unsupported ai address space descriptor for core %d:\n" ++ "\texpected 0x%x, got 0x%x, size 0x%x\n", ++ dev_i, SSB_AI_BASE + SSB_CORE_SIZE * dev_i, addrl, sizel); ++ return -EIO; ++ } ++ ++ if (ssb_bus_check_core(dev, &nr_80211_cores, dev_i) < 0) ++ continue; ++ ++ dev_i++; ++ } ++ bus->nr_devices = dev_i; ++ ++ if (eromptr >= eromend) ++ ssb_printk(KERN_WARNING PFX "Reached end of erom without finding END"); ++ ++ return 0; ++} ++ ++ + int ssb_bus_scan(struct ssb_bus *bus, + unsigned long baseaddr) + { + int err = -ENOMEM; + void __iomem *mmio; +- u32 tmp; ++ u32 tmp, chiptype = SSB_CHIPCO_TYPE_SB; + bool have_chipcommon = true; + + mmio = ssb_ioremap(bus, baseaddr); +@@ -402,8 +555,18 @@ + if (err) + goto err_unmap; + +- if (SSB_DEV_CHIPCOMMON != (scan_read32(bus, 0, SSB_IDHIGH) & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT) +- have_chipcommon = false; ++ /* the problem goes like this: ++ * if we access the normal core id backplane registers on an ai soc, the thing hangs ++ * to figure out, if we have an ai soc, we have to look in a chipcommon register ++ * the 4710 doesn't have a chipcommon core_index ++ * but we can't figure this out without scanning the cores, and we don't know, if we ++ * have to use the ai or normal method ++ * all known ai socs have a 74k cpu, so let's take this as an indicator that we have a ++ * chipcommon core and hope for the best */ ++ if (cpu_data[0].cputype != CPU_74K) { ++ if (SSB_DEV_CHIPCOMMON != (scan_read32(bus, 0, SSB_IDHIGH) & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT) ++ have_chipcommon = false; ++ } + + bus->nr_devices = 0; + if (have_chipcommon) { +@@ -414,6 +577,7 @@ + SSB_CHIPCO_REVSHIFT; + bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >> + SSB_CHIPCO_PACKSHIFT; ++ chiptype = tmp & SSB_CHIPCO_TYPE_MASK; + bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >> + SSB_CHIPCO_NRCORESSHIFT; + bus->chipco.capabilities = scan_read32(bus, 0, SSB_CHIPCO_CAP); +@@ -448,7 +612,17 @@ + bus->mmio = mmio; + } + +- err = ssb_scan_sb(bus); ++ switch (chiptype) { ++ case SSB_CHIPCO_TYPE_SB: ++ err = ssb_scan_sb(bus); ++ break; ++ case SSB_CHIPCO_TYPE_AI: ++ err = ssb_scan_ai(bus); ++ break; ++ default: ++ ssb_printk(KERN_ERR PFX "Unsupported chiptype 0x%x\n", chiptype); ++ err = -ENOSYS; ++ } + + if (err == 0) + return 0; +Index: linux-2.6.32.12/include/linux/ssb/ssb.h +=================================================================== +--- linux-2.6.32.12.orig/include/linux/ssb/ssb.h 2010-05-11 18:35:20.044100366 +0200 ++++ linux-2.6.32.12/include/linux/ssb/ssb.h 2010-05-11 18:36:27.629653312 +0200 +@@ -273,6 +273,7 @@ + struct ssb_bus { + /* The MMIO area. */ + void __iomem *mmio; ++ void __iomem *ai_mmio; + + const struct ssb_bus_ops *ops; + +Index: linux-2.6.32.12/include/linux/ssb/ssb_driver_chipcommon.h +=================================================================== +--- linux-2.6.32.12.orig/include/linux/ssb/ssb_driver_chipcommon.h 2010-05-11 18:35:20.044100366 +0200 ++++ linux-2.6.32.12/include/linux/ssb/ssb_driver_chipcommon.h 2010-05-11 18:36:27.629653312 +0200 +@@ -23,6 +23,9 @@ + #define SSB_CHIPCO_PACKSHIFT 20 + #define SSB_CHIPCO_NRCORESMASK 0x0F000000 + #define SSB_CHIPCO_NRCORESSHIFT 24 ++#define SSB_CHIPCO_TYPE_MASK 0xf0000000 ++#define SSB_CHIPCO_TYPE_SB 0 ++#define SSB_CHIPCO_TYPE_AI 0x10000000 + #define SSB_CHIPCO_CAP 0x0004 /* Capabilities */ + #define SSB_CHIPCO_CAP_NRUART 0x00000003 /* # of UARTs */ + #define SSB_CHIPCO_CAP_MIPSEB 0x00000004 /* MIPS in BigEndian Mode */ +@@ -170,6 +173,7 @@ + #define SSB_CHIPCO_SYSCLKCTL_CLKDIV 0xFFFF0000 /* ClkDiv (ILP = 1/(4+divisor)) */ + #define SSB_CHIPCO_SYSCLKCTL_CLKDIV_SHIFT 16 + #define SSB_CHIPCO_CLKSTSTR 0x00C4 /* Rev >= 3 only */ ++#define SSB_CHIPCO_EROM 0xFC /* erom for ai socs */ + #define SSB_CHIPCO_PCMCIA_CFG 0x0100 + #define SSB_CHIPCO_PCMCIA_MEMWAIT 0x0104 + #define SSB_CHIPCO_PCMCIA_ATTRWAIT 0x0108 +@@ -298,6 +302,28 @@ + #define SSB_PMU1_PLLCTL5_CLKDRV 0xFFFFFF00 /* clk drv */ + #define SSB_PMU1_PLLCTL5_CLKDRV_SHIFT 8 + ++/* PMU rev 5 (& 6) */ ++#define SSB_PMU5_PLL_P1P2_OFF 0 ++#define SSB_PMU5_PLL_P1_MASK 0x0f000000 ++#define SSB_PMU5_PLL_P1_SHIFT 24 ++#define SSB_PMU5_PLL_P2_MASK 0x00f00000 ++#define SSB_PMU5_PLL_P2_SHIFT 20 ++#define SSB_PMU5_PLL_M14_OFF 1 ++#define SSB_PMU5_PLL_MDIV_MASK 0x000000ff ++#define SSB_PMU5_PLL_MDIV_WIDTH 8 ++#define SSB_PMU5_PLL_NM5_OFF 2 ++#define SSB_PMU5_PLL_NDIV_MASK 0xfff00000 ++#define SSB_PMU5_PLL_NDIV_SHIFT 20 ++#define SSB_PMU5_PLL_FMAB_OFF 3 ++#define SSB_PMU5_PLL_MRAT_MASK 0xf0000000 ++#define SSB_PMU5_PLL_MRAT_SHIFT 28 ++#define SSB_PMU5_PLL_ABRAT_MASK 0x08000000 ++#define SSB_PMU5_PLL_ABRAT_SHIFT 27 ++#define SSB_PMU5_PLL_FDIV_MASK 0x07ffffff ++#define SSB_PMU5_PLL_PLLCTL_OFF 4 ++#define SSB_PMU5_PLL_PCHI_OFF 5 ++#define SSB_PMU5_PLL_PCHI_MASK 0x0000003f ++ + /* BCM4312 PLL resource numbers. */ + #define SSB_PMURES_4312_SWITCHER_BURST 0 + #define SSB_PMURES_4312_SWITCHER_PWM 1
_______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/mailman/listinfo/openwrt-devel