i915: Add render compression support for Gen-12

From Gen-12 onwards Render compression(RC) aux buffer layout has been
changed. Updating the buffer allocation logic accordingly.

BUG=b:149544398
TEST=Boot target board to UI and run this command in cros shell, and
verify type (6) of RC modifer is in the output:
localhost# cat /run/debugfs_gpu/i915_gem_framebuffer
user size: 2256 x 1504, depth 24, 32 bpp, modifier 0x100000000000006,...
...

Change-Id: Ic82302b81526028b18166737786d7848a506f7ee
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/2248284
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Vipin Anand <vipin.anand@intel.corp-partner.google.com>
Commit-Queue: Binu R S <binu.r.s@intel.com>
diff --git a/drv.h b/drv.h
index 9687025..3dffdff 100644
--- a/drv.h
+++ b/drv.h
@@ -71,6 +71,11 @@
 #define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0')
 #endif
 
+//TODO: remove this defination once drm_fourcc.h contains it.
+#ifndef I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS
+#define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS fourcc_mod_code(INTEL, 6)
+#endif
+
 // clang-format on
 struct driver;
 struct bo;
diff --git a/i915.c b/i915.c
index ccb3962..03aec0e 100644
--- a/i915.c
+++ b/i915.c
@@ -37,6 +37,10 @@
 static const uint64_t gen_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_CCS, I915_FORMAT_MOD_Y_TILED,
 					       I915_FORMAT_MOD_X_TILED, DRM_FORMAT_MOD_LINEAR };
 
+static const uint64_t gen12_modifier_order[] = { I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
+						 I915_FORMAT_MOD_Y_TILED, I915_FORMAT_MOD_X_TILED,
+						 DRM_FORMAT_MOD_LINEAR };
+
 struct modifier_support_t {
 	const uint64_t *order;
 	uint32_t count;
@@ -88,8 +92,13 @@
 
 static void i915_get_modifier_order(struct i915_device *i915)
 {
-	i915->modifier.order = gen_modifier_order;
-	i915->modifier.count = ARRAY_SIZE(gen_modifier_order);
+	if (i915->gen == 12) {
+		i915->modifier.order = gen12_modifier_order;
+		i915->modifier.count = ARRAY_SIZE(gen12_modifier_order);
+	} else {
+		i915->modifier.order = gen_modifier_order;
+		i915->modifier.count = ARRAY_SIZE(gen_modifier_order);
+	}
 }
 
 static uint64_t unset_flags(uint64_t current_flags, uint64_t mask)
@@ -419,6 +428,10 @@
 		break;
 	case I915_FORMAT_MOD_Y_TILED:
 	case I915_FORMAT_MOD_Y_TILED_CCS:
+	/* For now support only I915_TILING_Y as this works with all
+	 * IPs(render/media/display)
+	 */
+	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
 		bo->meta.tiling = I915_TILING_Y;
 		break;
 	}
@@ -477,6 +490,41 @@
 
 		bo->meta.num_planes = 2;
 		bo->meta.total_size = offset;
+	} else if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS) {
+
+		/*
+		 * considering only 128 byte compression and one cache line of
+		 * aux buffer(64B) contains compression status of 4-Y tiles.
+		 * Which is 4 * (128B * 32L).
+		 * line stride(bytes) is 4 * 128B
+		 * and tile stride(lines) is 32L
+		 */
+		uint32_t stride = ALIGN(drv_stride_from_format(format, width, 0), 512);
+
+		height = ALIGN(drv_height_from_format(format, height, 0), 32);
+
+		if (i915->is_adlp && (stride > 1)) {
+			stride = 1 << (32 - __builtin_clz(stride - 1));
+			height = ALIGN(drv_height_from_format(format, height, 0), 128);
+		}
+
+		bo->meta.strides[0] = stride;
+		/* size calculation and alignment are 64KB aligned
+		 * size as per spec
+		 */
+		bo->meta.sizes[0] = ALIGN(stride * height, 65536);
+		bo->meta.offsets[0] = 0;
+
+		/* Aux buffer is linear and page aligned. It is placed after
+		 * other planes and aligned to main buffer stride.
+		 */
+		bo->meta.strides[1] = bo->meta.strides[0] / 8;
+		/* Aligned to page size */
+		bo->meta.sizes[1] = ALIGN(bo->meta.sizes[0] / 256, getpagesize());
+		bo->meta.offsets[1] = bo->meta.sizes[0];
+		/* Total number of planes & sizes */
+		bo->meta.num_planes = 2;
+		bo->meta.total_size = bo->meta.sizes[0] + bo->meta.sizes[1];
 	} else {
 		i915_bo_from_format(bo, width, height, format);
 	}
@@ -579,6 +627,9 @@
 	if (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_CCS)
 		return MAP_FAILED;
 
+	if (bo->meta.format_modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS)
+		return MAP_FAILED;
+
 	if (bo->meta.tiling == I915_TILING_NONE) {
 		struct drm_i915_gem_mmap gem_map = { 0 };
 		/* TODO(b/118799155): We don't seem to have a good way to