[PATCH 09/10] INTEL_DII: drm/i915/mtl: Add support for 24 bit precision DG LUT

Borah, Chaitanya Kumar chaitanya.kumar.borah at intel.com
Wed Sep 14 12:48:02 UTC 2022


D14 onwards Degamma LUT/PRE-CSC LUT precision has been increased from
16 bit to 24 bits. For LUT values greater than or equal to 0 and
less than 1.0, the LUT value is used to linearly interpolate between
two adjacent points of the first 129 gamma entries to create the
result value. The first 128 entries are stored as 24 bits per color
in an unsigned 0.24 format with 0 integer and 24 fractional.
The 129th, 130th and 131th entries are stored as 27 bits per color
in an unsigned 3.24 format with 3 integer and 24 fractional bits.

Signed-off-by: Borah, Chaitanya Kumar <chaitanya.kumar.borah at intel.com>
---
 drivers/gpu/drm/i915/display/intel_color.c | 54 +++++++++++++++++++++-
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c
index ecab52ed715428..70cef8edcb6606 100644
--- a/drivers/gpu/drm/i915/display/intel_color.c
+++ b/drivers/gpu/drm/i915/display/intel_color.c
@@ -987,6 +987,51 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state)
 	}
 }
 
+static void mtl_load_degamma_lut(const struct intel_crtc_state *crtc_state)
+{
+	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+	const struct drm_property_blob *degamma_lut_blob = crtc_state->hw.degamma_lut;
+	struct drm_color_lut_ext *degamma_lut = degamma_lut_blob->data;
+	u32 i, lut_size = INTEL_INFO(i915)->display.color.degamma_lut_size;
+	enum pipe pipe = crtc->pipe;
+
+	/*
+	 * When setting the auto-increment bit, the hardware seems to
+	 * ignore the index bits, so we need to reset it to index 0
+	 * separately.
+	 */
+	intel_de_write_fw(i915, PRE_CSC_GAMC_INDEX(pipe), 0);
+	intel_de_write_fw(i915, PRE_CSC_GAMC_INDEX(pipe),
+			  PRE_CSC_GAMC_AUTO_INCREMENT);
+
+	if (degamma_lut_blob) {
+		degamma_lut = degamma_lut_blob->data;
+		for (i = 0; i < lut_size; i++) {
+			u64 word = drm_color_lut_extract_ext(degamma_lut[i].green, 24);
+			u32 lut_val = (word & 0xffffff);
+
+			intel_de_write_fw(i915, PRE_CSC_GAMC_DATA(pipe),
+					  lut_val);
+		}
+
+		while (i++ < glk_degamma_lut_size(i915))
+			intel_de_write_fw(i915, PRE_CSC_GAMC_DATA(pipe), degamma_lut[i].green);
+	} else {
+		for (i = 0; i < lut_size; i++) {
+			u32 v = (i * ((1 << 24) - 1)) / (lut_size - 1);
+
+			intel_de_write_fw(i915, PRE_CSC_GAMC_DATA(pipe), v);
+		}
+
+		/* Clamp values > 1.0. */
+		while (i++ < glk_degamma_lut_size(i915))
+			intel_de_write_fw(i915, PRE_CSC_GAMC_DATA(pipe), 1 << 24);
+	}
+
+	intel_de_write_fw(i915, PRE_CSC_GAMC_INDEX(pipe), 0);
+}
+
 /* ilk+ "12.4" interpolated format (high 10 bits) */
 static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color)
 {
@@ -1179,9 +1224,14 @@ static void xelpd_load_luts(const struct intel_crtc_state *crtc_state)
 {
 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
 
-	if (crtc_state->hw.degamma_lut)
-		glk_load_degamma_lut(crtc_state);
+	if (crtc_state->hw.degamma_lut) {
+		if ((DISPLAY_VER(i915) >= 14))
+			mtl_load_degamma_lut(crtc_state);
+		else
+			glk_load_degamma_lut(crtc_state);
+	}
 
 	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
 	case GAMMA_MODE_MODE_8BIT:
-- 
2.25.1



More information about the Intel-gfx-trybot mailing list