From patchwork Thu Mar 7 16:49:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Helen Koike X-Patchwork-Id: 10843397 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 A1EAE17E4 for ; Thu, 7 Mar 2019 16:50:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8D9B62F652 for ; Thu, 7 Mar 2019 16:50:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8BB7B2F663; Thu, 7 Mar 2019 16:50:07 +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 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 EB6322F652 for ; Thu, 7 Mar 2019 16:50:06 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6118B6E315; Thu, 7 Mar 2019 16:50:05 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [46.235.227.227]) by gabe.freedesktop.org (Postfix) with ESMTPS id C32B66E317 for ; Thu, 7 Mar 2019 16:50:02 +0000 (UTC) Received: from localhost.localdomain (unknown [IPv6:2804:431:9719:798c:6bb0:a97a:4a09:e6d8]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: koike) by bhuna.collabora.co.uk (Postfix) with ESMTPSA id 3447927F510; Thu, 7 Mar 2019 16:49:58 +0000 (GMT) From: Helen Koike To: dri-devel@lists.freedesktop.org Subject: [PATCH v8 2/2] drm/i915: update cursors asynchronously through atomic Date: Thu, 7 Mar 2019 13:49:48 -0300 Message-Id: <20190307164948.12138-2-helen.koike@collabora.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190307164948.12138-1-helen.koike@collabora.com> References: <20190307164948.12138-1-helen.koike@collabora.com> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: tfiga@chromium.org, mcasas@google.com, zhenyu.z.wang@intel.com, daniel.vetter@ffwll.ch, tina.zhang@intel.com, kernel@collabora.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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 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() drivers/gpu/drm/i915/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/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 244e1c94277d..bd84d5b9c441 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13005,6 +13005,10 @@ static int intel_atomic_check(struct drm_device *dev, if (ret) return ret; + if (state->legacy_cursor_update) + state->async_update = !drm_atomic_helper_async_check(dev, + state); + intel_fbc_choose_crtc(dev_priv, intel_state); return calc_watermark_data(intel_state); } @@ -13477,34 +13481,6 @@ static int intel_atomic_commit(struct drm_device *dev, i915_sw_fence_init(&intel_state->commit_ready, intel_atomic_commit_ready); - /* - * 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->legacy_cursor_update) { - struct intel_crtc_state *new_crtc_state; - struct intel_crtc *crtc; - int i; - - for_each_new_intel_crtc_in_state(intel_state, crtc, new_crtc_state, i) - if (new_crtc_state->wm.need_postvbl_update || - new_crtc_state->update_wm_post) - state->legacy_cursor_update = false; - } - ret = intel_atomic_prepare_commit(dev, state); if (ret) { DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret); @@ -14012,139 +13988,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->base) || - 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_get_property = intel_plane_atomic_get_property, diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 4c0e43caa5cd..1bfbb3ec39d4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -818,7 +818,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)