From mboxrd@z Thu Jan 1 00:00:00 1970 From: Marek Vasut Date: Wed, 29 Jul 2015 18:36:59 +0200 Subject: [U-Boot] [PATCH v2 1/4] dma: lpc32xx: add DMA driver In-Reply-To: <1438186450-4076-2-git-send-email-slemieux.tyco@gmail.com> References: <1438186450-4076-2-git-send-email-slemieux.tyco@gmail.com> Message-ID: <201507291836.59999.marex@denx.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Wednesday, July 29, 2015 at 06:14:07 PM, slemieux.tyco at gmail.com wrote: > From: Sylvain Lemieux > > 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 to integrate with the latest u-boot. > > Signed-off-by: Sylvain Lemieux [...] > diff --git a/drivers/dma/lpc32xx_dma.c b/drivers/dma/lpc32xx_dma.c > new file mode 100644 > index 0000000..feb16ce > --- /dev/null > +++ b/drivers/dma/lpc32xx_dma.c > @@ -0,0 +1,153 @@ > +/* > + * Copyright (C) 2008-2015 by NXP Semiconductors > + * All rights reserved. > + * > + * @Author: Kevin Wells > + * @Descr: LPC3250 DMA controller interface support functions > + * > + * See file CREDITS for list of people who contributed to this > + * project. > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* Some optimization stuff */ > +#ifndef unlikely > +#define likely(x) __builtin_expect(!!(x), 1) > +#define unlikely(x) __builtin_expect(!!(x), 0) > +#endif This is defined in include/compiler.h > +/* bit position macro */ > +#define _BIT(n) (0x1 << (n)) Drop this as well please. > +/* DMA controller channel register structure */ > +struct dmac_chan_reg { > + uint32_t src_addr; > + uint32_t dest_addr; > + uint32_t lli; > + uint32_t control; > + uint32_t config_ch; > + uint32_t reserved[3]; > +}; > + > +/* DMA controller register structures */ > +struct dma_reg { > + uint32_t int_stat; > + uint32_t int_tc_stat; > + uint32_t int_tc_clear; > + uint32_t int_err_stat; > + uint32_t int_err_clear; > + uint32_t raw_tc_stat; > + uint32_t raw_err_stat; > + uint32_t chan_enable; > + uint32_t sw_burst_req; > + uint32_t sw_single_req; > + uint32_t sw_last_burst_req; > + uint32_t sw_last_single_req; > + uint32_t config; > + uint32_t sync; > + uint32_t reserved[50]; > + struct dmac_chan_reg dma_chan[8]; > +}; > + > +/* Macro pointing to DMA registers */ > +#define DMA_NO_OF_CHANNELS 8 > + > +/* config register definitions */ > +#define DMAC_CTRL_ENABLE (1 << 0) /* For enabling the DMA controller */ > + > +static uint32_t alloc_ch; > + > +static struct dma_reg *dma = (struct dma_reg *)DMA_BASE; > + > +int lpc32xx_dma_get_channel(void) > +{ > + int i; > + uint32_t status = 0; > + > + if (!alloc_ch) { /* First time caller */ > + /* DMA clock are enable by "lpc32xx_dma_init()" and should > + * be call by board "board_early_init_f()" function. */ > + > + /* Make sure DMA controller and all channels are disabled. > + * Controller is in little-endian mode. Disable sync signals */ > + writel(0, &dma->config); > + writel(0, &dma->sync); > + > + /* Clear interrupt and error statuses */ > + writel(0xFF, &dma->int_tc_clear); > + writel(0xFF, &dma->raw_tc_stat); > + writel(0xFF, &dma->int_err_clear); > + writel(0xFF, &dma->raw_err_stat); > + > + /* Enable DMA controller */ > + writel(DMAC_CTRL_ENABLE, &dma->config); > + } > + > + for (i = 0; i < DMA_NO_OF_CHANNELS && (status & _BIT(i)); i++) > + ; I think you should look at ffs() and fls() in include/linux/bitops.h here. [...]