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+
75130static 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+
277375static int
278376fsl_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+
407513static 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};
418525MODULE_DEVICE_TABLE (of , fsl_edma_dt_ids );
0 commit comments