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