2 * arch/blackfin/lib/ins.S - ins{bwl} using hardware loops
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.
9 #include <linux/linkage.h>
10 #include <asm/blackfin.h>
19 call ___ipipe_disable_root_irqs_hw; \
22 # define CLI_INNER_NOP
24 # define DO_CLI cli R3;
25 # define CLI_INNER_NOP nop; nop; nop;
31 call ___ipipe_enable_root_irqs_hw; \
35 # define DO_STI 2: sti R3;
38 #ifdef CONFIG_BFIN_INS_LOWOVERHEAD
39 # define CLI_OUTER DO_CLI;
40 # define STI_OUTER DO_STI;
43 # define STI_INNER nop; 2: nop;
50 # define CLI_INNER 1: DO_CLI; CLI_INNER_NOP;
51 # define STI_INNER DO_STI;
55 * Reads on the Blackfin are speculative. In Blackfin terms, this means they
56 * can be interrupted at any time (even after they have been issued on to the
57 * external bus), and re-issued after the interrupt occurs.
59 * If a FIFO is sitting on the end of the read, it will see two reads,
60 * when the core only sees one. The FIFO receives the read which is cancelled,
61 * and not delivered to the core.
63 * To solve this, interrupts are turned off before reads occur to I/O space.
64 * There are 3 versions of all these functions
65 * - turns interrupts off every read (higher overhead, but lower latency)
66 * - turns interrupts off every loop (low overhead, but longer latency)
67 * - DMA version, which do not suffer from this issue. DMA versions have
68 * different name (prefixed by dma_ ), and are located in
69 * ../kernel/bfin_dma.c
70 * Using the dma related functions are recommended for transferring large
71 * buffers in/out of FIFOs.
74 #define COMMON_INS(func, ops) \
76 P0 = R0; /* P0 = port */ \
77 CLI_OUTER; /* 3 instructions before first read access */ \
78 P1 = R1; /* P1 = address */ \
79 P2 = R2; /* P2 = count */ \
82 LSETUP(1f, 2f) LC0 = P2; \