Commit 5adaea799c1c2c00a1ffe995255af25717029b65

Authored by Damien Lespiau
Committed by Daniel Vetter
1 parent 178f736ab9

drm/i915/hdmi: Port the infoframe code to the common hdmi helpers

Let's use the drivers/video/hmdi.c and drm infoframe helpers to build
our infoframes.

v2: Simplify the logic to compute the buffer size. We can just take the
maximum infoframe size rounded to 32, which happens to be what the
hardware let us write anyway.

v3: Remove unnecessary memset() (Ville Syrjälä)

Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Showing 1 changed file with 58 additions and 24 deletions Side-by-side Diff

drivers/gpu/drm/i915/intel_hdmi.c
... ... @@ -325,14 +325,43 @@
325 325 POSTING_READ(ctl_reg);
326 326 }
327 327  
  328 +/*
  329 + * The data we write to the DIP data buffer registers is 1 byte bigger than the
  330 + * HDMI infoframe size because of an ECC/reserved byte at position 3 (starting
  331 + * at 0). It's also a byte used by DisplayPort so the same DIP registers can be
  332 + * used for both technologies.
  333 + *
  334 + * DW0: Reserved/ECC/DP | HB2 | HB1 | HB0
  335 + * DW1: DB3 | DB2 | DB1 | DB0
  336 + * DW2: DB7 | DB6 | DB5 | DB4
  337 + * DW3: ...
  338 + *
  339 + * (HB is Header Byte, DB is Data Byte)
  340 + *
  341 + * The hdmi pack() functions don't know about that hardware specific hole so we
  342 + * trick them by giving an offset into the buffer and moving back the header
  343 + * bytes by one.
  344 + */
328 345 static void intel_set_infoframe(struct drm_encoder *encoder,
329   - struct dip_infoframe *frame)
  346 + union hdmi_infoframe *frame)
330 347 {
331 348 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
  349 + uint8_t buffer[VIDEO_DIP_DATA_SIZE];
  350 + ssize_t len;
332 351  
333   - intel_dip_infoframe_csum(frame);
334   - intel_hdmi->write_infoframe(encoder, frame->type, (uint8_t *)frame,
335   - DIP_HEADER_SIZE + frame->len);
  352 + /* see comment above for the reason for this offset */
  353 + len = hdmi_infoframe_pack(frame, buffer + 1, sizeof(buffer) - 1);
  354 + if (len < 0)
  355 + return;
  356 +
  357 + /* Insert the 'hole' (see big comment above) at position 3 */
  358 + buffer[0] = buffer[1];
  359 + buffer[1] = buffer[2];
  360 + buffer[2] = buffer[3];
  361 + buffer[3] = 0;
  362 + len++;
  363 +
  364 + intel_hdmi->write_infoframe(encoder, frame->any.type, buffer, len);
336 365 }
337 366  
338 367 static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
339 368  
340 369  
341 370  
342 371  
343 372  
344 373  
345 374  
346 375  
... ... @@ -340,40 +369,45 @@
340 369 {
341 370 struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
342 371 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
343   - struct dip_infoframe avi_if = {
344   - .type = DIP_TYPE_AVI,
345   - .ver = DIP_VERSION_AVI,
346   - .len = DIP_LEN_AVI,
347   - };
  372 + union hdmi_infoframe frame;
  373 + int ret;
348 374  
  375 + ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
  376 + adjusted_mode);
  377 + if (ret < 0) {
  378 + DRM_ERROR("couldn't fill AVI infoframe\n");
  379 + return;
  380 + }
  381 +
349 382 if (adjusted_mode->flags & DRM_MODE_FLAG_DBLCLK)
350   - avi_if.body.avi.YQ_CN_PR |= DIP_AVI_PR_2;
  383 + frame.avi.pixel_repeat = 1;
351 384  
352 385 if (intel_hdmi->rgb_quant_range_selectable) {
353 386 if (intel_crtc->config.limited_color_range)
354   - avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_LIMITED;
  387 + frame.avi.quantization_range =
  388 + HDMI_QUANTIZATION_RANGE_LIMITED;
355 389 else
356   - avi_if.body.avi.ITC_EC_Q_SC |= DIP_AVI_RGB_QUANT_RANGE_FULL;
  390 + frame.avi.quantization_range =
  391 + HDMI_QUANTIZATION_RANGE_FULL;
357 392 }
358 393  
359   - avi_if.body.avi.VIC = drm_match_cea_mode(adjusted_mode);
360   -
361   - intel_set_infoframe(encoder, &avi_if);
  394 + intel_set_infoframe(encoder, &frame);
362 395 }
363 396  
364 397 static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder)
365 398 {
366   - struct dip_infoframe spd_if;
  399 + union hdmi_infoframe frame;
  400 + int ret;
367 401  
368   - memset(&spd_if, 0, sizeof(spd_if));
369   - spd_if.type = DIP_TYPE_SPD;
370   - spd_if.ver = DIP_VERSION_SPD;
371   - spd_if.len = DIP_LEN_SPD;
372   - strcpy(spd_if.body.spd.vn, "Intel");
373   - strcpy(spd_if.body.spd.pd, "Integrated gfx");
374   - spd_if.body.spd.sdi = DIP_SPD_PC;
  402 + ret = hdmi_spd_infoframe_init(&frame.spd, "Intel", "Integrated gfx");
  403 + if (ret < 0) {
  404 + DRM_ERROR("couldn't fill SPD infoframe\n");
  405 + return;
  406 + }
375 407  
376   - intel_set_infoframe(encoder, &spd_if);
  408 + frame.spd.sdi = HDMI_SPD_SDI_PC;
  409 +
  410 + intel_set_infoframe(encoder, &frame);
377 411 }
378 412  
379 413 static void g4x_set_infoframes(struct drm_encoder *encoder,