fd1772dma.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <asm/hardware.h>
  2. @ Code for DMA with the 1772 fdc
  3. .text
  4. .global fdc1772_dataaddr
  5. fdc1772_fiqdata:
  6. @ Number of bytes left to DMA
  7. .global fdc1772_bytestogo
  8. fdc1772_bytestogo:
  9. .word 0
  10. @ Place to put/get data from in DMA
  11. .global fdc1772_dataaddr
  12. fdc1772_dataaddr:
  13. .word 0
  14. .global fdc1772_fdc_int_done
  15. fdc1772_fdc_int_done:
  16. .word 0
  17. .global fdc1772_comendstatus
  18. fdc1772_comendstatus:
  19. .word 0
  20. @ We hang this off DMA channel 1
  21. .global fdc1772_comendhandler
  22. fdc1772_comendhandler:
  23. mov r8,#IOC_BASE
  24. ldrb r9,[r8,#0x34] @ IOC FIQ status
  25. tst r9,#2
  26. subeqs pc,r14,#4 @ should I leave a space here
  27. orr r9,r8,#0x10000 @ FDC base
  28. adr r8,fdc1772_fdc_int_done
  29. ldrb r10,[r9,#0] @ FDC status
  30. mov r9,#1 @ Got a FIQ flag
  31. stmia r8,{r9,r10}
  32. subs pc,r14,#4
  33. .global fdc1772_dma_read
  34. fdc1772_dma_read:
  35. mov r8,#IOC_BASE
  36. ldrb r9,[r8,#0x34] @ IOC FIQ status
  37. tst r9,#1
  38. beq fdc1772_dma_read_notours
  39. orr r8,r8,#0x10000 @ FDC base
  40. ldrb r10,[r8,#0xc] @ Read from FDC data reg (also clears interrupt)
  41. ldmia r11,{r8,r9}
  42. subs r8,r8,#1 @ One less byte to go
  43. @ If there was somewhere for this data to go then store it and update pointers
  44. strplb r10,[r9],#1 @ Store the data and increment the pointer
  45. stmplia r11,{r8,r9} @ Update count/pointers
  46. @ Handle any other interrupts if there are any
  47. fdc1772_dma_read_notours:
  48. @ Cant branch because this code has been copied down to the FIQ vector
  49. ldr pc,[pc,#-4]
  50. .word fdc1772_comendhandler
  51. .global fdc1772_dma_read_end
  52. fdc1772_dma_read_end:
  53. .global fdc1772_dma_write
  54. fdc1772_dma_write:
  55. mov r8,#IOC_BASE
  56. ldrb r9,[r8,#0x34] @ IOC FIQ status
  57. tst r9,#1
  58. beq fdc1772_dma_write_notours
  59. orr r8,r8,#0x10000 @ FDC base
  60. ldmia r11,{r9,r10}
  61. subs r9,r9,#1 @ One less byte to go
  62. @ If there really is some data then get it, store it and update count
  63. ldrplb r12,[r10],#1
  64. strplb r12,[r8,#0xc] @ write it to FDC data reg
  65. stmplia r11,{r9,r10} @ Update count and pointer - should clear interrupt
  66. @ Handle any other interrupts
  67. fdc1772_dma_write_notours:
  68. @ Cant branch because this code has been copied down to the FIQ vector
  69. ldr pc,[pc,#-4]
  70. .word fdc1772_comendhandler
  71. .global fdc1772_dma_write_end
  72. fdc1772_dma_write_end:
  73. @ Setup the FIQ R11 to point to the data and store the count, address
  74. @ for this dma
  75. @ R0=count
  76. @ R1=address
  77. .global fdc1772_setupdma
  78. fdc1772_setupdma:
  79. @ The big job is flipping in and out of FIQ mode
  80. adr r2,fdc1772_fiqdata @ This is what we really came here for
  81. stmia r2,{r0,r1}
  82. mov r3, pc
  83. teqp pc,#0x0c000001 @ Disable FIQs, IRQs and switch to FIQ mode
  84. mov r0,r0 @ NOP
  85. mov r11,r2
  86. teqp r3,#0 @ Normal mode
  87. mov r0,r0 @ NOP
  88. mov pc,r14