Lines Matching +full:dma +full:- +full:channel
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
59 dbdma_channel_t *channel; /* DBDMA channel */ member
61 struct pcm_channel *pcm; /* PCM channel */
71 aoa_dma_set_program(struct aoa_dma *dma) in aoa_dma_set_program() argument
76 addr = (u_int32_t)dma->buf->buf_addr; in aoa_dma_set_program()
77 KASSERT(dma->bufsz == dma->buf->bufsize, ("bad size")); in aoa_dma_set_program()
79 dma->slots = dma->bufsz / dma->blksz; in aoa_dma_set_program()
81 for (i = 0; i < dma->slots; ++i) { in aoa_dma_set_program()
82 dbdma_insert_command(dma->channel, in aoa_dma_set_program()
87 dma->blksz, /* count */ in aoa_dma_set_program()
91 dma->slots + 1 /* branch_slot */ in aoa_dma_set_program()
94 addr += dma->blksz; in aoa_dma_set_program()
98 dbdma_insert_branch(dma->channel, dma->slots, 0); in aoa_dma_set_program()
101 dbdma_insert_stop(dma->channel, dma->slots + 1); in aoa_dma_set_program()
104 dbdma_set_branch_selector(dma->channel, 1 << 0, 1 << 0); in aoa_dma_set_program()
105 dbdma_set_device_status(dma->channel, 1 << 0, 0); in aoa_dma_set_program()
107 dbdma_sync_commands(dma->channel, BUS_DMASYNC_PREWRITE); in aoa_dma_set_program()
115 struct aoa_dma *dma; in aoa_dma_create() local
120 self = sc->sc_dev; in aoa_dma_create()
127 dma = malloc(sizeof(*dma), M_DEVBUF, M_WAITOK | M_ZERO); in aoa_dma_create()
128 dma->tag = tag; in aoa_dma_create()
129 dma->bufsz = AOA_BUFFER_SIZE; in aoa_dma_create()
130 dma->blksz = PAGE_SIZE; /* initial blocksize */ in aoa_dma_create()
132 mtx_init(&dma->mutex, "AOA", NULL, MTX_DEF); in aoa_dma_create()
134 sc->sc_intrp = dma; in aoa_dma_create()
136 return (dma); in aoa_dma_create()
140 aoa_dma_delete(struct aoa_dma *dma) in aoa_dma_delete() argument
142 bus_dma_tag_destroy(dma->tag); in aoa_dma_delete()
143 mtx_destroy(&dma->mutex); in aoa_dma_delete()
144 free(dma, M_DEVBUF); in aoa_dma_delete()
150 struct aoa_dma *dma = data; in aoa_chan_setblocksize() local
153 DPRINTF(("aoa_chan_setblocksize: blocksz = %u, dma->blksz = %u\n", in aoa_chan_setblocksize()
154 blocksz, dma->blksz)); in aoa_chan_setblocksize()
155 KASSERT(!dma->running, ("dma is running")); in aoa_chan_setblocksize()
160 blocksz = 1 << (31 - lz); in aoa_chan_setblocksize()
164 if (blocksz > dma->bufsz) in aoa_chan_setblocksize()
165 blocksz = dma->bufsz; in aoa_chan_setblocksize()
167 err = sndbuf_resize(dma->buf, dma->bufsz / blocksz, blocksz); in aoa_chan_setblocksize()
173 if (blocksz == dma->blksz) in aoa_chan_setblocksize()
174 return (dma->blksz); in aoa_chan_setblocksize()
177 err = dbdma_resize_channel(dma->channel, 2 + dma->bufsz / blocksz); in aoa_chan_setblocksize()
184 dma->blksz = blocksz; in aoa_chan_setblocksize()
185 aoa_dma_set_program(dma); in aoa_chan_setblocksize()
187 return (dma->blksz); in aoa_chan_setblocksize()
212 struct aoa_dma *dma = data; in aoa_chan_getptr() local
214 if (!dma->running) in aoa_chan_getptr()
217 return (dma->slot * dma->blksz); in aoa_chan_getptr()
225 struct aoa_dma *dma; in aoa_chan_init() local
230 dma = aoa_dma_create(sc); in aoa_chan_init()
231 if (!dma) in aoa_chan_init()
233 dma->pcm = c; in aoa_chan_init()
234 dma->buf = b; in aoa_chan_init()
235 dma->reg = sc->sc_odma; in aoa_chan_init()
238 max_slots = 2 + dma->bufsz / dma->blksz; in aoa_chan_init()
239 err = dbdma_allocate_channel(dma->reg, 0, bus_get_dma_tag(sc->sc_dev), in aoa_chan_init()
240 max_slots, &dma->channel ); in aoa_chan_init()
242 aoa_dma_delete(dma); in aoa_chan_init()
246 if (sndbuf_alloc(dma->buf, dma->tag, 0, dma->bufsz) != 0) { in aoa_chan_init()
247 dbdma_free_channel(dma->channel); in aoa_chan_init()
248 aoa_dma_delete(dma); in aoa_chan_init()
252 aoa_dma_set_program(dma); in aoa_chan_init()
254 return (dma); in aoa_chan_init()
260 struct aoa_dma *dma = data; in aoa_chan_trigger() local
266 /* Start the DMA. */ in aoa_chan_trigger()
267 dma->running = 1; in aoa_chan_trigger()
269 dma->slot = 0; in aoa_chan_trigger()
270 dbdma_set_current_cmd(dma->channel, dma->slot); in aoa_chan_trigger()
272 dbdma_run(dma->channel); in aoa_chan_trigger()
279 mtx_lock(&dma->mutex); in aoa_chan_trigger()
281 dma->running = 0; in aoa_chan_trigger()
284 dbdma_set_device_status(dma->channel, 1 << 0, 1 << 0); in aoa_chan_trigger()
289 /* Reset the DMA. */ in aoa_chan_trigger()
290 dbdma_stop(dma->channel); in aoa_chan_trigger()
291 dbdma_set_device_status(dma->channel, 1 << 0, 0); in aoa_chan_trigger()
293 for (i = 0; i < dma->slots; ++i) in aoa_chan_trigger()
294 dbdma_clear_cmd_status(dma->channel, i); in aoa_chan_trigger()
296 mtx_unlock(&dma->mutex); in aoa_chan_trigger()
307 struct aoa_dma *dma = data; in aoa_chan_free() local
309 sndbuf_free(dma->buf); in aoa_chan_free()
310 dbdma_free_channel(dma->channel); in aoa_chan_free()
311 aoa_dma_delete(dma); in aoa_chan_free()
320 struct aoa_dma *dma; in aoa_interrupt() local
322 if (!(dma = sc->sc_intrp) || !dma->running) in aoa_interrupt()
325 mtx_lock(&dma->mutex); in aoa_interrupt()
327 while (dbdma_get_cmd_status(dma->channel, dma->slot)) { in aoa_interrupt()
328 dbdma_clear_cmd_status(dma->channel, dma->slot); in aoa_interrupt()
329 dma->slot = (dma->slot + 1) % dma->slots; in aoa_interrupt()
331 mtx_unlock(&dma->mutex); in aoa_interrupt()
332 chn_intr(dma->pcm); in aoa_interrupt()
333 mtx_lock(&dma->mutex); in aoa_interrupt()
336 mtx_unlock(&dma->mutex); in aoa_interrupt()
373 self = sc->sc_dev; in aoa_attach()