summary refs log tree commit diff stats
path: root/hw/omap_lcdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/omap_lcdc.c')
-rw-r--r--hw/omap_lcdc.c96
1 files changed, 31 insertions, 65 deletions
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index a02d99d27a..6a91b27d43 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -20,6 +20,7 @@
 #include "hw.h"
 #include "console.h"
 #include "omap.h"
+#include "framebuffer.h"
 
 struct omap_lcd_panel_s {
     qemu_irq irq;
@@ -68,8 +69,7 @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
 
 #include "pixel_ops.h"
 
-typedef void draw_line_func(
-                uint8_t *d, const uint8_t *s, int width, const uint16_t *pal);
+#define draw_line_func drawfn
 
 #define DEPTH 8
 #include "omap_lcd_template.h"
@@ -80,31 +80,31 @@ typedef void draw_line_func(
 #define DEPTH 32
 #include "omap_lcd_template.h"
 
-static draw_line_func *draw_line_table2[33] = {
+static draw_line_func draw_line_table2[33] = {
     [0 ... 32]	= 0,
     [8]		= draw_line2_8,
     [15]	= draw_line2_15,
     [16]	= draw_line2_16,
     [32]	= draw_line2_32,
-}, *draw_line_table4[33] = {
+}, draw_line_table4[33] = {
     [0 ... 32]	= 0,
     [8]		= draw_line4_8,
     [15]	= draw_line4_15,
     [16]	= draw_line4_16,
     [32]	= draw_line4_32,
-}, *draw_line_table8[33] = {
+}, draw_line_table8[33] = {
     [0 ... 32]	= 0,
     [8]		= draw_line8_8,
     [15]	= draw_line8_15,
     [16]	= draw_line8_16,
     [32]	= draw_line8_32,
-}, *draw_line_table12[33] = {
+}, draw_line_table12[33] = {
     [0 ... 32]	= 0,
     [8]		= draw_line12_8,
     [15]	= draw_line12_15,
     [16]	= draw_line12_16,
     [32]	= draw_line12_32,
-}, *draw_line_table16[33] = {
+}, draw_line_table16[33] = {
     [0 ... 32]	= 0,
     [8]		= draw_line16_8,
     [15]	= draw_line16_15,
@@ -115,11 +115,10 @@ static draw_line_func *draw_line_table2[33] = {
 static void omap_update_display(void *opaque)
 {
     struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
-    draw_line_func *draw_line;
-    int size, dirty[2], minline, maxline, height;
-    int line, width, linesize, step, bpp, frame_offset;
-    ram_addr_t frame_base, scanline, newline, x;
-    uint8_t *s, *d;
+    draw_line_func draw_line;
+    int size, height, first, last;
+    int width, linesize, step, bpp, frame_offset;
+    target_phys_addr_t frame_base;
 
     if (!omap_lcd || omap_lcd->plm == 1 ||
                     !omap_lcd->enable || !ds_get_bits_per_pixel(omap_lcd->state))
@@ -127,9 +126,9 @@ static void omap_update_display(void *opaque)
 
     frame_offset = 0;
     if (omap_lcd->plm != 2) {
-        memcpy(omap_lcd->palette, phys_ram_base +
-                        omap_lcd->dma->phys_framebuffer[
-                        omap_lcd->dma->current_frame], 0x200);
+        cpu_physical_memory_read(omap_lcd->dma->phys_framebuffer[
+                                  omap_lcd->dma->current_frame],
+                                 (void *)omap_lcd->palette, 0x200);
         switch (omap_lcd->palette[0] >> 12 & 7) {
         case 3 ... 7:
             frame_offset += 0x200;
@@ -202,49 +201,28 @@ static void omap_update_display(void *opaque)
     if (!ds_get_bits_per_pixel(omap_lcd->state))
         return;
 
-    line = 0;
+    first = 0;
     height = omap_lcd->height;
     if (omap_lcd->subpanel & (1 << 31)) {
         if (omap_lcd->subpanel & (1 << 29))
-            line = (omap_lcd->subpanel >> 16) & 0x3ff;
+            first = (omap_lcd->subpanel >> 16) & 0x3ff;
         else
             height = (omap_lcd->subpanel >> 16) & 0x3ff;
         /* TODO: fill the rest of the panel with DPD */
     }
+
     step = width * bpp >> 3;
-    scanline = frame_base + step * line;
-    s = (uint8_t *) (phys_ram_base + scanline);
-    d = ds_get_data(omap_lcd->state);
     linesize = ds_get_linesize(omap_lcd->state);
-
-    dirty[0] = dirty[1] =
-            cpu_physical_memory_get_dirty(scanline, VGA_DIRTY_FLAG);
-    minline = height;
-    maxline = line;
-    for (; line < height; line ++) {
-        newline = scanline + step;
-        for (x = scanline + TARGET_PAGE_SIZE; x < newline;
-                        x += TARGET_PAGE_SIZE) {
-            dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG);
-            dirty[0] |= dirty[1];
-        }
-        if (dirty[0] || omap_lcd->invalidate) {
-            draw_line(d, s, width, omap_lcd->palette);
-            if (line < minline)
-                minline = line;
-            maxline = line + 1;
-        }
-        scanline = newline;
-        dirty[0] = dirty[1];
-        s += step;
-        d += linesize;
-    }
-
-    if (maxline >= minline) {
-        dpy_update(omap_lcd->state, 0, minline, width, maxline);
-        cpu_physical_memory_reset_dirty(frame_base + step * minline,
-                        frame_base + step * maxline, VGA_DIRTY_FLAG);
+    framebuffer_update_display(omap_lcd->state,
+                               frame_base, width, height,
+                               step, linesize, 0,
+                               omap_lcd->invalidate,
+                               draw_line, omap_lcd->palette,
+                               &first, &last);
+    if (first >= 0) {
+        dpy_update(omap_lcd->state, 0, first, width, last - first + 1);
     }
+    omap_lcd->invalidate = 0;
 }
 
 static int ppm_save(const char *filename, uint8_t *data,
@@ -336,25 +314,13 @@ static void omap_lcd_update(struct omap_lcd_panel_s *s) {
         return;
     }
 
-     if (s->dma->src == imif) {
-        /* Framebuffers are in SRAM */
-        s->dma->phys_framebuffer[0] = s->imif_base +
-                s->dma->src_f1_top - OMAP_IMIF_BASE;
-
-        s->dma->phys_framebuffer[1] = s->imif_base +
-                s->dma->src_f2_top - OMAP_IMIF_BASE;
-    } else {
-        /* Framebuffers are in RAM */
-        s->dma->phys_framebuffer[0] = s->emiff_base +
-                s->dma->src_f1_top - OMAP_EMIFF_BASE;
-
-        s->dma->phys_framebuffer[1] = s->emiff_base +
-                s->dma->src_f2_top - OMAP_EMIFF_BASE;
-    }
+    s->dma->phys_framebuffer[0] = s->dma->src_f1_top;
+    s->dma->phys_framebuffer[1] = s->dma->src_f2_top;
 
     if (s->plm != 2 && !s->palette_done) {
-        memcpy(s->palette, phys_ram_base +
-                s->dma->phys_framebuffer[s->dma->current_frame], 0x200);
+        cpu_physical_memory_read(
+            s->dma->phys_framebuffer[s->dma->current_frame],
+            (void *)s->palette, 0x200);
         s->palette_done = 1;
         omap_lcd_interrupts(s);
     }