| From 15ea6096dea84393e5346a7355ef4aa1a3dc2468 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> |
| Date: Mon, 23 Sep 2013 14:48:50 +0300 |
| Subject: drm/i915: Skip register reads in i915_get_crtc_scanoutpos() |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| We have all the information we need in the mode structure, so going and |
| reading it from the hardware is pointless, and slower. |
| |
| We never populated ->get_vblank_timestamp() in the UMS case, and as that |
| is the only way we'd ever call ->get_scanout_position(), we can |
| completely ignore UMS in i915_get_crtc_scanoutpos(). |
| |
| Also reorganize intel_irq_init() a bit to clarify the KMS vs. UMS |
| situation. |
| |
| v2: Drop UMS code |
| |
| Cc: Mario Kleiner <mario.kleiner@tuebingen.mpg.de> |
| Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Reviewed-by: mario.kleiner.de@gmail.com |
| Tested-by: mario.kleiner.de@gmail.com |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| (cherry picked from commit c2baf4b7097cb66e7ee3c2fa0f585d386dab6300) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/i915/i915_irq.c | 43 ++++++++++++++++------------------------- |
| 1 file changed, 17 insertions(+), 26 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c |
| index 1f91e1a8bfd1..cc35d52f0166 100644 |
| --- a/drivers/gpu/drm/i915/i915_irq.c |
| +++ b/drivers/gpu/drm/i915/i915_irq.c |
| @@ -595,24 +595,29 @@ static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) |
| 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; |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + 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; |
| + 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)) { |
| + if (!intel_crtc->active) { |
| DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " |
| "pipe %c\n", pipe_name(pipe)); |
| return 0; |
| } |
| |
| - /* Get vtotal. */ |
| - vtotal = 1 + ((I915_READ(VTOTAL(cpu_transcoder)) >> 16) & 0x1fff); |
| + htotal = mode->crtc_htotal; |
| + vtotal = mode->crtc_vtotal; |
| + vbl_start = mode->crtc_vblank_start; |
| + vbl_end = mode->crtc_vblank_end; |
| |
| - if (INTEL_INFO(dev)->gen >= 4) { |
| + 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. |
| */ |
| @@ -630,29 +635,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; |
| @@ -3188,11 +3180,10 @@ void intel_irq_init(struct drm_device *dev) |
| dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
| } |
| |
| - if (drm_core_check_feature(dev, DRIVER_MODESET)) |
| + if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
| dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; |
| - else |
| - dev->driver->get_vblank_timestamp = NULL; |
| - dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; |
| + dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; |
| + } |
| |
| if (IS_VALLEYVIEW(dev)) { |
| dev->driver->irq_handler = valleyview_irq_handler; |
| -- |
| 1.8.5.rc3 |
| |