summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2018-10-13 11:47:55 +1100
committerGeert Uytterhoeven <geert@linux-m68k.org>2018-12-03 13:05:42 +0100
commitb6cf523c16e148e1ece5fc4ff4657d79323a4635 (patch)
treea0268d6a6f4dd3651ef3f505d0acf22b5c1fe8b6 /arch
parent651022382c7f8da46cb4872a545ee1da6d097d2a (diff)
downloadlinux-b6cf523c16e148e1ece5fc4ff4657d79323a4635.tar.gz
m68k: Unroll raw_outsb() loop
Unroll the raw_outsb() loop using the optimized assembler code from
raw_outsw(). That code is copied and pasted, with movew changed to moveb.

This improves the performance of sequential write transfers using mac_esp
in PIO mode by 5% or 10%. (The DMA controller on the 840av/660av models is
still unsupported so PIO transfers are used.)

Tested-by: Stan Johnson <userm57@yahoo.com>
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/m68k/include/asm/raw_io.h39
1 files changed, 35 insertions, 4 deletions
diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h
index 85761255dde5..8a6dc6e5a279 100644
--- a/arch/m68k/include/asm/raw_io.h
+++ b/arch/m68k/include/asm/raw_io.h
@@ -107,12 +107,43 @@ static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len
 }
 
 static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf,
-			     unsigned int len)
+			     unsigned int nr)
 {
-	unsigned int i;
+	unsigned int tmp;
 
-        for (i = 0; i < len; i++)
-		out_8(port, *buf++);
+	if (nr & 15) {
+		tmp = (nr & 15) - 1;
+		asm volatile (
+			"1: moveb %0@+,%2@; dbra %1,1b"
+			: "=a" (buf), "=d" (tmp)
+			: "a" (port), "0" (buf),
+			  "1" (tmp));
+	}
+	if (nr >> 4) {
+		tmp = (nr >> 4) - 1;
+		asm volatile (
+			"1: "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"moveb %0@+,%2@; "
+			"dbra %1,1b"
+			: "=a" (buf), "=d" (tmp)
+			: "a" (port), "0" (buf),
+			  "1" (tmp));
+	}
 }
 
 static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr)