Commit 67165722 authored by Imre Deak's avatar Imre Deak

drm/i915/tc: Fix TC port link ref init for DP MST during HW readout

An enabled TC MST port holds one TC port link reference, regardless of
the number of enabled streams on it, but the TC port HW readout takes
one reference for each active MST stream.

Fix the HW readout, taking only one reference for MST ports.

This didn't cause an actual problem, since the encoder HW readout doesn't
yet support reading out the MST HW state.
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarMika Kahola <mika.kahola@intel.com>
Reviewed-by: default avatarAndrzej Hajda <andrzej.hajda@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230316131724.359612-3-imre.deak@intel.com
parent a972cd3f
...@@ -660,11 +660,14 @@ static void intel_tc_port_update_mode(struct intel_digital_port *dig_port, ...@@ -660,11 +660,14 @@ static void intel_tc_port_update_mode(struct intel_digital_port *dig_port,
tc_cold_unblock(dig_port, domain, wref); tc_cold_unblock(dig_port, domain, wref);
} }
static void static void __intel_tc_port_get_link(struct intel_digital_port *dig_port)
intel_tc_port_link_init_refcount(struct intel_digital_port *dig_port,
int refcount)
{ {
dig_port->tc_link_refcount = refcount; dig_port->tc_link_refcount++;
}
static void __intel_tc_port_put_link(struct intel_digital_port *dig_port)
{
dig_port->tc_link_refcount--;
} }
/** /**
...@@ -690,7 +693,7 @@ void intel_tc_port_init_mode(struct intel_digital_port *dig_port) ...@@ -690,7 +693,7 @@ void intel_tc_port_init_mode(struct intel_digital_port *dig_port)
dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port); dig_port->tc_mode = intel_tc_port_get_current_mode(dig_port);
/* Prevent changing dig_port->tc_mode until intel_tc_port_sanitize_mode() is called. */ /* Prevent changing dig_port->tc_mode until intel_tc_port_sanitize_mode() is called. */
intel_tc_port_link_init_refcount(dig_port, 1); __intel_tc_port_get_link(dig_port);
dig_port->tc_lock_wakeref = tc_cold_block(dig_port, &dig_port->tc_lock_power_domain); dig_port->tc_lock_wakeref = tc_cold_block(dig_port, &dig_port->tc_lock_power_domain);
tc_cold_unblock(dig_port, domain, tc_cold_wref); tc_cold_unblock(dig_port, domain, tc_cold_wref);
...@@ -726,8 +729,6 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port) ...@@ -726,8 +729,6 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port)
active_links = to_intel_crtc(encoder->base.crtc)->active; active_links = to_intel_crtc(encoder->base.crtc)->active;
drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount != 1); drm_WARN_ON(&i915->drm, dig_port->tc_link_refcount != 1);
intel_tc_port_link_init_refcount(dig_port, active_links);
if (active_links) { if (active_links) {
if (!icl_tc_phy_is_connected(dig_port)) if (!icl_tc_phy_is_connected(dig_port))
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
...@@ -746,6 +747,7 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port) ...@@ -746,6 +747,7 @@ void intel_tc_port_sanitize_mode(struct intel_digital_port *dig_port)
dig_port->tc_port_name, dig_port->tc_port_name,
tc_port_mode_name(dig_port->tc_mode)); tc_port_mode_name(dig_port->tc_mode));
icl_tc_phy_disconnect(dig_port); icl_tc_phy_disconnect(dig_port);
__intel_tc_port_put_link(dig_port);
tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain, tc_cold_unblock(dig_port, dig_port->tc_lock_power_domain,
fetch_and_zero(&dig_port->tc_lock_wakeref)); fetch_and_zero(&dig_port->tc_lock_wakeref));
...@@ -864,14 +866,14 @@ void intel_tc_port_get_link(struct intel_digital_port *dig_port, ...@@ -864,14 +866,14 @@ void intel_tc_port_get_link(struct intel_digital_port *dig_port,
int required_lanes) int required_lanes)
{ {
__intel_tc_port_lock(dig_port, required_lanes); __intel_tc_port_lock(dig_port, required_lanes);
dig_port->tc_link_refcount++; __intel_tc_port_get_link(dig_port);
intel_tc_port_unlock(dig_port); intel_tc_port_unlock(dig_port);
} }
void intel_tc_port_put_link(struct intel_digital_port *dig_port) void intel_tc_port_put_link(struct intel_digital_port *dig_port)
{ {
intel_tc_port_lock(dig_port); intel_tc_port_lock(dig_port);
--dig_port->tc_link_refcount; __intel_tc_port_put_link(dig_port);
intel_tc_port_unlock(dig_port); intel_tc_port_unlock(dig_port);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment