Add PowerPC power-management state check callback.
[qemu] / hw / omap.c
index 0684a2d..ccd8f4e 100644 (file)
--- a/hw/omap.c
+++ b/hw/omap.c
 #include "arm_pic.h"
 
 /* Should signal the TCMI */
-static uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
+uint32_t omap_badwidth_read16(void *opaque, target_phys_addr_t addr)
 {
     OMAP_16B_REG(addr);
     return 0;
 }
 
-static void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
+void omap_badwidth_write16(void *opaque, target_phys_addr_t addr,
                 uint32_t value)
 {
     OMAP_16B_REG(addr);
 }
 
-static uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
+uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr)
 {
     OMAP_32B_REG(addr);
     return 0;
 }
 
-static void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
+void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
                 uint32_t value)
 {
     OMAP_32B_REG(addr);
 }
 
-#define likely
-#define unlikely
-
 /* Interrupt Handlers */
 struct omap_intr_handler_s {
     qemu_irq *pins;
@@ -403,6 +400,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 +509,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 +591,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 +606,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 +750,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 +949,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 +979,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 +1008,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);
@@ -2806,6 +2813,7 @@ static void omap_mpu_reset(void *opaque)
     omap_uart_reset(mpu->uart1);
     omap_uart_reset(mpu->uart2);
     omap_uart_reset(mpu->uart3);
+    omap_mmc_reset(mpu->mmc);
     cpu_reset(mpu->env);
 }
 
@@ -2911,6 +2919,9 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
     omap_dpll_init(&s->dpll[1], 0xfffed000, omap_findclk(s, "dpll2"));
     omap_dpll_init(&s->dpll[2], 0xfffed100, omap_findclk(s, "dpll3"));
 
+    s->mmc = omap_mmc_init(0xfffb7800, s->irq[1][OMAP_INT_OQN],
+                    &s->drq[OMAP_DMA_MMC_TX], omap_findclk(s, "mmc_ck"));
+
     qemu_register_reset(omap_mpu_reset, s);
     s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];