aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/s3c24xx/patches-2.6.30/010-s3c-dma.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/s3c24xx/patches-2.6.30/010-s3c-dma.patch')
-rw-r--r--target/linux/s3c24xx/patches-2.6.30/010-s3c-dma.patch1324
1 files changed, 1324 insertions, 0 deletions
diff --git a/target/linux/s3c24xx/patches-2.6.30/010-s3c-dma.patch b/target/linux/s3c24xx/patches-2.6.30/010-s3c-dma.patch
new file mode 100644
index 000000000..e0ff7c442
--- /dev/null
+++ b/target/linux/s3c24xx/patches-2.6.30/010-s3c-dma.patch
@@ -0,0 +1,1324 @@
+--- a/arch/arm/mach-s3c2410/include/mach/dma.h
++++ b/arch/arm/mach-s3c2410/include/mach/dma.h
+@@ -3,7 +3,7 @@
+ * Copyright (C) 2003,2004,2006 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+- * Samsung S3C241XX DMA support
++ * Samsung S3C24XX DMA support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+@@ -13,8 +13,8 @@
+ #ifndef __ASM_ARCH_DMA_H
+ #define __ASM_ARCH_DMA_H __FILE__
+
++#include <plat/dma.h>
+ #include <linux/sysdev.h>
+-#include <mach/hardware.h>
+
+ #define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */
+
+@@ -55,9 +55,9 @@ enum dma_ch {
+
+ /* we have 4 dma channels */
+ #ifndef CONFIG_CPU_S3C2443
+-#define S3C2410_DMA_CHANNELS (4)
++#define S3C_DMA_CHANNELS (4)
+ #else
+-#define S3C2410_DMA_CHANNELS (6)
++#define S3C_DMA_CHANNELS (6)
+ #endif
+
+ /* types */
+@@ -68,7 +68,6 @@ enum s3c2410_dma_state {
+ S3C2410_DMA_PAUSED
+ };
+
+-
+ /* enum s3c2410_dma_loadst
+ *
+ * This represents the state of the DMA engine, wrt to the loaded / running
+@@ -104,32 +103,6 @@ enum s3c2410_dma_loadst {
+ S3C2410_DMALOAD_1LOADED_1RUNNING,
+ };
+
+-enum s3c2410_dma_buffresult {
+- S3C2410_RES_OK,
+- S3C2410_RES_ERR,
+- S3C2410_RES_ABORT
+-};
+-
+-enum s3c2410_dmasrc {
+- S3C2410_DMASRC_HW, /* source is memory */
+- S3C2410_DMASRC_MEM /* source is hardware */
+-};
+-
+-/* enum s3c2410_chan_op
+- *
+- * operation codes passed to the DMA code by the user, and also used
+- * to inform the current channel owner of any changes to the system state
+-*/
+-
+-enum s3c2410_chan_op {
+- S3C2410_DMAOP_START,
+- S3C2410_DMAOP_STOP,
+- S3C2410_DMAOP_PAUSE,
+- S3C2410_DMAOP_RESUME,
+- S3C2410_DMAOP_FLUSH,
+- S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */
+- S3C2410_DMAOP_STARTED, /* indicate channel started */
+-};
+
+ /* flags */
+
+@@ -137,19 +110,18 @@ enum s3c2410_chan_op {
+ * waiting for reloads */
+ #define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */
+
++#define S3C2410_DMAF_CIRCULAR (0x00) /* circular enqueue not supp. */
++
+ /* dma buffer */
+
+-struct s3c2410_dma_client {
+- char *name;
+-};
++struct s3c2410_dma_buf;
+
+-/* s3c2410_dma_buf_s
++/* s3c2410_dma_buf
+ *
+ * internally used buffer structure to describe a queued or running
+ * buffer.
+ */
+
+-struct s3c2410_dma_buf;
+ struct s3c2410_dma_buf {
+ struct s3c2410_dma_buf *next;
+ int magic; /* magic */
+@@ -161,20 +133,6 @@ struct s3c2410_dma_buf {
+
+ /* [1] is this updated for both recv/send modes? */
+
+-struct s3c2410_dma_chan;
+-
+-/* s3c2410_dma_cbfn_t
+- *
+- * buffer callback routine type
+-*/
+-
+-typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
+- void *buf, int size,
+- enum s3c2410_dma_buffresult result);
+-
+-typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *,
+- enum s3c2410_chan_op );
+-
+ struct s3c2410_dma_stats {
+ unsigned long loads;
+ unsigned long timeout_longest;
+@@ -206,10 +164,10 @@ struct s3c2410_dma_chan {
+
+ /* channel configuration */
+ enum s3c2410_dmasrc source;
++ enum dma_ch req_ch;
+ unsigned long dev_addr;
+ unsigned long load_timeout;
+ unsigned int flags; /* channel flags */
+- unsigned int hw_cfg; /* last hw config */
+
+ struct s3c24xx_dma_map *map; /* channel hw maps */
+
+@@ -236,213 +194,12 @@ struct s3c2410_dma_chan {
+ struct sys_device dev;
+ };
+
+-/* the currently allocated channel information */
+-extern struct s3c2410_dma_chan s3c2410_chans[];
+-
+-/* note, we don't really use dma_device_t at the moment */
+ typedef unsigned long dma_device_t;
+
+-/* functions --------------------------------------------------------------- */
+-
+-/* s3c2410_dma_request
+- *
+- * request a dma channel exclusivley
+-*/
+-
+-extern int s3c2410_dma_request(unsigned int channel,
+- struct s3c2410_dma_client *, void *dev);
+-
+-
+-/* s3c2410_dma_ctrl
+- *
+- * change the state of the dma channel
+-*/
+-
+-extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op);
+-
+-/* s3c2410_dma_setflags
+- *
+- * set the channel's flags to a given state
+-*/
+-
+-extern int s3c2410_dma_setflags(unsigned int channel,
+- unsigned int flags);
+-
+-/* s3c2410_dma_free
+- *
+- * free the dma channel (will also abort any outstanding operations)
+-*/
+-
+-extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *);
+-
+-/* s3c2410_dma_enqueue
+- *
+- * place the given buffer onto the queue of operations for the channel.
+- * The buffer must be allocated from dma coherent memory, or the Dcache/WB
+- * drained before the buffer is given to the DMA system.
+-*/
+-
+-extern int s3c2410_dma_enqueue(unsigned int channel, void *id,
+- dma_addr_t data, int size);
+-
+-/* s3c2410_dma_config
+- *
+- * configure the dma channel
+-*/
+-
+-extern int s3c2410_dma_config(unsigned int channel, int xferunit, int dcon);
+-
+-/* s3c2410_dma_devconfig
+- *
+- * configure the device we're talking to
+-*/
+-
+-extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source,
+- int hwcfg, unsigned long devaddr);
+-
+-/* s3c2410_dma_getposition
+- *
+- * get the position that the dma transfer is currently at
+-*/
+-
+-extern int s3c2410_dma_getposition(unsigned int channel,
+- dma_addr_t *src, dma_addr_t *dest);
+-
+-extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn);
+-extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn);
+-
+-/* DMA Register definitions */
+-
+-#define S3C2410_DMA_DISRC (0x00)
+-#define S3C2410_DMA_DISRCC (0x04)
+-#define S3C2410_DMA_DIDST (0x08)
+-#define S3C2410_DMA_DIDSTC (0x0C)
+-#define S3C2410_DMA_DCON (0x10)
+-#define S3C2410_DMA_DSTAT (0x14)
+-#define S3C2410_DMA_DCSRC (0x18)
+-#define S3C2410_DMA_DCDST (0x1C)
+-#define S3C2410_DMA_DMASKTRIG (0x20)
+-#define S3C2412_DMA_DMAREQSEL (0x24)
+-#define S3C2443_DMA_DMAREQSEL (0x24)
+-
+-#define S3C2410_DISRCC_INC (1<<0)
+-#define S3C2410_DISRCC_APB (1<<1)
+-
+-#define S3C2410_DMASKTRIG_STOP (1<<2)
+-#define S3C2410_DMASKTRIG_ON (1<<1)
+-#define S3C2410_DMASKTRIG_SWTRIG (1<<0)
+-
+-#define S3C2410_DCON_DEMAND (0<<31)
+-#define S3C2410_DCON_HANDSHAKE (1<<31)
+-#define S3C2410_DCON_SYNC_PCLK (0<<30)
+-#define S3C2410_DCON_SYNC_HCLK (1<<30)
+-
+-#define S3C2410_DCON_INTREQ (1<<29)
+-
+-#define S3C2410_DCON_CH0_XDREQ0 (0<<24)
+-#define S3C2410_DCON_CH0_UART0 (1<<24)
+-#define S3C2410_DCON_CH0_SDI (2<<24)
+-#define S3C2410_DCON_CH0_TIMER (3<<24)
+-#define S3C2410_DCON_CH0_USBEP1 (4<<24)
+-
+-#define S3C2410_DCON_CH1_XDREQ1 (0<<24)
+-#define S3C2410_DCON_CH1_UART1 (1<<24)
+-#define S3C2410_DCON_CH1_I2SSDI (2<<24)
+-#define S3C2410_DCON_CH1_SPI (3<<24)
+-#define S3C2410_DCON_CH1_USBEP2 (4<<24)
+-
+-#define S3C2410_DCON_CH2_I2SSDO (0<<24)
+-#define S3C2410_DCON_CH2_I2SSDI (1<<24)
+-#define S3C2410_DCON_CH2_SDI (2<<24)
+-#define S3C2410_DCON_CH2_TIMER (3<<24)
+-#define S3C2410_DCON_CH2_USBEP3 (4<<24)
+-
+-#define S3C2410_DCON_CH3_UART2 (0<<24)
+-#define S3C2410_DCON_CH3_SDI (1<<24)
+-#define S3C2410_DCON_CH3_SPI (2<<24)
+-#define S3C2410_DCON_CH3_TIMER (3<<24)
+-#define S3C2410_DCON_CH3_USBEP4 (4<<24)
+-
+-#define S3C2410_DCON_SRCSHIFT (24)
+-#define S3C2410_DCON_SRCMASK (7<<24)
+-
+-#define S3C2410_DCON_BYTE (0<<20)
+-#define S3C2410_DCON_HALFWORD (1<<20)
+-#define S3C2410_DCON_WORD (2<<20)
+-
+-#define S3C2410_DCON_AUTORELOAD (0<<22)
+-#define S3C2410_DCON_NORELOAD (1<<22)
+-#define S3C2410_DCON_HWTRIG (1<<23)
+-
+-#ifdef CONFIG_CPU_S3C2440
+-#define S3C2440_DIDSTC_CHKINT (1<<2)
+-
+-#define S3C2440_DCON_CH0_I2SSDO (5<<24)
+-#define S3C2440_DCON_CH0_PCMIN (6<<24)
+-
+-#define S3C2440_DCON_CH1_PCMOUT (5<<24)
+-#define S3C2440_DCON_CH1_SDI (6<<24)
+-
+-#define S3C2440_DCON_CH2_PCMIN (5<<24)
+-#define S3C2440_DCON_CH2_MICIN (6<<24)
+-
+-#define S3C2440_DCON_CH3_MICIN (5<<24)
+-#define S3C2440_DCON_CH3_PCMOUT (6<<24)
+-#endif
+-
+-#ifdef CONFIG_CPU_S3C2412
+-
+-#define S3C2412_DMAREQSEL_SRC(x) ((x)<<1)
+-
+-#define S3C2412_DMAREQSEL_HW (1)
+-
+-#define S3C2412_DMAREQSEL_SPI0TX S3C2412_DMAREQSEL_SRC(0)
+-#define S3C2412_DMAREQSEL_SPI0RX S3C2412_DMAREQSEL_SRC(1)
+-#define S3C2412_DMAREQSEL_SPI1TX S3C2412_DMAREQSEL_SRC(2)
+-#define S3C2412_DMAREQSEL_SPI1RX S3C2412_DMAREQSEL_SRC(3)
+-#define S3C2412_DMAREQSEL_I2STX S3C2412_DMAREQSEL_SRC(4)
+-#define S3C2412_DMAREQSEL_I2SRX S3C2412_DMAREQSEL_SRC(5)
+-#define S3C2412_DMAREQSEL_TIMER S3C2412_DMAREQSEL_SRC(9)
+-#define S3C2412_DMAREQSEL_SDI S3C2412_DMAREQSEL_SRC(10)
+-#define S3C2412_DMAREQSEL_USBEP1 S3C2412_DMAREQSEL_SRC(13)
+-#define S3C2412_DMAREQSEL_USBEP2 S3C2412_DMAREQSEL_SRC(14)
+-#define S3C2412_DMAREQSEL_USBEP3 S3C2412_DMAREQSEL_SRC(15)
+-#define S3C2412_DMAREQSEL_USBEP4 S3C2412_DMAREQSEL_SRC(16)
+-#define S3C2412_DMAREQSEL_XDREQ0 S3C2412_DMAREQSEL_SRC(17)
+-#define S3C2412_DMAREQSEL_XDREQ1 S3C2412_DMAREQSEL_SRC(18)
+-#define S3C2412_DMAREQSEL_UART0_0 S3C2412_DMAREQSEL_SRC(19)
+-#define S3C2412_DMAREQSEL_UART0_1 S3C2412_DMAREQSEL_SRC(20)
+-#define S3C2412_DMAREQSEL_UART1_0 S3C2412_DMAREQSEL_SRC(21)
+-#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22)
+-#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23)
+-#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24)
+-
+-#endif
+-
+-#define S3C2443_DMAREQSEL_SRC(x) ((x)<<1)
+-
+-#define S3C2443_DMAREQSEL_HW (1)
+
+-#define S3C2443_DMAREQSEL_SPI0TX S3C2443_DMAREQSEL_SRC(0)
+-#define S3C2443_DMAREQSEL_SPI0RX S3C2443_DMAREQSEL_SRC(1)
+-#define S3C2443_DMAREQSEL_SPI1TX S3C2443_DMAREQSEL_SRC(2)
+-#define S3C2443_DMAREQSEL_SPI1RX S3C2443_DMAREQSEL_SRC(3)
+-#define S3C2443_DMAREQSEL_I2STX S3C2443_DMAREQSEL_SRC(4)
+-#define S3C2443_DMAREQSEL_I2SRX S3C2443_DMAREQSEL_SRC(5)
+-#define S3C2443_DMAREQSEL_TIMER S3C2443_DMAREQSEL_SRC(9)
+-#define S3C2443_DMAREQSEL_SDI S3C2443_DMAREQSEL_SRC(10)
+-#define S3C2443_DMAREQSEL_XDREQ0 S3C2443_DMAREQSEL_SRC(17)
+-#define S3C2443_DMAREQSEL_XDREQ1 S3C2443_DMAREQSEL_SRC(18)
+-#define S3C2443_DMAREQSEL_UART0_0 S3C2443_DMAREQSEL_SRC(19)
+-#define S3C2443_DMAREQSEL_UART0_1 S3C2443_DMAREQSEL_SRC(20)
+-#define S3C2443_DMAREQSEL_UART1_0 S3C2443_DMAREQSEL_SRC(21)
+-#define S3C2443_DMAREQSEL_UART1_1 S3C2443_DMAREQSEL_SRC(22)
+-#define S3C2443_DMAREQSEL_UART2_0 S3C2443_DMAREQSEL_SRC(23)
+-#define S3C2443_DMAREQSEL_UART2_1 S3C2443_DMAREQSEL_SRC(24)
+-#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25)
+-#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26)
+-#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27)
+-#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28)
+-#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29)
++static int s3c_dma_has_circular(void)
++{
++ return 0;
++}
+
+ #endif /* __ASM_ARCH_DMA_H */
+--- a/arch/arm/mach-s3c2442/Kconfig
++++ b/arch/arm/mach-s3c2442/Kconfig
+@@ -11,6 +11,7 @@ config CPU_S3C2442
+ select S3C2410_CLOCK
+ select S3C2410_GPIO
+ select S3C2410_PM if PM
++ select S3C2440_DMA if S3C2410_DMA
+ select CPU_S3C244X
+ select CPU_LLSERIAL_S3C2440
+ help
+--- /dev/null
++++ b/arch/arm/plat-s3c/dma.c
+@@ -0,0 +1,86 @@
++/* linux/arch/arm/plat-s3c/dma.c
++ *
++ * Copyright (c) 2003-2005,2006,2009 Simtec Electronics
++ * Ben Dooks <ben@simtec.co.uk>
++ * http://armlinux.simtec.co.uk/
++ *
++ * S3C DMA core
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++struct s3c2410_dma_buf;
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++
++#include <mach/dma.h>
++#include <mach/irqs.h>
++
++#include <plat/dma-plat.h>
++
++/* dma channel state information */
++struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
++struct s3c2410_dma_chan *s3c_dma_chan_map[DMACH_MAX];
++
++/* s3c_dma_lookup_channel
++ *
++ * change the dma channel number given into a real dma channel id
++*/
++
++struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel)
++{
++ if (channel & DMACH_LOW_LEVEL)
++ return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
++ else
++ return s3c_dma_chan_map[channel];
++}
++
++/* do we need to protect the settings of the fields from
++ * irq?
++*/
++
++int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn)
++{
++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
++
++ if (chan == NULL)
++ return -EINVAL;
++
++ pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
++
++ chan->op_fn = rtn;
++
++ return 0;
++}
++EXPORT_SYMBOL(s3c2410_dma_set_opfn);
++
++int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn)
++{
++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
++
++ if (chan == NULL)
++ return -EINVAL;
++
++ pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
++
++ chan->callback_fn = rtn;
++
++ return 0;
++}
++EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
++
++int s3c2410_dma_setflags(unsigned int channel, unsigned int flags)
++{
++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
++
++ if (chan == NULL)
++ return -EINVAL;
++
++ chan->flags = flags;
++ return 0;
++}
++EXPORT_SYMBOL(s3c2410_dma_setflags);
+--- /dev/null
++++ b/arch/arm/plat-s3c/include/plat/dma-core.h
+@@ -0,0 +1,22 @@
++/* arch/arm/plat-s3c/include/plat/dma.h
++ *
++ * Copyright 2008 Openmoko, Inc.
++ * Copyright 2008 Simtec Electronics
++ * Ben Dooks <ben@simtec.co.uk>
++ * http://armlinux.simtec.co.uk/
++ *
++ * Samsung S3C DMA core support
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++extern struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel);
++
++extern struct s3c2410_dma_chan *s3c_dma_chan_map[];
++
++/* the currently allocated channel information */
++extern struct s3c2410_dma_chan s3c2410_chans[];
++
++
+--- /dev/null
++++ b/arch/arm/plat-s3c/include/plat/dma.h
+@@ -0,0 +1,128 @@
++/* arch/arm/plat-s3c/include/plat/dma.h
++ *
++ * Copyright (C) 2003,2004,2006 Simtec Electronics
++ * Ben Dooks <ben@simtec.co.uk>
++ *
++ * Samsung S3C DMA support
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++enum s3c2410_dma_buffresult {
++ S3C2410_RES_OK,
++ S3C2410_RES_ERR,
++ S3C2410_RES_ABORT
++};
++
++enum s3c2410_dmasrc {
++ S3C2410_DMASRC_HW, /* source is memory */
++ S3C2410_DMASRC_MEM /* source is hardware */
++};
++
++/* enum s3c2410_chan_op
++ *
++ * operation codes passed to the DMA code by the user, and also used
++ * to inform the current channel owner of any changes to the system state
++*/
++
++enum s3c2410_chan_op {
++ S3C2410_DMAOP_START,
++ S3C2410_DMAOP_STOP,
++ S3C2410_DMAOP_PAUSE,
++ S3C2410_DMAOP_RESUME,
++ S3C2410_DMAOP_FLUSH,
++ S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */
++ S3C2410_DMAOP_STARTED, /* indicate channel started */
++};
++
++struct s3c2410_dma_client {
++ char *name;
++};
++
++struct s3c2410_dma_chan;
++
++/* s3c2410_dma_cbfn_t
++ *
++ * buffer callback routine type
++*/
++
++typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
++ void *buf, int size,
++ enum s3c2410_dma_buffresult result);
++
++typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *,
++ enum s3c2410_chan_op );
++
++
++
++/* s3c2410_dma_request
++ *
++ * request a dma channel exclusivley
++*/
++
++extern int s3c2410_dma_request(unsigned int channel,
++ struct s3c2410_dma_client *, void *dev);
++
++
++/* s3c2410_dma_ctrl
++ *
++ * change the state of the dma channel
++*/
++
++extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op);
++
++/* s3c2410_dma_setflags
++ *
++ * set the channel's flags to a given state
++*/
++
++extern int s3c2410_dma_setflags(unsigned int channel,
++ unsigned int flags);
++
++/* s3c2410_dma_free
++ *
++ * free the dma channel (will also abort any outstanding operations)
++*/
++
++extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *);
++
++/* s3c2410_dma_enqueue
++ *
++ * place the given buffer onto the queue of operations for the channel.
++ * The buffer must be allocated from dma coherent memory, or the Dcache/WB
++ * drained before the buffer is given to the DMA system.
++*/
++
++extern int s3c2410_dma_enqueue(unsigned int channel, void *id,
++ dma_addr_t data, int size);
++
++
++/* s3c2410_dma_config
++ *
++ * configure the dma channel
++*/
++
++extern int s3c2410_dma_config(unsigned int channel, int xferunit);
++
++/* s3c2410_dma_devconfig
++ *
++ * configure the device we're talking to
++*/
++
++extern int s3c2410_dma_devconfig(int channel, enum s3c2410_dmasrc source,
++ unsigned long devaddr);
++
++/* s3c2410_dma_getposition
++ *
++ * get the position that the dma transfer is currently at
++*/
++
++extern int s3c2410_dma_getposition(unsigned int channel,
++ dma_addr_t *src, dma_addr_t *dest);
++
++extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn);
++extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn);
++
++
+--- a/arch/arm/plat-s3c/Kconfig
++++ b/arch/arm/plat-s3c/Kconfig
+@@ -150,6 +150,13 @@ config S3C_GPIO_CFG_S3C64XX
+ Internal configuration to enable S3C64XX style GPIO configuration
+ functions.
+
++# DMA
++
++config S3C_DMA
++ bool
++ help
++ Internal configuration for S3C DMA core
++
+ # device definitions to compile in
+
+ config S3C_DEV_HSMMC
+--- a/arch/arm/plat-s3c/Makefile
++++ b/arch/arm/plat-s3c/Makefile
+@@ -18,6 +18,10 @@ obj-y += pwm-clock.o
+ obj-y += gpio.o
+ obj-y += gpio-config.o
+
++# DMA support
++
++obj-$(CONFIG_S3C_DMA) += dma.o
++
+ # PM support
+
+ obj-$(CONFIG_PM) += pm.o
+@@ -31,3 +35,5 @@ obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmm
+ obj-y += dev-i2c0.o
+ obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
+ obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o
++obj-$(CONFIG_S3C_DMA) += dma.o
++
+--- a/arch/arm/plat-s3c24xx/dma.c
++++ b/arch/arm/plat-s3c24xx/dma.c
+@@ -31,10 +31,11 @@
+ #include <asm/irq.h>
+ #include <mach/hardware.h>
+ #include <mach/dma.h>
+-
+ #include <mach/map.h>
+
+-#include <plat/dma.h>
++#include <plat/dma-core.h>
++#include <plat/regs-dma.h>
++#include <plat/dma-plat.h>
+
+ /* io map for dma */
+ static void __iomem *dma_base;
+@@ -44,8 +45,6 @@ static int dma_channels;
+
+ static struct s3c24xx_dma_selection dma_sel;
+
+-/* dma channel state information */
+-struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
+
+ /* debugging functions */
+
+@@ -135,21 +134,6 @@ dmadbg_showregs(const char *fname, int l
+ #define dbg_showchan(chan) do { } while(0)
+ #endif /* CONFIG_S3C2410_DMA_DEBUG */
+
+-static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
+-
+-/* lookup_dma_channel
+- *
+- * change the dma channel number given into a real dma channel id
+-*/
+-
+-static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
+-{
+- if (channel & DMACH_LOW_LEVEL)
+- return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
+- else
+- return dma_chan_map[channel];
+-}
+-
+ /* s3c2410_dma_stats_timeout
+ *
+ * Update DMA stats from timeout info
+@@ -214,8 +198,6 @@ s3c2410_dma_waitforload(struct s3c2410_d
+ return 0;
+ }
+
+-
+-
+ /* s3c2410_dma_loadbuffer
+ *
+ * load a buffer, and update the channel state
+@@ -453,7 +435,7 @@ s3c2410_dma_canload(struct s3c2410_dma_c
+ int s3c2410_dma_enqueue(unsigned int channel, void *id,
+ dma_addr_t data, int size)
+ {
+- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ struct s3c2410_dma_buf *buf;
+ unsigned long flags;
+
+@@ -804,7 +786,7 @@ EXPORT_SYMBOL(s3c2410_dma_request);
+
+ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
+ {
+- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+ unsigned long flags;
+
+ if (chan == NULL)
+@@ -836,7 +818,7 @@ int s3c2410_dma_free(unsigned int channe
+ chan->irq_claimed = 0;
+
+ if (!(channel & DMACH_LOW_LEVEL))
+- dma_chan_map[channel] = NULL;
++ s3c_dma_chan_map[channel] = NULL;
+
+ local_irq_restore(flags);
+
+@@ -995,7 +977,7 @@ static int s3c2410_dma_started(struct s3
+ int
+ s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op)
+ {
+- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+@@ -1038,14 +1020,13 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl);
+ /* s3c2410_dma_config
+ *
+ * xfersize: size of unit in bytes (1,2,4)
+- * dcon: base value of the DCONx register
+ */
+
+ int s3c2410_dma_config(unsigned int channel,
+- int xferunit,
+- int dcon)
++ int xferunit)
+ {
+- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
++ unsigned int dcon;
+
+ pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
+ __func__, channel, xferunit, dcon);
+@@ -1055,10 +1036,33 @@ int s3c2410_dma_config(unsigned int chan
+
+ pr_debug("%s: Initial dcon is %08x\n", __func__, dcon);
+
+- dcon |= chan->dcon & dma_sel.dcon_mask;
++ dcon = chan->dcon & dma_sel.dcon_mask;
+
+ pr_debug("%s: New dcon is %08x\n", __func__, dcon);
+
++ switch (chan->req_ch) {
++ case DMACH_I2S_IN:
++ case DMACH_I2S_OUT:
++ case DMACH_PCM_IN:
++ case DMACH_PCM_OUT:
++ case DMACH_MIC_IN:
++ default:
++ dcon |= S3C2410_DCON_HANDSHAKE;
++ dcon |= S3C2410_DCON_SYNC_PCLK;
++ break;
++
++ case DMACH_SDI:
++ /* note, ensure if need HANDSHAKE or not */
++ dcon |= S3C2410_DCON_SYNC_PCLK;
++ break;
++
++ case DMACH_XD0:
++ case DMACH_XD1:
++ dcon |= S3C2410_DCON_HANDSHAKE;
++ dcon |= S3C2410_DCON_SYNC_HCLK;
++ break;
++ }
++
+ switch (xferunit) {
+ case 1:
+ dcon |= S3C2410_DCON_BYTE;
+@@ -1089,10 +1093,10 @@ int s3c2410_dma_config(unsigned int chan
+ }
+
+ EXPORT_SYMBOL(s3c2410_dma_config);
+-
++#if 0 /* moved to plat-s3c? */
+ int s3c2410_dma_setflags(unsigned int channel, unsigned int flags)
+ {
+- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+@@ -1105,43 +1109,7 @@ int s3c2410_dma_setflags(unsigned int ch
+ }
+
+ EXPORT_SYMBOL(s3c2410_dma_setflags);
+-
+-
+-/* do we need to protect the settings of the fields from
+- * irq?
+-*/
+-
+-int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn)
+-{
+- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+-
+- if (chan == NULL)
+- return -EINVAL;
+-
+- pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
+-
+- chan->op_fn = rtn;
+-
+- return 0;
+-}
+-
+-EXPORT_SYMBOL(s3c2410_dma_set_opfn);
+-
+-int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn)
+-{
+- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
+-
+- if (chan == NULL)
+- return -EINVAL;
+-
+- pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
+-
+- chan->callback_fn = rtn;
+-
+- return 0;
+-}
+-
+-EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
++#endif
+
+ /* s3c2410_dma_devconfig
+ *
+@@ -1150,29 +1118,38 @@ EXPORT_SYMBOL(s3c2410_dma_set_buffdone_f
+ * source: S3C2410_DMASRC_HW: source is hardware
+ * S3C2410_DMASRC_MEM: source is memory
+ *
+- * hwcfg: the value for xxxSTCn register,
+- * bit 0: 0=increment pointer, 1=leave pointer
+- * bit 1: 0=source is AHB, 1=source is APB
+- *
+ * devaddr: physical address of the source
+ */
+
+ int s3c2410_dma_devconfig(int channel,
+ enum s3c2410_dmasrc source,
+- int hwcfg,
+ unsigned long devaddr)
+ {
+- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
++ unsigned int hwcfg;
+
+ if (chan == NULL)
+ return -EINVAL;
+
+- pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
+- __func__, (int)source, hwcfg, devaddr);
++ pr_debug("%s: source=%d, devaddr=%08lx\n",
++ __func__, (int)source, devaddr);
+
+ chan->source = source;
+ chan->dev_addr = devaddr;
+- chan->hw_cfg = hwcfg;
++
++ switch (chan->req_ch) {
++ case DMACH_XD0:
++ case DMACH_XD1:
++ hwcfg = 0; /* AHB */
++ break;
++
++ default:
++ hwcfg = S3C2410_DISRCC_APB;
++ }
++
++ /* always assume our peripheral desintation is a fixed
++ * address in memory. */
++ hwcfg |= S3C2410_DISRCC_INC;
+
+ switch (source) {
+ case S3C2410_DMASRC_HW:
+@@ -1219,7 +1196,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig);
+
+ int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst)
+ {
+- struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
++ struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
+
+ if (chan == NULL)
+ return -EINVAL;
+@@ -1278,8 +1255,8 @@ static int s3c2410_dma_resume(struct sys
+
+ printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
+
+- s3c2410_dma_config(no, cp->xfer_unit, cp->dcon);
+- s3c2410_dma_devconfig(no, cp->source, cp->hw_cfg, cp->dev_addr);
++ s3c2410_dma_config(no, cp->xfer_unit);
++ s3c2410_dma_devconfig(no, cp->source, cp->dev_addr);
+
+ /* re-select the dma source for this channel */
+
+@@ -1476,7 +1453,8 @@ static struct s3c2410_dma_chan *s3c2410_
+ found:
+ dmach = &s3c2410_chans[ch];
+ dmach->map = ch_map;
+- dma_chan_map[channel] = dmach;
++ dmach->req_ch = channel;
++ s3c_dma_chan_map[channel] = dmach;
+
+ /* select the channel */
+
+--- a/arch/arm/plat-s3c24xx/include/plat/dma.h
++++ /dev/null
+@@ -1,82 +0,0 @@
+-/* linux/include/asm-arm/plat-s3c24xx/dma.h
+- *
+- * Copyright (C) 2006 Simtec Electronics
+- * Ben Dooks <ben@simtec.co.uk>
+- *
+- * Samsung S3C24XX DMA support
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+-*/
+-
+-extern struct sysdev_class dma_sysclass;
+-extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
+-
+-#define DMA_CH_VALID (1<<31)
+-#define DMA_CH_NEVER (1<<30)
+-
+-struct s3c24xx_dma_addr {
+- unsigned long from;
+- unsigned long to;
+-};
+-
+-/* struct s3c24xx_dma_map
+- *
+- * this holds the mapping information for the channel selected
+- * to be connected to the specified device
+-*/
+-
+-struct s3c24xx_dma_map {
+- const char *name;
+- struct s3c24xx_dma_addr hw_addr;
+-
+- unsigned long channels[S3C2410_DMA_CHANNELS];
+- unsigned long channels_rx[S3C2410_DMA_CHANNELS];
+-};
+-
+-struct s3c24xx_dma_selection {
+- struct s3c24xx_dma_map *map;
+- unsigned long map_size;
+- unsigned long dcon_mask;
+-
+- void (*select)(struct s3c2410_dma_chan *chan,
+- struct s3c24xx_dma_map *map);
+-
+- void (*direction)(struct s3c2410_dma_chan *chan,
+- struct s3c24xx_dma_map *map,
+- enum s3c2410_dmasrc dir);
+-};
+-
+-extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
+-
+-/* struct s3c24xx_dma_order_ch
+- *
+- * channel map for one of the `enum dma_ch` dma channels. the list
+- * entry contains a set of low-level channel numbers, orred with
+- * DMA_CH_VALID, which are checked in the order in the array.
+-*/
+-
+-struct s3c24xx_dma_order_ch {
+- unsigned int list[S3C2410_DMA_CHANNELS]; /* list of channels */
+- unsigned int flags; /* flags */
+-};
+-
+-/* struct s3c24xx_dma_order
+- *
+- * information provided by either the core or the board to give the
+- * dma system a hint on how to allocate channels
+-*/
+-
+-struct s3c24xx_dma_order {
+- struct s3c24xx_dma_order_ch channels[DMACH_MAX];
+-};
+-
+-extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
+-
+-/* DMA init code, called from the cpu support code */
+-
+-extern int s3c2410_dma_init(void);
+-
+-extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
+- unsigned int stride);
+--- /dev/null
++++ b/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
+@@ -0,0 +1,84 @@
++/* linux/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
++ *
++ * Copyright (C) 2006 Simtec Electronics
++ * Ben Dooks <ben@simtec.co.uk>
++ *
++ * Samsung S3C24XX DMA support
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++#include <plat/dma-core.h>
++
++extern struct sysdev_class dma_sysclass;
++extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
++
++#define DMA_CH_VALID (1<<31)
++#define DMA_CH_NEVER (1<<30)
++
++struct s3c24xx_dma_addr {
++ unsigned long from;
++ unsigned long to;
++};
++
++/* struct s3c24xx_dma_map
++ *
++ * this holds the mapping information for the channel selected
++ * to be connected to the specified device
++*/
++
++struct s3c24xx_dma_map {
++ const char *name;
++ struct s3c24xx_dma_addr hw_addr;
++
++ unsigned long channels[S3C_DMA_CHANNELS];
++ unsigned long channels_rx[S3C_DMA_CHANNELS];
++};
++
++struct s3c24xx_dma_selection {
++ struct s3c24xx_dma_map *map;
++ unsigned long map_size;
++ unsigned long dcon_mask;
++
++ void (*select)(struct s3c2410_dma_chan *chan,
++ struct s3c24xx_dma_map *map);
++
++ void (*direction)(struct s3c2410_dma_chan *chan,
++ struct s3c24xx_dma_map *map,
++ enum s3c2410_dmasrc dir);
++};
++
++extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
++
++/* struct s3c24xx_dma_order_ch
++ *
++ * channel map for one of the `enum dma_ch` dma channels. the list
++ * entry contains a set of low-level channel numbers, orred with
++ * DMA_CH_VALID, which are checked in the order in the array.
++*/
++
++struct s3c24xx_dma_order_ch {
++ unsigned int list[S3C_DMA_CHANNELS]; /* list of channels */
++ unsigned int flags; /* flags */
++};
++
++/* struct s3c24xx_dma_order
++ *
++ * information provided by either the core or the board to give the
++ * dma system a hint on how to allocate channels
++*/
++
++struct s3c24xx_dma_order {
++ struct s3c24xx_dma_order_ch channels[DMACH_MAX];
++};
++
++extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
++
++/* DMA init code, called from the cpu support code */
++
++extern int s3c2410_dma_init(void);
++
++extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
++ unsigned int stride);
+--- /dev/null
++++ b/arch/arm/plat-s3c24xx/include/plat/regs-dma.h
+@@ -0,0 +1,145 @@
++/* arch/arm/mach-s3c2410/include/mach/dma.h
++ *
++ * Copyright (C) 2003,2004,2006 Simtec Electronics
++ * Ben Dooks <ben@simtec.co.uk>
++ *
++ * Samsung S3C24XX DMA support
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++*/
++
++/* DMA Register definitions */
++
++#define S3C2410_DMA_DISRC (0x00)
++#define S3C2410_DMA_DISRCC (0x04)
++#define S3C2410_DMA_DIDST (0x08)
++#define S3C2410_DMA_DIDSTC (0x0C)
++#define S3C2410_DMA_DCON (0x10)
++#define S3C2410_DMA_DSTAT (0x14)
++#define S3C2410_DMA_DCSRC (0x18)
++#define S3C2410_DMA_DCDST (0x1C)
++#define S3C2410_DMA_DMASKTRIG (0x20)
++#define S3C2412_DMA_DMAREQSEL (0x24)
++#define S3C2443_DMA_DMAREQSEL (0x24)
++
++#define S3C2410_DISRCC_INC (1<<0)
++#define S3C2410_DISRCC_APB (1<<1)
++
++#define S3C2410_DMASKTRIG_STOP (1<<2)
++#define S3C2410_DMASKTRIG_ON (1<<1)
++#define S3C2410_DMASKTRIG_SWTRIG (1<<0)
++
++#define S3C2410_DCON_DEMAND (0<<31)
++#define S3C2410_DCON_HANDSHAKE (1<<31)
++#define S3C2410_DCON_SYNC_PCLK (0<<30)
++#define S3C2410_DCON_SYNC_HCLK (1<<30)
++
++#define S3C2410_DCON_INTREQ (1<<29)
++
++#define S3C2410_DCON_CH0_XDREQ0 (0<<24)
++#define S3C2410_DCON_CH0_UART0 (1<<24)
++#define S3C2410_DCON_CH0_SDI (2<<24)
++#define S3C2410_DCON_CH0_TIMER (3<<24)
++#define S3C2410_DCON_CH0_USBEP1 (4<<24)
++
++#define S3C2410_DCON_CH1_XDREQ1 (0<<24)
++#define S3C2410_DCON_CH1_UART1 (1<<24)
++#define S3C2410_DCON_CH1_I2SSDI (2<<24)
++#define S3C2410_DCON_CH1_SPI (3<<24)
++#define S3C2410_DCON_CH1_USBEP2 (4<<24)
++
++#define S3C2410_DCON_CH2_I2SSDO (0<<24)
++#define S3C2410_DCON_CH2_I2SSDI (1<<24)
++#define S3C2410_DCON_CH2_SDI (2<<24)
++#define S3C2410_DCON_CH2_TIMER (3<<24)
++#define S3C2410_DCON_CH2_USBEP3 (4<<24)
++
++#define S3C2410_DCON_CH3_UART2 (0<<24)
++#define S3C2410_DCON_CH3_SDI (1<<24)
++#define S3C2410_DCON_CH3_SPI (2<<24)
++#define S3C2410_DCON_CH3_TIMER (3<<24)
++#define S3C2410_DCON_CH3_USBEP4 (4<<24)
++
++#define S3C2410_DCON_SRCSHIFT (24)
++#define S3C2410_DCON_SRCMASK (7<<24)
++
++#define S3C2410_DCON_BYTE (0<<20)
++#define S3C2410_DCON_HALFWORD (1<<20)
++#define S3C2410_DCON_WORD (2<<20)
++
++#define S3C2410_DCON_AUTORELOAD (0<<22)
++#define S3C2410_DCON_NORELOAD (1<<22)
++#define S3C2410_DCON_HWTRIG (1<<23)
++
++#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
++#define S3C2440_DIDSTC_CHKINT (1<<2)
++
++#define S3C2440_DCON_CH0_I2SSDO (5<<24)
++#define S3C2440_DCON_CH0_PCMIN (6<<24)
++
++#define S3C2440_DCON_CH1_PCMOUT (5<<24)
++#define S3C2440_DCON_CH1_SDI (6<<24)
++
++#define S3C2440_DCON_CH2_PCMIN (5<<24)
++#define S3C2440_DCON_CH2_MICIN (6<<24)
++
++#define S3C2440_DCON_CH3_MICIN (5<<24)
++#define S3C2440_DCON_CH3_PCMOUT (6<<24)
++#endif
++
++#ifdef CONFIG_CPU_S3C2412
++
++#define S3C2412_DMAREQSEL_SRC(x) ((x)<<1)
++
++#define S3C2412_DMAREQSEL_HW (1)
++
++#define S3C2412_DMAREQSEL_SPI0TX S3C2412_DMAREQSEL_SRC(0)
++#define S3C2412_DMAREQSEL_SPI0RX S3C2412_DMAREQSEL_SRC(1)
++#define S3C2412_DMAREQSEL_SPI1TX S3C2412_DMAREQSEL_SRC(2)
++#define S3C2412_DMAREQSEL_SPI1RX S3C2412_DMAREQSEL_SRC(3)
++#define S3C2412_DMAREQSEL_I2STX S3C2412_DMAREQSEL_SRC(4)
++#define S3C2412_DMAREQSEL_I2SRX S3C2412_DMAREQSEL_SRC(5)
++#define S3C2412_DMAREQSEL_TIMER S3C2412_DMAREQSEL_SRC(9)
++#define S3C2412_DMAREQSEL_SDI S3C2412_DMAREQSEL_SRC(10)
++#define S3C2412_DMAREQSEL_USBEP1 S3C2412_DMAREQSEL_SRC(13)
++#define S3C2412_DMAREQSEL_USBEP2 S3C2412_DMAREQSEL_SRC(14)
++#define S3C2412_DMAREQSEL_USBEP3 S3C2412_DMAREQSEL_SRC(15)
++#define S3C2412_DMAREQSEL_USBEP4 S3C2412_DMAREQSEL_SRC(16)
++#define S3C2412_DMAREQSEL_XDREQ0 S3C2412_DMAREQSEL_SRC(17)
++#define S3C2412_DMAREQSEL_XDREQ1 S3C2412_DMAREQSEL_SRC(18)
++#define S3C2412_DMAREQSEL_UART0_0 S3C2412_DMAREQSEL_SRC(19)
++#define S3C2412_DMAREQSEL_UART0_1 S3C2412_DMAREQSEL_SRC(20)
++#define S3C2412_DMAREQSEL_UART1_0 S3C2412_DMAREQSEL_SRC(21)
++#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22)
++#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23)
++#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24)
++
++#endif
++
++#define S3C2443_DMAREQSEL_SRC(x) ((x)<<1)
++
++#define S3C2443_DMAREQSEL_HW (1)
++
++#define S3C2443_DMAREQSEL_SPI0TX S3C2443_DMAREQSEL_SRC(0)
++#define S3C2443_DMAREQSEL_SPI0RX S3C2443_DMAREQSEL_SRC(1)
++#define S3C2443_DMAREQSEL_SPI1TX S3C2443_DMAREQSEL_SRC(2)
++#define S3C2443_DMAREQSEL_SPI1RX S3C2443_DMAREQSEL_SRC(3)
++#define S3C2443_DMAREQSEL_I2STX S3C2443_DMAREQSEL_SRC(4)
++#define S3C2443_DMAREQSEL_I2SRX S3C2443_DMAREQSEL_SRC(5)
++#define S3C2443_DMAREQSEL_TIMER S3C2443_DMAREQSEL_SRC(9)
++#define S3C2443_DMAREQSEL_SDI S3C2443_DMAREQSEL_SRC(10)
++#define S3C2443_DMAREQSEL_XDREQ0 S3C2443_DMAREQSEL_SRC(17)
++#define S3C2443_DMAREQSEL_XDREQ1 S3C2443_DMAREQSEL_SRC(18)
++#define S3C2443_DMAREQSEL_UART0_0 S3C2443_DMAREQSEL_SRC(19)
++#define S3C2443_DMAREQSEL_UART0_1 S3C2443_DMAREQSEL_SRC(20)
++#define S3C2443_DMAREQSEL_UART1_0 S3C2443_DMAREQSEL_SRC(21)
++#define S3C2443_DMAREQSEL_UART1_1 S3C2443_DMAREQSEL_SRC(22)
++#define S3C2443_DMAREQSEL_UART2_0 S3C2443_DMAREQSEL_SRC(23)
++#define S3C2443_DMAREQSEL_UART2_1 S3C2443_DMAREQSEL_SRC(24)
++#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25)
++#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26)
++#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27)
++#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28)
++#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29)
+--- a/arch/arm/plat-s3c24xx/Kconfig
++++ b/arch/arm/plat-s3c24xx/Kconfig
+@@ -71,6 +71,7 @@ config PM_SIMTEC
+ config S3C2410_DMA
+ bool "S3C2410 DMA support"
+ depends on ARCH_S3C2410
++ select S3C_DMA
+ help
+ S3C2410 DMA support. This is needed for drivers like sound which
+ use the S3C2410's DMA system to move data to and from the
+--- a/arch/arm/mach-s3c2410/dma.c
++++ b/arch/arm/mach-s3c2410/dma.c
+@@ -17,14 +17,16 @@
+ #include <linux/sysdev.h>
+ #include <linux/serial_core.h>
+
++#include <mach/map.h>
+ #include <mach/dma.h>
+
+ #include <plat/cpu.h>
+-#include <plat/dma.h>
++#include <plat/dma-plat.h>
+
+ #include <plat/regs-serial.h>
+ #include <mach/regs-gpio.h>
+ #include <plat/regs-ac97.h>
++#include <plat/regs-dma.h>
+ #include <mach/regs-mem.h>
+ #include <mach/regs-lcd.h>
+ #include <mach/regs-sdi.h>
+--- a/arch/arm/mach-s3c2440/dma.c
++++ b/arch/arm/mach-s3c2440/dma.c
+@@ -17,14 +17,16 @@
+ #include <linux/sysdev.h>
+ #include <linux/serial_core.h>
+
++#include <mach/map.h>
+ #include <mach/dma.h>
+
+-#include <plat/dma.h>
++#include <plat/dma-plat.h>
+ #include <plat/cpu.h>
+
+ #include <plat/regs-serial.h>
+ #include <mach/regs-gpio.h>
+ #include <plat/regs-ac97.h>
++#include <plat/regs-dma.h>
+ #include <mach/regs-mem.h>
+ #include <mach/regs-lcd.h>
+ #include <mach/regs-sdi.h>
+--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
++++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
+@@ -218,24 +218,17 @@ static int s3c24xx_pcm_prepare(struct sn
+ * sync to pclk, half-word transfers to the IIS-FIFO. */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ s3c2410_dma_devconfig(prtd->params->channel,
+- S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC |
+- S3C2410_DISRCC_APB, prtd->params->dma_addr);
+-
+- s3c2410_dma_config(prtd->params->channel,
+- prtd->params->dma_size,
+- S3C2410_DCON_SYNC_PCLK |
+- S3C2410_DCON_HANDSHAKE);
++ S3C2410_DMASRC_MEM,
++ prtd->params->dma_addr);
+ } else {
+- s3c2410_dma_config(prtd->params->channel,
+- prtd->params->dma_size,
+- S3C2410_DCON_HANDSHAKE |
+- S3C2410_DCON_SYNC_PCLK);
+-
+ s3c2410_dma_devconfig(prtd->params->channel,
+- S3C2410_DMASRC_HW, 0x3,
+- prtd->params->dma_addr);
++ S3C2410_DMASRC_HW,
++ prtd->params->dma_addr);
+ }
+
++ s3c2410_dma_config(prtd->params->channel,
++ prtd->params->dma_size);
++
+ /* flush the DMA channel */
+ s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH);
+ prtd->dma_loaded = 0;