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/
---
 arch/arm/include/asm/io.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

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.
-- 
2.14.5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to