1/* linux/arch/arm/mach-s3c2443/dma.c 2 * 3 * Copyright (c) 2007 Simtec Electronics 4 * Ben Dooks <ben@simtec.co.uk> 5 * 6 * S3C2443 DMA selection 7 * 8 * http://armlinux.simtec.co.uk/ 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13*/ 14 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/device.h> 18#include <linux/serial_core.h> 19#include <linux/serial_s3c.h> 20#include <linux/io.h> 21 22#include <mach/dma.h> 23 24#include <plat/dma-s3c24xx.h> 25#include <plat/cpu.h> 26 27#include <mach/regs-gpio.h> 28#include <plat/regs-dma.h> 29#include <mach/regs-lcd.h> 30#include <plat/regs-spi.h> 31 32#define MAP(x) { \ 33 [0] = (x) | DMA_CH_VALID, \ 34 [1] = (x) | DMA_CH_VALID, \ 35 [2] = (x) | DMA_CH_VALID, \ 36 [3] = (x) | DMA_CH_VALID, \ 37 [4] = (x) | DMA_CH_VALID, \ 38 [5] = (x) | DMA_CH_VALID, \ 39 } 40 41static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = { 42 [DMACH_XD0] = { 43 .name = "xdreq0", 44 .channels = MAP(S3C2443_DMAREQSEL_XDREQ0), 45 }, 46 [DMACH_XD1] = { 47 .name = "xdreq1", 48 .channels = MAP(S3C2443_DMAREQSEL_XDREQ1), 49 }, 50 [DMACH_SDI] = { /* only on S3C2443 */ 51 .name = "sdi", 52 .channels = MAP(S3C2443_DMAREQSEL_SDI), 53 }, 54 [DMACH_SPI0_RX] = { 55 .name = "spi0-rx", 56 .channels = MAP(S3C2443_DMAREQSEL_SPI0RX), 57 }, 58 [DMACH_SPI0_TX] = { 59 .name = "spi0-tx", 60 .channels = MAP(S3C2443_DMAREQSEL_SPI0TX), 61 }, 62 [DMACH_SPI1_RX] = { /* only on S3C2443/S3C2450 */ 63 .name = "spi1-rx", 64 .channels = MAP(S3C2443_DMAREQSEL_SPI1RX), 65 }, 66 [DMACH_SPI1_TX] = { /* only on S3C2443/S3C2450 */ 67 .name = "spi1-tx", 68 .channels = MAP(S3C2443_DMAREQSEL_SPI1TX), 69 }, 70 [DMACH_UART0] = { 71 .name = "uart0", 72 .channels = MAP(S3C2443_DMAREQSEL_UART0_0), 73 }, 74 [DMACH_UART1] = { 75 .name = "uart1", 76 .channels = MAP(S3C2443_DMAREQSEL_UART1_0), 77 }, 78 [DMACH_UART2] = { 79 .name = "uart2", 80 .channels = MAP(S3C2443_DMAREQSEL_UART2_0), 81 }, 82 [DMACH_UART3] = { 83 .name = "uart3", 84 .channels = MAP(S3C2443_DMAREQSEL_UART3_0), 85 }, 86 [DMACH_UART0_SRC2] = { 87 .name = "uart0", 88 .channels = MAP(S3C2443_DMAREQSEL_UART0_1), 89 }, 90 [DMACH_UART1_SRC2] = { 91 .name = "uart1", 92 .channels = MAP(S3C2443_DMAREQSEL_UART1_1), 93 }, 94 [DMACH_UART2_SRC2] = { 95 .name = "uart2", 96 .channels = MAP(S3C2443_DMAREQSEL_UART2_1), 97 }, 98 [DMACH_UART3_SRC2] = { 99 .name = "uart3", 100 .channels = MAP(S3C2443_DMAREQSEL_UART3_1), 101 }, 102 [DMACH_TIMER] = { 103 .name = "timer", 104 .channels = MAP(S3C2443_DMAREQSEL_TIMER), 105 }, 106 [DMACH_I2S_IN] = { 107 .name = "i2s-sdi", 108 .channels = MAP(S3C2443_DMAREQSEL_I2SRX), 109 }, 110 [DMACH_I2S_OUT] = { 111 .name = "i2s-sdo", 112 .channels = MAP(S3C2443_DMAREQSEL_I2STX), 113 }, 114 [DMACH_PCM_IN] = { 115 .name = "pcm-in", 116 .channels = MAP(S3C2443_DMAREQSEL_PCMIN), 117 }, 118 [DMACH_PCM_OUT] = { 119 .name = "pcm-out", 120 .channels = MAP(S3C2443_DMAREQSEL_PCMOUT), 121 }, 122 [DMACH_MIC_IN] = { 123 .name = "mic-in", 124 .channels = MAP(S3C2443_DMAREQSEL_MICIN), 125 }, 126}; 127 128static void s3c2443_dma_select(struct s3c2410_dma_chan *chan, 129 struct s3c24xx_dma_map *map) 130{ 131 unsigned long chsel = map->channels[0] & (~DMA_CH_VALID); 132 writel(chsel | S3C2443_DMAREQSEL_HW, 133 chan->regs + S3C2443_DMA_DMAREQSEL); 134} 135 136static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = { 137 .select = s3c2443_dma_select, 138 .dcon_mask = 0, 139 .map = s3c2443_dma_mappings, 140 .map_size = ARRAY_SIZE(s3c2443_dma_mappings), 141}; 142 143static int __init s3c2443_dma_add(struct device *dev, 144 struct subsys_interface *sif) 145{ 146 s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100); 147 return s3c24xx_dma_init_map(&s3c2443_dma_sel); 148} 149 150#ifdef CONFIG_CPU_S3C2416 151/* S3C2416 DMA contains the same selection table as the S3C2443 */ 152static struct subsys_interface s3c2416_dma_interface = { 153 .name = "s3c2416_dma", 154 .subsys = &s3c2416_subsys, 155 .add_dev = s3c2443_dma_add, 156}; 157 158static int __init s3c2416_dma_init(void) 159{ 160 return subsys_interface_register(&s3c2416_dma_interface); 161} 162 163arch_initcall(s3c2416_dma_init); 164#endif 165 166#ifdef CONFIG_CPU_S3C2443 167static struct subsys_interface s3c2443_dma_interface = { 168 .name = "s3c2443_dma", 169 .subsys = &s3c2443_subsys, 170 .add_dev = s3c2443_dma_add, 171}; 172 173static int __init s3c2443_dma_init(void) 174{ 175 return subsys_interface_register(&s3c2443_dma_interface); 176} 177 178arch_initcall(s3c2443_dma_init); 179#endif 180