Revision afbb5194 hw/omap_dma.c

b/hw/omap_dma.c
23 23
#include "qemu-timer.h"
24 24
#include "omap.h"
25 25
#include "irq.h"
26
#include "soc_dma.h"
26 27

  
27 28
struct omap_dma_channel_s {
28 29
    /* transfer data */
......
66 67
    int pending_request;
67 68
    int waiting_end_prog;
68 69
    uint16_t cpc;
70
    int set_update;
69 71

  
70 72
    /* sync type */
71 73
    int fs;
......
89 91
        int pck_elements;
90 92
    } active_set;
91 93

  
94
    struct soc_dma_ch_s *dma;
95

  
92 96
    /* unused parameters */
93 97
    int write_mode;
94 98
    int priority;
......
99 103
};
100 104

  
101 105
struct omap_dma_s {
102
    QEMUTimer *tm;
106
    struct soc_dma_s *dma;
107

  
103 108
    struct omap_mpu_state_s *mpu;
104 109
    target_phys_addr_t base;
105 110
    omap_clk clk;
106
    int64_t delay;
107
    uint64_t drq;
108 111
    qemu_irq irq[4];
109 112
    void (*intr_update)(struct omap_dma_s *s);
110 113
    enum omap_dma_model model;
......
115 118
    uint32_t caps[5];
116 119
    uint32_t irqen[4];
117 120
    uint32_t irqstat[4];
118
    int run_count;
119 121

  
120 122
    int chans;
121 123
    struct omap_dma_channel_s ch[32];
......
139 141
    return s->intr_update(s);
140 142
}
141 143

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

  
149 150
    /*
......
189 190
        default:
190 191
            break;
191 192
        }
193

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

  
212
        ch->dma->vaddr[i] = ch->addr[i];
213
    }
214
    soc_dma_ch_update(ch->dma);
192 215
}
193 216

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

  
198 232
        ch->active = 1;
233
        soc_dma_set_request(ch->dma, 1);
199 234
        if (ch->sync)
200 235
            ch->status |= SYNC;
201
        s->run_count ++;
202 236
    }
203

  
204
    if (s->delay && !qemu_timer_pending(s->tm))
205
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
206 237
}
207 238

  
208 239
static void omap_dma_deactivate_channel(struct omap_dma_s *s,
......
219 250

  
220 251
    /* Don't deactive the channel if it is synchronized and the DMA request is
221 252
       active */
222
    if (ch->sync && ch->enable && (s->drq & (1 << ch->sync)))
253
    if (ch->sync && ch->enable && (s->dma->drqbmp & (1 << ch->sync)))
223 254
        return;
224 255

  
225 256
    if (ch->active) {
226 257
        ch->active = 0;
227 258
        ch->status &= ~SYNC;
228
        s->run_count --;
259
        soc_dma_set_request(ch->dma, 0);
229 260
    }
230

  
231
    if (!s->run_count)
232
        qemu_del_timer(s->tm);
233 261
}
234 262

  
235 263
static void omap_dma_enable_channel(struct omap_dma_s *s,
......
238 266
    if (!ch->enable) {
239 267
        ch->enable = 1;
240 268
        ch->waiting_end_prog = 0;
241
        omap_dma_channel_load(s, ch);
269
        omap_dma_channel_load(ch);
242 270
        /* TODO: theoretically if ch->sync && ch->prefetch &&
243
         * !s->drq[ch->sync], we should also activate and fetch from source
244
         * and then stall until signalled.  */
245
        if ((!ch->sync) || (s->drq & (1 << ch->sync)))
271
         * !s->dma->drqbmp[ch->sync], we should also activate and fetch
272
         * from source and then stall until signalled.  */
273
        if ((!ch->sync) || (s->dma->drqbmp & (1 << ch->sync)))
246 274
            omap_dma_activate_channel(s, ch);
247 275
    }
248 276
}
......
338 366
        omap_dma_interrupts_update(s);
339 367
}
340 368

  
341
static void omap_dma_channel_run(struct omap_dma_s *s)
369
static void omap_dma_transfer_generic(struct soc_dma_ch_s *dma)
342 370
{
343
    int n = s->chans;
344
    uint16_t status;
345 371
    uint8_t value[4];
346
    struct omap_dma_port_if_s *src_p, *dest_p;
347
    struct omap_dma_reg_set_s *a;
348
    struct omap_dma_channel_s *ch;
349

  
350
    for (ch = s->ch; n; n --, ch ++) {
351
        if (!ch->active)
352
            continue;
353

  
354
        a = &ch->active_set;
372
    struct omap_dma_channel_s *ch = dma->opaque;
373
    struct omap_dma_reg_set_s *a = &ch->active_set;
374
    int bytes = dma->bytes;
375
#ifdef MULTI_REQ
376
    uint16_t status = ch->status;
377
#endif
355 378

  
356
        src_p = &s->mpu->port[ch->port[0]];
357
        dest_p = &s->mpu->port[ch->port[1]];
358
        if ((!ch->constant_fill && !src_p->addr_valid(s->mpu, a->src)) ||
359
                        (!dest_p->addr_valid(s->mpu, a->dest))) {
360
#if 0
361
            /* Bus time-out */
362
            if (ch->interrupts & TIMEOUT_INTR)
363
                ch->status |= TIMEOUT_INTR;
379
    do {
380
        /* Transfer a single element */
381
        /* FIXME: check the endianness */
382
        if (!ch->constant_fill)
383
            cpu_physical_memory_read(a->src, value, ch->data_type);
384
        else
385
            *(uint32_t *) value = ch->color;
386

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

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

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

  
402
            /* If the channel is async, update cpc */
403
            if (!ch->sync)
404
                ch->cpc = a->dest & 0xffff;
405
        }
406
    } while ((bytes -= ch->data_type));
407
#else
408
        /* If the channel is element synchronized, deactivate it */
409
        if (ch->sync && !ch->fs && !ch->bs)
364 410
            omap_dma_deactivate_channel(s, ch);
365
            continue;
366
#endif
367
            printf("%s: Bus time-out in DMA%i operation\n",
368
                            __FUNCTION__, s->chans - n);
411

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

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

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

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

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

  
371
        status = ch->status;
372
        while (status == ch->status && ch->active) {
373
            /* Transfer a single element */
374
            /* FIXME: check the endianness */
375
            if (!ch->constant_fill)
376
                cpu_physical_memory_read(a->src, value, ch->data_type);
377
            else
378
                *(uint32_t *) value = ch->color;
379

  
380
            if (!ch->transparent_copy ||
381
                    *(uint32_t *) value != ch->color)
382
                cpu_physical_memory_write(a->dest, value, ch->data_type);
383

  
384
            a->src += a->elem_delta[0];
385
            a->dest += a->elem_delta[1];
386
            a->element ++;
387

  
388
            /* If the channel is element synchronized, deactivate it */
389
            if (ch->sync && !ch->fs && !ch->bs)
439
        if (a->element == a->elements) {
440
            /* End of Frame */
441
            a->element = 0;
442
            a->src += a->frame_delta[0];
443
            a->dest += a->frame_delta[1];
444
            a->frame ++;
445

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

  
392
            /* If it is the last frame, set the LAST_FRAME interrupt */
393
            if (a->element == 1 && a->frame == a->frames - 1)
394
                if (ch->interrupts & LAST_FRAME_INTR)
395
                    ch->status |= LAST_FRAME_INTR;
396

  
397
            /* If the half of the frame was reached, set the HALF_FRAME
398
               interrupt */
399
            if (a->element == (a->elements >> 1))
400
                if (ch->interrupts & HALF_FRAME_INTR)
401
                    ch->status |= HALF_FRAME_INTR;
402

  
403
            if (ch->fs && ch->bs) {
404
                a->pck_element ++;
405
                /* Check if a full packet has beed transferred.  */
406
                if (a->pck_element == a->pck_elements) {
407
                    a->pck_element = 0;
408

  
409
                    /* Set the END_PKT interrupt */
410
                    if ((ch->interrupts & END_PKT_INTR) && !ch->src_sync)
411
                        ch->status |= END_PKT_INTR;
412

  
413
                    /* If the channel is packet-synchronized, deactivate it */
414
                    if (ch->sync)
450
            /* If the channel is async, update cpc */
451
            if (!ch->sync)
452
                ch->cpc = a->dest & 0xffff;
453

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

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

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

  
478
                if (ch->interrupts & END_BLOCK_INTR)
479
                    ch->status |= END_BLOCK_INTR;
417 480
            }
481
        }
482
    } while (status == ch->status && ch->active);
418 483

  
419
            if (a->element == a->elements) {
420
                /* End of Frame */
421
                a->element = 0;
422
                a->src += a->frame_delta[0];
423
                a->dest += a->frame_delta[1];
424
                a->frame ++;
484
    omap_dma_interrupts_update(s);
485
#endif
486
}
425 487

  
426
                /* If the channel is frame synchronized, deactivate it */
427
                if (ch->sync && ch->fs && !ch->bs)
428
                    omap_dma_deactivate_channel(s, ch);
488
enum {
489
    omap_dma_intr_element_sync,
490
    omap_dma_intr_last_frame,
491
    omap_dma_intr_half_frame,
492
    omap_dma_intr_frame,
493
    omap_dma_intr_frame_sync,
494
    omap_dma_intr_packet,
495
    omap_dma_intr_packet_sync,
496
    omap_dma_intr_block,
497
    __omap_dma_intr_last,
498
};
429 499

  
430
                /* If the channel is async, update cpc */
431
                if (!ch->sync)
432
                    ch->cpc = a->dest & 0xffff;
500
static void omap_dma_transfer_setup(struct soc_dma_ch_s *dma)
501
{
502
    struct omap_dma_port_if_s *src_p, *dest_p;
503
    struct omap_dma_reg_set_s *a;
504
    struct omap_dma_channel_s *ch = dma->opaque;
505
    struct omap_dma_s *s = dma->dma->opaque;
506
    int frames, min_elems, elements[__omap_dma_intr_last];
433 507

  
434
                /* Set the END_FRAME interrupt */
435
                if (ch->interrupts & END_FRAME_INTR)
436
                    ch->status |= END_FRAME_INTR;
508
    a = &ch->active_set;
437 509

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

  
442
                    if (ch->omap_3_1_compatible_disable) {
443
                        omap_dma_disable_channel(s, ch);
444
                        if (ch->link_enabled)
445
                            omap_dma_enable_channel(s,
446
                                            &s->ch[ch->link_next_ch]);
447
                    } else {
448
                        if (!ch->auto_init)
449
                            omap_dma_disable_channel(s, ch);
450
                        else if (ch->repeat || ch->end_prog)
451
                            omap_dma_channel_load(s, ch);
452
                        else {
453
                            ch->waiting_end_prog = 1;
454
                            omap_dma_deactivate_channel(s, ch);
455
                        }
456
                    }
525
    min_elems = INT_MAX;
526

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

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

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

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

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

  
587
    dma->bytes = min_elems * ch->data_type;
588

  
589
    /* Set appropriate interrupts and/or deactivate channels */
590

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

  
458
                    if (ch->interrupts & END_BLOCK_INTR)
459
                        ch->status |= END_BLOCK_INTR;
460
                }
597
    /* If the channel is element synchronized, deactivate it */
598
    if (min_elems == elements[omap_dma_intr_element_sync])
599
        omap_dma_deactivate_channel(s, ch);
600

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

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

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

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

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

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

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

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

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

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

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

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

  
668
        /* If the channel is async, update cpc */
669
        if (!ch->sync && frames)
670
            ch->cpc = a->dest & 0xffff;
463 671
    }
464 672

  
465 673
    omap_dma_interrupts_update(s);
466
    if (s->run_count && s->delay)
467
        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
468 674
}
469 675

  
470
void omap_dma_reset(struct omap_dma_s *s)
676
void omap_dma_reset(struct soc_dma_s *dma)
471 677
{
472 678
    int i;
679
    struct omap_dma_s *s = dma->opaque;
473 680

  
474
    qemu_del_timer(s->tm);
681
    soc_dma_reset(s->dma);
475 682
    if (s->model < omap_dma_4)
476 683
        s->gcr = 0x0004;
477 684
    else
......
479 686
    s->ocp = 0x00000000;
480 687
    memset(&s->irqstat, 0, sizeof(s->irqstat));
481 688
    memset(&s->irqen, 0, sizeof(s->irqen));
482
    s->drq = 0x00000000;
483
    s->run_count = 0;
484 689
    s->lcd_ch.src = emiff;
485 690
    s->lcd_ch.condition = 0;
486 691
    s->lcd_ch.interrupts = 0;
......
1161 1366

  
1162 1367
    case 0x408:	/* DMA_GRST */
1163 1368
        if (value & 0x1)
1164
            omap_dma_reset(s);
1369
            omap_dma_reset(s->dma);
1165 1370
        break;
1166 1371

  
1167 1372
    default:
......
1338 1543
    struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1339 1544
    /* The request pins are level triggered in QEMU.  */
1340 1545
    if (req) {
1341
        if (~s->drq & (1 << drq)) {
1342
            s->drq |= 1 << drq;
1546
        if (~s->dma->drqbmp & (1 << drq)) {
1547
            s->dma->drqbmp |= 1 << drq;
1343 1548
            omap_dma_process_request(s, drq);
1344 1549
        }
1345 1550
    } else
1346
        s->drq &= ~(1 << drq);
1551
        s->dma->drqbmp &= ~(1 << drq);
1347 1552
}
1348 1553

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

  
1353
    if (on) {
1354
        /* TODO: make a clever calculation */
1355
        s->delay = ticks_per_sec >> 8;
1356
        if (s->run_count)
1357
            qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
1358
    } else {
1359
        s->delay = 0;
1360
        qemu_del_timer(s->tm);
1361
    }
1560
    s->dma->freq = omap_clk_getrate(s->clk);
1561

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

  
1364 1567
static void omap_dma_setcaps(struct omap_dma_s *s)
......
1407 1610
    }
1408 1611
}
1409 1612

  
1410
struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
1613
struct soc_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
1411 1614
                qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
1412 1615
                enum omap_dma_model model)
1413 1616
{
......
1428 1631
    s->clk = clk;
1429 1632
    s->lcd_ch.irq = lcd_irq;
1430 1633
    s->lcd_ch.mpu = mpu;
1431
    omap_dma_setcaps(s);
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

  
1432 1642
    while (num_irqs --)
1433 1643
        s->ch[num_irqs].irq = irqs[num_irqs];
1434 1644
    for (i = 0; i < 3; i ++) {
1435 1645
        s->ch[i].sibling = &s->ch[i + 6];
1436 1646
        s->ch[i + 6].sibling = &s->ch[i];
1437 1647
    }
1438
    s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
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);
1439 1654
    omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1440
    mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1441
    omap_dma_reset(s);
1655
    omap_dma_reset(s->dma);
1442 1656
    omap_dma_clk_update(s, 0, 1);
1443 1657

  
1444 1658
    iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1445 1659
                    omap_dma_writefn, s);
1446 1660
    cpu_register_physical_memory(s->base, memsize, iomemtype);
1447 1661

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

  
1664
    return s->dma;
1449 1665
}
1450 1666

  
1451 1667
static void omap_dma_interrupts_4_update(struct omap_dma_s *s)
......
1646 1862

  
1647 1863
    case 0x2c:	/* DMA4_OCP_SYSCONFIG */
1648 1864
        if (value & 2)						/* SOFTRESET */
1649
            omap_dma_reset(s);
1865
            omap_dma_reset(s->dma);
1650 1866
        s->ocp = value & 0x3321;
1651 1867
        if (((s->ocp >> 12) & 3) == 3)				/* MIDLEMODE */
1652 1868
            fprintf(stderr, "%s: invalid DMA power mode\n", __FUNCTION__);
......
1728 1944
        ch->endian[1] =(value >> 19) & 1;
1729 1945
        ch->endian_lock[1] =(value >> 18) & 1;
1730 1946
        if (ch->endian[0] != ch->endian[1])
1731
            fprintf(stderr, "%s: DMA endianned conversion enable attempt\n",
1947
            fprintf(stderr, "%s: DMA endiannes conversion enable attempt\n",
1732 1948
                            __FUNCTION__);
1733 1949
        ch->write_mode = (value >> 16) & 3;
1734 1950
        ch->burst[1] = (value & 0xc000) >> 14;
......
1746 1962
        break;
1747 1963

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

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

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

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

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

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

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

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

  
1780 2004
    case 0x44:	/* DMA4_COLOR */
......
1806 2030
    omap_dma4_write,
1807 2031
};
1808 2032

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

  
......
1819 2043
    s->chans = chans;
1820 2044
    s->mpu = mpu;
1821 2045
    s->clk = fclk;
2046

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

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

  
1824 2061
    omap_dma_setcaps(s);
1825
    s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
1826 2062
    omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1827
    mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 64);
1828
    omap_dma_reset(s);
1829
    omap_dma_clk_update(s, 0, 1);
2063
    omap_dma_reset(s->dma);
2064
    omap_dma_clk_update(s, 0, !!s->dma->freq);
1830 2065

  
1831 2066
    iomemtype = cpu_register_io_memory(0, omap_dma4_readfn,
1832 2067
                    omap_dma4_writefn, s);
1833 2068
    cpu_register_physical_memory(s->base, 0x1000, iomemtype);
1834 2069

  
1835
    return s;
2070
    mpu->drq = s->dma->drq;
2071

  
2072
    return s->dma;
1836 2073
}
1837 2074

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

  
1840 2079
    return &s->lcd_ch;
1841 2080
}

Also available in: Unified diff