aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_atomic_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_atomic_helper.c')
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c106
1 files changed, 85 insertions, 21 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index bbdbe4721573..541ba833ed36 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -330,7 +330,29 @@ mode_fixup(struct drm_atomic_state *state)
330 return 0; 330 return 0;
331} 331}
332 332
333static int 333/**
334 * drm_atomic_helper_check - validate state object for modeset changes
335 * @dev: DRM device
336 * @state: the driver state object
337 *
338 * Check the state object to see if the requested state is physically possible.
339 * This does all the crtc and connector related computations for an atomic
340 * update. It computes and updates crtc_state->mode_changed, adds any additional
341 * connectors needed for full modesets and calls down into ->mode_fixup
342 * functions of the driver backend.
343 *
344 * IMPORTANT:
345 *
346 * Drivers which update ->mode_changed (e.g. in their ->atomic_check hooks if a
347 * plane update can't be done without a full modeset) _must_ call this function
348 * afterwards after that change. It is permitted to call this function multiple
349 * times for the same update, e.g. when the ->atomic_check functions depend upon
350 * the adjusted dotclock for fifo space allocation and watermark computation.
351 *
352 * RETURNS
353 * Zero for success or -errno
354 */
355int
334drm_atomic_helper_check_modeset(struct drm_device *dev, 356drm_atomic_helper_check_modeset(struct drm_device *dev,
335 struct drm_atomic_state *state) 357 struct drm_atomic_state *state)
336{ 358{
@@ -406,23 +428,23 @@ drm_atomic_helper_check_modeset(struct drm_device *dev,
406 428
407 return mode_fixup(state); 429 return mode_fixup(state);
408} 430}
431EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
409 432
410/** 433/**
411 * drm_atomic_helper_check - validate state object 434 * drm_atomic_helper_check - validate state object for modeset changes
412 * @dev: DRM device 435 * @dev: DRM device
413 * @state: the driver state object 436 * @state: the driver state object
414 * 437 *
415 * Check the state object to see if the requested state is physically possible. 438 * Check the state object to see if the requested state is physically possible.
416 * Only crtcs and planes have check callbacks, so for any additional (global) 439 * This does all the plane update related checks using by calling into the
417 * checking that a driver needs it can simply wrap that around this function. 440 * ->atomic_check hooks provided by the driver.
418 * Drivers without such needs can directly use this as their ->atomic_check()
419 * callback.
420 * 441 *
421 * RETURNS 442 * RETURNS
422 * Zero for success or -errno 443 * Zero for success or -errno
423 */ 444 */
424int drm_atomic_helper_check(struct drm_device *dev, 445int
425 struct drm_atomic_state *state) 446drm_atomic_helper_check_planes(struct drm_device *dev,
447 struct drm_atomic_state *state)
426{ 448{
427 int nplanes = dev->mode_config.num_total_plane; 449 int nplanes = dev->mode_config.num_total_plane;
428 int ncrtcs = dev->mode_config.num_crtc; 450 int ncrtcs = dev->mode_config.num_crtc;
@@ -445,7 +467,7 @@ int drm_atomic_helper_check(struct drm_device *dev,
445 467
446 ret = funcs->atomic_check(plane, plane_state); 468 ret = funcs->atomic_check(plane, plane_state);
447 if (ret) { 469 if (ret) {
448 DRM_DEBUG_KMS("[PLANE:%d] atomic check failed\n", 470 DRM_DEBUG_KMS("[PLANE:%d] atomic driver check failed\n",
449 plane->base.id); 471 plane->base.id);
450 return ret; 472 return ret;
451 } 473 }
@@ -465,16 +487,49 @@ int drm_atomic_helper_check(struct drm_device *dev,
465 487
466 ret = funcs->atomic_check(crtc, state->crtc_states[i]); 488 ret = funcs->atomic_check(crtc, state->crtc_states[i]);
467 if (ret) { 489 if (ret) {
468 DRM_DEBUG_KMS("[CRTC:%d] atomic check failed\n", 490 DRM_DEBUG_KMS("[CRTC:%d] atomic driver check failed\n",
469 crtc->base.id); 491 crtc->base.id);
470 return ret; 492 return ret;
471 } 493 }
472 } 494 }
473 495
496 return ret;
497}
498EXPORT_SYMBOL(drm_atomic_helper_check_planes);
499
500/**
501 * drm_atomic_helper_check - validate state object
502 * @dev: DRM device
503 * @state: the driver state object
504 *
505 * Check the state object to see if the requested state is physically possible.
506 * Only crtcs and planes have check callbacks, so for any additional (global)
507 * checking that a driver needs it can simply wrap that around this function.
508 * Drivers without such needs can directly use this as their ->atomic_check()
509 * callback.
510 *
511 * This just wraps the two parts of the state checking for planes and modeset
512 * state in the default order: First it calls drm_atomic_helper_check_modeset()
513 * and then drm_atomic_helper_check_planes(). The assumption is that the
514 * ->atomic_check functions depend upon an updated adjusted_mode.clock to
515 * e.g. properly compute watermarks.
516 *
517 * RETURNS
518 * Zero for success or -errno
519 */
520int drm_atomic_helper_check(struct drm_device *dev,
521 struct drm_atomic_state *state)
522{
523 int ret;
524
474 ret = drm_atomic_helper_check_modeset(dev, state); 525 ret = drm_atomic_helper_check_modeset(dev, state);
475 if (ret) 526 if (ret)
476 return ret; 527 return ret;
477 528
529 ret = drm_atomic_helper_check_planes(dev, state);
530 if (ret)
531 return ret;
532
478 return ret; 533 return ret;
479} 534}
480EXPORT_SYMBOL(drm_atomic_helper_check); 535EXPORT_SYMBOL(drm_atomic_helper_check);
@@ -1222,7 +1277,7 @@ retry:
1222 goto fail; 1277 goto fail;
1223 } 1278 }
1224 1279
1225 ret = drm_atomic_set_crtc_for_plane(state, plane, crtc); 1280 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
1226 if (ret != 0) 1281 if (ret != 0)
1227 goto fail; 1282 goto fail;
1228 drm_atomic_set_fb_for_plane(plane_state, fb); 1283 drm_atomic_set_fb_for_plane(plane_state, fb);
@@ -1301,7 +1356,7 @@ retry:
1301 goto fail; 1356 goto fail;
1302 } 1357 }
1303 1358
1304 ret = drm_atomic_set_crtc_for_plane(state, plane, NULL); 1359 ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
1305 if (ret != 0) 1360 if (ret != 0)
1306 goto fail; 1361 goto fail;
1307 drm_atomic_set_fb_for_plane(plane_state, NULL); 1362 drm_atomic_set_fb_for_plane(plane_state, NULL);
@@ -1464,7 +1519,7 @@ retry:
1464 1519
1465 crtc_state->enable = false; 1520 crtc_state->enable = false;
1466 1521
1467 ret = drm_atomic_set_crtc_for_plane(state, crtc->primary, NULL); 1522 ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
1468 if (ret != 0) 1523 if (ret != 0)
1469 goto fail; 1524 goto fail;
1470 1525
@@ -1479,7 +1534,7 @@ retry:
1479 crtc_state->enable = true; 1534 crtc_state->enable = true;
1480 drm_mode_copy(&crtc_state->mode, set->mode); 1535 drm_mode_copy(&crtc_state->mode, set->mode);
1481 1536
1482 ret = drm_atomic_set_crtc_for_plane(state, crtc->primary, crtc); 1537 ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
1483 if (ret != 0) 1538 if (ret != 0)
1484 goto fail; 1539 goto fail;
1485 drm_atomic_set_fb_for_plane(primary_state, set->fb); 1540 drm_atomic_set_fb_for_plane(primary_state, set->fb);
@@ -1558,8 +1613,8 @@ retry:
1558 goto fail; 1613 goto fail;
1559 } 1614 }
1560 1615
1561 ret = crtc->funcs->atomic_set_property(crtc, crtc_state, 1616 ret = drm_atomic_crtc_set_property(crtc, crtc_state,
1562 property, val); 1617 property, val);
1563 if (ret) 1618 if (ret)
1564 goto fail; 1619 goto fail;
1565 1620
@@ -1617,8 +1672,8 @@ retry:
1617 goto fail; 1672 goto fail;
1618 } 1673 }
1619 1674
1620 ret = plane->funcs->atomic_set_property(plane, plane_state, 1675 ret = drm_atomic_plane_set_property(plane, plane_state,
1621 property, val); 1676 property, val);
1622 if (ret) 1677 if (ret)
1623 goto fail; 1678 goto fail;
1624 1679
@@ -1676,8 +1731,8 @@ retry:
1676 goto fail; 1731 goto fail;
1677 } 1732 }
1678 1733
1679 ret = connector->funcs->atomic_set_property(connector, connector_state, 1734 ret = drm_atomic_connector_set_property(connector, connector_state,
1680 property, val); 1735 property, val);
1681 if (ret) 1736 if (ret)
1682 goto fail; 1737 goto fail;
1683 1738
@@ -1751,7 +1806,7 @@ retry:
1751 goto fail; 1806 goto fail;
1752 } 1807 }
1753 1808
1754 ret = drm_atomic_set_crtc_for_plane(state, plane, crtc); 1809 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
1755 if (ret != 0) 1810 if (ret != 0)
1756 goto fail; 1811 goto fail;
1757 drm_atomic_set_fb_for_plane(plane_state, fb); 1812 drm_atomic_set_fb_for_plane(plane_state, fb);
@@ -1814,6 +1869,9 @@ void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
1814{ 1869{
1815 kfree(crtc->state); 1870 kfree(crtc->state);
1816 crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL); 1871 crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
1872
1873 if (crtc->state)
1874 crtc->state->crtc = crtc;
1817} 1875}
1818EXPORT_SYMBOL(drm_atomic_helper_crtc_reset); 1876EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
1819 1877
@@ -1873,6 +1931,9 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane)
1873 1931
1874 kfree(plane->state); 1932 kfree(plane->state);
1875 plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); 1933 plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
1934
1935 if (plane->state)
1936 plane->state->plane = plane;
1876} 1937}
1877EXPORT_SYMBOL(drm_atomic_helper_plane_reset); 1938EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
1878 1939
@@ -1930,6 +1991,9 @@ void drm_atomic_helper_connector_reset(struct drm_connector *connector)
1930{ 1991{
1931 kfree(connector->state); 1992 kfree(connector->state);
1932 connector->state = kzalloc(sizeof(*connector->state), GFP_KERNEL); 1993 connector->state = kzalloc(sizeof(*connector->state), GFP_KERNEL);
1994
1995 if (connector->state)
1996 connector->state->connector = connector;
1933} 1997}
1934EXPORT_SYMBOL(drm_atomic_helper_connector_reset); 1998EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
1935 1999