Skip to content

Commit 49c55f7

Browse files
committed
drm/i915/hdmi: Turn DP++ TMDS output buffers back on in encoder->shutdown()
Looks like our VBIOS/GOP generally fail to turn the DP dual mode adater TMDS output buffers back on after a reboot. This leads to a black screen after reboot if we turned the TMDS output buffers off prior to reboot. And if i915 decides to do a fastboot the black screen will persist even after i915 takes over. Apparently this has been a problem ever since commit b2ccb82 ("drm/i915: Enable/disable TMDS output buffers in DP++ adaptor as needed") if one rebooted while the display was turned off. And things became worse with commit fe0f1e3 ("drm/i915: Shut down displays gracefully on reboot") since now we always turn the display off before a reboot. This was reported on a RKL, but I confirmed the same behaviour on my SNB as well. So looks pretty universal. Let's fix this by explicitly turning the TMDS output buffers back on in the encoder->shutdown() hook. Note that this gets called after irqs have been disabled, so the i2c communication with the DP dual mode adapter has to be performed via polling (which the gmbus code is perfectly happy to do for us). We also need a bit of care in handling DDI encoders which may or may not be set up for HDMI output. Specifically ddc_pin will not be populated for a DP only DDI encoder, in which case we don't want to call intel_gmbus_get_adapter(). We can handle that by simply doing the dual mode adapter type check before calling intel_gmbus_get_adapter(). Cc: <[email protected]> # v5.11+ Fixes: fe0f1e3 ("drm/i915: Shut down displays gracefully on reboot") Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/4371 Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Stanislav Lisovskiy <[email protected]>
1 parent fa2a6c5 commit 49c55f7

File tree

4 files changed

+17
-2
lines changed

4 files changed

+17
-2
lines changed

drivers/gpu/drm/i915/display/g4x_hdmi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ void g4x_hdmi_init(struct drm_i915_private *dev_priv,
584584
else
585585
intel_encoder->enable = g4x_enable_hdmi;
586586
}
587+
intel_encoder->shutdown = intel_hdmi_encoder_shutdown;
587588

588589
intel_encoder->type = INTEL_OUTPUT_HDMI;
589590
intel_encoder->power_domain = intel_port_to_power_domain(port);

drivers/gpu/drm/i915/display/intel_ddi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4312,6 +4312,7 @@ static void intel_ddi_encoder_shutdown(struct intel_encoder *encoder)
43124312
enum phy phy = intel_port_to_phy(i915, encoder->port);
43134313

43144314
intel_dp_encoder_shutdown(encoder);
4315+
intel_hdmi_encoder_shutdown(encoder);
43154316

43164317
if (!intel_phy_is_tc(i915, phy))
43174318
return;

drivers/gpu/drm/i915/display/intel_hdmi.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,12 +1246,13 @@ static void hsw_set_infoframes(struct intel_encoder *encoder,
12461246
void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
12471247
{
12481248
struct drm_i915_private *dev_priv = intel_hdmi_to_i915(hdmi);
1249-
struct i2c_adapter *adapter =
1250-
intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
1249+
struct i2c_adapter *adapter;
12511250

12521251
if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
12531252
return;
12541253

1254+
adapter = intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
1255+
12551256
drm_dbg_kms(&dev_priv->drm, "%s DP dual mode adaptor TMDS output\n",
12561257
enable ? "Enabling" : "Disabling");
12571258

@@ -2285,6 +2286,17 @@ int intel_hdmi_compute_config(struct intel_encoder *encoder,
22852286
return 0;
22862287
}
22872288

2289+
void intel_hdmi_encoder_shutdown(struct intel_encoder *encoder)
2290+
{
2291+
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
2292+
2293+
/*
2294+
* Give a hand to buggy BIOSen which forget to turn
2295+
* the TMDS output buffers back on after a reboot.
2296+
*/
2297+
intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
2298+
}
2299+
22882300
static void
22892301
intel_hdmi_unset_edid(struct drm_connector *connector)
22902302
{

drivers/gpu/drm/i915/display/intel_hdmi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *dig_port,
2828
int intel_hdmi_compute_config(struct intel_encoder *encoder,
2929
struct intel_crtc_state *pipe_config,
3030
struct drm_connector_state *conn_state);
31+
void intel_hdmi_encoder_shutdown(struct intel_encoder *encoder);
3132
bool intel_hdmi_handle_sink_scrambling(struct intel_encoder *encoder,
3233
struct drm_connector *connector,
3334
bool high_tmds_clock_ratio,

0 commit comments

Comments
 (0)