From 3aeb0cbe126849bd8aaa332a18b7ab2fe0699c02 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 8 Feb 2018 21:47:09 +0100 Subject: [PATCH 1/7] dm: video: show correct colors in graphical console Get RGB sequence in pixels right (swap blue and red). Do not set reserved bits. qemu-system-i386 -display sdl -vga virtio and qemu-system-i386 -display sdl -vga cirrus now display the similar colors (highlighting still missing) as qemu-system-i386 -nographic Testing is possible via setenv efi_selftest test output bootefi selftest Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- drivers/video/vidconsole-uclass.c | 13 ++++++------- test/dm/video.c | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 5f63c12d6c..8a2a377161 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -127,15 +127,14 @@ static void set_color(struct video_priv *priv, unsigned idx, unsigned *c) { switch (priv->bpix) { case VIDEO_BPP16: - *c = ((colors[idx].r >> 3) << 0) | - ((colors[idx].g >> 2) << 5) | - ((colors[idx].b >> 3) << 11); + *c = ((colors[idx].r >> 3) << 11) | + ((colors[idx].g >> 2) << 5) | + ((colors[idx].b >> 3) << 0); break; case VIDEO_BPP32: - *c = 0xff000000 | - (colors[idx].r << 0) | - (colors[idx].g << 8) | - (colors[idx].b << 16); + *c = (colors[idx].r << 16) | + (colors[idx].g << 8) | + (colors[idx].b << 0); break; default: /* unsupported, leave current color in place */ diff --git a/test/dm/video.c b/test/dm/video.c index 29917d0c2d..d158f1fcb3 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -186,7 +186,7 @@ static int dm_test_video_ansi(struct unit_test_state *uts) /* test colors (30-37 fg color, 40-47 bg color) */ vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */ vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */ - ut_asserteq(268, compress_frame_buffer(dev)); + ut_asserteq(267, compress_frame_buffer(dev)); return 0; } From d7a75d3cd7cd7ce3665442e4e566b147c4c8602b Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 8 Feb 2018 21:47:10 +0100 Subject: [PATCH 2/7] dm: video: correctly clean background in 16bit mode In 16 bit mode we have to copy two bytes per pixels repeatedly and not four. Otherwise we will see a striped pattern. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- drivers/video/video-uclass.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index dcaceed42c..9a980ea3a1 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -91,14 +91,26 @@ void video_clear(struct udevice *dev) { struct video_priv *priv = dev_get_uclass_priv(dev); - if (priv->bpix == VIDEO_BPP32) { + switch (priv->bpix) { + case VIDEO_BPP16: { + u16 *ppix = priv->fb; + u16 *end = priv->fb + priv->fb_size; + + while (ppix < end) + *ppix++ = priv->colour_bg; + break; + } + case VIDEO_BPP32: { u32 *ppix = priv->fb; u32 *end = priv->fb + priv->fb_size; while (ppix < end) *ppix++ = priv->colour_bg; - } else { + break; + } + default: memset(priv->fb, priv->colour_bg, priv->fb_size); + break; } } From 5c30fbb8ec4aa364d5e441c86d7b5776d6c94fb0 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 8 Feb 2018 21:47:11 +0100 Subject: [PATCH 3/7] dm: video: use constants to refer to colors Use constants to refer to colors. Adjust initialization of foreground and background color to avoid setting reserved bits. Consistently u32 instead of unsigned for color bit mask. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- drivers/video/vidconsole-uclass.c | 55 ++++++++++++++++++------------- drivers/video/video-uclass.c | 19 +++++++---- include/video.h | 11 +++++-- include/video_console.h | 35 ++++++++++++++++++++ 4 files changed, 89 insertions(+), 31 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 8a2a377161..d32b101758 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -15,6 +15,15 @@ #include #include /* Get font data, width and height */ +/* + * Structure to describe a console color + */ +struct vid_rgb { + u32 r; + u32 g; + u32 b; +}; + /* By default we scroll by a single line */ #ifndef CONFIG_CONSOLE_SCROLL_LINES #define CONFIG_CONSOLE_SCROLL_LINES 1 @@ -108,11 +117,7 @@ static void vidconsole_newline(struct udevice *dev) video_sync(dev->parent); } -static const struct { - unsigned r; - unsigned g; - unsigned b; -} colors[] = { +static const struct vid_rgb colors[VID_COLOR_COUNT] = { { 0x00, 0x00, 0x00 }, /* black */ { 0xff, 0x00, 0x00 }, /* red */ { 0x00, 0xff, 0x00 }, /* green */ @@ -123,22 +128,26 @@ static const struct { { 0xff, 0xff, 0xff }, /* white */ }; -static void set_color(struct video_priv *priv, unsigned idx, unsigned *c) +u32 vid_console_color(struct video_priv *priv, unsigned int idx) { switch (priv->bpix) { case VIDEO_BPP16: - *c = ((colors[idx].r >> 3) << 11) | - ((colors[idx].g >> 2) << 5) | - ((colors[idx].b >> 3) << 0); - break; + return ((colors[idx].r >> 3) << 11) | + ((colors[idx].g >> 2) << 5) | + ((colors[idx].b >> 3) << 0); case VIDEO_BPP32: - *c = (colors[idx].r << 16) | - (colors[idx].g << 8) | - (colors[idx].b << 0); - break; + return (colors[idx].r << 16) | + (colors[idx].g << 8) | + (colors[idx].b << 0); default: - /* unsupported, leave current color in place */ - break; + /* + * For unknown bit arrangements just support + * black and white. + */ + if (idx) + return 0xffffff; /* white */ + else + return 0x000000; /* black */ } } @@ -270,17 +279,17 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) switch (val) { case 30 ... 37: - /* fg color */ - set_color(vid_priv, val - 30, - (unsigned *)&vid_priv->colour_fg); + /* foreground color */ + vid_priv->colour_fg = vid_console_color( + vid_priv, val - 30); break; case 40 ... 47: - /* bg color */ - set_color(vid_priv, val - 40, - (unsigned *)&vid_priv->colour_bg); + /* background color */ + vid_priv->colour_bg = vid_console_color( + vid_priv, val - 40); break; default: - /* unknown/unsupported */ + /* ignore unsupported SGR parameter */ break; } } diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index 9a980ea3a1..945b20ddfd 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -114,6 +114,17 @@ void video_clear(struct udevice *dev) } } +void video_set_default_colors(struct video_priv *priv) +{ +#ifdef CONFIG_SYS_WHITE_ON_BLACK + priv->colour_fg = vid_console_color(priv, VID_WHITE); + priv->colour_bg = vid_console_color(priv, VID_BLACK); +#else + priv->colour_fg = vid_console_color(priv, VID_BLACK); + priv->colour_bg = vid_console_color(priv, VID_WHITE); +#endif +} + /* Flush video activity to the caches */ void video_sync(struct udevice *vid) { @@ -203,12 +214,8 @@ static int video_post_probe(struct udevice *dev) priv->line_length = priv->xsize * VNBYTES(priv->bpix); priv->fb_size = priv->line_length * priv->ysize; - /* Set up colours - we could in future support other colours */ -#ifdef CONFIG_SYS_WHITE_ON_BLACK - priv->colour_fg = 0xffffff; -#else - priv->colour_bg = 0xffffff; -#endif + /* Set up colors */ + video_set_default_colors(priv); if (!CONFIG_IS_ENABLED(NO_FB_CLEAR)) video_clear(dev); diff --git a/include/video.h b/include/video.h index 61ff653121..841f3dc56b 100644 --- a/include/video.h +++ b/include/video.h @@ -84,8 +84,8 @@ struct video_priv { void *fb; int fb_size; int line_length; - int colour_fg; - int colour_bg; + u32 colour_fg; + u32 colour_bg; bool flush_dcache; ushort *cmap; }; @@ -183,6 +183,13 @@ int video_get_ysize(struct udevice *dev); */ void video_set_flush_dcache(struct udevice *dev, bool flush); +/** + * Set default colors and attributes + * + * @priv device information + */ +void video_set_default_colors(struct video_priv *priv); + #endif /* CONFIG_DM_VIDEO */ #ifndef CONFIG_DM_VIDEO diff --git a/include/video_console.h b/include/video_console.h index 9dce234bd9..656a47295f 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -7,11 +7,29 @@ #ifndef __video_console_h #define __video_console_h +#include + #define VID_FRAC_DIV 256 #define VID_TO_PIXEL(x) ((x) / VID_FRAC_DIV) #define VID_TO_POS(x) ((x) * VID_FRAC_DIV) +/* + * The 8 colors supported by the console + */ +enum color_idx { + VID_BLACK = 0, + VID_RED, + VID_GREEN, + VID_YELLOW, + VID_BLUE, + VID_MAGENTA, + VID_CYAN, + VID_WHITE, + + VID_COLOR_COUNT +}; + /** * struct vidconsole_priv - uclass-private data about a console device * @@ -196,4 +214,21 @@ int vidconsole_put_char(struct udevice *dev, char ch); void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row); +#ifdef CONFIG_DM_VIDEO + +/** + * vid_console_color() - convert a color code to a pixel's internal + * representation + * + * The caller has to guarantee that the color index is less than + * VID_COLOR_COUNT. + * + * @priv private data of the console device + * @idx color index + * @return color value + */ +u32 vid_console_color(struct video_priv *priv, unsigned int idx); + +#endif + #endif From 9ffa4d12a850c6fb8b9b8f7d5fc31ac28633fcdb Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 8 Feb 2018 21:47:12 +0100 Subject: [PATCH 4/7] dm: video: support increased intensity (bold) Support special rendition code 0 - reset attributes. Support special rendition code 1 - increased intensity (bold). Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- drivers/video/vidconsole-uclass.c | 32 +++++++++++++++++++++++++------ drivers/video/video-uclass.c | 5 ++++- include/video.h | 2 ++ include/video_console.h | 12 ++++++++++-- test/dm/video.c | 2 +- 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index d32b101758..6f3988d49e 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -119,12 +119,20 @@ static void vidconsole_newline(struct udevice *dev) static const struct vid_rgb colors[VID_COLOR_COUNT] = { { 0x00, 0x00, 0x00 }, /* black */ - { 0xff, 0x00, 0x00 }, /* red */ - { 0x00, 0xff, 0x00 }, /* green */ + { 0xc0, 0x00, 0x00 }, /* red */ + { 0x00, 0xc0, 0x00 }, /* green */ + { 0xc0, 0x60, 0x00 }, /* brown */ + { 0x00, 0x00, 0xc0 }, /* blue */ + { 0xc0, 0x00, 0xc0 }, /* magenta */ + { 0x00, 0xc0, 0xc0 }, /* cyan */ + { 0xc0, 0xc0, 0xc0 }, /* light gray */ + { 0x80, 0x80, 0x80 }, /* gray */ + { 0xff, 0x00, 0x00 }, /* bright red */ + { 0x00, 0xff, 0x00 }, /* bright green */ { 0xff, 0xff, 0x00 }, /* yellow */ - { 0x00, 0x00, 0xff }, /* blue */ - { 0xff, 0x00, 0xff }, /* magenta */ - { 0x00, 0xff, 0xff }, /* cyan */ + { 0x00, 0x00, 0xff }, /* bright blue */ + { 0xff, 0x00, 0xff }, /* bright magenta */ + { 0x00, 0xff, 0xff }, /* bright cyan */ { 0xff, 0xff, 0xff }, /* white */ }; @@ -278,10 +286,22 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) s++; switch (val) { + case 0: + /* all attributes off */ + video_set_default_colors(vid_priv); + break; + case 1: + /* bold */ + vid_priv->fg_col_idx |= 8; + vid_priv->colour_fg = vid_console_color( + vid_priv, vid_priv->fg_col_idx); + break; case 30 ... 37: /* foreground color */ + vid_priv->fg_col_idx &= ~7; + vid_priv->fg_col_idx |= val - 30; vid_priv->colour_fg = vid_console_color( - vid_priv, val - 30); + vid_priv, vid_priv->fg_col_idx); break; case 40 ... 47: /* background color */ diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index 945b20ddfd..b5bb8e0efd 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -117,9 +117,12 @@ void video_clear(struct udevice *dev) void video_set_default_colors(struct video_priv *priv) { #ifdef CONFIG_SYS_WHITE_ON_BLACK - priv->colour_fg = vid_console_color(priv, VID_WHITE); + /* White is used when switching to bold, use light gray here */ + priv->fg_col_idx = VID_LIGHT_GRAY; + priv->colour_fg = vid_console_color(priv, VID_LIGHT_GRAY); priv->colour_bg = vid_console_color(priv, VID_BLACK); #else + priv->fg_col_idx = VID_BLACK; priv->colour_fg = vid_console_color(priv, VID_BLACK); priv->colour_bg = vid_console_color(priv, VID_WHITE); #endif diff --git a/include/video.h b/include/video.h index 841f3dc56b..ddc2eeb5a9 100644 --- a/include/video.h +++ b/include/video.h @@ -67,6 +67,7 @@ enum video_log2_bpp { * @flush_dcache: true to enable flushing of the data cache after * the LCD is updated * @cmap: Colour map for 8-bit-per-pixel displays + * @fg_col_idx: Foreground color code (bit 3 = bold, bit 0-2 = color) */ struct video_priv { /* Things set up by the driver: */ @@ -88,6 +89,7 @@ struct video_priv { u32 colour_bg; bool flush_dcache; ushort *cmap; + u8 fg_col_idx; }; /* Placeholder - there are no video operations at present */ diff --git a/include/video_console.h b/include/video_console.h index 656a47295f..7621a189d2 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -15,16 +15,24 @@ #define VID_TO_POS(x) ((x) * VID_FRAC_DIV) /* - * The 8 colors supported by the console + * The 16 colors supported by the console */ enum color_idx { VID_BLACK = 0, VID_RED, VID_GREEN, - VID_YELLOW, + VID_BROWN, VID_BLUE, VID_MAGENTA, VID_CYAN, + VID_LIGHT_GRAY, + VID_GRAY, + VID_LIGHT_RED, + VID_LIGTH_GREEN, + VID_YELLOW, + VID_LIGHT_BLUE, + VID_LIGHT_MAGENTA, + VID_LIGHT_CYAN, VID_WHITE, VID_COLOR_COUNT diff --git a/test/dm/video.c b/test/dm/video.c index d158f1fcb3..caca496902 100644 --- a/test/dm/video.c +++ b/test/dm/video.c @@ -186,7 +186,7 @@ static int dm_test_video_ansi(struct unit_test_state *uts) /* test colors (30-37 fg color, 40-47 bg color) */ vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */ vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */ - ut_asserteq(267, compress_frame_buffer(dev)); + ut_asserteq(265, compress_frame_buffer(dev)); return 0; } From 19f124d8295f17f23bc4b6d050f96b9d9d651d9f Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 9 Feb 2018 10:45:12 +0800 Subject: [PATCH 5/7] pwm-backlight: make power-supply as option Some pwm backlight may not need 'power-supply', let's make it as option in pwm-backlight driver. Signed-off-by: Kever Yang Reviewed-by: Philipp Tomsich --- drivers/video/pwm_backlight.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/video/pwm_backlight.c b/drivers/video/pwm_backlight.c index fbd7bf7838..f40e57bb8e 100644 --- a/drivers/video/pwm_backlight.c +++ b/drivers/video/pwm_backlight.c @@ -32,16 +32,18 @@ static int pwm_backlight_enable(struct udevice *dev) uint duty_cycle; int ret; - plat = dev_get_uclass_platdata(priv->reg); - debug("%s: Enable '%s', regulator '%s'/'%s'\n", __func__, dev->name, - priv->reg->name, plat->name); - ret = regulator_set_enable(priv->reg, true); - if (ret) { - debug("%s: Cannot enable regulator for PWM '%s'\n", __func__, - dev->name); - return ret; + if (priv->reg) { + plat = dev_get_uclass_platdata(priv->reg); + debug("%s: Enable '%s', regulator '%s'/'%s'\n", __func__, + dev->name, priv->reg->name, plat->name); + ret = regulator_set_enable(priv->reg, true); + if (ret) { + debug("%s: Cannot enable regulator for PWM '%s'\n", + __func__, dev->name); + return ret; + } + mdelay(120); } - mdelay(120); duty_cycle = priv->period_ns * (priv->default_level - priv->min_level) / (priv->max_level - priv->min_level + 1); @@ -68,10 +70,8 @@ static int pwm_backlight_ofdata_to_platdata(struct udevice *dev) debug("%s: start\n", __func__); ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, "power-supply", &priv->reg); - if (ret) { + if (ret) debug("%s: Cannot get power supply: ret=%d\n", __func__, ret); - return ret; - } ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, GPIOD_IS_OUT); if (ret) { From 5fba532954fe0363bcaa802ba4990e9466dc7d8c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 2 Mar 2018 20:50:17 +0100 Subject: [PATCH 6/7] video: indicate code page of bitmap fonts Add comments clarifying that the bitmap fonts support code page 437. Signed-off-by: Heinrich Schuchardt --- drivers/video/vidconsole-uclass.c | 2 +- include/video_font_4x6.h | 4 ++-- include/video_font_data.h | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 6f3988d49e..5553d629b9 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -13,7 +13,7 @@ #include #include #include -#include /* Get font data, width and height */ +#include /* Bitmap font for code page 437 */ /* * Structure to describe a console color diff --git a/include/video_font_4x6.h b/include/video_font_4x6.h index 6aeed092ad..64c5ed2eda 100644 --- a/include/video_font_4x6.h +++ b/include/video_font_4x6.h @@ -1,5 +1,5 @@ -/* Hand composed "Minuscule" 4x6 font, with binary data generated using - * Perl stub. +/* Hand composed "Minuscule" 4x6 font for code page 437, with binary data + * generated using Perl stub. * * Use 'perl -x mini_4x6.c < mini_4x6.c > new_version.c' to regenerate * binary data. diff --git a/include/video_font_data.h b/include/video_font_data.h index 346a162f56..d52526a63c 100644 --- a/include/video_font_data.h +++ b/include/video_font_data.h @@ -3,6 +3,8 @@ * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it * * SPDX-License-Identifier: GPL-2.0+ + * + * This file contains an 8x16 bitmap font for code page 437. */ #ifndef _VIDEO_FONT_DATA_ From d06717f853cd98a6a4536e5de5248e6c99a2b7bc Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 3 Mar 2018 10:30:17 +0100 Subject: [PATCH 7/7] sunxi: video: mark framebuffer as EFI reserved memory Inform the EFI subsystem that the framebuffer memory is reserved. Without the patch the AllocatePool boot service allocates memory from the framebuffer which will will be overwritten by screen output. Signed-off-by: Heinrich Schuchardt --- drivers/video/sunxi/sunxi_display.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c index f191ef16c6..4da169fffd 100644 --- a/drivers/video/sunxi/sunxi_display.c +++ b/drivers/video/sunxi/sunxi_display.c @@ -8,6 +8,7 @@ */ #include +#include #include #include @@ -1207,6 +1208,13 @@ void *video_hw_init(void) gd->bd->bi_dram[0].size - sunxi_display.fb_size; sunxi_engines_init(); +#ifdef CONFIG_EFI_LOADER + efi_add_memory_map(gd->fb_base, + ALIGN(sunxi_display.fb_size, EFI_PAGE_SIZE) >> + EFI_PAGE_SHIFT, + EFI_RESERVED_MEMORY_TYPE, false); +#endif + fb_dma_addr = gd->fb_base - CONFIG_SYS_SDRAM_BASE; sunxi_display.fb_addr = gd->fb_base; if (overscan_offset) {