Lines Matching +full:mt6577 +full:- +full:uart +full:- +full:dma

1 // SPDX-License-Identifier: GPL-2.0
3 * MediaTek UART APDMA driver.
11 #include <linux/dma-mapping.h>
25 #include "../virt-dma.h"
123 writel(val, c->base + reg); in mtk_uart_apdma_write()
128 return readl(c->base + reg); in mtk_uart_apdma_read()
139 to_mtk_uart_apdma_dev(c->vc.chan.device); in mtk_uart_apdma_start_tx()
140 struct mtk_uart_apdma_desc *d = c->desc; in mtk_uart_apdma_start_tx()
143 vff_sz = c->cfg.dst_port_window_size; in mtk_uart_apdma_start_tx()
145 mtk_uart_apdma_write(c, VFF_ADDR, d->addr); in mtk_uart_apdma_start_tx()
151 if (mtkd->support_33bits) in mtk_uart_apdma_start_tx()
157 dev_err(c->vc.chan.device->dev, "Enable TX fail\n"); in mtk_uart_apdma_start_tx()
166 wpt += c->desc->avail_len; in mtk_uart_apdma_start_tx()
170 /* Let DMA start moving data */ in mtk_uart_apdma_start_tx()
182 to_mtk_uart_apdma_dev(c->vc.chan.device); in mtk_uart_apdma_start_rx()
183 struct mtk_uart_apdma_desc *d = c->desc; in mtk_uart_apdma_start_rx()
186 vff_sz = c->cfg.src_port_window_size; in mtk_uart_apdma_start_rx()
188 mtk_uart_apdma_write(c, VFF_ADDR, d->addr); in mtk_uart_apdma_start_rx()
194 if (mtkd->support_33bits) in mtk_uart_apdma_start_rx()
201 dev_err(c->vc.chan.device->dev, "Enable RX fail\n"); in mtk_uart_apdma_start_rx()
213 struct mtk_uart_apdma_desc *d = c->desc; in mtk_uart_apdma_rx_handler()
225 len = c->cfg.src_port_window_size; in mtk_uart_apdma_rx_handler()
228 cnt = (wg & VFF_RING_SIZE) - (rg & VFF_RING_SIZE); in mtk_uart_apdma_rx_handler()
237 c->rx_status = d->avail_len - cnt; in mtk_uart_apdma_rx_handler()
243 struct mtk_uart_apdma_desc *d = c->desc; in mtk_uart_apdma_chan_complete_handler()
246 list_del(&d->vd.node); in mtk_uart_apdma_chan_complete_handler()
247 vchan_cookie_complete(&d->vd); in mtk_uart_apdma_chan_complete_handler()
248 c->desc = NULL; in mtk_uart_apdma_chan_complete_handler()
258 spin_lock_irqsave(&c->vc.lock, flags); in mtk_uart_apdma_irq_handler()
259 if (c->dir == DMA_DEV_TO_MEM) in mtk_uart_apdma_irq_handler()
261 else if (c->dir == DMA_MEM_TO_DEV) in mtk_uart_apdma_irq_handler()
264 spin_unlock_irqrestore(&c->vc.lock, flags); in mtk_uart_apdma_irq_handler()
271 struct mtk_uart_apdmadev *mtkd = to_mtk_uart_apdma_dev(chan->device); in mtk_uart_apdma_alloc_chan_resources()
276 ret = pm_runtime_resume_and_get(mtkd->ddev.dev); in mtk_uart_apdma_alloc_chan_resources()
278 pm_runtime_put_noidle(chan->device->dev); in mtk_uart_apdma_alloc_chan_resources()
287 ret = readx_poll_timeout(readl, c->base + VFF_EN, in mtk_uart_apdma_alloc_chan_resources()
292 ret = request_irq(c->irq, mtk_uart_apdma_irq_handler, in mtk_uart_apdma_alloc_chan_resources()
295 dev_err(chan->device->dev, "Can't request dma IRQ\n"); in mtk_uart_apdma_alloc_chan_resources()
296 ret = -EINVAL; in mtk_uart_apdma_alloc_chan_resources()
300 if (mtkd->support_33bits) in mtk_uart_apdma_alloc_chan_resources()
304 pm_runtime_put_noidle(mtkd->ddev.dev); in mtk_uart_apdma_alloc_chan_resources()
310 struct mtk_uart_apdmadev *mtkd = to_mtk_uart_apdma_dev(chan->device); in mtk_uart_apdma_free_chan_resources()
313 free_irq(c->irq, chan); in mtk_uart_apdma_free_chan_resources()
315 tasklet_kill(&c->vc.task); in mtk_uart_apdma_free_chan_resources()
317 vchan_free_chan_resources(&c->vc); in mtk_uart_apdma_free_chan_resources()
319 pm_runtime_put_sync(mtkd->ddev.dev); in mtk_uart_apdma_free_chan_resources()
333 dma_set_residue(txstate, c->rx_status); in mtk_uart_apdma_tx_status()
340 * 8250 uart using one ring buffer, and deal with one sg.
358 d->avail_len = sg_dma_len(sgl); in mtk_uart_apdma_prep_slave_sg()
359 d->addr = sg_dma_address(sgl); in mtk_uart_apdma_prep_slave_sg()
360 c->dir = dir; in mtk_uart_apdma_prep_slave_sg()
362 return vchan_tx_prep(&c->vc, &d->vd, tx_flags); in mtk_uart_apdma_prep_slave_sg()
371 spin_lock_irqsave(&c->vc.lock, flags); in mtk_uart_apdma_issue_pending()
372 if (vchan_issue_pending(&c->vc) && !c->desc) { in mtk_uart_apdma_issue_pending()
373 vd = vchan_next_desc(&c->vc); in mtk_uart_apdma_issue_pending()
374 c->desc = to_mtk_uart_apdma_desc(&vd->tx); in mtk_uart_apdma_issue_pending()
376 if (c->dir == DMA_DEV_TO_MEM) in mtk_uart_apdma_issue_pending()
378 else if (c->dir == DMA_MEM_TO_DEV) in mtk_uart_apdma_issue_pending()
382 spin_unlock_irqrestore(&c->vc.lock, flags); in mtk_uart_apdma_issue_pending()
390 memcpy(&c->cfg, config, sizeof(*config)); in mtk_uart_apdma_slave_config()
405 ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, in mtk_uart_apdma_terminate_all()
408 dev_err(c->vc.chan.device->dev, "flush: fail, status=0x%x\n", in mtk_uart_apdma_terminate_all()
418 ret = readx_poll_timeout(readl, c->base + VFF_EN, in mtk_uart_apdma_terminate_all()
421 dev_err(c->vc.chan.device->dev, "stop: fail, status=0x%x\n", in mtk_uart_apdma_terminate_all()
427 if (c->dir == DMA_DEV_TO_MEM) in mtk_uart_apdma_terminate_all()
429 else if (c->dir == DMA_MEM_TO_DEV) in mtk_uart_apdma_terminate_all()
432 synchronize_irq(c->irq); in mtk_uart_apdma_terminate_all()
434 spin_lock_irqsave(&c->vc.lock, flags); in mtk_uart_apdma_terminate_all()
435 vchan_get_all_descriptors(&c->vc, &head); in mtk_uart_apdma_terminate_all()
436 spin_unlock_irqrestore(&c->vc.lock, flags); in mtk_uart_apdma_terminate_all()
438 vchan_dma_desc_free_list(&c->vc, &head); in mtk_uart_apdma_terminate_all()
448 spin_lock_irqsave(&c->vc.lock, flags); in mtk_uart_apdma_device_pause()
453 spin_unlock_irqrestore(&c->vc.lock, flags); in mtk_uart_apdma_device_pause()
454 synchronize_irq(c->irq); in mtk_uart_apdma_device_pause()
461 while (!list_empty(&mtkd->ddev.channels)) { in mtk_uart_apdma_free()
462 struct mtk_chan *c = list_first_entry(&mtkd->ddev.channels, in mtk_uart_apdma_free()
465 list_del(&c->vc.chan.device_node); in mtk_uart_apdma_free()
466 tasklet_kill(&c->vc.task); in mtk_uart_apdma_free()
471 { .compatible = "mediatek,mt6577-uart-dma", },
478 struct device_node *np = pdev->dev.of_node; in mtk_uart_apdma_probe()
484 mtkd = devm_kzalloc(&pdev->dev, sizeof(*mtkd), GFP_KERNEL); in mtk_uart_apdma_probe()
486 return -ENOMEM; in mtk_uart_apdma_probe()
488 mtkd->clk = devm_clk_get(&pdev->dev, NULL); in mtk_uart_apdma_probe()
489 if (IS_ERR(mtkd->clk)) { in mtk_uart_apdma_probe()
490 dev_err(&pdev->dev, "No clock specified\n"); in mtk_uart_apdma_probe()
491 rc = PTR_ERR(mtkd->clk); in mtk_uart_apdma_probe()
495 if (of_property_read_bool(np, "mediatek,dma-33bits")) in mtk_uart_apdma_probe()
496 mtkd->support_33bits = true; in mtk_uart_apdma_probe()
498 if (mtkd->support_33bits) in mtk_uart_apdma_probe()
501 rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(bit_mask)); in mtk_uart_apdma_probe()
505 dma_cap_set(DMA_SLAVE, mtkd->ddev.cap_mask); in mtk_uart_apdma_probe()
506 mtkd->ddev.device_alloc_chan_resources = in mtk_uart_apdma_probe()
508 mtkd->ddev.device_free_chan_resources = in mtk_uart_apdma_probe()
510 mtkd->ddev.device_tx_status = mtk_uart_apdma_tx_status; in mtk_uart_apdma_probe()
511 mtkd->ddev.device_issue_pending = mtk_uart_apdma_issue_pending; in mtk_uart_apdma_probe()
512 mtkd->ddev.device_prep_slave_sg = mtk_uart_apdma_prep_slave_sg; in mtk_uart_apdma_probe()
513 mtkd->ddev.device_config = mtk_uart_apdma_slave_config; in mtk_uart_apdma_probe()
514 mtkd->ddev.device_pause = mtk_uart_apdma_device_pause; in mtk_uart_apdma_probe()
515 mtkd->ddev.device_terminate_all = mtk_uart_apdma_terminate_all; in mtk_uart_apdma_probe()
516 mtkd->ddev.src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE); in mtk_uart_apdma_probe()
517 mtkd->ddev.dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE); in mtk_uart_apdma_probe()
518 mtkd->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV); in mtk_uart_apdma_probe()
519 mtkd->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; in mtk_uart_apdma_probe()
520 mtkd->ddev.dev = &pdev->dev; in mtk_uart_apdma_probe()
521 INIT_LIST_HEAD(&mtkd->ddev.channels); in mtk_uart_apdma_probe()
523 mtkd->dma_requests = MTK_UART_APDMA_NR_VCHANS; in mtk_uart_apdma_probe()
524 if (of_property_read_u32(np, "dma-requests", &mtkd->dma_requests)) { in mtk_uart_apdma_probe()
525 dev_info(&pdev->dev, in mtk_uart_apdma_probe()
526 "Using %u as missing dma-requests property\n", in mtk_uart_apdma_probe()
530 for (i = 0; i < mtkd->dma_requests; i++) { in mtk_uart_apdma_probe()
531 c = devm_kzalloc(mtkd->ddev.dev, sizeof(*c), GFP_KERNEL); in mtk_uart_apdma_probe()
533 rc = -ENODEV; in mtk_uart_apdma_probe()
537 c->base = devm_platform_ioremap_resource(pdev, i); in mtk_uart_apdma_probe()
538 if (IS_ERR(c->base)) { in mtk_uart_apdma_probe()
539 rc = PTR_ERR(c->base); in mtk_uart_apdma_probe()
542 c->vc.desc_free = mtk_uart_apdma_desc_free; in mtk_uart_apdma_probe()
543 vchan_init(&c->vc, &mtkd->ddev); in mtk_uart_apdma_probe()
548 c->irq = rc; in mtk_uart_apdma_probe()
551 pm_runtime_enable(&pdev->dev); in mtk_uart_apdma_probe()
553 rc = dma_async_device_register(&mtkd->ddev); in mtk_uart_apdma_probe()
559 /* Device-tree DMA controller registration */ in mtk_uart_apdma_probe()
567 dma_async_device_unregister(&mtkd->ddev); in mtk_uart_apdma_probe()
569 pm_runtime_disable(&pdev->dev); in mtk_uart_apdma_probe()
579 of_dma_controller_free(pdev->dev.of_node); in mtk_uart_apdma_remove()
583 dma_async_device_unregister(&mtkd->ddev); in mtk_uart_apdma_remove()
585 pm_runtime_disable(&pdev->dev); in mtk_uart_apdma_remove()
594 clk_disable_unprepare(mtkd->clk); in mtk_uart_apdma_suspend()
605 ret = clk_prepare_enable(mtkd->clk); in mtk_uart_apdma_resume()
619 clk_disable_unprepare(mtkd->clk); in mtk_uart_apdma_runtime_suspend()
628 return clk_prepare_enable(mtkd->clk); in mtk_uart_apdma_runtime_resume()
650 MODULE_DESCRIPTION("MediaTek UART APDMA Controller Driver");