fchan 31 drivers/dma/st_fdma.c static int st_fdma_dreq_get(struct st_fdma_chan *fchan) fchan 33 drivers/dma/st_fdma.c struct st_fdma_dev *fdev = fchan->fdev; fchan 34 drivers/dma/st_fdma.c u32 req_line_cfg = fchan->cfg.req_line; fchan 65 drivers/dma/st_fdma.c static void st_fdma_dreq_put(struct st_fdma_chan *fchan) fchan 67 drivers/dma/st_fdma.c struct st_fdma_dev *fdev = fchan->fdev; fchan 69 drivers/dma/st_fdma.c dev_dbg(fdev->dev, "put dreq_line:%#x\n", fchan->dreq_line); fchan 70 drivers/dma/st_fdma.c clear_bit(fchan->dreq_line, &fdev->dreq_mask); fchan 73 drivers/dma/st_fdma.c static void st_fdma_xfer_desc(struct st_fdma_chan *fchan) fchan 78 drivers/dma/st_fdma.c vdesc = vchan_next_desc(&fchan->vchan); fchan 82 drivers/dma/st_fdma.c fchan->fdesc = to_st_fdma_desc(vdesc); fchan 83 drivers/dma/st_fdma.c nbytes = fchan->fdesc->node[0].desc->nbytes; fchan 84 drivers/dma/st_fdma.c cmd = FDMA_CMD_START(fchan->vchan.chan.chan_id); fchan 85 drivers/dma/st_fdma.c ch_cmd = fchan->fdesc->node[0].pdesc | FDMA_CH_CMD_STA_START; fchan 88 drivers/dma/st_fdma.c fnode_write(fchan, nbytes, FDMA_CNTN_OFST); fchan 89 drivers/dma/st_fdma.c fchan_write(fchan, ch_cmd, FDMA_CH_CMD_OFST); fchan 91 drivers/dma/st_fdma.c fchan->fdev->slim_rproc->peri + FDMA_CMD_SET_OFST); fchan 93 drivers/dma/st_fdma.c dev_dbg(fchan->fdev->dev, "start chan:%d\n", fchan->vchan.chan.chan_id); fchan 96 drivers/dma/st_fdma.c static void st_fdma_ch_sta_update(struct st_fdma_chan *fchan, fchan 100 drivers/dma/st_fdma.c int ch_id = fchan->vchan.chan.chan_id; fchan 101 drivers/dma/st_fdma.c struct st_fdma_dev *fdev = fchan->fdev; fchan 103 drivers/dma/st_fdma.c ch_sta = fchan_read(fchan, FDMA_CH_CMD_OFST); fchan 109 drivers/dma/st_fdma.c fchan->status = DMA_ERROR; fchan 115 drivers/dma/st_fdma.c fchan->status = DMA_PAUSED; fchan 119 drivers/dma/st_fdma.c fchan->status = DMA_IN_PROGRESS; fchan 128 drivers/dma/st_fdma.c struct st_fdma_chan *fchan = &fdev->chans[0]; fchan 134 drivers/dma/st_fdma.c for (; int_sta != 0 ; int_sta >>= 2, fchan++) { fchan 138 drivers/dma/st_fdma.c spin_lock(&fchan->vchan.lock); fchan 139 drivers/dma/st_fdma.c st_fdma_ch_sta_update(fchan, int_sta); fchan 141 drivers/dma/st_fdma.c if (fchan->fdesc) { fchan 142 drivers/dma/st_fdma.c if (!fchan->fdesc->iscyclic) { fchan 143 drivers/dma/st_fdma.c list_del(&fchan->fdesc->vdesc.node); fchan 144 drivers/dma/st_fdma.c vchan_cookie_complete(&fchan->fdesc->vdesc); fchan 145 drivers/dma/st_fdma.c fchan->fdesc = NULL; fchan 146 drivers/dma/st_fdma.c fchan->status = DMA_COMPLETE; fchan 148 drivers/dma/st_fdma.c vchan_cyclic_callback(&fchan->fdesc->vdesc); fchan 152 drivers/dma/st_fdma.c if (!fchan->fdesc) fchan 153 drivers/dma/st_fdma.c st_fdma_xfer_desc(fchan); fchan 156 drivers/dma/st_fdma.c spin_unlock(&fchan->vchan.lock); fchan 170 drivers/dma/st_fdma.c struct st_fdma_chan *fchan; fchan 189 drivers/dma/st_fdma.c fchan = to_st_fdma_chan(chan); fchan 191 drivers/dma/st_fdma.c fchan->cfg.of_node = dma_spec->np; fchan 192 drivers/dma/st_fdma.c fchan->cfg.req_line = dma_spec->args[0]; fchan 193 drivers/dma/st_fdma.c fchan->cfg.req_ctrl = 0; fchan 194 drivers/dma/st_fdma.c fchan->cfg.type = ST_FDMA_TYPE_FREE_RUN; fchan 197 drivers/dma/st_fdma.c fchan->cfg.req_ctrl = dma_spec->args[1] fchan 201 drivers/dma/st_fdma.c fchan->cfg.type = dma_spec->args[2]; fchan 203 drivers/dma/st_fdma.c if (fchan->cfg.type == ST_FDMA_TYPE_FREE_RUN) { fchan 204 drivers/dma/st_fdma.c fchan->dreq_line = 0; fchan 206 drivers/dma/st_fdma.c fchan->dreq_line = st_fdma_dreq_get(fchan); fchan 207 drivers/dma/st_fdma.c if (IS_ERR_VALUE(fchan->dreq_line)) { fchan 208 drivers/dma/st_fdma.c chan = ERR_PTR(fchan->dreq_line); fchan 214 drivers/dma/st_fdma.c fchan->cfg.req_line, fchan->cfg.type, fchan->cfg.req_ctrl); fchan 231 drivers/dma/st_fdma.c dma_pool_free(fdesc->fchan->node_pool, fdesc->node[i].desc, fchan 236 drivers/dma/st_fdma.c static struct st_fdma_desc *st_fdma_alloc_desc(struct st_fdma_chan *fchan, fchan 246 drivers/dma/st_fdma.c fdesc->fchan = fchan; fchan 249 drivers/dma/st_fdma.c fdesc->node[i].desc = dma_pool_alloc(fchan->node_pool, fchan 258 drivers/dma/st_fdma.c dma_pool_free(fchan->node_pool, fdesc->node[i].desc, fchan 266 drivers/dma/st_fdma.c struct st_fdma_chan *fchan = to_st_fdma_chan(chan); fchan 269 drivers/dma/st_fdma.c fchan->node_pool = dma_pool_create(dev_name(&chan->dev->device), fchan 270 drivers/dma/st_fdma.c fchan->fdev->dev, fchan 275 drivers/dma/st_fdma.c if (!fchan->node_pool) { fchan 276 drivers/dma/st_fdma.c dev_err(fchan->fdev->dev, "unable to allocate desc pool\n"); fchan 280 drivers/dma/st_fdma.c dev_dbg(fchan->fdev->dev, "alloc ch_id:%d type:%d\n", fchan 281 drivers/dma/st_fdma.c fchan->vchan.chan.chan_id, fchan->cfg.type); fchan 288 drivers/dma/st_fdma.c struct st_fdma_chan *fchan = to_st_fdma_chan(chan); fchan 289 drivers/dma/st_fdma.c struct rproc *rproc = fchan->fdev->slim_rproc->rproc; fchan 292 drivers/dma/st_fdma.c dev_dbg(fchan->fdev->dev, "%s: freeing chan:%d\n", fchan 293 drivers/dma/st_fdma.c __func__, fchan->vchan.chan.chan_id); fchan 295 drivers/dma/st_fdma.c if (fchan->cfg.type != ST_FDMA_TYPE_FREE_RUN) fchan 296 drivers/dma/st_fdma.c st_fdma_dreq_put(fchan); fchan 298 drivers/dma/st_fdma.c spin_lock_irqsave(&fchan->vchan.lock, flags); fchan 299 drivers/dma/st_fdma.c fchan->fdesc = NULL; fchan 300 drivers/dma/st_fdma.c spin_unlock_irqrestore(&fchan->vchan.lock, flags); fchan 302 drivers/dma/st_fdma.c dma_pool_destroy(fchan->node_pool); fchan 303 drivers/dma/st_fdma.c fchan->node_pool = NULL; fchan 304 drivers/dma/st_fdma.c memset(&fchan->cfg, 0, sizeof(struct st_fdma_cfg)); fchan 313 drivers/dma/st_fdma.c struct st_fdma_chan *fchan; fchan 320 drivers/dma/st_fdma.c fchan = to_st_fdma_chan(chan); fchan 323 drivers/dma/st_fdma.c fdesc = st_fdma_alloc_desc(fchan, 1); fchan 325 drivers/dma/st_fdma.c dev_err(fchan->fdev->dev, "no memory for desc\n"); fchan 342 drivers/dma/st_fdma.c return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); fchan 345 drivers/dma/st_fdma.c static int config_reqctrl(struct st_fdma_chan *fchan, fchan 350 drivers/dma/st_fdma.c int ch_id = fchan->vchan.chan.chan_id; fchan 351 drivers/dma/st_fdma.c struct st_fdma_dev *fdev = fchan->fdev; fchan 356 drivers/dma/st_fdma.c fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_WNR; fchan 357 drivers/dma/st_fdma.c maxburst = fchan->scfg.src_maxburst; fchan 358 drivers/dma/st_fdma.c width = fchan->scfg.src_addr_width; fchan 359 drivers/dma/st_fdma.c addr = fchan->scfg.src_addr; fchan 363 drivers/dma/st_fdma.c fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_WNR; fchan 364 drivers/dma/st_fdma.c maxburst = fchan->scfg.dst_maxburst; fchan 365 drivers/dma/st_fdma.c width = fchan->scfg.dst_addr_width; fchan 366 drivers/dma/st_fdma.c addr = fchan->scfg.dst_addr; fchan 373 drivers/dma/st_fdma.c fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_OPCODE_MASK; fchan 378 drivers/dma/st_fdma.c fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST1; fchan 382 drivers/dma/st_fdma.c fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST2; fchan 386 drivers/dma/st_fdma.c fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST4; fchan 390 drivers/dma/st_fdma.c fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_OPCODE_LD_ST8; fchan 397 drivers/dma/st_fdma.c fchan->cfg.req_ctrl &= ~FDMA_REQ_CTRL_NUM_OPS_MASK; fchan 398 drivers/dma/st_fdma.c fchan->cfg.req_ctrl |= FDMA_REQ_CTRL_NUM_OPS(maxburst-1); fchan 399 drivers/dma/st_fdma.c dreq_write(fchan, fchan->cfg.req_ctrl, FDMA_REQ_CTRL_OFST); fchan 401 drivers/dma/st_fdma.c fchan->cfg.dev_addr = addr; fchan 402 drivers/dma/st_fdma.c fchan->cfg.dir = direction; fchan 405 drivers/dma/st_fdma.c ch_id, addr, fchan->cfg.req_ctrl); fchan 411 drivers/dma/st_fdma.c struct st_fdma_chan *fchan, fchan 417 drivers/dma/st_fdma.c hw_node->daddr = fchan->cfg.dev_addr; fchan 421 drivers/dma/st_fdma.c hw_node->saddr = fchan->cfg.dev_addr; fchan 431 drivers/dma/st_fdma.c struct st_fdma_chan *fchan; fchan 436 drivers/dma/st_fdma.c fchan = to_st_fdma_chan(chan); fchan 439 drivers/dma/st_fdma.c dev_err(fchan->fdev->dev, "bad direction?\n"); fchan 443 drivers/dma/st_fdma.c return fchan; fchan 451 drivers/dma/st_fdma.c struct st_fdma_chan *fchan; fchan 455 drivers/dma/st_fdma.c fchan = st_fdma_prep_common(chan, len, direction); fchan 456 drivers/dma/st_fdma.c if (!fchan) fchan 462 drivers/dma/st_fdma.c if (config_reqctrl(fchan, direction)) { fchan 463 drivers/dma/st_fdma.c dev_err(fchan->fdev->dev, "bad width or direction\n"); fchan 469 drivers/dma/st_fdma.c dev_err(fchan->fdev->dev, "len is not multiple of period\n"); fchan 474 drivers/dma/st_fdma.c fdesc = st_fdma_alloc_desc(fchan, sg_len); fchan 476 drivers/dma/st_fdma.c dev_err(fchan->fdev->dev, "no memory for desc\n"); fchan 488 drivers/dma/st_fdma.c FDMA_NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line); fchan 491 drivers/dma/st_fdma.c fill_hw_node(hw_node, fchan, direction); fchan 502 drivers/dma/st_fdma.c return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); fchan 510 drivers/dma/st_fdma.c struct st_fdma_chan *fchan; fchan 516 drivers/dma/st_fdma.c fchan = st_fdma_prep_common(chan, sg_len, direction); fchan 517 drivers/dma/st_fdma.c if (!fchan) fchan 523 drivers/dma/st_fdma.c fdesc = st_fdma_alloc_desc(fchan, sg_len); fchan 525 drivers/dma/st_fdma.c dev_err(fchan->fdev->dev, "no memory for desc\n"); fchan 535 drivers/dma/st_fdma.c hw_node->control = FDMA_NODE_CTRL_REQ_MAP_DREQ(fchan->dreq_line); fchan 537 drivers/dma/st_fdma.c fill_hw_node(hw_node, fchan, direction); fchan 551 drivers/dma/st_fdma.c return vchan_tx_prep(&fchan->vchan, &fdesc->vdesc, flags); fchan 554 drivers/dma/st_fdma.c static size_t st_fdma_desc_residue(struct st_fdma_chan *fchan, fchan 558 drivers/dma/st_fdma.c struct st_fdma_desc *fdesc = fchan->fdesc; fchan 564 drivers/dma/st_fdma.c cur_addr = fchan_read(fchan, FDMA_CH_CMD_OFST); fchan 568 drivers/dma/st_fdma.c for (i = fchan->fdesc->n_nodes - 1 ; i >= 0; i--) { fchan 570 drivers/dma/st_fdma.c residue += fnode_read(fchan, FDMA_CNTN_OFST); fchan 583 drivers/dma/st_fdma.c struct st_fdma_chan *fchan = to_st_fdma_chan(chan); fchan 592 drivers/dma/st_fdma.c spin_lock_irqsave(&fchan->vchan.lock, flags); fchan 593 drivers/dma/st_fdma.c vd = vchan_find_desc(&fchan->vchan, cookie); fchan 594 drivers/dma/st_fdma.c if (fchan->fdesc && cookie == fchan->fdesc->vdesc.tx.cookie) fchan 595 drivers/dma/st_fdma.c txstate->residue = st_fdma_desc_residue(fchan, vd, true); fchan 597 drivers/dma/st_fdma.c txstate->residue = st_fdma_desc_residue(fchan, vd, false); fchan 601 drivers/dma/st_fdma.c spin_unlock_irqrestore(&fchan->vchan.lock, flags); fchan 608 drivers/dma/st_fdma.c struct st_fdma_chan *fchan = to_st_fdma_chan(chan); fchan 611 drivers/dma/st_fdma.c spin_lock_irqsave(&fchan->vchan.lock, flags); fchan 613 drivers/dma/st_fdma.c if (vchan_issue_pending(&fchan->vchan) && !fchan->fdesc) fchan 614 drivers/dma/st_fdma.c st_fdma_xfer_desc(fchan); fchan 616 drivers/dma/st_fdma.c spin_unlock_irqrestore(&fchan->vchan.lock, flags); fchan 622 drivers/dma/st_fdma.c struct st_fdma_chan *fchan = to_st_fdma_chan(chan); fchan 623 drivers/dma/st_fdma.c int ch_id = fchan->vchan.chan.chan_id; fchan 626 drivers/dma/st_fdma.c dev_dbg(fchan->fdev->dev, "pause chan:%d\n", ch_id); fchan 628 drivers/dma/st_fdma.c spin_lock_irqsave(&fchan->vchan.lock, flags); fchan 629 drivers/dma/st_fdma.c if (fchan->fdesc) fchan 630 drivers/dma/st_fdma.c fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST); fchan 631 drivers/dma/st_fdma.c spin_unlock_irqrestore(&fchan->vchan.lock, flags); fchan 640 drivers/dma/st_fdma.c struct st_fdma_chan *fchan = to_st_fdma_chan(chan); fchan 641 drivers/dma/st_fdma.c int ch_id = fchan->vchan.chan.chan_id; fchan 643 drivers/dma/st_fdma.c dev_dbg(fchan->fdev->dev, "resume chan:%d\n", ch_id); fchan 645 drivers/dma/st_fdma.c spin_lock_irqsave(&fchan->vchan.lock, flags); fchan 646 drivers/dma/st_fdma.c if (fchan->fdesc) { fchan 647 drivers/dma/st_fdma.c val = fchan_read(fchan, FDMA_CH_CMD_OFST); fchan 649 drivers/dma/st_fdma.c fchan_write(fchan, val, FDMA_CH_CMD_OFST); fchan 651 drivers/dma/st_fdma.c spin_unlock_irqrestore(&fchan->vchan.lock, flags); fchan 660 drivers/dma/st_fdma.c struct st_fdma_chan *fchan = to_st_fdma_chan(chan); fchan 661 drivers/dma/st_fdma.c int ch_id = fchan->vchan.chan.chan_id; fchan 664 drivers/dma/st_fdma.c dev_dbg(fchan->fdev->dev, "terminate chan:%d\n", ch_id); fchan 666 drivers/dma/st_fdma.c spin_lock_irqsave(&fchan->vchan.lock, flags); fchan 667 drivers/dma/st_fdma.c fdma_write(fchan->fdev, cmd, FDMA_CMD_SET_OFST); fchan 668 drivers/dma/st_fdma.c fchan->fdesc = NULL; fchan 669 drivers/dma/st_fdma.c vchan_get_all_descriptors(&fchan->vchan, &head); fchan 670 drivers/dma/st_fdma.c spin_unlock_irqrestore(&fchan->vchan.lock, flags); fchan 671 drivers/dma/st_fdma.c vchan_dma_desc_free_list(&fchan->vchan, &head); fchan 679 drivers/dma/st_fdma.c struct st_fdma_chan *fchan = to_st_fdma_chan(chan); fchan 681 drivers/dma/st_fdma.c memcpy(&fchan->scfg, slave_cfg, sizeof(fchan->scfg)); fchan 728 drivers/dma/st_fdma.c struct st_fdma_chan *fchan; fchan 732 drivers/dma/st_fdma.c fchan = &fdev->chans[i]; fchan 733 drivers/dma/st_fdma.c list_del(&fchan->vchan.chan.device_node); fchan 734 drivers/dma/st_fdma.c tasklet_kill(&fchan->vchan.task); fchan 794 drivers/dma/st_fdma.c struct st_fdma_chan *fchan = &fdev->chans[i]; fchan 796 drivers/dma/st_fdma.c fchan->fdev = fdev; fchan 797 drivers/dma/st_fdma.c fchan->vchan.desc_free = st_fdma_free_desc; fchan 798 drivers/dma/st_fdma.c vchan_init(&fchan->vchan, &fdev->dma_device); fchan 97 drivers/dma/st_fdma.h struct st_fdma_chan *fchan; fchan 184 drivers/dma/st_fdma.h #define fchan_read(fchan, name) \ fchan 185 drivers/dma/st_fdma.h readl((fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ fchan 186 drivers/dma/st_fdma.h + (fchan)->vchan.chan.chan_id * 0x4 \ fchan 189 drivers/dma/st_fdma.h #define fchan_write(fchan, val, name) \ fchan 190 drivers/dma/st_fdma.h writel((val), (fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ fchan 191 drivers/dma/st_fdma.h + (fchan)->vchan.chan.chan_id * 0x4 \ fchan 196 drivers/dma/st_fdma.h #define dreq_write(fchan, val, name) \ fchan 197 drivers/dma/st_fdma.h writel((val), (fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ fchan 198 drivers/dma/st_fdma.h + fchan->dreq_line * 0x04 \ fchan 206 drivers/dma/st_fdma.h #define fnode_read(fchan, name) \ fchan 207 drivers/dma/st_fdma.h readl((fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ fchan 208 drivers/dma/st_fdma.h + (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \ fchan 211 drivers/dma/st_fdma.h #define fnode_write(fchan, val, name) \ fchan 212 drivers/dma/st_fdma.h writel((val), (fchan)->fdev->slim_rproc->mem[ST_SLIM_DMEM].cpu_addr \ fchan 213 drivers/dma/st_fdma.h + (fchan)->vchan.chan.chan_id * FDMA_NODE_SZ \