mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
2.8 KiB
144 lines
2.8 KiB
/* SPDX-License-Identifier: GPL-2.0-only */ |
|
/* |
|
* Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de> |
|
*/ |
|
|
|
#include <linux/linkage.h> |
|
#include <asm/assembler.h> |
|
|
|
/* |
|
* r8 = bit 0-15: tx offset, bit 16-31: tx buffer size |
|
* r9 = bit 0-15: rx offset, bit 16-31: rx buffer size |
|
*/ |
|
|
|
#define SSI_STX0 0x00 |
|
#define SSI_SRX0 0x08 |
|
#define SSI_SISR 0x14 |
|
#define SSI_SIER 0x18 |
|
#define SSI_SACNT 0x38 |
|
|
|
#define SSI_SACNT_AC97EN (1 << 0) |
|
|
|
#define SSI_SIER_TFE0_EN (1 << 0) |
|
#define SSI_SISR_TFE0 (1 << 0) |
|
#define SSI_SISR_RFF0 (1 << 2) |
|
#define SSI_SIER_RFF0_EN (1 << 2) |
|
|
|
.text |
|
.global imx_ssi_fiq_start |
|
.global imx_ssi_fiq_end |
|
.global imx_ssi_fiq_base |
|
.global imx_ssi_fiq_rx_buffer |
|
.global imx_ssi_fiq_tx_buffer |
|
|
|
/* |
|
* imx_ssi_fiq_start is _intentionally_ not marked as a function symbol |
|
* using ENDPROC(). imx_ssi_fiq_start and imx_ssi_fiq_end are used to |
|
* mark the function body so that it can be copied to the FIQ vector in |
|
* the vectors page. imx_ssi_fiq_start should only be called as the result |
|
* of an FIQ: calling it directly will not work. |
|
*/ |
|
imx_ssi_fiq_start: |
|
ldr r12, .L_imx_ssi_fiq_base |
|
|
|
/* TX */ |
|
ldr r13, .L_imx_ssi_fiq_tx_buffer |
|
|
|
/* shall we send? */ |
|
ldr r11, [r12, #SSI_SIER] |
|
tst r11, #SSI_SIER_TFE0_EN |
|
beq 1f |
|
|
|
/* TX FIFO empty? */ |
|
ldr r11, [r12, #SSI_SISR] |
|
tst r11, #SSI_SISR_TFE0 |
|
beq 1f |
|
|
|
mov r10, #0x10000 |
|
sub r10, #1 |
|
and r10, r10, r8 /* r10: current buffer offset */ |
|
|
|
add r13, r13, r10 |
|
|
|
ldrh r11, [r13] |
|
strh r11, [r12, #SSI_STX0] |
|
|
|
ldrh r11, [r13, #2] |
|
strh r11, [r12, #SSI_STX0] |
|
|
|
ldrh r11, [r13, #4] |
|
strh r11, [r12, #SSI_STX0] |
|
|
|
ldrh r11, [r13, #6] |
|
strh r11, [r12, #SSI_STX0] |
|
|
|
add r10, #8 |
|
lsr r11, r8, #16 /* r11: buffer size */ |
|
cmp r10, r11 |
|
lslgt r8, r11, #16 |
|
addle r8, #8 |
|
1: |
|
/* RX */ |
|
|
|
/* shall we receive? */ |
|
ldr r11, [r12, #SSI_SIER] |
|
tst r11, #SSI_SIER_RFF0_EN |
|
beq 1f |
|
|
|
/* RX FIFO full? */ |
|
ldr r11, [r12, #SSI_SISR] |
|
tst r11, #SSI_SISR_RFF0 |
|
beq 1f |
|
|
|
ldr r13, .L_imx_ssi_fiq_rx_buffer |
|
|
|
mov r10, #0x10000 |
|
sub r10, #1 |
|
and r10, r10, r9 /* r10: current buffer offset */ |
|
|
|
add r13, r13, r10 |
|
|
|
ldr r11, [r12, #SSI_SACNT] |
|
tst r11, #SSI_SACNT_AC97EN |
|
|
|
ldr r11, [r12, #SSI_SRX0] |
|
strh r11, [r13] |
|
|
|
ldr r11, [r12, #SSI_SRX0] |
|
strh r11, [r13, #2] |
|
|
|
/* dummy read to skip slot 12 */ |
|
ldrne r11, [r12, #SSI_SRX0] |
|
|
|
ldr r11, [r12, #SSI_SRX0] |
|
strh r11, [r13, #4] |
|
|
|
ldr r11, [r12, #SSI_SRX0] |
|
strh r11, [r13, #6] |
|
|
|
/* dummy read to skip slot 12 */ |
|
ldrne r11, [r12, #SSI_SRX0] |
|
|
|
add r10, #8 |
|
lsr r11, r9, #16 /* r11: buffer size */ |
|
cmp r10, r11 |
|
lslgt r9, r11, #16 |
|
addle r9, #8 |
|
|
|
1: |
|
@ return from FIQ |
|
subs pc, lr, #4 |
|
|
|
.align |
|
.L_imx_ssi_fiq_base: |
|
imx_ssi_fiq_base: |
|
.word 0x0 |
|
.L_imx_ssi_fiq_rx_buffer: |
|
imx_ssi_fiq_rx_buffer: |
|
.word 0x0 |
|
.L_imx_ssi_fiq_tx_buffer: |
|
imx_ssi_fiq_tx_buffer: |
|
.word 0x0 |
|
.L_imx_ssi_fiq_end: |
|
imx_ssi_fiq_end: |
|
|
|
|