make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / arch / ppc / kernel / qspan_pci.c
1 /*
2  * BK Id: SCCS/s.qspan_pci.c 1.11 08/13/02 21:52:53 paulus
3  */
4 /*
5  * QSpan pci routines.
6  * Most 8xx boards use the QSpan PCI bridge.  The config address register
7  * is located 0x500 from the base of the bridge control/status registers.
8  * The data register is located at 0x504.
9  * This is a two step operation.  First, the address register is written,
10  * then the data register is read/written as required.
11  * I don't know what to do about interrupts (yet).
12  *
13  * The RPX Classic implementation shares a chip select for normal
14  * PCI access and QSpan control register addresses.  The selection is
15  * further selected by a bit setting in a board control register.
16  * Although it should happen, we disable interrupts during this operation
17  * to make sure some driver doesn't accidentally access the PCI while
18  * we have switched the chip select.
19  */
20
21 #include <linux/config.h>
22 #include <linux/kernel.h>
23 #include <linux/pci.h>
24 #include <linux/delay.h>
25 #include <linux/string.h>
26 #include <linux/init.h>
27
28 #include <asm/io.h>
29 #include <asm/mpc8xx.h>
30 #include <asm/system.h>
31 #include <asm/machdep.h>
32 #include <asm/pci-bridge.h>
33
34
35 /*
36  * This blows......
37  * When reading the configuration space, if something does not respond
38  * the bus times out and we get a machine check interrupt.  So, the
39  * good ol' exception tables come to mind to trap it and return some
40  * value.
41  *
42  * On an error we just return a -1, since that is what the caller wants
43  * returned if nothing is present.  I copied this from __get_user_asm,
44  * with the only difference of returning -1 instead of EFAULT.
45  * There is an associated hack in the machine check trap code.
46  *
47  * The QSPAN is also a big endian device, that is it makes the PCI
48  * look big endian to us.  This presents a problem for the Linux PCI
49  * functions, which assume little endian.  For example, we see the
50  * first 32-bit word like this:
51  *      ------------------------
52  *      | Device ID | Vendor ID |
53  *      ------------------------
54  * If we read/write as a double word, that's OK.  But in our world,
55  * when read as a word, device ID is at location 0, not location 2 as
56  * the little endian PCI would believe.  We have to switch bits in
57  * the PCI addresses given to us to get the data to/from the correct
58  * byte lanes.
59  *
60  * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5.
61  * It always forces the MS bit to zero.  Therefore, dev_fn values
62  * greater than 128 are returned as "no device found" errors.
63  *
64  * The QSPAN can only perform long word (32-bit) configuration cycles.
65  * The "offset" must have the two LS bits set to zero.  Read operations
66  * require we read the entire word and then sort out what should be
67  * returned.  Write operations other than long word require that we
68  * read the long word, update the proper word or byte, then write the
69  * entire long word back.
70  *
71  * PCI Bridge hack.  We assume (correctly) that bus 0 is the primary
72  * PCI bus from the QSPAN.  If we are called with a bus number other
73  * than zero, we create a Type 1 configuration access that a downstream
74  * PCI bridge will interpret.
75  */
76
77 #define __get_qspan_pci_config(x, addr, op)             \
78         __asm__ __volatile__(                           \
79                 "1:     "op" %0,0(%1)\n"                \
80                 "       eieio\n"                        \
81                 "2:\n"                                  \
82                 ".section .fixup,\"ax\"\n"              \
83                 "3:     li %0,-1\n"                     \
84                 "       b 2b\n"                         \
85                 ".section __ex_table,\"a\"\n"           \
86                 "       .align 2\n"                     \
87                 "       .long 1b,3b\n"                  \
88                 ".text"                                 \
89                 : "=r"(x) : "r"(addr) : " %0")
90
91 #define QS_CONFIG_ADDR  ((volatile uint *)(PCI_CSR_ADDR + 0x500))
92 #define QS_CONFIG_DATA  ((volatile uint *)(PCI_CSR_ADDR + 0x504))
93
94 #define mk_config_addr(bus, dev, offset) \
95         (((bus)<<16) | ((dev)<<8) | (offset & 0xfc))
96
97 #define mk_config_type1(bus, dev, offset) \
98         mk_config_addr(bus, dev, offset) | 1;
99
100 int qspan_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
101                                   unsigned char offset, unsigned char *val)
102 {
103         uint    temp;
104         u_char  *cp;
105 #ifdef CONFIG_RPXCLASSIC
106         unsigned long flags;
107 #endif
108
109         if ((bus > 7) || (dev_fn > 127)) {
110                 *val = 0xff;
111                 return PCIBIOS_DEVICE_NOT_FOUND;
112         }
113
114 #ifdef CONFIG_RPXCLASSIC
115         save_flags(flags);
116         cli();
117         *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
118         eieio();
119 #endif
120
121         if (bus == 0)
122                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
123         else
124                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
125         __get_qspan_pci_config(temp, QS_CONFIG_DATA, "lwz");
126
127 #ifdef CONFIG_RPXCLASSIC
128         *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
129         eieio();
130         restore_flags(flags);
131 #endif
132
133         offset ^= 0x03;
134         cp = ((u_char *)&temp) + (offset & 0x03);
135         *val = *cp;
136         return PCIBIOS_SUCCESSFUL;
137 }
138
139 int qspan_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
140                                   unsigned char offset, unsigned short *val)
141 {
142         uint    temp;
143         ushort  *sp;
144 #ifdef CONFIG_RPXCLASSIC
145         unsigned long flags;
146 #endif
147
148         if ((bus > 7) || (dev_fn > 127)) {
149                 *val = 0xffff;
150                 return PCIBIOS_DEVICE_NOT_FOUND;
151         }
152
153 #ifdef CONFIG_RPXCLASSIC
154         save_flags(flags);
155         cli();
156         *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
157         eieio();
158 #endif
159
160         if (bus == 0)
161                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
162         else
163                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
164         __get_qspan_pci_config(temp, QS_CONFIG_DATA, "lwz");
165         offset ^= 0x02;
166
167 #ifdef CONFIG_RPXCLASSIC
168         *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
169         eieio();
170         restore_flags(flags);
171 #endif
172
173         sp = ((ushort *)&temp) + ((offset >> 1) & 1);
174         *val = *sp;
175         return PCIBIOS_SUCCESSFUL;
176 }
177
178 int qspan_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
179                                    unsigned char offset, unsigned int *val)
180 {
181 #ifdef CONFIG_RPXCLASSIC
182         unsigned long flags;
183 #endif
184
185         if ((bus > 7) || (dev_fn > 127)) {
186                 *val = 0xffffffff;
187                 return PCIBIOS_DEVICE_NOT_FOUND;
188         }
189
190 #ifdef CONFIG_RPXCLASSIC
191         save_flags(flags);
192         cli();
193         *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
194         eieio();
195 #endif
196
197         if (bus == 0)
198                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
199         else
200                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
201         __get_qspan_pci_config(*val, QS_CONFIG_DATA, "lwz");
202
203 #ifdef CONFIG_RPXCLASSIC
204         *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
205         eieio();
206         restore_flags(flags);
207 #endif
208
209         return PCIBIOS_SUCCESSFUL;
210 }
211
212 int qspan_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
213                                    unsigned char offset, unsigned char val)
214 {
215         uint    temp;
216         u_char  *cp;
217 #ifdef CONFIG_RPXCLASSIC
218         unsigned long flags;
219 #endif
220
221         if ((bus > 7) || (dev_fn > 127))
222                 return PCIBIOS_DEVICE_NOT_FOUND;
223
224         qspan_pcibios_read_config_dword(bus, dev_fn, offset, &temp);
225
226         offset ^= 0x03;
227         cp = ((u_char *)&temp) + (offset & 0x03);
228         *cp = val;
229
230 #ifdef CONFIG_RPXCLASSIC
231         save_flags(flags);
232         cli();
233         *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
234         eieio();
235 #endif
236
237         if (bus == 0)
238                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
239         else
240                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
241         *QS_CONFIG_DATA = temp;
242
243 #ifdef CONFIG_RPXCLASSIC
244         *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
245         eieio();
246         restore_flags(flags);
247 #endif
248
249         return PCIBIOS_SUCCESSFUL;
250 }
251
252 int qspan_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
253                                    unsigned char offset, unsigned short val)
254 {
255         uint    temp;
256         ushort  *sp;
257 #ifdef CONFIG_RPXCLASSIC
258         unsigned long flags;
259 #endif
260
261         if ((bus > 7) || (dev_fn > 127))
262                 return PCIBIOS_DEVICE_NOT_FOUND;
263
264         qspan_pcibios_read_config_dword(bus, dev_fn, offset, &temp);
265
266         offset ^= 0x02;
267         sp = ((ushort *)&temp) + ((offset >> 1) & 1);
268         *sp = val;
269
270 #ifdef CONFIG_RPXCLASSIC
271         save_flags(flags);
272         cli();
273         *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
274         eieio();
275 #endif
276
277         if (bus == 0)
278                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
279         else
280                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
281         *QS_CONFIG_DATA = temp;
282
283 #ifdef CONFIG_RPXCLASSIC
284         *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
285         eieio();
286         restore_flags(flags);
287 #endif
288
289         return PCIBIOS_SUCCESSFUL;
290 }
291
292 int qspan_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
293                                     unsigned char offset, unsigned int val)
294 {
295 #ifdef CONFIG_RPXCLASSIC
296         unsigned long flags;
297 #endif
298
299         if ((bus > 7) || (dev_fn > 127))
300                 return PCIBIOS_DEVICE_NOT_FOUND;
301
302 #ifdef CONFIG_RPXCLASSIC
303         save_flags(flags);
304         cli();
305         *((uint *)RPX_CSR_ADDR) &= ~BCSR2_QSPACESEL;
306         eieio();
307 #endif
308
309         if (bus == 0)
310                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
311         else
312                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
313         *(unsigned int *)QS_CONFIG_DATA = val;
314
315 #ifdef CONFIG_RPXCLASSIC
316         *((uint *)RPX_CSR_ADDR) |= BCSR2_QSPACESEL;
317         eieio();
318         restore_flags(flags);
319 #endif
320
321         return PCIBIOS_SUCCESSFUL;
322 }
323
324 int qspan_pcibios_find_device(unsigned short vendor, unsigned short dev_id,
325                              unsigned short index, unsigned char *bus_ptr,
326                              unsigned char *dev_fn_ptr)
327 {
328     int num, devfn;
329     unsigned int x, vendev;
330
331     if (vendor == 0xffff)
332         return PCIBIOS_BAD_VENDOR_ID;
333     vendev = (dev_id << 16) + vendor;
334     num = 0;
335     for (devfn = 0;  devfn < 32;  devfn++) {
336         qspan_pcibios_read_config_dword(0, devfn<<3, PCI_VENDOR_ID, &x);
337         if (x == vendev) {
338             if (index == num) {
339                 *bus_ptr = 0;
340                 *dev_fn_ptr = devfn<<3;
341                 return PCIBIOS_SUCCESSFUL;
342             }
343             ++num;
344         }
345     }
346     return PCIBIOS_DEVICE_NOT_FOUND;
347 }
348
349 int qspan_pcibios_find_class(unsigned int class_code, unsigned short index,
350                             unsigned char *bus_ptr, unsigned char *dev_fn_ptr)
351 {
352     int devnr, x, num;
353
354     num = 0;
355     for (devnr = 0;  devnr < 32;  devnr++) {
356         qspan_pcibios_read_config_dword(0, devnr<<3, PCI_CLASS_REVISION, &x);
357         if ((x>>8) == class_code) {
358             if (index == num) {
359                 *bus_ptr = 0;
360                 *dev_fn_ptr = devnr<<3;
361                 return PCIBIOS_SUCCESSFUL;
362             }
363             ++num;
364         }
365     }
366     return PCIBIOS_DEVICE_NOT_FOUND;
367 }
368
369 void __init
370 m8xx_pcibios_fixup(void))
371 {
372    /* Lots to do here, all board and configuration specific. */
373 }
374
375 void __init
376 m8xx_setup_pci_ptrs(void))
377 {
378         set_config_access_method(qspan);
379
380         ppc_md.pcibios_fixup = m8xx_pcibios_fixup;
381 }
382