X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=include%2Fasm-arm%2Farch-s3c2410%2Fdma.h;h=9cae3822a4840e9c05f8584327c0d23650de3a3c;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=ea084c784b25b7e98b4902cf11a61c38f815fe50;hpb=a2c21200f1c81b08cb55e417b68150bba439b646;p=linux-2.6.git diff --git a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h index ea084c784..9cae3822a 100644 --- a/include/asm-arm/arch-s3c2410/dma.h +++ b/include/asm-arm/arch-s3c2410/dma.h @@ -27,7 +27,7 @@ * */ #define MAX_DMA_ADDRESS 0x20000000 -#define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */ +#define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */ /* according to the samsung port, we cannot use the regular @@ -39,131 +39,282 @@ /* we have 4 dma channels */ -#define S3C2410_DMA_CHANNELS (4) +#define S3C2410_DMA_CHANNELS (4) +/* types */ + +typedef enum { + S3C2410_DMA_IDLE, + S3C2410_DMA_RUNNING, + S3C2410_DMA_PAUSED +} s3c2410_dma_state_t; + + +/* s3c2410_dma_loadst_t + * + * This represents the state of the DMA engine, wrt to the loaded / running + * transfers. Since we don't have any way of knowing exactly the state of + * the DMA transfers, we need to know the state to make decisions on wether + * we can + * + * S3C2410_DMA_NONE + * + * There are no buffers loaded (the channel should be inactive) + * + * S3C2410_DMA_1LOADED + * + * There is one buffer loaded, however it has not been confirmed to be + * loaded by the DMA engine. This may be because the channel is not + * yet running, or the DMA driver decided that it was too costly to + * sit and wait for it to happen. + * + * S3C2410_DMA_1RUNNING + * + * The buffer has been confirmed running, and not finisged + * + * S3C2410_DMA_1LOADED_1RUNNING + * + * There is a buffer waiting to be loaded by the DMA engine, and one + * currently running. +*/ + +typedef enum { + S3C2410_DMALOAD_NONE, + S3C2410_DMALOAD_1LOADED, + S3C2410_DMALOAD_1RUNNING, + S3C2410_DMALOAD_1LOADED_1RUNNING, +} s3c2410_dma_loadst_t; + +typedef enum { + S3C2410_RES_OK, + S3C2410_RES_ERR, + S3C2410_RES_ABORT +} s3c2410_dma_buffresult_t; + + +typedef enum s3c2410_dmasrc_e s3c2410_dmasrc_t; + +enum s3c2410_dmasrc_e { + S3C2410_DMASRC_HW, /* source is memory */ + S3C2410_DMASRC_MEM /* source is hardware */ +}; + +/* enum s3c2410_chan_op_e + * + * 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_e { + S3C2410_DMAOP_START, + S3C2410_DMAOP_STOP, + S3C2410_DMAOP_PAUSE, + S3C2410_DMAOP_RESUME, + S3C2410_DMAOP_FLUSH, + S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */ +}; + +typedef enum s3c2410_chan_op_e s3c2410_chan_op_t; + +/* flags */ + +#define S3C2410_DMAF_SLOW (1<<0) /* slow, so don't worry about + * waiting for reloads */ +#define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */ /* dma buffer */ typedef struct s3c2410_dma_buf_s s3c2410_dma_buf_t; +struct s3c2410_dma_client { + char *name; +}; + +typedef struct s3c2410_dma_client s3c2410_dma_client_t; + +/* s3c2410_dma_buf_s + * + * internally used buffer structure to describe a queued or running + * buffer. +*/ + struct s3c2410_dma_buf_s { s3c2410_dma_buf_t *next; - int magic; /* magic */ - int size; /* buffer size in bytes */ - dma_addr_t data; /* start of DMA data */ - dma_addr_t ptr; /* where the DMA got to [1] */ - int ref; - void *id; /* client's id */ - unsigned char no_callback; /* disable callback for buffer */ + int magic; /* magic */ + int size; /* buffer size in bytes */ + dma_addr_t data; /* start of DMA data */ + dma_addr_t ptr; /* where the DMA got to [1] */ + void *id; /* client's id */ }; /* [1] is this updated for both recv/send modes? */ typedef struct s3c2410_dma_chan_s s3c2410_dma_chan_t; -typedef void (*s3c2410_dma_cbfn_t)(s3c2410_dma_chan_t *, void *buf, int size); -typedef void (*s3c2410_dma_enfn_t)(s3c2410_dma_chan_t *, int on); -typedef void (*s3c2410_dma_pausefn_t)(s3c2410_dma_chan_t *, int on); +/* s3c2410_dma_cbfn_t + * + * buffer callback routine type +*/ + +typedef void (*s3c2410_dma_cbfn_t)(s3c2410_dma_chan_t *, void *buf, int size, + s3c2410_dma_buffresult_t result); + +typedef int (*s3c2410_dma_opfn_t)(s3c2410_dma_chan_t *, + s3c2410_chan_op_t ); + +struct s3c2410_dma_stats_s { + unsigned long loads; + unsigned long timeout_longest; + unsigned long timeout_shortest; + unsigned long timeout_avg; + unsigned long timeout_failed; +}; + +typedef struct s3c2410_dma_stats_s s3c2410_dma_stats_t; + +/* struct s3c2410_dma_chan_s + * + * full state information for each DMA channel +*/ struct s3c2410_dma_chan_s { - /* channel state flags */ - unsigned char number; /* number of this dma channel */ - unsigned char in_use; /* channel allocated */ - unsigned char started; /* channel has been started */ - unsigned char stopped; /* channel stopped */ - unsigned char sleeping; - unsigned char xfer_unit; /* size of an transfer */ - unsigned char irq_claimed; + /* channel state flags and information */ + unsigned char number; /* number of this dma channel */ + unsigned char in_use; /* channel allocated */ + unsigned char irq_claimed; /* irq claimed for channel */ + unsigned char irq_enabled; /* irq enabled for channel */ + unsigned char xfer_unit; /* size of an transfer */ + + /* channel state */ + + s3c2410_dma_state_t state; + s3c2410_dma_loadst_t load_state; + s3c2410_dma_client_t *client; + + /* channel configuration */ + s3c2410_dmasrc_t source; + unsigned long dev_addr; + unsigned long load_timeout; + unsigned int flags; /* channel flags */ /* channel's hardware position and configuration */ - unsigned long regs; /* channels registers */ - unsigned int irq; /* channel irq */ - unsigned long addr_reg; /* data address register for buffs */ - unsigned long dcon; /* default value of DCON */ + unsigned long regs; /* channels registers */ + unsigned int irq; /* channel irq */ + unsigned long addr_reg; /* data address register */ + unsigned long dcon; /* default value of DCON */ - /* driver handlers for channel */ - s3c2410_dma_cbfn_t callback_fn; /* callback function for buf-done */ - s3c2410_dma_enfn_t enable_fn; /* channel enable function */ - s3c2410_dma_pausefn_t pause_fn; /* channel pause function */ + /* driver handles */ + s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */ + s3c2410_dma_opfn_t op_fn; /* channel operation callback */ - /* buffer list and information */ - s3c2410_dma_buf_t *curr; /* current dma buffer */ - s3c2410_dma_buf_t *next; /* next buffer to load */ - s3c2410_dma_buf_t *end; /* end of queue */ + /* stats gathering */ + s3c2410_dma_stats_t *stats; + s3c2410_dma_stats_t stats_store; - int queue_count; /* number of items in queue */ - int loaded_count; /* number of loaded buffers */ + /* buffer list and information */ + s3c2410_dma_buf_t *curr; /* current dma buffer */ + s3c2410_dma_buf_t *next; /* next buffer to load */ + s3c2410_dma_buf_t *end; /* end of queue */ }; -/* note, we don't really use dma_deivce_t at the moment */ +/* the currently allocated channel information */ +extern s3c2410_dma_chan_t s3c2410_chans[]; + +/* note, we don't really use dma_device_t at the moment */ typedef unsigned long dma_device_t; -typedef enum s3c2410_dmasrc_e s3c2410_dmasrc_t; +/* functions --------------------------------------------------------------- */ -/* these two defines control the source for the dma channel, - * wether it is from memory or an device +/* s3c2410_dma_request + * + * request a dma channel exclusivley */ -enum s3c2410_dmasrc_e { - S3C2410_DMASRC_HW, /* source is memory */ - S3C2410_DMASRC_MEM /* source is hardware */ -}; +extern int s3c2410_dma_request(dmach_t channel, + s3c2410_dma_client_t *, void *dev); + + +/* s3c2410_dma_ctrl + * + * change the state of the dma channel +*/ + +extern int s3c2410_dma_ctrl(dmach_t channel, s3c2410_chan_op_t op); + +/* s3c2410_dma_setflags + * + * set the channel's flags to a given state +*/ -/* dma control routines */ +extern int s3c2410_dma_setflags(dmach_t channel, + unsigned int flags); -extern int s3c2410_request_dma(dmach_t channel, const char *devid, void *dev); -extern int s3c2410_free_dma(dmach_t channel); -extern int s3c2410_dma_flush_all(dmach_t channel); +/* s3c2410_dma_free + * + * free the dma channel (will also abort any outstanding operations) +*/ -extern int s3c2410_dma_stop(dmach_t channel); -extern int s3c2410_dma_resume(dmach_t channel); +extern int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *); -extern int s3c2410_dma_queue(dmach_t channel, void *id, - dma_addr_t data, int size); +/* 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. +*/ -#define s3c2410_dma_queue_buffer s3c2410_dma_queue +extern int s3c2410_dma_enqueue(dmach_t channel, void *id, + dma_addr_t data, int size); -/* channel configuration */ +/* s3c2410_dma_config + * + * configure the dma channel +*/ extern int s3c2410_dma_config(dmach_t channel, int xferunit, int dcon); +/* s3c2410_dma_devconfig + * + * configure the device we're talking to +*/ + extern int s3c2410_dma_devconfig(int channel, s3c2410_dmasrc_t source, int hwcfg, unsigned long devaddr); -extern int s3c2410_dma_set_enablefn(dmach_t, s3c2410_dma_enfn_t rtn); -extern int s3c2410_dma_set_pausefn(dmach_t, s3c2410_dma_pausefn_t rtn); -extern int s3c2410_dma_set_callbackfn(dmach_t, s3c2410_dma_cbfn_t rtn); +extern int s3c2410_dma_set_opfn(dmach_t, s3c2410_dma_opfn_t rtn); +extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn); -#define s3c2410_dma_set_callback s3c2410_dma_set_callbackfn +/* 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 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 S3C2410_DMASKTRIG_STOP (1<<2) -#define S3C2410_DMASKTRIG_ON (1<<1) +#define S3C2410_DMASKTRIG_STOP (1<<2) +#define S3C2410_DMASKTRIG_ON (1<<1) #define S3C2410_DMASKTRIG_SWTRIG (1<<0) -#define S3C2410_DCOM_DEMAND (0<<31) +#define S3C2410_DCOM_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_INTREQ (1<<29) -#define S3C2410_DCON_SRCSHIFT (24) +#define S3C2410_DCON_SRCSHIFT (24) -#define S3C2410_DCON_BYTE (0<<20) -#define S3C2410_DCON_HALFWORD (1<<20) -#define S3C2410_DCON_WORD (2<<20) +#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_HWTRIG (1<<23) +#define S3C2410_DCON_NORELOAD (1<<22) +#define S3C2410_DCON_HWTRIG (1<<23) #endif /* __ASM_ARCH_DMA_H */