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 592 OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
593 593 OBJS+= pflash_cfi01.o gumstix.o
594 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 596 OBJS+= palm.o tsc210x.o
597 597 OBJS+= mst_fpga.o mainstone.o
598 598 CPPFLAGS += -DHAS_AUDIO
... ...
hw/omap.h
1 1 /*
2 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 6 * This program is free software; you can redistribute it and/or
7 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 54 int64_t omap_clk_getrate(omap_clk clk);
55 55 void omap_clk_reparent(omap_clk clk, omap_clk parent);
56 56  
57   -/* omap.c */
  57 +/* omap[123].c */
58 58 struct omap_intr_handler_s;
59 59 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
60 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 340 # define OMAP_INT_243X_HS_USB_DMA 93
341 341 # define OMAP_INT_243X_CARKIT 94
342 342  
  343 +/* omap_dma.c */
343 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 351 struct omap_dma_s;
349 352 struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
350 353 qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
351 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 363 enum omap_dma_port {
354 364 emiff = 0,
355 365 emifs,
... ... @@ -367,6 +377,7 @@ typedef enum {
367 377 double_index,
368 378 } omap_dma_addressing_t;
369 379  
  380 +/* Only used in OMAP DMA 3.x gigacells */
370 381 struct omap_dma_lcd_channel_s {
371 382 enum omap_dma_port src;
372 383 target_phys_addr_t src_f1_top;
... ... @@ -411,7 +422,7 @@ struct omap_dma_lcd_channel_s {
411 422 ram_addr_t phys_framebuffer[2];
412 423 qemu_irq irq;
413 424 struct omap_mpu_state_s *mpu;
414   -};
  425 +} *omap_dma_get_lcdch(struct omap_dma_s *s);
415 426  
416 427 /*
417 428 * DMA request numbers for OMAP1
... ... @@ -477,6 +488,7 @@ struct omap_dma_lcd_channel_s {
477 488 # define OMAP_DMA_MMC2_RX 55
478 489 # define OMAP_DMA_CRYPTO_DES_OUT 56
479 490  
  491 +/* omap[123].c */
480 492 struct omap_mpu_timer_s;
481 493 struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
482 494 qemu_irq irq, omap_clk clk);
... ...
hw/omap.c renamed to hw/omap1.c
1 1 /*
2 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 6 * This program is free software; you can redistribute it and/or
7 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 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 404 /* MPU OS timers */
1769 405 struct omap_mpu_timer_s {
1770 406 qemu_irq irq;
... ... @@ -5577,11 +4213,6 @@ static void omap_mpu_wakeup(void *opaque, int irq, int req)
5577 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 4216 static const struct dma_irq_map omap_dma_irq_map[] = {
5586 4217 { 0, OMAP_INT_DMA_CH0_6 },
5587 4218 { 0, OMAP_INT_DMA_CH1_7 },
... ... @@ -5601,6 +4232,43 @@ static const struct dma_irq_map omap_dma_irq_map[] = {
5601 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 4272 struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
5605 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 4347 omap_findclk(s, "clk32-kHz"));
5680 4348  
5681 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 4351 omap_findclk(s, "lcd_ck"));
5684 4352  
5685 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 +}
... ...