mirror of
				https://source.denx.de/u-boot/u-boot.git
				synced 2025-10-31 16:31:25 +01:00 
			
		
		
		
	Some common code uses more of the io.h funcs than we currently provide, so pull in all of the ones from the linux kernel. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
		
			
				
	
	
		
			118 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			118 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * arch/blackfin/lib/ins.S - ins{bwl} using hardware loops
 | |
|  *
 | |
|  * Copyright 2004-2008 Analog Devices Inc.
 | |
|  * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
 | |
|  * Licensed under the GPL-2 or later.
 | |
|  */
 | |
| 
 | |
| #include <asm/blackfin.h>
 | |
| 
 | |
| .align 2
 | |
| 
 | |
| #ifdef CONFIG_IPIPE
 | |
| # define DO_CLI \
 | |
| 	[--sp] = rets; \
 | |
| 	[--sp] = (P5:0); \
 | |
| 	sp += -12; \
 | |
| 	call ___ipipe_disable_root_irqs_hw; \
 | |
| 	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_enable_root_irqs_hw; \
 | |
| 	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
 | |
|  * external bus), and re-issued after the interrupt occurs.
 | |
|  *
 | |
|  * If a FIFO is sitting on the end of the read, it will see two reads,
 | |
|  * when the core only sees one. The FIFO receives the read which is cancelled,
 | |
|  * and not delivered to the core.
 | |
|  *
 | |
|  * To solve this, interrupts are turned off before reads occur to I/O space.
 | |
|  * There are 3 versions of all these functions
 | |
|  *  - turns interrupts off every read (higher overhead, but lower latency)
 | |
|  *  - turns interrupts off every loop (low overhead, but longer latency)
 | |
|  *  - DMA version, which do not suffer from this issue. DMA versions have
 | |
|  *      different name (prefixed by dma_ ), and are located in
 | |
|  *      ../kernel/bfin_dma_5xx.c
 | |
|  * Using the dma related functions are recommended for transfering large
 | |
|  * buffers in/out of FIFOs.
 | |
|  */
 | |
| 
 | |
| #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)
 | |
| 
 | |
| COMMON_INS(l, \
 | |
| 	R0 = [P0]; \
 | |
| 	[P1++] = R0; \
 | |
| )
 | |
| 
 | |
| COMMON_INS(w, \
 | |
| 	R0 = W[P0]; \
 | |
| 	W[P1++] = R0; \
 | |
| )
 | |
| 
 | |
| COMMON_INS(w_8, \
 | |
| 	R0 = W[P0]; \
 | |
| 	B[P1++] = R0; \
 | |
| 	R0 = R0 >> 8; \
 | |
| 	B[P1++] = R0; \
 | |
| )
 | |
| 
 | |
| COMMON_INS(b, \
 | |
| 	R0 = B[P0]; \
 | |
| 	B[P1++] = R0; \
 | |
| )
 | |
| 
 | |
| COMMON_INS(l_16, \
 | |
| 	R0 = [P0]; \
 | |
| 	W[P1++] = R0; \
 | |
| 	R0 = R0 >> 16; \
 | |
| 	W[P1++] = R0; \
 | |
| )
 |