Commit b4e3104b518eda149c72863a7fe3ccea33f2e4ff

Authored by balrog
1 parent a8fbaf96

Split OMAP DMA out to a file apart.

Rename omap files to better reflect OMAP1-specific parts.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4025 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
@@ -592,7 +592,7 @@ OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o @@ -592,7 +592,7 @@ OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o
592 OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o 592 OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
593 OBJS+= pflash_cfi01.o gumstix.o 593 OBJS+= pflash_cfi01.o gumstix.o
594 OBJS+= spitz.o ide.o serial.o nand.o ecc.o 594 OBJS+= spitz.o ide.o serial.o nand.o ecc.o
595 -OBJS+= omap.o omap_lcdc.o omap1_clk.o omap_mmc.o omap_i2c.o 595 +OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o
596 OBJS+= palm.o tsc210x.o 596 OBJS+= palm.o tsc210x.o
597 OBJS+= mst_fpga.o mainstone.o 597 OBJS+= mst_fpga.o mainstone.o
598 CPPFLAGS += -DHAS_AUDIO 598 CPPFLAGS += -DHAS_AUDIO
hw/omap.h
1 /* 1 /*
2 * Texas Instruments OMAP processors. 2 * Texas Instruments OMAP processors.
3 * 3 *
4 - * Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org> 4 + * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as 7 * modify it under the terms of the GNU General Public License as
@@ -54,7 +54,7 @@ void omap_clk_setrate(omap_clk clk, int divide, int multiply); @@ -54,7 +54,7 @@ void omap_clk_setrate(omap_clk clk, int divide, int multiply);
54 int64_t omap_clk_getrate(omap_clk clk); 54 int64_t omap_clk_getrate(omap_clk clk);
55 void omap_clk_reparent(omap_clk clk, omap_clk parent); 55 void omap_clk_reparent(omap_clk clk, omap_clk parent);
56 56
57 -/* omap.c */ 57 +/* omap[123].c */
58 struct omap_intr_handler_s; 58 struct omap_intr_handler_s;
59 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, 59 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
60 unsigned long size, unsigned char nbanks, 60 unsigned long size, unsigned char nbanks,
@@ -340,16 +340,26 @@ static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, @@ -340,16 +340,26 @@ static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta,
340 # define OMAP_INT_243X_HS_USB_DMA 93 340 # define OMAP_INT_243X_HS_USB_DMA 93
341 # define OMAP_INT_243X_CARKIT 94 341 # define OMAP_INT_243X_CARKIT 94
342 342
  343 +/* omap_dma.c */
343 enum omap_dma_model { 344 enum omap_dma_model {
344 - omap_dma_3_1 = 0,  
345 - omap_dma_3_2 345 + omap_dma_3_0,
  346 + omap_dma_3_1,
  347 + omap_dma_3_2,
  348 + omap_dma_4,
346 }; 349 };
347 350
348 struct omap_dma_s; 351 struct omap_dma_s;
349 struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs, 352 struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
350 qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk, 353 qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
351 enum omap_dma_model model); 354 enum omap_dma_model model);
  355 +void omap_dma_reset(struct omap_dma_s *s);
352 356
  357 +struct dma_irq_map {
  358 + int ih;
  359 + int intr;
  360 +};
  361 +
  362 +/* Only used in OMAP DMA 3.x gigacells */
353 enum omap_dma_port { 363 enum omap_dma_port {
354 emiff = 0, 364 emiff = 0,
355 emifs, 365 emifs,
@@ -367,6 +377,7 @@ typedef enum { @@ -367,6 +377,7 @@ typedef enum {
367 double_index, 377 double_index,
368 } omap_dma_addressing_t; 378 } omap_dma_addressing_t;
369 379
  380 +/* Only used in OMAP DMA 3.x gigacells */
370 struct omap_dma_lcd_channel_s { 381 struct omap_dma_lcd_channel_s {
371 enum omap_dma_port src; 382 enum omap_dma_port src;
372 target_phys_addr_t src_f1_top; 383 target_phys_addr_t src_f1_top;
@@ -411,7 +422,7 @@ struct omap_dma_lcd_channel_s { @@ -411,7 +422,7 @@ struct omap_dma_lcd_channel_s {
411 ram_addr_t phys_framebuffer[2]; 422 ram_addr_t phys_framebuffer[2];
412 qemu_irq irq; 423 qemu_irq irq;
413 struct omap_mpu_state_s *mpu; 424 struct omap_mpu_state_s *mpu;
414 -}; 425 +} *omap_dma_get_lcdch(struct omap_dma_s *s);
415 426
416 /* 427 /*
417 * DMA request numbers for OMAP1 428 * DMA request numbers for OMAP1
@@ -477,6 +488,7 @@ struct omap_dma_lcd_channel_s { @@ -477,6 +488,7 @@ struct omap_dma_lcd_channel_s {
477 # define OMAP_DMA_MMC2_RX 55 488 # define OMAP_DMA_MMC2_RX 55
478 # define OMAP_DMA_CRYPTO_DES_OUT 56 489 # define OMAP_DMA_CRYPTO_DES_OUT 56
479 490
  491 +/* omap[123].c */
480 struct omap_mpu_timer_s; 492 struct omap_mpu_timer_s;
481 struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base, 493 struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
482 qemu_irq irq, omap_clk clk); 494 qemu_irq irq, omap_clk clk);
hw/omap.c renamed to hw/omap1.c
1 /* 1 /*
2 * TI OMAP processors emulation. 2 * TI OMAP processors emulation.
3 * 3 *
4 - * Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org> 4 + * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as 7 * modify it under the terms of the GNU General Public License as
@@ -401,1370 +401,6 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base, @@ -401,1370 +401,6 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
401 return s; 401 return s;
402 } 402 }
403 403
404 -/* OMAP1 DMA module */  
405 -struct omap_dma_channel_s {  
406 - /* transfer data */  
407 - int burst[2];  
408 - int pack[2];  
409 - enum omap_dma_port port[2];  
410 - target_phys_addr_t addr[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];  
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 */  
424 - int end_prog;  
425 - int repeat;  
426 - int auto_init;  
427 - int link_enabled;  
428 - int link_next_ch;  
429 -  
430 - /* interruption data */  
431 - int interrupts;  
432 - int status;  
433 -  
434 - /* state data */  
435 - int active;  
436 - int enable;  
437 - int sync;  
438 - int pending_request;  
439 - int waiting_end_prog;  
440 - uint16_t cpc;  
441 -  
442 - /* sync type */  
443 - int fs;  
444 - int bs;  
445 -  
446 - /* compatibility */  
447 - int omap_3_1_compatible_disable;  
448 -  
449 - qemu_irq irq;  
450 - struct omap_dma_channel_s *sibling;  
451 -  
452 - struct omap_dma_reg_set_s {  
453 - target_phys_addr_t src, dest;  
454 - int frame;  
455 - int element;  
456 - int frame_delta[2];  
457 - int elem_delta[2];  
458 - int frames;  
459 - int elements;  
460 - } active_set;  
461 -  
462 - /* unused parameters */  
463 - int priority;  
464 - int interleave_disabled;  
465 - int type;  
466 -};  
467 -  
468 -struct omap_dma_s {  
469 - QEMUTimer *tm;  
470 - struct omap_mpu_state_s *mpu;  
471 - target_phys_addr_t base;  
472 - omap_clk clk;  
473 - int64_t delay;  
474 - uint32_t drq;  
475 - enum omap_dma_model model;  
476 - int omap_3_1_mapping_disabled;  
477 -  
478 - uint16_t gcr;  
479 - int run_count;  
480 -  
481 - int chans;  
482 - struct omap_dma_channel_s ch[16];  
483 - struct omap_dma_lcd_channel_s lcd_ch;  
484 -};  
485 -  
486 -/* Interrupts */  
487 -#define TIMEOUT_INTR (1 << 0)  
488 -#define EVENT_DROP_INTR (1 << 1)  
489 -#define HALF_FRAME_INTR (1 << 2)  
490 -#define END_FRAME_INTR (1 << 3)  
491 -#define LAST_FRAME_INTR (1 << 4)  
492 -#define END_BLOCK_INTR (1 << 5)  
493 -#define SYNC (1 << 6)  
494 -  
495 -static void omap_dma_interrupts_update(struct omap_dma_s *s)  
496 -{  
497 - struct omap_dma_channel_s *ch = s->ch;  
498 - int i;  
499 -  
500 - if (s->omap_3_1_mapping_disabled) {  
501 - for (i = 0; i < s->chans; i ++, ch ++)  
502 - if (ch->status)  
503 - qemu_irq_raise(ch->irq);  
504 - } else {  
505 - /* First three interrupts are shared between two channels each. */  
506 - for (i = 0; i < 6; i ++, ch ++) {  
507 - if (ch->status || (ch->sibling && ch->sibling->status))  
508 - qemu_irq_raise(ch->irq);  
509 - }  
510 - }  
511 -}  
512 -  
513 -static void omap_dma_channel_load(struct omap_dma_s *s,  
514 - struct omap_dma_channel_s *ch)  
515 -{  
516 - struct omap_dma_reg_set_s *a = &ch->active_set;  
517 - int i;  
518 - int omap_3_1 = !ch->omap_3_1_compatible_disable;  
519 -  
520 - /*  
521 - * TODO: verify address ranges and alignment  
522 - * TODO: port endianness  
523 - */  
524 -  
525 - a->src = ch->addr[0];  
526 - a->dest = ch->addr[1];  
527 - a->frames = ch->frames;  
528 - a->elements = ch->elements;  
529 - a->frame = 0;  
530 - a->element = 0;  
531 -  
532 - if (unlikely(!ch->elements || !ch->frames)) {  
533 - printf("%s: bad DMA request\n", __FUNCTION__);  
534 - return;  
535 - }  
536 -  
537 - for (i = 0; i < 2; i ++)  
538 - switch (ch->mode[i]) {  
539 - case constant:  
540 - a->elem_delta[i] = 0;  
541 - a->frame_delta[i] = 0;  
542 - break;  
543 - case post_incremented:  
544 - a->elem_delta[i] = ch->data_type;  
545 - a->frame_delta[i] = 0;  
546 - break;  
547 - case single_index:  
548 - a->elem_delta[i] = ch->data_type +  
549 - ch->element_index[omap_3_1 ? 0 : i] - 1;  
550 - a->frame_delta[i] = 0;  
551 - break;  
552 - case double_index:  
553 - a->elem_delta[i] = ch->data_type +  
554 - ch->element_index[omap_3_1 ? 0 : i] - 1;  
555 - a->frame_delta[i] = ch->frame_index[omap_3_1 ? 0 : i] -  
556 - ch->element_index[omap_3_1 ? 0 : i];  
557 - break;  
558 - default:  
559 - break;  
560 - }  
561 -}  
562 -  
563 -static void omap_dma_activate_channel(struct omap_dma_s *s,  
564 - struct omap_dma_channel_s *ch)  
565 -{  
566 - if (!ch->active) {  
567 - ch->active = 1;  
568 - if (ch->sync)  
569 - ch->status |= SYNC;  
570 - s->run_count ++;  
571 - }  
572 -  
573 - if (s->delay && !qemu_timer_pending(s->tm))  
574 - qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);  
575 -}  
576 -  
577 -static void omap_dma_deactivate_channel(struct omap_dma_s *s,  
578 - struct omap_dma_channel_s *ch)  
579 -{  
580 - /* Update cpc */  
581 - ch->cpc = ch->active_set.dest & 0xffff;  
582 -  
583 - if (ch->pending_request && !ch->waiting_end_prog) {  
584 - /* Don't deactivate the channel */  
585 - ch->pending_request = 0;  
586 - if (ch->enable)  
587 - return;  
588 - }  
589 -  
590 - /* Don't deactive the channel if it is synchronized and the DMA request is  
591 - active */  
592 - if (ch->sync && (s->drq & (1 << ch->sync)) && ch->enable)  
593 - return;  
594 -  
595 - if (ch->active) {  
596 - ch->active = 0;  
597 - ch->status &= ~SYNC;  
598 - s->run_count --;  
599 - }  
600 -  
601 - if (!s->run_count)  
602 - qemu_del_timer(s->tm);  
603 -}  
604 -  
605 -static void omap_dma_enable_channel(struct omap_dma_s *s,  
606 - struct omap_dma_channel_s *ch)  
607 -{  
608 - if (!ch->enable) {  
609 - ch->enable = 1;  
610 - ch->waiting_end_prog = 0;  
611 - omap_dma_channel_load(s, ch);  
612 - if ((!ch->sync) || (s->drq & (1 << ch->sync)))  
613 - omap_dma_activate_channel(s, ch);  
614 - }  
615 -}  
616 -  
617 -static void omap_dma_disable_channel(struct omap_dma_s *s,  
618 - struct omap_dma_channel_s *ch)  
619 -{  
620 - if (ch->enable) {  
621 - ch->enable = 0;  
622 - /* Discard any pending request */  
623 - ch->pending_request = 0;  
624 - omap_dma_deactivate_channel(s, ch);  
625 - }  
626 -}  
627 -  
628 -static void omap_dma_channel_end_prog(struct omap_dma_s *s,  
629 - struct omap_dma_channel_s *ch)  
630 -{  
631 - if (ch->waiting_end_prog) {  
632 - ch->waiting_end_prog = 0;  
633 - if (!ch->sync || ch->pending_request) {  
634 - ch->pending_request = 0;  
635 - omap_dma_activate_channel(s, ch);  
636 - }  
637 - }  
638 -}  
639 -  
640 -static void omap_dma_enable_3_1_mapping(struct omap_dma_s *s)  
641 -{  
642 - s->omap_3_1_mapping_disabled = 0;  
643 - s->chans = 9;  
644 -}  
645 -  
646 -static void omap_dma_disable_3_1_mapping(struct omap_dma_s *s)  
647 -{  
648 - s->omap_3_1_mapping_disabled = 1;  
649 - s->chans = 16;  
650 -}  
651 -  
652 -static void omap_dma_process_request(struct omap_dma_s *s, int request)  
653 -{  
654 - int channel;  
655 - int drop_event = 0;  
656 - struct omap_dma_channel_s *ch = s->ch;  
657 -  
658 - for (channel = 0; channel < s->chans; channel ++, ch ++) {  
659 - if (ch->enable && ch->sync == request) {  
660 - if (!ch->active)  
661 - omap_dma_activate_channel(s, ch);  
662 - else if (!ch->pending_request)  
663 - ch->pending_request = 1;  
664 - else {  
665 - /* Request collision */  
666 - /* Second request received while processing other request */  
667 - ch->status |= EVENT_DROP_INTR;  
668 - drop_event = 1;  
669 - }  
670 - }  
671 - }  
672 -  
673 - if (drop_event)  
674 - omap_dma_interrupts_update(s);  
675 -}  
676 -  
677 -static void omap_dma_channel_run(struct omap_dma_s *s)  
678 -{  
679 - int n = s->chans;  
680 - uint16_t status;  
681 - uint8_t value[4];  
682 - struct omap_dma_port_if_s *src_p, *dest_p;  
683 - struct omap_dma_reg_set_s *a;  
684 - struct omap_dma_channel_s *ch;  
685 -  
686 - for (ch = s->ch; n; n --, ch ++) {  
687 - if (!ch->active)  
688 - continue;  
689 -  
690 - a = &ch->active_set;  
691 -  
692 - src_p = &s->mpu->port[ch->port[0]];  
693 - dest_p = &s->mpu->port[ch->port[1]];  
694 - if ((!ch->constant_fill && !src_p->addr_valid(s->mpu, a->src)) ||  
695 - (!dest_p->addr_valid(s->mpu, a->dest))) {  
696 -#if 0  
697 - /* Bus time-out */  
698 - if (ch->interrupts & TIMEOUT_INTR)  
699 - ch->status |= TIMEOUT_INTR;  
700 - omap_dma_deactivate_channel(s, ch);  
701 - continue;  
702 -#endif  
703 - printf("%s: Bus time-out in DMA%i operation\n",  
704 - __FUNCTION__, s->chans - n);  
705 - }  
706 -  
707 - status = ch->status;  
708 - while (status == ch->status && ch->active) {  
709 - /* Transfer a single element */  
710 - /* FIXME: check the endianness */  
711 - if (!ch->constant_fill)  
712 - cpu_physical_memory_read(a->src, value, ch->data_type);  
713 - else  
714 - *(uint32_t *) value = ch->color;  
715 -  
716 - if (!ch->transparent_copy ||  
717 - *(uint32_t *) value != ch->color)  
718 - cpu_physical_memory_write(a->dest, value, ch->data_type);  
719 -  
720 - a->src += a->elem_delta[0];  
721 - a->dest += a->elem_delta[1];  
722 - a->element ++;  
723 -  
724 - /* If the channel is element synchronized, deactivate it */  
725 - if (ch->sync && !ch->fs && !ch->bs)  
726 - omap_dma_deactivate_channel(s, ch);  
727 -  
728 - /* If it is the last frame, set the LAST_FRAME interrupt */  
729 - if (a->element == 1 && a->frame == a->frames - 1)  
730 - if (ch->interrupts & LAST_FRAME_INTR)  
731 - ch->status |= LAST_FRAME_INTR;  
732 -  
733 - /* If the half of the frame was reached, set the HALF_FRAME  
734 - interrupt */  
735 - if (a->element == (a->elements >> 1))  
736 - if (ch->interrupts & HALF_FRAME_INTR)  
737 - ch->status |= HALF_FRAME_INTR;  
738 -  
739 - if (a->element == a->elements) {  
740 - /* End of Frame */  
741 - a->element = 0;  
742 - a->src += a->frame_delta[0];  
743 - a->dest += a->frame_delta[1];  
744 - a->frame ++;  
745 -  
746 - /* If the channel is frame synchronized, deactivate it */  
747 - if (ch->sync && ch->fs)  
748 - omap_dma_deactivate_channel(s, ch);  
749 -  
750 - /* If the channel is async, update cpc */  
751 - if (!ch->sync)  
752 - ch->cpc = a->dest & 0xffff;  
753 -  
754 - /* Set the END_FRAME interrupt */  
755 - if (ch->interrupts & END_FRAME_INTR)  
756 - ch->status |= END_FRAME_INTR;  
757 -  
758 - if (a->frame == a->frames) {  
759 - /* End of Block */  
760 - /* Disable the channel */  
761 -  
762 - if (ch->omap_3_1_compatible_disable) {  
763 - omap_dma_disable_channel(s, ch);  
764 - if (ch->link_enabled)  
765 - omap_dma_enable_channel(s,  
766 - &s->ch[ch->link_next_ch]);  
767 - } else {  
768 - if (!ch->auto_init)  
769 - omap_dma_disable_channel(s, ch);  
770 - else if (ch->repeat || ch->end_prog)  
771 - omap_dma_channel_load(s, ch);  
772 - else {  
773 - ch->waiting_end_prog = 1;  
774 - omap_dma_deactivate_channel(s, ch);  
775 - }  
776 - }  
777 -  
778 - if (ch->interrupts & END_BLOCK_INTR)  
779 - ch->status |= END_BLOCK_INTR;  
780 - }  
781 - }  
782 - }  
783 - }  
784 -  
785 - omap_dma_interrupts_update(s);  
786 - if (s->run_count && s->delay)  
787 - qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);  
788 -}  
789 -  
790 -static void omap_dma_reset(struct omap_dma_s *s)  
791 -{  
792 - int i;  
793 -  
794 - qemu_del_timer(s->tm);  
795 - s->gcr = 0x0004;  
796 - s->drq = 0x00000000;  
797 - s->run_count = 0;  
798 - s->lcd_ch.src = emiff;  
799 - s->lcd_ch.condition = 0;  
800 - s->lcd_ch.interrupts = 0;  
801 - s->lcd_ch.dual = 0;  
802 - omap_dma_enable_3_1_mapping(s);  
803 - for (i = 0; i < s->chans; i ++) {  
804 - memset(&s->ch[i].burst, 0, sizeof(s->ch[i].burst));  
805 - memset(&s->ch[i].port, 0, sizeof(s->ch[i].port));  
806 - memset(&s->ch[i].mode, 0, sizeof(s->ch[i].mode));  
807 - memset(&s->ch[i].elements, 0, sizeof(s->ch[i].elements));  
808 - memset(&s->ch[i].frames, 0, sizeof(s->ch[i].frames));  
809 - memset(&s->ch[i].frame_index, 0, sizeof(s->ch[i].frame_index));  
810 - memset(&s->ch[i].element_index, 0, sizeof(s->ch[i].element_index));  
811 - memset(&s->ch[i].data_type, 0, sizeof(s->ch[i].data_type));  
812 - memset(&s->ch[i].transparent_copy, 0,  
813 - sizeof(s->ch[i].transparent_copy));  
814 - memset(&s->ch[i].constant_fill, 0, sizeof(s->ch[i].constant_fill));  
815 - memset(&s->ch[i].color, 0, sizeof(s->ch[i].color));  
816 - memset(&s->ch[i].end_prog, 0, sizeof(s->ch[i].end_prog));  
817 - memset(&s->ch[i].repeat, 0, sizeof(s->ch[i].repeat));  
818 - memset(&s->ch[i].auto_init, 0, sizeof(s->ch[i].auto_init));  
819 - memset(&s->ch[i].link_enabled, 0, sizeof(s->ch[i].link_enabled));  
820 - memset(&s->ch[i].link_next_ch, 0, sizeof(s->ch[i].link_next_ch));  
821 - s->ch[i].interrupts = 0x0003;  
822 - memset(&s->ch[i].status, 0, sizeof(s->ch[i].status));  
823 - memset(&s->ch[i].active, 0, sizeof(s->ch[i].active));  
824 - memset(&s->ch[i].enable, 0, sizeof(s->ch[i].enable));  
825 - memset(&s->ch[i].sync, 0, sizeof(s->ch[i].sync));  
826 - memset(&s->ch[i].pending_request, 0, sizeof(s->ch[i].pending_request));  
827 - memset(&s->ch[i].waiting_end_prog, 0,  
828 - sizeof(s->ch[i].waiting_end_prog));  
829 - memset(&s->ch[i].cpc, 0, sizeof(s->ch[i].cpc));  
830 - memset(&s->ch[i].fs, 0, sizeof(s->ch[i].fs));  
831 - memset(&s->ch[i].bs, 0, sizeof(s->ch[i].bs));  
832 - memset(&s->ch[i].omap_3_1_compatible_disable, 0,  
833 - sizeof(s->ch[i].omap_3_1_compatible_disable));  
834 - memset(&s->ch[i].active_set, 0, sizeof(s->ch[i].active_set));  
835 - memset(&s->ch[i].priority, 0, sizeof(s->ch[i].priority));  
836 - memset(&s->ch[i].interleave_disabled, 0,  
837 - sizeof(s->ch[i].interleave_disabled));  
838 - memset(&s->ch[i].type, 0, sizeof(s->ch[i].type));  
839 - }  
840 -}  
841 -  
842 -static int omap_dma_ch_reg_read(struct omap_dma_s *s,  
843 - struct omap_dma_channel_s *ch, int reg, uint16_t *value)  
844 -{  
845 - switch (reg) {  
846 - case 0x00: /* SYS_DMA_CSDP_CH0 */  
847 - *value = (ch->burst[1] << 14) |  
848 - (ch->pack[1] << 13) |  
849 - (ch->port[1] << 9) |  
850 - (ch->burst[0] << 7) |  
851 - (ch->pack[0] << 6) |  
852 - (ch->port[0] << 2) |  
853 - (ch->data_type >> 1);  
854 - break;  
855 -  
856 - case 0x02: /* SYS_DMA_CCR_CH0 */  
857 - if (s->model == omap_dma_3_1)  
858 - *value = 0 << 10; /* FIFO_FLUSH reads as 0 */  
859 - else  
860 - *value = ch->omap_3_1_compatible_disable << 10;  
861 - *value |= (ch->mode[1] << 14) |  
862 - (ch->mode[0] << 12) |  
863 - (ch->end_prog << 11) |  
864 - (ch->repeat << 9) |  
865 - (ch->auto_init << 8) |  
866 - (ch->enable << 7) |  
867 - (ch->priority << 6) |  
868 - (ch->fs << 5) | ch->sync;  
869 - break;  
870 -  
871 - case 0x04: /* SYS_DMA_CICR_CH0 */  
872 - *value = ch->interrupts;  
873 - break;  
874 -  
875 - case 0x06: /* SYS_DMA_CSR_CH0 */  
876 - *value = ch->status;  
877 - ch->status &= SYNC;  
878 - if (!ch->omap_3_1_compatible_disable && ch->sibling) {  
879 - *value |= (ch->sibling->status & 0x3f) << 6;  
880 - ch->sibling->status &= SYNC;  
881 - }  
882 - qemu_irq_lower(ch->irq);  
883 - break;  
884 -  
885 - case 0x08: /* SYS_DMA_CSSA_L_CH0 */  
886 - *value = ch->addr[0] & 0x0000ffff;  
887 - break;  
888 -  
889 - case 0x0a: /* SYS_DMA_CSSA_U_CH0 */  
890 - *value = ch->addr[0] >> 16;  
891 - break;  
892 -  
893 - case 0x0c: /* SYS_DMA_CDSA_L_CH0 */  
894 - *value = ch->addr[1] & 0x0000ffff;  
895 - break;  
896 -  
897 - case 0x0e: /* SYS_DMA_CDSA_U_CH0 */  
898 - *value = ch->addr[1] >> 16;  
899 - break;  
900 -  
901 - case 0x10: /* SYS_DMA_CEN_CH0 */  
902 - *value = ch->elements;  
903 - break;  
904 -  
905 - case 0x12: /* SYS_DMA_CFN_CH0 */  
906 - *value = ch->frames;  
907 - break;  
908 -  
909 - case 0x14: /* SYS_DMA_CFI_CH0 */  
910 - *value = ch->frame_index[0];  
911 - break;  
912 -  
913 - case 0x16: /* SYS_DMA_CEI_CH0 */  
914 - *value = ch->element_index[0];  
915 - break;  
916 -  
917 - case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */  
918 - if (ch->omap_3_1_compatible_disable)  
919 - *value = ch->active_set.src & 0xffff; /* CSAC */  
920 - else  
921 - *value = ch->cpc;  
922 - break;  
923 -  
924 - case 0x1a: /* DMA_CDAC */  
925 - *value = ch->active_set.dest & 0xffff; /* CDAC */  
926 - break;  
927 -  
928 - case 0x1c: /* DMA_CDEI */  
929 - *value = ch->element_index[1];  
930 - break;  
931 -  
932 - case 0x1e: /* DMA_CDFI */  
933 - *value = ch->frame_index[1];  
934 - break;  
935 -  
936 - case 0x20: /* DMA_COLOR_L */  
937 - *value = ch->color & 0xffff;  
938 - break;  
939 -  
940 - case 0x22: /* DMA_COLOR_U */  
941 - *value = ch->color >> 16;  
942 - break;  
943 -  
944 - case 0x24: /* DMA_CCR2 */  
945 - *value = (ch->bs << 2) |  
946 - (ch->transparent_copy << 1) |  
947 - ch->constant_fill;  
948 - break;  
949 -  
950 - case 0x28: /* DMA_CLNK_CTRL */  
951 - *value = (ch->link_enabled << 15) |  
952 - (ch->link_next_ch & 0xf);  
953 - break;  
954 -  
955 - case 0x2a: /* DMA_LCH_CTRL */  
956 - *value = (ch->interleave_disabled << 15) |  
957 - ch->type;  
958 - break;  
959 -  
960 - default:  
961 - return 1;  
962 - }  
963 - return 0;  
964 -}  
965 -  
966 -static int omap_dma_ch_reg_write(struct omap_dma_s *s,  
967 - struct omap_dma_channel_s *ch, int reg, uint16_t value)  
968 -{  
969 - switch (reg) {  
970 - case 0x00: /* SYS_DMA_CSDP_CH0 */  
971 - ch->burst[1] = (value & 0xc000) >> 14;  
972 - ch->pack[1] = (value & 0x2000) >> 13;  
973 - ch->port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);  
974 - ch->burst[0] = (value & 0x0180) >> 7;  
975 - ch->pack[0] = (value & 0x0040) >> 6;  
976 - ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);  
977 - ch->data_type = (1 << (value & 3));  
978 - if (ch->port[0] >= omap_dma_port_last)  
979 - printf("%s: invalid DMA port %i\n", __FUNCTION__,  
980 - ch->port[0]);  
981 - if (ch->port[1] >= omap_dma_port_last)  
982 - printf("%s: invalid DMA port %i\n", __FUNCTION__,  
983 - ch->port[1]);  
984 - if ((value & 3) == 3)  
985 - printf("%s: bad data_type for DMA channel\n", __FUNCTION__);  
986 - break;  
987 -  
988 - case 0x02: /* SYS_DMA_CCR_CH0 */  
989 - ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);  
990 - ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);  
991 - ch->end_prog = (value & 0x0800) >> 11;  
992 - if (s->model > omap_dma_3_1)  
993 - ch->omap_3_1_compatible_disable = (value >> 10) & 0x1;  
994 - ch->repeat = (value & 0x0200) >> 9;  
995 - ch->auto_init = (value & 0x0100) >> 8;  
996 - ch->priority = (value & 0x0040) >> 6;  
997 - ch->fs = (value & 0x0020) >> 5;  
998 - ch->sync = value & 0x001f;  
999 -  
1000 - if (value & 0x0080)  
1001 - omap_dma_enable_channel(s, ch);  
1002 - else  
1003 - omap_dma_disable_channel(s, ch);  
1004 -  
1005 - if (ch->end_prog)  
1006 - omap_dma_channel_end_prog(s, ch);  
1007 -  
1008 - break;  
1009 -  
1010 - case 0x04: /* SYS_DMA_CICR_CH0 */  
1011 - ch->interrupts = value;  
1012 - break;  
1013 -  
1014 - case 0x06: /* SYS_DMA_CSR_CH0 */  
1015 - OMAP_RO_REG((target_phys_addr_t) reg);  
1016 - break;  
1017 -  
1018 - case 0x08: /* SYS_DMA_CSSA_L_CH0 */  
1019 - ch->addr[0] &= 0xffff0000;  
1020 - ch->addr[0] |= value;  
1021 - break;  
1022 -  
1023 - case 0x0a: /* SYS_DMA_CSSA_U_CH0 */  
1024 - ch->addr[0] &= 0x0000ffff;  
1025 - ch->addr[0] |= (uint32_t) value << 16;  
1026 - break;  
1027 -  
1028 - case 0x0c: /* SYS_DMA_CDSA_L_CH0 */  
1029 - ch->addr[1] &= 0xffff0000;  
1030 - ch->addr[1] |= value;  
1031 - break;  
1032 -  
1033 - case 0x0e: /* SYS_DMA_CDSA_U_CH0 */  
1034 - ch->addr[1] &= 0x0000ffff;  
1035 - ch->addr[1] |= (uint32_t) value << 16;  
1036 - break;  
1037 -  
1038 - case 0x10: /* SYS_DMA_CEN_CH0 */  
1039 - ch->elements = value;  
1040 - break;  
1041 -  
1042 - case 0x12: /* SYS_DMA_CFN_CH0 */  
1043 - ch->frames = value;  
1044 - break;  
1045 -  
1046 - case 0x14: /* SYS_DMA_CFI_CH0 */  
1047 - ch->frame_index[0] = (int16_t) value;  
1048 - break;  
1049 -  
1050 - case 0x16: /* SYS_DMA_CEI_CH0 */  
1051 - ch->element_index[0] = (int16_t) value;  
1052 - break;  
1053 -  
1054 - case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */  
1055 - OMAP_RO_REG((target_phys_addr_t) reg);  
1056 - break;  
1057 -  
1058 - case 0x1c: /* DMA_CDEI */  
1059 - ch->element_index[1] = (int16_t) value;  
1060 - break;  
1061 -  
1062 - case 0x1e: /* DMA_CDFI */  
1063 - ch->frame_index[1] = (int16_t) value;  
1064 - break;  
1065 -  
1066 - case 0x20: /* DMA_COLOR_L */  
1067 - ch->color &= 0xffff0000;  
1068 - ch->color |= value;  
1069 - break;  
1070 -  
1071 - case 0x22: /* DMA_COLOR_U */  
1072 - ch->color &= 0xffff;  
1073 - ch->color |= value << 16;  
1074 - break;  
1075 -  
1076 - case 0x24: /* DMA_CCR2 */  
1077 - ch->bs = (value >> 2) & 0x1;  
1078 - ch->transparent_copy = (value >> 1) & 0x1;  
1079 - ch->constant_fill = value & 0x1;  
1080 - break;  
1081 -  
1082 - case 0x28: /* DMA_CLNK_CTRL */  
1083 - ch->link_enabled = (value >> 15) & 0x1;  
1084 - if (value & (1 << 14)) { /* Stop_Lnk */  
1085 - ch->link_enabled = 0;  
1086 - omap_dma_disable_channel(s, ch);  
1087 - }  
1088 - ch->link_next_ch = value & 0x1f;  
1089 - break;  
1090 -  
1091 - case 0x2a: /* DMA_LCH_CTRL */  
1092 - ch->interleave_disabled = (value >> 15) & 0x1;  
1093 - ch->type = value & 0xf;  
1094 - break;  
1095 -  
1096 - default:  
1097 - return 1;  
1098 - }  
1099 - return 0;  
1100 -}  
1101 -  
1102 -static int omap_dma_3_2_lcd_write(struct omap_dma_lcd_channel_s *s, int offset,  
1103 - uint16_t value)  
1104 -{  
1105 - switch (offset) {  
1106 - case 0xbc0: /* DMA_LCD_CSDP */  
1107 - s->brust_f2 = (value >> 14) & 0x3;  
1108 - s->pack_f2 = (value >> 13) & 0x1;  
1109 - s->data_type_f2 = (1 << ((value >> 11) & 0x3));  
1110 - s->brust_f1 = (value >> 7) & 0x3;  
1111 - s->pack_f1 = (value >> 6) & 0x1;  
1112 - s->data_type_f1 = (1 << ((value >> 0) & 0x3));  
1113 - break;  
1114 -  
1115 - case 0xbc2: /* DMA_LCD_CCR */  
1116 - s->mode_f2 = (value >> 14) & 0x3;  
1117 - s->mode_f1 = (value >> 12) & 0x3;  
1118 - s->end_prog = (value >> 11) & 0x1;  
1119 - s->omap_3_1_compatible_disable = (value >> 10) & 0x1;  
1120 - s->repeat = (value >> 9) & 0x1;  
1121 - s->auto_init = (value >> 8) & 0x1;  
1122 - s->running = (value >> 7) & 0x1;  
1123 - s->priority = (value >> 6) & 0x1;  
1124 - s->bs = (value >> 4) & 0x1;  
1125 - break;  
1126 -  
1127 - case 0xbc4: /* DMA_LCD_CTRL */  
1128 - s->dst = (value >> 8) & 0x1;  
1129 - s->src = ((value >> 6) & 0x3) << 1;  
1130 - s->condition = 0;  
1131 - /* Assume no bus errors and thus no BUS_ERROR irq bits. */  
1132 - s->interrupts = (value >> 1) & 1;  
1133 - s->dual = value & 1;  
1134 - break;  
1135 -  
1136 - case 0xbc8: /* TOP_B1_L */  
1137 - s->src_f1_top &= 0xffff0000;  
1138 - s->src_f1_top |= 0x0000ffff & value;  
1139 - break;  
1140 -  
1141 - case 0xbca: /* TOP_B1_U */  
1142 - s->src_f1_top &= 0x0000ffff;  
1143 - s->src_f1_top |= value << 16;  
1144 - break;  
1145 -  
1146 - case 0xbcc: /* BOT_B1_L */  
1147 - s->src_f1_bottom &= 0xffff0000;  
1148 - s->src_f1_bottom |= 0x0000ffff & value;  
1149 - break;  
1150 -  
1151 - case 0xbce: /* BOT_B1_U */  
1152 - s->src_f1_bottom &= 0x0000ffff;  
1153 - s->src_f1_bottom |= (uint32_t) value << 16;  
1154 - break;  
1155 -  
1156 - case 0xbd0: /* TOP_B2_L */  
1157 - s->src_f2_top &= 0xffff0000;  
1158 - s->src_f2_top |= 0x0000ffff & value;  
1159 - break;  
1160 -  
1161 - case 0xbd2: /* TOP_B2_U */  
1162 - s->src_f2_top &= 0x0000ffff;  
1163 - s->src_f2_top |= (uint32_t) value << 16;  
1164 - break;  
1165 -  
1166 - case 0xbd4: /* BOT_B2_L */  
1167 - s->src_f2_bottom &= 0xffff0000;  
1168 - s->src_f2_bottom |= 0x0000ffff & value;  
1169 - break;  
1170 -  
1171 - case 0xbd6: /* BOT_B2_U */  
1172 - s->src_f2_bottom &= 0x0000ffff;  
1173 - s->src_f2_bottom |= (uint32_t) value << 16;  
1174 - break;  
1175 -  
1176 - case 0xbd8: /* DMA_LCD_SRC_EI_B1 */  
1177 - s->element_index_f1 = value;  
1178 - break;  
1179 -  
1180 - case 0xbda: /* DMA_LCD_SRC_FI_B1_L */  
1181 - s->frame_index_f1 &= 0xffff0000;  
1182 - s->frame_index_f1 |= 0x0000ffff & value;  
1183 - break;  
1184 -  
1185 - case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */  
1186 - s->frame_index_f1 &= 0x0000ffff;  
1187 - s->frame_index_f1 |= (uint32_t) value << 16;  
1188 - break;  
1189 -  
1190 - case 0xbdc: /* DMA_LCD_SRC_EI_B2 */  
1191 - s->element_index_f2 = value;  
1192 - break;  
1193 -  
1194 - case 0xbde: /* DMA_LCD_SRC_FI_B2_L */  
1195 - s->frame_index_f2 &= 0xffff0000;  
1196 - s->frame_index_f2 |= 0x0000ffff & value;  
1197 - break;  
1198 -  
1199 - case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */  
1200 - s->frame_index_f2 &= 0x0000ffff;  
1201 - s->frame_index_f2 |= (uint32_t) value << 16;  
1202 - break;  
1203 -  
1204 - case 0xbe0: /* DMA_LCD_SRC_EN_B1 */  
1205 - s->elements_f1 = value;  
1206 - break;  
1207 -  
1208 - case 0xbe4: /* DMA_LCD_SRC_FN_B1 */  
1209 - s->frames_f1 = value;  
1210 - break;  
1211 -  
1212 - case 0xbe2: /* DMA_LCD_SRC_EN_B2 */  
1213 - s->elements_f2 = value;  
1214 - break;  
1215 -  
1216 - case 0xbe6: /* DMA_LCD_SRC_FN_B2 */  
1217 - s->frames_f2 = value;  
1218 - break;  
1219 -  
1220 - case 0xbea: /* DMA_LCD_LCH_CTRL */  
1221 - s->lch_type = value & 0xf;  
1222 - break;  
1223 -  
1224 - default:  
1225 - return 1;  
1226 - }  
1227 - return 0;  
1228 -}  
1229 -  
1230 -static int omap_dma_3_2_lcd_read(struct omap_dma_lcd_channel_s *s, int offset,  
1231 - uint16_t *ret)  
1232 -{  
1233 - switch (offset) {  
1234 - case 0xbc0: /* DMA_LCD_CSDP */  
1235 - *ret = (s->brust_f2 << 14) |  
1236 - (s->pack_f2 << 13) |  
1237 - ((s->data_type_f2 >> 1) << 11) |  
1238 - (s->brust_f1 << 7) |  
1239 - (s->pack_f1 << 6) |  
1240 - ((s->data_type_f1 >> 1) << 0);  
1241 - break;  
1242 -  
1243 - case 0xbc2: /* DMA_LCD_CCR */  
1244 - *ret = (s->mode_f2 << 14) |  
1245 - (s->mode_f1 << 12) |  
1246 - (s->end_prog << 11) |  
1247 - (s->omap_3_1_compatible_disable << 10) |  
1248 - (s->repeat << 9) |  
1249 - (s->auto_init << 8) |  
1250 - (s->running << 7) |  
1251 - (s->priority << 6) |  
1252 - (s->bs << 4);  
1253 - break;  
1254 -  
1255 - case 0xbc4: /* DMA_LCD_CTRL */  
1256 - qemu_irq_lower(s->irq);  
1257 - *ret = (s->dst << 8) |  
1258 - ((s->src & 0x6) << 5) |  
1259 - (s->condition << 3) |  
1260 - (s->interrupts << 1) |  
1261 - s->dual;  
1262 - break;  
1263 -  
1264 - case 0xbc8: /* TOP_B1_L */  
1265 - *ret = s->src_f1_top & 0xffff;  
1266 - break;  
1267 -  
1268 - case 0xbca: /* TOP_B1_U */  
1269 - *ret = s->src_f1_top >> 16;  
1270 - break;  
1271 -  
1272 - case 0xbcc: /* BOT_B1_L */  
1273 - *ret = s->src_f1_bottom & 0xffff;  
1274 - break;  
1275 -  
1276 - case 0xbce: /* BOT_B1_U */  
1277 - *ret = s->src_f1_bottom >> 16;  
1278 - break;  
1279 -  
1280 - case 0xbd0: /* TOP_B2_L */  
1281 - *ret = s->src_f2_top & 0xffff;  
1282 - break;  
1283 -  
1284 - case 0xbd2: /* TOP_B2_U */  
1285 - *ret = s->src_f2_top >> 16;  
1286 - break;  
1287 -  
1288 - case 0xbd4: /* BOT_B2_L */  
1289 - *ret = s->src_f2_bottom & 0xffff;  
1290 - break;  
1291 -  
1292 - case 0xbd6: /* BOT_B2_U */  
1293 - *ret = s->src_f2_bottom >> 16;  
1294 - break;  
1295 -  
1296 - case 0xbd8: /* DMA_LCD_SRC_EI_B1 */  
1297 - *ret = s->element_index_f1;  
1298 - break;  
1299 -  
1300 - case 0xbda: /* DMA_LCD_SRC_FI_B1_L */  
1301 - *ret = s->frame_index_f1 & 0xffff;  
1302 - break;  
1303 -  
1304 - case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */  
1305 - *ret = s->frame_index_f1 >> 16;  
1306 - break;  
1307 -  
1308 - case 0xbdc: /* DMA_LCD_SRC_EI_B2 */  
1309 - *ret = s->element_index_f2;  
1310 - break;  
1311 -  
1312 - case 0xbde: /* DMA_LCD_SRC_FI_B2_L */  
1313 - *ret = s->frame_index_f2 & 0xffff;  
1314 - break;  
1315 -  
1316 - case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */  
1317 - *ret = s->frame_index_f2 >> 16;  
1318 - break;  
1319 -  
1320 - case 0xbe0: /* DMA_LCD_SRC_EN_B1 */  
1321 - *ret = s->elements_f1;  
1322 - break;  
1323 -  
1324 - case 0xbe4: /* DMA_LCD_SRC_FN_B1 */  
1325 - *ret = s->frames_f1;  
1326 - break;  
1327 -  
1328 - case 0xbe2: /* DMA_LCD_SRC_EN_B2 */  
1329 - *ret = s->elements_f2;  
1330 - break;  
1331 -  
1332 - case 0xbe6: /* DMA_LCD_SRC_FN_B2 */  
1333 - *ret = s->frames_f2;  
1334 - break;  
1335 -  
1336 - case 0xbea: /* DMA_LCD_LCH_CTRL */  
1337 - *ret = s->lch_type;  
1338 - break;  
1339 -  
1340 - default:  
1341 - return 1;  
1342 - }  
1343 - return 0;  
1344 -}  
1345 -  
1346 -static int omap_dma_3_1_lcd_write(struct omap_dma_lcd_channel_s *s, int offset,  
1347 - uint16_t value)  
1348 -{  
1349 - switch (offset) {  
1350 - case 0x300: /* SYS_DMA_LCD_CTRL */  
1351 - s->src = (value & 0x40) ? imif : emiff;  
1352 - s->condition = 0;  
1353 - /* Assume no bus errors and thus no BUS_ERROR irq bits. */  
1354 - s->interrupts = (value >> 1) & 1;  
1355 - s->dual = value & 1;  
1356 - break;  
1357 -  
1358 - case 0x302: /* SYS_DMA_LCD_TOP_F1_L */  
1359 - s->src_f1_top &= 0xffff0000;  
1360 - s->src_f1_top |= 0x0000ffff & value;  
1361 - break;  
1362 -  
1363 - case 0x304: /* SYS_DMA_LCD_TOP_F1_U */  
1364 - s->src_f1_top &= 0x0000ffff;  
1365 - s->src_f1_top |= value << 16;  
1366 - break;  
1367 -  
1368 - case 0x306: /* SYS_DMA_LCD_BOT_F1_L */  
1369 - s->src_f1_bottom &= 0xffff0000;  
1370 - s->src_f1_bottom |= 0x0000ffff & value;  
1371 - break;  
1372 -  
1373 - case 0x308: /* SYS_DMA_LCD_BOT_F1_U */  
1374 - s->src_f1_bottom &= 0x0000ffff;  
1375 - s->src_f1_bottom |= value << 16;  
1376 - break;  
1377 -  
1378 - case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */  
1379 - s->src_f2_top &= 0xffff0000;  
1380 - s->src_f2_top |= 0x0000ffff & value;  
1381 - break;  
1382 -  
1383 - case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */  
1384 - s->src_f2_top &= 0x0000ffff;  
1385 - s->src_f2_top |= value << 16;  
1386 - break;  
1387 -  
1388 - case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */  
1389 - s->src_f2_bottom &= 0xffff0000;  
1390 - s->src_f2_bottom |= 0x0000ffff & value;  
1391 - break;  
1392 -  
1393 - case 0x310: /* SYS_DMA_LCD_BOT_F2_U */  
1394 - s->src_f2_bottom &= 0x0000ffff;  
1395 - s->src_f2_bottom |= value << 16;  
1396 - break;  
1397 -  
1398 - default:  
1399 - return 1;  
1400 - }  
1401 - return 0;  
1402 -}  
1403 -  
1404 -static int omap_dma_3_1_lcd_read(struct omap_dma_lcd_channel_s *s, int offset,  
1405 - uint16_t *ret)  
1406 -{  
1407 - int i;  
1408 -  
1409 - switch (offset) {  
1410 - case 0x300: /* SYS_DMA_LCD_CTRL */  
1411 - i = s->condition;  
1412 - s->condition = 0;  
1413 - qemu_irq_lower(s->irq);  
1414 - *ret = ((s->src == imif) << 6) | (i << 3) |  
1415 - (s->interrupts << 1) | s->dual;  
1416 - break;  
1417 -  
1418 - case 0x302: /* SYS_DMA_LCD_TOP_F1_L */  
1419 - *ret = s->src_f1_top & 0xffff;  
1420 - break;  
1421 -  
1422 - case 0x304: /* SYS_DMA_LCD_TOP_F1_U */  
1423 - *ret = s->src_f1_top >> 16;  
1424 - break;  
1425 -  
1426 - case 0x306: /* SYS_DMA_LCD_BOT_F1_L */  
1427 - *ret = s->src_f1_bottom & 0xffff;  
1428 - break;  
1429 -  
1430 - case 0x308: /* SYS_DMA_LCD_BOT_F1_U */  
1431 - *ret = s->src_f1_bottom >> 16;  
1432 - break;  
1433 -  
1434 - case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */  
1435 - *ret = s->src_f2_top & 0xffff;  
1436 - break;  
1437 -  
1438 - case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */  
1439 - *ret = s->src_f2_top >> 16;  
1440 - break;  
1441 -  
1442 - case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */  
1443 - *ret = s->src_f2_bottom & 0xffff;  
1444 - break;  
1445 -  
1446 - case 0x310: /* SYS_DMA_LCD_BOT_F2_U */  
1447 - *ret = s->src_f2_bottom >> 16;  
1448 - break;  
1449 -  
1450 - default:  
1451 - return 1;  
1452 - }  
1453 - return 0;  
1454 -}  
1455 -  
1456 -static int omap_dma_sys_write(struct omap_dma_s *s, int offset, uint16_t value)  
1457 -{  
1458 - switch (offset) {  
1459 - case 0x400: /* SYS_DMA_GCR */  
1460 - s->gcr = value;  
1461 - break;  
1462 -  
1463 - case 0x404: /* DMA_GSCR */  
1464 - if (value & 0x8)  
1465 - omap_dma_disable_3_1_mapping(s);  
1466 - else  
1467 - omap_dma_enable_3_1_mapping(s);  
1468 - break;  
1469 -  
1470 - case 0x408: /* DMA_GRST */  
1471 - if (value & 0x1)  
1472 - omap_dma_reset(s);  
1473 - break;  
1474 -  
1475 - default:  
1476 - return 1;  
1477 - }  
1478 - return 0;  
1479 -}  
1480 -  
1481 -static int omap_dma_sys_read(struct omap_dma_s *s, int offset,  
1482 - uint16_t *ret)  
1483 -{  
1484 - switch (offset) {  
1485 - case 0x400: /* SYS_DMA_GCR */  
1486 - *ret = s->gcr;  
1487 - break;  
1488 -  
1489 - case 0x404: /* DMA_GSCR */  
1490 - *ret = s->omap_3_1_mapping_disabled << 3;  
1491 - break;  
1492 -  
1493 - case 0x408: /* DMA_GRST */  
1494 - *ret = 0;  
1495 - break;  
1496 -  
1497 - case 0x442: /* DMA_HW_ID */  
1498 - case 0x444: /* DMA_PCh2_ID */  
1499 - case 0x446: /* DMA_PCh0_ID */  
1500 - case 0x448: /* DMA_PCh1_ID */  
1501 - case 0x44a: /* DMA_PChG_ID */  
1502 - case 0x44c: /* DMA_PChD_ID */  
1503 - *ret = 1;  
1504 - break;  
1505 -  
1506 - case 0x44e: /* DMA_CAPS_0_U */  
1507 - *ret = (1 << 3) | /* Constant Fill Capacity */  
1508 - (1 << 2); /* Transparent BLT Capacity */  
1509 - break;  
1510 -  
1511 - case 0x450: /* DMA_CAPS_0_L */  
1512 - case 0x452: /* DMA_CAPS_1_U */  
1513 - *ret = 0;  
1514 - break;  
1515 -  
1516 - case 0x454: /* DMA_CAPS_1_L */  
1517 - *ret = (1 << 1); /* 1-bit palletized capability */  
1518 - break;  
1519 -  
1520 - case 0x456: /* DMA_CAPS_2 */  
1521 - *ret = (1 << 8) | /* SSDIC */  
1522 - (1 << 7) | /* DDIAC */  
1523 - (1 << 6) | /* DSIAC */  
1524 - (1 << 5) | /* DPIAC */  
1525 - (1 << 4) | /* DCAC */  
1526 - (1 << 3) | /* SDIAC */  
1527 - (1 << 2) | /* SSIAC */  
1528 - (1 << 1) | /* SPIAC */  
1529 - 1; /* SCAC */  
1530 - break;  
1531 -  
1532 - case 0x458: /* DMA_CAPS_3 */  
1533 - *ret = (1 << 5) | /* CCC */  
1534 - (1 << 4) | /* IC */  
1535 - (1 << 3) | /* ARC */  
1536 - (1 << 2) | /* AEC */  
1537 - (1 << 1) | /* FSC */  
1538 - 1; /* ESC */  
1539 - break;  
1540 -  
1541 - case 0x45a: /* DMA_CAPS_4 */  
1542 - *ret = (1 << 6) | /* SSC */  
1543 - (1 << 5) | /* BIC */  
1544 - (1 << 4) | /* LFIC */  
1545 - (1 << 3) | /* FIC */  
1546 - (1 << 2) | /* HFIC */  
1547 - (1 << 1) | /* EDIC */  
1548 - 1; /* TOIC */  
1549 - break;  
1550 -  
1551 - case 0x460: /* DMA_PCh2_SR */  
1552 - case 0x480: /* DMA_PCh0_SR */  
1553 - case 0x482: /* DMA_PCh1_SR */  
1554 - case 0x4c0: /* DMA_PChD_SR_0 */  
1555 - printf("%s: Physical Channel Status Registers not implemented.\n",  
1556 - __FUNCTION__);  
1557 - *ret = 0xff;  
1558 - break;  
1559 -  
1560 - default:  
1561 - return 1;  
1562 - }  
1563 - return 0;  
1564 -}  
1565 -  
1566 -static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)  
1567 -{  
1568 - struct omap_dma_s *s = (struct omap_dma_s *) opaque;  
1569 - int reg, ch, offset = addr - s->base;  
1570 - uint16_t ret;  
1571 -  
1572 - switch (offset) {  
1573 - case 0x300 ... 0x3fe:  
1574 - if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {  
1575 - if (omap_dma_3_1_lcd_read(&s->lcd_ch, offset, &ret))  
1576 - break;  
1577 - return ret;  
1578 - }  
1579 - /* Fall through. */  
1580 - case 0x000 ... 0x2fe:  
1581 - reg = offset & 0x3f;  
1582 - ch = (offset >> 6) & 0x0f;  
1583 - if (omap_dma_ch_reg_read(s, &s->ch[ch], reg, &ret))  
1584 - break;  
1585 - return ret;  
1586 -  
1587 - case 0x404 ... 0x4fe:  
1588 - if (s->model == omap_dma_3_1)  
1589 - break;  
1590 - /* Fall through. */  
1591 - case 0x400:  
1592 - if (omap_dma_sys_read(s, offset, &ret))  
1593 - break;  
1594 - return ret;  
1595 -  
1596 - case 0xb00 ... 0xbfe:  
1597 - if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {  
1598 - if (omap_dma_3_2_lcd_read(&s->lcd_ch, offset, &ret))  
1599 - break;  
1600 - return ret;  
1601 - }  
1602 - break;  
1603 - }  
1604 -  
1605 - OMAP_BAD_REG(addr);  
1606 - return 0;  
1607 -}  
1608 -  
1609 -static void omap_dma_write(void *opaque, target_phys_addr_t addr,  
1610 - uint32_t value)  
1611 -{  
1612 - struct omap_dma_s *s = (struct omap_dma_s *) opaque;  
1613 - int reg, ch, offset = addr - s->base;  
1614 -  
1615 - switch (offset) {  
1616 - case 0x300 ... 0x3fe:  
1617 - if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {  
1618 - if (omap_dma_3_1_lcd_write(&s->lcd_ch, offset, value))  
1619 - break;  
1620 - return;  
1621 - }  
1622 - /* Fall through. */  
1623 - case 0x000 ... 0x2fe:  
1624 - reg = offset & 0x3f;  
1625 - ch = (offset >> 6) & 0x0f;  
1626 - if (omap_dma_ch_reg_write(s, &s->ch[ch], reg, value))  
1627 - break;  
1628 - return;  
1629 -  
1630 - case 0x404 ... 0x4fe:  
1631 - if (s->model == omap_dma_3_1)  
1632 - break;  
1633 - case 0x400:  
1634 - /* Fall through. */  
1635 - if (omap_dma_sys_write(s, offset, value))  
1636 - break;  
1637 - return;  
1638 -  
1639 - case 0xb00 ... 0xbfe:  
1640 - if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {  
1641 - if (omap_dma_3_2_lcd_write(&s->lcd_ch, offset, value))  
1642 - break;  
1643 - return;  
1644 - }  
1645 - break;  
1646 - }  
1647 -  
1648 - OMAP_BAD_REG(addr);  
1649 -}  
1650 -  
1651 -static CPUReadMemoryFunc *omap_dma_readfn[] = {  
1652 - omap_badwidth_read16,  
1653 - omap_dma_read,  
1654 - omap_badwidth_read16,  
1655 -};  
1656 -  
1657 -static CPUWriteMemoryFunc *omap_dma_writefn[] = {  
1658 - omap_badwidth_write16,  
1659 - omap_dma_write,  
1660 - omap_badwidth_write16,  
1661 -};  
1662 -  
1663 -static void omap_dma_request(void *opaque, int drq, int req)  
1664 -{  
1665 - struct omap_dma_s *s = (struct omap_dma_s *) opaque;  
1666 - /* The request pins are level triggered. */  
1667 - if (req) {  
1668 - if (~s->drq & (1 << drq)) {  
1669 - s->drq |= 1 << drq;  
1670 - omap_dma_process_request(s, drq);  
1671 - }  
1672 - } else  
1673 - s->drq &= ~(1 << drq);  
1674 -}  
1675 -  
1676 -static void omap_dma_clk_update(void *opaque, int line, int on)  
1677 -{  
1678 - struct omap_dma_s *s = (struct omap_dma_s *) opaque;  
1679 -  
1680 - if (on) {  
1681 - /* TODO: make a clever calculation */  
1682 - s->delay = ticks_per_sec >> 8;  
1683 - if (s->run_count)  
1684 - qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);  
1685 - } else {  
1686 - s->delay = 0;  
1687 - qemu_del_timer(s->tm);  
1688 - }  
1689 -}  
1690 -  
1691 -struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,  
1692 - qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,  
1693 - enum omap_dma_model model)  
1694 -{  
1695 - int iomemtype, num_irqs, memsize, i;  
1696 - struct omap_dma_s *s = (struct omap_dma_s *)  
1697 - qemu_mallocz(sizeof(struct omap_dma_s));  
1698 -  
1699 - if (model == omap_dma_3_1) {  
1700 - num_irqs = 6;  
1701 - memsize = 0x800;  
1702 - } else {  
1703 - num_irqs = 16;  
1704 - memsize = 0xc00;  
1705 - }  
1706 - s->base = base;  
1707 - s->model = model;  
1708 - s->mpu = mpu;  
1709 - s->clk = clk;  
1710 - s->lcd_ch.irq = lcd_irq;  
1711 - s->lcd_ch.mpu = mpu;  
1712 - while (num_irqs --)  
1713 - s->ch[num_irqs].irq = irqs[num_irqs];  
1714 - for (i = 0; i < 3; i ++) {  
1715 - s->ch[i].sibling = &s->ch[i + 6];  
1716 - s->ch[i + 6].sibling = &s->ch[i];  
1717 - }  
1718 - s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);  
1719 - omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);  
1720 - mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);  
1721 - omap_dma_reset(s);  
1722 - omap_dma_clk_update(s, 0, 1);  
1723 -  
1724 - iomemtype = cpu_register_io_memory(0, omap_dma_readfn,  
1725 - omap_dma_writefn, s);  
1726 - cpu_register_physical_memory(s->base, memsize, iomemtype);  
1727 -  
1728 - return s;  
1729 -}  
1730 -  
1731 -/* DMA ports */  
1732 -static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,  
1733 - target_phys_addr_t addr)  
1734 -{  
1735 - return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;  
1736 -}  
1737 -  
1738 -static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,  
1739 - target_phys_addr_t addr)  
1740 -{  
1741 - return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;  
1742 -}  
1743 -  
1744 -static int omap_validate_imif_addr(struct omap_mpu_state_s *s,  
1745 - target_phys_addr_t addr)  
1746 -{  
1747 - return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;  
1748 -}  
1749 -  
1750 -static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,  
1751 - target_phys_addr_t addr)  
1752 -{  
1753 - return addr >= 0xfffb0000 && addr < 0xffff0000;  
1754 -}  
1755 -  
1756 -static int omap_validate_local_addr(struct omap_mpu_state_s *s,  
1757 - target_phys_addr_t addr)  
1758 -{  
1759 - return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;  
1760 -}  
1761 -  
1762 -static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,  
1763 - target_phys_addr_t addr)  
1764 -{  
1765 - return addr >= 0xe1010000 && addr < 0xe1020004;  
1766 -}  
1767 -  
1768 /* MPU OS timers */ 404 /* MPU OS timers */
1769 struct omap_mpu_timer_s { 405 struct omap_mpu_timer_s {
1770 qemu_irq irq; 406 qemu_irq irq;
@@ -5577,11 +4213,6 @@ static void omap_mpu_wakeup(void *opaque, int irq, int req) @@ -5577,11 +4213,6 @@ static void omap_mpu_wakeup(void *opaque, int irq, int req)
5577 cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB); 4213 cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
5578 } 4214 }
5579 4215
5580 -struct dma_irq_map {  
5581 - int ih;  
5582 - int intr;  
5583 -};  
5584 -  
5585 static const struct dma_irq_map omap_dma_irq_map[] = { 4216 static const struct dma_irq_map omap_dma_irq_map[] = {
5586 { 0, OMAP_INT_DMA_CH0_6 }, 4217 { 0, OMAP_INT_DMA_CH0_6 },
5587 { 0, OMAP_INT_DMA_CH1_7 }, 4218 { 0, OMAP_INT_DMA_CH1_7 },
@@ -5601,6 +4232,43 @@ static const struct dma_irq_map omap_dma_irq_map[] = { @@ -5601,6 +4232,43 @@ static const struct dma_irq_map omap_dma_irq_map[] = {
5601 { 1, OMAP_INT_1610_DMA_CH15 } 4232 { 1, OMAP_INT_1610_DMA_CH15 }
5602 }; 4233 };
5603 4234
  4235 +/* DMA ports for OMAP1 */
  4236 +static int omap_validate_emiff_addr(struct omap_mpu_state_s *s,
  4237 + target_phys_addr_t addr)
  4238 +{
  4239 + return addr >= OMAP_EMIFF_BASE && addr < OMAP_EMIFF_BASE + s->sdram_size;
  4240 +}
  4241 +
  4242 +static int omap_validate_emifs_addr(struct omap_mpu_state_s *s,
  4243 + target_phys_addr_t addr)
  4244 +{
  4245 + return addr >= OMAP_EMIFS_BASE && addr < OMAP_EMIFF_BASE;
  4246 +}
  4247 +
  4248 +static int omap_validate_imif_addr(struct omap_mpu_state_s *s,
  4249 + target_phys_addr_t addr)
  4250 +{
  4251 + return addr >= OMAP_IMIF_BASE && addr < OMAP_IMIF_BASE + s->sram_size;
  4252 +}
  4253 +
  4254 +static int omap_validate_tipb_addr(struct omap_mpu_state_s *s,
  4255 + target_phys_addr_t addr)
  4256 +{
  4257 + return addr >= 0xfffb0000 && addr < 0xffff0000;
  4258 +}
  4259 +
  4260 +static int omap_validate_local_addr(struct omap_mpu_state_s *s,
  4261 + target_phys_addr_t addr)
  4262 +{
  4263 + return addr >= OMAP_LOCALBUS_BASE && addr < OMAP_LOCALBUS_BASE + 0x1000000;
  4264 +}
  4265 +
  4266 +static int omap_validate_tipb_mpui_addr(struct omap_mpu_state_s *s,
  4267 + target_phys_addr_t addr)
  4268 +{
  4269 + return addr >= 0xe1010000 && addr < 0xe1020004;
  4270 +}
  4271 +
5604 struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, 4272 struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
5605 DisplayState *ds, const char *core) 4273 DisplayState *ds, const char *core)
5606 { 4274 {
@@ -5679,7 +4347,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size, @@ -5679,7 +4347,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
5679 omap_findclk(s, "clk32-kHz")); 4347 omap_findclk(s, "clk32-kHz"));
5680 4348
5681 s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL], 4349 s->lcd = omap_lcdc_init(0xfffec000, s->irq[0][OMAP_INT_LCD_CTRL],
5682 - &s->dma->lcd_ch, ds, imif_base, emiff_base, 4350 + omap_dma_get_lcdch(s->dma), ds, imif_base, emiff_base,
5683 omap_findclk(s, "lcd_ck")); 4351 omap_findclk(s, "lcd_ck"));
5684 4352
5685 omap_ulpd_pm_init(0xfffe0800, s); 4353 omap_ulpd_pm_init(0xfffe0800, s);
hw/omap1_clk.c renamed to hw/omap_clk.c
hw/omap_dma.c 0 โ†’ 100644
  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
  18 + * along with this program; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 + * MA 02111-1307 USA
  21 + */
  22 +#include "qemu-common.h"
  23 +#include "qemu-timer.h"
  24 +#include "omap.h"
  25 +#include "irq.h"
  26 +
  27 +struct omap_dma_channel_s {
  28 + /* transfer data */
  29 + int burst[2];
  30 + int pack[2];
  31 + enum omap_dma_port port[2];
  32 + target_phys_addr_t addr[2];
  33 + omap_dma_addressing_t mode[2];
  34 + uint16_t elements;
  35 + uint16_t frames;
  36 + int16_t frame_index[2];
  37 + int16_t element_index[2];
  38 + int data_type;
  39 +
  40 + /* transfer type */
  41 + int transparent_copy;
  42 + int constant_fill;
  43 + uint32_t color;
  44 +
  45 + /* auto init and linked channel data */
  46 + int end_prog;
  47 + int repeat;
  48 + int auto_init;
  49 + int link_enabled;
  50 + int link_next_ch;
  51 +
  52 + /* interruption data */
  53 + int interrupts;
  54 + int status;
  55 +
  56 + /* state data */
  57 + int active;
  58 + int enable;
  59 + int sync;
  60 + int pending_request;
  61 + int waiting_end_prog;
  62 + uint16_t cpc;
  63 +
  64 + /* sync type */
  65 + int fs;
  66 + int bs;
  67 +
  68 + /* compatibility */
  69 + int omap_3_1_compatible_disable;
  70 +
  71 + qemu_irq irq;
  72 + struct omap_dma_channel_s *sibling;
  73 +
  74 + struct omap_dma_reg_set_s {
  75 + target_phys_addr_t src, dest;
  76 + int frame;
  77 + int element;
  78 + int frame_delta[2];
  79 + int elem_delta[2];
  80 + int frames;
  81 + int elements;
  82 + } active_set;
  83 +
  84 + /* unused parameters */
  85 + int priority;
  86 + int interleave_disabled;
  87 + int type;
  88 +};
  89 +
  90 +struct omap_dma_s {
  91 + QEMUTimer *tm;
  92 + struct omap_mpu_state_s *mpu;
  93 + target_phys_addr_t base;
  94 + omap_clk clk;
  95 + int64_t delay;
  96 + uint32_t drq;
  97 + enum omap_dma_model model;
  98 + int omap_3_1_mapping_disabled;
  99 +
  100 + uint16_t gcr;
  101 + int run_count;
  102 +
  103 + int chans;
  104 + struct omap_dma_channel_s ch[16];
  105 + struct omap_dma_lcd_channel_s lcd_ch;
  106 +};
  107 +
  108 +/* Interrupts */
  109 +#define TIMEOUT_INTR (1 << 0)
  110 +#define EVENT_DROP_INTR (1 << 1)
  111 +#define HALF_FRAME_INTR (1 << 2)
  112 +#define END_FRAME_INTR (1 << 3)
  113 +#define LAST_FRAME_INTR (1 << 4)
  114 +#define END_BLOCK_INTR (1 << 5)
  115 +#define SYNC (1 << 6)
  116 +
  117 +static void omap_dma_interrupts_update(struct omap_dma_s *s)
  118 +{
  119 + struct omap_dma_channel_s *ch = s->ch;
  120 + int i;
  121 +
  122 + if (s->omap_3_1_mapping_disabled) {
  123 + for (i = 0; i < s->chans; i ++, ch ++)
  124 + if (ch->status)
  125 + qemu_irq_raise(ch->irq);
  126 + } else {
  127 + /* First three interrupts are shared between two channels each. */
  128 + for (i = 0; i < 6; i ++, ch ++) {
  129 + if (ch->status || (ch->sibling && ch->sibling->status))
  130 + qemu_irq_raise(ch->irq);
  131 + }
  132 + }
  133 +}
  134 +
  135 +static void omap_dma_channel_load(struct omap_dma_s *s,
  136 + struct omap_dma_channel_s *ch)
  137 +{
  138 + struct omap_dma_reg_set_s *a = &ch->active_set;
  139 + int i;
  140 + int omap_3_1 = !ch->omap_3_1_compatible_disable;
  141 +
  142 + /*
  143 + * TODO: verify address ranges and alignment
  144 + * TODO: port endianness
  145 + */
  146 +
  147 + a->src = ch->addr[0];
  148 + a->dest = ch->addr[1];
  149 + a->frames = ch->frames;
  150 + a->elements = ch->elements;
  151 + a->frame = 0;
  152 + a->element = 0;
  153 +
  154 + if (unlikely(!ch->elements || !ch->frames)) {
  155 + printf("%s: bad DMA request\n", __FUNCTION__);
  156 + return;
  157 + }
  158 +
  159 + for (i = 0; i < 2; i ++)
  160 + switch (ch->mode[i]) {
  161 + case constant:
  162 + a->elem_delta[i] = 0;
  163 + a->frame_delta[i] = 0;
  164 + break;
  165 + case post_incremented:
  166 + a->elem_delta[i] = ch->data_type;
  167 + a->frame_delta[i] = 0;
  168 + break;
  169 + case single_index:
  170 + a->elem_delta[i] = ch->data_type +
  171 + ch->element_index[omap_3_1 ? 0 : i] - 1;
  172 + a->frame_delta[i] = 0;
  173 + break;
  174 + case double_index:
  175 + a->elem_delta[i] = ch->data_type +
  176 + ch->element_index[omap_3_1 ? 0 : i] - 1;
  177 + a->frame_delta[i] = ch->frame_index[omap_3_1 ? 0 : i] -
  178 + ch->element_index[omap_3_1 ? 0 : i];
  179 + break;
  180 + default:
  181 + break;
  182 + }
  183 +}
  184 +
  185 +static void omap_dma_activate_channel(struct omap_dma_s *s,
  186 + struct omap_dma_channel_s *ch)
  187 +{
  188 + if (!ch->active) {
  189 + ch->active = 1;
  190 + if (ch->sync)
  191 + ch->status |= SYNC;
  192 + s->run_count ++;
  193 + }
  194 +
  195 + if (s->delay && !qemu_timer_pending(s->tm))
  196 + qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
  197 +}
  198 +
  199 +static void omap_dma_deactivate_channel(struct omap_dma_s *s,
  200 + struct omap_dma_channel_s *ch)
  201 +{
  202 + /* Update cpc */
  203 + ch->cpc = ch->active_set.dest & 0xffff;
  204 +
  205 + if (ch->pending_request && !ch->waiting_end_prog) {
  206 + /* Don't deactivate the channel */
  207 + ch->pending_request = 0;
  208 + if (ch->enable)
  209 + return;
  210 + }
  211 +
  212 + /* Don't deactive the channel if it is synchronized and the DMA request is
  213 + active */
  214 + if (ch->sync && (s->drq & (1 << ch->sync)) && ch->enable)
  215 + return;
  216 +
  217 + if (ch->active) {
  218 + ch->active = 0;
  219 + ch->status &= ~SYNC;
  220 + s->run_count --;
  221 + }
  222 +
  223 + if (!s->run_count)
  224 + qemu_del_timer(s->tm);
  225 +}
  226 +
  227 +static void omap_dma_enable_channel(struct omap_dma_s *s,
  228 + struct omap_dma_channel_s *ch)
  229 +{
  230 + if (!ch->enable) {
  231 + ch->enable = 1;
  232 + ch->waiting_end_prog = 0;
  233 + omap_dma_channel_load(s, ch);
  234 + if ((!ch->sync) || (s->drq & (1 << ch->sync)))
  235 + omap_dma_activate_channel(s, ch);
  236 + }
  237 +}
  238 +
  239 +static void omap_dma_disable_channel(struct omap_dma_s *s,
  240 + struct omap_dma_channel_s *ch)
  241 +{
  242 + if (ch->enable) {
  243 + ch->enable = 0;
  244 + /* Discard any pending request */
  245 + ch->pending_request = 0;
  246 + omap_dma_deactivate_channel(s, ch);
  247 + }
  248 +}
  249 +
  250 +static void omap_dma_channel_end_prog(struct omap_dma_s *s,
  251 + struct omap_dma_channel_s *ch)
  252 +{
  253 + if (ch->waiting_end_prog) {
  254 + ch->waiting_end_prog = 0;
  255 + if (!ch->sync || ch->pending_request) {
  256 + ch->pending_request = 0;
  257 + omap_dma_activate_channel(s, ch);
  258 + }
  259 + }
  260 +}
  261 +
  262 +static void omap_dma_enable_3_1_mapping(struct omap_dma_s *s)
  263 +{
  264 + s->omap_3_1_mapping_disabled = 0;
  265 + s->chans = 9;
  266 +}
  267 +
  268 +static void omap_dma_disable_3_1_mapping(struct omap_dma_s *s)
  269 +{
  270 + s->omap_3_1_mapping_disabled = 1;
  271 + s->chans = 16;
  272 +}
  273 +
  274 +static void omap_dma_process_request(struct omap_dma_s *s, int request)
  275 +{
  276 + int channel;
  277 + int drop_event = 0;
  278 + struct omap_dma_channel_s *ch = s->ch;
  279 +
  280 + for (channel = 0; channel < s->chans; channel ++, ch ++) {
  281 + if (ch->enable && ch->sync == request) {
  282 + if (!ch->active)
  283 + omap_dma_activate_channel(s, ch);
  284 + else if (!ch->pending_request)
  285 + ch->pending_request = 1;
  286 + else {
  287 + /* Request collision */
  288 + /* Second request received while processing other request */
  289 + ch->status |= EVENT_DROP_INTR;
  290 + drop_event = 1;
  291 + }
  292 + }
  293 + }
  294 +
  295 + if (drop_event)
  296 + omap_dma_interrupts_update(s);
  297 +}
  298 +
  299 +static void omap_dma_channel_run(struct omap_dma_s *s)
  300 +{
  301 + int n = s->chans;
  302 + uint16_t status;
  303 + uint8_t value[4];
  304 + struct omap_dma_port_if_s *src_p, *dest_p;
  305 + struct omap_dma_reg_set_s *a;
  306 + struct omap_dma_channel_s *ch;
  307 +
  308 + for (ch = s->ch; n; n --, ch ++) {
  309 + if (!ch->active)
  310 + continue;
  311 +
  312 + a = &ch->active_set;
  313 +
  314 + src_p = &s->mpu->port[ch->port[0]];
  315 + dest_p = &s->mpu->port[ch->port[1]];
  316 + if ((!ch->constant_fill && !src_p->addr_valid(s->mpu, a->src)) ||
  317 + (!dest_p->addr_valid(s->mpu, a->dest))) {
  318 +#if 0
  319 + /* Bus time-out */
  320 + if (ch->interrupts & TIMEOUT_INTR)
  321 + ch->status |= TIMEOUT_INTR;
  322 + omap_dma_deactivate_channel(s, ch);
  323 + continue;
  324 +#endif
  325 + printf("%s: Bus time-out in DMA%i operation\n",
  326 + __FUNCTION__, s->chans - n);
  327 + }
  328 +
  329 + status = ch->status;
  330 + while (status == ch->status && ch->active) {
  331 + /* Transfer a single element */
  332 + /* FIXME: check the endianness */
  333 + if (!ch->constant_fill)
  334 + cpu_physical_memory_read(a->src, value, ch->data_type);
  335 + else
  336 + *(uint32_t *) value = ch->color;
  337 +
  338 + if (!ch->transparent_copy ||
  339 + *(uint32_t *) value != ch->color)
  340 + cpu_physical_memory_write(a->dest, value, ch->data_type);
  341 +
  342 + a->src += a->elem_delta[0];
  343 + a->dest += a->elem_delta[1];
  344 + a->element ++;
  345 +
  346 + /* If the channel is element synchronized, deactivate it */
  347 + if (ch->sync && !ch->fs && !ch->bs)
  348 + omap_dma_deactivate_channel(s, ch);
  349 +
  350 + /* If it is the last frame, set the LAST_FRAME interrupt */
  351 + if (a->element == 1 && a->frame == a->frames - 1)
  352 + if (ch->interrupts & LAST_FRAME_INTR)
  353 + ch->status |= LAST_FRAME_INTR;
  354 +
  355 + /* If the half of the frame was reached, set the HALF_FRAME
  356 + interrupt */
  357 + if (a->element == (a->elements >> 1))
  358 + if (ch->interrupts & HALF_FRAME_INTR)
  359 + ch->status |= HALF_FRAME_INTR;
  360 +
  361 + if (a->element == a->elements) {
  362 + /* End of Frame */
  363 + a->element = 0;
  364 + a->src += a->frame_delta[0];
  365 + a->dest += a->frame_delta[1];
  366 + a->frame ++;
  367 +
  368 + /* If the channel is frame synchronized, deactivate it */
  369 + if (ch->sync && ch->fs)
  370 + omap_dma_deactivate_channel(s, ch);
  371 +
  372 + /* If the channel is async, update cpc */
  373 + if (!ch->sync)
  374 + ch->cpc = a->dest & 0xffff;
  375 +
  376 + /* Set the END_FRAME interrupt */
  377 + if (ch->interrupts & END_FRAME_INTR)
  378 + ch->status |= END_FRAME_INTR;
  379 +
  380 + if (a->frame == a->frames) {
  381 + /* End of Block */
  382 + /* Disable the channel */
  383 +
  384 + if (ch->omap_3_1_compatible_disable) {
  385 + omap_dma_disable_channel(s, ch);
  386 + if (ch->link_enabled)
  387 + omap_dma_enable_channel(s,
  388 + &s->ch[ch->link_next_ch]);
  389 + } else {
  390 + if (!ch->auto_init)
  391 + omap_dma_disable_channel(s, ch);
  392 + else if (ch->repeat || ch->end_prog)
  393 + omap_dma_channel_load(s, ch);
  394 + else {
  395 + ch->waiting_end_prog = 1;
  396 + omap_dma_deactivate_channel(s, ch);
  397 + }
  398 + }
  399 +
  400 + if (ch->interrupts & END_BLOCK_INTR)
  401 + ch->status |= END_BLOCK_INTR;
  402 + }
  403 + }
  404 + }
  405 + }
  406 +
  407 + omap_dma_interrupts_update(s);
  408 + if (s->run_count && s->delay)
  409 + qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
  410 +}
  411 +
  412 +void omap_dma_reset(struct omap_dma_s *s)
  413 +{
  414 + int i;
  415 +
  416 + qemu_del_timer(s->tm);
  417 + s->gcr = 0x0004;
  418 + s->drq = 0x00000000;
  419 + s->run_count = 0;
  420 + s->lcd_ch.src = emiff;
  421 + s->lcd_ch.condition = 0;
  422 + s->lcd_ch.interrupts = 0;
  423 + s->lcd_ch.dual = 0;
  424 + omap_dma_enable_3_1_mapping(s);
  425 + for (i = 0; i < s->chans; i ++) {
  426 + memset(&s->ch[i].burst, 0, sizeof(s->ch[i].burst));
  427 + memset(&s->ch[i].port, 0, sizeof(s->ch[i].port));
  428 + memset(&s->ch[i].mode, 0, sizeof(s->ch[i].mode));
  429 + memset(&s->ch[i].elements, 0, sizeof(s->ch[i].elements));
  430 + memset(&s->ch[i].frames, 0, sizeof(s->ch[i].frames));
  431 + memset(&s->ch[i].frame_index, 0, sizeof(s->ch[i].frame_index));
  432 + memset(&s->ch[i].element_index, 0, sizeof(s->ch[i].element_index));
  433 + memset(&s->ch[i].data_type, 0, sizeof(s->ch[i].data_type));
  434 + memset(&s->ch[i].transparent_copy, 0,
  435 + sizeof(s->ch[i].transparent_copy));
  436 + memset(&s->ch[i].constant_fill, 0, sizeof(s->ch[i].constant_fill));
  437 + memset(&s->ch[i].color, 0, sizeof(s->ch[i].color));
  438 + memset(&s->ch[i].end_prog, 0, sizeof(s->ch[i].end_prog));
  439 + memset(&s->ch[i].repeat, 0, sizeof(s->ch[i].repeat));
  440 + memset(&s->ch[i].auto_init, 0, sizeof(s->ch[i].auto_init));
  441 + memset(&s->ch[i].link_enabled, 0, sizeof(s->ch[i].link_enabled));
  442 + memset(&s->ch[i].link_next_ch, 0, sizeof(s->ch[i].link_next_ch));
  443 + s->ch[i].interrupts = 0x0003;
  444 + memset(&s->ch[i].status, 0, sizeof(s->ch[i].status));
  445 + memset(&s->ch[i].active, 0, sizeof(s->ch[i].active));
  446 + memset(&s->ch[i].enable, 0, sizeof(s->ch[i].enable));
  447 + memset(&s->ch[i].sync, 0, sizeof(s->ch[i].sync));
  448 + memset(&s->ch[i].pending_request, 0, sizeof(s->ch[i].pending_request));
  449 + memset(&s->ch[i].waiting_end_prog, 0,
  450 + sizeof(s->ch[i].waiting_end_prog));
  451 + memset(&s->ch[i].cpc, 0, sizeof(s->ch[i].cpc));
  452 + memset(&s->ch[i].fs, 0, sizeof(s->ch[i].fs));
  453 + memset(&s->ch[i].bs, 0, sizeof(s->ch[i].bs));
  454 + memset(&s->ch[i].omap_3_1_compatible_disable, 0,
  455 + sizeof(s->ch[i].omap_3_1_compatible_disable));
  456 + memset(&s->ch[i].active_set, 0, sizeof(s->ch[i].active_set));
  457 + memset(&s->ch[i].priority, 0, sizeof(s->ch[i].priority));
  458 + memset(&s->ch[i].interleave_disabled, 0,
  459 + sizeof(s->ch[i].interleave_disabled));
  460 + memset(&s->ch[i].type, 0, sizeof(s->ch[i].type));
  461 + }
  462 +}
  463 +
  464 +static int omap_dma_ch_reg_read(struct omap_dma_s *s,
  465 + struct omap_dma_channel_s *ch, int reg, uint16_t *value)
  466 +{
  467 + switch (reg) {
  468 + case 0x00: /* SYS_DMA_CSDP_CH0 */
  469 + *value = (ch->burst[1] << 14) |
  470 + (ch->pack[1] << 13) |
  471 + (ch->port[1] << 9) |
  472 + (ch->burst[0] << 7) |
  473 + (ch->pack[0] << 6) |
  474 + (ch->port[0] << 2) |
  475 + (ch->data_type >> 1);
  476 + break;
  477 +
  478 + case 0x02: /* SYS_DMA_CCR_CH0 */
  479 + if (s->model == omap_dma_3_1)
  480 + *value = 0 << 10; /* FIFO_FLUSH reads as 0 */
  481 + else
  482 + *value = ch->omap_3_1_compatible_disable << 10;
  483 + *value |= (ch->mode[1] << 14) |
  484 + (ch->mode[0] << 12) |
  485 + (ch->end_prog << 11) |
  486 + (ch->repeat << 9) |
  487 + (ch->auto_init << 8) |
  488 + (ch->enable << 7) |
  489 + (ch->priority << 6) |
  490 + (ch->fs << 5) | ch->sync;
  491 + break;
  492 +
  493 + case 0x04: /* SYS_DMA_CICR_CH0 */
  494 + *value = ch->interrupts;
  495 + break;
  496 +
  497 + case 0x06: /* SYS_DMA_CSR_CH0 */
  498 + *value = ch->status;
  499 + ch->status &= SYNC;
  500 + if (!ch->omap_3_1_compatible_disable && ch->sibling) {
  501 + *value |= (ch->sibling->status & 0x3f) << 6;
  502 + ch->sibling->status &= SYNC;
  503 + }
  504 + qemu_irq_lower(ch->irq);
  505 + break;
  506 +
  507 + case 0x08: /* SYS_DMA_CSSA_L_CH0 */
  508 + *value = ch->addr[0] & 0x0000ffff;
  509 + break;
  510 +
  511 + case 0x0a: /* SYS_DMA_CSSA_U_CH0 */
  512 + *value = ch->addr[0] >> 16;
  513 + break;
  514 +
  515 + case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
  516 + *value = ch->addr[1] & 0x0000ffff;
  517 + break;
  518 +
  519 + case 0x0e: /* SYS_DMA_CDSA_U_CH0 */
  520 + *value = ch->addr[1] >> 16;
  521 + break;
  522 +
  523 + case 0x10: /* SYS_DMA_CEN_CH0 */
  524 + *value = ch->elements;
  525 + break;
  526 +
  527 + case 0x12: /* SYS_DMA_CFN_CH0 */
  528 + *value = ch->frames;
  529 + break;
  530 +
  531 + case 0x14: /* SYS_DMA_CFI_CH0 */
  532 + *value = ch->frame_index[0];
  533 + break;
  534 +
  535 + case 0x16: /* SYS_DMA_CEI_CH0 */
  536 + *value = ch->element_index[0];
  537 + break;
  538 +
  539 + case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */
  540 + if (ch->omap_3_1_compatible_disable)
  541 + *value = ch->active_set.src & 0xffff; /* CSAC */
  542 + else
  543 + *value = ch->cpc;
  544 + break;
  545 +
  546 + case 0x1a: /* DMA_CDAC */
  547 + *value = ch->active_set.dest & 0xffff; /* CDAC */
  548 + break;
  549 +
  550 + case 0x1c: /* DMA_CDEI */
  551 + *value = ch->element_index[1];
  552 + break;
  553 +
  554 + case 0x1e: /* DMA_CDFI */
  555 + *value = ch->frame_index[1];
  556 + break;
  557 +
  558 + case 0x20: /* DMA_COLOR_L */
  559 + *value = ch->color & 0xffff;
  560 + break;
  561 +
  562 + case 0x22: /* DMA_COLOR_U */
  563 + *value = ch->color >> 16;
  564 + break;
  565 +
  566 + case 0x24: /* DMA_CCR2 */
  567 + *value = (ch->bs << 2) |
  568 + (ch->transparent_copy << 1) |
  569 + ch->constant_fill;
  570 + break;
  571 +
  572 + case 0x28: /* DMA_CLNK_CTRL */
  573 + *value = (ch->link_enabled << 15) |
  574 + (ch->link_next_ch & 0xf);
  575 + break;
  576 +
  577 + case 0x2a: /* DMA_LCH_CTRL */
  578 + *value = (ch->interleave_disabled << 15) |
  579 + ch->type;
  580 + break;
  581 +
  582 + default:
  583 + return 1;
  584 + }
  585 + return 0;
  586 +}
  587 +
  588 +static int omap_dma_ch_reg_write(struct omap_dma_s *s,
  589 + struct omap_dma_channel_s *ch, int reg, uint16_t value)
  590 +{
  591 + switch (reg) {
  592 + case 0x00: /* SYS_DMA_CSDP_CH0 */
  593 + ch->burst[1] = (value & 0xc000) >> 14;
  594 + ch->pack[1] = (value & 0x2000) >> 13;
  595 + ch->port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
  596 + ch->burst[0] = (value & 0x0180) >> 7;
  597 + ch->pack[0] = (value & 0x0040) >> 6;
  598 + ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
  599 + ch->data_type = (1 << (value & 3));
  600 + if (ch->port[0] >= omap_dma_port_last)
  601 + printf("%s: invalid DMA port %i\n", __FUNCTION__,
  602 + ch->port[0]);
  603 + if (ch->port[1] >= omap_dma_port_last)
  604 + printf("%s: invalid DMA port %i\n", __FUNCTION__,
  605 + ch->port[1]);
  606 + if ((value & 3) == 3)
  607 + printf("%s: bad data_type for DMA channel\n", __FUNCTION__);
  608 + break;
  609 +
  610 + case 0x02: /* SYS_DMA_CCR_CH0 */
  611 + ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
  612 + ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
  613 + ch->end_prog = (value & 0x0800) >> 11;
  614 + if (s->model > omap_dma_3_1)
  615 + ch->omap_3_1_compatible_disable = (value >> 10) & 0x1;
  616 + ch->repeat = (value & 0x0200) >> 9;
  617 + ch->auto_init = (value & 0x0100) >> 8;
  618 + ch->priority = (value & 0x0040) >> 6;
  619 + ch->fs = (value & 0x0020) >> 5;
  620 + ch->sync = value & 0x001f;
  621 +
  622 + if (value & 0x0080)
  623 + omap_dma_enable_channel(s, ch);
  624 + else
  625 + omap_dma_disable_channel(s, ch);
  626 +
  627 + if (ch->end_prog)
  628 + omap_dma_channel_end_prog(s, ch);
  629 +
  630 + break;
  631 +
  632 + case 0x04: /* SYS_DMA_CICR_CH0 */
  633 + ch->interrupts = value;
  634 + break;
  635 +
  636 + case 0x06: /* SYS_DMA_CSR_CH0 */
  637 + OMAP_RO_REG((target_phys_addr_t) reg);
  638 + break;
  639 +
  640 + case 0x08: /* SYS_DMA_CSSA_L_CH0 */
  641 + ch->addr[0] &= 0xffff0000;
  642 + ch->addr[0] |= value;
  643 + break;
  644 +
  645 + case 0x0a: /* SYS_DMA_CSSA_U_CH0 */
  646 + ch->addr[0] &= 0x0000ffff;
  647 + ch->addr[0] |= (uint32_t) value << 16;
  648 + break;
  649 +
  650 + case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
  651 + ch->addr[1] &= 0xffff0000;
  652 + ch->addr[1] |= value;
  653 + break;
  654 +
  655 + case 0x0e: /* SYS_DMA_CDSA_U_CH0 */
  656 + ch->addr[1] &= 0x0000ffff;
  657 + ch->addr[1] |= (uint32_t) value << 16;
  658 + break;
  659 +
  660 + case 0x10: /* SYS_DMA_CEN_CH0 */
  661 + ch->elements = value;
  662 + break;
  663 +
  664 + case 0x12: /* SYS_DMA_CFN_CH0 */
  665 + ch->frames = value;
  666 + break;
  667 +
  668 + case 0x14: /* SYS_DMA_CFI_CH0 */
  669 + ch->frame_index[0] = (int16_t) value;
  670 + break;
  671 +
  672 + case 0x16: /* SYS_DMA_CEI_CH0 */
  673 + ch->element_index[0] = (int16_t) value;
  674 + break;
  675 +
  676 + case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */
  677 + OMAP_RO_REG((target_phys_addr_t) reg);
  678 + break;
  679 +
  680 + case 0x1c: /* DMA_CDEI */
  681 + ch->element_index[1] = (int16_t) value;
  682 + break;
  683 +
  684 + case 0x1e: /* DMA_CDFI */
  685 + ch->frame_index[1] = (int16_t) value;
  686 + break;
  687 +
  688 + case 0x20: /* DMA_COLOR_L */
  689 + ch->color &= 0xffff0000;
  690 + ch->color |= value;
  691 + break;
  692 +
  693 + case 0x22: /* DMA_COLOR_U */
  694 + ch->color &= 0xffff;
  695 + ch->color |= value << 16;
  696 + break;
  697 +
  698 + case 0x24: /* DMA_CCR2 */
  699 + ch->bs = (value >> 2) & 0x1;
  700 + ch->transparent_copy = (value >> 1) & 0x1;
  701 + ch->constant_fill = value & 0x1;
  702 + break;
  703 +
  704 + case 0x28: /* DMA_CLNK_CTRL */
  705 + ch->link_enabled = (value >> 15) & 0x1;
  706 + if (value & (1 << 14)) { /* Stop_Lnk */
  707 + ch->link_enabled = 0;
  708 + omap_dma_disable_channel(s, ch);
  709 + }
  710 + ch->link_next_ch = value & 0x1f;
  711 + break;
  712 +
  713 + case 0x2a: /* DMA_LCH_CTRL */
  714 + ch->interleave_disabled = (value >> 15) & 0x1;
  715 + ch->type = value & 0xf;
  716 + break;
  717 +
  718 + default:
  719 + return 1;
  720 + }
  721 + return 0;
  722 +}
  723 +
  724 +static int omap_dma_3_2_lcd_write(struct omap_dma_lcd_channel_s *s, int offset,
  725 + uint16_t value)
  726 +{
  727 + switch (offset) {
  728 + case 0xbc0: /* DMA_LCD_CSDP */
  729 + s->brust_f2 = (value >> 14) & 0x3;
  730 + s->pack_f2 = (value >> 13) & 0x1;
  731 + s->data_type_f2 = (1 << ((value >> 11) & 0x3));
  732 + s->brust_f1 = (value >> 7) & 0x3;
  733 + s->pack_f1 = (value >> 6) & 0x1;
  734 + s->data_type_f1 = (1 << ((value >> 0) & 0x3));
  735 + break;
  736 +
  737 + case 0xbc2: /* DMA_LCD_CCR */
  738 + s->mode_f2 = (value >> 14) & 0x3;
  739 + s->mode_f1 = (value >> 12) & 0x3;
  740 + s->end_prog = (value >> 11) & 0x1;
  741 + s->omap_3_1_compatible_disable = (value >> 10) & 0x1;
  742 + s->repeat = (value >> 9) & 0x1;
  743 + s->auto_init = (value >> 8) & 0x1;
  744 + s->running = (value >> 7) & 0x1;
  745 + s->priority = (value >> 6) & 0x1;
  746 + s->bs = (value >> 4) & 0x1;
  747 + break;
  748 +
  749 + case 0xbc4: /* DMA_LCD_CTRL */
  750 + s->dst = (value >> 8) & 0x1;
  751 + s->src = ((value >> 6) & 0x3) << 1;
  752 + s->condition = 0;
  753 + /* Assume no bus errors and thus no BUS_ERROR irq bits. */
  754 + s->interrupts = (value >> 1) & 1;
  755 + s->dual = value & 1;
  756 + break;
  757 +
  758 + case 0xbc8: /* TOP_B1_L */
  759 + s->src_f1_top &= 0xffff0000;
  760 + s->src_f1_top |= 0x0000ffff & value;
  761 + break;
  762 +
  763 + case 0xbca: /* TOP_B1_U */
  764 + s->src_f1_top &= 0x0000ffff;
  765 + s->src_f1_top |= value << 16;
  766 + break;
  767 +
  768 + case 0xbcc: /* BOT_B1_L */
  769 + s->src_f1_bottom &= 0xffff0000;
  770 + s->src_f1_bottom |= 0x0000ffff & value;
  771 + break;
  772 +
  773 + case 0xbce: /* BOT_B1_U */
  774 + s->src_f1_bottom &= 0x0000ffff;
  775 + s->src_f1_bottom |= (uint32_t) value << 16;
  776 + break;
  777 +
  778 + case 0xbd0: /* TOP_B2_L */
  779 + s->src_f2_top &= 0xffff0000;
  780 + s->src_f2_top |= 0x0000ffff & value;
  781 + break;
  782 +
  783 + case 0xbd2: /* TOP_B2_U */
  784 + s->src_f2_top &= 0x0000ffff;
  785 + s->src_f2_top |= (uint32_t) value << 16;
  786 + break;
  787 +
  788 + case 0xbd4: /* BOT_B2_L */
  789 + s->src_f2_bottom &= 0xffff0000;
  790 + s->src_f2_bottom |= 0x0000ffff & value;
  791 + break;
  792 +
  793 + case 0xbd6: /* BOT_B2_U */
  794 + s->src_f2_bottom &= 0x0000ffff;
  795 + s->src_f2_bottom |= (uint32_t) value << 16;
  796 + break;
  797 +
  798 + case 0xbd8: /* DMA_LCD_SRC_EI_B1 */
  799 + s->element_index_f1 = value;
  800 + break;
  801 +
  802 + case 0xbda: /* DMA_LCD_SRC_FI_B1_L */
  803 + s->frame_index_f1 &= 0xffff0000;
  804 + s->frame_index_f1 |= 0x0000ffff & value;
  805 + break;
  806 +
  807 + case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */
  808 + s->frame_index_f1 &= 0x0000ffff;
  809 + s->frame_index_f1 |= (uint32_t) value << 16;
  810 + break;
  811 +
  812 + case 0xbdc: /* DMA_LCD_SRC_EI_B2 */
  813 + s->element_index_f2 = value;
  814 + break;
  815 +
  816 + case 0xbde: /* DMA_LCD_SRC_FI_B2_L */
  817 + s->frame_index_f2 &= 0xffff0000;
  818 + s->frame_index_f2 |= 0x0000ffff & value;
  819 + break;
  820 +
  821 + case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */
  822 + s->frame_index_f2 &= 0x0000ffff;
  823 + s->frame_index_f2 |= (uint32_t) value << 16;
  824 + break;
  825 +
  826 + case 0xbe0: /* DMA_LCD_SRC_EN_B1 */
  827 + s->elements_f1 = value;
  828 + break;
  829 +
  830 + case 0xbe4: /* DMA_LCD_SRC_FN_B1 */
  831 + s->frames_f1 = value;
  832 + break;
  833 +
  834 + case 0xbe2: /* DMA_LCD_SRC_EN_B2 */
  835 + s->elements_f2 = value;
  836 + break;
  837 +
  838 + case 0xbe6: /* DMA_LCD_SRC_FN_B2 */
  839 + s->frames_f2 = value;
  840 + break;
  841 +
  842 + case 0xbea: /* DMA_LCD_LCH_CTRL */
  843 + s->lch_type = value & 0xf;
  844 + break;
  845 +
  846 + default:
  847 + return 1;
  848 + }
  849 + return 0;
  850 +}
  851 +
  852 +static int omap_dma_3_2_lcd_read(struct omap_dma_lcd_channel_s *s, int offset,
  853 + uint16_t *ret)
  854 +{
  855 + switch (offset) {
  856 + case 0xbc0: /* DMA_LCD_CSDP */
  857 + *ret = (s->brust_f2 << 14) |
  858 + (s->pack_f2 << 13) |
  859 + ((s->data_type_f2 >> 1) << 11) |
  860 + (s->brust_f1 << 7) |
  861 + (s->pack_f1 << 6) |
  862 + ((s->data_type_f1 >> 1) << 0);
  863 + break;
  864 +
  865 + case 0xbc2: /* DMA_LCD_CCR */
  866 + *ret = (s->mode_f2 << 14) |
  867 + (s->mode_f1 << 12) |
  868 + (s->end_prog << 11) |
  869 + (s->omap_3_1_compatible_disable << 10) |
  870 + (s->repeat << 9) |
  871 + (s->auto_init << 8) |
  872 + (s->running << 7) |
  873 + (s->priority << 6) |
  874 + (s->bs << 4);
  875 + break;
  876 +
  877 + case 0xbc4: /* DMA_LCD_CTRL */
  878 + qemu_irq_lower(s->irq);
  879 + *ret = (s->dst << 8) |
  880 + ((s->src & 0x6) << 5) |
  881 + (s->condition << 3) |
  882 + (s->interrupts << 1) |
  883 + s->dual;
  884 + break;
  885 +
  886 + case 0xbc8: /* TOP_B1_L */
  887 + *ret = s->src_f1_top & 0xffff;
  888 + break;
  889 +
  890 + case 0xbca: /* TOP_B1_U */
  891 + *ret = s->src_f1_top >> 16;
  892 + break;
  893 +
  894 + case 0xbcc: /* BOT_B1_L */
  895 + *ret = s->src_f1_bottom & 0xffff;
  896 + break;
  897 +
  898 + case 0xbce: /* BOT_B1_U */
  899 + *ret = s->src_f1_bottom >> 16;
  900 + break;
  901 +
  902 + case 0xbd0: /* TOP_B2_L */
  903 + *ret = s->src_f2_top & 0xffff;
  904 + break;
  905 +
  906 + case 0xbd2: /* TOP_B2_U */
  907 + *ret = s->src_f2_top >> 16;
  908 + break;
  909 +
  910 + case 0xbd4: /* BOT_B2_L */
  911 + *ret = s->src_f2_bottom & 0xffff;
  912 + break;
  913 +
  914 + case 0xbd6: /* BOT_B2_U */
  915 + *ret = s->src_f2_bottom >> 16;
  916 + break;
  917 +
  918 + case 0xbd8: /* DMA_LCD_SRC_EI_B1 */
  919 + *ret = s->element_index_f1;
  920 + break;
  921 +
  922 + case 0xbda: /* DMA_LCD_SRC_FI_B1_L */
  923 + *ret = s->frame_index_f1 & 0xffff;
  924 + break;
  925 +
  926 + case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */
  927 + *ret = s->frame_index_f1 >> 16;
  928 + break;
  929 +
  930 + case 0xbdc: /* DMA_LCD_SRC_EI_B2 */
  931 + *ret = s->element_index_f2;
  932 + break;
  933 +
  934 + case 0xbde: /* DMA_LCD_SRC_FI_B2_L */
  935 + *ret = s->frame_index_f2 & 0xffff;
  936 + break;
  937 +
  938 + case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */
  939 + *ret = s->frame_index_f2 >> 16;
  940 + break;
  941 +
  942 + case 0xbe0: /* DMA_LCD_SRC_EN_B1 */
  943 + *ret = s->elements_f1;
  944 + break;
  945 +
  946 + case 0xbe4: /* DMA_LCD_SRC_FN_B1 */
  947 + *ret = s->frames_f1;
  948 + break;
  949 +
  950 + case 0xbe2: /* DMA_LCD_SRC_EN_B2 */
  951 + *ret = s->elements_f2;
  952 + break;
  953 +
  954 + case 0xbe6: /* DMA_LCD_SRC_FN_B2 */
  955 + *ret = s->frames_f2;
  956 + break;
  957 +
  958 + case 0xbea: /* DMA_LCD_LCH_CTRL */
  959 + *ret = s->lch_type;
  960 + break;
  961 +
  962 + default:
  963 + return 1;
  964 + }
  965 + return 0;
  966 +}
  967 +
  968 +static int omap_dma_3_1_lcd_write(struct omap_dma_lcd_channel_s *s, int offset,
  969 + uint16_t value)
  970 +{
  971 + switch (offset) {
  972 + case 0x300: /* SYS_DMA_LCD_CTRL */
  973 + s->src = (value & 0x40) ? imif : emiff;
  974 + s->condition = 0;
  975 + /* Assume no bus errors and thus no BUS_ERROR irq bits. */
  976 + s->interrupts = (value >> 1) & 1;
  977 + s->dual = value & 1;
  978 + break;
  979 +
  980 + case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
  981 + s->src_f1_top &= 0xffff0000;
  982 + s->src_f1_top |= 0x0000ffff & value;
  983 + break;
  984 +
  985 + case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
  986 + s->src_f1_top &= 0x0000ffff;
  987 + s->src_f1_top |= value << 16;
  988 + break;
  989 +
  990 + case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
  991 + s->src_f1_bottom &= 0xffff0000;
  992 + s->src_f1_bottom |= 0x0000ffff & value;
  993 + break;
  994 +
  995 + case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
  996 + s->src_f1_bottom &= 0x0000ffff;
  997 + s->src_f1_bottom |= value << 16;
  998 + break;
  999 +
  1000 + case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
  1001 + s->src_f2_top &= 0xffff0000;
  1002 + s->src_f2_top |= 0x0000ffff & value;
  1003 + break;
  1004 +
  1005 + case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
  1006 + s->src_f2_top &= 0x0000ffff;
  1007 + s->src_f2_top |= value << 16;
  1008 + break;
  1009 +
  1010 + case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
  1011 + s->src_f2_bottom &= 0xffff0000;
  1012 + s->src_f2_bottom |= 0x0000ffff & value;
  1013 + break;
  1014 +
  1015 + case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
  1016 + s->src_f2_bottom &= 0x0000ffff;
  1017 + s->src_f2_bottom |= value << 16;
  1018 + break;
  1019 +
  1020 + default:
  1021 + return 1;
  1022 + }
  1023 + return 0;
  1024 +}
  1025 +
  1026 +static int omap_dma_3_1_lcd_read(struct omap_dma_lcd_channel_s *s, int offset,
  1027 + uint16_t *ret)
  1028 +{
  1029 + int i;
  1030 +
  1031 + switch (offset) {
  1032 + case 0x300: /* SYS_DMA_LCD_CTRL */
  1033 + i = s->condition;
  1034 + s->condition = 0;
  1035 + qemu_irq_lower(s->irq);
  1036 + *ret = ((s->src == imif) << 6) | (i << 3) |
  1037 + (s->interrupts << 1) | s->dual;
  1038 + break;
  1039 +
  1040 + case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
  1041 + *ret = s->src_f1_top & 0xffff;
  1042 + break;
  1043 +
  1044 + case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
  1045 + *ret = s->src_f1_top >> 16;
  1046 + break;
  1047 +
  1048 + case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
  1049 + *ret = s->src_f1_bottom & 0xffff;
  1050 + break;
  1051 +
  1052 + case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
  1053 + *ret = s->src_f1_bottom >> 16;
  1054 + break;
  1055 +
  1056 + case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
  1057 + *ret = s->src_f2_top & 0xffff;
  1058 + break;
  1059 +
  1060 + case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
  1061 + *ret = s->src_f2_top >> 16;
  1062 + break;
  1063 +
  1064 + case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
  1065 + *ret = s->src_f2_bottom & 0xffff;
  1066 + break;
  1067 +
  1068 + case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
  1069 + *ret = s->src_f2_bottom >> 16;
  1070 + break;
  1071 +
  1072 + default:
  1073 + return 1;
  1074 + }
  1075 + return 0;
  1076 +}
  1077 +
  1078 +static int omap_dma_sys_write(struct omap_dma_s *s, int offset, uint16_t value)
  1079 +{
  1080 + switch (offset) {
  1081 + case 0x400: /* SYS_DMA_GCR */
  1082 + s->gcr = value;
  1083 + break;
  1084 +
  1085 + case 0x404: /* DMA_GSCR */
  1086 + if (value & 0x8)
  1087 + omap_dma_disable_3_1_mapping(s);
  1088 + else
  1089 + omap_dma_enable_3_1_mapping(s);
  1090 + break;
  1091 +
  1092 + case 0x408: /* DMA_GRST */
  1093 + if (value & 0x1)
  1094 + omap_dma_reset(s);
  1095 + break;
  1096 +
  1097 + default:
  1098 + return 1;
  1099 + }
  1100 + return 0;
  1101 +}
  1102 +
  1103 +static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
  1104 + uint16_t *ret)
  1105 +{
  1106 + switch (offset) {
  1107 + case 0x400: /* SYS_DMA_GCR */
  1108 + *ret = s->gcr;
  1109 + break;
  1110 +
  1111 + case 0x404: /* DMA_GSCR */
  1112 + *ret = s->omap_3_1_mapping_disabled << 3;
  1113 + break;
  1114 +
  1115 + case 0x408: /* DMA_GRST */
  1116 + *ret = 0;
  1117 + break;
  1118 +
  1119 + case 0x442: /* DMA_HW_ID */
  1120 + case 0x444: /* DMA_PCh2_ID */
  1121 + case 0x446: /* DMA_PCh0_ID */
  1122 + case 0x448: /* DMA_PCh1_ID */
  1123 + case 0x44a: /* DMA_PChG_ID */
  1124 + case 0x44c: /* DMA_PChD_ID */
  1125 + *ret = 1;
  1126 + break;
  1127 +
  1128 + case 0x44e: /* DMA_CAPS_0_U */
  1129 + *ret = (1 << 3) | /* Constant Fill Capacity */
  1130 + (1 << 2); /* Transparent BLT Capacity */
  1131 + break;
  1132 +
  1133 + case 0x450: /* DMA_CAPS_0_L */
  1134 + case 0x452: /* DMA_CAPS_1_U */
  1135 + *ret = 0;
  1136 + break;
  1137 +
  1138 + case 0x454: /* DMA_CAPS_1_L */
  1139 + *ret = (1 << 1); /* 1-bit palletized capability */
  1140 + break;
  1141 +
  1142 + case 0x456: /* DMA_CAPS_2 */
  1143 + *ret = (1 << 8) | /* SSDIC */
  1144 + (1 << 7) | /* DDIAC */
  1145 + (1 << 6) | /* DSIAC */
  1146 + (1 << 5) | /* DPIAC */
  1147 + (1 << 4) | /* DCAC */
  1148 + (1 << 3) | /* SDIAC */
  1149 + (1 << 2) | /* SSIAC */
  1150 + (1 << 1) | /* SPIAC */
  1151 + 1; /* SCAC */
  1152 + break;
  1153 +
  1154 + case 0x458: /* DMA_CAPS_3 */
  1155 + *ret = (1 << 5) | /* CCC */
  1156 + (1 << 4) | /* IC */
  1157 + (1 << 3) | /* ARC */
  1158 + (1 << 2) | /* AEC */
  1159 + (1 << 1) | /* FSC */
  1160 + 1; /* ESC */
  1161 + break;
  1162 +
  1163 + case 0x45a: /* DMA_CAPS_4 */
  1164 + *ret = (1 << 6) | /* SSC */
  1165 + (1 << 5) | /* BIC */
  1166 + (1 << 4) | /* LFIC */
  1167 + (1 << 3) | /* FIC */
  1168 + (1 << 2) | /* HFIC */
  1169 + (1 << 1) | /* EDIC */
  1170 + 1; /* TOIC */
  1171 + break;
  1172 +
  1173 + case 0x460: /* DMA_PCh2_SR */
  1174 + case 0x480: /* DMA_PCh0_SR */
  1175 + case 0x482: /* DMA_PCh1_SR */
  1176 + case 0x4c0: /* DMA_PChD_SR_0 */
  1177 + printf("%s: Physical Channel Status Registers not implemented.\n",
  1178 + __FUNCTION__);
  1179 + *ret = 0xff;
  1180 + break;
  1181 +
  1182 + default:
  1183 + return 1;
  1184 + }
  1185 + return 0;
  1186 +}
  1187 +
  1188 +static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
  1189 +{
  1190 + struct omap_dma_s *s = (struct omap_dma_s *) opaque;
  1191 + int reg, ch, offset = addr - s->base;
  1192 + uint16_t ret;
  1193 +
  1194 + switch (offset) {
  1195 + case 0x300 ... 0x3fe:
  1196 + if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
  1197 + if (omap_dma_3_1_lcd_read(&s->lcd_ch, offset, &ret))
  1198 + break;
  1199 + return ret;
  1200 + }
  1201 + /* Fall through. */
  1202 + case 0x000 ... 0x2fe:
  1203 + reg = offset & 0x3f;
  1204 + ch = (offset >> 6) & 0x0f;
  1205 + if (omap_dma_ch_reg_read(s, &s->ch[ch], reg, &ret))
  1206 + break;
  1207 + return ret;
  1208 +
  1209 + case 0x404 ... 0x4fe:
  1210 + if (s->model == omap_dma_3_1)
  1211 + break;
  1212 + /* Fall through. */
  1213 + case 0x400:
  1214 + if (omap_dma_sys_read(s, offset, &ret))
  1215 + break;
  1216 + return ret;
  1217 +
  1218 + case 0xb00 ... 0xbfe:
  1219 + if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
  1220 + if (omap_dma_3_2_lcd_read(&s->lcd_ch, offset, &ret))
  1221 + break;
  1222 + return ret;
  1223 + }
  1224 + break;
  1225 + }
  1226 +
  1227 + OMAP_BAD_REG(addr);
  1228 + return 0;
  1229 +}
  1230 +
  1231 +static void omap_dma_write(void *opaque, target_phys_addr_t addr,
  1232 + uint32_t value)
  1233 +{
  1234 + struct omap_dma_s *s = (struct omap_dma_s *) opaque;
  1235 + int reg, ch, offset = addr - s->base;
  1236 +
  1237 + switch (offset) {
  1238 + case 0x300 ... 0x3fe:
  1239 + if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
  1240 + if (omap_dma_3_1_lcd_write(&s->lcd_ch, offset, value))
  1241 + break;
  1242 + return;
  1243 + }
  1244 + /* Fall through. */
  1245 + case 0x000 ... 0x2fe:
  1246 + reg = offset & 0x3f;
  1247 + ch = (offset >> 6) & 0x0f;
  1248 + if (omap_dma_ch_reg_write(s, &s->ch[ch], reg, value))
  1249 + break;
  1250 + return;
  1251 +
  1252 + case 0x404 ... 0x4fe:
  1253 + if (s->model == omap_dma_3_1)
  1254 + break;
  1255 + case 0x400:
  1256 + /* Fall through. */
  1257 + if (omap_dma_sys_write(s, offset, value))
  1258 + break;
  1259 + return;
  1260 +
  1261 + case 0xb00 ... 0xbfe:
  1262 + if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
  1263 + if (omap_dma_3_2_lcd_write(&s->lcd_ch, offset, value))
  1264 + break;
  1265 + return;
  1266 + }
  1267 + break;
  1268 + }
  1269 +
  1270 + OMAP_BAD_REG(addr);
  1271 +}
  1272 +
  1273 +static CPUReadMemoryFunc *omap_dma_readfn[] = {
  1274 + omap_badwidth_read16,
  1275 + omap_dma_read,
  1276 + omap_badwidth_read16,
  1277 +};
  1278 +
  1279 +static CPUWriteMemoryFunc *omap_dma_writefn[] = {
  1280 + omap_badwidth_write16,
  1281 + omap_dma_write,
  1282 + omap_badwidth_write16,
  1283 +};
  1284 +
  1285 +static void omap_dma_request(void *opaque, int drq, int req)
  1286 +{
  1287 + struct omap_dma_s *s = (struct omap_dma_s *) opaque;
  1288 + /* The request pins are level triggered. */
  1289 + if (req) {
  1290 + if (~s->drq & (1 << drq)) {
  1291 + s->drq |= 1 << drq;
  1292 + omap_dma_process_request(s, drq);
  1293 + }
  1294 + } else
  1295 + s->drq &= ~(1 << drq);
  1296 +}
  1297 +
  1298 +static void omap_dma_clk_update(void *opaque, int line, int on)
  1299 +{
  1300 + struct omap_dma_s *s = (struct omap_dma_s *) opaque;
  1301 +
  1302 + if (on) {
  1303 + /* TODO: make a clever calculation */
  1304 + s->delay = ticks_per_sec >> 8;
  1305 + if (s->run_count)
  1306 + qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
  1307 + } else {
  1308 + s->delay = 0;
  1309 + qemu_del_timer(s->tm);
  1310 + }
  1311 +}
  1312 +
  1313 +struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
  1314 + qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
  1315 + enum omap_dma_model model)
  1316 +{
  1317 + int iomemtype, num_irqs, memsize, i;
  1318 + struct omap_dma_s *s = (struct omap_dma_s *)
  1319 + qemu_mallocz(sizeof(struct omap_dma_s));
  1320 +
  1321 + if (model == omap_dma_3_1) {
  1322 + num_irqs = 6;
  1323 + memsize = 0x800;
  1324 + } else {
  1325 + num_irqs = 16;
  1326 + memsize = 0xc00;
  1327 + }
  1328 + s->base = base;
  1329 + s->model = model;
  1330 + s->mpu = mpu;
  1331 + s->clk = clk;
  1332 + s->lcd_ch.irq = lcd_irq;
  1333 + s->lcd_ch.mpu = mpu;
  1334 + while (num_irqs --)
  1335 + s->ch[num_irqs].irq = irqs[num_irqs];
  1336 + for (i = 0; i < 3; i ++) {
  1337 + s->ch[i].sibling = &s->ch[i + 6];
  1338 + s->ch[i + 6].sibling = &s->ch[i];
  1339 + }
  1340 + s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
  1341 + omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
  1342 + mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
  1343 + omap_dma_reset(s);
  1344 + omap_dma_clk_update(s, 0, 1);
  1345 +
  1346 + iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
  1347 + omap_dma_writefn, s);
  1348 + cpu_register_physical_memory(s->base, memsize, iomemtype);
  1349 +
  1350 + return s;
  1351 +}
  1352 +
  1353 +struct omap_dma_lcd_channel_s *omap_dma_get_lcdch(struct omap_dma_s *s)
  1354 +{
  1355 + return &s->lcd_ch;
  1356 +}