1 // SPDX-License-Identifier: GPL-2.0+
2 
3 #include <kunit/test.h>
4 
5 #include <drm/drm_device.h>
6 #include <drm/drm_file.h>
7 #include <drm/drm_format_helper.h>
8 #include <drm/drm_fourcc.h>
9 #include <drm/drm_framebuffer.h>
10 #include <drm/drm_gem_framebuffer_helper.h>
11 #include <drm/drm_mode.h>
12 #include <drm/drm_print.h>
13 #include <drm/drm_rect.h>
14 
15 #include "../drm_crtc_internal.h"
16 
17 #define TEST_BUF_SIZE 50
18 
19 struct convert_to_gray8_result {
20 	unsigned int dst_pitch;
21 	const u8 expected[TEST_BUF_SIZE];
22 };
23 
24 struct convert_to_rgb332_result {
25 	unsigned int dst_pitch;
26 	const u8 expected[TEST_BUF_SIZE];
27 };
28 
29 struct convert_to_rgb565_result {
30 	unsigned int dst_pitch;
31 	const u16 expected[TEST_BUF_SIZE];
32 	const u16 expected_swab[TEST_BUF_SIZE];
33 };
34 
35 struct convert_to_xrgb1555_result {
36 	unsigned int dst_pitch;
37 	const u16 expected[TEST_BUF_SIZE];
38 };
39 
40 struct convert_to_argb1555_result {
41 	unsigned int dst_pitch;
42 	const u16 expected[TEST_BUF_SIZE];
43 };
44 
45 struct convert_to_rgba5551_result {
46 	unsigned int dst_pitch;
47 	const u16 expected[TEST_BUF_SIZE];
48 };
49 
50 struct convert_to_rgb888_result {
51 	unsigned int dst_pitch;
52 	const u8 expected[TEST_BUF_SIZE];
53 };
54 
55 struct convert_to_argb8888_result {
56 	unsigned int dst_pitch;
57 	const u32 expected[TEST_BUF_SIZE];
58 };
59 
60 struct convert_to_xrgb2101010_result {
61 	unsigned int dst_pitch;
62 	const u32 expected[TEST_BUF_SIZE];
63 };
64 
65 struct convert_to_argb2101010_result {
66 	unsigned int dst_pitch;
67 	const u32 expected[TEST_BUF_SIZE];
68 };
69 
70 struct convert_xrgb8888_case {
71 	const char *name;
72 	unsigned int pitch;
73 	struct drm_rect clip;
74 	const u32 xrgb8888[TEST_BUF_SIZE];
75 	struct convert_to_gray8_result gray8_result;
76 	struct convert_to_rgb332_result rgb332_result;
77 	struct convert_to_rgb565_result rgb565_result;
78 	struct convert_to_xrgb1555_result xrgb1555_result;
79 	struct convert_to_argb1555_result argb1555_result;
80 	struct convert_to_rgba5551_result rgba5551_result;
81 	struct convert_to_rgb888_result rgb888_result;
82 	struct convert_to_argb8888_result argb8888_result;
83 	struct convert_to_xrgb2101010_result xrgb2101010_result;
84 	struct convert_to_argb2101010_result argb2101010_result;
85 };
86 
87 static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
88 	{
89 		.name = "single_pixel_source_buffer",
90 		.pitch = 1 * 4,
91 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
92 		.xrgb8888 = { 0x01FF0000 },
93 		.gray8_result = {
94 			.dst_pitch = 0,
95 			.expected = { 0x4C },
96 		},
97 		.rgb332_result = {
98 			.dst_pitch = 0,
99 			.expected = { 0xE0 },
100 		},
101 		.rgb565_result = {
102 			.dst_pitch = 0,
103 			.expected = { 0xF800 },
104 			.expected_swab = { 0x00F8 },
105 		},
106 		.xrgb1555_result = {
107 			.dst_pitch = 0,
108 			.expected = { 0x7C00 },
109 		},
110 		.argb1555_result = {
111 			.dst_pitch = 0,
112 			.expected = { 0xFC00 },
113 		},
114 		.rgba5551_result = {
115 			.dst_pitch = 0,
116 			.expected = { 0xF801 },
117 		},
118 		.rgb888_result = {
119 			.dst_pitch = 0,
120 			.expected = { 0x00, 0x00, 0xFF },
121 		},
122 		.argb8888_result = {
123 			.dst_pitch = 0,
124 			.expected = { 0xFFFF0000 },
125 		},
126 		.xrgb2101010_result = {
127 			.dst_pitch = 0,
128 			.expected = { 0x3FF00000 },
129 		},
130 		.argb2101010_result = {
131 			.dst_pitch = 0,
132 			.expected = { 0xFFF00000 },
133 		},
134 	},
135 	{
136 		.name = "single_pixel_clip_rectangle",
137 		.pitch = 2 * 4,
138 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
139 		.xrgb8888 = {
140 			0x00000000, 0x00000000,
141 			0x00000000, 0x10FF0000,
142 		},
143 		.gray8_result = {
144 			.dst_pitch = 0,
145 			.expected = { 0x4C },
146 		},
147 		.rgb332_result = {
148 			.dst_pitch = 0,
149 			.expected = { 0xE0 },
150 		},
151 		.rgb565_result = {
152 			.dst_pitch = 0,
153 			.expected = { 0xF800 },
154 			.expected_swab = { 0x00F8 },
155 		},
156 		.xrgb1555_result = {
157 			.dst_pitch = 0,
158 			.expected = { 0x7C00 },
159 		},
160 		.argb1555_result = {
161 			.dst_pitch = 0,
162 			.expected = { 0xFC00 },
163 		},
164 		.rgba5551_result = {
165 			.dst_pitch = 0,
166 			.expected = { 0xF801 },
167 		},
168 		.rgb888_result = {
169 			.dst_pitch = 0,
170 			.expected = { 0x00, 0x00, 0xFF },
171 		},
172 		.argb8888_result = {
173 			.dst_pitch = 0,
174 			.expected = { 0xFFFF0000 },
175 		},
176 		.xrgb2101010_result = {
177 			.dst_pitch = 0,
178 			.expected = { 0x3FF00000 },
179 		},
180 		.argb2101010_result = {
181 			.dst_pitch = 0,
182 			.expected = { 0xFFF00000 },
183 		},
184 	},
185 	{
186 		/* Well known colors: White, black, red, green, blue, magenta,
187 		 * yellow and cyan. Different values for the X in XRGB8888 to
188 		 * make sure it is ignored. Partial clip area.
189 		 */
190 		.name = "well_known_colors",
191 		.pitch = 4 * 4,
192 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
193 		.xrgb8888 = {
194 			0x00000000, 0x00000000, 0x00000000, 0x00000000,
195 			0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
196 			0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
197 			0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
198 			0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
199 		},
200 		.gray8_result = {
201 			.dst_pitch = 0,
202 			.expected = {
203 				0xFF, 0x00,
204 				0x4C, 0x99,
205 				0x19, 0x66,
206 				0xE5, 0xB2,
207 			},
208 		},
209 		.rgb332_result = {
210 			.dst_pitch = 0,
211 			.expected = {
212 				0xFF, 0x00,
213 				0xE0, 0x1C,
214 				0x03, 0xE3,
215 				0xFC, 0x1F,
216 			},
217 		},
218 		.rgb565_result = {
219 			.dst_pitch = 0,
220 			.expected = {
221 				0xFFFF, 0x0000,
222 				0xF800, 0x07E0,
223 				0x001F, 0xF81F,
224 				0xFFE0, 0x07FF,
225 			},
226 			.expected_swab = {
227 				0xFFFF, 0x0000,
228 				0x00F8, 0xE007,
229 				0x1F00, 0x1FF8,
230 				0xE0FF, 0xFF07,
231 			},
232 		},
233 		.xrgb1555_result = {
234 			.dst_pitch = 0,
235 			.expected = {
236 				0x7FFF, 0x0000,
237 				0x7C00, 0x03E0,
238 				0x001F, 0x7C1F,
239 				0x7FE0, 0x03FF,
240 			},
241 		},
242 		.argb1555_result = {
243 			.dst_pitch = 0,
244 			.expected = {
245 				0xFFFF, 0x8000,
246 				0xFC00, 0x83E0,
247 				0x801F, 0xFC1F,
248 				0xFFE0, 0x83FF,
249 			},
250 		},
251 		.rgba5551_result = {
252 			.dst_pitch = 0,
253 			.expected = {
254 				0xFFFF, 0x0001,
255 				0xF801, 0x07C1,
256 				0x003F, 0xF83F,
257 				0xFFC1, 0x07FF,
258 			},
259 		},
260 		.rgb888_result = {
261 			.dst_pitch = 0,
262 			.expected = {
263 				0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
264 				0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00,
265 				0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF,
266 				0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
267 			},
268 		},
269 		.argb8888_result = {
270 			.dst_pitch = 0,
271 			.expected = {
272 				0xFFFFFFFF, 0xFF000000,
273 				0xFFFF0000, 0xFF00FF00,
274 				0xFF0000FF, 0xFFFF00FF,
275 				0xFFFFFF00, 0xFF00FFFF,
276 			},
277 		},
278 		.xrgb2101010_result = {
279 			.dst_pitch = 0,
280 			.expected = {
281 				0x3FFFFFFF, 0x00000000,
282 				0x3FF00000, 0x000FFC00,
283 				0x000003FF, 0x3FF003FF,
284 				0x3FFFFC00, 0x000FFFFF,
285 			},
286 		},
287 		.argb2101010_result = {
288 			.dst_pitch = 0,
289 			.expected = {
290 				0xFFFFFFFF, 0xC0000000,
291 				0xFFF00000, 0xC00FFC00,
292 				0xC00003FF, 0xFFF003FF,
293 				0xFFFFFC00, 0xC00FFFFF,
294 			},
295 		},
296 	},
297 	{
298 		/* Randomly picked colors. Full buffer within the clip area. */
299 		.name = "destination_pitch",
300 		.pitch = 3 * 4,
301 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
302 		.xrgb8888 = {
303 			0xA10E449C, 0xB1114D05, 0xC1A80303,
304 			0xD16C7073, 0xA20E449C, 0xB2114D05,
305 			0xC2A80303, 0xD26C7073, 0xA30E449C,
306 		},
307 		.gray8_result = {
308 			.dst_pitch = 5,
309 			.expected = {
310 				0x3C, 0x33, 0x34, 0x00, 0x00,
311 				0x6F, 0x3C, 0x33, 0x00, 0x00,
312 				0x34, 0x6F, 0x3C, 0x00, 0x00,
313 			},
314 		},
315 		.rgb332_result = {
316 			.dst_pitch = 5,
317 			.expected = {
318 				0x0A, 0x08, 0xA0, 0x00, 0x00,
319 				0x6D, 0x0A, 0x08, 0x00, 0x00,
320 				0xA0, 0x6D, 0x0A, 0x00, 0x00,
321 			},
322 		},
323 		.rgb565_result = {
324 			.dst_pitch = 10,
325 			.expected = {
326 				0x0A33, 0x1260, 0xA800, 0x0000, 0x0000,
327 				0x6B8E, 0x0A33, 0x1260, 0x0000, 0x0000,
328 				0xA800, 0x6B8E, 0x0A33, 0x0000, 0x0000,
329 			},
330 			.expected_swab = {
331 				0x330A, 0x6012, 0x00A8, 0x0000, 0x0000,
332 				0x8E6B, 0x330A, 0x6012, 0x0000, 0x0000,
333 				0x00A8, 0x8E6B, 0x330A, 0x0000, 0x0000,
334 			},
335 		},
336 		.xrgb1555_result = {
337 			.dst_pitch = 10,
338 			.expected = {
339 				0x0513, 0x0920, 0x5400, 0x0000, 0x0000,
340 				0x35CE, 0x0513, 0x0920, 0x0000, 0x0000,
341 				0x5400, 0x35CE, 0x0513, 0x0000, 0x0000,
342 			},
343 		},
344 		.argb1555_result = {
345 			.dst_pitch = 10,
346 			.expected = {
347 				0x8513, 0x8920, 0xD400, 0x0000, 0x0000,
348 				0xB5CE, 0x8513, 0x8920, 0x0000, 0x0000,
349 				0xD400, 0xB5CE, 0x8513, 0x0000, 0x0000,
350 			},
351 		},
352 		.rgba5551_result = {
353 			.dst_pitch = 10,
354 			.expected = {
355 				0x0A27, 0x1241, 0xA801, 0x0000, 0x0000,
356 				0x6B9D, 0x0A27, 0x1241, 0x0000, 0x0000,
357 				0xA801, 0x6B9D, 0x0A27, 0x0000, 0x0000,
358 			},
359 		},
360 		.rgb888_result = {
361 			.dst_pitch = 15,
362 			.expected = {
363 				0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11, 0x03, 0x03, 0xA8,
364 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 				0x73, 0x70, 0x6C, 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11,
366 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 				0x03, 0x03, 0xA8, 0x73, 0x70, 0x6C, 0x9C, 0x44, 0x0E,
368 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 			},
370 		},
371 		.argb8888_result = {
372 			.dst_pitch = 20,
373 			.expected = {
374 				0xFF0E449C, 0xFF114D05, 0xFFA80303, 0x00000000, 0x00000000,
375 				0xFF6C7073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
376 				0xFFA80303, 0xFF6C7073, 0xFF0E449C, 0x00000000, 0x00000000,
377 			},
378 		},
379 		.xrgb2101010_result = {
380 			.dst_pitch = 20,
381 			.expected = {
382 				0x03844672, 0x0444D414, 0x2A20300C, 0x00000000, 0x00000000,
383 				0x1B1705CD, 0x03844672, 0x0444D414, 0x00000000, 0x00000000,
384 				0x2A20300C, 0x1B1705CD, 0x03844672, 0x00000000, 0x00000000,
385 			},
386 		},
387 		.argb2101010_result = {
388 			.dst_pitch = 20,
389 			.expected = {
390 				0xC3844672, 0xC444D414, 0xEA20300C, 0x00000000, 0x00000000,
391 				0xDB1705CD, 0xC3844672, 0xC444D414, 0x00000000, 0x00000000,
392 				0xEA20300C, 0xDB1705CD, 0xC3844672, 0x00000000, 0x00000000,
393 			},
394 		},
395 	},
396 };
397 
398 /*
399  * conversion_buf_size - Return the destination buffer size required to convert
400  * between formats.
401  * @dst_format: destination buffer pixel format (DRM_FORMAT_*)
402  * @dst_pitch: Number of bytes between two consecutive scanlines within dst
403  * @clip: Clip rectangle area to convert
404  *
405  * Returns:
406  * The size of the destination buffer or negative value on error.
407  */
408 static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
409 				  const struct drm_rect *clip)
410 {
411 	const struct drm_format_info *dst_fi = drm_format_info(dst_format);
412 	unsigned int bpp;
413 
414 	if (!dst_fi)
415 		return -EINVAL;
416 
417 	if (!dst_pitch) {
418 		bpp = drm_format_info_bpp(dst_fi, 0);
419 		dst_pitch = DIV_ROUND_UP(drm_rect_width(clip) * bpp, 8);
420 	}
421 
422 	return dst_pitch * drm_rect_height(clip);
423 }
424 
425 static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size)
426 {
427 	u16 *dst = NULL;
428 	int n;
429 
430 	dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
431 	if (!dst)
432 		return NULL;
433 
434 	for (n = 0; n < buf_size; n++)
435 		dst[n] = le16_to_cpu(buf[n]);
436 
437 	return dst;
438 }
439 
440 static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size)
441 {
442 	u32 *dst = NULL;
443 	int n;
444 
445 	dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
446 	if (!dst)
447 		return NULL;
448 
449 	for (n = 0; n < buf_size; n++)
450 		dst[n] = le32_to_cpu((__force __le32)buf[n]);
451 
452 	return dst;
453 }
454 
455 static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size)
456 {
457 	__le32 *dst = NULL;
458 	int n;
459 
460 	dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
461 	if (!dst)
462 		return NULL;
463 
464 	for (n = 0; n < buf_size; n++)
465 		dst[n] = cpu_to_le32(buf[n]);
466 
467 	return dst;
468 }
469 
470 static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t,
471 				       char *desc)
472 {
473 	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
474 }
475 
476 KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
477 		  convert_xrgb8888_case_desc);
478 
479 static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test)
480 {
481 	const struct convert_xrgb8888_case *params = test->param_value;
482 	const struct convert_to_gray8_result *result = &params->gray8_result;
483 	size_t dst_size;
484 	u8 *buf = NULL;
485 	__le32 *xrgb8888 = NULL;
486 	struct iosys_map dst, src;
487 
488 	struct drm_framebuffer fb = {
489 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
490 		.pitches = { params->pitch, 0, 0 },
491 	};
492 
493 	dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch,
494 				       &params->clip);
495 	KUNIT_ASSERT_GT(test, dst_size, 0);
496 
497 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
498 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
499 	iosys_map_set_vaddr(&dst, buf);
500 
501 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
502 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
503 	iosys_map_set_vaddr(&src, xrgb8888);
504 
505 	drm_fb_xrgb8888_to_gray8(&dst, &result->dst_pitch, &src, &fb, &params->clip);
506 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
507 }
508 
509 static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test)
510 {
511 	const struct convert_xrgb8888_case *params = test->param_value;
512 	const struct convert_to_rgb332_result *result = &params->rgb332_result;
513 	size_t dst_size;
514 	u8 *buf = NULL;
515 	__le32 *xrgb8888 = NULL;
516 	struct iosys_map dst, src;
517 
518 	struct drm_framebuffer fb = {
519 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
520 		.pitches = { params->pitch, 0, 0 },
521 	};
522 
523 	dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch,
524 				       &params->clip);
525 	KUNIT_ASSERT_GT(test, dst_size, 0);
526 
527 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
528 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
529 	iosys_map_set_vaddr(&dst, buf);
530 
531 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
532 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
533 	iosys_map_set_vaddr(&src, xrgb8888);
534 
535 	drm_fb_xrgb8888_to_rgb332(&dst, &result->dst_pitch, &src, &fb, &params->clip);
536 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
537 }
538 
539 static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
540 {
541 	const struct convert_xrgb8888_case *params = test->param_value;
542 	const struct convert_to_rgb565_result *result = &params->rgb565_result;
543 	size_t dst_size;
544 	u16 *buf = NULL;
545 	__le32 *xrgb8888 = NULL;
546 	struct iosys_map dst, src;
547 
548 	struct drm_framebuffer fb = {
549 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
550 		.pitches = { params->pitch, 0, 0 },
551 	};
552 
553 	dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
554 				       &params->clip);
555 	KUNIT_ASSERT_GT(test, dst_size, 0);
556 
557 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
558 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
559 	iosys_map_set_vaddr(&dst, buf);
560 
561 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
562 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
563 	iosys_map_set_vaddr(&src, xrgb8888);
564 
565 	drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, &params->clip, false);
566 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
567 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
568 
569 	buf = dst.vaddr; /* restore original value of buf */
570 	drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, &params->clip, true);
571 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
572 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
573 }
574 
575 static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)
576 {
577 	const struct convert_xrgb8888_case *params = test->param_value;
578 	const struct convert_to_xrgb1555_result *result = &params->xrgb1555_result;
579 	size_t dst_size;
580 	u16 *buf = NULL;
581 	__le32 *xrgb8888 = NULL;
582 	struct iosys_map dst, src;
583 
584 	struct drm_framebuffer fb = {
585 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
586 		.pitches = { params->pitch, 0, 0 },
587 	};
588 
589 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
590 				       &params->clip);
591 	KUNIT_ASSERT_GT(test, dst_size, 0);
592 
593 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
594 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
595 	iosys_map_set_vaddr(&dst, buf);
596 
597 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
598 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
599 	iosys_map_set_vaddr(&src, xrgb8888);
600 
601 	drm_fb_xrgb8888_to_xrgb1555(&dst, &result->dst_pitch, &src, &fb, &params->clip);
602 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
603 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
604 }
605 
606 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
607 {
608 	const struct convert_xrgb8888_case *params = test->param_value;
609 	const struct convert_to_argb1555_result *result = &params->argb1555_result;
610 	size_t dst_size;
611 	u16 *buf = NULL;
612 	__le32 *xrgb8888 = NULL;
613 	struct iosys_map dst, src;
614 
615 	struct drm_framebuffer fb = {
616 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
617 		.pitches = { params->pitch, 0, 0 },
618 	};
619 
620 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
621 				       &params->clip);
622 	KUNIT_ASSERT_GT(test, dst_size, 0);
623 
624 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
625 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
626 	iosys_map_set_vaddr(&dst, buf);
627 
628 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
629 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
630 	iosys_map_set_vaddr(&src, xrgb8888);
631 
632 	drm_fb_xrgb8888_to_argb1555(&dst, &result->dst_pitch, &src, &fb, &params->clip);
633 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
634 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
635 }
636 
637 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
638 {
639 	const struct convert_xrgb8888_case *params = test->param_value;
640 	const struct convert_to_rgba5551_result *result = &params->rgba5551_result;
641 	size_t dst_size;
642 	u16 *buf = NULL;
643 	__le32 *xrgb8888 = NULL;
644 	struct iosys_map dst, src;
645 
646 	struct drm_framebuffer fb = {
647 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
648 		.pitches = { params->pitch, 0, 0 },
649 	};
650 
651 	dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
652 				       &params->clip);
653 	KUNIT_ASSERT_GT(test, dst_size, 0);
654 
655 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
656 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
657 	iosys_map_set_vaddr(&dst, buf);
658 
659 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
660 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
661 	iosys_map_set_vaddr(&src, xrgb8888);
662 
663 	drm_fb_xrgb8888_to_rgba5551(&dst, &result->dst_pitch, &src, &fb, &params->clip);
664 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
665 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
666 }
667 
668 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
669 {
670 	const struct convert_xrgb8888_case *params = test->param_value;
671 	const struct convert_to_rgb888_result *result = &params->rgb888_result;
672 	size_t dst_size;
673 	u8 *buf = NULL;
674 	__le32 *xrgb8888 = NULL;
675 	struct iosys_map dst, src;
676 
677 	struct drm_framebuffer fb = {
678 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
679 		.pitches = { params->pitch, 0, 0 },
680 	};
681 
682 	dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
683 				       &params->clip);
684 	KUNIT_ASSERT_GT(test, dst_size, 0);
685 
686 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
687 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
688 	iosys_map_set_vaddr(&dst, buf);
689 
690 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
691 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
692 	iosys_map_set_vaddr(&src, xrgb8888);
693 
694 	/*
695 	 * RGB888 expected results are already in little-endian
696 	 * order, so there's no need to convert the test output.
697 	 */
698 	drm_fb_xrgb8888_to_rgb888(&dst, &result->dst_pitch, &src, &fb, &params->clip);
699 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
700 }
701 
702 static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)
703 {
704 	const struct convert_xrgb8888_case *params = test->param_value;
705 	const struct convert_to_argb8888_result *result = &params->argb8888_result;
706 	size_t dst_size;
707 	u32 *buf = NULL;
708 	__le32 *xrgb8888 = NULL;
709 	struct iosys_map dst, src;
710 
711 	struct drm_framebuffer fb = {
712 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
713 		.pitches = { params->pitch, 0, 0 },
714 	};
715 
716 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888,
717 				       result->dst_pitch, &params->clip);
718 	KUNIT_ASSERT_GT(test, dst_size, 0);
719 
720 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
721 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
722 	iosys_map_set_vaddr(&dst, buf);
723 
724 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
725 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
726 	iosys_map_set_vaddr(&src, xrgb8888);
727 
728 	drm_fb_xrgb8888_to_argb8888(&dst, &result->dst_pitch, &src, &fb, &params->clip);
729 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
730 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
731 }
732 
733 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
734 {
735 	const struct convert_xrgb8888_case *params = test->param_value;
736 	const struct convert_to_xrgb2101010_result *result = &params->xrgb2101010_result;
737 	size_t dst_size;
738 	u32 *buf = NULL;
739 	__le32 *xrgb8888 = NULL;
740 	struct iosys_map dst, src;
741 
742 	struct drm_framebuffer fb = {
743 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
744 		.pitches = { params->pitch, 0, 0 },
745 	};
746 
747 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
748 				       result->dst_pitch, &params->clip);
749 	KUNIT_ASSERT_GT(test, dst_size, 0);
750 
751 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
752 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
753 	iosys_map_set_vaddr(&dst, buf);
754 
755 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
756 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
757 	iosys_map_set_vaddr(&src, xrgb8888);
758 
759 	drm_fb_xrgb8888_to_xrgb2101010(&dst, &result->dst_pitch, &src, &fb, &params->clip);
760 	buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32));
761 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
762 }
763 
764 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
765 {
766 	const struct convert_xrgb8888_case *params = test->param_value;
767 	const struct convert_to_argb2101010_result *result = &params->argb2101010_result;
768 	size_t dst_size;
769 	u32 *buf = NULL;
770 	__le32 *xrgb8888 = NULL;
771 	struct iosys_map dst, src;
772 
773 	struct drm_framebuffer fb = {
774 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
775 		.pitches = { params->pitch, 0, 0 },
776 	};
777 
778 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010,
779 				       result->dst_pitch, &params->clip);
780 	KUNIT_ASSERT_GT(test, dst_size, 0);
781 
782 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
783 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
784 	iosys_map_set_vaddr(&dst, buf);
785 
786 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
787 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
788 	iosys_map_set_vaddr(&src, xrgb8888);
789 
790 	drm_fb_xrgb8888_to_argb2101010(&dst, &result->dst_pitch, &src, &fb, &params->clip);
791 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
792 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
793 }
794 
795 static struct kunit_case drm_format_helper_test_cases[] = {
796 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
797 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
798 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
799 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params),
800 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params),
801 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params),
802 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
803 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params),
804 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
805 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params),
806 	{}
807 };
808 
809 static struct kunit_suite drm_format_helper_test_suite = {
810 	.name = "drm_format_helper_test",
811 	.test_cases = drm_format_helper_test_cases,
812 };
813 
814 kunit_test_suite(drm_format_helper_test_suite);
815 
816 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
817 MODULE_LICENSE("GPL");
818 MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
819