* [PATCH 1/3] ARM: S3C64XX: Add SDMA clocks [not found] <cover.1275306279.git.mcuelenaere@gmail.com> @ 2010-05-31 11:58 ` Maurus Cuelenaere 2010-05-31 11:58 ` [PATCH 2/3] ARM: S3C64XX: Add SDMA support to DMA core Maurus Cuelenaere 2010-05-31 11:58 ` [PATCH 3/3] ARM: S3C64XX: Stop and flush requests on freeing Maurus Cuelenaere 2 siblings, 0 replies; 8+ messages in thread From: Maurus Cuelenaere @ 2010-05-31 11:58 UTC (permalink / raw) To: linux-arm-kernel This adds the clock definition bits for SDMA. Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com> --- arch/arm/mach-s3c64xx/clock.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index 7a4138b..d3e11a1 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -218,6 +218,18 @@ static struct clk init_clocks_disable[] = { .parent = &clk_h, .enable = s3c64xx_hclk_ctrl, .ctrlbit = S3C_CLKCON_HCLK_DMA1, + }, { + .name = "sdma0", + .id = -1, + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_SDMA0, + }, { + .name = "sdma1", + .id = -1, + .parent = &clk_h, + .enable = s3c64xx_hclk_ctrl, + .ctrlbit = S3C_CLKCON_HCLK_SDMA1, }, }; -- 1.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/3] ARM: S3C64XX: Add SDMA support to DMA core [not found] <cover.1275306279.git.mcuelenaere@gmail.com> 2010-05-31 11:58 ` [PATCH 1/3] ARM: S3C64XX: Add SDMA clocks Maurus Cuelenaere @ 2010-05-31 11:58 ` Maurus Cuelenaere 2010-05-31 12:16 ` [PATCH 2/3 v2] " Maurus Cuelenaere 2010-05-31 11:58 ` [PATCH 3/3] ARM: S3C64XX: Stop and flush requests on freeing Maurus Cuelenaere 2 siblings, 1 reply; 8+ messages in thread From: Maurus Cuelenaere @ 2010-05-31 11:58 UTC (permalink / raw) To: linux-arm-kernel The crypto engine uses the DMACH_SECURITY_[RT]X channels, who seem to be hardcoded to SDMA-only in hardware, so add support for SDMA to the S3C64XX DMA core. Only DMACH_SECURITY_[RT]X are using SDMA, other channels are unaffected and will continue to use standard DMA. Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com> --- arch/arm/mach-s3c64xx/dma.c | 52 +++++++++++++++++++++++++++++++++--------- 1 files changed, 41 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 5567e03..8c9946f 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -45,6 +45,15 @@ struct s3c64xx_dmac { /* pool to provide LLI buffers */ static struct dma_pool *dma_pool; +/* SDMA channel state information */ +struct s3c2410_dma_chan sdma_chans[S3C_DMA_CHANNELS]; + +/* Currently hardcodes SECURITY_[RT]X SDMA-only as dictated by HW */ +static inline bool channel_needs_sdma(unsigned int chan) +{ + return chan == DMACH_SECURITY_RX || chan == DMACH_SECURITY_TX; +} + /* Debug configuration and code */ static unsigned char debug_show_buffs = 0; @@ -92,16 +101,20 @@ static void dbg_showbuffs(struct s3c2410_dma_chan *chan) static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel) { + struct s3c2410_dma_chan *chans = s3c2410_chans; struct s3c2410_dma_chan *chan; unsigned int start, offs; + if (channel_needs_sdma(channel)) + chans = sdma_chans; + start = 0; if (channel >= DMACH_PCM1_TX) start = 8; for (offs = 0; offs < 8; offs++) { - chan = &s3c2410_chans[start + offs]; + chan = &chans[start + offs]; if (!chan->in_use) goto found; } @@ -549,7 +562,6 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) /* sort out stopping and freeing the channel */ - chan->client = NULL; chan->in_use = 0; @@ -634,8 +646,12 @@ static struct sysdev_class dma_sysclass = { .name = "s3c64xx-dma", }; +static struct sysdev_class sdma_sysclass = { + .name = "s3c64xx-sdma", +}; + static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, - int irq, unsigned int base) + int irq, unsigned int base, bool sdma) { struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno]; struct s3c64xx_dmac *dmac; @@ -651,7 +667,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, } dmac->sysdev.id = chno / 8; - dmac->sysdev.cls = &dma_sysclass; + dmac->sysdev.cls = sdma ? &sdma_sysclass : &dma_sysclass; err = sysdev_register(&dmac->sysdev); if (err) { @@ -666,7 +682,11 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, goto err_dev; } - snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id); + if (sdma) { + snprintf(clkname, sizeof(clkname), "sdma%d", dmac->sysdev.id); + chptr = &sdma_chans[chno]; + } else + snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id); dmac->clk = clk_get(NULL, clkname); if (IS_ERR(dmac->clk)) { @@ -690,8 +710,8 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, regptr = regs + PL080_Cx_BASE(0); for (ch = 0; ch < 8; ch++, chno++, chptr++) { - printk(KERN_INFO "%s: registering DMA %d (%p)\n", - __func__, chno, regptr); + printk(KERN_INFO "%s: registering %sDMA %d (%p)\n", + __func__, sdma ? "S" : "", chno, regptr); chptr->bit = 1 << ch; chptr->number = chno; @@ -737,12 +757,22 @@ static int __init s3c64xx_dma_init(void) return -ENOMEM; } - /* Set all DMA configuration to be DMA, not SDMA */ - writel(0xffffff, S3C_SYSREG(0x110)); + ret = sysdev_class_register(&sdma_sysclass); + if (ret) { + printk(KERN_ERR "%s: failed to create sysclass\n", __func__); + return -ENOMEM; + } + + /* Set all DMA configuration to be DMA, except SECURITY_[RT]X */ + writel(0x3fffffff, S3C_SYSREG(0x110)); /* Register standard DMA controlers */ - s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000); - s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000); + s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000, false); + s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000, false); + + /* Register SDMA controllers */ + s3c64xx_dma_init1(0, DMACH_UART0, IRQ_SDMA0, 0x7DB00000, true); + s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_SDMA1, 0x7DC00000, true); return 0; } -- 1.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/3 v2] ARM: S3C64XX: Add SDMA support to DMA core 2010-05-31 11:58 ` [PATCH 2/3] ARM: S3C64XX: Add SDMA support to DMA core Maurus Cuelenaere @ 2010-05-31 12:16 ` Maurus Cuelenaere 0 siblings, 0 replies; 8+ messages in thread From: Maurus Cuelenaere @ 2010-05-31 12:16 UTC (permalink / raw) To: linux-arm-kernel The crypto engine uses the DMACH_SECURITY_[RT]X channels, who seem to be hardcoded to SDMA-only in hardware, so add support for SDMA to the S3C64XX DMA core. Only DMACH_SECURITY_[RT]X are using SDMA, other channels are unaffected and will continue to use standard DMA. Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com> --- arch/arm/mach-s3c64xx/dma.c | 51 ++++++++++++++++++++++++++++++++++-------- 1 files changed, 41 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 5567e03..be043db 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -45,6 +45,15 @@ struct s3c64xx_dmac { /* pool to provide LLI buffers */ static struct dma_pool *dma_pool; +/* SDMA channel state information */ +static struct s3c2410_dma_chan sdma_chans[S3C_DMA_CHANNELS]; + +/* Currently hardcodes SECURITY_[RT]X SDMA-only as dictated by HW */ +static inline bool channel_needs_sdma(unsigned int chan) +{ + return chan == DMACH_SECURITY_RX || chan == DMACH_SECURITY_TX; +} + /* Debug configuration and code */ static unsigned char debug_show_buffs = 0; @@ -92,16 +101,20 @@ static void dbg_showbuffs(struct s3c2410_dma_chan *chan) static struct s3c2410_dma_chan *s3c64xx_dma_map_channel(unsigned int channel) { + struct s3c2410_dma_chan *chans = s3c2410_chans; struct s3c2410_dma_chan *chan; unsigned int start, offs; + if (channel_needs_sdma(channel)) + chans = sdma_chans; + start = 0; if (channel >= DMACH_PCM1_TX) start = 8; for (offs = 0; offs < 8; offs++) { - chan = &s3c2410_chans[start + offs]; + chan = &chans[start + offs]; if (!chan->in_use) goto found; } @@ -634,8 +647,12 @@ static struct sysdev_class dma_sysclass = { .name = "s3c64xx-dma", }; +static struct sysdev_class sdma_sysclass = { + .name = "s3c64xx-sdma", +}; + static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, - int irq, unsigned int base) + int irq, unsigned int base, bool sdma) { struct s3c2410_dma_chan *chptr = &s3c2410_chans[chno]; struct s3c64xx_dmac *dmac; @@ -651,7 +668,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, } dmac->sysdev.id = chno / 8; - dmac->sysdev.cls = &dma_sysclass; + dmac->sysdev.cls = sdma ? &sdma_sysclass : &dma_sysclass; err = sysdev_register(&dmac->sysdev); if (err) { @@ -666,7 +683,11 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, goto err_dev; } - snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id); + if (sdma) { + snprintf(clkname, sizeof(clkname), "sdma%d", dmac->sysdev.id); + chptr = &sdma_chans[chno]; + } else + snprintf(clkname, sizeof(clkname), "dma%d", dmac->sysdev.id); dmac->clk = clk_get(NULL, clkname); if (IS_ERR(dmac->clk)) { @@ -690,8 +711,8 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, regptr = regs + PL080_Cx_BASE(0); for (ch = 0; ch < 8; ch++, chno++, chptr++) { - printk(KERN_INFO "%s: registering DMA %d (%p)\n", - __func__, chno, regptr); + printk(KERN_INFO "%s: registering %sDMA %d (%p)\n", + __func__, sdma ? "S" : "", chno, regptr); chptr->bit = 1 << ch; chptr->number = chno; @@ -737,12 +758,22 @@ static int __init s3c64xx_dma_init(void) return -ENOMEM; } - /* Set all DMA configuration to be DMA, not SDMA */ - writel(0xffffff, S3C_SYSREG(0x110)); + ret = sysdev_class_register(&sdma_sysclass); + if (ret) { + printk(KERN_ERR "%s: failed to create sysclass\n", __func__); + return -ENOMEM; + } + + /* Set all DMA configuration to be DMA, except SECURITY_[RT]X */ + writel(0x3fffffff, S3C_SYSREG(0x110)); /* Register standard DMA controlers */ - s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000); - s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000); + s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000, false); + s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000, false); + + /* Register SDMA controllers */ + s3c64xx_dma_init1(0, DMACH_UART0, IRQ_SDMA0, 0x7DB00000, true); + s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_SDMA1, 0x7DC00000, true); return 0; } -- 1.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] ARM: S3C64XX: Stop and flush requests on freeing [not found] <cover.1275306279.git.mcuelenaere@gmail.com> 2010-05-31 11:58 ` [PATCH 1/3] ARM: S3C64XX: Add SDMA clocks Maurus Cuelenaere 2010-05-31 11:58 ` [PATCH 2/3] ARM: S3C64XX: Add SDMA support to DMA core Maurus Cuelenaere @ 2010-05-31 11:58 ` Maurus Cuelenaere 2 siblings, 0 replies; 8+ messages in thread From: Maurus Cuelenaere @ 2010-05-31 11:58 UTC (permalink / raw) To: linux-arm-kernel When a DMA channel is freed, its pending requests should be flushed and the channel should be halted. This patch ensures that happens. Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com> --- arch/arm/mach-s3c64xx/dma.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 8c9946f..193b07f 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -560,7 +560,8 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) channel, chan->client, client); } - /* sort out stopping and freeing the channel */ + s3c64xx_dma_flush(chan); + s3c64xx_dma_stop(chan); chan->client = NULL; chan->in_use = 0; -- 1.7.1 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] ARM: S3C64XX: Stop and flush requests on freeing @ 2010-08-15 13:08 Maurus Cuelenaere 2010-08-15 13:28 ` Jassi Brar 0 siblings, 1 reply; 8+ messages in thread From: Maurus Cuelenaere @ 2010-08-15 13:08 UTC (permalink / raw) To: linux-arm-kernel When a DMA channel is freed, its pending requests should be flushed and the channel should be halted. This patch ensures that happens. Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com> --- arch/arm/mach-s3c64xx/dma.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 1fd9d0c..e1f22af 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -560,7 +560,8 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) channel, chan->client, client); } - /* sort out stopping and freeing the channel */ + s3c64xx_dma_flush(chan); + s3c64xx_dma_stop(chan); chan->client = NULL; -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] ARM: S3C64XX: Stop and flush requests on freeing 2010-08-15 13:08 Maurus Cuelenaere @ 2010-08-15 13:28 ` Jassi Brar 2010-08-15 13:36 ` Jassi Brar 0 siblings, 1 reply; 8+ messages in thread From: Jassi Brar @ 2010-08-15 13:28 UTC (permalink / raw) To: linux-arm-kernel On Mon, May 31, 2010 at 8:34 PM, Maurus Cuelenaere <mcuelenaere@gmail.com> wrote: > When a DMA channel is freed, its pending requests should be flushed and the > channel should be halted. This patch ensures that happens. > > Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com> > --- > ?arch/arm/mach-s3c64xx/dma.c | ? ?3 ++- > ?1 files changed, 2 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c > index 1fd9d0c..e1f22af 100644 > --- a/arch/arm/mach-s3c64xx/dma.c > +++ b/arch/arm/mach-s3c64xx/dma.c > @@ -560,7 +560,8 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) > ? ? ? ? ? ? ? ? ? ? ? channel, chan->client, client); > ? ? ? ?} > > - ? ? ? /* sort out stopping and freeing the channel */ > + ? ? ? s3c64xx_dma_flush(chan); > + ? ? ? s3c64xx_dma_stop(chan); I think, the order should be reverted. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/3] ARM: S3C64XX: Stop and flush requests on freeing 2010-08-15 13:28 ` Jassi Brar @ 2010-08-15 13:36 ` Jassi Brar 2010-08-15 13:42 ` Maurus Cuelenaere 0 siblings, 1 reply; 8+ messages in thread From: Jassi Brar @ 2010-08-15 13:36 UTC (permalink / raw) To: linux-arm-kernel On Sun, Aug 15, 2010 at 10:28 PM, Jassi Brar <jassisinghbrar@gmail.com> wrote: > On Mon, May 31, 2010 at 8:34 PM, Maurus Cuelenaere > <mcuelenaere@gmail.com> wrote: >> When a DMA channel is freed, its pending requests should be flushed and the >> channel should be halted. This patch ensures that happens. >> >> Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com> >> --- >> ?arch/arm/mach-s3c64xx/dma.c | ? ?3 ++- >> ?1 files changed, 2 insertions(+), 1 deletions(-) >> >> diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c >> index 1fd9d0c..e1f22af 100644 >> --- a/arch/arm/mach-s3c64xx/dma.c >> +++ b/arch/arm/mach-s3c64xx/dma.c >> @@ -560,7 +560,8 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) >> ? ? ? ? ? ? ? ? ? ? ? channel, chan->client, client); >> ? ? ? ?} >> >> - ? ? ? /* sort out stopping and freeing the channel */ >> + ? ? ? s3c64xx_dma_flush(chan); >> + ? ? ? s3c64xx_dma_stop(chan); > > I think, the order should be reverted. Though it's a matter of S3C DMA API spec. Shouldn't the client be made to explicitly do S3C2410_DMAOP_FLUSH a pending req before freeing the channel? If so, the patch may not be needed. ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/3] ARM: S3C64XX: Stop and flush requests on freeing 2010-08-15 13:36 ` Jassi Brar @ 2010-08-15 13:42 ` Maurus Cuelenaere 0 siblings, 0 replies; 8+ messages in thread From: Maurus Cuelenaere @ 2010-08-15 13:42 UTC (permalink / raw) To: linux-arm-kernel Op 15-08-10 15:36, Jassi Brar schreef: > On Sun, Aug 15, 2010 at 10:28 PM, Jassi Brar <jassisinghbrar@gmail.com> wrote: >> On Mon, May 31, 2010 at 8:34 PM, Maurus Cuelenaere >> <mcuelenaere@gmail.com> wrote: >>> When a DMA channel is freed, its pending requests should be flushed and the >>> channel should be halted. This patch ensures that happens. >>> >>> Signed-off-by: Maurus Cuelenaere <mcuelenaere@gmail.com> >>> --- >>> arch/arm/mach-s3c64xx/dma.c | 3 ++- >>> 1 files changed, 2 insertions(+), 1 deletions(-) >>> >>> diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c >>> index 1fd9d0c..e1f22af 100644 >>> --- a/arch/arm/mach-s3c64xx/dma.c >>> +++ b/arch/arm/mach-s3c64xx/dma.c >>> @@ -560,7 +560,8 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) >>> channel, chan->client, client); >>> } >>> >>> - /* sort out stopping and freeing the channel */ >>> + s3c64xx_dma_flush(chan); >>> + s3c64xx_dma_stop(chan); >> I think, the order should be reverted. You're probably right. > Though it's a matter of S3C DMA API spec. > Shouldn't the client be made to explicitly do S3C2410_DMAOP_FLUSH > a pending req before freeing the channel? If so, the patch may not be needed. I can't find anything about the client needing to flush the request itself. Documentation/arm/Samsung-S3C24XX/DMA.txt doesn't mention anything regarding it and the comment above s3c2410_dma_free() says "release the given channel back to the system, will stop and flush any outstanding transfers, and ensure the channel is ready for the next claimant." -- Maurus Cuelenaere ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2010-08-15 13:42 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <cover.1275306279.git.mcuelenaere@gmail.com> 2010-05-31 11:58 ` [PATCH 1/3] ARM: S3C64XX: Add SDMA clocks Maurus Cuelenaere 2010-05-31 11:58 ` [PATCH 2/3] ARM: S3C64XX: Add SDMA support to DMA core Maurus Cuelenaere 2010-05-31 12:16 ` [PATCH 2/3 v2] " Maurus Cuelenaere 2010-05-31 11:58 ` [PATCH 3/3] ARM: S3C64XX: Stop and flush requests on freeing Maurus Cuelenaere 2010-08-15 13:08 Maurus Cuelenaere 2010-08-15 13:28 ` Jassi Brar 2010-08-15 13:36 ` Jassi Brar 2010-08-15 13:42 ` Maurus Cuelenaere
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).