diff options
Diffstat (limited to 'firmware/target/arm/pbell/vibe500/lcd-vibe500.c')
-rw-r--r-- | firmware/target/arm/pbell/vibe500/lcd-vibe500.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/firmware/target/arm/pbell/vibe500/lcd-vibe500.c b/firmware/target/arm/pbell/vibe500/lcd-vibe500.c index 2daa5def74..047ef2bf53 100644 --- a/firmware/target/arm/pbell/vibe500/lcd-vibe500.c +++ b/firmware/target/arm/pbell/vibe500/lcd-vibe500.c | |||
@@ -35,6 +35,8 @@ static unsigned short disp_control_rev; | |||
35 | /* Contrast setting << 8 */ | 35 | /* Contrast setting << 8 */ |
36 | static int lcd_contrast; | 36 | static int lcd_contrast; |
37 | 37 | ||
38 | static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0; | ||
39 | |||
38 | /* Forward declarations */ | 40 | /* Forward declarations */ |
39 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | 41 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) |
40 | static void lcd_display_off(void); | 42 | static void lcd_display_off(void); |
@@ -375,6 +377,79 @@ bool lcd_active(void) | |||
375 | 377 | ||
376 | /*** update functions ***/ | 378 | /*** update functions ***/ |
377 | 379 | ||
380 | void lcd_yuv_set_options(unsigned options) | ||
381 | { | ||
382 | lcd_yuv_options = options; | ||
383 | } | ||
384 | |||
385 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
386 | |||
387 | extern void lcd_write_yuv420_lines(unsigned char const * const src[3], | ||
388 | int width, | ||
389 | int stride); | ||
390 | extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], | ||
391 | int width, | ||
392 | int stride, | ||
393 | int x_screen, /* To align dither pattern */ | ||
394 | int y_screen); | ||
395 | |||
396 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
397 | void lcd_blit_yuv(unsigned char * const src[3], | ||
398 | int src_x, int src_y, int stride, | ||
399 | int x, int y, int width, int height) | ||
400 | { | ||
401 | const unsigned char *yuv_src[3]; | ||
402 | const unsigned char *ysrc_max; | ||
403 | int y0; | ||
404 | int options; | ||
405 | |||
406 | if (!display_on) | ||
407 | return; | ||
408 | |||
409 | width &= ~1; | ||
410 | height &= ~1; | ||
411 | |||
412 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((LCD_WIDTH - 1 - x) << 8) | | ||
413 | ((LCD_WIDTH-1) - (x + width - 1))); | ||
414 | |||
415 | y0 = LCD_HEIGHT - 1 - y; | ||
416 | |||
417 | lcd_write_reg(R_ENTRY_MODE,0x1000); | ||
418 | |||
419 | yuv_src[0] = src[0] + src_y * stride + src_x; | ||
420 | yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1); | ||
421 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
422 | ysrc_max = yuv_src[0] + height * stride; | ||
423 | |||
424 | options = lcd_yuv_options; | ||
425 | |||
426 | do | ||
427 | { | ||
428 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1)); | ||
429 | lcd_write_reg(R_RAM_ADDR_SET, ((LCD_WIDTH - 1 - x) << 8) | y0); | ||
430 | |||
431 | /* start drawing */ | ||
432 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); | ||
433 | |||
434 | if (options & LCD_YUV_DITHER) | ||
435 | { | ||
436 | lcd_write_yuv420_lines_odither(yuv_src, width, stride,x, y); | ||
437 | y -= 2; | ||
438 | } | ||
439 | else | ||
440 | { | ||
441 | lcd_write_yuv420_lines(yuv_src, width, stride); | ||
442 | } | ||
443 | |||
444 | y0 -= 2; | ||
445 | yuv_src[0] += stride << 1; | ||
446 | yuv_src[1] += stride >> 1; | ||
447 | yuv_src[2] += stride >> 1; | ||
448 | } | ||
449 | while (yuv_src[0] < ysrc_max); | ||
450 | lcd_write_reg(R_ENTRY_MODE,0x1008); | ||
451 | } | ||
452 | |||
378 | /* Update a fraction of the display. */ | 453 | /* Update a fraction of the display. */ |
379 | void lcd_update_rect(int x0, int y0, int width, int height) | 454 | void lcd_update_rect(int x0, int y0, int width, int height) |
380 | { | 455 | { |