Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / ppc / syslib / m8260_pci_erratum9.c
1 /*
2  * Workaround for device erratum PCI 9.
3  * See Motorola's "XPC826xA Family Device Errata Reference."
4  * The erratum applies to all 8260 family Hip4 processors.  It is scheduled 
5  * to be fixed in HiP4 Rev C.  Erratum PCI 9 states that a simultaneous PCI 
6  * inbound write transaction and PCI outbound read transaction can result in a 
7  * bus deadlock.  The suggested workaround is to use the IDMA controller to 
8  * perform all reads from PCI configuration, memory, and I/O space.
9  *
10  * Author:  andy_lowe@mvista.com
11  *
12  * 2003 (c) MontaVista Software, Inc. This file is licensed under
13  * the terms of the GNU General Public License version 2. This program
14  * is licensed "as is" without any warranty of any kind, whether express
15  * or implied.
16  */
17 #include <linux/kernel.h>
18 #include <linux/config.h>
19 #include <linux/module.h>
20 #include <linux/pci.h>
21 #include <linux/types.h>
22 #include <linux/string.h>
23
24 #include <asm/io.h>
25 #include <asm/pci-bridge.h>
26 #include <asm/machdep.h>
27 #include <asm/byteorder.h>
28 #include <asm/mpc8260.h>
29 #include <asm/immap_cpm2.h>
30 #include <asm/cpm2.h>
31
32 #include "m82xx_pci.h"
33
34 #ifdef CONFIG_8260_PCI9
35 /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */
36
37 #define IDMA_XFER_BUF_SIZE 64   /* size of the IDMA transfer buffer */
38
39 /* define a structure for the IDMA dpram usage */
40 typedef struct idma_dpram_s {
41         idma_t pram;                            /* IDMA parameter RAM */
42         u_char xfer_buf[IDMA_XFER_BUF_SIZE];    /* IDMA transfer buffer */
43         idma_bd_t bd;                           /* buffer descriptor */
44 } idma_dpram_t;
45
46 /* define offsets relative to start of IDMA dpram */
47 #define IDMA_XFER_BUF_OFFSET (sizeof(idma_t))
48 #define IDMA_BD_OFFSET (sizeof(idma_t) + IDMA_XFER_BUF_SIZE)
49
50 /* define globals */
51 static volatile idma_dpram_t *idma_dpram;
52
53 /* Exactly one of CONFIG_8260_PCI9_IDMAn must be defined, 
54  * where n is 1, 2, 3, or 4.  This selects the IDMA channel used for 
55  * the PCI9 workaround.
56  */
57 #ifdef CONFIG_8260_PCI9_IDMA1
58 #define IDMA_CHAN 0
59 #define PROFF_IDMA PROFF_IDMA1_BASE
60 #define IDMA_PAGE CPM_CR_IDMA1_PAGE
61 #define IDMA_SBLOCK CPM_CR_IDMA1_SBLOCK
62 #endif
63 #ifdef CONFIG_8260_PCI9_IDMA2
64 #define IDMA_CHAN 1
65 #define PROFF_IDMA PROFF_IDMA2_BASE
66 #define IDMA_PAGE CPM_CR_IDMA2_PAGE
67 #define IDMA_SBLOCK CPM_CR_IDMA2_SBLOCK
68 #endif
69 #ifdef CONFIG_8260_PCI9_IDMA3
70 #define IDMA_CHAN 2
71 #define PROFF_IDMA PROFF_IDMA3_BASE
72 #define IDMA_PAGE CPM_CR_IDMA3_PAGE
73 #define IDMA_SBLOCK CPM_CR_IDMA3_SBLOCK
74 #endif
75 #ifdef CONFIG_8260_PCI9_IDMA4
76 #define IDMA_CHAN 3
77 #define PROFF_IDMA PROFF_IDMA4_BASE
78 #define IDMA_PAGE CPM_CR_IDMA4_PAGE
79 #define IDMA_SBLOCK CPM_CR_IDMA4_SBLOCK
80 #endif
81
82 void idma_pci9_init(void)
83 {
84         uint dpram_offset;
85         volatile idma_t *pram;
86         volatile im_idma_t *idma_reg;
87         volatile cpm2_map_t *immap = cpm2_immr;
88
89         /* allocate IDMA dpram */
90         dpram_offset = cpm_dpalloc(sizeof(idma_dpram_t), 64);
91         idma_dpram = cpm_dpram_addr(dpram_offset); 
92
93         /* initialize the IDMA parameter RAM */
94         memset((void *)idma_dpram, 0, sizeof(idma_dpram_t));
95         pram = &idma_dpram->pram;
96         pram->ibase = dpram_offset + IDMA_BD_OFFSET;
97         pram->dpr_buf = dpram_offset + IDMA_XFER_BUF_OFFSET;
98         pram->ss_max = 32;
99         pram->dts = 32;
100
101         /* initialize the IDMA_BASE pointer to the IDMA parameter RAM */
102         *((ushort *) &immap->im_dprambase[PROFF_IDMA]) = dpram_offset;
103
104         /* initialize the IDMA registers */
105         idma_reg = (volatile im_idma_t *) &immap->im_sdma.sdma_idsr1;
106         idma_reg[IDMA_CHAN].idmr = 0;           /* mask all IDMA interrupts */
107         idma_reg[IDMA_CHAN].idsr = 0xff;        /* clear all event flags */
108
109         printk("<4>Using IDMA%d for MPC8260 device erratum PCI 9 workaround\n",
110                 IDMA_CHAN + 1);
111
112         return;
113 }
114
115 /* Use the IDMA controller to transfer data from I/O memory to local RAM.
116  * The src address must be a physical address suitable for use by the DMA 
117  * controller with no translation.  The dst address must be a kernel virtual 
118  * address.  The dst address is translated to a physical address via 
119  * virt_to_phys().
120  * The sinc argument specifies whether or not the source address is incremented
121  * by the DMA controller.  The source address is incremented if and only if sinc
122  * is non-zero.  The destination address is always incremented since the 
123  * destination is always host RAM.
124  */
125 static void 
126 idma_pci9_read(u8 *dst, u8 *src, int bytes, int unit_size, int sinc)
127 {
128         unsigned long flags;
129         volatile idma_t *pram = &idma_dpram->pram;
130         volatile idma_bd_t *bd = &idma_dpram->bd;
131         volatile cpm2_map_t *immap = cpm2_immr;
132
133         local_irq_save(flags);
134
135         /* initialize IDMA parameter RAM for this transfer */
136         if (sinc)
137                 pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC
138                           | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM;
139         else
140                 pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_DINC 
141                           | IDMA_DCM_SD_MEM2MEM;
142         pram->ibdptr = pram->ibase;
143         pram->sts = unit_size;
144         pram->istate = 0;
145
146         /* initialize the buffer descriptor */
147         bd->dst = virt_to_phys(dst);
148         bd->src = (uint) src;
149         bd->len = bytes;
150         bd->flags = IDMA_BD_V | IDMA_BD_W | IDMA_BD_I | IDMA_BD_L | IDMA_BD_DGBL
151                   | IDMA_BD_DBO_BE | IDMA_BD_SBO_BE | IDMA_BD_SDTB;
152
153         /* issue the START_IDMA command to the CP */
154         while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
155         immap->im_cpm.cp_cpcr = mk_cr_cmd(IDMA_PAGE, IDMA_SBLOCK, 0,
156                                          CPM_CR_START_IDMA) | CPM_CR_FLG;
157         while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
158
159         /* wait for transfer to complete */
160         while(bd->flags & IDMA_BD_V);
161
162         local_irq_restore(flags);
163
164         return;
165 }
166
167 /* Use the IDMA controller to transfer data from I/O memory to local RAM.
168  * The dst address must be a physical address suitable for use by the DMA 
169  * controller with no translation.  The src address must be a kernel virtual 
170  * address.  The src address is translated to a physical address via 
171  * virt_to_phys().
172  * The dinc argument specifies whether or not the dest address is incremented
173  * by the DMA controller.  The source address is incremented if and only if sinc
174  * is non-zero.  The source address is always incremented since the 
175  * source is always host RAM.
176  */
177 static void 
178 idma_pci9_write(u8 *dst, u8 *src, int bytes, int unit_size, int dinc)
179 {
180         unsigned long flags;
181         volatile idma_t *pram = &idma_dpram->pram;
182         volatile idma_bd_t *bd = &idma_dpram->bd;
183         volatile cpm2_map_t *immap = cpm2_immr;
184
185         local_irq_save(flags);
186
187         /* initialize IDMA parameter RAM for this transfer */
188         if (dinc)
189                 pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC
190                           | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM;
191         else
192                 pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC 
193                           | IDMA_DCM_SD_MEM2MEM;
194         pram->ibdptr = pram->ibase;
195         pram->sts = unit_size;
196         pram->istate = 0;
197
198         /* initialize the buffer descriptor */
199         bd->dst = (uint) dst;
200         bd->src = virt_to_phys(src);
201         bd->len = bytes;
202         bd->flags = IDMA_BD_V | IDMA_BD_W | IDMA_BD_I | IDMA_BD_L | IDMA_BD_DGBL
203                   | IDMA_BD_DBO_BE | IDMA_BD_SBO_BE | IDMA_BD_SDTB;
204
205         /* issue the START_IDMA command to the CP */
206         while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
207         immap->im_cpm.cp_cpcr = mk_cr_cmd(IDMA_PAGE, IDMA_SBLOCK, 0,
208                                          CPM_CR_START_IDMA) | CPM_CR_FLG;
209         while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
210
211         /* wait for transfer to complete */
212         while(bd->flags & IDMA_BD_V);
213
214         local_irq_restore(flags);
215
216         return;
217 }
218
219 /* Same as idma_pci9_read, but 16-bit little-endian byte swapping is performed
220  * if the unit_size is 2, and 32-bit little-endian byte swapping is performed if
221  * the unit_size is 4.
222  */
223 static void 
224 idma_pci9_read_le(u8 *dst, u8 *src, int bytes, int unit_size, int sinc)
225 {
226         int i;
227         u8 *p;
228
229         idma_pci9_read(dst, src, bytes, unit_size, sinc);
230         switch(unit_size) {
231                 case 2:
232                         for (i = 0, p = dst; i < bytes; i += 2, p += 2)
233                                 swab16s((u16 *) p);
234                         break;
235                 case 4:
236                         for (i = 0, p = dst; i < bytes; i += 4, p += 4)
237                                 swab32s((u32 *) p);
238                         break;
239                 default:
240                         break;
241         }
242 }
243 EXPORT_SYMBOL(idma_pci9_init);
244 EXPORT_SYMBOL(idma_pci9_read);
245 EXPORT_SYMBOL(idma_pci9_read_le);
246
247 static inline int is_pci_mem(unsigned long addr)
248 {
249         if (addr >= M82xx_PCI_LOWER_MMIO &&
250                 addr <= M82xx_PCI_UPPER_MMIO)
251                 return 1;
252         if (addr >= M82xx_PCI_LOWER_MEM &&
253                 addr <= M82xx_PCI_UPPER_MEM)
254                 return 1;
255         return 0;
256 }
257
258 #define is_pci_mem(pa) ( (pa > 0x80000000) && (pa < 0xc0000000))
259 int readb(volatile unsigned char *addr)
260 {
261         u8 val;
262         unsigned long pa = iopa((unsigned long) addr);
263
264         if (!is_pci_mem(pa))
265                 return in_8(addr);
266
267         idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
268         return val;
269 }
270
271 int readw(volatile unsigned short *addr)
272 {
273         u16 val;
274         unsigned long pa = iopa((unsigned long) addr);
275
276         if (!is_pci_mem(pa))
277                 return in_le16(addr);
278
279         idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
280         return swab16(val);
281 }
282
283 unsigned readl(volatile unsigned *addr)
284 {
285         u32 val;
286         unsigned long pa = iopa((unsigned long) addr);
287
288         if (!is_pci_mem(pa))
289                 return in_le32(addr);
290
291         idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
292         return swab32(val);
293 }
294
295 int inb(unsigned port)
296 {
297         u8 val;
298         u8 *addr = (u8 *)(port + _IO_BASE);
299
300         idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
301         return val;
302 }
303
304 int inw(unsigned port)
305 {
306         u16 val;
307         u8 *addr = (u8 *)(port + _IO_BASE);
308
309         idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
310         return swab16(val);
311 }
312
313 unsigned inl(unsigned port)
314 {
315         u32 val;
316         u8 *addr = (u8 *)(port + _IO_BASE);
317
318         idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
319         return swab32(val);
320 }
321
322 void insb(unsigned port, void *buf, int ns)
323 {
324         u8 *addr = (u8 *)(port + _IO_BASE);
325
326         idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u8), sizeof(u8), 0);
327 }
328
329 void insw(unsigned port, void *buf, int ns)
330 {
331         u8 *addr = (u8 *)(port + _IO_BASE);
332
333         idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0);
334 }
335
336 void insl(unsigned port, void *buf, int nl)
337 {
338         u8 *addr = (u8 *)(port + _IO_BASE);
339
340         idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
341 }
342
343 void insw_ns(unsigned port, void *buf, int ns)
344 {
345         u8 *addr = (u8 *)(port + _IO_BASE);
346
347         idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0);
348 }
349
350 void insl_ns(unsigned port, void *buf, int nl)
351 {
352         u8 *addr = (u8 *)(port + _IO_BASE);
353
354         idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
355 }
356
357 void *memcpy_fromio(void *dest, unsigned long src, size_t count)
358 {
359         unsigned long pa = iopa((unsigned long) src);
360
361         if (is_pci_mem(pa))
362                 idma_pci9_read((u8 *)dest, (u8 *)pa, count, 32, 1);
363         else
364                 memcpy(dest, (void *)src, count);
365         return dest;
366 }
367
368 EXPORT_SYMBOL(readb);
369 EXPORT_SYMBOL(readw);
370 EXPORT_SYMBOL(readl);
371 EXPORT_SYMBOL(inb);
372 EXPORT_SYMBOL(inw);
373 EXPORT_SYMBOL(inl);
374 EXPORT_SYMBOL(insb);
375 EXPORT_SYMBOL(insw);
376 EXPORT_SYMBOL(insl);
377 EXPORT_SYMBOL(insw_ns);
378 EXPORT_SYMBOL(insl_ns);
379 EXPORT_SYMBOL(memcpy_fromio);
380
381 #endif  /* ifdef CONFIG_8260_PCI9 */
382
383 /* Indirect PCI routines adapted from arch/ppc/kernel/indirect_pci.c.
384  * Copyright (C) 1998 Gabriel Paubert.
385  */
386 #ifndef CONFIG_8260_PCI9
387 #define cfg_read(val, addr, type, op)   *val = op((type)(addr))
388 #else
389 #define cfg_read(val, addr, type, op) \
390         idma_pci9_read_le((u8*)(val),(u8*)(addr),sizeof(*(val)),sizeof(*(val)),0)
391 #endif
392
393 #define cfg_write(val, addr, type, op)  op((type *)(addr), (val))
394
395 static int indirect_write_config(struct pci_bus *pbus, unsigned int devfn, int where,
396                          int size, u32 value)
397 {
398         struct pci_controller *hose = pbus->sysdata;
399         u8 cfg_type = 0;
400         if (ppc_md.pci_exclude_device)
401                 if (ppc_md.pci_exclude_device(pbus->number, devfn))
402                         return PCIBIOS_DEVICE_NOT_FOUND;
403
404         if (hose->set_cfg_type)
405                 if (pbus->number != hose->first_busno)
406                         cfg_type = 1;
407
408         out_be32(hose->cfg_addr,
409                  (((where & 0xfc) | cfg_type) << 24) | (devfn << 16)
410                  | ((pbus->number - hose->bus_offset) << 8) | 0x80);
411
412         switch (size)
413         {
414                 case 1:
415                         cfg_write(value, hose->cfg_data + (where & 3), u8, out_8);
416                         break;
417                 case 2:
418                         cfg_write(value, hose->cfg_data + (where & 2), u16, out_le16);
419                         break;
420                 case 4:
421                         cfg_write(value, hose->cfg_data + (where & 0), u32, out_le32);
422                         break;
423         }               
424         return PCIBIOS_SUCCESSFUL;
425 }
426
427 static int indirect_read_config(struct pci_bus *pbus, unsigned int devfn, int where,
428                          int size, u32 *value)
429 {
430         struct pci_controller *hose = pbus->sysdata;
431         u8 cfg_type = 0;
432         if (ppc_md.pci_exclude_device)
433                 if (ppc_md.pci_exclude_device(pbus->number, devfn))
434                         return PCIBIOS_DEVICE_NOT_FOUND;
435
436         if (hose->set_cfg_type)
437                 if (pbus->number != hose->first_busno)
438                         cfg_type = 1;
439
440         out_be32(hose->cfg_addr,
441                  (((where & 0xfc) | cfg_type) << 24) | (devfn << 16)
442                  | ((pbus->number - hose->bus_offset) << 8) | 0x80);
443
444         switch (size)
445         {
446                 case 1:
447                         cfg_read(value, hose->cfg_data + (where & 3), u8 *, in_8);
448                         break;
449                 case 2:
450                         cfg_read(value, hose->cfg_data + (where & 2), u16 *, in_le16);
451                         break;
452                 case 4:
453                         cfg_read(value, hose->cfg_data + (where & 0), u32 *, in_le32);
454                         break;
455         }               
456         return PCIBIOS_SUCCESSFUL;
457 }
458
459 static struct pci_ops indirect_pci_ops =
460 {
461         .read = indirect_read_config,
462         .write = indirect_write_config,
463 };
464
465 void
466 setup_m8260_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
467 {
468         hose->ops = &indirect_pci_ops;
469         hose->cfg_addr = (unsigned int *) ioremap(cfg_addr, 4);
470         hose->cfg_data = (unsigned char *) ioremap(cfg_data, 4);
471 }