Lines Matching +full:8 +full:- +full:ch
1 /*-
56 #define DMA_IRQ_EN_REG(ch) (DMA_IRQ_EN_REG0 + ((ch) / 8) * 4) argument
57 #define DMA_PKG_IRQ_EN(ch) (1 << (((ch) % 8) * 4 + 1)) argument
61 #define DMA_IRQ_PEND_REG(ch) (DMA_IRQ_PEND_REG0 + ((ch) / 8) * 4) argument
119 static const struct a31dmac_config a83t_config = { .nchans = 8 };
120 static const struct a31dmac_config a64_config = { .nchans = 8 };
123 { "allwinner,sun6i-a31-dma", (uintptr_t)&a31_config },
124 { "allwinner,sun8i-a83t-dma", (uintptr_t)&a83t_config },
125 { "allwinner,sun8i-h3-dma", (uintptr_t)&h3_config },
126 { "allwinner,sun50i-a64-dma", (uintptr_t)&a64_config },
157 { -1, 0 }
160 #define DMA_READ(sc, reg) bus_read_4((sc)->res[0], (reg))
161 #define DMA_WRITE(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val))
172 if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) in a31dmac_probe()
190 conf = (void *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; in a31dmac_attach()
194 if (bus_alloc_resources(dev, a31dmac_spec, sc->res)) { in a31dmac_attach()
199 mtx_init(&sc->mtx, "a31 dmac", NULL, MTX_SPIN); in a31dmac_attach()
215 device_printf(dev, "cannot de-assert reset\n"); in a31dmac_attach()
230 &sc->dmat); in a31dmac_attach()
243 sc->nchans = conf->nchans; in a31dmac_attach()
244 sc->chans = malloc(sizeof(*sc->chans) * sc->nchans, M_DEVBUF, in a31dmac_attach()
247 for (index = 0; index < sc->nchans; index++) { in a31dmac_attach()
248 sc->chans[index].sc = sc; in a31dmac_attach()
249 sc->chans[index].index = index; in a31dmac_attach()
250 sc->chans[index].callback = NULL; in a31dmac_attach()
251 sc->chans[index].callbackarg = NULL; in a31dmac_attach()
253 error = bus_dmamem_alloc(sc->dmat, in a31dmac_attach()
254 (void **)&sc->chans[index].desc, in a31dmac_attach()
256 &sc->chans[index].dmamap); in a31dmac_attach()
261 error = bus_dmamap_load(sc->dmat, sc->chans[index].dmamap, in a31dmac_attach()
262 sc->chans[index].desc, sizeof(*sc->chans[index].desc), in a31dmac_attach()
263 a31dmac_dmamap_cb, &sc->chans[index], BUS_DMA_WAITOK); in a31dmac_attach()
272 error = bus_setup_intr(dev, sc->res[1], INTR_MPSAFE | INTR_TYPE_MISC, in a31dmac_attach()
273 NULL, a31dmac_intr, sc, &sc->ih); in a31dmac_attach()
276 bus_release_resources(dev, a31dmac_spec, sc->res); in a31dmac_attach()
277 mtx_destroy(&sc->mtx); in a31dmac_attach()
285 for (index = 0; index < sc->nchans; index++) in a31dmac_attach()
286 if (sc->chans[index].desc != NULL) { in a31dmac_attach()
287 bus_dmamap_unload(sc->dmat, sc->chans[index].dmamap); in a31dmac_attach()
288 bus_dmamem_free(sc->dmat, sc->chans[index].desc, in a31dmac_attach()
289 sc->chans[index].dmamap); in a31dmac_attach()
291 if (sc->chans != NULL) in a31dmac_attach()
292 free(sc->chans, M_DEVBUF); in a31dmac_attach()
293 if (sc->ih != NULL) in a31dmac_attach()
294 bus_teardown_intr(dev, sc->res[1], sc->ih); in a31dmac_attach()
299 bus_release_resources(dev, a31dmac_spec, sc->res); in a31dmac_attach()
307 struct a31dmac_channel *ch; in a31dmac_dmamap_cb() local
312 ch = priv; in a31dmac_dmamap_cb()
313 ch->physaddr = segs[0].ds_addr; in a31dmac_dmamap_cb()
326 pend1 = sc->nchans > 8 ? DMA_READ(sc, DMA_IRQ_PEND_REG1) : 0; in a31dmac_intr()
338 mask = (1U << (bit - 1)); in a31dmac_intr()
340 index = (bit - 1) / 4; in a31dmac_intr()
342 if (index >= sc->nchans) in a31dmac_intr()
344 if (sc->chans[index].callback == NULL) in a31dmac_intr()
346 sc->chans[index].callback(sc->chans[index].callbackarg); in a31dmac_intr()
353 struct a31dmac_channel *ch; in a31dmac_set_config() local
358 ch = priv; in a31dmac_set_config()
360 switch (cfg->dst_width) { in a31dmac_set_config()
361 case 8: in a31dmac_set_config()
376 switch (cfg->dst_burst_len) { in a31dmac_set_config()
383 case 8: in a31dmac_set_config()
392 switch (cfg->src_width) { in a31dmac_set_config()
393 case 8: in a31dmac_set_config()
407 switch (cfg->src_burst_len) { in a31dmac_set_config()
414 case 8: in a31dmac_set_config()
423 dst_am = cfg->dst_noincr ? DMA_ADDR_MODE_IO : DMA_ADDR_MODE_LINEAR; in a31dmac_set_config()
424 src_am = cfg->src_noincr ? DMA_ADDR_MODE_IO : DMA_ADDR_MODE_LINEAR; in a31dmac_set_config()
425 dst_wc = cfg->dst_wait_cyc; in a31dmac_set_config()
426 src_wc = cfg->src_wait_cyc; in a31dmac_set_config()
433 (cfg->dst_drqtype << DMA_DEST_DRQ_TYPE_SHIFT) | in a31dmac_set_config()
437 (cfg->src_drqtype << DMA_SRC_DRQ_TYPE_SHIFT); in a31dmac_set_config()
440 ch->desc->config = htole32(config); in a31dmac_set_config()
441 ch->desc->para = htole32(para); in a31dmac_set_config()
450 struct a31dmac_channel *ch; in a31dmac_alloc() local
455 ch = NULL; in a31dmac_alloc()
457 mtx_lock_spin(&sc->mtx); in a31dmac_alloc()
458 for (index = 0; index < sc->nchans; index++) { in a31dmac_alloc()
459 if (sc->chans[index].callback == NULL) { in a31dmac_alloc()
460 ch = &sc->chans[index]; in a31dmac_alloc()
461 ch->callback = cb; in a31dmac_alloc()
462 ch->callbackarg = cbarg; in a31dmac_alloc()
470 mtx_unlock_spin(&sc->mtx); in a31dmac_alloc()
472 return (ch); in a31dmac_alloc()
478 struct a31dmac_channel *ch; in a31dmac_free() local
483 ch = priv; in a31dmac_free()
484 sc = ch->sc; in a31dmac_free()
485 index = ch->index; in a31dmac_free()
487 mtx_lock_spin(&sc->mtx); in a31dmac_free()
494 ch->callback = NULL; in a31dmac_free()
495 ch->callbackarg = NULL; in a31dmac_free()
497 mtx_unlock_spin(&sc->mtx); in a31dmac_free()
504 struct a31dmac_channel *ch; in a31dmac_transfer() local
507 ch = priv; in a31dmac_transfer()
508 sc = ch->sc; in a31dmac_transfer()
510 ch->desc->srcaddr = htole32((uint32_t)src); in a31dmac_transfer()
511 ch->desc->dstaddr = htole32((uint32_t)dst); in a31dmac_transfer()
512 ch->desc->bcnt = htole32(nbytes); in a31dmac_transfer()
513 ch->desc->next = htole32(DMA_NULL); in a31dmac_transfer()
515 DMA_WRITE(sc, DMA_STAR_ADDR_REG(ch->index), (uint32_t)ch->physaddr); in a31dmac_transfer()
516 DMA_WRITE(sc, DMA_EN_REG(ch->index), DMA_EN); in a31dmac_transfer()
524 struct a31dmac_channel *ch; in a31dmac_halt() local
527 ch = priv; in a31dmac_halt()
528 sc = ch->sc; in a31dmac_halt()
530 DMA_WRITE(sc, DMA_EN_REG(ch->index), 0); in a31dmac_halt()