Lines Matching refs:fchan

35 static int st_fdma_dreq_get(struct st_fdma_chan *fchan)  in st_fdma_dreq_get()  argument
37 struct st_fdma_dev *fdev = fchan->fdev; in st_fdma_dreq_get()
38 u32 req_line_cfg = fchan->cfg.req_line; in st_fdma_dreq_get()
69 static void st_fdma_dreq_put(struct st_fdma_chan *fchan) in st_fdma_dreq_put() argument
71 struct st_fdma_dev *fdev = fchan->fdev; in st_fdma_dreq_put()
73 dev_dbg(fdev->dev, "put dreq_line:%#x\n", fchan->dreq_line); in st_fdma_dreq_put()
74 clear_bit(fchan->dreq_line, &fdev->dreq_mask); in st_fdma_dreq_put()
77 static void st_fdma_xfer_desc(struct st_fdma_chan *fchan) in st_fdma_xfer_desc() argument
82 vdesc = vchan_next_desc(&fchan->vchan); in st_fdma_xfer_desc()
86 fchan->fdesc = to_st_fdma_desc(vdesc); in st_fdma_xfer_desc()
87 nbytes = fchan->fdesc->node[0].desc->nbytes; in st_fdma_xfer_desc()
88 cmd = FDMA_CMD_START(fchan->vchan.chan.chan_id); in st_fdma_xfer_desc()
89 ch_cmd = fchan->fdesc->node[0].pdesc | FDMA_CH_CMD_STA_START; in st_fdma_xfer_desc()
92 fnode_write(fchan, nbytes, FDMA_CNTN_OFST); in st_fdma_xfer_desc()
93 fchan_write(fchan, ch_cmd, FDMA_CH_CMD_OFST); in st_fdma_xfer_desc()
95 fchan->fdev->slim_rproc->peri + FDMA_CMD_SET_OFST); in st_fdma_xfer_desc()
97 dev_dbg(fchan->fdev->dev, "start chan:%d\n", fchan->vchan.chan.chan_id); in st_fdma_xfer_desc()
100 static void st_fdma_ch_sta_update(struct st_fdma_chan *fchan, in st_fdma_ch_sta_update() argument
104 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_ch_sta_update()
105 struct st_fdma_dev *fdev = fchan->fdev; in st_fdma_ch_sta_update()
107 ch_sta = fchan_read(fchan, FDMA_CH_CMD_OFST); in st_fdma_ch_sta_update()
113 fchan->status = DMA_ERROR; in st_fdma_ch_sta_update()
119 fchan->status = DMA_PAUSED; in st_fdma_ch_sta_update()
123 fchan->status = DMA_IN_PROGRESS; in st_fdma_ch_sta_update()
132 struct st_fdma_chan *fchan = &fdev->chans[0]; in st_fdma_irq_handler() local
138 for (; int_sta != 0 ; int_sta >>= 2, fchan++) { in st_fdma_irq_handler()
142 spin_lock(&fchan->vchan.lock); in st_fdma_irq_handler()
143 st_fdma_ch_sta_update(fchan, int_sta); in st_fdma_irq_handler()
145 if (fchan->fdesc) { in st_fdma_irq_handler()
146 if (!fchan->fdesc->iscyclic) { in st_fdma_irq_handler()
147 list_del(&fchan->fdesc->vdesc.node); in st_fdma_irq_handler()
148 vchan_cookie_complete(&fchan->fdesc->vdesc); in st_fdma_irq_handler()
149 fchan->fdesc = NULL; in st_fdma_irq_handler()
150 fchan->status = DMA_COMPLETE; in st_fdma_irq_handler()
152 vchan_cyclic_callback(&fchan->fdesc->vdesc); in st_fdma_irq_handler()
156 if (!fchan->fdesc) in st_fdma_irq_handler()
157 st_fdma_xfer_desc(fchan); in st_fdma_irq_handler()
160 spin_unlock(&fchan->vchan.lock); in st_fdma_irq_handler()
174 struct st_fdma_chan *fchan; in st_fdma_of_xlate() local
193 fchan = to_st_fdma_chan(chan); in st_fdma_of_xlate()
195 fchan->cfg.of_node = dma_spec->np; in st_fdma_of_xlate()
196 fchan->cfg.req_line = dma_spec->args[0]; in st_fdma_of_xlate()
197 fchan->cfg.req_ctrl = 0; in st_fdma_of_xlate()
198 fchan->cfg.type = ST_FDMA_TYPE_FREE_RUN; in st_fdma_of_xlate()
201 fchan->cfg.req_ctrl = dma_spec->args[1] in st_fdma_of_xlate()
205 fchan->cfg.type = dma_spec->args[2]; in st_fdma_of_xlate()
207 if (fchan->cfg.type == ST_FDMA_TYPE_FREE_RUN) { in st_fdma_of_xlate()
208 fchan->dreq_line = 0; in st_fdma_of_xlate()
210 fchan->dreq_line = st_fdma_dreq_get(fchan); in st_fdma_of_xlate()
211 if (IS_ERR_VALUE(fchan->dreq_line)) { in st_fdma_of_xlate()
212 chan = ERR_PTR(fchan->dreq_line); in st_fdma_of_xlate()
218 fchan->cfg.req_line, fchan->cfg.type, fchan->cfg.req_ctrl); in st_fdma_of_xlate()
235 dma_pool_free(fdesc->fchan->node_pool, fdesc->node[i].desc, in st_fdma_free_desc()
240 static struct st_fdma_desc *st_fdma_alloc_desc(struct st_fdma_chan *fchan, in st_fdma_alloc_desc() argument
251 fdesc->fchan = fchan; in st_fdma_alloc_desc()
254 fdesc->node[i].desc = dma_pool_alloc(fchan->node_pool, in st_fdma_alloc_desc()
263 dma_pool_free(fchan->node_pool, fdesc->node[i].desc, in st_fdma_alloc_desc()
271 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_alloc_chan_res() local
274 fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device), in st_fdma_alloc_chan_res()
275 fchan->fdev->dev, in st_fdma_alloc_chan_res()
280 if (!fchan->node_pool) { in st_fdma_alloc_chan_res()
281 dev_err(fchan->fdev->dev, "unable to allocate desc pool\n"); in st_fdma_alloc_chan_res()
285 dev_dbg(fchan->fdev->dev, "alloc ch_id:%d type:%d\n", in st_fdma_alloc_chan_res()
286 fchan->vchan.chan.chan_id, fchan->cfg.type); in st_fdma_alloc_chan_res()
293 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_free_chan_res() local
294 struct rproc *rproc = fchan->fdev->slim_rproc->rproc; in st_fdma_free_chan_res()
299 dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n", in st_fdma_free_chan_res()
300 __func__, fchan->vchan.chan.chan_id); in st_fdma_free_chan_res()
302 if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN) in st_fdma_free_chan_res()
303 st_fdma_dreq_put(fchan); in st_fdma_free_chan_res()
305 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_free_chan_res()
306 fchan->fdesc = NULL; in st_fdma_free_chan_res()
307 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_free_chan_res()
309 dma_pool_destroy(fchan->node_pool); in st_fdma_free_chan_res()
310 fchan->node_pool = NULL; in st_fdma_free_chan_res()
311 memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg)); in st_fdma_free_chan_res()
320 struct st_fdma_chan *fchan; in st_fdma_prep_dma_memcpy() local
327 fchan = to_st_fdma_chan(chan); in st_fdma_prep_dma_memcpy()
330 fdesc = st_fdma_alloc_desc(fchan, 1); in st_fdma_prep_dma_memcpy()
332 dev_err(fchan->fdev->dev, "no memory for desc\n"); in st_fdma_prep_dma_memcpy()
349 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); in st_fdma_prep_dma_memcpy()
352 static int config_reqctrl(struct st_fdma_chan *fchan, in config_reqctrl() argument
357 int ch_id = fchan->vchan.chan.chan_id; in config_reqctrl()
358 struct st_fdma_dev *fdev = fchan->fdev; in config_reqctrl()
363 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_WNR; in config_reqctrl()
364 maxburst = fchan->scfg.src_maxburst; in config_reqctrl()
365 width = fchan->scfg.src_addr_width; in config_reqctrl()
366 addr = fchan->scfg.src_addr; in config_reqctrl()
370 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_WNR; in config_reqctrl()
371 maxburst = fchan->scfg.dst_maxburst; in config_reqctrl()
372 width = fchan->scfg.dst_addr_width; in config_reqctrl()
373 addr = fchan->scfg.dst_addr; in config_reqctrl()
380 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_OPCODE_MASK; in config_reqctrl()
385 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST1; in config_reqctrl()
389 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST2; in config_reqctrl()
393 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST4; in config_reqctrl()
397 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST8; in config_reqctrl()
404 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_NUM_OPS_MASK; in config_reqctrl()
405 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_NUM_OPS(maxburst-1); in config_reqctrl()
406 dreq_write(fchan, fchan->cfg.req_ctrl, FDMA_REQ_CTRL_OFST); in config_reqctrl()
408 fchan->cfg.dev_addr = addr; in config_reqctrl()
409 fchan->cfg.dir = direction; in config_reqctrl()
412 ch_id, addr, fchan->cfg.req_ctrl); in config_reqctrl()
418 struct st_fdma_chan *fchan, in fill_hw_node() argument
424 hw_node->daddr = fchan->cfg.dev_addr; in fill_hw_node()
428 hw_node->saddr = fchan->cfg.dev_addr; in fill_hw_node()
438 struct st_fdma_chan *fchan; in st_fdma_prep_common() local
443 fchan = to_st_fdma_chan(chan); in st_fdma_prep_common()
446 dev_err(fchan->fdev->dev, "bad direction?\n"); in st_fdma_prep_common()
450 return fchan; in st_fdma_prep_common()
458 struct st_fdma_chan *fchan; in st_fdma_prep_dma_cyclic() local
462 fchan = st_fdma_prep_common(chan, len, direction); in st_fdma_prep_dma_cyclic()
463 if (!fchan) in st_fdma_prep_dma_cyclic()
469 if (config_reqctrl(fchan, direction)) { in st_fdma_prep_dma_cyclic()
470 dev_err(fchan->fdev->dev, "bad width or direction\n"); in st_fdma_prep_dma_cyclic()
476 dev_err(fchan->fdev->dev, "len is not multiple of period\n"); in st_fdma_prep_dma_cyclic()
481 fdesc = st_fdma_alloc_desc(fchan, sg_len); in st_fdma_prep_dma_cyclic()
483 dev_err(fchan->fdev->dev, "no memory for desc\n"); in st_fdma_prep_dma_cyclic()
495 FDMA_NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line); in st_fdma_prep_dma_cyclic()
498 fill_hw_node(hw_node, fchan, direction); in st_fdma_prep_dma_cyclic()
509 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); in st_fdma_prep_dma_cyclic()
517 struct st_fdma_chan *fchan; in st_fdma_prep_slave_sg() local
523 fchan = st_fdma_prep_common(chan, sg_len, direction); in st_fdma_prep_slave_sg()
524 if (!fchan) in st_fdma_prep_slave_sg()
530 fdesc = st_fdma_alloc_desc(fchan, sg_len); in st_fdma_prep_slave_sg()
532 dev_err(fchan->fdev->dev, "no memory for desc\n"); in st_fdma_prep_slave_sg()
542 hw_node->control = FDMA_NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line); in st_fdma_prep_slave_sg()
544 fill_hw_node(hw_node, fchan, direction); in st_fdma_prep_slave_sg()
558 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); in st_fdma_prep_slave_sg()
561 static size_t st_fdma_desc_residue(struct st_fdma_chan *fchan, in st_fdma_desc_residue() argument
565 struct st_fdma_desc *fdesc = fchan->fdesc; in st_fdma_desc_residue()
571 cur_addr = fchan_read(fchan, FDMA_CH_CMD_OFST); in st_fdma_desc_residue()
575 for (i = fchan->fdesc->n_nodes - 1 ; i >= 0; i--) { in st_fdma_desc_residue()
577 residue += fnode_read(fchan, FDMA_CNTN_OFST); in st_fdma_desc_residue()
590 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_tx_status() local
599 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_tx_status()
600 vd = vchan_find_desc(&fchan->vchan, cookie); in st_fdma_tx_status()
601 if (fchan->fdesc && cookie == fchan->fdesc->vdesc.tx.cookie) in st_fdma_tx_status()
602 txstate->residue = st_fdma_desc_residue(fchan, vd, true); in st_fdma_tx_status()
604 txstate->residue = st_fdma_desc_residue(fchan, vd, false); in st_fdma_tx_status()
608 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_tx_status()
615 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_issue_pending() local
618 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_issue_pending()
620 if (vchan_issue_pending(&fchan->vchan) && !fchan->fdesc) in st_fdma_issue_pending()
621 st_fdma_xfer_desc(fchan); in st_fdma_issue_pending()
623 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_issue_pending()
630 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_pause() local
631 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_pause()
634 dev_dbg(fchan->fdev->dev, "pause chan:%d\n", ch_id); in st_fdma_pause()
636 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_pause()
637 if (fchan->fdesc) in st_fdma_pause()
638 fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST); in st_fdma_pause()
639 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_pause()
648 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_resume() local
649 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_resume()
651 dev_dbg(fchan->fdev->dev, "resume chan:%d\n", ch_id); in st_fdma_resume()
653 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_resume()
654 if (fchan->fdesc) { in st_fdma_resume()
655 val = fchan_read(fchan, FDMA_CH_CMD_OFST); in st_fdma_resume()
657 fchan_write(fchan, val, FDMA_CH_CMD_OFST); in st_fdma_resume()
659 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_resume()
668 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_terminate_all() local
669 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_terminate_all()
672 dev_dbg(fchan->fdev->dev, "terminate chan:%d\n", ch_id); in st_fdma_terminate_all()
674 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_terminate_all()
675 fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST); in st_fdma_terminate_all()
676 fchan->fdesc = NULL; in st_fdma_terminate_all()
677 vchan_get_all_descriptors(&fchan->vchan, &head); in st_fdma_terminate_all()
678 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_terminate_all()
679 vchan_dma_desc_free_list(&fchan->vchan, &head); in st_fdma_terminate_all()
687 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_slave_config() local
689 memcpy(&fchan->scfg, slave_cfg, sizeof(fchan->scfg)); in st_fdma_slave_config()
736 struct st_fdma_chan *fchan; in st_fdma_free() local
740 fchan = &fdev->chans[i]; in st_fdma_free()
741 list_del(&fchan->vchan.chan.device_node); in st_fdma_free()
742 tasklet_kill(&fchan->vchan.task); in st_fdma_free()
804 struct st_fdma_chan *fchan = &fdev->chans[i]; in st_fdma_probe() local
806 fchan->fdev = fdev; in st_fdma_probe()
807 fchan->vchan.desc_free = st_fdma_free_desc; in st_fdma_probe()
808 vchan_init(&fchan->vchan, &fdev->dma_device); in st_fdma_probe()