[Intel-gfx] [PATCH 4/6] drm/i915/chv: Implement color management
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Thu Dec 17 10:57:56 PST 2015
From: Shashank Sharma <shashank.sharma at intel.com>
Implement degamma, csc and gamma steps on CHV.
Signed-off-by: Shashank Sharma <shashank.sharma at intel.com>
Signed-off-by: Kausal Malladi <kausalmalladi at gmail.com>
---
drivers/gpu/drm/i915/Makefile | 3 +-
drivers/gpu/drm/i915/i915_drv.c | 5 +-
drivers/gpu/drm/i915/i915_drv.h | 2 +
drivers/gpu/drm/i915/i915_reg.h | 26 +++
drivers/gpu/drm/i915/intel_color_manager.c | 353 +++++++++++++++++++++++++++++
drivers/gpu/drm/i915/intel_color_manager.h | 91 ++++++++
drivers/gpu/drm/i915/intel_display.c | 2 +
drivers/gpu/drm/i915/intel_drv.h | 4 +
8 files changed, 484 insertions(+), 2 deletions(-)
create mode 100644 drivers/gpu/drm/i915/intel_color_manager.c
create mode 100644 drivers/gpu/drm/i915/intel_color_manager.h
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index 0851de07..c66d56a 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -64,7 +64,8 @@ i915-y += intel_audio.o \
intel_overlay.o \
intel_psr.o \
intel_sideband.o \
- intel_sprite.o
+ intel_sprite.o \
+ intel_color_manager.o
i915-$(CONFIG_ACPI) += intel_acpi.o intel_opregion.o
i915-$(CONFIG_DRM_FBDEV_EMULATION) += intel_fbdev.o
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 3ac616d..4396300 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -34,6 +34,7 @@
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"
+#include "intel_color_manager.h"
#include <linux/console.h>
#include <linux/module.h>
@@ -311,7 +312,9 @@ static const struct intel_device_info intel_cherryview_info = {
.gen = 8, .num_pipes = 3,
.need_gfx_hws = 1, .has_hotplug = 1,
.ring_mask = RENDER_RING | BSD_RING | BLT_RING | VEBOX_RING,
- .is_cherryview = 1,
+ .is_valleyview = 1,
+ .num_samples_after_ctm = CHV_10BIT_GAMMA_MAX_VALS,
+ .num_samples_before_ctm = CHV_DEGAMMA_MAX_VALS,
.display_mmio_offset = VLV_DISPLAY_BASE,
GEN_CHV_PIPEOFFSETS,
CURSOR_OFFSETS,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1d28d90..4eb0fab 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -793,6 +793,8 @@ struct intel_device_info {
u8 num_sprites[I915_MAX_PIPES];
u8 gen;
u8 ring_mask; /* Rings supported by the HW */
+ u16 num_samples_after_ctm;
+ u16 num_samples_before_ctm;
DEV_INFO_FOR_EACH_FLAG(DEFINE_FLAG, SEP_SEMICOLON);
/* Register offsets for the various display pipes and transcoders */
int pipe_offsets[I915_MAX_TRANSCODERS];
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 007ae83..36bb320 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8154,4 +8154,30 @@ enum skl_disp_power_wells {
#define GEN9_VEBOX_MOCS(i) _MMIO(0xcb00 + (i) * 4) /* Video MOCS registers */
#define GEN9_BLT_MOCS(i) _MMIO(0xcc00 + (i) * 4) /* Blitter MOCS registers */
+/* Color Management */
+#define PIPEA_CGM_CONTROL (VLV_DISPLAY_BASE + 0x67A00)
+#define PIPEB_CGM_CONTROL (VLV_DISPLAY_BASE + 0x69A00)
+#define PIPEC_CGM_CONTROL (VLV_DISPLAY_BASE + 0x6BA00)
+#define PIPEA_CGM_GAMMA (VLV_DISPLAY_BASE + 0x67000)
+#define PIPEB_CGM_GAMMA (VLV_DISPLAY_BASE + 0x69000)
+#define PIPEC_CGM_GAMMA (VLV_DISPLAY_BASE + 0x6B000)
+#define _PIPE_CGM_CONTROL(pipe) \
+ (_PIPE3(pipe, PIPEA_CGM_CONTROL, PIPEB_CGM_CONTROL, PIPEC_CGM_CONTROL))
+#define _PIPE_GAMMA_BASE(pipe) \
+ (_PIPE3(pipe, PIPEA_CGM_GAMMA, PIPEB_CGM_GAMMA, PIPEC_CGM_GAMMA))
+
+#define PIPEA_CGM_DEGAMMA (VLV_DISPLAY_BASE + 0x66000)
+#define PIPEB_CGM_DEGAMMA (VLV_DISPLAY_BASE + 0x68000)
+#define PIPEC_CGM_DEGAMMA (VLV_DISPLAY_BASE + 0x6A000)
+#define _PIPE_DEGAMMA_BASE(pipe) \
+ (_PIPE3(pipe, PIPEA_CGM_DEGAMMA, PIPEB_CGM_DEGAMMA, PIPEC_CGM_DEGAMMA))
+
+#define PIPEA_CGM_CSC (VLV_DISPLAY_BASE + 0x67900)
+#define PIPEB_CGM_CSC (VLV_DISPLAY_BASE + 0x69900)
+#define PIPEC_CGM_CSC (VLV_DISPLAY_BASE + 0x6B900)
+#define _PIPE_CSC_BASE(pipe) \
+ (_PIPE3(pipe, PIPEA_CGM_CSC, PIPEB_CGM_CSC, PIPEC_CGM_CSC))
+
+
+
#endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_color_manager.c b/drivers/gpu/drm/i915/intel_color_manager.c
new file mode 100644
index 0000000..02eee98
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Shashank Sharma <shashank.sharma at intel.com>
+ * Kausal Malladi <Kausal.Malladi at intel.com>
+ */
+
+#include "intel_color_manager.h"
+
+static u16 chv_prepare_csc_coeff(s64 csc_coeff)
+{
+ u16 csc_s3_12_format = 0;
+ u16 csc_int_value;
+ u16 csc_fract_value;
+
+ if (csc_coeff < 0)
+ csc_s3_12_format = CSC_COEFF_SIGN;
+ csc_coeff = abs(csc_coeff);
+ csc_coeff += CHV_CSC_FRACT_ROUNDOFF;
+ if (csc_coeff > CHV_CSC_COEFF_MAX + 1)
+ csc_coeff = CHV_CSC_COEFF_MAX + 1;
+ else if (csc_coeff > CHV_CSC_COEFF_MAX)
+ csc_coeff = CHV_CSC_COEFF_MAX;
+
+ csc_int_value = csc_coeff >> CHV_CSC_COEFF_SHIFT;
+ csc_int_value <<= CHV_CSC_COEFF_INT_SHIFT;
+
+ csc_fract_value = csc_coeff >> CHV_CSC_COEFF_FRACT_SHIFT;
+
+ csc_s3_12_format |= csc_int_value | csc_fract_value;
+
+ return csc_s3_12_format;
+}
+
+static int chv_set_csc(struct drm_device *dev, struct drm_property_blob *blob,
+ struct drm_crtc *crtc)
+{
+ u16 temp;
+ u32 word = 0;
+ int count = 0;
+ i915_reg_t val;
+ struct drm_ctm *csc_data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ enum pipe pipe;
+
+ if (WARN_ON(!blob))
+ return -EINVAL;
+
+ if (blob->length != sizeof(struct drm_ctm)) {
+ DRM_ERROR("Invalid length of data received\n");
+ return -EINVAL;
+ }
+
+ csc_data = (struct drm_ctm *)blob->data;
+ pipe = to_intel_crtc(crtc)->pipe;
+
+ /* Disable CSC functionality */
+ val = _MMIO(_PIPE_CGM_CONTROL(pipe));
+ I915_WRITE(val, I915_READ(val) & (~CGM_CSC_EN));
+
+ DRM_DEBUG_DRIVER("Disabled CSC Functionality on Pipe %c\n",
+ pipe_name(pipe));
+
+ val = _MMIO(_PIPE_CSC_BASE(pipe));
+
+ /*
+ * First 8 of 9 CSC correction values go in pair, to first
+ * 4 CSC register (bit 0:15 and 16:31)
+ */
+ while (count < CSC_MAX_VALS - 1) {
+ temp = chv_prepare_csc_coeff(
+ csc_data->ctm_coeff[count]);
+ SET_BITS(word, temp, 0, 16);
+ count++;
+
+ temp = chv_prepare_csc_coeff(
+ csc_data->ctm_coeff[count]);
+ SET_BITS(word, temp, 16, 16);
+ count++;
+
+ I915_WRITE(val, word);
+ val.reg += 4;
+ }
+
+ /* 9th coeff goes to 5th register, bit 0:16 */
+ temp = chv_prepare_csc_coeff(
+ csc_data->ctm_coeff[count]);
+ SET_BITS(word, temp, 0, 16);
+ I915_WRITE(val, word);
+
+ /* Enable CSC functionality */
+ val = _MMIO(_PIPE_CGM_CONTROL(pipe));
+ I915_WRITE(val, I915_READ(val) | CGM_CSC_EN);
+ DRM_DEBUG_DRIVER("CSC enabled on Pipe %c\n", pipe_name(pipe));
+ return 0;
+}
+
+static int chv_set_degamma(struct drm_device *dev,
+ struct drm_property_blob *blob, struct drm_crtc *crtc)
+{
+ u16 red_fract, green_fract, blue_fract;
+ u32 red, green, blue;
+ u32 num_samples;
+ u32 word = 0;
+ u32 count, cgm_control, cgm_degamma_reg;
+ i915_reg_t val;
+ enum pipe pipe;
+ struct drm_palette *degamma_data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_r32g32b32 *correction_values = NULL;
+ struct drm_crtc_state *state = crtc->state;
+
+ if (WARN_ON(!blob))
+ return -EINVAL;
+
+ degamma_data = (struct drm_palette *)blob->data;
+ pipe = to_intel_crtc(crtc)->pipe;
+ num_samples = blob->length / sizeof(struct drm_r32g32b32);
+
+ switch (num_samples) {
+ case GAMMA_DISABLE_VALS:
+ /* Disable DeGamma functionality on Pipe - CGM Block */
+ val = _MMIO(_PIPE_CGM_CONTROL(pipe));
+ cgm_control = I915_READ(val);
+ cgm_control &= ~CGM_DEGAMMA_EN;
+ state->palette_before_ctm_blob = NULL;
+
+ I915_WRITE(val, cgm_control);
+ DRM_DEBUG_DRIVER("DeGamma disabled on Pipe %c\n",
+ pipe_name(pipe));
+ break;
+
+ case CHV_DEGAMMA_MAX_VALS:
+ cgm_degamma_reg = _PIPE_DEGAMMA_BASE(pipe);
+ count = 0;
+ correction_values = degamma_data->lut;
+ while (count < CHV_DEGAMMA_MAX_VALS) {
+ blue = correction_values[count].b32;
+ green = correction_values[count].g32;
+ red = correction_values[count].r32;
+
+ if (blue > CHV_MAX_GAMMA)
+ blue = CHV_MAX_GAMMA;
+
+ if (green > CHV_MAX_GAMMA)
+ green = CHV_MAX_GAMMA;
+
+ if (red > CHV_MAX_GAMMA)
+ red = CHV_MAX_GAMMA;
+
+ blue_fract = GET_BITS(blue, 10, 14);
+ green_fract = GET_BITS(green, 10, 14);
+ red_fract = GET_BITS(red, 10, 14);
+
+ /* Green (29:16) and Blue (13:0) in DWORD1 */
+ SET_BITS(word, green_fract, 16, 14);
+ SET_BITS(word, blue_fract, 0, 14);
+ val = _MMIO(cgm_degamma_reg);
+ I915_WRITE(val, word);
+ cgm_degamma_reg += 4;
+
+ /* Red (13:0) to be written to DWORD2 */
+ word = red_fract;
+ val = _MMIO(cgm_degamma_reg);
+ I915_WRITE(val, word);
+ cgm_degamma_reg += 4;
+ count++;
+ }
+
+ DRM_DEBUG_DRIVER("DeGamma LUT loaded for Pipe %c\n",
+ pipe_name(pipe));
+
+ /* Enable DeGamma on Pipe */
+ val = _MMIO(_PIPE_CGM_CONTROL(pipe));
+ I915_WRITE(val, I915_READ(val) | CGM_DEGAMMA_EN);
+ DRM_DEBUG_DRIVER("DeGamma correction enabled on Pipe %c\n",
+ pipe_name(pipe));
+ break;
+
+ default:
+ DRM_ERROR("Invalid number of samples for DeGamma LUT\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int chv_set_gamma(struct drm_device *dev, struct drm_property_blob *blob,
+ struct drm_crtc *crtc)
+{
+ enum pipe pipe;
+ u16 red_fract, green_fract, blue_fract;
+ u32 red, green, blue, num_samples;
+ u32 word = 0;
+ u32 count, cgm_gamma_reg, cgm_control;
+ i915_reg_t val;
+ struct drm_r32g32b32 *correction_values;
+ struct drm_palette *gamma_data;
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct drm_crtc_state *state = crtc->state;
+
+ if (WARN_ON(!blob))
+ return -EINVAL;
+
+ gamma_data = (struct drm_palette *)blob->data;
+ pipe = to_intel_crtc(crtc)->pipe;
+ num_samples = blob->length / sizeof(struct drm_r32g32b32);
+
+ switch (num_samples) {
+ case GAMMA_DISABLE_VALS:
+
+ /* Disable Gamma functionality on Pipe - CGM Block */
+ val = _MMIO(_PIPE_CGM_CONTROL(pipe));
+ cgm_control = I915_READ(val);
+ cgm_control &= ~CGM_GAMMA_EN;
+ I915_WRITE(val, cgm_control);
+ state->palette_after_ctm_blob = NULL;
+ DRM_DEBUG_DRIVER("Gamma disabled on Pipe %c\n",
+ pipe_name(pipe));
+ return 0;
+
+ case CHV_8BIT_GAMMA_MAX_VALS:
+ case CHV_10BIT_GAMMA_MAX_VALS:
+
+ count = 0;
+ cgm_gamma_reg = _PIPE_GAMMA_BASE(pipe);
+ correction_values = gamma_data->lut;
+
+ while (count < num_samples) {
+ blue = correction_values[count].b32;
+ green = correction_values[count].g32;
+ red = correction_values[count].r32;
+
+ if (blue > CHV_MAX_GAMMA)
+ blue = CHV_MAX_GAMMA;
+
+ if (green > CHV_MAX_GAMMA)
+ green = CHV_MAX_GAMMA;
+
+ if (red > CHV_MAX_GAMMA)
+ red = CHV_MAX_GAMMA;
+
+ /* get MSB 10 bits from fraction part (14:23) */
+ blue_fract = GET_BITS(blue, 14, 10);
+ green_fract = GET_BITS(green, 14, 10);
+ red_fract = GET_BITS(red, 14, 10);
+
+ /* Green (25:16) and Blue (9:0) to be written */
+ SET_BITS(word, green_fract, 16, 10);
+ SET_BITS(word, blue_fract, 0, 10);
+ val = _MMIO(cgm_gamma_reg);
+ I915_WRITE(val, word);
+ cgm_gamma_reg += 4;
+
+ /* Red (9:0) to be written */
+ word = red_fract;
+ val = _MMIO(cgm_gamma_reg);
+ I915_WRITE(val, word);
+ cgm_gamma_reg += 4;
+ count++;
+ }
+
+ /* Enable (CGM) Gamma on Pipe */
+ val = _MMIO(_PIPE_CGM_CONTROL(pipe));
+ I915_WRITE(val, I915_READ(val) | CGM_GAMMA_EN);
+ DRM_DEBUG_DRIVER("CGM Gamma enabled on Pipe %c\n",
+ pipe_name(pipe));
+ return 0;
+
+ default:
+ DRM_ERROR("Invalid number of samples (%u) for Gamma LUT\n",
+ num_samples);
+ return -EINVAL;
+ }
+}
+
+void intel_color_manager_commit(struct drm_device *dev,
+ struct drm_crtc_state *crtc_state)
+{
+ struct drm_property_blob *blob;
+ struct drm_crtc *crtc = crtc_state->crtc;
+ int ret = -EINVAL;
+
+ /*
+ * CRTC level color correction, once applied on the
+ * pipe, goes on forever, until disabled, so there is no
+ * need to program all those correction registers on every
+ * commit. Do this only when a new correction applied.
+ */
+ if (!crtc_state->color_correction_changed)
+ return;
+
+ blob = crtc_state->palette_after_ctm_blob;
+ if (blob) {
+ /* Gamma correction is platform specific */
+ if (IS_CHERRYVIEW(dev))
+ ret = chv_set_gamma(dev, blob, crtc);
+
+ if (ret)
+ DRM_ERROR("set Gamma correction failed\n");
+ else
+ DRM_DEBUG_DRIVER("Gamma correction success\n");
+ }
+
+ blob = crtc_state->palette_before_ctm_blob;
+ if (blob) {
+ /* Degamma correction */
+ if (IS_CHERRYVIEW(dev))
+ ret = chv_set_degamma(dev, blob, crtc);
+
+ if (ret)
+ DRM_ERROR("set degamma correction failed\n");
+ else
+ DRM_DEBUG_DRIVER("degamma correction success\n");
+ }
+
+ blob = crtc_state->ctm_blob;
+ if (blob) {
+ /* CSC correction */
+ if (IS_CHERRYVIEW(dev))
+ ret = chv_set_csc(dev, blob, crtc);
+
+ if (ret)
+ DRM_ERROR("set CSC correction failed\n");
+ else
+ DRM_DEBUG_DRIVER("CSC correction success\n");
+ }
+
+ crtc_state->color_correction_changed = false;
+}
+
+void intel_crtc_attach_color_properties(struct drm_crtc *crtc)
+{
+}
diff --git a/drivers/gpu/drm/i915/intel_color_manager.h b/drivers/gpu/drm/i915/intel_color_manager.h
new file mode 100644
index 0000000..04185ac
--- /dev/null
+++ b/drivers/gpu/drm/i915/intel_color_manager.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Shashank Sharma <shashank.sharma at intel.com>
+ * Kausal Malladi <Kausal.Malladi at intel.com>
+ */
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include "i915_drv.h"
+
+/* Color management bit utilities */
+#define GET_BIT_MASK(n) ((1 << n) - 1)
+
+/* Read bits of a word from bit no. 'start'(lsb) till 'n' bits */
+#define GET_BITS(x, start, nbits) ((x >> start) & GET_BIT_MASK(nbits))
+
+/* Round off by adding 1 to the immediate lower bit */
+#define GET_BITS_ROUNDOFF(x, start, nbits) \
+ ((GET_BITS(x, start, (nbits + 1)) + 1) >> 1)
+
+/* Clear bits of a word from bit no. 'start' till nbits */
+#define CLEAR_BITS(x, start, nbits) ( \
+ x &= ~((GET_BIT_MASK(nbits) << start)))
+
+/* Write bit_pattern of no_bits bits in a target word */
+#define SET_BITS(target, bit_pattern, start_bit, no_bits) \
+ do { \
+ CLEAR_BITS(target, start_bit, no_bits); \
+ target |= (bit_pattern << start_bit); \
+ } while (0)
+
+/* CHV */
+#define CHV_10BIT_GAMMA_MAX_VALS 257
+#define CHV_DEGAMMA_MAX_VALS 65
+
+/* No of coeff for disabling gamma is 0 */
+#define GAMMA_DISABLE_VALS 0
+
+/* Gamma on CHV */
+#define CHV_10BIT_GAMMA_MAX_VALS 257
+#define CHV_8BIT_GAMMA_MAX_VALS 256
+#define CHV_10BIT_GAMMA_MSB_SHIFT 6
+#define CHV_GAMMA_SHIFT_GREEN 16
+#define CHV_MAX_GAMMA ((1 << 24) - 1)
+
+/*
+ * CSC on CHV
+ * Fractional part is 32 bit, and we need only 12 MSBs for programming
+ * into registers. ROUNDOFF is required to minimize loss of precision.
+ */
+#define CHV_CSC_FRACT_ROUNDOFF (1 << 19)
+/*
+ * CSC values are 64-bit values. For CHV, the maximum CSC value that
+ * user can program is 7.99999..., which can be represented in fixed point
+ * S31.32 format like this, with all fractional bits as 1
+ */
+#define CHV_CSC_COEFF_MAX 0x00000007FFFFFFFF
+#define CHV_CSC_COEFF_SHIFT 32
+#define CHV_CSC_COEFF_INT_SHIFT 12
+#define CSC_COEFF_SIGN (1 << 15)
+#define CHV_CSC_COEFF_FRACT_SHIFT 20
+#define CSC_MAX_VALS 9
+
+/* Degamma on CHV */
+#define CHV_DEGAMMA_MSB_SHIFT 2
+#define CHV_DEGAMMA_GREEN_SHIFT 16
+
+/* CHV CGM Block */
+#define CGM_GAMMA_EN (1 << 2)
+#define CGM_CSC_EN (1 << 1)
+#define CGM_DEGAMMA_EN (1 << 0)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index a05ba28..b9eb507 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -13940,6 +13940,8 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
intel_update_pipe_config(intel_crtc, old_intel_state);
else if (INTEL_INFO(dev)->gen >= 9)
skl_detach_scalers(intel_crtc);
+
+ intel_color_manager_commit(dev, crtc->state);
}
static void intel_finish_crtc_commit(struct drm_crtc *crtc,
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d523ebb..2ee655a 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1604,4 +1604,8 @@ void intel_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state);
extern const struct drm_plane_helper_funcs intel_plane_helper_funcs;
+/* intel_color_manager.c */
+void intel_crtc_attach_color_properties(struct drm_crtc *crtc);
+void intel_color_manager_commit(struct drm_device *dev,
+ struct drm_crtc_state *crtc_state);
#endif /* __INTEL_DRV_H__ */
--
2.6.3
More information about the Intel-gfx
mailing list