Lines Matching refs:tdc
180 static inline void tdma_ch_write(struct tegra_adma_chan *tdc, u32 reg, u32 val) in tdma_ch_write() argument
182 writel(val, tdc->chan_addr + reg); in tdma_ch_write()
185 static inline u32 tdma_ch_read(struct tegra_adma_chan *tdc, u32 reg) in tdma_ch_read() argument
187 return readl(tdc->chan_addr + reg); in tdma_ch_read()
201 static inline struct device *tdc2dev(struct tegra_adma_chan *tdc) in tdc2dev() argument
203 return tdc->tdma->dev; in tdc2dev()
214 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_slave_config() local
216 memcpy(&tdc->sconfig, sconfig, sizeof(*sconfig)); in tegra_adma_slave_config()
247 static int tegra_adma_request_alloc(struct tegra_adma_chan *tdc, in tegra_adma_request_alloc() argument
250 struct tegra_adma *tdma = tdc->tdma; in tegra_adma_request_alloc()
251 unsigned int sreq_index = tdc->sreq_index; in tegra_adma_request_alloc()
253 if (tdc->sreq_reserved) in tegra_adma_request_alloc()
254 return tdc->sreq_dir == direction ? 0 : -EINVAL; in tegra_adma_request_alloc()
278 dma_chan_name(&tdc->vc.chan)); in tegra_adma_request_alloc()
282 tdc->sreq_dir = direction; in tegra_adma_request_alloc()
283 tdc->sreq_reserved = true; in tegra_adma_request_alloc()
288 static void tegra_adma_request_free(struct tegra_adma_chan *tdc) in tegra_adma_request_free() argument
290 struct tegra_adma *tdma = tdc->tdma; in tegra_adma_request_free()
292 if (!tdc->sreq_reserved) in tegra_adma_request_free()
295 switch (tdc->sreq_dir) { in tegra_adma_request_free()
297 clear_bit(tdc->sreq_index, &tdma->tx_requests_reserved); in tegra_adma_request_free()
301 clear_bit(tdc->sreq_index, &tdma->rx_requests_reserved); in tegra_adma_request_free()
306 dma_chan_name(&tdc->vc.chan)); in tegra_adma_request_free()
310 tdc->sreq_reserved = false; in tegra_adma_request_free()
313 static u32 tegra_adma_irq_status(struct tegra_adma_chan *tdc) in tegra_adma_irq_status() argument
315 u32 status = tdma_ch_read(tdc, ADMA_CH_INT_STATUS); in tegra_adma_irq_status()
320 static u32 tegra_adma_irq_clear(struct tegra_adma_chan *tdc) in tegra_adma_irq_clear() argument
322 u32 status = tegra_adma_irq_status(tdc); in tegra_adma_irq_clear()
325 tdma_ch_write(tdc, ADMA_CH_INT_CLEAR, status); in tegra_adma_irq_clear()
330 static void tegra_adma_stop(struct tegra_adma_chan *tdc) in tegra_adma_stop() argument
335 tdma_ch_write(tdc, ADMA_CH_CMD, 0); in tegra_adma_stop()
338 tegra_adma_irq_clear(tdc); in tegra_adma_stop()
340 if (readx_poll_timeout_atomic(readl, tdc->chan_addr + ADMA_CH_STATUS, in tegra_adma_stop()
343 dev_err(tdc2dev(tdc), "unable to stop DMA channel\n"); in tegra_adma_stop()
347 kfree(tdc->desc); in tegra_adma_stop()
348 tdc->desc = NULL; in tegra_adma_stop()
351 static void tegra_adma_start(struct tegra_adma_chan *tdc) in tegra_adma_start() argument
353 struct virt_dma_desc *vd = vchan_next_desc(&tdc->vc); in tegra_adma_start()
365 dev_warn(tdc2dev(tdc), "unable to start DMA, no descriptor\n"); in tegra_adma_start()
371 tdc->tx_buf_pos = 0; in tegra_adma_start()
372 tdc->tx_buf_count = 0; in tegra_adma_start()
373 tdma_ch_write(tdc, ADMA_CH_TC, ch_regs->tc); in tegra_adma_start()
374 tdma_ch_write(tdc, ADMA_CH_CTRL, ch_regs->ctrl); in tegra_adma_start()
375 tdma_ch_write(tdc, ADMA_CH_LOWER_SRC_ADDR, ch_regs->src_addr); in tegra_adma_start()
376 tdma_ch_write(tdc, ADMA_CH_LOWER_TRG_ADDR, ch_regs->trg_addr); in tegra_adma_start()
377 tdma_ch_write(tdc, ADMA_CH_FIFO_CTRL, ch_regs->fifo_ctrl); in tegra_adma_start()
378 tdma_ch_write(tdc, ADMA_CH_CONFIG, ch_regs->config); in tegra_adma_start()
381 tdma_ch_write(tdc, ADMA_CH_CMD, 1); in tegra_adma_start()
383 tdc->desc = desc; in tegra_adma_start()
386 static unsigned int tegra_adma_get_residue(struct tegra_adma_chan *tdc) in tegra_adma_get_residue() argument
388 struct tegra_adma_desc *desc = tdc->desc; in tegra_adma_get_residue()
390 unsigned int pos = tdma_ch_read(tdc, ADMA_CH_XFER_STATUS); in tegra_adma_get_residue()
396 if (pos < tdc->tx_buf_pos) in tegra_adma_get_residue()
397 tdc->tx_buf_count += pos + (max - tdc->tx_buf_pos); in tegra_adma_get_residue()
399 tdc->tx_buf_count += pos - tdc->tx_buf_pos; in tegra_adma_get_residue()
401 periods_remaining = tdc->tx_buf_count % desc->num_periods; in tegra_adma_get_residue()
402 tdc->tx_buf_pos = pos; in tegra_adma_get_residue()
409 struct tegra_adma_chan *tdc = dev_id; in tegra_adma_isr() local
413 spin_lock_irqsave(&tdc->vc.lock, flags); in tegra_adma_isr()
415 status = tegra_adma_irq_clear(tdc); in tegra_adma_isr()
416 if (status == 0 || !tdc->desc) { in tegra_adma_isr()
417 spin_unlock_irqrestore(&tdc->vc.lock, flags); in tegra_adma_isr()
421 vchan_cyclic_callback(&tdc->desc->vd); in tegra_adma_isr()
423 spin_unlock_irqrestore(&tdc->vc.lock, flags); in tegra_adma_isr()
430 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_issue_pending() local
433 spin_lock_irqsave(&tdc->vc.lock, flags); in tegra_adma_issue_pending()
435 if (vchan_issue_pending(&tdc->vc)) { in tegra_adma_issue_pending()
436 if (!tdc->desc) in tegra_adma_issue_pending()
437 tegra_adma_start(tdc); in tegra_adma_issue_pending()
440 spin_unlock_irqrestore(&tdc->vc.lock, flags); in tegra_adma_issue_pending()
443 static bool tegra_adma_is_paused(struct tegra_adma_chan *tdc) in tegra_adma_is_paused() argument
447 csts = tdma_ch_read(tdc, ADMA_CH_STATUS); in tegra_adma_is_paused()
455 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_pause() local
456 struct tegra_adma_desc *desc = tdc->desc; in tegra_adma_pause()
460 ch_regs->ctrl = tdma_ch_read(tdc, ADMA_CH_CTRL); in tegra_adma_pause()
462 tdma_ch_write(tdc, ADMA_CH_CTRL, ch_regs->ctrl); in tegra_adma_pause()
464 while (dcnt-- && !tegra_adma_is_paused(tdc)) in tegra_adma_pause()
468 dev_err(tdc2dev(tdc), "unable to pause DMA channel\n"); in tegra_adma_pause()
477 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_resume() local
478 struct tegra_adma_desc *desc = tdc->desc; in tegra_adma_resume()
481 ch_regs->ctrl = tdma_ch_read(tdc, ADMA_CH_CTRL); in tegra_adma_resume()
483 tdma_ch_write(tdc, ADMA_CH_CTRL, ch_regs->ctrl); in tegra_adma_resume()
490 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_terminate_all() local
494 spin_lock_irqsave(&tdc->vc.lock, flags); in tegra_adma_terminate_all()
496 if (tdc->desc) in tegra_adma_terminate_all()
497 tegra_adma_stop(tdc); in tegra_adma_terminate_all()
499 tegra_adma_request_free(tdc); in tegra_adma_terminate_all()
500 vchan_get_all_descriptors(&tdc->vc, &head); in tegra_adma_terminate_all()
501 spin_unlock_irqrestore(&tdc->vc.lock, flags); in tegra_adma_terminate_all()
502 vchan_dma_desc_free_list(&tdc->vc, &head); in tegra_adma_terminate_all()
511 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_tx_status() local
522 spin_lock_irqsave(&tdc->vc.lock, flags); in tegra_adma_tx_status()
524 vd = vchan_find_desc(&tdc->vc, cookie); in tegra_adma_tx_status()
528 } else if (tdc->desc && tdc->desc->vd.tx.cookie == cookie) { in tegra_adma_tx_status()
529 residual = tegra_adma_get_residue(tdc); in tegra_adma_tx_status()
534 spin_unlock_irqrestore(&tdc->vc.lock, flags); in tegra_adma_tx_status()
557 static int tegra_adma_set_xfer_params(struct tegra_adma_chan *tdc, in tegra_adma_set_xfer_params() argument
563 const struct tegra_adma_chip_data *cdata = tdc->tdma->cdata; in tegra_adma_set_xfer_params()
572 burst_size = tdc->sconfig.dst_maxburst; in tegra_adma_set_xfer_params()
574 ch_regs->ctrl = ADMA_CH_REG_FIELD_VAL(tdc->sreq_index, in tegra_adma_set_xfer_params()
582 burst_size = tdc->sconfig.src_maxburst; in tegra_adma_set_xfer_params()
584 ch_regs->ctrl = ADMA_CH_REG_FIELD_VAL(tdc->sreq_index, in tegra_adma_set_xfer_params()
591 dev_err(tdc2dev(tdc), "DMA direction is not supported\n"); in tegra_adma_set_xfer_params()
605 return tegra_adma_request_alloc(tdc, direction); in tegra_adma_set_xfer_params()
613 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_prep_dma_cyclic() local
617 dev_err(tdc2dev(tdc), "invalid buffer/period len\n"); in tegra_adma_prep_dma_cyclic()
622 dev_err(tdc2dev(tdc), "buf_len not a multiple of period_len\n"); in tegra_adma_prep_dma_cyclic()
627 dev_err(tdc2dev(tdc), "invalid buffer alignment\n"); in tegra_adma_prep_dma_cyclic()
639 if (tegra_adma_set_xfer_params(tdc, desc, buf_addr, direction)) { in tegra_adma_prep_dma_cyclic()
644 return vchan_tx_prep(&tdc->vc, &desc->vd, flags); in tegra_adma_prep_dma_cyclic()
649 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_alloc_chan_resources() local
652 ret = request_irq(tdc->irq, tegra_adma_isr, 0, dma_chan_name(dc), tdc); in tegra_adma_alloc_chan_resources()
654 dev_err(tdc2dev(tdc), "failed to get interrupt for %s\n", in tegra_adma_alloc_chan_resources()
659 ret = pm_runtime_get_sync(tdc2dev(tdc)); in tegra_adma_alloc_chan_resources()
661 pm_runtime_put_noidle(tdc2dev(tdc)); in tegra_adma_alloc_chan_resources()
662 free_irq(tdc->irq, tdc); in tegra_adma_alloc_chan_resources()
666 dma_cookie_init(&tdc->vc.chan); in tegra_adma_alloc_chan_resources()
673 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_free_chan_resources() local
676 vchan_free_chan_resources(&tdc->vc); in tegra_adma_free_chan_resources()
677 tasklet_kill(&tdc->vc.task); in tegra_adma_free_chan_resources()
678 free_irq(tdc->irq, tdc); in tegra_adma_free_chan_resources()
679 pm_runtime_put(tdc2dev(tdc)); in tegra_adma_free_chan_resources()
681 tdc->sreq_index = 0; in tegra_adma_free_chan_resources()
682 tdc->sreq_dir = DMA_TRANS_NONE; in tegra_adma_free_chan_resources()
689 struct tegra_adma_chan *tdc; in tegra_dma_of_xlate() local
707 tdc = to_tegra_adma_chan(chan); in tegra_dma_of_xlate()
708 tdc->sreq_index = sreq_index; in tegra_dma_of_xlate()
717 struct tegra_adma_chan *tdc; in tegra_adma_runtime_suspend() local
725 tdc = &tdma->channels[i]; in tegra_adma_runtime_suspend()
726 ch_reg = &tdc->ch_regs; in tegra_adma_runtime_suspend()
727 ch_reg->cmd = tdma_ch_read(tdc, ADMA_CH_CMD); in tegra_adma_runtime_suspend()
731 ch_reg->tc = tdma_ch_read(tdc, ADMA_CH_TC); in tegra_adma_runtime_suspend()
732 ch_reg->src_addr = tdma_ch_read(tdc, ADMA_CH_LOWER_SRC_ADDR); in tegra_adma_runtime_suspend()
733 ch_reg->trg_addr = tdma_ch_read(tdc, ADMA_CH_LOWER_TRG_ADDR); in tegra_adma_runtime_suspend()
734 ch_reg->ctrl = tdma_ch_read(tdc, ADMA_CH_CTRL); in tegra_adma_runtime_suspend()
735 ch_reg->fifo_ctrl = tdma_ch_read(tdc, ADMA_CH_FIFO_CTRL); in tegra_adma_runtime_suspend()
736 ch_reg->config = tdma_ch_read(tdc, ADMA_CH_CONFIG); in tegra_adma_runtime_suspend()
749 struct tegra_adma_chan *tdc; in tegra_adma_runtime_resume() local
763 tdc = &tdma->channels[i]; in tegra_adma_runtime_resume()
764 ch_reg = &tdc->ch_regs; in tegra_adma_runtime_resume()
768 tdma_ch_write(tdc, ADMA_CH_TC, ch_reg->tc); in tegra_adma_runtime_resume()
769 tdma_ch_write(tdc, ADMA_CH_LOWER_SRC_ADDR, ch_reg->src_addr); in tegra_adma_runtime_resume()
770 tdma_ch_write(tdc, ADMA_CH_LOWER_TRG_ADDR, ch_reg->trg_addr); in tegra_adma_runtime_resume()
771 tdma_ch_write(tdc, ADMA_CH_CTRL, ch_reg->ctrl); in tegra_adma_runtime_resume()
772 tdma_ch_write(tdc, ADMA_CH_FIFO_CTRL, ch_reg->fifo_ctrl); in tegra_adma_runtime_resume()
773 tdma_ch_write(tdc, ADMA_CH_CONFIG, ch_reg->config); in tegra_adma_runtime_resume()
774 tdma_ch_write(tdc, ADMA_CH_CMD, ch_reg->cmd); in tegra_adma_runtime_resume()
854 struct tegra_adma_chan *tdc = &tdma->channels[i]; in tegra_adma_probe() local
856 tdc->chan_addr = tdma->base_addr + cdata->ch_base_offset in tegra_adma_probe()
859 tdc->irq = of_irq_get(pdev->dev.of_node, i); in tegra_adma_probe()
860 if (tdc->irq <= 0) { in tegra_adma_probe()
861 ret = tdc->irq ?: -ENXIO; in tegra_adma_probe()
865 vchan_init(&tdc->vc, &tdma->dma_dev); in tegra_adma_probe()
866 tdc->vc.desc_free = tegra_adma_desc_free; in tegra_adma_probe()
867 tdc->tdma = tdma; in tegra_adma_probe()