Skip to content

Commit

Permalink
drm/i915: Apply the IBX transcoder A w/a for HDMI to SDVO as well
Browse files Browse the repository at this point in the history
As the SDVO/HDMI registers are multiplex, it is safe to assume that the
w/a required for HDMI on IbexPoint, namely that the SDVO register cannot
both be disabled and have selected transcoder B, is also required for
SDVO. At least the modeset state checker detects that the transcoder
selection is left in the undefined state, and so it appears sensible to
apply the w/a:

[ 1814.480052] WARNING: at drivers/gpu/drm/i915/intel_display.c:1487 assert_pch_hdmi_disabled+0xad/0xb5()
[ 1814.480053] Hardware name: Libretto W100
[ 1814.480054] IBX PCH hdmi port still using transcoder B

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=57066
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
  • Loading branch information
Chris Wilson authored and Daniel Vetter committed Nov 21, 2012
1 parent b3bf076 commit 776ca7c
Showing 1 changed file with 37 additions and 1 deletion.
38 changes: 37 additions & 1 deletion drivers/gpu/drm/i915/intel_sdvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,30 @@ static void intel_disable_sdvo(struct intel_encoder *encoder)

temp = I915_READ(intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) != 0) {
/* HW workaround for IBX, we need to move the port to
* transcoder A before disabling it. */
if (HAS_PCH_IBX(encoder->base.dev)) {
struct drm_crtc *crtc = encoder->base.crtc;
int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;

if (temp & SDVO_PIPE_B_SELECT) {
temp &= ~SDVO_PIPE_B_SELECT;
I915_WRITE(intel_sdvo->sdvo_reg, temp);
POSTING_READ(intel_sdvo->sdvo_reg);

/* Again we need to write this twice. */
I915_WRITE(intel_sdvo->sdvo_reg, temp);
POSTING_READ(intel_sdvo->sdvo_reg);

/* Transcoder selection bits only update
* effectively on vblank. */
if (crtc)
intel_wait_for_vblank(encoder->base.dev, pipe);
else
msleep(50);
}
}

intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE);
}
}
Expand All @@ -1244,8 +1268,20 @@ static void intel_enable_sdvo(struct intel_encoder *encoder)
u8 status;

temp = I915_READ(intel_sdvo->sdvo_reg);
if ((temp & SDVO_ENABLE) == 0)
if ((temp & SDVO_ENABLE) == 0) {
/* HW workaround for IBX, we need to move the port
* to transcoder A before disabling it. */
if (HAS_PCH_IBX(dev)) {
struct drm_crtc *crtc = encoder->base.crtc;
int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1;

/* Restore the transcoder select bit. */
if (pipe == PIPE_B)
temp |= SDVO_PIPE_B_SELECT;
}

intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE);
}
for (i = 0; i < 2; i++)
intel_wait_for_vblank(dev, intel_crtc->pipe);

Expand Down

0 comments on commit 776ca7c

Please sign in to comment.