/* * dma.h - Blackfin DMA defines/structures/etc... * * Copyright 2004-2008 Analog Devices Inc. * Licensed under the GPL-2 or later. */ #ifndef _BLACKFIN_DMA_H_ #define _BLACKFIN_DMA_H_ #include #include #include #include #include #include #include #include #include #define MAX_DMA_ADDRESS PAGE_OFFSET /***************************************************************************** * Generic DMA Declarations * ****************************************************************************/ enum dma_chan_status { DMA_CHANNEL_FREE, DMA_CHANNEL_REQUESTED, DMA_CHANNEL_ENABLED, }; /*------------------------- * config reg bits value *-------------------------*/ #define DATA_SIZE_8 0 #define DATA_SIZE_16 1 #define DATA_SIZE_32 2 #define DMA_FLOW_STOP 0 #define DMA_FLOW_AUTO 1 #define DMA_FLOW_ARRAY 4 #define DMA_FLOW_SMALL 6 #define DMA_FLOW_LARGE 7 #define DIMENSION_LINEAR 0 #define DIMENSION_2D 1 #define DIR_READ 0 #define DIR_WRITE 1 #define INTR_DISABLE 0 #define INTR_ON_BUF 2 #define INTR_ON_ROW 3 #define DMA_NOSYNC_KEEP_DMA_BUF 0 #define DMA_SYNC_RESTART 1 struct dmasg { unsigned long next_desc_addr; unsigned long start_addr; unsigned short cfg; unsigned short x_count; short x_modify; unsigned short y_count; short y_modify; } __attribute__((packed)); struct dma_register { unsigned long next_desc_ptr; /* DMA Next Descriptor Pointer register */ unsigned long start_addr; /* DMA Start address register */ unsigned short cfg; /* DMA Configuration register */ unsigned short dummy1; /* DMA Configuration register */ unsigned long reserved; unsigned short x_count; /* DMA x_count register */ unsigned short dummy2; short x_modify; /* DMA x_modify register */ unsigned short dummy3; unsigned short y_count; /* DMA y_count register */ unsigned short dummy4; short y_modify; /* DMA y_modify register */ unsigned short dummy5; unsigned long curr_desc_ptr; /* DMA Current Descriptor Pointer register */ unsigned long curr_addr_ptr; /* DMA Current Address Pointer register */ unsigned short irq_status; /* DMA irq status register */ unsigned short dummy6; unsigned short peripheral_map; /* DMA peripheral map register */ unsigned short dummy7; unsigned short curr_x_count; /* DMA Current x-count register */ unsigned short dummy8; unsigned long reserved2; unsigned short curr_y_count; /* DMA Current y-count register */ unsigned short dummy9; unsigned long reserved3; }; typedef irqreturn_t(*dma_interrupt_t) (int irq, void *dev_id); struct dma_channel { struct mutex dmalock; const char *device_id; enum dma_chan_status chan_status; struct dma_register *regs; struct dmasg *sg; /* large mode descriptor */ unsigned int ctrl_num; /* controller number */ unsigned int irq; dma_interrupt_t irq_callback; void *data; unsigned int dma_enable_flag; unsigned int loopback_flag; #ifdef CONFIG_PM unsigned short saved_peripheral_map; #endif }; #ifdef CONFIG_PM int blackfin_dma_suspend(void); void blackfin_dma_resume(void); #endif /******************************************************************************* * DMA API's *******************************************************************************/ /* functions to set register mode */ void set_dma_start_addr(unsigned int channel, unsigned long addr); void set_dma_next_desc_addr(unsigned int channel, unsigned long addr); void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr); void set_dma_x_count(unsigned int channel, unsigned short x_count); void set_dma_x_modify(unsigned int channel, short x_modify); void set_dma_y_count(unsigned int channel, unsigned short y_count); void set_dma_y_modify(unsigned int channel, short y_modify); void set_dma_config(unsigned int channel, unsigned short config); unsigned short set_bfin_dma_config(char direction, char flow_mode, char intr_mode, char dma_mode, char width, char syncmode); void set_dma_curr_addr(unsigned int channel, unsigned long addr); /* get curr status for polling */ unsigned short get_dma_curr_irqstat(unsigned int channel); unsigned short get_dma_curr_xcount(unsigned int channel); unsigned short get_dma_curr_ycount(unsigned int channel); unsigned long get_dma_next_desc_ptr(unsigned int channel); unsigned long get_dma_curr_desc_ptr(unsigned int channel); unsigned long get_dma_curr_addr(unsigned int channel); /* set large DMA mode descriptor */ void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg); /* check if current channel is in use */ int dma_channel_active(unsigned int channel); /* common functions must be called in any mode */ void free_dma(unsigned int channel); int dma_channel_active(unsigned int channel); /* check if a channel is in use */ void disable_dma(unsigned int channel); void enable_dma(unsigned int channel); int request_dma(unsigned int channel, const char *device_id); int set_dma_callback(unsigned int channel, dma_interrupt_t callback, void *data); void dma_disable_irq(unsigned int channel); void dma_enable_irq(unsigned int channel); void clear_dma_irqstat(unsigned int channel); void *dma_memcpy(void *dest, const void *src, size_t count); void *safe_dma_memcpy(void *dest, const void *src, size_t count); void blackfin_dma_early_init(void); extern int channel2irq(unsigned int channel); extern struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS]; #endif