Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / sound / oss / vidc_fill.S
diff --git a/kernel/sound/oss/vidc_fill.S b/kernel/sound/oss/vidc_fill.S
new file mode 100644 (file)
index 0000000..bed3492
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ *  linux/drivers/sound/vidc_fill.S
+ *
+ *  Copyright (C) 1997 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Filler routines for DMA buffers
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+#include <asm/hardware/iomd.h>
+
+               .text
+
+ENTRY(vidc_fill_1x8_u)
+               mov     ip, #0xff00
+1:             cmp     r0, r1
+               bge     vidc_clear
+               ldrb    r4, [r0], #1
+               eor     r4, r4, #0x80
+               and     r4, ip, r4, lsl #8
+               orr     r4, r4, r4, lsl #16
+               str     r4, [r2], #4
+               cmp     r2, r3
+               blt     1b
+               mov     pc, lr
+
+ENTRY(vidc_fill_2x8_u)
+               mov     ip, #0xff00
+1:             cmp     r0, r1
+               bge     vidc_clear
+               ldr     r4, [r0], #2
+               and     r5, r4, ip
+               and     r4, ip, r4, lsl #8
+               orr     r4, r4, r5, lsl #16
+               orr     r4, r4, r4, lsr #8
+               str     r4, [r2], #4
+               cmp     r2, r3
+               blt     1b
+               mov     pc, lr
+
+ENTRY(vidc_fill_1x8_s)
+               mov     ip, #0xff00
+1:             cmp     r0, r1
+               bge     vidc_clear
+               ldrb    r4, [r0], #1
+               and     r4, ip, r4, lsl #8
+               orr     r4, r4, r4, lsl #16
+               str     r4, [r2], #4
+               cmp     r2, r3
+               blt     1b
+               mov     pc, lr
+
+ENTRY(vidc_fill_2x8_s)
+               mov     ip, #0xff00
+1:             cmp     r0, r1
+               bge     vidc_clear
+               ldr     r4, [r0], #2
+               and     r5, r4, ip
+               and     r4, ip, r4, lsl #8
+               orr     r4, r4, r5, lsl #16
+               orr     r4, r4, r4, lsr #8
+               str     r4, [r2], #4
+               cmp     r2, r3
+               blt     1b
+               mov     pc, lr
+
+ENTRY(vidc_fill_1x16_s)
+               mov     ip, #0xff00
+               orr     ip, ip, ip, lsr #8
+1:             cmp     r0, r1
+               bge     vidc_clear
+               ldr     r5, [r0], #2
+               and     r4, r5, ip
+               orr     r4, r4, r4, lsl #16
+               str     r4, [r2], #4
+               cmp     r0, r1
+               addlt   r0, r0, #2
+               andlt   r4, r5, ip, lsl #16
+               orrlt   r4, r4, r4, lsr #16
+               strlt   r4, [r2], #4
+               cmp     r2, r3
+               blt     1b
+               mov     pc, lr
+
+ENTRY(vidc_fill_2x16_s)
+               mov     ip, #0xff00
+               orr     ip, ip, ip, lsr #8
+1:             cmp     r0, r1
+               bge     vidc_clear
+               ldr     r4, [r0], #4
+               str     r4, [r2], #4
+               cmp     r0, r1
+               ldrlt   r4, [r0], #4
+               strlt   r4, [r2], #4
+               cmp     r2, r3
+               blt     1b
+               mov     pc, lr
+
+ENTRY(vidc_fill_noaudio)
+               mov     r0, #0
+               mov     r1, #0
+2:             mov     r4, #0
+               mov     r5, #0
+1:             cmp     r2, r3
+               stmltia r2!, {r0, r1, r4, r5}
+               blt     1b
+               mov     pc, lr
+
+ENTRY(vidc_clear)
+               mov     r0, #0
+               mov     r1, #0
+               tst     r2, #4
+               str     r0, [r2], #4
+               tst     r2, #8
+               stmia   r2!, {r0, r1}
+               b       2b
+
+/*
+ * Call filler routines with:
+ *  r0 = phys address
+ *  r1 = phys end
+ *  r2 = buffer
+ * Returns:
+ *  r0 = new buffer address
+ *  r2 = new buffer finish
+ *  r4 = corrupted
+ *  r5 = corrupted
+ *  ip = corrupted
+ */
+
+ENTRY(vidc_sound_dma_irq)
+               stmfd   sp!, {r4 - r8, lr}
+               ldr     r8, =dma_start
+               ldmia   r8, {r0, r1, r2, r3, r4, r5}
+               teq     r1, #0
+               adreq   r4, vidc_fill_noaudio
+               moveq   r7, #1 << 31
+               movne   r7, #0
+               mov     ip, #IOMD_BASE & 0xff000000
+               orr     ip, ip, #IOMD_BASE & 0x00ff0000
+               ldrb    r6, [ip, #IOMD_SD0ST]
+               tst     r6, #DMA_ST_OFL                 @ Check for overrun
+               eorne   r6, r6, #DMA_ST_AB
+               tst     r6, #DMA_ST_AB
+               moveq   r2, r3                          @ DMAing A, update B
+               add     r3, r2, r5                      @ End of DMA buffer
+               add     r1, r1, r0                      @ End of virtual DMA buffer
+               mov     lr, pc
+               mov     pc, r4                          @ Call fill routine (uses r4, ip)
+               sub     r1, r1, r0                      @ Remaining length
+               stmia   r8, {r0, r1}
+               mov     r0, #0
+               tst     r2, #4                          @ Round buffer up to 4 words
+               strne   r0, [r2], #4
+               tst     r2, #8
+               strne   r0, [r2], #4
+               strne   r0, [r2], #4
+               sub     r2, r2, #16
+               mov     r2, r2, lsl #20
+               movs    r2, r2, lsr #20
+               orreq   r2, r2, #1 << 30                @ Set L bit
+               orr     r2, r2, r7
+               ldmdb   r8, {r3, r4, r5}
+               tst     r6, #DMA_ST_AB
+               mov     ip, #IOMD_BASE & 0xff000000
+               orr     ip, ip, #IOMD_BASE & 0x00ff0000
+               streq   r4, [ip, #IOMD_SD0CURB]
+               strne   r5, [ip, #IOMD_SD0CURA]
+               streq   r2, [ip, #IOMD_SD0ENDB]
+               strne   r2, [ip, #IOMD_SD0ENDA]
+               ldr     lr, [ip, #IOMD_SD0ST]
+               tst     lr, #DMA_ST_OFL
+               bne     1f
+               tst     r6, #DMA_ST_AB
+               strne   r4, [ip, #IOMD_SD0CURB]
+               streq   r5, [ip, #IOMD_SD0CURA]
+               strne   r2, [ip, #IOMD_SD0ENDB]
+               streq   r2, [ip, #IOMD_SD0ENDA]
+1:             teq     r7, #0
+               mov     r0, #0x10
+               strneb  r0, [ip, #IOMD_SD0CR]
+               ldmfd   sp!, {r4 - r8, lr}
+               mov     r0, #1                          @ IRQ_HANDLED
+               teq     r1, #0                          @ If we have no more
+               movne   pc, lr
+               teq     r3, #0
+               movne   pc, r3                          @ Call interrupt routine
+               mov     pc, lr
+
+               .data
+               .globl  dma_interrupt
+dma_interrupt:
+               .long   0                               @ r3
+               .globl  dma_pbuf
+dma_pbuf:
+               .long   0                               @ r4
+               .long   0                               @ r5
+               .globl  dma_start
+dma_start:
+               .long   0                               @ r0
+               .globl  dma_count
+dma_count:
+               .long   0                               @ r1
+               .globl  dma_buf
+dma_buf:
+               .long   0                               @ r2
+               .long   0                               @ r3
+               .globl  vidc_filler
+vidc_filler:
+               .long   vidc_fill_noaudio               @ r4
+               .globl  dma_bufsize
+dma_bufsize:
+               .long   0x1000                          @ r5