From patchwork Wed Jan 3 20:39:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dhinakaran Pandiyan X-Patchwork-Id: 10143375 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3CA586063B for ; Wed, 3 Jan 2018 20:41:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 33007291A7 for ; Wed, 3 Jan 2018 20:41:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 27FC92931B; Wed, 3 Jan 2018 20:41:32 +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=-4.2 required=2.0 tests=BAYES_00, 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 885D5291A7 for ; Wed, 3 Jan 2018 20:41:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 07541891B3; Wed, 3 Jan 2018 20:41:29 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by gabe.freedesktop.org (Postfix) with ESMTPS id E5FEF8919B for ; Wed, 3 Jan 2018 20:41:27 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 03 Jan 2018 12:41:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,503,1508828400"; d="scan'208";a="16568746" Received: from dk-thinkpad-x260.jf.intel.com (HELO localhost.localdomain) ([10.54.75.38]) by FMSMGA003.fm.intel.com with ESMTP; 03 Jan 2018 12:41:27 -0800 From: Dhinakaran Pandiyan To: intel-gfx@lists.freedesktop.org Date: Wed, 3 Jan 2018 12:39:58 -0800 Message-Id: <20180103204001.3008-2-dhinakaran.pandiyan@intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180103204001.3008-1-dhinakaran.pandiyan@intel.com> References: <20180103204001.3008-1-dhinakaran.pandiyan@intel.com> MIME-Version: 1.0 Cc: Daniel Vetter , Dhinakaran Pandiyan , Rodrigo Vivi Subject: [Intel-gfx] [PATCH 2/5] drm/vblank: Restoring vblank counts after device runtime PM events. X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP The HW frame counter can get reset when devices enters low power states and this messes up any following vblank count updates. So, compute the missed vblank interrupts for that low power state duration using time stamps. This is similar to _crtc_vblank_on() except that it doesn't enable vblank interrupts because this function is expected to be called from the driver _enable_vblank() vfunc. Cc: Daniel Vetter Cc: Ville Syrjälä Cc: Rodrigo Vivi Signed-off-by: Dhinakaran Pandiyan --- drivers/gpu/drm/drm_vblank.c | 33 +++++++++++++++++++++++++++++++++ include/drm/drm_vblank.h | 1 + 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 7eee82c06ed8..494e2cff6e55 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -1230,6 +1230,39 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc) } EXPORT_SYMBOL(drm_crtc_vblank_on); +void drm_crtc_vblank_restore(struct drm_device *dev, unsigned int pipe) +{ + ktime_t t_vblank; + struct drm_vblank_crtc *vblank; + int framedur_ns; + u64 diff_ns; + u32 cur_vblank, diff = 1; + int count = DRM_TIMESTAMP_MAXRETRIES; + + if (WARN_ON(pipe >= dev->num_crtcs)) + return; + + vblank = &dev->vblank[pipe]; + WARN_ONCE((drm_debug & DRM_UT_VBL) && !vblank->framedur_ns, + "Cannot compute missed vblanks without frame duration\n"); + framedur_ns = vblank->framedur_ns; + + do { + cur_vblank = __get_vblank_counter(dev, pipe); + drm_get_last_vbltimestamp(dev, pipe, &t_vblank, false); + } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0); + + diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time)); + if (framedur_ns) + diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns); + + + DRM_DEBUG_VBL("missed %d vblanks in %lld ns, frame duration=%d ns, hw_diff=%d\n", + diff, diff_ns, framedur_ns, cur_vblank - vblank->last); + store_vblank(dev, pipe, diff, t_vblank, cur_vblank); +} +EXPORT_SYMBOL(drm_crtc_vblank_restore); + static void drm_legacy_vblank_pre_modeset(struct drm_device *dev, unsigned int pipe) { diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h index 848b463a0af5..aafcbef91bd7 100644 --- a/include/drm/drm_vblank.h +++ b/include/drm/drm_vblank.h @@ -180,6 +180,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc); void drm_crtc_vblank_reset(struct drm_crtc *crtc); void drm_crtc_vblank_on(struct drm_crtc *crtc); u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc); +void drm_crtc_vblank_restore(struct drm_device *dev, unsigned int pipe); bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, unsigned int pipe, int *max_error,