mn10300-serial-low.S 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. ###############################################################################
  2. #
  3. # Virtual DMA driver for MN10300 serial ports
  4. #
  5. # Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
  6. # Written by David Howells (dhowells@redhat.com)
  7. #
  8. # This program is free software; you can redistribute it and/or
  9. # modify it under the terms of the GNU General Public Licence
  10. # as published by the Free Software Foundation; either version
  11. # 2 of the Licence, or (at your option) any later version.
  12. #
  13. ###############################################################################
  14. #include <linux/sys.h>
  15. #include <linux/linkage.h>
  16. #include <asm/page.h>
  17. #include <asm/smp.h>
  18. #include <asm/cpu-regs.h>
  19. #include <asm/frame.inc>
  20. #include <asm/timer-regs.h>
  21. #include <proc/cache.h>
  22. #include <unit/timex.h>
  23. #include "mn10300-serial.h"
  24. #define SCxCTR 0x00
  25. #define SCxICR 0x04
  26. #define SCxTXB 0x08
  27. #define SCxRXB 0x09
  28. #define SCxSTR 0x0c
  29. #define SCxTIM 0x0d
  30. .text
  31. ###############################################################################
  32. #
  33. # serial port interrupt virtual DMA entry point
  34. # - intended to run at interrupt priority 1 (not affected by local_irq_disable)
  35. #
  36. ###############################################################################
  37. .balign L1_CACHE_BYTES
  38. ENTRY(mn10300_serial_vdma_interrupt)
  39. # or EPSW_IE,psw # permit overriding by
  40. # debugging interrupts
  41. movm [d2,d3,a2,a3,exreg0],(sp)
  42. movhu (IAGR),a2 # see if which interrupt is
  43. # pending
  44. and IAGR_GN,a2
  45. add a2,a2
  46. add mn10300_serial_int_tbl,a2
  47. mov (a2+),a3
  48. mov (__iobase,a3),e2
  49. mov (a2),a2
  50. jmp (a2)
  51. ###############################################################################
  52. #
  53. # serial port receive interrupt virtual DMA entry point
  54. # - intended to run at interrupt priority 1 (not affected by local_irq_disable)
  55. # - stores data/status byte pairs in the ring buffer
  56. # - induces a scheduler tick timer interrupt when done, which we then subvert
  57. # on entry:
  58. # A3 struct mn10300_serial_port *
  59. # E2 I/O port base
  60. #
  61. ###############################################################################
  62. ENTRY(mn10300_serial_vdma_rx_handler)
  63. mov (__rx_icr,a3),e3
  64. mov GxICR_DETECT,d2
  65. movbu d2,(e3) # ACK the interrupt
  66. movhu (e3),d2 # flush
  67. mov (__rx_inp,a3),d3
  68. mov d3,a2
  69. add 2,d3
  70. and MNSC_BUFFER_SIZE-1,d3
  71. mov (__rx_outp,a3),d2
  72. cmp d3,d2
  73. beq mnsc_vdma_rx_overflow
  74. mov (__rx_buffer,a3),d2
  75. add d2,a2
  76. movhu (SCxSTR,e2),d2
  77. movbu d2,(1,a2)
  78. movbu (SCxRXB,e2),d2
  79. movbu d2,(a2)
  80. mov d3,(__rx_inp,a3)
  81. bset MNSCx_RX_AVAIL,(__intr_flags,a3)
  82. mnsc_vdma_rx_done:
  83. mov (__tm_icr,a3),a2
  84. mov GxICR_LEVEL_6|GxICR_ENABLE|GxICR_REQUEST|GxICR_DETECT,d2
  85. movhu d2,(a2) # request a slow interrupt
  86. movhu (a2),d2 # flush
  87. movm (sp),[d2,d3,a2,a3,exreg0]
  88. rti
  89. mnsc_vdma_rx_overflow:
  90. bset MNSCx_RX_OVERF,(__intr_flags,a3)
  91. bra mnsc_vdma_rx_done
  92. ###############################################################################
  93. #
  94. # serial port transmit interrupt virtual DMA entry point
  95. # - intended to run at interrupt priority 1 (not affected by local_irq_disable)
  96. # - retrieves data bytes from the ring buffer and passes them to the serial port
  97. # - induces a scheduler tick timer interrupt when done, which we then subvert
  98. # A3 struct mn10300_serial_port *
  99. # E2 I/O port base
  100. #
  101. ###############################################################################
  102. .balign L1_CACHE_BYTES
  103. ENTRY(mn10300_serial_vdma_tx_handler)
  104. mov (__tx_icr,a3),e3
  105. mov GxICR_DETECT,d2
  106. movbu d2,(e3) # ACK the interrupt
  107. movhu (e3),d2 # flush
  108. btst 0xFF,(__tx_flags,a3) # handle transmit flags
  109. bne mnsc_vdma_tx_flags
  110. movbu (SCxSTR,e2),d2 # don't try and transmit a char if the
  111. # buffer is not empty
  112. btst SC01STR_TBF,d2 # (may have tried to jumpstart)
  113. bne mnsc_vdma_tx_noint
  114. movbu (__tx_xchar,a3),d2 # handle hi-pri XON/XOFF
  115. or d2,d2
  116. bne mnsc_vdma_tx_xchar
  117. mov (__uart_state,a3),a2 # see if the TTY Tx queue has anything in it
  118. mov (__xmit_tail,a2),d3
  119. mov (__xmit_head,a2),d2
  120. cmp d3,d2
  121. beq mnsc_vdma_tx_empty
  122. mov (__xmit_buffer,a2),d2 # get a char from the buffer and
  123. # transmit it
  124. movbu (d3,d2),d2
  125. movbu d2,(SCxTXB,e2) # Tx
  126. inc d3 # advance the buffer pointer
  127. and __UART_XMIT_SIZE-1,d3
  128. mov (__xmit_head,a2),d2
  129. mov d3,(__xmit_tail,a2)
  130. sub d3,d2 # see if we've written everything
  131. beq mnsc_vdma_tx_empty
  132. and __UART_XMIT_SIZE-1,d2 # see if we just made a hole
  133. cmp __UART_XMIT_SIZE-2,d2
  134. beq mnsc_vdma_tx_made_hole
  135. mnsc_vdma_tx_done:
  136. mov (__tm_icr,a3),a2
  137. mov GxICR_LEVEL_6|GxICR_ENABLE|GxICR_REQUEST|GxICR_DETECT,d2
  138. movhu d2,(a2) # request a slow interrupt
  139. movhu (a2),d2 # flush
  140. mnsc_vdma_tx_noint:
  141. movm (sp),[d2,d3,a2,a3,exreg0]
  142. rti
  143. mnsc_vdma_tx_empty:
  144. mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
  145. movhu d2,(e3) # disable the interrupt
  146. movhu (e3),d2 # flush
  147. bset MNSCx_TX_EMPTY,(__intr_flags,a3)
  148. bra mnsc_vdma_tx_done
  149. mnsc_vdma_tx_flags:
  150. btst MNSCx_TX_STOP,(__tx_flags,a3)
  151. bne mnsc_vdma_tx_stop
  152. movhu (SCxCTR,e2),d2 # turn on break mode
  153. or SC01CTR_BKE,d2
  154. movhu d2,(SCxCTR,e2)
  155. mnsc_vdma_tx_stop:
  156. mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
  157. movhu d2,(e3) # disable transmit interrupts on this
  158. # channel
  159. movhu (e3),d2 # flush
  160. bra mnsc_vdma_tx_noint
  161. mnsc_vdma_tx_xchar:
  162. bclr 0xff,(__tx_xchar,a3)
  163. movbu d2,(SCxTXB,e2)
  164. bra mnsc_vdma_tx_done
  165. mnsc_vdma_tx_made_hole:
  166. bset MNSCx_TX_SPACE,(__intr_flags,a3)
  167. bra mnsc_vdma_tx_done