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