xref: /linux/drivers/gpu/drm/i915/display/intel_color.c (revision 8dd765a5d769c521d73931850d1c8708fbc490cb)
1 /*
2  * Copyright © 2016 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  */
24 
25 #include "i915_reg.h"
26 #include "intel_color.h"
27 #include "intel_de.h"
28 #include "intel_display_types.h"
29 #include "intel_dsb.h"
30 
31 struct intel_color_funcs {
32 	int (*color_check)(struct intel_crtc_state *crtc_state);
33 	/*
34 	 * Program non-arming double buffered color management registers
35 	 * before vblank evasion. The registers should then latch after
36 	 * the arming register is written (by color_commit_arm()) during
37 	 * the next vblank start, alongside any other double buffered
38 	 * registers involved with the same commit. This hook is optional.
39 	 */
40 	void (*color_commit_noarm)(const struct intel_crtc_state *crtc_state);
41 	/*
42 	 * Program arming double buffered color management registers
43 	 * during vblank evasion. The registers (and whatever other registers
44 	 * they arm that were written by color_commit_noarm) should then latch
45 	 * during the next vblank start, alongside any other double buffered
46 	 * registers involved with the same commit.
47 	 */
48 	void (*color_commit_arm)(const struct intel_crtc_state *crtc_state);
49 	/*
50 	 * Perform any extra tasks needed after all the
51 	 * double buffered registers have been latched.
52 	 */
53 	void (*color_post_update)(const struct intel_crtc_state *crtc_state);
54 	/*
55 	 * Load LUTs (and other single buffered color management
56 	 * registers). Will (hopefully) be called during the vblank
57 	 * following the latching of any double buffered registers
58 	 * involved with the same commit.
59 	 */
60 	void (*load_luts)(const struct intel_crtc_state *crtc_state);
61 	/*
62 	 * Read out the LUTs from the hardware into the software state.
63 	 * Used by eg. the hardware state checker.
64 	 */
65 	void (*read_luts)(struct intel_crtc_state *crtc_state);
66 	/*
67 	 * Compare the LUTs
68 	 */
69 	bool (*lut_equal)(const struct intel_crtc_state *crtc_state,
70 			  const struct drm_property_blob *blob1,
71 			  const struct drm_property_blob *blob2,
72 			  bool is_pre_csc_lut);
73 	/*
74 	 * Read out the CSCs (if any) from the hardware into the
75 	 * software state. Used by eg. the hardware state checker.
76 	 */
77 	void (*read_csc)(struct intel_crtc_state *crtc_state);
78 };
79 
80 #define CTM_COEFF_SIGN	(1ULL << 63)
81 
82 #define CTM_COEFF_1_0	(1ULL << 32)
83 #define CTM_COEFF_2_0	(CTM_COEFF_1_0 << 1)
84 #define CTM_COEFF_4_0	(CTM_COEFF_2_0 << 1)
85 #define CTM_COEFF_8_0	(CTM_COEFF_4_0 << 1)
86 #define CTM_COEFF_0_5	(CTM_COEFF_1_0 >> 1)
87 #define CTM_COEFF_0_25	(CTM_COEFF_0_5 >> 1)
88 #define CTM_COEFF_0_125	(CTM_COEFF_0_25 >> 1)
89 
90 #define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
91 
92 #define CTM_COEFF_NEGATIVE(coeff)	(((coeff) & CTM_COEFF_SIGN) != 0)
93 #define CTM_COEFF_ABS(coeff)		((coeff) & (CTM_COEFF_SIGN - 1))
94 
95 #define LEGACY_LUT_LENGTH		256
96 
97 /*
98  * ILK+ csc matrix:
99  *
100  * |R/Cr|   | c0 c1 c2 |   ( |R/Cr|   |preoff0| )   |postoff0|
101  * |G/Y | = | c3 c4 c5 | x ( |G/Y | + |preoff1| ) + |postoff1|
102  * |B/Cb|   | c6 c7 c8 |   ( |B/Cb|   |preoff2| )   |postoff2|
103  *
104  * ILK/SNB don't have explicit post offsets, and instead
105  * CSC_MODE_YUV_TO_RGB and CSC_BLACK_SCREEN_OFFSET are used:
106  *  CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=0 -> 1/2, 0, 1/2
107  *  CSC_MODE_YUV_TO_RGB=0 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/2, 1/16, 1/2
108  *  CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=0 -> 0, 0, 0
109  *  CSC_MODE_YUV_TO_RGB=1 + CSC_BLACK_SCREEN_OFFSET=1 -> 1/16, 1/16, 1/16
110  */
111 
112 /*
113  * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
114  * format). This macro takes the coefficient we want transformed and the
115  * number of fractional bits.
116  *
117  * We only have a 9 bits precision window which slides depending on the value
118  * of the CTM coefficient and we write the value from bit 3. We also round the
119  * value.
120  */
121 #define ILK_CSC_COEFF_FP(coeff, fbits)	\
122 	(clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
123 
124 #define ILK_CSC_COEFF_1_0 0x7800
125 #define ILK_CSC_COEFF_LIMITED_RANGE ((235 - 16) << (12 - 8)) /* exponent 0 */
126 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 << (12 - 8))
127 
128 static const struct intel_csc_matrix ilk_csc_matrix_identity = {
129 	.preoff = {},
130 	.coeff = {
131 		ILK_CSC_COEFF_1_0, 0, 0,
132 		0, ILK_CSC_COEFF_1_0, 0,
133 		0, 0, ILK_CSC_COEFF_1_0,
134 	},
135 	.postoff = {},
136 };
137 
138 /* Full range RGB -> limited range RGB matrix */
139 static const struct intel_csc_matrix ilk_csc_matrix_limited_range = {
140 	.preoff = {},
141 	.coeff = {
142 		ILK_CSC_COEFF_LIMITED_RANGE, 0, 0,
143 		0, ILK_CSC_COEFF_LIMITED_RANGE, 0,
144 		0, 0, ILK_CSC_COEFF_LIMITED_RANGE,
145 	},
146 	.postoff = {
147 		ILK_CSC_POSTOFF_LIMITED_RANGE,
148 		ILK_CSC_POSTOFF_LIMITED_RANGE,
149 		ILK_CSC_POSTOFF_LIMITED_RANGE,
150 	},
151 };
152 
153 /* BT.709 full range RGB -> limited range YCbCr matrix */
154 static const struct intel_csc_matrix ilk_csc_matrix_rgb_to_ycbcr = {
155 	.preoff = {},
156 	.coeff = {
157 		0x1e08, 0x9cc0, 0xb528,
158 		0x2ba8, 0x09d8, 0x37e8,
159 		0xbce8, 0x9ad8, 0x1e08,
160 	},
161 	.postoff = {
162 		0x0800, 0x0100, 0x0800,
163 	},
164 };
165 
166 static void intel_csc_clear(struct intel_csc_matrix *csc)
167 {
168 	memset(csc, 0, sizeof(*csc));
169 }
170 
171 static bool lut_is_legacy(const struct drm_property_blob *lut)
172 {
173 	return lut && drm_color_lut_size(lut) == LEGACY_LUT_LENGTH;
174 }
175 
176 /*
177  * When using limited range, multiply the matrix given by userspace by
178  * the matrix that we would use for the limited range.
179  */
180 static u64 *ctm_mult_by_limited(u64 *result, const u64 *input)
181 {
182 	int i;
183 
184 	for (i = 0; i < 9; i++) {
185 		u64 user_coeff = input[i];
186 		u32 limited_coeff = CTM_COEFF_LIMITED_RANGE;
187 		u32 abs_coeff = clamp_val(CTM_COEFF_ABS(user_coeff), 0,
188 					  CTM_COEFF_4_0 - 1) >> 2;
189 
190 		/*
191 		 * By scaling every co-efficient with limited range (16-235)
192 		 * vs full range (0-255) the final o/p will be scaled down to
193 		 * fit in the limited range supported by the panel.
194 		 */
195 		result[i] = mul_u32_u32(limited_coeff, abs_coeff) >> 30;
196 		result[i] |= user_coeff & CTM_COEFF_SIGN;
197 	}
198 
199 	return result;
200 }
201 
202 static void ilk_update_pipe_csc(struct intel_crtc *crtc,
203 				const struct intel_csc_matrix *csc)
204 {
205 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
206 	enum pipe pipe = crtc->pipe;
207 
208 	intel_de_write_fw(i915, PIPE_CSC_PREOFF_HI(pipe), csc->preoff[0]);
209 	intel_de_write_fw(i915, PIPE_CSC_PREOFF_ME(pipe), csc->preoff[1]);
210 	intel_de_write_fw(i915, PIPE_CSC_PREOFF_LO(pipe), csc->preoff[2]);
211 
212 	intel_de_write_fw(i915, PIPE_CSC_COEFF_RY_GY(pipe),
213 			  csc->coeff[0] << 16 | csc->coeff[1]);
214 	intel_de_write_fw(i915, PIPE_CSC_COEFF_BY(pipe),
215 			  csc->coeff[2] << 16);
216 
217 	intel_de_write_fw(i915, PIPE_CSC_COEFF_RU_GU(pipe),
218 			  csc->coeff[3] << 16 | csc->coeff[4]);
219 	intel_de_write_fw(i915, PIPE_CSC_COEFF_BU(pipe),
220 			  csc->coeff[5] << 16);
221 
222 	intel_de_write_fw(i915, PIPE_CSC_COEFF_RV_GV(pipe),
223 			  csc->coeff[6] << 16 | csc->coeff[7]);
224 	intel_de_write_fw(i915, PIPE_CSC_COEFF_BV(pipe),
225 			  csc->coeff[8] << 16);
226 
227 	if (DISPLAY_VER(i915) < 7)
228 		return;
229 
230 	intel_de_write_fw(i915, PIPE_CSC_POSTOFF_HI(pipe), csc->postoff[0]);
231 	intel_de_write_fw(i915, PIPE_CSC_POSTOFF_ME(pipe), csc->postoff[1]);
232 	intel_de_write_fw(i915, PIPE_CSC_POSTOFF_LO(pipe), csc->postoff[2]);
233 }
234 
235 static void ilk_read_pipe_csc(struct intel_crtc *crtc,
236 			      struct intel_csc_matrix *csc)
237 {
238 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
239 	enum pipe pipe = crtc->pipe;
240 	u32 tmp;
241 
242 	csc->preoff[0] = intel_de_read_fw(i915, PIPE_CSC_PREOFF_HI(pipe));
243 	csc->preoff[1] = intel_de_read_fw(i915, PIPE_CSC_PREOFF_ME(pipe));
244 	csc->preoff[2] = intel_de_read_fw(i915, PIPE_CSC_PREOFF_LO(pipe));
245 
246 	tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_RY_GY(pipe));
247 	csc->coeff[0] = tmp >> 16;
248 	csc->coeff[1] = tmp & 0xffff;
249 	tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_BY(pipe));
250 	csc->coeff[2] = tmp >> 16;
251 
252 	tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_RU_GU(pipe));
253 	csc->coeff[3] = tmp >> 16;
254 	csc->coeff[4] = tmp & 0xffff;
255 	tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_BU(pipe));
256 	csc->coeff[5] = tmp >> 16;
257 
258 	tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_RV_GV(pipe));
259 	csc->coeff[6] = tmp >> 16;
260 	csc->coeff[7] = tmp & 0xffff;
261 	tmp = intel_de_read_fw(i915, PIPE_CSC_COEFF_BV(pipe));
262 	csc->coeff[8] = tmp >> 16;
263 
264 	if (DISPLAY_VER(i915) < 7)
265 		return;
266 
267 	csc->postoff[0] = intel_de_read_fw(i915, PIPE_CSC_POSTOFF_HI(pipe));
268 	csc->postoff[1] = intel_de_read_fw(i915, PIPE_CSC_POSTOFF_ME(pipe));
269 	csc->postoff[2] = intel_de_read_fw(i915, PIPE_CSC_POSTOFF_LO(pipe));
270 }
271 
272 static void ilk_read_csc(struct intel_crtc_state *crtc_state)
273 {
274 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
275 
276 	if (crtc_state->csc_enable)
277 		ilk_read_pipe_csc(crtc, &crtc_state->csc);
278 }
279 
280 static void skl_read_csc(struct intel_crtc_state *crtc_state)
281 {
282 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
283 
284 	/*
285 	 * Display WA #1184: skl,glk
286 	 * Wa_1406463849: icl
287 	 *
288 	 * Danger! On SKL-ICL *reads* from the CSC coeff/offset registers
289 	 * will disarm an already armed CSC double buffer update.
290 	 * So this must not be called while armed. Fortunately the state checker
291 	 * readout happens only after the update has been already been latched.
292 	 *
293 	 * On earlier and later platforms only writes to said registers will
294 	 * disarm the update. This is considered normal behavior and also
295 	 * happens with various other hardware units.
296 	 */
297 	if (crtc_state->csc_enable)
298 		ilk_read_pipe_csc(crtc, &crtc_state->csc);
299 }
300 
301 static void icl_update_output_csc(struct intel_crtc *crtc,
302 				  const struct intel_csc_matrix *csc)
303 {
304 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
305 	enum pipe pipe = crtc->pipe;
306 
307 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_HI(pipe), csc->preoff[0]);
308 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_ME(pipe), csc->preoff[1]);
309 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_PREOFF_LO(pipe), csc->preoff[2]);
310 
311 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe),
312 			  csc->coeff[0] << 16 | csc->coeff[1]);
313 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BY(pipe),
314 			  csc->coeff[2] << 16);
315 
316 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe),
317 			  csc->coeff[3] << 16 | csc->coeff[4]);
318 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BU(pipe),
319 			  csc->coeff[5] << 16);
320 
321 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe),
322 			  csc->coeff[6] << 16 | csc->coeff[7]);
323 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_COEFF_BV(pipe),
324 			  csc->coeff[8] << 16);
325 
326 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe), csc->postoff[0]);
327 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe), csc->postoff[1]);
328 	intel_de_write_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe), csc->postoff[2]);
329 }
330 
331 static void icl_read_output_csc(struct intel_crtc *crtc,
332 				struct intel_csc_matrix *csc)
333 {
334 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
335 	enum pipe pipe = crtc->pipe;
336 	u32 tmp;
337 
338 	csc->preoff[0] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_PREOFF_HI(pipe));
339 	csc->preoff[1] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_PREOFF_ME(pipe));
340 	csc->preoff[2] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_PREOFF_LO(pipe));
341 
342 	tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe));
343 	csc->coeff[0] = tmp >> 16;
344 	csc->coeff[1] = tmp & 0xffff;
345 	tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_BY(pipe));
346 	csc->coeff[2] = tmp >> 16;
347 
348 	tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe));
349 	csc->coeff[3] = tmp >> 16;
350 	csc->coeff[4] = tmp & 0xffff;
351 	tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_BU(pipe));
352 	csc->coeff[5] = tmp >> 16;
353 
354 	tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe));
355 	csc->coeff[6] = tmp >> 16;
356 	csc->coeff[7] = tmp & 0xffff;
357 	tmp = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_COEFF_BV(pipe));
358 	csc->coeff[8] = tmp >> 16;
359 
360 	csc->postoff[0] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_HI(pipe));
361 	csc->postoff[1] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_ME(pipe));
362 	csc->postoff[2] = intel_de_read_fw(i915, PIPE_CSC_OUTPUT_POSTOFF_LO(pipe));
363 }
364 
365 static void icl_read_csc(struct intel_crtc_state *crtc_state)
366 {
367 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
368 
369 	/*
370 	 * Wa_1406463849: icl
371 	 *
372 	 * See skl_read_csc()
373 	 */
374 	if (crtc_state->csc_mode & ICL_CSC_ENABLE)
375 		ilk_read_pipe_csc(crtc, &crtc_state->csc);
376 
377 	if (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE)
378 		icl_read_output_csc(crtc, &crtc_state->output_csc);
379 }
380 
381 static bool ilk_limited_range(const struct intel_crtc_state *crtc_state)
382 {
383 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
384 
385 	/* icl+ have dedicated output CSC */
386 	if (DISPLAY_VER(i915) >= 11)
387 		return false;
388 
389 	/* pre-hsw have TRANSCONF_COLOR_RANGE_SELECT */
390 	if (DISPLAY_VER(i915) < 7 || IS_IVYBRIDGE(i915))
391 		return false;
392 
393 	return crtc_state->limited_color_range;
394 }
395 
396 static bool ilk_lut_limited_range(const struct intel_crtc_state *crtc_state)
397 {
398 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
399 
400 	if (!ilk_limited_range(crtc_state))
401 		return false;
402 
403 	if (crtc_state->c8_planes)
404 		return false;
405 
406 	if (DISPLAY_VER(i915) == 10)
407 		return crtc_state->hw.gamma_lut;
408 	else
409 		return crtc_state->hw.gamma_lut &&
410 			(crtc_state->hw.degamma_lut || crtc_state->hw.ctm);
411 }
412 
413 static bool ilk_csc_limited_range(const struct intel_crtc_state *crtc_state)
414 {
415 	if (!ilk_limited_range(crtc_state))
416 		return false;
417 
418 	return !ilk_lut_limited_range(crtc_state);
419 }
420 
421 static void ilk_csc_copy(struct drm_i915_private *i915,
422 			 struct intel_csc_matrix *dst,
423 			 const struct intel_csc_matrix *src)
424 {
425 	*dst = *src;
426 
427 	if (DISPLAY_VER(i915) < 7)
428 		memset(dst->postoff, 0, sizeof(dst->postoff));
429 }
430 
431 static void ilk_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
432 				struct intel_csc_matrix *csc,
433 				bool limited_color_range)
434 {
435 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
436 	const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
437 	const u64 *input;
438 	u64 temp[9];
439 	int i;
440 
441 	/* for preoff/postoff */
442 	if (limited_color_range)
443 		ilk_csc_copy(i915, csc, &ilk_csc_matrix_limited_range);
444 	else
445 		ilk_csc_copy(i915, csc, &ilk_csc_matrix_identity);
446 
447 	if (limited_color_range)
448 		input = ctm_mult_by_limited(temp, ctm->matrix);
449 	else
450 		input = ctm->matrix;
451 
452 	/*
453 	 * Convert fixed point S31.32 input to format supported by the
454 	 * hardware.
455 	 */
456 	for (i = 0; i < 9; i++) {
457 		u64 abs_coeff = ((1ULL << 63) - 1) & input[i];
458 
459 		/*
460 		 * Clamp input value to min/max supported by
461 		 * hardware.
462 		 */
463 		abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1);
464 
465 		csc->coeff[i] = 0;
466 
467 		/* sign bit */
468 		if (CTM_COEFF_NEGATIVE(input[i]))
469 			csc->coeff[i] |= 1 << 15;
470 
471 		if (abs_coeff < CTM_COEFF_0_125)
472 			csc->coeff[i] |= (3 << 12) |
473 				ILK_CSC_COEFF_FP(abs_coeff, 12);
474 		else if (abs_coeff < CTM_COEFF_0_25)
475 			csc->coeff[i] |= (2 << 12) |
476 				ILK_CSC_COEFF_FP(abs_coeff, 11);
477 		else if (abs_coeff < CTM_COEFF_0_5)
478 			csc->coeff[i] |= (1 << 12) |
479 				ILK_CSC_COEFF_FP(abs_coeff, 10);
480 		else if (abs_coeff < CTM_COEFF_1_0)
481 			csc->coeff[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9);
482 		else if (abs_coeff < CTM_COEFF_2_0)
483 			csc->coeff[i] |= (7 << 12) |
484 				ILK_CSC_COEFF_FP(abs_coeff, 8);
485 		else
486 			csc->coeff[i] |= (6 << 12) |
487 				ILK_CSC_COEFF_FP(abs_coeff, 7);
488 	}
489 }
490 
491 static void ilk_assign_csc(struct intel_crtc_state *crtc_state)
492 {
493 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
494 	bool limited_color_range = ilk_csc_limited_range(crtc_state);
495 
496 	if (crtc_state->hw.ctm) {
497 		drm_WARN_ON(&i915->drm, !crtc_state->csc_enable);
498 
499 		ilk_csc_convert_ctm(crtc_state, &crtc_state->csc, limited_color_range);
500 	} else if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
501 		drm_WARN_ON(&i915->drm, !crtc_state->csc_enable);
502 
503 		ilk_csc_copy(i915, &crtc_state->csc, &ilk_csc_matrix_rgb_to_ycbcr);
504 	} else if (limited_color_range) {
505 		drm_WARN_ON(&i915->drm, !crtc_state->csc_enable);
506 
507 		ilk_csc_copy(i915, &crtc_state->csc, &ilk_csc_matrix_limited_range);
508 	} else if (crtc_state->csc_enable) {
509 		/*
510 		 * On GLK both pipe CSC and degamma LUT are controlled
511 		 * by csc_enable. Hence for the cases where the degama
512 		 * LUT is needed but CSC is not we need to load an
513 		 * identity matrix.
514 		 */
515 		drm_WARN_ON(&i915->drm, !IS_GEMINILAKE(i915));
516 
517 		ilk_csc_copy(i915, &crtc_state->csc, &ilk_csc_matrix_identity);
518 	} else {
519 		intel_csc_clear(&crtc_state->csc);
520 	}
521 }
522 
523 static void ilk_load_csc_matrix(const struct intel_crtc_state *crtc_state)
524 {
525 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
526 
527 	if (crtc_state->csc_enable)
528 		ilk_update_pipe_csc(crtc, &crtc_state->csc);
529 }
530 
531 static void icl_assign_csc(struct intel_crtc_state *crtc_state)
532 {
533 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
534 
535 	if (crtc_state->hw.ctm) {
536 		drm_WARN_ON(&i915->drm, (crtc_state->csc_mode & ICL_CSC_ENABLE) == 0);
537 
538 		ilk_csc_convert_ctm(crtc_state, &crtc_state->csc, false);
539 	} else {
540 		drm_WARN_ON(&i915->drm, (crtc_state->csc_mode & ICL_CSC_ENABLE) != 0);
541 
542 		intel_csc_clear(&crtc_state->csc);
543 	}
544 
545 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) {
546 		drm_WARN_ON(&i915->drm, (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE) == 0);
547 
548 		ilk_csc_copy(i915, &crtc_state->output_csc, &ilk_csc_matrix_rgb_to_ycbcr);
549 	} else if (crtc_state->limited_color_range) {
550 		drm_WARN_ON(&i915->drm, (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE) == 0);
551 
552 		ilk_csc_copy(i915, &crtc_state->output_csc, &ilk_csc_matrix_limited_range);
553 	} else {
554 		drm_WARN_ON(&i915->drm, (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE) != 0);
555 
556 		intel_csc_clear(&crtc_state->output_csc);
557 	}
558 }
559 
560 static void icl_load_csc_matrix(const struct intel_crtc_state *crtc_state)
561 {
562 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
563 
564 	if (crtc_state->csc_mode & ICL_CSC_ENABLE)
565 		ilk_update_pipe_csc(crtc, &crtc_state->csc);
566 
567 	if (crtc_state->csc_mode & ICL_OUTPUT_CSC_ENABLE)
568 		icl_update_output_csc(crtc, &crtc_state->output_csc);
569 }
570 
571 static u16 ctm_to_twos_complement(u64 coeff, int int_bits, int frac_bits)
572 {
573 	s64 c = CTM_COEFF_ABS(coeff);
574 
575 	/* leave an extra bit for rounding */
576 	c >>= 32 - frac_bits - 1;
577 
578 	/* round and drop the extra bit */
579 	c = (c + 1) >> 1;
580 
581 	if (CTM_COEFF_NEGATIVE(coeff))
582 		c = -c;
583 
584 	c = clamp(c, -(s64)BIT(int_bits + frac_bits - 1),
585 		  (s64)(BIT(int_bits + frac_bits - 1) - 1));
586 
587 	return c & (BIT(int_bits + frac_bits) - 1);
588 }
589 
590 /*
591  * VLV/CHV Wide Gamut Color Correction (WGC) CSC
592  * |r|   | c0 c1 c2 |   |r|
593  * |g| = | c3 c4 c5 | x |g|
594  * |b|   | c6 c7 c8 |   |b|
595  *
596  * Coefficients are two's complement s2.10.
597  */
598 static void vlv_wgc_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
599 				    struct intel_csc_matrix *csc)
600 {
601 	const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
602 	int i;
603 
604 	for (i = 0; i < 9; i++)
605 		csc->coeff[i] = ctm_to_twos_complement(ctm->matrix[i], 2, 10);
606 }
607 
608 static void vlv_load_wgc_csc(struct intel_crtc *crtc,
609 			     const struct intel_csc_matrix *csc)
610 {
611 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
612 	enum pipe pipe = crtc->pipe;
613 
614 	intel_de_write_fw(dev_priv, PIPE_WGC_C01_C00(pipe),
615 			  csc->coeff[1] << 16 | csc->coeff[0]);
616 	intel_de_write_fw(dev_priv, PIPE_WGC_C02(pipe),
617 			  csc->coeff[2]);
618 
619 	intel_de_write_fw(dev_priv, PIPE_WGC_C11_C10(pipe),
620 			  csc->coeff[4] << 16 | csc->coeff[3]);
621 	intel_de_write_fw(dev_priv, PIPE_WGC_C12(pipe),
622 			  csc->coeff[5]);
623 
624 	intel_de_write_fw(dev_priv, PIPE_WGC_C21_C20(pipe),
625 			  csc->coeff[7] << 16 | csc->coeff[6]);
626 	intel_de_write_fw(dev_priv, PIPE_WGC_C22(pipe),
627 			  csc->coeff[8]);
628 }
629 
630 static void vlv_read_wgc_csc(struct intel_crtc *crtc,
631 			     struct intel_csc_matrix *csc)
632 {
633 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
634 	enum pipe pipe = crtc->pipe;
635 	u32 tmp;
636 
637 	tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C01_C00(pipe));
638 	csc->coeff[0] = tmp & 0xffff;
639 	csc->coeff[1] = tmp >> 16;
640 
641 	tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C02(pipe));
642 	csc->coeff[2] = tmp & 0xffff;
643 
644 	tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C11_C10(pipe));
645 	csc->coeff[3] = tmp & 0xffff;
646 	csc->coeff[4] = tmp >> 16;
647 
648 	tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C12(pipe));
649 	csc->coeff[5] = tmp & 0xffff;
650 
651 	tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C21_C20(pipe));
652 	csc->coeff[6] = tmp & 0xffff;
653 	csc->coeff[7] = tmp >> 16;
654 
655 	tmp = intel_de_read_fw(dev_priv, PIPE_WGC_C22(pipe));
656 	csc->coeff[8] = tmp & 0xffff;
657 }
658 
659 static void vlv_read_csc(struct intel_crtc_state *crtc_state)
660 {
661 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
662 
663 	if (crtc_state->wgc_enable)
664 		vlv_read_wgc_csc(crtc, &crtc_state->csc);
665 }
666 
667 static void vlv_assign_csc(struct intel_crtc_state *crtc_state)
668 {
669 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
670 
671 	if (crtc_state->hw.ctm) {
672 		drm_WARN_ON(&i915->drm, !crtc_state->wgc_enable);
673 
674 		vlv_wgc_csc_convert_ctm(crtc_state, &crtc_state->csc);
675 	} else {
676 		drm_WARN_ON(&i915->drm, crtc_state->wgc_enable);
677 
678 		intel_csc_clear(&crtc_state->csc);
679 	}
680 }
681 
682 /*
683  * CHV Color Gamut Mapping (CGM) CSC
684  * |r|   | c0 c1 c2 |   |r|
685  * |g| = | c3 c4 c5 | x |g|
686  * |b|   | c6 c7 c8 |   |b|
687  *
688  * Coefficients are two's complement s4.12.
689  */
690 static void chv_cgm_csc_convert_ctm(const struct intel_crtc_state *crtc_state,
691 				    struct intel_csc_matrix *csc)
692 {
693 	const struct drm_color_ctm *ctm = crtc_state->hw.ctm->data;
694 	int i;
695 
696 	for (i = 0; i < 9; i++)
697 		csc->coeff[i] = ctm_to_twos_complement(ctm->matrix[i], 4, 12);
698 }
699 
700 #define CHV_CGM_CSC_COEFF_1_0 (1 << 12)
701 
702 static const struct intel_csc_matrix chv_cgm_csc_matrix_identity = {
703 	.coeff = {
704 		CHV_CGM_CSC_COEFF_1_0, 0, 0,
705 		0, CHV_CGM_CSC_COEFF_1_0, 0,
706 		0, 0, CHV_CGM_CSC_COEFF_1_0,
707 	},
708 };
709 
710 static void chv_load_cgm_csc(struct intel_crtc *crtc,
711 			     const struct intel_csc_matrix *csc)
712 {
713 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
714 	enum pipe pipe = crtc->pipe;
715 
716 	intel_de_write_fw(i915, CGM_PIPE_CSC_COEFF01(pipe),
717 			  csc->coeff[1] << 16 | csc->coeff[0]);
718 	intel_de_write_fw(i915, CGM_PIPE_CSC_COEFF23(pipe),
719 			  csc->coeff[3] << 16 | csc->coeff[2]);
720 	intel_de_write_fw(i915, CGM_PIPE_CSC_COEFF45(pipe),
721 			  csc->coeff[5] << 16 | csc->coeff[4]);
722 	intel_de_write_fw(i915, CGM_PIPE_CSC_COEFF67(pipe),
723 			  csc->coeff[7] << 16 | csc->coeff[6]);
724 	intel_de_write_fw(i915, CGM_PIPE_CSC_COEFF8(pipe),
725 			  csc->coeff[8]);
726 }
727 
728 static void chv_read_cgm_csc(struct intel_crtc *crtc,
729 			     struct intel_csc_matrix *csc)
730 {
731 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
732 	enum pipe pipe = crtc->pipe;
733 	u32 tmp;
734 
735 	tmp = intel_de_read_fw(i915, CGM_PIPE_CSC_COEFF01(pipe));
736 	csc->coeff[0] = tmp & 0xffff;
737 	csc->coeff[1] = tmp >> 16;
738 
739 	tmp = intel_de_read_fw(i915, CGM_PIPE_CSC_COEFF23(pipe));
740 	csc->coeff[2] = tmp & 0xffff;
741 	csc->coeff[3] = tmp >> 16;
742 
743 	tmp = intel_de_read_fw(i915, CGM_PIPE_CSC_COEFF45(pipe));
744 	csc->coeff[4] = tmp & 0xffff;
745 	csc->coeff[5] = tmp >> 16;
746 
747 	tmp = intel_de_read_fw(i915, CGM_PIPE_CSC_COEFF67(pipe));
748 	csc->coeff[6] = tmp & 0xffff;
749 	csc->coeff[7] = tmp >> 16;
750 
751 	tmp = intel_de_read_fw(i915, CGM_PIPE_CSC_COEFF8(pipe));
752 	csc->coeff[8] = tmp & 0xffff;
753 }
754 
755 static void chv_read_csc(struct intel_crtc_state *crtc_state)
756 {
757 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
758 
759 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC)
760 		chv_read_cgm_csc(crtc, &crtc_state->csc);
761 }
762 
763 static void chv_assign_csc(struct intel_crtc_state *crtc_state)
764 {
765 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
766 
767 	drm_WARN_ON(&i915->drm, crtc_state->wgc_enable);
768 
769 	if (crtc_state->hw.ctm) {
770 		drm_WARN_ON(&i915->drm, (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC) == 0);
771 
772 		chv_cgm_csc_convert_ctm(crtc_state, &crtc_state->csc);
773 	} else {
774 		drm_WARN_ON(&i915->drm, (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC) == 0);
775 
776 		crtc_state->csc = chv_cgm_csc_matrix_identity;
777 	}
778 }
779 
780 /* convert hw value with given bit_precision to lut property val */
781 static u32 intel_color_lut_pack(u32 val, int bit_precision)
782 {
783 	u32 max = 0xffff >> (16 - bit_precision);
784 
785 	val = clamp_val(val, 0, max);
786 
787 	if (bit_precision < 16)
788 		val <<= 16 - bit_precision;
789 
790 	return val;
791 }
792 
793 static u32 i9xx_lut_8(const struct drm_color_lut *color)
794 {
795 	return REG_FIELD_PREP(PALETTE_RED_MASK, drm_color_lut_extract(color->red, 8)) |
796 		REG_FIELD_PREP(PALETTE_GREEN_MASK, drm_color_lut_extract(color->green, 8)) |
797 		REG_FIELD_PREP(PALETTE_BLUE_MASK, drm_color_lut_extract(color->blue, 8));
798 }
799 
800 static void i9xx_lut_8_pack(struct drm_color_lut *entry, u32 val)
801 {
802 	entry->red = intel_color_lut_pack(REG_FIELD_GET(PALETTE_RED_MASK, val), 8);
803 	entry->green = intel_color_lut_pack(REG_FIELD_GET(PALETTE_GREEN_MASK, val), 8);
804 	entry->blue = intel_color_lut_pack(REG_FIELD_GET(PALETTE_BLUE_MASK, val), 8);
805 }
806 
807 /* i8xx/i9xx+ 10bit slope format "even DW" (low 8 bits) */
808 static u32 _i9xx_lut_10_ldw(u16 a)
809 {
810 	return drm_color_lut_extract(a, 10) & 0xff;
811 }
812 
813 static u32 i9xx_lut_10_ldw(const struct drm_color_lut *color)
814 {
815 	return REG_FIELD_PREP(PALETTE_RED_MASK, _i9xx_lut_10_ldw(color[0].red)) |
816 		REG_FIELD_PREP(PALETTE_GREEN_MASK, _i9xx_lut_10_ldw(color[0].green)) |
817 		REG_FIELD_PREP(PALETTE_BLUE_MASK, _i9xx_lut_10_ldw(color[0].blue));
818 }
819 
820 /* i8xx/i9xx+ 10bit slope format "odd DW" (high 2 bits + slope) */
821 static u32 _i9xx_lut_10_udw(u16 a, u16 b)
822 {
823 	unsigned int mantissa, exponent;
824 
825 	a = drm_color_lut_extract(a, 10);
826 	b = drm_color_lut_extract(b, 10);
827 
828 	/* b = a + 8 * m * 2 ^ -e */
829 	mantissa = clamp(b - a, 0, 0x7f);
830 	exponent = 3;
831 	while (mantissa > 0xf) {
832 		mantissa >>= 1;
833 		exponent--;
834 	}
835 
836 	return (exponent << 6) |
837 		(mantissa << 2) |
838 		(a >> 8);
839 }
840 
841 static u32 i9xx_lut_10_udw(const struct drm_color_lut *color)
842 {
843 	return REG_FIELD_PREP(PALETTE_RED_MASK, _i9xx_lut_10_udw(color[0].red, color[1].red)) |
844 		REG_FIELD_PREP(PALETTE_GREEN_MASK, _i9xx_lut_10_udw(color[0].green, color[1].green)) |
845 		REG_FIELD_PREP(PALETTE_BLUE_MASK, _i9xx_lut_10_udw(color[0].blue, color[1].blue));
846 }
847 
848 static void i9xx_lut_10_pack(struct drm_color_lut *color,
849 			     u32 ldw, u32 udw)
850 {
851 	u16 red = REG_FIELD_GET(PALETTE_10BIT_RED_LDW_MASK, ldw) |
852 		REG_FIELD_GET(PALETTE_10BIT_RED_UDW_MASK, udw) << 8;
853 	u16 green = REG_FIELD_GET(PALETTE_10BIT_GREEN_LDW_MASK, ldw) |
854 		REG_FIELD_GET(PALETTE_10BIT_GREEN_UDW_MASK, udw) << 8;
855 	u16 blue = REG_FIELD_GET(PALETTE_10BIT_BLUE_LDW_MASK, ldw) |
856 		REG_FIELD_GET(PALETTE_10BIT_BLUE_UDW_MASK, udw) << 8;
857 
858 	color->red = intel_color_lut_pack(red, 10);
859 	color->green = intel_color_lut_pack(green, 10);
860 	color->blue = intel_color_lut_pack(blue, 10);
861 }
862 
863 static void i9xx_lut_10_pack_slope(struct drm_color_lut *color,
864 				   u32 ldw, u32 udw)
865 {
866 	int r_exp = REG_FIELD_GET(PALETTE_10BIT_RED_EXP_MASK, udw);
867 	int r_mant = REG_FIELD_GET(PALETTE_10BIT_RED_MANT_MASK, udw);
868 	int g_exp = REG_FIELD_GET(PALETTE_10BIT_GREEN_EXP_MASK, udw);
869 	int g_mant = REG_FIELD_GET(PALETTE_10BIT_GREEN_MANT_MASK, udw);
870 	int b_exp = REG_FIELD_GET(PALETTE_10BIT_BLUE_EXP_MASK, udw);
871 	int b_mant = REG_FIELD_GET(PALETTE_10BIT_BLUE_MANT_MASK, udw);
872 
873 	i9xx_lut_10_pack(color, ldw, udw);
874 
875 	color->red += r_mant << (3 - r_exp);
876 	color->green += g_mant << (3 - g_exp);
877 	color->blue += b_mant << (3 - b_exp);
878 }
879 
880 /* i965+ "10.6" bit interpolated format "even DW" (low 8 bits) */
881 static u32 i965_lut_10p6_ldw(const struct drm_color_lut *color)
882 {
883 	return REG_FIELD_PREP(PALETTE_RED_MASK, color->red & 0xff) |
884 		REG_FIELD_PREP(PALETTE_GREEN_MASK, color->green & 0xff) |
885 		REG_FIELD_PREP(PALETTE_BLUE_MASK, color->blue & 0xff);
886 }
887 
888 /* i965+ "10.6" interpolated format "odd DW" (high 8 bits) */
889 static u32 i965_lut_10p6_udw(const struct drm_color_lut *color)
890 {
891 	return REG_FIELD_PREP(PALETTE_RED_MASK, color->red >> 8) |
892 		REG_FIELD_PREP(PALETTE_GREEN_MASK, color->green >> 8) |
893 		REG_FIELD_PREP(PALETTE_BLUE_MASK, color->blue >> 8);
894 }
895 
896 static void i965_lut_10p6_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
897 {
898 	entry->red = REG_FIELD_GET(PALETTE_RED_MASK, udw) << 8 |
899 		REG_FIELD_GET(PALETTE_RED_MASK, ldw);
900 	entry->green = REG_FIELD_GET(PALETTE_GREEN_MASK, udw) << 8 |
901 		REG_FIELD_GET(PALETTE_GREEN_MASK, ldw);
902 	entry->blue = REG_FIELD_GET(PALETTE_BLUE_MASK, udw) << 8 |
903 		REG_FIELD_GET(PALETTE_BLUE_MASK, ldw);
904 }
905 
906 static u16 i965_lut_11p6_max_pack(u32 val)
907 {
908 	/* PIPEGCMAX is 11.6, clamp to 10.6 */
909 	return clamp_val(val, 0, 0xffff);
910 }
911 
912 static u32 ilk_lut_10(const struct drm_color_lut *color)
913 {
914 	return REG_FIELD_PREP(PREC_PALETTE_10_RED_MASK, drm_color_lut_extract(color->red, 10)) |
915 		REG_FIELD_PREP(PREC_PALETTE_10_GREEN_MASK, drm_color_lut_extract(color->green, 10)) |
916 		REG_FIELD_PREP(PREC_PALETTE_10_BLUE_MASK, drm_color_lut_extract(color->blue, 10));
917 }
918 
919 static void ilk_lut_10_pack(struct drm_color_lut *entry, u32 val)
920 {
921 	entry->red = intel_color_lut_pack(REG_FIELD_GET(PREC_PALETTE_10_RED_MASK, val), 10);
922 	entry->green = intel_color_lut_pack(REG_FIELD_GET(PREC_PALETTE_10_GREEN_MASK, val), 10);
923 	entry->blue = intel_color_lut_pack(REG_FIELD_GET(PREC_PALETTE_10_BLUE_MASK, val), 10);
924 }
925 
926 /* ilk+ "12.4" interpolated format (low 6 bits) */
927 static u32 ilk_lut_12p4_ldw(const struct drm_color_lut *color)
928 {
929 	return REG_FIELD_PREP(PREC_PALETTE_12P4_RED_LDW_MASK, color->red & 0x3f) |
930 		REG_FIELD_PREP(PREC_PALETTE_12P4_GREEN_LDW_MASK, color->green & 0x3f) |
931 		REG_FIELD_PREP(PREC_PALETTE_12P4_BLUE_LDW_MASK, color->blue & 0x3f);
932 }
933 
934 /* ilk+ "12.4" interpolated format (high 10 bits) */
935 static u32 ilk_lut_12p4_udw(const struct drm_color_lut *color)
936 {
937 	return REG_FIELD_PREP(PREC_PALETTE_12P4_RED_UDW_MASK, color->red >> 6) |
938 		REG_FIELD_PREP(PREC_PALETTE_12P4_GREEN_UDW_MASK, color->green >> 6) |
939 		REG_FIELD_PREP(PREC_PALETTE_12P4_BLUE_UDW_MASK, color->blue >> 6);
940 }
941 
942 static void ilk_lut_12p4_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
943 {
944 	entry->red = REG_FIELD_GET(PREC_PALETTE_12P4_RED_UDW_MASK, udw) << 6 |
945 		REG_FIELD_GET(PREC_PALETTE_12P4_RED_LDW_MASK, ldw);
946 	entry->green = REG_FIELD_GET(PREC_PALETTE_12P4_GREEN_UDW_MASK, udw) << 6 |
947 		REG_FIELD_GET(PREC_PALETTE_12P4_GREEN_LDW_MASK, ldw);
948 	entry->blue = REG_FIELD_GET(PREC_PALETTE_12P4_BLUE_UDW_MASK, udw) << 6 |
949 		REG_FIELD_GET(PREC_PALETTE_12P4_BLUE_LDW_MASK, ldw);
950 }
951 
952 static void icl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
953 {
954 	/*
955 	 * Despite Wa_1406463849, ICL no longer suffers from the SKL
956 	 * DC5/PSR CSC black screen issue (see skl_color_commit_noarm()).
957 	 * Possibly due to the extra sticky CSC arming
958 	 * (see icl_color_post_update()).
959 	 *
960 	 * On TGL+ all CSC arming issues have been properly fixed.
961 	 */
962 	icl_load_csc_matrix(crtc_state);
963 }
964 
965 static void skl_color_commit_noarm(const struct intel_crtc_state *crtc_state)
966 {
967 	/*
968 	 * Possibly related to display WA #1184, SKL CSC loses the latched
969 	 * CSC coeff/offset register values if the CSC registers are disarmed
970 	 * between DC5 exit and PSR exit. This will cause the plane(s) to
971 	 * output all black (until CSC_MODE is rearmed and properly latched).
972 	 * Once PSR exit (and proper register latching) has occurred the
973 	 * danger is over. Thus when PSR is enabled the CSC coeff/offset
974 	 * register programming will be peformed from skl_color_commit_arm()
975 	 * which is called after PSR exit.
976 	 */
977 	if (!crtc_state->has_psr)
978 		ilk_load_csc_matrix(crtc_state);
979 }
980 
981 static void ilk_color_commit_noarm(const struct intel_crtc_state *crtc_state)
982 {
983 	ilk_load_csc_matrix(crtc_state);
984 }
985 
986 static void i9xx_color_commit_arm(const struct intel_crtc_state *crtc_state)
987 {
988 	/* update TRANSCONF GAMMA_MODE */
989 	i9xx_set_pipeconf(crtc_state);
990 }
991 
992 static void ilk_color_commit_arm(const struct intel_crtc_state *crtc_state)
993 {
994 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
995 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
996 
997 	/* update TRANSCONF GAMMA_MODE */
998 	ilk_set_pipeconf(crtc_state);
999 
1000 	intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
1001 			  crtc_state->csc_mode);
1002 }
1003 
1004 static void hsw_color_commit_arm(const struct intel_crtc_state *crtc_state)
1005 {
1006 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1007 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1008 
1009 	intel_de_write(i915, GAMMA_MODE(crtc->pipe),
1010 		       crtc_state->gamma_mode);
1011 
1012 	intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
1013 			  crtc_state->csc_mode);
1014 }
1015 
1016 static void skl_color_commit_arm(const struct intel_crtc_state *crtc_state)
1017 {
1018 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1019 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1020 	enum pipe pipe = crtc->pipe;
1021 	u32 val = 0;
1022 
1023 	if (crtc_state->has_psr)
1024 		ilk_load_csc_matrix(crtc_state);
1025 
1026 	/*
1027 	 * We don't (yet) allow userspace to control the pipe background color,
1028 	 * so force it to black, but apply pipe gamma and CSC appropriately
1029 	 * so that its handling will match how we program our planes.
1030 	 */
1031 	if (crtc_state->gamma_enable)
1032 		val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE;
1033 	if (crtc_state->csc_enable)
1034 		val |= SKL_BOTTOM_COLOR_CSC_ENABLE;
1035 	intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), val);
1036 
1037 	intel_de_write(i915, GAMMA_MODE(crtc->pipe),
1038 		       crtc_state->gamma_mode);
1039 
1040 	intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
1041 			  crtc_state->csc_mode);
1042 }
1043 
1044 static void icl_color_commit_arm(const struct intel_crtc_state *crtc_state)
1045 {
1046 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1047 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1048 	enum pipe pipe = crtc->pipe;
1049 
1050 	/*
1051 	 * We don't (yet) allow userspace to control the pipe background color,
1052 	 * so force it to black.
1053 	 */
1054 	intel_de_write(i915, SKL_BOTTOM_COLOR(pipe), 0);
1055 
1056 	intel_de_write(i915, GAMMA_MODE(crtc->pipe),
1057 		       crtc_state->gamma_mode);
1058 
1059 	intel_de_write_fw(i915, PIPE_CSC_MODE(crtc->pipe),
1060 			  crtc_state->csc_mode);
1061 }
1062 
1063 static void icl_color_post_update(const struct intel_crtc_state *crtc_state)
1064 {
1065 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1066 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1067 
1068 	/*
1069 	 * Despite Wa_1406463849, ICL CSC is no longer disarmed by
1070 	 * coeff/offset register *writes*. Instead, once CSC_MODE
1071 	 * is armed it stays armed, even after it has been latched.
1072 	 * Afterwards the coeff/offset registers become effectively
1073 	 * self-arming. That self-arming must be disabled before the
1074 	 * next icl_color_commit_noarm() tries to write the next set
1075 	 * of coeff/offset registers. Fortunately register *reads*
1076 	 * do still disarm the CSC. Naturally this must not be done
1077 	 * until the previously written CSC registers have actually
1078 	 * been latched.
1079 	 *
1080 	 * TGL+ no longer need this workaround.
1081 	 */
1082 	intel_de_read_fw(i915, PIPE_CSC_PREOFF_HI(crtc->pipe));
1083 }
1084 
1085 static struct drm_property_blob *
1086 create_linear_lut(struct drm_i915_private *i915, int lut_size)
1087 {
1088 	struct drm_property_blob *blob;
1089 	struct drm_color_lut *lut;
1090 	int i;
1091 
1092 	blob = drm_property_create_blob(&i915->drm,
1093 					sizeof(lut[0]) * lut_size,
1094 					NULL);
1095 	if (IS_ERR(blob))
1096 		return blob;
1097 
1098 	lut = blob->data;
1099 
1100 	for (i = 0; i < lut_size; i++) {
1101 		u16 val = 0xffff * i / (lut_size - 1);
1102 
1103 		lut[i].red = val;
1104 		lut[i].green = val;
1105 		lut[i].blue = val;
1106 	}
1107 
1108 	return blob;
1109 }
1110 
1111 static u16 lut_limited_range(unsigned int value)
1112 {
1113 	unsigned int min = 16 << 8;
1114 	unsigned int max = 235 << 8;
1115 
1116 	return value * (max - min) / 0xffff + min;
1117 }
1118 
1119 static struct drm_property_blob *
1120 create_resized_lut(struct drm_i915_private *i915,
1121 		   const struct drm_property_blob *blob_in, int lut_out_size,
1122 		   bool limited_color_range)
1123 {
1124 	int i, lut_in_size = drm_color_lut_size(blob_in);
1125 	struct drm_property_blob *blob_out;
1126 	const struct drm_color_lut *lut_in;
1127 	struct drm_color_lut *lut_out;
1128 
1129 	blob_out = drm_property_create_blob(&i915->drm,
1130 					    sizeof(lut_out[0]) * lut_out_size,
1131 					    NULL);
1132 	if (IS_ERR(blob_out))
1133 		return blob_out;
1134 
1135 	lut_in = blob_in->data;
1136 	lut_out = blob_out->data;
1137 
1138 	for (i = 0; i < lut_out_size; i++) {
1139 		const struct drm_color_lut *entry =
1140 			&lut_in[i * (lut_in_size - 1) / (lut_out_size - 1)];
1141 
1142 		if (limited_color_range) {
1143 			lut_out[i].red = lut_limited_range(entry->red);
1144 			lut_out[i].green = lut_limited_range(entry->green);
1145 			lut_out[i].blue = lut_limited_range(entry->blue);
1146 		} else {
1147 			lut_out[i] = *entry;
1148 		}
1149 	}
1150 
1151 	return blob_out;
1152 }
1153 
1154 static void i9xx_load_lut_8(struct intel_crtc *crtc,
1155 			    const struct drm_property_blob *blob)
1156 {
1157 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1158 	const struct drm_color_lut *lut;
1159 	enum pipe pipe = crtc->pipe;
1160 	int i;
1161 
1162 	if (!blob)
1163 		return;
1164 
1165 	lut = blob->data;
1166 
1167 	for (i = 0; i < 256; i++)
1168 		intel_de_write_fw(dev_priv, PALETTE(pipe, i),
1169 				  i9xx_lut_8(&lut[i]));
1170 }
1171 
1172 static void i9xx_load_lut_10(struct intel_crtc *crtc,
1173 			     const struct drm_property_blob *blob)
1174 {
1175 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1176 	const struct drm_color_lut *lut = blob->data;
1177 	int i, lut_size = drm_color_lut_size(blob);
1178 	enum pipe pipe = crtc->pipe;
1179 
1180 	for (i = 0; i < lut_size - 1; i++) {
1181 		intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 0),
1182 				  i9xx_lut_10_ldw(&lut[i]));
1183 		intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 1),
1184 				  i9xx_lut_10_udw(&lut[i]));
1185 	}
1186 }
1187 
1188 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state)
1189 {
1190 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1191 	const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1192 
1193 	switch (crtc_state->gamma_mode) {
1194 	case GAMMA_MODE_MODE_8BIT:
1195 		i9xx_load_lut_8(crtc, post_csc_lut);
1196 		break;
1197 	case GAMMA_MODE_MODE_10BIT:
1198 		i9xx_load_lut_10(crtc, post_csc_lut);
1199 		break;
1200 	default:
1201 		MISSING_CASE(crtc_state->gamma_mode);
1202 		break;
1203 	}
1204 }
1205 
1206 static void i965_load_lut_10p6(struct intel_crtc *crtc,
1207 			       const struct drm_property_blob *blob)
1208 {
1209 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1210 	const struct drm_color_lut *lut = blob->data;
1211 	int i, lut_size = drm_color_lut_size(blob);
1212 	enum pipe pipe = crtc->pipe;
1213 
1214 	for (i = 0; i < lut_size - 1; i++) {
1215 		intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 0),
1216 				  i965_lut_10p6_ldw(&lut[i]));
1217 		intel_de_write_fw(dev_priv, PALETTE(pipe, 2 * i + 1),
1218 				  i965_lut_10p6_udw(&lut[i]));
1219 	}
1220 
1221 	intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 0), lut[i].red);
1222 	intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 1), lut[i].green);
1223 	intel_de_write_fw(dev_priv, PIPEGCMAX(pipe, 2), lut[i].blue);
1224 }
1225 
1226 static void i965_load_luts(const struct intel_crtc_state *crtc_state)
1227 {
1228 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1229 	const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1230 
1231 	switch (crtc_state->gamma_mode) {
1232 	case GAMMA_MODE_MODE_8BIT:
1233 		i9xx_load_lut_8(crtc, post_csc_lut);
1234 		break;
1235 	case GAMMA_MODE_MODE_10BIT:
1236 		i965_load_lut_10p6(crtc, post_csc_lut);
1237 		break;
1238 	default:
1239 		MISSING_CASE(crtc_state->gamma_mode);
1240 		break;
1241 	}
1242 }
1243 
1244 static void ilk_lut_write(const struct intel_crtc_state *crtc_state,
1245 			  i915_reg_t reg, u32 val)
1246 {
1247 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1248 
1249 	if (crtc_state->dsb)
1250 		intel_dsb_reg_write(crtc_state->dsb, reg, val);
1251 	else
1252 		intel_de_write_fw(i915, reg, val);
1253 }
1254 
1255 static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state,
1256 			   const struct drm_property_blob *blob)
1257 {
1258 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1259 	const struct drm_color_lut *lut;
1260 	enum pipe pipe = crtc->pipe;
1261 	int i;
1262 
1263 	if (!blob)
1264 		return;
1265 
1266 	lut = blob->data;
1267 
1268 	for (i = 0; i < 256; i++)
1269 		ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i),
1270 			      i9xx_lut_8(&lut[i]));
1271 }
1272 
1273 static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state,
1274 			    const struct drm_property_blob *blob)
1275 {
1276 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1277 	const struct drm_color_lut *lut = blob->data;
1278 	int i, lut_size = drm_color_lut_size(blob);
1279 	enum pipe pipe = crtc->pipe;
1280 
1281 	for (i = 0; i < lut_size; i++)
1282 		ilk_lut_write(crtc_state, PREC_PALETTE(pipe, i),
1283 			      ilk_lut_10(&lut[i]));
1284 }
1285 
1286 static void ilk_load_luts(const struct intel_crtc_state *crtc_state)
1287 {
1288 	const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1289 	const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1290 	const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
1291 
1292 	switch (crtc_state->gamma_mode) {
1293 	case GAMMA_MODE_MODE_8BIT:
1294 		ilk_load_lut_8(crtc_state, blob);
1295 		break;
1296 	case GAMMA_MODE_MODE_10BIT:
1297 		ilk_load_lut_10(crtc_state, blob);
1298 		break;
1299 	default:
1300 		MISSING_CASE(crtc_state->gamma_mode);
1301 		break;
1302 	}
1303 }
1304 
1305 static int ivb_lut_10_size(u32 prec_index)
1306 {
1307 	if (prec_index & PAL_PREC_SPLIT_MODE)
1308 		return 512;
1309 	else
1310 		return 1024;
1311 }
1312 
1313 /*
1314  * IVB/HSW Bspec / PAL_PREC_INDEX:
1315  * "Restriction : Index auto increment mode is not
1316  *  supported and must not be enabled."
1317  */
1318 static void ivb_load_lut_10(const struct intel_crtc_state *crtc_state,
1319 			    const struct drm_property_blob *blob,
1320 			    u32 prec_index)
1321 {
1322 	const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1323 	const struct drm_color_lut *lut = blob->data;
1324 	int i, lut_size = drm_color_lut_size(blob);
1325 	enum pipe pipe = crtc->pipe;
1326 
1327 	for (i = 0; i < lut_size; i++) {
1328 		ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1329 			      prec_index + i);
1330 		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1331 			      ilk_lut_10(&lut[i]));
1332 	}
1333 
1334 	/*
1335 	 * Reset the index, otherwise it prevents the legacy palette to be
1336 	 * written properly.
1337 	 */
1338 	ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1339 		      PAL_PREC_INDEX_VALUE(0));
1340 }
1341 
1342 /* On BDW+ the index auto increment mode actually works */
1343 static void bdw_load_lut_10(const struct intel_crtc_state *crtc_state,
1344 			    const struct drm_property_blob *blob,
1345 			    u32 prec_index)
1346 {
1347 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1348 	const struct drm_color_lut *lut = blob->data;
1349 	int i, lut_size = drm_color_lut_size(blob);
1350 	enum pipe pipe = crtc->pipe;
1351 
1352 	ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1353 		      prec_index);
1354 	ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1355 		      PAL_PREC_AUTO_INCREMENT |
1356 		      prec_index);
1357 
1358 	for (i = 0; i < lut_size; i++)
1359 		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1360 			      ilk_lut_10(&lut[i]));
1361 
1362 	/*
1363 	 * Reset the index, otherwise it prevents the legacy palette to be
1364 	 * written properly.
1365 	 */
1366 	ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1367 		      PAL_PREC_INDEX_VALUE(0));
1368 }
1369 
1370 static void ivb_load_lut_ext_max(const struct intel_crtc_state *crtc_state)
1371 {
1372 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1373 	enum pipe pipe = crtc->pipe;
1374 
1375 	/* Program the max register to clamp values > 1.0. */
1376 	ilk_lut_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16);
1377 	ilk_lut_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16);
1378 	ilk_lut_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16);
1379 }
1380 
1381 static void glk_load_lut_ext2_max(const struct intel_crtc_state *crtc_state)
1382 {
1383 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1384 	enum pipe pipe = crtc->pipe;
1385 
1386 	/* Program the max register to clamp values > 1.0. */
1387 	ilk_lut_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 0), 1 << 16);
1388 	ilk_lut_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 1), 1 << 16);
1389 	ilk_lut_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 2), 1 << 16);
1390 }
1391 
1392 static void ivb_load_luts(const struct intel_crtc_state *crtc_state)
1393 {
1394 	const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1395 	const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1396 	const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
1397 
1398 	switch (crtc_state->gamma_mode) {
1399 	case GAMMA_MODE_MODE_8BIT:
1400 		ilk_load_lut_8(crtc_state, blob);
1401 		break;
1402 	case GAMMA_MODE_MODE_SPLIT:
1403 		ivb_load_lut_10(crtc_state, pre_csc_lut, PAL_PREC_SPLIT_MODE |
1404 				PAL_PREC_INDEX_VALUE(0));
1405 		ivb_load_lut_ext_max(crtc_state);
1406 		ivb_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_SPLIT_MODE |
1407 				PAL_PREC_INDEX_VALUE(512));
1408 		break;
1409 	case GAMMA_MODE_MODE_10BIT:
1410 		ivb_load_lut_10(crtc_state, blob,
1411 				PAL_PREC_INDEX_VALUE(0));
1412 		ivb_load_lut_ext_max(crtc_state);
1413 		break;
1414 	default:
1415 		MISSING_CASE(crtc_state->gamma_mode);
1416 		break;
1417 	}
1418 }
1419 
1420 static void bdw_load_luts(const struct intel_crtc_state *crtc_state)
1421 {
1422 	const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1423 	const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1424 	const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut;
1425 
1426 	switch (crtc_state->gamma_mode) {
1427 	case GAMMA_MODE_MODE_8BIT:
1428 		ilk_load_lut_8(crtc_state, blob);
1429 		break;
1430 	case GAMMA_MODE_MODE_SPLIT:
1431 		bdw_load_lut_10(crtc_state, pre_csc_lut, PAL_PREC_SPLIT_MODE |
1432 				PAL_PREC_INDEX_VALUE(0));
1433 		ivb_load_lut_ext_max(crtc_state);
1434 		bdw_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_SPLIT_MODE |
1435 				PAL_PREC_INDEX_VALUE(512));
1436 		break;
1437 	case GAMMA_MODE_MODE_10BIT:
1438 		bdw_load_lut_10(crtc_state, blob,
1439 				PAL_PREC_INDEX_VALUE(0));
1440 		ivb_load_lut_ext_max(crtc_state);
1441 		break;
1442 	default:
1443 		MISSING_CASE(crtc_state->gamma_mode);
1444 		break;
1445 	}
1446 }
1447 
1448 static int glk_degamma_lut_size(struct drm_i915_private *i915)
1449 {
1450 	if (DISPLAY_VER(i915) >= 13)
1451 		return 131;
1452 	else
1453 		return 35;
1454 }
1455 
1456 /*
1457  * change_lut_val_precision: helper function to upscale or downscale lut values.
1458  * Parameters 'to' and 'from' needs to be less than 32. This should be sufficient
1459  * as currently there are no lut values exceeding 32 bit.
1460  */
1461 static u32 change_lut_val_precision(u32 lut_val, int to, int from)
1462 {
1463 	return mul_u32_u32(lut_val, (1 << to)) / (1 << from);
1464 }
1465 
1466 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state,
1467 				 const struct drm_property_blob *blob)
1468 {
1469 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1470 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1471 	const struct drm_color_lut *lut = blob->data;
1472 	int i, lut_size = drm_color_lut_size(blob);
1473 	enum pipe pipe = crtc->pipe;
1474 
1475 	/*
1476 	 * When setting the auto-increment bit, the hardware seems to
1477 	 * ignore the index bits, so we need to reset it to index 0
1478 	 * separately.
1479 	 */
1480 	ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe),
1481 		      PRE_CSC_GAMC_INDEX_VALUE(0));
1482 	ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe),
1483 		      PRE_CSC_GAMC_AUTO_INCREMENT |
1484 		      PRE_CSC_GAMC_INDEX_VALUE(0));
1485 
1486 	for (i = 0; i < lut_size; i++) {
1487 		/*
1488 		 * First lut_size entries represent range from 0 to 1.0
1489 		 * 3 additional lut entries will represent extended range
1490 		 * inputs 3.0 and 7.0 respectively, currently clamped
1491 		 * at 1.0. Since the precision is 16bit, the user
1492 		 * value can be directly filled to register.
1493 		 * The pipe degamma table in GLK+ onwards doesn't
1494 		 * support different values per channel, so this just
1495 		 * programs green value which will be equal to Red and
1496 		 * Blue into the lut registers.
1497 		 * ToDo: Extend to max 7.0. Enable 32 bit input value
1498 		 * as compared to just 16 to achieve this.
1499 		 */
1500 		u32 lut_val;
1501 
1502 		if (DISPLAY_VER(i915) >= 14)
1503 			lut_val = change_lut_val_precision(lut[i].green, 24, 16);
1504 		else
1505 			lut_val = lut[i].green;
1506 
1507 		ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe),
1508 			      lut_val);
1509 	}
1510 
1511 	/* Clamp values > 1.0. */
1512 	while (i++ < glk_degamma_lut_size(i915))
1513 		ilk_lut_write(crtc_state, PRE_CSC_GAMC_DATA(pipe), 1 << 16);
1514 
1515 	ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe), 0);
1516 }
1517 
1518 static void glk_load_luts(const struct intel_crtc_state *crtc_state)
1519 {
1520 	const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1521 	const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1522 
1523 	if (pre_csc_lut)
1524 		glk_load_degamma_lut(crtc_state, pre_csc_lut);
1525 
1526 	switch (crtc_state->gamma_mode) {
1527 	case GAMMA_MODE_MODE_8BIT:
1528 		ilk_load_lut_8(crtc_state, post_csc_lut);
1529 		break;
1530 	case GAMMA_MODE_MODE_10BIT:
1531 		bdw_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_INDEX_VALUE(0));
1532 		ivb_load_lut_ext_max(crtc_state);
1533 		glk_load_lut_ext2_max(crtc_state);
1534 		break;
1535 	default:
1536 		MISSING_CASE(crtc_state->gamma_mode);
1537 		break;
1538 	}
1539 }
1540 
1541 static void
1542 ivb_load_lut_max(const struct intel_crtc_state *crtc_state,
1543 		 const struct drm_color_lut *color)
1544 {
1545 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1546 	enum pipe pipe = crtc->pipe;
1547 
1548 	/* FIXME LUT entries are 16 bit only, so we can prog 0xFFFF max */
1549 	ilk_lut_write(crtc_state, PREC_PAL_GC_MAX(pipe, 0), color->red);
1550 	ilk_lut_write(crtc_state, PREC_PAL_GC_MAX(pipe, 1), color->green);
1551 	ilk_lut_write(crtc_state, PREC_PAL_GC_MAX(pipe, 2), color->blue);
1552 }
1553 
1554 static void
1555 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state)
1556 {
1557 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1558 	const struct drm_property_blob *blob = crtc_state->post_csc_lut;
1559 	const struct drm_color_lut *lut = blob->data;
1560 	enum pipe pipe = crtc->pipe;
1561 	int i;
1562 
1563 	/*
1564 	 * Program Super Fine segment (let's call it seg1)...
1565 	 *
1566 	 * Super Fine segment's step is 1/(8 * 128 * 256) and it has
1567 	 * 9 entries, corresponding to values 0, 1/(8 * 128 * 256),
1568 	 * 2/(8 * 128 * 256) ... 8/(8 * 128 * 256).
1569 	 */
1570 	ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe),
1571 		      PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
1572 	ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe),
1573 		      PAL_PREC_AUTO_INCREMENT |
1574 		      PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
1575 
1576 	for (i = 0; i < 9; i++) {
1577 		const struct drm_color_lut *entry = &lut[i];
1578 
1579 		ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
1580 			      ilk_lut_12p4_ldw(entry));
1581 		ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe),
1582 			      ilk_lut_12p4_udw(entry));
1583 	}
1584 
1585 	ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe),
1586 		      PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
1587 }
1588 
1589 static void
1590 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state)
1591 {
1592 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1593 	const struct drm_property_blob *blob = crtc_state->post_csc_lut;
1594 	const struct drm_color_lut *lut = blob->data;
1595 	const struct drm_color_lut *entry;
1596 	enum pipe pipe = crtc->pipe;
1597 	int i;
1598 
1599 	/*
1600 	 * Program Fine segment (let's call it seg2)...
1601 	 *
1602 	 * Fine segment's step is 1/(128 * 256) i.e. 1/(128 * 256), 2/(128 * 256)
1603 	 * ... 256/(128 * 256). So in order to program fine segment of LUT we
1604 	 * need to pick every 8th entry in the LUT, and program 256 indexes.
1605 	 *
1606 	 * PAL_PREC_INDEX[0] and PAL_PREC_INDEX[1] map to seg2[1],
1607 	 * seg2[0] being unused by the hardware.
1608 	 */
1609 	ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1610 		      PAL_PREC_INDEX_VALUE(0));
1611 	ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1612 		      PAL_PREC_AUTO_INCREMENT |
1613 		      PAL_PREC_INDEX_VALUE(0));
1614 
1615 	for (i = 1; i < 257; i++) {
1616 		entry = &lut[i * 8];
1617 
1618 		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1619 			      ilk_lut_12p4_ldw(entry));
1620 		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1621 			      ilk_lut_12p4_udw(entry));
1622 	}
1623 
1624 	/*
1625 	 * Program Coarse segment (let's call it seg3)...
1626 	 *
1627 	 * Coarse segment starts from index 0 and it's step is 1/256 ie 0,
1628 	 * 1/256, 2/256 ... 256/256. As per the description of each entry in LUT
1629 	 * above, we need to pick every (8 * 128)th entry in LUT, and
1630 	 * program 256 of those.
1631 	 *
1632 	 * Spec is not very clear about if entries seg3[0] and seg3[1] are
1633 	 * being used or not, but we still need to program these to advance
1634 	 * the index.
1635 	 */
1636 	for (i = 0; i < 256; i++) {
1637 		entry = &lut[i * 8 * 128];
1638 
1639 		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1640 			      ilk_lut_12p4_ldw(entry));
1641 		ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe),
1642 			      ilk_lut_12p4_udw(entry));
1643 	}
1644 
1645 	ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe),
1646 		      PAL_PREC_INDEX_VALUE(0));
1647 
1648 	/* The last entry in the LUT is to be programmed in GCMAX */
1649 	entry = &lut[256 * 8 * 128];
1650 	ivb_load_lut_max(crtc_state, entry);
1651 }
1652 
1653 static void icl_load_luts(const struct intel_crtc_state *crtc_state)
1654 {
1655 	const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1656 	const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1657 
1658 	if (pre_csc_lut)
1659 		glk_load_degamma_lut(crtc_state, pre_csc_lut);
1660 
1661 	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
1662 	case GAMMA_MODE_MODE_8BIT:
1663 		ilk_load_lut_8(crtc_state, post_csc_lut);
1664 		break;
1665 	case GAMMA_MODE_MODE_12BIT_MULTI_SEG:
1666 		icl_program_gamma_superfine_segment(crtc_state);
1667 		icl_program_gamma_multi_segment(crtc_state);
1668 		ivb_load_lut_ext_max(crtc_state);
1669 		glk_load_lut_ext2_max(crtc_state);
1670 		break;
1671 	case GAMMA_MODE_MODE_10BIT:
1672 		bdw_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_INDEX_VALUE(0));
1673 		ivb_load_lut_ext_max(crtc_state);
1674 		glk_load_lut_ext2_max(crtc_state);
1675 		break;
1676 	default:
1677 		MISSING_CASE(crtc_state->gamma_mode);
1678 		break;
1679 	}
1680 
1681 	if (crtc_state->dsb) {
1682 		intel_dsb_finish(crtc_state->dsb);
1683 		intel_dsb_commit(crtc_state->dsb, false);
1684 		intel_dsb_wait(crtc_state->dsb);
1685 	}
1686 }
1687 
1688 static void vlv_load_luts(const struct intel_crtc_state *crtc_state)
1689 {
1690 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1691 
1692 	if (crtc_state->wgc_enable)
1693 		vlv_load_wgc_csc(crtc, &crtc_state->csc);
1694 
1695 	i965_load_luts(crtc_state);
1696 }
1697 
1698 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color)
1699 {
1700 	return REG_FIELD_PREP(CGM_PIPE_DEGAMMA_GREEN_LDW_MASK, drm_color_lut_extract(color->green, 14)) |
1701 		REG_FIELD_PREP(CGM_PIPE_DEGAMMA_BLUE_LDW_MASK, drm_color_lut_extract(color->blue, 14));
1702 }
1703 
1704 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color)
1705 {
1706 	return REG_FIELD_PREP(CGM_PIPE_DEGAMMA_RED_UDW_MASK, drm_color_lut_extract(color->red, 14));
1707 }
1708 
1709 static void chv_cgm_degamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
1710 {
1711 	entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_DEGAMMA_GREEN_LDW_MASK, ldw), 14);
1712 	entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_DEGAMMA_BLUE_LDW_MASK, ldw), 14);
1713 	entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_DEGAMMA_RED_UDW_MASK, udw), 14);
1714 }
1715 
1716 static void chv_load_cgm_degamma(struct intel_crtc *crtc,
1717 				 const struct drm_property_blob *blob)
1718 {
1719 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1720 	const struct drm_color_lut *lut = blob->data;
1721 	int i, lut_size = drm_color_lut_size(blob);
1722 	enum pipe pipe = crtc->pipe;
1723 
1724 	for (i = 0; i < lut_size; i++) {
1725 		intel_de_write_fw(i915, CGM_PIPE_DEGAMMA(pipe, i, 0),
1726 				  chv_cgm_degamma_ldw(&lut[i]));
1727 		intel_de_write_fw(i915, CGM_PIPE_DEGAMMA(pipe, i, 1),
1728 				  chv_cgm_degamma_udw(&lut[i]));
1729 	}
1730 }
1731 
1732 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color)
1733 {
1734 	return REG_FIELD_PREP(CGM_PIPE_GAMMA_GREEN_LDW_MASK, drm_color_lut_extract(color->green, 10)) |
1735 		REG_FIELD_PREP(CGM_PIPE_GAMMA_BLUE_LDW_MASK, drm_color_lut_extract(color->blue, 10));
1736 }
1737 
1738 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color)
1739 {
1740 	return REG_FIELD_PREP(CGM_PIPE_GAMMA_RED_UDW_MASK, drm_color_lut_extract(color->red, 10));
1741 }
1742 
1743 static void chv_cgm_gamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw)
1744 {
1745 	entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_GREEN_LDW_MASK, ldw), 10);
1746 	entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_BLUE_LDW_MASK, ldw), 10);
1747 	entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_RED_UDW_MASK, udw), 10);
1748 }
1749 
1750 static void chv_load_cgm_gamma(struct intel_crtc *crtc,
1751 			       const struct drm_property_blob *blob)
1752 {
1753 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1754 	const struct drm_color_lut *lut = blob->data;
1755 	int i, lut_size = drm_color_lut_size(blob);
1756 	enum pipe pipe = crtc->pipe;
1757 
1758 	for (i = 0; i < lut_size; i++) {
1759 		intel_de_write_fw(i915, CGM_PIPE_GAMMA(pipe, i, 0),
1760 				  chv_cgm_gamma_ldw(&lut[i]));
1761 		intel_de_write_fw(i915, CGM_PIPE_GAMMA(pipe, i, 1),
1762 				  chv_cgm_gamma_udw(&lut[i]));
1763 	}
1764 }
1765 
1766 static void chv_load_luts(const struct intel_crtc_state *crtc_state)
1767 {
1768 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1769 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1770 	const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut;
1771 	const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut;
1772 
1773 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC)
1774 		chv_load_cgm_csc(crtc, &crtc_state->csc);
1775 
1776 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
1777 		chv_load_cgm_degamma(crtc, pre_csc_lut);
1778 
1779 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
1780 		chv_load_cgm_gamma(crtc, post_csc_lut);
1781 	else
1782 		i965_load_luts(crtc_state);
1783 
1784 	intel_de_write_fw(i915, CGM_PIPE_MODE(crtc->pipe),
1785 			  crtc_state->cgm_mode);
1786 }
1787 
1788 void intel_color_load_luts(const struct intel_crtc_state *crtc_state)
1789 {
1790 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1791 
1792 	i915->display.funcs.color->load_luts(crtc_state);
1793 }
1794 
1795 void intel_color_commit_noarm(const struct intel_crtc_state *crtc_state)
1796 {
1797 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1798 
1799 	if (i915->display.funcs.color->color_commit_noarm)
1800 		i915->display.funcs.color->color_commit_noarm(crtc_state);
1801 }
1802 
1803 void intel_color_commit_arm(const struct intel_crtc_state *crtc_state)
1804 {
1805 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1806 
1807 	i915->display.funcs.color->color_commit_arm(crtc_state);
1808 }
1809 
1810 void intel_color_post_update(const struct intel_crtc_state *crtc_state)
1811 {
1812 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1813 
1814 	if (i915->display.funcs.color->color_post_update)
1815 		i915->display.funcs.color->color_post_update(crtc_state);
1816 }
1817 
1818 void intel_color_prepare_commit(struct intel_crtc_state *crtc_state)
1819 {
1820 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1821 
1822 	/* FIXME DSB has issues loading LUTs, disable it for now */
1823 	return;
1824 
1825 	if (!crtc_state->pre_csc_lut && !crtc_state->post_csc_lut)
1826 		return;
1827 
1828 	crtc_state->dsb = intel_dsb_prepare(crtc, 1024);
1829 }
1830 
1831 void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state)
1832 {
1833 	if (!crtc_state->dsb)
1834 		return;
1835 
1836 	intel_dsb_cleanup(crtc_state->dsb);
1837 	crtc_state->dsb = NULL;
1838 }
1839 
1840 static bool intel_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1841 {
1842 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1843 	struct intel_atomic_state *state =
1844 		to_intel_atomic_state(new_crtc_state->uapi.state);
1845 	const struct intel_crtc_state *old_crtc_state =
1846 		intel_atomic_get_old_crtc_state(state, crtc);
1847 
1848 	return !old_crtc_state->post_csc_lut &&
1849 		!old_crtc_state->pre_csc_lut;
1850 }
1851 
1852 static bool vlv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1853 {
1854 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1855 	struct intel_atomic_state *state =
1856 		to_intel_atomic_state(new_crtc_state->uapi.state);
1857 	const struct intel_crtc_state *old_crtc_state =
1858 		intel_atomic_get_old_crtc_state(state, crtc);
1859 
1860 	return !old_crtc_state->wgc_enable &&
1861 		!old_crtc_state->post_csc_lut;
1862 }
1863 
1864 static bool chv_can_preload_luts(const struct intel_crtc_state *new_crtc_state)
1865 {
1866 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1867 	struct intel_atomic_state *state =
1868 		to_intel_atomic_state(new_crtc_state->uapi.state);
1869 	const struct intel_crtc_state *old_crtc_state =
1870 		intel_atomic_get_old_crtc_state(state, crtc);
1871 
1872 	/*
1873 	 * CGM_PIPE_MODE is itself single buffered. We'd have to
1874 	 * somehow split it out from chv_load_luts() if we wanted
1875 	 * the ability to preload the CGM LUTs/CSC without tearing.
1876 	 */
1877 	if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode)
1878 		return false;
1879 
1880 	return vlv_can_preload_luts(new_crtc_state);
1881 }
1882 
1883 int intel_color_check(struct intel_crtc_state *crtc_state)
1884 {
1885 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1886 
1887 	return i915->display.funcs.color->color_check(crtc_state);
1888 }
1889 
1890 void intel_color_get_config(struct intel_crtc_state *crtc_state)
1891 {
1892 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1893 
1894 	i915->display.funcs.color->read_luts(crtc_state);
1895 
1896 	if (i915->display.funcs.color->read_csc)
1897 		i915->display.funcs.color->read_csc(crtc_state);
1898 }
1899 
1900 bool intel_color_lut_equal(const struct intel_crtc_state *crtc_state,
1901 			   const struct drm_property_blob *blob1,
1902 			   const struct drm_property_blob *blob2,
1903 			   bool is_pre_csc_lut)
1904 {
1905 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1906 
1907 	/*
1908 	 * FIXME c8_planes readout missing thus
1909 	 * .read_luts() doesn't read out post_csc_lut.
1910 	 */
1911 	if (!is_pre_csc_lut && crtc_state->c8_planes)
1912 		return true;
1913 
1914 	return i915->display.funcs.color->lut_equal(crtc_state, blob1, blob2,
1915 						    is_pre_csc_lut);
1916 }
1917 
1918 static bool need_plane_update(struct intel_plane *plane,
1919 			      const struct intel_crtc_state *crtc_state)
1920 {
1921 	struct drm_i915_private *i915 = to_i915(plane->base.dev);
1922 
1923 	/*
1924 	 * On pre-SKL the pipe gamma enable and pipe csc enable for
1925 	 * the pipe bottom color are configured via the primary plane.
1926 	 * We have to reconfigure that even if the plane is inactive.
1927 	 */
1928 	return crtc_state->active_planes & BIT(plane->id) ||
1929 		(DISPLAY_VER(i915) < 9 &&
1930 		 plane->id == PLANE_PRIMARY);
1931 }
1932 
1933 static int
1934 intel_color_add_affected_planes(struct intel_crtc_state *new_crtc_state)
1935 {
1936 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
1937 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
1938 	struct intel_atomic_state *state =
1939 		to_intel_atomic_state(new_crtc_state->uapi.state);
1940 	const struct intel_crtc_state *old_crtc_state =
1941 		intel_atomic_get_old_crtc_state(state, crtc);
1942 	struct intel_plane *plane;
1943 
1944 	if (!new_crtc_state->hw.active ||
1945 	    intel_crtc_needs_modeset(new_crtc_state))
1946 		return 0;
1947 
1948 	if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable &&
1949 	    new_crtc_state->csc_enable == old_crtc_state->csc_enable)
1950 		return 0;
1951 
1952 	for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
1953 		struct intel_plane_state *plane_state;
1954 
1955 		if (!need_plane_update(plane, new_crtc_state))
1956 			continue;
1957 
1958 		plane_state = intel_atomic_get_plane_state(state, plane);
1959 		if (IS_ERR(plane_state))
1960 			return PTR_ERR(plane_state);
1961 
1962 		new_crtc_state->update_planes |= BIT(plane->id);
1963 		new_crtc_state->async_flip_planes = 0;
1964 		new_crtc_state->do_async_flip = false;
1965 
1966 		/* plane control register changes blocked by CxSR */
1967 		if (HAS_GMCH(i915))
1968 			new_crtc_state->disable_cxsr = true;
1969 	}
1970 
1971 	return 0;
1972 }
1973 
1974 static u32 intel_gamma_lut_tests(const struct intel_crtc_state *crtc_state)
1975 {
1976 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1977 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1978 
1979 	if (lut_is_legacy(gamma_lut))
1980 		return 0;
1981 
1982 	return DISPLAY_INFO(i915)->color.gamma_lut_tests;
1983 }
1984 
1985 static u32 intel_degamma_lut_tests(const struct intel_crtc_state *crtc_state)
1986 {
1987 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1988 
1989 	return DISPLAY_INFO(i915)->color.degamma_lut_tests;
1990 }
1991 
1992 static int intel_gamma_lut_size(const struct intel_crtc_state *crtc_state)
1993 {
1994 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
1995 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
1996 
1997 	if (lut_is_legacy(gamma_lut))
1998 		return LEGACY_LUT_LENGTH;
1999 
2000 	return DISPLAY_INFO(i915)->color.gamma_lut_size;
2001 }
2002 
2003 static u32 intel_degamma_lut_size(const struct intel_crtc_state *crtc_state)
2004 {
2005 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2006 
2007 	return DISPLAY_INFO(i915)->color.degamma_lut_size;
2008 }
2009 
2010 static int check_lut_size(const struct drm_property_blob *lut, int expected)
2011 {
2012 	int len;
2013 
2014 	if (!lut)
2015 		return 0;
2016 
2017 	len = drm_color_lut_size(lut);
2018 	if (len != expected) {
2019 		DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
2020 			      len, expected);
2021 		return -EINVAL;
2022 	}
2023 
2024 	return 0;
2025 }
2026 
2027 static int _check_luts(const struct intel_crtc_state *crtc_state,
2028 		       u32 degamma_tests, u32 gamma_tests)
2029 {
2030 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2031 	const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut;
2032 	const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut;
2033 	int gamma_length, degamma_length;
2034 
2035 	/* C8 relies on its palette being stored in the legacy LUT */
2036 	if (crtc_state->c8_planes && !lut_is_legacy(crtc_state->hw.gamma_lut)) {
2037 		drm_dbg_kms(&i915->drm,
2038 			    "C8 pixelformat requires the legacy LUT\n");
2039 		return -EINVAL;
2040 	}
2041 
2042 	degamma_length = intel_degamma_lut_size(crtc_state);
2043 	gamma_length = intel_gamma_lut_size(crtc_state);
2044 
2045 	if (check_lut_size(degamma_lut, degamma_length) ||
2046 	    check_lut_size(gamma_lut, gamma_length))
2047 		return -EINVAL;
2048 
2049 	if (drm_color_lut_check(degamma_lut, degamma_tests) ||
2050 	    drm_color_lut_check(gamma_lut, gamma_tests))
2051 		return -EINVAL;
2052 
2053 	return 0;
2054 }
2055 
2056 static int check_luts(const struct intel_crtc_state *crtc_state)
2057 {
2058 	return _check_luts(crtc_state,
2059 			   intel_degamma_lut_tests(crtc_state),
2060 			   intel_gamma_lut_tests(crtc_state));
2061 }
2062 
2063 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state)
2064 {
2065 	if (!crtc_state->gamma_enable ||
2066 	    lut_is_legacy(crtc_state->hw.gamma_lut))
2067 		return GAMMA_MODE_MODE_8BIT;
2068 	else
2069 		return GAMMA_MODE_MODE_10BIT;
2070 }
2071 
2072 static int i9xx_lut_10_diff(u16 a, u16 b)
2073 {
2074 	return drm_color_lut_extract(a, 10) -
2075 		drm_color_lut_extract(b, 10);
2076 }
2077 
2078 static int i9xx_check_lut_10(struct drm_i915_private *dev_priv,
2079 			     const struct drm_property_blob *blob)
2080 {
2081 	const struct drm_color_lut *lut = blob->data;
2082 	int lut_size = drm_color_lut_size(blob);
2083 	const struct drm_color_lut *a = &lut[lut_size - 2];
2084 	const struct drm_color_lut *b = &lut[lut_size - 1];
2085 
2086 	if (i9xx_lut_10_diff(b->red, a->red) > 0x7f ||
2087 	    i9xx_lut_10_diff(b->green, a->green) > 0x7f ||
2088 	    i9xx_lut_10_diff(b->blue, a->blue) > 0x7f) {
2089 		drm_dbg_kms(&dev_priv->drm, "Last gamma LUT entry exceeds max slope\n");
2090 		return -EINVAL;
2091 	}
2092 
2093 	return 0;
2094 }
2095 
2096 void intel_color_assert_luts(const struct intel_crtc_state *crtc_state)
2097 {
2098 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2099 
2100 	/* make sure {pre,post}_csc_lut were correctly assigned */
2101 	if (DISPLAY_VER(i915) >= 11 || HAS_GMCH(i915)) {
2102 		drm_WARN_ON(&i915->drm,
2103 			    crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut);
2104 		drm_WARN_ON(&i915->drm,
2105 			    crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2106 	} else if (DISPLAY_VER(i915) == 10) {
2107 		drm_WARN_ON(&i915->drm,
2108 			    crtc_state->post_csc_lut == crtc_state->hw.gamma_lut &&
2109 			    crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
2110 			    crtc_state->pre_csc_lut != i915->display.color.glk_linear_degamma_lut);
2111 		drm_WARN_ON(&i915->drm,
2112 			    !ilk_lut_limited_range(crtc_state) &&
2113 			    crtc_state->post_csc_lut != NULL &&
2114 			    crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2115 	} else if (crtc_state->gamma_mode != GAMMA_MODE_MODE_SPLIT) {
2116 		drm_WARN_ON(&i915->drm,
2117 			    crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut &&
2118 			    crtc_state->pre_csc_lut != crtc_state->hw.gamma_lut);
2119 		drm_WARN_ON(&i915->drm,
2120 			    !ilk_lut_limited_range(crtc_state) &&
2121 			    crtc_state->post_csc_lut != crtc_state->hw.degamma_lut &&
2122 			    crtc_state->post_csc_lut != crtc_state->hw.gamma_lut);
2123 	}
2124 }
2125 
2126 static void intel_assign_luts(struct intel_crtc_state *crtc_state)
2127 {
2128 	drm_property_replace_blob(&crtc_state->pre_csc_lut,
2129 				  crtc_state->hw.degamma_lut);
2130 	drm_property_replace_blob(&crtc_state->post_csc_lut,
2131 				  crtc_state->hw.gamma_lut);
2132 }
2133 
2134 static int i9xx_color_check(struct intel_crtc_state *crtc_state)
2135 {
2136 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2137 	int ret;
2138 
2139 	ret = check_luts(crtc_state);
2140 	if (ret)
2141 		return ret;
2142 
2143 	crtc_state->gamma_enable =
2144 		crtc_state->hw.gamma_lut &&
2145 		!crtc_state->c8_planes;
2146 
2147 	crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
2148 
2149 	if (DISPLAY_VER(i915) < 4 &&
2150 	    crtc_state->gamma_mode == GAMMA_MODE_MODE_10BIT) {
2151 		ret = i9xx_check_lut_10(i915, crtc_state->hw.gamma_lut);
2152 		if (ret)
2153 			return ret;
2154 	}
2155 
2156 	ret = intel_color_add_affected_planes(crtc_state);
2157 	if (ret)
2158 		return ret;
2159 
2160 	intel_assign_luts(crtc_state);
2161 
2162 	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2163 
2164 	return 0;
2165 }
2166 
2167 /*
2168  * VLV color pipeline:
2169  * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
2170  */
2171 static int vlv_color_check(struct intel_crtc_state *crtc_state)
2172 {
2173 	int ret;
2174 
2175 	ret = check_luts(crtc_state);
2176 	if (ret)
2177 		return ret;
2178 
2179 	crtc_state->gamma_enable =
2180 		crtc_state->hw.gamma_lut &&
2181 		!crtc_state->c8_planes;
2182 
2183 	crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state);
2184 
2185 	crtc_state->wgc_enable = crtc_state->hw.ctm;
2186 
2187 	ret = intel_color_add_affected_planes(crtc_state);
2188 	if (ret)
2189 		return ret;
2190 
2191 	intel_assign_luts(crtc_state);
2192 
2193 	vlv_assign_csc(crtc_state);
2194 
2195 	crtc_state->preload_luts = vlv_can_preload_luts(crtc_state);
2196 
2197 	return 0;
2198 }
2199 
2200 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state)
2201 {
2202 	u32 cgm_mode = 0;
2203 
2204 	if (crtc_state->hw.degamma_lut)
2205 		cgm_mode |= CGM_PIPE_MODE_DEGAMMA;
2206 	if (crtc_state->hw.ctm)
2207 		cgm_mode |= CGM_PIPE_MODE_CSC;
2208 	if (crtc_state->hw.gamma_lut &&
2209 	    !lut_is_legacy(crtc_state->hw.gamma_lut))
2210 		cgm_mode |= CGM_PIPE_MODE_GAMMA;
2211 
2212 	/*
2213 	 * Toggling the CGM CSC on/off outside of the tiny window
2214 	 * between start of vblank and frame start causes underruns.
2215 	 * Always enable the CGM CSC as a workaround.
2216 	 */
2217 	cgm_mode |= CGM_PIPE_MODE_CSC;
2218 
2219 	return cgm_mode;
2220 }
2221 
2222 /*
2223  * CHV color pipeline:
2224  * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
2225  * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
2226  *
2227  * We always bypass the WGC csc and use the CGM csc
2228  * instead since it has degamma and better precision.
2229  */
2230 static int chv_color_check(struct intel_crtc_state *crtc_state)
2231 {
2232 	int ret;
2233 
2234 	ret = check_luts(crtc_state);
2235 	if (ret)
2236 		return ret;
2237 
2238 	/*
2239 	 * Pipe gamma will be used only for the legacy LUT.
2240 	 * Otherwise we bypass it and use the CGM gamma instead.
2241 	 */
2242 	crtc_state->gamma_enable =
2243 		lut_is_legacy(crtc_state->hw.gamma_lut) &&
2244 		!crtc_state->c8_planes;
2245 
2246 	crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT;
2247 
2248 	crtc_state->cgm_mode = chv_cgm_mode(crtc_state);
2249 
2250 	/*
2251 	 * We always bypass the WGC CSC and use the CGM CSC
2252 	 * instead since it has degamma and better precision.
2253 	 */
2254 	crtc_state->wgc_enable = false;
2255 
2256 	ret = intel_color_add_affected_planes(crtc_state);
2257 	if (ret)
2258 		return ret;
2259 
2260 	intel_assign_luts(crtc_state);
2261 
2262 	chv_assign_csc(crtc_state);
2263 
2264 	crtc_state->preload_luts = chv_can_preload_luts(crtc_state);
2265 
2266 	return 0;
2267 }
2268 
2269 static bool ilk_gamma_enable(const struct intel_crtc_state *crtc_state)
2270 {
2271 	return (crtc_state->hw.gamma_lut ||
2272 		crtc_state->hw.degamma_lut) &&
2273 		!crtc_state->c8_planes;
2274 }
2275 
2276 static bool ilk_csc_enable(const struct intel_crtc_state *crtc_state)
2277 {
2278 	return crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2279 		ilk_csc_limited_range(crtc_state) ||
2280 		crtc_state->hw.ctm;
2281 }
2282 
2283 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state)
2284 {
2285 	if (!crtc_state->gamma_enable ||
2286 	    lut_is_legacy(crtc_state->hw.gamma_lut))
2287 		return GAMMA_MODE_MODE_8BIT;
2288 	else
2289 		return GAMMA_MODE_MODE_10BIT;
2290 }
2291 
2292 static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state)
2293 {
2294 	/*
2295 	 * CSC comes after the LUT in RGB->YCbCr mode.
2296 	 * RGB->YCbCr needs the limited range offsets added to
2297 	 * the output. RGB limited range output is handled by
2298 	 * the hw automagically elsewhere.
2299 	 */
2300 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
2301 		return CSC_BLACK_SCREEN_OFFSET;
2302 
2303 	if (crtc_state->hw.degamma_lut)
2304 		return CSC_MODE_YUV_TO_RGB;
2305 
2306 	return CSC_MODE_YUV_TO_RGB |
2307 		CSC_POSITION_BEFORE_GAMMA;
2308 }
2309 
2310 static int ilk_assign_luts(struct intel_crtc_state *crtc_state)
2311 {
2312 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2313 
2314 	if (ilk_lut_limited_range(crtc_state)) {
2315 		struct drm_property_blob *gamma_lut;
2316 
2317 		gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut,
2318 					       drm_color_lut_size(crtc_state->hw.gamma_lut),
2319 					       true);
2320 		if (IS_ERR(gamma_lut))
2321 			return PTR_ERR(gamma_lut);
2322 
2323 		drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2324 
2325 		drm_property_blob_put(gamma_lut);
2326 
2327 		drm_property_replace_blob(&crtc_state->pre_csc_lut, crtc_state->hw.degamma_lut);
2328 
2329 		return 0;
2330 	}
2331 
2332 	if (crtc_state->hw.degamma_lut ||
2333 	    crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) {
2334 		drm_property_replace_blob(&crtc_state->pre_csc_lut,
2335 					  crtc_state->hw.degamma_lut);
2336 		drm_property_replace_blob(&crtc_state->post_csc_lut,
2337 					  crtc_state->hw.gamma_lut);
2338 	} else {
2339 		drm_property_replace_blob(&crtc_state->pre_csc_lut,
2340 					  crtc_state->hw.gamma_lut);
2341 		drm_property_replace_blob(&crtc_state->post_csc_lut,
2342 					  NULL);
2343 	}
2344 
2345 	return 0;
2346 }
2347 
2348 static int ilk_color_check(struct intel_crtc_state *crtc_state)
2349 {
2350 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2351 	int ret;
2352 
2353 	ret = check_luts(crtc_state);
2354 	if (ret)
2355 		return ret;
2356 
2357 	if (crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2358 		drm_dbg_kms(&i915->drm,
2359 			    "Degamma and gamma together are not possible\n");
2360 		return -EINVAL;
2361 	}
2362 
2363 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2364 	    crtc_state->hw.ctm) {
2365 		drm_dbg_kms(&i915->drm,
2366 			    "YCbCr and CTM together are not possible\n");
2367 		return -EINVAL;
2368 	}
2369 
2370 	crtc_state->gamma_enable = ilk_gamma_enable(crtc_state);
2371 
2372 	crtc_state->csc_enable = ilk_csc_enable(crtc_state);
2373 
2374 	crtc_state->gamma_mode = ilk_gamma_mode(crtc_state);
2375 
2376 	crtc_state->csc_mode = ilk_csc_mode(crtc_state);
2377 
2378 	ret = intel_color_add_affected_planes(crtc_state);
2379 	if (ret)
2380 		return ret;
2381 
2382 	ret = ilk_assign_luts(crtc_state);
2383 	if (ret)
2384 		return ret;
2385 
2386 	ilk_assign_csc(crtc_state);
2387 
2388 	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2389 
2390 	return 0;
2391 }
2392 
2393 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state)
2394 {
2395 	if (crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut)
2396 		return GAMMA_MODE_MODE_SPLIT;
2397 
2398 	return ilk_gamma_mode(crtc_state);
2399 }
2400 
2401 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state)
2402 {
2403 	bool limited_color_range = ilk_csc_limited_range(crtc_state);
2404 
2405 	/*
2406 	 * CSC comes after the LUT in degamma, RGB->YCbCr,
2407 	 * and RGB full->limited range mode.
2408 	 */
2409 	if (crtc_state->hw.degamma_lut ||
2410 	    crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2411 	    limited_color_range)
2412 		return 0;
2413 
2414 	return CSC_POSITION_BEFORE_GAMMA;
2415 }
2416 
2417 static int ivb_assign_luts(struct intel_crtc_state *crtc_state)
2418 {
2419 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2420 	struct drm_property_blob *degamma_lut, *gamma_lut;
2421 
2422 	if (crtc_state->gamma_mode != GAMMA_MODE_MODE_SPLIT)
2423 		return ilk_assign_luts(crtc_state);
2424 
2425 	drm_WARN_ON(&i915->drm, drm_color_lut_size(crtc_state->hw.degamma_lut) != 1024);
2426 	drm_WARN_ON(&i915->drm, drm_color_lut_size(crtc_state->hw.gamma_lut) != 1024);
2427 
2428 	degamma_lut = create_resized_lut(i915, crtc_state->hw.degamma_lut, 512,
2429 					 false);
2430 	if (IS_ERR(degamma_lut))
2431 		return PTR_ERR(degamma_lut);
2432 
2433 	gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut, 512,
2434 				       ilk_lut_limited_range(crtc_state));
2435 	if (IS_ERR(gamma_lut)) {
2436 		drm_property_blob_put(degamma_lut);
2437 		return PTR_ERR(gamma_lut);
2438 	}
2439 
2440 	drm_property_replace_blob(&crtc_state->pre_csc_lut, degamma_lut);
2441 	drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2442 
2443 	drm_property_blob_put(degamma_lut);
2444 	drm_property_blob_put(gamma_lut);
2445 
2446 	return 0;
2447 }
2448 
2449 static int ivb_color_check(struct intel_crtc_state *crtc_state)
2450 {
2451 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2452 	int ret;
2453 
2454 	ret = check_luts(crtc_state);
2455 	if (ret)
2456 		return ret;
2457 
2458 	if (crtc_state->c8_planes && crtc_state->hw.degamma_lut) {
2459 		drm_dbg_kms(&i915->drm,
2460 			    "C8 pixelformat and degamma together are not possible\n");
2461 		return -EINVAL;
2462 	}
2463 
2464 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2465 	    crtc_state->hw.ctm) {
2466 		drm_dbg_kms(&i915->drm,
2467 			    "YCbCr and CTM together are not possible\n");
2468 		return -EINVAL;
2469 	}
2470 
2471 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2472 	    crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2473 		drm_dbg_kms(&i915->drm,
2474 			    "YCbCr and degamma+gamma together are not possible\n");
2475 		return -EINVAL;
2476 	}
2477 
2478 	crtc_state->gamma_enable = ilk_gamma_enable(crtc_state);
2479 
2480 	crtc_state->csc_enable = ilk_csc_enable(crtc_state);
2481 
2482 	crtc_state->gamma_mode = ivb_gamma_mode(crtc_state);
2483 
2484 	crtc_state->csc_mode = ivb_csc_mode(crtc_state);
2485 
2486 	ret = intel_color_add_affected_planes(crtc_state);
2487 	if (ret)
2488 		return ret;
2489 
2490 	ret = ivb_assign_luts(crtc_state);
2491 	if (ret)
2492 		return ret;
2493 
2494 	ilk_assign_csc(crtc_state);
2495 
2496 	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2497 
2498 	return 0;
2499 }
2500 
2501 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state)
2502 {
2503 	if (!crtc_state->gamma_enable ||
2504 	    lut_is_legacy(crtc_state->hw.gamma_lut))
2505 		return GAMMA_MODE_MODE_8BIT;
2506 	else
2507 		return GAMMA_MODE_MODE_10BIT;
2508 }
2509 
2510 static bool glk_use_pre_csc_lut_for_gamma(const struct intel_crtc_state *crtc_state)
2511 {
2512 	return crtc_state->hw.gamma_lut &&
2513 		!crtc_state->c8_planes &&
2514 		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB;
2515 }
2516 
2517 static int glk_assign_luts(struct intel_crtc_state *crtc_state)
2518 {
2519 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2520 
2521 	if (glk_use_pre_csc_lut_for_gamma(crtc_state)) {
2522 		struct drm_property_blob *gamma_lut;
2523 
2524 		gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut,
2525 					       DISPLAY_INFO(i915)->color.degamma_lut_size,
2526 					       false);
2527 		if (IS_ERR(gamma_lut))
2528 			return PTR_ERR(gamma_lut);
2529 
2530 		drm_property_replace_blob(&crtc_state->pre_csc_lut, gamma_lut);
2531 		drm_property_replace_blob(&crtc_state->post_csc_lut, NULL);
2532 
2533 		drm_property_blob_put(gamma_lut);
2534 
2535 		return 0;
2536 	}
2537 
2538 	if (ilk_lut_limited_range(crtc_state)) {
2539 		struct drm_property_blob *gamma_lut;
2540 
2541 		gamma_lut = create_resized_lut(i915, crtc_state->hw.gamma_lut,
2542 					       drm_color_lut_size(crtc_state->hw.gamma_lut),
2543 					       true);
2544 		if (IS_ERR(gamma_lut))
2545 			return PTR_ERR(gamma_lut);
2546 
2547 		drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut);
2548 
2549 		drm_property_blob_put(gamma_lut);
2550 	} else {
2551 		drm_property_replace_blob(&crtc_state->post_csc_lut, crtc_state->hw.gamma_lut);
2552 	}
2553 
2554 	drm_property_replace_blob(&crtc_state->pre_csc_lut, crtc_state->hw.degamma_lut);
2555 
2556 	/*
2557 	 * On GLK+ both pipe CSC and degamma LUT are controlled
2558 	 * by csc_enable. Hence for the cases where the CSC is
2559 	 * needed but degamma LUT is not we need to load a
2560 	 * linear degamma LUT.
2561 	 */
2562 	if (crtc_state->csc_enable && !crtc_state->pre_csc_lut)
2563 		drm_property_replace_blob(&crtc_state->pre_csc_lut,
2564 					  i915->display.color.glk_linear_degamma_lut);
2565 
2566 	return 0;
2567 }
2568 
2569 static int glk_check_luts(const struct intel_crtc_state *crtc_state)
2570 {
2571 	u32 degamma_tests = intel_degamma_lut_tests(crtc_state);
2572 	u32 gamma_tests = intel_gamma_lut_tests(crtc_state);
2573 
2574 	if (glk_use_pre_csc_lut_for_gamma(crtc_state))
2575 		gamma_tests |= degamma_tests;
2576 
2577 	return _check_luts(crtc_state, degamma_tests, gamma_tests);
2578 }
2579 
2580 static int glk_color_check(struct intel_crtc_state *crtc_state)
2581 {
2582 	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
2583 	int ret;
2584 
2585 	ret = glk_check_luts(crtc_state);
2586 	if (ret)
2587 		return ret;
2588 
2589 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2590 	    crtc_state->hw.ctm) {
2591 		drm_dbg_kms(&i915->drm,
2592 			    "YCbCr and CTM together are not possible\n");
2593 		return -EINVAL;
2594 	}
2595 
2596 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB &&
2597 	    crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) {
2598 		drm_dbg_kms(&i915->drm,
2599 			    "YCbCr and degamma+gamma together are not possible\n");
2600 		return -EINVAL;
2601 	}
2602 
2603 	crtc_state->gamma_enable =
2604 		!glk_use_pre_csc_lut_for_gamma(crtc_state) &&
2605 		crtc_state->hw.gamma_lut &&
2606 		!crtc_state->c8_planes;
2607 
2608 	/* On GLK+ degamma LUT is controlled by csc_enable */
2609 	crtc_state->csc_enable =
2610 		glk_use_pre_csc_lut_for_gamma(crtc_state) ||
2611 		crtc_state->hw.degamma_lut ||
2612 		crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2613 		crtc_state->hw.ctm || ilk_csc_limited_range(crtc_state);
2614 
2615 	crtc_state->gamma_mode = glk_gamma_mode(crtc_state);
2616 
2617 	crtc_state->csc_mode = 0;
2618 
2619 	ret = intel_color_add_affected_planes(crtc_state);
2620 	if (ret)
2621 		return ret;
2622 
2623 	ret = glk_assign_luts(crtc_state);
2624 	if (ret)
2625 		return ret;
2626 
2627 	ilk_assign_csc(crtc_state);
2628 
2629 	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2630 
2631 	return 0;
2632 }
2633 
2634 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state)
2635 {
2636 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
2637 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
2638 	u32 gamma_mode = 0;
2639 
2640 	if (crtc_state->hw.degamma_lut)
2641 		gamma_mode |= PRE_CSC_GAMMA_ENABLE;
2642 
2643 	if (crtc_state->hw.gamma_lut &&
2644 	    !crtc_state->c8_planes)
2645 		gamma_mode |= POST_CSC_GAMMA_ENABLE;
2646 
2647 	if (!crtc_state->hw.gamma_lut ||
2648 	    lut_is_legacy(crtc_state->hw.gamma_lut))
2649 		gamma_mode |= GAMMA_MODE_MODE_8BIT;
2650 	/*
2651 	 * Enable 10bit gamma for D13
2652 	 * ToDo: Extend to Logarithmic Gamma once the new UAPI
2653 	 * is accepted and implemented by a userspace consumer
2654 	 */
2655 	else if (DISPLAY_VER(i915) >= 13)
2656 		gamma_mode |= GAMMA_MODE_MODE_10BIT;
2657 	else
2658 		gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEG;
2659 
2660 	return gamma_mode;
2661 }
2662 
2663 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state)
2664 {
2665 	u32 csc_mode = 0;
2666 
2667 	if (crtc_state->hw.ctm)
2668 		csc_mode |= ICL_CSC_ENABLE;
2669 
2670 	if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB ||
2671 	    crtc_state->limited_color_range)
2672 		csc_mode |= ICL_OUTPUT_CSC_ENABLE;
2673 
2674 	return csc_mode;
2675 }
2676 
2677 static int icl_color_check(struct intel_crtc_state *crtc_state)
2678 {
2679 	int ret;
2680 
2681 	ret = check_luts(crtc_state);
2682 	if (ret)
2683 		return ret;
2684 
2685 	crtc_state->gamma_mode = icl_gamma_mode(crtc_state);
2686 
2687 	crtc_state->csc_mode = icl_csc_mode(crtc_state);
2688 
2689 	intel_assign_luts(crtc_state);
2690 
2691 	icl_assign_csc(crtc_state);
2692 
2693 	crtc_state->preload_luts = intel_can_preload_luts(crtc_state);
2694 
2695 	return 0;
2696 }
2697 
2698 static int i9xx_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2699 {
2700 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2701 		return 0;
2702 
2703 	switch (crtc_state->gamma_mode) {
2704 	case GAMMA_MODE_MODE_8BIT:
2705 		return 8;
2706 	case GAMMA_MODE_MODE_10BIT:
2707 		return 10;
2708 	default:
2709 		MISSING_CASE(crtc_state->gamma_mode);
2710 		return 0;
2711 	}
2712 }
2713 
2714 static int i9xx_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2715 {
2716 	return 0;
2717 }
2718 
2719 static int i965_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2720 {
2721 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2722 		return 0;
2723 
2724 	switch (crtc_state->gamma_mode) {
2725 	case GAMMA_MODE_MODE_8BIT:
2726 		return 8;
2727 	case GAMMA_MODE_MODE_10BIT:
2728 		return 16;
2729 	default:
2730 		MISSING_CASE(crtc_state->gamma_mode);
2731 		return 0;
2732 	}
2733 }
2734 
2735 static int ilk_gamma_mode_precision(u32 gamma_mode)
2736 {
2737 	switch (gamma_mode) {
2738 	case GAMMA_MODE_MODE_8BIT:
2739 		return 8;
2740 	case GAMMA_MODE_MODE_10BIT:
2741 		return 10;
2742 	default:
2743 		MISSING_CASE(gamma_mode);
2744 		return 0;
2745 	}
2746 }
2747 
2748 static bool ilk_has_post_csc_lut(const struct intel_crtc_state *crtc_state)
2749 {
2750 	if (crtc_state->c8_planes)
2751 		return true;
2752 
2753 	return crtc_state->gamma_enable &&
2754 		(crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) != 0;
2755 }
2756 
2757 static bool ilk_has_pre_csc_lut(const struct intel_crtc_state *crtc_state)
2758 {
2759 	return crtc_state->gamma_enable &&
2760 		(crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0;
2761 }
2762 
2763 static int ilk_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2764 {
2765 	if (!ilk_has_post_csc_lut(crtc_state))
2766 		return 0;
2767 
2768 	return ilk_gamma_mode_precision(crtc_state->gamma_mode);
2769 }
2770 
2771 static int ilk_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2772 {
2773 	if (!ilk_has_pre_csc_lut(crtc_state))
2774 		return 0;
2775 
2776 	return ilk_gamma_mode_precision(crtc_state->gamma_mode);
2777 }
2778 
2779 static int ivb_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2780 {
2781 	if (crtc_state->gamma_enable &&
2782 	    crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
2783 		return 10;
2784 
2785 	return ilk_post_csc_lut_precision(crtc_state);
2786 }
2787 
2788 static int ivb_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2789 {
2790 	if (crtc_state->gamma_enable &&
2791 	    crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT)
2792 		return 10;
2793 
2794 	return ilk_pre_csc_lut_precision(crtc_state);
2795 }
2796 
2797 static int chv_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2798 {
2799 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
2800 		return 10;
2801 
2802 	return i965_post_csc_lut_precision(crtc_state);
2803 }
2804 
2805 static int chv_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2806 {
2807 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
2808 		return 14;
2809 
2810 	return 0;
2811 }
2812 
2813 static int glk_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2814 {
2815 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
2816 		return 0;
2817 
2818 	return ilk_gamma_mode_precision(crtc_state->gamma_mode);
2819 }
2820 
2821 static int glk_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2822 {
2823 	if (!crtc_state->csc_enable)
2824 		return 0;
2825 
2826 	return 16;
2827 }
2828 
2829 static bool icl_has_post_csc_lut(const struct intel_crtc_state *crtc_state)
2830 {
2831 	if (crtc_state->c8_planes)
2832 		return true;
2833 
2834 	return crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE;
2835 }
2836 
2837 static bool icl_has_pre_csc_lut(const struct intel_crtc_state *crtc_state)
2838 {
2839 	return crtc_state->gamma_mode & PRE_CSC_GAMMA_ENABLE;
2840 }
2841 
2842 static int icl_post_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2843 {
2844 	if (!icl_has_post_csc_lut(crtc_state))
2845 		return 0;
2846 
2847 	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
2848 	case GAMMA_MODE_MODE_8BIT:
2849 		return 8;
2850 	case GAMMA_MODE_MODE_10BIT:
2851 		return 10;
2852 	case GAMMA_MODE_MODE_12BIT_MULTI_SEG:
2853 		return 16;
2854 	default:
2855 		MISSING_CASE(crtc_state->gamma_mode);
2856 		return 0;
2857 	}
2858 }
2859 
2860 static int icl_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state)
2861 {
2862 	if (!icl_has_pre_csc_lut(crtc_state))
2863 		return 0;
2864 
2865 	return 16;
2866 }
2867 
2868 static bool err_check(struct drm_color_lut *lut1,
2869 		      struct drm_color_lut *lut2, u32 err)
2870 {
2871 	return ((abs((long)lut2->red - lut1->red)) <= err) &&
2872 		((abs((long)lut2->blue - lut1->blue)) <= err) &&
2873 		((abs((long)lut2->green - lut1->green)) <= err);
2874 }
2875 
2876 static bool intel_lut_entries_equal(struct drm_color_lut *lut1,
2877 				    struct drm_color_lut *lut2,
2878 				    int lut_size, u32 err)
2879 {
2880 	int i;
2881 
2882 	for (i = 0; i < lut_size; i++) {
2883 		if (!err_check(&lut1[i], &lut2[i], err))
2884 			return false;
2885 	}
2886 
2887 	return true;
2888 }
2889 
2890 static bool intel_lut_equal(const struct drm_property_blob *blob1,
2891 			    const struct drm_property_blob *blob2,
2892 			    int check_size, int precision)
2893 {
2894 	struct drm_color_lut *lut1, *lut2;
2895 	int lut_size1, lut_size2;
2896 	u32 err;
2897 
2898 	if (!blob1 != !blob2)
2899 		return false;
2900 
2901 	if (!blob1 != !precision)
2902 		return false;
2903 
2904 	if (!blob1)
2905 		return true;
2906 
2907 	lut_size1 = drm_color_lut_size(blob1);
2908 	lut_size2 = drm_color_lut_size(blob2);
2909 
2910 	if (lut_size1 != lut_size2)
2911 		return false;
2912 
2913 	if (check_size > lut_size1)
2914 		return false;
2915 
2916 	lut1 = blob1->data;
2917 	lut2 = blob2->data;
2918 
2919 	err = 0xffff >> precision;
2920 
2921 	if (!check_size)
2922 		check_size = lut_size1;
2923 
2924 	return intel_lut_entries_equal(lut1, lut2, check_size, err);
2925 }
2926 
2927 static bool i9xx_lut_equal(const struct intel_crtc_state *crtc_state,
2928 			   const struct drm_property_blob *blob1,
2929 			   const struct drm_property_blob *blob2,
2930 			   bool is_pre_csc_lut)
2931 {
2932 	int check_size = 0;
2933 
2934 	if (is_pre_csc_lut)
2935 		return intel_lut_equal(blob1, blob2, 0,
2936 				       i9xx_pre_csc_lut_precision(crtc_state));
2937 
2938 	/* 10bit mode last entry is implicit, just skip it */
2939 	if (crtc_state->gamma_mode == GAMMA_MODE_MODE_10BIT)
2940 		check_size = 128;
2941 
2942 	return intel_lut_equal(blob1, blob2, check_size,
2943 			       i9xx_post_csc_lut_precision(crtc_state));
2944 }
2945 
2946 static bool i965_lut_equal(const struct intel_crtc_state *crtc_state,
2947 			   const struct drm_property_blob *blob1,
2948 			   const struct drm_property_blob *blob2,
2949 			   bool is_pre_csc_lut)
2950 {
2951 	if (is_pre_csc_lut)
2952 		return intel_lut_equal(blob1, blob2, 0,
2953 				       i9xx_pre_csc_lut_precision(crtc_state));
2954 	else
2955 		return intel_lut_equal(blob1, blob2, 0,
2956 				       i965_post_csc_lut_precision(crtc_state));
2957 }
2958 
2959 static bool chv_lut_equal(const struct intel_crtc_state *crtc_state,
2960 			  const struct drm_property_blob *blob1,
2961 			  const struct drm_property_blob *blob2,
2962 			  bool is_pre_csc_lut)
2963 {
2964 	if (is_pre_csc_lut)
2965 		return intel_lut_equal(blob1, blob2, 0,
2966 				       chv_pre_csc_lut_precision(crtc_state));
2967 	else
2968 		return intel_lut_equal(blob1, blob2, 0,
2969 				       chv_post_csc_lut_precision(crtc_state));
2970 }
2971 
2972 static bool ilk_lut_equal(const struct intel_crtc_state *crtc_state,
2973 			  const struct drm_property_blob *blob1,
2974 			  const struct drm_property_blob *blob2,
2975 			  bool is_pre_csc_lut)
2976 {
2977 	if (is_pre_csc_lut)
2978 		return intel_lut_equal(blob1, blob2, 0,
2979 				       ilk_pre_csc_lut_precision(crtc_state));
2980 	else
2981 		return intel_lut_equal(blob1, blob2, 0,
2982 				       ilk_post_csc_lut_precision(crtc_state));
2983 }
2984 
2985 static bool ivb_lut_equal(const struct intel_crtc_state *crtc_state,
2986 			  const struct drm_property_blob *blob1,
2987 			  const struct drm_property_blob *blob2,
2988 			  bool is_pre_csc_lut)
2989 {
2990 	if (is_pre_csc_lut)
2991 		return intel_lut_equal(blob1, blob2, 0,
2992 				       ivb_pre_csc_lut_precision(crtc_state));
2993 	else
2994 		return intel_lut_equal(blob1, blob2, 0,
2995 				       ivb_post_csc_lut_precision(crtc_state));
2996 }
2997 
2998 static bool glk_lut_equal(const struct intel_crtc_state *crtc_state,
2999 			  const struct drm_property_blob *blob1,
3000 			  const struct drm_property_blob *blob2,
3001 			  bool is_pre_csc_lut)
3002 {
3003 	if (is_pre_csc_lut)
3004 		return intel_lut_equal(blob1, blob2, 0,
3005 				       glk_pre_csc_lut_precision(crtc_state));
3006 	else
3007 		return intel_lut_equal(blob1, blob2, 0,
3008 				       glk_post_csc_lut_precision(crtc_state));
3009 }
3010 
3011 static bool icl_lut_equal(const struct intel_crtc_state *crtc_state,
3012 			  const struct drm_property_blob *blob1,
3013 			  const struct drm_property_blob *blob2,
3014 			  bool is_pre_csc_lut)
3015 {
3016 	int check_size = 0;
3017 
3018 	if (is_pre_csc_lut)
3019 		return intel_lut_equal(blob1, blob2, 0,
3020 				       icl_pre_csc_lut_precision(crtc_state));
3021 
3022 	/* hw readout broken except for the super fine segment :( */
3023 	if ((crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) ==
3024 	    GAMMA_MODE_MODE_12BIT_MULTI_SEG)
3025 		check_size = 9;
3026 
3027 	return intel_lut_equal(blob1, blob2, check_size,
3028 			       icl_post_csc_lut_precision(crtc_state));
3029 }
3030 
3031 static struct drm_property_blob *i9xx_read_lut_8(struct intel_crtc *crtc)
3032 {
3033 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3034 	enum pipe pipe = crtc->pipe;
3035 	struct drm_property_blob *blob;
3036 	struct drm_color_lut *lut;
3037 	int i;
3038 
3039 	blob = drm_property_create_blob(&dev_priv->drm,
3040 					sizeof(lut[0]) * LEGACY_LUT_LENGTH,
3041 					NULL);
3042 	if (IS_ERR(blob))
3043 		return NULL;
3044 
3045 	lut = blob->data;
3046 
3047 	for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
3048 		u32 val = intel_de_read_fw(dev_priv, PALETTE(pipe, i));
3049 
3050 		i9xx_lut_8_pack(&lut[i], val);
3051 	}
3052 
3053 	return blob;
3054 }
3055 
3056 static struct drm_property_blob *i9xx_read_lut_10(struct intel_crtc *crtc)
3057 {
3058 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3059 	u32 lut_size = DISPLAY_INFO(dev_priv)->color.gamma_lut_size;
3060 	enum pipe pipe = crtc->pipe;
3061 	struct drm_property_blob *blob;
3062 	struct drm_color_lut *lut;
3063 	u32 ldw, udw;
3064 	int i;
3065 
3066 	blob = drm_property_create_blob(&dev_priv->drm,
3067 					lut_size * sizeof(lut[0]), NULL);
3068 	if (IS_ERR(blob))
3069 		return NULL;
3070 
3071 	lut = blob->data;
3072 
3073 	for (i = 0; i < lut_size - 1; i++) {
3074 		ldw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 0));
3075 		udw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 1));
3076 
3077 		i9xx_lut_10_pack(&lut[i], ldw, udw);
3078 	}
3079 
3080 	i9xx_lut_10_pack_slope(&lut[i], ldw, udw);
3081 
3082 	return blob;
3083 }
3084 
3085 static void i9xx_read_luts(struct intel_crtc_state *crtc_state)
3086 {
3087 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3088 
3089 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3090 		return;
3091 
3092 	switch (crtc_state->gamma_mode) {
3093 	case GAMMA_MODE_MODE_8BIT:
3094 		crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
3095 		break;
3096 	case GAMMA_MODE_MODE_10BIT:
3097 		crtc_state->post_csc_lut = i9xx_read_lut_10(crtc);
3098 		break;
3099 	default:
3100 		MISSING_CASE(crtc_state->gamma_mode);
3101 		break;
3102 	}
3103 }
3104 
3105 static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc)
3106 {
3107 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3108 	int i, lut_size = DISPLAY_INFO(dev_priv)->color.gamma_lut_size;
3109 	enum pipe pipe = crtc->pipe;
3110 	struct drm_property_blob *blob;
3111 	struct drm_color_lut *lut;
3112 
3113 	blob = drm_property_create_blob(&dev_priv->drm,
3114 					sizeof(lut[0]) * lut_size,
3115 					NULL);
3116 	if (IS_ERR(blob))
3117 		return NULL;
3118 
3119 	lut = blob->data;
3120 
3121 	for (i = 0; i < lut_size - 1; i++) {
3122 		u32 ldw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 0));
3123 		u32 udw = intel_de_read_fw(dev_priv, PALETTE(pipe, 2 * i + 1));
3124 
3125 		i965_lut_10p6_pack(&lut[i], ldw, udw);
3126 	}
3127 
3128 	lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 0)));
3129 	lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 1)));
3130 	lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(dev_priv, PIPEGCMAX(pipe, 2)));
3131 
3132 	return blob;
3133 }
3134 
3135 static void i965_read_luts(struct intel_crtc_state *crtc_state)
3136 {
3137 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3138 
3139 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3140 		return;
3141 
3142 	switch (crtc_state->gamma_mode) {
3143 	case GAMMA_MODE_MODE_8BIT:
3144 		crtc_state->post_csc_lut = i9xx_read_lut_8(crtc);
3145 		break;
3146 	case GAMMA_MODE_MODE_10BIT:
3147 		crtc_state->post_csc_lut = i965_read_lut_10p6(crtc);
3148 		break;
3149 	default:
3150 		MISSING_CASE(crtc_state->gamma_mode);
3151 		break;
3152 	}
3153 }
3154 
3155 static struct drm_property_blob *chv_read_cgm_degamma(struct intel_crtc *crtc)
3156 {
3157 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3158 	int i, lut_size = DISPLAY_INFO(dev_priv)->color.degamma_lut_size;
3159 	enum pipe pipe = crtc->pipe;
3160 	struct drm_property_blob *blob;
3161 	struct drm_color_lut *lut;
3162 
3163 	blob = drm_property_create_blob(&dev_priv->drm,
3164 					sizeof(lut[0]) * lut_size,
3165 					NULL);
3166 	if (IS_ERR(blob))
3167 		return NULL;
3168 
3169 	lut = blob->data;
3170 
3171 	for (i = 0; i < lut_size; i++) {
3172 		u32 ldw = intel_de_read_fw(dev_priv, CGM_PIPE_DEGAMMA(pipe, i, 0));
3173 		u32 udw = intel_de_read_fw(dev_priv, CGM_PIPE_DEGAMMA(pipe, i, 1));
3174 
3175 		chv_cgm_degamma_pack(&lut[i], ldw, udw);
3176 	}
3177 
3178 	return blob;
3179 }
3180 
3181 static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc)
3182 {
3183 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3184 	int i, lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3185 	enum pipe pipe = crtc->pipe;
3186 	struct drm_property_blob *blob;
3187 	struct drm_color_lut *lut;
3188 
3189 	blob = drm_property_create_blob(&i915->drm,
3190 					sizeof(lut[0]) * lut_size,
3191 					NULL);
3192 	if (IS_ERR(blob))
3193 		return NULL;
3194 
3195 	lut = blob->data;
3196 
3197 	for (i = 0; i < lut_size; i++) {
3198 		u32 ldw = intel_de_read_fw(i915, CGM_PIPE_GAMMA(pipe, i, 0));
3199 		u32 udw = intel_de_read_fw(i915, CGM_PIPE_GAMMA(pipe, i, 1));
3200 
3201 		chv_cgm_gamma_pack(&lut[i], ldw, udw);
3202 	}
3203 
3204 	return blob;
3205 }
3206 
3207 static void chv_read_luts(struct intel_crtc_state *crtc_state)
3208 {
3209 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3210 
3211 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA)
3212 		crtc_state->pre_csc_lut = chv_read_cgm_degamma(crtc);
3213 
3214 	if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA)
3215 		crtc_state->post_csc_lut = chv_read_cgm_gamma(crtc);
3216 	else
3217 		i965_read_luts(crtc_state);
3218 }
3219 
3220 static struct drm_property_blob *ilk_read_lut_8(struct intel_crtc *crtc)
3221 {
3222 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3223 	enum pipe pipe = crtc->pipe;
3224 	struct drm_property_blob *blob;
3225 	struct drm_color_lut *lut;
3226 	int i;
3227 
3228 	blob = drm_property_create_blob(&i915->drm,
3229 					sizeof(lut[0]) * LEGACY_LUT_LENGTH,
3230 					NULL);
3231 	if (IS_ERR(blob))
3232 		return NULL;
3233 
3234 	lut = blob->data;
3235 
3236 	for (i = 0; i < LEGACY_LUT_LENGTH; i++) {
3237 		u32 val = intel_de_read_fw(i915, LGC_PALETTE(pipe, i));
3238 
3239 		i9xx_lut_8_pack(&lut[i], val);
3240 	}
3241 
3242 	return blob;
3243 }
3244 
3245 static struct drm_property_blob *ilk_read_lut_10(struct intel_crtc *crtc)
3246 {
3247 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3248 	int i, lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3249 	enum pipe pipe = crtc->pipe;
3250 	struct drm_property_blob *blob;
3251 	struct drm_color_lut *lut;
3252 
3253 	blob = drm_property_create_blob(&i915->drm,
3254 					sizeof(lut[0]) * lut_size,
3255 					NULL);
3256 	if (IS_ERR(blob))
3257 		return NULL;
3258 
3259 	lut = blob->data;
3260 
3261 	for (i = 0; i < lut_size; i++) {
3262 		u32 val = intel_de_read_fw(i915, PREC_PALETTE(pipe, i));
3263 
3264 		ilk_lut_10_pack(&lut[i], val);
3265 	}
3266 
3267 	return blob;
3268 }
3269 
3270 static void ilk_read_luts(struct intel_crtc_state *crtc_state)
3271 {
3272 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3273 	struct drm_property_blob **blob =
3274 		ilk_has_post_csc_lut(crtc_state) ?
3275 		&crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3276 
3277 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3278 		return;
3279 
3280 	switch (crtc_state->gamma_mode) {
3281 	case GAMMA_MODE_MODE_8BIT:
3282 		*blob = ilk_read_lut_8(crtc);
3283 		break;
3284 	case GAMMA_MODE_MODE_10BIT:
3285 		*blob = ilk_read_lut_10(crtc);
3286 		break;
3287 	default:
3288 		MISSING_CASE(crtc_state->gamma_mode);
3289 		break;
3290 	}
3291 }
3292 
3293 /*
3294  * IVB/HSW Bspec / PAL_PREC_INDEX:
3295  * "Restriction : Index auto increment mode is not
3296  *  supported and must not be enabled."
3297  */
3298 static struct drm_property_blob *ivb_read_lut_10(struct intel_crtc *crtc,
3299 						 u32 prec_index)
3300 {
3301 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3302 	int i, lut_size = ivb_lut_10_size(prec_index);
3303 	enum pipe pipe = crtc->pipe;
3304 	struct drm_property_blob *blob;
3305 	struct drm_color_lut *lut;
3306 
3307 	blob = drm_property_create_blob(&dev_priv->drm,
3308 					sizeof(lut[0]) * lut_size,
3309 					NULL);
3310 	if (IS_ERR(blob))
3311 		return NULL;
3312 
3313 	lut = blob->data;
3314 
3315 	for (i = 0; i < lut_size; i++) {
3316 		u32 val;
3317 
3318 		intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe),
3319 				  prec_index + i);
3320 		val = intel_de_read_fw(dev_priv, PREC_PAL_DATA(pipe));
3321 
3322 		ilk_lut_10_pack(&lut[i], val);
3323 	}
3324 
3325 	intel_de_write_fw(dev_priv, PREC_PAL_INDEX(pipe),
3326 			  PAL_PREC_INDEX_VALUE(0));
3327 
3328 	return blob;
3329 }
3330 
3331 static void ivb_read_luts(struct intel_crtc_state *crtc_state)
3332 {
3333 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3334 	struct drm_property_blob **blob =
3335 		ilk_has_post_csc_lut(crtc_state) ?
3336 		&crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3337 
3338 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3339 		return;
3340 
3341 	switch (crtc_state->gamma_mode) {
3342 	case GAMMA_MODE_MODE_8BIT:
3343 		*blob = ilk_read_lut_8(crtc);
3344 		break;
3345 	case GAMMA_MODE_MODE_SPLIT:
3346 		crtc_state->pre_csc_lut =
3347 			ivb_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3348 					PAL_PREC_INDEX_VALUE(0));
3349 		crtc_state->post_csc_lut =
3350 			ivb_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3351 					PAL_PREC_INDEX_VALUE(512));
3352 		break;
3353 	case GAMMA_MODE_MODE_10BIT:
3354 		*blob = ivb_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3355 		break;
3356 	default:
3357 		MISSING_CASE(crtc_state->gamma_mode);
3358 		break;
3359 	}
3360 }
3361 
3362 /* On BDW+ the index auto increment mode actually works */
3363 static struct drm_property_blob *bdw_read_lut_10(struct intel_crtc *crtc,
3364 						 u32 prec_index)
3365 {
3366 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3367 	int i, lut_size = ivb_lut_10_size(prec_index);
3368 	enum pipe pipe = crtc->pipe;
3369 	struct drm_property_blob *blob;
3370 	struct drm_color_lut *lut;
3371 
3372 	blob = drm_property_create_blob(&i915->drm,
3373 					sizeof(lut[0]) * lut_size,
3374 					NULL);
3375 	if (IS_ERR(blob))
3376 		return NULL;
3377 
3378 	lut = blob->data;
3379 
3380 	intel_de_write_fw(i915, PREC_PAL_INDEX(pipe),
3381 			  prec_index);
3382 	intel_de_write_fw(i915, PREC_PAL_INDEX(pipe),
3383 			  PAL_PREC_AUTO_INCREMENT |
3384 			  prec_index);
3385 
3386 	for (i = 0; i < lut_size; i++) {
3387 		u32 val = intel_de_read_fw(i915, PREC_PAL_DATA(pipe));
3388 
3389 		ilk_lut_10_pack(&lut[i], val);
3390 	}
3391 
3392 	intel_de_write_fw(i915, PREC_PAL_INDEX(pipe),
3393 			  PAL_PREC_INDEX_VALUE(0));
3394 
3395 	return blob;
3396 }
3397 
3398 static void bdw_read_luts(struct intel_crtc_state *crtc_state)
3399 {
3400 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3401 	struct drm_property_blob **blob =
3402 		ilk_has_post_csc_lut(crtc_state) ?
3403 		&crtc_state->post_csc_lut : &crtc_state->pre_csc_lut;
3404 
3405 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3406 		return;
3407 
3408 	switch (crtc_state->gamma_mode) {
3409 	case GAMMA_MODE_MODE_8BIT:
3410 		*blob = ilk_read_lut_8(crtc);
3411 		break;
3412 	case GAMMA_MODE_MODE_SPLIT:
3413 		crtc_state->pre_csc_lut =
3414 			bdw_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3415 					PAL_PREC_INDEX_VALUE(0));
3416 		crtc_state->post_csc_lut =
3417 			bdw_read_lut_10(crtc, PAL_PREC_SPLIT_MODE |
3418 					PAL_PREC_INDEX_VALUE(512));
3419 		break;
3420 	case GAMMA_MODE_MODE_10BIT:
3421 		*blob = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3422 		break;
3423 	default:
3424 		MISSING_CASE(crtc_state->gamma_mode);
3425 		break;
3426 	}
3427 }
3428 
3429 static struct drm_property_blob *glk_read_degamma_lut(struct intel_crtc *crtc)
3430 {
3431 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
3432 	int i, lut_size = DISPLAY_INFO(dev_priv)->color.degamma_lut_size;
3433 	enum pipe pipe = crtc->pipe;
3434 	struct drm_property_blob *blob;
3435 	struct drm_color_lut *lut;
3436 
3437 	blob = drm_property_create_blob(&dev_priv->drm,
3438 					sizeof(lut[0]) * lut_size,
3439 					NULL);
3440 	if (IS_ERR(blob))
3441 		return NULL;
3442 
3443 	lut = blob->data;
3444 
3445 	/*
3446 	 * When setting the auto-increment bit, the hardware seems to
3447 	 * ignore the index bits, so we need to reset it to index 0
3448 	 * separately.
3449 	 */
3450 	intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
3451 			  PRE_CSC_GAMC_INDEX_VALUE(0));
3452 	intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
3453 			  PRE_CSC_GAMC_AUTO_INCREMENT |
3454 			  PRE_CSC_GAMC_INDEX_VALUE(0));
3455 
3456 	for (i = 0; i < lut_size; i++) {
3457 		u32 val = intel_de_read_fw(dev_priv, PRE_CSC_GAMC_DATA(pipe));
3458 
3459 		/*
3460 		 * For MTL and beyond, convert back the 24 bit lut values
3461 		 * read from HW to 16 bit values to maintain parity with
3462 		 * userspace values
3463 		 */
3464 		if (DISPLAY_VER(dev_priv) >= 14)
3465 			val = change_lut_val_precision(val, 16, 24);
3466 
3467 		lut[i].red = val;
3468 		lut[i].green = val;
3469 		lut[i].blue = val;
3470 	}
3471 
3472 	intel_de_write_fw(dev_priv, PRE_CSC_GAMC_INDEX(pipe),
3473 			  PRE_CSC_GAMC_INDEX_VALUE(0));
3474 
3475 	return blob;
3476 }
3477 
3478 static void glk_read_luts(struct intel_crtc_state *crtc_state)
3479 {
3480 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3481 
3482 	if (crtc_state->csc_enable)
3483 		crtc_state->pre_csc_lut = glk_read_degamma_lut(crtc);
3484 
3485 	if (!crtc_state->gamma_enable && !crtc_state->c8_planes)
3486 		return;
3487 
3488 	switch (crtc_state->gamma_mode) {
3489 	case GAMMA_MODE_MODE_8BIT:
3490 		crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
3491 		break;
3492 	case GAMMA_MODE_MODE_10BIT:
3493 		crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3494 		break;
3495 	default:
3496 		MISSING_CASE(crtc_state->gamma_mode);
3497 		break;
3498 	}
3499 }
3500 
3501 static struct drm_property_blob *
3502 icl_read_lut_multi_segment(struct intel_crtc *crtc)
3503 {
3504 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3505 	int i, lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3506 	enum pipe pipe = crtc->pipe;
3507 	struct drm_property_blob *blob;
3508 	struct drm_color_lut *lut;
3509 
3510 	blob = drm_property_create_blob(&i915->drm,
3511 					sizeof(lut[0]) * lut_size,
3512 					NULL);
3513 	if (IS_ERR(blob))
3514 		return NULL;
3515 
3516 	lut = blob->data;
3517 
3518 	intel_de_write_fw(i915, PREC_PAL_MULTI_SEG_INDEX(pipe),
3519 			  PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3520 	intel_de_write_fw(i915, PREC_PAL_MULTI_SEG_INDEX(pipe),
3521 			  PAL_PREC_MULTI_SEG_AUTO_INCREMENT |
3522 			  PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3523 
3524 	for (i = 0; i < 9; i++) {
3525 		u32 ldw = intel_de_read_fw(i915, PREC_PAL_MULTI_SEG_DATA(pipe));
3526 		u32 udw = intel_de_read_fw(i915, PREC_PAL_MULTI_SEG_DATA(pipe));
3527 
3528 		ilk_lut_12p4_pack(&lut[i], ldw, udw);
3529 	}
3530 
3531 	intel_de_write_fw(i915, PREC_PAL_MULTI_SEG_INDEX(pipe),
3532 			  PAL_PREC_MULTI_SEG_INDEX_VALUE(0));
3533 
3534 	/*
3535 	 * FIXME readouts from PAL_PREC_DATA register aren't giving
3536 	 * correct values in the case of fine and coarse segments.
3537 	 * Restricting readouts only for super fine segment as of now.
3538 	 */
3539 
3540 	return blob;
3541 }
3542 
3543 static void icl_read_luts(struct intel_crtc_state *crtc_state)
3544 {
3545 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
3546 
3547 	if (icl_has_pre_csc_lut(crtc_state))
3548 		crtc_state->pre_csc_lut = glk_read_degamma_lut(crtc);
3549 
3550 	if (!icl_has_post_csc_lut(crtc_state))
3551 		return;
3552 
3553 	switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) {
3554 	case GAMMA_MODE_MODE_8BIT:
3555 		crtc_state->post_csc_lut = ilk_read_lut_8(crtc);
3556 		break;
3557 	case GAMMA_MODE_MODE_10BIT:
3558 		crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0));
3559 		break;
3560 	case GAMMA_MODE_MODE_12BIT_MULTI_SEG:
3561 		crtc_state->post_csc_lut = icl_read_lut_multi_segment(crtc);
3562 		break;
3563 	default:
3564 		MISSING_CASE(crtc_state->gamma_mode);
3565 		break;
3566 	}
3567 }
3568 
3569 static const struct intel_color_funcs chv_color_funcs = {
3570 	.color_check = chv_color_check,
3571 	.color_commit_arm = i9xx_color_commit_arm,
3572 	.load_luts = chv_load_luts,
3573 	.read_luts = chv_read_luts,
3574 	.lut_equal = chv_lut_equal,
3575 	.read_csc = chv_read_csc,
3576 };
3577 
3578 static const struct intel_color_funcs vlv_color_funcs = {
3579 	.color_check = vlv_color_check,
3580 	.color_commit_arm = i9xx_color_commit_arm,
3581 	.load_luts = vlv_load_luts,
3582 	.read_luts = i965_read_luts,
3583 	.lut_equal = i965_lut_equal,
3584 	.read_csc = vlv_read_csc,
3585 };
3586 
3587 static const struct intel_color_funcs i965_color_funcs = {
3588 	.color_check = i9xx_color_check,
3589 	.color_commit_arm = i9xx_color_commit_arm,
3590 	.load_luts = i965_load_luts,
3591 	.read_luts = i965_read_luts,
3592 	.lut_equal = i965_lut_equal,
3593 };
3594 
3595 static const struct intel_color_funcs i9xx_color_funcs = {
3596 	.color_check = i9xx_color_check,
3597 	.color_commit_arm = i9xx_color_commit_arm,
3598 	.load_luts = i9xx_load_luts,
3599 	.read_luts = i9xx_read_luts,
3600 	.lut_equal = i9xx_lut_equal,
3601 };
3602 
3603 static const struct intel_color_funcs tgl_color_funcs = {
3604 	.color_check = icl_color_check,
3605 	.color_commit_noarm = icl_color_commit_noarm,
3606 	.color_commit_arm = icl_color_commit_arm,
3607 	.load_luts = icl_load_luts,
3608 	.read_luts = icl_read_luts,
3609 	.lut_equal = icl_lut_equal,
3610 	.read_csc = icl_read_csc,
3611 };
3612 
3613 static const struct intel_color_funcs icl_color_funcs = {
3614 	.color_check = icl_color_check,
3615 	.color_commit_noarm = icl_color_commit_noarm,
3616 	.color_commit_arm = icl_color_commit_arm,
3617 	.color_post_update = icl_color_post_update,
3618 	.load_luts = icl_load_luts,
3619 	.read_luts = icl_read_luts,
3620 	.lut_equal = icl_lut_equal,
3621 	.read_csc = icl_read_csc,
3622 };
3623 
3624 static const struct intel_color_funcs glk_color_funcs = {
3625 	.color_check = glk_color_check,
3626 	.color_commit_noarm = skl_color_commit_noarm,
3627 	.color_commit_arm = skl_color_commit_arm,
3628 	.load_luts = glk_load_luts,
3629 	.read_luts = glk_read_luts,
3630 	.lut_equal = glk_lut_equal,
3631 	.read_csc = skl_read_csc,
3632 };
3633 
3634 static const struct intel_color_funcs skl_color_funcs = {
3635 	.color_check = ivb_color_check,
3636 	.color_commit_noarm = skl_color_commit_noarm,
3637 	.color_commit_arm = skl_color_commit_arm,
3638 	.load_luts = bdw_load_luts,
3639 	.read_luts = bdw_read_luts,
3640 	.lut_equal = ivb_lut_equal,
3641 	.read_csc = skl_read_csc,
3642 };
3643 
3644 static const struct intel_color_funcs bdw_color_funcs = {
3645 	.color_check = ivb_color_check,
3646 	.color_commit_noarm = ilk_color_commit_noarm,
3647 	.color_commit_arm = hsw_color_commit_arm,
3648 	.load_luts = bdw_load_luts,
3649 	.read_luts = bdw_read_luts,
3650 	.lut_equal = ivb_lut_equal,
3651 	.read_csc = ilk_read_csc,
3652 };
3653 
3654 static const struct intel_color_funcs hsw_color_funcs = {
3655 	.color_check = ivb_color_check,
3656 	.color_commit_noarm = ilk_color_commit_noarm,
3657 	.color_commit_arm = hsw_color_commit_arm,
3658 	.load_luts = ivb_load_luts,
3659 	.read_luts = ivb_read_luts,
3660 	.lut_equal = ivb_lut_equal,
3661 	.read_csc = ilk_read_csc,
3662 };
3663 
3664 static const struct intel_color_funcs ivb_color_funcs = {
3665 	.color_check = ivb_color_check,
3666 	.color_commit_noarm = ilk_color_commit_noarm,
3667 	.color_commit_arm = ilk_color_commit_arm,
3668 	.load_luts = ivb_load_luts,
3669 	.read_luts = ivb_read_luts,
3670 	.lut_equal = ivb_lut_equal,
3671 	.read_csc = ilk_read_csc,
3672 };
3673 
3674 static const struct intel_color_funcs ilk_color_funcs = {
3675 	.color_check = ilk_color_check,
3676 	.color_commit_noarm = ilk_color_commit_noarm,
3677 	.color_commit_arm = ilk_color_commit_arm,
3678 	.load_luts = ilk_load_luts,
3679 	.read_luts = ilk_read_luts,
3680 	.lut_equal = ilk_lut_equal,
3681 	.read_csc = ilk_read_csc,
3682 };
3683 
3684 void intel_color_crtc_init(struct intel_crtc *crtc)
3685 {
3686 	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
3687 	int degamma_lut_size, gamma_lut_size;
3688 	bool has_ctm;
3689 
3690 	drm_mode_crtc_set_gamma_size(&crtc->base, 256);
3691 
3692 	gamma_lut_size = DISPLAY_INFO(i915)->color.gamma_lut_size;
3693 	degamma_lut_size = DISPLAY_INFO(i915)->color.degamma_lut_size;
3694 	has_ctm = DISPLAY_VER(i915) >= 5;
3695 
3696 	/*
3697 	 * "DPALETTE_A: NOTE: The 8-bit (non-10-bit) mode is the
3698 	 *  only mode supported by Alviso and Grantsdale."
3699 	 *
3700 	 * Actually looks like this affects all of gen3.
3701 	 * Confirmed on alv,cst,pnv. Mobile gen2 parts (alm,mgm)
3702 	 * are confirmed not to suffer from this restriction.
3703 	 */
3704 	if (DISPLAY_VER(i915) == 3 && crtc->pipe == PIPE_A)
3705 		gamma_lut_size = 256;
3706 
3707 	drm_crtc_enable_color_mgmt(&crtc->base, degamma_lut_size,
3708 				   has_ctm, gamma_lut_size);
3709 }
3710 
3711 int intel_color_init(struct drm_i915_private *i915)
3712 {
3713 	struct drm_property_blob *blob;
3714 
3715 	if (DISPLAY_VER(i915) != 10)
3716 		return 0;
3717 
3718 	blob = create_linear_lut(i915,
3719 				 DISPLAY_INFO(i915)->color.degamma_lut_size);
3720 	if (IS_ERR(blob))
3721 		return PTR_ERR(blob);
3722 
3723 	i915->display.color.glk_linear_degamma_lut = blob;
3724 
3725 	return 0;
3726 }
3727 
3728 void intel_color_init_hooks(struct drm_i915_private *i915)
3729 {
3730 	if (HAS_GMCH(i915)) {
3731 		if (IS_CHERRYVIEW(i915))
3732 			i915->display.funcs.color = &chv_color_funcs;
3733 		else if (IS_VALLEYVIEW(i915))
3734 			i915->display.funcs.color = &vlv_color_funcs;
3735 		else if (DISPLAY_VER(i915) >= 4)
3736 			i915->display.funcs.color = &i965_color_funcs;
3737 		else
3738 			i915->display.funcs.color = &i9xx_color_funcs;
3739 	} else {
3740 		if (DISPLAY_VER(i915) >= 12)
3741 			i915->display.funcs.color = &tgl_color_funcs;
3742 		else if (DISPLAY_VER(i915) == 11)
3743 			i915->display.funcs.color = &icl_color_funcs;
3744 		else if (DISPLAY_VER(i915) == 10)
3745 			i915->display.funcs.color = &glk_color_funcs;
3746 		else if (DISPLAY_VER(i915) == 9)
3747 			i915->display.funcs.color = &skl_color_funcs;
3748 		else if (DISPLAY_VER(i915) == 8)
3749 			i915->display.funcs.color = &bdw_color_funcs;
3750 		else if (IS_HASWELL(i915))
3751 			i915->display.funcs.color = &hsw_color_funcs;
3752 		else if (DISPLAY_VER(i915) == 7)
3753 			i915->display.funcs.color = &ivb_color_funcs;
3754 		else
3755 			i915->display.funcs.color = &ilk_color_funcs;
3756 	}
3757 }
3758