xref: /linux/drivers/gpu/drm/tests/drm_format_helper_test.c (revision 989fe6771266bdb82a815d78802c5aa7c918fdfd)
1 // SPDX-License-Identifier: GPL-2.0+
2 
3 #include <kunit/test.h>
4 
5 #include <drm/drm_device.h>
6 #include <drm/drm_drv.h>
7 #include <drm/drm_file.h>
8 #include <drm/drm_format_helper.h>
9 #include <drm/drm_fourcc.h>
10 #include <drm/drm_framebuffer.h>
11 #include <drm/drm_gem_framebuffer_helper.h>
12 #include <drm/drm_kunit_helpers.h>
13 #include <drm/drm_mode.h>
14 #include <drm/drm_print.h>
15 #include <drm/drm_rect.h>
16 
17 #include "../drm_crtc_internal.h"
18 
19 #define TEST_BUF_SIZE 50
20 
21 #define TEST_USE_DEFAULT_PITCH 0
22 
23 static unsigned char fmtcnv_state_mem[PAGE_SIZE];
24 static struct drm_format_conv_state fmtcnv_state =
25 	DRM_FORMAT_CONV_STATE_INIT_PREALLOCATED(fmtcnv_state_mem, sizeof(fmtcnv_state_mem));
26 
27 struct convert_to_gray8_result {
28 	unsigned int dst_pitch;
29 	const u8 expected[TEST_BUF_SIZE];
30 };
31 
32 struct convert_to_rgb332_result {
33 	unsigned int dst_pitch;
34 	const u8 expected[TEST_BUF_SIZE];
35 };
36 
37 struct convert_to_rgb565_result {
38 	unsigned int dst_pitch;
39 	const u16 expected[TEST_BUF_SIZE];
40 	const u16 expected_swab[TEST_BUF_SIZE];
41 };
42 
43 struct convert_to_xrgb1555_result {
44 	unsigned int dst_pitch;
45 	const u16 expected[TEST_BUF_SIZE];
46 };
47 
48 struct convert_to_argb1555_result {
49 	unsigned int dst_pitch;
50 	const u16 expected[TEST_BUF_SIZE];
51 };
52 
53 struct convert_to_rgba5551_result {
54 	unsigned int dst_pitch;
55 	const u16 expected[TEST_BUF_SIZE];
56 };
57 
58 struct convert_to_rgb888_result {
59 	unsigned int dst_pitch;
60 	const u8 expected[TEST_BUF_SIZE];
61 };
62 
63 struct convert_to_bgr888_result {
64 	unsigned int dst_pitch;
65 	const u8 expected[TEST_BUF_SIZE];
66 };
67 
68 struct convert_to_argb8888_result {
69 	unsigned int dst_pitch;
70 	const u32 expected[TEST_BUF_SIZE];
71 };
72 
73 struct convert_to_xrgb2101010_result {
74 	unsigned int dst_pitch;
75 	const u32 expected[TEST_BUF_SIZE];
76 };
77 
78 struct convert_to_argb2101010_result {
79 	unsigned int dst_pitch;
80 	const u32 expected[TEST_BUF_SIZE];
81 };
82 
83 struct convert_to_mono_result {
84 	unsigned int dst_pitch;
85 	const u8 expected[TEST_BUF_SIZE];
86 };
87 
88 struct fb_swab_result {
89 	unsigned int dst_pitch;
90 	const u32 expected[TEST_BUF_SIZE];
91 };
92 
93 struct convert_to_xbgr8888_result {
94 	unsigned int dst_pitch;
95 	const u32 expected[TEST_BUF_SIZE];
96 };
97 
98 struct convert_to_abgr8888_result {
99 	unsigned int dst_pitch;
100 	const u32 expected[TEST_BUF_SIZE];
101 };
102 
103 struct convert_xrgb8888_case {
104 	const char *name;
105 	unsigned int pitch;
106 	struct drm_rect clip;
107 	const u32 xrgb8888[TEST_BUF_SIZE];
108 	struct convert_to_gray8_result gray8_result;
109 	struct convert_to_rgb332_result rgb332_result;
110 	struct convert_to_rgb565_result rgb565_result;
111 	struct convert_to_xrgb1555_result xrgb1555_result;
112 	struct convert_to_argb1555_result argb1555_result;
113 	struct convert_to_rgba5551_result rgba5551_result;
114 	struct convert_to_rgb888_result rgb888_result;
115 	struct convert_to_bgr888_result bgr888_result;
116 	struct convert_to_argb8888_result argb8888_result;
117 	struct convert_to_xrgb2101010_result xrgb2101010_result;
118 	struct convert_to_argb2101010_result argb2101010_result;
119 	struct convert_to_mono_result mono_result;
120 	struct fb_swab_result swab_result;
121 	struct convert_to_xbgr8888_result xbgr8888_result;
122 	struct convert_to_abgr8888_result abgr8888_result;
123 };
124 
125 static struct convert_xrgb8888_case convert_xrgb8888_cases[] = {
126 	{
127 		.name = "single_pixel_source_buffer",
128 		.pitch = 1 * 4,
129 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
130 		.xrgb8888 = { 0x01FF0000 },
131 		.gray8_result = {
132 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
133 			.expected = { 0x4C },
134 		},
135 		.rgb332_result = {
136 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
137 			.expected = { 0xE0 },
138 		},
139 		.rgb565_result = {
140 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
141 			.expected = { 0xF800 },
142 			.expected_swab = { 0x00F8 },
143 		},
144 		.xrgb1555_result = {
145 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
146 			.expected = { 0x7C00 },
147 		},
148 		.argb1555_result = {
149 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
150 			.expected = { 0xFC00 },
151 		},
152 		.rgba5551_result = {
153 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
154 			.expected = { 0xF801 },
155 		},
156 		.rgb888_result = {
157 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
158 			.expected = { 0x00, 0x00, 0xFF },
159 		},
160 		.bgr888_result = {
161 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
162 			.expected = { 0xFF, 0x00, 0x00 },
163 		},
164 		.argb8888_result = {
165 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
166 			.expected = { 0xFFFF0000 },
167 		},
168 		.xrgb2101010_result = {
169 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
170 			.expected = { 0x3FF00000 },
171 		},
172 		.argb2101010_result = {
173 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
174 			.expected = { 0xFFF00000 },
175 		},
176 		.mono_result = {
177 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
178 			.expected = { 0b0 },
179 		},
180 		.swab_result = {
181 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
182 			.expected = { 0x0000FF01 },
183 		},
184 		.xbgr8888_result = {
185 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
186 			.expected = { 0x010000FF },
187 		},
188 		.abgr8888_result = {
189 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
190 			.expected = { 0xFF0000FF },
191 		},
192 	},
193 	{
194 		.name = "single_pixel_clip_rectangle",
195 		.pitch = 2 * 4,
196 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
197 		.xrgb8888 = {
198 			0x00000000, 0x00000000,
199 			0x00000000, 0x10FF0000,
200 		},
201 		.gray8_result = {
202 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
203 			.expected = { 0x4C },
204 		},
205 		.rgb332_result = {
206 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
207 			.expected = { 0xE0 },
208 		},
209 		.rgb565_result = {
210 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
211 			.expected = { 0xF800 },
212 			.expected_swab = { 0x00F8 },
213 		},
214 		.xrgb1555_result = {
215 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
216 			.expected = { 0x7C00 },
217 		},
218 		.argb1555_result = {
219 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
220 			.expected = { 0xFC00 },
221 		},
222 		.rgba5551_result = {
223 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
224 			.expected = { 0xF801 },
225 		},
226 		.rgb888_result = {
227 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
228 			.expected = { 0x00, 0x00, 0xFF },
229 		},
230 		.bgr888_result = {
231 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
232 			.expected = { 0xFF, 0x00, 0x00 },
233 		},
234 		.argb8888_result = {
235 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
236 			.expected = { 0xFFFF0000 },
237 		},
238 		.xrgb2101010_result = {
239 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
240 			.expected = { 0x3FF00000 },
241 		},
242 		.argb2101010_result = {
243 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
244 			.expected = { 0xFFF00000 },
245 		},
246 		.mono_result = {
247 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
248 			.expected = { 0b0 },
249 		},
250 		.swab_result = {
251 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
252 			.expected = { 0x0000FF10 },
253 		},
254 		.xbgr8888_result = {
255 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
256 			.expected = { 0x100000FF },
257 		},
258 		.abgr8888_result = {
259 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
260 			.expected = { 0xFF0000FF },
261 		},
262 	},
263 	{
264 		/* Well known colors: White, black, red, green, blue, magenta,
265 		 * yellow and cyan. Different values for the X in XRGB8888 to
266 		 * make sure it is ignored. Partial clip area.
267 		 */
268 		.name = "well_known_colors",
269 		.pitch = 4 * 4,
270 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
271 		.xrgb8888 = {
272 			0x00000000, 0x00000000, 0x00000000, 0x00000000,
273 			0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
274 			0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
275 			0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
276 			0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
277 		},
278 		.gray8_result = {
279 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
280 			.expected = {
281 				0xFF, 0x00,
282 				0x4C, 0x95,
283 				0x1C, 0x69,
284 				0xE2, 0xB2,
285 			},
286 		},
287 		.rgb332_result = {
288 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
289 			.expected = {
290 				0xFF, 0x00,
291 				0xE0, 0x1C,
292 				0x03, 0xE3,
293 				0xFC, 0x1F,
294 			},
295 		},
296 		.rgb565_result = {
297 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
298 			.expected = {
299 				0xFFFF, 0x0000,
300 				0xF800, 0x07E0,
301 				0x001F, 0xF81F,
302 				0xFFE0, 0x07FF,
303 			},
304 			.expected_swab = {
305 				0xFFFF, 0x0000,
306 				0x00F8, 0xE007,
307 				0x1F00, 0x1FF8,
308 				0xE0FF, 0xFF07,
309 			},
310 		},
311 		.xrgb1555_result = {
312 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
313 			.expected = {
314 				0x7FFF, 0x0000,
315 				0x7C00, 0x03E0,
316 				0x001F, 0x7C1F,
317 				0x7FE0, 0x03FF,
318 			},
319 		},
320 		.argb1555_result = {
321 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
322 			.expected = {
323 				0xFFFF, 0x8000,
324 				0xFC00, 0x83E0,
325 				0x801F, 0xFC1F,
326 				0xFFE0, 0x83FF,
327 			},
328 		},
329 		.rgba5551_result = {
330 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
331 			.expected = {
332 				0xFFFF, 0x0001,
333 				0xF801, 0x07C1,
334 				0x003F, 0xF83F,
335 				0xFFC1, 0x07FF,
336 			},
337 		},
338 		.rgb888_result = {
339 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
340 			.expected = {
341 				0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
342 				0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00,
343 				0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF,
344 				0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
345 			},
346 		},
347 		.bgr888_result = {
348 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
349 			.expected = {
350 				0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
351 				0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00,
352 				0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF,
353 				0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
354 			},
355 		},
356 		.argb8888_result = {
357 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
358 			.expected = {
359 				0xFFFFFFFF, 0xFF000000,
360 				0xFFFF0000, 0xFF00FF00,
361 				0xFF0000FF, 0xFFFF00FF,
362 				0xFFFFFF00, 0xFF00FFFF,
363 			},
364 		},
365 		.xrgb2101010_result = {
366 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
367 			.expected = {
368 				0x3FFFFFFF, 0x00000000,
369 				0x3FF00000, 0x000FFC00,
370 				0x000003FF, 0x3FF003FF,
371 				0x3FFFFC00, 0x000FFFFF,
372 			},
373 		},
374 		.argb2101010_result = {
375 			.dst_pitch = TEST_USE_DEFAULT_PITCH,
376 			.expected = {
377 				0xFFFFFFFF, 0xC0000000,
378 				0xFFF00000, 0xC00FFC00,
379 				0xC00003FF, 0xFFF003FF,
380 				0xFFFFFC00, 0xC00FFFFF,
381 			},
382 		},
383 		.mono_result = {
384 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
385 			.expected = {
386 				0b01,
387 				0b10,
388 				0b00,
389 				0b11,
390 			},
391 		},
392 		.swab_result = {
393 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
394 			.expected = {
395 				0xFFFFFF11, 0x00000022,
396 				0x0000FF33, 0x00FF0044,
397 				0xFF000055, 0xFF00FF66,
398 				0x00FFFF77, 0xFFFF0088,
399 			},
400 		},
401 		.xbgr8888_result = {
402 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
403 			.expected = {
404 				0x11FFFFFF, 0x22000000,
405 				0x330000FF, 0x4400FF00,
406 				0x55FF0000, 0x66FF00FF,
407 				0x7700FFFF, 0x88FFFF00,
408 			},
409 		},
410 		.abgr8888_result = {
411 			.dst_pitch =  TEST_USE_DEFAULT_PITCH,
412 			.expected = {
413 				0xFFFFFFFF, 0xFF000000,
414 				0xFF0000FF, 0xFF00FF00,
415 				0xFFFF0000, 0xFFFF00FF,
416 				0xFF00FFFF, 0xFFFFFF00,
417 			},
418 		},
419 	},
420 	{
421 		/* Randomly picked colors. Full buffer within the clip area. */
422 		.name = "destination_pitch",
423 		.pitch = 3 * 4,
424 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
425 		.xrgb8888 = {
426 			0xA10E449C, 0xB1114D05, 0xC1A8F303,
427 			0xD16CF073, 0xA20E449C, 0xB2114D05,
428 			0xC2A80303, 0xD26CF073, 0xA30E449C,
429 		},
430 		.gray8_result = {
431 			.dst_pitch = 5,
432 			.expected = {
433 				0x3D, 0x32, 0xC1, 0x00, 0x00,
434 				0xBA, 0x3D, 0x32, 0x00, 0x00,
435 				0x34, 0xBA, 0x3D, 0x00, 0x00,
436 			},
437 		},
438 		.rgb332_result = {
439 			.dst_pitch = 5,
440 			.expected = {
441 				0x0A, 0x08, 0xBC, 0x00, 0x00,
442 				0x7D, 0x0A, 0x08, 0x00, 0x00,
443 				0xA0, 0x7D, 0x0A, 0x00, 0x00,
444 			},
445 		},
446 		.rgb565_result = {
447 			.dst_pitch = 10,
448 			.expected = {
449 				0x0A33, 0x1260, 0xAF80, 0x0000, 0x0000,
450 				0x6F8E, 0x0A33, 0x1260, 0x0000, 0x0000,
451 				0xA800, 0x6F8E, 0x0A33, 0x0000, 0x0000,
452 			},
453 			.expected_swab = {
454 				0x330A, 0x6012, 0x80AF, 0x0000, 0x0000,
455 				0x8E6F, 0x330A, 0x6012, 0x0000, 0x0000,
456 				0x00A8, 0x8E6F, 0x330A, 0x0000, 0x0000,
457 			},
458 		},
459 		.xrgb1555_result = {
460 			.dst_pitch = 10,
461 			.expected = {
462 				0x0513, 0x0920, 0x57C0, 0x0000, 0x0000,
463 				0x37CE, 0x0513, 0x0920, 0x0000, 0x0000,
464 				0x5400, 0x37CE, 0x0513, 0x0000, 0x0000,
465 			},
466 		},
467 		.argb1555_result = {
468 			.dst_pitch = 10,
469 			.expected = {
470 				0x8513, 0x8920, 0xD7C0, 0x0000, 0x0000,
471 				0xB7CE, 0x8513, 0x8920, 0x0000, 0x0000,
472 				0xD400, 0xB7CE, 0x8513, 0x0000, 0x0000,
473 			},
474 		},
475 		.rgba5551_result = {
476 			.dst_pitch = 10,
477 			.expected = {
478 				0x0A27, 0x1241, 0xAF81, 0x0000, 0x0000,
479 				0x6F9D, 0x0A27, 0x1241, 0x0000, 0x0000,
480 				0xA801, 0x6F9D, 0x0A27, 0x0000, 0x0000,
481 			},
482 		},
483 		.rgb888_result = {
484 			.dst_pitch = 15,
485 			.expected = {
486 				0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11, 0x03, 0xF3, 0xA8,
487 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 				0x73, 0xF0, 0x6C, 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11,
489 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 				0x03, 0x03, 0xA8, 0x73, 0xF0, 0x6C, 0x9C, 0x44, 0x0E,
491 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 			},
493 		},
494 		.bgr888_result = {
495 			.dst_pitch = 15,
496 			.expected = {
497 				0x0E, 0x44, 0x9C, 0x11, 0x4D, 0x05, 0xA8, 0xF3, 0x03,
498 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 				0x6C, 0xF0, 0x73, 0x0E, 0x44, 0x9C, 0x11, 0x4D, 0x05,
500 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 				0xA8, 0x03, 0x03, 0x6C, 0xF0, 0x73, 0x0E, 0x44, 0x9C,
502 				0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503 			},
504 		},
505 		.argb8888_result = {
506 			.dst_pitch = 20,
507 			.expected = {
508 				0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
509 				0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
510 				0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
511 			},
512 		},
513 		.xrgb2101010_result = {
514 			.dst_pitch = 20,
515 			.expected = {
516 				0x03844672, 0x0444D414, 0x2A2F3C0C, 0x00000000, 0x00000000,
517 				0x1B1F0DCD, 0x03844672, 0x0444D414, 0x00000000, 0x00000000,
518 				0x2A20300C, 0x1B1F0DCD, 0x03844672, 0x00000000, 0x00000000,
519 			},
520 		},
521 		.argb2101010_result = {
522 			.dst_pitch = 20,
523 			.expected = {
524 				0xC3844672, 0xC444D414, 0xEA2F3C0C, 0x00000000, 0x00000000,
525 				0xDB1F0DCD, 0xC3844672, 0xC444D414, 0x00000000, 0x00000000,
526 				0xEA20300C, 0xDB1F0DCD, 0xC3844672, 0x00000000, 0x00000000,
527 			},
528 		},
529 		.mono_result = {
530 			.dst_pitch = 2,
531 			.expected = {
532 				0b100, 0b000,
533 				0b001, 0b000,
534 				0b010, 0b000,
535 			},
536 		},
537 		.swab_result = {
538 			.dst_pitch =  20,
539 			.expected = {
540 				0x9C440EA1, 0x054D11B1, 0x03F3A8C1, 0x00000000, 0x00000000,
541 				0x73F06CD1, 0x9C440EA2, 0x054D11B2, 0x00000000, 0x00000000,
542 				0x0303A8C2, 0x73F06CD2, 0x9C440EA3, 0x00000000, 0x00000000,
543 			},
544 		},
545 		.xbgr8888_result = {
546 			.dst_pitch =  20,
547 			.expected = {
548 				0xA19C440E, 0xB1054D11, 0xC103F3A8, 0x00000000, 0x00000000,
549 				0xD173F06C, 0xA29C440E, 0xB2054D11, 0x00000000, 0x00000000,
550 				0xC20303A8, 0xD273F06C, 0xA39C440E, 0x00000000, 0x00000000,
551 			},
552 		},
553 		.abgr8888_result = {
554 			.dst_pitch =  20,
555 			.expected = {
556 				0xFF9C440E, 0xFF054D11, 0xFF03F3A8, 0x00000000, 0x00000000,
557 				0xFF73F06C, 0xFF9C440E, 0xFF054D11, 0x00000000, 0x00000000,
558 				0xFF0303A8, 0xFF73F06C, 0xFF9C440E, 0x00000000, 0x00000000,
559 			},
560 		},
561 	},
562 };
563 
564 /*
565  * conversion_buf_size - Return the destination buffer size required to convert
566  * between formats.
567  * @dst_format: destination buffer pixel format (DRM_FORMAT_*)
568  * @dst_pitch: Number of bytes between two consecutive scanlines within dst
569  * @clip: Clip rectangle area to convert
570  *
571  * Returns:
572  * The size of the destination buffer or negative value on error.
573  */
574 static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch,
575 				  const struct drm_rect *clip, int plane)
576 {
577 	const struct drm_format_info *dst_fi = drm_format_info(dst_format);
578 
579 	if (!dst_fi)
580 		return -EINVAL;
581 
582 	if (!dst_pitch)
583 		dst_pitch = drm_format_info_min_pitch(dst_fi, plane, drm_rect_width(clip));
584 
585 	return dst_pitch * drm_rect_height(clip);
586 }
587 
588 static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size)
589 {
590 	u16 *dst = NULL;
591 	int n;
592 
593 	dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
594 	if (!dst)
595 		return NULL;
596 
597 	for (n = 0; n < buf_size; n++)
598 		dst[n] = le16_to_cpu(buf[n]);
599 
600 	return dst;
601 }
602 
603 static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size)
604 {
605 	u32 *dst = NULL;
606 	int n;
607 
608 	dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
609 	if (!dst)
610 		return NULL;
611 
612 	for (n = 0; n < buf_size; n++)
613 		dst[n] = le32_to_cpu((__force __le32)buf[n]);
614 
615 	return dst;
616 }
617 
618 static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size)
619 {
620 	__le32 *dst = NULL;
621 	int n;
622 
623 	dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL);
624 	if (!dst)
625 		return NULL;
626 
627 	for (n = 0; n < buf_size; n++)
628 		dst[n] = cpu_to_le32(buf[n]);
629 
630 	return dst;
631 }
632 
633 static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t,
634 				       char *desc)
635 {
636 	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
637 }
638 
639 KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
640 		  convert_xrgb8888_case_desc);
641 
642 static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test)
643 {
644 	const struct convert_xrgb8888_case *params = test->param_value;
645 	const struct convert_to_gray8_result *result = &params->gray8_result;
646 	size_t dst_size;
647 	u8 *buf = NULL;
648 	__le32 *xrgb8888 = NULL;
649 	struct iosys_map dst, src;
650 
651 	struct drm_framebuffer fb = {
652 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
653 		.pitches = { params->pitch, 0, 0 },
654 	};
655 
656 	dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch,
657 				       &params->clip, 0);
658 	KUNIT_ASSERT_GT(test, dst_size, 0);
659 
660 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
661 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
662 	iosys_map_set_vaddr(&dst, buf);
663 
664 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
665 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
666 	iosys_map_set_vaddr(&src, xrgb8888);
667 
668 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
669 		NULL : &result->dst_pitch;
670 
671 	drm_fb_xrgb8888_to_gray8(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
672 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
673 }
674 
675 static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test)
676 {
677 	const struct convert_xrgb8888_case *params = test->param_value;
678 	const struct convert_to_rgb332_result *result = &params->rgb332_result;
679 	size_t dst_size;
680 	u8 *buf = NULL;
681 	__le32 *xrgb8888 = NULL;
682 	struct iosys_map dst, src;
683 
684 	struct drm_framebuffer fb = {
685 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
686 		.pitches = { params->pitch, 0, 0 },
687 	};
688 
689 	dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch,
690 				       &params->clip, 0);
691 	KUNIT_ASSERT_GT(test, dst_size, 0);
692 
693 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
694 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
695 	iosys_map_set_vaddr(&dst, buf);
696 
697 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
698 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
699 	iosys_map_set_vaddr(&src, xrgb8888);
700 
701 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
702 		NULL : &result->dst_pitch;
703 
704 	drm_fb_xrgb8888_to_rgb332(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
705 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
706 }
707 
708 static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test)
709 {
710 	const struct convert_xrgb8888_case *params = test->param_value;
711 	const struct convert_to_rgb565_result *result = &params->rgb565_result;
712 	size_t dst_size;
713 	u16 *buf = NULL;
714 	__le32 *xrgb8888 = NULL;
715 	struct iosys_map dst, src;
716 
717 	struct drm_framebuffer fb = {
718 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
719 		.pitches = { params->pitch, 0, 0 },
720 	};
721 
722 	dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch,
723 				       &params->clip, 0);
724 	KUNIT_ASSERT_GT(test, dst_size, 0);
725 
726 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
727 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
728 	iosys_map_set_vaddr(&dst, buf);
729 
730 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
731 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
732 	iosys_map_set_vaddr(&src, xrgb8888);
733 
734 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
735 		NULL : &result->dst_pitch;
736 
737 	drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, &params->clip,
738 				  &fmtcnv_state);
739 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
740 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
741 
742 	buf = dst.vaddr; /* restore original value of buf */
743 	drm_fb_xrgb8888_to_rgb565be(&dst, &result->dst_pitch, &src, &fb, &params->clip,
744 				    &fmtcnv_state);
745 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
746 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size);
747 
748 	buf = dst.vaddr;
749 	memset(buf, 0, dst_size);
750 
751 	drm_fb_xrgb8888_to_rgb565(&dst, dst_pitch, &src, &fb, &params->clip,
752 				  &fmtcnv_state);
753 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
754 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
755 }
756 
757 static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)
758 {
759 	const struct convert_xrgb8888_case *params = test->param_value;
760 	const struct convert_to_xrgb1555_result *result = &params->xrgb1555_result;
761 	size_t dst_size;
762 	u16 *buf = NULL;
763 	__le32 *xrgb8888 = NULL;
764 	struct iosys_map dst, src;
765 
766 	struct drm_framebuffer fb = {
767 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
768 		.pitches = { params->pitch, 0, 0 },
769 	};
770 
771 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
772 				       &params->clip, 0);
773 	KUNIT_ASSERT_GT(test, dst_size, 0);
774 
775 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
776 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
777 	iosys_map_set_vaddr(&dst, buf);
778 
779 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
780 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
781 	iosys_map_set_vaddr(&src, xrgb8888);
782 
783 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
784 		NULL : &result->dst_pitch;
785 
786 	drm_fb_xrgb8888_to_xrgb1555(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
787 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
788 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
789 
790 	buf = dst.vaddr; /* restore original value of buf */
791 	memset(buf, 0, dst_size);
792 
793 	drm_fb_xrgb8888_to_xrgb1555(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
794 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
795 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
796 }
797 
798 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
799 {
800 	const struct convert_xrgb8888_case *params = test->param_value;
801 	const struct convert_to_argb1555_result *result = &params->argb1555_result;
802 	size_t dst_size;
803 	u16 *buf = NULL;
804 	__le32 *xrgb8888 = NULL;
805 	struct iosys_map dst, src;
806 
807 	struct drm_framebuffer fb = {
808 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
809 		.pitches = { params->pitch, 0, 0 },
810 	};
811 
812 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
813 				       &params->clip, 0);
814 	KUNIT_ASSERT_GT(test, dst_size, 0);
815 
816 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
817 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
818 	iosys_map_set_vaddr(&dst, buf);
819 
820 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
821 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
822 	iosys_map_set_vaddr(&src, xrgb8888);
823 
824 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
825 		NULL : &result->dst_pitch;
826 
827 	drm_fb_xrgb8888_to_argb1555(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
828 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
829 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
830 
831 	buf = dst.vaddr; /* restore original value of buf */
832 	memset(buf, 0, dst_size);
833 
834 	drm_fb_xrgb8888_to_argb1555(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
835 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
836 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
837 }
838 
839 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
840 {
841 	const struct convert_xrgb8888_case *params = test->param_value;
842 	const struct convert_to_rgba5551_result *result = &params->rgba5551_result;
843 	size_t dst_size;
844 	u16 *buf = NULL;
845 	__le32 *xrgb8888 = NULL;
846 	struct iosys_map dst, src;
847 
848 	struct drm_framebuffer fb = {
849 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
850 		.pitches = { params->pitch, 0, 0 },
851 	};
852 
853 	dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
854 				       &params->clip, 0);
855 	KUNIT_ASSERT_GT(test, dst_size, 0);
856 
857 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
858 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
859 	iosys_map_set_vaddr(&dst, buf);
860 
861 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
862 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
863 	iosys_map_set_vaddr(&src, xrgb8888);
864 
865 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
866 		NULL : &result->dst_pitch;
867 
868 	drm_fb_xrgb8888_to_rgba5551(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
869 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
870 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
871 
872 	buf = dst.vaddr; /* restore original value of buf */
873 	memset(buf, 0, dst_size);
874 
875 	drm_fb_xrgb8888_to_rgba5551(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
876 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
877 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
878 }
879 
880 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
881 {
882 	const struct convert_xrgb8888_case *params = test->param_value;
883 	const struct convert_to_rgb888_result *result = &params->rgb888_result;
884 	size_t dst_size;
885 	u8 *buf = NULL;
886 	__le32 *xrgb8888 = NULL;
887 	struct iosys_map dst, src;
888 
889 	struct drm_framebuffer fb = {
890 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
891 		.pitches = { params->pitch, 0, 0 },
892 	};
893 
894 	dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
895 				       &params->clip, 0);
896 	KUNIT_ASSERT_GT(test, dst_size, 0);
897 
898 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
899 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
900 	iosys_map_set_vaddr(&dst, buf);
901 
902 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
903 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
904 	iosys_map_set_vaddr(&src, xrgb8888);
905 
906 	/*
907 	 * RGB888 expected results are already in little-endian
908 	 * order, so there's no need to convert the test output.
909 	 */
910 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
911 		NULL : &result->dst_pitch;
912 
913 	drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
914 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
915 
916 	buf = dst.vaddr; /* restore original value of buf */
917 	memset(buf, 0, dst_size);
918 
919 	drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
920 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
921 }
922 
923 static void drm_test_fb_xrgb8888_to_bgr888(struct kunit *test)
924 {
925 	const struct convert_xrgb8888_case *params = test->param_value;
926 	const struct convert_to_bgr888_result *result = &params->bgr888_result;
927 	size_t dst_size;
928 	u8 *buf = NULL;
929 	__le32 *xrgb8888 = NULL;
930 	struct iosys_map dst, src;
931 
932 	struct drm_framebuffer fb = {
933 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
934 		.pitches = { params->pitch, 0, 0 },
935 	};
936 
937 	dst_size = conversion_buf_size(DRM_FORMAT_BGR888, result->dst_pitch,
938 				       &params->clip, 0);
939 	KUNIT_ASSERT_GT(test, dst_size, 0);
940 
941 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
942 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
943 	iosys_map_set_vaddr(&dst, buf);
944 
945 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
946 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
947 	iosys_map_set_vaddr(&src, xrgb8888);
948 
949 	/*
950 	 * BGR888 expected results are already in little-endian
951 	 * order, so there's no need to convert the test output.
952 	 */
953 	drm_fb_xrgb8888_to_bgr888(&dst, &result->dst_pitch, &src, &fb, &params->clip,
954 				  &fmtcnv_state);
955 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
956 
957 	buf = dst.vaddr; /* restore original value of buf */
958 	memset(buf, 0, dst_size);
959 
960 	drm_fb_xrgb8888_to_bgr888(&dst, &result->dst_pitch, &src, &fb, &params->clip,
961 				  &fmtcnv_state);
962 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
963 }
964 
965 static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)
966 {
967 	const struct convert_xrgb8888_case *params = test->param_value;
968 	const struct convert_to_argb8888_result *result = &params->argb8888_result;
969 	size_t dst_size;
970 	u32 *buf = NULL;
971 	__le32 *xrgb8888 = NULL;
972 	struct iosys_map dst, src;
973 
974 	struct drm_framebuffer fb = {
975 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
976 		.pitches = { params->pitch, 0, 0 },
977 	};
978 
979 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888,
980 				       result->dst_pitch, &params->clip, 0);
981 	KUNIT_ASSERT_GT(test, dst_size, 0);
982 
983 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
984 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
985 	iosys_map_set_vaddr(&dst, buf);
986 
987 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
988 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
989 	iosys_map_set_vaddr(&src, xrgb8888);
990 
991 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
992 		NULL : &result->dst_pitch;
993 
994 	drm_fb_xrgb8888_to_argb8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
995 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
996 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
997 
998 	buf = dst.vaddr; /* restore original value of buf */
999 	memset(buf, 0, dst_size);
1000 
1001 	drm_fb_xrgb8888_to_argb8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1002 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1003 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1004 }
1005 
1006 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
1007 {
1008 	const struct convert_xrgb8888_case *params = test->param_value;
1009 	const struct convert_to_xrgb2101010_result *result = &params->xrgb2101010_result;
1010 	size_t dst_size;
1011 	u32 *buf = NULL;
1012 	__le32 *xrgb8888 = NULL;
1013 	struct iosys_map dst, src;
1014 
1015 	struct drm_framebuffer fb = {
1016 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1017 		.pitches = { params->pitch, 0, 0 },
1018 	};
1019 
1020 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
1021 				       result->dst_pitch, &params->clip, 0);
1022 	KUNIT_ASSERT_GT(test, dst_size, 0);
1023 
1024 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1025 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1026 	iosys_map_set_vaddr(&dst, buf);
1027 
1028 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1029 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1030 	iosys_map_set_vaddr(&src, xrgb8888);
1031 
1032 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1033 		NULL : &result->dst_pitch;
1034 
1035 	drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1036 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1037 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1038 
1039 	buf = dst.vaddr; /* restore original value of buf */
1040 	memset(buf, 0, dst_size);
1041 
1042 	drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1043 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1044 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1045 }
1046 
1047 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
1048 {
1049 	const struct convert_xrgb8888_case *params = test->param_value;
1050 	const struct convert_to_argb2101010_result *result = &params->argb2101010_result;
1051 	size_t dst_size;
1052 	u32 *buf = NULL;
1053 	__le32 *xrgb8888 = NULL;
1054 	struct iosys_map dst, src;
1055 
1056 	struct drm_framebuffer fb = {
1057 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1058 		.pitches = { params->pitch, 0, 0 },
1059 	};
1060 
1061 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010,
1062 				       result->dst_pitch, &params->clip, 0);
1063 	KUNIT_ASSERT_GT(test, dst_size, 0);
1064 
1065 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1066 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1067 	iosys_map_set_vaddr(&dst, buf);
1068 
1069 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1070 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1071 	iosys_map_set_vaddr(&src, xrgb8888);
1072 
1073 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1074 		NULL : &result->dst_pitch;
1075 
1076 	drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1077 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1078 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1079 
1080 	buf = dst.vaddr; /* restore original value of buf */
1081 	memset(buf, 0, dst_size);
1082 
1083 	drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1084 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1085 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1086 }
1087 
1088 static void drm_test_fb_xrgb8888_to_mono(struct kunit *test)
1089 {
1090 	const struct convert_xrgb8888_case *params = test->param_value;
1091 	const struct convert_to_mono_result *result = &params->mono_result;
1092 	size_t dst_size;
1093 	u8 *buf = NULL;
1094 	__le32 *xrgb8888 = NULL;
1095 	struct iosys_map dst, src;
1096 
1097 	struct drm_framebuffer fb = {
1098 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1099 		.pitches = { params->pitch, 0, 0 },
1100 	};
1101 
1102 	dst_size = conversion_buf_size(DRM_FORMAT_C1, result->dst_pitch, &params->clip, 0);
1103 
1104 	KUNIT_ASSERT_GT(test, dst_size, 0);
1105 
1106 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1107 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1108 	iosys_map_set_vaddr(&dst, buf);
1109 
1110 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1111 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1112 	iosys_map_set_vaddr(&src, xrgb8888);
1113 
1114 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1115 		NULL : &result->dst_pitch;
1116 
1117 	drm_fb_xrgb8888_to_mono(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1118 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1119 }
1120 
1121 static void drm_test_fb_swab(struct kunit *test)
1122 {
1123 	const struct convert_xrgb8888_case *params = test->param_value;
1124 	const struct fb_swab_result *result = &params->swab_result;
1125 	size_t dst_size;
1126 	u32 *buf = NULL;
1127 	__le32 *xrgb8888 = NULL;
1128 	struct iosys_map dst, src;
1129 
1130 	struct drm_framebuffer fb = {
1131 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1132 		.pitches = { params->pitch, 0, 0 },
1133 	};
1134 
1135 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB8888, result->dst_pitch, &params->clip, 0);
1136 
1137 	KUNIT_ASSERT_GT(test, dst_size, 0);
1138 
1139 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1140 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1141 	iosys_map_set_vaddr(&dst, buf);
1142 
1143 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1144 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1145 	iosys_map_set_vaddr(&src, xrgb8888);
1146 
1147 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1148 		NULL : &result->dst_pitch;
1149 
1150 	drm_fb_swab(&dst, dst_pitch, &src, &fb, &params->clip, false, &fmtcnv_state);
1151 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1152 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1153 
1154 	buf = dst.vaddr; /* restore original value of buf */
1155 	memset(buf, 0, dst_size);
1156 
1157 	drm_fb_swab(&dst, dst_pitch, &src, &fb, &params->clip, false, &fmtcnv_state);
1158 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1159 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1160 
1161 	buf = dst.vaddr;
1162 	memset(buf, 0, dst_size);
1163 
1164 	drm_fb_xrgb8888_to_bgrx8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1165 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1166 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1167 
1168 	buf = dst.vaddr;
1169 	memset(buf, 0, dst_size);
1170 
1171 	struct drm_format_info mock_format = *fb.format;
1172 
1173 	mock_format.format |= DRM_FORMAT_BIG_ENDIAN;
1174 	fb.format = &mock_format;
1175 
1176 	drm_fb_swab(&dst, dst_pitch, &src, &fb, &params->clip, false, &fmtcnv_state);
1177 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1178 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1179 }
1180 
1181 static void drm_test_fb_xrgb8888_to_abgr8888(struct kunit *test)
1182 {
1183 	const struct convert_xrgb8888_case *params = test->param_value;
1184 	const struct convert_to_abgr8888_result *result = &params->abgr8888_result;
1185 	size_t dst_size;
1186 	u32 *buf = NULL;
1187 	__le32 *xrgb8888 = NULL;
1188 	struct iosys_map dst, src;
1189 
1190 	struct drm_framebuffer fb = {
1191 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1192 		.pitches = { params->pitch, 0, 0 },
1193 	};
1194 
1195 	dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, &params->clip, 0);
1196 
1197 	KUNIT_ASSERT_GT(test, dst_size, 0);
1198 
1199 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1200 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1201 	iosys_map_set_vaddr(&dst, buf);
1202 
1203 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1204 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1205 	iosys_map_set_vaddr(&src, xrgb8888);
1206 
1207 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1208 		NULL : &result->dst_pitch;
1209 
1210 	drm_fb_xrgb8888_to_abgr8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1211 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1212 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1213 }
1214 
1215 static void drm_test_fb_xrgb8888_to_xbgr8888(struct kunit *test)
1216 {
1217 	const struct convert_xrgb8888_case *params = test->param_value;
1218 	const struct convert_to_xbgr8888_result *result = &params->xbgr8888_result;
1219 	size_t dst_size;
1220 	u32 *buf = NULL;
1221 	__le32 *xrgb8888 = NULL;
1222 	struct iosys_map dst, src;
1223 
1224 	struct drm_framebuffer fb = {
1225 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1226 		.pitches = { params->pitch, 0, 0 },
1227 	};
1228 
1229 	dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, &params->clip, 0);
1230 
1231 	KUNIT_ASSERT_GT(test, dst_size, 0);
1232 
1233 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1234 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1235 	iosys_map_set_vaddr(&dst, buf);
1236 
1237 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1238 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1239 	iosys_map_set_vaddr(&src, xrgb8888);
1240 
1241 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1242 		NULL : &result->dst_pitch;
1243 
1244 	drm_fb_xrgb8888_to_xbgr8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1245 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1246 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1247 }
1248 
1249 struct clip_offset_case {
1250 	const char *name;
1251 	unsigned int pitch;
1252 	u32 format;
1253 	struct drm_rect clip;
1254 	unsigned int expected_offset;
1255 };
1256 
1257 static struct clip_offset_case clip_offset_cases[] = {
1258 	{
1259 		.name = "pass through",
1260 		.pitch = TEST_USE_DEFAULT_PITCH,
1261 		.format = DRM_FORMAT_XRGB8888,
1262 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1263 		.expected_offset = 0
1264 	},
1265 	{
1266 		.name = "horizontal offset",
1267 		.pitch = TEST_USE_DEFAULT_PITCH,
1268 		.format = DRM_FORMAT_XRGB8888,
1269 		.clip = DRM_RECT_INIT(1, 0, 3, 3),
1270 		.expected_offset = 4,
1271 	},
1272 	{
1273 		.name = "vertical offset",
1274 		.pitch = TEST_USE_DEFAULT_PITCH,
1275 		.format = DRM_FORMAT_XRGB8888,
1276 		.clip = DRM_RECT_INIT(0, 1, 3, 3),
1277 		.expected_offset = 12,
1278 	},
1279 	{
1280 		.name = "horizontal and vertical offset",
1281 		.pitch = TEST_USE_DEFAULT_PITCH,
1282 		.format = DRM_FORMAT_XRGB8888,
1283 		.clip = DRM_RECT_INIT(1, 1, 3, 3),
1284 		.expected_offset = 16,
1285 	},
1286 	{
1287 		.name = "horizontal offset (custom pitch)",
1288 		.pitch = 20,
1289 		.format = DRM_FORMAT_XRGB8888,
1290 		.clip = DRM_RECT_INIT(1, 0, 3, 3),
1291 		.expected_offset = 4,
1292 	},
1293 	{
1294 		.name = "vertical offset (custom pitch)",
1295 		.pitch = 20,
1296 		.format = DRM_FORMAT_XRGB8888,
1297 		.clip = DRM_RECT_INIT(0, 1, 3, 3),
1298 		.expected_offset = 20,
1299 	},
1300 	{
1301 		.name = "horizontal and vertical offset (custom pitch)",
1302 		.pitch = 20,
1303 		.format = DRM_FORMAT_XRGB8888,
1304 		.clip = DRM_RECT_INIT(1, 1, 3, 3),
1305 		.expected_offset = 24,
1306 	},
1307 };
1308 
1309 static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
1310 {
1311 	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1312 }
1313 
1314 KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);
1315 
1316 static void drm_test_fb_clip_offset(struct kunit *test)
1317 {
1318 	const struct clip_offset_case *params = test->param_value;
1319 	const struct drm_format_info *format_info = drm_format_info(params->format);
1320 
1321 	unsigned int offset;
1322 	unsigned int pitch = params->pitch;
1323 
1324 	if (pitch == TEST_USE_DEFAULT_PITCH)
1325 		pitch = drm_format_info_min_pitch(format_info, 0,
1326 						  drm_rect_width(&params->clip));
1327 
1328 	/*
1329 	 * Assure that the pitch is not zero, because this will inevitable cause the
1330 	 * wrong expected result
1331 	 */
1332 	KUNIT_ASSERT_NE(test, pitch, 0);
1333 
1334 	offset = drm_fb_clip_offset(pitch, format_info, &params->clip);
1335 
1336 	KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
1337 }
1338 
1339 struct fb_memcpy_case {
1340 	const char *name;
1341 	u32 format;
1342 	struct drm_rect clip;
1343 	unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
1344 	const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1345 	unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
1346 	const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1347 };
1348 
1349 /* The `src` and `expected` buffers are u32 arrays. To deal with planes that
1350  * have a cpp != 4 the values are stored together on the same u32 number in a
1351  * way so the order in memory is correct in a little-endian machine.
1352  *
1353  * Because of that, on some occasions, parts of a u32 will not be part of the
1354  * test, to make this explicit the 0xFF byte is used on those parts.
1355  */
1356 
1357 static struct fb_memcpy_case fb_memcpy_cases[] = {
1358 	{
1359 		.name = "single_pixel_source_buffer",
1360 		.format = DRM_FORMAT_XRGB8888,
1361 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
1362 		.src_pitches = { 1 * 4 },
1363 		.src = {{ 0x01020304 }},
1364 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1365 		.expected = {{ 0x01020304 }},
1366 	},
1367 	{
1368 		.name = "single_pixel_source_buffer",
1369 		.format = DRM_FORMAT_XRGB8888_A8,
1370 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
1371 		.src_pitches = { 1 * 4, 1 },
1372 		.src = {
1373 			{ 0x01020304 },
1374 			{ 0xFFFFFF01 },
1375 		},
1376 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1377 		.expected = {
1378 			{ 0x01020304 },
1379 			{ 0x00000001 },
1380 		},
1381 	},
1382 	{
1383 		.name = "single_pixel_source_buffer",
1384 		.format = DRM_FORMAT_YUV444,
1385 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
1386 		.src_pitches = { 1, 1, 1 },
1387 		.src = {
1388 			{ 0xFFFFFF01 },
1389 			{ 0xFFFFFF01 },
1390 			{ 0xFFFFFF01 },
1391 		},
1392 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1393 		.expected = {
1394 			{ 0x00000001 },
1395 			{ 0x00000001 },
1396 			{ 0x00000001 },
1397 		},
1398 	},
1399 	{
1400 		.name = "single_pixel_clip_rectangle",
1401 		.format = DRM_FORMAT_XBGR8888,
1402 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
1403 		.src_pitches = { 2 * 4 },
1404 		.src = {
1405 			{
1406 				0x00000000, 0x00000000,
1407 				0x00000000, 0x01020304,
1408 			},
1409 		},
1410 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1411 		.expected = {
1412 			{ 0x01020304 },
1413 		},
1414 	},
1415 	{
1416 		.name = "single_pixel_clip_rectangle",
1417 		.format = DRM_FORMAT_XRGB8888_A8,
1418 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
1419 		.src_pitches = { 2 * 4, 2 * 1 },
1420 		.src = {
1421 			{
1422 				0x00000000, 0x00000000,
1423 				0x00000000, 0x01020304,
1424 			},
1425 			{ 0x01000000 },
1426 		},
1427 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1428 		.expected = {
1429 			{ 0x01020304 },
1430 			{ 0x00000001 },
1431 		},
1432 	},
1433 	{
1434 		.name = "single_pixel_clip_rectangle",
1435 		.format = DRM_FORMAT_YUV444,
1436 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
1437 		.src_pitches = { 2 * 1, 2 * 1, 2 * 1 },
1438 		.src = {
1439 			{ 0x01000000 },
1440 			{ 0x01000000 },
1441 			{ 0x01000000 },
1442 		},
1443 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1444 		.expected = {
1445 			{ 0x00000001 },
1446 			{ 0x00000001 },
1447 			{ 0x00000001 },
1448 		},
1449 	},
1450 	{
1451 		.name = "well_known_colors",
1452 		.format = DRM_FORMAT_XBGR8888,
1453 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
1454 		.src_pitches = { 4 * 4 },
1455 		.src = {
1456 			{
1457 				0x00000000, 0x00000000, 0x00000000, 0x00000000,
1458 				0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
1459 				0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
1460 				0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
1461 				0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
1462 			},
1463 		},
1464 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1465 		.expected = {
1466 			{
1467 				0x11FFFFFF, 0x22000000,
1468 				0x33FF0000, 0x4400FF00,
1469 				0x550000FF, 0x66FF00FF,
1470 				0x77FFFF00, 0x8800FFFF,
1471 			},
1472 		},
1473 	},
1474 	{
1475 		.name = "well_known_colors",
1476 		.format = DRM_FORMAT_XRGB8888_A8,
1477 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
1478 		.src_pitches = { 4 * 4, 4 * 1 },
1479 		.src = {
1480 			{
1481 				0x00000000, 0x00000000, 0x00000000, 0x00000000,
1482 				0x00000000, 0xFFFFFFFF, 0xFF000000, 0x00000000,
1483 				0x00000000, 0xFFFF0000, 0xFF00FF00, 0x00000000,
1484 				0x00000000, 0xFF0000FF, 0xFFFF00FF, 0x00000000,
1485 				0x00000000, 0xFFFFFF00, 0xFF00FFFF, 0x00000000,
1486 			},
1487 			{
1488 				0x00000000,
1489 				0x00221100,
1490 				0x00443300,
1491 				0x00665500,
1492 				0x00887700,
1493 			},
1494 		},
1495 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1496 		.expected = {
1497 			{
1498 				0xFFFFFFFF, 0xFF000000,
1499 				0xFFFF0000, 0xFF00FF00,
1500 				0xFF0000FF, 0xFFFF00FF,
1501 				0xFFFFFF00, 0xFF00FFFF,
1502 			},
1503 			{
1504 				0x44332211,
1505 				0x88776655,
1506 			},
1507 		},
1508 	},
1509 	{
1510 		.name = "well_known_colors",
1511 		.format = DRM_FORMAT_YUV444,
1512 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
1513 		.src_pitches = { 4 * 1, 4 * 1, 4 * 1 },
1514 		.src = {
1515 			{
1516 				0x00000000,
1517 				0x0000FF00,
1518 				0x00954C00,
1519 				0x00691D00,
1520 				0x00B2E100,
1521 			},
1522 			{
1523 				0x00000000,
1524 				0x00000000,
1525 				0x00BEDE00,
1526 				0x00436500,
1527 				0x00229B00,
1528 			},
1529 			{
1530 				0x00000000,
1531 				0x00000000,
1532 				0x007E9C00,
1533 				0x0083E700,
1534 				0x00641A00,
1535 			},
1536 		},
1537 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1538 		.expected = {
1539 			{
1540 				0x954C00FF,
1541 				0xB2E1691D,
1542 			},
1543 			{
1544 				0xBEDE0000,
1545 				0x229B4365,
1546 			},
1547 			{
1548 				0x7E9C0000,
1549 				0x641A83E7,
1550 			},
1551 		},
1552 	},
1553 	{
1554 		.name = "destination_pitch",
1555 		.format = DRM_FORMAT_XBGR8888,
1556 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1557 		.src_pitches = { 3 * 4 },
1558 		.src = {
1559 			{
1560 				0xA10E449C, 0xB1114D05, 0xC1A8F303,
1561 				0xD16CF073, 0xA20E449C, 0xB2114D05,
1562 				0xC2A80303, 0xD26CF073, 0xA30E449C,
1563 			},
1564 		},
1565 		.dst_pitches = { 5 * 4 },
1566 		.expected = {
1567 			{
1568 				0xA10E449C, 0xB1114D05, 0xC1A8F303, 0x00000000, 0x00000000,
1569 				0xD16CF073, 0xA20E449C, 0xB2114D05, 0x00000000, 0x00000000,
1570 				0xC2A80303, 0xD26CF073, 0xA30E449C, 0x00000000, 0x00000000,
1571 			},
1572 		},
1573 	},
1574 	{
1575 		.name = "destination_pitch",
1576 		.format = DRM_FORMAT_XRGB8888_A8,
1577 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1578 		.src_pitches = { 3 * 4, 3 * 1 },
1579 		.src = {
1580 			{
1581 				0xFF0E449C, 0xFF114D05, 0xFFA8F303,
1582 				0xFF6CF073, 0xFF0E449C, 0xFF114D05,
1583 				0xFFA80303, 0xFF6CF073, 0xFF0E449C,
1584 			},
1585 			{
1586 				0xB2C1B1A1,
1587 				0xD2A3D1A2,
1588 				0xFFFFFFC2,
1589 			},
1590 		},
1591 		.dst_pitches = { 5 * 4, 5 * 1 },
1592 		.expected = {
1593 			{
1594 				0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
1595 				0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
1596 				0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
1597 			},
1598 			{
1599 				0x00C1B1A1,
1600 				0xD1A2B200,
1601 				0xD2A30000,
1602 				0xFF0000C2,
1603 			},
1604 		},
1605 	},
1606 	{
1607 		.name = "destination_pitch",
1608 		.format = DRM_FORMAT_YUV444,
1609 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1610 		.src_pitches = { 3 * 1, 3 * 1, 3 * 1 },
1611 		.src = {
1612 			{
1613 				0xBAC1323D,
1614 				0xBA34323D,
1615 				0xFFFFFF3D,
1616 			},
1617 			{
1618 				0xE1ABEC2A,
1619 				0xE1EAEC2A,
1620 				0xFFFFFF2A,
1621 			},
1622 			{
1623 				0xBCEBE4D7,
1624 				0xBC65E4D7,
1625 				0xFFFFFFD7,
1626 			},
1627 		},
1628 		.dst_pitches = { 5 * 1, 5 * 1, 5 * 1 },
1629 		.expected = {
1630 			{
1631 				0x00C1323D,
1632 				0x323DBA00,
1633 				0xBA340000,
1634 				0xFF00003D,
1635 			},
1636 			{
1637 				0x00ABEC2A,
1638 				0xEC2AE100,
1639 				0xE1EA0000,
1640 				0xFF00002A,
1641 			},
1642 			{
1643 				0x00EBE4D7,
1644 				0xE4D7BC00,
1645 				0xBC650000,
1646 				0xFF0000D7,
1647 			},
1648 		},
1649 	},
1650 };
1651 
1652 static void fb_memcpy_case_desc(struct fb_memcpy_case *t, char *desc)
1653 {
1654 	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s: %p4cc", t->name, &t->format);
1655 }
1656 
1657 KUNIT_ARRAY_PARAM(fb_memcpy, fb_memcpy_cases, fb_memcpy_case_desc);
1658 
1659 static void drm_test_fb_memcpy(struct kunit *test)
1660 {
1661 	const struct fb_memcpy_case *params = test->param_value;
1662 	size_t dst_size[DRM_FORMAT_MAX_PLANES] = { 0 };
1663 	u32 *buf[DRM_FORMAT_MAX_PLANES] = { 0 };
1664 	__le32 *src_cp[DRM_FORMAT_MAX_PLANES] = { 0 };
1665 	__le32 *expected[DRM_FORMAT_MAX_PLANES] = { 0 };
1666 	struct iosys_map dst[DRM_FORMAT_MAX_PLANES];
1667 	struct iosys_map src[DRM_FORMAT_MAX_PLANES];
1668 
1669 	struct drm_framebuffer fb = {
1670 		.format = drm_format_info(params->format),
1671 	};
1672 
1673 	memcpy(fb.pitches, params->src_pitches, DRM_FORMAT_MAX_PLANES * sizeof(int));
1674 
1675 	for (size_t i = 0; i < fb.format->num_planes; i++) {
1676 		dst_size[i] = conversion_buf_size(params->format, params->dst_pitches[i],
1677 						  &params->clip, i);
1678 		KUNIT_ASSERT_GT(test, dst_size[i], 0);
1679 
1680 		buf[i] = kunit_kzalloc(test, dst_size[i], GFP_KERNEL);
1681 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf[i]);
1682 		iosys_map_set_vaddr(&dst[i], buf[i]);
1683 
1684 		src_cp[i] = cpubuf_to_le32(test, params->src[i], TEST_BUF_SIZE);
1685 		iosys_map_set_vaddr(&src[i], src_cp[i]);
1686 	}
1687 
1688 	const unsigned int *dst_pitches = params->dst_pitches[0] == TEST_USE_DEFAULT_PITCH ? NULL :
1689 		params->dst_pitches;
1690 
1691 	drm_fb_memcpy(dst, dst_pitches, src, &fb, &params->clip);
1692 
1693 	for (size_t i = 0; i < fb.format->num_planes; i++) {
1694 		expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1695 		KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1696 				       "Failed expectation on plane %zu", i);
1697 
1698 		memset(buf[i], 0, dst_size[i]);
1699 	}
1700 
1701 	drm_fb_memcpy(dst, dst_pitches, src, &fb, &params->clip);
1702 
1703 	for (size_t i = 0; i < fb.format->num_planes; i++) {
1704 		expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1705 		KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1706 				       "Failed expectation on plane %zu", i);
1707 	}
1708 }
1709 
1710 static struct kunit_case drm_format_helper_test_cases[] = {
1711 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
1712 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
1713 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
1714 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params),
1715 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params),
1716 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params),
1717 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
1718 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_bgr888, convert_xrgb8888_gen_params),
1719 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params),
1720 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
1721 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params),
1722 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_mono, convert_xrgb8888_gen_params),
1723 	KUNIT_CASE_PARAM(drm_test_fb_swab, convert_xrgb8888_gen_params),
1724 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xbgr8888, convert_xrgb8888_gen_params),
1725 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_abgr8888, convert_xrgb8888_gen_params),
1726 	KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params),
1727 	KUNIT_CASE_PARAM(drm_test_fb_memcpy, fb_memcpy_gen_params),
1728 	{}
1729 };
1730 
1731 static struct kunit_suite drm_format_helper_test_suite = {
1732 	.name = "drm_format_helper_test",
1733 	.test_cases = drm_format_helper_test_cases,
1734 };
1735 
1736 kunit_test_suite(drm_format_helper_test_suite);
1737 
1738 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
1739 MODULE_LICENSE("GPL");
1740 MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
1741