Lines Matching full:channel

189 static void rz_dmac_ch_writel(struct rz_dmac_chan *channel, unsigned int val,  in rz_dmac_ch_writel()  argument
193 writel(val, channel->ch_base + offset); in rz_dmac_ch_writel()
195 writel(val, channel->ch_cmn_base + offset); in rz_dmac_ch_writel()
198 static u32 rz_dmac_ch_readl(struct rz_dmac_chan *channel, in rz_dmac_ch_readl() argument
202 return readl(channel->ch_base + offset); in rz_dmac_ch_readl()
204 return readl(channel->ch_cmn_base + offset); in rz_dmac_ch_readl()
212 static void rz_lmdesc_setup(struct rz_dmac_chan *channel, in rz_lmdesc_setup() argument
217 channel->lmdesc.base = lmdesc; in rz_lmdesc_setup()
218 channel->lmdesc.head = lmdesc; in rz_lmdesc_setup()
219 channel->lmdesc.tail = lmdesc; in rz_lmdesc_setup()
220 nxla = channel->lmdesc.base_dma; in rz_lmdesc_setup()
221 while (lmdesc < (channel->lmdesc.base + (DMAC_NR_LMDESC - 1))) { in rz_lmdesc_setup()
229 lmdesc->nxla = channel->lmdesc.base_dma; in rz_lmdesc_setup()
237 static void rz_dmac_lmdesc_recycle(struct rz_dmac_chan *channel) in rz_dmac_lmdesc_recycle() argument
239 struct rz_lmdesc *lmdesc = channel->lmdesc.head; in rz_dmac_lmdesc_recycle()
244 if (lmdesc >= (channel->lmdesc.base + DMAC_NR_LMDESC)) in rz_dmac_lmdesc_recycle()
245 lmdesc = channel->lmdesc.base; in rz_dmac_lmdesc_recycle()
247 channel->lmdesc.head = lmdesc; in rz_dmac_lmdesc_recycle()
250 static void rz_dmac_enable_hw(struct rz_dmac_chan *channel) in rz_dmac_enable_hw() argument
252 struct dma_chan *chan = &channel->vc.chan; in rz_dmac_enable_hw()
259 dev_dbg(dmac->dev, "%s channel %d\n", __func__, channel->index); in rz_dmac_enable_hw()
263 rz_dmac_lmdesc_recycle(channel); in rz_dmac_enable_hw()
265 nxla = channel->lmdesc.base_dma + in rz_dmac_enable_hw()
266 (sizeof(struct rz_lmdesc) * (channel->lmdesc.head - in rz_dmac_enable_hw()
267 channel->lmdesc.base)); in rz_dmac_enable_hw()
269 chstat = rz_dmac_ch_readl(channel, CHSTAT, 1); in rz_dmac_enable_hw()
271 chctrl = (channel->chctrl | CHCTRL_SETEN); in rz_dmac_enable_hw()
272 rz_dmac_ch_writel(channel, nxla, NXLA, 1); in rz_dmac_enable_hw()
273 rz_dmac_ch_writel(channel, channel->chcfg, CHCFG, 1); in rz_dmac_enable_hw()
274 rz_dmac_ch_writel(channel, CHCTRL_SWRST, CHCTRL, 1); in rz_dmac_enable_hw()
275 rz_dmac_ch_writel(channel, chctrl, CHCTRL, 1); in rz_dmac_enable_hw()
281 static void rz_dmac_disable_hw(struct rz_dmac_chan *channel) in rz_dmac_disable_hw() argument
283 struct dma_chan *chan = &channel->vc.chan; in rz_dmac_disable_hw()
287 dev_dbg(dmac->dev, "%s channel %d\n", __func__, channel->index); in rz_dmac_disable_hw()
290 rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1); in rz_dmac_disable_hw()
307 static void rz_dmac_prepare_desc_for_memcpy(struct rz_dmac_chan *channel) in rz_dmac_prepare_desc_for_memcpy() argument
309 struct dma_chan *chan = &channel->vc.chan; in rz_dmac_prepare_desc_for_memcpy()
311 struct rz_lmdesc *lmdesc = channel->lmdesc.tail; in rz_dmac_prepare_desc_for_memcpy()
312 struct rz_dmac_desc *d = channel->desc; in rz_dmac_prepare_desc_for_memcpy()
324 rz_dmac_set_dmars_register(dmac, channel->index, 0); in rz_dmac_prepare_desc_for_memcpy()
326 channel->chcfg = chcfg; in rz_dmac_prepare_desc_for_memcpy()
327 channel->chctrl = CHCTRL_STG | CHCTRL_SETEN; in rz_dmac_prepare_desc_for_memcpy()
330 static void rz_dmac_prepare_descs_for_slave_sg(struct rz_dmac_chan *channel) in rz_dmac_prepare_descs_for_slave_sg() argument
332 struct dma_chan *chan = &channel->vc.chan; in rz_dmac_prepare_descs_for_slave_sg()
334 struct rz_dmac_desc *d = channel->desc; in rz_dmac_prepare_descs_for_slave_sg()
339 channel->chcfg |= CHCFG_SEL(channel->index) | CHCFG_DEM | CHCFG_DMS; in rz_dmac_prepare_descs_for_slave_sg()
342 channel->chcfg |= CHCFG_SAD; in rz_dmac_prepare_descs_for_slave_sg()
343 channel->chcfg &= ~CHCFG_REQD; in rz_dmac_prepare_descs_for_slave_sg()
345 channel->chcfg |= CHCFG_DAD | CHCFG_REQD; in rz_dmac_prepare_descs_for_slave_sg()
348 lmdesc = channel->lmdesc.tail; in rz_dmac_prepare_descs_for_slave_sg()
352 lmdesc->sa = channel->src_per_address; in rz_dmac_prepare_descs_for_slave_sg()
356 lmdesc->da = channel->dst_per_address; in rz_dmac_prepare_descs_for_slave_sg()
363 lmdesc->chcfg = (channel->chcfg & ~CHCFG_DEM); in rz_dmac_prepare_descs_for_slave_sg()
366 lmdesc->chcfg = channel->chcfg; in rz_dmac_prepare_descs_for_slave_sg()
369 if (++lmdesc >= (channel->lmdesc.base + DMAC_NR_LMDESC)) in rz_dmac_prepare_descs_for_slave_sg()
370 lmdesc = channel->lmdesc.base; in rz_dmac_prepare_descs_for_slave_sg()
373 channel->lmdesc.tail = lmdesc; in rz_dmac_prepare_descs_for_slave_sg()
375 rz_dmac_set_dmars_register(dmac, channel->index, channel->mid_rid); in rz_dmac_prepare_descs_for_slave_sg()
376 channel->chctrl = CHCTRL_SETEN; in rz_dmac_prepare_descs_for_slave_sg()
415 struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); in rz_dmac_alloc_chan_resources() local
417 while (channel->descs_allocated < RZ_DMAC_MAX_CHAN_DESCRIPTORS) { in rz_dmac_alloc_chan_resources()
424 list_add_tail(&desc->node, &channel->ld_free); in rz_dmac_alloc_chan_resources()
425 channel->descs_allocated++; in rz_dmac_alloc_chan_resources()
428 if (!channel->descs_allocated) in rz_dmac_alloc_chan_resources()
431 return channel->descs_allocated; in rz_dmac_alloc_chan_resources()
436 struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); in rz_dmac_free_chan_resources() local
438 struct rz_lmdesc *lmdesc = channel->lmdesc.base; in rz_dmac_free_chan_resources()
443 spin_lock_irqsave(&channel->vc.lock, flags); in rz_dmac_free_chan_resources()
448 rz_dmac_disable_hw(channel); in rz_dmac_free_chan_resources()
449 list_splice_tail_init(&channel->ld_active, &channel->ld_free); in rz_dmac_free_chan_resources()
450 list_splice_tail_init(&channel->ld_queue, &channel->ld_free); in rz_dmac_free_chan_resources()
452 if (channel->mid_rid >= 0) { in rz_dmac_free_chan_resources()
453 clear_bit(channel->mid_rid, dmac->modules); in rz_dmac_free_chan_resources()
454 channel->mid_rid = -EINVAL; in rz_dmac_free_chan_resources()
457 spin_unlock_irqrestore(&channel->vc.lock, flags); in rz_dmac_free_chan_resources()
459 list_for_each_entry_safe(desc, _desc, &channel->ld_free, node) { in rz_dmac_free_chan_resources()
461 channel->descs_allocated--; in rz_dmac_free_chan_resources()
464 INIT_LIST_HEAD(&channel->ld_free); in rz_dmac_free_chan_resources()
465 vchan_free_chan_resources(&channel->vc); in rz_dmac_free_chan_resources()
472 struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); in rz_dmac_prep_dma_memcpy() local
476 dev_dbg(dmac->dev, "%s channel: %d src=0x%pad dst=0x%pad len=%zu\n", in rz_dmac_prep_dma_memcpy()
477 __func__, channel->index, &src, &dest, len); in rz_dmac_prep_dma_memcpy()
479 if (list_empty(&channel->ld_free)) in rz_dmac_prep_dma_memcpy()
482 desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node); in rz_dmac_prep_dma_memcpy()
490 list_move_tail(channel->ld_free.next, &channel->ld_queue); in rz_dmac_prep_dma_memcpy()
491 return vchan_tx_prep(&channel->vc, &desc->vd, flags); in rz_dmac_prep_dma_memcpy()
500 struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); in rz_dmac_prep_slave_sg() local
506 if (list_empty(&channel->ld_free)) in rz_dmac_prep_slave_sg()
509 desc = list_first_entry(&channel->ld_free, struct rz_dmac_desc, node); in rz_dmac_prep_slave_sg()
522 desc->src = channel->src_per_address; in rz_dmac_prep_slave_sg()
524 desc->dest = channel->dst_per_address; in rz_dmac_prep_slave_sg()
526 list_move_tail(channel->ld_free.next, &channel->ld_queue); in rz_dmac_prep_slave_sg()
527 return vchan_tx_prep(&channel->vc, &desc->vd, flags); in rz_dmac_prep_slave_sg()
532 struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); in rz_dmac_terminate_all() local
536 rz_dmac_disable_hw(channel); in rz_dmac_terminate_all()
537 spin_lock_irqsave(&channel->vc.lock, flags); in rz_dmac_terminate_all()
538 list_splice_tail_init(&channel->ld_active, &channel->ld_free); in rz_dmac_terminate_all()
539 list_splice_tail_init(&channel->ld_queue, &channel->ld_free); in rz_dmac_terminate_all()
540 spin_unlock_irqrestore(&channel->vc.lock, flags); in rz_dmac_terminate_all()
541 vchan_get_all_descriptors(&channel->vc, &head); in rz_dmac_terminate_all()
542 vchan_dma_desc_free_list(&channel->vc, &head); in rz_dmac_terminate_all()
549 struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); in rz_dmac_issue_pending() local
554 spin_lock_irqsave(&channel->vc.lock, flags); in rz_dmac_issue_pending()
556 if (!list_empty(&channel->ld_queue)) { in rz_dmac_issue_pending()
557 desc = list_first_entry(&channel->ld_queue, in rz_dmac_issue_pending()
559 channel->desc = desc; in rz_dmac_issue_pending()
560 if (vchan_issue_pending(&channel->vc)) { in rz_dmac_issue_pending()
561 if (rz_dmac_xfer_desc(channel) < 0) in rz_dmac_issue_pending()
563 channel->index); in rz_dmac_issue_pending()
565 list_move_tail(channel->ld_queue.next, in rz_dmac_issue_pending()
566 &channel->ld_active); in rz_dmac_issue_pending()
570 spin_unlock_irqrestore(&channel->vc.lock, flags); in rz_dmac_issue_pending()
598 struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); in rz_dmac_config() local
601 channel->src_per_address = config->src_addr; in rz_dmac_config()
602 channel->src_word_size = config->src_addr_width; in rz_dmac_config()
603 channel->dst_per_address = config->dst_addr; in rz_dmac_config()
604 channel->dst_word_size = config->dst_addr_width; in rz_dmac_config()
610 channel->chcfg |= CHCFG_FILL_DDS(val); in rz_dmac_config()
616 channel->chcfg |= CHCFG_FILL_SDS(val); in rz_dmac_config()
637 static void rz_dmac_irq_handle_channel(struct rz_dmac_chan *channel) in rz_dmac_irq_handle_channel() argument
639 struct dma_chan *chan = &channel->vc.chan; in rz_dmac_irq_handle_channel()
643 chstat = rz_dmac_ch_readl(channel, CHSTAT, 1); in rz_dmac_irq_handle_channel()
646 channel->index, chstat); in rz_dmac_irq_handle_channel()
647 rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1); in rz_dmac_irq_handle_channel()
651 chctrl = rz_dmac_ch_readl(channel, CHCTRL, 1); in rz_dmac_irq_handle_channel()
652 rz_dmac_ch_writel(channel, chctrl | CHCTRL_CLREND, CHCTRL, 1); in rz_dmac_irq_handle_channel()
659 struct rz_dmac_chan *channel = dev_id; in rz_dmac_irq_handler() local
661 if (channel) { in rz_dmac_irq_handler()
662 rz_dmac_irq_handle_channel(channel); in rz_dmac_irq_handler()
671 struct rz_dmac_chan *channel = dev_id; in rz_dmac_irq_handler_thread() local
675 spin_lock_irqsave(&channel->vc.lock, flags); in rz_dmac_irq_handler_thread()
677 if (list_empty(&channel->ld_active)) { in rz_dmac_irq_handler_thread()
682 desc = list_first_entry(&channel->ld_active, struct rz_dmac_desc, node); in rz_dmac_irq_handler_thread()
684 list_move_tail(channel->ld_active.next, &channel->ld_free); in rz_dmac_irq_handler_thread()
685 if (!list_empty(&channel->ld_queue)) { in rz_dmac_irq_handler_thread()
686 desc = list_first_entry(&channel->ld_queue, struct rz_dmac_desc, in rz_dmac_irq_handler_thread()
688 channel->desc = desc; in rz_dmac_irq_handler_thread()
689 if (rz_dmac_xfer_desc(channel) == 0) in rz_dmac_irq_handler_thread()
690 list_move_tail(channel->ld_queue.next, &channel->ld_active); in rz_dmac_irq_handler_thread()
693 spin_unlock_irqrestore(&channel->vc.lock, flags); in rz_dmac_irq_handler_thread()
700 * OF xlate and channel filter
705 struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); in rz_dmac_chan_filter() local
710 channel->mid_rid = dma_spec->args[0] & MID_RID_MASK; in rz_dmac_chan_filter()
712 channel->chcfg = CHCFG_FILL_TM(ch_cfg) | CHCFG_FILL_AM(ch_cfg) | in rz_dmac_chan_filter()
715 return !test_and_set_bit(channel->mid_rid, dmac->modules); in rz_dmac_chan_filter()
739 struct rz_dmac_chan *channel, in rz_dmac_chan_probe() argument
748 channel->index = index; in rz_dmac_chan_probe()
749 channel->mid_rid = -EINVAL; in rz_dmac_chan_probe()
751 /* Request the channel interrupt. */ in rz_dmac_chan_probe()
753 channel->irq = platform_get_irq_byname(pdev, pdev_irqname); in rz_dmac_chan_probe()
754 if (channel->irq < 0) in rz_dmac_chan_probe()
755 return channel->irq; in rz_dmac_chan_probe()
762 ret = devm_request_threaded_irq(dmac->dev, channel->irq, in rz_dmac_chan_probe()
765 irqname, channel); in rz_dmac_chan_probe()
768 channel->irq, ret); in rz_dmac_chan_probe()
772 /* Set io base address for each channel */ in rz_dmac_chan_probe()
774 channel->ch_base = dmac->base + CHANNEL_0_7_OFFSET + in rz_dmac_chan_probe()
776 channel->ch_cmn_base = dmac->base + CHANNEL_0_7_COMMON_BASE; in rz_dmac_chan_probe()
778 channel->ch_base = dmac->base + CHANNEL_8_15_OFFSET + in rz_dmac_chan_probe()
780 channel->ch_cmn_base = dmac->base + CHANNEL_8_15_COMMON_BASE; in rz_dmac_chan_probe()
786 &channel->lmdesc.base_dma, GFP_KERNEL); in rz_dmac_chan_probe()
791 rz_lmdesc_setup(channel, lmdesc); in rz_dmac_chan_probe()
793 /* Initialize register for each channel */ in rz_dmac_chan_probe()
794 rz_dmac_ch_writel(channel, CHCTRL_DEFAULT, CHCTRL, 1); in rz_dmac_chan_probe()
796 channel->vc.desc_free = rz_dmac_virt_desc_free; in rz_dmac_chan_probe()
797 vchan_init(&channel->vc, &dmac->engine); in rz_dmac_chan_probe()
798 INIT_LIST_HEAD(&channel->ld_queue); in rz_dmac_chan_probe()
799 INIT_LIST_HEAD(&channel->ld_free); in rz_dmac_chan_probe()
800 INIT_LIST_HEAD(&channel->ld_active); in rz_dmac_chan_probe()
920 struct rz_dmac_chan *channel = &dmac->channels[i]; in rz_dmac_probe() local
924 channel->lmdesc.base, in rz_dmac_probe()
925 channel->lmdesc.base_dma); in rz_dmac_probe()
937 struct rz_dmac_chan *channel = &dmac->channels[i]; in rz_dmac_remove() local
941 channel->lmdesc.base, in rz_dmac_remove()
942 channel->lmdesc.base_dma); in rz_dmac_remove()