aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2011-09-22 01:46:00 -0400
committerKeith Packard <keithp@keithp.com>2011-10-21 02:22:02 -0400
commit64a8fc0145a1d0fdc25fc9367c2e6c621955fb3b (patch)
tree4493ede40ed91d9e2835078f4d6397f65adcce68
parenta60f0e38d72a5e24085d6e7e27a4cadc20ae268a (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.c18
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