[PATCH v6 20/23] modetest: Support pipes with multiple connectors
The -s argument can now take a list of connectors. Configure all of them in cloned mode using a single CRTC. Signed-off-by: Laurent Pinchart --- tests/modetest/modetest.c | 211 ++ 1 file changed, 157 insertions(+), 54 deletions(-) diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 922d9b0..450c86d 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -40,6 +40,7 @@ #include "config.h" #include +#include #include #include #include @@ -634,6 +635,34 @@ error: return NULL; } +static drmModeConnector *get_connector_by_id(struct device *dev, uint32_t id) +{ + drmModeConnector *connector; + int i; + + for (i = 0; i < dev->resources->res->count_connectors; i++) { + connector = dev->resources->connectors[i].connector; + if (connector && connector->connector_id == id) + return connector; + } + + return NULL; +} + +static drmModeEncoder *get_encoder_by_id(struct device *dev, uint32_t id) +{ + drmModeEncoder *encoder; + int i; + + for (i = 0; i < dev->resources->res->count_encoders; i++) { + encoder = dev->resources->encoders[i].encoder; + if (encoder && encoder->encoder_id == id) + return encoder; + } + + return NULL; +} + /* - * Pipes and planes */ @@ -646,7 +675,8 @@ error: * can bind it with a free crtc. */ struct pipe_arg { - uint32_t con_id; + uint32_t *con_ids; + unsigned int num_cons; uint32_t crtc_id; char mode_str[64]; char format_str[5]; @@ -669,69 +699,114 @@ struct plane_arg { unsigned int fourcc; }; -static void pipe_find_mode(struct device *dev, struct pipe_arg *pipe) +static drmModeModeInfo * +connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str) { drmModeConnector *connector; - drmModeEncoder *encoder; - int i, j; + drmModeModeInfo *mode; + int i; - /* First, find the connector & mode */ - pipe->mode = NULL; - for (i = 0; i < dev->resources->res->count_connectors; i++) { - connector = dev->resources->connectors[i].connector; + connector = get_connector_by_id(dev, con_id); + if (!connector || !connector->count_modes) + return NULL; + + for (i = 0; i < connector->count_modes; i++) { + mode = >modes[i]; + if (!strcmp(mode->name, mode_str)) + return mode; + } + + return NULL; +} + +static struct crtc *pipe_find_crtc(struct device *dev, struct pipe_arg *pipe) +{ + uint32_t possible_crtcs = ~0; + uint32_t active_crtcs = 0; + unsigned int crtc_idx; + unsigned int i; + int j; + + for (i = 0; i < pipe->num_cons; ++i) { + drmModeConnector *connector; + drmModeEncoder *encoder; + + connector = get_connector_by_id(dev, pipe->con_ids[i]); if (!connector) - continue; + return NULL; - if (!connector->count_modes) - continue; + encoder = get_encoder_by_id(dev, connector->encoder_id); + if (!encoder) + return NULL; - if (connector->connector_id != pipe->con_id) - continue; + possible_crtcs &= encoder->possible_crtcs; - for (j = 0; j < connector->count_modes; j++) { - pipe->mode = >modes[j]; - if (!strcmp(pipe->mode->name, pipe->mode_str)) + for (j = 0; j < dev->resources->res->count_crtcs; ++j) { + drmModeCrtc *crtc = dev->resources->crtcs[j].crtc; + if (crtc && crtc->crtc_id == encoder->crtc_id) { + active_crtcs |= 1 << j; break; + } } - - /* Found it, break out */ - if (pipe->mode) - break; } - if (!pipe->mode) { - fprintf(stderr, "failed to find mode \"%s\"\n", pipe->mode_str); - return; + if (!possible_crtcs) + return NULL; + + /* Return the first possible and active CRTC if one exists, or the first +* possible CRTC otherwise. +*/ + if (possible_crtcs & active_crtcs) + crtc_idx = ffs(possible_crtcs & active_crtcs); + else + crtc_idx = ffs(possible_crtcs); + + return >resources->crtcs[crtc_idx - 1]; +} + +static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe) +{ + drmModeModeInfo *mode; + int i; + + pipe->mode = NULL; + +
[PATCH v6 20/23] modetest: Support pipes with multiple connectors
The -s argument can now take a list of connectors. Configure all of them in cloned mode using a single CRTC. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- tests/modetest/modetest.c | 211 ++ 1 file changed, 157 insertions(+), 54 deletions(-) diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 922d9b0..450c86d 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -40,6 +40,7 @@ #include config.h #include assert.h +#include ctype.h #include stdbool.h #include stdio.h #include stdlib.h @@ -634,6 +635,34 @@ error: return NULL; } +static drmModeConnector *get_connector_by_id(struct device *dev, uint32_t id) +{ + drmModeConnector *connector; + int i; + + for (i = 0; i dev-resources-res-count_connectors; i++) { + connector = dev-resources-connectors[i].connector; + if (connector connector-connector_id == id) + return connector; + } + + return NULL; +} + +static drmModeEncoder *get_encoder_by_id(struct device *dev, uint32_t id) +{ + drmModeEncoder *encoder; + int i; + + for (i = 0; i dev-resources-res-count_encoders; i++) { + encoder = dev-resources-encoders[i].encoder; + if (encoder encoder-encoder_id == id) + return encoder; + } + + return NULL; +} + /* - * Pipes and planes */ @@ -646,7 +675,8 @@ error: * can bind it with a free crtc. */ struct pipe_arg { - uint32_t con_id; + uint32_t *con_ids; + unsigned int num_cons; uint32_t crtc_id; char mode_str[64]; char format_str[5]; @@ -669,69 +699,114 @@ struct plane_arg { unsigned int fourcc; }; -static void pipe_find_mode(struct device *dev, struct pipe_arg *pipe) +static drmModeModeInfo * +connector_find_mode(struct device *dev, uint32_t con_id, const char *mode_str) { drmModeConnector *connector; - drmModeEncoder *encoder; - int i, j; + drmModeModeInfo *mode; + int i; - /* First, find the connector mode */ - pipe-mode = NULL; - for (i = 0; i dev-resources-res-count_connectors; i++) { - connector = dev-resources-connectors[i].connector; + connector = get_connector_by_id(dev, con_id); + if (!connector || !connector-count_modes) + return NULL; + + for (i = 0; i connector-count_modes; i++) { + mode = connector-modes[i]; + if (!strcmp(mode-name, mode_str)) + return mode; + } + + return NULL; +} + +static struct crtc *pipe_find_crtc(struct device *dev, struct pipe_arg *pipe) +{ + uint32_t possible_crtcs = ~0; + uint32_t active_crtcs = 0; + unsigned int crtc_idx; + unsigned int i; + int j; + + for (i = 0; i pipe-num_cons; ++i) { + drmModeConnector *connector; + drmModeEncoder *encoder; + + connector = get_connector_by_id(dev, pipe-con_ids[i]); if (!connector) - continue; + return NULL; - if (!connector-count_modes) - continue; + encoder = get_encoder_by_id(dev, connector-encoder_id); + if (!encoder) + return NULL; - if (connector-connector_id != pipe-con_id) - continue; + possible_crtcs = encoder-possible_crtcs; - for (j = 0; j connector-count_modes; j++) { - pipe-mode = connector-modes[j]; - if (!strcmp(pipe-mode-name, pipe-mode_str)) + for (j = 0; j dev-resources-res-count_crtcs; ++j) { + drmModeCrtc *crtc = dev-resources-crtcs[j].crtc; + if (crtc crtc-crtc_id == encoder-crtc_id) { + active_crtcs |= 1 j; break; + } } - - /* Found it, break out */ - if (pipe-mode) - break; } - if (!pipe-mode) { - fprintf(stderr, failed to find mode \%s\\n, pipe-mode_str); - return; + if (!possible_crtcs) + return NULL; + + /* Return the first possible and active CRTC if one exists, or the first +* possible CRTC otherwise. +*/ + if (possible_crtcs active_crtcs) + crtc_idx = ffs(possible_crtcs active_crtcs); + else + crtc_idx = ffs(possible_crtcs); + + return dev-resources-crtcs[crtc_idx - 1]; +} + +static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe) +{ + drmModeModeInfo *mode; + int i; + +