0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/types.h>
0009 #include <linux/pci.h>
0010 #include <linux/kernel.h>
0011
0012 #include <asm/gt64120.h>
0013
0014 #define PCI_ACCESS_READ 0
0015 #define PCI_ACCESS_WRITE 1
0016
0017
0018
0019
0020
0021 #define PCI_CFG_TYPE0_REG_SHF 0
0022 #define PCI_CFG_TYPE0_FUNC_SHF 8
0023
0024
0025 #define PCI_CFG_TYPE1_REG_SHF 0
0026 #define PCI_CFG_TYPE1_FUNC_SHF 8
0027 #define PCI_CFG_TYPE1_DEV_SHF 11
0028 #define PCI_CFG_TYPE1_BUS_SHF 16
0029
0030 static int gt64xxx_pci0_pcibios_config_access(unsigned char access_type,
0031 struct pci_bus *bus, unsigned int devfn, int where, u32 * data)
0032 {
0033 unsigned char busnum = bus->number;
0034 u32 intr;
0035
0036 if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0)))
0037 return -1;
0038
0039
0040 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
0041 GT_INTRCAUSE_TARABORT0_BIT));
0042
0043
0044 GT_WRITE(GT_PCI0_CFGADDR_OFS,
0045 (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) |
0046 (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
0047 ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
0048 GT_PCI0_CFGADDR_CONFIGEN_BIT);
0049
0050 if (access_type == PCI_ACCESS_WRITE) {
0051 if (busnum == 0 && PCI_SLOT(devfn) == 0) {
0052
0053
0054
0055
0056 GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
0057 } else
0058 __GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
0059 } else {
0060 if (busnum == 0 && PCI_SLOT(devfn) == 0) {
0061
0062
0063
0064
0065 *data = GT_READ(GT_PCI0_CFGDATA_OFS);
0066 } else
0067 *data = __GT_READ(GT_PCI0_CFGDATA_OFS);
0068 }
0069
0070
0071 intr = GT_READ(GT_INTRCAUSE_OFS);
0072
0073 if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) {
0074
0075
0076
0077 GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
0078 GT_INTRCAUSE_TARABORT0_BIT));
0079
0080 return -1;
0081 }
0082
0083 return 0;
0084 }
0085
0086
0087
0088
0089
0090
0091 static int gt64xxx_pci0_pcibios_read(struct pci_bus *bus, unsigned int devfn,
0092 int where, int size, u32 * val)
0093 {
0094 u32 data = 0;
0095
0096 if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
0097 where, &data))
0098 return PCIBIOS_DEVICE_NOT_FOUND;
0099
0100 if (size == 1)
0101 *val = (data >> ((where & 3) << 3)) & 0xff;
0102 else if (size == 2)
0103 *val = (data >> ((where & 3) << 3)) & 0xffff;
0104 else
0105 *val = data;
0106
0107 return PCIBIOS_SUCCESSFUL;
0108 }
0109
0110 static int gt64xxx_pci0_pcibios_write(struct pci_bus *bus, unsigned int devfn,
0111 int where, int size, u32 val)
0112 {
0113 u32 data = 0;
0114
0115 if (size == 4)
0116 data = val;
0117 else {
0118 if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_READ, bus,
0119 devfn, where, &data))
0120 return PCIBIOS_DEVICE_NOT_FOUND;
0121
0122 if (size == 1)
0123 data = (data & ~(0xff << ((where & 3) << 3))) |
0124 (val << ((where & 3) << 3));
0125 else if (size == 2)
0126 data = (data & ~(0xffff << ((where & 3) << 3))) |
0127 (val << ((where & 3) << 3));
0128 }
0129
0130 if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
0131 where, &data))
0132 return PCIBIOS_DEVICE_NOT_FOUND;
0133
0134 return PCIBIOS_SUCCESSFUL;
0135 }
0136
0137 struct pci_ops gt64xxx_pci0_ops = {
0138 .read = gt64xxx_pci0_pcibios_read,
0139 .write = gt64xxx_pci0_pcibios_write
0140 };