Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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 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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | /* * 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> #include <irq.h> /* * PCIMT Shortcuts ... */ #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 * Device 7: Slot 4 * * 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] = { /* 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] = { /* 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 */ }; static char irq_tab_rm300e[5][5] = { /* 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] = { /* 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 */ }; static char irq_tab_pcit_cplus[13][5] = { /* INTA INTB INTC INTD */ { 0, 0, 0, 0, 0 }, /* HOST bridge */ { 0, INTB, INTC, INTD, INTA }, /* PCI Slot 9 */ { 0, 0, 0, 0, 0 }, /* PCI-EISA */ { 0, 0, 0, 0, 0 }, /* Unused */ { 0, INTA, INTB, INTC, INTD }, /* PCI-PCI bridge */ { 0, INTB, INTC, INTD, INTA }, /* fixup */ }; static inline int is_rm300_revd(void) { unsigned char csmsr = *(volatile unsigned char *)PCIMT_CSMSR; return (csmsr & 0xa0) == 0x20; } int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { switch (sni_brd_type) { case SNI_BRD_PCI_TOWER_CPLUS: if (slot == 4) { /* * SNI messed up interrupt wiring for onboard * PCI bus 1; we need to fix this up here */ while (dev && dev->bus->number != 1) dev = dev->bus->self; if (dev && dev->devfn >= PCI_DEVFN(4, 0)) slot = 5; } return irq_tab_pcit_cplus[slot][pin]; case SNI_BRD_PCI_TOWER: return irq_tab_pcit[slot][pin]; case SNI_BRD_PCI_MTOWER: if (is_rm300_revd()) return irq_tab_rm300d[slot][pin]; fallthrough; 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; } /* Do platform specific device initialization at pci_enable_device() time */ int pcibios_plat_dev_init(struct pci_dev *dev) { return 0; } |