fixup-sni.c 4.3 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * SNI specific PCI support for RM200/RM300.
 *
 * Copyright (C) 1997 - 2000, 2003, 04 Ralf Baechle (ralf@linux-mips.org)
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>

#include <asm/mipsregs.h>
#include <asm/sni.h>

/*
18
 * PCIMT Shortcuts ...
L
Linus Torvalds 已提交
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
 */
#define SCSI	PCIMT_IRQ_SCSI
#define ETH	PCIMT_IRQ_ETHERNET
#define INTA	PCIMT_IRQ_INTA
#define INTB	PCIMT_IRQ_INTB
#define INTC	PCIMT_IRQ_INTC
#define INTD	PCIMT_IRQ_INTD

/*
 * Device 0: PCI EISA Bridge	(directly routed)
 * Device 1: NCR53c810 SCSI	(directly routed)
 * Device 2: PCnet32 Ethernet	(directly routed)
 * Device 3: VGA		(routed to INTB)
 * Device 4: Unused
 * Device 5: Slot 2
 * Device 6: Slot 3
35
 * Device 7: Slot 4
L
Linus Torvalds 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
 *
 * Documentation says the VGA is device 5 and device 3 is unused but that
 * seem to be a documentation error.  At least on my RM200C the Cirrus
 * Logic CL-GD5434 VGA is device 3.
 */
static char irq_tab_rm200[8][5] __initdata = {
	/*       INTA  INTB  INTC  INTD */
	{     0,    0,    0,    0,    0 },	/* EISA bridge */
	{  SCSI, SCSI, SCSI, SCSI, SCSI },	/* SCSI */
	{   ETH,  ETH,  ETH,  ETH,  ETH },	/* Ethernet */
	{  INTB, INTB, INTB, INTB, INTB },	/* VGA */
	{     0,    0,    0,    0,    0 },	/* Unused */
	{     0, INTB, INTC, INTD, INTA },	/* Slot 2 */
	{     0, INTC, INTD, INTA, INTB },	/* Slot 3 */
	{     0, INTD, INTA, INTB, INTC },	/* Slot 4 */
};

/*
 * In Revision D of the RM300 Device 2 has become a normal purpose Slot 1
 *
 * The VGA card is optional for RM300 systems.
 */
static char irq_tab_rm300d[8][5] __initdata = {
	/*       INTA  INTB  INTC  INTD */
	{     0,    0,    0,    0,    0 },	/* EISA bridge */
	{  SCSI, SCSI, SCSI, SCSI, SCSI },	/* SCSI */
	{     0, INTC, INTD, INTA, INTB },	/* Slot 1 */
	{  INTB, INTB, INTB, INTB, INTB },	/* VGA */
	{     0,    0,    0,    0,    0 },	/* Unused */
	{     0, INTB, INTC, INTD, INTA },	/* Slot 2 */
	{     0, INTC, INTD, INTA, INTB },	/* Slot 3 */
	{     0, INTD, INTA, INTB, INTC },	/* Slot 4 */
};

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
static char irq_tab_rm300e[5][5] __initdata = {
	/*       INTA  INTB  INTC  INTD */
	{     0,    0,    0,    0,    0 },	/* HOST bridge */
	{  SCSI, SCSI, SCSI, SCSI, SCSI },	/* SCSI */
	{     0, INTC, INTD, INTA, INTB },	/* Bridge/i960 */
	{     0, INTD, INTA, INTB, INTC },	/* Slot 1 */
	{     0, INTA, INTB, INTC, INTD },	/* Slot 2 */
};
#undef SCSI
#undef ETH
#undef INTA
#undef INTB
#undef INTC
#undef INTD


/*
 * PCIT Shortcuts ...
 */
#define SCSI0	PCIT_IRQ_SCSI0
#define SCSI1	PCIT_IRQ_SCSI1
#define ETH	PCIT_IRQ_ETHERNET
#define INTA	PCIT_IRQ_INTA
#define INTB	PCIT_IRQ_INTB
#define INTC	PCIT_IRQ_INTC
#define INTD	PCIT_IRQ_INTD

static char irq_tab_pcit[13][5] __initdata = {
	/*       INTA  INTB  INTC  INTD */
	{     0,     0,     0,     0,     0 },	/* HOST bridge */
	{ SCSI0, SCSI0, SCSI0, SCSI0, SCSI0 },	/* SCSI */
	{ SCSI1, SCSI1, SCSI1, SCSI1, SCSI1 },	/* SCSI */
	{   ETH,   ETH,   ETH,   ETH,   ETH },	/* Ethernet */
	{     0,  INTA,  INTB,  INTC,  INTD },	/* PCI-PCI bridge */
	{     0,     0,     0,     0,     0 },	/* Unused */
	{     0,     0,     0,     0,     0 },	/* Unused */
	{     0,     0,     0,     0,     0 },	/* Unused */
	{     0,  INTA,  INTB,  INTC,  INTD },	/* Slot 1 */
	{     0,  INTB,  INTC,  INTD,  INTA },	/* Slot 2 */
	{     0,  INTC,  INTD,  INTA,  INTB },	/* Slot 3 */
	{     0,  INTD,  INTA,  INTB,  INTC },	/* Slot 4 */
	{     0,  INTA,  INTB,  INTC,  INTD },	/* Slot 5 */
};

L
Linus Torvalds 已提交
114 115 116 117 118 119 120 121 122
static inline int is_rm300_revd(void)
{
	unsigned char csmsr = *(volatile unsigned char *)PCIMT_CSMSR;

	return (csmsr & 0xa0) == 0x20;
}

int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
123 124 125 126 127 128 129 130 131
	switch (sni_brd_type) {
	case SNI_BRD_PCI_TOWER:
	case SNI_BRD_PCI_TOWER_CPLUS:
	        return irq_tab_pcit[slot][pin];

	case SNI_BRD_PCI_MTOWER:
	        if (is_rm300_revd())
		        return irq_tab_rm300d[slot][pin];
	        /* fall through */
L
Linus Torvalds 已提交
132

133 134 135 136 137 138 139 140
	case SNI_BRD_PCI_DESKTOP:
	        return irq_tab_rm200[slot][pin];

	case SNI_BRD_PCI_MTOWER_CPLUS:
	        return irq_tab_rm300e[slot][pin];
	}

	return 0;
L
Linus Torvalds 已提交
141 142 143 144 145 146 147
}

/* Do platform specific device initialization at pci_enable_device() time */
int pcibios_plat_dev_init(struct pci_dev *dev)
{
	return 0;
}