From 1ec1e82f2510e2bdcb6268ed74aa79e1a7bc9594 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 30 Sep 2010 13:56:34 +0000 Subject: dmaengine: Add Freescale i.MX SDMA support This patch adds support for the Freescale i.MX SDMA engine. The SDMA engine is a scatter/gather DMA engine which is implemented as a seperate coprocessor. SDMA needs its own firmware which is requested using the standard request_firmware mechanism. The firmware has different entry points for each peripheral type, so drivers have to pass the peripheral type to the DMA engine which in turn picks the correct firmware entry point from a table contained in the firmware image itself. The original Freescale code also supports support for transfering data to the internal SRAM which needs different entry points to the firmware. Support for this is currently not implemented. Also, support for the ASRC (asymmetric sample rate converter) is skipped. I took a very simple approach to implement dmaengine support. Only a single descriptor is statically assigned to a each channel. This means that transfers can't be queued up but only a single transfer is in progress. This simplifies implementation a lot and is sufficient for the usual device/memory transfers. Signed-off-by: Sascha Hauer Reviewed-by: Linus Walleij Signed-off-by: Dan Williams --- arch/arm/mach-imx/include/mach/dma-v1.h | 8 +--- arch/arm/plat-mxc/include/mach/dma.h | 67 +++++++++++++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/sdma.h | 17 +++++++++ 3 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 arch/arm/plat-mxc/include/mach/dma.h create mode 100644 arch/arm/plat-mxc/include/mach/sdma.h (limited to 'arch') diff --git a/arch/arm/mach-imx/include/mach/dma-v1.h b/arch/arm/mach-imx/include/mach/dma-v1.h index 287431cc13e5..ac6fd713828a 100644 --- a/arch/arm/mach-imx/include/mach/dma-v1.h +++ b/arch/arm/mach-imx/include/mach/dma-v1.h @@ -27,6 +27,8 @@ #define imx_has_dma_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) +#include + #define IMX_DMA_CHANNELS 16 #define DMA_MODE_READ 0 @@ -96,12 +98,6 @@ int imx_dma_request(int channel, const char *name); void imx_dma_free(int channel); -enum imx_dma_prio { - DMA_PRIO_HIGH = 0, - DMA_PRIO_MEDIUM = 1, - DMA_PRIO_LOW = 2 -}; - int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio); #endif /* __MACH_DMA_V1_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/dma.h b/arch/arm/plat-mxc/include/mach/dma.h new file mode 100644 index 000000000000..ef7751546f5f --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/dma.h @@ -0,0 +1,67 @@ +/* + * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __ASM_ARCH_MXC_DMA_H__ +#define __ASM_ARCH_MXC_DMA_H__ + +#include +#include +#include + +/* + * This enumerates peripheral types. Used for SDMA. + */ +enum sdma_peripheral_type { + IMX_DMATYPE_SSI, /* MCU domain SSI */ + IMX_DMATYPE_SSI_SP, /* Shared SSI */ + IMX_DMATYPE_MMC, /* MMC */ + IMX_DMATYPE_SDHC, /* SDHC */ + IMX_DMATYPE_UART, /* MCU domain UART */ + IMX_DMATYPE_UART_SP, /* Shared UART */ + IMX_DMATYPE_FIRI, /* FIRI */ + IMX_DMATYPE_CSPI, /* MCU domain CSPI */ + IMX_DMATYPE_CSPI_SP, /* Shared CSPI */ + IMX_DMATYPE_SIM, /* SIM */ + IMX_DMATYPE_ATA, /* ATA */ + IMX_DMATYPE_CCM, /* CCM */ + IMX_DMATYPE_EXT, /* External peripheral */ + IMX_DMATYPE_MSHC, /* Memory Stick Host Controller */ + IMX_DMATYPE_MSHC_SP, /* Shared Memory Stick Host Controller */ + IMX_DMATYPE_DSP, /* DSP */ + IMX_DMATYPE_MEMORY, /* Memory */ + IMX_DMATYPE_FIFO_MEMORY,/* FIFO type Memory */ + IMX_DMATYPE_SPDIF, /* SPDIF */ + IMX_DMATYPE_IPU_MEMORY, /* IPU Memory */ + IMX_DMATYPE_ASRC, /* ASRC */ + IMX_DMATYPE_ESAI, /* ESAI */ +}; + +enum imx_dma_prio { + DMA_PRIO_HIGH = 0, + DMA_PRIO_MEDIUM = 1, + DMA_PRIO_LOW = 2 +}; + +struct imx_dma_data { + int dma_request; /* DMA request line */ + enum sdma_peripheral_type peripheral_type; + int priority; +}; + +static inline int imx_dma_is_ipu(struct dma_chan *chan) +{ + return !strcmp(dev_name(chan->device->dev), "ipu-core"); +} + +static inline int imx_dma_is_general_purpose(struct dma_chan *chan) +{ + return !strcmp(dev_name(chan->device->dev), "imx-sdma") || + !strcmp(dev_name(chan->device->dev), "imx-dma"); +} + +#endif diff --git a/arch/arm/plat-mxc/include/mach/sdma.h b/arch/arm/plat-mxc/include/mach/sdma.h new file mode 100644 index 000000000000..9be112227ac4 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/sdma.h @@ -0,0 +1,17 @@ +#ifndef __MACH_MXC_SDMA_H__ +#define __MACH_MXC_SDMA_H__ + +/** + * struct sdma_platform_data - platform specific data for SDMA engine + * + * @sdma_version The version of this SDMA engine + * @cpu_name used to generate the firmware name + * @to_version CPU Tape out version + */ +struct sdma_platform_data { + int sdma_version; + char *cpu_name; + int to_version; +}; + +#endif /* __MACH_MXC_SDMA_H__ */ -- cgit v1.2.2 From 968f19ae802fdc6b6b6b5af6fe79cf23d281be0f Mon Sep 17 00:00:00 2001 From: Ira Snyder Date: Thu, 30 Sep 2010 11:46:46 +0000 Subject: fsldma: improved DMA_SLAVE support Now that the generic DMAEngine API has support for scatterlist to scatterlist copying, the device_prep_slave_sg() portion of the DMA_SLAVE API is no longer necessary and has been removed. However, the device_control() portion of the DMA_SLAVE API is still useful to control device specific parameters, such as externally controlled DMA transfers and maximum burst length. A special dma_ctrl_cmd has been added to enable externally controlled DMA transfers. This is currently specific to the Freescale DMA controller, but can easily be made generic when another user is found. Signed-off-by: Ira W. Snyder Signed-off-by: Dan Williams --- arch/powerpc/include/asm/fsldma.h | 137 -------------------------------------- 1 file changed, 137 deletions(-) delete mode 100644 arch/powerpc/include/asm/fsldma.h (limited to 'arch') diff --git a/arch/powerpc/include/asm/fsldma.h b/arch/powerpc/include/asm/fsldma.h deleted file mode 100644 index debc5ed96d6e..000000000000 --- a/arch/powerpc/include/asm/fsldma.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Freescale MPC83XX / MPC85XX DMA Controller - * - * Copyright (c) 2009 Ira W. Snyder - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#ifndef __ARCH_POWERPC_ASM_FSLDMA_H__ -#define __ARCH_POWERPC_ASM_FSLDMA_H__ - -#include -#include - -/* - * Definitions for the Freescale DMA controller's DMA_SLAVE implemention - * - * The Freescale DMA_SLAVE implementation was designed to handle many-to-many - * transfers. An example usage would be an accelerated copy between two - * scatterlists. Another example use would be an accelerated copy from - * multiple non-contiguous device buffers into a single scatterlist. - * - * A DMA_SLAVE transaction is defined by a struct fsl_dma_slave. This - * structure contains a list of hardware addresses that should be copied - * to/from the scatterlist passed into device_prep_slave_sg(). The structure - * also has some fields to enable hardware-specific features. - */ - -/** - * struct fsl_dma_hw_addr - * @entry: linked list entry - * @address: the hardware address - * @length: length to transfer - * - * Holds a single physical hardware address / length pair for use - * with the DMAEngine DMA_SLAVE API. - */ -struct fsl_dma_hw_addr { - struct list_head entry; - - dma_addr_t address; - size_t length; -}; - -/** - * struct fsl_dma_slave - * @addresses: a linked list of struct fsl_dma_hw_addr structures - * @request_count: value for DMA request count - * @src_loop_size: setup and enable constant source-address DMA transfers - * @dst_loop_size: setup and enable constant destination address DMA transfers - * @external_start: enable externally started DMA transfers - * @external_pause: enable externally paused DMA transfers - * - * Holds a list of address / length pairs for use with the DMAEngine - * DMA_SLAVE API implementation for the Freescale DMA controller. - */ -struct fsl_dma_slave { - - /* List of hardware address/length pairs */ - struct list_head addresses; - - /* Support for extra controller features */ - unsigned int request_count; - unsigned int src_loop_size; - unsigned int dst_loop_size; - bool external_start; - bool external_pause; -}; - -/** - * fsl_dma_slave_append - add an address/length pair to a struct fsl_dma_slave - * @slave: the &struct fsl_dma_slave to add to - * @address: the hardware address to add - * @length: the length of bytes to transfer from @address - * - * Add a hardware address/length pair to a struct fsl_dma_slave. Returns 0 on - * success, -ERRNO otherwise. - */ -static inline int fsl_dma_slave_append(struct fsl_dma_slave *slave, - dma_addr_t address, size_t length) -{ - struct fsl_dma_hw_addr *addr; - - addr = kzalloc(sizeof(*addr), GFP_ATOMIC); - if (!addr) - return -ENOMEM; - - INIT_LIST_HEAD(&addr->entry); - addr->address = address; - addr->length = length; - - list_add_tail(&addr->entry, &slave->addresses); - return 0; -} - -/** - * fsl_dma_slave_free - free a struct fsl_dma_slave - * @slave: the struct fsl_dma_slave to free - * - * Free a struct fsl_dma_slave and all associated address/length pairs - */ -static inline void fsl_dma_slave_free(struct fsl_dma_slave *slave) -{ - struct fsl_dma_hw_addr *addr, *tmp; - - if (slave) { - list_for_each_entry_safe(addr, tmp, &slave->addresses, entry) { - list_del(&addr->entry); - kfree(addr); - } - - kfree(slave); - } -} - -/** - * fsl_dma_slave_alloc - allocate a struct fsl_dma_slave - * @gfp: the flags to pass to kmalloc when allocating this structure - * - * Allocate a struct fsl_dma_slave for use by the DMA_SLAVE API. Returns a new - * struct fsl_dma_slave on success, or NULL on failure. - */ -static inline struct fsl_dma_slave *fsl_dma_slave_alloc(gfp_t gfp) -{ - struct fsl_dma_slave *slave; - - slave = kzalloc(sizeof(*slave), gfp); - if (!slave) - return NULL; - - INIT_LIST_HEAD(&slave->addresses); - return slave; -} - -#endif /* __ARCH_POWERPC_ASM_FSLDMA_H__ */ -- cgit v1.2.2