~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/blackfin/lib/ins.S

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <linux/linkage.h>
 
10
#include <asm/blackfin.h>
 
11
 
 
12
.align 2
 
13
 
 
14
#ifdef CONFIG_IPIPE
 
15
# define DO_CLI \
 
16
        [--sp] = rets; \
 
17
        [--sp] = (P5:0); \
 
18
        sp += -12; \
 
19
        call ___ipipe_disable_root_irqs_hw; \
 
20
        sp += 12; \
 
21
        (P5:0) = [sp++];
 
22
# define CLI_INNER_NOP
 
23
#else
 
24
# define DO_CLI cli R3;
 
25
# define CLI_INNER_NOP nop; nop; nop;
 
26
#endif
 
27
 
 
28
#ifdef CONFIG_IPIPE
 
29
# define DO_STI \
 
30
        sp += -12; \
 
31
        call ___ipipe_enable_root_irqs_hw; \
 
32
        sp += 12; \
 
33
2:      rets = [sp++];
 
34
#else
 
35
# define DO_STI 2: sti R3;
 
36
#endif
 
37
 
 
38
#ifdef CONFIG_BFIN_INS_LOWOVERHEAD
 
39
# define CLI_OUTER DO_CLI;
 
40
# define STI_OUTER DO_STI;
 
41
# define CLI_INNER 1:
 
42
# if ANOMALY_05000416
 
43
#  define STI_INNER nop; 2: nop;
 
44
# else
 
45
#  define STI_INNER 2:
 
46
# endif
 
47
#else
 
48
# define CLI_OUTER
 
49
# define STI_OUTER
 
50
# define CLI_INNER 1: DO_CLI; CLI_INNER_NOP;
 
51
# define STI_INNER DO_STI;
 
52
#endif
 
53
 
 
54
/*
 
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.
 
58
 *
 
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.
 
62
 *
 
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_5xx.c
 
70
 * Using the dma related functions are recommended for transferring large
 
71
 * buffers in/out of FIFOs.
 
72
 */
 
73
 
 
74
#define COMMON_INS(func, ops) \
 
75
ENTRY(_ins##func) \
 
76
        P0 = R0;        /* P0 = port */ \
 
77
        CLI_OUTER;      /* 3 instructions before first read access */ \
 
78
        P1 = R1;        /* P1 = address */ \
 
79
        P2 = R2;        /* P2 = count */ \
 
80
        SSYNC; \
 
81
 \
 
82
        LSETUP(1f, 2f) LC0 = P2; \
 
83
        CLI_INNER; \
 
84
        ops; \
 
85
        STI_INNER; \
 
86
 \
 
87
        STI_OUTER; \
 
88
        RTS; \
 
89
ENDPROC(_ins##func)
 
90
 
 
91
COMMON_INS(l, \
 
92
        R0 = [P0]; \
 
93
        [P1++] = R0; \
 
94
)
 
95
 
 
96
COMMON_INS(w, \
 
97
        R0 = W[P0]; \
 
98
        W[P1++] = R0; \
 
99
)
 
100
 
 
101
COMMON_INS(w_8, \
 
102
        R0 = W[P0]; \
 
103
        B[P1++] = R0; \
 
104
        R0 = R0 >> 8; \
 
105
        B[P1++] = R0; \
 
106
)
 
107
 
 
108
COMMON_INS(b, \
 
109
        R0 = B[P0]; \
 
110
        B[P1++] = R0; \
 
111
)
 
112
 
 
113
COMMON_INS(l_16, \
 
114
        R0 = [P0]; \
 
115
        W[P1++] = R0; \
 
116
        R0 = R0 >> 16; \
 
117
        W[P1++] = R0; \
 
118
)