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