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/sysdev.h> 18#include <linux/serial_core.h> 19#include <linux/io.h> 20 21#include <mach/dma.h> 22 23#include <plat/dma-s3c24xx.h> 24#include <plat/cpu.h> 25 26#include <plat/regs-serial.h> 27#include <mach/regs-gpio.h> 28#include <plat/regs-ac97.h> 29#include <plat/regs-dma.h> 30#include <mach/regs-mem.h> 31#include <mach/regs-lcd.h> 32#include <mach/regs-sdi.h> 33#include <plat/regs-iis.h> 34#include <plat/regs-spi.h> 35 36#define MAP(x) { \ 37 [0] = (x) | DMA_CH_VALID, \ 38 [1] = (x) | DMA_CH_VALID, \ 39 [2] = (x) | DMA_CH_VALID, \ 40 [3] = (x) | DMA_CH_VALID, \ 41 [4] = (x) | DMA_CH_VALID, \ 42 [5] = (x) | DMA_CH_VALID, \ 43 } 44 45static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = { 46 [DMACH_XD0] = { 47 .name = "xdreq0", 48 .channels = MAP(S3C2443_DMAREQSEL_XDREQ0), 49 }, 50 [DMACH_XD1] = { 51 .name = "xdreq1", 52 .channels = MAP(S3C2443_DMAREQSEL_XDREQ1), 53 }, 54 [DMACH_SDI] = { 55 .name = "sdi", 56 .channels = MAP(S3C2443_DMAREQSEL_SDI), 57 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, 58 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, 59 }, 60 [DMACH_SPI0] = { 61 .name = "spi0", 62 .channels = MAP(S3C2443_DMAREQSEL_SPI0TX), 63 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, 64 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, 65 }, 66 [DMACH_SPI1] = { 67 .name = "spi1", 68 .channels = MAP(S3C2443_DMAREQSEL_SPI1TX), 69 .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT, 70 .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT, 71 }, 72 [DMACH_UART0] = { 73 .name = "uart0", 74 .channels = MAP(S3C2443_DMAREQSEL_UART0_0), 75 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, 76 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, 77 }, 78 [DMACH_UART1] = { 79 .name = "uart1", 80 .channels = MAP(S3C2443_DMAREQSEL_UART1_0), 81 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, 82 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, 83 }, 84 [DMACH_UART2] = { 85 .name = "uart2", 86 .channels = MAP(S3C2443_DMAREQSEL_UART2_0), 87 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, 88 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, 89 }, 90 [DMACH_UART3] = { 91 .name = "uart3", 92 .channels = MAP(S3C2443_DMAREQSEL_UART3_0), 93 .hw_addr.to = S3C2443_PA_UART3 + S3C2410_UTXH, 94 .hw_addr.from = S3C2443_PA_UART3 + S3C2410_URXH, 95 }, 96 [DMACH_UART0_SRC2] = { 97 .name = "uart0", 98 .channels = MAP(S3C2443_DMAREQSEL_UART0_1), 99 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, 100 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, 101 }, 102 [DMACH_UART1_SRC2] = { 103 .name = "uart1", 104 .channels = MAP(S3C2443_DMAREQSEL_UART1_1), 105 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, 106 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, 107 }, 108 [DMACH_UART2_SRC2] = { 109 .name = "uart2", 110 .channels = MAP(S3C2443_DMAREQSEL_UART2_1), 111 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, 112 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, 113 }, 114 [DMACH_UART3_SRC2] = { 115 .name = "uart3", 116 .channels = MAP(S3C2443_DMAREQSEL_UART3_1), 117 .hw_addr.to = S3C2443_PA_UART3 + S3C2410_UTXH, 118 .hw_addr.from = S3C2443_PA_UART3 + S3C2410_URXH, 119 }, 120 [DMACH_TIMER] = { 121 .name = "timer", 122 .channels = MAP(S3C2443_DMAREQSEL_TIMER), 123 }, 124 [DMACH_I2S_IN] = { 125 .name = "i2s-sdi", 126 .channels = MAP(S3C2443_DMAREQSEL_I2SRX), 127 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, 128 }, 129 [DMACH_I2S_OUT] = { 130 .name = "i2s-sdo", 131 .channels = MAP(S3C2443_DMAREQSEL_I2STX), 132 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, 133 }, 134 [DMACH_PCM_IN] = { 135 .name = "pcm-in", 136 .channels = MAP(S3C2443_DMAREQSEL_PCMIN), 137 .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, 138 }, 139 [DMACH_PCM_OUT] = { 140 .name = "pcm-out", 141 .channels = MAP(S3C2443_DMAREQSEL_PCMOUT), 142 .hw_addr.to = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, 143 }, 144 [DMACH_MIC_IN] = { 145 .name = "mic-in", 146 .channels = MAP(S3C2443_DMAREQSEL_MICIN), 147 .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA, 148 }, 149}; 150 151static void s3c2443_dma_select(struct s3c2410_dma_chan *chan, 152 struct s3c24xx_dma_map *map) 153{ 154 writel(map->channels[0] | S3C2443_DMAREQSEL_HW, 155 chan->regs + S3C2443_DMA_DMAREQSEL); 156} 157 158static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = { 159 .select = s3c2443_dma_select, 160 .dcon_mask = 0, 161 .map = s3c2443_dma_mappings, 162 .map_size = ARRAY_SIZE(s3c2443_dma_mappings), 163}; 164 165static int __init s3c2443_dma_add(struct sys_device *sysdev) 166{ 167 s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100); 168 return s3c24xx_dma_init_map(&s3c2443_dma_sel); 169} 170 171static struct sysdev_driver s3c2443_dma_driver = { 172 .add = s3c2443_dma_add, 173}; 174 175static int __init s3c2443_dma_init(void) 176{ 177 return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_dma_driver); 178} 179 180arch_initcall(s3c2443_dma_init); 181