Commit 195b7a0d authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/i915: Introduce the plane->min_alignment() vfunc



Different hardware generations have different scanout alignment
requirements. Introduce a new vfunc that will allow us to
make that distinction without horrible if-ladders.

For now we directly plug in the existing intel_surf_alignment()
and intel_cursor_alignment() functions.

For fbdev we (temporarily) introduce intel_fbdev_min_alignment()
that simply queries the alignment from the primary plane of
the first crtc.

TODO: someone will need to fix xe's alignment handling

Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240612204712.31404-4-ville.syrjala@linux.intel.com


Acked-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent 1c5f18d8
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -225,8 +225,8 @@ static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,

int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
{
	struct drm_i915_private *dev_priv =
		to_i915(plane_state->uapi.plane->dev);
	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
	const struct drm_framebuffer *fb = plane_state->hw.fb;
	int src_x, src_y, src_w;
	u32 offset;
@@ -267,7 +267,7 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
	 * despite them not using the linear offset anymore.
	 */
	if (DISPLAY_VER(dev_priv) >= 4 && fb->modifier == I915_FORMAT_MOD_X_TILED) {
		unsigned int alignment = intel_surf_alignment(fb, 0);
		unsigned int alignment = plane->min_alignment(plane, fb, 0);
		int cpp = fb->format->cpp[0];

		while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].mapping_stride) {
@@ -869,6 +869,8 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
			plane->max_stride = ilk_primary_max_stride;
	}

	plane->min_alignment = intel_surf_alignment;

	if (IS_I830(dev_priv) || IS_I845G(dev_priv)) {
		plane->update_arm = i830_plane_update_arm;
	} else {
+2 −0
Original line number Diff line number Diff line
@@ -954,6 +954,8 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
		cursor->check_plane = i9xx_check_cursor;
	}

	cursor->min_alignment = intel_cursor_alignment;

	cursor->cursor.base = ~0;
	cursor->cursor.cntl = ~0;

+3 −0
Original line number Diff line number Diff line
@@ -1566,6 +1566,9 @@ struct intel_plane {
	int (*max_height)(const struct drm_framebuffer *fb,
			  int color_plane,
			  unsigned int rotation);
	unsigned int (*min_alignment)(struct intel_plane *plane,
				      const struct drm_framebuffer *fb,
				      int color_plane);
	unsigned int (*max_stride)(struct intel_plane *plane,
				   u32 pixel_format, u64 modifier,
				   unsigned int rotation);
+11 −11
Original line number Diff line number Diff line
@@ -776,8 +776,12 @@ bool intel_fb_uses_dpt(const struct drm_framebuffer *fb)
		intel_fb_modifier_uses_dpt(to_i915(fb->dev), fb->modifier);
}

unsigned int intel_cursor_alignment(const struct drm_i915_private *i915)
unsigned int intel_cursor_alignment(struct intel_plane *plane,
				    const struct drm_framebuffer *fb,
				    int color_plane)
{
	struct drm_i915_private *i915 = to_i915(plane->base.dev);

	if (IS_I830(i915))
		return 16 * 1024;
	else if (IS_I85X(i915))
@@ -801,10 +805,11 @@ static unsigned int intel_linear_alignment(const struct drm_i915_private *dev_pr
		return 0;
}

unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
unsigned int intel_surf_alignment(struct intel_plane *plane,
				  const struct drm_framebuffer *fb,
				  int color_plane)
{
	struct drm_i915_private *dev_priv = to_i915(fb->dev);
	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);

	if (intel_fb_uses_dpt(fb)) {
		/* AUX_DIST needs only 4K alignment */
@@ -1099,17 +1104,12 @@ u32 intel_plane_compute_aligned_offset(int *x, int *y,
				       const struct intel_plane_state *state,
				       int color_plane)
{
	struct intel_plane *intel_plane = to_intel_plane(state->uapi.plane);
	struct drm_i915_private *i915 = to_i915(intel_plane->base.dev);
	struct intel_plane *plane = to_intel_plane(state->uapi.plane);
	struct drm_i915_private *i915 = to_i915(plane->base.dev);
	const struct drm_framebuffer *fb = state->hw.fb;
	unsigned int rotation = state->hw.rotation;
	unsigned int pitch = state->view.color_plane[color_plane].mapping_stride;
	unsigned int alignment;

	if (intel_plane->id == PLANE_CURSOR)
		alignment = intel_cursor_alignment(i915);
	else
		alignment = intel_surf_alignment(fb, color_plane);
	unsigned int alignment = plane->min_alignment(plane, fb, color_plane);

	return intel_compute_aligned_offset(i915, x, y, fb, color_plane,
					    pitch, rotation, alignment);
+5 −2
Original line number Diff line number Diff line
@@ -60,8 +60,11 @@ unsigned int intel_tile_height(const struct drm_framebuffer *fb, int color_plane
unsigned int intel_tile_row_size(const struct drm_framebuffer *fb, int color_plane);
unsigned int intel_fb_align_height(const struct drm_framebuffer *fb,
				   int color_plane, unsigned int height);
unsigned int intel_cursor_alignment(const struct drm_i915_private *i915);
unsigned int intel_surf_alignment(const struct drm_framebuffer *fb,
unsigned int intel_cursor_alignment(struct intel_plane *plane,
				    const struct drm_framebuffer *fb,
				    int color_plane);
unsigned int intel_surf_alignment(struct intel_plane *plane,
				  const struct drm_framebuffer *fb,
				  int color_plane);

void intel_fb_plane_get_subsampling(int *hsub, int *vsub,
Loading