drm/i915: Enable HDMI on ValleyView
authorShobhit Kumar <shobhit.kumar@intel.com>
Wed, 28 Mar 2012 20:39:32 +0000 (13:39 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 28 Mar 2012 22:00:09 +0000 (00:00 +0200)
HDMI register offsets are different in Valleyview. Add support for the
same.

v2: drop superfluous comments in HDMI init (Daniel)

Signed-off-by: Beeresh G <beeresh.g@intel.com>
Signed-off-by: Shobhit Kumar <shobhit.kumar@intel.com>
Reviewed-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com>
Reviewed-by: Jesse Barnes <jesse.barnes@intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_hdmi.c

index 2f6576d..841d0d1 100644 (file)
 #define TVIDEO_DIP_DATA(pipe) _PIPE(pipe, _VIDEO_DIP_DATA_A, _VIDEO_DIP_DATA_B)
 #define TVIDEO_DIP_GCP(pipe) _PIPE(pipe, _VIDEO_DIP_GCP_A, _VIDEO_DIP_GCP_B)
 
+#define VLV_VIDEO_DIP_CTL_A            0x60220
+#define VLV_VIDEO_DIP_DATA_A           0x60208
+#define VLV_VIDEO_DIP_GDCP_PAYLOAD_A   0x60210
+
+#define VLV_VIDEO_DIP_CTL_B            0x61170
+#define VLV_VIDEO_DIP_DATA_B           0x61174
+#define VLV_VIDEO_DIP_GDCP_PAYLOAD_B   0x61178
+
+#define VLV_TVIDEO_DIP_CTL(pipe) \
+        _PIPE(pipe, VLV_VIDEO_DIP_CTL_A, VLV_VIDEO_DIP_CTL_B)
+#define VLV_TVIDEO_DIP_DATA(pipe) \
+        _PIPE(pipe, VLV_VIDEO_DIP_DATA_A, VLV_VIDEO_DIP_DATA_B)
+#define VLV_TVIDEO_DIP_GCP(pipe) \
+       _PIPE(pipe, VLV_VIDEO_DIP_GDCP_PAYLOAD_A, VLV_VIDEO_DIP_GDCP_PAYLOAD_B)
+
 #define _TRANS_HTOTAL_B          0xe1000
 #define _TRANS_HBLANK_B          0xe1004
 #define _TRANS_HSYNC_B           0xe1008
 #define  ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16)
 
 /* or SDVOB */
+#define VLV_HDMIB 0x61140
 #define HDMIB   0xe1140
 #define  PORT_ENABLE    (1 << 31)
 #define  TRANSCODER(pipe)       ((pipe) << 30)
index 1d00f61..7de2d3b 100644 (file)
@@ -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);