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 */ 83static const u16 ilk_csc_off_zero[3] = {}; 84 85/* Identity matrix */ 86static 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 */ 93static 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 */ 100static 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 */ 107static 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 */ 114static const u16 ilk_csc_postoff_rgb_to_ycbcr[3] = { 115 0x0800, 0x0100, 0x0800, 116}; 117 118static bool lut_is_legacy(const struct drm_property_blob *lut) 119{ 120 return drm_color_lut_size(lut) == LEGACY_LUT_LENGTH; 121} 122 123static 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 */ 135static 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 157static 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 185static 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 211static 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 224static 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 276static 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 315static 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 */ 344static 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) */ 386static 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) */ 394static 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 401static 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. */ 409static 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 441static 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 446static 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 459static 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 474static 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 484static 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 510static 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 530static 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 541static 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 553static 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 564static 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 */ 577static 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 */ 604static 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 632static 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 660static 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 683static 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 706static 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 745static 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 772static 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) */ 799static 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) */ 806static 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 812static void 813icl_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 827static void 828icl_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 859static void 860icl_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 916static 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 942static 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 948static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color) 949{ 950 return drm_color_lut_extract(color->red, 14); 951} 952 953static 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 969static 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 975static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color) 976{ 977 return drm_color_lut_extract(color->red, 10); 978} 979 980static 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 996static 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 1016void 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 1023void 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 1030static 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 1042static 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 1061static 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 1079int 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 1086void 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 1094static 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 1109static int 1110intel_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 1144static 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 1161static 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 1195static 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 1204static 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 1227static 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 */ 1252static 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 1281static 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 1290static 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 1305static 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 1337static 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 1349static 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 1365static 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 1396static 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 1405static 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 1436static 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 1456static 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 1470static 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 1487static 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 1503static 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 1522static 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 1530static 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 1546int 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 1566static 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 1574static 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 1588bool 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 */ 1639static 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 1651static struct drm_property_blob * 1652i9xx_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 1686static 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 1694static struct drm_property_blob * 1695i965_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 1735static 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 1746static struct drm_property_blob * 1747chv_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 1780static 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 1788static struct drm_property_blob * 1789ilk_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 1821static 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 1835static struct drm_property_blob * 1836glk_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 1873static 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 1884void 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