[PATCH] ocfs2: fix oops in mmap_truncate testing
[pandora-kernel.git] / arch / ppc / boot / simple / qspan_pci.c
1 /*
2  * LinuxPPC arch/ppc/kernel/qspan_pci.c   Dan Malek (dmalek@jlc.net)
3  *
4  * QSpan Motorola bus to PCI bridge.  The config address register
5  * is located 0x500 from the base of the bridge control/status registers.
6  * The data register is located at 0x504.
7  * This is a two step operation.  First, the address register is written,
8  * then the data register is read/written as required.
9  * I don't know what to do about interrupts (yet).
10  */
11
12 #include <linux/types.h>
13 #include <linux/kernel.h>
14 #include <linux/pci.h>
15 #include <asm/mpc8xx.h>
16
17 /*
18  * When reading the configuration space, if something does not respond
19  * the bus times out and we get a machine check interrupt.  So, the
20  * good ol' exception tables come to mind to trap it and return some
21  * value.
22  *
23  * On an error we just return a -1, since that is what the caller wants
24  * returned if nothing is present.  I copied this from __get_user_asm,
25  * with the only difference of returning -1 instead of EFAULT.
26  * There is an associated hack in the machine check trap code.
27  *
28  * The QSPAN is also a big endian device, that is it makes the PCI
29  * look big endian to us.  This presents a problem for the Linux PCI
30  * functions, which assume little endian.  For example, we see the
31  * first 32-bit word like this:
32  *      ------------------------
33  *      | Device ID | Vendor ID |
34  *      ------------------------
35  * If we read/write as a double word, that's OK.  But in our world,
36  * when read as a word, device ID is at location 0, not location 2 as
37  * the little endian PCI would believe.  We have to switch bits in
38  * the PCI addresses given to us to get the data to/from the correct
39  * byte lanes.
40  *
41  * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5.
42  * It always forces the MS bit to zero.  Therefore, dev_fn values
43  * greater than 128 are returned as "no device found" errors.
44  *
45  * The QSPAN can only perform long word (32-bit) configuration cycles.
46  * The "offset" must have the two LS bits set to zero.  Read operations
47  * require we read the entire word and then sort out what should be
48  * returned.  Write operations other than long word require that we
49  * read the long word, update the proper word or byte, then write the
50  * entire long word back.
51  *
52  * PCI Bridge hack.  We assume (correctly) that bus 0 is the primary
53  * PCI bus from the QSPAN.  If we are called with a bus number other
54  * than zero, we create a Type 1 configuration access that a downstream
55  * PCI bridge will interpret.
56  */
57
58 #define __get_pci_config(x, addr, op)           \
59         __asm__ __volatile__(                           \
60                 "1:     "op" %0,0(%1)\n"                \
61                 "       eieio\n"                        \
62                 "2:\n"                                  \
63                 ".section .fixup,\"ax\"\n"              \
64                 "3:     li %0,-1\n"                     \
65                 "       b 2b\n"                         \
66                 ".section __ex_table,\"a\"\n"           \
67                 "       .align 2\n"                     \
68                 "       .long 1b,3b\n"                  \
69                 ".text"                                 \
70                 : "=r"(x) : "r"(addr))
71
72 #define QS_CONFIG_ADDR  ((volatile uint *)(PCI_CSR_ADDR + 0x500))
73 #define QS_CONFIG_DATA  ((volatile uint *)(PCI_CSR_ADDR + 0x504))
74
75 #define mk_config_addr(bus, dev, offset) \
76         (((bus)<<16) | ((dev)<<8) | (offset & 0xfc))
77
78 #define mk_config_type1(bus, dev, offset) \
79         mk_config_addr(bus, dev, offset) | 1;
80
81 /* Initialize the QSpan device registers after power up.
82 */
83 void
84 qspan_init(void)
85 {
86         uint    *qptr;
87
88
89
90         qptr = (uint *)PCI_CSR_ADDR;
91
92         /* PCI Configuration/status.  Upper bits written to clear
93          * pending interrupt or status.  Lower bits enable QSPAN as
94          * PCI master, enable memory and I/O cycles, and enable PCI
95          * parity error checking.
96          * IMPORTANT:  The last two bits of this word enable PCI
97          * master cycles into the QBus.  The QSpan is broken and can't
98          * meet the timing specs of the PQ bus for this to work.  Therefore,
99          * if you don't have external bus arbitration, you can't use
100          * this function.
101          */
102 #ifdef EXTERNAL_PQ_ARB
103         qptr[1] = 0xf9000147;
104 #else
105         qptr[1] = 0xf9000144;
106 #endif
107
108         /* PCI Misc configuration.  Set PCI latency timer resolution
109          * of 8 cycles, set cache size to 4 x 32.
110          */
111         qptr[3] = 0;
112
113         /* Set up PCI Target address mapping.  Enable, Posted writes,
114          * 2Gbyte space (processor memory controller determines actual size).
115          */
116         qptr[64] = 0x8f000080;
117
118         /* Map processor 0x80000000 to PCI 0x00000000.
119          * Processor address bit 1 determines I/O type access (0x80000000)
120          * or memory type access (0xc0000000).
121          */
122         qptr[65] = 0x80000000;
123
124         /* Enable error logging and clear any pending error status.
125         */
126         qptr[80] = 0x90000000;
127
128         qptr[512] = 0x000c0003;
129
130         /* Set up Qbus slave image.
131         */
132         qptr[960] = 0x01000000;
133         qptr[961] = 0x000000d1;
134         qptr[964] = 0x00000000;
135         qptr[965] = 0x000000d1;
136
137 }
138
139 /* Functions to support PCI bios-like features to read/write configuration
140  * space.  If the function fails for any reason, a -1 (0xffffffff) value
141  * must be returned.
142  */
143 #define DEVICE_NOT_FOUND        (-1)
144 #define SUCCESSFUL              0
145
146 int qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
147                                   unsigned char offset, unsigned char *val)
148 {
149         uint    temp;
150         u_char  *cp;
151
152         if ((bus > 7) || (dev_fn > 127)) {
153                 *val = 0xff;
154                 return DEVICE_NOT_FOUND;
155         }
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_pci_config(temp, QS_CONFIG_DATA, "lwz");
162
163         offset ^= 0x03;
164         cp = ((u_char *)&temp) + (offset & 0x03);
165         *val = *cp;
166         return SUCCESSFUL;
167 }
168
169 int qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn,
170                                   unsigned char offset, unsigned short *val)
171 {
172         uint    temp;
173         ushort  *sp;
174
175         if ((bus > 7) || (dev_fn > 127)) {
176                 *val = 0xffff;
177                 return DEVICE_NOT_FOUND;
178         }
179
180         if (bus == 0)
181                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
182         else
183                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
184         __get_pci_config(temp, QS_CONFIG_DATA, "lwz");
185         offset ^= 0x02;
186
187         sp = ((ushort *)&temp) + ((offset >> 1) & 1);
188         *val = *sp;
189         return SUCCESSFUL;
190 }
191
192 int qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn,
193                                    unsigned char offset, unsigned int *val)
194 {
195         if ((bus > 7) || (dev_fn > 127)) {
196                 *val = 0xffffffff;
197                 return DEVICE_NOT_FOUND;
198         }
199         if (bus == 0)
200                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
201         else
202                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
203         __get_pci_config(*val, QS_CONFIG_DATA, "lwz");
204         return SUCCESSFUL;
205 }
206
207 int qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn,
208                                    unsigned char offset, unsigned char val)
209 {
210         uint    temp;
211         u_char  *cp;
212
213         if ((bus > 7) || (dev_fn > 127))
214                 return DEVICE_NOT_FOUND;
215
216         qs_pci_read_config_dword(bus, dev_fn, offset, &temp);
217
218         offset ^= 0x03;
219         cp = ((u_char *)&temp) + (offset & 0x03);
220         *cp = val;
221
222         if (bus == 0)
223                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
224         else
225                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
226         *QS_CONFIG_DATA = temp;
227
228         return SUCCESSFUL;
229 }
230
231 int qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn,
232                                    unsigned char offset, unsigned short val)
233 {
234         uint    temp;
235         ushort  *sp;
236
237         if ((bus > 7) || (dev_fn > 127))
238                 return DEVICE_NOT_FOUND;
239
240         qs_pci_read_config_dword(bus, dev_fn, offset, &temp);
241
242         offset ^= 0x02;
243         sp = ((ushort *)&temp) + ((offset >> 1) & 1);
244         *sp = val;
245
246         if (bus == 0)
247                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
248         else
249                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
250         *QS_CONFIG_DATA = temp;
251
252         return SUCCESSFUL;
253 }
254
255 int qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn,
256                                     unsigned char offset, unsigned int val)
257 {
258         if ((bus > 7) || (dev_fn > 127))
259                 return DEVICE_NOT_FOUND;
260
261         if (bus == 0)
262                 *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset);
263         else
264                 *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset);
265         *(unsigned int *)QS_CONFIG_DATA = val;
266
267         return SUCCESSFUL;
268 }
269