static void ibx_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 intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); unsigned i, len = DIP_HEADER_SIZE + frame->len; u32 val = I915_READ(reg); val &= ~VIDEO_DIP_PORT_MASK; switch (intel_hdmi->sdvox_reg) { case HDMIB: val |= VIDEO_DIP_PORT_B; break; case HDMIC: val |= VIDEO_DIP_PORT_C; break; case HDMID: val |= VIDEO_DIP_PORT_D; break; default: return; } intel_wait_for_vblank(dev, intel_crtc->pipe); val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ val |= g4x_infoframe_index(frame); val &= ~g4x_infoframe_enable(frame); val |= VIDEO_DIP_ENABLE; I915_WRITE(reg, val); mmiowb(); for (i = 0; i < len; i += 4) { I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); data++; } /* Write every possible data byte to force correct ECC calculation. */ for (; i < VIDEO_DIP_DATA_SIZE; i += 4) I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); mmiowb(); val |= g4x_infoframe_enable(frame); val &= ~VIDEO_DIP_FREQ_MASK; val |= VIDEO_DIP_FREQ_VSYNC; I915_WRITE(reg, val); POSTING_READ(reg); }
static void ibx_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 intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); unsigned i, len = DIP_HEADER_SIZE + frame->len; u32 val = I915_READ(reg); WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ val |= g4x_infoframe_index(frame); val &= ~g4x_infoframe_enable(frame); I915_WRITE(reg, val); mmiowb(); for (i = 0; i < len; i += 4) { I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); data++; } mmiowb(); val |= g4x_infoframe_enable(frame); val &= ~VIDEO_DIP_FREQ_MASK; val |= VIDEO_DIP_FREQ_VSYNC; I915_WRITE(reg, val); POSTING_READ(reg); }
static void cpt_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 intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); unsigned i, len = DIP_HEADER_SIZE + frame->len; u32 val = I915_READ(reg); intel_wait_for_vblank(dev, intel_crtc->pipe); val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ val |= g4x_infoframe_index(frame); /* The DIP control register spec says that we need to update the AVI * infoframe without clearing its enable bit */ if (frame->type == DIP_TYPE_AVI) val |= VIDEO_DIP_ENABLE_AVI; else val &= ~g4x_infoframe_enable(frame); val |= VIDEO_DIP_ENABLE; I915_WRITE(reg, val); mmiowb(); for (i = 0; i < len; i += 4) { I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); data++; } /* Write every possible data byte to force correct ECC calculation. */ for (; i < VIDEO_DIP_DATA_SIZE; i += 4) I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); mmiowb(); val |= g4x_infoframe_enable(frame); val &= ~VIDEO_DIP_FREQ_MASK; val |= VIDEO_DIP_FREQ_VSYNC; I915_WRITE(reg, val); POSTING_READ(reg); }
static void cpt_write_infoframe(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const void *frame, ssize_t len) { const uint32_t *data = frame; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); int i, reg = TVIDEO_DIP_CTL(intel_crtc->pipe); u32 val = I915_READ(reg); WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ val |= g4x_infoframe_index(type); /* The DIP control register spec says that we need to update the AVI * infoframe without clearing its enable bit */ if (type != HDMI_INFOFRAME_TYPE_AVI) val &= ~g4x_infoframe_enable(type); I915_WRITE(reg, val); mmiowb(); for (i = 0; i < len; i += 4) { I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); data++; } /* Write every possible data byte to force correct ECC calculation. */ for (; i < VIDEO_DIP_DATA_SIZE; i += 4) I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); mmiowb(); val |= g4x_infoframe_enable(type); val &= ~VIDEO_DIP_FREQ_MASK; val |= VIDEO_DIP_FREQ_VSYNC; I915_WRITE(reg, val); POSTING_READ(reg); }
static void ibx_write_infoframe(struct drm_encoder *encoder, enum hdmi_infoframe_type type, const uint8_t *frame, ssize_t len) { uint32_t *data = (uint32_t *)frame; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); int i, reg = TVIDEO_DIP_CTL(intel_crtc->pipe); u32 val = I915_READ(reg); WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ val |= g4x_infoframe_index(type); val &= ~g4x_infoframe_enable(type); I915_WRITE(reg, val); mmiowb(); for (i = 0; i < len; i += 4) { I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); data++; } /* Write every possible data byte to force correct ECC calculation. */ for (; i < VIDEO_DIP_DATA_SIZE; i += 4) I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); mmiowb(); val |= g4x_infoframe_enable(type); val &= ~VIDEO_DIP_FREQ_MASK; val |= VIDEO_DIP_FREQ_VSYNC; I915_WRITE(reg, val); POSTING_READ(reg); }