| From de4eccc5978c9b1d3173011e7bb6754ad7ddc9ca Mon Sep 17 00:00:00 2001 |
| From: Damien Lespiau <damien.lespiau@intel.com> |
| Date: Tue, 6 Aug 2013 20:32:18 +0100 |
| Subject: drm/i915/hdmi: Change the write_infoframe vfunc to take a buffer and |
| a type |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| First step in the move to the shared infoframe infrastructure, let's |
| move the different infoframe helpers and the write_infoframe() vfunc to |
| a type (enum hdmi_infoframe_type) and a buffer + len instead of using |
| our struct dip_infoframe. |
| |
| v2: constify the infoframe pointer and don't mix signs (Ville Syrjälä) |
| |
| Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> |
| Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com> |
| Signed-off-by: Thierry Reding <thierry.reding at avionic-design.de> |
| Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| (cherry picked from commit 178f736ab96637bc17bcf00c3b58af0137e880e0) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/i915/intel_drv.h | 4 +- |
| drivers/gpu/drm/i915/intel_hdmi.c | 106 ++++++++++++++++++++------------------ |
| 2 files changed, 59 insertions(+), 51 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h |
| index 54e389de9f42..712e29e27c14 100644 |
| --- a/drivers/gpu/drm/i915/intel_drv.h |
| +++ b/drivers/gpu/drm/i915/intel_drv.h |
| @@ -26,6 +26,7 @@ |
| #define __INTEL_DRV_H__ |
| |
| #include <linux/i2c.h> |
| +#include <linux/hdmi.h> |
| #include <drm/i915_drm.h> |
| #include "i915_drv.h" |
| #include <drm/drm_crtc.h> |
| @@ -464,7 +465,8 @@ struct intel_hdmi { |
| enum hdmi_force_audio force_audio; |
| bool rgb_quant_range_selectable; |
| void (*write_infoframe)(struct drm_encoder *encoder, |
| - struct dip_infoframe *frame); |
| + enum hdmi_infoframe_type type, |
| + const uint8_t *frame, ssize_t len); |
| void (*set_infoframes)(struct drm_encoder *encoder, |
| struct drm_display_mode *adjusted_mode); |
| }; |
| diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c |
| index 0b3750f11a97..594c103136c4 100644 |
| --- a/drivers/gpu/drm/i915/intel_hdmi.c |
| +++ b/drivers/gpu/drm/i915/intel_hdmi.c |
| @@ -29,6 +29,7 @@ |
| #include <linux/i2c.h> |
| #include <linux/slab.h> |
| #include <linux/delay.h> |
| +#include <linux/hdmi.h> |
| #include <drm/drmP.h> |
| #include <drm/drm_crtc.h> |
| #include <drm/drm_edid.h> |
| @@ -81,74 +82,75 @@ void intel_dip_infoframe_csum(struct dip_infoframe *frame) |
| frame->checksum = 0x100 - sum; |
| } |
| |
| -static u32 g4x_infoframe_index(struct dip_infoframe *frame) |
| +static u32 g4x_infoframe_index(enum hdmi_infoframe_type type) |
| { |
| - switch (frame->type) { |
| - case DIP_TYPE_AVI: |
| + switch (type) { |
| + case HDMI_INFOFRAME_TYPE_AVI: |
| return VIDEO_DIP_SELECT_AVI; |
| - case DIP_TYPE_SPD: |
| + case HDMI_INFOFRAME_TYPE_SPD: |
| return VIDEO_DIP_SELECT_SPD; |
| default: |
| - DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); |
| + DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); |
| return 0; |
| } |
| } |
| |
| -static u32 g4x_infoframe_enable(struct dip_infoframe *frame) |
| +static u32 g4x_infoframe_enable(enum hdmi_infoframe_type type) |
| { |
| - switch (frame->type) { |
| - case DIP_TYPE_AVI: |
| + switch (type) { |
| + case HDMI_INFOFRAME_TYPE_AVI: |
| return VIDEO_DIP_ENABLE_AVI; |
| - case DIP_TYPE_SPD: |
| + case HDMI_INFOFRAME_TYPE_SPD: |
| return VIDEO_DIP_ENABLE_SPD; |
| default: |
| - DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); |
| + DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); |
| return 0; |
| } |
| } |
| |
| -static u32 hsw_infoframe_enable(struct dip_infoframe *frame) |
| +static u32 hsw_infoframe_enable(enum hdmi_infoframe_type type) |
| { |
| - switch (frame->type) { |
| - case DIP_TYPE_AVI: |
| + switch (type) { |
| + case HDMI_INFOFRAME_TYPE_AVI: |
| return VIDEO_DIP_ENABLE_AVI_HSW; |
| - case DIP_TYPE_SPD: |
| + case HDMI_INFOFRAME_TYPE_SPD: |
| return VIDEO_DIP_ENABLE_SPD_HSW; |
| default: |
| - DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); |
| + DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); |
| return 0; |
| } |
| } |
| |
| -static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, |
| +static u32 hsw_infoframe_data_reg(enum hdmi_infoframe_type type, |
| enum transcoder cpu_transcoder) |
| { |
| - switch (frame->type) { |
| - case DIP_TYPE_AVI: |
| + switch (type) { |
| + case HDMI_INFOFRAME_TYPE_AVI: |
| return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder); |
| - case DIP_TYPE_SPD: |
| + case HDMI_INFOFRAME_TYPE_SPD: |
| return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder); |
| default: |
| - DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); |
| + DRM_DEBUG_DRIVER("unknown info frame type %d\n", type); |
| return 0; |
| } |
| } |
| |
| static void g4x_write_infoframe(struct drm_encoder *encoder, |
| - struct dip_infoframe *frame) |
| + 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; |
| u32 val = I915_READ(VIDEO_DIP_CTL); |
| - unsigned i, len = DIP_HEADER_SIZE + frame->len; |
| + int i; |
| |
| 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_index(type); |
| |
| - val &= ~g4x_infoframe_enable(frame); |
| + val &= ~g4x_infoframe_enable(type); |
| |
| I915_WRITE(VIDEO_DIP_CTL, val); |
| |
| @@ -162,7 +164,7 @@ static void g4x_write_infoframe(struct drm_encoder *encoder, |
| I915_WRITE(VIDEO_DIP_DATA, 0); |
| mmiowb(); |
| |
| - val |= g4x_infoframe_enable(frame); |
| + val |= g4x_infoframe_enable(type); |
| val &= ~VIDEO_DIP_FREQ_MASK; |
| val |= VIDEO_DIP_FREQ_VSYNC; |
| |
| @@ -171,22 +173,22 @@ static void g4x_write_infoframe(struct drm_encoder *encoder, |
| } |
| |
| static void ibx_write_infoframe(struct drm_encoder *encoder, |
| - struct dip_infoframe *frame) |
| + 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 reg = TVIDEO_DIP_CTL(intel_crtc->pipe); |
| - unsigned i, len = DIP_HEADER_SIZE + frame->len; |
| + 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(frame); |
| + val |= g4x_infoframe_index(type); |
| |
| - val &= ~g4x_infoframe_enable(frame); |
| + val &= ~g4x_infoframe_enable(type); |
| |
| I915_WRITE(reg, val); |
| |
| @@ -200,7 +202,7 @@ static void ibx_write_infoframe(struct drm_encoder *encoder, |
| I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); |
| mmiowb(); |
| |
| - val |= g4x_infoframe_enable(frame); |
| + val |= g4x_infoframe_enable(type); |
| val &= ~VIDEO_DIP_FREQ_MASK; |
| val |= VIDEO_DIP_FREQ_VSYNC; |
| |
| @@ -209,25 +211,25 @@ static void ibx_write_infoframe(struct drm_encoder *encoder, |
| } |
| |
| static void cpt_write_infoframe(struct drm_encoder *encoder, |
| - struct dip_infoframe *frame) |
| + 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 reg = TVIDEO_DIP_CTL(intel_crtc->pipe); |
| - unsigned i, len = DIP_HEADER_SIZE + frame->len; |
| + 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(frame); |
| + 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 (frame->type != DIP_TYPE_AVI) |
| - val &= ~g4x_infoframe_enable(frame); |
| + if (type != HDMI_INFOFRAME_TYPE_AVI) |
| + val &= ~g4x_infoframe_enable(type); |
| |
| I915_WRITE(reg, val); |
| |
| @@ -241,7 +243,7 @@ static void cpt_write_infoframe(struct drm_encoder *encoder, |
| I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); |
| mmiowb(); |
| |
| - val |= g4x_infoframe_enable(frame); |
| + val |= g4x_infoframe_enable(type); |
| val &= ~VIDEO_DIP_FREQ_MASK; |
| val |= VIDEO_DIP_FREQ_VSYNC; |
| |
| @@ -250,22 +252,22 @@ static void cpt_write_infoframe(struct drm_encoder *encoder, |
| } |
| |
| static void vlv_write_infoframe(struct drm_encoder *encoder, |
| - struct dip_infoframe *frame) |
| + 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 reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); |
| - unsigned i, len = DIP_HEADER_SIZE + frame->len; |
| + int i, reg = VLV_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(frame); |
| + val |= g4x_infoframe_index(type); |
| |
| - val &= ~g4x_infoframe_enable(frame); |
| + val &= ~g4x_infoframe_enable(type); |
| |
| I915_WRITE(reg, val); |
| |
| @@ -279,7 +281,7 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, |
| I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0); |
| mmiowb(); |
| |
| - val |= g4x_infoframe_enable(frame); |
| + val |= g4x_infoframe_enable(type); |
| val &= ~VIDEO_DIP_FREQ_MASK; |
| val |= VIDEO_DIP_FREQ_VSYNC; |
| |
| @@ -288,21 +290,24 @@ static void vlv_write_infoframe(struct drm_encoder *encoder, |
| } |
| |
| static void hsw_write_infoframe(struct drm_encoder *encoder, |
| - struct dip_infoframe *frame) |
| + 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); |
| u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder); |
| - u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->config.cpu_transcoder); |
| - unsigned int i, len = DIP_HEADER_SIZE + frame->len; |
| + u32 data_reg; |
| + int i; |
| u32 val = I915_READ(ctl_reg); |
| |
| + data_reg = hsw_infoframe_data_reg(type, |
| + intel_crtc->config.cpu_transcoder); |
| if (data_reg == 0) |
| return; |
| |
| - val &= ~hsw_infoframe_enable(frame); |
| + val &= ~hsw_infoframe_enable(type); |
| I915_WRITE(ctl_reg, val); |
| |
| mmiowb(); |
| @@ -315,7 +320,7 @@ static void hsw_write_infoframe(struct drm_encoder *encoder, |
| I915_WRITE(data_reg + i, 0); |
| mmiowb(); |
| |
| - val |= hsw_infoframe_enable(frame); |
| + val |= hsw_infoframe_enable(type); |
| I915_WRITE(ctl_reg, val); |
| POSTING_READ(ctl_reg); |
| } |
| @@ -326,7 +331,8 @@ static void intel_set_infoframe(struct drm_encoder *encoder, |
| struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
| |
| intel_dip_infoframe_csum(frame); |
| - intel_hdmi->write_infoframe(encoder, frame); |
| + intel_hdmi->write_infoframe(encoder, frame->type, (uint8_t *)frame, |
| + DIP_HEADER_SIZE + frame->len); |
| } |
| |
| static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, |
| -- |
| 1.8.5.rc3 |
| |