Commit 1af2b62d123ae5601eb44786faf3be17aed1b2b2

Authored by balrog
1 parent cfa0b71d

OMAP DMA input signals must be level-triggered.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3096 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 17 additions and 7 deletions
hw/omap.c
@@ -403,6 +403,7 @@ struct omap_dma_s { @@ -403,6 +403,7 @@ struct omap_dma_s {
403 target_phys_addr_t base; 403 target_phys_addr_t base;
404 omap_clk clk; 404 omap_clk clk;
405 int64_t delay; 405 int64_t delay;
  406 + uint32_t drq;
406 407
407 uint16_t gcr; 408 uint16_t gcr;
408 int run_count; 409 int run_count;
@@ -511,7 +512,7 @@ next_channel: @@ -511,7 +512,7 @@ next_channel:
511 if (request > 0) 512 if (request > 0)
512 s->ch[channel].status |= 0x40; /* External request */ 513 s->ch[channel].status |= 0x40; /* External request */
513 514
514 - if (s->delay) 515 + if (s->delay && !qemu_timer_pending(s->tm))
515 qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay); 516 qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);
516 517
517 if (request > 0) { 518 if (request > 0) {
@@ -593,7 +594,8 @@ static void omap_dma_channel_run(struct omap_dma_s *s) @@ -593,7 +594,8 @@ static void omap_dma_channel_run(struct omap_dma_s *s)
593 if (s->ch[ch].interrupts & 0x08) 594 if (s->ch[ch].interrupts & 0x08)
594 s->ch[ch].status |= 0x08; 595 s->ch[ch].status |= 0x08;
595 596
596 - if (s->ch[ch].sync && s->ch[ch].fs) { 597 + if (s->ch[ch].sync && s->ch[ch].fs &&
  598 + !(s->drq & (1 << s->ch[ch].sync))) {
597 s->ch[ch].status &= ~0x40; 599 s->ch[ch].status &= ~0x40;
598 omap_dma_request_stop(s, ch); 600 omap_dma_request_stop(s, ch);
599 } 601 }
@@ -607,7 +609,8 @@ static void omap_dma_channel_run(struct omap_dma_s *s) @@ -607,7 +609,8 @@ static void omap_dma_channel_run(struct omap_dma_s *s)
607 if (s->ch[ch].interrupts & 0x04) 609 if (s->ch[ch].interrupts & 0x04)
608 s->ch[ch].status |= 0x04; 610 s->ch[ch].status |= 0x04;
609 611
610 - if (s->ch[ch].sync && !s->ch[ch].fs) { 612 + if (s->ch[ch].sync && !s->ch[ch].fs &&
  613 + !(s->drq & (1 << s->ch[ch].sync))) {
611 s->ch[ch].status &= ~0x40; 614 s->ch[ch].status &= ~0x40;
612 omap_dma_request_stop(s, ch); 615 omap_dma_request_stop(s, ch);
613 } 616 }
@@ -750,7 +753,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, @@ -750,7 +753,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
750 s->ch[ch].running = 1; 753 s->ch[ch].running = 1;
751 omap_dma_channel_load(s, ch); 754 omap_dma_channel_load(s, ch);
752 } 755 }
753 - if (!s->ch[ch].sync) 756 + if (!s->ch[ch].sync || (s->drq & (1 << s->ch[ch].sync)))
754 omap_dma_request_run(s, ch, 0); 757 omap_dma_request_run(s, ch, 0);
755 } else { 758 } else {
756 s->ch[ch].running = 0; 759 s->ch[ch].running = 0;
@@ -949,9 +952,14 @@ static CPUWriteMemoryFunc *omap_dma_writefn[] = { @@ -949,9 +952,14 @@ static CPUWriteMemoryFunc *omap_dma_writefn[] = {
949 static void omap_dma_request(void *opaque, int drq, int req) 952 static void omap_dma_request(void *opaque, int drq, int req)
950 { 953 {
951 struct omap_dma_s *s = (struct omap_dma_s *) opaque; 954 struct omap_dma_s *s = (struct omap_dma_s *) opaque;
952 - /* All the request pins are edge triggered. */  
953 - if (req)  
954 - omap_dma_request_run(s, 0, drq); 955 + /* The request pins are level triggered. */
  956 + if (req) {
  957 + if (~s->drq & (1 << drq)) {
  958 + s->drq |= 1 << drq;
  959 + omap_dma_request_run(s, 0, drq);
  960 + }
  961 + } else
  962 + s->drq &= ~(1 << drq);
955 } 963 }
956 964
957 static void omap_dma_clk_update(void *opaque, int line, int on) 965 static void omap_dma_clk_update(void *opaque, int line, int on)
@@ -974,6 +982,7 @@ static void omap_dma_reset(struct omap_dma_s *s) @@ -974,6 +982,7 @@ static void omap_dma_reset(struct omap_dma_s *s)
974 982
975 qemu_del_timer(s->tm); 983 qemu_del_timer(s->tm);
976 s->gcr = 0x0004; 984 s->gcr = 0x0004;
  985 + s->drq = 0x00000000;
977 s->run_count = 0; 986 s->run_count = 0;
978 s->lcd_ch.src = emiff; 987 s->lcd_ch.src = emiff;
979 s->lcd_ch.condition = 0; 988 s->lcd_ch.condition = 0;
@@ -1002,6 +1011,7 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, @@ -1002,6 +1011,7 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base,
1002 omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]); 1011 omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
1003 mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32); 1012 mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1004 omap_dma_reset(s); 1013 omap_dma_reset(s);
  1014 + omap_dma_clk_update(s, 0, 1);
1005 1015
1006 iomemtype = cpu_register_io_memory(0, omap_dma_readfn, 1016 iomemtype = cpu_register_io_memory(0, omap_dma_readfn,
1007 omap_dma_writefn, s); 1017 omap_dma_writefn, s);