2 * arch/ppc/platforms/mpc8260_pci9.c
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.
12 * Author: andy_lowe@mvista.com
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
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>
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>
34 #include "m8260_pci.h"
36 #ifdef CONFIG_8260_PCI9
37 /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */
39 #define IDMA_XFER_BUF_SIZE 64 /* size of the IDMA transfer buffer */
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 */
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)
53 static volatile idma_dpram_t *idma_dpram;
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.
59 #ifdef CONFIG_8260_PCI9_IDMA1
61 #define PROFF_IDMA PROFF_IDMA1_BASE
62 #define IDMA_PAGE CPM_CR_IDMA1_PAGE
63 #define IDMA_SBLOCK CPM_CR_IDMA1_SBLOCK
65 #ifdef CONFIG_8260_PCI9_IDMA2
67 #define PROFF_IDMA PROFF_IDMA2_BASE
68 #define IDMA_PAGE CPM_CR_IDMA2_PAGE
69 #define IDMA_SBLOCK CPM_CR_IDMA2_SBLOCK
71 #ifdef CONFIG_8260_PCI9_IDMA3
73 #define PROFF_IDMA PROFF_IDMA3_BASE
74 #define IDMA_PAGE CPM_CR_IDMA3_PAGE
75 #define IDMA_SBLOCK CPM_CR_IDMA3_SBLOCK
77 #ifdef CONFIG_8260_PCI9_IDMA4
79 #define PROFF_IDMA PROFF_IDMA4_BASE
80 #define IDMA_PAGE CPM_CR_IDMA4_PAGE
81 #define IDMA_SBLOCK CPM_CR_IDMA4_SBLOCK
84 void idma_pci9_init(void)
87 volatile idma_t *pram;
88 volatile im_idma_t *idma_reg;
89 volatile cpm2_map_t *immap = cpm2_immr;
91 /* allocate IDMA dpram */
92 dpram_offset = cpm2_dpalloc(sizeof(idma_dpram_t), 64);
94 (volatile idma_dpram_t *)&immap->im_dprambase[dpram_offset];
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;
104 /* initialize the IDMA_BASE pointer to the IDMA parameter RAM */
105 *((ushort *) &immap->im_dprambase[PROFF_IDMA]) = dpram_offset;
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 */
112 printk("<4>Using IDMA%d for MPC8260 device erratum PCI 9 workaround\n",
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
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.
129 idma_pci9_read(u8 *dst, u8 *src, int bytes, int unit_size, int sinc)
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;
136 local_irq_save(flags);
138 /* initialize IDMA parameter RAM for this transfer */
140 pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC
141 | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM;
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;
149 /* initialize the buffer descriptor */
150 bd->dst = virt_to_phys(dst);
151 bd->src = (uint) src;
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;
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);
162 /* wait for transfer to complete */
163 while(bd->flags & IDMA_BD_V);
165 local_irq_restore(flags);
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
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.
181 idma_pci9_write(u8 *dst, u8 *src, int bytes, int unit_size, int dinc)
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;
188 local_irq_save(flags);
190 /* initialize IDMA parameter RAM for this transfer */
192 pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC
193 | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM;
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;
201 /* initialize the buffer descriptor */
202 bd->dst = (uint) dst;
203 bd->src = virt_to_phys(src);
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;
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);
214 /* wait for transfer to complete */
215 while(bd->flags & IDMA_BD_V);
217 local_irq_restore(flags);
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.
227 idma_pci9_read_le(u8 *dst, u8 *src, int bytes, int unit_size, int sinc)
232 idma_pci9_read(dst, src, bytes, unit_size, sinc);
235 for (i = 0, p = dst; i < bytes; i += 2, p += 2)
239 for (i = 0, p = dst; i < bytes; i += 4, p += 4)
246 EXPORT_SYMBOL(idma_pci9_init);
247 EXPORT_SYMBOL(idma_pci9_read);
248 EXPORT_SYMBOL(idma_pci9_read_le);
250 static inline int is_pci_mem(unsigned long addr)
252 if (addr >= MPC826x_PCI_LOWER_MMIO &&
253 addr <= MPC826x_PCI_UPPER_MMIO)
255 if (addr >= MPC826x_PCI_LOWER_MEM &&
256 addr <= MPC826x_PCI_UPPER_MEM)
261 #define is_pci_mem(pa) ( (pa > 0x80000000) && (pa < 0xc0000000))
262 int readb(volatile unsigned char *addr)
265 unsigned long pa = iopa((unsigned long) addr);
270 idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
274 int readw(volatile unsigned short *addr)
277 unsigned long pa = iopa((unsigned long) addr);
280 return in_le16(addr);
282 idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
286 unsigned readl(volatile unsigned *addr)
289 unsigned long pa = iopa((unsigned long) addr);
292 return in_le32(addr);
294 idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
298 int inb(unsigned port)
301 u8 *addr = (u8 *)(port + _IO_BASE);
303 idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
307 int inw(unsigned port)
310 u8 *addr = (u8 *)(port + _IO_BASE);
312 idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
316 unsigned inl(unsigned port)
319 u8 *addr = (u8 *)(port + _IO_BASE);
321 idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
325 void insb(unsigned port, void *buf, int ns)
327 u8 *addr = (u8 *)(port + _IO_BASE);
329 idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u8), sizeof(u8), 0);
332 void insw(unsigned port, void *buf, int ns)
334 u8 *addr = (u8 *)(port + _IO_BASE);
336 idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0);
339 void insl(unsigned port, void *buf, int nl)
341 u8 *addr = (u8 *)(port + _IO_BASE);
343 idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
346 void insw_ns(unsigned port, void *buf, int ns)
348 u8 *addr = (u8 *)(port + _IO_BASE);
350 idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0);
353 void insl_ns(unsigned port, void *buf, int nl)
355 u8 *addr = (u8 *)(port + _IO_BASE);
357 idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
360 void *memcpy_fromio(void *dest, unsigned long src, size_t count)
362 unsigned long pa = iopa((unsigned long) src);
365 idma_pci9_read((u8 *)dest, (u8 *)pa, count, 32, 1);
367 memcpy(dest, (void *)src, count);
371 EXPORT_SYMBOL(readb);
372 EXPORT_SYMBOL(readw);
373 EXPORT_SYMBOL(readl);
380 EXPORT_SYMBOL(insw_ns);
381 EXPORT_SYMBOL(insl_ns);
382 EXPORT_SYMBOL(memcpy_fromio);
384 #endif /* ifdef CONFIG_8260_PCI9 */
386 /* Indirect PCI routines adapted from arch/ppc/kernel/indirect_pci.c.
387 * Copyright (C) 1998 Gabriel Paubert.
389 #ifndef CONFIG_8260_PCI9
390 #define cfg_read(val, addr, type, op) *val = op((type)(addr))
392 #define cfg_read(val, addr, type, op) \
393 idma_pci9_read_le((u8*)(val),(u8*)(addr),sizeof(*(val)),sizeof(*(val)),0)
396 #define cfg_write(val, addr, type, op) op((type *)(addr), (val))
398 static int indirect_write_config(struct pci_bus *pbus, unsigned int devfn, int where,
401 struct pci_controller *hose = pbus->sysdata;
403 if (ppc_md.pci_exclude_device)
404 if (ppc_md.pci_exclude_device(pbus->number, devfn))
405 return PCIBIOS_DEVICE_NOT_FOUND;
407 if (hose->set_cfg_type)
408 if (pbus->number != hose->first_busno)
411 out_be32(hose->cfg_addr,
412 (((where & 0xfc) | cfg_type) << 24) | (devfn << 16)
413 | ((pbus->number - hose->bus_offset) << 8) | 0x80);
418 cfg_write(value, hose->cfg_data + (where & 3), u8, out_8);
421 cfg_write(value, hose->cfg_data + (where & 2), u16, out_le16);
424 cfg_write(value, hose->cfg_data + (where & 0), u32, out_le32);
427 return PCIBIOS_SUCCESSFUL;
430 static int indirect_read_config(struct pci_bus *pbus, unsigned int devfn, int where,
431 int size, u32 *value)
433 struct pci_controller *hose = pbus->sysdata;
435 if (ppc_md.pci_exclude_device)
436 if (ppc_md.pci_exclude_device(pbus->number, devfn))
437 return PCIBIOS_DEVICE_NOT_FOUND;
439 if (hose->set_cfg_type)
440 if (pbus->number != hose->first_busno)
443 out_be32(hose->cfg_addr,
444 (((where & 0xfc) | cfg_type) << 24) | (devfn << 16)
445 | ((pbus->number - hose->bus_offset) << 8) | 0x80);
450 cfg_read(value, hose->cfg_data + (where & 3), u8 *, in_8);
453 cfg_read(value, hose->cfg_data + (where & 2), u16 *, in_le16);
456 cfg_read(value, hose->cfg_data + (where & 0), u32 *, in_le32);
459 return PCIBIOS_SUCCESSFUL;
462 static struct pci_ops indirect_pci_ops =
464 .read = indirect_read_config,
465 .write = indirect_write_config,
469 setup_m8260_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
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);