1/*
2 *  linux/drivers/sound/vidc_fill.S
3 *
4 *  Copyright (C) 1997 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 *  Filler routines for DMA buffers
11 */
12#include <linux/linkage.h>
13#include <asm/assembler.h>
14#include <asm/hardware.h>
15#include <asm/hardware/iomd.h>
16
17		.text
18
19ENTRY(vidc_fill_1x8_u)
20		mov	ip, #0xff00
211:		cmp	r0, r1
22		bge	vidc_clear
23		ldrb	r4, [r0], #1
24		eor	r4, r4, #0x80
25		and	r4, ip, r4, lsl #8
26		orr	r4, r4, r4, lsl #16
27		str	r4, [r2], #4
28		cmp	r2, r3
29		blt	1b
30		mov	pc, lr
31
32ENTRY(vidc_fill_2x8_u)
33		mov	ip, #0xff00
341:		cmp	r0, r1
35		bge	vidc_clear
36		ldr	r4, [r0], #2
37		and	r5, r4, ip
38		and	r4, ip, r4, lsl #8
39		orr	r4, r4, r5, lsl #16
40		orr	r4, r4, r4, lsr #8
41		str	r4, [r2], #4
42		cmp	r2, r3
43		blt	1b
44		mov	pc, lr
45
46ENTRY(vidc_fill_1x8_s)
47		mov	ip, #0xff00
481:		cmp	r0, r1
49		bge	vidc_clear
50		ldrb	r4, [r0], #1
51		and	r4, ip, r4, lsl #8
52		orr	r4, r4, r4, lsl #16
53		str	r4, [r2], #4
54		cmp	r2, r3
55		blt	1b
56		mov	pc, lr
57
58ENTRY(vidc_fill_2x8_s)
59		mov	ip, #0xff00
601:		cmp	r0, r1
61		bge	vidc_clear
62		ldr	r4, [r0], #2
63		and	r5, r4, ip
64		and	r4, ip, r4, lsl #8
65		orr	r4, r4, r5, lsl #16
66		orr	r4, r4, r4, lsr #8
67		str	r4, [r2], #4
68		cmp	r2, r3
69		blt	1b
70		mov	pc, lr
71
72ENTRY(vidc_fill_1x16_s)
73		mov	ip, #0xff00
74		orr	ip, ip, ip, lsr #8
751:		cmp	r0, r1
76		bge	vidc_clear
77		ldr	r5, [r0], #2
78		and	r4, r5, ip
79		orr	r4, r4, r4, lsl #16
80		str	r4, [r2], #4
81		cmp	r0, r1
82		addlt	r0, r0, #2
83		andlt	r4, r5, ip, lsl #16
84		orrlt	r4, r4, r4, lsr #16
85		strlt	r4, [r2], #4
86		cmp	r2, r3
87		blt	1b
88		mov	pc, lr
89
90ENTRY(vidc_fill_2x16_s)
91		mov	ip, #0xff00
92		orr	ip, ip, ip, lsr #8
931:		cmp	r0, r1
94		bge	vidc_clear
95		ldr	r4, [r0], #4
96		str	r4, [r2], #4
97		cmp	r0, r1
98		ldrlt	r4, [r0], #4
99		strlt	r4, [r2], #4
100		cmp	r2, r3
101		blt	1b
102		mov	pc, lr
103
104ENTRY(vidc_fill_noaudio)
105		mov	r0, #0
106		mov	r1, #0
1072:		mov	r4, #0
108		mov	r5, #0
1091:		cmp	r2, r3
110		stmltia	r2!, {r0, r1, r4, r5}
111		blt	1b
112		mov	pc, lr
113
114ENTRY(vidc_clear)
115		mov	r0, #0
116		mov	r1, #0
117		tst	r2, #4
118		str	r0, [r2], #4
119		tst	r2, #8
120		stmia	r2!, {r0, r1}
121		b	2b
122
123/*
124 * Call filler routines with:
125 *  r0 = phys address
126 *  r1 = phys end
127 *  r2 = buffer
128 * Returns:
129 *  r0 = new buffer address
130 *  r2 = new buffer finish
131 *  r4 = corrupted
132 *  r5 = corrupted
133 *  ip = corrupted
134 */
135
136ENTRY(vidc_sound_dma_irq)
137		stmfd	sp!, {r4 - r8, lr}
138		ldr	r8, =dma_start
139		ldmia	r8, {r0, r1, r2, r3, r4, r5}
140		teq	r1, #0
141		adreq	r4, vidc_fill_noaudio
142		moveq	r7, #1 << 31
143		movne	r7, #0
144		mov	ip, #IOMD_BASE & 0xff000000
145		orr	ip, ip, #IOMD_BASE & 0x00ff0000
146		ldrb	r6, [ip, #IOMD_SD0ST]
147		tst	r6, #DMA_ST_OFL			@ Check for overrun
148		eorne	r6, r6, #DMA_ST_AB
149		tst	r6, #DMA_ST_AB
150		moveq	r2, r3				@ DMAing A, update B
151		add	r3, r2, r5			@ End of DMA buffer
152		add	r1, r1, r0			@ End of virtual DMA buffer
153		mov	lr, pc
154		mov	pc, r4				@ Call fill routine (uses r4, ip)
155		sub	r1, r1, r0			@ Remaining length
156		stmia	r8, {r0, r1}
157		mov	r0, #0
158		tst	r2, #4				@ Round buffer up to 4 words
159		strne	r0, [r2], #4
160		tst	r2, #8
161		strne	r0, [r2], #4
162		strne	r0, [r2], #4
163		sub	r2, r2, #16
164		mov	r2, r2, lsl #20
165		movs	r2, r2, lsr #20
166		orreq	r2, r2, #1 << 30		@ Set L bit
167		orr	r2, r2, r7
168		ldmdb	r8, {r3, r4, r5}
169		tst	r6, #DMA_ST_AB
170		mov	ip, #IOMD_BASE & 0xff000000
171		orr	ip, ip, #IOMD_BASE & 0x00ff0000
172		streq	r4, [ip, #IOMD_SD0CURB]
173		strne	r5, [ip, #IOMD_SD0CURA]
174		streq	r2, [ip, #IOMD_SD0ENDB]
175		strne	r2, [ip, #IOMD_SD0ENDA]
176		ldr	lr, [ip, #IOMD_SD0ST]
177		tst	lr, #DMA_ST_OFL
178		bne	1f
179		tst	r6, #DMA_ST_AB
180		strne	r4, [ip, #IOMD_SD0CURB]
181		streq	r5, [ip, #IOMD_SD0CURA]
182		strne	r2, [ip, #IOMD_SD0ENDB]
183		streq	r2, [ip, #IOMD_SD0ENDA]
1841:		teq	r7, #0
185		mov	r0, #0x10
186		strneb	r0, [ip, #IOMD_SD0CR]
187		ldmfd	sp!, {r4 - r8, lr}
188		mov	r0, #1				@ IRQ_HANDLED
189		teq	r1, #0				@ If we have no more
190		movne	pc, lr
191		teq	r3, #0
192		movne	pc, r3				@ Call interrupt routine
193		mov	pc, lr
194
195		.data
196		.globl	dma_interrupt
197dma_interrupt:
198		.long	0				@ r3
199		.globl	dma_pbuf
200dma_pbuf:
201		.long	0				@ r4
202		.long	0				@ r5
203		.globl	dma_start
204dma_start:
205		.long	0				@ r0
206		.globl	dma_count
207dma_count:
208		.long	0				@ r1
209		.globl	dma_buf
210dma_buf:
211		.long	0				@ r2
212		.long	0				@ r3
213		.globl	vidc_filler
214vidc_filler:
215		.long	vidc_fill_noaudio		@ r4
216		.globl	dma_bufsize
217dma_bufsize:
218		.long	0x1000				@ r5
219