Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 291906f1 authored by Jesse Barnes's avatar Jesse Barnes Committed by Chris Wilson
Browse files

drm/i915: add port assertion check when disabling transcoders



When a transcoder is disabled, any ports pointing at it should also be
disabled.  If they're not, we may fail to disable the transcoder,
leading to blank displays.

Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 19ec1358
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -1265,6 +1265,62 @@ static void assert_transcoder_disabled(struct drm_i915_private *dev_priv,
	WARN(enabled, "transcoder assertion failed, should be off on pipe %c but is still active\n", pipe ? 'B' :'A');
}

static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
				   enum pipe pipe, int reg)
{
	u32 val;
	u32 sel_pipe;

	val = I915_READ(reg);
	sel_pipe = (val & DP_PIPEB_SELECT) >> 30;
	WARN((val & DP_PORT_EN) && sel_pipe == pipe,
	     "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
	     reg, pipe ? 'B' : 'A');
}

static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
				     enum pipe pipe, int reg)
{
	u32 val;
	u32 sel_pipe;

	val = I915_READ(reg);
	sel_pipe = (val & TRANSCODER_B) >> 30;
	WARN((val & PORT_ENABLE) && sel_pipe == pipe,
	     "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
	     reg, pipe ? 'B' : 'A');
}

static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
				      enum pipe pipe)
{
	int reg;
	u32 val;
	u32 sel_pipe;

	assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B);
	assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C);
	assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D);

	reg = PCH_ADPA;
	val = I915_READ(reg);
	sel_pipe = (val & ADPA_TRANS_B_SELECT) >> 30;
	WARN(sel_pipe == pipe && (val & ADPA_DAC_ENABLE),
	     "PCH VGA enabled on transcoder %c, should be disabled\n",
	     pipe ? 'B' : 'A');

	reg = PCH_LVDS;
	val = I915_READ(reg);
	sel_pipe = (val & LVDS_PIPEB_SELECT) >> 30;
	WARN(sel_pipe == pipe && (val & LVDS_PORT_EN),
	     "PCH LVDS enabled on transcoder %c, should be disabled\n",
	     pipe ? 'B' : 'A');

	assert_pch_hdmi_disabled(dev_priv, pipe, HDMIB);
	assert_pch_hdmi_disabled(dev_priv, pipe, HDMIC);
	assert_pch_hdmi_disabled(dev_priv, pipe, HDMID);
}

/**
 * intel_enable_pll - enable a PLL
 * @dev_priv: i915 private structure
@@ -1419,6 +1475,9 @@ static void intel_disable_transcoder(struct drm_i915_private *dev_priv,
	assert_fdi_tx_disabled(dev_priv, pipe);
	assert_fdi_rx_disabled(dev_priv, pipe);

	/* Ports must be off as well */
	assert_pch_ports_disabled(dev_priv, pipe);

	reg = TRANSCONF(pipe);
	val = I915_READ(reg);
	val &= ~TRANS_ENABLE;