1 #include <linux/kernel.h>
2 #include <linux/init.h>
3 #include <linux/pci.h>
4 #include <linux/spinlock.h>
5 #include <asm/bootinfo.h>
6
7 #include <asm/nile4.h>
8 #include <asm/lasat/lasat.h>
9
10 #define PCI_ACCESS_READ 0
11 #define PCI_ACCESS_WRITE 1
12
13 #define LO(reg) (reg / 4)
14 #define HI(reg) (reg / 4 + 1)
15
16 static volatile unsigned long * const vrc_pciregs = (void *)Vrc5074_BASE;
17
18 static spinlock_t nile4_pci_lock;
19
nile4_pcibios_config_access(unsigned char access_type,struct pci_dev * dev,unsigned char reg,u32 * data)20 static int nile4_pcibios_config_access(unsigned char access_type,
21 struct pci_dev *dev, unsigned char reg, u32 *data)
22 {
23 unsigned char bus = dev->bus->number;
24 unsigned char dev_fn = dev->devfn;
25 u32 adr, mask, err;
26
27 if ((bus == 0) && (PCI_SLOT(dev_fn) > 8))
28 /* The addressing scheme chosen leaves room for just
29 * 8 devices on the first bus (besides the PCI
30 * controller itself) */
31 return PCIBIOS_DEVICE_NOT_FOUND;
32
33 if ((bus == 0) && (dev_fn == PCI_DEVFN(0,0))) {
34 /* Access controller registers directly */
35 if (access_type == PCI_ACCESS_WRITE) {
36 vrc_pciregs[(0x200+reg) >> 2] = *data;
37 } else {
38 *data = vrc_pciregs[(0x200+reg) >> 2];
39 }
40 return PCIBIOS_SUCCESSFUL;
41 }
42
43 /* Temporarily map PCI Window 1 to config space */
44 mask = vrc_pciregs[LO(NILE4_PCIINIT1)];
45 vrc_pciregs[LO(NILE4_PCIINIT1)] = 0x0000001a | (bus ? 0x200 : 0);
46
47 /* Clear PCI Error register. This also clears the Error Type
48 * bits in the Control register */
49 vrc_pciregs[LO(NILE4_PCIERR)] = 0;
50 vrc_pciregs[HI(NILE4_PCIERR)] = 0;
51
52 /* Setup address */
53 if (bus == 0)
54 adr = KSEG1ADDR(PCI_WINDOW1) +
55 ((1 << (PCI_SLOT(dev_fn) + 15)) |
56 (PCI_FUNC(dev_fn) << 8) | (reg & ~3));
57 else
58 adr = KSEG1ADDR(PCI_WINDOW1) | (bus << 16) | (dev_fn << 8) |
59 (reg & ~3);
60
61 if (access_type == PCI_ACCESS_WRITE)
62 *(u32 *)adr = *data;
63 else
64 *data = *(u32 *)adr;
65
66 /* Check for master or target abort */
67 err = (vrc_pciregs[HI(NILE4_PCICTRL)] >> 5) & 0x7;
68
69 /* Restore PCI Window 1 */
70 vrc_pciregs[LO(NILE4_PCIINIT1)] = mask;
71
72 if (err)
73 return PCIBIOS_DEVICE_NOT_FOUND;
74
75 return PCIBIOS_SUCCESSFUL;
76 }
77
78 /*
79 * We can't address 8 and 16 bit words directly. Instead we have to
80 * read/write a 32bit word and mask/modify the data we actually want.
81 */
nile4_pcibios_read_config_byte(struct pci_dev * dev,int reg,u8 * val)82 static int nile4_pcibios_read_config_byte(struct pci_dev *dev, int reg, u8 *val)
83 {
84 unsigned long flags;
85 u32 data = 0;
86 int err;
87
88 spin_lock_irqsave(&nile4_pci_lock, flags);
89 err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data);
90 spin_unlock_irqrestore(&nile4_pci_lock, flags);
91
92 if (err)
93 return err;
94
95 *val = (data >> ((reg & 3) << 3)) & 0xff;
96
97 return PCIBIOS_SUCCESSFUL;
98 }
99
nile4_pcibios_read_config_word(struct pci_dev * dev,int reg,u16 * val)100 static int nile4_pcibios_read_config_word(struct pci_dev *dev, int reg, u16 *val)
101 {
102 unsigned long flags;
103 u32 data = 0;
104 int err;
105
106 if (reg & 1)
107 return PCIBIOS_BAD_REGISTER_NUMBER;
108
109 spin_lock_irqsave(&nile4_pci_lock, flags);
110 err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data);
111 spin_unlock_irqrestore(&nile4_pci_lock, flags);
112
113 if (err)
114 return err;
115
116 *val = (data >> ((reg & 3) << 3)) & 0xffff;
117
118 return PCIBIOS_SUCCESSFUL;
119 }
120
nile4_pcibios_read_config_dword(struct pci_dev * dev,int reg,u32 * val)121 static int nile4_pcibios_read_config_dword(struct pci_dev *dev, int reg, u32 *val)
122 {
123 unsigned long flags;
124 u32 data = 0;
125 int err;
126
127 if (reg & 3)
128 return PCIBIOS_BAD_REGISTER_NUMBER;
129
130 spin_lock_irqsave(&nile4_pci_lock, flags);
131 err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data);
132 spin_unlock_irqrestore(&nile4_pci_lock, flags);
133
134 if (err)
135 return err;
136
137 *val = data;
138
139 return PCIBIOS_SUCCESSFUL;
140 }
141
142
nile4_pcibios_write_config_byte(struct pci_dev * dev,int reg,u8 val)143 static int nile4_pcibios_write_config_byte(struct pci_dev *dev, int reg, u8 val)
144 {
145 unsigned long flags;
146 u32 data = 0;
147 int err;
148
149 spin_lock_irqsave(&nile4_pci_lock, flags);
150 err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data);
151 if (err)
152 goto out;
153
154 data = (data & ~(0xff << ((reg & 3) << 3))) | (val << ((reg & 3) << 3));
155 err = nile4_pcibios_config_access(PCI_ACCESS_WRITE, dev, reg, &data);
156
157 out:
158 spin_unlock_irqrestore(&nile4_pci_lock, flags);
159 return err;
160 }
161
nile4_pcibios_write_config_word(struct pci_dev * dev,int reg,u16 val)162 static int nile4_pcibios_write_config_word(struct pci_dev *dev, int reg, u16 val)
163 {
164 unsigned long flags;
165 u32 data = 0;
166 int err;
167
168 if (reg & 1)
169 return PCIBIOS_BAD_REGISTER_NUMBER;
170
171 spin_lock_irqsave(&nile4_pci_lock, flags);
172 err = nile4_pcibios_config_access(PCI_ACCESS_READ, dev, reg, &data);
173 if (err)
174 goto out;
175
176 data = (data & ~(0xffff << ((reg & 3) << 3))) | (val << ((reg&3) << 3));
177 err = nile4_pcibios_config_access(PCI_ACCESS_WRITE, dev, reg, &data);
178
179 out:
180 spin_unlock_irqrestore(&nile4_pci_lock, flags);
181 return err;
182 }
183
nile4_pcibios_write_config_dword(struct pci_dev * dev,int reg,u32 val)184 static int nile4_pcibios_write_config_dword(struct pci_dev *dev, int reg, u32 val)
185 {
186 unsigned long flags;
187 u32 data = 0;
188 int err;
189
190 if (reg & 3)
191 return PCIBIOS_BAD_REGISTER_NUMBER;
192
193 spin_lock_irqsave(&nile4_pci_lock, flags);
194 err = nile4_pcibios_config_access(PCI_ACCESS_WRITE, dev, reg, &val);
195 spin_unlock_irqrestore(&nile4_pci_lock, flags);
196
197 if (err)
198 return -1;
199 else
200 return PCIBIOS_SUCCESSFUL;
201 out:
202 return err;
203 }
204
205 struct pci_ops nile4_pci_ops = {
206 nile4_pcibios_read_config_byte,
207 nile4_pcibios_read_config_word,
208 nile4_pcibios_read_config_dword,
209 nile4_pcibios_write_config_byte,
210 nile4_pcibios_write_config_word,
211 nile4_pcibios_write_config_dword
212 };
213