All of lore.kernel.org
 help / color / mirror / Atom feed
From: Shashank Sharma <shashank.sharma@intel.com>
To: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org,
	emil.l.velikov@gmail.com, matthew.d.roper@intel.com,
	robert.bradford@intel.com, jim.bish@intel.com
Cc: annie.j.matheson@intel.com, avinash.reddy.palleti@intel.com,
	indranil.mukherjee@intel.com, kausalmalladi@gmail.com,
	gary.k.smith@intel.com, daniel.vetter@intel.com,
	kiran.s.kumar@intel.com
Subject: [PATCH v6 19/23] drm/i915: BDW: Pipe level Gamma correction
Date: Fri, 16 Oct 2015 19:59:07 +0530	[thread overview]
Message-ID: <1445005751-14918-20-git-send-email-shashank.sharma@intel.com> (raw)
In-Reply-To: <1445005751-14918-1-git-send-email-shashank.sharma@intel.com>

BDW/SKL/BXT platforms support various Gamma correction modes
which are:
1. Legacy 8-bit mode
2. 10-bit mode
3. Split mode
4. 12-bit mode

This patch does the following:
1. Adds the core function to program Gamma correction values
   for BDW/SKL/BXT platforms
2. Adds Gamma correction macros/defines

Signed-off-by: Shashank Sharma <shashank.sharma@intel.com>
Signed-off-by: Kausal Malladi <kausalmalladi@gmail.com>
---
 drivers/gpu/drm/i915/i915_reg.h            |  25 ++-
 drivers/gpu/drm/i915/intel_color_manager.c | 281 +++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/intel_color_manager.h |   6 +
 3 files changed, 310 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 3db42f4..39fbafc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5685,11 +5685,15 @@ enum skl_disp_power_wells {
 /* legacy palette */
 #define _LGC_PALETTE_A           0x4a000
 #define _LGC_PALETTE_B           0x4a800
-#define LGC_PALETTE(pipe, i) (_PIPE(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B) + (i) * 4)
+#define _LGC_PALETTE_C           0x4b000
+#define LGC_PALETTE(pipe, i) (_PIPE3(pipe, _LGC_PALETTE_A, _LGC_PALETTE_B, \
+			 _LGC_PALETTE_C) + (i) * 4)
 
 #define _GAMMA_MODE_A		0x4a480
 #define _GAMMA_MODE_B		0x4ac80
-#define GAMMA_MODE(pipe) _PIPE(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B)
+#define _GAMMA_MODE_C		0x4b480
+#define GAMMA_MODE(pipe) \
+	_PIPE3(pipe, _GAMMA_MODE_A, _GAMMA_MODE_B, _GAMMA_MODE_C)
 #define GAMMA_MODE_MODE_MASK	(3 << 0)
 #define GAMMA_MODE_MODE_8BIT	(0 << 0)
 #define GAMMA_MODE_MODE_10BIT	(1 << 0)
@@ -8172,6 +8176,23 @@ enum skl_disp_power_wells {
 #define _PIPE_CSC_BASE(pipe) \
 	(_PIPE3(pipe, PIPEA_CGM_CSC, PIPEB_CGM_CSC, PIPEC_CGM_CSC))
 
+/* BDW gamma correction */
+#define PAL_PREC_INDEX_A                       0x4A400
+#define PAL_PREC_INDEX_B                       0x4AC00
+#define PAL_PREC_INDEX_C                       0x4B400
+#define PAL_PREC_DATA_A                        0x4A404
+#define PAL_PREC_DATA_B                        0x4AC04
+#define PAL_PREC_DATA_C                        0x4B404
+#define PAL_PREC_GCMAX_A			0x4A410
+#define PAL_PREC_GCMAX_B			0x4AC10
+#define PAL_PREC_GCMAX_C			0x4B410
+
+#define _PREC_PAL_INDEX(pipe) \
+	(_PIPE3(pipe, PAL_PREC_INDEX_A, PAL_PREC_INDEX_B, PAL_PREC_INDEX_C))
+#define _PREC_PAL_DATA(pipe) \
+	(_PIPE3(pipe, PAL_PREC_DATA_A, PAL_PREC_DATA_B, PAL_PREC_DATA_C))
+#define _PREC_PAL_GCMAX(pipe) \
+	(_PIPE3(pipe, PAL_PREC_GCMAX_A, PAL_PREC_GCMAX_B, PAL_PREC_GCMAX_C))
 
 
 #endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/intel_color_manager.c b/drivers/gpu/drm/i915/intel_color_manager.c
index 6b59531..44f99be 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.c
+++ b/drivers/gpu/drm/i915/intel_color_manager.c
@@ -27,6 +27,285 @@
 
 #include "intel_color_manager.h"
 
+static void bdw_write_8bit_gamma_legacy(struct drm_device *dev,
+	struct drm_r32g32b32 *correction_values, u32 palette)
+{
+	u16 blue_fract, green_fract, red_fract;
+	u32 blue, green, red;
+	u32 count = 0;
+	u32 word = 0;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	while (count < BDW_8BIT_GAMMA_MAX_VALS) {
+		blue = correction_values[count].b32;
+		green = correction_values[count].g32;
+		red = correction_values[count].r32;
+
+		/*
+		* Maximum possible gamma correction value supported
+		* for BDW is 0xFFFFFFFF, so clamp the values accordingly
+		*/
+		if (blue >= BDW_MAX_GAMMA)
+			blue = BDW_MAX_GAMMA;
+		if (green >= BDW_MAX_GAMMA)
+			green = BDW_MAX_GAMMA;
+		if (red >= BDW_MAX_GAMMA)
+			red = BDW_MAX_GAMMA;
+
+		blue_fract = GET_BITS(blue, 16, 8);
+		green_fract = GET_BITS(green, 16, 8);
+		red_fract = GET_BITS(red, 16, 8);
+
+		/* Blue (7:0) Green (15:8) and Red (23:16) */
+		SET_BITS(word, blue_fract, 0, 8);
+		SET_BITS(word, green_fract, 8, 8);
+		SET_BITS(word, blue_fract, 16, 8);
+		I915_WRITE(palette, word);
+		palette += 4;
+		count++;
+	}
+}
+
+static void bdw_write_10bit_gamma_precision(struct drm_device *dev,
+	struct drm_r32g32b32 *correction_values, u32 pal_prec_data,
+			u32 no_of_coeff)
+{
+	u16 blue_fract, green_fract, red_fract;
+	u32 word = 0;
+	u32 count = 0;
+	u32 blue, green, red;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	while (count < no_of_coeff) {
+
+		blue = correction_values[count].b32;
+		green = correction_values[count].g32;
+		red = correction_values[count].r32;
+
+		/*
+		* Maximum possible gamma correction value supported
+		* for BDW is 0xFFFFFFFF, so clamp the values accordingly
+		*/
+		if (blue >= BDW_MAX_GAMMA)
+			blue = BDW_MAX_GAMMA;
+		if (green >= BDW_MAX_GAMMA)
+			green = BDW_MAX_GAMMA;
+		if (red >= BDW_MAX_GAMMA)
+			red = BDW_MAX_GAMMA;
+
+		/*
+		* Gamma correction values are sent in 8.24 format
+		* with 8 int and 24 fraction bits. BDW 10 bit gamma
+		* unit expects correction registers to be programmed in
+		* 0.10 format, with 0 int and 16 fraction bits. So take
+		* MSB 10 bit values(bits 23-14) from the fraction part and
+		* prepare the correction registers.
+		*/
+		blue_fract = GET_BITS(blue, 14, 10);
+		green_fract = GET_BITS(green, 14, 10);
+		red_fract = GET_BITS(red, 14, 10);
+
+		/* Arrange: Red (29:20) Green (19:10) and Blue (9:0) */
+		SET_BITS(word, red_fract, 20, 10);
+		SET_BITS(word, green_fract, 10, 10);
+		SET_BITS(word, blue_fract, 0, 10);
+		I915_WRITE(pal_prec_data, word);
+		count++;
+	}
+	DRM_DEBUG_DRIVER("Gamma correction programmed\n");
+}
+
+static void bdw_write_12bit_gamma_precision(struct drm_device *dev,
+	struct drm_r32g32b32 *correction_values, u32 pal_prec_data,
+		enum pipe pipe)
+{
+	uint16_t blue_fract, green_fract, red_fract;
+	uint32_t gcmax;
+	uint32_t word = 0;
+	uint32_t count = 0;
+	uint32_t gcmax_reg;
+	u32 blue, green, red;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/* Program first 512 values in precision palette */
+	while (count < BDW_12BIT_GAMMA_MAX_VALS - 1) {
+
+		blue = correction_values[count].b32;
+		green = correction_values[count].g32;
+		red = correction_values[count].r32;
+
+		/*
+		* Maximum possible gamma correction value supported
+		* for BDW is 0xFFFFFFFF, so clamp the values accordingly
+		*/
+		if (blue >= BDW_MAX_GAMMA)
+			blue = BDW_MAX_GAMMA;
+		if (green >= BDW_MAX_GAMMA)
+			green = BDW_MAX_GAMMA;
+		if (red >= BDW_MAX_GAMMA)
+			red = BDW_MAX_GAMMA;
+
+		/*
+		* Framework's general gamma format is 8.24 (8 int 16 fraction)
+		* BDW Platform's supported gamma format is 16 bit correction
+		* values in 0.16 format. So extract higher 16 fraction bits
+		* from 8.24 gamma correction values.
+		*/
+		red_fract = GET_BITS(red, 8, 16);
+		green_fract = GET_BITS(green, 8, 16);
+		blue_fract = GET_BITS(blue, 8, 16);
+
+		/*
+		* From the bspec:
+		* For 12 bit gamma correction, program precision palette
+		* with 16 bits per color in a 0.16 format with 0 integer and
+		* 16 fractional bits (upper 10 bits in odd indexes, lower 6
+		* bits in even indexes)
+		*/
+
+		/* Even index: Lower 6 bits from correction should go as MSB */
+		SET_BITS(word, GET_BITS(red_fract, 0, 6), 24, 6);
+		SET_BITS(word, GET_BITS(green_fract, 0, 6), 14, 6);
+		SET_BITS(word, GET_BITS(blue_fract, 0, 6), 4, 6);
+		I915_WRITE(pal_prec_data, word);
+
+		word = 0x0;
+		/* Odd index: Upper 10 bits of correction should go as MSB */
+		SET_BITS(word, GET_BITS(red_fract, 6, 10), 20, 10);
+		SET_BITS(word, GET_BITS(green_fract, 6, 10), 10, 10);
+		SET_BITS(word, GET_BITS(blue_fract, 6, 10), 0, 10);
+
+		I915_WRITE(pal_prec_data, word);
+		count++;
+	}
+
+	/* Now program the 513th value in GCMAX regs */
+	word = 0;
+	gcmax_reg = _PREC_PAL_GCMAX(pipe);
+	gcmax = min_t(u32, GET_BITS(correction_values[count].r32, 8, 17),
+				BDW_MAX_GAMMA);
+	SET_BITS(word, gcmax, 0, 17);
+	I915_WRITE(gcmax_reg, word);
+	gcmax_reg += 4;
+
+	word = 0;
+	gcmax = min_t(u32, GET_BITS(correction_values[count].g32, 8, 17),
+				BDW_MAX_GAMMA);
+	SET_BITS(word, gcmax, 0, 17);
+	I915_WRITE(gcmax_reg, word);
+	gcmax_reg += 4;
+
+	word = 0;
+	gcmax = min_t(u32, GET_BITS(correction_values[count].b32, 8, 17),
+				BDW_MAX_GAMMA);
+	SET_BITS(word, gcmax, 0, 17);
+	I915_WRITE(gcmax_reg, word);
+}
+
+/* Apply unity gamma for gamma reset */
+static void bdw_reset_gamma(struct drm_i915_private *dev_priv,
+			enum pipe pipe)
+{
+	u16 count = 0;
+	u32 val;
+	u32 pal_prec_data = LGC_PALETTE(pipe, 0);
+
+	DRM_DEBUG_DRIVER("\n");
+
+	/* Reset the palette for unit gamma */
+	while (count < BDW_8BIT_GAMMA_MAX_VALS) {
+		/* Red (23:16) Green (15:8) and Blue (7:0) */
+		val = (count << 16) | (count << 8) | count;
+		I915_WRITE(pal_prec_data, val);
+		pal_prec_data += 4;
+		count++;
+	}
+}
+
+static int bdw_set_gamma(struct drm_device *dev, struct drm_property_blob *blob,
+			struct drm_crtc *crtc)
+{
+	enum pipe pipe;
+	int num_samples;
+	u32 mode, pal_prec_index, pal_prec_data, index;
+	u32 word = 0;
+	struct drm_palette *gamma_data;
+	struct drm_crtc_state *state = crtc->state;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_r32g32b32 *correction_values = NULL;
+
+	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);
+
+	pal_prec_index = _PREC_PAL_INDEX(pipe);
+	pal_prec_data = _PREC_PAL_DATA(pipe);
+
+	correction_values = (struct drm_r32g32b32 *)&gamma_data->lut;
+	index = I915_READ(pal_prec_index);
+
+	switch (num_samples) {
+	case GAMMA_DISABLE_VALS:
+		/* Disable Gamma functionality on Pipe */
+		DRM_DEBUG_DRIVER("Disabling gamma on Pipe %c\n",
+			pipe_name(pipe));
+		mode = I915_READ(GAMMA_MODE(pipe));
+		if ((mode & GAMMA_MODE_MODE_MASK) == GAMMA_MODE_MODE_12BIT)
+			bdw_reset_gamma(dev_priv, pipe);
+		state->palette_after_ctm_blob = NULL;
+		word = GAMMA_MODE_MODE_8BIT;
+		break;
+
+	case BDW_8BIT_GAMMA_MAX_VALS:
+		/* Legacy palette */
+		bdw_write_8bit_gamma_legacy(dev, correction_values,
+				LGC_PALETTE(pipe, 0));
+		word = GAMMA_MODE_MODE_8BIT;
+		break;
+
+	case BDW_SPLITGAMMA_MAX_VALS:
+		index |= BDW_INDEX_AUTO_INCREMENT | BDW_INDEX_SPLIT_MODE;
+		I915_WRITE(pal_prec_index, index);
+		bdw_write_10bit_gamma_precision(dev, correction_values,
+			pal_prec_data, BDW_SPLITGAMMA_MAX_VALS);
+		word = GAMMA_MODE_MODE_SPLIT;
+		break;
+
+	case BDW_12BIT_GAMMA_MAX_VALS:
+		index |= BDW_INDEX_AUTO_INCREMENT;
+		index &= ~BDW_INDEX_SPLIT_MODE;
+		I915_WRITE(pal_prec_index, index);
+		bdw_write_12bit_gamma_precision(dev, correction_values,
+			pal_prec_data, pipe);
+		word = GAMMA_MODE_MODE_12BIT;
+		break;
+
+	case BDW_10BIT_GAMMA_MAX_VALS:
+		index |= BDW_INDEX_AUTO_INCREMENT;
+		index &= ~BDW_INDEX_SPLIT_MODE;
+		I915_WRITE(pal_prec_index, index);
+		bdw_write_10bit_gamma_precision(dev, correction_values,
+			pal_prec_data, BDW_10BIT_GAMMA_MAX_VALS);
+		word = GAMMA_MODE_MODE_10BIT;
+		break;
+
+	default:
+		DRM_ERROR("Invalid number of samples\n");
+		return -EINVAL;
+	}
+
+	/* Set gamma mode on pipe control reg */
+	mode = I915_READ(GAMMA_MODE(pipe));
+	mode &= ~GAMMA_MODE_MODE_MASK;
+	I915_WRITE(GAMMA_MODE(pipe), mode | word);
+	DRM_DEBUG_DRIVER("Gamma applied on pipe %c\n",
+		pipe_name(pipe));
+	return 0;
+}
+
 static s32 chv_prepare_csc_coeff(s64 csc_value)
 {
 	s32 csc_int_value;
@@ -303,6 +582,8 @@ void intel_color_manager_crtc_commit(struct drm_device *dev,
 		/* Gamma correction is platform specific */
 		if (IS_CHERRYVIEW(dev))
 			ret = chv_set_gamma(dev, blob, crtc);
+		else if (IS_BROADWELL(dev) || IS_GEN9(dev))
+			ret = bdw_set_gamma(dev, blob, crtc);
 
 		if (ret)
 			DRM_ERROR("set Gamma correction failed\n");
diff --git a/drivers/gpu/drm/i915/intel_color_manager.h b/drivers/gpu/drm/i915/intel_color_manager.h
index 271246a..6c7cb08 100644
--- a/drivers/gpu/drm/i915/intel_color_manager.h
+++ b/drivers/gpu/drm/i915/intel_color_manager.h
@@ -92,3 +92,9 @@
 
 /* Gamma on BDW */
 #define BDW_SPLITGAMMA_MAX_VALS                512
+#define BDW_8BIT_GAMMA_MAX_VALS		256
+#define BDW_10BIT_GAMMA_MAX_VALS		1024
+#define BDW_12BIT_GAMMA_MAX_VALS		513
+#define BDW_MAX_GAMMA                         ((1 << 24) - 1)
+#define BDW_INDEX_AUTO_INCREMENT               (1 << 15)
+#define BDW_INDEX_SPLIT_MODE                   (1 << 31)
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2015-10-16 14:29 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-16 14:28 [PATCH v6 00/23] Color Management for DRM framework Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 01/23] drm: Create Color Management DRM properties Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 02/23] drm: Create Color Management query properties Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 03/23] drm: Add color correction blobs in CRTC state Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 04/23] drm: Add set property support for color manager Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 05/23] drm: Add get " Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 06/23] drm: Add drm structures for palette color property Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 07/23] drm: Add structure for CTM " Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 08/23] drm/i915: Add set property interface for CRTC Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 09/23] drm/i915: Create color management files Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 10/23] drm/i915: Register color correction capabilities Shashank Sharma
2015-10-16 14:28 ` [PATCH v6 11/23] drm/i915: CHV: Load gamma color correction values Shashank Sharma
2015-10-16 14:29 ` [PATCH v6 12/23] drm/i915: CHV: Load degamma " Shashank Sharma
2015-10-16 14:29 ` [PATCH v6 13/23] drm/i915: CHV: Pipe level Gamma correction Shashank Sharma
2015-10-16 14:29 ` [PATCH v6 14/23] drm/i915: CHV: Pipe level degamma correction Shashank Sharma
2015-10-19 18:08   ` Smith, Gary K
2015-10-19 18:54     ` Daniel Vetter
2015-10-19 20:39       ` Bish, Jim
2015-10-19 21:57         ` [Intel-gfx] " Daniel Vetter
2015-10-19 22:23           ` Smith, Gary K
2015-10-19 22:27             ` Smith, Gary K
2015-10-19 23:48               ` [Intel-gfx] " Matheson, Annie J
2015-10-20  4:09                 ` Sharma, Shashank
2015-10-20  7:27               ` Daniel Vetter
2015-10-20  8:15                 ` [Intel-gfx] " Sharma, Shashank
2015-10-20 12:11                 ` Sharma, Shashank
2015-10-16 14:29 ` [PATCH v6 15/23] drm/i915: CHV: Pipe level CSC correction Shashank Sharma
2015-10-16 14:29 ` [PATCH v6 16/23] drm/i915: Commit color correction to CRTC Shashank Sharma
2015-10-16 14:29 ` [PATCH v6 17/23] drm/i915: Attach color properties " Shashank Sharma
2015-10-16 14:29 ` [PATCH v6 18/23] drm/i915: BDW: Load gamma correction values Shashank Sharma
2015-10-16 14:29 ` Shashank Sharma [this message]
2015-10-16 14:29 ` [PATCH v6 20/23] drm/i915: BDW: Load degamma " Shashank Sharma
2015-10-16 14:29 ` [PATCH v6 21/23] drm/i915: BDW: Pipe level degamma correction Shashank Sharma
2015-10-16 14:29 ` [PATCH v6 22/23] drm/i915: BDW: Pipe level CSC correction Shashank Sharma
2015-10-16 14:29 ` [PATCH v6 23/23] drm/i915: disable plane gamma Shashank Sharma

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1445005751-14918-20-git-send-email-shashank.sharma@intel.com \
    --to=shashank.sharma@intel.com \
    --cc=annie.j.matheson@intel.com \
    --cc=avinash.reddy.palleti@intel.com \
    --cc=daniel.vetter@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=emil.l.velikov@gmail.com \
    --cc=gary.k.smith@intel.com \
    --cc=indranil.mukherjee@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jim.bish@intel.com \
    --cc=kausalmalladi@gmail.com \
    --cc=kiran.s.kumar@intel.com \
    --cc=matthew.d.roper@intel.com \
    --cc=robert.bradford@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.