On Wed, Dec 03, 2025 at 02:22:10PM +0530, Uma Shankar wrote:
> From: Chaitanya Kumar Borah <[email protected]>
> 
> Add helpers to program the 3D LUT registers and arm them.
> 
> LUT_3D_READY in LUT_3D_CLT is cleared off by the HW once
> the LUT buffer is loaded into it's internal working RAM.
> So by the time we try to load/commit new values, we expect
> it to be cleared off. If not, log an error and return
> without writing new values. Do it only when writing with MMIO.
> There is no way to read register within DSB execution.
> 
> v2:
> - Add information regarding LUT_3D_READY to commit message (Jani)
> - Log error instead of a drm_warn and return without committing changes
>   if 3DLUT HW is not ready to accept new values.
> - Refactor intel_color_crtc_has_3dlut()
>   Also remove Gen10 check (Suraj)
> v3:
> - Addressed review comments (Suraj)
> 
> Reviewed-by: Suraj Kandpal <[email protected]>
> Signed-off-by: Chaitanya Kumar Borah <[email protected]>
> Signed-off-by: Uma Shankar <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_color.c    | 78 +++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_color.h    |  4 +
>  .../drm/i915/display/intel_color_pipeline.c   | 29 +++++--
>  .../drm/i915/display/intel_color_pipeline.h   |  3 +-
>  .../drm/i915/display/intel_display_limits.h   |  1 +
>  .../drm/i915/display/intel_display_types.h    |  2 +-
>  drivers/gpu/drm/i915/display/intel_plane.c    |  2 +
>  7 files changed, 112 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_color.c 
> b/drivers/gpu/drm/i915/display/intel_color.c
> index 08f3b5b47b8e..e7950655434b 100644
> --- a/drivers/gpu/drm/i915/display/intel_color.c
> +++ b/drivers/gpu/drm/i915/display/intel_color.c
> @@ -4062,6 +4062,52 @@ xelpd_plane_load_luts(struct intel_dsb *dsb, const 
> struct intel_plane_state *pla
>               xelpd_program_plane_post_csc_lut(dsb, plane_state);
>  }
>  
> +static u32 glk_3dlut_10(const struct drm_color_lut32 *color)
> +{
> +     return REG_FIELD_PREP(LUT_3D_DATA_RED_MASK, 
> drm_color_lut32_extract(color->red, 10)) |
> +             REG_FIELD_PREP(LUT_3D_DATA_GREEN_MASK, 
> drm_color_lut32_extract(color->green, 10)) |
> +             REG_FIELD_PREP(LUT_3D_DATA_BLUE_MASK, 
> drm_color_lut32_extract(color->blue, 10));
> +}
> +
> +static void glk_load_lut_3d(struct intel_dsb *dsb,
> +                         struct intel_crtc *crtc,
> +                         const struct drm_property_blob *blob)
> +{
> +     struct intel_display *display = to_intel_display(crtc->base.dev);
> +     const struct drm_color_lut32 *lut = blob->data;
> +     int i, lut_size = drm_color_lut32_size(blob);
> +     enum pipe pipe = crtc->pipe;
> +
> +     if (!dsb && intel_de_read(display, LUT_3D_CTL(pipe)) & LUT_3D_READY) {
> +             drm_err(display->drm, "[CRTC:%d:%s] 3D LUT not ready, not 
> loading LUTs\n",
> +                     crtc->base.base.id, crtc->base.name);
> +             return;

Just ran into this while perusing the code...

This check could be implemented exactly like intel_vrr_check_push_sent()
so that it works for both the DSB and non-DSB paths. The 'return' should
just get nuked IMO.

> +void intel_color_plane_commit_arm(struct intel_dsb *dsb,
> +                               const struct intel_plane_state *plane_state)
> +{
> +     struct intel_display *display = to_intel_display(plane_state);
> +     struct intel_crtc *crtc = to_intel_crtc(plane_state->uapi.crtc);
> +
> +     if (crtc && intel_color_crtc_has_3dlut(display, crtc->pipe))
> +             glk_lut_3d_commit(dsb, crtc, !!plane_state->hw.lut_3d);
                                              ^^^^^^^^^^^^

And this looks like a pretty major fail. Why is the 3D LUT stored in
the *plane* state when it's a pipe level thing?

-- 
Ville Syrjälä
Intel

Reply via email to