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