summaryrefslogtreecommitdiffstats
path: root/drivers/acorn/block/fd1772dma.S
blob: 7964435443ecc39585b5e6d979168baef04e4f23 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <asm/hardware.h>

@ Code for DMA with the 1772 fdc
.text


  .global fdc1772_dataaddr
fdc1772_fiqdata:
@ Number of bytes left to DMA
  .global fdc1772_bytestogo
fdc1772_bytestogo:
  .word 0
@ Place to put/get data from in DMA
  .global fdc1772_dataaddr
fdc1772_dataaddr:
  .word 0
  
  .global fdc1772_fdc_int_done
fdc1772_fdc_int_done:
  .word 0
  .global fdc1772_comendstatus
fdc1772_comendstatus:
  .word 0

@ We hang this off DMA channel 1
    .global fdc1772_comendhandler
fdc1772_comendhandler:
  mov      r8,#IOC_BASE
  ldrb     r9,[r8,#0x34]    @ IOC FIQ status
  tst      r9,#2
  subeqs   pc,r14,#4        @ should I leave a space here
  orr      r9,r8,#0x10000   @ FDC base
  adr      r8,fdc1772_fdc_int_done
  ldrb     r10,[r9,#0]  @ FDC status
  mov      r9,#1        @ Got a FIQ flag
  stmia    r8,{r9,r10}
  subs     pc,r14,#4


    .global fdc1772_dma_read
fdc1772_dma_read:
  mov      r8,#IOC_BASE
  ldrb     r9,[r8,#0x34]    @ IOC FIQ status
  tst      r9,#1
  beq      fdc1772_dma_read_notours
  orr      r8,r8,#0x10000   @ FDC base
  ldrb     r10,[r8,#0xc]   @ Read from FDC data reg (also clears interrupt)
  ldmia    r11,{r8,r9}
  subs     r8,r8,#1        @ One less byte to go
  @ If there was somewhere for this data to go then store it and update pointers
  strplb   r10,[r9],#1     @ Store the data and increment the pointer
  stmplia  r11,{r8,r9}     @ Update count/pointers
  @ Handle any other interrupts if there are any
fdc1772_dma_read_notours:
  @ Cant branch because this code has been copied down to the FIQ vector
  ldr pc,[pc,#-4]
  .word fdc1772_comendhandler
  .global fdc1772_dma_read_end
fdc1772_dma_read_end:

    .global fdc1772_dma_write
fdc1772_dma_write:
  mov      r8,#IOC_BASE
  ldrb     r9,[r8,#0x34]    @ IOC FIQ status
  tst      r9,#1
  beq      fdc1772_dma_write_notours
  orr      r8,r8,#0x10000   @ FDC base
  ldmia    r11,{r9,r10}
  subs     r9,r9,#1        @ One less byte to go
  @ If there really is some data then get it, store it and update count
  ldrplb   r12,[r10],#1
  strplb   r12,[r8,#0xc]   @ write it to FDC data reg
  stmplia  r11,{r9,r10}    @ Update count and pointer - should clear interrupt
  @ Handle any other interrupts
fdc1772_dma_write_notours:
  @ Cant branch because this code has been copied down to the FIQ vector
  ldr pc,[pc,#-4]
  .word fdc1772_comendhandler

  .global fdc1772_dma_write_end
fdc1772_dma_write_end:
  

@ Setup the FIQ R11 to point to the data and store the count, address
@ for this dma
@ R0=count
@ R1=address
  .global fdc1772_setupdma
fdc1772_setupdma:
	@ The big job is flipping in and out of FIQ mode
	adr	r2,fdc1772_fiqdata	@ This is what we really came here for
  stmia  r2,{r0,r1}
	mov	r3, pc
	teqp	pc,#0x0c000001	@ Disable FIQs, IRQs and switch to FIQ mode
	mov	r0,r0      	@ NOP
	mov r11,r2
	teqp	r3,#0		@ Normal mode
	mov	r0,r0		@ NOP
  mov pc,r14