0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/types.h>
0011 #include <linux/pci.h>
0012 #include <linux/kernel.h>
0013
0014 #include <asm/mips-boards/bonito64.h>
0015
0016 #define PCI_ACCESS_READ 0
0017 #define PCI_ACCESS_WRITE 1
0018
0019 #define CFG_SPACE_REG(offset) (void *)CKSEG1ADDR(_pcictrl_bonito_pcicfg + (offset))
0020 #define ID_SEL_BEGIN 10
0021 #define MAX_DEV_NUM (31 - ID_SEL_BEGIN)
0022
0023
0024 static int bonito64_pcibios_config_access(unsigned char access_type,
0025 struct pci_bus *bus,
0026 unsigned int devfn, int where,
0027 u32 * data)
0028 {
0029 u32 busnum = bus->number;
0030 u32 addr, type;
0031 u32 dummy;
0032 void *addrp;
0033 int device = PCI_SLOT(devfn);
0034 int function = PCI_FUNC(devfn);
0035 int reg = where & ~3;
0036
0037 if (busnum == 0) {
0038
0039 if (device > MAX_DEV_NUM)
0040 return -1;
0041
0042 addr = (1 << (device + ID_SEL_BEGIN)) | (function << 8) | reg;
0043 type = 0;
0044 } else {
0045
0046 addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
0047 type = 0x10000;
0048 }
0049
0050
0051 BONITO_PCICMD |= BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR;
0052
0053 BONITO_PCIMAP_CFG = (addr >> 16) | type;
0054
0055
0056 dummy = BONITO_PCIMAP_CFG;
0057 mmiowb();
0058
0059 addrp = CFG_SPACE_REG(addr & 0xffff);
0060 if (access_type == PCI_ACCESS_WRITE) {
0061 writel(cpu_to_le32(*data), addrp);
0062
0063 while (BONITO_PCIMSTAT & 0xF);
0064 } else {
0065 *data = le32_to_cpu(readl(addrp));
0066 }
0067
0068
0069 if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR |
0070 BONITO_PCICMD_MTABORT_CLR)) {
0071
0072
0073
0074 BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
0075 BONITO_PCICMD_MTABORT_CLR);
0076
0077 return -1;
0078 }
0079
0080 return 0;
0081
0082 }
0083
0084
0085
0086
0087
0088
0089 static int bonito64_pcibios_read(struct pci_bus *bus, unsigned int devfn,
0090 int where, int size, u32 * val)
0091 {
0092 u32 data = 0;
0093
0094 if ((size == 2) && (where & 1))
0095 return PCIBIOS_BAD_REGISTER_NUMBER;
0096 else if ((size == 4) && (where & 3))
0097 return PCIBIOS_BAD_REGISTER_NUMBER;
0098
0099 if (bonito64_pcibios_config_access(PCI_ACCESS_READ, bus, devfn, where,
0100 &data))
0101 return -1;
0102
0103 if (size == 1)
0104 *val = (data >> ((where & 3) << 3)) & 0xff;
0105 else if (size == 2)
0106 *val = (data >> ((where & 3) << 3)) & 0xffff;
0107 else
0108 *val = data;
0109
0110 return PCIBIOS_SUCCESSFUL;
0111 }
0112
0113 static int bonito64_pcibios_write(struct pci_bus *bus, unsigned int devfn,
0114 int where, int size, u32 val)
0115 {
0116 u32 data = 0;
0117
0118 if ((size == 2) && (where & 1))
0119 return PCIBIOS_BAD_REGISTER_NUMBER;
0120 else if ((size == 4) && (where & 3))
0121 return PCIBIOS_BAD_REGISTER_NUMBER;
0122
0123 if (size == 4)
0124 data = val;
0125 else {
0126 if (bonito64_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
0127 where, &data))
0128 return -1;
0129
0130 if (size == 1)
0131 data = (data & ~(0xff << ((where & 3) << 3))) |
0132 (val << ((where & 3) << 3));
0133 else if (size == 2)
0134 data = (data & ~(0xffff << ((where & 3) << 3))) |
0135 (val << ((where & 3) << 3));
0136 }
0137
0138 if (bonito64_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn, where,
0139 &data))
0140 return -1;
0141
0142 return PCIBIOS_SUCCESSFUL;
0143 }
0144
0145 struct pci_ops bonito64_pci_ops = {
0146 .read = bonito64_pcibios_read,
0147 .write = bonito64_pcibios_write
0148 };