Home | History | Annotate | Line # | Download | only in display
      1 /*	$NetBSD: intel_color.c,v 1.2 2021/12/18 23:45:29 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright  2016 Intel Corporation
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the next
     14  * paragraph) shall be included in all copies or substantial portions of the
     15  * Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     23  * DEALINGS IN THE SOFTWARE.
     24  *
     25  */
     26 
     27 #include <sys/cdefs.h>
     28 __KERNEL_RCSID(0, "$NetBSD: intel_color.c,v 1.2 2021/12/18 23:45:29 riastradh Exp $");
     29 
     30 #include "intel_color.h"
     31 #include "intel_display_types.h"
     32 
     33 #define CTM_COEFF_SIGN	(1ULL << 63)
     34 
     35 #define CTM_COEFF_1_0	(1ULL << 32)
     36 #define CTM_COEFF_2_0	(CTM_COEFF_1_0 << 1)
     37 #define CTM_COEFF_4_0	(CTM_COEFF_2_0 << 1)
     38 #define CTM_COEFF_8_0	(CTM_COEFF_4_0 << 1)
     39 #define CTM_COEFF_0_5	(CTM_COEFF_1_0 >> 1)
     40 #define CTM_COEFF_0_25	(CTM_COEFF_0_5 >> 1)
     41 #define CTM_COEFF_0_125	(CTM_COEFF_0_25 >> 1)
     42 
     43 #define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
     44 
     45 #define CTM_COEFF_NEGATIVE(coeff)	(((coeff) & CTM_COEFF_SIGN) != 0)
     46 #define CTM_COEFF_ABS(coeff)		((coeff) & (CTM_COEFF_SIGN - 1))
     47 
     48 #define LEGACY_LUT_LENGTH		256
     49 
     50 /*
     51  * ILK+ csc matrix:
     52  *
     53  * |R/Cr|   | c0 c1 c2 |   ( |R/Cr|   |preoff0| )   |postoff0|
     54  * |G/Y | = | c3 c4 c5 | x ( |G/Y | + |preoff1| ) + |postoff1|
     55  * |B/Cb|   | c6 c7 c8 |   ( |B/Cb|   |preoff2| )   |postoff2|
     56  *
     57  * ILK/SNB don't have explicit post offsets, and instead
     58  * CSC_MODE_YUV_TO_RGB and CSC_BLACK_SCREEN_OFFSET are used:
     59  *  CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=0 -> 1/2, 0, 1/2
     60  *  CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/2, 1/16, 1/2
     61  *  CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=0 -> 0, 0, 0
     62  *  CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/16, 1/16, 1/16
     63  */
     64 
     65 /*
     66  * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
     67  * format). This macro takes the coefficient we want transformed and the
     68  * number of fractional bits.
     69  *
     70  * We only have a 9 bits precision window which slides depending on the value
     71  * of the CTM coefficient and we write the value from bit 3. We also round the
     72  * value.
     73  */
     74 #define ILK_CSC_COEFF_FP(coeff, fbits)	\
     75 	(clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
     76 
     77 #define ILK_CSC_COEFF_LIMITED_RANGE 0x0dc0
     78 #define ILK_CSC_COEFF_1_0 0x7800
     79 
     80 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 * (1 << 12) / 255)
     81 
     82 /* Nop pre/post offsets */
     83 static const u16 ilk_csc_off_zero[3] = {};
     84 
     85 /* Identity matrix */
     86 static const u16 ilk_csc_coeff_identity[9] = {
     87 	ILK_CSC_COEFF_1_0, 0, 0,
     88 	0, ILK_CSC_COEFF_1_0, 0,
     89 	0, 0, ILK_CSC_COEFF_1_0,
     90 };
     91 
     92 /* Limited range RGB post offsets */
     93 static const u16 ilk_csc_postoff_limited_range[3] = {
     94 	ILK_CSC_POSTOFF_LIMITED_RANGE,
     95 	ILK_CSC_POSTOFF_LIMITED_RANGE,
     96 	ILK_CSC_POSTOFF_LIMITED_RANGE,
     97 };
     98 
     99 /* Full range RGB -> limited range RGB matrix */
    100 static const u16 ilk_csc_coeff_limited_range[9] = {
    101 	ILK_CSC_COEFF_LIMITED_RANGE, 0, 0,
    102 	0, ILK_CSC_COEFF_LIMITED_RANGE, 0,
    103 	0, 0, ILK_CSC_COEFF_LIMITED_RANGE,
    104 };
    105 
    106 /* BT.709 full range RGB -> limited range YCbCr matrix */
    107 static const u16 ilk_csc_coeff_rgb_to_ycbcr[9] = {
    108 	0x1e08, 0x9cc0, 0xb528,
    109 	0x2ba8, 0x09d8, 0x37e8,
    110 	0xbce8, 0x9ad8, 0x1e08,
    111 };
    112 
    113 /* Limited range YCbCr post offsets */
    114 static const u16 ilk_csc_postoff_rgb_to_ycbcr[3] = {
    115 	0x0800, 0x0100, 0x0800,
    116 };
    117 
    118 static bool lut_is_legacy(const struct drm_property_blob *lut)
    119 {
    120 	return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
    121 }
    122 
    123 static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state *crtc_state)
    124 {
    125 	return !crtc_state->hw.degamma_lut &&
    126 		!crtc_state->hw.ctm &&
    127 		crtc_state->hw.gamma_lut &&
    128 		lut_is_legacy(crtc_state->hw.gamma_lut);
    129 }
    130 
    131 /*
    132  * When using limited range, multiply the matrix given by userspace by
    133  * the matrix that we would use for the limited range.
    134  */
    135 static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
    136 {
    137 	int i;
    138 
    139 	for (i = 0; i < 9; i++) {
    140 		u64 user_coeff = input[i];
    141 		u32 limited_coeff = CTM_COEFF_LIMITED_RANGE;
    142 		u32 abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), 0,
    143 					  CTM_COEFF_4_0 - 1) >> 2;
    144 
    145 		/*
    146 		 * By scaling every co-efficient with limited range (16-235)
    147 		 * vs full range (0-255) the final o/p will be scaled down to
    148 		 * fit in the limited range supported by the panel.
    149 		 */
    150 		result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
    151 		result[i] |= user_coeff & CTM_COEFF_SIGN;
    152 	}
    153 
    154 	return result;
    155 }
    156 
    157 static void ilk_update_pipe_csc(struct intel_crtc *crtc,
    158 				const u16 preoff[3],
    159 				const u16 coeff[9],
    160 				const u16 postoff[3])
    161 {
    162 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    163 	enum pipe pipe = crtc->pipe;
    164 
    165 	I915_WRITE(PIPE_CSC_PREOFF_HI(pipe), preoff[0]);
    166 	I915_WRITE(PIPE_CSC_PREOFF_ME(pipe), preoff[1]);
    167 	I915_WRITE(PIPE_CSC_PREOFF_LO(pipe), preoff[2]);
    168 
    169 	I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]);
    170 	I915_WRITE(PIPE_CSC_COEFF_BY(pipe), coeff[2] << 16);
    171 
    172 	I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]);
    173 	I915_WRITE(PIPE_CSC_COEFF_BU(pipe), coeff[5] << 16);
    174 
    175 	I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]);
    176 	I915_WRITE(PIPE_CSC_COEFF_BV(pipe), coeff[8] << 16);
    177 
    178 	if (INTEL_GEN(dev_priv) >= 7) {
    179 		I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe), postoff[0]);
    180 		I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe), postoff[1]);
    181 		I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe), postoff[2]);
    182 	}
    183 }
    184 
    185 static void icl_update_output_csc(struct intel_crtc *crtc,
    186 				  const u16 preoff[3],
    187 				  const u16 coeff[9],
    188 				  const u16 postoff[3])
    189 {
    190 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    191 	enum pipe pipe = crtc->pipe;
    192 
    193 	I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_HI(pipe), preoff[0]);
    194 	I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_ME(pipe), preoff[1]);
    195 	I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_LO(pipe), preoff[2]);
    196 
    197 	I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe), coeff[0] << 16 | coeff[1]);
    198 	I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BY(pipe), coeff[2] << 16);
    199 
    200 	I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe), coeff[3] << 16 | coeff[4]);
    201 	I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BU(pipe), coeff[5] << 16);
    202 
    203 	I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe), coeff[6] << 16 | coeff[7]);
    204 	I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BV(pipe), coeff[8] << 16);
    205 
    206 	I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), postoff[0]);
    207 	I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), postoff[1]);
    208 	I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), postoff[2]);
    209 }
    210 
    211 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
    212 {
    213 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
    214 
    215 	/*
    216 	 * FIXME if there's a gamma LUT after the CSC, we should
    217 	 * do the range compression using the gamma LUT instead.
    218 	 */
    219 	return crtc_state->limited_color_range &&
    220 		(IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv) ||
    221 		 IS_GEN_RANGE(dev_priv, 9, 10));
    222 }
    223 
    224 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
    225 				u16 coeffs[9])
    226 {
    227 	const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
    228 	const u64 *input;
    229 	u64 temp[9];
    230 	int i;
    231 
    232 	if (ilk_csc_limited_range(crtc_state))
    233 		input = ctm_mult_by_limited(temp, ctm->matrix);
    234 	else
    235 		input = ctm->matrix;
    236 
    237 	/*
    238 	 * Convert fixed point S31.32 input to format supported by the
    239 	 * hardware.
    240 	 */
    241 	for (i = 0; i < 9; i++) {
    242 		u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
    243 
    244 		/*
    245 		 * Clamp input value to min/max supported by
    246 		 * hardware.
    247 		 */
    248 		abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
    249 
    250 		coeffs[i] = 0;
    251 
    252 		/* sign bit */
    253 		if (CTM_COEFF_NEGATIVE(input[i]))
    254 			coeffs[i] |= 1 << 15;
    255 
    256 		if (abs_coeff < CTM_COEFF_0_125)
    257 			coeffs[i] |= (3 << 12) |
    258 				ILK_CSC_COEFF_FP(abs_coeff, 12);
    259 		else if (abs_coeff < CTM_COEFF_0_25)
    260 			coeffs[i] |= (2 << 12) |
    261 				ILK_CSC_COEFF_FP(abs_coeff, 11);
    262 		else if (abs_coeff < CTM_COEFF_0_5)
    263 			coeffs[i] |= (1 << 12) |
    264 				ILK_CSC_COEFF_FP(abs_coeff, 10);
    265 		else if (abs_coeff < CTM_COEFF_1_0)
    266 			coeffs[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9);
    267 		else if (abs_coeff < CTM_COEFF_2_0)
    268 			coeffs[i] |= (7 << 12) |
    269 				ILK_CSC_COEFF_FP(abs_coeff, 8);
    270 		else
    271 			coeffs[i] |= (6 << 12) |
    272 				ILK_CSC_COEFF_FP(abs_coeff, 7);
    273 	}
    274 }
    275 
    276 static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
    277 {
    278 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    279 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    280 	bool limited_color_range = ilk_csc_limited_range(crtc_state);
    281 
    282 	if (crtc_state->hw.ctm) {
    283 		u16 coeff[9];
    284 
    285 		ilk_csc_convert_ctm(crtc_state, coeff);
    286 		ilk_update_pipe_csc(crtc, ilk_csc_off_zero, coeff,
    287 				    limited_color_range ?
    288 				    ilk_csc_postoff_limited_range :
    289 				    ilk_csc_off_zero);
    290 	} else if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
    291 		ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
    292 				    ilk_csc_coeff_rgb_to_ycbcr,
    293 				    ilk_csc_postoff_rgb_to_ycbcr);
    294 	} else if (limited_color_range) {
    295 		ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
    296 				    ilk_csc_coeff_limited_range,
    297 				    ilk_csc_postoff_limited_range);
    298 	} else if (crtc_state->csc_enable) {
    299 		/*
    300 		 * On GLK+ both pipe CSC and degamma LUT are controlled
    301 		 * by csc_enable. Hence for the cases where the degama
    302 		 * LUT is needed but CSC is not we need to load an
    303 		 * identity matrix.
    304 		 */
    305 		WARN_ON(!IS_CANNONLAKE(dev_priv) && !IS_GEMINILAKE(dev_priv));
    306 
    307 		ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
    308 				    ilk_csc_coeff_identity,
    309 				    ilk_csc_off_zero);
    310 	}
    311 
    312 	I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
    313 }
    314 
    315 static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
    316 {
    317 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    318 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    319 
    320 	if (crtc_state->hw.ctm) {
    321 		u16 coeff[9];
    322 
    323 		ilk_csc_convert_ctm(crtc_state, coeff);
    324 		ilk_update_pipe_csc(crtc, ilk_csc_off_zero,
    325 				    coeff, ilk_csc_off_zero);
    326 	}
    327 
    328 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
    329 		icl_update_output_csc(crtc, ilk_csc_off_zero,
    330 				      ilk_csc_coeff_rgb_to_ycbcr,
    331 				      ilk_csc_postoff_rgb_to_ycbcr);
    332 	} else if (crtc_state->limited_color_range) {
    333 		icl_update_output_csc(crtc, ilk_csc_off_zero,
    334 				      ilk_csc_coeff_limited_range,
    335 				      ilk_csc_postoff_limited_range);
    336 	}
    337 
    338 	I915_WRITE(PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode);
    339 }
    340 
    341 /*
    342  * Set up the pipe CSC unit on CherryView.
    343  */
    344 static void cherryview_load_csc_matrix(const struct intel_crtc_state *crtc_state)
    345 {
    346 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    347 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    348 	enum pipe pipe = crtc->pipe;
    349 
    350 	if (crtc_state->hw.ctm) {
    351 		const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
    352 		u16 coeffs[9] = {};
    353 		int i;
    354 
    355 		for (i = 0; i < ARRAY_SIZE(coeffs); i++) {
    356 			u64 abs_coeff =
    357 				((1ULL << 63) - 1) & ctm->matrix[i];
    358 
    359 			/* Round coefficient. */
    360 			abs_coeff += 1 << (32 - 13);
    361 			/* Clamp to hardware limits. */
    362 			abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_8_0 - 1);
    363 
    364 			/* Write coefficients in S3.12 format. */
    365 			if (ctm->matrix[i] & (1ULL << 63))
    366 				coeffs[i] = 1 << 15;
    367 			coeffs[i] |= ((abs_coeff >> 32) & 7) << 12;
    368 			coeffs[i] |= (abs_coeff >> 20) & 0xfff;
    369 		}
    370 
    371 		I915_WRITE(CGM_PIPE_CSC_COEFF01(pipe),
    372 			   coeffs[1] << 16 | coeffs[0]);
    373 		I915_WRITE(CGM_PIPE_CSC_COEFF23(pipe),
    374 			   coeffs[3] << 16 | coeffs[2]);
    375 		I915_WRITE(CGM_PIPE_CSC_COEFF45(pipe),
    376 			   coeffs[5] << 16 | coeffs[4]);
    377 		I915_WRITE(CGM_PIPE_CSC_COEFF67(pipe),
    378 			   coeffs[7] << 16 | coeffs[6]);
    379 		I915_WRITE(CGM_PIPE_CSC_COEFF8(pipe), coeffs[8]);
    380 	}
    381 
    382 	I915_WRITE(CGM_PIPE_MODE(pipe), crtc_state->cgm_mode);
    383 }
    384 
    385 /* i965+ "10.6" bit interpolated format "even DW" (low 8 bits) */
    386 static u32 i965_lut_10p6_ldw(const struct drm_color_lut *color)
    387 {
    388 	return (color->red & 0xff) << 16 |
    389 		(color->green & 0xff) << 8 |
    390 		(color->blue & 0xff);
    391 }
    392 
    393 /* i965+ "10.6" interpolated format "odd DW" (high 8 bits) */
    394 static u32 i965_lut_10p6_udw(const struct drm_color_lut *color)
    395 {
    396 	return (color->red >> 8) << 16 |
    397 		(color->green >> 8) << 8 |
    398 		(color->blue >> 8);
    399 }
    400 
    401 static u32 ilk_lut_10(const struct drm_color_lut *color)
    402 {
    403 	return drm_color_lut_extract(color->red, 10) << 20 |
    404 		drm_color_lut_extract(color->green, 10) << 10 |
    405 		drm_color_lut_extract(color->blue, 10);
    406 }
    407 
    408 /* Loads the legacy palette/gamma unit for the CRTC. */
    409 static void i9xx_load_luts_internal(const struct intel_crtc_state *crtc_state,
    410 				    const struct drm_property_blob *blob)
    411 {
    412 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    413 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    414 	enum pipe pipe = crtc->pipe;
    415 	int i;
    416 
    417 	if (HAS_GMCH(dev_priv)) {
    418 		if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI))
    419 			assert_dsi_pll_enabled(dev_priv);
    420 		else
    421 			assert_pll_enabled(dev_priv, pipe);
    422 	}
    423 
    424 	if (blob) {
    425 		const struct drm_color_lut *lut = blob->data;
    426 
    427 		for (i = 0; i < 256; i++) {
    428 			u32 word =
    429 				(drm_color_lut_extract(lut[i].red, 8) << 16) |
    430 				(drm_color_lut_extract(lut[i].green, 8) << 8) |
    431 				drm_color_lut_extract(lut[i].blue, 8);
    432 
    433 			if (HAS_GMCH(dev_priv))
    434 				I915_WRITE(PALETTE(pipe, i), word);
    435 			else
    436 				I915_WRITE(LGC_PALETTE(pipe, i), word);
    437 		}
    438 	}
    439 }
    440 
    441 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
    442 {
    443 	i9xx_load_luts_internal(crtc_state, crtc_state->hw.gamma_lut);
    444 }
    445 
    446 static void i9xx_color_commit(const struct intel_crtc_state *crtc_state)
    447 {
    448 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    449 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    450 	enum pipe pipe = crtc->pipe;
    451 	u32 val;
    452 
    453 	val = I915_READ(PIPECONF(pipe));
    454 	val &= ~PIPECONF_GAMMA_MODE_MASK_I9XX;
    455 	val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
    456 	I915_WRITE(PIPECONF(pipe), val);
    457 }
    458 
    459 static void ilk_color_commit(const struct intel_crtc_state *crtc_state)
    460 {
    461 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    462 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    463 	enum pipe pipe = crtc->pipe;
    464 	u32 val;
    465 
    466 	val = I915_READ(PIPECONF(pipe));
    467 	val &= ~PIPECONF_GAMMA_MODE_MASK_ILK;
    468 	val |= PIPECONF_GAMMA_MODE(crtc_state->gamma_mode);
    469 	I915_WRITE(PIPECONF(pipe), val);
    470 
    471 	ilk_load_csc_matrix(crtc_state);
    472 }
    473 
    474 static void hsw_color_commit(const struct intel_crtc_state *crtc_state)
    475 {
    476 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    477 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    478 
    479 	I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
    480 
    481 	ilk_load_csc_matrix(crtc_state);
    482 }
    483 
    484 static void skl_color_commit(const struct intel_crtc_state *crtc_state)
    485 {
    486 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    487 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    488 	enum pipe pipe = crtc->pipe;
    489 	u32 val = 0;
    490 
    491 	/*
    492 	 * We don't (yet) allow userspace to control the pipe background color,
    493 	 * so force it to black, but apply pipe gamma and CSC appropriately
    494 	 * so that its handling will match how we program our planes.
    495 	 */
    496 	if (crtc_state->gamma_enable)
    497 		val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
    498 	if (crtc_state->csc_enable)
    499 		val |= SKL_BOTTOM_COLOR_CSC_ENABLE;
    500 	I915_WRITE(SKL_BOTTOM_COLOR(pipe), val);
    501 
    502 	I915_WRITE(GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode);
    503 
    504 	if (INTEL_GEN(dev_priv) >= 11)
    505 		icl_load_csc_matrix(crtc_state);
    506 	else
    507 		ilk_load_csc_matrix(crtc_state);
    508 }
    509 
    510 static void i965_load_lut_10p6(struct intel_crtc *crtc,
    511 			       const struct drm_property_blob *blob)
    512 {
    513 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    514 	const struct drm_color_lut *lut = blob->data;
    515 	int i, lut_size = drm_color_lut_size(blob);
    516 	enum pipe pipe = crtc->pipe;
    517 
    518 	for (i = 0; i < lut_size - 1; i++) {
    519 		I915_WRITE(PALETTE(pipe, 2 * i + 0),
    520 			   i965_lut_10p6_ldw(&lut[i]));
    521 		I915_WRITE(PALETTE(pipe, 2 * i + 1),
    522 			   i965_lut_10p6_udw(&lut[i]));
    523 	}
    524 
    525 	I915_WRITE(PIPEGCMAX(pipe, 0), lut[i].red);
    526 	I915_WRITE(PIPEGCMAX(pipe, 1), lut[i].green);
    527 	I915_WRITE(PIPEGCMAX(pipe, 2), lut[i].blue);
    528 }
    529 
    530 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
    531 {
    532 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    533 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
    534 
    535 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
    536 		i9xx_load_luts(crtc_state);
    537 	else
    538 		i965_load_lut_10p6(crtc, gamma_lut);
    539 }
    540 
    541 static void ilk_load_lut_10(struct intel_crtc *crtc,
    542 			    const struct drm_property_blob *blob)
    543 {
    544 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    545 	const struct drm_color_lut *lut = blob->data;
    546 	int i, lut_size = drm_color_lut_size(blob);
    547 	enum pipe pipe = crtc->pipe;
    548 
    549 	for (i = 0; i < lut_size; i++)
    550 		I915_WRITE(PREC_PALETTE(pipe, i), ilk_lut_10(&lut[i]));
    551 }
    552 
    553 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
    554 {
    555 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    556 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
    557 
    558 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
    559 		i9xx_load_luts(crtc_state);
    560 	else
    561 		ilk_load_lut_10(crtc, gamma_lut);
    562 }
    563 
    564 static int ivb_lut_10_size(u32 prec_index)
    565 {
    566 	if (prec_index & PAL_PREC_SPLIT_MODE)
    567 		return 512;
    568 	else
    569 		return 1024;
    570 }
    571 
    572 /*
    573  * IVB/HSW Bspec / PAL_PREC_INDEX:
    574  * "Restriction : Index auto increment mode is not
    575  *  supported and must not be enabled."
    576  */
    577 static void ivb_load_lut_10(struct intel_crtc *crtc,
    578 			    const struct drm_property_blob *blob,
    579 			    u32 prec_index)
    580 {
    581 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    582 	int hw_lut_size = ivb_lut_10_size(prec_index);
    583 	const struct drm_color_lut *lut = blob->data;
    584 	int i, lut_size = drm_color_lut_size(blob);
    585 	enum pipe pipe = crtc->pipe;
    586 
    587 	for (i = 0; i < hw_lut_size; i++) {
    588 		/* We discard half the user entries in split gamma mode */
    589 		const struct drm_color_lut *entry =
    590 			&lut[i * (lut_size - 1) / (hw_lut_size - 1)];
    591 
    592 		I915_WRITE(PREC_PAL_INDEX(pipe), prec_index++);
    593 		I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
    594 	}
    595 
    596 	/*
    597 	 * Reset the index, otherwise it prevents the legacy palette to be
    598 	 * written properly.
    599 	 */
    600 	I915_WRITE(PREC_PAL_INDEX(pipe), 0);
    601 }
    602 
    603 /* On BDW+ the index auto increment mode actually works */
    604 static void bdw_load_lut_10(struct intel_crtc *crtc,
    605 			    const struct drm_property_blob *blob,
    606 			    u32 prec_index)
    607 {
    608 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    609 	int hw_lut_size = ivb_lut_10_size(prec_index);
    610 	const struct drm_color_lut *lut = blob->data;
    611 	int i, lut_size = drm_color_lut_size(blob);
    612 	enum pipe pipe = crtc->pipe;
    613 
    614 	I915_WRITE(PREC_PAL_INDEX(pipe), prec_index |
    615 		   PAL_PREC_AUTO_INCREMENT);
    616 
    617 	for (i = 0; i < hw_lut_size; i++) {
    618 		/* We discard half the user entries in split gamma mode */
    619 		const struct drm_color_lut *entry =
    620 			&lut[i * (lut_size - 1) / (hw_lut_size - 1)];
    621 
    622 		I915_WRITE(PREC_PAL_DATA(pipe), ilk_lut_10(entry));
    623 	}
    624 
    625 	/*
    626 	 * Reset the index, otherwise it prevents the legacy palette to be
    627 	 * written properly.
    628 	 */
    629 	I915_WRITE(PREC_PAL_INDEX(pipe), 0);
    630 }
    631 
    632 static void ivb_load_lut_ext_max(struct intel_crtc *crtc)
    633 {
    634 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    635 	struct intel_dsb *dsb = intel_dsb_get(crtc);
    636 	enum pipe pipe = crtc->pipe;
    637 
    638 	/* Program the max register to clamp values > 1.0. */
    639 	intel_dsb_reg_write(dsb, PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16);
    640 	intel_dsb_reg_write(dsb, PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16);
    641 	intel_dsb_reg_write(dsb, PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16);
    642 
    643 	/*
    644 	 * Program the gc max 2 register to clamp values > 1.0.
    645 	 * ToDo: Extend the ABI to be able to program values
    646 	 * from 3.0 to 7.0
    647 	 */
    648 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
    649 		intel_dsb_reg_write(dsb, PREC_PAL_EXT2_GC_MAX(pipe, 0),
    650 				    1 << 16);
    651 		intel_dsb_reg_write(dsb, PREC_PAL_EXT2_GC_MAX(pipe, 1),
    652 				    1 << 16);
    653 		intel_dsb_reg_write(dsb, PREC_PAL_EXT2_GC_MAX(pipe, 2),
    654 				    1 << 16);
    655 	}
    656 
    657 	intel_dsb_put(dsb);
    658 }
    659 
    660 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
    661 {
    662 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    663 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
    664 	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
    665 
    666 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
    667 		i9xx_load_luts(crtc_state);
    668 	} else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
    669 		ivb_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
    670 				PAL_PREC_INDEX_VALUE(0));
    671 		ivb_load_lut_ext_max(crtc);
    672 		ivb_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
    673 				PAL_PREC_INDEX_VALUE(512));
    674 	} else {
    675 		const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
    676 
    677 		ivb_load_lut_10(crtc, blob,
    678 				PAL_PREC_INDEX_VALUE(0));
    679 		ivb_load_lut_ext_max(crtc);
    680 	}
    681 }
    682 
    683 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
    684 {
    685 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    686 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
    687 	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
    688 
    689 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
    690 		i9xx_load_luts(crtc_state);
    691 	} else if (crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) {
    692 		bdw_load_lut_10(crtc, degamma_lut, PAL_PREC_SPLIT_MODE |
    693 				PAL_PREC_INDEX_VALUE(0));
    694 		ivb_load_lut_ext_max(crtc);
    695 		bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_SPLIT_MODE |
    696 				PAL_PREC_INDEX_VALUE(512));
    697 	} else {
    698 		const struct drm_property_blob *blob = gamma_lut ?: degamma_lut;
    699 
    700 		bdw_load_lut_10(crtc, blob,
    701 				PAL_PREC_INDEX_VALUE(0));
    702 		ivb_load_lut_ext_max(crtc);
    703 	}
    704 }
    705 
    706 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state)
    707 {
    708 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    709 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    710 	enum pipe pipe = crtc->pipe;
    711 	const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
    712 	const struct drm_color_lut *lut = crtc_state->hw.degamma_lut->data;
    713 	u32 i;
    714 
    715 	/*
    716 	 * When setting the auto-increment bit, the hardware seems to
    717 	 * ignore the index bits, so we need to reset it to index 0
    718 	 * separately.
    719 	 */
    720 	I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
    721 	I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
    722 
    723 	for (i = 0; i < lut_size; i++) {
    724 		/*
    725 		 * First 33 entries represent range from 0 to 1.0
    726 		 * 34th and 35th entry will represent extended range
    727 		 * inputs 3.0 and 7.0 respectively, currently clamped
    728 		 * at 1.0. Since the precision is 16bit, the user
    729 		 * value can be directly filled to register.
    730 		 * The pipe degamma table in GLK+ onwards doesn't
    731 		 * support different values per channel, so this just
    732 		 * programs green value which will be equal to Red and
    733 		 * Blue into the lut registers.
    734 		 * ToDo: Extend to max 7.0. Enable 32 bit input value
    735 		 * as compared to just 16 to achieve this.
    736 		 */
    737 		I915_WRITE(PRE_CSC_GAMC_DATA(pipe), lut[i].green);
    738 	}
    739 
    740 	/* Clamp values > 1.0. */
    741 	while (i++ < 35)
    742 		I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
    743 }
    744 
    745 static void glk_load_degamma_lut_linear(const struct intel_crtc_state *crtc_state)
    746 {
    747 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    748 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    749 	enum pipe pipe = crtc->pipe;
    750 	const u32 lut_size = INTEL_INFO(dev_priv)->color.degamma_lut_size;
    751 	u32 i;
    752 
    753 	/*
    754 	 * When setting the auto-increment bit, the hardware seems to
    755 	 * ignore the index bits, so we need to reset it to index 0
    756 	 * separately.
    757 	 */
    758 	I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), 0);
    759 	I915_WRITE(PRE_CSC_GAMC_INDEX(pipe), PRE_CSC_GAMC_AUTO_INCREMENT);
    760 
    761 	for (i = 0; i < lut_size; i++) {
    762 		u32 v = (i << 16) / (lut_size - 1);
    763 
    764 		I915_WRITE(PRE_CSC_GAMC_DATA(pipe), v);
    765 	}
    766 
    767 	/* Clamp values > 1.0. */
    768 	while (i++ < 35)
    769 		I915_WRITE(PRE_CSC_GAMC_DATA(pipe), 1 << 16);
    770 }
    771 
    772 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
    773 {
    774 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
    775 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    776 
    777 	/*
    778 	 * On GLK+ both pipe CSC and degamma LUT are controlled
    779 	 * by csc_enable. Hence for the cases where the CSC is
    780 	 * needed but degamma LUT is not we need to load a
    781 	 * linear degamma LUT. In fact we'll just always load
    782 	 * the degama LUT so that we don't have to reload
    783 	 * it every time the pipe CSC is being enabled.
    784 	 */
    785 	if (crtc_state->hw.degamma_lut)
    786 		glk_load_degamma_lut(crtc_state);
    787 	else
    788 		glk_load_degamma_lut_linear(crtc_state);
    789 
    790 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT) {
    791 		i9xx_load_luts(crtc_state);
    792 	} else {
    793 		bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
    794 		ivb_load_lut_ext_max(crtc);
    795 	}
    796 }
    797 
    798 /* ilk+ "12.4" interpolated format (high 10 bits) */
    799 static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color)
    800 {
    801 	return (color->red >> 6) << 20 | (color->green >> 6) << 10 |
    802 		(color->blue >> 6);
    803 }
    804 
    805 /* ilk+ "12.4" interpolated format (low 6 bits) */
    806 static u32 ilk_lut_12p4_ldw(const struct drm_color_lut *color)
    807 {
    808 	return (color->red & 0x3f) << 24 | (color->green & 0x3f) << 14 |
    809 		(color->blue & 0x3f) << 4;
    810 }
    811 
    812 static void
    813 icl_load_gcmax(const struct intel_crtc_state *crtc_state,
    814 	       const struct drm_color_lut *color)
    815 {
    816 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    817 	struct intel_dsb *dsb = intel_dsb_get(crtc);
    818 	enum pipe pipe = crtc->pipe;
    819 
    820 	/* Fixme: LUT entries are 16 bit only, so we can prog 0xFFFF max */
    821 	intel_dsb_reg_write(dsb, PREC_PAL_GC_MAX(pipe, 0), color->red);
    822 	intel_dsb_reg_write(dsb, PREC_PAL_GC_MAX(pipe, 1), color->green);
    823 	intel_dsb_reg_write(dsb, PREC_PAL_GC_MAX(pipe, 2), color->blue);
    824 	intel_dsb_put(dsb);
    825 }
    826 
    827 static void
    828 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
    829 {
    830 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    831 	const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
    832 	const struct drm_color_lut *lut = blob->data;
    833 	struct intel_dsb *dsb = intel_dsb_get(crtc);
    834 	enum pipe pipe = crtc->pipe;
    835 	u32 i;
    836 
    837 	/*
    838 	 * Program Super Fine segment (let's call it seg1)...
    839 	 *
    840 	 * Super Fine segment's step is 1/(8 * 128 * 256) and it has
    841 	 * 9 entries, corresponding to values 0, 1/(8 * 128 * 256),
    842 	 * 2/(8 * 128 * 256) ... 8/(8 * 128 * 256).
    843 	 */
    844 	intel_dsb_reg_write(dsb, PREC_PAL_MULTI_SEG_INDEX(pipe),
    845 			    PAL_PREC_AUTO_INCREMENT);
    846 
    847 	for (i = 0; i < 9; i++) {
    848 		const struct drm_color_lut *entry = &lut[i];
    849 
    850 		intel_dsb_indexed_reg_write(dsb, PREC_PAL_MULTI_SEG_DATA(pipe),
    851 					    ilk_lut_12p4_ldw(entry));
    852 		intel_dsb_indexed_reg_write(dsb, PREC_PAL_MULTI_SEG_DATA(pipe),
    853 					    ilk_lut_12p4_udw(entry));
    854 	}
    855 
    856 	intel_dsb_put(dsb);
    857 }
    858 
    859 static void
    860 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
    861 {
    862 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    863 	const struct drm_property_blob *blob = crtc_state->hw.gamma_lut;
    864 	const struct drm_color_lut *lut = blob->data;
    865 	const struct drm_color_lut *entry;
    866 	struct intel_dsb *dsb = intel_dsb_get(crtc);
    867 	enum pipe pipe = crtc->pipe;
    868 	u32 i;
    869 
    870 	/*
    871 	 * Program Fine segment (let's call it seg2)...
    872 	 *
    873 	 * Fine segment's step is 1/(128 * 256) i.e. 1/(128 * 256), 2/(128 * 256)
    874 	 * ... 256/(128 * 256). So in order to program fine segment of LUT we
    875 	 * need to pick every 8th entry in the LUT, and program 256 indexes.
    876 	 *
    877 	 * PAL_PREC_INDEX[0] and PAL_PREC_INDEX[1] map to seg2[1],
    878 	 * seg2[0] being unused by the hardware.
    879 	 */
    880 	intel_dsb_reg_write(dsb, PREC_PAL_INDEX(pipe), PAL_PREC_AUTO_INCREMENT);
    881 	for (i = 1; i < 257; i++) {
    882 		entry = &lut[i * 8];
    883 		intel_dsb_indexed_reg_write(dsb, PREC_PAL_DATA(pipe),
    884 					    ilk_lut_12p4_ldw(entry));
    885 		intel_dsb_indexed_reg_write(dsb, PREC_PAL_DATA(pipe),
    886 					    ilk_lut_12p4_udw(entry));
    887 	}
    888 
    889 	/*
    890 	 * Program Coarse segment (let's call it seg3)...
    891 	 *
    892 	 * Coarse segment starts from index 0 and it's step is 1/256 ie 0,
    893 	 * 1/256, 2/256 ... 256/256. As per the description of each entry in LUT
    894 	 * above, we need to pick every (8 * 128)th entry in LUT, and
    895 	 * program 256 of those.
    896 	 *
    897 	 * Spec is not very clear about if entries seg3[0] and seg3[1] are
    898 	 * being used or not, but we still need to program these to advance
    899 	 * the index.
    900 	 */
    901 	for (i = 0; i < 256; i++) {
    902 		entry = &lut[i * 8 * 128];
    903 		intel_dsb_indexed_reg_write(dsb, PREC_PAL_DATA(pipe),
    904 					    ilk_lut_12p4_ldw(entry));
    905 		intel_dsb_indexed_reg_write(dsb, PREC_PAL_DATA(pipe),
    906 					    ilk_lut_12p4_udw(entry));
    907 	}
    908 
    909 	/* The last entry in the LUT is to be programmed in GCMAX */
    910 	entry = &lut[256 * 8 * 128];
    911 	icl_load_gcmax(crtc_state, entry);
    912 	ivb_load_lut_ext_max(crtc);
    913 	intel_dsb_put(dsb);
    914 }
    915 
    916 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
    917 {
    918 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
    919 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    920 	struct intel_dsb *dsb = intel_dsb_get(crtc);
    921 
    922 	if (crtc_state->hw.degamma_lut)
    923 		glk_load_degamma_lut(crtc_state);
    924 
    925 	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
    926 	case GAMMA_MODE_MODE_8BIT:
    927 		i9xx_load_luts(crtc_state);
    928 		break;
    929 	case GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED:
    930 		icl_program_gamma_superfine_segment(crtc_state);
    931 		icl_program_gamma_multi_segment(crtc_state);
    932 		break;
    933 	default:
    934 		bdw_load_lut_10(crtc, gamma_lut, PAL_PREC_INDEX_VALUE(0));
    935 		ivb_load_lut_ext_max(crtc);
    936 	}
    937 
    938 	intel_dsb_commit(dsb);
    939 	intel_dsb_put(dsb);
    940 }
    941 
    942 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
    943 {
    944 	return drm_color_lut_extract(color->green, 14) << 16 |
    945 		drm_color_lut_extract(color->blue, 14);
    946 }
    947 
    948 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
    949 {
    950 	return drm_color_lut_extract(color->red, 14);
    951 }
    952 
    953 static void chv_load_cgm_degamma(struct intel_crtc *crtc,
    954 				 const struct drm_property_blob *blob)
    955 {
    956 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    957 	const struct drm_color_lut *lut = blob->data;
    958 	int i, lut_size = drm_color_lut_size(blob);
    959 	enum pipe pipe = crtc->pipe;
    960 
    961 	for (i = 0; i < lut_size; i++) {
    962 		I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 0),
    963 			   chv_cgm_degamma_ldw(&lut[i]));
    964 		I915_WRITE(CGM_PIPE_DEGAMMA(pipe, i, 1),
    965 			   chv_cgm_degamma_udw(&lut[i]));
    966 	}
    967 }
    968 
    969 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
    970 {
    971 	return drm_color_lut_extract(color->green, 10) << 16 |
    972 		drm_color_lut_extract(color->blue, 10);
    973 }
    974 
    975 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
    976 {
    977 	return drm_color_lut_extract(color->red, 10);
    978 }
    979 
    980 static void chv_load_cgm_gamma(struct intel_crtc *crtc,
    981 			       const struct drm_property_blob *blob)
    982 {
    983 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    984 	const struct drm_color_lut *lut = blob->data;
    985 	int i, lut_size = drm_color_lut_size(blob);
    986 	enum pipe pipe = crtc->pipe;
    987 
    988 	for (i = 0; i < lut_size; i++) {
    989 		I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 0),
    990 			   chv_cgm_gamma_ldw(&lut[i]));
    991 		I915_WRITE(CGM_PIPE_GAMMA(pipe, i, 1),
    992 			   chv_cgm_gamma_udw(&lut[i]));
    993 	}
    994 }
    995 
    996 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
    997 {
    998 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
    999 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
   1000 	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
   1001 
   1002 	cherryview_load_csc_matrix(crtc_state);
   1003 
   1004 	if (crtc_state_is_legacy_gamma(crtc_state)) {
   1005 		i9xx_load_luts(crtc_state);
   1006 		return;
   1007 	}
   1008 
   1009 	if (degamma_lut)
   1010 		chv_load_cgm_degamma(crtc, degamma_lut);
   1011 
   1012 	if (gamma_lut)
   1013 		chv_load_cgm_gamma(crtc, gamma_lut);
   1014 }
   1015 
   1016 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
   1017 {
   1018 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
   1019 
   1020 	dev_priv->display.load_luts(crtc_state);
   1021 }
   1022 
   1023 void intel_color_commit(const struct intel_crtc_state *crtc_state)
   1024 {
   1025 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
   1026 
   1027 	dev_priv->display.color_commit(crtc_state);
   1028 }
   1029 
   1030 static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
   1031 {
   1032 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
   1033 	struct intel_atomic_state *state =
   1034 		to_intel_atomic_state(new_crtc_state->uapi.state);
   1035 	const struct intel_crtc_state *old_crtc_state =
   1036 		intel_atomic_get_old_crtc_state(state, crtc);
   1037 
   1038 	return !old_crtc_state->hw.gamma_lut &&
   1039 		!old_crtc_state->hw.degamma_lut;
   1040 }
   1041 
   1042 static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
   1043 {
   1044 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
   1045 	struct intel_atomic_state *state =
   1046 		to_intel_atomic_state(new_crtc_state->uapi.state);
   1047 	const struct intel_crtc_state *old_crtc_state =
   1048 		intel_atomic_get_old_crtc_state(state, crtc);
   1049 
   1050 	/*
   1051 	 * CGM_PIPE_MODE is itself single buffered. We'd have to
   1052 	 * somehow split it out from chv_load_luts() if we wanted
   1053 	 * the ability to preload the CGM LUTs/CSC without tearing.
   1054 	 */
   1055 	if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
   1056 		return false;
   1057 
   1058 	return !old_crtc_state->hw.gamma_lut;
   1059 }
   1060 
   1061 static bool glk_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
   1062 {
   1063 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
   1064 	struct intel_atomic_state *state =
   1065 		to_intel_atomic_state(new_crtc_state->uapi.state);
   1066 	const struct intel_crtc_state *old_crtc_state =
   1067 		intel_atomic_get_old_crtc_state(state, crtc);
   1068 
   1069 	/*
   1070 	 * The hardware degamma is active whenever the pipe
   1071 	 * CSC is active. Thus even if the old state has no
   1072 	 * software degamma we need to avoid clobbering the
   1073 	 * linear hardware degamma mid scanout.
   1074 	 */
   1075 	return !old_crtc_state->csc_enable &&
   1076 		!old_crtc_state->hw.gamma_lut;
   1077 }
   1078 
   1079 int intel_color_check(struct intel_crtc_state *crtc_state)
   1080 {
   1081 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
   1082 
   1083 	return dev_priv->display.color_check(crtc_state);
   1084 }
   1085 
   1086 void intel_color_get_config(struct intel_crtc_state *crtc_state)
   1087 {
   1088 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
   1089 
   1090 	if (dev_priv->display.read_luts)
   1091 		dev_priv->display.read_luts(crtc_state);
   1092 }
   1093 
   1094 static bool need_plane_update(struct intel_plane *plane,
   1095 			      const struct intel_crtc_state *crtc_state)
   1096 {
   1097 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1098 
   1099 	/*
   1100 	 * On pre-SKL the pipe gamma enable and pipe csc enable for
   1101 	 * the pipe bottom color are configured via the primary plane.
   1102 	 * We have to reconfigure that even if the plane is inactive.
   1103 	 */
   1104 	return crtc_state->active_planes & BIT(plane->id) ||
   1105 		(INTEL_GEN(dev_priv) < 9 &&
   1106 		 plane->id == PLANE_PRIMARY);
   1107 }
   1108 
   1109 static int
   1110 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
   1111 {
   1112 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
   1113 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
   1114 	struct intel_atomic_state *state =
   1115 		to_intel_atomic_state(new_crtc_state->uapi.state);
   1116 	const struct intel_crtc_state *old_crtc_state =
   1117 		intel_atomic_get_old_crtc_state(state, crtc);
   1118 	struct intel_plane *plane;
   1119 
   1120 	if (!new_crtc_state->hw.active ||
   1121 	    drm_atomic_crtc_needs_modeset(&new_crtc_state->uapi))
   1122 		return 0;
   1123 
   1124 	if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
   1125 	    new_crtc_state->csc_enable == old_crtc_state->csc_enable)
   1126 		return 0;
   1127 
   1128 	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
   1129 		struct intel_plane_state *plane_state;
   1130 
   1131 		if (!need_plane_update(plane, new_crtc_state))
   1132 			continue;
   1133 
   1134 		plane_state = intel_atomic_get_plane_state(state, plane);
   1135 		if (IS_ERR(plane_state))
   1136 			return PTR_ERR(plane_state);
   1137 
   1138 		new_crtc_state->update_planes |= BIT(plane->id);
   1139 	}
   1140 
   1141 	return 0;
   1142 }
   1143 
   1144 static int check_lut_size(const struct drm_property_blob *lut, int expected)
   1145 {
   1146 	int len;
   1147 
   1148 	if (!lut)
   1149 		return 0;
   1150 
   1151 	len = drm_color_lut_size(lut);
   1152 	if (len != expected) {
   1153 		DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
   1154 			      len, expected);
   1155 		return -EINVAL;
   1156 	}
   1157 
   1158 	return 0;
   1159 }
   1160 
   1161 static int check_luts(const struct intel_crtc_state *crtc_state)
   1162 {
   1163 	struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
   1164 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
   1165 	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
   1166 	int gamma_length, degamma_length;
   1167 	u32 gamma_tests, degamma_tests;
   1168 
   1169 	/* Always allow legacy gamma LUT with no further checking. */
   1170 	if (crtc_state_is_legacy_gamma(crtc_state))
   1171 		return 0;
   1172 
   1173 	/* C8 relies on its palette being stored in the legacy LUT */
   1174 	if (crtc_state->c8_planes) {
   1175 		DRM_DEBUG_KMS("C8 pixelformat requires the legacy LUT\n");
   1176 		return -EINVAL;
   1177 	}
   1178 
   1179 	degamma_length = INTEL_INFO(dev_priv)->color.degamma_lut_size;
   1180 	gamma_length = INTEL_INFO(dev_priv)->color.gamma_lut_size;
   1181 	degamma_tests = INTEL_INFO(dev_priv)->color.degamma_lut_tests;
   1182 	gamma_tests = INTEL_INFO(dev_priv)->color.gamma_lut_tests;
   1183 
   1184 	if (check_lut_size(degamma_lut, degamma_length) ||
   1185 	    check_lut_size(gamma_lut, gamma_length))
   1186 		return -EINVAL;
   1187 
   1188 	if (drm_color_lut_check(degamma_lut, degamma_tests) ||
   1189 	    drm_color_lut_check(gamma_lut, gamma_tests))
   1190 		return -EINVAL;
   1191 
   1192 	return 0;
   1193 }
   1194 
   1195 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
   1196 {
   1197 	if (!crtc_state->gamma_enable ||
   1198 	    crtc_state_is_legacy_gamma(crtc_state))
   1199 		return GAMMA_MODE_MODE_8BIT;
   1200 	else
   1201 		return GAMMA_MODE_MODE_10BIT; /* i965+ only */
   1202 }
   1203 
   1204 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
   1205 {
   1206 	int ret;
   1207 
   1208 	ret = check_luts(crtc_state);
   1209 	if (ret)
   1210 		return ret;
   1211 
   1212 	crtc_state->gamma_enable =
   1213 		crtc_state->hw.gamma_lut &&
   1214 		!crtc_state->c8_planes;
   1215 
   1216 	crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
   1217 
   1218 	ret = intel_color_add_affected_planes(crtc_state);
   1219 	if (ret)
   1220 		return ret;
   1221 
   1222 	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
   1223 
   1224 	return 0;
   1225 }
   1226 
   1227 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
   1228 {
   1229 	u32 cgm_mode = 0;
   1230 
   1231 	if (crtc_state_is_legacy_gamma(crtc_state))
   1232 		return 0;
   1233 
   1234 	if (crtc_state->hw.degamma_lut)
   1235 		cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
   1236 	if (crtc_state->hw.ctm)
   1237 		cgm_mode |= CGM_PIPE_MODE_CSC;
   1238 	if (crtc_state->hw.gamma_lut)
   1239 		cgm_mode |= CGM_PIPE_MODE_GAMMA;
   1240 
   1241 	return cgm_mode;
   1242 }
   1243 
   1244 /*
   1245  * CHV color pipeline:
   1246  * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
   1247  * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
   1248  *
   1249  * We always bypass the WGC csc and use the CGM csc
   1250  * instead since it has degamma and better precision.
   1251  */
   1252 static int chv_color_check(struct intel_crtc_state *crtc_state)
   1253 {
   1254 	int ret;
   1255 
   1256 	ret = check_luts(crtc_state);
   1257 	if (ret)
   1258 		return ret;
   1259 
   1260 	/*
   1261 	 * Pipe gamma will be used only for the legacy LUT.
   1262 	 * Otherwise we bypass it and use the CGM gamma instead.
   1263 	 */
   1264 	crtc_state->gamma_enable =
   1265 		crtc_state_is_legacy_gamma(crtc_state) &&
   1266 		!crtc_state->c8_planes;
   1267 
   1268 	crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
   1269 
   1270 	crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
   1271 
   1272 	ret = intel_color_add_affected_planes(crtc_state);
   1273 	if (ret)
   1274 		return ret;
   1275 
   1276 	crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
   1277 
   1278 	return 0;
   1279 }
   1280 
   1281 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
   1282 {
   1283 	if (!crtc_state->gamma_enable ||
   1284 	    crtc_state_is_legacy_gamma(crtc_state))
   1285 		return GAMMA_MODE_MODE_8BIT;
   1286 	else
   1287 		return GAMMA_MODE_MODE_10BIT;
   1288 }
   1289 
   1290 static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
   1291 {
   1292 	/*
   1293 	 * CSC comes after the LUT in RGB->YCbCr mode.
   1294 	 * RGB->YCbCr needs the limited range offsets added to
   1295 	 * the output. RGB limited range output is handled by
   1296 	 * the hw automagically elsewhere.
   1297 	 */
   1298 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
   1299 		return CSC_BLACK_SCREEN_OFFSET;
   1300 
   1301 	return CSC_MODE_YUV_TO_RGB |
   1302 		CSC_POSITION_BEFORE_GAMMA;
   1303 }
   1304 
   1305 static int ilk_color_check(struct intel_crtc_state *crtc_state)
   1306 {
   1307 	int ret;
   1308 
   1309 	ret = check_luts(crtc_state);
   1310 	if (ret)
   1311 		return ret;
   1312 
   1313 	crtc_state->gamma_enable =
   1314 		crtc_state->hw.gamma_lut &&
   1315 		!crtc_state->c8_planes;
   1316 
   1317 	/*
   1318 	 * We don't expose the ctm on ilk/snb currently, also RGB
   1319 	 * limited range output is handled by the hw automagically.
   1320 	 */
   1321 	crtc_state->csc_enable =
   1322 		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB;
   1323 
   1324 	crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
   1325 
   1326 	crtc_state->csc_mode = ilk_csc_mode(crtc_state);
   1327 
   1328 	ret = intel_color_add_affected_planes(crtc_state);
   1329 	if (ret)
   1330 		return ret;
   1331 
   1332 	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
   1333 
   1334 	return 0;
   1335 }
   1336 
   1337 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
   1338 {
   1339 	if (!crtc_state->gamma_enable ||
   1340 	    crtc_state_is_legacy_gamma(crtc_state))
   1341 		return GAMMA_MODE_MODE_8BIT;
   1342 	else if (crtc_state->hw.gamma_lut &&
   1343 		 crtc_state->hw.degamma_lut)
   1344 		return GAMMA_MODE_MODE_SPLIT;
   1345 	else
   1346 		return GAMMA_MODE_MODE_10BIT;
   1347 }
   1348 
   1349 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
   1350 {
   1351 	bool limited_color_range = ilk_csc_limited_range(crtc_state);
   1352 
   1353 	/*
   1354 	 * CSC comes after the LUT in degamma, RGB->YCbCr,
   1355 	 * and RGB full->limited range mode.
   1356 	 */
   1357 	if (crtc_state->hw.degamma_lut ||
   1358 	    crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
   1359 	    limited_color_range)
   1360 		return 0;
   1361 
   1362 	return CSC_POSITION_BEFORE_GAMMA;
   1363 }
   1364 
   1365 static int ivb_color_check(struct intel_crtc_state *crtc_state)
   1366 {
   1367 	bool limited_color_range = ilk_csc_limited_range(crtc_state);
   1368 	int ret;
   1369 
   1370 	ret = check_luts(crtc_state);
   1371 	if (ret)
   1372 		return ret;
   1373 
   1374 	crtc_state->gamma_enable =
   1375 		(crtc_state->hw.gamma_lut ||
   1376 		 crtc_state->hw.degamma_lut) &&
   1377 		!crtc_state->c8_planes;
   1378 
   1379 	crtc_state->csc_enable =
   1380 		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
   1381 		crtc_state->hw.ctm || limited_color_range;
   1382 
   1383 	crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
   1384 
   1385 	crtc_state->csc_mode = ivb_csc_mode(crtc_state);
   1386 
   1387 	ret = intel_color_add_affected_planes(crtc_state);
   1388 	if (ret)
   1389 		return ret;
   1390 
   1391 	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
   1392 
   1393 	return 0;
   1394 }
   1395 
   1396 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
   1397 {
   1398 	if (!crtc_state->gamma_enable ||
   1399 	    crtc_state_is_legacy_gamma(crtc_state))
   1400 		return GAMMA_MODE_MODE_8BIT;
   1401 	else
   1402 		return GAMMA_MODE_MODE_10BIT;
   1403 }
   1404 
   1405 static int glk_color_check(struct intel_crtc_state *crtc_state)
   1406 {
   1407 	int ret;
   1408 
   1409 	ret = check_luts(crtc_state);
   1410 	if (ret)
   1411 		return ret;
   1412 
   1413 	crtc_state->gamma_enable =
   1414 		crtc_state->hw.gamma_lut &&
   1415 		!crtc_state->c8_planes;
   1416 
   1417 	/* On GLK+ degamma LUT is controlled by csc_enable */
   1418 	crtc_state->csc_enable =
   1419 		crtc_state->hw.degamma_lut ||
   1420 		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
   1421 		crtc_state->hw.ctm || crtc_state->limited_color_range;
   1422 
   1423 	crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
   1424 
   1425 	crtc_state->csc_mode = 0;
   1426 
   1427 	ret = intel_color_add_affected_planes(crtc_state);
   1428 	if (ret)
   1429 		return ret;
   1430 
   1431 	crtc_state->preload_luts = glk_can_preload_luts(crtc_state);
   1432 
   1433 	return 0;
   1434 }
   1435 
   1436 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
   1437 {
   1438 	u32 gamma_mode = 0;
   1439 
   1440 	if (crtc_state->hw.degamma_lut)
   1441 		gamma_mode |= PRE_CSC_GAMMA_ENABLE;
   1442 
   1443 	if (crtc_state->hw.gamma_lut &&
   1444 	    !crtc_state->c8_planes)
   1445 		gamma_mode |= POST_CSC_GAMMA_ENABLE;
   1446 
   1447 	if (!crtc_state->hw.gamma_lut ||
   1448 	    crtc_state_is_legacy_gamma(crtc_state))
   1449 		gamma_mode |= GAMMA_MODE_MODE_8BIT;
   1450 	else
   1451 		gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEGMENTED;
   1452 
   1453 	return gamma_mode;
   1454 }
   1455 
   1456 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
   1457 {
   1458 	u32 csc_mode = 0;
   1459 
   1460 	if (crtc_state->hw.ctm)
   1461 		csc_mode |= ICL_CSC_ENABLE;
   1462 
   1463 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
   1464 	    crtc_state->limited_color_range)
   1465 		csc_mode |= ICL_OUTPUT_CSC_ENABLE;
   1466 
   1467 	return csc_mode;
   1468 }
   1469 
   1470 static int icl_color_check(struct intel_crtc_state *crtc_state)
   1471 {
   1472 	int ret;
   1473 
   1474 	ret = check_luts(crtc_state);
   1475 	if (ret)
   1476 		return ret;
   1477 
   1478 	crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
   1479 
   1480 	crtc_state->csc_mode = icl_csc_mode(crtc_state);
   1481 
   1482 	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
   1483 
   1484 	return 0;
   1485 }
   1486 
   1487 static int i9xx_gamma_precision(const struct intel_crtc_state *crtc_state)
   1488 {
   1489 	if (!crtc_state->gamma_enable)
   1490 		return 0;
   1491 
   1492 	switch (crtc_state->gamma_mode) {
   1493 	case GAMMA_MODE_MODE_8BIT:
   1494 		return 8;
   1495 	case GAMMA_MODE_MODE_10BIT:
   1496 		return 16;
   1497 	default:
   1498 		MISSING_CASE(crtc_state->gamma_mode);
   1499 		return 0;
   1500 	}
   1501 }
   1502 
   1503 static int ilk_gamma_precision(const struct intel_crtc_state *crtc_state)
   1504 {
   1505 	if (!crtc_state->gamma_enable)
   1506 		return 0;
   1507 
   1508 	if ((crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0)
   1509 		return 0;
   1510 
   1511 	switch (crtc_state->gamma_mode) {
   1512 	case GAMMA_MODE_MODE_8BIT:
   1513 		return 8;
   1514 	case GAMMA_MODE_MODE_10BIT:
   1515 		return 10;
   1516 	default:
   1517 		MISSING_CASE(crtc_state->gamma_mode);
   1518 		return 0;
   1519 	}
   1520 }
   1521 
   1522 static int chv_gamma_precision(const struct intel_crtc_state *crtc_state)
   1523 {
   1524 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
   1525 		return 10;
   1526 	else
   1527 		return i9xx_gamma_precision(crtc_state);
   1528 }
   1529 
   1530 static int glk_gamma_precision(const struct intel_crtc_state *crtc_state)
   1531 {
   1532 	if (!crtc_state->gamma_enable)
   1533 		return 0;
   1534 
   1535 	switch (crtc_state->gamma_mode) {
   1536 	case GAMMA_MODE_MODE_8BIT:
   1537 		return 8;
   1538 	case GAMMA_MODE_MODE_10BIT:
   1539 		return 10;
   1540 	default:
   1541 		MISSING_CASE(crtc_state->gamma_mode);
   1542 		return 0;
   1543 	}
   1544 }
   1545 
   1546 int intel_color_get_gamma_bit_precision(const struct intel_crtc_state *crtc_state)
   1547 {
   1548 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
   1549 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
   1550 
   1551 	if (HAS_GMCH(dev_priv)) {
   1552 		if (IS_CHERRYVIEW(dev_priv))
   1553 			return chv_gamma_precision(crtc_state);
   1554 		else
   1555 			return i9xx_gamma_precision(crtc_state);
   1556 	} else {
   1557 		if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
   1558 			return glk_gamma_precision(crtc_state);
   1559 		else if (IS_IRONLAKE(dev_priv))
   1560 			return ilk_gamma_precision(crtc_state);
   1561 	}
   1562 
   1563 	return 0;
   1564 }
   1565 
   1566 static bool err_check(struct drm_color_lut *lut1,
   1567 		      struct drm_color_lut *lut2, u32 err)
   1568 {
   1569 	return ((abs((long)lut2->red - lut1->red)) <= err) &&
   1570 		((abs((long)lut2->blue - lut1->blue)) <= err) &&
   1571 		((abs((long)lut2->green - lut1->green)) <= err);
   1572 }
   1573 
   1574 static bool intel_color_lut_entry_equal(struct drm_color_lut *lut1,
   1575 					struct drm_color_lut *lut2,
   1576 					int lut_size, u32 err)
   1577 {
   1578 	int i;
   1579 
   1580 	for (i = 0; i < lut_size; i++) {
   1581 		if (!err_check(&lut1[i], &lut2[i], err))
   1582 			return false;
   1583 	}
   1584 
   1585 	return true;
   1586 }
   1587 
   1588 bool intel_color_lut_equal(struct drm_property_blob *blob1,
   1589 			   struct drm_property_blob *blob2,
   1590 			   u32 gamma_mode, u32 bit_precision)
   1591 {
   1592 	struct drm_color_lut *lut1, *lut2;
   1593 	int lut_size1, lut_size2;
   1594 	u32 err;
   1595 
   1596 	if (!blob1 != !blob2)
   1597 		return false;
   1598 
   1599 	if (!blob1)
   1600 		return true;
   1601 
   1602 	lut_size1 = drm_color_lut_size(blob1);
   1603 	lut_size2 = drm_color_lut_size(blob2);
   1604 
   1605 	/* check sw and hw lut size */
   1606 	switch (gamma_mode) {
   1607 	case GAMMA_MODE_MODE_8BIT:
   1608 	case GAMMA_MODE_MODE_10BIT:
   1609 		if (lut_size1 != lut_size2)
   1610 			return false;
   1611 		break;
   1612 	default:
   1613 		MISSING_CASE(gamma_mode);
   1614 			return false;
   1615 	}
   1616 
   1617 	lut1 = blob1->data;
   1618 	lut2 = blob2->data;
   1619 
   1620 	err = 0xffff >> bit_precision;
   1621 
   1622 	/* check sw and hw lut entry to be equal */
   1623 	switch (gamma_mode) {
   1624 	case GAMMA_MODE_MODE_8BIT:
   1625 	case GAMMA_MODE_MODE_10BIT:
   1626 		if (!intel_color_lut_entry_equal(lut1, lut2,
   1627 						 lut_size2, err))
   1628 			return false;
   1629 		break;
   1630 	default:
   1631 		MISSING_CASE(gamma_mode);
   1632 			return false;
   1633 	}
   1634 
   1635 	return true;
   1636 }
   1637 
   1638 /* convert hw value with given bit_precision to lut property val */
   1639 static u32 intel_color_lut_pack(u32 val, u32 bit_precision)
   1640 {
   1641 	u32 max = 0xffff >> (16 - bit_precision);
   1642 
   1643 	val = clamp_val(val, 0, max);
   1644 
   1645 	if (bit_precision < 16)
   1646 		val <<= 16 - bit_precision;
   1647 
   1648 	return val;
   1649 }
   1650 
   1651 static struct drm_property_blob *
   1652 i9xx_read_lut_8(const struct intel_crtc_state *crtc_state)
   1653 {
   1654 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
   1655 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
   1656 	enum pipe pipe = crtc->pipe;
   1657 	struct drm_property_blob *blob;
   1658 	struct drm_color_lut *blob_data;
   1659 	u32 i, val;
   1660 
   1661 	blob = drm_property_create_blob(&dev_priv->drm,
   1662 					sizeof(struct drm_color_lut) * LEGACY_LUT_LENGTH,
   1663 					NULL);
   1664 	if (IS_ERR(blob))
   1665 		return NULL;
   1666 
   1667 	blob_data = blob->data;
   1668 
   1669 	for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
   1670 		if (HAS_GMCH(dev_priv))
   1671 			val = I915_READ(PALETTE(pipe, i));
   1672 		else
   1673 			val = I915_READ(LGC_PALETTE(pipe, i));
   1674 
   1675 		blob_data[i].red = intel_color_lut_pack(REG_FIELD_GET(
   1676 							LGC_PALETTE_RED_MASK, val), 8);
   1677 		blob_data[i].green = intel_color_lut_pack(REG_FIELD_GET(
   1678 							  LGC_PALETTE_GREEN_MASK, val), 8);
   1679 		blob_data[i].blue = intel_color_lut_pack(REG_FIELD_GET(
   1680 							 LGC_PALETTE_BLUE_MASK, val), 8);
   1681 	}
   1682 
   1683 	return blob;
   1684 }
   1685 
   1686 static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
   1687 {
   1688 	if (!crtc_state->gamma_enable)
   1689 		return;
   1690 
   1691 	crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc_state);
   1692 }
   1693 
   1694 static struct drm_property_blob *
   1695 i965_read_lut_10p6(const struct intel_crtc_state *crtc_state)
   1696 {
   1697 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
   1698 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
   1699 	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
   1700 	enum pipe pipe = crtc->pipe;
   1701 	struct drm_property_blob *blob;
   1702 	struct drm_color_lut *blob_data;
   1703 	u32 i, val1, val2;
   1704 
   1705 	blob = drm_property_create_blob(&dev_priv->drm,
   1706 					sizeof(struct drm_color_lut) * lut_size,
   1707 					NULL);
   1708 	if (IS_ERR(blob))
   1709 		return NULL;
   1710 
   1711 	blob_data = blob->data;
   1712 
   1713 	for (i = 0; i < lut_size - 1; i++) {
   1714 		val1 = I915_READ(PALETTE(pipe, 2 * i + 0));
   1715 		val2 = I915_READ(PALETTE(pipe, 2 * i + 1));
   1716 
   1717 		blob_data[i].red = REG_FIELD_GET(PALETTE_RED_MASK, val2) << 8 |
   1718 						 REG_FIELD_GET(PALETTE_RED_MASK, val1);
   1719 		blob_data[i].green = REG_FIELD_GET(PALETTE_GREEN_MASK, val2) << 8 |
   1720 						   REG_FIELD_GET(PALETTE_GREEN_MASK, val1);
   1721 		blob_data[i].blue = REG_FIELD_GET(PALETTE_BLUE_MASK, val2) << 8 |
   1722 						  REG_FIELD_GET(PALETTE_BLUE_MASK, val1);
   1723 	}
   1724 
   1725 	blob_data[i].red = REG_FIELD_GET(PIPEGCMAX_RGB_MASK,
   1726 					 I915_READ(PIPEGCMAX(pipe, 0)));
   1727 	blob_data[i].green = REG_FIELD_GET(PIPEGCMAX_RGB_MASK,
   1728 					   I915_READ(PIPEGCMAX(pipe, 1)));
   1729 	blob_data[i].blue = REG_FIELD_GET(PIPEGCMAX_RGB_MASK,
   1730 					  I915_READ(PIPEGCMAX(pipe, 2)));
   1731 
   1732 	return blob;
   1733 }
   1734 
   1735 static void i965_read_luts(struct intel_crtc_state *crtc_state)
   1736 {
   1737 	if (!crtc_state->gamma_enable)
   1738 		return;
   1739 
   1740 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
   1741 		crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc_state);
   1742 	else
   1743 		crtc_state->hw.gamma_lut = i965_read_lut_10p6(crtc_state);
   1744 }
   1745 
   1746 static struct drm_property_blob *
   1747 chv_read_cgm_lut(const struct intel_crtc_state *crtc_state)
   1748 {
   1749 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
   1750 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
   1751 	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
   1752 	enum pipe pipe = crtc->pipe;
   1753 	struct drm_property_blob *blob;
   1754 	struct drm_color_lut *blob_data;
   1755 	u32 i, val;
   1756 
   1757 	blob = drm_property_create_blob(&dev_priv->drm,
   1758 					sizeof(struct drm_color_lut) * lut_size,
   1759 					NULL);
   1760 	if (IS_ERR(blob))
   1761 		return NULL;
   1762 
   1763 	blob_data = blob->data;
   1764 
   1765 	for (i = 0; i < lut_size; i++) {
   1766 		val = I915_READ(CGM_PIPE_GAMMA(pipe, i, 0));
   1767 		blob_data[i].green = intel_color_lut_pack(REG_FIELD_GET(
   1768 							  CGM_PIPE_GAMMA_GREEN_MASK, val), 10);
   1769 		blob_data[i].blue = intel_color_lut_pack(REG_FIELD_GET(
   1770 							 CGM_PIPE_GAMMA_BLUE_MASK, val), 10);
   1771 
   1772 		val = I915_READ(CGM_PIPE_GAMMA(pipe, i, 1));
   1773 		blob_data[i].red = intel_color_lut_pack(REG_FIELD_GET(
   1774 							CGM_PIPE_GAMMA_RED_MASK, val), 10);
   1775 	}
   1776 
   1777 	return blob;
   1778 }
   1779 
   1780 static void chv_read_luts(struct intel_crtc_state *crtc_state)
   1781 {
   1782 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
   1783 		crtc_state->hw.gamma_lut = chv_read_cgm_lut(crtc_state);
   1784 	else
   1785 		i965_read_luts(crtc_state);
   1786 }
   1787 
   1788 static struct drm_property_blob *
   1789 ilk_read_lut_10(const struct intel_crtc_state *crtc_state)
   1790 {
   1791 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
   1792 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
   1793 	u32 lut_size = INTEL_INFO(dev_priv)->color.gamma_lut_size;
   1794 	enum pipe pipe = crtc->pipe;
   1795 	struct drm_property_blob *blob;
   1796 	struct drm_color_lut *blob_data;
   1797 	u32 i, val;
   1798 
   1799 	blob = drm_property_create_blob(&dev_priv->drm,
   1800 					sizeof(struct drm_color_lut) * lut_size,
   1801 					NULL);
   1802 	if (IS_ERR(blob))
   1803 		return NULL;
   1804 
   1805 	blob_data = blob->data;
   1806 
   1807 	for (i = 0; i < lut_size; i++) {
   1808 		val = I915_READ(PREC_PALETTE(pipe, i));
   1809 
   1810 		blob_data[i].red = intel_color_lut_pack(REG_FIELD_GET(
   1811 							PREC_PALETTE_RED_MASK, val), 10);
   1812 		blob_data[i].green = intel_color_lut_pack(REG_FIELD_GET(
   1813 							  PREC_PALETTE_GREEN_MASK, val), 10);
   1814 		blob_data[i].blue = intel_color_lut_pack(REG_FIELD_GET(
   1815 							 PREC_PALETTE_BLUE_MASK, val), 10);
   1816 	}
   1817 
   1818 	return blob;
   1819 }
   1820 
   1821 static void ilk_read_luts(struct intel_crtc_state *crtc_state)
   1822 {
   1823 	if (!crtc_state->gamma_enable)
   1824 		return;
   1825 
   1826 	if ((crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0)
   1827 		return;
   1828 
   1829 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
   1830 		crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc_state);
   1831 	else
   1832 		crtc_state->hw.gamma_lut = ilk_read_lut_10(crtc_state);
   1833 }
   1834 
   1835 static struct drm_property_blob *
   1836 glk_read_lut_10(const struct intel_crtc_state *crtc_state, u32 prec_index)
   1837 {
   1838 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
   1839 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
   1840 	int hw_lut_size = ivb_lut_10_size(prec_index);
   1841 	enum pipe pipe = crtc->pipe;
   1842 	struct drm_property_blob *blob;
   1843 	struct drm_color_lut *blob_data;
   1844 	u32 i, val;
   1845 
   1846 	blob = drm_property_create_blob(&dev_priv->drm,
   1847 					sizeof(struct drm_color_lut) * hw_lut_size,
   1848 					NULL);
   1849 	if (IS_ERR(blob))
   1850 		return NULL;
   1851 
   1852 	blob_data = blob->data;
   1853 
   1854 	I915_WRITE(PREC_PAL_INDEX(pipe), prec_index |
   1855 		   PAL_PREC_AUTO_INCREMENT);
   1856 
   1857 	for (i = 0; i < hw_lut_size; i++) {
   1858 		val = I915_READ(PREC_PAL_DATA(pipe));
   1859 
   1860 		blob_data[i].red = intel_color_lut_pack(REG_FIELD_GET(
   1861 							PREC_PAL_DATA_RED_MASK, val), 10);
   1862 		blob_data[i].green = intel_color_lut_pack(REG_FIELD_GET(
   1863 							PREC_PAL_DATA_GREEN_MASK, val), 10);
   1864 		blob_data[i].blue = intel_color_lut_pack(REG_FIELD_GET(
   1865 							PREC_PAL_DATA_BLUE_MASK, val), 10);
   1866 	}
   1867 
   1868 	I915_WRITE(PREC_PAL_INDEX(pipe), 0);
   1869 
   1870 	return blob;
   1871 }
   1872 
   1873 static void glk_read_luts(struct intel_crtc_state *crtc_state)
   1874 {
   1875 	if (!crtc_state->gamma_enable)
   1876 		return;
   1877 
   1878 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_8BIT)
   1879 		crtc_state->hw.gamma_lut = i9xx_read_lut_8(crtc_state);
   1880 	else
   1881 		crtc_state->hw.gamma_lut = glk_read_lut_10(crtc_state, PAL_PREC_INDEX_VALUE(0));
   1882 }
   1883 
   1884 void intel_color_init(struct intel_crtc *crtc)
   1885 {
   1886 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
   1887 	bool has_ctm = INTEL_INFO(dev_priv)->color.degamma_lut_size != 0;
   1888 
   1889 	drm_mode_crtc_set_gamma_size(&crtc->base, 256);
   1890 
   1891 	if (HAS_GMCH(dev_priv)) {
   1892 		if (IS_CHERRYVIEW(dev_priv)) {
   1893 			dev_priv->display.color_check = chv_color_check;
   1894 			dev_priv->display.color_commit = i9xx_color_commit;
   1895 			dev_priv->display.load_luts = chv_load_luts;
   1896 			dev_priv->display.read_luts = chv_read_luts;
   1897 		} else if (INTEL_GEN(dev_priv) >= 4) {
   1898 			dev_priv->display.color_check = i9xx_color_check;
   1899 			dev_priv->display.color_commit = i9xx_color_commit;
   1900 			dev_priv->display.load_luts = i965_load_luts;
   1901 			dev_priv->display.read_luts = i965_read_luts;
   1902 		} else {
   1903 			dev_priv->display.color_check = i9xx_color_check;
   1904 			dev_priv->display.color_commit = i9xx_color_commit;
   1905 			dev_priv->display.load_luts = i9xx_load_luts;
   1906 			dev_priv->display.read_luts = i9xx_read_luts;
   1907 		}
   1908 	} else {
   1909 		if (INTEL_GEN(dev_priv) >= 11)
   1910 			dev_priv->display.color_check = icl_color_check;
   1911 		else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
   1912 			dev_priv->display.color_check = glk_color_check;
   1913 		else if (INTEL_GEN(dev_priv) >= 7)
   1914 			dev_priv->display.color_check = ivb_color_check;
   1915 		else
   1916 			dev_priv->display.color_check = ilk_color_check;
   1917 
   1918 		if (INTEL_GEN(dev_priv) >= 9)
   1919 			dev_priv->display.color_commit = skl_color_commit;
   1920 		else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
   1921 			dev_priv->display.color_commit = hsw_color_commit;
   1922 		else
   1923 			dev_priv->display.color_commit = ilk_color_commit;
   1924 
   1925 		if (INTEL_GEN(dev_priv) >= 11) {
   1926 			dev_priv->display.load_luts = icl_load_luts;
   1927 		} else if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv)) {
   1928 			dev_priv->display.load_luts = glk_load_luts;
   1929 			dev_priv->display.read_luts = glk_read_luts;
   1930 		} else if (INTEL_GEN(dev_priv) >= 8) {
   1931 			dev_priv->display.load_luts = bdw_load_luts;
   1932 		} else if (INTEL_GEN(dev_priv) >= 7) {
   1933 			dev_priv->display.load_luts = ivb_load_luts;
   1934 		} else {
   1935 			dev_priv->display.load_luts = ilk_load_luts;
   1936 			dev_priv->display.read_luts = ilk_read_luts;
   1937 		}
   1938 	}
   1939 
   1940 	drm_crtc_enable_color_mgmt(&crtc->base,
   1941 				   INTEL_INFO(dev_priv)->color.degamma_lut_size,
   1942 				   has_ctm,
   1943 				   INTEL_INFO(dev_priv)->color.gamma_lut_size);
   1944 }
   1945