Lines Matching +full:dma +full:- +full:info

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
112 /* DMA Control Block - 256bit aligned (p.40) */
114 uint32_t info; /* Transfer Information */ member
129 /* DMA channel private info */
154 {"broadcom,bcm2835-dma", 1},
155 {"brcm,bcm2835-dma", 1},
183 cs = bus_read_4(sc->sc_mem, BCM_DMA_CS(ch)); in bcm_dma_reset()
187 bus_write_4(sc->sc_mem, BCM_DMA_CS(ch), 0); in bcm_dma_reset()
191 cs = bus_read_4(sc->sc_mem, BCM_DMA_CS(ch)); in bcm_dma_reset()
192 } while (!(cs & CS_ISPAUSED) && (count-- > 0)); in bcm_dma_reset()
196 "Can't abort DMA transfer at channel %d\n", ch); in bcm_dma_reset()
199 bus_write_4(sc->sc_mem, BCM_DMA_CBNEXT(ch), 0); in bcm_dma_reset()
202 bus_write_4(sc->sc_mem, BCM_DMA_CS(ch), in bcm_dma_reset()
207 bus_write_4(sc->sc_mem, BCM_DMA_CBADDR(ch), 0); in bcm_dma_reset()
208 bus_write_4(sc->sc_mem, BCM_DMA_CBNEXT(ch), 0); in bcm_dma_reset()
211 cb = sc->sc_dma_ch[ch].cb; in bcm_dma_reset()
213 cb->info = INFO_WAIT_RESP; in bcm_dma_reset()
240 reg = bus_read_4(sc->sc_mem, BCM_DMA_ENABLE); in bcm_dma_init()
243 reg = bus_read_4(sc->sc_mem, BCM_DMA_INT_STATUS); in bcm_dma_init()
248 * Allocate DMA chunks control blocks based on p.40 of the peripheral in bcm_dma_init()
249 * spec - control block should be 32-bit aligned. The DMA controller in bcm_dma_init()
250 * has a full 32-bit register dedicated to this address, so we do not in bcm_dma_init()
251 * need to bother with the per-SoC peripheral restrictions. in bcm_dma_init()
259 &sc->sc_dma_tag); in bcm_dma_init()
262 device_printf(dev, "failed allocate DMA tag\n"); in bcm_dma_init()
268 ch = &sc->sc_dma_ch[i]; in bcm_dma_init()
271 ch->ch = i; in bcm_dma_init()
272 ch->flags = BCM_DMA_CH_UNMAP; in bcm_dma_init()
277 err = bus_dmamem_alloc(sc->sc_dma_tag, &cb_virt, in bcm_dma_init()
279 &ch->dma_map); in bcm_dma_init()
281 device_printf(dev, "cannot allocate DMA memory\n"); in bcm_dma_init()
286 * Least alignment for busdma-allocated stuff is cache in bcm_dma_init()
292 "DMA address is not 32-bytes aligned: %p\n", in bcm_dma_init()
297 err = bus_dmamap_load(sc->sc_dma_tag, ch->dma_map, cb_virt, in bcm_dma_init()
301 device_printf(dev, "cannot load DMA memory\n"); in bcm_dma_init()
305 ch->cb = cb_virt; in bcm_dma_init()
306 ch->vc_cb = cb_phys; in bcm_dma_init()
307 ch->flags = BCM_DMA_CH_FREE; in bcm_dma_init()
308 ch->cb->info = INFO_WAIT_RESP; in bcm_dma_init()
310 /* reset DMA engine */ in bcm_dma_init()
311 bus_write_4(sc->sc_mem, BCM_DMA_CS(i), CS_RESET); in bcm_dma_init()
318 * Allocate DMA channel for further use, returns channel # or
335 mtx_lock(&sc->sc_mtx); in bcm_dma_allocate()
339 if (sc->sc_dma_ch[i].flags & BCM_DMA_CH_FREE) { in bcm_dma_allocate()
341 sc->sc_dma_ch[ch].flags &= ~BCM_DMA_CH_FREE; in bcm_dma_allocate()
342 sc->sc_dma_ch[ch].flags |= BCM_DMA_CH_USED; in bcm_dma_allocate()
346 } else if (sc->sc_dma_ch[req_ch].flags & BCM_DMA_CH_FREE) { in bcm_dma_allocate()
348 sc->sc_dma_ch[ch].flags &= ~BCM_DMA_CH_FREE; in bcm_dma_allocate()
349 sc->sc_dma_ch[ch].flags |= BCM_DMA_CH_USED; in bcm_dma_allocate()
352 mtx_unlock(&sc->sc_mtx); in bcm_dma_allocate()
357 * Frees allocated channel. Returns 0 on success, -1 otherwise
365 return (-1); in bcm_dma_free()
368 return (-1); in bcm_dma_free()
370 mtx_lock(&sc->sc_mtx); in bcm_dma_free()
371 if (sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED) { in bcm_dma_free()
372 sc->sc_dma_ch[ch].flags |= BCM_DMA_CH_FREE; in bcm_dma_free()
373 sc->sc_dma_ch[ch].flags &= ~BCM_DMA_CH_USED; in bcm_dma_free()
374 sc->sc_dma_ch[ch].intr_func = NULL; in bcm_dma_free()
375 sc->sc_dma_ch[ch].intr_arg = NULL; in bcm_dma_free()
377 /* reset DMA engine */ in bcm_dma_free()
378 bcm_dma_reset(sc->sc_dev, ch); in bcm_dma_free()
381 mtx_unlock(&sc->sc_mtx); in bcm_dma_free()
387 * Returns 0 on success, -1 otherwise
396 return (-1); in bcm_dma_setup_intr()
399 return (-1); in bcm_dma_setup_intr()
401 if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED)) in bcm_dma_setup_intr()
402 return (-1); in bcm_dma_setup_intr()
404 sc->sc_dma_ch[ch].intr_func = func; in bcm_dma_setup_intr()
405 sc->sc_dma_ch[ch].intr_arg = arg; in bcm_dma_setup_intr()
406 cb = sc->sc_dma_ch[ch].cb; in bcm_dma_setup_intr()
407 cb->info |= INFO_INT_EN; in bcm_dma_setup_intr()
413 * Setup DMA source parameters
414 * ch - channel number
415 * dreq - hardware DREQ # or BCM_DMA_DREQ_NONE if
417 * inc_addr - BCM_DMA_INC_ADDR if source address
421 * width - size of read operation, BCM_DMA_32BIT
424 * Returns 0 on success, -1 otherwise
430 uint32_t info; in bcm_dma_setup_src() local
433 return (-1); in bcm_dma_setup_src()
435 if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED)) in bcm_dma_setup_src()
436 return (-1); in bcm_dma_setup_src()
438 info = sc->sc_dma_ch[ch].cb->info; in bcm_dma_setup_src()
439 info &= ~INFO_PERMAP_MASK; in bcm_dma_setup_src()
440 info |= (dreq << INFO_PERMAP_SHIFT) & INFO_PERMAP_MASK; in bcm_dma_setup_src()
443 info |= INFO_S_DREQ; in bcm_dma_setup_src()
445 info &= ~INFO_S_DREQ; in bcm_dma_setup_src()
448 info |= INFO_S_WIDTH; in bcm_dma_setup_src()
450 info &= ~INFO_S_WIDTH; in bcm_dma_setup_src()
453 info |= INFO_S_INC; in bcm_dma_setup_src()
455 info &= ~INFO_S_INC; in bcm_dma_setup_src()
457 sc->sc_dma_ch[ch].cb->info = info; in bcm_dma_setup_src()
463 * Setup DMA destination parameters
464 * ch - channel number
465 * dreq - hardware DREQ # or BCM_DMA_DREQ_NONE if
467 * inc_addr - BCM_DMA_INC_ADDR if source address
471 * width - size of write operation, BCM_DMA_32BIT
474 * Returns 0 on success, -1 otherwise
480 uint32_t info; in bcm_dma_setup_dst() local
483 return (-1); in bcm_dma_setup_dst()
485 if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED)) in bcm_dma_setup_dst()
486 return (-1); in bcm_dma_setup_dst()
488 info = sc->sc_dma_ch[ch].cb->info; in bcm_dma_setup_dst()
489 info &= ~INFO_PERMAP_MASK; in bcm_dma_setup_dst()
490 info |= (dreq << INFO_PERMAP_SHIFT) & INFO_PERMAP_MASK; in bcm_dma_setup_dst()
493 info |= INFO_D_DREQ; in bcm_dma_setup_dst()
495 info &= ~INFO_D_DREQ; in bcm_dma_setup_dst()
498 info |= INFO_D_WIDTH; in bcm_dma_setup_dst()
500 info &= ~INFO_D_WIDTH; in bcm_dma_setup_dst()
503 info |= INFO_D_INC; in bcm_dma_setup_dst()
505 info &= ~INFO_D_INC; in bcm_dma_setup_dst()
507 sc->sc_dma_ch[ch].cb->info = info; in bcm_dma_setup_dst()
517 printf("DMA CB "); in bcm_dma_cb_dump()
518 printf("INFO: %8.8x ", cb->info); in bcm_dma_cb_dump()
519 printf("SRC: %8.8x ", cb->src); in bcm_dma_cb_dump()
520 printf("DST: %8.8x ", cb->dst); in bcm_dma_cb_dump()
521 printf("LEN: %8.8x ", cb->len); in bcm_dma_cb_dump()
523 printf("STRIDE: %8.8x ", cb->stride); in bcm_dma_cb_dump()
524 printf("NEXT: %8.8x ", cb->next); in bcm_dma_cb_dump()
525 printf("RSVD1: %8.8x ", cb->rsvd1); in bcm_dma_cb_dump()
526 printf("RSVD2: %8.8x ", cb->rsvd2); in bcm_dma_cb_dump()
543 printf("DMA%d: ", ch); in bcm_dma_reg_dump()
545 reg = bus_read_4(sc->sc_mem, BCM_DMA_CH(ch) + i*4); in bcm_dma_reg_dump()
553 * Start DMA transaction
554 * ch - channel number
555 * src, dst - source and destination address in
557 * len - amount of bytes to be transferred
559 * Returns 0 on success, -1 otherwise
568 return (-1); in bcm_dma_start()
571 return (-1); in bcm_dma_start()
573 if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED)) in bcm_dma_start()
574 return (-1); in bcm_dma_start()
576 cb = sc->sc_dma_ch[ch].cb; in bcm_dma_start()
577 cb->src = ARMC_TO_VCBUS(src); in bcm_dma_start()
578 cb->dst = ARMC_TO_VCBUS(dst); in bcm_dma_start()
580 cb->len = len; in bcm_dma_start()
582 bus_dmamap_sync(sc->sc_dma_tag, in bcm_dma_start()
583 sc->sc_dma_ch[ch].dma_map, BUS_DMASYNC_PREWRITE); in bcm_dma_start()
585 bus_write_4(sc->sc_mem, BCM_DMA_CBADDR(ch), in bcm_dma_start()
586 sc->sc_dma_ch[ch].vc_cb); in bcm_dma_start()
587 bus_write_4(sc->sc_mem, BCM_DMA_CS(ch), CS_ACTIVE); in bcm_dma_start()
590 bcm_dma_cb_dump(sc->sc_dma_ch[ch].cb); in bcm_dma_start()
598 * Get length requested for DMA transaction
599 * ch - channel number
615 if (!(sc->sc_dma_ch[ch].flags & BCM_DMA_CH_USED)) in bcm_dma_length()
618 cb = sc->sc_dma_ch[ch].cb; in bcm_dma_length()
620 return (cb->len); in bcm_dma_length()
631 cs = bus_read_4(sc->sc_mem, BCM_DMA_CS(ch->ch)); in bcm_dma_intr()
639 if (!(ch->flags & BCM_DMA_CH_USED)) in bcm_dma_intr()
647 debug = bus_read_4(sc->sc_mem, BCM_DMA_DEBUG(ch->ch)); in bcm_dma_intr()
648 device_printf(sc->sc_dev, "DMA error %d on CH%d\n", in bcm_dma_intr()
649 debug & DEBUG_ERROR_MASK, ch->ch); in bcm_dma_intr()
650 bus_write_4(sc->sc_mem, BCM_DMA_DEBUG(ch->ch), in bcm_dma_intr()
652 bcm_dma_reset(sc->sc_dev, ch->ch); in bcm_dma_intr()
657 bus_write_4(sc->sc_mem, BCM_DMA_CS(ch->ch), in bcm_dma_intr()
661 bus_dmamap_sync(sc->sc_dma_tag, ch->dma_map, in bcm_dma_intr()
665 if (ch->intr_func) in bcm_dma_intr()
666 ch->intr_func(ch->ch, ch->intr_arg); in bcm_dma_intr()
677 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) in bcm_dma_probe()
680 device_set_desc(dev, "BCM2835 DMA Controller"); in bcm_dma_probe()
692 sc->sc_dev = dev; in bcm_dma_attach()
698 sc->sc_irq[i] = NULL; in bcm_dma_attach()
699 sc->sc_intrhand[i] = NULL; in bcm_dma_attach()
702 /* Get DMA channel mask. */ in bcm_dma_attach()
703 node = ofw_bus_get_node(sc->sc_dev); in bcm_dma_attach()
704 if (OF_getencprop(node, "brcm,dma-channel-mask", &bcm_dma_channel_mask, in bcm_dma_attach()
705 sizeof(bcm_dma_channel_mask)) == -1 && in bcm_dma_attach()
707 sizeof(bcm_dma_channel_mask)) == -1) { in bcm_dma_attach()
715 /* DMA0 - DMA14 */ in bcm_dma_attach()
717 sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); in bcm_dma_attach()
718 if (sc->sc_mem == NULL) { in bcm_dma_attach()
723 /* IRQ DMA0 - DMA11 XXX NOT USE DMA12(spurious?) */ in bcm_dma_attach()
728 sc->sc_irq[rid] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, in bcm_dma_attach()
730 if (sc->sc_irq[rid] == NULL) { in bcm_dma_attach()
735 if (bus_setup_intr(dev, sc->sc_irq[rid], INTR_TYPE_MISC | INTR_MPSAFE, in bcm_dma_attach()
736 NULL, bcm_dma_intr, &sc->sc_dma_ch[rid], in bcm_dma_attach()
737 &sc->sc_intrhand[rid])) { in bcm_dma_attach()
744 mtx_init(&sc->sc_mtx, "bcmdma", "bcmdma", MTX_DEF); in bcm_dma_attach()
754 if (sc->sc_mem) in bcm_dma_attach()
755 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem); in bcm_dma_attach()
758 if (sc->sc_intrhand[i]) in bcm_dma_attach()
759 bus_teardown_intr(dev, sc->sc_irq[i], sc->sc_intrhand[i]); in bcm_dma_attach()
760 if (sc->sc_irq[i]) in bcm_dma_attach()
761 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq[i]); in bcm_dma_attach()