[ARM] 3050/1: remove ixp2000_reg_write erratum #66 workaround
authorLennert Buytenhek <buytenh@wantstofly.org>
Sat, 29 Oct 2005 15:28:26 +0000 (16:28 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 29 Oct 2005 15:28:26 +0000 (16:28 +0100)
Patch from Lennert Buytenhek

The workaround that we do for avoiding triggering ixp2400 erratum #66
involves mapping I/O pages using XCB=101 instead of XCB=000 so that we
prevent the I/O signal to the gasket from being asserted (which can
cause data corruption.)  But XCB=101 mappings are write-buffered while
mappings using XCB=000 are not, which is why if we use XCB=101 mappings
we do a readback for every CSR store in an attempt to make sure that
the store has been pushed out of the xscale core and the gasket.

Unfortunately, there are two issues with this:
- we do a readback for every CSR store, which is wrong, because the
  register we are writing to might have unwanted side-effects on read,
  for example, in the case of the scratchpad ring enqueue/dequeue
  registers; and
- the readback is totally ineffective in the way we currently do it,
  because we just issue a load but do not issue any instruction that
  depends on the return value of that load, so the xscale core does
  not wait for the load to complete before continuing.

See this linux-arm-kernel mailing list post for further information:
http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2005-September/031314.html

This means that my ixp2400 boxes have been running for many months
without a working readback in ixp2000_reg_write, without any apparent
adverse effects.  Two of them have been running for a week now with
the actual readback deleted from ixp2000_reg_write, also without any
apparent ill effects.

So, because in its current form it does more harm than good, the
readback in ixp2000_reg_write should simply be killed, as the patch
below does.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Deepak Saxena <dsaxena@plexity.net>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
include/asm-arm/arch-ixp2000/platform.h

index abdcf51bd28374e3a6a06eca20709fc84e541ba7..aabeef2454dda21f9738724e2ded7e05ba04a79b 100644 (file)
 
 #ifndef __ASSEMBLY__
 
-/*
- * The IXP2400 B0 silicon contains an erratum (#66) that causes writes
- * to on-chip I/O register to not complete fully. What this means is
- * that if you have a write to on-chip I/O followed by a back-to-back
- * read or write, the first write will happen twice. OR...if it's
- * not a back-to-back transaction, the read or write will generate
- * incorrect data.
- *
- * The official work around for this is to set the on-chip I/O regions
- * as XCB=101 and then force a read-back from the register.
- *
- */
-#if defined(CONFIG_ARCH_ENP2611) || defined(CONFIG_ARCH_IXDP2400) || defined(CONFIG_ARCH_IXDP2401)
-
-#include <asm/system.h>                /* Pickup local_irq_ functions */
-
-static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
-{
-       unsigned long dummy;
-       unsigned long flags;
-
-       local_irq_save(flags);
-       *((volatile unsigned long *)reg) = val;
-       barrier();
-       dummy = *((volatile unsigned long *)reg);
-       local_irq_restore(flags);
-}
-#else
 static inline void ixp2000_reg_write(volatile void *reg, unsigned long val)
 {
        *((volatile unsigned long *)reg) = val;
 }
-#endif /* IXDP2400 || IXDP2401 */
 #define ixp2000_reg_read(reg)  (*((volatile unsigned long *)reg))
 
 /*