Skip to content
lba_pci.c 47.8 KiB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
/*
**
**  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 <linux/smp_lock.h>

#include <asm/byteorder.h>
#include <asm/pdc.h>
#include <asm/pdcpat.h>
#include <asm/page.h>
#include <asm/system.h>

#include <asm/hardware.h>	/* for register_parisc_driver() stuff */
#include <asm/parisc-device.h>
#include <asm/iosapic.h>	/* for iosapic_register() */
#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"

#define LBA_FUNC_ID	0x0000	/* function id */
#define LBA_FCLASS	0x0008	/* function class, bist, header, rev... */
#define LBA_CAPABLE	0x0030	/* capabilities register */

#define LBA_PCI_CFG_ADDR	0x0040	/* poke CFG address here */
#define LBA_PCI_CFG_DATA	0x0048	/* read or write data here */

#define LBA_PMC_MTLT	0x0050	/* Firmware sets this - read only. */
#define LBA_FW_SCRATCH	0x0058	/* Firmware writes the PCI bus number here. */
#define LBA_ERROR_ADDR	0x0070	/* On error, address gets logged here */

#define LBA_ARB_MASK	0x0080	/* bit 0 enable arbitration. PAT/PDC enables */
#define LBA_ARB_PRI	0x0088	/* firmware sets this. */
#define LBA_ARB_MODE	0x0090	/* firmware sets this. */
#define LBA_ARB_MTLT	0x0098	/* firmware sets this. */

#define LBA_MOD_ID	0x0100	/* Module ID. PDC_PAT_CELL reports 4 */

#define LBA_STAT_CTL	0x0108	/* Status & Control */
#define   LBA_BUS_RESET		0x01	/*  Deassert PCI Bus Reset Signal */
#define   CLEAR_ERRLOG		0x10	/*  "Clear Error Log" cmd */
#define   CLEAR_ERRLOG_ENABLE	0x20	/*  "Clear Error Log" Enable */
#define   HF_ENABLE	0x40	/*    enable HF mode (default is -1 mode) */

#define LBA_LMMIO_BASE	0x0200	/* < 4GB I/O address range */
#define LBA_LMMIO_MASK	0x0208

#define LBA_GMMIO_BASE	0x0210	/* > 4GB I/O address range */
#define LBA_GMMIO_MASK	0x0218

#define LBA_WLMMIO_BASE	0x0220	/* All < 4GB ranges under the same *SBA* */
#define LBA_WLMMIO_MASK	0x0228

#define LBA_WGMMIO_BASE	0x0230	/* All > 4GB ranges under the same *SBA* */
#define LBA_WGMMIO_MASK	0x0238

#define LBA_IOS_BASE	0x0240	/* I/O port space for this LBA */
#define LBA_IOS_MASK	0x0248

#define LBA_ELMMIO_BASE	0x0250	/* Extra LMMIO range */
#define LBA_ELMMIO_MASK	0x0258

#define LBA_EIOS_BASE	0x0260	/* Extra I/O port space */
#define LBA_EIOS_MASK	0x0268

#define LBA_GLOBAL_MASK	0x0270	/* Mercury only: Global Address Mask */
#define LBA_DMA_CTL	0x0278	/* firmware sets this */

#define LBA_IBASE	0x0300	/* SBA DMA support */
#define LBA_IMASK	0x0308

/* FIXME: ignore DMA Hint stuff until we can measure performance */
#define LBA_HINT_CFG	0x0310
#define LBA_HINT_BASE	0x0380	/* 14 registers at every 8 bytes. */

#define LBA_BUS_MODE	0x0620

/* ERROR regs are needed for config cycle kluges */
#define LBA_ERROR_CONFIG 0x0680
#define     LBA_SMART_MODE 0x20
#define LBA_ERROR_STATUS 0x0688
#define LBA_ROPE_CTL     0x06A0

#define LBA_IOSAPIC_BASE	0x800 /* Offset of IRQ logic */

/* non-postable I/O port space, densely packed */
#define LBA_PORT_BASE	(PCI_F_EXTEND | 0xfee00000UL)
static void __iomem *astro_iop_base;

#define ELROY_HVERS	0x782
#define MERCURY_HVERS	0x783
#define QUICKSILVER_HVERS	0x784

static inline int IS_ELROY(struct parisc_device *d)
{
	return (d->id.hversion == ELROY_HVERS);
}

static inline int IS_MERCURY(struct parisc_device *d)
{
	return (d->id.hversion == MERCURY_HVERS);
}

static inline int IS_QUICKSILVER(struct parisc_device *d)
{
	return (d->id.hversion == QUICKSILVER_HVERS);
}


/*
** lba_device: Per instance Elroy data structure
*/
struct lba_device {
	struct pci_hba_data hba;

	spinlock_t	lba_lock;
	void		*iosapic_obj;

Loading
Loading full blame...