* [igt-dev] [PATCH i-g-t v4 0/4] Test tiled display with aid of chamelium.
@ 2020-09-20 18:28 Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 1/4] Make basic chamelium function accessible to other tests Kunal Joshi
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Kunal Joshi @ 2020-09-20 18:28 UTC (permalink / raw
To: igt-dev; +Cc: Kunal Joshi, petri.latvala
As of now we have kms_dp_tiled_display test which needs a physical
panel. Added changes to have chamelium act as a tiled panel and then
execute the test.
Kunal Joshi (4):
Make basic chamelium function accessible to other tests
Added structures and functions to generate tiled edids
Added a subtest where chamelium acts as a tiled panel
HAX: Run in BAT
lib/igt_chamelium.c | 253 +++++++++++++++++++++++
lib/igt_chamelium.h | 45 +++++
lib/igt_edid.c | 27 +++
lib/igt_edid.h | 20 ++
lib/igt_kms.c | 125 ++++++++++++
lib/igt_kms.h | 3 +
tests/intel-ci/fast-feedback.testlist | 1 +
tests/kms_chamelium.c | 281 ++++++++------------------
tests/kms_dp_tiled_display.c | 119 ++++++++---
9 files changed, 648 insertions(+), 226 deletions(-)
--
2.25.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 8+ messages in thread
* [igt-dev] [PATCH i-g-t v4 1/4] Make basic chamelium function accessible to other tests
2020-09-20 18:28 [igt-dev] [PATCH i-g-t v4 0/4] Test tiled display with aid of chamelium Kunal Joshi
@ 2020-09-20 18:28 ` Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 2/4] Added structures and functions to generate tiled edids Kunal Joshi
` (3 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Kunal Joshi @ 2020-09-20 18:28 UTC (permalink / raw
To: igt-dev; +Cc: Kunal Joshi, petri.latvala
There are many use case where we can integrate chamelium with other tests,
Migrating some of basic chamelium functions to igt_chamelium lib to avoid
Code rewriting.
v2: Moved one more function reset_state from tests/kms_chamelium to
lib/igt_chamelium.
v3: - Shifted disabling of modeset to igt_kms
- Replace connection_str with kmstest_connector_status_str (Petri)
- Generalized require__connector_present (Petri)
- Avoided using data_chamelium_t struct (Petri)
v4: - Moved function to library (Petri)
- Renamed some functions and added documentation (Petri)
Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Karthik B S <karthik.b.s@intel.com>
---
lib/igt_chamelium.c | 186 ++++++++++++++++++++++++++++
lib/igt_chamelium.h | 40 ++++++
lib/igt_kms.c | 23 ++++
lib/igt_kms.h | 1 +
tests/kms_chamelium.c | 281 ++++++++++++------------------------------
5 files changed, 329 insertions(+), 202 deletions(-)
diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index d9fab902..0dddbe6f 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -218,6 +218,137 @@ const char *chamelium_port_get_name(struct chamelium_port *port)
return port->name;
}
+/**
+ * chamelium_require_connector_present
+ * @ports: All connected ports
+ * @type: Required port type
+ * @port_count: Total port count
+ * @count: The required number of port count
+ *
+ * Check there are required ports connected of given type
+ */
+void
+chamelium_require_connector_present(struct chamelium_port **ports,
+ unsigned int type,
+ int port_count,
+ int count)
+{
+ int i;
+ int found = 0;
+
+ for (i = 0; i < port_count; i++) {
+ if (chamelium_port_get_type(ports[i]) == type)
+ found++;
+ }
+
+ igt_require_f(found == count,
+ "port of type %s found %d and required %d\n",
+ kmstest_connector_type_str(type), found, count);
+}
+
+/**
+ * chamelium_reprobe_connector
+ * @display: A pointer to an #igt_display_t structure
+ * @chamelium: The Chamelium instance to use
+ * @port: Chamelium port to reprobe
+ *
+ * Reprobe the given connector and fetch current status
+ *
+ * Returns: drmModeConnection
+ */
+drmModeConnection
+chamelium_reprobe_connector(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port)
+{
+ drmModeConnector *connector;
+ drmModeConnection status;
+ igt_output_t *output;
+
+ igt_debug("Reprobing %s...\n", chamelium_port_get_name(port));
+ connector = chamelium_port_get_connector(chamelium, port, true);
+ igt_assert(connector);
+ status = connector->connection;
+
+ /* let's make sure that igt_display is up to date too */
+ output = igt_output_from_connector(display, connector);
+ output->force_reprobe = true;
+ igt_output_refresh(output);
+
+ drmModeFreeConnector(connector);
+ return status;
+}
+
+/**
+ * chamelium_wait_for_conn_status_change
+ * @display: A pointer to an #igt_display_t structure
+ * @chamelium: The Chamelium instance to use
+ * @port: Chamelium port to check connector status update
+ * @status: Enum which describes connector states
+ *
+ * Wait for the connector to change the status
+ */
+void
+chamelium_wait_for_conn_status_change(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port,
+ drmModeConnection status)
+{
+ igt_debug("Waiting for %s to get %s...\n",
+ chamelium_port_get_name(port),
+ kmstest_connector_status_str(status));
+
+ /*
+ * Rely on simple reprobing so we don't fail tests that don't require
+ * that hpd events work in the event that hpd doesn't work on the system
+ */
+ igt_until_timeout(HOTPLUG_TIMEOUT) {
+ if (chamelium_reprobe_connector(display,
+ chamelium, port) == status)
+ return;
+
+ usleep(50000);
+ }
+
+ igt_assert_f(false, "Timed out waiting for %s to get %s\n",
+ chamelium_port_get_name(port),
+ kmstest_connector_status_str(status));
+}
+
+/**
+ * chamelium_reset_state
+ *
+ * @chamelium: The Chamelium instance to use
+ * @port: Chamelium port to reset
+ * @ports: All connected ports
+ * @port_count: Count of connected ports
+ *
+ * Reset chamelium ports
+ */
+void
+chamelium_reset_state(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port,
+ struct chamelium_port **ports,
+ int port_count)
+{
+ int p;
+
+ chamelium_reset(chamelium);
+
+ if (port) {
+ chamelium_wait_for_conn_status_change(display, chamelium,
+ port,
+ DRM_MODE_DISCONNECTED);
+ } else {
+ for (p = 0; p < port_count; p++) {
+ port = ports[p];
+ chamelium_wait_for_conn_status_change(display, chamelium,
+ port, DRM_MODE_DISCONNECTED);
+ }
+ }
+}
+
/**
* chamelium_destroy_frame_dump:
* @dump: The frame dump to destroy
@@ -627,6 +758,61 @@ void chamelium_schedule_hpd_toggle(struct chamelium *chamelium,
"(iii)", port->id, delay_ms, rising_edge));
}
+const struct edid *chamelium_get_aspect_ratio_edid(void)
+{
+ static unsigned char raw_edid[2 * EDID_BLOCK_SIZE] = {0};
+ struct edid *edid;
+ struct edid_ext *edid_ext;
+ struct edid_cea *edid_cea;
+ char *cea_data;
+ struct edid_cea_data_block *block;
+ size_t cea_data_size = 0, vsdb_size;
+ const struct cea_vsdb *vsdb;
+
+ 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;
+
+ /* The HDMI VSDB advertises support for InfoFrames */
+ block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
+ vsdb = cea_vsdb_get_hdmi_default(&vsdb_size);
+ cea_data_size += edid_cea_data_block_set_vsdb(block, vsdb,
+ vsdb_size);
+
+ /* 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_ar_svds,
+ sizeof(edid_ar_svds));
+
+ assert(cea_data_size <= sizeof(edid_cea->data));
+
+ edid_ext_set_cea(edid_ext, cea_data_size, 0, 0);
+
+ edid_update_checksum(edid);
+
+ return edid;
+}
+
+const struct edid *chamelium_get_edid(enum test_edid edid)
+{
+ switch (edid) {
+ case TEST_EDID_BASE:
+ return igt_kms_get_base_edid();
+ case TEST_EDID_ALT:
+ return igt_kms_get_alt_edid();
+ case TEST_EDID_HDMI_AUDIO:
+ return igt_kms_get_hdmi_audio_edid();
+ case TEST_EDID_DP_AUDIO:
+ return igt_kms_get_dp_audio_edid();
+ case TEST_EDID_ASPECT_RATIO:
+ return chamelium_get_aspect_ratio_edid();
+ }
+ assert(0); /* unreachable */
+}
+
static int chamelium_upload_edid(struct chamelium *chamelium,
const struct edid *edid)
{
diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h
index 359f4ab3..bce6331d 100644
--- a/lib/igt_chamelium.h
+++ b/lib/igt_chamelium.h
@@ -32,6 +32,7 @@
#include <xf86drmMode.h>
#include "igt_debugfs.h"
+#include "igt_kms.h"
struct igt_fb;
struct edid;
@@ -73,6 +74,16 @@ enum chamelium_infoframe_type {
CHAMELIUM_INFOFRAME_VENDOR,
};
+enum test_edid {
+ TEST_EDID_BASE,
+ TEST_EDID_ALT,
+ TEST_EDID_HDMI_AUDIO,
+ TEST_EDID_DP_AUDIO,
+ TEST_EDID_ASPECT_RATIO,
+};
+#define TEST_EDID_COUNT 5
+
+
struct chamelium_infoframe {
int version;
size_t payload_size;
@@ -81,6 +92,11 @@ struct chamelium_infoframe {
struct chamelium_edid;
+/* Set of Video Identification Codes advertised in the EDID */
+static const uint8_t edid_ar_svds[] = {
+ 16, /* 1080p @ 60Hz, 16:9 */
+};
+
/**
* CHAMELIUM_MAX_PORTS: the maximum number of ports supported by igt_chamelium.
*
@@ -100,6 +116,8 @@ struct chamelium_edid;
*/
#define CHAMELIUM_MAX_AUDIO_CHANNELS 8
+#define HOTPLUG_TIMEOUT 20 /* seconds */
+
void chamelium_deinit_rpc_only(struct chamelium *chamelium);
struct chamelium *chamelium_init_rpc_only(void);
struct chamelium *chamelium_init(int drm_fd);
@@ -113,6 +131,26 @@ drmModeConnector *chamelium_port_get_connector(struct chamelium *chamelium,
struct chamelium_port *port,
bool reprobe);
const char *chamelium_port_get_name(struct chamelium_port *port);
+void
+chamelium_require_connector_present(struct chamelium_port **ports,
+ unsigned int type,
+ int port_count,
+ int count);
+drmModeConnection
+chamelium_reprobe_connector(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port);
+void
+chamelium_wait_for_conn_status_change(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port,
+ drmModeConnection status);
+void
+chamelium_reset_state(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port,
+ struct chamelium_port **ports,
+ int port_count);
bool chamelium_wait_reachable(struct chamelium *chamelium, int timeout);
void chamelium_assert_reachable(struct chamelium *chamelium, int timeout);
@@ -135,6 +173,8 @@ struct chamelium_edid *chamelium_new_edid(struct chamelium *chamelium,
const struct edid *edid);
const struct edid *chamelium_edid_get_raw(struct chamelium_edid *edid,
struct chamelium_port *port);
+const struct edid *chamelium_get_aspect_ratio_edid(void);
+const struct edid *chamelium_get_edid(enum test_edid edid);
void chamelium_port_set_edid(struct chamelium *chamelium,
struct chamelium_port *port,
struct chamelium_edid *edid);
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index f57972f1..bffa4d94 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2254,6 +2254,29 @@ const drmModeModeInfo *igt_std_1024_mode_get(void)
return &std_1024_mode;
}
+/*
+ * igt_modeset_disable_all_outputs
+ * @diplay: igt display structure
+ *
+ * Modeset to disable all output
+ *
+ * We need to do a modeset disabling all output to get the next
+ * HPD event on TypeC port
+ */
+void igt_modeset_disable_all_outputs(igt_display_t *display)
+{
+ int i;
+
+ for (i = 0; i < display->n_outputs; i++) {
+ igt_output_t *output = &display->outputs[i];
+
+ igt_output_set_pipe(output, PIPE_NONE);
+ }
+
+ igt_display_commit2(display, COMMIT_ATOMIC);
+
+}
+
static void igt_pipe_fini(igt_pipe_t *pipe)
{
free(pipe->planes);
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 26dc9f5f..9ffad56e 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -438,6 +438,7 @@ igt_output_t *igt_output_from_connector(igt_display_t *display,
drmModeConnector *connector);
void igt_output_refresh(igt_output_t *output);
const drmModeModeInfo *igt_std_1024_mode_get(void);
+void igt_modeset_disable_all_outputs(igt_display_t *display);
igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index e1c81e01..9de5f47e 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -36,15 +36,6 @@
#include <string.h>
#include <stdatomic.h>
-enum test_edid {
- TEST_EDID_BASE,
- TEST_EDID_ALT,
- TEST_EDID_HDMI_AUDIO,
- TEST_EDID_DP_AUDIO,
- TEST_EDID_ASPECT_RATIO,
-};
-#define TEST_EDID_COUNT 5
-
enum test_modeset_mode {
TEST_MODESET_ON,
TEST_MODESET_ON_OFF,
@@ -62,7 +53,6 @@ typedef struct {
struct chamelium_edid *edids[TEST_EDID_COUNT];
} data_t;
-#define HOTPLUG_TIMEOUT 20 /* seconds */
#define ONLINE_TIMEOUT 20 /* seconds */
#define HPD_STORM_PULSE_INTERVAL_DP 100 /* ms */
@@ -97,78 +87,6 @@ get_connectors_link_status_failed(data_t *data, bool *link_status_failed)
}
}
-static void
-require_connector_present(data_t *data, unsigned int type)
-{
- int i;
- bool found = false;
-
- for (i = 0; i < data->port_count && !found; i++) {
- if (chamelium_port_get_type(data->ports[i]) == type)
- found = true;
- }
-
- igt_require_f(found, "No port of type %s was found\n",
- kmstest_connector_type_str(type));
-}
-
-static drmModeConnection
-reprobe_connector(data_t *data, struct chamelium_port *port)
-{
- drmModeConnector *connector;
- drmModeConnection status;
- igt_output_t *output;
-
- igt_debug("Reprobing %s...\n", chamelium_port_get_name(port));
- connector = chamelium_port_get_connector(data->chamelium, port, true);
- igt_assert(connector);
- status = connector->connection;
-
- /* let's make sure that igt_display is up to date too */
- output = igt_output_from_connector(&data->display, connector);
- output->force_reprobe = true;
- igt_output_refresh(output);
-
- drmModeFreeConnector(connector);
- return status;
-}
-
-static const char *connection_str(drmModeConnection c)
-{
- switch (c) {
- case DRM_MODE_CONNECTED:
- return "connected";
- case DRM_MODE_DISCONNECTED:
- return "disconnected";
- case DRM_MODE_UNKNOWNCONNECTION:
- return "unknown";
- }
- assert(0); /* unreachable */
-}
-
-static void
-wait_for_connector(data_t *data, struct chamelium_port *port,
- drmModeConnection status)
-{
- igt_debug("Waiting for %s to get %s...\n",
- chamelium_port_get_name(port), connection_str(status));
-
- /*
- * Rely on simple reprobing so we don't fail tests that don't require
- * that hpd events work in the event that hpd doesn't work on the system
- */
- igt_until_timeout(HOTPLUG_TIMEOUT) {
- if (reprobe_connector(data, port) == status) {
- return;
- }
-
- usleep(50000);
- }
-
- igt_assert_f(false, "Timed out waiting for %s to get %s\n",
- chamelium_port_get_name(port), connection_str(status));
-}
-
/* Wait for hotplug and return the remaining time left from timeout */
static bool wait_for_hotplug(struct udev_monitor *mon, int *timeout)
{
@@ -196,7 +114,8 @@ wait_for_connector_after_hotplug(data_t *data, struct udev_monitor *mon,
int hotplug_count = 0;
igt_debug("Waiting for %s to get %s after a hotplug event...\n",
- chamelium_port_get_name(port), connection_str(status));
+ chamelium_port_get_name(port),
+ kmstest_connector_status_str(status));
while (timeout > 0) {
if (!wait_for_hotplug(mon, &timeout))
@@ -204,13 +123,15 @@ wait_for_connector_after_hotplug(data_t *data, struct udev_monitor *mon,
hotplug_count++;
- if (reprobe_connector(data, port) == status)
+ if (chamelium_reprobe_connector(&data->display, data->chamelium,
+ port) == status)
return;
}
igt_assert_f(false, "Timed out waiting for %s to get %s after a hotplug. Current state %s hotplug_count %d\n",
- chamelium_port_get_name(port), connection_str(status),
- connection_str(reprobe_connector(data, port)), hotplug_count);
+ chamelium_port_get_name(port),
+ kmstest_connector_status_str(status),
+ kmstest_connector_status_str(chamelium_reprobe_connector(&data->display, data->chamelium, port)), hotplug_count);
}
@@ -282,30 +203,6 @@ check_analog_bridge(data_t *data, struct chamelium_port *port)
return false;
}
-static void
-reset_state(data_t *data, struct chamelium_port *port)
-{
- int p, i;
-
- for (i = 0; i < data->display.n_outputs; i++) {
- igt_output_t *output = &data->display.outputs[i];
- igt_output_set_pipe(output, PIPE_NONE);
- }
-
- igt_display_commit2(&data->display, COMMIT_ATOMIC);
-
- chamelium_reset(data->chamelium);
-
- if (port) {
- wait_for_connector(data, port, DRM_MODE_DISCONNECTED);
- } else {
- for (p = 0; p < data->port_count; p++) {
- port = data->ports[p];
- wait_for_connector(data, port, DRM_MODE_DISCONNECTED);
- }
- }
-}
-
static void chamelium_paint_xr24_pattern(uint32_t *data,
size_t width, size_t height,
size_t stride, size_t block_size)
@@ -441,7 +338,11 @@ test_hotplug(data_t *data, struct chamelium_port *port, int toggle_count,
struct udev_monitor *mon = igt_watch_uevents();
igt_output_t *output = get_output_for_port(data, port);
- reset_state(data, NULL);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium, NULL,
+ data->ports, data->port_count);
+
+
igt_hpd_storm_set_threshold(data->drm_fd, 0);
for (i = 0; i < toggle_count; i++) {
@@ -486,8 +387,6 @@ test_hotplug(data_t *data, struct chamelium_port *port, int toggle_count,
igt_remove_fb(data->drm_fd, &fb);
}
-static const struct edid *get_edid(enum test_edid edid);
-
static void set_edid(data_t *data, struct chamelium_port *port,
enum test_edid edid)
{
@@ -506,11 +405,14 @@ test_edid_read(data_t *data, struct chamelium_port *port, enum test_edid edid)
const struct edid *raw_edid;
uint64_t edid_blob_id;
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
set_edid(data, port, edid);
chamelium_plug(data->chamelium, port);
- wait_for_connector(data, port, DRM_MODE_CONNECTED);
+ chamelium_wait_for_conn_status_change(&data->display, data->chamelium,
+ port, DRM_MODE_CONNECTED);
igt_skip_on(check_analog_bridge(data, port));
@@ -562,7 +464,10 @@ try_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
chamelium_assert_reachable(data->chamelium, ONLINE_TIMEOUT);
if (port) {
- igt_assert_eq(reprobe_connector(data, port), target_state);
+ igt_assert_eq(chamelium_reprobe_connector(&data->display,
+ data->chamelium,
+ port),
+ target_state);
} else {
for (p = 0; p < data->port_count; p++) {
drmModeConnection current_state;
@@ -575,10 +480,10 @@ try_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
* the expected connector state try to wait for an HPD
* event for each connector/port.
*/
- current_state = reprobe_connector(data, port);
+ current_state = chamelium_reprobe_connector(&data->display, data->chamelium, port);
if (p > 0 && current_state != target_state) {
igt_assert(wait_for_hotplug(mon, &timeout));
- current_state = reprobe_connector(data, port);
+ current_state = chamelium_reprobe_connector(&data->display, data->chamelium, port);
}
igt_assert_eq(current_state, target_state);
@@ -598,7 +503,9 @@ test_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
{
struct udev_monitor *mon = igt_watch_uevents();
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/* Make sure we notice new connectors after resuming */
try_suspend_resume_hpd(data, port, state, test, mon, false);
@@ -625,7 +532,9 @@ test_suspend_resume_hpd_common(data_t *data, enum igt_suspend_state state,
igt_debug("Testing port %s\n", chamelium_port_get_name(port));
}
- reset_state(data, NULL);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium, NULL,
+ data->ports, data->port_count);
/* Make sure we notice new connectors after resuming */
try_suspend_resume_hpd(data, NULL, state, test, mon, false);
@@ -651,7 +560,9 @@ test_suspend_resume_edid_change(data_t *data, struct chamelium_port *port,
bool link_status_failed[2][data->port_count];
int p;
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/* Catch the event and flush all remaining ones. */
igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
@@ -662,7 +573,8 @@ test_suspend_resume_edid_change(data_t *data, struct chamelium_port *port,
chamelium_plug(data->chamelium, port);
igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
- wait_for_connector(data, port, DRM_MODE_CONNECTED);
+ chamelium_wait_for_conn_status_change(&data->display, data->chamelium,
+ port, DRM_MODE_CONNECTED);
/*
* Change the edid before we suspend. On resume, the machine should
@@ -698,7 +610,8 @@ prepare_output(data_t *data, struct chamelium_port *port, enum test_edid edid)
set_edid(data, port, edid);
chamelium_plug(data->chamelium, port);
- wait_for_connector(data, port, DRM_MODE_CONNECTED);
+ chamelium_wait_for_conn_status_change(&data->display, data->chamelium,
+ port, DRM_MODE_CONNECTED);
igt_display_reset(display);
@@ -796,7 +709,9 @@ static void test_display_one_mode(data_t *data, struct chamelium_port *port,
igt_output_t *output;
igt_plane_t *primary;
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
output = prepare_output(data, port, TEST_EDID_BASE);
connector = chamelium_port_get_connector(data->chamelium, port, false);
@@ -841,7 +756,9 @@ static void test_display_all_modes(data_t *data, struct chamelium_port *port,
* let's reset state each mode so we will get the
* HPD pulses realibably
*/
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/*
* modes may change due to mode pruining and link issues, so we
@@ -897,7 +814,9 @@ test_display_frame_dump(data_t *data, struct chamelium_port *port)
* let's reset state each mode so we will get the
* HPD pulses realibably
*/
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/*
* modes may change due to mode pruining and link issues, so we
@@ -1034,7 +953,9 @@ static void test_mode_timings(data_t *data, struct chamelium_port *port)
* let's reset state each mode so we will get the
* HPD pulses realibably
*/
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/*
* modes may change due to mode pruining and link issues, so we
@@ -1071,11 +992,6 @@ static void test_mode_timings(data_t *data, struct chamelium_port *port)
} while (++i < count_modes);
}
-/* Set of Video Identification Codes advertised in the EDID */
-static const uint8_t edid_ar_svds[] = {
- 16, /* 1080p @ 60Hz, 16:9 */
-};
-
struct vic_mode {
int hactive, vactive;
int vrefresh; /* Hz */
@@ -1122,44 +1038,6 @@ static bool vic_mode_matches_drm(const struct vic_mode *vic_mode,
ar_flag == (drm_mode->flags & DRM_MODE_FLAG_PIC_AR_MASK);
}
-static const struct edid *get_aspect_ratio_edid(void)
-{
- static unsigned char raw_edid[2 * EDID_BLOCK_SIZE] = {0};
- struct edid *edid;
- struct edid_ext *edid_ext;
- struct edid_cea *edid_cea;
- char *cea_data;
- struct edid_cea_data_block *block;
- size_t cea_data_size = 0, vsdb_size;
- const struct cea_vsdb *vsdb;
-
- 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;
-
- /* The HDMI VSDB advertises support for InfoFrames */
- block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
- vsdb = cea_vsdb_get_hdmi_default(&vsdb_size);
- cea_data_size += edid_cea_data_block_set_vsdb(block, vsdb,
- vsdb_size);
-
- /* 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_ar_svds,
- sizeof(edid_ar_svds));
-
- assert(cea_data_size <= sizeof(edid_cea->data));
-
- edid_ext_set_cea(edid_ext, cea_data_size, 0, 0);
-
- edid_update_checksum(edid);
-
- return edid;
-}
-
static const char test_display_aspect_ratio_desc[] =
"Pick a mode with a picture aspect-ratio, capture AVI InfoFrames and "
"check they include the relevant fields";
@@ -1181,7 +1059,9 @@ static void test_display_aspect_ratio(data_t *data, struct chamelium_port *port)
igt_require(chamelium_supports_get_last_infoframe(data->chamelium));
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
output = prepare_output(data, port, TEST_EDID_ASPECT_RATIO);
connector = chamelium_port_get_connector(data->chamelium, port, false);
@@ -1911,7 +1791,9 @@ test_display_audio(data_t *data, struct chamelium_port *port,
alsa = alsa_init();
igt_assert(alsa);
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
output = prepare_output(data, port, edid);
connector = chamelium_port_get_connector(data->chamelium, port, false);
@@ -1992,7 +1874,9 @@ test_display_audio_edid(data_t *data, struct chamelium_port *port,
igt_require(eld_is_supported());
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
output = prepare_output(data, port, edid);
connector = chamelium_port_get_connector(data->chamelium, port, false);
@@ -2432,7 +2316,9 @@ static void test_display_planes_random(data_t *data,
srand(time(NULL));
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/* Find the connector and pipe. */
output = prepare_output(data, port, TEST_EDID_BASE);
@@ -2535,7 +2421,9 @@ test_hpd_without_ddc(data_t *data, struct chamelium_port *port)
{
struct udev_monitor *mon = igt_watch_uevents();
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
igt_flush_uevents(mon);
/* Disable the DDC on the connector and make sure we still get a
@@ -2545,7 +2433,9 @@ test_hpd_without_ddc(data_t *data, struct chamelium_port *port)
chamelium_plug(data->chamelium, port);
igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
- igt_assert_eq(reprobe_connector(data, port), DRM_MODE_CONNECTED);
+ igt_assert_eq(chamelium_reprobe_connector(&data->display,
+ data->chamelium, port),
+ DRM_MODE_CONNECTED);
igt_cleanup_uevents(mon);
}
@@ -2561,7 +2451,9 @@ test_hpd_storm_detect(data_t *data, struct chamelium_port *port, int width)
int count = 0;
igt_require_hpd_storm_ctl(data->drm_fd);
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
igt_hpd_storm_set_threshold(data->drm_fd, 1);
chamelium_fire_hpd_pulses(data->chamelium, port, width, 10);
@@ -2589,7 +2481,9 @@ static void
test_hpd_storm_disable(data_t *data, struct chamelium_port *port, int width)
{
igt_require_hpd_storm_ctl(data->drm_fd);
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
igt_hpd_storm_set_threshold(data->drm_fd, 0);
chamelium_fire_hpd_pulses(data->chamelium, port,
@@ -2599,23 +2493,6 @@ test_hpd_storm_disable(data_t *data, struct chamelium_port *port, int width)
igt_hpd_storm_reset(data->drm_fd);
}
-static const struct edid *get_edid(enum test_edid edid)
-{
- switch (edid) {
- case TEST_EDID_BASE:
- return igt_kms_get_base_edid();
- case TEST_EDID_ALT:
- return igt_kms_get_alt_edid();
- case TEST_EDID_HDMI_AUDIO:
- return igt_kms_get_hdmi_audio_edid();
- case TEST_EDID_DP_AUDIO:
- return igt_kms_get_dp_audio_edid();
- case TEST_EDID_ASPECT_RATIO:
- return get_aspect_ratio_edid();
- }
- assert(0); /* unreachable */
-}
-
#define for_each_port(p, port) \
for (p = 0, port = data.ports[p]; \
p < data.port_count; \
@@ -2666,15 +2543,15 @@ igt_main
for (i = 0; i < TEST_EDID_COUNT; ++i) {
data.edids[i] = chamelium_new_edid(data.chamelium,
- get_edid(i));
+ chamelium_get_edid(i));
}
}
igt_describe("DisplayPort tests");
igt_subtest_group {
igt_fixture {
- require_connector_present(
- &data, DRM_MODE_CONNECTOR_DisplayPort);
+ chamelium_require_connector_present(data.ports, DRM_MODE_CONNECTOR_DisplayPort,
+ data.port_count, 1);
}
igt_describe(test_basic_hotplug_desc);
@@ -2782,8 +2659,8 @@ igt_main
igt_describe("HDMI tests");
igt_subtest_group {
igt_fixture {
- require_connector_present(
- &data, DRM_MODE_CONNECTOR_HDMIA);
+ chamelium_require_connector_present(data.ports, DRM_MODE_CONNECTOR_HDMIA,
+ data.port_count, 1);
}
igt_describe(test_basic_hotplug_desc);
@@ -2957,8 +2834,8 @@ igt_main
igt_describe("VGA tests");
igt_subtest_group {
igt_fixture {
- require_connector_present(
- &data, DRM_MODE_CONNECTOR_VGA);
+ chamelium_require_connector_present(data.ports, DRM_MODE_CONNECTOR_VGA,
+ data.port_count, 1);
}
igt_describe(test_basic_hotplug_desc);
--
2.25.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [igt-dev] [PATCH i-g-t v4 2/4] Added structures and functions to generate tiled edids
2020-09-20 18:28 [igt-dev] [PATCH i-g-t v4 0/4] Test tiled display with aid of chamelium Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 1/4] Make basic chamelium function accessible to other tests Kunal Joshi
@ 2020-09-20 18:28 ` Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 3/4] Added a subtest where chamelium acts as a tiled panel Kunal Joshi
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Kunal Joshi @ 2020-09-20 18:28 UTC (permalink / raw
To: igt-dev; +Cc: Kunal Joshi, petri.latvala
Generating the tiled edid which can be flashed on chamelium and added
some functions to support the same.
v2: No change.
v3: No change.
v4: No change.
Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Karthik B S <karthik.b.s@intel.com>
Reviewed-by: Navare Manasi D <manasi.d.navare@intel.com>
---
lib/igt_chamelium.c | 67 +++++++++++++++++++++++++++++
lib/igt_chamelium.h | 5 +++
lib/igt_edid.c | 27 ++++++++++++
lib/igt_edid.h | 20 +++++++++
lib/igt_kms.c | 102 ++++++++++++++++++++++++++++++++++++++++++++
lib/igt_kms.h | 2 +
6 files changed, 223 insertions(+)
diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index 0dddbe6f..d8c7bb6f 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -909,6 +909,33 @@ const struct edid *chamelium_edid_get_raw(struct chamelium_edid *edid,
return edid->raw[port_index];
}
+/**
+ * chamelium_edid_get_editable_raw: get the raw EDID which can be edited later.
+ * @edid: the Chamelium EDID
+ * @port: the Chamelium port
+ *
+ * The EDID provided to #chamelium_new_edid may be mutated for identification
+ * purposes. This function allows to retrieve the exact EDID that will be set
+ * for a given port.
+ *
+ * The returned raw EDID is only valid until the next call to this function.
+ */
+struct edid *chamelium_edid_get_editable_raw(struct chamelium_edid *edid,
+ struct chamelium_port *port)
+{
+ size_t port_index = port - edid->chamelium->ports;
+ size_t edid_size;
+
+ if (!edid->raw[port_index]) {
+ edid_size = edid_get_size(edid->base);
+ edid->raw[port_index] = malloc(edid_size);
+ memcpy(edid->raw[port_index], edid->base, edid_size);
+ chamelium_port_tag_edid(port, edid->raw[port_index]);
+ }
+
+ return edid->raw[port_index];
+}
+
/**
* chamelium_port_set_edid:
* @chamelium: The Chamelium instance to use
@@ -947,6 +974,46 @@ void chamelium_port_set_edid(struct chamelium *chamelium,
port->id, edid_id));
}
+/**
+ * chamelium_port_set_tiled_edid:
+ * @chamelium: The Chamelium instance to use
+ * @port: The port on the Chamelium to set the EDID on
+ * @edid: The Chamelium EDID to set or NULL to use the default Chamelium EDID
+ *
+ * Sets unique serial for tiled edid.
+ * Sets a port on the chamelium to use the specified EDID. This does not fire a
+ * hotplug pulse on it's own, and merely changes what EDID the chamelium port
+ * will report to us the next time we probe it. Users will need to reprobe the
+ * connectors themselves if they want to see the EDID reported by the port
+ * change.
+ *
+ * To create an EDID, see #chamelium_new_edid.
+ */
+void chamelium_port_set_tiled_edid(struct chamelium *chamelium,
+ struct chamelium_port *port,
+ struct chamelium_edid *edid)
+{
+ int edid_id;
+ size_t port_index;
+ struct edid *raw_edid;
+
+ if (edid) {
+ port_index = port - chamelium->ports;
+ edid_id = edid->ids[port_index];
+ if (edid_id == 0) {
+ raw_edid = chamelium_edid_get_editable_raw(edid, port);
+ raw_edid->serial[0] = 0x02;
+ base_edid_update_checksum(raw_edid);
+ edid_id = chamelium_upload_edid(chamelium, raw_edid);
+ edid->ids[port_index] = edid_id;
+ }
+ } else {
+ edid_id = 0;
+ }
+ xmlrpc_DECREF(chamelium_rpc(chamelium, NULL, "ApplyEdid", "(ii)",
+ port->id, edid_id));
+}
+
/**
* chamelium_port_set_ddc_state:
* @chamelium: The Chamelium instance to use
diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h
index bce6331d..13a5c607 100644
--- a/lib/igt_chamelium.h
+++ b/lib/igt_chamelium.h
@@ -175,9 +175,14 @@ const struct edid *chamelium_edid_get_raw(struct chamelium_edid *edid,
struct chamelium_port *port);
const struct edid *chamelium_get_aspect_ratio_edid(void);
const struct edid *chamelium_get_edid(enum test_edid edid);
+struct edid *chamelium_edid_get_editable_raw(struct chamelium_edid *edid,
+ struct chamelium_port *port);
void chamelium_port_set_edid(struct chamelium *chamelium,
struct chamelium_port *port,
struct chamelium_edid *edid);
+void chamelium_port_set_tiled_edid(struct chamelium *chamelium,
+ struct chamelium_port *port,
+ struct chamelium_edid *edid);
bool chamelium_port_get_ddc_state(struct chamelium *chamelium,
struct chamelium_port *port);
void chamelium_port_set_ddc_state(struct chamelium *chamelium,
diff --git a/lib/igt_edid.c b/lib/igt_edid.c
index 1c85486d..b6edde8d 100644
--- a/lib/igt_edid.c
+++ b/lib/igt_edid.c
@@ -313,9 +313,27 @@ void edid_update_checksum(struct edid *edid)
ext->data.cea.checksum =
compute_checksum((uint8_t *) ext,
sizeof(struct edid_ext));
+ else if (ext->tag == EDID_EXT_DISPLAYID) {
+ ext->data.tile.extension_checksum =
+ compute_checksum((uint8_t *) &ext->data.tile,
+ sizeof(struct edid_ext));
+ ext->data.tile.checksum =
+ compute_checksum((uint8_t *) ext,
+ sizeof(struct edid_ext));
+ }
}
}
+/**
+ * base_edid_update_checksum: compute and update the checksum of the main EDID
+ * block
+ */
+void base_edid_update_checksum(struct edid *edid)
+{
+ edid->checksum = compute_checksum((uint8_t *) edid,
+ sizeof(struct edid));
+}
+
/**
* edid_get_size: return the size of the EDID block in bytes including EDID
* extensions, if any.
@@ -458,6 +476,15 @@ size_t edid_cea_data_block_set_speaker_alloc(struct edid_cea_data_block *block,
return sizeof(struct edid_cea_data_block) + size;
}
+/**
+ * edid_ext_set_tile initialize an EDID extension block to be identified
+ * as a tiled display topology block
+ */
+void edid_ext_set_displayid(struct edid_ext *ext)
+{
+ ext->tag = EDID_EXT_DISPLAYID;
+}
+
/**
* edid_ext_set_cea: initialize an EDID extension block to contain a CEA
* extension. CEA extensions contain a Data Block Collection (with multiple
diff --git a/lib/igt_edid.h b/lib/igt_edid.h
index 59b47a97..7c2ce123 100644
--- a/lib/igt_edid.h
+++ b/lib/igt_edid.h
@@ -304,12 +304,30 @@ struct edid_cea {
enum edid_ext_tag {
EDID_EXT_CEA = 0x02,
+ EDID_EXT_DISPLAYID = 0x70,
+};
+
+struct edid_tile {
+ uint8_t header[7];
+ uint8_t tile_cap;
+ uint8_t topo[3];
+ uint8_t tile_size[4];
+ uint8_t tile_pixel_bezel[5];
+ uint8_t topology_id[9];
+ uint8_t data[96];
+ uint8_t extension_checksum;
+ uint8_t checksum;
+} __attribute__((packed));
+
+enum edid_tile_cap {
+ SCALE_TO_FIT = 0x82,
};
struct edid_ext {
uint8_t tag; /* enum edid_ext_tag */
union {
struct edid_cea cea;
+ struct edid_tile tile;
} data;
} __attribute__((packed));
@@ -356,6 +374,7 @@ struct edid {
void edid_init(struct edid *edid);
void edid_init_with_mode(struct edid *edid, drmModeModeInfo *mode);
void edid_update_checksum(struct edid *edid);
+void base_edid_update_checksum(struct edid *edid);
size_t edid_get_size(const struct edid *edid);
void edid_get_mfg(const struct edid *edid, char out[static 3]);
void detailed_timing_set_mode(struct detailed_timing *dt, drmModeModeInfo *mode,
@@ -383,4 +402,5 @@ size_t edid_cea_data_block_set_speaker_alloc(struct edid_cea_data_block *block,
void edid_ext_set_cea(struct edid_ext *ext, size_t data_blocks_size,
uint8_t num_native_dtds, uint8_t flags);
+void edid_ext_set_displayid(struct edid_ext *ext);
#endif
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index bffa4d94..163e8597 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -87,6 +87,9 @@
/* list of connectors that need resetting on exit */
#define MAX_CONNECTORS 32
+#define MAX_EDID 2
+#define DISPLAY_TILE_BLOCK 0x12
+
static struct {
uint32_t connector_type;
uint32_t connector_type_id;
@@ -129,6 +132,26 @@ const struct edid *igt_kms_get_base_edid(void)
return &edid;
}
+const struct edid *igt_kms_get_base_tile_edid(void)
+{
+ static struct edid edid;
+ drmModeModeInfo mode = {};
+
+ mode.clock = 277250;
+ mode.hdisplay = 1920;
+ mode.hsync_start = 1968;
+ mode.hsync_end = 2000;
+ mode.htotal = 2080;
+ mode.vdisplay = 2160;
+ mode.vsync_start = 2163;
+ mode.vsync_end = 2173;
+ mode.vtotal = 2222;
+ mode.vrefresh = 60;
+ edid_init_with_mode(&edid, &mode);
+ edid_update_checksum(&edid);
+ return &edid;
+}
+
/**
* igt_kms_get_alt_edid:
*
@@ -264,6 +287,85 @@ const struct edid *igt_kms_get_dp_audio_edid(void)
return generate_audio_edid(raw_edid, false, &sad, &speaker_alloc);
}
+struct edid **igt_kms_get_tiled_edid(uint8_t htile, uint8_t vtile)
+{
+ uint8_t top[2];
+ int edids, i;
+ static char raw_edid[MAX_EDID][256] = {0};
+ static struct edid *edid[MAX_EDID];
+
+ top[0] = 0x00;
+ top[1] = 0x00;
+ top[0] = top[0] | (htile<<4);
+ vtile = vtile & 15;
+ top[0] = top[0] | vtile;
+ top[1] = top[1] | ((htile << 2) & 192);
+ top[1] = top[1] | (vtile & 48);
+
+ edids = (htile+1) * (vtile+1);
+
+ for (i = 0; i < edids; i++)
+ edid[i] = (struct edid *) raw_edid[i];
+
+ for (i = 0; i < edids; i++) {
+
+ struct edid_ext *edid_ext;
+ struct edid_tile *edid_tile;
+
+ /* Create a new EDID from the base IGT EDID, and add an
+ * extension that advertises tile support.
+ */
+ memcpy(edid[i],
+ igt_kms_get_base_tile_edid(), sizeof(struct edid));
+ edid[i]->extensions_len = 1;
+ edid_ext = &edid[i]->extensions[0];
+ edid_tile = &edid_ext->data.tile;
+ /* Set 0x70 to 1st byte of extension,
+ * so it is identified as display block
+ */
+ edid_ext_set_displayid(edid_ext);
+ /* To identify it as a tiled display block extension */
+ edid_tile->header[0] = DISPLAY_TILE_BLOCK;
+ edid_tile->header[1] = 0x79;
+ edid_tile->header[2] = 0x00;
+ edid_tile->header[3] = 0x00;
+ edid_tile->header[4] = 0x12;
+ edid_tile->header[5] = 0x00;
+ edid_tile->header[6] = 0x16;
+ /* Tile Capabilities */
+ edid_tile->tile_cap = SCALE_TO_FIT;
+ /* Set number of htile and vtile */
+ edid_tile->topo[0] = top[0];
+ if (i == 0)
+ edid_tile->topo[1] = 0x10;
+ else if (i == 1)
+ edid_tile->topo[1] = 0x00;
+ edid_tile->topo[2] = top[1];
+ /* Set tile resolution */
+ edid_tile->tile_size[0] = 0x7f;
+ edid_tile->tile_size[1] = 0x07;
+ edid_tile->tile_size[2] = 0x6f;
+ edid_tile->tile_size[3] = 0x08;
+ /* Dimension of Bezels */
+ edid_tile->tile_pixel_bezel[0] = 0;
+ edid_tile->tile_pixel_bezel[1] = 0;
+ edid_tile->tile_pixel_bezel[2] = 0;
+ edid_tile->tile_pixel_bezel[3] = 0;
+ edid_tile->tile_pixel_bezel[4] = 0;
+ /* Manufacturer Information */
+ edid_tile->topology_id[0] = 0x44;
+ edid_tile->topology_id[1] = 0x45;
+ edid_tile->topology_id[2] = 0x4c;
+ edid_tile->topology_id[3] = 0x43;
+ edid_tile->topology_id[4] = 0x48;
+ edid_tile->topology_id[5] = 0x02;
+ edid_tile->topology_id[6] = 0x00;
+ edid_tile->topology_id[7] = 0x00;
+ edid_tile->topology_id[8] = 0x00;
+ }
+ return edid;
+}
+
static const uint8_t edid_4k_svds[] = {
32 | CEA_SVD_NATIVE, /* 1080p @ 24Hz (native) */
5, /* 1080i @ 60Hz */
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 9ffad56e..cadee7a7 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -788,6 +788,8 @@ const struct edid *igt_kms_get_hdmi_audio_edid(void);
const struct edid *igt_kms_get_dp_audio_edid(void);
const struct edid *igt_kms_get_4k_edid(void);
const struct edid *igt_kms_get_3d_edid(void);
+const struct edid *igt_kms_get_base_tile_edid(void);
+struct edid **igt_kms_get_tiled_edid(uint8_t htile, uint8_t vtile);
struct udev_monitor *igt_watch_uevents(void);
bool igt_hotplug_detected(struct udev_monitor *mon,
--
2.25.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [igt-dev] [PATCH i-g-t v4 3/4] Added a subtest where chamelium acts as a tiled panel
2020-09-20 18:28 [igt-dev] [PATCH i-g-t v4 0/4] Test tiled display with aid of chamelium Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 1/4] Make basic chamelium function accessible to other tests Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 2/4] Added structures and functions to generate tiled edids Kunal Joshi
@ 2020-09-20 18:28 ` Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 4/4] HAX: Run in BAT Kunal Joshi
2020-09-20 18:31 ` [igt-dev] ✗ Fi.CI.BUILD: failure for Test tiled display with aid of chamelium. (rev4) Patchwork
4 siblings, 0 replies; 8+ messages in thread
From: Kunal Joshi @ 2020-09-20 18:28 UTC (permalink / raw
To: igt-dev; +Cc: Kunal Joshi, petri.latvala
Split kms_dp_tiled_display into to two subtest.First to execute the
basic test with physical tiled panel and second with chamelium.
v2: Revised to just have basic test if chamelium dependencies are not present.
Reset ports after the test executes.Changed subtest name from with-chamelium
to basic-test-pattern-with-chamelium
v3: Changes required to adapt to changes done in first patch.
v4: Changes required to adapt to changes done in first patch.
Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Karthik B S <karthik.b.s@intel.com>
Reviewed-by: Navare Manasi D <manasi.d.navare@intel.com>
---
tests/kms_dp_tiled_display.c | 119 ++++++++++++++++++++++++++++-------
1 file changed, 95 insertions(+), 24 deletions(-)
diff --git a/tests/kms_dp_tiled_display.c b/tests/kms_dp_tiled_display.c
index b1160fee..98f6a07e 100644
--- a/tests/kms_dp_tiled_display.c
+++ b/tests/kms_dp_tiled_display.c
@@ -40,6 +40,7 @@
#include "poll.h"
#include "drm_mode.h"
#include "drm_fourcc.h"
+#include "igt_edid.h"
IGT_TEST_DESCRIPTION("Test for Transcoder Port Sync for Display Port Tiled Displays");
@@ -59,8 +60,22 @@ typedef struct {
data_connector_t *conns;
enum igt_commit_style commit;
struct timeval first_ts;
+
+ #ifdef HAVE_CHAMELIUM
+ struct chamelium *chamelium;
+ struct chamelium_port **ports;
+ int port_count;
+ struct chamelium_edid *edids[TEST_EDID_COUNT];
+ #endif
+
} data_t;
+void basic_test(data_t *data, drmEventContext *drm_event, struct pollfd *pfd);
+
+#ifdef HAVE_CHAMELIUM
+static void test_with_chamelium(data_t *data);
+#endif
+
static int drm_property_is_tile(drmModePropertyPtr prop)
{
return (strcmp(prop->name, "TILE") ? 0 : 1) &&
@@ -206,7 +221,6 @@ static void test_cleanup(data_t *data)
igt_display_commit2(data->display, data->commit);
memset(conns, 0, sizeof(data_connector_t) * data->num_h_tiles);
}
-
static void setup_mode(data_t *data)
{
int count = 0, prev = 0, i = 0;
@@ -380,21 +394,83 @@ static bool got_all_page_flips(data_t *data)
return true;
}
+#ifdef HAVE_CHAMELIUM
+static void test_with_chamelium(data_t *data)
+{
+ int i, count = 0;
+ uint8_t htile = 2, vtile = 1;
+ struct edid **edid;
+
+ data->chamelium = chamelium_init(data->drm_fd);
+ igt_assert(data->chamelium);
+ data->ports = chamelium_get_ports
+ (data->chamelium, &data->port_count);
+ chamelium_require_connector_present(data->ports,
+ DRM_MODE_CONNECTOR_DisplayPort,
+ data->port_count, 2);
+ edid = igt_kms_get_tiled_edid(htile-1, vtile-1);
+
+ for (i = 0; i < 2; i++)
+ data->edids[i] =
+ chamelium_new_edid(data->chamelium, edid[i]);
+
+ for (i = 0; i < data->port_count; i++) {
+ if (chamelium_port_get_type(data->ports[i]) ==
+ DRM_MODE_CONNECTOR_DisplayPort) {
+
+ chamelium_port_set_tiled_edid(data->chamelium,
+ data->ports[i], data->edids[i]);
+ chamelium_plug(data->chamelium,
+ data->ports[i]);
+ chamelium_wait_for_conn_status_change(data->display,
+ data->chamelium,
+ data->ports[i],
+ DRM_MODE_CONNECTED);
+ count++;
+ }
+ if (count == 2)
+ break;
+ }
+}
+#endif
+
+void basic_test(data_t *data, drmEventContext *drm_event, struct pollfd *pfd)
+{
+ int ret;
+
+ get_number_of_h_tiles(data);
+ igt_debug("Number of Horizontal Tiles: %d\n",
+ data->num_h_tiles);
+ igt_require(data->num_h_tiles > 0);
+ data->conns = calloc(data->num_h_tiles,
+ sizeof(data_connector_t));
+ igt_assert(data->conns);
+
+ get_connectors(data);
+ setup_mode(data);
+ setup_framebuffer(data);
+ timerclear(&data->first_ts);
+ igt_display_commit_atomic(data->display,
+ DRM_MODE_ATOMIC_NONBLOCK |
+ DRM_MODE_PAGE_FLIP_EVENT, data);
+ while (!got_all_page_flips(data)) {
+ ret = poll(pfd, 1, 1000);
+ igt_assert(ret == 1);
+ drmHandleEvent(data->drm_fd, drm_event);
+ }
+}
+
igt_main
{
igt_display_t display;
data_t data = {0};
struct pollfd pfd = {0};
drmEventContext drm_event = {0};
- int ret;
-
igt_fixture {
data.drm_fd = drm_open_driver_master(DRIVER_ANY);
-
kmstest_set_vt_graphics_mode();
igt_display_require(&display, data.drm_fd);
igt_display_reset(&display);
-
data.display = &display;
pfd.fd = data.drm_fd;
pfd.events = POLLIN;
@@ -402,33 +478,28 @@ igt_main
drm_event.page_flip_handler2 = page_flip_handler;
data.commit = data.display->is_atomic ? COMMIT_ATOMIC : COMMIT_LEGACY;
igt_require(data.commit == COMMIT_ATOMIC);
-
- get_number_of_h_tiles(&data);
- igt_debug("Number of Horizontal Tiles: %d\n", data.num_h_tiles);
- igt_require(data.num_h_tiles > 0);
- data.conns = calloc(data.num_h_tiles, sizeof(data_connector_t));
}
igt_describe("Make sure the Tiled CRTCs are synchronized and we get "
"page flips for all tiled CRTCs in one vblank.");
igt_subtest("basic-test-pattern") {
- igt_assert(data.conns);
-
- get_connectors(&data);
- setup_mode(&data);
- setup_framebuffer(&data);
- timerclear(&data.first_ts);
- igt_display_commit_atomic(data.display, DRM_MODE_ATOMIC_NONBLOCK |
- DRM_MODE_PAGE_FLIP_EVENT, &data);
- while (!got_all_page_flips(&data)) {
- ret = poll(&pfd, 1, 1000);
- igt_assert(ret == 1);
- drmHandleEvent(data.drm_fd, &drm_event);
- }
-
+ basic_test(&data, &drm_event, &pfd);
test_cleanup(&data);
}
+ #ifdef HAVE_CHAMELIUM
+ igt_subtest_f("basic-test-pattern-with-chamelium") {
+ int i;
+
+ test_with_chamelium(&data);
+ basic_test(&data, &drm_event, &pfd);
+ test_cleanup(&data);
+ for (i = 0; i < data.port_count; i++)
+ chamelium_reset_state(data.display, data.chamelium,
+ data.ports[i], data.ports,
+ data.port_count);
+ }
+ #endif
igt_fixture {
free(data.conns);
close(data.drm_fd);
--
2.25.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [igt-dev] [PATCH i-g-t v4 4/4] HAX: Run in BAT
2020-09-20 18:28 [igt-dev] [PATCH i-g-t v4 0/4] Test tiled display with aid of chamelium Kunal Joshi
` (2 preceding siblings ...)
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 3/4] Added a subtest where chamelium acts as a tiled panel Kunal Joshi
@ 2020-09-20 18:28 ` Kunal Joshi
2020-09-20 18:31 ` [igt-dev] ✗ Fi.CI.BUILD: failure for Test tiled display with aid of chamelium. (rev4) Patchwork
4 siblings, 0 replies; 8+ messages in thread
From: Kunal Joshi @ 2020-09-20 18:28 UTC (permalink / raw
To: igt-dev; +Cc: Kunal Joshi, petri.latvala
BAT run to test the patch, not for merge
Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
---
tests/intel-ci/fast-feedback.testlist | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/intel-ci/fast-feedback.testlist b/tests/intel-ci/fast-feedback.testlist
index b98cdb24..fef23fb5 100644
--- a/tests/intel-ci/fast-feedback.testlist
+++ b/tests/intel-ci/fast-feedback.testlist
@@ -83,6 +83,7 @@ igt@kms_addfb_basic@unused-modifier
igt@kms_addfb_basic@unused-offsets
igt@kms_addfb_basic@unused-pitches
igt@kms_busy@basic
+igt@kms_dp_tiled_display@basic-test-pattern-with-chamelium
igt@kms_chamelium@dp-hpd-fast
igt@kms_chamelium@dp-edid-read
igt@kms_chamelium@dp-crc-fast
--
2.25.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [igt-dev] ✗ Fi.CI.BUILD: failure for Test tiled display with aid of chamelium. (rev4)
2020-09-20 18:28 [igt-dev] [PATCH i-g-t v4 0/4] Test tiled display with aid of chamelium Kunal Joshi
` (3 preceding siblings ...)
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 4/4] HAX: Run in BAT Kunal Joshi
@ 2020-09-20 18:31 ` Patchwork
4 siblings, 0 replies; 8+ messages in thread
From: Patchwork @ 2020-09-20 18:31 UTC (permalink / raw
To: Kunal Joshi; +Cc: igt-dev
== Series Details ==
Series: Test tiled display with aid of chamelium. (rev4)
URL : https://patchwork.freedesktop.org/series/71393/
State : failure
== Summary ==
Applying: Make basic chamelium function accessible to other tests
Using index info to reconstruct a base tree...
M lib/igt_kms.c
M lib/igt_kms.h
Falling back to patching base and 3-way merge...
Auto-merging lib/igt_kms.h
CONFLICT (content): Merge conflict in lib/igt_kms.h
Auto-merging lib/igt_kms.c
Patch failed at 0001 Make basic chamelium function accessible to other tests
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 8+ messages in thread
* [igt-dev] [PATCH i-g-t v4 1/4] Make basic chamelium function accessible to other tests
2020-09-20 18:56 [igt-dev] [PATCH i-g-t v4 0/4] Test tiled display with aid of chamelium Kunal Joshi
@ 2020-09-20 18:56 ` Kunal Joshi
2020-09-21 8:01 ` Petri Latvala
0 siblings, 1 reply; 8+ messages in thread
From: Kunal Joshi @ 2020-09-20 18:56 UTC (permalink / raw
To: igt-dev; +Cc: Kunal Joshi, petri.latvala
There are many use case where we can integrate chamelium with other tests,
Migrating some of basic chamelium functions to igt_chamelium lib to avoid
Code rewriting.
v2: Moved one more function reset_state from tests/kms_chamelium to
lib/igt_chamelium.
v3: - Shifted disabling of modeset to igt_kms
- Replace connection_str with kmstest_connector_status_str (Petri)
- Generalized require__connector_present (Petri)
- Avoided using data_chamelium_t struct (Petri)
v4: - Moved function to library (Petri)
- Renamed some functions and added documentation (Petri)
Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
Signed-off-by: Karthik B S <karthik.b.s@intel.com>
---
lib/igt_chamelium.c | 186 ++++++++++++++++++++++++++++
lib/igt_chamelium.h | 40 ++++++
lib/igt_kms.c | 23 ++++
lib/igt_kms.h | 1 +
tests/kms_chamelium.c | 281 ++++++++++++------------------------------
5 files changed, 329 insertions(+), 202 deletions(-)
diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index d9fab902..0dddbe6f 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -218,6 +218,137 @@ const char *chamelium_port_get_name(struct chamelium_port *port)
return port->name;
}
+/**
+ * chamelium_require_connector_present
+ * @ports: All connected ports
+ * @type: Required port type
+ * @port_count: Total port count
+ * @count: The required number of port count
+ *
+ * Check there are required ports connected of given type
+ */
+void
+chamelium_require_connector_present(struct chamelium_port **ports,
+ unsigned int type,
+ int port_count,
+ int count)
+{
+ int i;
+ int found = 0;
+
+ for (i = 0; i < port_count; i++) {
+ if (chamelium_port_get_type(ports[i]) == type)
+ found++;
+ }
+
+ igt_require_f(found == count,
+ "port of type %s found %d and required %d\n",
+ kmstest_connector_type_str(type), found, count);
+}
+
+/**
+ * chamelium_reprobe_connector
+ * @display: A pointer to an #igt_display_t structure
+ * @chamelium: The Chamelium instance to use
+ * @port: Chamelium port to reprobe
+ *
+ * Reprobe the given connector and fetch current status
+ *
+ * Returns: drmModeConnection
+ */
+drmModeConnection
+chamelium_reprobe_connector(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port)
+{
+ drmModeConnector *connector;
+ drmModeConnection status;
+ igt_output_t *output;
+
+ igt_debug("Reprobing %s...\n", chamelium_port_get_name(port));
+ connector = chamelium_port_get_connector(chamelium, port, true);
+ igt_assert(connector);
+ status = connector->connection;
+
+ /* let's make sure that igt_display is up to date too */
+ output = igt_output_from_connector(display, connector);
+ output->force_reprobe = true;
+ igt_output_refresh(output);
+
+ drmModeFreeConnector(connector);
+ return status;
+}
+
+/**
+ * chamelium_wait_for_conn_status_change
+ * @display: A pointer to an #igt_display_t structure
+ * @chamelium: The Chamelium instance to use
+ * @port: Chamelium port to check connector status update
+ * @status: Enum which describes connector states
+ *
+ * Wait for the connector to change the status
+ */
+void
+chamelium_wait_for_conn_status_change(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port,
+ drmModeConnection status)
+{
+ igt_debug("Waiting for %s to get %s...\n",
+ chamelium_port_get_name(port),
+ kmstest_connector_status_str(status));
+
+ /*
+ * Rely on simple reprobing so we don't fail tests that don't require
+ * that hpd events work in the event that hpd doesn't work on the system
+ */
+ igt_until_timeout(HOTPLUG_TIMEOUT) {
+ if (chamelium_reprobe_connector(display,
+ chamelium, port) == status)
+ return;
+
+ usleep(50000);
+ }
+
+ igt_assert_f(false, "Timed out waiting for %s to get %s\n",
+ chamelium_port_get_name(port),
+ kmstest_connector_status_str(status));
+}
+
+/**
+ * chamelium_reset_state
+ *
+ * @chamelium: The Chamelium instance to use
+ * @port: Chamelium port to reset
+ * @ports: All connected ports
+ * @port_count: Count of connected ports
+ *
+ * Reset chamelium ports
+ */
+void
+chamelium_reset_state(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port,
+ struct chamelium_port **ports,
+ int port_count)
+{
+ int p;
+
+ chamelium_reset(chamelium);
+
+ if (port) {
+ chamelium_wait_for_conn_status_change(display, chamelium,
+ port,
+ DRM_MODE_DISCONNECTED);
+ } else {
+ for (p = 0; p < port_count; p++) {
+ port = ports[p];
+ chamelium_wait_for_conn_status_change(display, chamelium,
+ port, DRM_MODE_DISCONNECTED);
+ }
+ }
+}
+
/**
* chamelium_destroy_frame_dump:
* @dump: The frame dump to destroy
@@ -627,6 +758,61 @@ void chamelium_schedule_hpd_toggle(struct chamelium *chamelium,
"(iii)", port->id, delay_ms, rising_edge));
}
+const struct edid *chamelium_get_aspect_ratio_edid(void)
+{
+ static unsigned char raw_edid[2 * EDID_BLOCK_SIZE] = {0};
+ struct edid *edid;
+ struct edid_ext *edid_ext;
+ struct edid_cea *edid_cea;
+ char *cea_data;
+ struct edid_cea_data_block *block;
+ size_t cea_data_size = 0, vsdb_size;
+ const struct cea_vsdb *vsdb;
+
+ 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;
+
+ /* The HDMI VSDB advertises support for InfoFrames */
+ block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
+ vsdb = cea_vsdb_get_hdmi_default(&vsdb_size);
+ cea_data_size += edid_cea_data_block_set_vsdb(block, vsdb,
+ vsdb_size);
+
+ /* 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_ar_svds,
+ sizeof(edid_ar_svds));
+
+ assert(cea_data_size <= sizeof(edid_cea->data));
+
+ edid_ext_set_cea(edid_ext, cea_data_size, 0, 0);
+
+ edid_update_checksum(edid);
+
+ return edid;
+}
+
+const struct edid *chamelium_get_edid(enum test_edid edid)
+{
+ switch (edid) {
+ case TEST_EDID_BASE:
+ return igt_kms_get_base_edid();
+ case TEST_EDID_ALT:
+ return igt_kms_get_alt_edid();
+ case TEST_EDID_HDMI_AUDIO:
+ return igt_kms_get_hdmi_audio_edid();
+ case TEST_EDID_DP_AUDIO:
+ return igt_kms_get_dp_audio_edid();
+ case TEST_EDID_ASPECT_RATIO:
+ return chamelium_get_aspect_ratio_edid();
+ }
+ assert(0); /* unreachable */
+}
+
static int chamelium_upload_edid(struct chamelium *chamelium,
const struct edid *edid)
{
diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h
index 359f4ab3..bce6331d 100644
--- a/lib/igt_chamelium.h
+++ b/lib/igt_chamelium.h
@@ -32,6 +32,7 @@
#include <xf86drmMode.h>
#include "igt_debugfs.h"
+#include "igt_kms.h"
struct igt_fb;
struct edid;
@@ -73,6 +74,16 @@ enum chamelium_infoframe_type {
CHAMELIUM_INFOFRAME_VENDOR,
};
+enum test_edid {
+ TEST_EDID_BASE,
+ TEST_EDID_ALT,
+ TEST_EDID_HDMI_AUDIO,
+ TEST_EDID_DP_AUDIO,
+ TEST_EDID_ASPECT_RATIO,
+};
+#define TEST_EDID_COUNT 5
+
+
struct chamelium_infoframe {
int version;
size_t payload_size;
@@ -81,6 +92,11 @@ struct chamelium_infoframe {
struct chamelium_edid;
+/* Set of Video Identification Codes advertised in the EDID */
+static const uint8_t edid_ar_svds[] = {
+ 16, /* 1080p @ 60Hz, 16:9 */
+};
+
/**
* CHAMELIUM_MAX_PORTS: the maximum number of ports supported by igt_chamelium.
*
@@ -100,6 +116,8 @@ struct chamelium_edid;
*/
#define CHAMELIUM_MAX_AUDIO_CHANNELS 8
+#define HOTPLUG_TIMEOUT 20 /* seconds */
+
void chamelium_deinit_rpc_only(struct chamelium *chamelium);
struct chamelium *chamelium_init_rpc_only(void);
struct chamelium *chamelium_init(int drm_fd);
@@ -113,6 +131,26 @@ drmModeConnector *chamelium_port_get_connector(struct chamelium *chamelium,
struct chamelium_port *port,
bool reprobe);
const char *chamelium_port_get_name(struct chamelium_port *port);
+void
+chamelium_require_connector_present(struct chamelium_port **ports,
+ unsigned int type,
+ int port_count,
+ int count);
+drmModeConnection
+chamelium_reprobe_connector(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port);
+void
+chamelium_wait_for_conn_status_change(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port,
+ drmModeConnection status);
+void
+chamelium_reset_state(igt_display_t *display,
+ struct chamelium *chamelium,
+ struct chamelium_port *port,
+ struct chamelium_port **ports,
+ int port_count);
bool chamelium_wait_reachable(struct chamelium *chamelium, int timeout);
void chamelium_assert_reachable(struct chamelium *chamelium, int timeout);
@@ -135,6 +173,8 @@ struct chamelium_edid *chamelium_new_edid(struct chamelium *chamelium,
const struct edid *edid);
const struct edid *chamelium_edid_get_raw(struct chamelium_edid *edid,
struct chamelium_port *port);
+const struct edid *chamelium_get_aspect_ratio_edid(void);
+const struct edid *chamelium_get_edid(enum test_edid edid);
void chamelium_port_set_edid(struct chamelium *chamelium,
struct chamelium_port *port,
struct chamelium_edid *edid);
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 4023811a..1c9aa4d1 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2269,6 +2269,29 @@ const drmModeModeInfo *igt_std_1024_mode_get(void)
return &std_1024_mode;
}
+/*
+ * igt_modeset_disable_all_outputs
+ * @diplay: igt display structure
+ *
+ * Modeset to disable all output
+ *
+ * We need to do a modeset disabling all output to get the next
+ * HPD event on TypeC port
+ */
+void igt_modeset_disable_all_outputs(igt_display_t *display)
+{
+ int i;
+
+ for (i = 0; i < display->n_outputs; i++) {
+ igt_output_t *output = &display->outputs[i];
+
+ igt_output_set_pipe(output, PIPE_NONE);
+ }
+
+ igt_display_commit2(display, COMMIT_ATOMIC);
+
+}
+
static void igt_pipe_fini(igt_pipe_t *pipe)
{
free(pipe->planes);
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index f41eadaf..aaeedd45 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -445,6 +445,7 @@ igt_output_t *igt_output_from_connector(igt_display_t *display,
void igt_output_refresh(igt_output_t *output);
const drmModeModeInfo *igt_std_1024_mode_get(void);
void igt_output_set_writeback_fb(igt_output_t *output, struct igt_fb *fb);
+void igt_modeset_disable_all_outputs(igt_display_t *display);
igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
int igt_pipe_count_plane_type(igt_pipe_t *pipe, int plane_type);
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index e1c81e01..9de5f47e 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -36,15 +36,6 @@
#include <string.h>
#include <stdatomic.h>
-enum test_edid {
- TEST_EDID_BASE,
- TEST_EDID_ALT,
- TEST_EDID_HDMI_AUDIO,
- TEST_EDID_DP_AUDIO,
- TEST_EDID_ASPECT_RATIO,
-};
-#define TEST_EDID_COUNT 5
-
enum test_modeset_mode {
TEST_MODESET_ON,
TEST_MODESET_ON_OFF,
@@ -62,7 +53,6 @@ typedef struct {
struct chamelium_edid *edids[TEST_EDID_COUNT];
} data_t;
-#define HOTPLUG_TIMEOUT 20 /* seconds */
#define ONLINE_TIMEOUT 20 /* seconds */
#define HPD_STORM_PULSE_INTERVAL_DP 100 /* ms */
@@ -97,78 +87,6 @@ get_connectors_link_status_failed(data_t *data, bool *link_status_failed)
}
}
-static void
-require_connector_present(data_t *data, unsigned int type)
-{
- int i;
- bool found = false;
-
- for (i = 0; i < data->port_count && !found; i++) {
- if (chamelium_port_get_type(data->ports[i]) == type)
- found = true;
- }
-
- igt_require_f(found, "No port of type %s was found\n",
- kmstest_connector_type_str(type));
-}
-
-static drmModeConnection
-reprobe_connector(data_t *data, struct chamelium_port *port)
-{
- drmModeConnector *connector;
- drmModeConnection status;
- igt_output_t *output;
-
- igt_debug("Reprobing %s...\n", chamelium_port_get_name(port));
- connector = chamelium_port_get_connector(data->chamelium, port, true);
- igt_assert(connector);
- status = connector->connection;
-
- /* let's make sure that igt_display is up to date too */
- output = igt_output_from_connector(&data->display, connector);
- output->force_reprobe = true;
- igt_output_refresh(output);
-
- drmModeFreeConnector(connector);
- return status;
-}
-
-static const char *connection_str(drmModeConnection c)
-{
- switch (c) {
- case DRM_MODE_CONNECTED:
- return "connected";
- case DRM_MODE_DISCONNECTED:
- return "disconnected";
- case DRM_MODE_UNKNOWNCONNECTION:
- return "unknown";
- }
- assert(0); /* unreachable */
-}
-
-static void
-wait_for_connector(data_t *data, struct chamelium_port *port,
- drmModeConnection status)
-{
- igt_debug("Waiting for %s to get %s...\n",
- chamelium_port_get_name(port), connection_str(status));
-
- /*
- * Rely on simple reprobing so we don't fail tests that don't require
- * that hpd events work in the event that hpd doesn't work on the system
- */
- igt_until_timeout(HOTPLUG_TIMEOUT) {
- if (reprobe_connector(data, port) == status) {
- return;
- }
-
- usleep(50000);
- }
-
- igt_assert_f(false, "Timed out waiting for %s to get %s\n",
- chamelium_port_get_name(port), connection_str(status));
-}
-
/* Wait for hotplug and return the remaining time left from timeout */
static bool wait_for_hotplug(struct udev_monitor *mon, int *timeout)
{
@@ -196,7 +114,8 @@ wait_for_connector_after_hotplug(data_t *data, struct udev_monitor *mon,
int hotplug_count = 0;
igt_debug("Waiting for %s to get %s after a hotplug event...\n",
- chamelium_port_get_name(port), connection_str(status));
+ chamelium_port_get_name(port),
+ kmstest_connector_status_str(status));
while (timeout > 0) {
if (!wait_for_hotplug(mon, &timeout))
@@ -204,13 +123,15 @@ wait_for_connector_after_hotplug(data_t *data, struct udev_monitor *mon,
hotplug_count++;
- if (reprobe_connector(data, port) == status)
+ if (chamelium_reprobe_connector(&data->display, data->chamelium,
+ port) == status)
return;
}
igt_assert_f(false, "Timed out waiting for %s to get %s after a hotplug. Current state %s hotplug_count %d\n",
- chamelium_port_get_name(port), connection_str(status),
- connection_str(reprobe_connector(data, port)), hotplug_count);
+ chamelium_port_get_name(port),
+ kmstest_connector_status_str(status),
+ kmstest_connector_status_str(chamelium_reprobe_connector(&data->display, data->chamelium, port)), hotplug_count);
}
@@ -282,30 +203,6 @@ check_analog_bridge(data_t *data, struct chamelium_port *port)
return false;
}
-static void
-reset_state(data_t *data, struct chamelium_port *port)
-{
- int p, i;
-
- for (i = 0; i < data->display.n_outputs; i++) {
- igt_output_t *output = &data->display.outputs[i];
- igt_output_set_pipe(output, PIPE_NONE);
- }
-
- igt_display_commit2(&data->display, COMMIT_ATOMIC);
-
- chamelium_reset(data->chamelium);
-
- if (port) {
- wait_for_connector(data, port, DRM_MODE_DISCONNECTED);
- } else {
- for (p = 0; p < data->port_count; p++) {
- port = data->ports[p];
- wait_for_connector(data, port, DRM_MODE_DISCONNECTED);
- }
- }
-}
-
static void chamelium_paint_xr24_pattern(uint32_t *data,
size_t width, size_t height,
size_t stride, size_t block_size)
@@ -441,7 +338,11 @@ test_hotplug(data_t *data, struct chamelium_port *port, int toggle_count,
struct udev_monitor *mon = igt_watch_uevents();
igt_output_t *output = get_output_for_port(data, port);
- reset_state(data, NULL);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium, NULL,
+ data->ports, data->port_count);
+
+
igt_hpd_storm_set_threshold(data->drm_fd, 0);
for (i = 0; i < toggle_count; i++) {
@@ -486,8 +387,6 @@ test_hotplug(data_t *data, struct chamelium_port *port, int toggle_count,
igt_remove_fb(data->drm_fd, &fb);
}
-static const struct edid *get_edid(enum test_edid edid);
-
static void set_edid(data_t *data, struct chamelium_port *port,
enum test_edid edid)
{
@@ -506,11 +405,14 @@ test_edid_read(data_t *data, struct chamelium_port *port, enum test_edid edid)
const struct edid *raw_edid;
uint64_t edid_blob_id;
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
set_edid(data, port, edid);
chamelium_plug(data->chamelium, port);
- wait_for_connector(data, port, DRM_MODE_CONNECTED);
+ chamelium_wait_for_conn_status_change(&data->display, data->chamelium,
+ port, DRM_MODE_CONNECTED);
igt_skip_on(check_analog_bridge(data, port));
@@ -562,7 +464,10 @@ try_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
chamelium_assert_reachable(data->chamelium, ONLINE_TIMEOUT);
if (port) {
- igt_assert_eq(reprobe_connector(data, port), target_state);
+ igt_assert_eq(chamelium_reprobe_connector(&data->display,
+ data->chamelium,
+ port),
+ target_state);
} else {
for (p = 0; p < data->port_count; p++) {
drmModeConnection current_state;
@@ -575,10 +480,10 @@ try_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
* the expected connector state try to wait for an HPD
* event for each connector/port.
*/
- current_state = reprobe_connector(data, port);
+ current_state = chamelium_reprobe_connector(&data->display, data->chamelium, port);
if (p > 0 && current_state != target_state) {
igt_assert(wait_for_hotplug(mon, &timeout));
- current_state = reprobe_connector(data, port);
+ current_state = chamelium_reprobe_connector(&data->display, data->chamelium, port);
}
igt_assert_eq(current_state, target_state);
@@ -598,7 +503,9 @@ test_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
{
struct udev_monitor *mon = igt_watch_uevents();
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/* Make sure we notice new connectors after resuming */
try_suspend_resume_hpd(data, port, state, test, mon, false);
@@ -625,7 +532,9 @@ test_suspend_resume_hpd_common(data_t *data, enum igt_suspend_state state,
igt_debug("Testing port %s\n", chamelium_port_get_name(port));
}
- reset_state(data, NULL);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium, NULL,
+ data->ports, data->port_count);
/* Make sure we notice new connectors after resuming */
try_suspend_resume_hpd(data, NULL, state, test, mon, false);
@@ -651,7 +560,9 @@ test_suspend_resume_edid_change(data_t *data, struct chamelium_port *port,
bool link_status_failed[2][data->port_count];
int p;
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/* Catch the event and flush all remaining ones. */
igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
@@ -662,7 +573,8 @@ test_suspend_resume_edid_change(data_t *data, struct chamelium_port *port,
chamelium_plug(data->chamelium, port);
igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
- wait_for_connector(data, port, DRM_MODE_CONNECTED);
+ chamelium_wait_for_conn_status_change(&data->display, data->chamelium,
+ port, DRM_MODE_CONNECTED);
/*
* Change the edid before we suspend. On resume, the machine should
@@ -698,7 +610,8 @@ prepare_output(data_t *data, struct chamelium_port *port, enum test_edid edid)
set_edid(data, port, edid);
chamelium_plug(data->chamelium, port);
- wait_for_connector(data, port, DRM_MODE_CONNECTED);
+ chamelium_wait_for_conn_status_change(&data->display, data->chamelium,
+ port, DRM_MODE_CONNECTED);
igt_display_reset(display);
@@ -796,7 +709,9 @@ static void test_display_one_mode(data_t *data, struct chamelium_port *port,
igt_output_t *output;
igt_plane_t *primary;
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
output = prepare_output(data, port, TEST_EDID_BASE);
connector = chamelium_port_get_connector(data->chamelium, port, false);
@@ -841,7 +756,9 @@ static void test_display_all_modes(data_t *data, struct chamelium_port *port,
* let's reset state each mode so we will get the
* HPD pulses realibably
*/
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/*
* modes may change due to mode pruining and link issues, so we
@@ -897,7 +814,9 @@ test_display_frame_dump(data_t *data, struct chamelium_port *port)
* let's reset state each mode so we will get the
* HPD pulses realibably
*/
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/*
* modes may change due to mode pruining and link issues, so we
@@ -1034,7 +953,9 @@ static void test_mode_timings(data_t *data, struct chamelium_port *port)
* let's reset state each mode so we will get the
* HPD pulses realibably
*/
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/*
* modes may change due to mode pruining and link issues, so we
@@ -1071,11 +992,6 @@ static void test_mode_timings(data_t *data, struct chamelium_port *port)
} while (++i < count_modes);
}
-/* Set of Video Identification Codes advertised in the EDID */
-static const uint8_t edid_ar_svds[] = {
- 16, /* 1080p @ 60Hz, 16:9 */
-};
-
struct vic_mode {
int hactive, vactive;
int vrefresh; /* Hz */
@@ -1122,44 +1038,6 @@ static bool vic_mode_matches_drm(const struct vic_mode *vic_mode,
ar_flag == (drm_mode->flags & DRM_MODE_FLAG_PIC_AR_MASK);
}
-static const struct edid *get_aspect_ratio_edid(void)
-{
- static unsigned char raw_edid[2 * EDID_BLOCK_SIZE] = {0};
- struct edid *edid;
- struct edid_ext *edid_ext;
- struct edid_cea *edid_cea;
- char *cea_data;
- struct edid_cea_data_block *block;
- size_t cea_data_size = 0, vsdb_size;
- const struct cea_vsdb *vsdb;
-
- 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;
-
- /* The HDMI VSDB advertises support for InfoFrames */
- block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
- vsdb = cea_vsdb_get_hdmi_default(&vsdb_size);
- cea_data_size += edid_cea_data_block_set_vsdb(block, vsdb,
- vsdb_size);
-
- /* 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_ar_svds,
- sizeof(edid_ar_svds));
-
- assert(cea_data_size <= sizeof(edid_cea->data));
-
- edid_ext_set_cea(edid_ext, cea_data_size, 0, 0);
-
- edid_update_checksum(edid);
-
- return edid;
-}
-
static const char test_display_aspect_ratio_desc[] =
"Pick a mode with a picture aspect-ratio, capture AVI InfoFrames and "
"check they include the relevant fields";
@@ -1181,7 +1059,9 @@ static void test_display_aspect_ratio(data_t *data, struct chamelium_port *port)
igt_require(chamelium_supports_get_last_infoframe(data->chamelium));
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
output = prepare_output(data, port, TEST_EDID_ASPECT_RATIO);
connector = chamelium_port_get_connector(data->chamelium, port, false);
@@ -1911,7 +1791,9 @@ test_display_audio(data_t *data, struct chamelium_port *port,
alsa = alsa_init();
igt_assert(alsa);
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
output = prepare_output(data, port, edid);
connector = chamelium_port_get_connector(data->chamelium, port, false);
@@ -1992,7 +1874,9 @@ test_display_audio_edid(data_t *data, struct chamelium_port *port,
igt_require(eld_is_supported());
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
output = prepare_output(data, port, edid);
connector = chamelium_port_get_connector(data->chamelium, port, false);
@@ -2432,7 +2316,9 @@ static void test_display_planes_random(data_t *data,
srand(time(NULL));
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
/* Find the connector and pipe. */
output = prepare_output(data, port, TEST_EDID_BASE);
@@ -2535,7 +2421,9 @@ test_hpd_without_ddc(data_t *data, struct chamelium_port *port)
{
struct udev_monitor *mon = igt_watch_uevents();
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
igt_flush_uevents(mon);
/* Disable the DDC on the connector and make sure we still get a
@@ -2545,7 +2433,9 @@ test_hpd_without_ddc(data_t *data, struct chamelium_port *port)
chamelium_plug(data->chamelium, port);
igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
- igt_assert_eq(reprobe_connector(data, port), DRM_MODE_CONNECTED);
+ igt_assert_eq(chamelium_reprobe_connector(&data->display,
+ data->chamelium, port),
+ DRM_MODE_CONNECTED);
igt_cleanup_uevents(mon);
}
@@ -2561,7 +2451,9 @@ test_hpd_storm_detect(data_t *data, struct chamelium_port *port, int width)
int count = 0;
igt_require_hpd_storm_ctl(data->drm_fd);
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
igt_hpd_storm_set_threshold(data->drm_fd, 1);
chamelium_fire_hpd_pulses(data->chamelium, port, width, 10);
@@ -2589,7 +2481,9 @@ static void
test_hpd_storm_disable(data_t *data, struct chamelium_port *port, int width)
{
igt_require_hpd_storm_ctl(data->drm_fd);
- reset_state(data, port);
+ igt_modeset_disable_all_outputs(&data->display);
+ chamelium_reset_state(&data->display, data->chamelium,
+ port, data->ports, data->port_count);
igt_hpd_storm_set_threshold(data->drm_fd, 0);
chamelium_fire_hpd_pulses(data->chamelium, port,
@@ -2599,23 +2493,6 @@ test_hpd_storm_disable(data_t *data, struct chamelium_port *port, int width)
igt_hpd_storm_reset(data->drm_fd);
}
-static const struct edid *get_edid(enum test_edid edid)
-{
- switch (edid) {
- case TEST_EDID_BASE:
- return igt_kms_get_base_edid();
- case TEST_EDID_ALT:
- return igt_kms_get_alt_edid();
- case TEST_EDID_HDMI_AUDIO:
- return igt_kms_get_hdmi_audio_edid();
- case TEST_EDID_DP_AUDIO:
- return igt_kms_get_dp_audio_edid();
- case TEST_EDID_ASPECT_RATIO:
- return get_aspect_ratio_edid();
- }
- assert(0); /* unreachable */
-}
-
#define for_each_port(p, port) \
for (p = 0, port = data.ports[p]; \
p < data.port_count; \
@@ -2666,15 +2543,15 @@ igt_main
for (i = 0; i < TEST_EDID_COUNT; ++i) {
data.edids[i] = chamelium_new_edid(data.chamelium,
- get_edid(i));
+ chamelium_get_edid(i));
}
}
igt_describe("DisplayPort tests");
igt_subtest_group {
igt_fixture {
- require_connector_present(
- &data, DRM_MODE_CONNECTOR_DisplayPort);
+ chamelium_require_connector_present(data.ports, DRM_MODE_CONNECTOR_DisplayPort,
+ data.port_count, 1);
}
igt_describe(test_basic_hotplug_desc);
@@ -2782,8 +2659,8 @@ igt_main
igt_describe("HDMI tests");
igt_subtest_group {
igt_fixture {
- require_connector_present(
- &data, DRM_MODE_CONNECTOR_HDMIA);
+ chamelium_require_connector_present(data.ports, DRM_MODE_CONNECTOR_HDMIA,
+ data.port_count, 1);
}
igt_describe(test_basic_hotplug_desc);
@@ -2957,8 +2834,8 @@ igt_main
igt_describe("VGA tests");
igt_subtest_group {
igt_fixture {
- require_connector_present(
- &data, DRM_MODE_CONNECTOR_VGA);
+ chamelium_require_connector_present(data.ports, DRM_MODE_CONNECTOR_VGA,
+ data.port_count, 1);
}
igt_describe(test_basic_hotplug_desc);
--
2.25.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [igt-dev] [PATCH i-g-t v4 1/4] Make basic chamelium function accessible to other tests
2020-09-20 18:56 ` [igt-dev] [PATCH i-g-t v4 1/4] Make basic chamelium function accessible to other tests Kunal Joshi
@ 2020-09-21 8:01 ` Petri Latvala
0 siblings, 0 replies; 8+ messages in thread
From: Petri Latvala @ 2020-09-21 8:01 UTC (permalink / raw
To: Kunal Joshi; +Cc: igt-dev
On Mon, Sep 21, 2020 at 12:26:12AM +0530, Kunal Joshi wrote:
> There are many use case where we can integrate chamelium with other tests,
> Migrating some of basic chamelium functions to igt_chamelium lib to avoid
> Code rewriting.
>
> v2: Moved one more function reset_state from tests/kms_chamelium to
> lib/igt_chamelium.
>
> v3: - Shifted disabling of modeset to igt_kms
> - Replace connection_str with kmstest_connector_status_str (Petri)
> - Generalized require__connector_present (Petri)
> - Avoided using data_chamelium_t struct (Petri)
>
> v4: - Moved function to library (Petri)
> - Renamed some functions and added documentation (Petri)
>
> Signed-off-by: Kunal Joshi <kunal1.joshi@intel.com>
> Signed-off-by: Karthik B S <karthik.b.s@intel.com>
> ---
> lib/igt_chamelium.c | 186 ++++++++++++++++++++++++++++
> lib/igt_chamelium.h | 40 ++++++
> lib/igt_kms.c | 23 ++++
> lib/igt_kms.h | 1 +
> tests/kms_chamelium.c | 281 ++++++++++++------------------------------
> 5 files changed, 329 insertions(+), 202 deletions(-)
>
> diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
> index d9fab902..0dddbe6f 100644
> --- a/lib/igt_chamelium.c
> +++ b/lib/igt_chamelium.c
> @@ -218,6 +218,137 @@ const char *chamelium_port_get_name(struct chamelium_port *port)
> return port->name;
> }
>
> +/**
> + * chamelium_require_connector_present
> + * @ports: All connected ports
> + * @type: Required port type
> + * @port_count: Total port count
> + * @count: The required number of port count
> + *
> + * Check there are required ports connected of given type
> + */
> +void
> +chamelium_require_connector_present(struct chamelium_port **ports,
> + unsigned int type,
> + int port_count,
> + int count)
> +{
> + int i;
> + int found = 0;
> +
> + for (i = 0; i < port_count; i++) {
> + if (chamelium_port_get_type(ports[i]) == type)
> + found++;
> + }
> +
> + igt_require_f(found == count,
> + "port of type %s found %d and required %d\n",
> + kmstest_connector_type_str(type), found, count);
> +}
> +
> +/**
> + * chamelium_reprobe_connector
> + * @display: A pointer to an #igt_display_t structure
> + * @chamelium: The Chamelium instance to use
> + * @port: Chamelium port to reprobe
> + *
> + * Reprobe the given connector and fetch current status
> + *
> + * Returns: drmModeConnection
> + */
> +drmModeConnection
> +chamelium_reprobe_connector(igt_display_t *display,
> + struct chamelium *chamelium,
> + struct chamelium_port *port)
> +{
> + drmModeConnector *connector;
> + drmModeConnection status;
> + igt_output_t *output;
> +
> + igt_debug("Reprobing %s...\n", chamelium_port_get_name(port));
> + connector = chamelium_port_get_connector(chamelium, port, true);
> + igt_assert(connector);
> + status = connector->connection;
> +
> + /* let's make sure that igt_display is up to date too */
> + output = igt_output_from_connector(display, connector);
> + output->force_reprobe = true;
> + igt_output_refresh(output);
> +
> + drmModeFreeConnector(connector);
> + return status;
> +}
> +
> +/**
> + * chamelium_wait_for_conn_status_change
> + * @display: A pointer to an #igt_display_t structure
> + * @chamelium: The Chamelium instance to use
> + * @port: Chamelium port to check connector status update
> + * @status: Enum which describes connector states
> + *
> + * Wait for the connector to change the status
> + */
> +void
> +chamelium_wait_for_conn_status_change(igt_display_t *display,
> + struct chamelium *chamelium,
> + struct chamelium_port *port,
> + drmModeConnection status)
> +{
> + igt_debug("Waiting for %s to get %s...\n",
> + chamelium_port_get_name(port),
> + kmstest_connector_status_str(status));
> +
> + /*
> + * Rely on simple reprobing so we don't fail tests that don't require
> + * that hpd events work in the event that hpd doesn't work on the system
> + */
> + igt_until_timeout(HOTPLUG_TIMEOUT) {
> + if (chamelium_reprobe_connector(display,
> + chamelium, port) == status)
> + return;
> +
> + usleep(50000);
> + }
> +
> + igt_assert_f(false, "Timed out waiting for %s to get %s\n",
> + chamelium_port_get_name(port),
> + kmstest_connector_status_str(status));
> +}
> +
> +/**
> + * chamelium_reset_state
> + *
> + * @chamelium: The Chamelium instance to use
> + * @port: Chamelium port to reset
> + * @ports: All connected ports
> + * @port_count: Count of connected ports
> + *
> + * Reset chamelium ports
> + */
> +void
> +chamelium_reset_state(igt_display_t *display,
> + struct chamelium *chamelium,
> + struct chamelium_port *port,
> + struct chamelium_port **ports,
> + int port_count)
> +{
> + int p;
> +
> + chamelium_reset(chamelium);
> +
> + if (port) {
> + chamelium_wait_for_conn_status_change(display, chamelium,
> + port,
> + DRM_MODE_DISCONNECTED);
> + } else {
> + for (p = 0; p < port_count; p++) {
> + port = ports[p];
> + chamelium_wait_for_conn_status_change(display, chamelium,
> + port, DRM_MODE_DISCONNECTED);
> + }
> + }
> +}
> +
> /**
> * chamelium_destroy_frame_dump:
> * @dump: The frame dump to destroy
> @@ -627,6 +758,61 @@ void chamelium_schedule_hpd_toggle(struct chamelium *chamelium,
> "(iii)", port->id, delay_ms, rising_edge));
> }
>
> +const struct edid *chamelium_get_aspect_ratio_edid(void)
> +{
> + static unsigned char raw_edid[2 * EDID_BLOCK_SIZE] = {0};
> + struct edid *edid;
> + struct edid_ext *edid_ext;
> + struct edid_cea *edid_cea;
> + char *cea_data;
> + struct edid_cea_data_block *block;
> + size_t cea_data_size = 0, vsdb_size;
> + const struct cea_vsdb *vsdb;
> +
> + 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;
> +
> + /* The HDMI VSDB advertises support for InfoFrames */
> + block = (struct edid_cea_data_block *) &cea_data[cea_data_size];
> + vsdb = cea_vsdb_get_hdmi_default(&vsdb_size);
> + cea_data_size += edid_cea_data_block_set_vsdb(block, vsdb,
> + vsdb_size);
> +
> + /* 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_ar_svds,
> + sizeof(edid_ar_svds));
> +
> + assert(cea_data_size <= sizeof(edid_cea->data));
> +
> + edid_ext_set_cea(edid_ext, cea_data_size, 0, 0);
> +
> + edid_update_checksum(edid);
> +
> + return edid;
> +}
Hmm, is there anything actually chamelium-specific for this edid?
> +
> +const struct edid *chamelium_get_edid(enum test_edid edid)
> +{
> + switch (edid) {
> + case TEST_EDID_BASE:
> + return igt_kms_get_base_edid();
> + case TEST_EDID_ALT:
> + return igt_kms_get_alt_edid();
> + case TEST_EDID_HDMI_AUDIO:
> + return igt_kms_get_hdmi_audio_edid();
> + case TEST_EDID_DP_AUDIO:
> + return igt_kms_get_dp_audio_edid();
> + case TEST_EDID_ASPECT_RATIO:
> + return chamelium_get_aspect_ratio_edid();
> + }
> + assert(0); /* unreachable */
> +}
Same here, doesn't look like chamelium-specific. Documentation for
both functions would be lovely as well.
Maybe igt_kms_get_aspect_ratio_edid and igt_kms_get_edid for the
names? Or igt_kms_get_special_edid. igt_kms_get_custom_edid?
Naturally if they're indeed not chamelium-specific, their place is
igt_kms.[ch] instead.
> +
> static int chamelium_upload_edid(struct chamelium *chamelium,
> const struct edid *edid)
> {
> diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h
> index 359f4ab3..bce6331d 100644
> --- a/lib/igt_chamelium.h
> +++ b/lib/igt_chamelium.h
> @@ -32,6 +32,7 @@
> #include <xf86drmMode.h>
>
> #include "igt_debugfs.h"
> +#include "igt_kms.h"
>
> struct igt_fb;
> struct edid;
> @@ -73,6 +74,16 @@ enum chamelium_infoframe_type {
> CHAMELIUM_INFOFRAME_VENDOR,
> };
>
> +enum test_edid {
> + TEST_EDID_BASE,
> + TEST_EDID_ALT,
> + TEST_EDID_HDMI_AUDIO,
> + TEST_EDID_DP_AUDIO,
> + TEST_EDID_ASPECT_RATIO,
> +};
> +#define TEST_EDID_COUNT 5
Name of enum and the prefix are too generic. enum
igt_custom_edid_type? IGT_CUSTOM_EDID_<type>?
Documentation for this enum is needed too, to explain that it's used
with igt_get_custom_edid or whatever it ends up called in the end.
> +
> +
> struct chamelium_infoframe {
> int version;
> size_t payload_size;
> @@ -81,6 +92,11 @@ struct chamelium_infoframe {
>
> struct chamelium_edid;
>
> +/* Set of Video Identification Codes advertised in the EDID */
> +static const uint8_t edid_ar_svds[] = {
> + 16, /* 1080p @ 60Hz, 16:9 */
> +};
> +
> /**
> * CHAMELIUM_MAX_PORTS: the maximum number of ports supported by igt_chamelium.
> *
> @@ -100,6 +116,8 @@ struct chamelium_edid;
> */
> #define CHAMELIUM_MAX_AUDIO_CHANNELS 8
>
> +#define HOTPLUG_TIMEOUT 20 /* seconds */
CHAMELIUM_HOTPLUG_TIMEOUT maybe? Oh, but is this even needed here in
the header, is it only used in the reprobe function?
--
Petri Latvala
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-09-21 8:01 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-09-20 18:28 [igt-dev] [PATCH i-g-t v4 0/4] Test tiled display with aid of chamelium Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 1/4] Make basic chamelium function accessible to other tests Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 2/4] Added structures and functions to generate tiled edids Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 3/4] Added a subtest where chamelium acts as a tiled panel Kunal Joshi
2020-09-20 18:28 ` [igt-dev] [PATCH i-g-t v4 4/4] HAX: Run in BAT Kunal Joshi
2020-09-20 18:31 ` [igt-dev] ✗ Fi.CI.BUILD: failure for Test tiled display with aid of chamelium. (rev4) Patchwork
-- strict thread matches above, loose matches on Subject: below --
2020-09-20 18:56 [igt-dev] [PATCH i-g-t v4 0/4] Test tiled display with aid of chamelium Kunal Joshi
2020-09-20 18:56 ` [igt-dev] [PATCH i-g-t v4 1/4] Make basic chamelium function accessible to other tests Kunal Joshi
2020-09-21 8:01 ` Petri Latvala
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.