summary refs log tree commit diff
path: root/arch/blackfin
diff options
context:
space:
mode:
authorMike Frysinger <vapier.adi@gmail.com>2009-01-07 23:14:38 +0800
committerBryan Wu <cooloney@kernel.org>2009-01-07 23:14:38 +0800
commitc250bfb93c046a789989af475ae18d08c61b4cfa (patch)
treee666f2d2702eba6ac50df0ec981526f501b26e7a /arch/blackfin
parent39ca44536d03cc0cd3e8a265d6e5ca1f7dd60719 (diff)
downloadlinux-c250bfb93c046a789989af475ae18d08c61b4cfa.tar.gz
Blackfin arch: cleanup and unify the ins functions
this also fixes some errors in the ipipe merge

Signed-off-by: Mike Frysinger <vapier.adi@gmail.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>

Diffstat (limited to 'arch/blackfin')
-rw-r--r--arch/blackfin/lib/ins.S429
1 files changed, 84 insertions, 345 deletions
diff --git a/arch/blackfin/lib/ins.S b/arch/blackfin/lib/ins.S
index 1b84b21ca7d1..1863a6ba507c 100644
--- a/arch/blackfin/lib/ins.S
+++ b/arch/blackfin/lib/ins.S
@@ -1,31 +1,9 @@
 /*
- * File:         arch/blackfin/lib/ins.S
- * Based on:
- * Author:       Bas Vermeulen <bas@buyways.nl>
+ * arch/blackfin/lib/ins.S - ins{bwl} using hardware loops
  *
- * Created:      Tue Mar 22 15:27:24 CEST 2005
- * Description:  Implementation of ins{bwl} for BlackFin processors using zero overhead loops.
- *
- * Modified:
- *               Copyright 2004-2008 Analog Devices Inc.
- *               Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
- *
- * Bugs:         Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ * Copyright 2004-2008 Analog Devices Inc.
+ * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
+ * Licensed under the GPL-2 or later.
  */
 
 #include <linux/linkage.h>
@@ -33,6 +11,46 @@
 
 .align 2
 
+#ifdef CONFIG_IPIPE
+# define DO_CLI \
+	[--sp] = rets; \
+	[--sp] = (P5:0); \
+	sp += -12; \
+	call ___ipipe_stall_root_raw; \
+	sp += 12; \
+	(P5:0) = [sp++];
+# define CLI_INNER_NOP
+#else
+# define DO_CLI cli R3;
+# define CLI_INNER_NOP nop; nop; nop;
+#endif
+
+#ifdef CONFIG_IPIPE
+# define DO_STI \
+	sp += -12; \
+	call ___ipipe_unstall_root_raw; \
+	sp += 12; \
+2:	rets = [sp++];
+#else
+# define DO_STI 2: sti R3;
+#endif
+
+#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
+# define CLI_OUTER DO_CLI;
+# define STI_OUTER DO_STI;
+# define CLI_INNER 1:
+# if ANOMALY_05000416
+#  define STI_INNER nop; 2: nop;
+# else
+#  define STI_INNER 2:
+# endif
+#else
+# define CLI_OUTER
+# define STI_OUTER
+# define CLI_INNER 1: DO_CLI; CLI_INNER_NOP;
+# define STI_INNER DO_STI;
+#endif
+
 /*
  * Reads on the Blackfin are speculative. In Blackfin terms, this means they
  * can be interrupted at any time (even after they have been issued on to the
@@ -53,327 +71,48 @@
  * buffers in/out of FIFOs.
  */
 
-ENTRY(_insl)
-#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
-	P0 = R0;	/* P0 = port */
-#ifdef CONFIG_IPIPE
-	[--sp] = rets
-	[--sp] = (P5:0);
-	sp += -12
-	call ___ipipe_stall_root_raw
-	sp += 12
-	(P5:0) = [sp++];
-#else
-	cli R3;
-#endif
-	P1 = R1;	/* P1 = address */
-	P2 = R2;	/* P2 = count */
-	SSYNC;
-	LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2;
-.Llong_loop_s:  R0 = [P0];
-		[P1++] = R0;
-		NOP;
-.Llong_loop_e: 	NOP;
-#ifdef CONFIG_IPIPE
-	sp += -12
-	call ___ipipe_unstall_root_raw
-	sp += 12
-	rets = [sp++]
-#else
-	sti R3;
-#endif
-	RTS;
-#else
-	P0 = R0;	/* P0 = port */
-	P1 = R1;	/* P1 = address */
-	P2 = R2;	/* P2 = count */
-	SSYNC;
-	LSETUP( .Llong_loop_s, .Llong_loop_e) LC0 = P2;
-.Llong_loop_s:
-#ifdef CONFIG_IPIPE
-	[--sp] = rets
-	[--sp] = (P5:0);
-	sp += -12
-	call ___ipipe_stall_root_raw
-	sp += 12
-	(P5:0) = [sp++];
-#else
-	CLI R3;
-#endif
-	NOP; NOP; NOP;
-	R0 = [P0];
-	[P1++] = R0;
-.Llong_loop_e:
-#ifdef CONFIG_IPIPE
-	sp += -12
-	call ___ipipe_unstall_root_raw
-	sp += 12
-	rets = [sp++]
-#else
-	STI R3;
-#endif
-	RTS;
-#endif
-ENDPROC(_insl)
+#define COMMON_INS(func, ops) \
+ENTRY(_ins##func) \
+	P0 = R0;	/* P0 = port */ \
+	CLI_OUTER;	/* 3 instructions before first read access */ \
+	P1 = R1;	/* P1 = address */ \
+	P2 = R2;	/* P2 = count */ \
+	SSYNC; \
+ \
+	LSETUP(1f, 2f) LC0 = P2; \
+	CLI_INNER; \
+	ops; \
+	STI_INNER; \
+ \
+	STI_OUTER; \
+	RTS; \
+ENDPROC(_ins##func)
 
-ENTRY(_insw)
-#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
-	P0 = R0;	/* P0 = port */
-#ifdef CONFIG_IPIPE
-	[--sp] = rets
-	[--sp] = (P5:0);
-	sp += -12
-	call ___ipipe_stall_root_raw
-	sp += 12
-	(P5:0) = [sp++];
-#else
-	cli R3;
-#endif
-	P1 = R1;	/* P1 = address */
-	P2 = R2;	/* P2 = count */
-	SSYNC;
-	LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
-.Lword_loop_s:  R0 = W[P0];
-		W[P1++] = R0;
-		NOP;
-.Lword_loop_e: 	NOP;
-#ifdef CONFIG_IPIPE
-	sp += -12
-	call ___ipipe_unstall_root_raw
-	sp += 12
-	rets = [sp++]
-#else
-	sti R3;
-#endif
-	RTS;
-#else
-	P0 = R0;	/* P0 = port */
-	P1 = R1;	/* P1 = address */
-	P2 = R2;	/* P2 = count */
-	SSYNC;
-	LSETUP( .Lword_loop_s, .Lword_loop_e) LC0 = P2;
-.Lword_loop_s:
-#ifdef CONFIG_IPIPE
-	[--sp] = rets
-	[--sp] = (P5:0);
-	sp += -12
-	call ___ipipe_stall_root_raw
-	sp += 12
-	(P5:0) = [sp++];
-#else
-	CLI R3;
-#endif
-	NOP; NOP; NOP;
-	R0 = W[P0];
-	W[P1++] = R0;
-.Lword_loop_e:
-#ifdef CONFIG_IPIPE
-	sp += -12
-	call ___ipipe_unstall_root_raw
-	sp += 12
-	rets = [sp++]
-#else
-	STI R3;
-#endif
-	RTS;
+COMMON_INS(l, \
+	R0 = [P0]; \
+	[P1++] = R0; \
+)
 
-#endif
-ENDPROC(_insw)
+COMMON_INS(w, \
+	R0 = W[P0]; \
+	W[P1++] = R0; \
+)
 
-ENTRY(_insw_8)
-#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
-	P0 = R0;	/* P0 = port */
-#ifdef CONFIG_IPIPE
-	[--sp] = rets
-	[--sp] = (P5:0);
-	sp += -12
-	call ___ipipe_stall_root_raw
-	sp += 12
-	(P5:0) = [sp++];
-#else
-	cli R3;
-#endif
-	P1 = R1;	/* P1 = address */
-	P2 = R2;	/* P2 = count */
-	SSYNC;
-	LSETUP( .Lword8_loop_s, .Lword8_loop_e) LC0 = P2;
-.Lword8_loop_s:  R0 = W[P0];
-		B[P1++] = R0;
-		R0 = R0 >> 8;
-		B[P1++] = R0;
-		NOP;
-.Lword8_loop_e: NOP;
-#ifdef CONFIG_IPIPE
-	sp += -12
-	call ___ipipe_unstall_root_raw
-	sp += 12
-	rets = [sp++]
-#else
-	sti R3;
-#endif
-	RTS;
-#else
-	P0 = R0;	/* P0 = port */
-	P1 = R1;	/* P1 = address */
-	P2 = R2;	/* P2 = count */
-	SSYNC;
-	LSETUP( .Lword8_loop_s, .Lword8_loop_e) LC0 = P2;
-.Lword8_loop_s:
-#ifdef CONFIG_IPIPE
-	[--sp] = rets
-	[--sp] = (P5:0);
-	sp += -12
-	call ___ipipe_stall_root_raw
-	sp += 12
-	(P5:0) = [sp++];
-#else
-	CLI R3;
-#endif
-	NOP; NOP; NOP;
-	R0 = W[P0];
-	B[P1++] = R0;
-	R0 = R0 >> 8;
-	B[P1++] = R0;
-	NOP;
-.Lword8_loop_e:
-#ifdef CONFIG_IPIPE
-	sp += -12
-	call ___ipipe_unstall_root_raw
-	sp += 12
-	rets = [sp++]
-#else
-	STI R3;
-#endif
-	RTS;
-#endif
-ENDPROC(_insw_8)
+COMMON_INS(w_8, \
+	R0 = W[P0]; \
+	B[P1++] = R0; \
+	R0 = R0 >> 8; \
+	B[P1++] = R0; \
+)
 
-ENTRY(_insb)
-#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
-	P0 = R0;	/* P0 = port */
-#ifdef CONFIG_IPIPE
-	[--sp] = rets
-	[--sp] = (P5:0);
-	sp += -12
-	call ___ipipe_stall_root_raw
-	sp += 12
-	(P5:0) = [sp++];
-#else
-	cli R3;
-#endif
-	P1 = R1;	/* P1 = address */
-	P2 = R2;	/* P2 = count */
-	SSYNC;
-	LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2;
-.Lbyte_loop_s:  R0 = B[P0];
-		B[P1++] = R0;
-		NOP;
-.Lbyte_loop_e:  NOP;
-#ifdef CONFIG_IPIPE
-	sp += -12
-	call ___ipipe_unstall_root_raw
-	sp += 12
-	rets = [sp++]
-#else
-	sti R3;
-#endif
-	RTS;
-#else
-	P0 = R0;        /* P0 = port */
-	P1 = R1;        /* P1 = address */
-	P2 = R2;        /* P2 = count */
-	SSYNC;
-	LSETUP( .Lbyte_loop_s, .Lbyte_loop_e) LC0 = P2;
-.Lbyte_loop_s:
-#ifdef CONFIG_IPIPE
-	[--sp] = rets
-	[--sp] = (P5:0);
-	sp += -12
-	call ___ipipe_stall_root_raw
-	sp += 12
-	(P5:0) = [sp++];
-#else
-	CLI R3;
-#endif
-	NOP; NOP; NOP;
-	R0 = B[P0];
-	B[P1++] = R0;
-.Lbyte_loop_e:
-#ifdef CONFIG_IPIPE
-	sp += -12
-	call ___ipipe_unstall_root_raw
-	sp += 12
-	rets = [sp++]
-#else
-	STI R3;
-#endif
-	RTS;
-#endif
-ENDPROC(_insb)
+COMMON_INS(b, \
+	R0 = B[P0]; \
+	B[P1++] = R0; \
+)
 
-ENTRY(_insl_16)
-#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
-	P0 = R0;	/* P0 = port */
-#ifdef CONFIG_IPIPE
-	[--sp] = rets
-	[--sp] = (P5:0);
-	sp += -12
-	call ___ipipe_stall_root_raw
-	sp += 12
-	(P5:0) = [sp++];
-#else
-	cli R3;
-#endif
-	P1 = R1;	/* P1 = address */
-	P2 = R2;	/* P2 = count */
-	SSYNC;
-	LSETUP( .Llong16_loop_s, .Llong16_loop_e) LC0 = P2;
-.Llong16_loop_s:  R0 = [P0];
-		  W[P1++] = R0;
-		  R0 = R0 >> 16;
-		  W[P1++] = R0;
-		  NOP;
-.Llong16_loop_e:  NOP;
-#ifdef CONFIG_IPIPE
-	sp += -12
-	call ___ipipe_unstall_root_raw
-	sp += 12
-	rets = [sp++]
-#else
-	sti R3;
-#endif
-	RTS;
-#else
-	P0 = R0;	/* P0 = port */
-	P1 = R1;	/* P1 = address */
-	P2 = R2;	/* P2 = count */
-	SSYNC;
-	LSETUP( .Llong16_loop_s, .Llong16_loop_e) LC0 = P2;
-.Llong16_loop_s:
-#ifdef CONFIG_IPIPE
-	[--sp] = rets
-	[--sp] = (P5:0);
-	sp += -12
-	call ___ipipe_stall_root_raw
-	sp += 12
-	(P5:0) = [sp++];
-#else
-	CLI R3;
-#endif
-	NOP; NOP; NOP;
-	R0 = [P0];
-	W[P1++] = R0;
-	R0 = R0 >> 16;
-	W[P1++] = R0;
-.Llong16_loop_e:
-#ifdef CONFIG_IPIPE
-	sp += -12
-	call ___ipipe_unstall_root_raw
-	sp += 12
-	rets = [sp++]
-#else
-	STI R3;
-#endif
-	RTS;
-#endif
-ENDPROC(_insl_16)
+COMMON_INS(l_16, \
+	R0 = [P0]; \
+	W[P1++] = R0; \
+	R0 = R0 >> 16; \
+	W[P1++] = R0; \
+)