From patchwork Wed Aug 3 21:33:38 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodrigo Vivi X-Patchwork-Id: 9262227 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 1FD966048B for ; Wed, 3 Aug 2016 21:34:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 155E51FE95 for ; Wed, 3 Aug 2016 21:34:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0A4C4280CF; Wed, 3 Aug 2016 21:34:52 +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]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 93BDC1FE95 for ; Wed, 3 Aug 2016 21:34:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 335FC6E900; Wed, 3 Aug 2016 21:34:24 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id 0FB726E8EB; Wed, 3 Aug 2016 21:34:10 +0000 (UTC) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga101.fm.intel.com with ESMTP; 03 Aug 2016 14:34:09 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,467,1464678000"; d="scan'208";a="859262350" Received: from rdvivi-dublin.jf.intel.com ([10.7.196.152]) by orsmga003.jf.intel.com with ESMTP; 03 Aug 2016 14:34:08 -0700 From: Rodrigo Vivi To: intel-gfx@lists.freedesktop.org Subject: [PATCH 5/6] drm: Introduce drm_crtc_vblank_sanitize_counter. Date: Wed, 3 Aug 2016 14:33:38 -0700 Message-Id: <1470260019-6173-6-git-send-email-rodrigo.vivi@intel.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1470260019-6173-1-git-send-email-rodrigo.vivi@intel.com> References: <1470260019-6173-1-git-send-email-rodrigo.vivi@intel.com> Cc: dri-devel@lists.freedesktop.org, Rodrigo Vivi 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: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP In modern systems there are situations that you can let the screen enabled and sleep or shut off a most of the display controler. In situations like this the vblank hw counter can be reset. When this happens everything in the system gets crazy by the big count. So, the right approach is to make sure we are avoiding any runtime suspend when vblank is enabled but also restore drm crtc vblank counter to a state we can rely. Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/drm_irq.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_irq.h | 1 + 2 files changed, 47 insertions(+) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index d0d1dde..7320836 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -265,6 +265,52 @@ u32 drm_accurate_vblank_count(struct drm_crtc *crtc) } EXPORT_SYMBOL(drm_accurate_vblank_count); +/** + * drm_crtc_vblank_sanitize_counter - Sanitize vblank counter + * @crtc: which counter to sanitize + * + * This function returns drm crtc vblank counter to the latest + * known counter. + * + * This function is useful for runtime suspend where the hw + * counter or timer might reset. + * + * Use this only when there is no risk of the runtime suspend + * reseting hardware counter and before enabling vblank irq. + */ +void drm_crtc_vblank_sanitize_counter(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + unsigned int pipe = drm_crtc_index(crtc); + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; + unsigned long irqflags; + struct timeval t_vblank; + int count = DRM_TIMESTAMP_MAXRETRIES; + u32 cur_vblank; + bool rc; + + spin_lock_irqsave(&dev->vblank_time_lock, irqflags); + + if (vblank->enabled) { + DRM_DEBUG_VBL("Skip sanitize - Vblank is enabled on pipe %d\n", + pipe); + goto unlock; + } + + do { + cur_vblank = dev->driver->get_vblank_counter(dev, pipe); + rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, 0); + } while (cur_vblank != dev->driver->get_vblank_counter(dev, pipe) && --count > 0); + + if (!rc) + t_vblank = (struct timeval) {0, 0}; + + store_vblank(dev, pipe, 0, &t_vblank, cur_vblank); +unlock: + spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); +} +EXPORT_SYMBOL(drm_crtc_vblank_sanitize_counter); + /* * Disable vblank irq's on crtc, make sure that last vblank count * of hardware and corresponding consistent software vblank counter diff --git a/include/drm/drm_irq.h b/include/drm/drm_irq.h index 93a9e9d..55c419a 100644 --- a/include/drm/drm_irq.h +++ b/include/drm/drm_irq.h @@ -160,6 +160,7 @@ extern u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe); extern u32 drm_crtc_vblank_count(struct drm_crtc *crtc); extern u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc, struct timeval *vblanktime); +extern void drm_crtc_vblank_sanitize_counter(struct drm_crtc *crtc); extern void drm_crtc_send_vblank_event(struct drm_crtc *crtc, struct drm_pending_vblank_event *e); extern void drm_crtc_arm_vblank_event(struct drm_crtc *crtc,