All of lore.kernel.org
 help / color / mirror / Atom feed
From: Radhakrishna Sripada <radhakrishna.sripada@intel.com>
To: intel-gfx@lists.freedesktop.org
Cc: nanley.g.chery@intel.com,
	Lucas De Marchi <lucas.demarchi@intel.com>,
	dhinakaran.pandiyan@intel.com, ville.syrjala@intel.com
Subject: [PATCH v4 08/10] Gen-12 display can decompress surfaces compressed by the media engine.
Date: Mon, 14 Oct 2019 17:05:31 -0700	[thread overview]
Message-ID: <20191015000533.11425-9-radhakrishna.sripada@intel.com> (raw)
In-Reply-To: <20191015000533.11425-1-radhakrishna.sripada@intel.com>

From: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>

Detect the modifier corresponding to media compression to enable
display decompression for YUV and xRGB packed formats. A new modifier is
added so that the driver can distinguish between media and render
compressed buffers. Unlike render decompression, plane 6 and  plane 7 do not
support media decompression.

v2: Fix checkpatch warnings on code style (Lucas)

From DK:
Separate modifier array for planes that cannot decompress media (Ville)

v3: Support planar formats

Cc: Nanley G Chery <nanley.g.chery@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/display/intel_display.c  | 237 +++++++++++++-----
 .../drm/i915/display/intel_display_types.h    |   2 +-
 drivers/gpu/drm/i915/display/intel_sprite.c   |  44 +++-
 drivers/gpu/drm/i915/i915_reg.h               |   1 +
 4 files changed, 220 insertions(+), 64 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index be61dfdebb34..448168a4d780 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -1909,6 +1909,10 @@ intel_tile_width_bytes(const struct drm_framebuffer *fb, int color_plane)
 		if (color_plane == 1)
 			return 128;
 		/* fall through */
+	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
+		if (color_plane == 3)
+			return 64;
+		/* fall through */
 	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
 		if (color_plane == 1)
 			return 64;
@@ -2251,8 +2255,16 @@ static u32 intel_adjust_tile_offset(int *x, int *y,
 
 static bool is_surface_linear(u64 modifier, int color_plane)
 {
-	return modifier == DRM_FORMAT_MOD_LINEAR ||
-	       (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS && color_plane == 1);
+	switch (modifier) {
+	case DRM_FORMAT_MOD_LINEAR:
+		return true;
+	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
+		return color_plane == 1;
+	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
+		return color_plane == 1 || color_plane == 3;
+	default:
+		return false;
+	}
 }
 
 static u32 intel_adjust_aligned_offset(int *x, int *y,
@@ -2440,6 +2452,7 @@ static unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier)
 	case I915_FORMAT_MOD_Y_TILED:
 	case I915_FORMAT_MOD_Y_TILED_CCS:
 	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
+	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
 		return I915_TILING_Y;
 	default:
 		return I915_TILING_NONE;
@@ -2487,6 +2500,10 @@ static const struct drm_format_info gen12_ccs_formats[] = {
 	  .cpp = { 4, 1, }, .hsub = 2, .vsub = 32, .has_alpha = true },
 	{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
 	  .cpp = { 4, 1, }, .hsub = 2, .vsub = 32, .has_alpha = true },
+	{ .format = DRM_FORMAT_YUYV, .num_planes = 2,
+	  .cpp = { 2, 1, }, .hsub = 4, .vsub = 32, .is_yuv = true },
+	{ .format = DRM_FORMAT_NV12, .num_planes = 4,
+	  .cpp = { 1, 1, 2, 1}, .hsub = 2, .vsub = 2, .is_yuv = true },
 };
 
 static const struct drm_format_info *
@@ -2524,6 +2541,7 @@ intel_get_format_info(const struct drm_mode_fb_cmd2 *cmd)
 bool is_ccs_modifier(u64 modifier)
 {
 	return modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
+	       modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS ||
 	       modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
 	       modifier == I915_FORMAT_MOD_Yf_TILED_CCS;
 }
@@ -2587,7 +2605,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
 	}
 
 	tile_width = intel_tile_width_bytes(fb, color_plane);
-	if (is_ccs_modifier(fb->modifier) && color_plane == 0) {
+	if (is_ccs_modifier(fb->modifier)) {
 		/*
 		 * Display WA #0531: skl,bxt,kbl,glk
 		 *
@@ -2597,7 +2615,7 @@ intel_fb_stride_alignment(const struct drm_framebuffer *fb, int color_plane)
 		 * require the entire fb to accommodate that to avoid
 		 * potential runtime errors at plane configuration time.
 		 */
-		if (IS_GEN(dev_priv, 9) && fb->width > 3840)
+		if (IS_GEN(dev_priv, 9) && color_plane == 0 && fb->width > 3840)
 			tile_width *= 4;
 		/*
 		 * The main surface pitch must be padded to a multiple of four
@@ -2677,25 +2695,71 @@ static bool intel_plane_needs_remap(const struct intel_plane_state *plane_state)
 	return stride > max_stride;
 }
 
+static void
+intel_fb_plane_get_subsampling(int *hsub, int *vsub, const struct drm_framebuffer *fb, int color_plane)
+{
+	if (fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS) {
+		static const struct {
+			int cpp[4];
+			int vsub[4];
+			int hsub[4];
+		} mc_ccs_subsampling = {.cpp = {1, 1, 2, 1}, .hsub = {1, 8, 2, 16}, .vsub = {1, 32, 2, 32} };
+
+		*hsub = mc_ccs_subsampling.hsub[color_plane];
+		*vsub = mc_ccs_subsampling.vsub[color_plane];
+	} else {
+		*hsub = fb->format->hsub;
+		*vsub = fb->format->vsub;
+	}
+}
+
+static void
+intel_fb_plane_dims(int *w, int *h, struct drm_framebuffer *fb, int color_plane)
+{
+	int hsub, vsub;
+
+	intel_fb_plane_get_subsampling(&hsub, &vsub, fb, color_plane);
+	*w = fb->width / hsub;
+	*h = fb->height / vsub;
+}
+
+static bool is_ccs_plane(u64 modifier, int color_plane)
+{
+	if (!is_ccs_modifier(modifier))
+		return false;
+	else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)
+		return color_plane == 3 || color_plane == 1;
+	else
+		return color_plane == 1;
+}
+
 static int
-intel_fb_check_ccs_xy(struct drm_framebuffer *fb, int x, int y)
+intel_fb_check_ccs_xy(struct drm_framebuffer *fb, int color_plane, int x, int y)
 {
 	struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
-	int hsub = fb->format->hsub;
-	int vsub = fb->format->vsub;
+	int hsub, vsub;
+	int hsub_main, vsub_main;
 	int tile_width, tile_height;
 	int ccs_x, ccs_y;
 	int main_x, main_y;
 
-	intel_tile_dims(fb, 1, &tile_width, &tile_height);
+	if (!is_ccs_plane(fb->modifier, color_plane))
+		return 0;
+
+	intel_tile_dims(fb, color_plane, &tile_width, &tile_height);
+	intel_fb_plane_get_subsampling(&hsub, &vsub, fb, color_plane);
+	intel_fb_plane_get_subsampling(&hsub_main, &vsub_main, fb, color_plane - 1);
+
+	hsub /= hsub_main;
+	vsub /= vsub_main;
 
 	tile_width *= hsub;
 	tile_height *= vsub;
 
 	ccs_x = (x * hsub) % tile_width;
 	ccs_y = (y * vsub) % tile_height;
-	main_x = intel_fb->normal[0].x % tile_width;
-	main_y = intel_fb->normal[0].y % tile_height;
+	main_x = intel_fb->normal[color_plane - 1].x % tile_width;
+	main_y = intel_fb->normal[color_plane - 1].y % tile_height;
 
 	/*
 	 * CCS doesn't have its own x/y offset register, so the intra CCS tile
@@ -2705,8 +2769,8 @@ intel_fb_check_ccs_xy(struct drm_framebuffer *fb, int x, int y)
 		DRM_DEBUG_KMS("Bad CCS x/y (main %d,%d ccs %d,%d) full (main %d,%d ccs %d,%d)\n",
 			      main_x, main_y,
 			      ccs_x, ccs_y,
-			      intel_fb->normal[0].x,
-			      intel_fb->normal[0].y,
+			      intel_fb->normal[color_plane - 1].x,
+			      intel_fb->normal[color_plane - 1].y,
 			      x, y);
 		return -EINVAL;
 	}
@@ -2734,8 +2798,7 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
 		int ret;
 
 		cpp = fb->format->cpp[i];
-		width = drm_framebuffer_plane_width(fb->width, fb, i);
-		height = drm_framebuffer_plane_height(fb->height, fb, i);
+		intel_fb_plane_dims(&width, &height, fb, i);
 
 		ret = intel_fb_offset_to_xy(&x, &y, fb, i);
 		if (ret) {
@@ -2744,11 +2807,9 @@ intel_fill_fb_info(struct drm_i915_private *dev_priv,
 			return ret;
 		}
 
-		if (is_ccs_modifier(fb->modifier) && i == 1) {
-			ret = intel_fb_check_ccs_xy(fb, x, y);
-			if (ret)
-				return ret;
-		}
+		ret = intel_fb_check_ccs_xy(fb, i, x, y);
+		if (ret)
+			return ret;
 
 		/*
 		 * The fence (if used) is aligned to the start of the object
@@ -3360,6 +3421,7 @@ static int skl_max_plane_width(const struct drm_framebuffer *fb,
 			return 5120;
 	case I915_FORMAT_MOD_Y_TILED_CCS:
 	case I915_FORMAT_MOD_Yf_TILED_CCS:
+	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
 		/* FIXME AUX plane? */
 	case I915_FORMAT_MOD_Y_TILED:
 	case I915_FORMAT_MOD_Yf_TILED:
@@ -3419,16 +3481,18 @@ static int icl_max_plane_height(void)
 }
 
 static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
-					   int main_x, int main_y, u32 main_offset)
+					   int main_x, int main_y, u32 main_offset,
+					   int aux_plane)
 {
 	const struct drm_framebuffer *fb = plane_state->base.fb;
-	int hsub = fb->format->hsub;
-	int vsub = fb->format->vsub;
-	int aux_x = plane_state->color_plane[1].x;
-	int aux_y = plane_state->color_plane[1].y;
-	u32 aux_offset = plane_state->color_plane[1].offset;
-	u32 alignment = intel_surf_alignment(fb, 1);
-
+	int hsub;
+	int vsub;
+	int aux_x = plane_state->color_plane[aux_plane].x;
+	int aux_y = plane_state->color_plane[aux_plane].y;
+	u32 aux_offset = plane_state->color_plane[aux_plane].offset;
+	u32 alignment = intel_surf_alignment(fb, aux_plane);
+
+	intel_fb_plane_get_subsampling(&hsub, &vsub, fb, aux_plane);
 	while (aux_offset >= main_offset && aux_y <= main_y) {
 		int x, y;
 
@@ -3440,7 +3504,7 @@ static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state
 
 		x = aux_x / hsub;
 		y = aux_y / vsub;
-		aux_offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, 1,
+		aux_offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, aux_plane,
 							       aux_offset, aux_offset - alignment);
 		aux_x = x * hsub + aux_x % hsub;
 		aux_y = y * vsub + aux_y % vsub;
@@ -3449,9 +3513,9 @@ static bool skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state
 	if (aux_x != main_x || aux_y != main_y)
 		return false;
 
-	plane_state->color_plane[1].offset = aux_offset;
-	plane_state->color_plane[1].x = aux_x;
-	plane_state->color_plane[1].y = aux_y;
+	plane_state->color_plane[aux_plane].offset = aux_offset;
+	plane_state->color_plane[aux_plane].x = aux_x;
+	plane_state->color_plane[aux_plane].y = aux_y;
 
 	return true;
 }
@@ -3525,7 +3589,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
 	 * they match with the main surface x/y offsets.
 	 */
 	if (is_ccs_modifier(fb->modifier)) {
-		while (!skl_check_main_ccs_coordinates(plane_state, x, y, offset)) {
+		while (!skl_check_main_ccs_coordinates(plane_state, x, y, offset, 1)) {
 			if (offset == 0)
 				break;
 
@@ -3558,7 +3622,8 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
 {
 	const struct drm_framebuffer *fb = plane_state->base.fb;
 	unsigned int rotation = plane_state->base.rotation;
-	int max_width = skl_max_plane_width(fb, 1, rotation);
+	int uv = is_ccs_modifier(fb->modifier) ? 2 : 1;
+	int max_width = skl_max_plane_width(fb, uv, rotation);
 	int max_height = 4096;
 	int x = plane_state->base.src.x1 >> 17;
 	int y = plane_state->base.src.y1 >> 17;
@@ -3566,8 +3631,8 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
 	int h = drm_rect_height(&plane_state->base.src) >> 17;
 	u32 offset;
 
-	intel_add_fb_offsets(&x, &y, plane_state, 1);
-	offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 1);
+	intel_add_fb_offsets(&x, &y, plane_state, uv);
+	offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, uv);
 
 	/* FIXME not quite sure how/if these apply to the chroma plane */
 	if (w > max_width || h > max_height) {
@@ -3576,9 +3641,41 @@ static int skl_check_nv12_aux_surface(struct intel_plane_state *plane_state)
 		return -EINVAL;
 	}
 
-	plane_state->color_plane[1].offset = offset;
-	plane_state->color_plane[1].x = x;
-	plane_state->color_plane[1].y = y;
+	if (is_ccs_modifier(fb->modifier)) {
+		int aux_offset = plane_state->color_plane[3].offset;
+		int alignment = intel_surf_alignment(fb, uv);
+
+		if (offset > aux_offset) {
+			int hsub, vsub;
+			int main_x = x, main_y = y;
+
+			intel_fb_plane_get_subsampling(&hsub, &vsub, fb, uv);
+			x = main_x / hsub;
+			y = main_y / vsub;
+			offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, uv,
+								   offset,
+								   aux_offset & ~(alignment - 1));
+			x = x * hsub + main_x % hsub;
+			y = y * vsub + main_y % vsub;
+		}
+
+		while (!skl_check_main_ccs_coordinates(plane_state, x, y, offset, 3)) {
+			if (offset == 0)
+				break;
+
+			offset = intel_plane_adjust_aligned_offset(&x, &y, plane_state, uv,
+								   offset, offset - alignment);
+		}
+
+		if (x != plane_state->color_plane[3].x || y != plane_state->color_plane[3].y) {
+			DRM_DEBUG_KMS("Unable to find suitable display surface offset due to CCS\n");
+			return -EINVAL;
+		}
+	}
+
+	plane_state->color_plane[uv].offset = offset;
+	plane_state->color_plane[uv].x = x;
+	plane_state->color_plane[uv].y = y;
 
 	return 0;
 }
@@ -3588,19 +3685,30 @@ static int skl_check_ccs_aux_surface(struct intel_plane_state *plane_state)
 	const struct drm_framebuffer *fb = plane_state->base.fb;
 	int src_x = plane_state->base.src.x1 >> 16;
 	int src_y = plane_state->base.src.y1 >> 16;
-	int hsub = fb->format->hsub;
-	int vsub = fb->format->vsub;
-	int x = src_x / hsub;
-	int y = src_y / vsub;
 	u32 offset;
+	int ccs;
 
-	intel_add_fb_offsets(&x, &y, plane_state, 1);
-	offset = intel_plane_compute_aligned_offset(&x, &y, plane_state, 1);
 
-	plane_state->color_plane[1].offset = offset;
-	plane_state->color_plane[1].x = x * hsub + src_x % hsub;
-	plane_state->color_plane[1].y = y * vsub + src_y % vsub;
+	for (ccs = 1; ccs < fb->format->num_planes; ccs += 2) {
+		int hsub, vsub;
+		int main_hsub, main_vsub;
+		int x, y;
+
+		intel_fb_plane_get_subsampling(&hsub, &vsub, fb, ccs);
+		intel_fb_plane_get_subsampling(&main_hsub, &main_vsub, fb, ccs - 1);
 
+		hsub /= main_hsub;
+		vsub /= main_vsub;
+		x = src_x / hsub;
+		y = src_y / vsub;
+
+		intel_add_fb_offsets(&x, &y, plane_state, ccs);
+		offset = intel_plane_compute_aligned_offset(&x, &y,
+							    plane_state, ccs);
+		plane_state->color_plane[ccs].offset = offset;
+		plane_state->color_plane[ccs].x = x * hsub + src_x % hsub;
+		plane_state->color_plane[ccs].y = y * vsub + src_y % vsub;
+	}
 	return 0;
 }
 
@@ -3608,6 +3716,7 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
 {
 	const struct drm_framebuffer *fb = plane_state->base.fb;
 	int ret;
+	bool needs_aux = false;
 
 	ret = intel_plane_compute_gtt(plane_state);
 	if (ret)
@@ -3617,21 +3726,31 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
 		return 0;
 
 	/*
-	 * Handle the AUX surface first since
-	 * the main surface setup depends on it.
+	 * Handle the AUX surface first since the main surface setup depends on
+	 * it.
 	 */
-	if (drm_format_info_is_yuv_semiplanar(fb->format)) {
-		ret = skl_check_nv12_aux_surface(plane_state);
+	if (is_ccs_modifier(fb->modifier)) {
+		needs_aux = true;
+		ret = skl_check_ccs_aux_surface(plane_state);
 		if (ret)
 			return ret;
-	} else if (is_ccs_modifier(fb->modifier)) {
-		ret = skl_check_ccs_aux_surface(plane_state);
+	}
+
+	if (drm_format_info_is_yuv_semiplanar(fb->format)) {
+		needs_aux = true;
+		ret = skl_check_nv12_aux_surface(plane_state);
 		if (ret)
 			return ret;
-	} else {
-		plane_state->color_plane[1].offset = ~0xfff;
-		plane_state->color_plane[1].x = 0;
-		plane_state->color_plane[1].y = 0;
+	}
+
+	if (!needs_aux) {
+		int i;
+
+		for (i = 1; i < fb->format->num_planes; i++) {
+			plane_state->color_plane[i].offset = ~0xfff;
+			plane_state->color_plane[i].x = 0;
+			plane_state->color_plane[i].y = 0;
+		}
 	}
 
 	ret = skl_check_main_surface(plane_state);
@@ -4149,6 +4268,8 @@ static u32 skl_plane_ctl_tiling(u64 fb_modifier)
 		return PLANE_CTL_TILED_Y |
 		       PLANE_CTL_RENDER_DECOMPRESSION_ENABLE |
 		       PLANE_CTL_CLEAR_COLOR_DISABLE;
+	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
+		return PLANE_CTL_TILED_Y | PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE;
 	case I915_FORMAT_MOD_Yf_TILED:
 		return PLANE_CTL_TILED_YF;
 	case I915_FORMAT_MOD_Yf_TILED_CCS:
@@ -9913,6 +10034,8 @@ skylake_get_initial_plane_config(struct intel_crtc *crtc,
 			fb->modifier = INTEL_GEN(dev_priv) >= 12 ?
 				I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS :
 				I915_FORMAT_MOD_Y_TILED_CCS;
+		else if (val & PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE)
+			fb->modifier = I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS;
 		else
 			fb->modifier = I915_FORMAT_MOD_Y_TILED;
 		break;
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 40390d855815..91241f2bc575 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -530,7 +530,7 @@ struct intel_plane_state {
 		 */
 		u32 stride;
 		int x, y;
-	} color_plane[2];
+	} color_plane[4];
 
 	/* plane control register */
 	u32 ctl;
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c
index 20df64336669..fdb9dcc4060c 100644
--- a/drivers/gpu/drm/i915/display/intel_sprite.c
+++ b/drivers/gpu/drm/i915/display/intel_sprite.c
@@ -1738,7 +1738,8 @@ static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
 	     fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
 	     fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
 	     fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
-	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS)) {
+	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
+	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)) {
 		DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
 		return -EINVAL;
 	}
@@ -2150,7 +2151,16 @@ static const u64 skl_plane_format_modifiers_ccs[] = {
 	DRM_FORMAT_MOD_INVALID
 };
 
-static const u64 gen12_plane_format_modifiers_ccs[] = {
+static const u64 gen12_plane_format_modifiers_mc_ccs[] = {
+	I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
+	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
+	I915_FORMAT_MOD_Y_TILED,
+	I915_FORMAT_MOD_X_TILED,
+	DRM_FORMAT_MOD_LINEAR,
+	DRM_FORMAT_MOD_INVALID
+};
+
+static const u64 gen12_plane_format_modifiers_rc_ccs[] = {
 	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
 	I915_FORMAT_MOD_Y_TILED,
 	I915_FORMAT_MOD_X_TILED,
@@ -2306,10 +2316,21 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
 	}
 }
 
+static bool gen12_plane_supports_mc_ccs(enum plane_id plane_id)
+{
+	return plane_id < PLANE_SPRITE4;
+}
+
 static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
 					     u32 format, u64 modifier)
 {
+	struct intel_plane *plane = to_intel_plane(_plane);
+
 	switch (modifier) {
+	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
+		if (!gen12_plane_supports_mc_ccs(plane->id))
+			return false;
+		/* fall through */
 	case DRM_FORMAT_MOD_LINEAR:
 	case I915_FORMAT_MOD_X_TILED:
 	case I915_FORMAT_MOD_Y_TILED:
@@ -2327,14 +2348,17 @@ static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
 		if (is_ccs_modifier(modifier))
 			return true;
 		/* fall through */
-	case DRM_FORMAT_RGB565:
-	case DRM_FORMAT_XRGB2101010:
-	case DRM_FORMAT_XBGR2101010:
 	case DRM_FORMAT_YUYV:
 	case DRM_FORMAT_YVYU:
 	case DRM_FORMAT_UYVY:
 	case DRM_FORMAT_VYUY:
+		if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)
+			return true;
+		/* fall through */
 	case DRM_FORMAT_NV12:
+	case DRM_FORMAT_RGB565:
+	case DRM_FORMAT_XRGB2101010:
+	case DRM_FORMAT_XBGR2101010:
 	case DRM_FORMAT_P010:
 	case DRM_FORMAT_P012:
 	case DRM_FORMAT_P016:
@@ -2471,6 +2495,14 @@ static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
 	}
 }
 
+static const u64 *gen12_get_plane_modifiers(enum plane_id plane_id)
+{
+	if (gen12_plane_supports_mc_ccs(plane_id))
+		return gen12_plane_format_modifiers_mc_ccs;
+	else
+		return gen12_plane_format_modifiers_rc_ccs;
+}
+
 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
 			      enum pipe pipe, enum plane_id plane_id)
 {
@@ -2537,7 +2569,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
 
 	plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
 	if (INTEL_GEN(dev_priv) >= 12) {
-		modifiers = gen12_plane_format_modifiers_ccs;
+		modifiers = gen12_get_plane_modifiers(plane_id);
 		plane_funcs = &gen12_plane_funcs;
 	} else {
 		if (plane->has_ccs)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c1583f5c413b..5fad9cb35979 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6710,6 +6710,7 @@ enum {
 #define   PLANE_CTL_TILED_Y			(4 << 10)
 #define   PLANE_CTL_TILED_YF			(5 << 10)
 #define   PLANE_CTL_FLIP_HORIZONTAL		(1 << 8)
+#define   PLANE_CTL_MEDIA_DECOMPRESSION_ENABLE	(1 << 4) /* TGL+ */
 #define   PLANE_CTL_ALPHA_MASK			(0x3 << 4) /* Pre-GLK */
 #define   PLANE_CTL_ALPHA_DISABLE		(0 << 4)
 #define   PLANE_CTL_ALPHA_SW_PREMULTIPLY	(2 << 4)
-- 
2.20.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2019-10-15  0:03 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-15  0:05 [PATCH v4 00/10] Clear Color Support for TGL Render Decompression Radhakrishna Sripada
2019-10-15  0:05 ` [PATCH v4 01/10] drm/framebuffer: Format modifier for Intel Gen-12 render compression Radhakrishna Sripada
2019-10-15  0:05 ` [PATCH v4 02/10] drm/i915: Use intel_tile_height() instead of re-implementing Radhakrishna Sripada
2019-10-15  0:05 ` [PATCH v4 03/10] drm/i915: Move CCS stride alignment W/A inside intel_fb_stride_alignment Radhakrishna Sripada
2019-10-15  0:05 ` [PATCH v4 04/10] drm/i915/tgl: Gen-12 render decompression Radhakrishna Sripada
2019-10-15  0:05 ` [PATCH v4 05/10] drm/i915: Extract framebufer CCS offset checks into a function Radhakrishna Sripada
2019-10-15  0:05 ` [PATCH v4 06/10] drm/framebuffer: Format modifier for Intel Gen-12 media compression Radhakrishna Sripada
2019-10-15  0:05 ` [PATCH v4 07/10] drm/fb: Extend format_info member arrays to handle four planes Radhakrishna Sripada
2019-10-15  0:05 ` Radhakrishna Sripada [this message]
2019-10-15  0:05 ` [PATCH v4 09/10] drm/framebuffer/tgl: Format modifier for Intel Gen 12 render compression with Clear Color Radhakrishna Sripada
2019-10-15  0:47   ` Radhakrishna Sripada
2019-10-23  0:09     ` [PATCH v5 " Radhakrishna Sripada
2019-10-24  0:00       ` Chery, Nanley G
2019-10-24  0:00         ` [Intel-gfx] " Chery, Nanley G
2019-10-28 18:58       ` [PATCH v6 10/10] drm/i915/tgl: Add Clear Color supoort for TGL Render Decompression Radhakrishna Sripada
2019-10-28 18:58         ` [Intel-gfx] " Radhakrishna Sripada
2019-10-15  0:05 ` [PATCH v4 " Radhakrishna Sripada
2019-10-22 18:15   ` Matt Roper
2019-10-22 18:37     ` Sripada, Radhakrishna
2019-10-23  0:09   ` [PATCH v5 " Radhakrishna Sripada
2019-10-15  0:09 ` ✗ Fi.CI.CHECKPATCH: warning for Clear Color Support for TGL Render Decompression (rev4) Patchwork
2019-10-15  0:34 ` ✓ Fi.CI.BAT: success " Patchwork
2019-10-15  1:08 ` ✗ Fi.CI.CHECKPATCH: warning for Clear Color Support for TGL Render Decompression (rev5) Patchwork
2019-10-15  1:56 ` ✓ Fi.CI.BAT: success " Patchwork
2019-10-15 12:12 ` ✓ Fi.CI.IGT: " Patchwork
2019-10-23  1:52 ` ✗ Fi.CI.CHECKPATCH: warning for Clear Color Support for TGL Render Decompression (rev7) Patchwork
2019-10-23  2:35 ` ✓ Fi.CI.BAT: success " Patchwork
2019-10-23 17:20 ` ✓ Fi.CI.IGT: " Patchwork
2019-10-23 17:20   ` [Intel-gfx] " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191015000533.11425-9-radhakrishna.sripada@intel.com \
    --to=radhakrishna.sripada@intel.com \
    --cc=dhinakaran.pandiyan@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=lucas.demarchi@intel.com \
    --cc=nanley.g.chery@intel.com \
    --cc=ville.syrjala@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.