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 
413 	if (!dst_fi)
414 		return -EINVAL;
415 
416 	if (!dst_pitch)
417 		dst_pitch = drm_rect_width(clip) * dst_fi->cpp[0];
418 
419 	return dst_pitch * drm_rect_height(clip);
420 }
421 
422 static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size)
423 {
424 	u16 *dst = NULL;
425 	int n;
426 
427 	dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
428 	if (!dst)
429 		return NULL;
430 
431 	for (n = 0; n < buf_size; n++)
432 		dst[n] = le16_to_cpu(buf[n]);
433 
434 	return dst;
435 }
436 
437 static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size)
438 {
439 	u32 *dst = NULL;
440 	int n;
441 
442 	dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
443 	if (!dst)
444 		return NULL;
445 
446 	for (n = 0; n < buf_size; n++)
447 		dst[n] = le32_to_cpu((__force __le32)buf[n]);
448 
449 	return dst;
450 }
451 
452 static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size)
453 {
454 	__le32 *dst = NULL;
455 	int n;
456 
457 	dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
458 	if (!dst)
459 		return NULL;
460 
461 	for (n = 0; n < buf_size; n++)
462 		dst[n] = cpu_to_le32(buf[n]);
463 
464 	return dst;
465 }
466 
467 static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t,
468 				       char *desc)
469 {
470 	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
471 }
472 
473 KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
474 		  convert_xrgb8888_case_desc);
475 
476 static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test)
477 {
478 	const struct convert_xrgb8888_case *params = test->param_value;
479 	const struct convert_to_gray8_result *result = &params->gray8_result;
480 	size_t dst_size;
481 	u8 *buf = NULL;
482 	__le32 *xrgb8888 = NULL;
483 	struct iosys_map dst, src;
484 
485 	struct drm_framebuffer fb = {
486 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
487 		.pitches = { params->pitch, 0, 0 },
488 	};
489 
490 	dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch,
491 				       &params->clip);
492 	KUNIT_ASSERT_GT(test, dst_size, 0);
493 
494 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
495 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
496 	iosys_map_set_vaddr(&dst, buf);
497 
498 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
499 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
500 	iosys_map_set_vaddr(&src, xrgb8888);
501 
502 	drm_fb_xrgb8888_to_gray8(&dst, &result->dst_pitch, &src, &fb, &params->clip);
503 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
504 }
505 
506 static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test)
507 {
508 	const struct convert_xrgb8888_case *params = test->param_value;
509 	const struct convert_to_rgb332_result *result = &params->rgb332_result;
510 	size_t dst_size;
511 	u8 *buf = NULL;
512 	__le32 *xrgb8888 = NULL;
513 	struct iosys_map dst, src;
514 
515 	struct drm_framebuffer fb = {
516 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
517 		.pitches = { params->pitch, 0, 0 },
518 	};
519 
520 	dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch,
521 				       &params->clip);
522 	KUNIT_ASSERT_GT(test, dst_size, 0);
523 
524 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
525 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
526 	iosys_map_set_vaddr(&dst, buf);
527 
528 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
529 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
530 	iosys_map_set_vaddr(&src, xrgb8888);
531 
532 	drm_fb_xrgb8888_to_rgb332(&dst, &result->dst_pitch, &src, &fb, &params->clip);
533 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
534 }
535 
536 static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
537 {
538 	const struct convert_xrgb8888_case *params = test->param_value;
539 	const struct convert_to_rgb565_result *result = &params->rgb565_result;
540 	size_t dst_size;
541 	u16 *buf = NULL;
542 	__le32 *xrgb8888 = NULL;
543 	struct iosys_map dst, src;
544 
545 	struct drm_framebuffer fb = {
546 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
547 		.pitches = { params->pitch, 0, 0 },
548 	};
549 
550 	dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
551 				       &params->clip);
552 	KUNIT_ASSERT_GT(test, dst_size, 0);
553 
554 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
555 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
556 	iosys_map_set_vaddr(&dst, buf);
557 
558 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
559 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
560 	iosys_map_set_vaddr(&src, xrgb8888);
561 
562 	drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, &params->clip, false);
563 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
564 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
565 
566 	buf = dst.vaddr; /* restore original value of buf */
567 	drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, &params->clip, true);
568 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
569 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
570 }
571 
572 static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)
573 {
574 	const struct convert_xrgb8888_case *params = test->param_value;
575 	const struct convert_to_xrgb1555_result *result = &params->xrgb1555_result;
576 	size_t dst_size;
577 	u16 *buf = NULL;
578 	__le32 *xrgb8888 = NULL;
579 	struct iosys_map dst, src;
580 
581 	struct drm_framebuffer fb = {
582 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
583 		.pitches = { params->pitch, 0, 0 },
584 	};
585 
586 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
587 				       &params->clip);
588 	KUNIT_ASSERT_GT(test, dst_size, 0);
589 
590 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
591 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
592 	iosys_map_set_vaddr(&dst, buf);
593 
594 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
595 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
596 	iosys_map_set_vaddr(&src, xrgb8888);
597 
598 	drm_fb_xrgb8888_to_xrgb1555(&dst, &result->dst_pitch, &src, &fb, &params->clip);
599 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
600 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
601 }
602 
603 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
604 {
605 	const struct convert_xrgb8888_case *params = test->param_value;
606 	const struct convert_to_argb1555_result *result = &params->argb1555_result;
607 	size_t dst_size;
608 	u16 *buf = NULL;
609 	__le32 *xrgb8888 = NULL;
610 	struct iosys_map dst, src;
611 
612 	struct drm_framebuffer fb = {
613 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
614 		.pitches = { params->pitch, 0, 0 },
615 	};
616 
617 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
618 				       &params->clip);
619 	KUNIT_ASSERT_GT(test, dst_size, 0);
620 
621 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
622 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
623 	iosys_map_set_vaddr(&dst, buf);
624 
625 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
626 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
627 	iosys_map_set_vaddr(&src, xrgb8888);
628 
629 	drm_fb_xrgb8888_to_argb1555(&dst, &result->dst_pitch, &src, &fb, &params->clip);
630 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
631 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
632 }
633 
634 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
635 {
636 	const struct convert_xrgb8888_case *params = test->param_value;
637 	const struct convert_to_rgba5551_result *result = &params->rgba5551_result;
638 	size_t dst_size;
639 	u16 *buf = NULL;
640 	__le32 *xrgb8888 = NULL;
641 	struct iosys_map dst, src;
642 
643 	struct drm_framebuffer fb = {
644 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
645 		.pitches = { params->pitch, 0, 0 },
646 	};
647 
648 	dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
649 				       &params->clip);
650 	KUNIT_ASSERT_GT(test, dst_size, 0);
651 
652 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
653 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
654 	iosys_map_set_vaddr(&dst, buf);
655 
656 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
657 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
658 	iosys_map_set_vaddr(&src, xrgb8888);
659 
660 	drm_fb_xrgb8888_to_rgba5551(&dst, &result->dst_pitch, &src, &fb, &params->clip);
661 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
662 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
663 }
664 
665 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
666 {
667 	const struct convert_xrgb8888_case *params = test->param_value;
668 	const struct convert_to_rgb888_result *result = &params->rgb888_result;
669 	size_t dst_size;
670 	u8 *buf = NULL;
671 	__le32 *xrgb8888 = NULL;
672 	struct iosys_map dst, src;
673 
674 	struct drm_framebuffer fb = {
675 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
676 		.pitches = { params->pitch, 0, 0 },
677 	};
678 
679 	dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
680 				       &params->clip);
681 	KUNIT_ASSERT_GT(test, dst_size, 0);
682 
683 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
684 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
685 	iosys_map_set_vaddr(&dst, buf);
686 
687 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
688 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
689 	iosys_map_set_vaddr(&src, xrgb8888);
690 
691 	/*
692 	 * RGB888 expected results are already in little-endian
693 	 * order, so there's no need to convert the test output.
694 	 */
695 	drm_fb_xrgb8888_to_rgb888(&dst, &result->dst_pitch, &src, &fb, &params->clip);
696 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
697 }
698 
699 static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)
700 {
701 	const struct convert_xrgb8888_case *params = test->param_value;
702 	const struct convert_to_argb8888_result *result = &params->argb8888_result;
703 	size_t dst_size;
704 	u32 *buf = NULL;
705 	__le32 *xrgb8888 = NULL;
706 	struct iosys_map dst, src;
707 
708 	struct drm_framebuffer fb = {
709 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
710 		.pitches = { params->pitch, 0, 0 },
711 	};
712 
713 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888,
714 				       result->dst_pitch, &params->clip);
715 	KUNIT_ASSERT_GT(test, dst_size, 0);
716 
717 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
718 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
719 	iosys_map_set_vaddr(&dst, buf);
720 
721 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
722 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
723 	iosys_map_set_vaddr(&src, xrgb8888);
724 
725 	drm_fb_xrgb8888_to_argb8888(&dst, &result->dst_pitch, &src, &fb, &params->clip);
726 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
727 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
728 }
729 
730 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
731 {
732 	const struct convert_xrgb8888_case *params = test->param_value;
733 	const struct convert_to_xrgb2101010_result *result = &params->xrgb2101010_result;
734 	size_t dst_size;
735 	u32 *buf = NULL;
736 	__le32 *xrgb8888 = NULL;
737 	struct iosys_map dst, src;
738 
739 	struct drm_framebuffer fb = {
740 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
741 		.pitches = { params->pitch, 0, 0 },
742 	};
743 
744 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
745 				       result->dst_pitch, &params->clip);
746 	KUNIT_ASSERT_GT(test, dst_size, 0);
747 
748 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
749 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
750 	iosys_map_set_vaddr(&dst, buf);
751 
752 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
753 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
754 	iosys_map_set_vaddr(&src, xrgb8888);
755 
756 	drm_fb_xrgb8888_to_xrgb2101010(&dst, &result->dst_pitch, &src, &fb, &params->clip);
757 	buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32));
758 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
759 }
760 
761 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
762 {
763 	const struct convert_xrgb8888_case *params = test->param_value;
764 	const struct convert_to_argb2101010_result *result = &params->argb2101010_result;
765 	size_t dst_size;
766 	u32 *buf = NULL;
767 	__le32 *xrgb8888 = NULL;
768 	struct iosys_map dst, src;
769 
770 	struct drm_framebuffer fb = {
771 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
772 		.pitches = { params->pitch, 0, 0 },
773 	};
774 
775 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010,
776 				       result->dst_pitch, &params->clip);
777 	KUNIT_ASSERT_GT(test, dst_size, 0);
778 
779 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
780 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
781 	iosys_map_set_vaddr(&dst, buf);
782 
783 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
784 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
785 	iosys_map_set_vaddr(&src, xrgb8888);
786 
787 	drm_fb_xrgb8888_to_argb2101010(&dst, &result->dst_pitch, &src, &fb, &params->clip);
788 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
789 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
790 }
791 
792 static struct kunit_case drm_format_helper_test_cases[] = {
793 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
794 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
795 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
796 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params),
797 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params),
798 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params),
799 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
800 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params),
801 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
802 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params),
803 	{}
804 };
805 
806 static struct kunit_suite drm_format_helper_test_suite = {
807 	.name = "drm_format_helper_test",
808 	.test_cases = drm_format_helper_test_cases,
809 };
810 
811 kunit_test_suite(drm_format_helper_test_suite);
812 
813 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
814 MODULE_LICENSE("GPL");
815 MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
816