openwrtv3/target/linux/apm821xx/patches-4.4/030-usb-dwc2-endian-fix.patch
Christian Lamparter dc7efaefb5 apm821xx: add support for the Western Digital MyBook Live Series
Hardware Highlights:

This patch adds support for Western Digital MyBook Live Series:
CPU: AMCC PowerPC  UNKNOWN (PVR=12c41c83) at 800 MHz (PLB=200, OPB=100, EBC=100 MHz)
     32 kB I-Cache 32 kB D-Cache, 256 kB L2-Cache, 32 kB OnChip Memory
Board: Apollo-3G - APM82181 Board, 1*SATA
DRAM:  256 MB (2x NT5TU64M16GG-AC)
FLASH: 512 kB (SST 39VF040)
Ethernet: 1xRGMII - 1 Gbit - Broadcom PHY BCM54610

WARNING: The serial port needs a TTL/RS-232 v3.3 level converter!

The MyBook Live Duo additionally features a 1x USB 2.0 host port
and can support a second hard-drive.

This target produces two images for a target.
 1. ext4 image
    The extracted/raw image can be directly installed on
    the internal HDD via "dd if=img.ext4 of=/dev/sdX".

    This can either be done in place with the stock MyBook Live
    firmware via ssh. Or by removing the HDD and writing the image
    with a different PC.

    The the compressed images are useful for sysupgrade.

 2. recovery.tar image for TFTP and Serial.

    extract the recovery.tar to a TFTP server directory.

    On the MyBook Live (Duo) serial port - Hit Enter during u-boot and insert:
    # setenv serverip 192.168.1.254; setenv ipaddr 192.168.1.1; run net_self

    Where 192.168.1.254 is your TFTP server.

Signed-off-by: Christian Lamparter <chunkeey@gmail.com>
2016-07-22 09:48:12 +02:00

95 lines
3.6 KiB
Diff

From: Arnd Bergmann <arnd@arndb.de>
Subject: [PATCH v4] usb: dwc2: fix regression on big-endian PowerPC/ARM systems
Date: Fri, 13 May 2016 15:52:27 +0200
Message-Id: <1463147559-544140-1-git-send-email-arnd@arndb.de>
A patch that went into Linux-4.4 to fix big-endian mode on a Lantiq
MIPS system unfortunately broke big-endian operation on PowerPC
APM82181 as reported by Christian Lamparter, and likely other
systems.
It actually introduced multiple issues:
- it broke big-endian ARM kernels: any machine that was working
correctly with a little-endian kernel is no longer using byteswaps
on big-endian kernels, which clearly breaks them.
- On PowerPC the same thing must be true: if it was working before,
using big-endian kernels is now broken. Unlike ARM, 32-bit PowerPC
usually uses big-endian kernels, so they are likely all broken.
- The barrier for dwc2_writel is on the wrong side of the __raw_writel(),
so the MMIO no longer synchronizes with DMA operations.
- On architectures that require specific CPU instructions for MMIO
access, using the __raw_ variant may turn this into a pointer
dereference that does not have the same effect as the readl/writel.
This patch is a simple revert for all architectures other than MIPS,
in the hope that we can more easily backport it to fix the regression
on PowerPC and ARM systems without breaking the Lantiq system again.
We should follow this up with a more elaborate change to add runtime
detection of endianness, to make sure it also works on all other
combinations of architectures and implementations of the usb-dwc2
device. That patch however will be fairly large and not appropriate
for backports to stable kernels.
Felipe suggested a different approach, using an endianness switching
register to always put the device into LE mode, but unfortunately
the dwc2 hardware does not provide a generic way to do that. Also,
I see no practical way of addressing the problem more generally by
patching architecture specific code on MIPS.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Fixes: 95c8bc360944 ("usb: dwc2: Use platform endianness when accessing registers")
---
drivers/usb/dwc2/core.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
index 3c58d633ce80..dec0b21fc626 100644
--- a/drivers/usb/dwc2/core.h
+++ b/drivers/usb/dwc2/core.h
@@ -64,6 +64,17 @@
DWC2_TRACE_SCHEDULER_VB(pr_fmt("%s: SCH: " fmt), \
dev_name(hsotg->dev), ##__VA_ARGS__)
+#ifdef CONFIG_MIPS
+/*
+ * There are some MIPS machines that can run in either big-endian
+ * or little-endian mode and that use the dwc2 register without
+ * a byteswap in both ways.
+ * Unlike other architectures, MIPS apparently does not require a
+ * barrier before the __raw_writel() to synchronize with DMA but does
+ * require the barrier after the __raw_writel() to serialize a set of
+ * writes. This set of operations was added specifically for MIPS and
+ * should only be used there.
+ */
static inline u32 dwc2_readl(const void __iomem *addr)
{
u32 value = __raw_readl(addr);
@@ -90,6 +101,22 @@ static inline void dwc2_writel(u32 value, void __iomem *addr)
pr_info("INFO:: wrote %08x to %p\n", value, addr);
#endif
}
+#else
+/* Normal architectures just use readl/write */
+static inline u32 dwc2_readl(const void __iomem *addr)
+{
+ return readl(addr);
+}
+
+static inline void dwc2_writel(u32 value, void __iomem *addr)
+{
+ writel(value, addr);
+
+#ifdef DWC2_LOG_WRITES
+ pr_info("info:: wrote %08x to %p\n", value, addr);
+#endif
+}
+#endif
/* Maximum number of Endpoints/HostChannels */
#define MAX_EPS_CHANNELS 16
--
2.7.0