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