From patchwork Thu Dec 17 18:57:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lionel Landwerlin X-Patchwork-Id: 7876221 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B9360BEEE5 for ; Thu, 17 Dec 2015 18:58:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 19728203F1 for ; Thu, 17 Dec 2015 18:58:18 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 7C75E2042C for ; Thu, 17 Dec 2015 18:58:15 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AC1DB6E2F2; Thu, 17 Dec 2015 10:58:14 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by gabe.freedesktop.org (Postfix) with ESMTP id E02D7897D7 for ; Thu, 17 Dec 2015 10:58:08 -0800 (PST) Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga102.jf.intel.com with ESMTP; 17 Dec 2015 10:58:09 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,442,1444719600"; d="scan'208";a="15070919" Received: from ddesurmo-mobl1.ger.corp.intel.com (HELO ivy.ger.corp.intel.com) ([10.252.43.166]) by fmsmga004.fm.intel.com with ESMTP; 17 Dec 2015 10:58:07 -0800 From: Lionel Landwerlin To: intel-gfx@lists.freedesktop.org Date: Thu, 17 Dec 2015 18:57:56 +0000 Message-Id: <1450378678-24296-5-git-send-email-lionel.g.landwerlin@intel.com> X-Mailer: git-send-email 2.6.3 In-Reply-To: <1450378678-24296-1-git-send-email-lionel.g.landwerlin@intel.com> References: <1450378678-24296-1-git-send-email-lionel.g.landwerlin@intel.com> MIME-Version: 1.0 Cc: Kausal Malladi Subject: [Intel-gfx] [PATCH 4/6] drm/i915/chv: Implement color management X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Shashank Sharma Implement degamma, csc and gamma steps on CHV. Signed-off-by: Shashank Sharma Signed-off-by: Kausal Malladi --- 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 #include @@ -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 + * Kausal Malladi + */ + +#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 + * Kausal Malladi + */ +#include +#include +#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__ */