diff options
author | Ben Dooks <ben-linux@fluff.org> | 2009-05-18 16:32:29 +0100 |
---|---|---|
committer | Ben Dooks <ben-linux@fluff.org> | 2009-05-18 16:32:29 +0100 |
commit | bcb8a0d6f5e73c61a5290b4faaaa48dfa629e6b0 (patch) | |
tree | 6a4345fe0f908d60f52085b97818be705c62af8e /arch/arm | |
parent | 543899f610799426babb5313682fd9c249e34677 (diff) | |
parent | 0b13406a1f1928ec71e81dde52cb62d72ffd28ef (diff) |
[ARM] S3C: Merge next-s3c64xx-dma2 into for-rmk-devel
Merge branch 'next-s3c64xx-dma2' into for-rmk-devel
Conflicts:
arch/arm/plat-s3c64xx/Makefile
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/include/asm/hardware/pl080.h | 138 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/dma.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-s3c2410/include/mach/dma.h | 265 | ||||
-rw-r--r-- | arch/arm/mach-s3c2412/dma.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-s3c2440/dma.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-s3c2443/dma.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-s3c6400/include/mach/dma.h | 59 | ||||
-rw-r--r-- | arch/arm/plat-s3c/Kconfig | 7 | ||||
-rw-r--r-- | arch/arm/plat-s3c/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/plat-s3c/dma.c | 86 | ||||
-rw-r--r-- | arch/arm/plat-s3c/include/plat/dma-core.h | 22 | ||||
-rw-r--r-- | arch/arm/plat-s3c/include/plat/dma.h | 127 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/dma.c | 151 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/include/plat/dma-plat.h (renamed from arch/arm/plat-s3c24xx/include/plat/dma.h) | 12 | ||||
-rw-r--r-- | arch/arm/plat-s3c24xx/include/plat/regs-dma.h | 145 | ||||
-rw-r--r-- | arch/arm/plat-s3c64xx/Kconfig | 4 | ||||
-rw-r--r-- | arch/arm/plat-s3c64xx/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/plat-s3c64xx/dma.c | 722 | ||||
-rw-r--r-- | arch/arm/plat-s3c64xx/include/plat/dma-plat.h | 70 |
20 files changed, 1468 insertions, 363 deletions
diff --git a/arch/arm/include/asm/hardware/pl080.h b/arch/arm/include/asm/hardware/pl080.h new file mode 100644 index 00000000000..6a6c66be7f6 --- /dev/null +++ b/arch/arm/include/asm/hardware/pl080.h @@ -0,0 +1,138 @@ +/* arch/arm/include/asm/hardware/pl080.h + * + * Copyright 2008 Openmoko, Inc. + * Copyright 2008 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks <ben@simtec.co.uk> + * + * ARM PrimeCell PL080 DMA controller + * + * 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. +*/ + +/* Note, there are some Samsung updates to this controller block which + * make it not entierly compatible with the PL080 specification from + * ARM. When in doubt, check the Samsung documentation first. + * + * The Samsung defines are PL080S, and add an extra controll register, + * the ability to move more than 2^11 counts of data and some extra + * OneNAND features. +*/ + +#define PL080_INT_STATUS (0x00) +#define PL080_TC_STATUS (0x04) +#define PL080_TC_CLEAR (0x08) +#define PL080_ERR_STATUS (0x0C) +#define PL080_ERR_CLEAR (0x10) +#define PL080_RAW_TC_STATUS (0x14) +#define PL080_RAW_ERR_STATUS (0x18) +#define PL080_EN_CHAN (0x1c) +#define PL080_SOFT_BREQ (0x20) +#define PL080_SOFT_SREQ (0x24) +#define PL080_SOFT_LBREQ (0x28) +#define PL080_SOFT_LSREQ (0x2C) + +#define PL080_CONFIG (0x30) +#define PL080_CONFIG_M2_BE (1 << 2) +#define PL080_CONFIG_M1_BE (1 << 1) +#define PL080_CONFIG_ENABLE (1 << 0) + +#define PL080_SYNC (0x34) + +/* Per channel configuration registers */ + +#define PL008_Cx_STRIDE (0x20) +#define PL080_Cx_BASE(x) ((0x100 + (x * 0x20))) +#define PL080_Cx_SRC_ADDR(x) ((0x100 + (x * 0x20))) +#define PL080_Cx_DST_ADDR(x) ((0x104 + (x * 0x20))) +#define PL080_Cx_LLI(x) ((0x108 + (x * 0x20))) +#define PL080_Cx_CONTROL(x) ((0x10C + (x * 0x20))) +#define PL080_Cx_CONFIG(x) ((0x110 + (x * 0x20))) +#define PL080S_Cx_CONTROL2(x) ((0x110 + (x * 0x20))) +#define PL080S_Cx_CONFIG(x) ((0x114 + (x * 0x20))) + +#define PL080_CH_SRC_ADDR (0x00) +#define PL080_CH_DST_ADDR (0x04) +#define PL080_CH_LLI (0x08) +#define PL080_CH_CONTROL (0x0C) +#define PL080_CH_CONFIG (0x10) +#define PL080S_CH_CONTROL2 (0x10) +#define PL080S_CH_CONFIG (0x14) + +#define PL080_LLI_ADDR_MASK (0x3fffffff << 2) +#define PL080_LLI_ADDR_SHIFT (2) +#define PL080_LLI_LM_AHB2 (1 << 0) + +#define PL080_CONTROL_TC_IRQ_EN (1 << 31) +#define PL080_CONTROL_PROT_MASK (0x7 << 28) +#define PL080_CONTROL_PROT_SHIFT (28) +#define PL080_CONTROL_PROT_SYS (1 << 28) +#define PL080_CONTROL_DST_INCR (1 << 27) +#define PL080_CONTROL_SRC_INCR (1 << 26) +#define PL080_CONTROL_DST_AHB2 (1 << 25) +#define PL080_CONTROL_SRC_AHB2 (1 << 24) +#define PL080_CONTROL_DWIDTH_MASK (0x7 << 21) +#define PL080_CONTROL_DWIDTH_SHIFT (21) +#define PL080_CONTROL_SWIDTH_MASK (0x7 << 18) +#define PL080_CONTROL_SWIDTH_SHIFT (18) +#define PL080_CONTROL_DB_SIZE_MASK (0x7 << 15) +#define PL080_CONTROL_DB_SIZE_SHIFT (15) +#define PL080_CONTROL_SB_SIZE_MASK (0x7 << 12) +#define PL080_CONTROL_SB_SIZE_SHIFT (12) +#define PL080_CONTROL_TRANSFER_SIZE_MASK (0xfff << 0) +#define PL080_CONTROL_TRANSFER_SIZE_SHIFT (0) + +#define PL080_BSIZE_1 (0x0) +#define PL080_BSIZE_4 (0x1) +#define PL080_BSIZE_8 (0x2) +#define PL080_BSIZE_16 (0x3) +#define PL080_BSIZE_32 (0x4) +#define PL080_BSIZE_64 (0x5) +#define PL080_BSIZE_128 (0x6) +#define PL080_BSIZE_256 (0x7) + +#define PL080_WIDTH_8BIT (0x0) +#define PL080_WIDTH_16BIT (0x1) +#define PL080_WIDTH_32BIT (0x2) + +#define PL080_CONFIG_HALT (1 << 18) +#define PL080_CONFIG_ACTIVE (1 << 17) /* RO */ +#define PL080_CONFIG_LOCK (1 << 16) +#define PL080_CONFIG_TC_IRQ_MASK (1 << 15) +#define PL080_CONFIG_ERR_IRQ_MASK (1 << 14) +#define PL080_CONFIG_FLOW_CONTROL_MASK (0x7 << 11) +#define PL080_CONFIG_FLOW_CONTROL_SHIFT (11) +#define PL080_CONFIG_DST_SEL_MASK (0xf << 6) +#define PL080_CONFIG_DST_SEL_SHIFT (6) +#define PL080_CONFIG_SRC_SEL_MASK (0xf << 1) +#define PL080_CONFIG_SRC_SEL_SHIFT (1) +#define PL080_CONFIG_ENABLE (1 << 0) + +#define PL080_FLOW_MEM2MEM (0x0) +#define PL080_FLOW_MEM2PER (0x1) +#define PL080_FLOW_PER2MEM (0x2) +#define PL080_FLOW_SRC2DST (0x3) +#define PL080_FLOW_SRC2DST_DST (0x4) +#define PL080_FLOW_MEM2PER_PER (0x5) +#define PL080_FLOW_PER2MEM_PER (0x6) +#define PL080_FLOW_SRC2DST_SRC (0x7) + +/* DMA linked list chain structure */ + +struct pl080_lli { + u32 src_addr; + u32 dst_addr; + u32 next_lli; + u32 control0; +}; + +struct pl080s_lli { + u32 src_addr; + u32 dst_addr; + u32 next_lli; + u32 control0; + u32 control1; +}; + diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index 440c014e24b..dbf96e60d99 100644 --- 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> diff --git a/arch/arm/mach-s3c2410/include/mach/dma.h b/arch/arm/mach-s3c2410/include/mach/dma.h index 13358ce2128..c3a2629e0de 100644 --- 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 */ @@ -139,17 +112,14 @@ enum s3c2410_chan_op { /* 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 +131,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 +162,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 +192,6 @@ 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) - #endif /* __ASM_ARCH_DMA_H */ diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c index 9e3478506c6..f8d16fc10bc 100644 --- a/arch/arm/mach-s3c2412/dma.c +++ b/arch/arm/mach-s3c2412/dma.c @@ -20,12 +20,13 @@ #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> diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c index 69b6cf34df4..e08e081430f 100644 --- 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> diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c index 8430e582918..397f3b5c0b4 100644 --- a/arch/arm/mach-s3c2443/dma.c +++ b/arch/arm/mach-s3c2443/dma.c @@ -20,12 +20,13 @@ #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> diff --git a/arch/arm/mach-s3c6400/include/mach/dma.h b/arch/arm/mach-s3c6400/include/mach/dma.h index 9771ac2cb07..1067619f0ba 100644 --- a/arch/arm/mach-s3c6400/include/mach/dma.h +++ b/arch/arm/mach-s3c6400/include/mach/dma.h @@ -11,6 +11,63 @@ #ifndef __ASM_ARCH_DMA_H #define __ASM_ARCH_DMA_H __FILE__ -/* currently nothing here, placeholder */ +#define S3C_DMA_CHANNELS (16) + +/* see mach-s3c2410/dma.h for notes on dma channel numbers */ + +/* Note, for the S3C64XX architecture we keep the DMACH_ + * defines in the order they are allocated to [S]DMA0/[S]DMA1 + * so that is easy to do DHACH_ -> DMA controller conversion + */ +enum dma_ch { + /* DMA0/SDMA0 */ + DMACH_UART0 = 0, + DMACH_UART0_SRC2, + DMACH_UART1, + DMACH_UART1_SRC2, + DMACH_UART2, + DMACH_UART2_SRC2, + DMACH_UART3, + DMACH_UART3_SRC2, + DMACH_PCM0_TX, + DMACH_PCM0_RX, + DMACH_I2S0_OUT, + DMACH_I2S0_IN, + DMACH_SPI0_TX, + DMACH_SPI0_RX, + DMACH_HSI_I2SV40_TX, + DMACH_HSI_I2SV40_RX, + + /* DMA1/SDMA1 */ + DMACH_PCM1_TX = 16, + DMACH_PCM1_RX, + DMACH_I2S1_OUT, + DMACH_I2S1_IN, + DMACH_SPI1_TX, + DMACH_SPI1_RX, + DMACH_AC97_PCMOUT, + DMACH_AC97_PCMIN, + DMACH_AC97_MICIN, + DMACH_PWM, + DMACH_IRDA, + DMACH_EXTERNAL, + DMACH_RES1, + DMACH_RES2, + DMACH_SECURITY_RX, /* SDMA1 only */ + DMACH_SECURITY_TX, /* SDMA1 only */ + DMACH_MAX /* the end */ +}; + +static __inline__ int s3c_dma_has_circular(void) +{ + /* we will be supporting ciruclar buffers as soon as we have DMA + * engine support. + */ + return 1; +} + +#define S3C2410_DMAF_CIRCULAR (1 << 0) + +#include <plat/dma.h> #endif /* __ASM_ARCH_IRQ_H */ diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index 140391587c3..935c7558469 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig @@ -159,6 +159,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 diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile index 061e20458e8..610651455a7 100644 --- 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 diff --git a/arch/arm/plat-s3c/dma.c b/arch/arm/plat-s3c/dma.c new file mode 100644 index 00000000000..c9db75c06af --- /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); diff --git a/arch/arm/plat-s3c/include/plat/dma-core.h b/arch/arm/plat-s3c/include/plat/dma-core.h new file mode 100644 index 00000000000..32ff2a92cb3 --- /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[]; + + diff --git a/arch/arm/plat-s3c/include/plat/dma.h b/arch/arm/plat-s3c/include/plat/dma.h new file mode 100644 index 00000000000..34dba98f08e --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/dma.h @@ -0,0 +1,127 @@ +/* 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); + + diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index 2c8a2f5d75f..5b0bc914f58 100644 --- 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 diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index aee2aeb46c6..b07fec01ab4 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/ |