[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Z2BTMqAX+GKBzeFJ@lizhi-Precision-Tower-5810>
Date: Mon, 16 Dec 2024 11:20:02 -0500
From: Frank Li <Frank.li@....com>
To: Larisa Grigore <larisa.grigore@....nxp.com>
Cc: dmaengine@...r.kernel.org, imx@...ts.linux.dev,
linux-kernel@...r.kernel.org, s32@....com,
Christophe Lizzi <clizzi@...hat.com>,
Alberto Ruiz <aruizrui@...hat.com>,
Enric Balletbo <eballetb@...hat.com>,
Ciprian Marian Costea <ciprianmarian.costea@....com>
Subject: Re: [PATCH 6/8] dmaengine: fsl-edma: add support for S32G based
platforms
On Mon, Dec 16, 2024 at 09:58:16AM +0200, Larisa Grigore wrote:
> S32G2/S32G3 includes two system eDMA instances based on v3 version, each of
> them integrated with two DMAMUX blocks.
Nit: empty line here
> Another particularity of these SoCs is that the interrupts are shared
> between channels as follows:
> - DMA Channels 0-15 share the 'tx-0-15' interrupt
> - DMA Channels 16-31 share the 'tx-16-31' interrupt
> - all channels share the 'err' interrupt
>
> Signed-off-by: Larisa Grigore <larisa.grigore@....nxp.com>
> Co-developed-by: Ciprian Marian Costea <ciprianmarian.costea@....com>
> Signed-off-by: Ciprian Marian Costea <ciprianmarian.costea@....com>
> ---
Reviewed-by: Frank Li <Frank.Li@....com>
> drivers/dma/fsl-edma-common.h | 3 +
> drivers/dma/fsl-edma-main.c | 109 +++++++++++++++++++++++++++++++++-
> 2 files changed, 111 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
> index 52901623d6fc..63e908fc3575 100644
> --- a/drivers/dma/fsl-edma-common.h
> +++ b/drivers/dma/fsl-edma-common.h
> @@ -68,6 +68,8 @@
> #define EDMA_V3_CH_CSR_EEI BIT(2)
> #define EDMA_V3_CH_CSR_DONE BIT(30)
> #define EDMA_V3_CH_CSR_ACTIVE BIT(31)
> +#define EDMA_V3_CH_ES_ERR BIT(31)
> +#define EDMA_V3_MP_ES_VLD BIT(31)
>
> enum fsl_edma_pm_state {
> RUNNING = 0,
> @@ -252,6 +254,7 @@ struct fsl_edma_engine {
> const struct fsl_edma_drvdata *drvdata;
> u32 n_chans;
> int txirq;
> + int txirq_16_31;
> int errirq;
> bool big_endian;
> struct edma_regs regs;
> diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
> index cc1787698b56..27bae3649026 100644
> --- a/drivers/dma/fsl-edma-main.c
> +++ b/drivers/dma/fsl-edma-main.c
> @@ -3,10 +3,11 @@
> * drivers/dma/fsl-edma.c
> *
> * Copyright 2013-2014 Freescale Semiconductor, Inc.
> + * Copyright 2024 NXP
> *
> * Driver for the Freescale eDMA engine with flexible channel multiplexing
> * capability for DMA request sources. The eDMA block can be found on some
> - * Vybrid and Layerscape SoCs.
> + * Vybrid, Layerscape and S32G SoCs.
> */
>
> #include <dt-bindings/dma/fsl-edma.h>
> @@ -73,6 +74,60 @@ static irqreturn_t fsl_edma2_tx_handler(int irq, void *devi_id)
> return fsl_edma_tx_handler(irq, fsl_chan->edma);
> }
>
> +static irqreturn_t fsl_edma3_or_tx_handler(int irq, void *dev_id,
> + u8 start, u8 end)
> +{
> + struct fsl_edma_engine *fsl_edma = dev_id;
> + struct fsl_edma_chan *chan;
> + int i;
> +
> + end = min(end, fsl_edma->n_chans);
> +
> + for (i = start; i < end; i++) {
> + chan = &fsl_edma->chans[i];
> +
> + fsl_edma3_tx_handler(irq, chan);
> + }
> +
> + return IRQ_HANDLED;
> +}
> +
> +static irqreturn_t fsl_edma3_tx_0_15_handler(int irq, void *dev_id)
> +{
> + return fsl_edma3_or_tx_handler(irq, dev_id, 0, 16);
> +}
> +
> +static irqreturn_t fsl_edma3_tx_16_31_handler(int irq, void *dev_id)
> +{
> + return fsl_edma3_or_tx_handler(irq, dev_id, 16, 32);
> +}
> +
> +static irqreturn_t fsl_edma3_or_err_handler(int irq, void *dev_id)
> +{
> + struct fsl_edma_engine *fsl_edma = dev_id;
> + struct edma_regs *regs = &fsl_edma->regs;
> + unsigned int err, ch, ch_es;
> + struct fsl_edma_chan *chan;
> +
> + err = edma_readl(fsl_edma, regs->es);
> + if (!(err & EDMA_V3_MP_ES_VLD))
> + return IRQ_NONE;
> +
> + for (ch = 0; ch < fsl_edma->n_chans; ch++) {
> + chan = &fsl_edma->chans[ch];
> +
> + ch_es = edma_readl_chreg(chan, ch_es);
> + if (!(ch_es & EDMA_V3_CH_ES_ERR))
> + continue;
> +
> + edma_writel_chreg(chan, EDMA_V3_CH_ES_ERR, ch_es);
> + fsl_edma_disable_request(chan);
> + fsl_edma->chans[ch].status = DMA_ERROR;
> + }
> +
> + return IRQ_HANDLED;
> +}
> +
> static irqreturn_t fsl_edma_err_handler(int irq, void *dev_id)
> {
> struct fsl_edma_engine *fsl_edma = dev_id;
> @@ -276,6 +331,49 @@ static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engi
> return 0;
> }
>
> +static int fsl_edma3_or_irq_init(struct platform_device *pdev,
> + struct fsl_edma_engine *fsl_edma)
> +{
> + int ret;
> +
> + fsl_edma->txirq = platform_get_irq_byname(pdev, "tx-0-15");
> + if (fsl_edma->txirq < 0)
> + return fsl_edma->txirq;
> +
> + fsl_edma->txirq_16_31 = platform_get_irq_byname(pdev, "tx-16-31");
> + if (fsl_edma->txirq_16_31 < 0)
> + return fsl_edma->txirq_16_31;
> +
> + fsl_edma->errirq = platform_get_irq_byname(pdev, "err");
> + if (fsl_edma->errirq < 0)
> + return fsl_edma->errirq;
> +
> + ret = devm_request_irq(&pdev->dev, fsl_edma->txirq,
> + fsl_edma3_tx_0_15_handler, 0, "eDMA tx0_15",
> + fsl_edma);
> + if (ret)
> + return dev_err_probe(&pdev->dev, ret,
> + "Can't register eDMA tx0_15 IRQ.\n");
> +
> + if (fsl_edma->n_chans > 16) {
> + ret = devm_request_irq(&pdev->dev, fsl_edma->txirq_16_31,
> + fsl_edma3_tx_16_31_handler, 0,
> + "eDMA tx16_31", fsl_edma);
> + if (ret)
> + return dev_err_probe(&pdev->dev, ret,
> + "Can't register eDMA tx16_31 IRQ.\n");
> + }
> +
> + ret = devm_request_irq(&pdev->dev, fsl_edma->errirq,
> + fsl_edma3_or_err_handler, 0, "eDMA err",
> + fsl_edma);
> + if (ret)
> + return dev_err_probe(&pdev->dev, ret,
> + "Can't register eDMA err IRQ.\n");
> +
> + return 0;
> +}
> +
> static int
> fsl_edma2_irq_init(struct platform_device *pdev,
> struct fsl_edma_engine *fsl_edma)
> @@ -406,6 +504,14 @@ static struct fsl_edma_drvdata imx95_data5 = {
> .setup_irq = fsl_edma3_irq_init,
> };
>
> +static const struct fsl_edma_drvdata s32g2_data = {
> + .dmamuxs = DMAMUX_NR,
> + .chreg_space_sz = EDMA_TCD,
> + .chreg_off = 0x4000,
> + .flags = FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_MUX_SWAP,
> + .setup_irq = fsl_edma3_or_irq_init,
> +};
> +
> static const struct of_device_id fsl_edma_dt_ids[] = {
> { .compatible = "fsl,vf610-edma", .data = &vf610_data},
> { .compatible = "fsl,ls1028a-edma", .data = &ls1028a_data},
> @@ -415,6 +521,7 @@ static const struct of_device_id fsl_edma_dt_ids[] = {
> { .compatible = "fsl,imx93-edma3", .data = &imx93_data3},
> { .compatible = "fsl,imx93-edma4", .data = &imx93_data4},
> { .compatible = "fsl,imx95-edma5", .data = &imx95_data5},
> + { .compatible = "nxp,s32g2-edma", .data = &s32g2_data},
> { /* sentinel */ }
> };
> MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
> --
> 2.47.0
>
Powered by blists - more mailing lists