On Thu, Jun 04, 2015 at 07:12:41PM +0530, Kausal Malladi wrote: > From: Kausal Malladi <Kausal.Malladi@xxxxxxxxx> > > 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@xxxxxxxxx> > Signed-off-by: Kausal Malladi <Kausal.Malladi@xxxxxxxxx> > --- > 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 > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel