diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-04-17 06:38:35 +0100 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-05-04 12:38:02 -0700 |
commit | 31acbcc408f412d1ba73765b846c38642be553c3 (patch) | |
tree | 6a1f340e21b0c24d067eccbc369c1d96098e6ffc | |
parent | 2dd251f0a294300a1cf8f4b63768145fa6153c4d (diff) | |
download | linux-31acbcc408f412d1ba73765b846c38642be553c3.tar.bz2 |
drm/i915/dp: Be paranoid in case we disable a DP before it is attached
Given that the hardware may be left in a random condition by the BIOS,
it is conceivable that we then attempt to clear the DP_PIPEB_SELECT bit
without us ever enabling/attaching the DP encoder to a pipe. Thus
causing a NULL deference when we attempt to wait for a vblank on that
crtc.
Reported-and-tested-by: Bryan Christ <bryan.christ@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=36314
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=36456
Reported-and-tested-by: Bo Wang <bo.b.wang@intel.com>
Cc: stable@kernel.org
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cb8578b7e443..a4d80314e7f8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1470,7 +1470,8 @@ intel_dp_link_down(struct intel_dp *intel_dp) if (!HAS_PCH_CPT(dev) && I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { - struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); + struct drm_crtc *crtc = intel_dp->base.base.crtc; + /* Hardware workaround: leaving our transcoder select * set to transcoder B while it's off will prevent the * corresponding HDMI output on transcoder A. @@ -1485,7 +1486,19 @@ intel_dp_link_down(struct intel_dp *intel_dp) /* Changes to enable or select take place the vblank * after being written. */ - intel_wait_for_vblank(dev, intel_crtc->pipe); + if (crtc == NULL) { + /* We can arrive here never having been attached + * to a CRTC, for instance, due to inheriting + * random state from the BIOS. + * + * If the pipe is not running, play safe and + * wait for the clocks to stabilise before + * continuing. + */ + POSTING_READ(intel_dp->output_reg); + msleep(50); + } else + intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); } I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |