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

Commit 72618ebf authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/i915: Use fb modifiers for display tiling decisions



Soon the fence tiling mode may not always match the fb modifier
even for X tiled buffers. So let's use the fb modifier
consistently for all display tiling decisions.

v2: Rebased due to s/ring/engine/
v3: Rebased due to s/engine/ring/ O_o
v4: Rebase due to i915_gem_object_get_tiling() & co.

Reviewed-by: Matthew Auld <matthew.auld@intel.com> (v1)
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470821001-25272-6-git-send-email-ville.syrjala@linux.intel.com
parent 2949056c
Loading
Loading
Loading
Loading
+23 −12
Original line number Diff line number Diff line
@@ -2436,6 +2436,18 @@ static void intel_fb_offset_to_xy(int *x, int *y,
	*x = linear_offset % pitch / cpp;
}

static unsigned int intel_fb_modifier_to_tiling(uint64_t fb_modifier)
{
	switch (fb_modifier) {
	case I915_FORMAT_MOD_X_TILED:
		return I915_TILING_X;
	case I915_FORMAT_MOD_Y_TILED:
		return I915_TILING_Y;
	default:
		return I915_TILING_NONE;
	}
}

static int
intel_fill_fb_info(struct drm_i915_private *dev_priv,
		   struct drm_framebuffer *fb)
@@ -2834,7 +2846,8 @@ static void i9xx_update_primary_plane(struct drm_plane *primary,
		BUG();
	}

	if (INTEL_INFO(dev)->gen >= 4 && i915_gem_object_is_tiled(obj))
	if (INTEL_GEN(dev_priv) >= 4 &&
	    fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
		dspcntr |= DISPPLANE_TILED;

	if (IS_G4X(dev))
@@ -2899,7 +2912,6 @@ static void ironlake_update_primary_plane(struct drm_plane *primary,
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
	struct drm_framebuffer *fb = plane_state->base.fb;
	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
	int plane = intel_crtc->plane;
	u32 linear_offset;
	u32 dspcntr;
@@ -2937,7 +2949,7 @@ static void ironlake_update_primary_plane(struct drm_plane *primary,
		BUG();
	}

	if (i915_gem_object_is_tiled(obj))
	if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
		dspcntr |= DISPPLANE_TILED;

	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
@@ -11444,7 +11456,7 @@ static int intel_gen4_queue_flip(struct drm_device *dev,
			MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
	intel_ring_emit(ring, fb->pitches[0]);
	intel_ring_emit(ring, intel_crtc->flip_work->gtt_offset |
			i915_gem_object_get_tiling(obj));
			intel_fb_modifier_to_tiling(fb->modifier[0]));

	/* XXX Enabling the panel-fitter across page-flip is so far
	 * untested on non-native modes, so ignore it for now.
@@ -11476,7 +11488,8 @@ static int intel_gen6_queue_flip(struct drm_device *dev,

	intel_ring_emit(ring, MI_DISPLAY_FLIP |
			MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
	intel_ring_emit(ring, fb->pitches[0] | i915_gem_object_get_tiling(obj));
	intel_ring_emit(ring, fb->pitches[0] |
			intel_fb_modifier_to_tiling(fb->modifier[0]));
	intel_ring_emit(ring, intel_crtc->flip_work->gtt_offset);

	/* Contrary to the suggestions in the documentation,
@@ -11579,7 +11592,8 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
	}

	intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
	intel_ring_emit(ring, fb->pitches[0] | i915_gem_object_get_tiling(obj));
	intel_ring_emit(ring, fb->pitches[0] |
			intel_fb_modifier_to_tiling(fb->modifier[0]));
	intel_ring_emit(ring, intel_crtc->flip_work->gtt_offset);
	intel_ring_emit(ring, (MI_NOOP));

@@ -11664,15 +11678,13 @@ static void ilk_do_mmio_flip(struct intel_crtc *intel_crtc,
{
	struct drm_device *dev = intel_crtc->base.dev;
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct intel_framebuffer *intel_fb =
		to_intel_framebuffer(intel_crtc->base.primary->fb);
	struct drm_i915_gem_object *obj = intel_fb->obj;
	struct drm_framebuffer *fb = intel_crtc->base.primary->fb;
	i915_reg_t reg = DSPCNTR(intel_crtc->plane);
	u32 dspcntr;

	dspcntr = I915_READ(reg);

	if (i915_gem_object_is_tiled(obj))
	if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
		dspcntr |= DISPPLANE_TILED;
	else
		dspcntr &= ~DISPPLANE_TILED;
@@ -11900,8 +11912,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,

	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
		engine = &dev_priv->engine[BCS];
		if (i915_gem_object_get_tiling(obj) !=
		    i915_gem_object_get_tiling(intel_fb_obj(work->old_fb)))
		if (fb->modifier[0] != old_fb->modifier[0])
			/* vlv: DISPLAY_FLIP fails to change tiling */
			engine = NULL;
	} else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) {
+6 −9
Original line number Diff line number Diff line
@@ -360,7 +360,6 @@ vlv_update_plane(struct drm_plane *dplane,
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct intel_plane *intel_plane = to_intel_plane(dplane);
	struct drm_framebuffer *fb = plane_state->base.fb;
	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
	int pipe = intel_plane->pipe;
	int plane = intel_plane->plane;
	u32 sprctl;
@@ -427,7 +426,7 @@ vlv_update_plane(struct drm_plane *dplane,
	 */
	sprctl |= SP_GAMMA_ENABLE;

	if (i915_gem_object_is_tiled(obj))
	if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
		sprctl |= SP_TILED;

	/* Sizes are 0 based */
@@ -463,7 +462,7 @@ vlv_update_plane(struct drm_plane *dplane,
	I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
	I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);

	if (i915_gem_object_is_tiled(obj))
	if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
		I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
	else
		I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
@@ -501,7 +500,6 @@ ivb_update_plane(struct drm_plane *plane,
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct intel_plane *intel_plane = to_intel_plane(plane);
	struct drm_framebuffer *fb = plane_state->base.fb;
	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
	enum pipe pipe = intel_plane->pipe;
	u32 sprctl, sprscale = 0;
	u32 sprsurf_offset, linear_offset;
@@ -547,7 +545,7 @@ ivb_update_plane(struct drm_plane *plane,
	 */
	sprctl |= SPRITE_GAMMA_ENABLE;

	if (i915_gem_object_is_tiled(obj))
	if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
		sprctl |= SPRITE_TILED;

	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
@@ -600,7 +598,7 @@ ivb_update_plane(struct drm_plane *plane,
	 * register */
	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
		I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
	else if (i915_gem_object_is_tiled(obj))
	else if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
		I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
	else
		I915_WRITE(SPRLINOFF(pipe), linear_offset);
@@ -640,7 +638,6 @@ ilk_update_plane(struct drm_plane *plane,
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct intel_plane *intel_plane = to_intel_plane(plane);
	struct drm_framebuffer *fb = plane_state->base.fb;
	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
	int pipe = intel_plane->pipe;
	u32 dvscntr, dvsscale;
	u32 dvssurf_offset, linear_offset;
@@ -686,7 +683,7 @@ ilk_update_plane(struct drm_plane *plane,
	 */
	dvscntr |= DVS_GAMMA_ENABLE;

	if (i915_gem_object_is_tiled(obj))
	if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
		dvscntr |= DVS_TILED;

	if (IS_GEN6(dev))
@@ -728,7 +725,7 @@ ilk_update_plane(struct drm_plane *plane,
	I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
	I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);

	if (i915_gem_object_is_tiled(obj))
	if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
		I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
	else
		I915_WRITE(DVSLINOFF(pipe), linear_offset);