Skip to contentSkip to conversation

dma: lpc32xx: add DMA driver

PATCH New slemieux.tyco at gmail.com 3 participants 4 messages Aug 4, 2015 – Aug 5, 2015

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH v4 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 v3 to v4:
* Addressed Marek's comments on LPC32xx DMA driver:
- updated multiline comments style.
- use "u32" instead of "uint32_t".
- fixed unbounded loop.

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       |  44 ++++++++
 arch/arm/include/asm/arch-lpc32xx/sys_proto.h |   1 +
 drivers/dma/Makefile                          |   1 +
 drivers/dma/lpc32xx_dma.c                     | 157 ++++++++++++++++++++++++++
 6 files changed, 212 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
index c0c9c6c..0d2ef7a 100644
@@ -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
index 010211a..663f6bc 100644
@@ -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 +44 -0

44 lines not on this page · raw message

arch/arm/include/asm/arch-lpc32xx/sys_proto.h +1 -0
index 0845f83..7f997d9 100644
@@ -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
index 4c8fcc2..f95fe70 100644
@@ -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 +157 -0

157 lines not on this page · raw message

Signature · 1 line
1.8.3.1
#1 lore raw

PATCH v4 1/5 dma: lpc32xx: add DMA driver

Quoted 11 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.

The legacy driver was updated and clean-up as part of the integration with the latest u-boot.

[...]

arch/arm/include/asm/arch-lpc32xx/dma.h line 28

Quoted 10 lines
arch/arm/include/asm/arch-lpc32xx/dma.h new file +10 -0
+
+/*
+ * The "dmac_ll" structure is mapping the DMA channel register,
+ * 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.
+ */
+#define lpc32xx_dmac_next_lli(x) (uint32_t)x

Ew, and it's not even used :-)

Quoted 7 lines
arch/arm/include/asm/arch-lpc32xx/dma.h new file +7 -0
+/* DMA linked list structure used with a channel's LLI register */
+struct lpc32xx_dmac_ll {
+	u32 dma_src;
+	u32 dma_dest;
+	u32 next_lli;
+	u32 next_ctrl;
+};

[...]

drivers/dma/lpc32xx_dma.c line 121

Quoted 6 lines
drivers/dma/lpc32xx_dma.c new file +6 -0
+int lpc32xx_dma_wait_status(int channel)
+{
+	unsigned long start;
+
+	start = get_timer(0);
+	while (1) {

Here , you can do

reg = readl();
reg |= readl();
if (reg & BIT_MASK())

    break;
Quoted 9 lines
drivers/dma/lpc32xx_dma.c new file +9 -0
+		if (((readl(&dma->raw_tc_stat) | readl(dma->raw_err_stat))
+		     & BIT_MASK(channel)) != 0)
+			break;
+
+		if (get_timer(start) > 10000)
+			return -1;
+
+		udelay(1);
+	}

drivers/dma/lpc32xx_dma.c line 140

Quoted 10 lines
drivers/dma/lpc32xx_dma.c new file +10 -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;
+}

Other than that,

#2 lore raw

PATCH v4 1/5 dma: lpc32xx: add DMA driver

Hi Marek,

See comment and question below.

Quoted 19 lines

-----Original Message-----
From: Marek Vasut [mailto:marex at denx.de]
Sent: 4-Aug-15 5:32 PM

Quoted 11 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.

The legacy driver was updated and clean-up as part of the integration with the latest u-boot.

[...]

Quoted 12 lines

arch/arm/include/asm/arch-lpc32xx/dma.h line 28

Quoted 10 lines
arch/arm/include/asm/arch-lpc32xx/dma.h new file +10 -0
+
+/*
+ * The "dmac_ll" structure is mapping the DMA channel register,
+ * 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.
+ */
+#define lpc32xx_dmac_next_lli(x) (uint32_t)x

Ew, and it's not even used :-)

This is used inside "drivers/mtd/nand/lpc32xx_nand_slc.c"; Refer to this patch for details: https://patchwork.ozlabs.org/patch/503815/

Are we OK to keep this define there?

Quoted 20 lines
Quoted 8 lines
arch/arm/include/asm/arch-lpc32xx/dma.h new file +7 -0
+/* DMA linked list structure used with a channel's LLI register */
+struct lpc32xx_dmac_ll {
+   u32 dma_src;
+   u32 dma_dest;
+   u32 next_lli;
+   u32 next_ctrl;
+};

[...]

drivers/dma/lpc32xx_dma.c line 121

Quoted 6 lines
drivers/dma/lpc32xx_dma.c new file +6 -0
+int lpc32xx_dma_wait_status(int channel)
+{
+   unsigned long start;
+
+   start = get_timer(0);
+   while (1) {

Here , you can do

Quoted 5 lines

reg = readl();
reg |= readl();
if (reg & BIT_MASK())

    break;

Will update the patch.

Quoted 22 lines
Quoted 9 lines
drivers/dma/lpc32xx_dma.c new file +9 -0
+           if (((readl(&dma->raw_tc_stat) | readl(dma->raw_err_stat))
+                & BIT_MASK(channel)) != 0)
+                   break;
+
+           if (get_timer(start) > 10000)
+                   return -1;
+
+           udelay(1);
+   }

drivers/dma/lpc32xx_dma.c line 140

Quoted 10 lines
drivers/dma/lpc32xx_dma.c new file +10 -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;
+}

Other than that,

Quoted 1 line

________________________________

This e-mail contains privileged and confidential information intended for the use of the addressees named above. If you are not the intended recipient of this e-mail, you are hereby notified that you must not disseminate, copy or take any action in respect of any information contained in it. If you have received this e-mail in error, please notify the sender immediately by e-mail and immediately destroy this e-mail and its attachments.

#3 lore raw

PATCH v4 1/5 dma: lpc32xx: add DMA driver

Quoted 1 line · SYLVAIN

Hi Marek,

Hi!

Quoted 34 lines

See comment and question below.

Quoted 19 lines

-----Original Message-----
From: Marek Vasut [mailto:marex at denx.de]
Sent: 4-Aug-15 5:32 PM

Quoted 11 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.

The legacy driver was updated and clean-up as part of the integration with the latest u-boot.

[...]

Quoted 12 lines

arch/arm/include/asm/arch-lpc32xx/dma.h line 28

Quoted 10 lines
arch/arm/include/asm/arch-lpc32xx/dma.h new file +10 -0
+
+/*
+ * The "dmac_ll" structure is mapping the DMA channel register,
+ * 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.
+ */
+#define lpc32xx_dmac_next_lli(x) (uint32_t)x

Ew, and it's not even used :-)

Quoted 4 lines

This is used inside "drivers/mtd/nand/lpc32xx_nand_slc.c"; Refer to this patch for details: https://patchwork.ozlabs.org/patch/503815/

Are we OK to keep this define there?

Sorry, I didn't realize that. But in that case, just use (x) in lpc32xx_nand_slc.c ? The macro is only obfuscating the code.

Also, the macro is wrong, not only does it do explicit cast (not a very nice thing to do), but it also doens't put parenthesis around the x, which can have ugly impacts.

Best regards,
Marek Vasut