Commit 3a71cfd5 authored by David Woodhouse's avatar David Woodhouse

Workaround for MPC826x PCI erratum #9.

parent e4bc3871
...@@ -1026,6 +1026,29 @@ config PCI_8260 ...@@ -1026,6 +1026,29 @@ config PCI_8260
depends on PCI && 8260 && !8272 depends on PCI && 8260 && !8272
default y default y
config 8260_PCI9
bool " Enable workaround for MPC826x erratum PCI 9"
depends on PCI_8260
default y
choice
prompt " IDMA channel for PCI 9 workaround"
depends on 8260_PCI9
config 8260_PCI9_IDMA1
bool "IDMA1"
config 8260_PCI9_IDMA2
bool "IDMA2"
config 8260_PCI9_IDMA3
bool "IDMA3"
config 8260_PCI9_IDMA4
bool "IDMA4"
endchoice
config PCI_PERMEDIA config PCI_PERMEDIA
bool "PCI for Permedia2" bool "PCI for Permedia2"
depends on !4xx && !8xx && APUS depends on !4xx && !8xx && APUS
......
...@@ -68,6 +68,7 @@ obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \ ...@@ -68,6 +68,7 @@ obj-$(CONFIG_SPRUCE) += cpc700_pic.o indirect_pci.o pci_auto.o \
todc_time.o todc_time.o
obj-$(CONFIG_8260) += m8260_setup.o cpm2_pic.o obj-$(CONFIG_8260) += m8260_setup.o cpm2_pic.o
obj-$(CONFIG_PCI_8260) += m8260_pci.o indirect_pci.o obj-$(CONFIG_PCI_8260) += m8260_pci.o indirect_pci.o
obj-$(CONFIG_8260_PCI9) += m8260_pci_erratum9.o
obj-$(CONFIG_CPM2) += cpm2_common.o obj-$(CONFIG_CPM2) += cpm2_common.o
ifeq ($(CONFIG_PPC_GEN550),y) ifeq ($(CONFIG_PPC_GEN550),y)
obj-$(CONFIG_KGDB) += gen550_kgdb.o gen550_dbg.o obj-$(CONFIG_KGDB) += gen550_kgdb.o gen550_dbg.o
......
...@@ -164,9 +164,9 @@ void __init m8260_find_bridges(void) ...@@ -164,9 +164,9 @@ void __init m8260_find_bridges(void)
hose->bus_offset = 0; hose->bus_offset = 0;
hose->last_busno = 0xff; hose->last_busno = 0xff;
setup_indirect_pci(hose, setup_m8260_indirect_pci(hose,
(unsigned long)&cpm2_immr->im_pci.pci_cfg_addr, (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
(unsigned long)&cpm2_immr->im_pci.pci_cfg_data); (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
m8260_setup_pci(hose); m8260_setup_pci(hose);
hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET; hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET;
......
...@@ -65,4 +65,11 @@ ...@@ -65,4 +65,11 @@
#define _IO_BASE isa_io_base #define _IO_BASE isa_io_base
#endif #endif
#ifdef CONFIG_8260_PCI9
extern void setup_m8260_indirect_pci(struct pci_controller* hose,
u32 cfg_addr, u32 cfg_data);
#else
#define setup_m8260_indirect_pci setup_indirect_pci
#endif
#endif /* _PPC_KERNEL_M8260_PCI_H */ #endif /* _PPC_KERNEL_M8260_PCI_H */
This diff is collapsed.
...@@ -54,6 +54,7 @@ unsigned char __res[sizeof(bd_t)]; ...@@ -54,6 +54,7 @@ unsigned char __res[sizeof(bd_t)];
extern void cpm2_reset(void); extern void cpm2_reset(void);
extern void m8260_find_bridges(void); extern void m8260_find_bridges(void);
extern void idma_pci9_init(void);
static void __init static void __init
m8260_setup_arch(void) m8260_setup_arch(void)
...@@ -61,6 +62,10 @@ m8260_setup_arch(void) ...@@ -61,6 +62,10 @@ m8260_setup_arch(void)
/* Reset the Communication Processor Module. /* Reset the Communication Processor Module.
*/ */
cpm2_reset(); cpm2_reset();
#ifdef CONFIG_8260_PCI9
/* Initialise IDMA for PCI erratum workaround */
idma_pci9_init();
#endif
#ifdef CONFIG_PCI_8260 #ifdef CONFIG_PCI_8260
m8260_find_bridges(); m8260_find_bridges();
#endif #endif
......
...@@ -138,18 +138,27 @@ extern __inline__ void name(unsigned int val, unsigned int port) \ ...@@ -138,18 +138,27 @@ extern __inline__ void name(unsigned int val, unsigned int port) \
: : "r" (val), "r" (port + _IO_BASE)); \ : : "r" (val), "r" (port + _IO_BASE)); \
} }
__do_in_asm(inb, "lbzx")
__do_out_asm(outb, "stbx") __do_out_asm(outb, "stbx")
#ifdef CONFIG_APUS #ifdef CONFIG_APUS
__do_in_asm(inb, "lbzx")
__do_in_asm(inw, "lhz%U1%X1") __do_in_asm(inw, "lhz%U1%X1")
__do_in_asm(inl, "lwz%U1%X1") __do_in_asm(inl, "lwz%U1%X1")
__do_out_asm(outl,"stw%U0%X0") __do_out_asm(outl,"stw%U0%X0")
__do_out_asm(outw, "sth%U0%X0") __do_out_asm(outw, "sth%U0%X0")
#elif defined (CONFIG_8260_PCI9)
/* in asm cannot be defined if PCI9 workaround is used */
#define inb(port) in_8((u8 *)((port)+_IO_BASE))
#define inw(port) in_le16((u16 *)((port)+_IO_BASE))
#define inl(port) in_le32((u32 *)((port)+_IO_BASE))
__do_out_asm(outw, "sthbrx")
__do_out_asm(outl, "stwbrx")
#else #else
__do_in_asm(inb, "lbzx")
__do_in_asm(inw, "lhbrx") __do_in_asm(inw, "lhbrx")
__do_in_asm(inl, "lwbrx") __do_in_asm(inl, "lwbrx")
__do_out_asm(outw, "sthbrx") __do_out_asm(outw, "sthbrx")
__do_out_asm(outl, "stwbrx") __do_out_asm(outl, "stwbrx")
#endif #endif
#define inb_p(port) inb((port)) #define inb_p(port) inb((port))
...@@ -389,4 +398,9 @@ static inline int isa_check_signature(unsigned long io_addr, ...@@ -389,4 +398,9 @@ static inline int isa_check_signature(unsigned long io_addr,
} }
#endif /* _PPC_IO_H */ #endif /* _PPC_IO_H */
#ifdef CONFIG_8260_PCI9
#include <asm/mpc8260_pci9.h>
#endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
/* include/asm-ppc/mpc8260_pci9.h
*
* Undefine the PCI read* and in* macros so we can define them as functions
* that implement the workaround for the MPC8260 device erratum PCI 9.
*
* This header file should only be included at the end of include/asm-ppc/io.h
* and never included directly anywhere else.
*
* Author: andy_lowe@mvista.com
*
* 2003 (c) MontaVista Software, Inc. This file is licensed under
* the terms of the GNU General Public License version 2. This program
* is licensed "as is" without any warranty of any kind, whether express
* or implied.
*/
#ifndef _PPC_IO_H
#error "Do not include mpc8260_pci9.h directly."
#endif
#ifdef __KERNEL__
#ifndef __CONFIG_8260_PCI9_DEFS
#define __CONFIG_8260_PCI9_DEFS
#undef readb
#undef readw
#undef readl
#undef insb
#undef insw
#undef insl
#undef inb
#undef inw
#undef inl
#undef insw_ns
#undef insl_ns
#undef memcpy_fromio
extern int readb(volatile unsigned char *addr);
extern int readw(volatile unsigned short *addr);
extern unsigned readl(volatile unsigned *addr);
extern void insb(unsigned port, void *buf, int ns);
extern void insw(unsigned port, void *buf, int ns);
extern void insl(unsigned port, void *buf, int nl);
extern int inb(unsigned port);
extern int inw(unsigned port);
extern unsigned inl(unsigned port);
extern void insw_ns(unsigned port, void *buf, int ns);
extern void insl_ns(unsigned port, void *buf, int nl);
extern void *memcpy_fromio(void *dest, unsigned long src, size_t count);
#endif /* !__CONFIG_8260_PCI9_DEFS */
#endif /* __KERNEL__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment