Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *  Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
0004  */
0005 
0006 #include <linux/linkage.h>
0007 #include <asm/assembler.h>
0008 
0009 /*
0010  * r8  = bit 0-15: tx offset, bit 16-31: tx buffer size
0011  * r9  = bit 0-15: rx offset, bit 16-31: rx buffer size
0012  */
0013 
0014 #define SSI_STX0    0x00
0015 #define SSI_SRX0    0x08
0016 #define SSI_SISR    0x14
0017 #define SSI_SIER    0x18
0018 #define SSI_SACNT   0x38
0019 
0020 #define SSI_SACNT_AC97EN    (1 << 0)
0021 
0022 #define SSI_SIER_TFE0_EN    (1 << 0)
0023 #define SSI_SISR_TFE0       (1 << 0)
0024 #define SSI_SISR_RFF0       (1 << 2)
0025 #define SSI_SIER_RFF0_EN    (1 << 2)
0026 
0027         .text
0028         .global imx_ssi_fiq_start
0029         .global imx_ssi_fiq_end
0030         .global imx_ssi_fiq_base
0031         .global imx_ssi_fiq_rx_buffer
0032         .global imx_ssi_fiq_tx_buffer
0033 
0034 /*
0035  * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol
0036  * using ENDPROC().  imx_ssi_fiq_start and imx_ssi_fiq_end are used to
0037  * mark the function body so that it can be copied to the FIQ vector in
0038  * the vectors page.  imx_ssi_fiq_start should only be called as the result
0039  * of an FIQ: calling it directly will not work.
0040  */
0041 imx_ssi_fiq_start:
0042         ldr r12, .L_imx_ssi_fiq_base
0043 
0044         /* TX */
0045         ldr r13, .L_imx_ssi_fiq_tx_buffer
0046 
0047         /* shall we send? */
0048         ldr r11, [r12, #SSI_SIER]
0049         tst r11, #SSI_SIER_TFE0_EN
0050         beq 1f
0051 
0052         /* TX FIFO empty? */
0053         ldr r11, [r12, #SSI_SISR]
0054         tst r11, #SSI_SISR_TFE0
0055         beq 1f
0056 
0057         mov r10, #0x10000
0058         sub r10, #1
0059         and r10, r10, r8    /* r10: current buffer offset */
0060 
0061         add r13, r13, r10
0062 
0063         ldrh r11, [r13]
0064         strh r11, [r12, #SSI_STX0]
0065 
0066         ldrh r11, [r13, #2]
0067         strh r11, [r12, #SSI_STX0]
0068 
0069         ldrh r11, [r13, #4]
0070         strh r11, [r12, #SSI_STX0]
0071 
0072         ldrh r11, [r13, #6]
0073         strh r11, [r12, #SSI_STX0]
0074 
0075         add r10, #8
0076         lsr r11, r8, #16    /* r11: buffer size */
0077         cmp r10, r11
0078         lslgt r8, r11, #16
0079         addle r8, #8
0080 1:
0081         /* RX */
0082 
0083         /* shall we receive? */
0084         ldr r11, [r12, #SSI_SIER]
0085         tst r11, #SSI_SIER_RFF0_EN
0086         beq 1f
0087 
0088         /* RX FIFO full? */
0089         ldr r11, [r12, #SSI_SISR]
0090         tst r11, #SSI_SISR_RFF0
0091         beq 1f
0092 
0093         ldr r13, .L_imx_ssi_fiq_rx_buffer
0094 
0095         mov r10, #0x10000
0096         sub r10, #1
0097         and r10, r10, r9    /* r10: current buffer offset */
0098 
0099         add r13, r13, r10
0100 
0101         ldr r11, [r12, #SSI_SACNT]
0102         tst r11, #SSI_SACNT_AC97EN
0103 
0104         ldr r11, [r12, #SSI_SRX0]
0105         strh r11, [r13]
0106 
0107         ldr r11, [r12, #SSI_SRX0]
0108         strh r11, [r13, #2]
0109 
0110         /* dummy read to skip slot 12 */
0111         ldrne r11, [r12, #SSI_SRX0]
0112 
0113         ldr r11, [r12, #SSI_SRX0]
0114         strh r11, [r13, #4]
0115 
0116         ldr r11, [r12, #SSI_SRX0]
0117         strh r11, [r13, #6]
0118 
0119         /* dummy read to skip slot 12 */
0120         ldrne r11, [r12, #SSI_SRX0]
0121 
0122         add r10, #8
0123         lsr r11, r9, #16    /* r11: buffer size */
0124         cmp r10, r11
0125         lslgt r9, r11, #16
0126         addle r9, #8
0127 
0128 1:
0129         @ return from FIQ
0130         subs    pc, lr, #4
0131 
0132         .align
0133 .L_imx_ssi_fiq_base:
0134 imx_ssi_fiq_base:
0135         .word 0x0
0136 .L_imx_ssi_fiq_rx_buffer:
0137 imx_ssi_fiq_rx_buffer:
0138         .word 0x0
0139 .L_imx_ssi_fiq_tx_buffer:
0140 imx_ssi_fiq_tx_buffer:
0141         .word 0x0
0142 .L_imx_ssi_fiq_end:
0143 imx_ssi_fiq_end:
0144