Lines Matching +full:sun4i +full:- +full:a10 +full:- +full:dma
1 /*-
2 * Copyright (c) 2014-2016 Jared D. McNeill <jmcneill@invisible.ca>
29 * Allwinner A10/A20 DMA controller
83 { -1, 0 }
86 #define DMA_READ(sc, reg) bus_read_4((sc)->sc_res[0], (reg))
87 #define DMA_WRITE(sc, reg, val) bus_write_4((sc)->sc_res[0], (reg), (val))
89 DMA_READ((ch)->ch_sc, (reg) + (ch)->ch_regoff)
91 DMA_WRITE((ch)->ch_sc, (reg) + (ch)->ch_regoff, (val))
101 if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-dma")) in a10dmac_probe()
104 device_set_desc(dev, "Allwinner DMA controller"); in a10dmac_probe()
118 if (bus_alloc_resources(dev, a10dmac_spec, sc->sc_res)) { in a10dmac_attach()
123 mtx_init(&sc->sc_mtx, "a10 dmac", NULL, MTX_SPIN); in a10dmac_attach()
125 /* Activate DMA controller clock */ in a10dmac_attach()
143 sc->sc_ndma_channels[index].ch_sc = sc; in a10dmac_attach()
144 sc->sc_ndma_channels[index].ch_index = index; in a10dmac_attach()
145 sc->sc_ndma_channels[index].ch_type = CH_NDMA; in a10dmac_attach()
146 sc->sc_ndma_channels[index].ch_callback = NULL; in a10dmac_attach()
147 sc->sc_ndma_channels[index].ch_callbackarg = NULL; in a10dmac_attach()
148 sc->sc_ndma_channels[index].ch_regoff = AWIN_NDMA_REG(index); in a10dmac_attach()
149 DMACH_WRITE(&sc->sc_ndma_channels[index], AWIN_NDMA_CTL_REG, 0); in a10dmac_attach()
152 sc->sc_ddma_channels[index].ch_sc = sc; in a10dmac_attach()
153 sc->sc_ddma_channels[index].ch_index = index; in a10dmac_attach()
154 sc->sc_ddma_channels[index].ch_type = CH_DDMA; in a10dmac_attach()
155 sc->sc_ddma_channels[index].ch_callback = NULL; in a10dmac_attach()
156 sc->sc_ddma_channels[index].ch_callbackarg = NULL; in a10dmac_attach()
157 sc->sc_ddma_channels[index].ch_regoff = AWIN_DDMA_REG(index); in a10dmac_attach()
158 DMACH_WRITE(&sc->sc_ddma_channels[index], AWIN_DDMA_CTL_REG, 0); in a10dmac_attach()
161 error = bus_setup_intr(dev, sc->sc_res[1], INTR_MPSAFE | INTR_TYPE_MISC, in a10dmac_attach()
162 NULL, a10dmac_intr, sc, &sc->sc_ih); in a10dmac_attach()
165 bus_release_resources(dev, a10dmac_spec, sc->sc_res); in a10dmac_attach()
166 mtx_destroy(&sc->sc_mtx); in a10dmac_attach()
185 mask = (1U << (bit - 1)); in a10dmac_intr()
191 * pending). The 8 normal DMA channel status are in the lower in a10dmac_intr()
192 * 16 bits and the 8 dedicated DMA channel status are in in a10dmac_intr()
193 * the upper 16 bits. The output is a channel number from 0-7. in a10dmac_intr()
195 index = ((bit - 1) / 2) & 7; in a10dmac_intr()
197 if (sc->sc_ndma_channels[index].ch_callback == NULL) in a10dmac_intr()
199 sc->sc_ndma_channels[index].ch_callback( in a10dmac_intr()
200 sc->sc_ndma_channels[index].ch_callbackarg); in a10dmac_intr()
202 if (sc->sc_ddma_channels[index].ch_callback == NULL) in a10dmac_intr()
204 sc->sc_ddma_channels[index].ch_callback( in a10dmac_intr()
205 sc->sc_ddma_channels[index].ch_callbackarg); in a10dmac_intr()
213 if (ch->ch_type == CH_NDMA) { in a10dmac_read_ctl()
223 if (ch->ch_type == CH_NDMA) { in a10dmac_write_ctl()
238 switch (cfg->dst_width) { in a10dmac_set_config()
251 switch (cfg->dst_burst_len) { in a10dmac_set_config()
264 switch (cfg->src_width) { in a10dmac_set_config()
277 switch (cfg->src_burst_len) { in a10dmac_set_config()
293 (cfg->dst_drqtype << AWIN_DMA_CTL_DST_DRQ_TYPE_SHIFT) | in a10dmac_set_config()
296 (cfg->src_drqtype << AWIN_DMA_CTL_SRC_DRQ_TYPE_SHIFT); in a10dmac_set_config()
298 if (ch->ch_type == CH_NDMA) { in a10dmac_set_config()
299 if (cfg->dst_noincr) in a10dmac_set_config()
301 if (cfg->src_noincr) in a10dmac_set_config()
306 dst_am = cfg->dst_noincr ? AWIN_DDMA_CTL_DMA_ADDR_IO : in a10dmac_set_config()
308 src_am = cfg->src_noincr ? AWIN_DDMA_CTL_DMA_ADDR_IO : in a10dmac_set_config()
316 dst_bs = cfg->dst_blksize - 1; in a10dmac_set_config()
317 dst_wc = cfg->dst_wait_cyc - 1; in a10dmac_set_config()
318 src_bs = cfg->src_blksize - 1; in a10dmac_set_config()
319 src_wc = cfg->src_wait_cyc - 1; in a10dmac_set_config()
341 ch_list = sc->sc_ddma_channels; in a10dmac_alloc()
344 ch_list = sc->sc_ndma_channels; in a10dmac_alloc()
348 mtx_lock_spin(&sc->sc_mtx); in a10dmac_alloc()
352 ch->ch_callback = cb; in a10dmac_alloc()
353 ch->ch_callbackarg = cbarg; in a10dmac_alloc()
356 if (ch->ch_type == CH_NDMA) in a10dmac_alloc()
365 mtx_unlock_spin(&sc->sc_mtx); in a10dmac_alloc()
374 struct a10dmac_softc *sc = ch->ch_sc; in a10dmac_free()
377 mtx_lock_spin(&sc->sc_mtx); in a10dmac_free()
381 if (ch->ch_type == CH_NDMA) { in a10dmac_free()
382 sta = AWIN_DMA_IRQ_NDMA_END(ch->ch_index); in a10dmac_free()
385 sta = AWIN_DMA_IRQ_DDMA_END(ch->ch_index); in a10dmac_free()
393 ch->ch_callback = NULL; in a10dmac_free()
394 ch->ch_callbackarg = NULL; in a10dmac_free()
396 mtx_unlock_spin(&sc->sc_mtx); in a10dmac_free()
407 if (ch->ch_type == CH_NDMA) { in a10dmac_transfer()
439 if (ch->ch_type == CH_NDMA) { in a10dmac_halt()
452 /* sunxi DMA interface */