From patchwork Mon Sep 3 13:49:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 10585977 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 E8BFA175A for ; Mon, 3 Sep 2018 13:49:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D5E4B297E1 for ; Mon, 3 Sep 2018 13:49:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C9150297EC; Mon, 3 Sep 2018 13:49:47 +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 611CB297E1 for ; Mon, 3 Sep 2018 13:49:47 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 1A7DE890AF; Mon, 3 Sep 2018 13:49:45 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wr1-x444.google.com (mail-wr1-x444.google.com [IPv6:2a00:1450:4864:20::444]) by gabe.freedesktop.org (Postfix) with ESMTPS id A3312890AF for ; Mon, 3 Sep 2018 13:49:43 +0000 (UTC) Received: by mail-wr1-x444.google.com with SMTP id o37-v6so745608wrf.6 for ; Mon, 03 Sep 2018 06:49:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=eGdPVS1hmmh8A+MBC/MKcmxcBqsPEV4vpqI/JhInOdQ=; b=U9Nl5QjBOrG/qzV4QmrpssUag1pvcFKn/c/42Vp851oNB9AGAs2OfSOwu0+zF6OPL6 q56Wmw7T07wiIWXvq1zlcJK9HFqACEHh35V7Tj7AVNXfni7YsRzfEW3jw+R1qRRtLb6A 0HQ5ofUdZcZRGPxeIMB8kwncBTZiHuCUgaDmytfrZsU93lg4RdYL5I/WklO5fviFsf+O heuUIDTyRdMFy1Tko6KiccqGHG7JLdWc0h8+XpRu7GXsvsBsYsRa90S0UorzL0zwIgDn JLcDowf01l5P1GNj6KVxfjozr9vd3rUj+0YuaEO3bAr+BJVI4tOR9xNuhPvTSjZB+eoX 3aKA== X-Gm-Message-State: APzg51CVTgV1Ev5MINR75wg4zGI/CscaKtLIUAnXpi3gZiYWwBb1+d4P iBe7MxomGCJyu81W7irR8OZPwg== X-Google-Smtp-Source: ANB0VdZWiH4oHb6tIQ+Q4eneKMKPC8jCCnmpaZspBdoxpy1i87Vgw80xIeGgA/OtHiUfDmpwrU+cLQ== X-Received: by 2002:a5d:4a44:: with SMTP id v4-v6mr19190365wrs.278.1535982582262; Mon, 03 Sep 2018 06:49:42 -0700 (PDT) Received: from lmecxl0911.lme.st.com ([2a04:cec0:10c6:f4fe:894b:34a5:5366:e59c]) by smtp.gmail.com with ESMTPSA id z16-v6sm14750416wrq.78.2018.09.03.06.49.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 03 Sep 2018 06:49:41 -0700 (PDT) From: Benjamin Gaignard To: yannick.fertre@st.com, philippe.cornu@st.com, airlied@linux.ie Subject: [PATCH] drm: stm: implement get_scanout_position function Date: Mon, 3 Sep 2018 15:49:27 +0200 Message-Id: <20180903134927.27583-1-benjamin.gaignard@linaro.org> X-Mailer: git-send-email 2.15.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: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Benjamin Gaignard MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Hardware allow to read the position in scanout buffer so we can use this information to make wait of vblank more accurate. Active area bounds (start, end, total height) have already been computed and written in ltdc registers, read them and get the current line position to compute vpos value. Signed-off-by: Benjamin Gaignard --- drivers/gpu/drm/stm/drv.c | 2 ++ drivers/gpu/drm/stm/ltdc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/stm/ltdc.h | 5 +++++ 3 files changed, 52 insertions(+) diff --git a/drivers/gpu/drm/stm/drv.c b/drivers/gpu/drm/stm/drv.c index 8698e08313e1..ac53383350e3 100644 --- a/drivers/gpu/drm/stm/drv.c +++ b/drivers/gpu/drm/stm/drv.c @@ -72,6 +72,8 @@ static struct drm_driver drv_driver = { .gem_prime_vmap = drm_gem_cma_prime_vmap, .gem_prime_vunmap = drm_gem_cma_prime_vunmap, .gem_prime_mmap = drm_gem_cma_prime_mmap, + .get_scanout_position = ltdc_crtc_scanoutpos, + .get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos, }; static int drv_load(struct drm_device *ddev) diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index d997a6014d6c..05b714673042 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -148,6 +148,8 @@ #define IER_TERRIE BIT(2) /* Transfer ERRor Interrupt Enable */ #define IER_RRIE BIT(3) /* Register Reload Interrupt enable */ +#define CPSR_CYPOS GENMASK(15, 0) /* Current Y position */ + #define ISR_LIF BIT(0) /* Line Interrupt Flag */ #define ISR_FUIF BIT(1) /* Fifo Underrun Interrupt Flag */ #define ISR_TERRIF BIT(2) /* Transfer ERRor Interrupt Flag */ @@ -622,6 +624,49 @@ static void ltdc_crtc_disable_vblank(struct drm_crtc *crtc) reg_clear(ldev->regs, LTDC_IER, IER_LIE); } +bool ltdc_crtc_scanoutpos(struct drm_device *ddev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode) +{ + struct ltdc_device *ldev = ddev->dev_private; + int line, vactive_start, vactive_end, vtotal; + + if (stime) + *stime = ktime_get(); + + /* The active area starts after vsync + front porch and ends + * at vsync + front porc + display size. + * The total height also include back porch. + * We have 3 possible cases to handle: + * - line < vactive_start: vpos = line - vactive_start and will be + * negative + * - vactive_start < line < vactive_end: vpos = line - vactive_start + * and will be positive + * - line > vactive_end: vpos = line - vtotal - vactive_start + * and will negative + * + * Computation for the two first cases are identical so we can + * simplify the code and only test if line > vactive_end + */ + line = reg_read(ldev->regs, LTDC_CPSR) & CPSR_CYPOS; + vactive_start = reg_read(ldev->regs, LTDC_BPCR) & BPCR_AVBP; + vactive_end = reg_read(ldev->regs, LTDC_AWCR) & AWCR_AAH; + vtotal = reg_read(ldev->regs, LTDC_TWCR) & TWCR_TOTALH; + + if (line > vactive_end) + *vpos = line - vtotal - vactive_start; + else + *vpos = line - vactive_start; + + *hpos = 0; + + if (etime) + *etime = ktime_get(); + + return true; +} + static const struct drm_crtc_funcs ltdc_crtc_funcs = { .destroy = drm_crtc_cleanup, .set_config = drm_atomic_helper_set_config, diff --git a/drivers/gpu/drm/stm/ltdc.h b/drivers/gpu/drm/stm/ltdc.h index 1e16d6afb0d2..b8c5cc41e17a 100644 --- a/drivers/gpu/drm/stm/ltdc.h +++ b/drivers/gpu/drm/stm/ltdc.h @@ -37,6 +37,11 @@ struct ltdc_device { struct fps_info plane_fpsi[LTDC_MAX_LAYER]; }; +bool ltdc_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe, + bool in_vblank_irq, int *vpos, int *hpos, + ktime_t *stime, ktime_t *etime, + const struct drm_display_mode *mode); + int ltdc_load(struct drm_device *ddev); void ltdc_unload(struct drm_device *ddev);