Statistics
| Branch: | Revision:

root / hw / pxa2xx_dma.c @ 43997225

History | View | Annotate | Download (16.2 kB)

1 c1713132 balrog
/*
2 c1713132 balrog
 * Intel XScale PXA255/270 DMA controller.
3 c1713132 balrog
 *
4 c1713132 balrog
 * Copyright (c) 2006 Openedhand Ltd.
5 c1713132 balrog
 * Copyright (c) 2006 Thorsten Zitterell
6 c1713132 balrog
 * Written by Andrzej Zaborowski <balrog@zabor.org>
7 c1713132 balrog
 *
8 8e31bf38 Matthew Fernandez
 * This code is licensed under the GPL.
9 c1713132 balrog
 */
10 c1713132 balrog
11 87ecb68b pbrook
#include "hw.h"
12 87ecb68b pbrook
#include "pxa.h"
13 2115c019 Andrzej Zaborowski
#include "sysbus.h"
14 2115c019 Andrzej Zaborowski
15 2115c019 Andrzej Zaborowski
#define PXA255_DMA_NUM_CHANNELS 16
16 2115c019 Andrzej Zaborowski
#define PXA27X_DMA_NUM_CHANNELS 32
17 2115c019 Andrzej Zaborowski
18 2115c019 Andrzej Zaborowski
#define PXA2XX_DMA_NUM_REQUESTS 75
19 c1713132 balrog
20 bc24a225 Paul Brook
typedef struct {
21 a10394e1 Mitsyanko Igor
    uint32_t descr;
22 a10394e1 Mitsyanko Igor
    uint32_t src;
23 a10394e1 Mitsyanko Igor
    uint32_t dest;
24 c1713132 balrog
    uint32_t cmd;
25 c1713132 balrog
    uint32_t state;
26 c1713132 balrog
    int request;
27 bc24a225 Paul Brook
} PXA2xxDMAChannel;
28 c1713132 balrog
29 2115c019 Andrzej Zaborowski
typedef struct PXA2xxDMAState {
30 2115c019 Andrzej Zaborowski
    SysBusDevice busdev;
31 00049a12 Avi Kivity
    MemoryRegion iomem;
32 c1713132 balrog
    qemu_irq irq;
33 c1713132 balrog
34 c1713132 balrog
    uint32_t stopintr;
35 c1713132 balrog
    uint32_t eorintr;
36 c1713132 balrog
    uint32_t rasintr;
37 c1713132 balrog
    uint32_t startintr;
38 c1713132 balrog
    uint32_t endintr;
39 c1713132 balrog
40 c1713132 balrog
    uint32_t align;
41 c1713132 balrog
    uint32_t pio;
42 c1713132 balrog
43 c1713132 balrog
    int channels;
44 bc24a225 Paul Brook
    PXA2xxDMAChannel *chan;
45 c1713132 balrog
46 2115c019 Andrzej Zaborowski
    uint8_t req[PXA2XX_DMA_NUM_REQUESTS];
47 c1713132 balrog
48 c1713132 balrog
    /* Flag to avoid recursive DMA invocations.  */
49 c1713132 balrog
    int running;
50 2115c019 Andrzej Zaborowski
} PXA2xxDMAState;
51 c1713132 balrog
52 c1713132 balrog
#define DCSR0        0x0000        /* DMA Control / Status register for Channel 0 */
53 c1713132 balrog
#define DCSR31        0x007c        /* DMA Control / Status register for Channel 31 */
54 c1713132 balrog
#define DALGN        0x00a0        /* DMA Alignment register */
55 c1713132 balrog
#define DPCSR        0x00a4        /* DMA Programmed I/O Control Status register */
56 c1713132 balrog
#define DRQSR0        0x00e0        /* DMA DREQ<0> Status register */
57 c1713132 balrog
#define DRQSR1        0x00e4        /* DMA DREQ<1> Status register */
58 c1713132 balrog
#define DRQSR2        0x00e8        /* DMA DREQ<2> Status register */
59 c1713132 balrog
#define DINT        0x00f0        /* DMA Interrupt register */
60 c1713132 balrog
#define DRCMR0        0x0100        /* Request to Channel Map register 0 */
61 c1713132 balrog
#define DRCMR63        0x01fc        /* Request to Channel Map register 63 */
62 c1713132 balrog
#define D_CH0        0x0200        /* Channel 0 Descriptor start */
63 c1713132 balrog
#define DRCMR64        0x1100        /* Request to Channel Map register 64 */
64 c1713132 balrog
#define DRCMR74        0x1128        /* Request to Channel Map register 74 */
65 c1713132 balrog
66 c1713132 balrog
/* Per-channel register */
67 c1713132 balrog
#define DDADR        0x00
68 c1713132 balrog
#define DSADR        0x01
69 c1713132 balrog
#define DTADR        0x02
70 c1713132 balrog
#define DCMD        0x03
71 c1713132 balrog
72 c1713132 balrog
/* Bit-field masks */
73 c1713132 balrog
#define DRCMR_CHLNUM                0x1f
74 c1713132 balrog
#define DRCMR_MAPVLD                (1 << 7)
75 c1713132 balrog
#define DDADR_STOP                (1 << 0)
76 c1713132 balrog
#define DDADR_BREN                (1 << 1)
77 c1713132 balrog
#define DCMD_LEN                0x1fff
78 c1713132 balrog
#define DCMD_WIDTH(x)                (1 << ((((x) >> 14) & 3) - 1))
79 c1713132 balrog
#define DCMD_SIZE(x)                (4 << (((x) >> 16) & 3))
80 c1713132 balrog
#define DCMD_FLYBYT                (1 << 19)
81 c1713132 balrog
#define DCMD_FLYBYS                (1 << 20)
82 c1713132 balrog
#define DCMD_ENDIRQEN                (1 << 21)
83 c1713132 balrog
#define DCMD_STARTIRQEN                (1 << 22)
84 c1713132 balrog
#define DCMD_CMPEN                (1 << 25)
85 c1713132 balrog
#define DCMD_FLOWTRG                (1 << 28)
86 c1713132 balrog
#define DCMD_FLOWSRC                (1 << 29)
87 c1713132 balrog
#define DCMD_INCTRGADDR                (1 << 30)
88 c1713132 balrog
#define DCMD_INCSRCADDR                (1 << 31)
89 c1713132 balrog
#define DCSR_BUSERRINTR                (1 << 0)
90 c1713132 balrog
#define DCSR_STARTINTR                (1 << 1)
91 c1713132 balrog
#define DCSR_ENDINTR                (1 << 2)
92 c1713132 balrog
#define DCSR_STOPINTR                (1 << 3)
93 c1713132 balrog
#define DCSR_RASINTR                (1 << 4)
94 c1713132 balrog
#define DCSR_REQPEND                (1 << 8)
95 c1713132 balrog
#define DCSR_EORINT                (1 << 9)
96 c1713132 balrog
#define DCSR_CMPST                (1 << 10)
97 c1713132 balrog
#define DCSR_MASKRUN                (1 << 22)
98 c1713132 balrog
#define DCSR_RASIRQEN                (1 << 23)
99 c1713132 balrog
#define DCSR_CLRCMPST                (1 << 24)
100 c1713132 balrog
#define DCSR_SETCMPST                (1 << 25)
101 c1713132 balrog
#define DCSR_EORSTOPEN                (1 << 26)
102 c1713132 balrog
#define DCSR_EORJMPEN                (1 << 27)
103 c1713132 balrog
#define DCSR_EORIRQEN                (1 << 28)
104 c1713132 balrog
#define DCSR_STOPIRQEN                (1 << 29)
105 c1713132 balrog
#define DCSR_NODESCFETCH        (1 << 30)
106 c1713132 balrog
#define DCSR_RUN                (1 << 31)
107 c1713132 balrog
108 bc24a225 Paul Brook
static inline void pxa2xx_dma_update(PXA2xxDMAState *s, int ch)
109 c1713132 balrog
{
110 c1713132 balrog
    if (ch >= 0) {
111 c1713132 balrog
        if ((s->chan[ch].state & DCSR_STOPIRQEN) &&
112 c1713132 balrog
                (s->chan[ch].state & DCSR_STOPINTR))
113 c1713132 balrog
            s->stopintr |= 1 << ch;
114 c1713132 balrog
        else
115 c1713132 balrog
            s->stopintr &= ~(1 << ch);
116 c1713132 balrog
117 c1713132 balrog
        if ((s->chan[ch].state & DCSR_EORIRQEN) &&
118 c1713132 balrog
                (s->chan[ch].state & DCSR_EORINT))
119 c1713132 balrog
            s->eorintr |= 1 << ch;
120 c1713132 balrog
        else
121 c1713132 balrog
            s->eorintr &= ~(1 << ch);
122 c1713132 balrog
123 c1713132 balrog
        if ((s->chan[ch].state & DCSR_RASIRQEN) &&
124 c1713132 balrog
                (s->chan[ch].state & DCSR_RASINTR))
125 c1713132 balrog
            s->rasintr |= 1 << ch;
126 c1713132 balrog
        else
127 c1713132 balrog
            s->rasintr &= ~(1 << ch);
128 c1713132 balrog
129 c1713132 balrog
        if (s->chan[ch].state & DCSR_STARTINTR)
130 c1713132 balrog
            s->startintr |= 1 << ch;
131 c1713132 balrog
        else
132 c1713132 balrog
            s->startintr &= ~(1 << ch);
133 c1713132 balrog
134 c1713132 balrog
        if (s->chan[ch].state & DCSR_ENDINTR)
135 c1713132 balrog
            s->endintr |= 1 << ch;
136 c1713132 balrog
        else
137 c1713132 balrog
            s->endintr &= ~(1 << ch);
138 c1713132 balrog
    }
139 c1713132 balrog
140 c1713132 balrog
    if (s->stopintr | s->eorintr | s->rasintr | s->startintr | s->endintr)
141 c1713132 balrog
        qemu_irq_raise(s->irq);
142 c1713132 balrog
    else
143 c1713132 balrog
        qemu_irq_lower(s->irq);
144 c1713132 balrog
}
145 c1713132 balrog
146 c1713132 balrog
static inline void pxa2xx_dma_descriptor_fetch(
147 bc24a225 Paul Brook
                PXA2xxDMAState *s, int ch)
148 c1713132 balrog
{
149 c1713132 balrog
    uint32_t desc[4];
150 c227f099 Anthony Liguori
    target_phys_addr_t daddr = s->chan[ch].descr & ~0xf;
151 c1713132 balrog
    if ((s->chan[ch].descr & DDADR_BREN) && (s->chan[ch].state & DCSR_CMPST))
152 c1713132 balrog
        daddr += 32;
153 c1713132 balrog
154 c1713132 balrog
    cpu_physical_memory_read(daddr, (uint8_t *) desc, 16);
155 c1713132 balrog
    s->chan[ch].descr = desc[DDADR];
156 c1713132 balrog
    s->chan[ch].src = desc[DSADR];
157 c1713132 balrog
    s->chan[ch].dest = desc[DTADR];
158 c1713132 balrog
    s->chan[ch].cmd = desc[DCMD];
159 c1713132 balrog
160 c1713132 balrog
    if (s->chan[ch].cmd & DCMD_FLOWSRC)
161 c1713132 balrog
        s->chan[ch].src &= ~3;
162 c1713132 balrog
    if (s->chan[ch].cmd & DCMD_FLOWTRG)
163 c1713132 balrog
        s->chan[ch].dest &= ~3;
164 c1713132 balrog
165 c1713132 balrog
    if (s->chan[ch].cmd & (DCMD_CMPEN | DCMD_FLYBYS | DCMD_FLYBYT))
166 c1713132 balrog
        printf("%s: unsupported mode in channel %i\n", __FUNCTION__, ch);
167 c1713132 balrog
168 c1713132 balrog
    if (s->chan[ch].cmd & DCMD_STARTIRQEN)
169 c1713132 balrog
        s->chan[ch].state |= DCSR_STARTINTR;
170 c1713132 balrog
}
171 c1713132 balrog
172 bc24a225 Paul Brook
static void pxa2xx_dma_run(PXA2xxDMAState *s)
173 c1713132 balrog
{
174 c1713132 balrog
    int c, srcinc, destinc;
175 c1713132 balrog
    uint32_t n, size;
176 c1713132 balrog
    uint32_t width;
177 c1713132 balrog
    uint32_t length;
178 b55266b5 blueswir1
    uint8_t buffer[32];
179 bc24a225 Paul Brook
    PXA2xxDMAChannel *ch;
180 c1713132 balrog
181 c1713132 balrog
    if (s->running ++)
182 c1713132 balrog
        return;
183 c1713132 balrog
184 c1713132 balrog
    while (s->running) {
185 c1713132 balrog
        s->running = 1;
186 c1713132 balrog
        for (c = 0; c < s->channels; c ++) {
187 c1713132 balrog
            ch = &s->chan[c];
188 c1713132 balrog
189 c1713132 balrog
            while ((ch->state & DCSR_RUN) && !(ch->state & DCSR_STOPINTR)) {
190 c1713132 balrog
                /* Test for pending requests */
191 c1713132 balrog
                if ((ch->cmd & (DCMD_FLOWSRC | DCMD_FLOWTRG)) && !ch->request)
192 c1713132 balrog
                    break;
193 c1713132 balrog
194 c1713132 balrog
                length = ch->cmd & DCMD_LEN;
195 c1713132 balrog
                size = DCMD_SIZE(ch->cmd);
196 c1713132 balrog
                width = DCMD_WIDTH(ch->cmd);
197 c1713132 balrog
198 c1713132 balrog
                srcinc = (ch->cmd & DCMD_INCSRCADDR) ? width : 0;
199 c1713132 balrog
                destinc = (ch->cmd & DCMD_INCTRGADDR) ? width : 0;
200 c1713132 balrog
201 c1713132 balrog
                while (length) {
202 c1713132 balrog
                    size = MIN(length, size);
203 c1713132 balrog
204 c1713132 balrog
                    for (n = 0; n < size; n += width) {
205 c1713132 balrog
                        cpu_physical_memory_read(ch->src, buffer + n, width);
206 c1713132 balrog
                        ch->src += srcinc;
207 c1713132 balrog
                    }
208 c1713132 balrog
209 c1713132 balrog
                    for (n = 0; n < size; n += width) {
210 c1713132 balrog
                        cpu_physical_memory_write(ch->dest, buffer + n, width);
211 c1713132 balrog
                        ch->dest += destinc;
212 c1713132 balrog
                    }
213 c1713132 balrog
214 c1713132 balrog
                    length -= size;
215 c1713132 balrog
216 c1713132 balrog
                    if ((ch->cmd & (DCMD_FLOWSRC | DCMD_FLOWTRG)) &&
217 c1713132 balrog
                            !ch->request) {
218 c1713132 balrog
                        ch->state |= DCSR_EORINT;
219 c1713132 balrog
                        if (ch->state & DCSR_EORSTOPEN)
220 c1713132 balrog
                            ch->state |= DCSR_STOPINTR;
221 c1713132 balrog
                        if ((ch->state & DCSR_EORJMPEN) &&
222 c1713132 balrog
                                        !(ch->state & DCSR_NODESCFETCH))
223 c1713132 balrog
                            pxa2xx_dma_descriptor_fetch(s, c);
224 c1713132 balrog
                        break;
225 c1713132 balrog
                    }
226 c1713132 balrog
                }
227 c1713132 balrog
228 c1713132 balrog
                ch->cmd = (ch->cmd & ~DCMD_LEN) | length;
229 c1713132 balrog
230 c1713132 balrog
                /* Is the transfer complete now? */
231 c1713132 balrog
                if (!length) {
232 c1713132 balrog
                    if (ch->cmd & DCMD_ENDIRQEN)
233 c1713132 balrog
                        ch->state |= DCSR_ENDINTR;
234 c1713132 balrog
235 c1713132 balrog
                    if ((ch->state & DCSR_NODESCFETCH) ||
236 c1713132 balrog
                                (ch->descr & DDADR_STOP) ||
237 c1713132 balrog
                                (ch->state & DCSR_EORSTOPEN)) {
238 c1713132 balrog
                        ch->state |= DCSR_STOPINTR;
239 c1713132 balrog
                        ch->state &= ~DCSR_RUN;
240 c1713132 balrog
241 c1713132 balrog
                        break;
242 c1713132 balrog
                    }
243 c1713132 balrog
244 c1713132 balrog
                    ch->state |= DCSR_STOPINTR;
245 c1713132 balrog
                    break;
246 c1713132 balrog
                }
247 c1713132 balrog
            }
248 c1713132 balrog
        }
249 c1713132 balrog
250 c1713132 balrog
        s->running --;
251 c1713132 balrog
    }
252 c1713132 balrog
}
253 c1713132 balrog
254 00049a12 Avi Kivity
static uint64_t pxa2xx_dma_read(void *opaque, target_phys_addr_t offset,
255 00049a12 Avi Kivity
                                unsigned size)
256 c1713132 balrog
{
257 bc24a225 Paul Brook
    PXA2xxDMAState *s = (PXA2xxDMAState *) opaque;
258 c1713132 balrog
    unsigned int channel;
259 c1713132 balrog
260 00049a12 Avi Kivity
    if (size != 4) {
261 00049a12 Avi Kivity
        hw_error("%s: Bad access width\n", __FUNCTION__);
262 00049a12 Avi Kivity
        return 5;
263 00049a12 Avi Kivity
    }
264 00049a12 Avi Kivity
265 c1713132 balrog
    switch (offset) {
266 c1713132 balrog
    case DRCMR64 ... DRCMR74:
267 c1713132 balrog
        offset -= DRCMR64 - DRCMR0 - (64 << 2);
268 c1713132 balrog
        /* Fall through */
269 c1713132 balrog
    case DRCMR0 ... DRCMR63:
270 c1713132 balrog
        channel = (offset - DRCMR0) >> 2;
271 c1713132 balrog
        return s->req[channel];
272 c1713132 balrog
273 c1713132 balrog
    case DRQSR0:
274 c1713132 balrog
    case DRQSR1:
275 c1713132 balrog
    case DRQSR2:
276 c1713132 balrog
        return 0;
277 c1713132 balrog
278 c1713132 balrog
    case DCSR0 ... DCSR31:
279 c1713132 balrog
        channel = offset >> 2;
280 c1713132 balrog
        if (s->chan[channel].request)
281 c1713132 balrog
            return s->chan[channel].state | DCSR_REQPEND;
282 c1713132 balrog
        return s->chan[channel].state;
283 c1713132 balrog
284 c1713132 balrog
    case DINT:
285 c1713132 balrog
        return s->stopintr | s->eorintr | s->rasintr |
286 c1713132 balrog
                s->startintr | s->endintr;
287 c1713132 balrog
288 c1713132 balrog
    case DALGN:
289 c1713132 balrog
        return s->align;
290 c1713132 balrog
291 c1713132 balrog
    case DPCSR:
292 c1713132 balrog
        return s->pio;
293 c1713132 balrog
    }
294 c1713132 balrog
295 c1713132 balrog
    if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) {
296 c1713132 balrog
        channel = (offset - D_CH0) >> 4;
297 c1713132 balrog
        switch ((offset & 0x0f) >> 2) {
298 c1713132 balrog
        case DDADR:
299 c1713132 balrog
            return s->chan[channel].descr;
300 c1713132 balrog
        case DSADR:
301 c1713132 balrog
            return s->chan[channel].src;
302 c1713132 balrog
        case DTADR:
303 c1713132 balrog
            return s->chan[channel].dest;
304 c1713132 balrog
        case DCMD:
305 c1713132 balrog
            return s->chan[channel].cmd;
306 c1713132 balrog
        }
307 c1713132 balrog
    }
308 c1713132 balrog
309 2ac71179 Paul Brook
    hw_error("%s: Bad offset 0x" TARGET_FMT_plx "\n", __FUNCTION__, offset);
310 c1713132 balrog
    return 7;
311 c1713132 balrog
}
312 c1713132 balrog
313 00049a12 Avi Kivity
static void pxa2xx_dma_write(void *opaque, target_phys_addr_t offset,
314 00049a12 Avi Kivity
                             uint64_t value, unsigned size)
315 c1713132 balrog
{
316 bc24a225 Paul Brook
    PXA2xxDMAState *s = (PXA2xxDMAState *) opaque;
317 c1713132 balrog
    unsigned int channel;
318 c1713132 balrog
319 00049a12 Avi Kivity
    if (size != 4) {
320 00049a12 Avi Kivity
        hw_error("%s: Bad access width\n", __FUNCTION__);
321 00049a12 Avi Kivity
        return;
322 00049a12 Avi Kivity
    }
323 00049a12 Avi Kivity
324 c1713132 balrog
    switch (offset) {
325 c1713132 balrog
    case DRCMR64 ... DRCMR74:
326 c1713132 balrog
        offset -= DRCMR64 - DRCMR0 - (64 << 2);
327 c1713132 balrog
        /* Fall through */
328 c1713132 balrog
    case DRCMR0 ... DRCMR63:
329 c1713132 balrog
        channel = (offset - DRCMR0) >> 2;
330 c1713132 balrog
331 c1713132 balrog
        if (value & DRCMR_MAPVLD)
332 c1713132 balrog
            if ((value & DRCMR_CHLNUM) > s->channels)
333 2ac71179 Paul Brook
                hw_error("%s: Bad DMA channel %i\n",
334 00049a12 Avi Kivity
                         __FUNCTION__, (unsigned)value & DRCMR_CHLNUM);
335 c1713132 balrog
336 c1713132 balrog
        s->req[channel] = value;
337 c1713132 balrog
        break;
338 c1713132 balrog
339 c1713132 balrog
    case DRQSR0:
340 c1713132 balrog
    case DRQSR1:
341 c1713132 balrog
    case DRQSR2:
342 c1713132 balrog
        /* Nothing to do */
343 c1713132 balrog
        break;
344 c1713132 balrog
345 c1713132 balrog
    case DCSR0 ... DCSR31:
346 c1713132 balrog
        channel = offset >> 2;
347 c1713132 balrog
        s->chan[channel].state &= 0x0000071f & ~(value &
348 c1713132 balrog
                        (DCSR_EORINT | DCSR_ENDINTR |
349 c1713132 balrog
                         DCSR_STARTINTR | DCSR_BUSERRINTR));
350 c1713132 balrog
        s->chan[channel].state |= value & 0xfc800000;
351 c1713132 balrog
352 c1713132 balrog
        if (s->chan[channel].state & DCSR_STOPIRQEN)
353 c1713132 balrog
            s->chan[channel].state &= ~DCSR_STOPINTR;
354 c1713132 balrog
355 c1713132 balrog
        if (value & DCSR_NODESCFETCH) {
356 c1713132 balrog
            /* No-descriptor-fetch mode */
357 e1dad5a6 balrog
            if (value & DCSR_RUN) {
358 e1dad5a6 balrog
                s->chan[channel].state &= ~DCSR_STOPINTR;
359 c1713132 balrog
                pxa2xx_dma_run(s);
360 e1dad5a6 balrog
            }
361 c1713132 balrog
        } else {
362 c1713132 balrog
            /* Descriptor-fetch mode */
363 c1713132 balrog
            if (value & DCSR_RUN) {
364 c1713132 balrog
                s->chan[channel].state &= ~DCSR_STOPINTR;
365 c1713132 balrog
                pxa2xx_dma_descriptor_fetch(s, channel);
366 c1713132 balrog
                pxa2xx_dma_run(s);
367 c1713132 balrog
            }
368 c1713132 balrog
        }
369 c1713132 balrog
370 c1713132 balrog
        /* Shouldn't matter as our DMA is synchronous.  */
371 c1713132 balrog
        if (!(value & (DCSR_RUN | DCSR_MASKRUN)))
372 c1713132 balrog
            s->chan[channel].state |= DCSR_STOPINTR;
373 c1713132 balrog
374 c1713132 balrog
        if (value & DCSR_CLRCMPST)
375 c1713132 balrog
            s->chan[channel].state &= ~DCSR_CMPST;
376 c1713132 balrog
        if (value & DCSR_SETCMPST)
377 c1713132 balrog
            s->chan[channel].state |= DCSR_CMPST;
378 c1713132 balrog
379 c1713132 balrog
        pxa2xx_dma_update(s, channel);
380 c1713132 balrog
        break;
381 c1713132 balrog
382 c1713132 balrog
    case DALGN:
383 c1713132 balrog
        s->align = value;
384 c1713132 balrog
        break;
385 c1713132 balrog
386 c1713132 balrog
    case DPCSR:
387 c1713132 balrog
        s->pio = value & 0x80000001;
388 c1713132 balrog
        break;
389 c1713132 balrog
390 c1713132 balrog
    default:
391 c1713132 balrog
        if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) {
392 c1713132 balrog
            channel = (offset - D_CH0) >> 4;
393 c1713132 balrog
            switch ((offset & 0x0f) >> 2) {
394 c1713132 balrog
            case DDADR:
395 c1713132 balrog
                s->chan[channel].descr = value;
396 c1713132 balrog
                break;
397 c1713132 balrog
            case DSADR:
398 c1713132 balrog
                s->chan[channel].src = value;
399 c1713132 balrog
                break;
400 c1713132 balrog
            case DTADR:
401 c1713132 balrog
                s->chan[channel].dest = value;
402 c1713132 balrog
                break;
403 c1713132 balrog
            case DCMD:
404 c1713132 balrog
                s->chan[channel].cmd = value;
405 c1713132 balrog
                break;
406 c1713132 balrog
            default:
407 c1713132 balrog
                goto fail;
408 c1713132 balrog
            }
409 c1713132 balrog
410 c1713132 balrog
            break;
411 c1713132 balrog
        }
412 c1713132 balrog
    fail:
413 2ac71179 Paul Brook
        hw_error("%s: Bad offset " TARGET_FMT_plx "\n", __FUNCTION__, offset);
414 c1713132 balrog
    }
415 c1713132 balrog
}
416 c1713132 balrog
417 00049a12 Avi Kivity
static const MemoryRegionOps pxa2xx_dma_ops = {
418 00049a12 Avi Kivity
    .read = pxa2xx_dma_read,
419 00049a12 Avi Kivity
    .write = pxa2xx_dma_write,
420 00049a12 Avi Kivity
    .endianness = DEVICE_NATIVE_ENDIAN,
421 c1713132 balrog
};
422 c1713132 balrog
423 f114c826 Andrzej Zaborowski
static void pxa2xx_dma_request(void *opaque, int req_num, int on)
424 f114c826 Andrzej Zaborowski
{
425 f114c826 Andrzej Zaborowski
    PXA2xxDMAState *s = opaque;
426 f114c826 Andrzej Zaborowski
    int ch;
427 f114c826 Andrzej Zaborowski
    if (req_num < 0 || req_num >= PXA2XX_DMA_NUM_REQUESTS)
428 f114c826 Andrzej Zaborowski
        hw_error("%s: Bad DMA request %i\n", __FUNCTION__, req_num);
429 f114c826 Andrzej Zaborowski
430 f114c826 Andrzej Zaborowski
    if (!(s->req[req_num] & DRCMR_MAPVLD))
431 f114c826 Andrzej Zaborowski
        return;
432 f114c826 Andrzej Zaborowski
    ch = s->req[req_num] & DRCMR_CHLNUM;
433 f114c826 Andrzej Zaborowski
434 f114c826 Andrzej Zaborowski
    if (!s->chan[ch].request && on)
435 f114c826 Andrzej Zaborowski
        s->chan[ch].state |= DCSR_RASINTR;
436 f114c826 Andrzej Zaborowski
    else
437 f114c826 Andrzej Zaborowski
        s->chan[ch].state &= ~DCSR_RASINTR;
438 f114c826 Andrzej Zaborowski
    if (s->chan[ch].request && !on)
439 f114c826 Andrzej Zaborowski
        s->chan[ch].state |= DCSR_EORINT;
440 f114c826 Andrzej Zaborowski
441 f114c826 Andrzej Zaborowski
    s->chan[ch].request = on;
442 f114c826 Andrzej Zaborowski
    if (on) {
443 f114c826 Andrzej Zaborowski
        pxa2xx_dma_run(s);
444 f114c826 Andrzej Zaborowski
        pxa2xx_dma_update(s, ch);
445 f114c826 Andrzej Zaborowski
    }
446 f114c826 Andrzej Zaborowski
}
447 aa941b94 balrog
448 2115c019 Andrzej Zaborowski
static int pxa2xx_dma_init(SysBusDevice *dev)
449 c1713132 balrog
{
450 00049a12 Avi Kivity
    int i;
451 bc24a225 Paul Brook
    PXA2xxDMAState *s;
452 2115c019 Andrzej Zaborowski
    s = FROM_SYSBUS(PXA2xxDMAState, dev);
453 2115c019 Andrzej Zaborowski
454 2115c019 Andrzej Zaborowski
    if (s->channels <= 0) {
455 2115c019 Andrzej Zaborowski
        return -1;
456 2115c019 Andrzej Zaborowski
    }
457 c1713132 balrog
458 7267c094 Anthony Liguori
    s->chan = g_malloc0(sizeof(PXA2xxDMAChannel) * s->channels);
459 c1713132 balrog
460 bc24a225 Paul Brook
    memset(s->chan, 0, sizeof(PXA2xxDMAChannel) * s->channels);
461 c1713132 balrog
    for (i = 0; i < s->channels; i ++)
462 c1713132 balrog
        s->chan[i].state = DCSR_STOPINTR;
463 c1713132 balrog
464 3f582262 balrog
    memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);
465 c1713132 balrog
466 2115c019 Andrzej Zaborowski
    qdev_init_gpio_in(&dev->qdev, pxa2xx_dma_request, PXA2XX_DMA_NUM_REQUESTS);
467 2115c019 Andrzej Zaborowski
468 00049a12 Avi Kivity
    memory_region_init_io(&s->iomem, &pxa2xx_dma_ops, s,
469 00049a12 Avi Kivity
                          "pxa2xx.dma", 0x00010000);
470 750ecd44 Avi Kivity
    sysbus_init_mmio(dev, &s->iomem);
471 2115c019 Andrzej Zaborowski
    sysbus_init_irq(dev, &s->irq);
472 c1713132 balrog
473 2115c019 Andrzej Zaborowski
    return 0;
474 c1713132 balrog
}
475 c1713132 balrog
476 2115c019 Andrzej Zaborowski
DeviceState *pxa27x_dma_init(target_phys_addr_t base, qemu_irq irq)
477 c1713132 balrog
{
478 2115c019 Andrzej Zaborowski
    DeviceState *dev;
479 2115c019 Andrzej Zaborowski
480 2115c019 Andrzej Zaborowski
    dev = qdev_create(NULL, "pxa2xx-dma");
481 2115c019 Andrzej Zaborowski
    qdev_prop_set_int32(dev, "channels", PXA27X_DMA_NUM_CHANNELS);
482 2115c019 Andrzej Zaborowski
    qdev_init_nofail(dev);
483 2115c019 Andrzej Zaborowski
484 2115c019 Andrzej Zaborowski
    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
485 2115c019 Andrzej Zaborowski
    sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
486 2115c019 Andrzej Zaborowski
487 2115c019 Andrzej Zaborowski
    return dev;
488 c1713132 balrog
}
489 c1713132 balrog
490 2115c019 Andrzej Zaborowski
DeviceState *pxa255_dma_init(target_phys_addr_t base, qemu_irq irq)
491 c1713132 balrog
{
492 2115c019 Andrzej Zaborowski
    DeviceState *dev;
493 2115c019 Andrzej Zaborowski
494 2115c019 Andrzej Zaborowski
    dev = qdev_create(NULL, "pxa2xx-dma");
495 2115c019 Andrzej Zaborowski
    qdev_prop_set_int32(dev, "channels", PXA27X_DMA_NUM_CHANNELS);
496 2115c019 Andrzej Zaborowski
    qdev_init_nofail(dev);
497 2115c019 Andrzej Zaborowski
498 2115c019 Andrzej Zaborowski
    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
499 2115c019 Andrzej Zaborowski
    sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
500 2115c019 Andrzej Zaborowski
501 2115c019 Andrzej Zaborowski
    return dev;
502 c1713132 balrog
}
503 c1713132 balrog
504 2115c019 Andrzej Zaborowski
static bool is_version_0(void *opaque, int version_id)
505 2115c019 Andrzej Zaborowski
{
506 2115c019 Andrzej Zaborowski
    return version_id == 0;
507 2115c019 Andrzej Zaborowski
}
508 2115c019 Andrzej Zaborowski
509 2115c019 Andrzej Zaborowski
static VMStateDescription vmstate_pxa2xx_dma_chan = {
510 2115c019 Andrzej Zaborowski
    .name = "pxa2xx_dma_chan",
511 2115c019 Andrzej Zaborowski
    .version_id = 1,
512 2115c019 Andrzej Zaborowski
    .minimum_version_id = 1,
513 2115c019 Andrzej Zaborowski
    .minimum_version_id_old = 1,
514 2115c019 Andrzej Zaborowski
    .fields = (VMStateField[]) {
515 a10394e1 Mitsyanko Igor
        VMSTATE_UINT32(descr, PXA2xxDMAChannel),
516 a10394e1 Mitsyanko Igor
        VMSTATE_UINT32(src, PXA2xxDMAChannel),
517 a10394e1 Mitsyanko Igor
        VMSTATE_UINT32(dest, PXA2xxDMAChannel),
518 2115c019 Andrzej Zaborowski
        VMSTATE_UINT32(cmd, PXA2xxDMAChannel),
519 2115c019 Andrzej Zaborowski
        VMSTATE_UINT32(state, PXA2xxDMAChannel),
520 2115c019 Andrzej Zaborowski
        VMSTATE_INT32(request, PXA2xxDMAChannel),
521 2115c019 Andrzej Zaborowski
        VMSTATE_END_OF_LIST(),
522 2115c019 Andrzej Zaborowski
    },
523 2115c019 Andrzej Zaborowski
};
524 2115c019 Andrzej Zaborowski
525 2115c019 Andrzej Zaborowski
static VMStateDescription vmstate_pxa2xx_dma = {
526 2115c019 Andrzej Zaborowski
    .name = "pxa2xx_dma",
527 2115c019 Andrzej Zaborowski
    .version_id = 1,
528 2115c019 Andrzej Zaborowski
    .minimum_version_id = 0,
529 2115c019 Andrzej Zaborowski
    .minimum_version_id_old = 0,
530 2115c019 Andrzej Zaborowski
    .fields = (VMStateField[]) {
531 2115c019 Andrzej Zaborowski
        VMSTATE_UNUSED_TEST(is_version_0, 4),
532 2115c019 Andrzej Zaborowski
        VMSTATE_UINT32(stopintr, PXA2xxDMAState),
533 2115c019 Andrzej Zaborowski
        VMSTATE_UINT32(eorintr, PXA2xxDMAState),
534 2115c019 Andrzej Zaborowski
        VMSTATE_UINT32(rasintr, PXA2xxDMAState),
535 2115c019 Andrzej Zaborowski
        VMSTATE_UINT32(startintr, PXA2xxDMAState),
536 2115c019 Andrzej Zaborowski
        VMSTATE_UINT32(endintr, PXA2xxDMAState),
537 2115c019 Andrzej Zaborowski
        VMSTATE_UINT32(align, PXA2xxDMAState),
538 2115c019 Andrzej Zaborowski
        VMSTATE_UINT32(pio, PXA2xxDMAState),
539 2115c019 Andrzej Zaborowski
        VMSTATE_BUFFER(req, PXA2xxDMAState),
540 2115c019 Andrzej Zaborowski
        VMSTATE_STRUCT_VARRAY_POINTER_INT32(chan, PXA2xxDMAState, channels,
541 2115c019 Andrzej Zaborowski
                vmstate_pxa2xx_dma_chan, PXA2xxDMAChannel),
542 2115c019 Andrzej Zaborowski
        VMSTATE_END_OF_LIST(),
543 2115c019 Andrzej Zaborowski
    },
544 2115c019 Andrzej Zaborowski
};
545 2115c019 Andrzej Zaborowski
546 999e12bb Anthony Liguori
static Property pxa2xx_dma_properties[] = {
547 999e12bb Anthony Liguori
    DEFINE_PROP_INT32("channels", PXA2xxDMAState, channels, -1),
548 999e12bb Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
549 999e12bb Anthony Liguori
};
550 999e12bb Anthony Liguori
551 999e12bb Anthony Liguori
static void pxa2xx_dma_class_init(ObjectClass *klass, void *data)
552 999e12bb Anthony Liguori
{
553 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
554 999e12bb Anthony Liguori
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
555 999e12bb Anthony Liguori
556 999e12bb Anthony Liguori
    k->init = pxa2xx_dma_init;
557 39bffca2 Anthony Liguori
    dc->desc = "PXA2xx DMA controller";
558 39bffca2 Anthony Liguori
    dc->vmsd = &vmstate_pxa2xx_dma;
559 39bffca2 Anthony Liguori
    dc->props = pxa2xx_dma_properties;
560 999e12bb Anthony Liguori
}
561 999e12bb Anthony Liguori
562 39bffca2 Anthony Liguori
static TypeInfo pxa2xx_dma_info = {
563 39bffca2 Anthony Liguori
    .name          = "pxa2xx-dma",
564 39bffca2 Anthony Liguori
    .parent        = TYPE_SYS_BUS_DEVICE,
565 39bffca2 Anthony Liguori
    .instance_size = sizeof(PXA2xxDMAState),
566 39bffca2 Anthony Liguori
    .class_init    = pxa2xx_dma_class_init,
567 2115c019 Andrzej Zaborowski
};
568 2115c019 Andrzej Zaborowski
569 83f7d43a Andreas Färber
static void pxa2xx_dma_register_types(void)
570 2115c019 Andrzej Zaborowski
{
571 39bffca2 Anthony Liguori
    type_register_static(&pxa2xx_dma_info);
572 2115c019 Andrzej Zaborowski
}
573 83f7d43a Andreas Färber
574 83f7d43a Andreas Färber
type_init(pxa2xx_dma_register_types)