aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/pwm_backlight.c24
-rw-r--r--drivers/video/sunxi/sunxi_display.c8
-rw-r--r--drivers/video/vidconsole-uclass.c88
-rw-r--r--drivers/video/video-uclass.c38
-rw-r--r--include/video.h13
-rw-r--r--include/video_console.h43
-rw-r--r--include/video_font_4x6.h4
-rw-r--r--include/video_font_data.h2
-rw-r--r--test/dm/video.c2
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;
}