/* * File: include/asm-blackfin/simple_bf533_dma.h * Based on: none - original work * Author: LG Soft India * Copyright (C) 2004-2005 Analog Devices Inc. * Created: Tue Sep 21 2004 * Description: This file contains the major Data structures and constants * used for DMA Implementation in BF533 * Modified: * * Bugs: Enter bugs at http://blackfin.uclinux.org/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. * If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _BLACKFIN_DMA_H_ #define _BLACKFIN_DMA_H_ #include <asm/io.h> #include <linux/slab.h> #include <asm/irq.h> #include <asm/signal.h> #include <linux/kernel.h> #include <asm/mach/dma.h> #include <linux/mm.h> #include <linux/interrupt.h> #include <asm/blackfin.h> #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; 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 */ dma_interrupt_t irq_callback; void *data; unsigned int dma_enable_flag; unsigned int loopback_flag; }; /******************************************************************************* * 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, 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); extern int channel2irq(unsigned int channel); extern struct dma_register *dma_io_base_addr[MAX_BLACKFIN_DMA_CHANNEL]; #endif