Lines Matching refs:fchan

33 static int st_fdma_dreq_get(struct st_fdma_chan *fchan)  in st_fdma_dreq_get()  argument
35 struct st_fdma_dev *fdev = fchan->fdev; in st_fdma_dreq_get()
36 u32 req_line_cfg = fchan->cfg.req_line; in st_fdma_dreq_get()
67 static void st_fdma_dreq_put(struct st_fdma_chan *fchan) in st_fdma_dreq_put() argument
69 struct st_fdma_dev *fdev = fchan->fdev; in st_fdma_dreq_put()
71 dev_dbg(fdev->dev, "put dreq_line:%#x\n", fchan->dreq_line); in st_fdma_dreq_put()
72 clear_bit(fchan->dreq_line, &fdev->dreq_mask); in st_fdma_dreq_put()
75 static void st_fdma_xfer_desc(struct st_fdma_chan *fchan) in st_fdma_xfer_desc() argument
80 vdesc = vchan_next_desc(&fchan->vchan); in st_fdma_xfer_desc()
84 fchan->fdesc = to_st_fdma_desc(vdesc); in st_fdma_xfer_desc()
85 nbytes = fchan->fdesc->node[0].desc->nbytes; in st_fdma_xfer_desc()
86 cmd = FDMA_CMD_START(fchan->vchan.chan.chan_id); in st_fdma_xfer_desc()
87 ch_cmd = fchan->fdesc->node[0].pdesc | FDMA_CH_CMD_STA_START; in st_fdma_xfer_desc()
90 fnode_write(fchan, nbytes, FDMA_CNTN_OFST); in st_fdma_xfer_desc()
91 fchan_write(fchan, ch_cmd, FDMA_CH_CMD_OFST); in st_fdma_xfer_desc()
93 fchan->fdev->slim_rproc->peri + FDMA_CMD_SET_OFST); in st_fdma_xfer_desc()
95 dev_dbg(fchan->fdev->dev, "start chan:%d\n", fchan->vchan.chan.chan_id); in st_fdma_xfer_desc()
98 static void st_fdma_ch_sta_update(struct st_fdma_chan *fchan, in st_fdma_ch_sta_update() argument
102 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_ch_sta_update()
103 struct st_fdma_dev *fdev = fchan->fdev; in st_fdma_ch_sta_update()
105 ch_sta = fchan_read(fchan, FDMA_CH_CMD_OFST); in st_fdma_ch_sta_update()
111 fchan->status = DMA_ERROR; in st_fdma_ch_sta_update()
117 fchan->status = DMA_PAUSED; in st_fdma_ch_sta_update()
121 fchan->status = DMA_IN_PROGRESS; in st_fdma_ch_sta_update()
130 struct st_fdma_chan *fchan = &fdev->chans[0]; in st_fdma_irq_handler() local
136 for (; int_sta != 0 ; int_sta >>= 2, fchan++) { in st_fdma_irq_handler()
140 spin_lock(&fchan->vchan.lock); in st_fdma_irq_handler()
141 st_fdma_ch_sta_update(fchan, int_sta); in st_fdma_irq_handler()
143 if (fchan->fdesc) { in st_fdma_irq_handler()
144 if (!fchan->fdesc->iscyclic) { in st_fdma_irq_handler()
145 list_del(&fchan->fdesc->vdesc.node); in st_fdma_irq_handler()
146 vchan_cookie_complete(&fchan->fdesc->vdesc); in st_fdma_irq_handler()
147 fchan->fdesc = NULL; in st_fdma_irq_handler()
148 fchan->status = DMA_COMPLETE; in st_fdma_irq_handler()
150 vchan_cyclic_callback(&fchan->fdesc->vdesc); in st_fdma_irq_handler()
154 if (!fchan->fdesc) in st_fdma_irq_handler()
155 st_fdma_xfer_desc(fchan); in st_fdma_irq_handler()
158 spin_unlock(&fchan->vchan.lock); in st_fdma_irq_handler()
172 struct st_fdma_chan *fchan; in st_fdma_of_xlate() local
191 fchan = to_st_fdma_chan(chan); in st_fdma_of_xlate()
193 fchan->cfg.of_node = dma_spec->np; in st_fdma_of_xlate()
194 fchan->cfg.req_line = dma_spec->args[0]; in st_fdma_of_xlate()
195 fchan->cfg.req_ctrl = 0; in st_fdma_of_xlate()
196 fchan->cfg.type = ST_FDMA_TYPE_FREE_RUN; in st_fdma_of_xlate()
199 fchan->cfg.req_ctrl = dma_spec->args[1] in st_fdma_of_xlate()
203 fchan->cfg.type = dma_spec->args[2]; in st_fdma_of_xlate()
205 if (fchan->cfg.type == ST_FDMA_TYPE_FREE_RUN) { in st_fdma_of_xlate()
206 fchan->dreq_line = 0; in st_fdma_of_xlate()
208 fchan->dreq_line = st_fdma_dreq_get(fchan); in st_fdma_of_xlate()
209 if (IS_ERR_VALUE(fchan->dreq_line)) { in st_fdma_of_xlate()
210 chan = ERR_PTR(fchan->dreq_line); in st_fdma_of_xlate()
216 fchan->cfg.req_line, fchan->cfg.type, fchan->cfg.req_ctrl); in st_fdma_of_xlate()
233 dma_pool_free(fdesc->fchan->node_pool, fdesc->node[i].desc, in st_fdma_free_desc()
238 static struct st_fdma_desc *st_fdma_alloc_desc(struct st_fdma_chan *fchan, in st_fdma_alloc_desc() argument
248 fdesc->fchan = fchan; in st_fdma_alloc_desc()
251 fdesc->node[i].desc = dma_pool_alloc(fchan->node_pool, in st_fdma_alloc_desc()
260 dma_pool_free(fchan->node_pool, fdesc->node[i].desc, in st_fdma_alloc_desc()
268 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_alloc_chan_res() local
271 fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device), in st_fdma_alloc_chan_res()
272 fchan->fdev->dev, in st_fdma_alloc_chan_res()
277 if (!fchan->node_pool) { in st_fdma_alloc_chan_res()
278 dev_err(fchan->fdev->dev, "unable to allocate desc pool\n"); in st_fdma_alloc_chan_res()
282 dev_dbg(fchan->fdev->dev, "alloc ch_id:%d type:%d\n", in st_fdma_alloc_chan_res()
283 fchan->vchan.chan.chan_id, fchan->cfg.type); in st_fdma_alloc_chan_res()
290 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_free_chan_res() local
291 struct rproc *rproc = fchan->fdev->slim_rproc->rproc; in st_fdma_free_chan_res()
294 dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n", in st_fdma_free_chan_res()
295 __func__, fchan->vchan.chan.chan_id); in st_fdma_free_chan_res()
297 if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN) in st_fdma_free_chan_res()
298 st_fdma_dreq_put(fchan); in st_fdma_free_chan_res()
300 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_free_chan_res()
301 fchan->fdesc = NULL; in st_fdma_free_chan_res()
302 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_free_chan_res()
304 dma_pool_destroy(fchan->node_pool); in st_fdma_free_chan_res()
305 fchan->node_pool = NULL; in st_fdma_free_chan_res()
306 memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg)); in st_fdma_free_chan_res()
315 struct st_fdma_chan *fchan; in st_fdma_prep_dma_memcpy() local
322 fchan = to_st_fdma_chan(chan); in st_fdma_prep_dma_memcpy()
325 fdesc = st_fdma_alloc_desc(fchan, 1); in st_fdma_prep_dma_memcpy()
327 dev_err(fchan->fdev->dev, "no memory for desc\n"); in st_fdma_prep_dma_memcpy()
344 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); in st_fdma_prep_dma_memcpy()
347 static int config_reqctrl(struct st_fdma_chan *fchan, in config_reqctrl() argument
352 int ch_id = fchan->vchan.chan.chan_id; in config_reqctrl()
353 struct st_fdma_dev *fdev = fchan->fdev; in config_reqctrl()
358 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_WNR; in config_reqctrl()
359 maxburst = fchan->scfg.src_maxburst; in config_reqctrl()
360 width = fchan->scfg.src_addr_width; in config_reqctrl()
361 addr = fchan->scfg.src_addr; in config_reqctrl()
365 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_WNR; in config_reqctrl()
366 maxburst = fchan->scfg.dst_maxburst; in config_reqctrl()
367 width = fchan->scfg.dst_addr_width; in config_reqctrl()
368 addr = fchan->scfg.dst_addr; in config_reqctrl()
375 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_OPCODE_MASK; in config_reqctrl()
380 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST1; in config_reqctrl()
384 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST2; in config_reqctrl()
388 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST4; in config_reqctrl()
392 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST8; in config_reqctrl()
399 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_NUM_OPS_MASK; in config_reqctrl()
400 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_NUM_OPS(maxburst-1); in config_reqctrl()
401 dreq_write(fchan, fchan->cfg.req_ctrl, FDMA_REQ_CTRL_OFST); in config_reqctrl()
403 fchan->cfg.dev_addr = addr; in config_reqctrl()
404 fchan->cfg.dir = direction; in config_reqctrl()
407 ch_id, addr, fchan->cfg.req_ctrl); in config_reqctrl()
413 struct st_fdma_chan *fchan, in fill_hw_node() argument
419 hw_node->daddr = fchan->cfg.dev_addr; in fill_hw_node()
423 hw_node->saddr = fchan->cfg.dev_addr; in fill_hw_node()
433 struct st_fdma_chan *fchan; in st_fdma_prep_common() local
438 fchan = to_st_fdma_chan(chan); in st_fdma_prep_common()
441 dev_err(fchan->fdev->dev, "bad direction?\n"); in st_fdma_prep_common()
445 return fchan; in st_fdma_prep_common()
453 struct st_fdma_chan *fchan; in st_fdma_prep_dma_cyclic() local
457 fchan = st_fdma_prep_common(chan, len, direction); in st_fdma_prep_dma_cyclic()
458 if (!fchan) in st_fdma_prep_dma_cyclic()
464 if (config_reqctrl(fchan, direction)) { in st_fdma_prep_dma_cyclic()
465 dev_err(fchan->fdev->dev, "bad width or direction\n"); in st_fdma_prep_dma_cyclic()
471 dev_err(fchan->fdev->dev, "len is not multiple of period\n"); in st_fdma_prep_dma_cyclic()
476 fdesc = st_fdma_alloc_desc(fchan, sg_len); in st_fdma_prep_dma_cyclic()
478 dev_err(fchan->fdev->dev, "no memory for desc\n"); in st_fdma_prep_dma_cyclic()
490 FDMA_NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line); in st_fdma_prep_dma_cyclic()
493 fill_hw_node(hw_node, fchan, direction); in st_fdma_prep_dma_cyclic()
504 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); in st_fdma_prep_dma_cyclic()
512 struct st_fdma_chan *fchan; in st_fdma_prep_slave_sg() local
518 fchan = st_fdma_prep_common(chan, sg_len, direction); in st_fdma_prep_slave_sg()
519 if (!fchan) in st_fdma_prep_slave_sg()
525 fdesc = st_fdma_alloc_desc(fchan, sg_len); in st_fdma_prep_slave_sg()
527 dev_err(fchan->fdev->dev, "no memory for desc\n"); in st_fdma_prep_slave_sg()
537 hw_node->control = FDMA_NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line); in st_fdma_prep_slave_sg()
539 fill_hw_node(hw_node, fchan, direction); in st_fdma_prep_slave_sg()
553 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); in st_fdma_prep_slave_sg()
556 static size_t st_fdma_desc_residue(struct st_fdma_chan *fchan, in st_fdma_desc_residue() argument
560 struct st_fdma_desc *fdesc = fchan->fdesc; in st_fdma_desc_residue()
566 cur_addr = fchan_read(fchan, FDMA_CH_CMD_OFST); in st_fdma_desc_residue()
570 for (i = fchan->fdesc->n_nodes - 1 ; i >= 0; i--) { in st_fdma_desc_residue()
572 residue += fnode_read(fchan, FDMA_CNTN_OFST); in st_fdma_desc_residue()
585 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_tx_status() local
594 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_tx_status()
595 vd = vchan_find_desc(&fchan->vchan, cookie); in st_fdma_tx_status()
596 if (fchan->fdesc && cookie == fchan->fdesc->vdesc.tx.cookie) in st_fdma_tx_status()
597 txstate->residue = st_fdma_desc_residue(fchan, vd, true); in st_fdma_tx_status()
599 txstate->residue = st_fdma_desc_residue(fchan, vd, false); in st_fdma_tx_status()
603 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_tx_status()
610 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_issue_pending() local
613 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_issue_pending()
615 if (vchan_issue_pending(&fchan->vchan) && !fchan->fdesc) in st_fdma_issue_pending()
616 st_fdma_xfer_desc(fchan); in st_fdma_issue_pending()
618 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_issue_pending()
624 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_pause() local
625 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_pause()
628 dev_dbg(fchan->fdev->dev, "pause chan:%d\n", ch_id); in st_fdma_pause()
630 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_pause()
631 if (fchan->fdesc) in st_fdma_pause()
632 fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST); in st_fdma_pause()
633 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_pause()
642 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_resume() local
643 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_resume()
645 dev_dbg(fchan->fdev->dev, "resume chan:%d\n", ch_id); in st_fdma_resume()
647 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_resume()
648 if (fchan->fdesc) { in st_fdma_resume()
649 val = fchan_read(fchan, FDMA_CH_CMD_OFST); in st_fdma_resume()
651 fchan_write(fchan, val, FDMA_CH_CMD_OFST); in st_fdma_resume()
653 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_resume()
662 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_terminate_all() local
663 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_terminate_all()
666 dev_dbg(fchan->fdev->dev, "terminate chan:%d\n", ch_id); in st_fdma_terminate_all()
668 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_terminate_all()
669 fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST); in st_fdma_terminate_all()
670 fchan->fdesc = NULL; in st_fdma_terminate_all()
671 vchan_get_all_descriptors(&fchan->vchan, &head); in st_fdma_terminate_all()
672 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_terminate_all()
673 vchan_dma_desc_free_list(&fchan->vchan, &head); in st_fdma_terminate_all()
681 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_slave_config() local
683 memcpy(&fchan->scfg, slave_cfg, sizeof(fchan->scfg)); in st_fdma_slave_config()
730 struct st_fdma_chan *fchan; in st_fdma_free() local
734 fchan = &fdev->chans[i]; in st_fdma_free()
735 list_del(&fchan->vchan.chan.device_node); in st_fdma_free()
736 tasklet_kill(&fchan->vchan.task); in st_fdma_free()
789 struct st_fdma_chan *fchan = &fdev->chans[i]; in st_fdma_probe() local
791 fchan->fdev = fdev; in st_fdma_probe()
792 fchan->vchan.desc_free = st_fdma_free_desc; in st_fdma_probe()
793 vchan_init(&fchan->vchan, &fdev->dma_device); in st_fdma_probe()