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 u32 color; 1106 1107 crtc_state->gamma_mode = hsw_read_gamma_mode(crtc); 1108 crtc_state->csc_mode = ilk_read_csc_mode(crtc); 1109 1110 color = intel_de_read(display, SKL_BOTTOM_COLOR(crtc->pipe)); 1111 if (DISPLAY_VER(display) < 35) { 1112 if (color & SKL_BOTTOM_COLOR_GAMMA_ENABLE) 1113 crtc_state->gamma_enable = true; 1114 1115 if (color & SKL_BOTTOM_COLOR_CSC_ENABLE) 1116 crtc_state->csc_enable = true; 1117 } 1118 1119 crtc_state->hw.background_color = color & GENMASK(29, 0); 1120 } 1121 1122 u32 intel_color_background_color_drm_to_hw(u64 drm_background_color) 1123 { 1124 return (DRM_ARGB64_GETR_BPC(drm_background_color, 10) << 20) | 1125 (DRM_ARGB64_GETG_BPC(drm_background_color, 10) << 10) | 1126 (DRM_ARGB64_GETB_BPC(drm_background_color, 10)); 1127 } 1128 1129 u64 intel_color_background_color_hw_to_drm(u32 hw_background_color) 1130 { 1131 u16 r = (hw_background_color >> 20) & 0x3ff; 1132 u16 g = (hw_background_color >> 10) & 0x3ff; 1133 u16 b = hw_background_color & 0x3ff; 1134 1135 return DRM_ARGB64_PREP_BPC(0x3ff, r, g, b, 10); 1136 } 1137 1138 static void skl_color_commit_arm(struct intel_dsb *dsb, 1139 const struct intel_crtc_state *crtc_state) 1140 { 1141 struct intel_display *display = to_intel_display(crtc_state); 1142 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1143 enum pipe pipe = crtc->pipe; 1144 u32 val = crtc_state->hw.background_color; 1145 1146 if (crtc_state->has_psr) 1147 ilk_load_csc_matrix(dsb, crtc_state); 1148 1149 if (crtc_state->gamma_enable) 1150 val |= SKL_BOTTOM_COLOR_GAMMA_ENABLE; 1151 if (crtc_state->csc_enable) 1152 val |= SKL_BOTTOM_COLOR_CSC_ENABLE; 1153 intel_de_write_dsb(display, dsb, SKL_BOTTOM_COLOR(pipe), val); 1154 1155 intel_de_write_dsb(display, dsb, GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode); 1156 1157 intel_de_write_dsb(display, dsb, PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode); 1158 } 1159 1160 static void icl_color_commit_arm(struct intel_dsb *dsb, 1161 const struct intel_crtc_state *crtc_state) 1162 { 1163 struct intel_display *display = to_intel_display(crtc_state); 1164 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1165 enum pipe pipe = crtc->pipe; 1166 1167 intel_de_write_dsb(display, dsb, SKL_BOTTOM_COLOR(pipe), crtc_state->hw.background_color); 1168 1169 intel_de_write_dsb(display, dsb, GAMMA_MODE(crtc->pipe), crtc_state->gamma_mode); 1170 1171 intel_de_write_dsb(display, dsb, PIPE_CSC_MODE(crtc->pipe), crtc_state->csc_mode); 1172 } 1173 1174 static void icl_color_post_update(const struct intel_crtc_state *crtc_state) 1175 { 1176 struct intel_display *display = to_intel_display(crtc_state); 1177 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1178 1179 /* 1180 * Despite Wa_1406463849, ICL CSC is no longer disarmed by 1181 * coeff/offset register *writes*. Instead, once CSC_MODE 1182 * is armed it stays armed, even after it has been latched. 1183 * Afterwards the coeff/offset registers become effectively 1184 * self-arming. That self-arming must be disabled before the 1185 * next icl_color_commit_noarm() tries to write the next set 1186 * of coeff/offset registers. Fortunately register *reads* 1187 * do still disarm the CSC. Naturally this must not be done 1188 * until the previously written CSC registers have actually 1189 * been latched. 1190 * 1191 * TGL+ no longer need this workaround. 1192 */ 1193 intel_de_read_fw(display, PIPE_CSC_PREOFF_HI(crtc->pipe)); 1194 } 1195 1196 static struct drm_property_blob * 1197 create_linear_lut(struct intel_display *display, int lut_size) 1198 { 1199 struct drm_property_blob *blob; 1200 struct drm_color_lut *lut; 1201 int i; 1202 1203 blob = drm_property_create_blob(display->drm, 1204 sizeof(lut[0]) * lut_size, 1205 NULL); 1206 if (IS_ERR(blob)) 1207 return blob; 1208 1209 lut = blob->data; 1210 1211 for (i = 0; i < lut_size; i++) { 1212 u16 val = 0xffff * i / (lut_size - 1); 1213 1214 lut[i].red = val; 1215 lut[i].green = val; 1216 lut[i].blue = val; 1217 } 1218 1219 return blob; 1220 } 1221 1222 static u16 lut_limited_range(unsigned int value) 1223 { 1224 unsigned int min = 16 << 8; 1225 unsigned int max = 235 << 8; 1226 1227 return value * (max - min) / 0xffff + min; 1228 } 1229 1230 static struct drm_property_blob * 1231 create_resized_lut(struct intel_display *display, 1232 const struct drm_property_blob *blob_in, int lut_out_size, 1233 bool limited_color_range) 1234 { 1235 int i, lut_in_size = drm_color_lut_size(blob_in); 1236 struct drm_property_blob *blob_out; 1237 const struct drm_color_lut *lut_in; 1238 struct drm_color_lut *lut_out; 1239 1240 blob_out = drm_property_create_blob(display->drm, 1241 sizeof(lut_out[0]) * lut_out_size, 1242 NULL); 1243 if (IS_ERR(blob_out)) 1244 return blob_out; 1245 1246 lut_in = blob_in->data; 1247 lut_out = blob_out->data; 1248 1249 for (i = 0; i < lut_out_size; i++) { 1250 const struct drm_color_lut *entry = 1251 &lut_in[i * (lut_in_size - 1) / (lut_out_size - 1)]; 1252 1253 if (limited_color_range) { 1254 lut_out[i].red = lut_limited_range(entry->red); 1255 lut_out[i].green = lut_limited_range(entry->green); 1256 lut_out[i].blue = lut_limited_range(entry->blue); 1257 } else { 1258 lut_out[i] = *entry; 1259 } 1260 } 1261 1262 return blob_out; 1263 } 1264 1265 static void i9xx_load_lut_8(struct intel_crtc *crtc, 1266 const struct drm_property_blob *blob) 1267 { 1268 struct intel_display *display = to_intel_display(crtc); 1269 const struct drm_color_lut *lut; 1270 enum pipe pipe = crtc->pipe; 1271 int i; 1272 1273 if (!blob) 1274 return; 1275 1276 lut = blob->data; 1277 1278 for (i = 0; i < 256; i++) 1279 intel_de_write_fw(display, PALETTE(display, pipe, i), 1280 i9xx_lut_8(&lut[i])); 1281 } 1282 1283 static void i9xx_load_lut_10(struct intel_crtc *crtc, 1284 const struct drm_property_blob *blob) 1285 { 1286 struct intel_display *display = to_intel_display(crtc); 1287 const struct drm_color_lut *lut = blob->data; 1288 int i, lut_size = drm_color_lut_size(blob); 1289 enum pipe pipe = crtc->pipe; 1290 1291 for (i = 0; i < lut_size - 1; i++) { 1292 intel_de_write_fw(display, 1293 PALETTE(display, pipe, 2 * i + 0), 1294 i9xx_lut_10_ldw(&lut[i])); 1295 intel_de_write_fw(display, 1296 PALETTE(display, pipe, 2 * i + 1), 1297 i9xx_lut_10_udw(&lut[i])); 1298 } 1299 } 1300 1301 static void i9xx_load_luts(const struct intel_crtc_state *crtc_state) 1302 { 1303 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1304 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut; 1305 1306 switch (crtc_state->gamma_mode) { 1307 case GAMMA_MODE_MODE_8BIT: 1308 i9xx_load_lut_8(crtc, post_csc_lut); 1309 break; 1310 case GAMMA_MODE_MODE_10BIT: 1311 i9xx_load_lut_10(crtc, post_csc_lut); 1312 break; 1313 default: 1314 MISSING_CASE(crtc_state->gamma_mode); 1315 break; 1316 } 1317 } 1318 1319 static void i965_load_lut_10p6(struct intel_crtc *crtc, 1320 const struct drm_property_blob *blob) 1321 { 1322 struct intel_display *display = to_intel_display(crtc); 1323 const struct drm_color_lut *lut = blob->data; 1324 int i, lut_size = drm_color_lut_size(blob); 1325 enum pipe pipe = crtc->pipe; 1326 1327 for (i = 0; i < lut_size - 1; i++) { 1328 intel_de_write_fw(display, 1329 PALETTE(display, pipe, 2 * i + 0), 1330 i965_lut_10p6_ldw(&lut[i])); 1331 intel_de_write_fw(display, 1332 PALETTE(display, pipe, 2 * i + 1), 1333 i965_lut_10p6_udw(&lut[i])); 1334 } 1335 1336 intel_de_write_fw(display, PIPEGCMAX(display, pipe, 0), lut[i].red); 1337 intel_de_write_fw(display, PIPEGCMAX(display, pipe, 1), lut[i].green); 1338 intel_de_write_fw(display, PIPEGCMAX(display, pipe, 2), lut[i].blue); 1339 } 1340 1341 static void i965_load_luts(const struct intel_crtc_state *crtc_state) 1342 { 1343 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1344 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut; 1345 1346 switch (crtc_state->gamma_mode) { 1347 case GAMMA_MODE_MODE_8BIT: 1348 i9xx_load_lut_8(crtc, post_csc_lut); 1349 break; 1350 case GAMMA_MODE_MODE_10BIT: 1351 i965_load_lut_10p6(crtc, post_csc_lut); 1352 break; 1353 default: 1354 MISSING_CASE(crtc_state->gamma_mode); 1355 break; 1356 } 1357 } 1358 1359 static void ilk_lut_write(const struct intel_crtc_state *crtc_state, 1360 intel_reg_t reg, u32 val) 1361 { 1362 struct intel_display *display = to_intel_display(crtc_state); 1363 1364 if (crtc_state->dsb_color) 1365 intel_dsb_reg_write(crtc_state->dsb_color, reg, val); 1366 else 1367 intel_de_write_fw(display, reg, val); 1368 } 1369 1370 static void ilk_lut_write_indexed(const struct intel_crtc_state *crtc_state, 1371 intel_reg_t reg, u32 val) 1372 { 1373 struct intel_display *display = to_intel_display(crtc_state); 1374 1375 if (crtc_state->dsb_color) 1376 intel_dsb_reg_write_indexed(crtc_state->dsb_color, reg, val); 1377 else 1378 intel_de_write_fw(display, reg, val); 1379 } 1380 1381 static void ilk_load_lut_8(const struct intel_crtc_state *crtc_state, 1382 const struct drm_property_blob *blob) 1383 { 1384 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1385 const struct drm_color_lut *lut; 1386 enum pipe pipe = crtc->pipe; 1387 int i; 1388 1389 if (!blob) 1390 return; 1391 1392 lut = blob->data; 1393 1394 /* 1395 * DSB fails to correctly load the legacy LUT unless 1396 * we either write each entry twice when using posted 1397 * writes, or we use non-posted writes. 1398 * 1399 * If palette anti-collision is active during LUT 1400 * register writes: 1401 * - posted writes simply get dropped and thus the LUT 1402 * contents may not be correctly updated 1403 * - non-posted writes are blocked and thus the LUT 1404 * contents are always correct, but simultaneous CPU 1405 * MMIO access will start to fail 1406 * 1407 * Choose the lesser of two evils and use posted writes. 1408 * Using posted writes is also faster, even when having 1409 * to write each register twice. 1410 */ 1411 for (i = 0; i < 256; i++) { 1412 ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i), 1413 i9xx_lut_8(&lut[i])); 1414 if (crtc_state->dsb_color) 1415 ilk_lut_write(crtc_state, LGC_PALETTE(pipe, i), 1416 i9xx_lut_8(&lut[i])); 1417 } 1418 } 1419 1420 static void ilk_load_lut_10(const struct intel_crtc_state *crtc_state, 1421 const struct drm_property_blob *blob) 1422 { 1423 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1424 const struct drm_color_lut *lut = blob->data; 1425 int i, lut_size = drm_color_lut_size(blob); 1426 enum pipe pipe = crtc->pipe; 1427 1428 for (i = 0; i < lut_size; i++) 1429 ilk_lut_write(crtc_state, PREC_PALETTE(pipe, i), 1430 ilk_lut_10(&lut[i])); 1431 } 1432 1433 static void ilk_load_luts(const struct intel_crtc_state *crtc_state) 1434 { 1435 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut; 1436 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut; 1437 const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut; 1438 1439 switch (crtc_state->gamma_mode) { 1440 case GAMMA_MODE_MODE_8BIT: 1441 ilk_load_lut_8(crtc_state, blob); 1442 break; 1443 case GAMMA_MODE_MODE_10BIT: 1444 ilk_load_lut_10(crtc_state, blob); 1445 break; 1446 default: 1447 MISSING_CASE(crtc_state->gamma_mode); 1448 break; 1449 } 1450 } 1451 1452 static int ivb_lut_10_size(u32 prec_index) 1453 { 1454 if (prec_index & PAL_PREC_SPLIT_MODE) 1455 return 512; 1456 else 1457 return 1024; 1458 } 1459 1460 /* 1461 * IVB/HSW Bspec / PAL_PREC_INDEX: 1462 * "Restriction : Index auto increment mode is not 1463 * supported and must not be enabled." 1464 */ 1465 static void ivb_load_lut_10(const struct intel_crtc_state *crtc_state, 1466 const struct drm_property_blob *blob, 1467 u32 prec_index) 1468 { 1469 const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1470 const struct drm_color_lut *lut = blob->data; 1471 int i, lut_size = drm_color_lut_size(blob); 1472 enum pipe pipe = crtc->pipe; 1473 1474 for (i = 0; i < lut_size; i++) { 1475 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe), 1476 prec_index + i); 1477 ilk_lut_write(crtc_state, PREC_PAL_DATA(pipe), 1478 ilk_lut_10(&lut[i])); 1479 } 1480 1481 /* 1482 * Reset the index, otherwise it prevents the legacy palette to be 1483 * written properly. 1484 */ 1485 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe), 1486 PAL_PREC_INDEX_VALUE(0)); 1487 } 1488 1489 /* On BDW+ the index auto increment mode actually works */ 1490 static void bdw_load_lut_10(const struct intel_crtc_state *crtc_state, 1491 const struct drm_property_blob *blob, 1492 u32 prec_index) 1493 { 1494 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1495 const struct drm_color_lut *lut = blob->data; 1496 int i, lut_size = drm_color_lut_size(blob); 1497 enum pipe pipe = crtc->pipe; 1498 1499 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe), 1500 prec_index); 1501 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe), 1502 PAL_PREC_AUTO_INCREMENT | 1503 prec_index); 1504 1505 for (i = 0; i < lut_size; i++) 1506 ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe), 1507 ilk_lut_10(&lut[i])); 1508 1509 /* 1510 * Reset the index, otherwise it prevents the legacy palette to be 1511 * written properly. 1512 */ 1513 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe), 1514 PAL_PREC_INDEX_VALUE(0)); 1515 } 1516 1517 static void ivb_load_lut_ext_max(const struct intel_crtc_state *crtc_state) 1518 { 1519 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1520 enum pipe pipe = crtc->pipe; 1521 1522 /* Program the max register to clamp values > 1.0. */ 1523 ilk_lut_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 0), 1 << 16); 1524 ilk_lut_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 1), 1 << 16); 1525 ilk_lut_write(crtc_state, PREC_PAL_EXT_GC_MAX(pipe, 2), 1 << 16); 1526 } 1527 1528 static void glk_load_lut_ext2_max(const struct intel_crtc_state *crtc_state) 1529 { 1530 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1531 enum pipe pipe = crtc->pipe; 1532 1533 /* Program the max register to clamp values > 1.0. */ 1534 ilk_lut_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 0), 1 << 16); 1535 ilk_lut_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 1), 1 << 16); 1536 ilk_lut_write(crtc_state, PREC_PAL_EXT2_GC_MAX(pipe, 2), 1 << 16); 1537 } 1538 1539 static void ivb_load_luts(const struct intel_crtc_state *crtc_state) 1540 { 1541 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut; 1542 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut; 1543 const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut; 1544 1545 switch (crtc_state->gamma_mode) { 1546 case GAMMA_MODE_MODE_8BIT: 1547 ilk_load_lut_8(crtc_state, blob); 1548 break; 1549 case GAMMA_MODE_MODE_SPLIT: 1550 ivb_load_lut_10(crtc_state, pre_csc_lut, PAL_PREC_SPLIT_MODE | 1551 PAL_PREC_INDEX_VALUE(0)); 1552 ivb_load_lut_ext_max(crtc_state); 1553 ivb_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_SPLIT_MODE | 1554 PAL_PREC_INDEX_VALUE(512)); 1555 break; 1556 case GAMMA_MODE_MODE_10BIT: 1557 ivb_load_lut_10(crtc_state, blob, 1558 PAL_PREC_INDEX_VALUE(0)); 1559 ivb_load_lut_ext_max(crtc_state); 1560 break; 1561 default: 1562 MISSING_CASE(crtc_state->gamma_mode); 1563 break; 1564 } 1565 } 1566 1567 static void bdw_load_luts(const struct intel_crtc_state *crtc_state) 1568 { 1569 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut; 1570 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut; 1571 const struct drm_property_blob *blob = post_csc_lut ?: pre_csc_lut; 1572 1573 switch (crtc_state->gamma_mode) { 1574 case GAMMA_MODE_MODE_8BIT: 1575 ilk_load_lut_8(crtc_state, blob); 1576 break; 1577 case GAMMA_MODE_MODE_SPLIT: 1578 bdw_load_lut_10(crtc_state, pre_csc_lut, PAL_PREC_SPLIT_MODE | 1579 PAL_PREC_INDEX_VALUE(0)); 1580 ivb_load_lut_ext_max(crtc_state); 1581 bdw_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_SPLIT_MODE | 1582 PAL_PREC_INDEX_VALUE(512)); 1583 break; 1584 case GAMMA_MODE_MODE_10BIT: 1585 bdw_load_lut_10(crtc_state, blob, 1586 PAL_PREC_INDEX_VALUE(0)); 1587 ivb_load_lut_ext_max(crtc_state); 1588 break; 1589 default: 1590 MISSING_CASE(crtc_state->gamma_mode); 1591 break; 1592 } 1593 } 1594 1595 static int glk_degamma_lut_size(struct intel_display *display) 1596 { 1597 if (DISPLAY_VER(display) >= 13) 1598 return 131; 1599 else 1600 return 35; 1601 } 1602 1603 static u32 glk_degamma_lut(const struct drm_color_lut *color) 1604 { 1605 return color->green; 1606 } 1607 1608 static void glk_degamma_lut_pack(struct drm_color_lut *entry, u32 val) 1609 { 1610 /* PRE_CSC_GAMC_DATA is 3.16, clamp to 0.16 */ 1611 entry->red = entry->green = entry->blue = min(val, 0xffffu); 1612 } 1613 1614 static u32 mtl_degamma_lut(const struct drm_color_lut *color) 1615 { 1616 return drm_color_lut_extract(color->green, 24); 1617 } 1618 1619 static void mtl_degamma_lut_pack(struct drm_color_lut *entry, u32 val) 1620 { 1621 /* PRE_CSC_GAMC_DATA is 3.24, clamp to 0.16 */ 1622 entry->red = entry->green = entry->blue = 1623 intel_color_lut_pack(min(val, 0xffffffu), 24); 1624 } 1625 1626 static void glk_load_degamma_lut(const struct intel_crtc_state *crtc_state, 1627 const struct drm_property_blob *blob) 1628 { 1629 struct intel_display *display = to_intel_display(crtc_state); 1630 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1631 const struct drm_color_lut *lut = blob->data; 1632 int i, lut_size = drm_color_lut_size(blob); 1633 enum pipe pipe = crtc->pipe; 1634 1635 /* 1636 * When setting the auto-increment bit, the hardware seems to 1637 * ignore the index bits, so we need to reset it to index 0 1638 * separately. 1639 */ 1640 ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe), 1641 PRE_CSC_GAMC_INDEX_VALUE(0)); 1642 ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe), 1643 PRE_CSC_GAMC_AUTO_INCREMENT | 1644 PRE_CSC_GAMC_INDEX_VALUE(0)); 1645 1646 for (i = 0; i < lut_size; i++) { 1647 /* 1648 * First lut_size entries represent range from 0 to 1.0 1649 * 3 additional lut entries will represent extended range 1650 * inputs 3.0 and 7.0 respectively, currently clamped 1651 * at 1.0. Since the precision is 16bit, the user 1652 * value can be directly filled to register. 1653 * The pipe degamma table in GLK+ onwards doesn't 1654 * support different values per channel, so this just 1655 * programs green value which will be equal to Red and 1656 * Blue into the lut registers. 1657 * ToDo: Extend to max 7.0. Enable 32 bit input value 1658 * as compared to just 16 to achieve this. 1659 */ 1660 ilk_lut_write_indexed(crtc_state, PRE_CSC_GAMC_DATA(pipe), 1661 DISPLAY_VER(display) >= 14 ? 1662 mtl_degamma_lut(&lut[i]) : glk_degamma_lut(&lut[i])); 1663 } 1664 1665 /* Clamp values > 1.0. */ 1666 while (i++ < glk_degamma_lut_size(display)) 1667 ilk_lut_write_indexed(crtc_state, PRE_CSC_GAMC_DATA(pipe), 1668 DISPLAY_VER(display) >= 14 ? 1669 1 << 24 : 1 << 16); 1670 1671 ilk_lut_write(crtc_state, PRE_CSC_GAMC_INDEX(pipe), 0); 1672 } 1673 1674 static void glk_load_luts(const struct intel_crtc_state *crtc_state) 1675 { 1676 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut; 1677 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut; 1678 1679 if (pre_csc_lut) 1680 glk_load_degamma_lut(crtc_state, pre_csc_lut); 1681 1682 switch (crtc_state->gamma_mode) { 1683 case GAMMA_MODE_MODE_8BIT: 1684 ilk_load_lut_8(crtc_state, post_csc_lut); 1685 break; 1686 case GAMMA_MODE_MODE_10BIT: 1687 bdw_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_INDEX_VALUE(0)); 1688 ivb_load_lut_ext_max(crtc_state); 1689 glk_load_lut_ext2_max(crtc_state); 1690 break; 1691 default: 1692 MISSING_CASE(crtc_state->gamma_mode); 1693 break; 1694 } 1695 } 1696 1697 static void 1698 ivb_load_lut_max(const struct intel_crtc_state *crtc_state, 1699 const struct drm_color_lut *color) 1700 { 1701 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1702 enum pipe pipe = crtc->pipe; 1703 1704 /* FIXME LUT entries are 16 bit only, so we can prog 0xFFFF max */ 1705 ilk_lut_write(crtc_state, PREC_PAL_GC_MAX(pipe, 0), color->red); 1706 ilk_lut_write(crtc_state, PREC_PAL_GC_MAX(pipe, 1), color->green); 1707 ilk_lut_write(crtc_state, PREC_PAL_GC_MAX(pipe, 2), color->blue); 1708 } 1709 1710 static void 1711 icl_program_gamma_superfine_segment(const struct intel_crtc_state *crtc_state) 1712 { 1713 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1714 const struct drm_property_blob *blob = crtc_state->post_csc_lut; 1715 const struct drm_color_lut *lut = blob->data; 1716 enum pipe pipe = crtc->pipe; 1717 int i; 1718 1719 /* 1720 * Program Super Fine segment (let's call it seg1)... 1721 * 1722 * Super Fine segment's step is 1/(8 * 128 * 256) and it has 1723 * 9 entries, corresponding to values 0, 1/(8 * 128 * 256), 1724 * 2/(8 * 128 * 256) ... 8/(8 * 128 * 256). 1725 */ 1726 ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe), 1727 PAL_PREC_MULTI_SEG_INDEX_VALUE(0)); 1728 ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe), 1729 PAL_PREC_AUTO_INCREMENT | 1730 PAL_PREC_MULTI_SEG_INDEX_VALUE(0)); 1731 1732 for (i = 0; i < 9; i++) { 1733 const struct drm_color_lut *entry = &lut[i]; 1734 1735 ilk_lut_write_indexed(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe), 1736 ilk_lut_12p4_ldw(entry)); 1737 ilk_lut_write_indexed(crtc_state, PREC_PAL_MULTI_SEG_DATA(pipe), 1738 ilk_lut_12p4_udw(entry)); 1739 } 1740 1741 ilk_lut_write(crtc_state, PREC_PAL_MULTI_SEG_INDEX(pipe), 1742 PAL_PREC_MULTI_SEG_INDEX_VALUE(0)); 1743 } 1744 1745 static void 1746 icl_program_gamma_multi_segment(const struct intel_crtc_state *crtc_state) 1747 { 1748 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1749 const struct drm_property_blob *blob = crtc_state->post_csc_lut; 1750 const struct drm_color_lut *lut = blob->data; 1751 const struct drm_color_lut *entry; 1752 enum pipe pipe = crtc->pipe; 1753 int i; 1754 1755 /* 1756 * Program Fine segment (let's call it seg2)... 1757 * 1758 * Fine segment's step is 1/(128 * 256) i.e. 1/(128 * 256), 2/(128 * 256) 1759 * ... 256/(128 * 256). So in order to program fine segment of LUT we 1760 * need to pick every 8th entry in the LUT, and program 256 indexes. 1761 * 1762 * PAL_PREC_INDEX[0] and PAL_PREC_INDEX[1] map to seg2[1], 1763 * seg2[0] being unused by the hardware. 1764 */ 1765 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe), 1766 PAL_PREC_INDEX_VALUE(0)); 1767 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe), 1768 PAL_PREC_AUTO_INCREMENT | 1769 PAL_PREC_INDEX_VALUE(0)); 1770 1771 for (i = 1; i < 257; i++) { 1772 entry = &lut[i * 8]; 1773 1774 ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe), 1775 ilk_lut_12p4_ldw(entry)); 1776 ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe), 1777 ilk_lut_12p4_udw(entry)); 1778 } 1779 1780 /* 1781 * Program Coarse segment (let's call it seg3)... 1782 * 1783 * Coarse segment starts from index 0 and it's step is 1/256 ie 0, 1784 * 1/256, 2/256 ... 256/256. As per the description of each entry in LUT 1785 * above, we need to pick every (8 * 128)th entry in LUT, and 1786 * program 256 of those. 1787 * 1788 * Spec is not very clear about if entries seg3[0] and seg3[1] are 1789 * being used or not, but we still need to program these to advance 1790 * the index. 1791 */ 1792 for (i = 0; i < 256; i++) { 1793 entry = &lut[i * 8 * 128]; 1794 1795 ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe), 1796 ilk_lut_12p4_ldw(entry)); 1797 ilk_lut_write_indexed(crtc_state, PREC_PAL_DATA(pipe), 1798 ilk_lut_12p4_udw(entry)); 1799 } 1800 1801 ilk_lut_write(crtc_state, PREC_PAL_INDEX(pipe), 1802 PAL_PREC_INDEX_VALUE(0)); 1803 1804 /* The last entry in the LUT is to be programmed in GCMAX */ 1805 entry = &lut[256 * 8 * 128]; 1806 ivb_load_lut_max(crtc_state, entry); 1807 } 1808 1809 static void icl_load_luts(const struct intel_crtc_state *crtc_state) 1810 { 1811 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut; 1812 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut; 1813 1814 if (pre_csc_lut) 1815 glk_load_degamma_lut(crtc_state, pre_csc_lut); 1816 1817 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) { 1818 case GAMMA_MODE_MODE_8BIT: 1819 ilk_load_lut_8(crtc_state, post_csc_lut); 1820 break; 1821 case GAMMA_MODE_MODE_12BIT_MULTI_SEG: 1822 icl_program_gamma_superfine_segment(crtc_state); 1823 icl_program_gamma_multi_segment(crtc_state); 1824 ivb_load_lut_ext_max(crtc_state); 1825 glk_load_lut_ext2_max(crtc_state); 1826 break; 1827 case GAMMA_MODE_MODE_10BIT: 1828 bdw_load_lut_10(crtc_state, post_csc_lut, PAL_PREC_INDEX_VALUE(0)); 1829 ivb_load_lut_ext_max(crtc_state); 1830 glk_load_lut_ext2_max(crtc_state); 1831 break; 1832 default: 1833 MISSING_CASE(crtc_state->gamma_mode); 1834 break; 1835 } 1836 } 1837 1838 static void vlv_load_luts(const struct intel_crtc_state *crtc_state) 1839 { 1840 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1841 1842 if (crtc_state->wgc_enable) 1843 vlv_load_wgc_csc(crtc, &crtc_state->csc); 1844 1845 i965_load_luts(crtc_state); 1846 } 1847 1848 static u32 chv_cgm_degamma_ldw(const struct drm_color_lut *color) 1849 { 1850 return REG_FIELD_PREP(CGM_PIPE_DEGAMMA_GREEN_LDW_MASK, drm_color_lut_extract(color->green, 14)) | 1851 REG_FIELD_PREP(CGM_PIPE_DEGAMMA_BLUE_LDW_MASK, drm_color_lut_extract(color->blue, 14)); 1852 } 1853 1854 static u32 chv_cgm_degamma_udw(const struct drm_color_lut *color) 1855 { 1856 return REG_FIELD_PREP(CGM_PIPE_DEGAMMA_RED_UDW_MASK, drm_color_lut_extract(color->red, 14)); 1857 } 1858 1859 static void chv_cgm_degamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw) 1860 { 1861 entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_DEGAMMA_GREEN_LDW_MASK, ldw), 14); 1862 entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_DEGAMMA_BLUE_LDW_MASK, ldw), 14); 1863 entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_DEGAMMA_RED_UDW_MASK, udw), 14); 1864 } 1865 1866 static void chv_load_cgm_degamma(struct intel_crtc *crtc, 1867 const struct drm_property_blob *blob) 1868 { 1869 struct intel_display *display = to_intel_display(crtc); 1870 const struct drm_color_lut *lut = blob->data; 1871 int i, lut_size = drm_color_lut_size(blob); 1872 enum pipe pipe = crtc->pipe; 1873 1874 for (i = 0; i < lut_size; i++) { 1875 intel_de_write_fw(display, CGM_PIPE_DEGAMMA(pipe, i, 0), 1876 chv_cgm_degamma_ldw(&lut[i])); 1877 intel_de_write_fw(display, CGM_PIPE_DEGAMMA(pipe, i, 1), 1878 chv_cgm_degamma_udw(&lut[i])); 1879 } 1880 } 1881 1882 static u32 chv_cgm_gamma_ldw(const struct drm_color_lut *color) 1883 { 1884 return REG_FIELD_PREP(CGM_PIPE_GAMMA_GREEN_LDW_MASK, drm_color_lut_extract(color->green, 10)) | 1885 REG_FIELD_PREP(CGM_PIPE_GAMMA_BLUE_LDW_MASK, drm_color_lut_extract(color->blue, 10)); 1886 } 1887 1888 static u32 chv_cgm_gamma_udw(const struct drm_color_lut *color) 1889 { 1890 return REG_FIELD_PREP(CGM_PIPE_GAMMA_RED_UDW_MASK, drm_color_lut_extract(color->red, 10)); 1891 } 1892 1893 static void chv_cgm_gamma_pack(struct drm_color_lut *entry, u32 ldw, u32 udw) 1894 { 1895 entry->green = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_GREEN_LDW_MASK, ldw), 10); 1896 entry->blue = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_BLUE_LDW_MASK, ldw), 10); 1897 entry->red = intel_color_lut_pack(REG_FIELD_GET(CGM_PIPE_GAMMA_RED_UDW_MASK, udw), 10); 1898 } 1899 1900 static void chv_load_cgm_gamma(struct intel_crtc *crtc, 1901 const struct drm_property_blob *blob) 1902 { 1903 struct intel_display *display = to_intel_display(crtc); 1904 const struct drm_color_lut *lut = blob->data; 1905 int i, lut_size = drm_color_lut_size(blob); 1906 enum pipe pipe = crtc->pipe; 1907 1908 for (i = 0; i < lut_size; i++) { 1909 intel_de_write_fw(display, CGM_PIPE_GAMMA(pipe, i, 0), 1910 chv_cgm_gamma_ldw(&lut[i])); 1911 intel_de_write_fw(display, CGM_PIPE_GAMMA(pipe, i, 1), 1912 chv_cgm_gamma_udw(&lut[i])); 1913 } 1914 } 1915 1916 static void chv_load_luts(const struct intel_crtc_state *crtc_state) 1917 { 1918 struct intel_display *display = to_intel_display(crtc_state); 1919 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1920 const struct drm_property_blob *pre_csc_lut = crtc_state->pre_csc_lut; 1921 const struct drm_property_blob *post_csc_lut = crtc_state->post_csc_lut; 1922 1923 if (crtc_state->cgm_mode & CGM_PIPE_MODE_CSC) 1924 chv_load_cgm_csc(crtc, &crtc_state->csc); 1925 1926 if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA) 1927 chv_load_cgm_degamma(crtc, pre_csc_lut); 1928 1929 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA) 1930 chv_load_cgm_gamma(crtc, post_csc_lut); 1931 else 1932 i965_load_luts(crtc_state); 1933 1934 intel_de_write_fw(display, CGM_PIPE_MODE(crtc->pipe), 1935 crtc_state->cgm_mode); 1936 } 1937 1938 void intel_color_load_luts(const struct intel_crtc_state *crtc_state) 1939 { 1940 struct intel_display *display = to_intel_display(crtc_state); 1941 1942 if (crtc_state->dsb_color) 1943 return; 1944 1945 display->color.funcs->load_luts(crtc_state); 1946 } 1947 1948 void intel_color_commit_noarm(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 if (display->color.funcs->color_commit_noarm) 1954 display->color.funcs->color_commit_noarm(dsb, crtc_state); 1955 } 1956 1957 void intel_color_commit_arm(struct intel_dsb *dsb, 1958 const struct intel_crtc_state *crtc_state) 1959 { 1960 struct intel_display *display = to_intel_display(crtc_state); 1961 1962 display->color.funcs->color_commit_arm(dsb, crtc_state); 1963 } 1964 1965 void intel_color_post_update(const struct intel_crtc_state *crtc_state) 1966 { 1967 struct intel_display *display = to_intel_display(crtc_state); 1968 1969 if (display->color.funcs->color_post_update) 1970 display->color.funcs->color_post_update(crtc_state); 1971 } 1972 1973 void intel_color_modeset(const struct intel_crtc_state *crtc_state) 1974 { 1975 struct intel_display *display = to_intel_display(crtc_state); 1976 1977 intel_color_load_luts(crtc_state); 1978 intel_color_commit_noarm(NULL, crtc_state); 1979 intel_color_commit_arm(NULL, crtc_state); 1980 1981 if (DISPLAY_VER(display) < 9) { 1982 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 1983 struct intel_plane *plane = to_intel_plane(crtc->base.primary); 1984 1985 /* update DSPCNTR to configure gamma/csc for pipe bottom color */ 1986 plane->disable_arm(NULL, plane, crtc_state); 1987 } 1988 } 1989 1990 bool intel_color_uses_dsb(const struct intel_crtc_state *crtc_state) 1991 { 1992 return crtc_state->dsb_color; 1993 } 1994 1995 bool intel_color_uses_chained_dsb(const struct intel_crtc_state *crtc_state) 1996 { 1997 struct intel_display *display = to_intel_display(crtc_state); 1998 1999 return crtc_state->dsb_color && !HAS_DOUBLE_BUFFERED_LUT(display); 2000 } 2001 2002 bool intel_color_uses_gosub_dsb(const struct intel_crtc_state *crtc_state) 2003 { 2004 struct intel_display *display = to_intel_display(crtc_state); 2005 2006 return crtc_state->dsb_color && HAS_DOUBLE_BUFFERED_LUT(display); 2007 } 2008 2009 void intel_color_prepare_commit(struct intel_atomic_state *state, 2010 struct intel_crtc *crtc) 2011 { 2012 struct intel_display *display = to_intel_display(state); 2013 struct intel_crtc_state *crtc_state = 2014 intel_atomic_get_new_crtc_state(state, crtc); 2015 2016 if (!crtc_state->hw.active || 2017 intel_crtc_needs_modeset(crtc_state)) 2018 return; 2019 2020 if (!intel_crtc_needs_color_update(crtc_state)) 2021 return; 2022 2023 if (!crtc_state->pre_csc_lut && !crtc_state->post_csc_lut) 2024 return; 2025 2026 if (HAS_DOUBLE_BUFFERED_LUT(display)) 2027 crtc_state->dsb_color = intel_dsb_prepare(state, crtc, INTEL_DSB_0, 1024); 2028 else 2029 crtc_state->dsb_color = intel_dsb_prepare(state, crtc, INTEL_DSB_1, 1024); 2030 2031 if (!intel_color_uses_dsb(crtc_state)) 2032 return; 2033 2034 display->color.funcs->load_luts(crtc_state); 2035 2036 if (crtc_state->use_dsb && intel_color_uses_chained_dsb(crtc_state)) { 2037 intel_vrr_send_push(crtc_state->dsb_color, crtc_state); 2038 intel_dsb_wait_for_delayed_vblank(state, crtc_state->dsb_color); 2039 intel_vrr_check_push_sent(crtc_state->dsb_color, crtc_state); 2040 intel_dsb_interrupt(crtc_state->dsb_color); 2041 } 2042 2043 if (intel_color_uses_gosub_dsb(crtc_state)) 2044 intel_dsb_gosub_finish(crtc_state->dsb_color); 2045 else 2046 intel_dsb_finish(crtc_state->dsb_color); 2047 } 2048 2049 void intel_color_cleanup_commit(struct intel_crtc_state *crtc_state) 2050 { 2051 if (crtc_state->dsb_color) { 2052 intel_dsb_cleanup(crtc_state->dsb_color); 2053 crtc_state->dsb_color = NULL; 2054 } 2055 } 2056 2057 void intel_color_wait_commit(const struct intel_crtc_state *crtc_state) 2058 { 2059 if (crtc_state->dsb_color) 2060 intel_dsb_wait(crtc_state->dsb_color); 2061 } 2062 2063 static bool intel_can_preload_luts(struct intel_atomic_state *state, 2064 struct intel_crtc *crtc) 2065 { 2066 struct intel_display *display = to_intel_display(state); 2067 const struct intel_crtc_state *old_crtc_state = 2068 intel_atomic_get_old_crtc_state(state, crtc); 2069 2070 if (HAS_DOUBLE_BUFFERED_LUT(display)) 2071 return false; 2072 2073 return !old_crtc_state->post_csc_lut && 2074 !old_crtc_state->pre_csc_lut; 2075 } 2076 2077 static bool vlv_can_preload_luts(struct intel_atomic_state *state, 2078 struct intel_crtc *crtc) 2079 { 2080 const struct intel_crtc_state *old_crtc_state = 2081 intel_atomic_get_old_crtc_state(state, crtc); 2082 2083 return !old_crtc_state->wgc_enable && 2084 !old_crtc_state->post_csc_lut; 2085 } 2086 2087 static bool chv_can_preload_luts(struct intel_atomic_state *state, 2088 struct intel_crtc *crtc) 2089 { 2090 const struct intel_crtc_state *old_crtc_state = 2091 intel_atomic_get_old_crtc_state(state, crtc); 2092 const struct intel_crtc_state *new_crtc_state = 2093 intel_atomic_get_new_crtc_state(state, crtc); 2094 2095 /* 2096 * CGM_PIPE_MODE is itself single buffered. We'd have to 2097 * somehow split it out from chv_load_luts() if we wanted 2098 * the ability to preload the CGM LUTs/CSC without tearing. 2099 */ 2100 if (old_crtc_state->cgm_mode || new_crtc_state->cgm_mode) 2101 return false; 2102 2103 return vlv_can_preload_luts(state, crtc); 2104 } 2105 2106 int intel_color_check(struct intel_atomic_state *state, 2107 struct intel_crtc *crtc) 2108 { 2109 struct intel_display *display = to_intel_display(state); 2110 const struct intel_crtc_state *old_crtc_state = 2111 intel_atomic_get_old_crtc_state(state, crtc); 2112 struct intel_crtc_state *new_crtc_state = 2113 intel_atomic_get_new_crtc_state(state, crtc); 2114 2115 /* 2116 * May need to update pipe gamma enable bits 2117 * when C8 planes are getting enabled/disabled. 2118 */ 2119 if (!old_crtc_state->c8_planes != !new_crtc_state->c8_planes || 2120 old_crtc_state->hw.background_color != new_crtc_state->hw.background_color) 2121 new_crtc_state->uapi.color_mgmt_changed = true; 2122 2123 if (DRM_ARGB64_GETA(new_crtc_state->uapi.background_color) != 0xffff) { 2124 drm_dbg_kms(display->drm, "New background not completely opaque\n"); 2125 return -EINVAL; 2126 } 2127 2128 if (!intel_crtc_needs_color_update(new_crtc_state)) 2129 return 0; 2130 2131 return display->color.funcs->color_check(state, crtc); 2132 } 2133 2134 void intel_color_get_config(struct intel_crtc_state *crtc_state) 2135 { 2136 struct intel_display *display = to_intel_display(crtc_state); 2137 2138 display->color.funcs->get_config(crtc_state); 2139 2140 display->color.funcs->read_luts(crtc_state); 2141 2142 if (display->color.funcs->read_csc) 2143 display->color.funcs->read_csc(crtc_state); 2144 } 2145 2146 bool intel_color_lut_equal(const struct intel_crtc_state *crtc_state, 2147 const struct drm_property_blob *blob1, 2148 const struct drm_property_blob *blob2, 2149 bool is_pre_csc_lut) 2150 { 2151 struct intel_display *display = to_intel_display(crtc_state); 2152 2153 /* 2154 * FIXME c8_planes readout missing thus 2155 * .read_luts() doesn't read out post_csc_lut. 2156 */ 2157 if (!is_pre_csc_lut && crtc_state->c8_planes) 2158 return true; 2159 2160 return display->color.funcs->lut_equal(crtc_state, blob1, blob2, 2161 is_pre_csc_lut); 2162 } 2163 2164 static bool need_plane_update(struct intel_plane *plane, 2165 const struct intel_crtc_state *crtc_state) 2166 { 2167 struct intel_display *display = to_intel_display(plane); 2168 2169 /* 2170 * On pre-SKL the pipe gamma enable and pipe csc enable for 2171 * the pipe bottom color are configured via the primary plane. 2172 * We have to reconfigure that even if the plane is inactive. 2173 */ 2174 return crtc_state->active_planes & BIT(plane->id) || 2175 (DISPLAY_VER(display) < 9 && plane->id == PLANE_PRIMARY); 2176 } 2177 2178 static int 2179 intel_color_add_affected_planes(struct intel_atomic_state *state, 2180 struct intel_crtc *crtc) 2181 { 2182 struct intel_display *display = to_intel_display(state); 2183 const struct intel_crtc_state *old_crtc_state = 2184 intel_atomic_get_old_crtc_state(state, crtc); 2185 struct intel_crtc_state *new_crtc_state = 2186 intel_atomic_get_new_crtc_state(state, crtc); 2187 struct intel_plane *plane; 2188 2189 if (!new_crtc_state->hw.active || 2190 intel_crtc_needs_modeset(new_crtc_state)) 2191 return 0; 2192 2193 if (new_crtc_state->gamma_enable == old_crtc_state->gamma_enable && 2194 new_crtc_state->csc_enable == old_crtc_state->csc_enable) 2195 return 0; 2196 2197 for_each_intel_plane_on_crtc(display->drm, crtc, plane) { 2198 struct intel_plane_state *plane_state; 2199 2200 if (!need_plane_update(plane, new_crtc_state)) 2201 continue; 2202 2203 plane_state = intel_atomic_get_plane_state(state, plane); 2204 if (IS_ERR(plane_state)) 2205 return PTR_ERR(plane_state); 2206 2207 new_crtc_state->update_planes |= BIT(plane->id); 2208 new_crtc_state->async_flip_planes = 0; 2209 new_crtc_state->do_async_flip = false; 2210 2211 /* plane control register changes blocked by CxSR */ 2212 if (HAS_GMCH(display)) 2213 new_crtc_state->disable_cxsr = true; 2214 } 2215 2216 return 0; 2217 } 2218 2219 static u32 intel_gamma_lut_tests(const struct intel_crtc_state *crtc_state) 2220 { 2221 struct intel_display *display = to_intel_display(crtc_state); 2222 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut; 2223 2224 if (lut_is_legacy(gamma_lut)) 2225 return 0; 2226 2227 return DISPLAY_INFO(display)->color.gamma_lut_tests; 2228 } 2229 2230 static u32 intel_degamma_lut_tests(const struct intel_crtc_state *crtc_state) 2231 { 2232 struct intel_display *display = to_intel_display(crtc_state); 2233 2234 return DISPLAY_INFO(display)->color.degamma_lut_tests; 2235 } 2236 2237 static int intel_gamma_lut_size(const struct intel_crtc_state *crtc_state) 2238 { 2239 struct intel_display *display = to_intel_display(crtc_state); 2240 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut; 2241 2242 if (lut_is_legacy(gamma_lut)) 2243 return LEGACY_LUT_LENGTH; 2244 2245 return DISPLAY_INFO(display)->color.gamma_lut_size; 2246 } 2247 2248 static u32 intel_degamma_lut_size(const struct intel_crtc_state *crtc_state) 2249 { 2250 struct intel_display *display = to_intel_display(crtc_state); 2251 2252 return DISPLAY_INFO(display)->color.degamma_lut_size; 2253 } 2254 2255 static int check_lut_size(struct intel_crtc *crtc, const char *lut_name, 2256 const struct drm_property_blob *lut, int expected) 2257 { 2258 struct intel_display *display = to_intel_display(crtc); 2259 int len; 2260 2261 if (!lut) 2262 return 0; 2263 2264 len = drm_color_lut_size(lut); 2265 if (len != expected) { 2266 drm_dbg_kms(display->drm, 2267 "[CRTC:%d:%s] Invalid %s LUT size; got %d, expected %d\n", 2268 crtc->base.base.id, crtc->base.name, lut_name, len, expected); 2269 return -EINVAL; 2270 } 2271 2272 return 0; 2273 } 2274 2275 static int _check_luts(const struct intel_crtc_state *crtc_state, 2276 u32 degamma_tests, u32 gamma_tests) 2277 { 2278 struct intel_display *display = to_intel_display(crtc_state); 2279 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 2280 const struct drm_property_blob *gamma_lut = crtc_state->hw.gamma_lut; 2281 const struct drm_property_blob *degamma_lut = crtc_state->hw.degamma_lut; 2282 int gamma_length, degamma_length; 2283 2284 /* C8 relies on its palette being stored in the legacy LUT */ 2285 if (crtc_state->c8_planes && !lut_is_legacy(crtc_state->hw.gamma_lut)) { 2286 drm_dbg_kms(display->drm, 2287 "[CRTC:%d:%s] C8 pixelformat requires the legacy LUT\n", 2288 crtc->base.base.id, crtc->base.name); 2289 return -EINVAL; 2290 } 2291 2292 degamma_length = intel_degamma_lut_size(crtc_state); 2293 gamma_length = intel_gamma_lut_size(crtc_state); 2294 2295 if (check_lut_size(crtc, "degamma", degamma_lut, degamma_length) || 2296 check_lut_size(crtc, "gamma", gamma_lut, gamma_length)) 2297 return -EINVAL; 2298 2299 if (drm_color_lut_check(degamma_lut, degamma_tests) || 2300 drm_color_lut_check(gamma_lut, gamma_tests)) 2301 return -EINVAL; 2302 2303 return 0; 2304 } 2305 2306 static int check_luts(const struct intel_crtc_state *crtc_state) 2307 { 2308 return _check_luts(crtc_state, 2309 intel_degamma_lut_tests(crtc_state), 2310 intel_gamma_lut_tests(crtc_state)); 2311 } 2312 2313 static u32 i9xx_gamma_mode(struct intel_crtc_state *crtc_state) 2314 { 2315 if (!crtc_state->gamma_enable || 2316 lut_is_legacy(crtc_state->hw.gamma_lut)) 2317 return GAMMA_MODE_MODE_8BIT; 2318 else 2319 return GAMMA_MODE_MODE_10BIT; 2320 } 2321 2322 static int i9xx_lut_10_diff(u16 a, u16 b) 2323 { 2324 return drm_color_lut_extract(a, 10) - 2325 drm_color_lut_extract(b, 10); 2326 } 2327 2328 static int i9xx_check_lut_10(struct intel_crtc *crtc, 2329 const struct drm_property_blob *blob) 2330 { 2331 struct intel_display *display = to_intel_display(crtc); 2332 const struct drm_color_lut *lut = blob->data; 2333 int lut_size = drm_color_lut_size(blob); 2334 const struct drm_color_lut *a = &lut[lut_size - 2]; 2335 const struct drm_color_lut *b = &lut[lut_size - 1]; 2336 2337 if (i9xx_lut_10_diff(b->red, a->red) > 0x7f || 2338 i9xx_lut_10_diff(b->green, a->green) > 0x7f || 2339 i9xx_lut_10_diff(b->blue, a->blue) > 0x7f) { 2340 drm_dbg_kms(display->drm, 2341 "[CRTC:%d:%s] Last gamma LUT entry exceeds max slope\n", 2342 crtc->base.base.id, crtc->base.name); 2343 return -EINVAL; 2344 } 2345 2346 return 0; 2347 } 2348 2349 void intel_color_assert_luts(const struct intel_crtc_state *crtc_state) 2350 { 2351 struct intel_display *display = to_intel_display(crtc_state); 2352 2353 /* make sure {pre,post}_csc_lut were correctly assigned */ 2354 if (DISPLAY_VER(display) >= 11 || HAS_GMCH(display)) { 2355 drm_WARN_ON(display->drm, 2356 crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut); 2357 drm_WARN_ON(display->drm, 2358 crtc_state->post_csc_lut != crtc_state->hw.gamma_lut); 2359 } else if (DISPLAY_VER(display) == 10) { 2360 drm_WARN_ON(display->drm, 2361 crtc_state->post_csc_lut == crtc_state->hw.gamma_lut && 2362 crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut && 2363 crtc_state->pre_csc_lut != display->color.glk_linear_degamma_lut); 2364 drm_WARN_ON(display->drm, 2365 !ilk_lut_limited_range(crtc_state) && 2366 crtc_state->post_csc_lut != NULL && 2367 crtc_state->post_csc_lut != crtc_state->hw.gamma_lut); 2368 } else if (crtc_state->gamma_mode != GAMMA_MODE_MODE_SPLIT) { 2369 drm_WARN_ON(display->drm, 2370 crtc_state->pre_csc_lut != crtc_state->hw.degamma_lut && 2371 crtc_state->pre_csc_lut != crtc_state->hw.gamma_lut); 2372 drm_WARN_ON(display->drm, 2373 !ilk_lut_limited_range(crtc_state) && 2374 crtc_state->post_csc_lut != crtc_state->hw.degamma_lut && 2375 crtc_state->post_csc_lut != crtc_state->hw.gamma_lut); 2376 } 2377 } 2378 2379 static void intel_assign_luts(struct intel_crtc_state *crtc_state) 2380 { 2381 drm_property_replace_blob(&crtc_state->pre_csc_lut, 2382 crtc_state->hw.degamma_lut); 2383 drm_property_replace_blob(&crtc_state->post_csc_lut, 2384 crtc_state->hw.gamma_lut); 2385 } 2386 2387 static int i9xx_color_check(struct intel_atomic_state *state, 2388 struct intel_crtc *crtc) 2389 { 2390 struct intel_display *display = to_intel_display(state); 2391 struct intel_crtc_state *crtc_state = 2392 intel_atomic_get_new_crtc_state(state, crtc); 2393 int ret; 2394 2395 ret = check_luts(crtc_state); 2396 if (ret) 2397 return ret; 2398 2399 crtc_state->gamma_enable = 2400 crtc_state->hw.gamma_lut && 2401 !crtc_state->c8_planes; 2402 2403 crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state); 2404 2405 if (DISPLAY_VER(display) < 4 && 2406 crtc_state->gamma_mode == GAMMA_MODE_MODE_10BIT) { 2407 ret = i9xx_check_lut_10(crtc, crtc_state->hw.gamma_lut); 2408 if (ret) 2409 return ret; 2410 } 2411 2412 ret = intel_color_add_affected_planes(state, crtc); 2413 if (ret) 2414 return ret; 2415 2416 intel_assign_luts(crtc_state); 2417 2418 crtc_state->preload_luts = intel_can_preload_luts(state, crtc); 2419 2420 return 0; 2421 } 2422 2423 /* 2424 * VLV color pipeline: 2425 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10 2426 */ 2427 static int vlv_color_check(struct intel_atomic_state *state, 2428 struct intel_crtc *crtc) 2429 { 2430 struct intel_crtc_state *crtc_state = 2431 intel_atomic_get_new_crtc_state(state, crtc); 2432 int ret; 2433 2434 ret = check_luts(crtc_state); 2435 if (ret) 2436 return ret; 2437 2438 crtc_state->gamma_enable = 2439 crtc_state->hw.gamma_lut && 2440 !crtc_state->c8_planes; 2441 2442 crtc_state->gamma_mode = i9xx_gamma_mode(crtc_state); 2443 2444 crtc_state->wgc_enable = crtc_state->hw.ctm; 2445 2446 ret = intel_color_add_affected_planes(state, crtc); 2447 if (ret) 2448 return ret; 2449 2450 intel_assign_luts(crtc_state); 2451 2452 vlv_assign_csc(crtc_state); 2453 2454 crtc_state->preload_luts = vlv_can_preload_luts(state, crtc); 2455 2456 return 0; 2457 } 2458 2459 static u32 chv_cgm_mode(const struct intel_crtc_state *crtc_state) 2460 { 2461 u32 cgm_mode = 0; 2462 2463 if (crtc_state->hw.degamma_lut) 2464 cgm_mode |= CGM_PIPE_MODE_DEGAMMA; 2465 if (crtc_state->hw.ctm) 2466 cgm_mode |= CGM_PIPE_MODE_CSC; 2467 if (crtc_state->hw.gamma_lut && 2468 !lut_is_legacy(crtc_state->hw.gamma_lut)) 2469 cgm_mode |= CGM_PIPE_MODE_GAMMA; 2470 2471 /* 2472 * Toggling the CGM CSC on/off outside of the tiny window 2473 * between start of vblank and frame start causes underruns. 2474 * Always enable the CGM CSC as a workaround. 2475 */ 2476 cgm_mode |= CGM_PIPE_MODE_CSC; 2477 2478 return cgm_mode; 2479 } 2480 2481 /* 2482 * CHV color pipeline: 2483 * u0.10 -> CGM degamma -> u0.14 -> CGM csc -> u0.14 -> CGM gamma -> 2484 * u0.10 -> WGC csc -> u0.10 -> pipe gamma -> u0.10 2485 * 2486 * We always bypass the WGC csc and use the CGM csc 2487 * instead since it has degamma and better precision. 2488 */ 2489 static int chv_color_check(struct intel_atomic_state *state, 2490 struct intel_crtc *crtc) 2491 { 2492 struct intel_crtc_state *crtc_state = 2493 intel_atomic_get_new_crtc_state(state, crtc); 2494 int ret; 2495 2496 ret = check_luts(crtc_state); 2497 if (ret) 2498 return ret; 2499 2500 /* 2501 * Pipe gamma will be used only for the legacy LUT. 2502 * Otherwise we bypass it and use the CGM gamma instead. 2503 */ 2504 crtc_state->gamma_enable = 2505 lut_is_legacy(crtc_state->hw.gamma_lut) && 2506 !crtc_state->c8_planes; 2507 2508 crtc_state->gamma_mode = GAMMA_MODE_MODE_8BIT; 2509 2510 crtc_state->cgm_mode = chv_cgm_mode(crtc_state); 2511 2512 /* 2513 * We always bypass the WGC CSC and use the CGM CSC 2514 * instead since it has degamma and better precision. 2515 */ 2516 crtc_state->wgc_enable = false; 2517 2518 ret = intel_color_add_affected_planes(state, crtc); 2519 if (ret) 2520 return ret; 2521 2522 intel_assign_luts(crtc_state); 2523 2524 chv_assign_csc(crtc_state); 2525 2526 crtc_state->preload_luts = chv_can_preload_luts(state, crtc); 2527 2528 return 0; 2529 } 2530 2531 static bool ilk_gamma_enable(const struct intel_crtc_state *crtc_state) 2532 { 2533 return (crtc_state->hw.gamma_lut || 2534 crtc_state->hw.degamma_lut) && 2535 !crtc_state->c8_planes; 2536 } 2537 2538 static bool ilk_csc_enable(const struct intel_crtc_state *crtc_state) 2539 { 2540 return crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || 2541 ilk_csc_limited_range(crtc_state) || 2542 crtc_state->hw.ctm; 2543 } 2544 2545 static u32 ilk_gamma_mode(const struct intel_crtc_state *crtc_state) 2546 { 2547 if (!crtc_state->gamma_enable || 2548 lut_is_legacy(crtc_state->hw.gamma_lut)) 2549 return GAMMA_MODE_MODE_8BIT; 2550 else 2551 return GAMMA_MODE_MODE_10BIT; 2552 } 2553 2554 static u32 ilk_csc_mode(const struct intel_crtc_state *crtc_state) 2555 { 2556 /* 2557 * CSC comes after the LUT in RGB->YCbCr mode. 2558 * RGB->YCbCr needs the limited range offsets added to 2559 * the output. RGB limited range output is handled by 2560 * the hw automagically elsewhere. 2561 */ 2562 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB) 2563 return CSC_BLACK_SCREEN_OFFSET; 2564 2565 if (crtc_state->hw.degamma_lut) 2566 return CSC_MODE_YUV_TO_RGB; 2567 2568 return CSC_MODE_YUV_TO_RGB | 2569 CSC_POSITION_BEFORE_GAMMA; 2570 } 2571 2572 static int ilk_assign_luts(struct intel_crtc_state *crtc_state) 2573 { 2574 struct intel_display *display = to_intel_display(crtc_state); 2575 2576 if (ilk_lut_limited_range(crtc_state)) { 2577 struct drm_property_blob *gamma_lut; 2578 2579 gamma_lut = create_resized_lut(display, crtc_state->hw.gamma_lut, 2580 drm_color_lut_size(crtc_state->hw.gamma_lut), 2581 true); 2582 if (IS_ERR(gamma_lut)) 2583 return PTR_ERR(gamma_lut); 2584 2585 drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut); 2586 2587 drm_property_blob_put(gamma_lut); 2588 2589 drm_property_replace_blob(&crtc_state->pre_csc_lut, crtc_state->hw.degamma_lut); 2590 2591 return 0; 2592 } 2593 2594 if (crtc_state->hw.degamma_lut || 2595 crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) { 2596 drm_property_replace_blob(&crtc_state->pre_csc_lut, 2597 crtc_state->hw.degamma_lut); 2598 drm_property_replace_blob(&crtc_state->post_csc_lut, 2599 crtc_state->hw.gamma_lut); 2600 } else { 2601 drm_property_replace_blob(&crtc_state->pre_csc_lut, 2602 crtc_state->hw.gamma_lut); 2603 drm_property_replace_blob(&crtc_state->post_csc_lut, 2604 NULL); 2605 } 2606 2607 return 0; 2608 } 2609 2610 static int ilk_color_check(struct intel_atomic_state *state, 2611 struct intel_crtc *crtc) 2612 { 2613 struct intel_display *display = to_intel_display(state); 2614 struct intel_crtc_state *crtc_state = 2615 intel_atomic_get_new_crtc_state(state, crtc); 2616 int ret; 2617 2618 ret = check_luts(crtc_state); 2619 if (ret) 2620 return ret; 2621 2622 if (crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) { 2623 drm_dbg_kms(display->drm, 2624 "[CRTC:%d:%s] Degamma and gamma together are not possible\n", 2625 crtc->base.base.id, crtc->base.name); 2626 return -EINVAL; 2627 } 2628 2629 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB && 2630 crtc_state->hw.ctm) { 2631 drm_dbg_kms(display->drm, 2632 "[CRTC:%d:%s] YCbCr and CTM together are not possible\n", 2633 crtc->base.base.id, crtc->base.name); 2634 return -EINVAL; 2635 } 2636 2637 crtc_state->gamma_enable = ilk_gamma_enable(crtc_state); 2638 2639 crtc_state->csc_enable = ilk_csc_enable(crtc_state); 2640 2641 crtc_state->gamma_mode = ilk_gamma_mode(crtc_state); 2642 2643 crtc_state->csc_mode = ilk_csc_mode(crtc_state); 2644 2645 ret = intel_color_add_affected_planes(state, crtc); 2646 if (ret) 2647 return ret; 2648 2649 ret = ilk_assign_luts(crtc_state); 2650 if (ret) 2651 return ret; 2652 2653 ilk_assign_csc(crtc_state); 2654 2655 crtc_state->preload_luts = intel_can_preload_luts(state, crtc); 2656 2657 return 0; 2658 } 2659 2660 static u32 ivb_gamma_mode(const struct intel_crtc_state *crtc_state) 2661 { 2662 if (crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) 2663 return GAMMA_MODE_MODE_SPLIT; 2664 2665 return ilk_gamma_mode(crtc_state); 2666 } 2667 2668 static u32 ivb_csc_mode(const struct intel_crtc_state *crtc_state) 2669 { 2670 bool limited_color_range = ilk_csc_limited_range(crtc_state); 2671 2672 /* 2673 * CSC comes after the LUT in degamma, RGB->YCbCr, 2674 * and RGB full->limited range mode. 2675 */ 2676 if (crtc_state->hw.degamma_lut || 2677 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || 2678 limited_color_range) 2679 return 0; 2680 2681 return CSC_POSITION_BEFORE_GAMMA; 2682 } 2683 2684 static int ivb_assign_luts(struct intel_crtc_state *crtc_state) 2685 { 2686 struct intel_display *display = to_intel_display(crtc_state); 2687 struct drm_property_blob *degamma_lut, *gamma_lut; 2688 2689 if (crtc_state->gamma_mode != GAMMA_MODE_MODE_SPLIT) 2690 return ilk_assign_luts(crtc_state); 2691 2692 drm_WARN_ON(display->drm, drm_color_lut_size(crtc_state->hw.degamma_lut) != 1024); 2693 drm_WARN_ON(display->drm, drm_color_lut_size(crtc_state->hw.gamma_lut) != 1024); 2694 2695 degamma_lut = create_resized_lut(display, crtc_state->hw.degamma_lut, 512, 2696 false); 2697 if (IS_ERR(degamma_lut)) 2698 return PTR_ERR(degamma_lut); 2699 2700 gamma_lut = create_resized_lut(display, crtc_state->hw.gamma_lut, 512, 2701 ilk_lut_limited_range(crtc_state)); 2702 if (IS_ERR(gamma_lut)) { 2703 drm_property_blob_put(degamma_lut); 2704 return PTR_ERR(gamma_lut); 2705 } 2706 2707 drm_property_replace_blob(&crtc_state->pre_csc_lut, degamma_lut); 2708 drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut); 2709 2710 drm_property_blob_put(degamma_lut); 2711 drm_property_blob_put(gamma_lut); 2712 2713 return 0; 2714 } 2715 2716 static int ivb_color_check(struct intel_atomic_state *state, 2717 struct intel_crtc *crtc) 2718 { 2719 struct intel_display *display = to_intel_display(state); 2720 struct intel_crtc_state *crtc_state = 2721 intel_atomic_get_new_crtc_state(state, crtc); 2722 int ret; 2723 2724 ret = check_luts(crtc_state); 2725 if (ret) 2726 return ret; 2727 2728 if (crtc_state->c8_planes && crtc_state->hw.degamma_lut) { 2729 drm_dbg_kms(display->drm, 2730 "[CRTC:%d:%s] C8 pixelformat and degamma together are not possible\n", 2731 crtc->base.base.id, crtc->base.name); 2732 return -EINVAL; 2733 } 2734 2735 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB && 2736 crtc_state->hw.ctm) { 2737 drm_dbg_kms(display->drm, 2738 "[CRTC:%d:%s] YCbCr and CTM together are not possible\n", 2739 crtc->base.base.id, crtc->base.name); 2740 return -EINVAL; 2741 } 2742 2743 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB && 2744 crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) { 2745 drm_dbg_kms(display->drm, 2746 "[CRTC:%d:%s] YCbCr and degamma+gamma together are not possible\n", 2747 crtc->base.base.id, crtc->base.name); 2748 return -EINVAL; 2749 } 2750 2751 crtc_state->gamma_enable = ilk_gamma_enable(crtc_state); 2752 2753 crtc_state->csc_enable = ilk_csc_enable(crtc_state); 2754 2755 crtc_state->gamma_mode = ivb_gamma_mode(crtc_state); 2756 2757 crtc_state->csc_mode = ivb_csc_mode(crtc_state); 2758 2759 ret = intel_color_add_affected_planes(state, crtc); 2760 if (ret) 2761 return ret; 2762 2763 ret = ivb_assign_luts(crtc_state); 2764 if (ret) 2765 return ret; 2766 2767 ilk_assign_csc(crtc_state); 2768 2769 crtc_state->preload_luts = intel_can_preload_luts(state, crtc); 2770 2771 return 0; 2772 } 2773 2774 static u32 glk_gamma_mode(const struct intel_crtc_state *crtc_state) 2775 { 2776 if (!crtc_state->gamma_enable || 2777 lut_is_legacy(crtc_state->hw.gamma_lut)) 2778 return GAMMA_MODE_MODE_8BIT; 2779 else 2780 return GAMMA_MODE_MODE_10BIT; 2781 } 2782 2783 static bool glk_use_pre_csc_lut_for_gamma(const struct intel_crtc_state *crtc_state) 2784 { 2785 return crtc_state->hw.gamma_lut && 2786 !crtc_state->c8_planes && 2787 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB; 2788 } 2789 2790 static int glk_assign_luts(struct intel_crtc_state *crtc_state) 2791 { 2792 struct intel_display *display = to_intel_display(crtc_state); 2793 2794 if (glk_use_pre_csc_lut_for_gamma(crtc_state)) { 2795 struct drm_property_blob *gamma_lut; 2796 2797 gamma_lut = create_resized_lut(display, crtc_state->hw.gamma_lut, 2798 DISPLAY_INFO(display)->color.degamma_lut_size, 2799 false); 2800 if (IS_ERR(gamma_lut)) 2801 return PTR_ERR(gamma_lut); 2802 2803 drm_property_replace_blob(&crtc_state->pre_csc_lut, gamma_lut); 2804 drm_property_replace_blob(&crtc_state->post_csc_lut, NULL); 2805 2806 drm_property_blob_put(gamma_lut); 2807 2808 return 0; 2809 } 2810 2811 if (ilk_lut_limited_range(crtc_state)) { 2812 struct drm_property_blob *gamma_lut; 2813 2814 gamma_lut = create_resized_lut(display, crtc_state->hw.gamma_lut, 2815 drm_color_lut_size(crtc_state->hw.gamma_lut), 2816 true); 2817 if (IS_ERR(gamma_lut)) 2818 return PTR_ERR(gamma_lut); 2819 2820 drm_property_replace_blob(&crtc_state->post_csc_lut, gamma_lut); 2821 2822 drm_property_blob_put(gamma_lut); 2823 } else { 2824 drm_property_replace_blob(&crtc_state->post_csc_lut, crtc_state->hw.gamma_lut); 2825 } 2826 2827 drm_property_replace_blob(&crtc_state->pre_csc_lut, crtc_state->hw.degamma_lut); 2828 2829 /* 2830 * On GLK+ both pipe CSC and degamma LUT are controlled 2831 * by csc_enable. Hence for the cases where the CSC is 2832 * needed but degamma LUT is not we need to load a 2833 * linear degamma LUT. 2834 */ 2835 if (crtc_state->csc_enable && !crtc_state->pre_csc_lut) 2836 drm_property_replace_blob(&crtc_state->pre_csc_lut, 2837 display->color.glk_linear_degamma_lut); 2838 2839 return 0; 2840 } 2841 2842 static int glk_check_luts(const struct intel_crtc_state *crtc_state) 2843 { 2844 u32 degamma_tests = intel_degamma_lut_tests(crtc_state); 2845 u32 gamma_tests = intel_gamma_lut_tests(crtc_state); 2846 2847 if (glk_use_pre_csc_lut_for_gamma(crtc_state)) 2848 gamma_tests |= degamma_tests; 2849 2850 return _check_luts(crtc_state, degamma_tests, gamma_tests); 2851 } 2852 2853 static int glk_color_check(struct intel_atomic_state *state, 2854 struct intel_crtc *crtc) 2855 { 2856 struct intel_display *display = to_intel_display(state); 2857 struct intel_crtc_state *crtc_state = 2858 intel_atomic_get_new_crtc_state(state, crtc); 2859 int ret; 2860 2861 ret = glk_check_luts(crtc_state); 2862 if (ret) 2863 return ret; 2864 2865 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB && 2866 crtc_state->hw.ctm) { 2867 drm_dbg_kms(display->drm, 2868 "[CRTC:%d:%s] YCbCr and CTM together are not possible\n", 2869 crtc->base.base.id, crtc->base.name); 2870 return -EINVAL; 2871 } 2872 2873 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB && 2874 crtc_state->hw.degamma_lut && crtc_state->hw.gamma_lut) { 2875 drm_dbg_kms(display->drm, 2876 "[CRTC:%d:%s] YCbCr and degamma+gamma together are not possible\n", 2877 crtc->base.base.id, crtc->base.name); 2878 return -EINVAL; 2879 } 2880 2881 crtc_state->gamma_enable = 2882 !glk_use_pre_csc_lut_for_gamma(crtc_state) && 2883 crtc_state->hw.gamma_lut && 2884 !crtc_state->c8_planes; 2885 2886 /* On GLK+ degamma LUT is controlled by csc_enable */ 2887 crtc_state->csc_enable = 2888 glk_use_pre_csc_lut_for_gamma(crtc_state) || 2889 crtc_state->hw.degamma_lut || 2890 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || 2891 crtc_state->hw.ctm || ilk_csc_limited_range(crtc_state); 2892 2893 crtc_state->gamma_mode = glk_gamma_mode(crtc_state); 2894 2895 crtc_state->csc_mode = 0; 2896 2897 ret = intel_color_add_affected_planes(state, crtc); 2898 if (ret) 2899 return ret; 2900 2901 ret = glk_assign_luts(crtc_state); 2902 if (ret) 2903 return ret; 2904 2905 ilk_assign_csc(crtc_state); 2906 2907 crtc_state->preload_luts = intel_can_preload_luts(state, crtc); 2908 2909 return 0; 2910 } 2911 2912 static u32 icl_gamma_mode(const struct intel_crtc_state *crtc_state) 2913 { 2914 struct intel_display *display = to_intel_display(crtc_state); 2915 u32 gamma_mode = 0; 2916 2917 if (crtc_state->hw.degamma_lut) 2918 gamma_mode |= PRE_CSC_GAMMA_ENABLE; 2919 2920 if (crtc_state->hw.gamma_lut && 2921 !crtc_state->c8_planes) 2922 gamma_mode |= POST_CSC_GAMMA_ENABLE; 2923 2924 if (!crtc_state->hw.gamma_lut || 2925 lut_is_legacy(crtc_state->hw.gamma_lut)) 2926 gamma_mode |= GAMMA_MODE_MODE_8BIT; 2927 /* 2928 * Enable 10bit gamma for D13 2929 * ToDo: Extend to Logarithmic Gamma once the new UAPI 2930 * is accepted and implemented by a userspace consumer 2931 */ 2932 else if (DISPLAY_VER(display) >= 13) 2933 gamma_mode |= GAMMA_MODE_MODE_10BIT; 2934 else 2935 gamma_mode |= GAMMA_MODE_MODE_12BIT_MULTI_SEG; 2936 2937 return gamma_mode; 2938 } 2939 2940 static u32 icl_csc_mode(const struct intel_crtc_state *crtc_state) 2941 { 2942 u32 csc_mode = 0; 2943 2944 if (crtc_state->hw.ctm) 2945 csc_mode |= ICL_CSC_ENABLE; 2946 2947 if (crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB || 2948 crtc_state->limited_color_range) 2949 csc_mode |= ICL_OUTPUT_CSC_ENABLE; 2950 2951 return csc_mode; 2952 } 2953 2954 static int icl_color_check(struct intel_atomic_state *state, 2955 struct intel_crtc *crtc) 2956 { 2957 struct intel_crtc_state *crtc_state = 2958 intel_atomic_get_new_crtc_state(state, crtc); 2959 int ret; 2960 2961 ret = check_luts(crtc_state); 2962 if (ret) 2963 return ret; 2964 2965 crtc_state->gamma_mode = icl_gamma_mode(crtc_state); 2966 2967 crtc_state->csc_mode = icl_csc_mode(crtc_state); 2968 2969 intel_assign_luts(crtc_state); 2970 2971 icl_assign_csc(crtc_state); 2972 2973 crtc_state->preload_luts = intel_can_preload_luts(state, crtc); 2974 2975 return 0; 2976 } 2977 2978 static int i9xx_post_csc_lut_precision(const struct intel_crtc_state *crtc_state) 2979 { 2980 if (!crtc_state->gamma_enable && !crtc_state->c8_planes) 2981 return 0; 2982 2983 switch (crtc_state->gamma_mode) { 2984 case GAMMA_MODE_MODE_8BIT: 2985 return 8; 2986 case GAMMA_MODE_MODE_10BIT: 2987 return 10; 2988 default: 2989 MISSING_CASE(crtc_state->gamma_mode); 2990 return 0; 2991 } 2992 } 2993 2994 static int i9xx_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state) 2995 { 2996 return 0; 2997 } 2998 2999 static int i965_post_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3000 { 3001 if (!crtc_state->gamma_enable && !crtc_state->c8_planes) 3002 return 0; 3003 3004 switch (crtc_state->gamma_mode) { 3005 case GAMMA_MODE_MODE_8BIT: 3006 return 8; 3007 case GAMMA_MODE_MODE_10BIT: 3008 return 16; 3009 default: 3010 MISSING_CASE(crtc_state->gamma_mode); 3011 return 0; 3012 } 3013 } 3014 3015 static int ilk_gamma_mode_precision(u32 gamma_mode) 3016 { 3017 switch (gamma_mode) { 3018 case GAMMA_MODE_MODE_8BIT: 3019 return 8; 3020 case GAMMA_MODE_MODE_10BIT: 3021 return 10; 3022 default: 3023 MISSING_CASE(gamma_mode); 3024 return 0; 3025 } 3026 } 3027 3028 static bool ilk_has_post_csc_lut(const struct intel_crtc_state *crtc_state) 3029 { 3030 if (crtc_state->c8_planes) 3031 return true; 3032 3033 return crtc_state->gamma_enable && 3034 (crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) != 0; 3035 } 3036 3037 static bool ilk_has_pre_csc_lut(const struct intel_crtc_state *crtc_state) 3038 { 3039 return crtc_state->gamma_enable && 3040 (crtc_state->csc_mode & CSC_POSITION_BEFORE_GAMMA) == 0; 3041 } 3042 3043 static int ilk_post_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3044 { 3045 if (!ilk_has_post_csc_lut(crtc_state)) 3046 return 0; 3047 3048 return ilk_gamma_mode_precision(crtc_state->gamma_mode); 3049 } 3050 3051 static int ilk_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3052 { 3053 if (!ilk_has_pre_csc_lut(crtc_state)) 3054 return 0; 3055 3056 return ilk_gamma_mode_precision(crtc_state->gamma_mode); 3057 } 3058 3059 static int ivb_post_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3060 { 3061 if (crtc_state->gamma_enable && 3062 crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) 3063 return 10; 3064 3065 return ilk_post_csc_lut_precision(crtc_state); 3066 } 3067 3068 static int ivb_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3069 { 3070 if (crtc_state->gamma_enable && 3071 crtc_state->gamma_mode == GAMMA_MODE_MODE_SPLIT) 3072 return 10; 3073 3074 return ilk_pre_csc_lut_precision(crtc_state); 3075 } 3076 3077 static int chv_post_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3078 { 3079 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA) 3080 return 10; 3081 3082 return i965_post_csc_lut_precision(crtc_state); 3083 } 3084 3085 static int chv_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3086 { 3087 if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA) 3088 return 14; 3089 3090 return 0; 3091 } 3092 3093 static int glk_post_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3094 { 3095 if (!crtc_state->gamma_enable && !crtc_state->c8_planes) 3096 return 0; 3097 3098 return ilk_gamma_mode_precision(crtc_state->gamma_mode); 3099 } 3100 3101 static int glk_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3102 { 3103 if (!crtc_state->csc_enable) 3104 return 0; 3105 3106 return 16; 3107 } 3108 3109 static bool icl_has_post_csc_lut(const struct intel_crtc_state *crtc_state) 3110 { 3111 if (crtc_state->c8_planes) 3112 return true; 3113 3114 return crtc_state->gamma_mode & POST_CSC_GAMMA_ENABLE; 3115 } 3116 3117 static bool icl_has_pre_csc_lut(const struct intel_crtc_state *crtc_state) 3118 { 3119 return crtc_state->gamma_mode & PRE_CSC_GAMMA_ENABLE; 3120 } 3121 3122 static int icl_post_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3123 { 3124 if (!icl_has_post_csc_lut(crtc_state)) 3125 return 0; 3126 3127 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) { 3128 case GAMMA_MODE_MODE_8BIT: 3129 return 8; 3130 case GAMMA_MODE_MODE_10BIT: 3131 return 10; 3132 case GAMMA_MODE_MODE_12BIT_MULTI_SEG: 3133 return 16; 3134 default: 3135 MISSING_CASE(crtc_state->gamma_mode); 3136 return 0; 3137 } 3138 } 3139 3140 static int icl_pre_csc_lut_precision(const struct intel_crtc_state *crtc_state) 3141 { 3142 if (!icl_has_pre_csc_lut(crtc_state)) 3143 return 0; 3144 3145 return 16; 3146 } 3147 3148 static bool err_check(const struct drm_color_lut *lut1, 3149 const struct drm_color_lut *lut2, u32 err) 3150 { 3151 return ((abs((long)lut2->red - lut1->red)) <= err) && 3152 ((abs((long)lut2->blue - lut1->blue)) <= err) && 3153 ((abs((long)lut2->green - lut1->green)) <= err); 3154 } 3155 3156 static bool intel_lut_entries_equal(const struct drm_color_lut *lut1, 3157 const struct drm_color_lut *lut2, 3158 int lut_size, u32 err) 3159 { 3160 int i; 3161 3162 for (i = 0; i < lut_size; i++) { 3163 if (!err_check(&lut1[i], &lut2[i], err)) 3164 return false; 3165 } 3166 3167 return true; 3168 } 3169 3170 static bool intel_lut_equal(const struct drm_property_blob *blob1, 3171 const struct drm_property_blob *blob2, 3172 int check_size, int precision) 3173 { 3174 const struct drm_color_lut *lut1, *lut2; 3175 int lut_size1, lut_size2; 3176 u32 err; 3177 3178 if (!blob1 != !blob2) 3179 return false; 3180 3181 if (!blob1 != !precision) 3182 return false; 3183 3184 if (!blob1) 3185 return true; 3186 3187 lut_size1 = drm_color_lut_size(blob1); 3188 lut_size2 = drm_color_lut_size(blob2); 3189 3190 if (lut_size1 != lut_size2) 3191 return false; 3192 3193 if (check_size > lut_size1) 3194 return false; 3195 3196 lut1 = blob1->data; 3197 lut2 = blob2->data; 3198 3199 err = 0xffff >> precision; 3200 3201 if (!check_size) 3202 check_size = lut_size1; 3203 3204 return intel_lut_entries_equal(lut1, lut2, check_size, err); 3205 } 3206 3207 static bool i9xx_lut_equal(const struct intel_crtc_state *crtc_state, 3208 const struct drm_property_blob *blob1, 3209 const struct drm_property_blob *blob2, 3210 bool is_pre_csc_lut) 3211 { 3212 int check_size = 0; 3213 3214 if (is_pre_csc_lut) 3215 return intel_lut_equal(blob1, blob2, 0, 3216 i9xx_pre_csc_lut_precision(crtc_state)); 3217 3218 /* 10bit mode last entry is implicit, just skip it */ 3219 if (crtc_state->gamma_mode == GAMMA_MODE_MODE_10BIT) 3220 check_size = 128; 3221 3222 return intel_lut_equal(blob1, blob2, check_size, 3223 i9xx_post_csc_lut_precision(crtc_state)); 3224 } 3225 3226 static bool i965_lut_equal(const struct intel_crtc_state *crtc_state, 3227 const struct drm_property_blob *blob1, 3228 const struct drm_property_blob *blob2, 3229 bool is_pre_csc_lut) 3230 { 3231 if (is_pre_csc_lut) 3232 return intel_lut_equal(blob1, blob2, 0, 3233 i9xx_pre_csc_lut_precision(crtc_state)); 3234 else 3235 return intel_lut_equal(blob1, blob2, 0, 3236 i965_post_csc_lut_precision(crtc_state)); 3237 } 3238 3239 static bool chv_lut_equal(const struct intel_crtc_state *crtc_state, 3240 const struct drm_property_blob *blob1, 3241 const struct drm_property_blob *blob2, 3242 bool is_pre_csc_lut) 3243 { 3244 if (is_pre_csc_lut) 3245 return intel_lut_equal(blob1, blob2, 0, 3246 chv_pre_csc_lut_precision(crtc_state)); 3247 else 3248 return intel_lut_equal(blob1, blob2, 0, 3249 chv_post_csc_lut_precision(crtc_state)); 3250 } 3251 3252 static bool ilk_lut_equal(const struct intel_crtc_state *crtc_state, 3253 const struct drm_property_blob *blob1, 3254 const struct drm_property_blob *blob2, 3255 bool is_pre_csc_lut) 3256 { 3257 if (is_pre_csc_lut) 3258 return intel_lut_equal(blob1, blob2, 0, 3259 ilk_pre_csc_lut_precision(crtc_state)); 3260 else 3261 return intel_lut_equal(blob1, blob2, 0, 3262 ilk_post_csc_lut_precision(crtc_state)); 3263 } 3264 3265 static bool ivb_lut_equal(const struct intel_crtc_state *crtc_state, 3266 const struct drm_property_blob *blob1, 3267 const struct drm_property_blob *blob2, 3268 bool is_pre_csc_lut) 3269 { 3270 if (is_pre_csc_lut) 3271 return intel_lut_equal(blob1, blob2, 0, 3272 ivb_pre_csc_lut_precision(crtc_state)); 3273 else 3274 return intel_lut_equal(blob1, blob2, 0, 3275 ivb_post_csc_lut_precision(crtc_state)); 3276 } 3277 3278 static bool glk_lut_equal(const struct intel_crtc_state *crtc_state, 3279 const struct drm_property_blob *blob1, 3280 const struct drm_property_blob *blob2, 3281 bool is_pre_csc_lut) 3282 { 3283 if (is_pre_csc_lut) 3284 return intel_lut_equal(blob1, blob2, 0, 3285 glk_pre_csc_lut_precision(crtc_state)); 3286 else 3287 return intel_lut_equal(blob1, blob2, 0, 3288 glk_post_csc_lut_precision(crtc_state)); 3289 } 3290 3291 static bool icl_lut_equal(const struct intel_crtc_state *crtc_state, 3292 const struct drm_property_blob *blob1, 3293 const struct drm_property_blob *blob2, 3294 bool is_pre_csc_lut) 3295 { 3296 int check_size = 0; 3297 3298 if (is_pre_csc_lut) 3299 return intel_lut_equal(blob1, blob2, 0, 3300 icl_pre_csc_lut_precision(crtc_state)); 3301 3302 /* hw readout broken except for the super fine segment :( */ 3303 if ((crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) == 3304 GAMMA_MODE_MODE_12BIT_MULTI_SEG) 3305 check_size = 9; 3306 3307 return intel_lut_equal(blob1, blob2, check_size, 3308 icl_post_csc_lut_precision(crtc_state)); 3309 } 3310 3311 static struct drm_property_blob *i9xx_read_lut_8(struct intel_crtc *crtc) 3312 { 3313 struct intel_display *display = to_intel_display(crtc); 3314 enum pipe pipe = crtc->pipe; 3315 struct drm_property_blob *blob; 3316 struct drm_color_lut *lut; 3317 int i; 3318 3319 blob = drm_property_create_blob(display->drm, 3320 sizeof(lut[0]) * LEGACY_LUT_LENGTH, 3321 NULL); 3322 if (IS_ERR(blob)) 3323 return NULL; 3324 3325 lut = blob->data; 3326 3327 for (i = 0; i < LEGACY_LUT_LENGTH; i++) { 3328 u32 val = intel_de_read_fw(display, 3329 PALETTE(display, pipe, i)); 3330 3331 i9xx_lut_8_pack(&lut[i], val); 3332 } 3333 3334 return blob; 3335 } 3336 3337 static struct drm_property_blob *i9xx_read_lut_10(struct intel_crtc *crtc) 3338 { 3339 struct intel_display *display = to_intel_display(crtc); 3340 u32 lut_size = DISPLAY_INFO(display)->color.gamma_lut_size; 3341 enum pipe pipe = crtc->pipe; 3342 struct drm_property_blob *blob; 3343 struct drm_color_lut *lut; 3344 u32 ldw, udw; 3345 int i; 3346 3347 blob = drm_property_create_blob(display->drm, 3348 lut_size * sizeof(lut[0]), NULL); 3349 if (IS_ERR(blob)) 3350 return NULL; 3351 3352 lut = blob->data; 3353 3354 for (i = 0; i < lut_size - 1; i++) { 3355 ldw = intel_de_read_fw(display, 3356 PALETTE(display, pipe, 2 * i + 0)); 3357 udw = intel_de_read_fw(display, 3358 PALETTE(display, pipe, 2 * i + 1)); 3359 3360 i9xx_lut_10_pack(&lut[i], ldw, udw); 3361 } 3362 3363 i9xx_lut_10_pack_slope(&lut[i], ldw, udw); 3364 3365 return blob; 3366 } 3367 3368 static void i9xx_read_luts(struct intel_crtc_state *crtc_state) 3369 { 3370 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 3371 3372 if (!crtc_state->gamma_enable && !crtc_state->c8_planes) 3373 return; 3374 3375 switch (crtc_state->gamma_mode) { 3376 case GAMMA_MODE_MODE_8BIT: 3377 crtc_state->post_csc_lut = i9xx_read_lut_8(crtc); 3378 break; 3379 case GAMMA_MODE_MODE_10BIT: 3380 crtc_state->post_csc_lut = i9xx_read_lut_10(crtc); 3381 break; 3382 default: 3383 MISSING_CASE(crtc_state->gamma_mode); 3384 break; 3385 } 3386 } 3387 3388 static struct drm_property_blob *i965_read_lut_10p6(struct intel_crtc *crtc) 3389 { 3390 struct intel_display *display = to_intel_display(crtc); 3391 int i, lut_size = DISPLAY_INFO(display)->color.gamma_lut_size; 3392 enum pipe pipe = crtc->pipe; 3393 struct drm_property_blob *blob; 3394 struct drm_color_lut *lut; 3395 3396 blob = drm_property_create_blob(display->drm, 3397 sizeof(lut[0]) * lut_size, 3398 NULL); 3399 if (IS_ERR(blob)) 3400 return NULL; 3401 3402 lut = blob->data; 3403 3404 for (i = 0; i < lut_size - 1; i++) { 3405 u32 ldw = intel_de_read_fw(display, 3406 PALETTE(display, pipe, 2 * i + 0)); 3407 u32 udw = intel_de_read_fw(display, 3408 PALETTE(display, pipe, 2 * i + 1)); 3409 3410 i965_lut_10p6_pack(&lut[i], ldw, udw); 3411 } 3412 3413 lut[i].red = i965_lut_11p6_max_pack(intel_de_read_fw(display, PIPEGCMAX(display, pipe, 0))); 3414 lut[i].green = i965_lut_11p6_max_pack(intel_de_read_fw(display, PIPEGCMAX(display, pipe, 1))); 3415 lut[i].blue = i965_lut_11p6_max_pack(intel_de_read_fw(display, PIPEGCMAX(display, pipe, 2))); 3416 3417 return blob; 3418 } 3419 3420 static void i965_read_luts(struct intel_crtc_state *crtc_state) 3421 { 3422 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 3423 3424 if (!crtc_state->gamma_enable && !crtc_state->c8_planes) 3425 return; 3426 3427 switch (crtc_state->gamma_mode) { 3428 case GAMMA_MODE_MODE_8BIT: 3429 crtc_state->post_csc_lut = i9xx_read_lut_8(crtc); 3430 break; 3431 case GAMMA_MODE_MODE_10BIT: 3432 crtc_state->post_csc_lut = i965_read_lut_10p6(crtc); 3433 break; 3434 default: 3435 MISSING_CASE(crtc_state->gamma_mode); 3436 break; 3437 } 3438 } 3439 3440 static struct drm_property_blob *chv_read_cgm_degamma(struct intel_crtc *crtc) 3441 { 3442 struct intel_display *display = to_intel_display(crtc); 3443 int i, lut_size = DISPLAY_INFO(display)->color.degamma_lut_size; 3444 enum pipe pipe = crtc->pipe; 3445 struct drm_property_blob *blob; 3446 struct drm_color_lut *lut; 3447 3448 blob = drm_property_create_blob(display->drm, 3449 sizeof(lut[0]) * lut_size, 3450 NULL); 3451 if (IS_ERR(blob)) 3452 return NULL; 3453 3454 lut = blob->data; 3455 3456 for (i = 0; i < lut_size; i++) { 3457 u32 ldw = intel_de_read_fw(display, CGM_PIPE_DEGAMMA(pipe, i, 0)); 3458 u32 udw = intel_de_read_fw(display, CGM_PIPE_DEGAMMA(pipe, i, 1)); 3459 3460 chv_cgm_degamma_pack(&lut[i], ldw, udw); 3461 } 3462 3463 return blob; 3464 } 3465 3466 static struct drm_property_blob *chv_read_cgm_gamma(struct intel_crtc *crtc) 3467 { 3468 struct intel_display *display = to_intel_display(crtc); 3469 int i, lut_size = DISPLAY_INFO(display)->color.gamma_lut_size; 3470 enum pipe pipe = crtc->pipe; 3471 struct drm_property_blob *blob; 3472 struct drm_color_lut *lut; 3473 3474 blob = drm_property_create_blob(display->drm, 3475 sizeof(lut[0]) * lut_size, 3476 NULL); 3477 if (IS_ERR(blob)) 3478 return NULL; 3479 3480 lut = blob->data; 3481 3482 for (i = 0; i < lut_size; i++) { 3483 u32 ldw = intel_de_read_fw(display, CGM_PIPE_GAMMA(pipe, i, 0)); 3484 u32 udw = intel_de_read_fw(display, CGM_PIPE_GAMMA(pipe, i, 1)); 3485 3486 chv_cgm_gamma_pack(&lut[i], ldw, udw); 3487 } 3488 3489 return blob; 3490 } 3491 3492 static void chv_get_config(struct intel_crtc_state *crtc_state) 3493 { 3494 struct intel_display *display = to_intel_display(crtc_state); 3495 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 3496 3497 crtc_state->cgm_mode = intel_de_read(display, CGM_PIPE_MODE(crtc->pipe)); 3498 3499 i9xx_get_config(crtc_state); 3500 } 3501 3502 static void chv_read_luts(struct intel_crtc_state *crtc_state) 3503 { 3504 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 3505 3506 if (crtc_state->cgm_mode & CGM_PIPE_MODE_DEGAMMA) 3507 crtc_state->pre_csc_lut = chv_read_cgm_degamma(crtc); 3508 3509 if (crtc_state->cgm_mode & CGM_PIPE_MODE_GAMMA) 3510 crtc_state->post_csc_lut = chv_read_cgm_gamma(crtc); 3511 else 3512 i965_read_luts(crtc_state); 3513 } 3514 3515 static struct drm_property_blob *ilk_read_lut_8(struct intel_crtc *crtc) 3516 { 3517 struct intel_display *display = to_intel_display(crtc); 3518 enum pipe pipe = crtc->pipe; 3519 struct drm_property_blob *blob; 3520 struct drm_color_lut *lut; 3521 int i; 3522 3523 blob = drm_property_create_blob(display->drm, 3524 sizeof(lut[0]) * LEGACY_LUT_LENGTH, 3525 NULL); 3526 if (IS_ERR(blob)) 3527 return NULL; 3528 3529 lut = blob->data; 3530 3531 for (i = 0; i < LEGACY_LUT_LENGTH; i++) { 3532 u32 val = intel_de_read_fw(display, LGC_PALETTE(pipe, i)); 3533 3534 i9xx_lut_8_pack(&lut[i], val); 3535 } 3536 3537 return blob; 3538 } 3539 3540 static struct drm_property_blob *ilk_read_lut_10(struct intel_crtc *crtc) 3541 { 3542 struct intel_display *display = to_intel_display(crtc); 3543 int i, lut_size = DISPLAY_INFO(display)->color.gamma_lut_size; 3544 enum pipe pipe = crtc->pipe; 3545 struct drm_property_blob *blob; 3546 struct drm_color_lut *lut; 3547 3548 blob = drm_property_create_blob(display->drm, 3549 sizeof(lut[0]) * lut_size, 3550 NULL); 3551 if (IS_ERR(blob)) 3552 return NULL; 3553 3554 lut = blob->data; 3555 3556 for (i = 0; i < lut_size; i++) { 3557 u32 val = intel_de_read_fw(display, PREC_PALETTE(pipe, i)); 3558 3559 ilk_lut_10_pack(&lut[i], val); 3560 } 3561 3562 return blob; 3563 } 3564 3565 static void ilk_get_config(struct intel_crtc_state *crtc_state) 3566 { 3567 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 3568 3569 crtc_state->csc_mode = ilk_read_csc_mode(crtc); 3570 3571 i9xx_get_config(crtc_state); 3572 } 3573 3574 static void ilk_read_luts(struct intel_crtc_state *crtc_state) 3575 { 3576 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 3577 struct drm_property_blob **blob = 3578 ilk_has_post_csc_lut(crtc_state) ? 3579 &crtc_state->post_csc_lut : &crtc_state->pre_csc_lut; 3580 3581 if (!crtc_state->gamma_enable && !crtc_state->c8_planes) 3582 return; 3583 3584 switch (crtc_state->gamma_mode) { 3585 case GAMMA_MODE_MODE_8BIT: 3586 *blob = ilk_read_lut_8(crtc); 3587 break; 3588 case GAMMA_MODE_MODE_10BIT: 3589 *blob = ilk_read_lut_10(crtc); 3590 break; 3591 default: 3592 MISSING_CASE(crtc_state->gamma_mode); 3593 break; 3594 } 3595 } 3596 3597 /* 3598 * IVB/HSW Bspec / PAL_PREC_INDEX: 3599 * "Restriction : Index auto increment mode is not 3600 * supported and must not be enabled." 3601 */ 3602 static struct drm_property_blob *ivb_read_lut_10(struct intel_crtc *crtc, 3603 u32 prec_index) 3604 { 3605 struct intel_display *display = to_intel_display(crtc); 3606 int i, lut_size = ivb_lut_10_size(prec_index); 3607 enum pipe pipe = crtc->pipe; 3608 struct drm_property_blob *blob; 3609 struct drm_color_lut *lut; 3610 3611 blob = drm_property_create_blob(display->drm, 3612 sizeof(lut[0]) * lut_size, 3613 NULL); 3614 if (IS_ERR(blob)) 3615 return NULL; 3616 3617 lut = blob->data; 3618 3619 for (i = 0; i < lut_size; i++) { 3620 u32 val; 3621 3622 intel_de_write_fw(display, PREC_PAL_INDEX(pipe), 3623 prec_index + i); 3624 val = intel_de_read_fw(display, PREC_PAL_DATA(pipe)); 3625 3626 ilk_lut_10_pack(&lut[i], val); 3627 } 3628 3629 intel_de_write_fw(display, PREC_PAL_INDEX(pipe), 3630 PAL_PREC_INDEX_VALUE(0)); 3631 3632 return blob; 3633 } 3634 3635 static void ivb_read_luts(struct intel_crtc_state *crtc_state) 3636 { 3637 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 3638 struct drm_property_blob **blob = 3639 ilk_has_post_csc_lut(crtc_state) ? 3640 &crtc_state->post_csc_lut : &crtc_state->pre_csc_lut; 3641 3642 if (!crtc_state->gamma_enable && !crtc_state->c8_planes) 3643 return; 3644 3645 switch (crtc_state->gamma_mode) { 3646 case GAMMA_MODE_MODE_8BIT: 3647 *blob = ilk_read_lut_8(crtc); 3648 break; 3649 case GAMMA_MODE_MODE_SPLIT: 3650 crtc_state->pre_csc_lut = 3651 ivb_read_lut_10(crtc, PAL_PREC_SPLIT_MODE | 3652 PAL_PREC_INDEX_VALUE(0)); 3653 crtc_state->post_csc_lut = 3654 ivb_read_lut_10(crtc, PAL_PREC_SPLIT_MODE | 3655 PAL_PREC_INDEX_VALUE(512)); 3656 break; 3657 case GAMMA_MODE_MODE_10BIT: 3658 *blob = ivb_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0)); 3659 break; 3660 default: 3661 MISSING_CASE(crtc_state->gamma_mode); 3662 break; 3663 } 3664 } 3665 3666 /* On BDW+ the index auto increment mode actually works */ 3667 static struct drm_property_blob *bdw_read_lut_10(struct intel_crtc *crtc, 3668 u32 prec_index) 3669 { 3670 struct intel_display *display = to_intel_display(crtc); 3671 int i, lut_size = ivb_lut_10_size(prec_index); 3672 enum pipe pipe = crtc->pipe; 3673 struct drm_property_blob *blob; 3674 struct drm_color_lut *lut; 3675 3676 blob = drm_property_create_blob(display->drm, 3677 sizeof(lut[0]) * lut_size, 3678 NULL); 3679 if (IS_ERR(blob)) 3680 return NULL; 3681 3682 lut = blob->data; 3683 3684 intel_de_write_fw(display, PREC_PAL_INDEX(pipe), 3685 prec_index); 3686 intel_de_write_fw(display, PREC_PAL_INDEX(pipe), 3687 PAL_PREC_AUTO_INCREMENT | 3688 prec_index); 3689 3690 for (i = 0; i < lut_size; i++) { 3691 u32 val = intel_de_read_fw(display, PREC_PAL_DATA(pipe)); 3692 3693 ilk_lut_10_pack(&lut[i], val); 3694 } 3695 3696 intel_de_write_fw(display, PREC_PAL_INDEX(pipe), 3697 PAL_PREC_INDEX_VALUE(0)); 3698 3699 return blob; 3700 } 3701 3702 static void bdw_read_luts(struct intel_crtc_state *crtc_state) 3703 { 3704 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 3705 struct drm_property_blob **blob = 3706 ilk_has_post_csc_lut(crtc_state) ? 3707 &crtc_state->post_csc_lut : &crtc_state->pre_csc_lut; 3708 3709 if (!crtc_state->gamma_enable && !crtc_state->c8_planes) 3710 return; 3711 3712 switch (crtc_state->gamma_mode) { 3713 case GAMMA_MODE_MODE_8BIT: 3714 *blob = ilk_read_lut_8(crtc); 3715 break; 3716 case GAMMA_MODE_MODE_SPLIT: 3717 crtc_state->pre_csc_lut = 3718 bdw_read_lut_10(crtc, PAL_PREC_SPLIT_MODE | 3719 PAL_PREC_INDEX_VALUE(0)); 3720 crtc_state->post_csc_lut = 3721 bdw_read_lut_10(crtc, PAL_PREC_SPLIT_MODE | 3722 PAL_PREC_INDEX_VALUE(512)); 3723 break; 3724 case GAMMA_MODE_MODE_10BIT: 3725 *blob = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0)); 3726 break; 3727 default: 3728 MISSING_CASE(crtc_state->gamma_mode); 3729 break; 3730 } 3731 } 3732 3733 static struct drm_property_blob *glk_read_degamma_lut(struct intel_crtc *crtc) 3734 { 3735 struct intel_display *display = to_intel_display(crtc); 3736 int i, lut_size = DISPLAY_INFO(display)->color.degamma_lut_size; 3737 enum pipe pipe = crtc->pipe; 3738 struct drm_property_blob *blob; 3739 struct drm_color_lut *lut; 3740 3741 blob = drm_property_create_blob(display->drm, 3742 sizeof(lut[0]) * lut_size, 3743 NULL); 3744 if (IS_ERR(blob)) 3745 return NULL; 3746 3747 lut = blob->data; 3748 3749 /* 3750 * When setting the auto-increment bit, the hardware seems to 3751 * ignore the index bits, so we need to reset it to index 0 3752 * separately. 3753 */ 3754 intel_de_write_fw(display, PRE_CSC_GAMC_INDEX(pipe), 3755 PRE_CSC_GAMC_INDEX_VALUE(0)); 3756 intel_de_write_fw(display, PRE_CSC_GAMC_INDEX(pipe), 3757 PRE_CSC_GAMC_AUTO_INCREMENT | 3758 PRE_CSC_GAMC_INDEX_VALUE(0)); 3759 3760 for (i = 0; i < lut_size; i++) { 3761 u32 val = intel_de_read_fw(display, PRE_CSC_GAMC_DATA(pipe)); 3762 3763 if (DISPLAY_VER(display) >= 14) 3764 mtl_degamma_lut_pack(&lut[i], val); 3765 else 3766 glk_degamma_lut_pack(&lut[i], val); 3767 } 3768 3769 intel_de_write_fw(display, PRE_CSC_GAMC_INDEX(pipe), 3770 PRE_CSC_GAMC_INDEX_VALUE(0)); 3771 3772 return blob; 3773 } 3774 3775 static void glk_read_luts(struct intel_crtc_state *crtc_state) 3776 { 3777 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 3778 3779 if (crtc_state->csc_enable) 3780 crtc_state->pre_csc_lut = glk_read_degamma_lut(crtc); 3781 3782 if (!crtc_state->gamma_enable && !crtc_state->c8_planes) 3783 return; 3784 3785 switch (crtc_state->gamma_mode) { 3786 case GAMMA_MODE_MODE_8BIT: 3787 crtc_state->post_csc_lut = ilk_read_lut_8(crtc); 3788 break; 3789 case GAMMA_MODE_MODE_10BIT: 3790 crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0)); 3791 break; 3792 default: 3793 MISSING_CASE(crtc_state->gamma_mode); 3794 break; 3795 } 3796 } 3797 3798 static struct drm_property_blob * 3799 icl_read_lut_multi_segment(struct intel_crtc *crtc) 3800 { 3801 struct intel_display *display = to_intel_display(crtc); 3802 int i, lut_size = DISPLAY_INFO(display)->color.gamma_lut_size; 3803 enum pipe pipe = crtc->pipe; 3804 struct drm_property_blob *blob; 3805 struct drm_color_lut *lut; 3806 3807 blob = drm_property_create_blob(display->drm, 3808 sizeof(lut[0]) * lut_size, 3809 NULL); 3810 if (IS_ERR(blob)) 3811 return NULL; 3812 3813 lut = blob->data; 3814 3815 intel_de_write_fw(display, PREC_PAL_MULTI_SEG_INDEX(pipe), 3816 PAL_PREC_MULTI_SEG_INDEX_VALUE(0)); 3817 intel_de_write_fw(display, PREC_PAL_MULTI_SEG_INDEX(pipe), 3818 PAL_PREC_MULTI_SEG_AUTO_INCREMENT | 3819 PAL_PREC_MULTI_SEG_INDEX_VALUE(0)); 3820 3821 for (i = 0; i < 9; i++) { 3822 u32 ldw = intel_de_read_fw(display, PREC_PAL_MULTI_SEG_DATA(pipe)); 3823 u32 udw = intel_de_read_fw(display, PREC_PAL_MULTI_SEG_DATA(pipe)); 3824 3825 ilk_lut_12p4_pack(&lut[i], ldw, udw); 3826 } 3827 3828 intel_de_write_fw(display, PREC_PAL_MULTI_SEG_INDEX(pipe), 3829 PAL_PREC_MULTI_SEG_INDEX_VALUE(0)); 3830 3831 /* 3832 * FIXME readouts from PAL_PREC_DATA register aren't giving 3833 * correct values in the case of fine and coarse segments. 3834 * Restricting readouts only for super fine segment as of now. 3835 */ 3836 3837 return blob; 3838 } 3839 3840 static void icl_read_luts(struct intel_crtc_state *crtc_state) 3841 { 3842 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); 3843 3844 if (icl_has_pre_csc_lut(crtc_state)) 3845 crtc_state->pre_csc_lut = glk_read_degamma_lut(crtc); 3846 3847 if (!icl_has_post_csc_lut(crtc_state)) 3848 return; 3849 3850 switch (crtc_state->gamma_mode & GAMMA_MODE_MODE_MASK) { 3851 case GAMMA_MODE_MODE_8BIT: 3852 crtc_state->post_csc_lut = ilk_read_lut_8(crtc); 3853 break; 3854 case GAMMA_MODE_MODE_10BIT: 3855 crtc_state->post_csc_lut = bdw_read_lut_10(crtc, PAL_PREC_INDEX_VALUE(0)); 3856 break; 3857 case GAMMA_MODE_MODE_12BIT_MULTI_SEG: 3858 crtc_state->post_csc_lut = icl_read_lut_multi_segment(crtc); 3859 break; 3860 default: 3861 MISSING_CASE(crtc_state->gamma_mode); 3862 break; 3863 } 3864 } 3865 3866 static void 3867 xelpd_load_plane_csc_matrix(struct intel_dsb *dsb, 3868 const struct intel_plane_state *plane_state) 3869 { 3870 struct intel_display *display = to_intel_display(plane_state); 3871 const struct drm_plane_state *state = &plane_state->uapi; 3872 enum pipe pipe = to_intel_plane(state->plane)->pipe; 3873 enum plane_id plane = to_intel_plane(state->plane)->id; 3874 const struct drm_property_blob *blob = plane_state->hw.ctm; 3875 struct drm_color_ctm_3x4 *ctm; 3876 const u64 *input; 3877 u16 coeffs[9] = {}; 3878 int i, j; 3879 3880 if (!icl_is_hdr_plane(display, plane) || !blob) 3881 return; 3882 3883 ctm = blob->data; 3884 input = ctm->matrix; 3885 3886 /* 3887 * Convert fixed point S31.32 input to format supported by the 3888 * hardware. 3889 */ 3890 for (i = 0, j = 0; i < ARRAY_SIZE(coeffs); i++) { 3891 u64 abs_coeff = ((1ULL << 63) - 1) & input[j]; 3892 3893 /* 3894 * Clamp input value to min/max supported by 3895 * hardware. 3896 */ 3897 abs_coeff = clamp_val(abs_coeff, 0, CTM_COEFF_4_0 - 1); 3898 3899 /* sign bit */ 3900 if (CTM_COEFF_NEGATIVE(input[j])) 3901 coeffs[i] |= 1 << 15; 3902 3903 if (abs_coeff < CTM_COEFF_0_125) 3904 coeffs[i] |= (3 << 12) | 3905 ILK_CSC_COEFF_FP(abs_coeff, 12); 3906 else if (abs_coeff < CTM_COEFF_0_25) 3907 coeffs[i] |= (2 << 12) | 3908 ILK_CSC_COEFF_FP(abs_coeff, 11); 3909 else if (abs_coeff < CTM_COEFF_0_5) 3910 coeffs[i] |= (1 << 12) | 3911 ILK_CSC_COEFF_FP(abs_coeff, 10); 3912 else if (abs_coeff < CTM_COEFF_1_0) 3913 coeffs[i] |= ILK_CSC_COEFF_FP(abs_coeff, 9); 3914 else if (abs_coeff < CTM_COEFF_2_0) 3915 coeffs[i] |= (7 << 12) | 3916 ILK_CSC_COEFF_FP(abs_coeff, 8); 3917 else 3918 coeffs[i] |= (6 << 12) | 3919 ILK_CSC_COEFF_FP(abs_coeff, 7); 3920 3921 /* Skip postoffs */ 3922 if (!((j + 2) % 4)) 3923 j += 2; 3924 else 3925 j++; 3926 } 3927 3928 intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 0), 3929 coeffs[0] << 16 | coeffs[1]); 3930 intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 1), 3931 coeffs[2] << 16); 3932 3933 intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 2), 3934 coeffs[3] << 16 | coeffs[4]); 3935 intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 3), 3936 coeffs[5] << 16); 3937 3938 intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 4), 3939 coeffs[6] << 16 | coeffs[7]); 3940 intel_de_write_dsb(display, dsb, PLANE_CSC_COEFF(pipe, plane, 5), 3941 coeffs[8] << 16); 3942 3943 intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane, 0), 0); 3944 intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane, 1), 0); 3945 intel_de_write_dsb(display, dsb, PLANE_CSC_PREOFF(pipe, plane, 2), 0); 3946 3947 /* 3948 * Conversion from S31.32 to S0.12. BIT[12] is the signed bit 3949 */ 3950 intel_de_write_dsb(display, dsb, 3951 PLANE_CSC_POSTOFF(pipe, plane, 0), 3952 ctm_to_twos_complement(input[3], 0, 12)); 3953 intel_de_write_dsb(display, dsb, 3954 PLANE_CSC_POSTOFF(pipe, plane, 1), 3955 ctm_to_twos_complement(input[7], 0, 12)); 3956 intel_de_write_dsb(display, dsb, 3957 PLANE_CSC_POSTOFF(pipe, plane, 2), 3958 ctm_to_twos_complement(input[11], 0, 12)); 3959 } 3960 3961 static void 3962 xelpd_program_plane_pre_csc_lut(struct intel_dsb *dsb, 3963 const struct intel_plane_state *plane_state) 3964 { 3965 struct intel_display *display = to_intel_display(plane_state); 3966 const struct drm_plane_state *state = &plane_state->uapi; 3967 enum pipe pipe = to_intel_plane(state->plane)->pipe; 3968 enum plane_id plane = to_intel_plane(state->plane)->id; 3969 const struct drm_color_lut32 *pre_csc_lut = plane_state->hw.degamma_lut->data; 3970 u32 i, lut_size; 3971 3972 if (icl_is_hdr_plane(display, plane)) { 3973 lut_size = 128; 3974 3975 intel_de_write_dsb(display, dsb, 3976 PLANE_PRE_CSC_GAMC_INDEX_ENH(pipe, plane, 0), 3977 PLANE_PAL_PREC_AUTO_INCREMENT); 3978 3979 if (pre_csc_lut) { 3980 for (i = 0; i < lut_size; i++) { 3981 u32 lut_val = drm_color_lut32_extract(pre_csc_lut[i].green, 24); 3982 3983 intel_de_write_dsb(display, dsb, 3984 PLANE_PRE_CSC_GAMC_DATA_ENH(pipe, plane, 0), 3985 lut_val); 3986 } 3987 3988 /* Program the max register to clamp values > 1.0. */ 3989 /* TODO: Restrict to 0x7ffffff */ 3990 do { 3991 intel_de_write_dsb(display, dsb, 3992 PLANE_PRE_CSC_GAMC_DATA_ENH(pipe, plane, 0), 3993 (1 << 24)); 3994 } while (i++ < 130); 3995 } else { 3996 for (i = 0; i < lut_size; i++) { 3997 u32 v = (i * ((1 << 24) - 1)) / (lut_size - 1); 3998 3999 intel_de_write_dsb(display, dsb, 4000 PLANE_PRE_CSC_GAMC_DATA_ENH(pipe, plane, 0), v); 4001 } 4002 4003 do { 4004 intel_de_write_dsb(display, dsb, 4005 PLANE_PRE_CSC_GAMC_DATA_ENH(pipe, plane, 0), 4006 1 << 24); 4007 } while (i++ < 130); 4008 } 4009 4010 intel_de_write_dsb(display, dsb, PLANE_PRE_CSC_GAMC_INDEX_ENH(pipe, plane, 0), 0); 4011 } 4012 } 4013 4014 static void 4015 xelpd_program_plane_post_csc_lut(struct intel_dsb *dsb, 4016 const struct intel_plane_state *plane_state) 4017 { 4018 struct intel_display *display = to_intel_display(plane_state); 4019 const struct drm_plane_state *state = &plane_state->uapi; 4020 enum pipe pipe = to_intel_plane(state->plane)->pipe; 4021 enum plane_id plane = to_intel_plane(state->plane)->id; 4022 const struct drm_color_lut32 *post_csc_lut = plane_state->hw.gamma_lut->data; 4023 u32 i, lut_size, lut_val; 4024 4025 if (icl_is_hdr_plane(display, plane)) { 4026 intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX_ENH(pipe, plane, 0), 4027 PLANE_PAL_PREC_AUTO_INCREMENT); 4028 /* TODO: Add macro */ 4029 intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_SEG0_INDEX_ENH(pipe, plane, 0), 4030 PLANE_PAL_PREC_AUTO_INCREMENT); 4031 if (post_csc_lut) { 4032 lut_size = 32; 4033 for (i = 0; i < lut_size; i++) { 4034 lut_val = drm_color_lut32_extract(post_csc_lut[i].green, 24); 4035 4036 intel_de_write_dsb(display, dsb, 4037 PLANE_POST_CSC_GAMC_DATA_ENH(pipe, plane, 0), 4038 lut_val); 4039 } 4040 4041 /* Segment 2 */ 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 } else { 4048 /*TODO: Add for segment 0 */ 4049 lut_size = 32; 4050 for (i = 0; i < lut_size; i++) { 4051 u32 v = (i * ((1 << 24) - 1)) / (lut_size - 1); 4052 4053 intel_de_write_dsb(display, dsb, 4054 PLANE_POST_CSC_GAMC_DATA_ENH(pipe, plane, 0), v); 4055 } 4056 4057 do { 4058 intel_de_write_dsb(display, dsb, 4059 PLANE_POST_CSC_GAMC_DATA_ENH(pipe, plane, 0), 4060 1 << 24); 4061 } while (i++ < 34); 4062 } 4063 4064 intel_de_write_dsb(display, dsb, PLANE_POST_CSC_GAMC_INDEX_ENH(pipe, plane, 0), 0); 4065 intel_de_write_dsb(display, dsb, 4066 PLANE_POST_CSC_GAMC_SEG0_INDEX_ENH(pipe, plane, 0), 0); 4067 } 4068 } 4069 4070 static void 4071 xelpd_plane_load_luts(struct intel_dsb *dsb, const struct intel_plane_state *plane_state) 4072 { 4073 if (plane_state->hw.degamma_lut) 4074 xelpd_program_plane_pre_csc_lut(dsb, plane_state); 4075 4076 if (plane_state->hw.gamma_lut) 4077 xelpd_program_plane_post_csc_lut(dsb, plane_state); 4078 } 4079 4080 static u32 glk_3dlut_10(const struct drm_color_lut32 *color) 4081 { 4082 return REG_FIELD_PREP(LUT_3D_DATA_RED_MASK, drm_color_lut32_extract(color->red, 10)) | 4083 REG_FIELD_PREP(LUT_3D_DATA_GREEN_MASK, drm_color_lut32_extract(color->green, 10)) | 4084 REG_FIELD_PREP(LUT_3D_DATA_BLUE_MASK, drm_color_lut32_extract(color->blue, 10)); 4085 } 4086 4087 static void glk_load_lut_3d(struct intel_dsb *dsb, 4088 struct intel_crtc *crtc, 4089 const struct drm_property_blob *blob) 4090 { 4091 struct intel_display *display = to_intel_display(crtc->base.dev); 4092 const struct drm_color_lut32 *lut = blob->data; 4093 int i, lut_size = drm_color_lut32_size(blob); 4094 enum pipe pipe = crtc->pipe; 4095 4096 if (!dsb && intel_de_read(display, LUT_3D_CTL(pipe)) & LUT_3D_READY) { 4097 drm_err(display->drm, "[CRTC:%d:%s] 3D LUT not ready, not loading LUTs\n", 4098 crtc->base.base.id, crtc->base.name); 4099 return; 4100 } 4101 4102 intel_de_write_dsb(display, dsb, LUT_3D_INDEX(pipe), LUT_3D_AUTO_INCREMENT); 4103 for (i = 0; i < lut_size; i++) 4104 intel_de_write_dsb(display, dsb, LUT_3D_DATA(pipe), glk_3dlut_10(&lut[i])); 4105 intel_de_write_dsb(display, dsb, LUT_3D_INDEX(pipe), 0); 4106 } 4107 4108 static void glk_lut_3d_commit(struct intel_dsb *dsb, struct intel_crtc *crtc, bool enable) 4109 { 4110 struct intel_display *display = to_intel_display(crtc); 4111 enum pipe pipe = crtc->pipe; 4112 u32 val = 0; 4113 4114 if (!dsb && intel_de_read(display, LUT_3D_CTL(pipe)) & LUT_3D_READY) { 4115 drm_err(display->drm, "[CRTC:%d:%s] 3D LUT not ready, not committing change\n", 4116 crtc->base.base.id, crtc->base.name); 4117 return; 4118 } 4119 4120 if (enable) 4121 val = LUT_3D_ENABLE | LUT_3D_READY | LUT_3D_BIND_PLANE_1; 4122 4123 intel_de_write_dsb(display, dsb, LUT_3D_CTL(pipe), val); 4124 } 4125 4126 static const struct intel_color_funcs chv_color_funcs = { 4127 .color_check = chv_color_check, 4128 .color_commit_arm = i9xx_color_commit_arm, 4129 .load_luts = chv_load_luts, 4130 .read_luts = chv_read_luts, 4131 .lut_equal = chv_lut_equal, 4132 .read_csc = chv_read_csc, 4133 .get_config = chv_get_config, 4134 }; 4135 4136 static const struct intel_color_funcs vlv_color_funcs = { 4137 .color_check = vlv_color_check, 4138 .color_commit_arm = i9xx_color_commit_arm, 4139 .load_luts = vlv_load_luts, 4140 .read_luts = i965_read_luts, 4141 .lut_equal = i965_lut_equal, 4142 .read_csc = vlv_read_csc, 4143 .get_config = i9xx_get_config, 4144 }; 4145 4146 static const struct intel_color_funcs i965_color_funcs = { 4147 .color_check = i9xx_color_check, 4148 .color_commit_arm = i9xx_color_commit_arm, 4149 .load_luts = i965_load_luts, 4150 .read_luts = i965_read_luts, 4151 .lut_equal = i965_lut_equal, 4152 .get_config = i9xx_get_config, 4153 }; 4154 4155 static const struct intel_color_funcs i9xx_color_funcs = { 4156 .color_check = i9xx_color_check, 4157 .color_commit_arm = i9xx_color_commit_arm, 4158 .load_luts = i9xx_load_luts, 4159 .read_luts = i9xx_read_luts, 4160 .lut_equal = i9xx_lut_equal, 4161 .get_config = i9xx_get_config, 4162 }; 4163 4164 static const struct intel_color_funcs tgl_color_funcs = { 4165 .color_check = icl_color_check, 4166 .color_commit_noarm = icl_color_commit_noarm, 4167 .color_commit_arm = icl_color_commit_arm, 4168 .load_luts = icl_load_luts, 4169 .read_luts = icl_read_luts, 4170 .lut_equal = icl_lut_equal, 4171 .read_csc = icl_read_csc, 4172 .get_config = skl_get_config, 4173 .load_plane_csc_matrix = xelpd_load_plane_csc_matrix, 4174 .load_plane_luts = xelpd_plane_load_luts, 4175 }; 4176 4177 static const struct intel_color_funcs icl_color_funcs = { 4178 .color_check = icl_color_check, 4179 .color_commit_noarm = icl_color_commit_noarm, 4180 .color_commit_arm = icl_color_commit_arm, 4181 .color_post_update = icl_color_post_update, 4182 .load_luts = icl_load_luts, 4183 .read_luts = icl_read_luts, 4184 .lut_equal = icl_lut_equal, 4185 .read_csc = icl_read_csc, 4186 .get_config = skl_get_config, 4187 }; 4188 4189 static const struct intel_color_funcs glk_color_funcs = { 4190 .color_check = glk_color_check, 4191 .color_commit_noarm = skl_color_commit_noarm, 4192 .color_commit_arm = skl_color_commit_arm, 4193 .load_luts = glk_load_luts, 4194 .read_luts = glk_read_luts, 4195 .lut_equal = glk_lut_equal, 4196 .read_csc = skl_read_csc, 4197 .get_config = skl_get_config, 4198 }; 4199 4200 static const struct intel_color_funcs skl_color_funcs = { 4201 .color_check = ivb_color_check, 4202 .color_commit_noarm = skl_color_commit_noarm, 4203 .color_commit_arm = skl_color_commit_arm, 4204 .load_luts = bdw_load_luts, 4205 .read_luts = bdw_read_luts, 4206 .lut_equal = ivb_lut_equal, 4207 .read_csc = skl_read_csc, 4208 .get_config = skl_get_config, 4209 }; 4210 4211 static const struct intel_color_funcs bdw_color_funcs = { 4212 .color_check = ivb_color_check, 4213 .color_commit_noarm = ilk_color_commit_noarm, 4214 .color_commit_arm = hsw_color_commit_arm, 4215 .load_luts = bdw_load_luts, 4216 .read_luts = bdw_read_luts, 4217 .lut_equal = ivb_lut_equal, 4218 .read_csc = ilk_read_csc, 4219 .get_config = hsw_get_config, 4220 }; 4221 4222 static const struct intel_color_funcs hsw_color_funcs = { 4223 .color_check = ivb_color_check, 4224 .color_commit_noarm = ilk_color_commit_noarm, 4225 .color_commit_arm = hsw_color_commit_arm, 4226 .load_luts = ivb_load_luts, 4227 .read_luts = ivb_read_luts, 4228 .lut_equal = ivb_lut_equal, 4229 .read_csc = ilk_read_csc, 4230 .get_config = hsw_get_config, 4231 }; 4232 4233 static const struct intel_color_funcs ivb_color_funcs = { 4234 .color_check = ivb_color_check, 4235 .color_commit_noarm = ilk_color_commit_noarm, 4236 .color_commit_arm = ilk_color_commit_arm, 4237 .load_luts = ivb_load_luts, 4238 .read_luts = ivb_read_luts, 4239 .lut_equal = ivb_lut_equal, 4240 .read_csc = ilk_read_csc, 4241 .get_config = ilk_get_config, 4242 }; 4243 4244 static const struct intel_color_funcs ilk_color_funcs = { 4245 .color_check = ilk_color_check, 4246 .color_commit_noarm = ilk_color_commit_noarm, 4247 .color_commit_arm = ilk_color_commit_arm, 4248 .load_luts = ilk_load_luts, 4249 .read_luts = ilk_read_luts, 4250 .lut_equal = ilk_lut_equal, 4251 .read_csc = ilk_read_csc, 4252 .get_config = ilk_get_config, 4253 }; 4254 4255 void intel_color_plane_commit_arm(struct intel_dsb *dsb, 4256 const struct intel_plane_state *plane_state) 4257 { 4258 struct intel_display *display = to_intel_display(plane_state); 4259 struct intel_crtc *crtc = to_intel_crtc(plane_state->uapi.crtc); 4260 4261 if (crtc && intel_color_crtc_has_3dlut(display, crtc->pipe)) 4262 glk_lut_3d_commit(dsb, crtc, !!plane_state->hw.lut_3d); 4263 } 4264 4265 static void 4266 intel_color_load_plane_csc_matrix(struct intel_dsb *dsb, 4267 const struct intel_plane_state *plane_state) 4268 { 4269 struct intel_display *display = to_intel_display(plane_state); 4270 4271 if (display->color.funcs->load_plane_csc_matrix) 4272 display->color.funcs->load_plane_csc_matrix(dsb, plane_state); 4273 } 4274 4275 static void 4276 intel_color_load_plane_luts(struct intel_dsb *dsb, 4277 const struct intel_plane_state *plane_state) 4278 { 4279 struct intel_display *display = to_intel_display(plane_state); 4280 4281 if (display->color.funcs->load_plane_luts) 4282 display->color.funcs->load_plane_luts(dsb, plane_state); 4283 } 4284 4285 bool 4286 intel_color_crtc_has_3dlut(struct intel_display *display, enum pipe pipe) 4287 { 4288 if (DISPLAY_VER(display) >= 12) 4289 return pipe == PIPE_A || pipe == PIPE_B; 4290 else 4291 return false; 4292 } 4293 4294 static void 4295 intel_color_load_3dlut(struct intel_dsb *dsb, 4296 const struct intel_plane_state *plane_state) 4297 { 4298 struct intel_display *display = to_intel_display(plane_state); 4299 struct intel_crtc *crtc = to_intel_crtc(plane_state->uapi.crtc); 4300 4301 if (crtc && intel_color_crtc_has_3dlut(display, crtc->pipe)) 4302 glk_load_lut_3d(dsb, crtc, plane_state->hw.lut_3d); 4303 } 4304 4305 void intel_color_plane_program_pipeline(struct intel_dsb *dsb, 4306 const struct intel_plane_state *plane_state) 4307 { 4308 if (plane_state->hw.ctm) 4309 intel_color_load_plane_csc_matrix(dsb, plane_state); 4310 if (plane_state->hw.degamma_lut || plane_state->hw.gamma_lut) 4311 intel_color_load_plane_luts(dsb, plane_state); 4312 if (plane_state->hw.lut_3d) 4313 intel_color_load_3dlut(dsb, plane_state); 4314 } 4315 4316 void intel_color_crtc_init(struct intel_crtc *crtc) 4317 { 4318 struct intel_display *display = to_intel_display(crtc); 4319 int degamma_lut_size, gamma_lut_size; 4320 bool has_ctm; 4321 4322 drm_mode_crtc_set_gamma_size(&crtc->base, 256); 4323 4324 gamma_lut_size = DISPLAY_INFO(display)->color.gamma_lut_size; 4325 degamma_lut_size = DISPLAY_INFO(display)->color.degamma_lut_size; 4326 has_ctm = DISPLAY_VER(display) >= 5; 4327 4328 /* 4329 * "DPALETTE_A: NOTE: The 8-bit (non-10-bit) mode is the 4330 * only mode supported by Alviso and Grantsdale." 4331 * 4332 * Actually looks like this affects all of gen3. 4333 * Confirmed on alv,cst,pnv. Mobile gen2 parts (alm,mgm) 4334 * are confirmed not to suffer from this restriction. 4335 */ 4336 if (DISPLAY_VER(display) == 3 && crtc->pipe == PIPE_A) 4337 gamma_lut_size = 256; 4338 4339 drm_crtc_enable_color_mgmt(&crtc->base, degamma_lut_size, 4340 has_ctm, gamma_lut_size); 4341 } 4342 4343 int intel_color_init(struct intel_display *display) 4344 { 4345 struct drm_property_blob *blob; 4346 4347 if (DISPLAY_VER(display) != 10) 4348 return 0; 4349 4350 blob = create_linear_lut(display, 4351 DISPLAY_INFO(display)->color.degamma_lut_size); 4352 if (IS_ERR(blob)) 4353 return PTR_ERR(blob); 4354 4355 display->color.glk_linear_degamma_lut = blob; 4356 4357 return 0; 4358 } 4359 4360 void intel_color_init_hooks(struct intel_display *display) 4361 { 4362 if (HAS_GMCH(display)) { 4363 if (display->platform.cherryview) 4364 display->color.funcs = &chv_color_funcs; 4365 else if (display->platform.valleyview) 4366 display->color.funcs = &vlv_color_funcs; 4367 else if (DISPLAY_VER(display) >= 4) 4368 display->color.funcs = &i965_color_funcs; 4369 else 4370 display->color.funcs = &i9xx_color_funcs; 4371 } else { 4372 if (DISPLAY_VER(display) >= 12) 4373 display->color.funcs = &tgl_color_funcs; 4374 else if (DISPLAY_VER(display) == 11) 4375 display->color.funcs = &icl_color_funcs; 4376 else if (DISPLAY_VER(display) == 10) 4377 display->color.funcs = &glk_color_funcs; 4378 else if (DISPLAY_VER(display) == 9) 4379 display->color.funcs = &skl_color_funcs; 4380 else if (DISPLAY_VER(display) == 8) 4381 display->color.funcs = &bdw_color_funcs; 4382 else if (display->platform.haswell) 4383 display->color.funcs = &hsw_color_funcs; 4384 else if (DISPLAY_VER(display) == 7) 4385 display->color.funcs = &ivb_color_funcs; 4386 else 4387 display->color.funcs = &ilk_color_funcs; 4388 } 4389 } 4390