Extract the LUT and program plane post csc registers. Signed-off-by: Uma Shankar <uma.shankar@xxxxxxxxx> Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@xxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_color.c | 109 +++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_color.c b/drivers/gpu/drm/i915/display/intel_color.c index d942e70bcb56..f3333d0c8b49 100644 --- a/drivers/gpu/drm/i915/display/intel_color.c +++ b/drivers/gpu/drm/i915/display/intel_color.c @@ -3964,6 +3964,113 @@ 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, + const struct drm_color_lut_32 *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, j; + + 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); + /* TODO: Add macro */ + intel_de_write_fw(dev_priv, PLANE_POST_CSC_GAMC_SEG0_INDEX_ENH(pipe, plane, 0), + PLANE_PAL_PREC_AUTO_INCREMENT); + if (post_csc_lut) { + /* Segment 0 */ + for (i = 0, j = 0; i < 9; i++, j++) { + u32 lut_val = (post_csc_lut[j].green & 0xffffff); + + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_SEG0_DATA_ENH(pipe, plane, 0), + lut_val); + } + + /* Segment 1 */ + lut_size = 32; + for (i = 0; i < lut_size; i++) { + u32 lut_val; + + if (i == 0) + lut_val = post_csc_lut[0].green & 0xffffff; + else if (i == 1) + lut_val = (post_csc_lut[8].green & 0xffffff); + else + lut_val = (post_csc_lut[j++].green & 0xffffff); + + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_DATA_ENH(pipe, plane, 0), + lut_val); + } + + /* Segment 2 */ + do { + intel_de_write_fw(dev_priv, + PLANE_POST_CSC_GAMC_DATA_ENH(pipe, plane, 0), + post_csc_lut[j++].green); + } while (j < 42); + } else { + /*TODO: Add for segment 0 */ + 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); + intel_de_write_fw(dev_priv, PLANE_POST_CSC_GAMC_SEG0_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 *blob, bool is_pre_csc) { @@ -3971,6 +4078,8 @@ static void xelpd_plane_load_luts(const struct drm_plane_state *plane_state, if (is_pre_csc) xelpd_program_plane_pre_csc_lut(plane_state, lut, 0); + else + xelpd_program_plane_post_csc_lut(plane_state, lut, 0); } void intel_color_load_plane_luts(const struct drm_plane_state *plane_state, -- 2.42.0