Skip to content
Snippets Groups Projects
Commit fdbafce2 authored by Mark Yacoub's avatar Mark Yacoub Committed by Mark Yacoub
Browse files

Chamelium: Handle getting port connector if it's MST.


[Why]
When getting a connector for a port, the connector ID might be invalid
after a replug if it's an MST connector. Getting the connector with just
the connector ID will not always work.

[How]
Check if the connector is MST by checking the port's connector path.
If it is, iterate through all connectors until a connector with a
matching path is found.

TEST=./kms_chamelium --run-subtest dp-hpd [on intel Volteer board with
Chamelium V3 connected]

Signed-off-by: default avatarMark Yacoub <markyacoub@chromium.org>
Reviewed-by: Lyude Paul's avatarLyude Paul <lyude@redhat.com>
parent 8312a2fe
No related branches found
No related tags found
No related merge requests found
...@@ -182,6 +182,20 @@ unsigned int chamelium_port_get_type(const struct chamelium_port *port) { ...@@ -182,6 +182,20 @@ unsigned int chamelium_port_get_type(const struct chamelium_port *port) {
return port->type; return port->type;
} }
/**
* chamelium_port_get_name:
* @port: The chamelium port to retrieve the name of
*
* Gets the name of the DRM connector corresponding to the given Chamelium
* port.
*
* Returns: the name of the DRM connector
*/
const char *chamelium_port_get_name(struct chamelium_port *port)
{
return port->name;
}
/** /**
* chamelium_port_get_connector: * chamelium_port_get_connector:
* @chamelium: The Chamelium instance to use * @chamelium: The Chamelium instance to use
...@@ -197,30 +211,79 @@ drmModeConnector *chamelium_port_get_connector(struct chamelium *chamelium, ...@@ -197,30 +211,79 @@ drmModeConnector *chamelium_port_get_connector(struct chamelium *chamelium,
struct chamelium_port *port, struct chamelium_port *port,
bool reprobe) bool reprobe)
{ {
drmModeConnector *connector; typedef drmModeConnectorPtr (*getConnectorPtr)(int fd,
uint32_t connector_id);
if (reprobe) drmModeRes *res = NULL;
connector = drmModeGetConnector(chamelium->drm_fd, int i;
port->connector_id);
else
connector = drmModeGetConnectorCurrent(
chamelium->drm_fd, port->connector_id);
return connector; bool is_mst_port = !!port->connector_path;
} getConnectorPtr getConnector = reprobe ? &drmModeGetConnector :
&drmModeGetConnectorCurrent;
int drm_fd = chamelium->drm_fd;
drmModeConnector *connector = getConnector(drm_fd, port->connector_id);
/** /* If the port isn't MST, then the connector ID should be consistent to grab the connector. */
* chamelium_port_get_name: if (!is_mst_port) {
* @port: The chamelium port to retrieve the name of return connector;
* }
* Gets the name of the DRM connector corresponding to the given Chamelium
* port. /* If the port is MST, then we need to find the connector ID from the path. */
*
* Returns: the name of the DRM connector /* In case the connector ID is still valid, do a quick check if we're have the connector we expect.
*/ * Otherwise, read the new resources and find the new connector we're looking for. */
const char *chamelium_port_get_name(struct chamelium_port *port) if (connector) {
{ drmModePropertyBlobPtr path_blob =
return port->name; kmstest_get_path_blob(drm_fd, connector->connector_id);
if (path_blob) {
bool is_correct_connector =
strcmp(port->connector_path, path_blob->data) ==
0;
drmModeFreePropertyBlob(path_blob);
if (is_correct_connector)
return connector;
}
drmModeFreeConnector(connector);
connector = NULL;
}
res = drmModeGetResources(drm_fd);
for (i = 0; i < res->count_connectors; i++) {
drmModePropertyBlobPtr path_blob = NULL;
connector = getConnector(drm_fd, res->connectors[i]);
/* Check if the connector is not disconnected and in zombie mode. */
if (!connector)
continue;
/* Check if the connector is MST. */
path_blob =
kmstest_get_path_blob(drm_fd, connector->connector_id);
if (!path_blob)
continue;
if (strcmp(path_blob->data, port->connector_path) == 0) {
char connector_name[50];
/* At finding the connector, update its metadata. */
port->connector_id = connector->connector_id;
snprintf(connector_name, 50, "%s-%u",
kmstest_connector_type_str(
connector->connector_type),
connector->connector_type_id);
port->name = strdup(connector_name);
goto out;
}
drmModeFreePropertyBlob(path_blob);
drmModeFreeConnector(connector);
connector = NULL;
}
out:
drmModeFreeResources(res);
return connector;
} }
/** /**
...@@ -2862,7 +2925,7 @@ struct chamelium *chamelium_init(int drm_fd) ...@@ -2862,7 +2925,7 @@ struct chamelium *chamelium_init(int drm_fd)
bool type_mismatch = false; bool type_mismatch = false;
struct chamelium_port * port = &chamelium->ports[i]; struct chamelium_port * port = &chamelium->ports[i];
drmModeConnectorPtr connector = drmModeConnectorPtr connector =
drmModeGetConnectorCurrent(drm_fd, port->connector_id); chamelium_port_get_connector(chamelium, port, false);
igt_assert(connector != NULL); igt_assert(connector != NULL);
......
...@@ -1786,6 +1786,22 @@ bool kmstest_get_connector_config(int drm_fd, uint32_t connector_id, ...@@ -1786,6 +1786,22 @@ bool kmstest_get_connector_config(int drm_fd, uint32_t connector_id,
config, 0); config, 0);
} }
drmModePropertyBlobPtr kmstest_get_path_blob(int drm_fd, uint32_t connector_id)
{
uint64_t path_blob_id = 0;
drmModePropertyBlobPtr path_blob = NULL;
if (!kmstest_get_property(drm_fd, connector_id,
DRM_MODE_OBJECT_CONNECTOR, "PATH", NULL,
&path_blob_id, NULL)) {
return NULL;
}
path_blob = drmModeGetPropertyBlob(drm_fd, path_blob_id);
igt_assert(path_blob);
return path_blob;
}
/** /**
* kmstest_probe_connector_config: * kmstest_probe_connector_config:
* @drm_fd: DRM fd * @drm_fd: DRM fd
......
...@@ -234,6 +234,7 @@ bool kmstest_get_connector_default_mode(int drm_fd, drmModeConnector *connector, ...@@ -234,6 +234,7 @@ bool kmstest_get_connector_default_mode(int drm_fd, drmModeConnector *connector,
bool kmstest_get_connector_config(int drm_fd, uint32_t connector_id, bool kmstest_get_connector_config(int drm_fd, uint32_t connector_id,
unsigned long crtc_idx_mask, unsigned long crtc_idx_mask,
struct kmstest_connector_config *config); struct kmstest_connector_config *config);
drmModePropertyBlobPtr kmstest_get_path_blob(int drm_fd, uint32_t connector_id);
bool kmstest_probe_connector_config(int drm_fd, uint32_t connector_id, bool kmstest_probe_connector_config(int drm_fd, uint32_t connector_id,
unsigned long crtc_idx_mask, unsigned long crtc_idx_mask,
struct kmstest_connector_config *config); struct kmstest_connector_config *config);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment