xref: /OK3568_Linux_fs/u-boot/test/dm/video.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2014 Google, Inc
3*4882a593Smuzhiyun  * Written by Simon Glass <sjg@chromium.org>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <common.h>
9*4882a593Smuzhiyun #include <bzlib.h>
10*4882a593Smuzhiyun #include <dm.h>
11*4882a593Smuzhiyun #include <mapmem.h>
12*4882a593Smuzhiyun #include <os.h>
13*4882a593Smuzhiyun #include <video.h>
14*4882a593Smuzhiyun #include <video_console.h>
15*4882a593Smuzhiyun #include <dm/test.h>
16*4882a593Smuzhiyun #include <dm/uclass-internal.h>
17*4882a593Smuzhiyun #include <test/ut.h>
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /*
20*4882a593Smuzhiyun  * These tests use the standard sandbox frame buffer, the resolution of which
21*4882a593Smuzhiyun  * is defined in the device tree. This only supports 16bpp so the tests only
22*4882a593Smuzhiyun  * test that code path. It would be possible to adjust this fairly easily,
23*4882a593Smuzhiyun  * by adjusting the bpix value in struct sandbox_sdl_plat. However the code
24*4882a593Smuzhiyun  * in sandbox_sdl_sync() would also need to change to handle the different
25*4882a593Smuzhiyun  * surface depth.
26*4882a593Smuzhiyun  */
27*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun /* Basic test of the video uclass */
dm_test_video_base(struct unit_test_state * uts)30*4882a593Smuzhiyun static int dm_test_video_base(struct unit_test_state *uts)
31*4882a593Smuzhiyun {
32*4882a593Smuzhiyun 	struct video_priv *priv;
33*4882a593Smuzhiyun 	struct udevice *dev;
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
36*4882a593Smuzhiyun 	ut_asserteq(1366, video_get_xsize(dev));
37*4882a593Smuzhiyun 	ut_asserteq(768, video_get_ysize(dev));
38*4882a593Smuzhiyun 	priv = dev_get_uclass_priv(dev);
39*4882a593Smuzhiyun 	ut_asserteq(priv->fb_size, 1366 * 768 * 2);
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun 	return 0;
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun DM_TEST(dm_test_video_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /**
46*4882a593Smuzhiyun  * compress_frame_buffer() - Compress the frame buffer and return its size
47*4882a593Smuzhiyun  *
48*4882a593Smuzhiyun  * We want to write tests which perform operations on the video console and
49*4882a593Smuzhiyun  * check that the frame buffer ends up with the correct contents. But it is
50*4882a593Smuzhiyun  * painful to store 'known good' images for comparison with the frame
51*4882a593Smuzhiyun  * buffer. As an alternative, we can compress the frame buffer and check the
52*4882a593Smuzhiyun  * size of the compressed data. This provides a pretty good level of
53*4882a593Smuzhiyun  * certainty and the resulting tests need only check a single value.
54*4882a593Smuzhiyun  *
55*4882a593Smuzhiyun  * @dev:	Video device
56*4882a593Smuzhiyun  * @return compressed size of the frame buffer, or -ve on error
57*4882a593Smuzhiyun  */
compress_frame_buffer(struct udevice * dev)58*4882a593Smuzhiyun static int compress_frame_buffer(struct udevice *dev)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	struct video_priv *priv = dev_get_uclass_priv(dev);
61*4882a593Smuzhiyun 	uint destlen;
62*4882a593Smuzhiyun 	void *dest;
63*4882a593Smuzhiyun 	int ret;
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun 	destlen = priv->fb_size;
66*4882a593Smuzhiyun 	dest = malloc(priv->fb_size);
67*4882a593Smuzhiyun 	if (!dest)
68*4882a593Smuzhiyun 		return -ENOMEM;
69*4882a593Smuzhiyun 	ret = BZ2_bzBuffToBuffCompress(dest, &destlen,
70*4882a593Smuzhiyun 				       priv->fb, priv->fb_size,
71*4882a593Smuzhiyun 				       3, 0, 0);
72*4882a593Smuzhiyun 	free(dest);
73*4882a593Smuzhiyun 	if (ret)
74*4882a593Smuzhiyun 		return ret;
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun 	return destlen;
77*4882a593Smuzhiyun }
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun /*
80*4882a593Smuzhiyun  * Call this function at any point to halt and show the current display. Be
81*4882a593Smuzhiyun  * sure to run the test with the -l flag.
82*4882a593Smuzhiyun  */
see_output(void)83*4882a593Smuzhiyun static void __maybe_unused see_output(void)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun 	video_sync_all();
86*4882a593Smuzhiyun 	while (1);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun /* Select the video console driver to use for a video device */
select_vidconsole(struct unit_test_state * uts,const char * drv_name)90*4882a593Smuzhiyun static int select_vidconsole(struct unit_test_state *uts, const char *drv_name)
91*4882a593Smuzhiyun {
92*4882a593Smuzhiyun 	struct sandbox_sdl_plat *plat;
93*4882a593Smuzhiyun 	struct udevice *dev;
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
96*4882a593Smuzhiyun 	ut_assert(!device_active(dev));
97*4882a593Smuzhiyun 	plat = dev_get_platdata(dev);
98*4882a593Smuzhiyun 	plat->vidconsole_drv_name = "vidconsole0";
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	return 0;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun /* Test text output works on the video console */
dm_test_video_text(struct unit_test_state * uts)104*4882a593Smuzhiyun static int dm_test_video_text(struct unit_test_state *uts)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun 	struct udevice *dev, *con;
107*4882a593Smuzhiyun 	int i;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun #define WHITE		0xffff
110*4882a593Smuzhiyun #define SCROLL_LINES	100
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	ut_assertok(select_vidconsole(uts, "vidconsole0"));
113*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
114*4882a593Smuzhiyun 	ut_asserteq(46, compress_frame_buffer(dev));
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
117*4882a593Smuzhiyun 	vidconsole_putc_xy(con, 0, 0, 'a');
118*4882a593Smuzhiyun 	ut_asserteq(79, compress_frame_buffer(dev));
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	vidconsole_putc_xy(con, 0, 0, ' ');
121*4882a593Smuzhiyun 	ut_asserteq(46, compress_frame_buffer(dev));
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	for (i = 0; i < 20; i++)
124*4882a593Smuzhiyun 		vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
125*4882a593Smuzhiyun 	ut_asserteq(273, compress_frame_buffer(dev));
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	vidconsole_set_row(con, 0, WHITE);
128*4882a593Smuzhiyun 	ut_asserteq(46, compress_frame_buffer(dev));
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 	for (i = 0; i < 20; i++)
131*4882a593Smuzhiyun 		vidconsole_putc_xy(con, VID_TO_POS(i * 8), 0, ' ' + i);
132*4882a593Smuzhiyun 	ut_asserteq(273, compress_frame_buffer(dev));
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	return 0;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun DM_TEST(dm_test_video_text, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun /* Test handling of special characters in the console */
dm_test_video_chars(struct unit_test_state * uts)139*4882a593Smuzhiyun static int dm_test_video_chars(struct unit_test_state *uts)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	struct udevice *dev, *con;
142*4882a593Smuzhiyun 	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.";
143*4882a593Smuzhiyun 	const char *s;
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun 	ut_assertok(select_vidconsole(uts, "vidconsole0"));
146*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
147*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
148*4882a593Smuzhiyun 	for (s = test_string; *s; s++)
149*4882a593Smuzhiyun 		vidconsole_put_char(con, *s);
150*4882a593Smuzhiyun 	ut_asserteq(466, compress_frame_buffer(dev));
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	return 0;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun DM_TEST(dm_test_video_chars, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun /**
157*4882a593Smuzhiyun  * check_vidconsole_output() - Run a text console test
158*4882a593Smuzhiyun  *
159*4882a593Smuzhiyun  * @uts:	Test state
160*4882a593Smuzhiyun  * @rot:	Console rotation (0, 90, 180, 270)
161*4882a593Smuzhiyun  * @wrap_size:	Expected size of compressed frame buffer for the wrap test
162*4882a593Smuzhiyun  * @scroll_size: Same for the scroll test
163*4882a593Smuzhiyun  * @return 0 on success
164*4882a593Smuzhiyun  */
check_vidconsole_output(struct unit_test_state * uts,int rot,int wrap_size,int scroll_size)165*4882a593Smuzhiyun static int check_vidconsole_output(struct unit_test_state *uts, int rot,
166*4882a593Smuzhiyun 				   int wrap_size, int scroll_size)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	struct udevice *dev, *con;
169*4882a593Smuzhiyun 	struct sandbox_sdl_plat *plat;
170*4882a593Smuzhiyun 	int i;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
173*4882a593Smuzhiyun 	ut_assert(!device_active(dev));
174*4882a593Smuzhiyun 	plat = dev_get_platdata(dev);
175*4882a593Smuzhiyun 	plat->rot = rot;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
178*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
179*4882a593Smuzhiyun 	ut_asserteq(46, compress_frame_buffer(dev));
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	/* Check display wrap */
182*4882a593Smuzhiyun 	for (i = 0; i < 120; i++)
183*4882a593Smuzhiyun 		vidconsole_put_char(con, 'A' + i % 50);
184*4882a593Smuzhiyun 	ut_asserteq(wrap_size, compress_frame_buffer(dev));
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	/* Check display scrolling */
187*4882a593Smuzhiyun 	for (i = 0; i < SCROLL_LINES; i++) {
188*4882a593Smuzhiyun 		vidconsole_put_char(con, 'A' + i % 50);
189*4882a593Smuzhiyun 		vidconsole_put_char(con, '\n');
190*4882a593Smuzhiyun 	}
191*4882a593Smuzhiyun 	ut_asserteq(scroll_size, compress_frame_buffer(dev));
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	/* If we scroll enough, the screen becomes blank again */
194*4882a593Smuzhiyun 	for (i = 0; i < SCROLL_LINES; i++)
195*4882a593Smuzhiyun 		vidconsole_put_char(con, '\n');
196*4882a593Smuzhiyun 	ut_asserteq(46, compress_frame_buffer(dev));
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	return 0;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun /* Test text output through the console uclass */
dm_test_video_context(struct unit_test_state * uts)202*4882a593Smuzhiyun static int dm_test_video_context(struct unit_test_state *uts)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	ut_assertok(select_vidconsole(uts, "vidconsole0"));
205*4882a593Smuzhiyun 	ut_assertok(check_vidconsole_output(uts, 0, 788, 453));
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	return 0;
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun DM_TEST(dm_test_video_context, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun /* Test rotated text output through the console uclass */
dm_test_video_rotation1(struct unit_test_state * uts)212*4882a593Smuzhiyun static int dm_test_video_rotation1(struct unit_test_state *uts)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun 	ut_assertok(check_vidconsole_output(uts, 1, 1112, 680));
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	return 0;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun DM_TEST(dm_test_video_rotation1, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun /* Test rotated text output through the console uclass */
dm_test_video_rotation2(struct unit_test_state * uts)221*4882a593Smuzhiyun static int dm_test_video_rotation2(struct unit_test_state *uts)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	ut_assertok(check_vidconsole_output(uts, 2, 785, 446));
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	return 0;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun DM_TEST(dm_test_video_rotation2, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun /* Test rotated text output through the console uclass */
dm_test_video_rotation3(struct unit_test_state * uts)230*4882a593Smuzhiyun static int dm_test_video_rotation3(struct unit_test_state *uts)
231*4882a593Smuzhiyun {
232*4882a593Smuzhiyun 	ut_assertok(check_vidconsole_output(uts, 3, 1134, 681));
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	return 0;
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun DM_TEST(dm_test_video_rotation3, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun /* Read a file into memory and return a pointer to it */
read_file(struct unit_test_state * uts,const char * fname,ulong * addrp)239*4882a593Smuzhiyun static int read_file(struct unit_test_state *uts, const char *fname,
240*4882a593Smuzhiyun 		     ulong *addrp)
241*4882a593Smuzhiyun {
242*4882a593Smuzhiyun 	int buf_size = 100000;
243*4882a593Smuzhiyun 	ulong addr = 0;
244*4882a593Smuzhiyun 	int size, fd;
245*4882a593Smuzhiyun 	char *buf;
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 	buf = map_sysmem(addr, 0);
248*4882a593Smuzhiyun 	ut_assert(buf != NULL);
249*4882a593Smuzhiyun 	fd = os_open(fname, OS_O_RDONLY);
250*4882a593Smuzhiyun 	ut_assert(fd >= 0);
251*4882a593Smuzhiyun 	size = os_read(fd, buf, buf_size);
252*4882a593Smuzhiyun 	os_close(fd);
253*4882a593Smuzhiyun 	ut_assert(size >= 0);
254*4882a593Smuzhiyun 	ut_assert(size < buf_size);
255*4882a593Smuzhiyun 	*addrp = addr;
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 	return 0;
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun /* Test drawing a bitmap file */
dm_test_video_bmp(struct unit_test_state * uts)261*4882a593Smuzhiyun static int dm_test_video_bmp(struct unit_test_state *uts)
262*4882a593Smuzhiyun {
263*4882a593Smuzhiyun 	struct udevice *dev;
264*4882a593Smuzhiyun 	ulong addr;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
267*4882a593Smuzhiyun 	ut_assertok(read_file(uts, "tools/logos/denx.bmp", &addr));
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
270*4882a593Smuzhiyun 	ut_asserteq(1368, compress_frame_buffer(dev));
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	return 0;
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun DM_TEST(dm_test_video_bmp, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun /* Test drawing a compressed bitmap file */
dm_test_video_bmp_comp(struct unit_test_state * uts)277*4882a593Smuzhiyun static int dm_test_video_bmp_comp(struct unit_test_state *uts)
278*4882a593Smuzhiyun {
279*4882a593Smuzhiyun 	struct udevice *dev;
280*4882a593Smuzhiyun 	ulong addr;
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
283*4882a593Smuzhiyun 	ut_assertok(read_file(uts, "tools/logos/denx-comp.bmp", &addr));
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun 	ut_assertok(video_bmp_display(dev, addr, 0, 0, false));
286*4882a593Smuzhiyun 	ut_asserteq(1368, compress_frame_buffer(dev));
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	return 0;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun DM_TEST(dm_test_video_bmp_comp, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun /* Test TrueType console */
dm_test_video_truetype(struct unit_test_state * uts)293*4882a593Smuzhiyun static int dm_test_video_truetype(struct unit_test_state *uts)
294*4882a593Smuzhiyun {
295*4882a593Smuzhiyun 	struct udevice *dev, *con;
296*4882a593Smuzhiyun 	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";
297*4882a593Smuzhiyun 	const char *s;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
300*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
301*4882a593Smuzhiyun 	for (s = test_string; *s; s++)
302*4882a593Smuzhiyun 		vidconsole_put_char(con, *s);
303*4882a593Smuzhiyun 	ut_asserteq(12619, compress_frame_buffer(dev));
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	return 0;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun DM_TEST(dm_test_video_truetype, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun /* Test scrolling TrueType console */
dm_test_video_truetype_scroll(struct unit_test_state * uts)310*4882a593Smuzhiyun static int dm_test_video_truetype_scroll(struct unit_test_state *uts)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun 	struct sandbox_sdl_plat *plat;
313*4882a593Smuzhiyun 	struct udevice *dev, *con;
314*4882a593Smuzhiyun 	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";
315*4882a593Smuzhiyun 	const char *s;
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
318*4882a593Smuzhiyun 	ut_assert(!device_active(dev));
319*4882a593Smuzhiyun 	plat = dev_get_platdata(dev);
320*4882a593Smuzhiyun 	plat->font_size = 100;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
323*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
324*4882a593Smuzhiyun 	for (s = test_string; *s; s++)
325*4882a593Smuzhiyun 		vidconsole_put_char(con, *s);
326*4882a593Smuzhiyun 	ut_asserteq(33849, compress_frame_buffer(dev));
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 	return 0;
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun DM_TEST(dm_test_video_truetype_scroll, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun /* Test TrueType backspace, within and across lines */
dm_test_video_truetype_bs(struct unit_test_state * uts)333*4882a593Smuzhiyun static int dm_test_video_truetype_bs(struct unit_test_state *uts)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun 	struct sandbox_sdl_plat *plat;
336*4882a593Smuzhiyun 	struct udevice *dev, *con;
337*4882a593Smuzhiyun 	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.";
338*4882a593Smuzhiyun 	const char *s;
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun 	ut_assertok(uclass_find_device(UCLASS_VIDEO, 0, &dev));
341*4882a593Smuzhiyun 	ut_assert(!device_active(dev));
342*4882a593Smuzhiyun 	plat = dev_get_platdata(dev);
343*4882a593Smuzhiyun 	plat->font_size = 100;
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO, 0, &dev));
346*4882a593Smuzhiyun 	ut_assertok(uclass_get_device(UCLASS_VIDEO_CONSOLE, 0, &con));
347*4882a593Smuzhiyun 	for (s = test_string; *s; s++)
348*4882a593Smuzhiyun 		vidconsole_put_char(con, *s);
349*4882a593Smuzhiyun 	ut_asserteq(34871, compress_frame_buffer(dev));
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	return 0;
352*4882a593Smuzhiyun }
353*4882a593Smuzhiyun DM_TEST(dm_test_video_truetype_bs, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
354