summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/sandbox/dts/test.dts7
-rw-r--r--drivers/video/sandbox_sdl.c9
-rw-r--r--include/dm/test.h8
-rw-r--r--test/dm/Makefile1
-rw-r--r--test/dm/video.c190
5 files changed, 206 insertions, 9 deletions
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 2e0d320..9b8d658 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -195,6 +195,13 @@
vss-microvolts = <0>;
};
+ lcd {
+ u-boot,dm-pre-reloc;
+ compatible = "sandbox,lcd-sdl";
+ xres = <1366>;
+ yres = <768>;
+ };
+
leds {
compatible = "gpio-leds";
diff --git a/drivers/video/sandbox_sdl.c b/drivers/video/sandbox_sdl.c
index 450628e..21448a1 100644
--- a/drivers/video/sandbox_sdl.c
+++ b/drivers/video/sandbox_sdl.c
@@ -20,15 +20,6 @@ enum {
LCD_MAX_HEIGHT = 768,
};
-
-/* This platform data is needed in tests, so declare it here */
-struct sandbox_sdl_plat {
- int xres;
- int yres;
- int bpix;
- int rot;
-};
-
static int sandbox_sdl_probe(struct udevice *dev)
{
struct sandbox_sdl_plat *plat = dev_get_platdata(dev);
diff --git a/include/dm/test.h b/include/dm/test.h
index a4bc5c8..ca924d9 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -155,6 +155,14 @@ enum {
/* Declare a new driver model test */
#define DM_TEST(_name, _flags) UNIT_TEST(_name, _flags, dm_test)
+/* This platform data is needed in tests, so declare it here */
+struct sandbox_sdl_plat {
+ int xres;
+ int yres;
+ int bpix;
+ int rot;
+};
+
/* Declare ping methods for the drivers */
int test_ping(struct udevice *dev, int pingval, int *pingret);
int testfdt_ping(struct udevice *dev, int pingval, int *pingret);
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 3ff1b75..d4f3f22 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -34,5 +34,6 @@ obj-$(CONFIG_DM_USB) += usb.o
obj-$(CONFIG_DM_PMIC) += pmic.o
obj-$(CONFIG_DM_REGULATOR) += regulator.o
obj-$(CONFIG_TIMER) += timer.o
+obj-$(CONFIG_DM_VIDEO) += video.o
obj-$(CONFIG_ADC) += adc.o
endif
diff --git a/test/dm/video.c b/test/dm/video.c
new file mode 100644
index 0000000..b197b01
--- /dev/null
+++ b/test/dm/video.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <bzlib.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <os.h>
+#include <video.h>
+#include <video_console.h>
+#include <dm/test.h>
+#include <dm/uclass-internal.h>
+#include <test/ut.h>
+
+/*
+ * These tests use the standard sandbox frame buffer, the resolution of which
+ * is defined in the device tree. This only supports 16bpp so the tests only
+ * test that code path. It would be possible to adjust this fairly easily,
+ * by adjusting the bpix value in struct sandbox_sdl_plat. However the code
+ * in sandbox_sdl_sync() would also need to change to handle the different
+ * surface depth.
+ */
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Basic test of the video uclass */
+static int dm_test_video_base(struct unit_test_state *uts)
+{
+ struct video_priv *priv;
+ struct udevice *dev;
+
+ ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
+ ut_asserteq(1366, video_get_xsize(dev));
+ ut_asserteq(768, video_get_ysize(dev));
+ priv = dev_get_uclass_priv(dev);
+ ut_asserteq(priv->fb_size, 1366 * 768 * 2);
+
+ return 0;
+}
+DM_TEST(dm_test_video_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/**
+ * compress_frame_buffer() - Compress the frame buffer and return its size
+ *
+ * We want to write tests which perform operations on the video console and
+ * check that the frame buffer ends up with the correct contents. But it is
+ * painful to store 'known good' images for comparison with the frame
+ * buffer. As an alternative, we can compress the frame buffer and check the
+ * size of the compressed data. This provides a pretty good level of
+ * certainty and the resulting tests need only check a single value.
+ *
+ * @dev: Video device
+ * @return compressed size of the frame buffer, or -ve on error
+ */
+static int compress_frame_buffer(struct udevice *dev)
+{
+ struct video_priv *priv = dev_get_uclass_priv(dev);
+ uint destlen;
+ void *dest;
+ int ret;
+
+ destlen = priv->fb_size;
+ dest = malloc(priv->fb_size);
+ if (!dest)
+ return -ENOMEM;
+ ret = BZ2_bzBuffToBuffCompress(dest, &destlen,
+ priv->fb, priv->fb_size,
+ 3, 0, 0);
+ free(dest);
+ if (ret)
+ return ret;
+
+ return destlen;
+}
+
+/*
+ * Call this function at any point to halt and show the current display. Be
+ * sure to run the test with the -l flag.
+ */
+static void __maybe_unused see_output(void)
+{
+ video_sync_all();
+ while (1);
+}
+
+/* Test text output works on the video console */
+static int dm_test_video_text(struct unit_test_state *uts)
+{
+ struct udevice *dev, *con;
+ int i;
+
+#define WHITE 0xffff
+#define SCROLL_LINES 100
+
+ ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
+ ut_asserteq(46, compress_frame_buffer(dev));
+
+ ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
+ vidconsole_putc_xy(con, 0, 0, 'a');
+ ut_asserteq(79, compress_frame_buffer(dev));
+
+ vidconsole_putc_xy(con, 0, 0, ' ');
+ ut_asserteq(46, compress_frame_buffer(dev));
+
+ for (i = 0; i < 20; i++)
+ vidconsole_putc_xy(con, i * 8, 0, ' ' + i);
+ ut_asserteq(273, compress_frame_buffer(dev));
+
+ vidconsole_set_row(con, 0, WHITE);
+ ut_asserteq(46, compress_frame_buffer(dev));
+
+ for (i = 0; i < 20; i++)
+ vidconsole_putc_xy(con, i * 8, 0, ' ' + i);
+ ut_asserteq(273, compress_frame_buffer(dev));
+
+ return 0;
+}
+DM_TEST(dm_test_video_text, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test handling of special characters in the console */
+static int dm_test_video_chars(struct unit_test_state *uts)
+{
+ struct udevice *dev, *con;
+ const char *test_string = "Well\b\b\b\bxhe is\r \n\ta very modest \bman\n\t\tand Has much to\b\bto be modest about.";
+ const char *s;
+
+ ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
+ ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
+ for (s = test_string; *s; s++)
+ vidconsole_put_char(con, *s);
+ ut_asserteq(466, compress_frame_buffer(dev));
+
+ return 0;
+}
+DM_TEST(dm_test_video_chars, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/**
+ * check_vidconsole_output() - Run a text console test
+ *
+ * @uts: Test state
+ * @rot: Console rotation (0, 90, 180, 270)
+ * @wrap_size: Expected size of compressed frame buffer for the wrap test
+ * @scroll_size: Same for the scroll test
+ * @return 0 on success
+ */
+static int check_vidconsole_output(struct unit_test_state *uts, int rot,
+ int wrap_size, int scroll_size)
+{
+ struct udevice *dev, *con;
+ struct sandbox_sdl_plat *plat;
+ int i;
+
+ ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
+ ut_assert(!device_active(dev));
+ plat = dev_get_platdata(dev);
+ plat->rot = rot;
+
+ ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
+ ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
+ ut_asserteq(46, compress_frame_buffer(dev));
+
+ /* Check display wrap */
+ for (i = 0; i < 120; i++)
+ vidconsole_put_char(con, 'A' + i % 50);
+ ut_asserteq(wrap_size, compress_frame_buffer(dev));
+
+ /* Check display scrolling */
+ for (i = 0; i < SCROLL_LINES; i++) {
+ vidconsole_put_char(con, 'A' + i % 50);
+ vidconsole_put_char(con, '\n');
+ }
+ ut_asserteq(scroll_size, compress_frame_buffer(dev));
+
+ /* If we scroll enough, the screen becomes blank again */
+ for (i = 0; i < SCROLL_LINES; i++)
+ vidconsole_put_char(con, '\n');
+ ut_asserteq(46, compress_frame_buffer(dev));
+
+ return 0;
+}
+
+/* Test text output through the console uclass */
+static int dm_test_video_context(struct unit_test_state *uts)
+{
+ return check_vidconsole_output(uts, 0, 788, 453);
+}
+DM_TEST(dm_test_video_context, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);