diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-06-26 20:41:59 +0000 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2010-06-26 20:41:59 +0000 |
commit | d3ec4c6f75195bf79f15804024036a5eb6c0b94d (patch) | |
tree | 1c3c36fd5f358bb19c2b181de417425f68444d82 /target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c | |
parent | 19a9284b9a6fd60ac78a129052cc677a39abf3cb (diff) | |
download | master-187ad058-d3ec4c6f75195bf79f15804024036a5eb6c0b94d.tar.gz master-187ad058-d3ec4c6f75195bf79f15804024036a5eb6c0b94d.tar.bz2 master-187ad058-d3ec4c6f75195bf79f15804024036a5eb6c0b94d.zip |
remove the brcm-2.4 target, it will no longer be supported in future releases. please use brcm47xx with broadcom-wl instead
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@21946 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c')
-rw-r--r-- | target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c | 780 |
1 files changed, 0 insertions, 780 deletions
diff --git a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c b/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c deleted file mode 100644 index c8846e7743..0000000000 --- a/target/linux/brcm-2.4/files/arch/mips/bcm947xx/sbpci.c +++ /dev/null @@ -1,780 +0,0 @@ -/* - * Low-Level PCI and SB support for BCM47xx - * - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - */ - -#include <typedefs.h> -#include <osl.h> -#include <pcicfg.h> -#include <bcmdevs.h> -#include <sbconfig.h> -#include <sbutils.h> -#include <sbpci.h> -#include <bcmendian.h> -#include <bcmnvram.h> -#include <hndcpu.h> -#include <hndmips.h> -#include <hndpci.h> - -/* debug/trace */ -#ifdef BCMDBG_PCI -#define PCI_MSG(args) printf args -#else -#define PCI_MSG(args) -#endif /* BCMDBG_PCI */ - -/* Can free sbpci_init() memory after boot */ -#ifndef linux -#define __init -#endif /* linux */ - -/* Emulated configuration space */ -typedef struct { - int n; - uint size0; - uint size1; - uint size2; - uint size3; -} sb_bar_cfg_t; -static pci_config_regs sb_config_regs[SB_MAXCORES]; -static sb_bar_cfg_t sb_bar_cfg[SB_MAXCORES]; - -/* Links to emulated and real PCI configuration spaces */ -#define MAXFUNCS 2 -typedef struct { - pci_config_regs *emu; /* emulated PCI config */ - pci_config_regs *pci; /* real PCI config */ - sb_bar_cfg_t *bar; /* region sizes */ -} sb_pci_cfg_t; -static sb_pci_cfg_t sb_pci_cfg[SB_MAXCORES][MAXFUNCS]; - -/* Special emulated config space for non-existing device */ -static pci_config_regs sb_pci_null = { 0xffff, 0xffff }; - -/* Banned cores */ -static uint16 pci_ban[SB_MAXCORES] = { 0 }; -static uint pci_banned = 0; - -/* CardBus mode */ -static bool cardbus = FALSE; - -/* Disable PCI host core */ -static bool pci_disabled = FALSE; - -/* Host bridge slot #, default to 0 */ -static uint8 pci_hbslot = 0; - -/* Internal macros */ -#define PCI_SLOTAD_MAP 16 /* SLOT<n> mapps to AD<n+16> */ -#define PCI_HBSBCFG_REV 8 /* MIN. core rev. required to - * access host bridge PCI cfg space - * from SB - */ - -/* - * Functions for accessing external PCI configuration space - */ - -/* Assume one-hot slot wiring */ -#define PCI_SLOT_MAX 16 /* Max. PCI Slots */ - -static uint32 config_cmd(sb_t * sbh, uint bus, uint dev, uint func, uint off) -{ - uint coreidx; - sbpciregs_t *regs; - uint32 addr = 0; - osl_t *osh; - - /* CardBusMode supports only one device */ - if (cardbus && dev > 1) - return 0; - - osh = sb_osh(sbh); - - coreidx = sb_coreidx(sbh); - regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); - - /* Type 0 transaction */ - if (bus == 1) { - /* Skip unwired slots */ - if (dev < PCI_SLOT_MAX) { - uint32 win; - - /* Slide the PCI window to the appropriate slot */ - win = - (SBTOPCI_CFG0 | - ((1 << (dev + PCI_SLOTAD_MAP)) & SBTOPCI1_MASK)); - W_REG(osh, ®s->sbtopci1, win); - addr = SB_PCI_CFG | - ((1 << (dev + PCI_SLOTAD_MAP)) & ~SBTOPCI1_MASK) | - (func << PCICFG_FUN_SHIFT) | (off & ~3); - } - } else { - /* Type 1 transaction */ - W_REG(osh, ®s->sbtopci1, SBTOPCI_CFG1); - addr = SB_PCI_CFG | - (bus << PCICFG_BUS_SHIFT) | - (dev << PCICFG_SLOT_SHIFT) | - (func << PCICFG_FUN_SHIFT) | (off & ~3); - } - - sb_setcoreidx(sbh, coreidx); - - return addr; -} - -/* - * Read host bridge PCI config registers from Silicon Backplane (>=rev8). - * - * It returns TRUE to indicate that access to the host bridge's pci config - * from SB is ok, and values in 'addr' and 'val' are valid. - * - * It can only read registers at multiple of 4-bytes. Callers must pick up - * needed bytes from 'val' based on 'off' value. Value in 'addr' reflects - * the register address where value in 'val' is read. - */ -static bool -sb_pcihb_read_config(sb_t * sbh, uint bus, uint dev, uint func, uint off, - uint32 ** addr, uint32 * val) -{ - sbpciregs_t *regs; - osl_t *osh; - uint coreidx; - bool ret = FALSE; - - /* sanity check */ - ASSERT(bus == 1); - ASSERT(dev == pci_hbslot); - ASSERT(func == 0); - - osh = sb_osh(sbh); - - /* read pci config when core rev >= 8 */ - coreidx = sb_coreidx(sbh); - regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); - if (regs && sb_corerev(sbh) >= PCI_HBSBCFG_REV) { - *addr = (uint32 *) & regs->pcicfg[func][off >> 2]; - *val = R_REG(osh, *addr); - ret = TRUE; - } - sb_setcoreidx(sbh, coreidx); - - return ret; -} - -int -extpci_read_config(sb_t * sbh, uint bus, uint dev, uint func, uint off, - void *buf, int len) -{ - uint32 addr = 0, *reg = NULL, val; - int ret = 0; - - /* - * Set value to -1 when: - * flag 'pci_disabled' is true; - * value of 'addr' is zero; - * REG_MAP() fails; - * BUSPROBE() fails; - */ - if (pci_disabled) - val = 0xffffffff; - else if (bus == 1 && dev == pci_hbslot && func == 0 && - sb_pcihb_read_config(sbh, bus, dev, func, off, ®, &val)) ; - else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) || - ((reg = (uint32 *) REG_MAP(addr, len)) == 0) || - (BUSPROBE(val, reg) != 0)) - val = 0xffffffff; - - PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n", - __FUNCTION__, val, reg, addr, len, off, buf)); - - val >>= 8 * (off & 3); - if (len == 4) - *((uint32 *) buf) = val; - else if (len == 2) - *((uint16 *) buf) = (uint16) val; - else if (len == 1) - *((uint8 *) buf) = (uint8) val; - else - ret = -1; - - if (reg && addr) - REG_UNMAP(reg); - - return ret; -} - -int -extpci_write_config(sb_t * sbh, uint bus, uint dev, uint func, uint off, - void *buf, int len) -{ - osl_t *osh; - uint32 addr = 0, *reg = NULL, val; - int ret = 0; - - osh = sb_osh(sbh); - - /* - * Ignore write attempt when: - * flag 'pci_disabled' is true; - * value of 'addr' is zero; - * REG_MAP() fails; - * BUSPROBE() fails; - */ - if (pci_disabled) - return 0; - else if (bus == 1 && dev == pci_hbslot && func == 0 && - sb_pcihb_read_config(sbh, bus, dev, func, off, ®, &val)) ; - else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) || - ((reg = (uint32 *) REG_MAP(addr, len)) == 0) || - (BUSPROBE(val, reg) != 0)) - goto done; - - if (len == 4) - val = *((uint32 *) buf); - else if (len == 2) { - val &= ~(0xffff << (8 * (off & 3))); - val |= *((uint16 *) buf) << (8 * (off & 3)); - } else if (len == 1) { - val &= ~(0xff << (8 * (off & 3))); - val |= *((uint8 *) buf) << (8 * (off & 3)); - } else { - ret = -1; - goto done; - } - - PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__, val, reg)); - - W_REG(osh, reg, val); - - done: - if (reg && addr) - REG_UNMAP(reg); - - return ret; -} - -/* - * Must access emulated PCI configuration at these locations even when - * the real PCI config space exists and is accessible. - * - * PCI_CFG_VID (0x00) - * PCI_CFG_DID (0x02) - * PCI_CFG_PROGIF (0x09) - * PCI_CFG_SUBCL (0x0a) - * PCI_CFG_BASECL (0x0b) - * PCI_CFG_HDR (0x0e) - * PCI_CFG_INT (0x3c) - * PCI_CFG_PIN (0x3d) - */ -#define FORCE_EMUCFG(off, len) \ - ((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \ - (off == PCI_CFG_PROGIF) || \ - (off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \ - (off == PCI_CFG_HDR) || \ - (off == PCI_CFG_INT) || (off == PCI_CFG_PIN)) - -/* Sync the emulation registers and the real PCI config registers. */ -static void -sb_pcid_read_config(sb_t * sbh, uint coreidx, sb_pci_cfg_t * cfg, - uint off, uint len) -{ - osl_t *osh; - uint oldidx; - - ASSERT(cfg); - ASSERT(cfg->emu); - ASSERT(cfg->pci); - - /* decide if real PCI config register access is necessary */ - if (FORCE_EMUCFG(off, len)) - return; - - osh = sb_osh(sbh); - - /* access to the real pci config space only when the core is up */ - oldidx = sb_coreidx(sbh); - sb_setcoreidx(sbh, coreidx); - if (sb_iscoreup(sbh)) { - if (len == 4) - *(uint32 *) ((ulong) cfg->emu + off) = - htol32(R_REG - (osh, (uint32 *) ((ulong) cfg->pci + off))); - else if (len == 2) - *(uint16 *) ((ulong) cfg->emu + off) = - htol16(R_REG - (osh, (uint16 *) ((ulong) cfg->pci + off))); - else if (len == 1) - *(uint8 *) ((ulong) cfg->emu + off) = - R_REG(osh, (uint8 *) ((ulong) cfg->pci + off)); - } - sb_setcoreidx(sbh, oldidx); -} - -static void -sb_pcid_write_config(sb_t * sbh, uint coreidx, sb_pci_cfg_t * cfg, - uint off, uint len) -{ - osl_t *osh; - uint oldidx; - - ASSERT(cfg); - ASSERT(cfg->emu); - ASSERT(cfg->pci); - - osh = sb_osh(sbh); - - /* decide if real PCI config register access is necessary */ - if (FORCE_EMUCFG(off, len)) - return; - - /* access to the real pci config space only when the core is up */ - oldidx = sb_coreidx(sbh); - sb_setcoreidx(sbh, coreidx); - if (sb_iscoreup(sbh)) { - if (len == 4) - W_REG(osh, (uint32 *) ((ulong) cfg->pci + off), - ltoh32(*(uint32 *) ((ulong) cfg->emu + off))); - else if (len == 2) - W_REG(osh, (uint16 *) ((ulong) cfg->pci + off), - ltoh16(*(uint16 *) ((ulong) cfg->emu + off))); - else if (len == 1) - W_REG(osh, (uint8 *) ((ulong) cfg->pci + off), - *(uint8 *) ((ulong) cfg->emu + off)); - } - sb_setcoreidx(sbh, oldidx); -} - -/* - * Functions for accessing translated SB configuration space - */ -static int -sb_read_config(sb_t * sbh, uint bus, uint dev, uint func, uint off, void *buf, - int len) -{ - pci_config_regs *cfg; - - if (dev >= SB_MAXCORES || func >= MAXFUNCS - || (off + len) > sizeof(pci_config_regs)) - return -1; - cfg = sb_pci_cfg[dev][func].emu; - - ASSERT(ISALIGNED(off, len)); - ASSERT(ISALIGNED((uintptr) buf, len)); - - /* use special config space if the device does not exist */ - if (!cfg) - cfg = &sb_pci_null; - /* sync emulation with real PCI config if necessary */ - else if (sb_pci_cfg[dev][func].pci) - sb_pcid_read_config(sbh, dev, &sb_pci_cfg[dev][func], off, len); - - if (len == 4) - *((uint32 *) buf) = ltoh32(*((uint32 *) ((ulong) cfg + off))); - else if (len == 2) - *((uint16 *) buf) = ltoh16(*((uint16 *) ((ulong) cfg + off))); - else if (len == 1) - *((uint8 *) buf) = *((uint8 *) ((ulong) cfg + off)); - else - return -1; - - return 0; -} - -static int -sb_write_config(sb_t * sbh, uint bus, uint dev, uint func, uint off, void *buf, - int len) -{ - uint coreidx; - void *regs; - pci_config_regs *cfg; - osl_t *osh; - sb_bar_cfg_t *bar; - - if (dev >= SB_MAXCORES || func >= MAXFUNCS - || (off + len) > sizeof(pci_config_regs)) - return -1; - cfg = sb_pci_cfg[dev][func].emu; - if (!cfg) - return -1; - - ASSERT(ISALIGNED(off, len)); - ASSERT(ISALIGNED((uintptr) buf, len)); - - osh = sb_osh(sbh); - - /* Emulate BAR sizing */ - if (off >= OFFSETOF(pci_config_regs, base[0]) && - off <= OFFSETOF(pci_config_regs, base[3]) && - len == 4 && *((uint32 *) buf) == ~0) { - coreidx = sb_coreidx(sbh); - if ((regs = sb_setcoreidx(sbh, dev))) { - bar = sb_pci_cfg[dev][func].bar; - /* Highest numbered address match register */ - if (off == OFFSETOF(pci_config_regs, base[0])) - cfg->base[0] = ~(bar->size0 - 1); - else if (off == OFFSETOF(pci_config_regs, base[1]) - && bar->n >= 1) - cfg->base[1] = ~(bar->size1 - 1); - else if (off == OFFSETOF(pci_config_regs, base[2]) - && bar->n >= 2) - cfg->base[2] = ~(bar->size2 - 1); - else if (off == OFFSETOF(pci_config_regs, base[3]) - && bar->n >= 3) - cfg->base[3] = ~(bar->size3 - 1); - } - sb_setcoreidx(sbh, coreidx); - } else if (len == 4) - *((uint32 *) ((ulong) cfg + off)) = htol32(*((uint32 *) buf)); - else if (len == 2) - *((uint16 *) ((ulong) cfg + off)) = htol16(*((uint16 *) buf)); - else if (len == 1) - *((uint8 *) ((ulong) cfg + off)) = *((uint8 *) buf); - else - return -1; - - /* sync emulation with real PCI config if necessary */ - if (sb_pci_cfg[dev][func].pci) - sb_pcid_write_config(sbh, dev, &sb_pci_cfg[dev][func], off, - len); - - return 0; -} - -int -sbpci_read_config(sb_t * sbh, uint bus, uint dev, uint func, uint off, - void *buf, int len) -{ - if (bus == 0) - return sb_read_config(sbh, bus, dev, func, off, buf, len); - else - return extpci_read_config(sbh, bus, dev, func, off, buf, len); -} - -int -sbpci_write_config(sb_t * sbh, uint bus, uint dev, uint func, uint off, - void *buf, int len) -{ - if (bus == 0) - return sb_write_config(sbh, bus, dev, func, off, buf, len); - else - return extpci_write_config(sbh, bus, dev, func, off, buf, len); -} - -void sbpci_ban(uint16 core) -{ - if (pci_banned < ARRAYSIZE(pci_ban)) - pci_ban[pci_banned++] = core; -} - -/* - * Initiliaze PCI core. Return 0 after a successful initialization. - * Otherwise return -1 to indicate there is no PCI core and return 1 - * to indicate PCI core is disabled. - */ -int __init sbpci_init_pci(sb_t * sbh) -{ - uint chip, chiprev, chippkg, host; - uint32 boardflags; - sbpciregs_t *pci; - sbconfig_t *sb; - uint32 val; - int ret = 0; - char *hbslot; - osl_t *osh; - - chip = sb_chip(sbh); - chiprev = sb_chiprev(sbh); - chippkg = sb_chippkg(sbh); - - osh = sb_osh(sbh); - - if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) { - printk("PCI: no core\n"); - pci_disabled = TRUE; - return -1; - } - - if ((chip == 0x4310) && (chiprev == 0)) - pci_disabled = TRUE; - - sb = (sbconfig_t *) ((ulong) pci + SBCONFIGOFF); - - boardflags = (uint32) getintvar(NULL, "boardflags"); - - /* - * The 200-pin BCM4712 package does not bond out PCI. Even when - * PCI is bonded out, some boards may leave the pins - * floating. - */ - if (((chip == BCM4712_CHIP_ID) && - ((chippkg == BCM4712SMALL_PKG_ID) || - (chippkg == BCM4712MID_PKG_ID))) || (boardflags & BFL_NOPCI)) - pci_disabled = TRUE; - - /* Enable the core */ - sb_core_reset(sbh, 0, 0); - - /* - * If the PCI core should not be touched (disabled, not bonded - * out, or pins floating), do not even attempt to access core - * registers. Otherwise, try to determine if it is in host - * mode. - */ - if (pci_disabled) - host = 0; - else - host = !BUSPROBE(val, &pci->control); - - if (!host) { - ret = 1; - - /* Disable PCI interrupts in client mode */ - W_REG(osh, &sb->sbintvec, 0); - - /* Disable the PCI bridge in client mode */ - sbpci_ban(SB_PCI); - sb_core_disable(sbh, 0); - - printk("PCI: Disabled\n"); - } else { - printk("PCI: Initializing host\n"); - - /* Disable PCI SBReqeustTimeout for BCM4785 */ - if (chip == BCM4785_CHIP_ID) { - AND_REG(osh, &sb->sbimconfiglow, ~0x00000070); - sb_commit(sbh); - } - - /* Reset the external PCI bus and enable the clock */ - W_REG(osh, &pci->control, 0x5); /* enable the tristate drivers */ - W_REG(osh, &pci->control, 0xd); /* enable the PCI clock */ - OSL_DELAY(150); /* delay > 100 us */ - W_REG(osh, &pci->control, 0xf); /* deassert PCI reset */ - /* Use internal arbiter and park REQ/GRNT at external master 0 */ - W_REG(osh, &pci->arbcontrol, PCI_INT_ARB); - OSL_DELAY(1); /* delay 1 us */ - if (sb_corerev(sbh) >= 8) { - val = getintvar(NULL, "parkid"); - ASSERT(val <= PCI_PARKID_LAST); - OR_REG(osh, &pci->arbcontrol, val << PCI_PARKID_SHIFT); - OSL_DELAY(1); - } - - /* Enable CardBusMode */ - cardbus = getintvar(NULL, "cardbus") == 1; - if (cardbus) { - printk("PCI: Enabling CardBus\n"); - /* GPIO 1 resets the CardBus device on bcm94710ap */ - sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY); - sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY); - W_REG(osh, &pci->sprom[0], - R_REG(osh, &pci->sprom[0]) | 0x400); - } - - /* 64 MB I/O access window */ - W_REG(osh, &pci->sbtopci0, SBTOPCI_IO); - /* 64 MB configuration access window */ - W_REG(osh, &pci->sbtopci1, SBTOPCI_CFG0); - /* 1 GB memory access window */ - W_REG(osh, &pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA); - - /* Host bridge slot # nvram overwrite */ - if ((hbslot = nvram_get("pcihbslot"))) { - pci_hbslot = simple_strtoul(hbslot, NULL, 0); - ASSERT(pci_hbslot < PCI_MAX_DEVICES); - } - - /* Enable PCI bridge BAR0 prefetch and burst */ - val = 6; - sbpci_write_config(sbh, 1, pci_hbslot, 0, PCI_CFG_CMD, &val, - sizeof(val)); - - /* Enable PCI interrupts */ - W_REG(osh, &pci->intmask, PCI_INTA); - } - - return ret; -} - -/* - * Get the PCI region address and size information. - */ -static void __init -sbpci_init_regions(sb_t * sbh, uint func, pci_config_regs * cfg, - sb_bar_cfg_t * bar) -{ - osl_t *osh; - uint16 coreid; - void *regs; - sbconfig_t *sb; - uint32 base; - - osh = sb_osh(sbh); - coreid = sb_coreid(sbh); - regs = sb_coreregs(sbh); - sb = (sbconfig_t *) ((ulong) regs + SBCONFIGOFF); - - switch (coreid) { - case SB_USB20H: - base = htol32(sb_base(R_REG(osh, &sb->sbadmatch0))); - - cfg->base[0] = func == 0 ? base : base + 0x800; /* OHCI/EHCI */ - cfg->base[1] = 0; - cfg->base[2] = 0; - cfg->base[3] = 0; - cfg->base[4] = 0; - cfg->base[5] = 0; - bar->n = 1; - bar->size0 = func == 0 ? 0x200 : 0x100; /* OHCI/EHCI */ - bar->size1 = 0; - bar->size2 = 0; - bar->size3 = 0; - break; - default: - cfg->base[0] = htol32(sb_base(R_REG(osh, &sb->sbadmatch0))); - cfg->base[1] = htol32(sb_base(R_REG(osh, &sb->sbadmatch1))); - cfg->base[2] = htol32(sb_base(R_REG(osh, &sb->sbadmatch2))); - cfg->base[3] = htol32(sb_base(R_REG(osh, &sb->sbadmatch3))); - cfg->base[4] = 0; - cfg->base[5] = 0; - bar->n = - (R_REG(osh, &sb->sbidlow) & SBIDL_AR_MASK) >> - SBIDL_AR_SHIFT; - bar->size0 = sb_size(R_REG(osh, &sb->sbadmatch0)); - bar->size1 = sb_size(R_REG(osh, &sb->sbadmatch1)); - bar->size2 = sb_size(R_REG(osh, &sb->sbadmatch2)); - bar->size3 = sb_size(R_REG(osh, &sb->sbadmatch3)); - break; - } -} - -/* - * Construct PCI config spaces for SB cores so that they - * can be accessed as if they were PCI devices. - */ -static void __init sbpci_init_cores(sb_t * sbh) -{ - uint chiprev, coreidx, i; - sbconfig_t *sb; - pci_config_regs *cfg, *pci; - sb_bar_cfg_t *bar; - void *regs; - osl_t *osh; - uint16 vendor, device; - uint16 coreid; - uint8 class, subclass, progif; - uint dev; - uint8 header; - uint func; - - chiprev = sb_chiprev(sbh); - coreidx = sb_coreidx(sbh); - - osh = sb_osh(sbh); - - /* Scan the SB bus */ - bzero(sb_config_regs, sizeof(sb_config_regs)); - bzero(sb_bar_cfg, sizeof(sb_bar_cfg)); - bzero(sb_pci_cfg, sizeof(sb_pci_cfg)); - memset(&sb_pci_null, -1, sizeof(sb_pci_null)); - cfg = sb_config_regs; - bar = sb_bar_cfg; - for (dev = 0; dev < SB_MAXCORES; dev++) { - /* Check if the core exists */ - if (!(regs = sb_setcoreidx(sbh, dev))) - continue; - sb = (sbconfig_t *) ((ulong) regs + SBCONFIGOFF); - - /* Check if this core is banned */ - coreid = sb_coreid(sbh); - for (i = 0; i < pci_banned; i++) - if (coreid == pci_ban[i]) - break; - if (i < pci_banned) - continue; - - for (func = 0; func < MAXFUNCS; ++func) { - /* Make sure we won't go beyond the limit */ - if (cfg >= &sb_config_regs[SB_MAXCORES]) { - printk("PCI: too many emulated devices\n"); - goto done; - } - - /* Convert core id to pci id */ - if (sb_corepciid - (sbh, func, &vendor, &device, &class, &subclass, - &progif, &header)) - continue; - - /* - * Differentiate real PCI config from emulated. - * non zero 'pci' indicate there is a real PCI config space - * for this device. - */ - switch (device) { - case BCM47XX_GIGETH_ID: - pci = - (pci_config_regs *) ((uint32) regs + 0x800); - break; - case BCM47XX_SATAXOR_ID: - pci = - (pci_config_regs *) ((uint32) regs + 0x400); - break; - case BCM47XX_ATA100_ID: - pci = - (pci_config_regs *) ((uint32) regs + 0x800); - break; - default: - pci = NULL; - break; - } - /* Supported translations */ - cfg->vendor = htol16(vendor); - cfg->device = htol16(device); - cfg->rev_id = chiprev; - cfg->prog_if = progif; - cfg->sub_class = subclass; - cfg->base_class = class; - cfg->header_type = header; - sbpci_init_regions(sbh, func, cfg, bar); - /* Save core interrupt flag */ - cfg->int_pin = - R_REG(osh, &sb->sbtpsflag) & SBTPS_NUM0_MASK; - /* Save core interrupt assignment */ - cfg->int_line = sb_irq(sbh); - /* Indicate there is no SROM */ - *((uint32 *) & cfg->sprom_control) = 0xffffffff; - - /* Point to the PCI config spaces */ - sb_pci_cfg[dev][func].emu = cfg; - sb_pci_cfg[dev][func].pci = pci; - sb_pci_cfg[dev][func].bar = bar; - cfg++; - bar++; - } - } - - done: - sb_setcoreidx(sbh, coreidx); -} - -/* - * Initialize PCI core and construct PCI config spaces for SB cores. - * Must propagate sbpci_init_pci() return value to the caller to let - * them know the PCI core initialization status. - */ -int __init sbpci_init(sb_t * sbh) -{ - int status = sbpci_init_pci(sbh); - sbpci_init_cores(sbh); - return status; -} |