1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 259de3cf1SG, Manjunath Kondaiah /* 359de3cf1SG, Manjunath Kondaiah * OMAP2+ DMA driver 459de3cf1SG, Manjunath Kondaiah * 559de3cf1SG, Manjunath Kondaiah * Copyright (C) 2003 - 2008 Nokia Corporation 659de3cf1SG, Manjunath Kondaiah * Author: Juha Yrjölä <juha.yrjola@nokia.com> 759de3cf1SG, Manjunath Kondaiah * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> 859de3cf1SG, Manjunath Kondaiah * Graphics DMA and LCD DMA graphics tranformations 959de3cf1SG, Manjunath Kondaiah * by Imre Deak <imre.deak@nokia.com> 1059de3cf1SG, Manjunath Kondaiah * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc. 1159de3cf1SG, Manjunath Kondaiah * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. 1259de3cf1SG, Manjunath Kondaiah * 1359de3cf1SG, Manjunath Kondaiah * Copyright (C) 2009 Texas Instruments 1459de3cf1SG, Manjunath Kondaiah * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> 1559de3cf1SG, Manjunath Kondaiah * 1659de3cf1SG, Manjunath Kondaiah * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 1759de3cf1SG, Manjunath Kondaiah * Converted DMA library into platform driver 1859de3cf1SG, Manjunath Kondaiah * - G, Manjunath Kondaiah <manjugk@ti.com> 1959de3cf1SG, Manjunath Kondaiah */ 2059de3cf1SG, Manjunath Kondaiah 2159de3cf1SG, Manjunath Kondaiah #include <linux/err.h> 2259de3cf1SG, Manjunath Kondaiah #include <linux/io.h> 2359de3cf1SG, Manjunath Kondaiah #include <linux/slab.h> 2459de3cf1SG, Manjunath Kondaiah #include <linux/module.h> 2559de3cf1SG, Manjunath Kondaiah #include <linux/init.h> 2659de3cf1SG, Manjunath Kondaiah #include <linux/device.h> 27be1f9481STony Lindgren #include <linux/dma-mapping.h> 28731ec4d8SPeter Ujfalusi #include <linux/dmaengine.h> 298d30662aSJon Hunter #include <linux/of.h> 3045c3eb7dSTony Lindgren #include <linux/omap-dma.h> 3159de3cf1SG, Manjunath Kondaiah 32e4c060dbSTony Lindgren #include "soc.h" 33f31cc962SG, Manjunath Kondaiah 3464a2dc3dSRussell King static const struct omap_dma_reg reg_map[] = { 3564a2dc3dSRussell King [REVISION] = { 0x0000, 0x00, OMAP_DMA_REG_32BIT }, 3664a2dc3dSRussell King [GCR] = { 0x0078, 0x00, OMAP_DMA_REG_32BIT }, 3764a2dc3dSRussell King [IRQSTATUS_L0] = { 0x0008, 0x00, OMAP_DMA_REG_32BIT }, 3864a2dc3dSRussell King [IRQSTATUS_L1] = { 0x000c, 0x00, OMAP_DMA_REG_32BIT }, 3964a2dc3dSRussell King [IRQSTATUS_L2] = { 0x0010, 0x00, OMAP_DMA_REG_32BIT }, 4064a2dc3dSRussell King [IRQSTATUS_L3] = { 0x0014, 0x00, OMAP_DMA_REG_32BIT }, 4164a2dc3dSRussell King [IRQENABLE_L0] = { 0x0018, 0x00, OMAP_DMA_REG_32BIT }, 4264a2dc3dSRussell King [IRQENABLE_L1] = { 0x001c, 0x00, OMAP_DMA_REG_32BIT }, 4364a2dc3dSRussell King [IRQENABLE_L2] = { 0x0020, 0x00, OMAP_DMA_REG_32BIT }, 4464a2dc3dSRussell King [IRQENABLE_L3] = { 0x0024, 0x00, OMAP_DMA_REG_32BIT }, 4564a2dc3dSRussell King [SYSSTATUS] = { 0x0028, 0x00, OMAP_DMA_REG_32BIT }, 4664a2dc3dSRussell King [OCP_SYSCONFIG] = { 0x002c, 0x00, OMAP_DMA_REG_32BIT }, 4764a2dc3dSRussell King [CAPS_0] = { 0x0064, 0x00, OMAP_DMA_REG_32BIT }, 4864a2dc3dSRussell King [CAPS_2] = { 0x006c, 0x00, OMAP_DMA_REG_32BIT }, 4964a2dc3dSRussell King [CAPS_3] = { 0x0070, 0x00, OMAP_DMA_REG_32BIT }, 5064a2dc3dSRussell King [CAPS_4] = { 0x0074, 0x00, OMAP_DMA_REG_32BIT }, 51f31cc962SG, Manjunath Kondaiah 52f31cc962SG, Manjunath Kondaiah /* Common register offsets */ 5364a2dc3dSRussell King [CCR] = { 0x0080, 0x60, OMAP_DMA_REG_32BIT }, 5464a2dc3dSRussell King [CLNK_CTRL] = { 0x0084, 0x60, OMAP_DMA_REG_32BIT }, 5564a2dc3dSRussell King [CICR] = { 0x0088, 0x60, OMAP_DMA_REG_32BIT }, 5664a2dc3dSRussell King [CSR] = { 0x008c, 0x60, OMAP_DMA_REG_32BIT }, 5764a2dc3dSRussell King [CSDP] = { 0x0090, 0x60, OMAP_DMA_REG_32BIT }, 5864a2dc3dSRussell King [CEN] = { 0x0094, 0x60, OMAP_DMA_REG_32BIT }, 5964a2dc3dSRussell King [CFN] = { 0x0098, 0x60, OMAP_DMA_REG_32BIT }, 6064a2dc3dSRussell King [CSEI] = { 0x00a4, 0x60, OMAP_DMA_REG_32BIT }, 6164a2dc3dSRussell King [CSFI] = { 0x00a8, 0x60, OMAP_DMA_REG_32BIT }, 6264a2dc3dSRussell King [CDEI] = { 0x00ac, 0x60, OMAP_DMA_REG_32BIT }, 6364a2dc3dSRussell King [CDFI] = { 0x00b0, 0x60, OMAP_DMA_REG_32BIT }, 6464a2dc3dSRussell King [CSAC] = { 0x00b4, 0x60, OMAP_DMA_REG_32BIT }, 6564a2dc3dSRussell King [CDAC] = { 0x00b8, 0x60, OMAP_DMA_REG_32BIT }, 66f31cc962SG, Manjunath Kondaiah 67f31cc962SG, Manjunath Kondaiah /* Channel specific register offsets */ 6864a2dc3dSRussell King [CSSA] = { 0x009c, 0x60, OMAP_DMA_REG_32BIT }, 6964a2dc3dSRussell King [CDSA] = { 0x00a0, 0x60, OMAP_DMA_REG_32BIT }, 7064a2dc3dSRussell King [CCEN] = { 0x00bc, 0x60, OMAP_DMA_REG_32BIT }, 7164a2dc3dSRussell King [CCFN] = { 0x00c0, 0x60, OMAP_DMA_REG_32BIT }, 7264a2dc3dSRussell King [COLOR] = { 0x00c4, 0x60, OMAP_DMA_REG_32BIT }, 73f31cc962SG, Manjunath Kondaiah 74f31cc962SG, Manjunath Kondaiah /* OMAP4 specific registers */ 7564a2dc3dSRussell King [CDP] = { 0x00d0, 0x60, OMAP_DMA_REG_32BIT }, 7664a2dc3dSRussell King [CNDP] = { 0x00d4, 0x60, OMAP_DMA_REG_32BIT }, 7764a2dc3dSRussell King [CCDN] = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT }, 78f31cc962SG, Manjunath Kondaiah }; 79f31cc962SG, Manjunath Kondaiah 800ef64986SRussell King static unsigned configure_dma_errata(void) 81f31cc962SG, Manjunath Kondaiah { 820ef64986SRussell King unsigned errata = 0; 83f31cc962SG, Manjunath Kondaiah 84f31cc962SG, Manjunath Kondaiah /* 85f31cc962SG, Manjunath Kondaiah * Errata applicable for OMAP2430ES1.0 and all omap2420 86f31cc962SG, Manjunath Kondaiah * 87f31cc962SG, Manjunath Kondaiah * I. 88f31cc962SG, Manjunath Kondaiah * Erratum ID: Not Available 89f31cc962SG, Manjunath Kondaiah * Inter Frame DMA buffering issue DMA will wrongly 90f31cc962SG, Manjunath Kondaiah * buffer elements if packing and bursting is enabled. This might 91f31cc962SG, Manjunath Kondaiah * result in data gets stalled in FIFO at the end of the block. 92f31cc962SG, Manjunath Kondaiah * Workaround: DMA channels must have BUFFERING_DISABLED bit set to 93f31cc962SG, Manjunath Kondaiah * guarantee no data will stay in the DMA FIFO in case inter frame 94f31cc962SG, Manjunath Kondaiah * buffering occurs 95f31cc962SG, Manjunath Kondaiah * 96f31cc962SG, Manjunath Kondaiah * II. 97f31cc962SG, Manjunath Kondaiah * Erratum ID: Not Available 98f31cc962SG, Manjunath Kondaiah * DMA may hang when several channels are used in parallel 99f31cc962SG, Manjunath Kondaiah * In the following configuration, DMA channel hanging can occur: 100f31cc962SG, Manjunath Kondaiah * a. Channel i, hardware synchronized, is enabled 101f31cc962SG, Manjunath Kondaiah * b. Another channel (Channel x), software synchronized, is enabled. 102f31cc962SG, Manjunath Kondaiah * c. Channel i is disabled before end of transfer 103f31cc962SG, Manjunath Kondaiah * d. Channel i is reenabled. 104f31cc962SG, Manjunath Kondaiah * e. Steps 1 to 4 are repeated a certain number of times. 105f31cc962SG, Manjunath Kondaiah * f. A third channel (Channel y), software synchronized, is enabled. 106f31cc962SG, Manjunath Kondaiah * Channel x and Channel y may hang immediately after step 'f'. 107f31cc962SG, Manjunath Kondaiah * Workaround: 108f31cc962SG, Manjunath Kondaiah * For any channel used - make sure NextLCH_ID is set to the value j. 109f31cc962SG, Manjunath Kondaiah */ 110f31cc962SG, Manjunath Kondaiah if (cpu_is_omap2420() || (cpu_is_omap2430() && 111f31cc962SG, Manjunath Kondaiah (omap_type() == OMAP2430_REV_ES1_0))) { 112f31cc962SG, Manjunath Kondaiah 113f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_IFRAME_BUFFERING); 114f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_PARALLEL_CHANNELS); 115f31cc962SG, Manjunath Kondaiah } 116f31cc962SG, Manjunath Kondaiah 117f31cc962SG, Manjunath Kondaiah /* 118f31cc962SG, Manjunath Kondaiah * Erratum ID: i378: OMAP2+: sDMA Channel is not disabled 119f31cc962SG, Manjunath Kondaiah * after a transaction error. 120f31cc962SG, Manjunath Kondaiah * Workaround: SW should explicitely disable the channel. 121f31cc962SG, Manjunath Kondaiah */ 122f31cc962SG, Manjunath Kondaiah if (cpu_class_is_omap2()) 123f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_i378); 124f31cc962SG, Manjunath Kondaiah 125f31cc962SG, Manjunath Kondaiah /* 126f31cc962SG, Manjunath Kondaiah * Erratum ID: i541: sDMA FIFO draining does not finish 127f31cc962SG, Manjunath Kondaiah * If sDMA channel is disabled on the fly, sDMA enters standby even 128f31cc962SG, Manjunath Kondaiah * through FIFO Drain is still in progress 129f31cc962SG, Manjunath Kondaiah * Workaround: Put sDMA in NoStandby more before a logical channel is 130f31cc962SG, Manjunath Kondaiah * disabled, then put it back to SmartStandby right after the channel 131f31cc962SG, Manjunath Kondaiah * finishes FIFO draining. 132f31cc962SG, Manjunath Kondaiah */ 133f31cc962SG, Manjunath Kondaiah if (cpu_is_omap34xx()) 134f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_i541); 135f31cc962SG, Manjunath Kondaiah 136f31cc962SG, Manjunath Kondaiah /* 137f31cc962SG, Manjunath Kondaiah * Erratum ID: i88 : Special programming model needed to disable DMA 138f31cc962SG, Manjunath Kondaiah * before end of block. 139f31cc962SG, Manjunath Kondaiah * Workaround: software must ensure that the DMA is configured in No 140f31cc962SG, Manjunath Kondaiah * Standby mode(DMAx_OCP_SYSCONFIG.MIDLEMODE = "01") 141f31cc962SG, Manjunath Kondaiah */ 142f31cc962SG, Manjunath Kondaiah if (omap_type() == OMAP3430_REV_ES1_0) 143f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_i88); 144f31cc962SG, Manjunath Kondaiah 145f31cc962SG, Manjunath Kondaiah /* 146f31cc962SG, Manjunath Kondaiah * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is 147f31cc962SG, Manjunath Kondaiah * read before the DMA controller finished disabling the channel. 148f31cc962SG, Manjunath Kondaiah */ 149f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ERRATA_3_3); 150f31cc962SG, Manjunath Kondaiah 151f31cc962SG, Manjunath Kondaiah /* 152f31cc962SG, Manjunath Kondaiah * Erratum ID: Not Available 153f31cc962SG, Manjunath Kondaiah * A bug in ROM code leaves IRQ status for channels 0 and 1 uncleared 154f31cc962SG, Manjunath Kondaiah * after secure sram context save and restore. 155f31cc962SG, Manjunath Kondaiah * Work around: Hence we need to manually clear those IRQs to avoid 156f31cc962SG, Manjunath Kondaiah * spurious interrupts. This affects only secure devices. 157f31cc962SG, Manjunath Kondaiah */ 158f31cc962SG, Manjunath Kondaiah if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) 159f31cc962SG, Manjunath Kondaiah SET_DMA_ERRATA(DMA_ROMCODE_BUG); 160f31cc962SG, Manjunath Kondaiah 161f31cc962SG, Manjunath Kondaiah return errata; 162f31cc962SG, Manjunath Kondaiah } 163f31cc962SG, Manjunath Kondaiah 164868772d8SPeter Ujfalusi static const struct dma_slave_map omap24xx_sdma_dt_map[] = { 165868772d8SPeter Ujfalusi /* external DMA requests when tusb6010 is used */ 166868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq0", SDMA_FILTER_PARAM(2) }, 167868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq1", SDMA_FILTER_PARAM(3) }, 168868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */ 169868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */ 170868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */ 171868772d8SPeter Ujfalusi { "musb-hdrc.1.auto", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */ 172731ec4d8SPeter Ujfalusi }; 173731ec4d8SPeter Ujfalusi 174c6797bcdSTony Lindgren static struct omap_dma_dev_attr dma_attr = { 175c6797bcdSTony Lindgren .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY | 176c6797bcdSTony Lindgren IS_CSSA_32 | IS_CDSA_32, 177c6797bcdSTony Lindgren .lch_count = 32, 178c6797bcdSTony Lindgren }; 179c6797bcdSTony Lindgren 180211010aeSTony Lindgren struct omap_system_dma_plat_info dma_plat_info = { 181596c471bSRussell King .reg_map = reg_map, 182596c471bSRussell King .channel_stride = 0x60, 183c6797bcdSTony Lindgren .dma_attr = &dma_attr, 184596c471bSRussell King }; 185596c471bSRussell King 18659de3cf1SG, Manjunath Kondaiah /* One time initializations */ 187*82f12e64STony Lindgren static int __init omap2_system_dma_init(void) 18859de3cf1SG, Manjunath Kondaiah { 189c6797bcdSTony Lindgren dma_plat_info.errata = configure_dma_errata(); 19059de3cf1SG, Manjunath Kondaiah 191868772d8SPeter Ujfalusi if (soc_is_omap24xx()) { 192868772d8SPeter Ujfalusi /* DMA slave map for drivers not yet converted to DT */ 193c6797bcdSTony Lindgren dma_plat_info.slave_map = omap24xx_sdma_dt_map; 194c6797bcdSTony Lindgren dma_plat_info.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map); 195868772d8SPeter Ujfalusi } 196731ec4d8SPeter Ujfalusi 197c6797bcdSTony Lindgren if (!soc_is_omap242x()) 198c6797bcdSTony Lindgren dma_attr.dev_caps |= IS_RW_PRIORITY; 199c6797bcdSTony Lindgren 200c6797bcdSTony Lindgren if (soc_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP)) 201c6797bcdSTony Lindgren dma_attr.dev_caps |= HS_CHANNELS_RESERVED; 202c6797bcdSTony Lindgren 20359de3cf1SG, Manjunath Kondaiah return 0; 20459de3cf1SG, Manjunath Kondaiah } 205b76c8b19STony Lindgren omap_arch_initcall(omap2_system_dma_init); 206