From: Kausal Malladi <kausalmalladi@xxxxxxxxx> BDW/SKL/BXT supports DeGamma color correction feature, which linearizes all the non-linear color values. This will be applied before Color Transformation. This patch does the following: 1. Adds the core function to program DeGamma correction values for BDW/SKL/BXT platform 2. Adds DeGamma correction macros/defines Signed-off-by: Shashank Sharma <shashank.sharma@xxxxxxxxx> Signed-off-by: Kausal Malladi <kausalmalladi@xxxxxxxxx> --- drivers/gpu/drm/i915/intel_color_manager.c | 68 ++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_color_manager.h | 2 + 2 files changed, 70 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_color_manager.c b/drivers/gpu/drm/i915/intel_color_manager.c index a894f4c..9f9fb1a 100644 --- a/drivers/gpu/drm/i915/intel_color_manager.c +++ b/drivers/gpu/drm/i915/intel_color_manager.c @@ -154,6 +154,72 @@ u32 gen9_write_10bit_gamma_precision(u32 red, u32 green, u32 blue) return word; } +int gen9_set_degamma(struct drm_device *dev, struct drm_property_blob *blob, + struct drm_crtc *crtc) +{ + struct drm_palette *degamma_data; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_r32g32b32 *correction_values = NULL; + u32 mode, pal_prec_index, pal_prec_data; + int count = 0; + u32 blue, green, red; + enum pipe pipe; + int num_samples, length; + u32 index, word; + + if (!blob) { + DRM_ERROR("Null Blob\n"); + return -EINVAL; + } + + degamma_data = (struct drm_palette *)blob->data; + + if (degamma_data->version != GEN9_DEGAMMA_DATA_STRUCT_VERSION) { + DRM_ERROR("Invalid DeGamma Data struct version\n"); + return -EINVAL; + } + + pipe = to_intel_crtc(crtc)->pipe; + num_samples = degamma_data->num_samples; + if (num_samples != GEN9_SPLITGAMMA_MAX_VALS) { + DRM_ERROR("Invalid number of samples\n"); + return -EINVAL; + } + + length = num_samples * sizeof(struct drm_r32g32b32); + mode = I915_READ(GAMMA_MODE(pipe)); + + pal_prec_index = _PREC_PAL_INDEX(pipe); + pal_prec_data = _PREC_PAL_DATA(pipe); + + correction_values = (struct drm_r32g32b32 *)°amma_data->lut; + index = I915_READ(pal_prec_index); + index |= GEN9_INDEX_AUTO_INCREMENT | GEN9_INDEX_SPLIT_MODE; + I915_WRITE(pal_prec_index, index); + + while (count < num_samples) { + blue = correction_values[count].b32; + green = correction_values[count].g32; + red = correction_values[count].r32; + + word = gen9_write_10bit_gamma_precision(red, green, blue); + I915_WRITE(pal_prec_data, word); + count++; + } + + mode &= ~GAMMA_MODE_MODE_MASK; + I915_WRITE(GAMMA_MODE(pipe), mode | GAMMA_MODE_MODE_SPLIT); + + /* Enable DeGamma on Pipe */ + I915_WRITE(_PIPE_CGM_CONTROL(pipe), + I915_READ(_PIPE_CGM_CONTROL(pipe)) | CGM_DEGAMMA_EN); + + DRM_DEBUG_DRIVER("DeGamma correction enabled on Pipe %c\n", + pipe_name(pipe)); + + return 0; +} + int chv_set_degamma(struct drm_device *dev, struct drm_property_blob *blob, struct drm_crtc *crtc) { @@ -640,6 +706,8 @@ void intel_color_manager_crtc_commit(struct drm_device *dev, /* degamma correction */ if (IS_CHERRYVIEW(dev)) ret = chv_set_degamma(dev, blob, crtc); + else if (IS_BROADWELL(dev) || IS_GEN9(dev)) + ret = gen9_set_degamma(dev, blob, crtc); if (ret) DRM_ERROR("set degamma correction failed\n"); diff --git a/drivers/gpu/drm/i915/intel_color_manager.h b/drivers/gpu/drm/i915/intel_color_manager.h index fa9d0b0..ca89f25 100644 --- a/drivers/gpu/drm/i915/intel_color_manager.h +++ b/drivers/gpu/drm/i915/intel_color_manager.h @@ -72,6 +72,8 @@ #define CHV_DEGAMMA_DATA_STRUCT_VERSION 1 #define CHV_DEGAMMA_MSB_SHIFT 2 #define CHV_DEGAMMA_GREEN_SHIFT 16 +/* Gen 9 */ +#define GEN9_DEGAMMA_DATA_STRUCT_VERSION 1 /* CSC correction */ #define CHV_CSC_DATA_STRUCT_VERSION 1 -- 1.9.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel