dma.h 5.9 KB
Newer Older
B
Bryan Wu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
/*
 * 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 <asm/semaphore.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

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 short curr_addr_ptr_lo;	/* DMA Current Address Pointer
						   register */
	unsigned short curr_addr_ptr_hi;	/* 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);
155
void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr);
B
Bryan Wu 已提交
156 157 158 159 160 161 162
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);
163
void set_dma_curr_addr(unsigned int channel, unsigned long addr);
B
Bryan Wu 已提交
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190

/* 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);

/* 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);

#endif