diff mbox

[i-g-t,2/4] lib: add the ability to set an EDID data block on a connector

Message ID 1403099053-31243-3-git-send-email-thomas.wood@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Thomas Wood June 18, 2014, 1:44 p.m. UTC
Add a function to set an EDID data block on a connector and include a
set of generic EDID blocks for testing.

Signed-off-by: Thomas Wood <thomas.wood@intel.com>
---
 .../intel-gpu-tools/intel-gpu-tools-docs.xml       |   1 +
 lib/Makefile.sources                               |   1 +
 lib/igt_edid.h                                     | 125 +++++++++++++++++++++
 lib/igt_kms.c                                      |  50 ++++++++-
 lib/igt_kms.h                                      |  23 ++++
 tests/kms_force_connector.c                        |  24 ++++
 6 files changed, 220 insertions(+), 4 deletions(-)
 create mode 100644 lib/igt_edid.h

Comments

Daniel Vetter June 18, 2014, 1:57 p.m. UTC | #1
On Wed, Jun 18, 2014 at 02:44:11PM +0100, Thomas Wood wrote:
> +/**
> + * kmstest_generic_edid:
> + * @EDID_XGA: 1024x768
> + * @EDID_SXGA: 1280x1024
> + * @EDID_UXGA: 1600x1200
> + * @EDID_WSXGA: 1680x1050
> + * @EDID_FHD: 1920x1080
> + * @MAX_EDIDS: Size of #generic_edid array
> + */
> +enum kmstest_generic_edid {
> +	EDID_XGA,   /* 1024x768 */
> +	EDID_SXGA,  /* 1280x1024 */
> +	EDID_UXGA,  /* 1600x1200 */
> +	EDID_WSXGA, /* 1680x1050 */
> +	EDID_FHD,   /* 1920x1080 */

Hm, can't we have just one full hd edid which supports all the above
modes?
-Daniel
Thomas Wood June 18, 2014, 2:03 p.m. UTC | #2
On 18 June 2014 14:57, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Wed, Jun 18, 2014 at 02:44:11PM +0100, Thomas Wood wrote:
>> +/**
>> + * kmstest_generic_edid:
>> + * @EDID_XGA: 1024x768
>> + * @EDID_SXGA: 1280x1024
>> + * @EDID_UXGA: 1600x1200
>> + * @EDID_WSXGA: 1680x1050
>> + * @EDID_FHD: 1920x1080
>> + * @MAX_EDIDS: Size of #generic_edid array
>> + */
>> +enum kmstest_generic_edid {
>> +     EDID_XGA,   /* 1024x768 */
>> +     EDID_SXGA,  /* 1280x1024 */
>> +     EDID_UXGA,  /* 1600x1200 */
>> +     EDID_WSXGA, /* 1680x1050 */
>> +     EDID_FHD,   /* 1920x1080 */
>
> Hm, can't we have just one full hd edid which supports all the above
> modes?


Yes, although for kms_force_connector I actually wanted two different
EDIDs to make sure overwriting the value worked correctly.


> -Daniel
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
diff mbox

Patch

diff --git a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
index 68ca8d4..3d9caf8 100644
--- a/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
+++ b/docs/reference/intel-gpu-tools/intel-gpu-tools-docs.xml
@@ -25,6 +25,7 @@ 
     <xi:include href="xml/intel_batchbuffer.xml"/>
     <xi:include href="xml/intel_chipset.xml"/>
     <xi:include href="xml/intel_io.xml"/>
+    <xi:include href="xml/igt_edid.xml"/>
 
   </chapter>
   <index id="api-index-full">
diff --git a/lib/Makefile.sources b/lib/Makefile.sources
index 62a0c75..8c6c4dc 100644
--- a/lib/Makefile.sources
+++ b/lib/Makefile.sources
@@ -40,6 +40,7 @@  libintel_tools_la_SOURCES = 	\
 	intel_iosf.c		\
 	igt_kms.c		\
 	igt_kms.h		\
+	igt_edid.h		\
 	igt_fb.c		\
 	igt_fb.h		\
 	igt_core.c		\
diff --git a/lib/igt_edid.h b/lib/igt_edid.h
new file mode 100644
index 0000000..27373b7
--- /dev/null
+++ b/lib/igt_edid.h
@@ -0,0 +1,125 @@ 
+/*
+ * generic edid taken from Linux, drivers/gpu/drm/drm_edid_load.c:
+ *
+ *
+   drm_edid_load.c: use a built-in EDID data set or load it via the firmware
+		    interface
+
+   Copyright (C) 2012 Carsten Emde <C.Emde@osadl.org>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either version 2
+   of the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
+*/
+
+#ifndef __IGT_EDID_H__
+#define __IGT_EDID_H__
+
+#include "igt_kms.h"
+
+#define EDID_LENGTH 128
+
+static const unsigned char generic_edid[MAX_EDIDS][EDID_LENGTH] = {
+	{
+	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+	0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x05, 0x16, 0x01, 0x03, 0x6d, 0x23, 0x1a, 0x78,
+	0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
+	0x20, 0x50, 0x54, 0x00, 0x08, 0x00, 0x61, 0x40,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x64, 0x19,
+	0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x08, 0x90,
+	0x36, 0x00, 0x63, 0x0a, 0x11, 0x00, 0x00, 0x18,
+	0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
+	0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
+	0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
+	0x3d, 0x2f, 0x31, 0x07, 0x00, 0x0a, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
+	0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x58,
+	0x47, 0x41, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x55,
+	},
+	{
+	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+	0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x05, 0x16, 0x01, 0x03, 0x6d, 0x2c, 0x23, 0x78,
+	0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
+	0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0x81, 0x80,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x30, 0x2a,
+	0x00, 0x98, 0x51, 0x00, 0x2a, 0x40, 0x30, 0x70,
+	0x13, 0x00, 0xbc, 0x63, 0x11, 0x00, 0x00, 0x1e,
+	0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
+	0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
+	0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
+	0x3d, 0x3e, 0x40, 0x0b, 0x00, 0x0a, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
+	0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x53,
+	0x58, 0x47, 0x41, 0x0a, 0x20, 0x20, 0x00, 0xa0,
+	},
+	{
+	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+	0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x05, 0x16, 0x01, 0x03, 0x6d, 0x37, 0x29, 0x78,
+	0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
+	0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0xa9, 0x40,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x48, 0x3f,
+	0x40, 0x30, 0x62, 0xb0, 0x32, 0x40, 0x40, 0xc0,
+	0x13, 0x00, 0x2b, 0xa0, 0x21, 0x00, 0x00, 0x1e,
+	0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
+	0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
+	0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
+	0x3d, 0x4a, 0x4c, 0x11, 0x00, 0x0a, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
+	0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x55,
+	0x58, 0x47, 0x41, 0x0a, 0x20, 0x20, 0x00, 0x9d,
+	},
+	{
+	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+	0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x05, 0x16, 0x01, 0x03, 0x6d, 0x2b, 0x1b, 0x78,
+	0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
+	0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0xb3, 0x00,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x21, 0x39,
+	0x90, 0x30, 0x62, 0x1a, 0x27, 0x40, 0x68, 0xb0,
+	0x36, 0x00, 0xb5, 0x11, 0x11, 0x00, 0x00, 0x1e,
+	0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
+	0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
+	0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
+	0x3d, 0x40, 0x42, 0x0f, 0x00, 0x0a, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
+	0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x57,
+	0x53, 0x58, 0x47, 0x41, 0x0a, 0x20, 0x00, 0x26,
+	},
+	{
+	0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+	0x31, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x05, 0x16, 0x01, 0x03, 0x6d, 0x32, 0x1c, 0x78,
+	0xea, 0x5e, 0xc0, 0xa4, 0x59, 0x4a, 0x98, 0x25,
+	0x20, 0x50, 0x54, 0x00, 0x00, 0x00, 0xd1, 0xc0,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+	0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a,
+	0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
+	0x45, 0x00, 0xf4, 0x19, 0x11, 0x00, 0x00, 0x1e,
+	0x00, 0x00, 0x00, 0xff, 0x00, 0x4c, 0x69, 0x6e,
+	0x75, 0x78, 0x20, 0x23, 0x30, 0x0a, 0x20, 0x20,
+	0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x3b,
+	0x3d, 0x42, 0x44, 0x0f, 0x00, 0x0a, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc,
+	0x00, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x20, 0x46,
+	0x48, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x05,
+	}
+};
+
+#endif /* __IGT_EDID_H__ */
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 8de8e0a..86dec51 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -394,6 +394,20 @@  static int get_card_number(int fd)
 	return minor(buf.st_rdev);
 }
 
+static char* get_debugfs_connector_path(int drm_fd, drmModeConnector *connector,
+					const char *file)
+{
+	char *path;
+
+	asprintf(&path, "/sys/kernel/debug/dri/%d/%s-%d/%s",
+		 get_card_number(drm_fd),
+		 kmstest_connector_type_str(connector->connector_type),
+		 connector->connector_type_id,
+		 file);
+
+	return path;
+}
+
 /**
  * kmstest_force_connector:
  * @fd: drm file descriptor
@@ -426,10 +440,7 @@  void kmstest_force_connector(int drm_fd, drmModeConnector *connector, enum
 		break;
 	}
 
-	asprintf(&path, "/sys/kernel/debug/dri/%d/%s-%d/force",
-		 get_card_number(drm_fd),
-		 kmstest_connector_type_str(connector->connector_type),
-		 connector->connector_type_id);
+	path = get_debugfs_connector_path(drm_fd, connector, "force");
 	debugfs_fd = open(path, O_WRONLY | O_TRUNC);
 	free(path);
 
@@ -441,6 +452,37 @@  void kmstest_force_connector(int drm_fd, drmModeConnector *connector, enum
 	igt_assert(ret != -1);
 }
 
+/**
+ * kmstest_force_edid:
+ * @drm_fd: drm file descriptor
+ * @connector: connector to set @edid on
+ * @edid: An EDID data block
+ * @length: length of the EDID data. #EDID_LENGTH defines the standard EDID
+ * length
+ *
+ * Set the EDID data on @connector to @edid. See #generic_edid and
+ * #kmstest_generic_edid for a set of generic EDID data blocks.
+ */
+void kmstest_force_edid(int drm_fd, drmModeConnector *connector,
+			const unsigned char *edid, size_t length)
+{
+	char *path;
+	int debugfs_fd, ret;
+
+	path = get_debugfs_connector_path(drm_fd, connector, "edid_override");
+
+	debugfs_fd = open(path, O_WRONLY | O_TRUNC);
+
+	free(path);
+
+	igt_assert(debugfs_fd != -1);
+
+	ret = write(debugfs_fd, edid, length);
+	close(debugfs_fd);
+
+	igt_assert(ret != -1);
+}
+
 void kmstest_free_connector_config(struct kmstest_connector_config *config)
 {
 	drmModeFreeCrtc(config->crtc);
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 45a98c8..4cf74e8 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -90,6 +90,27 @@  enum kmstest_force_connector_state {
 	FORCE_CONNECTOR_OFF
 };
 
+
+/**
+ * kmstest_generic_edid:
+ * @EDID_XGA: 1024x768
+ * @EDID_SXGA: 1280x1024
+ * @EDID_UXGA: 1600x1200
+ * @EDID_WSXGA: 1680x1050
+ * @EDID_FHD: 1920x1080
+ * @MAX_EDIDS: Size of #generic_edid array
+ */
+enum kmstest_generic_edid {
+	EDID_XGA,   /* 1024x768 */
+	EDID_SXGA,  /* 1280x1024 */
+	EDID_UXGA,  /* 1600x1200 */
+	EDID_WSXGA, /* 1680x1050 */
+	EDID_FHD,   /* 1920x1080 */
+
+	MAX_EDIDS
+};
+
+
 int kmstest_get_connector_default_mode(int drm_fd, drmModeConnector *connector,
 				      drmModeModeInfo *mode);
 int kmstest_get_connector_config(int drm_fd, uint32_t connector_id,
@@ -97,6 +118,8 @@  int kmstest_get_connector_config(int drm_fd, uint32_t connector_id,
 				 struct kmstest_connector_config *config);
 void kmstest_force_connector(int fd, drmModeConnector *connector,
 			     enum kmstest_force_connector_state state);
+void kmstest_force_edid(int drm_fd, drmModeConnector *connector,
+			const unsigned char *edid, size_t length);
 void kmstest_free_connector_config(struct kmstest_connector_config *config);
 
 void kmstest_dump_mode(drmModeModeInfo *mode);
diff --git a/tests/kms_force_connector.c b/tests/kms_force_connector.c
index 0591da0..54a92c5 100644
--- a/tests/kms_force_connector.c
+++ b/tests/kms_force_connector.c
@@ -25,6 +25,7 @@ 
 #include "igt_core.h"
 #include "igt_kms.h"
 #include "drmtest.h"
+#include "igt_edid.h"
 
 int
 main (int argc, char **argv)
@@ -68,6 +69,29 @@  main (int argc, char **argv)
 	igt_display_init(&display, drm_fd);
 	igt_display_commit(&display);
 
+	/* test edid forcing */
+	kmstest_force_edid(drm_fd, connector, generic_edid[EDID_FHD],
+			   EDID_LENGTH);
+	temp = drmModeGetConnector(drm_fd, connector->connector_id);
+
+	igt_assert(temp->count_modes == 1);
+	igt_assert(temp->modes[0].vrefresh == 60
+		   && temp->modes[0].hdisplay == 1920
+		   && temp->modes[0].vdisplay == 1080);
+
+	drmModeFreeConnector(temp);
+
+	/* custom edid */
+	kmstest_force_edid(drm_fd, connector, generic_edid[EDID_WSXGA],
+			   EDID_LENGTH);
+	temp = drmModeGetConnector(drm_fd, connector->connector_id);
+
+	igt_assert(temp->count_modes == 1);
+	igt_assert(temp->modes[0].vrefresh == 60
+		   && temp->modes[0].hdisplay == 1680
+		   && temp->modes[0].vdisplay == 1050);
+
+	drmModeFreeConnector(temp);
 
 	/* force the connector off */
 	kmstest_force_connector(drm_fd, connector, FORCE_CONNECTOR_OFF);