ssi-fiq.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2009 Sascha Hauer <[email protected]>
  4. */
  5. #include <linux/linkage.h>
  6. #include <asm/assembler.h>
  7. /*
  8. * r8 = bit 0-15: tx offset, bit 16-31: tx buffer size
  9. * r9 = bit 0-15: rx offset, bit 16-31: rx buffer size
  10. */
  11. #define SSI_STX0 0x00
  12. #define SSI_SRX0 0x08
  13. #define SSI_SISR 0x14
  14. #define SSI_SIER 0x18
  15. #define SSI_SACNT 0x38
  16. #define SSI_SACNT_AC97EN (1 << 0)
  17. #define SSI_SIER_TFE0_EN (1 << 0)
  18. #define SSI_SISR_TFE0 (1 << 0)
  19. #define SSI_SISR_RFF0 (1 << 2)
  20. #define SSI_SIER_RFF0_EN (1 << 2)
  21. .text
  22. .global imx_ssi_fiq_start
  23. .global imx_ssi_fiq_end
  24. .global imx_ssi_fiq_base
  25. .global imx_ssi_fiq_rx_buffer
  26. .global imx_ssi_fiq_tx_buffer
  27. /*
  28. * imx_ssi_fiq_start is _intentionally_ not marked as a function symbol
  29. * using ENDPROC(). imx_ssi_fiq_start and imx_ssi_fiq_end are used to
  30. * mark the function body so that it can be copied to the FIQ vector in
  31. * the vectors page. imx_ssi_fiq_start should only be called as the result
  32. * of an FIQ: calling it directly will not work.
  33. */
  34. imx_ssi_fiq_start:
  35. ldr r12, .L_imx_ssi_fiq_base
  36. /* TX */
  37. ldr r13, .L_imx_ssi_fiq_tx_buffer
  38. /* shall we send? */
  39. ldr r11, [r12, #SSI_SIER]
  40. tst r11, #SSI_SIER_TFE0_EN
  41. beq 1f
  42. /* TX FIFO empty? */
  43. ldr r11, [r12, #SSI_SISR]
  44. tst r11, #SSI_SISR_TFE0
  45. beq 1f
  46. mov r10, #0x10000
  47. sub r10, #1
  48. and r10, r10, r8 /* r10: current buffer offset */
  49. add r13, r13, r10
  50. ldrh r11, [r13]
  51. strh r11, [r12, #SSI_STX0]
  52. ldrh r11, [r13, #2]
  53. strh r11, [r12, #SSI_STX0]
  54. ldrh r11, [r13, #4]
  55. strh r11, [r12, #SSI_STX0]
  56. ldrh r11, [r13, #6]
  57. strh r11, [r12, #SSI_STX0]
  58. add r10, #8
  59. lsr r11, r8, #16 /* r11: buffer size */
  60. cmp r10, r11
  61. lslgt r8, r11, #16
  62. addle r8, #8
  63. 1:
  64. /* RX */
  65. /* shall we receive? */
  66. ldr r11, [r12, #SSI_SIER]
  67. tst r11, #SSI_SIER_RFF0_EN
  68. beq 1f
  69. /* RX FIFO full? */
  70. ldr r11, [r12, #SSI_SISR]
  71. tst r11, #SSI_SISR_RFF0
  72. beq 1f
  73. ldr r13, .L_imx_ssi_fiq_rx_buffer
  74. mov r10, #0x10000
  75. sub r10, #1
  76. and r10, r10, r9 /* r10: current buffer offset */
  77. add r13, r13, r10
  78. ldr r11, [r12, #SSI_SACNT]
  79. tst r11, #SSI_SACNT_AC97EN
  80. ldr r11, [r12, #SSI_SRX0]
  81. strh r11, [r13]
  82. ldr r11, [r12, #SSI_SRX0]
  83. strh r11, [r13, #2]
  84. /* dummy read to skip slot 12 */
  85. ldrne r11, [r12, #SSI_SRX0]
  86. ldr r11, [r12, #SSI_SRX0]
  87. strh r11, [r13, #4]
  88. ldr r11, [r12, #SSI_SRX0]
  89. strh r11, [r13, #6]
  90. /* dummy read to skip slot 12 */
  91. ldrne r11, [r12, #SSI_SRX0]
  92. add r10, #8
  93. lsr r11, r9, #16 /* r11: buffer size */
  94. cmp r10, r11
  95. lslgt r9, r11, #16
  96. addle r9, #8
  97. 1:
  98. @ return from FIQ
  99. subs pc, lr, #4
  100. .align
  101. .L_imx_ssi_fiq_base:
  102. imx_ssi_fiq_base:
  103. .word 0x0
  104. .L_imx_ssi_fiq_rx_buffer:
  105. imx_ssi_fiq_rx_buffer:
  106. .word 0x0
  107. .L_imx_ssi_fiq_tx_buffer:
  108. imx_ssi_fiq_tx_buffer:
  109. .word 0x0
  110. .L_imx_ssi_fiq_end:
  111. imx_ssi_fiq_end: