aboutsummaryrefslogtreecommitdiff
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);