> -----Original Message-----
> From: Intel-gfx <[email protected]> On Behalf Of Ville
> Syrjala
> Sent: Saturday, July 18, 2020 2:44 AM
> To: [email protected]
> Subject: [Intel-gfx] [PATCH 19/20] drm/i915: Complete the gamma/degamma
> state checking
> 
> From: Ville Syrjälä <[email protected]>
> 
> Add new .gamma_equal() and .degamma_equal() vfuncs to be used by the state
> checker to verify the gamma/degamma LUTs. We need somewhat custom
> behaviour for some platforms due to sometimes swapping the roles of the
> gamma and degamma LUTs (due to RGB limited color range or YCbCr output CSC
> usage). Also glk has a special relationship between the CSC enable bit and the
> degamma LUT so it also needs customized behaviour.
> 
> We could pontially compute the state in a better way to make these state check
> hacks unnecessary, but that's going to require some actual thought so we'll 
> leave
> it for the future.

Like the idea of how the anomalies of various platforms are balanced.
Reviewed-by: Uma Shankar <[email protected]>

> Signed-off-by: Ville Syrjälä <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_color.c   | 435 +++++++++++++++----
>  drivers/gpu/drm/i915/display/intel_color.h   |  10 +-
>  drivers/gpu/drm/i915/display/intel_display.c |  25 +-
>  drivers/gpu/drm/i915/i915_drv.h              |   7 +
>  4 files changed, 378 insertions(+), 99 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_color.c
> b/drivers/gpu/drm/i915/display/intel_color.c
> index f714c87d8e42..ca6c6679368c 100644
> --- a/drivers/gpu/drm/i915/display/intel_color.c
> +++ b/drivers/gpu/drm/i915/display/intel_color.c
> @@ -1628,26 +1628,71 @@ static int i9xx_gamma_precision(const struct
> intel_crtc_state *crtc_state)
>       }
>  }
> 
> +static bool ilk_crtc_has_degamma(const struct intel_crtc_state
> +*crtc_state) {
> +     return crtc_state->gamma_enable &&
> +             (crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0; }
> +
>  static bool ilk_crtc_has_gamma(const struct intel_crtc_state *crtc_state)  {
>       return crtc_state->gamma_enable &&
>               (crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) != 0;  }
> 
> +static int ilk_lut_precision(const struct intel_crtc_state *crtc_state)
> +{
> +     switch (crtc_state->gamma_mode) {
> +     case GAMMA_MODE_MODE_8BIT:
> +             return 8;
> +     case GAMMA_MODE_MODE_10BIT:
> +             return 10;
> +     default:
> +             MISSING_CASE(crtc_state->gamma_mode);
> +             return 0;
> +     }
> +}
> +
> +static int ilk_degamma_precision(const struct intel_crtc_state
> +*crtc_state) {
> +     if (ilk_crtc_has_degamma(crtc_state))
> +             return ilk_lut_precision(crtc_state);
> +     else
> +             return 0;
> +}
> +
>  static int ilk_gamma_precision(const struct intel_crtc_state *crtc_state)  {
> -     if (!ilk_crtc_has_gamma(crtc_state))
> +     if (ilk_crtc_has_gamma(crtc_state))
> +             return ilk_lut_precision(crtc_state);
> +     else
>               return 0;
> +}
> 
> -     switch (crtc_state->gamma_mode) {
> -     case GAMMA_MODE_MODE_8BIT:
> -             return 8;
> -     case GAMMA_MODE_MODE_10BIT:
> +static int ivb_degamma_precision(const struct intel_crtc_state
> +*crtc_state) {
> +     if (crtc_state->gamma_enable &&
> +         crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
>               return 10;
> -     default:
> -             MISSING_CASE(crtc_state->gamma_mode);
> +     else
> +             return ilk_degamma_precision(crtc_state);
> +}
> +
> +static int ivb_gamma_precision(const struct intel_crtc_state
> +*crtc_state) {
> +     if (crtc_state->gamma_enable &&
> +         crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
> +             return 10;
> +     else
> +             return ilk_gamma_precision(crtc_state); }
> +
> +static int chv_degamma_precision(const struct intel_crtc_state
> +*crtc_state) {
> +     if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
> +             return 14;
> +     else
>               return 0;
> -     }
>  }
> 
>  static int chv_gamma_precision(const struct intel_crtc_state *crtc_state) @@ 
> -
> 1658,20 +1703,20 @@ static int chv_gamma_precision(const struct
> intel_crtc_state *crtc_state)
>               return i9xx_gamma_precision(crtc_state);  }
> 
> +static int glk_degamma_precision(const struct intel_crtc_state
> +*crtc_state) {
> +     if (crtc_state->csc_enable)
> +             return 16;
> +     else
> +             return 0;
> +}
> +
>  static int glk_gamma_precision(const struct intel_crtc_state *crtc_state)  {
> -     if (!crtc_state->gamma_enable)
> +     if (crtc_state->gamma_enable)
> +             return ilk_lut_precision(crtc_state);
> +     else
>               return 0;
> -
> -     switch (crtc_state->gamma_mode) {
> -     case GAMMA_MODE_MODE_8BIT:
> -             return 8;
> -     case GAMMA_MODE_MODE_10BIT:
> -             return 10;
> -     default:
> -             MISSING_CASE(crtc_state->gamma_mode);
> -             return 0;
> -     }
>  }
> 
>  static bool icl_crtc_has_degamma(const struct intel_crtc_state *crtc_state) 
> @@ -
> 1684,6 +1729,14 @@ static bool icl_crtc_has_gamma(const struct 
> intel_crtc_state
> *crtc_state)
>       return crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE;  }
> 
> +static int icl_degamma_precision(const struct intel_crtc_state
> +*crtc_state) {
> +     if (icl_crtc_has_degamma(crtc_state))
> +             return 16;
> +     else
> +             return 0;
> +}
> +
>  static int icl_gamma_precision(const struct intel_crtc_state *crtc_state)  {
>       if (!icl_crtc_has_gamma(crtc_state))
> @@ -1702,97 +1755,310 @@ static int icl_gamma_precision(const struct
> intel_crtc_state *crtc_state)
>       }
>  }
> 
> -int intel_color_get_gamma_bit_precision(const struct intel_crtc_state
> *crtc_state) -{
> -     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> -
> -     if (HAS_GMCH(dev_priv)) {
> -             if (IS_CHERRYVIEW(dev_priv))
> -                     return chv_gamma_precision(crtc_state);
> -             else
> -                     return i9xx_gamma_precision(crtc_state);
> -     } else {
> -             if (INTEL_GEN(dev_priv) >= 11)
> -                     return icl_gamma_precision(crtc_state);
> -             else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
> -                     return glk_gamma_precision(crtc_state);
> -             else if (IS_IRONLAKE(dev_priv))
> -                     return ilk_gamma_precision(crtc_state);
> -     }
> -
> -     return 0;
> -}
> -
> -static bool err_check(struct drm_color_lut *lut1,
> -                   struct drm_color_lut *lut2, u32 err)
> +static bool lut_entry_equal(const struct drm_color_lut *lut1,
> +                         const struct drm_color_lut *lut2, u32 err)
>  {
>       return ((abs((long)lut2->red - lut1->red)) <= err) &&
>               ((abs((long)lut2->blue - lut1->blue)) <= err) &&
>               ((abs((long)lut2->green - lut1->green)) <= err);  }
> 
> -static bool intel_color_lut_entries_equal(struct drm_color_lut *lut1,
> -                                       struct drm_color_lut *lut2,
> -                                       int lut_size, u32 err)
> +static int intel_color_lut_size(const struct drm_property_blob *blob)
>  {
> -     int i;
> +     return blob ? drm_color_lut_size(blob) : 0; }
> +
> +static bool intel_color_lut_sizes_equal(const struct drm_property_blob 
> *blob1,
> +                                     const struct drm_property_blob *blob2) {
> +     return intel_color_lut_size(blob1) == intel_color_lut_size(blob2); }
> +
> +static bool intel_lut_equal(const struct drm_property_blob *blob1,
> +                         const struct drm_property_blob *blob2,
> +                         int bit_precision)
> +{
> +     const struct drm_color_lut *lut1, *lut2;
> +     int i, lut_size;
> +
> +     if (!intel_color_lut_sizes_equal(blob1, blob2))
> +             return false;
> +
> +     if (!blob1)
> +             return true;
> +
> +     if (!bit_precision)
> +             return false;
> +
> +     lut_size = drm_color_lut_size(blob1);
> +     lut1 = blob1->data;
> +     lut2 = blob2->data;
> 
>       for (i = 0; i < lut_size; i++) {
> -             if (!err_check(&lut1[i], &lut2[i], err))
> +             if (!lut_entry_equal(&lut1[i], &lut2[i],
> +                                  0xffff >> bit_precision))
>                       return false;
>       }
> 
>       return true;
>  }
> 
> -bool intel_color_lut_equal(struct drm_property_blob *blob1,
> -                        struct drm_property_blob *blob2,
> -                        u32 gamma_mode, u32 bit_precision)
> +static bool i9xx_degamma_equal(const struct intel_crtc_state *crtc_state1,
> +                            const struct intel_crtc_state *crtc_state2,
> +                            bool fastset)
>  {
> -     struct drm_color_lut *lut1, *lut2;
> -     int lut_size1, lut_size2;
> -     u32 err;
> +     const struct drm_property_blob *degamma_lut1 = crtc_state1-
> >hw.degamma_lut;
> +     const struct drm_property_blob *degamma_lut2 =
> +crtc_state2->hw.degamma_lut;
> 
> -     if (!blob1 != !blob2)
> +     /* no degamma */
> +     return !degamma_lut1 && !degamma_lut2; }
> +
> +static bool i9xx_gamma_equal(const struct intel_crtc_state *crtc_state1,
> +                          const struct intel_crtc_state *crtc_state2,
> +                          bool fastset)
> +{
> +     const struct drm_property_blob *gamma_lut1 = crtc_state1-
> >hw.gamma_lut;
> +     const struct drm_property_blob *gamma_lut2 =
> +crtc_state2->hw.gamma_lut;
> +
> +     return intel_lut_equal(gamma_lut1, gamma_lut2,
> +                            i9xx_gamma_precision(crtc_state1));
> +}
> +
> +static bool chv_degamma_equal(const struct intel_crtc_state *crtc_state1,
> +                           const struct intel_crtc_state *crtc_state2,
> +                           bool fastset)
> +{
> +     const struct drm_property_blob *degamma_lut1 = crtc_state1-
> >hw.degamma_lut;
> +     const struct drm_property_blob *degamma_lut2 =
> +crtc_state2->hw.degamma_lut;
> +
> +     return intel_lut_equal(degamma_lut1, degamma_lut2,
> +                            chv_degamma_precision(crtc_state1));
> +}
> +
> +static bool chv_gamma_equal(const struct intel_crtc_state *crtc_state1,
> +                         const struct intel_crtc_state *crtc_state2,
> +                         bool fastset)
> +{
> +     const struct drm_property_blob *gamma_lut1 = crtc_state1-
> >hw.gamma_lut;
> +     const struct drm_property_blob *gamma_lut2 =
> +crtc_state2->hw.gamma_lut;
> +
> +     return intel_lut_equal(gamma_lut1, gamma_lut2,
> +                            chv_gamma_precision(crtc_state1));
> +}
> +
> +static bool ilk_degamma_equal(const struct intel_crtc_state *crtc_state1,
> +                           const struct intel_crtc_state *crtc_state2,
> +                           bool fastset)
> +{
> +     const struct drm_property_blob *degamma_lut1 = crtc_state2-
> >hw.degamma_lut;
> +     const struct drm_property_blob *degamma_lut2 =
> +crtc_state2->hw.degamma_lut;
> +
> +     if (!fastset) {
> +             const struct drm_property_blob *gamma_lut2 =
> +crtc_state2->hw.gamma_lut;
> +
> +             /*
> +              * For readout crtc_state1 is the software state,
> +              * crtc_state2 is the hardware state.
> +              *
> +              * On ILK-BDW the single LUT may appear before or after the
> +              * CSC due to various reasons. Readout does not know whether
> +              * the user supplied it as a gamma LUT or degamma LUT. If the
> +              * software and hardware states look inconsistent assume
> +              * readout got things the wrong way around.
> +              *
> +              * FIXME think about assigning these consistently from the
> hardware
> +              * POV already when computing the state. Would avoid this
> hideous
> +              * hack, but possibly not entirely trivial to do since we 
> currently
> +              * just blindly copy those from the uapi state.
> +              */
> +             if (!!degamma_lut1 != !!degamma_lut2)
> +                     swap(gamma_lut2, degamma_lut2);
> +     }
> +
> +     return intel_lut_equal(degamma_lut1, degamma_lut2,
> +                            ilk_degamma_precision(crtc_state1));
> +}
> +
> +static bool ilk_gamma_equal(const struct intel_crtc_state *crtc_state1,
> +                         const struct intel_crtc_state *crtc_state2,
> +                         bool fastset)
> +{
> +     const struct drm_property_blob *gamma_lut1 = crtc_state1-
> >hw.gamma_lut;
> +     const struct drm_property_blob *gamma_lut2 =
> +crtc_state2->hw.gamma_lut;
> +
> +     if (!fastset) {
> +             const struct drm_property_blob *degamma_lut2 =
> +crtc_state2->hw.degamma_lut;
> +
> +             /*
> +              * For readout crtc_state1 is the software state,
> +              * crtc_state2 is the hardware state.
> +              *
> +              * On ILK-BDW the single LUT may appear before or after the
> +              * CSC due to various reasons. Readout does not know whether
> +              * the user supplied it as a gamma LUT or degamma LUT. If the
> +              * software and hardware states look inconsistent assume
> +              * readout got things the wrong way around.
> +              *
> +              * FIXME think about assigning these consistently from the
> hardware
> +              * POV already when computing the state. Would avoid this
> hideous
> +              * hack, but possibly not entirely trivial to do since we 
> currently
> +              * just blindly copy those from the uapi state.
> +              */
> +             if (!!gamma_lut1 != !!gamma_lut2)
> +                     swap(gamma_lut2, degamma_lut2);
> +     }
> +
> +     return intel_lut_equal(gamma_lut1, gamma_lut2,
> +                            ilk_gamma_precision(crtc_state1));
> +}
> +
> +static bool ivb_lut_split_equal(const struct drm_property_blob *blob1,
> +                             const struct drm_property_blob *blob2,
> +                             int bit_precision)
> +{
> +     const struct drm_color_lut *lut1, *lut2;
> +     int i, lut_size, hw_lut_size;
> +
> +     if (!intel_color_lut_sizes_equal(blob1, blob2))
>               return false;
> 
>       if (!blob1)
>               return true;
> 
> -     lut_size1 = drm_color_lut_size(blob1);
> -     lut_size2 = drm_color_lut_size(blob2);
> -
> -     /* check sw and hw lut size */
> -     if (lut_size1 != lut_size2)
> +     if (!bit_precision)
>               return false;
> 
> +     lut_size = drm_color_lut_size(blob1);
> +     hw_lut_size = ivb_lut_10_size(PAL_PREC_SPLIT_MODE);
>       lut1 = blob1->data;
>       lut2 = blob2->data;
> 
> -     err = 0xffff >> bit_precision;
> +     for (i = 0; i < hw_lut_size; i++) {
> +             /* We discard half the user entries in split gamma mode */
> +             const struct drm_color_lut *entry1 =
> +                     &lut1[i * (lut_size - 1) / (hw_lut_size - 1)];
> +             const struct drm_color_lut *entry2 =
> +                     &lut2[i * (lut_size - 1) / (hw_lut_size - 1)];
> 
> -     /* check sw and hw lut entry to be equal */
> -     switch (gamma_mode & GAMMA_MODE_MODE_MASK) {
> -     case GAMMA_MODE_MODE_8BIT:
> -     case GAMMA_MODE_MODE_10BIT:
> -             if (!intel_color_lut_entries_equal(lut1, lut2,
> -                                                lut_size2, err))
> +             if (!lut_entry_equal(entry1, entry2, 0xffff >> bit_precision))
>                       return false;
> -             break;
> -     case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
> -             if (!intel_color_lut_entries_equal(lut1, lut2,
> -                                                9, err))
> -                     return false;
> -             break;
> -     default:
> -             MISSING_CASE(gamma_mode);
> -             return false;
>       }
> 
>       return true;
>  }
> 
> +static bool ivb_degamma_equal(const struct intel_crtc_state *crtc_state1,
> +                           const struct intel_crtc_state *crtc_state2,
> +                           bool fastset)
> +{
> +     if (crtc_state1->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
> +             const struct drm_property_blob *degamma_lut1 = crtc_state1-
> >hw.degamma_lut;
> +             const struct drm_property_blob *degamma_lut2 =
> +crtc_state2->hw.degamma_lut;
> +
> +             return ivb_lut_split_equal(degamma_lut1, degamma_lut2,
> +                                        ivb_degamma_precision(crtc_state1));
> +     } else {
> +             return ilk_degamma_equal(crtc_state1, crtc_state2, fastset);
> +     }
> +}
> +
> +static bool ivb_gamma_equal(const struct intel_crtc_state *crtc_state1,
> +                         const struct intel_crtc_state *crtc_state2,
> +                         bool fastset)
> +{
> +     if (crtc_state1->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
> +             const struct drm_property_blob *gamma_lut1 = crtc_state1-
> >hw.gamma_lut;
> +             const struct drm_property_blob *gamma_lut2 =
> +crtc_state2->hw.gamma_lut;
> +
> +             return ivb_lut_split_equal(gamma_lut1, gamma_lut2,
> +                                        ivb_gamma_precision(crtc_state1));
> +     } else {
> +             return ilk_gamma_equal(crtc_state1, crtc_state2, fastset);
> +     }
> +}
> +
> +static bool glk_degamma_equal(const struct intel_crtc_state *crtc_state1,
> +                           const struct intel_crtc_state *crtc_state2,
> +                           bool fastset)
> +{
> +     const struct drm_property_blob *degamma_lut1 = crtc_state1-
> >hw.degamma_lut;
> +     const struct drm_property_blob *degamma_lut2 =
> +crtc_state2->hw.degamma_lut;
> +
> +     if (!fastset) {
> +             /*
> +              * For readout crtc_state1 is the software state,
> +              * crtc_state2 is the hardware state.
> +              *
> +              * Readout can't tell the difference between an actual
> +              * degamma LUT and the linear degamma LUT we have to load
> +              * whenever the pipe CSC is active. Ignore the hardware
> +              * degamma LUT when we don't have a software degamma LUT.
> +              *
> +              * FIXME think about assigning an internal linear lut already
> +              * when computing the state. Would avoid this hideous hack,
> +              * but possibly not entirely trivial to do since we currently
> +              * just blindly copy this from the uapi state.
> +              */
> +             if (!degamma_lut1)
> +                     degamma_lut2 = NULL;
> +     }
> +
> +     return intel_lut_equal(degamma_lut1, degamma_lut2,
> +                            glk_degamma_precision(crtc_state1));
> +}
> +
> +static bool glk_gamma_equal(const struct intel_crtc_state *crtc_state1,
> +                         const struct intel_crtc_state *crtc_state2,
> +                         bool fastset)
> +{
> +     const struct drm_property_blob *gamma_lut1 = crtc_state1-
> >hw.gamma_lut;
> +     const struct drm_property_blob *gamma_lut2 =
> +crtc_state2->hw.gamma_lut;
> +
> +     return intel_lut_equal(gamma_lut1, gamma_lut2,
> +                            glk_gamma_precision(crtc_state1));
> +}
> +
> +static bool icl_degamma_equal(const struct intel_crtc_state *crtc_state1,
> +                           const struct intel_crtc_state *crtc_state2,
> +                           bool fastset)
> +{
> +     const struct drm_property_blob *degamma_lut1 = crtc_state1-
> >hw.degamma_lut;
> +     const struct drm_property_blob *degamma_lut2 =
> +crtc_state2->hw.degamma_lut;
> +
> +     return intel_lut_equal(degamma_lut1, degamma_lut2,
> +                            icl_degamma_precision(crtc_state1));
> +}
> +
> +static bool icl_gamma_equal(const struct intel_crtc_state *crtc_state1,
> +                         const struct intel_crtc_state *crtc_state2,
> +                         bool fastset)
> +{
> +     const struct drm_property_blob *gamma_lut1 = crtc_state1-
> >hw.gamma_lut;
> +     const struct drm_property_blob *gamma_lut2 =
> +crtc_state2->hw.gamma_lut;
> +
> +     return intel_lut_equal(gamma_lut1, gamma_lut2,
> +                            icl_gamma_precision(crtc_state1));
> +}
> +
> +bool intel_color_degamma_lut_equal(const struct intel_crtc_state 
> *crtc_state1,
> +                                const struct intel_crtc_state *crtc_state2,
> +                                bool fastset)
> +{
> +     struct drm_i915_private *dev_priv =
> +to_i915(crtc_state1->uapi.crtc->dev);
> +
> +     return dev_priv->display.degamma_equal(crtc_state1, crtc_state2,
> +fastset); }
> +
> +bool intel_color_gamma_lut_equal(const struct intel_crtc_state *crtc_state1,
> +                              const struct intel_crtc_state *crtc_state2,
> +                              bool fastset)
> +{
> +     struct drm_i915_private *dev_priv =
> +to_i915(crtc_state1->uapi.crtc->dev);
> +
> +     return dev_priv->display.gamma_equal(crtc_state1, crtc_state2,
> +fastset); }
> +
>  static struct drm_property_blob *i9xx_read_lut_8(struct intel_crtc *crtc)  {
>       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); @@ -
> 2289,16 +2555,22 @@ void intel_color_init(struct intel_crtc *crtc)
>                       dev_priv->display.color_commit = i9xx_color_commit;
>                       dev_priv->display.load_luts = chv_load_luts;
>                       dev_priv->display.read_luts = chv_read_luts;
> +                     dev_priv->display.gamma_equal = chv_gamma_equal;
> +                     dev_priv->display.degamma_equal =
> chv_degamma_equal;
>               } else if (INTEL_GEN(dev_priv) >= 4) {
>                       dev_priv->display.color_check = i9xx_color_check;
>                       dev_priv->display.color_commit = i9xx_color_commit;
>                       dev_priv->display.load_luts = i965_load_luts;
>                       dev_priv->display.read_luts = i965_read_luts;
> +                     dev_priv->display.gamma_equal = i9xx_gamma_equal;
> +                     dev_priv->display.degamma_equal =
> i9xx_degamma_equal;
>               } else {
>                       dev_priv->display.color_check = i9xx_color_check;
>                       dev_priv->display.color_commit = i9xx_color_commit;
>                       dev_priv->display.load_luts = i9xx_load_luts;
>                       dev_priv->display.read_luts = i9xx_read_luts;
> +                     dev_priv->display.gamma_equal = i9xx_gamma_equal;
> +                     dev_priv->display.degamma_equal =
> i9xx_degamma_equal;
>               }
>       } else {
>               if (INTEL_GEN(dev_priv) >= 11)
> @@ -2320,19 +2592,30 @@ void intel_color_init(struct intel_crtc *crtc)
>               if (INTEL_GEN(dev_priv) >= 11) {
>                       dev_priv->display.load_luts = icl_load_luts;
>                       dev_priv->display.read_luts = icl_read_luts;
> +                     dev_priv->display.gamma_equal = icl_gamma_equal;
> +                     dev_priv->display.degamma_equal = icl_degamma_equal;
>               } else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
> {
>                       dev_priv->display.load_luts = glk_load_luts;
>                       dev_priv->display.read_luts = glk_read_luts;
> +                     dev_priv->display.gamma_equal = glk_gamma_equal;
> +                     dev_priv->display.degamma_equal =
> glk_degamma_equal;
>               } else if (INTEL_GEN(dev_priv) >= 8) {
>                       dev_priv->display.load_luts = bdw_load_luts;
>                       dev_priv->display.read_luts = bdw_read_luts;
> +                     dev_priv->display.gamma_equal = ivb_gamma_equal;
> +                     dev_priv->display.degamma_equal =
> ivb_degamma_equal;
>               } else if (INTEL_GEN(dev_priv) >= 7) {
>                       dev_priv->display.load_luts = ivb_load_luts;
>                       dev_priv->display.read_luts = ivb_read_luts;
> +                     dev_priv->display.gamma_equal = ivb_gamma_equal;
> +                     dev_priv->display.degamma_equal =
> ivb_degamma_equal;
>               } else {
>                       dev_priv->display.load_luts = ilk_load_luts;
>                       dev_priv->display.read_luts = ilk_read_luts;
> +                     dev_priv->display.gamma_equal = ilk_gamma_equal;
> +                     dev_priv->display.degamma_equal =
> ilk_degamma_equal;
>               }
> +
>       }
> 
>       drm_crtc_enable_color_mgmt(&crtc->base,
> diff --git a/drivers/gpu/drm/i915/display/intel_color.h
> b/drivers/gpu/drm/i915/display/intel_color.h
> index 173727aaa24d..079ea90c22c8 100644
> --- a/drivers/gpu/drm/i915/display/intel_color.h
> +++ b/drivers/gpu/drm/i915/display/intel_color.h
> @@ -17,9 +17,11 @@ int intel_color_check(struct intel_crtc_state *crtc_state);
> void intel_color_commit(const struct intel_crtc_state *crtc_state);  void
> intel_color_load_luts(const struct intel_crtc_state *crtc_state);  void
> intel_color_get_config(struct intel_crtc_state *crtc_state); -int
> intel_color_get_gamma_bit_precision(const struct intel_crtc_state 
> *crtc_state); -
> bool intel_color_lut_equal(struct drm_property_blob *blob1,
> -                        struct drm_property_blob *blob2,
> -                        u32 gamma_mode, u32 bit_precision);
> +bool intel_color_gamma_lut_equal(const struct intel_crtc_state *crtc_state1,
> +                              const struct intel_crtc_state *crtc_state2,
> +                              bool fastset);
> +bool intel_color_degamma_lut_equal(const struct intel_crtc_state 
> *crtc_state1,
> +                                const struct intel_crtc_state *crtc_state2,
> +                                bool fastset);
> 
>  #endif /* __INTEL_COLOR_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 9279df7757fc..e80b4cd8eea1 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -13635,7 +13635,6 @@ intel_pipe_config_compare(const struct
> intel_crtc_state *current_config,
>       struct drm_i915_private *dev_priv = to_i915(current_config->uapi.crtc-
> >dev);
>       struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
>       bool ret = true;
> -     u32 bp_gamma = 0;
>       bool fixup_inherited = fastset &&
>               current_config->inherited && !pipe_config->inherited;
> 
> @@ -13798,21 +13797,10 @@ intel_pipe_config_compare(const struct
> intel_crtc_state *current_config,
>       } \
>  } while (0)
> 
> -#define PIPE_CONF_CHECK_COLOR_LUT(name1, name2, bit_precision) do { \
> -     if (current_config->name1 != pipe_config->name1) { \
> -             pipe_config_mismatch(fastset, crtc, __stringify(name1), \
> -                             "(expected %i, found %i, won't compare lut
> values)", \
> -                             current_config->name1, \
> -                             pipe_config->name1); \
> -             ret = false;\
> -     } else { \
> -             if (!intel_color_lut_equal(current_config->name2, \
> -                                     pipe_config->name2, pipe_config-
> >name1, \
> -                                     bit_precision)) { \
> -                     pipe_config_mismatch(fastset, crtc, __stringify(name2), 
> \
> -                                     "hw_state doesn't match sw_state"); \
> -                     ret = false; \
> -             } \
> +#define PIPE_CONF_CHECK_COLOR_LUT(name) do { \
> +     if (!intel_color_##name##_equal(current_config, pipe_config, fastset)) 
> { \
> +             pipe_config_mismatch(fastset, crtc, "hw." __stringify(name), " 
> ");
> \
> +             ret = false; \
>       } \
>  } while (0)
> 
> @@ -13918,9 +13906,8 @@ intel_pipe_config_compare(const struct
> intel_crtc_state *current_config,
>               PIPE_CONF_CHECK_I(linetime);
>               PIPE_CONF_CHECK_I(ips_linetime);
> 
> -             bp_gamma = intel_color_get_gamma_bit_precision(pipe_config);
> -             if (bp_gamma)
> -                     PIPE_CONF_CHECK_COLOR_LUT(gamma_mode,
> hw.gamma_lut, bp_gamma);
> +             PIPE_CONF_CHECK_COLOR_LUT(gamma_lut);
> +             PIPE_CONF_CHECK_COLOR_LUT(degamma_lut);
>       }
> 
>       PIPE_CONF_CHECK_BOOL(double_wide);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index e4f7f6518945..54d224be256a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -256,6 +256,7 @@ struct sdvo_device_mapping {
>       u8 ddc_pin;
>  };
> 
> +struct drm_property_blob;
>  struct intel_connector;
>  struct intel_encoder;
>  struct intel_atomic_state;
> @@ -334,6 +335,12 @@ struct drm_i915_display_funcs {
>        */
>       void (*load_luts)(const struct intel_crtc_state *crtc_state);
>       void (*read_luts)(struct intel_crtc_state *crtc_state);
> +     bool (*gamma_equal)(const struct intel_crtc_state *crtc_state1,
> +                         const struct intel_crtc_state *crtc_state2,
> +                         bool fastset);
> +     bool (*degamma_equal)(const struct intel_crtc_state *crtc_state1,
> +                           const struct intel_crtc_state *crtc_state2,
> +                           bool fastset);
>  };
> 
>  struct intel_csr {
> --
> 2.26.2
> 
> _______________________________________________
> Intel-gfx mailing list
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to