blob: 4928e7aa480189c1262b503357d2a8b5a73efb6e [file] [log] [blame]
Bryan Wu1394f032007-05-06 14:50:22 -07001/*
Mike Frysingerb03f2032009-01-07 23:14:38 +08002 * dma.h - Blackfin DMA defines/structures/etc...
Bryan Wu1394f032007-05-06 14:50:22 -07003 *
Mike Frysingerb03f2032009-01-07 23:14:38 +08004 * Copyright 2004-2008 Analog Devices Inc.
5 * Licensed under the GPL-2 or later.
Bryan Wu1394f032007-05-06 14:50:22 -07006 */
7
8#ifndef _BLACKFIN_DMA_H_
9#define _BLACKFIN_DMA_H_
10
Bryan Wu1394f032007-05-06 14:50:22 -070011#include <linux/interrupt.h>
Mike Frysinger4c1ed6a2009-01-07 23:14:38 +080012#include <mach/dma.h>
Bryan Wu1394f032007-05-06 14:50:22 -070013#include <asm/blackfin.h>
Mike Frysinger4c1ed6a2009-01-07 23:14:38 +080014#include <asm/page.h>
Bryan Wu1394f032007-05-06 14:50:22 -070015
16#define MAX_DMA_ADDRESS PAGE_OFFSET
17
18/*****************************************************************************
19* Generic DMA Declarations
20*
21****************************************************************************/
22enum dma_chan_status {
23 DMA_CHANNEL_FREE,
24 DMA_CHANNEL_REQUESTED,
25 DMA_CHANNEL_ENABLED,
26};
27
28/*-------------------------
29 * config reg bits value
30 *-------------------------*/
31#define DATA_SIZE_8 0
32#define DATA_SIZE_16 1
33#define DATA_SIZE_32 2
34
35#define DMA_FLOW_STOP 0
36#define DMA_FLOW_AUTO 1
37#define DMA_FLOW_ARRAY 4
38#define DMA_FLOW_SMALL 6
39#define DMA_FLOW_LARGE 7
40
41#define DIMENSION_LINEAR 0
42#define DIMENSION_2D 1
43
44#define DIR_READ 0
45#define DIR_WRITE 1
46
47#define INTR_DISABLE 0
48#define INTR_ON_BUF 2
49#define INTR_ON_ROW 3
50
Michael Hennerich2047e402008-01-22 15:29:18 +080051#define DMA_NOSYNC_KEEP_DMA_BUF 0
52#define DMA_SYNC_RESTART 1
53
Bryan Wu1394f032007-05-06 14:50:22 -070054struct dmasg {
55 unsigned long next_desc_addr;
56 unsigned long start_addr;
57 unsigned short cfg;
58 unsigned short x_count;
59 short x_modify;
60 unsigned short y_count;
61 short y_modify;
62} __attribute__((packed));
63
64struct dma_register {
65 unsigned long next_desc_ptr; /* DMA Next Descriptor Pointer register */
66 unsigned long start_addr; /* DMA Start address register */
67
68 unsigned short cfg; /* DMA Configuration register */
69 unsigned short dummy1; /* DMA Configuration register */
70
71 unsigned long reserved;
72
73 unsigned short x_count; /* DMA x_count register */
74 unsigned short dummy2;
75
76 short x_modify; /* DMA x_modify register */
77 unsigned short dummy3;
78
79 unsigned short y_count; /* DMA y_count register */
80 unsigned short dummy4;
81
82 short y_modify; /* DMA y_modify register */
83 unsigned short dummy5;
84
85 unsigned long curr_desc_ptr; /* DMA Current Descriptor Pointer
86 register */
Bryan Wu452af712007-10-22 00:02:14 +080087 unsigned long curr_addr_ptr; /* DMA Current Address Pointer
Bryan Wu1394f032007-05-06 14:50:22 -070088 register */
89 unsigned short irq_status; /* DMA irq status register */
90 unsigned short dummy6;
91
92 unsigned short peripheral_map; /* DMA peripheral map register */
93 unsigned short dummy7;
94
95 unsigned short curr_x_count; /* DMA Current x-count register */
96 unsigned short dummy8;
97
98 unsigned long reserved2;
99
100 unsigned short curr_y_count; /* DMA Current y-count register */
101 unsigned short dummy9;
102
103 unsigned long reserved3;
104
105};
106
Mike Frysinger4c1ed6a2009-01-07 23:14:38 +0800107struct mutex;
Bryan Wu1394f032007-05-06 14:50:22 -0700108struct dma_channel {
109 struct mutex dmalock;
Michael McTernan99532fd2009-01-07 23:14:38 +0800110 const char *device_id;
Bryan Wu1394f032007-05-06 14:50:22 -0700111 enum dma_chan_status chan_status;
112 struct dma_register *regs;
113 struct dmasg *sg; /* large mode descriptor */
114 unsigned int ctrl_num; /* controller number */
Michael Hennericha2ba8b12008-10-28 18:19:29 +0800115 unsigned int irq;
Bryan Wu1394f032007-05-06 14:50:22 -0700116 void *data;
117 unsigned int dma_enable_flag;
118 unsigned int loopback_flag;
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800119#ifdef CONFIG_PM
120 unsigned short saved_peripheral_map;
121#endif
Bryan Wu1394f032007-05-06 14:50:22 -0700122};
123
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800124#ifdef CONFIG_PM
125int blackfin_dma_suspend(void);
126void blackfin_dma_resume(void);
127#endif
128
Bryan Wu1394f032007-05-06 14:50:22 -0700129/*******************************************************************************
130* DMA API's
131*******************************************************************************/
132/* functions to set register mode */
133void set_dma_start_addr(unsigned int channel, unsigned long addr);
134void set_dma_next_desc_addr(unsigned int channel, unsigned long addr);
Sonic Zhang8a26ac72007-08-05 16:14:58 +0800135void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr);
Bryan Wu1394f032007-05-06 14:50:22 -0700136void set_dma_x_count(unsigned int channel, unsigned short x_count);
137void set_dma_x_modify(unsigned int channel, short x_modify);
138void set_dma_y_count(unsigned int channel, unsigned short y_count);
139void set_dma_y_modify(unsigned int channel, short y_modify);
140void set_dma_config(unsigned int channel, unsigned short config);
141unsigned short set_bfin_dma_config(char direction, char flow_mode,
Michael Hennerich2047e402008-01-22 15:29:18 +0800142 char intr_mode, char dma_mode, char width,
143 char syncmode);
Roy Huang1d945e22007-10-10 23:31:19 +0800144void set_dma_curr_addr(unsigned int channel, unsigned long addr);
Bryan Wu1394f032007-05-06 14:50:22 -0700145
146/* get curr status for polling */
147unsigned short get_dma_curr_irqstat(unsigned int channel);
148unsigned short get_dma_curr_xcount(unsigned int channel);
149unsigned short get_dma_curr_ycount(unsigned int channel);
Bryan Wu452af712007-10-22 00:02:14 +0800150unsigned long get_dma_next_desc_ptr(unsigned int channel);
151unsigned long get_dma_curr_desc_ptr(unsigned int channel);
152unsigned long get_dma_curr_addr(unsigned int channel);
Bryan Wu1394f032007-05-06 14:50:22 -0700153
154/* set large DMA mode descriptor */
155void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg);
156
157/* check if current channel is in use */
158int dma_channel_active(unsigned int channel);
159
160/* common functions must be called in any mode */
161void free_dma(unsigned int channel);
162int dma_channel_active(unsigned int channel); /* check if a channel is in use */
163void disable_dma(unsigned int channel);
164void enable_dma(unsigned int channel);
Michael McTernan99532fd2009-01-07 23:14:38 +0800165int request_dma(unsigned int channel, const char *device_id);
Mike Frysinger68532bd2009-01-07 23:14:38 +0800166int set_dma_callback(unsigned int channel, irq_handler_t callback,
Bryan Wu1394f032007-05-06 14:50:22 -0700167 void *data);
168void dma_disable_irq(unsigned int channel);
169void dma_enable_irq(unsigned int channel);
170void clear_dma_irqstat(unsigned int channel);
171void *dma_memcpy(void *dest, const void *src, size_t count);
172void *safe_dma_memcpy(void *dest, const void *src, size_t count);
Mike Frysingerdd3dd382009-01-07 23:14:39 +0800173void blackfin_dma_early_init(void);
Bryan Wu1394f032007-05-06 14:50:22 -0700174
Bernd Schmidt77955662008-04-24 05:31:18 +0800175extern int channel2irq(unsigned int channel);
Mike Frysinger211daf92009-01-07 23:14:39 +0800176extern struct dma_register *dma_io_base_addr[MAX_DMA_CHANNELS];
Bernd Schmidt77955662008-04-24 05:31:18 +0800177
Bryan Wu1394f032007-05-06 14:50:22 -0700178#endif