Gen11 introduced a new gamma mode i.e, multi segmented gamma mode. Added support for the same. Signed-off-by: Uma Shankar <uma.shankar@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_color.c | 105 +++++++++++++++++++++++++++++++------ 1 file changed, 90 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_color.c b/drivers/gpu/drm/i915/intel_color.c index 399d63d..7733c256 100644 --- a/drivers/gpu/drm/i915/intel_color.c +++ b/drivers/gpu/drm/i915/intel_color.c @@ -105,6 +105,9 @@ MULTI_SEGMENTED_GAMMA_MODE_12BIT | \ BIT_SPLIT_GAMMA_MODE_12BIT) +#define GEN11_GET_MS10BITS_OF_LUT(lut) (((lut) >> 6) & 0x3FF) +#define GEN11_GET_LS6BITS_OF_LUT(lut) ((lut) & 0x3F) + static bool lut_is_legacy(const struct drm_property_blob *lut) { return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH; @@ -538,6 +541,10 @@ static void bdw_load_degamma_lut(const struct intel_crtc_state *crtc_state) if (degamma_lut) { const struct drm_color_lut *lut = degamma_lut->data; + if (crtc_state->gamma_mode_type == + MULTI_SEGMENTED_GAMMA_MODE_12BIT) + lut += 9; + for (i = 0; i < lut_size; i++) { u32 word = drm_color_lut_extract(lut[i].red, 10) << 20 | @@ -563,6 +570,7 @@ static void bdw_load_gamma_lut(const struct intel_crtc_state *crtc_state, u32 of const struct drm_property_blob *gamma_lut = crtc_state->base.gamma_lut; u32 i, lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size; enum pipe pipe = crtc->pipe; + u32 word; WARN_ON(offset & ~PAL_PREC_INDEX_VALUE_MASK); @@ -574,13 +582,32 @@ static void bdw_load_gamma_lut(const struct intel_crtc_state *crtc_state, u32 of if (gamma_lut) { const struct drm_color_lut *lut = gamma_lut->data; - for (i = 0; i < lut_size; i++) { - u32 word = - (drm_color_lut_extract(lut[i].red, 10) << 20) | - (drm_color_lut_extract(lut[i].green, 10) << 10) | - drm_color_lut_extract(lut[i].blue, 10); - - I915_WRITE(PREC_PAL_DATA(pipe), word); + if (crtc_state->gamma_mode_type == + MULTI_SEGMENTED_GAMMA_MODE_12BIT) { + lut_size = 9 + 512; + for (i = 9; i < lut_size; i++) { + /* For Even Index */ + word = (GEN11_GET_LS6BITS_OF_LUT(lut[i].red) << 20) | + (GEN11_GET_LS6BITS_OF_LUT(lut[i].green) << 10)| + GEN11_GET_LS6BITS_OF_LUT(lut[i].blue); + + I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe), word); + + /* For ODD index */ + word = (GEN11_GET_MS10BITS_OF_LUT(lut[i].red) << 20) | + (GEN11_GET_MS10BITS_OF_LUT(lut[i].green) << 10) | + GEN11_GET_MS10BITS_OF_LUT(lut[i].blue); + + I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe), word); + } + } else { + for (i = 0; i < lut_size; i++) { + word = (drm_color_lut_extract(lut[i].red, 10) << 20) | + (drm_color_lut_extract(lut[i].green, 10) << 10) | + drm_color_lut_extract(lut[i].blue, 10); + + I915_WRITE(PREC_PAL_DATA(pipe), word); + } } /* Program the max register to clamp values > 1.0. */ @@ -685,15 +712,57 @@ static void glk_load_luts(const struct intel_crtc_state *crtc_state) bdw_load_gamma_lut(crtc_state, 0); } +static void icl_load_gamma_multi_segmented_lut(const struct intel_crtc_state + *crtc_state, u32 offset) +{ + struct drm_crtc *crtc = crtc_state->base.crtc; + struct drm_device *dev = crtc_state->base.crtc->dev; + struct drm_i915_private *dev_priv = to_i915(dev); + enum pipe pipe = to_intel_crtc(crtc)->pipe; + u32 i, lut_size = 9; + + WARN_ON(offset & ~PAL_PREC_MULTI_SEGMENT_INDEX_VALUE_MASK); + + I915_WRITE(PREC_PAL_MULTI_SEG_INDEX(pipe), + (PAL_PREC_AUTO_INCREMENT | offset)); + + if (crtc_state->base.gamma_lut) { + struct drm_color_lut *lut = + (struct drm_color_lut *)crtc_state->base.gamma_lut->data; + + for (i = 0; i < lut_size; i++) { + u32 word; + + /* For Even Index */ + word = (GEN11_GET_LS6BITS_OF_LUT(lut[i].red) << 20) | + (GEN11_GET_LS6BITS_OF_LUT(lut[i].green) << 10) | + GEN11_GET_LS6BITS_OF_LUT(lut[i].blue); + I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe), word); + + /* For ODD index */ + word = (GEN11_GET_MS10BITS_OF_LUT(lut[i].red) << 20) | + (GEN11_GET_MS10BITS_OF_LUT(lut[i].green) << 10) | + GEN11_GET_MS10BITS_OF_LUT(lut[i].blue); + I915_WRITE(PREC_PAL_MULTI_SEG_DATA(pipe), word); + } + } + + bdw_load_gamma_lut(crtc_state, 0); +} + static void icl_load_luts(const struct intel_crtc_state *crtc_state) { glk_load_degamma_lut(crtc_state); - if (crtc_state_is_legacy_gamma(crtc_state)) + if (crtc_state_is_legacy_gamma(crtc_state)) { i9xx_load_luts(crtc_state); - else + } else if (crtc_state->gamma_mode_type == + MULTI_SEGMENTED_GAMMA_MODE_12BIT) { + icl_load_gamma_multi_segmented_lut(crtc_state, 0); + } else { /* ToDo: Add support for multi segment gamma LUT */ bdw_load_gamma_lut(crtc_state, 0); + } } static void cherryview_load_luts(const struct intel_crtc_state *crtc_state) @@ -910,16 +979,22 @@ int intel_color_check(struct intel_crtc_state *crtc_state) drm_color_lut_check(gamma_lut, gamma_tests)) return -EINVAL; - if (INTEL_GEN(dev_priv) >= 11) - crtc_state->gamma_mode = GAMMA_MODE_MODE_10BIT | - PRE_CSC_GAMMA_ENABLE | + if (INTEL_GEN(dev_priv) >= 11) { + crtc_state->gamma_mode = PRE_CSC_GAMMA_ENABLE | POST_CSC_GAMMA_ENABLE; - else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) + if (crtc_state->gamma_mode_type == + MULTI_SEGMENTED_GAMMA_MODE_12BIT) + crtc_state->gamma_mode |= + GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED; + else + crtc_state->gamma_mode |= GAMMA_MODE_MODE_10BIT; + } else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) { crtc_state->gamma_mode = GAMMA_MODE_MODE_10BIT; - else if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) + } else if (INTEL_GEN(dev_priv) >= 9 || IS_BROADWELL(dev_priv)) { crtc_state->gamma_mode = GAMMA_MODE_MODE_SPLIT; - else + } else { crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; + } if (INTEL_GEN(dev_priv) >= 11) { if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx