video_osd: Add osd sandbox driver and tests
authorMario Six <mario.six@gdsys.cc>
Thu, 27 Sep 2018 07:19:31 +0000 (09:19 +0200)
committerAnatolij Gustschin <agust@denx.de>
Fri, 28 Sep 2018 16:26:52 +0000 (18:26 +0200)
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>
13 files changed:
arch/sandbox/dts/test.dts
arch/sandbox/include/asm/test.h
configs/sandbox64_defconfig
configs/sandbox_defconfig
configs/sandbox_flattree_defconfig
configs/sandbox_noblk_defconfig
configs/sandbox_spl_defconfig
drivers/video/Kconfig
drivers/video/Makefile
drivers/video/sandbox_osd.c [new file with mode: 0644]
drivers/video/sandbox_osd.h [new file with mode: 0644]
test/dm/Makefile
test/dm/osd.c [new file with mode: 0644]

index b8524e3b7d69284ec15cf8d43bb1a590388f2277..cfa47bcd0dec792101179b43c6924ca00c694de9 100644 (file)
@@ -37,6 +37,7 @@
                usb1 = &usb_1;
                usb2 = &usb_2;
                axi0 = &axi;
+               osd0 = "/osd";
        };
 
        a-test {
                        };
                };
        };
+
+       osd {
+               compatible = "sandbox,sandbox_osd";
+       };
 };
 
 #include "sandbox_pmic.dtsi"
index c8ae52b248db9454e1f102f697cd7ca2ac76acef..89f3d90c734f05fc73adc7032408756b064086e1 100644 (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
index 27797c6990bbc7e54f8c3c13beadc02e0f1f05b2..fb511d411a4ac6d7d0f5a62667de419b7ed4851a 100644 (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
index 0b209686bf9ed8c5572782970e6fb55c1b464680..af8375e22e579882d3d839200c69170cf48f28e4 100644 (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
index 618d6462a8c1d7f0ae737a8dce883f2c7cd7293a..3dcfdcc5391b2387f40c00b58aabb897a1fc5c93 100644 (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
index a7691daa008f35521b1bac698db448c5d3bc5b97..34c461422985da88271658aafe2dfda27d8e6a25 100644 (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
index dad5e1ce770cb20ba97bee62d04970ea4d8203a7..746f59fae8566ef4241f303543864aa35c53bb78 100644 (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
index 1e2cbe7afcfdda4f2435b3c775ee2e215bb5be0e..c68066692d7783332b941d3c0f11c4b1681e4d8f 100644 (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
index 290747ba94f810aa153311a9a9bf62396f174865..b31017e436d4cbaeb769c6deb74be7c99f3b0ca3 100644 (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
diff --git a/drivers/video/sandbox_osd.c b/drivers/video/sandbox_osd.c
new file mode 100644 (file)
index 0000000..dd84489
--- /dev/null
@@ -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),
+};
diff --git a/drivers/video/sandbox_osd.h b/drivers/video/sandbox_osd.h
new file mode 100644 (file)
index 0000000..15a2c91
--- /dev/null
@@ -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,
+};
index 8b1ba915d017e6cf928d3cab8336945ff0bcc66a..16033271f8de525a4a531f17a338e5196a95385c 100644 (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
diff --git a/test/dm/osd.c b/test/dm/osd.c
new file mode 100644 (file)
index 0000000..6910690
--- /dev/null
@@ -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);