[U-Boot] [PATCH v2 3/5] video_osd: Add osd sandbox driver and tests
Mario Six
mario.six at gdsys.cc
Wed May 23 12:09:52 UTC 2018
Add sandbox driver and tests for the new OSD uclass.
Signed-off-by: Mario Six <mario.six at gdsys.cc>
---
v1 -> v2:
New in v2
---
arch/sandbox/dts/test.dts | 4 +
configs/sandbox64_defconfig | 3 +
configs/sandbox_defconfig | 3 +
configs/sandbox_flattree_defconfig | 3 +
configs/sandbox_noblk_defconfig | 3 +
configs/sandbox_spl_defconfig | 3 +
drivers/video/Kconfig | 6 ++
drivers/video/Makefile | 1 +
drivers/video/sandbox_osd.c | 157 ++++++++++++++++++++++++++++
drivers/video/sandbox_osd.h | 14 +++
drivers/video/video_osd-uclass.c | 9 ++
include/video_osd.h | 7 ++
test/dm/Makefile | 1 +
test/dm/osd.c | 208 +++++++++++++++++++++++++++++++++++++
14 files changed, 422 insertions(+)
create mode 100644 drivers/video/sandbox_osd.c
create mode 100644 drivers/video/sandbox_osd.h
create mode 100644 test/dm/osd.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 5a0f187d8b7..b6cdda0fd33 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -559,6 +559,10 @@
};
};
};
+
+ osd {
+ compatible = "sandbox,sandbox_osd";
+ };
};
#include "sandbox_pmic.dtsi"
diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig
index 20a2ab3ffb7..7464a3ca3af 100644
--- a/configs/sandbox64_defconfig
+++ b/configs/sandbox64_defconfig
@@ -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
@@ -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_WDT=y
CONFIG_WDT_SANDBOX=y
CONFIG_FS_CBFS=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 2fc84a16c91..f7925dfe6fb 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -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
diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig
index e922c4b38ff..126b9c07c54 100644
--- a/configs/sandbox_flattree_defconfig
+++ b/configs/sandbox_flattree_defconfig
@@ -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
diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig
index 8bdd4edcda6..243234b6c72 100644
--- a/configs/sandbox_noblk_defconfig
+++ b/configs/sandbox_noblk_defconfig
@@ -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
diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig
index fb6bb4baa2b..771d0f05a48 100644
--- a/configs/sandbox_spl_defconfig
+++ b/configs/sandbox_spl_defconfig
@@ -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
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4ca15174bb2..b1a8e05ad74 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -667,6 +667,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
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 44252b5989a..80a8b19ed5d 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -56,6 +56,7 @@ obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/
obj-${CONFIG_VIDEO_STM32} += stm32/
obj-${CONFIG_OSD} += video_osd-uclass.o
+obj-${CONFIG_SANDBOX_OSD} += sandbox_osd.o
obj-$(CONFIG_IHS_VIDEO_OUT) += ihs_video_out.o
obj-y += bridge/
diff --git a/drivers/video/sandbox_osd.c b/drivers/video/sandbox_osd.c
new file mode 100644
index 00000000000..4fdae1bbedd
--- /dev/null
+++ b/drivers/video/sandbox_osd.c
@@ -0,0 +1,157 @@
+#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,
+ .get_mem = sandbox_osd_get_mem,
+};
+
+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),
+};
diff --git a/drivers/video/sandbox_osd.h b/drivers/video/sandbox_osd.h
new file mode 100644
index 00000000000..644779913ec
--- /dev/null
+++ b/drivers/video/sandbox_osd.h
@@ -0,0 +1,14 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+enum {
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_RED,
+ COLOR_GREEN,
+ COLOR_BLUE,
+};
diff --git a/drivers/video/video_osd-uclass.c b/drivers/video/video_osd-uclass.c
index ae9b6a6fa82..05886f3bd5b 100644
--- a/drivers/video/video_osd-uclass.c
+++ b/drivers/video/video_osd-uclass.c
@@ -39,6 +39,15 @@ int video_osd_print(struct udevice *dev, uint col, uint row, ulong color,
return ops->print(dev, col, row, color, text);
}
+#ifdef CONFIG_SANDBOX
+int video_osd_get_mem(struct udevice *dev, u8 *buf, size_t buflen)
+{
+ struct video_osd_ops *ops = video_osd_get_ops(dev);
+
+ return ops->get_mem(dev, buf, buflen);
+}
+#endif
+
UCLASS_DRIVER(video_osd) = {
.id = UCLASS_VIDEO_OSD,
.name = "video_osd",
diff --git a/include/video_osd.h b/include/video_osd.h
index c3bcd3a4fd8..006cf916c94 100644
--- a/include/video_osd.h
+++ b/include/video_osd.h
@@ -113,6 +113,9 @@ struct video_osd_ops {
*/
int (*print)(struct udevice *dev, uint col, uint row, ulong color,
char *text);
+#ifdef CONFIG_SANDBOX
+ int (*get_mem)(struct udevice *dev, u8 *buf, size_t buflen);
+#endif
};
#define video_osd_get_ops(dev) ((struct video_osd_ops *)(dev)->driver->ops)
@@ -190,4 +193,8 @@ int video_osd_set_size(struct udevice *dev, uint col, uint row);
int video_osd_print(struct udevice *dev, uint col, uint row, ulong color,
char *text);
+#ifdef CONFIG_SANDBOX
+int video_osd_get_mem(struct udevice *dev, u8 *buf, size_t buflen);
+#endif
+
#endif /* !_VIDEO_OSD_H_ */
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 5511a85700c..7b390e1d2a0 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -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
diff --git a/test/dm/osd.c b/test/dm/osd.c
new file mode 100644
index 00000000000..807cb885077
--- /dev/null
+++ b/test/dm/osd.c
@@ -0,0 +1,208 @@
+/*
+ * (C) Copyright 2018
+ * Mario Six, Guntermann & Drunck GmbH, mario.six at gdsys.cc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <video_osd.h>
+#include <display_options.h>
+#include <test/ut.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(video_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(video_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(video_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(video_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);
--
2.11.0
More information about the U-Boot
mailing list