linux/drivers/gpu/drm/drm_atomic_state_helper.c
<<
>>
Prefs
   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 */
  72void
  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}
  81EXPORT_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 */
  90void 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}
 100EXPORT_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 */
 110void __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        /* Self refresh should be canceled when a new update is available */
 134        state->active = drm_atomic_crtc_effectively_active(state);
 135        state->self_refresh_active = false;
 136}
 137EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
 138
 139/**
 140 * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook
 141 * @crtc: drm CRTC
 142 *
 143 * Default CRTC state duplicate hook for drivers which don't have their own
 144 * subclassed CRTC state structure.
 145 */
 146struct drm_crtc_state *
 147drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
 148{
 149        struct drm_crtc_state *state;
 150
 151        if (WARN_ON(!crtc->state))
 152                return NULL;
 153
 154        state = kmalloc(sizeof(*state), GFP_KERNEL);
 155        if (state)
 156                __drm_atomic_helper_crtc_duplicate_state(crtc, state);
 157
 158        return state;
 159}
 160EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
 161
 162/**
 163 * __drm_atomic_helper_crtc_destroy_state - release CRTC state
 164 * @state: CRTC state object to release
 165 *
 166 * Releases all resources stored in the CRTC state without actually freeing
 167 * the memory of the CRTC state. This is useful for drivers that subclass the
 168 * CRTC state.
 169 */
 170void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
 171{
 172        if (state->commit) {
 173                /*
 174                 * In the event that a non-blocking commit returns
 175                 * -ERESTARTSYS before the commit_tail work is queued, we will
 176                 * have an extra reference to the commit object. Release it, if
 177                 * the event has not been consumed by the worker.
 178                 *
 179                 * state->event may be freed, so we can't directly look at
 180                 * state->event->base.completion.
 181                 */
 182                if (state->event && state->commit->abort_completion)
 183                        drm_crtc_commit_put(state->commit);
 184
 185                kfree(state->commit->event);
 186                state->commit->event = NULL;
 187
 188                drm_crtc_commit_put(state->commit);
 189        }
 190
 191        drm_property_blob_put(state->mode_blob);
 192        drm_property_blob_put(state->degamma_lut);
 193        drm_property_blob_put(state->ctm);
 194        drm_property_blob_put(state->gamma_lut);
 195}
 196EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
 197
 198/**
 199 * drm_atomic_helper_crtc_destroy_state - default state destroy hook
 200 * @crtc: drm CRTC
 201 * @state: CRTC state object to release
 202 *
 203 * Default CRTC state destroy hook for drivers which don't have their own
 204 * subclassed CRTC state structure.
 205 */
 206void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
 207                                          struct drm_crtc_state *state)
 208{
 209        __drm_atomic_helper_crtc_destroy_state(state);
 210        kfree(state);
 211}
 212EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
 213
 214/**
 215 * __drm_atomic_helper_plane_reset - resets planes state to default values
 216 * @plane: plane object, must not be NULL
 217 * @state: atomic plane state, must not be NULL
 218 *
 219 * Initializes plane state to default. This is useful for drivers that subclass
 220 * the plane state.
 221 */
 222void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
 223                                     struct drm_plane_state *state)
 224{
 225        state->plane = plane;
 226        state->rotation = DRM_MODE_ROTATE_0;
 227
 228        state->alpha = DRM_BLEND_ALPHA_OPAQUE;
 229        state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
 230
 231        plane->state = state;
 232}
 233EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
 234
 235/**
 236 * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes
 237 * @plane: drm plane
 238 *
 239 * Resets the atomic state for @plane by freeing the state pointer (which might
 240 * be NULL, e.g. at driver load time) and allocating a new empty state object.
 241 */
 242void drm_atomic_helper_plane_reset(struct drm_plane *plane)
 243{
 244        if (plane->state)
 245                __drm_atomic_helper_plane_destroy_state(plane->state);
 246
 247        kfree(plane->state);
 248        plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
 249        if (plane->state)
 250                __drm_atomic_helper_plane_reset(plane, plane->state);
 251}
 252EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
 253
 254/**
 255 * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state
 256 * @plane: plane object
 257 * @state: atomic plane state
 258 *
 259 * Copies atomic state from a plane's current state. This is useful for
 260 * drivers that subclass the plane state.
 261 */
 262void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
 263                                               struct drm_plane_state *state)
 264{
 265        memcpy(state, plane->state, sizeof(*state));
 266
 267        if (state->fb)
 268                drm_framebuffer_get(state->fb);
 269
 270        state->fence = NULL;
 271        state->commit = NULL;
 272        state->fb_damage_clips = NULL;
 273}
 274EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
 275
 276/**
 277 * drm_atomic_helper_plane_duplicate_state - default state duplicate hook
 278 * @plane: drm plane
 279 *
 280 * Default plane state duplicate hook for drivers which don't have their own
 281 * subclassed plane state structure.
 282 */
 283struct drm_plane_state *
 284drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
 285{
 286        struct drm_plane_state *state;
 287
 288        if (WARN_ON(!plane->state))
 289                return NULL;
 290
 291        state = kmalloc(sizeof(*state), GFP_KERNEL);
 292        if (state)
 293                __drm_atomic_helper_plane_duplicate_state(plane, state);
 294
 295        return state;
 296}
 297EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
 298
 299/**
 300 * __drm_atomic_helper_plane_destroy_state - release plane state
 301 * @state: plane state object to release
 302 *
 303 * Releases all resources stored in the plane state without actually freeing
 304 * the memory of the plane state. This is useful for drivers that subclass the
 305 * plane state.
 306 */
 307void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
 308{
 309        if (state->fb)
 310                drm_framebuffer_put(state->fb);
 311
 312        if (state->fence)
 313                dma_fence_put(state->fence);
 314
 315        if (state->commit)
 316                drm_crtc_commit_put(state->commit);
 317
 318        drm_property_blob_put(state->fb_damage_clips);
 319}
 320EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
 321
 322/**
 323 * drm_atomic_helper_plane_destroy_state - default state destroy hook
 324 * @plane: drm plane
 325 * @state: plane state object to release
 326 *
 327 * Default plane state destroy hook for drivers which don't have their own
 328 * subclassed plane state structure.
 329 */
 330void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
 331                                           struct drm_plane_state *state)
 332{
 333        __drm_atomic_helper_plane_destroy_state(state);
 334        kfree(state);
 335}
 336EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
 337
 338/**
 339 * __drm_atomic_helper_connector_reset - reset state on connector
 340 * @connector: drm connector
 341 * @conn_state: connector state to assign
 342 *
 343 * Initializes the newly allocated @conn_state and assigns it to
 344 * the &drm_connector->state pointer of @connector, usually required when
 345 * initializing the drivers or when called from the &drm_connector_funcs.reset
 346 * hook.
 347 *
 348 * This is useful for drivers that subclass the connector state.
 349 */
 350void
 351__drm_atomic_helper_connector_reset(struct drm_connector *connector,
 352                                    struct drm_connector_state *conn_state)
 353{
 354        if (conn_state)
 355                conn_state->connector = connector;
 356
 357        connector->state = conn_state;
 358}
 359EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
 360
 361/**
 362 * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors
 363 * @connector: drm connector
 364 *
 365 * Resets the atomic state for @connector by freeing the state pointer (which
 366 * might be NULL, e.g. at driver load time) and allocating a new empty state
 367 * object.
 368 */
 369void drm_atomic_helper_connector_reset(struct drm_connector *connector)
 370{
 371        struct drm_connector_state *conn_state =
 372                kzalloc(sizeof(*conn_state), GFP_KERNEL);
 373
 374        if (connector->state)
 375                __drm_atomic_helper_connector_destroy_state(connector->state);
 376
 377        kfree(connector->state);
 378        __drm_atomic_helper_connector_reset(connector, conn_state);
 379}
 380EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
 381
 382/**
 383 * drm_atomic_helper_connector_tv_reset - Resets TV connector properties
 384 * @connector: DRM connector
 385 *
 386 * Resets the TV-related properties attached to a connector.
 387 */
 388void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
 389{
 390        struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
 391        struct drm_connector_state *state = connector->state;
 392
 393        state->tv.margins.left = cmdline->tv_margins.left;
 394        state->tv.margins.right = cmdline->tv_margins.right;
 395        state->tv.margins.top = cmdline->tv_margins.top;
 396        state->tv.margins.bottom = cmdline->tv_margins.bottom;
 397}
 398EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
 399
 400/**
 401 * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
 402 * @connector: connector object
 403 * @state: atomic connector state
 404 *
 405 * Copies atomic state from a connector's current state. This is useful for
 406 * drivers that subclass the connector state.
 407 */
 408void
 409__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
 410                                            struct drm_connector_state *state)
 411{
 412        memcpy(state, connector->state, sizeof(*state));
 413        if (state->crtc)
 414                drm_connector_get(connector);
 415        state->commit = NULL;
 416
 417        if (state->hdr_output_metadata)
 418                drm_property_blob_get(state->hdr_output_metadata);
 419
 420        /* Don't copy over a writeback job, they are used only once */
 421        state->writeback_job = NULL;
 422}
 423EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
 424
 425/**
 426 * drm_atomic_helper_connector_duplicate_state - default state duplicate hook
 427 * @connector: drm connector
 428 *
 429 * Default connector state duplicate hook for drivers which don't have their own
 430 * subclassed connector state structure.
 431 */
 432struct drm_connector_state *
 433drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
 434{
 435        struct drm_connector_state *state;
 436
 437        if (WARN_ON(!connector->state))
 438                return NULL;
 439
 440        state = kmalloc(sizeof(*state), GFP_KERNEL);
 441        if (state)
 442                __drm_atomic_helper_connector_duplicate_state(connector, state);
 443
 444        return state;
 445}
 446EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
 447
 448/**
 449 * __drm_atomic_helper_connector_destroy_state - release connector state
 450 * @state: connector state object to release
 451 *
 452 * Releases all resources stored in the connector state without actually
 453 * freeing the memory of the connector state. This is useful for drivers that
 454 * subclass the connector state.
 455 */
 456void
 457__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
 458{
 459        if (state->crtc)
 460                drm_connector_put(state->connector);
 461
 462        if (state->commit)
 463                drm_crtc_commit_put(state->commit);
 464
 465        if (state->writeback_job)
 466                drm_writeback_cleanup_job(state->writeback_job);
 467
 468        drm_property_blob_put(state->hdr_output_metadata);
 469}
 470EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
 471
 472/**
 473 * drm_atomic_helper_connector_destroy_state - default state destroy hook
 474 * @connector: drm connector
 475 * @state: connector state object to release
 476 *
 477 * Default connector state destroy hook for drivers which don't have their own
 478 * subclassed connector state structure.
 479 */
 480void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
 481                                          struct drm_connector_state *state)
 482{
 483        __drm_atomic_helper_connector_destroy_state(state);
 484        kfree(state);
 485}
 486EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
 487
 488/**
 489 * __drm_atomic_helper_private_duplicate_state - copy atomic private state
 490 * @obj: CRTC object
 491 * @state: new private object state
 492 *
 493 * Copies atomic state from a private objects's current state and resets inferred values.
 494 * This is useful for drivers that subclass the private state.
 495 */
 496void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
 497                                                     struct drm_private_state *state)
 498{
 499        memcpy(state, obj->state, sizeof(*state));
 500}
 501EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
 502