2 * Copyright © 2016 Intel Corporation
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:
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
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.
25 #include "intel_drv.h"
27 #define CTM_COEFF_SIGN (1ULL << 63)
29 #define CTM_COEFF_1_0 (1ULL << 32)
30 #define CTM_COEFF_2_0 (CTM_COEFF_1_0 << 1)
31 #define CTM_COEFF_4_0 (CTM_COEFF_2_0 << 1)
32 #define CTM_COEFF_8_0 (CTM_COEFF_4_0 << 1)
33 #define CTM_COEFF_0_5 (CTM_COEFF_1_0 >> 1)
34 #define CTM_COEFF_0_25 (CTM_COEFF_0_5 >> 1)
35 #define CTM_COEFF_0_125 (CTM_COEFF_0_25 >> 1)
37 #define CTM_COEFF_LIMITED_RANGE ((235ULL - 16ULL) * CTM_COEFF_1_0 / 255)
39 #define CTM_COEFF_NEGATIVE(coeff) (((coeff) & CTM_COEFF_SIGN) != 0)
40 #define CTM_COEFF_ABS(coeff) ((coeff) & (CTM_COEFF_SIGN - 1))
42 #define LEGACY_LUT_LENGTH 256
44 * Extract the CSC coefficient from a CTM coefficient (in U32.32 fixed point
45 * format). This macro takes the coefficient we want transformed and the
46 * number of fractional bits.
48 * We only have a 9 bits precision window which slides depending on the value
49 * of the CTM coefficient and we write the value from bit 3. We also round the
52 #define ILK_CSC_COEFF_FP(coeff, fbits) \
53 (clamp_val(((coeff) >> (32 - (fbits) - 3)) + 4, 0, 0xfff) & 0xff8)
55 #define ILK_CSC_COEFF_LIMITED_RANGE 0x0dc0
56 #define ILK_CSC_COEFF_1_0 0x7800
58 #define ILK_CSC_POSTOFF_LIMITED_RANGE (16 * (1 << 12) / 255)
60 static const u16 ilk_csc_off_zero
[3] = {};
62 static const u16 ilk_csc_coeff_identity
[9] = {
63 ILK_CSC_COEFF_1_0
, 0, 0,
64 0, ILK_CSC_COEFF_1_0
, 0,
65 0, 0, ILK_CSC_COEFF_1_0
,
68 static const u16 ilk_csc_postoff_limited_range
[3] = {
69 ILK_CSC_POSTOFF_LIMITED_RANGE
,
70 ILK_CSC_POSTOFF_LIMITED_RANGE
,
71 ILK_CSC_POSTOFF_LIMITED_RANGE
,
74 static const u16 ilk_csc_coeff_limited_range
[9] = {
75 ILK_CSC_COEFF_LIMITED_RANGE
, 0, 0,
76 0, ILK_CSC_COEFF_LIMITED_RANGE
, 0,
77 0, 0, ILK_CSC_COEFF_LIMITED_RANGE
,
81 * These values are direct register values specified in the Bspec,
82 * for RGB->YUV conversion matrix (colorspace BT709)
84 static const u16 ilk_csc_coeff_rgb_to_ycbcr
[9] = {
85 0x1e08, 0x9cc0, 0xb528,
86 0x2ba8, 0x09d8, 0x37e8,
87 0xbce8, 0x9ad8, 0x1e08,
90 /* Post offset values for RGB->YCBCR conversion */
91 static const u16 ilk_csc_postoff_rgb_to_ycbcr
[3] = {
92 0x0800, 0x0100, 0x0800,
95 static bool lut_is_legacy(const struct drm_property_blob
*lut
)
97 return drm_color_lut_size(lut
) == LEGACY_LUT_LENGTH
;
100 static bool crtc_state_is_legacy_gamma(const struct intel_crtc_state
*crtc_state
)
102 return !crtc_state
->base
.degamma_lut
&&
103 !crtc_state
->base
.ctm
&&
104 crtc_state
->base
.gamma_lut
&&
105 lut_is_legacy(crtc_state
->base
.gamma_lut
);
109 * When using limited range, multiply the matrix given by userspace by
110 * the matrix that we would use for the limited range.
112 static u64
*ctm_mult_by_limited(u64
*result
, const u64
*input
)
116 for (i
= 0; i
< 9; i
++) {
117 u64 user_coeff
= input
[i
];
118 u32 limited_coeff
= CTM_COEFF_LIMITED_RANGE
;
119 u32 abs_coeff
= clamp_val(CTM_COEFF_ABS(user_coeff
), 0,
120 CTM_COEFF_4_0
- 1) >> 2;
123 * By scaling every co-efficient with limited range (16-235)
124 * vs full range (0-255) the final o/p will be scaled down to
125 * fit in the limited range supported by the panel.
127 result
[i
] = mul_u32_u32(limited_coeff
, abs_coeff
) >> 30;
128 result
[i
] |= user_coeff
& CTM_COEFF_SIGN
;
134 static void ilk_update_pipe_csc(struct intel_crtc
*crtc
,
137 const u16 postoff
[3])
139 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
140 enum pipe pipe
= crtc
->pipe
;
142 I915_WRITE(PIPE_CSC_PREOFF_HI(pipe
), preoff
[0]);
143 I915_WRITE(PIPE_CSC_PREOFF_ME(pipe
), preoff
[1]);
144 I915_WRITE(PIPE_CSC_PREOFF_LO(pipe
), preoff
[2]);
146 I915_WRITE(PIPE_CSC_COEFF_RY_GY(pipe
), coeff
[0] << 16 | coeff
[1]);
147 I915_WRITE(PIPE_CSC_COEFF_BY(pipe
), coeff
[2] << 16);
149 I915_WRITE(PIPE_CSC_COEFF_RU_GU(pipe
), coeff
[3] << 16 | coeff
[4]);
150 I915_WRITE(PIPE_CSC_COEFF_BU(pipe
), coeff
[5] << 16);
152 I915_WRITE(PIPE_CSC_COEFF_RV_GV(pipe
), coeff
[6] << 16 | coeff
[7]);
153 I915_WRITE(PIPE_CSC_COEFF_BV(pipe
), coeff
[8] << 16);
155 if (INTEL_GEN(dev_priv
) >= 7) {
156 I915_WRITE(PIPE_CSC_POSTOFF_HI(pipe
), postoff
[0]);
157 I915_WRITE(PIPE_CSC_POSTOFF_ME(pipe
), postoff
[1]);
158 I915_WRITE(PIPE_CSC_POSTOFF_LO(pipe
), postoff
[2]);
162 static void icl_update_output_csc(struct intel_crtc
*crtc
,
165 const u16 postoff
[3])
167 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
168 enum pipe pipe
= crtc
->pipe
;
170 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_HI(pipe
), preoff
[0]);
171 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_ME(pipe
), preoff
[1]);
172 I915_WRITE(PIPE_CSC_OUTPUT_PREOFF_LO(pipe
), preoff
[2]);
174 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RY_GY(pipe
), coeff
[0] << 16 | coeff
[1]);
175 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BY(pipe
), coeff
[2]);
177 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RU_GU(pipe
), coeff
[3] << 16 | coeff
[4]);
178 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BU(pipe
), coeff
[5]);
180 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_RV_GV(pipe
), coeff
[6] << 16 | coeff
[7]);
181 I915_WRITE(PIPE_CSC_OUTPUT_COEFF_BV(pipe
), coeff
[8]);
183 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_HI(pipe
), postoff
[0]);
184 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_ME(pipe
), postoff
[1]);
185 I915_WRITE(PIPE_CSC_OUTPUT_POSTOFF_LO(pipe
), postoff
[2]);
188 static bool ilk_csc_limited_range(const struct intel_crtc_state
*crtc_state
)
190 struct drm_i915_private
*dev_priv
= to_i915(crtc_state
->base
.crtc
->dev
);
193 * FIXME if there's a gamma LUT after the CSC, we should
194 * do the range compression using the gamma LUT instead.
196 return crtc_state
->limited_color_range
&&
197 (IS_HASWELL(dev_priv
) || IS_BROADWELL(dev_priv
) ||
198 IS_GEN_RANGE(dev_priv
, 9, 10));
201 static void ilk_csc_convert_ctm(const struct intel_crtc_state
*crtc_state
,
204 const struct drm_color_ctm
*ctm
= crtc_state
->base
.ctm
->data
;
209 if (ilk_csc_limited_range(crtc_state
))
210 input
= ctm_mult_by_limited(temp
, ctm
->matrix
);
215 * Convert fixed point S31.32 input to format supported by the
218 for (i
= 0; i
< 9; i
++) {
219 u64 abs_coeff
= ((1ULL << 63) - 1) & input
[i
];
222 * Clamp input value to min/max supported by
225 abs_coeff
= clamp_val(abs_coeff
, 0, CTM_COEFF_4_0
- 1);
230 if (CTM_COEFF_NEGATIVE(input
[i
]))
231 coeffs
[i
] |= 1 << 15;
233 if (abs_coeff
< CTM_COEFF_0_125
)
234 coeffs
[i
] |= (3 << 12) |
235 ILK_CSC_COEFF_FP(abs_coeff
, 12);
236 else if (abs_coeff
< CTM_COEFF_0_25
)
237 coeffs
[i
] |= (2 << 12) |
238 ILK_CSC_COEFF_FP(abs_coeff
, 11);
239 else if (abs_coeff
< CTM_COEFF_0_5
)
240 coeffs
[i
] |= (1 << 12) |
241 ILK_CSC_COEFF_FP(abs_coeff
, 10);
242 else if (abs_coeff
< CTM_COEFF_1_0
)
243 coeffs
[i
] |= ILK_CSC_COEFF_FP(abs_coeff
, 9);
244 else if (abs_coeff
< CTM_COEFF_2_0
)
245 coeffs
[i
] |= (7 << 12) |
246 ILK_CSC_COEFF_FP(abs_coeff
, 8);
248 coeffs
[i
] |= (6 << 12) |
249 ILK_CSC_COEFF_FP(abs_coeff
, 7);
253 static void ilk_load_csc_matrix(const struct intel_crtc_state
*crtc_state
)
255 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
256 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
257 bool limited_color_range
= ilk_csc_limited_range(crtc_state
);
259 if (crtc_state
->base
.ctm
) {
262 ilk_csc_convert_ctm(crtc_state
, coeff
);
263 ilk_update_pipe_csc(crtc
, ilk_csc_off_zero
, coeff
,
264 limited_color_range
?
265 ilk_csc_postoff_limited_range
:
267 } else if (crtc_state
->output_format
!= INTEL_OUTPUT_FORMAT_RGB
) {
268 ilk_update_pipe_csc(crtc
, ilk_csc_off_zero
,
269 ilk_csc_coeff_rgb_to_ycbcr
,
270 ilk_csc_postoff_rgb_to_ycbcr
);
271 } else if (limited_color_range
) {
272 ilk_update_pipe_csc(crtc
, ilk_csc_off_zero
,
273 ilk_csc_coeff_limited_range
,
274 ilk_csc_postoff_limited_range
);
275 } else if (crtc_state
->csc_enable
) {
276 ilk_update_pipe_csc(crtc
, ilk_csc_off_zero
,
277 ilk_csc_coeff_identity
,
281 I915_WRITE(PIPE_CSC_MODE(crtc
->pipe
), crtc_state
->csc_mode
);
284 static void icl_load_csc_matrix(const struct intel_crtc_state
*crtc_state
)
286 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
287 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
289 if (crtc_state
->base
.ctm
) {
292 ilk_csc_convert_ctm(crtc_state
, coeff
);
293 ilk_update_pipe_csc(crtc
, ilk_csc_off_zero
,
294 coeff
, ilk_csc_off_zero
);
297 if (crtc_state
->output_format
!= INTEL_OUTPUT_FORMAT_RGB
) {
298 icl_update_output_csc(crtc
, ilk_csc_off_zero
,
299 ilk_csc_coeff_rgb_to_ycbcr
,
300 ilk_csc_postoff_rgb_to_ycbcr
);
301 } else if (crtc_state
->limited_color_range
) {
302 icl_update_output_csc(crtc
, ilk_csc_off_zero
,
303 ilk_csc_coeff_limited_range
,
304 ilk_csc_postoff_limited_range
);
307 I915_WRITE(PIPE_CSC_MODE(crtc
->pipe
), crtc_state
->csc_mode
);
311 * Set up the pipe CSC unit on CherryView.
313 static void cherryview_load_csc_matrix(const struct intel_crtc_state
*crtc_state
)
315 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
316 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
317 enum pipe pipe
= crtc
->pipe
;
319 if (crtc_state
->base
.ctm
) {
320 const struct drm_color_ctm
*ctm
= crtc_state
->base
.ctm
->data
;
324 for (i
= 0; i
< ARRAY_SIZE(coeffs
); i
++) {
326 ((1ULL << 63) - 1) & ctm
->matrix
[i
];
328 /* Round coefficient. */
329 abs_coeff
+= 1 << (32 - 13);
330 /* Clamp to hardware limits. */
331 abs_coeff
= clamp_val(abs_coeff
, 0, CTM_COEFF_8_0
- 1);
333 /* Write coefficients in S3.12 format. */
334 if (ctm
->matrix
[i
] & (1ULL << 63))
336 coeffs
[i
] |= ((abs_coeff
>> 32) & 7) << 12;
337 coeffs
[i
] |= (abs_coeff
>> 20) & 0xfff;
340 I915_WRITE(CGM_PIPE_CSC_COEFF01(pipe
),
341 coeffs
[1] << 16 | coeffs
[0]);
342 I915_WRITE(CGM_PIPE_CSC_COEFF23(pipe
),
343 coeffs
[3] << 16 | coeffs
[2]);
344 I915_WRITE(CGM_PIPE_CSC_COEFF45(pipe
),
345 coeffs
[5] << 16 | coeffs
[4]);
346 I915_WRITE(CGM_PIPE_CSC_COEFF67(pipe
),
347 coeffs
[7] << 16 | coeffs
[6]);
348 I915_WRITE(CGM_PIPE_CSC_COEFF8(pipe
), coeffs
[8]);
351 I915_WRITE(CGM_PIPE_MODE(pipe
), crtc_state
->cgm_mode
);
354 /* Loads the legacy palette/gamma unit for the CRTC. */
355 static void i9xx_load_luts_internal(const struct intel_crtc_state
*crtc_state
,
356 const struct drm_property_blob
*blob
)
358 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
359 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
360 enum pipe pipe
= crtc
->pipe
;
363 if (HAS_GMCH(dev_priv
)) {
364 if (intel_crtc_has_type(crtc_state
, INTEL_OUTPUT_DSI
))
365 assert_dsi_pll_enabled(dev_priv
);
367 assert_pll_enabled(dev_priv
, pipe
);
371 const struct drm_color_lut
*lut
= blob
->data
;
373 for (i
= 0; i
< 256; i
++) {
375 (drm_color_lut_extract(lut
[i
].red
, 8) << 16) |
376 (drm_color_lut_extract(lut
[i
].green
, 8) << 8) |
377 drm_color_lut_extract(lut
[i
].blue
, 8);
379 if (HAS_GMCH(dev_priv
))
380 I915_WRITE(PALETTE(pipe
, i
), word
);
382 I915_WRITE(LGC_PALETTE(pipe
, i
), word
);
385 for (i
= 0; i
< 256; i
++) {
386 u32 word
= (i
<< 16) | (i
<< 8) | i
;
388 if (HAS_GMCH(dev_priv
))
389 I915_WRITE(PALETTE(pipe
, i
), word
);
391 I915_WRITE(LGC_PALETTE(pipe
, i
), word
);
396 static void i9xx_load_luts(const struct intel_crtc_state
*crtc_state
)
398 i9xx_load_luts_internal(crtc_state
, crtc_state
->base
.gamma_lut
);
401 static void i9xx_color_commit(const struct intel_crtc_state
*crtc_state
)
403 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
404 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
405 enum pipe pipe
= crtc
->pipe
;
408 val
= I915_READ(PIPECONF(pipe
));
409 val
&= ~PIPECONF_GAMMA_MODE_MASK_I9XX
;
410 val
|= PIPECONF_GAMMA_MODE(crtc_state
->gamma_mode
);
411 I915_WRITE(PIPECONF(pipe
), val
);
414 static void ilk_color_commit(const struct intel_crtc_state
*crtc_state
)
416 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
417 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
418 enum pipe pipe
= crtc
->pipe
;
421 val
= I915_READ(PIPECONF(pipe
));
422 val
&= ~PIPECONF_GAMMA_MODE_MASK_ILK
;
423 val
|= PIPECONF_GAMMA_MODE(crtc_state
->gamma_mode
);
424 I915_WRITE(PIPECONF(pipe
), val
);
427 static void hsw_color_commit(const struct intel_crtc_state
*crtc_state
)
429 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
430 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
432 I915_WRITE(GAMMA_MODE(crtc
->pipe
), crtc_state
->gamma_mode
);
434 ilk_load_csc_matrix(crtc_state
);
437 static void skl_color_commit(const struct intel_crtc_state
*crtc_state
)
439 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
440 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
441 enum pipe pipe
= crtc
->pipe
;
445 * We don't (yet) allow userspace to control the pipe background color,
446 * so force it to black, but apply pipe gamma and CSC appropriately
447 * so that its handling will match how we program our planes.
449 if (crtc_state
->gamma_enable
)
450 val
|= SKL_BOTTOM_COLOR_GAMMA_ENABLE
;
451 if (crtc_state
->csc_enable
)
452 val
|= SKL_BOTTOM_COLOR_CSC_ENABLE
;
453 I915_WRITE(SKL_BOTTOM_COLOR(pipe
), val
);
455 I915_WRITE(GAMMA_MODE(crtc
->pipe
), crtc_state
->gamma_mode
);
457 if (INTEL_GEN(dev_priv
) >= 11)
458 icl_load_csc_matrix(crtc_state
);
460 ilk_load_csc_matrix(crtc_state
);
463 static void bdw_load_degamma_lut(const struct intel_crtc_state
*crtc_state
)
465 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
466 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
467 const struct drm_property_blob
*degamma_lut
= crtc_state
->base
.degamma_lut
;
468 u32 i
, lut_size
= INTEL_INFO(dev_priv
)->color
.degamma_lut_size
;
469 enum pipe pipe
= crtc
->pipe
;
471 I915_WRITE(PREC_PAL_INDEX(pipe
),
472 PAL_PREC_SPLIT_MODE
| PAL_PREC_AUTO_INCREMENT
);
475 const struct drm_color_lut
*lut
= degamma_lut
->data
;
477 for (i
= 0; i
< lut_size
; i
++) {
479 drm_color_lut_extract(lut
[i
].red
, 10) << 20 |
480 drm_color_lut_extract(lut
[i
].green
, 10) << 10 |
481 drm_color_lut_extract(lut
[i
].blue
, 10);
483 I915_WRITE(PREC_PAL_DATA(pipe
), word
);
486 for (i
= 0; i
< lut_size
; i
++) {
487 u32 v
= (i
* ((1 << 10) - 1)) / (lut_size
- 1);
489 I915_WRITE(PREC_PAL_DATA(pipe
),
490 (v
<< 20) | (v
<< 10) | v
);
495 static void bdw_load_gamma_lut(const struct intel_crtc_state
*crtc_state
, u32 offset
)
497 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
498 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
499 const struct drm_property_blob
*gamma_lut
= crtc_state
->base
.gamma_lut
;
500 u32 i
, lut_size
= INTEL_INFO(dev_priv
)->color
.gamma_lut_size
;
501 enum pipe pipe
= crtc
->pipe
;
503 WARN_ON(offset
& ~PAL_PREC_INDEX_VALUE_MASK
);
505 I915_WRITE(PREC_PAL_INDEX(pipe
),
506 (offset
? PAL_PREC_SPLIT_MODE
: 0) |
507 PAL_PREC_AUTO_INCREMENT
|
511 const struct drm_color_lut
*lut
= gamma_lut
->data
;
513 for (i
= 0; i
< lut_size
; i
++) {
515 (drm_color_lut_extract(lut
[i
].red
, 10) << 20) |
516 (drm_color_lut_extract(lut
[i
].green
, 10) << 10) |
517 drm_color_lut_extract(lut
[i
].blue
, 10);
519 I915_WRITE(PREC_PAL_DATA(pipe
), word
);
522 /* Program the max register to clamp values > 1.0. */
524 I915_WRITE(PREC_PAL_GC_MAX(pipe
, 0),
525 drm_color_lut_extract(lut
[i
].red
, 16));
526 I915_WRITE(PREC_PAL_GC_MAX(pipe
, 1),
527 drm_color_lut_extract(lut
[i
].green
, 16));
528 I915_WRITE(PREC_PAL_GC_MAX(pipe
, 2),
529 drm_color_lut_extract(lut
[i
].blue
, 16));
531 for (i
= 0; i
< lut_size
; i
++) {
532 u32 v
= (i
* ((1 << 10) - 1)) / (lut_size
- 1);
534 I915_WRITE(PREC_PAL_DATA(pipe
),
535 (v
<< 20) | (v
<< 10) | v
);
538 I915_WRITE(PREC_PAL_GC_MAX(pipe
, 0), (1 << 16) - 1);
539 I915_WRITE(PREC_PAL_GC_MAX(pipe
, 1), (1 << 16) - 1);
540 I915_WRITE(PREC_PAL_GC_MAX(pipe
, 2), (1 << 16) - 1);
544 * Reset the index, otherwise it prevents the legacy palette to be
547 I915_WRITE(PREC_PAL_INDEX(pipe
), 0);
550 /* Loads the palette/gamma unit for the CRTC on Broadwell+. */
551 static void broadwell_load_luts(const struct intel_crtc_state
*crtc_state
)
553 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
554 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
556 if (crtc_state_is_legacy_gamma(crtc_state
)) {
557 i9xx_load_luts(crtc_state
);
559 bdw_load_degamma_lut(crtc_state
);
560 bdw_load_gamma_lut(crtc_state
,
561 INTEL_INFO(dev_priv
)->color
.degamma_lut_size
);
565 static void glk_load_degamma_lut(const struct intel_crtc_state
*crtc_state
)
567 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
568 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
569 enum pipe pipe
= crtc
->pipe
;
570 const u32 lut_size
= INTEL_INFO(dev_priv
)->color
.degamma_lut_size
;
574 * When setting the auto-increment bit, the hardware seems to
575 * ignore the index bits, so we need to reset it to index 0
578 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe
), 0);
579 I915_WRITE(PRE_CSC_GAMC_INDEX(pipe
), PRE_CSC_GAMC_AUTO_INCREMENT
);
581 if (crtc_state
->base
.degamma_lut
) {
582 struct drm_color_lut
*lut
= crtc_state
->base
.degamma_lut
->data
;
584 for (i
= 0; i
< lut_size
; i
++) {
586 * First 33 entries represent range from 0 to 1.0
587 * 34th and 35th entry will represent extended range
588 * inputs 3.0 and 7.0 respectively, currently clamped
589 * at 1.0. Since the precision is 16bit, the user
590 * value can be directly filled to register.
591 * The pipe degamma table in GLK+ onwards doesn't
592 * support different values per channel, so this just
593 * programs green value which will be equal to Red and
594 * Blue into the lut registers.
595 * ToDo: Extend to max 7.0. Enable 32 bit input value
596 * as compared to just 16 to achieve this.
598 I915_WRITE(PRE_CSC_GAMC_DATA(pipe
), lut
[i
].green
);
601 /* load a linear table. */
602 for (i
= 0; i
< lut_size
; i
++) {
603 u32 v
= (i
* (1 << 16)) / (lut_size
- 1);
605 I915_WRITE(PRE_CSC_GAMC_DATA(pipe
), v
);
609 /* Clamp values > 1.0. */
611 I915_WRITE(PRE_CSC_GAMC_DATA(pipe
), (1 << 16));
614 static void glk_load_luts(const struct intel_crtc_state
*crtc_state
)
616 glk_load_degamma_lut(crtc_state
);
618 if (crtc_state_is_legacy_gamma(crtc_state
))
619 i9xx_load_luts(crtc_state
);
621 bdw_load_gamma_lut(crtc_state
, 0);
624 static void icl_load_luts(const struct intel_crtc_state
*crtc_state
)
626 glk_load_degamma_lut(crtc_state
);
628 if (crtc_state_is_legacy_gamma(crtc_state
))
629 i9xx_load_luts(crtc_state
);
631 /* ToDo: Add support for multi segment gamma LUT */
632 bdw_load_gamma_lut(crtc_state
, 0);
635 static void cherryview_load_luts(const struct intel_crtc_state
*crtc_state
)
637 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->base
.crtc
);
638 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
639 const struct drm_property_blob
*gamma_lut
= crtc_state
->base
.gamma_lut
;
640 const struct drm_property_blob
*degamma_lut
= crtc_state
->base
.degamma_lut
;
641 enum pipe pipe
= crtc
->pipe
;
643 cherryview_load_csc_matrix(crtc_state
);
645 if (crtc_state_is_legacy_gamma(crtc_state
)) {
646 i9xx_load_luts_internal(crtc_state
, gamma_lut
);
651 const struct drm_color_lut
*lut
= degamma_lut
->data
;
652 int i
, lut_size
= INTEL_INFO(dev_priv
)->color
.degamma_lut_size
;
654 for (i
= 0; i
< lut_size
; i
++) {
657 /* Write LUT in U0.14 format. */
659 (drm_color_lut_extract(lut
[i
].green
, 14) << 16) |
660 drm_color_lut_extract(lut
[i
].blue
, 14);
661 word1
= drm_color_lut_extract(lut
[i
].red
, 14);
663 I915_WRITE(CGM_PIPE_DEGAMMA(pipe
, i
, 0), word0
);
664 I915_WRITE(CGM_PIPE_DEGAMMA(pipe
, i
, 1), word1
);
669 const struct drm_color_lut
*lut
= gamma_lut
->data
;
670 int i
, lut_size
= INTEL_INFO(dev_priv
)->color
.gamma_lut_size
;
672 for (i
= 0; i
< lut_size
; i
++) {
675 /* Write LUT in U0.10 format. */
677 (drm_color_lut_extract(lut
[i
].green
, 10) << 16) |
678 drm_color_lut_extract(lut
[i
].blue
, 10);
679 word1
= drm_color_lut_extract(lut
[i
].red
, 10);
681 I915_WRITE(CGM_PIPE_GAMMA(pipe
, i
, 0), word0
);
682 I915_WRITE(CGM_PIPE_GAMMA(pipe
, i
, 1), word1
);
687 * Also program a linear LUT in the legacy block (behind the
690 i9xx_load_luts_internal(crtc_state
, NULL
);
693 void intel_color_load_luts(const struct intel_crtc_state
*crtc_state
)
695 struct drm_i915_private
*dev_priv
= to_i915(crtc_state
->base
.crtc
->dev
);
697 dev_priv
->display
.load_luts(crtc_state
);
700 void intel_color_commit(const struct intel_crtc_state
*crtc_state
)
702 struct drm_i915_private
*dev_priv
= to_i915(crtc_state
->base
.crtc
->dev
);
704 dev_priv
->display
.color_commit(crtc_state
);
707 int intel_color_check(struct intel_crtc_state
*crtc_state
)
709 struct drm_i915_private
*dev_priv
= to_i915(crtc_state
->base
.crtc
->dev
);
711 return dev_priv
->display
.color_check(crtc_state
);
714 static bool need_plane_update(struct intel_plane
*plane
,
715 const struct intel_crtc_state
*crtc_state
)
717 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
720 * On pre-SKL the pipe gamma enable and pipe csc enable for
721 * the pipe bottom color are configured via the primary plane.
722 * We have to reconfigure that even if the plane is inactive.
724 return crtc_state
->active_planes
& BIT(plane
->id
) ||
725 (INTEL_GEN(dev_priv
) < 9 &&
726 plane
->id
== PLANE_PRIMARY
);
730 intel_color_add_affected_planes(struct intel_crtc_state
*new_crtc_state
)
732 struct intel_crtc
*crtc
= to_intel_crtc(new_crtc_state
->base
.crtc
);
733 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
734 struct intel_atomic_state
*state
=
735 to_intel_atomic_state(new_crtc_state
->base
.state
);
736 const struct intel_crtc_state
*old_crtc_state
=
737 intel_atomic_get_old_crtc_state(state
, crtc
);
738 struct intel_plane
*plane
;
740 if (!new_crtc_state
->base
.active
||
741 drm_atomic_crtc_needs_modeset(&new_crtc_state
->base
))
744 if (new_crtc_state
->gamma_enable
== old_crtc_state
->gamma_enable
&&
745 new_crtc_state
->csc_enable
== old_crtc_state
->csc_enable
)
748 for_each_intel_plane_on_crtc(&dev_priv
->drm
, crtc
, plane
) {
749 struct intel_plane_state
*plane_state
;
751 if (!need_plane_update(plane
, new_crtc_state
))
754 plane_state
= intel_atomic_get_plane_state(state
, plane
);
755 if (IS_ERR(plane_state
))
756 return PTR_ERR(plane_state
);
758 new_crtc_state
->update_planes
|= BIT(plane
->id
);
764 static int check_lut_size(const struct drm_property_blob
*lut
, int expected
)
771 len
= drm_color_lut_size(lut
);
772 if (len
!= expected
) {
773 DRM_DEBUG_KMS("Invalid LUT size; got %d, expected %d\n",
781 static int check_luts(const struct intel_crtc_state
*crtc_state
)
783 struct drm_i915_private
*dev_priv
= to_i915(crtc_state
->base
.crtc
->dev
);
784 const struct drm_property_blob
*gamma_lut
= crtc_state
->base
.gamma_lut
;
785 const struct drm_property_blob
*degamma_lut
= crtc_state
->base
.degamma_lut
;
786 int gamma_length
, degamma_length
;
787 u32 gamma_tests
, degamma_tests
;
789 /* Always allow legacy gamma LUT with no further checking. */
790 if (crtc_state_is_legacy_gamma(crtc_state
))
793 /* C8 relies on its palette being stored in the legacy LUT */
794 if (crtc_state
->c8_planes
)
797 degamma_length
= INTEL_INFO(dev_priv
)->color
.degamma_lut_size
;
798 gamma_length
= INTEL_INFO(dev_priv
)->color
.gamma_lut_size
;
799 degamma_tests
= INTEL_INFO(dev_priv
)->color
.degamma_lut_tests
;
800 gamma_tests
= INTEL_INFO(dev_priv
)->color
.gamma_lut_tests
;
802 if (check_lut_size(degamma_lut
, degamma_length
) ||
803 check_lut_size(gamma_lut
, gamma_length
))
806 if (drm_color_lut_check(degamma_lut
, degamma_tests
) ||
807 drm_color_lut_check(gamma_lut
, gamma_tests
))
813 static int i9xx_color_check(struct intel_crtc_state
*crtc_state
)
817 ret
= check_luts(crtc_state
);
821 crtc_state
->gamma_enable
=
822 crtc_state
->base
.gamma_lut
&&
823 !crtc_state
->c8_planes
;
825 crtc_state
->gamma_mode
= GAMMA_MODE_MODE_8BIT
;
827 ret
= intel_color_add_affected_planes(crtc_state
);
834 static u32
chv_cgm_mode(const struct intel_crtc_state
*crtc_state
)
838 if (crtc_state_is_legacy_gamma(crtc_state
))
841 if (crtc_state
->base
.degamma_lut
)
842 cgm_mode
|= CGM_PIPE_MODE_DEGAMMA
;
843 if (crtc_state
->base
.ctm
)
844 cgm_mode
|= CGM_PIPE_MODE_CSC
;
845 if (crtc_state
->base
.gamma_lut
)
846 cgm_mode
|= CGM_PIPE_MODE_GAMMA
;
852 * CHV color pipeline:
853 * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma ->
854 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10
856 * We always bypass the WGC csc and use the CGM csc
857 * instead since it has degamma and better precision.
859 static int chv_color_check(struct intel_crtc_state
*crtc_state
)
863 ret
= check_luts(crtc_state
);
868 * Pipe gamma will be used only for the legacy LUT.
869 * Otherwise we bypass it and use the CGM gamma instead.
871 crtc_state
->gamma_enable
=
872 crtc_state_is_legacy_gamma(crtc_state
) &&
873 !crtc_state
->c8_planes
;
875 crtc_state
->gamma_mode
= GAMMA_MODE_MODE_8BIT
;
877 crtc_state
->cgm_mode
= chv_cgm_mode(crtc_state
);
879 ret
= intel_color_add_affected_planes(crtc_state
);
886 static u32
bdw_gamma_mode(const struct intel_crtc_state
*crtc_state
)
888 if (!crtc_state
->gamma_enable
||
889 crtc_state_is_legacy_gamma(crtc_state
))
890 return GAMMA_MODE_MODE_8BIT
;
892 return GAMMA_MODE_MODE_SPLIT
;
895 static int bdw_color_check(struct intel_crtc_state
*crtc_state
)
899 ret
= check_luts(crtc_state
);
903 crtc_state
->gamma_enable
=
904 (crtc_state
->base
.gamma_lut
||
905 crtc_state
->base
.degamma_lut
) &&
906 !crtc_state
->c8_planes
;
908 crtc_state
->csc_enable
=
909 crtc_state
->output_format
!= INTEL_OUTPUT_FORMAT_RGB
||
910 crtc_state
->base
.ctm
|| crtc_state
->limited_color_range
;
912 crtc_state
->gamma_mode
= bdw_gamma_mode(crtc_state
);
914 crtc_state
->csc_mode
= 0;
916 ret
= intel_color_add_affected_planes(crtc_state
);
923 static u32
glk_gamma_mode(const struct intel_crtc_state
*crtc_state
)
925 if (!crtc_state
->gamma_enable
||
926 crtc_state_is_legacy_gamma(crtc_state
))
927 return GAMMA_MODE_MODE_8BIT
;
929 return GAMMA_MODE_MODE_10BIT
;
932 static int glk_color_check(struct intel_crtc_state
*crtc_state
)
936 ret
= check_luts(crtc_state
);
940 crtc_state
->gamma_enable
=
941 crtc_state
->base
.gamma_lut
&&
942 !crtc_state
->c8_planes
;
944 /* On GLK+ degamma LUT is controlled by csc_enable */
945 crtc_state
->csc_enable
=
946 crtc_state
->base
.degamma_lut
||
947 crtc_state
->output_format
!= INTEL_OUTPUT_FORMAT_RGB
||
948 crtc_state
->base
.ctm
|| crtc_state
->limited_color_range
;
950 crtc_state
->gamma_mode
= glk_gamma_mode(crtc_state
);
952 crtc_state
->csc_mode
= 0;
954 ret
= intel_color_add_affected_planes(crtc_state
);
961 static u32
icl_gamma_mode(const struct intel_crtc_state
*crtc_state
)
965 if (crtc_state
->base
.degamma_lut
)
966 gamma_mode
|= PRE_CSC_GAMMA_ENABLE
;
968 if (crtc_state
->base
.gamma_lut
&&
969 !crtc_state
->c8_planes
)
970 gamma_mode
|= POST_CSC_GAMMA_ENABLE
;
972 if (!crtc_state
->base
.gamma_lut
||
973 crtc_state_is_legacy_gamma(crtc_state
))
974 gamma_mode
|= GAMMA_MODE_MODE_8BIT
;
976 gamma_mode
|= GAMMA_MODE_MODE_10BIT
;
981 static u32
icl_csc_mode(const struct intel_crtc_state
*crtc_state
)
985 if (crtc_state
->base
.ctm
)
986 csc_mode
|= ICL_CSC_ENABLE
;
988 if (crtc_state
->output_format
!= INTEL_OUTPUT_FORMAT_RGB
||
989 crtc_state
->limited_color_range
)
990 csc_mode
|= ICL_OUTPUT_CSC_ENABLE
;
995 static int icl_color_check(struct intel_crtc_state
*crtc_state
)
999 ret
= check_luts(crtc_state
);
1003 crtc_state
->gamma_mode
= icl_gamma_mode(crtc_state
);
1005 crtc_state
->csc_mode
= icl_csc_mode(crtc_state
);
1010 static int _intel_color_check(struct intel_crtc_state
*crtc_state
)
1012 struct drm_i915_private
*dev_priv
= to_i915(crtc_state
->base
.crtc
->dev
);
1013 const struct drm_property_blob
*gamma_lut
= crtc_state
->base
.gamma_lut
;
1014 const struct drm_property_blob
*degamma_lut
= crtc_state
->base
.degamma_lut
;
1015 bool limited_color_range
= false;
1018 ret
= check_luts(crtc_state
);
1022 crtc_state
->gamma_enable
= (gamma_lut
|| degamma_lut
) &&
1023 !crtc_state
->c8_planes
;
1025 if (INTEL_GEN(dev_priv
) >= 9 ||
1026 IS_BROADWELL(dev_priv
) || IS_HASWELL(dev_priv
))
1027 limited_color_range
= crtc_state
->limited_color_range
;
1029 crtc_state
->csc_enable
=
1030 crtc_state
->output_format
!= INTEL_OUTPUT_FORMAT_RGB
||
1031 crtc_state
->base
.ctm
|| limited_color_range
;
1033 ret
= intel_color_add_affected_planes(crtc_state
);
1037 crtc_state
->csc_mode
= 0;
1039 if (!crtc_state
->gamma_enable
||
1040 crtc_state_is_legacy_gamma(crtc_state
))
1041 crtc_state
->gamma_mode
= GAMMA_MODE_MODE_8BIT
;
1042 else if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
))
1043 crtc_state
->gamma_mode
= GAMMA_MODE_MODE_10BIT
;
1044 else if (INTEL_GEN(dev_priv
) >= 9 || IS_BROADWELL(dev_priv
))
1045 crtc_state
->gamma_mode
= GAMMA_MODE_MODE_SPLIT
;
1047 crtc_state
->gamma_mode
= GAMMA_MODE_MODE_8BIT
;
1052 void intel_color_init(struct intel_crtc
*crtc
)
1054 struct drm_i915_private
*dev_priv
= to_i915(crtc
->base
.dev
);
1056 drm_mode_crtc_set_gamma_size(&crtc
->base
, 256);
1058 if (HAS_GMCH(dev_priv
)) {
1059 if (IS_CHERRYVIEW(dev_priv
)) {
1060 dev_priv
->display
.color_check
= chv_color_check
;
1061 dev_priv
->display
.color_commit
= i9xx_color_commit
;
1062 dev_priv
->display
.load_luts
= cherryview_load_luts
;
1064 dev_priv
->display
.color_check
= i9xx_color_check
;
1065 dev_priv
->display
.color_commit
= i9xx_color_commit
;
1066 dev_priv
->display
.load_luts
= i9xx_load_luts
;
1069 if (INTEL_GEN(dev_priv
) >= 11)
1070 dev_priv
->display
.color_check
= icl_color_check
;
1071 else if (INTEL_GEN(dev_priv
) >= 10 || IS_GEMINILAKE(dev_priv
))
1072 dev_priv
->display
.color_check
= glk_color_check
;
1073 else if (INTEL_GEN(dev_priv
) >= 8)
1074 dev_priv
->display
.color_check
= bdw_color_check
;
1076 dev_priv
->display
.color_check
= _intel_color_check
;
1078 if (INTEL_GEN(dev_priv
) >= 9)
1079 dev_priv
->display
.color_commit
= skl_color_commit
;
1080 else if (IS_BROADWELL(dev_priv
) || IS_HASWELL(dev_priv
))
1081 dev_priv
->display
.color_commit
= hsw_color_commit
;
1083 dev_priv
->display
.color_commit
= ilk_color_commit
;
1085 if (INTEL_GEN(dev_priv
) >= 11)
1086 dev_priv
->display
.load_luts
= icl_load_luts
;
1087 else if (IS_CANNONLAKE(dev_priv
) || IS_GEMINILAKE(dev_priv
))
1088 dev_priv
->display
.load_luts
= glk_load_luts
;
1089 else if (INTEL_GEN(dev_priv
) >= 9 || IS_BROADWELL(dev_priv
))
1090 dev_priv
->display
.load_luts
= broadwell_load_luts
;
1092 dev_priv
->display
.load_luts
= i9xx_load_luts
;
1095 /* Enable color management support when we have degamma & gamma LUTs. */
1096 if (INTEL_INFO(dev_priv
)->color
.degamma_lut_size
!= 0 &&
1097 INTEL_INFO(dev_priv
)->color
.gamma_lut_size
!= 0)
1098 drm_crtc_enable_color_mgmt(&crtc
->base
,
1099 INTEL_INFO(dev_priv
)->color
.degamma_lut_size
,
1101 INTEL_INFO(dev_priv
)->color
.gamma_lut_size
);