Lines Matching refs:bdma_chan

68 				struct tsi721_bdma_chan *bdma_chan)  in tsi721_dma_first_active()  argument
70 return list_first_entry(&bdma_chan->active_list, in tsi721_dma_first_active()
74 static int tsi721_bdma_ch_init(struct tsi721_bdma_chan *bdma_chan, int bd_num) in tsi721_bdma_ch_init() argument
77 struct device *dev = bdma_chan->dchan.device->dev; in tsi721_bdma_ch_init()
83 struct tsi721_device *priv = to_tsi721(bdma_chan->dchan.device); in tsi721_bdma_ch_init()
86 dev_dbg(dev, "Init Block DMA Engine, CH%d\n", bdma_chan->id); in tsi721_bdma_ch_init()
98 bdma_chan->bd_num = bd_num; in tsi721_bdma_ch_init()
99 bdma_chan->bd_phys = bd_phys; in tsi721_bdma_ch_init()
100 bdma_chan->bd_base = bd_ptr; in tsi721_bdma_ch_init()
117 bdma_chan->bd_base = NULL; in tsi721_bdma_ch_init()
121 bdma_chan->sts_phys = sts_phys; in tsi721_bdma_ch_init()
122 bdma_chan->sts_base = sts_ptr; in tsi721_bdma_ch_init()
123 bdma_chan->sts_size = sts_size; in tsi721_bdma_ch_init()
137 bdma_chan->regs + TSI721_DMAC_DPTRH); in tsi721_bdma_ch_init()
139 bdma_chan->regs + TSI721_DMAC_DPTRL); in tsi721_bdma_ch_init()
143 bdma_chan->regs + TSI721_DMAC_DSBH); in tsi721_bdma_ch_init()
145 bdma_chan->regs + TSI721_DMAC_DSBL); in tsi721_bdma_ch_init()
147 bdma_chan->regs + TSI721_DMAC_DSSZ); in tsi721_bdma_ch_init()
151 bdma_chan->regs + TSI721_DMAC_INT); in tsi721_bdma_ch_init()
153 ioread32(bdma_chan->regs + TSI721_DMAC_INT); in tsi721_bdma_ch_init()
160 idx = TSI721_VECT_DMA0_DONE + bdma_chan->id; in tsi721_bdma_ch_init()
163 priv->msix[idx].irq_name, (void *)bdma_chan); in tsi721_bdma_ch_init()
167 bdma_chan->id); in tsi721_bdma_ch_init()
171 idx = TSI721_VECT_DMA0_INT + bdma_chan->id; in tsi721_bdma_ch_init()
174 priv->msix[idx].irq_name, (void *)bdma_chan); in tsi721_bdma_ch_init()
178 bdma_chan->id); in tsi721_bdma_ch_init()
181 bdma_chan->id].vector, in tsi721_bdma_ch_init()
182 (void *)bdma_chan); in tsi721_bdma_ch_init()
191 bdma_chan->bd_base = NULL; in tsi721_bdma_ch_init()
197 bdma_chan->sts_base = NULL; in tsi721_bdma_ch_init()
205 iowrite32(TSI721_DMAC_CTL_INIT, bdma_chan->regs + TSI721_DMAC_CTL); in tsi721_bdma_ch_init()
206 ioread32(bdma_chan->regs + TSI721_DMAC_CTL); in tsi721_bdma_ch_init()
207 bdma_chan->wr_count = bdma_chan->wr_count_next = 0; in tsi721_bdma_ch_init()
208 bdma_chan->sts_rdptr = 0; in tsi721_bdma_ch_init()
214 static int tsi721_bdma_ch_free(struct tsi721_bdma_chan *bdma_chan) in tsi721_bdma_ch_free() argument
218 struct tsi721_device *priv = to_tsi721(bdma_chan->dchan.device); in tsi721_bdma_ch_free()
221 if (bdma_chan->bd_base == NULL) in tsi721_bdma_ch_free()
225 ch_stat = ioread32(bdma_chan->regs + TSI721_DMAC_STS); in tsi721_bdma_ch_free()
230 iowrite32(TSI721_DMAC_CTL_INIT, bdma_chan->regs + TSI721_DMAC_CTL); in tsi721_bdma_ch_free()
235 bdma_chan->id].vector, (void *)bdma_chan); in tsi721_bdma_ch_free()
237 bdma_chan->id].vector, (void *)bdma_chan); in tsi721_bdma_ch_free()
242 dma_free_coherent(bdma_chan->dchan.device->dev, in tsi721_bdma_ch_free()
243 (bdma_chan->bd_num + 1) * sizeof(struct tsi721_dma_desc), in tsi721_bdma_ch_free()
244 bdma_chan->bd_base, bdma_chan->bd_phys); in tsi721_bdma_ch_free()
245 bdma_chan->bd_base = NULL; in tsi721_bdma_ch_free()
248 dma_free_coherent(bdma_chan->dchan.device->dev, in tsi721_bdma_ch_free()
249 bdma_chan->sts_size * sizeof(struct tsi721_dma_sts), in tsi721_bdma_ch_free()
250 bdma_chan->sts_base, bdma_chan->sts_phys); in tsi721_bdma_ch_free()
251 bdma_chan->sts_base = NULL; in tsi721_bdma_ch_free()
256 tsi721_bdma_interrupt_enable(struct tsi721_bdma_chan *bdma_chan, int enable) in tsi721_bdma_interrupt_enable() argument
261 bdma_chan->regs + TSI721_DMAC_INT); in tsi721_bdma_interrupt_enable()
262 ioread32(bdma_chan->regs + TSI721_DMAC_INT); in tsi721_bdma_interrupt_enable()
265 bdma_chan->regs + TSI721_DMAC_INTE); in tsi721_bdma_interrupt_enable()
268 iowrite32(0, bdma_chan->regs + TSI721_DMAC_INTE); in tsi721_bdma_interrupt_enable()
271 bdma_chan->regs + TSI721_DMAC_INT); in tsi721_bdma_interrupt_enable()
276 static bool tsi721_dma_is_idle(struct tsi721_bdma_chan *bdma_chan) in tsi721_dma_is_idle() argument
280 sts = ioread32(bdma_chan->regs + TSI721_DMAC_STS); in tsi721_dma_is_idle()
284 void tsi721_bdma_handler(struct tsi721_bdma_chan *bdma_chan) in tsi721_bdma_handler() argument
287 iowrite32(0, bdma_chan->regs + TSI721_DMAC_INTE); in tsi721_bdma_handler()
288 if (bdma_chan->active) in tsi721_bdma_handler()
289 tasklet_schedule(&bdma_chan->tasklet); in tsi721_bdma_handler()
302 struct tsi721_bdma_chan *bdma_chan = ptr; in tsi721_bdma_msix() local
304 tsi721_bdma_handler(bdma_chan); in tsi721_bdma_msix()
310 static void tsi721_start_dma(struct tsi721_bdma_chan *bdma_chan) in tsi721_start_dma() argument
312 if (!tsi721_dma_is_idle(bdma_chan)) { in tsi721_start_dma()
313 dev_err(bdma_chan->dchan.device->dev, in tsi721_start_dma()
318 if (bdma_chan->wr_count == bdma_chan->wr_count_next) { in tsi721_start_dma()
319 dev_err(bdma_chan->dchan.device->dev, in tsi721_start_dma()
324 dev_dbg(bdma_chan->dchan.device->dev, in tsi721_start_dma()
325 "%s: chan_%d (wrc=%d)\n", __func__, bdma_chan->id, in tsi721_start_dma()
326 bdma_chan->wr_count_next); in tsi721_start_dma()
328 iowrite32(bdma_chan->wr_count_next, in tsi721_start_dma()
329 bdma_chan->regs + TSI721_DMAC_DWRCNT); in tsi721_start_dma()
330 ioread32(bdma_chan->regs + TSI721_DMAC_DWRCNT); in tsi721_start_dma()
332 bdma_chan->wr_count = bdma_chan->wr_count_next; in tsi721_start_dma()
377 static void tsi721_dma_tx_err(struct tsi721_bdma_chan *bdma_chan, in tsi721_dma_tx_err() argument
384 list_move(&desc->desc_node, &bdma_chan->free_list); in tsi721_dma_tx_err()
390 static void tsi721_clr_stat(struct tsi721_bdma_chan *bdma_chan) in tsi721_clr_stat() argument
397 srd_ptr = bdma_chan->sts_rdptr; in tsi721_clr_stat()
398 sts_ptr = bdma_chan->sts_base; in tsi721_clr_stat()
405 srd_ptr %= bdma_chan->sts_size; in tsi721_clr_stat()
409 iowrite32(srd_ptr, bdma_chan->regs + TSI721_DMAC_DSRP); in tsi721_clr_stat()
410 bdma_chan->sts_rdptr = srd_ptr; in tsi721_clr_stat()
417 struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan); in tsi721_submit_sg() local
429 if (!tsi721_dma_is_idle(bdma_chan)) { in tsi721_submit_sg()
430 dev_err(bdma_chan->dchan.device->dev, in tsi721_submit_sg()
442 sys_size = dma_to_mport(bdma_chan->dchan.device)->sys_size; in tsi721_submit_sg()
444 rd_idx = ioread32(bdma_chan->regs + TSI721_DMAC_DRDCNT); in tsi721_submit_sg()
445 rd_idx %= (bdma_chan->bd_num + 1); in tsi721_submit_sg()
447 idx = bdma_chan->wr_count_next % (bdma_chan->bd_num + 1); in tsi721_submit_sg()
448 if (idx == bdma_chan->bd_num) { in tsi721_submit_sg()
498 bd_ptr = &((struct tsi721_dma_desc *)bdma_chan->bd_base)[idx]; in tsi721_submit_sg()
513 if (++idx == bdma_chan->bd_num) { in tsi721_submit_sg()
532 bdma_chan->wr_count_next += add_count; in tsi721_submit_sg()
537 static void tsi721_advance_work(struct tsi721_bdma_chan *bdma_chan) in tsi721_advance_work() argument
542 dev_dbg(bdma_chan->dchan.device->dev, "%s: Enter\n", __func__); in tsi721_advance_work()
548 if (!list_empty(&bdma_chan->queue)) in tsi721_advance_work()
549 list_splice_init(&bdma_chan->queue, &bdma_chan->active_list); in tsi721_advance_work()
552 if (!list_empty(&bdma_chan->active_list)) { in tsi721_advance_work()
553 desc = tsi721_dma_first_active(bdma_chan); in tsi721_advance_work()
556 tsi721_start_dma(bdma_chan); in tsi721_advance_work()
558 tsi721_dma_tx_err(bdma_chan, desc); in tsi721_advance_work()
559 dev_dbg(bdma_chan->dchan.device->dev, in tsi721_advance_work()
565 dev_dbg(bdma_chan->dchan.device->dev, "%s: Exit\n", __func__); in tsi721_advance_work()
570 struct tsi721_bdma_chan *bdma_chan = (struct tsi721_bdma_chan *)data; in tsi721_dma_tasklet() local
573 dmac_int = ioread32(bdma_chan->regs + TSI721_DMAC_INT); in tsi721_dma_tasklet()
574 dev_dbg(bdma_chan->dchan.device->dev, "%s: DMAC%d_INT = 0x%x\n", in tsi721_dma_tasklet()
575 __func__, bdma_chan->id, dmac_int); in tsi721_dma_tasklet()
577 iowrite32(dmac_int, bdma_chan->regs + TSI721_DMAC_INT); in tsi721_dma_tasklet()
580 dmac_sts = ioread32(bdma_chan->regs + TSI721_DMAC_STS); in tsi721_dma_tasklet()
581 dev_err(bdma_chan->dchan.device->dev, in tsi721_dma_tasklet()
583 __func__, bdma_chan->id, dmac_sts); in tsi721_dma_tasklet()
587 dev_err(bdma_chan->dchan.device->dev, in tsi721_dma_tasklet()
589 __func__, bdma_chan->id); in tsi721_dma_tasklet()
595 tsi721_clr_stat(bdma_chan); in tsi721_dma_tasklet()
596 spin_lock(&bdma_chan->lock); in tsi721_dma_tasklet()
597 desc = tsi721_dma_first_active(bdma_chan); in tsi721_dma_tasklet()
609 list_move(&desc->desc_node, &bdma_chan->free_list); in tsi721_dma_tasklet()
610 spin_unlock(&bdma_chan->lock); in tsi721_dma_tasklet()
613 spin_lock(&bdma_chan->lock); in tsi721_dma_tasklet()
616 tsi721_advance_work(bdma_chan); in tsi721_dma_tasklet()
617 spin_unlock(&bdma_chan->lock); in tsi721_dma_tasklet()
621 iowrite32(TSI721_DMAC_INT_ALL, bdma_chan->regs + TSI721_DMAC_INTE); in tsi721_dma_tasklet()
627 struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(txd->chan); in tsi721_tx_submit() local
632 dev_err(bdma_chan->dchan.device->dev, in tsi721_tx_submit()
637 spin_lock_bh(&bdma_chan->lock); in tsi721_tx_submit()
639 if (!bdma_chan->active) { in tsi721_tx_submit()
640 spin_unlock_bh(&bdma_chan->lock); in tsi721_tx_submit()
646 list_add_tail(&desc->desc_node, &bdma_chan->queue); in tsi721_tx_submit()
648 spin_unlock_bh(&bdma_chan->lock); in tsi721_tx_submit()
654 struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan); in tsi721_alloc_chan_resources() local
659 __func__, bdma_chan->id); in tsi721_alloc_chan_resources()
661 if (bdma_chan->bd_base) in tsi721_alloc_chan_resources()
665 if (tsi721_bdma_ch_init(bdma_chan, dma_desc_per_channel)) { in tsi721_alloc_chan_resources()
667 " channel %d, aborting\n", bdma_chan->id); in tsi721_alloc_chan_resources()
677 tsi721_bdma_ch_free(bdma_chan); in tsi721_alloc_chan_resources()
681 bdma_chan->tx_desc = desc; in tsi721_alloc_chan_resources()
687 list_add(&desc[i].desc_node, &bdma_chan->free_list); in tsi721_alloc_chan_resources()
692 bdma_chan->active = true; in tsi721_alloc_chan_resources()
693 tsi721_bdma_interrupt_enable(bdma_chan, 1); in tsi721_alloc_chan_resources()
698 static void tsi721_sync_dma_irq(struct tsi721_bdma_chan *bdma_chan) in tsi721_sync_dma_irq() argument
700 struct tsi721_device *priv = to_tsi721(bdma_chan->dchan.device); in tsi721_sync_dma_irq()
705 bdma_chan->id].vector); in tsi721_sync_dma_irq()
707 bdma_chan->id].vector); in tsi721_sync_dma_irq()
715 struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan); in tsi721_free_chan_resources() local
718 __func__, bdma_chan->id); in tsi721_free_chan_resources()
720 if (bdma_chan->bd_base == NULL) in tsi721_free_chan_resources()
723 BUG_ON(!list_empty(&bdma_chan->active_list)); in tsi721_free_chan_resources()
724 BUG_ON(!list_empty(&bdma_chan->queue)); in tsi721_free_chan_resources()
726 tsi721_bdma_interrupt_enable(bdma_chan, 0); in tsi721_free_chan_resources()
727 bdma_chan->active = false; in tsi721_free_chan_resources()
728 tsi721_sync_dma_irq(bdma_chan); in tsi721_free_chan_resources()
729 tasklet_kill(&bdma_chan->tasklet); in tsi721_free_chan_resources()
730 INIT_LIST_HEAD(&bdma_chan->free_list); in tsi721_free_chan_resources()
731 kfree(bdma_chan->tx_desc); in tsi721_free_chan_resources()
732 tsi721_bdma_ch_free(bdma_chan); in tsi721_free_chan_resources()
744 struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan); in tsi721_issue_pending() local
748 if (tsi721_dma_is_idle(bdma_chan) && bdma_chan->active) { in tsi721_issue_pending()
749 spin_lock_bh(&bdma_chan->lock); in tsi721_issue_pending()
750 tsi721_advance_work(bdma_chan); in tsi721_issue_pending()
751 spin_unlock_bh(&bdma_chan->lock); in tsi721_issue_pending()
761 struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan); in tsi721_prep_rio_sg() local
796 spin_lock_bh(&bdma_chan->lock); in tsi721_prep_rio_sg()
798 list_for_each_entry_safe(desc, _d, &bdma_chan->free_list, desc_node) { in tsi721_prep_rio_sg()
813 spin_unlock_bh(&bdma_chan->lock); in tsi721_prep_rio_sg()
820 struct tsi721_bdma_chan *bdma_chan = to_tsi721_chan(dchan); in tsi721_terminate_all() local
827 spin_lock_bh(&bdma_chan->lock); in tsi721_terminate_all()
829 bdma_chan->active = false; in tsi721_terminate_all()
831 if (!tsi721_dma_is_idle(bdma_chan)) { in tsi721_terminate_all()
834 bdma_chan->regs + TSI721_DMAC_CTL); in tsi721_terminate_all()
838 dmac_int = ioread32(bdma_chan->regs + TSI721_DMAC_INT); in tsi721_terminate_all()
842 list_splice_init(&bdma_chan->active_list, &list); in tsi721_terminate_all()
843 list_splice_init(&bdma_chan->queue, &list); in tsi721_terminate_all()
846 tsi721_dma_tx_err(bdma_chan, desc); in tsi721_terminate_all()
848 spin_unlock_bh(&bdma_chan->lock); in tsi721_terminate_all()
863 struct tsi721_bdma_chan *bdma_chan = &priv->bdma[i]; in tsi721_register_dma() local
868 bdma_chan->regs = priv->regs + TSI721_DMAC_BASE(i); in tsi721_register_dma()
870 bdma_chan->dchan.device = &mport->dma; in tsi721_register_dma()
871 bdma_chan->dchan.cookie = 1; in tsi721_register_dma()
872 bdma_chan->dchan.chan_id = i; in tsi721_register_dma()
873 bdma_chan->id = i; in tsi721_register_dma()
874 bdma_chan->active = false; in tsi721_register_dma()
876 spin_lock_init(&bdma_chan->lock); in tsi721_register_dma()
878 INIT_LIST_HEAD(&bdma_chan->active_list); in tsi721_register_dma()
879 INIT_LIST_HEAD(&bdma_chan->queue); in tsi721_register_dma()
880 INIT_LIST_HEAD(&bdma_chan->free_list); in tsi721_register_dma()
882 tasklet_init(&bdma_chan->tasklet, tsi721_dma_tasklet, in tsi721_register_dma()
883 (unsigned long)bdma_chan); in tsi721_register_dma()
884 list_add_tail(&bdma_chan->dchan.device_node, in tsi721_register_dma()