Revision 714fa308 hw/omap_lcdc.c
b/hw/omap_lcdc.c | ||
---|---|---|
20 | 20 |
#include "hw.h" |
21 | 21 |
#include "console.h" |
22 | 22 |
#include "omap.h" |
23 |
#include "framebuffer.h" |
|
23 | 24 |
|
24 | 25 |
struct omap_lcd_panel_s { |
25 | 26 |
qemu_irq irq; |
... | ... | |
68 | 69 |
|
69 | 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 | 74 |
#define DEPTH 8 |
75 | 75 |
#include "omap_lcd_template.h" |
... | ... | |
80 | 80 |
#define DEPTH 32 |
81 | 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 | 84 |
[0 ... 32] = 0, |
85 | 85 |
[8] = draw_line2_8, |
86 | 86 |
[15] = draw_line2_15, |
87 | 87 |
[16] = draw_line2_16, |
88 | 88 |
[32] = draw_line2_32, |
89 |
}, *draw_line_table4[33] = {
|
|
89 |
}, draw_line_table4[33] = { |
|
90 | 90 |
[0 ... 32] = 0, |
91 | 91 |
[8] = draw_line4_8, |
92 | 92 |
[15] = draw_line4_15, |
93 | 93 |
[16] = draw_line4_16, |
94 | 94 |
[32] = draw_line4_32, |
95 |
}, *draw_line_table8[33] = {
|
|
95 |
}, draw_line_table8[33] = { |
|
96 | 96 |
[0 ... 32] = 0, |
97 | 97 |
[8] = draw_line8_8, |
98 | 98 |
[15] = draw_line8_15, |
99 | 99 |
[16] = draw_line8_16, |
100 | 100 |
[32] = draw_line8_32, |
101 |
}, *draw_line_table12[33] = {
|
|
101 |
}, draw_line_table12[33] = { |
|
102 | 102 |
[0 ... 32] = 0, |
103 | 103 |
[8] = draw_line12_8, |
104 | 104 |
[15] = draw_line12_15, |
105 | 105 |
[16] = draw_line12_16, |
106 | 106 |
[32] = draw_line12_32, |
107 |
}, *draw_line_table16[33] = {
|
|
107 |
}, draw_line_table16[33] = { |
|
108 | 108 |
[0 ... 32] = 0, |
109 | 109 |
[8] = draw_line16_8, |
110 | 110 |
[15] = draw_line16_15, |
... | ... | |
115 | 115 |
static void omap_update_display(void *opaque) |
116 | 116 |
{ |
117 | 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 | 123 |
if (!omap_lcd || omap_lcd->plm == 1 || |
125 | 124 |
!omap_lcd->enable || !ds_get_bits_per_pixel(omap_lcd->state)) |
... | ... | |
127 | 126 |
|
128 | 127 |
frame_offset = 0; |
129 | 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 | 132 |
switch (omap_lcd->palette[0] >> 12 & 7) { |
134 | 133 |
case 3 ... 7: |
135 | 134 |
frame_offset += 0x200; |
... | ... | |
202 | 201 |
if (!ds_get_bits_per_pixel(omap_lcd->state)) |
203 | 202 |
return; |
204 | 203 |
|
205 |
line = 0;
|
|
204 |
first = 0;
|
|
206 | 205 |
height = omap_lcd->height; |
207 | 206 |
if (omap_lcd->subpanel & (1 << 31)) { |
208 | 207 |
if (omap_lcd->subpanel & (1 << 29)) |
209 |
line = (omap_lcd->subpanel >> 16) & 0x3ff;
|
|
208 |
first = (omap_lcd->subpanel >> 16) & 0x3ff;
|
|
210 | 209 |
else |
211 | 210 |
height = (omap_lcd->subpanel >> 16) & 0x3ff; |
212 | 211 |
/* TODO: fill the rest of the panel with DPD */ |
213 | 212 |
} |
213 |
|
|
214 | 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 | 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 | 228 |
static int ppm_save(const char *filename, uint8_t *data, |
... | ... | |
336 | 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 | 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 | 324 |
s->palette_done = 1; |
359 | 325 |
omap_lcd_interrupts(s); |
360 | 326 |
} |
Also available in: Unified diff