Lines Matching refs:edmac
217 static inline struct device *chan2dev(struct ep93xx_dma_chan *edmac) in chan2dev() argument
219 return &edmac->chan.dev->device; in chan2dev()
238 static void ep93xx_dma_set_active(struct ep93xx_dma_chan *edmac, in ep93xx_dma_set_active() argument
241 BUG_ON(!list_empty(&edmac->active)); in ep93xx_dma_set_active()
243 list_add_tail(&desc->node, &edmac->active); in ep93xx_dma_set_active()
259 list_move_tail(&d->node, &edmac->active); in ep93xx_dma_set_active()
265 ep93xx_dma_get_active(struct ep93xx_dma_chan *edmac) in ep93xx_dma_get_active() argument
267 return list_first_entry_or_null(&edmac->active, in ep93xx_dma_get_active()
283 static bool ep93xx_dma_advance_active(struct ep93xx_dma_chan *edmac) in ep93xx_dma_advance_active() argument
287 list_rotate_left(&edmac->active); in ep93xx_dma_advance_active()
289 if (test_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags)) in ep93xx_dma_advance_active()
292 desc = ep93xx_dma_get_active(edmac); in ep93xx_dma_advance_active()
307 static void m2p_set_control(struct ep93xx_dma_chan *edmac, u32 control) in m2p_set_control() argument
309 writel(control, edmac->regs + M2P_CONTROL); in m2p_set_control()
314 readl(edmac->regs + M2P_CONTROL); in m2p_set_control()
317 static int m2p_hw_setup(struct ep93xx_dma_chan *edmac) in m2p_hw_setup() argument
319 struct ep93xx_dma_data *data = edmac->chan.private; in m2p_hw_setup()
322 writel(data->port & 0xf, edmac->regs + M2P_PPALLOC); in m2p_hw_setup()
326 m2p_set_control(edmac, control); in m2p_hw_setup()
328 edmac->buffer = 0; in m2p_hw_setup()
333 static inline u32 m2p_channel_state(struct ep93xx_dma_chan *edmac) in m2p_channel_state() argument
335 return (readl(edmac->regs + M2P_STATUS) >> 4) & 0x3; in m2p_channel_state()
338 static void m2p_hw_synchronize(struct ep93xx_dma_chan *edmac) in m2p_hw_synchronize() argument
343 spin_lock_irqsave(&edmac->lock, flags); in m2p_hw_synchronize()
344 control = readl(edmac->regs + M2P_CONTROL); in m2p_hw_synchronize()
346 m2p_set_control(edmac, control); in m2p_hw_synchronize()
347 spin_unlock_irqrestore(&edmac->lock, flags); in m2p_hw_synchronize()
349 while (m2p_channel_state(edmac) >= M2P_STATE_ON) in m2p_hw_synchronize()
353 static void m2p_hw_shutdown(struct ep93xx_dma_chan *edmac) in m2p_hw_shutdown() argument
355 m2p_set_control(edmac, 0); in m2p_hw_shutdown()
357 while (m2p_channel_state(edmac) != M2P_STATE_IDLE) in m2p_hw_shutdown()
358 dev_warn(chan2dev(edmac), "M2P: Not yet IDLE\n"); in m2p_hw_shutdown()
361 static void m2p_fill_desc(struct ep93xx_dma_chan *edmac) in m2p_fill_desc() argument
366 desc = ep93xx_dma_get_active(edmac); in m2p_fill_desc()
368 dev_warn(chan2dev(edmac), "M2P: empty descriptor list\n"); in m2p_fill_desc()
372 if (ep93xx_dma_chan_direction(&edmac->chan) == DMA_MEM_TO_DEV) in m2p_fill_desc()
377 if (edmac->buffer == 0) { in m2p_fill_desc()
378 writel(desc->size, edmac->regs + M2P_MAXCNT0); in m2p_fill_desc()
379 writel(bus_addr, edmac->regs + M2P_BASE0); in m2p_fill_desc()
381 writel(desc->size, edmac->regs + M2P_MAXCNT1); in m2p_fill_desc()
382 writel(bus_addr, edmac->regs + M2P_BASE1); in m2p_fill_desc()
385 edmac->buffer ^= 1; in m2p_fill_desc()
388 static void m2p_hw_submit(struct ep93xx_dma_chan *edmac) in m2p_hw_submit() argument
390 u32 control = readl(edmac->regs + M2P_CONTROL); in m2p_hw_submit()
392 m2p_fill_desc(edmac); in m2p_hw_submit()
395 if (ep93xx_dma_advance_active(edmac)) { in m2p_hw_submit()
396 m2p_fill_desc(edmac); in m2p_hw_submit()
400 m2p_set_control(edmac, control); in m2p_hw_submit()
403 static int m2p_hw_interrupt(struct ep93xx_dma_chan *edmac) in m2p_hw_interrupt() argument
405 u32 irq_status = readl(edmac->regs + M2P_INTERRUPT); in m2p_hw_interrupt()
409 struct ep93xx_dma_desc *desc = ep93xx_dma_get_active(edmac); in m2p_hw_interrupt()
412 writel(1, edmac->regs + M2P_INTERRUPT); in m2p_hw_interrupt()
422 dev_err(chan2dev(edmac), in m2p_hw_interrupt()
440 if (ep93xx_dma_advance_active(edmac)) { in m2p_hw_interrupt()
441 m2p_fill_desc(edmac); in m2p_hw_interrupt()
446 control = readl(edmac->regs + M2P_CONTROL); in m2p_hw_interrupt()
448 m2p_set_control(edmac, control); in m2p_hw_interrupt()
457 static int m2m_hw_setup(struct ep93xx_dma_chan *edmac) in m2m_hw_setup() argument
459 const struct ep93xx_dma_data *data = edmac->chan.private; in m2m_hw_setup()
464 writel(control, edmac->regs + M2M_CONTROL); in m2m_hw_setup()
514 writel(control, edmac->regs + M2M_CONTROL); in m2m_hw_setup()
518 static void m2m_hw_shutdown(struct ep93xx_dma_chan *edmac) in m2m_hw_shutdown() argument
521 writel(0, edmac->regs + M2M_CONTROL); in m2m_hw_shutdown()
524 static void m2m_fill_desc(struct ep93xx_dma_chan *edmac) in m2m_fill_desc() argument
528 desc = ep93xx_dma_get_active(edmac); in m2m_fill_desc()
530 dev_warn(chan2dev(edmac), "M2M: empty descriptor list\n"); in m2m_fill_desc()
534 if (edmac->buffer == 0) { in m2m_fill_desc()
535 writel(desc->src_addr, edmac->regs + M2M_SAR_BASE0); in m2m_fill_desc()
536 writel(desc->dst_addr, edmac->regs + M2M_DAR_BASE0); in m2m_fill_desc()
537 writel(desc->size, edmac->regs + M2M_BCR0); in m2m_fill_desc()
539 writel(desc->src_addr, edmac->regs + M2M_SAR_BASE1); in m2m_fill_desc()
540 writel(desc->dst_addr, edmac->regs + M2M_DAR_BASE1); in m2m_fill_desc()
541 writel(desc->size, edmac->regs + M2M_BCR1); in m2m_fill_desc()
544 edmac->buffer ^= 1; in m2m_fill_desc()
547 static void m2m_hw_submit(struct ep93xx_dma_chan *edmac) in m2m_hw_submit() argument
549 struct ep93xx_dma_data *data = edmac->chan.private; in m2m_hw_submit()
550 u32 control = readl(edmac->regs + M2M_CONTROL); in m2m_hw_submit()
558 control |= edmac->runtime_ctrl; in m2m_hw_submit()
560 m2m_fill_desc(edmac); in m2m_hw_submit()
563 if (ep93xx_dma_advance_active(edmac)) { in m2m_hw_submit()
564 m2m_fill_desc(edmac); in m2m_hw_submit()
573 writel(control, edmac->regs + M2M_CONTROL); in m2m_hw_submit()
581 writel(control, edmac->regs + M2M_CONTROL); in m2m_hw_submit()
595 static int m2m_hw_interrupt(struct ep93xx_dma_chan *edmac) in m2m_hw_interrupt() argument
597 u32 status = readl(edmac->regs + M2M_STATUS); in m2m_hw_interrupt()
606 if (!(readl(edmac->regs + M2M_INTERRUPT) & M2M_INTERRUPT_MASK)) in m2m_hw_interrupt()
611 writel(0, edmac->regs + M2M_INTERRUPT); in m2m_hw_interrupt()
618 desc = ep93xx_dma_get_active(edmac); in m2m_hw_interrupt()
635 if (ep93xx_dma_advance_active(edmac)) { in m2m_hw_interrupt()
636 m2m_fill_desc(edmac); in m2m_hw_interrupt()
637 if (done && !edmac->chan.private) { in m2m_hw_interrupt()
639 control = readl(edmac->regs + M2M_CONTROL); in m2m_hw_interrupt()
641 writel(control, edmac->regs + M2M_CONTROL); in m2m_hw_interrupt()
657 control = readl(edmac->regs + M2M_CONTROL); in m2m_hw_interrupt()
660 writel(control, edmac->regs + M2M_CONTROL); in m2m_hw_interrupt()
675 ep93xx_dma_desc_get(struct ep93xx_dma_chan *edmac) in ep93xx_dma_desc_get() argument
681 spin_lock_irqsave(&edmac->lock, flags); in ep93xx_dma_desc_get()
682 list_for_each_entry_safe(desc, _desc, &edmac->free_list, node) { in ep93xx_dma_desc_get()
699 spin_unlock_irqrestore(&edmac->lock, flags); in ep93xx_dma_desc_get()
703 static void ep93xx_dma_desc_put(struct ep93xx_dma_chan *edmac, in ep93xx_dma_desc_put() argument
709 spin_lock_irqsave(&edmac->lock, flags); in ep93xx_dma_desc_put()
710 list_splice_init(&desc->tx_list, &edmac->free_list); in ep93xx_dma_desc_put()
711 list_add(&desc->node, &edmac->free_list); in ep93xx_dma_desc_put()
712 spin_unlock_irqrestore(&edmac->lock, flags); in ep93xx_dma_desc_put()
724 static void ep93xx_dma_advance_work(struct ep93xx_dma_chan *edmac) in ep93xx_dma_advance_work() argument
729 spin_lock_irqsave(&edmac->lock, flags); in ep93xx_dma_advance_work()
730 if (!list_empty(&edmac->active) || list_empty(&edmac->queue)) { in ep93xx_dma_advance_work()
731 spin_unlock_irqrestore(&edmac->lock, flags); in ep93xx_dma_advance_work()
736 new = list_first_entry(&edmac->queue, struct ep93xx_dma_desc, node); in ep93xx_dma_advance_work()
739 ep93xx_dma_set_active(edmac, new); in ep93xx_dma_advance_work()
742 edmac->edma->hw_submit(edmac); in ep93xx_dma_advance_work()
743 spin_unlock_irqrestore(&edmac->lock, flags); in ep93xx_dma_advance_work()
748 struct ep93xx_dma_chan *edmac = (struct ep93xx_dma_chan *)data; in ep93xx_dma_tasklet() local
754 spin_lock_irq(&edmac->lock); in ep93xx_dma_tasklet()
760 desc = ep93xx_dma_get_active(edmac); in ep93xx_dma_tasklet()
764 if (!test_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags)) in ep93xx_dma_tasklet()
766 list_splice_init(&edmac->active, &list); in ep93xx_dma_tasklet()
770 spin_unlock_irq(&edmac->lock); in ep93xx_dma_tasklet()
773 ep93xx_dma_advance_work(edmac); in ep93xx_dma_tasklet()
778 ep93xx_dma_desc_put(edmac, desc); in ep93xx_dma_tasklet()
786 struct ep93xx_dma_chan *edmac = dev_id; in ep93xx_dma_interrupt() local
790 spin_lock(&edmac->lock); in ep93xx_dma_interrupt()
792 desc = ep93xx_dma_get_active(edmac); in ep93xx_dma_interrupt()
794 dev_warn(chan2dev(edmac), in ep93xx_dma_interrupt()
796 spin_unlock(&edmac->lock); in ep93xx_dma_interrupt()
800 switch (edmac->edma->hw_interrupt(edmac)) { in ep93xx_dma_interrupt()
803 tasklet_schedule(&edmac->tasklet); in ep93xx_dma_interrupt()
807 if (test_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags)) in ep93xx_dma_interrupt()
808 tasklet_schedule(&edmac->tasklet); in ep93xx_dma_interrupt()
812 dev_warn(chan2dev(edmac), "unknown interrupt!\n"); in ep93xx_dma_interrupt()
817 spin_unlock(&edmac->lock); in ep93xx_dma_interrupt()
831 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(tx->chan); in ep93xx_dma_tx_submit() local
836 spin_lock_irqsave(&edmac->lock, flags); in ep93xx_dma_tx_submit()
846 if (list_empty(&edmac->active)) { in ep93xx_dma_tx_submit()
847 ep93xx_dma_set_active(edmac, desc); in ep93xx_dma_tx_submit()
848 edmac->edma->hw_submit(edmac); in ep93xx_dma_tx_submit()
850 list_add_tail(&desc->node, &edmac->queue); in ep93xx_dma_tx_submit()
853 spin_unlock_irqrestore(&edmac->lock, flags); in ep93xx_dma_tx_submit()
867 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); in ep93xx_dma_alloc_chan_resources() local
873 if (!edmac->edma->m2m) { in ep93xx_dma_alloc_chan_resources()
898 ret = clk_enable(edmac->clk); in ep93xx_dma_alloc_chan_resources()
902 ret = request_irq(edmac->irq, ep93xx_dma_interrupt, 0, name, edmac); in ep93xx_dma_alloc_chan_resources()
906 spin_lock_irq(&edmac->lock); in ep93xx_dma_alloc_chan_resources()
907 dma_cookie_init(&edmac->chan); in ep93xx_dma_alloc_chan_resources()
908 ret = edmac->edma->hw_setup(edmac); in ep93xx_dma_alloc_chan_resources()
909 spin_unlock_irq(&edmac->lock); in ep93xx_dma_alloc_chan_resources()
919 dev_warn(chan2dev(edmac), "not enough descriptors\n"); in ep93xx_dma_alloc_chan_resources()
929 ep93xx_dma_desc_put(edmac, desc); in ep93xx_dma_alloc_chan_resources()
935 free_irq(edmac->irq, edmac); in ep93xx_dma_alloc_chan_resources()
937 clk_disable(edmac->clk); in ep93xx_dma_alloc_chan_resources()
951 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); in ep93xx_dma_free_chan_resources() local
956 BUG_ON(!list_empty(&edmac->active)); in ep93xx_dma_free_chan_resources()
957 BUG_ON(!list_empty(&edmac->queue)); in ep93xx_dma_free_chan_resources()
959 spin_lock_irqsave(&edmac->lock, flags); in ep93xx_dma_free_chan_resources()
960 edmac->edma->hw_shutdown(edmac); in ep93xx_dma_free_chan_resources()
961 edmac->runtime_addr = 0; in ep93xx_dma_free_chan_resources()
962 edmac->runtime_ctrl = 0; in ep93xx_dma_free_chan_resources()
963 edmac->buffer = 0; in ep93xx_dma_free_chan_resources()
964 list_splice_init(&edmac->free_list, &list); in ep93xx_dma_free_chan_resources()
965 spin_unlock_irqrestore(&edmac->lock, flags); in ep93xx_dma_free_chan_resources()
970 clk_disable(edmac->clk); in ep93xx_dma_free_chan_resources()
971 free_irq(edmac->irq, edmac); in ep93xx_dma_free_chan_resources()
988 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); in ep93xx_dma_prep_dma_memcpy() local
994 desc = ep93xx_dma_desc_get(edmac); in ep93xx_dma_prep_dma_memcpy()
996 dev_warn(chan2dev(edmac), "couldn't get descriptor\n"); in ep93xx_dma_prep_dma_memcpy()
1017 ep93xx_dma_desc_put(edmac, first); in ep93xx_dma_prep_dma_memcpy()
1037 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); in ep93xx_dma_prep_slave_sg() local
1042 if (!edmac->edma->m2m && dir != ep93xx_dma_chan_direction(chan)) { in ep93xx_dma_prep_slave_sg()
1043 dev_warn(chan2dev(edmac), in ep93xx_dma_prep_slave_sg()
1048 if (test_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags)) { in ep93xx_dma_prep_slave_sg()
1049 dev_warn(chan2dev(edmac), in ep93xx_dma_prep_slave_sg()
1054 ep93xx_dma_slave_config_write(chan, dir, &edmac->slave_config); in ep93xx_dma_prep_slave_sg()
1061 dev_warn(chan2dev(edmac), "too big transfer size %zu\n", in ep93xx_dma_prep_slave_sg()
1066 desc = ep93xx_dma_desc_get(edmac); in ep93xx_dma_prep_slave_sg()
1068 dev_warn(chan2dev(edmac), "couldn't get descriptor\n"); in ep93xx_dma_prep_slave_sg()
1074 desc->dst_addr = edmac->runtime_addr; in ep93xx_dma_prep_slave_sg()
1076 desc->src_addr = edmac->runtime_addr; in ep93xx_dma_prep_slave_sg()
1093 ep93xx_dma_desc_put(edmac, first); in ep93xx_dma_prep_slave_sg()
1119 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); in ep93xx_dma_prep_dma_cyclic() local
1123 if (!edmac->edma->m2m && dir != ep93xx_dma_chan_direction(chan)) { in ep93xx_dma_prep_dma_cyclic()
1124 dev_warn(chan2dev(edmac), in ep93xx_dma_prep_dma_cyclic()
1129 if (test_and_set_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags)) { in ep93xx_dma_prep_dma_cyclic()
1130 dev_warn(chan2dev(edmac), in ep93xx_dma_prep_dma_cyclic()
1136 dev_warn(chan2dev(edmac), "too big period length %zu\n", in ep93xx_dma_prep_dma_cyclic()
1141 ep93xx_dma_slave_config_write(chan, dir, &edmac->slave_config); in ep93xx_dma_prep_dma_cyclic()
1146 desc = ep93xx_dma_desc_get(edmac); in ep93xx_dma_prep_dma_cyclic()
1148 dev_warn(chan2dev(edmac), "couldn't get descriptor\n"); in ep93xx_dma_prep_dma_cyclic()
1154 desc->dst_addr = edmac->runtime_addr; in ep93xx_dma_prep_dma_cyclic()
1156 desc->src_addr = edmac->runtime_addr; in ep93xx_dma_prep_dma_cyclic()
1173 ep93xx_dma_desc_put(edmac, first); in ep93xx_dma_prep_dma_cyclic()
1191 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); in ep93xx_dma_synchronize() local
1193 if (edmac->edma->hw_synchronize) in ep93xx_dma_synchronize()
1194 edmac->edma->hw_synchronize(edmac); in ep93xx_dma_synchronize()
1206 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); in ep93xx_dma_terminate_all() local
1211 spin_lock_irqsave(&edmac->lock, flags); in ep93xx_dma_terminate_all()
1213 edmac->edma->hw_shutdown(edmac); in ep93xx_dma_terminate_all()
1214 clear_bit(EP93XX_DMA_IS_CYCLIC, &edmac->flags); in ep93xx_dma_terminate_all()
1215 list_splice_init(&edmac->active, &list); in ep93xx_dma_terminate_all()
1216 list_splice_init(&edmac->queue, &list); in ep93xx_dma_terminate_all()
1221 edmac->edma->hw_setup(edmac); in ep93xx_dma_terminate_all()
1222 spin_unlock_irqrestore(&edmac->lock, flags); in ep93xx_dma_terminate_all()
1225 ep93xx_dma_desc_put(edmac, desc); in ep93xx_dma_terminate_all()
1233 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); in ep93xx_dma_slave_config() local
1235 memcpy(&edmac->slave_config, config, sizeof(*config)); in ep93xx_dma_slave_config()
1244 struct ep93xx_dma_chan *edmac = to_ep93xx_dma_chan(chan); in ep93xx_dma_slave_config_write() local
1249 if (!edmac->edma->m2m) in ep93xx_dma_slave_config_write()
1281 spin_lock_irqsave(&edmac->lock, flags); in ep93xx_dma_slave_config_write()
1282 edmac->runtime_addr = addr; in ep93xx_dma_slave_config_write()
1283 edmac->runtime_ctrl = ctrl; in ep93xx_dma_slave_config_write()
1284 spin_unlock_irqrestore(&edmac->lock, flags); in ep93xx_dma_slave_config_write()
1336 struct ep93xx_dma_chan *edmac = &edma->channels[i]; in ep93xx_dma_probe() local
1338 edmac->chan.device = dma_dev; in ep93xx_dma_probe()
1339 edmac->regs = cdata->base; in ep93xx_dma_probe()
1340 edmac->irq = cdata->irq; in ep93xx_dma_probe()
1341 edmac->edma = edma; in ep93xx_dma_probe()
1343 edmac->clk = clk_get(NULL, cdata->name); in ep93xx_dma_probe()
1344 if (IS_ERR(edmac->clk)) { in ep93xx_dma_probe()
1350 spin_lock_init(&edmac->lock); in ep93xx_dma_probe()
1351 INIT_LIST_HEAD(&edmac->active); in ep93xx_dma_probe()
1352 INIT_LIST_HEAD(&edmac->queue); in ep93xx_dma_probe()
1353 INIT_LIST_HEAD(&edmac->free_list); in ep93xx_dma_probe()
1354 tasklet_init(&edmac->tasklet, ep93xx_dma_tasklet, in ep93xx_dma_probe()
1355 (unsigned long)edmac); in ep93xx_dma_probe()
1357 list_add_tail(&edmac->chan.device_node, in ep93xx_dma_probe()
1399 struct ep93xx_dma_chan *edmac = &edma->channels[i]; in ep93xx_dma_probe() local
1400 if (!IS_ERR_OR_NULL(edmac->clk)) in ep93xx_dma_probe()
1401 clk_put(edmac->clk); in ep93xx_dma_probe()