159de3cf1SG, Manjunath Kondaiah /* 259de3cf1SG, Manjunath Kondaiah * OMAP2+ DMA driver 359de3cf1SG, Manjunath Kondaiah * 459de3cf1SG, Manjunath Kondaiah * Copyright (C) 2003 - 2008 Nokia Corporation 559de3cf1SG, Manjunath Kondaiah * Author: Juha Yrjölä <juha.yrjola@nokia.com> 659de3cf1SG, Manjunath Kondaiah * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> 759de3cf1SG, Manjunath Kondaiah * Graphics DMA and LCD DMA graphics tranformations 859de3cf1SG, Manjunath Kondaiah * by Imre Deak <imre.deak@nokia.com> 959de3cf1SG, Manjunath Kondaiah * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc. 1059de3cf1SG, Manjunath Kondaiah * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. 1159de3cf1SG, Manjunath Kondaiah * 1259de3cf1SG, Manjunath Kondaiah * Copyright (C) 2009 Texas Instruments 1359de3cf1SG, Manjunath Kondaiah * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> 1459de3cf1SG, Manjunath Kondaiah * 1559de3cf1SG, Manjunath Kondaiah * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 1659de3cf1SG, Manjunath Kondaiah * Converted DMA library into platform driver 1759de3cf1SG, Manjunath Kondaiah * - G, Manjunath Kondaiah <manjugk@ti.com> 1859de3cf1SG, Manjunath Kondaiah * 1959de3cf1SG, Manjunath Kondaiah * This program is free software; you can redistribute it and/or modify 2059de3cf1SG, Manjunath Kondaiah * it under the terms of the GNU General Public License version 2 as 2159de3cf1SG, Manjunath Kondaiah * published by the Free Software Foundation. 2259de3cf1SG, Manjunath Kondaiah */ 2359de3cf1SG, Manjunath Kondaiah 2459de3cf1SG, Manjunath Kondaiah #include <linux/err.h> 2559de3cf1SG, Manjunath Kondaiah #include <linux/io.h> 2659de3cf1SG, Manjunath Kondaiah #include <linux/slab.h> 2759de3cf1SG, Manjunath Kondaiah #include <linux/module.h> 2859de3cf1SG, Manjunath Kondaiah #include <linux/init.h> 2959de3cf1SG, Manjunath Kondaiah #include <linux/device.h> 30be1f9481STony Lindgren #include <linux/dma-mapping.h> 31731ec4d8SPeter Ujfalusi #include <linux/dmaengine.h> 328d30662aSJon Hunter #include <linux/of.h> 3345c3eb7dSTony Lindgren #include <linux/omap-dma.h> 3459de3cf1SG, Manjunath Kondaiah 35e4c060dbSTony Lindgren #include "soc.h" 362a296c8fSTony Lindgren #include "omap_hwmod.h" 3725c7d49eSTony Lindgren #include "omap_device.h" 3825c7d49eSTony Lindgren 39ad0c381aSRussell King static enum omap_reg_offsets dma_common_ch_end; 40f31cc962SG, Manjunath Kondaiah 4164a2dc3dSRussell King static const struct omap_dma_reg reg_map[] = { 4264a2dc3dSRussell King [REVISION] = { 0x0000, 0x00, OMAP_DMA_REG_32BIT }, 4364a2dc3dSRussell King [GCR] = { 0x0078, 0x00, OMAP_DMA_REG_32BIT }, 4464a2dc3dSRussell King [IRQSTATUS_L0] = { 0x0008, 0x00, OMAP_DMA_REG_32BIT }, 4564a2dc3dSRussell King [IRQSTATUS_L1] = { 0x000c, 0x00, OMAP_DMA_REG_32BIT }, 4664a2dc3dSRussell King [IRQSTATUS_L2] = { 0x0010, 0x00, OMAP_DMA_REG_32BIT }, 4764a2dc3dSRussell King [IRQSTATUS_L3] = { 0x0014, 0x00, OMAP_DMA_REG_32BIT }, 4864a2dc3dSRussell King [IRQENABLE_L0] = { 0x0018, 0x00, OMAP_DMA_REG_32BIT }, 4964a2dc3dSRussell King [IRQENABLE_L1] = { 0x001c, 0x00, OMAP_DMA_REG_32BIT }, 5064a2dc3dSRussell King [IRQENABLE_L2] = { 0x0020, 0x00, OMAP_DMA_REG_32BIT }, 5164a2dc3dSRussell King [IRQENABLE_L3] = { 0x0024, 0x00, OMAP_DMA_REG_32BIT }, 5264a2dc3dSRussell King [SYSSTATUS] = { 0x0028, 0x00, OMAP_DMA_REG_32BIT }, 5364a2dc3dSRussell King [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT }, 5464a2dc3dSRussell King [CAPS_0] = { 0x0064, 0x00, OMAP_DMA_REG_32BIT }, 5564a2dc3dSRussell King [CAPS_2] = { 0x006c, 0x00, OMAP_DMA_REG_32BIT }, 5664a2dc3dSRussell King [CAPS_3] = { 0x0070, 0x00, OMAP_DMA_REG_32BIT }, 5764a2dc3dSRussell King [CAPS_4] = { 0x0074, 0x00, OMAP_DMA_REG_32BIT }, 58f31cc962SG, Manjunath Kondaiah 59f31cc962SG, Manjunath Kondaiah /* Common register offsets */ 6064a2dc3dSRussell King [CCR] = { 0x0080, 0x60, OMAP_DMA_REG_32BIT }, 6164a2dc3dSRussell King [CLNK_CTRL] = { 0x0084, 0x60, OMAP_DMA_REG_32BIT }, 6264a2dc3dSRussell King [CICR] = { 0x0088, 0x60, OMAP_DMA_REG_32BIT }, 6364a2dc3dSRussell King [CSR] = { 0x008c, 0x60, OMAP_DMA_REG_32BIT }, 6464a2dc3dSRussell King [CSDP] = { 0x0090, 0x60, OMAP_DMA_REG_32BIT }, 6564a2dc3dSRussell King [CEN] = { 0x0094, 0x60, OMAP_DMA_REG_32BIT }, 6664a2dc3dSRussell King [CFN] = { 0x0098, 0x60, OMAP_DMA_REG_32BIT }, 6764a2dc3dSRussell King [CSEI] = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT }, 6864a2dc3dSRussell King [CSFI] = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT }, 6964a2dc3dSRussell King [CDEI] = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT }, 7064a2dc3dSRussell King [CDFI] = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT }, 7164a2dc3dSRussell King [CSAC] = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT }, 7264a2dc3dSRussell King [CDAC] = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT }, 73f31cc962SG, Manjunath Kondaiah 74f31cc962SG, Manjunath Kondaiah /* Channel specific register offsets */ 7564a2dc3dSRussell King [CSSA] = { 0x009c, 0x60, OMAP_DMA_REG_32BIT }, 7664a2dc3dSRussell King [CDSA] = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT }, 7764a2dc3dSRussell King [CCEN] = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT }, 7864a2dc3dSRussell King [CCFN] = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT }, 7964a2dc3dSRussell King [COLOR] = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT }, 80f31cc962SG, Manjunath Kondaiah 81f31cc962SG, Manjunath Kondaiah /* OMAP4 specific registers */ 8264a2dc3dSRussell King [CDP] = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT }, 8364a2dc3dSRussell King [CNDP] = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT }, 8464a2dc3dSRussell King [CCDN] = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT }, 85f31cc962SG, Manjunath Kondaiah }; 86f31cc962SG, Manjunath Kondaiah 87f31cc962SG, Manjunath Kondaiah static void __iomem *dma_base; 88f31cc962SG, Manjunath Kondaiah static inline void dma_write(u32 val, int reg, int lch) 89f31cc962SG, Manjunath Kondaiah { 9064a2dc3dSRussell King void __iomem *addr = dma_base; 91f31cc962SG, Manjunath Kondaiah 9264a2dc3dSRussell King addr += reg_map[reg].offset; 9364a2dc3dSRussell King addr += reg_map[reg].stride * lch; 9464a2dc3dSRussell King 95edfaf05cSVictor Kamensky writel_relaxed(val, addr); 96f31cc962SG, Manjunath Kondaiah } 97f31cc962SG, Manjunath Kondaiah 98f31cc962SG, Manjunath Kondaiah static inline u32 dma_read(int reg, int lch) 99f31cc962SG, Manjunath Kondaiah { 10064a2dc3dSRussell King void __iomem *addr = dma_base; 101f31cc962SG, Manjunath Kondaiah 10264a2dc3dSRussell King addr += reg_map[reg].offset; 10364a2dc3dSRussell King addr += reg_map[reg].stride * lch; 10464a2dc3dSRussell King 105edfaf05cSVictor Kamensky return readl_relaxed(addr); 106f31cc962SG, Manjunath Kondaiah } 107f31cc962SG, Manjunath Kondaiah 108f31cc962SG, Manjunath Kondaiah static void omap2_clear_dma(int lch) 109f31cc962SG, Manjunath Kondaiah { 110ad0c381aSRussell King int i; 111f31cc962SG, Manjunath Kondaiah 112ad0c381aSRussell King for (i = CSDP; i <= dma_common_ch_end; i += 1) 113f31cc962SG, Manjunath Kondaiah dma_write(0, i, lch); 114f31cc962SG, Manjunath Kondaiah } 115f31cc962SG, Manjunath Kondaiah 116f31cc962SG, Manjunath Kondaiah static void omap2_show_dma_caps(void) 117f31cc962SG, Manjunath Kondaiah { 118f31cc962SG, Manjunath Kondaiah u8 revision = dma_read(REVISION, 0) & 0xff; 119f31cc962SG, Manjunath Kondaiah printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n", 120f31cc962SG, Manjunath Kondaiah revision >> 4, revision & 0xf); 121f31cc962SG, Manjunath Kondaiah } 122f31cc962SG, Manjunath Kondaiah 1230ef64986SRussell King static unsigned configure_dma_errata(void) 124f31cc962SG, Manjunath Kondaiah { 1250ef64986SRussell King unsigned errata = 0; 126f31cc962SG, Manjunath Kondaiah 127f31cc962SG, Manjunath Kondaiah /* 128f31cc962SG, Manjunath Kondaiah * Errata applicable for OMAP2430ES1.0 and all omap2420 129f31cc962SG, Manjunath Kondaiah * 130f31cc962SG, Manjunath Kondaiah * I. 131f31cc962SG, Manjunath Kondaiah * Erratum ID: Not Available 132f31cc962SG, Manjunath Kondaiah * Inter Frame DMA buffering issue DMA will wrongly 133f31cc962SG, Manjunath Kondaiah * buffer elements if packing and bursting is enabled. This might 134f31cc962SG, Manjunath Kondaiah * result in data gets stalled in FIFO at the end of the block. 135f31cc962SG, Manjunath Kondaiah * Workaround: DMA channels must have BUFFERING_DISABLED bit set to 136f31cc962SG, Manjunath Kondaiah * guarantee no data will stay in the DMA FIFO in case inter frame 137f31cc962SG, Manjunath Kondaiah * buffering occurs 138f31cc962SG, Manjunath Kondaiah * 139f31cc962SG, Manjunath Kondaiah * II. 140f31cc962SG, Manjunath Kondaiah * Erratum ID: Not Available 141f31cc962SG, Manjunath Kondaiah * DMA may hang when several channels are used in parallel 142f31cc962SG, Manjunath Kondaiah * In the following configuration, DMA channel hanging can occur: 143f31cc962SG, Manjunath Kondaiah * a. Channel i, hardware synchronized, is enabled 144f31cc962SG, Manjunath Kondaiah * b. Another channel (Channel x), software synchronized, is enabled. 145f31cc962SG, Manjunath Kondaiah * c. Channel i is disabled before end of transfer 146f31cc962SG, Manjunath Kondaiah * d. Channel i is reenabled. 147f31cc962SG, Manjunath Kondaiah * e. Steps 1 to 4 are repeated a certain number of times. 148f31cc962SG, Manjunath Kondaiah * f. A third channel (Channel y), software synchronized, is enabled. 149f31cc962SG, Manjunath Kondaiah * Channel x and Channel y may hang immediately after step 'f'. 150f31cc962SG, Manjunath Kondaiah * Workaround: 151f31cc962SG, Manjunath Kondaiah * For any channel used - make sure NextLCH_ID is set to the value j. 152f31cc962SG, Manjunath Kondaiah */ 153f31cc962SG, Manjunath Kondaiah if (cpu_is_omap2420() || (cpu_is_omap2430() && 154f31cc962SG, Manjunath Kondaiah (omap_type() == OMAP2430_REV_ES1_0))) { 155f31cc962SG, Manjunath Kondaiah 156f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING); 157f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS); 158f31cc962SG, Manjunath Kondaiah } 159f31cc962SG, Manjunath Kondaiah 160f31cc962SG, Manjunath Kondaiah /* 161f31cc962SG, Manjunath Kondaiah * Erratum ID: i378: OMAP2+: sDMA Channel is not disabled 162f31cc962SG, Manjunath Kondaiah * after a transaction error. 163f31cc962SG, Manjunath Kondaiah * Workaround: SW should explicitely disable the channel. 164f31cc962SG, Manjunath Kondaiah */ 165f31cc962SG, Manjunath Kondaiah if (cpu_class_is_omap2()) 166f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_i378); 167f31cc962SG, Manjunath Kondaiah 168f31cc962SG, Manjunath Kondaiah /* 169f31cc962SG, Manjunath Kondaiah * Erratum ID: i541: sDMA FIFO draining does not finish 170f31cc962SG, Manjunath Kondaiah * If sDMA channel is disabled on the fly, sDMA enters standby even 171f31cc962SG, Manjunath Kondaiah * through FIFO Drain is still in progress 172f31cc962SG, Manjunath Kondaiah * Workaround: Put sDMA in NoStandby more before a logical channel is 173f31cc962SG, Manjunath Kondaiah * disabled, then put it back to SmartStandby right after the channel 174f31cc962SG, Manjunath Kondaiah * finishes FIFO draining. 175f31cc962SG, Manjunath Kondaiah */ 176f31cc962SG, Manjunath Kondaiah if (cpu_is_omap34xx()) 177f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_i541); 178f31cc962SG, Manjunath Kondaiah 179f31cc962SG, Manjunath Kondaiah /* 180f31cc962SG, Manjunath Kondaiah * Erratum ID: i88 : Special programming model needed to disable DMA 181f31cc962SG, Manjunath Kondaiah * before end of block. 182f31cc962SG, Manjunath Kondaiah * Workaround: software must ensure that the DMA is configured in No 183f31cc962SG, Manjunath Kondaiah * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01") 184f31cc962SG, Manjunath Kondaiah */ 185f31cc962SG, Manjunath Kondaiah if (omap_type() == OMAP3430_REV_ES1_0) 186f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_i88); 187f31cc962SG, Manjunath Kondaiah 188f31cc962SG, Manjunath Kondaiah /* 189f31cc962SG, Manjunath Kondaiah * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is 190f31cc962SG, Manjunath Kondaiah * read before the DMA controller finished disabling the channel. 191f31cc962SG, Manjunath Kondaiah */ 192f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_3_3); 193f31cc962SG, Manjunath Kondaiah 194f31cc962SG, Manjunath Kondaiah /* 195f31cc962SG, Manjunath Kondaiah * Erratum ID: Not Available 196f31cc962SG, Manjunath Kondaiah * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared 197f31cc962SG, Manjunath Kondaiah * after secure sram context save and restore. 198f31cc962SG, Manjunath Kondaiah * Work around: Hence we need to manually clear those IRQs to avoid 199f31cc962SG, Manjunath Kondaiah * spurious interrupts. This affects only secure devices. 200f31cc962SG, Manjunath Kondaiah */ 201f31cc962SG, Manjunath Kondaiah if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) 202f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ROMCODE_BUG); 203f31cc962SG, Manjunath Kondaiah 204f31cc962SG, Manjunath Kondaiah return errata; 205f31cc962SG, Manjunath Kondaiah } 206f31cc962SG, Manjunath Kondaiah 207731ec4d8SPeter Ujfalusi static const struct dma_slave_map omap24xx_sdma_map[] = { 208731ec4d8SPeter Ujfalusi { "omap-gpmc", "rxtx", SDMA_FILTER_PARAM(4) }, 209731ec4d8SPeter Ujfalusi { "omap-aes", "tx", SDMA_FILTER_PARAM(9) }, 210731ec4d8SPeter Ujfalusi { "omap-aes", "rx", SDMA_FILTER_PARAM(10) }, 211731ec4d8SPeter Ujfalusi { "omap-sham", "rx", SDMA_FILTER_PARAM(13) }, 212731ec4d8SPeter Ujfalusi { "omap2_mcspi.2", "tx0", SDMA_FILTER_PARAM(15) }, 213731ec4d8SPeter Ujfalusi { "omap2_mcspi.2", "rx0", SDMA_FILTER_PARAM(16) }, 214731ec4d8SPeter Ujfalusi { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(17) }, 215731ec4d8SPeter Ujfalusi { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(18) }, 216731ec4d8SPeter Ujfalusi { "omap-mcbsp.4", "tx", SDMA_FILTER_PARAM(19) }, 217731ec4d8SPeter Ujfalusi { "omap-mcbsp.4", "rx", SDMA_FILTER_PARAM(20) }, 218731ec4d8SPeter Ujfalusi { "omap-mcbsp.5", "tx", SDMA_FILTER_PARAM(21) }, 219731ec4d8SPeter Ujfalusi { "omap-mcbsp.5", "rx", SDMA_FILTER_PARAM(22) }, 220731ec4d8SPeter Ujfalusi { "omap2_mcspi.2", "tx1", SDMA_FILTER_PARAM(23) }, 221731ec4d8SPeter Ujfalusi { "omap2_mcspi.2", "rx1", SDMA_FILTER_PARAM(24) }, 222731ec4d8SPeter Ujfalusi { "omap_i2c.1", "tx", SDMA_FILTER_PARAM(27) }, 223731ec4d8SPeter Ujfalusi { "omap_i2c.1", "rx", SDMA_FILTER_PARAM(28) }, 224731ec4d8SPeter Ujfalusi { "omap_i2c.2", "tx", SDMA_FILTER_PARAM(29) }, 225731ec4d8SPeter Ujfalusi { "omap_i2c.2", "rx", SDMA_FILTER_PARAM(30) }, 226731ec4d8SPeter Ujfalusi { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(31) }, 227731ec4d8SPeter Ujfalusi { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(32) }, 228731ec4d8SPeter Ujfalusi { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(33) }, 229731ec4d8SPeter Ujfalusi { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(34) }, 230731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "tx0", SDMA_FILTER_PARAM(35) }, 231731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "rx0", SDMA_FILTER_PARAM(36) }, 232731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "tx1", SDMA_FILTER_PARAM(37) }, 233731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "rx1", SDMA_FILTER_PARAM(38) }, 234731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "tx2", SDMA_FILTER_PARAM(39) }, 235731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "rx2", SDMA_FILTER_PARAM(40) }, 236731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "tx3", SDMA_FILTER_PARAM(41) }, 237731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "rx3", SDMA_FILTER_PARAM(42) }, 238731ec4d8SPeter Ujfalusi { "omap2_mcspi.1", "tx0", SDMA_FILTER_PARAM(43) }, 239731ec4d8SPeter Ujfalusi { "omap2_mcspi.1", "rx0", SDMA_FILTER_PARAM(44) }, 240731ec4d8SPeter Ujfalusi { "omap2_mcspi.1", "tx1", SDMA_FILTER_PARAM(45) }, 241731ec4d8SPeter Ujfalusi { "omap2_mcspi.1", "rx1", SDMA_FILTER_PARAM(46) }, 242731ec4d8SPeter Ujfalusi { "omap_hsmmc.1", "tx", SDMA_FILTER_PARAM(47) }, 243731ec4d8SPeter Ujfalusi { "omap_hsmmc.1", "rx", SDMA_FILTER_PARAM(48) }, 244731ec4d8SPeter Ujfalusi { "omap_uart.0", "tx", SDMA_FILTER_PARAM(49) }, 245731ec4d8SPeter Ujfalusi { "omap_uart.0", "rx", SDMA_FILTER_PARAM(50) }, 246731ec4d8SPeter Ujfalusi { "omap_uart.1", "tx", SDMA_FILTER_PARAM(51) }, 247731ec4d8SPeter Ujfalusi { "omap_uart.1", "rx", SDMA_FILTER_PARAM(52) }, 248731ec4d8SPeter Ujfalusi { "omap_uart.2", "tx", SDMA_FILTER_PARAM(53) }, 249731ec4d8SPeter Ujfalusi { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, 250731ec4d8SPeter Ujfalusi { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, 251731ec4d8SPeter Ujfalusi { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, 252868772d8SPeter Ujfalusi 253868772d8SPeter Ujfalusi /* external DMA requests when tusb6010 is used */ 254868772d8SPeter Ujfalusi { "musb-tusb", "dmareq0", SDMA_FILTER_PARAM(2) }, 255868772d8SPeter Ujfalusi { "musb-tusb", "dmareq1", SDMA_FILTER_PARAM(3) }, 256868772d8SPeter Ujfalusi { "musb-tusb", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */ 257868772d8SPeter Ujfalusi { "musb-tusb", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */ 258868772d8SPeter Ujfalusi { "musb-tusb", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */ 259868772d8SPeter Ujfalusi { "musb-tusb", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */ 260868772d8SPeter Ujfalusi }; 261868772d8SPeter Ujfalusi 262868772d8SPeter Ujfalusi static const struct dma_slave_map omap24xx_sdma_dt_map[] = { 263868772d8SPeter Ujfalusi /* external DMA requests when tusb6010 is used */ 264868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq0", SDMA_FILTER_PARAM(2) }, 265868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq1", SDMA_FILTER_PARAM(3) }, 266868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */ 267868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */ 268868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */ 269868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */ 270731ec4d8SPeter Ujfalusi }; 271731ec4d8SPeter Ujfalusi 272731ec4d8SPeter Ujfalusi static const struct dma_slave_map omap3xxx_sdma_map[] = { 273731ec4d8SPeter Ujfalusi { "omap-gpmc", "rxtx", SDMA_FILTER_PARAM(4) }, 274731ec4d8SPeter Ujfalusi { "omap2_mcspi.2", "tx0", SDMA_FILTER_PARAM(15) }, 275731ec4d8SPeter Ujfalusi { "omap2_mcspi.2", "rx0", SDMA_FILTER_PARAM(16) }, 276731ec4d8SPeter Ujfalusi { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(17) }, 277731ec4d8SPeter Ujfalusi { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(18) }, 278731ec4d8SPeter Ujfalusi { "omap-mcbsp.4", "tx", SDMA_FILTER_PARAM(19) }, 279731ec4d8SPeter Ujfalusi { "omap-mcbsp.4", "rx", SDMA_FILTER_PARAM(20) }, 280731ec4d8SPeter Ujfalusi { "omap-mcbsp.5", "tx", SDMA_FILTER_PARAM(21) }, 281731ec4d8SPeter Ujfalusi { "omap-mcbsp.5", "rx", SDMA_FILTER_PARAM(22) }, 282731ec4d8SPeter Ujfalusi { "omap2_mcspi.2", "tx1", SDMA_FILTER_PARAM(23) }, 283731ec4d8SPeter Ujfalusi { "omap2_mcspi.2", "rx1", SDMA_FILTER_PARAM(24) }, 284731ec4d8SPeter Ujfalusi { "omap_i2c.3", "tx", SDMA_FILTER_PARAM(25) }, 285731ec4d8SPeter Ujfalusi { "omap_i2c.3", "rx", SDMA_FILTER_PARAM(26) }, 286731ec4d8SPeter Ujfalusi { "omap_i2c.1", "tx", SDMA_FILTER_PARAM(27) }, 287731ec4d8SPeter Ujfalusi { "omap_i2c.1", "rx", SDMA_FILTER_PARAM(28) }, 288731ec4d8SPeter Ujfalusi { "omap_i2c.2", "tx", SDMA_FILTER_PARAM(29) }, 289731ec4d8SPeter Ujfalusi { "omap_i2c.2", "rx", SDMA_FILTER_PARAM(30) }, 290731ec4d8SPeter Ujfalusi { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(31) }, 291731ec4d8SPeter Ujfalusi { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(32) }, 292731ec4d8SPeter Ujfalusi { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(33) }, 293731ec4d8SPeter Ujfalusi { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(34) }, 294731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "tx0", SDMA_FILTER_PARAM(35) }, 295731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "rx0", SDMA_FILTER_PARAM(36) }, 296731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "tx1", SDMA_FILTER_PARAM(37) }, 297731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "rx1", SDMA_FILTER_PARAM(38) }, 298731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "tx2", SDMA_FILTER_PARAM(39) }, 299731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "rx2", SDMA_FILTER_PARAM(40) }, 300731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "tx3", SDMA_FILTER_PARAM(41) }, 301731ec4d8SPeter Ujfalusi { "omap2_mcspi.0", "rx3", SDMA_FILTER_PARAM(42) }, 302731ec4d8SPeter Ujfalusi { "omap2_mcspi.1", "tx0", SDMA_FILTER_PARAM(43) }, 303731ec4d8SPeter Ujfalusi { "omap2_mcspi.1", "rx0", SDMA_FILTER_PARAM(44) }, 304731ec4d8SPeter Ujfalusi { "omap2_mcspi.1", "tx1", SDMA_FILTER_PARAM(45) }, 305731ec4d8SPeter Ujfalusi { "omap2_mcspi.1", "rx1", SDMA_FILTER_PARAM(46) }, 306731ec4d8SPeter Ujfalusi { "omap_hsmmc.1", "tx", SDMA_FILTER_PARAM(47) }, 307731ec4d8SPeter Ujfalusi { "omap_hsmmc.1", "rx", SDMA_FILTER_PARAM(48) }, 308731ec4d8SPeter Ujfalusi { "omap_uart.0", "tx", SDMA_FILTER_PARAM(49) }, 309731ec4d8SPeter Ujfalusi { "omap_uart.0", "rx", SDMA_FILTER_PARAM(50) }, 310731ec4d8SPeter Ujfalusi { "omap_uart.1", "tx", SDMA_FILTER_PARAM(51) }, 311731ec4d8SPeter Ujfalusi { "omap_uart.1", "rx", SDMA_FILTER_PARAM(52) }, 312731ec4d8SPeter Ujfalusi { "omap_uart.2", "tx", SDMA_FILTER_PARAM(53) }, 313731ec4d8SPeter Ujfalusi { "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) }, 314731ec4d8SPeter Ujfalusi { "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) }, 315731ec4d8SPeter Ujfalusi { "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) }, 316731ec4d8SPeter Ujfalusi { "omap-aes", "tx", SDMA_FILTER_PARAM(65) }, 317731ec4d8SPeter Ujfalusi { "omap-aes", "rx", SDMA_FILTER_PARAM(66) }, 318731ec4d8SPeter Ujfalusi { "omap-sham", "rx", SDMA_FILTER_PARAM(69) }, 319731ec4d8SPeter Ujfalusi { "omap2_mcspi.3", "tx0", SDMA_FILTER_PARAM(70) }, 320731ec4d8SPeter Ujfalusi { "omap2_mcspi.3", "rx0", SDMA_FILTER_PARAM(71) }, 321731ec4d8SPeter Ujfalusi { "omap_hsmmc.2", "tx", SDMA_FILTER_PARAM(77) }, 322731ec4d8SPeter Ujfalusi { "omap_hsmmc.2", "rx", SDMA_FILTER_PARAM(78) }, 323731ec4d8SPeter Ujfalusi { "omap_uart.3", "tx", SDMA_FILTER_PARAM(81) }, 324731ec4d8SPeter Ujfalusi { "omap_uart.3", "rx", SDMA_FILTER_PARAM(82) }, 325731ec4d8SPeter Ujfalusi }; 326731ec4d8SPeter Ujfalusi 32734a378fcSRussell King static struct omap_system_dma_plat_info dma_plat_info __initdata = { 328596c471bSRussell King .reg_map = reg_map, 329596c471bSRussell King .channel_stride = 0x60, 33034a378fcSRussell King .show_dma_caps = omap2_show_dma_caps, 33134a378fcSRussell King .clear_dma = omap2_clear_dma, 33234a378fcSRussell King .dma_write = dma_write, 33334a378fcSRussell King .dma_read = dma_read, 33434a378fcSRussell King }; 33534a378fcSRussell King 336596c471bSRussell King static struct platform_device_info omap_dma_dev_info = { 337596c471bSRussell King .name = "omap-dma-engine", 338596c471bSRussell King .id = -1, 339596c471bSRussell King .dma_mask = DMA_BIT_MASK(32), 340596c471bSRussell King }; 341596c471bSRussell King 34259de3cf1SG, Manjunath Kondaiah /* One time initializations */ 34359de3cf1SG, Manjunath Kondaiah static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused) 34459de3cf1SG, Manjunath Kondaiah { 3453528c58eSKevin Hilman struct platform_device *pdev; 34634a378fcSRussell King struct omap_system_dma_plat_info p; 34734a378fcSRussell King struct omap_dma_dev_attr *d; 348f31cc962SG, Manjunath Kondaiah struct resource *mem; 34959de3cf1SG, Manjunath Kondaiah char *name = "omap_dma_system"; 35059de3cf1SG, Manjunath Kondaiah 35134a378fcSRussell King p = dma_plat_info; 35234a378fcSRussell King p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr; 35334a378fcSRussell King p.errata = configure_dma_errata(); 35459de3cf1SG, Manjunath Kondaiah 355731ec4d8SPeter Ujfalusi if (!of_have_populated_dt()) { 356731ec4d8SPeter Ujfalusi if (soc_is_omap24xx()) { 357731ec4d8SPeter Ujfalusi p.slave_map = omap24xx_sdma_map; 358731ec4d8SPeter Ujfalusi p.slavecnt = ARRAY_SIZE(omap24xx_sdma_map); 359731ec4d8SPeter Ujfalusi } else if (soc_is_omap34xx() || soc_is_omap3630()) { 360731ec4d8SPeter Ujfalusi p.slave_map = omap3xxx_sdma_map; 361731ec4d8SPeter Ujfalusi p.slavecnt = ARRAY_SIZE(omap3xxx_sdma_map); 362731ec4d8SPeter Ujfalusi } else { 363731ec4d8SPeter Ujfalusi pr_err("%s: The legacy DMA map is not provided!\n", 364731ec4d8SPeter Ujfalusi __func__); 365731ec4d8SPeter Ujfalusi return -ENODEV; 366731ec4d8SPeter Ujfalusi } 367868772d8SPeter Ujfalusi } else { 368868772d8SPeter Ujfalusi if (soc_is_omap24xx()) { 369868772d8SPeter Ujfalusi /* DMA slave map for drivers not yet converted to DT */ 370868772d8SPeter Ujfalusi p.slave_map = omap24xx_sdma_dt_map; 371868772d8SPeter Ujfalusi p.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map); 372868772d8SPeter Ujfalusi } 373731ec4d8SPeter Ujfalusi } 374731ec4d8SPeter Ujfalusi 37534a378fcSRussell King pdev = omap_device_build(name, 0, oh, &p, sizeof(p)); 3763528c58eSKevin Hilman if (IS_ERR(pdev)) { 37725985edcSLucas De Marchi pr_err("%s: Can't build omap_device for %s:%s.\n", 37859de3cf1SG, Manjunath Kondaiah __func__, name, oh->name); 3793528c58eSKevin Hilman return PTR_ERR(pdev); 38059de3cf1SG, Manjunath Kondaiah } 38159de3cf1SG, Manjunath Kondaiah 382596c471bSRussell King omap_dma_dev_info.res = pdev->resource; 383596c471bSRussell King omap_dma_dev_info.num_res = pdev->num_resources; 384596c471bSRussell King 3853528c58eSKevin Hilman mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 386f31cc962SG, Manjunath Kondaiah if (!mem) { 3873528c58eSKevin Hilman dev_err(&pdev->dev, "%s: no mem resource\n", __func__); 388f31cc962SG, Manjunath Kondaiah return -EINVAL; 389f31cc962SG, Manjunath Kondaiah } 390596c471bSRussell King 391f31cc962SG, Manjunath Kondaiah dma_base = ioremap(mem->start, resource_size(mem)); 392f31cc962SG, Manjunath Kondaiah if (!dma_base) { 3933528c58eSKevin Hilman dev_err(&pdev->dev, "%s: ioremap fail\n", __func__); 394f31cc962SG, Manjunath Kondaiah return -ENOMEM; 395f31cc962SG, Manjunath Kondaiah } 396f31cc962SG, Manjunath Kondaiah 397f31cc962SG, Manjunath Kondaiah d = oh->dev_attr; 398f6d5e079SR Sricharan 39982809601STony Lindgren if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) 40082809601STony Lindgren d->dev_caps |= HS_CHANNELS_RESERVED; 40182809601STony Lindgren 40276be4a54SNishanth Menon if (platform_get_irq_byname(pdev, "0") < 0) 40376be4a54SNishanth Menon d->dev_caps |= DMA_ENGINE_HANDLE_IRQ; 40476be4a54SNishanth Menon 405f6d5e079SR Sricharan /* Check the capabilities register for descriptor loading feature */ 406f6d5e079SR Sricharan if (dma_read(CAPS_0, 0) & DMA_HAS_DESCRIPTOR_CAPS) 407f6d5e079SR Sricharan dma_common_ch_end = CCDN; 408f6d5e079SR Sricharan else 409f6d5e079SR Sricharan dma_common_ch_end = CCFN; 410f6d5e079SR Sricharan 41159de3cf1SG, Manjunath Kondaiah return 0; 41259de3cf1SG, Manjunath Kondaiah } 41359de3cf1SG, Manjunath Kondaiah 41459de3cf1SG, Manjunath Kondaiah static int __init omap2_system_dma_init(void) 41559de3cf1SG, Manjunath Kondaiah { 416be1f9481STony Lindgren struct platform_device *pdev; 417be1f9481STony Lindgren int res; 418be1f9481STony Lindgren 419be1f9481STony Lindgren res = omap_hwmod_for_each_by_class("dma", 42059de3cf1SG, Manjunath Kondaiah omap2_system_dma_init_dev, NULL); 421be1f9481STony Lindgren if (res) 422be1f9481STony Lindgren return res; 423be1f9481STony Lindgren 4248d30662aSJon Hunter if (of_have_populated_dt()) 4258d30662aSJon Hunter return res; 4268d30662aSJon Hunter 427be1f9481STony Lindgren pdev = platform_device_register_full(&omap_dma_dev_info); 428be1f9481STony Lindgren if (IS_ERR(pdev)) 429be1f9481STony Lindgren return PTR_ERR(pdev); 430be1f9481STony Lindgren 431be1f9481STony Lindgren return res; 43259de3cf1SG, Manjunath Kondaiah } 433b76c8b19STony Lindgren omap_arch_initcall(omap2_system_dma_init); 434