ssi-fiq.S 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. #include <linux/linkage.h>
  9. #include <asm/assembler.h>
  10. /*
  11. * r8 = bit 0-15: tx offset, bit 16-31: tx buffer size
  12. * r9 = bit 0-15: rx offset, bit 16-31: rx buffer size
  13. */
  14. #define SSI_STX0 0x00
  15. #define SSI_SRX0 0x08
  16. #define SSI_SISR 0x14
  17. #define SSI_SIER 0x18
  18. #define SSI_SACNT 0x38
  19. #define SSI_SACNT_AC97EN (1 << 0)
  20. #define SSI_SIER_TFE0_EN (1 << 0)
  21. #define SSI_SISR_TFE0 (1 << 0)
  22. #define SSI_SISR_RFF0 (1 << 2)
  23. #define SSI_SIER_RFF0_EN (1 << 2)
  24. .text
  25. .global imx_ssi_fiq_start
  26. .global imx_ssi_fiq_end
  27. .global imx_ssi_fiq_base
  28. .global imx_ssi_fiq_rx_buffer
  29. .global imx_ssi_fiq_tx_buffer
  30. imx_ssi_fiq_start:
  31. ldr r12, imx_ssi_fiq_base
  32. /* TX */
  33. ldr r11, imx_ssi_fiq_tx_buffer
  34. /* shall we send? */
  35. ldr r13, [r12, #SSI_SIER]
  36. tst r13, #SSI_SIER_TFE0_EN
  37. beq 1f
  38. /* TX FIFO empty? */
  39. ldr r13, [r12, #SSI_SISR]
  40. tst r13, #SSI_SISR_TFE0
  41. beq 1f
  42. mov r10, #0x10000
  43. sub r10, #1
  44. and r10, r10, r8 /* r10: current buffer offset */
  45. add r11, r11, r10
  46. ldrh r13, [r11]
  47. strh r13, [r12, #SSI_STX0]
  48. ldrh r13, [r11, #2]
  49. strh r13, [r12, #SSI_STX0]
  50. ldrh r13, [r11, #4]
  51. strh r13, [r12, #SSI_STX0]
  52. ldrh r13, [r11, #6]
  53. strh r13, [r12, #SSI_STX0]
  54. add r10, #8
  55. lsr r13, r8, #16 /* r13: buffer size */
  56. cmp r10, r13
  57. lslgt r8, r13, #16
  58. addle r8, #8
  59. 1:
  60. /* RX */
  61. /* shall we receive? */
  62. ldr r13, [r12, #SSI_SIER]
  63. tst r13, #SSI_SIER_RFF0_EN
  64. beq 1f
  65. /* RX FIFO full? */
  66. ldr r13, [r12, #SSI_SISR]
  67. tst r13, #SSI_SISR_RFF0
  68. beq 1f
  69. ldr r11, imx_ssi_fiq_rx_buffer
  70. mov r10, #0x10000
  71. sub r10, #1
  72. and r10, r10, r9 /* r10: current buffer offset */
  73. add r11, r11, r10
  74. ldr r13, [r12, #SSI_SACNT]
  75. tst r13, #SSI_SACNT_AC97EN
  76. ldr r13, [r12, #SSI_SRX0]
  77. strh r13, [r11]
  78. ldr r13, [r12, #SSI_SRX0]
  79. strh r13, [r11, #2]
  80. /* dummy read to skip slot 12 */
  81. ldrne r13, [r12, #SSI_SRX0]
  82. ldr r13, [r12, #SSI_SRX0]
  83. strh r13, [r11, #4]
  84. ldr r13, [r12, #SSI_SRX0]
  85. strh r13, [r11, #6]
  86. /* dummy read to skip slot 12 */
  87. ldrne r13, [r12, #SSI_SRX0]
  88. add r10, #8
  89. lsr r13, r9, #16 /* r13: buffer size */
  90. cmp r10, r13
  91. lslgt r9, r13, #16
  92. addle r9, #8
  93. 1:
  94. @ return from FIQ
  95. subs pc, lr, #4
  96. .align
  97. imx_ssi_fiq_base:
  98. .word 0x0
  99. imx_ssi_fiq_rx_buffer:
  100. .word 0x0
  101. imx_ssi_fiq_tx_buffer:
  102. .word 0x0
  103. imx_ssi_fiq_end: