i.MX28: DMA fixups
Subsystems (6)
cover i.MX28: DMA fixups
This patchset fixes DMA issues found on Freescale MX28EVK.
NOTE: This patch depends on:
http://patchwork.ozlabs.org/patch/150957/
Marek Vasut (2):
DMA: Split the APBH DMA init into block and channel init
M28: Pull out CONFIG_APBH_DMA so it's always enabled
arch/arm/cpu/arm926ejs/mx28/mx28.c | 6 +++++ arch/arm/include/asm/arch-mx28/dma.h | 4 ++- drivers/dma/apbh_dma.c | 37 ++++++++++++++------------------- drivers/mmc/mxsmmc.c | 5 ++++ drivers/mtd/nand/mxs_nand.c | 12 ++++++++++- include/configs/m28evk.h | 6 ++++- 6 files changed, 46 insertions(+), 24 deletions(-)
Signature · 1 line
1.7.9.1
PATCH 1/2 DMA: Split the APBH DMA init into block and channel init
This fixes the issue where mxs_dma_init() was called either twice or never, without introducing any new init hooks.
The idea is to allow each and every device using the APBH DMA block to configure and request only the channels it uses, instead of making it call init for all the channels as is now.
The common DMA block init part, which only configures the block, is then called from CPUs arch_cpu_init() call.
NOTE: This patch depends on:
http://patchwork.ozlabs.org/patch/150957/
--- arch/arm/cpu/arm926ejs/mx28/mx28.c | 6 +++++ arch/arm/include/asm/arch-mx28/dma.h | 4 ++- drivers/dma/apbh_dma.c | 37 ++++++++++++++------------------- drivers/mmc/mxsmmc.c | 5 ++++ drivers/mtd/nand/mxs_nand.c | 12 ++++++++++- 5 files changed, 41 insertions(+), 23 deletions(-)
arch/arm/cpu/arm926ejs/mx28/mx28.c +6 -0
@@ -30,6 +30,7 @@#include <asm/errno.h> #include <asm/io.h> #include <asm/arch/clock.h> +#include <asm/arch/dma.h> #include <asm/arch/gpio.h> #include <asm/arch/iomux.h> #include <asm/arch/imx-regs.h>
@@ -172,6 +173,11 @@ int arch_cpu_init(void)*/ mxs_gpio_init (); +#ifdef CONFIG_APBH_DMA +/* Start APBH DMA */ +mxs_dma_init (); +#endif + return 0; }#endif
arch/arm/include/asm/arch-mx28/dma.h +3 -1
@@ -140,6 +140,8 @@ void mxs_dma_desc_free(struct mxs_dma_desc *);int mxs_dma_desc_append (int channel,struct mxs_dma_desc *pdesc);int mxs_dma_go (int chan); -int mxs_dma_init (void ); +void mxs_dma_init (void ); +int mxs_dma_init_channel (int chan); +int mxs_dma_release (int chan);#endif /* __DMA_H__ */
drivers/dma/apbh_dma.c +16 -21
@@ -316,7 +316,7 @@ static int mxs_dma_request(int channel)* The channel will NOT be released if it's marked "busy" (see * mxs_dma_enable()). */ -static int mxs_dma_release (int channel) +int mxs_dma_release (int channel) {struct mxs_dma_chan *pchan;int ret;
@@ -552,12 +552,10 @@ int mxs_dma_go(int chan)/* * Initialize the DMA hardware */ -int mxs_dma_init (void ) +void mxs_dma_init (void ) {struct mx28_apbh_regs *apbh_regs = (struct mx28_apbh_regs *)MXS_APBH_BASE ; -struct mxs_dma_chan *pchan; -int ret, channel;mx28_reset_block (&apbh_regs->hw_apbh_ctrl0_reg);
@@ -576,28 +574,25 @@ int mxs_dma_init(void)writel (APBH_CTRL0_APB_BURST_EN , &apbh_regs->hw_apbh_ctrl0_clr);#endif +} -for (channel =0 ; channel <MXS_MAX_DMA_CHANNELS ; channel++) { - pchan = mxs_dma_channels + channel; - pchan->flags =MXS_DMA_FLAGS_VALID ; +int mxs_dma_init_channel (int channel) { +struct mxs_dma_chan *pchan; +int ret; - ret =mxs_dma_request (channel); + pchan = mxs_dma_channels + channel; + pchan->flags =MXS_DMA_FLAGS_VALID ; -if (ret) { -printf ("MXS DMA: Can't acquire DMA channel %i\n" , - channel); + ret =mxs_dma_request (channel); - goto err; - } - -mxs_dma_reset (channel); -mxs_dma_ack_irq (channel); +if (ret) { +printf ("MXS DMA: Can't acquire DMA channel %i\n" , + channel); +return ret; } -return 0 ; +mxs_dma_reset (channel); +mxs_dma_ack_irq (channel); -err: -while (--channel >=0 ) -mxs_dma_release (channel); -return ret; +return 0 ; }
drivers/mmc/mxsmmc.c +5 -0
@@ -338,6 +338,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int)) (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE ;struct mmc *mmc =NULL ;struct mxsmmc_priv *priv =NULL ; +int ret; mmc =malloc (sizeof (struct mmc ));if (!mmc)
@@ -356,6 +357,10 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int))return -ENOMEM ; } + ret =mxs_dma_init_channel (id); +if (ret) +return ret; + priv->mmc_is_wp = wp; priv->id = id;switch (id) {
drivers/mtd/nand/mxs_nand.c +11 -1
@@ -1058,7 +1058,7 @@ int mxs_nand_init(struct mxs_nand_info *info) {struct mx28_gpmi_regs *gpmi_regs = (struct mx28_gpmi_regs *)MXS_GPMI_BASE ; -int i =0 ; +int i =0 , j; info->desc =malloc (sizeof (struct mxs_dma_desc *) *MXS_NAND_DMA_DESCRIPTOR_COUNT );
@@ -1074,6 +1074,13 @@ int mxs_nand_init(struct mxs_nand_info *info)/* Init the DMA controller. */ mxs_dma_init (); +for (j =MXS_DMA_CHANNEL_AHB_APBH_GPMI0 ; + j <=MXS_DMA_CHANNEL_AHB_APBH_GPMI7 ; j++) + { + ret =mxs_dma_init_channel (j); +if (ret) + goto err3; + }/* Reset the GPMI block. */ mx28_reset_block (&gpmi_regs->hw_gpmi_ctrl0_reg);
@@ -1089,6 +1096,9 @@ int mxs_nand_init(struct mxs_nand_info *info)return 0 ; +err3: +for (--j; j >=0 ; j--) +mxs_dma_release (j); err2:free (info->desc); err1:
Signature · 1 line
1.7.9.1
PATCH v2 1/2 DMA: Split the APBH DMA init into block and channel init
This fixes the issue where mxs_dma_init() was called either twice or never, without introducing any new init hooks.
The idea is to allow each and every device using the APBH DMA block to configure and request only the channels it uses, instead of making it call init for all the channels as is now.
The common DMA block init part, which only configures the block, is then called from CPUs arch_cpu_init() call.
NOTE: This patch depends on:
http://patchwork.ozlabs.org/patch/150957/
--- arch/arm/cpu/arm926ejs/mx28/mx28.c | 6 +++++ arch/arm/include/asm/arch-mx28/dma.h | 4 ++- drivers/dma/apbh_dma.c | 37 ++++++++++++++------------------- drivers/mmc/mxsmmc.c | 5 ++++ drivers/mtd/nand/mxs_nand.c | 11 +++++++++- 5 files changed, 40 insertions(+), 23 deletions(-)
V2: Pardon my rebasing mistake:
mxs_nand.c: In function ?mxs_nand_init?:
mxs_nand.c:1080:3: error: ?ret? undeclared (first use in this function) mxs_nand.c:1080:3: note: each undeclared identifier is reported only once for each function it appears in
make[1]: *** [mxs_nand.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [drivers/mtd/nand/libnand.o] Error 2
make: *** Waiting for unfinished jobs....
arch/arm/cpu/arm926ejs/mx28/mx28.c +6 -0
@@ -30,6 +30,7 @@#include <asm/errno.h> #include <asm/io.h> #include <asm/arch/clock.h> +#include <asm/arch/dma.h> #include <asm/arch/gpio.h> #include <asm/arch/iomux.h> #include <asm/arch/imx-regs.h>
@@ -172,6 +173,11 @@ int arch_cpu_init(void)*/ mxs_gpio_init (); +#ifdef CONFIG_APBH_DMA +/* Start APBH DMA */ +mxs_dma_init (); +#endif + return 0; }#endif
arch/arm/include/asm/arch-mx28/dma.h +3 -1
@@ -140,6 +140,8 @@ void mxs_dma_desc_free(struct mxs_dma_desc *);int mxs_dma_desc_append (int channel,struct mxs_dma_desc *pdesc);int mxs_dma_go (int chan); -int mxs_dma_init (void ); +void mxs_dma_init (void ); +int mxs_dma_init_channel (int chan); +int mxs_dma_release (int chan);#endif /* __DMA_H__ */
drivers/dma/apbh_dma.c +16 -21
@@ -316,7 +316,7 @@ static int mxs_dma_request(int channel)* The channel will NOT be released if it's marked "busy" (see * mxs_dma_enable()). */ -static int mxs_dma_release (int channel) +int mxs_dma_release (int channel) {struct mxs_dma_chan *pchan;int ret;
@@ -552,12 +552,10 @@ int mxs_dma_go(int chan)/* * Initialize the DMA hardware */ -int mxs_dma_init (void ) +void mxs_dma_init (void ) {struct mx28_apbh_regs *apbh_regs = (struct mx28_apbh_regs *)MXS_APBH_BASE ; -struct mxs_dma_chan *pchan; -int ret, channel;mx28_reset_block (&apbh_regs->hw_apbh_ctrl0_reg);
@@ -576,28 +574,25 @@ int mxs_dma_init(void)writel (APBH_CTRL0_APB_BURST_EN , &apbh_regs->hw_apbh_ctrl0_clr);#endif +} -for (channel =0 ; channel <MXS_MAX_DMA_CHANNELS ; channel++) { - pchan = mxs_dma_channels + channel; - pchan->flags =MXS_DMA_FLAGS_VALID ; +int mxs_dma_init_channel (int channel) { +struct mxs_dma_chan *pchan; +int ret; - ret =mxs_dma_request (channel); + pchan = mxs_dma_channels + channel; + pchan->flags =MXS_DMA_FLAGS_VALID ; -if (ret) { -printf ("MXS DMA: Can't acquire DMA channel %i\n" , - channel); + ret =mxs_dma_request (channel); - goto err; - } - -mxs_dma_reset (channel); -mxs_dma_ack_irq (channel); +if (ret) { +printf ("MXS DMA: Can't acquire DMA channel %i\n" , + channel); +return ret; } -return 0 ; +mxs_dma_reset (channel); +mxs_dma_ack_irq (channel); -err: -while (--channel >=0 ) -mxs_dma_release (channel); -return ret; +return 0 ; }
drivers/mmc/mxsmmc.c +5 -0
@@ -338,6 +338,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int)) (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE ;struct mmc *mmc =NULL ;struct mxsmmc_priv *priv =NULL ; +int ret; mmc =malloc (sizeof (struct mmc ));if (!mmc)
@@ -356,6 +357,10 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int))return -ENOMEM ; } + ret =mxs_dma_init_channel (id); +if (ret) +return ret; + priv->mmc_is_wp = wp; priv->id = id;switch (id) {
drivers/mtd/nand/mxs_nand.c +10 -1
@@ -1058,7 +1058,7 @@ int mxs_nand_init(struct mxs_nand_info *info) {struct mx28_gpmi_regs *gpmi_regs = (struct mx28_gpmi_regs *)MXS_GPMI_BASE ; -int i =0 ; +int i =0 , j; info->desc =malloc (sizeof (struct mxs_dma_desc *) *MXS_NAND_DMA_DESCRIPTOR_COUNT );
@@ -1074,6 +1074,12 @@ int mxs_nand_init(struct mxs_nand_info *info)/* Init the DMA controller. */ mxs_dma_init (); +for (j =MXS_DMA_CHANNEL_AHB_APBH_GPMI0 ; + j <=MXS_DMA_CHANNEL_AHB_APBH_GPMI7 ; j++) + { +if (mxs_dma_init_channel (j)); + goto err3; + }/* Reset the GPMI block. */ mx28_reset_block (&gpmi_regs->hw_gpmi_ctrl0_reg);
@@ -1089,6 +1095,9 @@ int mxs_nand_init(struct mxs_nand_info *info)return 0 ; +err3: +for (--j; j >=0 ; j--) +mxs_dma_release (j); err2:free (info->desc); err1:
Signature · 1 line
1.7.9.1
PATCH v3 1/2 DMA: Split the APBH DMA init into block and channel init
This fixes the issue where mxs_dma_init() was called either twice or never, without introducing any new init hooks.
The idea is to allow each and every device using the APBH DMA block to configure and request only the channels it uses, instead of making it call init for all the channels as is now.
The common DMA block init part, which only configures the block, is then called from CPUs arch_cpu_init() call.
NOTE: This patch depends on:
http://patchwork.ozlabs.org/patch/150957/
--- arch/arm/cpu/arm926ejs/mx28/mx28.c | 6 +++++ arch/arm/include/asm/arch-mx28/dma.h | 4 ++- drivers/dma/apbh_dma.c | 37 ++++++++++++++------------------- drivers/mmc/mxsmmc.c | 5 ++++ drivers/mtd/nand/mxs_nand.c | 12 +++++++++- 5 files changed, 40 insertions(+), 24 deletions(-)
V2: Rebasing mistake
V3: Rebasing mistake (forgotten mxs_dma_init() in NAND init code)
arch/arm/cpu/arm926ejs/mx28/mx28.c +6 -0
@@ -30,6 +30,7 @@#include <asm/errno.h> #include <asm/io.h> #include <asm/arch/clock.h> +#include <asm/arch/dma.h> #include <asm/arch/gpio.h> #include <asm/arch/iomux.h> #include <asm/arch/imx-regs.h>
@@ -172,6 +173,11 @@ int arch_cpu_init(void)*/ mxs_gpio_init (); +#ifdef CONFIG_APBH_DMA +/* Start APBH DMA */ +mxs_dma_init (); +#endif + return 0; }#endif
arch/arm/include/asm/arch-mx28/dma.h +3 -1
@@ -140,6 +140,8 @@ void mxs_dma_desc_free(struct mxs_dma_desc *);int mxs_dma_desc_append (int channel,struct mxs_dma_desc *pdesc);int mxs_dma_go (int chan); -int mxs_dma_init (void ); +void mxs_dma_init (void ); +int mxs_dma_init_channel (int chan); +int mxs_dma_release (int chan);#endif /* __DMA_H__ */
drivers/dma/apbh_dma.c +16 -21
@@ -316,7 +316,7 @@ static int mxs_dma_request(int channel)* The channel will NOT be released if it's marked "busy" (see * mxs_dma_enable()). */ -static int mxs_dma_release (int channel) +int mxs_dma_release (int channel) {struct mxs_dma_chan *pchan;int ret;
@@ -552,12 +552,10 @@ int mxs_dma_go(int chan)/* * Initialize the DMA hardware */ -int mxs_dma_init (void ) +void mxs_dma_init (void ) {struct mx28_apbh_regs *apbh_regs = (struct mx28_apbh_regs *)MXS_APBH_BASE ; -struct mxs_dma_chan *pchan; -int ret, channel;mx28_reset_block (&apbh_regs->hw_apbh_ctrl0_reg);
@@ -576,28 +574,25 @@ int mxs_dma_init(void)writel (APBH_CTRL0_APB_BURST_EN , &apbh_regs->hw_apbh_ctrl0_clr);#endif +} -for (channel =0 ; channel <MXS_MAX_DMA_CHANNELS ; channel++) { - pchan = mxs_dma_channels + channel; - pchan->flags =MXS_DMA_FLAGS_VALID ; +int mxs_dma_init_channel (int channel) { +struct mxs_dma_chan *pchan; +int ret; - ret =mxs_dma_request (channel); + pchan = mxs_dma_channels + channel; + pchan->flags =MXS_DMA_FLAGS_VALID ; -if (ret) { -printf ("MXS DMA: Can't acquire DMA channel %i\n" , - channel); + ret =mxs_dma_request (channel); - goto err; - } - -mxs_dma_reset (channel); -mxs_dma_ack_irq (channel); +if (ret) { +printf ("MXS DMA: Can't acquire DMA channel %i\n" , + channel); +return ret; } -return 0 ; +mxs_dma_reset (channel); +mxs_dma_ack_irq (channel); -err: -while (--channel >=0 ) -mxs_dma_release (channel); -return ret; +return 0 ; }
drivers/mmc/mxsmmc.c +5 -0
@@ -338,6 +338,7 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int)) (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE ;struct mmc *mmc =NULL ;struct mxsmmc_priv *priv =NULL ; +int ret; mmc =malloc (sizeof (struct mmc ));if (!mmc)
@@ -356,6 +357,10 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int))return -ENOMEM ; } + ret =mxs_dma_init_channel (id); +if (ret) +return ret; + priv->mmc_is_wp = wp; priv->id = id;switch (id) {
drivers/mtd/nand/mxs_nand.c +10 -2
@@ -1058,7 +1058,7 @@ int mxs_nand_init(struct mxs_nand_info *info) {struct mx28_gpmi_regs *gpmi_regs = (struct mx28_gpmi_regs *)MXS_GPMI_BASE ; -int i =0 ; +int i =0 , j; info->desc =malloc (sizeof (struct mxs_dma_desc *) *MXS_NAND_DMA_DESCRIPTOR_COUNT );
@@ -1073,7 +1073,12 @@ int mxs_nand_init(struct mxs_nand_info *info) }/* Init the DMA controller. */ -mxs_dma_init (); +for (j =MXS_DMA_CHANNEL_AHB_APBH_GPMI0 ; + j <=MXS_DMA_CHANNEL_AHB_APBH_GPMI7 ; j++) + { +if (mxs_dma_init_channel (j)) + goto err3; + }/* Reset the GPMI block. */ mx28_reset_block (&gpmi_regs->hw_gpmi_ctrl0_reg);
@@ -1089,6 +1094,9 @@ int mxs_nand_init(struct mxs_nand_info *info)return 0 ; +err3: +for (--j; j >=0 ; j--) +mxs_dma_release (j); err2:free (info->desc); err1:
Signature · 1 line
1.7.9.1
Fabio Estevam
reviewerPATCH v3 1/2 DMA: Split the APBH DMA init into block and channel init
Quoted 12 lines · Marek Vasut
This fixes the issue where
mxs_dma_init()was called either twice or never, without introducing any new init hooks.The idea is to allow each and every device using the APBH DMA block to configure and request only the channels it uses, instead of making it call init for all the channels as is now.
The common DMA block init part, which only configures the block, is then called from CPUs
arch_cpu_init()call.NOTE: This patch depends on:
Quoted 7 lines
? ? ? ?http://patchwork.ozlabs.org/patch/150957/
Signed-off-by Marek Vasut <[email protected]>Cc Stefano Babic <[email protected]>Cc Wolfgang Denk <[email protected]>Cc Detlev Zundel <[email protected]>Cc Fabio Estevam <[email protected]>
This fixes the mmc issue on mx28.
PATCH v3 1/2 DMA: Split the APBH DMA init into block and channel init
In reply to Marek VasutQuoted 12 lines · Marek Vasut
This fixes the issue where
mxs_dma_init()was called either twice or never, without introducing any new init hooks.The idea is to allow each and every device using the APBH DMA block to configure and request only the channels it uses, instead of making it call init for all the channels as is now.
The common DMA block init part, which only configures the block, is then called from CPUs
arch_cpu_init()call.NOTE: This patch depends on:
Quoted 8 lines
http://patchwork.ozlabs.org/patch/150957/Signed-off-by Marek Vasut <[email protected]>Cc Stefano Babic <[email protected]>Cc Wolfgang Denk <[email protected]>Cc Detlev Zundel <[email protected]>Cc Fabio Estevam <[email protected]>---
After fixing the following checkpatch errors:
ERROR: open brace '{' following function declarations go on the next line #120: FILE: drivers/dma/apbh_dma.c:579:
+int mxs_dma_init_channel(int channel) {
ERROR: that open brace { should be on the previous line #195: FILE: drivers/mtd/nand/mxs_nand.c:1076:
+ for (j = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
+ j <= MXS_DMA_CHANNEL_AHB_APBH_GPMI7; j++)
+ {
total: 2 errors, 0 warnings, 137 lines checked
Applied to u-boot-imx, thanks.
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: [email protected] =====================================================================
PATCH 2/2 M28: Pull out CONFIG_APBH_DMA so it's always enabled
In reply to Marek VasutThe ABPH DMA is now used also by the SD card. Therefore it has to be enabled even if NAND is disabled.
--- include/configs/m28evk.h | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-)
include/configs/m28evk.h +5 -1
@@ -147,12 +147,16 @@#endif /* +* APBH DMA +*/ +#define CONFIG_APBH_DMA + +/* * NAND */ #define CONFIG_ENV_SIZE (16 * 1024)#ifdef CONFIG_CMD_NAND #define CONFIG_NAND_MXS -#define CONFIG_APBH_DMA #define CONFIG_SYS_MAX_NAND_DEVICE 1#define CONFIG_SYS_NAND_BASE 0x60000000#define CONFIG_SYS_NAND_5_ADDR_CYCLE
Signature · 1 line
1.7.9.1
PATCH 2/2 M28: Pull out CONFIG_APBH_DMA so it's always enabled
Quoted 9 lines · Marek Vasut
The ABPH DMA is now used also by the SD card. Therefore it has to be enabled even if NAND is disabled.
Signed-off-by Marek Vasut <[email protected]>Cc Stefano Babic <[email protected]>Cc Wolfgang Denk <[email protected]>Cc Detlev Zundel <[email protected]>Cc Fabio Estevam <[email protected]>---
Applied to u-boot-imx, thanks.
Best regards,
Stefano Babic
Signature · 5 lines
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de =====================================================================
cover i.MX28: DMA fixups
In reply to Marek VasutDear Marek Vasut,
Quoted 19 lines
This patchset fixes DMA issues found on Freescale MX28EVK.
NOTE: This patch depends on:
http://patchwork.ozlabs.org/patch/150957/Marek Vasut (2):
DMA: Split the APBH DMA init into block and channel init
M28: Pull outCONFIG_APBH_DMAso it's always enabledarch/arm/cpu/arm926ejs/mx28/mx28.c | 6 +++++ arch/arm/include/asm/arch-mx28/dma.h | 4 ++- drivers/dma/apbh_dma.c | 37 ++++++++++++++------------------- drivers/mmc/mxsmmc.c | 5 ++++ drivers/mtd/nand/mxs_nand.c | 12 ++++++++++- include/configs/m28evk.h | 6 ++++- 6 files changed, 46 insertions(+), 24 deletions(-)
Quoted 4 lines
Cc Stefano Babic <[email protected]>Cc Wolfgang Denk <[email protected]>Cc Detlev Zundel <[email protected]>Cc Fabio Estevam <[email protected]>
Fabio, I'd like to merge this into -RC2 in favor of your patch. I think this way is better. Can you please test this and give Ack/Nak/T-B ASAP?
Thanks very much in advance!
Best regards,
Marek Vasut