[PATCH v6 20/23] modetest: Support pipes with multiple connectors

2013-06-15 Thread Laurent Pinchart
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

2013-06-14 Thread Laurent Pinchart
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;
+
+