diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-09-22 01:46:00 -0400 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2011-10-21 02:22:02 -0400 |
commit | 64a8fc0145a1d0fdc25fc9367c2e6c621955fb3b (patch) | |
tree | 4493ede40ed91d9e2835078f4d6397f65adcce68 | |
parent | a60f0e38d72a5e24085d6e7e27a4cadc20ae268a (diff) |
drm/i915: fix ILK+ infoframe support
Misc fixes based on tests with an infoframe analyzer:
- checksum *does* include header bytes
- DIP enable & AVI infoframe are tied together in hw, so disable both
and make sure AVI frames are enabled first
- use every vsync flag for SPD frames to avoid reserved value in
frequency field when enabling both AVI & SPD
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=40281.
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Cc: stable@kernel.org
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index e7e716cb1c9..d4f5a0b2120 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -69,8 +69,7 @@ void intel_dip_infoframe_csum(struct dip_infoframe *frame) | |||
69 | frame->checksum = 0; | 69 | frame->checksum = 0; |
70 | frame->ecc = 0; | 70 | frame->ecc = 0; |
71 | 71 | ||
72 | /* Header isn't part of the checksum */ | 72 | for (i = 0; i < frame->len + DIP_HEADER_SIZE; i++) |
73 | for (i = 5; i < frame->len; i++) | ||
74 | sum += data[i]; | 73 | sum += data[i]; |
75 | 74 | ||
76 | frame->checksum = 0x100 - sum; | 75 | frame->checksum = 0x100 - sum; |
@@ -104,7 +103,7 @@ static u32 intel_infoframe_flags(struct dip_infoframe *frame) | |||
104 | flags |= VIDEO_DIP_ENABLE_AVI | VIDEO_DIP_FREQ_VSYNC; | 103 | flags |= VIDEO_DIP_ENABLE_AVI | VIDEO_DIP_FREQ_VSYNC; |
105 | break; | 104 | break; |
106 | case DIP_TYPE_SPD: | 105 | case DIP_TYPE_SPD: |
107 | flags |= VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_FREQ_2VSYNC; | 106 | flags |= VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_FREQ_VSYNC; |
108 | break; | 107 | break; |
109 | default: | 108 | default: |
110 | DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); | 109 | DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); |
@@ -165,9 +164,9 @@ static void ironlake_write_infoframe(struct drm_encoder *encoder, | |||
165 | 164 | ||
166 | flags = intel_infoframe_index(frame); | 165 | flags = intel_infoframe_index(frame); |
167 | 166 | ||
168 | val &= ~VIDEO_DIP_SELECT_MASK; | 167 | val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ |
169 | 168 | ||
170 | I915_WRITE(reg, val | flags); | 169 | I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags); |
171 | 170 | ||
172 | for (i = 0; i < len; i += 4) { | 171 | for (i = 0; i < len; i += 4) { |
173 | I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); | 172 | I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); |
@@ -487,6 +486,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
487 | struct intel_encoder *intel_encoder; | 486 | struct intel_encoder *intel_encoder; |
488 | struct intel_connector *intel_connector; | 487 | struct intel_connector *intel_connector; |
489 | struct intel_hdmi *intel_hdmi; | 488 | struct intel_hdmi *intel_hdmi; |
489 | int i; | ||
490 | 490 | ||
491 | intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); | 491 | intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); |
492 | if (!intel_hdmi) | 492 | if (!intel_hdmi) |
@@ -539,10 +539,14 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
539 | 539 | ||
540 | intel_hdmi->sdvox_reg = sdvox_reg; | 540 | intel_hdmi->sdvox_reg = sdvox_reg; |
541 | 541 | ||
542 | if (!HAS_PCH_SPLIT(dev)) | 542 | if (!HAS_PCH_SPLIT(dev)) { |
543 | intel_hdmi->write_infoframe = i9xx_write_infoframe; | 543 | intel_hdmi->write_infoframe = i9xx_write_infoframe; |
544 | else | 544 | I915_WRITE(VIDEO_DIP_CTL, 0); |
545 | } else { | ||
545 | intel_hdmi->write_infoframe = ironlake_write_infoframe; | 546 | intel_hdmi->write_infoframe = ironlake_write_infoframe; |
547 | for_each_pipe(i) | ||
548 | I915_WRITE(TVIDEO_DIP_CTL(i), 0); | ||
549 | } | ||
546 | 550 | ||
547 | drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); | 551 | drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); |
548 | 552 | ||