Re: [PATCH v9 3/9] ARM: edma: add AM33XX support to the private EDMA API
On Thu, Mar 07, 2013 at 08:42:18AM +0200, Andy Shevchenko wrote: On Wed, Mar 6, 2013 at 6:15 PM, Matt Porter mpor...@ti.com wrote: Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Adds AM33XX EDMA crossbar event mux support. Enables build on OMAP. --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ + int ret = 0; + int i; + struct resource res; + void *xbar; + const s16 (*xbar_chans)[2]; + u32 shift, offset, mux; + + xbar_chans = devm_kzalloc(dev, + len/sizeof(s16) + 2*sizeof(s16), + GFP_KERNEL); + if (!xbar_chans) + return -ENOMEM; + + ret = of_address_to_resource(node, 1, res); + if (ret) + return -EIO; + + xbar = devm_ioremap(dev, res.start, resource_size(res)); + if (!xbar) + return -ENOMEM; + + ret = edma_of_read_u32_to_s16_array(node, + ti,edma-xbar-event-map, + (s16 *)xbar_chans, + len/sizeof(u32)); + if (ret) + return -EIO; + + for (i = 0; xbar_chans[i][0] != -1; i++) { + shift = (xbar_chans[i][1] % 4) * 8; Looks like shift = (xbar_chans[i][1] 0x03) 3; Yes, will update. + offset = xbar_chans[i][1] 2; + offset = 2; Is it offset = xbar_chans[i][1] 0xfffc; ? Yes, will update + mux = readl((void *)((u32)xbar + offset)); + mux = ~(0xff shift); + mux |= xbar_chans[i][0] shift; + writel(mux, (void *)((u32)xbar + offset)); + } -- With Best Regards, Andy Shevchenko ___ devicetree-discuss mailing list devicetree-disc...@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v9 5/9] dmaengine: edma: Add TI EDMA device tree binding
On Tue, Mar 12, 2013 at 06:53:03AM +, Sekhar Nori wrote: On 3/6/2013 9:45 PM, Matt Porter wrote: The binding definition is based on the generic DMA controller binding. Signed-off-by: Matt Porter mpor...@ti.com Okay the bindings the documented after they are used leading to some confusion. This patch should be moved up the series. As I noted in my other e-mail, some of these bindings are not really hardware description and need to be re-looked. Sure, I'll reorder it. -Matt --- Documentation/devicetree/bindings/dma/ti-edma.txt | 49 + 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt new file mode 100644 index 000..075a60e3 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt @@ -0,0 +1,49 @@ +TI EDMA + +Required properties: +- compatible : ti,edma3 +- ti,hwmods: Name of the hwmods associated to the EDMA +- ti,edma-regions: Number of regions +- ti,edma-slots: Number of slots +- ti,edma-queue-tc-map: List of transfer control to queue mappings +- ti,edma-queue-priority-map: List of queue priority mappings +- ti,edma-default-queue: Default queue value + +Optional properties: +- ti,edma-reserved-channels: List of reserved channel regions +- ti,edma-reserved-slots: List of reserved slot regions +- ti,edma-xbar-event-map: Crossbar event to channel map + +Example: + +edma: edma@4900 { + reg = 0x4900 0x1; + interrupt-parent = intc; + interrupts = 12 13 14; + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-reserved-channels = 0 2 +14 2 +26 6 +48 4 +56 8; + ti,edma-reserved-slots = 0 2 + 14 2 + 26 6 + 48 4 + 56 8 + 64 127; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + ti,edma-xbar-event-map = 1 12 + 2 13; +}; ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v9 3/9] ARM: edma: add AM33XX support to the private EDMA API
On Tue, Mar 12, 2013 at 06:45:46AM +, Sekhar Nori wrote: On 3/6/2013 9:45 PM, Matt Porter wrote: Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Adds AM33XX EDMA crossbar event mux support. Enables build on OMAP. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c | 300 ++-- arch/arm/mach-omap2/Kconfig|1 + include/linux/platform_data/edma.h |1 + 3 files changed, 292 insertions(+), 10 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index a1db6cd..e68ac38 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -24,6 +24,13 @@ #include linux/platform_device.h #include linux/io.h #include linux/slab.h +#include linux/edma.h +#include linux/err.h +#include linux/of_address.h +#include linux/of_device.h +#include linux/of_dma.h +#include linux/of_irq.h +#include linux/pm_runtime.h #include linux/platform_data/edma.h @@ -1369,31 +1376,278 @@ void edma_clear_event(unsigned channel) EXPORT_SYMBOL(edma_clear_event); /*---*/ +static int edma_of_read_u32_to_s8_array(const struct device_node *np, +const char *propname, s8 *out_values, +size_t sz) +{ + int ret; + + ret = of_property_read_u8_array(np, propname, out_values, sz); + if (ret) + return ret; + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_of_read_u32_to_s16_array(const struct device_node *np, +const char *propname, s16 *out_values, +size_t sz) +{ + int ret; + + ret = of_property_read_u16_array(np, propname, out_values, sz); + if (ret) + return ret; + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ It will be nice to separate the xbar feature from DT'fication of the existing driver. Right now because of the mix the patch has become pretty big and its becoming tough to review in isolation. Sure, I'll do that on v10. + int ret = 0; + int i; + struct resource res; + void *xbar; + const s16 (*xbar_chans)[2]; + u32 shift, offset, mux; + + xbar_chans = devm_kzalloc(dev, + len/sizeof(s16) + 2*sizeof(s16), + GFP_KERNEL); + if (!xbar_chans) + return -ENOMEM; + + ret = of_address_to_resource(node, 1, res); + if (ret) + return -EIO; + + xbar = devm_ioremap(dev, res.start, resource_size(res)); + if (!xbar) + return -ENOMEM; + + ret = edma_of_read_u32_to_s16_array(node, + ti,edma-xbar-event-map, + (s16 *)xbar_chans, + len/sizeof(u32)); + if (ret) + return -EIO; + + for (i = 0; xbar_chans[i][0] != -1; i++) { + shift = (xbar_chans[i][1] % 4) * 8; + offset = xbar_chans[i][1] 2; + offset = 2; + mux = readl((void *)((u32)xbar + offset)); + mux = ~(0xff shift); + mux |= xbar_chans[i][0] shift; + writel(mux, (void *)((u32)xbar + offset)); + } + + pdata-xbar_chans = xbar_chans; + + return 0; +} + +static int edma_of_parse_dt(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata) +{ + int ret = 0; + u32 value; + struct property *prop; + size_t sz; + struct edma_rsv_info *rsv_info; + const s16 (*rsv_chans)[2], (*rsv_slots)[2]; + const s8 (*queue_tc_map)[2], (*queue_priority_map)[2]; + + memset(pdata, 0, sizeof(struct edma_soc_info)); + + ret = of_property_read_u32(node, dma-channels, value); + if (ret 0) + return ret; + pdata-n_channel = value; + + ret = of_property_read_u32(node, ti,edma-regions, value); + if (ret 0) + return ret; + pdata-n_region = value; + + ret = of_property_read_u32(node, ti,edma-slots, value); + if (ret 0) + return ret; + pdata-n_slot = value; + + pdata-n_cc = 1; + pdata-n_tc = 3; Will this mean the DT portion of this driver cannot be used on SoCs where there are two CCs like DA850? If you are hard-coding
[PATCH v9 2/9] ARM: edma: remove unused transfer controller handlers
Fix build on OMAP, the irqs are undefined on AM33xx. These error interrupt handlers were hardcoded as disabled so since they are unused code, simply remove them. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c | 37 - 1 file changed, 37 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index dcaeb8e..a1db6cd 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -494,26 +494,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) return IRQ_HANDLED; } -/** - * - * Transfer controller error interrupt handlers - * - */ - -#define tc_errs_handledfalse /* disabled as long as they're NOPs */ - -static irqreturn_t dma_tc0err_handler(int irq, void *data) -{ - dev_dbg(data, dma_tc0err_handler\n); - return IRQ_HANDLED; -} - -static irqreturn_t dma_tc1err_handler(int irq, void *data) -{ - dev_dbg(data, dma_tc1err_handler\n); - return IRQ_HANDLED; -} - static int reserve_contiguous_slots(int ctlr, unsigned int id, unsigned int num_slots, unsigned int start_slot) @@ -1541,23 +1521,6 @@ static int __init edma_probe(struct platform_device *pdev) arch_num_cc++; } - if (tc_errs_handled) { - status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0, - edma_tc0, pdev-dev); - if (status 0) { - dev_dbg(pdev-dev, request_irq %d failed -- %d\n, - IRQ_TCERRINT0, status); - return status; - } - status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0, - edma_tc1, pdev-dev); - if (status 0) { - dev_dbg(pdev-dev, request_irq %d -- %d\n, - IRQ_TCERRINT, status); - return status; - } - } - return 0; fail: -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v9 1/9] ARM: davinci: move private EDMA API to arm/common
Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/Kconfig |1 + arch/arm/common/Kconfig|3 + arch/arm/common/Makefile |1 + arch/arm/{mach-davinci/dma.c = common/edma.c} |2 +- arch/arm/mach-davinci/Makefile |2 +- arch/arm/mach-davinci/board-tnetv107x-evm.c|2 +- arch/arm/mach-davinci/davinci.h|2 +- arch/arm/mach-davinci/devices-tnetv107x.c |2 +- arch/arm/mach-davinci/devices.c|6 +- arch/arm/mach-davinci/dm355.c |2 +- arch/arm/mach-davinci/dm365.c |2 +- arch/arm/mach-davinci/dm644x.c |2 +- arch/arm/mach-davinci/dm646x.c |2 +- arch/arm/mach-davinci/include/mach/da8xx.h |2 +- drivers/dma/edma.c |2 +- drivers/mmc/host/davinci_mmc.c |1 + include/linux/mfd/davinci_voicecodec.h |3 +- .../mach = include/linux/platform_data}/edma.h| 89 +--- include/linux/platform_data/spi-davinci.h |2 +- sound/soc/davinci/davinci-evm.c|1 + sound/soc/davinci/davinci-pcm.c|1 + sound/soc/davinci/davinci-pcm.h|2 +- sound/soc/davinci/davinci-sffsdr.c |5 +- 23 files changed, 33 insertions(+), 104 deletions(-) rename arch/arm/{mach-davinci/dma.c = common/edma.c} (99%) rename {arch/arm/mach-davinci/include/mach = include/linux/platform_data}/edma.h (59%) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5b71469..cb80a4d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -956,6 +956,7 @@ config ARCH_DAVINCI select GENERIC_IRQ_CHIP select HAVE_IDE select NEED_MACH_GPIO_H + select TI_PRIV_EDMA select USE_OF select ZONE_DMA help diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 9353184..c3a4e9c 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -17,3 +17,6 @@ config SHARP_PARAM config SHARP_SCOOP bool + +config TI_PRIV_EDMA + bool diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index dc8dd0d..9643c50 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o +obj-$(CONFIG_TI_PRIV_EDMA) += edma.o diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/common/edma.c similarity index 99% rename from arch/arm/mach-davinci/dma.c rename to arch/arm/common/edma.c index 45b7c71..dcaeb8e 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/common/edma.c @@ -25,7 +25,7 @@ #include linux/io.h #include linux/slab.h -#include mach/edma.h +#include linux/platform_data/edma.h /* Offsets matching struct edmacc_param */ #define PARM_OPT 0x00 diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index fb5c1aa..493a36b 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -5,7 +5,7 @@ # Common objects obj-y := time.o clock.o serial.o psc.o \ - dma.o usb.o common.o sram.o aemif.o + usb.o common.o sram.o aemif.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 4f41602..10c9efd 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -26,12 +26,12 @@ #include linux/input.h #include linux/input/matrix_keypad.h #include linux/spi/spi.h +#include linux/platform_data/edma.h #include asm/mach/arch.h #include asm/mach-types.h #include mach/irqs.h -#include mach/edma.h #include mach/mux.h #include mach/cp_intc.h #include mach/tnetv107x.h diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index 12d544b..d26a6bc 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h @@ -23,9 +23,9 @@ #include linux/platform_device.h #include linux/spi/spi.h #include linux/platform_data/davinci_asp.h +#include linux/platform_data/edma.h #include linux/platform_data/keyscan-davinci.h #include mach/hardware.h -#include mach/edma.h #include media/davinci/vpfe_capture.h #include media/davinci/vpif_types.h diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index 773ab07..ba37760 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm
[PATCH v9 0/9] DMA Engine support for AM33XX
Changes since v8: - Removed edma node interrupt-parent property, it is inherited Changes since v7: - Dropped dmaengine compat() patch. It is upstream. - Submitted edma_alloc_slot() error checking bug fix separately, now a dependency - Fixed bisect issues due to 3/10 hunks that went into 1/10 - Fixed incorrect IS_ERRVALUE() use in 3/10 Changes since v6: - Converted edma_of_read_*() to wrappers around of_property_read_*() - Fixed wording on the omap-spi generic DMA properties - Added comment/check to clarify that the driver only supports a single EDMA instance when booting from DT Changes since v5: - Dropped mmc portion and moved it to a separate series - Incorporate corrected version of dma_request_slave_channel_compat() - Fix #defines and enablement of TI_PRIV_EDMA option Changes since v4: - Fixed debug section mismatch in private edma api [01/14] - Respun format-patch to catch the platform_data/edma.h rename [01/14] - Removed address/size-cells from the EDMA binding [05/14] Changes since v3: - Rebased on 3.8-rc3 - No longer an RFC - Fixed bugs in DT/pdata parsing reported by Vaibhav Bedia - Restored all the Davinci pdata to const - Removed max_segs hack in favor of using dma_get_channel_caps() - Fixed extra parens, __raw_* accessors and, ioremap error checks in xbar handling - Removed excess license info in platform_data/edma.h - Removed unneeded reserved channels data for AM33xx - Removed test-specific pinmuxing from dts files - Adjusted mmc1 node to be disabled by default in the dtsi Changes since v2: - Rebased on 3.7-rc1 - Fixed bug in DT/pdata parsing first found by Gururaja that turned out to be masked by some toolchains - Dropped unused mach-omap2/devices.c hsmmc patch - Added AM33XX crossbar DMA event mux support - Added am335x-evm support Changes since v1: - Rebased on top of mainline from 12250d8 - Dropped the feature removal schedule patch - Implemented dma_request_slave_channel_compat() and converted the mmc and spi drivers to use it - Dropped unneeded #address-cells and #size-cells from EDMA DT support - Moved private EDMA header to linux/platform_data/ and removed some unneeded definitions - Fixed parsing of optional properties This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. The series applies on top of 3.9-rc1 and the following patches: - edma private api error check fix from http://www.spinics.net/lists/arm-kernel/msg227886.html The approach taken is similar to how OMAP DMA is being converted to DMA Engine support. With the functional EDMA private API already existing in mach-davinci/dma.c, we first move that to an ARM common area so it can be shared. Adding DT and runtime PM support to the private EDMA API implementation allows it to run on AM33xx. AM33xx *only* boots using DT so the upstream generic DT DMA helpers are leveraged to register EDMA DMAC with the of_dma framework. SPI (and MMC in a separate series) are supported using the upstream dma_request_slave_channel_compat() dmaengine call that allows compatibility with !DT platforms. With this series both BeagleBone and the AM335x EVM have working SPI DMA support (and MMC support with the separate MMC series). This is tested on BeagleBone with a SPI framebuffer driver and MMC rootfs. A trivial gpio DMA event misc driver was used to test the crossbar DMA event support. It is also tested on the AM335x EVM with the onboard SPI flash and MMC rootfs. Note that MMC can only be tested with a separate MMC dmaengine/DT series applied. Regression testing was done on AM180x-EVM (which also makes use of the EDMA dmaengine driver and the EDMA private API) using SD, SPI flash, and the onboard audio supported by the ASoC Davinci driver. Regression testing was also done on a BeagleBoard xM booting from the legacy board file using MMC rootfs. Matt Porter (9): ARM: davinci: move private EDMA API to arm/common ARM: edma: remove unused transfer controller handlers ARM: edma: add AM33XX support to the private EDMA API dmaengine: edma: enable build for AM33XX dmaengine: edma: Add TI EDMA device tree binding ARM: dts: add AM33XX EDMA support spi: omap2-mcspi: convert to dma_request_slave_channel_compat() spi: omap2-mcspi: add generic DMA request support to the DT binding ARM: dts: add AM33XX SPI DMA support Documentation/devicetree/bindings/dma/ti-edma.txt | 49 +++ Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +- arch/arm/Kconfig
[PATCH v9 8/9] spi: omap2-mcspi: add generic DMA request support to the DT binding
The binding definition is based on the generic DMA request binding Signed-off-by: Matt Porter mpor...@ti.com --- Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/omap-spi.txt b/Documentation/devicetree/bindings/spi/omap-spi.txt index 938809c..4c85c4c 100644 --- a/Documentation/devicetree/bindings/spi/omap-spi.txt +++ b/Documentation/devicetree/bindings/spi/omap-spi.txt @@ -10,7 +10,18 @@ Required properties: input. The default is D0 as input and D1 as output. -Example: +Optional properties: +- dmas: List of DMA specifiers with the controller specific format + as described in the generic DMA client binding. A tx and rx + specifier is required for each chip select. +- dma-names: List of DMA request names. These strings correspond + 1:1 with the DMA specifiers listed in dmas. The string naming + is to be rxN and txN for RX and TX requests, + respectively, where N equals the chip select number. + +Examples: + +[hwmod populated DMA resources] mcspi1: mcspi@1 { #address-cells = 1; @@ -20,3 +31,17 @@ mcspi1: mcspi@1 { ti,spi-num-cs = 4; }; +[generic DMA request binding] + +mcspi1: mcspi@1 { +#address-cells = 1; +#size-cells = 0; +compatible = ti,omap4-mcspi; +ti,hwmods = mcspi1; +ti,spi-num-cs = 2; +dmas = edma 42 + edma 43 + edma 44 + edma 45; +dma-names = tx0, rx0, tx1, rx1; +}; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v9 3/9] ARM: edma: add AM33XX support to the private EDMA API
Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Adds AM33XX EDMA crossbar event mux support. Enables build on OMAP. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c | 300 ++-- arch/arm/mach-omap2/Kconfig|1 + include/linux/platform_data/edma.h |1 + 3 files changed, 292 insertions(+), 10 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index a1db6cd..e68ac38 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -24,6 +24,13 @@ #include linux/platform_device.h #include linux/io.h #include linux/slab.h +#include linux/edma.h +#include linux/err.h +#include linux/of_address.h +#include linux/of_device.h +#include linux/of_dma.h +#include linux/of_irq.h +#include linux/pm_runtime.h #include linux/platform_data/edma.h @@ -1369,31 +1376,278 @@ void edma_clear_event(unsigned channel) EXPORT_SYMBOL(edma_clear_event); /*---*/ +static int edma_of_read_u32_to_s8_array(const struct device_node *np, +const char *propname, s8 *out_values, +size_t sz) +{ + int ret; + + ret = of_property_read_u8_array(np, propname, out_values, sz); + if (ret) + return ret; + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_of_read_u32_to_s16_array(const struct device_node *np, +const char *propname, s16 *out_values, +size_t sz) +{ + int ret; + + ret = of_property_read_u16_array(np, propname, out_values, sz); + if (ret) + return ret; + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ + int ret = 0; + int i; + struct resource res; + void *xbar; + const s16 (*xbar_chans)[2]; + u32 shift, offset, mux; + + xbar_chans = devm_kzalloc(dev, + len/sizeof(s16) + 2*sizeof(s16), + GFP_KERNEL); + if (!xbar_chans) + return -ENOMEM; + + ret = of_address_to_resource(node, 1, res); + if (ret) + return -EIO; + + xbar = devm_ioremap(dev, res.start, resource_size(res)); + if (!xbar) + return -ENOMEM; + + ret = edma_of_read_u32_to_s16_array(node, + ti,edma-xbar-event-map, + (s16 *)xbar_chans, + len/sizeof(u32)); + if (ret) + return -EIO; + + for (i = 0; xbar_chans[i][0] != -1; i++) { + shift = (xbar_chans[i][1] % 4) * 8; + offset = xbar_chans[i][1] 2; + offset = 2; + mux = readl((void *)((u32)xbar + offset)); + mux = ~(0xff shift); + mux |= xbar_chans[i][0] shift; + writel(mux, (void *)((u32)xbar + offset)); + } + + pdata-xbar_chans = xbar_chans; + + return 0; +} + +static int edma_of_parse_dt(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata) +{ + int ret = 0; + u32 value; + struct property *prop; + size_t sz; + struct edma_rsv_info *rsv_info; + const s16 (*rsv_chans)[2], (*rsv_slots)[2]; + const s8 (*queue_tc_map)[2], (*queue_priority_map)[2]; + + memset(pdata, 0, sizeof(struct edma_soc_info)); + + ret = of_property_read_u32(node, dma-channels, value); + if (ret 0) + return ret; + pdata-n_channel = value; + + ret = of_property_read_u32(node, ti,edma-regions, value); + if (ret 0) + return ret; + pdata-n_region = value; + + ret = of_property_read_u32(node, ti,edma-slots, value); + if (ret 0) + return ret; + pdata-n_slot = value; + + pdata-n_cc = 1; + pdata-n_tc = 3; + + rsv_info = + devm_kzalloc(dev, sizeof(struct edma_rsv_info), GFP_KERNEL); + if (!rsv_info) + return -ENOMEM; + pdata-rsv = rsv_info; + + /* Build the reserved channel/slots arrays */ + prop = of_find_property(node, ti,edma-reserved-channels, sz); + if (prop) { + rsv_chans = devm_kzalloc(dev, +sz/sizeof(s16) + 2*sizeof(s16
[PATCH v9 9/9] ARM: dts: add AM33XX SPI DMA support
Adds DMA resources to the AM33XX SPI nodes. Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index cbea5ab..c3c781a 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -327,6 +327,11 @@ interrupt = 65; ti,spi-num-cs = 2; ti,hwmods = spi0; + dmas = edma 16 + edma 17 + edma 18 + edma 19; + dma-names = tx0, rx0, tx1, rx1; status = disabled; }; @@ -338,6 +343,11 @@ interrupt = 125; ti,spi-num-cs = 2; ti,hwmods = spi1; + dmas = edma 42 + edma 43 + edma 44 + edma 45; + dma-names = tx0, rx0, tx1, rx1; status = disabled; }; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v9 5/9] dmaengine: edma: Add TI EDMA device tree binding
The binding definition is based on the generic DMA controller binding. Signed-off-by: Matt Porter mpor...@ti.com --- Documentation/devicetree/bindings/dma/ti-edma.txt | 49 + 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt new file mode 100644 index 000..075a60e3 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt @@ -0,0 +1,49 @@ +TI EDMA + +Required properties: +- compatible : ti,edma3 +- ti,hwmods: Name of the hwmods associated to the EDMA +- ti,edma-regions: Number of regions +- ti,edma-slots: Number of slots +- ti,edma-queue-tc-map: List of transfer control to queue mappings +- ti,edma-queue-priority-map: List of queue priority mappings +- ti,edma-default-queue: Default queue value + +Optional properties: +- ti,edma-reserved-channels: List of reserved channel regions +- ti,edma-reserved-slots: List of reserved slot regions +- ti,edma-xbar-event-map: Crossbar event to channel map + +Example: + +edma: edma@4900 { + reg = 0x4900 0x1; + interrupt-parent = intc; + interrupts = 12 13 14; + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-reserved-channels = 0 2 +14 2 +26 6 +48 4 +56 8; + ti,edma-reserved-slots = 0 2 + 14 2 + 26 6 + 48 4 + 56 8 + 64 127; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + ti,edma-xbar-event-map = 1 12 + 2 13; +}; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v9 4/9] dmaengine: edma: enable build for AM33XX
Enable TI EDMA option on OMAP. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/dma/Kconfig |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 80b6997..3b7ea20 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -222,7 +222,7 @@ config SIRF_DMA config TI_EDMA tristate TI EDMA support - depends on ARCH_DAVINCI + depends on ARCH_DAVINCI || ARCH_OMAP select DMA_ENGINE select DMA_VIRTUAL_CHANNELS default n -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v9 6/9] ARM: dts: add AM33XX EDMA support
Adds AM33XX EDMA support to the am33xx.dtsi as documented in Documentation/devicetree/bindings/dma/ti-edma.txt Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 19 +++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 0957645..cbea5ab 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -87,6 +87,25 @@ reg = 0x4820 0x1000; }; + edma: edma@4900 { + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + reg = 0x4900 0x1, + 0x44e10f90 0x10; + interrupts = 12 13 14; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + }; + gpio1: gpio@44e07000 { compatible = ti,omap4-gpio; ti,hwmods = gpio1; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v9 7/9] spi: omap2-mcspi: convert to dma_request_slave_channel_compat()
Convert dmaengine channel requests to use dma_request_slave_channel_compat(). This supports the DT case of platforms requiring channel selection from either the OMAP DMA or the EDMA engine. AM33xx only boots from DT and is the only user implementing EDMA so in the !DT case we can default to the OMAP DMA filter. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Mark Brown broo...@opensource.wolfsonmicro.com --- drivers/spi/spi-omap2-mcspi.c | 27 --- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 893c3d7..38d0915 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -102,6 +102,9 @@ struct omap2_mcspi_dma { struct completion dma_tx_completion; struct completion dma_rx_completion; + + char dma_rx_ch_name[14]; + char dma_tx_ch_name[14]; }; /* use PIO for small transfers, avoiding DMA setup/teardown overhead and @@ -822,14 +825,23 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); sig = mcspi_dma-dma_rx_sync_dev; - mcspi_dma-dma_rx = dma_request_channel(mask, omap_dma_filter_fn, sig); + + mcspi_dma-dma_rx = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +sig, master-dev, +mcspi_dma-dma_rx_ch_name); + if (!mcspi_dma-dma_rx) { dev_err(spi-dev, no RX DMA engine channel for McSPI\n); return -EAGAIN; } sig = mcspi_dma-dma_tx_sync_dev; - mcspi_dma-dma_tx = dma_request_channel(mask, omap_dma_filter_fn, sig); + mcspi_dma-dma_tx = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +sig, master-dev, +mcspi_dma-dma_tx_ch_name); + if (!mcspi_dma-dma_tx) { dev_err(spi-dev, no TX DMA engine channel for McSPI\n); dma_release_channel(mcspi_dma-dma_rx); @@ -1240,12 +1252,13 @@ static int omap2_mcspi_probe(struct platform_device *pdev) goto free_master; for (i = 0; i master-num_chipselect; i++) { - char dma_ch_name[14]; + char *dma_rx_ch_name = mcspi-dma_channels[i].dma_rx_ch_name; + char *dma_tx_ch_name = mcspi-dma_channels[i].dma_tx_ch_name; struct resource *dma_res; - sprintf(dma_ch_name, rx%d, i); + sprintf(dma_rx_ch_name, rx%d, i); dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); + dma_rx_ch_name); if (!dma_res) { dev_dbg(pdev-dev, cannot get DMA RX channel\n); status = -ENODEV; @@ -1253,9 +1266,9 @@ static int omap2_mcspi_probe(struct platform_device *pdev) } mcspi-dma_channels[i].dma_rx_sync_dev = dma_res-start; - sprintf(dma_ch_name, tx%d, i); + sprintf(dma_tx_ch_name, tx%d, i); dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); + dma_tx_ch_name); if (!dma_res) { dev_dbg(pdev-dev, cannot get DMA TX channel\n); status = -ENODEV; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v4 2/3] dma: edma: add device_slave_sg_limits() support
Implement device_slave_sg_limits(). EDMA has a finite set of PaRAM slots available for linking a multi-segment SG transfer. In order to prevent any one channel from consuming all PaRAM slots to fulfill a large SG transfer, the driver reports a static per-channel max number of SG segments it will handle. The maximum size of an SG segment is limited by the addr_width and maxburst of a given transfer request. These values are provided by the client driver and used to calculate and return the maximum segment length. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/dma/edma.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index cd7e328..42373bf 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -70,6 +70,7 @@ struct edma_chan { boolalloced; int slot[EDMA_MAX_SLOTS]; struct dma_slave_config cfg; + struct dma_slave_sg_limits sg_limits; }; struct edma_cc { @@ -462,6 +463,20 @@ static void edma_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(echan-vchan.lock, flags); } +static struct dma_slave_sg_limits +*edma_get_slave_sg_limits(struct dma_chan *chan, + enum dma_slave_buswidth addr_width, + u32 maxburst) +{ + struct edma_chan *echan; + + echan = to_edma_chan(chan); + echan-sg_limits.max_seg_len = + (SZ_64K - 1) * addr_width * maxburst; + + return echan-sg_limits; +} + static size_t edma_desc_size(struct edma_desc *edesc) { int i; @@ -521,6 +536,7 @@ static void __init edma_chan_init(struct edma_cc *ecc, echan-ch_num = EDMA_CTLR_CHAN(ecc-ctlr, i); echan-ecc = ecc; echan-vchan.desc_free = edma_desc_free; + echan-sg_limits.max_seg_nr = MAX_NR_SG; vchan_init(echan-vchan, dma); @@ -537,6 +553,7 @@ static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma, dma-device_alloc_chan_resources = edma_alloc_chan_resources; dma-device_free_chan_resources = edma_free_chan_resources; dma-device_issue_pending = edma_issue_pending; + dma-device_slave_sg_limits = edma_get_slave_sg_limits; dma-device_tx_status = edma_tx_status; dma-device_control = edma_control; dma-dev = dev; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v4 0/3] dmaengine: add slave sg transfer limits api
Changes since v3: - Change api name to dma_get_slave_sg_limits() to avoid confusion with h/w caps which are static. Changes since v2: - Change to a separate slave sg specific api. Drop the generic per-channel capabilities api that is not used. Changes since v1: - Use the existing dma_transaction_type enums instead of adding the mostly duplicated dmaengine_apis enums This series adds a new dmaengine api, dma_get_slave_sg_limits(), which may be used by a client driver to get slave SG transfer limits for a particular channel. At this time, these include the max number of segments and max length of a segment that a channel can handle for a SG transfer. Along with the API implementation, this series implements the backend device_slave_sg_limits() in the EDMA DMA Engine driver and converts the davinci_mmc driver to use dma_get_slave_sg_limits() to replace hardcoded limits. This is tested on the AM1808-EVM. Matt Porter (3): dmaengine: add dma_get_slave_sg_limits() dma: edma: add device_slave_sg_limits() support mmc: davinci: get SG segment limits with dma_get_slave_sg_limits() drivers/dma/edma.c| 17 + drivers/mmc/host/davinci_mmc.c| 37 --- include/linux/dmaengine.h | 39 + include/linux/platform_data/mmc-davinci.h |3 --- 4 files changed, 66 insertions(+), 30 deletions(-) -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v4 3/3] mmc: davinci: get SG segment limits with dma_get_slave_sg_limits()
Replace the hardcoded values used to set max_segs/max_seg_size with a dma_get_slave_sg_limits() query to the dmaengine driver. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/mmc/host/davinci_mmc.c| 37 - include/linux/platform_data/mmc-davinci.h |3 --- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 2063677..a98b5bc 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -144,18 +144,6 @@ /* MMCSD Init clock in Hz in opendrain mode */ #define MMCSD_INIT_CLOCK 20 -/* - * One scatterlist dma segment is at most MAX_CCNT rw_threshold units, - * and we handle up to MAX_NR_SG segments. MMC_BLOCK_BOUNCE kicks in only - * for drivers with max_segs == 1, making the segments bigger (64KB) - * than the page or two that's otherwise typical. nr_sg (passed from - * platform data) == 16 gives at least the same throughput boost, using - * EDMA transfer linkage instead of spending CPU time copying pages. - */ -#define MAX_CCNT ((1 16) - 1) - -#define MAX_NR_SG 16 - static unsigned rw_threshold = 32; module_param(rw_threshold, uint, S_IRUGO); MODULE_PARM_DESC(rw_threshold, @@ -216,8 +204,6 @@ struct mmc_davinci_host { u8 version; /* for ns in one cycle calculation */ unsigned ns_in_one_cycle; - /* Number of sg segments */ - u8 nr_sg; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; #endif @@ -1165,6 +1151,7 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) struct resource *r, *mem = NULL; int ret = 0, irq = 0; size_t mem_size; + struct dma_slave_sg_limits *dma_sg_limits; /* REVISIT: when we're fully converted, fail if pdata is NULL */ @@ -1214,12 +1201,6 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) init_mmcsd_host(host); - if (pdata-nr_sg) - host-nr_sg = pdata-nr_sg - 1; - - if (host-nr_sg MAX_NR_SG || !host-nr_sg) - host-nr_sg = MAX_NR_SG; - host-use_dma = use_dma; host-mmc_irq = irq; host-sdio_irq = platform_get_irq(pdev, 1); @@ -1248,14 +1229,16 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) mmc-caps |= pdata-caps; mmc-ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - /* With no iommu coalescing pages, each phys_seg is a hw_seg. -* Each hw_seg uses one EDMA parameter RAM slot, always one -* channel and then usually some linked slots. -*/ - mmc-max_segs = MAX_NR_SG; + /* Just check one channel for the DMA SG limits */ + dma_sg_limits = dma_get_slave_sg_limits( + host-dma_tx, + DMA_SLAVE_BUSWIDTH_4_BYTES, + rw_threshold / DMA_SLAVE_BUSWIDTH_4_BYTES); - /* EDMA limit per hw segment (one or two MBytes) */ - mmc-max_seg_size = MAX_CCNT * rw_threshold; + if (dma_sg_limits) { + mmc-max_segs = dma_sg_limits-max_seg_nr; + mmc-max_seg_size = dma_sg_limits-max_seg_len; + } /* MMC/SD controller limits for multiblock requests */ mmc-max_blk_size = 4095; /* BLEN is 12 bits */ diff --git a/include/linux/platform_data/mmc-davinci.h b/include/linux/platform_data/mmc-davinci.h index 5ba6b22..6910209 100644 --- a/include/linux/platform_data/mmc-davinci.h +++ b/include/linux/platform_data/mmc-davinci.h @@ -25,9 +25,6 @@ struct davinci_mmc_config { /* Version of the MMC/SD controller */ u8 version; - - /* Number of sg segments */ - u8 nr_sg; }; void davinci_setup_mmc(int module, struct davinci_mmc_config *config); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v4 1/3] dmaengine: add dma_get_slave_sg_limits()
Add a dmaengine API to retrieve slave SG transfer limits. The API is optionally implemented by dmaengine drivers and when unimplemented will return a NULL pointer. A client driver using this API provides the required dma channel, address width, and burst size of the transfer. dma_get_slave_sg_limits() returns an SG limits structure with the maximum number and size of SG segments that the given channel can handle. Signed-off-by: Matt Porter mpor...@ti.com --- include/linux/dmaengine.h | 39 +++ 1 file changed, 39 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 91ac8da..a4a6aac 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -371,6 +371,18 @@ struct dma_slave_config { unsigned int slave_id; }; +/* struct dma_slave_sg_limits - expose SG transfer limits of a channel + * + * @max_seg_nr: maximum number of SG segments supported on a SG/SLAVE + * channel (0 for no maximum or not a SG/SLAVE channel) + * @max_seg_len: maximum length of SG segments supported on a SG/SLAVE + * channel (0 for no maximum or not a SG/SLAVE channel) + */ +struct dma_slave_sg_limits { + u32 max_seg_nr; + u32 max_seg_len; +}; + static inline const char *dma_chan_name(struct dma_chan *chan) { return dev_name(chan-dev-device); @@ -534,6 +546,7 @@ struct dma_tx_state { * struct with auxiliary transfer status information, otherwise the call * will just return a simple status code * @device_issue_pending: push pending transactions to hardware + * @device_slave_sg_limits: return the slave SG capabilities */ struct dma_device { @@ -602,6 +615,9 @@ struct dma_device { dma_cookie_t cookie, struct dma_tx_state *txstate); void (*device_issue_pending)(struct dma_chan *chan); + struct dma_slave_sg_limits *(*device_slave_sg_limits)( + struct dma_chan *chan, enum dma_slave_buswidth addr_width, + u32 maxburst); }; static inline int dmaengine_device_control(struct dma_chan *chan, @@ -963,6 +979,29 @@ dma_set_tx_state(struct dma_tx_state *st, dma_cookie_t last, dma_cookie_t used, } } +/** + * dma_get_slave_sg_limits - get DMAC SG transfer capabilities + * @chan: target DMA channel + * @addr_width: address width of the DMA transfer + * @maxburst: maximum DMA transfer burst size + * + * Get SG transfer capabilities for a specified channel. If the dmaengine + * driver does not implement SG transfer capabilities then NULL is + * returned. + */ +static inline struct dma_slave_sg_limits +*dma_get_slave_sg_limits(struct dma_chan *chan, + enum dma_slave_buswidth addr_width, + u32 maxburst) +{ + if (chan-device-device_slave_sg_limits) + return chan-device-device_slave_sg_limits(chan, + addr_width, + maxburst); + + return NULL; +} + enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); #ifdef CONFIG_DMA_ENGINE enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v3 1/3] dmaengine: add dma_get_slave_sg_caps()
On Tue, Feb 12, 2013 at 05:08:44PM +, Vinod Koul wrote: On Mon, Feb 04, 2013 at 02:47:02PM -0500, Matt Porter wrote: Add a dmaengine API to retrieve slave SG transfer capabilities. The API is optionally implemented by dmaengine drivers and when unimplemented will return a NULL pointer. A client driver using this API provides the required dma channel, address width, and burst size of the transfer. dma_get_slave_sg_caps() returns an SG caps structure with the maximum number and size of SG segments that the given channel can handle. Okay this sounds much better :-) few points though: - you added API for caps, but is actually calculating for given configuration the max allowed range. IMHO that is not caps, perhaps renaming to get_max_sg /some_better_name would be more apt. I went with get_slave_sg_limits(), seemed pretty descriptive. Just posted v4 with that change. - Still I like the idea of caps, but it should give H/W support capablity. If you want to add that, pls develop on same line... Ok, seems like a good separate submission. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v9 5/9] dmaengine: edma: Add TI EDMA device tree binding
On Wed, Mar 06, 2013 at 08:24:06PM +, Peter Korsgaard wrote: Matt == Matt Porter mpor...@ti.com writes: Matt The binding definition is based on the generic DMA controller Matt binding. Matt Signed-off-by: Matt Porter mpor...@ti.com Matt --- Matt Documentation/devicetree/bindings/dma/ti-edma.txt | 49 + Matt 1 file changed, 49 insertions(+) Matt create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt Matt diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt Matt new file mode 100644 Matt index 000..075a60e3 Matt --- /dev/null Matt +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt Matt @@ -0,0 +1,49 @@ Matt +TI EDMA Matt + Matt +Required properties: Matt +- compatible : ti,edma3 Matt +- ti,hwmods: Name of the hwmods associated to the EDMA Matt +- ti,edma-regions: Number of regions Matt +- ti,edma-slots: Number of slots Matt +- ti,edma-queue-tc-map: List of transfer control to queue mappings Matt +- ti,edma-queue-priority-map: List of queue priority mappings Matt +- ti,edma-default-queue: Default queue value Matt + Matt +Optional properties: Matt +- ti,edma-reserved-channels: List of reserved channel regions Matt +- ti,edma-reserved-slots: List of reserved slot regions Matt +- ti,edma-xbar-event-map: Crossbar event to channel map Matt + Matt +Example: Matt + Matt +edma: edma@4900 { Matt + reg = 0x4900 0x1; Matt + interrupt-parent = intc; Matt + interrupts = 12 13 14; Probably interrupt-parent should be removed from the example as well to match am33xx.dtsi I'm not sure what the DT maintainers want here. Full context within the example or the actual real usage where it's typically inherited. Grant or Rob, any thoughts? -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH] arm: davinci: fix edma dmaengine induced null pointer dereference on da830
On Tue, Mar 05, 2013 at 06:43:41AM +, Sekhar Nori wrote: Hi Matt, I dropped the copy to stable folks since they dont want to be involved in patch reviews of this kind. On 3/4/2013 10:22 PM, Matt Porter wrote: This adds additional error checking to the private edma api implementation to catch the case where the edma_alloc_slot() has an invalid controller parameter. The edma dmaengine wrapper driver relies on this condition being handled in order to avoid setting up a second edma dmaengine instance on DA830. Verfied using a DA850 with the second EDMA controller platform instance removed to simulate a DA830 which only has a single EDMA controller. Reported-by: Tomas Novotny to...@novotny.cz Signed-off-by: Matt Porter mpor...@ti.com Cc: sta...@kernel.org This should be sta...@vger.kernel.org per Documentation/stable_kernel_rules.txt. Also, I think it is better to request the back port only from v3.7.x+ since the bug is important only after drivers/dma/edma.c was merged. So: Cc: sta...@vger.kernel.org # v3.7.x+ Agreed. Had the two year old email in my macros. Will update to reflect 3.7.x+ only. arch/arm/mach-davinci/dma.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index a685e97..f9eb836 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -747,6 +747,8 @@ int edma_alloc_slot(unsigned ctlr, int slot) slot = EDMA_CHAN_SLOT(slot); if (slot 0) { + if (!edma_cc[ctlr]) + return -EINVAL; Shouldn't such a check be done outside of the if() since there is an 'else if' later which also accesses edma_cc[ctlr] Yeah, as it turns out I also separately added the correct version of this in the am33xx dmaengine series as it was an issue there. I will correct this in v2. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v2] arm: davinci: fix edma dmaengine induced null pointer dereference on da830
This adds additional error checking to the private edma api implementation to catch the case where the edma_alloc_slot() has an invalid controller parameter. The edma dmaengine wrapper driver relies on this condition being handled in order to avoid setting up a second edma dmaengine instance on DA830. Verfied using a DA850 with the second EDMA controller platform instance removed to simulate a DA830 which only has a single EDMA controller. Reported-by: Tomas Novotny to...@novotny.cz Signed-off-by: Matt Porter mpor...@ti.com Cc: sta...@vger.kernel.org # v3.7.x+ --- v2: Move error check out of conditional to catch all cases arch/arm/mach-davinci/dma.c |3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index a685e97..45b7c71 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -743,6 +743,9 @@ EXPORT_SYMBOL(edma_free_channel); */ int edma_alloc_slot(unsigned ctlr, int slot) { + if (!edma_cc[ctlr]) + return -EINVAL; + if (slot = 0) slot = EDMA_CHAN_SLOT(slot); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v8 0/9] DMA Engine support for AM33XX
Changes since v7: - Dropped dmaengine compat() patch. It is upstream. - Submitted edma_alloc_slot() error checking bug fix separately, now a dependency - Fixed bisect issues due to 3/10 hunks that went into 1/10 - Fixed incorrect IS_ERRVALUE() use in 3/10 Changes since v6: - Converted edma_of_read_*() to wrappers around of_property_read_*() - Fixed wording on the omap-spi generic DMA properties - Added comment/check to clarify that the driver only supports a single EDMA instance when booting from DT Changes since v5: - Dropped mmc portion and moved it to a separate series - Incorporate corrected version of dma_request_slave_channel_compat() - Fix #defines and enablement of TI_PRIV_EDMA option Changes since v4: - Fixed debug section mismatch in private edma api [01/14] - Respun format-patch to catch the platform_data/edma.h rename [01/14] - Removed address/size-cells from the EDMA binding [05/14] Changes since v3: - Rebased on 3.8-rc3 - No longer an RFC - Fixed bugs in DT/pdata parsing reported by Vaibhav Bedia - Restored all the Davinci pdata to const - Removed max_segs hack in favor of using dma_get_channel_caps() - Fixed extra parens, __raw_* accessors and, ioremap error checks in xbar handling - Removed excess license info in platform_data/edma.h - Removed unneeded reserved channels data for AM33xx - Removed test-specific pinmuxing from dts files - Adjusted mmc1 node to be disabled by default in the dtsi Changes since v2: - Rebased on 3.7-rc1 - Fixed bug in DT/pdata parsing first found by Gururaja that turned out to be masked by some toolchains - Dropped unused mach-omap2/devices.c hsmmc patch - Added AM33XX crossbar DMA event mux support - Added am335x-evm support Changes since v1: - Rebased on top of mainline from 12250d8 - Dropped the feature removal schedule patch - Implemented dma_request_slave_channel_compat() and converted the mmc and spi drivers to use it - Dropped unneeded #address-cells and #size-cells from EDMA DT support - Moved private EDMA header to linux/platform_data/ and removed some unneeded definitions - Fixed parsing of optional properties This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. The series applies on top of 3.9-rc1 and the following patches: - edma private api error check fix from http://www.spinics.net/lists/arm-kernel/msg227886.html The approach taken is similar to how OMAP DMA is being converted to DMA Engine support. With the functional EDMA private API already existing in mach-davinci/dma.c, we first move that to an ARM common area so it can be shared. Adding DT and runtime PM support to the private EDMA API implementation allows it to run on AM33xx. AM33xx *only* boots using DT so we leverage Jon's generic DT DMA helpers to register EDMA DMAC with the of_dma framework and then add support for calling the dma_request_slave_channel() API to both the mmc and spi drivers. With this series both BeagleBone and the AM335x EVM have working SPI DMA support (and MMC support with the separate MMC series). This is tested on BeagleBone with a SPI framebuffer driver and MMC rootfs. A trivial gpio DMA event misc driver was used to test the crossbar DMA event support. It is also tested on the AM335x EVM with the onboard SPI flash and MMC rootfs. The branch at https://github.com/ohporter/linux/tree/edma-dmaengine-am33xx-v7 has the complete series, dependencies, and some test drivers/defconfigs. Note that MMC can only be tested with a separate MMC dmaengine/DT series applied. Regression testing was done on AM180x-EVM (which also makes use of the EDMA dmaengine driver and the EDMA private API) using SD, SPI flash, and the onboard audio supported by the ASoC Davinci driver. Regression testing was also done on a BeagleBoard xM booting from the legacy board file using MMC rootfs. Matt Porter (9): ARM: davinci: move private EDMA API to arm/common ARM: edma: remove unused transfer controller handlers ARM: edma: add AM33XX support to the private EDMA API dmaengine: edma: enable build for AM33XX dmaengine: edma: Add TI EDMA device tree binding ARM: dts: add AM33XX EDMA support spi: omap2-mcspi: convert to dma_request_slave_channel_compat() spi: omap2-mcspi: add generic DMA request support to the DT binding ARM: dts: add AM33XX SPI DMA support Documentation/devicetree/bindings/dma/ti-edma.txt | 49 +++ Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +- arch/arm/Kconfig |1
[PATCH v8 2/9] ARM: edma: remove unused transfer controller handlers
Fix build on OMAP, the irqs are undefined on AM33xx. These error interrupt handlers were hardcoded as disabled so since they are unused code, simply remove them. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c | 37 - 1 file changed, 37 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index dcaeb8e..a1db6cd 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -494,26 +494,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) return IRQ_HANDLED; } -/** - * - * Transfer controller error interrupt handlers - * - */ - -#define tc_errs_handledfalse /* disabled as long as they're NOPs */ - -static irqreturn_t dma_tc0err_handler(int irq, void *data) -{ - dev_dbg(data, dma_tc0err_handler\n); - return IRQ_HANDLED; -} - -static irqreturn_t dma_tc1err_handler(int irq, void *data) -{ - dev_dbg(data, dma_tc1err_handler\n); - return IRQ_HANDLED; -} - static int reserve_contiguous_slots(int ctlr, unsigned int id, unsigned int num_slots, unsigned int start_slot) @@ -1541,23 +1521,6 @@ static int __init edma_probe(struct platform_device *pdev) arch_num_cc++; } - if (tc_errs_handled) { - status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0, - edma_tc0, pdev-dev); - if (status 0) { - dev_dbg(pdev-dev, request_irq %d failed -- %d\n, - IRQ_TCERRINT0, status); - return status; - } - status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0, - edma_tc1, pdev-dev); - if (status 0) { - dev_dbg(pdev-dev, request_irq %d -- %d\n, - IRQ_TCERRINT, status); - return status; - } - } - return 0; fail: -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v8 3/9] ARM: edma: add AM33XX support to the private EDMA API
Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Adds AM33XX EDMA crossbar event mux support. Enables build on OMAP. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c | 300 ++-- arch/arm/mach-omap2/Kconfig|1 + include/linux/platform_data/edma.h |1 + 3 files changed, 292 insertions(+), 10 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index a1db6cd..e68ac38 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -24,6 +24,13 @@ #include linux/platform_device.h #include linux/io.h #include linux/slab.h +#include linux/edma.h +#include linux/err.h +#include linux/of_address.h +#include linux/of_device.h +#include linux/of_dma.h +#include linux/of_irq.h +#include linux/pm_runtime.h #include linux/platform_data/edma.h @@ -1369,31 +1376,278 @@ void edma_clear_event(unsigned channel) EXPORT_SYMBOL(edma_clear_event); /*---*/ +static int edma_of_read_u32_to_s8_array(const struct device_node *np, +const char *propname, s8 *out_values, +size_t sz) +{ + int ret; + + ret = of_property_read_u8_array(np, propname, out_values, sz); + if (ret) + return ret; + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_of_read_u32_to_s16_array(const struct device_node *np, +const char *propname, s16 *out_values, +size_t sz) +{ + int ret; + + ret = of_property_read_u16_array(np, propname, out_values, sz); + if (ret) + return ret; + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ + int ret = 0; + int i; + struct resource res; + void *xbar; + const s16 (*xbar_chans)[2]; + u32 shift, offset, mux; + + xbar_chans = devm_kzalloc(dev, + len/sizeof(s16) + 2*sizeof(s16), + GFP_KERNEL); + if (!xbar_chans) + return -ENOMEM; + + ret = of_address_to_resource(node, 1, res); + if (ret) + return -EIO; + + xbar = devm_ioremap(dev, res.start, resource_size(res)); + if (!xbar) + return -ENOMEM; + + ret = edma_of_read_u32_to_s16_array(node, + ti,edma-xbar-event-map, + (s16 *)xbar_chans, + len/sizeof(u32)); + if (ret) + return -EIO; + + for (i = 0; xbar_chans[i][0] != -1; i++) { + shift = (xbar_chans[i][1] % 4) * 8; + offset = xbar_chans[i][1] 2; + offset = 2; + mux = readl((void *)((u32)xbar + offset)); + mux = ~(0xff shift); + mux |= xbar_chans[i][0] shift; + writel(mux, (void *)((u32)xbar + offset)); + } + + pdata-xbar_chans = xbar_chans; + + return 0; +} + +static int edma_of_parse_dt(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata) +{ + int ret = 0; + u32 value; + struct property *prop; + size_t sz; + struct edma_rsv_info *rsv_info; + const s16 (*rsv_chans)[2], (*rsv_slots)[2]; + const s8 (*queue_tc_map)[2], (*queue_priority_map)[2]; + + memset(pdata, 0, sizeof(struct edma_soc_info)); + + ret = of_property_read_u32(node, dma-channels, value); + if (ret 0) + return ret; + pdata-n_channel = value; + + ret = of_property_read_u32(node, ti,edma-regions, value); + if (ret 0) + return ret; + pdata-n_region = value; + + ret = of_property_read_u32(node, ti,edma-slots, value); + if (ret 0) + return ret; + pdata-n_slot = value; + + pdata-n_cc = 1; + pdata-n_tc = 3; + + rsv_info = + devm_kzalloc(dev, sizeof(struct edma_rsv_info), GFP_KERNEL); + if (!rsv_info) + return -ENOMEM; + pdata-rsv = rsv_info; + + /* Build the reserved channel/slots arrays */ + prop = of_find_property(node, ti,edma-reserved-channels, sz); + if (prop) { + rsv_chans = devm_kzalloc(dev, +sz/sizeof(s16) + 2*sizeof(s16
[PATCH v8 5/9] dmaengine: edma: Add TI EDMA device tree binding
The binding definition is based on the generic DMA controller binding. Signed-off-by: Matt Porter mpor...@ti.com --- Documentation/devicetree/bindings/dma/ti-edma.txt | 49 + 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt new file mode 100644 index 000..075a60e3 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt @@ -0,0 +1,49 @@ +TI EDMA + +Required properties: +- compatible : ti,edma3 +- ti,hwmods: Name of the hwmods associated to the EDMA +- ti,edma-regions: Number of regions +- ti,edma-slots: Number of slots +- ti,edma-queue-tc-map: List of transfer control to queue mappings +- ti,edma-queue-priority-map: List of queue priority mappings +- ti,edma-default-queue: Default queue value + +Optional properties: +- ti,edma-reserved-channels: List of reserved channel regions +- ti,edma-reserved-slots: List of reserved slot regions +- ti,edma-xbar-event-map: Crossbar event to channel map + +Example: + +edma: edma@4900 { + reg = 0x4900 0x1; + interrupt-parent = intc; + interrupts = 12 13 14; + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-reserved-channels = 0 2 +14 2 +26 6 +48 4 +56 8; + ti,edma-reserved-slots = 0 2 + 14 2 + 26 6 + 48 4 + 56 8 + 64 127; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + ti,edma-xbar-event-map = 1 12 + 2 13; +}; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v8 1/9] ARM: davinci: move private EDMA API to arm/common
Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/Kconfig |1 + arch/arm/common/Kconfig|3 + arch/arm/common/Makefile |1 + arch/arm/{mach-davinci/dma.c = common/edma.c} |2 +- arch/arm/mach-davinci/Makefile |2 +- arch/arm/mach-davinci/board-tnetv107x-evm.c|2 +- arch/arm/mach-davinci/davinci.h|2 +- arch/arm/mach-davinci/devices-tnetv107x.c |2 +- arch/arm/mach-davinci/devices.c|6 +- arch/arm/mach-davinci/dm355.c |2 +- arch/arm/mach-davinci/dm365.c |2 +- arch/arm/mach-davinci/dm644x.c |2 +- arch/arm/mach-davinci/dm646x.c |2 +- arch/arm/mach-davinci/include/mach/da8xx.h |2 +- drivers/dma/edma.c |2 +- drivers/mmc/host/davinci_mmc.c |1 + include/linux/mfd/davinci_voicecodec.h |3 +- .../mach = include/linux/platform_data}/edma.h| 89 +--- include/linux/platform_data/spi-davinci.h |2 +- sound/soc/davinci/davinci-evm.c|1 + sound/soc/davinci/davinci-pcm.c|1 + sound/soc/davinci/davinci-pcm.h|2 +- sound/soc/davinci/davinci-sffsdr.c |5 +- 23 files changed, 33 insertions(+), 104 deletions(-) rename arch/arm/{mach-davinci/dma.c = common/edma.c} (99%) rename {arch/arm/mach-davinci/include/mach = include/linux/platform_data}/edma.h (59%) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5b71469..cb80a4d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -956,6 +956,7 @@ config ARCH_DAVINCI select GENERIC_IRQ_CHIP select HAVE_IDE select NEED_MACH_GPIO_H + select TI_PRIV_EDMA select USE_OF select ZONE_DMA help diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 9353184..c3a4e9c 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -17,3 +17,6 @@ config SHARP_PARAM config SHARP_SCOOP bool + +config TI_PRIV_EDMA + bool diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index dc8dd0d..9643c50 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o +obj-$(CONFIG_TI_PRIV_EDMA) += edma.o diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/common/edma.c similarity index 99% rename from arch/arm/mach-davinci/dma.c rename to arch/arm/common/edma.c index 45b7c71..dcaeb8e 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/common/edma.c @@ -25,7 +25,7 @@ #include linux/io.h #include linux/slab.h -#include mach/edma.h +#include linux/platform_data/edma.h /* Offsets matching struct edmacc_param */ #define PARM_OPT 0x00 diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index fb5c1aa..493a36b 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -5,7 +5,7 @@ # Common objects obj-y := time.o clock.o serial.o psc.o \ - dma.o usb.o common.o sram.o aemif.o + usb.o common.o sram.o aemif.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index 4f41602..10c9efd 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -26,12 +26,12 @@ #include linux/input.h #include linux/input/matrix_keypad.h #include linux/spi/spi.h +#include linux/platform_data/edma.h #include asm/mach/arch.h #include asm/mach-types.h #include mach/irqs.h -#include mach/edma.h #include mach/mux.h #include mach/cp_intc.h #include mach/tnetv107x.h diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index 12d544b..d26a6bc 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h @@ -23,9 +23,9 @@ #include linux/platform_device.h #include linux/spi/spi.h #include linux/platform_data/davinci_asp.h +#include linux/platform_data/edma.h #include linux/platform_data/keyscan-davinci.h #include mach/hardware.h -#include mach/edma.h #include media/davinci/vpfe_capture.h #include media/davinci/vpif_types.h diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c index 773ab07..ba37760 100644 --- a/arch/arm/mach-davinci/devices-tnetv107x.c +++ b/arch/arm
[PATCH v8 4/9] dmaengine: edma: enable build for AM33XX
Enable TI EDMA option on OMAP. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/dma/Kconfig |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 80b6997..3b7ea20 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -222,7 +222,7 @@ config SIRF_DMA config TI_EDMA tristate TI EDMA support - depends on ARCH_DAVINCI + depends on ARCH_DAVINCI || ARCH_OMAP select DMA_ENGINE select DMA_VIRTUAL_CHANNELS default n -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v8 7/9] spi: omap2-mcspi: convert to dma_request_slave_channel_compat()
Convert dmaengine channel requests to use dma_request_slave_channel_compat(). This supports the DT case of platforms requiring channel selection from either the OMAP DMA or the EDMA engine. AM33xx only boots from DT and is the only user implementing EDMA so in the !DT case we can default to the OMAP DMA filter. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Mark Brown broo...@opensource.wolfsonmicro.com --- drivers/spi/spi-omap2-mcspi.c | 27 --- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 893c3d7..38d0915 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -102,6 +102,9 @@ struct omap2_mcspi_dma { struct completion dma_tx_completion; struct completion dma_rx_completion; + + char dma_rx_ch_name[14]; + char dma_tx_ch_name[14]; }; /* use PIO for small transfers, avoiding DMA setup/teardown overhead and @@ -822,14 +825,23 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); sig = mcspi_dma-dma_rx_sync_dev; - mcspi_dma-dma_rx = dma_request_channel(mask, omap_dma_filter_fn, sig); + + mcspi_dma-dma_rx = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +sig, master-dev, +mcspi_dma-dma_rx_ch_name); + if (!mcspi_dma-dma_rx) { dev_err(spi-dev, no RX DMA engine channel for McSPI\n); return -EAGAIN; } sig = mcspi_dma-dma_tx_sync_dev; - mcspi_dma-dma_tx = dma_request_channel(mask, omap_dma_filter_fn, sig); + mcspi_dma-dma_tx = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +sig, master-dev, +mcspi_dma-dma_tx_ch_name); + if (!mcspi_dma-dma_tx) { dev_err(spi-dev, no TX DMA engine channel for McSPI\n); dma_release_channel(mcspi_dma-dma_rx); @@ -1240,12 +1252,13 @@ static int omap2_mcspi_probe(struct platform_device *pdev) goto free_master; for (i = 0; i master-num_chipselect; i++) { - char dma_ch_name[14]; + char *dma_rx_ch_name = mcspi-dma_channels[i].dma_rx_ch_name; + char *dma_tx_ch_name = mcspi-dma_channels[i].dma_tx_ch_name; struct resource *dma_res; - sprintf(dma_ch_name, rx%d, i); + sprintf(dma_rx_ch_name, rx%d, i); dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); + dma_rx_ch_name); if (!dma_res) { dev_dbg(pdev-dev, cannot get DMA RX channel\n); status = -ENODEV; @@ -1253,9 +1266,9 @@ static int omap2_mcspi_probe(struct platform_device *pdev) } mcspi-dma_channels[i].dma_rx_sync_dev = dma_res-start; - sprintf(dma_ch_name, tx%d, i); + sprintf(dma_tx_ch_name, tx%d, i); dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); + dma_tx_ch_name); if (!dma_res) { dev_dbg(pdev-dev, cannot get DMA TX channel\n); status = -ENODEV; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v8 9/9] ARM: dts: add AM33XX SPI DMA support
Adds DMA resources to the AM33XX SPI nodes. Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index aaf44122..a13d710 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -328,6 +328,11 @@ interrupt = 65; ti,spi-num-cs = 2; ti,hwmods = spi0; + dmas = edma 16 + edma 17 + edma 18 + edma 19; + dma-names = tx0, rx0, tx1, rx1; status = disabled; }; @@ -339,6 +344,11 @@ interrupt = 125; ti,spi-num-cs = 2; ti,hwmods = spi1; + dmas = edma 42 + edma 43 + edma 44 + edma 45; + dma-names = tx0, rx0, tx1, rx1; status = disabled; }; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v8 6/9] ARM: dts: add AM33XX EDMA support
Adds AM33XX EDMA support to the am33xx.dtsi as documented in Documentation/devicetree/bindings/dma/ti-edma.txt Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 0957645..aaf44122 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -87,6 +87,26 @@ reg = 0x4820 0x1000; }; + edma: edma@4900 { + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + reg = 0x4900 0x1, + 0x44e10f90 0x10; + interrupt-parent = intc; + interrupts = 12 13 14; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + }; + gpio1: gpio@44e07000 { compatible = ti,omap4-gpio; ti,hwmods = gpio1; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v8 8/9] spi: omap2-mcspi: add generic DMA request support to the DT binding
The binding definition is based on the generic DMA request binding Signed-off-by: Matt Porter mpor...@ti.com --- Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/omap-spi.txt b/Documentation/devicetree/bindings/spi/omap-spi.txt index 938809c..4c85c4c 100644 --- a/Documentation/devicetree/bindings/spi/omap-spi.txt +++ b/Documentation/devicetree/bindings/spi/omap-spi.txt @@ -10,7 +10,18 @@ Required properties: input. The default is D0 as input and D1 as output. -Example: +Optional properties: +- dmas: List of DMA specifiers with the controller specific format + as described in the generic DMA client binding. A tx and rx + specifier is required for each chip select. +- dma-names: List of DMA request names. These strings correspond + 1:1 with the DMA specifiers listed in dmas. The string naming + is to be rxN and txN for RX and TX requests, + respectively, where N equals the chip select number. + +Examples: + +[hwmod populated DMA resources] mcspi1: mcspi@1 { #address-cells = 1; @@ -20,3 +31,17 @@ mcspi1: mcspi@1 { ti,spi-num-cs = 4; }; +[generic DMA request binding] + +mcspi1: mcspi@1 { +#address-cells = 1; +#size-cells = 0; +compatible = ti,omap4-mcspi; +ti,hwmods = mcspi1; +ti,spi-num-cs = 2; +dmas = edma 42 + edma 43 + edma 44 + edma 45; +dma-names = tx0, rx0, tx1, rx1; +}; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH] arm: davinci: fix edma dmaengine induced null pointer dereference on da830
This adds additional error checking to the private edma api implementation to catch the case where the edma_alloc_slot() has an invalid controller parameter. The edma dmaengine wrapper driver relies on this condition being handled in order to avoid setting up a second edma dmaengine instance on DA830. Verfied using a DA850 with the second EDMA controller platform instance removed to simulate a DA830 which only has a single EDMA controller. Reported-by: Tomas Novotny to...@novotny.cz Signed-off-by: Matt Porter mpor...@ti.com Cc: sta...@kernel.org --- arch/arm/mach-davinci/dma.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/mach-davinci/dma.c index a685e97..f9eb836 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/mach-davinci/dma.c @@ -747,6 +747,8 @@ int edma_alloc_slot(unsigned ctlr, int slot) slot = EDMA_CHAN_SLOT(slot); if (slot 0) { + if (!edma_cc[ctlr]) + return -EINVAL; slot = edma_cc[ctlr]-num_channels; for (;;) { slot = find_next_zero_bit(edma_cc[ctlr]-edma_inuse, -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: EDMA and kernel panic (null pointer) on da830
On Tue, Feb 19, 2013 at 11:37:25AM +, Tomas Novotny wrote: On Tue, 19 Feb 2013 15:45:20 +0530, Sekhar Nori nsek...@ti.com wrote: + LAKML and Matt On 2/18/2013 9:09 PM, Tomas Novotny wrote: Hi all, I'm working on custom board based on AM1707, which is quite similar to EVM. Board file is derived from board-da830-evm.c. I'm unable to boot because of null pointer access in edma after upgrading linux-davinci to v3.7-davinci1. The DMA was working in 3.3 on my board. The pointer is accessed in the arch/arm/mach-davinci/dma.c in function edma_alloc_slot on the line 750: slot = edma_cc[ctlr]-num_channels; The problem is, that allocation is performed also with ctlr = 1, which shouldn't (?) be done on AM1707, as there is only one channel controller. I can see the problem on v3.7-davinci1 and latest commit (c03f8ea25) in the linux-davinci. I don't have EVM now, so I can't check untouched v3.7-davinci1. But changes are done only in the board file and DMA related code is the same. Is anybody here, who has similar issue? Or is it working for anybody here on the da830? If you want, I can post more information. For beginning, kernel log is attached. Thanks and best regards, Stoupa DEBUG switched on in dma.c; added own print of pointer in the edma_alloc_slot: Booting Linux on physical CPU 0x0 Linux version 3.8.0-rc7-08807-g00c74d8-dirty (tom@pcnovotny-t) (gcc version 4.6.3 (Sourcery CodeBench Lite 2012.03-57) ) #118 PREEM... CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177 CPU: VIVT data cache, VIVT instruction cache Machine: ELKO EP iNELS Central Unit 3 bootconsole [earlycon0] enabled Memory policy: ECC disabled, Data cache writeback DaVinci da830/omap-l137 rev2.0 variant 0x9 On node 0 totalpages: 16384 free_area_init_node: node 0, pgdat c038e0e0, node_mem_map c03ac000 DMA zone: 128 pages used for memmap DMA zone: 0 pages reserved DMA zone: 16256 pages, LIFO batch:3 pcpu-alloc: s0 r0 d32768 u32768 alloc=1*32768 pcpu-alloc: [0] 0 Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256 Kernel command line: console=ttyS1,115200n8 noinitrd rw rootwait rootfstype=jffs2 root=mtd3 mtdparts=davinci_nand.1:128k(u-boot_env)ro... PID hash table entries: 256 (order: -2, 1024 bytes) Dentry cache hash table entries: 8192 (order: 3, 32768 bytes) Inode-cache hash table entries: 4096 (order: 2, 16384 bytes) __ex_table already sorted, skipping sort Memory: 64MB = 64MB total Memory: 61168k/61168k available, 4368k reserved, 0K highmem Virtual kernel memory layout: vector : 0x - 0x1000 ( 4 kB) fixmap : 0xfff0 - 0xfffe ( 896 kB) vmalloc : 0xc480 - 0xff00 ( 936 MB) lowmem : 0xc000 - 0xc400 ( 64 MB) .text : 0xc0008000 - 0xc03441c8 (3313 kB) .init : 0xc0345000 - 0xc0365e00 ( 132 kB) .data : 0xc0366000 - 0xc038eb60 ( 163 kB) .bss : 0xc038eb60 - 0xc03ab578 ( 115 kB) SLUB: Genslabs=13, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 NR_IRQS:245 sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms Calibrating delay loop... 148.88 BogoMIPS (lpj=78) pid_max: default: 32768 minimum: 301 Mount-cache hash table entries: 512 CPU: Testing write buffer coherency: ok Setting up static identity map for 0xc02af890 - 0xc02af8cc DaVinci: 128 gpio irqs NET: Registered protocol family 16 DMA: preallocated 256 KiB pool for atomic coherent allocations edma edma: DMA REG BASE ADDR=fec0 bio: create slab bio-0 at 0 EDMA: edma_alloc_slot: edma_cc[ctlr]: c3847000 edma-dma-engine edma-dma-engine.0: TI EDMA DMA engine driver EDMA: edma_alloc_slot: edma_cc[ctlr]: (null) Unable to handle kernel NULL pointer dereference at virtual address pgd = c0004000 [] *pgd= Internal error: Oops: 5 [#1] PREEMPT ARM CPU: 0Not tainted (3.8.0-rc7-08807-g00c74d8-dirty #118) PC is at edma_alloc_slot+0x8c/0xf4 LR is at edma_alloc_slot+0x84/0xf4 pc : [c0013ac4]lr : [c0013abc]psr: 6053 sp : c3823e40 ip : 0001 fp : r10: c034520c r9 : c0365b9c r8 : c0383908 r7 : c038ee54 r6 : c038ee54 r5 : 0001 r4 : c386af10 r3 : c3822000 r2 : 0001 r1 : r0 : Flags: nZCv IRQs on FIQs off Mode SVC_32 ISA ARM Segment kernel Control: 0005317f Table: c0004000 DAC: 0017 Process swapper (pid: 1, stack limit = 0xc38221b8) Stack: (0xc3823e40 to 0xc3824000) 3e40: c386af10 c386af00 c387a010 c019c2b8 c03a6590 2053 3e60:
Re: [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
On Sat, Feb 09, 2013 at 09:35:53PM +0530, Sekhar Nori wrote: Hi Matt, This version introduces build/bisect issues. Ok, see later comment which addresses this... On 2/1/2013 11:52 PM, Matt Porter wrote: Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/common/edma.c @@ -25,7 +25,7 @@ #include linux/io.h #include linux/slab.h -#include mach/edma.h +#include linux/platform_data/edma.h /*---*/ +static int edma_of_read_u32_to_s8_array(const struct device_node *np, +const char *propname, s8 *out_values, +size_t sz) +{ + int ret; + + ret = of_property_read_u8_array(np, propname, out_values, sz); This needs linux/of.h to be included in this file. +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ + int ret = 0; + int i; + struct resource res; + void *xbar; + const s16 (*xbar_chans)[2]; + u32 shift, offset, mux; + + xbar_chans = devm_kzalloc(dev, + len/sizeof(s16) + 2*sizeof(s16), + GFP_KERNEL); + if (!xbar_chans) + return -ENOMEM; + + ret = of_address_to_resource(node, 1, res); of_address_to_resource() needs linux/of_address.h + if (IS_ERR_VALUE(ret)) This needs linux/err.h + return -EIO; + + xbar = devm_ioremap(dev, res.start, resource_size(res)); + if (!xbar) + return -ENOMEM; + + ret = edma_of_read_u32_to_s16_array(node, + ti,edma-xbar-event-map, + (s16 *)xbar_chans, + len/sizeof(u32)); + if (IS_ERR_VALUE(ret)) + return -EIO; + + for (i = 0; xbar_chans[i][0] != -1; i++) { + shift = (xbar_chans[i][1] % 4) * 8; + offset = xbar_chans[i][1] 2; + offset = 2; + mux = readl((void *)((u32)xbar + offset)); + mux = ~(0xff shift); + mux |= xbar_chans[i][0] shift; + writel(mux, (void *)((u32)xbar + offset)); + } + + pdata-xbar_chans = xbar_chans; There is no member xbar_chans ATM. It seems to be introduced in 03/10. + +static struct of_dma_filter_info edma_filter_info = { of_dma_filter_info needs linux/of_dma.h. + .filter_fn = edma_filter_fn, edma_filter_fn needs linux/edma.h BTW, I am not sure if you really intended to introduce EDMA DT support in this patch. I thought 1/10 was supposed to just move EDMA private API to a common place. If you really want to introduce DT support as well, that should be noted in the description. I think it is better done in a later patch. This was a complete fubared rebase for this patch. As you noticed, I got hunks from 3/10 in there and the bisect test didn't run so it was missed. I've got this fixed up for v8 which address all these comments that stem from that issue. diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c @@ -17,6 +17,7 @@ #include linux/timer.h #include linux/interrupt.h #include linux/platform_device.h +#include linux/platform_data/edma.h #include linux/gpio.h #include sound/core.h #include sound/pcm.h @@ -28,12 +29,14 @@ #include asm/plat-sffsdr/sffsdr-fpga.h #endif -#include mach/edma.h #include ../codecs/pcm3008.h #include davinci-pcm.h #include davinci-i2s.h +#define DAVINCI_DMA_MCBSP_TX 2 +#define DAVINCI_DMA_MCBSP_RX 3 + /* * CLKX and CLKR are the inputs for the Sample Rate Generator. * FSX and FSR are outputs, driven by the sample Rate Generator. @@ -124,7 +127,7 @@ static struct resource sffsdr_snd_resources[] = { static struct evm_snd_platform_data sffsdr_snd_data = { .tx_dma_ch = DAVINCI_DMA_MCBSP_TX, - .rx_dma_ch = DAVINCI_DMA_MCBSP_RX, + .rx_dma_ch = DAVINCI_DMA_MCBAP_RX, Typo here. Should be DAVINCI_DMA_MCBSP_RX. Unfortunately davinci-sffsdr.c seems to be broken already. Ok, fixed..definitely shouldn't break it more. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v3 3/3] mmc: davinci: get SG segment limits with dma_get_slave_sg_caps()
Replace the hardcoded values used to set max_segs/max_seg_size with a dma_get_slave_sg_caps() query to the dmaengine driver. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/mmc/host/davinci_mmc.c| 37 - include/linux/platform_data/mmc-davinci.h |3 --- 2 files changed, 10 insertions(+), 30 deletions(-) diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 2063677..583cbd0 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -144,18 +144,6 @@ /* MMCSD Init clock in Hz in opendrain mode */ #define MMCSD_INIT_CLOCK 20 -/* - * One scatterlist dma segment is at most MAX_CCNT rw_threshold units, - * and we handle up to MAX_NR_SG segments. MMC_BLOCK_BOUNCE kicks in only - * for drivers with max_segs == 1, making the segments bigger (64KB) - * than the page or two that's otherwise typical. nr_sg (passed from - * platform data) == 16 gives at least the same throughput boost, using - * EDMA transfer linkage instead of spending CPU time copying pages. - */ -#define MAX_CCNT ((1 16) - 1) - -#define MAX_NR_SG 16 - static unsigned rw_threshold = 32; module_param(rw_threshold, uint, S_IRUGO); MODULE_PARM_DESC(rw_threshold, @@ -216,8 +204,6 @@ struct mmc_davinci_host { u8 version; /* for ns in one cycle calculation */ unsigned ns_in_one_cycle; - /* Number of sg segments */ - u8 nr_sg; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; #endif @@ -1165,6 +1151,7 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) struct resource *r, *mem = NULL; int ret = 0, irq = 0; size_t mem_size; + struct dma_slave_sg_caps *dma_sg_caps; /* REVISIT: when we're fully converted, fail if pdata is NULL */ @@ -1214,12 +1201,6 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) init_mmcsd_host(host); - if (pdata-nr_sg) - host-nr_sg = pdata-nr_sg - 1; - - if (host-nr_sg MAX_NR_SG || !host-nr_sg) - host-nr_sg = MAX_NR_SG; - host-use_dma = use_dma; host-mmc_irq = irq; host-sdio_irq = platform_get_irq(pdev, 1); @@ -1248,14 +1229,16 @@ static int __init davinci_mmcsd_probe(struct platform_device *pdev) mmc-caps |= pdata-caps; mmc-ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; - /* With no iommu coalescing pages, each phys_seg is a hw_seg. -* Each hw_seg uses one EDMA parameter RAM slot, always one -* channel and then usually some linked slots. -*/ - mmc-max_segs = MAX_NR_SG; + /* Just check one channel for the DMA SG limits */ + dma_sg_caps = dma_get_slave_sg_caps( + host-dma_tx, + DMA_SLAVE_BUSWIDTH_4_BYTES, + rw_threshold / DMA_SLAVE_BUSWIDTH_4_BYTES); - /* EDMA limit per hw segment (one or two MBytes) */ - mmc-max_seg_size = MAX_CCNT * rw_threshold; + if (dma_sg_caps) { + mmc-max_segs = dma_sg_caps-max_seg_nr; + mmc-max_seg_size = dma_sg_caps-max_seg_len; + } /* MMC/SD controller limits for multiblock requests */ mmc-max_blk_size = 4095; /* BLEN is 12 bits */ diff --git a/include/linux/platform_data/mmc-davinci.h b/include/linux/platform_data/mmc-davinci.h index 5ba6b22..6910209 100644 --- a/include/linux/platform_data/mmc-davinci.h +++ b/include/linux/platform_data/mmc-davinci.h @@ -25,9 +25,6 @@ struct davinci_mmc_config { /* Version of the MMC/SD controller */ u8 version; - - /* Number of sg segments */ - u8 nr_sg; }; void davinci_setup_mmc(int module, struct davinci_mmc_config *config); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v3 2/3] dma: edma: add device_slave_sg_caps() support
Implement device_slave_sg_caps(). EDMA has a finite set of PaRAM slots available for linking a multi-segment SG transfer. In order to prevent any one channel from consuming all PaRAM slots to fulfill a large SG transfer, the driver reports a static per-channel max number of SG segments it will handle. The maximum size of an SG segment is limited by the addr_width and maxburst of a given transfer request. These values are provided by the client driver and used to calculate and return the maximum segment length. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/dma/edma.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index f424298..b779cee 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -72,6 +72,7 @@ struct edma_chan { dma_addr_t addr; int addr_width; int maxburst; + struct dma_slave_sg_capssg_caps; }; struct edma_cc { @@ -463,6 +464,20 @@ static void edma_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(echan-vchan.lock, flags); } +static struct dma_slave_sg_caps +*edma_get_slave_sg_caps(struct dma_chan *chan, + enum dma_slave_buswidth addr_width, + u32 maxburst) +{ + struct edma_chan *echan; + + echan = to_edma_chan(chan); + echan-sg_caps.max_seg_len = + (SZ_64K - 1) * addr_width * maxburst; + + return echan-sg_caps; +} + static size_t edma_desc_size(struct edma_desc *edesc) { int i; @@ -522,6 +537,7 @@ static void __init edma_chan_init(struct edma_cc *ecc, echan-ch_num = EDMA_CTLR_CHAN(ecc-ctlr, i); echan-ecc = ecc; echan-vchan.desc_free = edma_desc_free; + echan-sg_caps.max_seg_nr = MAX_NR_SG; vchan_init(echan-vchan, dma); @@ -538,6 +554,7 @@ static void edma_dma_init(struct edma_cc *ecc, struct dma_device *dma, dma-device_alloc_chan_resources = edma_alloc_chan_resources; dma-device_free_chan_resources = edma_free_chan_resources; dma-device_issue_pending = edma_issue_pending; + dma-device_slave_sg_caps = edma_get_slave_sg_caps; dma-device_tx_status = edma_tx_status; dma-device_control = edma_control; dma-dev = dev; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v3 1/3] dmaengine: add dma_get_slave_sg_caps()
Add a dmaengine API to retrieve slave SG transfer capabilities. The API is optionally implemented by dmaengine drivers and when unimplemented will return a NULL pointer. A client driver using this API provides the required dma channel, address width, and burst size of the transfer. dma_get_slave_sg_caps() returns an SG caps structure with the maximum number and size of SG segments that the given channel can handle. Signed-off-by: Matt Porter mpor...@ti.com --- include/linux/dmaengine.h | 40 1 file changed, 40 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index d3201e4..5b5b220 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -371,6 +371,19 @@ struct dma_slave_config { unsigned int slave_id; }; +/* struct dma_slave_sg_caps - expose SG transfer capability of a + * channel. + * + * @max_seg_nr: maximum number of SG segments supported on a SG/SLAVE + * channel (0 for no maximum or not a SG/SLAVE channel) + * @max_seg_len: maximum length of SG segments supported on a SG/SLAVE + * channel (0 for no maximum or not a SG/SLAVE channel) + */ +struct dma_slave_sg_caps { + u32 max_seg_nr; + u32 max_seg_len; +}; + static inline const char *dma_chan_name(struct dma_chan *chan) { return dev_name(chan-dev-device); @@ -534,6 +547,7 @@ struct dma_tx_state { * struct with auxiliary transfer status information, otherwise the call * will just return a simple status code * @device_issue_pending: push pending transactions to hardware + * @device_slave_sg_caps: return the slave SG capabilities */ struct dma_device { @@ -602,6 +616,9 @@ struct dma_device { dma_cookie_t cookie, struct dma_tx_state *txstate); void (*device_issue_pending)(struct dma_chan *chan); + struct dma_slave_sg_caps *(*device_slave_sg_caps)( + struct dma_chan *chan, enum dma_slave_buswidth addr_width, + u32 maxburst); }; static inline int dmaengine_device_control(struct dma_chan *chan, @@ -969,6 +986,29 @@ dma_set_tx_state(struct dma_tx_state *st, dma_cookie_t last, dma_cookie_t used, } } +/** + * dma_get_slave_sg_caps - get DMAC SG transfer capabilities + * @chan: target DMA channel + * @addr_width: address width of the DMA transfer + * @maxburst: maximum DMA transfer burst size + * + * Get SG transfer capabilities for a specified channel. If the dmaengine + * driver does not implement SG transfer capabilities then NULL is + * returned. + */ +static inline struct dma_slave_sg_caps +*dma_get_slave_sg_caps(struct dma_chan *chan, + enum dma_slave_buswidth addr_width, + u32 maxburst) +{ + if (chan-device-device_slave_sg_caps) + return chan-device-device_slave_sg_caps(chan, + addr_width, + maxburst); + + return NULL; +} + enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); #ifdef CONFIG_DMA_ENGINE enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v3 0/3] dmaengine: add slave sg transfer capabilities api
Changes since v2: - Change to a separate slave sg specific api. Drop the generic per-channel capabilities api that is not used. Changes since v1: - Use the existing dma_transaction_type enums instead of adding the mostly duplicated dmaengine_apis enums This series adds a new dmaengine api, dma_get_slave_sg_caps(), which may be used by a client driver to get slave SG transfer capabilities for a particular channel. At this time, these include the max number of segments and max length of a segment that a channel can handle for a SG transfer. Along with the API implementation, this series implements the backend device_slave_sg_caps() in the EDMA DMA Engine driver and converts the davinci_mmc driver to use dma_get_slave_sg_caps() to replace hardcoded limits. This is tested on the AM1808-EVM. Matt Porter (3): dmaengine: add dma_get_slave_sg_caps() dma: edma: add device_slave_sg_caps() support mmc: davinci: get SG segment limits with dma_get_slave_sg_caps() drivers/dma/edma.c| 17 drivers/mmc/host/davinci_mmc.c| 37 -- include/linux/dmaengine.h | 40 + include/linux/platform_data/mmc-davinci.h |3 --- 4 files changed, 67 insertions(+), 30 deletions(-) -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
On Sat, Feb 02, 2013 at 12:49:06PM +, Russell King wrote: On Fri, Feb 01, 2013 at 10:41:08AM -0800, Tony Lindgren wrote: * Matt Porter mpor...@ti.com [130201 10:25]: Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. I think this should rather go to drivers/dma/? Yes, it should, but just like OMAP, there's a conversion effort that needs to be gone through. It has one point - and only one point - which allows its continued existence under arch/arm, and that is it already exists there. If it was new code, the answer would be a definite NACK, but it isn't. It's pre-existing code which is already in mainline. It's merely being moved. Another plus point for it is that there does seem to be a DMA engine driver for it, so hopefully we'll see it killed off in arch/arm soon. That's definitely the plan. I was able to start this effort independently by converting the Davinci mmc and spi drivers to dmaengine before I took this step. I've got the next micro-step of addressing omap_hsmmc in process (pending on agreement on a dmaengine api change with Vinod), cleaning up the mcasp driver is also pending this series so that it can also be converted to dmaengine. Once mcasp (or davinci audio) is converted, we're rid of all the in-kernel users of the private API and can get rid of this...which also is helping clean up mach-davinci, of course. If I can get your ack on this patch that should move things along to these next steps. Thanks, Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
On Sat, Feb 02, 2013 at 12:01:37AM +, Sergei Shtylyov wrote: Hello. On 01-02-2013 22:59, Matt Porter wrote: Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. I think this should rather go to drivers/dma/? No, this is the private EDMA API. It's the analogous thing to the private OMAP dma API that is in plat-omap/dma.c. The actual dmaengine driver is in drivers/dma/edma.c as a wrapper around this...same way OMAP DMA engine conversion is being done. Keeps me wondering why we couldn't have the same with CPPI 4.1 when I proposed that, instead of waiting indefinitely for TI to convert it to drivers/dma/ directly. We could have working MUSB DMA on OMAP-L1x/Sitara all this time... Sigh. That is a shame. Yeah, I've pointed out that I was doing this exactly the same way as was acceptable for the OMAP DMA conversion since it was in RFC. The reasons are sound since in both cases, we have many drivers to convert that need to continue using the private DMA APIs. In case of CPPI 4.1, we'd only have to convert MUSB DMA driver. Other in-tree CPPI 4.1 having SoCs don't use it for anything but MUSB -- it even is sub-block of their MUSB device, AFAIK (I maybe wrong about Sitaras -- I don't know them well). Well, it's pretty clear to me now that there's good reason for it not landing in arch/arm/ so the obvious path is to do the dmaengine conversion and put it in drivers/dma/ if it's really a generic dma engine. I'm not sure why you express concern over the dma engine api not fitting with CPPI 4.1? If it doesn't work, work with Vinod to fix the api. It's expected, I'm working on dmaengine API changes right now to deal with a limitation of EDMA that needs to be abstracted. As pointed out, edma.c is already here in arch/arm/, so moving it doesn't add something new. It does let us regression test all platforms that use it (both Davinci and AM33xx) as I go through the conversion process. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
On Sat, Feb 02, 2013 at 10:16:43AM -0800, Tony Lindgren wrote: * Matt Porter mpor...@ti.com [130202 10:10]: If it doesn't work, work with Vinod to fix the api. It's expected, I'm working on dmaengine API changes right now to deal with a limitation of EDMA that needs to be abstracted. Regarding the DMA API limitations, I'm only aware of lack of capability to configure autoincrement at the device end. And that keeps us from converting all GPMC related devices using omap SDMA to use the DMA API. Are there other limitations currently known with the DMA API? Yes, I called one out when this was first posted as an RFC and was working it in parallel with this support. This one blocks AM33XX support in mmc and is the reason I split all of the mmc support out of the base edma dmaengine for am33xx series. Independent of the blockage, whatever we finally settle on to address this API need will also cleanup the use of magic values in the davinci mmc driver (that's part of the second thread below). RFC posting: https://patchwork.kernel.org/patch/1583531/ Posting with initial attempt at a caps api: http://www.spinics.net/lists/linux-mmc/msg18351.html Also, I haven't fully vetted the situation with cyclic transfers and EDMA, however, I'm pretty sure that we'll need some API changes there. The reason is that some Davinci platforms have no FIFO on their McASP implementation (that was a new feature added on DA8xx and also AM33xx). As such they have audio support implemented using ping-pong buffering via an SRAM buffer. There's been a number of patches ahead of all this that myself and others have worked upstream to get the SRAM stuff to be Davinci-independent (genalloc). But, at the end of all of this, there's no notion in a cyclic transfer of doing synchronized ping-pong buffering using two chain channels. This is how it is implemented (and documented in EDMA docs going back to the DSPs this IP first showed up on) using the private API. I'll be looking at this soon, but, I'm more interested in 1) getting the base support in 2) then the mmc stuff blocking DT populated platforms using omap_hsmmc (split out and posted) 3) v3 of the caps api w/ vinod's concerns address (working it not) Normally, I'm not going to bring up the cyclic transfer issue until I have some code to show or reference for discussion...but it's worth being aware. But, in any case, I'm confident that will gate having the mcasp driver that am33xx also uses converted to dmaengine. Except for the gpmc limitation you menationed, that's the last in kernel user of the privat edma api needed to be converted such that we can kill off arch/arm/common/edma.c once it's taken in. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
On Sat, Feb 02, 2013 at 07:06:06PM +, Sergei Shtylyov wrote: Hello. On 02-02-2013 22:07, Matt Porter wrote: Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. I think this should rather go to drivers/dma/? No, this is the private EDMA API. It's the analogous thing to the private OMAP dma API that is in plat-omap/dma.c. The actual dmaengine driver is in drivers/dma/edma.c as a wrapper around this...same way OMAP DMA engine conversion is being done. Keeps me wondering why we couldn't have the same with CPPI 4.1 when I proposed that, instead of waiting indefinitely for TI to convert it to drivers/dma/ directly. We could have working MUSB DMA on OMAP-L1x/Sitara all this time... Sigh. That is a shame. Yeah, I've pointed out that I was doing this exactly the same way as was acceptable for the OMAP DMA conversion since it was in RFC. The reasons are sound since in both cases, we have many drivers to convert that need to continue using the private DMA APIs. In case of CPPI 4.1, we'd only have to convert MUSB DMA driver. Other in-tree CPPI 4.1 having SoCs don't use it for anything but MUSB -- it even is sub-block of their MUSB device, AFAIK (I maybe wrong about Sitaras -- I don't know them well). Well, it's pretty clear to me now that there's good reason for it not landing in arch/arm/ so the obvious path is to do the dmaengine conversion and put it in drivers/dma/ if it's really a generic dma engine. I'm not sure why you express concern over the dma engine api not fitting with CPPI 4.1? It's not a DMA controller only, it's 3 distinct devices, with the DMA controller being one among them and using another one, the queue manager, as some sort of proxy. The third device doesn't exist on OMAP-L1x SoCs -- it's the buffer manager. Interesting, and you don't see a way to have this split between dmaengine and the musb driver? This all assumes there's even a match as RMK did raise concerns elsewhere in this thread. If it doesn't work, work with Vinod to fix the api. It's expected, I'm working on dmaengine API changes right now to deal with a limitation of EDMA that needs to be abstracted. Sorry, now it's TI's task. I no longer have time to work on this (my internal project to push OMAP-L1x support upstream has expired at Sep 2010) and my future in MV is very uncertain at this moment. Most probably I'll leave it (or be forced to leave). Too bad, it's certainly somebody's task. The people employed by TI have names too. ;) I suspect it falls to Felipe or Kishon these days, but I try to avoid USB as it's generally a source of pain. As pointed out, edma.c is already here in arch/arm/, so moving it doesn't add something new. It does let us regression test all platforms that use it (both Davinci and AM33xx) as I go through the conversion process. Could have been the same with CPPI 4.1 in theory if it was added to mach-davinci/ back in 2009... we'd then only have to move it. EDMA code is much older of course, so it's probably more justified. Absolutely, timing is everything. I can assure you I've flamed enough people internally about leaving this EDMA dmaengine conversion for so long. As you might have guessed, AM33xx is a bit of a driver for it, but all of this would have been quite a bit simpler had somebody taken a little effort and moved edma to dmaengine years ago when slave dma support was added to dmaengine. ;) -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v6 03/10] ARM: edma: add AM33XX support to the private EDMA API
On Fri, Feb 01, 2013 at 08:01:41AM +0200, Luciano Coelho wrote: On Thu, 2013-01-31 at 16:42 -0500, Matt Porter wrote: On Thu, Jan 31, 2013 at 08:58:39PM +, Arnd Bergmann wrote: On Thursday 31 January 2013, Matt Porter wrote: On Wed, Jan 30, 2013 at 09:32:58AM +, Arnd Bergmann wrote: On Wednesday 30 January 2013, Matt Porter wrote: + dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap); + of_dma_controller_register(dev-of_node, + of_dma_simple_xlate, + edma_filter_info); + } How do you actually deal with the problem mentioned by Padma, that the filter function does not know which edma instance it is looking at? If you assume that there can only be a single edma instance in the system, that is probably a limitation that should be documented somewhere, and ideally the probe() function should check for that. I make an assumption of one edma instance in the system in the case of DT being populated. This is always true right now as the only SoC with two EDMA controllers in existence is Davinci DA850. Until recently, Davinci had no DT support. Given the steady work being done today on DT support for DA850, it'll probably be something needed in 3.10. I will add a comment and check in probe() to capture this assumption and then plan to update separately to support DA850 booting from DT. Ok, sounds good. Hopefully by then we will already have a nicer way to write an xlate function that does not rely on a filter function. Yes, it would be nice to avoid what Padma had to do. I should have mentioned also that the second EDMA on DA850 has no DMA events of immediate use on it anyway. All the in-kernel users use events on the first controller, except for the second MMC instance. That's only used for a wl12xx module on the EVM and that driver has no DT support so it doesn't matter yet in the DT case. Because of this, DA850 can actually add EDMA DT support immediately (on top of this series) and add DMA support to the DT support already posted for the Davinci SPI and MMC client drivers. I haven't followed this whole discussion in details, but please notice that I'm aiming to get DT support for the WiLink modules (wlcore, wl12xx...) for 3.10. ;) Great, looks like we'll all be synced then. ;) -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v7 04/10] dmaengine: edma: enable build for AM33XX
Enable TI EDMA option on OMAP. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/dma/Kconfig |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 0b408bb..239020b 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -220,7 +220,7 @@ config SIRF_DMA config TI_EDMA tristate TI EDMA support - depends on ARCH_DAVINCI + depends on ARCH_DAVINCI || ARCH_OMAP select DMA_ENGINE select DMA_VIRTUAL_CHANNELS default n -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v7 00/10] DMA Engine support for AM33XX
Changes since v6: - Converted edma_of_read_*() to wrappers around of_property_read_*() - Fixed wording on the omap-spi generic DMA properties - Added comment/check to clarify that the driver only supports a single EDMA instance when booting from DT Changes since v5: - Dropped mmc portion and moved it to a separate series - Incorporate corrected version of dma_request_slave_channel_compat() - Fix #defines and enablement of TI_PRIV_EDMA option Changes since v4: - Fixed debug section mismatch in private edma api [01/14] - Respun format-patch to catch the platform_data/edma.h rename [01/14] - Removed address/size-cells from the EDMA binding [05/14] Changes since v3: - Rebased on 3.8-rc3 - No longer an RFC - Fixed bugs in DT/pdata parsing reported by Vaibhav Bedia - Restored all the Davinci pdata to const - Removed max_segs hack in favor of using dma_get_channel_caps() - Fixed extra parens, __raw_* accessors and, ioremap error checks in xbar handling - Removed excess license info in platform_data/edma.h - Removed unneeded reserved channels data for AM33xx - Removed test-specific pinmuxing from dts files - Adjusted mmc1 node to be disabled by default in the dtsi Changes since v2: - Rebased on 3.7-rc1 - Fixed bug in DT/pdata parsing first found by Gururaja that turned out to be masked by some toolchains - Dropped unused mach-omap2/devices.c hsmmc patch - Added AM33XX crossbar DMA event mux support - Added am335x-evm support Changes since v1: - Rebased on top of mainline from 12250d8 - Dropped the feature removal schedule patch - Implemented dma_request_slave_channel_compat() and converted the mmc and spi drivers to use it - Dropped unneeded #address-cells and #size-cells from EDMA DT support - Moved private EDMA header to linux/platform_data/ and removed some unneeded definitions - Fixed parsing of optional properties This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. The series applies on top of 3.8-rc5 and the following patches: - dmaengine DT support and edma dmaengine driver fix from the git://git.infradead.org/users/vkoul/slave-dma.git next branch The approach taken is similar to how OMAP DMA is being converted to DMA Engine support. With the functional EDMA private API already existing in mach-davinci/dma.c, we first move that to an ARM common area so it can be shared. Adding DT and runtime PM support to the private EDMA API implementation allows it to run on AM33xx. AM33xx *only* boots using DT so we leverage Jon's generic DT DMA helpers to register EDMA DMAC with the of_dma framework and then add support for calling the dma_request_slave_channel() API to both the mmc and spi drivers. With this series both BeagleBone and the AM335x EVM have working SPI DMA support (and MMC support with the separate MMC series). This is tested on BeagleBone with a SPI framebuffer driver and MMC rootfs. A trivial gpio DMA event misc driver was used to test the crossbar DMA event support. It is also tested on the AM335x EVM with the onboard SPI flash and MMC rootfs. The branch at https://github.com/ohporter/linux/tree/edma-dmaengine-am33xx-v7 has the complete series, dependencies, and some test drivers/defconfigs. Note that MMC can only be tested with a separate MMC dmaengine/DT series applied. Regression testing was done on AM180x-EVM (which also makes use of the EDMA dmaengine driver and the EDMA private API) using SD, SPI flash, and the onboard audio supported by the ASoC Davinci driver. Regression testing was also done on a BeagleBoard xM booting from the legacy board file using MMC rootfs. Matt Porter (10): ARM: davinci: move private EDMA API to arm/common ARM: edma: remove unused transfer controller handlers ARM: edma: add AM33XX support to the private EDMA API dmaengine: edma: enable build for AM33XX dmaengine: edma: Add TI EDMA device tree binding ARM: dts: add AM33XX EDMA support dmaengine: add dma_request_slave_channel_compat() spi: omap2-mcspi: convert to dma_request_slave_channel_compat() spi: omap2-mcspi: add generic DMA request support to the DT binding ARM: dts: add AM33XX SPI DMA support Documentation/devicetree/bindings/dma/ti-edma.txt | 49 +++ Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +- arch/arm/Kconfig |1 + arch/arm/boot/dts/am33xx.dtsi | 30 ++ arch/arm/common/Kconfig|3 + arch/arm/common/Makefile |1 + arch/arm/{mach-davinci
[PATCH v7 02/10] ARM: edma: remove unused transfer controller handlers
Fix build on OMAP, the irqs are undefined on AM33xx. These error interrupt handlers were hardcoded as disabled so since they are unused code, simply remove them. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c | 37 - 1 file changed, 37 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index aa4a49a..3440d16 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -494,26 +494,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) return IRQ_HANDLED; } -/** - * - * Transfer controller error interrupt handlers - * - */ - -#define tc_errs_handledfalse /* disabled as long as they're NOPs */ - -static irqreturn_t dma_tc0err_handler(int irq, void *data) -{ - dev_dbg(data, dma_tc0err_handler\n); - return IRQ_HANDLED; -} - -static irqreturn_t dma_tc1err_handler(int irq, void *data) -{ - dev_dbg(data, dma_tc1err_handler\n); - return IRQ_HANDLED; -} - static int reserve_contiguous_slots(int ctlr, unsigned int id, unsigned int num_slots, unsigned int start_slot) @@ -1743,23 +1723,6 @@ static int edma_probe(struct platform_device *pdev) arch_num_cc++; } - if (tc_errs_handled) { - status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0, - edma_tc0, pdev-dev); - if (status 0) { - dev_dbg(pdev-dev, request_irq %d failed -- %d\n, - IRQ_TCERRINT0, status); - return status; - } - status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0, - edma_tc1, pdev-dev); - if (status 0) { - dev_dbg(pdev-dev, request_irq %d -- %d\n, - IRQ_TCERRINT, status); - return status; - } - } - return 0; fail: -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v7 08/10] spi: omap2-mcspi: convert to dma_request_slave_channel_compat()
Convert dmaengine channel requests to use dma_request_slave_channel_compat(). This supports the DT case of platforms requiring channel selection from either the OMAP DMA or the EDMA engine. AM33xx only boots from DT and is the only user implementing EDMA so in the !DT case we can default to the OMAP DMA filter. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Mark Brown broo...@opensource.wolfsonmicro.com --- drivers/spi/spi-omap2-mcspi.c | 65 - 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index b610f52..2c02c02 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -102,6 +102,9 @@ struct omap2_mcspi_dma { struct completion dma_tx_completion; struct completion dma_rx_completion; + + char dma_rx_ch_name[14]; + char dma_tx_ch_name[14]; }; /* use PIO for small transfers, avoiding DMA setup/teardown overhead and @@ -822,14 +825,23 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); sig = mcspi_dma-dma_rx_sync_dev; - mcspi_dma-dma_rx = dma_request_channel(mask, omap_dma_filter_fn, sig); + + mcspi_dma-dma_rx = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +sig, master-dev, +mcspi_dma-dma_rx_ch_name); + if (!mcspi_dma-dma_rx) { dev_err(spi-dev, no RX DMA engine channel for McSPI\n); return -EAGAIN; } sig = mcspi_dma-dma_tx_sync_dev; - mcspi_dma-dma_tx = dma_request_channel(mask, omap_dma_filter_fn, sig); + mcspi_dma-dma_tx = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +sig, master-dev, +mcspi_dma-dma_tx_ch_name); + if (!mcspi_dma-dma_tx) { dev_err(spi-dev, no TX DMA engine channel for McSPI\n); dma_release_channel(mcspi_dma-dma_rx); @@ -1223,29 +1235,42 @@ static int omap2_mcspi_probe(struct platform_device *pdev) goto free_master; for (i = 0; i master-num_chipselect; i++) { - char dma_ch_name[14]; + char *dma_rx_ch_name = mcspi-dma_channels[i].dma_rx_ch_name; + char *dma_tx_ch_name = mcspi-dma_channels[i].dma_tx_ch_name; struct resource *dma_res; - sprintf(dma_ch_name, rx%d, i); - dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); - if (!dma_res) { - dev_dbg(pdev-dev, cannot get DMA RX channel\n); - status = -ENODEV; - break; - } + sprintf(dma_rx_ch_name, rx%d, i); + if (!pdev-dev.of_node) { + dma_res = + platform_get_resource_byname(pdev, +IORESOURCE_DMA, +dma_rx_ch_name); + if (!dma_res) { + dev_dbg(pdev-dev, + cannot get DMA RX channel\n); + status = -ENODEV; + break; + } - mcspi-dma_channels[i].dma_rx_sync_dev = dma_res-start; - sprintf(dma_ch_name, tx%d, i); - dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); - if (!dma_res) { - dev_dbg(pdev-dev, cannot get DMA TX channel\n); - status = -ENODEV; - break; + mcspi-dma_channels[i].dma_rx_sync_dev = + dma_res-start; } + sprintf(dma_tx_ch_name, tx%d, i); + if (!pdev-dev.of_node) { + dma_res = + platform_get_resource_byname(pdev, +IORESOURCE_DMA, +dma_tx_ch_name); + if (!dma_res) { + dev_dbg(pdev-dev, + cannot get DMA TX channel\n); + status = -ENODEV; + break; + } - mcspi-dma_channels[i].dma_tx_sync_dev = dma_res-start; + mcspi-dma_channels[i].dma_tx_sync_dev = + dma_res-start
[PATCH v7 05/10] dmaengine: edma: Add TI EDMA device tree binding
The binding definition is based on the generic DMA controller binding. Signed-off-by: Matt Porter mpor...@ti.com --- Documentation/devicetree/bindings/dma/ti-edma.txt | 49 + 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt new file mode 100644 index 000..075a60e3 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt @@ -0,0 +1,49 @@ +TI EDMA + +Required properties: +- compatible : ti,edma3 +- ti,hwmods: Name of the hwmods associated to the EDMA +- ti,edma-regions: Number of regions +- ti,edma-slots: Number of slots +- ti,edma-queue-tc-map: List of transfer control to queue mappings +- ti,edma-queue-priority-map: List of queue priority mappings +- ti,edma-default-queue: Default queue value + +Optional properties: +- ti,edma-reserved-channels: List of reserved channel regions +- ti,edma-reserved-slots: List of reserved slot regions +- ti,edma-xbar-event-map: Crossbar event to channel map + +Example: + +edma: edma@4900 { + reg = 0x4900 0x1; + interrupt-parent = intc; + interrupts = 12 13 14; + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-reserved-channels = 0 2 +14 2 +26 6 +48 4 +56 8; + ti,edma-reserved-slots = 0 2 + 14 2 + 26 6 + 48 4 + 56 8 + 64 127; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + ti,edma-xbar-event-map = 1 12 + 2 13; +}; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v7 06/10] ARM: dts: add AM33XX EDMA support
Adds AM33XX EDMA support to the am33xx.dtsi as documented in Documentation/devicetree/bindings/dma/ti-edma.txt Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index c2f14e8..e711ffb 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -87,6 +87,26 @@ reg = 0x4820 0x1000; }; + edma: edma@4900 { + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + reg = 0x4900 0x1, + 0x44e10f90 0x10; + interrupt-parent = intc; + interrupts = 12 13 14; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + }; + gpio1: gpio@44e07000 { compatible = ti,omap4-gpio; ti,hwmods = gpio1; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v7 07/10] dmaengine: add dma_request_slave_channel_compat()
Adds a dma_request_slave_channel_compat() wrapper which accepts both the arguments from dma_request_channel() and dma_request_slave_channel(). Based on whether the driver is instantiated via DT, the appropriate channel request call will be made. This allows for a much cleaner migration of drivers to the dmaengine DT API as platforms continue to be mixed between those that boot using DT and those that do not. Suggested-by: Tony Lindgren t...@atomide.com Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Tony Lindgren t...@atomide.com Acked-by: Arnd Bergmann a...@arndb.de --- include/linux/dmaengine.h | 16 1 file changed, 16 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index bfcdecb..17d8ffd 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -1001,6 +1001,22 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel((mask), x, y) +#define dma_request_slave_channel_compat(mask, x, y, dev, name) \ + __dma_request_slave_channel_compat((mask), x, y, dev, name) + +static inline struct dma_chan +*__dma_request_slave_channel_compat(dma_cap_mask_t *mask, dma_filter_fn fn, + void *fn_param, struct device *dev, + char *name) +{ + struct dma_chan *chan; + + chan = dma_request_slave_channel(dev, name); + if (chan) + return chan; + + return __dma_request_channel(mask, fn, fn_param); +} /* --- Helper iov-locking functions --- */ -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/Kconfig |1 + arch/arm/common/Kconfig|3 + arch/arm/common/Makefile |1 + arch/arm/{mach-davinci/dma.c = common/edma.c} | 209 +++- arch/arm/mach-davinci/Makefile |2 +- arch/arm/mach-davinci/board-tnetv107x-evm.c|2 +- arch/arm/mach-davinci/davinci.h|2 +- arch/arm/mach-davinci/devices-tnetv107x.c |2 +- arch/arm/mach-davinci/devices.c|6 +- arch/arm/mach-davinci/dm355.c |2 +- arch/arm/mach-davinci/dm365.c |2 +- arch/arm/mach-davinci/dm644x.c |2 +- arch/arm/mach-davinci/dm646x.c |2 +- arch/arm/mach-davinci/include/mach/da8xx.h |2 +- drivers/dma/edma.c |2 +- drivers/mmc/host/davinci_mmc.c |1 + include/linux/mfd/davinci_voicecodec.h |3 +- .../mach = include/linux/platform_data}/edma.h| 89 + include/linux/platform_data/spi-davinci.h |2 +- sound/soc/davinci/davinci-evm.c|1 + sound/soc/davinci/davinci-pcm.c|1 + sound/soc/davinci/davinci-pcm.h|2 +- sound/soc/davinci/davinci-sffsdr.c |7 +- 23 files changed, 240 insertions(+), 106 deletions(-) rename arch/arm/{mach-davinci/dma.c = common/edma.c} (90%) rename {arch/arm/mach-davinci/include/mach = include/linux/platform_data}/edma.h (59%) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 67874b8..7637d31 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -932,6 +932,7 @@ config ARCH_DAVINCI select GENERIC_IRQ_CHIP select HAVE_IDE select NEED_MACH_GPIO_H + select TI_PRIV_EDMA select USE_OF select ZONE_DMA help diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 45ceeb0..9e32d0d 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -40,3 +40,6 @@ config SHARP_PARAM config SHARP_SCOOP bool + +config TI_PRIV_EDMA + bool diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index e8a4e58..d09a39b 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o +obj-$(CONFIG_TI_PRIV_EDMA) += edma.o diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/common/edma.c similarity index 90% rename from arch/arm/mach-davinci/dma.c rename to arch/arm/common/edma.c index a685e97..aa4a49a 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/common/edma.c @@ -25,7 +25,7 @@ #include linux/io.h #include linux/slab.h -#include mach/edma.h +#include linux/platform_data/edma.h /* Offsets matching struct edmacc_param */ #define PARM_OPT 0x00 @@ -1386,8 +1386,213 @@ void edma_clear_event(unsigned channel) EXPORT_SYMBOL(edma_clear_event); /*---*/ +static int edma_of_read_u32_to_s8_array(const struct device_node *np, +const char *propname, s8 *out_values, +size_t sz) +{ + int ret; + + ret = of_property_read_u8_array(np, propname, out_values, sz); + if (ret) + return ret; + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_of_read_u32_to_s16_array(const struct device_node *np, +const char *propname, s16 *out_values, +size_t sz) +{ + int ret; + + ret = of_property_read_u16_array(np, propname, out_values, sz); + if (ret) + return ret; + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ + int ret = 0; + int i; + struct resource res; + void *xbar; + const s16 (*xbar_chans)[2]; + u32 shift, offset, mux; + + xbar_chans = devm_kzalloc(dev, + len/sizeof(s16) + 2*sizeof(s16), + GFP_KERNEL); + if (!xbar_chans) + return -ENOMEM; + + ret = of_address_to_resource(node, 1, res); + if (IS_ERR_VALUE(ret
[PATCH v7 10/10] ARM: dts: add AM33XX SPI DMA support
Adds DMA resources to the AM33XX SPI nodes. Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index e711ffb..ddf702a 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -328,6 +328,11 @@ interrupt = 65; ti,spi-num-cs = 2; ti,hwmods = spi0; + dmas = edma 16 + edma 17 + edma 18 + edma 19; + dma-names = tx0, rx0, tx1, rx1; status = disabled; }; @@ -339,6 +344,11 @@ interrupt = 125; ti,spi-num-cs = 2; ti,hwmods = spi1; + dmas = edma 42 + edma 43 + edma 44 + edma 45; + dma-names = tx0, rx0, tx1, rx1; status = disabled; }; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v7 09/10] spi: omap2-mcspi: add generic DMA request support to the DT binding
The binding definition is based on the generic DMA request binding Signed-off-by: Matt Porter mpor...@ti.com --- Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/omap-spi.txt b/Documentation/devicetree/bindings/spi/omap-spi.txt index 938809c..4c85c4c 100644 --- a/Documentation/devicetree/bindings/spi/omap-spi.txt +++ b/Documentation/devicetree/bindings/spi/omap-spi.txt @@ -10,7 +10,18 @@ Required properties: input. The default is D0 as input and D1 as output. -Example: +Optional properties: +- dmas: List of DMA specifiers with the controller specific format + as described in the generic DMA client binding. A tx and rx + specifier is required for each chip select. +- dma-names: List of DMA request names. These strings correspond + 1:1 with the DMA specifiers listed in dmas. The string naming + is to be rxN and txN for RX and TX requests, + respectively, where N equals the chip select number. + +Examples: + +[hwmod populated DMA resources] mcspi1: mcspi@1 { #address-cells = 1; @@ -20,3 +31,17 @@ mcspi1: mcspi@1 { ti,spi-num-cs = 4; }; +[generic DMA request binding] + +mcspi1: mcspi@1 { +#address-cells = 1; +#size-cells = 0; +compatible = ti,omap4-mcspi; +ti,hwmods = mcspi1; +ti,spi-num-cs = 2; +dmas = edma 42 + edma 43 + edma 44 + edma 45; +dma-names = tx0, rx0, tx1, rx1; +}; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v7 03/10] ARM: edma: add AM33XX support to the private EDMA API
Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Adds AM33XX EDMA crossbar event mux support. Enables build on OMAP. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c | 96 arch/arm/plat-omap/Kconfig |1 + include/linux/platform_data/edma.h |1 + 3 files changed, 89 insertions(+), 9 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 3440d16..bd2416a 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -24,6 +24,13 @@ #include linux/platform_device.h #include linux/io.h #include linux/slab.h +#include linux/edma.h +#include linux/err.h +#include linux/of_address.h +#include linux/of_device.h +#include linux/of_dma.h +#include linux/of_irq.h +#include linux/pm_runtime.h #include linux/platform_data/edma.h @@ -723,6 +730,9 @@ EXPORT_SYMBOL(edma_free_channel); */ int edma_alloc_slot(unsigned ctlr, int slot) { + if (!edma_cc[ctlr]) + return -EINVAL; + if (slot = 0) slot = EDMA_CHAN_SLOT(slot); @@ -1575,27 +1585,69 @@ static struct of_dma_filter_info edma_filter_info = { static int edma_probe(struct platform_device *pdev) { struct edma_soc_info**info = pdev-dev.platform_data; + struct edma_soc_info*ninfo[EDMA_MAX_CC] = {NULL, NULL}; + struct edma_soc_infotmpinfo; const s8(*queue_priority_mapping)[2]; const s8(*queue_tc_mapping)[2]; int i, j, off, ln, found = 0; int status = -1; const s16 (*rsv_chans)[2]; const s16 (*rsv_slots)[2]; + const s16 (*xbar_chans)[2]; int irq[EDMA_MAX_CC] = {0, 0}; int err_irq[EDMA_MAX_CC] = {0, 0}; - struct resource *r[EDMA_MAX_CC] = {NULL}; + struct resource *r[EDMA_MAX_CC] = {NULL, NULL}; + struct resource res[EDMA_MAX_CC]; resource_size_t len[EDMA_MAX_CC]; charres_name[10]; charirq_name[10]; + struct device_node *node = pdev-dev.of_node; + struct device *dev = pdev-dev; + int ret; + + if (node) { + /* Check if this is a second instance registered */ + if (arch_num_cc) { + dev_err(dev, only one EDMA instance is supported via DT\n); + return -ENODEV; + } + info = ninfo; + edma_of_parse_dt(dev, node, tmpinfo); + info[0] = tmpinfo; + + dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap); + of_dma_controller_register(dev-of_node, + of_dma_simple_xlate, + edma_filter_info); + } if (!info) return -ENODEV; + pm_runtime_enable(dev); + ret = pm_runtime_get_sync(dev); + if (IS_ERR_VALUE(ret)) { + dev_err(dev, pm_runtime_get_sync() failed\n); + return ret; + } + for (j = 0; j EDMA_MAX_CC; j++) { - sprintf(res_name, edma_cc%d, j); - r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM, + if (!info[j]) { + if (!found) + return -ENODEV; + break; + } + if (node) { + ret = of_address_to_resource(node, j, res[j]); + if (!IS_ERR_VALUE(ret)) + r[j] = res[j]; + } else { + sprintf(res_name, edma_cc%d, j); + r[j] = platform_get_resource_byname(pdev, + IORESOURCE_MEM, res_name); - if (!r[j] || !info[j]) { + } + if (!r[j]) { if (found) break; else @@ -1670,8 +1722,22 @@ static int edma_probe(struct platform_device *pdev) } } - sprintf(irq_name, edma%d, j); - irq[j] = platform_get_irq_byname(pdev, irq_name); + /* Clear the xbar mapped channels in unused list */ + xbar_chans = info[j]-xbar_chans; + if (xbar_chans) { + for (i = 0; xbar_chans[i][1] != -1; i++) { + off = xbar_chans[i][1]; + clear_bits(off, 1, + edma_cc[j
Re: [PATCH v7 05/10] dmaengine: edma: Add TI EDMA device tree binding
On Fri, Feb 01, 2013 at 01:22:50PM -0500, Matt Porter wrote: The binding definition is based on the generic DMA controller binding. Signed-off-by: Matt Porter mpor...@ti.com Grant or Rob, can I get an ack on this binding and others in this series? --- Documentation/devicetree/bindings/dma/ti-edma.txt | 49 + 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt new file mode 100644 index 000..075a60e3 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt @@ -0,0 +1,49 @@ +TI EDMA + +Required properties: +- compatible : ti,edma3 +- ti,hwmods: Name of the hwmods associated to the EDMA +- ti,edma-regions: Number of regions +- ti,edma-slots: Number of slots +- ti,edma-queue-tc-map: List of transfer control to queue mappings +- ti,edma-queue-priority-map: List of queue priority mappings +- ti,edma-default-queue: Default queue value + +Optional properties: +- ti,edma-reserved-channels: List of reserved channel regions +- ti,edma-reserved-slots: List of reserved slot regions +- ti,edma-xbar-event-map: Crossbar event to channel map + +Example: + +edma: edma@4900 { + reg = 0x4900 0x1; + interrupt-parent = intc; + interrupts = 12 13 14; + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-reserved-channels = 0 2 + 14 2 + 26 6 + 48 4 + 56 8; + ti,edma-reserved-slots = 0 2 + 14 2 + 26 6 + 48 4 + 56 8 + 64 127; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + ti,edma-xbar-event-map = 1 12 + 2 13; +}; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v7 07/10] dmaengine: add dma_request_slave_channel_compat()
On Fri, Feb 01, 2013 at 01:22:52PM -0500, Matt Porter wrote: Adds a dma_request_slave_channel_compat() wrapper which accepts both the arguments from dma_request_channel() and dma_request_slave_channel(). Based on whether the driver is instantiated via DT, the appropriate channel request call will be made. This allows for a much cleaner migration of drivers to the dmaengine DT API as platforms continue to be mixed between those that boot using DT and those that do not. Suggested-by: Tony Lindgren t...@atomide.com Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Tony Lindgren t...@atomide.com Acked-by: Arnd Bergmann a...@arndb.de Vinod, can I get an ack on this one? -Matt --- include/linux/dmaengine.h | 16 1 file changed, 16 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index bfcdecb..17d8ffd 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -1001,6 +1001,22 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel((mask), x, y) +#define dma_request_slave_channel_compat(mask, x, y, dev, name) \ + __dma_request_slave_channel_compat((mask), x, y, dev, name) + +static inline struct dma_chan +*__dma_request_slave_channel_compat(dma_cap_mask_t *mask, dma_filter_fn fn, + void *fn_param, struct device *dev, + char *name) +{ + struct dma_chan *chan; + + chan = dma_request_slave_channel(dev, name); + if (chan) + return chan; + + return __dma_request_channel(mask, fn, fn_param); +} /* --- Helper iov-locking functions --- */ -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v7 00/10] DMA Engine support for AM33XX
On Fri, Feb 01, 2013 at 01:22:45PM -0500, Matt Porter wrote: snip This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. Tony, Will you be able to take this series in through your tree? It appears we just need acks on the new bindings and the compat api change. I haven't heard from you or Benoit on the dts patches so it seems those are ready as well. Thanks, Matt The series applies on top of 3.8-rc5 and the following patches: - dmaengine DT support and edma dmaengine driver fix from the git://git.infradead.org/users/vkoul/slave-dma.git next branch The approach taken is similar to how OMAP DMA is being converted to DMA Engine support. With the functional EDMA private API already existing in mach-davinci/dma.c, we first move that to an ARM common area so it can be shared. Adding DT and runtime PM support to the private EDMA API implementation allows it to run on AM33xx. AM33xx *only* boots using DT so we leverage Jon's generic DT DMA helpers to register EDMA DMAC with the of_dma framework and then add support for calling the dma_request_slave_channel() API to both the mmc and spi drivers. With this series both BeagleBone and the AM335x EVM have working SPI DMA support (and MMC support with the separate MMC series). This is tested on BeagleBone with a SPI framebuffer driver and MMC rootfs. A trivial gpio DMA event misc driver was used to test the crossbar DMA event support. It is also tested on the AM335x EVM with the onboard SPI flash and MMC rootfs. The branch at https://github.com/ohporter/linux/tree/edma-dmaengine-am33xx-v7 has the complete series, dependencies, and some test drivers/defconfigs. Note that MMC can only be tested with a separate MMC dmaengine/DT series applied. Regression testing was done on AM180x-EVM (which also makes use of the EDMA dmaengine driver and the EDMA private API) using SD, SPI flash, and the onboard audio supported by the ASoC Davinci driver. Regression testing was also done on a BeagleBoard xM booting from the legacy board file using MMC rootfs. Matt Porter (10): ARM: davinci: move private EDMA API to arm/common ARM: edma: remove unused transfer controller handlers ARM: edma: add AM33XX support to the private EDMA API dmaengine: edma: enable build for AM33XX dmaengine: edma: Add TI EDMA device tree binding ARM: dts: add AM33XX EDMA support dmaengine: add dma_request_slave_channel_compat() spi: omap2-mcspi: convert to dma_request_slave_channel_compat() spi: omap2-mcspi: add generic DMA request support to the DT binding ARM: dts: add AM33XX SPI DMA support Documentation/devicetree/bindings/dma/ti-edma.txt | 49 +++ Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +- arch/arm/Kconfig |1 + arch/arm/boot/dts/am33xx.dtsi | 30 ++ arch/arm/common/Kconfig|3 + arch/arm/common/Makefile |1 + arch/arm/{mach-davinci/dma.c = common/edma.c} | 342 +--- arch/arm/mach-davinci/Makefile |2 +- arch/arm/mach-davinci/board-tnetv107x-evm.c|2 +- arch/arm/mach-davinci/davinci.h|2 +- arch/arm/mach-davinci/devices-tnetv107x.c |2 +- arch/arm/mach-davinci/devices.c|6 +- arch/arm/mach-davinci/dm355.c |2 +- arch/arm/mach-davinci/dm365.c |2 +- arch/arm/mach-davinci/dm644x.c |2 +- arch/arm/mach-davinci/dm646x.c |2 +- arch/arm/mach-davinci/include/mach/da8xx.h |2 +- arch/arm/plat-omap/Kconfig |1 + drivers/dma/Kconfig|2 +- drivers/dma/edma.c |2 +- drivers/mmc/host/davinci_mmc.c |1 + drivers/spi/spi-omap2-mcspi.c | 65 ++-- include/linux/dmaengine.h | 16 + include/linux/mfd/davinci_voicecodec.h |3 +- .../mach = include/linux/platform_data}/edma.h| 90 +- include/linux/platform_data/spi-davinci.h |2 +- sound/soc/davinci/davinci-evm.c|1 + sound/soc/davinci/davinci-pcm.c|1 + sound/soc/davinci/davinci-pcm.h|2 +- sound/soc/davinci/davinci-sffsdr.c |7 +- 30 files changed, 496 insertions(+), 174 deletions(-) create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt rename arch/arm/{mach-davinci/dma.c = common/edma.c} (86%) rename {arch/arm/mach-davinci/include/mach = include/linux/platform_data}/edma.h
Re: [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
On Fri, Feb 01, 2013 at 06:41:08PM +, Tony Lindgren wrote: * Matt Porter mpor...@ti.com [130201 10:25]: Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. I think this should rather go to drivers/dma/? No, this is the private EDMA API. It's the analogous thing to the private OMAP dma API that is in plat-omap/dma.c. The actual dmaengine driver is in drivers/dma/edma.c as a wrapper around this...same way OMAP DMA engine conversion is being done. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v7 01/10] ARM: davinci: move private EDMA API to arm/common
On Fri, Feb 01, 2013 at 07:52:46PM +, Sergei Shtylyov wrote: Hello. On 02/01/2013 09:49 PM, Matt Porter wrote: Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. I think this should rather go to drivers/dma/? No, this is the private EDMA API. It's the analogous thing to the private OMAP dma API that is in plat-omap/dma.c. The actual dmaengine driver is in drivers/dma/edma.c as a wrapper around this...same way OMAP DMA engine conversion is being done. Keeps me wondering why we couldn't have the same with CPPI 4.1 when I proposed that, instead of waiting indefinitely for TI to convert it to drivers/dma/ directly. We could have working MUSB DMA on OMAP-L1x/Sitara all this time... Sigh. That is a shame. Yeah, I've pointed out that I was doing this exactly the same way as was acceptable for the OMAP DMA conversion since it was in RFC. The reasons are sound since in both cases, we have many drivers to convert that need to continue using the private DMA APIs. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v6 03/10] ARM: edma: add AM33XX support to the private EDMA API
On Wed, Jan 30, 2013 at 09:32:58AM +, Arnd Bergmann wrote: On Wednesday 30 January 2013, Matt Porter wrote: + dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap); + of_dma_controller_register(dev-of_node, + of_dma_simple_xlate, + edma_filter_info); + } How do you actually deal with the problem mentioned by Padma, that the filter function does not know which edma instance it is looking at? If you assume that there can only be a single edma instance in the system, that is probably a limitation that should be documented somewhere, and ideally the probe() function should check for that. I make an assumption of one edma instance in the system in the case of DT being populated. This is always true right now as the only SoC with two EDMA controllers in existence is Davinci DA850. Until recently, Davinci had no DT support. Given the steady work being done today on DT support for DA850, it'll probably be something needed in 3.10. I will add a comment and check in probe() to capture this assumption and then plan to update separately to support DA850 booting from DT. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v6 03/10] ARM: edma: add AM33XX support to the private EDMA API
On Thu, Jan 31, 2013 at 08:58:39PM +, Arnd Bergmann wrote: On Thursday 31 January 2013, Matt Porter wrote: On Wed, Jan 30, 2013 at 09:32:58AM +, Arnd Bergmann wrote: On Wednesday 30 January 2013, Matt Porter wrote: + dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap); + of_dma_controller_register(dev-of_node, + of_dma_simple_xlate, + edma_filter_info); + } How do you actually deal with the problem mentioned by Padma, that the filter function does not know which edma instance it is looking at? If you assume that there can only be a single edma instance in the system, that is probably a limitation that should be documented somewhere, and ideally the probe() function should check for that. I make an assumption of one edma instance in the system in the case of DT being populated. This is always true right now as the only SoC with two EDMA controllers in existence is Davinci DA850. Until recently, Davinci had no DT support. Given the steady work being done today on DT support for DA850, it'll probably be something needed in 3.10. I will add a comment and check in probe() to capture this assumption and then plan to update separately to support DA850 booting from DT. Ok, sounds good. Hopefully by then we will already have a nicer way to write an xlate function that does not rely on a filter function. Yes, it would be nice to avoid what Padma had to do. I should have mentioned also that the second EDMA on DA850 has no DMA events of immediate use on it anyway. All the in-kernel users use events on the first controller, except for the second MMC instance. That's only used for a wl12xx module on the EVM and that driver has no DT support so it doesn't matter yet in the DT case. Because of this, DA850 can actually add EDMA DT support immediately (on top of this series) and add DMA support to the DT support already posted for the Davinci SPI and MMC client drivers. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v5 03/14] ARM: edma: add AM33XX support to the private EDMA API
On Wed, Jan 30, 2013 at 09:40:52AM +0200, Andy Shevchenko wrote: On Wed, Jan 30, 2013 at 8:41 AM, Matt Porter mpor...@ti.com wrote: On Mon, Jan 28, 2013 at 09:27:24PM +0200, Andy Shevchenko wrote: On Tue, Jan 15, 2013 at 10:32 PM, Matt Porter mpor...@ti.com wrote: Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Adds AM33XX EMDA crossbar event mux support. Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/common/edma.c | 314 ++-- include/linux/platform_data/edma.h |1 + 2 files changed, 306 insertions(+), 9 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 2dce245..beeb1d2 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -24,6 +24,13 @@ #include linux/platform_device.h #include linux/io.h #include linux/slab.h +#include linux/edma.h +#include linux/err.h +#include linux/of_address.h +#include linux/of_device.h +#include linux/of_dma.h +#include linux/of_irq.h +#include linux/pm_runtime.h #include linux/platform_data/edma.h @@ -723,6 +730,9 @@ EXPORT_SYMBOL(edma_free_channel); */ int edma_alloc_slot(unsigned ctlr, int slot) { + if (!edma_cc[ctlr]) + return -EINVAL; + if (slot = 0) slot = EDMA_CHAN_SLOT(slot); @@ -1366,31 +1376,291 @@ void edma_clear_event(unsigned channel) EXPORT_SYMBOL(edma_clear_event); /*---*/ +static int edma_of_read_u32_to_s8_array(const struct device_node *np, +const char *propname, s8 *out_values, +size_t sz) I'm sorry I didn't get why you couldn't use of_property_read_u8_array() ? The similar comment to u16 and so on. There's some manipulation of the legacy Davinci platform data structures going on here. The driving reason was to not change any of the davinci platforms pdata which uses s8/s16 tables of mapping values with signed values as terminators. These versions below add the convert to the signed value and terminate the array as needed by the existing driver. This will all go away when the driver is rewritten and merged into drivers/dma/edma.c. At that point I want to throwaway all these legacy data structures. First, there's some more drivers to convert to dmaengine api. I mean instead of custom functions you could use existing ones. And sign here will be implicitly applied. Yes, sorry, wasn't following you at first. The is definitely much better and does work fine. I will update this...thanks! -Matt So, what I propose is to do something like this static int edma_of_read_u32_to_s8_array(const struct device_node *np, const char *propname, s8 *out_values, size_t sz) { int ret; ret = of_property_read_u8_array(np, propname, out_values, sz); if (ret) return ret; /* Terminate it */ *out_values++ = -1; *out_values++ = -1; } -Matt +{ + struct property *prop = of_find_property(np, propname, NULL); + const __be32 *val; + + if (!prop) + return -EINVAL; + if (!prop-value) + return -ENODATA; + if ((sz * sizeof(u32)) prop-length) + return -EOVERFLOW; + + val = prop-value; + + while (sz--) + *out_values++ = (s8)(be32_to_cpup(val++) 0xff); + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_of_read_u32_to_s16_array(const struct device_node *np, +const char *propname, s16 *out_values, +size_t sz) +{ + struct property *prop = of_find_property(np, propname, NULL); + const __be32 *val; + + if (!prop) + return -EINVAL; + if (!prop-value) + return -ENODATA; + if ((sz * sizeof(u32)) prop-length) + return -EOVERFLOW; + + val = prop-value; + + while (sz--) + *out_values++ = (s16)(be32_to_cpup(val++) 0x); + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ + int ret = 0; + int i; + struct resource res
Re: [PATCH v6 09/10] spi: omap2-mcspi: add generic DMA request support to the DT binding
On Wed, Jan 30, 2013 at 09:24:00AM +, Arnd Bergmann wrote: On Wednesday 30 January 2013, Matt Porter wrote: +Optional properties: +- dmas: List of DMA controller phandle and DMA request ordered + pairs. One tx and one rx pair is required for each chip + select. The binding looks ok, but the wording is slightly incorrect here: strictly speaking, it's not a pair of controller phandle and request line number, but a DMA descriptor as specified in bindings/dma/dma.txt with a format specific to the dma engine being used. That can require more than just a single integer request number. Correct. I will update accordingly. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v6 07/10] dmaengine: add dma_request_slave_channel_compat()
On Wed, Jan 30, 2013 at 09:27:18AM +, Arnd Bergmann wrote: On Wednesday 30 January 2013, Matt Porter wrote: Adds a dma_request_slave_channel_compat() wrapper which accepts both the arguments from dma_request_channel() and dma_request_slave_channel(). Based on whether the driver is instantiated via DT, the appropriate channel request call will be made. This allows for a much cleaner migration of drivers to the dmaengine DT API as platforms continue to be mixed between those that boot using DT and those that do not. Suggested-by: Tony Lindgren t...@atomide.com Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Tony Lindgren t...@atomide.com Acked-by: Arnd Bergmann a...@arndb.de @@ -1001,6 +1001,22 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel((mask), x, y) +#define dma_request_slave_channel_compat(mask, x, y, dev, name) \ + __dma_request_slave_channel_compat((mask), x, y, dev, name) + +static inline struct dma_chan +*__dma_request_slave_channel_compat(dma_cap_mask_t *mask, dma_filter_fn fn, + void *fn_param, struct device *dev, + char *name) +{ + struct dma_chan *chan; + + chan = dma_request_slave_channel(dev, name); + if (chan) + return chan; + + return __dma_request_channel(mask, fn, fn_param); +} After I have spent some more time with implementing the code for dw_dma, I think the mask is actually unnecessary here, the helper could just always set it to DMA_SLAVE before calling __dma_request_channel. It's not a bug to do it this way though, and it may help convert drivers a little easier if there is less to change. Agreed. -Matt Arnd ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v5 07/14] dmaengine: add dma_request_slave_channel_compat()
On Wed, Jan 23, 2013 at 10:28:46PM +, Arnd Bergmann wrote: On Tuesday 15 January 2013, Matt Porter wrote: Adds a dma_request_slave_channel_compat() wrapper which accepts both the arguments from dma_request_channel() and dma_request_slave_channel(). Based on whether the driver is instantiated via DT, the appropriate channel request call will be made. This allows for a much cleaner migration of drivers to the dmaengine DT API as platforms continue to be mixed between those that boot using DT and those that do not. I noticed today some drivers in linux-next that rely on this patch, but the patch itself still missing from -next. --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -1047,6 +1047,16 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel((mask), x, y) +static inline struct dma_chan +*dma_request_slave_channel_compat(dma_cap_mask_t mask, dma_filter_fn fn, + void *fn_param, struct device *dev, + char *name) +{ + if (dev-of_node) + return dma_request_slave_channel(dev, name); + else + return dma_request_channel(mask, fn, fn_param); +} Hmm, dma_request_channel is actually a macro that passes mask by reference, presumably because it can get modified by the filter function. Also, there may be cases where we do have an of_node but don't use the dma binding yet, or where dma_request_slave_channel doesn't actually use DT information but rather one of the other methods that Vinod was talking about adding. I think what it should look like instead is the below. Yes, looks correct now, thanks. I've incorporated it into v6. -Matt Arnd diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index bfcdecb..b6ffd7d 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -993,6 +993,19 @@ static inline void dma_release_channel(struct dma_chan *chan) } #endif +static inline struct dma_chan *__dma_request_slave_channel_compat(dma_cap_mask_t *mask, + dma_filter_fn fn, void *fn_param, struct device *dev, + char *name) +{ + struct dma_chan *chan; + + chan = dma_request_slave_channel(dev, name); + if (chan) + return chan; + + return __dma_request_channel(mask, fn, fn_param); +} + /* --- DMA device --- */ int dma_async_device_register(struct dma_device *device); @@ -1001,6 +1014,8 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel((mask), x, y) +#define dma_request_slave_channel_compat(mask, x, y, dev, name) \ + __dma_request_slave_channel_compat((mask), x, y, dev, name) /* --- Helper iov-locking functions --- */ ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v5 03/14] ARM: edma: add AM33XX support to the private EDMA API
On Mon, Jan 28, 2013 at 09:27:24PM +0200, Andy Shevchenko wrote: On Tue, Jan 15, 2013 at 10:32 PM, Matt Porter mpor...@ti.com wrote: Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Adds AM33XX EMDA crossbar event mux support. Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/common/edma.c | 314 ++-- include/linux/platform_data/edma.h |1 + 2 files changed, 306 insertions(+), 9 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 2dce245..beeb1d2 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -24,6 +24,13 @@ #include linux/platform_device.h #include linux/io.h #include linux/slab.h +#include linux/edma.h +#include linux/err.h +#include linux/of_address.h +#include linux/of_device.h +#include linux/of_dma.h +#include linux/of_irq.h +#include linux/pm_runtime.h #include linux/platform_data/edma.h @@ -723,6 +730,9 @@ EXPORT_SYMBOL(edma_free_channel); */ int edma_alloc_slot(unsigned ctlr, int slot) { + if (!edma_cc[ctlr]) + return -EINVAL; + if (slot = 0) slot = EDMA_CHAN_SLOT(slot); @@ -1366,31 +1376,291 @@ void edma_clear_event(unsigned channel) EXPORT_SYMBOL(edma_clear_event); /*---*/ +static int edma_of_read_u32_to_s8_array(const struct device_node *np, +const char *propname, s8 *out_values, +size_t sz) I'm sorry I didn't get why you couldn't use of_property_read_u8_array() ? The similar comment to u16 and so on. There's some manipulation of the legacy Davinci platform data structures going on here. The driving reason was to not change any of the davinci platforms pdata which uses s8/s16 tables of mapping values with signed values as terminators. These versions below add the convert to the signed value and terminate the array as needed by the existing driver. This will all go away when the driver is rewritten and merged into drivers/dma/edma.c. At that point I want to throwaway all these legacy data structures. First, there's some more drivers to convert to dmaengine api. -Matt +{ + struct property *prop = of_find_property(np, propname, NULL); + const __be32 *val; + + if (!prop) + return -EINVAL; + if (!prop-value) + return -ENODATA; + if ((sz * sizeof(u32)) prop-length) + return -EOVERFLOW; + + val = prop-value; + + while (sz--) + *out_values++ = (s8)(be32_to_cpup(val++) 0xff); + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_of_read_u32_to_s16_array(const struct device_node *np, +const char *propname, s16 *out_values, +size_t sz) +{ + struct property *prop = of_find_property(np, propname, NULL); + const __be32 *val; + + if (!prop) + return -EINVAL; + if (!prop-value) + return -ENODATA; + if ((sz * sizeof(u32)) prop-length) + return -EOVERFLOW; + + val = prop-value; + + while (sz--) + *out_values++ = (s16)(be32_to_cpup(val++) 0x); + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ + int ret = 0; + int i; + struct resource res; + void *xbar; + const s16 (*xbar_chans)[2]; + u32 shift, offset, mux; + + xbar_chans = devm_kzalloc(dev, + len/sizeof(s16) + 2*sizeof(s16), + GFP_KERNEL); + if (!xbar_chans) + return -ENOMEM; + + ret = of_address_to_resource(node, 1, res); + if (IS_ERR_VALUE(ret)) + return -EIO; + + xbar = devm_ioremap(dev, res.start, resource_size(res)); + if (!xbar) + return -ENOMEM; + + ret = edma_of_read_u32_to_s16_array(node, + ti,edma-xbar-event-map, + (s16 *)xbar_chans, + len/sizeof(u32)); + if (IS_ERR_VALUE(ret)) + return -EIO; + + for (i = 0; xbar_chans[i][0] != -1; i++) { + shift
[PATCH v6 01/10] ARM: davinci: move private EDMA API to arm/common
Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. This just moves the private EDMA API and enables it to build on OMAP. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/Kconfig |1 + arch/arm/common/Kconfig|3 + arch/arm/common/Makefile |1 + arch/arm/{mach-davinci/dma.c = common/edma.c} |4 +- arch/arm/mach-davinci/Makefile |2 +- arch/arm/mach-davinci/board-tnetv107x-evm.c|2 +- arch/arm/mach-davinci/davinci.h|2 +- arch/arm/mach-davinci/devices-tnetv107x.c |2 +- arch/arm/mach-davinci/devices.c|6 +- arch/arm/mach-davinci/dm355.c |2 +- arch/arm/mach-davinci/dm365.c |2 +- arch/arm/mach-davinci/dm644x.c |2 +- arch/arm/mach-davinci/dm646x.c |2 +- arch/arm/mach-davinci/include/mach/da8xx.h |2 +- drivers/dma/edma.c |2 +- drivers/mmc/host/davinci_mmc.c |1 + include/linux/mfd/davinci_voicecodec.h |3 +- .../mach = include/linux/platform_data}/edma.h| 89 +--- include/linux/platform_data/spi-davinci.h |2 +- sound/soc/davinci/davinci-evm.c|1 + sound/soc/davinci/davinci-pcm.c|1 + sound/soc/davinci/davinci-pcm.h|2 +- sound/soc/davinci/davinci-sffsdr.c |7 +- 23 files changed, 35 insertions(+), 106 deletions(-) rename arch/arm/{mach-davinci/dma.c = common/edma.c} (99%) rename {arch/arm/mach-davinci/include/mach = include/linux/platform_data}/edma.h (59%) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 67874b8..7637d31 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -932,6 +932,7 @@ config ARCH_DAVINCI select GENERIC_IRQ_CHIP select HAVE_IDE select NEED_MACH_GPIO_H + select TI_PRIV_EDMA select USE_OF select ZONE_DMA help diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 45ceeb0..9e32d0d 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -40,3 +40,6 @@ config SHARP_PARAM config SHARP_SCOOP bool + +config TI_PRIV_EDMA + bool diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index e8a4e58..d09a39b 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o +obj-$(CONFIG_TI_PRIV_EDMA) += edma.o diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/common/edma.c similarity index 99% rename from arch/arm/mach-davinci/dma.c rename to arch/arm/common/edma.c index a685e97..be3c04a 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/common/edma.c @@ -25,7 +25,7 @@ #include linux/io.h #include linux/slab.h -#include mach/edma.h +#include linux/platform_data/edma.h /* Offsets matching struct edmacc_param */ #define PARM_OPT 0x00 @@ -1387,7 +1387,7 @@ EXPORT_SYMBOL(edma_clear_event); /*---*/ -static int __init edma_probe(struct platform_device *pdev) +static int edma_probe(struct platform_device *pdev) { struct edma_soc_info**info = pdev-dev.platform_data; const s8(*queue_priority_mapping)[2]; diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index fb5c1aa..493a36b 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -5,7 +5,7 @@ # Common objects obj-y := time.o clock.o serial.o psc.o \ - dma.o usb.o common.o sram.o aemif.o + usb.o common.o sram.o aemif.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index be30997..86f55ba 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -26,12 +26,12 @@ #include linux/input.h #include linux/input/matrix_keypad.h #include linux/spi/spi.h +#include linux/platform_data/edma.h #include asm/mach/arch.h #include asm/mach-types.h #include mach/irqs.h -#include mach/edma.h #include mach/mux.h #include mach/cp_intc.h #include mach/tnetv107x.h diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index 12d544b..d26a6bc 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h @@ -23,9 +23,9 @@ #include linux/platform_device.h #include linux/spi/spi.h
[PATCH v6 02/10] ARM: edma: remove unused transfer controller handlers
Fix build on OMAP, the irqs are undefined on AM33xx. These error interrupt handlers were hardcoded as disabled so since they are unused code, simply remove them. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c | 37 - 1 file changed, 37 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index be3c04a..2dce245 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -494,26 +494,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) return IRQ_HANDLED; } -/** - * - * Transfer controller error interrupt handlers - * - */ - -#define tc_errs_handledfalse /* disabled as long as they're NOPs */ - -static irqreturn_t dma_tc0err_handler(int irq, void *data) -{ - dev_dbg(data, dma_tc0err_handler\n); - return IRQ_HANDLED; -} - -static irqreturn_t dma_tc1err_handler(int irq, void *data) -{ - dev_dbg(data, dma_tc1err_handler\n); - return IRQ_HANDLED; -} - static int reserve_contiguous_slots(int ctlr, unsigned int id, unsigned int num_slots, unsigned int start_slot) @@ -1538,23 +1518,6 @@ static int edma_probe(struct platform_device *pdev) arch_num_cc++; } - if (tc_errs_handled) { - status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0, - edma_tc0, pdev-dev); - if (status 0) { - dev_dbg(pdev-dev, request_irq %d failed -- %d\n, - IRQ_TCERRINT0, status); - return status; - } - status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0, - edma_tc1, pdev-dev); - if (status 0) { - dev_dbg(pdev-dev, request_irq %d -- %d\n, - IRQ_TCERRINT, status); - return status; - } - } - return 0; fail: -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v6 05/10] dmaengine: edma: Add TI EDMA device tree binding
The binding definition is based on the generic DMA controller binding. Signed-off-by: Matt Porter mpor...@ti.com --- Documentation/devicetree/bindings/dma/ti-edma.txt | 49 + 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt new file mode 100644 index 000..075a60e3 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt @@ -0,0 +1,49 @@ +TI EDMA + +Required properties: +- compatible : ti,edma3 +- ti,hwmods: Name of the hwmods associated to the EDMA +- ti,edma-regions: Number of regions +- ti,edma-slots: Number of slots +- ti,edma-queue-tc-map: List of transfer control to queue mappings +- ti,edma-queue-priority-map: List of queue priority mappings +- ti,edma-default-queue: Default queue value + +Optional properties: +- ti,edma-reserved-channels: List of reserved channel regions +- ti,edma-reserved-slots: List of reserved slot regions +- ti,edma-xbar-event-map: Crossbar event to channel map + +Example: + +edma: edma@4900 { + reg = 0x4900 0x1; + interrupt-parent = intc; + interrupts = 12 13 14; + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-reserved-channels = 0 2 +14 2 +26 6 +48 4 +56 8; + ti,edma-reserved-slots = 0 2 + 14 2 + 26 6 + 48 4 + 56 8 + 64 127; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + ti,edma-xbar-event-map = 1 12 + 2 13; +}; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v6 00/10] DMA Engine support for AM33XX
Changes since v5: - Dropped mmc portion and moved it to a separate series - Incorporate corrected version of dma_request_slave_channel_compat() - Fix #defines and enablement of TI_PRIV_EDMA option Changes since v4: - Fixed debug section mismatch in private edma api [01/14] - Respun format-patch to catch the platform_data/edma.h rename [01/14] - Removed address/size-cells from the EDMA binding [05/14] Changes since v3: - Rebased on 3.8-rc3 - No longer an RFC - Fixed bugs in DT/pdata parsing reported by Vaibhav Bedia - Restored all the Davinci pdata to const - Removed max_segs hack in favor of using dma_get_channel_caps() - Fixed extra parens, __raw_* accessors and, ioremap error checks in xbar handling - Removed excess license info in platform_data/edma.h - Removed unneeded reserved channels data for AM33xx - Removed test-specific pinmuxing from dts files - Adjusted mmc1 node to be disabled by default in the dtsi Changes since v2: - Rebased on 3.7-rc1 - Fixed bug in DT/pdata parsing first found by Gururaja that turned out to be masked by some toolchains - Dropped unused mach-omap2/devices.c hsmmc patch - Added AM33XX crossbar DMA event mux support - Added am335x-evm support Changes since v1: - Rebased on top of mainline from 12250d8 - Dropped the feature removal schedule patch - Implemented dma_request_slave_channel_compat() and converted the mmc and spi drivers to use it - Dropped unneeded #address-cells and #size-cells from EDMA DT support - Moved private EDMA header to linux/platform_data/ and removed some unneeded definitions - Fixed parsing of optional properties This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. The series applies on top of 3.8-rc5 and the following patches: - dmaengine DT support and edma dmaengine driver fix from the git://git.infradead.org/users/vkoul/slave-dma.git next branch The approach taken is similar to how OMAP DMA is being converted to DMA Engine support. With the functional EDMA private API already existing in mach-davinci/dma.c, we first move that to an ARM common area so it can be shared. Adding DT and runtime PM support to the private EDMA API implementation allows it to run on AM33xx. AM33xx *only* boots using DT so we leverage Jon's generic DT DMA helpers to register EDMA DMAC with the of_dma framework and then add support for calling the dma_request_slave_channel() API to both the mmc and spi drivers. With this series both BeagleBone and the AM335x EVM have working SPI DMA support (and MMC support with the separate MMC series). This is tested on BeagleBone with a SPI framebuffer driver and MMC rootfs. A trivial gpio DMA event misc driver was used to test the crossbar DMA event support. It is also tested on the AM335x EVM with the onboard SPI flash and MMC rootfs. The branch at https://github.com/ohporter/linux/tree/edma-dmaengine-am33xx-v6 has the complete series, dependencies, and some test drivers/defconfigs. Note that MMC can only be tested with a separate MMC dmaengine/DT series applied. Regression testing was done on AM180x-EVM (which also makes use of the EDMA dmaengine driver and the EDMA private API) using SD, SPI flash, and the onboard audio supported by the ASoC Davinci driver. Regression testing was also done on a BeagleBoard xM booting from the legacy board file using MMC rootfs. Matt Porter (10): ARM: davinci: move private EDMA API to arm/common ARM: edma: remove unused transfer controller handlers ARM: edma: add AM33XX support to the private EDMA API dmaengine: edma: enable build for AM33XX dmaengine: edma: Add TI EDMA device tree binding ARM: dts: add AM33XX EDMA support dmaengine: add dma_request_slave_channel_compat() spi: omap2-mcspi: convert to dma_request_slave_channel_compat() spi: omap2-mcspi: add generic DMA request support to the DT binding ARM: dts: add AM33XX SPI DMA support Documentation/devicetree/bindings/dma/ti-edma.txt | 49 +++ Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +- arch/arm/Kconfig |1 + arch/arm/boot/dts/am33xx.dtsi | 30 ++ arch/arm/common/Kconfig|3 + arch/arm/common/Makefile |1 + arch/arm/{mach-davinci/dma.c = common/edma.c} | 355 +--- arch/arm/mach-davinci/Makefile |2 +- arch/arm/mach-davinci/board-tnetv107x-evm.c|2 +- arch/arm/mach-davinci/davinci.h|2 +- arch/arm/mach-davinci/devices-tnetv107x.c
[PATCH v6 03/10] ARM: edma: add AM33XX support to the private EDMA API
Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Adds AM33XX EMDA crossbar event mux support. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Sekhar Nori nsek...@ti.com --- arch/arm/common/edma.c | 314 ++-- arch/arm/plat-omap/Kconfig |1 + include/linux/platform_data/edma.h |1 + 3 files changed, 307 insertions(+), 9 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 2dce245..beeb1d2 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -24,6 +24,13 @@ #include linux/platform_device.h #include linux/io.h #include linux/slab.h +#include linux/edma.h +#include linux/err.h +#include linux/of_address.h +#include linux/of_device.h +#include linux/of_dma.h +#include linux/of_irq.h +#include linux/pm_runtime.h #include linux/platform_data/edma.h @@ -723,6 +730,9 @@ EXPORT_SYMBOL(edma_free_channel); */ int edma_alloc_slot(unsigned ctlr, int slot) { + if (!edma_cc[ctlr]) + return -EINVAL; + if (slot = 0) slot = EDMA_CHAN_SLOT(slot); @@ -1366,31 +1376,291 @@ void edma_clear_event(unsigned channel) EXPORT_SYMBOL(edma_clear_event); /*---*/ +static int edma_of_read_u32_to_s8_array(const struct device_node *np, +const char *propname, s8 *out_values, +size_t sz) +{ + struct property *prop = of_find_property(np, propname, NULL); + const __be32 *val; + + if (!prop) + return -EINVAL; + if (!prop-value) + return -ENODATA; + if ((sz * sizeof(u32)) prop-length) + return -EOVERFLOW; + + val = prop-value; + + while (sz--) + *out_values++ = (s8)(be32_to_cpup(val++) 0xff); + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_of_read_u32_to_s16_array(const struct device_node *np, +const char *propname, s16 *out_values, +size_t sz) +{ + struct property *prop = of_find_property(np, propname, NULL); + const __be32 *val; + + if (!prop) + return -EINVAL; + if (!prop-value) + return -ENODATA; + if ((sz * sizeof(u32)) prop-length) + return -EOVERFLOW; + + val = prop-value; + + while (sz--) + *out_values++ = (s16)(be32_to_cpup(val++) 0x); + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ + int ret = 0; + int i; + struct resource res; + void *xbar; + const s16 (*xbar_chans)[2]; + u32 shift, offset, mux; + + xbar_chans = devm_kzalloc(dev, + len/sizeof(s16) + 2*sizeof(s16), + GFP_KERNEL); + if (!xbar_chans) + return -ENOMEM; + + ret = of_address_to_resource(node, 1, res); + if (IS_ERR_VALUE(ret)) + return -EIO; + + xbar = devm_ioremap(dev, res.start, resource_size(res)); + if (!xbar) + return -ENOMEM; + + ret = edma_of_read_u32_to_s16_array(node, + ti,edma-xbar-event-map, + (s16 *)xbar_chans, + len/sizeof(u32)); + if (IS_ERR_VALUE(ret)) + return -EIO; + + for (i = 0; xbar_chans[i][0] != -1; i++) { + shift = (xbar_chans[i][1] % 4) * 8; + offset = xbar_chans[i][1] 2; + offset = 2; + mux = readl((void *)((u32)xbar + offset)); + mux = ~(0xff shift); + mux |= xbar_chans[i][0] shift; + writel(mux, (void *)((u32)xbar + offset)); + } + + pdata-xbar_chans = xbar_chans; + + return 0; +} + +static int edma_of_parse_dt(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata) +{ + int ret = 0; + u32 value; + struct property *prop; + size_t sz; + struct edma_rsv_info *rsv_info; + const s16 (*rsv_chans)[2], (*rsv_slots)[2]; + const s8 (*queue_tc_map)[2], (*queue_priority_map)[2]; + + memset(pdata, 0, sizeof(struct edma_soc_info)); + + ret = of_property_read_u32(node, dma-channels, value); + if (ret 0) + return ret; + pdata-n_channel = value
[PATCH v6 04/10] dmaengine: edma: enable build for AM33XX
Enable TI EDMA option on OMAP. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/dma/Kconfig |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 0b408bb..239020b 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -220,7 +220,7 @@ config SIRF_DMA config TI_EDMA tristate TI EDMA support - depends on ARCH_DAVINCI + depends on ARCH_DAVINCI || ARCH_OMAP select DMA_ENGINE select DMA_VIRTUAL_CHANNELS default n -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v6 08/10] spi: omap2-mcspi: convert to dma_request_slave_channel_compat()
Convert dmaengine channel requests to use dma_request_slave_channel_compat(). This supports the DT case of platforms requiring channel selection from either the OMAP DMA or the EDMA engine. AM33xx only boots from DT and is the only user implementing EDMA so in the !DT case we can default to the OMAP DMA filter. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/spi/spi-omap2-mcspi.c | 65 - 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index b610f52..2c02c02 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -102,6 +102,9 @@ struct omap2_mcspi_dma { struct completion dma_tx_completion; struct completion dma_rx_completion; + + char dma_rx_ch_name[14]; + char dma_tx_ch_name[14]; }; /* use PIO for small transfers, avoiding DMA setup/teardown overhead and @@ -822,14 +825,23 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); sig = mcspi_dma-dma_rx_sync_dev; - mcspi_dma-dma_rx = dma_request_channel(mask, omap_dma_filter_fn, sig); + + mcspi_dma-dma_rx = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +sig, master-dev, +mcspi_dma-dma_rx_ch_name); + if (!mcspi_dma-dma_rx) { dev_err(spi-dev, no RX DMA engine channel for McSPI\n); return -EAGAIN; } sig = mcspi_dma-dma_tx_sync_dev; - mcspi_dma-dma_tx = dma_request_channel(mask, omap_dma_filter_fn, sig); + mcspi_dma-dma_tx = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +sig, master-dev, +mcspi_dma-dma_tx_ch_name); + if (!mcspi_dma-dma_tx) { dev_err(spi-dev, no TX DMA engine channel for McSPI\n); dma_release_channel(mcspi_dma-dma_rx); @@ -1223,29 +1235,42 @@ static int omap2_mcspi_probe(struct platform_device *pdev) goto free_master; for (i = 0; i master-num_chipselect; i++) { - char dma_ch_name[14]; + char *dma_rx_ch_name = mcspi-dma_channels[i].dma_rx_ch_name; + char *dma_tx_ch_name = mcspi-dma_channels[i].dma_tx_ch_name; struct resource *dma_res; - sprintf(dma_ch_name, rx%d, i); - dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); - if (!dma_res) { - dev_dbg(pdev-dev, cannot get DMA RX channel\n); - status = -ENODEV; - break; - } + sprintf(dma_rx_ch_name, rx%d, i); + if (!pdev-dev.of_node) { + dma_res = + platform_get_resource_byname(pdev, +IORESOURCE_DMA, +dma_rx_ch_name); + if (!dma_res) { + dev_dbg(pdev-dev, + cannot get DMA RX channel\n); + status = -ENODEV; + break; + } - mcspi-dma_channels[i].dma_rx_sync_dev = dma_res-start; - sprintf(dma_ch_name, tx%d, i); - dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); - if (!dma_res) { - dev_dbg(pdev-dev, cannot get DMA TX channel\n); - status = -ENODEV; - break; + mcspi-dma_channels[i].dma_rx_sync_dev = + dma_res-start; } + sprintf(dma_tx_ch_name, tx%d, i); + if (!pdev-dev.of_node) { + dma_res = + platform_get_resource_byname(pdev, +IORESOURCE_DMA, +dma_tx_ch_name); + if (!dma_res) { + dev_dbg(pdev-dev, + cannot get DMA TX channel\n); + status = -ENODEV; + break; + } - mcspi-dma_channels[i].dma_tx_sync_dev = dma_res-start; + mcspi-dma_channels[i].dma_tx_sync_dev = + dma_res-start; + } } if (status 0
[PATCH v6 10/10] ARM: dts: add AM33XX SPI DMA support
Adds DMA resources to the AM33XX SPI nodes. Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 10 ++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index e711ffb..ddf702a 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -328,6 +328,11 @@ interrupt = 65; ti,spi-num-cs = 2; ti,hwmods = spi0; + dmas = edma 16 + edma 17 + edma 18 + edma 19; + dma-names = tx0, rx0, tx1, rx1; status = disabled; }; @@ -339,6 +344,11 @@ interrupt = 125; ti,spi-num-cs = 2; ti,hwmods = spi1; + dmas = edma 42 + edma 43 + edma 44 + edma 45; + dma-names = tx0, rx0, tx1, rx1; status = disabled; }; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v6 09/10] spi: omap2-mcspi: add generic DMA request support to the DT binding
The binding definition is based on the generic DMA request binding Signed-off-by: Matt Porter mpor...@ti.com --- Documentation/devicetree/bindings/spi/omap-spi.txt | 27 +++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/omap-spi.txt b/Documentation/devicetree/bindings/spi/omap-spi.txt index 938809c..68cb28e 100644 --- a/Documentation/devicetree/bindings/spi/omap-spi.txt +++ b/Documentation/devicetree/bindings/spi/omap-spi.txt @@ -10,7 +10,18 @@ Required properties: input. The default is D0 as input and D1 as output. -Example: +Optional properties: +- dmas: List of DMA controller phandle and DMA request ordered + pairs. One tx and one rx pair is required for each chip + select. +- dma-names: List of DMA request names. These strings correspond + 1:1 with the ordered pairs in dmas. The string naming is + to be rxN and txN for RX and TX requests, + respectively, where N equals the chip select number. + +Examples: + +[hwmod populated DMA resources] mcspi1: mcspi@1 { #address-cells = 1; @@ -20,3 +31,17 @@ mcspi1: mcspi@1 { ti,spi-num-cs = 4; }; +[generic DMA request binding] + +mcspi1: mcspi@1 { +#address-cells = 1; +#size-cells = 0; +compatible = ti,omap4-mcspi; +ti,hwmods = mcspi1; +ti,spi-num-cs = 2; +dmas = edma 42 + edma 43 + edma 44 + edma 45; +dma-names = tx0, rx0, tx1, rx1; +}; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v5 00/14] DMA Engine support for AM33XX
On Thu, Jan 24, 2013 at 05:14:13AM +, Sekhar Nori wrote: Matt, On 1/24/2013 3:07 AM, Matt Porter wrote: On Wed, Jan 23, 2013 at 10:21:42AM +0800, Mark Brown wrote: On Tue, Jan 22, 2013 at 09:26:34PM +0530, Sekhar Nori wrote: On 1/16/2013 2:02 AM, Matt Porter wrote: This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. Will you take this series through the OMAP tree? Only 1/14 touches mach-davinci and I am mostly okay with it except some changes I just requested Matt to make in another thread. Is this series somewhere near actually getting merged then? It seemed like there was lots of stuff going on. The issues raised by Sekhar and Santosh were reasonably minor and will be addressed. My major concern is that the dependency on some api to fetch dmaengine driver SG limitations is not resolved. That's being discussed in https://lkml.org/lkml/2013/1/10/432 It might be worth posting the patches which don't have dependencies and are ready for acceptance as a separate series. That way at least some of these patches have a good chance of getting into v3.9 if not the entire series. Yes a good idea and seems to be the best option. I've dropped the mmc support from the series for the next version. I'll repost the separately when we have an api to support it. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v5 00/14] DMA Engine support for AM33XX
On Thu, Jan 24, 2013 at 05:12:05AM +, Shilimkar, Santosh wrote: On Thursday 24 January 2013 02:19 AM, Matt Porter wrote: On Wed, Jan 23, 2013 at 04:37:55PM +0530, Santosh Shilimkar wrote: Matt, On Wednesday 16 January 2013 02:02 AM, Matt Porter wrote: [..] This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. The series applies on top of 3.8-rc3 and the following patches: - TPS65910 REGMAP_IRQ build fix: https://patchwork.kernel.org/patch/1857701/ - dmaengine DT support from Vinod's dmaengine_dt branch in git://git.infradead.org/users/vkoul/slave-dma.git since 027478851791df751176398be02a3b1c5f6aa824 - edma dmaengine driver fix: https://patchwork.kernel.org/patch/1961521/ - dmaengine dma_get_channel_caps v2: https://patchwork.kernel.org/patch/1961601/ - dmaengine edma driver channel caps support v2: https://patchwork.kernel.org/patch/1961591/ The approach taken is similar to how OMAP DMA is being converted to DMA Engine support. With the functional EDMA private API already existing in mach-davinci/dma.c, we first move that to an ARM common area so it can be shared. Adding DT and runtime PM support to the private EDMA API implementation allows it to run on AM33xx. AM33xx *only* boots using DT so we leverage Jon's generic DT DMA helpers to register EDMA DMAC with the of_dma framework and then add support for calling the dma_request_slave_channel() API to both the mmc and spi drivers. With this series both BeagleBone and the AM335x EVM have working MMC and SPI support. This is tested on BeagleBone with a SPI framebuffer driver and MMC rootfs. A trivial gpio DMA event misc driver was used to test the crossbar DMA event support. It is also tested on the AM335x EVM with the onboard SPI flash and MMC rootfs. The branch at https://github.com/ohporter/linux/tree/edma-dmaengine-am33xx-v4 has the complete series, dependencies, and some test drivers/defconfigs. Regression testing was done on AM180x-EVM (which also makes use of the EDMA dmaengine driver and the EDMA private API) using SD, SPI flash, and the onboard audio supported by the ASoC Davinci driver. Regression testing was also done on a BeagleBoard xM booting from the legacy board file using MMC rootfs. Matt Porter (14): ARM: davinci: move private EDMA API to arm/common ARM: edma: remove unused transfer controller handlers ARM: edma: add AM33XX support to the private EDMA API dmaengine: edma: enable build for AM33XX dmaengine: edma: Add TI EDMA device tree binding ARM: dts: add AM33XX EDMA support dmaengine: add dma_request_slave_channel_compat() mmc: omap_hsmmc: convert to dma_request_slave_channel_compat() mmc: omap_hsmmc: set max_segs based on dma engine limitations mmc: omap_hsmmc: add generic DMA request support to the DT binding ARM: dts: add AM33XX MMC support spi: omap2-mcspi: convert to dma_request_slave_channel_compat() spi: omap2-mcspi: add generic DMA request support to the DT binding ARM: dts: add AM33XX SPI DMA support While going through the series and testing it out, I observed an issue with MMC driver. You need patch in the end of the email to avoid the issue. Same is attached in case mailer damages it. Can you please add it with your series if you agree ? Yes, by inspection this makes sense. As you noticed, we've been relying on the fact that DMA resources still don't come from DT, we only use our DT data in conjunction with the DMA OF helpers to do channel filtering. I was figuring we would address that separately later, but I see how even omap4 has this issue with DMA resources named with tx1, for example. A good followup once this series is taken will be to only use hwmod resources on a !populated-dt platform like we do for other resources now. Baby steps. :) We are already on it :-) Great! Thanks for the catch, I'll add this in with your tested line as well for the series. BTW, since I'm dropping mmc support from this series, I'll move your patch into a separate series with only the mmc pieces. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v5 00/14] DMA Engine support for AM33XX
On Wed, Jan 23, 2013 at 04:37:55PM +0530, Santosh Shilimkar wrote: Matt, On Wednesday 16 January 2013 02:02 AM, Matt Porter wrote: [..] This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. The series applies on top of 3.8-rc3 and the following patches: - TPS65910 REGMAP_IRQ build fix: https://patchwork.kernel.org/patch/1857701/ - dmaengine DT support from Vinod's dmaengine_dt branch in git://git.infradead.org/users/vkoul/slave-dma.git since 027478851791df751176398be02a3b1c5f6aa824 - edma dmaengine driver fix: https://patchwork.kernel.org/patch/1961521/ - dmaengine dma_get_channel_caps v2: https://patchwork.kernel.org/patch/1961601/ - dmaengine edma driver channel caps support v2: https://patchwork.kernel.org/patch/1961591/ The approach taken is similar to how OMAP DMA is being converted to DMA Engine support. With the functional EDMA private API already existing in mach-davinci/dma.c, we first move that to an ARM common area so it can be shared. Adding DT and runtime PM support to the private EDMA API implementation allows it to run on AM33xx. AM33xx *only* boots using DT so we leverage Jon's generic DT DMA helpers to register EDMA DMAC with the of_dma framework and then add support for calling the dma_request_slave_channel() API to both the mmc and spi drivers. With this series both BeagleBone and the AM335x EVM have working MMC and SPI support. This is tested on BeagleBone with a SPI framebuffer driver and MMC rootfs. A trivial gpio DMA event misc driver was used to test the crossbar DMA event support. It is also tested on the AM335x EVM with the onboard SPI flash and MMC rootfs. The branch at https://github.com/ohporter/linux/tree/edma-dmaengine-am33xx-v4 has the complete series, dependencies, and some test drivers/defconfigs. Regression testing was done on AM180x-EVM (which also makes use of the EDMA dmaengine driver and the EDMA private API) using SD, SPI flash, and the onboard audio supported by the ASoC Davinci driver. Regression testing was also done on a BeagleBoard xM booting from the legacy board file using MMC rootfs. Matt Porter (14): ARM: davinci: move private EDMA API to arm/common ARM: edma: remove unused transfer controller handlers ARM: edma: add AM33XX support to the private EDMA API dmaengine: edma: enable build for AM33XX dmaengine: edma: Add TI EDMA device tree binding ARM: dts: add AM33XX EDMA support dmaengine: add dma_request_slave_channel_compat() mmc: omap_hsmmc: convert to dma_request_slave_channel_compat() mmc: omap_hsmmc: set max_segs based on dma engine limitations mmc: omap_hsmmc: add generic DMA request support to the DT binding ARM: dts: add AM33XX MMC support spi: omap2-mcspi: convert to dma_request_slave_channel_compat() spi: omap2-mcspi: add generic DMA request support to the DT binding ARM: dts: add AM33XX SPI DMA support While going through the series and testing it out, I observed an issue with MMC driver. You need patch in the end of the email to avoid the issue. Same is attached in case mailer damages it. Can you please add it with your series if you agree ? Yes, by inspection this makes sense. As you noticed, we've been relying on the fact that DMA resources still don't come from DT, we only use our DT data in conjunction with the DMA OF helpers to do channel filtering. I was figuring we would address that separately later, but I see how even omap4 has this issue with DMA resources named with tx1, for example. A good followup once this series is taken will be to only use hwmod resources on a !populated-dt platform like we do for other resources now. Baby steps. :) Thanks for the catch, I'll add this in with your tested line as well for the series. -Matt Overall the series looks good to my eyes. Acked-tested-by: Santosh Shilimkar santosh.shilim...@ti.com Regards, Santosh From 2dcc90b7a4b2dcdb52ddd052ca7f3e88a78e83e4 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar santosh.shilim...@ti.com Date: Wed, 23 Jan 2013 16:04:32 +0530 Subject: [PATCH] mmc: omap_hsmmc: Skip platform_get_resource_byname() for dt case MMC driver probe will abort for DT case because of failed platform_get_resource_byname() lookup. Fix it by skipping resource byname lookup for device tree build. Issue is hidden because hwmod popullates the IO resources which helps to succeed platform_get_resource_byname() and probe. Signed-off-by: Santosh Shilimkar santosh.shilim...@ti.com --- drivers/mmc/host/omap_hsmmc.c | 28 +++- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index f74bd69..d4655e7
Re: [RFC PATCH v3 02/16] ARM: davinci: move private EDMA API to arm/common
On Tue, Jan 22, 2013 at 03:40:06PM +, Sekhar Nori wrote: Matt, Sorry about the late reply. I noticed this mail only after I started to look at v5 of your series :( Any time is fine! :) On 1/11/2013 5:21 AM, Matt Porter wrote: On Sun, Oct 28, 2012 at 01:47:09PM +0530, Sekhar Nori wrote: On 10/18/2012 6:56 PM, Matt Porter wrote: Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. This just moves the private EDMA API but does not support OMAP. Signed-off-by: Matt Porter mpor...@ti.com --- diff --git a/arch/arm/mach-davinci/devices.c b/arch/arm/mach-davinci/devices.c index 4c48a36..f45d591 100644 --- a/arch/arm/mach-davinci/devices.c +++ b/arch/arm/mach-davinci/devices.c @@ -19,9 +19,10 @@ #include mach/irqs.h #include mach/cputype.h #include mach/mux.h -#include mach/edma.h #include linux/platform_data/mmc-davinci.h #include mach/time.h +#include linux/platform_data/edma.h Can you please introduce a patch to clean this mixture of linux/ and mach/ includes? Yeah, are you ok with a follow on series to clean all these files? I don't want to make this series longer with something not dma related that's purely cleanup from the great header reorg of 2012. Okay. I agree doing this sort of change now will cause merge issues. Ok. + #include davinci.h #include clock.h @@ -141,10 +142,10 @@ static struct resource mmcsd0_resources[] = { }, /* DMA channels: RX, then TX */ { - .start = EDMA_CTLR_CHAN(0, DAVINCI_DMA_MMCRXEVT), + .start = EDMA_CTLR_CHAN(0, 26), Instead of just replacing the event #defines with plain numbers, can you introduce a mach-davinci local edma.h which can then be included in the davinci platform files which refer to edma channel numbers? Ok, so when I removed the old edma.h it was full of unused defines and we are left with just this one. If I introduced something like that it would be used in just one place here. and only for these two values. How about we just add a comment? I prefer adding a local #define in this file. This will keep it consistent with what is done in arch/arm/mach-davinci/dm365.c for example. Same for the change in sound/soc/davinci/davinci-sffsdr.c Ok, will do. diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 7cd56ed..153fab8 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -28,6 +28,7 @@ config ARCH_OMAP2PLUS select OMAP_DM_TIMER select PROC_DEVICETREE if PROC_FS select SPARSE_IRQ + select TI_PRIV_EDMA This hunk does not seem to belong to subject of this patch. Let me reword the subject/description. The idea of this logical chunk was to put everything in place to make it build on OMAP, with the expectation that the build fails without the next patch in the series. But this will break bisect. With just this patch applied, omap build breaks. Looks like it will be more logical to merge this hunk with 3/14 since that's when you really start using the private DMA support on OMAP platforms. Ahh, yes,. thanks for pointing that out. I will address it and add your ack. Thanks. This issue is a must fix IMO. Ok. I am ok with the patch otherwise. With these changes done, you can add: Acked-by: Sekhar Nori nsek...@ti.com Thanks, Sekhar ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v5 00/14] DMA Engine support for AM33XX
On Wed, Jan 23, 2013 at 10:21:42AM +0800, Mark Brown wrote: On Tue, Jan 22, 2013 at 09:26:34PM +0530, Sekhar Nori wrote: On 1/16/2013 2:02 AM, Matt Porter wrote: This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. Will you take this series through the OMAP tree? Only 1/14 touches mach-davinci and I am mostly okay with it except some changes I just requested Matt to make in another thread. Is this series somewhere near actually getting merged then? It seemed like there was lots of stuff going on. The issues raised by Sekhar and Santosh were reasonably minor and will be addressed. My major concern is that the dependency on some api to fetch dmaengine driver SG limitations is not resolved. That's being discussed in https://lkml.org/lkml/2013/1/10/432 If I don't get confirmation from Vinod soon, I'll just take a stab at implementing the callbacks he mentioned in that thread. Static per-channel caps don't provide the information needed by a client driver the uses the EDMA DMAC. Alternatively, we can go back to the hack that looks at the edma phandle and hardcodes the mmc SG limits to magic values, but that's just plain ugly. I could live with it temporarily if we can't get the dmaengine api resolved until 3.10...dunno if others can though. ;) -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v2 0/3] dmaengine: add per channel capabilities api
On Mon, Jan 21, 2013 at 03:15:23AM +, Vinod Koul wrote: On Sun, Jan 20, 2013 at 11:37:35AM -0500, Matt Porter wrote: On Sun, Jan 20, 2013 at 12:37:34PM +, Vinod Koul wrote: On Thu, Jan 10, 2013 at 02:07:03PM -0500, Matt Porter wrote: The call is implemented as follows: struct dmaengine_chan_caps *dma_get_channel_caps(struct dma_chan *chan, enum dma_transfer_direction dir); The dma transfer direction parameter may appear a bit out of place but it is necessary since the direction field in struct dma_slave_config was deprecated. In some cases, EDMA for one, it is necessary for the dmaengine driver to have the burst and address width slave configuration parameters available in order to compute the maximum segment size that can be handle. Due to this requirement, the calling order of this api is as follows: Well you are passing direction as argument so even in EDMA it doesn't seem to help you as you seem to need burst and width!. So why do you even need the direction to compute the capablities Yes, I need burst and width, but they are dependent on direction (dst vs src, as stored in the slave channel config). Ok, so I think I know where this is leading...the problem is probably that I made an implicit dependency on burst and width here. The expectation in this And also due to wrong documentation. This is what you have put up the flow as: Due to this requirement, the calling order of this api is as follows: 1. Allocate a DMA slave channel 1a. [Optionally] Get channel capabilities 2. Set slave and controller specific parameters 3. Get a descriptor for transaction 4. Submit the transaction 5. Issue pending requests and wait for callback notification Now when we query capablities, slave parameters _are_not_set_. So seems like you have thought something and written something else! Agreed. My documentation is incorrect. My bad, it should have been ordered 1, 2, 1a, ... as you've noted. Which brings me to the point on what are we trying to query: a) API capability, dont need slave parameters for that agreed b) Sg segment length and numbers: Well these are capabilities, so it tells you what is the maximum I can do. IMO it doesn't make sense to tie it down to burst, width etc. For that configuration you are checking maximum. What this needs to return is what is the maximum length it supports and maximum number of sg list the h/w can use. Also if you return your burst and width capablity, then any client can easily find out what is the length byte value it can hold. Ok, so I could report the max burst size to the client, but on EDMA it's going to be SZ_64K-1, as that's the hw limit. Max addr width would also be the same or capped at the maximum enum the current API support of 8 bytes. This information is not useful to the client in my case. Only the client knows its FIFO size, and thus the actual burst size it needs to request as that is a value specific to the IP the client driver controls. So it knows actual burst size and the width of that fifo transfer, because we already support telling the dmaengine driver this info in the current API. But, the client driver has no idea what DMAC it's using under the API. So, whereas if the omap_hsmmc driver is running on omap-dma, it can handle any SG segment size, if the driver happens to be running on edma, it needs to know the actual allowed max segment size for the slave channel parameters that it has set. The theoretical max segment size on EDMA is far larger than the actual maximum for a configured slave channel. This is why (yes, I screwed up and the documentation had the ordering wrong) I had the intention of dma_get_channel_caps() only being valid *after* dma_slave_config() was called. This is, in fact, the only point at which the edma driver has enough information to be able to report a valid max number of segments back to a client driver. Consider that on another channel, with burst size configured by a client driver to a high value (e.g. twice as big of a FIFO), now the edma driver has to report a small max segment size that can be used. The client driver has no idea it's on an edma controller so it needs some help from the dmaengine API to choose the optimal constraints when it builds SG lists. Too large and the EDMA driver has to reject it, too small and we lose performance and also run into the constraint edma has on the total number of segments we can handle in one sg list. If you feel this computaion if client specific, though looking at doesnt make me think so, you can add a callback for this computaion given the parameters. It's client-specific in the sense that the client peripheral is what provides the address width and burst size constraint (based on the FIFO integrated with that peripheral instantiation), but the abstracted dmaengine peripheral is what provides the segment size
Re: [PATCH v2 2/3] dma: edma: add device_channel_caps() support
On Mon, Jan 21, 2013 at 03:16:32AM +, Vinod Koul wrote: On Sun, Jan 20, 2013 at 11:51:08AM -0500, Matt Porter wrote: The explanation in the cover letter mentions that dmaengine_slave_config() is required to be called prior to dmaengine_get_channel_caps(). If we switch to the alternative API, then that would go away including the dependency on direction. Nope you got that wrong! :) Yes, dropped the ball there, should have been for the api to make sense as implemented: 1. Allocate a DMA slave channel 2. Set slave and controller specific parameters 2a. [Optionally] Get channel capabilities 3. Get a descriptor for transaction 4. Submit the transaction 5. Issue pending requests and wait for callback notification FWIW, the implementation example in the davinci mmc client driver shows proper use as in the correct documentation above. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v2 0/3] dmaengine: add per channel capabilities api
On Sun, Jan 20, 2013 at 12:37:34PM +, Vinod Koul wrote: On Thu, Jan 10, 2013 at 02:07:03PM -0500, Matt Porter wrote: The call is implemented as follows: struct dmaengine_chan_caps *dma_get_channel_caps(struct dma_chan *chan, enum dma_transfer_direction dir); The dma transfer direction parameter may appear a bit out of place but it is necessary since the direction field in struct dma_slave_config was deprecated. In some cases, EDMA for one, it is necessary for the dmaengine driver to have the burst and address width slave configuration parameters available in order to compute the maximum segment size that can be handle. Due to this requirement, the calling order of this api is as follows: Well you are passing direction as argument so even in EDMA it doesn't seem to help you as you seem to need burst and width!. So why do you even need the direction to compute the capablities Yes, I need burst and width, but they are dependent on direction (dst vs src, as stored in the slave channel config). Ok, so I think I know where this is leading...the problem is probably that I made an implicit dependency on burst and width here. The expectation in this implementation is that dmaengine_slave_config() has already been called and as a result, the dmaengine driver has either src_* or dst_* attributes populated depending on the direction of the channel. Given that, the call to dma_get_channel_caps() needs to provide the direction in order for the driver to know which of src_*/dst_* attributes are valid in order to do the max segment size calculation. An alternative, since the slave driver is the one that provided the info in the first place is: struct dmaengine_chan_caps *dma_get_channel_caps(struct dma_chan *chan, enum dma_slave_buswidth addr_width, u32 maxburst); where the attributes required by the edma driver to find the max segment size are now explicitly provided. This approach also removes the ordering requirement of calling dmaengine_slave_config() first. Is this what you had in mind? -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v2 1/3] dmaengine: add dma_get_channel_caps()
On Sun, Jan 20, 2013 at 12:52:43PM +, Vinod Koul wrote: On Thu, Jan 10, 2013 at 02:07:04PM -0500, Matt Porter wrote: +/* struct dmaengine_chan_caps - expose capability of a channel + * Note: each channel can have same or different capabilities + * + * This primarily classifies capabilities into + * a) APIs/ops supported + * b) channel physical capabilities + * + * @cap_mask: api/ops capability (DMA_INTERRUPT and DMA_PRIVATE + *are invalid api/ops and will never be set) + * @seg_nr: maximum number of SG segments supported on a SG/SLAVE + * channel (0 for no maximum or not a SG/SLAVE channel) + * @seg_len: maximum length of SG segments supported on a SG/SLAVE + * channel (0 for no maximum or not a SG/SLAVE channel) + */ +struct dmaengine_chan_caps { + dma_cap_mask_t cap_mask; + int seg_nr; + int seg_len; +}; Now am really unclear why we would need direction as argument. Best explanation is my reply to your comments on 0/3. In summary, the direction allows the edma driver to select the src vs dst addr_width and maxburst fields to be used to calculate the max segment size that can be handled. Also, I would add the channel physical capablities like direction, widths, lengths etc supported. Ok, I can take a stab at this...I didn't bother initially as I don't have user for that info at this point. Though, I suppose we don't have an immediate user for the cap_mask either. +/** + * dma_get_channel_caps - flush pending transactions to HW flush pending... ??? ugh, cp fail...will fix. + * driver does not implement per channel capbilities then + * NULL is returned. + */ +static inline struct dmaengine_chan_caps +*dma_get_channel_caps(struct dma_chan *chan, enum dma_transfer_direction dir) you need to add this for when CONFIG_DMA_ENGINE is not defined as well. ok, will fix. +{ + if (chan-device-device_channel_caps) + return chan-device-device_channel_caps(chan, dir); + return NULL; +} + enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); #ifdef CONFIG_DMA_ENGINE enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); -- ~Vinod ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
Re: [PATCH v2 2/3] dma: edma: add device_channel_caps() support
On Sun, Jan 20, 2013 at 01:03:21PM +, Vinod Koul wrote: On Thu, Jan 10, 2013 at 02:07:05PM -0500, Matt Porter wrote: Implement device_channel_caps(). EDMA has a finite set of PaRAM slots available for linking a multi-segment SG transfer. In order to prevent any one channel from consuming all PaRAM slots to fulfill a large SG transfer, the driver reports a static per-channel max number of SG segments it will handle. The maximum size of SG segment is limited by the slave config maxburst and addr_width for the channel in question. These values are used from the current channel config to calculate and return the max segment length cap. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/dma/edma.c | 27 +++ 1 file changed, 27 insertions(+) diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 82c8672..fc4b9db 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -70,6 +70,7 @@ struct edma_chan { boolalloced; int slot[EDMA_MAX_SLOTS]; struct dma_slave_config cfg; + struct dmaengine_chan_caps caps; }; struct edma_cc { @@ -462,6 +463,28 @@ static void edma_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(echan-vchan.lock, flags); } +static struct dmaengine_chan_caps +*edma_get_channel_caps(struct dma_chan *chan, enum dma_transfer_direction dir) +{ + struct edma_chan *echan; + enum dma_slave_buswidth width = 0; + u32 burst = 0; + + if (chan) { I think this check is redundant. Yes, will remove. + echan = to_edma_chan(chan); + if (dir == DMA_MEM_TO_DEV) { + width = echan-cfg.dst_addr_width; + burst = echan-cfg.dst_maxburst; Per you API example burst and width is not set yet, so this doesn't make sense The explanation in the cover letter mentions that dmaengine_slave_config() is required to be called prior to dmaengine_get_channel_caps(). If we switch to the alternative API, then that would go away including the dependency on direction. + } else if (dir == DMA_DEV_TO_MEM) { + width = echan-cfg.src_addr_width; + burst = echan-cfg.src_maxburst; + } + echan-caps.seg_len = (SZ_64K - 1) * width * burst; Also the defination of API is max, above computation doesn't make sense to me! Ok, so in this case, the slave driver has informed the dmaengine driver that the max burst for the channel is foo. That's in units of addr_width. On the EDMA DMAC, we program burst transfers by setting ACNT to our per-transfer width (FIFO width in the slave SG case we are covering here) then BCNT gets the maxburst setting. We then have a CCNT field for EDMA that has a limit of SZ_64K-1 transfers. Thus, if a slave driver tells us the maxburst for the channel is foo and our width is bar, the maximum size of an SG segment in that configuration is: (SZ_64K - 1) * bar * foo. -Matt ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 02/14] ARM: edma: remove unused transfer controller handlers
Fix build on OMAP, the irqs are undefined on AM33xx. These error interrupt handlers were hardcoded as disabled so since they are unused code, simply remove them. Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/common/edma.c | 37 - 1 file changed, 37 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index be3c04a..2dce245 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -494,26 +494,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data) return IRQ_HANDLED; } -/** - * - * Transfer controller error interrupt handlers - * - */ - -#define tc_errs_handledfalse /* disabled as long as they're NOPs */ - -static irqreturn_t dma_tc0err_handler(int irq, void *data) -{ - dev_dbg(data, dma_tc0err_handler\n); - return IRQ_HANDLED; -} - -static irqreturn_t dma_tc1err_handler(int irq, void *data) -{ - dev_dbg(data, dma_tc1err_handler\n); - return IRQ_HANDLED; -} - static int reserve_contiguous_slots(int ctlr, unsigned int id, unsigned int num_slots, unsigned int start_slot) @@ -1538,23 +1518,6 @@ static int edma_probe(struct platform_device *pdev) arch_num_cc++; } - if (tc_errs_handled) { - status = request_irq(IRQ_TCERRINT0, dma_tc0err_handler, 0, - edma_tc0, pdev-dev); - if (status 0) { - dev_dbg(pdev-dev, request_irq %d failed -- %d\n, - IRQ_TCERRINT0, status); - return status; - } - status = request_irq(IRQ_TCERRINT, dma_tc1err_handler, 0, - edma_tc1, pdev-dev); - if (status 0) { - dev_dbg(pdev-dev, request_irq %d -- %d\n, - IRQ_TCERRINT, status); - return status; - } - } - return 0; fail: -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 01/14] ARM: davinci: move private EDMA API to arm/common
Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. This just moves the private EDMA API and enables it to build on OMAP. Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/Kconfig |1 + arch/arm/common/Kconfig|3 + arch/arm/common/Makefile |1 + arch/arm/{mach-davinci/dma.c = common/edma.c} |4 +- arch/arm/mach-davinci/Makefile |2 +- arch/arm/mach-davinci/board-tnetv107x-evm.c|2 +- arch/arm/mach-davinci/davinci.h|2 +- arch/arm/mach-davinci/devices-tnetv107x.c |2 +- arch/arm/mach-davinci/devices.c|7 +- arch/arm/mach-davinci/dm355.c |2 +- arch/arm/mach-davinci/dm365.c |2 +- arch/arm/mach-davinci/dm644x.c |2 +- arch/arm/mach-davinci/dm646x.c |2 +- arch/arm/mach-davinci/include/mach/da8xx.h |2 +- arch/arm/plat-omap/Kconfig |1 + drivers/dma/edma.c |2 +- drivers/mmc/host/davinci_mmc.c |1 + include/linux/mfd/davinci_voicecodec.h |3 +- .../mach = include/linux/platform_data}/edma.h| 89 +--- include/linux/platform_data/spi-davinci.h |2 +- sound/soc/davinci/davinci-evm.c|1 + sound/soc/davinci/davinci-pcm.c|1 + sound/soc/davinci/davinci-pcm.h|2 +- sound/soc/davinci/davinci-sffsdr.c |6 +- 24 files changed, 33 insertions(+), 109 deletions(-) rename arch/arm/{mach-davinci/dma.c = common/edma.c} (99%) rename {arch/arm/mach-davinci/include/mach = include/linux/platform_data}/edma.h (59%) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 67874b8..7637d31 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -932,6 +932,7 @@ config ARCH_DAVINCI select GENERIC_IRQ_CHIP select HAVE_IDE select NEED_MACH_GPIO_H + select TI_PRIV_EDMA select USE_OF select ZONE_DMA help diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 45ceeb0..9e32d0d 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -40,3 +40,6 @@ config SHARP_PARAM config SHARP_SCOOP bool + +config TI_PRIV_EDMA + bool diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index e8a4e58..d09a39b 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o +obj-$(CONFIG_TI_PRIV_EDMA) += edma.o diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/common/edma.c similarity index 99% rename from arch/arm/mach-davinci/dma.c rename to arch/arm/common/edma.c index a685e97..be3c04a 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/common/edma.c @@ -25,7 +25,7 @@ #include linux/io.h #include linux/slab.h -#include mach/edma.h +#include linux/platform_data/edma.h /* Offsets matching struct edmacc_param */ #define PARM_OPT 0x00 @@ -1387,7 +1387,7 @@ EXPORT_SYMBOL(edma_clear_event); /*---*/ -static int __init edma_probe(struct platform_device *pdev) +static int edma_probe(struct platform_device *pdev) { struct edma_soc_info**info = pdev-dev.platform_data; const s8(*queue_priority_mapping)[2]; diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index fb5c1aa..493a36b 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -5,7 +5,7 @@ # Common objects obj-y := time.o clock.o serial.o psc.o \ - dma.o usb.o common.o sram.o aemif.o + usb.o common.o sram.o aemif.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index be30997..86f55ba 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -26,12 +26,12 @@ #include linux/input.h #include linux/input/matrix_keypad.h #include linux/spi/spi.h +#include linux/platform_data/edma.h #include asm/mach/arch.h #include asm/mach-types.h #include mach/irqs.h -#include mach/edma.h #include mach/mux.h #include mach/cp_intc.h #include mach/tnetv107x.h diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index 12d544b..d26a6bc 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h @@ -23,9 +23,9 @@ #include linux/platform_device.h
[PATCH v5 03/14] ARM: edma: add AM33XX support to the private EDMA API
Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Adds AM33XX EMDA crossbar event mux support. Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/common/edma.c | 314 ++-- include/linux/platform_data/edma.h |1 + 2 files changed, 306 insertions(+), 9 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 2dce245..beeb1d2 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -24,6 +24,13 @@ #include linux/platform_device.h #include linux/io.h #include linux/slab.h +#include linux/edma.h +#include linux/err.h +#include linux/of_address.h +#include linux/of_device.h +#include linux/of_dma.h +#include linux/of_irq.h +#include linux/pm_runtime.h #include linux/platform_data/edma.h @@ -723,6 +730,9 @@ EXPORT_SYMBOL(edma_free_channel); */ int edma_alloc_slot(unsigned ctlr, int slot) { + if (!edma_cc[ctlr]) + return -EINVAL; + if (slot = 0) slot = EDMA_CHAN_SLOT(slot); @@ -1366,31 +1376,291 @@ void edma_clear_event(unsigned channel) EXPORT_SYMBOL(edma_clear_event); /*---*/ +static int edma_of_read_u32_to_s8_array(const struct device_node *np, +const char *propname, s8 *out_values, +size_t sz) +{ + struct property *prop = of_find_property(np, propname, NULL); + const __be32 *val; + + if (!prop) + return -EINVAL; + if (!prop-value) + return -ENODATA; + if ((sz * sizeof(u32)) prop-length) + return -EOVERFLOW; + + val = prop-value; + + while (sz--) + *out_values++ = (s8)(be32_to_cpup(val++) 0xff); + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_of_read_u32_to_s16_array(const struct device_node *np, +const char *propname, s16 *out_values, +size_t sz) +{ + struct property *prop = of_find_property(np, propname, NULL); + const __be32 *val; + + if (!prop) + return -EINVAL; + if (!prop-value) + return -ENODATA; + if ((sz * sizeof(u32)) prop-length) + return -EOVERFLOW; + + val = prop-value; + + while (sz--) + *out_values++ = (s16)(be32_to_cpup(val++) 0x); + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_xbar_event_map(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata, int len) +{ + int ret = 0; + int i; + struct resource res; + void *xbar; + const s16 (*xbar_chans)[2]; + u32 shift, offset, mux; + + xbar_chans = devm_kzalloc(dev, + len/sizeof(s16) + 2*sizeof(s16), + GFP_KERNEL); + if (!xbar_chans) + return -ENOMEM; + + ret = of_address_to_resource(node, 1, res); + if (IS_ERR_VALUE(ret)) + return -EIO; + + xbar = devm_ioremap(dev, res.start, resource_size(res)); + if (!xbar) + return -ENOMEM; + + ret = edma_of_read_u32_to_s16_array(node, + ti,edma-xbar-event-map, + (s16 *)xbar_chans, + len/sizeof(u32)); + if (IS_ERR_VALUE(ret)) + return -EIO; + + for (i = 0; xbar_chans[i][0] != -1; i++) { + shift = (xbar_chans[i][1] % 4) * 8; + offset = xbar_chans[i][1] 2; + offset = 2; + mux = readl((void *)((u32)xbar + offset)); + mux = ~(0xff shift); + mux |= xbar_chans[i][0] shift; + writel(mux, (void *)((u32)xbar + offset)); + } + + pdata-xbar_chans = xbar_chans; + + return 0; +} + +static int edma_of_parse_dt(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata) +{ + int ret = 0; + u32 value; + struct property *prop; + size_t sz; + struct edma_rsv_info *rsv_info; + const s16 (*rsv_chans)[2], (*rsv_slots)[2]; + const s8 (*queue_tc_map)[2], (*queue_priority_map)[2]; + + memset(pdata, 0, sizeof(struct edma_soc_info)); + + ret = of_property_read_u32(node, dma-channels, value); + if (ret 0) + return ret; + pdata-n_channel = value; + + ret = of_property_read_u32(node, ti,edma-regions, value); + if (ret 0
[PATCH v5 04/14] dmaengine: edma: enable build for AM33XX
Enable TI EDMA option on OMAP. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/dma/Kconfig |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index d4c1218..20ef955 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -221,7 +221,7 @@ config SIRF_DMA config TI_EDMA tristate TI EDMA support - depends on ARCH_DAVINCI + depends on ARCH_DAVINCI || ARCH_OMAP select DMA_ENGINE select DMA_VIRTUAL_CHANNELS default n -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 08/14] mmc: omap_hsmmc: convert to dma_request_slave_channel_compat()
Convert dmaengine channel requests to use dma_request_slave_channel_compat(). This supports the DT case of platforms requiring channel selection from either the OMAP DMA or the EDMA engine. AM33xx only boots from DT and is the only user implementing EDMA so in the !DT case we can default to the OMAP DMA filter. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Tony Lindgren t...@atomide.com --- drivers/mmc/host/omap_hsmmc.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index bc58078..e79b12d 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1915,14 +1915,20 @@ static int omap_hsmmc_probe(struct platform_device *pdev) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - host-rx_chan = dma_request_channel(mask, omap_dma_filter_fn, rx_req); + host-rx_chan = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +rx_req, pdev-dev, rx); + if (!host-rx_chan) { dev_err(mmc_dev(host-mmc), unable to obtain RX DMA engine channel %u\n, rx_req); ret = -ENXIO; goto err_irq; } - host-tx_chan = dma_request_channel(mask, omap_dma_filter_fn, tx_req); + host-tx_chan = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +tx_req, pdev-dev, tx); + if (!host-tx_chan) { dev_err(mmc_dev(host-mmc), unable to obtain TX DMA engine channel %u\n, tx_req); ret = -ENXIO; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 00/14] DMA Engine support for AM33XX
Changes since v4: - Fixed debug section mismatch in private edma api [01/14] - Respun format-patch to catch the platform_data/edma.h rename [01/14] - Removed address/size-cells from the EDMA binding [05/14] Changes since v3: - Rebased on 3.8-rc3 - No longer an RFC - Fixed bugs in DT/pdata parsing reported by Vaibhav Bedia - Restored all the Davinci pdata to const - Removed max_segs hack in favor of using dma_get_channel_caps() - Fixed extra parens, __raw_* accessors and, ioremap error checks in xbar handling - Removed excess license info in platform_data/edma.h - Removed unneeded reserved channels data for AM33xx - Removed test-specific pinmuxing from dts files - Adjusted mmc1 node to be disabled by default in the dtsi Changes since v2: - Rebased on 3.7-rc1 - Fixed bug in DT/pdata parsing first found by Gururaja that turned out to be masked by some toolchains - Dropped unused mach-omap2/devices.c hsmmc patch - Added AM33XX crossbar DMA event mux support - Added am335x-evm support Changes since v1: - Rebased on top of mainline from 12250d8 - Dropped the feature removal schedule patch - Implemented dma_request_slave_channel_compat() and converted the mmc and spi drivers to use it - Dropped unneeded #address-cells and #size-cells from EDMA DT support - Moved private EDMA header to linux/platform_data/ and removed some unneeded definitions - Fixed parsing of optional properties This series adds DMA Engine support for AM33xx, which uses an EDMA DMAC. The EDMA DMAC has been previously supported by only a private API implementation (much like the situation with OMAP DMA) found on the DaVinci family of SoCs. The series applies on top of 3.8-rc3 and the following patches: - TPS65910 REGMAP_IRQ build fix: https://patchwork.kernel.org/patch/1857701/ - dmaengine DT support from Vinod's dmaengine_dt branch in git://git.infradead.org/users/vkoul/slave-dma.git since 027478851791df751176398be02a3b1c5f6aa824 - edma dmaengine driver fix: https://patchwork.kernel.org/patch/1961521/ - dmaengine dma_get_channel_caps v2: https://patchwork.kernel.org/patch/1961601/ - dmaengine edma driver channel caps support v2: https://patchwork.kernel.org/patch/1961591/ The approach taken is similar to how OMAP DMA is being converted to DMA Engine support. With the functional EDMA private API already existing in mach-davinci/dma.c, we first move that to an ARM common area so it can be shared. Adding DT and runtime PM support to the private EDMA API implementation allows it to run on AM33xx. AM33xx *only* boots using DT so we leverage Jon's generic DT DMA helpers to register EDMA DMAC with the of_dma framework and then add support for calling the dma_request_slave_channel() API to both the mmc and spi drivers. With this series both BeagleBone and the AM335x EVM have working MMC and SPI support. This is tested on BeagleBone with a SPI framebuffer driver and MMC rootfs. A trivial gpio DMA event misc driver was used to test the crossbar DMA event support. It is also tested on the AM335x EVM with the onboard SPI flash and MMC rootfs. The branch at https://github.com/ohporter/linux/tree/edma-dmaengine-am33xx-v4 has the complete series, dependencies, and some test drivers/defconfigs. Regression testing was done on AM180x-EVM (which also makes use of the EDMA dmaengine driver and the EDMA private API) using SD, SPI flash, and the onboard audio supported by the ASoC Davinci driver. Regression testing was also done on a BeagleBoard xM booting from the legacy board file using MMC rootfs. Matt Porter (14): ARM: davinci: move private EDMA API to arm/common ARM: edma: remove unused transfer controller handlers ARM: edma: add AM33XX support to the private EDMA API dmaengine: edma: enable build for AM33XX dmaengine: edma: Add TI EDMA device tree binding ARM: dts: add AM33XX EDMA support dmaengine: add dma_request_slave_channel_compat() mmc: omap_hsmmc: convert to dma_request_slave_channel_compat() mmc: omap_hsmmc: set max_segs based on dma engine limitations mmc: omap_hsmmc: add generic DMA request support to the DT binding ARM: dts: add AM33XX MMC support spi: omap2-mcspi: convert to dma_request_slave_channel_compat() spi: omap2-mcspi: add generic DMA request support to the DT binding ARM: dts: add AM33XX SPI DMA support Documentation/devicetree/bindings/dma/ti-edma.txt | 49 +++ .../devicetree/bindings/mmc/ti-omap-hsmmc.txt | 25 +- Documentation/devicetree/bindings/spi/omap-spi.txt | 28 +- arch/arm/Kconfig |1 + arch/arm/boot/dts/am335x-bone.dts |7 + arch/arm/boot/dts/am335x-evm.dts |7
[PATCH v5 05/14] dmaengine: edma: Add TI EDMA device tree binding
The binding definition is based on the generic DMA controller binding. Signed-off-by: Matt Porter mpor...@ti.com --- Documentation/devicetree/bindings/dma/ti-edma.txt | 49 + 1 file changed, 49 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/ti-edma.txt diff --git a/Documentation/devicetree/bindings/dma/ti-edma.txt b/Documentation/devicetree/bindings/dma/ti-edma.txt new file mode 100644 index 000..075a60e3 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/ti-edma.txt @@ -0,0 +1,49 @@ +TI EDMA + +Required properties: +- compatible : ti,edma3 +- ti,hwmods: Name of the hwmods associated to the EDMA +- ti,edma-regions: Number of regions +- ti,edma-slots: Number of slots +- ti,edma-queue-tc-map: List of transfer control to queue mappings +- ti,edma-queue-priority-map: List of queue priority mappings +- ti,edma-default-queue: Default queue value + +Optional properties: +- ti,edma-reserved-channels: List of reserved channel regions +- ti,edma-reserved-slots: List of reserved slot regions +- ti,edma-xbar-event-map: Crossbar event to channel map + +Example: + +edma: edma@4900 { + reg = 0x4900 0x1; + interrupt-parent = intc; + interrupts = 12 13 14; + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-reserved-channels = 0 2 +14 2 +26 6 +48 4 +56 8; + ti,edma-reserved-slots = 0 2 + 14 2 + 26 6 + 48 4 + 56 8 + 64 127; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + ti,edma-xbar-event-map = 1 12 + 2 13; +}; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 06/14] ARM: dts: add AM33XX EDMA support
Adds AM33XX EDMA support to the am33xx.dtsi as documented in Documentation/devicetree/bindings/dma/ti-edma.txt Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/boot/dts/am33xx.dtsi | 20 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index c2f14e8..e711ffb 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -87,6 +87,26 @@ reg = 0x4820 0x1000; }; + edma: edma@4900 { + compatible = ti,edma3; + ti,hwmods = tpcc, tptc0, tptc1, tptc2; + reg = 0x4900 0x1, + 0x44e10f90 0x10; + interrupt-parent = intc; + interrupts = 12 13 14; + #dma-cells = 1; + dma-channels = 64; + ti,edma-regions = 4; + ti,edma-slots = 256; + ti,edma-queue-tc-map = 0 0 + 1 1 + 2 2; + ti,edma-queue-priority-map = 0 0 + 1 1 + 2 2; + ti,edma-default-queue = 0; + }; + gpio1: gpio@44e07000 { compatible = ti,omap4-gpio; ti,hwmods = gpio1; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 07/14] dmaengine: add dma_request_slave_channel_compat()
Adds a dma_request_slave_channel_compat() wrapper which accepts both the arguments from dma_request_channel() and dma_request_slave_channel(). Based on whether the driver is instantiated via DT, the appropriate channel request call will be made. This allows for a much cleaner migration of drivers to the dmaengine DT API as platforms continue to be mixed between those that boot using DT and those that do not. Suggested-by: Tony Lindgren t...@atomide.com Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Tony Lindgren t...@atomide.com --- include/linux/dmaengine.h | 10 ++ 1 file changed, 10 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 9fd0c5b..64f9f69 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -1047,6 +1047,16 @@ void dma_run_dependencies(struct dma_async_tx_descriptor *tx); struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); struct dma_chan *net_dma_find_channel(void); #define dma_request_channel(mask, x, y) __dma_request_channel((mask), x, y) +static inline struct dma_chan +*dma_request_slave_channel_compat(dma_cap_mask_t mask, dma_filter_fn fn, + void *fn_param, struct device *dev, + char *name) +{ + if (dev-of_node) + return dma_request_slave_channel(dev, name); + else + return dma_request_channel(mask, fn, fn_param); +} /* --- Helper iov-locking functions --- */ -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 13/14] spi: omap2-mcspi: add generic DMA request support to the DT binding
The binding definition is based on the generic DMA request binding. Signed-off-by: Matt Porter mpor...@ti.com --- Documentation/devicetree/bindings/spi/omap-spi.txt | 28 +++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/spi/omap-spi.txt b/Documentation/devicetree/bindings/spi/omap-spi.txt index 938809c..3bd8eed 100644 --- a/Documentation/devicetree/bindings/spi/omap-spi.txt +++ b/Documentation/devicetree/bindings/spi/omap-spi.txt @@ -10,7 +10,18 @@ Required properties: input. The default is D0 as input and D1 as output. -Example: +Optional properties: +- dmas: List of DMA controller phandle and DMA request ordered + pairs. One tx and one rx pair is required for each chip + select. +- dma-names: List of DMA request names. These strings correspond + 1:1 with the ordered pairs in dmas. The string naming is + to be rxN and txN for RX and TX requests, + respectively, where N equals the chip select number. + +Examples: + +[hwmod populated DMA resources] mcspi1: mcspi@1 { #address-cells = 1; @@ -20,3 +31,18 @@ mcspi1: mcspi@1 { ti,spi-num-cs = 4; }; +[generic DMA request binding] + +mcspi1: mcspi@1 { +#address-cells = 1; +#size-cells = 0; +compatible = ti,omap4-mcspi; +ti,hwmods = mcspi1; +ti,spi-num-cs = 2; +dmas = edma 42 + edma 43 + edma 44 + edma 45; +dma-names = tx0, rx0, tx1, rx1; +}; + -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 10/14] mmc: omap_hsmmc: add generic DMA request support to the DT binding
The binding definition is based on the generic DMA request binding. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Tony Lindgren t...@atomide.com --- .../devicetree/bindings/mmc/ti-omap-hsmmc.txt | 25 +++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt index ed271fc..826cc51 100644 --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt @@ -20,8 +20,28 @@ ti,dual-volt: boolean, supports dual voltage cards ti,non-removable: non-removable slot (like eMMC) ti,needs-special-reset: Requires a special softreset sequence ti,needs-special-hs-handling: HSMMC IP needs special setting for handling High Speed +dmas: DMA controller phandle and DMA request value ordered pair +One tx and one rx pair is required. +dma-names: DMA request names. These strings correspond 1:1 with +the ordered pairs in dmas. The RX request must be rx and the +TX request must be tx. + +Examples: + +[hwmod populated DMA resources] + + mmc1: mmc@0x4809c000 { + compatible = ti,omap4-hsmmc; + reg = 0x4809c000 0x400; + ti,hwmods = mmc1; + ti,dual-volt; + bus-width = 4; + vmmc-supply = vmmc; /* phandle to regulator node */ + ti,non-removable; + }; + +[generic DMA request binding] -Example: mmc1: mmc@0x4809c000 { compatible = ti,omap4-hsmmc; reg = 0x4809c000 0x400; @@ -30,4 +50,7 @@ Example: bus-width = 4; vmmc-supply = vmmc; /* phandle to regulator node */ ti,non-removable; + dmas = edma 24 + edma 25; + dma-names = tx, rx; }; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 09/14] mmc: omap_hsmmc: set max_segs based on dma engine limitations
The EDMA DMAC has a hardware limitation that prevents supporting scatter gather lists with any number of segments. The DMA Engine API reports the maximum number of segments a channel can support via the optional dma_get_channel_caps() API. If the nr_segs capability is present, the value is used to configure mmc-max_segs appropriately. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Tony Lindgren t...@atomide.com --- drivers/mmc/host/omap_hsmmc.c |6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index e79b12d..f74bd69 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -1769,6 +1769,7 @@ static int omap_hsmmc_probe(struct platform_device *pdev) const struct of_device_id *match; dma_cap_mask_t mask; unsigned tx_req, rx_req; + struct dmaengine_chan_caps *dma_chan_caps; struct pinctrl *pinctrl; match = of_match_device(of_match_ptr(omap_mmc_of_match), pdev-dev); @@ -1935,6 +1936,11 @@ static int omap_hsmmc_probe(struct platform_device *pdev) goto err_irq; } + /* Some DMA Engines only handle a limited number of SG segments */ + dma_chan_caps = dma_get_channel_caps(host-rx_chan, DMA_DEV_TO_MEM); + if (dma_chan_caps dma_chan_caps-seg_nr) + mmc-max_segs = dma_chan_caps-seg_nr; + /* Request IRQ for MMC operations */ ret = request_irq(host-irq, omap_hsmmc_irq, 0, mmc_hostname(mmc), host); -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 11/14] ARM: dts: add AM33XX MMC support
Adds AM33XX MMC support for am335x-bone, am335x-evm, and am335x-evmsk. Signed-off-by: Matt Porter mpor...@ti.com Acked-by: Tony Lindgren t...@atomide.com --- arch/arm/boot/dts/am335x-bone.dts |7 +++ arch/arm/boot/dts/am335x-evm.dts |7 +++ arch/arm/boot/dts/am335x-evmsk.dts |7 +++ arch/arm/boot/dts/am33xx.dtsi | 28 4 files changed, 49 insertions(+) diff --git a/arch/arm/boot/dts/am335x-bone.dts b/arch/arm/boot/dts/am335x-bone.dts index 11b240c..a154ce0 100644 --- a/arch/arm/boot/dts/am335x-bone.dts +++ b/arch/arm/boot/dts/am335x-bone.dts @@ -120,6 +120,8 @@ }; ldo3_reg: regulator@5 { + regulator-min-microvolt = 180; + regulator-max-microvolt = 330; regulator-always-on; }; @@ -136,3 +138,8 @@ cpsw_emac1 { phy_id = davinci_mdio, 1; }; + +mmc1 { + status = okay; + vmmc-supply = ldo3_reg; +}; diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index d649644..2907da6 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -232,6 +232,8 @@ }; vmmc_reg: regulator@12 { + regulator-min-microvolt = 180; + regulator-max-microvolt = 330; regulator-always-on; }; }; @@ -244,3 +246,8 @@ cpsw_emac1 { phy_id = davinci_mdio, 1; }; + +mmc1 { + status = okay; + vmmc-supply = vmmc_reg; +}; diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index f5a6162..f050c46 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -244,7 +244,14 @@ }; vmmc_reg: regulator@12 { + regulator-min-microvolt = 180; + regulator-max-microvolt = 330; regulator-always-on; }; }; }; + +mmc1 { + status = okay; + vmmc-supply = vmmc_reg; +}; diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index e711ffb..278b75d 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -235,6 +235,34 @@ status = disabled; }; + mmc1: mmc@4806 { + compatible = ti,omap3-hsmmc; + ti,hwmods = mmc1; + ti,dual-volt; + ti,needs-special-reset; + dmas = edma 24 + edma 25; + dma-names = tx, rx; + status = disabled; + }; + + mmc2: mmc@481d8000 { + compatible = ti,omap3-hsmmc; + ti,hwmods = mmc2; + ti,needs-special-reset; + dmas = edma 2 + edma 3; + dma-names = tx, rx; + status = disabled; + }; + + mmc3: mmc@4781 { + compatible = ti,omap3-hsmmc; + ti,hwmods = mmc3; + ti,needs-special-reset; + status = disabled; + }; + wdt2: wdt@44e35000 { compatible = ti,omap3-wdt; ti,hwmods = wd_timer2; -- 1.7.9.5 ___ Davinci-linux-open-source mailing list Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source
[PATCH v5 12/14] spi: omap2-mcspi: convert to dma_request_slave_channel_compat()
Convert dmaengine channel requests to use dma_request_slave_channel_compat(). This supports the DT case of platforms requiring channel selection from either the OMAP DMA or the EDMA engine. AM33xx only boots from DT and is the only user implementing EDMA so in the !DT case we can default to the OMAP DMA filter. Signed-off-by: Matt Porter mpor...@ti.com --- drivers/spi/spi-omap2-mcspi.c | 65 - 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index b610f52..2c02c02 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -102,6 +102,9 @@ struct omap2_mcspi_dma { struct completion dma_tx_completion; struct completion dma_rx_completion; + + char dma_rx_ch_name[14]; + char dma_tx_ch_name[14]; }; /* use PIO for small transfers, avoiding DMA setup/teardown overhead and @@ -822,14 +825,23 @@ static int omap2_mcspi_request_dma(struct spi_device *spi) dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); sig = mcspi_dma-dma_rx_sync_dev; - mcspi_dma-dma_rx = dma_request_channel(mask, omap_dma_filter_fn, sig); + + mcspi_dma-dma_rx = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +sig, master-dev, +mcspi_dma-dma_rx_ch_name); + if (!mcspi_dma-dma_rx) { dev_err(spi-dev, no RX DMA engine channel for McSPI\n); return -EAGAIN; } sig = mcspi_dma-dma_tx_sync_dev; - mcspi_dma-dma_tx = dma_request_channel(mask, omap_dma_filter_fn, sig); + mcspi_dma-dma_tx = + dma_request_slave_channel_compat(mask, omap_dma_filter_fn, +sig, master-dev, +mcspi_dma-dma_tx_ch_name); + if (!mcspi_dma-dma_tx) { dev_err(spi-dev, no TX DMA engine channel for McSPI\n); dma_release_channel(mcspi_dma-dma_rx); @@ -1223,29 +1235,42 @@ static int omap2_mcspi_probe(struct platform_device *pdev) goto free_master; for (i = 0; i master-num_chipselect; i++) { - char dma_ch_name[14]; + char *dma_rx_ch_name = mcspi-dma_channels[i].dma_rx_ch_name; + char *dma_tx_ch_name = mcspi-dma_channels[i].dma_tx_ch_name; struct resource *dma_res; - sprintf(dma_ch_name, rx%d, i); - dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); - if (!dma_res) { - dev_dbg(pdev-dev, cannot get DMA RX channel\n); - status = -ENODEV; - break; - } + sprintf(dma_rx_ch_name, rx%d, i); + if (!pdev-dev.of_node) { + dma_res = + platform_get_resource_byname(pdev, +IORESOURCE_DMA, +dma_rx_ch_name); + if (!dma_res) { + dev_dbg(pdev-dev, + cannot get DMA RX channel\n); + status = -ENODEV; + break; + } - mcspi-dma_channels[i].dma_rx_sync_dev = dma_res-start; - sprintf(dma_ch_name, tx%d, i); - dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA, - dma_ch_name); - if (!dma_res) { - dev_dbg(pdev-dev, cannot get DMA TX channel\n); - status = -ENODEV; - break; + mcspi-dma_channels[i].dma_rx_sync_dev = + dma_res-start; } + sprintf(dma_tx_ch_name, tx%d, i); + if (!pdev-dev.of_node) { + dma_res = + platform_get_resource_byname(pdev, +IORESOURCE_DMA, +dma_tx_ch_name); + if (!dma_res) { + dev_dbg(pdev-dev, + cannot get DMA TX channel\n); + status = -ENODEV; + break; + } - mcspi-dma_channels[i].dma_tx_sync_dev = dma_res-start; + mcspi-dma_channels[i].dma_tx_sync_dev = + dma_res-start; + } } if (status 0
Re: [PATCH v4 01/14] ARM: davinci: move private EDMA API to arm/common
On Fri, Jan 11, 2013 at 06:15:06AM +, Hebbar, Gururaja wrote: On Fri, Jan 11, 2013 at 11:18:37, Porter, Matt wrote: Move mach-davinci/dma.c to common/edma.c so it can be used by OMAP (specifically AM33xx) as well. This just moves the private EDMA API and enables it to build on OMAP. Signed-off-by: Matt Porter mpor...@ti.com --- arch/arm/Kconfig |1 + arch/arm/common/Kconfig|3 + arch/arm/common/Makefile |1 + arch/arm/{mach-davinci/dma.c = common/edma.c} |2 +- arch/arm/mach-davinci/Makefile |2 +- arch/arm/mach-davinci/board-tnetv107x-evm.c|2 +- arch/arm/mach-davinci/davinci.h|2 +- arch/arm/mach-davinci/devices-tnetv107x.c |2 +- arch/arm/mach-davinci/devices.c|7 +- arch/arm/mach-davinci/dm355.c |2 +- arch/arm/mach-davinci/dm365.c |2 +- arch/arm/mach-davinci/dm644x.c |2 +- arch/arm/mach-davinci/dm646x.c |2 +- arch/arm/mach-davinci/include/mach/da8xx.h |2 +- arch/arm/mach-davinci/include/mach/edma.h | 267 arch/arm/plat-omap/Kconfig |1 + drivers/dma/edma.c |2 +- drivers/mmc/host/davinci_mmc.c |1 + include/linux/mfd/davinci_voicecodec.h |3 +- include/linux/platform_data/edma.h | 182 Headers file are just moved here. So git mv file1 flie2; and the git format-patch -C on commit should just generate few lines of patch. Ok, good catch. include/linux/platform_data/spi-davinci.h |2 +- sound/soc/davinci/davinci-evm.c|1 + sound/soc/davinci/davinci-pcm.c|1 + sound/soc/davinci/davinci-pcm.h|2 +- sound/soc/davinci/davinci-sffsdr.c |6 +- 25 files changed, 212 insertions(+), 288 deletions(-) rename arch/arm/{mach-davinci/dma.c = common/edma.c} (99%) delete mode 100644 arch/arm/mach-davinci/include/mach/edma.h create mode 100644 include/linux/platform_data/edma.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 67874b8..7637d31 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -932,6 +932,7 @@ config ARCH_DAVINCI select GENERIC_IRQ_CHIP select HAVE_IDE select NEED_MACH_GPIO_H + select TI_PRIV_EDMA select USE_OF select ZONE_DMA help diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 45ceeb0..9e32d0d 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -40,3 +40,6 @@ config SHARP_PARAM config SHARP_SCOOP bool + +config TI_PRIV_EDMA + bool diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile index e8a4e58..d09a39b 100644 --- a/arch/arm/common/Makefile +++ b/arch/arm/common/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp.o +obj-$(CONFIG_TI_PRIV_EDMA) += edma.o diff --git a/arch/arm/mach-davinci/dma.c b/arch/arm/common/edma.c similarity index 99% rename from arch/arm/mach-davinci/dma.c rename to arch/arm/common/edma.c index a685e97..4411087 100644 --- a/arch/arm/mach-davinci/dma.c +++ b/arch/arm/common/edma.c @@ -25,7 +25,7 @@ #include linux/io.h #include linux/slab.h -#include mach/edma.h +#include linux/platform_data/edma.h /* Offsets matching struct edmacc_param */ #define PARM_OPT 0x00 diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile index fb5c1aa..493a36b 100644 --- a/arch/arm/mach-davinci/Makefile +++ b/arch/arm/mach-davinci/Makefile @@ -5,7 +5,7 @@ # Common objects obj-y := time.o clock.o serial.o psc.o \ - dma.o usb.o common.o sram.o aemif.o + usb.o common.o sram.o aemif.o obj-$(CONFIG_DAVINCI_MUX) += mux.o diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c index be30997..86f55ba 100644 --- a/arch/arm/mach-davinci/board-tnetv107x-evm.c +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c @@ -26,12 +26,12 @@ #include linux/input.h #include linux/input/matrix_keypad.h #include linux/spi/spi.h +#include linux/platform_data/edma.h #include asm/mach/arch.h #include asm/mach-types.h #include mach/irqs.h -#include mach/edma.h #include mach/mux.h #include mach/cp_intc.h #include mach/tnetv107x.h diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index 12d544b..d26a6bc 100644 --- a/arch/arm/mach-davinci