183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
23c97c4fbSSimon Glass /*
33c97c4fbSSimon Glass * Copyright (c) 2014 Google, Inc
43c97c4fbSSimon Glass * Written by Simon Glass <sjg@chromium.org>
53c97c4fbSSimon Glass */
63c97c4fbSSimon Glass
73c97c4fbSSimon Glass #include <common.h>
83c97c4fbSSimon Glass #include <bzlib.h>
93c97c4fbSSimon Glass #include <dm.h>
103c97c4fbSSimon Glass #include <mapmem.h>
113c97c4fbSSimon Glass #include <os.h>
123c97c4fbSSimon Glass #include <video.h>
133c97c4fbSSimon Glass #include <video_console.h>
143c97c4fbSSimon Glass #include <dm/test.h>
153c97c4fbSSimon Glass #include <dm/uclass-internal.h>
163c97c4fbSSimon Glass #include <test/ut.h>
173c97c4fbSSimon Glass
183c97c4fbSSimon Glass /*
193c97c4fbSSimon Glass * These tests use the standard sandbox frame buffer, the resolution of which
203c97c4fbSSimon Glass * is defined in the device tree. This only supports 16bpp so the tests only
213c97c4fbSSimon Glass * test that code path. It would be possible to adjust this fairly easily,
223c97c4fbSSimon Glass * by adjusting the bpix value in struct sandbox_sdl_plat. However the code
233c97c4fbSSimon Glass * in sandbox_sdl_sync() would also need to change to handle the different
243c97c4fbSSimon Glass * surface depth.
253c97c4fbSSimon Glass */
263c97c4fbSSimon Glass /* Basic test of the video uclass */
dm_test_video_base(struct unit_test_state * uts)273c97c4fbSSimon Glass static int dm_test_video_base(struct unit_test_state *uts)
283c97c4fbSSimon Glass {
293c97c4fbSSimon Glass struct video_priv *priv;
303c97c4fbSSimon Glass struct udevice *dev;
313c97c4fbSSimon Glass
323c97c4fbSSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
333c97c4fbSSimon Glass ut_asserteq(1366, video_get_xsize(dev));
343c97c4fbSSimon Glass ut_asserteq(768, video_get_ysize(dev));
353c97c4fbSSimon Glass priv = dev_get_uclass_priv(dev);
363c97c4fbSSimon Glass ut_asserteq(priv->fb_size, 1366 * 768 * 2);
373c97c4fbSSimon Glass
383c97c4fbSSimon Glass return 0;
393c97c4fbSSimon Glass }
403c97c4fbSSimon Glass DM_TEST(dm_test_video_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
413c97c4fbSSimon Glass
423c97c4fbSSimon Glass /**
433c97c4fbSSimon Glass * compress_frame_buffer() - Compress the frame buffer and return its size
443c97c4fbSSimon Glass *
453c97c4fbSSimon Glass * We want to write tests which perform operations on the video console and
463c97c4fbSSimon Glass * check that the frame buffer ends up with the correct contents. But it is
473c97c4fbSSimon Glass * painful to store 'known good' images for comparison with the frame
483c97c4fbSSimon Glass * buffer. As an alternative, we can compress the frame buffer and check the
493c97c4fbSSimon Glass * size of the compressed data. This provides a pretty good level of
503c97c4fbSSimon Glass * certainty and the resulting tests need only check a single value.
513c97c4fbSSimon Glass *
523c97c4fbSSimon Glass * @dev: Video device
533c97c4fbSSimon Glass * @return compressed size of the frame buffer, or -ve on error
543c97c4fbSSimon Glass */
compress_frame_buffer(struct udevice * dev)553c97c4fbSSimon Glass static int compress_frame_buffer(struct udevice *dev)
563c97c4fbSSimon Glass {
573c97c4fbSSimon Glass struct video_priv *priv = dev_get_uclass_priv(dev);
583c97c4fbSSimon Glass uint destlen;
593c97c4fbSSimon Glass void *dest;
603c97c4fbSSimon Glass int ret;
613c97c4fbSSimon Glass
623c97c4fbSSimon Glass destlen = priv->fb_size;
633c97c4fbSSimon Glass dest = malloc(priv->fb_size);
643c97c4fbSSimon Glass if (!dest)
653c97c4fbSSimon Glass return -ENOMEM;
663c97c4fbSSimon Glass ret = BZ2_bzBuffToBuffCompress(dest, &destlen,
673c97c4fbSSimon Glass priv->fb, priv->fb_size,
683c97c4fbSSimon Glass 3, 0, 0);
693c97c4fbSSimon Glass free(dest);
703c97c4fbSSimon Glass if (ret)
713c97c4fbSSimon Glass return ret;
723c97c4fbSSimon Glass
733c97c4fbSSimon Glass return destlen;
743c97c4fbSSimon Glass }
753c97c4fbSSimon Glass
763c97c4fbSSimon Glass /*
773c97c4fbSSimon Glass * Call this function at any point to halt and show the current display. Be
783c97c4fbSSimon Glass * sure to run the test with the -l flag.
793c97c4fbSSimon Glass */
see_output(void)803c97c4fbSSimon Glass static void __maybe_unused see_output(void)
813c97c4fbSSimon Glass {
823c97c4fbSSimon Glass video_sync_all();
833c97c4fbSSimon Glass while (1);
843c97c4fbSSimon Glass }
853c97c4fbSSimon Glass
868df8dad5SSimon Glass /* Select the video console driver to use for a video device */
select_vidconsole(struct unit_test_state * uts,const char * drv_name)878df8dad5SSimon Glass static int select_vidconsole(struct unit_test_state *uts, const char *drv_name)
888df8dad5SSimon Glass {
898df8dad5SSimon Glass struct sandbox_sdl_plat *plat;
908df8dad5SSimon Glass struct udevice *dev;
918df8dad5SSimon Glass
928df8dad5SSimon Glass ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
938df8dad5SSimon Glass ut_assert(!device_active(dev));
948df8dad5SSimon Glass plat = dev_get_platdata(dev);
958df8dad5SSimon Glass plat->vidconsole_drv_name = "vidconsole0";
968df8dad5SSimon Glass
978df8dad5SSimon Glass return 0;
988df8dad5SSimon Glass }
998df8dad5SSimon Glass
vidconsole_put_string(struct udevice * dev,const char * str)100a7495ac8SRob Clark static void vidconsole_put_string(struct udevice *dev, const char *str)
101a7495ac8SRob Clark {
102a7495ac8SRob Clark const char *s;
103a7495ac8SRob Clark
104a7495ac8SRob Clark for (s = str; *s; s++)
105a7495ac8SRob Clark vidconsole_put_char(dev, *s);
106a7495ac8SRob Clark }
107a7495ac8SRob Clark
1083c97c4fbSSimon Glass /* Test text output works on the video console */
dm_test_video_text(struct unit_test_state * uts)1093c97c4fbSSimon Glass static int dm_test_video_text(struct unit_test_state *uts)
1103c97c4fbSSimon Glass {
1113c97c4fbSSimon Glass struct udevice *dev, *con;
1123c97c4fbSSimon Glass int i;
1133c97c4fbSSimon Glass
1143c97c4fbSSimon Glass #define WHITE 0xffff
1153c97c4fbSSimon Glass #define SCROLL_LINES 100
1163c97c4fbSSimon Glass
1178df8dad5SSimon Glass ut_assertok(select_vidconsole(uts, "vidconsole0"));
1183c97c4fbSSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
1193c97c4fbSSimon Glass ut_asserteq(46, compress_frame_buffer(dev));
1203c97c4fbSSimon Glass
1213c97c4fbSSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
1223c97c4fbSSimon Glass vidconsole_putc_xy(con, 0, 0, 'a');
1233c97c4fbSSimon Glass ut_asserteq(79, compress_frame_buffer(dev));
1243c97c4fbSSimon Glass
1253c97c4fbSSimon Glass vidconsole_putc_xy(con, 0, 0, ' ');
1263c97c4fbSSimon Glass ut_asserteq(46, compress_frame_buffer(dev));
1273c97c4fbSSimon Glass
1283c97c4fbSSimon Glass for (i = 0; i < 20; i++)
129f2661786SSimon Glass vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
1303c97c4fbSSimon Glass ut_asserteq(273, compress_frame_buffer(dev));
1313c97c4fbSSimon Glass
1323c97c4fbSSimon Glass vidconsole_set_row(con, 0, WHITE);
1333c97c4fbSSimon Glass ut_asserteq(46, compress_frame_buffer(dev));
1343c97c4fbSSimon Glass
1353c97c4fbSSimon Glass for (i = 0; i < 20; i++)
136f2661786SSimon Glass vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
1373c97c4fbSSimon Glass ut_asserteq(273, compress_frame_buffer(dev));
1383c97c4fbSSimon Glass
1393c97c4fbSSimon Glass return 0;
1403c97c4fbSSimon Glass }
1413c97c4fbSSimon Glass DM_TEST(dm_test_video_text, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
1423c97c4fbSSimon Glass
1433c97c4fbSSimon Glass /* Test handling of special characters in the console */
dm_test_video_chars(struct unit_test_state * uts)1443c97c4fbSSimon Glass static int dm_test_video_chars(struct unit_test_state *uts)
1453c97c4fbSSimon Glass {
1463c97c4fbSSimon Glass struct udevice *dev, *con;
1475508f10aSSimon Glass const char *test_string = "Well\b\b\b\bxhe is\r \n\ta very \amodest \bman\n\t\tand Has much to\b\bto be modest about.";
1483c97c4fbSSimon Glass
1498df8dad5SSimon Glass ut_assertok(select_vidconsole(uts, "vidconsole0"));
1503c97c4fbSSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
1513c97c4fbSSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
152a7495ac8SRob Clark vidconsole_put_string(con, test_string);
1533c97c4fbSSimon Glass ut_asserteq(466, compress_frame_buffer(dev));
1543c97c4fbSSimon Glass
1553c97c4fbSSimon Glass return 0;
1563c97c4fbSSimon Glass }
1573c97c4fbSSimon Glass DM_TEST(dm_test_video_chars, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
1583c97c4fbSSimon Glass
15940186ee2SRob Clark #ifdef CONFIG_VIDEO_ANSI
16040186ee2SRob Clark #define ANSI_ESC "\x1b"
16140186ee2SRob Clark /* Test handling of ANSI escape sequences */
dm_test_video_ansi(struct unit_test_state * uts)16240186ee2SRob Clark static int dm_test_video_ansi(struct unit_test_state *uts)
16340186ee2SRob Clark {
16440186ee2SRob Clark struct udevice *dev, *con;
16540186ee2SRob Clark
16640186ee2SRob Clark ut_assertok(select_vidconsole(uts, "vidconsole0"));
16740186ee2SRob Clark ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
16840186ee2SRob Clark ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
16940186ee2SRob Clark
17040186ee2SRob Clark /* reference clear: */
17140186ee2SRob Clark video_clear(con->parent);
17255d39911SSimon Glass video_sync(con->parent, false);
17340186ee2SRob Clark ut_asserteq(46, compress_frame_buffer(dev));
17440186ee2SRob Clark
17540186ee2SRob Clark /* test clear escape sequence: [2J */
17640186ee2SRob Clark vidconsole_put_string(con, "A\tB\tC"ANSI_ESC"[2J");
17740186ee2SRob Clark ut_asserteq(46, compress_frame_buffer(dev));
17840186ee2SRob Clark
17940186ee2SRob Clark /* test set-cursor: [%d;%df */
18040186ee2SRob Clark vidconsole_put_string(con, "abc"ANSI_ESC"[2;2fab"ANSI_ESC"[4;4fcd");
181118f020dSHeinrich Schuchardt ut_asserteq(143, compress_frame_buffer(dev));
18240186ee2SRob Clark
18340186ee2SRob Clark /* test colors (30-37 fg color, 40-47 bg color) */
18440186ee2SRob Clark vidconsole_put_string(con, ANSI_ESC"[30;41mfoo"); /* black on red */
18540186ee2SRob Clark vidconsole_put_string(con, ANSI_ESC"[33;44mbar"); /* yellow on blue */
186118f020dSHeinrich Schuchardt ut_asserteq(272, compress_frame_buffer(dev));
18740186ee2SRob Clark
18840186ee2SRob Clark return 0;
18940186ee2SRob Clark }
19040186ee2SRob Clark DM_TEST(dm_test_video_ansi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
19140186ee2SRob Clark #endif
19240186ee2SRob Clark
1933c97c4fbSSimon Glass /**
1943c97c4fbSSimon Glass * check_vidconsole_output() - Run a text console test
1953c97c4fbSSimon Glass *
1963c97c4fbSSimon Glass * @uts: Test state
1973c97c4fbSSimon Glass * @rot: Console rotation (0, 90, 180, 270)
1983c97c4fbSSimon Glass * @wrap_size: Expected size of compressed frame buffer for the wrap test
1993c97c4fbSSimon Glass * @scroll_size: Same for the scroll test
2003c97c4fbSSimon Glass * @return 0 on success
2013c97c4fbSSimon Glass */
check_vidconsole_output(struct unit_test_state * uts,int rot,int wrap_size,int scroll_size)2023c97c4fbSSimon Glass static int check_vidconsole_output(struct unit_test_state *uts, int rot,
2033c97c4fbSSimon Glass int wrap_size, int scroll_size)
2043c97c4fbSSimon Glass {
2053c97c4fbSSimon Glass struct udevice *dev, *con;
2063c97c4fbSSimon Glass struct sandbox_sdl_plat *plat;
2073c97c4fbSSimon Glass int i;
2083c97c4fbSSimon Glass
2093c97c4fbSSimon Glass ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
2103c97c4fbSSimon Glass ut_assert(!device_active(dev));
2113c97c4fbSSimon Glass plat = dev_get_platdata(dev);
2123c97c4fbSSimon Glass plat->rot = rot;
2133c97c4fbSSimon Glass
2143c97c4fbSSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
2153c97c4fbSSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
2163c97c4fbSSimon Glass ut_asserteq(46, compress_frame_buffer(dev));
2173c97c4fbSSimon Glass
2183c97c4fbSSimon Glass /* Check display wrap */
2193c97c4fbSSimon Glass for (i = 0; i < 120; i++)
2203c97c4fbSSimon Glass vidconsole_put_char(con, 'A' + i % 50);
2213c97c4fbSSimon Glass ut_asserteq(wrap_size, compress_frame_buffer(dev));
2223c97c4fbSSimon Glass
2233c97c4fbSSimon Glass /* Check display scrolling */
2243c97c4fbSSimon Glass for (i = 0; i < SCROLL_LINES; i++) {
2253c97c4fbSSimon Glass vidconsole_put_char(con, 'A' + i % 50);
2263c97c4fbSSimon Glass vidconsole_put_char(con, '\n');
2273c97c4fbSSimon Glass }
2283c97c4fbSSimon Glass ut_asserteq(scroll_size, compress_frame_buffer(dev));
2293c97c4fbSSimon Glass
2303c97c4fbSSimon Glass /* If we scroll enough, the screen becomes blank again */
2313c97c4fbSSimon Glass for (i = 0; i < SCROLL_LINES; i++)
2323c97c4fbSSimon Glass vidconsole_put_char(con, '\n');
2333c97c4fbSSimon Glass ut_asserteq(46, compress_frame_buffer(dev));
2343c97c4fbSSimon Glass
2353c97c4fbSSimon Glass return 0;
2363c97c4fbSSimon Glass }
2373c97c4fbSSimon Glass
2383c97c4fbSSimon Glass /* Test text output through the console uclass */
dm_test_video_context(struct unit_test_state * uts)2393c97c4fbSSimon Glass static int dm_test_video_context(struct unit_test_state *uts)
2403c97c4fbSSimon Glass {
2418df8dad5SSimon Glass ut_assertok(select_vidconsole(uts, "vidconsole0"));
2428df8dad5SSimon Glass ut_assertok(check_vidconsole_output(uts, 0, 788, 453));
2438df8dad5SSimon Glass
2448df8dad5SSimon Glass return 0;
2453c97c4fbSSimon Glass }
2463c97c4fbSSimon Glass DM_TEST(dm_test_video_context, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
24785e08db8SSimon Glass
24885e08db8SSimon Glass /* Test rotated text output through the console uclass */
dm_test_video_rotation1(struct unit_test_state * uts)24985e08db8SSimon Glass static int dm_test_video_rotation1(struct unit_test_state *uts)
25085e08db8SSimon Glass {
25185e08db8SSimon Glass ut_assertok(check_vidconsole_output(uts, 1, 1112, 680));
25285e08db8SSimon Glass
25385e08db8SSimon Glass return 0;
25485e08db8SSimon Glass }
25585e08db8SSimon Glass DM_TEST(dm_test_video_rotation1, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
25685e08db8SSimon Glass
25785e08db8SSimon Glass /* Test rotated text output through the console uclass */
dm_test_video_rotation2(struct unit_test_state * uts)25885e08db8SSimon Glass static int dm_test_video_rotation2(struct unit_test_state *uts)
25985e08db8SSimon Glass {
26085e08db8SSimon Glass ut_assertok(check_vidconsole_output(uts, 2, 785, 446));
26185e08db8SSimon Glass
26285e08db8SSimon Glass return 0;
26385e08db8SSimon Glass }
26485e08db8SSimon Glass DM_TEST(dm_test_video_rotation2, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
26585e08db8SSimon Glass
26685e08db8SSimon Glass /* Test rotated text output through the console uclass */
dm_test_video_rotation3(struct unit_test_state * uts)26785e08db8SSimon Glass static int dm_test_video_rotation3(struct unit_test_state *uts)
26885e08db8SSimon Glass {
26985e08db8SSimon Glass ut_assertok(check_vidconsole_output(uts, 3, 1134, 681));
27085e08db8SSimon Glass
27185e08db8SSimon Glass return 0;
27285e08db8SSimon Glass }
27385e08db8SSimon Glass DM_TEST(dm_test_video_rotation3, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
274747440d0SSimon Glass
275747440d0SSimon Glass /* Read a file into memory and return a pointer to it */
read_file(struct unit_test_state * uts,const char * fname,ulong * addrp)276747440d0SSimon Glass static int read_file(struct unit_test_state *uts, const char *fname,
277747440d0SSimon Glass ulong *addrp)
278747440d0SSimon Glass {
279747440d0SSimon Glass int buf_size = 100000;
280747440d0SSimon Glass ulong addr = 0;
281747440d0SSimon Glass int size, fd;
282747440d0SSimon Glass char *buf;
283747440d0SSimon Glass
284747440d0SSimon Glass buf = map_sysmem(addr, 0);
285747440d0SSimon Glass ut_assert(buf != NULL);
286747440d0SSimon Glass fd = os_open(fname, OS_O_RDONLY);
287747440d0SSimon Glass ut_assert(fd >= 0);
288747440d0SSimon Glass size = os_read(fd, buf, buf_size);
289a108082dSSimon Glass os_close(fd);
290747440d0SSimon Glass ut_assert(size >= 0);
291747440d0SSimon Glass ut_assert(size < buf_size);
292747440d0SSimon Glass *addrp = addr;
293747440d0SSimon Glass
294747440d0SSimon Glass return 0;
295747440d0SSimon Glass }
296747440d0SSimon Glass
297747440d0SSimon Glass /* Test drawing a bitmap file */
dm_test_video_bmp(struct unit_test_state * uts)298747440d0SSimon Glass static int dm_test_video_bmp(struct unit_test_state *uts)
299747440d0SSimon Glass {
300747440d0SSimon Glass struct udevice *dev;
301747440d0SSimon Glass ulong addr;
302747440d0SSimon Glass
303747440d0SSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
304747440d0SSimon Glass ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
305747440d0SSimon Glass
306747440d0SSimon Glass ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
307747440d0SSimon Glass ut_asserteq(1368, compress_frame_buffer(dev));
308747440d0SSimon Glass
309747440d0SSimon Glass return 0;
310747440d0SSimon Glass }
311747440d0SSimon Glass DM_TEST(dm_test_video_bmp, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
312747440d0SSimon Glass
313747440d0SSimon Glass /* Test drawing a compressed bitmap file */
dm_test_video_bmp_comp(struct unit_test_state * uts)314747440d0SSimon Glass static int dm_test_video_bmp_comp(struct unit_test_state *uts)
315747440d0SSimon Glass {
316747440d0SSimon Glass struct udevice *dev;
317747440d0SSimon Glass ulong addr;
318747440d0SSimon Glass
319747440d0SSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
320747440d0SSimon Glass ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
321747440d0SSimon Glass
322747440d0SSimon Glass ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
323747440d0SSimon Glass ut_asserteq(1368, compress_frame_buffer(dev));
324747440d0SSimon Glass
325747440d0SSimon Glass return 0;
326747440d0SSimon Glass }
327747440d0SSimon Glass DM_TEST(dm_test_video_bmp_comp, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
3285674ead7SSimon Glass
3295674ead7SSimon Glass /* Test TrueType console */
dm_test_video_truetype(struct unit_test_state * uts)3305674ead7SSimon Glass static int dm_test_video_truetype(struct unit_test_state *uts)
3315674ead7SSimon Glass {
3325674ead7SSimon Glass struct udevice *dev, *con;
3335674ead7SSimon Glass const char *test_string = "Criticism may not be agreeable, but it is necessary. It fulfils the same function as pain in the human body. It calls attention to an unhealthy state of things. Some see private enterprise as a predatory target to be shot, others as a cow to be milked, but few are those who see it as a sturdy horse pulling the wagon. The \aprice OF\b\bof greatness\n\tis responsibility.\n\nBye";
3345674ead7SSimon Glass
3355674ead7SSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
3365674ead7SSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
337a7495ac8SRob Clark vidconsole_put_string(con, test_string);
338*daaba089SAnatolij Gustschin ut_asserteq(12237, compress_frame_buffer(dev));
3395674ead7SSimon Glass
3405674ead7SSimon Glass return 0;
3415674ead7SSimon Glass }
3425674ead7SSimon Glass DM_TEST(dm_test_video_truetype, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
3435674ead7SSimon Glass
3445674ead7SSimon Glass /* Test scrolling TrueType console */
dm_test_video_truetype_scroll(struct unit_test_state * uts)3455674ead7SSimon Glass static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
3465674ead7SSimon Glass {
3475674ead7SSimon Glass struct sandbox_sdl_plat *plat;
3485674ead7SSimon Glass struct udevice *dev, *con;
3495674ead7SSimon Glass const char *test_string = "Criticism may not be agreeable, but it is necessary. It fulfils the same function as pain in the human body. It calls attention to an unhealthy state of things. Some see private enterprise as a predatory target to be shot, others as a cow to be milked, but few are those who see it as a sturdy horse pulling the wagon. The \aprice OF\b\bof greatness\n\tis responsibility.\n\nBye";
3505674ead7SSimon Glass
3515674ead7SSimon Glass ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
3525674ead7SSimon Glass ut_assert(!device_active(dev));
3535674ead7SSimon Glass plat = dev_get_platdata(dev);
3545674ead7SSimon Glass plat->font_size = 100;
3555674ead7SSimon Glass
3565674ead7SSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
3575674ead7SSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
358a7495ac8SRob Clark vidconsole_put_string(con, test_string);
359*daaba089SAnatolij Gustschin ut_asserteq(35030, compress_frame_buffer(dev));
3605674ead7SSimon Glass
3615674ead7SSimon Glass return 0;
3625674ead7SSimon Glass }
3635674ead7SSimon Glass DM_TEST(dm_test_video_truetype_scroll, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
3645674ead7SSimon Glass
3655674ead7SSimon Glass /* Test TrueType backspace, within and across lines */
dm_test_video_truetype_bs(struct unit_test_state * uts)3665674ead7SSimon Glass static int dm_test_video_truetype_bs(struct unit_test_state *uts)
3675674ead7SSimon Glass {
3685674ead7SSimon Glass struct sandbox_sdl_plat *plat;
3695674ead7SSimon Glass struct udevice *dev, *con;
3705674ead7SSimon Glass const char *test_string = "...Criticism may or may\b\b\b\b\b\bnot be agreeable, but seldom it is necessary\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bit is necessary. It fulfils the same function as pain in the human body. It calls attention to an unhealthy state of things.";
3715674ead7SSimon Glass
3725674ead7SSimon Glass ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
3735674ead7SSimon Glass ut_assert(!device_active(dev));
3745674ead7SSimon Glass plat = dev_get_platdata(dev);
3755674ead7SSimon Glass plat->font_size = 100;
3765674ead7SSimon Glass
3775674ead7SSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
3785674ead7SSimon Glass ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
379a7495ac8SRob Clark vidconsole_put_string(con, test_string);
380*daaba089SAnatolij Gustschin ut_asserteq(29018, compress_frame_buffer(dev));
3815674ead7SSimon Glass
3825674ead7SSimon Glass return 0;
3835674ead7SSimon Glass }
3845674ead7SSimon Glass DM_TEST(dm_test_video_truetype_bs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
385