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
> 

Reply via email to