diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2015-05-05 10:17:34 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-05-21 17:07:45 -0400 |
commit | 1612c8bd4cef20dd06e8622bb8ab9bbe9f90c0e5 (patch) | |
tree | c4bfdf1a397a069bcdc6ef4629cea4dd72065d93 /drivers/gpu/drm/i915/intel_hdmi.c | |
parent | e8504ee293f62b380b55b727d2da7aa429db8f8d (diff) |
drm/i915: Fix the IBX transcoder B workarounds
Currently the IBX transcoder B workarounds are not working correctly.
Well, the HDMI one seems to be working somewhat, but the DP one is
definitely busted.
After a bit of experimentation it looks like the best way to make this
work is first disable the port on transcoder B, and then re-enable it
transcoder A, and immediately disable it again.
We can also clean up the code by noting that we can't be called without
a valid crtc. And also note that port A on ILK does not need the
workaround, so let's check for that one too.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_hdmi.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 50 |
1 files changed, 23 insertions, 27 deletions
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index d148e09db901..fb2dc84e1061 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -873,41 +873,37 @@ static void intel_disable_hdmi(struct intel_encoder *encoder) | |||
873 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); | 873 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base); |
874 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); | 874 | struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); |
875 | u32 temp; | 875 | u32 temp; |
876 | u32 enable_bits = SDVO_ENABLE | SDVO_AUDIO_ENABLE; | ||
877 | 876 | ||
878 | if (crtc->config->has_audio) | 877 | if (crtc->config->has_audio) |
879 | intel_audio_codec_disable(encoder); | 878 | intel_audio_codec_disable(encoder); |
880 | 879 | ||
881 | temp = I915_READ(intel_hdmi->hdmi_reg); | 880 | temp = I915_READ(intel_hdmi->hdmi_reg); |
882 | 881 | ||
883 | /* HW workaround for IBX, we need to move the port to transcoder A | 882 | temp &= ~(SDVO_ENABLE | SDVO_AUDIO_ENABLE); |
884 | * before disabling it. */ | ||
885 | if (HAS_PCH_IBX(dev)) { | ||
886 | struct drm_crtc *crtc = encoder->base.crtc; | ||
887 | int pipe = crtc ? to_intel_crtc(crtc)->pipe : -1; | ||
888 | |||
889 | if (temp & SDVO_PIPE_B_SELECT) { | ||
890 | temp &= ~SDVO_PIPE_B_SELECT; | ||
891 | I915_WRITE(intel_hdmi->hdmi_reg, temp); | ||
892 | POSTING_READ(intel_hdmi->hdmi_reg); | ||
893 | |||
894 | /* Again we need to write this twice. */ | ||
895 | I915_WRITE(intel_hdmi->hdmi_reg, temp); | ||
896 | POSTING_READ(intel_hdmi->hdmi_reg); | ||
897 | |||
898 | /* Transcoder selection bits only update | ||
899 | * effectively on vblank. */ | ||
900 | if (crtc) | ||
901 | intel_wait_for_vblank(dev, pipe); | ||
902 | else | ||
903 | msleep(50); | ||
904 | } | ||
905 | } | ||
906 | |||
907 | temp &= ~enable_bits; | ||
908 | |||
909 | I915_WRITE(intel_hdmi->hdmi_reg, temp); | 883 | I915_WRITE(intel_hdmi->hdmi_reg, temp); |
910 | POSTING_READ(intel_hdmi->hdmi_reg); | 884 | POSTING_READ(intel_hdmi->hdmi_reg); |
885 | |||
886 | /* | ||
887 | * HW workaround for IBX, we need to move the port | ||
888 | * to transcoder A after disabling it to allow the | ||
889 | * matching DP port to be enabled on transcoder A. | ||
890 | */ | ||
891 | if (HAS_PCH_IBX(dev) && crtc->pipe == PIPE_B) { | ||
892 | temp &= ~SDVO_PIPE_B_SELECT; | ||
893 | temp |= SDVO_ENABLE; | ||
894 | /* | ||
895 | * HW workaround, need to write this twice for issue | ||
896 | * that may result in first write getting masked. | ||
897 | */ | ||
898 | I915_WRITE(intel_hdmi->hdmi_reg, temp); | ||
899 | POSTING_READ(intel_hdmi->hdmi_reg); | ||
900 | I915_WRITE(intel_hdmi->hdmi_reg, temp); | ||
901 | POSTING_READ(intel_hdmi->hdmi_reg); | ||
902 | |||
903 | temp &= ~SDVO_ENABLE; | ||
904 | I915_WRITE(intel_hdmi->hdmi_reg, temp); | ||
905 | POSTING_READ(intel_hdmi->hdmi_reg); | ||
906 | } | ||
911 | } | 907 | } |
912 | 908 | ||
913 | static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit) | 909 | static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit) |