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