Re: [PATCH v2 6/7] dmaengine: fsl-edma: add i.mx7ulp edma2 version support
On 27-05-19, 11:05, Sascha Hauer wrote: > On Mon, May 27, 2019 at 04:51:17PM +0800, yibin.g...@nxp.com wrote: > > From: Robin Gong > > > > +static const struct of_device_id fsl_edma_dt_ids[] = { > > + { .compatible = "fsl,vf610-edma", .data = (void *)v1 }, > > + { .compatible = "fsl,imx7ulp-edma", .data = (void *)v3 }, > > + { /* sentinel */ } > > Please put a struct type behind the .data pointer so that you can > configure... Yeah that was the idea behind the suggestion in previous version. Something like struct fsl_edma_driver_data { unsigned int channels; ... }; and then you have const struct fsl_edma_driver_data v1_data { .channels = 1; ... }; > > > +}; > > +MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids); > > + > > @@ -218,6 +272,22 @@ static int fsl_edma_probe(struct platform_device *pdev) > > fsl_edma_setup_regs(fsl_edma); > > regs = _edma->regs; > > > > + if (fsl_edma->version == v3) { > > + fsl_edma->dmamux_nr = 1; You can store the struct in driver context or store the values, so here it becomes driver->data->channel; and so on for other data, you can also point function pointers (hint edma/2_irq_init) > > ...things like this... > > > @@ -264,7 +334,11 @@ static int fsl_edma_probe(struct platform_device *pdev) > > } > > > > edma_writel(fsl_edma, ~0, regs->intl); > > - ret = fsl_edma_irq_init(pdev, fsl_edma); > > + > > + if (fsl_edma->version == v3) > > + ret = fsl_edma2_irq_init(pdev, fsl_edma); > > + else > > + ret = fsl_edma_irq_init(pdev, fsl_edma); > > ...and this one in that struct rather than littering the code more and > more with such version tests. > > Sascha > > -- > Pengutronix e.K. | | > Industrial Linux Solutions | http://www.pengutronix.de/ | > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- | -- ~Vinod
Re: [PATCH v2 6/7] dmaengine: fsl-edma: add i.mx7ulp edma2 version support
On 2019-05-27 at 11:05 +0200, Sascha Hauer wrote: > On Mon, May 27, 2019 at 04:51:17PM +0800, yibin.g...@nxp.com wrote: > > > > From: Robin Gong > > > > +static const struct of_device_id fsl_edma_dt_ids[] = { > > + { .compatible = "fsl,vf610-edma", .data = (void *)v1 }, > > + { .compatible = "fsl,imx7ulp-edma", .data = (void *)v3 }, > > + { /* sentinel */ } > Please put a struct type behind the .data pointer so that you can > configure... But current only version needed, so I give up struct define > > > > > +}; > > +MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids); > > + > > @@ -218,6 +272,22 @@ static int fsl_edma_probe(struct > > platform_device *pdev) > > fsl_edma_setup_regs(fsl_edma); > > regs = _edma->regs; > > > > + if (fsl_edma->version == v3) { > > + fsl_edma->dmamux_nr = 1; > ...things like this... Yes, dmamux_nr could be moved to struct at least. > > > > > @@ -264,7 +334,11 @@ static int fsl_edma_probe(struct > > platform_device *pdev) > > } > > > > edma_writel(fsl_edma, ~0, regs->intl); > > - ret = fsl_edma_irq_init(pdev, fsl_edma); > > + > > + if (fsl_edma->version == v3) > > + ret = fsl_edma2_irq_init(pdev, fsl_edma); > > + else > > + ret = fsl_edma_irq_init(pdev, fsl_edma); > ...and this one in that struct rather than littering the code more > and > more with such version tests. Yes, such irq setup function could be moved to struct, thus, no version test in this file. Will refine it in v3. > > Sascha >
Re: [PATCH v2 6/7] dmaengine: fsl-edma: add i.mx7ulp edma2 version support
On Mon, May 27, 2019 at 04:51:17PM +0800, yibin.g...@nxp.com wrote: > From: Robin Gong > > +static const struct of_device_id fsl_edma_dt_ids[] = { > + { .compatible = "fsl,vf610-edma", .data = (void *)v1 }, > + { .compatible = "fsl,imx7ulp-edma", .data = (void *)v3 }, > + { /* sentinel */ } Please put a struct type behind the .data pointer so that you can configure... > +}; > +MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids); > + > @@ -218,6 +272,22 @@ static int fsl_edma_probe(struct platform_device *pdev) > fsl_edma_setup_regs(fsl_edma); > regs = _edma->regs; > > + if (fsl_edma->version == v3) { > + fsl_edma->dmamux_nr = 1; ...things like this... > @@ -264,7 +334,11 @@ static int fsl_edma_probe(struct platform_device *pdev) > } > > edma_writel(fsl_edma, ~0, regs->intl); > - ret = fsl_edma_irq_init(pdev, fsl_edma); > + > + if (fsl_edma->version == v3) > + ret = fsl_edma2_irq_init(pdev, fsl_edma); > + else > + ret = fsl_edma_irq_init(pdev, fsl_edma); ...and this one in that struct rather than littering the code more and more with such version tests. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0| Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917- |
[PATCH v2 6/7] dmaengine: fsl-edma: add i.mx7ulp edma2 version support
From: Robin Gong Add edma2 for i.mx7ulp by version v3, since v2 has already been used by mcf-edma. The big changes based on v1 are belows: 1. only one dmamux. 2. another clock dma_clk except dmamux clk. 3. 16 independent interrupts instead of only one interrupt for all channels. Signed-off-by: Robin Gong --- drivers/dma/fsl-edma-common.c | 18 +- drivers/dma/fsl-edma-common.h | 3 ++ drivers/dma/fsl-edma.c| 84 ++- 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c index 45d70d3..0d9915c 100644 --- a/drivers/dma/fsl-edma-common.c +++ b/drivers/dma/fsl-edma-common.c @@ -90,6 +90,19 @@ static void mux_configure8(struct fsl_edma_chan *fsl_chan, void __iomem *addr, iowrite8(val8, addr + off); } +void mux_configure32(struct fsl_edma_chan *fsl_chan, void __iomem *addr, +u32 off, u32 slot, bool enable) +{ + u32 val; + + if (enable) + val = EDMAMUX_CHCFG_ENBL << 24 | slot; + else + val = EDMAMUX_CHCFG_DIS; + + iowrite32(val, addr + off * 4); +} + void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan, unsigned int slot, bool enable) { @@ -102,7 +115,10 @@ void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan, muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux]; slot = EDMAMUX_CHCFG_SOURCE(slot); - mux_configure8(fsl_chan, muxaddr, ch_off, slot, enable); + if (fsl_chan->edma->version == v3) + mux_configure32(fsl_chan, muxaddr, ch_off, slot, enable); + else + mux_configure8(fsl_chan, muxaddr, ch_off, slot, enable); } EXPORT_SYMBOL_GPL(fsl_edma_chan_mux); diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h index 21a9cfd..2b0cc8e 100644 --- a/drivers/dma/fsl-edma-common.h +++ b/drivers/dma/fsl-edma-common.h @@ -124,6 +124,7 @@ struct fsl_edma_chan { dma_addr_t dma_dev_addr; u32 dma_dev_size; enum dma_data_direction dma_dir; + charchan_name[16]; }; struct fsl_edma_desc { @@ -138,6 +139,7 @@ struct fsl_edma_desc { enum edma_version { v1, /* 32ch, Vybrid, mpc57x, etc */ v2, /* 64ch Coldfire */ + v3, /* 32ch, i.mx7ulp */ }; struct fsl_edma_engine { @@ -145,6 +147,7 @@ struct fsl_edma_engine { void __iomem*membase; void __iomem*muxbase[DMAMUX_NR]; struct clk *muxclk[DMAMUX_NR]; + struct clk *dmaclk; u32 dmamux_nr; struct mutexfsl_edma_mutex; u32 n_chans; diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index 7b65ef4..055f430 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c @@ -165,6 +165,51 @@ fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma return 0; } +static int +fsl_edma2_irq_init(struct platform_device *pdev, + struct fsl_edma_engine *fsl_edma) +{ + struct device_node *np = pdev->dev.of_node; + int i, ret, irq; + int count = 0; + + count = of_irq_count(np); + dev_info(>dev, "%s Found %d interrupts\r\n", __func__, count); + if (count <= 2) { + dev_err(>dev, "Interrupts in DTS not correct.\n"); + return -EINVAL; + } + /* +* 16 channel independent interrupts + 1 error interrupt on i.mx7ulp. +* 2 channel share one interrupt, for example, ch0/ch16, ch1/ch17... +* For now, just simply request irq without IRQF_SHARED flag, since 16 +* channels are enough on i.mx7ulp whose M4 domain own some peripherals. +*/ + for (i = 0; i < count; i++) { + irq = platform_get_irq(pdev, i); + if (irq < 0) + return -ENXIO; + + sprintf(fsl_edma->chans[i].chan_name, "eDMA2-CH%02d", i); + + /* The last IRQ is for eDMA err */ + if (i == count - 1) + ret = devm_request_irq(>dev, irq, + fsl_edma_err_handler, + 0, "eDMA2-ERR", fsl_edma); + else + + ret = devm_request_irq(>dev, irq, + fsl_edma_tx_handler, 0, + fsl_edma->chans[i].chan_name, + fsl_edma); + if (ret) + return ret; + } + + return 0; +} + static void fsl_edma_irq_exit( struct platform_device *pdev, struct fsl_edma_engine *fsl_edma) { @@ -184,8 +229,17 @@ static void fsl_disable_clocks(struct fsl_edma_engine