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, 0x99,
283 				0x19, 0x66,
284 				0xE5, 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 				0x3C, 0x33, 0xC4, 0x00, 0x00,
434 				0xBB, 0x3C, 0x33, 0x00, 0x00,
435 				0x34, 0xBB, 0x3C, 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  */
conversion_buf_size(u32 dst_format,unsigned int dst_pitch,const struct drm_rect * clip,int plane)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 
le16buf_to_cpu(struct kunit * test,const __le16 * buf,size_t buf_size)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 
le32buf_to_cpu(struct kunit * test,const __le32 * buf,size_t buf_size)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 
cpubuf_to_le32(struct kunit * test,const u32 * buf,size_t buf_size)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 
convert_xrgb8888_case_desc(struct convert_xrgb8888_case * t,char * desc)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 
drm_test_fb_xrgb8888_to_gray8(struct kunit * test)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 
drm_test_fb_xrgb8888_to_rgb332(struct kunit * test)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 
drm_test_fb_xrgb8888_to_rgb565(struct kunit * test)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, false);
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_rgb565(&dst, &result->dst_pitch, &src, &fb, &params->clip,
744 				  &fmtcnv_state, true);
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 	int blit_result = 0;
752 
753 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB565, &src, &fb, &params->clip,
754 				  &fmtcnv_state);
755 
756 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
757 
758 	KUNIT_EXPECT_FALSE(test, blit_result);
759 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
760 }
761 
drm_test_fb_xrgb8888_to_xrgb1555(struct kunit * test)762 static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test)
763 {
764 	const struct convert_xrgb8888_case *params = test->param_value;
765 	const struct convert_to_xrgb1555_result *result = &params->xrgb1555_result;
766 	size_t dst_size;
767 	u16 *buf = NULL;
768 	__le32 *xrgb8888 = NULL;
769 	struct iosys_map dst, src;
770 
771 	struct drm_framebuffer fb = {
772 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
773 		.pitches = { params->pitch, 0, 0 },
774 	};
775 
776 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch,
777 				       &params->clip, 0);
778 	KUNIT_ASSERT_GT(test, dst_size, 0);
779 
780 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
781 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
782 	iosys_map_set_vaddr(&dst, buf);
783 
784 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
785 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
786 	iosys_map_set_vaddr(&src, xrgb8888);
787 
788 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
789 		NULL : &result->dst_pitch;
790 
791 	drm_fb_xrgb8888_to_xrgb1555(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
792 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
793 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
794 
795 	buf = dst.vaddr; /* restore original value of buf */
796 	memset(buf, 0, dst_size);
797 
798 	int blit_result = 0;
799 
800 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB1555, &src, &fb, &params->clip,
801 				  &fmtcnv_state);
802 
803 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
804 
805 	KUNIT_EXPECT_FALSE(test, blit_result);
806 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
807 }
808 
drm_test_fb_xrgb8888_to_argb1555(struct kunit * test)809 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test)
810 {
811 	const struct convert_xrgb8888_case *params = test->param_value;
812 	const struct convert_to_argb1555_result *result = &params->argb1555_result;
813 	size_t dst_size;
814 	u16 *buf = NULL;
815 	__le32 *xrgb8888 = NULL;
816 	struct iosys_map dst, src;
817 
818 	struct drm_framebuffer fb = {
819 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
820 		.pitches = { params->pitch, 0, 0 },
821 	};
822 
823 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch,
824 				       &params->clip, 0);
825 	KUNIT_ASSERT_GT(test, dst_size, 0);
826 
827 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
828 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
829 	iosys_map_set_vaddr(&dst, buf);
830 
831 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
832 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
833 	iosys_map_set_vaddr(&src, xrgb8888);
834 
835 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
836 		NULL : &result->dst_pitch;
837 
838 	drm_fb_xrgb8888_to_argb1555(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
839 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
840 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
841 
842 	buf = dst.vaddr; /* restore original value of buf */
843 	memset(buf, 0, dst_size);
844 
845 	int blit_result = 0;
846 
847 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB1555, &src, &fb, &params->clip,
848 				  &fmtcnv_state);
849 
850 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
851 
852 	KUNIT_EXPECT_FALSE(test, blit_result);
853 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
854 }
855 
drm_test_fb_xrgb8888_to_rgba5551(struct kunit * test)856 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test)
857 {
858 	const struct convert_xrgb8888_case *params = test->param_value;
859 	const struct convert_to_rgba5551_result *result = &params->rgba5551_result;
860 	size_t dst_size;
861 	u16 *buf = NULL;
862 	__le32 *xrgb8888 = NULL;
863 	struct iosys_map dst, src;
864 
865 	struct drm_framebuffer fb = {
866 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
867 		.pitches = { params->pitch, 0, 0 },
868 	};
869 
870 	dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch,
871 				       &params->clip, 0);
872 	KUNIT_ASSERT_GT(test, dst_size, 0);
873 
874 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
875 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
876 	iosys_map_set_vaddr(&dst, buf);
877 
878 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
879 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
880 	iosys_map_set_vaddr(&src, xrgb8888);
881 
882 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
883 		NULL : &result->dst_pitch;
884 
885 	drm_fb_xrgb8888_to_rgba5551(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
886 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
887 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
888 
889 	buf = dst.vaddr; /* restore original value of buf */
890 	memset(buf, 0, dst_size);
891 
892 	int blit_result = 0;
893 
894 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGBA5551, &src, &fb, &params->clip,
895 				  &fmtcnv_state);
896 
897 	buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16));
898 
899 	KUNIT_EXPECT_FALSE(test, blit_result);
900 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
901 }
902 
drm_test_fb_xrgb8888_to_rgb888(struct kunit * test)903 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test)
904 {
905 	const struct convert_xrgb8888_case *params = test->param_value;
906 	const struct convert_to_rgb888_result *result = &params->rgb888_result;
907 	size_t dst_size;
908 	u8 *buf = NULL;
909 	__le32 *xrgb8888 = NULL;
910 	struct iosys_map dst, src;
911 
912 	struct drm_framebuffer fb = {
913 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
914 		.pitches = { params->pitch, 0, 0 },
915 	};
916 
917 	dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch,
918 				       &params->clip, 0);
919 	KUNIT_ASSERT_GT(test, dst_size, 0);
920 
921 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
922 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
923 	iosys_map_set_vaddr(&dst, buf);
924 
925 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
926 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
927 	iosys_map_set_vaddr(&src, xrgb8888);
928 
929 	/*
930 	 * RGB888 expected results are already in little-endian
931 	 * order, so there's no need to convert the test output.
932 	 */
933 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
934 		NULL : &result->dst_pitch;
935 
936 	drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
937 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
938 
939 	buf = dst.vaddr; /* restore original value of buf */
940 	memset(buf, 0, dst_size);
941 
942 	int blit_result = 0;
943 
944 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_RGB888, &src, &fb, &params->clip,
945 				  &fmtcnv_state);
946 
947 	KUNIT_EXPECT_FALSE(test, blit_result);
948 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
949 }
950 
drm_test_fb_xrgb8888_to_bgr888(struct kunit * test)951 static void drm_test_fb_xrgb8888_to_bgr888(struct kunit *test)
952 {
953 	const struct convert_xrgb8888_case *params = test->param_value;
954 	const struct convert_to_bgr888_result *result = &params->bgr888_result;
955 	size_t dst_size;
956 	u8 *buf = NULL;
957 	__le32 *xrgb8888 = NULL;
958 	struct iosys_map dst, src;
959 
960 	struct drm_framebuffer fb = {
961 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
962 		.pitches = { params->pitch, 0, 0 },
963 	};
964 
965 	dst_size = conversion_buf_size(DRM_FORMAT_BGR888, result->dst_pitch,
966 				       &params->clip, 0);
967 	KUNIT_ASSERT_GT(test, dst_size, 0);
968 
969 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
970 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
971 	iosys_map_set_vaddr(&dst, buf);
972 
973 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
974 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
975 	iosys_map_set_vaddr(&src, xrgb8888);
976 
977 	/*
978 	 * BGR888 expected results are already in little-endian
979 	 * order, so there's no need to convert the test output.
980 	 */
981 	drm_fb_xrgb8888_to_bgr888(&dst, &result->dst_pitch, &src, &fb, &params->clip,
982 				  &fmtcnv_state);
983 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
984 
985 	buf = dst.vaddr; /* restore original value of buf */
986 	memset(buf, 0, dst_size);
987 
988 	int blit_result = 0;
989 
990 	blit_result = drm_fb_blit(&dst, &result->dst_pitch, DRM_FORMAT_BGR888, &src, &fb, &params->clip,
991 				  &fmtcnv_state);
992 
993 	KUNIT_EXPECT_FALSE(test, blit_result);
994 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
995 }
996 
drm_test_fb_xrgb8888_to_argb8888(struct kunit * test)997 static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test)
998 {
999 	const struct convert_xrgb8888_case *params = test->param_value;
1000 	const struct convert_to_argb8888_result *result = &params->argb8888_result;
1001 	size_t dst_size;
1002 	u32 *buf = NULL;
1003 	__le32 *xrgb8888 = NULL;
1004 	struct iosys_map dst, src;
1005 
1006 	struct drm_framebuffer fb = {
1007 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1008 		.pitches = { params->pitch, 0, 0 },
1009 	};
1010 
1011 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888,
1012 				       result->dst_pitch, &params->clip, 0);
1013 	KUNIT_ASSERT_GT(test, dst_size, 0);
1014 
1015 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1016 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1017 	iosys_map_set_vaddr(&dst, buf);
1018 
1019 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1020 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1021 	iosys_map_set_vaddr(&src, xrgb8888);
1022 
1023 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1024 		NULL : &result->dst_pitch;
1025 
1026 	drm_fb_xrgb8888_to_argb8888(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1027 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1028 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1029 
1030 	buf = dst.vaddr; /* restore original value of buf */
1031 	memset(buf, 0, dst_size);
1032 
1033 	int blit_result = 0;
1034 
1035 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB8888, &src, &fb, &params->clip,
1036 				  &fmtcnv_state);
1037 
1038 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1039 
1040 	KUNIT_EXPECT_FALSE(test, blit_result);
1041 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1042 }
1043 
drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit * test)1044 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)
1045 {
1046 	const struct convert_xrgb8888_case *params = test->param_value;
1047 	const struct convert_to_xrgb2101010_result *result = &params->xrgb2101010_result;
1048 	size_t dst_size;
1049 	u32 *buf = NULL;
1050 	__le32 *xrgb8888 = NULL;
1051 	struct iosys_map dst, src;
1052 
1053 	struct drm_framebuffer fb = {
1054 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1055 		.pitches = { params->pitch, 0, 0 },
1056 	};
1057 
1058 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010,
1059 				       result->dst_pitch, &params->clip, 0);
1060 	KUNIT_ASSERT_GT(test, dst_size, 0);
1061 
1062 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1063 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1064 	iosys_map_set_vaddr(&dst, buf);
1065 
1066 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1067 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1068 	iosys_map_set_vaddr(&src, xrgb8888);
1069 
1070 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1071 		NULL : &result->dst_pitch;
1072 
1073 	drm_fb_xrgb8888_to_xrgb2101010(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1074 	buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32));
1075 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1076 
1077 	buf = dst.vaddr; /* restore original value of buf */
1078 	memset(buf, 0, dst_size);
1079 
1080 	int blit_result = 0;
1081 
1082 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB2101010, &src, &fb,
1083 				  &params->clip, &fmtcnv_state);
1084 
1085 	KUNIT_EXPECT_FALSE(test, blit_result);
1086 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1087 }
1088 
drm_test_fb_xrgb8888_to_argb2101010(struct kunit * test)1089 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test)
1090 {
1091 	const struct convert_xrgb8888_case *params = test->param_value;
1092 	const struct convert_to_argb2101010_result *result = &params->argb2101010_result;
1093 	size_t dst_size;
1094 	u32 *buf = NULL;
1095 	__le32 *xrgb8888 = NULL;
1096 	struct iosys_map dst, src;
1097 
1098 	struct drm_framebuffer fb = {
1099 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1100 		.pitches = { params->pitch, 0, 0 },
1101 	};
1102 
1103 	dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010,
1104 				       result->dst_pitch, &params->clip, 0);
1105 	KUNIT_ASSERT_GT(test, dst_size, 0);
1106 
1107 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1108 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1109 	iosys_map_set_vaddr(&dst, buf);
1110 
1111 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1112 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1113 	iosys_map_set_vaddr(&src, xrgb8888);
1114 
1115 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1116 		NULL : &result->dst_pitch;
1117 
1118 	drm_fb_xrgb8888_to_argb2101010(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1119 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1120 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1121 
1122 	buf = dst.vaddr; /* restore original value of buf */
1123 	memset(buf, 0, dst_size);
1124 
1125 	int blit_result = 0;
1126 
1127 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ARGB2101010, &src, &fb,
1128 				  &params->clip, &fmtcnv_state);
1129 
1130 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1131 
1132 	KUNIT_EXPECT_FALSE(test, blit_result);
1133 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1134 }
1135 
drm_test_fb_xrgb8888_to_mono(struct kunit * test)1136 static void drm_test_fb_xrgb8888_to_mono(struct kunit *test)
1137 {
1138 	const struct convert_xrgb8888_case *params = test->param_value;
1139 	const struct convert_to_mono_result *result = &params->mono_result;
1140 	size_t dst_size;
1141 	u8 *buf = NULL;
1142 	__le32 *xrgb8888 = NULL;
1143 	struct iosys_map dst, src;
1144 
1145 	struct drm_framebuffer fb = {
1146 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1147 		.pitches = { params->pitch, 0, 0 },
1148 	};
1149 
1150 	dst_size = conversion_buf_size(DRM_FORMAT_C1, result->dst_pitch, &params->clip, 0);
1151 
1152 	KUNIT_ASSERT_GT(test, dst_size, 0);
1153 
1154 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1155 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1156 	iosys_map_set_vaddr(&dst, buf);
1157 
1158 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1159 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1160 	iosys_map_set_vaddr(&src, xrgb8888);
1161 
1162 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1163 		NULL : &result->dst_pitch;
1164 
1165 	drm_fb_xrgb8888_to_mono(&dst, dst_pitch, &src, &fb, &params->clip, &fmtcnv_state);
1166 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1167 }
1168 
drm_test_fb_swab(struct kunit * test)1169 static void drm_test_fb_swab(struct kunit *test)
1170 {
1171 	const struct convert_xrgb8888_case *params = test->param_value;
1172 	const struct fb_swab_result *result = &params->swab_result;
1173 	size_t dst_size;
1174 	u32 *buf = NULL;
1175 	__le32 *xrgb8888 = NULL;
1176 	struct iosys_map dst, src;
1177 
1178 	struct drm_framebuffer fb = {
1179 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1180 		.pitches = { params->pitch, 0, 0 },
1181 	};
1182 
1183 	dst_size = conversion_buf_size(DRM_FORMAT_XRGB8888, result->dst_pitch, &params->clip, 0);
1184 
1185 	KUNIT_ASSERT_GT(test, dst_size, 0);
1186 
1187 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1188 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1189 	iosys_map_set_vaddr(&dst, buf);
1190 
1191 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1192 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1193 	iosys_map_set_vaddr(&src, xrgb8888);
1194 
1195 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1196 		NULL : &result->dst_pitch;
1197 
1198 	drm_fb_swab(&dst, dst_pitch, &src, &fb, &params->clip, false, &fmtcnv_state);
1199 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1200 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1201 
1202 	buf = dst.vaddr; /* restore original value of buf */
1203 	memset(buf, 0, dst_size);
1204 
1205 	int blit_result;
1206 
1207 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888 | DRM_FORMAT_BIG_ENDIAN,
1208 				  &src, &fb, &params->clip, &fmtcnv_state);
1209 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1210 
1211 	KUNIT_EXPECT_FALSE(test, blit_result);
1212 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1213 
1214 	buf = dst.vaddr;
1215 	memset(buf, 0, dst_size);
1216 
1217 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_BGRX8888, &src, &fb, &params->clip,
1218 				  &fmtcnv_state);
1219 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1220 
1221 	KUNIT_EXPECT_FALSE(test, blit_result);
1222 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1223 
1224 	buf = dst.vaddr;
1225 	memset(buf, 0, dst_size);
1226 
1227 	struct drm_format_info mock_format = *fb.format;
1228 
1229 	mock_format.format |= DRM_FORMAT_BIG_ENDIAN;
1230 	fb.format = &mock_format;
1231 
1232 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XRGB8888, &src, &fb, &params->clip,
1233 				  &fmtcnv_state);
1234 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1235 
1236 	KUNIT_EXPECT_FALSE(test, blit_result);
1237 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1238 }
1239 
drm_test_fb_xrgb8888_to_abgr8888(struct kunit * test)1240 static void drm_test_fb_xrgb8888_to_abgr8888(struct kunit *test)
1241 {
1242 	const struct convert_xrgb8888_case *params = test->param_value;
1243 	const struct convert_to_abgr8888_result *result = &params->abgr8888_result;
1244 	size_t dst_size;
1245 	u32 *buf = NULL;
1246 	__le32 *xrgb8888 = NULL;
1247 	struct iosys_map dst, src;
1248 
1249 	struct drm_framebuffer fb = {
1250 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1251 		.pitches = { params->pitch, 0, 0 },
1252 	};
1253 
1254 	dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, &params->clip, 0);
1255 
1256 	KUNIT_ASSERT_GT(test, dst_size, 0);
1257 
1258 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1259 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1260 	iosys_map_set_vaddr(&dst, buf);
1261 
1262 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1263 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1264 	iosys_map_set_vaddr(&src, xrgb8888);
1265 
1266 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1267 		NULL : &result->dst_pitch;
1268 
1269 	int blit_result = 0;
1270 
1271 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_ABGR8888, &src, &fb, &params->clip,
1272 				  &fmtcnv_state);
1273 
1274 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1275 
1276 	KUNIT_EXPECT_FALSE(test, blit_result);
1277 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1278 }
1279 
drm_test_fb_xrgb8888_to_xbgr8888(struct kunit * test)1280 static void drm_test_fb_xrgb8888_to_xbgr8888(struct kunit *test)
1281 {
1282 	const struct convert_xrgb8888_case *params = test->param_value;
1283 	const struct convert_to_xbgr8888_result *result = &params->xbgr8888_result;
1284 	size_t dst_size;
1285 	u32 *buf = NULL;
1286 	__le32 *xrgb8888 = NULL;
1287 	struct iosys_map dst, src;
1288 
1289 	struct drm_framebuffer fb = {
1290 		.format = drm_format_info(DRM_FORMAT_XRGB8888),
1291 		.pitches = { params->pitch, 0, 0 },
1292 	};
1293 
1294 	dst_size = conversion_buf_size(DRM_FORMAT_XBGR8888, result->dst_pitch, &params->clip, 0);
1295 
1296 	KUNIT_ASSERT_GT(test, dst_size, 0);
1297 
1298 	buf = kunit_kzalloc(test, dst_size, GFP_KERNEL);
1299 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf);
1300 	iosys_map_set_vaddr(&dst, buf);
1301 
1302 	xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE);
1303 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888);
1304 	iosys_map_set_vaddr(&src, xrgb8888);
1305 
1306 	const unsigned int *dst_pitch = (result->dst_pitch == TEST_USE_DEFAULT_PITCH) ?
1307 		NULL : &result->dst_pitch;
1308 
1309 	int blit_result = 0;
1310 
1311 	blit_result = drm_fb_blit(&dst, dst_pitch, DRM_FORMAT_XBGR8888, &src, &fb, &params->clip,
1312 				  &fmtcnv_state);
1313 
1314 	buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32));
1315 
1316 	KUNIT_EXPECT_FALSE(test, blit_result);
1317 	KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size);
1318 }
1319 
1320 struct clip_offset_case {
1321 	const char *name;
1322 	unsigned int pitch;
1323 	u32 format;
1324 	struct drm_rect clip;
1325 	unsigned int expected_offset;
1326 };
1327 
1328 static struct clip_offset_case clip_offset_cases[] = {
1329 	{
1330 		.name = "pass through",
1331 		.pitch = TEST_USE_DEFAULT_PITCH,
1332 		.format = DRM_FORMAT_XRGB8888,
1333 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1334 		.expected_offset = 0
1335 	},
1336 	{
1337 		.name = "horizontal offset",
1338 		.pitch = TEST_USE_DEFAULT_PITCH,
1339 		.format = DRM_FORMAT_XRGB8888,
1340 		.clip = DRM_RECT_INIT(1, 0, 3, 3),
1341 		.expected_offset = 4,
1342 	},
1343 	{
1344 		.name = "vertical offset",
1345 		.pitch = TEST_USE_DEFAULT_PITCH,
1346 		.format = DRM_FORMAT_XRGB8888,
1347 		.clip = DRM_RECT_INIT(0, 1, 3, 3),
1348 		.expected_offset = 12,
1349 	},
1350 	{
1351 		.name = "horizontal and vertical offset",
1352 		.pitch = TEST_USE_DEFAULT_PITCH,
1353 		.format = DRM_FORMAT_XRGB8888,
1354 		.clip = DRM_RECT_INIT(1, 1, 3, 3),
1355 		.expected_offset = 16,
1356 	},
1357 	{
1358 		.name = "horizontal offset (custom pitch)",
1359 		.pitch = 20,
1360 		.format = DRM_FORMAT_XRGB8888,
1361 		.clip = DRM_RECT_INIT(1, 0, 3, 3),
1362 		.expected_offset = 4,
1363 	},
1364 	{
1365 		.name = "vertical offset (custom pitch)",
1366 		.pitch = 20,
1367 		.format = DRM_FORMAT_XRGB8888,
1368 		.clip = DRM_RECT_INIT(0, 1, 3, 3),
1369 		.expected_offset = 20,
1370 	},
1371 	{
1372 		.name = "horizontal and vertical offset (custom pitch)",
1373 		.pitch = 20,
1374 		.format = DRM_FORMAT_XRGB8888,
1375 		.clip = DRM_RECT_INIT(1, 1, 3, 3),
1376 		.expected_offset = 24,
1377 	},
1378 };
1379 
clip_offset_case_desc(struct clip_offset_case * t,char * desc)1380 static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
1381 {
1382 	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1383 }
1384 
1385 KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);
1386 
drm_test_fb_clip_offset(struct kunit * test)1387 static void drm_test_fb_clip_offset(struct kunit *test)
1388 {
1389 	const struct clip_offset_case *params = test->param_value;
1390 	const struct drm_format_info *format_info = drm_format_info(params->format);
1391 
1392 	unsigned int offset;
1393 	unsigned int pitch = params->pitch;
1394 
1395 	if (pitch == TEST_USE_DEFAULT_PITCH)
1396 		pitch = drm_format_info_min_pitch(format_info, 0,
1397 						  drm_rect_width(&params->clip));
1398 
1399 	/*
1400 	 * Assure that the pitch is not zero, because this will inevitable cause the
1401 	 * wrong expected result
1402 	 */
1403 	KUNIT_ASSERT_NE(test, pitch, 0);
1404 
1405 	offset = drm_fb_clip_offset(pitch, format_info, &params->clip);
1406 
1407 	KUNIT_EXPECT_EQ(test, offset, params->expected_offset);
1408 }
1409 
1410 struct fb_build_fourcc_list_case {
1411 	const char *name;
1412 	u32 native_fourccs[TEST_BUF_SIZE];
1413 	size_t native_fourccs_size;
1414 	u32 expected[TEST_BUF_SIZE];
1415 	size_t expected_fourccs_size;
1416 };
1417 
1418 static struct fb_build_fourcc_list_case fb_build_fourcc_list_cases[] = {
1419 	{
1420 		.name = "no native formats",
1421 		.native_fourccs = { },
1422 		.native_fourccs_size = 0,
1423 		.expected = { DRM_FORMAT_XRGB8888 },
1424 		.expected_fourccs_size = 1,
1425 	},
1426 	{
1427 		.name = "XRGB8888 as native format",
1428 		.native_fourccs = { DRM_FORMAT_XRGB8888 },
1429 		.native_fourccs_size = 1,
1430 		.expected = { DRM_FORMAT_XRGB8888 },
1431 		.expected_fourccs_size = 1,
1432 	},
1433 	{
1434 		.name = "remove duplicates",
1435 		.native_fourccs = {
1436 			DRM_FORMAT_XRGB8888,
1437 			DRM_FORMAT_XRGB8888,
1438 			DRM_FORMAT_RGB888,
1439 			DRM_FORMAT_RGB888,
1440 			DRM_FORMAT_RGB888,
1441 			DRM_FORMAT_XRGB8888,
1442 			DRM_FORMAT_RGB888,
1443 			DRM_FORMAT_RGB565,
1444 			DRM_FORMAT_RGB888,
1445 			DRM_FORMAT_XRGB8888,
1446 			DRM_FORMAT_RGB565,
1447 			DRM_FORMAT_RGB565,
1448 			DRM_FORMAT_XRGB8888,
1449 		},
1450 		.native_fourccs_size = 11,
1451 		.expected = {
1452 			DRM_FORMAT_XRGB8888,
1453 			DRM_FORMAT_RGB888,
1454 			DRM_FORMAT_RGB565,
1455 		},
1456 		.expected_fourccs_size = 3,
1457 	},
1458 	{
1459 		.name = "convert alpha formats",
1460 		.native_fourccs = {
1461 			DRM_FORMAT_ARGB1555,
1462 			DRM_FORMAT_ABGR1555,
1463 			DRM_FORMAT_RGBA5551,
1464 			DRM_FORMAT_BGRA5551,
1465 			DRM_FORMAT_ARGB8888,
1466 			DRM_FORMAT_ABGR8888,
1467 			DRM_FORMAT_RGBA8888,
1468 			DRM_FORMAT_BGRA8888,
1469 			DRM_FORMAT_ARGB2101010,
1470 			DRM_FORMAT_ABGR2101010,
1471 			DRM_FORMAT_RGBA1010102,
1472 			DRM_FORMAT_BGRA1010102,
1473 		},
1474 		.native_fourccs_size = 12,
1475 		.expected = {
1476 			DRM_FORMAT_XRGB1555,
1477 			DRM_FORMAT_XBGR1555,
1478 			DRM_FORMAT_RGBX5551,
1479 			DRM_FORMAT_BGRX5551,
1480 			DRM_FORMAT_XRGB8888,
1481 			DRM_FORMAT_XBGR8888,
1482 			DRM_FORMAT_RGBX8888,
1483 			DRM_FORMAT_BGRX8888,
1484 			DRM_FORMAT_XRGB2101010,
1485 			DRM_FORMAT_XBGR2101010,
1486 			DRM_FORMAT_RGBX1010102,
1487 			DRM_FORMAT_BGRX1010102,
1488 		},
1489 		.expected_fourccs_size = 12,
1490 	},
1491 	{
1492 		.name = "random formats",
1493 		.native_fourccs = {
1494 			DRM_FORMAT_Y212,
1495 			DRM_FORMAT_ARGB1555,
1496 			DRM_FORMAT_ABGR16161616F,
1497 			DRM_FORMAT_C8,
1498 			DRM_FORMAT_BGR888,
1499 			DRM_FORMAT_XRGB1555,
1500 			DRM_FORMAT_RGBA5551,
1501 			DRM_FORMAT_BGR565_A8,
1502 			DRM_FORMAT_R10,
1503 			DRM_FORMAT_XYUV8888,
1504 		},
1505 		.native_fourccs_size = 10,
1506 		.expected = {
1507 			DRM_FORMAT_Y212,
1508 			DRM_FORMAT_XRGB1555,
1509 			DRM_FORMAT_ABGR16161616F,
1510 			DRM_FORMAT_C8,
1511 			DRM_FORMAT_BGR888,
1512 			DRM_FORMAT_RGBX5551,
1513 			DRM_FORMAT_BGR565_A8,
1514 			DRM_FORMAT_R10,
1515 			DRM_FORMAT_XYUV8888,
1516 			DRM_FORMAT_XRGB8888,
1517 		},
1518 		.expected_fourccs_size = 10,
1519 	},
1520 };
1521 
fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case * t,char * desc)1522 static void fb_build_fourcc_list_case_desc(struct fb_build_fourcc_list_case *t, char *desc)
1523 {
1524 	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1525 }
1526 
1527 KUNIT_ARRAY_PARAM(fb_build_fourcc_list, fb_build_fourcc_list_cases, fb_build_fourcc_list_case_desc);
1528 
drm_test_fb_build_fourcc_list(struct kunit * test)1529 static void drm_test_fb_build_fourcc_list(struct kunit *test)
1530 {
1531 	const struct fb_build_fourcc_list_case *params = test->param_value;
1532 	u32 fourccs_out[TEST_BUF_SIZE] = {0};
1533 	size_t nfourccs_out;
1534 	struct drm_device *drm;
1535 	struct device *dev;
1536 
1537 	dev = drm_kunit_helper_alloc_device(test);
1538 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
1539 
1540 	drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET);
1541 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
1542 
1543 	nfourccs_out = drm_fb_build_fourcc_list(drm, params->native_fourccs,
1544 						params->native_fourccs_size,
1545 						fourccs_out, TEST_BUF_SIZE);
1546 
1547 	KUNIT_EXPECT_EQ(test, nfourccs_out, params->expected_fourccs_size);
1548 	KUNIT_EXPECT_MEMEQ(test, fourccs_out, params->expected, TEST_BUF_SIZE);
1549 }
1550 
1551 struct fb_memcpy_case {
1552 	const char *name;
1553 	u32 format;
1554 	struct drm_rect clip;
1555 	unsigned int src_pitches[DRM_FORMAT_MAX_PLANES];
1556 	const u32 src[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1557 	unsigned int dst_pitches[DRM_FORMAT_MAX_PLANES];
1558 	const u32 expected[DRM_FORMAT_MAX_PLANES][TEST_BUF_SIZE];
1559 };
1560 
1561 /* The `src` and `expected` buffers are u32 arrays. To deal with planes that
1562  * have a cpp != 4 the values are stored together on the same u32 number in a
1563  * way so the order in memory is correct in a little-endian machine.
1564  *
1565  * Because of that, on some occasions, parts of a u32 will not be part of the
1566  * test, to make this explicit the 0xFF byte is used on those parts.
1567  */
1568 
1569 static struct fb_memcpy_case fb_memcpy_cases[] = {
1570 	{
1571 		.name = "single_pixel_source_buffer",
1572 		.format = DRM_FORMAT_XRGB8888,
1573 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
1574 		.src_pitches = { 1 * 4 },
1575 		.src = {{ 0x01020304 }},
1576 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1577 		.expected = {{ 0x01020304 }},
1578 	},
1579 	{
1580 		.name = "single_pixel_source_buffer",
1581 		.format = DRM_FORMAT_XRGB8888_A8,
1582 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
1583 		.src_pitches = { 1 * 4, 1 },
1584 		.src = {
1585 			{ 0x01020304 },
1586 			{ 0xFFFFFF01 },
1587 		},
1588 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1589 		.expected = {
1590 			{ 0x01020304 },
1591 			{ 0x00000001 },
1592 		},
1593 	},
1594 	{
1595 		.name = "single_pixel_source_buffer",
1596 		.format = DRM_FORMAT_YUV444,
1597 		.clip = DRM_RECT_INIT(0, 0, 1, 1),
1598 		.src_pitches = { 1, 1, 1 },
1599 		.src = {
1600 			{ 0xFFFFFF01 },
1601 			{ 0xFFFFFF01 },
1602 			{ 0xFFFFFF01 },
1603 		},
1604 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1605 		.expected = {
1606 			{ 0x00000001 },
1607 			{ 0x00000001 },
1608 			{ 0x00000001 },
1609 		},
1610 	},
1611 	{
1612 		.name = "single_pixel_clip_rectangle",
1613 		.format = DRM_FORMAT_XBGR8888,
1614 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
1615 		.src_pitches = { 2 * 4 },
1616 		.src = {
1617 			{
1618 				0x00000000, 0x00000000,
1619 				0x00000000, 0x01020304,
1620 			},
1621 		},
1622 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1623 		.expected = {
1624 			{ 0x01020304 },
1625 		},
1626 	},
1627 	{
1628 		.name = "single_pixel_clip_rectangle",
1629 		.format = DRM_FORMAT_XRGB8888_A8,
1630 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
1631 		.src_pitches = { 2 * 4, 2 * 1 },
1632 		.src = {
1633 			{
1634 				0x00000000, 0x00000000,
1635 				0x00000000, 0x01020304,
1636 			},
1637 			{ 0x01000000 },
1638 		},
1639 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1640 		.expected = {
1641 			{ 0x01020304 },
1642 			{ 0x00000001 },
1643 		},
1644 	},
1645 	{
1646 		.name = "single_pixel_clip_rectangle",
1647 		.format = DRM_FORMAT_YUV444,
1648 		.clip = DRM_RECT_INIT(1, 1, 1, 1),
1649 		.src_pitches = { 2 * 1, 2 * 1, 2 * 1 },
1650 		.src = {
1651 			{ 0x01000000 },
1652 			{ 0x01000000 },
1653 			{ 0x01000000 },
1654 		},
1655 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1656 		.expected = {
1657 			{ 0x00000001 },
1658 			{ 0x00000001 },
1659 			{ 0x00000001 },
1660 		},
1661 	},
1662 	{
1663 		.name = "well_known_colors",
1664 		.format = DRM_FORMAT_XBGR8888,
1665 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
1666 		.src_pitches = { 4 * 4 },
1667 		.src = {
1668 			{
1669 				0x00000000, 0x00000000, 0x00000000, 0x00000000,
1670 				0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000,
1671 				0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000,
1672 				0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000,
1673 				0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000,
1674 			},
1675 		},
1676 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1677 		.expected = {
1678 			{
1679 				0x11FFFFFF, 0x22000000,
1680 				0x33FF0000, 0x4400FF00,
1681 				0x550000FF, 0x66FF00FF,
1682 				0x77FFFF00, 0x8800FFFF,
1683 			},
1684 		},
1685 	},
1686 	{
1687 		.name = "well_known_colors",
1688 		.format = DRM_FORMAT_XRGB8888_A8,
1689 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
1690 		.src_pitches = { 4 * 4, 4 * 1 },
1691 		.src = {
1692 			{
1693 				0x00000000, 0x00000000, 0x00000000, 0x00000000,
1694 				0x00000000, 0xFFFFFFFF, 0xFF000000, 0x00000000,
1695 				0x00000000, 0xFFFF0000, 0xFF00FF00, 0x00000000,
1696 				0x00000000, 0xFF0000FF, 0xFFFF00FF, 0x00000000,
1697 				0x00000000, 0xFFFFFF00, 0xFF00FFFF, 0x00000000,
1698 			},
1699 			{
1700 				0x00000000,
1701 				0x00221100,
1702 				0x00443300,
1703 				0x00665500,
1704 				0x00887700,
1705 			},
1706 		},
1707 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1708 		.expected = {
1709 			{
1710 				0xFFFFFFFF, 0xFF000000,
1711 				0xFFFF0000, 0xFF00FF00,
1712 				0xFF0000FF, 0xFFFF00FF,
1713 				0xFFFFFF00, 0xFF00FFFF,
1714 			},
1715 			{
1716 				0x44332211,
1717 				0x88776655,
1718 			},
1719 		},
1720 	},
1721 	{
1722 		.name = "well_known_colors",
1723 		.format = DRM_FORMAT_YUV444,
1724 		.clip = DRM_RECT_INIT(1, 1, 2, 4),
1725 		.src_pitches = { 4 * 1, 4 * 1, 4 * 1 },
1726 		.src = {
1727 			{
1728 				0x00000000,
1729 				0x0000FF00,
1730 				0x00954C00,
1731 				0x00691D00,
1732 				0x00B2E100,
1733 			},
1734 			{
1735 				0x00000000,
1736 				0x00000000,
1737 				0x00BEDE00,
1738 				0x00436500,
1739 				0x00229B00,
1740 			},
1741 			{
1742 				0x00000000,
1743 				0x00000000,
1744 				0x007E9C00,
1745 				0x0083E700,
1746 				0x00641A00,
1747 			},
1748 		},
1749 		.dst_pitches = { TEST_USE_DEFAULT_PITCH },
1750 		.expected = {
1751 			{
1752 				0x954C00FF,
1753 				0xB2E1691D,
1754 			},
1755 			{
1756 				0xBEDE0000,
1757 				0x229B4365,
1758 			},
1759 			{
1760 				0x7E9C0000,
1761 				0x641A83E7,
1762 			},
1763 		},
1764 	},
1765 	{
1766 		.name = "destination_pitch",
1767 		.format = DRM_FORMAT_XBGR8888,
1768 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1769 		.src_pitches = { 3 * 4 },
1770 		.src = {
1771 			{
1772 				0xA10E449C, 0xB1114D05, 0xC1A8F303,
1773 				0xD16CF073, 0xA20E449C, 0xB2114D05,
1774 				0xC2A80303, 0xD26CF073, 0xA30E449C,
1775 			},
1776 		},
1777 		.dst_pitches = { 5 * 4 },
1778 		.expected = {
1779 			{
1780 				0xA10E449C, 0xB1114D05, 0xC1A8F303, 0x00000000, 0x00000000,
1781 				0xD16CF073, 0xA20E449C, 0xB2114D05, 0x00000000, 0x00000000,
1782 				0xC2A80303, 0xD26CF073, 0xA30E449C, 0x00000000, 0x00000000,
1783 			},
1784 		},
1785 	},
1786 	{
1787 		.name = "destination_pitch",
1788 		.format = DRM_FORMAT_XRGB8888_A8,
1789 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1790 		.src_pitches = { 3 * 4, 3 * 1 },
1791 		.src = {
1792 			{
1793 				0xFF0E449C, 0xFF114D05, 0xFFA8F303,
1794 				0xFF6CF073, 0xFF0E449C, 0xFF114D05,
1795 				0xFFA80303, 0xFF6CF073, 0xFF0E449C,
1796 			},
1797 			{
1798 				0xB2C1B1A1,
1799 				0xD2A3D1A2,
1800 				0xFFFFFFC2,
1801 			},
1802 		},
1803 		.dst_pitches = { 5 * 4, 5 * 1 },
1804 		.expected = {
1805 			{
1806 				0xFF0E449C, 0xFF114D05, 0xFFA8F303, 0x00000000, 0x00000000,
1807 				0xFF6CF073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000,
1808 				0xFFA80303, 0xFF6CF073, 0xFF0E449C, 0x00000000, 0x00000000,
1809 			},
1810 			{
1811 				0x00C1B1A1,
1812 				0xD1A2B200,
1813 				0xD2A30000,
1814 				0xFF0000C2,
1815 			},
1816 		},
1817 	},
1818 	{
1819 		.name = "destination_pitch",
1820 		.format = DRM_FORMAT_YUV444,
1821 		.clip = DRM_RECT_INIT(0, 0, 3, 3),
1822 		.src_pitches = { 3 * 1, 3 * 1, 3 * 1 },
1823 		.src = {
1824 			{
1825 				0xBAC1323D,
1826 				0xBA34323D,
1827 				0xFFFFFF3D,
1828 			},
1829 			{
1830 				0xE1ABEC2A,
1831 				0xE1EAEC2A,
1832 				0xFFFFFF2A,
1833 			},
1834 			{
1835 				0xBCEBE4D7,
1836 				0xBC65E4D7,
1837 				0xFFFFFFD7,
1838 			},
1839 		},
1840 		.dst_pitches = { 5 * 1, 5 * 1, 5 * 1 },
1841 		.expected = {
1842 			{
1843 				0x00C1323D,
1844 				0x323DBA00,
1845 				0xBA340000,
1846 				0xFF00003D,
1847 			},
1848 			{
1849 				0x00ABEC2A,
1850 				0xEC2AE100,
1851 				0xE1EA0000,
1852 				0xFF00002A,
1853 			},
1854 			{
1855 				0x00EBE4D7,
1856 				0xE4D7BC00,
1857 				0xBC650000,
1858 				0xFF0000D7,
1859 			},
1860 		},
1861 	},
1862 };
1863 
fb_memcpy_case_desc(struct fb_memcpy_case * t,char * desc)1864 static void fb_memcpy_case_desc(struct fb_memcpy_case *t, char *desc)
1865 {
1866 	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s: %p4cc", t->name, &t->format);
1867 }
1868 
1869 KUNIT_ARRAY_PARAM(fb_memcpy, fb_memcpy_cases, fb_memcpy_case_desc);
1870 
drm_test_fb_memcpy(struct kunit * test)1871 static void drm_test_fb_memcpy(struct kunit *test)
1872 {
1873 	const struct fb_memcpy_case *params = test->param_value;
1874 	size_t dst_size[DRM_FORMAT_MAX_PLANES] = { 0 };
1875 	u32 *buf[DRM_FORMAT_MAX_PLANES] = { 0 };
1876 	__le32 *src_cp[DRM_FORMAT_MAX_PLANES] = { 0 };
1877 	__le32 *expected[DRM_FORMAT_MAX_PLANES] = { 0 };
1878 	struct iosys_map dst[DRM_FORMAT_MAX_PLANES];
1879 	struct iosys_map src[DRM_FORMAT_MAX_PLANES];
1880 
1881 	struct drm_framebuffer fb = {
1882 		.format = drm_format_info(params->format),
1883 	};
1884 
1885 	memcpy(fb.pitches, params->src_pitches, DRM_FORMAT_MAX_PLANES * sizeof(int));
1886 
1887 	for (size_t i = 0; i < fb.format->num_planes; i++) {
1888 		dst_size[i] = conversion_buf_size(params->format, params->dst_pitches[i],
1889 						  &params->clip, i);
1890 		KUNIT_ASSERT_GT(test, dst_size[i], 0);
1891 
1892 		buf[i] = kunit_kzalloc(test, dst_size[i], GFP_KERNEL);
1893 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf[i]);
1894 		iosys_map_set_vaddr(&dst[i], buf[i]);
1895 
1896 		src_cp[i] = cpubuf_to_le32(test, params->src[i], TEST_BUF_SIZE);
1897 		iosys_map_set_vaddr(&src[i], src_cp[i]);
1898 	}
1899 
1900 	const unsigned int *dst_pitches = params->dst_pitches[0] == TEST_USE_DEFAULT_PITCH ? NULL :
1901 		params->dst_pitches;
1902 
1903 	drm_fb_memcpy(dst, dst_pitches, src, &fb, &params->clip);
1904 
1905 	for (size_t i = 0; i < fb.format->num_planes; i++) {
1906 		expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1907 		KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1908 				       "Failed expectation on plane %zu", i);
1909 
1910 		memset(buf[i], 0, dst_size[i]);
1911 	}
1912 
1913 	int blit_result;
1914 
1915 	blit_result = drm_fb_blit(dst, dst_pitches, params->format, src, &fb, &params->clip,
1916 				  &fmtcnv_state);
1917 
1918 	KUNIT_EXPECT_FALSE(test, blit_result);
1919 	for (size_t i = 0; i < fb.format->num_planes; i++) {
1920 		expected[i] = cpubuf_to_le32(test, params->expected[i], TEST_BUF_SIZE);
1921 		KUNIT_EXPECT_MEMEQ_MSG(test, buf[i], expected[i], dst_size[i],
1922 				       "Failed expectation on plane %zu", i);
1923 	}
1924 }
1925 
1926 static struct kunit_case drm_format_helper_test_cases[] = {
1927 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params),
1928 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params),
1929 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params),
1930 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params),
1931 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params),
1932 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params),
1933 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params),
1934 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_bgr888, convert_xrgb8888_gen_params),
1935 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params),
1936 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params),
1937 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params),
1938 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_mono, convert_xrgb8888_gen_params),
1939 	KUNIT_CASE_PARAM(drm_test_fb_swab, convert_xrgb8888_gen_params),
1940 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xbgr8888, convert_xrgb8888_gen_params),
1941 	KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_abgr8888, convert_xrgb8888_gen_params),
1942 	KUNIT_CASE_PARAM(drm_test_fb_clip_offset, clip_offset_gen_params),
1943 	KUNIT_CASE_PARAM(drm_test_fb_build_fourcc_list, fb_build_fourcc_list_gen_params),
1944 	KUNIT_CASE_PARAM(drm_test_fb_memcpy, fb_memcpy_gen_params),
1945 	{}
1946 };
1947 
1948 static struct kunit_suite drm_format_helper_test_suite = {
1949 	.name = "drm_format_helper_test",
1950 	.test_cases = drm_format_helper_test_cases,
1951 };
1952 
1953 kunit_test_suite(drm_format_helper_test_suite);
1954 
1955 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
1956 MODULE_LICENSE("GPL");
1957 MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
1958