Skip to content

Commit 3dfeb63

Browse files
mlankhorstdanvet
authored andcommitted
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 <[email protected]> (v4) Cc: Maarten Lankhorst <[email protected]> Cc: Tomi Valkeinen <[email protected] Cc: Laurent Pinchart <[email protected]> Signed-off-by: Daniel Vetter <[email protected]> (v4) Signed-off-by: Maarten Lankhorst <[email protected]> Reviewed-by: Tomi Valkeinen <[email protected]> Signed-off-by: Daniel Vetter <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 481e162 commit 3dfeb63

File tree

1 file changed

+85
-39
lines changed

1 file changed

+85
-39
lines changed

drivers/gpu/drm/omapdrm/omap_crtc.c

Lines changed: 85 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626

2727
#include "omap_drv.h"
2828

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+
2939
#define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
3040

3141
struct omap_crtc {
@@ -445,6 +455,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
445455
static int omap_crtc_atomic_check(struct drm_crtc *crtc,
446456
struct drm_crtc_state *state)
447457
{
458+
struct drm_plane_state *pri_state;
459+
448460
if (state->color_mgmt_changed && state->gamma_lut) {
449461
uint length = state->gamma_lut->length /
450462
sizeof(struct drm_color_lut);
@@ -453,6 +465,16 @@ static int omap_crtc_atomic_check(struct drm_crtc *crtc,
453465
return -EINVAL;
454466
}
455467

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+
456478
return 0;
457479
}
458480

@@ -498,68 +520,92 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc,
498520
spin_unlock_irq(&crtc->dev->event_lock);
499521
}
500522

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-
511523
static int omap_crtc_atomic_set_property(struct drm_crtc *crtc,
512524
struct drm_crtc_state *state,
513525
struct drm_property *property,
514526
uint64_t val)
515527
{
516-
if (omap_crtc_is_plane_prop(crtc, property)) {
517-
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+
struct omap_drm_private *priv = crtc->dev->dev_private;
529+
struct drm_plane_state *plane_state;
528530

529-
return drm_atomic_plane_set_property(plane, plane_state,
530-
property, val);
531-
}
531+
/*
532+
* Delegate property set to the primary plane. Get the plane state and
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;
532547

533-
return -EINVAL;
548+
return 0;
534549
}
535550

536551
static int omap_crtc_atomic_get_property(struct drm_crtc *crtc,
537552
const struct drm_crtc_state *state,
538553
struct drm_property *property,
539554
uint64_t *val)
540555
{
541-
if (omap_crtc_is_plane_prop(crtc, property)) {
542-
/*
543-
* Delegate property get to the primary plane. The
544-
* drm_atomic_plane_get_property() function isn't exported, but
545-
* can be called through drm_object_property_get_value() as that
546-
* will call drm_atomic_get_property() for atomic drivers.
547-
*/
548-
return drm_object_property_get_value(&crtc->primary->base,
549-
property, val);
550-
}
556+
struct omap_drm_private *priv = crtc->dev->dev_private;
557+
struct omap_crtc_state *omap_state = to_omap_crtc_state(state);
558+
559+
if (property == crtc->primary->rotation_property)
560+
*val = omap_state->rotation;
561+
else if (property == priv->zorder_prop)
562+
*val = omap_state->zpos;
563+
else
564+
return -EINVAL;
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;
551597

552-
return -EINVAL;
598+
return &state->base;
553599
}
554600

555601
static const struct drm_crtc_funcs omap_crtc_funcs = {
556-
.reset = drm_atomic_helper_crtc_reset,
602+
.reset = omap_crtc_reset,
557603
.set_config = drm_atomic_helper_set_config,
558604
.destroy = omap_crtc_destroy,
559605
.page_flip = drm_atomic_helper_page_flip,
560606
.gamma_set = drm_atomic_helper_legacy_gamma_set,
561607
.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,
563609
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
564610
.atomic_set_property = omap_crtc_atomic_set_property,
565611
.atomic_get_property = omap_crtc_atomic_get_property,

0 commit comments

Comments
 (0)