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 26 #include <linux/iopoll.h> 27 28 #include <drm/display/drm_dp_dual_mode_helper.h> 29 #include <drm/display/drm_hdmi_helper.h> 30 #include <drm/drm_atomic_helper.h> 31 #include <drm/drm_edid.h> 32 #include <drm/drm_print.h> 33 34 #include "i915_utils.h" 35 #include "intel_de.h" 36 #include "intel_display_regs.h" 37 #include "intel_display_types.h" 38 #include "intel_dp.h" 39 #include "intel_hdmi.h" 40 #include "intel_lspcon.h" 41 42 /* LSPCON OUI Vendor ID(signatures) */ 43 #define LSPCON_VENDOR_PARADE_OUI 0x001CF8 44 #define LSPCON_VENDOR_MCA_OUI 0x0060AD 45 46 #define DPCD_MCA_LSPCON_HDR_STATUS 0x70003 47 #define DPCD_PARADE_LSPCON_HDR_STATUS 0x00511 48 49 /* AUX addresses to write MCA AVI IF */ 50 #define LSPCON_MCA_AVI_IF_WRITE_OFFSET 0x5C0 51 #define LSPCON_MCA_AVI_IF_CTRL 0x5DF 52 #define LSPCON_MCA_AVI_IF_KICKOFF (1 << 0) 53 #define LSPCON_MCA_AVI_IF_HANDLED (1 << 1) 54 55 /* AUX addresses to write Parade AVI IF */ 56 #define LSPCON_PARADE_AVI_IF_WRITE_OFFSET 0x516 57 #define LSPCON_PARADE_AVI_IF_CTRL 0x51E 58 #define LSPCON_PARADE_AVI_IF_KICKOFF (1 << 7) 59 #define LSPCON_PARADE_AVI_IF_DATA_SIZE 32 60 61 static struct intel_lspcon *enc_to_intel_lspcon(struct intel_encoder *encoder) 62 { 63 return &enc_to_dig_port(encoder)->lspcon; 64 } 65 66 static struct intel_dp *lspcon_to_intel_dp(struct intel_lspcon *lspcon) 67 { 68 struct intel_digital_port *dig_port = 69 container_of(lspcon, struct intel_digital_port, lspcon); 70 71 return &dig_port->dp; 72 } 73 74 static const char *lspcon_mode_name(enum drm_lspcon_mode mode) 75 { 76 switch (mode) { 77 case DRM_LSPCON_MODE_PCON: 78 return "PCON"; 79 case DRM_LSPCON_MODE_LS: 80 return "LS"; 81 case DRM_LSPCON_MODE_INVALID: 82 return "INVALID"; 83 default: 84 MISSING_CASE(mode); 85 return "INVALID"; 86 } 87 } 88 89 static bool lspcon_detect_vendor(struct intel_lspcon *lspcon) 90 { 91 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); 92 struct intel_display *display = to_intel_display(intel_dp); 93 struct drm_dp_dpcd_ident *ident; 94 u32 vendor_oui; 95 96 if (drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc, drm_dp_is_branch(intel_dp->dpcd))) { 97 drm_err(display->drm, "Can't read description\n"); 98 return false; 99 } 100 101 ident = &intel_dp->desc.ident; 102 vendor_oui = (ident->oui[0] << 16) | (ident->oui[1] << 8) | 103 ident->oui[2]; 104 105 switch (vendor_oui) { 106 case LSPCON_VENDOR_MCA_OUI: 107 lspcon->vendor = LSPCON_VENDOR_MCA; 108 drm_dbg_kms(display->drm, "Vendor: Mega Chips\n"); 109 break; 110 111 case LSPCON_VENDOR_PARADE_OUI: 112 lspcon->vendor = LSPCON_VENDOR_PARADE; 113 drm_dbg_kms(display->drm, "Vendor: Parade Tech\n"); 114 break; 115 116 default: 117 drm_err(display->drm, "Invalid/Unknown vendor OUI\n"); 118 return false; 119 } 120 121 return true; 122 } 123 124 static u32 get_hdr_status_reg(struct intel_lspcon *lspcon) 125 { 126 if (lspcon->vendor == LSPCON_VENDOR_MCA) 127 return DPCD_MCA_LSPCON_HDR_STATUS; 128 else 129 return DPCD_PARADE_LSPCON_HDR_STATUS; 130 } 131 132 bool intel_lspcon_detect_hdr_capability(struct intel_digital_port *dig_port) 133 { 134 struct intel_lspcon *lspcon = &dig_port->lspcon; 135 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); 136 struct intel_display *display = to_intel_display(intel_dp); 137 u8 hdr_caps; 138 int ret; 139 140 ret = drm_dp_dpcd_read(&intel_dp->aux, get_hdr_status_reg(lspcon), 141 &hdr_caps, 1); 142 143 if (ret < 0) { 144 drm_dbg_kms(display->drm, "HDR capability detection failed\n"); 145 lspcon->hdr_supported = false; 146 } else if (hdr_caps & 0x1) { 147 drm_dbg_kms(display->drm, "LSPCON capable of HDR\n"); 148 lspcon->hdr_supported = true; 149 } 150 151 return lspcon->hdr_supported; 152 } 153 154 static enum drm_lspcon_mode lspcon_get_current_mode(struct intel_lspcon *lspcon) 155 { 156 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); 157 struct intel_display *display = to_intel_display(intel_dp); 158 enum drm_lspcon_mode current_mode; 159 struct i2c_adapter *ddc = &intel_dp->aux.ddc; 160 161 if (drm_lspcon_get_mode(intel_dp->aux.drm_dev, ddc, ¤t_mode)) { 162 drm_dbg_kms(display->drm, "Error reading LSPCON mode\n"); 163 return DRM_LSPCON_MODE_INVALID; 164 } 165 return current_mode; 166 } 167 168 static int lspcon_get_mode_settle_timeout(struct intel_lspcon *lspcon) 169 { 170 /* 171 * On some CometLake-based device designs the Parade PS175 takes more 172 * than 400ms to settle in PCON mode. 100 reboot trials on one device 173 * resulted in a median settle time of 440ms and a maximum of 444ms. 174 * Even after increasing the timeout to 500ms, 2% of devices still had 175 * this error. So this sets the timeout to 800ms. 176 */ 177 return lspcon->vendor == LSPCON_VENDOR_PARADE ? 800 : 400; 178 } 179 180 static enum drm_lspcon_mode lspcon_wait_mode(struct intel_lspcon *lspcon, 181 enum drm_lspcon_mode mode) 182 { 183 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); 184 struct intel_display *display = to_intel_display(intel_dp); 185 enum drm_lspcon_mode current_mode; 186 int timeout_us; 187 int ret; 188 189 current_mode = lspcon_get_current_mode(lspcon); 190 if (current_mode == mode) 191 goto out; 192 193 drm_dbg_kms(display->drm, "Waiting for LSPCON mode %s to settle\n", 194 lspcon_mode_name(mode)); 195 196 timeout_us = lspcon_get_mode_settle_timeout(lspcon) * 1000; 197 198 ret = poll_timeout_us(current_mode = lspcon_get_current_mode(lspcon), 199 current_mode == mode, 200 5000, timeout_us, false); 201 if (ret) 202 drm_err(display->drm, "LSPCON mode hasn't settled\n"); 203 204 out: 205 drm_dbg_kms(display->drm, "Current LSPCON mode %s\n", 206 lspcon_mode_name(current_mode)); 207 208 return current_mode; 209 } 210 211 static int lspcon_change_mode(struct intel_lspcon *lspcon, 212 enum drm_lspcon_mode mode) 213 { 214 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); 215 struct intel_display *display = to_intel_display(intel_dp); 216 int err; 217 enum drm_lspcon_mode current_mode; 218 struct i2c_adapter *ddc = &intel_dp->aux.ddc; 219 220 err = drm_lspcon_get_mode(intel_dp->aux.drm_dev, ddc, ¤t_mode); 221 if (err) { 222 drm_err(display->drm, "Error reading LSPCON mode\n"); 223 return err; 224 } 225 226 if (current_mode == mode) { 227 drm_dbg_kms(display->drm, "Current mode = desired LSPCON mode\n"); 228 return 0; 229 } 230 231 err = drm_lspcon_set_mode(intel_dp->aux.drm_dev, ddc, mode, 232 lspcon_get_mode_settle_timeout(lspcon)); 233 if (err < 0) { 234 drm_err(display->drm, "LSPCON mode change failed\n"); 235 return err; 236 } 237 238 lspcon->mode = mode; 239 drm_dbg_kms(display->drm, "LSPCON mode changed done\n"); 240 return 0; 241 } 242 243 static bool lspcon_wake_native_aux_ch(struct intel_lspcon *lspcon) 244 { 245 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); 246 struct intel_display *display = to_intel_display(intel_dp); 247 u8 rev; 248 249 if (drm_dp_dpcd_readb(&lspcon_to_intel_dp(lspcon)->aux, DP_DPCD_REV, 250 &rev) != 1) { 251 drm_dbg_kms(display->drm, "Native AUX CH down\n"); 252 return false; 253 } 254 255 drm_dbg_kms(display->drm, "Native AUX CH up, DPCD version: %d.%d\n", 256 rev >> 4, rev & 0xf); 257 258 return true; 259 } 260 261 static bool lspcon_probe(struct intel_lspcon *lspcon) 262 { 263 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); 264 struct intel_display *display = to_intel_display(intel_dp); 265 struct i2c_adapter *ddc = &intel_dp->aux.ddc; 266 enum drm_dp_dual_mode_type adaptor_type; 267 enum drm_lspcon_mode expected_mode; 268 int retry; 269 270 expected_mode = lspcon_wake_native_aux_ch(lspcon) ? 271 DRM_LSPCON_MODE_PCON : DRM_LSPCON_MODE_LS; 272 273 /* Lets probe the adaptor and check its type */ 274 for (retry = 0; retry < 6; retry++) { 275 if (retry) 276 usleep_range(500, 1000); 277 278 adaptor_type = drm_dp_dual_mode_detect(intel_dp->aux.drm_dev, ddc); 279 if (adaptor_type == DRM_DP_DUAL_MODE_LSPCON) 280 break; 281 } 282 283 if (adaptor_type != DRM_DP_DUAL_MODE_LSPCON) { 284 drm_dbg_kms(display->drm, "No LSPCON detected, found %s\n", 285 drm_dp_get_dual_mode_type_name(adaptor_type)); 286 return false; 287 } 288 289 /* Yay ... got a LSPCON device */ 290 drm_dbg_kms(display->drm, "LSPCON detected\n"); 291 lspcon->mode = lspcon_wait_mode(lspcon, expected_mode); 292 293 /* 294 * In the SW state machine, lets Put LSPCON in PCON mode only. 295 * In this way, it will work with both HDMI 1.4 sinks as well as HDMI 296 * 2.0 sinks. 297 */ 298 if (lspcon->mode != DRM_LSPCON_MODE_PCON) { 299 if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON) < 0) { 300 drm_err(display->drm, "LSPCON mode change to PCON failed\n"); 301 return false; 302 } 303 } 304 return true; 305 } 306 307 static void lspcon_resume_in_pcon_wa(struct intel_lspcon *lspcon) 308 { 309 struct intel_dp *intel_dp = lspcon_to_intel_dp(lspcon); 310 struct intel_display *display = to_intel_display(intel_dp); 311 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 312 unsigned long start = jiffies; 313 314 while (1) { 315 if (intel_digital_port_connected(&dig_port->base)) { 316 drm_dbg_kms(display->drm, "LSPCON recovering in PCON mode after %u ms\n", 317 jiffies_to_msecs(jiffies - start)); 318 return; 319 } 320 321 if (time_after(jiffies, start + msecs_to_jiffies(1000))) 322 break; 323 324 usleep_range(10000, 15000); 325 } 326 327 drm_dbg_kms(display->drm, "LSPCON DP descriptor mismatch after resume\n"); 328 } 329 330 static bool lspcon_parade_fw_ready(struct drm_dp_aux *aux) 331 { 332 u8 avi_if_ctrl; 333 u8 retry; 334 ssize_t ret; 335 336 /* Check if LSPCON FW is ready for data */ 337 for (retry = 0; retry < 5; retry++) { 338 if (retry) 339 usleep_range(200, 300); 340 341 ret = drm_dp_dpcd_read(aux, LSPCON_PARADE_AVI_IF_CTRL, 342 &avi_if_ctrl, 1); 343 if (ret < 0) { 344 drm_err(aux->drm_dev, "Failed to read AVI IF control\n"); 345 return false; 346 } 347 348 if ((avi_if_ctrl & LSPCON_PARADE_AVI_IF_KICKOFF) == 0) 349 return true; 350 } 351 352 drm_err(aux->drm_dev, "Parade FW not ready to accept AVI IF\n"); 353 return false; 354 } 355 356 static bool _lspcon_parade_write_infoframe_blocks(struct drm_dp_aux *aux, 357 u8 *avi_buf) 358 { 359 u8 avi_if_ctrl; 360 u8 block_count = 0; 361 u8 *data; 362 u16 reg; 363 ssize_t ret; 364 365 while (block_count < 4) { 366 if (!lspcon_parade_fw_ready(aux)) { 367 drm_dbg_kms(aux->drm_dev, "LSPCON FW not ready, block %d\n", 368 block_count); 369 return false; 370 } 371 372 reg = LSPCON_PARADE_AVI_IF_WRITE_OFFSET; 373 data = avi_buf + block_count * 8; 374 ret = drm_dp_dpcd_write(aux, reg, data, 8); 375 if (ret < 0) { 376 drm_err(aux->drm_dev, "Failed to write AVI IF block %d\n", 377 block_count); 378 return false; 379 } 380 381 /* 382 * Once a block of data is written, we have to inform the FW 383 * about this by writing into avi infoframe control register: 384 * - set the kickoff bit[7] to 1 385 * - write the block no. to bits[1:0] 386 */ 387 reg = LSPCON_PARADE_AVI_IF_CTRL; 388 avi_if_ctrl = LSPCON_PARADE_AVI_IF_KICKOFF | block_count; 389 ret = drm_dp_dpcd_write(aux, reg, &avi_if_ctrl, 1); 390 if (ret < 0) { 391 drm_err(aux->drm_dev, "Failed to update (0x%x), block %d\n", 392 reg, block_count); 393 return false; 394 } 395 396 block_count++; 397 } 398 399 drm_dbg_kms(aux->drm_dev, "Wrote AVI IF blocks successfully\n"); 400 return true; 401 } 402 403 static bool _lspcon_write_avi_infoframe_parade(struct drm_dp_aux *aux, 404 const u8 *frame, 405 ssize_t len) 406 { 407 u8 avi_if[LSPCON_PARADE_AVI_IF_DATA_SIZE] = {1, }; 408 409 /* 410 * Parade's frames contains 32 bytes of data, divided 411 * into 4 frames: 412 * Token byte (first byte of first frame, must be non-zero) 413 * HB0 to HB2 from AVI IF (3 bytes header) 414 * PB0 to PB27 from AVI IF (28 bytes data) 415 * So it should look like this 416 * first block: | <token> <HB0-HB2> <DB0-DB3> | 417 * next 3 blocks: |<DB4-DB11>|<DB12-DB19>|<DB20-DB28>| 418 */ 419 420 if (len > LSPCON_PARADE_AVI_IF_DATA_SIZE - 1) { 421 drm_err(aux->drm_dev, "Invalid length of infoframes\n"); 422 return false; 423 } 424 425 memcpy(&avi_if[1], frame, len); 426 427 if (!_lspcon_parade_write_infoframe_blocks(aux, avi_if)) { 428 drm_dbg_kms(aux->drm_dev, "Failed to write infoframe blocks\n"); 429 return false; 430 } 431 432 return true; 433 } 434 435 static bool _lspcon_write_avi_infoframe_mca(struct drm_dp_aux *aux, 436 const u8 *buffer, ssize_t len) 437 { 438 int ret; 439 u32 val = 0; 440 u32 retry; 441 u16 reg; 442 const u8 *data = buffer; 443 444 reg = LSPCON_MCA_AVI_IF_WRITE_OFFSET; 445 while (val < len) { 446 /* DPCD write for AVI IF can fail on a slow FW day, so retry */ 447 for (retry = 0; retry < 5; retry++) { 448 ret = drm_dp_dpcd_write(aux, reg, (void *)data, 1); 449 if (ret == 1) { 450 break; 451 } else if (retry < 4) { 452 mdelay(50); 453 continue; 454 } else { 455 drm_err(aux->drm_dev, "DPCD write failed at:0x%x\n", reg); 456 return false; 457 } 458 } 459 val++; reg++; data++; 460 } 461 462 val = 0; 463 reg = LSPCON_MCA_AVI_IF_CTRL; 464 ret = drm_dp_dpcd_read(aux, reg, &val, 1); 465 if (ret < 0) { 466 drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg); 467 return false; 468 } 469 470 /* Indicate LSPCON chip about infoframe, clear bit 1 and set bit 0 */ 471 val &= ~LSPCON_MCA_AVI_IF_HANDLED; 472 val |= LSPCON_MCA_AVI_IF_KICKOFF; 473 474 ret = drm_dp_dpcd_write(aux, reg, &val, 1); 475 if (ret < 0) { 476 drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg); 477 return false; 478 } 479 480 val = 0; 481 ret = drm_dp_dpcd_read(aux, reg, &val, 1); 482 if (ret < 0) { 483 drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg); 484 return false; 485 } 486 487 if (val == LSPCON_MCA_AVI_IF_HANDLED) 488 drm_dbg_kms(aux->drm_dev, "AVI IF handled by FW\n"); 489 490 return true; 491 } 492 493 void lspcon_write_infoframe(struct intel_encoder *encoder, 494 const struct intel_crtc_state *crtc_state, 495 unsigned int type, 496 const void *frame, ssize_t len) 497 { 498 struct intel_display *display = to_intel_display(encoder); 499 struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 500 struct intel_lspcon *lspcon = enc_to_intel_lspcon(encoder); 501 bool ret = true; 502 503 switch (type) { 504 case HDMI_INFOFRAME_TYPE_AVI: 505 if (lspcon->vendor == LSPCON_VENDOR_MCA) 506 ret = _lspcon_write_avi_infoframe_mca(&intel_dp->aux, 507 frame, len); 508 else 509 ret = _lspcon_write_avi_infoframe_parade(&intel_dp->aux, 510 frame, len); 511 break; 512 case HDMI_PACKET_TYPE_GAMUT_METADATA: 513 drm_dbg_kms(display->drm, "Update HDR metadata for lspcon\n"); 514 /* It uses the legacy hsw implementation for the same */ 515 hsw_write_infoframe(encoder, crtc_state, type, frame, len); 516 break; 517 default: 518 return; 519 } 520 521 if (!ret) { 522 drm_err(display->drm, "Failed to write infoframes\n"); 523 return; 524 } 525 } 526 527 void lspcon_read_infoframe(struct intel_encoder *encoder, 528 const struct intel_crtc_state *crtc_state, 529 unsigned int type, 530 void *frame, ssize_t len) 531 { 532 /* FIXME implement for AVI Infoframe as well */ 533 if (type == HDMI_PACKET_TYPE_GAMUT_METADATA) 534 hsw_read_infoframe(encoder, crtc_state, type, 535 frame, len); 536 } 537 538 void lspcon_set_infoframes(struct intel_encoder *encoder, 539 bool enable, 540 const struct intel_crtc_state *crtc_state, 541 const struct drm_connector_state *conn_state) 542 { 543 struct intel_display *display = to_intel_display(encoder); 544 struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 545 struct intel_lspcon *lspcon = &dig_port->lspcon; 546 const struct drm_display_mode *adjusted_mode = 547 &crtc_state->hw.adjusted_mode; 548 union hdmi_infoframe frame; 549 u8 buf[VIDEO_DIP_DATA_SIZE]; 550 ssize_t ret; 551 552 if (!lspcon->active) { 553 drm_err(display->drm, "Writing infoframes while LSPCON disabled ?\n"); 554 return; 555 } 556 557 /* FIXME precompute infoframes */ 558 559 ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, 560 conn_state->connector, 561 adjusted_mode); 562 if (ret < 0) { 563 drm_err(display->drm, "couldn't fill AVI infoframe\n"); 564 return; 565 } 566 567 /* 568 * Currently there is no interface defined to 569 * check user preference between RGB/YCBCR444 570 * or YCBCR420. So the only possible case for 571 * YCBCR444 usage is driving YCBCR420 output 572 * with LSPCON, when pipe is configured for 573 * YCBCR444 output and LSPCON takes care of 574 * downsampling it. 575 */ 576 if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) 577 frame.avi.colorspace = HDMI_COLORSPACE_YUV420; 578 else 579 frame.avi.colorspace = HDMI_COLORSPACE_RGB; 580 581 /* Set the Colorspace as per the HDMI spec */ 582 drm_hdmi_avi_infoframe_colorimetry(&frame.avi, conn_state); 583 584 /* nonsense combination */ 585 drm_WARN_ON(encoder->base.dev, crtc_state->limited_color_range && 586 crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB); 587 588 if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_RGB) { 589 drm_hdmi_avi_infoframe_quant_range(&frame.avi, 590 conn_state->connector, 591 adjusted_mode, 592 crtc_state->limited_color_range ? 593 HDMI_QUANTIZATION_RANGE_LIMITED : 594 HDMI_QUANTIZATION_RANGE_FULL); 595 } else { 596 frame.avi.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT; 597 frame.avi.ycc_quantization_range = HDMI_YCC_QUANTIZATION_RANGE_LIMITED; 598 } 599 600 drm_hdmi_avi_infoframe_content_type(&frame.avi, conn_state); 601 602 ret = hdmi_infoframe_pack(&frame, buf, sizeof(buf)); 603 if (ret < 0) { 604 drm_err(display->drm, "Failed to pack AVI IF\n"); 605 return; 606 } 607 608 dig_port->write_infoframe(encoder, crtc_state, HDMI_INFOFRAME_TYPE_AVI, 609 buf, ret); 610 } 611 612 static bool _lspcon_read_avi_infoframe_enabled_mca(struct drm_dp_aux *aux) 613 { 614 int ret; 615 u32 val = 0; 616 u16 reg = LSPCON_MCA_AVI_IF_CTRL; 617 618 ret = drm_dp_dpcd_read(aux, reg, &val, 1); 619 if (ret < 0) { 620 drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg); 621 return false; 622 } 623 624 return val & LSPCON_MCA_AVI_IF_KICKOFF; 625 } 626 627 static bool _lspcon_read_avi_infoframe_enabled_parade(struct drm_dp_aux *aux) 628 { 629 int ret; 630 u32 val = 0; 631 u16 reg = LSPCON_PARADE_AVI_IF_CTRL; 632 633 ret = drm_dp_dpcd_read(aux, reg, &val, 1); 634 if (ret < 0) { 635 drm_err(aux->drm_dev, "DPCD read failed, address 0x%x\n", reg); 636 return false; 637 } 638 639 return val & LSPCON_PARADE_AVI_IF_KICKOFF; 640 } 641 642 u32 lspcon_infoframes_enabled(struct intel_encoder *encoder, 643 const struct intel_crtc_state *pipe_config) 644 { 645 struct intel_display *display = to_intel_display(encoder); 646 struct intel_dp *intel_dp = enc_to_intel_dp(encoder); 647 struct intel_lspcon *lspcon = enc_to_intel_lspcon(encoder); 648 bool infoframes_enabled; 649 u32 val = 0; 650 u32 mask, tmp; 651 652 if (lspcon->vendor == LSPCON_VENDOR_MCA) 653 infoframes_enabled = _lspcon_read_avi_infoframe_enabled_mca(&intel_dp->aux); 654 else 655 infoframes_enabled = _lspcon_read_avi_infoframe_enabled_parade(&intel_dp->aux); 656 657 if (infoframes_enabled) 658 val |= intel_hdmi_infoframe_enable(HDMI_INFOFRAME_TYPE_AVI); 659 660 if (lspcon->hdr_supported) { 661 tmp = intel_de_read(display, 662 HSW_TVIDEO_DIP_CTL(display, pipe_config->cpu_transcoder)); 663 mask = VIDEO_DIP_ENABLE_GMP_HSW; 664 665 if (tmp & mask) 666 val |= intel_hdmi_infoframe_enable(HDMI_PACKET_TYPE_GAMUT_METADATA); 667 } 668 669 return val; 670 } 671 672 void intel_lspcon_wait_pcon_mode(struct intel_digital_port *dig_port) 673 { 674 struct intel_lspcon *lspcon = &dig_port->lspcon; 675 676 lspcon_wait_mode(lspcon, DRM_LSPCON_MODE_PCON); 677 } 678 679 bool intel_lspcon_init(struct intel_digital_port *dig_port) 680 { 681 struct intel_display *display = to_intel_display(dig_port); 682 struct intel_dp *intel_dp = &dig_port->dp; 683 struct intel_lspcon *lspcon = &dig_port->lspcon; 684 struct drm_connector *connector = &intel_dp->attached_connector->base; 685 686 lspcon->active = false; 687 lspcon->mode = DRM_LSPCON_MODE_INVALID; 688 689 if (!lspcon_probe(lspcon)) { 690 drm_err(display->drm, "Failed to probe lspcon\n"); 691 return false; 692 } 693 694 if (drm_dp_read_dpcd_caps(&intel_dp->aux, intel_dp->dpcd) != 0) { 695 drm_err(display->drm, "LSPCON DPCD read failed\n"); 696 return false; 697 } 698 699 if (!lspcon_detect_vendor(lspcon)) { 700 drm_err(display->drm, "LSPCON vendor detection failed\n"); 701 return false; 702 } 703 704 connector->ycbcr_420_allowed = true; 705 lspcon->active = true; 706 drm_dbg_kms(display->drm, "Success: LSPCON init\n"); 707 return true; 708 } 709 710 bool intel_lspcon_active(struct intel_digital_port *dig_port) 711 { 712 struct intel_lspcon *lspcon = &dig_port->lspcon; 713 714 return lspcon->active; 715 } 716 717 u32 intel_lspcon_infoframes_enabled(struct intel_encoder *encoder, 718 const struct intel_crtc_state *pipe_config) 719 { 720 struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 721 722 return dig_port->infoframes_enabled(encoder, pipe_config); 723 } 724 725 void intel_lspcon_resume(struct intel_digital_port *dig_port) 726 { 727 struct intel_display *display = to_intel_display(dig_port); 728 struct intel_lspcon *lspcon = &dig_port->lspcon; 729 enum drm_lspcon_mode expected_mode; 730 731 if (!intel_bios_encoder_is_lspcon(dig_port->base.devdata)) 732 return; 733 734 if (!lspcon->active) { 735 if (!intel_lspcon_init(dig_port)) { 736 drm_err(display->drm, "LSPCON init failed on port %c\n", 737 port_name(dig_port->base.port)); 738 return; 739 } 740 } 741 742 if (lspcon_wake_native_aux_ch(lspcon)) { 743 expected_mode = DRM_LSPCON_MODE_PCON; 744 lspcon_resume_in_pcon_wa(lspcon); 745 } else { 746 expected_mode = DRM_LSPCON_MODE_LS; 747 } 748 749 if (lspcon_wait_mode(lspcon, expected_mode) == DRM_LSPCON_MODE_PCON) 750 return; 751 752 if (lspcon_change_mode(lspcon, DRM_LSPCON_MODE_PCON)) 753 drm_err(display->drm, "LSPCON resume failed\n"); 754 else 755 drm_dbg_kms(display->drm, "LSPCON resume success\n"); 756 } 757