1/* 2 * arch/mips/pci/fixup-vr4133.c 3 * 4 * The NEC CMB-VR4133 Board specific PCI fixups. 5 * 6 * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and 7 * Alex Sapkov <asapkov@ru.mvista.com> 8 * 9 * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under 10 * the terms of the GNU General Public License version 2. This program 11 * is licensed "as is" without any warranty of any kind, whether express 12 * or implied. 13 * 14 * Modified for support in 2.6 15 * Author: Manish Lachwani (mlachwani@mvista.com) 16 * 17 */ 18#include <linux/init.h> 19#include <linux/pci.h> 20#include <linux/kernel.h> 21 22#include <asm/io.h> 23#include <asm/i8259.h> 24#include <asm/vr41xx/cmbvr4133.h> 25 26extern int vr4133_rockhopper; 27extern void ali_m1535plus_init(struct pci_dev *dev); 28extern void ali_m5229_init(struct pci_dev *dev); 29 30/* Do platform specific device initialization at pci_enable_device() time */ 31int pcibios_plat_dev_init(struct pci_dev *dev) 32{ 33 /* 34 * We have to reset AMD PCnet adapter on Rockhopper since 35 * PMON leaves it enabled and generating interrupts. This leads 36 * to a lock if some PCI device driver later enables the IRQ line 37 * shared with PCnet and there is no AMD PCnet driver to catch its 38 * interrupts. 39 */ 40#ifdef CONFIG_ROCKHOPPER 41 if (dev->vendor == PCI_VENDOR_ID_AMD && 42 dev->device == PCI_DEVICE_ID_AMD_LANCE) { 43 inl(pci_resource_start(dev, 0) + 0x18); 44 } 45#endif 46 47 /* 48 * we have to open the bridges' windows down to 0 because otherwise 49 * we cannot access ISA south bridge I/O registers that get mapped from 50 * 0. for example, 8259 PIC would be unaccessible without that 51 */ 52 if(dev->vendor == PCI_VENDOR_ID_INTEL && dev->device == PCI_DEVICE_ID_INTEL_S21152BB) { 53 pci_write_config_byte(dev, PCI_IO_BASE, 0); 54 if(dev->bus->number == 0) { 55 pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0); 56 } else { 57 pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 1); 58 } 59 } 60 61 return 0; 62} 63 64/* 65 * M1535 IRQ mapping 66 * Feel free to change this, although it shouldn't be needed 67 */ 68#define M1535_IRQ_INTA 7 69#define M1535_IRQ_INTB 9 70#define M1535_IRQ_INTC 10 71#define M1535_IRQ_INTD 11 72 73#define M1535_IRQ_USB 9 74#define M1535_IRQ_IDE 14 75#define M1535_IRQ_IDE2 15 76#define M1535_IRQ_PS2 12 77#define M1535_IRQ_RTC 8 78#define M1535_IRQ_FDC 6 79#define M1535_IRQ_AUDIO 5 80#define M1535_IRQ_COM1 4 81#define M1535_IRQ_COM2 4 82#define M1535_IRQ_IRDA 3 83#define M1535_IRQ_KBD 1 84#define M1535_IRQ_TMR 0 85 86/* Rockhopper "slots" assignment; this is hard-coded ... */ 87#define ROCKHOPPER_M5451_SLOT 1 88#define ROCKHOPPER_M1535_SLOT 2 89#define ROCKHOPPER_M5229_SLOT 11 90#define ROCKHOPPER_M5237_SLOT 15 91#define ROCKHOPPER_PMU_SLOT 12 92/* ... and hard-wired. */ 93#define ROCKHOPPER_PCI1_SLOT 3 94#define ROCKHOPPER_PCI2_SLOT 4 95#define ROCKHOPPER_PCI3_SLOT 5 96#define ROCKHOPPER_PCI4_SLOT 6 97#define ROCKHOPPER_PCNET_SLOT 1 98 99#define M1535_IRQ_MASK(n) (1 << (n)) 100 101#define M1535_IRQ_EDGE (M1535_IRQ_MASK(M1535_IRQ_TMR) | \ 102 M1535_IRQ_MASK(M1535_IRQ_KBD) | \ 103 M1535_IRQ_MASK(M1535_IRQ_COM1) | \ 104 M1535_IRQ_MASK(M1535_IRQ_COM2) | \ 105 M1535_IRQ_MASK(M1535_IRQ_IRDA) | \ 106 M1535_IRQ_MASK(M1535_IRQ_RTC) | \ 107 M1535_IRQ_MASK(M1535_IRQ_FDC) | \ 108 M1535_IRQ_MASK(M1535_IRQ_PS2)) 109 110#define M1535_IRQ_LEVEL (M1535_IRQ_MASK(M1535_IRQ_IDE) | \ 111 M1535_IRQ_MASK(M1535_IRQ_USB) | \ 112 M1535_IRQ_MASK(M1535_IRQ_INTA) | \ 113 M1535_IRQ_MASK(M1535_IRQ_INTB) | \ 114 M1535_IRQ_MASK(M1535_IRQ_INTC) | \ 115 M1535_IRQ_MASK(M1535_IRQ_INTD)) 116 117struct irq_map_entry { 118 u16 bus; 119 u8 slot; 120 u8 irq; 121}; 122static struct irq_map_entry int_map[] = { 123 {1, ROCKHOPPER_M5451_SLOT, M1535_IRQ_AUDIO}, /* Audio controller */ 124 {1, ROCKHOPPER_PCI1_SLOT, M1535_IRQ_INTD}, /* PCI slot #1 */ 125 {1, ROCKHOPPER_PCI2_SLOT, M1535_IRQ_INTC}, /* PCI slot #2 */ 126 {1, ROCKHOPPER_M5237_SLOT, M1535_IRQ_USB}, /* USB host controller */ 127 {1, ROCKHOPPER_M5229_SLOT, IDE_PRIMARY_IRQ}, /* IDE controller */ 128 {2, ROCKHOPPER_PCNET_SLOT, M1535_IRQ_INTD}, /* AMD Am79c973 on-board 129 ethernet */ 130 {2, ROCKHOPPER_PCI3_SLOT, M1535_IRQ_INTB}, /* PCI slot #3 */ 131 {2, ROCKHOPPER_PCI4_SLOT, M1535_IRQ_INTC} /* PCI slot #4 */ 132}; 133 134static int pci_intlines[] = 135 { M1535_IRQ_INTA, M1535_IRQ_INTB, M1535_IRQ_INTC, M1535_IRQ_INTD }; 136 137/* Determine the Rockhopper IRQ line number for the PCI device */ 138int rockhopper_get_irq(struct pci_dev *dev, u8 pin, u8 slot) 139{ 140 struct pci_bus *bus; 141 int i; 142 143 bus = dev->bus; 144 if (bus == NULL) 145 return -1; 146 147 for (i = 0; i < ARRAY_SIZE(int_map); i++) { 148 if (int_map[i].bus == bus->number && int_map[i].slot == slot) { 149 int line; 150 for (line = 0; line < 4; line++) 151 if (pci_intlines[line] == int_map[i].irq) 152 break; 153 if (line < 4) 154 return pci_intlines[(line + (pin - 1)) % 4]; 155 else 156 return int_map[i].irq; 157 } 158 } 159 return -1; 160} 161 162#ifdef CONFIG_ROCKHOPPER 163void i8259_init(void) 164{ 165 init_i8259_irqs(); 166 167 outb(0x00, 0x4d0); 168 outb(0x02, 0x4d1); /* USB IRQ9 is level */ 169} 170#endif 171 172int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 173{ 174 extern int pci_probe_only; 175 pci_probe_only = 1; 176 177#ifdef CONFIG_ROCKHOPPER 178 if( dev->bus->number == 1 && vr4133_rockhopper ) { 179 if(slot == ROCKHOPPER_PCI1_SLOT || slot == ROCKHOPPER_PCI2_SLOT) 180 dev->irq = CMBVR41XX_INTA_IRQ; 181 else 182 dev->irq = rockhopper_get_irq(dev, pin, slot); 183 } else 184 dev->irq = CMBVR41XX_INTA_IRQ; 185#else 186 dev->irq = CMBVR41XX_INTA_IRQ; 187#endif 188 189 return dev->irq; 190} 191 192DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, ali_m1535plus_init); 193DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, ali_m5229_init); 194