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#define __ASSEMBLY__ 13#include <linux/linkage.h> 14#include <asm/assembler.h> 15#include <asm/hardware.h> 16#include <asm/hardware/iomd.h> 17 18 .text 19 20ENTRY(vidc_fill_1x8_u) 21 mov ip, #0xff00 221: cmp r0, r1 23 bge SYMBOL_NAME(vidc_clear) 24 ldrb r4, [r0], #1 25 eor r4, r4, #0x80 26 and r4, ip, r4, lsl #8 27 orr r4, r4, r4, lsl #16 28 str r4, [r2], #4 29 cmp r2, r3 30 blt 1b 31 mov pc, lr 32 33ENTRY(vidc_fill_2x8_u) 34 mov ip, #0xff00 351: cmp r0, r1 36 bge SYMBOL_NAME(vidc_clear) 37 ldr r4, [r0], #2 38 and r5, r4, ip 39 and r4, ip, r4, lsl #8 40 orr r4, r4, r5, lsl #16 41 orr r4, r4, r4, lsr #8 42 str r4, [r2], #4 43 cmp r2, r3 44 blt 1b 45 mov pc, lr 46 47ENTRY(vidc_fill_1x8_s) 48 mov ip, #0xff00 491: cmp r0, r1 50 bge SYMBOL_NAME(vidc_clear) 51 ldrb r4, [r0], #1 52 and r4, ip, r4, lsl #8 53 orr r4, r4, r4, lsl #16 54 str r4, [r2], #4 55 cmp r2, r3 56 blt 1b 57 mov pc, lr 58 59ENTRY(vidc_fill_2x8_s) 60 mov ip, #0xff00 611: cmp r0, r1 62 bge SYMBOL_NAME(vidc_clear) 63 ldr r4, [r0], #2 64 and r5, r4, ip 65 and r4, ip, r4, lsl #8 66 orr r4, r4, r5, lsl #16 67 orr r4, r4, r4, lsr #8 68 str r4, [r2], #4 69 cmp r2, r3 70 blt 1b 71 mov pc, lr 72 73ENTRY(vidc_fill_1x16_s) 74 mov ip, #0xff00 75 orr ip, ip, ip, lsr #8 761: cmp r0, r1 77 bge SYMBOL_NAME(vidc_clear) 78 ldr r5, [r0], #2 79 and r4, r5, ip 80 orr r4, r4, r4, lsl #16 81 str r4, [r2], #4 82 cmp r0, r1 83 addlt r0, r0, #2 84 andlt r4, r5, ip, lsl #16 85 orrlt r4, r4, r4, lsr #16 86 strlt r4, [r2], #4 87 cmp r2, r3 88 blt 1b 89 mov pc, lr 90 91ENTRY(vidc_fill_2x16_s) 92 mov ip, #0xff00 93 orr ip, ip, ip, lsr #8 941: cmp r0, r1 95 bge SYMBOL_NAME(vidc_clear) 96 ldr r4, [r0], #4 97 str r4, [r2], #4 98 cmp r0, r1 99 ldrlt r4, [r0], #4 100 strlt r4, [r2], #4 101 cmp r2, r3 102 blt 1b 103 mov pc, lr 104 105ENTRY(vidc_fill_noaudio) 106 mov r0, #0 107 mov r1, #0 1082: mov r4, #0 109 mov r5, #0 1101: cmp r2, r3 111 stmltia r2!, {r0, r1, r4, r5} 112 blt 1b 113 mov pc, lr 114 115ENTRY(vidc_clear) 116 mov r0, #0 117 mov r1, #0 118 tst r2, #4 119 str r0, [r2], #4 120 tst r2, #8 121 stmia r2!, {r0, r1} 122 b 2b 123 124/* 125 * Call filler routines with: 126 * r0 = phys address 127 * r1 = phys end 128 * r2 = buffer 129 * Returns: 130 * r0 = new buffer address 131 * r2 = new buffer finish 132 * r4 = corrupted 133 * r5 = corrupted 134 * ip = corrupted 135 */ 136 137ENTRY(vidc_sound_dma_irq) 138 stmfd sp!, {r4 - r8, lr} 139 ldr r8, =SYMBOL_NAME(dma_start) 140 ldmia r8, {r0, r1, r2, r3, r4, r5} 141 teq r1, #0 142 adreq r4, SYMBOL_NAME(vidc_fill_noaudio) 143 moveq r7, #1 << 31 144 movne r7, #0 145 mov ip, #IOMD_BASE & 0xff000000 146 orr ip, ip, #IOMD_BASE & 0x00ff0000 147 ldrb r6, [ip, #IOMD_SD0ST] 148 tst r6, #DMA_ST_OFL @ Check for overrun 149 eorne r6, r6, #DMA_ST_AB 150 tst r6, #DMA_ST_AB 151 moveq r2, r3 @ DMAing A, update B 152 add r3, r2, r5 @ End of DMA buffer 153 add r1, r1, r0 @ End of virtual DMA buffer 154 mov lr, pc 155 mov pc, r4 @ Call fill routine (uses r4, ip) 156 sub r1, r1, r0 @ Remaining length 157 stmia r8, {r0, r1} 158 mov r0, #0 159 tst r2, #4 @ Round buffer up to 4 words 160 strne r0, [r2], #4 161 tst r2, #8 162 strne r0, [r2], #4 163 strne r0, [r2], #4 164 sub r2, r2, #16 165 mov r2, r2, lsl #20 166 movs r2, r2, lsr #20 167 orreq r2, r2, #1 << 30 @ Set L bit 168 orr r2, r2, r7 169 ldmdb r8, {r3, r4, r5} 170 tst r6, #DMA_ST_AB 171 mov ip, #IOMD_BASE & 0xff000000 172 orr ip, ip, #IOMD_BASE & 0x00ff0000 173 streq r4, [ip, #IOMD_SD0CURB] 174 strne r5, [ip, #IOMD_SD0CURA] 175 streq r2, [ip, #IOMD_SD0ENDB] 176 strne r2, [ip, #IOMD_SD0ENDA] 177 ldr lr, [ip, #IOMD_SD0ST] 178 tst lr, #DMA_ST_OFL 179 bne 1f 180 tst r6, #DMA_ST_AB 181 strne r4, [ip, #IOMD_SD0CURB] 182 streq r5, [ip, #IOMD_SD0CURA] 183 strne r2, [ip, #IOMD_SD0ENDB] 184 streq r2, [ip, #IOMD_SD0ENDA] 1851: teq r7, #0 186 mov r0, #0x10 187 strneb r0, [ip, #IOMD_SD0CR] 188 ldmfd sp!, {r4 - r8, lr} 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 SYMBOL_NAME(dma_interrupt) 197SYMBOL_NAME(dma_interrupt): 198 .long 0 @ r3 199 .globl SYMBOL_NAME(dma_pbuf) 200SYMBOL_NAME(dma_pbuf): 201 .long 0 @ r4 202 .long 0 @ r5 203 .globl SYMBOL_NAME(dma_start) 204SYMBOL_NAME(dma_start): 205 .long 0 @ r0 206 .globl SYMBOL_NAME(dma_count) 207SYMBOL_NAME(dma_count): 208 .long 0 @ r1 209 .globl SYMBOL_NAME(dma_buf) 210SYMBOL_NAME(dma_buf): 211 .long 0 @ r2 212 .long 0 @ r3 213 .globl SYMBOL_NAME(vidc_filler) 214SYMBOL_NAME(vidc_filler): 215 .long SYMBOL_NAME(vidc_fill_noaudio) @ r4 216 .globl SYMBOL_NAME(dma_bufsize) 217SYMBOL_NAME(dma_bufsize): 218 .long 0x1000 @ r5 219