|
@@ -177,6 +177,37 @@ static void ironlake_write_infoframe(struct drm_encoder *encoder,
|
|
|
|
|
|
I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags);
|
|
|
}
|
|
|
+
|
|
|
+static void vlv_write_infoframe(struct drm_encoder *encoder,
|
|
|
+ struct dip_infoframe *frame)
|
|
|
+{
|
|
|
+ uint32_t *data = (uint32_t *)frame;
|
|
|
+ struct drm_device *dev = encoder->dev;
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+ struct drm_crtc *crtc = encoder->crtc;
|
|
|
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
+ int reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
|
|
|
+ unsigned i, len = DIP_HEADER_SIZE + frame->len;
|
|
|
+ u32 flags, val = I915_READ(reg);
|
|
|
+
|
|
|
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
|
|
|
+
|
|
|
+ flags = intel_infoframe_index(frame);
|
|
|
+
|
|
|
+ val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
|
|
|
+
|
|
|
+ I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags);
|
|
|
+
|
|
|
+ for (i = 0; i < len; i += 4) {
|
|
|
+ I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), *data);
|
|
|
+ data++;
|
|
|
+ }
|
|
|
+
|
|
|
+ flags |= intel_infoframe_flags(frame);
|
|
|
+
|
|
|
+ I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags);
|
|
|
+}
|
|
|
+
|
|
|
static void intel_set_infoframe(struct drm_encoder *encoder,
|
|
|
struct dip_infoframe *frame)
|
|
|
{
|
|
@@ -552,7 +583,11 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
|
|
|
if (!HAS_PCH_SPLIT(dev)) {
|
|
|
intel_hdmi->write_infoframe = i9xx_write_infoframe;
|
|
|
I915_WRITE(VIDEO_DIP_CTL, 0);
|
|
|
- } else {
|
|
|
+ } else if (IS_VALLEYVIEW(dev)) {
|
|
|
+ intel_hdmi->write_infoframe = vlv_write_infoframe;
|
|
|
+ for_each_pipe(i)
|
|
|
+ I915_WRITE(VLV_TVIDEO_DIP_CTL(i), 0);
|
|
|
+ } else {
|
|
|
intel_hdmi->write_infoframe = ironlake_write_infoframe;
|
|
|
for_each_pipe(i)
|
|
|
I915_WRITE(TVIDEO_DIP_CTL(i), 0);
|