18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * OMAP1/OMAP7xx - specific DMA driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2003 - 2008 Nokia Corporation 68c2ecf20Sopenharmony_ci * Author: Juha Yrjölä <juha.yrjola@nokia.com> 78c2ecf20Sopenharmony_ci * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com> 88c2ecf20Sopenharmony_ci * Graphics DMA and LCD DMA graphics tranformations 98c2ecf20Sopenharmony_ci * by Imre Deak <imre.deak@nokia.com> 108c2ecf20Sopenharmony_ci * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc. 118c2ecf20Sopenharmony_ci * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/ 148c2ecf20Sopenharmony_ci * Converted DMA library into platform driver 158c2ecf20Sopenharmony_ci * - G, Manjunath Kondaiah <manjugk@ti.com> 168c2ecf20Sopenharmony_ci */ 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <linux/err.h> 198c2ecf20Sopenharmony_ci#include <linux/slab.h> 208c2ecf20Sopenharmony_ci#include <linux/module.h> 218c2ecf20Sopenharmony_ci#include <linux/init.h> 228c2ecf20Sopenharmony_ci#include <linux/device.h> 238c2ecf20Sopenharmony_ci#include <linux/io.h> 248c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 258c2ecf20Sopenharmony_ci#include <linux/dmaengine.h> 268c2ecf20Sopenharmony_ci#include <linux/omap-dma.h> 278c2ecf20Sopenharmony_ci#include <mach/tc.h> 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include "soc.h" 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#define OMAP1_DMA_BASE (0xfffed800) 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_cistatic u32 enable_1510_mode; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic const struct omap_dma_reg reg_map[] = { 368c2ecf20Sopenharmony_ci [GCR] = { 0x0400, 0x00, OMAP_DMA_REG_16BIT }, 378c2ecf20Sopenharmony_ci [GSCR] = { 0x0404, 0x00, OMAP_DMA_REG_16BIT }, 388c2ecf20Sopenharmony_ci [GRST1] = { 0x0408, 0x00, OMAP_DMA_REG_16BIT }, 398c2ecf20Sopenharmony_ci [HW_ID] = { 0x0442, 0x00, OMAP_DMA_REG_16BIT }, 408c2ecf20Sopenharmony_ci [PCH2_ID] = { 0x0444, 0x00, OMAP_DMA_REG_16BIT }, 418c2ecf20Sopenharmony_ci [PCH0_ID] = { 0x0446, 0x00, OMAP_DMA_REG_16BIT }, 428c2ecf20Sopenharmony_ci [PCH1_ID] = { 0x0448, 0x00, OMAP_DMA_REG_16BIT }, 438c2ecf20Sopenharmony_ci [PCHG_ID] = { 0x044a, 0x00, OMAP_DMA_REG_16BIT }, 448c2ecf20Sopenharmony_ci [PCHD_ID] = { 0x044c, 0x00, OMAP_DMA_REG_16BIT }, 458c2ecf20Sopenharmony_ci [CAPS_0] = { 0x044e, 0x00, OMAP_DMA_REG_2X16BIT }, 468c2ecf20Sopenharmony_ci [CAPS_1] = { 0x0452, 0x00, OMAP_DMA_REG_2X16BIT }, 478c2ecf20Sopenharmony_ci [CAPS_2] = { 0x0456, 0x00, OMAP_DMA_REG_16BIT }, 488c2ecf20Sopenharmony_ci [CAPS_3] = { 0x0458, 0x00, OMAP_DMA_REG_16BIT }, 498c2ecf20Sopenharmony_ci [CAPS_4] = { 0x045a, 0x00, OMAP_DMA_REG_16BIT }, 508c2ecf20Sopenharmony_ci [PCH2_SR] = { 0x0460, 0x00, OMAP_DMA_REG_16BIT }, 518c2ecf20Sopenharmony_ci [PCH0_SR] = { 0x0480, 0x00, OMAP_DMA_REG_16BIT }, 528c2ecf20Sopenharmony_ci [PCH1_SR] = { 0x0482, 0x00, OMAP_DMA_REG_16BIT }, 538c2ecf20Sopenharmony_ci [PCHD_SR] = { 0x04c0, 0x00, OMAP_DMA_REG_16BIT }, 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci /* Common Registers */ 568c2ecf20Sopenharmony_ci [CSDP] = { 0x0000, 0x40, OMAP_DMA_REG_16BIT }, 578c2ecf20Sopenharmony_ci [CCR] = { 0x0002, 0x40, OMAP_DMA_REG_16BIT }, 588c2ecf20Sopenharmony_ci [CICR] = { 0x0004, 0x40, OMAP_DMA_REG_16BIT }, 598c2ecf20Sopenharmony_ci [CSR] = { 0x0006, 0x40, OMAP_DMA_REG_16BIT }, 608c2ecf20Sopenharmony_ci [CEN] = { 0x0010, 0x40, OMAP_DMA_REG_16BIT }, 618c2ecf20Sopenharmony_ci [CFN] = { 0x0012, 0x40, OMAP_DMA_REG_16BIT }, 628c2ecf20Sopenharmony_ci [CSFI] = { 0x0014, 0x40, OMAP_DMA_REG_16BIT }, 638c2ecf20Sopenharmony_ci [CSEI] = { 0x0016, 0x40, OMAP_DMA_REG_16BIT }, 648c2ecf20Sopenharmony_ci [CPC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT }, /* 15xx only */ 658c2ecf20Sopenharmony_ci [CSAC] = { 0x0018, 0x40, OMAP_DMA_REG_16BIT }, 668c2ecf20Sopenharmony_ci [CDAC] = { 0x001a, 0x40, OMAP_DMA_REG_16BIT }, 678c2ecf20Sopenharmony_ci [CDEI] = { 0x001c, 0x40, OMAP_DMA_REG_16BIT }, 688c2ecf20Sopenharmony_ci [CDFI] = { 0x001e, 0x40, OMAP_DMA_REG_16BIT }, 698c2ecf20Sopenharmony_ci [CLNK_CTRL] = { 0x0028, 0x40, OMAP_DMA_REG_16BIT }, 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci /* Channel specific register offsets */ 728c2ecf20Sopenharmony_ci [CSSA] = { 0x0008, 0x40, OMAP_DMA_REG_2X16BIT }, 738c2ecf20Sopenharmony_ci [CDSA] = { 0x000c, 0x40, OMAP_DMA_REG_2X16BIT }, 748c2ecf20Sopenharmony_ci [COLOR] = { 0x0020, 0x40, OMAP_DMA_REG_2X16BIT }, 758c2ecf20Sopenharmony_ci [CCR2] = { 0x0024, 0x40, OMAP_DMA_REG_16BIT }, 768c2ecf20Sopenharmony_ci [LCH_CTRL] = { 0x002a, 0x40, OMAP_DMA_REG_16BIT }, 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_cistatic struct resource res[] __initdata = { 808c2ecf20Sopenharmony_ci [0] = { 818c2ecf20Sopenharmony_ci .start = OMAP1_DMA_BASE, 828c2ecf20Sopenharmony_ci .end = OMAP1_DMA_BASE + SZ_2K - 1, 838c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 848c2ecf20Sopenharmony_ci }, 858c2ecf20Sopenharmony_ci [1] = { 868c2ecf20Sopenharmony_ci .name = "0", 878c2ecf20Sopenharmony_ci .start = INT_DMA_CH0_6, 888c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 898c2ecf20Sopenharmony_ci }, 908c2ecf20Sopenharmony_ci [2] = { 918c2ecf20Sopenharmony_ci .name = "1", 928c2ecf20Sopenharmony_ci .start = INT_DMA_CH1_7, 938c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 948c2ecf20Sopenharmony_ci }, 958c2ecf20Sopenharmony_ci [3] = { 968c2ecf20Sopenharmony_ci .name = "2", 978c2ecf20Sopenharmony_ci .start = INT_DMA_CH2_8, 988c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 998c2ecf20Sopenharmony_ci }, 1008c2ecf20Sopenharmony_ci [4] = { 1018c2ecf20Sopenharmony_ci .name = "3", 1028c2ecf20Sopenharmony_ci .start = INT_DMA_CH3, 1038c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1048c2ecf20Sopenharmony_ci }, 1058c2ecf20Sopenharmony_ci [5] = { 1068c2ecf20Sopenharmony_ci .name = "4", 1078c2ecf20Sopenharmony_ci .start = INT_DMA_CH4, 1088c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1098c2ecf20Sopenharmony_ci }, 1108c2ecf20Sopenharmony_ci [6] = { 1118c2ecf20Sopenharmony_ci .name = "5", 1128c2ecf20Sopenharmony_ci .start = INT_DMA_CH5, 1138c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1148c2ecf20Sopenharmony_ci }, 1158c2ecf20Sopenharmony_ci /* Handled in lcd_dma.c */ 1168c2ecf20Sopenharmony_ci [7] = { 1178c2ecf20Sopenharmony_ci .name = "6", 1188c2ecf20Sopenharmony_ci .start = INT_1610_DMA_CH6, 1198c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1208c2ecf20Sopenharmony_ci }, 1218c2ecf20Sopenharmony_ci /* irq's for omap16xx and omap7xx */ 1228c2ecf20Sopenharmony_ci [8] = { 1238c2ecf20Sopenharmony_ci .name = "7", 1248c2ecf20Sopenharmony_ci .start = INT_1610_DMA_CH7, 1258c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1268c2ecf20Sopenharmony_ci }, 1278c2ecf20Sopenharmony_ci [9] = { 1288c2ecf20Sopenharmony_ci .name = "8", 1298c2ecf20Sopenharmony_ci .start = INT_1610_DMA_CH8, 1308c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1318c2ecf20Sopenharmony_ci }, 1328c2ecf20Sopenharmony_ci [10] = { 1338c2ecf20Sopenharmony_ci .name = "9", 1348c2ecf20Sopenharmony_ci .start = INT_1610_DMA_CH9, 1358c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1368c2ecf20Sopenharmony_ci }, 1378c2ecf20Sopenharmony_ci [11] = { 1388c2ecf20Sopenharmony_ci .name = "10", 1398c2ecf20Sopenharmony_ci .start = INT_1610_DMA_CH10, 1408c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1418c2ecf20Sopenharmony_ci }, 1428c2ecf20Sopenharmony_ci [12] = { 1438c2ecf20Sopenharmony_ci .name = "11", 1448c2ecf20Sopenharmony_ci .start = INT_1610_DMA_CH11, 1458c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1468c2ecf20Sopenharmony_ci }, 1478c2ecf20Sopenharmony_ci [13] = { 1488c2ecf20Sopenharmony_ci .name = "12", 1498c2ecf20Sopenharmony_ci .start = INT_1610_DMA_CH12, 1508c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1518c2ecf20Sopenharmony_ci }, 1528c2ecf20Sopenharmony_ci [14] = { 1538c2ecf20Sopenharmony_ci .name = "13", 1548c2ecf20Sopenharmony_ci .start = INT_1610_DMA_CH13, 1558c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1568c2ecf20Sopenharmony_ci }, 1578c2ecf20Sopenharmony_ci [15] = { 1588c2ecf20Sopenharmony_ci .name = "14", 1598c2ecf20Sopenharmony_ci .start = INT_1610_DMA_CH14, 1608c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1618c2ecf20Sopenharmony_ci }, 1628c2ecf20Sopenharmony_ci [16] = { 1638c2ecf20Sopenharmony_ci .name = "15", 1648c2ecf20Sopenharmony_ci .start = INT_1610_DMA_CH15, 1658c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1668c2ecf20Sopenharmony_ci }, 1678c2ecf20Sopenharmony_ci [17] = { 1688c2ecf20Sopenharmony_ci .name = "16", 1698c2ecf20Sopenharmony_ci .start = INT_DMA_LCD, 1708c2ecf20Sopenharmony_ci .flags = IORESOURCE_IRQ, 1718c2ecf20Sopenharmony_ci }, 1728c2ecf20Sopenharmony_ci}; 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_cistatic void __iomem *dma_base; 1758c2ecf20Sopenharmony_cistatic inline void dma_write(u32 val, int reg, int lch) 1768c2ecf20Sopenharmony_ci{ 1778c2ecf20Sopenharmony_ci void __iomem *addr = dma_base; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci addr += reg_map[reg].offset; 1808c2ecf20Sopenharmony_ci addr += reg_map[reg].stride * lch; 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci __raw_writew(val, addr); 1838c2ecf20Sopenharmony_ci if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT) 1848c2ecf20Sopenharmony_ci __raw_writew(val >> 16, addr + 2); 1858c2ecf20Sopenharmony_ci} 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cistatic inline u32 dma_read(int reg, int lch) 1888c2ecf20Sopenharmony_ci{ 1898c2ecf20Sopenharmony_ci void __iomem *addr = dma_base; 1908c2ecf20Sopenharmony_ci uint32_t val; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci addr += reg_map[reg].offset; 1938c2ecf20Sopenharmony_ci addr += reg_map[reg].stride * lch; 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci val = __raw_readw(addr); 1968c2ecf20Sopenharmony_ci if (reg_map[reg].type == OMAP_DMA_REG_2X16BIT) 1978c2ecf20Sopenharmony_ci val |= __raw_readw(addr + 2) << 16; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci return val; 2008c2ecf20Sopenharmony_ci} 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cistatic void omap1_clear_lch_regs(int lch) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci int i; 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci for (i = CPC; i <= COLOR; i += 1) 2078c2ecf20Sopenharmony_ci dma_write(0, i, lch); 2088c2ecf20Sopenharmony_ci} 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistatic void omap1_clear_dma(int lch) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci u32 l; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci l = dma_read(CCR, lch); 2158c2ecf20Sopenharmony_ci l &= ~OMAP_DMA_CCR_EN; 2168c2ecf20Sopenharmony_ci dma_write(l, CCR, lch); 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci /* Clear pending interrupts */ 2198c2ecf20Sopenharmony_ci l = dma_read(CSR, lch); 2208c2ecf20Sopenharmony_ci} 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_cistatic void omap1_show_dma_caps(void) 2238c2ecf20Sopenharmony_ci{ 2248c2ecf20Sopenharmony_ci if (enable_1510_mode) { 2258c2ecf20Sopenharmony_ci printk(KERN_INFO "DMA support for OMAP15xx initialized\n"); 2268c2ecf20Sopenharmony_ci } else { 2278c2ecf20Sopenharmony_ci u16 w; 2288c2ecf20Sopenharmony_ci printk(KERN_INFO "OMAP DMA hardware version %d\n", 2298c2ecf20Sopenharmony_ci dma_read(HW_ID, 0)); 2308c2ecf20Sopenharmony_ci printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n", 2318c2ecf20Sopenharmony_ci dma_read(CAPS_0, 0), dma_read(CAPS_1, 0), 2328c2ecf20Sopenharmony_ci dma_read(CAPS_2, 0), dma_read(CAPS_3, 0), 2338c2ecf20Sopenharmony_ci dma_read(CAPS_4, 0)); 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci /* Disable OMAP 3.0/3.1 compatibility mode. */ 2368c2ecf20Sopenharmony_ci w = dma_read(GSCR, 0); 2378c2ecf20Sopenharmony_ci w |= 1 << 3; 2388c2ecf20Sopenharmony_ci dma_write(w, GSCR, 0); 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistatic unsigned configure_dma_errata(void) 2438c2ecf20Sopenharmony_ci{ 2448c2ecf20Sopenharmony_ci unsigned errata = 0; 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci /* 2478c2ecf20Sopenharmony_ci * Erratum 3.2/3.3: sometimes 0 is returned if CSAC/CDAC is 2488c2ecf20Sopenharmony_ci * read before the DMA controller finished disabling the channel. 2498c2ecf20Sopenharmony_ci */ 2508c2ecf20Sopenharmony_ci if (!cpu_is_omap15xx()) 2518c2ecf20Sopenharmony_ci SET_DMA_ERRATA(DMA_ERRATA_3_3); 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci return errata; 2548c2ecf20Sopenharmony_ci} 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_cistatic const struct platform_device_info omap_dma_dev_info = { 2578c2ecf20Sopenharmony_ci .name = "omap-dma-engine", 2588c2ecf20Sopenharmony_ci .id = -1, 2598c2ecf20Sopenharmony_ci .dma_mask = DMA_BIT_MASK(32), 2608c2ecf20Sopenharmony_ci .res = res, 2618c2ecf20Sopenharmony_ci .num_res = 1, 2628c2ecf20Sopenharmony_ci}; 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci/* OMAP730, OMAP850 */ 2658c2ecf20Sopenharmony_cistatic const struct dma_slave_map omap7xx_sdma_map[] = { 2668c2ecf20Sopenharmony_ci { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(8) }, 2678c2ecf20Sopenharmony_ci { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(9) }, 2688c2ecf20Sopenharmony_ci { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(10) }, 2698c2ecf20Sopenharmony_ci { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(11) }, 2708c2ecf20Sopenharmony_ci { "mmci-omap.0", "tx", SDMA_FILTER_PARAM(21) }, 2718c2ecf20Sopenharmony_ci { "mmci-omap.0", "rx", SDMA_FILTER_PARAM(22) }, 2728c2ecf20Sopenharmony_ci { "omap_udc", "rx0", SDMA_FILTER_PARAM(26) }, 2738c2ecf20Sopenharmony_ci { "omap_udc", "rx1", SDMA_FILTER_PARAM(27) }, 2748c2ecf20Sopenharmony_ci { "omap_udc", "rx2", SDMA_FILTER_PARAM(28) }, 2758c2ecf20Sopenharmony_ci { "omap_udc", "tx0", SDMA_FILTER_PARAM(29) }, 2768c2ecf20Sopenharmony_ci { "omap_udc", "tx1", SDMA_FILTER_PARAM(30) }, 2778c2ecf20Sopenharmony_ci { "omap_udc", "tx2", SDMA_FILTER_PARAM(31) }, 2788c2ecf20Sopenharmony_ci}; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci/* OMAP1510, OMAP1610*/ 2818c2ecf20Sopenharmony_cistatic const struct dma_slave_map omap1xxx_sdma_map[] = { 2828c2ecf20Sopenharmony_ci { "omap-mcbsp.1", "tx", SDMA_FILTER_PARAM(8) }, 2838c2ecf20Sopenharmony_ci { "omap-mcbsp.1", "rx", SDMA_FILTER_PARAM(9) }, 2848c2ecf20Sopenharmony_ci { "omap-mcbsp.3", "tx", SDMA_FILTER_PARAM(10) }, 2858c2ecf20Sopenharmony_ci { "omap-mcbsp.3", "rx", SDMA_FILTER_PARAM(11) }, 2868c2ecf20Sopenharmony_ci { "omap-mcbsp.2", "tx", SDMA_FILTER_PARAM(16) }, 2878c2ecf20Sopenharmony_ci { "omap-mcbsp.2", "rx", SDMA_FILTER_PARAM(17) }, 2888c2ecf20Sopenharmony_ci { "mmci-omap.0", "tx", SDMA_FILTER_PARAM(21) }, 2898c2ecf20Sopenharmony_ci { "mmci-omap.0", "rx", SDMA_FILTER_PARAM(22) }, 2908c2ecf20Sopenharmony_ci { "omap_udc", "rx0", SDMA_FILTER_PARAM(26) }, 2918c2ecf20Sopenharmony_ci { "omap_udc", "rx1", SDMA_FILTER_PARAM(27) }, 2928c2ecf20Sopenharmony_ci { "omap_udc", "rx2", SDMA_FILTER_PARAM(28) }, 2938c2ecf20Sopenharmony_ci { "omap_udc", "tx0", SDMA_FILTER_PARAM(29) }, 2948c2ecf20Sopenharmony_ci { "omap_udc", "tx1", SDMA_FILTER_PARAM(30) }, 2958c2ecf20Sopenharmony_ci { "omap_udc", "tx2", SDMA_FILTER_PARAM(31) }, 2968c2ecf20Sopenharmony_ci { "mmci-omap.1", "tx", SDMA_FILTER_PARAM(54) }, 2978c2ecf20Sopenharmony_ci { "mmci-omap.1", "rx", SDMA_FILTER_PARAM(55) }, 2988c2ecf20Sopenharmony_ci}; 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_cistatic struct omap_system_dma_plat_info dma_plat_info __initdata = { 3018c2ecf20Sopenharmony_ci .reg_map = reg_map, 3028c2ecf20Sopenharmony_ci .channel_stride = 0x40, 3038c2ecf20Sopenharmony_ci .show_dma_caps = omap1_show_dma_caps, 3048c2ecf20Sopenharmony_ci .clear_lch_regs = omap1_clear_lch_regs, 3058c2ecf20Sopenharmony_ci .clear_dma = omap1_clear_dma, 3068c2ecf20Sopenharmony_ci .dma_write = dma_write, 3078c2ecf20Sopenharmony_ci .dma_read = dma_read, 3088c2ecf20Sopenharmony_ci}; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_cistatic int __init omap1_system_dma_init(void) 3118c2ecf20Sopenharmony_ci{ 3128c2ecf20Sopenharmony_ci struct omap_system_dma_plat_info p; 3138c2ecf20Sopenharmony_ci struct omap_dma_dev_attr *d; 3148c2ecf20Sopenharmony_ci struct platform_device *pdev, *dma_pdev; 3158c2ecf20Sopenharmony_ci int ret; 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci pdev = platform_device_alloc("omap_dma_system", 0); 3188c2ecf20Sopenharmony_ci if (!pdev) { 3198c2ecf20Sopenharmony_ci pr_err("%s: Unable to device alloc for dma\n", 3208c2ecf20Sopenharmony_ci __func__); 3218c2ecf20Sopenharmony_ci return -ENOMEM; 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci dma_base = ioremap(res[0].start, resource_size(&res[0])); 3258c2ecf20Sopenharmony_ci if (!dma_base) { 3268c2ecf20Sopenharmony_ci pr_err("%s: Unable to ioremap\n", __func__); 3278c2ecf20Sopenharmony_ci ret = -ENODEV; 3288c2ecf20Sopenharmony_ci goto exit_device_put; 3298c2ecf20Sopenharmony_ci } 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res)); 3328c2ecf20Sopenharmony_ci if (ret) { 3338c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n", 3348c2ecf20Sopenharmony_ci __func__, pdev->name, pdev->id); 3358c2ecf20Sopenharmony_ci goto exit_iounmap; 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci d = kzalloc(sizeof(*d), GFP_KERNEL); 3398c2ecf20Sopenharmony_ci if (!d) { 3408c2ecf20Sopenharmony_ci ret = -ENOMEM; 3418c2ecf20Sopenharmony_ci goto exit_iounmap; 3428c2ecf20Sopenharmony_ci } 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci /* Valid attributes for omap1 plus processors */ 3458c2ecf20Sopenharmony_ci if (cpu_is_omap15xx()) 3468c2ecf20Sopenharmony_ci d->dev_caps = ENABLE_1510_MODE; 3478c2ecf20Sopenharmony_ci enable_1510_mode = d->dev_caps & ENABLE_1510_MODE; 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ci if (cpu_is_omap16xx()) 3508c2ecf20Sopenharmony_ci d->dev_caps = ENABLE_16XX_MODE; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci d->dev_caps |= SRC_PORT; 3538c2ecf20Sopenharmony_ci d->dev_caps |= DST_PORT; 3548c2ecf20Sopenharmony_ci d->dev_caps |= SRC_INDEX; 3558c2ecf20Sopenharmony_ci d->dev_caps |= DST_INDEX; 3568c2ecf20Sopenharmony_ci d->dev_caps |= IS_BURST_ONLY4; 3578c2ecf20Sopenharmony_ci d->dev_caps |= CLEAR_CSR_ON_READ; 3588c2ecf20Sopenharmony_ci d->dev_caps |= IS_WORD_16; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci /* available logical channels */ 3618c2ecf20Sopenharmony_ci if (cpu_is_omap15xx()) { 3628c2ecf20Sopenharmony_ci d->lch_count = 9; 3638c2ecf20Sopenharmony_ci } else { 3648c2ecf20Sopenharmony_ci if (d->dev_caps & ENABLE_1510_MODE) 3658c2ecf20Sopenharmony_ci d->lch_count = 9; 3668c2ecf20Sopenharmony_ci else 3678c2ecf20Sopenharmony_ci d->lch_count = 16; 3688c2ecf20Sopenharmony_ci } 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci p = dma_plat_info; 3718c2ecf20Sopenharmony_ci p.dma_attr = d; 3728c2ecf20Sopenharmony_ci p.errata = configure_dma_errata(); 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci if (cpu_is_omap7xx()) { 3758c2ecf20Sopenharmony_ci p.slave_map = omap7xx_sdma_map; 3768c2ecf20Sopenharmony_ci p.slavecnt = ARRAY_SIZE(omap7xx_sdma_map); 3778c2ecf20Sopenharmony_ci } else { 3788c2ecf20Sopenharmony_ci p.slave_map = omap1xxx_sdma_map; 3798c2ecf20Sopenharmony_ci p.slavecnt = ARRAY_SIZE(omap1xxx_sdma_map); 3808c2ecf20Sopenharmony_ci } 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_ci ret = platform_device_add_data(pdev, &p, sizeof(p)); 3838c2ecf20Sopenharmony_ci if (ret) { 3848c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n", 3858c2ecf20Sopenharmony_ci __func__, pdev->name, pdev->id); 3868c2ecf20Sopenharmony_ci goto exit_release_d; 3878c2ecf20Sopenharmony_ci } 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci ret = platform_device_add(pdev); 3908c2ecf20Sopenharmony_ci if (ret) { 3918c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n", 3928c2ecf20Sopenharmony_ci __func__, pdev->name, pdev->id); 3938c2ecf20Sopenharmony_ci goto exit_release_d; 3948c2ecf20Sopenharmony_ci } 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci dma_pdev = platform_device_register_full(&omap_dma_dev_info); 3978c2ecf20Sopenharmony_ci if (IS_ERR(dma_pdev)) { 3988c2ecf20Sopenharmony_ci ret = PTR_ERR(dma_pdev); 3998c2ecf20Sopenharmony_ci goto exit_release_pdev; 4008c2ecf20Sopenharmony_ci } 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci return ret; 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ciexit_release_pdev: 4058c2ecf20Sopenharmony_ci platform_device_del(pdev); 4068c2ecf20Sopenharmony_ciexit_release_d: 4078c2ecf20Sopenharmony_ci kfree(d); 4088c2ecf20Sopenharmony_ciexit_iounmap: 4098c2ecf20Sopenharmony_ci iounmap(dma_base); 4108c2ecf20Sopenharmony_ciexit_device_put: 4118c2ecf20Sopenharmony_ci platform_device_put(pdev); 4128c2ecf20Sopenharmony_ci 4138c2ecf20Sopenharmony_ci return ret; 4148c2ecf20Sopenharmony_ci} 4158c2ecf20Sopenharmony_ciarch_initcall(omap1_system_dma_init); 416