Commit 089b7c0a4c2a0b0953ed4323f893eb5af2ca4e2c

Authored by balrog
1 parent 7eb0c8e8

OMAP DMA 3.2 support by Lauro Ramos Venancio.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3786 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 949 additions and 248 deletions
hw/omap.c
@@ -402,38 +402,50 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, @@ -402,38 +402,50 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
402 } 402 }
403 403
404 /* OMAP1 DMA module */ 404 /* OMAP1 DMA module */
405 -typedef enum {  
406 - constant = 0,  
407 - post_incremented,  
408 - single_index,  
409 - double_index,  
410 -} omap_dma_addressing_t;  
411 -  
412 struct omap_dma_channel_s { 405 struct omap_dma_channel_s {
  406 + /* transfer data */
413 int burst[2]; 407 int burst[2];
414 int pack[2]; 408 int pack[2];
415 enum omap_dma_port port[2]; 409 enum omap_dma_port port[2];
416 target_phys_addr_t addr[2]; 410 target_phys_addr_t addr[2];
417 omap_dma_addressing_t mode[2]; 411 omap_dma_addressing_t mode[2];
  412 + uint16_t elements;
  413 + uint16_t frames;
  414 + int16_t frame_index[2];
  415 + int16_t element_index[2];
418 int data_type; 416 int data_type;
  417 +
  418 + /* transfer type */
  419 + int transparent_copy;
  420 + int constant_fill;
  421 + uint32_t color;
  422 +
  423 + /* auto init and linked channel data */
419 int end_prog; 424 int end_prog;
420 int repeat; 425 int repeat;
421 int auto_init; 426 int auto_init;
422 - int priority;  
423 - int fs;  
424 - int sync;  
425 - int running; 427 + int link_enabled;
  428 + int link_next_ch;
  429 +
  430 + /* interruption data */
426 int interrupts; 431 int interrupts;
427 int status; 432 int status;
428 - int signalled;  
429 - int post_sync;  
430 - int transfer;  
431 - uint16_t elements;  
432 - uint16_t frames;  
433 - uint16_t frame_index;  
434 - uint16_t element_index; 433 +
  434 + /* state data */
  435 + int active;
  436 + int enable;
  437 + int sync;
  438 + int pending_request;
  439 + int waiting_end_prog;
435 uint16_t cpc; 440 uint16_t cpc;
436 441
  442 + /* sync type */
  443 + int fs;
  444 + int bs;
  445 +
  446 + /* compatibility */
  447 + int omap_3_1_compatible_disable;
  448 +
437 struct omap_dma_reg_set_s { 449 struct omap_dma_reg_set_s {
438 target_phys_addr_t src, dest; 450 target_phys_addr_t src, dest;
439 int frame; 451 int frame;
@@ -443,16 +455,23 @@ struct omap_dma_channel_s { @@ -443,16 +455,23 @@ struct omap_dma_channel_s {
443 int frames; 455 int frames;
444 int elements; 456 int elements;
445 } active_set; 457 } active_set;
  458 +
  459 + /* unused parameters */
  460 + int priority;
  461 + int interleave_disabled;
  462 + int type;
446 }; 463 };
447 464
448 struct omap_dma_s { 465 struct omap_dma_s {
449 - qemu_irq *ih; 466 + qemu_irq irqs[16];
450 QEMUTimer *tm; 467 QEMUTimer *tm;
451 struct omap_mpu_state_s *mpu; 468 struct omap_mpu_state_s *mpu;
452 target_phys_addr_t base; 469 target_phys_addr_t base;
453 omap_clk clk; 470 omap_clk clk;
454 int64_t delay; 471 int64_t delay;
455 uint32_t drq; 472 uint32_t drq;
  473 + enum omap_dma_model model;
  474 + int omap_3_1_mapping_disabled;
456 475
457 uint16_t gcr; 476 uint16_t gcr;
458 int run_count; 477 int run_count;
@@ -462,27 +481,55 @@ struct omap_dma_s { @@ -462,27 +481,55 @@ struct omap_dma_s {
462 struct omap_dma_lcd_channel_s lcd_ch; 481 struct omap_dma_lcd_channel_s lcd_ch;
463 }; 482 };
464 483
  484 +/* Interrupts */
  485 +#define TIMEOUT_INTR (1 << 0)
  486 +#define EVENT_DROP_INTR (1 << 1)
  487 +#define HALF_FRAME_INTR (1 << 2)
  488 +#define END_FRAME_INTR (1 << 3)
  489 +#define LAST_FRAME_INTR (1 << 4)
  490 +#define END_BLOCK_INTR (1 << 5)
  491 +#define SYNC (1 << 6)
  492 +
  493 +static int omap_dma_get_sibling_channel(struct omap_dma_s *s, int channel)
  494 +{
  495 + if (s->omap_3_1_mapping_disabled)
  496 + return -1;
  497 + switch (channel) {
  498 + case 0 ... 2:
  499 + return channel + 6;
  500 + case 6 ... 8:
  501 + return channel % 6;
  502 + }
  503 + return -1;
  504 +}
  505 +
465 static void omap_dma_interrupts_update(struct omap_dma_s *s) 506 static void omap_dma_interrupts_update(struct omap_dma_s *s)
466 { 507 {
467 - /* First three interrupts are shared between two channels each. */  
468 - qemu_set_irq(s->ih[OMAP_INT_DMA_CH0_6],  
469 - (s->ch[0].status | s->ch[6].status) & 0x3f);  
470 - qemu_set_irq(s->ih[OMAP_INT_DMA_CH1_7],  
471 - (s->ch[1].status | s->ch[7].status) & 0x3f);  
472 - qemu_set_irq(s->ih[OMAP_INT_DMA_CH2_8],  
473 - (s->ch[2].status | s->ch[8].status) & 0x3f);  
474 - qemu_set_irq(s->ih[OMAP_INT_DMA_CH3],  
475 - (s->ch[3].status) & 0x3f);  
476 - qemu_set_irq(s->ih[OMAP_INT_DMA_CH4],  
477 - (s->ch[4].status) & 0x3f);  
478 - qemu_set_irq(s->ih[OMAP_INT_DMA_CH5],  
479 - (s->ch[5].status) & 0x3f); 508 + int i, sibiling, raise;
  509 +
  510 + if (s->omap_3_1_mapping_disabled) {
  511 + for (i = 0; i < s->chans; i ++) {
  512 + if (s->ch[i].status)
  513 + qemu_irq_raise(s->irqs[i]);
  514 + }
  515 + } else {
  516 + /* First three interrupts are shared between two channels each. */
  517 + for (i = 0; i < 6; i ++) {
  518 + raise = s->ch[i].status;
  519 + sibiling = omap_dma_get_sibling_channel(s, i);
  520 + if (sibiling != -1)
  521 + raise |= s->ch[sibiling].status;
  522 + if (raise)
  523 + qemu_irq_raise(s->irqs[i]);
  524 + }
  525 + }
480 } 526 }
481 527
482 static void omap_dma_channel_load(struct omap_dma_s *s, int ch) 528 static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
483 { 529 {
484 struct omap_dma_reg_set_s *a = &s->ch[ch].active_set; 530 struct omap_dma_reg_set_s *a = &s->ch[ch].active_set;
485 int i; 531 int i;
  532 + int omap_3_1 = !s->ch[ch].omap_3_1_compatible_disable;
486 533
487 /* 534 /*
488 * TODO: verify address ranges and alignment 535 * TODO: verify address ranges and alignment
@@ -513,71 +560,126 @@ static void omap_dma_channel_load(struct omap_dma_s *s, int ch) @@ -513,71 +560,126 @@ static void omap_dma_channel_load(struct omap_dma_s *s, int ch)
513 break; 560 break;
514 case single_index: 561 case single_index:
515 a->elem_delta[i] = s->ch[ch].data_type + 562 a->elem_delta[i] = s->ch[ch].data_type +
516 - s->ch[ch].element_index - 1;  
517 - if (s->ch[ch].element_index > 0x7fff)  
518 - a->elem_delta[i] -= 0x10000; 563 + s->ch[ch].element_index[omap_3_1 ? 0 : i] - 1;
519 a->frame_delta[i] = 0; 564 a->frame_delta[i] = 0;
520 break; 565 break;
521 case double_index: 566 case double_index:
522 a->elem_delta[i] = s->ch[ch].data_type + 567 a->elem_delta[i] = s->ch[ch].data_type +
523 - s->ch[ch].element_index - 1;  
524 - if (s->ch[ch].element_index > 0x7fff)  
525 - a->elem_delta[i] -= 0x10000;  
526 - a->frame_delta[i] = s->ch[ch].frame_index -  
527 - s->ch[ch].element_index;  
528 - if (s->ch[ch].frame_index > 0x7fff)  
529 - a->frame_delta[i] -= 0x10000; 568 + s->ch[ch].element_index[omap_3_1 ? 0 : i] - 1;
  569 + a->frame_delta[i] = s->ch[ch].frame_index[omap_3_1 ? 0 : i] -
  570 + s->ch[ch].element_index[omap_3_1 ? 0 : i];
530 break; 571 break;
531 default: 572 default:
532 break; 573 break;
533 } 574 }
534 } 575 }
535 576
536 -static inline void omap_dma_request_run(struct omap_dma_s *s,  
537 - int channel, int request) 577 +static void omap_dma_activate_channel(struct omap_dma_s *s, int channel)
538 { 578 {
539 -next_channel:  
540 - if (request > 0)  
541 - for (; channel < 9; channel ++)  
542 - if (s->ch[channel].sync == request && s->ch[channel].running)  
543 - break;  
544 - if (channel >= 9) 579 + if (!s->ch[channel].active) {
  580 + s->ch[channel].active = 1;
  581 + if (s->ch[channel].sync)
  582 + s->ch[channel].status |= SYNC;
  583 + s->run_count ++;
  584 + }
  585 +
  586 + if (s->delay && !qemu_timer_pending(s->tm))
  587 + qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
  588 +}
  589 +
  590 +static void omap_dma_deactivate_channel(struct omap_dma_s *s, int channel)
  591 +{
  592 + /* Update cpc */
  593 + s->ch[channel].cpc = s->ch[channel].active_set.dest & 0xffff;
  594 +
  595 + if (s->ch[channel].pending_request &&
  596 + !s->ch[channel].waiting_end_prog) {
  597 + /* Don't deactivate the channel */
  598 + s->ch[channel].pending_request = 0;
545 return; 599 return;
  600 + }
546 601
547 - if (s->ch[channel].transfer) {  
548 - if (request > 0) {  
549 - s->ch[channel ++].post_sync = request;  
550 - goto next_channel;  
551 - }  
552 - s->ch[channel].status |= 0x02; /* Synchronisation drop */  
553 - omap_dma_interrupts_update(s); 602 + /* Don't deactive the channel if it is synchronized and the DMA request is
  603 + active */
  604 + if (s->ch[channel].sync && (s->drq & (1 << s->ch[channel].sync)))
554 return; 605 return;
  606 +
  607 + if (s->ch[channel].active) {
  608 + s->ch[channel].active = 0;
  609 + s->ch[channel].status &= ~SYNC;
  610 + s->run_count --;
555 } 611 }
556 612
557 - if (!s->ch[channel].signalled)  
558 - s->run_count ++;  
559 - s->ch[channel].signalled = 1; 613 + if (!s->run_count)
  614 + qemu_del_timer(s->tm);
  615 +}
560 616
561 - if (request > 0)  
562 - s->ch[channel].status |= 0x40; /* External request */ 617 +static void omap_dma_enable_channel(struct omap_dma_s *s, int channel)
  618 +{
  619 + if (!s->ch[channel].enable) {
  620 + s->ch[channel].enable = 1;
  621 + s->ch[channel].waiting_end_prog = 0;
  622 + omap_dma_channel_load(s, channel);
  623 + if ((!s->ch[channel].sync) || (s->drq & (1 << s->ch[channel].sync)))
  624 + omap_dma_activate_channel(s, channel);
  625 + }
  626 +}
563 627
564 - if (s->delay && !qemu_timer_pending(s->tm))  
565 - qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay); 628 +static void omap_dma_disable_channel(struct omap_dma_s *s, int channel)
  629 +{
  630 + if (s->ch[channel].enable) {
  631 + s->ch[channel].enable = 0;
  632 + /* Discard any pending request */
  633 + s->ch[channel].pending_request = 0;
  634 + omap_dma_deactivate_channel(s, channel);
  635 + }
  636 +}
566 637
567 - if (request > 0) {  
568 - channel ++;  
569 - goto next_channel; 638 +static void omap_dma_channel_end_prog(struct omap_dma_s *s, int channel)
  639 +{
  640 + if (s->ch[channel].waiting_end_prog) {
  641 + s->ch[channel].waiting_end_prog = 0;
  642 + if (!s->ch[channel].sync || s->ch[channel].pending_request) {
  643 + s->ch[channel].pending_request = 0;
  644 + omap_dma_activate_channel(s, channel);
  645 + }
570 } 646 }
571 } 647 }
572 648
573 -static inline void omap_dma_request_stop(struct omap_dma_s *s, int channel) 649 +static void omap_dma_enable_3_1_mapping(struct omap_dma_s *s)
574 { 650 {
575 - if (s->ch[channel].signalled)  
576 - s->run_count --;  
577 - s->ch[channel].signalled = 0; 651 + s->omap_3_1_mapping_disabled = 0;
  652 + s->chans = 9;
  653 +}
578 654
579 - if (!s->run_count)  
580 - qemu_del_timer(s->tm); 655 +static void omap_dma_disable_3_1_mapping(struct omap_dma_s *s)
  656 +{
  657 + s->omap_3_1_mapping_disabled = 1;
  658 + s->chans = 16;
  659 +}
  660 +
  661 +static void omap_dma_process_request(struct omap_dma_s *s, int request)
  662 +{
  663 + int channel;
  664 + int drop_event = 0;
  665 +
  666 + for (channel = 0; channel < s->chans; channel ++) {
  667 + if (s->ch[channel].enable && s->ch[channel].sync == request) {
  668 + if (!s->ch[channel].active)
  669 + omap_dma_activate_channel(s, channel);
  670 + else if (!s->ch[channel].pending_request)
  671 + s->ch[channel].pending_request = 1;
  672 + else {
  673 + /* Request collision */
  674 + /* Second request received while processing other request */
  675 + s->ch[channel].status |= EVENT_DROP_INTR;
  676 + drop_event = 1;
  677 + }
  678 + }
  679 + }
  680 +
  681 + if (drop_event)
  682 + omap_dma_interrupts_update(s);
581 } 683 }
582 684
583 static void omap_dma_channel_run(struct omap_dma_s *s) 685 static void omap_dma_channel_run(struct omap_dma_s *s)
@@ -588,97 +690,101 @@ static void omap_dma_channel_run(struct omap_dma_s *s) @@ -588,97 +690,101 @@ static void omap_dma_channel_run(struct omap_dma_s *s)
588 struct omap_dma_port_if_s *src_p, *dest_p; 690 struct omap_dma_port_if_s *src_p, *dest_p;
589 struct omap_dma_reg_set_s *a; 691 struct omap_dma_reg_set_s *a;
590 692
591 - for (ch = 0; ch < 9; ch ++) { 693 + for (ch = 0; ch < s->chans; ch ++) {
  694 + if (!s->ch[ch].active)
  695 + continue;
  696 +
592 a = &s->ch[ch].active_set; 697 a = &s->ch[ch].active_set;
593 698
594 src_p = &s->mpu->port[s->ch[ch].port[0]]; 699 src_p = &s->mpu->port[s->ch[ch].port[0]];
595 dest_p = &s->mpu->port[s->ch[ch].port[1]]; 700 dest_p = &s->mpu->port[s->ch[ch].port[1]];
596 - if (s->ch[ch].signalled && (!src_p->addr_valid(s->mpu, a->src) ||  
597 - !dest_p->addr_valid(s->mpu, a->dest))) { 701 + if ((!s->ch[ch].constant_fill && !src_p->addr_valid(s->mpu, a->src)) ||
  702 + (!dest_p->addr_valid(s->mpu, a->dest))) {
598 #if 0 703 #if 0
599 /* Bus time-out */ 704 /* Bus time-out */
600 - if (s->ch[ch].interrupts & 0x01)  
601 - s->ch[ch].status |= 0x01;  
602 - omap_dma_request_stop(s, ch); 705 + if (s->ch[ch].interrupts & TIMEOUT_INTR)
  706 + s->ch[ch].status |= TIMEOUT_INTR;
  707 + omap_dma_deactivate_channel(s, ch);
603 continue; 708 continue;
604 #endif 709 #endif
605 printf("%s: Bus time-out in DMA%i operation\n", __FUNCTION__, ch); 710 printf("%s: Bus time-out in DMA%i operation\n", __FUNCTION__, ch);
606 } 711 }
607 712
608 status = s->ch[ch].status; 713 status = s->ch[ch].status;
609 - while (status == s->ch[ch].status && s->ch[ch].signalled) { 714 + while (status == s->ch[ch].status && s->ch[ch].active) {
610 /* Transfer a single element */ 715 /* Transfer a single element */
611 - s->ch[ch].transfer = 1;  
612 - cpu_physical_memory_read(a->src, value, s->ch[ch].data_type);  
613 - cpu_physical_memory_write(a->dest, value, s->ch[ch].data_type);  
614 - s->ch[ch].transfer = 0; 716 + /* FIXME: check the endianness */
  717 + if (!s->ch[ch].constant_fill)
  718 + cpu_physical_memory_read(a->src, value, s->ch[ch].data_type);
  719 + else
  720 + *(uint32_t *) value = s->ch[ch].color;
  721 +
  722 + if (!s->ch[ch].transparent_copy ||
  723 + *(uint32_t *) value != s->ch[ch].color)
  724 + cpu_physical_memory_write(a->dest, value, s->ch[ch].data_type);
615 725
616 a->src += a->elem_delta[0]; 726 a->src += a->elem_delta[0];
617 a->dest += a->elem_delta[1]; 727 a->dest += a->elem_delta[1];
618 a->element ++; 728 a->element ++;
619 729
620 - /* Check interrupt conditions */ 730 + /* If the channel is element synchronized, deactivate it */
  731 + if (s->ch[ch].sync && !s->ch[ch].fs && !s->ch[ch].bs)
  732 + omap_dma_deactivate_channel(s, ch);
  733 +
  734 + /* If it is the last frame, set the LAST_FRAME interrupt */
  735 + if (a->element == 1 && a->frame == a->frames - 1)
  736 + if (s->ch[ch].interrupts & LAST_FRAME_INTR)
  737 + s->ch[ch].status |= LAST_FRAME_INTR;
  738 +
  739 + /* If the half of the frame was reached, set the HALF_FRAME
  740 + interrupt */
  741 + if (a->element == (a->elements >> 1))
  742 + if (s->ch[ch].interrupts & HALF_FRAME_INTR)
  743 + s->ch[ch].status |= HALF_FRAME_INTR;
  744 +
621 if (a->element == a->elements) { 745 if (a->element == a->elements) {
  746 + /* End of Frame */
622 a->element = 0; 747 a->element = 0;
623 a->src += a->frame_delta[0]; 748 a->src += a->frame_delta[0];
624 a->dest += a->frame_delta[1]; 749 a->dest += a->frame_delta[1];
625 a->frame ++; 750 a->frame ++;
626 751
627 - if (a->frame == a->frames) {  
628 - if (!s->ch[ch].repeat || !s->ch[ch].auto_init)  
629 - s->ch[ch].running = 0; 752 + /* If the channel is frame synchronized, deactivate it */
  753 + if (s->ch[ch].sync && s->ch[ch].fs)
  754 + omap_dma_deactivate_channel(s, ch);
630 755
631 - if (s->ch[ch].auto_init &&  
632 - (s->ch[ch].repeat ||  
633 - s->ch[ch].end_prog))  
634 - omap_dma_channel_load(s, ch); 756 + /* If the channel is async, update cpc */
  757 + if (!s->ch[ch].sync)
  758 + s->ch[ch].cpc = a->dest & 0xffff;
635 759
636 - if (s->ch[ch].interrupts & 0x20)  
637 - s->ch[ch].status |= 0x20; 760 + /* Set the END_FRAME interrupt */
  761 + if (s->ch[ch].interrupts & END_FRAME_INTR)
  762 + s->ch[ch].status |= END_FRAME_INTR;
638 763
639 - if (!s->ch[ch].sync)  
640 - omap_dma_request_stop(s, ch);  
641 - }  
642 -  
643 - if (s->ch[ch].interrupts & 0x08)  
644 - s->ch[ch].status |= 0x08;  
645 -  
646 - if (s->ch[ch].sync && s->ch[ch].fs &&  
647 - !(s->drq & (1 << s->ch[ch].sync))) {  
648 - s->ch[ch].status &= ~0x40;  
649 - omap_dma_request_stop(s, ch); 764 + if (a->frame == a->frames) {
  765 + /* End of Block */
  766 + /* Disable the channel */
  767 +
  768 + if (s->ch[ch].omap_3_1_compatible_disable) {
  769 + omap_dma_disable_channel(s, ch);
  770 + if (s->ch[ch].link_enabled)
  771 + omap_dma_enable_channel(s, s->ch[ch].link_next_ch);
  772 + } else {
  773 + if (!s->ch[ch].auto_init)
  774 + omap_dma_disable_channel(s, ch);
  775 + else if (s->ch[ch].repeat || s->ch[ch].end_prog)
  776 + omap_dma_channel_load(s, ch);
  777 + else {
  778 + s->ch[ch].waiting_end_prog = 1;
  779 + omap_dma_deactivate_channel(s, ch);
  780 + }
  781 + }
  782 +
  783 + if (s->ch[ch].interrupts & END_BLOCK_INTR)
  784 + s->ch[ch].status |= END_BLOCK_INTR;
650 } 785 }
651 } 786 }
652 -  
653 - if (a->element == 1 && a->frame == a->frames - 1)  
654 - if (s->ch[ch].interrupts & 0x10)  
655 - s->ch[ch].status |= 0x10;  
656 -  
657 - if (a->element == (a->elements >> 1))  
658 - if (s->ch[ch].interrupts & 0x04)  
659 - s->ch[ch].status |= 0x04;  
660 -  
661 - if (s->ch[ch].sync && !s->ch[ch].fs &&  
662 - !(s->drq & (1 << s->ch[ch].sync))) {  
663 - s->ch[ch].status &= ~0x40;  
664 - omap_dma_request_stop(s, ch);  
665 - }  
666 -  
667 - /*  
668 - * Process requests made while the element was  
669 - * being transferred.  
670 - */  
671 - if (s->ch[ch].post_sync) {  
672 - omap_dma_request_run(s, 0, s->ch[ch].post_sync);  
673 - s->ch[ch].post_sync = 0;  
674 - }  
675 -  
676 -#if 0  
677 - break;  
678 -#endif  
679 } 787 }
680 -  
681 - s->ch[ch].cpc = a->dest & 0x0000ffff;  
682 } 788 }
683 789
684 omap_dma_interrupts_update(s); 790 omap_dma_interrupts_update(s);
@@ -686,8 +792,29 @@ static void omap_dma_channel_run(struct omap_dma_s *s) @@ -686,8 +792,29 @@ static void omap_dma_channel_run(struct omap_dma_s *s)
686 qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay); 792 qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
687 } 793 }
688 794
689 -static int omap_dma_ch_reg_read(struct omap_dma_s *s,  
690 - int ch, int reg, uint16_t *value) { 795 +static void omap_dma_reset(struct omap_dma_s *s)
  796 +{
  797 + int i;
  798 +
  799 + qemu_del_timer(s->tm);
  800 + s->gcr = 0x0004;
  801 + s->drq = 0x00000000;
  802 + s->run_count = 0;
  803 + s->lcd_ch.src = emiff;
  804 + s->lcd_ch.condition = 0;
  805 + s->lcd_ch.interrupts = 0;
  806 + s->lcd_ch.dual = 0;
  807 + omap_dma_enable_3_1_mapping(s);
  808 + memset(s->ch, 0, sizeof(s->ch));
  809 + for (i = 0; i < s->chans; i ++)
  810 + s->ch[i].interrupts = 0x0003;
  811 +}
  812 +
  813 +static int omap_dma_ch_reg_read(struct omap_dma_s *s, int ch, int reg,
  814 + uint16_t *value)
  815 +{
  816 + int sibling;
  817 +
691 switch (reg) { 818 switch (reg) {
692 case 0x00: /* SYS_DMA_CSDP_CH0 */ 819 case 0x00: /* SYS_DMA_CSDP_CH0 */
693 *value = (s->ch[ch].burst[1] << 14) | 820 *value = (s->ch[ch].burst[1] << 14) |
@@ -700,12 +827,16 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s, @@ -700,12 +827,16 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s,
700 break; 827 break;
701 828
702 case 0x02: /* SYS_DMA_CCR_CH0 */ 829 case 0x02: /* SYS_DMA_CCR_CH0 */
703 - *value = (s->ch[ch].mode[1] << 14) | 830 + if (s->model == omap_dma_3_1)
  831 + *value = 0 << 10; /* FIFO_FLUSH bit */
  832 + else
  833 + *value = s->ch[ch].omap_3_1_compatible_disable << 10;
  834 + *value |= (s->ch[ch].mode[1] << 14) |
704 (s->ch[ch].mode[0] << 12) | 835 (s->ch[ch].mode[0] << 12) |
705 (s->ch[ch].end_prog << 11) | 836 (s->ch[ch].end_prog << 11) |
706 (s->ch[ch].repeat << 9) | 837 (s->ch[ch].repeat << 9) |
707 (s->ch[ch].auto_init << 8) | 838 (s->ch[ch].auto_init << 8) |
708 - (s->ch[ch].running << 7) | 839 + (s->ch[ch].enable << 7) |
709 (s->ch[ch].priority << 6) | 840 (s->ch[ch].priority << 6) |
710 (s->ch[ch].fs << 5) | s->ch[ch].sync; 841 (s->ch[ch].fs << 5) | s->ch[ch].sync;
711 break; 842 break;
@@ -715,10 +846,18 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s, @@ -715,10 +846,18 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s,
715 break; 846 break;
716 847
717 case 0x06: /* SYS_DMA_CSR_CH0 */ 848 case 0x06: /* SYS_DMA_CSR_CH0 */
718 - /* FIXME: shared CSR for channels sharing the interrupts */ 849 + sibling = omap_dma_get_sibling_channel(s, ch);
719 *value = s->ch[ch].status; 850 *value = s->ch[ch].status;
720 - s->ch[ch].status &= 0x40;  
721 - omap_dma_interrupts_update(s); 851 + s->ch[ch].status &= SYNC;
  852 + if (sibling != -1) {
  853 + *value |= (s->ch[sibling].status & 0x3f) << 6;
  854 + s->ch[sibling].status &= SYNC;
  855 + if (sibling < ch) {
  856 + qemu_irq_lower(s->irqs[sibling]);
  857 + break;
  858 + }
  859 + }
  860 + qemu_irq_lower(s->irqs[ch]);
722 break; 861 break;
723 862
724 case 0x08: /* SYS_DMA_CSSA_L_CH0 */ 863 case 0x08: /* SYS_DMA_CSSA_L_CH0 */
@@ -746,15 +885,54 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s, @@ -746,15 +885,54 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s,
746 break; 885 break;
747 886
748 case 0x14: /* SYS_DMA_CFI_CH0 */ 887 case 0x14: /* SYS_DMA_CFI_CH0 */
749 - *value = s->ch[ch].frame_index; 888 + *value = s->ch[ch].frame_index[0];
750 break; 889 break;
751 890
752 case 0x16: /* SYS_DMA_CEI_CH0 */ 891 case 0x16: /* SYS_DMA_CEI_CH0 */
753 - *value = s->ch[ch].element_index; 892 + *value = s->ch[ch].element_index[0];
  893 + break;
  894 +
  895 + case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */
  896 + if (s->ch[ch].omap_3_1_compatible_disable)
  897 + *value = s->ch[ch].active_set.src & 0xffff; /* CSAC */
  898 + else
  899 + *value = s->ch[ch].cpc;
  900 + break;
  901 +
  902 + case 0x1a: /* DMA_CDAC */
  903 + *value = s->ch[ch].active_set.dest & 0xffff; /* CDAC */
  904 + break;
  905 +
  906 + case 0x1c: /* DMA_CDEI */
  907 + *value = s->ch[ch].element_index[1];
  908 + break;
  909 +
  910 + case 0x1e: /* DMA_CDFI */
  911 + *value = s->ch[ch].frame_index[1];
  912 + break;
  913 +
  914 + case 0x20: /* DMA_COLOR_L */
  915 + *value = s->ch[ch].color & 0xffff;
  916 + break;
  917 +
  918 + case 0x22: /* DMA_COLOR_U */
  919 + *value = s->ch[ch].color >> 16;
754 break; 920 break;
755 921
756 - case 0x18: /* SYS_DMA_CPC_CH0 */  
757 - *value = s->ch[ch].cpc; 922 + case 0x24: /* DMA_CCR2 */
  923 + *value = (s->ch[ch].bs << 2) |
  924 + (s->ch[ch].transparent_copy << 1) |
  925 + s->ch[ch].constant_fill;
  926 + break;
  927 +
  928 + case 0x28: /* DMA_CLNK_CTRL */
  929 + *value = (s->ch[ch].link_enabled << 15) |
  930 + (s->ch[ch].link_next_ch & 0xf);
  931 + break;
  932 +
  933 + case 0x2a: /* DMA_LCH_CTRL */
  934 + *value = (s->ch[ch].interleave_disabled << 15) |
  935 + s->ch[ch].type;
758 break; 936 break;
759 937
760 default: 938 default:
@@ -764,7 +942,8 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s, @@ -764,7 +942,8 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s,
764 } 942 }
765 943
766 static int omap_dma_ch_reg_write(struct omap_dma_s *s, 944 static int omap_dma_ch_reg_write(struct omap_dma_s *s,
767 - int ch, int reg, uint16_t value) { 945 + int ch, int reg, uint16_t value)
  946 +{
768 switch (reg) { 947 switch (reg) {
769 case 0x00: /* SYS_DMA_CSDP_CH0 */ 948 case 0x00: /* SYS_DMA_CSDP_CH0 */
770 s->ch[ch].burst[1] = (value & 0xc000) >> 14; 949 s->ch[ch].burst[1] = (value & 0xc000) >> 14;
@@ -788,30 +967,26 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, @@ -788,30 +967,26 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
788 s->ch[ch].mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14); 967 s->ch[ch].mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
789 s->ch[ch].mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12); 968 s->ch[ch].mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
790 s->ch[ch].end_prog = (value & 0x0800) >> 11; 969 s->ch[ch].end_prog = (value & 0x0800) >> 11;
  970 + if (s->model > omap_dma_3_1)
  971 + s->ch[ch].omap_3_1_compatible_disable = (value >> 10) & 0x1;
791 s->ch[ch].repeat = (value & 0x0200) >> 9; 972 s->ch[ch].repeat = (value & 0x0200) >> 9;
792 s->ch[ch].auto_init = (value & 0x0100) >> 8; 973 s->ch[ch].auto_init = (value & 0x0100) >> 8;
793 s->ch[ch].priority = (value & 0x0040) >> 6; 974 s->ch[ch].priority = (value & 0x0040) >> 6;
794 s->ch[ch].fs = (value & 0x0020) >> 5; 975 s->ch[ch].fs = (value & 0x0020) >> 5;
795 s->ch[ch].sync = value & 0x001f; 976 s->ch[ch].sync = value & 0x001f;
796 - if (value & 0x0080) {  
797 - if (s->ch[ch].running) {  
798 - if (!s->ch[ch].signalled &&  
799 - s->ch[ch].auto_init && s->ch[ch].end_prog)  
800 - omap_dma_channel_load(s, ch);  
801 - } else {  
802 - s->ch[ch].running = 1;  
803 - omap_dma_channel_load(s, ch);  
804 - }  
805 - if (!s->ch[ch].sync || (s->drq & (1 << s->ch[ch].sync)))  
806 - omap_dma_request_run(s, ch, 0);  
807 - } else {  
808 - s->ch[ch].running = 0;  
809 - omap_dma_request_stop(s, ch);  
810 - } 977 +
  978 + if (value & 0x0080)
  979 + omap_dma_enable_channel(s, ch);
  980 + else
  981 + omap_dma_disable_channel(s, ch);
  982 +
  983 + if (s->ch[ch].end_prog)
  984 + omap_dma_channel_end_prog(s, ch);
  985 +
811 break; 986 break;
812 987
813 case 0x04: /* SYS_DMA_CICR_CH0 */ 988 case 0x04: /* SYS_DMA_CICR_CH0 */
814 - s->ch[ch].interrupts = value & 0x003f; 989 + s->ch[ch].interrupts = value;
815 break; 990 break;
816 991
817 case 0x06: /* SYS_DMA_CSR_CH0 */ 992 case 0x06: /* SYS_DMA_CSR_CH0 */
@@ -838,97 +1013,317 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, @@ -838,97 +1013,317 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
838 break; 1013 break;
839 1014
840 case 0x10: /* SYS_DMA_CEN_CH0 */ 1015 case 0x10: /* SYS_DMA_CEN_CH0 */
841 - s->ch[ch].elements = value & 0xffff; 1016 + s->ch[ch].elements = value;
842 break; 1017 break;
843 1018
844 case 0x12: /* SYS_DMA_CFN_CH0 */ 1019 case 0x12: /* SYS_DMA_CFN_CH0 */
845 - s->ch[ch].frames = value & 0xffff; 1020 + s->ch[ch].frames = value;
846 break; 1021 break;
847 1022
848 case 0x14: /* SYS_DMA_CFI_CH0 */ 1023 case 0x14: /* SYS_DMA_CFI_CH0 */
849 - s->ch[ch].frame_index = value & 0xffff; 1024 + s->ch[ch].frame_index[0] = (int16_t) value;
850 break; 1025 break;
851 1026
852 case 0x16: /* SYS_DMA_CEI_CH0 */ 1027 case 0x16: /* SYS_DMA_CEI_CH0 */
853 - s->ch[ch].element_index = value & 0xffff; 1028 + s->ch[ch].element_index[0] = (int16_t) value;
854 break; 1029 break;
855 1030
856 - case 0x18: /* SYS_DMA_CPC_CH0 */  
857 - return 1; 1031 + case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */
  1032 + OMAP_RO_REG((target_phys_addr_t) reg);
  1033 + break;
  1034 +
  1035 + case 0x1c: /* DMA_CDEI */
  1036 + s->ch[ch].element_index[1] = (int16_t) value;
  1037 + break;
  1038 +
  1039 + case 0x1e: /* DMA_CDFI */
  1040 + s->ch[ch].frame_index[1] = (int16_t) value;
  1041 + break;
  1042 +
  1043 + case 0x20: /* DMA_COLOR_L */
  1044 + s->ch[ch].color &= 0xffff0000;
  1045 + s->ch[ch].color |= value;
  1046 + break;
  1047 +
  1048 + case 0x22: /* DMA_COLOR_U */
  1049 + s->ch[ch].color &= 0xffff;
  1050 + s->ch[ch].color |= value << 16;
  1051 + break;
  1052 +
  1053 + case 0x24: /* DMA_CCR2 */
  1054 + s->ch[ch].bs = (value >> 2) & 0x1;
  1055 + s->ch[ch].transparent_copy = (value >> 1) & 0x1;
  1056 + s->ch[ch].constant_fill = value & 0x1;
  1057 + break;
  1058 +
  1059 + case 0x28: /* DMA_CLNK_CTRL */
  1060 + s->ch[ch].link_enabled = (value >> 15) & 0x1;
  1061 + if (value & (1 << 14)) { /* Stop_Lnk */
  1062 + s->ch[ch].link_enabled = 0;
  1063 + omap_dma_disable_channel(s, ch);
  1064 + }
  1065 + s->ch[ch].link_next_ch = value & 0x1f;
  1066 + break;
  1067 +
  1068 + case 0x2a: /* DMA_LCH_CTRL */
  1069 + s->ch[ch].interleave_disabled = (value >> 15) & 0x1;
  1070 + s->ch[ch].type = value & 0xf;
  1071 + break;
858 1072
859 default: 1073 default:
860 - OMAP_BAD_REG((target_phys_addr_t) reg); 1074 + return 1;
861 } 1075 }
862 return 0; 1076 return 0;
863 } 1077 }
864 1078
865 -static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr) 1079 +static int omap_dma_3_2_lcd_write(struct omap_dma_s *s, int offset,
  1080 + uint16_t value)
866 { 1081 {
867 - struct omap_dma_s *s = (struct omap_dma_s *) opaque;  
868 - int i, reg, ch, offset = addr - s->base;  
869 - uint16_t ret;  
870 -  
871 switch (offset) { 1082 switch (offset) {
872 - case 0x000 ... 0x2fe:  
873 - reg = offset & 0x3f;  
874 - ch = (offset >> 6) & 0x0f;  
875 - if (omap_dma_ch_reg_read(s, ch, reg, &ret))  
876 - break;  
877 - return ret; 1083 + case 0xbc0: /* DMA_LCD_CSDP */
  1084 + s->lcd_ch.brust_f2 = (value >> 14) & 0x3;
  1085 + s->lcd_ch.pack_f2 = (value >> 13) & 0x1;
  1086 + s->lcd_ch.data_type_f2 = (1 << ((value >> 11) & 0x3));
  1087 + s->lcd_ch.brust_f1 = (value >> 7) & 0x3;
  1088 + s->lcd_ch.pack_f1 = (value >> 6) & 0x1;
  1089 + s->lcd_ch.data_type_f1 = (1 << ((value >> 0) & 0x3));
  1090 + break;
878 1091
879 - case 0x300: /* SYS_DMA_LCD_CTRL */  
880 - i = s->lcd_ch.condition; 1092 + case 0xbc2: /* DMA_LCD_CCR */
  1093 + s->lcd_ch.mode_f2 = (value >> 14) & 0x3;
  1094 + s->lcd_ch.mode_f1 = (value >> 12) & 0x3;
  1095 + s->lcd_ch.end_prog = (value >> 11) & 0x1;
  1096 + s->lcd_ch.omap_3_1_compatible_disable = (value >> 10) & 0x1;
  1097 + s->lcd_ch.repeat = (value >> 9) & 0x1;
  1098 + s->lcd_ch.auto_init = (value >> 8) & 0x1;
  1099 + s->lcd_ch.running = (value >> 7) & 0x1;
  1100 + s->lcd_ch.priority = (value >> 6) & 0x1;
  1101 + s->lcd_ch.bs = (value >> 4) & 0x1;
  1102 + break;
  1103 +
  1104 + case 0xbc4: /* DMA_LCD_CTRL */
  1105 + s->lcd_ch.dst = (value >> 8) & 0x1;
  1106 + s->lcd_ch.src = ((value >> 6) & 0x3) << 1;
881 s->lcd_ch.condition = 0; 1107 s->lcd_ch.condition = 0;
882 - qemu_irq_lower(s->lcd_ch.irq);  
883 - return ((s->lcd_ch.src == imif) << 6) | (i << 3) |  
884 - (s->lcd_ch.interrupts << 1) | s->lcd_ch.dual; 1108 + /* Assume no bus errors and thus no BUS_ERROR irq bits. */
  1109 + s->lcd_ch.interrupts = (value >> 1) & 1;
  1110 + s->lcd_ch.dual = value & 1;
  1111 + break;
885 1112
886 - case 0x302: /* SYS_DMA_LCD_TOP_F1_L */  
887 - return s->lcd_ch.src_f1_top & 0xffff; 1113 + case 0xbc8: /* TOP_B1_L */
  1114 + s->lcd_ch.src_f1_top &= 0xffff0000;
  1115 + s->lcd_ch.src_f1_top |= 0x0000ffff & value;
  1116 + break;
888 1117
889 - case 0x304: /* SYS_DMA_LCD_TOP_F1_U */  
890 - return s->lcd_ch.src_f1_top >> 16; 1118 + case 0xbca: /* TOP_B1_U */
  1119 + s->lcd_ch.src_f1_top &= 0x0000ffff;
  1120 + s->lcd_ch.src_f1_top |= value << 16;
  1121 + break;
891 1122
892 - case 0x306: /* SYS_DMA_LCD_BOT_F1_L */  
893 - return s->lcd_ch.src_f1_bottom & 0xffff; 1123 + case 0xbcc: /* BOT_B1_L */
  1124 + s->lcd_ch.src_f1_bottom &= 0xffff0000;
  1125 + s->lcd_ch.src_f1_bottom |= 0x0000ffff & value;
  1126 + break;
894 1127
895 - case 0x308: /* SYS_DMA_LCD_BOT_F1_U */  
896 - return s->lcd_ch.src_f1_bottom >> 16; 1128 + case 0xbce: /* BOT_B1_U */
  1129 + s->lcd_ch.src_f1_bottom &= 0x0000ffff;
  1130 + s->lcd_ch.src_f1_bottom |= (uint32_t) value << 16;
  1131 + break;
897 1132
898 - case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */  
899 - return s->lcd_ch.src_f2_top & 0xffff; 1133 + case 0xbd0: /* TOP_B2_L */
  1134 + s->lcd_ch.src_f2_top &= 0xffff0000;
  1135 + s->lcd_ch.src_f2_top |= 0x0000ffff & value;
  1136 + break;
900 1137
901 - case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */  
902 - return s->lcd_ch.src_f2_top >> 16; 1138 + case 0xbd2: /* TOP_B2_U */
  1139 + s->lcd_ch.src_f2_top &= 0x0000ffff;
  1140 + s->lcd_ch.src_f2_top |= (uint32_t) value << 16;
  1141 + break;
903 1142
904 - case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */  
905 - return s->lcd_ch.src_f2_bottom & 0xffff; 1143 + case 0xbd4: /* BOT_B2_L */
  1144 + s->lcd_ch.src_f2_bottom &= 0xffff0000;
  1145 + s->lcd_ch.src_f2_bottom |= 0x0000ffff & value;
  1146 + break;
906 1147
907 - case 0x310: /* SYS_DMA_LCD_BOT_F2_U */  
908 - return s->lcd_ch.src_f2_bottom >> 16; 1148 + case 0xbd6: /* BOT_B2_U */
  1149 + s->lcd_ch.src_f2_bottom &= 0x0000ffff;
  1150 + s->lcd_ch.src_f2_bottom |= (uint32_t) value << 16;
  1151 + break;
909 1152
910 - case 0x400: /* SYS_DMA_GCR */  
911 - return s->gcr;  
912 - } 1153 + case 0xbd8: /* DMA_LCD_SRC_EI_B1 */
  1154 + s->lcd_ch.element_index_f1 = value;
  1155 + break;
913 1156
914 - OMAP_BAD_REG(addr); 1157 + case 0xbda: /* DMA_LCD_SRC_FI_B1_L */
  1158 + s->lcd_ch.frame_index_f1 &= 0xffff0000;
  1159 + s->lcd_ch.frame_index_f1 |= 0x0000ffff & value;
  1160 + break;
  1161 +
  1162 + case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */
  1163 + s->lcd_ch.frame_index_f1 &= 0x0000ffff;
  1164 + s->lcd_ch.frame_index_f1 |= (uint32_t) value << 16;
  1165 + break;
  1166 +
  1167 + case 0xbdc: /* DMA_LCD_SRC_EI_B2 */
  1168 + s->lcd_ch.element_index_f2 = value;
  1169 + break;
  1170 +
  1171 + case 0xbde: /* DMA_LCD_SRC_FI_B2_L */
  1172 + s->lcd_ch.frame_index_f2 &= 0xffff0000;
  1173 + s->lcd_ch.frame_index_f2 |= 0x0000ffff & value;
  1174 + break;
  1175 +
  1176 + case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */
  1177 + s->lcd_ch.frame_index_f2 &= 0x0000ffff;
  1178 + s->lcd_ch.frame_index_f2 |= (uint32_t) value << 16;
  1179 + break;
  1180 +
  1181 + case 0xbe0: /* DMA_LCD_SRC_EN_B1 */
  1182 + s->lcd_ch.elements_f1 = value;
  1183 + break;
  1184 +
  1185 + case 0xbe4: /* DMA_LCD_SRC_FN_B1 */
  1186 + s->lcd_ch.frames_f1 = value;
  1187 + break;
  1188 +
  1189 + case 0xbe2: /* DMA_LCD_SRC_EN_B2 */
  1190 + s->lcd_ch.elements_f2 = value;
  1191 + break;
  1192 +
  1193 + case 0xbe6: /* DMA_LCD_SRC_FN_B2 */
  1194 + s->lcd_ch.frames_f2 = value;
  1195 + break;
  1196 +
  1197 + case 0xbea: /* DMA_LCD_LCH_CTRL */
  1198 + s->lcd_ch.lch_type = value & 0xf;
  1199 + break;
  1200 +
  1201 + default:
  1202 + return 1;
  1203 + }
915 return 0; 1204 return 0;
916 } 1205 }
917 1206
918 -static void omap_dma_write(void *opaque, target_phys_addr_t addr,  
919 - uint32_t value) 1207 +static int omap_dma_3_2_lcd_read(struct omap_dma_s *s, int offset,
  1208 + uint16_t *ret)
920 { 1209 {
921 - struct omap_dma_s *s = (struct omap_dma_s *) opaque;  
922 - int reg, ch, offset = addr - s->base;  
923 -  
924 switch (offset) { 1210 switch (offset) {
925 - case 0x000 ... 0x2fe:  
926 - reg = offset & 0x3f;  
927 - ch = (offset >> 6) & 0x0f;  
928 - if (omap_dma_ch_reg_write(s, ch, reg, value))  
929 - OMAP_RO_REG(addr); 1211 + case 0xbc0: /* DMA_LCD_CSDP */
  1212 + *ret = (s->lcd_ch.brust_f2 << 14) |
  1213 + (s->lcd_ch.pack_f2 << 13) |
  1214 + ((s->lcd_ch.data_type_f2 >> 1) << 11) |
  1215 + (s->lcd_ch.brust_f1 << 7) |
  1216 + (s->lcd_ch.pack_f1 << 6) |
  1217 + ((s->lcd_ch.data_type_f1 >> 1) << 0);
  1218 + break;
  1219 +
  1220 + case 0xbc2: /* DMA_LCD_CCR */
  1221 + *ret = (s->lcd_ch.mode_f2 << 14) |
  1222 + (s->lcd_ch.mode_f1 << 12) |
  1223 + (s->lcd_ch.end_prog << 11) |
  1224 + (s->lcd_ch.omap_3_1_compatible_disable << 10) |
  1225 + (s->lcd_ch.repeat << 9) |
  1226 + (s->lcd_ch.auto_init << 8) |
  1227 + (s->lcd_ch.running << 7) |
  1228 + (s->lcd_ch.priority << 6) |
  1229 + (s->lcd_ch.bs << 4);
  1230 + break;
  1231 +
  1232 + case 0xbc4: /* DMA_LCD_CTRL */
  1233 + qemu_irq_lower(s->lcd_ch.irq);
  1234 + *ret = (s->lcd_ch.dst << 8) |
  1235 + ((s->lcd_ch.src & 0x6) << 5) |
  1236 + (s->lcd_ch.condition << 3) |
  1237 + (s->lcd_ch.interrupts << 1) |
  1238 + s->lcd_ch.dual;
  1239 + break;
  1240 +
  1241 + case 0xbc8: /* TOP_B1_L */
  1242 + *ret = s->lcd_ch.src_f1_top & 0xffff;
  1243 + break;
  1244 +
  1245 + case 0xbca: /* TOP_B1_U */
  1246 + *ret = s->lcd_ch.src_f1_top >> 16;
  1247 + break;
  1248 +
  1249 + case 0xbcc: /* BOT_B1_L */
  1250 + *ret = s->lcd_ch.src_f1_bottom & 0xffff;
  1251 + break;
  1252 +
  1253 + case 0xbce: /* BOT_B1_U */
  1254 + *ret = s->lcd_ch.src_f1_bottom >> 16;
  1255 + break;
  1256 +
  1257 + case 0xbd0: /* TOP_B2_L */
  1258 + *ret = s->lcd_ch.src_f2_top & 0xffff;
  1259 + break;
  1260 +
  1261 + case 0xbd2: /* TOP_B2_U */
  1262 + *ret = s->lcd_ch.src_f2_top >> 16;
  1263 + break;
  1264 +
  1265 + case 0xbd4: /* BOT_B2_L */
  1266 + *ret = s->lcd_ch.src_f2_bottom & 0xffff;
930 break; 1267 break;
931 1268
  1269 + case 0xbd6: /* BOT_B2_U */
  1270 + *ret = s->lcd_ch.src_f2_bottom >> 16;
  1271 + break;
  1272 +
  1273 + case 0xbd8: /* DMA_LCD_SRC_EI_B1 */
  1274 + *ret = s->lcd_ch.element_index_f1;
  1275 + break;
  1276 +
  1277 + case 0xbda: /* DMA_LCD_SRC_FI_B1_L */
  1278 + *ret = s->lcd_ch.frame_index_f1 & 0xffff;
  1279 + break;
  1280 +
  1281 + case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */
  1282 + *ret = s->lcd_ch.frame_index_f1 >> 16;
  1283 + break;
  1284 +
  1285 + case 0xbdc: /* DMA_LCD_SRC_EI_B2 */
  1286 + *ret = s->lcd_ch.element_index_f2;
  1287 + break;
  1288 +
  1289 + case 0xbde: /* DMA_LCD_SRC_FI_B2_L */
  1290 + *ret = s->lcd_ch.frame_index_f2 & 0xffff;
  1291 + break;
  1292 +
  1293 + case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */
  1294 + *ret = s->lcd_ch.frame_index_f2 >> 16;
  1295 + break;
  1296 +
  1297 + case 0xbe0: /* DMA_LCD_SRC_EN_B1 */
  1298 + *ret = s->lcd_ch.elements_f1;
  1299 + break;
  1300 +
  1301 + case 0xbe4: /* DMA_LCD_SRC_FN_B1 */
  1302 + *ret = s->lcd_ch.frames_f1;
  1303 + break;
  1304 +
  1305 + case 0xbe2: /* DMA_LCD_SRC_EN_B2 */
  1306 + *ret = s->lcd_ch.elements_f2;
  1307 + break;
  1308 +
  1309 + case 0xbe6: /* DMA_LCD_SRC_FN_B2 */
  1310 + *ret = s->lcd_ch.frames_f2;
  1311 + break;
  1312 +
  1313 + case 0xbea: /* DMA_LCD_LCH_CTRL */
  1314 + *ret = s->lcd_ch.lch_type;
  1315 + break;
  1316 +
  1317 + default:
  1318 + return 1;
  1319 + }
  1320 + return 0;
  1321 +}
  1322 +
  1323 +static int omap_dma_3_1_lcd_write(struct omap_dma_s *s, int offset,
  1324 + uint16_t value)
  1325 +{
  1326 + switch (offset) {
932 case 0x300: /* SYS_DMA_LCD_CTRL */ 1327 case 0x300: /* SYS_DMA_LCD_CTRL */
933 s->lcd_ch.src = (value & 0x40) ? imif : emiff; 1328 s->lcd_ch.src = (value & 0x40) ? imif : emiff;
934 s->lcd_ch.condition = 0; 1329 s->lcd_ch.condition = 0;
@@ -977,13 +1372,257 @@ static void omap_dma_write(void *opaque, target_phys_addr_t addr, @@ -977,13 +1372,257 @@ static void omap_dma_write(void *opaque, target_phys_addr_t addr,
977 s->lcd_ch.src_f2_bottom |= value << 16; 1372 s->lcd_ch.src_f2_bottom |= value << 16;
978 break; 1373 break;
979 1374
  1375 + default:
  1376 + return 1;
  1377 + }
  1378 + return 0;
  1379 +}
  1380 +
  1381 +static int omap_dma_3_1_lcd_read(struct omap_dma_s *s, int offset,
  1382 + uint16_t *ret)
  1383 +{
  1384 + int i;
  1385 +
  1386 + switch (offset) {
  1387 + case 0x300: /* SYS_DMA_LCD_CTRL */
  1388 + i = s->lcd_ch.condition;
  1389 + s->lcd_ch.condition = 0;
  1390 + qemu_irq_lower(s->lcd_ch.irq);
  1391 + *ret = ((s->lcd_ch.src == imif) << 6) | (i << 3) |
  1392 + (s->lcd_ch.interrupts << 1) | s->lcd_ch.dual;
  1393 + break;
  1394 +
  1395 + case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
  1396 + *ret = s->lcd_ch.src_f1_top & 0xffff;
  1397 + break;
  1398 +
  1399 + case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
  1400 + *ret = s->lcd_ch.src_f1_top >> 16;
  1401 + break;
  1402 +
  1403 + case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
  1404 + *ret = s->lcd_ch.src_f1_bottom & 0xffff;
  1405 + break;
  1406 +
  1407 + case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
  1408 + *ret = s->lcd_ch.src_f1_bottom >> 16;
  1409 + break;
  1410 +
  1411 + case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
  1412 + *ret = s->lcd_ch.src_f2_top & 0xffff;
  1413 + break;
  1414 +
  1415 + case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
  1416 + *ret = s->lcd_ch.src_f2_top >> 16;
  1417 + break;
  1418 +
  1419 + case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
  1420 + *ret = s->lcd_ch.src_f2_bottom & 0xffff;
  1421 + break;
  1422 +
  1423 + case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
  1424 + *ret = s->lcd_ch.src_f2_bottom >> 16;
  1425 + break;
  1426 +
  1427 + default:
  1428 + return 1;
  1429 + }
  1430 + return 0;
  1431 +}
  1432 +
  1433 +static int omap_dma_sys_write(struct omap_dma_s *s, int offset, uint16_t value)
  1434 +{
  1435 + switch (offset) {
980 case 0x400: /* SYS_DMA_GCR */ 1436 case 0x400: /* SYS_DMA_GCR */
981 - s->gcr = value & 0x000c; 1437 + s->gcr = value;
  1438 + break;
  1439 +
  1440 + case 0x404: /* DMA_GSCR */
  1441 + if (value & 0x8)
  1442 + omap_dma_disable_3_1_mapping(s);
  1443 + else
  1444 + omap_dma_enable_3_1_mapping(s);
  1445 + break;
  1446 +
  1447 + case 0x408: /* DMA_GRST */
  1448 + if (value & 0x1)
  1449 + omap_dma_reset(s);
982 break; 1450 break;
983 1451
984 default: 1452 default:
985 - OMAP_BAD_REG(addr); 1453 + return 1;
986 } 1454 }
  1455 + return 0;
  1456 +}
  1457 +
  1458 +static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
  1459 + uint16_t *ret)
  1460 +{
  1461 + switch (offset) {
  1462 + case 0x400: /* SYS_DMA_GCR */
  1463 + *ret = s->gcr;
  1464 + break;
  1465 +
  1466 + case 0x404: /* DMA_GSCR */
  1467 + *ret = s->omap_3_1_mapping_disabled << 3;
  1468 + break;
  1469 +
  1470 + case 0x408: /* DMA_GRST */
  1471 + *ret = 0;
  1472 + break;
  1473 +
  1474 + case 0x442: /* DMA_HW_ID */
  1475 + case 0x444: /* DMA_PCh2_ID */
  1476 + case 0x446: /* DMA_PCh0_ID */
  1477 + case 0x448: /* DMA_PCh1_ID */
  1478 + case 0x44a: /* DMA_PChG_ID */
  1479 + case 0x44c: /* DMA_PChD_ID */
  1480 + *ret = 1;
  1481 + break;
  1482 +
  1483 + case 0x44e: /* DMA_CAPS_0_U */
  1484 + *ret = (1 << 3) | /* Constant Fill Capacity */
  1485 + (1 << 2); /* Transparent BLT Capacity */
  1486 + break;
  1487 +
  1488 + case 0x450: /* DMA_CAPS_0_L */
  1489 + case 0x452: /* DMA_CAPS_1_U */
  1490 + *ret = 0;
  1491 + break;
  1492 +
  1493 + case 0x454: /* DMA_CAPS_1_L */
  1494 + *ret = (1 << 1); /* 1-bit palletized capability */
  1495 + break;
  1496 +
  1497 + case 0x456: /* DMA_CAPS_2 */
  1498 + *ret = (1 << 8) | /* SSDIC */
  1499 + (1 << 7) | /* DDIAC */
  1500 + (1 << 6) | /* DSIAC */
  1501 + (1 << 5) | /* DPIAC */
  1502 + (1 << 4) | /* DCAC */
  1503 + (1 << 3) | /* SDIAC */
  1504 + (1 << 2) | /* SSIAC */
  1505 + (1 << 1) | /* SPIAC */
  1506 + 1; /* SCAC */
  1507 + break;
  1508 +
  1509 + case 0x458: /* DMA_CAPS_3 */
  1510 + *ret = (1 << 5) | /* CCC */
  1511 + (1 << 4) | /* IC */
  1512 + (1 << 3) | /* ARC */
  1513 + (1 << 2) | /* AEC */
  1514 + (1 << 1) | /* FSC */
  1515 + 1; /* ESC */
  1516 + break;
  1517 +
  1518 + case 0x45a: /* DMA_CAPS_4 */
  1519 + *ret = (1 << 6) | /* SSC */
  1520 + (1 << 5) | /* BIC */
  1521 + (1 << 4) | /* LFIC */
  1522 + (1 << 3) | /* FIC */
  1523 + (1 << 2) | /* HFIC */
  1524 + (1 << 1) | /* EDIC */
  1525 + 1; /* TOIC */
  1526 + break;
  1527 +
  1528 + case 0x460: /* DMA_PCh2_SR */
  1529 + case 0x480: /* DMA_PCh0_SR */
  1530 + case 0x482: /* DMA_PCh1_SR */
  1531 + case 0x4c0: /* DMA_PChD_SR_0 */
  1532 + printf("%s: Physical Channel Status Registers not implemented.\n",
  1533 + __FUNCTION__);
  1534 + *ret = 0xff;
  1535 + break;
  1536 +
  1537 + default:
  1538 + return 1;
  1539 + }
  1540 + return 0;
  1541 +}
  1542 +
  1543 +static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
  1544 +{
  1545 + struct omap_dma_s *s = (struct omap_dma_s *) opaque;
  1546 + int reg, ch, offset = addr - s->base;
  1547 + uint16_t ret;
  1548 +
  1549 + switch (offset) {
  1550 + case 0x300 ... 0x3fe:
  1551 + if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
  1552 + if (omap_dma_3_1_lcd_read(s, offset, &ret))
  1553 + break;
  1554 + return ret;
  1555 + }
  1556 + /* Fall through. */
  1557 + case 0x000 ... 0x2fe:
  1558 + reg = offset & 0x3f;
  1559 + ch = (offset >> 6) & 0x0f;
  1560 + if (omap_dma_ch_reg_read(s, ch, reg, &ret))
  1561 + break;
  1562 + return ret;
  1563 +
  1564 + case 0x404 ... 0x4fe:
  1565 + if (s->model == omap_dma_3_1)
  1566 + break;
  1567 + /* Fall through. */
  1568 + case 0x400:
  1569 + if (omap_dma_sys_read(s, offset, &ret))
  1570 + break;
  1571 + return ret;
  1572 +
  1573 + case 0xb00 ... 0xbfe:
  1574 + if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
  1575 + if (omap_dma_3_2_lcd_read(s, offset, &ret))
  1576 + break;
  1577 + return ret;
  1578 + }
  1579 + break;
  1580 + }
  1581 +
  1582 + OMAP_BAD_REG(addr);
  1583 + return 0;
  1584 +}
  1585 +
  1586 +static void omap_dma_write(void *opaque, target_phys_addr_t addr,
  1587 + uint32_t value)
  1588 +{
  1589 + struct omap_dma_s *s = (struct omap_dma_s *) opaque;
  1590 + int reg, ch, offset = addr - s->base;
  1591 +
  1592 + switch (offset) {
  1593 + case 0x300 ... 0x3fe:
  1594 + if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
  1595 + if (omap_dma_3_1_lcd_write(s, offset, value))
  1596 + break;
  1597 + return;
  1598 + }
  1599 + /* Fall through. */
  1600 + case 0x000 ... 0x2fe:
  1601 + reg = offset & 0x3f;
  1602 + ch = (offset >> 6) & 0x0f;
  1603 + if (omap_dma_ch_reg_write(s, ch, reg, value))
  1604 + break;
  1605 + return;
  1606 +
  1607 + case 0x404 ... 0x4fe:
  1608 + if (s->model == omap_dma_3_1)
  1609 + break;
  1610 + case 0x400:
  1611 + /* Fall through. */
  1612 + if (omap_dma_sys_write(s, offset, value))
  1613 + break;
  1614 + return;
  1615 +
  1616 + case 0xb00 ... 0xbfe:
  1617 + if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
  1618 + if (omap_dma_3_2_lcd_write(s, offset, value))
  1619 + break;
  1620 + return;
  1621 + }
  1622 + break;
  1623 + }
  1624 +
  1625 + OMAP_BAD_REG(addr);
987 } 1626 }
988 1627
989 static CPUReadMemoryFunc *omap_dma_readfn[] = { 1628 static CPUReadMemoryFunc *omap_dma_readfn[] = {
@@ -1005,7 +1644,7 @@ static void omap_dma_request(void *opaque, int drq, int req) @@ -1005,7 +1644,7 @@ static void omap_dma_request(void *opaque, int drq, int req)
1005 if (req) { 1644 if (req) {
1006 if (~s->drq & (1 << drq)) { 1645 if (~s->drq & (1 << drq)) {
1007 s->drq |= 1 << drq; 1646 s->drq |= 1 << drq;
1008 - omap_dma_request_run(s, 0, drq); 1647 + omap_dma_process_request(s, drq);
1009 } 1648 }
1010 } else 1649 } else
1011 s->drq &= ~(1 << drq); 1650 s->drq &= ~(1 << drq);
@@ -1026,36 +1665,27 @@ static void omap_dma_clk_update(void *opaque, int line, int on) @@ -1026,36 +1665,27 @@ static void omap_dma_clk_update(void *opaque, int line, int on)
1026 } 1665 }
1027 } 1666 }
1028 1667
1029 -static void omap_dma_reset(struct omap_dma_s *s)  
1030 -{  
1031 - int i;  
1032 -  
1033 - qemu_del_timer(s->tm);  
1034 - s->gcr = 0x0004;  
1035 - s->drq = 0x00000000;  
1036 - s->run_count = 0;  
1037 - s->lcd_ch.src = emiff;  
1038 - s->lcd_ch.condition = 0;  
1039 - s->lcd_ch.interrupts = 0;  
1040 - s->lcd_ch.dual = 0;  
1041 - memset(s->ch, 0, sizeof(s->ch));  
1042 - for (i = 0; i < s->chans; i ++)  
1043 - s->ch[i].interrupts = 0x0003;  
1044 -}  
1045 -  
1046 -struct omap_dma_s *omap_dma_init(target_phys_addr_t base,  
1047 - qemu_irq pic[], struct omap_mpu_state_s *mpu, omap_clk clk) 1668 +struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
  1669 + qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
  1670 + enum omap_dma_model model)
1048 { 1671 {
1049 - int iomemtype; 1672 + int iomemtype, num_irqs, memsize;
1050 struct omap_dma_s *s = (struct omap_dma_s *) 1673 struct omap_dma_s *s = (struct omap_dma_s *)
1051 qemu_mallocz(sizeof(struct omap_dma_s)); 1674 qemu_mallocz(sizeof(struct omap_dma_s));
1052 1675
1053 - s->ih = pic; 1676 + if (model == omap_dma_3_1) {
  1677 + num_irqs = 6;
  1678 + memsize = 0x800;
  1679 + } else {
  1680 + num_irqs = 16;
  1681 + memsize = 0xc00;
  1682 + }
  1683 + memcpy(s->irqs, irqs, num_irqs * sizeof(qemu_irq));
1054 s->base = base; 1684 s->base = base;
1055 - s->chans = 9; 1685 + s->model = model;
1056 s->mpu = mpu; 1686 s->mpu = mpu;
1057 s->clk = clk; 1687 s->clk = clk;
1058 - s->lcd_ch.irq = pic[OMAP_INT_DMA_LCD]; 1688 + s->lcd_ch.irq = lcd_irq;
1059 s->lcd_ch.mpu = mpu; 1689 s->lcd_ch.mpu = mpu;
1060 s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s); 1690 s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
1061 omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]); 1691 omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
@@ -1065,7 +1695,7 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, @@ -1065,7 +1695,7 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
1065 1695
1066 iomemtype = cpu_register_io_memory(0, omap_dma_readfn, 1696 iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1067 omap_dma_writefn, s); 1697 omap_dma_writefn, s);
1068 - cpu_register_physical_memory(s->base, 0x800, iomemtype); 1698 + cpu_register_physical_memory(s->base, memsize, iomemtype);
1069 1699
1070 return s; 1700 return s;
1071 } 1701 }
@@ -4919,13 +5549,39 @@ static void omap_mpu_wakeup(void *opaque, int irq, int req) @@ -4919,13 +5549,39 @@ static void omap_mpu_wakeup(void *opaque, int irq, int req)
4919 cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB); 5549 cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4920 } 5550 }
4921 5551
  5552 +struct dma_irq_map {
  5553 + int ih;
  5554 + int intr;
  5555 +};
  5556 +
  5557 +static const struct dma_irq_map omap_dma_irq_map[] = {
  5558 + { 0, OMAP_INT_DMA_CH0_6 },
  5559 + { 0, OMAP_INT_DMA_CH1_7 },
  5560 + { 0, OMAP_INT_DMA_CH2_8 },
  5561 + { 0, OMAP_INT_DMA_CH3 },
  5562 + { 0, OMAP_INT_DMA_CH4 },
  5563 + { 0, OMAP_INT_DMA_CH5 },
  5564 + { 1, OMAP_INT_1610_DMA_CH6 },
  5565 + { 1, OMAP_INT_1610_DMA_CH7 },
  5566 + { 1, OMAP_INT_1610_DMA_CH8 },
  5567 + { 1, OMAP_INT_1610_DMA_CH9 },
  5568 + { 1, OMAP_INT_1610_DMA_CH10 },
  5569 + { 1, OMAP_INT_1610_DMA_CH11 },
  5570 + { 1, OMAP_INT_1610_DMA_CH12 },
  5571 + { 1, OMAP_INT_1610_DMA_CH13 },
  5572 + { 1, OMAP_INT_1610_DMA_CH14 },
  5573 + { 1, OMAP_INT_1610_DMA_CH15 }
  5574 +};
  5575 +
4922 struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, 5576 struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4923 DisplayState *ds, const char *core) 5577 DisplayState *ds, const char *core)
4924 { 5578 {
  5579 + int i;
4925 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) 5580 struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
4926 qemu_mallocz(sizeof(struct omap_mpu_state_s)); 5581 qemu_mallocz(sizeof(struct omap_mpu_state_s));
4927 ram_addr_t imif_base, emiff_base; 5582 ram_addr_t imif_base, emiff_base;
4928 qemu_irq *cpu_irq; 5583 qemu_irq *cpu_irq;
  5584 + qemu_irq dma_irqs[6];
4929 int sdindex; 5585 int sdindex;
4930 5586
4931 if (!core) 5587 if (!core)
@@ -4964,8 +5620,11 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, @@ -4964,8 +5620,11 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4964 s->irq[0] = s->ih[0]->pins; 5620 s->irq[0] = s->ih[0]->pins;
4965 s->irq[1] = s->ih[1]->pins; 5621 s->irq[1] = s->ih[1]->pins;
4966 5622
4967 - s->dma = omap_dma_init(0xfffed800, s->irq[0], s,  
4968 - omap_findclk(s, "dma_ck")); 5623 + for (i = 0; i < 6; i ++)
  5624 + dma_irqs[i] = s->irq[omap_dma_irq_map[i].ih][omap_dma_irq_map[i].intr];
  5625 + s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
  5626 + s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
  5627 +
4969 s->port[emiff ].addr_valid = omap_validate_emiff_addr; 5628 s->port[emiff ].addr_valid = omap_validate_emiff_addr;
4970 s->port[emifs ].addr_valid = omap_validate_emifs_addr; 5629 s->port[emifs ].addr_valid = omap_validate_emifs_addr;
4971 s->port[imif ].addr_valid = omap_validate_imif_addr; 5630 s->port[imif ].addr_valid = omap_validate_imif_addr;
hw/omap.h
@@ -336,26 +336,68 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, @@ -336,26 +336,68 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
336 # define OMAP_INT_243X_HS_USB_DMA 93 336 # define OMAP_INT_243X_HS_USB_DMA 93
337 # define OMAP_INT_243X_CARKIT 94 337 # define OMAP_INT_243X_CARKIT 94
338 338
  339 +enum omap_dma_model {
  340 + omap_dma_3_1 = 0,
  341 + omap_dma_3_2
  342 +};
  343 +
339 struct omap_dma_s; 344 struct omap_dma_s;
340 -struct omap_dma_s *omap_dma_init(target_phys_addr_t base,  
341 - qemu_irq pic[], struct omap_mpu_state_s *mpu, omap_clk clk); 345 +struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
  346 + qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
  347 + enum omap_dma_model model);
342 348
343 enum omap_dma_port { 349 enum omap_dma_port {
344 emiff = 0, 350 emiff = 0,
345 emifs, 351 emifs,
346 - imif, 352 + imif, /* omap16xx: ocp_t1 */
347 tipb, 353 tipb,
348 - local, 354 + local, /* omap16xx: ocp_t2 */
349 tipb_mpui, 355 tipb_mpui,
350 omap_dma_port_last, 356 omap_dma_port_last,
351 }; 357 };
352 358
  359 +typedef enum {
  360 + constant = 0,
  361 + post_incremented,
  362 + single_index,
  363 + double_index,
  364 +} omap_dma_addressing_t;
  365 +
353 struct omap_dma_lcd_channel_s { 366 struct omap_dma_lcd_channel_s {
354 enum omap_dma_port src; 367 enum omap_dma_port src;
355 target_phys_addr_t src_f1_top; 368 target_phys_addr_t src_f1_top;
356 target_phys_addr_t src_f1_bottom; 369 target_phys_addr_t src_f1_bottom;
357 target_phys_addr_t src_f2_top; 370 target_phys_addr_t src_f2_top;
358 target_phys_addr_t src_f2_bottom; 371 target_phys_addr_t src_f2_bottom;
  372 +
  373 + /* Used in OMAP DMA 3.2 gigacell */
  374 + unsigned char brust_f1;
  375 + unsigned char pack_f1;
  376 + unsigned char data_type_f1;
  377 + unsigned char brust_f2;
  378 + unsigned char pack_f2;
  379 + unsigned char data_type_f2;
  380 + unsigned char end_prog;
  381 + unsigned char repeat;
  382 + unsigned char auto_init;
  383 + unsigned char priority;
  384 + unsigned char fs;
  385 + unsigned char running;
  386 + unsigned char bs;
  387 + unsigned char omap_3_1_compatible_disable;
  388 + unsigned char dst;
  389 + unsigned char lch_type;
  390 + int16_t element_index_f1;
  391 + int16_t element_index_f2;
  392 + int32_t frame_index_f1;
  393 + int32_t frame_index_f2;
  394 + uint16_t elements_f1;
  395 + uint16_t frames_f1;
  396 + uint16_t elements_f2;
  397 + uint16_t frames_f2;
  398 + omap_dma_addressing_t mode_f1;
  399 + omap_dma_addressing_t mode_f2;
  400 +
359 /* Destination port is fixed. */ 401 /* Destination port is fixed. */
360 int interrupts; 402 int interrupts;
361 int condition; 403 int condition;