1/* linux/arch/arm/mach-s3c2412/dma.c 2 * 3 * Copyright (c) 2006 Simtec Electronics 4 * Ben Dooks <ben@simtec.co.uk> 5 * 6 * S3C2412 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 20#include <asm/dma.h> 21#include <asm/arch/dma.h> 22#include <asm/io.h> 23 24#include <asm/plat-s3c24xx/dma.h> 25#include <asm/plat-s3c24xx/cpu.h> 26 27#include <asm/arch/regs-serial.h> 28#include <asm/arch/regs-gpio.h> 29#include <asm/arch/regs-ac97.h> 30#include <asm/arch/regs-mem.h> 31#include <asm/arch/regs-lcd.h> 32#include <asm/arch/regs-sdi.h> 33#include <asm/arch/regs-iis.h> 34#include <asm/arch/regs-spi.h> 35 36#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID } 37 38static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = { 39 [DMACH_XD0] = { 40 .name = "xdreq0", 41 .channels = MAP(S3C2412_DMAREQSEL_XDREQ0), 42 }, 43 [DMACH_XD1] = { 44 .name = "xdreq1", 45 .channels = MAP(S3C2412_DMAREQSEL_XDREQ1), 46 }, 47 [DMACH_SDI] = { 48 .name = "sdi", 49 .channels = MAP(S3C2412_DMAREQSEL_SDI), 50 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, 51 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, 52 }, 53 [DMACH_SPI0] = { 54 .name = "spi0", 55 .channels = MAP(S3C2412_DMAREQSEL_SPI0TX), 56 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT, 57 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT, 58 }, 59 [DMACH_SPI1] = { 60 .name = "spi1", 61 .channels = MAP(S3C2412_DMAREQSEL_SPI1TX), 62 .hw_addr.to = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPTDAT, 63 .hw_addr.from = S3C2410_PA_SPI + S3C2412_SPI1 + S3C2410_SPRDAT, 64 }, 65 [DMACH_UART0] = { 66 .name = "uart0", 67 .channels = MAP(S3C2412_DMAREQSEL_UART0_0), 68 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, 69 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, 70 }, 71 [DMACH_UART1] = { 72 .name = "uart1", 73 .channels = MAP(S3C2412_DMAREQSEL_UART1_0), 74 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, 75 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, 76 }, 77 [DMACH_UART2] = { 78 .name = "uart2", 79 .channels = MAP(S3C2412_DMAREQSEL_UART2_0), 80 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, 81 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, 82 }, 83 [DMACH_UART0_SRC2] = { 84 .name = "uart0", 85 .channels = MAP(S3C2412_DMAREQSEL_UART0_1), 86 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH, 87 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH, 88 }, 89 [DMACH_UART1_SRC2] = { 90 .name = "uart1", 91 .channels = MAP(S3C2412_DMAREQSEL_UART1_1), 92 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH, 93 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH, 94 }, 95 [DMACH_UART2_SRC2] = { 96 .name = "uart2", 97 .channels = MAP(S3C2412_DMAREQSEL_UART2_1), 98 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH, 99 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH, 100 }, 101 [DMACH_TIMER] = { 102 .name = "timer", 103 .channels = MAP(S3C2412_DMAREQSEL_TIMER), 104 }, 105 [DMACH_I2S_IN] = { 106 .name = "i2s-sdi", 107 .channels = MAP(S3C2412_DMAREQSEL_I2SRX), 108 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO, 109 }, 110 [DMACH_I2S_OUT] = { 111 .name = "i2s-sdo", 112 .channels = MAP(S3C2412_DMAREQSEL_I2STX), 113 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO, 114 }, 115 [DMACH_USB_EP1] = { 116 .name = "usb-ep1", 117 .channels = MAP(S3C2412_DMAREQSEL_USBEP1), 118 }, 119 [DMACH_USB_EP2] = { 120 .name = "usb-ep2", 121 .channels = MAP(S3C2412_DMAREQSEL_USBEP2), 122 }, 123 [DMACH_USB_EP3] = { 124 .name = "usb-ep3", 125 .channels = MAP(S3C2412_DMAREQSEL_USBEP3), 126 }, 127 [DMACH_USB_EP4] = { 128 .name = "usb-ep4", 129 .channels = MAP(S3C2412_DMAREQSEL_USBEP4), 130 }, 131}; 132 133static void s3c2412_dma_select(struct s3c2410_dma_chan *chan, 134 struct s3c24xx_dma_map *map) 135{ 136 writel(map->channels[0] | S3C2412_DMAREQSEL_HW, 137 chan->regs + S3C2412_DMA_DMAREQSEL); 138} 139 140static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = { 141 .select = s3c2412_dma_select, 142 .dcon_mask = 0, 143 .map = s3c2412_dma_mappings, 144 .map_size = ARRAY_SIZE(s3c2412_dma_mappings), 145}; 146 147static int s3c2412_dma_add(struct sys_device *sysdev) 148{ 149 s3c2410_dma_init(); 150 return s3c24xx_dma_init_map(&s3c2412_dma_sel); 151} 152 153static struct sysdev_driver s3c2412_dma_driver = { 154 .add = s3c2412_dma_add, 155}; 156 157static int __init s3c2412_dma_init(void) 158{ 159 return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_dma_driver); 160} 161 162arch_initcall(s3c2412_dma_init); 163