Merge tag 'loongarch-6.8' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai...
[linux-2.6-microblaze.git] / drivers / gpu / drm / tests / drm_format_helper_test.c
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_argb8888_result {
64         unsigned int dst_pitch;
65         const u32 expected[TEST_BUF_SIZE];
66 };
67
68 struct convert_to_xrgb2101010_result {
69         unsigned int dst_pitch;
70         const u32 expected[TEST_BUF_SIZE];
71 };
72
73 struct convert_to_argb2101010_result {
74         unsigned int dst_pitch;
75         const u32 expected[TEST_BUF_SIZE];
76 };
77
78 struct convert_to_mono_result {
79         unsigned int dst_pitch;
80         const u8 expected[TEST_BUF_SIZE];
81 };
82
83 struct fb_swab_result {
84         unsigned int dst_pitch;
85         const u32 expected[TEST_BUF_SIZE];
86 };
87
88 struct convert_to_xbgr8888_result {
89         unsigned int dst_pitch;
90         const u32 expected[TEST_BUF_SIZE];
91 };
92
93 struct convert_to_abgr8888_result {
94         unsigned int dst_pitch;
95         const u32 expected[TEST_BUF_SIZE];
96 };
97
98 struct 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
119 static 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  */
540 static 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
554 static 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
569 static 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
584 static __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
599 static 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
605 KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases,
606                   convert_xrgb8888_case_desc);
607
608 static 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
641 static 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
674 static 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
728 static 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
775 static 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
822 static 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
869 static 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
917 static 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
964 static 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
1009 static 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
1056 static 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
1089 static 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
1160 static 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
1200 static 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
1240 struct 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
1248 static 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
1300 static void clip_offset_case_desc(struct clip_offset_case *t, char *desc)
1301 {
1302         strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
1303 }
1304
1305 KUNIT_ARRAY_PARAM(clip_offset, clip_offset_cases, clip_offset_case_desc);
1306
1307 static 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
1330 struct 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
1338 static 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
1442 static 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
1447 KUNIT_ARRAY_PARAM(fb_build_fourcc_list, fb_build_fourcc_list_cases, fb_build_fourcc_list_case_desc);
1448
1449 static 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
1471 struct 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
1489 static 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
1784 static 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
1789 KUNIT_ARRAY_PARAM(fb_memcpy, fb_memcpy_cases, fb_memcpy_case_desc);
1790
1791 static 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
1846 static 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
1867 static struct kunit_suite drm_format_helper_test_suite = {
1868         .name = "drm_format_helper_test",
1869         .test_cases = drm_format_helper_test_cases,
1870 };
1871
1872 kunit_test_suite(drm_format_helper_test_suite);
1873
1874 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs");
1875 MODULE_LICENSE("GPL");
1876 MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");