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 413 if (!dst_fi) 414 return -EINVAL; 415 416 if (!dst_pitch) 417 dst_pitch = drm_rect_width(clip) * dst_fi->cpp[0]; 418 419 return dst_pitch * drm_rect_height(clip); 420 } 421 422 static u16 *le16buf_to_cpu(struct kunit *test, const __le16 *buf, size_t buf_size) 423 { 424 u16 *dst = NULL; 425 int n; 426 427 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL); 428 if (!dst) 429 return NULL; 430 431 for (n = 0; n < buf_size; n++) 432 dst[n] = le16_to_cpu(buf[n]); 433 434 return dst; 435 } 436 437 static u32 *le32buf_to_cpu(struct kunit *test, const __le32 *buf, size_t buf_size) 438 { 439 u32 *dst = NULL; 440 int n; 441 442 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL); 443 if (!dst) 444 return NULL; 445 446 for (n = 0; n < buf_size; n++) 447 dst[n] = le32_to_cpu((__force __le32)buf[n]); 448 449 return dst; 450 } 451 452 static __le32 *cpubuf_to_le32(struct kunit *test, const u32 *buf, size_t buf_size) 453 { 454 __le32 *dst = NULL; 455 int n; 456 457 dst = kunit_kzalloc(test, sizeof(*dst) * buf_size, GFP_KERNEL); 458 if (!dst) 459 return NULL; 460 461 for (n = 0; n < buf_size; n++) 462 dst[n] = cpu_to_le32(buf[n]); 463 464 return dst; 465 } 466 467 static void convert_xrgb8888_case_desc(struct convert_xrgb8888_case *t, 468 char *desc) 469 { 470 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); 471 } 472 473 KUNIT_ARRAY_PARAM(convert_xrgb8888, convert_xrgb8888_cases, 474 convert_xrgb8888_case_desc); 475 476 static void drm_test_fb_xrgb8888_to_gray8(struct kunit *test) 477 { 478 const struct convert_xrgb8888_case *params = test->param_value; 479 const struct convert_to_gray8_result *result = ¶ms->gray8_result; 480 size_t dst_size; 481 u8 *buf = NULL; 482 __le32 *xrgb8888 = NULL; 483 struct iosys_map dst, src; 484 485 struct drm_framebuffer fb = { 486 .format = drm_format_info(DRM_FORMAT_XRGB8888), 487 .pitches = { params->pitch, 0, 0 }, 488 }; 489 490 dst_size = conversion_buf_size(DRM_FORMAT_R8, result->dst_pitch, 491 ¶ms->clip); 492 KUNIT_ASSERT_GT(test, dst_size, 0); 493 494 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 495 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 496 iosys_map_set_vaddr(&dst, buf); 497 498 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 499 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 500 iosys_map_set_vaddr(&src, xrgb8888); 501 502 drm_fb_xrgb8888_to_gray8(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 503 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 504 } 505 506 static void drm_test_fb_xrgb8888_to_rgb332(struct kunit *test) 507 { 508 const struct convert_xrgb8888_case *params = test->param_value; 509 const struct convert_to_rgb332_result *result = ¶ms->rgb332_result; 510 size_t dst_size; 511 u8 *buf = NULL; 512 __le32 *xrgb8888 = NULL; 513 struct iosys_map dst, src; 514 515 struct drm_framebuffer fb = { 516 .format = drm_format_info(DRM_FORMAT_XRGB8888), 517 .pitches = { params->pitch, 0, 0 }, 518 }; 519 520 dst_size = conversion_buf_size(DRM_FORMAT_RGB332, result->dst_pitch, 521 ¶ms->clip); 522 KUNIT_ASSERT_GT(test, dst_size, 0); 523 524 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 525 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 526 iosys_map_set_vaddr(&dst, buf); 527 528 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 529 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 530 iosys_map_set_vaddr(&src, xrgb8888); 531 532 drm_fb_xrgb8888_to_rgb332(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 533 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 534 } 535 536 static void drm_test_fb_xrgb8888_to_rgb565(struct kunit *test) 537 { 538 const struct convert_xrgb8888_case *params = test->param_value; 539 const struct convert_to_rgb565_result *result = ¶ms->rgb565_result; 540 size_t dst_size; 541 u16 *buf = NULL; 542 __le32 *xrgb8888 = NULL; 543 struct iosys_map dst, src; 544 545 struct drm_framebuffer fb = { 546 .format = drm_format_info(DRM_FORMAT_XRGB8888), 547 .pitches = { params->pitch, 0, 0 }, 548 }; 549 550 dst_size = conversion_buf_size(DRM_FORMAT_RGB565, result->dst_pitch, 551 ¶ms->clip); 552 KUNIT_ASSERT_GT(test, dst_size, 0); 553 554 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 555 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 556 iosys_map_set_vaddr(&dst, buf); 557 558 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 559 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 560 iosys_map_set_vaddr(&src, xrgb8888); 561 562 drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, false); 563 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 564 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 565 566 buf = dst.vaddr; /* restore original value of buf */ 567 drm_fb_xrgb8888_to_rgb565(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, true); 568 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 569 KUNIT_EXPECT_MEMEQ(test, buf, result->expected_swab, dst_size); 570 } 571 572 static void drm_test_fb_xrgb8888_to_xrgb1555(struct kunit *test) 573 { 574 const struct convert_xrgb8888_case *params = test->param_value; 575 const struct convert_to_xrgb1555_result *result = ¶ms->xrgb1555_result; 576 size_t dst_size; 577 u16 *buf = NULL; 578 __le32 *xrgb8888 = NULL; 579 struct iosys_map dst, src; 580 581 struct drm_framebuffer fb = { 582 .format = drm_format_info(DRM_FORMAT_XRGB8888), 583 .pitches = { params->pitch, 0, 0 }, 584 }; 585 586 dst_size = conversion_buf_size(DRM_FORMAT_XRGB1555, result->dst_pitch, 587 ¶ms->clip); 588 KUNIT_ASSERT_GT(test, dst_size, 0); 589 590 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 591 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 592 iosys_map_set_vaddr(&dst, buf); 593 594 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 595 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 596 iosys_map_set_vaddr(&src, xrgb8888); 597 598 drm_fb_xrgb8888_to_xrgb1555(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 599 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 600 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 601 } 602 603 static void drm_test_fb_xrgb8888_to_argb1555(struct kunit *test) 604 { 605 const struct convert_xrgb8888_case *params = test->param_value; 606 const struct convert_to_argb1555_result *result = ¶ms->argb1555_result; 607 size_t dst_size; 608 u16 *buf = NULL; 609 __le32 *xrgb8888 = NULL; 610 struct iosys_map dst, src; 611 612 struct drm_framebuffer fb = { 613 .format = drm_format_info(DRM_FORMAT_XRGB8888), 614 .pitches = { params->pitch, 0, 0 }, 615 }; 616 617 dst_size = conversion_buf_size(DRM_FORMAT_ARGB1555, result->dst_pitch, 618 ¶ms->clip); 619 KUNIT_ASSERT_GT(test, dst_size, 0); 620 621 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 622 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 623 iosys_map_set_vaddr(&dst, buf); 624 625 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 626 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 627 iosys_map_set_vaddr(&src, xrgb8888); 628 629 drm_fb_xrgb8888_to_argb1555(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 630 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 631 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 632 } 633 634 static void drm_test_fb_xrgb8888_to_rgba5551(struct kunit *test) 635 { 636 const struct convert_xrgb8888_case *params = test->param_value; 637 const struct convert_to_rgba5551_result *result = ¶ms->rgba5551_result; 638 size_t dst_size; 639 u16 *buf = NULL; 640 __le32 *xrgb8888 = NULL; 641 struct iosys_map dst, src; 642 643 struct drm_framebuffer fb = { 644 .format = drm_format_info(DRM_FORMAT_XRGB8888), 645 .pitches = { params->pitch, 0, 0 }, 646 }; 647 648 dst_size = conversion_buf_size(DRM_FORMAT_RGBA5551, result->dst_pitch, 649 ¶ms->clip); 650 KUNIT_ASSERT_GT(test, dst_size, 0); 651 652 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 653 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 654 iosys_map_set_vaddr(&dst, buf); 655 656 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 657 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 658 iosys_map_set_vaddr(&src, xrgb8888); 659 660 drm_fb_xrgb8888_to_rgba5551(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 661 buf = le16buf_to_cpu(test, (__force const __le16 *)buf, dst_size / sizeof(__le16)); 662 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 663 } 664 665 static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test) 666 { 667 const struct convert_xrgb8888_case *params = test->param_value; 668 const struct convert_to_rgb888_result *result = ¶ms->rgb888_result; 669 size_t dst_size; 670 u8 *buf = NULL; 671 __le32 *xrgb8888 = NULL; 672 struct iosys_map dst, src; 673 674 struct drm_framebuffer fb = { 675 .format = drm_format_info(DRM_FORMAT_XRGB8888), 676 .pitches = { params->pitch, 0, 0 }, 677 }; 678 679 dst_size = conversion_buf_size(DRM_FORMAT_RGB888, result->dst_pitch, 680 ¶ms->clip); 681 KUNIT_ASSERT_GT(test, dst_size, 0); 682 683 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 684 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 685 iosys_map_set_vaddr(&dst, buf); 686 687 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 688 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 689 iosys_map_set_vaddr(&src, xrgb8888); 690 691 /* 692 * RGB888 expected results are already in little-endian 693 * order, so there's no need to convert the test output. 694 */ 695 drm_fb_xrgb8888_to_rgb888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 696 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 697 } 698 699 static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test) 700 { 701 const struct convert_xrgb8888_case *params = test->param_value; 702 const struct convert_to_argb8888_result *result = ¶ms->argb8888_result; 703 size_t dst_size; 704 u32 *buf = NULL; 705 __le32 *xrgb8888 = NULL; 706 struct iosys_map dst, src; 707 708 struct drm_framebuffer fb = { 709 .format = drm_format_info(DRM_FORMAT_XRGB8888), 710 .pitches = { params->pitch, 0, 0 }, 711 }; 712 713 dst_size = conversion_buf_size(DRM_FORMAT_ARGB8888, 714 result->dst_pitch, ¶ms->clip); 715 KUNIT_ASSERT_GT(test, dst_size, 0); 716 717 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 718 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 719 iosys_map_set_vaddr(&dst, buf); 720 721 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 722 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 723 iosys_map_set_vaddr(&src, xrgb8888); 724 725 drm_fb_xrgb8888_to_argb8888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 726 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 727 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 728 } 729 730 static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test) 731 { 732 const struct convert_xrgb8888_case *params = test->param_value; 733 const struct convert_to_xrgb2101010_result *result = ¶ms->xrgb2101010_result; 734 size_t dst_size; 735 u32 *buf = NULL; 736 __le32 *xrgb8888 = NULL; 737 struct iosys_map dst, src; 738 739 struct drm_framebuffer fb = { 740 .format = drm_format_info(DRM_FORMAT_XRGB8888), 741 .pitches = { params->pitch, 0, 0 }, 742 }; 743 744 dst_size = conversion_buf_size(DRM_FORMAT_XRGB2101010, 745 result->dst_pitch, ¶ms->clip); 746 KUNIT_ASSERT_GT(test, dst_size, 0); 747 748 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 749 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 750 iosys_map_set_vaddr(&dst, buf); 751 752 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 753 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 754 iosys_map_set_vaddr(&src, xrgb8888); 755 756 drm_fb_xrgb8888_to_xrgb2101010(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 757 buf = le32buf_to_cpu(test, buf, dst_size / sizeof(u32)); 758 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 759 } 760 761 static void drm_test_fb_xrgb8888_to_argb2101010(struct kunit *test) 762 { 763 const struct convert_xrgb8888_case *params = test->param_value; 764 const struct convert_to_argb2101010_result *result = ¶ms->argb2101010_result; 765 size_t dst_size; 766 u32 *buf = NULL; 767 __le32 *xrgb8888 = NULL; 768 struct iosys_map dst, src; 769 770 struct drm_framebuffer fb = { 771 .format = drm_format_info(DRM_FORMAT_XRGB8888), 772 .pitches = { params->pitch, 0, 0 }, 773 }; 774 775 dst_size = conversion_buf_size(DRM_FORMAT_ARGB2101010, 776 result->dst_pitch, ¶ms->clip); 777 KUNIT_ASSERT_GT(test, dst_size, 0); 778 779 buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); 780 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); 781 iosys_map_set_vaddr(&dst, buf); 782 783 xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); 784 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); 785 iosys_map_set_vaddr(&src, xrgb8888); 786 787 drm_fb_xrgb8888_to_argb2101010(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip); 788 buf = le32buf_to_cpu(test, (__force const __le32 *)buf, dst_size / sizeof(u32)); 789 KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); 790 } 791 792 static struct kunit_case drm_format_helper_test_cases[] = { 793 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_gray8, convert_xrgb8888_gen_params), 794 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb332, convert_xrgb8888_gen_params), 795 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb565, convert_xrgb8888_gen_params), 796 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb1555, convert_xrgb8888_gen_params), 797 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params), 798 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params), 799 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params), 800 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params), 801 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params), 802 KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params), 803 {} 804 }; 805 806 static struct kunit_suite drm_format_helper_test_suite = { 807 .name = "drm_format_helper_test", 808 .test_cases = drm_format_helper_test_cases, 809 }; 810 811 kunit_test_suite(drm_format_helper_test_suite); 812 813 MODULE_DESCRIPTION("KUnit tests for the drm_format_helper APIs"); 814 MODULE_LICENSE("GPL"); 815 MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>"); 816