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