From patchwork Tue Dec 19 05:26:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dhinakaran Pandiyan X-Patchwork-Id: 10122279 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 9501E6019C for ; Tue, 19 Dec 2017 05:28:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 86D6628C09 for ; Tue, 19 Dec 2017 05:28:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7B9E928C40; Tue, 19 Dec 2017 05:28:06 +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=unavailable 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 41B3828C09 for ; Tue, 19 Dec 2017 05:28:06 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 27EB589E7C; Tue, 19 Dec 2017 05:27:49 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7EA1289AA7; Tue, 19 Dec 2017 05:27:44 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Dec 2017 21:27:42 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,425,1508828400"; d="scan'208";a="3514465" Received: from dk-thinkpad-x260.jf.intel.com (HELO localhost.localdomain) ([10.54.75.18]) by fmsmga007.fm.intel.com with ESMTP; 18 Dec 2017 21:27:24 -0800 From: Dhinakaran Pandiyan To: intel-gfx@lists.freedesktop.org Date: Mon, 18 Dec 2017 21:26:56 -0800 Message-Id: <20171219052659.2355-6-dhinakaran.pandiyan@intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20171219052659.2355-1-dhinakaran.pandiyan@intel.com> References: <20171219052659.2355-1-dhinakaran.pandiyan@intel.com> MIME-Version: 1.0 Cc: Daniel Vetter , Dhinakaran Pandiyan , dri-devel@lists.freedesktop.org, Rodrigo Vivi Subject: [Intel-gfx] [PATCH v2 5/8] 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,