video_osd: Add osd sandbox driver and tests

Add sandbox driver and tests for the new OSD uclass.

Signed-off-by: Mario Six <mario.six@gdsys.cc>
Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Mario Six 2018-09-27 09:19:31 +02:00 committed by Anatolij Gustschin
parent 9671f696e5
commit 4eea531859
13 changed files with 420 additions and 0 deletions

View file

@ -37,6 +37,7 @@
usb1 = &usb_1;
usb2 = &usb_2;
axi0 = &axi;
osd0 = "/osd";
};
a-test {
@ -642,6 +643,10 @@
};
};
};
osd {
compatible = "sandbox,sandbox_osd";
};
};
#include "sandbox_pmic.dtsi"

View file

@ -90,4 +90,12 @@ long sandbox_i2c_rtc_get_set_base_time(struct udevice *dev, long base_time);
int sandbox_usb_keyb_add_string(struct udevice *dev, const char *str);
/**
* sandbox_osd_get_mem() - get the internal memory of a sandbox OSD
*
* @dev: OSD device for which to access the internal memory for
* @buf: pointer to buffer to receive the OSD memory data
* @buflen: length of buffer in bytes
*/
int sandbox_osd_get_mem(struct udevice *dev, u8 *buf, size_t buflen);
#endif

View file

@ -39,6 +39,7 @@ CONFIG_CMD_GPT=y
CONFIG_CMD_GPT_RENAME=y
CONFIG_CMD_IDE=y
CONFIG_CMD_I2C=y
CONFIG_CMD_OSD=y
CONFIG_CMD_PCI=y
CONFIG_CMD_READ=y
CONFIG_CMD_REMOTEPROC=y
@ -186,6 +187,8 @@ CONFIG_CONSOLE_ROTATION=y
CONFIG_CONSOLE_TRUETYPE=y
CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
CONFIG_VIDEO_SANDBOX_SDL=y
CONFIG_OSD=y
CONFIG_SANDBOX_OSD=y
CONFIG_WDT=y
CONFIG_WDT_SANDBOX=y
CONFIG_FS_CBFS=y

View file

@ -41,6 +41,7 @@ CONFIG_CMD_GPT=y
CONFIG_CMD_GPT_RENAME=y
CONFIG_CMD_IDE=y
CONFIG_CMD_I2C=y
CONFIG_CMD_OSD=y
CONFIG_CMD_PCI=y
CONFIG_CMD_READ=y
CONFIG_CMD_REMOTEPROC=y
@ -192,6 +193,8 @@ CONFIG_CONSOLE_ROTATION=y
CONFIG_CONSOLE_TRUETYPE=y
CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
CONFIG_VIDEO_SANDBOX_SDL=y
CONFIG_OSD=y
CONFIG_SANDBOX_OSD=y
CONFIG_WDT=y
CONFIG_WDT_SANDBOX=y
CONFIG_FS_CBFS=y

View file

@ -31,6 +31,7 @@ CONFIG_CMD_DEMO=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
CONFIG_CMD_OSD=y
CONFIG_CMD_PCI=y
CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_SF=y
@ -167,6 +168,8 @@ CONFIG_CONSOLE_ROTATION=y
CONFIG_CONSOLE_TRUETYPE=y
CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
CONFIG_VIDEO_SANDBOX_SDL=y
CONFIG_OSD=y
CONFIG_SANDBOX_OSD=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_TPM=y
CONFIG_LZ4=y

View file

@ -35,6 +35,7 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_IDE=y
CONFIG_CMD_I2C=y
CONFIG_CMD_OSD=y
CONFIG_CMD_PCI=y
CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_SF=y
@ -166,6 +167,8 @@ CONFIG_CONSOLE_ROTATION=y
CONFIG_CONSOLE_TRUETYPE=y
CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
CONFIG_VIDEO_SANDBOX_SDL=y
CONFIG_OSD=y
CONFIG_SANDBOX_OSD=y
CONFIG_FS_CBFS=y
CONFIG_FS_CRAMFS=y
CONFIG_CMD_DHRYSTONE=y

View file

@ -43,6 +43,7 @@ CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_IDE=y
CONFIG_CMD_I2C=y
CONFIG_CMD_OSD=y
CONFIG_CMD_PCI=y
CONFIG_CMD_REMOTEPROC=y
CONFIG_CMD_SF=y
@ -185,6 +186,8 @@ CONFIG_CONSOLE_ROTATION=y
CONFIG_CONSOLE_TRUETYPE=y
CONFIG_CONSOLE_TRUETYPE_CANTORAONE=y
CONFIG_VIDEO_SANDBOX_SDL=y
CONFIG_OSD=y
CONFIG_SANDBOX_OSD=y
CONFIG_FS_CBFS=y
CONFIG_FS_CRAMFS=y
CONFIG_CMD_DHRYSTONE=y

View file

@ -692,6 +692,12 @@ config OSD
is a (usually text-oriented) graphics buffer to show information on
a display.
config SANDBOX_OSD
bool "Enable sandbox OSD"
depends on OSD
help
Enable support for sandbox OSD device used for testing purposes.
config IHS_VIDEO_OUT
bool "Enable IHS video out driver"
depends on OSD

View file

@ -34,6 +34,7 @@ obj-$(CONFIG_LG4573) += lg4573.o
obj-$(CONFIG_LOGICORE_DP_TX) += logicore_dp_tx.o
obj-$(CONFIG_OSD) += video_osd-uclass.o
obj-$(CONFIG_PXA_LCD) += pxa_lcd.o
obj-$(CONFIG_SANDBOX_OSD) += sandbox_osd.o
obj-$(CONFIG_S6E8AX0) += s6e8ax0.o
obj-$(CONFIG_SCF0403_LCD) += scf0403_lcd.o
obj-$(CONFIG_VIDEO_BCM2835) += bcm2835.o

161
drivers/video/sandbox_osd.c Normal file
View file

@ -0,0 +1,161 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2018
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
*/
#include <common.h>
#include <display.h>
#include <dm.h>
#include <video_osd.h>
#include "sandbox_osd.h"
struct sandbox_osd_priv {
uint width;
uint height;
u16 *buf;
};
static const struct udevice_id sandbox_osd_ids[] = {
{ .compatible = "sandbox,sandbox_osd" },
{ }
};
inline u16 make_memval(u8 chr, u8 color)
{
return chr * 0x100 + color;
}
int sandbox_osd_get_info(struct udevice *dev, struct video_osd_info *info)
{
struct sandbox_osd_priv *priv = dev_get_priv(dev);
info->width = priv->width;
info->height = priv->height;
info->major_version = 1;
info->minor_version = 0;
return 0;
}
int sandbox_osd_set_mem(struct udevice *dev, uint col, uint row, u8 *buf,
size_t buflen, uint count)
{
struct sandbox_osd_priv *priv = dev_get_priv(dev);
int pos;
u8 *mem = (u8 *)priv->buf;
int i;
pos = 2 * (row * priv->width + col);
if (pos >= 2 * (priv->width * priv->height))
return -EINVAL;
for (i = 0; i < count; i++)
memcpy(mem + pos + (i * buflen), buf, buflen);
return 0;
}
int _sandbox_osd_set_size(struct udevice *dev, uint col, uint row)
{
struct sandbox_osd_priv *priv = dev_get_priv(dev);
int i;
uint size;
priv->width = col;
priv->height = row;
size = priv->width * priv->height;
if (!priv->buf)
priv->buf = calloc(size, sizeof(u16));
else
priv->buf = realloc(priv->buf, size * sizeof(u16));
if (!priv->buf)
return -ENOMEM;
/* Fill OSD with black spaces */
for (i = 0; i < size; i++)
priv->buf[i] = make_memval(' ', 'k');
return 0;
}
int sandbox_osd_set_size(struct udevice *dev, uint col, uint row)
{
return _sandbox_osd_set_size(dev, col, row);
}
int sandbox_osd_print(struct udevice *dev, uint col, uint row, ulong color,
char *text)
{
struct sandbox_osd_priv *priv = dev_get_priv(dev);
char cval;
char *p;
int pos;
if (col >= priv->width || row >= priv->height)
return -EINVAL;
switch (color) {
case COLOR_BLACK:
cval = 'k';
break;
case COLOR_WHITE:
cval = 'w';
break;
case COLOR_RED:
cval = 'r';
break;
case COLOR_GREEN:
cval = 'g';
break;
case COLOR_BLUE:
cval = 'b';
break;
default:
return -EINVAL;
}
p = text;
pos = row * priv->width + col;
while (*p)
priv->buf[pos++] = make_memval(*(p++), cval);
return 0;
}
int sandbox_osd_get_mem(struct udevice *dev, u8 *buf, size_t buflen)
{
struct sandbox_osd_priv *priv = dev_get_priv(dev);
uint memsize = 2 * (priv->width * priv->height);
if (buflen < memsize)
return -EINVAL;
memcpy(buf, priv->buf, memsize);
return 0;
}
static const struct video_osd_ops sandbox_osd_ops = {
.get_info = sandbox_osd_get_info,
.set_mem = sandbox_osd_set_mem,
.set_size = sandbox_osd_set_size,
.print = sandbox_osd_print,
};
int sandbox_osd_probe(struct udevice *dev)
{
return _sandbox_osd_set_size(dev, 10, 10);
}
U_BOOT_DRIVER(sandbox_osd_drv) = {
.name = "sandbox_osd_drv",
.id = UCLASS_VIDEO_OSD,
.ops = &sandbox_osd_ops,
.of_match = sandbox_osd_ids,
.probe = sandbox_osd_probe,
.priv_auto_alloc_size = sizeof(struct sandbox_osd_priv),
};

View file

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2018
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
*/
enum {
COLOR_BLACK,
COLOR_WHITE,
COLOR_RED,
COLOR_GREEN,
COLOR_BLUE,
};

View file

@ -22,6 +22,7 @@ obj-$(CONFIG_LED) += led.o
obj-$(CONFIG_DM_MAILBOX) += mailbox.o
obj-$(CONFIG_DM_MMC) += mmc.o
obj-y += ofnode.o
obj-$(CONFIG_OSD) += osd.o
obj-$(CONFIG_DM_PCI) += pci.o
obj-$(CONFIG_PHY) += phy.o
obj-$(CONFIG_POWER_DOMAIN) += power-domain.o

210
test/dm/osd.c Normal file
View file

@ -0,0 +1,210 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2018
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
*/
#include <common.h>
#include <display_options.h>
#include <dm.h>
#include <dm/test.h>
#include <test/ut.h>
#include <video_osd.h>
#include <asm/test.h>
#include "../../drivers/video/sandbox_osd.h"
const uint memsize = 2 * 10 * 10;
static void split(u8 *mem, uint size, u8 *text, u8 *colors)
{
int i;
u16 *p = (u16 *)mem;
for (i = 0; i < size; i++) {
colors[i] = p[i] % 0x100;
text[i] = p[i] / 0x100;
}
}
static void print_mem(u8 *mem, uint width, uint height)
{
const uint memsize = 2 * 10 * 10;
u8 colors[memsize / 2];
u8 text[memsize / 2];
int i;
split(mem, memsize / 2, text, colors);
for (i = 0; i < width * height; i++) {
printf("%c", text[i]);
if (i > 0 && ((i + 1) % width) == 0)
printf("\n");
}
printf("\n");
for (i = 0; i < width * height; i++) {
printf("%c", colors[i]);
if (i > 0 && ((i + 1) % width) == 0)
printf("\n");
}
}
static int dm_test_osd_basics(struct unit_test_state *uts)
{
struct udevice *dev;
u8 mem[memsize + 1];
u8 colors[memsize / 2];
u8 text[memsize / 2];
struct video_osd_info info;
ut_assertok(uclass_first_device_err(UCLASS_VIDEO_OSD, &dev));
video_osd_get_info(dev, &info);
ut_asserteq(10, info.width);
ut_asserteq(10, info.height);
ut_asserteq(1, info.major_version);
ut_asserteq(0, info.minor_version);
ut_assertok(sandbox_osd_get_mem(dev, mem, memsize));
split(mem, memsize / 2, text, colors);
ut_assertok(memcmp(text, " "
" "
" "
" "
" "
" "
" "
" "
" "
" ", memsize / 2));
ut_assertok(memcmp(colors, "kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk", memsize / 2));
print_mem(mem, 10, 10);
ut_assertok(video_osd_print(dev, 1, 1, COLOR_RED, "Blah"));
ut_assertok(sandbox_osd_get_mem(dev, mem, memsize));
split(mem, memsize / 2, text, colors);
ut_assertok(memcmp(text, " "
" Blah "
" "
" "
" "
" "
" "
" "
" "
" ", memsize / 2));
ut_assertok(memcmp(colors, "kkkkkkkkkk"
"krrrrkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk"
"kkkkkkkkkk", memsize / 2));
print_mem(mem, 10, 10);
return 0;
}
DM_TEST(dm_test_osd_basics, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
static int dm_test_osd_extended(struct unit_test_state *uts)
{
struct udevice *dev;
u8 mem[memsize + 1];
u8 colors[memsize / 2];
u8 text[memsize / 2];
struct video_osd_info info;
u16 val;
ut_assertok(uclass_first_device_err(UCLASS_VIDEO_OSD, &dev));
ut_assertok(video_osd_set_size(dev, 20, 5));
video_osd_get_info(dev, &info);
ut_asserteq(20, info.width);
ut_asserteq(5, info.height);
ut_asserteq(1, info.major_version);
ut_asserteq(0, info.minor_version);
ut_assertok(sandbox_osd_get_mem(dev, mem, memsize));
split(mem, memsize / 2, text, colors);
ut_assertok(memcmp(text, " "
" "
" "
" "
" ", memsize / 2));
ut_assertok(memcmp(colors, "kkkkkkkkkkkkkkkkkkkk"
"kkkkkkkkkkkkkkkkkkkk"
"kkkkkkkkkkkkkkkkkkkk"
"kkkkkkkkkkkkkkkkkkkk"
"kkkkkkkkkkkkkkkkkkkk", memsize / 2));
print_mem(mem, 20, 5);
/* Draw green border */
val = '-' * 0x100 + 'g';
ut_assertok(video_osd_set_mem(dev, 1, 0, (u8 *)&val, 2, 18));
ut_assertok(video_osd_set_mem(dev, 1, 4, (u8 *)&val, 2, 18));
ut_assertok(video_osd_print(dev, 0, 1, COLOR_GREEN, "|"));
ut_assertok(video_osd_print(dev, 0, 2, COLOR_GREEN, "|"));
ut_assertok(video_osd_print(dev, 0, 3, COLOR_GREEN, "|"));
ut_assertok(video_osd_print(dev, 19, 1, COLOR_GREEN, "|"));
ut_assertok(video_osd_print(dev, 19, 2, COLOR_GREEN, "|"));
ut_assertok(video_osd_print(dev, 19, 3, COLOR_GREEN, "|"));
ut_assertok(video_osd_print(dev, 0, 0, COLOR_GREEN, "+"));
ut_assertok(video_osd_print(dev, 19, 0, COLOR_GREEN, "+"));
ut_assertok(video_osd_print(dev, 19, 4, COLOR_GREEN, "+"));
ut_assertok(video_osd_print(dev, 0, 4, COLOR_GREEN, "+"));
/* Add menu caption and entries */
ut_assertok(video_osd_print(dev, 5, 0, COLOR_GREEN, " OSD menu "));
ut_assertok(video_osd_print(dev, 2, 1, COLOR_BLUE, " * Entry 1"));
ut_assertok(video_osd_print(dev, 2, 2, COLOR_BLUE, "(*) Entry 2"));
ut_assertok(video_osd_print(dev, 2, 3, COLOR_BLUE, " * Entry 3"));
ut_assertok(sandbox_osd_get_mem(dev, mem, memsize));
split(mem, memsize / 2, text, colors);
print_mem(mem, 20, 5);
ut_assertok(memcmp(text, "+---- OSD menu ----+"
"| * Entry 1 |"
"| (*) Entry 2 |"
"| * Entry 3 |"
"+------------------+", memsize / 2));
ut_assertok(memcmp(colors, "gggggggggggggggggggg"
"gkbbbbbbbbbbbkkkkkkg"
"gkbbbbbbbbbbbkkkkkkg"
"gkbbbbbbbbbbbkkkkkkg"
"gggggggggggggggggggg", memsize / 2));
return 0;
}
DM_TEST(dm_test_osd_extended, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);