CTA-861-G adds AVI Infoframe version 3 for sending VIC codes 193-219 and IDO defined new colorspace information. Specifically, bits 5-7 of Data Byte 1 is used for representing colorspaces instead of bits 5-6 in version 2. Similarly the bits 0-7 of Data Byte 4 is to be used to accommodate VICs between 193-219, as compared to 0-6 in version 2. This patch adds a new helper function to set the AVI version to 3 if any of the above information is added to the AVI infoframe. It also calls this function to set the appropriate version while computing avi infoframes for i915 driver. Signed-off-by: Ankit Nautiyal <ankit.k.nautiyal@xxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_hdmi.c | 1 + drivers/video/hdmi.c | 29 ++++++++++++++++++++--- include/linux/hdmi.h | 1 + 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c index 0fbcdddb7ad5..0950d48e4e5f 100644 --- a/drivers/gpu/drm/i915/display/intel_hdmi.c +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c @@ -751,6 +751,7 @@ bool intel_hdmi_compute_avi_infoframe(struct intel_encoder *encoder, /* TODO: handle pixel repetition for YCBCR420 outputs */ + hdmi_avi_infoframe_set_version(frame); ret = hdmi_avi_infoframe_check(frame); if (drm_WARN_ON(encoder->base.dev, ret)) return false; diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index f8e325cccfee..aab8900efa24 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -50,6 +50,20 @@ static void hdmi_infoframe_set_checksum(void *buffer, size_t size) ptr[3] = hdmi_infoframe_checksum(buffer, size); } +/** + * hdmi_avi_infoframe_set_version() - fill the HDMI AVI infoframe + * version information + * @frame: HDMI AVI infoframe + */ +void +hdmi_avi_infoframe_set_version(struct hdmi_avi_infoframe *frame) +{ + if (frame->video_code > 127 || + frame->colorspace == HDMI_COLORSPACE_IDO_DEFINED) + frame->version = 3; +} +EXPORT_SYMBOL(hdmi_avi_infoframe_set_version); + /** * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe * @frame: HDMI AVI infoframe @@ -67,10 +81,17 @@ EXPORT_SYMBOL(hdmi_avi_infoframe_init); static int hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe *frame) { if (frame->type != HDMI_INFOFRAME_TYPE_AVI || - frame->version != 2 || frame->length != HDMI_AVI_INFOFRAME_SIZE) return -EINVAL; + if (frame->video_code > 127 || + frame->colorspace == HDMI_COLORSPACE_IDO_DEFINED) { + if (frame->version != 3) + return -EINVAL; + } else if (frame->version != 2) { + return -EINVAL; + } + if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9) return -EINVAL; @@ -159,7 +180,7 @@ ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame, if (frame->itc) ptr[2] |= BIT(7); - ptr[3] = frame->video_code & 0x7f; + ptr[3] = frame->video_code; ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) | ((frame->content_type & 0x3) << 4) | @@ -1583,12 +1604,14 @@ int hdmi_avi_infoframe_unpack_only(struct hdmi_avi_infoframe *frame, frame->quantization_range = (ptr[2] >> 2) & 0x3; frame->nups = ptr[2] & 0x3; - frame->video_code = ptr[3] & 0x7f; + frame->video_code = ptr[3]; frame->ycc_quantization_range = (ptr[4] >> 6) & 0x3; frame->content_type = (ptr[4] >> 4) & 0x3; frame->pixel_repeat = ptr[4] & 0xf; + hdmi_avi_infoframe_set_version(frame); + return 0; } EXPORT_SYMBOL(hdmi_avi_infoframe_unpack_only); diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index dda209fb77e3..2fe012670ad3 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -438,5 +438,6 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, const void *buffer, size_t size); void hdmi_infoframe_log(const char *level, struct device *dev, const union hdmi_infoframe *frame); +void hdmi_avi_infoframe_set_version(struct hdmi_avi_infoframe *frame); #endif /* _DRM_HDMI_H */ -- 2.25.1