summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig30
-rw-r--r--drivers/video/Makefile6
-rw-r--r--drivers/video/console_core.c212
-rw-r--r--drivers/video/console_normal.c177
-rw-r--r--drivers/video/console_rotate.c371
-rw-r--r--drivers/video/console_truetype.c3
-rw-r--r--drivers/video/vidconsole-uclass.c11
-rw-r--r--drivers/video/vidconsole_internal.h120
8 files changed, 530 insertions, 400 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2a76d19cc8..60f4a4bf9c 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -16,6 +16,35 @@ config VIDEO
if VIDEO
+config VIDEO_FONT_4X6
+ bool "4 x 6 font size"
+ help
+ Font for video console driver, 4 x 6 pixels.
+ Provides character bitmap data in header file.
+ When selecting multiple fonts, you may want to enable CMD_SELECT_FONT too.
+
+config VIDEO_FONT_8X16
+ bool "8 x 16 font size"
+ default y
+ help
+ Font for video console driver, 8 x 16 pixels
+ Provides character bitmap data in header file.
+ When selecting multiple fonts, you may want to enable CMD_SELECT_FONT too.
+
+config VIDEO_FONT_SUN12X22
+ bool "12 x 22 font size"
+ help
+ Font for video console driver, 12 x 22 pixels
+ Provides character bitmap data in header file.
+ When selecting multiple fonts, you may want to enable CMD_SELECT_FONT too.
+
+config VIDEO_FONT_16X32
+ bool "16 x 32 font size"
+ help
+ Font for video console driver, 16 x 32 pixels
+ Provides character bitmap data in header file.
+ When selecting multiple fonts, you may want to enable CMD_SELECT_FONT too.
+
config VIDEO_LOGO
bool "Show the U-Boot logo on the display"
default y if !SPLASH_SCREEN
@@ -150,6 +179,7 @@ config CONSOLE_ROTATION
config CONSOLE_TRUETYPE
bool "Support a console that uses TrueType fonts"
+ select CMD_SELECT_FONT
help
TrueTrype fonts can provide outline-drawing capability rather than
needing to provide a bitmap for each font and size that is needed.
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index cdb7d9a54d..cb3f373645 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -9,6 +9,12 @@ obj-$(CONFIG_BACKLIGHT_GPIO) += backlight_gpio.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_backlight.o
obj-$(CONFIG_CONSOLE_NORMAL) += console_normal.o
obj-$(CONFIG_CONSOLE_ROTATION) += console_rotate.o
+ifdef CONFIG_CONSOLE_NORMAL
+obj-y += console_core.o
+else ifdef CONFIG_CONSOLE_ROTATION
+obj-y += console_core.o
+endif
+obj-$(CONFIG_CONSOLE_ROTATION) += console_core.o
obj-$(CONFIG_CONSOLE_TRUETYPE) += console_truetype.o fonts/
obj-$(CONFIG_DISPLAY) += display-uclass.o
obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi-host-uclass.o
diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c
new file mode 100644
index 0000000000..d4f79c656a
--- /dev/null
+++ b/drivers/video/console_core.c
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2015 Google, Inc
+ * (C) Copyright 2015
+ * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
+ * (C) Copyright 2023 Dzmitry Sankouski <dsankouski@gmail.com>
+ */
+
+#include <video.h>
+#include <video_console.h>
+#include <dm.h>
+#include <video_font.h>
+#include "vidconsole_internal.h"
+
+/**
+ * console_set_font() - prepare vidconsole for chosen font.
+ *
+ * @dev vidconsole device
+ * @fontdata pointer to font data struct
+ */
+static int console_set_font(struct udevice *dev, struct video_fontdata *fontdata)
+{
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
+ struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+
+ debug("console_simple: setting %s font\n", fontdata->name);
+ debug("width: %d\n", fontdata->width);
+ debug("byte width: %d\n", fontdata->byte_width);
+ debug("height: %d\n", fontdata->height);
+
+ priv->fontdata = fontdata;
+ vc_priv->x_charsize = fontdata->width;
+ vc_priv->y_charsize = fontdata->height;
+ if (vid_priv->rot % 2) {
+ vc_priv->cols = vid_priv->ysize / fontdata->width;
+ vc_priv->rows = vid_priv->xsize / fontdata->height;
+ vc_priv->xsize_frac = VID_TO_POS(vid_priv->ysize);
+ } else {
+ vc_priv->cols = vid_priv->xsize / fontdata->width;
+ vc_priv->rows = vid_priv->ysize / fontdata->height;
+ }
+
+ return 0;
+}
+
+int check_bpix_support(int bpix)
+{
+ if (bpix == VIDEO_BPP8 && IS_ENABLED(CONFIG_VIDEO_BPP8))
+ return 0;
+ else if (bpix == VIDEO_BPP16 && IS_ENABLED(CONFIG_VIDEO_BPP16))
+ return 0;
+ else if (bpix == VIDEO_BPP32 && IS_ENABLED(CONFIG_VIDEO_BPP32))
+ return 0;
+ else
+ return -ENOSYS;
+}
+
+inline void fill_pixel_and_goto_next(void **dstp, u32 value, int pbytes, int step)
+{
+ u8 *dst_byte = *dstp;
+
+ if (pbytes == 4) {
+ u32 *dst = *dstp;
+ *dst = value;
+ }
+ if (pbytes == 2) {
+ u16 *dst = *dstp;
+ *dst = value;
+ }
+ if (pbytes == 1) {
+ u8 *dst = *dstp;
+ *dst = value;
+ }
+ *dstp = dst_byte + step;
+}
+
+int fill_char_vertically(uchar *pfont, void **line, struct video_priv *vid_priv,
+ struct video_fontdata *fontdata, bool direction)
+{
+ int step, line_step, pbytes, bitcount, width_remainder, ret;
+ void *dst;
+
+ ret = check_bpix_support(vid_priv->bpix);
+ if (ret)
+ return ret;
+
+ pbytes = VNBYTES(vid_priv->bpix);
+ if (direction) {
+ step = -pbytes;
+ line_step = -vid_priv->line_length;
+ } else {
+ step = pbytes;
+ line_step = vid_priv->line_length;
+ }
+
+ width_remainder = fontdata->width % 8;
+ for (int row = 0; row < fontdata->height; row++) {
+ uchar bits;
+
+ bitcount = 8;
+ dst = *line;
+ for (int col = 0; col < fontdata->byte_width; col++) {
+ if (width_remainder) {
+ bool is_last_col = (fontdata->byte_width - col == 1);
+
+ if (is_last_col)
+ bitcount = width_remainder;
+ }
+ bits = pfont[col];
+
+ for (int bit = 0; bit < bitcount; bit++) {
+ u32 value = (bits & 0x80) ?
+ vid_priv->colour_fg :
+ vid_priv->colour_bg;
+
+ fill_pixel_and_goto_next(&dst,
+ value,
+ pbytes,
+ step
+ );
+ bits <<= 1;
+ }
+ }
+ *line += line_step;
+ pfont += fontdata->byte_width;
+ }
+ return ret;
+}
+
+int fill_char_horizontally(uchar *pfont, void **line, struct video_priv *vid_priv,
+ struct video_fontdata *fontdata, bool direction)
+{
+ int step, line_step, pbytes, bitcount = 8, width_remainder, ret;
+ void *dst;
+ u8 mask;
+
+ ret = check_bpix_support(vid_priv->bpix);
+ if (ret)
+ return ret;
+
+ pbytes = VNBYTES(vid_priv->bpix);
+ if (direction) {
+ step = -pbytes;
+ line_step = vid_priv->line_length;
+ } else {
+ step = pbytes;
+ line_step = -vid_priv->line_length;
+ }
+
+ width_remainder = fontdata->width % 8;
+ for (int col = 0; col < fontdata->byte_width; col++) {
+ mask = 0x80;
+ if (width_remainder) {
+ bool is_last_col = (fontdata->byte_width - col == 1);
+
+ if (is_last_col)
+ bitcount = width_remainder;
+ }
+ for (int bit = 0; bit < bitcount; bit++) {
+ dst = *line;
+ for (int row = 0; row < fontdata->height; row++) {
+ u32 value = (pfont[row * fontdata->byte_width + col]
+ & mask) ? vid_priv->colour_fg : vid_priv->colour_bg;
+
+ fill_pixel_and_goto_next(&dst,
+ value,
+ pbytes,
+ step
+ );
+ }
+ *line += line_step;
+ mask >>= 1;
+ }
+ }
+ return ret;
+}
+
+int console_probe(struct udevice *dev)
+{
+ return console_set_font(dev, fonts);
+}
+
+const char *console_simple_get_font_size(struct udevice *dev, uint *sizep)
+{
+ struct console_simple_priv *priv = dev_get_priv(dev);
+
+ *sizep = priv->fontdata->width;
+
+ return priv->fontdata->name;
+}
+
+int console_simple_get_font(struct udevice *dev, int seq, struct vidfont_info *info)
+{
+ info->name = fonts[seq].name;
+
+ return 0;
+}
+
+int console_simple_select_font(struct udevice *dev, const char *name, uint size)
+{
+ struct video_fontdata *font;
+
+ for (font = fonts; font->name; font++) {
+ if (!strcmp(name, font->name)) {
+ console_set_font(dev, font);
+ return 0;
+ }
+ };
+ printf("no such font: %s, make sure it's name has <width>x<height> format\n", name);
+ return -ENOENT;
+}
diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index 04f022491e..413c7abee9 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -1,10 +1,9 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2015 Google, Inc
- * (C) Copyright 2001-2015
- * DENX Software Engineering -- wd@denx.de
- * Compulab Ltd - http://compulab.co.il/
+ * (C) Copyright 2015
* Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
+ * (C) Copyright 2023 Dzmitry Sankouski <dsankouski@gmail.com>
*/
#include <common.h>
@@ -12,47 +11,30 @@
#include <video.h>
#include <video_console.h>
#include <video_font.h> /* Get font data, width and height */
+#include "vidconsole_internal.h"
-static int console_normal_set_row(struct udevice *dev, uint row, int clr)
+static int console_set_row(struct udevice *dev, uint row, int clr)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
- void *line, *end;
- int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
+ void *line, *dst, *end;
+ int pixels = fontdata->height * vid_priv->xsize;
int ret;
int i;
+ int pbytes;
+
+ ret = check_bpix_support(vid_priv->bpix);
+ if (ret)
+ return ret;
+
+ line = vid_priv->fb + row * fontdata->height * vid_priv->line_length;
+ dst = line;
+ pbytes = VNBYTES(vid_priv->bpix);
+ for (i = 0; i < pixels; i++)
+ fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
+ end = dst;
- line = vid_priv->fb + row * VIDEO_FONT_HEIGHT * vid_priv->line_length;
- switch (vid_priv->bpix) {
- case VIDEO_BPP8:
- if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
- uint8_t *dst = line;
-
- for (i = 0; i < pixels; i++)
- *dst++ = clr;
- end = dst;
- break;
- }
- case VIDEO_BPP16:
- if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
- uint16_t *dst = line;
-
- for (i = 0; i < pixels; i++)
- *dst++ = clr;
- end = dst;
- break;
- }
- case VIDEO_BPP32:
- if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
- uint32_t *dst = line;
-
- for (i = 0; i < pixels; i++)
- *dst++ = clr;
- end = dst;
- break;
- }
- default:
- return -ENOSYS;
- }
ret = vidconsole_sync_copy(dev, line, end);
if (ret)
return ret;
@@ -60,18 +42,20 @@ static int console_normal_set_row(struct udevice *dev, uint row, int clr)
return 0;
}
-static int console_normal_move_rows(struct udevice *dev, uint rowdst,
- uint rowsrc, uint count)
+static int console_move_rows(struct udevice *dev, uint rowdst,
+ uint rowsrc, uint count)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
void *dst;
void *src;
int size;
int ret;
- dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * vid_priv->line_length;
- src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * vid_priv->line_length;
- size = VIDEO_FONT_HEIGHT * vid_priv->line_length * count;
+ dst = vid_priv->fb + rowdst * fontdata->height * vid_priv->line_length;
+ src = vid_priv->fb + rowsrc * fontdata->height * vid_priv->line_length;
+ size = fontdata->height * vid_priv->line_length * count;
ret = vidconsole_memmove(dev, dst, src, size);
if (ret)
return ret;
@@ -79,100 +63,53 @@ static int console_normal_move_rows(struct udevice *dev, uint rowdst,
return 0;
}
-static int console_normal_putc_xy(struct udevice *dev, uint x_frac, uint y,
- char ch)
+static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, char ch)
{
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
- int i, row;
- void *start;
- void *line;
- int ret;
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
+ int pbytes = VNBYTES(vid_priv->bpix);
+ int x, linenum, ret;
+ void *start, *line;
+ uchar *pfont = fontdata->video_fontdata +
+ (u8)ch * fontdata->char_pixel_bytes;
- start = vid_priv->fb + y * vid_priv->line_length +
- VID_TO_PIXEL(x_frac) * VNBYTES(vid_priv->bpix);
+ if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
+ return -EAGAIN;
+ linenum = y;
+ x = VID_TO_PIXEL(x_frac);
+ start = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
line = start;
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
- for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
- unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
- uchar bits = video_fontdata[idx];
-
- switch (vid_priv->bpix) {
- case VIDEO_BPP8:
- if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
- uint8_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
- *dst++ = (bits & 0x80) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- bits <<= 1;
- }
- break;
- }
- case VIDEO_BPP16:
- if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
- uint16_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
- *dst++ = (bits & 0x80) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- bits <<= 1;
- }
- break;
- }
- case VIDEO_BPP32:
- if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
- uint32_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
- *dst++ = (bits & 0x80) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- bits <<= 1;
- }
- break;
- }
- default:
- return -ENOSYS;
- }
- line += vid_priv->line_length;
- }
- ret = vidconsole_sync_copy(dev, start, line);
+ ret = fill_char_vertically(pfont, &line, vid_priv, fontdata, NORMAL_DIRECTION);
if (ret)
return ret;
- return VID_TO_POS(VIDEO_FONT_WIDTH);
-}
-
-static int console_normal_probe(struct udevice *dev)
-{
- struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
- struct udevice *vid_dev = dev->parent;
- struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
-
- vc_priv->x_charsize = VIDEO_FONT_WIDTH;
- vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
- vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH;
- vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT;
+ ret = vidconsole_sync_copy(dev, start, line);
+ if (ret)
+ return ret;
- return 0;
+ return VID_TO_POS(fontdata->width);
}
-struct vidconsole_ops console_normal_ops = {
- .putc_xy = console_normal_putc_xy,
- .move_rows = console_normal_move_rows,
- .set_row = console_normal_set_row,
+struct vidconsole_ops console_ops = {
+ .putc_xy = console_putc_xy,
+ .move_rows = console_move_rows,
+ .set_row = console_set_row,
+ .get_font_size = console_simple_get_font_size,
+ .get_font = console_simple_get_font,
+ .select_font = console_simple_select_font,
};
U_BOOT_DRIVER(vidconsole_normal) = {
- .name = "vidconsole0",
- .id = UCLASS_VIDEO_CONSOLE,
- .ops = &console_normal_ops,
- .probe = console_normal_probe,
+ .name = "vidconsole0",
+ .id = UCLASS_VIDEO_CONSOLE,
+ .ops = &console_ops,
+ .probe = console_probe,
+ .priv_auto = sizeof(struct console_simple_priv),
};
diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index 36c8d0609d..65358a1c6e 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -3,6 +3,7 @@
* Copyright (c) 2015 Google, Inc
* (C) Copyright 2015
* Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
+ * (C) Copyright 2023 Dzmitry Sankouski <dsankouski@gmail.com>
*/
#include <common.h>
@@ -10,47 +11,25 @@
#include <video.h>
#include <video_console.h>
#include <video_font.h> /* Get font data, width and height */
+#include "vidconsole_internal.h"
static int console_set_row_1(struct udevice *dev, uint row, int clr)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
int pbytes = VNBYTES(vid_priv->bpix);
- void *start, *line;
+ void *start, *dst, *line;
int i, j;
int ret;
start = vid_priv->fb + vid_priv->line_length -
- (row + 1) * VIDEO_FONT_HEIGHT * pbytes;
+ (row + 1) * fontdata->height * pbytes;
line = start;
for (j = 0; j < vid_priv->ysize; j++) {
- switch (vid_priv->bpix) {
- case VIDEO_BPP8:
- if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
- uint8_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
- *dst++ = clr;
- break;
- }
- case VIDEO_BPP16:
- if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
- uint16_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
- *dst++ = clr;
- break;
- }
- case VIDEO_BPP32:
- if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
- uint32_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
- *dst++ = clr;
- break;
- }
- default:
- return -ENOSYS;
- }
+ dst = line;
+ for (i = 0; i < fontdata->height; i++)
+ fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
line += vid_priv->line_length;
}
ret = vidconsole_sync_copy(dev, start, line);
@@ -61,22 +40,24 @@ static int console_set_row_1(struct udevice *dev, uint row, int clr)
}
static int console_move_rows_1(struct udevice *dev, uint rowdst, uint rowsrc,
- uint count)
+ uint count)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
int pbytes = VNBYTES(vid_priv->bpix);
void *dst;
void *src;
int j, ret;
dst = vid_priv->fb + vid_priv->line_length -
- (rowdst + count) * VIDEO_FONT_HEIGHT * pbytes;
+ (rowdst + count) * fontdata->height * pbytes;
src = vid_priv->fb + vid_priv->line_length -
- (rowsrc + count) * VIDEO_FONT_HEIGHT * pbytes;
+ (rowsrc + count) * fontdata->height * pbytes;
for (j = 0; j < vid_priv->ysize; j++) {
ret = vidconsole_memmove(dev, dst, src,
- VIDEO_FONT_HEIGHT * pbytes * count);
+ fontdata->height * pbytes * count);
if (ret)
return ret;
src += vid_priv->line_length;
@@ -91,110 +72,51 @@ static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
- uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
int pbytes = VNBYTES(vid_priv->bpix);
- int i, col, x, linenum, ret;
- int mask = 0x80;
+ int x, linenum, ret;
void *start, *line;
+ uchar *pfont = fontdata->video_fontdata +
+ (u8)ch * fontdata->char_pixel_bytes;
+ if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
+ return -EAGAIN;
linenum = VID_TO_PIXEL(x_frac) + 1;
x = y + 1;
start = vid_priv->fb + linenum * vid_priv->line_length - x * pbytes;
line = start;
- if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
- return -EAGAIN;
- for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
- switch (vid_priv->bpix) {
- case VIDEO_BPP8:
- if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
- uint8_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
- *dst-- = (pfont[i] & mask) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- }
- break;
- }
- case VIDEO_BPP16:
- if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
- uint16_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
- *dst-- = (pfont[i] & mask) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- }
- break;
- }
- case VIDEO_BPP32:
- if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
- uint32_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
- *dst-- = (pfont[i] & mask) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- }
- break;
- }
- default:
- return -ENOSYS;
- }
- line += vid_priv->line_length;
- mask >>= 1;
- }
+ ret = fill_char_horizontally(pfont, &line, vid_priv, fontdata, FLIPPED_DIRECTION);
+ if (ret)
+ return ret;
+
/* We draw backwards from 'start, so account for the first line */
ret = vidconsole_sync_copy(dev, start - vid_priv->line_length, line);
if (ret)
return ret;
- return VID_TO_POS(VIDEO_FONT_WIDTH);
+ return VID_TO_POS(fontdata->width);
}
static int console_set_row_2(struct udevice *dev, uint row, int clr)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
- void *start, *line, *end;
- int pixels = VIDEO_FONT_HEIGHT * vid_priv->xsize;
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
+ void *start, *line, *dst, *end;
+ int pixels = fontdata->height * vid_priv->xsize;
int i, ret;
+ int pbytes = VNBYTES(vid_priv->bpix);
start = vid_priv->fb + vid_priv->ysize * vid_priv->line_length -
- (row + 1) * VIDEO_FONT_HEIGHT * vid_priv->line_length;
+ (row + 1) * fontdata->height * vid_priv->line_length;
line = start;
- switch (vid_priv->bpix) {
- case VIDEO_BPP8:
- if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
- uint8_t *dst = line;
-
- for (i = 0; i < pixels; i++)
- *dst++ = clr;
- end = dst;
- break;
- }
- case VIDEO_BPP16:
- if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
- uint16_t *dst = line;
-
- for (i = 0; i < pixels; i++)
- *dst++ = clr;
- end = dst;
- break;
- }
- case VIDEO_BPP32:
- if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
- uint32_t *dst = line;
-
- for (i = 0; i < pixels; i++)
- *dst++ = clr;
- end = dst;
- break;
- }
- default:
- return -ENOSYS;
- }
+ dst = line;
+ for (i = 0; i < pixels; i++)
+ fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
+ end = dst;
ret = vidconsole_sync_copy(dev, start, end);
if (ret)
return ret;
@@ -206,17 +128,19 @@ static int console_move_rows_2(struct udevice *dev, uint rowdst, uint rowsrc,
uint count)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
void *dst;
void *src;
void *end;
end = vid_priv->fb + vid_priv->ysize * vid_priv->line_length;
- dst = end - (rowdst + count) * VIDEO_FONT_HEIGHT *
+ dst = end - (rowdst + count) * fontdata->height *
vid_priv->line_length;
- src = end - (rowsrc + count) * VIDEO_FONT_HEIGHT *
+ src = end - (rowsrc + count) * fontdata->height *
vid_priv->line_length;
vidconsole_memmove(dev, dst, src,
- VIDEO_FONT_HEIGHT * vid_priv->line_length * count);
+ fontdata->height * vid_priv->line_length * count);
return 0;
}
@@ -226,9 +150,13 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
int pbytes = VNBYTES(vid_priv->bpix);
- int i, row, x, linenum, ret;
+ int linenum, x, ret;
void *start, *line;
+ uchar *pfont = fontdata->video_fontdata +
+ (u8)ch * fontdata->char_pixel_bytes;
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
@@ -237,98 +165,33 @@ static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
start = vid_priv->fb + linenum * vid_priv->line_length + x * pbytes;
line = start;
- for (row = 0; row < VIDEO_FONT_HEIGHT; row++) {
- unsigned int idx = (u8)ch * VIDEO_FONT_HEIGHT + row;
- uchar bits = video_fontdata[idx];
-
- switch (vid_priv->bpix) {
- case VIDEO_BPP8:
- if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
- uint8_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
- *dst-- = (bits & 0x80) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- bits <<= 1;
- }
- break;
- }
- case VIDEO_BPP16:
- if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
- uint16_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
- *dst-- = (bits & 0x80) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- bits <<= 1;
- }
- break;
- }
- case VIDEO_BPP32:
- if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
- uint32_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_WIDTH; i++) {
- *dst-- = (bits & 0x80) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- bits <<= 1;
- }
- break;
- }
- default:
- return -ENOSYS;
- }
- line -= vid_priv->line_length;
- }
+ ret = fill_char_vertically(pfont, &line, vid_priv, fontdata, FLIPPED_DIRECTION);
+ if (ret)
+ return ret;
+
/* Add 4 bytes to allow for the first pixel writen */
ret = vidconsole_sync_copy(dev, start + 4, line);
if (ret)
return ret;
- return VID_TO_POS(VIDEO_FONT_WIDTH);
+ return VID_TO_POS(fontdata->width);
}
static int console_set_row_3(struct udevice *dev, uint row, int clr)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
int pbytes = VNBYTES(vid_priv->bpix);
- void *start, *line;
+ void *start, *dst, *line;
int i, j, ret;
- start = vid_priv->fb + row * VIDEO_FONT_HEIGHT * pbytes;
+ start = vid_priv->fb + row * fontdata->height * pbytes;
line = start;
for (j = 0; j < vid_priv->ysize; j++) {
- switch (vid_priv->bpix) {
- case VIDEO_BPP8:
- if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
- uint8_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
- *dst++ = clr;
- break;
- }
- case VIDEO_BPP16:
- if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
- uint16_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
- *dst++ = clr;
- break;
- }
- case VIDEO_BPP32:
- if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
- uint32_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++)
- *dst++ = clr;
- break;
- }
- default:
- return -ENOSYS;
- }
+ dst = line;
+ for (i = 0; i < fontdata->height; i++)
+ fill_pixel_and_goto_next(&dst, clr, pbytes, pbytes);
line += vid_priv->line_length;
}
ret = vidconsole_sync_copy(dev, start, line);
@@ -342,17 +205,19 @@ static int console_move_rows_3(struct udevice *dev, uint rowdst, uint rowsrc,
uint count)
{
struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent);
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
int pbytes = VNBYTES(vid_priv->bpix);
void *dst;
void *src;
int j, ret;
- dst = vid_priv->fb + rowdst * VIDEO_FONT_HEIGHT * pbytes;
- src = vid_priv->fb + rowsrc * VIDEO_FONT_HEIGHT * pbytes;
+ dst = vid_priv->fb + rowdst * fontdata->height * pbytes;
+ src = vid_priv->fb + rowsrc * fontdata->height * pbytes;
for (j = 0; j < vid_priv->ysize; j++) {
ret = vidconsole_memmove(dev, dst, src,
- VIDEO_FONT_HEIGHT * pbytes * count);
+ fontdata->height * pbytes * count);
if (ret)
return ret;
src += vid_priv->line_length;
@@ -367,131 +232,79 @@ static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
struct video_priv *vid_priv = dev_get_uclass_priv(vid);
- uchar *pfont = video_fontdata + (u8)ch * VIDEO_FONT_HEIGHT;
+ struct console_simple_priv *priv = dev_get_priv(dev);
+ struct video_fontdata *fontdata = priv->fontdata;
int pbytes = VNBYTES(vid_priv->bpix);
- int i, col, x, ret;
- int mask = 0x80;
+ int linenum, x, ret;
void *start, *line;
+ uchar *pfont = fontdata->video_fontdata +
+ (u8)ch * fontdata->char_pixel_bytes;
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
- x = vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1;
- start = vid_priv->fb + x * vid_priv->line_length + y * pbytes;
+ x = y;
+ linenum = vid_priv->ysize - VID_TO_PIXEL(x_frac) - 1;
+ start = vid_priv->fb + linenum * vid_priv->line_length + y * pbytes;
line = start;
- for (col = 0; col < VIDEO_FONT_HEIGHT; col++) {
- switch (vid_priv->bpix) {
- case VIDEO_BPP8:
- if (IS_ENABLED(CONFIG_VIDEO_BPP8)) {
- uint8_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
- *dst++ = (pfont[i] & mask) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- }
- break;
- }
- case VIDEO_BPP16:
- if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
- uint16_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
- *dst++ = (pfont[i] & mask) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- }
- break;
- }
- case VIDEO_BPP32:
- if (IS_ENABLED(CONFIG_VIDEO_BPP32)) {
- uint32_t *dst = line;
-
- for (i = 0; i < VIDEO_FONT_HEIGHT; i++) {
- *dst++ = (pfont[i] & mask) ?
- vid_priv->colour_fg :
- vid_priv->colour_bg;
- }
- break;
- }
- default:
- return -ENOSYS;
- }
- line -= vid_priv->line_length;
- mask >>= 1;
- }
+
+ ret = fill_char_horizontally(pfont, &line, vid_priv, fontdata, NORMAL_DIRECTION);
+ if (ret)
+ return ret;
/* Add a line to allow for the first pixels writen */
ret = vidconsole_sync_copy(dev, start + vid_priv->line_length, line);
if (ret)
return ret;
- return VID_TO_POS(VIDEO_FONT_WIDTH);
-}
-
-
-static int console_probe_2(struct udevice *dev)
-{
- struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
- struct udevice *vid_dev = dev->parent;
- struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
-
- vc_priv->x_charsize = VIDEO_FONT_WIDTH;
- vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
- vc_priv->cols = vid_priv->xsize / VIDEO_FONT_WIDTH;
- vc_priv->rows = vid_priv->ysize / VIDEO_FONT_HEIGHT;
-
- return 0;
-}
-
-static int console_probe_1_3(struct udevice *dev)
-{
- struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
- struct udevice *vid_dev = dev->parent;
- struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev);
-
- vc_priv->x_charsize = VIDEO_FONT_WIDTH;
- vc_priv->y_charsize = VIDEO_FONT_HEIGHT;
- vc_priv->cols = vid_priv->ysize / VIDEO_FONT_WIDTH;
- vc_priv->rows = vid_priv->xsize / VIDEO_FONT_HEIGHT;
- vc_priv->xsize_frac = VID_TO_POS(vid_priv->ysize);
-
- return 0;
+ return VID_TO_POS(fontdata->width);
}
struct vidconsole_ops console_ops_1 = {
.putc_xy = console_putc_xy_1,
.move_rows = console_move_rows_1,
.set_row = console_set_row_1,
+ .get_font_size = console_simple_get_font_size,
+ .get_font = console_simple_get_font,
+ .select_font = console_simple_select_font,
};
struct vidconsole_ops console_ops_2 = {
.putc_xy = console_putc_xy_2,
.move_rows = console_move_rows_2,
.set_row = console_set_row_2,
+ .get_font_size = console_simple_get_font_size,
+ .get_font = console_simple_get_font,
+ .select_font = console_simple_select_font,
};
struct vidconsole_ops console_ops_3 = {
.putc_xy = console_putc_xy_3,
.move_rows = console_move_rows_3,
.set_row = console_set_row_3,
+ .get_font_size = console_simple_get_font_size,
+ .get_font = console_simple_get_font,
+ .select_font = console_simple_select_font,
};
U_BOOT_DRIVER(vidconsole_1) = {
.name = "vidconsole1",
.id = UCLASS_VIDEO_CONSOLE,
.ops = &console_ops_1,
- .probe = console_probe_1_3,
+ .probe = console_probe,
+ .priv_auto = sizeof(struct console_simple_priv),
};
U_BOOT_DRIVER(vidconsole_2) = {
.name = "vidconsole2",
.id = UCLASS_VIDEO_CONSOLE,
.ops = &console_ops_2,
- .probe = console_probe_2,
+ .probe = console_probe,
+ .priv_auto = sizeof(struct console_simple_priv),
};
U_BOOT_DRIVER(vidconsole_3) = {
.name = "vidconsole3",
.id = UCLASS_VIDEO_CONSOLE,
.ops = &console_ops_3,
- .probe = console_probe_1_3,
+ .probe = console_probe,
+ .priv_auto = sizeof(struct console_simple_priv),
};
diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 9cac9a6de4..6b5390136a 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -724,7 +724,7 @@ static int truetype_select_font(struct udevice *dev, const char *name,
return 0;
}
-const char *vidconsole_get_font_size(struct udevice *dev, uint *sizep)
+const char *console_truetype_get_font_size(struct udevice *dev, uint *sizep)
{
struct console_tt_priv *priv = dev_get_priv(dev);
struct console_tt_metrics *met = priv->cur_met;
@@ -773,6 +773,7 @@ struct vidconsole_ops console_truetype_ops = {
.backspace = console_truetype_backspace,
.entry_start = console_truetype_entry_start,
.get_font = console_truetype_get_font,
+ .get_font_size = console_truetype_get_font_size,
.select_font = truetype_select_font,
};
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 72a13d3052..a5f2350ca1 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -575,6 +575,17 @@ int vidconsole_get_font(struct udevice *dev, int seq,
return ops->get_font(dev, seq, info);
}
+int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep)
+{
+ struct vidconsole_ops *ops = vidconsole_get_ops(dev);
+
+ if (!ops->get_font_size)
+ return -ENOSYS;
+
+ *name = ops->get_font_size(dev, sizep);
+ return 0;
+}
+
int vidconsole_select_font(struct udevice *dev, const char *name, uint size)
{
struct vidconsole_ops *ops = vidconsole_get_ops(dev);
diff --git a/drivers/video/vidconsole_internal.h b/drivers/video/vidconsole_internal.h
new file mode 100644
index 0000000000..c41edd4524
--- /dev/null
+++ b/drivers/video/vidconsole_internal.h
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2015 Google, Inc
+ * (C) Copyright 2015
+ * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
+ * (C) Copyright 2023 Dzmitry Sankouski <dsankouski@gmail.com>
+ */
+
+#define FLIPPED_DIRECTION 1
+#define NORMAL_DIRECTION 0
+
+/**
+ * struct console_simple_priv - Private data for this driver
+ *
+ * @video_fontdata font graphical representation data
+ */
+struct console_simple_priv {
+ struct video_fontdata *fontdata;
+};
+
+/**
+ * Checks if bits per pixel supported.
+ *
+ * @param bpix framebuffer bits per pixel.
+ *
+ * @returns 0, if supported, or else -ENOSYS.
+ */
+int check_bpix_support(int bpix);
+
+/**
+ * Fill 1 pixel in framebuffer, and go to next one.
+ *
+ * @param dstp a pointer to pointer to framebuffer.
+ * @param value value to write to framebuffer.
+ * @param pbytes framebuffer bytes per pixel.
+ * @param step framebuffer pointer increment. Usually is equal to pbytes,
+ * and may be negative to control filling direction.
+ */
+void fill_pixel_and_goto_next(void **dstp, u32 value, int pbytes, int step);
+
+/**
+ * Fills 1 character in framebuffer vertically. Vertically means we're filling char font data rows
+ * across the lines.
+ *
+ * @param pfont a pointer to character font data.
+ * @param line a pointer to pointer to framebuffer. It's a point for upper left char corner
+ * @param vid_priv driver private data.
+ * @fontdata font graphical representation data
+ * @param direction controls character orientation. Can be normal or flipped.
+ * When normal: When flipped:
+ *|-----------------------------------------------|
+ *| line stepping | |
+ *| | | stepping -> |
+ *| * | | * * * |
+ *| * * v | * |
+ *| * | * |
+ *| * | * * ^ |
+ *| * * * | * | |
+ *| | | |
+ *| stepping -> | line stepping |
+ *|---!!we're starting from upper left char corner|
+ *|-----------------------------------------------|
+ *
+ * @returns 0, if success, or else error code.
+ */
+int fill_char_vertically(uchar *pfont, void **line, struct video_priv *vid_priv,
+ struct video_fontdata *fontdata, bool direction);
+
+/**
+ * Fills 1 character in framebuffer horizontally.
+ * Horizontally means we're filling char font data columns across the lines.
+ *
+ * @param pfont a pointer to character font data.
+ * @param line a pointer to pointer to framebuffer. It's a point for upper left char corner
+ * @param vid_priv driver private data.
+ * @fontdata font graphical representation data
+ * @param direction controls character orientation. Can be normal or flipped.
+ * When normal: When flipped:
+ *|-----------------------------------------------|
+ *| * | line stepping |
+ *| ^ * * * * * | | |
+ *| | * * | v * * |
+ *| | | * * * * * |
+ *| line stepping | * |
+ *| | |
+ *| stepping -> | <- stepping |
+ *|---!!we're starting from upper left char corner|
+ *|-----------------------------------------------|
+ *
+ * @returns 0, if success, or else error code.
+ */
+int fill_char_horizontally(uchar *pfont, void **line, struct video_priv *vid_priv,
+ struct video_fontdata *fontdata, bool direction);
+
+/**
+ * console probe function.
+ *
+ * @param dev a pointer to device.
+ *
+ * @returns 0, if success, or else error code.
+ */
+int console_probe(struct udevice *dev);
+
+/**
+ * Internal function to be used in as ops.
+ * See details in video_console.h get_font_size function
+ **/
+const char *console_simple_get_font_size(struct udevice *dev, uint *sizep);
+
+/**
+ * Internal function to be used in as ops.
+ * See details in video_console.h get_font function
+ **/
+int console_simple_get_font(struct udevice *dev, int seq, struct vidfont_info *info);
+
+/**
+ * Internal function to be used in as ops.
+ * See details in video_console.h select_font function
+ **/
+int console_simple_select_font(struct udevice *dev, const char *name, uint size);