On Mon, 2021-02-08 at 17:43 +0200, Imre Deak wrote: > The TypeC FIA can be powered down if the TC-COLD power state is allowed, > so block the TC-COLD state when initializing the FIA. > > Note that this isn't needed on ICL where the FIA is never modular and > which has no generic way to block TC-COLD (except for platforms with a > legacy TypeC port and on those too only via these legacy ports, not via > a DP-alt/TBT port). Reviewed-by: José Roberto de Souza <jose.souza@xxxxxxxxx> > > Cc: <stable@xxxxxxxxxxxxxxx> # v5.10+ > Cc: José Roberto de Souza <jose.souza@xxxxxxxxx> > Reported-by: Paul Menzel <pmenzel@xxxxxxxxxxxxx> > Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/3027 > Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx> > --- > drivers/gpu/drm/i915/display/intel_tc.c | 67 ++++++++++++++----------- > 1 file changed, 37 insertions(+), 30 deletions(-) > > diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c > index 27dc2dad6809c..2cefc13535a0f 100644 > --- a/drivers/gpu/drm/i915/display/intel_tc.c > +++ b/drivers/gpu/drm/i915/display/intel_tc.c > @@ -23,36 +23,6 @@ static const char *tc_port_mode_name(enum tc_port_mode mode) > return names[mode]; > } > > > > > -static void > -tc_port_load_fia_params(struct drm_i915_private *i915, > - struct intel_digital_port *dig_port) > -{ > - enum port port = dig_port->base.port; > - enum tc_port tc_port = intel_port_to_tc(i915, port); > - u32 modular_fia; > - > - if (INTEL_INFO(i915)->display.has_modular_fia) { > - modular_fia = intel_uncore_read(&i915->uncore, > - PORT_TX_DFLEXDPSP(FIA1)); > - drm_WARN_ON(&i915->drm, modular_fia == 0xffffffff); > - modular_fia &= MODULAR_FIA_MASK; > - } else { > - modular_fia = 0; > - } > - > - /* > - * Each Modular FIA instance houses 2 TC ports. In SOC that has more > - * than two TC ports, there are multiple instances of Modular FIA. > - */ > - if (modular_fia) { > - dig_port->tc_phy_fia = tc_port / 2; > - dig_port->tc_phy_fia_idx = tc_port % 2; > - } else { > - dig_port->tc_phy_fia = FIA1; > - dig_port->tc_phy_fia_idx = tc_port; > - } > -} > - > static enum intel_display_power_domain > tc_cold_get_power_domain(struct intel_digital_port *dig_port) > { > @@ -646,6 +616,43 @@ void intel_tc_port_put_link(struct intel_digital_port *dig_port) > mutex_unlock(&dig_port->tc_lock); > } > > > > > +static bool > +tc_has_modular_fia(struct drm_i915_private *i915, struct intel_digital_port *dig_port) > +{ > + intel_wakeref_t wakeref; > + u32 val; > + > + if (!INTEL_INFO(i915)->display.has_modular_fia) > + return false; > + > + wakeref = tc_cold_block(dig_port); > + val = intel_uncore_read(&i915->uncore, PORT_TX_DFLEXDPSP(FIA1)); > + tc_cold_unblock(dig_port, wakeref); > + > + drm_WARN_ON(&i915->drm, val == 0xffffffff); > + > + return val & MODULAR_FIA_MASK; > +} > + > +static void > +tc_port_load_fia_params(struct drm_i915_private *i915, struct intel_digital_port *dig_port) > +{ > + enum port port = dig_port->base.port; > + enum tc_port tc_port = intel_port_to_tc(i915, port); > + > + /* > + * Each Modular FIA instance houses 2 TC ports. In SOC that has more > + * than two TC ports, there are multiple instances of Modular FIA. > + */ > + if (tc_has_modular_fia(i915, dig_port)) { > + dig_port->tc_phy_fia = tc_port / 2; > + dig_port->tc_phy_fia_idx = tc_port % 2; > + } else { > + dig_port->tc_phy_fia = FIA1; > + dig_port->tc_phy_fia_idx = tc_port; > + } > +} > + > void intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) > { > struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);