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