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