xref: /openbmc/linux/arch/arm/mach-imx/ssi-fiq.S (revision d2912cb1)
1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
23995eb82SShawn Guo/*
33995eb82SShawn Guo *  Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
43995eb82SShawn Guo */
53995eb82SShawn Guo
63995eb82SShawn Guo#include <linux/linkage.h>
73995eb82SShawn Guo#include <asm/assembler.h>
83995eb82SShawn Guo
93995eb82SShawn Guo/*
103995eb82SShawn Guo * r8  = bit 0-15: tx offset, bit 16-31: tx buffer size
113995eb82SShawn Guo * r9  = bit 0-15: rx offset, bit 16-31: rx buffer size
123995eb82SShawn Guo */
133995eb82SShawn Guo
143995eb82SShawn Guo#define SSI_STX0	0x00
153995eb82SShawn Guo#define SSI_SRX0	0x08
163995eb82SShawn Guo#define SSI_SISR	0x14
173995eb82SShawn Guo#define SSI_SIER	0x18
183995eb82SShawn Guo#define SSI_SACNT	0x38
193995eb82SShawn Guo
203995eb82SShawn Guo#define SSI_SACNT_AC97EN	(1 << 0)
213995eb82SShawn Guo
223995eb82SShawn Guo#define SSI_SIER_TFE0_EN	(1 << 0)
233995eb82SShawn Guo#define SSI_SISR_TFE0		(1 << 0)
243995eb82SShawn Guo#define SSI_SISR_RFF0		(1 << 2)
253995eb82SShawn Guo#define SSI_SIER_RFF0_EN	(1 << 2)
263995eb82SShawn Guo
273995eb82SShawn Guo		.text
283995eb82SShawn Guo		.global	imx_ssi_fiq_start
293995eb82SShawn Guo		.global	imx_ssi_fiq_end
303995eb82SShawn Guo		.global imx_ssi_fiq_base
313995eb82SShawn Guo		.global imx_ssi_fiq_rx_buffer
323995eb82SShawn Guo		.global imx_ssi_fiq_tx_buffer
333995eb82SShawn Guo
343995eb82SShawn Guo/*
353995eb82SShawn Guo * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol
363995eb82SShawn Guo * using ENDPROC().  imx_ssi_fiq_start and imx_ssi_fiq_end are used to
373995eb82SShawn Guo * mark the function body so that it can be copied to the FIQ vector in
383995eb82SShawn Guo * the vectors page.  imx_ssi_fiq_start should only be called as the result
393995eb82SShawn Guo * of an FIQ: calling it directly will not work.
403995eb82SShawn Guo */
413995eb82SShawn Guoimx_ssi_fiq_start:
423995eb82SShawn Guo		ldr r12, .L_imx_ssi_fiq_base
433995eb82SShawn Guo
443995eb82SShawn Guo		/* TX */
453995eb82SShawn Guo		ldr r13, .L_imx_ssi_fiq_tx_buffer
463995eb82SShawn Guo
473995eb82SShawn Guo		/* shall we send? */
483995eb82SShawn Guo		ldr r11, [r12, #SSI_SIER]
493995eb82SShawn Guo		tst r11, #SSI_SIER_TFE0_EN
503995eb82SShawn Guo		beq 1f
513995eb82SShawn Guo
523995eb82SShawn Guo		/* TX FIFO empty? */
533995eb82SShawn Guo		ldr r11, [r12, #SSI_SISR]
543995eb82SShawn Guo		tst r11, #SSI_SISR_TFE0
553995eb82SShawn Guo		beq 1f
563995eb82SShawn Guo
573995eb82SShawn Guo		mov r10, #0x10000
583995eb82SShawn Guo		sub r10, #1
593995eb82SShawn Guo		and r10, r10, r8	/* r10: current buffer offset */
603995eb82SShawn Guo
613995eb82SShawn Guo		add r13, r13, r10
623995eb82SShawn Guo
633995eb82SShawn Guo		ldrh r11, [r13]
643995eb82SShawn Guo		strh r11, [r12, #SSI_STX0]
653995eb82SShawn Guo
663995eb82SShawn Guo		ldrh r11, [r13, #2]
673995eb82SShawn Guo		strh r11, [r12, #SSI_STX0]
683995eb82SShawn Guo
693995eb82SShawn Guo		ldrh r11, [r13, #4]
703995eb82SShawn Guo		strh r11, [r12, #SSI_STX0]
713995eb82SShawn Guo
723995eb82SShawn Guo		ldrh r11, [r13, #6]
733995eb82SShawn Guo		strh r11, [r12, #SSI_STX0]
743995eb82SShawn Guo
753995eb82SShawn Guo		add r10, #8
763995eb82SShawn Guo		lsr r11, r8, #16	/* r11: buffer size */
773995eb82SShawn Guo		cmp r10, r11
783995eb82SShawn Guo		lslgt r8, r11, #16
793995eb82SShawn Guo		addle r8, #8
803995eb82SShawn Guo1:
813995eb82SShawn Guo		/* RX */
823995eb82SShawn Guo
833995eb82SShawn Guo		/* shall we receive? */
843995eb82SShawn Guo		ldr r11, [r12, #SSI_SIER]
853995eb82SShawn Guo		tst r11, #SSI_SIER_RFF0_EN
863995eb82SShawn Guo		beq 1f
873995eb82SShawn Guo
883995eb82SShawn Guo		/* RX FIFO full? */
893995eb82SShawn Guo		ldr r11, [r12, #SSI_SISR]
903995eb82SShawn Guo		tst r11, #SSI_SISR_RFF0
913995eb82SShawn Guo		beq 1f
923995eb82SShawn Guo
933995eb82SShawn Guo		ldr r13, .L_imx_ssi_fiq_rx_buffer
943995eb82SShawn Guo
953995eb82SShawn Guo		mov r10, #0x10000
963995eb82SShawn Guo		sub r10, #1
973995eb82SShawn Guo		and r10, r10, r9	/* r10: current buffer offset */
983995eb82SShawn Guo
993995eb82SShawn Guo		add r13, r13, r10
1003995eb82SShawn Guo
1013995eb82SShawn Guo		ldr r11, [r12, #SSI_SACNT]
1023995eb82SShawn Guo		tst r11, #SSI_SACNT_AC97EN
1033995eb82SShawn Guo
1043995eb82SShawn Guo		ldr r11, [r12, #SSI_SRX0]
1053995eb82SShawn Guo		strh r11, [r13]
1063995eb82SShawn Guo
1073995eb82SShawn Guo		ldr r11, [r12, #SSI_SRX0]
1083995eb82SShawn Guo		strh r11, [r13, #2]
1093995eb82SShawn Guo
1103995eb82SShawn Guo		/* dummy read to skip slot 12 */
1113995eb82SShawn Guo		ldrne r11, [r12, #SSI_SRX0]
1123995eb82SShawn Guo
1133995eb82SShawn Guo		ldr r11, [r12, #SSI_SRX0]
1143995eb82SShawn Guo		strh r11, [r13, #4]
1153995eb82SShawn Guo
1163995eb82SShawn Guo		ldr r11, [r12, #SSI_SRX0]
1173995eb82SShawn Guo		strh r11, [r13, #6]
1183995eb82SShawn Guo
1193995eb82SShawn Guo		/* dummy read to skip slot 12 */
1203995eb82SShawn Guo		ldrne r11, [r12, #SSI_SRX0]
1213995eb82SShawn Guo
1223995eb82SShawn Guo		add r10, #8
1233995eb82SShawn Guo		lsr r11, r9, #16	/* r11: buffer size */
1243995eb82SShawn Guo		cmp r10, r11
1253995eb82SShawn Guo		lslgt r9, r11, #16
1263995eb82SShawn Guo		addle r9, #8
1273995eb82SShawn Guo
1283995eb82SShawn Guo1:
1293995eb82SShawn Guo		@ return from FIQ
1303995eb82SShawn Guo		subs	pc, lr, #4
1313995eb82SShawn Guo
1323995eb82SShawn Guo		.align
1333995eb82SShawn Guo.L_imx_ssi_fiq_base:
1343995eb82SShawn Guoimx_ssi_fiq_base:
1353995eb82SShawn Guo		.word 0x0
1363995eb82SShawn Guo.L_imx_ssi_fiq_rx_buffer:
1373995eb82SShawn Guoimx_ssi_fiq_rx_buffer:
1383995eb82SShawn Guo		.word 0x0
1393995eb82SShawn Guo.L_imx_ssi_fiq_tx_buffer:
1403995eb82SShawn Guoimx_ssi_fiq_tx_buffer:
1413995eb82SShawn Guo		.word 0x0
1423995eb82SShawn Guo.L_imx_ssi_fiq_end:
1433995eb82SShawn Guoimx_ssi_fiq_end:
1448478132aSRussell King
145