Skip to content

Commit 2500243

Browse files
Larisa Grigorevinodkoul
authored andcommitted
dmaengine: fsl-edma: add support for S32G based platforms
S32G2/S32G3 includes two system eDMA instances based on v3 version, each of them integrated with two DMAMUX blocks. 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 <[email protected]> Co-developed-by: Ciprian Marian Costea <[email protected]> Signed-off-by: Ciprian Marian Costea <[email protected]> Reviewed-by: Frank Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent 57eeb0a commit 2500243

File tree

2 files changed

+111
-1
lines changed

2 files changed

+111
-1
lines changed

drivers/dma/fsl-edma-common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@
6868
#define EDMA_V3_CH_CSR_EEI BIT(2)
6969
#define EDMA_V3_CH_CSR_DONE BIT(30)
7070
#define EDMA_V3_CH_CSR_ACTIVE BIT(31)
71+
#define EDMA_V3_CH_ES_ERR BIT(31)
72+
#define EDMA_V3_MP_ES_VLD BIT(31)
7173

7274
enum fsl_edma_pm_state {
7375
RUNNING = 0,
@@ -240,6 +242,7 @@ struct fsl_edma_engine {
240242
const struct fsl_edma_drvdata *drvdata;
241243
u32 n_chans;
242244
int txirq;
245+
int txirq_16_31;
243246
int errirq;
244247
bool big_endian;
245248
struct edma_regs regs;

drivers/dma/fsl-edma-main.c

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
* drivers/dma/fsl-edma.c
44
*
55
* Copyright 2013-2014 Freescale Semiconductor, Inc.
6+
* Copyright 2024 NXP
67
*
78
* Driver for the Freescale eDMA engine with flexible channel multiplexing
89
* capability for DMA request sources. The eDMA block can be found on some
9-
* Vybrid and Layerscape SoCs.
10+
* Vybrid, Layerscape and S32G SoCs.
1011
*/
1112

1213
#include <dt-bindings/dma/fsl-edma.h>
@@ -72,6 +73,60 @@ static irqreturn_t fsl_edma2_tx_handler(int irq, void *devi_id)
7273
return fsl_edma_tx_handler(irq, fsl_chan->edma);
7374
}
7475

76+
static irqreturn_t fsl_edma3_or_tx_handler(int irq, void *dev_id,
77+
u8 start, u8 end)
78+
{
79+
struct fsl_edma_engine *fsl_edma = dev_id;
80+
struct fsl_edma_chan *chan;
81+
int i;
82+
83+
end = min(end, fsl_edma->n_chans);
84+
85+
for (i = start; i < end; i++) {
86+
chan = &fsl_edma->chans[i];
87+
88+
fsl_edma3_tx_handler(irq, chan);
89+
}
90+
91+
return IRQ_HANDLED;
92+
}
93+
94+
static irqreturn_t fsl_edma3_tx_0_15_handler(int irq, void *dev_id)
95+
{
96+
return fsl_edma3_or_tx_handler(irq, dev_id, 0, 16);
97+
}
98+
99+
static irqreturn_t fsl_edma3_tx_16_31_handler(int irq, void *dev_id)
100+
{
101+
return fsl_edma3_or_tx_handler(irq, dev_id, 16, 32);
102+
}
103+
104+
static irqreturn_t fsl_edma3_or_err_handler(int irq, void *dev_id)
105+
{
106+
struct fsl_edma_engine *fsl_edma = dev_id;
107+
struct edma_regs *regs = &fsl_edma->regs;
108+
unsigned int err, ch, ch_es;
109+
struct fsl_edma_chan *chan;
110+
111+
err = edma_readl(fsl_edma, regs->es);
112+
if (!(err & EDMA_V3_MP_ES_VLD))
113+
return IRQ_NONE;
114+
115+
for (ch = 0; ch < fsl_edma->n_chans; ch++) {
116+
chan = &fsl_edma->chans[ch];
117+
118+
ch_es = edma_readl_chreg(chan, ch_es);
119+
if (!(ch_es & EDMA_V3_CH_ES_ERR))
120+
continue;
121+
122+
edma_writel_chreg(chan, EDMA_V3_CH_ES_ERR, ch_es);
123+
fsl_edma_disable_request(chan);
124+
fsl_edma->chans[ch].status = DMA_ERROR;
125+
}
126+
127+
return IRQ_HANDLED;
128+
}
129+
75130
static irqreturn_t fsl_edma_err_handler(int irq, void *dev_id)
76131
{
77132
struct fsl_edma_engine *fsl_edma = dev_id;
@@ -274,6 +329,49 @@ static int fsl_edma3_irq_init(struct platform_device *pdev, struct fsl_edma_engi
274329
return 0;
275330
}
276331

332+
static int fsl_edma3_or_irq_init(struct platform_device *pdev,
333+
struct fsl_edma_engine *fsl_edma)
334+
{
335+
int ret;
336+
337+
fsl_edma->txirq = platform_get_irq_byname(pdev, "tx-0-15");
338+
if (fsl_edma->txirq < 0)
339+
return fsl_edma->txirq;
340+
341+
fsl_edma->txirq_16_31 = platform_get_irq_byname(pdev, "tx-16-31");
342+
if (fsl_edma->txirq_16_31 < 0)
343+
return fsl_edma->txirq_16_31;
344+
345+
fsl_edma->errirq = platform_get_irq_byname(pdev, "err");
346+
if (fsl_edma->errirq < 0)
347+
return fsl_edma->errirq;
348+
349+
ret = devm_request_irq(&pdev->dev, fsl_edma->txirq,
350+
fsl_edma3_tx_0_15_handler, 0, "eDMA tx0_15",
351+
fsl_edma);
352+
if (ret)
353+
return dev_err_probe(&pdev->dev, ret,
354+
"Can't register eDMA tx0_15 IRQ.\n");
355+
356+
if (fsl_edma->n_chans > 16) {
357+
ret = devm_request_irq(&pdev->dev, fsl_edma->txirq_16_31,
358+
fsl_edma3_tx_16_31_handler, 0,
359+
"eDMA tx16_31", fsl_edma);
360+
if (ret)
361+
return dev_err_probe(&pdev->dev, ret,
362+
"Can't register eDMA tx16_31 IRQ.\n");
363+
}
364+
365+
ret = devm_request_irq(&pdev->dev, fsl_edma->errirq,
366+
fsl_edma3_or_err_handler, 0, "eDMA err",
367+
fsl_edma);
368+
if (ret)
369+
return dev_err_probe(&pdev->dev, ret,
370+
"Can't register eDMA err IRQ.\n");
371+
372+
return 0;
373+
}
374+
277375
static int
278376
fsl_edma2_irq_init(struct platform_device *pdev,
279377
struct fsl_edma_engine *fsl_edma)
@@ -404,6 +502,14 @@ static struct fsl_edma_drvdata imx95_data5 = {
404502
.setup_irq = fsl_edma3_irq_init,
405503
};
406504

505+
static const struct fsl_edma_drvdata s32g2_data = {
506+
.dmamuxs = DMAMUX_NR,
507+
.chreg_space_sz = EDMA_TCD,
508+
.chreg_off = 0x4000,
509+
.flags = FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_MUX_SWAP,
510+
.setup_irq = fsl_edma3_or_irq_init,
511+
};
512+
407513
static const struct of_device_id fsl_edma_dt_ids[] = {
408514
{ .compatible = "fsl,vf610-edma", .data = &vf610_data},
409515
{ .compatible = "fsl,ls1028a-edma", .data = &ls1028a_data},
@@ -413,6 +519,7 @@ static const struct of_device_id fsl_edma_dt_ids[] = {
413519
{ .compatible = "fsl,imx93-edma3", .data = &imx93_data3},
414520
{ .compatible = "fsl,imx93-edma4", .data = &imx93_data4},
415521
{ .compatible = "fsl,imx95-edma5", .data = &imx95_data5},
522+
{ .compatible = "nxp,s32g2-edma", .data = &s32g2_data},
416523
{ /* sentinel */ }
417524
};
418525
MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);

0 commit comments

Comments
 (0)