Lines Matching refs:tdmac
137 struct mmp_tdma_chan *tdmac[TDMA_CHANNEL_NUM]; member
142 static void mmp_tdma_chan_set_desc(struct mmp_tdma_chan *tdmac, dma_addr_t phys) in mmp_tdma_chan_set_desc() argument
144 writel(phys, tdmac->reg_base + TDNDPR); in mmp_tdma_chan_set_desc()
145 writel(readl(tdmac->reg_base + TDCR) | TDCR_FETCHND, in mmp_tdma_chan_set_desc()
146 tdmac->reg_base + TDCR); in mmp_tdma_chan_set_desc()
149 static void mmp_tdma_enable_irq(struct mmp_tdma_chan *tdmac, bool enable) in mmp_tdma_enable_irq() argument
152 writel(TDIMR_COMP, tdmac->reg_base + TDIMR); in mmp_tdma_enable_irq()
154 writel(0, tdmac->reg_base + TDIMR); in mmp_tdma_enable_irq()
157 static void mmp_tdma_enable_chan(struct mmp_tdma_chan *tdmac) in mmp_tdma_enable_chan() argument
160 writel(readl(tdmac->reg_base + TDCR) | TDCR_CHANEN, in mmp_tdma_enable_chan()
161 tdmac->reg_base + TDCR); in mmp_tdma_enable_chan()
162 tdmac->status = DMA_IN_PROGRESS; in mmp_tdma_enable_chan()
167 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_disable_chan() local
170 tdcr = readl(tdmac->reg_base + TDCR); in mmp_tdma_disable_chan()
173 writel(tdcr, tdmac->reg_base + TDCR); in mmp_tdma_disable_chan()
175 tdmac->status = DMA_COMPLETE; in mmp_tdma_disable_chan()
182 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_resume_chan() local
184 writel(readl(tdmac->reg_base + TDCR) | TDCR_CHANEN, in mmp_tdma_resume_chan()
185 tdmac->reg_base + TDCR); in mmp_tdma_resume_chan()
186 tdmac->status = DMA_IN_PROGRESS; in mmp_tdma_resume_chan()
193 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_pause_chan() local
195 writel(readl(tdmac->reg_base + TDCR) & ~TDCR_CHANEN, in mmp_tdma_pause_chan()
196 tdmac->reg_base + TDCR); in mmp_tdma_pause_chan()
197 tdmac->status = DMA_PAUSED; in mmp_tdma_pause_chan()
204 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_config_chan() local
209 if (tdmac->dir == DMA_MEM_TO_DEV) in mmp_tdma_config_chan()
211 else if (tdmac->dir == DMA_DEV_TO_MEM) in mmp_tdma_config_chan()
214 if (tdmac->type == MMP_AUD_TDMA) { in mmp_tdma_config_chan()
217 switch (tdmac->burst_sz) { in mmp_tdma_config_chan()
237 dev_err(tdmac->dev, "mmp_tdma: unknown burst size.\n"); in mmp_tdma_config_chan()
241 switch (tdmac->buswidth) { in mmp_tdma_config_chan()
252 dev_err(tdmac->dev, "mmp_tdma: unknown bus size.\n"); in mmp_tdma_config_chan()
255 } else if (tdmac->type == PXA910_SQU) { in mmp_tdma_config_chan()
258 switch (tdmac->burst_sz) { in mmp_tdma_config_chan()
278 dev_err(tdmac->dev, "mmp_tdma: unknown burst size.\n"); in mmp_tdma_config_chan()
283 writel(tdcr, tdmac->reg_base + TDCR); in mmp_tdma_config_chan()
287 static int mmp_tdma_clear_chan_irq(struct mmp_tdma_chan *tdmac) in mmp_tdma_clear_chan_irq() argument
289 u32 reg = readl(tdmac->reg_base + TDISR); in mmp_tdma_clear_chan_irq()
294 writel(reg, tdmac->reg_base + TDISR); in mmp_tdma_clear_chan_irq()
301 static size_t mmp_tdma_get_pos(struct mmp_tdma_chan *tdmac) in mmp_tdma_get_pos() argument
305 if (tdmac->idx == 0) { in mmp_tdma_get_pos()
306 reg = __raw_readl(tdmac->reg_base + TDSAR); in mmp_tdma_get_pos()
307 reg -= tdmac->desc_arr[0].src_addr; in mmp_tdma_get_pos()
308 } else if (tdmac->idx == 1) { in mmp_tdma_get_pos()
309 reg = __raw_readl(tdmac->reg_base + TDDAR); in mmp_tdma_get_pos()
310 reg -= tdmac->desc_arr[0].dst_addr; in mmp_tdma_get_pos()
319 struct mmp_tdma_chan *tdmac = dev_id; in mmp_tdma_chan_handler() local
321 if (mmp_tdma_clear_chan_irq(tdmac) == 0) { in mmp_tdma_chan_handler()
322 tasklet_schedule(&tdmac->tasklet); in mmp_tdma_chan_handler()
335 struct mmp_tdma_chan *tdmac = tdev->tdmac[i]; in mmp_tdma_int_handler() local
337 ret = mmp_tdma_chan_handler(irq, tdmac); in mmp_tdma_int_handler()
350 struct mmp_tdma_chan *tdmac = (struct mmp_tdma_chan *)data; in dma_do_tasklet() local
352 if (tdmac->desc.callback) in dma_do_tasklet()
353 tdmac->desc.callback(tdmac->desc.callback_param); in dma_do_tasklet()
357 static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac) in mmp_tdma_free_descriptor() argument
360 int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc); in mmp_tdma_free_descriptor()
362 gpool = tdmac->pool; in mmp_tdma_free_descriptor()
363 if (gpool && tdmac->desc_arr) in mmp_tdma_free_descriptor()
364 gen_pool_free(gpool, (unsigned long)tdmac->desc_arr, in mmp_tdma_free_descriptor()
366 tdmac->desc_arr = NULL; in mmp_tdma_free_descriptor()
373 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(tx->chan); in mmp_tdma_tx_submit() local
375 mmp_tdma_chan_set_desc(tdmac, tdmac->desc_arr_phys); in mmp_tdma_tx_submit()
382 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_alloc_chan_resources() local
385 dma_async_tx_descriptor_init(&tdmac->desc, chan); in mmp_tdma_alloc_chan_resources()
386 tdmac->desc.tx_submit = mmp_tdma_tx_submit; in mmp_tdma_alloc_chan_resources()
388 if (tdmac->irq) { in mmp_tdma_alloc_chan_resources()
389 ret = devm_request_irq(tdmac->dev, tdmac->irq, in mmp_tdma_alloc_chan_resources()
390 mmp_tdma_chan_handler, 0, "tdma", tdmac); in mmp_tdma_alloc_chan_resources()
399 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_free_chan_resources() local
401 if (tdmac->irq) in mmp_tdma_free_chan_resources()
402 devm_free_irq(tdmac->dev, tdmac->irq, tdmac); in mmp_tdma_free_chan_resources()
403 mmp_tdma_free_descriptor(tdmac); in mmp_tdma_free_chan_resources()
407 struct mmp_tdma_desc *mmp_tdma_alloc_descriptor(struct mmp_tdma_chan *tdmac) in mmp_tdma_alloc_descriptor() argument
410 int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc); in mmp_tdma_alloc_descriptor()
412 gpool = tdmac->pool; in mmp_tdma_alloc_descriptor()
416 tdmac->desc_arr = gen_pool_dma_alloc(gpool, size, &tdmac->desc_arr_phys); in mmp_tdma_alloc_descriptor()
418 return tdmac->desc_arr; in mmp_tdma_alloc_descriptor()
426 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_prep_dma_cyclic() local
431 if (tdmac->status != DMA_COMPLETE) in mmp_tdma_prep_dma_cyclic()
435 dev_err(tdmac->dev, in mmp_tdma_prep_dma_cyclic()
441 tdmac->status = DMA_IN_PROGRESS; in mmp_tdma_prep_dma_cyclic()
442 tdmac->desc_num = num_periods; in mmp_tdma_prep_dma_cyclic()
443 desc = mmp_tdma_alloc_descriptor(tdmac); in mmp_tdma_prep_dma_cyclic()
448 desc = &tdmac->desc_arr[i]; in mmp_tdma_prep_dma_cyclic()
451 desc->nxt_desc = tdmac->desc_arr_phys; in mmp_tdma_prep_dma_cyclic()
453 desc->nxt_desc = tdmac->desc_arr_phys + in mmp_tdma_prep_dma_cyclic()
458 desc->dst_addr = tdmac->dev_addr; in mmp_tdma_prep_dma_cyclic()
460 desc->src_addr = tdmac->dev_addr; in mmp_tdma_prep_dma_cyclic()
471 mmp_tdma_enable_irq(tdmac, true); in mmp_tdma_prep_dma_cyclic()
473 tdmac->buf_len = buf_len; in mmp_tdma_prep_dma_cyclic()
474 tdmac->period_len = period_len; in mmp_tdma_prep_dma_cyclic()
475 tdmac->pos = 0; in mmp_tdma_prep_dma_cyclic()
477 return &tdmac->desc; in mmp_tdma_prep_dma_cyclic()
480 tdmac->status = DMA_ERROR; in mmp_tdma_prep_dma_cyclic()
486 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_terminate_all() local
490 mmp_tdma_enable_irq(tdmac, false); in mmp_tdma_terminate_all()
498 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_config() local
501 tdmac->dev_addr = dmaengine_cfg->src_addr; in mmp_tdma_config()
502 tdmac->burst_sz = dmaengine_cfg->src_maxburst; in mmp_tdma_config()
503 tdmac->buswidth = dmaengine_cfg->src_addr_width; in mmp_tdma_config()
505 tdmac->dev_addr = dmaengine_cfg->dst_addr; in mmp_tdma_config()
506 tdmac->burst_sz = dmaengine_cfg->dst_maxburst; in mmp_tdma_config()
507 tdmac->buswidth = dmaengine_cfg->dst_addr_width; in mmp_tdma_config()
509 tdmac->dir = dmaengine_cfg->direction; in mmp_tdma_config()
517 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_tx_status() local
519 tdmac->pos = mmp_tdma_get_pos(tdmac); in mmp_tdma_tx_status()
521 tdmac->buf_len - tdmac->pos); in mmp_tdma_tx_status()
523 return tdmac->status; in mmp_tdma_tx_status()
528 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_issue_pending() local
530 mmp_tdma_enable_chan(tdmac); in mmp_tdma_issue_pending()
545 struct mmp_tdma_chan *tdmac; in mmp_tdma_chan_init() local
553 tdmac = devm_kzalloc(tdev->dev, sizeof(*tdmac), GFP_KERNEL); in mmp_tdma_chan_init()
554 if (!tdmac) { in mmp_tdma_chan_init()
559 tdmac->irq = irq; in mmp_tdma_chan_init()
560 tdmac->dev = tdev->dev; in mmp_tdma_chan_init()
561 tdmac->chan.device = &tdev->device; in mmp_tdma_chan_init()
562 tdmac->idx = idx; in mmp_tdma_chan_init()
563 tdmac->type = type; in mmp_tdma_chan_init()
564 tdmac->reg_base = tdev->base + idx * 4; in mmp_tdma_chan_init()
565 tdmac->pool = pool; in mmp_tdma_chan_init()
566 tdmac->status = DMA_COMPLETE; in mmp_tdma_chan_init()
567 tdev->tdmac[tdmac->idx] = tdmac; in mmp_tdma_chan_init()
568 tasklet_init(&tdmac->tasklet, dma_do_tasklet, (unsigned long)tdmac); in mmp_tdma_chan_init()
571 list_add_tail(&tdmac->chan.device_node, in mmp_tdma_chan_init()
584 struct mmp_tdma_chan *tdmac = to_mmp_tdma_chan(chan); in mmp_tdma_filter_fn() local
585 struct dma_device *pdma_device = tdmac->chan.device; in mmp_tdma_filter_fn()