Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2baf4b7 authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter
Browse files

drm/i915: Skip register reads in i915_get_crtc_scanoutpos()



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: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatar <mario.kleiner.de@gmail.com>
Tested-by: default avatar <mario.kleiner.de@gmail.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent f646628b
Loading
Loading
Loading
Loading
+17 −26
Original line number Diff line number Diff line
@@ -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;
	}

	if (IS_VALLEYVIEW(dev)) {
		dev->driver->irq_handler = valleyview_irq_handler;