1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * drm gem framebuffer helper functions 4 * 5 * Copyright (C) 2017 Noralf Trønnes 6 */ 7 8 #include <linux/slab.h> 9 #include <linux/module.h> 10 11 #include <drm/drm_damage_helper.h> 12 #include <drm/drm_fourcc.h> 13 #include <drm/drm_framebuffer.h> 14 #include <drm/drm_gem.h> 15 #include <drm/drm_gem_framebuffer_helper.h> 16 #include <drm/drm_modeset_helper.h> 17 18 #include "drm_internal.h" 19 20 MODULE_IMPORT_NS(DMA_BUF); 21 22 #define AFBC_HEADER_SIZE 16 23 #define AFBC_TH_LAYOUT_ALIGNMENT 8 24 #define AFBC_HDR_ALIGN 64 25 #define AFBC_SUPERBLOCK_PIXELS 256 26 #define AFBC_SUPERBLOCK_ALIGNMENT 128 27 #define AFBC_TH_BODY_START_ALIGNMENT 4096 28 29 /** 30 * DOC: overview 31 * 32 * This library provides helpers for drivers that don't subclass 33 * &drm_framebuffer and use &drm_gem_object for their backing storage. 34 * 35 * Drivers without additional needs to validate framebuffers can simply use 36 * drm_gem_fb_create() and everything is wired up automatically. Other drivers 37 * can use all parts independently. 38 */ 39 40 /** 41 * drm_gem_fb_get_obj() - Get GEM object backing the framebuffer 42 * @fb: Framebuffer 43 * @plane: Plane index 44 * 45 * No additional reference is taken beyond the one that the &drm_frambuffer 46 * already holds. 47 * 48 * Returns: 49 * Pointer to &drm_gem_object for the given framebuffer and plane index or NULL 50 * if it does not exist. 51 */ 52 struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb, 53 unsigned int plane) 54 { 55 struct drm_device *dev = fb->dev; 56 57 if (drm_WARN_ON_ONCE(dev, plane >= ARRAY_SIZE(fb->obj))) 58 return NULL; 59 else if (drm_WARN_ON_ONCE(dev, !fb->obj[plane])) 60 return NULL; 61 62 return fb->obj[plane]; 63 } 64 EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj); 65 66 static int 67 drm_gem_fb_init(struct drm_device *dev, 68 struct drm_framebuffer *fb, 69 const struct drm_mode_fb_cmd2 *mode_cmd, 70 struct drm_gem_object **obj, unsigned int num_planes, 71 const struct drm_framebuffer_funcs *funcs) 72 { 73 unsigned int i; 74 int ret; 75 76 drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd); 77 78 for (i = 0; i < num_planes; i++) 79 fb->obj[i] = obj[i]; 80 81 ret = drm_framebuffer_init(dev, fb, funcs); 82 if (ret) 83 drm_err(dev, "Failed to init framebuffer: %d\n", ret); 84 85 return ret; 86 } 87 88 /** 89 * drm_gem_fb_destroy - Free GEM backed framebuffer 90 * @fb: Framebuffer 91 * 92 * Frees a GEM backed framebuffer with its backing buffer(s) and the structure 93 * itself. Drivers can use this as their &drm_framebuffer_funcs->destroy 94 * callback. 95 */ 96 void drm_gem_fb_destroy(struct drm_framebuffer *fb) 97 { 98 unsigned int i; 99 100 for (i = 0; i < fb->format->num_planes; i++) 101 drm_gem_object_put(fb->obj[i]); 102 103 drm_framebuffer_cleanup(fb); 104 kfree(fb); 105 } 106 EXPORT_SYMBOL(drm_gem_fb_destroy); 107 108 /** 109 * drm_gem_fb_create_handle - Create handle for GEM backed framebuffer 110 * @fb: Framebuffer 111 * @file: DRM file to register the handle for 112 * @handle: Pointer to return the created handle 113 * 114 * This function creates a handle for the GEM object backing the framebuffer. 115 * Drivers can use this as their &drm_framebuffer_funcs->create_handle 116 * callback. The GETFB IOCTL calls into this callback. 117 * 118 * Returns: 119 * 0 on success or a negative error code on failure. 120 */ 121 int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file *file, 122 unsigned int *handle) 123 { 124 return drm_gem_handle_create(file, fb->obj[0], handle); 125 } 126 EXPORT_SYMBOL(drm_gem_fb_create_handle); 127 128 /** 129 * drm_gem_fb_init_with_funcs() - Helper function for implementing 130 * &drm_mode_config_funcs.fb_create 131 * callback in cases when the driver 132 * allocates a subclass of 133 * struct drm_framebuffer 134 * @dev: DRM device 135 * @fb: framebuffer object 136 * @file: DRM file that holds the GEM handle(s) backing the framebuffer 137 * @mode_cmd: Metadata from the userspace framebuffer creation request 138 * @funcs: vtable to be used for the new framebuffer object 139 * 140 * This function can be used to set &drm_framebuffer_funcs for drivers that need 141 * custom framebuffer callbacks. Use drm_gem_fb_create() if you don't need to 142 * change &drm_framebuffer_funcs. The function does buffer size validation. 143 * The buffer size validation is for a general case, though, so users should 144 * pay attention to the checks being appropriate for them or, at least, 145 * non-conflicting. 146 * 147 * Returns: 148 * Zero or a negative error code. 149 */ 150 int drm_gem_fb_init_with_funcs(struct drm_device *dev, 151 struct drm_framebuffer *fb, 152 struct drm_file *file, 153 const struct drm_mode_fb_cmd2 *mode_cmd, 154 const struct drm_framebuffer_funcs *funcs) 155 { 156 const struct drm_format_info *info; 157 struct drm_gem_object *objs[DRM_FORMAT_MAX_PLANES]; 158 unsigned int i; 159 int ret; 160 161 info = drm_get_format_info(dev, mode_cmd); 162 if (!info) { 163 drm_dbg_kms(dev, "Failed to get FB format info\n"); 164 return -EINVAL; 165 } 166 167 for (i = 0; i < info->num_planes; i++) { 168 unsigned int width = mode_cmd->width / (i ? info->hsub : 1); 169 unsigned int height = mode_cmd->height / (i ? info->vsub : 1); 170 unsigned int min_size; 171 172 objs[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]); 173 if (!objs[i]) { 174 drm_dbg_kms(dev, "Failed to lookup GEM object\n"); 175 ret = -ENOENT; 176 goto err_gem_object_put; 177 } 178 179 min_size = (height - 1) * mode_cmd->pitches[i] 180 + drm_format_info_min_pitch(info, i, width) 181 + mode_cmd->offsets[i]; 182 183 if (objs[i]->size < min_size) { 184 drm_dbg_kms(dev, 185 "GEM object size (%zu) smaller than minimum size (%u) for plane %d\n", 186 objs[i]->size, min_size, i); 187 drm_gem_object_put(objs[i]); 188 ret = -EINVAL; 189 goto err_gem_object_put; 190 } 191 } 192 193 ret = drm_gem_fb_init(dev, fb, mode_cmd, objs, i, funcs); 194 if (ret) 195 goto err_gem_object_put; 196 197 return 0; 198 199 err_gem_object_put: 200 while (i > 0) { 201 --i; 202 drm_gem_object_put(objs[i]); 203 } 204 return ret; 205 } 206 EXPORT_SYMBOL_GPL(drm_gem_fb_init_with_funcs); 207 208 /** 209 * drm_gem_fb_create_with_funcs() - Helper function for the 210 * &drm_mode_config_funcs.fb_create 211 * callback 212 * @dev: DRM device 213 * @file: DRM file that holds the GEM handle(s) backing the framebuffer 214 * @mode_cmd: Metadata from the userspace framebuffer creation request 215 * @funcs: vtable to be used for the new framebuffer object 216 * 217 * This function can be used to set &drm_framebuffer_funcs for drivers that need 218 * custom framebuffer callbacks. Use drm_gem_fb_create() if you don't need to 219 * change &drm_framebuffer_funcs. The function does buffer size validation. 220 * 221 * Returns: 222 * Pointer to a &drm_framebuffer on success or an error pointer on failure. 223 */ 224 struct drm_framebuffer * 225 drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file, 226 const struct drm_mode_fb_cmd2 *mode_cmd, 227 const struct drm_framebuffer_funcs *funcs) 228 { 229 struct drm_framebuffer *fb; 230 int ret; 231 232 fb = kzalloc(sizeof(*fb), GFP_KERNEL); 233 if (!fb) 234 return ERR_PTR(-ENOMEM); 235 236 ret = drm_gem_fb_init_with_funcs(dev, fb, file, mode_cmd, funcs); 237 if (ret) { 238 kfree(fb); 239 return ERR_PTR(ret); 240 } 241 242 return fb; 243 } 244 EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_funcs); 245 246 static const struct drm_framebuffer_funcs drm_gem_fb_funcs = { 247 .destroy = drm_gem_fb_destroy, 248 .create_handle = drm_gem_fb_create_handle, 249 }; 250 251 /** 252 * drm_gem_fb_create() - Helper function for the 253 * &drm_mode_config_funcs.fb_create callback 254 * @dev: DRM device 255 * @file: DRM file that holds the GEM handle(s) backing the framebuffer 256 * @mode_cmd: Metadata from the userspace framebuffer creation request 257 * 258 * This function creates a new framebuffer object described by 259 * &drm_mode_fb_cmd2. This description includes handles for the buffer(s) 260 * backing the framebuffer. 261 * 262 * If your hardware has special alignment or pitch requirements these should be 263 * checked before calling this function. The function does buffer size 264 * validation. Use drm_gem_fb_create_with_dirty() if you need framebuffer 265 * flushing. 266 * 267 * Drivers can use this as their &drm_mode_config_funcs.fb_create callback. 268 * The ADDFB2 IOCTL calls into this callback. 269 * 270 * Returns: 271 * Pointer to a &drm_framebuffer on success or an error pointer on failure. 272 */ 273 struct drm_framebuffer * 274 drm_gem_fb_create(struct drm_device *dev, struct drm_file *file, 275 const struct drm_mode_fb_cmd2 *mode_cmd) 276 { 277 return drm_gem_fb_create_with_funcs(dev, file, mode_cmd, 278 &drm_gem_fb_funcs); 279 } 280 EXPORT_SYMBOL_GPL(drm_gem_fb_create); 281 282 static const struct drm_framebuffer_funcs drm_gem_fb_funcs_dirtyfb = { 283 .destroy = drm_gem_fb_destroy, 284 .create_handle = drm_gem_fb_create_handle, 285 .dirty = drm_atomic_helper_dirtyfb, 286 }; 287 288 /** 289 * drm_gem_fb_create_with_dirty() - Helper function for the 290 * &drm_mode_config_funcs.fb_create callback 291 * @dev: DRM device 292 * @file: DRM file that holds the GEM handle(s) backing the framebuffer 293 * @mode_cmd: Metadata from the userspace framebuffer creation request 294 * 295 * This function creates a new framebuffer object described by 296 * &drm_mode_fb_cmd2. This description includes handles for the buffer(s) 297 * backing the framebuffer. drm_atomic_helper_dirtyfb() is used for the dirty 298 * callback giving framebuffer flushing through the atomic machinery. Use 299 * drm_gem_fb_create() if you don't need the dirty callback. 300 * The function does buffer size validation. 301 * 302 * Drivers should also call drm_plane_enable_fb_damage_clips() on all planes 303 * to enable userspace to use damage clips also with the ATOMIC IOCTL. 304 * 305 * Drivers can use this as their &drm_mode_config_funcs.fb_create callback. 306 * The ADDFB2 IOCTL calls into this callback. 307 * 308 * Returns: 309 * Pointer to a &drm_framebuffer on success or an error pointer on failure. 310 */ 311 struct drm_framebuffer * 312 drm_gem_fb_create_with_dirty(struct drm_device *dev, struct drm_file *file, 313 const struct drm_mode_fb_cmd2 *mode_cmd) 314 { 315 return drm_gem_fb_create_with_funcs(dev, file, mode_cmd, 316 &drm_gem_fb_funcs_dirtyfb); 317 } 318 EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty); 319 320 /** 321 * drm_gem_fb_vmap - maps all framebuffer BOs into kernel address space 322 * @fb: the framebuffer 323 * @map: returns the mapping's address for each BO 324 * @data: returns the data address for each BO, can be NULL 325 * 326 * This function maps all buffer objects of the given framebuffer into 327 * kernel address space and stores them in struct iosys_map. If the 328 * mapping operation fails for one of the BOs, the function unmaps the 329 * already established mappings automatically. 330 * 331 * Callers that want to access a BO's stored data should pass @data. 332 * The argument returns the addresses of the data stored in each BO. This 333 * is different from @map if the framebuffer's offsets field is non-zero. 334 * 335 * Both, @map and @data, must each refer to arrays with at least 336 * fb->format->num_planes elements. 337 * 338 * See drm_gem_fb_vunmap() for unmapping. 339 * 340 * Returns: 341 * 0 on success, or a negative errno code otherwise. 342 */ 343 int drm_gem_fb_vmap(struct drm_framebuffer *fb, struct iosys_map *map, 344 struct iosys_map *data) 345 { 346 struct drm_gem_object *obj; 347 unsigned int i; 348 int ret; 349 350 for (i = 0; i < fb->format->num_planes; ++i) { 351 obj = drm_gem_fb_get_obj(fb, i); 352 if (!obj) { 353 ret = -EINVAL; 354 goto err_drm_gem_vunmap; 355 } 356 ret = drm_gem_vmap_unlocked(obj, &map[i]); 357 if (ret) 358 goto err_drm_gem_vunmap; 359 } 360 361 if (data) { 362 for (i = 0; i < fb->format->num_planes; ++i) { 363 memcpy(&data[i], &map[i], sizeof(data[i])); 364 if (iosys_map_is_null(&data[i])) 365 continue; 366 iosys_map_incr(&data[i], fb->offsets[i]); 367 } 368 } 369 370 return 0; 371 372 err_drm_gem_vunmap: 373 while (i) { 374 --i; 375 obj = drm_gem_fb_get_obj(fb, i); 376 if (!obj) 377 continue; 378 drm_gem_vunmap_unlocked(obj, &map[i]); 379 } 380 return ret; 381 } 382 EXPORT_SYMBOL(drm_gem_fb_vmap); 383 384 /** 385 * drm_gem_fb_vunmap - unmaps framebuffer BOs from kernel address space 386 * @fb: the framebuffer 387 * @map: mapping addresses as returned by drm_gem_fb_vmap() 388 * 389 * This function unmaps all buffer objects of the given framebuffer. 390 * 391 * See drm_gem_fb_vmap() for more information. 392 */ 393 void drm_gem_fb_vunmap(struct drm_framebuffer *fb, struct iosys_map *map) 394 { 395 unsigned int i = fb->format->num_planes; 396 struct drm_gem_object *obj; 397 398 while (i) { 399 --i; 400 obj = drm_gem_fb_get_obj(fb, i); 401 if (!obj) 402 continue; 403 if (iosys_map_is_null(&map[i])) 404 continue; 405 drm_gem_vunmap_unlocked(obj, &map[i]); 406 } 407 } 408 EXPORT_SYMBOL(drm_gem_fb_vunmap); 409 410 static void __drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir, 411 unsigned int num_planes) 412 { 413 struct dma_buf_attachment *import_attach; 414 struct drm_gem_object *obj; 415 int ret; 416 417 while (num_planes) { 418 --num_planes; 419 obj = drm_gem_fb_get_obj(fb, num_planes); 420 if (!obj) 421 continue; 422 import_attach = obj->import_attach; 423 if (!import_attach) 424 continue; 425 ret = dma_buf_end_cpu_access(import_attach->dmabuf, dir); 426 if (ret) 427 drm_err(fb->dev, "dma_buf_end_cpu_access(%u, %d) failed: %d\n", 428 ret, num_planes, dir); 429 } 430 } 431 432 /** 433 * drm_gem_fb_begin_cpu_access - prepares GEM buffer objects for CPU access 434 * @fb: the framebuffer 435 * @dir: access mode 436 * 437 * Prepares a framebuffer's GEM buffer objects for CPU access. This function 438 * must be called before accessing the BO data within the kernel. For imported 439 * BOs, the function calls dma_buf_begin_cpu_access(). 440 * 441 * See drm_gem_fb_end_cpu_access() for signalling the end of CPU access. 442 * 443 * Returns: 444 * 0 on success, or a negative errno code otherwise. 445 */ 446 int drm_gem_fb_begin_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir) 447 { 448 struct dma_buf_attachment *import_attach; 449 struct drm_gem_object *obj; 450 unsigned int i; 451 int ret; 452 453 for (i = 0; i < fb->format->num_planes; ++i) { 454 obj = drm_gem_fb_get_obj(fb, i); 455 if (!obj) { 456 ret = -EINVAL; 457 goto err___drm_gem_fb_end_cpu_access; 458 } 459 import_attach = obj->import_attach; 460 if (!import_attach) 461 continue; 462 ret = dma_buf_begin_cpu_access(import_attach->dmabuf, dir); 463 if (ret) 464 goto err___drm_gem_fb_end_cpu_access; 465 } 466 467 return 0; 468 469 err___drm_gem_fb_end_cpu_access: 470 __drm_gem_fb_end_cpu_access(fb, dir, i); 471 return ret; 472 } 473 EXPORT_SYMBOL(drm_gem_fb_begin_cpu_access); 474 475 /** 476 * drm_gem_fb_end_cpu_access - signals end of CPU access to GEM buffer objects 477 * @fb: the framebuffer 478 * @dir: access mode 479 * 480 * Signals the end of CPU access to the given framebuffer's GEM buffer objects. This 481 * function must be paired with a corresponding call to drm_gem_fb_begin_cpu_access(). 482 * For imported BOs, the function calls dma_buf_end_cpu_access(). 483 * 484 * See also drm_gem_fb_begin_cpu_access(). 485 */ 486 void drm_gem_fb_end_cpu_access(struct drm_framebuffer *fb, enum dma_data_direction dir) 487 { 488 __drm_gem_fb_end_cpu_access(fb, dir, fb->format->num_planes); 489 } 490 EXPORT_SYMBOL(drm_gem_fb_end_cpu_access); 491 492 // TODO Drop this function and replace by drm_format_info_bpp() once all 493 // DRM_FORMAT_* provide proper block info in drivers/gpu/drm/drm_fourcc.c 494 static __u32 drm_gem_afbc_get_bpp(struct drm_device *dev, 495 const struct drm_mode_fb_cmd2 *mode_cmd) 496 { 497 const struct drm_format_info *info; 498 499 info = drm_get_format_info(dev, mode_cmd); 500 501 switch (info->format) { 502 case DRM_FORMAT_YUV420_8BIT: 503 return 12; 504 case DRM_FORMAT_YUV420_10BIT: 505 return 15; 506 case DRM_FORMAT_VUY101010: 507 return 30; 508 default: 509 return drm_format_info_bpp(info, 0); 510 } 511 } 512 513 static int drm_gem_afbc_min_size(struct drm_device *dev, 514 const struct drm_mode_fb_cmd2 *mode_cmd, 515 struct drm_afbc_framebuffer *afbc_fb) 516 { 517 __u32 n_blocks, w_alignment, h_alignment, hdr_alignment; 518 /* remove bpp when all users properly encode cpp in drm_format_info */ 519 __u32 bpp; 520 521 switch (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) { 522 case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16: 523 afbc_fb->block_width = 16; 524 afbc_fb->block_height = 16; 525 break; 526 case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8: 527 afbc_fb->block_width = 32; 528 afbc_fb->block_height = 8; 529 break; 530 /* no user exists yet - fall through */ 531 case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4: 532 case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4: 533 default: 534 drm_dbg_kms(dev, "Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n", 535 mode_cmd->modifier[0] 536 & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK); 537 return -EINVAL; 538 } 539 540 /* tiled header afbc */ 541 w_alignment = afbc_fb->block_width; 542 h_alignment = afbc_fb->block_height; 543 hdr_alignment = AFBC_HDR_ALIGN; 544 if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) { 545 w_alignment *= AFBC_TH_LAYOUT_ALIGNMENT; 546 h_alignment *= AFBC_TH_LAYOUT_ALIGNMENT; 547 hdr_alignment = AFBC_TH_BODY_START_ALIGNMENT; 548 } 549 550 afbc_fb->aligned_width = ALIGN(mode_cmd->width, w_alignment); 551 afbc_fb->aligned_height = ALIGN(mode_cmd->height, h_alignment); 552 afbc_fb->offset = mode_cmd->offsets[0]; 553 554 bpp = drm_gem_afbc_get_bpp(dev, mode_cmd); 555 if (!bpp) { 556 drm_dbg_kms(dev, "Invalid AFBC bpp value: %d\n", bpp); 557 return -EINVAL; 558 } 559 560 n_blocks = (afbc_fb->aligned_width * afbc_fb->aligned_height) 561 / AFBC_SUPERBLOCK_PIXELS; 562 afbc_fb->afbc_size = ALIGN(n_blocks * AFBC_HEADER_SIZE, hdr_alignment); 563 afbc_fb->afbc_size += n_blocks * ALIGN(bpp * AFBC_SUPERBLOCK_PIXELS / 8, 564 AFBC_SUPERBLOCK_ALIGNMENT); 565 566 return 0; 567 } 568 569 /** 570 * drm_gem_fb_afbc_init() - Helper function for drivers using afbc to 571 * fill and validate all the afbc-specific 572 * struct drm_afbc_framebuffer members 573 * 574 * @dev: DRM device 575 * @afbc_fb: afbc-specific framebuffer 576 * @mode_cmd: Metadata from the userspace framebuffer creation request 577 * @afbc_fb: afbc framebuffer 578 * 579 * This function can be used by drivers which support afbc to complete 580 * the preparation of struct drm_afbc_framebuffer. It must be called after 581 * allocating the said struct and calling drm_gem_fb_init_with_funcs(). 582 * It is caller's responsibility to put afbc_fb->base.obj objects in case 583 * the call is unsuccessful. 584 * 585 * Returns: 586 * Zero on success or a negative error value on failure. 587 */ 588 int drm_gem_fb_afbc_init(struct drm_device *dev, 589 const struct drm_mode_fb_cmd2 *mode_cmd, 590 struct drm_afbc_framebuffer *afbc_fb) 591 { 592 const struct drm_format_info *info; 593 struct drm_gem_object **objs; 594 int ret; 595 596 objs = afbc_fb->base.obj; 597 info = drm_get_format_info(dev, mode_cmd); 598 if (!info) 599 return -EINVAL; 600 601 ret = drm_gem_afbc_min_size(dev, mode_cmd, afbc_fb); 602 if (ret < 0) 603 return ret; 604 605 if (objs[0]->size < afbc_fb->afbc_size) 606 return -EINVAL; 607 608 return 0; 609 } 610 EXPORT_SYMBOL_GPL(drm_gem_fb_afbc_init); 611