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