From: arnd@arndb.de (Arnd Bergmann)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 3/7] usb: gadget: pxa25x_udc: use readl/writel for mmio
Date: Wed, 17 Feb 2016 11:36:49 +0100 [thread overview]
Message-ID: <2926671.iEYNiy920m@wuerfel> (raw)
In-Reply-To: <m3ziuzpwbu.fsf@t19.piap.pl>
On Wednesday 17 February 2016 09:36:37 Krzysztof Ha?asa wrote:
> Arnd Bergmann <arnd@arndb.de> writes:
>
> > ixp4xx is really special in that it performs hardware swapping for
> > internal devices based on CPU endianess but not on PCI devices.
>
> Again, IXP4xx does not perform hardware (nor any other) swapping for
> registers of on-chip devices. The registers are connected 1:1,
> bit 0 to bit 0 etc.
>
> (Yes, IXP4xx can be optionally programmed for such swapping, depending
> on silicon revision, but it is not used in mainline kernel).
>
> The only hardware swapping happens on PCI bus (in BE mode), to be
> compatible with other platforms and non-IXP4xx-specific PCI drivers.
Ok, so I guess what this means is that ixp4xx (or xscale in general)
implements its big-endian mode by adding a byteswap on its DRAM
and PCI interfaces in be32 mode, rather than by changing the behavior of
the load/store operations (as be8 mode does) or by having the byteswap
in its load/store pipeline or the top-level AHB bridge?
It's a bit surprising but it sounds plausible and explains most of
the code we see.
I'm still unsure about __indirect_readsl()/ioread32_rep()/insl()/readsl().
insl() does a double-swap on big-endian, which seems right, as we
end up with four swaps total, preserving correct byte order.
__raw_readsl() performs no swap, which would be correct for PCI
(same swap on PCI and RAM, so byteorder is preserved), but wrong
for on-chip FIFO registers (one swap on RAM, no swap on MMIO).
This is probably fine as well, as I don't see any use of __raw_readsl()
on non-PCI devices.
However, when CONFIG_IXP4XX_INDIRECT_PCI is set, both
ioread32_rep() and readsl() call __indirect_readsl(), which
in turn swaps the data once, so I think we actually need this patch:
diff --git a/arch/arm/mach-ixp4xx/include/mach/io.h b/arch/arm/mach-ixp4xx/include/mach/io.h
index e770858b490a..871f92f3504a 100644
--- a/arch/arm/mach-ixp4xx/include/mach/io.h
+++ b/arch/arm/mach-ixp4xx/include/mach/io.h
@@ -85,6 +85,8 @@ u8 __indirect_readb(const volatile void __iomem *p);
u16 __indirect_readw(const volatile void __iomem *p);
u32 __indirect_readl(const volatile void __iomem *p);
+/* string functions may need to swap data back to revert the byte swap on
+ big-endian __indirect_{read,write}{w,l}() accesses */
static inline void __indirect_writesb(volatile void __iomem *bus_addr,
const void *p, int count)
{
@@ -100,7 +102,7 @@ static inline void __indirect_writesw(volatile void __iomem *bus_addr,
const u16 *vaddr = p;
while (count--)
- writew(*vaddr++, bus_addr);
+ writew((u16 __force)cpu_to_le32(*vaddr++), bus_addr);
}
static inline void __indirect_writesl(volatile void __iomem *bus_addr,
@@ -108,7 +110,7 @@ static inline void __indirect_writesl(volatile void __iomem *bus_addr,
{
const u32 *vaddr = p;
while (count--)
- writel(*vaddr++, bus_addr);
+ writel((u32 __force)cpu_to_le32(*vaddr++), bus_addr);
}
static inline void __indirect_readsb(const volatile void __iomem *bus_addr,
@@ -126,7 +128,7 @@ static inline void __indirect_readsw(const volatile void __iomem *bus_addr,
u16 *vaddr = p;
while (count--)
- *vaddr++ = readw(bus_addr);
+ *vaddr++ = (u16 __force)cpu_to_le16(readw(bus_addr));
}
static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
@@ -135,7 +137,7 @@ static inline void __indirect_readsl(const volatile void __iomem *bus_addr,
u32 *vaddr = p;
while (count--)
- *vaddr++ = readl(bus_addr);
+ *vaddr++ = (u32 __force)cpu_to_le32(readl(bus_addr));
}
Does that make sense to you? This is essentially the same thing we already
do for inw/inl/outw/outl.
> > Coming back to the specific pxa25x_udc case: using __raw_* accessors
> > in the driver would possibly end up breaking the PXA25x machines in
> > the (very unlikely) case that someone wants to make it work with
> > big-endian kernels, assuming it does not have the same hardware
> > byteswap logic as ixp4xx.
>
> I'd expect both CPUs to behave in exactly the same manner, i.e., to
> not swap anything on the internal bus. If true, it would mean it should
> "just work" in both BE and LE modes (including BE mode on PXA, should
> it be actually possible).
Ok, I'll change the patch accordingly and resubmit.
Arnd
next prev parent reply other threads:[~2016-02-17 10:36 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-28 16:15 [PATCH 0/7] USB changes for rare warnings Arnd Bergmann
2016-01-28 16:17 ` [PATCH 1/7] usb: gadget: pxa25x_udc: move register definitions from arch Arnd Bergmann
2016-01-28 16:17 ` [PATCH 2/7] usb: gadget: pxa25x_udc cleanup Arnd Bergmann
2016-01-29 10:13 ` Robert Jarzmik
2016-01-28 16:17 ` [PATCH 3/7] usb: gadget: pxa25x_udc: use readl/writel for mmio Arnd Bergmann
2016-01-29 10:17 ` Robert Jarzmik
2016-01-29 16:18 ` Krzysztof Hałasa
2016-01-29 17:06 ` Arnd Bergmann
2016-02-15 7:33 ` Krzysztof Hałasa
2016-02-15 9:33 ` Arnd Bergmann
2016-02-15 13:51 ` Krzysztof Hałasa
2016-02-15 16:12 ` Arnd Bergmann
2016-02-16 9:26 ` Krzysztof Hałasa
2016-02-16 11:26 ` Arnd Bergmann
2016-02-16 13:24 ` Krzysztof Hałasa
2016-02-16 13:55 ` Arnd Bergmann
2016-02-17 8:36 ` Krzysztof Hałasa
2016-02-17 10:36 ` Arnd Bergmann [this message]
2016-02-17 16:14 ` Krzysztof Hałasa
2016-02-20 20:54 ` Robert Jarzmik
2016-01-29 18:03 ` Sergei Shtylyov
2016-01-29 21:02 ` Arnd Bergmann
2016-01-29 9:32 ` [PATCH 1/7] usb: gadget: pxa25x_udc: move register definitions from arch Robert Jarzmik
2016-01-29 10:07 ` Arnd Bergmann
2016-01-29 15:26 ` Robert Jarzmik
2016-01-29 15:55 ` Krzysztof Hałasa
2016-02-17 15:08 ` Felipe Balbi
2016-02-17 16:00 ` Arnd Bergmann
2016-01-28 16:20 ` [PATCH 4/7] usb: fsl: drop USB_FSL_MPH_DR_OF Kconfig symbol Arnd Bergmann
2016-01-28 16:23 ` [PATCH 5/7] usb: isp1301-omap: mark power_up as __maybe_unused Arnd Bergmann
2016-01-28 16:23 ` [PATCH 6/7] usb: musb: use %pad format string from dma_addr_t Arnd Bergmann
2016-01-28 17:50 ` Tony Lindgren
2016-01-28 16:23 ` [PATCH 7/7] usb: musb/ux500: remove duplicate check for dma_is_compatible Arnd Bergmann
2016-02-03 18:12 ` [PATCH 0/7] USB changes for rare warnings Felipe Balbi
2016-02-03 19:15 ` Robert Jarzmik
2016-02-03 20:49 ` Arnd Bergmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2926671.iEYNiy920m@wuerfel \
--to=arnd@arndb.de \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox