[Intel-gfx] [PATCH 19/20] drm/i915: Complete the gamma/degamma state checking

Shankar, Uma uma.shankar at intel.com
Thu Sep 17 21:52:20 UTC 2020



> -----Original Message-----
> From: Intel-gfx <intel-gfx-bounces at lists.freedesktop.org> On Behalf Of Ville
> Syrjala
> Sent: Saturday, July 18, 2020 2:44 AM
> To: intel-gfx at lists.freedesktop.org
> Subject: [Intel-gfx] [PATCH 19/20] drm/i915: Complete the gamma/degamma
> state checking
> 
> From: Ville Syrjälä <ville.syrjala at linux.intel.com>
> 
> 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 <uma.shankar at intel.com>

> Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
> ---
>  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
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx


More information about the Intel-gfx mailing list