Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
To: igt-dev@lists.freedesktop.org
Subject: [igt-dev] [PATCH i-g-t 1/5] lib/igt_kms: Add functions to get only a single output for a pipe.
Date: Wed, 14 Mar 2018 12:20:17 +0100	[thread overview]
Message-ID: <20180314112021.60224-2-maarten.lankhorst@linux.intel.com> (raw)
In-Reply-To: <20180314112021.60224-1-maarten.lankhorst@linux.intel.com>

igt_get_single_output_for_pipe() will give a valid output for a pipe,
for_each_pipe_with_single_output will iterate over all pipes, and
will be called for each pipe with an output once.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
 lib/igt_kms.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_kms.h | 26 +++++++++++++++++
 2 files changed, 119 insertions(+)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 6bac4d1fae50..1313ef12ebc5 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -2195,6 +2195,99 @@ igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type)
 	return &pipe->planes[plane_idx];
 }
 
+static bool output_is_internal_panel(igt_output_t *output)
+{
+	switch (output->config.connector->connector_type) {
+	case DRM_MODE_CONNECTOR_LVDS:
+	case DRM_MODE_CONNECTOR_eDP:
+	case DRM_MODE_CONNECTOR_DSI:
+	case DRM_MODE_CONNECTOR_DPI:
+		return true;
+	default:
+		return false;
+	}
+}
+
+igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display, igt_output_t **chosen_outputs)
+{
+	unsigned full_pipe_mask = (1 << (display->n_pipes)) - 1, assigned_pipes = 0;
+	igt_output_t *output;
+	int i, j;
+
+	memset(chosen_outputs, 0, sizeof(*chosen_outputs) * display->n_pipes);
+
+	/*
+	 * Try to assign all outputs to the first available CRTC for
+	 * it, start with the outputs restricted to 1 pipe, then increase
+	 * number of pipes until we assign connectors to all pipes.
+	 */
+	for (i = 0; i <= display->n_pipes; i++) {
+		for_each_connected_output(display, output) {
+			uint32_t pipe_mask = output->config.valid_crtc_idx_mask & full_pipe_mask;
+			bool found = false;
+
+			if (output_is_internal_panel(output)) {
+				/*
+				 * Internal panel should be assigned to pipe A
+				 * if possible, so make sure they're enumerated
+				 * first.
+				 */
+
+				if (i)
+					continue;
+			} else if (__builtin_popcount(pipe_mask) != i)
+				continue;
+
+			for (j = 0; j < display->n_pipes; j++) {
+				bool pipe_assigned = assigned_pipes & (1 << j);
+
+				if (pipe_assigned || !(pipe_mask & (1 << j)))
+					continue;
+
+				if (!found) {
+					/* We found an unassigned pipe, use it! */
+					found = true;
+					assigned_pipes |= 1 << j;
+					chosen_outputs[j] = output;
+				} else if (!chosen_outputs[j] ||
+					   /*
+					    * Overwrite internal panel if not assigned,
+					    * external outputs are faster to do modesets
+					    */
+					   output_is_internal_panel(chosen_outputs[j]))
+					chosen_outputs[j] = output;
+			}
+
+			if (!found)
+				igt_warn("Output %s could not be assigned to a pipe\n",
+					 igt_output_name(output));
+		}
+	}
+
+	return chosen_outputs;
+}
+
+/**
+ * igt_get_single_output_for_pipe:
+ * @display: a pointer to an #igt_display_t structure
+ * @pipe: The pipe for which an #igt_output_t must be returned.
+ *
+ * Get a compatible output for a pipe.
+ *
+ * Returns: A compatible output for a given pipe, or NULL.
+ */
+igt_output_t *igt_get_single_output_for_pipe(igt_display_t *display, enum pipe pipe)
+{
+	igt_output_t *chosen_outputs[display->n_pipes];
+
+	igt_assert(pipe != PIPE_NONE);
+	igt_require(pipe < display->n_pipes);
+
+	__igt_pipe_populate_outputs(display, chosen_outputs);
+
+	return chosen_outputs[pipe];
+}
+
 static igt_output_t *igt_pipe_get_output(igt_pipe_t *pipe)
 {
 	igt_display_t *display = pipe->display;
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 1c46186e8a9d..178b636c143e 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -380,7 +380,9 @@ igt_plane_t *igt_output_get_plane(igt_output_t *output, int plane_idx);
 igt_plane_t *igt_output_get_plane_type(igt_output_t *output, int plane_type);
 igt_output_t *igt_output_from_connector(igt_display_t *display,
     drmModeConnector *connector);
+
 igt_plane_t *igt_pipe_get_plane_type(igt_pipe_t *pipe, int plane_type);
+igt_output_t *igt_get_single_output_for_pipe(igt_display_t *display, enum pipe pipe);
 
 void igt_pipe_request_out_fence(igt_pipe_t *pipe);
 
@@ -468,6 +470,10 @@ static inline bool igt_output_is_connected(igt_output_t *output)
  *
  * This for loop is called over all connected outputs. This function
  * will try every combination of @pipe and @output.
+ *
+ * If you only need to test a single output for each pipe, use
+ * for_each_pipe_with_single_output(), if you only need an
+ * output for a single pipe, use igt_get_single_output_for_pipe().
  */
 #define for_each_pipe_with_valid_output(display, pipe, output) \
 	for (int con__ = (pipe) = 0; \
@@ -476,6 +482,26 @@ static inline bool igt_output_is_connected(igt_output_t *output)
 		for_each_if ((((output) = &(display)->outputs[con__]), \
 			     igt_pipe_connector_valid((pipe), (output))))
 
+igt_output_t **__igt_pipe_populate_outputs(igt_display_t *display,
+					   igt_output_t **chosen_outputs);
+
+/**
+ * for_each_pipe_with_single_output:
+ * @display: a pointer to an #igt_display_t structure
+ * @pipe: The pipe for which this @pipe / @output combination is valid.
+ * @output: The output for which this @pipe / @output combination is valid.
+ *
+ * This loop is called over all pipes, and will try to find a compatible output
+ * for each pipe. Unlike for_each_pipe_with_valid_output(), this function will
+ * be called at most once for each pipe.
+ */
+#define for_each_pipe_with_single_output(display, pipe, output) \
+	for (igt_output_t *__outputs[(display)->n_pipes], \
+	     **__output = __igt_pipe_populate_outputs((display), __outputs); \
+	     __output < &__outputs[(display)->n_pipes]; __output++) \
+		for_each_if (*__output && \
+			     ((pipe) = (__outputs - __output), (output) = *__output, 1))
+
 /**
  * for_each_valid_output_on_pipe:
  * @display: a pointer to an #igt_display_t structure
-- 
2.16.2

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  reply	other threads:[~2018-03-14 11:20 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-14 11:20 [igt-dev] [PATCH i-g-t 0/5] lib/igt_kms: Add for_each_pipe_with_single_output and igt_get_single_output_for_pipe Maarten Lankhorst
2018-03-14 11:20 ` Maarten Lankhorst [this message]
2018-03-14 14:43   ` [igt-dev] [PATCH i-g-t 1/5] lib/igt_kms: Add functions to get only a single output for a pipe Ville Syrjälä
2018-03-15 16:58     ` [igt-dev] [PATCH i-g-t] lib/igt_kms: Add functions to get only a single output for a pipe, v2 Maarten Lankhorst
2018-03-14 11:20 ` [igt-dev] [PATCH i-g-t 2/5] tests/kms_rmfb: Use for_each_pipe_with_single_output Maarten Lankhorst
2018-03-14 14:44   ` Ville Syrjälä
2018-03-14 11:20 ` [igt-dev] [PATCH i-g-t 3/5] tests/kms_busy: Convert to using igt_get_single_output_for_pipe Maarten Lankhorst
2018-03-14 14:46   ` Ville Syrjälä
2018-03-16  8:28     ` [igt-dev] [PATCH i-g-t] tests/kms_busy: Convert to using igt_get_single_output_for_pipe, v2 Maarten Lankhorst
2018-03-14 11:20 ` [igt-dev] [PATCH i-g-t 4/5] tests/kms_chv_cursor_fail: Reorder tests, and use igt_display_require_output_on_pipe Maarten Lankhorst
2018-03-14 11:20 ` [igt-dev] [PATCH i-g-t 5/5] tests/kms_chv_cursor_fail: Handle cleanup better Maarten Lankhorst
2018-03-14 14:48   ` Ville Syrjälä
2018-03-19 15:07     ` Maarten Lankhorst
2018-03-14 13:37 ` [igt-dev] ✓ Fi.CI.BAT: success for lib/igt_kms: Add for_each_pipe_with_single_output and igt_get_single_output_for_pipe Patchwork
2018-03-14 17:22 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
2018-03-15 18:31 ` [igt-dev] ✗ Fi.CI.BAT: warning for lib/igt_kms: Add for_each_pipe_with_single_output and igt_get_single_output_for_pipe. (rev2) Patchwork
2018-03-15 19:29 ` Patchwork
2018-03-16  7:29 ` Patchwork
2018-03-16  9:03 ` [igt-dev] ✓ Fi.CI.BAT: success for lib/igt_kms: Add for_each_pipe_with_single_output and igt_get_single_output_for_pipe. (rev3) Patchwork
2018-03-16 10:41 ` [igt-dev] ✗ Fi.CI.IGT: warning " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180314112021.60224-2-maarten.lankhorst@linux.intel.com \
    --to=maarten.lankhorst@linux.intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox