Statistics
| Branch: | Revision:

root / hw / pxa2xx_dma.c @ e57ec016

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