Commit d8d43558 authored by Joy Zou's avatar Joy Zou Committed by Vinod Koul
Browse files

dmaengine: fsl-edma: add i.MX8ULP edma support



Add support for the i.MX8ULP platform to the eDMA driver. Introduce the use
of the correct FSL_EDMA_DRV_HAS_CHCLK flag to handle per-channel clock
configurations.

Signed-off-by: default avatarJoy Zou <joy.zou@nxp.com>
Reviewed-by: default avatarFrank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20240323-8ulp_edma-v3-5-c0e981027c05@nxp.com


Signed-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent b14f56be
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
// Copyright (c) 2013-2014 Freescale Semiconductor, Inc
// Copyright (c) 2017 Sysam, Angelo Dureghello  <angelo@sysam.it>

#include <linux/clk.h>
#include <linux/dmapool.h>
#include <linux/module.h>
#include <linux/slab.h>
@@ -810,6 +811,9 @@ int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
{
	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);

	if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK)
		clk_prepare_enable(fsl_chan->clk);

	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
				fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_TCD64 ?
				sizeof(struct fsl_edma_hw_tcd64) : sizeof(struct fsl_edma_hw_tcd),
@@ -838,6 +842,8 @@ void fsl_edma_free_chan_resources(struct dma_chan *chan)
	fsl_chan->tcd_pool = NULL;
	fsl_chan->is_sw = false;
	fsl_chan->srcid = 0;
	if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK)
		clk_disable_unprepare(fsl_chan->clk);
}

void fsl_edma_cleanup_vchan(struct dma_device *dmadev)
+1 −0
Original line number Diff line number Diff line
@@ -192,6 +192,7 @@ struct fsl_edma_desc {
#define FSL_EDMA_DRV_WRAP_IO		BIT(3)
#define FSL_EDMA_DRV_EDMA64		BIT(4)
#define FSL_EDMA_DRV_HAS_PD		BIT(5)
#define FSL_EDMA_DRV_HAS_CHCLK		BIT(6)
#define FSL_EDMA_DRV_HAS_CHMUX		BIT(7)
/* imx8 QM audio edma remote local swapped */
#define FSL_EDMA_DRV_QUIRK_SWAPPED	BIT(8)
+22 −0
Original line number Diff line number Diff line
@@ -356,6 +356,16 @@ static struct fsl_edma_drvdata imx8qm_audio_data = {
	.setup_irq = fsl_edma3_irq_init,
};

static struct fsl_edma_drvdata imx8ulp_data = {
	.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_CHCLK | FSL_EDMA_DRV_HAS_DMACLK |
		 FSL_EDMA_DRV_EDMA3,
	.chreg_space_sz = 0x10000,
	.chreg_off = 0x10000,
	.mux_off = 0x10000 + offsetof(struct fsl_edma3_ch_reg, ch_mux),
	.mux_skip = 0x10000,
	.setup_irq = fsl_edma3_irq_init,
};

static struct fsl_edma_drvdata imx93_data3 = {
	.flags = FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA3,
	.chreg_space_sz = 0x10000,
@@ -388,6 +398,7 @@ static const struct of_device_id fsl_edma_dt_ids[] = {
	{ .compatible = "fsl,imx7ulp-edma", .data = &imx7ulp_data},
	{ .compatible = "fsl,imx8qm-edma", .data = &imx8qm_data},
	{ .compatible = "fsl,imx8qm-adma", .data = &imx8qm_audio_data},
	{ .compatible = "fsl,imx8ulp-edma", .data = &imx8ulp_data},
	{ .compatible = "fsl,imx93-edma3", .data = &imx93_data3},
	{ .compatible = "fsl,imx93-edma4", .data = &imx93_data4},
	{ .compatible = "fsl,imx95-edma5", .data = &imx95_data5},
@@ -441,6 +452,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
	struct fsl_edma_engine *fsl_edma;
	const struct fsl_edma_drvdata *drvdata = NULL;
	u32 chan_mask[2] = {0, 0};
	char clk_name[36];
	struct edma_regs *regs;
	int chans;
	int ret, i;
@@ -550,11 +562,21 @@ static int fsl_edma_probe(struct platform_device *pdev)
				+ i * drvdata->chreg_space_sz + drvdata->chreg_off + len;
		fsl_chan->mux_addr = fsl_edma->membase + drvdata->mux_off + i * drvdata->mux_skip;

		if (drvdata->flags & FSL_EDMA_DRV_HAS_CHCLK) {
			snprintf(clk_name, sizeof(clk_name), "ch%02d", i);
			fsl_chan->clk = devm_clk_get_enabled(&pdev->dev,
							     (const char *)clk_name);

			if (IS_ERR(fsl_chan->clk))
				return PTR_ERR(fsl_chan->clk);
		}
		fsl_chan->pdev = pdev;
		vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev);

		edma_write_tcdreg(fsl_chan, cpu_to_le32(0), csr);
		fsl_edma_chan_mux(fsl_chan, 0, false);
		if (fsl_chan->edma->drvdata->flags & FSL_EDMA_DRV_HAS_CHCLK)
			clk_disable_unprepare(fsl_chan->clk);
	}

	ret = fsl_edma->drvdata->setup_irq(pdev, fsl_edma);