1 /* 2 * Copyright (C) 2018 Intel Corp. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: 23 * Rob Clark <robdclark@gmail.com> 24 * Daniel Vetter <daniel.vetter@ffwll.ch> 25 */ 26 27 #include <drm/drm_atomic.h> 28 #include <drm/drm_atomic_state_helper.h> 29 #include <drm/drm_connector.h> 30 #include <drm/drm_crtc.h> 31 #include <drm/drm_device.h> 32 #include <drm/drm_plane.h> 33 #include <drm/drm_print.h> 34 #include <drm/drm_writeback.h> 35 36 #include <linux/slab.h> 37 #include <linux/dma-fence.h> 38 39 /** 40 * DOC: atomic state reset and initialization 41 * 42 * Both the drm core and the atomic helpers assume that there is always the full 43 * and correct atomic software state for all connectors, CRTCs and planes 44 * available. Which is a bit a problem on driver load and also after system 45 * suspend. One way to solve this is to have a hardware state read-out 46 * infrastructure which reconstructs the full software state (e.g. the i915 47 * driver). 48 * 49 * The simpler solution is to just reset the software state to everything off, 50 * which is easiest to do by calling drm_mode_config_reset(). To facilitate this 51 * the atomic helpers provide default reset implementations for all hooks. 52 * 53 * On the upside the precise state tracking of atomic simplifies system suspend 54 * and resume a lot. For drivers using drm_mode_config_reset() a complete recipe 55 * is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume(). 56 * For other drivers the building blocks are split out, see the documentation 57 * for these functions. 58 */ 59 60 /** 61 * __drm_atomic_helper_crtc_reset - reset state on CRTC 62 * @crtc: drm CRTC 63 * @crtc_state: CRTC state to assign 64 * 65 * Initializes the newly allocated @crtc_state and assigns it to 66 * the &drm_crtc->state pointer of @crtc, usually required when 67 * initializing the drivers or when called from the &drm_crtc_funcs.reset 68 * hook. 69 * 70 * This is useful for drivers that subclass the CRTC state. 71 */ 72 void 73 __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, 74 struct drm_crtc_state *crtc_state) 75 { 76 if (crtc_state) 77 crtc_state->crtc = crtc; 78 79 crtc->state = crtc_state; 80 } 81 EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset); 82 83 /** 84 * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs 85 * @crtc: drm CRTC 86 * 87 * Resets the atomic state for @crtc by freeing the state pointer (which might 88 * be NULL, e.g. at driver load time) and allocating a new empty state object. 89 */ 90 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc) 91 { 92 struct drm_crtc_state *crtc_state = 93 kzalloc(sizeof(*crtc->state), GFP_KERNEL); 94 95 if (crtc->state) 96 crtc->funcs->atomic_destroy_state(crtc, crtc->state); 97 98 __drm_atomic_helper_crtc_reset(crtc, crtc_state); 99 } 100 EXPORT_SYMBOL(drm_atomic_helper_crtc_reset); 101 102 /** 103 * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state 104 * @crtc: CRTC object 105 * @state: atomic CRTC state 106 * 107 * Copies atomic state from a CRTC's current state and resets inferred values. 108 * This is useful for drivers that subclass the CRTC state. 109 */ 110 void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc, 111 struct drm_crtc_state *state) 112 { 113 memcpy(state, crtc->state, sizeof(*state)); 114 115 if (state->mode_blob) 116 drm_property_blob_get(state->mode_blob); 117 if (state->degamma_lut) 118 drm_property_blob_get(state->degamma_lut); 119 if (state->ctm) 120 drm_property_blob_get(state->ctm); 121 if (state->gamma_lut) 122 drm_property_blob_get(state->gamma_lut); 123 state->mode_changed = false; 124 state->active_changed = false; 125 state->planes_changed = false; 126 state->connectors_changed = false; 127 state->color_mgmt_changed = false; 128 state->zpos_changed = false; 129 state->commit = NULL; 130 state->event = NULL; 131 state->pageflip_flags = 0; 132 } 133 EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state); 134 135 /** 136 * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook 137 * @crtc: drm CRTC 138 * 139 * Default CRTC state duplicate hook for drivers which don't have their own 140 * subclassed CRTC state structure. 141 */ 142 struct drm_crtc_state * 143 drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc) 144 { 145 struct drm_crtc_state *state; 146 147 if (WARN_ON(!crtc->state)) 148 return NULL; 149 150 state = kmalloc(sizeof(*state), GFP_KERNEL); 151 if (state) 152 __drm_atomic_helper_crtc_duplicate_state(crtc, state); 153 154 return state; 155 } 156 EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state); 157 158 /** 159 * __drm_atomic_helper_crtc_destroy_state - release CRTC state 160 * @state: CRTC state object to release 161 * 162 * Releases all resources stored in the CRTC state without actually freeing 163 * the memory of the CRTC state. This is useful for drivers that subclass the 164 * CRTC state. 165 */ 166 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state) 167 { 168 if (state->commit) { 169 /* 170 * In the event that a non-blocking commit returns 171 * -ERESTARTSYS before the commit_tail work is queued, we will 172 * have an extra reference to the commit object. Release it, if 173 * the event has not been consumed by the worker. 174 * 175 * state->event may be freed, so we can't directly look at 176 * state->event->base.completion. 177 */ 178 if (state->event && state->commit->abort_completion) 179 drm_crtc_commit_put(state->commit); 180 181 kfree(state->commit->event); 182 state->commit->event = NULL; 183 184 drm_crtc_commit_put(state->commit); 185 } 186 187 drm_property_blob_put(state->mode_blob); 188 drm_property_blob_put(state->degamma_lut); 189 drm_property_blob_put(state->ctm); 190 drm_property_blob_put(state->gamma_lut); 191 } 192 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state); 193 194 /** 195 * drm_atomic_helper_crtc_destroy_state - default state destroy hook 196 * @crtc: drm CRTC 197 * @state: CRTC state object to release 198 * 199 * Default CRTC state destroy hook for drivers which don't have their own 200 * subclassed CRTC state structure. 201 */ 202 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, 203 struct drm_crtc_state *state) 204 { 205 __drm_atomic_helper_crtc_destroy_state(state); 206 kfree(state); 207 } 208 EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); 209 210 /** 211 * __drm_atomic_helper_plane_reset - resets planes state to default values 212 * @plane: plane object, must not be NULL 213 * @state: atomic plane state, must not be NULL 214 * 215 * Initializes plane state to default. This is useful for drivers that subclass 216 * the plane state. 217 */ 218 void __drm_atomic_helper_plane_reset(struct drm_plane *plane, 219 struct drm_plane_state *state) 220 { 221 state->plane = plane; 222 state->rotation = DRM_MODE_ROTATE_0; 223 224 state->alpha = DRM_BLEND_ALPHA_OPAQUE; 225 state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; 226 227 plane->state = state; 228 } 229 EXPORT_SYMBOL(__drm_atomic_helper_plane_reset); 230 231 /** 232 * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes 233 * @plane: drm plane 234 * 235 * Resets the atomic state for @plane by freeing the state pointer (which might 236 * be NULL, e.g. at driver load time) and allocating a new empty state object. 237 */ 238 void drm_atomic_helper_plane_reset(struct drm_plane *plane) 239 { 240 if (plane->state) 241 __drm_atomic_helper_plane_destroy_state(plane->state); 242 243 kfree(plane->state); 244 plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); 245 if (plane->state) 246 __drm_atomic_helper_plane_reset(plane, plane->state); 247 } 248 EXPORT_SYMBOL(drm_atomic_helper_plane_reset); 249 250 /** 251 * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state 252 * @plane: plane object 253 * @state: atomic plane state 254 * 255 * Copies atomic state from a plane's current state. This is useful for 256 * drivers that subclass the plane state. 257 */ 258 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, 259 struct drm_plane_state *state) 260 { 261 memcpy(state, plane->state, sizeof(*state)); 262 263 if (state->fb) 264 drm_framebuffer_get(state->fb); 265 266 state->fence = NULL; 267 state->commit = NULL; 268 state->fb_damage_clips = NULL; 269 } 270 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state); 271 272 /** 273 * drm_atomic_helper_plane_duplicate_state - default state duplicate hook 274 * @plane: drm plane 275 * 276 * Default plane state duplicate hook for drivers which don't have their own 277 * subclassed plane state structure. 278 */ 279 struct drm_plane_state * 280 drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane) 281 { 282 struct drm_plane_state *state; 283 284 if (WARN_ON(!plane->state)) 285 return NULL; 286 287 state = kmalloc(sizeof(*state), GFP_KERNEL); 288 if (state) 289 __drm_atomic_helper_plane_duplicate_state(plane, state); 290 291 return state; 292 } 293 EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state); 294 295 /** 296 * __drm_atomic_helper_plane_destroy_state - release plane state 297 * @state: plane state object to release 298 * 299 * Releases all resources stored in the plane state without actually freeing 300 * the memory of the plane state. This is useful for drivers that subclass the 301 * plane state. 302 */ 303 void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) 304 { 305 if (state->fb) 306 drm_framebuffer_put(state->fb); 307 308 if (state->fence) 309 dma_fence_put(state->fence); 310 311 if (state->commit) 312 drm_crtc_commit_put(state->commit); 313 314 drm_property_blob_put(state->fb_damage_clips); 315 } 316 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); 317 318 /** 319 * drm_atomic_helper_plane_destroy_state - default state destroy hook 320 * @plane: drm plane 321 * @state: plane state object to release 322 * 323 * Default plane state destroy hook for drivers which don't have their own 324 * subclassed plane state structure. 325 */ 326 void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, 327 struct drm_plane_state *state) 328 { 329 __drm_atomic_helper_plane_destroy_state(state); 330 kfree(state); 331 } 332 EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); 333 334 /** 335 * __drm_atomic_helper_connector_reset - reset state on connector 336 * @connector: drm connector 337 * @conn_state: connector state to assign 338 * 339 * Initializes the newly allocated @conn_state and assigns it to 340 * the &drm_connector->state pointer of @connector, usually required when 341 * initializing the drivers or when called from the &drm_connector_funcs.reset 342 * hook. 343 * 344 * This is useful for drivers that subclass the connector state. 345 */ 346 void 347 __drm_atomic_helper_connector_reset(struct drm_connector *connector, 348 struct drm_connector_state *conn_state) 349 { 350 if (conn_state) 351 conn_state->connector = connector; 352 353 connector->state = conn_state; 354 } 355 EXPORT_SYMBOL(__drm_atomic_helper_connector_reset); 356 357 /** 358 * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors 359 * @connector: drm connector 360 * 361 * Resets the atomic state for @connector by freeing the state pointer (which 362 * might be NULL, e.g. at driver load time) and allocating a new empty state 363 * object. 364 */ 365 void drm_atomic_helper_connector_reset(struct drm_connector *connector) 366 { 367 struct drm_connector_state *conn_state = 368 kzalloc(sizeof(*conn_state), GFP_KERNEL); 369 370 if (connector->state) 371 __drm_atomic_helper_connector_destroy_state(connector->state); 372 373 kfree(connector->state); 374 __drm_atomic_helper_connector_reset(connector, conn_state); 375 } 376 EXPORT_SYMBOL(drm_atomic_helper_connector_reset); 377 378 /** 379 * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state 380 * @connector: connector object 381 * @state: atomic connector state 382 * 383 * Copies atomic state from a connector's current state. This is useful for 384 * drivers that subclass the connector state. 385 */ 386 void 387 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, 388 struct drm_connector_state *state) 389 { 390 memcpy(state, connector->state, sizeof(*state)); 391 if (state->crtc) 392 drm_connector_get(connector); 393 state->commit = NULL; 394 395 if (state->hdr_output_metadata) 396 drm_property_blob_get(state->hdr_output_metadata); 397 398 /* Don't copy over a writeback job, they are used only once */ 399 state->writeback_job = NULL; 400 } 401 EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state); 402 403 /** 404 * drm_atomic_helper_connector_duplicate_state - default state duplicate hook 405 * @connector: drm connector 406 * 407 * Default connector state duplicate hook for drivers which don't have their own 408 * subclassed connector state structure. 409 */ 410 struct drm_connector_state * 411 drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector) 412 { 413 struct drm_connector_state *state; 414 415 if (WARN_ON(!connector->state)) 416 return NULL; 417 418 state = kmalloc(sizeof(*state), GFP_KERNEL); 419 if (state) 420 __drm_atomic_helper_connector_duplicate_state(connector, state); 421 422 return state; 423 } 424 EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state); 425 426 /** 427 * __drm_atomic_helper_connector_destroy_state - release connector state 428 * @state: connector state object to release 429 * 430 * Releases all resources stored in the connector state without actually 431 * freeing the memory of the connector state. This is useful for drivers that 432 * subclass the connector state. 433 */ 434 void 435 __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state) 436 { 437 if (state->crtc) 438 drm_connector_put(state->connector); 439 440 if (state->commit) 441 drm_crtc_commit_put(state->commit); 442 443 if (state->writeback_job) 444 drm_writeback_cleanup_job(state->writeback_job); 445 446 drm_property_blob_put(state->hdr_output_metadata); 447 } 448 EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state); 449 450 /** 451 * drm_atomic_helper_connector_destroy_state - default state destroy hook 452 * @connector: drm connector 453 * @state: connector state object to release 454 * 455 * Default connector state destroy hook for drivers which don't have their own 456 * subclassed connector state structure. 457 */ 458 void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, 459 struct drm_connector_state *state) 460 { 461 __drm_atomic_helper_connector_destroy_state(state); 462 kfree(state); 463 } 464 EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state); 465 466 /** 467 * __drm_atomic_helper_private_duplicate_state - copy atomic private state 468 * @obj: CRTC object 469 * @state: new private object state 470 * 471 * Copies atomic state from a private objects's current state and resets inferred values. 472 * This is useful for drivers that subclass the private state. 473 */ 474 void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj, 475 struct drm_private_state *state) 476 { 477 memcpy(state, obj->state, sizeof(*state)); 478 } 479 EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state); 480