From patchwork Thu Sep 24 16:35:35 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 7258191 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B4D0DBF036 for ; Thu, 24 Sep 2015 16:36:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 695B120933 for ; Thu, 24 Sep 2015 16:36:30 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 57C782082E for ; Thu, 24 Sep 2015 16:36:27 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8AF4C7A11E; Thu, 24 Sep 2015 09:36:26 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pa0-f48.google.com (mail-pa0-f48.google.com [209.85.220.48]) by gabe.freedesktop.org (Postfix) with ESMTPS id 871A96EF02 for ; Thu, 24 Sep 2015 09:36:24 -0700 (PDT) Received: by padhy16 with SMTP id hy16so77663329pad.1 for ; Thu, 24 Sep 2015 09:36:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=nEUGkkghIw7Sf223LM2P9Xt6IK4A/+znH9iXTXnKloY=; b=acH02eznIdzrRfe2VBb3hLwY1ouFHRV4uCHsEK7wrDfYRjhUJMPkabUtWkwxU9b59J 1cwmNPuswmgg6weCrB0Ls+WQATYWFitRFy9iS9wUWnq67LmovJB9wISQNgIoNTK2omO5 +6m0K59wiy8Q3H1nYE0YA5sv+mRuefeBmq4r7wvPJgAHDwBddViVl/E/p8oW7uxp5CYx sjsBMwfhRxfmxZxugq3VobOHIv+9I0mNll12gQ1LlbDrMDP3iBalSwcA7g69agXDxP6j 5GQ9IjNiKKBPNHM1E3rIvp0zl+XjsyMgdrxtC/I6zq5OK5kPCV/doAb2zl3orveBWbTJ bIoQ== X-Received: by 10.66.253.199 with SMTP id ac7mr753819pad.56.1443112584243; Thu, 24 Sep 2015 09:36:24 -0700 (PDT) Received: from localhost (port-5631.pppoe.wtnet.de. [84.46.22.21]) by smtp.gmail.com with ESMTPSA id de4sm14484640pbb.60.2015.09.24.09.36.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 24 Sep 2015 09:36:23 -0700 (PDT) From: Thierry Reding To: dri-devel@lists.freedesktop.org Subject: [PATCH 13/16] drm: Move ->get_scanout_position() to struct drm_crtc_funcs Date: Thu, 24 Sep 2015 18:35:35 +0200 Message-Id: <1443112538-9616-13-git-send-email-thierry.reding@gmail.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1443112538-9616-1-git-send-email-thierry.reding@gmail.com> References: <1443112538-9616-1-git-send-email-thierry.reding@gmail.com> MIME-Version: 1.0 Cc: Alex Deucher , Daniel Vetter , Ben Skeggs , =?UTF-8?q?Christian=20K=C3=B6nig?= X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FILL_THIS_FORM_LOAN,FREEMAIL_FROM,RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Thierry Reding None of the drivers use this in legacy mode, so it can be converted to use struct drm_crtc * directly. While at it, also make the sole user of the callback, drm_calc_vbltimestamp_from_scanoutpos(), pass through the CRTC directly. v2: use standard [CRTC:%u] format Cc: Daniel Vetter Cc: Jani Nikula Cc: Ben Skeggs Cc: Alex Deucher Cc: Christian König Signed-off-by: Thierry Reding --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 13 ++++---- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 6 ++-- drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 1 + drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 1 + drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 1 + drivers/gpu/drm/drm_irq.c | 40 ++++++++++--------------- drivers/gpu/drm/i915/i915_irq.c | 14 ++++----- drivers/gpu/drm/i915/intel_display.c | 1 + drivers/gpu/drm/i915/intel_drv.h | 4 +++ drivers/gpu/drm/nouveau/dispnv04/crtc.c | 1 + drivers/gpu/drm/nouveau/nouveau_display.c | 28 ++++-------------- drivers/gpu/drm/nouveau/nouveau_display.h | 12 ++++---- drivers/gpu/drm/nouveau/nouveau_drm.c | 1 - drivers/gpu/drm/nouveau/nv50_display.c | 1 + drivers/gpu/drm/radeon/radeon_display.c | 37 ++++++++++++----------- drivers/gpu/drm/radeon/radeon_drv.c | 1 - drivers/gpu/drm/radeon/radeon_kms.c | 2 +- drivers/gpu/drm/radeon/radeon_mode.h | 6 ++-- drivers/gpu/drm/radeon/radeon_pm.c | 6 ++-- include/drm/drmP.h | 46 ----------------------------- include/drm/drm_crtc.h | 46 +++++++++++++++++++++++++++++ 23 files changed, 127 insertions(+), 144 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index de116398fa49..ef2a32854fac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -720,8 +720,7 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * Retrieve current video scanout position of crtc on a given gpu, and * an optional accurate timestamp of when query happened. * - * \param dev Device to query. - * \param pipe Crtc to query. + * \param crtc CRTC to query. * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). * \param *vpos Location where vertical scanout position should be stored. * \param *hpos Location where horizontal scanout position should go. @@ -744,17 +743,17 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * unknown small number of scanlines wrt. real scanout position. * */ -int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, +int amdgpu_get_crtc_scanoutpos(struct drm_crtc *crtc, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, + ktime_t *etime, const struct drm_display_mode *mode) { + struct amdgpu_device *adev = crtc->dev->dev_private; + unsigned int pipe = drm_crtc_index(crtc); u32 vbl = 0, position = 0; int vbl_start, vbl_end, vtotal, ret = 0; bool in_vbl = true; - struct amdgpu_device *adev = dev->dev_private; - /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ /* Get optional system timestamp before query. */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 0fcc0bd1622c..b44f0bd9edfc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -480,7 +480,6 @@ static struct drm_driver kms_driver = { .enable_vblank = amdgpu_enable_vblank_kms, .disable_vblank = amdgpu_disable_vblank_kms, .get_vblank_timestamp = amdgpu_get_vblank_timestamp_kms, - .get_scanout_position = amdgpu_get_crtc_scanoutpos, #if defined(CONFIG_DEBUG_FS) .debugfs_init = amdgpu_debugfs_init, .debugfs_cleanup = amdgpu_debugfs_cleanup, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 0118fd3cda13..231b7a4c1391 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -679,7 +679,7 @@ int amdgpu_get_vblank_timestamp_kms(struct drm_device *dev, unsigned int pipe, crtc = &adev->mode_info.crtcs[pipe]->base; /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, + return drm_calc_vbltimestamp_from_scanoutpos(crtc, max_error, vblank_time, flags, &crtc->hwmode); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index f6b02994442b..4e0c66adfaf8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -540,9 +540,9 @@ bool amdgpu_ddc_probe(struct amdgpu_connector *amdgpu_connector, bool use_aux); void amdgpu_encoder_set_active_device(struct drm_encoder *encoder); -int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, +int amdgpu_get_crtc_scanoutpos(struct drm_crtc *crtc, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, + ktime_t *etime, const struct drm_display_mode *mode); int amdgpu_framebuffer_init(struct drm_device *dev, diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index e4d101b1252a..1932f41b610d 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -2647,6 +2647,7 @@ static const struct drm_crtc_funcs dce_v10_0_crtc_funcs = { .set_config = amdgpu_crtc_set_config, .destroy = dce_v10_0_crtc_destroy, .page_flip = amdgpu_crtc_page_flip, + .get_scanout_position = amdgpu_get_crtc_scanoutpos, }; static void dce_v10_0_crtc_dpms(struct drm_crtc *crtc, int mode) diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 6411e8244671..e89bce0aabca 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c @@ -2624,6 +2624,7 @@ static const struct drm_crtc_funcs dce_v11_0_crtc_funcs = { .set_config = amdgpu_crtc_set_config, .destroy = dce_v11_0_crtc_destroy, .page_flip = amdgpu_crtc_page_flip, + .get_scanout_position = amdgpu_get_crtc_scanoutpos, }; static void dce_v11_0_crtc_dpms(struct drm_crtc *crtc, int mode) diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index c86911c2ea2a..f6ab329b2e2f 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -2559,6 +2559,7 @@ static const struct drm_crtc_funcs dce_v8_0_crtc_funcs = { .set_config = amdgpu_crtc_set_config, .destroy = dce_v8_0_crtc_destroy, .page_flip = amdgpu_crtc_page_flip, + .get_scanout_position = amdgpu_get_crtc_scanoutpos, }; static void dce_v8_0_crtc_dpms(struct drm_crtc *crtc, int mode) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4a5dee5cd327..525bd82ab514 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -653,8 +653,7 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); /** * drm_calc_vbltimestamp_from_scanoutpos - precise vblank timestamp helper - * @dev: DRM device - * @pipe: index of CRTC whose vblank timestamp to retrieve + * @crtc: CRTC whose vblank timestamp to retrieve * @max_error: Desired maximum allowable error in timestamps (nanosecs) * On return contains true maximum error of timestamp * @vblank_time: Pointer to struct timeval which should receive the timestamp @@ -696,13 +695,13 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants); * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. * */ -int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, +int drm_calc_vbltimestamp_from_scanoutpos(struct drm_crtc *crtc, int *max_error, struct timeval *vblank_time, unsigned flags, const struct drm_display_mode *mode) { + const struct drm_crtc_funcs *funcs = crtc->funcs; struct timeval tv_etime; ktime_t stime, etime; unsigned int vbl_status; @@ -710,22 +709,16 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int vpos, hpos, i; int delta_ns, duration_ns; - if (pipe >= dev->num_crtcs) { - DRM_ERROR("Invalid crtc %u\n", pipe); - return -EINVAL; - } - /* Scanout position query not supported? Should not happen. */ - if (!dev->driver->get_scanout_position) { - DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); - return -EIO; - } + if (WARN_ON(funcs->get_scanout_position == NULL)) + return -ENOSYS; /* If mode timing undefined, just return as no-op: * Happens during initial modesetting of a crtc. */ if (mode->crtc_clock == 0) { - DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); + DRM_DEBUG("[CRTC:%u] Noop due to uninitialized mode.\n", + crtc->base.id); return -EAGAIN; } @@ -741,15 +734,14 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, * Get vertical and horizontal scanout position vpos, hpos, * and bounding timestamps stime, etime, pre/post query. */ - vbl_status = dev->driver->get_scanout_position(dev, pipe, flags, - &vpos, &hpos, - &stime, &etime, - mode); + vbl_status = funcs->get_scanout_position(crtc, flags, &vpos, + &hpos, &stime, &etime, + mode); /* Return as no-op if scanout query unsupported or failed. */ if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { - DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n", - pipe, vbl_status); + DRM_DEBUG("[CRTC:%u] scanoutpos query failed [%d].\n", + crtc->base.id, vbl_status); return -EIO; } @@ -763,8 +755,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, /* Noisy system timing? */ if (i == DRM_TIMESTAMP_MAXRETRIES) { - DRM_DEBUG("crtc %u: Noisy timestamp %d us > %d us [%d reps].\n", - pipe, duration_ns/1000, *max_error/1000, i); + DRM_DEBUG("[CRTC:%u] Noisy timestamp %d us > %d us [%d reps].\n", + crtc->base.id, duration_ns/1000, *max_error/1000, i); } /* Return upper bound of timestamp precision error. */ @@ -799,8 +791,8 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, etime = ktime_sub_ns(etime, delta_ns); *vblank_time = ktime_to_timeval(etime); - DRM_DEBUG("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", - pipe, vbl_status, hpos, vpos, + DRM_DEBUG("[CRTC:%u] v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", + crtc->base.id, vbl_status, hpos, vpos, (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, duration_ns/1000, i); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7b3aeb0f8056..6eec529b3a5b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -767,14 +767,15 @@ static int __intel_get_crtc_scanline(struct intel_crtc *crtc) return (position + crtc->scanline_offset) % vtotal; } -static int i915_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) +int i915_get_crtc_scanoutpos(struct drm_crtc *crtc, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, + ktime_t *etime, + const struct drm_display_mode *mode) { + struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum pipe pipe = intel_crtc->pipe; int position; int vbl_start, vbl_end, hsync_start, htotal, vtotal; bool in_vbl = true; @@ -929,7 +930,7 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, } /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, pipe, max_error, + return drm_calc_vbltimestamp_from_scanoutpos(crtc, max_error, vblank_time, flags, &crtc->hwmode); } @@ -4387,7 +4388,6 @@ void intel_irq_init(struct drm_i915_private *dev_priv) dev->vblank_disable_immediate = true; dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; - dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; if (IS_CHERRYVIEW(dev_priv)) { dev->driver->irq_handler = cherryview_irq_handler; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2a1fab3eb285..48965f206fda 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13203,6 +13203,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { .page_flip = intel_crtc_page_flip, .atomic_duplicate_state = intel_crtc_duplicate_state, .atomic_destroy_state = intel_crtc_destroy_state, + .get_scanout_position = i915_get_crtc_scanoutpos, }; static bool ibx_pch_dpll_get_hw_state(struct drm_i915_private *dev_priv, diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f4242d23f63f..bc86ae28d455 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -955,6 +955,10 @@ static inline bool intel_irqs_enabled(struct drm_i915_private *dev_priv) return dev_priv->pm.irqs_enabled; } +int i915_get_crtc_scanoutpos(struct drm_crtc *crtc, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, + ktime_t *etime, + const struct drm_display_mode *mode); int intel_get_crtc_scanline(struct intel_crtc *crtc); void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, unsigned int pipe_mask); diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 3d96b49fe662..1a1f9dec1572 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -1089,6 +1089,7 @@ static const struct drm_crtc_funcs nv04_crtc_funcs = { .set_config = nouveau_crtc_set_config, .page_flip = nouveau_crtc_page_flip, .destroy = nv_crtc_destroy, + .get_scanout_position = nouveau_display_scanoutpos, }; static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 886079dd9baa..8bd8421ce63c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -92,8 +92,9 @@ calc(int blanks, int blanke, int total, int line) } int -nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime) +nouveau_display_scanoutpos(struct drm_crtc *crtc, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, + ktime_t *etime, const struct drm_display_mode *mode) { struct { struct nv04_disp_mthd_v0 base; @@ -132,24 +133,6 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, } int -nouveau_display_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode) -{ - struct drm_crtc *crtc; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - if (nouveau_crtc(crtc)->index == pipe) { - return nouveau_display_scanoutpos_head(crtc, vpos, hpos, - stime, etime); - } - } - - return 0; -} - -int nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, int *max_error, struct timeval *time, unsigned flags) { @@ -157,9 +140,8 @@ nouveau_display_vblstamp(struct drm_device *dev, unsigned int pipe, list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (nouveau_crtc(crtc)->index == pipe) { - return drm_calc_vbltimestamp_from_scanoutpos(dev, - pipe, max_error, time, flags, - &crtc->hwmode); + return drm_calc_vbltimestamp_from_scanoutpos(crtc, + max_error, time, flags, &crtc->hwmode); } } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 856abe0f070d..e8b40117cb04 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -65,12 +65,12 @@ int nouveau_display_init(struct drm_device *dev); void nouveau_display_fini(struct drm_device *dev); int nouveau_display_suspend(struct drm_device *dev, bool runtime); void nouveau_display_resume(struct drm_device *dev, bool runtime); -int nouveau_display_vblank_enable(struct drm_device *, unsigned int); -void nouveau_display_vblank_disable(struct drm_device *, unsigned int); -int nouveau_display_scanoutpos(struct drm_device *, unsigned int, - unsigned int, int *, int *, ktime_t *, - ktime_t *, const struct drm_display_mode *); -int nouveau_display_vblstamp(struct drm_device *, unsigned int, int *, +int nouveau_display_vblank_enable(struct drm_device *, unsigned int pipe); +void nouveau_display_vblank_disable(struct drm_device *, unsigned int pipe); +int nouveau_display_scanoutpos(struct drm_crtc *, unsigned int, int *, int *, + ktime_t *, ktime_t *, + const struct drm_display_mode *); +int nouveau_display_vblstamp(struct drm_device *, unsigned int pipe, int *, struct timeval *, unsigned); int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index ccefb645fd55..55eac5310449 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -937,7 +937,6 @@ driver_stub = { .get_vblank_counter = drm_vblank_count, .enable_vblank = nouveau_display_vblank_enable, .disable_vblank = nouveau_display_vblank_disable, - .get_scanout_position = nouveau_display_scanoutpos, .get_vblank_timestamp = nouveau_display_vblstamp, .ioctls = nouveau_ioctls, diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 4ae87aed4505..0cd1826c20e4 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1423,6 +1423,7 @@ static const struct drm_crtc_funcs nv50_crtc_func = { .set_config = nouveau_crtc_set_config, .destroy = nv50_crtc_destroy, .page_flip = nouveau_crtc_page_flip, + .get_scanout_position = nouveau_display_scanoutpos, }; static int diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index a58635c5db3d..8dd7ffebef7f 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -322,10 +322,10 @@ void radeon_crtc_handle_vblank(struct radeon_device *rdev, int crtc_id) * to complete in this vblank? */ if (update_pending && - (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, 0, + (DRM_SCANOUTPOS_VALID & radeon_crtc_get_scanoutpos(&radeon_crtc->base, 0, &vpos, &hpos, NULL, NULL, - &rdev->mode_info.crtcs[crtc_id]->base.hwmode)) && - ((vpos >= (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100) || + &radeon_crtc->base.hwmode)) && + ((vpos >= (99 * radeon_crtc->base.hwmode.crtc_vdisplay)/100) || (vpos < 0 && !ASIC_IS_AVIVO(rdev)))) { /* crtc didn't flip in this target vblank interval, * but flip is pending in crtc. Based on the current @@ -642,6 +642,7 @@ static const struct drm_crtc_funcs radeon_crtc_funcs = { .set_config = radeon_crtc_set_config, .destroy = radeon_crtc_destroy, .page_flip = radeon_crtc_page_flip, + .get_scanout_position = radeon_crtc_get_scanoutpos, }; static void radeon_crtc_init(struct drm_device *dev, int index) @@ -1775,7 +1776,6 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * Retrieve current video scanout position of crtc on a given gpu, and * an optional accurate timestamp of when query happened. * - * \param dev Device to query. * \param crtc Crtc to query. * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). * \param *vpos Location where vertical scanout position should be stored. @@ -1799,16 +1799,17 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * unknown small number of scanlines wrt. real scanout position. * */ -int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, +int radeon_crtc_get_scanoutpos(struct drm_crtc *crtc, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, + ktime_t *etime, const struct drm_display_mode *mode) { + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); u32 stat_crtc = 0, vbl = 0, position = 0; int vbl_start, vbl_end, vtotal, ret = 0; bool in_vbl = true; - struct radeon_device *rdev = dev->dev_private; + struct radeon_device *rdev = crtc->dev->dev_private; /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ @@ -1817,42 +1818,42 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, *stime = ktime_get(); if (ASIC_IS_DCE4(rdev)) { - if (pipe == 0) { + if (radeon_crtc->crtc_id == 0) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC0_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC0_REGISTER_OFFSET); ret |= DRM_SCANOUTPOS_VALID; } - if (pipe == 1) { + if (radeon_crtc->crtc_id == 1) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC1_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC1_REGISTER_OFFSET); ret |= DRM_SCANOUTPOS_VALID; } - if (pipe == 2) { + if (radeon_crtc->crtc_id == 2) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC2_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC2_REGISTER_OFFSET); ret |= DRM_SCANOUTPOS_VALID; } - if (pipe == 3) { + if (radeon_crtc->crtc_id == 3) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC3_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC3_REGISTER_OFFSET); ret |= DRM_SCANOUTPOS_VALID; } - if (pipe == 4) { + if (radeon_crtc->crtc_id == 4) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC4_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC4_REGISTER_OFFSET); ret |= DRM_SCANOUTPOS_VALID; } - if (pipe == 5) { + if (radeon_crtc->crtc_id == 5) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC5_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + @@ -1860,19 +1861,19 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, ret |= DRM_SCANOUTPOS_VALID; } } else if (ASIC_IS_AVIVO(rdev)) { - if (pipe == 0) { + if (radeon_crtc->crtc_id == 0) { vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END); position = RREG32(AVIVO_D1CRTC_STATUS_POSITION); ret |= DRM_SCANOUTPOS_VALID; } - if (pipe == 1) { + if (radeon_crtc->crtc_id == 1) { vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END); position = RREG32(AVIVO_D2CRTC_STATUS_POSITION); ret |= DRM_SCANOUTPOS_VALID; } } else { /* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */ - if (pipe == 0) { + if (radeon_crtc->crtc_id == 0) { /* Assume vbl_end == 0, get vbl_start from * upper 16 bits. */ @@ -1886,7 +1887,7 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, ret |= DRM_SCANOUTPOS_VALID; } - if (pipe == 1) { + if (radeon_crtc->crtc_id == 1) { vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) & RADEON_CRTC_V_DISP) >> RADEON_CRTC_V_DISP_SHIFT; position = (RREG32(RADEON_CRTC2_VLINE_CRNT_VLINE) >> 16) & RADEON_CRTC_V_TOTAL; diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 5b6a6f5b3619..30ef157f02b5 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -578,7 +578,6 @@ static struct drm_driver kms_driver = { .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms, .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, - .get_scanout_position = radeon_get_crtc_scanoutpos, #if defined(CONFIG_DEBUG_FS) .debugfs_init = radeon_debugfs_init, .debugfs_cleanup = radeon_debugfs_cleanup, diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index fd9da282b29c..f3bcf925c3ba 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -839,7 +839,7 @@ int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, return -EINVAL; /* Helper routine in DRM core does all the work: */ - return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, + return drm_calc_vbltimestamp_from_scanoutpos(drmcrtc, max_error, vblank_time, flags, &drmcrtc->hwmode); } diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index de18f0668bea..4e11f1e40cef 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -874,9 +874,9 @@ extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); extern void radeon_cursor_reset(struct drm_crtc *crtc); -extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, +extern int radeon_crtc_get_scanoutpos(struct drm_crtc *crtc, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, + ktime_t *etime, const struct drm_display_mode *mode); extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 10f4c12e439e..dc4c29938cd1 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1732,10 +1732,12 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev) * otherwise return in_vbl == false. */ for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { + struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; + if (rdev->pm.active_crtcs & (1 << crtc)) { - vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, 0, + vbl_status = radeon_crtc_get_scanoutpos(&radeon_crtc->base, 0, &vpos, &hpos, NULL, NULL, - &rdev->mode_info.crtcs[crtc]->base.hwmode); + &radeon_crtc->base.hwmode); if ((vbl_status & DRM_SCANOUTPOS_VALID) && !(vbl_status & DRM_SCANOUTPOS_IN_VBLANK)) in_vbl = false; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index a013a0ed8e6a..ce693a1366c1 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -384,11 +384,6 @@ struct drm_master { #define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) #define DRM_VBLANKTIME_IN_VBLANK (1 << 1) -/* get_scanout_position() return flags */ -#define DRM_SCANOUTPOS_VALID (1 << 0) -#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) -#define DRM_SCANOUTPOS_ACCURATE (1 << 2) - /** * DRM driver structure. This structure represent the common code for * a family of cards. There will one drm_device for each card present @@ -468,42 +463,6 @@ struct drm_driver { int (*device_is_agp) (struct drm_device *dev); /** - * Called by vblank timestamping code. - * - * Return the current display scanout position from a crtc, and an - * optional accurate ktime_get timestamp of when position was measured. - * - * \param dev DRM device. - * \param pipe Id of the crtc to query. - * \param flags Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0). - * \param *vpos Target location for current vertical scanout position. - * \param *hpos Target location for current horizontal scanout position. - * \param *stime Target location for timestamp taken immediately before - * scanout position query. Can be NULL to skip timestamp. - * \param *etime Target location for timestamp taken immediately after - * scanout position query. Can be NULL to skip timestamp. - * \param mode Current display timings. - * - * Returns vpos as a positive number while in active scanout area. - * Returns vpos as a negative number inside vblank, counting the number - * of scanlines to go until end of vblank, e.g., -1 means "one scanline - * until start of active scanout / end of vblank." - * - * \return Flags, or'ed together as follows: - * - * DRM_SCANOUTPOS_VALID = Query successful. - * DRM_SCANOUTPOS_INVBL = Inside vblank. - * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of - * this flag means that returned position may be offset by a constant - * but unknown small number of scanlines wrt. real scanout position. - * - */ - int (*get_scanout_position) (struct drm_device *dev, unsigned int pipe, - unsigned int flags, int *vpos, int *hpos, - ktime_t *stime, ktime_t *etime, - const struct drm_display_mode *mode); - - /** * Called by \c drm_get_last_vbltimestamp. Should return a precise * timestamp when the most recent VBLANK interval ended or will end. * @@ -949,11 +908,6 @@ extern void drm_crtc_vblank_reset(struct drm_crtc *crtc); extern void drm_crtc_vblank_on(struct drm_crtc *crtc); extern void drm_vblank_cleanup(struct drm_device *dev); -extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, - unsigned int pipe, int *max_error, - struct timeval *vblank_time, - unsigned flags, - const struct drm_display_mode *mode); extern void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 683f1421a825..c5c9e316251a 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -307,6 +307,11 @@ struct drm_crtc_state { struct drm_atomic_state *state; }; +/* get_scanout_position() return flags */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) + /** * struct drm_crtc_funcs - control CRTCs for a given device * @save: save CRTC state @@ -326,6 +331,7 @@ struct drm_crtc_state { * (do not call directly, use drm_atomic_crtc_set_property()) * @atomic_get_property: get a property on an atomic state for this CRTC * (do not call directly, use drm_atomic_crtc_get_property()) + * @get_scanout_position: return the current scanout position * * The drm_crtc_funcs structure is the central CRTC management structure * in the DRM. Each CRTC controls one or more connectors (note that the name @@ -389,6 +395,40 @@ struct drm_crtc_funcs { const struct drm_crtc_state *state, struct drm_property *property, uint64_t *val); + + /** + * Called by vblank timestamping code. + * + * Return the current display scanout position from a crtc, and an + * optional accurate ktime_get timestamp of when position was measured. + * + * \param crtc CRTC to query. + * \param flags Flags from the caller (DRM_CALLED_FROM_VBLIRQ or 0). + * \param *vpos Target location for current vertical scanout position. + * \param *hpos Target location for current horizontal scanout position. + * \param *stime Target location for timestamp taken immediately before + * scanout position query. Can be NULL to skip timestamp. + * \param *etime Target location for timestamp taken immediately after + * scanout position query. Can be NULL to skip timestamp. + * \param mode Current display timings. + * + * Returns vpos as a positive number while in active scanout area. + * Returns vpos as a negative number inside vblank, counting the number + * of scanlines to go until end of vblank, e.g., -1 means "one scanline + * until start of active scanout / end of vblank." + * + * \return Flags, or'ed together as follows: + * + * DRM_SCANOUTPOS_VALID = Query successful. + * DRM_SCANOUTPOS_INVBL = Inside vblank. + * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of + * this flag means that returned position may be offset by a constant + * but unknown small number of scanlines wrt. real scanout position. + */ + int (*get_scanout_position)(struct drm_crtc *crtc, unsigned int flags, + int *vpos, int *hpos, ktime_t *stime, + ktime_t *etime, + const struct drm_display_mode *mode); }; /** @@ -1194,6 +1234,12 @@ extern int drm_crtc_init_with_planes(struct drm_device *dev, extern void drm_crtc_cleanup(struct drm_crtc *crtc); extern unsigned int drm_crtc_index(struct drm_crtc *crtc); +extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_crtc *crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags, + const struct drm_display_mode *mode); + /** * drm_crtc_mask - find the mask of a registered CRTC * @crtc: CRTC to find mask for