ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / arm / mach-iop3xx / iop310-pci.c
1 /*
2  * arch/arm/mach-iop3xx/iop310-pci.c
3  *
4  * PCI support for the Intel IOP310 chipset
5  *
6  * Matt Porter <mporter@mvista.com>
7  *
8  * Copyright (C) 2001 MontaVista Software, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  */
14 #include <linux/kernel.h>
15 #include <linux/pci.h>
16 #include <linux/slab.h>
17 #include <linux/mm.h>
18 #include <linux/init.h>
19 #include <linux/ioport.h>
20
21 #include <asm/io.h>
22 #include <asm/irq.h>
23 #include <asm/system.h>
24 #include <asm/hardware.h>
25 #include <asm/mach/pci.h>
26
27 #include <asm/arch/iop310.h>
28
29 /*
30  *    *** Special note - why the IOP310 should NOT be used ***
31  *
32  * The PCI ATU is a brain dead implementation, only allowing 32-bit
33  * accesses to PCI configuration space.  This is especially brain
34  * dead for writes to this space.  A simple for-instance:
35  *
36  *  You want to modify the command register *without* corrupting the
37  *  status register.
38  *
39  *  To perform this, you need to read *32* bits of data from offset 4,
40  *  mask off the low 16, replace them with the new data, and write *32*
41  *  bits back.
42  *
43  *  Writing the status register at offset 6 with status bits set *clears*
44  *  the status.
45  *
46  * Hello?  Could we have a *SANE* implementation of a PCI ATU some day
47  * *PLEASE*?
48  */
49 #undef DEBUG
50 #ifdef DEBUG
51 #define  DBG(x...) printk(x)
52 #else
53 #define  DBG(x...) do { } while (0)
54 #endif
55
56 /*
57  * Calculate the address, etc from the bus, devfn and register
58  * offset.  Note that we have two root buses, so we need some
59  * method to determine whether we need config type 0 or 1 cycles.
60  * We use a root bus number in our bus->sysdata structure for this.
61  */
62 static u32 iop310_cfg_address(struct pci_bus *bus, int devfn, int where)
63 {
64         struct pci_sys_data *sys = bus->sysdata;
65         u32 addr;
66
67         if (sys->busnr == bus->number)
68                 addr = 1 << (PCI_SLOT(devfn) + 16);
69         else
70                 addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
71
72         addr |= PCI_FUNC(devfn) << 8 | (where & ~3);
73
74         return addr;
75 }
76
77 /*
78  * Primary PCI interface support.
79  */
80 static int iop310_pri_pci_status(void)
81 {
82         unsigned int status;
83         int ret = 0;
84
85         status = *IOP310_PATUSR;
86         if (status & 0xf900) {
87                 *IOP310_PATUSR = status & 0xf900;
88                 ret = 1;
89         }
90         status = *IOP310_PATUISR;
91         if (status & 0x0000018f) {
92                 *IOP310_PATUISR = status & 0x0000018f;
93                 ret = 1;
94         }
95         status = *IOP310_PSR;
96         if (status & 0xf900) {
97                 *IOP310_PSR = status & 0xf900;
98                 ret = 1;
99         }
100         status = *IOP310_PBISR;
101         if (status & 0x003f) {
102                 *IOP310_PBISR = status & 0x003f;
103                 ret = 1;
104         }
105         return ret;
106 }
107
108 /*
109  * Simply write the address register and read the configuration
110  * data.  Note that the 4 nop's ensure that we are able to handle
111  * a delayed abort (in theory.)
112  */
113 static inline u32 iop310_pri_read(unsigned long addr)
114 {
115         u32 val;
116
117         __asm__ __volatile__(
118                 "str    %1, [%2]\n\t"
119                 "ldr    %0, [%3]\n\t"
120                 "nop\n\t"
121                 "nop\n\t"
122                 "nop\n\t"
123                 "nop\n\t"
124                 : "=r" (val)
125                 : "r" (addr), "r" (IOP310_POCCAR), "r" (IOP310_POCCDR));
126
127         return val;
128 }
129
130 static int
131 iop310_pri_read_config(struct pci_bus *bus, unsigned int devfn, int where,
132                        int size, u32 *value)
133 {
134         unsigned long addr = iop310_cfg_address(bus, devfn, where);
135         u32 val = iop310_pri_read(addr) >> ((where & 3) * 8);
136
137         if (iop310_pri_pci_status())
138                 val = 0xffffffff;
139
140         *value = val;
141
142         return PCIBIOS_SUCCESSFUL;
143 }
144
145 static int
146 iop310_pri_write_config(struct pci_bus *bus, unsigned int devfn, int where,
147                         int size, u32 value)
148 {
149         unsigned long addr = iop310_cfg_address(bus, devfn, where);
150         u32 val;
151
152         if (size != 4) {
153                 val = iop310_pri_read(addr);
154                 if (!iop310_pri_pci_status() == 0)
155                         return PCIBIOS_SUCCESSFUL;
156
157                 where = (where & 3) * 8;
158
159                 if (size == 1)
160                         val &= ~(0xff << where);
161                 else
162                         val &= ~(0xffff << where);
163
164                 *IOP310_POCCDR = val | value << where;
165         } else {
166                 asm volatile(
167                         "str    %1, [%2]\n\t"
168                         "str    %0, [%3]\n\t"
169                         "nop\n\t"
170                         "nop\n\t"
171                         "nop\n\t"
172                         "nop\n\t"
173                         :
174                         : "r" (value), "r" (addr),
175                           "r" (IOP310_POCCAR), "r" (IOP310_POCCDR));
176         }
177
178         return PCIBIOS_SUCCESSFUL;
179 }
180
181 static struct pci_ops iop310_primary_ops = {
182         .read   = iop310_pri_read_config,
183         .write  = iop310_pri_write_config,
184 };
185
186 /*
187  * Secondary PCI interface support.
188  */
189 static int iop310_sec_pci_status(void)
190 {
191         unsigned int usr, uisr;
192         int ret = 0;
193
194         usr = *IOP310_SATUSR;
195         uisr = *IOP310_SATUISR;
196         if (usr & 0xf900) {
197                 *IOP310_SATUSR = usr & 0xf900;
198                 ret = 1;
199         }
200         if (uisr & 0x0000069f) {
201                 *IOP310_SATUISR = uisr & 0x0000069f;
202                 ret = 1;
203         }
204         if (ret)
205                 DBG("ERROR (%08x %08x)", usr, uisr);
206         return ret;
207 }
208
209 /*
210  * Simply write the address register and read the configuration
211  * data.  Note that the 4 nop's ensure that we are able to handle
212  * a delayed abort (in theory.)
213  */
214 static inline u32 iop310_sec_read(unsigned long addr)
215 {
216         u32 val;
217
218         __asm__ __volatile__(
219                 "str    %1, [%2]\n\t"
220                 "ldr    %0, [%3]\n\t"
221                 "nop\n\t"
222                 "nop\n\t"
223                 "nop\n\t"
224                 "nop\n\t"
225                 : "=r" (val)
226                 : "r" (addr), "r" (IOP310_SOCCAR), "r" (IOP310_SOCCDR));
227
228         return val;
229 }
230
231 static int
232 iop310_sec_read_config(struct pci_bus *bus, unsigned int devfn, int where,
233                        int size, u32 *value)
234 {
235         unsigned long addr = iop310_cfg_address(bus, devfn, where);
236         u32 val = iop310_sec_read(addr) >> ((where & 3) * 8);
237
238         if (iop310_sec_pci_status())
239                 val = 0xffffffff;
240
241         *value = val;
242
243         return PCIBIOS_SUCCESSFUL;
244 }
245
246 static int
247 iop310_sec_write_config(struct pci_bus *bus, unsigned int devfn, int where,
248                         int size, u32 value)
249 {
250         unsigned long addr = iop310_cfg_address(bus, devfn, where);
251         u32 val;
252
253         if (size != 4) {
254                 val = iop310_sec_read(addr);
255
256                 if (!iop310_sec_pci_status() == 0)
257                         return PCIBIOS_SUCCESSFUL;
258
259                 where = (where & 3) * 8;
260
261                 if (size == 1)
262                         val &= ~(0xff << where);
263                 else
264                         val &= ~(0xffff << where);
265
266                 *IOP310_SOCCDR = val | value << where;
267         } else {
268                 asm volatile(
269                         "str    %1, [%2]\n\t"
270                         "str    %0, [%3]\n\t"
271                         "nop\n\t"
272                         "nop\n\t"
273                         "nop\n\t"
274                         "nop\n\t"
275                         :
276                         : "r" (value), "r" (addr),
277                           "r" (IOP310_SOCCAR), "r" (IOP310_SOCCDR));
278         }
279
280         return PCIBIOS_SUCCESSFUL;
281 }
282
283 static struct pci_ops iop310_secondary_ops = {
284         .read   = iop310_sec_read_config,
285         .write  = iop310_sec_write_config,
286 };
287
288 /*
289  * When a PCI device does not exist during config cycles, the 80200 gets
290  * an external abort instead of returning 0xffffffff.  If it was an
291  * imprecise abort, we need to correct the return address to point after
292  * the instruction.  Also note that the Xscale manual says:
293  *
294  *  "if a stall-until-complete LD or ST instruction triggers an
295  *  imprecise fault, then that fault will be seen by the program
296  *  within 3 instructions."
297  *
298  * This does not appear to be the case.  With 8 NOPs after the load, we
299  * see the imprecise abort occurring on the STM of iop310_sec_pci_status()
300  * which is about 10 instructions away.
301  *
302  * Always trust reality!
303  */
304 static int
305 iop310_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
306 {
307         DBG("PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx\n",
308                 addr, fsr, regs->ARM_pc, regs->ARM_lr);
309
310         /*
311          * If it was an imprecise abort, then we need to correct the
312          * return address to be _after_ the instruction.
313          */
314         if (fsr & (1 << 10))
315                 regs->ARM_pc += 4;
316
317         return 0;
318 }
319
320 /*
321  * Scan an IOP310 PCI bus.  sys->bus defines which bus we scan.
322  */
323 struct pci_bus *iop310_scan_bus(int nr, struct pci_sys_data *sys)
324 {
325         struct pci_ops *ops;
326
327         if (nr)
328                 ops = &iop310_secondary_ops;
329         else
330                 ops = &iop310_primary_ops;
331
332         return pci_scan_bus(sys->busnr, ops, sys);
333 }
334
335 /*
336  * Setup the system data for controller 'nr'.   Return 0 if none found,
337  * 1 if found, or negative error.
338  *
339  * We can alter:
340  *  io_offset   - offset between IO resources and PCI bus BARs
341  *  mem_offset  - offset between mem resources and PCI bus BARs
342  *  resource[0] - parent IO resource
343  *  resource[1] - parent non-prefetchable memory resource
344  *  resource[2] - parent prefetchable memory resource
345  *  swizzle     - bridge swizzling function
346  *  map_irq     - irq mapping function
347  *
348  * Note that 'io_offset' and 'mem_offset' are left as zero since
349  * the IOP310 doesn't attempt to perform any address translation
350  * on accesses from the host to the bus.
351  */
352 int iop310_setup(int nr, struct pci_sys_data *sys)
353 {
354         struct resource *res;
355
356         if (nr >= 2)
357                 return 0;
358
359         res = kmalloc(sizeof(struct resource) * 2, GFP_KERNEL);
360         if (!res)
361                 panic("PCI: unable to alloc resources");
362
363         memset(res, 0, sizeof(struct resource) * 2);
364
365         switch (nr) {
366         case 0:
367                 res[0].start = IOP310_PCIPRI_LOWER_IO + 0x6e000000;
368                 res[0].end   = IOP310_PCIPRI_LOWER_IO + 0x6e00ffff;
369                 res[0].name  = "PCI IO Primary";
370                 res[0].flags = IORESOURCE_IO;
371
372                 res[1].start = IOP310_PCIPRI_LOWER_MEM;
373                 res[1].end   = IOP310_PCIPRI_LOWER_MEM + IOP310_PCI_WINDOW_SIZE;
374                 res[1].name  = "PCI Memory Primary";
375                 res[1].flags = IORESOURCE_MEM;
376                 break;
377
378         case 1:
379                 res[0].start = IOP310_PCISEC_LOWER_IO + 0x6e000000;
380                 res[0].end   = IOP310_PCISEC_LOWER_IO + 0x6e00ffff;
381                 res[0].name  = "PCI IO Secondary";
382                 res[0].flags = IORESOURCE_IO;
383
384                 res[1].start = IOP310_PCISEC_LOWER_MEM;
385                 res[1].end   = IOP310_PCISEC_LOWER_MEM + IOP310_PCI_WINDOW_SIZE;
386                 res[1].name  = "PCI Memory Secondary";
387                 res[1].flags = IORESOURCE_MEM;
388                 break;
389         }
390
391         request_resource(&ioport_resource, &res[0]);
392         request_resource(&iomem_resource, &res[1]);
393
394         sys->resource[0] = &res[0];
395         sys->resource[1] = &res[1];
396         sys->resource[2] = NULL;
397         sys->io_offset   = 0x6e000000;
398
399         return 1;
400 }
401
402 void iop310_init(void)
403 {
404         DBG("PCI:  Intel 80312 PCI-to-PCI init code.\n");
405         DBG("  ATU secondary: ATUCR =0x%08x\n", *IOP310_ATUCR);
406         DBG("  ATU secondary: SOMWVR=0x%08x  SOIOWVR=0x%08x\n",
407                 *IOP310_SOMWVR, *IOP310_SOIOWVR);
408         DBG("  ATU secondary: SIABAR=0x%08x  SIALR  =0x%08x SIATVR=%08x\n",
409                 *IOP310_SIABAR, *IOP310_SIALR, *IOP310_SIATVR);
410         DBG("  ATU primary:   POMWVR=0x%08x  POIOWVR=0x%08x\n",
411                 *IOP310_POMWVR, *IOP310_POIOWVR);
412         DBG("  ATU primary:   PIABAR=0x%08x  PIALR  =0x%08x PIATVR=%08x\n",
413                 *IOP310_PIABAR, *IOP310_PIALR, *IOP310_PIATVR);
414         DBG("  P2P: PCR=0x%04x BCR=0x%04x EBCR=0x%04x\n",
415                 *IOP310_PCR, *IOP310_BCR, *IOP310_EBCR);
416
417         /*
418          * Windows have to be carefully opened via a nice set of calls
419          * here or just some direct register fiddling in the board
420          * specific init when we want transactions to occur between the
421          * two PCI hoses.
422          *
423          * To do this, we will have manage RETRY assertion between the
424          * firmware and the kernel.  This will ensure that the host
425          * system's enumeration code is held off until we have tweaked
426          * the interrupt routing and public/private IDSELs.
427          *
428          * For now we will simply default to disabling the integrated type
429          * 81 P2P bridge.
430          */
431         *IOP310_PCR &= 0xfff8;
432
433         hook_fault_code(16+6, iop310_pci_abort, SIGBUS, "imprecise external abort");
434 }