/*
* pcic.c: MicroSPARC-IIep PCI controller support
*
* Copyright (C) 1998 V. Roganov and G. Raiko
*
* Code is derived from Ultra/PCI PSYCHO controller support, see that
* for author info.
*
* Support for diverse IIep based platforms by Pete Zaitcev.
* CP-1200 by Eric Brower.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <asm/ebus.h>
#include <asm/sbus.h> /* for sanity check... */
#include <asm/swift.h> /* for cache flushing. */
#include <asm/io.h>
#include <linux/ctype.h>
#include <linux/pci.h>
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <asm/oplib.h>
#include <asm/pcic.h>
#include <asm/timer.h>
#include <asm/uaccess.h>
unsigned int pcic_pin_to_irq(unsigned int pin, char *name);
/*
* I studied different documents and many live PROMs both from 2.30
* family and 3.xx versions. I came to the amazing conclusion: there is
* absolutely no way to route interrupts in IIep systems relying on
* information which PROM presents. We must hardcode interrupt routing
* schematics. And this actually sucks. -- zaitcev 1999/05/12
*
* To find irq for a device we determine which routing map
* is in effect or, in other words, on which machine we are running.
* We use PROM name for this although other techniques may be used
* in special cases (Gleb reports a PROMless IIep based system).
* Once we know the map we take device configuration address and
* find PCIC pin number where INT line goes. Then we may either program
* preferred irq into the PCIC or supply the preexisting irq to the device.
*/
struct pcic_ca2irq {
unsigned char busno; /* PCI bus number */
unsigned char devfn; /* Configuration address */
unsigned char pin; /* PCIC external interrupt pin */
unsigned char irq; /* Preferred IRQ (mappable in PCIC) */
unsigned int force; /* Enforce preferred IRQ */
};
struct pcic_sn2list {
char *sysname;
struct pcic_ca2irq *intmap;
int mapdim;
};
/*
* JavaEngine-1 apparently has different versions.
*
* According to communications with Sun folks, for P2 build 501-4628-03:
* pin 0 - parallel, audio;
* pin 1 - Ethernet;
* pin 2 - su;
* pin 3 - PS/2 kbd and mouse.
*
* OEM manual (805-1486):
* pin 0: Ethernet
* pin 1: All EBus
* pin 2: IGA (unused)
* pin 3: Not connected
* OEM manual says that 501-4628 & 501-4811 are the same thing,
* only the latter has NAND flash in place.
*
* So far unofficial Sun wins over the OEM manual. Poor OEMs...
*/
static struct pcic_ca2irq pcic_i_je1a[] = { /* 501-4811-03 */
{ 0, 0x00, 2, 12, 0 }, /* EBus: hogs all */
{ 0, 0x01, 1, 6, 1 }, /* Happy Meal */
{ 0, 0x80, 0, 7, 0 }, /* IGA (unused) */
};
/* XXX JS-E entry is incomplete - PCI Slot 2 address (pin 7)? */
static struct pcic_ca2irq pcic_i_jse[] = {
{ 0, 0x00, 0, 13, 0 }, /* Ebus - serial and keyboard */
{ 0, 0x01, 1, 6, 0 }, /* hme */
{ 0, 0x08, 2, 9, 0 }, /* VGA - we hope not used :) */
{ 0, 0x10, 6, 8, 0 }, /* PCI INTA# in Slot 1 */
{ 0, 0x18, 7, 12, 0 }, /* PCI INTA# in Slot 2, shared w. RTC */
{ 0, 0x38, 4, 9, 0 }, /* All ISA devices. Read 8259. */
{ 0, 0x80, 5, 11, 0 }, /* EIDE */
/* {0,0x88, 0,0,0} - unknown device... PMU? Probably no interrupt. */
{ 0, 0xA0, 4, 9, 0 }, /* USB */
/*
* Some pins belong to non-PCI devices, we hardcode them in drivers.
* sun4m timers - irq 10, 14
* PC style RTC - pin 7, irq 4 ?
* Smart card, Parallel - pin 4 shared with USB, ISA
* audio - pin 3, irq 5 ?
*/
};
/* SPARCengine-6 was the original release name of CP1200.
* The documentation differs between the two versions
*/
static struct pcic_ca2irq pcic_i_se6[] = {
{ 0, 0x08, 0, 2, 0 }, /* SCSI */
{ 0, 0x01, 1, 6, 0 }, /* HME */
{ 0, 0x00, 3, 13, 0 }, /* EBus */
};
/*
* Krups (courtesy of Varol Kaptan)
* No documentation available, but it was easy to guess
* because it was very similar to Espresso.
*
* pin 0 - kbd, mouse, serial;
* pin 1 - Ethernet;
* pin 2 - igs (we do not use it);
* pin 3 - audio;
* pin 4,5,6 - unused;
* pin 7 - RTC (from P2 onwards as David B. says).
*/
static struct pcic_ca2irq pcic_i_jk[] = {
{ 0, 0x00, 0, 13, 0 }, /* Ebus - serial and keyboard */
{ 0, 0x01, 1, 6, 0 }, /* hme */
};
/*
* Several entries in this list may point to the same routing map
* as several PROMs may be installed on the same physical board.
*/
#define SN2L_INIT(name, map) \
{ name, map, sizeof(map)/sizeof(struct pcic_ca2irq) }
static struct pcic_sn2list pcic_known_sysnames[] = {
SN2L_INIT("SUNW,JavaEngine1", pcic_i_je1a), /* JE1, PROM 2.32 */
SN2L_INIT("SUNW,JS-E", pcic_i_jse), /* PROLL JavaStation-E */
SN2L_INIT("SUNW,SPARCengine-6", pcic_i_se6), /* SPARCengine-6/CP-1200 */
SN2L_INIT("SUNW,JS-NC", pcic_i_jk), /* PROLL JavaStation-NC */
SN2L_INIT("SUNW,JSIIep", pcic_i_jk), /* OBP JavaStation-NC */
{ NULL, NULL, 0 }
};
/*
* Only one PCIC per IIep,
* and since we have no SMP IIep, only one per system.
*/
static int pcic0_up;
static