From patchwork Wed Jul 17 19:21:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helen Koike X-Patchwork-Id: 11048173 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2739A13A4 for ; Wed, 17 Jul 2019 19:21:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 17B81286FD for ; Wed, 17 Jul 2019 19:21:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0BBE22874B; Wed, 17 Jul 2019 19:21:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 7313A286FD for ; Wed, 17 Jul 2019 19:21:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AC7526E294; Wed, 17 Jul 2019 19:21:42 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by gabe.freedesktop.org (Postfix) with ESMTPS id D890C6E29F; Wed, 17 Jul 2019 19:21:40 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: koike) with ESMTPSA id E354728A8A3 From: Helen Koike To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org Date: Wed, 17 Jul 2019 16:21:13 -0300 Message-Id: <20190717192114.21855-2-helen.koike@collabora.com> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190717192114.21855-1-helen.koike@collabora.com> References: <20190717192114.21855-1-helen.koike@collabora.com> MIME-Version: 1.0 Subject: [Intel-gfx] [PATCH v10 2/2] drm/i915: update cursors asynchronously through atomic X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mcasas@google.com, zhenyu.z.wang@intel.com, airlied@linux.ie, daniel.vetter@ffwll.ch, linux-kernel@vger.kernel.org, tfiga@chromium.org, gustavo.padovan@collabora.com, Helen Koike , enric.balletbo@collabora.com, kernel@collabora.com Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP From: Gustavo Padovan Replace the legacy cursor implementation by the async callbacks Signed-off-by: Gustavo Padovan Signed-off-by: Enric Balletbo i Serra Signed-off-by: Helen Koike --- Changes in v10: None Changes in v9: - v8: https://patchwork.kernel.org/patch/10843397/ - rebased and fixed conflicts on top of drm-tip Changes in v8: - v7: https://lkml.org/lkml/2018/6/8/168 - v7 was splited in two, one that adds the async callbacks and another that updates the cursor. - Update comment in intel_pm.c that was referencing intel_plane_atomic_async_update() Changes in v7: None Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None drivers/gpu/drm/i915/display/intel_display.c | 165 +------------------ drivers/gpu/drm/i915/intel_pm.c | 2 +- 2 files changed, 6 insertions(+), 161 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index acfb9b7939e2..619916f63c4f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -13662,6 +13662,10 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) goto fail; + if (_state->legacy_cursor_update) + _state->async_update = !drm_atomic_helper_async_check(dev, + _state); + intel_fbc_choose_crtc(dev_priv, state); ret = calc_watermark_data(state); if (ret) @@ -14158,34 +14162,6 @@ static int intel_atomic_commit(struct drm_device *dev, drm_atomic_state_get(&state->base); - /* - * The intel_legacy_cursor_update() fast path takes care - * of avoiding the vblank waits for simple cursor - * movement and flips. For cursor on/off and size changes, - * we want to perform the vblank waits so that watermark - * updates happen during the correct frames. Gen9+ have - * double buffered watermarks and so shouldn't need this. - * - * Unset state->legacy_cursor_update before the call to - * drm_atomic_helper_setup_commit() because otherwise - * drm_atomic_helper_wait_for_flip_done() is a noop and - * we get FIFO underruns because we didn't wait - * for vblank. - * - * FIXME doing watermarks and fb cleanup from a vblank worker - * (assuming we had any) would solve these problems. - */ - if (INTEL_GEN(dev_priv) < 9 && state->base.legacy_cursor_update) { - struct intel_crtc_state *new_crtc_state; - struct intel_crtc *crtc; - int i; - - for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) - if (new_crtc_state->wm.need_postvbl_update || - new_crtc_state->update_wm_post) - state->base.legacy_cursor_update = false; - } - ret = intel_atomic_prepare_commit(state); if (ret) { DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret); @@ -14677,139 +14653,8 @@ static const struct drm_plane_funcs i8xx_plane_funcs = { .format_mod_supported = i8xx_plane_format_mod_supported, }; -static int -intel_legacy_cursor_update(struct drm_plane *plane, - struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - u32 src_x, u32 src_y, - u32 src_w, u32 src_h, - struct drm_modeset_acquire_ctx *ctx) -{ - struct drm_i915_private *dev_priv = to_i915(crtc->dev); - int ret; - struct drm_plane_state *old_plane_state, *new_plane_state; - struct intel_plane *intel_plane = to_intel_plane(plane); - struct drm_framebuffer *old_fb; - struct intel_crtc_state *crtc_state = - to_intel_crtc_state(crtc->state); - struct intel_crtc_state *new_crtc_state; - - /* - * When crtc is inactive or there is a modeset pending, - * wait for it to complete in the slowpath - */ - if (!crtc_state->base.active || needs_modeset(crtc_state) || - crtc_state->update_pipe) - goto slow; - - old_plane_state = plane->state; - /* - * Don't do an async update if there is an outstanding commit modifying - * the plane. This prevents our async update's changes from getting - * overridden by a previous synchronous update's state. - */ - if (old_plane_state->commit && - !try_wait_for_completion(&old_plane_state->commit->hw_done)) - goto slow; - - /* - * If any parameters change that may affect watermarks, - * take the slowpath. Only changing fb or position should be - * in the fastpath. - */ - if (old_plane_state->crtc != crtc || - old_plane_state->src_w != src_w || - old_plane_state->src_h != src_h || - old_plane_state->crtc_w != crtc_w || - old_plane_state->crtc_h != crtc_h || - !old_plane_state->fb != !fb) - goto slow; - - new_plane_state = intel_plane_duplicate_state(plane); - if (!new_plane_state) - return -ENOMEM; - - new_crtc_state = to_intel_crtc_state(intel_crtc_duplicate_state(crtc)); - if (!new_crtc_state) { - ret = -ENOMEM; - goto out_free; - } - - drm_atomic_set_fb_for_plane(new_plane_state, fb); - - new_plane_state->src_x = src_x; - new_plane_state->src_y = src_y; - new_plane_state->src_w = src_w; - new_plane_state->src_h = src_h; - new_plane_state->crtc_x = crtc_x; - new_plane_state->crtc_y = crtc_y; - new_plane_state->crtc_w = crtc_w; - new_plane_state->crtc_h = crtc_h; - - ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state, - to_intel_plane_state(old_plane_state), - to_intel_plane_state(new_plane_state)); - if (ret) - goto out_free; - - ret = mutex_lock_interruptible(&dev_priv->drm.struct_mutex); - if (ret) - goto out_free; - - ret = intel_plane_pin_fb(to_intel_plane_state(new_plane_state)); - if (ret) - goto out_unlock; - - intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_FLIP); - - old_fb = old_plane_state->fb; - i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb), - intel_plane->frontbuffer_bit); - - /* Swap plane state */ - plane->state = new_plane_state; - - /* - * We cannot swap crtc_state as it may be in use by an atomic commit or - * page flip that's running simultaneously. If we swap crtc_state and - * destroy the old state, we will cause a use-after-free there. - * - * Only update active_planes, which is needed for our internal - * bookkeeping. Either value will do the right thing when updating - * planes atomically. If the cursor was part of the atomic update then - * we would have taken the slowpath. - */ - crtc_state->active_planes = new_crtc_state->active_planes; - - if (plane->state->visible) - intel_update_plane(intel_plane, crtc_state, - to_intel_plane_state(plane->state)); - else - intel_disable_plane(intel_plane, crtc_state); - - intel_plane_unpin_fb(to_intel_plane_state(old_plane_state)); - -out_unlock: - mutex_unlock(&dev_priv->drm.struct_mutex); -out_free: - if (new_crtc_state) - intel_crtc_destroy_state(crtc, &new_crtc_state->base); - if (ret) - intel_plane_destroy_state(plane, new_plane_state); - else - intel_plane_destroy_state(plane, old_plane_state); - return ret; - -slow: - return drm_atomic_helper_update_plane(plane, crtc, fb, - crtc_x, crtc_y, crtc_w, crtc_h, - src_x, src_y, src_w, src_h, ctx); -} - static const struct drm_plane_funcs intel_cursor_plane_funcs = { - .update_plane = intel_legacy_cursor_update, + .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = intel_plane_destroy, .atomic_duplicate_state = intel_plane_duplicate_state, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 22472f2bd31b..d8f7ba0f8d84 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -825,7 +825,7 @@ static bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state, * can happen faster than the vrefresh rate, and the current * watermark code doesn't handle that correctly. Cursor updates * which set/clear the fb or change the cursor size are going - * to get throttled by intel_legacy_cursor_update() to work + * to get throttled by intel_plane_atomic_async_update() to work * around this problem with the watermark code. */ if (plane->id == PLANE_CURSOR)