1#include <linux/kernel.h> 2#include <linux/pci.h> 3#include <asm/bootinfo.h> 4 5#include <asm/lasat/lasat.h> 6#include <asm/nile4.h> 7 8#define PCI_ACCESS_READ 0 9#define PCI_ACCESS_WRITE 1 10 11#define LO(reg) (reg / 4) 12#define HI(reg) (reg / 4 + 1) 13 14volatile unsigned long *const vrc_pciregs = (void *) Vrc5074_BASE; 15 16static DEFINE_SPINLOCK(nile4_pci_lock); 17 18static int nile4_pcibios_config_access(unsigned char access_type, 19 struct pci_bus *bus, unsigned int devfn, int where, u32 *val) 20{ 21 unsigned char busnum = bus->number; 22 u32 adr, mask, err; 23 24 if ((busnum == 0) && (PCI_SLOT(devfn) > 8)) 25 /* The addressing scheme chosen leaves room for just 26 * 8 devices on the first busnum (besides the PCI 27 * controller itself) */ 28 return PCIBIOS_DEVICE_NOT_FOUND; 29 30 if ((busnum == 0) && (devfn == PCI_DEVFN(0, 0))) { 31 /* Access controller registers directly */ 32 if (access_type == PCI_ACCESS_WRITE) { 33 vrc_pciregs[(0x200 + where) >> 2] = *val; 34 } else { 35 *val = vrc_pciregs[(0x200 + where) >> 2]; 36 } 37 return PCIBIOS_SUCCESSFUL; 38 } 39 40 /* Temporarily map PCI Window 1 to config space */ 41 mask = vrc_pciregs[LO(NILE4_PCIINIT1)]; 42 vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (busnum ? 0x200 : 0); 43 44 /* Clear PCI Error register. This also clears the Error Type 45 * bits in the Control register */ 46 vrc_pciregs[LO(NILE4_PCIERR)] = 0; 47 vrc_pciregs[HI(NILE4_PCIERR)] = 0; 48 49 /* Setup address */ 50 if (busnum == 0) 51 adr = 52 KSEG1ADDR(PCI_WINDOW1) + 53 ((1 << (PCI_SLOT(devfn) + 15)) | (PCI_FUNC(devfn) << 8) 54 | (where & ~3)); 55 else 56 adr = KSEG1ADDR(PCI_WINDOW1) | (busnum << 16) | (devfn << 8) | 57 (where & ~3); 58 59 if (access_type == PCI_ACCESS_WRITE) 60 *(u32 *) adr = *val; 61 else 62 *val = *(u32 *) adr; 63 64 /* Check for master or target abort */ 65 err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7; 66 67 /* Restore PCI Window 1 */ 68 vrc_pciregs[LO(NILE4_PCIINIT1)] = mask; 69 70 if (err) 71 return PCIBIOS_DEVICE_NOT_FOUND; 72 73 return PCIBIOS_SUCCESSFUL; 74} 75 76static int nile4_pcibios_read(struct pci_bus *bus, unsigned int devfn, 77 int where, int size, u32 *val) 78{ 79 unsigned long flags; 80 u32 data = 0; 81 int err; 82 83 if ((size == 2) && (where & 1)) 84 return PCIBIOS_BAD_REGISTER_NUMBER; 85 else if ((size == 4) && (where & 3)) 86 return PCIBIOS_BAD_REGISTER_NUMBER; 87 88 spin_lock_irqsave(&nile4_pci_lock, flags); 89 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, 90 &data); 91 spin_unlock_irqrestore(&nile4_pci_lock, flags); 92 93 if (err) 94 return err; 95 96 if (size == 1) 97 *val = (data >> ((where & 3) << 3)) & 0xff; 98 else if (size == 2) 99 *val = (data >> ((where & 3) << 3)) & 0xffff; 100 else 101 *val = data; 102 103 return PCIBIOS_SUCCESSFUL; 104} 105 106static int nile4_pcibios_write(struct pci_bus *bus, unsigned int devfn, 107 int where, int size, u32 val) 108{ 109 unsigned long flags; 110 u32 data = 0; 111 int err; 112 113 if ((size == 2) && (where & 1)) 114 return PCIBIOS_BAD_REGISTER_NUMBER; 115 else if ((size == 4) && (where & 3)) 116 return PCIBIOS_BAD_REGISTER_NUMBER; 117 118 spin_lock_irqsave(&nile4_pci_lock, flags); 119 err = nile4_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where, 120 &data); 121 spin_unlock_irqrestore(&nile4_pci_lock, flags); 122 123 if (err) 124 return err; 125 126 if (size == 1) 127 data = (data & ~(0xff << ((where & 3) << 3))) | 128 (val << ((where & 3) << 3)); 129 else if (size == 2) 130 data = (data & ~(0xffff << ((where & 3) << 3))) | 131 (val << ((where & 3) << 3)); 132 else 133 data = val; 134 135 if (nile4_pcibios_config_access 136 (PCI_ACCESS_WRITE, bus, devfn, where, &data)) 137 return -1; 138 139 return PCIBIOS_SUCCESSFUL; 140} 141 142struct pci_ops nile4_pci_ops = { 143 .read = nile4_pcibios_read, 144 .write = nile4_pcibios_write, 145}; 146