[Intel-gfx] [PATCH 1/3] drm/i915: Skip register reads in i915_get_crtc_scanoutpos()

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Mon Sep 23 12:02:05 CEST 2013


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

We have all the information we need in the mode structure, so going and
reading it from the hardware is pointless, and slower.

For the !kms case, leave the register reads in place.

Cc: Mario Kleiner <mario.kleiner at tuebingen.mpg.de>
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 51 +++++++++++++++++++++++++----------------
 1 file changed, 31 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b356dc1..697d62c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -571,12 +571,10 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
 			     int *vpos, int *hpos)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-	u32 vbl = 0, position = 0;
+	u32 position;
 	int vbl_start, vbl_end, htotal, vtotal;
 	bool in_vbl = true;
 	int ret = 0;
-	enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
-								      pipe);
 
 	if (!i915_pipe_enabled(dev, pipe)) {
 		DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled "
@@ -584,10 +582,36 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
 		return 0;
 	}
 
-	/* Get vtotal. */
-	vtotal = 1 + ((I915_READ(VTOTAL(cpu_transcoder)) >> 16) & 0x1fff);
+	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+		struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+		const struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode;
 
-	if (INTEL_INFO(dev)->gen >= 4) {
+		htotal = mode->crtc_htotal;
+		vtotal = mode->crtc_vtotal;
+		vbl_start = mode->crtc_vblank_start;
+		vbl_end = mode->crtc_vblank_end;
+
+		ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
+	} else {
+		enum transcoder cpu_transcoder =
+			intel_pipe_to_cpu_transcoder(dev_priv, pipe);
+		u32 vbl;
+
+		htotal = 1 + ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff);
+		vtotal = 1 + ((I915_READ(VTOTAL(cpu_transcoder)) >> 16) & 0x1fff);
+
+		vbl = I915_READ(VBLANK(cpu_transcoder));
+
+		vbl_start = 1 + (vbl & 0x1fff);
+		vbl_end = 1 + ((vbl >> 16) & 0x1fff);
+
+		/* Readouts valid? */
+		if (vbl > 0)
+			ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
+	}
+
+	if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
 		/* No obvious pixelcount register. Only query vertical
 		 * scanout position from Display scan line register.
 		 */
@@ -605,29 +629,16 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
 		 */
 		position = (I915_READ(PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT;
 
-		htotal = 1 + ((I915_READ(HTOTAL(cpu_transcoder)) >> 16) & 0x1fff);
 		*vpos = position / htotal;
 		*hpos = position - (*vpos * htotal);
 	}
 
-	/* Query vblank area. */
-	vbl = I915_READ(VBLANK(cpu_transcoder));
-
-	/* Test position against vblank region. */
-	vbl_start = vbl & 0x1fff;
-	vbl_end = (vbl >> 16) & 0x1fff;
-
-	if ((*vpos < vbl_start) || (*vpos > vbl_end))
-		in_vbl = false;
+	in_vbl = *vpos >= vbl_start && *vpos < vbl_end;
 
 	/* Inside "upper part" of vblank area? Apply corrective offset: */
 	if (in_vbl && (*vpos >= vbl_start))
 		*vpos = *vpos - vtotal;
 
-	/* Readouts valid? */
-	if (vbl > 0)
-		ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE;
-
 	/* In vblank? */
 	if (in_vbl)
 		ret |= DRM_SCANOUTPOS_INVBL;
-- 
1.8.1.5




More information about the Intel-gfx mailing list