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