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