sm501: Add support for panel layer

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Tested-by: Aurelien Jarno <aurelien@aurel32.net>
Message-id: 2029a276362c0c3a14c78acb56baa9466848dd51.1492787889.git.balaton@eik.bme.hu
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
BALATON Zoltan 2017-04-21 17:18:09 +02:00 committed by Peter Maydell
parent 01d2d584c9
commit 1ae5e6eb42
1 changed files with 32 additions and 31 deletions

View File

@ -2,6 +2,7 @@
* QEMU SM501 Device * QEMU SM501 Device
* *
* Copyright (c) 2008 Shin-ichiro KAWASAKI * Copyright (c) 2008 Shin-ichiro KAWASAKI
* Copyright (c) 2016 BALATON Zoltan
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -42,8 +43,11 @@
* - Minimum implementation for Linux console : mmio regs and CRT layer. * - Minimum implementation for Linux console : mmio regs and CRT layer.
* - 2D graphics acceleration partially supported : only fill rectangle. * - 2D graphics acceleration partially supported : only fill rectangle.
* *
* TODO: * Status: 2016/12/04
* - Misc fixes: endianness, hardware cursor
* - Panel support * - Panel support
*
* TODO:
* - Touch panel support * - Touch panel support
* - USB support * - USB support
* - UART support * - UART support
@ -1301,18 +1305,16 @@ static inline int get_depth_index(DisplaySurface *surface)
} }
} }
static void sm501_draw_crt(SM501State *s) static void sm501_update_display(void *opaque)
{ {
SM501State *s = (SM501State *)opaque;
DisplaySurface *surface = qemu_console_surface(s->con); DisplaySurface *surface = qemu_console_surface(s->con);
int y, c_x = 0, c_y = 0; int y, c_x = 0, c_y = 0;
uint8_t *hwc_src = NULL, *src = s->local_mem; int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0;
int width = get_width(s, 1); int width = get_width(s, crt);
int height = get_height(s, 1); int height = get_height(s, crt);
int src_bpp = get_bpp(s, 1); int src_bpp = get_bpp(s, crt);
int dst_bpp = surface_bytes_per_pixel(surface); int dst_bpp = surface_bytes_per_pixel(surface);
uint32_t *palette = (uint32_t *)&s->dc_palette[SM501_DC_CRT_PALETTE -
SM501_DC_PANEL_PALETTE];
uint8_t hwc_palette[3 * 3];
int dst_depth_index = get_depth_index(surface); int dst_depth_index = get_depth_index(surface);
draw_line_func *draw_line = NULL; draw_line_func *draw_line = NULL;
draw_hwc_line_func *draw_hwc_line = NULL; draw_hwc_line_func *draw_hwc_line = NULL;
@ -1320,7 +1322,19 @@ static void sm501_draw_crt(SM501State *s)
int y_start = -1; int y_start = -1;
ram_addr_t page_min = ~0l; ram_addr_t page_min = ~0l;
ram_addr_t page_max = 0l; ram_addr_t page_max = 0l;
ram_addr_t offset = 0; ram_addr_t offset;
uint32_t *palette;
uint8_t hwc_palette[3 * 3];
uint8_t *hwc_src = NULL;
if (!((crt ? s->dc_crt_control : s->dc_panel_control)
& SM501_DC_CRT_CONTROL_ENABLE)) {
return;
}
palette = (uint32_t *)(crt ? &s->dc_palette[SM501_DC_CRT_PALETTE -
SM501_DC_PANEL_PALETTE]
: &s->dc_palette[0]);
/* choose draw_line function */ /* choose draw_line function */
switch (src_bpp) { switch (src_bpp) {
@ -1334,20 +1348,19 @@ static void sm501_draw_crt(SM501State *s)
draw_line = draw_line32_funcs[dst_depth_index]; draw_line = draw_line32_funcs[dst_depth_index];
break; break;
default: default:
printf("sm501 draw crt : invalid DC_CRT_CONTROL=%x.\n", printf("sm501 update display : invalid control register value.\n");
s->dc_crt_control);
abort(); abort();
break; break;
} }
/* set up to draw hardware cursor */ /* set up to draw hardware cursor */
if (is_hwc_enabled(s, 1)) { if (is_hwc_enabled(s, crt)) {
/* choose cursor draw line function */ /* choose cursor draw line function */
draw_hwc_line = draw_hwc_line_funcs[dst_depth_index]; draw_hwc_line = draw_hwc_line_funcs[dst_depth_index];
hwc_src = get_hwc_address(s, 1); hwc_src = get_hwc_address(s, crt);
c_x = get_hwc_x(s, 1); c_x = get_hwc_x(s, crt);
c_y = get_hwc_y(s, 1); c_y = get_hwc_y(s, crt);
get_hwc_palette(s, 1, hwc_palette); get_hwc_palette(s, crt, hwc_palette);
} }
/* adjust console size */ /* adjust console size */
@ -1361,7 +1374,7 @@ static void sm501_draw_crt(SM501State *s)
/* draw each line according to conditions */ /* draw each line according to conditions */
memory_region_sync_dirty_bitmap(&s->local_mem_region); memory_region_sync_dirty_bitmap(&s->local_mem_region);
for (y = 0; y < height; y++) { for (y = 0, offset = 0; y < height; y++, offset += width * src_bpp) {
int update, update_hwc; int update, update_hwc;
ram_addr_t page0 = offset; ram_addr_t page0 = offset;
ram_addr_t page1 = offset + width * src_bpp - 1; ram_addr_t page1 = offset + width * src_bpp - 1;
@ -1379,7 +1392,7 @@ static void sm501_draw_crt(SM501State *s)
d += y * width * dst_bpp; d += y * width * dst_bpp;
/* draw graphics layer */ /* draw graphics layer */
draw_line(d, src, width, palette); draw_line(d, s->local_mem + offset, width, palette);
/* draw hardware cursor */ /* draw hardware cursor */
if (update_hwc) { if (update_hwc) {
@ -1402,9 +1415,6 @@ static void sm501_draw_crt(SM501State *s)
y_start = -1; y_start = -1;
} }
} }
src += width * src_bpp;
offset += width * src_bpp;
} }
/* complete flush to display */ /* complete flush to display */
@ -1420,15 +1430,6 @@ static void sm501_draw_crt(SM501State *s)
} }
} }
static void sm501_update_display(void *opaque)
{
SM501State *s = (SM501State *)opaque;
if (s->dc_crt_control & SM501_DC_CRT_CONTROL_ENABLE) {
sm501_draw_crt(s);
}
}
static const GraphicHwOps sm501_ops = { static const GraphicHwOps sm501_ops = {
.gfx_update = sm501_update_display, .gfx_update = sm501_update_display,
}; };