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: 1473995eb82SShawn Guo 148