dma: lpc32xx: add DMA driver
Subsystems (3)
PATCH v3 1/5 dma: lpc32xx: add DMA driver
From: Sylvain Lemieux <[email protected]>
Incorporate DMA driver from legacy LPCLinux NXP BSP. The files taken from the legacy patch are:
- lpc32xx DMA driver
- lpc3250 header file DMA registers definition.
The legacy driver was updated and clean-up as part of the integration with the latest u-boot.
---
Changes from v2 to v3:
* Addressed Marek's comments on LPC32xx DMA driver:
- use defined in header file instead of local definition.
- remove for loop and use "ffz()".
* Provide define to assign next DMA linked list item address to removed typecast in DMA client (ex. NAND SLC).
Changes from v1 to v2:
* Moved the DMA patch as the first patch of the series.
* The NAND SLC patch (link below) is applied before this
patch: https://patchwork.ozlabs.org/patch/497308/
Update to the legacy driver to integrate with the latest u-boot:
1) Fixed checkpatch script output in legacy code.
2) Use LPC32xx definition from "cpu.h" and "clk.h".
3) Incorporate DMA specific register definition from "lpc3250.h" header file from legacy BSP patch from LPCLinux.
4) Use u-boot API for register access to remove the volatile in register definition taken from "lpc3250.h" header file.
5) Add DMA interface to "dma.h".
6) Add dma clock control register bits (clk.h).
7) Add functions to initialize the DMA clock.
The legacy BSP patch (u-boot-2009.03_lpc32x0-v1.07.patch.tar.bz2) was downloaded from the LPCLinux Web site.
arch/arm/cpu/arm926ejs/lpc32xx/devices.c | 6 ++ arch/arm/include/asm/arch-lpc32xx/clk.h | 3 + arch/arm/include/asm/arch-lpc32xx/dma.h | 42 ++++++++ arch/arm/include/asm/arch-lpc32xx/sys_proto.h | 1 + drivers/dma/Makefile | 1 + drivers/dma/lpc32xx_dma.c | 147 ++++++++++++++++++++++++++ 6 files changed, 200 insertions(+) create mode 100644 arch/arm/include/asm/arch-lpc32xx/dma.h create mode 100644 drivers/dma/lpc32xx_dma.c
arch/arm/cpu/arm926ejs/lpc32xx/devices.c +6 -0
@@ -65,6 +65,12 @@ void lpc32xx_slc_nand_init(void)writel (CLK_NAND_SLC |CLK_NAND_SLC_SELECT , &clk->flashclk_ctrl); } +void lpc32xx_dma_init (void ) +{ +/* Enable DMA interface */ +setbits_le32 (&clk->dmaclk_ctrl,DMA_CLK_ENABLE ); +} +void lpc32xx_i2c_init (unsigned int devnum) {/* Enable I2C interface */
arch/arm/include/asm/arch-lpc32xx/clk.h +3 -0
@@ -158,6 +158,9 @@ struct clk_pm_regs {#define CLK_NAND_SLC_SELECT (1 << 2)#define CLK_NAND_MLC_INT (1 << 5) +/* DMA Clock Control Register bits */ +#define DMA_CLK_ENABLE (1 << 0) +/* SSP Clock Control Register bits */ #define CLK_SSP0_ENABLE_CLOCK (1 << 0)
arch/arm/include/asm/arch-lpc32xx/dma.h new file +42 -0
42 lines not on this page · raw message
arch/arm/include/asm/arch-lpc32xx/sys_proto.h +1 -0
@@ -13,6 +13,7 @@ void lpc32xx_uart_init(unsigned int uart_id);void lpc32xx_mac_init (void );void lpc32xx_mlc_nand_init (void );void lpc32xx_slc_nand_init (void ); +void lpc32xx_dma_init (void );void lpc32xx_i2c_init (unsigned int devnum);void lpc32xx_ssp_init (void );#if defined(CONFIG_SPL_BUILD )
drivers/dma/Makefile +1 -0
@@ -10,3 +10,4 @@ obj-$(CONFIG_APBH_DMA) += apbh_dma.o obj-$(CONFIG_FSL_DMA) += fsl_dma.o obj-$(CONFIG_TI_KSNAV) += keystone_nav.o keystone_nav_cfg.o obj-$(CONFIG_TI_EDMA3) += ti-edma3.o +obj-$(CONFIG_DMA_LPC32XX) += lpc32xx_dma.o
drivers/dma/lpc32xx_dma.c new file +147 -0
147 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v3 1/5 dma: lpc32xx: add DMA driver
Quoted 7 lines · slemieux.tyco at gmail.com
From: Sylvain Lemieux <[email protected]>
Incorporate DMA driver from legacy LPCLinux NXP BSP. The files taken from the legacy patch are:
- lpc32xx DMA driver
- lpc3250 header file DMA registers definition.
Quoted 5 lines
The legacy driver was updated and clean-up as part of the integration with the latest u-boot.
Signed-off-by Sylvain Lemieux <[email protected]>---
[...]
OK, let me nag a bit more ... :-)
arch/arm/include/asm/arch-lpc32xx/dma.h line 20
Quoted 4 lines
arch/arm/include/asm/arch-lpc32xx/dma.h new file +4
-0+#include <common.h> + + +/* The "dmac_ll" structure is mapping the DMA channel register,
The multiline comments (in Linux and U-Boot) have this form:
/*
* foo
* bar
*/
arch/arm/include/asm/arch-lpc32xx/dma.h line 33
Quoted 13 lines
+ * as per UM10326, "LPC32x0 and LPC32x0/01 User manual" - Rev. 3
+ * tables 84, 85, 86 & 87.
+ *
+ * The DMA client (ex. NAND SLC) can use this macro to write the
+ * next DMA linked list item address. */arch/arm/include/asm/arch-lpc32xx/dma.h new file +8
-0+#define lpc32xx_dmac_next_lli (x) (uint32_t)x + +/* DMA linked list structure used with a channel's LLI register */ +struct lpc32xx_dmac_ll { +uint32_t dma_src; +uint32_t dma_dest; +uint32_t next_lli; +uint32_t next_ctrl;
uintNNt should not be used, uNN should be used instead. This is to avoid conflict with stdint.h , which is userspace-only.
Quoted 9 lines
arch/arm/include/asm/arch-lpc32xx/dma.h new file +4
-0+}; + +int lpc32xx_dma_get_channel (void ); +int lpc32xx_dma_start_xfer(int channel, const struct lpc32xx_dmac_ll*desc, +
uint32_tconfig);arch/arm/include/asm/arch-lpc32xx/dma.h new file +4
-0+int lpc32xx_dma_wait_status (int channel); +void lpc32xx_dma_put_channel (int channel); + +#endif /* _LPC32XX_DMA_H */
[...]
drivers/dma/lpc32xx_dma.c line 120
Quoted 5 lines
drivers/dma/lpc32xx_dma.c new file +5
-0+int lpc32xx_dma_wait_status (int channel) +{ +while (((readl (&dma->raw_tc_stat) |readl (dma->raw_err_stat)) + &BIT_MASK (channel)) ==0 ) + ;
Looksie, an unbounded loop :-)
drivers/dma/lpc32xx_dma.c line 130
Quoted 9 lines
drivers/dma/lpc32xx_dma.c new file +9
-0+if (unlikely (readl (&dma->raw_err_stat) &BIT_MASK (channel))) { +setbits_le32 (&dma->int_err_clear,BIT_MASK (channel)); +setbits_le32 (&dma->raw_err_stat,BIT_MASK (channel)); +return -1 ; + } +setbits_le32 (&dma->int_tc_clear,BIT_MASK (channel)); +setbits_le32 (&dma->raw_tc_stat,BIT_MASK (channel)); +return 0 ; +}
[...]
Looks much better than before though :-)