Commit 714fa308a3f86e1dc55021ff1282c1afe6954d3d
1 parent
602dafcf
Implement and use shared memory framebuffer device rendering reoutine.
Use DMA mapping API. Signed-off-by: Paul Brook <paul@codesourcery.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6965 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
10 changed files
with
253 additions
and
231 deletions
Makefile.target
| @@ -672,6 +672,7 @@ OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o | @@ -672,6 +672,7 @@ OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o | ||
| 672 | OBJS+= tsc2005.o bt-hci-csr.o | 672 | OBJS+= tsc2005.o bt-hci-csr.o |
| 673 | OBJS+= mst_fpga.o mainstone.o | 673 | OBJS+= mst_fpga.o mainstone.o |
| 674 | OBJS+= musicpal.o pflash_cfi02.o | 674 | OBJS+= musicpal.o pflash_cfi02.o |
| 675 | +OBJS+= framebuffer.o | ||
| 675 | CPPFLAGS += -DHAS_AUDIO | 676 | CPPFLAGS += -DHAS_AUDIO |
| 676 | endif | 677 | endif |
| 677 | ifeq ($(TARGET_BASE_ARCH), sh4) | 678 | ifeq ($(TARGET_BASE_ARCH), sh4) |
hw/framebuffer.c
0 → 100644
| 1 | +/* | ||
| 2 | + * Framebuffer device helper routines | ||
| 3 | + * | ||
| 4 | + * Copyright (c) 2009 CodeSourcery | ||
| 5 | + * Written by Paul Brook <paul@codesourcery.com> | ||
| 6 | + * | ||
| 7 | + * This code is licensed under the GNU GPLv2. | ||
| 8 | + */ | ||
| 9 | + | ||
| 10 | +/* TODO: | ||
| 11 | + - Do something similar for framebuffers with local ram | ||
| 12 | + - Handle rotation here instead of hacking dest_pitch | ||
| 13 | + - Use common pixel conversion routines instead of per-device drawfn | ||
| 14 | + - Remove all DisplayState knowledge from devices. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +#include "hw.h" | ||
| 18 | +#include "console.h" | ||
| 19 | +#include "framebuffer.h" | ||
| 20 | +#include "kvm.h" | ||
| 21 | + | ||
| 22 | +/* Render an image from a shared memory framebuffer. */ | ||
| 23 | + | ||
| 24 | +void framebuffer_update_display( | ||
| 25 | + DisplayState *ds, | ||
| 26 | + target_phys_addr_t base, | ||
| 27 | + int cols, /* Width in pixels. */ | ||
| 28 | + int rows, /* Leight in pixels. */ | ||
| 29 | + int src_width, /* Length of source line, in bytes. */ | ||
| 30 | + int dest_row_pitch, /* Bytes between adjacent horizontal output pixels. */ | ||
| 31 | + int dest_col_pitch, /* Bytes between adjacent vertical output pixels. */ | ||
| 32 | + int invalidate, /* nonzero to redraw the whole image. */ | ||
| 33 | + drawfn fn, | ||
| 34 | + void *opaque, | ||
| 35 | + int *first_row, /* Input and output. */ | ||
| 36 | + int *last_row /* Output only */) | ||
| 37 | +{ | ||
| 38 | + target_phys_addr_t src_len; | ||
| 39 | + uint8_t *dest; | ||
| 40 | + uint8_t *src; | ||
| 41 | + uint8_t *src_base; | ||
| 42 | + int first, last = 0; | ||
| 43 | + int dirty; | ||
| 44 | + int i; | ||
| 45 | + ram_addr_t addr; | ||
| 46 | + ram_addr_t pd; | ||
| 47 | + ram_addr_t pd2; | ||
| 48 | + | ||
| 49 | + i = *first_row; | ||
| 50 | + *first_row = -1; | ||
| 51 | + src_len = src_width * rows; | ||
| 52 | + | ||
| 53 | + if (kvm_enabled()) { | ||
| 54 | + kvm_physical_sync_dirty_bitmap(base, src_len); | ||
| 55 | + } | ||
| 56 | + pd = cpu_get_physical_page_desc(base); | ||
| 57 | + pd2 = cpu_get_physical_page_desc(base + src_len - 1); | ||
| 58 | + /* We should reall check that this is a continuous ram region. | ||
| 59 | + Instead we just check that the first and last pages are | ||
| 60 | + both ram, and the right distance apart. */ | ||
| 61 | + if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM | ||
| 62 | + || (pd2 & ~TARGET_PAGE_MASK) > IO_MEM_ROM) { | ||
| 63 | + return; | ||
| 64 | + } | ||
| 65 | + pd = (pd & TARGET_PAGE_MASK) + (base & ~TARGET_PAGE_MASK); | ||
| 66 | + if (((pd + src_len - 1) & TARGET_PAGE_MASK) != (pd2 & TARGET_PAGE_MASK)) { | ||
| 67 | + return; | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + src_base = cpu_physical_memory_map(base, &src_len, 0); | ||
| 71 | + /* If we can't map the framebuffer then bail. We could try harder, | ||
| 72 | + but it's not really worth it as dirty flag tracking will probably | ||
| 73 | + already have failed above. */ | ||
| 74 | + if (!src_base) | ||
| 75 | + return; | ||
| 76 | + if (src_len != src_width * rows) { | ||
| 77 | + cpu_physical_memory_unmap(src_base, src_len, 0, 0); | ||
| 78 | + return; | ||
| 79 | + } | ||
| 80 | + src = src_base; | ||
| 81 | + dest = ds_get_data(ds); | ||
| 82 | + if (dest_col_pitch < 0) | ||
| 83 | + dest -= dest_col_pitch * (cols - 1); | ||
| 84 | + first = -1; | ||
| 85 | + addr = pd; | ||
| 86 | + | ||
| 87 | + addr += i * src_width; | ||
| 88 | + src += i * src_width; | ||
| 89 | + dest += i * dest_row_pitch; | ||
| 90 | + | ||
| 91 | + for (; i < rows; i++) { | ||
| 92 | + target_phys_addr_t dirty_offset; | ||
| 93 | + dirty = 0; | ||
| 94 | + dirty_offset = 0; | ||
| 95 | + while (addr + dirty_offset < TARGET_PAGE_ALIGN(addr + src_width)) { | ||
| 96 | + dirty |= cpu_physical_memory_get_dirty(addr + dirty_offset, | ||
| 97 | + VGA_DIRTY_FLAG); | ||
| 98 | + dirty_offset += TARGET_PAGE_SIZE; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + if (dirty || invalidate) { | ||
| 102 | + fn(opaque, dest, src, cols, dest_col_pitch); | ||
| 103 | + if (first == -1) | ||
| 104 | + first = i; | ||
| 105 | + last = i; | ||
| 106 | + } | ||
| 107 | + addr += src_width; | ||
| 108 | + src += src_width; | ||
| 109 | + dest += dest_row_pitch; | ||
| 110 | + } | ||
| 111 | + cpu_physical_memory_unmap(src_base, src_len, 0, 0); | ||
| 112 | + if (first < 0) { | ||
| 113 | + return; | ||
| 114 | + } | ||
| 115 | + cpu_physical_memory_reset_dirty(pd, pd + src_len, VGA_DIRTY_FLAG); | ||
| 116 | + *first_row = first; | ||
| 117 | + *last_row = last; | ||
| 118 | + return; | ||
| 119 | +} |
hw/framebuffer.h
0 → 100644
| 1 | +#ifndef QEMU_FRAMEBUFFER_H | ||
| 2 | +#define QEMU_FRAMEBUFFER_H | ||
| 3 | + | ||
| 4 | +/* Framebuffer device helper routines. */ | ||
| 5 | + | ||
| 6 | +typedef void (*drawfn)(void *, uint8_t *, const uint8_t *, int, int); | ||
| 7 | + | ||
| 8 | +void framebuffer_update_display( | ||
| 9 | + DisplayState *ds, | ||
| 10 | + target_phys_addr_t base, | ||
| 11 | + int cols, | ||
| 12 | + int rows, | ||
| 13 | + int src_width, | ||
| 14 | + int dest_row_pitch, | ||
| 15 | + int dest_col_pitch, | ||
| 16 | + int invalidate, | ||
| 17 | + drawfn fn, | ||
| 18 | + void *opaque, | ||
| 19 | + int *first_row, | ||
| 20 | + int *last_row); | ||
| 21 | + | ||
| 22 | +#endif |
hw/omap.h
| @@ -490,7 +490,7 @@ struct omap_dma_lcd_channel_s { | @@ -490,7 +490,7 @@ struct omap_dma_lcd_channel_s { | ||
| 490 | int dual; | 490 | int dual; |
| 491 | 491 | ||
| 492 | int current_frame; | 492 | int current_frame; |
| 493 | - ram_addr_t phys_framebuffer[2]; | 493 | + target_phys_addr_t phys_framebuffer[2]; |
| 494 | qemu_irq irq; | 494 | qemu_irq irq; |
| 495 | struct omap_mpu_state_s *mpu; | 495 | struct omap_mpu_state_s *mpu; |
| 496 | } *omap_dma_get_lcdch(struct soc_dma_s *s); | 496 | } *omap_dma_get_lcdch(struct soc_dma_s *s); |
hw/omap_lcd_template.h
| @@ -43,9 +43,10 @@ | @@ -43,9 +43,10 @@ | ||
| 43 | /* | 43 | /* |
| 44 | * 2-bit colour | 44 | * 2-bit colour |
| 45 | */ | 45 | */ |
| 46 | -static void glue(draw_line2_, DEPTH)( | ||
| 47 | - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal) | 46 | +static void glue(draw_line2_, DEPTH)(void *opaque, |
| 47 | + uint8_t *d, const uint8_t *s, int width, int deststep) | ||
| 48 | { | 48 | { |
| 49 | + uint16_t *pal = opaque; | ||
| 49 | uint8_t v, r, g, b; | 50 | uint8_t v, r, g, b; |
| 50 | 51 | ||
| 51 | do { | 52 | do { |
| @@ -81,9 +82,10 @@ static void glue(draw_line2_, DEPTH)( | @@ -81,9 +82,10 @@ static void glue(draw_line2_, DEPTH)( | ||
| 81 | /* | 82 | /* |
| 82 | * 4-bit colour | 83 | * 4-bit colour |
| 83 | */ | 84 | */ |
| 84 | -static void glue(draw_line4_, DEPTH)( | ||
| 85 | - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal) | 85 | +static void glue(draw_line4_, DEPTH)(void *opaque, |
| 86 | + uint8_t *d, const uint8_t *s, int width, int deststep) | ||
| 86 | { | 87 | { |
| 88 | + uint16_t *pal = opaque; | ||
| 87 | uint8_t v, r, g, b; | 89 | uint8_t v, r, g, b; |
| 88 | 90 | ||
| 89 | do { | 91 | do { |
| @@ -107,9 +109,10 @@ static void glue(draw_line4_, DEPTH)( | @@ -107,9 +109,10 @@ static void glue(draw_line4_, DEPTH)( | ||
| 107 | /* | 109 | /* |
| 108 | * 8-bit colour | 110 | * 8-bit colour |
| 109 | */ | 111 | */ |
| 110 | -static void glue(draw_line8_, DEPTH)( | ||
| 111 | - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal) | 112 | +static void glue(draw_line8_, DEPTH)(void *opaque, |
| 113 | + uint8_t *d, const uint8_t *s, int width, int deststep) | ||
| 112 | { | 114 | { |
| 115 | + uint16_t *pal = opaque; | ||
| 113 | uint8_t v, r, g, b; | 116 | uint8_t v, r, g, b; |
| 114 | 117 | ||
| 115 | do { | 118 | do { |
| @@ -126,8 +129,8 @@ static void glue(draw_line8_, DEPTH)( | @@ -126,8 +129,8 @@ static void glue(draw_line8_, DEPTH)( | ||
| 126 | /* | 129 | /* |
| 127 | * 12-bit colour | 130 | * 12-bit colour |
| 128 | */ | 131 | */ |
| 129 | -static void glue(draw_line12_, DEPTH)( | ||
| 130 | - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal) | 132 | +static void glue(draw_line12_, DEPTH)(void *opaque, |
| 133 | + uint8_t *d, const uint8_t *s, int width, int deststep) | ||
| 131 | { | 134 | { |
| 132 | uint16_t v; | 135 | uint16_t v; |
| 133 | uint8_t r, g, b; | 136 | uint8_t r, g, b; |
| @@ -146,8 +149,8 @@ static void glue(draw_line12_, DEPTH)( | @@ -146,8 +149,8 @@ static void glue(draw_line12_, DEPTH)( | ||
| 146 | /* | 149 | /* |
| 147 | * 16-bit colour | 150 | * 16-bit colour |
| 148 | */ | 151 | */ |
| 149 | -static void glue(draw_line16_, DEPTH)( | ||
| 150 | - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal) | 152 | +static void glue(draw_line16_, DEPTH)(void *opaque, |
| 153 | + uint8_t *d, const uint8_t *s, int width, int deststep) | ||
| 151 | { | 154 | { |
| 152 | #if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) | 155 | #if DEPTH == 16 && defined(WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) |
| 153 | memcpy(d, s, width * 2); | 156 | memcpy(d, s, width * 2); |
hw/omap_lcdc.c
| @@ -20,6 +20,7 @@ | @@ -20,6 +20,7 @@ | ||
| 20 | #include "hw.h" | 20 | #include "hw.h" |
| 21 | #include "console.h" | 21 | #include "console.h" |
| 22 | #include "omap.h" | 22 | #include "omap.h" |
| 23 | +#include "framebuffer.h" | ||
| 23 | 24 | ||
| 24 | struct omap_lcd_panel_s { | 25 | struct omap_lcd_panel_s { |
| 25 | qemu_irq irq; | 26 | qemu_irq irq; |
| @@ -68,8 +69,7 @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s) | @@ -68,8 +69,7 @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s) | ||
| 68 | 69 | ||
| 69 | #include "pixel_ops.h" | 70 | #include "pixel_ops.h" |
| 70 | 71 | ||
| 71 | -typedef void draw_line_func( | ||
| 72 | - uint8_t *d, const uint8_t *s, int width, const uint16_t *pal); | 72 | +#define draw_line_func drawfn |
| 73 | 73 | ||
| 74 | #define DEPTH 8 | 74 | #define DEPTH 8 |
| 75 | #include "omap_lcd_template.h" | 75 | #include "omap_lcd_template.h" |
| @@ -80,31 +80,31 @@ typedef void draw_line_func( | @@ -80,31 +80,31 @@ typedef void draw_line_func( | ||
| 80 | #define DEPTH 32 | 80 | #define DEPTH 32 |
| 81 | #include "omap_lcd_template.h" | 81 | #include "omap_lcd_template.h" |
| 82 | 82 | ||
| 83 | -static draw_line_func *draw_line_table2[33] = { | 83 | +static draw_line_func draw_line_table2[33] = { |
| 84 | [0 ... 32] = 0, | 84 | [0 ... 32] = 0, |
| 85 | [8] = draw_line2_8, | 85 | [8] = draw_line2_8, |
| 86 | [15] = draw_line2_15, | 86 | [15] = draw_line2_15, |
| 87 | [16] = draw_line2_16, | 87 | [16] = draw_line2_16, |
| 88 | [32] = draw_line2_32, | 88 | [32] = draw_line2_32, |
| 89 | -}, *draw_line_table4[33] = { | 89 | +}, draw_line_table4[33] = { |
| 90 | [0 ... 32] = 0, | 90 | [0 ... 32] = 0, |
| 91 | [8] = draw_line4_8, | 91 | [8] = draw_line4_8, |
| 92 | [15] = draw_line4_15, | 92 | [15] = draw_line4_15, |
| 93 | [16] = draw_line4_16, | 93 | [16] = draw_line4_16, |
| 94 | [32] = draw_line4_32, | 94 | [32] = draw_line4_32, |
| 95 | -}, *draw_line_table8[33] = { | 95 | +}, draw_line_table8[33] = { |
| 96 | [0 ... 32] = 0, | 96 | [0 ... 32] = 0, |
| 97 | [8] = draw_line8_8, | 97 | [8] = draw_line8_8, |
| 98 | [15] = draw_line8_15, | 98 | [15] = draw_line8_15, |
| 99 | [16] = draw_line8_16, | 99 | [16] = draw_line8_16, |
| 100 | [32] = draw_line8_32, | 100 | [32] = draw_line8_32, |
| 101 | -}, *draw_line_table12[33] = { | 101 | +}, draw_line_table12[33] = { |
| 102 | [0 ... 32] = 0, | 102 | [0 ... 32] = 0, |
| 103 | [8] = draw_line12_8, | 103 | [8] = draw_line12_8, |
| 104 | [15] = draw_line12_15, | 104 | [15] = draw_line12_15, |
| 105 | [16] = draw_line12_16, | 105 | [16] = draw_line12_16, |
| 106 | [32] = draw_line12_32, | 106 | [32] = draw_line12_32, |
| 107 | -}, *draw_line_table16[33] = { | 107 | +}, draw_line_table16[33] = { |
| 108 | [0 ... 32] = 0, | 108 | [0 ... 32] = 0, |
| 109 | [8] = draw_line16_8, | 109 | [8] = draw_line16_8, |
| 110 | [15] = draw_line16_15, | 110 | [15] = draw_line16_15, |
| @@ -115,11 +115,10 @@ static draw_line_func *draw_line_table2[33] = { | @@ -115,11 +115,10 @@ static draw_line_func *draw_line_table2[33] = { | ||
| 115 | static void omap_update_display(void *opaque) | 115 | static void omap_update_display(void *opaque) |
| 116 | { | 116 | { |
| 117 | struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque; | 117 | struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque; |
| 118 | - draw_line_func *draw_line; | ||
| 119 | - int size, dirty[2], minline, maxline, height; | ||
| 120 | - int line, width, linesize, step, bpp, frame_offset; | ||
| 121 | - ram_addr_t frame_base, scanline, newline, x; | ||
| 122 | - uint8_t *s, *d; | 118 | + draw_line_func draw_line; |
| 119 | + int size, height, first, last; | ||
| 120 | + int width, linesize, step, bpp, frame_offset; | ||
| 121 | + target_phys_addr_t frame_base; | ||
| 123 | 122 | ||
| 124 | if (!omap_lcd || omap_lcd->plm == 1 || | 123 | if (!omap_lcd || omap_lcd->plm == 1 || |
| 125 | !omap_lcd->enable || !ds_get_bits_per_pixel(omap_lcd->state)) | 124 | !omap_lcd->enable || !ds_get_bits_per_pixel(omap_lcd->state)) |
| @@ -127,9 +126,9 @@ static void omap_update_display(void *opaque) | @@ -127,9 +126,9 @@ static void omap_update_display(void *opaque) | ||
| 127 | 126 | ||
| 128 | frame_offset = 0; | 127 | frame_offset = 0; |
| 129 | if (omap_lcd->plm != 2) { | 128 | if (omap_lcd->plm != 2) { |
| 130 | - memcpy(omap_lcd->palette, phys_ram_base + | ||
| 131 | - omap_lcd->dma->phys_framebuffer[ | ||
| 132 | - omap_lcd->dma->current_frame], 0x200); | 129 | + cpu_physical_memory_read(omap_lcd->dma->phys_framebuffer[ |
| 130 | + omap_lcd->dma->current_frame], | ||
| 131 | + (void *)omap_lcd->palette, 0x200); | ||
| 133 | switch (omap_lcd->palette[0] >> 12 & 7) { | 132 | switch (omap_lcd->palette[0] >> 12 & 7) { |
| 134 | case 3 ... 7: | 133 | case 3 ... 7: |
| 135 | frame_offset += 0x200; | 134 | frame_offset += 0x200; |
| @@ -202,49 +201,28 @@ static void omap_update_display(void *opaque) | @@ -202,49 +201,28 @@ static void omap_update_display(void *opaque) | ||
| 202 | if (!ds_get_bits_per_pixel(omap_lcd->state)) | 201 | if (!ds_get_bits_per_pixel(omap_lcd->state)) |
| 203 | return; | 202 | return; |
| 204 | 203 | ||
| 205 | - line = 0; | 204 | + first = 0; |
| 206 | height = omap_lcd->height; | 205 | height = omap_lcd->height; |
| 207 | if (omap_lcd->subpanel & (1 << 31)) { | 206 | if (omap_lcd->subpanel & (1 << 31)) { |
| 208 | if (omap_lcd->subpanel & (1 << 29)) | 207 | if (omap_lcd->subpanel & (1 << 29)) |
| 209 | - line = (omap_lcd->subpanel >> 16) & 0x3ff; | 208 | + first = (omap_lcd->subpanel >> 16) & 0x3ff; |
| 210 | else | 209 | else |
| 211 | height = (omap_lcd->subpanel >> 16) & 0x3ff; | 210 | height = (omap_lcd->subpanel >> 16) & 0x3ff; |
| 212 | /* TODO: fill the rest of the panel with DPD */ | 211 | /* TODO: fill the rest of the panel with DPD */ |
| 213 | } | 212 | } |
| 213 | + | ||
| 214 | step = width * bpp >> 3; | 214 | step = width * bpp >> 3; |
| 215 | - scanline = frame_base + step * line; | ||
| 216 | - s = (uint8_t *) (phys_ram_base + scanline); | ||
| 217 | - d = ds_get_data(omap_lcd->state); | ||
| 218 | linesize = ds_get_linesize(omap_lcd->state); | 215 | linesize = ds_get_linesize(omap_lcd->state); |
| 219 | - | ||
| 220 | - dirty[0] = dirty[1] = | ||
| 221 | - cpu_physical_memory_get_dirty(scanline, VGA_DIRTY_FLAG); | ||
| 222 | - minline = height; | ||
| 223 | - maxline = line; | ||
| 224 | - for (; line < height; line ++) { | ||
| 225 | - newline = scanline + step; | ||
| 226 | - for (x = scanline + TARGET_PAGE_SIZE; x < newline; | ||
| 227 | - x += TARGET_PAGE_SIZE) { | ||
| 228 | - dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG); | ||
| 229 | - dirty[0] |= dirty[1]; | ||
| 230 | - } | ||
| 231 | - if (dirty[0] || omap_lcd->invalidate) { | ||
| 232 | - draw_line(d, s, width, omap_lcd->palette); | ||
| 233 | - if (line < minline) | ||
| 234 | - minline = line; | ||
| 235 | - maxline = line + 1; | ||
| 236 | - } | ||
| 237 | - scanline = newline; | ||
| 238 | - dirty[0] = dirty[1]; | ||
| 239 | - s += step; | ||
| 240 | - d += linesize; | ||
| 241 | - } | ||
| 242 | - | ||
| 243 | - if (maxline >= minline) { | ||
| 244 | - dpy_update(omap_lcd->state, 0, minline, width, maxline); | ||
| 245 | - cpu_physical_memory_reset_dirty(frame_base + step * minline, | ||
| 246 | - frame_base + step * maxline, VGA_DIRTY_FLAG); | 216 | + framebuffer_update_display(omap_lcd->state, |
| 217 | + frame_base, width, height, | ||
| 218 | + step, linesize, 0, | ||
| 219 | + omap_lcd->invalidate, | ||
| 220 | + draw_line, omap_lcd->palette, | ||
| 221 | + &first, &last); | ||
| 222 | + if (first >= 0) { | ||
| 223 | + dpy_update(omap_lcd->state, 0, first, width, last - first + 1); | ||
| 247 | } | 224 | } |
| 225 | + omap_lcd->invalidate = 0; | ||
| 248 | } | 226 | } |
| 249 | 227 | ||
| 250 | static int ppm_save(const char *filename, uint8_t *data, | 228 | 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) { | @@ -336,25 +314,13 @@ static void omap_lcd_update(struct omap_lcd_panel_s *s) { | ||
| 336 | return; | 314 | return; |
| 337 | } | 315 | } |
| 338 | 316 | ||
| 339 | - if (s->dma->src == imif) { | ||
| 340 | - /* Framebuffers are in SRAM */ | ||
| 341 | - s->dma->phys_framebuffer[0] = s->imif_base + | ||
| 342 | - s->dma->src_f1_top - OMAP_IMIF_BASE; | ||
| 343 | - | ||
| 344 | - s->dma->phys_framebuffer[1] = s->imif_base + | ||
| 345 | - s->dma->src_f2_top - OMAP_IMIF_BASE; | ||
| 346 | - } else { | ||
| 347 | - /* Framebuffers are in RAM */ | ||
| 348 | - s->dma->phys_framebuffer[0] = s->emiff_base + | ||
| 349 | - s->dma->src_f1_top - OMAP_EMIFF_BASE; | ||
| 350 | - | ||
| 351 | - s->dma->phys_framebuffer[1] = s->emiff_base + | ||
| 352 | - s->dma->src_f2_top - OMAP_EMIFF_BASE; | ||
| 353 | - } | 317 | + s->dma->phys_framebuffer[0] = s->dma->src_f1_top; |
| 318 | + s->dma->phys_framebuffer[1] = s->dma->src_f2_top; | ||
| 354 | 319 | ||
| 355 | if (s->plm != 2 && !s->palette_done) { | 320 | if (s->plm != 2 && !s->palette_done) { |
| 356 | - memcpy(s->palette, phys_ram_base + | ||
| 357 | - s->dma->phys_framebuffer[s->dma->current_frame], 0x200); | 321 | + cpu_physical_memory_read( |
| 322 | + s->dma->phys_framebuffer[s->dma->current_frame], | ||
| 323 | + (void *)s->palette, 0x200); | ||
| 358 | s->palette_done = 1; | 324 | s->palette_done = 1; |
| 359 | omap_lcd_interrupts(s); | 325 | omap_lcd_interrupts(s); |
| 360 | } | 326 | } |
hw/pl110.c
| @@ -10,6 +10,7 @@ | @@ -10,6 +10,7 @@ | ||
| 10 | #include "hw.h" | 10 | #include "hw.h" |
| 11 | #include "primecell.h" | 11 | #include "primecell.h" |
| 12 | #include "console.h" | 12 | #include "console.h" |
| 13 | +#include "framebuffer.h" | ||
| 13 | 14 | ||
| 14 | #define PL110_CR_EN 0x001 | 15 | #define PL110_CR_EN 0x001 |
| 15 | #define PL110_CR_BGR 0x100 | 16 | #define PL110_CR_BGR 0x100 |
| @@ -61,8 +62,6 @@ static const unsigned char pl110_versatile_id[] = | @@ -61,8 +62,6 @@ static const unsigned char pl110_versatile_id[] = | ||
| 61 | 62 | ||
| 62 | #include "pixel_ops.h" | 63 | #include "pixel_ops.h" |
| 63 | 64 | ||
| 64 | -typedef void (*drawfn)(uint32_t *, uint8_t *, const uint8_t *, int); | ||
| 65 | - | ||
| 66 | #define BITS 8 | 65 | #define BITS 8 |
| 67 | #include "pl110_template.h" | 66 | #include "pl110_template.h" |
| 68 | #define BITS 15 | 67 | #define BITS 15 |
| @@ -84,17 +83,11 @@ static void pl110_update_display(void *opaque) | @@ -84,17 +83,11 @@ static void pl110_update_display(void *opaque) | ||
| 84 | pl110_state *s = (pl110_state *)opaque; | 83 | pl110_state *s = (pl110_state *)opaque; |
| 85 | drawfn* fntable; | 84 | drawfn* fntable; |
| 86 | drawfn fn; | 85 | drawfn fn; |
| 87 | - uint32_t *pallette; | ||
| 88 | - uint32_t addr; | ||
| 89 | - uint32_t base; | ||
| 90 | int dest_width; | 86 | int dest_width; |
| 91 | int src_width; | 87 | int src_width; |
| 92 | - uint8_t *dest; | ||
| 93 | - uint8_t *src; | ||
| 94 | - int first, last = 0; | ||
| 95 | - int dirty, new_dirty; | ||
| 96 | - int i; | ||
| 97 | int bpp_offset; | 88 | int bpp_offset; |
| 89 | + int first; | ||
| 90 | + int last; | ||
| 98 | 91 | ||
| 99 | if (!pl110_enabled(s)) | 92 | if (!pl110_enabled(s)) |
| 100 | return; | 93 | return; |
| @@ -159,47 +152,17 @@ static void pl110_update_display(void *opaque) | @@ -159,47 +152,17 @@ static void pl110_update_display(void *opaque) | ||
| 159 | break; | 152 | break; |
| 160 | } | 153 | } |
| 161 | dest_width *= s->cols; | 154 | dest_width *= s->cols; |
| 162 | - pallette = s->pallette; | ||
| 163 | - base = s->upbase; | ||
| 164 | - /* HACK: Arm aliases physical memory at 0x80000000. */ | ||
| 165 | - if (base > 0x80000000) | ||
| 166 | - base -= 0x80000000; | ||
| 167 | - src = phys_ram_base + base; | ||
| 168 | - dest = ds_get_data(s->ds); | ||
| 169 | - first = -1; | ||
| 170 | - addr = base; | ||
| 171 | - | ||
| 172 | - dirty = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG); | ||
| 173 | - new_dirty = dirty; | ||
| 174 | - for (i = 0; i < s->rows; i++) { | ||
| 175 | - if ((addr & ~TARGET_PAGE_MASK) + src_width >= TARGET_PAGE_SIZE) { | ||
| 176 | - uint32_t tmp; | ||
| 177 | - new_dirty = 0; | ||
| 178 | - for (tmp = 0; tmp < src_width; tmp += TARGET_PAGE_SIZE) { | ||
| 179 | - new_dirty |= cpu_physical_memory_get_dirty(addr + tmp, | ||
| 180 | - VGA_DIRTY_FLAG); | ||
| 181 | - } | ||
| 182 | - } | ||
| 183 | - | ||
| 184 | - if (dirty || new_dirty || s->invalidate) { | ||
| 185 | - fn(pallette, dest, src, s->cols); | ||
| 186 | - if (first == -1) | ||
| 187 | - first = i; | ||
| 188 | - last = i; | ||
| 189 | - } | ||
| 190 | - dirty = new_dirty; | ||
| 191 | - addr += src_width; | ||
| 192 | - dest += dest_width; | ||
| 193 | - src += src_width; | 155 | + first = 0; |
| 156 | + framebuffer_update_display(s->ds, | ||
| 157 | + s->upbase, s->cols, s->rows, | ||
| 158 | + src_width, dest_width, 0, | ||
| 159 | + s->invalidate, | ||
| 160 | + fn, s->pallette, | ||
| 161 | + &first, &last); | ||
| 162 | + if (first >= 0) { | ||
| 163 | + dpy_update(s->ds, 0, first, s->cols, last - first + 1); | ||
| 194 | } | 164 | } |
| 195 | - if (first < 0) | ||
| 196 | - return; | ||
| 197 | - | ||
| 198 | s->invalidate = 0; | 165 | s->invalidate = 0; |
| 199 | - cpu_physical_memory_reset_dirty(base + first * src_width, | ||
| 200 | - base + (last + 1) * src_width, | ||
| 201 | - VGA_DIRTY_FLAG); | ||
| 202 | - dpy_update(s->ds, 0, first, s->cols, last - first + 1); | ||
| 203 | } | 166 | } |
| 204 | 167 | ||
| 205 | static void pl110_invalidate_display(void * opaque) | 168 | static void pl110_invalidate_display(void * opaque) |
hw/pl110_template.h
| @@ -115,8 +115,9 @@ static drawfn glue(pl110_draw_fn_,BITS)[36] = | @@ -115,8 +115,9 @@ static drawfn glue(pl110_draw_fn_,BITS)[36] = | ||
| 115 | #define FN_4(x, y) FN_2(x, y) FN_2(x+2, y) | 115 | #define FN_4(x, y) FN_2(x, y) FN_2(x+2, y) |
| 116 | #define FN_8(y) FN_4(0, y) FN_4(4, y) | 116 | #define FN_8(y) FN_4(0, y) FN_4(4, y) |
| 117 | 117 | ||
| 118 | -static void glue(pl110_draw_line1_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width) | 118 | +static void glue(pl110_draw_line1_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep) |
| 119 | { | 119 | { |
| 120 | + uint32_t *pallette = opaque; | ||
| 120 | uint32_t data; | 121 | uint32_t data; |
| 121 | while (width > 0) { | 122 | while (width > 0) { |
| 122 | data = *(uint32_t *)src; | 123 | data = *(uint32_t *)src; |
| @@ -142,8 +143,9 @@ static void glue(pl110_draw_line1_,NAME)(uint32_t *pallette, uint8_t *d, const u | @@ -142,8 +143,9 @@ static void glue(pl110_draw_line1_,NAME)(uint32_t *pallette, uint8_t *d, const u | ||
| 142 | } | 143 | } |
| 143 | } | 144 | } |
| 144 | 145 | ||
| 145 | -static void glue(pl110_draw_line2_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width) | 146 | +static void glue(pl110_draw_line2_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep) |
| 146 | { | 147 | { |
| 148 | + uint32_t *pallette = opaque; | ||
| 147 | uint32_t data; | 149 | uint32_t data; |
| 148 | while (width > 0) { | 150 | while (width > 0) { |
| 149 | data = *(uint32_t *)src; | 151 | data = *(uint32_t *)src; |
| @@ -169,8 +171,9 @@ static void glue(pl110_draw_line2_,NAME)(uint32_t *pallette, uint8_t *d, const u | @@ -169,8 +171,9 @@ static void glue(pl110_draw_line2_,NAME)(uint32_t *pallette, uint8_t *d, const u | ||
| 169 | } | 171 | } |
| 170 | } | 172 | } |
| 171 | 173 | ||
| 172 | -static void glue(pl110_draw_line4_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width) | 174 | +static void glue(pl110_draw_line4_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep) |
| 173 | { | 175 | { |
| 176 | + uint32_t *pallette = opaque; | ||
| 174 | uint32_t data; | 177 | uint32_t data; |
| 175 | while (width > 0) { | 178 | while (width > 0) { |
| 176 | data = *(uint32_t *)src; | 179 | data = *(uint32_t *)src; |
| @@ -196,8 +199,9 @@ static void glue(pl110_draw_line4_,NAME)(uint32_t *pallette, uint8_t *d, const u | @@ -196,8 +199,9 @@ static void glue(pl110_draw_line4_,NAME)(uint32_t *pallette, uint8_t *d, const u | ||
| 196 | } | 199 | } |
| 197 | } | 200 | } |
| 198 | 201 | ||
| 199 | -static void glue(pl110_draw_line8_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width) | 202 | +static void glue(pl110_draw_line8_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep) |
| 200 | { | 203 | { |
| 204 | + uint32_t *pallette = opaque; | ||
| 201 | uint32_t data; | 205 | uint32_t data; |
| 202 | while (width > 0) { | 206 | while (width > 0) { |
| 203 | data = *(uint32_t *)src; | 207 | data = *(uint32_t *)src; |
| @@ -219,7 +223,7 @@ static void glue(pl110_draw_line8_,NAME)(uint32_t *pallette, uint8_t *d, const u | @@ -219,7 +223,7 @@ static void glue(pl110_draw_line8_,NAME)(uint32_t *pallette, uint8_t *d, const u | ||
| 219 | } | 223 | } |
| 220 | } | 224 | } |
| 221 | 225 | ||
| 222 | -static void glue(pl110_draw_line16_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width) | 226 | +static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep) |
| 223 | { | 227 | { |
| 224 | uint32_t data; | 228 | uint32_t data; |
| 225 | unsigned int r, g, b; | 229 | unsigned int r, g, b; |
| @@ -265,7 +269,7 @@ static void glue(pl110_draw_line16_,NAME)(uint32_t *pallette, uint8_t *d, const | @@ -265,7 +269,7 @@ static void glue(pl110_draw_line16_,NAME)(uint32_t *pallette, uint8_t *d, const | ||
| 265 | } | 269 | } |
| 266 | } | 270 | } |
| 267 | 271 | ||
| 268 | -static void glue(pl110_draw_line32_,NAME)(uint32_t *pallette, uint8_t *d, const uint8_t *src, int width) | 272 | +static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep) |
| 269 | { | 273 | { |
| 270 | uint32_t data; | 274 | uint32_t data; |
| 271 | unsigned int r, g, b; | 275 | unsigned int r, g, b; |
hw/pxa2xx_lcd.c
| @@ -13,8 +13,7 @@ | @@ -13,8 +13,7 @@ | ||
| 13 | #include "pixel_ops.h" | 13 | #include "pixel_ops.h" |
| 14 | /* FIXME: For graphic_rotate. Should probably be done in common code. */ | 14 | /* FIXME: For graphic_rotate. Should probably be done in common code. */ |
| 15 | #include "sysemu.h" | 15 | #include "sysemu.h" |
| 16 | - | ||
| 17 | -typedef void (*drawfn)(uint32_t *, uint8_t *, const uint8_t *, int, int); | 16 | +#include "framebuffer.h" |
| 18 | 17 | ||
| 19 | struct pxa2xx_lcdc_s { | 18 | struct pxa2xx_lcdc_s { |
| 20 | qemu_irq irq; | 19 | qemu_irq irq; |
| @@ -56,7 +55,7 @@ struct pxa2xx_lcdc_s { | @@ -56,7 +55,7 @@ struct pxa2xx_lcdc_s { | ||
| 56 | int up; | 55 | int up; |
| 57 | uint8_t palette[1024]; | 56 | uint8_t palette[1024]; |
| 58 | uint8_t pbuffer[1024]; | 57 | uint8_t pbuffer[1024]; |
| 59 | - void (*redraw)(struct pxa2xx_lcdc_s *s, uint8_t *fb, | 58 | + void (*redraw)(struct pxa2xx_lcdc_s *s, target_phys_addr_t addr, |
| 60 | int *miny, int *maxy); | 59 | int *miny, int *maxy); |
| 61 | 60 | ||
| 62 | target_phys_addr_t descriptor; | 61 | target_phys_addr_t descriptor; |
| @@ -669,18 +668,15 @@ static void pxa2xx_palette_parse(struct pxa2xx_lcdc_s *s, int ch, int bpp) | @@ -669,18 +668,15 @@ static void pxa2xx_palette_parse(struct pxa2xx_lcdc_s *s, int ch, int bpp) | ||
| 669 | } | 668 | } |
| 670 | 669 | ||
| 671 | static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s, | 670 | static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s, |
| 672 | - uint8_t *fb, int *miny, int *maxy) | 671 | + target_phys_addr_t addr, int *miny, int *maxy) |
| 673 | { | 672 | { |
| 674 | - int y, src_width, dest_width, dirty[2]; | ||
| 675 | - uint8_t *src, *dest; | ||
| 676 | - ram_addr_t x, addr, new_addr, start, end; | 673 | + int src_width, dest_width; |
| 677 | drawfn fn = 0; | 674 | drawfn fn = 0; |
| 678 | if (s->dest_width) | 675 | if (s->dest_width) |
| 679 | fn = s->line_fn[s->transp][s->bpp]; | 676 | fn = s->line_fn[s->transp][s->bpp]; |
| 680 | if (!fn) | 677 | if (!fn) |
| 681 | return; | 678 | return; |
| 682 | 679 | ||
| 683 | - src = fb; | ||
| 684 | src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ | 680 | src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ |
| 685 | if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) | 681 | if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) |
| 686 | src_width *= 3; | 682 | src_width *= 3; |
| @@ -689,54 +685,25 @@ static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s, | @@ -689,54 +685,25 @@ static void pxa2xx_lcdc_dma0_redraw_horiz(struct pxa2xx_lcdc_s *s, | ||
| 689 | else if (s->bpp > pxa_lcdc_8bpp) | 685 | else if (s->bpp > pxa_lcdc_8bpp) |
| 690 | src_width *= 2; | 686 | src_width *= 2; |
| 691 | 687 | ||
| 692 | - dest = ds_get_data(s->ds); | ||
| 693 | dest_width = s->xres * s->dest_width; | 688 | dest_width = s->xres * s->dest_width; |
| 694 | - | ||
| 695 | - addr = (ram_addr_t) (fb - phys_ram_base); | ||
| 696 | - start = addr + s->yres * src_width; | ||
| 697 | - end = addr; | ||
| 698 | - dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(addr, VGA_DIRTY_FLAG); | ||
| 699 | - for (y = 0; y < s->yres; y ++) { | ||
| 700 | - new_addr = addr + src_width; | ||
| 701 | - for (x = addr + TARGET_PAGE_SIZE; x < new_addr; | ||
| 702 | - x += TARGET_PAGE_SIZE) { | ||
| 703 | - dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG); | ||
| 704 | - dirty[0] |= dirty[1]; | ||
| 705 | - } | ||
| 706 | - if (dirty[0] || s->invalidated) { | ||
| 707 | - fn((uint32_t *) s->dma_ch[0].palette, | ||
| 708 | - dest, src, s->xres, s->dest_width); | ||
| 709 | - if (addr < start) | ||
| 710 | - start = addr; | ||
| 711 | - end = new_addr; | ||
| 712 | - if (y < *miny) | ||
| 713 | - *miny = y; | ||
| 714 | - if (y >= *maxy) | ||
| 715 | - *maxy = y + 1; | ||
| 716 | - } | ||
| 717 | - addr = new_addr; | ||
| 718 | - dirty[0] = dirty[1]; | ||
| 719 | - src += src_width; | ||
| 720 | - dest += dest_width; | ||
| 721 | - } | ||
| 722 | - | ||
| 723 | - if (end > start) | ||
| 724 | - cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG); | 689 | + *miny = 0; |
| 690 | + framebuffer_update_display(s->ds, | ||
| 691 | + addr, s->xres, s->yres, | ||
| 692 | + src_width, dest_width, s->dest_width, | ||
| 693 | + s->invalidated, | ||
| 694 | + fn, s->dma_ch[0].palette, miny, maxy); | ||
| 725 | } | 695 | } |
| 726 | 696 | ||
| 727 | static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s, | 697 | static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s, |
| 728 | - uint8_t *fb, int *miny, int *maxy) | 698 | + target_phys_addr_t addr, int *miny, int *maxy) |
| 729 | { | 699 | { |
| 730 | - int y, src_width, dest_width, dirty[2]; | ||
| 731 | - uint8_t *src, *dest; | ||
| 732 | - ram_addr_t x, addr, new_addr, start, end; | 700 | + int src_width, dest_width; |
| 733 | drawfn fn = 0; | 701 | drawfn fn = 0; |
| 734 | if (s->dest_width) | 702 | if (s->dest_width) |
| 735 | fn = s->line_fn[s->transp][s->bpp]; | 703 | fn = s->line_fn[s->transp][s->bpp]; |
| 736 | if (!fn) | 704 | if (!fn) |
| 737 | return; | 705 | return; |
| 738 | 706 | ||
| 739 | - src = fb; | ||
| 740 | src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ | 707 | src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ |
| 741 | if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) | 708 | if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) |
| 742 | src_width *= 3; | 709 | src_width *= 3; |
| @@ -746,38 +713,13 @@ static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s, | @@ -746,38 +713,13 @@ static void pxa2xx_lcdc_dma0_redraw_vert(struct pxa2xx_lcdc_s *s, | ||
| 746 | src_width *= 2; | 713 | src_width *= 2; |
| 747 | 714 | ||
| 748 | dest_width = s->yres * s->dest_width; | 715 | dest_width = s->yres * s->dest_width; |
| 749 | - dest = ds_get_data(s->ds) + dest_width * (s->xres - 1); | ||
| 750 | - | ||
| 751 | - addr = (ram_addr_t) (fb - phys_ram_base); | ||
| 752 | - start = addr + s->yres * src_width; | ||
| 753 | - end = addr; | ||
| 754 | - x = addr + TARGET_PAGE_SIZE; | ||
| 755 | - dirty[0] = dirty[1] = cpu_physical_memory_get_dirty(start, VGA_DIRTY_FLAG); | ||
| 756 | - for (y = 0; y < s->yres; y ++) { | ||
| 757 | - new_addr = addr + src_width; | ||
| 758 | - for (; x < new_addr; x += TARGET_PAGE_SIZE) { | ||
| 759 | - dirty[1] = cpu_physical_memory_get_dirty(x, VGA_DIRTY_FLAG); | ||
| 760 | - dirty[0] |= dirty[1]; | ||
| 761 | - } | ||
| 762 | - if (dirty[0] || s->invalidated) { | ||
| 763 | - fn((uint32_t *) s->dma_ch[0].palette, | ||
| 764 | - dest, src, s->xres, -dest_width); | ||
| 765 | - if (addr < start) | ||
| 766 | - start = addr; | ||
| 767 | - end = new_addr; | ||
| 768 | - if (y < *miny) | ||
| 769 | - *miny = y; | ||
| 770 | - if (y >= *maxy) | ||
| 771 | - *maxy = y + 1; | ||
| 772 | - } | ||
| 773 | - addr = new_addr; | ||
| 774 | - dirty[0] = dirty[1]; | ||
| 775 | - src += src_width; | ||
| 776 | - dest += s->dest_width; | ||
| 777 | - } | ||
| 778 | - | ||
| 779 | - if (end > start) | ||
| 780 | - cpu_physical_memory_reset_dirty(start, end, VGA_DIRTY_FLAG); | 716 | + *miny = 0; |
| 717 | + framebuffer_update_display(s->ds, | ||
| 718 | + addr, s->xres, s->yres, | ||
| 719 | + src_width, s->dest_width, -dest_width, | ||
| 720 | + s->invalidated, | ||
| 721 | + fn, s->dma_ch[0].palette, | ||
| 722 | + miny, maxy); | ||
| 781 | } | 723 | } |
| 782 | 724 | ||
| 783 | static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s) | 725 | static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s) |
| @@ -803,7 +745,6 @@ static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s) | @@ -803,7 +745,6 @@ static void pxa2xx_lcdc_resize(struct pxa2xx_lcdc_s *s) | ||
| 803 | static void pxa2xx_update_display(void *opaque) | 745 | static void pxa2xx_update_display(void *opaque) |
| 804 | { | 746 | { |
| 805 | struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque; | 747 | struct pxa2xx_lcdc_s *s = (struct pxa2xx_lcdc_s *) opaque; |
| 806 | - uint8_t *fb; | ||
| 807 | target_phys_addr_t fbptr; | 748 | target_phys_addr_t fbptr; |
| 808 | int miny, maxy; | 749 | int miny, maxy; |
| 809 | int ch; | 750 | int ch; |
| @@ -829,13 +770,11 @@ static void pxa2xx_update_display(void *opaque) | @@ -829,13 +770,11 @@ static void pxa2xx_update_display(void *opaque) | ||
| 829 | pxa2xx_dma_ber_set(s, ch); | 770 | pxa2xx_dma_ber_set(s, ch); |
| 830 | continue; | 771 | continue; |
| 831 | } | 772 | } |
| 832 | - fbptr -= PXA2XX_SDRAM_BASE; | ||
| 833 | - fb = phys_ram_base + fbptr; | ||
| 834 | 773 | ||
| 835 | if (s->dma_ch[ch].command & LDCMD_PAL) { | 774 | if (s->dma_ch[ch].command & LDCMD_PAL) { |
| 836 | - memcpy(s->dma_ch[ch].pbuffer, fb, | ||
| 837 | - MAX(LDCMD_LENGTH(s->dma_ch[ch].command), | ||
| 838 | - sizeof(s->dma_ch[ch].pbuffer))); | 775 | + cpu_physical_memory_read(fbptr, s->dma_ch[ch].pbuffer, |
| 776 | + MAX(LDCMD_LENGTH(s->dma_ch[ch].command), | ||
| 777 | + sizeof(s->dma_ch[ch].pbuffer))); | ||
| 839 | pxa2xx_palette_parse(s, ch, s->bpp); | 778 | pxa2xx_palette_parse(s, ch, s->bpp); |
| 840 | } else { | 779 | } else { |
| 841 | /* Do we need to reparse palette */ | 780 | /* Do we need to reparse palette */ |
| @@ -845,7 +784,7 @@ static void pxa2xx_update_display(void *opaque) | @@ -845,7 +784,7 @@ static void pxa2xx_update_display(void *opaque) | ||
| 845 | /* ACK frame start */ | 784 | /* ACK frame start */ |
| 846 | pxa2xx_dma_sof_set(s, ch); | 785 | pxa2xx_dma_sof_set(s, ch); |
| 847 | 786 | ||
| 848 | - s->dma_ch[ch].redraw(s, fb, &miny, &maxy); | 787 | + s->dma_ch[ch].redraw(s, fbptr, &miny, &maxy); |
| 849 | s->invalidated = 0; | 788 | s->invalidated = 0; |
| 850 | 789 | ||
| 851 | /* ACK frame completed */ | 790 | /* ACK frame completed */ |
| @@ -859,10 +798,12 @@ static void pxa2xx_update_display(void *opaque) | @@ -859,10 +798,12 @@ static void pxa2xx_update_display(void *opaque) | ||
| 859 | s->status[0] |= LCSR0_LDD; | 798 | s->status[0] |= LCSR0_LDD; |
| 860 | } | 799 | } |
| 861 | 800 | ||
| 862 | - if (s->orientation) | ||
| 863 | - dpy_update(s->ds, miny, 0, maxy, s->xres); | ||
| 864 | - else | ||
| 865 | - dpy_update(s->ds, 0, miny, s->xres, maxy); | 801 | + if (miny >= 0) { |
| 802 | + if (s->orientation) | ||
| 803 | + dpy_update(s->ds, miny, 0, maxy, s->xres); | ||
| 804 | + else | ||
| 805 | + dpy_update(s->ds, 0, miny, s->xres, maxy); | ||
| 806 | + } | ||
| 866 | pxa2xx_lcdc_int_update(s); | 807 | pxa2xx_lcdc_int_update(s); |
| 867 | 808 | ||
| 868 | qemu_irq_raise(s->vsync_cb); | 809 | qemu_irq_raise(s->vsync_cb); |
hw/pxa2xx_template.h
| @@ -30,9 +30,10 @@ | @@ -30,9 +30,10 @@ | ||
| 30 | #define FN_2(x) FN(x + 1) FN(x) | 30 | #define FN_2(x) FN(x + 1) FN(x) |
| 31 | #define FN_4(x) FN_2(x + 2) FN_2(x) | 31 | #define FN_4(x) FN_2(x + 2) FN_2(x) |
| 32 | 32 | ||
| 33 | -static void glue(pxa2xx_draw_line2_, BITS)(uint32_t *palette, | 33 | +static void glue(pxa2xx_draw_line2_, BITS)(void *opaque, |
| 34 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 34 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 35 | { | 35 | { |
| 36 | + uint32_t *palette = opaque; | ||
| 36 | uint32_t data; | 37 | uint32_t data; |
| 37 | while (width > 0) { | 38 | while (width > 0) { |
| 38 | data = *(uint32_t *) src; | 39 | data = *(uint32_t *) src; |
| @@ -54,9 +55,10 @@ static void glue(pxa2xx_draw_line2_, BITS)(uint32_t *palette, | @@ -54,9 +55,10 @@ static void glue(pxa2xx_draw_line2_, BITS)(uint32_t *palette, | ||
| 54 | } | 55 | } |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | -static void glue(pxa2xx_draw_line4_, BITS)(uint32_t *palette, | 58 | +static void glue(pxa2xx_draw_line4_, BITS)(void *opaque, |
| 58 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 59 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 59 | { | 60 | { |
| 61 | + uint32_t *palette = opaque; | ||
| 60 | uint32_t data; | 62 | uint32_t data; |
| 61 | while (width > 0) { | 63 | while (width > 0) { |
| 62 | data = *(uint32_t *) src; | 64 | data = *(uint32_t *) src; |
| @@ -78,9 +80,10 @@ static void glue(pxa2xx_draw_line4_, BITS)(uint32_t *palette, | @@ -78,9 +80,10 @@ static void glue(pxa2xx_draw_line4_, BITS)(uint32_t *palette, | ||
| 78 | } | 80 | } |
| 79 | } | 81 | } |
| 80 | 82 | ||
| 81 | -static void glue(pxa2xx_draw_line8_, BITS)(uint32_t *palette, | 83 | +static void glue(pxa2xx_draw_line8_, BITS)(void *opaque, |
| 82 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 84 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 83 | { | 85 | { |
| 86 | + uint32_t *palette = opaque; | ||
| 84 | uint32_t data; | 87 | uint32_t data; |
| 85 | while (width > 0) { | 88 | while (width > 0) { |
| 86 | data = *(uint32_t *) src; | 89 | data = *(uint32_t *) src; |
| @@ -102,7 +105,7 @@ static void glue(pxa2xx_draw_line8_, BITS)(uint32_t *palette, | @@ -102,7 +105,7 @@ static void glue(pxa2xx_draw_line8_, BITS)(uint32_t *palette, | ||
| 102 | } | 105 | } |
| 103 | } | 106 | } |
| 104 | 107 | ||
| 105 | -static void glue(pxa2xx_draw_line16_, BITS)(uint32_t *palette, | 108 | +static void glue(pxa2xx_draw_line16_, BITS)(void *opaque, |
| 106 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 109 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 107 | { | 110 | { |
| 108 | uint32_t data; | 111 | uint32_t data; |
| @@ -130,7 +133,7 @@ static void glue(pxa2xx_draw_line16_, BITS)(uint32_t *palette, | @@ -130,7 +133,7 @@ static void glue(pxa2xx_draw_line16_, BITS)(uint32_t *palette, | ||
| 130 | } | 133 | } |
| 131 | } | 134 | } |
| 132 | 135 | ||
| 133 | -static void glue(pxa2xx_draw_line16t_, BITS)(uint32_t *palette, | 136 | +static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque, |
| 134 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 137 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 135 | { | 138 | { |
| 136 | uint32_t data; | 139 | uint32_t data; |
| @@ -166,7 +169,7 @@ static void glue(pxa2xx_draw_line16t_, BITS)(uint32_t *palette, | @@ -166,7 +169,7 @@ static void glue(pxa2xx_draw_line16t_, BITS)(uint32_t *palette, | ||
| 166 | } | 169 | } |
| 167 | } | 170 | } |
| 168 | 171 | ||
| 169 | -static void glue(pxa2xx_draw_line18_, BITS)(uint32_t *palette, | 172 | +static void glue(pxa2xx_draw_line18_, BITS)(void *opaque, |
| 170 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 173 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 171 | { | 174 | { |
| 172 | uint32_t data; | 175 | uint32_t data; |
| @@ -188,7 +191,7 @@ static void glue(pxa2xx_draw_line18_, BITS)(uint32_t *palette, | @@ -188,7 +191,7 @@ static void glue(pxa2xx_draw_line18_, BITS)(uint32_t *palette, | ||
| 188 | } | 191 | } |
| 189 | 192 | ||
| 190 | /* The wicked packed format */ | 193 | /* The wicked packed format */ |
| 191 | -static void glue(pxa2xx_draw_line18p_, BITS)(uint32_t *palette, | 194 | +static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque, |
| 192 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 195 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 193 | { | 196 | { |
| 194 | uint32_t data[3]; | 197 | uint32_t data[3]; |
| @@ -236,7 +239,7 @@ static void glue(pxa2xx_draw_line18p_, BITS)(uint32_t *palette, | @@ -236,7 +239,7 @@ static void glue(pxa2xx_draw_line18p_, BITS)(uint32_t *palette, | ||
| 236 | } | 239 | } |
| 237 | } | 240 | } |
| 238 | 241 | ||
| 239 | -static void glue(pxa2xx_draw_line19_, BITS)(uint32_t *palette, | 242 | +static void glue(pxa2xx_draw_line19_, BITS)(void *opaque, |
| 240 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 243 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 241 | { | 244 | { |
| 242 | uint32_t data; | 245 | uint32_t data; |
| @@ -262,7 +265,7 @@ static void glue(pxa2xx_draw_line19_, BITS)(uint32_t *palette, | @@ -262,7 +265,7 @@ static void glue(pxa2xx_draw_line19_, BITS)(uint32_t *palette, | ||
| 262 | } | 265 | } |
| 263 | 266 | ||
| 264 | /* The wicked packed format */ | 267 | /* The wicked packed format */ |
| 265 | -static void glue(pxa2xx_draw_line19p_, BITS)(uint32_t *palette, | 268 | +static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque, |
| 266 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 269 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 267 | { | 270 | { |
| 268 | uint32_t data[3]; | 271 | uint32_t data[3]; |
| @@ -326,7 +329,7 @@ static void glue(pxa2xx_draw_line19p_, BITS)(uint32_t *palette, | @@ -326,7 +329,7 @@ static void glue(pxa2xx_draw_line19p_, BITS)(uint32_t *palette, | ||
| 326 | } | 329 | } |
| 327 | } | 330 | } |
| 328 | 331 | ||
| 329 | -static void glue(pxa2xx_draw_line24_, BITS)(uint32_t *palette, | 332 | +static void glue(pxa2xx_draw_line24_, BITS)(void *opaque, |
| 330 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 333 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 331 | { | 334 | { |
| 332 | uint32_t data; | 335 | uint32_t data; |
| @@ -347,7 +350,7 @@ static void glue(pxa2xx_draw_line24_, BITS)(uint32_t *palette, | @@ -347,7 +350,7 @@ static void glue(pxa2xx_draw_line24_, BITS)(uint32_t *palette, | ||
| 347 | } | 350 | } |
| 348 | } | 351 | } |
| 349 | 352 | ||
| 350 | -static void glue(pxa2xx_draw_line24t_, BITS)(uint32_t *palette, | 353 | +static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque, |
| 351 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 354 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 352 | { | 355 | { |
| 353 | uint32_t data; | 356 | uint32_t data; |
| @@ -372,7 +375,7 @@ static void glue(pxa2xx_draw_line24t_, BITS)(uint32_t *palette, | @@ -372,7 +375,7 @@ static void glue(pxa2xx_draw_line24t_, BITS)(uint32_t *palette, | ||
| 372 | } | 375 | } |
| 373 | } | 376 | } |
| 374 | 377 | ||
| 375 | -static void glue(pxa2xx_draw_line25_, BITS)(uint32_t *palette, | 378 | +static void glue(pxa2xx_draw_line25_, BITS)(void *opaque, |
| 376 | uint8_t *dest, const uint8_t *src, int width, int deststep) | 379 | uint8_t *dest, const uint8_t *src, int width, int deststep) |
| 377 | { | 380 | { |
| 378 | uint32_t data; | 381 | uint32_t data; |