From 8fb756dfa273bcb42bdaff65baae83548b6c326d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 16 Mar 2018 15:04:33 -0700 Subject: drm: Trust format_mod_supported() when it OKs a plane modifier. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For parameterized modifiers (Broadcom's SAND and UIF), we need to allow the parameter fields to be filled in, while exposing only the variant of the modifier with the parameter unfilled in the internal arrays and the format blob. Signed-off-by: Eric Anholt Cc: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180316220435.31416-1-eric@anholt.net Reviewed-by: Ville Syrjälä --- drivers/gpu/drm/drm_plane.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/drm_plane.c') diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 035054455301..7ce88dff871d 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -561,19 +561,20 @@ int drm_plane_check_pixel_format(struct drm_plane *plane, if (i == plane->format_count) return -EINVAL; - if (!plane->modifier_count) - return 0; + if (plane->funcs->format_mod_supported) { + if (!plane->funcs->format_mod_supported(plane, format, modifier)) + return -EINVAL; + } else { + if (!plane->modifier_count) + return 0; - for (i = 0; i < plane->modifier_count; i++) { - if (modifier == plane->modifiers[i]) - break; + for (i = 0; i < plane->modifier_count; i++) { + if (modifier == plane->modifiers[i]) + break; + } + if (i == plane->modifier_count) + return -EINVAL; } - if (i == plane->modifier_count) - return -EINVAL; - - if (plane->funcs->format_mod_supported && - !plane->funcs->format_mod_supported(plane, format, modifier)) - return -EINVAL; return 0; } -- cgit From e00fb8564ee98c5c3a72c74b1a27e441abff6cca Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 25 May 2018 21:50:45 +0300 Subject: drm: Stop updating plane->crtc/fb/old_fb on atomic drivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop playing around with plane->crtc/fb/old_fb with atomic drivers. Make life a lot simpler when we don't have to do the magic old_fb vs. fb dance around plane updates. That way we can't risk plane->fb getting out of sync with plane->state->fb and we're less likely to leak any refcounts as well. Signed-off-by: Ville Syrjälä Reviewed-by: Maarten Lankhorst Acked-by: Harry Wentland Link: https://patchwork.freedesktop.org/patch/msgid/20180525185045.29689-14-ville.syrjala@linux.intel.com Reviewed-by: Sinclair Yeh --- drivers/gpu/drm/drm_atomic.c | 55 ++++--------------------------------- drivers/gpu/drm/drm_atomic_helper.c | 15 +--------- drivers/gpu/drm/drm_crtc.c | 8 ++++-- drivers/gpu/drm/drm_fb_helper.c | 7 ----- drivers/gpu/drm/drm_framebuffer.c | 5 ---- drivers/gpu/drm/drm_plane.c | 14 ++++++---- drivers/gpu/drm/drm_plane_helper.c | 4 ++- include/drm/drm_atomic.h | 3 -- 8 files changed, 24 insertions(+), 87 deletions(-) (limited to 'drivers/gpu/drm/drm_plane.c') diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 07fef42869aa..11059d556dbd 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -692,6 +692,11 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state, WARN_ON(!state->acquire_ctx); + /* the legacy pointers should never be set */ + WARN_ON(plane->fb); + WARN_ON(plane->old_fb); + WARN_ON(plane->crtc); + plane_state = drm_atomic_get_existing_plane_state(state, plane); if (plane_state) return plane_state; @@ -2039,45 +2044,6 @@ int drm_atomic_set_property(struct drm_atomic_state *state, return ret; } -/** - * drm_atomic_clean_old_fb -- Unset old_fb pointers and set plane->fb pointers. - * - * @dev: drm device to check. - * @plane_mask: plane mask for planes that were updated. - * @ret: return value, can be -EDEADLK for a retry. - * - * Before doing an update &drm_plane.old_fb is set to &drm_plane.fb, but before - * dropping the locks old_fb needs to be set to NULL and plane->fb updated. This - * is a common operation for each atomic update, so this call is split off as a - * helper. - */ -void drm_atomic_clean_old_fb(struct drm_device *dev, - unsigned plane_mask, - int ret) -{ - struct drm_plane *plane; - - /* if succeeded, fixup legacy plane crtc/fb ptrs before dropping - * locks (ie. while it is still safe to deref plane->state). We - * need to do this here because the driver entry points cannot - * distinguish between legacy and atomic ioctls. - */ - drm_for_each_plane_mask(plane, dev, plane_mask) { - if (ret == 0) { - struct drm_framebuffer *new_fb = plane->state->fb; - if (new_fb) - drm_framebuffer_get(new_fb); - plane->fb = new_fb; - plane->crtc = plane->state->crtc; - - if (plane->old_fb) - drm_framebuffer_put(plane->old_fb); - } - plane->old_fb = NULL; - } -} -EXPORT_SYMBOL(drm_atomic_clean_old_fb); - /** * DOC: explicit fencing properties * @@ -2298,9 +2264,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, unsigned int copied_objs, copied_props; struct drm_atomic_state *state; struct drm_modeset_acquire_ctx ctx; - struct drm_plane *plane; struct drm_out_fence_state *fence_state; - unsigned plane_mask; int ret = 0; unsigned int i, j, num_fences; @@ -2340,7 +2304,6 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET); retry: - plane_mask = 0; copied_objs = 0; copied_props = 0; fence_state = NULL; @@ -2411,12 +2374,6 @@ retry: copied_props++; } - if (obj->type == DRM_MODE_OBJECT_PLANE && count_props && - !(arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)) { - plane = obj_to_plane(obj); - plane_mask |= (1 << drm_plane_index(plane)); - plane->old_fb = plane->fb; - } drm_mode_object_put(obj); } @@ -2437,8 +2394,6 @@ retry: } out: - drm_atomic_clean_old_fb(dev, plane_mask, ret); - complete_crtc_signaling(dev, state, fence_state, num_fences, !ret); if (ret == -EDEADLK) { diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 130da5195f3b..232fa11a5e31 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -2914,7 +2914,6 @@ static int __drm_atomic_helper_disable_all(struct drm_device *dev, struct drm_plane *plane; struct drm_crtc_state *crtc_state; struct drm_crtc *crtc; - unsigned plane_mask = 0; int ret, i; state = drm_atomic_state_alloc(dev); @@ -2957,17 +2956,10 @@ static int __drm_atomic_helper_disable_all(struct drm_device *dev, goto free; drm_atomic_set_fb_for_plane(plane_state, NULL); - - if (clean_old_fbs) { - plane->old_fb = plane->fb; - plane_mask |= BIT(drm_plane_index(plane)); - } } ret = drm_atomic_commit(state); free: - if (plane_mask) - drm_atomic_clean_old_fb(dev, plane_mask, ret); drm_atomic_state_put(state); return ret; } @@ -3129,13 +3121,8 @@ int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state, state->acquire_ctx = ctx; - for_each_new_plane_in_state(state, plane, new_plane_state, i) { - WARN_ON(plane->crtc != new_plane_state->crtc); - WARN_ON(plane->fb != new_plane_state->fb); - WARN_ON(plane->old_fb); - + for_each_new_plane_in_state(state, plane, new_plane_state, i) state->planes[i].old_state = plane->state; - } for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) state->crtcs[i].old_state = crtc->state; diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 237bd34212db..53828fc8d911 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -479,8 +479,12 @@ static int __drm_mode_set_config_internal(struct drm_mode_set *set, ret = crtc->funcs->set_config(set, ctx); if (ret == 0) { - crtc->primary->crtc = fb ? crtc : NULL; - crtc->primary->fb = fb; + struct drm_plane *plane = crtc->primary; + + if (!plane->state) { + plane->crtc = fb ? crtc : NULL; + plane->fb = fb; + } } drm_for_each_crtc(tmp, crtc->dev) { diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 91f051e5e130..cab14f253384 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -368,7 +368,6 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ struct drm_plane *plane; struct drm_atomic_state *state; int i, ret; - unsigned int plane_mask; struct drm_modeset_acquire_ctx ctx; drm_modeset_acquire_init(&ctx, 0); @@ -381,7 +380,6 @@ static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool activ state->acquire_ctx = &ctx; retry: - plane_mask = 0; drm_for_each_plane(plane, dev) { plane_state = drm_atomic_get_plane_state(state, plane); if (IS_ERR(plane_state)) { @@ -391,9 +389,6 @@ retry: plane_state->rotation = DRM_MODE_ROTATE_0; - plane->old_fb = plane->fb; - plane_mask |= 1 << drm_plane_index(plane); - /* disable non-primary: */ if (plane->type == DRM_PLANE_TYPE_PRIMARY) continue; @@ -430,8 +425,6 @@ retry: ret = drm_atomic_commit(state); out_state: - drm_atomic_clean_old_fb(dev, plane_mask, ret); - if (ret == -EDEADLK) goto backoff; diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index bfedceff87bb..46b11e46edbd 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -836,8 +836,6 @@ retry: goto unlock; plane_mask |= BIT(drm_plane_index(plane)); - - plane->old_fb = plane->fb; } /* This list is only filled when disable_crtcs is set. */ @@ -852,9 +850,6 @@ retry: ret = drm_atomic_commit(state); unlock: - if (plane_mask) - drm_atomic_clean_old_fb(dev, plane_mask, ret); - if (ret == -EDEADLK) { drm_atomic_state_clear(state); drm_modeset_backoff(&ctx); diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 7ce88dff871d..534b57933576 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -651,9 +651,11 @@ static int __setplane_internal(struct drm_plane *plane, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h, ctx); if (!ret) { - plane->crtc = crtc; - plane->fb = fb; - drm_framebuffer_get(plane->fb); + if (!plane->state) { + plane->crtc = crtc; + plane->fb = fb; + drm_framebuffer_get(plane->fb); + } } else { plane->old_fb = NULL; } @@ -1093,8 +1095,10 @@ retry: /* Keep the old fb, don't unref it. */ plane->old_fb = NULL; } else { - plane->fb = fb; - drm_framebuffer_get(fb); + if (!plane->state) { + plane->fb = fb; + drm_framebuffer_get(fb); + } } out: diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index f88f68161519..2010794943bc 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -502,6 +502,7 @@ EXPORT_SYMBOL(drm_plane_helper_update); int drm_plane_helper_disable(struct drm_plane *plane) { struct drm_plane_state *plane_state; + struct drm_framebuffer *old_fb; /* crtc helpers love to call disable functions for already disabled hw * functions. So cope with that. */ @@ -521,8 +522,9 @@ int drm_plane_helper_disable(struct drm_plane *plane) plane_state->plane = plane; plane_state->crtc = NULL; + old_fb = plane_state->fb; drm_atomic_set_fb_for_plane(plane_state, NULL); - return drm_plane_helper_commit(plane, plane_state, plane->fb); + return drm_plane_helper_commit(plane, plane_state, old_fb); } EXPORT_SYMBOL(drm_plane_helper_disable); diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index a57a8aa90ffb..ca461b6cf71f 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -601,9 +601,6 @@ int __must_check drm_atomic_add_affected_planes(struct drm_atomic_state *state, struct drm_crtc *crtc); -void -drm_atomic_clean_old_fb(struct drm_device *dev, unsigned plane_mask, int ret); - int __must_check drm_atomic_check_only(struct drm_atomic_state *state); int __must_check drm_atomic_commit(struct drm_atomic_state *state); int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state); -- cgit From ba1f665f161ce112a2703649317bfdc9b6521613 Mon Sep 17 00:00:00 2001 From: Haneen Mohammed Date: Fri, 25 May 2018 04:25:55 +0300 Subject: drm: Add checks for atomic_[duplicate/destroy]_state with atomic drivers This patch add checks for atomic_[duplicate/destroy]_state of drm_[connector/crtc/plane]_funcs for atomic drivers in the relevant drm_*_init functions since these callback are mandatory for atomic drivers. Update the kerneldoc comments for those callbacks. Signed-off-by: Haneen Mohammed Reviewed-by: Sean Paul Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180525012555.GA8448@haneen-vb --- drivers/gpu/drm/drm_connector.c | 4 ++++ drivers/gpu/drm/drm_crtc.c | 4 ++++ drivers/gpu/drm/drm_plane.c | 4 ++++ include/drm/drm_connector.h | 4 ++++ include/drm/drm_crtc.h | 4 ++++ include/drm/drm_plane.h | 4 ++++ 6 files changed, 24 insertions(+) (limited to 'drivers/gpu/drm/drm_plane.c') diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 002b244391f9..549b89501e01 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -195,6 +195,10 @@ int drm_connector_init(struct drm_device *dev, struct ida *connector_ida = &drm_connector_enum_list[connector_type].ida; + WARN_ON(drm_drv_uses_atomic_modeset(dev) && + (!funcs->atomic_destroy_state || + !funcs->atomic_duplicate_state)); + ret = __drm_mode_object_add(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR, false, drm_connector_free); diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 163d82ac7d76..f45e7a8d4acd 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -286,6 +286,10 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, if (WARN_ON(config->num_crtc >= 32)) return -EINVAL; + WARN_ON(drm_drv_uses_atomic_modeset(dev) && + (!funcs->atomic_destroy_state || + !funcs->atomic_duplicate_state)); + crtc->dev = dev; crtc->funcs = funcs; diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 534b57933576..df0b4ebbedbf 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -177,6 +177,10 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, if (WARN_ON(config->num_total_plane >= 32)) return -EINVAL; + WARN_ON(drm_drv_uses_atomic_modeset(dev) && + (!funcs->atomic_destroy_state || + !funcs->atomic_duplicate_state)); + ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); if (ret) return ret; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index ee4c48218c85..c5797c24edd3 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -616,6 +616,8 @@ struct drm_connector_funcs { * cleaned up by calling the @atomic_destroy_state hook in this * structure. * + * This callback is mandatory for atomic drivers. + * * Atomic drivers which don't subclass &struct drm_connector_state should use * drm_atomic_helper_connector_duplicate_state(). Drivers that subclass the * state structure to extend it with driver-private state should use @@ -642,6 +644,8 @@ struct drm_connector_funcs { * * Destroy a state duplicated with @atomic_duplicate_state and release * or unreference all resources it references + * + * This callback is mandatory for atomic drivers. */ void (*atomic_destroy_state)(struct drm_connector *connector, struct drm_connector_state *state); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 5cf7adeae6a5..23eddbccab10 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -506,6 +506,8 @@ struct drm_crtc_funcs { * cleaned up by calling the @atomic_destroy_state hook in this * structure. * + * This callback is mandatory for atomic drivers. + * * Atomic drivers which don't subclass &struct drm_crtc_state should use * drm_atomic_helper_crtc_duplicate_state(). Drivers that subclass the * state structure to extend it with driver-private state should use @@ -532,6 +534,8 @@ struct drm_crtc_funcs { * * Destroy a state duplicated with @atomic_duplicate_state and release * or unreference all resources it references + * + * This callback is mandatory for atomic drivers. */ void (*atomic_destroy_state)(struct drm_crtc *crtc, struct drm_crtc_state *state); diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 14b1607aba4b..7d4d6c7f0afd 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -288,6 +288,8 @@ struct drm_plane_funcs { * cleaned up by calling the @atomic_destroy_state hook in this * structure. * + * This callback is mandatory for atomic drivers. + * * Atomic drivers which don't subclass &struct drm_plane_state should use * drm_atomic_helper_plane_duplicate_state(). Drivers that subclass the * state structure to extend it with driver-private state should use @@ -314,6 +316,8 @@ struct drm_plane_funcs { * * Destroy a state duplicated with @atomic_duplicate_state and release * or unreference all resources it references + * + * This callback is mandatory for atomic drivers. */ void (*atomic_destroy_state)(struct drm_plane *plane, struct drm_plane_state *state); -- cgit From 4dd4677c2d3d34a2bcd511c088da4535ea58e360 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 28 Jun 2018 16:54:55 +0300 Subject: drm: Extract __setplane_check() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pull all the error checking out from __set_plane_internal() to a helper function. We'll have another user of this soon. Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20180628135457.14647-1-ville.syrjala@linux.intel.com Reviewed-by: Rodrigo Vivi Reviewed-by: Daniel Vetter --- drivers/gpu/drm/drm_plane.c | 80 +++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 31 deletions(-) (limited to 'drivers/gpu/drm/drm_plane.c') diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index df0b4ebbedbf..5c97a0131484 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -583,6 +583,52 @@ int drm_plane_check_pixel_format(struct drm_plane *plane, return 0; } +static int __setplane_check(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int32_t crtc_x, int32_t crtc_y, + uint32_t crtc_w, uint32_t crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h) +{ + int ret; + + /* Check whether this plane is usable on this CRTC */ + if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) { + DRM_DEBUG_KMS("Invalid crtc for plane\n"); + return -EINVAL; + } + + /* Check whether this plane supports the fb pixel format. */ + ret = drm_plane_check_pixel_format(plane, fb->format->format, + fb->modifier); + if (ret) { + struct drm_format_name_buf format_name; + + DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n", + drm_get_format_name(fb->format->format, + &format_name), + fb->modifier); + return ret; + } + + /* Give drivers some help against integer overflows */ + if (crtc_w > INT_MAX || + crtc_x > INT_MAX - (int32_t) crtc_w || + crtc_h > INT_MAX || + crtc_y > INT_MAX - (int32_t) crtc_h) { + DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n", + crtc_w, crtc_h, crtc_x, crtc_y); + return -ERANGE; + } + + ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb); + if (ret) + return ret; + + return 0; +} + /* * __setplane_internal - setplane handler for internal callers * @@ -616,37 +662,9 @@ static int __setplane_internal(struct drm_plane *plane, goto out; } - /* Check whether this plane is usable on this CRTC */ - if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) { - DRM_DEBUG_KMS("Invalid crtc for plane\n"); - ret = -EINVAL; - goto out; - } - - /* Check whether this plane supports the fb pixel format. */ - ret = drm_plane_check_pixel_format(plane, fb->format->format, - fb->modifier); - if (ret) { - struct drm_format_name_buf format_name; - DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n", - drm_get_format_name(fb->format->format, - &format_name), - fb->modifier); - goto out; - } - - /* Give drivers some help against integer overflows */ - if (crtc_w > INT_MAX || - crtc_x > INT_MAX - (int32_t) crtc_w || - crtc_h > INT_MAX || - crtc_y > INT_MAX - (int32_t) crtc_h) { - DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n", - crtc_w, crtc_h, crtc_x, crtc_y); - ret = -ERANGE; - goto out; - } - - ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb); + ret = __setplane_check(plane, crtc, fb, + crtc_x, crtc_y, crtc_w, crtc_h, + src_x, src_y, src_w, src_h); if (ret) goto out; -- cgit From e7695eb6ea70ed143fafbcd12ce69886be3aa03d Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Thu, 5 Jul 2018 21:59:07 +0300 Subject: drm: Introduce __setplane_atomic() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All the plane->fb/old_fb/crtc dance of __setplane_internal() is pointless on atomic drivers. So let's just introduce a simpler version that skips all that. Ideally we could also skip the __setplane_check() as drm_atomic_plane_check() already checks for everything, but the legacy cursor/"async" .update_plane() tricks bypass that so we still need to call __setplane_check(). Toss in a FIXME to remind someone to clean this up later. v2: Use drm_drv_uses_atomic_modeset() (Daniel) Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180705185907.9524-1-ville.syrjala@linux.intel.com --- drivers/gpu/drm/drm_plane.c | 68 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 57 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/drm_plane.c') diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 5c97a0131484..6153cbda239f 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -649,6 +649,8 @@ static int __setplane_internal(struct drm_plane *plane, { int ret = 0; + WARN_ON(drm_drv_uses_atomic_modeset(plane->dev)); + /* No fb means shut it down */ if (!fb) { plane->old_fb = plane->fb; @@ -673,11 +675,9 @@ static int __setplane_internal(struct drm_plane *plane, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h, ctx); if (!ret) { - if (!plane->state) { - plane->crtc = crtc; - plane->fb = fb; - drm_framebuffer_get(plane->fb); - } + plane->crtc = crtc; + plane->fb = fb; + drm_framebuffer_get(plane->fb); } else { plane->old_fb = NULL; } @@ -690,6 +690,41 @@ out: return ret; } +static int __setplane_atomic(struct drm_plane *plane, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + int32_t crtc_x, int32_t crtc_y, + uint32_t crtc_w, uint32_t crtc_h, + uint32_t src_x, uint32_t src_y, + uint32_t src_w, uint32_t src_h, + struct drm_modeset_acquire_ctx *ctx) +{ + int ret; + + WARN_ON(!drm_drv_uses_atomic_modeset(plane->dev)); + + /* No fb means shut it down */ + if (!fb) + return plane->funcs->disable_plane(plane, ctx); + + /* + * FIXME: This is redundant with drm_atomic_plane_check(), + * but the legacy cursor/"async" .update_plane() tricks + * don't call that so we still need this here. Should remove + * this when all .update_plane() implementations have been + * fixed to call drm_atomic_plane_check(). + */ + ret = __setplane_check(plane, crtc, fb, + crtc_x, crtc_y, crtc_w, crtc_h, + src_x, src_y, src_w, src_h); + if (ret) + return ret; + + return plane->funcs->update_plane(plane, crtc, fb, + crtc_x, crtc_y, crtc_w, crtc_h, + src_x, src_y, src_w, src_h, ctx); +} + static int setplane_internal(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -707,9 +742,15 @@ retry: ret = drm_modeset_lock_all_ctx(plane->dev, &ctx); if (ret) goto fail; - ret = __setplane_internal(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - src_x, src_y, src_w, src_h, &ctx); + + if (drm_drv_uses_atomic_modeset(plane->dev)) + ret = __setplane_atomic(plane, crtc, fb, + crtc_x, crtc_y, crtc_w, crtc_h, + src_x, src_y, src_w, src_h, &ctx); + else + ret = __setplane_internal(plane, crtc, fb, + crtc_x, crtc_y, crtc_w, crtc_h, + src_x, src_y, src_w, src_h, &ctx); fail: if (ret == -EDEADLK) { @@ -841,9 +882,14 @@ static int drm_mode_cursor_universal(struct drm_crtc *crtc, src_h = fb->height << 16; } - ret = __setplane_internal(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - 0, 0, src_w, src_h, ctx); + if (drm_drv_uses_atomic_modeset(dev)) + ret = __setplane_atomic(plane, crtc, fb, + crtc_x, crtc_y, crtc_w, crtc_h, + 0, 0, src_w, src_h, ctx); + else + ret = __setplane_internal(plane, crtc, fb, + crtc_x, crtc_y, crtc_w, crtc_h, + 0, 0, src_w, src_h, ctx); if (fb) drm_framebuffer_put(fb); -- cgit