xref: /linux/drivers/gpu/drm/tests/drm_format_helper_test.c (revision 22c55fb9eb92395d999b8404d73e58540d11bdd8)
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, 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 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1044 }
1045 
1046 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
1047 {
1048 	const struct convert_xrgb8888_case *params = test->param_value;
1049 	const struct convert_to_argb2101010_result *result = &params->argb2101010_result;
1050 	size_t dst_size;
1051 	u32 *buf = NULL;
1052 	__le32 *xrgb8888 = NULL;
1053 	struct iosys_map dst, src;
1054 
1055 	struct drm_framebuffer fb = {
1056 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1057 		.pitches = { params->pitch, 0, 0 },
1058 	};
1059 
1060 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010,
1061 				       result->dst_pitch, &params->clip, 0);
1062 	KUNIT_ASSERT_GT(test, dst_size, 0);
1063 
1064 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1065 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1066 	iosys_map_set_vaddr(&dst, buf);
1067 
1068 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1069 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1070 	iosys_map_set_vaddr(&src, xrgb8888);
1071 
1072 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1073 		NULL : &result->dst_pitch;
1074 
1075 	drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1076 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1077 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1078 
1079 	buf = dst.vaddr; /* restore original value of buf */
1080 	memset(buf, 0, dst_size);
1081 
1082 	drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1083 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1084 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1085 }
1086 
1087 static void drm_test_fb_xrgb8888_to_mono(struct kunit *test)
1088 {
1089 	const struct convert_xrgb8888_case *params = test->param_value;
1090 	const struct convert_to_mono_result *result = &params->mono_result;
1091 	size_t dst_size;
1092 	u8 *buf = NULL;
1093 	__le32 *xrgb8888 = NULL;
1094 	struct iosys_map dst, src;
1095 
1096 	struct drm_framebuffer fb = {
1097 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1098 		.pitches = { params->pitch, 0, 0 },
1099 	};
1100 
1101 	dst_size = conversion_buf_size(DRM_FORMAT_C1, result->dst_pitch, &params->clip, 0);
1102 
1103 	KUNIT_ASSERT_GT(test, dst_size, 0);
1104 
1105 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1106 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1107 	iosys_map_set_vaddr(&dst, buf);
1108 
1109 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1110 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1111 	iosys_map_set_vaddr(&src, xrgb8888);
1112 
1113 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1114 		NULL : &result->dst_pitch;
1115 
1116 	drm_fb_xrgb8888_to_mono(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1117 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1118 }
1119 
1120 static void drm_test_fb_swab(struct kunit *test)
1121 {
1122 	const struct convert_xrgb8888_case *params = test->param_value;
1123 	const struct fb_swab_result *result = &params->swab_result;
1124 	size_t dst_size;
1125 	u32 *buf = NULL;
1126 	__le32 *xrgb8888 = NULL;
1127 	struct iosys_map dst, src;
1128 
1129 	struct drm_framebuffer fb = {
1130 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1131 		.pitches = { params->pitch, 0, 0 },
1132 	};
1133 
1134 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB8888, result->dst_pitch, &params->clip, 0);
1135 
1136 	KUNIT_ASSERT_GT(test, dst_size, 0);
1137 
1138 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1139 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1140 	iosys_map_set_vaddr(&dst, buf);
1141 
1142 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1143 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1144 	iosys_map_set_vaddr(&src, xrgb8888);
1145 
1146 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1147 		NULL : &result->dst_pitch;
1148 
1149 	drm_fb_swab(&dst, dst_pitch, &src, &fb, &params->clip, false, &fmtcnv_state);
1150 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1151 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1152 
1153 	buf = dst.vaddr; /* restore original value of buf */
1154 	memset(buf, 0, dst_size);
1155 
1156 	drm_fb_swab(&dst, dst_pitch, &src, &fb, &params->clip, false, &fmtcnv_state);
1157 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1158 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1159 
1160 	buf = dst.vaddr;
1161 	memset(buf, 0, dst_size);
1162 
1163 	drm_fb_xrgb8888_to_bgrx8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1164 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1165 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1166 
1167 	buf = dst.vaddr;
1168 	memset(buf, 0, dst_size);
1169 
1170 	struct drm_format_info mock_format = *fb.format;
1171 
1172 	mock_format.format |= DRM_FORMAT_BIG_ENDIAN;
1173 	fb.format = &mock_format;
1174 
1175 	drm_fb_swab(&dst, dst_pitch, &src, &fb, &params->clip, false, &fmtcnv_state);
1176 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1177 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1178 }
1179 
1180 static void drm_test_fb_xrgb8888_to_abgr8888(struct kunit *test)
1181 {
1182 	const struct convert_xrgb8888_case *params = test->param_value;
1183 	const struct convert_to_abgr8888_result *result = &params->abgr8888_result;
1184 	size_t dst_size;
1185 	u32 *buf = NULL;
1186 	__le32 *xrgb8888 = NULL;
1187 	struct iosys_map dst, src;
1188 
1189 	struct drm_framebuffer fb = {
1190 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1191 		.pitches = { params->pitch, 0, 0 },
1192 	};
1193 
1194 	dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, &params->clip, 0);
1195 
1196 	KUNIT_ASSERT_GT(test, dst_size, 0);
1197 
1198 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1199 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1200 	iosys_map_set_vaddr(&dst, buf);
1201 
1202 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1203 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1204 	iosys_map_set_vaddr(&src, xrgb8888);
1205 
1206 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1207 		NULL : &result->dst_pitch;
1208 
1209 	drm_fb_xrgb8888_to_abgr8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1210 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1211 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1212 }
1213 
1214 static void drm_test_fb_xrgb8888_to_xbgr8888(struct kunit *test)
1215 {
1216 	const struct convert_xrgb8888_case *params = test->param_value;
1217 	const struct convert_to_xbgr8888_result *result = &params->xbgr8888_result;
1218 	size_t dst_size;
1219 	u32 *buf = NULL;
1220 	__le32 *xrgb8888 = NULL;
1221 	struct iosys_map dst, src;
1222 
1223 	struct drm_framebuffer fb = {
1224 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1225 		.pitches = { params->pitch, 0, 0 },
1226 	};
1227 
1228 	dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, &params->clip, 0);
1229 
1230 	KUNIT_ASSERT_GT(test, dst_size, 0);
1231 
1232 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1233 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1234 	iosys_map_set_vaddr(&dst, buf);
1235 
1236 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1237 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1238 	iosys_map_set_vaddr(&src, xrgb8888);
1239 
1240 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1241 		NULL : &result->dst_pitch;
1242 
1243 	drm_fb_xrgb8888_to_xbgr8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1244 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1245 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1246 }
1247 
1248 struct clip_offset_case {
1249 	const char *name;
1250 	unsigned int pitch;
1251 	u32 format;
1252 	struct drm_rect clip;
1253 	unsigned int expected_offset;
1254 };
1255 
1256 static struct clip_offset_case clip_offset_cases[] = {
1257 	{
1258 		.name = "pass through",
1259 		.pitch = TEST_USE_DEFAULT_PITCH,
1260 		.format = DRM_FORMAT_XRGB8888,
1261 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1262 		.expected_offset = 0
1263 	},
1264 	{
1265 		.name = "horizontal offset",
1266 		.pitch = TEST_USE_DEFAULT_PITCH,
1267 		.format = DRM_FORMAT_XRGB8888,
1268 		.clip = DRM_RECT_INIT(1, 0, 3, 3),
1269 		.expected_offset = 4,
1270 	},
1271 	{
1272 		.name = "vertical offset",
1273 		.pitch = TEST_USE_DEFAULT_PITCH,
1274 		.format = DRM_FORMAT_XRGB8888,
1275 		.clip = DRM_RECT_INIT(0, 1, 3, 3),
1276 		.expected_offset = 12,
1277 	},
1278 	{
1279 		.name = "horizontal and vertical offset",
1280 		.pitch = TEST_USE_DEFAULT_PITCH,
1281 		.format = DRM_FORMAT_XRGB8888,
1282 		.clip = DRM_RECT_INIT(1, 1, 3, 3),
1283 		.expected_offset = 16,
1284 	},
1285 	{
1286 		.name = "horizontal offset (custom pitch)",
1287 		.pitch = 20,
1288 		.format = DRM_FORMAT_XRGB8888,
1289 		.clip = DRM_RECT_INIT(1, 0, 3, 3),
1290 		.expected_offset = 4,
1291 	},
1292 	{
1293 		.name = "vertical offset (custom pitch)",
1294 		.pitch = 20,
1295 		.format = DRM_FORMAT_XRGB8888,
1296 		.clip = DRM_RECT_INIT(0, 1, 3, 3),
1297 		.expected_offset = 20,
1298 	},
1299 	{
1300 		.name = "horizontal and vertical offset (custom pitch)",
1301 		.pitch = 20,
1302 		.format = DRM_FORMAT_XRGB8888,
1303 		.clip = DRM_RECT_INIT(1, 1, 3, 3),
1304 		.expected_offset = 24,
1305 	},
1306 };
1307 
1308 static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
1309 {
1310 	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1311 }
1312 
1313 KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);
1314 
1315 static void drm_test_fb_clip_offset(struct kunit *test)
1316 {
1317 	const struct clip_offset_case *params = test->param_value;
1318 	const struct drm_format_info *format_info = drm_format_info(params->format);
1319 
1320 	unsigned int offset;
1321 	unsigned int pitch = params->pitch;
1322 
1323 	if (pitch == TEST_USE_DEFAULT_PITCH)
1324 		pitch = drm_format_info_min_pitch(format_info, 0,
1325 						  drm_rect_width(&params->clip));
1326 
1327 	/*
1328 	 * Assure that the pitch is not zero, because this will inevitable cause the
1329 	 * wrong expected result
1330 	 */
1331 	KUNIT_ASSERT_NE(test, pitch, 0);
1332 
1333 	offset = drm_fb_clip_offset(pitch, format_info, &params->clip);
1334 
1335 	KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
1336 }
1337 
1338 struct fb_memcpy_case {
1339 	const char *name;
1340 	u32 format;
1341 	struct drm_rect clip;
1342 	unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
1343 	const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1344 	unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
1345 	const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1346 };
1347 
1348 /* The `src` and `expected` buffers are u32 arrays. To deal with planes that
1349  * have a cpp != 4 the values are stored together on the same u32 number in a
1350  * way so the order in memory is correct in a little-endian machine.
1351  *
1352  * Because of that, on some occasions, parts of a u32 will not be part of the
1353  * test, to make this explicit the 0xFF byte is used on those parts.
1354  */
1355 
1356 static struct fb_memcpy_case fb_memcpy_cases[] = {
1357 	{
1358 		.name = "single_pixel_source_buffer",
1359 		.format = DRM_FORMAT_XRGB8888,
1360 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
1361 		.src_pitches = { 1 * 4 },
1362 		.src = {{ 0x01020304 }},
1363 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1364 		.expected = {{ 0x01020304 }},
1365 	},
1366 	{
1367 		.name = "single_pixel_source_buffer",
1368 		.format = DRM_FORMAT_XRGB8888_A8,
1369 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
1370 		.src_pitches = { 1 * 4, 1 },
1371 		.src = {
1372 			{ 0x01020304 },
1373 			{ 0xFFFFFF01 },
1374 		},
1375 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1376 		.expected = {
1377 			{ 0x01020304 },
1378 			{ 0x00000001 },
1379 		},
1380 	},
1381 	{
1382 		.name = "single_pixel_source_buffer",
1383 		.format = DRM_FORMAT_YUV444,
1384 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
1385 		.src_pitches = { 1, 1, 1 },
1386 		.src = {
1387 			{ 0xFFFFFF01 },
1388 			{ 0xFFFFFF01 },
1389 			{ 0xFFFFFF01 },
1390 		},
1391 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1392 		.expected = {
1393 			{ 0x00000001 },
1394 			{ 0x00000001 },
1395 			{ 0x00000001 },
1396 		},
1397 	},
1398 	{
1399 		.name = "single_pixel_clip_rectangle",
1400 		.format = DRM_FORMAT_XBGR8888,
1401 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
1402 		.src_pitches = { 2 * 4 },
1403 		.src = {
1404 			{
1405 				0x00000000, 0x00000000,
1406 				0x00000000, 0x01020304,
1407 			},
1408 		},
1409 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1410 		.expected = {
1411 			{ 0x01020304 },
1412 		},
1413 	},
1414 	{
1415 		.name = "single_pixel_clip_rectangle",
1416 		.format = DRM_FORMAT_XRGB8888_A8,
1417 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
1418 		.src_pitches = { 2 * 4, 2 * 1 },
1419 		.src = {
1420 			{
1421 				0x00000000, 0x00000000,
1422 				0x00000000, 0x01020304,
1423 			},
1424 			{ 0x01000000 },
1425 		},
1426 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1427 		.expected = {
1428 			{ 0x01020304 },
1429 			{ 0x00000001 },
1430 		},
1431 	},
1432 	{
1433 		.name = "single_pixel_clip_rectangle",
1434 		.format = DRM_FORMAT_YUV444,
1435 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
1436 		.src_pitches = { 2 * 1, 2 * 1, 2 * 1 },
1437 		.src = {
1438 			{ 0x01000000 },
1439 			{ 0x01000000 },
1440 			{ 0x01000000 },
1441 		},
1442 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1443 		.expected = {
1444 			{ 0x00000001 },
1445 			{ 0x00000001 },
1446 			{ 0x00000001 },
1447 		},
1448 	},
1449 	{
1450 		.name = "well_known_colors",
1451 		.format = DRM_FORMAT_XBGR8888,
1452 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
1453 		.src_pitches = { 4 * 4 },
1454 		.src = {
1455 			{
1456 				0x00000000, 0x00000000, 0x00000000, 0x00000000,
1457 				0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
1458 				0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
1459 				0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
1460 				0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
1461 			},
1462 		},
1463 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1464 		.expected = {
1465 			{
1466 				0x11FFFFFF, 0x22000000,
1467 				0x33FF0000, 0x4400FF00,
1468 				0x550000FF, 0x66FF00FF,
1469 				0x77FFFF00, 0x8800FFFF,
1470 			},
1471 		},
1472 	},
1473 	{
1474 		.name = "well_known_colors",
1475 		.format = DRM_FORMAT_XRGB8888_A8,
1476 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
1477 		.src_pitches = { 4 * 4, 4 * 1 },
1478 		.src = {
1479 			{
1480 				0x00000000, 0x00000000, 0x00000000, 0x00000000,
1481 				0x00000000, 0xFFFFFFFF, 0xFF000000, 0x00000000,
1482 				0x00000000, 0xFFFF0000, 0xFF00FF00, 0x00000000,
1483 				0x00000000, 0xFF0000FF, 0xFFFF00FF, 0x00000000,
1484 				0x00000000, 0xFFFFFF00, 0xFF00FFFF, 0x00000000,
1485 			},
1486 			{
1487 				0x00000000,
1488 				0x00221100,
1489 				0x00443300,
1490 				0x00665500,
1491 				0x00887700,
1492 			},
1493 		},
1494 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1495 		.expected = {
1496 			{
1497 				0xFFFFFFFF, 0xFF000000,
1498 				0xFFFF0000, 0xFF00FF00,
1499 				0xFF0000FF, 0xFFFF00FF,
1500 				0xFFFFFF00, 0xFF00FFFF,
1501 			},
1502 			{
1503 				0x44332211,
1504 				0x88776655,
1505 			},
1506 		},
1507 	},
1508 	{
1509 		.name = "well_known_colors",
1510 		.format = DRM_FORMAT_YUV444,
1511 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
1512 		.src_pitches = { 4 * 1, 4 * 1, 4 * 1 },
1513 		.src = {
1514 			{
1515 				0x00000000,
1516 				0x0000FF00,
1517 				0x00954C00,
1518 				0x00691D00,
1519 				0x00B2E100,
1520 			},
1521 			{
1522 				0x00000000,
1523 				0x00000000,
1524 				0x00BEDE00,
1525 				0x00436500,
1526 				0x00229B00,
1527 			},
1528 			{
1529 				0x00000000,
1530 				0x00000000,
1531 				0x007E9C00,
1532 				0x0083E700,
1533 				0x00641A00,
1534 			},
1535 		},
1536 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1537 		.expected = {
1538 			{
1539 				0x954C00FF,
1540 				0xB2E1691D,
1541 			},
1542 			{
1543 				0xBEDE0000,
1544 				0x229B4365,
1545 			},
1546 			{
1547 				0x7E9C0000,
1548 				0x641A83E7,
1549 			},
1550 		},
1551 	},
1552 	{
1553 		.name = "destination_pitch",
1554 		.format = DRM_FORMAT_XBGR8888,
1555 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1556 		.src_pitches = { 3 * 4 },
1557 		.src = {
1558 			{
1559 				0xA10E449C, 0xB1114D05, 0xC1A8F303,
1560 				0xD16CF073, 0xA20E449C, 0xB2114D05,
1561 				0xC2A80303, 0xD26CF073, 0xA30E449C,
1562 			},
1563 		},
1564 		.dst_pitches = { 5 * 4 },
1565 		.expected = {
1566 			{
1567 				0xA10E449C, 0xB1114D05, 0xC1A8F303, 0x00000000, 0x00000000,
1568 				0xD16CF073, 0xA20E449C, 0xB2114D05, 0x00000000, 0x00000000,
1569 				0xC2A80303, 0xD26CF073, 0xA30E449C, 0x00000000, 0x00000000,
1570 			},
1571 		},
1572 	},
1573 	{
1574 		.name = "destination_pitch",
1575 		.format = DRM_FORMAT_XRGB8888_A8,
1576 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1577 		.src_pitches = { 3 * 4, 3 * 1 },
1578 		.src = {
1579 			{
1580 				0xFF0E449C, 0xFF114D05, 0xFFA8F303,
1581 				0xFF6CF073, 0xFF0E449C, 0xFF114D05,
1582 				0xFFA80303, 0xFF6CF073, 0xFF0E449C,
1583 			},
1584 			{
1585 				0xB2C1B1A1,
1586 				0xD2A3D1A2,
1587 				0xFFFFFFC2,
1588 			},
1589 		},
1590 		.dst_pitches = { 5 * 4, 5 * 1 },
1591 		.expected = {
1592 			{
1593 				0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
1594 				0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
1595 				0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
1596 			},
1597 			{
1598 				0x00C1B1A1,
1599 				0xD1A2B200,
1600 				0xD2A30000,
1601 				0xFF0000C2,
1602 			},
1603 		},
1604 	},
1605 	{
1606 		.name = "destination_pitch",
1607 		.format = DRM_FORMAT_YUV444,
1608 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1609 		.src_pitches = { 3 * 1, 3 * 1, 3 * 1 },
1610 		.src = {
1611 			{
1612 				0xBAC1323D,
1613 				0xBA34323D,
1614 				0xFFFFFF3D,
1615 			},
1616 			{
1617 				0xE1ABEC2A,
1618 				0xE1EAEC2A,
1619 				0xFFFFFF2A,
1620 			},
1621 			{
1622 				0xBCEBE4D7,
1623 				0xBC65E4D7,
1624 				0xFFFFFFD7,
1625 			},
1626 		},
1627 		.dst_pitches = { 5 * 1, 5 * 1, 5 * 1 },
1628 		.expected = {
1629 			{
1630 				0x00C1323D,
1631 				0x323DBA00,
1632 				0xBA340000,
1633 				0xFF00003D,
1634 			},
1635 			{
1636 				0x00ABEC2A,
1637 				0xEC2AE100,
1638 				0xE1EA0000,
1639 				0xFF00002A,
1640 			},
1641 			{
1642 				0x00EBE4D7,
1643 				0xE4D7BC00,
1644 				0xBC650000,
1645 				0xFF0000D7,
1646 			},
1647 		},
1648 	},
1649 };
1650 
1651 static void fb_memcpy_case_desc(struct fb_memcpy_case *t, char *desc)
1652 {
1653 	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s: %p4cc", t->name, &t->format);
1654 }
1655 
1656 KUNIT_ARRAY_PARAM(fb_memcpy, fb_memcpy_cases, fb_memcpy_case_desc);
1657 
1658 static void drm_test_fb_memcpy(struct kunit *test)
1659 {
1660 	const struct fb_memcpy_case *params = test->param_value;
1661 	size_t dst_size[DRM_FORMAT_MAX_PLANES] = { 0 };
1662 	u32 *buf[DRM_FORMAT_MAX_PLANES] = { 0 };
1663 	__le32 *src_cp[DRM_FORMAT_MAX_PLANES] = { 0 };
1664 	__le32 *expected[DRM_FORMAT_MAX_PLANES] = { 0 };
1665 	struct iosys_map dst[DRM_FORMAT_MAX_PLANES];
1666 	struct iosys_map src[DRM_FORMAT_MAX_PLANES];
1667 
1668 	struct drm_framebuffer fb = {
1669 		.format = drm_format_info(params->format),
1670 	};
1671 
1672 	memcpy(fb.pitches, params->src_pitches, DRM_FORMAT_MAX_PLANES * sizeof(int));
1673 
1674 	for (size_t i = 0; i < fb.format->num_planes; i++) {
1675 		dst_size[i] = conversion_buf_size(params->format, params->dst_pitches[i],
1676 						  &params->clip, i);
1677 		KUNIT_ASSERT_GT(test, dst_size[i], 0);
1678 
1679 		buf[i] = kunit_kzalloc(test, dst_size[i], GFP_KERNEL);
1680 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf[i]);
1681 		iosys_map_set_vaddr(&dst[i], buf[i]);
1682 
1683 		src_cp[i] = cpubuf_to_le32(test, params->src[i], TEST_BUF_SIZE);
1684 		iosys_map_set_vaddr(&src[i], src_cp[i]);
1685 	}
1686 
1687 	const unsigned int *dst_pitches = params->dst_pitches[0] == TEST_USE_DEFAULT_PITCH ? NULL :
1688 		params->dst_pitches;
1689 
1690 	drm_fb_memcpy(dst, dst_pitches, src, &fb, &params->clip);
1691 
1692 	for (size_t i = 0; i < fb.format->num_planes; i++) {
1693 		expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1694 		KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1695 				       "Failed expectation on plane %zu", i);
1696 
1697 		memset(buf[i], 0, dst_size[i]);
1698 	}
1699 
1700 	drm_fb_memcpy(dst, dst_pitches, src, &fb, &params->clip);
1701 
1702 	for (size_t i = 0; i < fb.format->num_planes; i++) {
1703 		expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1704 		KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1705 				       "Failed expectation on plane %zu", i);
1706 	}
1707 }
1708 
1709 static struct kunit_case drm_format_helper_test_cases[] = {
1710 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
1711 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
1712 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
1713 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params),
1714 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params),
1715 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params),
1716 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
1717 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_bgr888, convert_xrgb8888_gen_params),
1718 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params),
1719 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
1720 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params),
1721 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_mono, convert_xrgb8888_gen_params),
1722 	KUNIT_CASE_PARAM(drm_test_fb_swab, convert_xrgb8888_gen_params),
1723 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xbgr8888, convert_xrgb8888_gen_params),
1724 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_abgr8888, convert_xrgb8888_gen_params),
1725 	KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params),
1726 	KUNIT_CASE_PARAM(drm_test_fb_memcpy, fb_memcpy_gen_params),
1727 	{}
1728 };
1729 
1730 static struct kunit_suite drm_format_helper_test_suite = {
1731 	.name = "drm_format_helper_test",
1732 	.test_cases = drm_format_helper_test_cases,
1733 };
1734 
1735 kunit_test_suite(drm_format_helper_test_suite);
1736 
1737 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
1738 MODULE_LICENSE("GPL");
1739 MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
1740