Merge remote-tracking branch 'keys/keys-next'
[deliverable/linux.git] / arch / arm / mach-imx / ssi-fiq.S
1 /*
2 * Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9 #include <linux/linkage.h>
10 #include <asm/assembler.h>
11 #include <asm/export.h>
12
13 /*
14 * r8 = bit 0-15: tx offset, bit 16-31: tx buffer size
15 * r9 = bit 0-15: rx offset, bit 16-31: rx buffer size
16 */
17
18 #define SSI_STX0 0x00
19 #define SSI_SRX0 0x08
20 #define SSI_SISR 0x14
21 #define SSI_SIER 0x18
22 #define SSI_SACNT 0x38
23
24 #define SSI_SACNT_AC97EN (1 << 0)
25
26 #define SSI_SIER_TFE0_EN (1 << 0)
27 #define SSI_SISR_TFE0 (1 << 0)
28 #define SSI_SISR_RFF0 (1 << 2)
29 #define SSI_SIER_RFF0_EN (1 << 2)
30
31 .text
32 .global imx_ssi_fiq_start
33 .global imx_ssi_fiq_end
34 .global imx_ssi_fiq_base
35 .global imx_ssi_fiq_rx_buffer
36 .global imx_ssi_fiq_tx_buffer
37
38 /*
39 * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol
40 * using ENDPROC(). imx_ssi_fiq_start and imx_ssi_fiq_end are used to
41 * mark the function body so that it can be copied to the FIQ vector in
42 * the vectors page. imx_ssi_fiq_start should only be called as the result
43 * of an FIQ: calling it directly will not work.
44 */
45 imx_ssi_fiq_start:
46 ldr r12, .L_imx_ssi_fiq_base
47
48 /* TX */
49 ldr r13, .L_imx_ssi_fiq_tx_buffer
50
51 /* shall we send? */
52 ldr r11, [r12, #SSI_SIER]
53 tst r11, #SSI_SIER_TFE0_EN
54 beq 1f
55
56 /* TX FIFO empty? */
57 ldr r11, [r12, #SSI_SISR]
58 tst r11, #SSI_SISR_TFE0
59 beq 1f
60
61 mov r10, #0x10000
62 sub r10, #1
63 and r10, r10, r8 /* r10: current buffer offset */
64
65 add r13, r13, r10
66
67 ldrh r11, [r13]
68 strh r11, [r12, #SSI_STX0]
69
70 ldrh r11, [r13, #2]
71 strh r11, [r12, #SSI_STX0]
72
73 ldrh r11, [r13, #4]
74 strh r11, [r12, #SSI_STX0]
75
76 ldrh r11, [r13, #6]
77 strh r11, [r12, #SSI_STX0]
78
79 add r10, #8
80 lsr r11, r8, #16 /* r11: buffer size */
81 cmp r10, r11
82 lslgt r8, r11, #16
83 addle r8, #8
84 1:
85 /* RX */
86
87 /* shall we receive? */
88 ldr r11, [r12, #SSI_SIER]
89 tst r11, #SSI_SIER_RFF0_EN
90 beq 1f
91
92 /* RX FIFO full? */
93 ldr r11, [r12, #SSI_SISR]
94 tst r11, #SSI_SISR_RFF0
95 beq 1f
96
97 ldr r13, .L_imx_ssi_fiq_rx_buffer
98
99 mov r10, #0x10000
100 sub r10, #1
101 and r10, r10, r9 /* r10: current buffer offset */
102
103 add r13, r13, r10
104
105 ldr r11, [r12, #SSI_SACNT]
106 tst r11, #SSI_SACNT_AC97EN
107
108 ldr r11, [r12, #SSI_SRX0]
109 strh r11, [r13]
110
111 ldr r11, [r12, #SSI_SRX0]
112 strh r11, [r13, #2]
113
114 /* dummy read to skip slot 12 */
115 ldrne r11, [r12, #SSI_SRX0]
116
117 ldr r11, [r12, #SSI_SRX0]
118 strh r11, [r13, #4]
119
120 ldr r11, [r12, #SSI_SRX0]
121 strh r11, [r13, #6]
122
123 /* dummy read to skip slot 12 */
124 ldrne r11, [r12, #SSI_SRX0]
125
126 add r10, #8
127 lsr r11, r9, #16 /* r11: buffer size */
128 cmp r10, r11
129 lslgt r9, r11, #16
130 addle r9, #8
131
132 1:
133 @ return from FIQ
134 subs pc, lr, #4
135
136 .align
137 .L_imx_ssi_fiq_base:
138 imx_ssi_fiq_base:
139 .word 0x0
140 .L_imx_ssi_fiq_rx_buffer:
141 imx_ssi_fiq_rx_buffer:
142 .word 0x0
143 .L_imx_ssi_fiq_tx_buffer:
144 imx_ssi_fiq_tx_buffer:
145 .word 0x0
146 .L_imx_ssi_fiq_end:
147 imx_ssi_fiq_end:
148 EXPORT_SYMBOL(imx_ssi_fiq_tx_buffer)
149 EXPORT_SYMBOL(imx_ssi_fiq_rx_buffer)
150 EXPORT_SYMBOL(imx_ssi_fiq_start)
151 EXPORT_SYMBOL(imx_ssi_fiq_end)
152 EXPORT_SYMBOL(imx_ssi_fiq_base)
This page took 0.048867 seconds and 5 git commands to generate.