mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
- video console refactoring and optimization
- support for fonts wider than 1 byte - use named header for 8x16 font data - support multiple fonts configuration - move get_font_size() to truetype driver ops - support font size configuration at runtime - add 16x32 Terminus font from linux - add 12x22 Sun font from linux - add 12x22 console simple font test -----BEGIN PGP SIGNATURE----- iGwEABECACwWIQSC4hxrSoIUVfFO0kRM6ATMmsalXAUCZAdiLw4cYWd1c3RAZGVu eC5kZQAKCRBM6ATMmsalXDtGAJ9ZjsnfneJpUjwYJWOw2ibnm9Dh2QCfVCAy+Bxa YfqV8y7TbOuCQKTEY1s= =FJhw -----END PGP SIGNATURE----- Merge tag 'next-20230307' of https://source.denx.de/u-boot/custodians/u-boot-video into next - video console refactoring and optimization - support for fonts wider than 1 byte - use named header for 8x16 font data - support multiple fonts configuration - move get_font_size() to truetype driver ops - support font size configuration at runtime - add 16x32 Terminus font from linux - add 12x22 Sun font from linux - add 12x22 console simple font test
This commit is contained in:
commit
70ed05ce6c
23 changed files with 13507 additions and 5038 deletions
|
@ -2226,6 +2226,14 @@ config CMD_VIDCONSOLE
|
|||
The name 'lcdputs' is a bit of a misnomer, but so named because the
|
||||
video device is often an LCD.
|
||||
|
||||
config CMD_SELECT_FONT
|
||||
bool "select font size"
|
||||
depends on VIDEO
|
||||
default n
|
||||
help
|
||||
Enabling this will provide 'font' command.
|
||||
Allows font selection at runtime.
|
||||
|
||||
endmenu
|
||||
|
||||
source "cmd/ti/Kconfig"
|
||||
|
|
|
@ -78,7 +78,7 @@ obj-$(CONFIG_CMD_EXT2) += ext2.o
|
|||
obj-$(CONFIG_CMD_FAT) += fat.o
|
||||
obj-$(CONFIG_CMD_FDT) += fdt.o
|
||||
obj-$(CONFIG_CMD_SQUASHFS) += sqfs.o
|
||||
obj-$(CONFIG_CONSOLE_TRUETYPE) += font.o
|
||||
obj-$(CONFIG_CMD_SELECT_FONT) += font.o
|
||||
obj-$(CONFIG_CMD_FLASH) += flash.o
|
||||
obj-$(CONFIG_CMD_FPGA) += fpga.o
|
||||
obj-$(CONFIG_CMD_FPGAD) += fpgad.o
|
||||
|
|
|
@ -61,7 +61,11 @@ static int do_font_size(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||
|
||||
if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev))
|
||||
return CMD_RET_FAILURE;
|
||||
font_name = vidconsole_get_font_size(dev, &size);
|
||||
ret = vidconsole_get_font_size(dev, &font_name, &size);
|
||||
if (ret) {
|
||||
printf("Failed (error %d)\n", ret);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
size = dectoul(argv[1], NULL);
|
||||
|
||||
|
|
|
@ -127,9 +127,11 @@ void splash_get_pos(int *x, int *y)
|
|||
#include <dm.h>
|
||||
#include <video_console.h>
|
||||
#include <video_font.h>
|
||||
#include <video_font_data.h>
|
||||
|
||||
void splash_display_banner(void)
|
||||
{
|
||||
struct video_fontdata __maybe_unused *fontdata = fonts;
|
||||
struct udevice *dev;
|
||||
char buf[DISPLAY_OPTIONS_BANNER_LENGTH];
|
||||
int col, row, ret;
|
||||
|
@ -138,9 +140,9 @@ void splash_display_banner(void)
|
|||
if (ret)
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_VIDEO_LOGO
|
||||
col = BMP_LOGO_WIDTH / VIDEO_FONT_WIDTH + 1;
|
||||
row = BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT + 1;
|
||||
#if IS_ENABLED(CONFIG_VIDEO_LOGO)
|
||||
col = BMP_LOGO_WIDTH / fontdata->width + 1;
|
||||
row = BMP_LOGO_HEIGHT / fontdata->height + 1;
|
||||
#else
|
||||
col = 0;
|
||||
row = 0;
|
||||
|
|
|
@ -298,6 +298,7 @@ CONFIG_USB_GADGET_DOWNLOAD=y
|
|||
CONFIG_USB_ETHER=y
|
||||
CONFIG_USB_ETH_CDC=y
|
||||
CONFIG_VIDEO=y
|
||||
CONFIG_VIDEO_FONT_SUN12X22=y
|
||||
CONFIG_VIDEO_COPY=y
|
||||
CONFIG_CONSOLE_ROTATION=y
|
||||
CONFIG_CONSOLE_TRUETYPE=y
|
||||
|
|
|
@ -206,6 +206,7 @@ CONFIG_USB=y
|
|||
CONFIG_USB_EMUL=y
|
||||
CONFIG_USB_KEYBOARD=y
|
||||
CONFIG_VIDEO=y
|
||||
CONFIG_VIDEO_FONT_SUN12X22=y
|
||||
CONFIG_CONSOLE_ROTATION=y
|
||||
CONFIG_CONSOLE_TRUETYPE=y
|
||||
CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
212
drivers/video/console_core.c
Normal file
212
drivers/video/console_core.c
Normal file
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
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;
|
||||
ret = check_bpix_support(vid_priv->bpix);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < pixels; i++)
|
||||
*dst++ = clr;
|
||||
end = dst;
|
||||
break;
|
||||
}
|
||||
case VIDEO_BPP16:
|
||||
if (IS_ENABLED(CONFIG_VIDEO_BPP16)) {
|
||||
uint16_t *dst = line;
|
||||
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;
|
||||
|
||||
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];
|
||||
ret = fill_char_vertically(pfont, &line, vid_priv, fontdata, NORMAL_DIRECTION);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return VID_TO_POS(VIDEO_FONT_WIDTH);
|
||||
return VID_TO_POS(fontdata->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;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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),
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
ret = fill_char_horizontally(pfont, &line, vid_priv, fontdata, FLIPPED_DIRECTION);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
}
|
||||
/* 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];
|
||||
ret = fill_char_vertically(pfont, &line, vid_priv, fontdata, FLIPPED_DIRECTION);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
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;
|
||||
}
|
||||
/* 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),
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
120
drivers/video/vidconsole_internal.h
Normal file
120
drivers/video/vidconsole_internal.h
Normal file
|
@ -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);
|
|
@ -160,6 +160,15 @@ struct vidconsole_ops {
|
|||
int (*get_font)(struct udevice *dev, int seq,
|
||||
struct vidfont_info *info);
|
||||
|
||||
/**
|
||||
* get_font_size() - get the current font name and size
|
||||
*
|
||||
* @dev: vidconsole device
|
||||
* @sizep: Place to put the font size (nominal height in pixels)
|
||||
* Returns: Current font name
|
||||
*/
|
||||
const char *(*get_font_size)(struct udevice *dev, uint *sizep);
|
||||
|
||||
/**
|
||||
* select_font() - Select a particular font by name / size
|
||||
*
|
||||
|
@ -303,9 +312,10 @@ void vidconsole_list_fonts(struct udevice *dev);
|
|||
*
|
||||
* @dev: vidconsole device
|
||||
* @sizep: Place to put the font size (nominal height in pixels)
|
||||
* Returns: Current font name
|
||||
* @name: pointer to font name, a placeholder for result
|
||||
* Return: 0 if OK, -ENOSYS if not implemented in driver
|
||||
*/
|
||||
const char *vidconsole_get_font_size(struct udevice *dev, uint *sizep);
|
||||
int vidconsole_get_font_size(struct udevice *dev, const char **name, uint *sizep);
|
||||
|
||||
#ifdef CONFIG_VIDEO_COPY
|
||||
/**
|
||||
|
@ -340,6 +350,9 @@ int vidconsole_sync_copy(struct udevice *dev, void *from, void *to);
|
|||
int vidconsole_memmove(struct udevice *dev, void *dst, const void *src,
|
||||
int size);
|
||||
#else
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static inline int vidconsole_sync_copy(struct udevice *dev, void *from,
|
||||
void *to)
|
||||
{
|
||||
|
|
|
@ -7,10 +7,35 @@
|
|||
#ifndef _VIDEO_FONT_
|
||||
#define _VIDEO_FONT_
|
||||
|
||||
#ifdef CONFIG_VIDEO_FONT_4X6
|
||||
#include <video_font_4x6.h>
|
||||
#else
|
||||
#include <video_font_data.h>
|
||||
|
||||
#if defined(CONFIG_VIDEO_FONT_4X6)
|
||||
#include <video_font_4x6.h>
|
||||
#endif
|
||||
#if defined(CONFIG_VIDEO_FONT_8X16)
|
||||
#include <video_font_8x16.h>
|
||||
#endif
|
||||
#if defined(CONFIG_VIDEO_FONT_SUN12X22)
|
||||
#include <video_font_sun12x22.h>
|
||||
#endif
|
||||
#if defined(CONFIG_VIDEO_FONT_16X32)
|
||||
#include <video_font_ter16x32.h>
|
||||
#endif
|
||||
|
||||
static struct video_fontdata __maybe_unused fonts[] = {
|
||||
#if defined(CONFIG_VIDEO_FONT_8X16)
|
||||
FONT_ENTRY(8, 16, 8x16),
|
||||
#endif
|
||||
#if defined(CONFIG_VIDEO_FONT_4X6)
|
||||
FONT_ENTRY(4, 6, 4x6),
|
||||
#endif
|
||||
#if defined(CONFIG_VIDEO_FONT_SUN12X22)
|
||||
FONT_ENTRY(12, 22, 12x22),
|
||||
#endif
|
||||
#if defined(CONFIG_VIDEO_FONT_16X32)
|
||||
FONT_ENTRY(16, 32, 16x32),
|
||||
#endif
|
||||
{/* list terminator */}
|
||||
};
|
||||
|
||||
#endif /* _VIDEO_FONT_ */
|
||||
|
|
|
@ -38,15 +38,12 @@ __END__;
|
|||
MSBit to LSBit = left to right.
|
||||
*/
|
||||
|
||||
#ifndef _VIDEO_FONT_DATA_
|
||||
#define _VIDEO_FONT_DATA_
|
||||
#ifndef _VIDEO_FONT_4X6_
|
||||
#define _VIDEO_FONT_4X6_
|
||||
|
||||
#define VIDEO_FONT_CHARS 256
|
||||
#define VIDEO_FONT_WIDTH 4
|
||||
#define VIDEO_FONT_HEIGHT 6
|
||||
#define VIDEO_FONT_SIZE (VIDEO_FONT_CHARS * VIDEO_FONT_HEIGHT)
|
||||
#include <video_font_data.h>
|
||||
|
||||
static unsigned char video_fontdata[VIDEO_FONT_SIZE] = {
|
||||
static unsigned char video_fontdata_4x6[VIDEO_FONT_SIZE(256, 4, 6)] = {
|
||||
|
||||
/*{*/
|
||||
/* Char 0: ' ' */
|
||||
|
|
4624
include/video_font_8x16.h
Normal file
4624
include/video_font_8x16.h
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
6158
include/video_font_sun12x22.h
Normal file
6158
include/video_font_sun12x22.h
Normal file
File diff suppressed because it is too large
Load diff
2062
include/video_font_ter16x32.h
Normal file
2062
include/video_font_ter16x32.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -19,6 +19,7 @@
|
|||
static int font_test_base(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev;
|
||||
const char *name;
|
||||
int max_metrics;
|
||||
uint size;
|
||||
int ret;
|
||||
|
@ -32,8 +33,8 @@ static int font_test_base(struct unit_test_state *uts)
|
|||
ut_assert_nextline("cantoraone_regular");
|
||||
ut_assertok(ut_check_console_end(uts));
|
||||
|
||||
ut_asserteq_str("nimbus_sans_l_regular",
|
||||
vidconsole_get_font_size(dev, &size));
|
||||
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
|
||||
ut_asserteq_str("nimbus_sans_l_regular", name);
|
||||
ut_asserteq(18, size);
|
||||
|
||||
max_metrics = 1;
|
||||
|
@ -52,15 +53,15 @@ static int font_test_base(struct unit_test_state *uts)
|
|||
ut_assertok(ret);
|
||||
ut_assertok(ut_check_console_end(uts));
|
||||
|
||||
ut_asserteq_str("cantoraone_regular",
|
||||
vidconsole_get_font_size(dev, &size));
|
||||
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
|
||||
ut_asserteq_str("cantoraone_regular", name);
|
||||
ut_asserteq(40, size);
|
||||
|
||||
ut_assertok(run_command("font size 30", 0));
|
||||
ut_assertok(ut_check_console_end(uts));
|
||||
|
||||
ut_asserteq_str("cantoraone_regular",
|
||||
vidconsole_get_font_size(dev, &size));
|
||||
ut_assertok(vidconsole_get_font_size(dev, &name, &size));
|
||||
ut_asserteq_str("cantoraone_regular", name);
|
||||
ut_asserteq(30, size);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -151,6 +151,8 @@ static int dm_test_video_text(struct unit_test_state *uts)
|
|||
|
||||
ut_assertok(select_vidconsole(uts, "vidconsole0"));
|
||||
ut_assertok(video_get_nologo(uts, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
ut_assertok(vidconsole_select_font(con, "8x16", 0));
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
|
@ -175,6 +177,42 @@ static int dm_test_video_text(struct unit_test_state *uts)
|
|||
}
|
||||
DM_TEST(dm_test_video_text, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_video_text_12x22(struct unit_test_state *uts)
|
||||
{
|
||||
struct udevice *dev, *con;
|
||||
int i;
|
||||
|
||||
#define WHITE 0xffff
|
||||
#define SCROLL_LINES 100
|
||||
|
||||
ut_assertok(select_vidconsole(uts, "vidconsole0"));
|
||||
ut_assertok(video_get_nologo(uts, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
ut_assertok(vidconsole_select_font(con, "12x22", 0));
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
vidconsole_putc_xy(con, 0, 0, 'a');
|
||||
ut_asserteq(89, compress_frame_buffer(uts, dev));
|
||||
|
||||
vidconsole_putc_xy(con, 0, 0, ' ');
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
||||
ut_asserteq(363, compress_frame_buffer(uts, dev));
|
||||
|
||||
vidconsole_set_row(con, 0, WHITE);
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
for (i = 0; i < 20; i++)
|
||||
vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
|
||||
ut_asserteq(363, compress_frame_buffer(uts, dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_video_text_12x22, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
|
||||
|
||||
/* Test handling of special characters in the console */
|
||||
static int dm_test_video_chars(struct unit_test_state *uts)
|
||||
{
|
||||
|
@ -184,6 +222,7 @@ static int dm_test_video_chars(struct unit_test_state *uts)
|
|||
ut_assertok(select_vidconsole(uts, "vidconsole0"));
|
||||
ut_assertok(video_get_nologo(uts, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
ut_assertok(vidconsole_select_font(con, "8x16", 0));
|
||||
vidconsole_put_string(con, test_string);
|
||||
ut_asserteq(466, compress_frame_buffer(uts, dev));
|
||||
|
||||
|
@ -201,6 +240,7 @@ static int dm_test_video_ansi(struct unit_test_state *uts)
|
|||
ut_assertok(select_vidconsole(uts, "vidconsole0"));
|
||||
ut_assertok(video_get_nologo(uts, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
ut_assertok(vidconsole_select_font(con, "8x16", 0));
|
||||
|
||||
/* reference clear: */
|
||||
video_clear(con->parent);
|
||||
|
@ -249,6 +289,7 @@ static int check_vidconsole_output(struct unit_test_state *uts, int rot,
|
|||
|
||||
ut_assertok(video_get_nologo(uts, &dev));
|
||||
ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
|
||||
ut_assertok(vidconsole_select_font(con, "8x16", 0));
|
||||
ut_asserteq(46, compress_frame_buffer(uts, dev));
|
||||
|
||||
/* Check display wrap */
|
||||
|
|
Loading…
Reference in a new issue