Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp399567yba; Fri, 12 Apr 2019 06:01:03 -0700 (PDT) X-Google-Smtp-Source: APXvYqxsoJyIy5mQ3bHm/49SoIbH0WKddnXMRNY+71wWNPRboJGZ6TkR4iYK17xqTXbnyeA2qkaw X-Received: by 2002:a65:414a:: with SMTP id x10mr53818658pgp.237.1555074062940; Fri, 12 Apr 2019 06:01:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555074062; cv=none; d=google.com; s=arc-20160816; b=q15gggwOEaA7VtADmI+mJeASTJFoG8C5VT2UMrnk03UzPGeSka/yY5P8dmgAp6/i8k uAWgHKtsgei1z1d3KmoV7kii881vAhNQFpyhf/9PIAxPAUerZsA2+M8B2YCN/It9gcKT sWKGwzo9TADu5oDblqhdaGDCBaM/DZvBVvQ9wwxeQA0FZgADsfO/42pAwCiqCrm+2PxO YfXDcK6NOu9jtbXnebzQlODKQeEGSKzXWp6my4JUji7bev+s6U9pcKESLTTLHLYqPXxO JOGgp81ypjniMTfKqLzlbR95e+NLrCVmwJ9wl+xgCAntzY2eZrwNO2TuonGzRl+fP2zi aiSA== 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 :references:in-reply-to:message-id:date:subject:cc:to:from; bh=Tr+yRhZkDk7R5XRbnMFGxV5RAnOPUHtReJ46uPb21n4=; b=qPKntasZG3IQCqUFJZh1AGIR/BRw6vilPHDpdCUmOX/8eJ5HkMDP3Rx1p9CLZ3S9Pv ay3P6De7096oOngDcllxI3eCFiY9aAotu5R35JjB5npDqKRUyOJcDwmWQAUB7+LjkQji BXgV7+hmUOluRmW3N0MN8BeQamRBt5pujt7HH0EPxLgWkYQZpxCrzVsQqOAb75HQ39dt hsHBoAIeeMO/VMY6/jiodaGxFQLtDJ/hf3jmjAgjL+l0LhFwTDWKHAWQIOMkclW5UK3U xXs1Z77infpwVWDyI/2RuLkn9UHF86iFzCkwo4nEZrUHG5DikcAE0lb5Ykk1SPfzbQye yipg== 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 j64si20132439pge.398.2019.04.12.06.00.46; Fri, 12 Apr 2019 06:01:02 -0700 (PDT) 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 S1727881AbfDLM72 (ORCPT + 99 others); Fri, 12 Apr 2019 08:59:28 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:34596 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726702AbfDLM71 (ORCPT ); Fri, 12 Apr 2019 08:59:27 -0400 Received: from localhost.localdomain (unknown [IPv6:2804:431:9718:a5e8:c168:522a:50d5:d06d]) (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 533B22811D2; Fri, 12 Apr 2019 13:59:15 +0100 (BST) From: Helen Koike To: dri-devel@lists.freedesktop.org, David Airlie Cc: dnicoara@chromium.org, daniels@collabora.com, alexandros.frantzis@collabora.com, daniel.vetter@ffwll.ch, linux-kernel@vger.kernel.org, tomasz Figa , tina.zhang@intel.com, boris.brezillon@collabora.com, Sean Paul , kernel@collabora.com, nicholas.kazlauskas@amd.com, =?UTF-8?q?St=C3=A9phane=20Marchesin?= , Gustavo Padovan , Helen Koike , Sean Paul , Sandy Huang , Thomas Zimmermann , Harry Wentland , Alex Deucher , Bhawanpreet Lakha , "David (ChunMing) Zhou" , Anthony Koo , Russell King , linux-rockchip@lists.infradead.org, =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= , Rob Clark , =?UTF-8?q?Heiko=20St=C3=BCbner?= , Eric Anholt , Leo Li , linux-arm-msm@vger.kernel.org, =?UTF-8?q?Christian=20K=C3=B6nig?= , linux-arm-kernel@lists.infradead.org, David Francis , Mikita Lipski , amd-gfx@lists.freedesktop.org, Maarten Lankhorst , Daniel Vetter , freedreno@lists.freedesktop.org, Mamta Shukla , Maxime Ripard Subject: [PATCH RFC v3 4/4] drm/atomic: hook atomic_async_{check,update} with PAGE_FLIP_ASYNC flag Date: Fri, 12 Apr 2019 09:58:27 -0300 Message-Id: <20190412125827.5877-5-helen.koike@collabora.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190412125827.5877-1-helen.koike@collabora.com> References: <20190412125827.5877-1-helen.koike@collabora.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add atomic_async_{check,update} hooks in drm_plane_helper_funcs. These hooks are called when userspace requests asyncronous page flip in the atomic api through the flag DRM_MODE_PAGE_FLIP_ASYNC. Update those hooks in the drivers that implement async functions, except for amdgpu who handles the flag in the normal path, and rockchip who doesn't support async page flip. Signed-off-by: Helen Koike --- Hi, This patch is an attempt to expose the implementation that already exist for true async page flips updates through atomic api when the DRM_MODE_PAGE_FLIP_ASYNC is used. In this commit I'm re-introducing the atomic_async_{check,update} hooks. I know it is a bit weird to remove them first and them re-add them, but I did this in the last commit to avoid any state of inconsistency between commits, as rockchip doesn't support async page flip and they were being used as amend. So I reverted to amend first and then re-introced async again tied to the DRM_MODE_PAGE_FLIP_ASYNC flag (I also think this is easier to read). To use async, it is required to have dev->mode_config.async_page_flip = true; but I see that only amdgpu and vc4 have this, so this patch won't take effect on mdp5. Nouveau and radeon also have this flag, but they don't implement the async hooks yet. Please let me know what you think. Thanks Helen Changes in v3: None Changes in v2: None Changes in v1: None .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++ drivers/gpu/drm/drm_atomic_helper.c | 31 ++++++++++++---- drivers/gpu/drm/drm_atomic_uapi.c | 3 +- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 2 + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 ++ drivers/gpu/drm/vc4/vc4_plane.c | 2 + include/drm/drm_atomic.h | 2 + include/drm/drm_atomic_helper.h | 9 +++-- include/drm/drm_modeset_helper_vtables.h | 37 +++++++++++++++++++ 9 files changed, 83 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 711e7715e112..bb8a5f1997d6 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3785,6 +3785,11 @@ static const struct drm_plane_helper_funcs dm_plane_helper_funcs = { */ .atomic_amend_check = dm_plane_atomic_async_check, .atomic_amend_update = dm_plane_atomic_async_update + /* + * Note: amdgpu takes care of DRM_MODE_PAGE_FLIP_ASYNC flag in the + * normal commit path, thus .atomic_async_check and .atomic_async_update + * are not provided here. + */ }; /* diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 9b0df08836c3..bfcf88359de5 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -947,16 +947,31 @@ int drm_atomic_helper_check(struct drm_device *dev, if (ret) return ret; + /* + * If async page flip was explicitly requested, but it is not possible, + * return error instead of falling back to a normal commit. + * If async_amend_check returns -EOPNOTSUPP, it means + * ->atomic_async_update hook doesn't exist, so fallback to normal + * commit and let the driver handle DRM_MODE_PAGE_FLIP_ASYNC flag + * through normal commit code path. + */ + if (state->async_update) { + ret = drm_atomic_helper_async_amend_check(dev, state, false); + state->async_update = !ret; + return !ret || ret == -EOPNOTSUPP ? 0 : ret; + } + /* * If amend was explicitly requested, but it is not possible, * return error instead of falling back to a normal commit. */ if (state->amend_update) - return drm_atomic_helper_amend_check(dev, state); + return drm_atomic_helper_async_amend_check(dev, state, true); /* Legacy mode falls back to a normal commit if amend isn't possible. */ if (state->legacy_cursor_update) - state->amend_update = !drm_atomic_helper_amend_check(dev, state); + state->amend_update = + !drm_atomic_helper_async_amend_check(dev, state, true); return 0; } @@ -1651,8 +1666,9 @@ static void commit_work(struct work_struct *work) * if not. Note that error just mean it can't be committed in amend mode, if it * fails the commit should be treated like a normal commit. */ -int drm_atomic_helper_amend_check(struct drm_device *dev, - struct drm_atomic_state *state) +int drm_atomic_helper_async_amend_check(struct drm_device *dev, + struct drm_atomic_state *state, + bool amend) { struct drm_crtc *crtc; struct drm_crtc_state *crtc_state; @@ -1695,7 +1711,7 @@ int drm_atomic_helper_amend_check(struct drm_device *dev, return -EINVAL; /* Only allow amend update for cursor type planes. */ - if (plane->type != DRM_PLANE_TYPE_CURSOR) + if (amend && plane->type != DRM_PLANE_TYPE_CURSOR) return -EINVAL; /* @@ -1707,9 +1723,10 @@ int drm_atomic_helper_amend_check(struct drm_device *dev, !try_wait_for_completion(&old_plane_state->commit->hw_done)) return -EBUSY; - return funcs->atomic_amend_check(plane, new_plane_state); + return amend ? funcs->atomic_amend_check(plane, new_plane_state) : + funcs->atomic_async_check(plane, new_plane_state); } -EXPORT_SYMBOL(drm_atomic_helper_amend_check); +EXPORT_SYMBOL(drm_atomic_helper_async_amend_check); /** * drm_atomic_helper_amend_commit - commit state in amend mode diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index d1962cdea602..1d9a6142218e 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -1312,8 +1312,9 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); state->acquire_ctx = &ctx; state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET); + state->async_update = !!(arg->flags & DRM_MODE_PAGE_FLIP_ASYNC); /* async takes precedence over amend */ - state->amend_update = arg->flags & DRM_MODE_PAGE_FLIP_ASYNC ? 0 : + state->amend_update = state->async_update ? 0 : !!(arg->flags & DRM_MODE_ATOMIC_AMEND); retry: diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 814e8230cec6..e3b2a2c74852 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -531,6 +531,8 @@ static const struct drm_plane_helper_funcs mdp5_plane_helper_funcs = { .cleanup_fb = mdp5_plane_cleanup_fb, .atomic_check = mdp5_plane_atomic_check, .atomic_update = mdp5_plane_atomic_update, + .atomic_async_check = mdp5_plane_atomic_async_check, + .atomic_async_update = mdp5_plane_atomic_async_update, /* * FIXME: ideally, instead of hooking async updates to amend, * we could avoid tearing by modifying the pending commit. diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 216ad76118dc..c2f7201e52a9 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -954,6 +954,10 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = { .atomic_disable = vop_plane_atomic_disable, .atomic_amend_check = vop_plane_atomic_amend_check, .atomic_amend_update = vop_plane_atomic_amend_update, + /* + * Note: rockchip doesn't support async page flip, thus + * .atomic_async_update and .atomic_async_check are not provided. + */ .prepare_fb = drm_gem_fb_prepare_fb, }; diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index ea560000222d..24a9befe89e6 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -1175,6 +1175,8 @@ static const struct drm_plane_helper_funcs vc4_plane_helper_funcs = { */ .atomic_amend_check = vc4_plane_atomic_async_check, .atomic_amend_update = vc4_plane_atomic_async_update, + .atomic_async_check = vc4_plane_atomic_async_check, + .atomic_async_update = vc4_plane_atomic_async_update, }; static void vc4_plane_destroy(struct drm_plane *plane) diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h index b1ced069ffc1..05756a09e762 100644 --- a/include/drm/drm_atomic.h +++ b/include/drm/drm_atomic.h @@ -300,6 +300,7 @@ struct __drm_private_objs_state { * @ref: count of all references to this state (will not be freed until zero) * @dev: parent DRM device * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics + * @async_update: hint for asyncronous page flip update * @amend_update: hint for amend plane update * @planes: pointer to array of structures with per-plane data * @crtcs: pointer to array of CRTC pointers @@ -328,6 +329,7 @@ struct drm_atomic_state { */ bool allow_modeset : 1; bool legacy_cursor_update : 1; + bool async_update : 1; bool amend_update : 1; /** * @duplicated: diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 8ce0594ccfb9..39e57d559a30 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h @@ -55,10 +55,11 @@ void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *state); int drm_atomic_helper_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock); -int drm_atomic_helper_amend_check(struct drm_device *dev, - struct drm_atomic_state *state); -void drm_atomic_helper_amend_commit(struct drm_device *dev, - struct drm_atomic_state *state); +int drm_atomic_helper_async_amend_check(struct drm_device *dev, + struct drm_atomic_state *state, + bool amend); +void drm_atomic_helper_async_amend_commit(struct drm_device *dev, + struct drm_atomic_state *state); int drm_atomic_helper_wait_for_fences(struct drm_device *dev, struct drm_atomic_state *state, diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h index d92e62dd76c4..c2863d62f160 100644 --- a/include/drm/drm_modeset_helper_vtables.h +++ b/include/drm/drm_modeset_helper_vtables.h @@ -1135,6 +1135,43 @@ struct drm_plane_helper_funcs { void (*atomic_disable)(struct drm_plane *plane, struct drm_plane_state *old_state); + /** + * @atomic_async_check: + * + * Drivers should set this function pointer to check if a page flip can + * be performed asynchronously, i.e., immediately without waiting for a + * vblank. + * + * This hook is called by drm_atomic_async_check() to establish if a + * given update can be committed in async mode, that is, if it can + * jump ahead of the state currently queued for update. + * + * RETURNS: + * + * Return 0 on success and any error returned indicates that the update + * can not be applied in asynd mode. + */ + int (*atomic_async_check)(struct drm_plane *plane, + struct drm_plane_state *state); + + /** + * @atomic_async_update: + * + * Drivers should set this function pointer to perform asynchronous page + * flips through the atomic api, i.e. not vblank synchronized. + * + * Note that unlike &drm_plane_helper_funcs.atomic_update this hook + * takes the new &drm_plane_state as parameter. When doing async_update + * drivers shouldn't replace the &drm_plane_state but update the + * current one with the new plane configurations in the new + * plane_state. + * + * FIXME: + * - It only works for single plane updates + */ + void (*atomic_async_update)(struct drm_plane *plane, + struct drm_plane_state *new_state); + /** * @atomic_amend_check: * -- 2.20.1