diff options
author | Paulo Zanoni <paulo.r.zanoni@intel.com> | 2012-05-14 16:12:51 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-05-20 11:52:35 -0400 |
commit | 2da8af54059bd8c0d7bdf1f56b39cbec7f9c6f05 (patch) | |
tree | 1e5d38013cc33739788576eb27ddde114c5557be /drivers/gpu/drm/i915/intel_hdmi.c | |
parent | ed517fbbbd3a01692a667ac18b4a413695513428 (diff) |
drm/i915: implement hsw_write_infoframe
Both the control and data registers are completely different now.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
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 | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index cd5d9a9bdedc..2ead3bf7c21d 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -89,6 +89,32 @@ static u32 g4x_infoframe_enable(struct dip_infoframe *frame) | |||
89 | } | 89 | } |
90 | } | 90 | } |
91 | 91 | ||
92 | static u32 hsw_infoframe_enable(struct dip_infoframe *frame) | ||
93 | { | ||
94 | switch (frame->type) { | ||
95 | case DIP_TYPE_AVI: | ||
96 | return VIDEO_DIP_ENABLE_AVI_HSW; | ||
97 | case DIP_TYPE_SPD: | ||
98 | return VIDEO_DIP_ENABLE_SPD_HSW; | ||
99 | default: | ||
100 | DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); | ||
101 | return 0; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, enum pipe pipe) | ||
106 | { | ||
107 | switch (frame->type) { | ||
108 | case DIP_TYPE_AVI: | ||
109 | return HSW_TVIDEO_DIP_AVI_DATA(pipe); | ||
110 | case DIP_TYPE_SPD: | ||
111 | return HSW_TVIDEO_DIP_SPD_DATA(pipe); | ||
112 | default: | ||
113 | DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); | ||
114 | return 0; | ||
115 | } | ||
116 | } | ||
117 | |||
92 | static void g4x_write_infoframe(struct drm_encoder *encoder, | 118 | static void g4x_write_infoframe(struct drm_encoder *encoder, |
93 | struct dip_infoframe *frame) | 119 | struct dip_infoframe *frame) |
94 | { | 120 | { |
@@ -251,13 +277,30 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, | |||
251 | static void hsw_write_infoframe(struct drm_encoder *encoder, | 277 | static void hsw_write_infoframe(struct drm_encoder *encoder, |
252 | struct dip_infoframe *frame) | 278 | struct dip_infoframe *frame) |
253 | { | 279 | { |
254 | /* Not implemented yet, so avoid doing anything at all. | 280 | uint32_t *data = (uint32_t *)frame; |
255 | * This is the placeholder for Paulo Zanoni's infoframe writing patch | 281 | struct drm_device *dev = encoder->dev; |
256 | */ | 282 | struct drm_i915_private *dev_priv = dev->dev_private; |
257 | DRM_DEBUG_DRIVER("Attempting to write infoframe on Haswell, this is not implemented yet.\n"); | 283 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
284 | u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->pipe); | ||
285 | u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->pipe); | ||
286 | unsigned int i, len = DIP_HEADER_SIZE + frame->len; | ||
287 | u32 val = I915_READ(ctl_reg); | ||
258 | 288 | ||
259 | return; | 289 | if (data_reg == 0) |
290 | return; | ||
291 | |||
292 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
293 | |||
294 | val &= ~hsw_infoframe_enable(frame); | ||
295 | I915_WRITE(ctl_reg, val); | ||
296 | |||
297 | for (i = 0; i < len; i += 4) { | ||
298 | I915_WRITE(data_reg + i, *data); | ||
299 | data++; | ||
300 | } | ||
260 | 301 | ||
302 | val |= hsw_infoframe_enable(frame); | ||
303 | I915_WRITE(ctl_reg, val); | ||
261 | } | 304 | } |
262 | 305 | ||
263 | static void intel_set_infoframe(struct drm_encoder *encoder, | 306 | static void intel_set_infoframe(struct drm_encoder *encoder, |