[PATCH v2 10/10] drm/i915: Add CSC support for CHV/BSW

Damien Lespiau damien.lespiau at intel.com
Tue Jun 9 04:55:58 PDT 2015


On Thu, Jun 04, 2015 at 07:12:41PM +0530, Kausal Malladi wrote:
> From: Kausal Malladi <Kausal.Malladi at intel.com>
> 
> This patch does the following:
> 1. Adds the core function to program CSC correction values for
>    CHV/BSW platform
> 2. Adds CSC correction macros/defines
> 3. Adds a pointer to hold blob for CSC property in drm_crtc
> 
> Signed-off-by: Shashank Sharma <shashank.sharma at intel.com>
> Signed-off-by: Kausal Malladi <Kausal.Malladi at intel.com>
> ---
>  drivers/gpu/drm/i915/intel_atomic.c        |   3 +-
>  drivers/gpu/drm/i915/intel_color_manager.c | 115 +++++++++++++++++++++++++++++
>  drivers/gpu/drm/i915/intel_color_manager.h |  26 +++++++
>  3 files changed, 143 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> index 4726847..dcf4694 100644
> --- a/drivers/gpu/drm/i915/intel_atomic.c
> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> @@ -433,7 +433,8 @@ intel_crtc_atomic_set_property(struct drm_crtc *crtc,
>  
>  	if (property == config->gamma_property)
>  		return intel_color_manager_set_gamma(dev, &crtc->base, val);
> +	if (property == config->csc_property)
> +		return intel_color_manager_set_csc(dev, &crtc->base, val);
>  
> -	DRM_DEBUG_KMS("Unknown crtc property '%s'\n", property->name);
>  	return -EINVAL;
>  }
> diff --git a/drivers/gpu/drm/i915/intel_color_manager.c b/drivers/gpu/drm/i915/intel_color_manager.c
> index 421c267..d904050 100644
> --- a/drivers/gpu/drm/i915/intel_color_manager.c
> +++ b/drivers/gpu/drm/i915/intel_color_manager.c
> @@ -27,6 +27,108 @@
>  
>  #include "intel_color_manager.h"
>  
> +int chv_set_csc(struct drm_device *dev, uint64_t blob_id,
> +		struct drm_crtc *crtc)
> +{
> +	struct drm_csc *csc_data;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct drm_property_blob *blob;
> +	struct drm_mode_config *config = &dev->mode_config;
> +	u32 reg;
> +	enum pipe pipe;
> +	s16 csc_value;
> +	s32 word, temp;
> +	int ret, count = 0;
> +
> +	blob = drm_property_lookup_blob(dev, blob_id);
> +	if (!blob) {
> +		DRM_ERROR("Invalid Blob ID\n");
> +		return -EINVAL;
> +	}
> +
> +	csc_data = (struct drm_csc *)blob->data;
> +	pipe = to_intel_crtc(crtc)->pipe;
> +
> +	if (csc_data->csc_format == I915_CSC_COEFF_FORMAT_UNKNOWN) {
> +
> +		/* Disable CSC functionality */
> +		reg = _PIPE_CGM_CONTROL(pipe);
> +		I915_WRITE(reg, I915_READ(reg) & (~CGM_CSC_EN));
> +
> +		DRM_DEBUG_DRIVER("Disabled CSC Functionality on Pipe %c\n",
> +				pipe_name(pipe));
> +		ret = 0;

Same remarks here I did for the gamma property. i915 specific defines
for an interface that looks like it want to be generic, UNKNOWN Vs
DISABLED, DRM_ERROR, ...

And I haven't actually looked at the CHV details in this pass.

> +	} else if (csc_data->csc_format == I915_CSC_COEFF_FORMAT_S2_29) {
> +
> +		/* Disable CSC functionality in case it was set earlier */
> +		reg = _PIPE_CGM_CONTROL(pipe);
> +		I915_WRITE(reg, I915_READ(reg) & (~CGM_CSC_EN));
> +
> +		DRM_DEBUG_DRIVER("Disabled CSC Functionality on Pipe %c\n",
> +				pipe_name(pipe));
> +
> +		reg = _PIPE_CSC_BASE(pipe);
> +		while (count < CSC_MAX_VALS) {
> +
> +			/* Rounding off, to decrease loss of precision */
> +			if (csc_data->csc_matrix[count] < 0) {
> +				temp = csc_data->csc_matrix[count];
> +				temp -= CHV_CSC_ROUNDOFF;
> +				if (temp < CHV_CSC_MIN)
> +					temp = CHV_CSC_MIN;
> +			} else {
> +				temp = csc_data->csc_matrix[count];
> +				temp += CHV_CSC_ROUNDOFF;
> +				if (temp > CHV_CSC_MAX)
> +					temp = CHV_CSC_MIN;
> +			}
> +			csc_value = temp >> S2_29_CSC_COEFF_SHIFT;
> +			word = csc_value;
> +
> +			/*
> +			 * Last value to be written in 1 register.
> +			 * Otherwise, each pair of CSC values go
> +			 * into 1 register
> +			 */
> +			if (count != (CSC_MAX_VALS - 1)) {
> +				count++;
> +				csc_value = temp >> S2_29_CSC_COEFF_SHIFT;
> +				temp = csc_value;
> +				temp <<= CHV_CSC_SHIFT;
> +				word |= temp;
> +			}
> +			I915_WRITE(reg, word);
> +			reg += 4;
> +			count++;
> +		}
> +
> +		DRM_DEBUG_DRIVER("All CSC values written to registers\n");
> +
> +		/* Enable CSC functionality */
> +		reg = _PIPE_CGM_CONTROL(pipe);
> +		I915_WRITE(reg, I915_READ(reg) | CGM_CSC_EN);
> +		DRM_DEBUG_DRIVER("CSC enabled on Pipe %c\n",
> +				pipe_name(pipe));
> +		ret = 0;
> +	} else {
> +		DRM_ERROR("Invalid CSC COEFF Format\n");
> +		return -EINVAL;
> +	}
> +
> +	ret = drm_mode_crtc_update_color_property(&blob,
> +			sizeof(struct drm_csc), (void *) csc_data,
> +			&crtc->base, config->csc_property);
> +	if (ret) {
> +		DRM_ERROR("Error updating CSC blob\n");
> +		crtc->csc_blob_id = INVALID_BLOB_ID;
> +		return -EFAULT;
> +	}
> +
> +	/* Save blob ID for future reference */
> +	crtc->csc_blob_id = blob->base.id;
> +	return ret;
> +}
> +
>  int chv_set_gamma(struct drm_device *dev, uint32_t blob_id,
>  		struct drm_crtc *crtc)
>  {
> @@ -175,6 +277,19 @@ int chv_set_gamma(struct drm_device *dev, uint32_t blob_id,
>  	return ret;
>  }
>  
> +int intel_color_manager_set_csc(struct drm_device *dev,
> +		struct drm_mode_object *obj, uint64_t blob_id)
> +{
> +	struct drm_crtc *crtc = obj_to_crtc(obj);
> +
> +	DRM_DEBUG_DRIVER("\n");
> +
> +	if (IS_CHERRYVIEW(dev))
> +		return chv_set_csc(dev, blob_id, crtc);
> +
> +	return -EINVAL;
> +}
> +
>  int intel_color_manager_set_gamma(struct drm_device *dev,
>  		struct drm_mode_object *obj, uint32_t blob_id)
>  {
> diff --git a/drivers/gpu/drm/i915/intel_color_manager.h b/drivers/gpu/drm/i915/intel_color_manager.h
> index 0acf8e9..8a3e76a 100644
> --- a/drivers/gpu/drm/i915/intel_color_manager.h
> +++ b/drivers/gpu/drm/i915/intel_color_manager.h
> @@ -41,6 +41,14 @@
>  #define I915_GAMMA_PRECISION_14BIT		(1 << 3)
>  #define I915_GAMMA_PRECISION_16BIT		(1 << 4)
>  
> +/* Color Management macros for CSC */
> +#define I915_PIPE_CSC				(1 << 0)
> +#define I915_PLANE_CSC				(1 << 1)
> +#define I915_CSC_COEFF_FORMAT_UNKNOWN		0
> +#define I915_CSC_COEFF_FORMAT_CURRENT		0xFFFFFFFF
> +#define I915_CSC_COEFF_FORMAT_S1_30		(1 << 0)
> +#define I915_CSC_COEFF_FORMAT_S2_29		(1 << 1)
> +
>  #define CHV_MAX_PIPES				3
>  #define CHV_DISPLAY_BASE			0x180000
>  #define INVALID_BLOB_ID				9999
> @@ -52,6 +60,8 @@ struct rgb_pixel {
>  };
>  
>  /* CHV CGM Block */
> +/* Bit 1 to be enabled */
> +#define CGM_CSC_EN				2
>  /* Bit 2 to be enabled in CGM block for CHV */
>  #define CGM_GAMMA_EN				4
>  
> @@ -74,15 +84,27 @@ struct rgb_pixel {
>  #define CHV_8BIT_GAMMA_SHIFT_GREEN_REG		8
>  #define CHV_8BIT_GAMMA_SHIFT_RED_REG		16
>  
> +/* CSC */
> +#define CSC_MAX_VALS				9
> +#define CHV_CSC_SHIFT				16
> +#define CHV_CSC_ROUNDOFF			(1 << 15)
> +#define CHV_CSC_MAX				0x7FFF
> +#define CHV_CSC_MIN				0x8000
> +#define S2_29_CSC_COEFF_SHIFT			16
> +
>  /* CGM Registers */
>  #define CGM_OFFSET				0x2000
>  #define GAMMA_OFFSET				0x2000
> +#define CGM_CSC_OFFSET				0x2000
>  #define PIPEA_CGM_CONTROL			(CHV_DISPLAY_BASE + 0x67A00)
>  #define PIPEA_CGM_GAMMA_MIN			(CHV_DISPLAY_BASE + 0x67000)
> +#define PIPEA_CGM_CSC_MIN			(CHV_DISPLAY_BASE + 0x67900)
>  #define _PIPE_CGM_CONTROL(pipe) \
>  	(PIPEA_CGM_CONTROL + (pipe * CGM_OFFSET))
>  #define _PIPE_GAMMA_BASE(pipe) \
>  	(PIPEA_CGM_GAMMA_MIN + (pipe * GAMMA_OFFSET))
> +#define _PIPE_CSC_BASE(pipe) \
> +	(PIPEA_CGM_CSC_MIN + (pipe * CGM_CSC_OFFSET))
>  
>  /* Generic Function prototypes */
>  void intel_color_manager_init(struct drm_device *dev);
> @@ -90,7 +112,11 @@ void intel_color_manager_attach(struct drm_device *dev,
>  		struct drm_mode_object *mode_obj);
>  extern int intel_color_manager_set_gamma(struct drm_device *dev,
>  		struct drm_mode_object *obj, uint32_t blob_id);
> +extern int intel_color_manager_set_csc(struct drm_device *dev,
> +		struct drm_mode_object *obj, uint64_t blob_id);
>  
>  /* Platform specific function prototypes */
>  extern int chv_set_gamma(struct drm_device *dev,
>  		uint32_t blob_id, struct drm_crtc *crtc);
> +extern int chv_set_csc(struct drm_device *dev,
> +		uint64_t blob_id, struct drm_crtc *crtc);
> -- 
> 2.4.2
> 


More information about the dri-devel mailing list