1 // SPDX-License-Identifier: GPL-2.0-or-later 2 3 #include <linux/dma-resv.h> 4 #include <linux/dma-fence-chain.h> 5 6 #include <drm/drm_atomic_state_helper.h> 7 #include <drm/drm_atomic_uapi.h> 8 #include <drm/drm_gem.h> 9 #include <drm/drm_gem_atomic_helper.h> 10 #include <drm/drm_gem_framebuffer_helper.h> 11 #include <drm/drm_simple_kms_helper.h> 12 13 #include "drm_internal.h" 14 15 /** 16 * DOC: overview 17 * 18 * The GEM atomic helpers library implements generic atomic-commit 19 * functions for drivers that use GEM objects. Currently, it provides 20 * synchronization helpers, and plane state and framebuffer BO mappings 21 * for planes with shadow buffers. 22 * 23 * Before scanout, a plane's framebuffer needs to be synchronized with 24 * possible writers that draw into the framebuffer. All drivers should 25 * call drm_gem_plane_helper_prepare_fb() from their implementation of 26 * struct &drm_plane_helper.prepare_fb . It sets the plane's fence from 27 * the framebuffer so that the DRM core can synchronize access automatically. 28 * 29 * drm_gem_plane_helper_prepare_fb() can also be used directly as 30 * implementation of prepare_fb. For drivers based on 31 * struct drm_simple_display_pipe, drm_gem_simple_display_pipe_prepare_fb() 32 * provides equivalent functionality. 33 * 34 * .. code-block:: c 35 * 36 * #include <drm/drm_gem_atomic_helper.h> 37 * 38 * struct drm_plane_helper_funcs driver_plane_helper_funcs = { 39 * ..., 40 * . prepare_fb = drm_gem_plane_helper_prepare_fb, 41 * }; 42 * 43 * struct drm_simple_display_pipe_funcs driver_pipe_funcs = { 44 * ..., 45 * . prepare_fb = drm_gem_simple_display_pipe_prepare_fb, 46 * }; 47 * 48 * A driver using a shadow buffer copies the content of the shadow buffers 49 * into the HW's framebuffer memory during an atomic update. This requires 50 * a mapping of the shadow buffer into kernel address space. The mappings 51 * cannot be established by commit-tail functions, such as atomic_update, 52 * as this would violate locking rules around dma_buf_vmap(). 53 * 54 * The helpers for shadow-buffered planes establish and release mappings, 55 * and provide struct drm_shadow_plane_state, which stores the plane's mapping 56 * for commit-tail functions. 57 * 58 * Shadow-buffered planes can easily be enabled by using the provided macros 59 * %DRM_GEM_SHADOW_PLANE_FUNCS and %DRM_GEM_SHADOW_PLANE_HELPER_FUNCS. 60 * These macros set up the plane and plane-helper callbacks to point to the 61 * shadow-buffer helpers. 62 * 63 * .. code-block:: c 64 * 65 * #include <drm/drm_gem_atomic_helper.h> 66 * 67 * struct drm_plane_funcs driver_plane_funcs = { 68 * ..., 69 * DRM_GEM_SHADOW_PLANE_FUNCS, 70 * }; 71 * 72 * struct drm_plane_helper_funcs driver_plane_helper_funcs = { 73 * ..., 74 * DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, 75 * }; 76 * 77 * In the driver's atomic-update function, shadow-buffer mappings are available 78 * from the plane state. Use to_drm_shadow_plane_state() to upcast from 79 * struct drm_plane_state. 80 * 81 * .. code-block:: c 82 * 83 * void driver_plane_atomic_update(struct drm_plane *plane, 84 * struct drm_plane_state *old_plane_state) 85 * { 86 * struct drm_plane_state *plane_state = plane->state; 87 * struct drm_shadow_plane_state *shadow_plane_state = 88 * to_drm_shadow_plane_state(plane_state); 89 * 90 * // access shadow buffer via shadow_plane_state->map 91 * } 92 * 93 * A mapping address for each of the framebuffer's buffer object is stored in 94 * struct &drm_shadow_plane_state.map. The mappings are valid while the state 95 * is being used. 96 * 97 * Drivers that use struct drm_simple_display_pipe can use 98 * %DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS to initialize the rsp 99 * callbacks. Access to shadow-buffer mappings is similar to regular 100 * atomic_update. 101 * 102 * .. code-block:: c 103 * 104 * struct drm_simple_display_pipe_funcs driver_pipe_funcs = { 105 * ..., 106 * DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS, 107 * }; 108 * 109 * void driver_pipe_enable(struct drm_simple_display_pipe *pipe, 110 * struct drm_crtc_state *crtc_state, 111 * struct drm_plane_state *plane_state) 112 * { 113 * struct drm_shadow_plane_state *shadow_plane_state = 114 * to_drm_shadow_plane_state(plane_state); 115 * 116 * // access shadow buffer via shadow_plane_state->map 117 * } 118 */ 119 120 /* 121 * Plane Helpers 122 */ 123 124 /** 125 * drm_gem_plane_helper_prepare_fb() - Prepare a GEM backed framebuffer 126 * @plane: Plane 127 * @state: Plane state the fence will be attached to 128 * 129 * This function extracts the exclusive fence from &drm_gem_object.resv and 130 * attaches it to plane state for the atomic helper to wait on. This is 131 * necessary to correctly implement implicit synchronization for any buffers 132 * shared as a struct &dma_buf. This function can be used as the 133 * &drm_plane_helper_funcs.prepare_fb callback. 134 * 135 * There is no need for &drm_plane_helper_funcs.cleanup_fb hook for simple 136 * GEM based framebuffer drivers which have their buffers always pinned in 137 * memory. 138 * 139 * This function is the default implementation for GEM drivers of 140 * &drm_plane_helper_funcs.prepare_fb if no callback is provided. 141 */ 142 int drm_gem_plane_helper_prepare_fb(struct drm_plane *plane, 143 struct drm_plane_state *state) 144 { 145 struct dma_fence *fence = dma_fence_get(state->fence); 146 enum dma_resv_usage usage; 147 size_t i; 148 int ret; 149 150 if (!state->fb) 151 return 0; 152 153 /* 154 * Only add the kernel fences here if there is already a fence set via 155 * explicit fencing interfaces on the atomic ioctl. 156 * 157 * This way explicit fencing can be used to overrule implicit fencing, 158 * which is important to make explicit fencing use-cases work: One 159 * example is using one buffer for 2 screens with different refresh 160 * rates. Implicit fencing will clamp rendering to the refresh rate of 161 * the slower screen, whereas explicit fence allows 2 independent 162 * render and display loops on a single buffer. If a driver allows 163 * obeys both implicit and explicit fences for plane updates, then it 164 * will break all the benefits of explicit fencing. 165 */ 166 usage = fence ? DMA_RESV_USAGE_KERNEL : DMA_RESV_USAGE_WRITE; 167 168 for (i = 0; i < state->fb->format->num_planes; ++i) { 169 struct drm_gem_object *obj = drm_gem_fb_get_obj(state->fb, i); 170 struct dma_fence *new; 171 172 if (!obj) { 173 ret = -EINVAL; 174 goto error; 175 } 176 177 ret = dma_resv_get_singleton(obj->resv, usage, &new); 178 if (ret) 179 goto error; 180 181 if (new && fence) { 182 struct dma_fence_chain *chain = dma_fence_chain_alloc(); 183 184 if (!chain) { 185 ret = -ENOMEM; 186 goto error; 187 } 188 189 dma_fence_chain_init(chain, fence, new, 1); 190 fence = &chain->base; 191 192 } else if (new) { 193 fence = new; 194 } 195 } 196 197 dma_fence_put(state->fence); 198 state->fence = fence; 199 return 0; 200 201 error: 202 dma_fence_put(fence); 203 return ret; 204 } 205 EXPORT_SYMBOL_GPL(drm_gem_plane_helper_prepare_fb); 206 207 /** 208 * drm_gem_simple_display_pipe_prepare_fb - prepare_fb helper for &drm_simple_display_pipe 209 * @pipe: Simple display pipe 210 * @plane_state: Plane state 211 * 212 * This function uses drm_gem_plane_helper_prepare_fb() to extract the fences 213 * from &drm_gem_object.resv and attaches them to the plane state for the atomic 214 * helper to wait on. This is necessary to correctly implement implicit 215 * synchronization for any buffers shared as a struct &dma_buf. Drivers can use 216 * this as their &drm_simple_display_pipe_funcs.prepare_fb callback. 217 * 218 * See drm_gem_plane_helper_prepare_fb() for a discussion of implicit and 219 * explicit fencing in atomic modeset updates. 220 */ 221 int drm_gem_simple_display_pipe_prepare_fb(struct drm_simple_display_pipe *pipe, 222 struct drm_plane_state *plane_state) 223 { 224 return drm_gem_plane_helper_prepare_fb(&pipe->plane, plane_state); 225 } 226 EXPORT_SYMBOL(drm_gem_simple_display_pipe_prepare_fb); 227 228 /* 229 * Shadow-buffered Planes 230 */ 231 232 /** 233 * __drm_gem_duplicate_shadow_plane_state - duplicates shadow-buffered plane state 234 * @plane: the plane 235 * @new_shadow_plane_state: the new shadow-buffered plane state 236 * 237 * This function duplicates shadow-buffered plane state. This is helpful for drivers 238 * that subclass struct drm_shadow_plane_state. 239 * 240 * The function does not duplicate existing mappings of the shadow buffers. 241 * Mappings are maintained during the atomic commit by the plane's prepare_fb 242 * and cleanup_fb helpers. See drm_gem_prepare_shadow_fb() and drm_gem_cleanup_shadow_fb() 243 * for corresponding helpers. 244 */ 245 void 246 __drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane, 247 struct drm_shadow_plane_state *new_shadow_plane_state) 248 { 249 __drm_atomic_helper_plane_duplicate_state(plane, &new_shadow_plane_state->base); 250 } 251 EXPORT_SYMBOL(__drm_gem_duplicate_shadow_plane_state); 252 253 /** 254 * drm_gem_duplicate_shadow_plane_state - duplicates shadow-buffered plane state 255 * @plane: the plane 256 * 257 * This function implements struct &drm_plane_funcs.atomic_duplicate_state for 258 * shadow-buffered planes. It assumes the existing state to be of type 259 * struct drm_shadow_plane_state and it allocates the new state to be of this 260 * type. 261 * 262 * The function does not duplicate existing mappings of the shadow buffers. 263 * Mappings are maintained during the atomic commit by the plane's prepare_fb 264 * and cleanup_fb helpers. See drm_gem_prepare_shadow_fb() and drm_gem_cleanup_shadow_fb() 265 * for corresponding helpers. 266 * 267 * Returns: 268 * A pointer to a new plane state on success, or NULL otherwise. 269 */ 270 struct drm_plane_state * 271 drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane) 272 { 273 struct drm_plane_state *plane_state = plane->state; 274 struct drm_shadow_plane_state *new_shadow_plane_state; 275 276 if (!plane_state) 277 return NULL; 278 279 new_shadow_plane_state = kzalloc(sizeof(*new_shadow_plane_state), GFP_KERNEL); 280 if (!new_shadow_plane_state) 281 return NULL; 282 __drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state); 283 284 return &new_shadow_plane_state->base; 285 } 286 EXPORT_SYMBOL(drm_gem_duplicate_shadow_plane_state); 287 288 /** 289 * __drm_gem_destroy_shadow_plane_state - cleans up shadow-buffered plane state 290 * @shadow_plane_state: the shadow-buffered plane state 291 * 292 * This function cleans up shadow-buffered plane state. Helpful for drivers that 293 * subclass struct drm_shadow_plane_state. 294 */ 295 void __drm_gem_destroy_shadow_plane_state(struct drm_shadow_plane_state *shadow_plane_state) 296 { 297 __drm_atomic_helper_plane_destroy_state(&shadow_plane_state->base); 298 } 299 EXPORT_SYMBOL(__drm_gem_destroy_shadow_plane_state); 300 301 /** 302 * drm_gem_destroy_shadow_plane_state - deletes shadow-buffered plane state 303 * @plane: the plane 304 * @plane_state: the plane state of type struct drm_shadow_plane_state 305 * 306 * This function implements struct &drm_plane_funcs.atomic_destroy_state 307 * for shadow-buffered planes. It expects that mappings of shadow buffers 308 * have been released already. 309 */ 310 void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane, 311 struct drm_plane_state *plane_state) 312 { 313 struct drm_shadow_plane_state *shadow_plane_state = 314 to_drm_shadow_plane_state(plane_state); 315 316 __drm_gem_destroy_shadow_plane_state(shadow_plane_state); 317 kfree(shadow_plane_state); 318 } 319 EXPORT_SYMBOL(drm_gem_destroy_shadow_plane_state); 320 321 /** 322 * __drm_gem_reset_shadow_plane - resets a shadow-buffered plane 323 * @plane: the plane 324 * @shadow_plane_state: the shadow-buffered plane state 325 * 326 * This function resets state for shadow-buffered planes. Helpful 327 * for drivers that subclass struct drm_shadow_plane_state. 328 */ 329 void __drm_gem_reset_shadow_plane(struct drm_plane *plane, 330 struct drm_shadow_plane_state *shadow_plane_state) 331 { 332 __drm_atomic_helper_plane_reset(plane, &shadow_plane_state->base); 333 } 334 EXPORT_SYMBOL(__drm_gem_reset_shadow_plane); 335 336 /** 337 * drm_gem_reset_shadow_plane - resets a shadow-buffered plane 338 * @plane: the plane 339 * 340 * This function implements struct &drm_plane_funcs.reset_plane for 341 * shadow-buffered planes. It assumes the current plane state to be 342 * of type struct drm_shadow_plane and it allocates the new state of 343 * this type. 344 */ 345 void drm_gem_reset_shadow_plane(struct drm_plane *plane) 346 { 347 struct drm_shadow_plane_state *shadow_plane_state; 348 349 if (plane->state) { 350 drm_gem_destroy_shadow_plane_state(plane, plane->state); 351 plane->state = NULL; /* must be set to NULL here */ 352 } 353 354 shadow_plane_state = kzalloc(sizeof(*shadow_plane_state), GFP_KERNEL); 355 if (!shadow_plane_state) 356 return; 357 __drm_gem_reset_shadow_plane(plane, shadow_plane_state); 358 } 359 EXPORT_SYMBOL(drm_gem_reset_shadow_plane); 360 361 /** 362 * drm_gem_prepare_shadow_fb - prepares shadow framebuffers 363 * @plane: the plane 364 * @plane_state: the plane state of type struct drm_shadow_plane_state 365 * 366 * This function implements struct &drm_plane_helper_funcs.prepare_fb. It 367 * maps all buffer objects of the plane's framebuffer into kernel address 368 * space and stores them in &struct drm_shadow_plane_state.map. The 369 * framebuffer will be synchronized as part of the atomic commit. 370 * 371 * See drm_gem_cleanup_shadow_fb() for cleanup. 372 * 373 * Returns: 374 * 0 on success, or a negative errno code otherwise. 375 */ 376 int drm_gem_prepare_shadow_fb(struct drm_plane *plane, struct drm_plane_state *plane_state) 377 { 378 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); 379 struct drm_framebuffer *fb = plane_state->fb; 380 int ret; 381 382 if (!fb) 383 return 0; 384 385 ret = drm_gem_plane_helper_prepare_fb(plane, plane_state); 386 if (ret) 387 return ret; 388 389 return drm_gem_fb_vmap(fb, shadow_plane_state->map, shadow_plane_state->data); 390 } 391 EXPORT_SYMBOL(drm_gem_prepare_shadow_fb); 392 393 /** 394 * drm_gem_cleanup_shadow_fb - releases shadow framebuffers 395 * @plane: the plane 396 * @plane_state: the plane state of type struct drm_shadow_plane_state 397 * 398 * This function implements struct &drm_plane_helper_funcs.cleanup_fb. 399 * This function unmaps all buffer objects of the plane's framebuffer. 400 * 401 * See drm_gem_prepare_shadow_fb() for more information. 402 */ 403 void drm_gem_cleanup_shadow_fb(struct drm_plane *plane, struct drm_plane_state *plane_state) 404 { 405 struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); 406 struct drm_framebuffer *fb = plane_state->fb; 407 408 if (!fb) 409 return; 410 411 drm_gem_fb_vunmap(fb, shadow_plane_state->map); 412 } 413 EXPORT_SYMBOL(drm_gem_cleanup_shadow_fb); 414 415 /** 416 * drm_gem_simple_kms_prepare_shadow_fb - prepares shadow framebuffers 417 * @pipe: the simple display pipe 418 * @plane_state: the plane state of type struct drm_shadow_plane_state 419 * 420 * This function implements struct drm_simple_display_funcs.prepare_fb. It 421 * maps all buffer objects of the plane's framebuffer into kernel address 422 * space and stores them in struct drm_shadow_plane_state.map. The 423 * framebuffer will be synchronized as part of the atomic commit. 424 * 425 * See drm_gem_simple_kms_cleanup_shadow_fb() for cleanup. 426 * 427 * Returns: 428 * 0 on success, or a negative errno code otherwise. 429 */ 430 int drm_gem_simple_kms_prepare_shadow_fb(struct drm_simple_display_pipe *pipe, 431 struct drm_plane_state *plane_state) 432 { 433 return drm_gem_prepare_shadow_fb(&pipe->plane, plane_state); 434 } 435 EXPORT_SYMBOL(drm_gem_simple_kms_prepare_shadow_fb); 436 437 /** 438 * drm_gem_simple_kms_cleanup_shadow_fb - releases shadow framebuffers 439 * @pipe: the simple display pipe 440 * @plane_state: the plane state of type struct drm_shadow_plane_state 441 * 442 * This function implements struct drm_simple_display_funcs.cleanup_fb. 443 * This function unmaps all buffer objects of the plane's framebuffer. 444 * 445 * See drm_gem_simple_kms_prepare_shadow_fb(). 446 */ 447 void drm_gem_simple_kms_cleanup_shadow_fb(struct drm_simple_display_pipe *pipe, 448 struct drm_plane_state *plane_state) 449 { 450 drm_gem_cleanup_shadow_fb(&pipe->plane, plane_state); 451 } 452 EXPORT_SYMBOL(drm_gem_simple_kms_cleanup_shadow_fb); 453 454 /** 455 * drm_gem_simple_kms_reset_shadow_plane - resets a shadow-buffered plane 456 * @pipe: the simple display pipe 457 * 458 * This function implements struct drm_simple_display_funcs.reset_plane 459 * for shadow-buffered planes. 460 */ 461 void drm_gem_simple_kms_reset_shadow_plane(struct drm_simple_display_pipe *pipe) 462 { 463 drm_gem_reset_shadow_plane(&pipe->plane); 464 } 465 EXPORT_SYMBOL(drm_gem_simple_kms_reset_shadow_plane); 466 467 /** 468 * drm_gem_simple_kms_duplicate_shadow_plane_state - duplicates shadow-buffered plane state 469 * @pipe: the simple display pipe 470 * 471 * This function implements struct drm_simple_display_funcs.duplicate_plane_state 472 * for shadow-buffered planes. It does not duplicate existing mappings of the shadow 473 * buffers. Mappings are maintained during the atomic commit by the plane's prepare_fb 474 * and cleanup_fb helpers. 475 * 476 * Returns: 477 * A pointer to a new plane state on success, or NULL otherwise. 478 */ 479 struct drm_plane_state * 480 drm_gem_simple_kms_duplicate_shadow_plane_state(struct drm_simple_display_pipe *pipe) 481 { 482 return drm_gem_duplicate_shadow_plane_state(&pipe->plane); 483 } 484 EXPORT_SYMBOL(drm_gem_simple_kms_duplicate_shadow_plane_state); 485 486 /** 487 * drm_gem_simple_kms_destroy_shadow_plane_state - resets shadow-buffered plane state 488 * @pipe: the simple display pipe 489 * @plane_state: the plane state of type struct drm_shadow_plane_state 490 * 491 * This function implements struct drm_simple_display_funcs.destroy_plane_state 492 * for shadow-buffered planes. It expects that mappings of shadow buffers 493 * have been released already. 494 */ 495 void drm_gem_simple_kms_destroy_shadow_plane_state(struct drm_simple_display_pipe *pipe, 496 struct drm_plane_state *plane_state) 497 { 498 drm_gem_destroy_shadow_plane_state(&pipe->plane, plane_state); 499 } 500 EXPORT_SYMBOL(drm_gem_simple_kms_destroy_shadow_plane_state); 501