From patchwork Wed Jul 23 18:04:59 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Sharma, Shashank" X-Patchwork-Id: 4612431 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 438799F2B8 for ; Wed, 23 Jul 2014 18:02:02 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 72537201D5 for ; Wed, 23 Jul 2014 18:01:58 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 41AF3201C0 for ; Wed, 23 Jul 2014 18:01:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B3BF86E681; Wed, 23 Jul 2014 11:01:53 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id 836EA6E681 for ; Wed, 23 Jul 2014 11:01:50 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 23 Jul 2014 11:01:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,718,1400050800"; d="scan'208";a="574341194" Received: from shashanks-desktop.iind.intel.com ([10.223.26.11]) by fmsmga002.fm.intel.com with ESMTP; 23 Jul 2014 11:00:41 -0700 From: shashank.sharma@intel.com To: intel-gfx@lists.freedesktop.org, ville.syrjala@linux.intel.com, damien.lespiau@intel.com, daniel.vetter@intel.com, shobhit.kumar@intel.com, satheeshakrishna.m@intel.com Date: Wed, 23 Jul 2014 23:34:59 +0530 Message-Id: <1406138705-17334-6-git-send-email-shashank.sharma@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1406138705-17334-1-git-send-email-shashank.sharma@intel.com> References: <1406138705-17334-1-git-send-email-shashank.sharma@intel.com> Cc: =indranil.mukherjee@intel.com Subject: [Intel-gfx] [PATCH 05/11] drm/i915: Add color manager gamma correction X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 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, 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 This patch adds support for pipe gamma correction color property for intel color manager framework. It adds two functions: 1. intel_clrmgr_set_gamma: This is a wrapper function which checks the platform type, and calls the valleyview specific set_gamma function. As different platforms have different methods of setting pipe gamma, this function is required.The support for other platfroms can be plugged-in here in the wrapper function. Adding this function as .set_property of gamma-correction color property. 2. vlv_set_10_bit_gamma: Core function to program gamma coefficients as per vlv specs, and then enable gamma on pipe. This function uses 10-bit gamma programming method of VLV (10.6 method), which is more accurate, and can support fraction values also. Userspace encodes 16 bit per channel gamma correction value in 64bit value in format, and sends 128 such gamma correction values. The 129th value is GCMAX register value. Signed-off-by: Shashank Sharma --- drivers/gpu/drm/i915/i915_reg.h | 5 ++ drivers/gpu/drm/i915/intel_clrmgr.c | 125 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_clrmgr.h | 29 +++++++++ 3 files changed, 159 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3199f96..9501ad8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -6095,6 +6095,11 @@ enum punit_power_well { #define CSC_OFFSET (_PIPEBCSC - _PIPEACSC) #define PIPECSC(pipe) (_PIPEACSC + (pipe * CSC_OFFSET)) +/* Gamma GCMAX */ +#define VLV_PIPEA_GCMAX (dev_priv->info.display_mmio_offset + 0x70010) +#define VLV_PIPEB_GCMAX (dev_priv->info.display_mmio_offset + 0x71010) +#define VLV_PIPE_GCMAX(pipe) _PIPE(pipe, VLV_PIPEA_GCMAX, VLV_PIPEB_GCMAX) + /* VLV MIPI registers */ #define _MIPIA_PORT_CTRL (VLV_DISPLAY_BASE + 0x61190) diff --git a/drivers/gpu/drm/i915/intel_clrmgr.c b/drivers/gpu/drm/i915/intel_clrmgr.c index 601076b..38ba878 100644 --- a/drivers/gpu/drm/i915/intel_clrmgr.c +++ b/drivers/gpu/drm/i915/intel_clrmgr.c @@ -51,6 +51,7 @@ struct clrmgr_property gen6_pipe_color_corrections[] = { .type = DRM_MODE_PROP_BLOB, .len = VLV_10BIT_GAMMA_MAX_VALS, .name = "gamma-correction", + .set_property = intel_clrmgr_set_gamma, }, }; @@ -89,6 +90,130 @@ struct clrmgr_property gen6_plane_color_corrections[] = { }; /* +* vlv_set_10bit_gamma +* Valleyview specific gamma correction method. +* Programs the palette registers in 10bit method +* with 128 correction values, sampled across 1024 +* gamma correction values at sampling rate of 8. +* inputs: +* - intel_crtc* +* - color manager registered property for gamma correction +* - data: pointer to correction values to be applied +*/ +static bool vlv_set_10bit_gamma(struct intel_crtc *intel_crtc, + struct clrmgr_regd_prop *gamma, u64 *data) +{ + u16 red, green, blue; + u64 correct_rgb; + u32 val, even, odd; + u32 count = 0; + u32 reg = 0; + struct drm_property *property = gamma->property; + struct drm_device *dev = intel_crtc->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 palette = PALETTE(intel_crtc->pipe); + + /* Validate input */ + if (property->num_values != VLV_10BIT_GAMMA_MAX_VALS) { + DRM_ERROR("Unexpected value count for GAMMA LUT"); + return false; + } + + /* 128, 64 bit values, coming in <0> format containing + only 10 integer and 6fraction correction values */ + while (count < (property->num_values - CLRMGR_GAMMA_GCMAX_VAL)) { + correct_rgb = data[count]; + property->values[count] = correct_rgb; + + blue = correct_rgb >> CLRMGR_GAMMA_PARSER_SHIFT_BLUE; + green = correct_rgb >> CLRMGR_GAMMA_PARSER_SHIFT_GREEN; + red = correct_rgb >> CLRMGR_GAMMA_PARSER_SHIFT_RED; + + /* Prepare even and odd regs. Even register contains 6 + fractional and 2 integer base bits, so lower 8 bits */ + even = ((blue & VLV_GAMMA_EVEN_MASK) << + VLV_GAMMA_SHIFT_BLUE_REG) | + ((green & VLV_GAMMA_EVEN_MASK) << + VLV_GAMMA_SHIFT_GREEN_REG) | + ((red & VLV_GAMMA_EVEN_MASK) << + VLV_GAMMA_SHIFT_RED_REG); + + /* Odd register contains upper 8 (integer) bits */ + odd = ((blue >> VLV_GAMMA_ODD_SHIFT) << + VLV_GAMMA_SHIFT_BLUE_REG) | + ((green >> VLV_GAMMA_ODD_SHIFT) << + VLV_GAMMA_SHIFT_GREEN_REG) | + ((red >> VLV_GAMMA_ODD_SHIFT) << + VLV_GAMMA_SHIFT_RED_REG); + + /* Writing fraction part first, then integer part */ + I915_WRITE(palette, even); + palette += 4; + I915_WRITE(palette, odd); + palette += 4; + count++; + } + + /* Last 64bit values is in 11.6 format for GCmax, RGB sequence */ + correct_rgb = data[count]; + property->values[count] = correct_rgb; + + count = CLRMGR_GAMMA_TOTAL_GCMAX_REGS; + reg = VLV_PIPE_GCMAX(intel_crtc->pipe); + while (count--) { + val = (correct_rgb >> (count * VLV_CLRMGR_GAMMA_GCMAX_SHIFT)) & + VLV_GAMMA_GCMAX_MASK; + /* GCMAX value must be <= 1024 */ + if (val > VLV_CLRMGR_GAMMA_GCMAX_MAX) + val = VLV_CLRMGR_GAMMA_GCMAX_MAX; + + /* Write in 11.6 format */ + I915_WRITE(reg, (val << 6)); + reg += 4; + } + + /* Enable gamma for PIPE */ + reg = PIPECONF(intel_crtc->pipe); + val = I915_READ(reg) | PIPECONF_GAMMA; + I915_WRITE(reg, val); + + /* Enable gamma for sprites */ + for_each_sprite(intel_crtc->pipe, count) { + reg = SPCNTR(intel_crtc->pipe, count); + val = I915_READ(reg) | SPRITE_GAMMA_ENABLE; + I915_WRITE(reg, val); + } + + DRM_DEBUG_DRIVER("10bit gamma correction successfully applied"); + return true; +} + +bool intel_clrmgr_set_gamma(void *crtc, + struct clrmgr_regd_prop *gamma, u64 *data) +{ + struct intel_crtc *intel_crtc = crtc; + struct drm_device *dev = intel_crtc->base.dev; + + /* Validate input */ + if (!data || !gamma || !gamma->property) { + DRM_ERROR("Invalid input to set_gamma\n"); + return false; + } + + DRM_DEBUG_DRIVER("Setting gamma correction, len=%d\n", + gamma->property->num_values); + + /* VLV has legacy palette gamma correction */ + if (IS_VALLEYVIEW(dev)) + return vlv_set_10bit_gamma(intel_crtc, gamma, data); + + /* Todo: Support other gen devices */ + DRM_ERROR("Color correction is supported only on VLV for now\n"); + return false; +} + + +/* * vlv_set_csc * Valleyview specific csc correction method. * Programs the 6 csc registers with 3x3 correction matrix diff --git a/drivers/gpu/drm/i915/intel_clrmgr.h b/drivers/gpu/drm/i915/intel_clrmgr.h index e1279f6..fd8b98e 100644 --- a/drivers/gpu/drm/i915/intel_clrmgr.h +++ b/drivers/gpu/drm/i915/intel_clrmgr.h @@ -40,6 +40,12 @@ #define CLRMGR_PROP_NAME_MAX 128 #define CLRMGR_PROP_RANGE_MAX 0xFFFFFFFFFFFFFFFF +/* Gamma correcttion */ +#define CLRMGR_GAMMA_PARSER_SHIFT_BLUE 0 +#define CLRMGR_GAMMA_PARSER_SHIFT_GREEN 16 +#define CLRMGR_GAMMA_PARSER_SHIFT_RED 32 +#define CLRMGR_GAMMA_TOTAL_GCMAX_REGS 3 +#define CLRMGR_GAMMA_MAX_SAMPLES 1024 /* CSC / Wide gamut */ #define VLV_CSC_MATRIX_MAX_VALS 9 @@ -52,6 +58,16 @@ #define CLRMGR_GAMMA_GCMAX_VAL 1 #define VLV_10BIT_GAMMA_MAX_VALS (VLV_10BIT_GAMMA_MAX_INDEX + \ CLRMGR_GAMMA_GCMAX_VAL) +#define VLV_GAMMA_EVEN_MASK 0xFF +#define VLV_GAMMA_SHIFT_BLUE_REG 0 +#define VLV_GAMMA_SHIFT_GREEN_REG 8 +#define VLV_GAMMA_SHIFT_RED_REG 16 +#define VLV_GAMMA_ODD_SHIFT 8 +#define VLV_CLRMGR_GAMMA_GCMAX_SHIFT 17 +#define VLV_GAMMA_GCMAX_MASK 0x1FFFF +#define VLV_CLRMGR_GAMMA_GCMAX_MAX 0x400 + + /* Sprite Contrast and Brightness Registers */ #define VLV_CB_MAX_VALS 1 @@ -119,6 +135,19 @@ struct clrmgr_reg_request { }; /* +* intel_clrmgr_set_gamma +* Gamma correction method is different across various +* gen devices. This is a wrapper function which will call +* the platform specific gamma set function +* inputs: +* - crtc : void *, which can be typecasted to intel_crtc* +* - gamma: registered color property for gamma correction +* - data: pointer to correction values to be applied +*/ +bool intel_clrmgr_set_gamma(void *crtc, + struct clrmgr_regd_prop *gamma, u64 *data); + +/* * intel_clrmgr_set_csc * CSC correction method is different across various * gen devices. This wrapper function calls the respective