1 |
199 |
simons |
#ifndef _M5307_DMA_H
|
2 |
|
|
#define _M5307_DMA_H 1
|
3 |
|
|
|
4 |
|
|
|
5 |
|
|
#include <asm/coldfire.h>
|
6 |
|
|
#include <asm/mcfsim.h>
|
7 |
|
|
#include <asm/irq.h>
|
8 |
|
|
|
9 |
|
|
|
10 |
|
|
#define MAX_DMA_CHANNELS 4
|
11 |
|
|
|
12 |
|
|
/*
|
13 |
|
|
*DMA Address Definitions
|
14 |
|
|
*/
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
#define MCF5307_DMA_SAR (MCF_MBAR+0x300) /*Source Address Register Channel */
|
18 |
|
|
#define MCF5307_DMA_DAR (MCF_MBAR+0x304) /*Destination Address Register Channel*/
|
19 |
|
|
#define MCF5307_DMA_DCR (MCF_MBAR+0x308) /*DMA Controll Register Channel*/
|
20 |
|
|
#define MCF5307_DMA_BCR (MCF_MBAR+0x30C) /*Byte Count Register Channel*/
|
21 |
|
|
#define MCF5307_DMA_SR (MCF_MBAR+0x310) /*Status Register Channel*/
|
22 |
|
|
#define MCF5307_DMA_IVR (MCF_MBAR+0x314) /*InterruptVectorRegister Channel*/
|
23 |
|
|
|
24 |
|
|
/*
|
25 |
|
|
*DMA Controll Register Definition
|
26 |
|
|
*/
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
#define MCF5307_DMA_DCR_INT (0x8000) /* Interrupt on Completion */
|
30 |
|
|
#define MCF5307_DMA_DCR_EEXT (0x4000) /* Enable External Request */
|
31 |
|
|
#define MCF5307_DMA_DCR_CS (0x2000) /* Cycle Steal */
|
32 |
|
|
#define MCF5307_DMA_DCR_AA (0x1000) /* Auto Align */
|
33 |
|
|
#define MCF5307_DMA_DCR_BWC_DMA (0x0000) /* Bandwidth: DMA Priority */
|
34 |
|
|
#define MCF5307_DMA_DCR_BWC_512 (0x0200) /* Bandwidth: 512 Bytes */
|
35 |
|
|
#define MCF5307_DMA_DCR_BWC_1024 (0x0400) /* Bandwidth: 1024 Bytes */
|
36 |
|
|
#define MCF5307_DMA_DCR_BWC_2048 (0x0600) /* Bandwidth: 2048 Bytes */
|
37 |
|
|
#define MCF5307_DMA_DCR_BWC_4096 (0x0800) /* Bandwidth: 4096 Bytes */
|
38 |
|
|
#define MCF5307_DMA_DCR_BWC_8192 (0x0a00) /* Bandwidth: 8192 Bytes */
|
39 |
|
|
#define MCF5307_DMA_DCR_BWC_16384 (0x0c00) /* Bandwidth: 16384 Bytes */
|
40 |
|
|
#define MCF5307_DMA_DCR_BWC_32768 (0x0e00) /* Bandwidth: 32768 Bytes */
|
41 |
|
|
#define MCF5307_DMA_DCR_SAA (0x0100) /* Single Address Access */
|
42 |
|
|
#define MCF5307_DMA_DCR_SRW (0x0080) /* Forces MRW Signal High */
|
43 |
|
|
#define MCF5307_DMA_DCR_SINC (0x0040) /* Source Increment */
|
44 |
|
|
#define MCF5307_DMA_DCR_SSIZE_LONG (0x0000) /* Source Size: Longword */
|
45 |
|
|
#define MCF5307_DMA_DCR_SSIZE_BYTE (0x0010) /* Source Size: Byte */
|
46 |
|
|
#define MCF5307_DMA_DCR_SSIZE_WORD (0x0020) /* Source Size: Word */
|
47 |
|
|
#define MCF5307_DMA_DCR_SSIZE_LINE (0x0030) /* Source Size: Line */
|
48 |
|
|
#define MCF5307_DMA_DCR_DINC (0x0008) /* Destination Increment */
|
49 |
|
|
#define MCF5307_DMA_DCR_DSIZE_LONG (0x0000) /* Destination Size: Longword */
|
50 |
|
|
#define MCF5307_DMA_DCR_DSIZE_BYTE (0x0002) /* Destination Size: Byte */
|
51 |
|
|
#define MCF5307_DMA_DCR_DSIZE_WORD (0x0004) /* Destination Size: Word */
|
52 |
|
|
#define MCF5307_DMA_DCR_DSIZE_LINE (0x0006) /* Destination Size: Line */
|
53 |
|
|
#define MCF5307_DMA_DCR_START (0x0001) /* Start Transfer */
|
54 |
|
|
|
55 |
|
|
/*
|
56 |
|
|
*DMA Status Register Definitions
|
57 |
|
|
*/
|
58 |
|
|
|
59 |
|
|
|
60 |
|
|
#define MCF5307_DMA_DSR_CE (0x40) /* Configuration Error */
|
61 |
|
|
#define MCF5307_DMA_DSR_BES (0x20) /* Bus Error on Source */
|
62 |
|
|
#define MCF5307_DMA_DSR_BED (0x10) /* Bus Error on Destination */
|
63 |
|
|
#define MCF5307_DMA_DSR_REQ (0x04) /* Request */
|
64 |
|
|
#define MCF5307_DMA_DSR_BSY (0x02) /* Busy */
|
65 |
|
|
#define MCF5307_DMA_DSR_DONE (0x01) /* Transaction Done */
|
66 |
|
|
|
67 |
|
|
|
68 |
|
|
#define DMA_STATE_BUSY 1
|
69 |
|
|
#define DMA_STATE_IDLE 0
|
70 |
|
|
#define DMA_STATE_CONFIGURATION_ERROR -1
|
71 |
|
|
#define DMA_STATE_SOURCE_ERROR -2
|
72 |
|
|
#define DMA_STATE_DESTINATION_ERROR -3
|
73 |
|
|
|
74 |
|
|
struct dma_mcf
|
75 |
|
|
{
|
76 |
|
|
const char *devname;
|
77 |
|
|
unsigned char* source;
|
78 |
|
|
unsigned char* dest;
|
79 |
|
|
unsigned short count;
|
80 |
|
|
unsigned short creg; /*16 bit controllregister use the defines above*/
|
81 |
|
|
void (*handler) (int, void *, struct pt_regs *);
|
82 |
|
|
unsigned int irq_vector;
|
83 |
|
|
unsigned int irq_level;
|
84 |
|
|
unsigned long irq_flags;
|
85 |
|
|
};
|
86 |
|
|
|
87 |
|
|
static __inline__ int dma_init(int channel)
|
88 |
|
|
{
|
89 |
|
|
int err;
|
90 |
|
|
if ((err = request_dma(channel, 0)) != 0) return err;
|
91 |
|
|
|
92 |
|
|
*(unsigned char*) (MCF_MBAR + MCFSIM_MPARK) |= 0x80; /* DMA BUS
|
93 |
|
|
MASTER with highest priority*/
|
94 |
|
|
return err;
|
95 |
|
|
}
|
96 |
|
|
|
97 |
|
|
|
98 |
|
|
|
99 |
|
|
static __inline__ void dma_set(int channel, struct dma_mcf dma)
|
100 |
|
|
{
|
101 |
|
|
|
102 |
|
|
|
103 |
|
|
*(unsigned int*) (MCF5307_DMA_SAR + (0x40 * channel)) = dma.source;
|
104 |
|
|
*(unsigned int*) (MCF5307_DMA_DAR + (0x40 * channel)) = dma.dest;
|
105 |
|
|
*(unsigned short*) (MCF5307_DMA_BCR + (0x40 * channel)) = dma.count;
|
106 |
|
|
if ((dma.creg & MCF5307_DMA_DCR_INT) !=0) /* DMA generates a Interrupt on complrtion*/
|
107 |
|
|
{ /* Now configure the Interrupt handler*/
|
108 |
|
|
*(unsigned short*) (MCF5307_DMA_IVR + (0x40 * channel)) = dma.irq_vector;
|
109 |
|
|
if (request_irq(dma.irq_vector,dma.handler,dma.irq_flags,
|
110 |
|
|
dma.devname, 0) !=0)
|
111 |
|
|
printk("request irq fail\n");
|
112 |
|
|
|
113 |
|
|
*(volatile unsigned char*)(MCF_MBAR + 0x52 + channel) = dma.irq_level | MCFSIM_ICR_AUTOVEC; /* set MBUS IRQ-Level and autovector */
|
114 |
|
|
mcf_setimr(mcf_getimr() & ~(0x4000 << channel));
|
115 |
|
|
printk("maskreg%X\n",mcf_getimr());
|
116 |
|
|
}
|
117 |
|
|
*(unsigned short*) (MCF5307_DMA_DCR + (0x40 * channel)) = dma.creg;
|
118 |
|
|
}
|
119 |
|
|
|
120 |
|
|
|
121 |
|
|
static __inline__ unsigned char dma_busy(unsigned char channel)
|
122 |
|
|
{
|
123 |
|
|
if ((*(unsigned char*) (MCF5307_DMA_SR + (0x40 * channel)) & MCF5307_DMA_DSR_BSY)!=0) return(0x1);
|
124 |
|
|
|
125 |
|
|
return 0;
|
126 |
|
|
}
|
127 |
|
|
|
128 |
|
|
static __inline__ void dma_done(unsigned char channel)
|
129 |
|
|
{
|
130 |
|
|
|
131 |
|
|
|
132 |
|
|
*(unsigned char*) (MCF5307_DMA_SR + (0x40 * channel)) = MCF5307_DMA_DSR_DONE;
|
133 |
|
|
}
|
134 |
|
|
|
135 |
|
|
|
136 |
|
|
static __inline__ void dma_clear(unsigned char channel)
|
137 |
|
|
{
|
138 |
|
|
*(unsigned short*) (MCF5307_DMA_DCR + (0x40 * channel)) = 0x0000;
|
139 |
|
|
}
|
140 |
|
|
|
141 |
|
|
|
142 |
|
|
static __inline__ unsigned char dma_get_status(unsigned char dsr)
|
143 |
|
|
{
|
144 |
|
|
if ((dsr & MCF5307_DMA_DSR_CE) != 0) return(DMA_STATE_CONFIGURATION_ERROR);
|
145 |
|
|
if ((dsr & MCF5307_DMA_DSR_BES) !=0) return(DMA_STATE_SOURCE_ERROR);
|
146 |
|
|
if ((dsr & MCF5307_DMA_DSR_BED) !=0) return(DMA_STATE_DESTINATION_ERROR);
|
147 |
|
|
return 0;
|
148 |
|
|
}
|
149 |
|
|
|
150 |
|
|
extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
|
151 |
|
|
extern void free_dma(unsigned int dmanr); /* release it again */
|
152 |
|
|
#endif /* _M5307_DMA_H */
|