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