Commit 8e8289a0 authored by Imre Deak's avatar Imre Deak
Browse files

drm/i915/tc: Avoid using legacy AUX PW in TBT mode



For the ADL-P TBT mode the spec doesn't require blocking TC-cold by
using the legacy AUX power domain. To avoid the timeouts that this would
cause during PHY disconnect/reconnect sequences (which will be more
frequent after a follow-up change) use the TC_COLD_OFF power domain in
TBT mode on all platforms. On TGL this power domain blocks TC-cold via a
PUNIT command, while on other platforms the domain just takes a runtime
PM reference.

If the HPD live status indicates that the port mode needs to be reset
- for instance after switching from TBT to a DP-alt sink - still take
the AUX domain, since the IOM firmware handshake requires this.

v2: Rebased on v2 of the previous patch.

Cc: José Roberto de Souza <jose.souza@intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarJosé Roberto de Souza <jose.souza@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210929132833.2253961-5-imre.deak@intel.com
parent d0bc6770
Loading
Loading
Loading
Loading
+36 −19
Original line number Diff line number Diff line
@@ -59,10 +59,10 @@ bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port)
static enum intel_display_power_domain
tc_cold_get_power_domain(struct intel_digital_port *dig_port, enum tc_port_mode mode)
{
	if (intel_tc_cold_requires_aux_pw(dig_port))
		return intel_legacy_aux_to_power_domain(dig_port->aux_ch);
	else
	if (mode == TC_PORT_TBT_ALT || !intel_tc_cold_requires_aux_pw(dig_port))
		return POWER_DOMAIN_TC_COLD_OFF;

	return intel_legacy_aux_to_power_domain(dig_port->aux_ch);
}

static intel_wakeref_t
@@ -645,6 +645,36 @@ static void intel_tc_port_reset_mode(struct intel_digital_port *dig_port,
		    tc_port_mode_name(dig_port->tc_mode));
}

static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port)
{
	return intel_tc_port_get_target_mode(dig_port) != dig_port->tc_mode;
}

static void intel_tc_port_update_mode(struct intel_digital_port *dig_port,
				      int required_lanes, bool force_disconnect)
{
	enum intel_display_power_domain domain;
	intel_wakeref_t wref;
	bool needs_reset = force_disconnect;

	if (!needs_reset) {
		/* Get power domain required to check the hotplug live status. */
		wref = tc_cold_block(dig_port, &domain);
		needs_reset = intel_tc_port_needs_reset(dig_port);
		tc_cold_unblock(dig_port, domain, wref);
	}

	if (!needs_reset)
		return;

	/* Get power domain required for resetting the mode. */
	wref = tc_cold_block_in_mode(dig_port, TC_PORT_DISCONNECTED, &domain);

	intel_tc_port_reset_mode(dig_port, required_lanes, force_disconnect);

	tc_cold_unblock(dig_port, domain, wref);
}

static void
intel_tc_port_link_init_refcount(struct intel_digital_port *dig_port,
				 int refcount)
@@ -691,11 +721,6 @@ void intel_tc_port_sanitize(struct intel_digital_port *dig_port)
	mutex_unlock(&dig_port->tc_lock);
}

static bool intel_tc_port_needs_reset(struct intel_digital_port *dig_port)
{
	return intel_tc_port_get_target_mode(dig_port) != dig_port->tc_mode;
}

/*
 * The type-C ports are different because even when they are connected, they may
 * not be available/usable by the graphics driver: see the comment on
@@ -735,19 +760,11 @@ static void __intel_tc_port_lock(struct intel_digital_port *dig_port,

	mutex_lock(&dig_port->tc_lock);

	if (!dig_port->tc_link_refcount) {
		enum intel_display_power_domain domain;
		intel_wakeref_t tc_cold_wref;

		tc_cold_wref = tc_cold_block(dig_port, &domain);

		if (force_disconnect || intel_tc_port_needs_reset(dig_port))
			intel_tc_port_reset_mode(dig_port, required_lanes,
	if (!dig_port->tc_link_refcount)
		intel_tc_port_update_mode(dig_port, required_lanes,
					  force_disconnect);

		tc_cold_unblock(dig_port, domain, tc_cold_wref);
	}

	drm_WARN_ON(&i915->drm, dig_port->tc_lock_wakeref);
	dig_port->tc_lock_wakeref = wakeref;
}