diff options
author | balrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-07-31 01:43:17 +0000 |
---|---|---|
committer | balrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162> | 2007-07-31 01:43:17 +0000 |
commit | 1af2b62d123ae5601eb44786faf3be17aed1b2b2 (patch) | |
tree | c25ad3d842d2fbbfab3f9a08ae56666332143b51 | |
parent | cfa0b71dd84977b9378a9100b759739ef9220ac6 (diff) |
OMAP DMA input signals must be level-triggered.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3096 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | hw/omap.c | 24 |
1 files changed, 17 insertions, 7 deletions
@@ -403,6 +403,7 @@ struct omap_dma_s { target_phys_addr_t base; omap_clk clk; int64_t delay; + uint32_t drq; uint16_t gcr; int run_count; @@ -511,7 +512,7 @@ next_channel: if (request > 0) s->ch[channel].status |= 0x40; /* External request */ - if (s->delay) + if (s->delay && !qemu_timer_pending(s->tm)) qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay); if (request > 0) { @@ -593,7 +594,8 @@ static void omap_dma_channel_run(struct omap_dma_s *s) if (s->ch[ch].interrupts & 0x08) s->ch[ch].status |= 0x08; - if (s->ch[ch].sync && s->ch[ch].fs) { + if (s->ch[ch].sync && s->ch[ch].fs && + !(s->drq & (1 << s->ch[ch].sync))) { s->ch[ch].status &= ~0x40; omap_dma_request_stop(s, ch); } @@ -607,7 +609,8 @@ static void omap_dma_channel_run(struct omap_dma_s *s) if (s->ch[ch].interrupts & 0x04) s->ch[ch].status |= 0x04; - if (s->ch[ch].sync && !s->ch[ch].fs) { + if (s->ch[ch].sync && !s->ch[ch].fs && + !(s->drq & (1 << s->ch[ch].sync))) { s->ch[ch].status &= ~0x40; omap_dma_request_stop(s, ch); } @@ -750,7 +753,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, s->ch[ch].running = 1; omap_dma_channel_load(s, ch); } - if (!s->ch[ch].sync) + if (!s->ch[ch].sync || (s->drq & (1 << s->ch[ch].sync))) omap_dma_request_run(s, ch, 0); } else { s->ch[ch].running = 0; @@ -949,9 +952,14 @@ static CPUWriteMemoryFunc *omap_dma_writefn[] = { static void omap_dma_request(void *opaque, int drq, int req) { struct omap_dma_s *s = (struct omap_dma_s *) opaque; - /* All the request pins are edge triggered. */ - if (req) - omap_dma_request_run(s, 0, drq); + /* The request pins are level triggered. */ + if (req) { + if (~s->drq & (1 << drq)) { + s->drq |= 1 << drq; + omap_dma_request_run(s, 0, drq); + } + } else + s->drq &= ~(1 << drq); } 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) qemu_del_timer(s->tm); s->gcr = 0x0004; + s->drq = 0x00000000; s->run_count = 0; s->lcd_ch.src = emiff; s->lcd_ch.condition = 0; @@ -1002,6 +1011,7 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]); mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 32); omap_dma_reset(s); + omap_dma_clk_update(s, 0, 1); iomemtype = cpu_register_io_memory(0, omap_dma_readfn, omap_dma_writefn, s); |