From 321ab6a5fab812658626aee6bce2617f8cfb3a55 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sat, 25 Jun 2005 19:30:04 +0100 Subject: [PATCH] ARM: 2752/1: disable ixp2000 PCI I/O software workaround on chips that don't need it Patch from Lennert Buytenhek The later ixp2000 models don't need the PCI I/O workaround that we currently perform. Add a config option to disable the workaround, and panic on boot if a kernel without the workaround is booted on a buggy chip. As only pre-production ixp2000s need the workaround, the default is for it not to be configured in. Signed-off-by: Lennert Buytenhek Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/configs/enp2611_defconfig | 1 + arch/arm/configs/ixdp2400_defconfig | 1 + arch/arm/configs/ixdp2401_defconfig | 1 + arch/arm/configs/ixdp2800_defconfig | 1 + arch/arm/configs/ixdp2801_defconfig | 1 + arch/arm/mach-ixp2000/Kconfig | 8 ++++++++ arch/arm/mach-ixp2000/pci.c | 13 +++++++++++++ include/asm-arm/arch-ixp2000/io.h | 20 ++++++++++++++------ include/asm-arm/arch-ixp2000/ixp2000-regs.h | 2 +- 9 files changed, 41 insertions(+), 7 deletions(-) diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig index af21534245606..b8c51ee7f1bb0 100644 --- a/arch/arm/configs/enp2611_defconfig +++ b/arch/arm/configs/enp2611_defconfig @@ -99,6 +99,7 @@ CONFIG_ARCH_ENP2611=y # CONFIG_ARCH_IXDP2800 is not set # CONFIG_ARCH_IXDP2401 is not set # CONFIG_ARCH_IXDP2801 is not set +# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set # # Processor Type diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig index a7ee1a442f349..3cfbe2ec29ca6 100644 --- a/arch/arm/configs/ixdp2400_defconfig +++ b/arch/arm/configs/ixdp2400_defconfig @@ -100,6 +100,7 @@ CONFIG_ARCH_IXDP2400=y CONFIG_ARCH_IXDP2X00=y # CONFIG_ARCH_IXDP2401 is not set # CONFIG_ARCH_IXDP2801 is not set +# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set # # Processor Type diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig index 2da48fca5c1c1..5c87e8e6969b1 100644 --- a/arch/arm/configs/ixdp2401_defconfig +++ b/arch/arm/configs/ixdp2401_defconfig @@ -100,6 +100,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y CONFIG_ARCH_IXDP2401=y # CONFIG_ARCH_IXDP2801 is not set CONFIG_ARCH_IXDP2X01=y +# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set # # Processor Type diff --git a/arch/arm/configs/ixdp2800_defconfig b/arch/arm/configs/ixdp2800_defconfig index 7ba867f751fd3..3cb561a551cb5 100644 --- a/arch/arm/configs/ixdp2800_defconfig +++ b/arch/arm/configs/ixdp2800_defconfig @@ -100,6 +100,7 @@ CONFIG_ARCH_IXDP2800=y CONFIG_ARCH_IXDP2X00=y # CONFIG_ARCH_IXDP2401 is not set # CONFIG_ARCH_IXDP2801 is not set +# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set # # Processor Type diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig index c4df0ec34b085..b1e162f29cb94 100644 --- a/arch/arm/configs/ixdp2801_defconfig +++ b/arch/arm/configs/ixdp2801_defconfig @@ -100,6 +100,7 @@ CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y # CONFIG_ARCH_IXDP2401 is not set CONFIG_ARCH_IXDP2801=y CONFIG_ARCH_IXDP2X01=y +# CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set # # Processor Type diff --git a/arch/arm/mach-ixp2000/Kconfig b/arch/arm/mach-ixp2000/Kconfig index 9361e05f6fa39..ecb58d83478e3 100644 --- a/arch/arm/mach-ixp2000/Kconfig +++ b/arch/arm/mach-ixp2000/Kconfig @@ -54,6 +54,14 @@ config ARCH_IXDP2X01 depends on ARCH_IXDP2401 || ARCH_IXDP2801 default y +config IXP2000_SUPPORT_BROKEN_PCI_IO + bool "Support broken PCI I/O on older IXP2000s" + default y + help + Say 'N' here if you only intend to run your kernel on an + IXP2000 B0 or later model and do not need the PCI I/O + byteswap workaround. Say 'Y' otherwise. + endmenu endif diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index 5ff2f2718c58c..0788fb2b5c10e 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c @@ -198,6 +198,19 @@ clear_master_aborts(void) void __init ixp2000_pci_preinit(void) { +#ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO + /* + * Configure the PCI unit to properly byteswap I/O transactions, + * and verify that it worked. + */ + ixp2000_reg_write(IXP2000_PCI_CONTROL, + (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE)); + + if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0) + panic("IXP2000: PCI I/O is broken on this ixp model, and " + "the needed workaround has not been configured in"); +#endif + hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, "PCI config cycle to non-existent device"); } diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h index 5e56b47446e0c..3241cd6f0778e 100644 --- a/include/asm-arm/arch-ixp2000/io.h +++ b/include/asm-arm/arch-ixp2000/io.h @@ -17,16 +17,21 @@ #define IO_SPACE_LIMIT 0xffffffff #define __mem_pci(a) (a) -#define ___io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE)) /* - * The IXP2400 before revision B0 asserts byte lanes for PCI I/O + * The A? revisions of the IXP2000s assert byte lanes for PCI I/O * transactions the other way round (MEM transactions don't have this - * issue), so we need to override the standard functions. B0 and later - * have a bit that can be set to 1 to get the 'proper' behavior, but - * since that isn't available on the A? revisions we just keep doing - * things manually. + * issue), so if we want to support those models, we need to override + * the standard I/O functions. + * + * B0 and later have a bit that can be set to 1 to get the proper + * behavior for I/O transactions, which then allows us to use the + * standard I/O functions. This is what we do if the user does not + * explicitly ask for support for pre-B0. */ +#ifdef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO +#define ___io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE)) + #define alignb(addr) (void __iomem *)((unsigned long)(addr) ^ 3) #define alignw(addr) (void __iomem *)((unsigned long)(addr) ^ 2) @@ -119,6 +124,9 @@ #define ioport_map(port, nr) ___io(port) #define ioport_unmap(addr) +#else +#define __io(p) ((void __iomem *)((p)+IXP2000_PCI_IO_VIRT_BASE)) +#endif #ifdef CONFIG_ARCH_IXDP2X01 diff --git a/include/asm-arm/arch-ixp2000/ixp2000-regs.h b/include/asm-arm/arch-ixp2000/ixp2000-regs.h index a1d9e181b10f1..5eb47d4bfbf63 100644 --- a/include/asm-arm/arch-ixp2000/ixp2000-regs.h +++ b/include/asm-arm/arch-ixp2000/ixp2000-regs.h @@ -241,7 +241,7 @@ #define PCI_CONTROL_BE_DEI (1 << 21) /* Big Endian Data Enable In */ #define PCI_CONTROL_BE_BEO (1 << 20) /* Big Endian Byte Enable Out */ #define PCI_CONTROL_BE_BEI (1 << 19) /* Big Endian Byte Enable In */ -#define PCI_CONTROL_PNR (1 << 17) /* PCI Not Reset bit */ +#define PCI_CONTROL_IEE (1 << 17) /* I/O cycle Endian swap Enable */ #define IXP2000_PCI_RST_REL (1 << 2) #define CFG_RST_DIR (*IXP2000_PCI_CONTROL & IXP2000_PCICNTL_PCF) -- cgit 1.2.3-korg