diff options
-rw-r--r-- | drivers/video/pwm_backlight.c | 24 | ||||
-rw-r--r-- | drivers/video/sunxi/sunxi_display.c | 8 | ||||
-rw-r--r-- | drivers/video/vidconsole-uclass.c | 88 | ||||
-rw-r--r-- | drivers/video/video-uclass.c | 38 | ||||
-rw-r--r-- | include/video.h | 13 | ||||
-rw-r--r-- | include/video_console.h | 43 | ||||
-rw-r--r-- | include/video_font_4x6.h | 4 | ||||
-rw-r--r-- | include/video_font_data.h | 2 | ||||
-rw-r--r-- | test/dm/video.c | 2 |
9 files changed, 167 insertions, 55 deletions
diff --git a/drivers/video/pwm_backlight.c b/drivers/video/pwm_backlight.c index fbd7bf78389..f40e57bb8e6 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) { diff --git a/drivers/video/sunxi/sunxi_display.c b/drivers/video/sunxi/sunxi_display.c index f191ef16c63..4da169fffd8 100644 --- a/drivers/video/sunxi/sunxi_display.c +++ b/drivers/video/sunxi/sunxi_display.c @@ -8,6 +8,7 @@ */ #include <common.h> +#include <efi_loader.h> #include <asm/arch/clock.h> #include <asm/arch/display.h> @@ -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) { diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index 5f63c12d6c5..5553d629b98 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -13,7 +13,16 @@ #include <dm.h> #include <video.h> #include <video_console.h> -#include <video_font.h> /* Get font data, width and height */ +#include <video_font.h> /* Bitmap font for code page 437 */ + +/* + * 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 @@ -108,38 +117,45 @@ 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 */ + { 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 */ }; -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) << 0) | - ((colors[idx].g >> 2) << 5) | - ((colors[idx].b >> 3) << 11); - break; + return ((colors[idx].r >> 3) << 11) | + ((colors[idx].g >> 2) << 5) | + ((colors[idx].b >> 3) << 0); case VIDEO_BPP32: - *c = 0xff000000 | - (colors[idx].r << 0) | - (colors[idx].g << 8) | - (colors[idx].b << 16); - 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,18 +286,30 @@ 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: - /* fg color */ - set_color(vid_priv, val - 30, - (unsigned *)&vid_priv->colour_fg); + /* foreground color */ + vid_priv->fg_col_idx &= ~7; + vid_priv->fg_col_idx |= val - 30; + vid_priv->colour_fg = vid_console_color( + vid_priv, vid_priv->fg_col_idx); 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 dcaceed42c4..b5bb8e0efde 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -91,17 +91,43 @@ 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; } } +void video_set_default_colors(struct video_priv *priv) +{ +#ifdef CONFIG_SYS_WHITE_ON_BLACK + /* 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 +} + /* Flush video activity to the caches */ void video_sync(struct udevice *vid) { @@ -191,12 +217,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 61ff6531215..ddc2eeb5a95 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: */ @@ -84,10 +85,11 @@ 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; + u8 fg_col_idx; }; /* Placeholder - there are no video operations at present */ @@ -183,6 +185,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 9dce234bd92..7621a189d2a 100644 --- a/include/video_console.h +++ b/include/video_console.h @@ -7,11 +7,37 @@ #ifndef __video_console_h #define __video_console_h +#include <video.h> + #define VID_FRAC_DIV 256 #define VID_TO_PIXEL(x) ((x) / VID_FRAC_DIV) #define VID_TO_POS(x) ((x) * VID_FRAC_DIV) +/* + * The 16 colors supported by the console + */ +enum color_idx { + VID_BLACK = 0, + VID_RED, + VID_GREEN, + 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 +}; + /** * struct vidconsole_priv - uclass-private data about a console device * @@ -196,4 +222,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 diff --git a/include/video_font_4x6.h b/include/video_font_4x6.h index 6aeed092ad4..64c5ed2eda4 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 346a162f56f..d52526a63c8 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_ diff --git a/test/dm/video.c b/test/dm/video.c index 29917d0c2d8..caca4969027 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(265, compress_frame_buffer(dev)); return 0; } |