linux/arch/arm/mach-imx/ssi-fiq.S
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License version 2 as
   6 * published by the Free Software Foundation.
   7 */
   8
   9#include <linux/linkage.h>
  10#include <asm/assembler.h>
  11
  12/*
  13 * r8  = bit 0-15: tx offset, bit 16-31: tx buffer size
  14 * r9  = bit 0-15: rx offset, bit 16-31: rx buffer size
  15 */
  16
  17#define SSI_STX0        0x00
  18#define SSI_SRX0        0x08
  19#define SSI_SISR        0x14
  20#define SSI_SIER        0x18
  21#define SSI_SACNT       0x38
  22
  23#define SSI_SACNT_AC97EN        (1 << 0)
  24
  25#define SSI_SIER_TFE0_EN        (1 << 0)
  26#define SSI_SISR_TFE0           (1 << 0)
  27#define SSI_SISR_RFF0           (1 << 2)
  28#define SSI_SIER_RFF0_EN        (1 << 2)
  29
  30                .text
  31                .global imx_ssi_fiq_start
  32                .global imx_ssi_fiq_end
  33                .global imx_ssi_fiq_base
  34                .global imx_ssi_fiq_rx_buffer
  35                .global imx_ssi_fiq_tx_buffer
  36
  37/*
  38 * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol
  39 * using ENDPROC().  imx_ssi_fiq_start and imx_ssi_fiq_end are used to
  40 * mark the function body so that it can be copied to the FIQ vector in
  41 * the vectors page.  imx_ssi_fiq_start should only be called as the result
  42 * of an FIQ: calling it directly will not work.
  43 */
  44imx_ssi_fiq_start:
  45                ldr r12, .L_imx_ssi_fiq_base
  46
  47                /* TX */
  48                ldr r13, .L_imx_ssi_fiq_tx_buffer
  49
  50                /* shall we send? */
  51                ldr r11, [r12, #SSI_SIER]
  52                tst r11, #SSI_SIER_TFE0_EN
  53                beq 1f
  54
  55                /* TX FIFO empty? */
  56                ldr r11, [r12, #SSI_SISR]
  57                tst r11, #SSI_SISR_TFE0
  58                beq 1f
  59
  60                mov r10, #0x10000
  61                sub r10, #1
  62                and r10, r10, r8        /* r10: current buffer offset */
  63
  64                add r13, r13, r10
  65
  66                ldrh r11, [r13]
  67                strh r11, [r12, #SSI_STX0]
  68
  69                ldrh r11, [r13, #2]
  70                strh r11, [r12, #SSI_STX0]
  71
  72                ldrh r11, [r13, #4]
  73                strh r11, [r12, #SSI_STX0]
  74
  75                ldrh r11, [r13, #6]
  76                strh r11, [r12, #SSI_STX0]
  77
  78                add r10, #8
  79                lsr r11, r8, #16        /* r11: buffer size */
  80                cmp r10, r11
  81                lslgt r8, r11, #16
  82                addle r8, #8
  831:
  84                /* RX */
  85
  86                /* shall we receive? */
  87                ldr r11, [r12, #SSI_SIER]
  88                tst r11, #SSI_SIER_RFF0_EN
  89                beq 1f
  90
  91                /* RX FIFO full? */
  92                ldr r11, [r12, #SSI_SISR]
  93                tst r11, #SSI_SISR_RFF0
  94                beq 1f
  95
  96                ldr r13, .L_imx_ssi_fiq_rx_buffer
  97
  98                mov r10, #0x10000
  99                sub r10, #1
 100                and r10, r10, r9        /* r10: current buffer offset */
 101
 102                add r13, r13, r10
 103
 104                ldr r11, [r12, #SSI_SACNT]
 105                tst r11, #SSI_SACNT_AC97EN
 106
 107                ldr r11, [r12, #SSI_SRX0]
 108                strh r11, [r13]
 109
 110                ldr r11, [r12, #SSI_SRX0]
 111                strh r11, [r13, #2]
 112
 113                /* dummy read to skip slot 12 */
 114                ldrne r11, [r12, #SSI_SRX0]
 115
 116                ldr r11, [r12, #SSI_SRX0]
 117                strh r11, [r13, #4]
 118
 119                ldr r11, [r12, #SSI_SRX0]
 120                strh r11, [r13, #6]
 121
 122                /* dummy read to skip slot 12 */
 123                ldrne r11, [r12, #SSI_SRX0]
 124
 125                add r10, #8
 126                lsr r11, r9, #16        /* r11: buffer size */
 127                cmp r10, r11
 128                lslgt r9, r11, #16
 129                addle r9, #8
 130
 1311:
 132                @ return from FIQ
 133                subs    pc, lr, #4
 134
 135                .align
 136.L_imx_ssi_fiq_base:
 137imx_ssi_fiq_base:
 138                .word 0x0
 139.L_imx_ssi_fiq_rx_buffer:
 140imx_ssi_fiq_rx_buffer:
 141                .word 0x0
 142.L_imx_ssi_fiq_tx_buffer:
 143imx_ssi_fiq_tx_buffer:
 144                .word 0x0
 145.L_imx_ssi_fiq_end:
 146imx_ssi_fiq_end:
 147
 148