[PATCH] ARM: 2752/1: disable ixp2000 PCI I/O software workaround on chips that don...
Lennert Buytenhek [Sat, 25 Jun 2005 18:30:04 +0000 (19:30 +0100)]
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 <buytenh@wantstofly.org>
Signed-off-by: Deepak Saxena
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

arch/arm/configs/enp2611_defconfig
arch/arm/configs/ixdp2400_defconfig
arch/arm/configs/ixdp2401_defconfig
arch/arm/configs/ixdp2800_defconfig
arch/arm/configs/ixdp2801_defconfig
arch/arm/mach-ixp2000/Kconfig
arch/arm/mach-ixp2000/pci.c
include/asm-arm/arch-ixp2000/io.h
include/asm-arm/arch-ixp2000/ixp2000-regs.h

index af21534..b8c51ee 100644 (file)
@@ -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
index a7ee1a4..3cfbe2e 100644 (file)
@@ -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
index 2da48fc..5c87e8e 100644 (file)
@@ -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
index 7ba867f..3cb561a 100644 (file)
@@ -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
index c4df0ec..b1e162f 100644 (file)
@@ -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
index 9361e05..ecb58d8 100644 (file)
@@ -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
index 5ff2f27..0788fb2 100644 (file)
@@ -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");
 }
index 5e56b47..3241cd6 100644 (file)
 
 #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)
 
 #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
index a1d9e18..5eb47d4 100644 (file)
 #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)