Commit bcb8a0d6 authored by Ben Dooks's avatar Ben Dooks

[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
parents 543899f6 0b13406a
/* 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;
};
...@@ -17,14 +17,16 @@ ...@@ -17,14 +17,16 @@
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <mach/map.h>
#include <mach/dma.h> #include <mach/dma.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/dma.h> #include <plat/dma-plat.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <plat/regs-ac97.h> #include <plat/regs-ac97.h>
#include <plat/regs-dma.h>
#include <mach/regs-mem.h> #include <mach/regs-mem.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/regs-sdi.h> #include <mach/regs-sdi.h>
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Copyright (C) 2003,2004,2006 Simtec Electronics * Copyright (C) 2003,2004,2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk> * 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 * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
#ifndef __ASM_ARCH_DMA_H #ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H __FILE__ #define __ASM_ARCH_DMA_H __FILE__
#include <plat/dma.h>
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <mach/hardware.h>
#define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */ #define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */
...@@ -55,9 +55,9 @@ enum dma_ch { ...@@ -55,9 +55,9 @@ enum dma_ch {
/* we have 4 dma channels */ /* we have 4 dma channels */
#ifndef CONFIG_CPU_S3C2443 #ifndef CONFIG_CPU_S3C2443
#define S3C2410_DMA_CHANNELS (4) #define S3C_DMA_CHANNELS (4)
#else #else
#define S3C2410_DMA_CHANNELS (6) #define S3C_DMA_CHANNELS (6)
#endif #endif
/* types */ /* types */
...@@ -68,7 +68,6 @@ enum s3c2410_dma_state { ...@@ -68,7 +68,6 @@ enum s3c2410_dma_state {
S3C2410_DMA_PAUSED S3C2410_DMA_PAUSED
}; };
/* enum s3c2410_dma_loadst /* enum s3c2410_dma_loadst
* *
* This represents the state of the DMA engine, wrt to the loaded / running * This represents the state of the DMA engine, wrt to the loaded / running
...@@ -104,32 +103,6 @@ enum s3c2410_dma_loadst { ...@@ -104,32 +103,6 @@ enum s3c2410_dma_loadst {
S3C2410_DMALOAD_1LOADED_1RUNNING, 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 */ /* flags */
...@@ -139,17 +112,14 @@ enum s3c2410_chan_op { ...@@ -139,17 +112,14 @@ enum s3c2410_chan_op {
/* dma buffer */ /* dma buffer */
struct s3c2410_dma_client { struct s3c2410_dma_buf;
char *name;
};
/* s3c2410_dma_buf_s /* s3c2410_dma_buf
* *
* internally used buffer structure to describe a queued or running * internally used buffer structure to describe a queued or running
* buffer. * buffer.
*/ */
struct s3c2410_dma_buf;
struct s3c2410_dma_buf { struct s3c2410_dma_buf {
struct s3c2410_dma_buf *next; struct s3c2410_dma_buf *next;
int magic; /* magic */ int magic; /* magic */
...@@ -161,20 +131,6 @@ struct s3c2410_dma_buf { ...@@ -161,20 +131,6 @@ struct s3c2410_dma_buf {
/* [1] is this updated for both recv/send modes? */ /* [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 { struct s3c2410_dma_stats {
unsigned long loads; unsigned long loads;
unsigned long timeout_longest; unsigned long timeout_longest;
...@@ -206,10 +162,10 @@ struct s3c2410_dma_chan { ...@@ -206,10 +162,10 @@ struct s3c2410_dma_chan {
/* channel configuration */ /* channel configuration */
enum s3c2410_dmasrc source; enum s3c2410_dmasrc source;
enum dma_ch req_ch;
unsigned long dev_addr; unsigned long dev_addr;
unsigned long load_timeout; unsigned long load_timeout;
unsigned int flags; /* channel flags */ unsigned int flags; /* channel flags */
unsigned int hw_cfg; /* last hw config */
struct s3c24xx_dma_map *map; /* channel hw maps */ struct s3c24xx_dma_map *map; /* channel hw maps */
...@@ -236,213 +192,6 @@ struct s3c2410_dma_chan { ...@@ -236,213 +192,6 @@ struct s3c2410_dma_chan {
struct sys_device dev; 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; 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 */ #endif /* __ASM_ARCH_DMA_H */
...@@ -20,12 +20,13 @@ ...@@ -20,12 +20,13 @@
#include <mach/dma.h> #include <mach/dma.h>
#include <plat/dma.h> #include <plat/dma-plat.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <plat/regs-ac97.h> #include <plat/regs-ac97.h>
#include <plat/regs-dma.h>
#include <mach/regs-mem.h> #include <mach/regs-mem.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/regs-sdi.h> #include <mach/regs-sdi.h>
......
...@@ -17,14 +17,16 @@ ...@@ -17,14 +17,16 @@
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <mach/map.h>
#include <mach/dma.h> #include <mach/dma.h>
#include <plat/dma.h> #include <plat/dma-plat.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <plat/regs-ac97.h> #include <plat/regs-ac97.h>
#include <plat/regs-dma.h>
#include <mach/regs-mem.h> #include <mach/regs-mem.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/regs-sdi.h> #include <mach/regs-sdi.h>
......
...@@ -20,12 +20,13 @@ ...@@ -20,12 +20,13 @@
#include <mach/dma.h> #include <mach/dma.h>
#include <plat/dma.h> #include <plat/dma-plat.h>
#include <plat/cpu.h> #include <plat/cpu.h>
#include <plat/regs-serial.h> #include <plat/regs-serial.h>
#include <mach/regs-gpio.h> #include <mach/regs-gpio.h>
#include <plat/regs-ac97.h> #include <plat/regs-ac97.h>
#include <plat/regs-dma.h>
#include <mach/regs-mem.h> #include <mach/regs-mem.h>
#include <mach/regs-lcd.h> #include <mach/regs-lcd.h>
#include <mach/regs-sdi.h> #include <mach/regs-sdi.h>
......
...@@ -11,6 +11,63 @@ ...@@ -11,6 +11,63 @@
#ifndef __ASM_ARCH_DMA_H #ifndef __ASM_ARCH_DMA_H
#define __ASM_ARCH_DMA_H __FILE__ #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 */ #endif /* __ASM_ARCH_IRQ_H */
...@@ -159,6 +159,13 @@ config S3C_GPIO_CFG_S3C64XX ...@@ -159,6 +159,13 @@ config S3C_GPIO_CFG_S3C64XX
Internal configuration to enable S3C64XX style GPIO configuration Internal configuration to enable S3C64XX style GPIO configuration
functions. functions.
# DMA
config S3C_DMA
bool
help
Internal configuration for S3C DMA core
# device definitions to compile in # device definitions to compile in
config S3C_DEV_HSMMC config S3C_DEV_HSMMC
......
...@@ -18,6 +18,10 @@ obj-y += pwm-clock.o ...@@ -18,6 +18,10 @@ obj-y += pwm-clock.o
obj-y += gpio.o obj-y += gpio.o
obj-y += gpio-config.o obj-y += gpio-config.o
# DMA support
obj-$(CONFIG_S3C_DMA) += dma.o
# PM support # PM support
obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_PM) += pm.o
......
/* 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);
/* 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[];
/* 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);
...@@ -71,6 +71,7 @@ config PM_SIMTEC ...@@ -71,6 +71,7 @@ config PM_SIMTEC
config S3C2410_DMA config S3C2410_DMA
bool "S3C2410 DMA support" bool "S3C2410 DMA support"
depends on ARCH_S3C2410 depends on ARCH_S3C2410
select S3C_DMA
help help
S3C2410 DMA support. This is needed for drivers like sound which S3C2410 DMA support. This is needed for drivers like sound which
use the S3C2410's DMA system to move data to and from the use the S3C2410's DMA system to move data to and from the
......
...@@ -31,10 +31,10 @@ ...@@ -31,10 +31,10 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/dma.h> #include <mach/dma.h>
#include <mach/map.h> #include <mach/map.h>
#include <plat/dma.h> #include <plat/dma-plat.h>
#include <plat/regs-dma.h>
/* io map for dma */ /* io map for dma */
static void __iomem *dma_base; static void __iomem *dma_base;
...@@ -44,8 +44,6 @@ static int dma_channels; ...@@ -44,8 +44,6 @@ static int dma_channels;
static struct s3c24xx_dma_selection dma_sel; static struct s3c24xx_dma_selection dma_sel;
/* dma channel state information */
struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
/* debugging functions */ /* debugging functions */
...@@ -135,21 +133,6 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan) ...@@ -135,21 +133,6 @@ dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
#define dbg_showchan(chan) do { } while(0) #define dbg_showchan(chan) do { } while(0)
#endif /* CONFIG_S3C2410_DMA_DEBUG */ #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 /* s3c2410_dma_stats_timeout
* *
* Update DMA stats from timeout info * Update DMA stats from timeout info
...@@ -214,8 +197,6 @@ s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line) ...@@ -214,8 +197,6 @@ s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
return 0; return 0;
} }
/* s3c2410_dma_loadbuffer /* s3c2410_dma_loadbuffer
* *
* load a buffer, and update the channel state * load a buffer, and update the channel state
...@@ -453,7 +434,7 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan) ...@@ -453,7 +434,7 @@ s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
int s3c2410_dma_enqueue(unsigned int channel, void *id, int s3c2410_dma_enqueue(unsigned int channel, void *id,
dma_addr_t data, int size) 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; struct s3c2410_dma_buf *buf;
unsigned long flags; unsigned long flags;
...@@ -804,7 +785,7 @@ EXPORT_SYMBOL(s3c2410_dma_request); ...@@ -804,7 +785,7 @@ EXPORT_SYMBOL(s3c2410_dma_request);
int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) 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; unsigned long flags;
if (chan == NULL) if (chan == NULL)
...@@ -836,7 +817,7 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) ...@@ -836,7 +817,7 @@ int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client)
chan->irq_claimed = 0; chan->irq_claimed = 0;
if (!(channel & DMACH_LOW_LEVEL)) if (!(channel & DMACH_LOW_LEVEL))
dma_chan_map[channel] = NULL; s3c_dma_chan_map[channel] = NULL;
local_irq_restore(flags); local_irq_restore(flags);
...@@ -995,7 +976,7 @@ static int s3c2410_dma_started(struct s3c2410_dma_chan *chan) ...@@ -995,7 +976,7 @@ static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)
int int
s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) 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) if (chan == NULL)
return -EINVAL; return -EINVAL;
...@@ -1038,14 +1019,13 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl); ...@@ -1038,14 +1019,13 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl);
/* s3c2410_dma_config /* s3c2410_dma_config
* *
* xfersize: size of unit in bytes (1,2,4) * xfersize: size of unit in bytes (1,2,4)
* dcon: base value of the DCONx register
*/ */
int s3c2410_dma_config(unsigned int channel, int s3c2410_dma_config(unsigned int channel,
int xferunit, int xferunit)
int dcon)
{ {
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", pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
__func__, channel, xferunit, dcon); __func__, channel, xferunit, dcon);
...@@ -1055,10 +1035,33 @@ int s3c2410_dma_config(unsigned int channel, ...@@ -1055,10 +1035,33 @@ int s3c2410_dma_config(unsigned int channel,
pr_debug("%s: Initial dcon is %08x\n", __func__, dcon); 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); 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) { switch (xferunit) {
case 1: case 1:
dcon |= S3C2410_DCON_BYTE; dcon |= S3C2410_DCON_BYTE;
...@@ -1090,58 +1093,6 @@ int s3c2410_dma_config(unsigned int channel, ...@@ -1090,58 +1093,6 @@ int s3c2410_dma_config(unsigned int channel,
EXPORT_SYMBOL(s3c2410_dma_config); EXPORT_SYMBOL(s3c2410_dma_config);
int s3c2410_dma_setflags(unsigned int channel, unsigned int flags)
{
struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
if (chan == NULL)
return -EINVAL;
pr_debug("%s: chan=%p, flags=%08x\n", __func__, chan, flags);
chan->flags = flags;
return 0;
}
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);
/* s3c2410_dma_devconfig /* s3c2410_dma_devconfig
* *
...@@ -1150,29 +1101,38 @@ EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); ...@@ -1150,29 +1101,38 @@ EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
* source: S3C2410_DMASRC_HW: source is hardware * source: S3C2410_DMASRC_HW: source is hardware
* S3C2410_DMASRC_MEM: source is memory * 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 * devaddr: physical address of the source
*/ */
int s3c2410_dma_devconfig(int channel, int s3c2410_dma_devconfig(int channel,
enum s3c2410_dmasrc source, enum s3c2410_dmasrc source,
int hwcfg,
unsigned long devaddr) 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) if (chan == NULL)
return -EINVAL; return -EINVAL;
pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n", pr_debug("%s: source=%d, devaddr=%08lx\n",
__func__, (int)source, hwcfg, devaddr); __func__, (int)source, devaddr);
chan->source = source; chan->source = source;
chan->dev_addr = devaddr; 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) { switch (source) {
case S3C2410_DMASRC_HW: case S3C2410_DMASRC_HW:
...@@ -1219,7 +1179,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig); ...@@ -1219,7 +1179,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig);
int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst) 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) if (chan == NULL)
return -EINVAL; return -EINVAL;
...@@ -1278,8 +1238,8 @@ static int s3c2410_dma_resume(struct sys_device *dev) ...@@ -1278,8 +1238,8 @@ static int s3c2410_dma_resume(struct sys_device *dev)
printk(KERN_INFO "dma%d: restoring configuration\n", cp->number); printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
s3c2410_dma_config(no, cp->xfer_unit, cp->dcon); s3c2410_dma_config(no, cp->xfer_unit);
s3c2410_dma_devconfig(no, cp->source, cp->hw_cfg, cp->dev_addr); s3c2410_dma_devconfig(no, cp->source, cp->dev_addr);
/* re-select the dma source for this channel */ /* re-select the dma source for this channel */
...@@ -1476,7 +1436,8 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel) ...@@ -1476,7 +1436,8 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
found: found:
dmach = &s3c2410_chans[ch]; dmach = &s3c2410_chans[ch];
dmach->map = ch_map; dmach->map = ch_map;
dma_chan_map[channel] = dmach; dmach->req_ch = channel;
s3c_dma_chan_map[channel] = dmach;
/* select the channel */ /* select the channel */
......
/* linux/include/asm-arm/plat-s3c24xx/dma.h /* linux/arch/arm/plat-s3c24xx/include/plat/dma-plat.h
* *
* Copyright (C) 2006 Simtec Electronics * Copyright (C) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk> * Ben Dooks <ben@simtec.co.uk>
...@@ -10,8 +10,10 @@ ...@@ -10,8 +10,10 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <plat/dma-core.h>
extern struct sysdev_class dma_sysclass; extern struct sysdev_class dma_sysclass;
extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
#define DMA_CH_VALID (1<<31) #define DMA_CH_VALID (1<<31)
#define DMA_CH_NEVER (1<<30) #define DMA_CH_NEVER (1<<30)
...@@ -31,8 +33,8 @@ struct s3c24xx_dma_map { ...@@ -31,8 +33,8 @@ struct s3c24xx_dma_map {
const char *name; const char *name;
struct s3c24xx_dma_addr hw_addr; struct s3c24xx_dma_addr hw_addr;
unsigned long channels[S3C2410_DMA_CHANNELS]; unsigned long channels[S3C_DMA_CHANNELS];
unsigned long channels_rx[S3C2410_DMA_CHANNELS]; unsigned long channels_rx[S3C_DMA_CHANNELS];
}; };
struct s3c24xx_dma_selection { struct s3c24xx_dma_selection {
...@@ -58,7 +60,7 @@ extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); ...@@ -58,7 +60,7 @@ extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
*/ */
struct s3c24xx_dma_order_ch { struct s3c24xx_dma_order_ch {
unsigned int list[S3C2410_DMA_CHANNELS]; /* list of channels */ unsigned int list[S3C_DMA_CHANNELS]; /* list of channels */
unsigned int flags; /* flags */ unsigned int flags; /* flags */
}; };
......
/* 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)
#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)
...@@ -39,6 +39,10 @@ config CPU_S3C6400_CLOCK ...@@ -39,6 +39,10 @@ config CPU_S3C6400_CLOCK
Common clock support code for the S3C6400 that is shared Common clock support code for the S3C6400 that is shared
by other CPUs in the series, such as the S3C6410. by other CPUs in the series, such as the S3C6410.
config S3C64XX_DMA
bool "S3C64XX DMA"
select S3C_DMA
# platform specific device setup # platform specific device setup
config S3C64XX_SETUP_I2C0 config S3C64XX_SETUP_I2C0
......
...@@ -30,6 +30,10 @@ obj-$(CONFIG_PM) += pm.o ...@@ -30,6 +30,10 @@ obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_PM) += sleep.o obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_PM) += irq-pm.o obj-$(CONFIG_PM) += irq-pm.o
# DMA support
obj-$(CONFIG_S3C64XX_DMA) += dma.o
# Device setup # Device setup
obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
......
This diff is collapsed.
/* linux/arch/arm/plat-s3c64xx/include/plat/dma-plat.h
*
* Copyright 2009 Openmoko, Inc.
* Copyright 2009 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
* http://armlinux.simtec.co.uk/
*
* S3C64XX 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.
*/
#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
struct s3c64xx_dma_buff;
/** s3c64xx_dma_buff - S3C64XX DMA buffer descriptor
* @next: Pointer to next buffer in queue or ring.
* @pw: Client provided identifier
* @lli: Pointer to hardware descriptor this buffer is associated with.
* @lli_dma: Hardare address of the descriptor.
*/
struct s3c64xx_dma_buff {
struct s3c64xx_dma_buff *next;
void *pw;
struct pl080_lli *lli;
dma_addr_t lli_dma;
};
struct s3c64xx_dmac;
struct s3c2410_dma_chan {
unsigned char number; /* number of this dma channel */
unsigned char in_use; /* channel allocated */
unsigned char bit; /* bit for enable/disable/etc */
unsigned char hw_width;
unsigned char peripheral;
unsigned int flags;
enum s3c2410_dmasrc source;
dma_addr_t dev_addr;
struct s3c2410_dma_client *client;
struct s3c64xx_dmac *dmac; /* pointer to controller */
void __iomem *regs;
/* cdriver callbacks */
s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
s3c2410_dma_opfn_t op_fn; /* channel op callback */
/* buffer list and information */
struct s3c64xx_dma_buff *curr; /* current dma buffer */
struct s3c64xx_dma_buff *next; /* next buffer to load */
struct s3c64xx_dma_buff *end; /* end of queue */
/* note, when channel is running in circular mode, curr is the
* first buffer enqueued, end is the last and curr is where the
* last buffer-done event is set-at. The buffers are not freed
* and the last buffer hardware descriptor points back to the
* first.
*/
};
#include <plat/dma-core.h>
...@@ -789,7 +789,7 @@ static void s3cmci_dma_setup(struct s3cmci_host *host, ...@@ -789,7 +789,7 @@ static void s3cmci_dma_setup(struct s3cmci_host *host,
last_source = source; last_source = source;
s3c2410_dma_devconfig(host->dma, source, 3, s3c2410_dma_devconfig(host->dma, source,
host->mem->start + host->sdidata); host->mem->start + host->sdidata);
if (!setup_ok) { if (!setup_ok) {
......
...@@ -218,24 +218,17 @@ static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -218,24 +218,17 @@ static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream)
* sync to pclk, half-word transfers to the IIS-FIFO. */ * sync to pclk, half-word transfers to the IIS-FIFO. */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
s3c2410_dma_devconfig(prtd->params->channel, s3c2410_dma_devconfig(prtd->params->channel,
S3C2410_DMASRC_MEM, S3C2410_DISRCC_INC | S3C2410_DMASRC_MEM,
S3C2410_DISRCC_APB, prtd->params->dma_addr); prtd->params->dma_addr);
s3c2410_dma_config(prtd->params->channel,
prtd->params->dma_size,
S3C2410_DCON_SYNC_PCLK |
S3C2410_DCON_HANDSHAKE);
} else { } 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_dma_devconfig(prtd->params->channel,
S3C2410_DMASRC_HW, 0x3, S3C2410_DMASRC_HW,
prtd->params->dma_addr); prtd->params->dma_addr);
} }
s3c2410_dma_config(prtd->params->channel,
prtd->params->dma_size);
/* flush the DMA channel */ /* flush the DMA channel */
s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH);
prtd->dma_loaded = 0; prtd->dma_loaded = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment