18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/linkage.h>
78c2ecf20Sopenharmony_ci#include <asm/assembler.h>
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci/*
108c2ecf20Sopenharmony_ci * r8  = bit 0-15: tx offset, bit 16-31: tx buffer size
118c2ecf20Sopenharmony_ci * r9  = bit 0-15: rx offset, bit 16-31: rx buffer size
128c2ecf20Sopenharmony_ci */
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#define SSI_STX0	0x00
158c2ecf20Sopenharmony_ci#define SSI_SRX0	0x08
168c2ecf20Sopenharmony_ci#define SSI_SISR	0x14
178c2ecf20Sopenharmony_ci#define SSI_SIER	0x18
188c2ecf20Sopenharmony_ci#define SSI_SACNT	0x38
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#define SSI_SACNT_AC97EN	(1 << 0)
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#define SSI_SIER_TFE0_EN	(1 << 0)
238c2ecf20Sopenharmony_ci#define SSI_SISR_TFE0		(1 << 0)
248c2ecf20Sopenharmony_ci#define SSI_SISR_RFF0		(1 << 2)
258c2ecf20Sopenharmony_ci#define SSI_SIER_RFF0_EN	(1 << 2)
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci		.text
288c2ecf20Sopenharmony_ci		.global	imx_ssi_fiq_start
298c2ecf20Sopenharmony_ci		.global	imx_ssi_fiq_end
308c2ecf20Sopenharmony_ci		.global imx_ssi_fiq_base
318c2ecf20Sopenharmony_ci		.global imx_ssi_fiq_rx_buffer
328c2ecf20Sopenharmony_ci		.global imx_ssi_fiq_tx_buffer
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/*
358c2ecf20Sopenharmony_ci * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol
368c2ecf20Sopenharmony_ci * using ENDPROC().  imx_ssi_fiq_start and imx_ssi_fiq_end are used to
378c2ecf20Sopenharmony_ci * mark the function body so that it can be copied to the FIQ vector in
388c2ecf20Sopenharmony_ci * the vectors page.  imx_ssi_fiq_start should only be called as the result
398c2ecf20Sopenharmony_ci * of an FIQ: calling it directly will not work.
408c2ecf20Sopenharmony_ci */
418c2ecf20Sopenharmony_ciimx_ssi_fiq_start:
428c2ecf20Sopenharmony_ci		ldr r12, .L_imx_ssi_fiq_base
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci		/* TX */
458c2ecf20Sopenharmony_ci		ldr r13, .L_imx_ssi_fiq_tx_buffer
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci		/* shall we send? */
488c2ecf20Sopenharmony_ci		ldr r11, [r12, #SSI_SIER]
498c2ecf20Sopenharmony_ci		tst r11, #SSI_SIER_TFE0_EN
508c2ecf20Sopenharmony_ci		beq 1f
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci		/* TX FIFO empty? */
538c2ecf20Sopenharmony_ci		ldr r11, [r12, #SSI_SISR]
548c2ecf20Sopenharmony_ci		tst r11, #SSI_SISR_TFE0
558c2ecf20Sopenharmony_ci		beq 1f
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci		mov r10, #0x10000
588c2ecf20Sopenharmony_ci		sub r10, #1
598c2ecf20Sopenharmony_ci		and r10, r10, r8	/* r10: current buffer offset */
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci		add r13, r13, r10
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci		ldrh r11, [r13]
648c2ecf20Sopenharmony_ci		strh r11, [r12, #SSI_STX0]
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci		ldrh r11, [r13, #2]
678c2ecf20Sopenharmony_ci		strh r11, [r12, #SSI_STX0]
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci		ldrh r11, [r13, #4]
708c2ecf20Sopenharmony_ci		strh r11, [r12, #SSI_STX0]
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci		ldrh r11, [r13, #6]
738c2ecf20Sopenharmony_ci		strh r11, [r12, #SSI_STX0]
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci		add r10, #8
768c2ecf20Sopenharmony_ci		lsr r11, r8, #16	/* r11: buffer size */
778c2ecf20Sopenharmony_ci		cmp r10, r11
788c2ecf20Sopenharmony_ci		lslgt r8, r11, #16
798c2ecf20Sopenharmony_ci		addle r8, #8
808c2ecf20Sopenharmony_ci1:
818c2ecf20Sopenharmony_ci		/* RX */
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci		/* shall we receive? */
848c2ecf20Sopenharmony_ci		ldr r11, [r12, #SSI_SIER]
858c2ecf20Sopenharmony_ci		tst r11, #SSI_SIER_RFF0_EN
868c2ecf20Sopenharmony_ci		beq 1f
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci		/* RX FIFO full? */
898c2ecf20Sopenharmony_ci		ldr r11, [r12, #SSI_SISR]
908c2ecf20Sopenharmony_ci		tst r11, #SSI_SISR_RFF0
918c2ecf20Sopenharmony_ci		beq 1f
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci		ldr r13, .L_imx_ssi_fiq_rx_buffer
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci		mov r10, #0x10000
968c2ecf20Sopenharmony_ci		sub r10, #1
978c2ecf20Sopenharmony_ci		and r10, r10, r9	/* r10: current buffer offset */
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci		add r13, r13, r10
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci		ldr r11, [r12, #SSI_SACNT]
1028c2ecf20Sopenharmony_ci		tst r11, #SSI_SACNT_AC97EN
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci		ldr r11, [r12, #SSI_SRX0]
1058c2ecf20Sopenharmony_ci		strh r11, [r13]
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci		ldr r11, [r12, #SSI_SRX0]
1088c2ecf20Sopenharmony_ci		strh r11, [r13, #2]
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci		/* dummy read to skip slot 12 */
1118c2ecf20Sopenharmony_ci		ldrne r11, [r12, #SSI_SRX0]
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci		ldr r11, [r12, #SSI_SRX0]
1148c2ecf20Sopenharmony_ci		strh r11, [r13, #4]
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci		ldr r11, [r12, #SSI_SRX0]
1178c2ecf20Sopenharmony_ci		strh r11, [r13, #6]
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci		/* dummy read to skip slot 12 */
1208c2ecf20Sopenharmony_ci		ldrne r11, [r12, #SSI_SRX0]
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci		add r10, #8
1238c2ecf20Sopenharmony_ci		lsr r11, r9, #16	/* r11: buffer size */
1248c2ecf20Sopenharmony_ci		cmp r10, r11
1258c2ecf20Sopenharmony_ci		lslgt r9, r11, #16
1268c2ecf20Sopenharmony_ci		addle r9, #8
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci1:
1298c2ecf20Sopenharmony_ci		@ return from FIQ
1308c2ecf20Sopenharmony_ci		subs	pc, lr, #4
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci		.align
1338c2ecf20Sopenharmony_ci.L_imx_ssi_fiq_base:
1348c2ecf20Sopenharmony_ciimx_ssi_fiq_base:
1358c2ecf20Sopenharmony_ci		.word 0x0
1368c2ecf20Sopenharmony_ci.L_imx_ssi_fiq_rx_buffer:
1378c2ecf20Sopenharmony_ciimx_ssi_fiq_rx_buffer:
1388c2ecf20Sopenharmony_ci		.word 0x0
1398c2ecf20Sopenharmony_ci.L_imx_ssi_fiq_tx_buffer:
1408c2ecf20Sopenharmony_ciimx_ssi_fiq_tx_buffer:
1418c2ecf20Sopenharmony_ci		.word 0x0
1428c2ecf20Sopenharmony_ci.L_imx_ssi_fiq_end:
1438c2ecf20Sopenharmony_ciimx_ssi_fiq_end:
1448c2ecf20Sopenharmony_ci
145