1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2019 Intel Corporation 4 */ 5 6 #include "i915_drv.h" 7 #include "i915_reg.h" 8 #include "intel_ddi.h" 9 #include "intel_de.h" 10 #include "intel_display.h" 11 #include "intel_display_power_map.h" 12 #include "intel_display_types.h" 13 #include "intel_dkl_phy_regs.h" 14 #include "intel_dp_mst.h" 15 #include "intel_mg_phy_regs.h" 16 #include "intel_tc.h" 17 18 static const char *tc_port_mode_name(enum tc_port_mode mode) 19 { 20 static const char * const names[] = { 21 [TC_PORT_DISCONNECTED] = "disconnected", 22 [TC_PORT_TBT_ALT] = "tbt-alt", 23 [TC_PORT_DP_ALT] = "dp-alt", 24 [TC_PORT_LEGACY] = "legacy", 25 }; 26 27 if (WARN_ON(mode >= ARRAY_SIZE(names))) 28 mode = TC_PORT_DISCONNECTED; 29 30 return names[mode]; 31 } 32 33 static bool intel_tc_port_in_mode(struct intel_digital_port *dig_port, 34 enum tc_port_mode mode) 35 { 36 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 37 enum phy phy = intel_port_to_phy(i915, dig_port->base.port); 38 39 return intel_phy_is_tc(i915, phy) && dig_port->tc_mode == mode; 40 } 41 42 bool intel_tc_port_in_tbt_alt_mode(struct intel_digital_port *dig_port) 43 { 44 return intel_tc_port_in_mode(dig_port, TC_PORT_TBT_ALT); 45 } 46 47 bool intel_tc_port_in_dp_alt_mode(struct intel_digital_port *dig_port) 48 { 49 return intel_tc_port_in_mode(dig_port, TC_PORT_DP_ALT); 50 } 51 52 bool intel_tc_port_in_legacy_mode(struct intel_digital_port *dig_port) 53 { 54 return intel_tc_port_in_mode(dig_port, TC_PORT_LEGACY); 55 } 56 57 bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port) 58 { 59 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 60 61 return (DISPLAY_VER(i915) == 11 && dig_port->tc_legacy_port) || 62 IS_ALDERLAKE_P(i915); 63 } 64 65 static enum intel_display_power_domain 66 tc_cold_get_power_domain(struct intel_digital_port *dig_port, enum tc_port_mode mode) 67 { 68 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 69 70 if (mode == TC_PORT_TBT_ALT || !intel_tc_cold_requires_aux_pw(dig_port)) 71 return POWER_DOMAIN_TC_COLD_OFF; 72 73 return intel_display_power_legacy_aux_domain(i915, dig_port->aux_ch); 74 } 75 76 static intel_wakeref_t 77 tc_cold_block_in_mode(struct intel_digital_port *dig_port, enum tc_port_mode mode, 78 enum intel_display_power_domain *domain) 79 { 80 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 81 82 *domain = tc_cold_get_power_domain(dig_port, mode); 83 84 return intel_display_power_get(i915, *domain); 85 } 86 87 static intel_wakeref_t 88 tc_cold_block(struct intel_digital_port *dig_port, enum intel_display_power_domain *domain) 89 { 90 return tc_cold_block_in_mode(dig_port, dig_port->tc_mode, domain); 91 } 92 93 static void 94 tc_cold_unblock(struct intel_digital_port *dig_port, enum intel_display_power_domain domain, 95 intel_wakeref_t wakeref) 96 { 97 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 98 99 /* 100 * wakeref == -1, means some error happened saving save_depot_stack but 101 * power should still be put down and 0 is a invalid save_depot_stack 102 * id so can be used to skip it for non TC legacy ports. 103 */ 104 if (wakeref == 0) 105 return; 106 107 intel_display_power_put(i915, domain, wakeref); 108 } 109 110 static void 111 assert_tc_cold_blocked(struct intel_digital_port *dig_port) 112 { 113 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 114 bool enabled; 115 116 enabled = intel_display_power_is_enabled(i915, 117 tc_cold_get_power_domain(dig_port, 118 dig_port->tc_mode)); 119 drm_WARN_ON(&i915->drm, !enabled); 120 } 121 122 static enum intel_display_power_domain 123 tc_port_power_domain(struct intel_digital_port *dig_port) 124 { 125 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 126 enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); 127 128 return POWER_DOMAIN_PORT_DDI_LANES_TC1 + tc_port - TC_PORT_1; 129 } 130 131 static void 132 assert_tc_port_power_enabled(struct intel_digital_port *dig_port) 133 { 134 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 135 136 drm_WARN_ON(&i915->drm, 137 !intel_display_power_is_enabled(i915, tc_port_power_domain(dig_port))); 138 } 139 140 u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port) 141 { 142 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 143 u32 lane_mask; 144 145 lane_mask = intel_de_read(i915, PORT_TX_DFLEXDPSP(dig_port->tc_phy_fia)); 146 147 drm_WARN_ON(&i915->drm, lane_mask == 0xffffffff); 148 assert_tc_cold_blocked(dig_port); 149 150 lane_mask &= DP_LANE_ASSIGNMENT_MASK(dig_port->tc_phy_fia_idx); 151 return lane_mask >> DP_LANE_ASSIGNMENT_SHIFT(dig_port->tc_phy_fia_idx); 152 } 153 154 u32 intel_tc_port_get_pin_assignment_mask(struct intel_digital_port *dig_port) 155 { 156 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 157 u32 pin_mask; 158 159 pin_mask = intel_de_read(i915, PORT_TX_DFLEXPA1(dig_port->tc_phy_fia)); 160 161 drm_WARN_ON(&i915->drm, pin_mask == 0xffffffff); 162 assert_tc_cold_blocked(dig_port); 163 164 return (pin_mask & DP_PIN_ASSIGNMENT_MASK(dig_port->tc_phy_fia_idx)) >> 165 DP_PIN_ASSIGNMENT_SHIFT(dig_port->tc_phy_fia_idx); 166 } 167 168 int intel_tc_port_fia_max_lane_count(struct intel_digital_port *dig_port) 169 { 170 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 171 intel_wakeref_t wakeref; 172 u32 lane_mask; 173 174 if (dig_port->tc_mode != TC_PORT_DP_ALT) 175 return 4; 176 177 assert_tc_cold_blocked(dig_port); 178 179 lane_mask = 0; 180 with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref) 181 lane_mask = intel_tc_port_get_lane_mask(dig_port); 182 183 switch (lane_mask) { 184 default: 185 MISSING_CASE(lane_mask); 186 fallthrough; 187 case 0x1: 188 case 0x2: 189 case 0x4: 190 case 0x8: 191 return 1; 192 case 0x3: 193 case 0xc: 194 return 2; 195 case 0xf: 196 return 4; 197 } 198 } 199 200 void intel_tc_port_set_fia_lane_count(struct intel_digital_port *dig_port, 201 int required_lanes) 202 { 203 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 204 bool lane_reversal = dig_port->saved_port_bits & DDI_BUF_PORT_REVERSAL; 205 u32 val; 206 207 drm_WARN_ON(&i915->drm, 208 lane_reversal && dig_port->tc_mode != TC_PORT_LEGACY); 209 210 assert_tc_cold_blocked(dig_port); 211 212 val = intel_de_read(i915, PORT_TX_DFLEXDPMLE1(dig_port->tc_phy_fia)); 213 val &= ~DFLEXDPMLE1_DPMLETC_MASK(dig_port->tc_phy_fia_idx); 214 215 switch (required_lanes) { 216 case 1: 217 val |= lane_reversal ? 218 DFLEXDPMLE1_DPMLETC_ML3(dig_port->tc_phy_fia_idx) : 219 DFLEXDPMLE1_DPMLETC_ML0(dig_port->tc_phy_fia_idx); 220 break; 221 case 2: 222 val |= lane_reversal ? 223 DFLEXDPMLE1_DPMLETC_ML3_2(dig_port->tc_phy_fia_idx) : 224 DFLEXDPMLE1_DPMLETC_ML1_0(dig_port->tc_phy_fia_idx); 225 break; 226 case 4: 227 val |= DFLEXDPMLE1_DPMLETC_ML3_0(dig_port->tc_phy_fia_idx); 228 break; 229 default: 230 MISSING_CASE(required_lanes); 231 } 232 233 intel_de_write(i915, PORT_TX_DFLEXDPMLE1(dig_port->tc_phy_fia), val); 234 } 235 236 static void tc_port_fixup_legacy_flag(struct intel_digital_port *dig_port, 237 u32 live_status_mask) 238 { 239 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 240 u32 valid_hpd_mask; 241 242 if (dig_port->tc_legacy_port) 243 valid_hpd_mask = BIT(TC_PORT_LEGACY); 244 else 245 valid_hpd_mask = BIT(TC_PORT_DP_ALT) | 246 BIT(TC_PORT_TBT_ALT); 247 248 if (!(live_status_mask & ~valid_hpd_mask)) 249 return; 250 251 /* If live status mismatches the VBT flag, trust the live status. */ 252 drm_dbg_kms(&i915->drm, 253 "Port %s: live status %08x mismatches the legacy port flag %08x, fixing flag\n", 254 dig_port->tc_port_name, live_status_mask, valid_hpd_mask); 255 256 dig_port->tc_legacy_port = !dig_port->tc_legacy_port; 257 } 258 259 static u32 icl_tc_port_live_status_mask(struct intel_digital_port *dig_port) 260 { 261 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 262 u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; 263 u32 mask = 0; 264 u32 val; 265 266 val = intel_de_read(i915, PORT_TX_DFLEXDPSP(dig_port->tc_phy_fia)); 267 268 if (val == 0xffffffff) { 269 drm_dbg_kms(&i915->drm, 270 "Port %s: PHY in TCCOLD, nothing connected\n", 271 dig_port->tc_port_name); 272 return mask; 273 } 274 275 if (val & TC_LIVE_STATE_TBT(dig_port->tc_phy_fia_idx)) 276 mask |= BIT(TC_PORT_TBT_ALT); 277 if (val & TC_LIVE_STATE_TC(dig_port->tc_phy_fia_idx)) 278 mask |= BIT(TC_PORT_DP_ALT); 279 280 if (intel_de_read(i915, SDEISR) & isr_bit) 281 mask |= BIT(TC_PORT_LEGACY); 282 283 /* The sink can be connected only in a single mode. */ 284 if (!drm_WARN_ON_ONCE(&i915->drm, hweight32(mask) > 1)) 285 tc_port_fixup_legacy_flag(dig_port, mask); 286 287 return mask; 288 } 289 290 static u32 adl_tc_port_live_status_mask(struct intel_digital_port *dig_port) 291 { 292 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 293 enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); 294 u32 isr_bit = i915->display.hotplug.pch_hpd[dig_port->base.hpd_pin]; 295 u32 val, mask = 0; 296 297 /* 298 * On ADL-P HW/FW will wake from TCCOLD to complete the read access of 299 * registers in IOM. Note that this doesn't apply to PHY and FIA 300 * registers. 301 */ 302 val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); 303 if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT) 304 mask |= BIT(TC_PORT_DP_ALT); 305 if (val & TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT) 306 mask |= BIT(TC_PORT_TBT_ALT); 307 308 if (intel_de_read(i915, SDEISR) & isr_bit) 309 mask |= BIT(TC_PORT_LEGACY); 310 311 /* The sink can be connected only in a single mode. */ 312 if (!drm_WARN_ON(&i915->drm, hweight32(mask) > 1)) 313 tc_port_fixup_legacy_flag(dig_port, mask); 314 315 return mask; 316 } 317 318 static u32 tc_port_live_status_mask(struct intel_digital_port *dig_port) 319 { 320 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 321 322 if (IS_ALDERLAKE_P(i915)) 323 return adl_tc_port_live_status_mask(dig_port); 324 325 return icl_tc_port_live_status_mask(dig_port); 326 } 327 328 /* 329 * Return the PHY status complete flag indicating that display can acquire the 330 * PHY ownership. The IOM firmware sets this flag when a DP-alt or legacy sink 331 * is connected and it's ready to switch the ownership to display. The flag 332 * will be left cleared when a TBT-alt sink is connected, where the PHY is 333 * owned by the TBT subsystem and so switching the ownership to display is not 334 * required. 335 */ 336 static bool icl_tc_phy_status_complete(struct intel_digital_port *dig_port) 337 { 338 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 339 u32 val; 340 341 val = intel_de_read(i915, PORT_TX_DFLEXDPPMS(dig_port->tc_phy_fia)); 342 if (val == 0xffffffff) { 343 drm_dbg_kms(&i915->drm, 344 "Port %s: PHY in TCCOLD, assuming not complete\n", 345 dig_port->tc_port_name); 346 return false; 347 } 348 349 return val & DP_PHY_MODE_STATUS_COMPLETED(dig_port->tc_phy_fia_idx); 350 } 351 352 /* 353 * Return the PHY status complete flag indicating that display can acquire the 354 * PHY ownership. The IOM firmware sets this flag when it's ready to switch 355 * the ownership to display, regardless of what sink is connected (TBT-alt, 356 * DP-alt, legacy or nothing). For TBT-alt sinks the PHY is owned by the TBT 357 * subsystem and so switching the ownership to display is not required. 358 */ 359 static bool adl_tc_phy_status_complete(struct intel_digital_port *dig_port) 360 { 361 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 362 enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port); 363 u32 val; 364 365 val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port)); 366 if (val == 0xffffffff) { 367 drm_dbg_kms(&i915->drm, 368 "Port %s: PHY in TCCOLD, assuming not complete\n", 369 dig_port->tc_port_name); 370 return false; 371 } 372 373 return val & TCSS_DDI_STATUS_READY; 374 } 375 376 static bool tc_phy_status_complete(struct intel_digital_port *dig_port) 377 { 378 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 379 380 if (IS_ALDERLAKE_P(i915)) 381 return adl_tc_phy_status_complete(dig_port); 382 383 return icl_tc_phy_status_complete(dig_port); 384 } 385 386 static bool icl_tc_phy_take_ownership(struct intel_digital_port *dig_port, 387 bool take) 388 { 389 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 390 u32 val; 391 392 val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia)); 393 if (val == 0xffffffff) { 394 drm_dbg_kms(&i915->drm, 395 "Port %s: PHY in TCCOLD, can't %s ownership\n", 396 dig_port->tc_port_name, take ? "take" : "release"); 397 398 return false; 399 } 400 401 val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx); 402 if (take) 403 val |= DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx); 404 405 intel_de_write(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia), val); 406 407 return true; 408 } 409 410 static bool adl_tc_phy_take_ownership(struct intel_digital_port *dig_port, 411 bool take) 412 { 413 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 414 enum port port = dig_port->base.port; 415 416 intel_de_rmw(i915, DDI_BUF_CTL(port), DDI_BUF_CTL_TC_PHY_OWNERSHIP, 417 take ? DDI_BUF_CTL_TC_PHY_OWNERSHIP : 0); 418 419 return true; 420 } 421 422 static bool tc_phy_take_ownership(struct intel_digital_port *dig_port, bool take) 423 { 424 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 425 426 if (IS_ALDERLAKE_P(i915)) 427 return adl_tc_phy_take_ownership(dig_port, take); 428 429 return icl_tc_phy_take_ownership(dig_port, take); 430 } 431 432 static bool icl_tc_phy_is_owned(struct intel_digital_port *dig_port) 433 { 434 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 435 u32 val; 436 437 val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(dig_port->tc_phy_fia)); 438 if (val == 0xffffffff) { 439 drm_dbg_kms(&i915->drm, 440 "Port %s: PHY in TCCOLD, assume not owned\n", 441 dig_port->tc_port_name); 442 return false; 443 } 444 445 return val & DP_PHY_MODE_STATUS_NOT_SAFE(dig_port->tc_phy_fia_idx); 446 } 447 448 static bool adl_tc_phy_is_owned(struct intel_digital_port *dig_port) 449 { 450 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 451 enum port port = dig_port->base.port; 452 u32 val; 453 454 val = intel_de_read(i915, DDI_BUF_CTL(port)); 455 return val & DDI_BUF_CTL_TC_PHY_OWNERSHIP; 456 } 457 458 static bool tc_phy_is_owned(struct intel_digital_port *dig_port) 459 { 460 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 461 462 if (IS_ALDERLAKE_P(i915)) 463 return adl_tc_phy_is_owned(dig_port); 464 465 return icl_tc_phy_is_owned(dig_port); 466 } 467 468 /* 469 * This function implements the first part of the Connect Flow described by our 470 * specification, Gen11 TypeC Programming chapter. The rest of the flow (reading 471 * lanes, EDID, etc) is done as needed in the typical places. 472 * 473 * Unlike the other ports, type-C ports are not available to use as soon as we 474 * get a hotplug. The type-C PHYs can be shared between multiple controllers: 475 * display, USB, etc. As a result, handshaking through FIA is required around 476 * connect and disconnect to cleanly transfer ownership with the controller and 477 * set the type-C power state. 478 */ 479 static void icl_tc_phy_connect(struct intel_digital_port *dig_port, 480 int required_lanes) 481 { 482 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 483 u32 live_status_mask; 484 int max_lanes; 485 486 if (!tc_phy_status_complete(dig_port) && 487 !drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port)) { 488 drm_dbg_kms(&i915->drm, "Port %s: PHY not ready\n", 489 dig_port->tc_port_name); 490 goto out_set_tbt_alt_mode; 491 } 492 493 live_status_mask = tc_port_live_status_mask(dig_port); 494 if (!(live_status_mask & (BIT(TC_PORT_DP_ALT) | BIT(TC_PORT_LEGACY))) && 495 !dig_port->tc_legacy_port) { 496 drm_dbg_kms(&i915->drm, "Port %s: PHY ownership not required (live status %02x)\n", 497 dig_port->tc_port_name, live_status_mask); 498 goto out_set_tbt_alt_mode; 499 } 500 501 if (!tc_phy_take_ownership(dig_port, true) && 502 !drm_WARN_ON(&i915->drm, dig_port->tc_legacy_port)) 503 goto out_set_tbt_alt_mode; 504 505 max_lanes = intel_tc_port_fia_max_lane_count(dig_port); 506 if (dig_port->tc_legacy_port) { 507 drm_WARN_ON(&i915->drm, max_lanes != 4); 508 dig_port->tc_mode = TC_PORT_LEGACY; 509 510 return; 511 } 512 513 /* 514 * Now we have to re-check the live state, in case the port recently 515 * became disconnected. Not necessary for legacy mode. 516 */ 517 if (!(tc_port_live_status_mask(dig_port) & BIT(TC_PORT_DP_ALT))) { 518 drm_dbg_kms(&i915->drm, "Port %s: PHY sudden disconnect\n", 519 dig_port->tc_port_name); 520 goto out_release_phy; 521 } 522 523 if (max_lanes < required_lanes) { 524 drm_dbg_kms(&i915->drm, 525 "Port %s: PHY max lanes %d < required lanes %d\n", 526 dig_port->tc_port_name, 527 max_lanes, required_lanes); 528 goto out_release_phy; 529 } 530 531 dig_port->tc_mode = TC_PORT_DP_ALT; 532 533 return; 534 535 out_release_phy: 536 tc_phy_take_ownership(dig_port, false); 537 out_set_tbt_alt_mode: 538 dig_port->tc_mode = TC_PORT_TBT_ALT; 539 } 540 541 /* 542 * See the comment at the connect function. This implements the Disconnect 543 * Flow. 544 */ 545 static void icl_tc_phy_disconnect(struct intel_digital_port *dig_port) 546 { 547 switch (dig_port->tc_mode) { 548 case TC_PORT_LEGACY: 549 case TC_PORT_DP_ALT: 550 tc_phy_take_ownership(dig_port, false); 551 fallthrough; 552 case TC_PORT_TBT_ALT: 553 dig_port->tc_mode = TC_PORT_DISCONNECTED; 554 fallthrough; 555 case TC_PORT_DISCONNECTED: 556 break; 557 default: 558 MISSING_CASE(dig_port->tc_mode); 559 } 560 } 561 562 static bool tc_phy_is_ready_and_owned(struct intel_digital_port *dig_port, 563 bool phy_is_ready, bool phy_is_owned) 564 { 565 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 566 567 drm_WARN_ON(&i915->drm, phy_is_owned && !phy_is_ready); 568 569 return phy_is_ready && phy_is_owned; 570 } 571 572 static bool tc_phy_is_connected(struct intel_digital_port *dig_port, 573 enum icl_port_dpll_id port_pll_type) 574 { 575 struct intel_encoder *encoder = &dig_port->base; 576 struct drm_i915_private *i915 = to_i915(encoder->base.dev); 577 bool phy_is_ready = tc_phy_status_complete(dig_port); 578 bool phy_is_owned = tc_phy_is_owned(dig_port); 579 bool is_connected; 580 581 if (tc_phy_is_ready_and_owned(dig_port, phy_is_ready, phy_is_owned)) 582 is_connected = port_pll_type == ICL_PORT_DPLL_MG_PHY; 583 else 584 is_connected = port_pll_type == ICL_PORT_DPLL_DEFAULT; 585 586 drm_dbg_kms(&i915->drm, 587 "Port %s: PHY connected: %s (ready: %s, owned: %s, pll_type: %s)\n", 588 dig_port->tc_port_name, 589 str_yes_no(is_connected), 590 str_yes_no(phy_is_ready), 591 str_yes_no(phy_is_owned), 592 port_pll_type == ICL_PORT_DPLL_DEFAULT ? "tbt" : "non-tbt"); 593 594 return is_connected; 595 } 596 597 static void tc_phy_wait_for_ready(struct intel_digital_port *dig_port) 598 { 599 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 600 601 if (wait_for(tc_phy_status_complete(dig_port), 100)) 602 drm_err(&i915->drm, "Port %s: timeout waiting for PHY ready\n", 603 dig_port->tc_port_name); 604 } 605 606 static enum tc_port_mode 607 hpd_mask_to_tc_mode(u32 live_status_mask) 608 { 609 if (live_status_mask) 610 return fls(live_status_mask) - 1; 611 612 return TC_PORT_DISCONNECTED; 613 } 614 615 static enum tc_port_mode 616 tc_phy_hpd_live_mode(struct intel_digital_port *dig_port) 617 { 618 u32 live_status_mask = tc_port_live_status_mask(dig_port); 619 620 return hpd_mask_to_tc_mode(live_status_mask); 621 } 622 623 static enum tc_port_mode 624 get_tc_mode_in_phy_owned_state(struct intel_digital_port *dig_port, 625 enum tc_port_mode live_mode) 626 { 627 switch (live_mode) { 628 case TC_PORT_LEGACY: 629 case TC_PORT_DP_ALT: 630 return live_mode; 631 default: 632 MISSING_CASE(live_mode); 633 fallthrough; 634 case TC_PORT_TBT_ALT: 635 case TC_PORT_DISCONNECTED: 636 if (dig_port->tc_legacy_port) 637 return TC_PORT_LEGACY; 638 else 639 return TC_PORT_DP_ALT; 640 } 641 } 642 643 static enum tc_port_mode 644 get_tc_mode_in_phy_not_owned_state(struct intel_digital_port *dig_port, 645 enum tc_port_mode live_mode) 646 { 647 switch (live_mode) { 648 case TC_PORT_LEGACY: 649 return TC_PORT_DISCONNECTED; 650 case TC_PORT_DP_ALT: 651 case TC_PORT_TBT_ALT: 652 return TC_PORT_TBT_ALT; 653 default: 654 MISSING_CASE(live_mode); 655 fallthrough; 656 case TC_PORT_DISCONNECTED: 657 if (dig_port->tc_legacy_port) 658 return TC_PORT_DISCONNECTED; 659 else 660 return TC_PORT_TBT_ALT; 661 } 662 } 663 664 static enum tc_port_mode 665 intel_tc_port_get_current_mode(struct intel_digital_port *dig_port) 666 { 667 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 668 enum tc_port_mode live_mode = tc_phy_hpd_live_mode(dig_port); 669 bool phy_is_ready; 670 bool phy_is_owned; 671 enum tc_port_mode mode; 672 673 /* 674 * For legacy ports the IOM firmware initializes the PHY during boot-up 675 * and system resume whether or not a sink is connected. Wait here for 676 * the initialization to get ready. 677 */ 678 if (dig_port->tc_legacy_port) 679 tc_phy_wait_for_ready(dig_port); 680 681 phy_is_ready = tc_phy_status_complete(dig_port); 682 phy_is_owned = tc_phy_is_owned(dig_port); 683 684 if (!tc_phy_is_ready_and_owned(dig_port, phy_is_ready, phy_is_owned)) { 685 mode = get_tc_mode_in_phy_not_owned_state(dig_port, live_mode); 686 } else { 687 drm_WARN_ON(&i915->drm, live_mode == TC_PORT_TBT_ALT); 688 mode = get_tc_mode_in_phy_owned_state(dig_port, live_mode); 689 } 690 691 drm_dbg_kms(&i915->drm, 692 "Port %s: PHY mode: %s (ready: %s, owned: %s, HPD: %s)\n", 693 dig_port->tc_port_name, 694 tc_port_mode_name(mode), 695 str_yes_no(phy_is_ready), 696 str_yes_no(phy_is_owned), 697 tc_port_mode_name(live_mode)); 698 699 return mode; 700 } 701 702 static enum tc_port_mode default_tc_mode(struct intel_digital_port *dig_port) 703 { 704 if (dig_port->tc_legacy_port) 705 return TC_PORT_LEGACY; 706 707 return TC_PORT_TBT_ALT; 708 } 709 710 static enum tc_port_mode 711 hpd_mask_to_target_mode(struct intel_digital_port *dig_port, u32 live_status_mask) 712 { 713 enum tc_port_mode mode = hpd_mask_to_tc_mode(live_status_mask); 714 715 if (mode != TC_PORT_DISCONNECTED) 716 return mode; 717 718 return default_tc_mode(dig_port); 719 } 720 721 static enum tc_port_mode 722 intel_tc_port_get_target_mode(struct intel_digital_port *dig_port) 723 { 724 u32 live_status_mask = tc_port_live_status_mask(dig_port); 725 726 return hpd_mask_to_target_mode(dig_port, live_status_mask); 727 } 728 729 static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port, 730 int required_lanes, bool force_disconnect) 731 { 732 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 733 enum tc_port_mode old_tc_mode = dig_port->tc_mode; 734 735 intel_display_power_flush_work(i915); 736 if (!intel_tc_cold_requires_aux_pw(dig_port)) { 737 enum intel_display_power_domain aux_domain; 738 bool aux_powered; 739 740 aux_domain = intel_aux_power_domain(dig_port); 741 aux_powered = intel_display_power_is_enabled(i915, aux_domain); 742 drm_WARN_ON(&i915->drm, aux_powered); 743 } 744 745 icl_tc_phy_disconnect(dig_port); 746 if (!force_disconnect) 747 icl_tc_phy_connect(dig_port, required_lanes); 748 749 drm_dbg_kms(&i915->drm, "Port %s: TC port mode reset (%s -> %s)\n", 750 dig_port->tc_port_name, 751 tc_port_mode_name(old_tc_mode), 752 tc_port_mode_name(dig_port->tc_mode)); 753 } 754 755 static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port) 756 { 757 return intel_tc_port_get_target_mode(dig_port) != dig_port->tc_mode; 758 } 759 760 static void intel_tc_port_update_mode(struct intel_digital_port *dig_port, 761 int required_lanes, bool force_disconnect) 762 { 763 enum intel_display_power_domain domain; 764 intel_wakeref_t wref; 765 bool needs_reset = force_disconnect; 766 767 if (!needs_reset) { 768 /* Get power domain required to check the hotplug live status. */ 769 wref = tc_cold_block(dig_port, &domain); 770 needs_reset = intel_tc_port_needs_reset(dig_port); 771 tc_cold_unblock(dig_port, domain, wref); 772 } 773 774 if (!needs_reset) 775 return; 776 777 /* Get power domain required for resetting the mode. */ 778 wref = tc_cold_block_in_mode(dig_port, TC_PORT_DISCONNECTED, &domain); 779 780 intel_tc_port_reset_mode(dig_port, required_lanes, force_disconnect); 781 782 /* Get power domain matching the new mode after reset. */ 783 tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain, 784 fetch_and_zero(&dig_port->tc_lock_wakeref)); 785 if (dig_port->tc_mode != TC_PORT_DISCONNECTED) 786 dig_port->tc_lock_wakeref = tc_cold_block(dig_port, 787 &dig_port->tc_lock_power_domain); 788 789 tc_cold_unblock(dig_port, domain, wref); 790 } 791 792 static void __intel_tc_port_get_link(struct intel_digital_port *dig_port) 793 { 794 dig_port->tc_link_refcount++; 795 } 796 797 static void __intel_tc_port_put_link(struct intel_digital_port *dig_port) 798 { 799 dig_port->tc_link_refcount--; 800 } 801 802 static bool tc_port_is_enabled(struct intel_digital_port *dig_port) 803 { 804 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 805 806 assert_tc_port_power_enabled(dig_port); 807 808 return intel_de_read(i915, DDI_BUF_CTL(dig_port->base.port)) & 809 DDI_BUF_CTL_ENABLE; 810 } 811 812 /** 813 * intel_tc_port_init_mode: Read out HW state and init the given port's TypeC mode 814 * @dig_port: digital port 815 * 816 * Read out the HW state and initialize the TypeC mode of @dig_port. The mode 817 * will be locked until intel_tc_port_sanitize_mode() is called. 818 */ 819 void intel_tc_port_init_mode(struct intel_digital_port *dig_port) 820 { 821 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 822 intel_wakeref_t tc_cold_wref; 823 enum intel_display_power_domain domain; 824 bool update_mode = false; 825 826 mutex_lock(&dig_port->tc_lock); 827 828 drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_DISCONNECTED); 829 drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref); 830 drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount); 831 832 tc_cold_wref = tc_cold_block(dig_port, &domain); 833 834 dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port); 835 /* 836 * Save the initial mode for the state check in 837 * intel_tc_port_sanitize_mode(). 838 */ 839 dig_port->tc_init_mode = dig_port->tc_mode; 840 if (dig_port->tc_mode != TC_PORT_DISCONNECTED) 841 dig_port->tc_lock_wakeref = 842 tc_cold_block(dig_port, &dig_port->tc_lock_power_domain); 843 844 /* 845 * The PHY needs to be connected for AUX to work during HW readout and 846 * MST topology resume, but the PHY mode can only be changed if the 847 * port is disabled. 848 * 849 * An exception is the case where BIOS leaves the PHY incorrectly 850 * disconnected on an enabled legacy port. Work around that by 851 * connecting the PHY even though the port is enabled. This doesn't 852 * cause a problem as the PHY ownership state is ignored by the 853 * IOM/TCSS firmware (only display can own the PHY in that case). 854 */ 855 if (!tc_port_is_enabled(dig_port)) { 856 update_mode = true; 857 } else if (dig_port->tc_mode == TC_PORT_DISCONNECTED) { 858 drm_WARN_ON(&i915->drm, !dig_port->tc_legacy_port); 859 drm_err(&i915->drm, 860 "Port %s: PHY disconnected on enabled port, connecting it\n", 861 dig_port->tc_port_name); 862 update_mode = true; 863 } 864 865 if (update_mode) 866 intel_tc_port_update_mode(dig_port, 1, false); 867 868 /* Prevent changing dig_port->tc_mode until intel_tc_port_sanitize_mode() is called. */ 869 __intel_tc_port_get_link(dig_port); 870 871 tc_cold_unblock(dig_port, domain, tc_cold_wref); 872 873 mutex_unlock(&dig_port->tc_lock); 874 } 875 876 static bool tc_port_has_active_links(struct intel_digital_port *dig_port, 877 const struct intel_crtc_state *crtc_state) 878 { 879 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 880 enum icl_port_dpll_id pll_type = ICL_PORT_DPLL_DEFAULT; 881 int active_links = 0; 882 883 if (dig_port->dp.is_mst) { 884 /* TODO: get the PLL type for MST, once HW readout is done for it. */ 885 active_links = intel_dp_mst_encoder_active_links(dig_port); 886 } else if (crtc_state && crtc_state->hw.active) { 887 pll_type = intel_ddi_port_pll_type(&dig_port->base, crtc_state); 888 active_links = 1; 889 } 890 891 if (active_links && !tc_phy_is_connected(dig_port, pll_type)) 892 drm_err(&i915->drm, 893 "Port %s: PHY disconnected with %d active link(s)\n", 894 dig_port->tc_port_name, active_links); 895 896 return active_links; 897 } 898 899 /** 900 * intel_tc_port_sanitize_mode: Sanitize the given port's TypeC mode 901 * @dig_port: digital port 902 * @crtc_state: atomic state of CRTC connected to @dig_port 903 * 904 * Sanitize @dig_port's TypeC mode wrt. the encoder's state right after driver 905 * loading and system resume: 906 * If the encoder is enabled keep the TypeC mode/PHY connected state locked until 907 * the encoder is disabled. 908 * If the encoder is disabled make sure the PHY is disconnected. 909 * @crtc_state is valid if @dig_port is enabled, NULL otherwise. 910 */ 911 void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port, 912 const struct intel_crtc_state *crtc_state) 913 { 914 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 915 916 mutex_lock(&dig_port->tc_lock); 917 918 drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount != 1); 919 if (!tc_port_has_active_links(dig_port, crtc_state)) { 920 /* 921 * TBT-alt is the default mode in any case the PHY ownership is not 922 * held (regardless of the sink's connected live state), so 923 * we'll just switch to disconnected mode from it here without 924 * a note. 925 */ 926 if (dig_port->tc_init_mode != TC_PORT_TBT_ALT && 927 dig_port->tc_init_mode != TC_PORT_DISCONNECTED) 928 drm_dbg_kms(&i915->drm, 929 "Port %s: PHY left in %s mode on disabled port, disconnecting it\n", 930 dig_port->tc_port_name, 931 tc_port_mode_name(dig_port->tc_init_mode)); 932 icl_tc_phy_disconnect(dig_port); 933 __intel_tc_port_put_link(dig_port); 934 935 tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain, 936 fetch_and_zero(&dig_port->tc_lock_wakeref)); 937 } 938 939 drm_dbg_kms(&i915->drm, "Port %s: sanitize mode (%s)\n", 940 dig_port->tc_port_name, 941 tc_port_mode_name(dig_port->tc_mode)); 942 943 mutex_unlock(&dig_port->tc_lock); 944 } 945 946 /* 947 * The type-C ports are different because even when they are connected, they may 948 * not be available/usable by the graphics driver: see the comment on 949 * icl_tc_phy_connect(). So in our driver instead of adding the additional 950 * concept of "usable" and make everything check for "connected and usable" we 951 * define a port as "connected" when it is not only connected, but also when it 952 * is usable by the rest of the driver. That maintains the old assumption that 953 * connected ports are usable, and avoids exposing to the users objects they 954 * can't really use. 955 */ 956 bool intel_tc_port_connected_locked(struct intel_encoder *encoder) 957 { 958 struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 959 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 960 961 drm_WARN_ON(&i915->drm, !intel_tc_port_ref_held(dig_port)); 962 963 return tc_port_live_status_mask(dig_port) & BIT(dig_port->tc_mode); 964 } 965 966 bool intel_tc_port_connected(struct intel_encoder *encoder) 967 { 968 struct intel_digital_port *dig_port = enc_to_dig_port(encoder); 969 bool is_connected; 970 971 intel_tc_port_lock(dig_port); 972 is_connected = intel_tc_port_connected_locked(encoder); 973 intel_tc_port_unlock(dig_port); 974 975 return is_connected; 976 } 977 978 static void __intel_tc_port_lock(struct intel_digital_port *dig_port, 979 int required_lanes) 980 { 981 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 982 983 mutex_lock(&dig_port->tc_lock); 984 985 cancel_delayed_work(&dig_port->tc_disconnect_phy_work); 986 987 if (!dig_port->tc_link_refcount) 988 intel_tc_port_update_mode(dig_port, required_lanes, 989 false); 990 991 drm_WARN_ON(&i915->drm, dig_port->tc_mode == TC_PORT_DISCONNECTED); 992 drm_WARN_ON(&i915->drm, dig_port->tc_mode != TC_PORT_TBT_ALT && 993 !tc_phy_is_owned(dig_port)); 994 } 995 996 void intel_tc_port_lock(struct intel_digital_port *dig_port) 997 { 998 __intel_tc_port_lock(dig_port, 1); 999 } 1000 1001 /** 1002 * intel_tc_port_disconnect_phy_work: disconnect TypeC PHY from display port 1003 * @dig_port: digital port 1004 * 1005 * Disconnect the given digital port from its TypeC PHY (handing back the 1006 * control of the PHY to the TypeC subsystem). This will happen in a delayed 1007 * manner after each aux transactions and modeset disables. 1008 */ 1009 static void intel_tc_port_disconnect_phy_work(struct work_struct *work) 1010 { 1011 struct intel_digital_port *dig_port = 1012 container_of(work, struct intel_digital_port, tc_disconnect_phy_work.work); 1013 1014 mutex_lock(&dig_port->tc_lock); 1015 1016 if (!dig_port->tc_link_refcount) 1017 intel_tc_port_update_mode(dig_port, 1, true); 1018 1019 mutex_unlock(&dig_port->tc_lock); 1020 } 1021 1022 /** 1023 * intel_tc_port_flush_work: flush the work disconnecting the PHY 1024 * @dig_port: digital port 1025 * 1026 * Flush the delayed work disconnecting an idle PHY. 1027 */ 1028 void intel_tc_port_flush_work(struct intel_digital_port *dig_port) 1029 { 1030 flush_delayed_work(&dig_port->tc_disconnect_phy_work); 1031 } 1032 1033 void intel_tc_port_unlock(struct intel_digital_port *dig_port) 1034 { 1035 if (!dig_port->tc_link_refcount && dig_port->tc_mode != TC_PORT_DISCONNECTED) 1036 queue_delayed_work(system_unbound_wq, &dig_port->tc_disconnect_phy_work, 1037 msecs_to_jiffies(1000)); 1038 1039 mutex_unlock(&dig_port->tc_lock); 1040 } 1041 1042 bool intel_tc_port_ref_held(struct intel_digital_port *dig_port) 1043 { 1044 return mutex_is_locked(&dig_port->tc_lock) || 1045 dig_port->tc_link_refcount; 1046 } 1047 1048 void intel_tc_port_get_link(struct intel_digital_port *dig_port, 1049 int required_lanes) 1050 { 1051 __intel_tc_port_lock(dig_port, required_lanes); 1052 __intel_tc_port_get_link(dig_port); 1053 intel_tc_port_unlock(dig_port); 1054 } 1055 1056 void intel_tc_port_put_link(struct intel_digital_port *dig_port) 1057 { 1058 intel_tc_port_lock(dig_port); 1059 __intel_tc_port_put_link(dig_port); 1060 intel_tc_port_unlock(dig_port); 1061 1062 /* 1063 * Disconnecting the PHY after the PHY's PLL gets disabled may 1064 * hang the system on ADL-P, so disconnect the PHY here synchronously. 1065 * TODO: remove this once the root cause of the ordering requirement 1066 * is found/fixed. 1067 */ 1068 intel_tc_port_flush_work(dig_port); 1069 } 1070 1071 static bool 1072 tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig_port) 1073 { 1074 enum intel_display_power_domain domain; 1075 intel_wakeref_t wakeref; 1076 u32 val; 1077 1078 if (!INTEL_INFO(i915)->display.has_modular_fia) 1079 return false; 1080 1081 mutex_lock(&dig_port->tc_lock); 1082 wakeref = tc_cold_block(dig_port, &domain); 1083 val = intel_de_read(i915, PORT_TX_DFLEXDPSP(FIA1)); 1084 tc_cold_unblock(dig_port, domain, wakeref); 1085 mutex_unlock(&dig_port->tc_lock); 1086 1087 drm_WARN_ON(&i915->drm, val == 0xffffffff); 1088 1089 return val & MODULAR_FIA_MASK; 1090 } 1091 1092 static void 1093 tc_port_load_fia_params(struct drm_i915_private *i915, struct intel_digital_port *dig_port) 1094 { 1095 enum port port = dig_port->base.port; 1096 enum tc_port tc_port = intel_port_to_tc(i915, port); 1097 1098 /* 1099 * Each Modular FIA instance houses 2 TC ports. In SOC that has more 1100 * than two TC ports, there are multiple instances of Modular FIA. 1101 */ 1102 if (tc_has_modular_fia(i915, dig_port)) { 1103 dig_port->tc_phy_fia = tc_port / 2; 1104 dig_port->tc_phy_fia_idx = tc_port % 2; 1105 } else { 1106 dig_port->tc_phy_fia = FIA1; 1107 dig_port->tc_phy_fia_idx = tc_port; 1108 } 1109 } 1110 1111 void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) 1112 { 1113 struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev); 1114 enum port port = dig_port->base.port; 1115 enum tc_port tc_port = intel_port_to_tc(i915, port); 1116 1117 if (drm_WARN_ON(&i915->drm, tc_port == TC_PORT_NONE)) 1118 return; 1119 1120 snprintf(dig_port->tc_port_name, sizeof(dig_port->tc_port_name), 1121 "%c/TC#%d", port_name(port), tc_port + 1); 1122 1123 mutex_init(&dig_port->tc_lock); 1124 INIT_DELAYED_WORK(&dig_port->tc_disconnect_phy_work, intel_tc_port_disconnect_phy_work); 1125 dig_port->tc_legacy_port = is_legacy; 1126 dig_port->tc_mode = TC_PORT_DISCONNECTED; 1127 dig_port->tc_link_refcount = 0; 1128 tc_port_load_fia_params(i915, dig_port); 1129 1130 intel_tc_port_init_mode(dig_port); 1131 } 1132