Extract the LUT and program plane post csc registers. Co-developed-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@xxxxxxxxx> Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@xxxxxxxxx> Signed-off-by: Uma Shankar <uma.shankar@xxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_color.c | 95 +++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index 56bcf750b047..ff996b9ee77d 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -1963,16 +1963,109 @@ static void xelpd_program_plane_pre_csc_lut(const struct drm_plane_state *state, } } +static void xelpd_program_plane_post_csc_lut(const struct drm_plane_state *state, + struct drm_color_lut_ext *post_csc_lut, + u32 offset) +{ + struct drm_i915_private *dev_priv = to_i915(state->plane->dev); + enum pipe pipe = to_intel_plane(state->plane)->pipe; + enum plane_id plane = to_intel_plane(state->plane)->id; + u32 i, lut_size; + + if (icl_is_hdr_plane(dev_priv, plane)) { + intel_de_write_fw(dev_priv, PLANE_POST_CSC_GAMC_INDEX_ENH(pipe, plane, 0), + offset | PLANE_PAL_PREC_AUTO_INCREMENT); + if (post_csc_lut) { + lut_size = 32; + for (i = 0; i < lut_size; i++) { + u64 word = drm_color_lut_extract_ext(post_csc_lut[i].green, 24); + u32 lut_val = (word & 0xffffff); + + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_DATA_ENH(pipe, plane, 0), + lut_val); + } + + do { + /* Program the max register to clamp values > 1.0. */ + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_DATA_ENH(pipe, plane, 0), + post_csc_lut[i].green); + } while (i++ < 34); + } else { + lut_size = 32; + for (i = 0; i < lut_size; i++) { + u32 v = (i * ((1 << 24) - 1)) / (lut_size - 1); + + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_DATA_ENH(pipe, plane, 0), v); + } + + do { + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_DATA_ENH(pipe, plane, 0), + 1 << 24); + } while (i++ < 34); + } + + intel_de_write_fw(dev_priv, PLANE_POST_CSC_GAMC_INDEX_ENH(pipe, plane, 0), 0); + } else { + lut_size = 32; + /* + * First 3 planes are HDR, so reduce by 3 to get to the right + * SDR plane offset + */ + plane = plane - 3; + + intel_de_write_fw(dev_priv, PLANE_POST_CSC_GAMC_INDEX(pipe, plane, 0), + offset | PLANE_PAL_PREC_AUTO_INCREMENT); + + if (post_csc_lut) { + for (i = 0; i < lut_size; i++) + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_DATA(pipe, plane, 0), + post_csc_lut[i].green & 0xffff); + /* Program the max register to clamp values > 1.0. */ + while (i < 35) + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_DATA(pipe, plane, 0), + post_csc_lut[i++].green & 0x3ffff); + } else { + for (i = 0; i < lut_size; i++) { + u32 v = (i * ((1 << 16) - 1)) / (lut_size - 1); + + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_DATA(pipe, plane, 0), v); + } + + do { + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_DATA(pipe, plane, 0), + (1 << 16)); + } while (i++ < 34); + } + + intel_de_write_fw(dev_priv, PLANE_POST_CSC_GAMC_INDEX(pipe, plane, 0), 0); + } +} + static void xelpd_plane_load_luts(const struct drm_plane_state *plane_state) { const struct drm_property_blob *pre_csc_lut_blob = plane_state->color.pre_csc_lut; - struct drm_color_lut_ext *pre_csc_lut = NULL; + const struct drm_property_blob *post_csc_lut_blob = + plane_state->color.post_csc_lut; + struct drm_color_lut_ext *pre_csc_lut, *post_csc_lut; if (pre_csc_lut_blob) { pre_csc_lut = pre_csc_lut_blob->data; xelpd_program_plane_pre_csc_lut(plane_state, pre_csc_lut, 0); } + + if (post_csc_lut_blob) { + post_csc_lut = post_csc_lut_blob->data; + xelpd_program_plane_post_csc_lut(plane_state, post_csc_lut, 0); + } } void intel_color_load_luts(const struct intel_crtc_state *crtc_state) -- 2.38.1