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