All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH] arm64: Add  memcpy_{from, to}io() and memset_io() helpers
@ 2019-10-12 10:59 Vignesh Raghavendra
  2019-10-15  7:05 ` Lokesh Vutla
  2019-11-08 15:32 ` Tom Rini
  0 siblings, 2 replies; 3+ messages in thread
From: Vignesh Raghavendra @ 2019-10-12 10:59 UTC (permalink / raw)
  To: u-boot

Provide optimized memcpy_{from,to}io() and memset_io(). This is required
when moving large amount of data to and from IO regions such as IP
registers or accessing memory mapped flashes.

Code is borrowed from Linux Kernel v5.4.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 arch/arm/include/asm/io.h | 104 ++++++++++++++++++++++++++++++++++++--
 1 file changed, 101 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index e6d27b69f936..fcfb53f0d9d8 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -23,6 +23,7 @@
 #ifdef __KERNEL__
 
 #include <linux/types.h>
+#include <linux/kernel.h>
 #include <asm/byteorder.h>
 #include <asm/memory.h>
 #include <asm/barriers.h>
@@ -315,6 +316,95 @@ extern void _memset_io(unsigned long, int, size_t);
 
 extern void __readwrite_bug(const char *fn);
 
+/* Optimized copy functions to read from/write to IO sapce */
+#ifdef CONFIG_ARM64
+/*
+ * Copy data from IO memory space to "real" memory space.
+ */
+static inline
+void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
+{
+	while (count && !IS_ALIGNED((unsigned long)from, 8)) {
+		*(u8 *)to = __raw_readb(from);
+		from++;
+		to++;
+		count--;
+	}
+
+	while (count >= 8) {
+		*(u64 *)to = __raw_readq(from);
+		from += 8;
+		to += 8;
+		count -= 8;
+	}
+
+	while (count) {
+		*(u8 *)to = __raw_readb(from);
+		from++;
+		to++;
+		count--;
+	}
+}
+
+/*
+ * Copy data from "real" memory space to IO memory space.
+ */
+static inline
+void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
+{
+	while (count && !IS_ALIGNED((unsigned long)to, 8)) {
+		__raw_writeb(*(u8 *)from, to);
+		from++;
+		to++;
+		count--;
+	}
+
+	while (count >= 8) {
+		__raw_writeq(*(u64 *)from, to);
+		from += 8;
+		to += 8;
+		count -= 8;
+	}
+
+	while (count) {
+		__raw_writeb(*(u8 *)from, to);
+		from++;
+		to++;
+		count--;
+	}
+}
+
+/*
+ * "memset" on IO memory space.
+ */
+static inline
+void __memset_io(volatile void __iomem *dst, int c, size_t count)
+{
+	u64 qc = (u8)c;
+
+	qc |= qc << 8;
+	qc |= qc << 16;
+	qc |= qc << 32;
+
+	while (count && !IS_ALIGNED((unsigned long)dst, 8)) {
+		__raw_writeb(c, dst);
+		dst++;
+		count--;
+	}
+
+	while (count >= 8) {
+		__raw_writeq(qc, dst);
+		dst += 8;
+		count -= 8;
+	}
+
+	while (count) {
+		__raw_writeb(c, dst);
+		dst++;
+		count--;
+	}
+}
+#endif /* CONFIG_ARM64 */
 /*
  * If this architecture has PCI memory IO, then define the read/write
  * macros.  These should only be used with the cookie passed from
@@ -355,9 +445,17 @@ out:
 }
 
 #else
-#define memset_io(a, b, c)		memset((void *)(a), (b), (c))
-#define memcpy_fromio(a, b, c)		memcpy((a), (void *)(b), (c))
-#define memcpy_toio(a, b, c)		memcpy((void *)(a), (b), (c))
+
+#ifdef CONFIG_ARM64
+#define memset_io(a, b, c)		__memset_io((a), (b), (c))
+#define memcpy_fromio(a, b, c)		__memcpy_fromio((a), (b), (c))
+#define memcpy_toio(a, b, c)		__memcpy_toio((a), (b), (c))
+#else
+#define memset_io(a, b, c)             memset((void *)(a), (b), (c))
+#define memcpy_fromio(a, b, c)         memcpy((a), (void *)(b), (c))
+#define memcpy_toio(a, b, c)           memcpy((void *)(a), (b), (c))
+#endif
+
 
 #if !defined(readb)
 
-- 
2.23.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [U-Boot] [PATCH] arm64: Add memcpy_{from, to}io() and memset_io() helpers
  2019-10-12 10:59 [U-Boot] [PATCH] arm64: Add memcpy_{from, to}io() and memset_io() helpers Vignesh Raghavendra
@ 2019-10-15  7:05 ` Lokesh Vutla
  2019-11-08 15:32 ` Tom Rini
  1 sibling, 0 replies; 3+ messages in thread
From: Lokesh Vutla @ 2019-10-15  7:05 UTC (permalink / raw)
  To: u-boot



On 12/10/19 4:29 PM, Vignesh Raghavendra wrote:
> Provide optimized memcpy_{from,to}io() and memset_io(). This is required
> when moving large amount of data to and from IO regions such as IP
> registers or accessing memory mapped flashes.
> 
> Code is borrowed from Linux Kernel v5.4.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>

Reviewed-by: Lokesh Vutla <lokeshvutla@ti.com>

Thanks and regards,
Lokesh

> ---
>  arch/arm/include/asm/io.h | 104 ++++++++++++++++++++++++++++++++++++--
>  1 file changed, 101 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
> index e6d27b69f936..fcfb53f0d9d8 100644
> --- a/arch/arm/include/asm/io.h
> +++ b/arch/arm/include/asm/io.h
> @@ -23,6 +23,7 @@
>  #ifdef __KERNEL__
>  
>  #include <linux/types.h>
> +#include <linux/kernel.h>
>  #include <asm/byteorder.h>
>  #include <asm/memory.h>
>  #include <asm/barriers.h>
> @@ -315,6 +316,95 @@ extern void _memset_io(unsigned long, int, size_t);
>  
>  extern void __readwrite_bug(const char *fn);
>  
> +/* Optimized copy functions to read from/write to IO sapce */
> +#ifdef CONFIG_ARM64
> +/*
> + * Copy data from IO memory space to "real" memory space.
> + */
> +static inline
> +void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
> +{
> +	while (count && !IS_ALIGNED((unsigned long)from, 8)) {
> +		*(u8 *)to = __raw_readb(from);
> +		from++;
> +		to++;
> +		count--;
> +	}
> +
> +	while (count >= 8) {
> +		*(u64 *)to = __raw_readq(from);
> +		from += 8;
> +		to += 8;
> +		count -= 8;
> +	}
> +
> +	while (count) {
> +		*(u8 *)to = __raw_readb(from);
> +		from++;
> +		to++;
> +		count--;
> +	}
> +}
> +
> +/*
> + * Copy data from "real" memory space to IO memory space.
> + */
> +static inline
> +void __memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
> +{
> +	while (count && !IS_ALIGNED((unsigned long)to, 8)) {
> +		__raw_writeb(*(u8 *)from, to);
> +		from++;
> +		to++;
> +		count--;
> +	}
> +
> +	while (count >= 8) {
> +		__raw_writeq(*(u64 *)from, to);
> +		from += 8;
> +		to += 8;
> +		count -= 8;
> +	}
> +
> +	while (count) {
> +		__raw_writeb(*(u8 *)from, to);
> +		from++;
> +		to++;
> +		count--;
> +	}
> +}
> +
> +/*
> + * "memset" on IO memory space.
> + */
> +static inline
> +void __memset_io(volatile void __iomem *dst, int c, size_t count)
> +{
> +	u64 qc = (u8)c;
> +
> +	qc |= qc << 8;
> +	qc |= qc << 16;
> +	qc |= qc << 32;
> +
> +	while (count && !IS_ALIGNED((unsigned long)dst, 8)) {
> +		__raw_writeb(c, dst);
> +		dst++;
> +		count--;
> +	}
> +
> +	while (count >= 8) {
> +		__raw_writeq(qc, dst);
> +		dst += 8;
> +		count -= 8;
> +	}
> +
> +	while (count) {
> +		__raw_writeb(c, dst);
> +		dst++;
> +		count--;
> +	}
> +}
> +#endif /* CONFIG_ARM64 */
>  /*
>   * If this architecture has PCI memory IO, then define the read/write
>   * macros.  These should only be used with the cookie passed from
> @@ -355,9 +445,17 @@ out:
>  }
>  
>  #else
> -#define memset_io(a, b, c)		memset((void *)(a), (b), (c))
> -#define memcpy_fromio(a, b, c)		memcpy((a), (void *)(b), (c))
> -#define memcpy_toio(a, b, c)		memcpy((void *)(a), (b), (c))
> +
> +#ifdef CONFIG_ARM64
> +#define memset_io(a, b, c)		__memset_io((a), (b), (c))
> +#define memcpy_fromio(a, b, c)		__memcpy_fromio((a), (b), (c))
> +#define memcpy_toio(a, b, c)		__memcpy_toio((a), (b), (c))
> +#else
> +#define memset_io(a, b, c)             memset((void *)(a), (b), (c))
> +#define memcpy_fromio(a, b, c)         memcpy((a), (void *)(b), (c))
> +#define memcpy_toio(a, b, c)           memcpy((void *)(a), (b), (c))
> +#endif
> +
>  
>  #if !defined(readb)
>  
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [U-Boot] [PATCH] arm64: Add  memcpy_{from, to}io() and memset_io() helpers
  2019-10-12 10:59 [U-Boot] [PATCH] arm64: Add memcpy_{from, to}io() and memset_io() helpers Vignesh Raghavendra
  2019-10-15  7:05 ` Lokesh Vutla
@ 2019-11-08 15:32 ` Tom Rini
  1 sibling, 0 replies; 3+ messages in thread
From: Tom Rini @ 2019-11-08 15:32 UTC (permalink / raw)
  To: u-boot

On Sat, Oct 12, 2019 at 04:29:34PM +0530, Vignesh Raghavendra wrote:

> Provide optimized memcpy_{from,to}io() and memset_io(). This is required
> when moving large amount of data to and from IO regions such as IP
> registers or accessing memory mapped flashes.
> 
> Code is borrowed from Linux Kernel v5.4.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
> Reviewed-by: Lokesh Vutla <lokeshvutla@ti.com>

Applied to u-boot/master, thanks!

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20191108/f06fc7e0/attachment.sig>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-11-08 15:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-12 10:59 [U-Boot] [PATCH] arm64: Add memcpy_{from, to}io() and memset_io() helpers Vignesh Raghavendra
2019-10-15  7:05 ` Lokesh Vutla
2019-11-08 15:32 ` Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.