Lines Matching refs:fchan

32 static int st_fdma_dreq_get(struct st_fdma_chan *fchan)  in st_fdma_dreq_get()  argument
34 struct st_fdma_dev *fdev = fchan->fdev; in st_fdma_dreq_get()
35 u32 req_line_cfg = fchan->cfg.req_line; in st_fdma_dreq_get()
66 static void st_fdma_dreq_put(struct st_fdma_chan *fchan) in st_fdma_dreq_put() argument
68 struct st_fdma_dev *fdev = fchan->fdev; in st_fdma_dreq_put()
70 dev_dbg(fdev->dev, "put dreq_line:%#x\n", fchan->dreq_line); in st_fdma_dreq_put()
71 clear_bit(fchan->dreq_line, &fdev->dreq_mask); in st_fdma_dreq_put()
74 static void st_fdma_xfer_desc(struct st_fdma_chan *fchan) in st_fdma_xfer_desc() argument
79 vdesc = vchan_next_desc(&fchan->vchan); in st_fdma_xfer_desc()
83 fchan->fdesc = to_st_fdma_desc(vdesc); in st_fdma_xfer_desc()
84 nbytes = fchan->fdesc->node[0].desc->nbytes; in st_fdma_xfer_desc()
85 cmd = FDMA_CMD_START(fchan->vchan.chan.chan_id); in st_fdma_xfer_desc()
86 ch_cmd = fchan->fdesc->node[0].pdesc | FDMA_CH_CMD_STA_START; in st_fdma_xfer_desc()
89 fnode_write(fchan, nbytes, FDMA_CNTN_OFST); in st_fdma_xfer_desc()
90 fchan_write(fchan, ch_cmd, FDMA_CH_CMD_OFST); in st_fdma_xfer_desc()
92 fchan->fdev->slim_rproc->peri + FDMA_CMD_SET_OFST); in st_fdma_xfer_desc()
94 dev_dbg(fchan->fdev->dev, "start chan:%d\n", fchan->vchan.chan.chan_id); in st_fdma_xfer_desc()
97 static void st_fdma_ch_sta_update(struct st_fdma_chan *fchan, in st_fdma_ch_sta_update() argument
101 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_ch_sta_update()
102 struct st_fdma_dev *fdev = fchan->fdev; in st_fdma_ch_sta_update()
104 ch_sta = fchan_read(fchan, FDMA_CH_CMD_OFST); in st_fdma_ch_sta_update()
110 fchan->status = DMA_ERROR; in st_fdma_ch_sta_update()
116 fchan->status = DMA_PAUSED; in st_fdma_ch_sta_update()
120 fchan->status = DMA_IN_PROGRESS; in st_fdma_ch_sta_update()
129 struct st_fdma_chan *fchan = &fdev->chans[0]; in st_fdma_irq_handler() local
135 for (; int_sta != 0 ; int_sta >>= 2, fchan++) { in st_fdma_irq_handler()
139 spin_lock(&fchan->vchan.lock); in st_fdma_irq_handler()
140 st_fdma_ch_sta_update(fchan, int_sta); in st_fdma_irq_handler()
142 if (fchan->fdesc) { in st_fdma_irq_handler()
143 if (!fchan->fdesc->iscyclic) { in st_fdma_irq_handler()
144 list_del(&fchan->fdesc->vdesc.node); in st_fdma_irq_handler()
145 vchan_cookie_complete(&fchan->fdesc->vdesc); in st_fdma_irq_handler()
146 fchan->fdesc = NULL; in st_fdma_irq_handler()
147 fchan->status = DMA_COMPLETE; in st_fdma_irq_handler()
149 vchan_cyclic_callback(&fchan->fdesc->vdesc); in st_fdma_irq_handler()
153 if (!fchan->fdesc) in st_fdma_irq_handler()
154 st_fdma_xfer_desc(fchan); in st_fdma_irq_handler()
157 spin_unlock(&fchan->vchan.lock); in st_fdma_irq_handler()
171 struct st_fdma_chan *fchan; in st_fdma_of_xlate() local
190 fchan = to_st_fdma_chan(chan); in st_fdma_of_xlate()
192 fchan->cfg.of_node = dma_spec->np; in st_fdma_of_xlate()
193 fchan->cfg.req_line = dma_spec->args[0]; in st_fdma_of_xlate()
194 fchan->cfg.req_ctrl = 0; in st_fdma_of_xlate()
195 fchan->cfg.type = ST_FDMA_TYPE_FREE_RUN; in st_fdma_of_xlate()
198 fchan->cfg.req_ctrl = dma_spec->args[1] in st_fdma_of_xlate()
202 fchan->cfg.type = dma_spec->args[2]; in st_fdma_of_xlate()
204 if (fchan->cfg.type == ST_FDMA_TYPE_FREE_RUN) { in st_fdma_of_xlate()
205 fchan->dreq_line = 0; in st_fdma_of_xlate()
207 fchan->dreq_line = st_fdma_dreq_get(fchan); in st_fdma_of_xlate()
208 if (IS_ERR_VALUE(fchan->dreq_line)) { in st_fdma_of_xlate()
209 chan = ERR_PTR(fchan->dreq_line); in st_fdma_of_xlate()
215 fchan->cfg.req_line, fchan->cfg.type, fchan->cfg.req_ctrl); in st_fdma_of_xlate()
232 dma_pool_free(fdesc->fchan->node_pool, fdesc->node[i].desc, in st_fdma_free_desc()
237 static struct st_fdma_desc *st_fdma_alloc_desc(struct st_fdma_chan *fchan, in st_fdma_alloc_desc() argument
247 fdesc->fchan = fchan; in st_fdma_alloc_desc()
250 fdesc->node[i].desc = dma_pool_alloc(fchan->node_pool, in st_fdma_alloc_desc()
259 dma_pool_free(fchan->node_pool, fdesc->node[i].desc, in st_fdma_alloc_desc()
267 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_alloc_chan_res() local
270 fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device), in st_fdma_alloc_chan_res()
271 fchan->fdev->dev, in st_fdma_alloc_chan_res()
276 if (!fchan->node_pool) { in st_fdma_alloc_chan_res()
277 dev_err(fchan->fdev->dev, "unable to allocate desc pool\n"); in st_fdma_alloc_chan_res()
281 dev_dbg(fchan->fdev->dev, "alloc ch_id:%d type:%d\n", in st_fdma_alloc_chan_res()
282 fchan->vchan.chan.chan_id, fchan->cfg.type); in st_fdma_alloc_chan_res()
289 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_free_chan_res() local
290 struct rproc *rproc = fchan->fdev->slim_rproc->rproc; in st_fdma_free_chan_res()
293 dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n", in st_fdma_free_chan_res()
294 __func__, fchan->vchan.chan.chan_id); in st_fdma_free_chan_res()
296 if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN) in st_fdma_free_chan_res()
297 st_fdma_dreq_put(fchan); in st_fdma_free_chan_res()
299 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_free_chan_res()
300 fchan->fdesc = NULL; in st_fdma_free_chan_res()
301 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_free_chan_res()
303 dma_pool_destroy(fchan->node_pool); in st_fdma_free_chan_res()
304 fchan->node_pool = NULL; in st_fdma_free_chan_res()
305 memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg)); in st_fdma_free_chan_res()
314 struct st_fdma_chan *fchan; in st_fdma_prep_dma_memcpy() local
321 fchan = to_st_fdma_chan(chan); in st_fdma_prep_dma_memcpy()
324 fdesc = st_fdma_alloc_desc(fchan, 1); in st_fdma_prep_dma_memcpy()
326 dev_err(fchan->fdev->dev, "no memory for desc\n"); in st_fdma_prep_dma_memcpy()
343 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); in st_fdma_prep_dma_memcpy()
346 static int config_reqctrl(struct st_fdma_chan *fchan, in config_reqctrl() argument
351 int ch_id = fchan->vchan.chan.chan_id; in config_reqctrl()
352 struct st_fdma_dev *fdev = fchan->fdev; in config_reqctrl()
357 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_WNR; in config_reqctrl()
358 maxburst = fchan->scfg.src_maxburst; in config_reqctrl()
359 width = fchan->scfg.src_addr_width; in config_reqctrl()
360 addr = fchan->scfg.src_addr; in config_reqctrl()
364 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_WNR; in config_reqctrl()
365 maxburst = fchan->scfg.dst_maxburst; in config_reqctrl()
366 width = fchan->scfg.dst_addr_width; in config_reqctrl()
367 addr = fchan->scfg.dst_addr; in config_reqctrl()
374 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_OPCODE_MASK; in config_reqctrl()
379 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST1; in config_reqctrl()
383 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST2; in config_reqctrl()
387 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST4; in config_reqctrl()
391 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST8; in config_reqctrl()
398 fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_NUM_OPS_MASK; in config_reqctrl()
399 fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_NUM_OPS(maxburst-1); in config_reqctrl()
400 dreq_write(fchan, fchan->cfg.req_ctrl, FDMA_REQ_CTRL_OFST); in config_reqctrl()
402 fchan->cfg.dev_addr = addr; in config_reqctrl()
403 fchan->cfg.dir = direction; in config_reqctrl()
406 ch_id, addr, fchan->cfg.req_ctrl); in config_reqctrl()
412 struct st_fdma_chan *fchan, in fill_hw_node() argument
418 hw_node->daddr = fchan->cfg.dev_addr; in fill_hw_node()
422 hw_node->saddr = fchan->cfg.dev_addr; in fill_hw_node()
432 struct st_fdma_chan *fchan; in st_fdma_prep_common() local
437 fchan = to_st_fdma_chan(chan); in st_fdma_prep_common()
440 dev_err(fchan->fdev->dev, "bad direction?\n"); in st_fdma_prep_common()
444 return fchan; in st_fdma_prep_common()
452 struct st_fdma_chan *fchan; in st_fdma_prep_dma_cyclic() local
456 fchan = st_fdma_prep_common(chan, len, direction); in st_fdma_prep_dma_cyclic()
457 if (!fchan) in st_fdma_prep_dma_cyclic()
463 if (config_reqctrl(fchan, direction)) { in st_fdma_prep_dma_cyclic()
464 dev_err(fchan->fdev->dev, "bad width or direction\n"); in st_fdma_prep_dma_cyclic()
470 dev_err(fchan->fdev->dev, "len is not multiple of period\n"); in st_fdma_prep_dma_cyclic()
475 fdesc = st_fdma_alloc_desc(fchan, sg_len); in st_fdma_prep_dma_cyclic()
477 dev_err(fchan->fdev->dev, "no memory for desc\n"); in st_fdma_prep_dma_cyclic()
489 FDMA_NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line); in st_fdma_prep_dma_cyclic()
492 fill_hw_node(hw_node, fchan, direction); in st_fdma_prep_dma_cyclic()
503 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); in st_fdma_prep_dma_cyclic()
511 struct st_fdma_chan *fchan; in st_fdma_prep_slave_sg() local
517 fchan = st_fdma_prep_common(chan, sg_len, direction); in st_fdma_prep_slave_sg()
518 if (!fchan) in st_fdma_prep_slave_sg()
524 fdesc = st_fdma_alloc_desc(fchan, sg_len); in st_fdma_prep_slave_sg()
526 dev_err(fchan->fdev->dev, "no memory for desc\n"); in st_fdma_prep_slave_sg()
536 hw_node->control = FDMA_NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line); in st_fdma_prep_slave_sg()
538 fill_hw_node(hw_node, fchan, direction); in st_fdma_prep_slave_sg()
552 return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); in st_fdma_prep_slave_sg()
555 static size_t st_fdma_desc_residue(struct st_fdma_chan *fchan, in st_fdma_desc_residue() argument
559 struct st_fdma_desc *fdesc = fchan->fdesc; in st_fdma_desc_residue()
565 cur_addr = fchan_read(fchan, FDMA_CH_CMD_OFST); in st_fdma_desc_residue()
569 for (i = fchan->fdesc->n_nodes - 1 ; i >= 0; i--) { in st_fdma_desc_residue()
571 residue += fnode_read(fchan, FDMA_CNTN_OFST); in st_fdma_desc_residue()
584 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_tx_status() local
593 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_tx_status()
594 vd = vchan_find_desc(&fchan->vchan, cookie); in st_fdma_tx_status()
595 if (fchan->fdesc && cookie == fchan->fdesc->vdesc.tx.cookie) in st_fdma_tx_status()
596 txstate->residue = st_fdma_desc_residue(fchan, vd, true); in st_fdma_tx_status()
598 txstate->residue = st_fdma_desc_residue(fchan, vd, false); in st_fdma_tx_status()
602 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_tx_status()
609 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_issue_pending() local
612 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_issue_pending()
614 if (vchan_issue_pending(&fchan->vchan) && !fchan->fdesc) in st_fdma_issue_pending()
615 st_fdma_xfer_desc(fchan); in st_fdma_issue_pending()
617 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_issue_pending()
623 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_pause() local
624 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_pause()
627 dev_dbg(fchan->fdev->dev, "pause chan:%d\n", ch_id); in st_fdma_pause()
629 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_pause()
630 if (fchan->fdesc) in st_fdma_pause()
631 fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST); in st_fdma_pause()
632 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_pause()
641 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_resume() local
642 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_resume()
644 dev_dbg(fchan->fdev->dev, "resume chan:%d\n", ch_id); in st_fdma_resume()
646 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_resume()
647 if (fchan->fdesc) { in st_fdma_resume()
648 val = fchan_read(fchan, FDMA_CH_CMD_OFST); in st_fdma_resume()
650 fchan_write(fchan, val, FDMA_CH_CMD_OFST); in st_fdma_resume()
652 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_resume()
661 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_terminate_all() local
662 int ch_id = fchan->vchan.chan.chan_id; in st_fdma_terminate_all()
665 dev_dbg(fchan->fdev->dev, "terminate chan:%d\n", ch_id); in st_fdma_terminate_all()
667 spin_lock_irqsave(&fchan->vchan.lock, flags); in st_fdma_terminate_all()
668 fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST); in st_fdma_terminate_all()
669 fchan->fdesc = NULL; in st_fdma_terminate_all()
670 vchan_get_all_descriptors(&fchan->vchan, &head); in st_fdma_terminate_all()
671 spin_unlock_irqrestore(&fchan->vchan.lock, flags); in st_fdma_terminate_all()
672 vchan_dma_desc_free_list(&fchan->vchan, &head); in st_fdma_terminate_all()
680 struct st_fdma_chan *fchan = to_st_fdma_chan(chan); in st_fdma_slave_config() local
682 memcpy(&fchan->scfg, slave_cfg, sizeof(fchan->scfg)); in st_fdma_slave_config()
729 struct st_fdma_chan *fchan; in st_fdma_free() local
733 fchan = &fdev->chans[i]; in st_fdma_free()
734 list_del(&fchan->vchan.chan.device_node); in st_fdma_free()
735 tasklet_kill(&fchan->vchan.task); in st_fdma_free()
795 struct st_fdma_chan *fchan = &fdev->chans[i]; in st_fdma_probe() local
797 fchan->fdev = fdev; in st_fdma_probe()
798 fchan->vchan.desc_free = st_fdma_free_desc; in st_fdma_probe()
799 vchan_init(&fchan->vchan, &fdev->dma_device); in st_fdma_probe()