ssi-fiq.S 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. /*
  31. * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol
  32. * using ENDPROC(). imx_ssi_fiq_start and imx_ssi_fiq_end are used to
  33. * mark the function body so that it can be copied to the FIQ vector in
  34. * the vectors page. imx_ssi_fiq_start should only be called as the result
  35. * of an FIQ: calling it directly will not work.
  36. */
  37. imx_ssi_fiq_start:
  38. ldr r12, .L_imx_ssi_fiq_base
  39. /* TX */
  40. ldr r13, .L_imx_ssi_fiq_tx_buffer
  41. /* shall we send? */
  42. ldr r11, [r12, #SSI_SIER]
  43. tst r11, #SSI_SIER_TFE0_EN
  44. beq 1f
  45. /* TX FIFO empty? */
  46. ldr r11, [r12, #SSI_SISR]
  47. tst r11, #SSI_SISR_TFE0
  48. beq 1f
  49. mov r10, #0x10000
  50. sub r10, #1
  51. and r10, r10, r8 /* r10: current buffer offset */
  52. add r13, r13, r10
  53. ldrh r11, [r13]
  54. strh r11, [r12, #SSI_STX0]
  55. ldrh r11, [r13, #2]
  56. strh r11, [r12, #SSI_STX0]
  57. ldrh r11, [r13, #4]
  58. strh r11, [r12, #SSI_STX0]
  59. ldrh r11, [r13, #6]
  60. strh r11, [r12, #SSI_STX0]
  61. add r10, #8
  62. lsr r11, r8, #16 /* r11: buffer size */
  63. cmp r10, r11
  64. lslgt r8, r11, #16
  65. addle r8, #8
  66. 1:
  67. /* RX */
  68. /* shall we receive? */
  69. ldr r11, [r12, #SSI_SIER]
  70. tst r11, #SSI_SIER_RFF0_EN
  71. beq 1f
  72. /* RX FIFO full? */
  73. ldr r11, [r12, #SSI_SISR]
  74. tst r11, #SSI_SISR_RFF0
  75. beq 1f
  76. ldr r13, .L_imx_ssi_fiq_rx_buffer
  77. mov r10, #0x10000
  78. sub r10, #1
  79. and r10, r10, r9 /* r10: current buffer offset */
  80. add r13, r13, r10
  81. ldr r11, [r12, #SSI_SACNT]
  82. tst r11, #SSI_SACNT_AC97EN
  83. ldr r11, [r12, #SSI_SRX0]
  84. strh r11, [r13]
  85. ldr r11, [r12, #SSI_SRX0]
  86. strh r11, [r13, #2]
  87. /* dummy read to skip slot 12 */
  88. ldrne r11, [r12, #SSI_SRX0]
  89. ldr r11, [r12, #SSI_SRX0]
  90. strh r11, [r13, #4]
  91. ldr r11, [r12, #SSI_SRX0]
  92. strh r11, [r13, #6]
  93. /* dummy read to skip slot 12 */
  94. ldrne r11, [r12, #SSI_SRX0]
  95. add r10, #8
  96. lsr r11, r9, #16 /* r11: buffer size */
  97. cmp r10, r11
  98. lslgt r9, r11, #16
  99. addle r9, #8
  100. 1:
  101. @ return from FIQ
  102. subs pc, lr, #4
  103. .align
  104. .L_imx_ssi_fiq_base:
  105. imx_ssi_fiq_base:
  106. .word 0x0
  107. .L_imx_ssi_fiq_rx_buffer:
  108. imx_ssi_fiq_rx_buffer:
  109. .word 0x0
  110. .L_imx_ssi_fiq_tx_buffer:
  111. imx_ssi_fiq_tx_buffer:
  112. .word 0x0
  113. .L_imx_ssi_fiq_end:
  114. imx_ssi_fiq_end: