1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Test cases for the drm_framebuffer functions 4 * 5 * Copyright (c) 2022 Maíra Canal <mairacanal@riseup.net> 6 */ 7 8 #include <kunit/test.h> 9 10 #include <drm/drm_device.h> 11 #include <drm/drm_mode.h> 12 #include <drm/drm_fourcc.h> 13 #include <drm/drm_print.h> 14 15 #include "../drm_crtc_internal.h" 16 17 #define MIN_WIDTH 4 18 #define MAX_WIDTH 4096 19 #define MIN_HEIGHT 4 20 #define MAX_HEIGHT 4096 21 22 struct drm_framebuffer_test { 23 int buffer_created; 24 struct drm_mode_fb_cmd2 cmd; 25 const char *name; 26 }; 27 28 static const struct drm_framebuffer_test drm_framebuffer_create_cases[] = { 29 { .buffer_created = 1, .name = "ABGR8888 normal sizes", 30 .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_ABGR8888, 31 .handles = { 1, 0, 0 }, .pitches = { 4 * 600, 0, 0 }, 32 } 33 }, 34 { .buffer_created = 1, .name = "ABGR8888 max sizes", 35 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 36 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, 37 } 38 }, 39 { .buffer_created = 1, .name = "ABGR8888 pitch greater than min required", 40 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 41 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH + 1, 0, 0 }, 42 } 43 }, 44 { .buffer_created = 0, .name = "ABGR8888 pitch less than min required", 45 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 46 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH - 1, 0, 0 }, 47 } 48 }, 49 { .buffer_created = 0, .name = "ABGR8888 Invalid width", 50 .cmd = { .width = MAX_WIDTH + 1, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 51 .handles = { 1, 0, 0 }, .pitches = { 4 * (MAX_WIDTH + 1), 0, 0 }, 52 } 53 }, 54 { .buffer_created = 0, .name = "ABGR8888 Invalid buffer handle", 55 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 56 .handles = { 0, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, 57 } 58 }, 59 { .buffer_created = 0, .name = "No pixel format", 60 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = 0, 61 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, 62 } 63 }, 64 { .buffer_created = 0, .name = "ABGR8888 Width 0", 65 .cmd = { .width = 0, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 66 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, 67 } 68 }, 69 { .buffer_created = 0, .name = "ABGR8888 Height 0", 70 .cmd = { .width = MAX_WIDTH, .height = 0, .pixel_format = DRM_FORMAT_ABGR8888, 71 .handles = { 1, 0, 0 }, .pitches = { 4 * MAX_WIDTH, 0, 0 }, 72 } 73 }, 74 { .buffer_created = 0, .name = "ABGR8888 Out of bound height * pitch combination", 75 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 76 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX - 1, 0, 0 }, 77 .pitches = { 4 * MAX_WIDTH, 0, 0 }, 78 } 79 }, 80 { .buffer_created = 1, .name = "ABGR8888 Large buffer offset", 81 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 82 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, 83 .pitches = { 4 * MAX_WIDTH, 0, 0 }, 84 } 85 }, 86 { .buffer_created = 1, .name = "ABGR8888 Set DRM_MODE_FB_MODIFIERS without modifiers", 87 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 88 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, 89 .pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, 90 } 91 }, 92 { .buffer_created = 1, .name = "ABGR8888 Valid buffer modifier", 93 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 94 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, 95 .pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, 96 .modifier = { AFBC_FORMAT_MOD_YTR, 0, 0 }, 97 } 98 }, 99 { .buffer_created = 0, 100 .name = "ABGR8888 Invalid buffer modifier(DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)", 101 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 102 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, 103 .pitches = { 4 * MAX_WIDTH, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, 104 .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0, 0 }, 105 } 106 }, 107 { .buffer_created = 1, .name = "ABGR8888 Extra pitches without DRM_MODE_FB_MODIFIERS", 108 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 109 .handles = { 1, 0, 0 }, .offsets = { UINT_MAX / 2, 0, 0 }, 110 .pitches = { 4 * MAX_WIDTH, 4 * MAX_WIDTH, 0 }, 111 } 112 }, 113 { .buffer_created = 0, .name = "ABGR8888 Extra pitches with DRM_MODE_FB_MODIFIERS", 114 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_ABGR8888, 115 .handles = { 1, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, 116 .pitches = { 4 * MAX_WIDTH, 4 * MAX_WIDTH, 0 }, 117 } 118 }, 119 { .buffer_created = 1, .name = "NV12 Normal sizes", 120 .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_NV12, 121 .handles = { 1, 1, 0 }, .pitches = { 600, 600, 0 }, 122 } 123 }, 124 { .buffer_created = 1, .name = "NV12 Max sizes", 125 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, 126 .handles = { 1, 1, 0 }, .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, 127 } 128 }, 129 { .buffer_created = 0, .name = "NV12 Invalid pitch", 130 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, 131 .handles = { 1, 1, 0 }, .pitches = { MAX_WIDTH, MAX_WIDTH - 1, 0 }, 132 } 133 }, 134 { .buffer_created = 0, .name = "NV12 Invalid modifier/missing DRM_MODE_FB_MODIFIERS flag", 135 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, 136 .handles = { 1, 1, 0 }, .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0, 0 }, 137 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, 138 } 139 }, 140 { .buffer_created = 0, .name = "NV12 different modifier per-plane", 141 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, 142 .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS, 143 .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0, 0 }, 144 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, 145 } 146 }, 147 { .buffer_created = 1, .name = "NV12 with DRM_FORMAT_MOD_SAMSUNG_64_32_TILE", 148 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, 149 .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS, 150 .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 151 DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0 }, 152 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, 153 } 154 }, 155 { .buffer_created = 0, .name = "NV12 Valid modifiers without DRM_MODE_FB_MODIFIERS", 156 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, 157 .handles = { 1, 1, 0 }, .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 158 DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 0 }, 159 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, 160 } 161 }, 162 { .buffer_created = 0, .name = "NV12 Modifier for inexistent plane", 163 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, 164 .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS, 165 .modifier = { DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, DRM_FORMAT_MOD_SAMSUNG_64_32_TILE, 166 DRM_FORMAT_MOD_SAMSUNG_64_32_TILE }, 167 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, 168 } 169 }, 170 { .buffer_created = 0, .name = "NV12 Handle for inexistent plane", 171 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_NV12, 172 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, 173 .pitches = { MAX_WIDTH, MAX_WIDTH, 0 }, 174 } 175 }, 176 { .buffer_created = 1, .name = "NV12 Handle for inexistent plane without DRM_MODE_FB_MODIFIERS", 177 .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_NV12, 178 .handles = { 1, 1, 1 }, .pitches = { 600, 600, 600 }, 179 } 180 }, 181 { .buffer_created = 1, .name = "YVU420 DRM_MODE_FB_MODIFIERS set without modifier", 182 .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_YVU420, 183 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, 184 .pitches = { 600, 300, 300 }, 185 } 186 }, 187 { .buffer_created = 1, .name = "YVU420 Normal sizes", 188 .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_YVU420, 189 .handles = { 1, 1, 1 }, .pitches = { 600, 300, 300 }, 190 } 191 }, 192 { .buffer_created = 1, .name = "YVU420 Max sizes", 193 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, 194 .handles = { 1, 1, 1 }, .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), 195 DIV_ROUND_UP(MAX_WIDTH, 2) }, 196 } 197 }, 198 { .buffer_created = 0, .name = "YVU420 Invalid pitch", 199 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, 200 .handles = { 1, 1, 1 }, .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2) - 1, 201 DIV_ROUND_UP(MAX_WIDTH, 2) }, 202 } 203 }, 204 { .buffer_created = 1, .name = "YVU420 Different pitches", 205 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, 206 .handles = { 1, 1, 1 }, .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2) + 1, 207 DIV_ROUND_UP(MAX_WIDTH, 2) + 7 }, 208 } 209 }, 210 { .buffer_created = 1, .name = "YVU420 Different buffer offsets/pitches", 211 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, 212 .handles = { 1, 1, 1 }, .offsets = { MAX_WIDTH, MAX_WIDTH + 213 MAX_WIDTH * MAX_HEIGHT, MAX_WIDTH + 2 * MAX_WIDTH * MAX_HEIGHT }, 214 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2) + 1, 215 DIV_ROUND_UP(MAX_WIDTH, 2) + 7 }, 216 } 217 }, 218 { .buffer_created = 0, 219 .name = "YVU420 Modifier set just for plane 0, without DRM_MODE_FB_MODIFIERS", 220 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, 221 .handles = { 1, 1, 1 }, .modifier = { AFBC_FORMAT_MOD_SPARSE, 0, 0 }, 222 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, 223 } 224 }, 225 { .buffer_created = 0, 226 .name = "YVU420 Modifier set just for planes 0, 1, without DRM_MODE_FB_MODIFIERS", 227 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, 228 .handles = { 1, 1, 1 }, 229 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 0 }, 230 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, 231 } 232 }, 233 { .buffer_created = 0, 234 .name = "YVU420 Modifier set just for plane 0, 1, with DRM_MODE_FB_MODIFIERS", 235 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, 236 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, 237 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 0 }, 238 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, 239 } 240 }, 241 { .buffer_created = 1, .name = "YVU420 Valid modifier", 242 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, 243 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, 244 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 245 AFBC_FORMAT_MOD_SPARSE }, 246 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, 247 } 248 }, 249 { .buffer_created = 0, .name = "YVU420 Different modifiers per plane", 250 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, 251 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, 252 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE | AFBC_FORMAT_MOD_YTR, 253 AFBC_FORMAT_MOD_SPARSE }, 254 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, 255 } 256 }, 257 { .buffer_created = 0, .name = "YVU420 Modifier for inexistent plane", 258 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_YVU420, 259 .handles = { 1, 1, 1 }, .flags = DRM_MODE_FB_MODIFIERS, 260 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 261 AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE }, 262 .pitches = { MAX_WIDTH, DIV_ROUND_UP(MAX_WIDTH, 2), DIV_ROUND_UP(MAX_WIDTH, 2) }, 263 } 264 }, 265 { .buffer_created = 1, .name = "X0L2 Normal sizes", 266 .cmd = { .width = 600, .height = 600, .pixel_format = DRM_FORMAT_X0L2, 267 .handles = { 1, 0, 0 }, .pitches = { 1200, 0, 0 } 268 } 269 }, 270 { .buffer_created = 1, .name = "X0L2 Max sizes", 271 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, 272 .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH, 0, 0 } 273 } 274 }, 275 { .buffer_created = 0, .name = "X0L2 Invalid pitch", 276 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, 277 .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH - 1, 0, 0 } 278 } 279 }, 280 { .buffer_created = 1, .name = "X0L2 Pitch greater than minimum required", 281 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, 282 .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH + 1, 0, 0 } 283 } 284 }, 285 { .buffer_created = 0, .name = "X0L2 Handle for inexistent plane", 286 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, 287 .handles = { 1, 1, 0 }, .flags = DRM_MODE_FB_MODIFIERS, 288 .pitches = { 2 * MAX_WIDTH + 1, 0, 0 } 289 } 290 }, 291 { .buffer_created = 1, 292 .name = "X0L2 Offset for inexistent plane, without DRM_MODE_FB_MODIFIERS set", 293 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, 294 .handles = { 1, 0, 0 }, .offsets = { 0, 0, 3 }, 295 .pitches = { 2 * MAX_WIDTH + 1, 0, 0 } 296 } 297 }, 298 { .buffer_created = 0, .name = "X0L2 Modifier without DRM_MODE_FB_MODIFIERS set", 299 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, 300 .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH + 1, 0, 0 }, 301 .modifier = { AFBC_FORMAT_MOD_SPARSE, 0, 0 }, 302 } 303 }, 304 { .buffer_created = 1, .name = "X0L2 Valid modifier", 305 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, .pixel_format = DRM_FORMAT_X0L2, 306 .handles = { 1, 0, 0 }, .pitches = { 2 * MAX_WIDTH + 1, 0, 0 }, 307 .modifier = { AFBC_FORMAT_MOD_SPARSE, 0, 0 }, .flags = DRM_MODE_FB_MODIFIERS, 308 } 309 }, 310 { .buffer_created = 0, .name = "X0L2 Modifier for inexistent plane", 311 .cmd = { .width = MAX_WIDTH, .height = MAX_HEIGHT, 312 .pixel_format = DRM_FORMAT_X0L2, .handles = { 1, 0, 0 }, 313 .pitches = { 2 * MAX_WIDTH + 1, 0, 0 }, 314 .modifier = { AFBC_FORMAT_MOD_SPARSE, AFBC_FORMAT_MOD_SPARSE, 0 }, 315 .flags = DRM_MODE_FB_MODIFIERS, 316 } 317 }, 318 }; 319 320 static struct drm_framebuffer *fb_create_mock(struct drm_device *dev, 321 struct drm_file *file_priv, 322 const struct drm_mode_fb_cmd2 *mode_cmd) 323 { 324 int *buffer_created = dev->dev_private; 325 *buffer_created = 1; 326 return ERR_PTR(-EINVAL); 327 } 328 329 static struct drm_mode_config_funcs mock_config_funcs = { 330 .fb_create = fb_create_mock, 331 }; 332 333 static int drm_framebuffer_test_init(struct kunit *test) 334 { 335 struct drm_device *mock; 336 337 mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL); 338 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mock); 339 340 mock->mode_config.min_width = MIN_WIDTH; 341 mock->mode_config.max_width = MAX_WIDTH; 342 mock->mode_config.min_height = MIN_HEIGHT; 343 mock->mode_config.max_height = MAX_HEIGHT; 344 mock->mode_config.funcs = &mock_config_funcs; 345 346 test->priv = mock; 347 return 0; 348 } 349 350 static void drm_test_framebuffer_create(struct kunit *test) 351 { 352 const struct drm_framebuffer_test *params = test->param_value; 353 struct drm_device *mock = test->priv; 354 int buffer_created = 0; 355 356 mock->dev_private = &buffer_created; 357 drm_internal_framebuffer_create(mock, ¶ms->cmd, NULL); 358 KUNIT_EXPECT_EQ(test, params->buffer_created, buffer_created); 359 } 360 361 static void drm_framebuffer_test_to_desc(const struct drm_framebuffer_test *t, char *desc) 362 { 363 strcpy(desc, t->name); 364 } 365 366 KUNIT_ARRAY_PARAM(drm_framebuffer_create, drm_framebuffer_create_cases, 367 drm_framebuffer_test_to_desc); 368 369 static struct kunit_case drm_framebuffer_tests[] = { 370 KUNIT_CASE_PARAM(drm_test_framebuffer_create, drm_framebuffer_create_gen_params), 371 { } 372 }; 373 374 static struct kunit_suite drm_framebuffer_test_suite = { 375 .name = "drm_framebuffer", 376 .init = drm_framebuffer_test_init, 377 .test_cases = drm_framebuffer_tests, 378 }; 379 380 kunit_test_suite(drm_framebuffer_test_suite); 381 382 MODULE_DESCRIPTION("Test cases for the drm_framebuffer functions"); 383 MODULE_LICENSE("GPL"); 384