diff options
author | Andre Przywara <andre.przywara@arm.com> | 2019-01-11 00:31:20 +0000 |
---|---|---|
committer | Christoph Müllner <christophm30@gmail.com> | 2019-04-26 00:52:31 +0200 |
commit | cd6b6fcee217d2b2db036bf74bf01bc2c68b9254 (patch) | |
tree | 5a6c5c51d48e130bd9afdfea6493fe14cb8a473a | |
parent | 9fd9762b046f3af62b8cbe6d7491ebb6d1aa832a (diff) |
arm: introduce _relaxed MMIO accessors
The normal MMIO accessor macros (readX/writeX) guarantee a strong ordering,
even with normal memory accesses [1].
For some MMIO operations (framebuffers being a prominent example) this is
not needed, and the rather costly barrier inserted on weakly ordered
systems like ARM costs some performance.
To mitigate this issue, Linux introduced readX_relaxed and
writeX_relaxed primitives, which only guarantee ordering between each
other, so are typically faster due to the missing barrier.
We probably do not care so much about performance in U-Boot, but want to
have those primitives for two other reasons:
- Being able to use the _relaxed macros simplifies porting drivers from
Linux.
- The missing barrier typically allows to generate smaller code, which can
relieve some chronically tight SPL builds.
Add those macros definitions by using the __raw versions of the
accessors, which matches an earlier (and less complicated) version of
the Linux implementation.
[1] https://lwn.net/Articles/698014/
-rw-r--r-- | arch/arm/include/asm/io.h | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index bcbaf0d83c..5b24b88efc 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -98,11 +98,21 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen) #define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; }) #define writeq(v,c) ({ u64 __v = v; __iowmb(); __arch_putq(__v,c); __v; }) +#define writeb_relaxed(v,c) __raw_writeb(v, c) +#define writew_relaxed(v,c) __raw_writew(v, c) +#define writel_relaxed(v,c) __raw_writel(v, c) +#define writeq_relaxed(v,c) __raw_writeq(v, c) + #define readb(c) ({ u8 __v = __arch_getb(c); __iormb(); __v; }) #define readw(c) ({ u16 __v = __arch_getw(c); __iormb(); __v; }) #define readl(c) ({ u32 __v = __arch_getl(c); __iormb(); __v; }) #define readq(c) ({ u64 __v = __arch_getq(c); __iormb(); __v; }) +#define readb_relaxed(c) __raw_readb(c) +#define readw_relaxed(c) __raw_readw(c) +#define readl_relaxed(c) __raw_readl(c) +#define readq_relaxed(c) __raw_readq(c) + /* * The compiler seems to be incapable of optimising constants * properly. Spell it out to the compiler in some cases. |