Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp9416620imu; Wed, 5 Dec 2018 04:35:45 -0800 (PST) X-Google-Smtp-Source: AFSGD/WupzFu56/b5VGb6RChBf/xiSn4/HocQKfm/3dFc0CkwuFwki3BOkg8fQ0Sioxlwn/XudSH X-Received: by 2002:a17:902:4681:: with SMTP id p1mr24693932pld.184.1544013344975; Wed, 05 Dec 2018 04:35:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544013344; cv=none; d=google.com; s=arc-20160816; b=G07V1APrVvW8EWzhzI0b6Ea5zN1sVkg1mccs/vpaYk7drmscKgp1KQMWYx5VJO0g1Y 7Atl/vpam3qZAYQJ6E8HPOAbofK3yKXpU21WKdJG9hQ3czdDgkLUQ11cuGcv2GYiCQLY eSFpqiXcUJLZ2w0ztpxYpVEuLj5bIA+u9ESJEmKekATRmLwi9WZ930VkWQTW8rg18Gct WIjRnyAsUEOo5n7Jjr4VfRqf4lI7qgFQDaSV/fHwEFz6eL2FpDjyPk5lEedsdVe95vNZ U3IdVNC4Wa7o2vUhlsOzM1ct+b+n7xngYXqzaFyp/n7DYXDW/p7BviB3uaVc+qfu6uFm i5Eg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=IBRv+m+tUrnUyXmDXIPkCghsLcBt1cx+rTFHuxd/KkI=; b=pL9i6um1Tp/+5Aa2RDNB9skDI1JNxfaW2IL2x7cVffcOeLQgTnf7JRARAAHCapKqd3 y++pWBZ/DQ3z15awJUySnVENsJUZnY+fOUnZdj7aK5UWvTTFL7ajx++hev0s5jvYcuYW cEokbh4D+MzXOT2kTpyD2vy4rTrujiEDTho62wKZPLN5dpPptw8Zu+iDq6PVCo9lBrPM zzNYKb41Ed5G+asUFkb7UiF5cXjuet+34QvLsczKwB4Mw4ZxfA/rO6vRyHM5GziT3cQ9 8ChR7LMYbTh9GlOGHbjJeqUMLgfnT/7bLhK0koAERvkB4jXurvO7QMHv/3PhOpWKpsvP Ijxw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q24si20594014pls.325.2018.12.05.04.35.29; Wed, 05 Dec 2018 04:35:44 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727182AbeLEMd0 (ORCPT + 99 others); Wed, 5 Dec 2018 07:33:26 -0500 Received: from bhuna.collabora.co.uk ([46.235.227.227]:49264 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726918AbeLEMd0 (ORCPT ); Wed, 5 Dec 2018 07:33:26 -0500 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: koike) with ESMTPSA id D221C260C86 From: Helen Koike To: Sandy Huang , =?UTF-8?q?Heiko=20St=C3=BCbner?= , David Airlie Cc: linux-arm-kernel@lists.infradead.org, Enric Balletbo i Serra , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-rockchip@lists.infradead.org, Gustavo Padovan , Tomasz Figa , Sean Paul , kernel@collabora.com, =?UTF-8?q?St=C3=A9phane=20Marchesin?= Subject: [PATCH v4] drm/rockchip: update cursors asynchronously through atomic. Date: Wed, 5 Dec 2018 10:33:10 -0200 Message-Id: <20181205123310.7965-1-helen.koike@collabora.com> X-Mailer: git-send-email 2.19.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Enric Balletbo i Serra Add support to async updates of cursors by using the new atomic interface for that. Signed-off-by: Enric Balletbo i Serra [updated for upstream] Signed-off-by: Helen Koike --- Hello, This is the forth version of the async-plane update suport to the Rockchip driver. I tested running igt kms_cursor_legacy and kms_atomic tests using a 96Boards Ficus. Note that before the patch, the following igt tests failed: basic-flip-before-cursor-atomic basic-flip-before-cursor-legacy cursor-vs-flip-atomic cursor-vs-flip-legacy cursor-vs-flip-toggle flip-vs-cursor-atomic flip-vs-cursor-busy-crc-atomic flip-vs-cursor-busy-crc-legacy flip-vs-cursor-crc-atomic flip-vs-cursor-crc-legacy flip-vs-cursor-legacy Full log: https://people.collabora.com/~koike/results-4.20/html/ Now with only the following fails: cursor-vs-flip-legacy flip-vs-cursor-busy-crc-atomic flip-vs-cursor-busy-crc-legacy flip-vs-cursor-crc-atomic flip-vs-cursor-crc-legacy Full log: https://people.collabora.com/~koike/results-4.20-async/html/ Thanks Helen Changes in v4: - Removed vop_crtc_atomic_commit_flush - Call drm_atomic_set_fb_for_plane() only when framebuffers are different - Removed unecessary ret variable from vop_plane_atomic_async_check - async_update: duplicate plane state for an atomic swap - async_update: prevent releasing buffer current being scaned out by the hw by getting a reference and adding a worker Changes in v3: - Rebased on top of drm-misc - Fix missing include in rockchip_drm_vop.c - New function vop_crtc_atomic_commit_flush Changes in v2: - v2: https://patchwork.freedesktop.org/patch/254180/ - Change the framebuffer as well to cover jumpy cursor when hovering text boxes or hyperlink. (Tomasz) - Use the PSR inhibit mechanism when accessing VOP hardware instead of PSR flushing (Tomasz) Changes in v1: - Rebased on top of drm-misc - In async_check call drm_atomic_helper_check_plane_state to check that the desired plane is valid and update various bits of derived state (clipped coordinates etc.) - In async_check allow to configure new scaling in the fast path. - In async_update force to flush all registered PSR encoders. - In async_update call atomic_update directly. - In async_update call vop_cfg_done needed to set the vop registers and take effect. drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 36 ---------- drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 37 +++++++++++ drivers/gpu/drm/rockchip/rockchip_drm_psr.h | 3 + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 74 +++++++++++++++++++++ 4 files changed, 114 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index ea18cb2a76c0..08bec50d9c5d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c @@ -127,42 +127,6 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, return ERR_PTR(ret); } -static void -rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state) -{ - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - struct drm_encoder *encoder; - u32 encoder_mask = 0; - int i; - - for_each_old_crtc_in_state(state, crtc, crtc_state, i) { - encoder_mask |= crtc_state->encoder_mask; - encoder_mask |= crtc->state->encoder_mask; - } - - drm_for_each_encoder_mask(encoder, state->dev, encoder_mask) - rockchip_drm_psr_inhibit_get(encoder); -} - -static void -rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state) -{ - struct drm_crtc *crtc; - struct drm_crtc_state *crtc_state; - struct drm_encoder *encoder; - u32 encoder_mask = 0; - int i; - - for_each_old_crtc_in_state(state, crtc, crtc_state, i) { - encoder_mask |= crtc_state->encoder_mask; - encoder_mask |= crtc->state->encoder_mask; - } - - drm_for_each_encoder_mask(encoder, state->dev, encoder_mask) - rockchip_drm_psr_inhibit_put(encoder); -} - static void rockchip_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state) { diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c index 01ff3c858875..22a70ab6e214 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c @@ -13,6 +13,7 @@ */ #include +#include #include #include "rockchip_drm_drv.h" @@ -109,6 +110,42 @@ int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder) } EXPORT_SYMBOL(rockchip_drm_psr_inhibit_put); +void rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_encoder *encoder; + u32 encoder_mask = 0; + int i; + + for_each_old_crtc_in_state(state, crtc, crtc_state, i) { + encoder_mask |= crtc_state->encoder_mask; + encoder_mask |= crtc->state->encoder_mask; + } + + drm_for_each_encoder_mask(encoder, state->dev, encoder_mask) + rockchip_drm_psr_inhibit_get(encoder); +} +EXPORT_SYMBOL(rockchip_drm_psr_inhibit_get_state); + +void rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + struct drm_encoder *encoder; + u32 encoder_mask = 0; + int i; + + for_each_old_crtc_in_state(state, crtc, crtc_state, i) { + encoder_mask |= crtc_state->encoder_mask; + encoder_mask |= crtc->state->encoder_mask; + } + + drm_for_each_encoder_mask(encoder, state->dev, encoder_mask) + rockchip_drm_psr_inhibit_put(encoder); +} +EXPORT_SYMBOL(rockchip_drm_psr_inhibit_put_state); + /** * rockchip_drm_psr_inhibit_get - acquire PSR inhibit on given encoder * @encoder: encoder to obtain the PSR encoder diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h index 860c62494496..25350ba3237b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h @@ -20,6 +20,9 @@ void rockchip_drm_psr_flush_all(struct drm_device *dev); int rockchip_drm_psr_inhibit_put(struct drm_encoder *encoder); int rockchip_drm_psr_inhibit_get(struct drm_encoder *encoder); +void rockchip_drm_psr_inhibit_get_state(struct drm_atomic_state *state); +void rockchip_drm_psr_inhibit_put_state(struct drm_atomic_state *state); + int rockchip_drm_psr_register(struct drm_encoder *encoder, int (*psr_set)(struct drm_encoder *, bool enable)); void rockchip_drm_psr_unregister(struct drm_encoder *encoder); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index fb70fb486fbf..e5fb21e3ccf8 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -819,10 +820,83 @@ static void vop_plane_atomic_update(struct drm_plane *plane, spin_unlock(&vop->reg_lock); } +static int vop_plane_atomic_async_check(struct drm_plane *plane, + struct drm_plane_state *state) +{ + struct vop_win *vop_win = to_vop_win(plane); + const struct vop_win_data *win = vop_win->data; + int min_scale = win->phy->scl ? FRAC_16_16(1, 8) : + DRM_PLANE_HELPER_NO_SCALING; + int max_scale = win->phy->scl ? FRAC_16_16(8, 1) : + DRM_PLANE_HELPER_NO_SCALING; + struct drm_crtc_state *crtc_state; + + if (plane != state->crtc->cursor) + return -EINVAL; + + if (!plane->state) + return -EINVAL; + + if (!plane->state->fb) + return -EINVAL; + + if (state->state) + crtc_state = drm_atomic_get_existing_crtc_state(state->state, + state->crtc); + else /* Special case for asynchronous cursor updates. */ + crtc_state = plane->crtc->state; + + return drm_atomic_helper_check_plane_state(plane->state, crtc_state, + min_scale, max_scale, + true, true); +} + +static void vop_plane_atomic_async_update(struct drm_plane *plane, + struct drm_plane_state *new_state) +{ + struct vop *vop = to_vop(plane->state->crtc); + struct drm_plane_state *plane_state; + + plane_state = plane->funcs->atomic_duplicate_state(plane); + plane_state->crtc_x = new_state->crtc_x; + plane_state->crtc_y = new_state->crtc_y; + plane_state->crtc_h = new_state->crtc_h; + plane_state->crtc_w = new_state->crtc_w; + plane_state->src_x = new_state->src_x; + plane_state->src_y = new_state->src_y; + plane_state->src_h = new_state->src_h; + plane_state->src_w = new_state->src_w; + + if (plane_state->fb != new_state->fb) + drm_atomic_set_fb_for_plane(plane_state, new_state->fb); + + swap(plane_state, plane->state); + + if (plane->state->fb && plane->state->fb != new_state->fb) { + drm_framebuffer_get(plane->state->fb); + WARN_ON(drm_crtc_vblank_get(plane->state->crtc) != 0); + drm_flip_work_queue(&vop->fb_unref_work, plane->state->fb); + set_bit(VOP_PENDING_FB_UNREF, &vop->pending); + } + + if (vop->is_enabled) { + rockchip_drm_psr_inhibit_get_state(new_state->state); + vop_plane_atomic_update(plane, plane->state); + spin_lock(&vop->reg_lock); + vop_cfg_done(vop); + spin_unlock(&vop->reg_lock); + rockchip_drm_psr_inhibit_put_state(new_state->state); + } + + plane->funcs->atomic_destroy_state(plane, plane_state); +} + static const struct drm_plane_helper_funcs plane_helper_funcs = { .atomic_check = vop_plane_atomic_check, .atomic_update = vop_plane_atomic_update, .atomic_disable = vop_plane_atomic_disable, + .atomic_async_check = vop_plane_atomic_async_check, + .atomic_async_update = vop_plane_atomic_async_update, }; static const struct drm_plane_funcs vop_plane_funcs = { -- 2.19.1