aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Lespiau <damien.lespiau@intel.com>2013-08-06 15:32:18 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-08-08 08:04:47 -0400
commit178f736ab96637bc17bcf00c3b58af0137e880e0 (patch)
treeb41efc62c4315d1705cf46dfbd2c57f974cbad1c
parent03a7a189c22bf911025c695841c18a681498a102 (diff)
drm/i915/hdmi: Change the write_infoframe vfunc to take a buffer and a type
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>
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h4
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c106
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 @@
26#define __INTEL_DRV_H__ 26#define __INTEL_DRV_H__
27 27
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/hdmi.h>
29#include <drm/i915_drm.h> 30#include <drm/i915_drm.h>
30#include "i915_drv.h" 31#include "i915_drv.h"
31#include <drm/drm_crtc.h> 32#include <drm/drm_crtc.h>
@@ -464,7 +465,8 @@ struct intel_hdmi {
464 enum hdmi_force_audio force_audio; 465 enum hdmi_force_audio force_audio;
465 bool rgb_quant_range_selectable; 466 bool rgb_quant_range_selectable;
466 void (*write_infoframe)(struct drm_encoder *encoder, 467 void (*write_infoframe)(struct drm_encoder *encoder,
467 struct dip_infoframe *frame); 468 enum hdmi_infoframe_type type,
469 const uint8_t *frame, ssize_t len);
468 void (*set_infoframes)(struct drm_encoder *encoder, 470 void (*set_infoframes)(struct drm_encoder *encoder,
469 struct drm_display_mode *adjusted_mode); 471 struct drm_display_mode *adjusted_mode);
470}; 472};
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 5cad59fd6bd2..951f4817e1b6 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -29,6 +29,7 @@
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/hdmi.h>
32#include <drm/drmP.h> 33#include <drm/drmP.h>
33#include <drm/drm_crtc.h> 34#include <drm/drm_crtc.h>
34#include <drm/drm_edid.h> 35#include <drm/drm_edid.h>
@@ -81,74 +82,75 @@ void intel_dip_infoframe_csum(struct dip_infoframe *frame)
81 frame->checksum = 0x100 - sum; 82 frame->checksum = 0x100 - sum;
82} 83}
83 84
84static u32 g4x_infoframe_index(struct dip_infoframe *frame) 85static u32 g4x_infoframe_index(enum hdmi_infoframe_type type)
85{ 86{
86 switch (frame->type) { 87 switch (type) {
87 case DIP_TYPE_AVI: 88 case HDMI_INFOFRAME_TYPE_AVI:
88 return VIDEO_DIP_SELECT_AVI; 89 return VIDEO_DIP_SELECT_AVI;
89 case DIP_TYPE_SPD: 90 case HDMI_INFOFRAME_TYPE_SPD:
90 return VIDEO_DIP_SELECT_SPD; 91 return VIDEO_DIP_SELECT_SPD;
91 default: 92 default:
92 DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); 93 DRM_DEBUG_DRIVER("unknown info frame type %d\n", type);
93 return 0; 94 return 0;
94 } 95 }
95} 96}
96 97
97static u32 g4x_infoframe_enable(struct dip_infoframe *frame) 98static u32 g4x_infoframe_enable(enum hdmi_infoframe_type type)
98{ 99{
99 switch (frame->type) { 100 switch (type) {
100 case DIP_TYPE_AVI: 101 case HDMI_INFOFRAME_TYPE_AVI:
101 return VIDEO_DIP_ENABLE_AVI; 102 return VIDEO_DIP_ENABLE_AVI;
102 case DIP_TYPE_SPD: 103 case HDMI_INFOFRAME_TYPE_SPD:
103 return VIDEO_DIP_ENABLE_SPD; 104 return VIDEO_DIP_ENABLE_SPD;
104 default: 105 default:
105 DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); 106 DRM_DEBUG_DRIVER("unknown info frame type %d\n", type);
106 return 0; 107 return 0;
107 } 108 }
108} 109}
109 110
110static u32 hsw_infoframe_enable(struct dip_infoframe *frame) 111static u32 hsw_infoframe_enable(enum hdmi_infoframe_type type)
111{ 112{
112 switch (frame->type) { 113 switch (type) {
113 case DIP_TYPE_AVI: 114 case HDMI_INFOFRAME_TYPE_AVI:
114 return VIDEO_DIP_ENABLE_AVI_HSW; 115 return VIDEO_DIP_ENABLE_AVI_HSW;
115 case DIP_TYPE_SPD: 116 case HDMI_INFOFRAME_TYPE_SPD:
116 return VIDEO_DIP_ENABLE_SPD_HSW; 117 return VIDEO_DIP_ENABLE_SPD_HSW;
117 default: 118 default:
118 DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); 119 DRM_DEBUG_DRIVER("unknown info frame type %d\n", type);
119 return 0; 120 return 0;
120 } 121 }
121} 122}
122 123
123static u32 hsw_infoframe_data_reg(struct dip_infoframe *frame, 124static u32 hsw_infoframe_data_reg(enum hdmi_infoframe_type type,
124 enum transcoder cpu_transcoder) 125 enum transcoder cpu_transcoder)
125{ 126{
126 switch (frame->type) { 127 switch (type) {
127 case DIP_TYPE_AVI: 128 case HDMI_INFOFRAME_TYPE_AVI:
128 return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder); 129 return HSW_TVIDEO_DIP_AVI_DATA(cpu_transcoder);
129 case DIP_TYPE_SPD: 130 case HDMI_INFOFRAME_TYPE_SPD:
130 return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder); 131 return HSW_TVIDEO_DIP_SPD_DATA(cpu_transcoder);
131 default: 132 default:
132 DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); 133 DRM_DEBUG_DRIVER("unknown info frame type %d\n", type);
133 return 0; 134 return 0;
134 } 135 }
135} 136}
136 137
137static void g4x_write_infoframe(struct drm_encoder *encoder, 138static void g4x_write_infoframe(struct drm_encoder *encoder,
138 struct dip_infoframe *frame) 139 enum hdmi_infoframe_type type,
140 const uint8_t *frame, ssize_t len)
139{ 141{
140 uint32_t *data = (uint32_t *)frame; 142 uint32_t *data = (uint32_t *)frame;
141 struct drm_device *dev = encoder->dev; 143 struct drm_device *dev = encoder->dev;
142 struct drm_i915_private *dev_priv = dev->dev_private; 144 struct drm_i915_private *dev_priv = dev->dev_private;
143 u32 val = I915_READ(VIDEO_DIP_CTL); 145 u32 val = I915_READ(VIDEO_DIP_CTL);
144 unsigned i, len = DIP_HEADER_SIZE + frame->len; 146 int i;
145 147
146 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); 148 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
147 149
148 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ 150 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
149 val |= g4x_infoframe_index(frame); 151 val |= g4x_infoframe_index(type);
150 152
151 val &= ~g4x_infoframe_enable(frame); 153 val &= ~g4x_infoframe_enable(type);
152 154
153 I915_WRITE(VIDEO_DIP_CTL, val); 155 I915_WRITE(VIDEO_DIP_CTL, val);
154 156
@@ -162,7 +164,7 @@ static void g4x_write_infoframe(struct drm_encoder *encoder,
162 I915_WRITE(VIDEO_DIP_DATA, 0); 164 I915_WRITE(VIDEO_DIP_DATA, 0);
163 mmiowb(); 165 mmiowb();
164 166
165 val |= g4x_infoframe_enable(frame); 167 val |= g4x_infoframe_enable(type);
166 val &= ~VIDEO_DIP_FREQ_MASK; 168 val &= ~VIDEO_DIP_FREQ_MASK;
167 val |= VIDEO_DIP_FREQ_VSYNC; 169 val |= VIDEO_DIP_FREQ_VSYNC;
168 170
@@ -171,22 +173,22 @@ static void g4x_write_infoframe(struct drm_encoder *encoder,
171} 173}
172 174
173static void ibx_write_infoframe(struct drm_encoder *encoder, 175static void ibx_write_infoframe(struct drm_encoder *encoder,
174 struct dip_infoframe *frame) 176 enum hdmi_infoframe_type type,
177 const uint8_t *frame, ssize_t len)
175{ 178{
176 uint32_t *data = (uint32_t *)frame; 179 uint32_t *data = (uint32_t *)frame;
177 struct drm_device *dev = encoder->dev; 180 struct drm_device *dev = encoder->dev;
178 struct drm_i915_private *dev_priv = dev->dev_private; 181 struct drm_i915_private *dev_priv = dev->dev_private;
179 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); 182 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
180 int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); 183 int i, reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
181 unsigned i, len = DIP_HEADER_SIZE + frame->len;
182 u32 val = I915_READ(reg); 184 u32 val = I915_READ(reg);
183 185
184 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); 186 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
185 187
186 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ 188 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
187 val |= g4x_infoframe_index(frame); 189 val |= g4x_infoframe_index(type);
188 190
189 val &= ~g4x_infoframe_enable(frame); 191 val &= ~g4x_infoframe_enable(type);
190 192
191 I915_WRITE(reg, val); 193 I915_WRITE(reg, val);
192 194
@@ -200,7 +202,7 @@ static void ibx_write_infoframe(struct drm_encoder *encoder,
200 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); 202 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
201 mmiowb(); 203 mmiowb();
202 204
203 val |= g4x_infoframe_enable(frame); 205 val |= g4x_infoframe_enable(type);
204 val &= ~VIDEO_DIP_FREQ_MASK; 206 val &= ~VIDEO_DIP_FREQ_MASK;
205 val |= VIDEO_DIP_FREQ_VSYNC; 207 val |= VIDEO_DIP_FREQ_VSYNC;
206 208
@@ -209,25 +211,25 @@ static void ibx_write_infoframe(struct drm_encoder *encoder,
209} 211}
210 212
211static void cpt_write_infoframe(struct drm_encoder *encoder, 213static void cpt_write_infoframe(struct drm_encoder *encoder,
212 struct dip_infoframe *frame) 214 enum hdmi_infoframe_type type,
215 const uint8_t *frame, ssize_t len)
213{ 216{
214 uint32_t *data = (uint32_t *)frame; 217 uint32_t *data = (uint32_t *)frame;
215 struct drm_device *dev = encoder->dev; 218 struct drm_device *dev = encoder->dev;
216 struct drm_i915_private *dev_priv = dev->dev_private; 219 struct drm_i915_private *dev_priv = dev->dev_private;
217 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); 220 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
218 int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); 221 int i, reg = TVIDEO_DIP_CTL(intel_crtc->pipe);
219 unsigned i, len = DIP_HEADER_SIZE + frame->len;
220 u32 val = I915_READ(reg); 222 u32 val = I915_READ(reg);
221 223
222 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); 224 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
223 225
224 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ 226 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
225 val |= g4x_infoframe_index(frame); 227 val |= g4x_infoframe_index(type);
226 228
227 /* The DIP control register spec says that we need to update the AVI 229 /* The DIP control register spec says that we need to update the AVI
228 * infoframe without clearing its enable bit */ 230 * infoframe without clearing its enable bit */
229 if (frame->type != DIP_TYPE_AVI) 231 if (type != HDMI_INFOFRAME_TYPE_AVI)
230 val &= ~g4x_infoframe_enable(frame); 232 val &= ~g4x_infoframe_enable(type);
231 233
232 I915_WRITE(reg, val); 234 I915_WRITE(reg, val);
233 235
@@ -241,7 +243,7 @@ static void cpt_write_infoframe(struct drm_encoder *encoder,
241 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0); 243 I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
242 mmiowb(); 244 mmiowb();
243 245
244 val |= g4x_infoframe_enable(frame); 246 val |= g4x_infoframe_enable(type);
245 val &= ~VIDEO_DIP_FREQ_MASK; 247 val &= ~VIDEO_DIP_FREQ_MASK;
246 val |= VIDEO_DIP_FREQ_VSYNC; 248 val |= VIDEO_DIP_FREQ_VSYNC;
247 249
@@ -250,22 +252,22 @@ static void cpt_write_infoframe(struct drm_encoder *encoder,
250} 252}
251 253
252static void vlv_write_infoframe(struct drm_encoder *encoder, 254static void vlv_write_infoframe(struct drm_encoder *encoder,
253 struct dip_infoframe *frame) 255 enum hdmi_infoframe_type type,
256 const uint8_t *frame, ssize_t len)
254{ 257{
255 uint32_t *data = (uint32_t *)frame; 258 uint32_t *data = (uint32_t *)frame;
256 struct drm_device *dev = encoder->dev; 259 struct drm_device *dev = encoder->dev;
257 struct drm_i915_private *dev_priv = dev->dev_private; 260 struct drm_i915_private *dev_priv = dev->dev_private;
258 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); 261 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
259 int reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe); 262 int i, reg = VLV_TVIDEO_DIP_CTL(intel_crtc->pipe);
260 unsigned i, len = DIP_HEADER_SIZE + frame->len;
261 u32 val = I915_READ(reg); 263 u32 val = I915_READ(reg);
262 264
263 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n"); 265 WARN(!(val & VIDEO_DIP_ENABLE), "Writing DIP with CTL reg disabled\n");
264 266
265 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */ 267 val &= ~(VIDEO_DIP_SELECT_MASK | 0xf); /* clear DIP data offset */
266 val |= g4x_infoframe_index(frame); 268 val |= g4x_infoframe_index(type);
267 269
268 val &= ~g4x_infoframe_enable(frame); 270 val &= ~g4x_infoframe_enable(type);
269 271
270 I915_WRITE(reg, val); 272 I915_WRITE(reg, val);
271 273
@@ -279,7 +281,7 @@ static void vlv_write_infoframe(struct drm_encoder *encoder,
279 I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0); 281 I915_WRITE(VLV_TVIDEO_DIP_DATA(intel_crtc->pipe), 0);
280 mmiowb(); 282 mmiowb();
281 283
282 val |= g4x_infoframe_enable(frame); 284 val |= g4x_infoframe_enable(type);
283 val &= ~VIDEO_DIP_FREQ_MASK; 285 val &= ~VIDEO_DIP_FREQ_MASK;
284 val |= VIDEO_DIP_FREQ_VSYNC; 286 val |= VIDEO_DIP_FREQ_VSYNC;
285 287
@@ -288,21 +290,24 @@ static void vlv_write_infoframe(struct drm_encoder *encoder,
288} 290}
289 291
290static void hsw_write_infoframe(struct drm_encoder *encoder, 292static void hsw_write_infoframe(struct drm_encoder *encoder,
291 struct dip_infoframe *frame) 293 enum hdmi_infoframe_type type,
294 const uint8_t *frame, ssize_t len)
292{ 295{
293 uint32_t *data = (uint32_t *)frame; 296 uint32_t *data = (uint32_t *)frame;
294 struct drm_device *dev = encoder->dev; 297 struct drm_device *dev = encoder->dev;
295 struct drm_i915_private *dev_priv = dev->dev_private; 298 struct drm_i915_private *dev_priv = dev->dev_private;
296 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); 299 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
297 u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder); 300 u32 ctl_reg = HSW_TVIDEO_DIP_CTL(intel_crtc->config.cpu_transcoder);
298 u32 data_reg = hsw_infoframe_data_reg(frame, intel_crtc->config.cpu_transcoder); 301 u32 data_reg;
299 unsigned int i, len = DIP_HEADER_SIZE + frame->len; 302 int i;
300 u32 val = I915_READ(ctl_reg); 303 u32 val = I915_READ(ctl_reg);
301 304
305 data_reg = hsw_infoframe_data_reg(type,
306 intel_crtc->config.cpu_transcoder);
302 if (data_reg == 0) 307 if (data_reg == 0)
303 return; 308 return;
304 309
305 val &= ~hsw_infoframe_enable(frame); 310 val &= ~hsw_infoframe_enable(type);
306 I915_WRITE(ctl_reg, val); 311 I915_WRITE(ctl_reg, val);
307 312
308 mmiowb(); 313 mmiowb();
@@ -315,7 +320,7 @@ static void hsw_write_infoframe(struct drm_encoder *encoder,
315 I915_WRITE(data_reg + i, 0); 320 I915_WRITE(data_reg + i, 0);
316 mmiowb(); 321 mmiowb();
317 322
318 val |= hsw_infoframe_enable(frame); 323 val |= hsw_infoframe_enable(type);
319 I915_WRITE(ctl_reg, val); 324 I915_WRITE(ctl_reg, val);
320 POSTING_READ(ctl_reg); 325 POSTING_READ(ctl_reg);
321} 326}
@@ -326,7 +331,8 @@ static void intel_set_infoframe(struct drm_encoder *encoder,
326 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); 331 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
327 332
328 intel_dip_infoframe_csum(frame); 333 intel_dip_infoframe_csum(frame);
329 intel_hdmi->write_infoframe(encoder, frame); 334 intel_hdmi->write_infoframe(encoder, frame->type, (uint8_t *)frame,
335 DIP_HEADER_SIZE + frame->len);
330} 336}
331 337
332static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder, 338static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,