diff options
Diffstat (limited to 'hw/pxa2xx_lcd.c')
-rw-r--r-- | hw/pxa2xx_lcd.c | 117 |
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); |