From 96962e3de725f734b7f4671a21920b12cb2799c7 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 11 Dec 2020 19:46:34 +0100 Subject: drm: require each CRTC to have a unique primary plane User-space expects to be able to pick a primary plane for each CRTC exposed by the driver. Make sure this assumption holds in drm_mode_config_validate. Use the legacy drm_crtc.primary field to check this, because it's simpler and we require drivers to set it anyways. Accumulate a set of primary planes which are already used for a CRTC in a bitmask. Error out if a primary plane is re-used. v2: new patch v3: - Use u64 instead of __u64 (Jani) - Use `unsigned int` instead of `unsigned` (Jani) v4: - Use u32 instead of u64 for plane mask (Ville) - Use drm_plane_mask instead of BIT (Ville) - Fix typos (Ville) Signed-off-by: Simon Ser Reviewed-by: Daniel Vetter Acked-by: Ville Syrjala Cc: Pekka Paalanen Cc: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20201211184634.74534-4-contact@emersion.fr --- drivers/gpu/drm/drm_mode_config.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers/gpu/drm/drm_mode_config.c') diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 1e5da83fd2a8..9611f21bca00 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -626,6 +626,9 @@ void drm_mode_config_validate(struct drm_device *dev) { struct drm_encoder *encoder; struct drm_crtc *crtc; + struct drm_plane *plane; + u32 primary_with_crtc = 0, cursor_with_crtc = 0; + unsigned int num_primary = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return; @@ -647,12 +650,29 @@ void drm_mode_config_validate(struct drm_device *dev) "Bogus primary plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n", crtc->primary->base.id, crtc->primary->name, crtc->base.id, crtc->name); + WARN(primary_with_crtc & drm_plane_mask(crtc->primary), + "Primary plane [PLANE:%d:%s] used for multiple CRTCs", + crtc->primary->base.id, crtc->primary->name); + primary_with_crtc |= drm_plane_mask(crtc->primary); } if (crtc->cursor) { WARN(!(crtc->cursor->possible_crtcs & drm_crtc_mask(crtc)), "Bogus cursor plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n", crtc->cursor->base.id, crtc->cursor->name, crtc->base.id, crtc->name); + WARN(cursor_with_crtc & drm_plane_mask(crtc->cursor), + "Cursor plane [PLANE:%d:%s] used for multiple CRTCs", + crtc->cursor->base.id, crtc->cursor->name); + cursor_with_crtc |= drm_plane_mask(crtc->cursor); } } + + drm_for_each_plane(plane, dev) { + if (plane->type == DRM_PLANE_TYPE_PRIMARY) + num_primary++; + } + + WARN(num_primary != dev->mode_config.num_crtc, + "Must have as many primary planes as there are CRTCs, but have %u primary planes and %u CRTCs", + num_primary, dev->mode_config.num_crtc); } -- cgit From 9a01105389c92026ad483c2b214e5943c6e4b384 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 22 Dec 2020 14:40:02 +0100 Subject: drm: warn if cursor plane is set with legacy funcs A driver must not set drm_crtc.cursor and any of the legacy funcs at the same time, otherwise it's not clear which one DRM core should use for legacy cursor updates. Signed-off-by: Simon Ser Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20201222134002.161613-1-contact@emersion.fr --- drivers/gpu/drm/drm_mode_config.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/gpu/drm/drm_mode_config.c') diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 9611f21bca00..92e56baf04ad 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -645,6 +645,16 @@ void drm_mode_config_validate(struct drm_device *dev) WARN(!crtc->primary, "Missing primary plane on [CRTC:%d:%s]\n", crtc->base.id, crtc->name); + WARN(crtc->cursor && crtc->funcs->cursor_set, + "[CRTC:%d:%s] must not have both a cursor plane and a cursor_set func", + crtc->base.id, crtc->name); + WARN(crtc->cursor && crtc->funcs->cursor_set2, + "[CRTC:%d:%s] must not have both a cursor plane and a cursor_set2 func", + crtc->base.id, crtc->name); + WARN(crtc->cursor && crtc->funcs->cursor_move, + "[CRTC:%d:%s] must not have both a cursor plane and a cursor_move func", + crtc->base.id, crtc->name); + if (crtc->primary) { WARN(!(crtc->primary->possible_crtcs & drm_crtc_mask(crtc)), "Bogus primary plane possible_crtcs: [PLANE:%d:%s] must be compatible with [CRTC:%d:%s]\n", -- cgit