1 // SPDX-License-Identifier: GPL-2.0+ 2 3 #include <kunit/test.h> 4 5 #include <drm/drm_device.h> 6 #include <drm/drm_file.h> 7 #include <drm/drm_format_helper.h> 8 #include <drm/drm_fourcc.h> 9 #include <drm/drm_framebuffer.h> 10 #include <drm/drm_gem_framebuffer_helper.h> 11 #include <drm/drm_mode.h> 12 #include <drm/drm_print.h> 13 #include <drm/drm_rect.h> 14 15 #include "../drm_crtc_internal.h" 16 17 #define TEST_BUF_SIZE 50 18 19 struct convert_to_gray8_result { 20 unsigned int dst_pitch; 21 const u8 expected[TEST_BUF_SIZE]; 22 }; 23 24 struct convert_to_rgb332_result { 25 unsigned int dst_pitch; 26 const u8 expected[TEST_BUF_SIZE]; 27 }; 28 29 struct convert_to_rgb565_result { 30 unsigned int dst_pitch; 31 const u16 expected[TEST_BUF_SIZE]; 32 const u16 expected_swab[TEST_BUF_SIZE]; 33 }; 34 35 struct convert_to_xrgb1555_result { 36 unsigned int dst_pitch; 37 const u16 expected[TEST_BUF_SIZE]; 38 }; 39 40 struct convert_to_argb1555_result { 41 unsigned int dst_pitch; 42 const u16 expected[TEST_BUF_SIZE]; 43 }; 44 45 struct convert_to_rgba5551_result { 46 unsigned int dst_pitch; 47 const u16 expected[TEST_BUF_SIZE]; 48 }; 49 50 struct convert_to_rgb888_result { 51 unsigned int dst_pitch; 52 const u8 expected[TEST_BUF_SIZE]; 53 }; 54 55 struct convert_to_argb8888_result { 56 unsigned int dst_pitch; 57 const u32 expected[TEST_BUF_SIZE]; 58 }; 59 60 struct convert_to_xrgb2101010_result { 61 unsigned int dst_pitch; 62 const u32 expected[TEST_BUF_SIZE]; 63 }; 64 65 struct convert_to_argb2101010_result { 66 unsigned int dst_pitch; 67 const u32 expected[TEST_BUF_SIZE]; 68 }; 69 70 struct convert_xrgb8888_case { 71 const char *name; 72 unsigned int pitch; 73 struct drm_rect clip; 74 const u32 xrgb8888[TEST_BUF_SIZE]; 75 struct convert_to_gray8_result gray8_result; 76 struct convert_to_rgb332_result rgb332_result; 77 struct convert_to_rgb565_result rgb565_result; 78 struct convert_to_xrgb1555_result xrgb1555_result; 79 struct convert_to_argb1555_result argb1555_result; 80 struct convert_to_rgba5551_result rgba5551_result; 81 struct convert_to_rgb888_result rgb888_result; 82 struct convert_to_argb8888_result argb8888_result; 83 struct convert_to_xrgb2101010_result xrgb2101010_result; 84 struct convert_to_argb2101010_result argb2101010_result; 85 }; 86 87 static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { 88 { 89 .name = "single_pixel_source_buffer", 90 .pitch = 1 * 4, 91 .clip = DRM_RECT_INIT(0, 0, 1, 1), 92 .xrgb8888 = { 0x01FF0000 }, 93 .gray8_result = { 94 .dst_pitch = 0, 95 .expected = { 0x4C }, 96 }, 97 .rgb332_result = { 98 .dst_pitch = 0, 99 .expected = { 0xE0 }, 100 }, 101 .rgb565_result = { 102 .dst_pitch = 0, 103 .expected = { 0xF800 }, 104 .expected_swab = { 0x00F8 }, 105 }, 106 .xrgb1555_result = { 107 .dst_pitch = 0, 108 .expected = { 0x7C00 }, 109 }, 110 .argb1555_result = { 111 .dst_pitch = 0, 112 .expected = { 0xFC00 }, 113 }, 114 .rgba5551_result = { 115 .dst_pitch = 0, 116 .expected = { 0xF801 }, 117 }, 118 .rgb888_result = { 119 .dst_pitch = 0, 120 .expected = { 0x00, 0x00, 0xFF }, 121 }, 122 .argb8888_result = { 123 .dst_pitch = 0, 124 .expected = { 0xFFFF0000 }, 125 }, 126 .xrgb2101010_result = { 127 .dst_pitch = 0, 128 .expected = { 0x3FF00000 }, 129 }, 130 .argb2101010_result = { 131 .dst_pitch = 0, 132 .expected = { 0xFFF00000 }, 133 }, 134 }, 135 { 136 .name = "single_pixel_clip_rectangle", 137 .pitch = 2 * 4, 138 .clip = DRM_RECT_INIT(1, 1, 1, 1), 139 .xrgb8888 = { 140 0x00000000, 0x00000000, 141 0x00000000, 0x10FF0000, 142 }, 143 .gray8_result = { 144 .dst_pitch = 0, 145 .expected = { 0x4C }, 146 }, 147 .rgb332_result = { 148 .dst_pitch = 0, 149 .expected = { 0xE0 }, 150 }, 151 .rgb565_result = { 152 .dst_pitch = 0, 153 .expected = { 0xF800 }, 154 .expected_swab = { 0x00F8 }, 155 }, 156 .xrgb1555_result = { 157 .dst_pitch = 0, 158 .expected = { 0x7C00 }, 159 }, 160 .argb1555_result = { 161 .dst_pitch = 0, 162 .expected = { 0xFC00 }, 163 }, 164 .rgba5551_result = { 165 .dst_pitch = 0, 166 .expected = { 0xF801 }, 167 }, 168 .rgb888_result = { 169 .dst_pitch = 0, 170 .expected = { 0x00, 0x00, 0xFF }, 171 }, 172 .argb8888_result = { 173 .dst_pitch = 0, 174 .expected = { 0xFFFF0000 }, 175 }, 176 .xrgb2101010_result = { 177 .dst_pitch = 0, 178 .expected = { 0x3FF00000 }, 179 }, 180 .argb2101010_result = { 181 .dst_pitch = 0, 182 .expected = { 0xFFF00000 }, 183 }, 184 }, 185 { 186 /* Well known colors: White, black, red, green, blue, magenta, 187 * yellow and cyan. Different values for the X in XRGB8888 to 188 * make sure it is ignored. Partial clip area. 189 */ 190 .name = "well_known_colors", 191 .pitch = 4 * 4, 192 .clip = DRM_RECT_INIT(1, 1, 2, 4), 193 .xrgb8888 = { 194 0x00000000, 0x00000000, 0x00000000, 0x00000000, 195 0x00000000, 0x11FFFFFF, 0x22000000, 0x00000000, 196 0x00000000, 0x33FF0000, 0x4400FF00, 0x00000000, 197 0x00000000, 0x550000FF, 0x66FF00FF, 0x00000000, 198 0x00000000, 0x77FFFF00, 0x8800FFFF, 0x00000000, 199 }, 200 .gray8_result = { 201 .dst_pitch = 0, 202 .expected = { 203 0xFF, 0x00, 204 0x4C, 0x99, 205 0x19, 0x66, 206 0xE5, 0xB2, 207 }, 208 }, 209 .rgb332_result = { 210 .dst_pitch = 0, 211 .expected = { 212 0xFF, 0x00, 213 0xE0, 0x1C, 214 0x03, 0xE3, 215 0xFC, 0x1F, 216 }, 217 }, 218 .rgb565_result = { 219 .dst_pitch = 0, 220 .expected = { 221 0xFFFF, 0x0000, 222 0xF800, 0x07E0, 223 0x001F, 0xF81F, 224 0xFFE0, 0x07FF, 225 }, 226 .expected_swab = { 227 0xFFFF, 0x0000, 228 0x00F8, 0xE007, 229 0x1F00, 0x1FF8, 230 0xE0FF, 0xFF07, 231 }, 232 }, 233 .xrgb1555_result = { 234 .dst_pitch = 0, 235 .expected = { 236 0x7FFF, 0x0000, 237 0x7C00, 0x03E0, 238 0x001F, 0x7C1F, 239 0x7FE0, 0x03FF, 240 }, 241 }, 242 .argb1555_result = { 243 .dst_pitch = 0, 244 .expected = { 245 0xFFFF, 0x8000, 246 0xFC00, 0x83E0, 247 0x801F, 0xFC1F, 248 0xFFE0, 0x83FF, 249 }, 250 }, 251 .rgba5551_result = { 252 .dst_pitch = 0, 253 .expected = { 254 0xFFFF, 0x0001, 255 0xF801, 0x07C1, 256 0x003F, 0xF83F, 257 0xFFC1, 0x07FF, 258 }, 259 }, 260 .rgb888_result = { 261 .dst_pitch = 0, 262 .expected = { 263 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 264 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 265 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 266 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 267 }, 268 }, 269 .argb8888_result = { 270 .dst_pitch = 0, 271 .expected = { 272 0xFFFFFFFF, 0xFF000000, 273 0xFFFF0000, 0xFF00FF00, 274 0xFF0000FF, 0xFFFF00FF, 275 0xFFFFFF00, 0xFF00FFFF, 276 }, 277 }, 278 .xrgb2101010_result = { 279 .dst_pitch = 0, 280 .expected = { 281 0x3FFFFFFF, 0x00000000, 282 0x3FF00000, 0x000FFC00, 283 0x000003FF, 0x3FF003FF, 284 0x3FFFFC00, 0x000FFFFF, 285 }, 286 }, 287 .argb2101010_result = { 288 .dst_pitch = 0, 289 .expected = { 290 0xFFFFFFFF, 0xC0000000, 291 0xFFF00000, 0xC00FFC00, 292 0xC00003FF, 0xFFF003FF, 293 0xFFFFFC00, 0xC00FFFFF, 294 }, 295 }, 296 }, 297 { 298 /* Randomly picked colors. Full buffer within the clip area. */ 299 .name = "destination_pitch", 300 .pitch = 3 * 4, 301 .clip = DRM_RECT_INIT(0, 0, 3, 3), 302 .xrgb8888 = { 303 0xA10E449C, 0xB1114D05, 0xC1A80303, 304 0xD16C7073, 0xA20E449C, 0xB2114D05, 305 0xC2A80303, 0xD26C7073, 0xA30E449C, 306 }, 307 .gray8_result = { 308 .dst_pitch = 5, 309 .expected = { 310 0x3C, 0x33, 0x34, 0x00, 0x00, 311 0x6F, 0x3C, 0x33, 0x00, 0x00, 312 0x34, 0x6F, 0x3C, 0x00, 0x00, 313 }, 314 }, 315 .rgb332_result = { 316 .dst_pitch = 5, 317 .expected = { 318 0x0A, 0x08, 0xA0, 0x00, 0x00, 319 0x6D, 0x0A, 0x08, 0x00, 0x00, 320 0xA0, 0x6D, 0x0A, 0x00, 0x00, 321 }, 322 }, 323 .rgb565_result = { 324 .dst_pitch = 10, 325 .expected = { 326 0x0A33, 0x1260, 0xA800, 0x0000, 0x0000, 327 0x6B8E, 0x0A33, 0x1260, 0x0000, 0x0000, 328 0xA800, 0x6B8E, 0x0A33, 0x0000, 0x0000, 329 }, 330 .expected_swab = { 331 0x330A, 0x6012, 0x00A8, 0x0000, 0x0000, 332 0x8E6B, 0x330A, 0x6012, 0x0000, 0x0000, 333 0x00A8, 0x8E6B, 0x330A, 0x0000, 0x0000, 334 }, 335 }, 336 .xrgb1555_result = { 337 .dst_pitch = 10, 338 .expected = { 339 0x0513, 0x0920, 0x5400, 0x0000, 0x0000, 340 0x35CE, 0x0513, 0x0920, 0x0000, 0x0000, 341 0x5400, 0x35CE, 0x0513, 0x0000, 0x0000, 342 }, 343 }, 344 .argb1555_result = { 345 .dst_pitch = 10, 346 .expected = { 347 0x8513, 0x8920, 0xD400, 0x0000, 0x0000, 348 0xB5CE, 0x8513, 0x8920, 0x0000, 0x0000, 349 0xD400, 0xB5CE, 0x8513, 0x0000, 0x0000, 350 }, 351 }, 352 .rgba5551_result = { 353 .dst_pitch = 10, 354 .expected = { 355 0x0A27, 0x1241, 0xA801, 0x0000, 0x0000, 356 0x6B9D, 0x0A27, 0x1241, 0x0000, 0x0000, 357 0xA801, 0x6B9D, 0x0A27, 0x0000, 0x0000, 358 }, 359 }, 360 .rgb888_result = { 361 .dst_pitch = 15, 362 .expected = { 363 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11, 0x03, 0x03, 0xA8, 364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 365 0x73, 0x70, 0x6C, 0x9C, 0x44, 0x0E, 0x05, 0x4D, 0x11, 366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 367 0x03, 0x03, 0xA8, 0x73, 0x70, 0x6C, 0x9C, 0x44, 0x0E, 368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 369 }, 370 }, 371 .argb8888_result = { 372 .dst_pitch = 20, 373 .expected = { 374 0xFF0E449C, 0xFF114D05, 0xFFA80303, 0x00000000, 0x00000000, 375 0xFF6C7073, 0xFF0E449C, 0xFF114D05, 0x00000000, 0x00000000, 376 0xFFA80303, 0xFF6C7073, 0xFF0E449C, 0x00000000, 0x00000000, 377 }, 378 }, 379 .xrgb2101010_result = { 380 .dst_pitch = 20, 381 .expected = { 382 0x03844672, 0x0444D414, 0x2A20300C, 0x00000000, 0x00000000, 383 0x1B1705CD, 0x03844672, 0x0444D414, 0x00000000, 0x00000000, 384 0x2A20300C, 0x1B1705CD, 0x03844672, 0x00000000, 0x00000000, 385 }, 386 }, 387 .argb2101010_result = { 388 .dst_pitch = 20, 389 .expected = { 390 0xC3844672, 0xC444D414, 0xEA20300C, 0x00000000, 0x00000000, 391 0xDB1705CD, 0xC3844672, 0xC444D414, 0x00000000, 0x00000000, 392 0xEA20300C, 0xDB1705CD, 0xC3844672, 0x00000000, 0x00000000, 393 }, 394 }, 395 }, 396 }; 397 398 /* 399 * conversion_buf_size - Return the destination buffer size required to convert 400 * between formats. 401 * @dst_format: destination buffer pixel format (DRM_FORMAT_*) 402 * @dst_pitch: Number of bytes between two consecutive scanlines within dst 403 * @clip: Clip rectangle area to convert 404 * 405 * Returns: 406 * The size of the destination buffer or negative value on error. 407 */ 408 static size_t conversion_buf_size(u32 dst_format, unsigned int dst_pitch, 409 const struct drm_rect *clip) 410 { 411 const struct drm_format_info *dst_fi = drm_format_info(dst_format); 412 unsigned int bpp; 413 414 if (!dst_fi) 415 return -EINVAL; 416 417 if (!dst_pitch) { 418 bpp = drm_format_info_bpp(dst_fi, 0); 419 dst_pitch = DIV_ROUND_UP(drm_rect_width(clip) * bpp, 8); 420 } 421 422 return dst_pitch * drm_rect_height(clip); 423 } 424 425 static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size) 426 { 427 u16 *dst = NULL; 428 int n; 429 430 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL); 431 if (!dst) 432 return NULL; 433 434 for (n = 0; n < buf_size; n++) 435 dst[n] = le16_to_cpu(buf[n]); 436 437 return dst; 438 } 439 440 static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size) 441 { 442 u32 *dst = NULL; 443 int n; 444 445 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL); 446 if (!dst) 447 return NULL; 448 449 for (n = 0; n < buf_size; n++) 450 dst[n] = le32_to_cpu((__force __le32)buf[n]); 451 452 return dst; 453 } 454 455 static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size) 456 { 457 __le32 *dst = NULL; 458 int n; 459 460 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL); 461 if (!dst) 462 return NULL; 463 464 for (n = 0; n < buf_size; n++) 465 dst[n] = cpu_to_le32(buf[n]); 466 467 return dst; 468 } 469 470 static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t, 471 char *desc) 472 { 473 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); 474 } 475 476 KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases, 477 convert_xrgb8888_case_desc); 478 479 static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test) 480 { 481 const struct convert_xrgb8888_case *params = test->param_value; 482 const struct convert_to_gray8_result *result = ¶ms->gray8_result; 483 size_t dst_size; 484 u8 *buf = NULL; 485 __le32 *xrgb8888 = NULL; 486 struct iosys_map dst, src; 487 488 struct drm_framebuffer fb = { 489 .format = drm_format_info(DRM_FORMAT_XRGB8888), 490 .pitches = { params->pitch, 0, 0 }, 491 }; 492 493 dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch, 494 ¶ms->clip); 495 KUNIT_ASSERT_GT(test, dst_size, 0); 496 497 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 498 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 499 iosys_map_set_vaddr(&dst, buf); 500 501 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 502 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 503 iosys_map_set_vaddr(&src, xrgb8888); 504 505 drm_fb_xrgb8888_to_gray8(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 506 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 507 } 508 509 static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test) 510 { 511 const struct convert_xrgb8888_case *params = test->param_value; 512 const struct convert_to_rgb332_result *result = ¶ms->rgb332_result; 513 size_t dst_size; 514 u8 *buf = NULL; 515 __le32 *xrgb8888 = NULL; 516 struct iosys_map dst, src; 517 518 struct drm_framebuffer fb = { 519 .format = drm_format_info(DRM_FORMAT_XRGB8888), 520 .pitches = { params->pitch, 0, 0 }, 521 }; 522 523 dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch, 524 ¶ms->clip); 525 KUNIT_ASSERT_GT(test, dst_size, 0); 526 527 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 528 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 529 iosys_map_set_vaddr(&dst, buf); 530 531 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 532 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 533 iosys_map_set_vaddr(&src, xrgb8888); 534 535 drm_fb_xrgb8888_to_rgb332(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 536 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 537 } 538 539 static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test) 540 { 541 const struct convert_xrgb8888_case *params = test->param_value; 542 const struct convert_to_rgb565_result *result = ¶ms->rgb565_result; 543 size_t dst_size; 544 u16 *buf = NULL; 545 __le32 *xrgb8888 = NULL; 546 struct iosys_map dst, src; 547 548 struct drm_framebuffer fb = { 549 .format = drm_format_info(DRM_FORMAT_XRGB8888), 550 .pitches = { params->pitch, 0, 0 }, 551 }; 552 553 dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch, 554 ¶ms->clip); 555 KUNIT_ASSERT_GT(test, dst_size, 0); 556 557 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 558 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 559 iosys_map_set_vaddr(&dst, buf); 560 561 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 562 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 563 iosys_map_set_vaddr(&src, xrgb8888); 564 565 drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, false); 566 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 567 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 568 569 buf = dst.vaddr; /* restore original value of buf */ 570 drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, true); 571 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 572 KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size); 573 } 574 575 static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test) 576 { 577 const struct convert_xrgb8888_case *params = test->param_value; 578 const struct convert_to_xrgb1555_result *result = ¶ms->xrgb1555_result; 579 size_t dst_size; 580 u16 *buf = NULL; 581 __le32 *xrgb8888 = NULL; 582 struct iosys_map dst, src; 583 584 struct drm_framebuffer fb = { 585 .format = drm_format_info(DRM_FORMAT_XRGB8888), 586 .pitches = { params->pitch, 0, 0 }, 587 }; 588 589 dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch, 590 ¶ms->clip); 591 KUNIT_ASSERT_GT(test, dst_size, 0); 592 593 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 594 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 595 iosys_map_set_vaddr(&dst, buf); 596 597 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 598 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 599 iosys_map_set_vaddr(&src, xrgb8888); 600 601 drm_fb_xrgb8888_to_xrgb1555(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 602 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 603 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 604 } 605 606 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test) 607 { 608 const struct convert_xrgb8888_case *params = test->param_value; 609 const struct convert_to_argb1555_result *result = ¶ms->argb1555_result; 610 size_t dst_size; 611 u16 *buf = NULL; 612 __le32 *xrgb8888 = NULL; 613 struct iosys_map dst, src; 614 615 struct drm_framebuffer fb = { 616 .format = drm_format_info(DRM_FORMAT_XRGB8888), 617 .pitches = { params->pitch, 0, 0 }, 618 }; 619 620 dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch, 621 ¶ms->clip); 622 KUNIT_ASSERT_GT(test, dst_size, 0); 623 624 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 625 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 626 iosys_map_set_vaddr(&dst, buf); 627 628 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 629 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 630 iosys_map_set_vaddr(&src, xrgb8888); 631 632 drm_fb_xrgb8888_to_argb1555(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 633 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 634 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 635 } 636 637 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test) 638 { 639 const struct convert_xrgb8888_case *params = test->param_value; 640 const struct convert_to_rgba5551_result *result = ¶ms->rgba5551_result; 641 size_t dst_size; 642 u16 *buf = NULL; 643 __le32 *xrgb8888 = NULL; 644 struct iosys_map dst, src; 645 646 struct drm_framebuffer fb = { 647 .format = drm_format_info(DRM_FORMAT_XRGB8888), 648 .pitches = { params->pitch, 0, 0 }, 649 }; 650 651 dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch, 652 ¶ms->clip); 653 KUNIT_ASSERT_GT(test, dst_size, 0); 654 655 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 656 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 657 iosys_map_set_vaddr(&dst, buf); 658 659 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 660 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 661 iosys_map_set_vaddr(&src, xrgb8888); 662 663 drm_fb_xrgb8888_to_rgba5551(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 664 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 665 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 666 } 667 668 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test) 669 { 670 const struct convert_xrgb8888_case *params = test->param_value; 671 const struct convert_to_rgb888_result *result = ¶ms->rgb888_result; 672 size_t dst_size; 673 u8 *buf = NULL; 674 __le32 *xrgb8888 = NULL; 675 struct iosys_map dst, src; 676 677 struct drm_framebuffer fb = { 678 .format = drm_format_info(DRM_FORMAT_XRGB8888), 679 .pitches = { params->pitch, 0, 0 }, 680 }; 681 682 dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch, 683 ¶ms->clip); 684 KUNIT_ASSERT_GT(test, dst_size, 0); 685 686 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 687 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 688 iosys_map_set_vaddr(&dst, buf); 689 690 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 691 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 692 iosys_map_set_vaddr(&src, xrgb8888); 693 694 /* 695 * RGB888 expected results are already in little-endian 696 * order, so there's no need to convert the test output. 697 */ 698 drm_fb_xrgb8888_to_rgb888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 699 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 700 } 701 702 static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test) 703 { 704 const struct convert_xrgb8888_case *params = test->param_value; 705 const struct convert_to_argb8888_result *result = ¶ms->argb8888_result; 706 size_t dst_size; 707 u32 *buf = NULL; 708 __le32 *xrgb8888 = NULL; 709 struct iosys_map dst, src; 710 711 struct drm_framebuffer fb = { 712 .format = drm_format_info(DRM_FORMAT_XRGB8888), 713 .pitches = { params->pitch, 0, 0 }, 714 }; 715 716 dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888, 717 result->dst_pitch, ¶ms->clip); 718 KUNIT_ASSERT_GT(test, dst_size, 0); 719 720 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 721 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 722 iosys_map_set_vaddr(&dst, buf); 723 724 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 725 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 726 iosys_map_set_vaddr(&src, xrgb8888); 727 728 drm_fb_xrgb8888_to_argb8888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 729 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 730 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 731 } 732 733 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test) 734 { 735 const struct convert_xrgb8888_case *params = test->param_value; 736 const struct convert_to_xrgb2101010_result *result = ¶ms->xrgb2101010_result; 737 size_t dst_size; 738 u32 *buf = NULL; 739 __le32 *xrgb8888 = NULL; 740 struct iosys_map dst, src; 741 742 struct drm_framebuffer fb = { 743 .format = drm_format_info(DRM_FORMAT_XRGB8888), 744 .pitches = { params->pitch, 0, 0 }, 745 }; 746 747 dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010, 748 result->dst_pitch, ¶ms->clip); 749 KUNIT_ASSERT_GT(test, dst_size, 0); 750 751 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 752 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 753 iosys_map_set_vaddr(&dst, buf); 754 755 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 756 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 757 iosys_map_set_vaddr(&src, xrgb8888); 758 759 drm_fb_xrgb8888_to_xrgb2101010(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 760 buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32)); 761 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 762 } 763 764 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test) 765 { 766 const struct convert_xrgb8888_case *params = test->param_value; 767 const struct convert_to_argb2101010_result *result = ¶ms->argb2101010_result; 768 size_t dst_size; 769 u32 *buf = NULL; 770 __le32 *xrgb8888 = NULL; 771 struct iosys_map dst, src; 772 773 struct drm_framebuffer fb = { 774 .format = drm_format_info(DRM_FORMAT_XRGB8888), 775 .pitches = { params->pitch, 0, 0 }, 776 }; 777 778 dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010, 779 result->dst_pitch, ¶ms->clip); 780 KUNIT_ASSERT_GT(test, dst_size, 0); 781 782 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 783 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 784 iosys_map_set_vaddr(&dst, buf); 785 786 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 787 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 788 iosys_map_set_vaddr(&src, xrgb8888); 789 790 drm_fb_xrgb8888_to_argb2101010(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 791 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 792 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 793 } 794 795 static struct kunit_case drm_format_helper_test_cases[] = { 796 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params), 797 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params), 798 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params), 799 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params), 800 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params), 801 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params), 802 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params), 803 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params), 804 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params), 805 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params), 806 {} 807 }; 808 809 static struct kunit_suite drm_format_helper_test_suite = { 810 .name = "drm_format_helper_test", 811 .test_cases = drm_format_helper_test_cases, 812 }; 813 814 kunit_test_suite(drm_format_helper_test_suite); 815 816 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs"); 817 MODULE_LICENSE("GPL"); 818 MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>"); 819