xref: /openbmc/u-boot/test/dm/video.c (revision 53240275666acf32cb9811e44eaf2fd571a6cb75)
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