aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/omap_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_crtc.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c124
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
31struct 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
31struct omap_crtc { 41struct omap_crtc {
@@ -445,6 +455,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
445static int omap_crtc_atomic_check(struct drm_crtc *crtc, 455static 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
501static 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
511static int omap_crtc_atomic_set_property(struct drm_crtc *crtc, 523static 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
536static int omap_crtc_atomic_get_property(struct drm_crtc *crtc, 551static 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
569static 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
581static struct drm_crtc_state *
582omap_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
555static const struct drm_crtc_funcs omap_crtc_funcs = { 601static 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,