// SPDX-License-Identifier: GPL-2.0-or-later /* ** ** PCI Lower Bus Adapter (LBA) manager ** ** (c) Copyright 1999,2000 Grant Grundler ** (c) Copyright 1999,2000 Hewlett-Packard Company ** ** ** ** This module primarily provides access to PCI bus (config/IOport ** spaces) on platforms with an SBA/LBA chipset. A/B/C/J/L/N-class ** with 4 digit model numbers - eg C3000 (and A400...sigh). ** ** LBA driver isn't as simple as the Dino driver because: ** (a) this chip has substantial bug fixes between revisions ** (Only one Dino bug has a software workaround :^( ) ** (b) has more options which we don't (yet) support (DMA hints, OLARD) ** (c) IRQ support lives in the I/O SAPIC driver (not with PCI driver) ** (d) play nicely with both PAT and "Legacy" PA-RISC firmware (PDC). ** (dino only deals with "Legacy" PDC) ** ** LBA driver passes the I/O SAPIC HPA to the I/O SAPIC driver. ** (I/O SAPIC is integratd in the LBA chip). ** ** FIXME: Add support to SBA and LBA drivers for DMA hint sets ** FIXME: Add support for PCI card hot-plug (OLARD).
*/
/* ** Config accessor functions only pass in the 8-bit bus number and not ** the 8-bit "PCI Segment" number. Each LBA will be assigned a PCI bus ** number based on what firmware wrote into the scratch register. ** ** The "secondary" bus number is set to this before calling ** pci_register_ops(). If any PPB's are present, the scan will ** discover them and update the "secondary" and "subordinate" ** fields in the pci_bus structure. ** ** Changes in the configuration *may* result in a different ** bus number for each LBA depending on what firmware does.
*/
/* ** Extract LBA (Rope) number from HPA ** REVISIT: 16 ropes for Stretch/Ike?
*/ #define ROPES_PER_IOC 8 #define LBA_NUM(x) ((((unsignedlong) x) >> 13) & (ROPES_PER_IOC-1))
staticvoid
lba_dump_res(struct resource *r, int d)
{ int i;
if (NULL == r) return;
printk(KERN_DEBUG "(%p)", r->parent); for (i = d; i ; --i) printk(" ");
printk(KERN_DEBUG "%p [%lx,%lx]/%lx\n", r,
(long)r->start, (long)r->end, r->flags);
lba_dump_res(r->child, d+2);
lba_dump_res(r->sibling, d);
}
/* ** LBA rev 2.0, 2.1, 2.2, and 3.0 bus walks require a complex ** workaround for cfg cycles: ** -- preserve LBA state ** -- prevent any DMA from occurring ** -- turn on smart mode ** -- probe with config writes before doing config reads ** -- check ERROR_STATUS ** -- clear ERROR_STATUS ** -- restore LBA state ** ** The workaround is only used for device discovery.
*/
#define LBA_CFG_SETUP(d, tok) { \ /* Save contents of error config register. */ \
error_config = READ_REG32(d->hba.base_addr + LBA_ERROR_CONFIG); \
\ /* Save contents of status control register. */ \
status_control = READ_REG32(d->hba.base_addr + LBA_STAT_CTL); \
\ /* For LBA rev 2.0, 2.1, 2.2, and 3.0, we must disable DMA \ ** arbitration for full bus walks. \
*/ /* Save contents of arb mask register. */ \
arb_mask = READ_REG32(d->hba.base_addr + LBA_ARB_MASK); \
\ /* \ * Turn off all device arbitration bits (i.e. everything \ * except arbitration enable bit). \
*/
WRITE_REG32(0x1, d->hba.base_addr + LBA_ARB_MASK); \
\ /* \ * Set the smart mode bit so that master aborts don't cause \ * LBA to go into PCI fatal mode (required). \
*/
WRITE_REG32(error_config | LBA_SMART_MODE, d->hba.base_addr + LBA_ERROR_CONFIG); \
}
#define LBA_CFG_PROBE(d, tok) { \ /* \ * Setup Vendor ID write and read back the address register \ * to make sure that LBA is the bus master. \
*/
WRITE_REG32(tok | PCI_VENDOR_ID, (d)->hba.base_addr + LBA_PCI_CFG_ADDR);\ /* \ * Read address register to ensure that LBA is the bus master, \ * which implies that DMA traffic has stopped when DMA arb is off. \
*/
lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR); \ /* \ * Generate a cfg write cycle (will have no affect on \ * Vendor ID register since read-only). \
*/
WRITE_REG32(~0, (d)->hba.base_addr + LBA_PCI_CFG_DATA); \ /* \ * Make sure write has completed before proceeding further, \ * i.e. before setting clear enable. \
*/
lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
}
/* * HPREVISIT: * -- Can't tell if config cycle got the error. * * OV bit is broken until rev 4.0, so can't use OV bit and * LBA_ERROR_LOG_ADDR to tell if error belongs to config cycle. * * As of rev 4.0, no longer need the error check. * * -- Even if we could tell, we still want to return -1 * for **ANY** error (not just master abort). * * -- Only clear non-fatal errors (we don't want to bring * LBA out of pci-fatal mode). * * Actually, there is still a race in which * we could be clearing a fatal error. We will * live with this during our initial bus walk * until rev 4.0 (no driver activity during * initial bus walk). The initial bus walk * has race conditions concerning the use of * smart mode as well.
*/
#define LBA_CFG_ADDR_SETUP(d, addr) { \
WRITE_REG32(((addr) & ~3), (d)->hba.base_addr + LBA_PCI_CFG_ADDR); \ /* \ * Read address register to ensure that LBA is the bus master, \ * which implies that DMA traffic has stopped when DMA arb is off. \
*/
lba_t32 = READ_REG32((d)->hba.base_addr + LBA_PCI_CFG_ADDR); \
}
#define LBA_CFG_RESTORE(d, base) { \ /* \ * Restore status control register (turn off clear enable). \
*/
WRITE_REG32(status_control, base + LBA_STAT_CTL); \ /* \ * Restore error config register (turn off smart mode). \
*/
WRITE_REG32(error_config, base + LBA_ERROR_CONFIG); \ /* \ * Restore arb mask register (reenables DMA arbitration). \
*/
WRITE_REG32(arb_mask, base + LBA_ARB_MASK); \
}
staticunsignedint
lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size)
{
u32 data = ~0U; int error = 0;
u32 arb_mask = 0; /* used by LBA_CFG_SETUP/RESTORE */
u32 error_config = 0; /* used by LBA_CFG_SETUP/RESTORE */
u32 status_control = 0; /* used by LBA_CFG_SETUP/RESTORE */
/* FIXME: B2K/C3600 workaround is always use old method... */ /* if (!LBA_SKIP_PROBE(d)) */ { /* original - Generate config cycle on broken elroy
with risk we will miss PCI bus errors. */
*data = lba_rd_cfg(d, tok, pos, size);
DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __func__, tok, pos, *data); return 0;
}
if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->busn_res.start, devfn, d)) {
DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __func__, tok, pos); /* either don't want to look or know device isn't present. */
*data = ~0U; return(0);
}
/* Basic Algorithm ** Should only get here on fully working LBA rev. ** This is how simple the code should have been.
*/
LBA_CFG_ADDR_SETUP(d, tok | pos); switch(size) { case 1: *data = READ_REG8 (data_reg + (pos & 3)); break; case 2: *data = READ_REG16(data_reg + (pos & 2)); break; case 4: *data = READ_REG32(data_reg); break;
}
DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __func__, tok, pos, *data); return 0;
}
/* * The mercury_cfg_ops are slightly misnamed; they're also used for Elroy * TR4.0 as no additional bugs were found in this areea between Elroy and * Mercury
*/
/* * truncate_pat_collision: Deal with overlaps or outright collisions * between PAT PDC reported ranges. * * Broken PA8800 firmware will report lmmio range that * overlaps with CPU HPA. Just truncate the lmmio range. * * BEWARE: conflicts with this lmmio range may be an * elmmio range which is pointing down another rope. * * FIXME: only deals with one collision per range...theoretically we * could have several. Supporting more than one collision will get messy.
*/ staticunsignedlong
truncate_pat_collision(struct resource *root, struct resource *new)
{ unsignedlong start = new->start; unsignedlong end = new->end; struct resource *tmp = root->child;
/* * extend_lmmio_len: extend lmmio range to maximum length * * This is needed at least on C8000 systems to get the ATI FireGL card * working. On other systems we will currently not extend the lmmio space.
*/ staticunsignedlong
extend_lmmio_len(unsignedlong start, unsignedlong end, unsignedlong lba_len)
{ struct resource *tmp;
/* exit if not a C8000 */ if (boot_cpu_data.cpu_type < mako) return end;
pr_debug("LMMIO mismatch: PAT length = 0x%lx, MASK register = 0x%lx\n",
end - start, lba_len);
lba_len = min(lba_len+1, 256UL*1024*1024); /* limit to 256 MB */
/* Depth-First Search on bus tree */ if (bus->self)
pcibios_allocate_bridge_resources(bus->self);
list_for_each_entry(child, &bus->children, node)
pcibios_allocate_bus_resources(child);
}
/* ** The algorithm is generic code. ** But it needs to access local data structures to get the IRQ base. ** Could make this a "pci_fixup_irq(bus, region)" but not sure ** it's worth it. ** ** Called by do_pci_scan_bus() immediately after each PCI bus is walked. ** Resources aren't allocated until recursive buswalk below HBA is completed.
*/ staticvoid
lba_fixup_bus(struct pci_bus *bus)
{ struct pci_dev *dev; #ifdef FBB_SUPPORT
u16 status; #endif struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge));
DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n",
bus, (int)bus->busn_res.start, bus->bridge->platform_data);
/* ** Properly Setup MMIO resources for this bus. ** pci_alloc_primary_bus() mangles this.
*/ if (bus->parent) { /* PCI-PCI Bridge */
pci_read_bridge_bases(bus);
/* check and allocate bridge resources */
pcibios_allocate_bus_resources(bus);
} else { /* Host-PCI Bridge */ int err;
if (ldev->hba.lmmio_space.flags) {
err = request_resource(&iomem_resource, &(ldev->hba.lmmio_space)); if (err < 0) {
printk(KERN_ERR "FAILED: lba_fixup_bus() request for " "lmmio_space [%lx/%lx]\n",
(long)ldev->hba.lmmio_space.start,
(long)ldev->hba.lmmio_space.end);
}
}
#ifdef CONFIG_64BIT /* GMMIO is distributed range. Every LBA/Rope gets part it. */ if (ldev->hba.gmmio_space.flags) {
err = request_resource(&iomem_resource, &(ldev->hba.gmmio_space)); if (err < 0) {
printk("FAILED: lba_fixup_bus() request for " "gmmio_space [%lx/%lx]\n",
(long)ldev->hba.gmmio_space.start,
(long)ldev->hba.gmmio_space.end);
lba_dump_res(&iomem_resource, 2);
BUG();
}
} #endif
}
list_for_each_entry(dev, &bus->devices, bus_list) { int i;
DBG("lba_fixup_bus() %s\n", pci_name(dev));
/* Virtualize Device/Bridge Resources. */ for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { struct resource *res = &dev->resource[i];
/* If resource not allocated - skip it */ if (!res->start) continue;
/* ** FIXME: this will result in whinging for devices ** that share expansion ROMs (think quad tulip), but ** isn't harmful.
*/
pci_claim_resource(dev, i);
}
#ifdef FBB_SUPPORT /* ** If one device does not support FBB transfers, ** No one on the bus can be allowed to use them.
*/
(void) pci_read_config_word(dev, PCI_STATUS, &status);
bus->bridge_ctl &= ~(status & PCI_STATUS_FAST_BACK); #endif
/* ** P2PB's have no IRQs. ignore them.
*/ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
pcibios_init_bridge(dev); continue;
}
/* Adjust INTERRUPT_LINE for this dev */
iosapic_fixup_irq(ldev->iosapic_obj, dev);
}
#ifdef FBB_SUPPORT /* FIXME/REVISIT - finish figuring out to set FBB on both ** pci_setup_bridge() clobbers PCI_BRIDGE_CONTROL. ** Can't fixup here anyway....garr...
*/ if (fbb_enable) { if (bus->parent) {
u8 control; /* enable on PPB */
(void) pci_read_config_byte(bus->self, PCI_BRIDGE_CONTROL, &control);
(void) pci_write_config_byte(bus->self, PCI_BRIDGE_CONTROL, control | PCI_STATUS_FAST_BACK);
/******************************************************* ** ** LBA Sprockets "I/O Port" Space Accessor Functions ** ** This set of accessor functions is intended for use with ** "legacy firmware" (ie Sprockets on Allegro/Forte boxes). ** ** Many PCI devices don't require use of I/O port space (eg Tulip, ** NCR720) since they export the same registers to both MMIO and ** I/O port space. In general I/O port space is slower than ** MMIO since drivers are designed so PIO writes can be posted. **
********************************************************/
/* ** BUG X4107: Ordering broken - DMA RD return can bypass PIO WR ** ** Fixed in Elroy 2.2. The READ_U32(..., LBA_FUNC_ID) below is ** guarantee non-postable completion semantics - not avoid X4107. ** The READ_U32 only guarantees the write data gets to elroy but ** out to the PCI bus. We can't read stuff from I/O port space ** since we don't know what has side-effects. Attempting to read ** from configuration space would be suicidal given the number of ** bugs in that elroy functionality. ** ** Description: ** DMA read results can improperly pass PIO writes (X4107). The ** result of this bug is that if a processor modifies a location in ** memory after having issued PIO writes, the PIO writes are not ** guaranteed to be completed before a PCI device is allowed to see ** the modified data in a DMA read. ** ** Note that IKE bug X3719 in TR1 IKEs will result in the same ** symptom. ** ** Workaround: ** The workaround for this bug is to always follow a PIO write with ** a PIO read to the same bus before starting DMA on that PCI bus. **
*/ #define LBA_PORT_OUT(size, mask) \ staticvoid lba_astro_out##size (struct pci_hba_data *d, u16 addr, u##size val) \
{ \
DBG_PORT("%s(0x%p, 0x%x, 0x%x)\n", __func__, d, addr, val); \
WRITE_REG##size(val, astro_iop_base + addr); \ if (LBA_DEV(d)->hw_rev < 3) \
lba_t32 = READ_U32(d->base_addr + LBA_FUNC_ID); \
}
/******************************************************* ** ** LBA PAT "I/O Port" Space Accessor Functions ** ** This set of accessor functions is intended for use with ** "PAT PDC" firmware (ie Prelude/Rhapsody/Piranha boxes). ** ** This uses the PIOP space located in the first 64MB of GMMIO. ** Each rope gets a full 64*KB* (ie 4 bytes per page) this way. ** bits 1:0 stay the same. bits 15:2 become 25:12. ** Then add the base and we can generate an I/O Port cycle.
********************************************************/ #undef LBA_PORT_IN #define LBA_PORT_IN(size, mask) \ static u##size lba_pat_in##size (struct pci_hba_data *l, u16 addr) \
{ \
u##size t; \
DBG_PORT("%s(0x%p, 0x%x) ->", __func__, l, addr); \
t = READ_REG##size(PIOP_TO_GMMIO(LBA_DEV(l), addr)); \
DBG_PORT(" 0x%x\n", t); \ return (t); \
}
/* ** make range information from PDC available to PCI subsystem. ** We make the PDC call here in order to get the PCI bus range ** numbers. The rest will get forwarded in pcibios_fixup_bus(). ** We don't have a struct pci_bus assigned to us yet.
*/ staticvoid
lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev)
{ unsignedlong bytecnt; long io_count __maybe_unused; long status; /* PDC return status */ long pa_count;
pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell; /* PA_VIEW */
pdc_pat_cell_mod_maddr_block_t *io_pdc_cell; /* IO_VIEW */ int i;
pa_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL); if (!pa_pdc_cell) return;
io_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL); if (!io_pdc_cell) {
kfree(pa_pdc_cell); return;
}
status |= pdc_pat_cell_module(&bytecnt, pa_dev->pcell_loc, pa_dev->mod_index,
IO_VIEW, io_pdc_cell);
io_count = io_pdc_cell->mod[1];
/* We've already done this once for device discovery...*/ if (status != PDC_OK) {
panic("pdc_pat_cell_module() call failed for LBA!\n");
}
if (PAT_GET_ENTITY(pa_pdc_cell->mod_info) != PAT_ENTITY_LBA) {
panic("pdc_pat_cell_module() entity returned != PAT_ENTITY_LBA!\n");
}
/* ** Inspect the resources PAT tells us about
*/ for (i = 0; i < pa_count; i++) { struct { unsignedlong type; unsignedlong start; unsignedlong end; /* aka finish */
} *p, *io; struct resource *r;
p = (void *) &(pa_pdc_cell->mod[2+i*3]);
io = (void *) &(io_pdc_cell->mod[2+i*3]);
/* Convert the PAT range data to PCI "struct resource" */ switch(p->type & 0xff) { case PAT_PBNUM:
lba_dev->hba.bus_num.start = p->start;
lba_dev->hba.bus_num.end = p->end;
lba_dev->hba.bus_num.flags = IORESOURCE_BUS; break;
case PAT_LMMIO: /* used to fix up pre-initialized MEM BARs */ if (!lba_dev->hba.lmmio_space.flags) { unsignedlong lba_len;
case PAT_GMMIO: /* MMIO space > 4GB phys addr; for 64-bit BAR */
sprintf(lba_dev->hba.gmmio_name, "PCI%02x GMMIO",
(int)lba_dev->hba.bus_num.start);
r = &lba_dev->hba.gmmio_space;
r->name = lba_dev->hba.gmmio_name;
r->start = p->start;
r->end = p->end;
r->flags = IORESOURCE_MEM;
r->parent = r->sibling = r->child = NULL; break;
case PAT_NPIOP:
printk(KERN_WARNING MODULE_NAME " range[%d] : ignoring NPIOP (0x%lx)\n",
i, p->start); break;
case PAT_PIOP: /* ** Postable I/O port space is per PCI host adapter. ** base of 64MB PIOP region
*/
lba_dev->iop_base = ioremap(p->start, 64 * 1024 * 1024);
/* ** With "legacy" firmware, the lowest byte of FW_SCRATCH ** represents bus->secondary and the second byte represents ** bus->subsidiary (i.e. highest PPB programmed by firmware). ** PCI bus walk *should* end up with the same result. ** FIXME: But we don't have sanity checks in PCI or LBA.
*/
lba_num = READ_REG32(lba_dev->hba.base_addr + LBA_FW_SCRATCH);
r = &(lba_dev->hba.bus_num);
r->name = "LBA PCI Busses";
r->start = lba_num & 0xff;
r->end = (lba_num>>8) & 0xff;
r->flags = IORESOURCE_BUS;
/* Set up local PCI Bus resources - we don't need them for ** Legacy boxes but it's nice to see in /proc/iomem.
*/
r = &(lba_dev->hba.lmmio_space);
sprintf(lba_dev->hba.lmmio_name, "PCI%02x LMMIO",
(int)lba_dev->hba.bus_num.start);
r->name = lba_dev->hba.lmmio_name;
#if 1 /* We want the CPU -> IO routing of addresses. * The SBA BASE/MASK registers control CPU -> IO routing. * Ask SBA what is routed to this rope/LBA.
*/
sba_distributed_lmmio(pa_dev, r); #else /* * The LBA BASE/MASK registers control IO -> System routing. * * The following code works but doesn't get us what we want. * Well, only because firmware (v5.0) on C3000 doesn't program * the LBA BASE/MASE registers to be the exact inverse of * the corresponding SBA registers. Other Astro/Pluto * based platform firmware may do it right. * * Should someone want to mess with MSI, they may need to * reprogram LBA BASE/MASK registers. Thus preserve the code * below until MSI is known to work on C3000/A500/N4000/RP3440. * * Using the code below, /proc/iomem shows: * ... * f0000000-f0ffffff : PCI00 LMMIO * f05d0000-f05d0000 : lcd_data * f05d0008-f05d0008 : lcd_cmd * f1000000-f1ffffff : PCI01 LMMIO * f4000000-f4ffffff : PCI02 LMMIO * f4000000-f4001fff : sym53c8xx * f4002000-f4003fff : sym53c8xx * f4004000-f40043ff : sym53c8xx * f4005000-f40053ff : sym53c8xx * f4007000-f4007fff : ohci_hcd * f4008000-f40083ff : tulip * f6000000-f6ffffff : PCI03 LMMIO * f8000000-fbffffff : PCI00 ELMMIO * fa100000-fa4fffff : stifb mmio * fb000000-fb1fffff : stifb fb * * But everything listed under PCI02 actually lives under PCI00. * This is clearly wrong. * * Asking SBA how things are routed tells the correct story: * LMMIO_BASE/MASK/ROUTE f4000001 fc000000 00000000 * DIR0_BASE/MASK/ROUTE fa000001 fe000000 00000006 * DIR1_BASE/MASK/ROUTE f9000001 ff000000 00000004 * DIR2_BASE/MASK/ROUTE f0000000 fc000000 00000000 * DIR3_BASE/MASK/ROUTE f0000000 fc000000 00000000 * * Which looks like this in /proc/iomem: * f4000000-f47fffff : PCI00 LMMIO * f4000000-f4001fff : sym53c8xx * ...[deteled core devices - same as above]... * f4008000-f40083ff : tulip * f4800000-f4ffffff : PCI01 LMMIO * f6000000-f67fffff : PCI02 LMMIO * f7000000-f77fffff : PCI03 LMMIO * f9000000-f9ffffff : PCI02 ELMMIO * fa000000-fbffffff : PCI03 ELMMIO * fa100000-fa4fffff : stifb mmio * fb000000-fb1fffff : stifb fb * * ie all Built-in core are under now correctly under PCI00. * The "PCI02 ELMMIO" directed range is for: * +-[02]---03.0 3Dfx Interactive, Inc. Voodoo 2 * * All is well now.
*/
r->start = READ_REG32(lba_dev->hba.base_addr + LBA_LMMIO_BASE); if (r->start & 1) { unsignedlong rsize;
/* ** Each rope only gets part of the distributed range. ** Adjust "window" for this rope.
*/
rsize /= ROPES_PER_IOC;
r->start += (rsize + 1) * LBA_NUM(pa_dev->hpa.start);
r->end = r->start + rsize;
} else {
r->end = r->start = 0; /* Not enabled. */
} #endif
/* ** "Directed" ranges are used when the "distributed range" isn't ** sufficient for all devices below a given LBA. Typically devices ** like graphics cards or X25 may need a directed range when the ** bus has multiple slots (ie multiple devices) or the device ** needs more than the typical 4 or 8MB a distributed range offers. ** ** The main reason for ignoring it now frigging complications. ** Directed ranges may overlap (and have precedence) over ** distributed ranges. Or a distributed range assigned to a unused ** rope may be used by a directed range on a different rope. ** Support for graphics devices may require fixing this ** since they may be assigned a directed range which overlaps ** an existing (but unused portion of) distributed range.
*/
r = &(lba_dev->hba.elmmio_space);
sprintf(lba_dev->hba.elmmio_name, "PCI%02x ELMMIO",
(int)lba_dev->hba.bus_num.start);
r->name = lba_dev->hba.elmmio_name;
#if 1 /* See comment which precedes call to sba_directed_lmmio() */
sba_directed_lmmio(pa_dev, r); #else
r->start = READ_REG32(lba_dev->hba.base_addr + LBA_ELMMIO_BASE);
#ifdef CONFIG_64BIT /* * FIXME add support for PDC_PAT_IO "Get slot status" - OLAR support * Only N-Class and up can really make use of Get slot status. * maybe L-class too but I've never played with it there.
*/ #endif
/* PDC_PAT_BUG: exhibited in rev 40.48 on L2000 */
bus_reset = READ_REG32(d->hba.base_addr + LBA_STAT_CTL + 4) & 1; if (bus_reset) {
printk(KERN_DEBUG "NOTICE: PCI bus reset still asserted! (clearing)\n");
}
stat = READ_REG32(d->hba.base_addr + LBA_ERROR_CONFIG); if (stat & LBA_SMART_MODE) {
printk(KERN_DEBUG "NOTICE: LBA in SMART mode! (cleared)\n");
stat &= ~LBA_SMART_MODE;
WRITE_REG32(stat, d->hba.base_addr + LBA_ERROR_CONFIG);
}
/* * Hard Fail vs. Soft Fail on PCI "Master Abort". * * "Master Abort" means the MMIO transaction timed out - usually due to * the device not responding to an MMIO read. We would like HF to be * enabled to find driver problems, though it means the system will * crash with a HPMC. * * In SoftFail mode "~0L" is returned as a result of a timeout on the * pci bus. This is like how PCI busses on x86 and most other * architectures behave. In order to increase compatibility with * existing (x86) PCI hardware and existing Linux drivers we enable * Soft Faul mode on PA-RISC now too.
*/
stat = READ_REG32(d->hba.base_addr + LBA_STAT_CTL); #ifdefined(ENABLE_HARDFAIL)
WRITE_REG32(stat | HF_ENABLE, d->hba.base_addr + LBA_STAT_CTL); #else
WRITE_REG32(stat & ~HF_ENABLE, d->hba.base_addr + LBA_STAT_CTL); #endif
/* ** Writing a zero to STAT_CTL.rf (bit 0) will clear reset signal ** if it's not already set. If we just cleared the PCI Bus Reset ** signal, wait a bit for the PCI devices to recover and setup.
*/ if (bus_reset)
mdelay(pci_post_reset_delay);
if (0 == READ_REG32(d->hba.base_addr + LBA_ARB_MASK)) { /* ** PDC_PAT_BUG: PDC rev 40.48 on L2000. ** B2000/C3600/J6000 also have this problem? ** ** Elroys with hot pluggable slots don't get configured ** correctly if the slot is empty. ARB_MASK is set to 0 ** and we can't master transactions on the bus if it's ** not at least one. 0x3 enables elroy and first slot.
*/
printk(KERN_DEBUG "NOTICE: Enabling PCI Arbitration\n");
WRITE_REG32(0x3, d->hba.base_addr + LBA_ARB_MASK);
}
/* ** FIXME: Hint registers are programmed with default hint ** values by firmware. Hints should be sane even if we ** can't reprogram them the way drivers want.
*/ return 0;
}
/* * Unfortunately, when firmware numbers busses, it doesn't take into account * Cardbus bridges. So we have to renumber the busses to suit ourselves. * Elroy/Mercury don't actually know what bus number they're attached to; * we use bus 0 to indicate the directly attached bus and any other bus * number will be taken care of by the PCI-PCI bridge.
*/ staticunsignedint lba_next_bus = 0;
/* * Determine if lba should claim this chip (return 0) or not (return 1). * If so, initialize the chip and tell other partners in crime they * have work to do.
*/ staticint __init
lba_driver_probe(struct parisc_device *dev)
{ struct lba_device *lba_dev;
LIST_HEAD(resources); struct pci_bus *lba_bus; struct pci_ops *cfg_ops;
u32 func_class; void *tmp_obj; char *version; void __iomem *addr; int max;
addr = ioremap(dev->hpa.start, 4096); if (addr == NULL) return -ENOMEM;
if (IS_ELROY(dev)) {
func_class &= 0xf; switch (func_class) { case 0: version = "TR1.0"; break; case 1: version = "TR2.0"; break; case 2: version = "TR2.1"; break; case 3: version = "TR2.2"; break; case 4: version = "TR3.0"; break; case 5: version = "TR4.0"; break; default: version = "TR4+";
}
printk(KERN_INFO "Elroy version %s (0x%x) found at 0x%lx\n",
version, func_class & 0xf, (long)dev->hpa.start);
if (func_class < 2) {
printk(KERN_WARNING "Can't support LBA older than " "TR2.1 - continuing under adversity.\n");
}
#if 0 /* Elroy TR4.0 should work with simple algorithm. But it doesn't. Still missing something. *sigh*
*/ if (func_class > 4) {
cfg_ops = &mercury_cfg_ops;
} else #endif
{
cfg_ops = &elroy_cfg_ops;
}
} elseif (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { int major, minor;
func_class &= 0xff;
major = func_class >> 4, minor = func_class & 0xf;
/* We could use one printk for both Elroy and Mercury, * but for the mask for func_class.
*/
printk(KERN_INFO "%s version TR%d.%d (0x%x) found at 0x%lx\n",
IS_MERCURY(dev) ? "Mercury" : "Quicksilver", major,
minor, func_class, (long)dev->hpa.start);
cfg_ops = &mercury_cfg_ops;
} else {
printk(KERN_ERR "Unknown LBA found at 0x%lx\n",
(long)dev->hpa.start); return -ENODEV;
}
/* Tell I/O SAPIC driver we have a IRQ handler/region. */
tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE,
addr + LBA_IOSAPIC_BASE);
/* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't ** have an IRT entry will get NULL back from iosapic code.
*/
/* ---------- First : initialize data we already have --------- */
lba_dev->hw_rev = func_class;
lba_dev->hba.base_addr = addr;
lba_dev->hba.dev = dev;
lba_dev->iosapic_obj = tmp_obj; /* save interrupt handle */
lba_dev->hba.iommu = sba_get_iommu(dev); /* get iommu data */
parisc_set_drvdata(dev, lba_dev);
/* ------------ Second : initialize common stuff ---------- */
pci_bios = &lba_bios_ops;
pcibios_register_hba(&lba_dev->hba);
spin_lock_init(&lba_dev->lba_lock);
if (lba_hw_init(lba_dev)) return(1);
/* ---------- Third : setup I/O Port and MMIO resources --------- */
if (is_pdc_pat()) { /* PDC PAT firmware uses PIOP region of GMMIO space. */
pci_port = &lba_pat_port_ops; /* Go ask PDC PAT what resources this LBA has */
lba_pat_resources(dev, lba_dev);
} else { if (!astro_iop_base) { /* Sprockets PDC uses NPIOP region */
astro_iop_base = ioremap(LBA_PORT_BASE, 64 * 1024);
pci_port = &lba_astro_port_ops;
}
/* Poke the chip a bit for /proc output */
lba_legacy_resources(dev, lba_dev);
}
if (lba_dev->hba.bus_num.start < lba_next_bus)
lba_dev->hba.bus_num.start = lba_next_bus;
/* Overlaps with elmmio can (and should) fail here. * We will prune (or ignore) the distributed range. * * FIXME: SBA code should register all elmmio ranges first. * that would take care of elmmio ranges routed * to a different rope (already discovered) from * getting registered *after* LBA code has already * registered it's distributed lmmio range.
*/ if (truncate_pat_collision(&iomem_resource,
&(lba_dev->hba.lmmio_space))) {
printk(KERN_WARNING "LBA: lmmio_space [%lx/%lx] duplicate!\n",
(long)lba_dev->hba.lmmio_space.start,
(long)lba_dev->hba.lmmio_space.end);
lba_dev->hba.lmmio_space.flags = 0;
}
pci_add_resource_offset(&resources, &lba_dev->hba.io_space,
HBA_PORT_BASE(lba_dev->hba.hba_num)); if (lba_dev->hba.elmmio_space.flags)
pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space,
lba_dev->hba.lmmio_space_offset); if (lba_dev->hba.lmmio_space.flags)
pci_add_resource_offset(&resources, &lba_dev->hba.lmmio_space,
lba_dev->hba.lmmio_space_offset); if (lba_dev->hba.gmmio_space.flags) { /* Not registering GMMIO space - according to docs it's not
* even used on HP-UX. */ /* pci_add_resource(&resources, &lba_dev->hba.gmmio_space); */
}
/* ** Once PCI register ops has walked the bus, access to config ** space is restricted. Avoids master aborts on config cycles. ** Early LBA revs go fatal on *any* master abort.
*/ if (cfg_ops == &elroy_cfg_ops) {
lba_dev->flags |= LBA_FLAG_SKIP_PROBE;
}
lba_next_bus = max + 1;
pci_bus_add_devices(lba_bus);
/* Whew! Finally done! Tell services we got this one covered. */ return 0;
}
/* ** One time initialization to let the world know the LBA was found. ** Must be called exactly once before pci_init().
*/ staticint __init lba_init(void)
{ return register_parisc_driver(&lba_driver);
}
arch_initcall(lba_init);
/* ** Initialize the IBASE/IMASK registers for LBA (Elroy). ** Only called from sba_iommu.c in order to route ranges (MMIO vs DMA). ** sba_iommu is responsible for locking (none needed at init time).
*/ void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
{ void __iomem * base_addr = ioremap(lba->hpa.start, 4096);
imask <<= 2; /* adjust for hints - 2 more bits */
/* Make sure we aren't trying to set bits that aren't writeable. */
WARN_ON((ibase & 0x001fffff) != 0);
WARN_ON((imask & 0x001fffff) != 0);
/* * The design of the Diva management card in rp34x0 machines (rp3410, rp3440) * seems rushed, so that many built-in components simply don't work. * The following quirks disable the serial AUX port and the built-in ATI RV100 * Radeon 7000 graphics card which both don't have any external connectors and * thus are useless, and even worse, e.g. the AUX port occupies ttyS0 and as * such makes those machines the only PARISC machines on which we can't use * ttyS0 as boot console.
*/ staticvoid quirk_diva_ati_card(struct pci_dev *dev)
{ if (dev->subsystem_vendor != PCI_VENDOR_ID_HP ||
dev->subsystem_device != 0x1292) return;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.