Blackfin: shutdown video DMA when booting Linux
[oweals/u-boot.git] / arch / blackfin / lib / ins.S
1 /*
2  * arch/blackfin/lib/ins.S - ins{bwl} using hardware loops
3  *
4  * Copyright 2004-2008 Analog Devices Inc.
5  * Copyright (C) 2005 Bas Vermeulen, BuyWays BV <bas@buyways.nl>
6  * Licensed under the GPL-2 or later.
7  */
8
9 #include <asm/blackfin.h>
10
11 .align 2
12
13 #ifdef CONFIG_IPIPE
14 # define DO_CLI \
15         [--sp] = rets; \
16         [--sp] = (P5:0); \
17         sp += -12; \
18         call ___ipipe_disable_root_irqs_hw; \
19         sp += 12; \
20         (P5:0) = [sp++];
21 # define CLI_INNER_NOP
22 #else
23 # define DO_CLI cli R3;
24 # define CLI_INNER_NOP nop; nop; nop;
25 #endif
26
27 #ifdef CONFIG_IPIPE
28 # define DO_STI \
29         sp += -12; \
30         call ___ipipe_enable_root_irqs_hw; \
31         sp += 12; \
32 2:      rets = [sp++];
33 #else
34 # define DO_STI 2: sti R3;
35 #endif
36
37 #ifdef CONFIG_BFIN_INS_LOWOVERHEAD
38 # define CLI_OUTER DO_CLI;
39 # define STI_OUTER DO_STI;
40 # define CLI_INNER 1:
41 # if ANOMALY_05000416
42 #  define STI_INNER nop; 2: nop;
43 # else
44 #  define STI_INNER 2:
45 # endif
46 #else
47 # define CLI_OUTER
48 # define STI_OUTER
49 # define CLI_INNER 1: DO_CLI; CLI_INNER_NOP;
50 # define STI_INNER DO_STI;
51 #endif
52
53 /*
54  * Reads on the Blackfin are speculative. In Blackfin terms, this means they
55  * can be interrupted at any time (even after they have been issued on to the
56  * external bus), and re-issued after the interrupt occurs.
57  *
58  * If a FIFO is sitting on the end of the read, it will see two reads,
59  * when the core only sees one. The FIFO receives the read which is cancelled,
60  * and not delivered to the core.
61  *
62  * To solve this, interrupts are turned off before reads occur to I/O space.
63  * There are 3 versions of all these functions
64  *  - turns interrupts off every read (higher overhead, but lower latency)
65  *  - turns interrupts off every loop (low overhead, but longer latency)
66  *  - DMA version, which do not suffer from this issue. DMA versions have
67  *      different name (prefixed by dma_ ), and are located in
68  *      ../kernel/bfin_dma_5xx.c
69  * Using the dma related functions are recommended for transfering large
70  * buffers in/out of FIFOs.
71  */
72
73 #define COMMON_INS(func, ops) \
74 ENTRY(_ins##func) \
75         P0 = R0;        /* P0 = port */ \
76         CLI_OUTER;      /* 3 instructions before first read access */ \
77         P1 = R1;        /* P1 = address */ \
78         P2 = R2;        /* P2 = count */ \
79         SSYNC; \
80  \
81         LSETUP(1f, 2f) LC0 = P2; \
82         CLI_INNER; \
83         ops; \
84         STI_INNER; \
85  \
86         STI_OUTER; \
87         RTS; \
88 ENDPROC(_ins##func)
89
90 COMMON_INS(l, \
91         R0 = [P0]; \
92         [P1++] = R0; \
93 )
94
95 COMMON_INS(w, \
96         R0 = W[P0]; \
97         W[P1++] = R0; \
98 )
99
100 COMMON_INS(w_8, \
101         R0 = W[P0]; \
102         B[P1++] = R0; \
103         R0 = R0 >> 8; \
104         B[P1++] = R0; \
105 )
106
107 COMMON_INS(b, \
108         R0 = B[P0]; \
109         B[P1++] = R0; \
110 )
111
112 COMMON_INS(l_16, \
113         R0 = [P0]; \
114         W[P1++] = R0; \
115         R0 = R0 >> 16; \
116         W[P1++] = R0; \
117 )