All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>,
	Rodrigo Vivi <rodrigo.vivi@intel.com>,
	dri-devel@lists.freedesktop.org,
	Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Subject: [RFC PATCH] drm/vblanks: Deal with HW vblank counter resets.
Date: Mon,  6 Nov 2017 22:26:17 -0800	[thread overview]
Message-ID: <20171107062617.4227-1-dhinakaran.pandiyan@intel.com> (raw)

Some HW vblank counters reset due to power management events, which messes
up the vblank counting logic. This leads to screen freezes with user space
waiting on vblank events that may not occur if the counter keeps resetting.

For e.g., After the HW vblank counter resets
[    9.007359] [drm:drm_update_vblank_count [drm]] updating vblank count
on crtc 0: current=297, diff=4294965389, hw=5 hw_last=1912

So, fall back to the SW counter, computed using  vblank timestamps
and frame duration, when the HW counter value deviates by 50% of the SW
computed value.

I have tested this patch on my SKL laptop with i915.enable_psr=1 and it
*seems* to solve the screen freeze issue seen with PSR when DMC is loaded.

Known issues:
1) The 50% deviation margin is arbitrary.
2) "Redundant vblirq ignored" messages are more frequent.

I am sending this as an RFC to get feedback on whether the fall back
approach is sane and if it should be implemented in the core.

Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
---
 drivers/gpu/drm/drm_vblank.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 57cc6e37c810..8000aae5f1f7 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -190,11 +190,12 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
 				    bool in_vblank_irq)
 {
 	struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
-	u32 cur_vblank, diff;
+	u32 cur_vblank;
 	bool rc;
 	ktime_t t_vblank;
 	int count = DRM_TIMESTAMP_MAXRETRIES;
 	int framedur_ns = vblank->framedur_ns;
+	u32 diff = in_vblank_irq ? 1 : 0;
 
 	/*
 	 * Interrupts were disabled prior to this call, so deal with counter
@@ -213,26 +214,31 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
 		rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, in_vblank_irq);
 	} while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
 
-	if (dev->max_vblank_count != 0) {
-		/* trust the hw counter when it's around */
+	if (dev->max_vblank_count)
 		diff = (cur_vblank - vblank->last) & dev->max_vblank_count;
-	} else if (rc && framedur_ns) {
+
+	if (rc && framedur_ns) {
 		u64 diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
+		u32 sw_diff;
 
 		/*
 		 * Figure out how many vblanks we've missed based
 		 * on the difference in the timestamps and the
 		 * frame/field duration.
 		 */
-		diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
-
-		if (diff == 0 && in_vblank_irq)
+		sw_diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
+		if (sw_diff == 0 && in_vblank_irq)
 			DRM_DEBUG_VBL("crtc %u: Redundant vblirq ignored."
 				      " diff_ns = %lld, framedur_ns = %d)\n",
 				      pipe, (long long) diff_ns, framedur_ns);
-	} else {
-		/* some kind of default for drivers w/o accurate vbl timestamping */
-		diff = in_vblank_irq ? 1 : 0;
+
+		if (!dev->max_vblank_count)
+			diff = sw_diff;
+		else if (sw_diff && abs(diff - sw_diff) > DIV_ROUND_CLOSEST(sw_diff, 2)) {
+			DRM_DEBUG_VBL("hw vblank counter(%u) deviates from sw (%u)\n",
+				      diff, sw_diff);
+			diff = sw_diff;
+		}
 	}
 
 	/*
-- 
2.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

             reply	other threads:[~2017-11-07  6:26 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-07  6:26 Dhinakaran Pandiyan [this message]
2017-11-07  9:07 ` ✗ Fi.CI.BAT: failure for drm/vblanks: Deal with HW vblank counter resets Patchwork
2017-11-07  9:47 ` [RFC PATCH] " Michel Dänzer
2017-11-07 10:50   ` Ville Syrjälä
2017-11-07 10:55     ` Michel Dänzer
2017-11-07 11:26       ` Ville Syrjälä
2017-11-07 12:39   ` Daniel Vetter
2017-11-07 19:14     ` Pandiyan, Dhinakaran
2017-11-08 12:29 ` ✓ Fi.CI.BAT: success for " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171107062617.4227-1-dhinakaran.pandiyan@intel.com \
    --to=dhinakaran.pandiyan@intel.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=rodrigo.vivi@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.