/*
**
** PCI Lower Bus Adapter (LBA) manager
**
** (c) Copyright 1999,2000 Grant Grundler
** (c) Copyright 1999,2000 Hewlett-Packard Company
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
**
** 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).
*/
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/init.h> /* for __init and __devinit */
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <asm/byteorder.h>
#include <asm/pdc.h>
#include <asm/pdcpat.h>
#include <asm/page.h>
#include <asm/system.h>
#include <asm/ropes.h>
#include <asm/hardware.h> /* for register_parisc_driver() stuff */
#include <asm/parisc-device.h>
#include <asm/io.h> /* read/write stuff */
#undef DEBUG_LBA /* general stuff */
#undef DEBUG_LBA_PORT /* debug I/O Port access */
#undef DEBUG_LBA_CFG /* debug Config Space Access (ie PCI Bus walk) */
#undef DEBUG_LBA_PAT /* debug PCI Resource Mgt code - PDC PAT only */
#undef FBB_SUPPORT /* Fast Back-Back xfers - NOT READY YET */
#ifdef DEBUG_LBA
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
#ifdef DEBUG_LBA_PORT
#define DBG_PORT(x...) printk(x)
#else
#define DBG_PORT(x...)
#endif
#ifdef DEBUG_LBA_CFG
#define DBG_CFG(x...) printk(x)
#else
#define DBG_CFG(x...)
#endif
#ifdef DEBUG_LBA_PAT
#define DBG_PAT(x...) printk(x)
#else
#define DBG_PAT(x...)
#endif
/*
** 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.
*/
#define MODULE_NAME "LBA"
/* non-postable I/O port space, densely packed */
#define LBA_PORT_BASE (PCI_F_EXTEND | 0xfee00000UL)
static void __iomem *astro_iop_base __read_mostly;
static u32 lba_t32;
/* lba flags */
#define LBA_FLAG_SKIP_PROBE 0x10
#define LBA_SKIP_PROBE(d) ((d)->flags & LBA_FLAG_SKIP_PROBE)
/* Looks nice and keeps the compiler happy */
#define LBA_DEV(d) ((struct lba_device *) (d))
/*
** Only allow 8 subsidiary busses per LBA
** Problem is the PCI bus numbering is globally shared.
*/
#define LBA_MAX_NUM_BUSES 8
/************************************
* LBA register read and write support
*
* BE WARNED: register writes are posted.
* (ie follow writes which must reach HW with a read)
*/
#define READ_U8(addr) __raw_readb(addr)
#define READ_U16(addr) __raw_readw(addr)
#define READ_U32(addr) __raw_readl(addr)
#define WRITE_U8(value, addr) __raw_writeb(value, addr)
#define WRITE_U16(value, addr) __raw_writew(value, addr)
#define WRITE_U32(value, addr) __raw_writel(value, addr)
#define READ_REG8(addr) readb(addr)
#define READ_REG16(addr) readw(addr)
#define READ_REG32(addr) readl(addr)
#define READ_REG64(addr) readq(addr)
#define WRITE_REG8(value, addr) writeb(value, addr)
#define WRITE_REG16(value, addr) writew(value, addr)
#define WRITE_REG32(value, addr) writel(value, addr)
#define LBA_CFG_TOK(bus,dfn) ((u32) ((bus)<<16 | (dfn)<<8))
#define LBA_CFG_BUS(tok) ((u8) ((tok)>>16))
#define LBA_CFG_DEV(tok) ((u8) ((tok)>>11) & 0x1f)
#define LBA_CFG_FUNC(tok) ((u8) ((tok)>>8 ) & 0x7)
/*
** Extract LBA (Rope) number from HPA
** REVISIT: 16 ropes for Stretch/Ike?
*/
#define ROPES_PER_IOC 8
#define LBA_NUM(x) ((((unsigned long) x) >> 13) & (ROPES_PER_IOC-1))
static void
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:
** -
|