From: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Make HSW/BDW use the new VBT child device driven output probing as well. To achieve that the strap checks are moved into intel_ddi_init() itself. I have one HSW ULT laptop here which declares all the ports A-D in the VBT, so in order to avoid assert_port_valid() tripping on DDI D (which is not present on ULT/ULX) I kept the strap check as the first thing we do. Thought arguably this particular machine is an internal development device so not something any real user should have. But I suppose it's possible that real consumer systems also had similar VBTs in this era. Signed-off-by: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_ddi.c | 37 +++++++++++++++++--- drivers/gpu/drm/i915/display/intel_display.c | 17 +-------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c index e94eb7bb6e53..6deaa3433958 100644 --- a/drivers/gpu/drm/i915/display/intel_ddi.c +++ b/drivers/gpu/drm/i915/display/intel_ddi.c @@ -4277,8 +4277,29 @@ static bool port_in_use(struct drm_i915_private *i915, enum port port) return false; } +static bool port_strap_detected(struct drm_i915_private *i915, enum port port) +{ + /* straps not used on skl+ */ + if (DISPLAY_VER(i915) >= 9) + return true; + + switch (port) { + case PORT_A: + return intel_de_read(i915, DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED; + case PORT_B: + return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDIB_DETECTED; + case PORT_C: + return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDIC_DETECTED; + case PORT_D: + return intel_de_read(i915, SFUSE_STRAP) & SFUSE_STRAP_DDID_DETECTED; + default: + MISSING_CASE(port); + return false; + } +} + void intel_ddi_init(struct drm_i915_private *dev_priv, struct intel_bios_encoder_data *devdata, enum port port) { @@ -4286,8 +4307,20 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, struct intel_encoder *encoder; bool init_hdmi, init_dp; enum phy phy = intel_port_to_phy(dev_priv, port); + /* + * On some HSW ULT systems the VBT has been observed + * to advertise DDI D, even though it does not exist on + * the platform. Check the strap first to avoid tripping + * assert_port_valid(). + */ + if (!port_strap_detected(dev_priv, port)) { + drm_dbg_kms(&dev_priv->drm, + "Port %c strap not detected\n", port_name(port)); + return; + } + if (!assert_port_valid(dev_priv, port)) return; if (port_in_use(dev_priv, port)) { @@ -4295,12 +4328,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, "Port %c already claimed\n", port_name(port)); return; } - /* FIXME convert HSW/BDW */ - if (!devdata) - devdata = intel_bios_encoder_data_lookup(dev_priv, port); - intel_bios_encoder_sanitize(devdata, port); if (intel_bios_encoder_supports_dsi(devdata)) { /* BXT/GLK handled elsewhere, for now at least */ diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index bb1397381385..a68ad58f04d1 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7811,31 +7811,16 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) if (!HAS_DISPLAY(dev_priv)) return; - if (DISPLAY_VER(dev_priv) >= 9) { + if (HAS_DDI(dev_priv)) { intel_bios_for_each_encoder(dev_priv, intel_ddi_init); if (IS_GEMINILAKE(dev_priv) || IS_BROXTON(dev_priv)) vlv_dsi_init(dev_priv); - } else if (HAS_DDI(dev_priv)) { - u32 found; if (intel_ddi_crt_present(dev_priv)) intel_crt_init(dev_priv); - - /* Haswell uses DDI functions to detect digital outputs. */ - found = intel_de_read(dev_priv, DDI_BUF_CTL(PORT_A)) & DDI_INIT_DISPLAY_DETECTED; - if (found) - intel_ddi_init(dev_priv, NULL, PORT_A); - - found = intel_de_read(dev_priv, SFUSE_STRAP); - if (found & SFUSE_STRAP_DDIB_DETECTED) - intel_ddi_init(dev_priv, NULL, PORT_B); - if (found & SFUSE_STRAP_DDIC_DETECTED) - intel_ddi_init(dev_priv, NULL, PORT_C); - if (found & SFUSE_STRAP_DDID_DETECTED) - intel_ddi_init(dev_priv, NULL, PORT_D); } else if (HAS_PCH_SPLIT(dev_priv)) { int found; /* -- 2.39.2