Lines Matching refs:tc
37 enum intel_display_power_domain (*cold_off_domain)(struct intel_tc_port *tc);
38 u32 (*hpd_live_status)(struct intel_tc_port *tc);
39 bool (*is_ready)(struct intel_tc_port *tc);
40 bool (*is_owned)(struct intel_tc_port *tc);
41 void (*get_hw_state)(struct intel_tc_port *tc);
42 bool (*connect)(struct intel_tc_port *tc, int required_lanes);
43 void (*disconnect)(struct intel_tc_port *tc);
44 void (*init)(struct intel_tc_port *tc);
70 static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc);
71 static bool tc_phy_is_ready(struct intel_tc_port *tc);
72 static bool tc_phy_wait_for_ready(struct intel_tc_port *tc);
73 static enum tc_port_mode tc_phy_get_current_mode(struct intel_tc_port *tc);
92 return dig_port->tc; in to_tc_port()
95 static struct drm_i915_private *tc_to_i915(struct intel_tc_port *tc) in tc_to_i915() argument
97 return to_i915(tc->dig_port->base.base.dev); in tc_to_i915()
105 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_in_mode() local
107 return intel_phy_is_tc(i915, phy) && tc->mode == mode; in intel_tc_port_in_mode()
176 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_cold_requires_aux_pw() local
178 return tc_phy_cold_off_domain(tc) == in intel_tc_cold_requires_aux_pw()
183 __tc_cold_block(struct intel_tc_port *tc, enum intel_display_power_domain *domain) in __tc_cold_block() argument
185 struct drm_i915_private *i915 = tc_to_i915(tc); in __tc_cold_block()
187 *domain = tc_phy_cold_off_domain(tc); in __tc_cold_block()
193 tc_cold_block(struct intel_tc_port *tc) in tc_cold_block() argument
198 wakeref = __tc_cold_block(tc, &domain); in tc_cold_block()
200 tc->lock_power_domain = domain; in tc_cold_block()
206 __tc_cold_unblock(struct intel_tc_port *tc, enum intel_display_power_domain domain, in __tc_cold_unblock() argument
209 struct drm_i915_private *i915 = tc_to_i915(tc); in __tc_cold_unblock()
215 tc_cold_unblock(struct intel_tc_port *tc, intel_wakeref_t wakeref) in tc_cold_unblock() argument
217 enum intel_display_power_domain domain = tc_phy_cold_off_domain(tc); in tc_cold_unblock()
220 drm_WARN_ON(&tc_to_i915(tc)->drm, tc->lock_power_domain != domain); in tc_cold_unblock()
222 __tc_cold_unblock(tc, domain, wakeref); in tc_cold_unblock()
226 assert_display_core_power_enabled(struct intel_tc_port *tc) in assert_display_core_power_enabled() argument
228 struct drm_i915_private *i915 = tc_to_i915(tc); in assert_display_core_power_enabled()
235 assert_tc_cold_blocked(struct intel_tc_port *tc) in assert_tc_cold_blocked() argument
237 struct drm_i915_private *i915 = tc_to_i915(tc); in assert_tc_cold_blocked()
241 tc_phy_cold_off_domain(tc)); in assert_tc_cold_blocked()
246 tc_port_power_domain(struct intel_tc_port *tc) in tc_port_power_domain() argument
248 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_port_power_domain()
249 enum tc_port tc_port = intel_port_to_tc(i915, tc->dig_port->base.port); in tc_port_power_domain()
255 assert_tc_port_power_enabled(struct intel_tc_port *tc) in assert_tc_port_power_enabled() argument
257 struct drm_i915_private *i915 = tc_to_i915(tc); in assert_tc_port_power_enabled()
260 !intel_display_power_is_enabled(i915, tc_port_power_domain(tc))); in assert_tc_port_power_enabled()
266 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_get_lane_mask() local
269 lane_mask = intel_de_read(i915, PORT_TX_DFLEXDPSP(tc->phy_fia)); in intel_tc_port_get_lane_mask()
272 assert_tc_cold_blocked(tc); in intel_tc_port_get_lane_mask()
274 lane_mask &= DP_LANE_ASSIGNMENT_MASK(tc->phy_fia_idx); in intel_tc_port_get_lane_mask()
275 return lane_mask >> DP_LANE_ASSIGNMENT_SHIFT(tc->phy_fia_idx); in intel_tc_port_get_lane_mask()
281 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_get_pin_assignment_mask() local
284 pin_mask = intel_de_read(i915, PORT_TX_DFLEXPA1(tc->phy_fia)); in intel_tc_port_get_pin_assignment_mask()
287 assert_tc_cold_blocked(tc); in intel_tc_port_get_pin_assignment_mask()
289 return (pin_mask & DP_PIN_ASSIGNMENT_MASK(tc->phy_fia_idx)) >> in intel_tc_port_get_pin_assignment_mask()
290 DP_PIN_ASSIGNMENT_SHIFT(tc->phy_fia_idx); in intel_tc_port_get_pin_assignment_mask()
317 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_fia_max_lane_count() local
322 if (!intel_phy_is_tc(i915, phy) || tc->mode != TC_PORT_DP_ALT) in intel_tc_port_fia_max_lane_count()
325 assert_tc_cold_blocked(tc); in intel_tc_port_fia_max_lane_count()
355 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_set_fia_lane_count() local
360 lane_reversal && tc->mode != TC_PORT_LEGACY); in intel_tc_port_set_fia_lane_count()
362 assert_tc_cold_blocked(tc); in intel_tc_port_set_fia_lane_count()
364 val = intel_de_read(i915, PORT_TX_DFLEXDPMLE1(tc->phy_fia)); in intel_tc_port_set_fia_lane_count()
365 val &= ~DFLEXDPMLE1_DPMLETC_MASK(tc->phy_fia_idx); in intel_tc_port_set_fia_lane_count()
370 DFLEXDPMLE1_DPMLETC_ML3(tc->phy_fia_idx) : in intel_tc_port_set_fia_lane_count()
371 DFLEXDPMLE1_DPMLETC_ML0(tc->phy_fia_idx); in intel_tc_port_set_fia_lane_count()
375 DFLEXDPMLE1_DPMLETC_ML3_2(tc->phy_fia_idx) : in intel_tc_port_set_fia_lane_count()
376 DFLEXDPMLE1_DPMLETC_ML1_0(tc->phy_fia_idx); in intel_tc_port_set_fia_lane_count()
379 val |= DFLEXDPMLE1_DPMLETC_ML3_0(tc->phy_fia_idx); in intel_tc_port_set_fia_lane_count()
385 intel_de_write(i915, PORT_TX_DFLEXDPMLE1(tc->phy_fia), val); in intel_tc_port_set_fia_lane_count()
388 static void tc_port_fixup_legacy_flag(struct intel_tc_port *tc, in tc_port_fixup_legacy_flag() argument
391 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_port_fixup_legacy_flag()
394 drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_DISCONNECTED); in tc_port_fixup_legacy_flag()
399 if (tc->legacy_port) in tc_port_fixup_legacy_flag()
411 tc->port_name, live_status_mask, valid_hpd_mask); in tc_port_fixup_legacy_flag()
413 tc->legacy_port = !tc->legacy_port; in tc_port_fixup_legacy_flag()
416 static void tc_phy_load_fia_params(struct intel_tc_port *tc, bool modular_fia) in tc_phy_load_fia_params() argument
418 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_phy_load_fia_params()
419 enum port port = tc->dig_port->base.port; in tc_phy_load_fia_params()
427 tc->phy_fia = tc_port / 2; in tc_phy_load_fia_params()
428 tc->phy_fia_idx = tc_port % 2; in tc_phy_load_fia_params()
430 tc->phy_fia = FIA1; in tc_phy_load_fia_params()
431 tc->phy_fia_idx = tc_port; in tc_phy_load_fia_params()
440 icl_tc_phy_cold_off_domain(struct intel_tc_port *tc) in icl_tc_phy_cold_off_domain() argument
442 struct drm_i915_private *i915 = tc_to_i915(tc); in icl_tc_phy_cold_off_domain()
443 struct intel_digital_port *dig_port = tc->dig_port; in icl_tc_phy_cold_off_domain()
445 if (tc->legacy_port) in icl_tc_phy_cold_off_domain()
451 static u32 icl_tc_phy_hpd_live_status(struct intel_tc_port *tc) in icl_tc_phy_hpd_live_status() argument
453 struct drm_i915_private *i915 = tc_to_i915(tc); in icl_tc_phy_hpd_live_status()
454 struct intel_digital_port *dig_port = tc->dig_port; in icl_tc_phy_hpd_live_status()
461 with_intel_display_power(i915, tc_phy_cold_off_domain(tc), wakeref) { in icl_tc_phy_hpd_live_status()
462 fia_isr = intel_de_read(i915, PORT_TX_DFLEXDPSP(tc->phy_fia)); in icl_tc_phy_hpd_live_status()
469 tc->port_name); in icl_tc_phy_hpd_live_status()
473 if (fia_isr & TC_LIVE_STATE_TBT(tc->phy_fia_idx)) in icl_tc_phy_hpd_live_status()
475 if (fia_isr & TC_LIVE_STATE_TC(tc->phy_fia_idx)) in icl_tc_phy_hpd_live_status()
492 static bool icl_tc_phy_is_ready(struct intel_tc_port *tc) in icl_tc_phy_is_ready() argument
494 struct drm_i915_private *i915 = tc_to_i915(tc); in icl_tc_phy_is_ready()
497 assert_tc_cold_blocked(tc); in icl_tc_phy_is_ready()
499 val = intel_de_read(i915, PORT_TX_DFLEXDPPMS(tc->phy_fia)); in icl_tc_phy_is_ready()
503 tc->port_name); in icl_tc_phy_is_ready()
507 return val & DP_PHY_MODE_STATUS_COMPLETED(tc->phy_fia_idx); in icl_tc_phy_is_ready()
510 static bool icl_tc_phy_take_ownership(struct intel_tc_port *tc, in icl_tc_phy_take_ownership() argument
513 struct drm_i915_private *i915 = tc_to_i915(tc); in icl_tc_phy_take_ownership()
516 assert_tc_cold_blocked(tc); in icl_tc_phy_take_ownership()
518 val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia)); in icl_tc_phy_take_ownership()
522 tc->port_name, take ? "take" : "release"); in icl_tc_phy_take_ownership()
527 val &= ~DP_PHY_MODE_STATUS_NOT_SAFE(tc->phy_fia_idx); in icl_tc_phy_take_ownership()
529 val |= DP_PHY_MODE_STATUS_NOT_SAFE(tc->phy_fia_idx); in icl_tc_phy_take_ownership()
531 intel_de_write(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia), val); in icl_tc_phy_take_ownership()
536 static bool icl_tc_phy_is_owned(struct intel_tc_port *tc) in icl_tc_phy_is_owned() argument
538 struct drm_i915_private *i915 = tc_to_i915(tc); in icl_tc_phy_is_owned()
541 assert_tc_cold_blocked(tc); in icl_tc_phy_is_owned()
543 val = intel_de_read(i915, PORT_TX_DFLEXDPCSSS(tc->phy_fia)); in icl_tc_phy_is_owned()
547 tc->port_name); in icl_tc_phy_is_owned()
551 return val & DP_PHY_MODE_STATUS_NOT_SAFE(tc->phy_fia_idx); in icl_tc_phy_is_owned()
554 static void icl_tc_phy_get_hw_state(struct intel_tc_port *tc) in icl_tc_phy_get_hw_state() argument
559 tc_cold_wref = __tc_cold_block(tc, &domain); in icl_tc_phy_get_hw_state()
561 tc->mode = tc_phy_get_current_mode(tc); in icl_tc_phy_get_hw_state()
562 if (tc->mode != TC_PORT_DISCONNECTED) in icl_tc_phy_get_hw_state()
563 tc->lock_wakeref = tc_cold_block(tc); in icl_tc_phy_get_hw_state()
565 __tc_cold_unblock(tc, domain, tc_cold_wref); in icl_tc_phy_get_hw_state()
579 static bool tc_phy_verify_legacy_or_dp_alt_mode(struct intel_tc_port *tc, in tc_phy_verify_legacy_or_dp_alt_mode() argument
582 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_phy_verify_legacy_or_dp_alt_mode()
583 struct intel_digital_port *dig_port = tc->dig_port; in tc_phy_verify_legacy_or_dp_alt_mode()
587 if (tc->mode == TC_PORT_LEGACY) { in tc_phy_verify_legacy_or_dp_alt_mode()
592 drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_DP_ALT); in tc_phy_verify_legacy_or_dp_alt_mode()
598 if (!(tc_phy_hpd_live_status(tc) & BIT(TC_PORT_DP_ALT))) { in tc_phy_verify_legacy_or_dp_alt_mode()
600 tc->port_name); in tc_phy_verify_legacy_or_dp_alt_mode()
607 tc->port_name, in tc_phy_verify_legacy_or_dp_alt_mode()
615 static bool icl_tc_phy_connect(struct intel_tc_port *tc, in icl_tc_phy_connect() argument
618 struct drm_i915_private *i915 = tc_to_i915(tc); in icl_tc_phy_connect()
620 tc->lock_wakeref = tc_cold_block(tc); in icl_tc_phy_connect()
622 if (tc->mode == TC_PORT_TBT_ALT) in icl_tc_phy_connect()
625 if ((!tc_phy_is_ready(tc) || in icl_tc_phy_connect()
626 !icl_tc_phy_take_ownership(tc, true)) && in icl_tc_phy_connect()
627 !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { in icl_tc_phy_connect()
629 tc->port_name, in icl_tc_phy_connect()
630 str_yes_no(tc_phy_is_ready(tc))); in icl_tc_phy_connect()
635 if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) in icl_tc_phy_connect()
641 icl_tc_phy_take_ownership(tc, false); in icl_tc_phy_connect()
643 tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); in icl_tc_phy_connect()
652 static void icl_tc_phy_disconnect(struct intel_tc_port *tc) in icl_tc_phy_disconnect() argument
654 switch (tc->mode) { in icl_tc_phy_disconnect()
657 icl_tc_phy_take_ownership(tc, false); in icl_tc_phy_disconnect()
660 tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); in icl_tc_phy_disconnect()
663 MISSING_CASE(tc->mode); in icl_tc_phy_disconnect()
667 static void icl_tc_phy_init(struct intel_tc_port *tc) in icl_tc_phy_init() argument
669 tc_phy_load_fia_params(tc, false); in icl_tc_phy_init()
688 tgl_tc_phy_cold_off_domain(struct intel_tc_port *tc) in tgl_tc_phy_cold_off_domain() argument
693 static void tgl_tc_phy_init(struct intel_tc_port *tc) in tgl_tc_phy_init() argument
695 struct drm_i915_private *i915 = tc_to_i915(tc); in tgl_tc_phy_init()
699 with_intel_display_power(i915, tc_phy_cold_off_domain(tc), wakeref) in tgl_tc_phy_init()
704 tc_phy_load_fia_params(tc, val & MODULAR_FIA_MASK); in tgl_tc_phy_init()
723 adlp_tc_phy_cold_off_domain(struct intel_tc_port *tc) in adlp_tc_phy_cold_off_domain() argument
725 struct drm_i915_private *i915 = tc_to_i915(tc); in adlp_tc_phy_cold_off_domain()
726 struct intel_digital_port *dig_port = tc->dig_port; in adlp_tc_phy_cold_off_domain()
728 if (tc->mode != TC_PORT_TBT_ALT) in adlp_tc_phy_cold_off_domain()
734 static u32 adlp_tc_phy_hpd_live_status(struct intel_tc_port *tc) in adlp_tc_phy_hpd_live_status() argument
736 struct drm_i915_private *i915 = tc_to_i915(tc); in adlp_tc_phy_hpd_live_status()
737 struct intel_digital_port *dig_port = tc->dig_port; in adlp_tc_phy_hpd_live_status()
769 static bool adlp_tc_phy_is_ready(struct intel_tc_port *tc) in adlp_tc_phy_is_ready() argument
771 struct drm_i915_private *i915 = tc_to_i915(tc); in adlp_tc_phy_is_ready()
772 enum tc_port tc_port = intel_port_to_tc(i915, tc->dig_port->base.port); in adlp_tc_phy_is_ready()
775 assert_display_core_power_enabled(tc); in adlp_tc_phy_is_ready()
781 tc->port_name); in adlp_tc_phy_is_ready()
788 static bool adlp_tc_phy_take_ownership(struct intel_tc_port *tc, in adlp_tc_phy_take_ownership() argument
791 struct drm_i915_private *i915 = tc_to_i915(tc); in adlp_tc_phy_take_ownership()
792 enum port port = tc->dig_port->base.port; in adlp_tc_phy_take_ownership()
794 assert_tc_port_power_enabled(tc); in adlp_tc_phy_take_ownership()
802 static bool adlp_tc_phy_is_owned(struct intel_tc_port *tc) in adlp_tc_phy_is_owned() argument
804 struct drm_i915_private *i915 = tc_to_i915(tc); in adlp_tc_phy_is_owned()
805 enum port port = tc->dig_port->base.port; in adlp_tc_phy_is_owned()
808 assert_tc_port_power_enabled(tc); in adlp_tc_phy_is_owned()
814 static void adlp_tc_phy_get_hw_state(struct intel_tc_port *tc) in adlp_tc_phy_get_hw_state() argument
816 struct drm_i915_private *i915 = tc_to_i915(tc); in adlp_tc_phy_get_hw_state()
818 tc_port_power_domain(tc); in adlp_tc_phy_get_hw_state()
823 tc->mode = tc_phy_get_current_mode(tc); in adlp_tc_phy_get_hw_state()
824 if (tc->mode != TC_PORT_DISCONNECTED) in adlp_tc_phy_get_hw_state()
825 tc->lock_wakeref = tc_cold_block(tc); in adlp_tc_phy_get_hw_state()
830 static bool adlp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) in adlp_tc_phy_connect() argument
832 struct drm_i915_private *i915 = tc_to_i915(tc); in adlp_tc_phy_connect()
834 tc_port_power_domain(tc); in adlp_tc_phy_connect()
837 if (tc->mode == TC_PORT_TBT_ALT) { in adlp_tc_phy_connect()
838 tc->lock_wakeref = tc_cold_block(tc); in adlp_tc_phy_connect()
844 if (!adlp_tc_phy_take_ownership(tc, true) && in adlp_tc_phy_connect()
845 !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { in adlp_tc_phy_connect()
847 tc->port_name); in adlp_tc_phy_connect()
851 if (!tc_phy_is_ready(tc) && in adlp_tc_phy_connect()
852 !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { in adlp_tc_phy_connect()
854 tc->port_name); in adlp_tc_phy_connect()
858 tc->lock_wakeref = tc_cold_block(tc); in adlp_tc_phy_connect()
860 if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) in adlp_tc_phy_connect()
868 tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); in adlp_tc_phy_connect()
870 adlp_tc_phy_take_ownership(tc, false); in adlp_tc_phy_connect()
877 static void adlp_tc_phy_disconnect(struct intel_tc_port *tc) in adlp_tc_phy_disconnect() argument
879 struct drm_i915_private *i915 = tc_to_i915(tc); in adlp_tc_phy_disconnect()
881 tc_port_power_domain(tc); in adlp_tc_phy_disconnect()
886 tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); in adlp_tc_phy_disconnect()
888 switch (tc->mode) { in adlp_tc_phy_disconnect()
891 adlp_tc_phy_take_ownership(tc, false); in adlp_tc_phy_disconnect()
896 MISSING_CASE(tc->mode); in adlp_tc_phy_disconnect()
902 static void adlp_tc_phy_init(struct intel_tc_port *tc) in adlp_tc_phy_init() argument
904 tc_phy_load_fia_params(tc, true); in adlp_tc_phy_init()
922 static u32 xelpdp_tc_phy_hpd_live_status(struct intel_tc_port *tc) in xelpdp_tc_phy_hpd_live_status() argument
924 struct drm_i915_private *i915 = tc_to_i915(tc); in xelpdp_tc_phy_hpd_live_status()
925 struct intel_digital_port *dig_port = tc->dig_port; in xelpdp_tc_phy_hpd_live_status()
944 if (tc->legacy_port && (pch_isr & pch_isr_bit)) in xelpdp_tc_phy_hpd_live_status()
951 xelpdp_tc_phy_tcss_power_is_enabled(struct intel_tc_port *tc) in xelpdp_tc_phy_tcss_power_is_enabled() argument
953 struct drm_i915_private *i915 = tc_to_i915(tc); in xelpdp_tc_phy_tcss_power_is_enabled()
954 enum port port = tc->dig_port->base.port; in xelpdp_tc_phy_tcss_power_is_enabled()
956 assert_tc_cold_blocked(tc); in xelpdp_tc_phy_tcss_power_is_enabled()
962 xelpdp_tc_phy_wait_for_tcss_power(struct intel_tc_port *tc, bool enabled) in xelpdp_tc_phy_wait_for_tcss_power() argument
964 struct drm_i915_private *i915 = tc_to_i915(tc); in xelpdp_tc_phy_wait_for_tcss_power()
966 if (wait_for(xelpdp_tc_phy_tcss_power_is_enabled(tc) == enabled, 5)) { in xelpdp_tc_phy_wait_for_tcss_power()
970 tc->port_name); in xelpdp_tc_phy_wait_for_tcss_power()
977 static void __xelpdp_tc_phy_enable_tcss_power(struct intel_tc_port *tc, bool enable) in __xelpdp_tc_phy_enable_tcss_power() argument
979 struct drm_i915_private *i915 = tc_to_i915(tc); in __xelpdp_tc_phy_enable_tcss_power()
980 enum port port = tc->dig_port->base.port; in __xelpdp_tc_phy_enable_tcss_power()
983 assert_tc_cold_blocked(tc); in __xelpdp_tc_phy_enable_tcss_power()
993 static bool xelpdp_tc_phy_enable_tcss_power(struct intel_tc_port *tc, bool enable) in xelpdp_tc_phy_enable_tcss_power() argument
995 struct drm_i915_private *i915 = tc_to_i915(tc); in xelpdp_tc_phy_enable_tcss_power()
997 __xelpdp_tc_phy_enable_tcss_power(tc, enable); in xelpdp_tc_phy_enable_tcss_power()
999 if ((!tc_phy_wait_for_ready(tc) || in xelpdp_tc_phy_enable_tcss_power()
1000 !xelpdp_tc_phy_wait_for_tcss_power(tc, enable)) && in xelpdp_tc_phy_enable_tcss_power()
1001 !drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_LEGACY)) { in xelpdp_tc_phy_enable_tcss_power()
1003 __xelpdp_tc_phy_enable_tcss_power(tc, false); in xelpdp_tc_phy_enable_tcss_power()
1004 xelpdp_tc_phy_wait_for_tcss_power(tc, false); in xelpdp_tc_phy_enable_tcss_power()
1013 static void xelpdp_tc_phy_take_ownership(struct intel_tc_port *tc, bool take) in xelpdp_tc_phy_take_ownership() argument
1015 struct drm_i915_private *i915 = tc_to_i915(tc); in xelpdp_tc_phy_take_ownership()
1016 enum port port = tc->dig_port->base.port; in xelpdp_tc_phy_take_ownership()
1019 assert_tc_cold_blocked(tc); in xelpdp_tc_phy_take_ownership()
1029 static bool xelpdp_tc_phy_is_owned(struct intel_tc_port *tc) in xelpdp_tc_phy_is_owned() argument
1031 struct drm_i915_private *i915 = tc_to_i915(tc); in xelpdp_tc_phy_is_owned()
1032 enum port port = tc->dig_port->base.port; in xelpdp_tc_phy_is_owned()
1034 assert_tc_cold_blocked(tc); in xelpdp_tc_phy_is_owned()
1039 static void xelpdp_tc_phy_get_hw_state(struct intel_tc_port *tc) in xelpdp_tc_phy_get_hw_state() argument
1041 struct drm_i915_private *i915 = tc_to_i915(tc); in xelpdp_tc_phy_get_hw_state()
1045 tc_cold_wref = __tc_cold_block(tc, &domain); in xelpdp_tc_phy_get_hw_state()
1047 tc->mode = tc_phy_get_current_mode(tc); in xelpdp_tc_phy_get_hw_state()
1048 if (tc->mode != TC_PORT_DISCONNECTED) in xelpdp_tc_phy_get_hw_state()
1049 tc->lock_wakeref = tc_cold_block(tc); in xelpdp_tc_phy_get_hw_state()
1052 (tc->mode == TC_PORT_DP_ALT || tc->mode == TC_PORT_LEGACY) && in xelpdp_tc_phy_get_hw_state()
1053 !xelpdp_tc_phy_tcss_power_is_enabled(tc)); in xelpdp_tc_phy_get_hw_state()
1055 __tc_cold_unblock(tc, domain, tc_cold_wref); in xelpdp_tc_phy_get_hw_state()
1058 static bool xelpdp_tc_phy_connect(struct intel_tc_port *tc, int required_lanes) in xelpdp_tc_phy_connect() argument
1060 tc->lock_wakeref = tc_cold_block(tc); in xelpdp_tc_phy_connect()
1062 if (tc->mode == TC_PORT_TBT_ALT) in xelpdp_tc_phy_connect()
1065 if (!xelpdp_tc_phy_enable_tcss_power(tc, true)) in xelpdp_tc_phy_connect()
1068 xelpdp_tc_phy_take_ownership(tc, true); in xelpdp_tc_phy_connect()
1070 if (!tc_phy_verify_legacy_or_dp_alt_mode(tc, required_lanes)) in xelpdp_tc_phy_connect()
1076 xelpdp_tc_phy_take_ownership(tc, false); in xelpdp_tc_phy_connect()
1077 xelpdp_tc_phy_wait_for_tcss_power(tc, false); in xelpdp_tc_phy_connect()
1080 tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); in xelpdp_tc_phy_connect()
1085 static void xelpdp_tc_phy_disconnect(struct intel_tc_port *tc) in xelpdp_tc_phy_disconnect() argument
1087 switch (tc->mode) { in xelpdp_tc_phy_disconnect()
1090 xelpdp_tc_phy_take_ownership(tc, false); in xelpdp_tc_phy_disconnect()
1091 xelpdp_tc_phy_enable_tcss_power(tc, false); in xelpdp_tc_phy_disconnect()
1094 tc_cold_unblock(tc, fetch_and_zero(&tc->lock_wakeref)); in xelpdp_tc_phy_disconnect()
1097 MISSING_CASE(tc->mode); in xelpdp_tc_phy_disconnect()
1117 tc_phy_cold_off_domain(struct intel_tc_port *tc) in tc_phy_cold_off_domain() argument
1119 return tc->phy_ops->cold_off_domain(tc); in tc_phy_cold_off_domain()
1122 static u32 tc_phy_hpd_live_status(struct intel_tc_port *tc) in tc_phy_hpd_live_status() argument
1124 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_phy_hpd_live_status()
1127 mask = tc->phy_ops->hpd_live_status(tc); in tc_phy_hpd_live_status()
1135 static bool tc_phy_is_ready(struct intel_tc_port *tc) in tc_phy_is_ready() argument
1137 return tc->phy_ops->is_ready(tc); in tc_phy_is_ready()
1140 static bool tc_phy_is_owned(struct intel_tc_port *tc) in tc_phy_is_owned() argument
1142 return tc->phy_ops->is_owned(tc); in tc_phy_is_owned()
1145 static void tc_phy_get_hw_state(struct intel_tc_port *tc) in tc_phy_get_hw_state() argument
1147 tc->phy_ops->get_hw_state(tc); in tc_phy_get_hw_state()
1150 static bool tc_phy_is_ready_and_owned(struct intel_tc_port *tc, in tc_phy_is_ready_and_owned() argument
1153 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_phy_is_ready_and_owned()
1160 static bool tc_phy_is_connected(struct intel_tc_port *tc, in tc_phy_is_connected() argument
1163 struct intel_encoder *encoder = &tc->dig_port->base; in tc_phy_is_connected()
1165 bool phy_is_ready = tc_phy_is_ready(tc); in tc_phy_is_connected()
1166 bool phy_is_owned = tc_phy_is_owned(tc); in tc_phy_is_connected()
1169 if (tc_phy_is_ready_and_owned(tc, phy_is_ready, phy_is_owned)) in tc_phy_is_connected()
1176 tc->port_name, in tc_phy_is_connected()
1185 static bool tc_phy_wait_for_ready(struct intel_tc_port *tc) in tc_phy_wait_for_ready() argument
1187 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_phy_wait_for_ready()
1189 if (wait_for(tc_phy_is_ready(tc), 500)) { in tc_phy_wait_for_ready()
1191 tc->port_name); in tc_phy_wait_for_ready()
1209 tc_phy_hpd_live_mode(struct intel_tc_port *tc) in tc_phy_hpd_live_mode() argument
1211 u32 live_status_mask = tc_phy_hpd_live_status(tc); in tc_phy_hpd_live_mode()
1217 get_tc_mode_in_phy_owned_state(struct intel_tc_port *tc, in get_tc_mode_in_phy_owned_state() argument
1229 if (tc->legacy_port) in get_tc_mode_in_phy_owned_state()
1237 get_tc_mode_in_phy_not_owned_state(struct intel_tc_port *tc, in get_tc_mode_in_phy_not_owned_state() argument
1250 if (tc->legacy_port) in get_tc_mode_in_phy_not_owned_state()
1258 tc_phy_get_current_mode(struct intel_tc_port *tc) in tc_phy_get_current_mode() argument
1260 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_phy_get_current_mode()
1261 enum tc_port_mode live_mode = tc_phy_hpd_live_mode(tc); in tc_phy_get_current_mode()
1271 if (tc->legacy_port) in tc_phy_get_current_mode()
1272 tc_phy_wait_for_ready(tc); in tc_phy_get_current_mode()
1274 phy_is_ready = tc_phy_is_ready(tc); in tc_phy_get_current_mode()
1275 phy_is_owned = tc_phy_is_owned(tc); in tc_phy_get_current_mode()
1277 if (!tc_phy_is_ready_and_owned(tc, phy_is_ready, phy_is_owned)) { in tc_phy_get_current_mode()
1278 mode = get_tc_mode_in_phy_not_owned_state(tc, live_mode); in tc_phy_get_current_mode()
1281 mode = get_tc_mode_in_phy_owned_state(tc, live_mode); in tc_phy_get_current_mode()
1286 tc->port_name, in tc_phy_get_current_mode()
1295 static enum tc_port_mode default_tc_mode(struct intel_tc_port *tc) in default_tc_mode() argument
1297 if (tc->legacy_port) in default_tc_mode()
1304 hpd_mask_to_target_mode(struct intel_tc_port *tc, u32 live_status_mask) in hpd_mask_to_target_mode() argument
1311 return default_tc_mode(tc); in hpd_mask_to_target_mode()
1315 tc_phy_get_target_mode(struct intel_tc_port *tc) in tc_phy_get_target_mode() argument
1317 u32 live_status_mask = tc_phy_hpd_live_status(tc); in tc_phy_get_target_mode()
1319 return hpd_mask_to_target_mode(tc, live_status_mask); in tc_phy_get_target_mode()
1322 static void tc_phy_connect(struct intel_tc_port *tc, int required_lanes) in tc_phy_connect() argument
1324 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_phy_connect()
1325 u32 live_status_mask = tc_phy_hpd_live_status(tc); in tc_phy_connect()
1328 tc_port_fixup_legacy_flag(tc, live_status_mask); in tc_phy_connect()
1330 tc->mode = hpd_mask_to_target_mode(tc, live_status_mask); in tc_phy_connect()
1332 connected = tc->phy_ops->connect(tc, required_lanes); in tc_phy_connect()
1333 if (!connected && tc->mode != default_tc_mode(tc)) { in tc_phy_connect()
1334 tc->mode = default_tc_mode(tc); in tc_phy_connect()
1335 connected = tc->phy_ops->connect(tc, required_lanes); in tc_phy_connect()
1341 static void tc_phy_disconnect(struct intel_tc_port *tc) in tc_phy_disconnect() argument
1343 if (tc->mode != TC_PORT_DISCONNECTED) { in tc_phy_disconnect()
1344 tc->phy_ops->disconnect(tc); in tc_phy_disconnect()
1345 tc->mode = TC_PORT_DISCONNECTED; in tc_phy_disconnect()
1349 static void tc_phy_init(struct intel_tc_port *tc) in tc_phy_init() argument
1351 mutex_lock(&tc->lock); in tc_phy_init()
1352 tc->phy_ops->init(tc); in tc_phy_init()
1353 mutex_unlock(&tc->lock); in tc_phy_init()
1356 static void intel_tc_port_reset_mode(struct intel_tc_port *tc, in intel_tc_port_reset_mode() argument
1359 struct drm_i915_private *i915 = tc_to_i915(tc); in intel_tc_port_reset_mode()
1360 struct intel_digital_port *dig_port = tc->dig_port; in intel_tc_port_reset_mode()
1361 enum tc_port_mode old_tc_mode = tc->mode; in intel_tc_port_reset_mode()
1373 tc_phy_disconnect(tc); in intel_tc_port_reset_mode()
1375 tc_phy_connect(tc, required_lanes); in intel_tc_port_reset_mode()
1378 tc->port_name, in intel_tc_port_reset_mode()
1380 tc_port_mode_name(tc->mode)); in intel_tc_port_reset_mode()
1383 static bool intel_tc_port_needs_reset(struct intel_tc_port *tc) in intel_tc_port_needs_reset() argument
1385 return tc_phy_get_target_mode(tc) != tc->mode; in intel_tc_port_needs_reset()
1388 static void intel_tc_port_update_mode(struct intel_tc_port *tc, in intel_tc_port_update_mode() argument
1392 intel_tc_port_needs_reset(tc)) in intel_tc_port_update_mode()
1393 intel_tc_port_reset_mode(tc, required_lanes, force_disconnect); in intel_tc_port_update_mode()
1396 static void __intel_tc_port_get_link(struct intel_tc_port *tc) in __intel_tc_port_get_link() argument
1398 tc->link_refcount++; in __intel_tc_port_get_link()
1401 static void __intel_tc_port_put_link(struct intel_tc_port *tc) in __intel_tc_port_put_link() argument
1403 tc->link_refcount--; in __intel_tc_port_put_link()
1406 static bool tc_port_is_enabled(struct intel_tc_port *tc) in tc_port_is_enabled() argument
1408 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_port_is_enabled()
1409 struct intel_digital_port *dig_port = tc->dig_port; in tc_port_is_enabled()
1411 assert_tc_port_power_enabled(tc); in tc_port_is_enabled()
1427 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_init_mode() local
1430 mutex_lock(&tc->lock); in intel_tc_port_init_mode()
1432 drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_DISCONNECTED); in intel_tc_port_init_mode()
1433 drm_WARN_ON(&i915->drm, tc->lock_wakeref); in intel_tc_port_init_mode()
1434 drm_WARN_ON(&i915->drm, tc->link_refcount); in intel_tc_port_init_mode()
1436 tc_phy_get_hw_state(tc); in intel_tc_port_init_mode()
1441 tc->init_mode = tc->mode; in intel_tc_port_init_mode()
1454 if (!tc_port_is_enabled(tc)) { in intel_tc_port_init_mode()
1456 } else if (tc->mode == TC_PORT_DISCONNECTED) { in intel_tc_port_init_mode()
1457 drm_WARN_ON(&i915->drm, !tc->legacy_port); in intel_tc_port_init_mode()
1460 tc->port_name); in intel_tc_port_init_mode()
1465 intel_tc_port_update_mode(tc, 1, false); in intel_tc_port_init_mode()
1468 __intel_tc_port_get_link(tc); in intel_tc_port_init_mode()
1470 mutex_unlock(&tc->lock); in intel_tc_port_init_mode()
1473 static bool tc_port_has_active_links(struct intel_tc_port *tc, in tc_port_has_active_links() argument
1476 struct drm_i915_private *i915 = tc_to_i915(tc); in tc_port_has_active_links()
1477 struct intel_digital_port *dig_port = tc->dig_port; in tc_port_has_active_links()
1489 if (active_links && !tc_phy_is_connected(tc, pll_type)) in tc_port_has_active_links()
1492 tc->port_name, active_links); in tc_port_has_active_links()
1513 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_sanitize_mode() local
1515 mutex_lock(&tc->lock); in intel_tc_port_sanitize_mode()
1517 drm_WARN_ON(&i915->drm, tc->link_refcount != 1); in intel_tc_port_sanitize_mode()
1518 if (!tc_port_has_active_links(tc, crtc_state)) { in intel_tc_port_sanitize_mode()
1525 if (tc->init_mode != TC_PORT_TBT_ALT && in intel_tc_port_sanitize_mode()
1526 tc->init_mode != TC_PORT_DISCONNECTED) in intel_tc_port_sanitize_mode()
1529 tc->port_name, in intel_tc_port_sanitize_mode()
1530 tc_port_mode_name(tc->init_mode)); in intel_tc_port_sanitize_mode()
1531 tc_phy_disconnect(tc); in intel_tc_port_sanitize_mode()
1532 __intel_tc_port_put_link(tc); in intel_tc_port_sanitize_mode()
1536 tc->port_name, in intel_tc_port_sanitize_mode()
1537 tc_port_mode_name(tc->mode)); in intel_tc_port_sanitize_mode()
1539 mutex_unlock(&tc->lock); in intel_tc_port_sanitize_mode()
1556 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_connected_locked() local
1561 if (tc->mode != TC_PORT_DISCONNECTED) in intel_tc_port_connected_locked()
1562 mask = BIT(tc->mode); in intel_tc_port_connected_locked()
1564 return tc_phy_hpd_live_status(tc) & mask; in intel_tc_port_connected_locked()
1570 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_connected() local
1573 mutex_lock(&tc->lock); in intel_tc_port_connected()
1575 mutex_unlock(&tc->lock); in intel_tc_port_connected()
1580 static bool __intel_tc_port_link_needs_reset(struct intel_tc_port *tc) in __intel_tc_port_link_needs_reset() argument
1584 mutex_lock(&tc->lock); in __intel_tc_port_link_needs_reset()
1586 ret = tc->link_refcount && in __intel_tc_port_link_needs_reset()
1587 tc->mode == TC_PORT_DP_ALT && in __intel_tc_port_link_needs_reset()
1588 intel_tc_port_needs_reset(tc); in __intel_tc_port_link_needs_reset()
1590 mutex_unlock(&tc->lock); in __intel_tc_port_link_needs_reset()
1606 static int reset_link_commit(struct intel_tc_port *tc, in reset_link_commit() argument
1610 struct drm_i915_private *i915 = tc_to_i915(tc); in reset_link_commit()
1611 struct intel_digital_port *dig_port = tc->dig_port; in reset_link_commit()
1638 if (!__intel_tc_port_link_needs_reset(tc)) in reset_link_commit()
1644 static int reset_link(struct intel_tc_port *tc) in reset_link() argument
1646 struct drm_i915_private *i915 = tc_to_i915(tc); in reset_link()
1660 ret = reset_link_commit(tc, state, &ctx); in reset_link()
1669 struct intel_tc_port *tc = in intel_tc_port_link_reset_work() local
1671 struct drm_i915_private *i915 = tc_to_i915(tc); in intel_tc_port_link_reset_work()
1674 if (!__intel_tc_port_link_needs_reset(tc)) in intel_tc_port_link_reset_work()
1681 tc->port_name); in intel_tc_port_link_reset_work()
1682 ret = reset_link(tc); in intel_tc_port_link_reset_work()
1704 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_link_cancel_reset_work() local
1709 cancel_delayed_work(&tc->link_reset_work); in intel_tc_port_link_cancel_reset_work()
1712 static void __intel_tc_port_lock(struct intel_tc_port *tc, in __intel_tc_port_lock() argument
1715 struct drm_i915_private *i915 = tc_to_i915(tc); in __intel_tc_port_lock()
1717 mutex_lock(&tc->lock); in __intel_tc_port_lock()
1719 cancel_delayed_work(&tc->disconnect_phy_work); in __intel_tc_port_lock()
1721 if (!tc->link_refcount) in __intel_tc_port_lock()
1722 intel_tc_port_update_mode(tc, required_lanes, in __intel_tc_port_lock()
1725 drm_WARN_ON(&i915->drm, tc->mode == TC_PORT_DISCONNECTED); in __intel_tc_port_lock()
1726 drm_WARN_ON(&i915->drm, tc->mode != TC_PORT_TBT_ALT && in __intel_tc_port_lock()
1727 !tc_phy_is_owned(tc)); in __intel_tc_port_lock()
1742 struct intel_tc_port *tc = in intel_tc_port_disconnect_phy_work() local
1745 mutex_lock(&tc->lock); in intel_tc_port_disconnect_phy_work()
1747 if (!tc->link_refcount) in intel_tc_port_disconnect_phy_work()
1748 intel_tc_port_update_mode(tc, 1, true); in intel_tc_port_disconnect_phy_work()
1750 mutex_unlock(&tc->lock); in intel_tc_port_disconnect_phy_work()
1766 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_suspend() local
1768 cancel_delayed_work_sync(&tc->link_reset_work); in intel_tc_port_suspend()
1774 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_unlock() local
1776 if (!tc->link_refcount && tc->mode != TC_PORT_DISCONNECTED) in intel_tc_port_unlock()
1777 queue_delayed_work(system_unbound_wq, &tc->disconnect_phy_work, in intel_tc_port_unlock()
1780 mutex_unlock(&tc->lock); in intel_tc_port_unlock()
1785 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_ref_held() local
1787 return mutex_is_locked(&tc->lock) || in intel_tc_port_ref_held()
1788 tc->link_refcount; in intel_tc_port_ref_held()
1794 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_get_link() local
1796 __intel_tc_port_lock(tc, required_lanes); in intel_tc_port_get_link()
1797 __intel_tc_port_get_link(tc); in intel_tc_port_get_link()
1803 struct intel_tc_port *tc = to_tc_port(dig_port); in intel_tc_port_put_link() local
1806 __intel_tc_port_put_link(tc); in intel_tc_port_put_link()
1821 struct intel_tc_port *tc; in intel_tc_port_init() local
1828 tc = kzalloc(sizeof(*tc), GFP_KERNEL); in intel_tc_port_init()
1829 if (!tc) in intel_tc_port_init()
1832 dig_port->tc = tc; in intel_tc_port_init()
1833 tc->dig_port = dig_port; in intel_tc_port_init()
1836 tc->phy_ops = &xelpdp_tc_phy_ops; in intel_tc_port_init()
1838 tc->phy_ops = &adlp_tc_phy_ops; in intel_tc_port_init()
1840 tc->phy_ops = &tgl_tc_phy_ops; in intel_tc_port_init()
1842 tc->phy_ops = &icl_tc_phy_ops; in intel_tc_port_init()
1844 tc->port_name = kasprintf(GFP_KERNEL, "%c/TC#%d", port_name(port), in intel_tc_port_init()
1846 if (!tc->port_name) { in intel_tc_port_init()
1847 kfree(tc); in intel_tc_port_init()
1851 mutex_init(&tc->lock); in intel_tc_port_init()
1853 INIT_DELAYED_WORK(&tc->disconnect_phy_work, intel_tc_port_disconnect_phy_work); in intel_tc_port_init()
1854 INIT_DELAYED_WORK(&tc->link_reset_work, intel_tc_port_link_reset_work); in intel_tc_port_init()
1855 tc->legacy_port = is_legacy; in intel_tc_port_init()
1856 tc->mode = TC_PORT_DISCONNECTED; in intel_tc_port_init()
1857 tc->link_refcount = 0; in intel_tc_port_init()
1859 tc_phy_init(tc); in intel_tc_port_init()
1870 kfree(dig_port->tc->port_name); in intel_tc_port_cleanup()
1871 kfree(dig_port->tc); in intel_tc_port_cleanup()
1872 dig_port->tc = NULL; in intel_tc_port_cleanup()