GNU Linux-libre 4.19.314-gnu1
[releases.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
12 /*
13  * r8  = bit 0-15: tx offset, bit 16-31: tx buffer size
14  * r9  = bit 0-15: rx offset, bit 16-31: rx buffer size
15  */
16
17 #define SSI_STX0        0x00
18 #define SSI_SRX0        0x08
19 #define SSI_SISR        0x14
20 #define SSI_SIER        0x18
21 #define SSI_SACNT       0x38
22
23 #define SSI_SACNT_AC97EN        (1 << 0)
24
25 #define SSI_SIER_TFE0_EN        (1 << 0)
26 #define SSI_SISR_TFE0           (1 << 0)
27 #define SSI_SISR_RFF0           (1 << 2)
28 #define SSI_SIER_RFF0_EN        (1 << 2)
29
30                 .text
31                 .global imx_ssi_fiq_start
32                 .global imx_ssi_fiq_end
33                 .global imx_ssi_fiq_base
34                 .global imx_ssi_fiq_rx_buffer
35                 .global imx_ssi_fiq_tx_buffer
36
37 /*
38  * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol
39  * using ENDPROC().  imx_ssi_fiq_start and imx_ssi_fiq_end are used to
40  * mark the function body so that it can be copied to the FIQ vector in
41  * the vectors page.  imx_ssi_fiq_start should only be called as the result
42  * of an FIQ: calling it directly will not work.
43  */
44 imx_ssi_fiq_start:
45                 ldr r12, .L_imx_ssi_fiq_base
46
47                 /* TX */
48                 ldr r13, .L_imx_ssi_fiq_tx_buffer
49
50                 /* shall we send? */
51                 ldr r11, [r12, #SSI_SIER]
52                 tst r11, #SSI_SIER_TFE0_EN
53                 beq 1f
54
55                 /* TX FIFO empty? */
56                 ldr r11, [r12, #SSI_SISR]
57                 tst r11, #SSI_SISR_TFE0
58                 beq 1f
59
60                 mov r10, #0x10000
61                 sub r10, #1
62                 and r10, r10, r8        /* r10: current buffer offset */
63
64                 add r13, r13, r10
65
66                 ldrh r11, [r13]
67                 strh r11, [r12, #SSI_STX0]
68
69                 ldrh r11, [r13, #2]
70                 strh r11, [r12, #SSI_STX0]
71
72                 ldrh r11, [r13, #4]
73                 strh r11, [r12, #SSI_STX0]
74
75                 ldrh r11, [r13, #6]
76                 strh r11, [r12, #SSI_STX0]
77
78                 add r10, #8
79                 lsr r11, r8, #16        /* r11: buffer size */
80                 cmp r10, r11
81                 lslgt r8, r11, #16
82                 addle r8, #8
83 1:
84                 /* RX */
85
86                 /* shall we receive? */
87                 ldr r11, [r12, #SSI_SIER]
88                 tst r11, #SSI_SIER_RFF0_EN
89                 beq 1f
90
91                 /* RX FIFO full? */
92                 ldr r11, [r12, #SSI_SISR]
93                 tst r11, #SSI_SISR_RFF0
94                 beq 1f
95
96                 ldr r13, .L_imx_ssi_fiq_rx_buffer
97
98                 mov r10, #0x10000
99                 sub r10, #1
100                 and r10, r10, r9        /* r10: current buffer offset */
101
102                 add r13, r13, r10
103
104                 ldr r11, [r12, #SSI_SACNT]
105                 tst r11, #SSI_SACNT_AC97EN
106
107                 ldr r11, [r12, #SSI_SRX0]
108                 strh r11, [r13]
109
110                 ldr r11, [r12, #SSI_SRX0]
111                 strh r11, [r13, #2]
112
113                 /* dummy read to skip slot 12 */
114                 ldrne r11, [r12, #SSI_SRX0]
115
116                 ldr r11, [r12, #SSI_SRX0]
117                 strh r11, [r13, #4]
118
119                 ldr r11, [r12, #SSI_SRX0]
120                 strh r11, [r13, #6]
121
122                 /* dummy read to skip slot 12 */
123                 ldrne r11, [r12, #SSI_SRX0]
124
125                 add r10, #8
126                 lsr r11, r9, #16        /* r11: buffer size */
127                 cmp r10, r11
128                 lslgt r9, r11, #16
129                 addle r9, #8
130
131 1:
132                 @ return from FIQ
133                 subs    pc, lr, #4
134
135                 .align
136 .L_imx_ssi_fiq_base:
137 imx_ssi_fiq_base:
138                 .word 0x0
139 .L_imx_ssi_fiq_rx_buffer:
140 imx_ssi_fiq_rx_buffer:
141                 .word 0x0
142 .L_imx_ssi_fiq_tx_buffer:
143 imx_ssi_fiq_tx_buffer:
144                 .word 0x0
145 .L_imx_ssi_fiq_end:
146 imx_ssi_fiq_end:
147