• Home
  • Raw
  • Download

Lines Matching refs:tdc

167 static inline void tdma_ch_write(struct tegra_adma_chan *tdc, u32 reg, u32 val)  in tdma_ch_write()  argument
169 writel(val, tdc->chan_addr + reg); in tdma_ch_write()
172 static inline u32 tdma_ch_read(struct tegra_adma_chan *tdc, u32 reg) in tdma_ch_read() argument
174 return readl(tdc->chan_addr + reg); in tdma_ch_read()
188 static inline struct device *tdc2dev(struct tegra_adma_chan *tdc) in tdc2dev() argument
190 return tdc->tdma->dev; in tdc2dev()
201 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_slave_config() local
203 memcpy(&tdc->sconfig, sconfig, sizeof(*sconfig)); in tegra_adma_slave_config()
232 static int tegra_adma_request_alloc(struct tegra_adma_chan *tdc, in tegra_adma_request_alloc() argument
235 struct tegra_adma *tdma = tdc->tdma; in tegra_adma_request_alloc()
236 unsigned int sreq_index = tdc->sreq_index; in tegra_adma_request_alloc()
238 if (tdc->sreq_reserved) in tegra_adma_request_alloc()
239 return tdc->sreq_dir == direction ? 0 : -EINVAL; in tegra_adma_request_alloc()
268 dma_chan_name(&tdc->vc.chan)); in tegra_adma_request_alloc()
272 tdc->sreq_dir = direction; in tegra_adma_request_alloc()
273 tdc->sreq_reserved = true; in tegra_adma_request_alloc()
278 static void tegra_adma_request_free(struct tegra_adma_chan *tdc) in tegra_adma_request_free() argument
280 struct tegra_adma *tdma = tdc->tdma; in tegra_adma_request_free()
282 if (!tdc->sreq_reserved) in tegra_adma_request_free()
285 switch (tdc->sreq_dir) { in tegra_adma_request_free()
287 clear_bit(tdc->sreq_index, &tdma->tx_requests_reserved); in tegra_adma_request_free()
291 clear_bit(tdc->sreq_index, &tdma->rx_requests_reserved); in tegra_adma_request_free()
296 dma_chan_name(&tdc->vc.chan)); in tegra_adma_request_free()
300 tdc->sreq_reserved = false; in tegra_adma_request_free()
303 static u32 tegra_adma_irq_status(struct tegra_adma_chan *tdc) in tegra_adma_irq_status() argument
305 u32 status = tdma_ch_read(tdc, ADMA_CH_INT_STATUS); in tegra_adma_irq_status()
310 static u32 tegra_adma_irq_clear(struct tegra_adma_chan *tdc) in tegra_adma_irq_clear() argument
312 u32 status = tegra_adma_irq_status(tdc); in tegra_adma_irq_clear()
315 tdma_ch_write(tdc, ADMA_CH_INT_CLEAR, status); in tegra_adma_irq_clear()
320 static void tegra_adma_stop(struct tegra_adma_chan *tdc) in tegra_adma_stop() argument
325 tdma_ch_write(tdc, ADMA_CH_CMD, 0); in tegra_adma_stop()
328 tegra_adma_irq_clear(tdc); in tegra_adma_stop()
330 if (readx_poll_timeout_atomic(readl, tdc->chan_addr + ADMA_CH_STATUS, in tegra_adma_stop()
333 dev_err(tdc2dev(tdc), "unable to stop DMA channel\n"); in tegra_adma_stop()
337 kfree(tdc->desc); in tegra_adma_stop()
338 tdc->desc = NULL; in tegra_adma_stop()
341 static void tegra_adma_start(struct tegra_adma_chan *tdc) in tegra_adma_start() argument
343 struct virt_dma_desc *vd = vchan_next_desc(&tdc->vc); in tegra_adma_start()
355 dev_warn(tdc2dev(tdc), "unable to start DMA, no descriptor\n"); in tegra_adma_start()
361 tdc->tx_buf_pos = 0; in tegra_adma_start()
362 tdc->tx_buf_count = 0; in tegra_adma_start()
363 tdma_ch_write(tdc, ADMA_CH_TC, ch_regs->tc); in tegra_adma_start()
364 tdma_ch_write(tdc, ADMA_CH_CTRL, ch_regs->ctrl); in tegra_adma_start()
365 tdma_ch_write(tdc, ADMA_CH_LOWER_SRC_ADDR, ch_regs->src_addr); in tegra_adma_start()
366 tdma_ch_write(tdc, ADMA_CH_LOWER_TRG_ADDR, ch_regs->trg_addr); in tegra_adma_start()
367 tdma_ch_write(tdc, ADMA_CH_FIFO_CTRL, ch_regs->fifo_ctrl); in tegra_adma_start()
368 tdma_ch_write(tdc, ADMA_CH_CONFIG, ch_regs->config); in tegra_adma_start()
371 tdma_ch_write(tdc, ADMA_CH_CMD, 1); in tegra_adma_start()
373 tdc->desc = desc; in tegra_adma_start()
376 static unsigned int tegra_adma_get_residue(struct tegra_adma_chan *tdc) in tegra_adma_get_residue() argument
378 struct tegra_adma_desc *desc = tdc->desc; in tegra_adma_get_residue()
380 unsigned int pos = tdma_ch_read(tdc, ADMA_CH_XFER_STATUS); in tegra_adma_get_residue()
386 if (pos < tdc->tx_buf_pos) in tegra_adma_get_residue()
387 tdc->tx_buf_count += pos + (max - tdc->tx_buf_pos); in tegra_adma_get_residue()
389 tdc->tx_buf_count += pos - tdc->tx_buf_pos; in tegra_adma_get_residue()
391 periods_remaining = tdc->tx_buf_count % desc->num_periods; in tegra_adma_get_residue()
392 tdc->tx_buf_pos = pos; in tegra_adma_get_residue()
399 struct tegra_adma_chan *tdc = dev_id; in tegra_adma_isr() local
403 spin_lock_irqsave(&tdc->vc.lock, flags); in tegra_adma_isr()
405 status = tegra_adma_irq_clear(tdc); in tegra_adma_isr()
406 if (status == 0 || !tdc->desc) { in tegra_adma_isr()
407 spin_unlock_irqrestore(&tdc->vc.lock, flags); in tegra_adma_isr()
411 vchan_cyclic_callback(&tdc->desc->vd); in tegra_adma_isr()
413 spin_unlock_irqrestore(&tdc->vc.lock, flags); in tegra_adma_isr()
420 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_issue_pending() local
423 spin_lock_irqsave(&tdc->vc.lock, flags); in tegra_adma_issue_pending()
425 if (vchan_issue_pending(&tdc->vc)) { in tegra_adma_issue_pending()
426 if (!tdc->desc) in tegra_adma_issue_pending()
427 tegra_adma_start(tdc); in tegra_adma_issue_pending()
430 spin_unlock_irqrestore(&tdc->vc.lock, flags); in tegra_adma_issue_pending()
435 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_terminate_all() local
439 spin_lock_irqsave(&tdc->vc.lock, flags); in tegra_adma_terminate_all()
441 if (tdc->desc) in tegra_adma_terminate_all()
442 tegra_adma_stop(tdc); in tegra_adma_terminate_all()
444 tegra_adma_request_free(tdc); in tegra_adma_terminate_all()
445 vchan_get_all_descriptors(&tdc->vc, &head); in tegra_adma_terminate_all()
446 spin_unlock_irqrestore(&tdc->vc.lock, flags); in tegra_adma_terminate_all()
447 vchan_dma_desc_free_list(&tdc->vc, &head); in tegra_adma_terminate_all()
456 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_tx_status() local
467 spin_lock_irqsave(&tdc->vc.lock, flags); in tegra_adma_tx_status()
469 vd = vchan_find_desc(&tdc->vc, cookie); in tegra_adma_tx_status()
473 } else if (tdc->desc && tdc->desc->vd.tx.cookie == cookie) { in tegra_adma_tx_status()
474 residual = tegra_adma_get_residue(tdc); in tegra_adma_tx_status()
479 spin_unlock_irqrestore(&tdc->vc.lock, flags); in tegra_adma_tx_status()
486 static int tegra_adma_set_xfer_params(struct tegra_adma_chan *tdc, in tegra_adma_set_xfer_params() argument
500 burst_size = fls(tdc->sconfig.dst_maxburst); in tegra_adma_set_xfer_params()
502 ch_regs->ctrl = ADMA_CH_CTRL_TX_REQ(tdc->sreq_index); in tegra_adma_set_xfer_params()
508 burst_size = fls(tdc->sconfig.src_maxburst); in tegra_adma_set_xfer_params()
510 ch_regs->ctrl = ADMA_CH_CTRL_RX_REQ(tdc->sreq_index); in tegra_adma_set_xfer_params()
515 dev_err(tdc2dev(tdc), "DMA direction is not supported\n"); in tegra_adma_set_xfer_params()
530 return tegra_adma_request_alloc(tdc, direction); in tegra_adma_set_xfer_params()
538 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_prep_dma_cyclic() local
542 dev_err(tdc2dev(tdc), "invalid buffer/period len\n"); in tegra_adma_prep_dma_cyclic()
547 dev_err(tdc2dev(tdc), "buf_len not a multiple of period_len\n"); in tegra_adma_prep_dma_cyclic()
552 dev_err(tdc2dev(tdc), "invalid buffer alignment\n"); in tegra_adma_prep_dma_cyclic()
564 if (tegra_adma_set_xfer_params(tdc, desc, buf_addr, direction)) { in tegra_adma_prep_dma_cyclic()
569 return vchan_tx_prep(&tdc->vc, &desc->vd, flags); in tegra_adma_prep_dma_cyclic()
574 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_alloc_chan_resources() local
577 ret = request_irq(tdc->irq, tegra_adma_isr, 0, dma_chan_name(dc), tdc); in tegra_adma_alloc_chan_resources()
579 dev_err(tdc2dev(tdc), "failed to get interrupt for %s\n", in tegra_adma_alloc_chan_resources()
584 ret = pm_runtime_get_sync(tdc2dev(tdc)); in tegra_adma_alloc_chan_resources()
586 free_irq(tdc->irq, tdc); in tegra_adma_alloc_chan_resources()
590 dma_cookie_init(&tdc->vc.chan); in tegra_adma_alloc_chan_resources()
597 struct tegra_adma_chan *tdc = to_tegra_adma_chan(dc); in tegra_adma_free_chan_resources() local
600 vchan_free_chan_resources(&tdc->vc); in tegra_adma_free_chan_resources()
601 tasklet_kill(&tdc->vc.task); in tegra_adma_free_chan_resources()
602 free_irq(tdc->irq, tdc); in tegra_adma_free_chan_resources()
603 pm_runtime_put(tdc2dev(tdc)); in tegra_adma_free_chan_resources()
605 tdc->sreq_index = 0; in tegra_adma_free_chan_resources()
606 tdc->sreq_dir = DMA_TRANS_NONE; in tegra_adma_free_chan_resources()
613 struct tegra_adma_chan *tdc; in tegra_dma_of_xlate() local
631 tdc = to_tegra_adma_chan(chan); in tegra_dma_of_xlate()
632 tdc->sreq_index = sreq_index; in tegra_dma_of_xlate()
641 struct tegra_adma_chan *tdc; in tegra_adma_runtime_suspend() local
649 tdc = &tdma->channels[i]; in tegra_adma_runtime_suspend()
650 ch_reg = &tdc->ch_regs; in tegra_adma_runtime_suspend()
651 ch_reg->cmd = tdma_ch_read(tdc, ADMA_CH_CMD); in tegra_adma_runtime_suspend()
655 ch_reg->tc = tdma_ch_read(tdc, ADMA_CH_TC); in tegra_adma_runtime_suspend()
656 ch_reg->src_addr = tdma_ch_read(tdc, ADMA_CH_LOWER_SRC_ADDR); in tegra_adma_runtime_suspend()
657 ch_reg->trg_addr = tdma_ch_read(tdc, ADMA_CH_LOWER_TRG_ADDR); in tegra_adma_runtime_suspend()
658 ch_reg->ctrl = tdma_ch_read(tdc, ADMA_CH_CTRL); in tegra_adma_runtime_suspend()
659 ch_reg->fifo_ctrl = tdma_ch_read(tdc, ADMA_CH_FIFO_CTRL); in tegra_adma_runtime_suspend()
660 ch_reg->config = tdma_ch_read(tdc, ADMA_CH_CONFIG); in tegra_adma_runtime_suspend()
673 struct tegra_adma_chan *tdc; in tegra_adma_runtime_resume() local
687 tdc = &tdma->channels[i]; in tegra_adma_runtime_resume()
688 ch_reg = &tdc->ch_regs; in tegra_adma_runtime_resume()
692 tdma_ch_write(tdc, ADMA_CH_TC, ch_reg->tc); in tegra_adma_runtime_resume()
693 tdma_ch_write(tdc, ADMA_CH_LOWER_SRC_ADDR, ch_reg->src_addr); in tegra_adma_runtime_resume()
694 tdma_ch_write(tdc, ADMA_CH_LOWER_TRG_ADDR, ch_reg->trg_addr); in tegra_adma_runtime_resume()
695 tdma_ch_write(tdc, ADMA_CH_CTRL, ch_reg->ctrl); in tegra_adma_runtime_resume()
696 tdma_ch_write(tdc, ADMA_CH_FIFO_CTRL, ch_reg->fifo_ctrl); in tegra_adma_runtime_resume()
697 tdma_ch_write(tdc, ADMA_CH_CONFIG, ch_reg->config); in tegra_adma_runtime_resume()
698 tdma_ch_write(tdc, ADMA_CH_CMD, ch_reg->cmd); in tegra_adma_runtime_resume()
749 struct tegra_adma_chan *tdc = &tdma->channels[i]; in tegra_adma_probe() local
751 tdc->chan_addr = tdma->base_addr + ADMA_CH_REG_OFFSET(i); in tegra_adma_probe()
753 tdc->irq = of_irq_get(pdev->dev.of_node, i); in tegra_adma_probe()
754 if (tdc->irq <= 0) { in tegra_adma_probe()
755 ret = tdc->irq ?: -ENXIO; in tegra_adma_probe()
759 vchan_init(&tdc->vc, &tdma->dma_dev); in tegra_adma_probe()
760 tdc->vc.desc_free = tegra_adma_desc_free; in tegra_adma_probe()
761 tdc->tdma = tdma; in tegra_adma_probe()