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