Lines Matching +full:dma +full:- +full:mem

1 // SPDX-License-Identifier: GPL-2.0
3 // Renesas R-Car Audio DMAC support
43 } dma; member
52 #define rsnd_priv_to_dmac(p) ((struct rsnd_dma_ctrl *)(p)->dma)
54 #define rsnd_dma_to_dmaen(dma) (&(dma)->dma.en) argument
55 #define rsnd_dma_to_dmapp(dma) (&(dma)->dma.pp) argument
59 .name = "mem",
62 static struct rsnd_mod mem = { variable
100 struct rsnd_dma *dma = rsnd_mod_to_dma(mod); in rsnd_dmaen_stop() local
101 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); in rsnd_dmaen_stop()
103 if (dmaen->chan) in rsnd_dmaen_stop()
104 dmaengine_terminate_all(dmaen->chan); in rsnd_dmaen_stop()
113 struct rsnd_dma *dma = rsnd_mod_to_dma(mod); in rsnd_dmaen_cleanup() local
114 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); in rsnd_dmaen_cleanup()
121 if (dmaen->chan) in rsnd_dmaen_cleanup()
122 dma_release_channel(dmaen->chan); in rsnd_dmaen_cleanup()
124 dmaen->chan = NULL; in rsnd_dmaen_cleanup()
133 struct rsnd_dma *dma = rsnd_mod_to_dma(mod); in rsnd_dmaen_prepare() local
134 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); in rsnd_dmaen_prepare()
138 if (dmaen->chan) in rsnd_dmaen_prepare()
146 dmaen->chan = rsnd_dmaen_request_channel(io, in rsnd_dmaen_prepare()
147 dma->mod_from, in rsnd_dmaen_prepare()
148 dma->mod_to); in rsnd_dmaen_prepare()
149 if (IS_ERR_OR_NULL(dmaen->chan)) { in rsnd_dmaen_prepare()
150 dmaen->chan = NULL; in rsnd_dmaen_prepare()
151 dev_err(dev, "can't get dma channel\n"); in rsnd_dmaen_prepare()
152 return -EIO; in rsnd_dmaen_prepare()
162 struct rsnd_dma *dma = rsnd_mod_to_dma(mod); in rsnd_dmaen_start() local
163 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); in rsnd_dmaen_start()
164 struct snd_pcm_substream *substream = io->substream; in rsnd_dmaen_start()
173 * in case of monaural data writing or reading through Audio-DMAC in rsnd_dmaen_start()
175 * DMA Bus width need to be set equal to physical data width. in rsnd_dmaen_start()
179 int bits = snd_pcm_format_physical_width(runtime->format); in rsnd_dmaen_start()
193 return -EINVAL; in rsnd_dmaen_start()
198 cfg.src_addr = dma->src_addr; in rsnd_dmaen_start()
199 cfg.dst_addr = dma->dst_addr; in rsnd_dmaen_start()
203 dev_dbg(dev, "%s %pad -> %pad\n", in rsnd_dmaen_start()
207 ret = dmaengine_slave_config(dmaen->chan, &cfg); in rsnd_dmaen_start()
211 desc = dmaengine_prep_dma_cyclic(dmaen->chan, in rsnd_dmaen_start()
212 substream->runtime->dma_addr, in rsnd_dmaen_start()
220 return -EIO; in rsnd_dmaen_start()
223 desc->callback = rsnd_dmaen_complete; in rsnd_dmaen_start()
224 desc->callback_param = rsnd_mod_get(dma); in rsnd_dmaen_start()
226 dmaen->dma_len = snd_pcm_lib_buffer_bytes(substream); in rsnd_dmaen_start()
228 dmaen->cookie = dmaengine_submit(desc); in rsnd_dmaen_start()
229 if (dmaen->cookie < 0) { in rsnd_dmaen_start()
231 return -EIO; in rsnd_dmaen_start()
234 dma_async_issue_pending(dmaen->chan); in rsnd_dmaen_start()
259 struct rsnd_dma *dma, in rsnd_dmaen_attach() argument
269 /* Let's follow when -EPROBE_DEFER case */ in rsnd_dmaen_attach()
270 if (PTR_ERR(chan) == -EPROBE_DEFER) in rsnd_dmaen_attach()
274 * DMA failed. try to PIO mode in rsnd_dmaen_attach()
279 return -EAGAIN; in rsnd_dmaen_attach()
287 io->dmac_dev = chan->device->dev; in rsnd_dmaen_attach()
291 dmac->dmaen_num++; in rsnd_dmaen_attach()
301 struct rsnd_dma *dma = rsnd_mod_to_dma(mod); in rsnd_dmaen_pointer() local
302 struct rsnd_dmaen *dmaen = rsnd_dma_to_dmaen(dma); in rsnd_dmaen_pointer()
307 status = dmaengine_tx_status(dmaen->chan, dmaen->cookie, &state); in rsnd_dmaen_pointer()
309 if (state.residue > 0 && state.residue <= dmaen->dma_len) in rsnd_dmaen_pointer()
310 pos = dmaen->dma_len - state.residue; in rsnd_dmaen_pointer()
402 /* use non-prohibited SRS number as error */ in rsnd_dmapp_get_id()
417 #define rsnd_dmapp_addr(dmac, dma, reg) \ argument
418 (dmac->base + 0x20 + reg + \
419 (0x10 * rsnd_dma_to_dmapp(dma)->dmapp_id))
420 static void rsnd_dmapp_write(struct rsnd_dma *dma, u32 data, u32 reg) in rsnd_dmapp_write() argument
422 struct rsnd_mod *mod = rsnd_mod_get(dma); in rsnd_dmapp_write()
427 dev_dbg(dev, "w 0x%px : %08x\n", rsnd_dmapp_addr(dmac, dma, reg), data); in rsnd_dmapp_write()
429 iowrite32(data, rsnd_dmapp_addr(dmac, dma, reg)); in rsnd_dmapp_write()
432 static u32 rsnd_dmapp_read(struct rsnd_dma *dma, u32 reg) in rsnd_dmapp_read() argument
434 struct rsnd_mod *mod = rsnd_mod_get(dma); in rsnd_dmapp_read()
438 return ioread32(rsnd_dmapp_addr(dmac, dma, reg)); in rsnd_dmapp_read()
441 static void rsnd_dmapp_bset(struct rsnd_dma *dma, u32 data, u32 mask, u32 reg) in rsnd_dmapp_bset() argument
443 struct rsnd_mod *mod = rsnd_mod_get(dma); in rsnd_dmapp_bset()
446 void __iomem *addr = rsnd_dmapp_addr(dmac, dma, reg); in rsnd_dmapp_bset()
459 struct rsnd_dma *dma = rsnd_mod_to_dma(mod); in rsnd_dmapp_stop() local
462 rsnd_dmapp_bset(dma, 0, PDMACHCR_DE, PDMACHCR); in rsnd_dmapp_stop()
465 if (0 == (rsnd_dmapp_read(dma, PDMACHCR) & PDMACHCR_DE)) in rsnd_dmapp_stop()
470 return -EIO; in rsnd_dmapp_stop()
477 struct rsnd_dma *dma = rsnd_mod_to_dma(mod); in rsnd_dmapp_start() local
478 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); in rsnd_dmapp_start()
480 rsnd_dmapp_write(dma, dma->src_addr, PDMASAR); in rsnd_dmapp_start()
481 rsnd_dmapp_write(dma, dma->dst_addr, PDMADAR); in rsnd_dmapp_start()
482 rsnd_dmapp_write(dma, dmapp->chcr, PDMACHCR); in rsnd_dmapp_start()
488 struct rsnd_dma *dma, in rsnd_dmapp_attach() argument
491 struct rsnd_dmapp *dmapp = rsnd_dma_to_dmapp(dma); in rsnd_dmapp_attach()
496 dmapp->dmapp_id = dmac->dmapp_num; in rsnd_dmapp_attach()
497 dmapp->chcr = rsnd_dmapp_get_chcr(io, mod_from, mod_to) | PDMACHCR_DE; in rsnd_dmapp_attach()
499 dmac->dmapp_num++; in rsnd_dmapp_attach()
502 dmapp->dmapp_id, &dma->src_addr, &dma->dst_addr, dmapp->chcr); in rsnd_dmapp_attach()
508 .name = "audmac-pp",
520 * DMA read/write register offset
527 * ex) R-Car H2 case
534 #define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
535 #define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
537 …DMA_SSIU_I_N(addr, i, j) (addr ##_reg - 0x00441000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j)…
540 …DMA_SSIU_I_P(addr, i, j) (addr ##_reg - 0x00141000 + (0x1000 * (i)) + (((j) / 4) * 0xA000) + (((j)…
543 #define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i))
544 #define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i))
546 #define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i))
547 #define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i))
549 #define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i))
550 #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i))
607 * We can't support SSI9-4/5/6/7, because its address is in rsnd_gen2_dma_addr()
611 dev_err(dev, "This driver doesn't support SSI%d-%d, so far", in rsnd_gen2_dma_addr()
634 * gen1 uses default DMA addr in rsnd_dma_addr()
695 * [S] -*-> [E] in rsnd_dma_of_path()
696 * [S] -*-> SRC -o-> [E] in rsnd_dma_of_path()
697 * [S] -*-> SRC -> DVC -o-> [E] in rsnd_dma_of_path()
698 * [S] -*-> SRC -> CTU -> MIX -> DVC -o-> [E] in rsnd_dma_of_path()
700 * playback [S] = mem in rsnd_dma_of_path()
704 * [E] = mem in rsnd_dma_of_path()
706 * -*-> Audio DMAC in rsnd_dma_of_path()
707 * -o-> Audio DMAC peri peri in rsnd_dma_of_path()
733 * -------------+-----+-----+ in rsnd_dma_of_path()
738 *mod_from = mod[idx - 1]; in rsnd_dma_of_path()
748 rsnd_mod_name(mod[i] ? mod[i] : &mem), in rsnd_dma_of_path()
762 struct rsnd_dma *dma; in rsnd_dma_alloc() local
765 int (*attach)(struct rsnd_dai_stream *io, struct rsnd_dma *dma, in rsnd_dma_alloc()
771 * DMA failed. try to PIO mode in rsnd_dma_alloc()
777 return -EAGAIN; in rsnd_dma_alloc()
785 dma_id = dmac->dmapp_num; in rsnd_dma_alloc()
790 dma_id = dmac->dmaen_num; in rsnd_dma_alloc()
798 dma_id = dmac->dmaen_num; in rsnd_dma_alloc()
802 dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL); in rsnd_dma_alloc()
803 if (!dma) in rsnd_dma_alloc()
804 return -ENOMEM; in rsnd_dma_alloc()
806 *dma_mod = rsnd_mod_get(dma); in rsnd_dma_alloc()
813 dev_dbg(dev, "%s %s -> %s\n", in rsnd_dma_alloc()
815 rsnd_mod_name(mod_from ? mod_from : &mem), in rsnd_dma_alloc()
816 rsnd_mod_name(mod_to ? mod_to : &mem)); in rsnd_dma_alloc()
818 ret = attach(io, dma, mod_from, mod_to); in rsnd_dma_alloc()
822 dma->src_addr = rsnd_dma_addr(io, mod_from, is_play, 1); in rsnd_dma_alloc()
823 dma->dst_addr = rsnd_dma_addr(io, mod_to, is_play, 0); in rsnd_dma_alloc()
824 dma->mod_from = mod_from; in rsnd_dma_alloc()
825 dma->mod_to = mod_to; in rsnd_dma_alloc()
840 return rsnd_dai_connect(*dma_mod, io, (*dma_mod)->type); in rsnd_dma_attach()
862 dev_err(dev, "dma allocate failed\n"); in rsnd_dma_probe()
866 dmac->dmapp_num = 0; in rsnd_dma_probe()
867 dmac->base = devm_ioremap_resource(dev, res); in rsnd_dma_probe()
868 if (IS_ERR(dmac->base)) in rsnd_dma_probe()
869 return PTR_ERR(dmac->base); in rsnd_dma_probe()
871 priv->dma = dmac; in rsnd_dma_probe()
873 /* dummy mem mod for debug */ in rsnd_dma_probe()
874 return rsnd_mod_init(NULL, &mem, &mem_ops, NULL, 0, 0); in rsnd_dma_probe()