diff options
| author | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2017-08-07 06:20:06 -0400 |
|---|---|---|
| committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2017-08-08 08:09:34 -0400 |
| commit | 3dfeb631a15db17f187f1e5cc522207f46506611 (patch) | |
| tree | 5ef03ef049b16b09b3280535ff8ab2e2c3764f2c | |
| parent | 481e1625f04fa12cdaa80895e7d6a63eca5aa8c5 (diff) | |
drm/omap: Rework the rotation-on-crtc hack
I want/need to rework the core property handling, and this hack is
getting in the way. But since it's a non-standard propety only used by
legacy userspace we know that this will only every be called from
ioctl code. And never on some other free-standing state struct, where
this old hack wouldn't work either.
v2: don't forget zorder and get_property!
v3: Shadow the legacy state to avoid locking issues in get_property
(Maarten).
v4: Review from Laurent
- Move struct omap_crtc_state into omap_crtc.c
- Clean up comments.
- Don't forget to copy the shadowed state over on duplicate.
v5: Don't forget to update the reset handler (Maarten).
v6: Update omap_crtc_state shadow values in omap_crtc_atomic_check (Maarten).
v7:
- Fix get_property to return 0 and set value in *val (Maarten).
- Update comment in set_property for changes in v6 (Maarten).
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> (v4)
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> (v4)
Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/a6a10a4f-2ebc-5f81-00bd-5e906967f384@linux.intel.com
| -rw-r--r-- | drivers/gpu/drm/omapdrm/omap_crtc.c | 124 |
1 files changed, 85 insertions, 39 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 14e8a7738b06..09e05e002703 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c | |||
| @@ -26,6 +26,16 @@ | |||
| 26 | 26 | ||
| 27 | #include "omap_drv.h" | 27 | #include "omap_drv.h" |
| 28 | 28 | ||
| 29 | #define to_omap_crtc_state(x) container_of(x, struct omap_crtc_state, base) | ||
| 30 | |||
| 31 | struct omap_crtc_state { | ||
| 32 | /* Must be first. */ | ||
| 33 | struct drm_crtc_state base; | ||
| 34 | /* Shadow values for legacy userspace support. */ | ||
| 35 | unsigned int rotation; | ||
| 36 | unsigned int zpos; | ||
| 37 | }; | ||
| 38 | |||
| 29 | #define to_omap_crtc(x) container_of(x, struct omap_crtc, base) | 39 | #define to_omap_crtc(x) container_of(x, struct omap_crtc, base) |
| 30 | 40 | ||
| 31 | struct omap_crtc { | 41 | struct omap_crtc { |
| @@ -445,6 +455,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
| 445 | static int omap_crtc_atomic_check(struct drm_crtc *crtc, | 455 | static int omap_crtc_atomic_check(struct drm_crtc *crtc, |
| 446 | struct drm_crtc_state *state) | 456 | struct drm_crtc_state *state) |
| 447 | { | 457 | { |
| 458 | struct drm_plane_state *pri_state; | ||
| 459 | |||
| 448 | if (state->color_mgmt_changed && state->gamma_lut) { | 460 | if (state->color_mgmt_changed && state->gamma_lut) { |
| 449 | uint length = state->gamma_lut->length / | 461 | uint length = state->gamma_lut->length / |
| 450 | sizeof(struct drm_color_lut); | 462 | sizeof(struct drm_color_lut); |
| @@ -453,6 +465,16 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc, | |||
| 453 | return -EINVAL; | 465 | return -EINVAL; |
| 454 | } | 466 | } |
| 455 | 467 | ||
| 468 | pri_state = drm_atomic_get_new_plane_state(state->state, crtc->primary); | ||
| 469 | if (pri_state) { | ||
| 470 | struct omap_crtc_state *omap_crtc_state = | ||
| 471 | to_omap_crtc_state(state); | ||
| 472 | |||
| 473 | /* Mirror new values for zpos and rotation in omap_crtc_state */ | ||
| 474 | omap_crtc_state->zpos = pri_state->zpos; | ||
| 475 | omap_crtc_state->rotation = pri_state->rotation; | ||
| 476 | } | ||
| 477 | |||
| 456 | return 0; | 478 | return 0; |
| 457 | } | 479 | } |
| 458 | 480 | ||
| @@ -498,39 +520,32 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc, | |||
| 498 | spin_unlock_irq(&crtc->dev->event_lock); | 520 | spin_unlock_irq(&crtc->dev->event_lock); |
| 499 | } | 521 | } |
| 500 | 522 | ||
| 501 | static bool omap_crtc_is_plane_prop(struct drm_crtc *crtc, | ||
| 502 | struct drm_property *property) | ||
| 503 | { | ||
| 504 | struct drm_device *dev = crtc->dev; | ||
| 505 | struct omap_drm_private *priv = dev->dev_private; | ||
| 506 | |||
| 507 | return property == priv->zorder_prop || | ||
| 508 | property == crtc->primary->rotation_property; | ||
| 509 | } | ||
| 510 | |||
| 511 | static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, | 523 | static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, |
| 512 | struct drm_crtc_state *state, | 524 | struct drm_crtc_state *state, |
| 513 | struct drm_property *property, | 525 | struct drm_property *property, |
| 514 | uint64_t val) | 526 | uint64_t val) |
| 515 | { | 527 | { |
| 516 | if (omap_crtc_is_plane_prop(crtc, property)) { | 528 | struct omap_drm_private *priv = crtc->dev->dev_private; |
| 517 | struct drm_plane_state *plane_state; | 529 | struct drm_plane_state *plane_state; |
| 518 | struct drm_plane *plane = crtc->primary; | ||
| 519 | |||
| 520 | /* | ||
| 521 | * Delegate property set to the primary plane. Get the plane | ||
| 522 | * state and set the property directly. | ||
| 523 | */ | ||
| 524 | |||
| 525 | plane_state = drm_atomic_get_plane_state(state->state, plane); | ||
| 526 | if (IS_ERR(plane_state)) | ||
| 527 | return PTR_ERR(plane_state); | ||
| 528 | 530 | ||
| 529 | return drm_atomic_plane_set_property(plane, plane_state, | 531 | /* |
| 530 | property, val); | 532 | * Delegate property set to the primary plane. Get the plane state and |
| 531 | } | 533 | * set the property directly, the shadow copy will be assigned in the |
| 534 | * omap_crtc_atomic_check callback. This way updates to plane state will | ||
| 535 | * always be mirrored in the crtc state correctly. | ||
| 536 | */ | ||
| 537 | plane_state = drm_atomic_get_plane_state(state->state, crtc->primary); | ||
| 538 | if (IS_ERR(plane_state)) | ||
| 539 | return PTR_ERR(plane_state); | ||
| 540 | |||
| 541 | if (property == crtc->primary->rotation_property) | ||
| 542 | plane_state->rotation = val; | ||
| 543 | else if (property == priv->zorder_prop) | ||
| 544 | plane_state->zpos = val; | ||
| 545 | else | ||
| 546 | return -EINVAL; | ||
| 532 | 547 | ||
| 533 | return -EINVAL; | 548 | return 0; |
| 534 | } | 549 | } |
| 535 | 550 | ||
| 536 | static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, | 551 | static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, |
| @@ -538,28 +553,59 @@ static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, | |||
| 538 | struct drm_property *property, | 553 | struct drm_property *property, |
| 539 | uint64_t *val) | 554 | uint64_t *val) |
| 540 | { | 555 | { |
| 541 | if (omap_crtc_is_plane_prop(crtc, property)) { | 556 | struct omap_drm_private *priv = crtc->dev->dev_private; |
| 542 | /* | 557 | struct omap_crtc_state *omap_state = to_omap_crtc_state(state); |
| 543 | * Delegate property get to the primary plane. The | 558 | |
| 544 | * drm_atomic_plane_get_property() function isn't exported, but | 559 | if (property == crtc->primary->rotation_property) |
| 545 | * can be called through drm_object_property_get_value() as that | 560 | *val = omap_state->rotation; |
| 546 | * will call drm_atomic_get_property() for atomic drivers. | 561 | else if (property == priv->zorder_prop) |
| 547 | */ | 562 | *val = omap_state->zpos; |
| 548 | return drm_object_property_get_value(&crtc->primary->base, | 563 | else |
| 549 | property, val); | 564 | return -EINVAL; |
| 550 | } | 565 | |
| 566 | return 0; | ||
| 567 | } | ||
| 568 | |||
| 569 | static void omap_crtc_reset(struct drm_crtc *crtc) | ||
| 570 | { | ||
| 571 | if (crtc->state) | ||
| 572 | __drm_atomic_helper_crtc_destroy_state(crtc->state); | ||
| 573 | |||
| 574 | kfree(crtc->state); | ||
| 575 | crtc->state = kzalloc(sizeof(struct omap_crtc_state), GFP_KERNEL); | ||
| 576 | |||
| 577 | if (crtc->state) | ||
| 578 | crtc->state->crtc = crtc; | ||
| 579 | } | ||
| 580 | |||
| 581 | static struct drm_crtc_state * | ||
| 582 | omap_crtc_duplicate_state(struct drm_crtc *crtc) | ||
| 583 | { | ||
| 584 | struct omap_crtc_state *state, *current_state; | ||
| 585 | |||
| 586 | if (WARN_ON(!crtc->state)) | ||
| 587 | return NULL; | ||
| 588 | |||
| 589 | current_state = to_omap_crtc_state(crtc->state); | ||
| 590 | |||
| 591 | state = kmalloc(sizeof(*state), GFP_KERNEL); | ||
| 592 | if (state) | ||
| 593 | __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); | ||
| 594 | |||
| 595 | state->zpos = current_state->zpos; | ||
| 596 | state->rotation = current_state->rotation; | ||
| 551 | 597 | ||
| 552 | return -EINVAL; | 598 | return &state->base; |
| 553 | } | 599 | } |
| 554 | 600 | ||
| 555 | static const struct drm_crtc_funcs omap_crtc_funcs = { | 601 | static const struct drm_crtc_funcs omap_crtc_funcs = { |
| 556 | .reset = drm_atomic_helper_crtc_reset, | 602 | .reset = omap_crtc_reset, |
| 557 | .set_config = drm_atomic_helper_set_config, | 603 | .set_config = drm_atomic_helper_set_config, |
| 558 | .destroy = omap_crtc_destroy, | 604 | .destroy = omap_crtc_destroy, |
| 559 | .page_flip = drm_atomic_helper_page_flip, | 605 | .page_flip = drm_atomic_helper_page_flip, |
| 560 | .gamma_set = drm_atomic_helper_legacy_gamma_set, | 606 | .gamma_set = drm_atomic_helper_legacy_gamma_set, |
| 561 | .set_property = drm_atomic_helper_crtc_set_property, | 607 | .set_property = drm_atomic_helper_crtc_set_property, |
| 562 | .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, | 608 | .atomic_duplicate_state = omap_crtc_duplicate_state, |
| 563 | .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, | 609 | .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, |
| 564 | .atomic_set_property = omap_crtc_atomic_set_property, | 610 | .atomic_set_property = omap_crtc_atomic_set_property, |
| 565 | .atomic_get_property = omap_crtc_atomic_get_property, | 611 | .atomic_get_property = omap_crtc_atomic_get_property, |
