summary refs log tree commit diff stats
path: root/hw/pxa2xx_lcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/pxa2xx_lcd.c')
-rw-r--r--hw/pxa2xx_lcd.c117
1 files changed, 29 insertions, 88 deletions
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 5c2eff10e7..49eafa7226 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -13,8 +13,7 @@
 #include "pixel_ops.h"
 /* FIXME: For graphic_rotate. Should probably be done in common code.  */
 #include "sysemu.h"
-
-typedef void (*drawfn)(uint32_t *, uint8_t *, const uint8_t *, int, int);
+#include "framebuffer.h"
 
 struct pxa2xx_lcdc_s {
     qemu_irq irq;
@@ -56,7 +55,7 @@ struct pxa2xx_lcdc_s {
         int up;
         uint8_t palette[1024];
         uint8_t pbuffer[1024];
-        void (*redraw)(struct pxa2xx_lcdc_s *s, uint8_t *fb,
+        void (*redraw)(struct pxa2xx_lcdc_s *s, target_phys_addr_t addr,
                         int *miny, int *maxy);
 
         target_phys_addr_t descriptor;
@@ -669,18 +668,15 @@ static void pxa2xx_palette_parse(struct pxa2xx_lcdc_s *s, int ch, int bpp)
 }
 
 static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s,
-                uint8_t *fb, int *miny, int *maxy)
+                target_phys_addr_t addr, int *miny, int *maxy)
 {
-    int y, src_width, dest_width, dirty[2];
-    uint8_t *src, *dest;
-    ram_addr_t x, addr, new_addr, start, end;
+    int src_width, dest_width;
     drawfn fn = 0;
     if (s->dest_width)
         fn = s->line_fn[s->transp][s->bpp];
     if (!fn)
         return;
 
-    src = fb;
     src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
     if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
         src_width *= 3;
@@ -689,54 +685,25 @@ static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s,
     else if (s->bpp > pxa_lcdc_8bpp)
         src_width *= 2;
 
-    dest = ds_get_data(s->ds);
     dest_width = s->xres * s->dest_width;
-
-    addr = (ram_addr_t) (fb - phys_ram_base);
-    start = addr + s->yres * src_width;
-    end = addr;
-    dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG);
-    for (y = 0; y < s->yres; y ++) {
-        new_addr = addr + src_width;
-        for (x = addr + TARGET_PAGE_SIZE; x < new_addr;
-                        x += TARGET_PAGE_SIZE) {
-            dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
-            dirty[0] |= dirty[1];
-        }
-        if (dirty[0] || s->invalidated) {
-            fn((uint32_t *) s->dma_ch[0].palette,
-                            dest, src, s->xres, s->dest_width);
-            if (addr < start)
-                start = addr;
-            end = new_addr;
-            if (y < *miny)
-                *miny = y;
-            if (y >= *maxy)
-                *maxy = y + 1;
-        }
-        addr = new_addr;
-        dirty[0] = dirty[1];
-        src += src_width;
-        dest += dest_width;
-    }
-
-    if (end > start)
-        cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG);
+    *miny = 0;
+    framebuffer_update_display(s->ds,
+                               addr, s->xres, s->yres,
+                               src_width, dest_width, s->dest_width,
+                               s->invalidated,
+                               fn, s->dma_ch[0].palette, miny, maxy);
 }
 
 static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s,
-                uint8_t *fb, int *miny, int *maxy)
+               target_phys_addr_t addr, int *miny, int *maxy)
 {
-    int y, src_width, dest_width, dirty[2];
-    uint8_t *src, *dest;
-    ram_addr_t x, addr, new_addr, start, end;
+    int src_width, dest_width;
     drawfn fn = 0;
     if (s->dest_width)
         fn = s->line_fn[s->transp][s->bpp];
     if (!fn)
         return;
 
-    src = fb;
     src_width = (s->xres + 3) & ~3;     /* Pad to a 4 pixels multiple */
     if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp)
         src_width *= 3;
@@ -746,38 +713,13 @@ static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s,
         src_width *= 2;
 
     dest_width = s->yres * s->dest_width;
-    dest = ds_get_data(s->ds) + dest_width * (s->xres - 1);
-
-    addr = (ram_addr_t) (fb - phys_ram_base);
-    start = addr + s->yres * src_width;
-    end = addr;
-    x = addr + TARGET_PAGE_SIZE;
-    dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(start, VGA_DIRTY_FLAG);
-    for (y = 0; y < s->yres; y ++) {
-        new_addr = addr + src_width;
-        for (; x < new_addr; x += TARGET_PAGE_SIZE) {
-            dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
-            dirty[0] |= dirty[1];
-        }
-        if (dirty[0] || s->invalidated) {
-            fn((uint32_t *) s->dma_ch[0].palette,
-                            dest, src, s->xres, -dest_width);
-            if (addr < start)
-                start = addr;
-            end = new_addr;
-            if (y < *miny)
-                *miny = y;
-            if (y >= *maxy)
-                *maxy = y + 1;
-        }
-        addr = new_addr;
-        dirty[0] = dirty[1];
-        src += src_width;
-        dest += s->dest_width;
-    }
-
-    if (end > start)
-        cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG);
+    *miny = 0;
+    framebuffer_update_display(s->ds,
+                               addr, s->xres, s->yres,
+                               src_width, s->dest_width, -dest_width,
+                               s->invalidated,
+                               fn, s->dma_ch[0].palette,
+                               miny, maxy);
 }
 
 static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s)
@@ -803,7 +745,6 @@ static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s)
 static void pxa2xx_update_display(void *opaque)
 {
     struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque;
-    uint8_t *fb;
     target_phys_addr_t fbptr;
     int miny, maxy;
     int ch;
@@ -829,13 +770,11 @@ static void pxa2xx_update_display(void *opaque)
                 pxa2xx_dma_ber_set(s, ch);
                 continue;
             }
-            fbptr -= PXA2XX_SDRAM_BASE;
-            fb = phys_ram_base + fbptr;
 
             if (s->dma_ch[ch].command & LDCMD_PAL) {
-                memcpy(s->dma_ch[ch].pbuffer, fb,
-                                MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
-                                sizeof(s->dma_ch[ch].pbuffer)));
+                cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer,
+                    MAX(LDCMD_LENGTH(s->dma_ch[ch].command),
+                        sizeof(s->dma_ch[ch].pbuffer)));
                 pxa2xx_palette_parse(s, ch, s->bpp);
             } else {
                 /* Do we need to reparse palette */
@@ -845,7 +784,7 @@ static void pxa2xx_update_display(void *opaque)
                 /* ACK frame start */
                 pxa2xx_dma_sof_set(s, ch);
 
-                s->dma_ch[ch].redraw(s, fb, &miny, &maxy);
+                s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy);
                 s->invalidated = 0;
 
                 /* ACK frame completed */
@@ -859,10 +798,12 @@ static void pxa2xx_update_display(void *opaque)
         s->status[0] |= LCSR0_LDD;
     }
 
-    if (s->orientation)
-        dpy_update(s->ds, miny, 0, maxy, s->xres);
-    else
-        dpy_update(s->ds, 0, miny, s->xres, maxy);
+    if (miny >= 0) {
+        if (s->orientation)
+            dpy_update(s->ds, miny, 0, maxy, s->xres);
+        else
+            dpy_update(s->ds, 0, miny, s->xres, maxy);
+    }
     pxa2xx_lcdc_int_update(s);
 
     qemu_irq_raise(s->vsync_cb);