Statistics
| Branch: | Revision:

root / hw / omap_dma.c @ fad6cb1a

History | View | Annotate | Download (58.7 kB)

1
/*
2
 * TI OMAP DMA gigacell.
3
 *
4
 * Copyright (C) 2006-2008 Andrzej Zaborowski  <balrog@zabor.org>
5
 * Copyright (C) 2007-2008 Lauro Ramos Venancio  <lauro.venancio@indt.org.br>
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License as
9
 * published by the Free Software Foundation; either version 2 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program; if not, write to the Free Software Foundation, Inc.,
19
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
 */
21
#include "qemu-common.h"
22
#include "qemu-timer.h"
23
#include "omap.h"
24
#include "irq.h"
25
#include "soc_dma.h"
26

    
27
struct omap_dma_channel_s {
28
    /* transfer data */
29
    int burst[2];
30
    int pack[2];
31
    int endian[2];
32
    int endian_lock[2];
33
    int translate[2];
34
    enum omap_dma_port port[2];
35
    target_phys_addr_t addr[2];
36
    omap_dma_addressing_t mode[2];
37
    uint32_t elements;
38
    uint16_t frames;
39
    int32_t frame_index[2];
40
    int16_t element_index[2];
41
    int data_type;
42

    
43
    /* transfer type */
44
    int transparent_copy;
45
    int constant_fill;
46
    uint32_t color;
47
    int prefetch;
48

    
49
    /* auto init and linked channel data */
50
    int end_prog;
51
    int repeat;
52
    int auto_init;
53
    int link_enabled;
54
    int link_next_ch;
55

    
56
    /* interruption data */
57
    int interrupts;
58
    int status;
59
    int cstatus;
60

    
61
    /* state data */
62
    int active;
63
    int enable;
64
    int sync;
65
    int src_sync;
66
    int pending_request;
67
    int waiting_end_prog;
68
    uint16_t cpc;
69
    int set_update;
70

    
71
    /* sync type */
72
    int fs;
73
    int bs;
74

    
75
    /* compatibility */
76
    int omap_3_1_compatible_disable;
77

    
78
    qemu_irq irq;
79
    struct omap_dma_channel_s *sibling;
80

    
81
    struct omap_dma_reg_set_s {
82
        target_phys_addr_t src, dest;
83
        int frame;
84
        int element;
85
        int pck_element;
86
        int frame_delta[2];
87
        int elem_delta[2];
88
        int frames;
89
        int elements;
90
        int pck_elements;
91
    } active_set;
92

    
93
    struct soc_dma_ch_s *dma;
94

    
95
    /* unused parameters */
96
    int write_mode;
97
    int priority;
98
    int interleave_disabled;
99
    int type;
100
    int suspend;
101
    int buf_disable;
102
};
103

    
104
struct omap_dma_s {
105
    struct soc_dma_s *dma;
106

    
107
    struct omap_mpu_state_s *mpu;
108
    omap_clk clk;
109
    qemu_irq irq[4];
110
    void (*intr_update)(struct omap_dma_s *s);
111
    enum omap_dma_model model;
112
    int omap_3_1_mapping_disabled;
113

    
114
    uint32_t gcr;
115
    uint32_t ocp;
116
    uint32_t caps[5];
117
    uint32_t irqen[4];
118
    uint32_t irqstat[4];
119

    
120
    int chans;
121
    struct omap_dma_channel_s ch[32];
122
    struct omap_dma_lcd_channel_s lcd_ch;
123
};
124

    
125
/* Interrupts */
126
#define TIMEOUT_INTR    (1 << 0)
127
#define EVENT_DROP_INTR (1 << 1)
128
#define HALF_FRAME_INTR (1 << 2)
129
#define END_FRAME_INTR  (1 << 3)
130
#define LAST_FRAME_INTR (1 << 4)
131
#define END_BLOCK_INTR  (1 << 5)
132
#define SYNC            (1 << 6)
133
#define END_PKT_INTR        (1 << 7)
134
#define TRANS_ERR_INTR        (1 << 8)
135
#define MISALIGN_INTR        (1 << 11)
136

    
137
static inline void omap_dma_interrupts_update(struct omap_dma_s *s)
138
{
139
    return s->intr_update(s);
140
}
141

    
142
static void omap_dma_channel_load(struct omap_dma_channel_s *ch)
143
{
144
    struct omap_dma_reg_set_s *a = &ch->active_set;
145
    int i, normal;
146
    int omap_3_1 = !ch->omap_3_1_compatible_disable;
147

    
148
    /*
149
     * TODO: verify address ranges and alignment
150
     * TODO: port endianness
151
     */
152

    
153
    a->src = ch->addr[0];
154
    a->dest = ch->addr[1];
155
    a->frames = ch->frames;
156
    a->elements = ch->elements;
157
    a->pck_elements = ch->frame_index[!ch->src_sync];
158
    a->frame = 0;
159
    a->element = 0;
160
    a->pck_element = 0;
161

    
162
    if (unlikely(!ch->elements || !ch->frames)) {
163
        printf("%s: bad DMA request\n", __FUNCTION__);
164
        return;
165
    }
166

    
167
    for (i = 0; i < 2; i ++)
168
        switch (ch->mode[i]) {
169
        case constant:
170
            a->elem_delta[i] = 0;
171
            a->frame_delta[i] = 0;
172
            break;
173
        case post_incremented:
174
            a->elem_delta[i] = ch->data_type;
175
            a->frame_delta[i] = 0;
176
            break;
177
        case single_index:
178
            a->elem_delta[i] = ch->data_type +
179
                    ch->element_index[omap_3_1 ? 0 : i] - 1;
180
            a->frame_delta[i] = 0;
181
            break;
182
        case double_index:
183
            a->elem_delta[i] = ch->data_type +
184
                    ch->element_index[omap_3_1 ? 0 : i] - 1;
185
            a->frame_delta[i] = ch->frame_index[omap_3_1 ? 0 : i] -
186
                    ch->element_index[omap_3_1 ? 0 : i];
187
            break;
188
        default:
189
            break;
190
        }
191

    
192
    normal = !ch->transparent_copy && !ch->constant_fill &&
193
            /* FIFO is big-endian so either (ch->endian[n] == 1) OR
194
             * (ch->endian_lock[n] == 1) mean no endianism conversion.  */
195
            (ch->endian[0] | ch->endian_lock[0]) ==
196
            (ch->endian[1] | ch->endian_lock[1]);
197
    for (i = 0; i < 2; i ++) {
198
        /* TODO: for a->frame_delta[i] > 0 still use the fast path, just
199
         * limit min_elems in omap_dma_transfer_setup to the nearest frame
200
         * end.  */
201
        if (!a->elem_delta[i] && normal &&
202
                        (a->frames == 1 || !a->frame_delta[i]))
203
            ch->dma->type[i] = soc_dma_access_const;
204
        else if (a->elem_delta[i] == ch->data_type && normal &&
205
                        (a->frames == 1 || !a->frame_delta[i]))
206
            ch->dma->type[i] = soc_dma_access_linear;
207
        else
208
            ch->dma->type[i] = soc_dma_access_other;
209

    
210
        ch->dma->vaddr[i] = ch->addr[i];
211
    }
212
    soc_dma_ch_update(ch->dma);
213
}
214

    
215
static void omap_dma_activate_channel(struct omap_dma_s *s,
216
                struct omap_dma_channel_s *ch)
217
{
218
    if (!ch->active) {
219
        if (ch->set_update) {
220
            /* It's not clear when the active set is supposed to be
221
             * loaded from registers.  We're already loading it when the
222
             * channel is enabled, and for some guests this is not enough
223
             * but that may be also because of a race condition (no
224
             * delays in qemu) in the guest code, which we're just
225
             * working around here.  */
226
            omap_dma_channel_load(ch);
227
            ch->set_update = 0;
228
        }
229

    
230
        ch->active = 1;
231
        soc_dma_set_request(ch->dma, 1);
232
        if (ch->sync)
233
            ch->status |= SYNC;
234
    }
235
}
236

    
237
static void omap_dma_deactivate_channel(struct omap_dma_s *s,
238
                struct omap_dma_channel_s *ch)
239
{
240
    /* Update cpc */
241
    ch->cpc = ch->active_set.dest & 0xffff;
242

    
243
    if (ch->pending_request && !ch->waiting_end_prog && ch->enable) {
244
        /* Don't deactivate the channel */
245
        ch->pending_request = 0;
246
        return;
247
    }
248

    
249
    /* Don't deactive the channel if it is synchronized and the DMA request is
250
       active */
251
    if (ch->sync && ch->enable && (s->dma->drqbmp & (1 << ch->sync)))
252
        return;
253

    
254
    if (ch->active) {
255
        ch->active = 0;
256
        ch->status &= ~SYNC;
257
        soc_dma_set_request(ch->dma, 0);
258
    }
259
}
260

    
261
static void omap_dma_enable_channel(struct omap_dma_s *s,
262
                struct omap_dma_channel_s *ch)
263
{
264
    if (!ch->enable) {
265
        ch->enable = 1;
266
        ch->waiting_end_prog = 0;
267
        omap_dma_channel_load(ch);
268
        /* TODO: theoretically if ch->sync && ch->prefetch &&
269
         * !s->dma->drqbmp[ch->sync], we should also activate and fetch
270
         * from source and then stall until signalled.  */
271
        if ((!ch->sync) || (s->dma->drqbmp & (1 << ch->sync)))
272
            omap_dma_activate_channel(s, ch);
273
    }
274
}
275

    
276
static void omap_dma_disable_channel(struct omap_dma_s *s,
277
                struct omap_dma_channel_s *ch)
278
{
279
    if (ch->enable) {
280
        ch->enable = 0;
281
        /* Discard any pending request */
282
        ch->pending_request = 0;
283
        omap_dma_deactivate_channel(s, ch);
284
    }
285
}
286

    
287
static void omap_dma_channel_end_prog(struct omap_dma_s *s,
288
                struct omap_dma_channel_s *ch)
289
{
290
    if (ch->waiting_end_prog) {
291
        ch->waiting_end_prog = 0;
292
        if (!ch->sync || ch->pending_request) {
293
            ch->pending_request = 0;
294
            omap_dma_activate_channel(s, ch);
295
        }
296
    }
297
}
298

    
299
static void omap_dma_interrupts_3_1_update(struct omap_dma_s *s)
300
{
301
    struct omap_dma_channel_s *ch = s->ch;
302

    
303
    /* First three interrupts are shared between two channels each. */
304
    if (ch[0].status | ch[6].status)
305
        qemu_irq_raise(ch[0].irq);
306
    if (ch[1].status | ch[7].status)
307
        qemu_irq_raise(ch[1].irq);
308
    if (ch[2].status | ch[8].status)
309
        qemu_irq_raise(ch[2].irq);
310
    if (ch[3].status)
311
        qemu_irq_raise(ch[3].irq);
312
    if (ch[4].status)
313
        qemu_irq_raise(ch[4].irq);
314
    if (ch[5].status)
315
        qemu_irq_raise(ch[5].irq);
316
}
317

    
318
static void omap_dma_interrupts_3_2_update(struct omap_dma_s *s)
319
{
320
    struct omap_dma_channel_s *ch = s->ch;
321
    int i;
322

    
323
    for (i = s->chans; i; ch ++, i --)
324
        if (ch->status)
325
            qemu_irq_raise(ch->irq);
326
}
327

    
328
static void omap_dma_enable_3_1_mapping(struct omap_dma_s *s)
329
{
330
    s->omap_3_1_mapping_disabled = 0;
331
    s->chans = 9;
332
    s->intr_update = omap_dma_interrupts_3_1_update;
333
}
334

    
335
static void omap_dma_disable_3_1_mapping(struct omap_dma_s *s)
336
{
337
    s->omap_3_1_mapping_disabled = 1;
338
    s->chans = 16;
339
    s->intr_update = omap_dma_interrupts_3_2_update;
340
}
341

    
342
static void omap_dma_process_request(struct omap_dma_s *s, int request)
343
{
344
    int channel;
345
    int drop_event = 0;
346
    struct omap_dma_channel_s *ch = s->ch;
347

    
348
    for (channel = 0; channel < s->chans; channel ++, ch ++) {
349
        if (ch->enable && ch->sync == request) {
350
            if (!ch->active)
351
                omap_dma_activate_channel(s, ch);
352
            else if (!ch->pending_request)
353
                ch->pending_request = 1;
354
            else {
355
                /* Request collision */
356
                /* Second request received while processing other request */
357
                ch->status |= EVENT_DROP_INTR;
358
                drop_event = 1;
359
            }
360
        }
361
    }
362

    
363
    if (drop_event)
364
        omap_dma_interrupts_update(s);
365
}
366

    
367
static void omap_dma_transfer_generic(struct soc_dma_ch_s *dma)
368
{
369
    uint8_t value[4];
370
    struct omap_dma_channel_s *ch = dma->opaque;
371
    struct omap_dma_reg_set_s *a = &ch->active_set;
372
    int bytes = dma->bytes;
373
#ifdef MULTI_REQ
374
    uint16_t status = ch->status;
375
#endif
376

    
377
    do {
378
        /* Transfer a single element */
379
        /* FIXME: check the endianness */
380
        if (!ch->constant_fill)
381
            cpu_physical_memory_read(a->src, value, ch->data_type);
382
        else
383
            *(uint32_t *) value = ch->color;
384

    
385
        if (!ch->transparent_copy || *(uint32_t *) value != ch->color)
386
            cpu_physical_memory_write(a->dest, value, ch->data_type);
387

    
388
        a->src += a->elem_delta[0];
389
        a->dest += a->elem_delta[1];
390
        a->element ++;
391

    
392
#ifndef MULTI_REQ
393
        if (a->element == a->elements) {
394
            /* End of Frame */
395
            a->element = 0;
396
            a->src += a->frame_delta[0];
397
            a->dest += a->frame_delta[1];
398
            a->frame ++;
399

    
400
            /* If the channel is async, update cpc */
401
            if (!ch->sync)
402
                ch->cpc = a->dest & 0xffff;
403
        }
404
    } while ((bytes -= ch->data_type));
405
#else
406
        /* If the channel is element synchronized, deactivate it */
407
        if (ch->sync && !ch->fs && !ch->bs)
408
            omap_dma_deactivate_channel(s, ch);
409

    
410
        /* If it is the last frame, set the LAST_FRAME interrupt */
411
        if (a->element == 1 && a->frame == a->frames - 1)
412
            if (ch->interrupts & LAST_FRAME_INTR)
413
                ch->status |= LAST_FRAME_INTR;
414

    
415
        /* If the half of the frame was reached, set the HALF_FRAME
416
           interrupt */
417
        if (a->element == (a->elements >> 1))
418
            if (ch->interrupts & HALF_FRAME_INTR)
419
                ch->status |= HALF_FRAME_INTR;
420

    
421
        if (ch->fs && ch->bs) {
422
            a->pck_element ++;
423
            /* Check if a full packet has beed transferred.  */
424
            if (a->pck_element == a->pck_elements) {
425
                a->pck_element = 0;
426

    
427
                /* Set the END_PKT interrupt */
428
                if ((ch->interrupts & END_PKT_INTR) && !ch->src_sync)
429
                    ch->status |= END_PKT_INTR;
430

    
431
                /* If the channel is packet-synchronized, deactivate it */
432
                if (ch->sync)
433
                    omap_dma_deactivate_channel(s, ch);
434
            }
435
        }
436

    
437
        if (a->element == a->elements) {
438
            /* End of Frame */
439
            a->element = 0;
440
            a->src += a->frame_delta[0];
441
            a->dest += a->frame_delta[1];
442
            a->frame ++;
443

    
444
            /* If the channel is frame synchronized, deactivate it */
445
            if (ch->sync && ch->fs && !ch->bs)
446
                omap_dma_deactivate_channel(s, ch);
447

    
448
            /* If the channel is async, update cpc */
449
            if (!ch->sync)
450
                ch->cpc = a->dest & 0xffff;
451

    
452
            /* Set the END_FRAME interrupt */
453
            if (ch->interrupts & END_FRAME_INTR)
454
                ch->status |= END_FRAME_INTR;
455

    
456
            if (a->frame == a->frames) {
457
                /* End of Block */
458
                /* Disable the channel */
459

    
460
                if (ch->omap_3_1_compatible_disable) {
461
                    omap_dma_disable_channel(s, ch);
462
                    if (ch->link_enabled)
463
                        omap_dma_enable_channel(s,
464
                                        &s->ch[ch->link_next_ch]);
465
                } else {
466
                    if (!ch->auto_init)
467
                        omap_dma_disable_channel(s, ch);
468
                    else if (ch->repeat || ch->end_prog)
469
                        omap_dma_channel_load(ch);
470
                    else {
471
                        ch->waiting_end_prog = 1;
472
                        omap_dma_deactivate_channel(s, ch);
473
                    }
474
                }
475

    
476
                if (ch->interrupts & END_BLOCK_INTR)
477
                    ch->status |= END_BLOCK_INTR;
478
            }
479
        }
480
    } while (status == ch->status && ch->active);
481

    
482
    omap_dma_interrupts_update(s);
483
#endif
484
}
485

    
486
enum {
487
    omap_dma_intr_element_sync,
488
    omap_dma_intr_last_frame,
489
    omap_dma_intr_half_frame,
490
    omap_dma_intr_frame,
491
    omap_dma_intr_frame_sync,
492
    omap_dma_intr_packet,
493
    omap_dma_intr_packet_sync,
494
    omap_dma_intr_block,
495
    __omap_dma_intr_last,
496
};
497

    
498
static void omap_dma_transfer_setup(struct soc_dma_ch_s *dma)
499
{
500
    struct omap_dma_port_if_s *src_p, *dest_p;
501
    struct omap_dma_reg_set_s *a;
502
    struct omap_dma_channel_s *ch = dma->opaque;
503
    struct omap_dma_s *s = dma->dma->opaque;
504
    int frames, min_elems, elements[__omap_dma_intr_last];
505

    
506
    a = &ch->active_set;
507

    
508
    src_p = &s->mpu->port[ch->port[0]];
509
    dest_p = &s->mpu->port[ch->port[1]];
510
    if ((!ch->constant_fill && !src_p->addr_valid(s->mpu, a->src)) ||
511
                    (!dest_p->addr_valid(s->mpu, a->dest))) {
512
#if 0
513
        /* Bus time-out */
514
        if (ch->interrupts & TIMEOUT_INTR)
515
            ch->status |= TIMEOUT_INTR;
516
        omap_dma_deactivate_channel(s, ch);
517
        continue;
518
#endif
519
        printf("%s: Bus time-out in DMA%i operation\n",
520
                        __FUNCTION__, dma->num);
521
    }
522

    
523
    min_elems = INT_MAX;
524

    
525
    /* Check all the conditions that terminate the transfer starting
526
     * with those that can occur the soonest.  */
527
#define INTR_CHECK(cond, id, nelements)        \
528
    if (cond) {                        \
529
        elements[id] = nelements;        \
530
        if (elements[id] < min_elems)        \
531
            min_elems = elements[id];        \
532
    } else                                \
533
        elements[id] = INT_MAX;
534

    
535
    /* Elements */
536
    INTR_CHECK(
537
                    ch->sync && !ch->fs && !ch->bs,
538
                    omap_dma_intr_element_sync,
539
                    1)
540

    
541
    /* Frames */
542
    /* TODO: for transfers where entire frames can be read and written
543
     * using memcpy() but a->frame_delta is non-zero, try to still do
544
     * transfers using soc_dma but limit min_elems to a->elements - ...
545
     * See also the TODO in omap_dma_channel_load.  */
546
    INTR_CHECK(
547
                    (ch->interrupts & LAST_FRAME_INTR) &&
548
                    ((a->frame < a->frames - 1) || !a->element),
549
                    omap_dma_intr_last_frame,
550
                    (a->frames - a->frame - 2) * a->elements +
551
                    (a->elements - a->element + 1))
552
    INTR_CHECK(
553
                    ch->interrupts & HALF_FRAME_INTR,
554
                    omap_dma_intr_half_frame,
555
                    (a->elements >> 1) +
556
                    (a->element >= (a->elements >> 1) ? a->elements : 0) -
557
                    a->element)
558
    INTR_CHECK(
559
                    ch->sync && ch->fs && (ch->interrupts & END_FRAME_INTR),
560
                    omap_dma_intr_frame,
561
                    a->elements - a->element)
562
    INTR_CHECK(
563
                    ch->sync && ch->fs && !ch->bs,
564
                    omap_dma_intr_frame_sync,
565
                    a->elements - a->element)
566

    
567
    /* Packets */
568
    INTR_CHECK(
569
                    ch->fs && ch->bs &&
570
                    (ch->interrupts & END_PKT_INTR) && !ch->src_sync,
571
                    omap_dma_intr_packet,
572
                    a->pck_elements - a->pck_element)
573
    INTR_CHECK(
574
                    ch->fs && ch->bs && ch->sync,
575
                    omap_dma_intr_packet_sync,
576
                    a->pck_elements - a->pck_element)
577

    
578
    /* Blocks */
579
    INTR_CHECK(
580
                    1,
581
                    omap_dma_intr_block,
582
                    (a->frames - a->frame - 1) * a->elements +
583
                    (a->elements - a->element))
584

    
585
    dma->bytes = min_elems * ch->data_type;
586

    
587
    /* Set appropriate interrupts and/or deactivate channels */
588

    
589
#ifdef MULTI_REQ
590
    /* TODO: should all of this only be done if dma->update, and otherwise
591
     * inside omap_dma_transfer_generic below - check what's faster.  */
592
    if (dma->update) {
593
#endif
594

    
595
    /* If the channel is element synchronized, deactivate it */
596
    if (min_elems == elements[omap_dma_intr_element_sync])
597
        omap_dma_deactivate_channel(s, ch);
598

    
599
    /* If it is the last frame, set the LAST_FRAME interrupt */
600
    if (min_elems == elements[omap_dma_intr_last_frame])
601
        ch->status |= LAST_FRAME_INTR;
602

    
603
    /* If exactly half of the frame was reached, set the HALF_FRAME
604
       interrupt */
605
    if (min_elems == elements[omap_dma_intr_half_frame])
606
        ch->status |= HALF_FRAME_INTR;
607

    
608
    /* If a full packet has been transferred, set the END_PKT interrupt */
609
    if (min_elems == elements[omap_dma_intr_packet])
610
        ch->status |= END_PKT_INTR;
611

    
612
    /* If the channel is packet-synchronized, deactivate it */
613
    if (min_elems == elements[omap_dma_intr_packet_sync])
614
        omap_dma_deactivate_channel(s, ch);
615

    
616
    /* If the channel is frame synchronized, deactivate it */
617
    if (min_elems == elements[omap_dma_intr_frame_sync])
618
        omap_dma_deactivate_channel(s, ch);
619

    
620
    /* Set the END_FRAME interrupt */
621
    if (min_elems == elements[omap_dma_intr_frame])
622
        ch->status |= END_FRAME_INTR;
623

    
624
    if (min_elems == elements[omap_dma_intr_block]) {
625
        /* End of Block */
626
        /* Disable the channel */
627

    
628
        if (ch->omap_3_1_compatible_disable) {
629
            omap_dma_disable_channel(s, ch);
630
            if (ch->link_enabled)
631
                omap_dma_enable_channel(s, &s->ch[ch->link_next_ch]);
632
        } else {
633
            if (!ch->auto_init)
634
                omap_dma_disable_channel(s, ch);
635
            else if (ch->repeat || ch->end_prog)
636
                omap_dma_channel_load(ch);
637
            else {
638
                ch->waiting_end_prog = 1;
639
                omap_dma_deactivate_channel(s, ch);
640
            }
641
        }
642

    
643
        if (ch->interrupts & END_BLOCK_INTR)
644
            ch->status |= END_BLOCK_INTR;
645
    }
646

    
647
    /* Update packet number */
648
    if (ch->fs && ch->bs) {
649
        a->pck_element += min_elems;
650
        a->pck_element %= a->pck_elements;
651
    }
652

    
653
    /* TODO: check if we really need to update anything here or perhaps we
654
     * can skip part of this.  */
655
#ifndef MULTI_REQ
656
    if (dma->update) {
657
#endif
658
        a->element += min_elems;
659

    
660
        frames     = a->element / a->elements;
661
        a->element = a->element % a->elements;
662
        a->frame  += frames;
663
        a->src    += min_elems * a->elem_delta[0] + frames * a->frame_delta[0];
664
        a->dest   += min_elems * a->elem_delta[1] + frames * a->frame_delta[1];
665

    
666
        /* If the channel is async, update cpc */
667
        if (!ch->sync && frames)
668
            ch->cpc = a->dest & 0xffff;
669

    
670
        /* TODO: if the destination port is IMIF or EMIFF, set the dirty
671
         * bits on it.  */
672
    }
673

    
674
    omap_dma_interrupts_update(s);
675
}
676

    
677
void omap_dma_reset(struct soc_dma_s *dma)
678
{
679
    int i;
680
    struct omap_dma_s *s = dma->opaque;
681

    
682
    soc_dma_reset(s->dma);
683
    if (s->model < omap_dma_4)
684
        s->gcr = 0x0004;
685
    else
686
        s->gcr = 0x00010010;
687
    s->ocp = 0x00000000;
688
    memset(&s->irqstat, 0, sizeof(s->irqstat));
689
    memset(&s->irqen, 0, sizeof(s->irqen));
690
    s->lcd_ch.src = emiff;
691
    s->lcd_ch.condition = 0;
692
    s->lcd_ch.interrupts = 0;
693
    s->lcd_ch.dual = 0;
694
    if (s->model < omap_dma_4)
695
        omap_dma_enable_3_1_mapping(s);
696
    for (i = 0; i < s->chans; i ++) {
697
        s->ch[i].suspend = 0;
698
        s->ch[i].prefetch = 0;
699
        s->ch[i].buf_disable = 0;
700
        s->ch[i].src_sync = 0;
701
        memset(&s->ch[i].burst, 0, sizeof(s->ch[i].burst));
702
        memset(&s->ch[i].port, 0, sizeof(s->ch[i].port));
703
        memset(&s->ch[i].mode, 0, sizeof(s->ch[i].mode));
704
        memset(&s->ch[i].frame_index, 0, sizeof(s->ch[i].frame_index));
705
        memset(&s->ch[i].element_index, 0, sizeof(s->ch[i].element_index));
706
        memset(&s->ch[i].endian, 0, sizeof(s->ch[i].endian));
707
        memset(&s->ch[i].endian_lock, 0, sizeof(s->ch[i].endian_lock));
708
        memset(&s->ch[i].translate, 0, sizeof(s->ch[i].translate));
709
        s->ch[i].write_mode = 0;
710
        s->ch[i].data_type = 0;
711
        s->ch[i].transparent_copy = 0;
712
        s->ch[i].constant_fill = 0;
713
        s->ch[i].color = 0x00000000;
714
        s->ch[i].end_prog = 0;
715
        s->ch[i].repeat = 0;
716
        s->ch[i].auto_init = 0;
717
        s->ch[i].link_enabled = 0;
718
        if (s->model < omap_dma_4)
719
            s->ch[i].interrupts = 0x0003;
720
        else
721
            s->ch[i].interrupts = 0x0000;
722
        s->ch[i].status = 0;
723
        s->ch[i].cstatus = 0;
724
        s->ch[i].active = 0;
725
        s->ch[i].enable = 0;
726
        s->ch[i].sync = 0;
727
        s->ch[i].pending_request = 0;
728
        s->ch[i].waiting_end_prog = 0;
729
        s->ch[i].cpc = 0x0000;
730
        s->ch[i].fs = 0;
731
        s->ch[i].bs = 0;
732
        s->ch[i].omap_3_1_compatible_disable = 0;
733
        memset(&s->ch[i].active_set, 0, sizeof(s->ch[i].active_set));
734
        s->ch[i].priority = 0;
735
        s->ch[i].interleave_disabled = 0;
736
        s->ch[i].type = 0;
737
    }
738
}
739

    
740
static int omap_dma_ch_reg_read(struct omap_dma_s *s,
741
                struct omap_dma_channel_s *ch, int reg, uint16_t *value)
742
{
743
    switch (reg) {
744
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
745
        *value = (ch->burst[1] << 14) |
746
                (ch->pack[1] << 13) |
747
                (ch->port[1] << 9) |
748
                (ch->burst[0] << 7) |
749
                (ch->pack[0] << 6) |
750
                (ch->port[0] << 2) |
751
                (ch->data_type >> 1);
752
        break;
753

    
754
    case 0x02:        /* SYS_DMA_CCR_CH0 */
755
        if (s->model <= omap_dma_3_1)
756
            *value = 0 << 10;                        /* FIFO_FLUSH reads as 0 */
757
        else
758
            *value = ch->omap_3_1_compatible_disable << 10;
759
        *value |= (ch->mode[1] << 14) |
760
                (ch->mode[0] << 12) |
761
                (ch->end_prog << 11) |
762
                (ch->repeat << 9) |
763
                (ch->auto_init << 8) |
764
                (ch->enable << 7) |
765
                (ch->priority << 6) |
766
                (ch->fs << 5) | ch->sync;
767
        break;
768

    
769
    case 0x04:        /* SYS_DMA_CICR_CH0 */
770
        *value = ch->interrupts;
771
        break;
772

    
773
    case 0x06:        /* SYS_DMA_CSR_CH0 */
774
        *value = ch->status;
775
        ch->status &= SYNC;
776
        if (!ch->omap_3_1_compatible_disable && ch->sibling) {
777
            *value |= (ch->sibling->status & 0x3f) << 6;
778
            ch->sibling->status &= SYNC;
779
        }
780
        qemu_irq_lower(ch->irq);
781
        break;
782

    
783
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
784
        *value = ch->addr[0] & 0x0000ffff;
785
        break;
786

    
787
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
788
        *value = ch->addr[0] >> 16;
789
        break;
790

    
791
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
792
        *value = ch->addr[1] & 0x0000ffff;
793
        break;
794

    
795
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
796
        *value = ch->addr[1] >> 16;
797
        break;
798

    
799
    case 0x10:        /* SYS_DMA_CEN_CH0 */
800
        *value = ch->elements;
801
        break;
802

    
803
    case 0x12:        /* SYS_DMA_CFN_CH0 */
804
        *value = ch->frames;
805
        break;
806

    
807
    case 0x14:        /* SYS_DMA_CFI_CH0 */
808
        *value = ch->frame_index[0];
809
        break;
810

    
811
    case 0x16:        /* SYS_DMA_CEI_CH0 */
812
        *value = ch->element_index[0];
813
        break;
814

    
815
    case 0x18:        /* SYS_DMA_CPC_CH0 or DMA_CSAC */
816
        if (ch->omap_3_1_compatible_disable)
817
            *value = ch->active_set.src & 0xffff;        /* CSAC */
818
        else
819
            *value = ch->cpc;
820
        break;
821

    
822
    case 0x1a:        /* DMA_CDAC */
823
        *value = ch->active_set.dest & 0xffff;        /* CDAC */
824
        break;
825

    
826
    case 0x1c:        /* DMA_CDEI */
827
        *value = ch->element_index[1];
828
        break;
829

    
830
    case 0x1e:        /* DMA_CDFI */
831
        *value = ch->frame_index[1];
832
        break;
833

    
834
    case 0x20:        /* DMA_COLOR_L */
835
        *value = ch->color & 0xffff;
836
        break;
837

    
838
    case 0x22:        /* DMA_COLOR_U */
839
        *value = ch->color >> 16;
840
        break;
841

    
842
    case 0x24:        /* DMA_CCR2 */
843
        *value = (ch->bs << 2) |
844
                (ch->transparent_copy << 1) |
845
                ch->constant_fill;
846
        break;
847

    
848
    case 0x28:        /* DMA_CLNK_CTRL */
849
        *value = (ch->link_enabled << 15) |
850
                (ch->link_next_ch & 0xf);
851
        break;
852

    
853
    case 0x2a:        /* DMA_LCH_CTRL */
854
        *value = (ch->interleave_disabled << 15) |
855
                ch->type;
856
        break;
857

    
858
    default:
859
        return 1;
860
    }
861
    return 0;
862
}
863

    
864
static int omap_dma_ch_reg_write(struct omap_dma_s *s,
865
                struct omap_dma_channel_s *ch, int reg, uint16_t value)
866
{
867
    switch (reg) {
868
    case 0x00:        /* SYS_DMA_CSDP_CH0 */
869
        ch->burst[1] = (value & 0xc000) >> 14;
870
        ch->pack[1] = (value & 0x2000) >> 13;
871
        ch->port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
872
        ch->burst[0] = (value & 0x0180) >> 7;
873
        ch->pack[0] = (value & 0x0040) >> 6;
874
        ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
875
        ch->data_type = 1 << (value & 3);
876
        if (ch->port[0] >= __omap_dma_port_last)
877
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
878
                            ch->port[0]);
879
        if (ch->port[1] >= __omap_dma_port_last)
880
            printf("%s: invalid DMA port %i\n", __FUNCTION__,
881
                            ch->port[1]);
882
        if ((value & 3) == 3)
883
            printf("%s: bad data_type for DMA channel\n", __FUNCTION__);
884
        break;
885

    
886
    case 0x02:        /* SYS_DMA_CCR_CH0 */
887
        ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
888
        ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
889
        ch->end_prog = (value & 0x0800) >> 11;
890
        if (s->model >= omap_dma_3_2)
891
            ch->omap_3_1_compatible_disable  = (value >> 10) & 0x1;
892
        ch->repeat = (value & 0x0200) >> 9;
893
        ch->auto_init = (value & 0x0100) >> 8;
894
        ch->priority = (value & 0x0040) >> 6;
895
        ch->fs = (value & 0x0020) >> 5;
896
        ch->sync = value & 0x001f;
897

    
898
        if (value & 0x0080)
899
            omap_dma_enable_channel(s, ch);
900
        else
901
            omap_dma_disable_channel(s, ch);
902

    
903
        if (ch->end_prog)
904
            omap_dma_channel_end_prog(s, ch);
905

    
906
        break;
907

    
908
    case 0x04:        /* SYS_DMA_CICR_CH0 */
909
        ch->interrupts = value & 0x3f;
910
        break;
911

    
912
    case 0x06:        /* SYS_DMA_CSR_CH0 */
913
        OMAP_RO_REG((target_phys_addr_t) reg);
914
        break;
915

    
916
    case 0x08:        /* SYS_DMA_CSSA_L_CH0 */
917
        ch->addr[0] &= 0xffff0000;
918
        ch->addr[0] |= value;
919
        break;
920

    
921
    case 0x0a:        /* SYS_DMA_CSSA_U_CH0 */
922
        ch->addr[0] &= 0x0000ffff;
923
        ch->addr[0] |= (uint32_t) value << 16;
924
        break;
925

    
926
    case 0x0c:        /* SYS_DMA_CDSA_L_CH0 */
927
        ch->addr[1] &= 0xffff0000;
928
        ch->addr[1] |= value;
929
        break;
930

    
931
    case 0x0e:        /* SYS_DMA_CDSA_U_CH0 */
932
        ch->addr[1] &= 0x0000ffff;
933
        ch->addr[1] |= (uint32_t) value << 16;
934
        break;
935

    
936
    case 0x10:        /* SYS_DMA_CEN_CH0 */
937
        ch->elements = value;
938
        break;
939

    
940
    case 0x12:        /* SYS_DMA_CFN_CH0 */
941
        ch->frames = value;
942
        break;
943

    
944
    case 0x14:        /* SYS_DMA_CFI_CH0 */
945
        ch->frame_index[0] = (int16_t) value;
946
        break;
947

    
948
    case 0x16:        /* SYS_DMA_CEI_CH0 */
949
        ch->element_index[0] = (int16_t) value;
950
        break;
951

    
952
    case 0x18:        /* SYS_DMA_CPC_CH0 or DMA_CSAC */
953
        OMAP_RO_REG((target_phys_addr_t) reg);
954
        break;
955

    
956
    case 0x1c:        /* DMA_CDEI */
957
        ch->element_index[1] = (int16_t) value;
958
        break;
959

    
960
    case 0x1e:        /* DMA_CDFI */
961
        ch->frame_index[1] = (int16_t) value;
962
        break;
963

    
964
    case 0x20:        /* DMA_COLOR_L */
965
        ch->color &= 0xffff0000;
966
        ch->color |= value;
967
        break;
968

    
969
    case 0x22:        /* DMA_COLOR_U */
970
        ch->color &= 0xffff;
971
        ch->color |= value << 16;
972
        break;
973

    
974
    case 0x24:        /* DMA_CCR2 */
975
        ch->bs = (value >> 2) & 0x1;
976
        ch->transparent_copy = (value >> 1) & 0x1;
977
        ch->constant_fill = value & 0x1;
978
        break;
979

    
980
    case 0x28:        /* DMA_CLNK_CTRL */
981
        ch->link_enabled = (value >> 15) & 0x1;
982
        if (value & (1 << 14)) {                        /* Stop_Lnk */
983
            ch->link_enabled = 0;
984
            omap_dma_disable_channel(s, ch);
985
        }
986
        ch->link_next_ch = value & 0x1f;
987
        break;
988

    
989
    case 0x2a:        /* DMA_LCH_CTRL */
990
        ch->interleave_disabled = (value >> 15) & 0x1;
991
        ch->type = value & 0xf;
992
        break;
993

    
994
    default:
995
        return 1;
996
    }
997
    return 0;
998
}
999

    
1000
static int omap_dma_3_2_lcd_write(struct omap_dma_lcd_channel_s *s, int offset,
1001
                uint16_t value)
1002
{
1003
    switch (offset) {
1004
    case 0xbc0:        /* DMA_LCD_CSDP */
1005
        s->brust_f2 = (value >> 14) & 0x3;
1006
        s->pack_f2 = (value >> 13) & 0x1;
1007
        s->data_type_f2 = (1 << ((value >> 11) & 0x3));
1008
        s->brust_f1 = (value >> 7) & 0x3;
1009
        s->pack_f1 = (value >> 6) & 0x1;
1010
        s->data_type_f1 = (1 << ((value >> 0) & 0x3));
1011
        break;
1012

    
1013
    case 0xbc2:        /* DMA_LCD_CCR */
1014
        s->mode_f2 = (value >> 14) & 0x3;
1015
        s->mode_f1 = (value >> 12) & 0x3;
1016
        s->end_prog = (value >> 11) & 0x1;
1017
        s->omap_3_1_compatible_disable = (value >> 10) & 0x1;
1018
        s->repeat = (value >> 9) & 0x1;
1019
        s->auto_init = (value >> 8) & 0x1;
1020
        s->running = (value >> 7) & 0x1;
1021
        s->priority = (value >> 6) & 0x1;
1022
        s->bs = (value >> 4) & 0x1;
1023
        break;
1024

    
1025
    case 0xbc4:        /* DMA_LCD_CTRL */
1026
        s->dst = (value >> 8) & 0x1;
1027
        s->src = ((value >> 6) & 0x3) << 1;
1028
        s->condition = 0;
1029
        /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
1030
        s->interrupts = (value >> 1) & 1;
1031
        s->dual = value & 1;
1032
        break;
1033

    
1034
    case 0xbc8:        /* TOP_B1_L */
1035
        s->src_f1_top &= 0xffff0000;
1036
        s->src_f1_top |= 0x0000ffff & value;
1037
        break;
1038

    
1039
    case 0xbca:        /* TOP_B1_U */
1040
        s->src_f1_top &= 0x0000ffff;
1041
        s->src_f1_top |= value << 16;
1042
        break;
1043

    
1044
    case 0xbcc:        /* BOT_B1_L */
1045
        s->src_f1_bottom &= 0xffff0000;
1046
        s->src_f1_bottom |= 0x0000ffff & value;
1047
        break;
1048

    
1049
    case 0xbce:        /* BOT_B1_U */
1050
        s->src_f1_bottom &= 0x0000ffff;
1051
        s->src_f1_bottom |= (uint32_t) value << 16;
1052
        break;
1053

    
1054
    case 0xbd0:        /* TOP_B2_L */
1055
        s->src_f2_top &= 0xffff0000;
1056
        s->src_f2_top |= 0x0000ffff & value;
1057
        break;
1058

    
1059
    case 0xbd2:        /* TOP_B2_U */
1060
        s->src_f2_top &= 0x0000ffff;
1061
        s->src_f2_top |= (uint32_t) value << 16;
1062
        break;
1063

    
1064
    case 0xbd4:        /* BOT_B2_L */
1065
        s->src_f2_bottom &= 0xffff0000;
1066
        s->src_f2_bottom |= 0x0000ffff & value;
1067
        break;
1068

    
1069
    case 0xbd6:        /* BOT_B2_U */
1070
        s->src_f2_bottom &= 0x0000ffff;
1071
        s->src_f2_bottom |= (uint32_t) value << 16;
1072
        break;
1073

    
1074
    case 0xbd8:        /* DMA_LCD_SRC_EI_B1 */
1075
        s->element_index_f1 = value;
1076
        break;
1077

    
1078
    case 0xbda:        /* DMA_LCD_SRC_FI_B1_L */
1079
        s->frame_index_f1 &= 0xffff0000;
1080
        s->frame_index_f1 |= 0x0000ffff & value;
1081
        break;
1082

    
1083
    case 0xbf4:        /* DMA_LCD_SRC_FI_B1_U */
1084
        s->frame_index_f1 &= 0x0000ffff;
1085
        s->frame_index_f1 |= (uint32_t) value << 16;
1086
        break;
1087

    
1088
    case 0xbdc:        /* DMA_LCD_SRC_EI_B2 */
1089
        s->element_index_f2 = value;
1090
        break;
1091

    
1092
    case 0xbde:        /* DMA_LCD_SRC_FI_B2_L */
1093
        s->frame_index_f2 &= 0xffff0000;
1094
        s->frame_index_f2 |= 0x0000ffff & value;
1095
        break;
1096

    
1097
    case 0xbf6:        /* DMA_LCD_SRC_FI_B2_U */
1098
        s->frame_index_f2 &= 0x0000ffff;
1099
        s->frame_index_f2 |= (uint32_t) value << 16;
1100
        break;
1101

    
1102
    case 0xbe0:        /* DMA_LCD_SRC_EN_B1 */
1103
        s->elements_f1 = value;
1104
        break;
1105

    
1106
    case 0xbe4:        /* DMA_LCD_SRC_FN_B1 */
1107
        s->frames_f1 = value;
1108
        break;
1109

    
1110
    case 0xbe2:        /* DMA_LCD_SRC_EN_B2 */
1111
        s->elements_f2 = value;
1112
        break;
1113

    
1114
    case 0xbe6:        /* DMA_LCD_SRC_FN_B2 */
1115
        s->frames_f2 = value;
1116
        break;
1117

    
1118
    case 0xbea:        /* DMA_LCD_LCH_CTRL */
1119
        s->lch_type = value & 0xf;
1120
        break;
1121

    
1122
    default:
1123
        return 1;
1124
    }
1125
    return 0;
1126
}
1127

    
1128
static int omap_dma_3_2_lcd_read(struct omap_dma_lcd_channel_s *s, int offset,
1129
                uint16_t *ret)
1130
{
1131
    switch (offset) {
1132
    case 0xbc0:        /* DMA_LCD_CSDP */
1133
        *ret = (s->brust_f2 << 14) |
1134
            (s->pack_f2 << 13) |
1135
            ((s->data_type_f2 >> 1) << 11) |
1136
            (s->brust_f1 << 7) |
1137
            (s->pack_f1 << 6) |
1138
            ((s->data_type_f1 >> 1) << 0);
1139
        break;
1140

    
1141
    case 0xbc2:        /* DMA_LCD_CCR */
1142
        *ret = (s->mode_f2 << 14) |
1143
            (s->mode_f1 << 12) |
1144
            (s->end_prog << 11) |
1145
            (s->omap_3_1_compatible_disable << 10) |
1146
            (s->repeat << 9) |
1147
            (s->auto_init << 8) |
1148
            (s->running << 7) |
1149
            (s->priority << 6) |
1150
            (s->bs << 4);
1151
        break;
1152

    
1153
    case 0xbc4:        /* DMA_LCD_CTRL */
1154
        qemu_irq_lower(s->irq);
1155
        *ret = (s->dst << 8) |
1156
            ((s->src & 0x6) << 5) |
1157
            (s->condition << 3) |
1158
            (s->interrupts << 1) |
1159
            s->dual;
1160
        break;
1161

    
1162
    case 0xbc8:        /* TOP_B1_L */
1163
        *ret = s->src_f1_top & 0xffff;
1164
        break;
1165

    
1166
    case 0xbca:        /* TOP_B1_U */
1167
        *ret = s->src_f1_top >> 16;
1168
        break;
1169

    
1170
    case 0xbcc:        /* BOT_B1_L */
1171
        *ret = s->src_f1_bottom & 0xffff;
1172
        break;
1173

    
1174
    case 0xbce:        /* BOT_B1_U */
1175
        *ret = s->src_f1_bottom >> 16;
1176
        break;
1177

    
1178
    case 0xbd0:        /* TOP_B2_L */
1179
        *ret = s->src_f2_top & 0xffff;
1180
        break;
1181

    
1182
    case 0xbd2:        /* TOP_B2_U */
1183
        *ret = s->src_f2_top >> 16;
1184
        break;
1185

    
1186
    case 0xbd4:        /* BOT_B2_L */
1187
        *ret = s->src_f2_bottom & 0xffff;
1188
        break;
1189

    
1190
    case 0xbd6:        /* BOT_B2_U */
1191
        *ret = s->src_f2_bottom >> 16;
1192
        break;
1193

    
1194
    case 0xbd8:        /* DMA_LCD_SRC_EI_B1 */
1195
        *ret = s->element_index_f1;
1196
        break;
1197

    
1198
    case 0xbda:        /* DMA_LCD_SRC_FI_B1_L */
1199
        *ret = s->frame_index_f1 & 0xffff;
1200
        break;
1201

    
1202
    case 0xbf4:        /* DMA_LCD_SRC_FI_B1_U */
1203
        *ret = s->frame_index_f1 >> 16;
1204
        break;
1205

    
1206
    case 0xbdc:        /* DMA_LCD_SRC_EI_B2 */
1207
        *ret = s->element_index_f2;
1208
        break;
1209

    
1210
    case 0xbde:        /* DMA_LCD_SRC_FI_B2_L */
1211
        *ret = s->frame_index_f2 & 0xffff;
1212
        break;
1213

    
1214
    case 0xbf6:        /* DMA_LCD_SRC_FI_B2_U */
1215
        *ret = s->frame_index_f2 >> 16;
1216
        break;
1217

    
1218
    case 0xbe0:        /* DMA_LCD_SRC_EN_B1 */
1219
        *ret = s->elements_f1;
1220
        break;
1221

    
1222
    case 0xbe4:        /* DMA_LCD_SRC_FN_B1 */
1223
        *ret = s->frames_f1;
1224
        break;
1225

    
1226
    case 0xbe2:        /* DMA_LCD_SRC_EN_B2 */
1227
        *ret = s->elements_f2;
1228
        break;
1229

    
1230
    case 0xbe6:        /* DMA_LCD_SRC_FN_B2 */
1231
        *ret = s->frames_f2;
1232
        break;
1233

    
1234
    case 0xbea:        /* DMA_LCD_LCH_CTRL */
1235
        *ret = s->lch_type;
1236
        break;
1237

    
1238
    default:
1239
        return 1;
1240
    }
1241
    return 0;
1242
}
1243

    
1244
static int omap_dma_3_1_lcd_write(struct omap_dma_lcd_channel_s *s, int offset,
1245
                uint16_t value)
1246
{
1247
    switch (offset) {
1248
    case 0x300:        /* SYS_DMA_LCD_CTRL */
1249
        s->src = (value & 0x40) ? imif : emiff;
1250
        s->condition = 0;
1251
        /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
1252
        s->interrupts = (value >> 1) & 1;
1253
        s->dual = value & 1;
1254
        break;
1255

    
1256
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
1257
        s->src_f1_top &= 0xffff0000;
1258
        s->src_f1_top |= 0x0000ffff & value;
1259
        break;
1260

    
1261
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
1262
        s->src_f1_top &= 0x0000ffff;
1263
        s->src_f1_top |= value << 16;
1264
        break;
1265

    
1266
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
1267
        s->src_f1_bottom &= 0xffff0000;
1268
        s->src_f1_bottom |= 0x0000ffff & value;
1269
        break;
1270

    
1271
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
1272
        s->src_f1_bottom &= 0x0000ffff;
1273
        s->src_f1_bottom |= value << 16;
1274
        break;
1275

    
1276
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
1277
        s->src_f2_top &= 0xffff0000;
1278
        s->src_f2_top |= 0x0000ffff & value;
1279
        break;
1280

    
1281
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
1282
        s->src_f2_top &= 0x0000ffff;
1283
        s->src_f2_top |= value << 16;
1284
        break;
1285

    
1286
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
1287
        s->src_f2_bottom &= 0xffff0000;
1288
        s->src_f2_bottom |= 0x0000ffff & value;
1289
        break;
1290

    
1291
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
1292
        s->src_f2_bottom &= 0x0000ffff;
1293
        s->src_f2_bottom |= value << 16;
1294
        break;
1295

    
1296
    default:
1297
        return 1;
1298
    }
1299
    return 0;
1300
}
1301

    
1302
static int omap_dma_3_1_lcd_read(struct omap_dma_lcd_channel_s *s, int offset,
1303
                uint16_t *ret)
1304
{
1305
    int i;
1306

    
1307
    switch (offset) {
1308
    case 0x300:        /* SYS_DMA_LCD_CTRL */
1309
        i = s->condition;
1310
        s->condition = 0;
1311
        qemu_irq_lower(s->irq);
1312
        *ret = ((s->src == imif) << 6) | (i << 3) |
1313
                (s->interrupts << 1) | s->dual;
1314
        break;
1315

    
1316
    case 0x302:        /* SYS_DMA_LCD_TOP_F1_L */
1317
        *ret = s->src_f1_top & 0xffff;
1318
        break;
1319

    
1320
    case 0x304:        /* SYS_DMA_LCD_TOP_F1_U */
1321
        *ret = s->src_f1_top >> 16;
1322
        break;
1323

    
1324
    case 0x306:        /* SYS_DMA_LCD_BOT_F1_L */
1325
        *ret = s->src_f1_bottom & 0xffff;
1326
        break;
1327

    
1328
    case 0x308:        /* SYS_DMA_LCD_BOT_F1_U */
1329
        *ret = s->src_f1_bottom >> 16;
1330
        break;
1331

    
1332
    case 0x30a:        /* SYS_DMA_LCD_TOP_F2_L */
1333
        *ret = s->src_f2_top & 0xffff;
1334
        break;
1335

    
1336
    case 0x30c:        /* SYS_DMA_LCD_TOP_F2_U */
1337
        *ret = s->src_f2_top >> 16;
1338
        break;
1339

    
1340
    case 0x30e:        /* SYS_DMA_LCD_BOT_F2_L */
1341
        *ret = s->src_f2_bottom & 0xffff;
1342
        break;
1343

    
1344
    case 0x310:        /* SYS_DMA_LCD_BOT_F2_U */
1345
        *ret = s->src_f2_bottom >> 16;
1346
        break;
1347

    
1348
    default:
1349
        return 1;
1350
    }
1351
    return 0;
1352
}
1353

    
1354
static int omap_dma_sys_write(struct omap_dma_s *s, int offset, uint16_t value)
1355
{
1356
    switch (offset) {
1357
    case 0x400:        /* SYS_DMA_GCR */
1358
        s->gcr = value;
1359
        break;
1360

    
1361
    case 0x404:        /* DMA_GSCR */
1362
        if (value & 0x8)
1363
            omap_dma_disable_3_1_mapping(s);
1364
        else
1365
            omap_dma_enable_3_1_mapping(s);
1366
        break;
1367

    
1368
    case 0x408:        /* DMA_GRST */
1369
        if (value & 0x1)
1370
            omap_dma_reset(s->dma);
1371
        break;
1372

    
1373
    default:
1374
        return 1;
1375
    }
1376
    return 0;
1377
}
1378

    
1379
static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
1380
                uint16_t *ret)
1381
{
1382
    switch (offset) {
1383
    case 0x400:        /* SYS_DMA_GCR */
1384
        *ret = s->gcr;
1385
        break;
1386

    
1387
    case 0x404:        /* DMA_GSCR */
1388
        *ret = s->omap_3_1_mapping_disabled << 3;
1389
        break;
1390

    
1391
    case 0x408:        /* DMA_GRST */
1392
        *ret = 0;
1393
        break;
1394

    
1395
    case 0x442:        /* DMA_HW_ID */
1396
    case 0x444:        /* DMA_PCh2_ID */
1397
    case 0x446:        /* DMA_PCh0_ID */
1398
    case 0x448:        /* DMA_PCh1_ID */
1399
    case 0x44a:        /* DMA_PChG_ID */
1400
    case 0x44c:        /* DMA_PChD_ID */
1401
        *ret = 1;
1402
        break;
1403

    
1404
    case 0x44e:        /* DMA_CAPS_0_U */
1405
        *ret = (s->caps[0] >> 16) & 0xffff;
1406
        break;
1407
    case 0x450:        /* DMA_CAPS_0_L */
1408
        *ret = (s->caps[0] >>  0) & 0xffff;
1409
        break;
1410

    
1411
    case 0x452:        /* DMA_CAPS_1_U */
1412
        *ret = (s->caps[1] >> 16) & 0xffff;
1413
        break;
1414
    case 0x454:        /* DMA_CAPS_1_L */
1415
        *ret = (s->caps[1] >>  0) & 0xffff;
1416
        break;
1417

    
1418
    case 0x456:        /* DMA_CAPS_2 */
1419
        *ret = s->caps[2];
1420
        break;
1421

    
1422
    case 0x458:        /* DMA_CAPS_3 */
1423
        *ret = s->caps[3];
1424
        break;
1425

    
1426
    case 0x45a:        /* DMA_CAPS_4 */
1427
        *ret = s->caps[4];
1428
        break;
1429

    
1430
    case 0x460:        /* DMA_PCh2_SR */
1431
    case 0x480:        /* DMA_PCh0_SR */
1432
    case 0x482:        /* DMA_PCh1_SR */
1433
    case 0x4c0:        /* DMA_PChD_SR_0 */
1434
        printf("%s: Physical Channel Status Registers not implemented.\n",
1435
               __FUNCTION__);
1436
        *ret = 0xff;
1437
        break;
1438

    
1439
    default:
1440
        return 1;
1441
    }
1442
    return 0;
1443
}
1444

    
1445
static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
1446
{
1447
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1448
    int reg, ch;
1449
    uint16_t ret;
1450

    
1451
    switch (addr) {
1452
    case 0x300 ... 0x3fe:
1453
        if (s->model <= omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
1454
            if (omap_dma_3_1_lcd_read(&s->lcd_ch, addr, &ret))
1455
                break;
1456
            return ret;
1457
        }
1458
        /* Fall through. */
1459
    case 0x000 ... 0x2fe:
1460
        reg = addr & 0x3f;
1461
        ch = (addr >> 6) & 0x0f;
1462
        if (omap_dma_ch_reg_read(s, &s->ch[ch], reg, &ret))
1463
            break;
1464
        return ret;
1465

    
1466
    case 0x404 ... 0x4fe:
1467
        if (s->model <= omap_dma_3_1)
1468
            break;
1469
        /* Fall through. */
1470
    case 0x400:
1471
        if (omap_dma_sys_read(s, addr, &ret))
1472
            break;
1473
        return ret;
1474

    
1475
    case 0xb00 ... 0xbfe:
1476
        if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
1477
            if (omap_dma_3_2_lcd_read(&s->lcd_ch, addr, &ret))
1478
                break;
1479
            return ret;
1480
        }
1481
        break;
1482
    }
1483

    
1484
    OMAP_BAD_REG(addr);
1485
    return 0;
1486
}
1487

    
1488
static void omap_dma_write(void *opaque, target_phys_addr_t addr,
1489
                uint32_t value)
1490
{
1491
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1492
    int reg, ch;
1493

    
1494
    switch (addr) {
1495
    case 0x300 ... 0x3fe:
1496
        if (s->model <= omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
1497
            if (omap_dma_3_1_lcd_write(&s->lcd_ch, addr, value))
1498
                break;
1499
            return;
1500
        }
1501
        /* Fall through.  */
1502
    case 0x000 ... 0x2fe:
1503
        reg = addr & 0x3f;
1504
        ch = (addr >> 6) & 0x0f;
1505
        if (omap_dma_ch_reg_write(s, &s->ch[ch], reg, value))
1506
            break;
1507
        return;
1508

    
1509
    case 0x404 ... 0x4fe:
1510
        if (s->model <= omap_dma_3_1)
1511
            break;
1512
    case 0x400:
1513
        /* Fall through. */
1514
        if (omap_dma_sys_write(s, addr, value))
1515
            break;
1516
        return;
1517

    
1518
    case 0xb00 ... 0xbfe:
1519
        if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
1520
            if (omap_dma_3_2_lcd_write(&s->lcd_ch, addr, value))
1521
                break;
1522
            return;
1523
        }
1524
        break;
1525
    }
1526

    
1527
    OMAP_BAD_REG(addr);
1528
}
1529

    
1530
static CPUReadMemoryFunc *omap_dma_readfn[] = {
1531
    omap_badwidth_read16,
1532
    omap_dma_read,
1533
    omap_badwidth_read16,
1534
};
1535

    
1536
static CPUWriteMemoryFunc *omap_dma_writefn[] = {
1537
    omap_badwidth_write16,
1538
    omap_dma_write,
1539
    omap_badwidth_write16,
1540
};
1541

    
1542
static void omap_dma_request(void *opaque, int drq, int req)
1543
{
1544
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1545
    /* The request pins are level triggered in QEMU.  */
1546
    if (req) {
1547
        if (~s->dma->drqbmp & (1 << drq)) {
1548
            s->dma->drqbmp |= 1 << drq;
1549
            omap_dma_process_request(s, drq);
1550
        }
1551
    } else
1552
        s->dma->drqbmp &= ~(1 << drq);
1553
}
1554

    
1555
/* XXX: this won't be needed once soc_dma knows about clocks.  */
1556
static void omap_dma_clk_update(void *opaque, int line, int on)
1557
{
1558
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1559
    int i;
1560

    
1561
    s->dma->freq = omap_clk_getrate(s->clk);
1562

    
1563
    for (i = 0; i < s->chans; i ++)
1564
        if (s->ch[i].active)
1565
            soc_dma_set_request(s->ch[i].dma, on);
1566
}
1567

    
1568
static void omap_dma_setcaps(struct omap_dma_s *s)
1569
{
1570
    switch (s->model) {
1571
    default:
1572
    case omap_dma_3_1:
1573
        break;
1574
    case omap_dma_3_2:
1575
    case omap_dma_4:
1576
        /* XXX Only available for sDMA */
1577
        s->caps[0] =
1578
                (1 << 19) |        /* Constant Fill Capability */
1579
                (1 << 18);        /* Transparent BLT Capability */
1580
        s->caps[1] =
1581
                (1 << 1);        /* 1-bit palettized capability (DMA 3.2 only) */
1582
        s->caps[2] =
1583
                (1 << 8) |        /* SEPARATE_SRC_AND_DST_INDEX_CPBLTY */
1584
                (1 << 7) |        /* DST_DOUBLE_INDEX_ADRS_CPBLTY */
1585
                (1 << 6) |        /* DST_SINGLE_INDEX_ADRS_CPBLTY */
1586
                (1 << 5) |        /* DST_POST_INCRMNT_ADRS_CPBLTY */
1587
                (1 << 4) |        /* DST_CONST_ADRS_CPBLTY */
1588
                (1 << 3) |        /* SRC_DOUBLE_INDEX_ADRS_CPBLTY */
1589
                (1 << 2) |        /* SRC_SINGLE_INDEX_ADRS_CPBLTY */
1590
                (1 << 1) |        /* SRC_POST_INCRMNT_ADRS_CPBLTY */
1591
                (1 << 0);        /* SRC_CONST_ADRS_CPBLTY */
1592
        s->caps[3] =
1593
                (1 << 6) |        /* BLOCK_SYNCHR_CPBLTY (DMA 4 only) */
1594
                (1 << 7) |        /* PKT_SYNCHR_CPBLTY (DMA 4 only) */
1595
                (1 << 5) |        /* CHANNEL_CHAINING_CPBLTY */
1596
                (1 << 4) |        /* LCh_INTERLEAVE_CPBLTY */
1597
                (1 << 3) |        /* AUTOINIT_REPEAT_CPBLTY (DMA 3.2 only) */
1598
                (1 << 2) |        /* AUTOINIT_ENDPROG_CPBLTY (DMA 3.2 only) */
1599
                (1 << 1) |        /* FRAME_SYNCHR_CPBLTY */
1600
                (1 << 0);        /* ELMNT_SYNCHR_CPBLTY */
1601
        s->caps[4] =
1602
                (1 << 7) |        /* PKT_INTERRUPT_CPBLTY (DMA 4 only) */
1603
                (1 << 6) |        /* SYNC_STATUS_CPBLTY */
1604
                (1 << 5) |        /* BLOCK_INTERRUPT_CPBLTY */
1605
                (1 << 4) |        /* LAST_FRAME_INTERRUPT_CPBLTY */
1606
                (1 << 3) |        /* FRAME_INTERRUPT_CPBLTY */
1607
                (1 << 2) |        /* HALF_FRAME_INTERRUPT_CPBLTY */
1608
                (1 << 1) |        /* EVENT_DROP_INTERRUPT_CPBLTY */
1609
                (1 << 0);        /* TIMEOUT_INTERRUPT_CPBLTY (DMA 3.2 only) */
1610
        break;
1611
    }
1612
}
1613

    
1614
struct soc_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
1615
                qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
1616
                enum omap_dma_model model)
1617
{
1618
    int iomemtype, num_irqs, memsize, i;
1619
    struct omap_dma_s *s = (struct omap_dma_s *)
1620
            qemu_mallocz(sizeof(struct omap_dma_s));
1621

    
1622
    if (model <= omap_dma_3_1) {
1623
        num_irqs = 6;
1624
        memsize = 0x800;
1625
    } else {
1626
        num_irqs = 16;
1627
        memsize = 0xc00;
1628
    }
1629
    s->model = model;
1630
    s->mpu = mpu;
1631
    s->clk = clk;
1632
    s->lcd_ch.irq = lcd_irq;
1633
    s->lcd_ch.mpu = mpu;
1634

    
1635
    s->dma = soc_dma_init((model <= omap_dma_3_1) ? 9 : 16);
1636
    s->dma->freq = omap_clk_getrate(clk);
1637
    s->dma->transfer_fn = omap_dma_transfer_generic;
1638
    s->dma->setup_fn = omap_dma_transfer_setup;
1639
    s->dma->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1640
    s->dma->opaque = s;
1641

    
1642
    while (num_irqs --)
1643
        s->ch[num_irqs].irq = irqs[num_irqs];
1644
    for (i = 0; i < 3; i ++) {
1645
        s->ch[i].sibling = &s->ch[i + 6];
1646
        s->ch[i + 6].sibling = &s->ch[i];
1647
    }
1648
    for (i = (model <= omap_dma_3_1) ? 8 : 15; i >= 0; i --) {
1649
        s->ch[i].dma = &s->dma->ch[i];
1650
        s->dma->ch[i].opaque = &s->ch[i];
1651
    }
1652

    
1653
    omap_dma_setcaps(s);
1654
    omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1655
    omap_dma_reset(s->dma);
1656
    omap_dma_clk_update(s, 0, 1);
1657

    
1658
    iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1659
                    omap_dma_writefn, s);
1660
    cpu_register_physical_memory(base, memsize, iomemtype);
1661

    
1662
    mpu->drq = s->dma->drq;
1663

    
1664
    return s->dma;
1665
}
1666

    
1667
static void omap_dma_interrupts_4_update(struct omap_dma_s *s)
1668
{
1669
    struct omap_dma_channel_s *ch = s->ch;
1670
    uint32_t bmp, bit;
1671

    
1672
    for (bmp = 0, bit = 1; bit; ch ++, bit <<= 1)
1673
        if (ch->status) {
1674
            bmp |= bit;
1675
            ch->cstatus |= ch->status;
1676
            ch->status = 0;
1677
        }
1678
    if ((s->irqstat[0] |= s->irqen[0] & bmp))
1679
        qemu_irq_raise(s->irq[0]);
1680
    if ((s->irqstat[1] |= s->irqen[1] & bmp))
1681
        qemu_irq_raise(s->irq[1]);
1682
    if ((s->irqstat[2] |= s->irqen[2] & bmp))
1683
        qemu_irq_raise(s->irq[2]);
1684
    if ((s->irqstat[3] |= s->irqen[3] & bmp))
1685
        qemu_irq_raise(s->irq[3]);
1686
}
1687

    
1688
static uint32_t omap_dma4_read(void *opaque, target_phys_addr_t addr)
1689
{
1690
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1691
    int irqn = 0, chnum;
1692
    struct omap_dma_channel_s *ch;
1693

    
1694
    switch (addr) {
1695
    case 0x00:        /* DMA4_REVISION */
1696
        return 0x40;
1697

    
1698
    case 0x14:        /* DMA4_IRQSTATUS_L3 */
1699
        irqn ++;
1700
    case 0x10:        /* DMA4_IRQSTATUS_L2 */
1701
        irqn ++;
1702
    case 0x0c:        /* DMA4_IRQSTATUS_L1 */
1703
        irqn ++;
1704
    case 0x08:        /* DMA4_IRQSTATUS_L0 */
1705
        return s->irqstat[irqn];
1706

    
1707
    case 0x24:        /* DMA4_IRQENABLE_L3 */
1708
        irqn ++;
1709
    case 0x20:        /* DMA4_IRQENABLE_L2 */
1710
        irqn ++;
1711
    case 0x1c:        /* DMA4_IRQENABLE_L1 */
1712
        irqn ++;
1713
    case 0x18:        /* DMA4_IRQENABLE_L0 */
1714
        return s->irqen[irqn];
1715

    
1716
    case 0x28:        /* DMA4_SYSSTATUS */
1717
        return 1;                                                /* RESETDONE */
1718

    
1719
    case 0x2c:        /* DMA4_OCP_SYSCONFIG */
1720
        return s->ocp;
1721

    
1722
    case 0x64:        /* DMA4_CAPS_0 */
1723
        return s->caps[0];
1724
    case 0x6c:        /* DMA4_CAPS_2 */
1725
        return s->caps[2];
1726
    case 0x70:        /* DMA4_CAPS_3 */
1727
        return s->caps[3];
1728
    case 0x74:        /* DMA4_CAPS_4 */
1729
        return s->caps[4];
1730

    
1731
    case 0x78:        /* DMA4_GCR */
1732
        return s->gcr;
1733

    
1734
    case 0x80 ... 0xfff:
1735
        addr -= 0x80;
1736
        chnum = addr / 0x60;
1737
        ch = s->ch + chnum;
1738
        addr -= chnum * 0x60;
1739
        break;
1740

    
1741
    default:
1742
        OMAP_BAD_REG(addr);
1743
        return 0;
1744
    }
1745

    
1746
    /* Per-channel registers */
1747
    switch (addr) {
1748
    case 0x00:        /* DMA4_CCR */
1749
        return (ch->buf_disable << 25) |
1750
                (ch->src_sync << 24) |
1751
                (ch->prefetch << 23) |
1752
                ((ch->sync & 0x60) << 14) |
1753
                (ch->bs << 18) |
1754
                (ch->transparent_copy << 17) |
1755
                (ch->constant_fill << 16) |
1756
                (ch->mode[1] << 14) |
1757
                (ch->mode[0] << 12) |
1758
                (0 << 10) | (0 << 9) |
1759
                (ch->suspend << 8) |
1760
                (ch->enable << 7) |
1761
                (ch->priority << 6) |
1762
                (ch->fs << 5) | (ch->sync & 0x1f);
1763

    
1764
    case 0x04:        /* DMA4_CLNK_CTRL */
1765
        return (ch->link_enabled << 15) | ch->link_next_ch;
1766

    
1767
    case 0x08:        /* DMA4_CICR */
1768
        return ch->interrupts;
1769

    
1770
    case 0x0c:        /* DMA4_CSR */
1771
        return ch->cstatus;
1772

    
1773
    case 0x10:        /* DMA4_CSDP */
1774
        return (ch->endian[0] << 21) |
1775
                (ch->endian_lock[0] << 20) |
1776
                (ch->endian[1] << 19) |
1777
                (ch->endian_lock[1] << 18) |
1778
                (ch->write_mode << 16) |
1779
                (ch->burst[1] << 14) |
1780
                (ch->pack[1] << 13) |
1781
                (ch->translate[1] << 9) |
1782
                (ch->burst[0] << 7) |
1783
                (ch->pack[0] << 6) |
1784
                (ch->translate[0] << 2) |
1785
                (ch->data_type >> 1);
1786

    
1787
    case 0x14:        /* DMA4_CEN */
1788
        return ch->elements;
1789

    
1790
    case 0x18:        /* DMA4_CFN */
1791
        return ch->frames;
1792

    
1793
    case 0x1c:        /* DMA4_CSSA */
1794
        return ch->addr[0];
1795

    
1796
    case 0x20:        /* DMA4_CDSA */
1797
        return ch->addr[1];
1798

    
1799
    case 0x24:        /* DMA4_CSEI */
1800
        return ch->element_index[0];
1801

    
1802
    case 0x28:        /* DMA4_CSFI */
1803
        return ch->frame_index[0];
1804

    
1805
    case 0x2c:        /* DMA4_CDEI */
1806
        return ch->element_index[1];
1807

    
1808
    case 0x30:        /* DMA4_CDFI */
1809
        return ch->frame_index[1];
1810

    
1811
    case 0x34:        /* DMA4_CSAC */
1812
        return ch->active_set.src & 0xffff;
1813

    
1814
    case 0x38:        /* DMA4_CDAC */
1815
        return ch->active_set.dest & 0xffff;
1816

    
1817
    case 0x3c:        /* DMA4_CCEN */
1818
        return ch->active_set.element;
1819

    
1820
    case 0x40:        /* DMA4_CCFN */
1821
        return ch->active_set.frame;
1822

    
1823
    case 0x44:        /* DMA4_COLOR */
1824
        /* XXX only in sDMA */
1825
        return ch->color;
1826

    
1827
    default:
1828
        OMAP_BAD_REG(addr);
1829
        return 0;
1830
    }
1831
}
1832

    
1833
static void omap_dma4_write(void *opaque, target_phys_addr_t addr,
1834
                uint32_t value)
1835
{
1836
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1837
    int chnum, irqn = 0;
1838
    struct omap_dma_channel_s *ch;
1839

    
1840
    switch (addr) {
1841
    case 0x14:        /* DMA4_IRQSTATUS_L3 */
1842
        irqn ++;
1843
    case 0x10:        /* DMA4_IRQSTATUS_L2 */
1844
        irqn ++;
1845
    case 0x0c:        /* DMA4_IRQSTATUS_L1 */
1846
        irqn ++;
1847
    case 0x08:        /* DMA4_IRQSTATUS_L0 */
1848
        s->irqstat[irqn] &= ~value;
1849
        if (!s->irqstat[irqn])
1850
            qemu_irq_lower(s->irq[irqn]);
1851
        return;
1852

    
1853
    case 0x24:        /* DMA4_IRQENABLE_L3 */
1854
        irqn ++;
1855
    case 0x20:        /* DMA4_IRQENABLE_L2 */
1856
        irqn ++;
1857
    case 0x1c:        /* DMA4_IRQENABLE_L1 */
1858
        irqn ++;
1859
    case 0x18:        /* DMA4_IRQENABLE_L0 */
1860
        s->irqen[irqn] = value;
1861
        return;
1862

    
1863
    case 0x2c:        /* DMA4_OCP_SYSCONFIG */
1864
        if (value & 2)                                                /* SOFTRESET */
1865
            omap_dma_reset(s->dma);
1866
        s->ocp = value & 0x3321;
1867
        if (((s->ocp >> 12) & 3) == 3)                                /* MIDLEMODE */
1868
            fprintf(stderr, "%s: invalid DMA power mode\n", __FUNCTION__);
1869
        return;
1870

    
1871
    case 0x78:        /* DMA4_GCR */
1872
        s->gcr = value & 0x00ff00ff;
1873
        if ((value & 0xff) == 0x00)                /* MAX_CHANNEL_FIFO_DEPTH */
1874
            fprintf(stderr, "%s: wrong FIFO depth in GCR\n", __FUNCTION__);
1875
        return;
1876

    
1877
    case 0x80 ... 0xfff:
1878
        addr -= 0x80;
1879
        chnum = addr / 0x60;
1880
        ch = s->ch + chnum;
1881
        addr -= chnum * 0x60;
1882
        break;
1883

    
1884
    case 0x00:        /* DMA4_REVISION */
1885
    case 0x28:        /* DMA4_SYSSTATUS */
1886
    case 0x64:        /* DMA4_CAPS_0 */
1887
    case 0x6c:        /* DMA4_CAPS_2 */
1888
    case 0x70:        /* DMA4_CAPS_3 */
1889
    case 0x74:        /* DMA4_CAPS_4 */
1890
        OMAP_RO_REG(addr);
1891
        return;
1892

    
1893
    default:
1894
        OMAP_BAD_REG(addr);
1895
        return;
1896
    }
1897

    
1898
    /* Per-channel registers */
1899
    switch (addr) {
1900
    case 0x00:        /* DMA4_CCR */
1901
        ch->buf_disable = (value >> 25) & 1;
1902
        ch->src_sync = (value >> 24) & 1;        /* XXX For CamDMA must be 1 */
1903
        if (ch->buf_disable && !ch->src_sync)
1904
            fprintf(stderr, "%s: Buffering disable is not allowed in "
1905
                            "destination synchronised mode\n", __FUNCTION__);
1906
        ch->prefetch = (value >> 23) & 1;
1907
        ch->bs = (value >> 18) & 1;
1908
        ch->transparent_copy = (value >> 17) & 1;
1909
        ch->constant_fill = (value >> 16) & 1;
1910
        ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
1911
        ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
1912
        ch->suspend = (value & 0x0100) >> 8;
1913
        ch->priority = (value & 0x0040) >> 6;
1914
        ch->fs = (value & 0x0020) >> 5;
1915
        if (ch->fs && ch->bs && ch->mode[0] && ch->mode[1])
1916
            fprintf(stderr, "%s: For a packet transfer at least one port "
1917
                            "must be constant-addressed\n", __FUNCTION__);
1918
        ch->sync = (value & 0x001f) | ((value >> 14) & 0x0060);
1919
        /* XXX must be 0x01 for CamDMA */
1920

    
1921
        if (value & 0x0080)
1922
            omap_dma_enable_channel(s, ch);
1923
        else
1924
            omap_dma_disable_channel(s, ch);
1925

    
1926
        break;
1927

    
1928
    case 0x04:        /* DMA4_CLNK_CTRL */
1929
        ch->link_enabled = (value >> 15) & 0x1;
1930
        ch->link_next_ch = value & 0x1f;
1931
        break;
1932

    
1933
    case 0x08:        /* DMA4_CICR */
1934
        ch->interrupts = value & 0x09be;
1935
        break;
1936

    
1937
    case 0x0c:        /* DMA4_CSR */
1938
        ch->cstatus &= ~value;
1939
        break;
1940

    
1941
    case 0x10:        /* DMA4_CSDP */
1942
        ch->endian[0] =(value >> 21) & 1;
1943
        ch->endian_lock[0] =(value >> 20) & 1;
1944
        ch->endian[1] =(value >> 19) & 1;
1945
        ch->endian_lock[1] =(value >> 18) & 1;
1946
        if (ch->endian[0] != ch->endian[1])
1947
            fprintf(stderr, "%s: DMA endiannes conversion enable attempt\n",
1948
                            __FUNCTION__);
1949
        ch->write_mode = (value >> 16) & 3;
1950
        ch->burst[1] = (value & 0xc000) >> 14;
1951
        ch->pack[1] = (value & 0x2000) >> 13;
1952
        ch->translate[1] = (value & 0x1e00) >> 9;
1953
        ch->burst[0] = (value & 0x0180) >> 7;
1954
        ch->pack[0] = (value & 0x0040) >> 6;
1955
        ch->translate[0] = (value & 0x003c) >> 2;
1956
        if (ch->translate[0] | ch->translate[1])
1957
            fprintf(stderr, "%s: bad MReqAddressTranslate sideband signal\n",
1958
                            __FUNCTION__);
1959
        ch->data_type = 1 << (value & 3);
1960
        if ((value & 3) == 3)
1961
            printf("%s: bad data_type for DMA channel\n", __FUNCTION__);
1962
        break;
1963

    
1964
    case 0x14:        /* DMA4_CEN */
1965
        ch->set_update = 1;
1966
        ch->elements = value & 0xffffff;
1967
        break;
1968

    
1969
    case 0x18:        /* DMA4_CFN */
1970
        ch->frames = value & 0xffff;
1971
        ch->set_update = 1;
1972
        break;
1973

    
1974
    case 0x1c:        /* DMA4_CSSA */
1975
        ch->addr[0] = (target_phys_addr_t) (uint32_t) value;
1976
        ch->set_update = 1;
1977
        break;
1978

    
1979
    case 0x20:        /* DMA4_CDSA */
1980
        ch->addr[1] = (target_phys_addr_t) (uint32_t) value;
1981
        ch->set_update = 1;
1982
        break;
1983

    
1984
    case 0x24:        /* DMA4_CSEI */
1985
        ch->element_index[0] = (int16_t) value;
1986
        ch->set_update = 1;
1987
        break;
1988

    
1989
    case 0x28:        /* DMA4_CSFI */
1990
        ch->frame_index[0] = (int32_t) value;
1991
        ch->set_update = 1;
1992
        break;
1993

    
1994
    case 0x2c:        /* DMA4_CDEI */
1995
        ch->element_index[1] = (int16_t) value;
1996
        ch->set_update = 1;
1997
        break;
1998

    
1999
    case 0x30:        /* DMA4_CDFI */
2000
        ch->frame_index[1] = (int32_t) value;
2001
        ch->set_update = 1;
2002
        break;
2003

    
2004
    case 0x44:        /* DMA4_COLOR */
2005
        /* XXX only in sDMA */
2006
        ch->color = value;
2007
        break;
2008

    
2009
    case 0x34:        /* DMA4_CSAC */
2010
    case 0x38:        /* DMA4_CDAC */
2011
    case 0x3c:        /* DMA4_CCEN */
2012
    case 0x40:        /* DMA4_CCFN */
2013
        OMAP_RO_REG(addr);
2014
        break;
2015

    
2016
    default:
2017
        OMAP_BAD_REG(addr);
2018
    }
2019
}
2020

    
2021
static CPUReadMemoryFunc *omap_dma4_readfn[] = {
2022
    omap_badwidth_read16,
2023
    omap_dma4_read,
2024
    omap_dma4_read,
2025
};
2026

    
2027
static CPUWriteMemoryFunc *omap_dma4_writefn[] = {
2028
    omap_badwidth_write16,
2029
    omap_dma4_write,
2030
    omap_dma4_write,
2031
};
2032

    
2033
struct soc_dma_s *omap_dma4_init(target_phys_addr_t base, qemu_irq *irqs,
2034
                struct omap_mpu_state_s *mpu, int fifo,
2035
                int chans, omap_clk iclk, omap_clk fclk)
2036
{
2037
    int iomemtype, i;
2038
    struct omap_dma_s *s = (struct omap_dma_s *)
2039
            qemu_mallocz(sizeof(struct omap_dma_s));
2040

    
2041
    s->model = omap_dma_4;
2042
    s->chans = chans;
2043
    s->mpu = mpu;
2044
    s->clk = fclk;
2045

    
2046
    s->dma = soc_dma_init(s->chans);
2047
    s->dma->freq = omap_clk_getrate(fclk);
2048
    s->dma->transfer_fn = omap_dma_transfer_generic;
2049
    s->dma->setup_fn = omap_dma_transfer_setup;
2050
    s->dma->drq = qemu_allocate_irqs(omap_dma_request, s, 64);
2051
    s->dma->opaque = s;
2052
    for (i = 0; i < s->chans; i ++) {
2053
        s->ch[i].dma = &s->dma->ch[i];
2054
        s->dma->ch[i].opaque = &s->ch[i];
2055
    }
2056

    
2057
    memcpy(&s->irq, irqs, sizeof(s->irq));
2058
    s->intr_update = omap_dma_interrupts_4_update;
2059

    
2060
    omap_dma_setcaps(s);
2061
    omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
2062
    omap_dma_reset(s->dma);
2063
    omap_dma_clk_update(s, 0, !!s->dma->freq);
2064

    
2065
    iomemtype = cpu_register_io_memory(0, omap_dma4_readfn,
2066
                    omap_dma4_writefn, s);
2067
    cpu_register_physical_memory(base, 0x1000, iomemtype);
2068

    
2069
    mpu->drq = s->dma->drq;
2070

    
2071
    return s->dma;
2072
}
2073

    
2074
struct omap_dma_lcd_channel_s *omap_dma_get_lcdch(struct soc_dma_s *dma)
2075
{
2076
    struct omap_dma_s *s = dma->opaque;
2077

    
2078
    return &s->lcd_ch;
2079
}