From 3356087442806675438319578f1c964e51ee4965 Mon Sep 17 00:00:00 2001 From: Simon Ser <simon.ser@intel.com> Date: Tue, 2 Jul 2019 13:31:02 +0300 Subject: [PATCH] lib/igt_kms: use igt_edid to generate a 4K EDID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The new EDID has been byte-by-byte checked to be exactly the same as before. Signed-off-by: Simon Ser <simon.ser@intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> --- lib/igt_kms.c | 107 ++++++++++++++++++++---------------- lib/igt_kms.h | 2 +- lib/tests/igt_edid.c | 1 + lib/tests/igt_hdmi_inject.c | 1 - tests/kms_hdmi_inject.c | 9 +-- 5 files changed, 64 insertions(+), 56 deletions(-) diff --git a/lib/igt_kms.c b/lib/igt_kms.c index 424c83159..6fe3d4f0e 100644 --- a/lib/igt_kms.c +++ b/lib/igt_kms.c @@ -284,6 +284,66 @@ const unsigned char *igt_kms_get_dp_audio_edid(void) return raw_edid; } +static const uint8_t edid_4k_svds[] = { + 32 | CEA_SVD_NATIVE, /* 1080p @ 24Hz (native) */ + 5, /* 1080i @ 60Hz */ + 20, /* 1080i @ 50Hz */ + 4, /* 720p @ 60Hz */ + 19, /* 720p @ 50Hz */ +}; + +const unsigned char *igt_kms_get_4k_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 6 extension fields to the HDMI VSDB. */ + char raw_hdmi[HDMI_VSDB_MIN_SIZE + 6] = {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 4K 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; + /* 6 extension fields */ + hdmi->flags1 = 0; + hdmi->max_tdms_clock = 0; + hdmi->flags2 = HDMI_VSDB_VIDEO_PRESENT; + hdmi->data[0] = 0x00; /* HDMI video flags */ + hdmi->data[1] = 1 << 5; /* 1 VIC entry, 0 3D entries */ + hdmi->data[2] = 0x01; /* 2160p, specified as short descriptor */ + + 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", @@ -1346,8 +1406,6 @@ struct edid_block { unsigned char *data; }; -#define DTD_SUPPORTS_AUDIO 1<<6 - static struct edid_block init_cea_block(const unsigned char *edid, size_t length, unsigned char *new_edid_ptr[], size_t *new_length, @@ -1435,51 +1493,6 @@ void kmstest_edid_add_3d(const unsigned char *edid, size_t length, update_edid_csum(new_edid.data, length); } -/** - * kmstest_edid_add_4k: - * @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 - * a HDMI 4K mode in vsdb. - */ -void kmstest_edid_add_4k(const unsigned char *edid, size_t length, - unsigned char *new_edid_ptr[], size_t *new_length) -{ - char vsdb_block_len = 12; - 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++] = 0x00; /* 3D present */ - - /* HDMI MODE LEN -- how many entries */ - new_edid.data[pos++] = 0x20; - /* 2160p, specified as short descriptor */ - new_edid.data[pos++] = 0x01; - - 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 f72508640..203719878 100644 --- a/lib/igt_kms.h +++ b/lib/igt_kms.h @@ -195,7 +195,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_edid_add_4k(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_base_edid(void); 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); 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 a847df272..1a78b38a9 100644 --- a/lib/tests/igt_edid.c +++ b/lib/tests/igt_edid.c @@ -76,6 +76,7 @@ igt_simple_main { "base", igt_kms_get_base_edid, 0 }, { "alt", igt_kms_get_alt_edid, 0 }, { "hdmi_audio", igt_kms_get_hdmi_audio_edid, 1 }, + { "4k", igt_kms_get_4k_edid, 1 }, {0}, }, *f; const unsigned char *edid; diff --git a/lib/tests/igt_hdmi_inject.c b/lib/tests/igt_hdmi_inject.c index 2534b1a23..c70c3195c 100644 --- a/lib/tests/igt_hdmi_inject.c +++ b/lib/tests/igt_hdmi_inject.c @@ -72,7 +72,6 @@ igt_simple_main hdmi_inject_func inject; } funcs[] = { { "3D", kmstest_edid_add_3d }, - { "4k", kmstest_edid_add_4k }, { NULL, NULL }, }, *f; diff --git a/tests/kms_hdmi_inject.c b/tests/kms_hdmi_inject.c index 9a968fa9e..60198f529 100644 --- a/tests/kms_hdmi_inject.c +++ b/tests/kms_hdmi_inject.c @@ -76,8 +76,7 @@ get_connector(int drm_fd, drmModeRes *res) static void hdmi_inject_4k(int drm_fd, drmModeConnector *connector) { - unsigned char *edid; - size_t length; + const unsigned char *edid; struct kmstest_connector_config config; int ret, cid, i, crtc_mask = -1; int fb_id; @@ -90,9 +89,7 @@ hdmi_inject_4k(int drm_fd, drmModeConnector *connector) /* 4K requires at least HSW */ igt_require(IS_HASWELL(devid) || intel_gen(devid) >= 8); - kmstest_edid_add_4k(igt_kms_get_base_edid(), EDID_LENGTH, &edid, - &length); - + edid = igt_kms_get_4k_edid(); kmstest_force_edid(drm_fd, connector, edid); if (!kmstest_force_connector(drm_fd, connector, FORCE_CONNECTOR_ON)) @@ -135,8 +132,6 @@ hdmi_inject_4k(int drm_fd, drmModeConnector *connector) kmstest_force_connector(drm_fd, connector, FORCE_CONNECTOR_UNSPECIFIED); kmstest_force_edid(drm_fd, connector, NULL); - - free(edid); } static void -- GitLab