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
37imx_ssi_fiq_start:
38		ldr r12, imx_ssi_fiq_base
39
40		/* TX */
41		ldr r11, imx_ssi_fiq_tx_buffer
42
43		/* shall we send? */
44		ldr r13, [r12, #SSI_SIER]
45		tst r13, #SSI_SIER_TFE0_EN
46		beq 1f
47
48		/* TX FIFO empty? */
49		ldr r13, [r12, #SSI_SISR]
50		tst r13, #SSI_SISR_TFE0
51		beq 1f
52
53		mov r10, #0x10000
54		sub r10, #1
55		and r10, r10, r8	/* r10: current buffer offset */
56
57		add r11, r11, r10
58
59		ldrh r13, [r11]
60		strh r13, [r12, #SSI_STX0]
61
62		ldrh r13, [r11, #2]
63		strh r13, [r12, #SSI_STX0]
64
65		ldrh r13, [r11, #4]
66		strh r13, [r12, #SSI_STX0]
67
68		ldrh r13, [r11, #6]
69		strh r13, [r12, #SSI_STX0]
70
71		add r10, #8
72		lsr r13, r8, #16	/* r13: buffer size */
73		cmp r10, r13
74		lslgt r8, r13, #16
75		addle r8, #8
761:
77		/* RX */
78
79		/* shall we receive? */
80		ldr r13, [r12, #SSI_SIER]
81		tst r13, #SSI_SIER_RFF0_EN
82		beq 1f
83
84		/* RX FIFO full? */
85		ldr r13, [r12, #SSI_SISR]
86		tst r13, #SSI_SISR_RFF0
87		beq 1f
88
89		ldr r11, imx_ssi_fiq_rx_buffer
90
91		mov r10, #0x10000
92		sub r10, #1
93		and r10, r10, r9	/* r10: current buffer offset */
94
95		add r11, r11, r10
96
97		ldr r13, [r12, #SSI_SACNT]
98		tst r13, #SSI_SACNT_AC97EN
99
100		ldr r13, [r12, #SSI_SRX0]
101		strh r13, [r11]
102
103		ldr r13, [r12, #SSI_SRX0]
104		strh r13, [r11, #2]
105
106		/* dummy read to skip slot 12 */
107		ldrne r13, [r12, #SSI_SRX0]
108
109		ldr r13, [r12, #SSI_SRX0]
110		strh r13, [r11, #4]
111
112		ldr r13, [r12, #SSI_SRX0]
113		strh r13, [r11, #6]
114
115		/* dummy read to skip slot 12 */
116		ldrne r13, [r12, #SSI_SRX0]
117
118		add r10, #8
119		lsr r13, r9, #16	/* r13: buffer size */
120		cmp r10, r13
121		lslgt r9, r13, #16
122		addle r9, #8
123
1241:
125		@ return from FIQ
126		subs	pc, lr, #4
127
128		.align
129imx_ssi_fiq_base:
130		.word 0x0
131imx_ssi_fiq_rx_buffer:
132		.word 0x0
133imx_ssi_fiq_tx_buffer:
134		.word 0x0
135imx_ssi_fiq_end:
136
137