[PATCH 4/9] video/hdmi: Add AVI version 3 defined in CTA-861-G

Ankit Nautiyal ankit.k.nautiyal at intel.com
Mon Oct 17 08:43:07 UTC 2022


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 at intel.com>
---
 drivers/gpu/drm/i915/display/intel_hdmi.c |  1 +
 drivers/video/hdmi.c                      | 32 ++++++++++++++++++++---
 include/linux/hdmi.h                      |  1 +
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
index 93519fb23d9d..5551a52f6dca 100644
--- a/drivers/gpu/drm/i915/display/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
@@ -754,6 +754,7 @@ 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 e94af88e0701..97014c857841 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -51,6 +51,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
@@ -68,10 +82,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;
 
@@ -160,7 +181,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) |
@@ -1627,12 +1648,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);
@@ -1660,7 +1683,8 @@ static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
 		return -EINVAL;
 
 	if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI ||
-	    ptr[1] != 2 ||
+	    ptr[1] > 3 ||
+	    ptr[1] < 2 ||
 	    ptr[2] != HDMI_AVI_INFOFRAME_SIZE)
 		return -EINVAL;
 
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index b7e71b042d50..bfbcae45ca65 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -451,5 +451,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



More information about the Intel-gfx-trybot mailing list