[igt-dev] [PATCH i-g-t 2/3] lib/igt_kms: add igt_kms_get_3d_edid

Simon Ser simon.ser at intel.com
Fri Jul 5 13:08:38 UTC 2019


This replaces kmstest_edid_add_3d. The previous code for generating CEA
extensions can be removed.

The old and new generated EDIDs are byte-to-byte equal.

Signed-off-by: Simon Ser <simon.ser at intel.com>
---
 lib/igt_kms.c               | 149 ++++++++++++------------------------
 lib/igt_kms.h               |   2 +-
 lib/tests/igt_edid.c        |   1 +
 lib/tests/igt_hdmi_inject.c |  94 -----------------------
 lib/tests/meson.build       |   1 -
 tests/kms_3d.c              |   7 +-
 6 files changed, 55 insertions(+), 199 deletions(-)
 delete mode 100644 lib/tests/igt_hdmi_inject.c

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 6fe3d4f0ed4e..8a76acf9e8e4 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -116,9 +116,6 @@ static void update_edid_csum(unsigned char *edid, int cea_pos)
  *  - 800x600 60Hz
  *  - 640x480 60Hz
  *
- * This can be extended with further features using functions such as
- * #kmstest_edid_add_3d.
- *
  * Returns: a basic edid block
  */
 const unsigned char *igt_kms_get_base_edid(void)
@@ -155,9 +152,6 @@ const unsigned char *igt_kms_get_base_edid(void)
  *  - 800x600 60Hz
  *  - 640x480 60Hz
  *
- * This can be extended with further features using functions such as
- * #kmstest_edid_add_3d.
- *
  * Returns: an alternate edid block
  */
 const unsigned char *igt_kms_get_alt_edid(void)
@@ -344,6 +338,57 @@ const unsigned char *igt_kms_get_4k_edid(void)
 	return raw_edid;
 }
 
+const unsigned char *igt_kms_get_3d_edid(void)
+{
+	static unsigned char raw_edid[256] = {0};
+	struct edid *edid;
+	struct edid_ext *edid_ext;
+	struct edid_cea *edid_cea;
+	char *cea_data;
+	struct edid_cea_data_block *block;
+	/* We'll add 5 extension fields to the HDMI VSDB. */
+	char raw_hdmi[HDMI_VSDB_MIN_SIZE + 5] = {0};
+	struct hdmi_vsdb *hdmi;
+	size_t cea_data_size = 0;
+
+	/* Create a new EDID from the base IGT EDID, and add an
+	 * extension that advertises 3D support. */
+	edid = (struct edid *) raw_edid;
+	memcpy(edid, igt_kms_get_base_edid(), sizeof(struct edid));
+	edid->extensions_len = 1;
+	edid_ext = &edid->extensions[0];
+	edid_cea = &edid_ext->data.cea;
+	cea_data = edid_cea->data;
+
+	/* Short Video Descriptor */
+	block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
+	cea_data_size += edid_cea_data_block_set_svd(block, edid_4k_svds,
+						     sizeof(edid_4k_svds));
+
+	/* Vendor-Specific Data Block */
+	hdmi = (struct hdmi_vsdb *) raw_hdmi;
+	hdmi->src_phy_addr[0] = 0x10;
+	hdmi->src_phy_addr[1] = 0x00;
+	/* 5 extension fields */
+	hdmi->flags1 = 0;
+	hdmi->max_tdms_clock = 0;
+	hdmi->flags2 = HDMI_VSDB_VIDEO_PRESENT;
+	hdmi->data[0] = HDMI_VSDB_VIDEO_3D_PRESENT; /* HDMI video flags */
+	hdmi->data[1] = 0; /* 0 VIC entries, 0 3D entries */
+
+	block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
+	cea_data_size += edid_cea_data_block_set_hdmi_vsdb(block, hdmi,
+							   sizeof(raw_hdmi));
+
+	assert(cea_data_size <= sizeof(edid_cea->data));
+
+	edid_ext_set_cea(edid_ext, cea_data_size, 0, 0);
+
+	edid_update_checksum(edid);
+	edid_ext_update_cea_checksum(edid_ext);
+	return raw_edid;
+}
+
 const char * const igt_plane_prop_names[IGT_NUM_PLANE_PROPS] = {
 	[IGT_PLANE_SRC_X] = "SRC_X",
 	[IGT_PLANE_SRC_Y] = "SRC_Y",
@@ -1401,98 +1446,6 @@ kmstest_get_property(int drm_fd, uint32_t object_id, uint32_t object_type,
 	return found;
 }
 
-struct edid_block {
-    int pos;
-    unsigned char *data;
-};
-
-static struct edid_block
-init_cea_block(const unsigned char *edid, size_t length,
-	       unsigned char *new_edid_ptr[], size_t *new_length,
-	       char extra_extensions_length,
-	       uint32_t dtd_support)
-{
-	struct edid_block new_edid;
-	int n_extensions;
-	int pos;
-	static const char cea_header_len = 4, video_block_len = 6;
-
-	igt_assert(new_edid_ptr != NULL && new_length != NULL);
-
-	*new_length = length + 128;
-
-	new_edid.data = calloc(*new_length, sizeof(*new_edid.data));
-	igt_assert_f(new_edid.data, "Failed to allocate %zu bytes for edid\n", sizeof(new_length));
-	memcpy(new_edid.data, edid, length);
-	*new_edid_ptr = new_edid.data;
-
-	n_extensions = new_edid.data[126];
-	n_extensions++;
-	new_edid.data[126] = n_extensions;
-
-	update_edid_csum(new_edid.data, 0);
-
-	/* add a cea-861 extension block */
-	pos = length;
-	new_edid.data[pos++] = 0x2;
-	new_edid.data[pos++] = 0x3;
-	new_edid.data[pos++] = cea_header_len + video_block_len +
-		extra_extensions_length;
-	new_edid.data[pos++] = dtd_support;
-
-	/* video block (id | length) */
-	new_edid.data[pos++] = 2 << 5 | (video_block_len - 1);
-	new_edid.data[pos++] = 32 | 0x80; /* 1080p @ 24Hz | (native)*/
-	new_edid.data[pos++] = 5;         /* 1080i @ 60Hz */
-	new_edid.data[pos++] = 20;        /* 1080i @ 50Hz */
-	new_edid.data[pos++] = 4;         /* 720p @ 60Hz*/
-	new_edid.data[pos++] = 19;        /* 720p @ 50Hz*/
-	new_edid.pos = pos;
-
-	return new_edid;
-}
-
-/**
- * kmstest_edid_add_3d:
- * @edid: an existing valid edid block
- * @length: length of @edid
- * @new_edid_ptr: pointer to where the new edid will be placed
- * @new_length: pointer to the size of the new edid
- *
- * Makes a copy of an existing edid block and adds an extension indicating
- * stereo 3D capabilities.
- */
-void kmstest_edid_add_3d(const unsigned char *edid, size_t length,
-			 unsigned char *new_edid_ptr[], size_t *new_length)
-{
-	char vsdb_block_len = 11;
-	struct edid_block new_edid = init_cea_block(edid, length, new_edid_ptr,
-						    new_length, vsdb_block_len,
-						    0);
-	int pos = new_edid.pos;
-
-	/* vsdb block ( id | length ) */
-	new_edid.data[pos++] = 3 << 5 | (vsdb_block_len - 1);
-	/* registration id */
-	new_edid.data[pos++] = 0x3;
-	new_edid.data[pos++] = 0xc;
-	new_edid.data[pos++] = 0x0;
-	/* source physical address */
-	new_edid.data[pos++] = 0x10;
-	new_edid.data[pos++] = 0x00;
-	/* Supports_AI ... etc */
-	new_edid.data[pos++] = 0x00;
-	/* Max TMDS Clock */
-	new_edid.data[pos++] = 0x00;
-	/* Latency present, HDMI Video Present */
-	new_edid.data[pos++] = 0x20;
-	/* HDMI Video */
-	new_edid.data[pos++] = 0x80;
-	new_edid.data[pos++] = 0x00;
-
-	update_edid_csum(new_edid.data, length);
-}
-
 /**
  * kmstest_unset_all_crtcs:
  * @drm_fd: the DRM fd
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 203719878d86..0486737bb8be 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -194,7 +194,6 @@ enum intel_broadcast_rgb_mode {
 
 bool kmstest_force_connector(int fd, drmModeConnector *connector,
 			     enum kmstest_force_connector_state state);
-void kmstest_edid_add_3d(const unsigned char *edid, size_t length, unsigned char *new_edid_ptr[], size_t *new_length);
 void kmstest_force_edid(int drm_fd, drmModeConnector *connector,
 			const unsigned char *edid);
 
@@ -763,6 +762,7 @@ const unsigned char *igt_kms_get_alt_edid(void);
 const unsigned char *igt_kms_get_hdmi_audio_edid(void);
 const unsigned char *igt_kms_get_dp_audio_edid(void);
 const unsigned char *igt_kms_get_4k_edid(void);
+const unsigned char *igt_kms_get_3d_edid(void);
 
 struct udev_monitor *igt_watch_hotplug(void);
 bool igt_hotplug_detected(struct udev_monitor *mon,
diff --git a/lib/tests/igt_edid.c b/lib/tests/igt_edid.c
index 1a78b38a945b..e15748286ac0 100644
--- a/lib/tests/igt_edid.c
+++ b/lib/tests/igt_edid.c
@@ -77,6 +77,7 @@ igt_simple_main
 		{ "alt", igt_kms_get_alt_edid, 0 },
 		{ "hdmi_audio", igt_kms_get_hdmi_audio_edid, 1 },
 		{ "4k", igt_kms_get_4k_edid, 1 },
+		{ "3d", igt_kms_get_3d_edid, 1 },
 		{0},
 	}, *f;
 	const unsigned char *edid;
diff --git a/lib/tests/igt_hdmi_inject.c b/lib/tests/igt_hdmi_inject.c
deleted file mode 100644
index c70c3195cb1d..000000000000
--- a/lib/tests/igt_hdmi_inject.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright © 2017 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- */
-
-#include "igt.h"
-
-static const unsigned char edid_header[] = {
-	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
-};
-
-/**
- * Sanity check the header of the base EDID block.
- *
- * Return: 8 if the header is perfect, down to 0 if it's totally wrong.
- */
-static int edid_header_is_valid(const unsigned char *raw_edid)
-{
-	int i, score = 0;
-
-	for (i = 0; i < sizeof(edid_header); i++)
-		if (raw_edid[i] == edid_header[i])
-			score++;
-
-	return score;
-}
-
-/**
- * Sanity check the checksum of the EDID block.
- *
- * Return: 0 if the block is perfect.
- * See byte 127 of spec
- * https://en.wikipedia.org/wiki/Extended_Display_Identification_Data#EDID_1.3_data_format
- */
-static int edid_block_checksum(const unsigned char *raw_edid)
-{
-	int i;
-	unsigned char csum = 0;
-	for (i = 0; i < EDID_LENGTH; i++) {
-		csum += raw_edid[i];
-	}
-
-	return csum;
-}
-
-typedef void (*hdmi_inject_func)(const unsigned char *edid, size_t length,
-				 unsigned char *new_edid_ptr[], size_t *new_length);
-
-igt_simple_main
-{
-	const struct {
-		const char *desc;
-		hdmi_inject_func inject;
-	} funcs[] = {
-		{ "3D", kmstest_edid_add_3d },
-		{ NULL, NULL },
-	}, *f;
-
-	for (f = funcs; f->inject; f++) {
-		unsigned char *edid;
-		size_t length;
-
-		f->inject(igt_kms_get_base_edid(), EDID_LENGTH, &edid,
-			  &length);
-
-		igt_assert_f(edid_header_is_valid(edid) == 8,
-			     "invalid header on HDMI %s", f->desc);
-		/* check base edid block */
-		igt_assert_f(edid_block_checksum(edid) == 0,
-			     "checksum failed on HDMI %s", f->desc);
-		/* check extension block */
-		igt_assert_f(edid_block_checksum(edid + EDID_LENGTH) == 0,
-			     "CEA block checksum failed on HDMI %s", f->desc);
-	}
-}
diff --git a/lib/tests/meson.build b/lib/tests/meson.build
index b930ee6eb1cd..02fa335a718a 100644
--- a/lib/tests/meson.build
+++ b/lib/tests/meson.build
@@ -7,7 +7,6 @@ lib_tests = [
 	'igt_exit_handler',
 	'igt_fork',
 	'igt_fork_helper',
-	'igt_hdmi_inject',
 	'igt_list_only',
 	'igt_invalid_subtest_name',
 	'igt_no_exit',
diff --git a/tests/kms_3d.c b/tests/kms_3d.c
index a170814f6356..8ade6d347a29 100644
--- a/tests/kms_3d.c
+++ b/tests/kms_3d.c
@@ -31,8 +31,7 @@ igt_simple_main
 	int drm_fd;
 	drmModeRes *res;
 	drmModeConnector *connector;
-	unsigned char *edid;
-	size_t length;
+	const unsigned char *edid;
 	int mode_count, connector_id;
 
 	drm_fd = drm_open_driver_master(DRIVER_INTEL);
@@ -57,8 +56,7 @@ igt_simple_main
 	}
 	igt_require(connector);
 
-	kmstest_edid_add_3d(igt_kms_get_base_edid(), EDID_LENGTH, &edid,
-			    &length);
+	edid = igt_kms_get_3d_edid();
 
 	kmstest_force_edid(drm_fd, connector, edid);
 	if (!kmstest_force_connector(drm_fd, connector, FORCE_CONNECTOR_ON))
@@ -116,5 +114,4 @@ igt_simple_main
 	kmstest_force_edid(drm_fd, connector, NULL);
 
 	drmModeFreeConnector(connector);
-	free(edid);
 }
-- 
2.22.0



More information about the igt-dev mailing list