Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: igt-dev@lists.freedesktop.org
Subject: Re: [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 16:43:19 +0200	[thread overview]
Message-ID: <20180314144319.GE5453@intel.com> (raw)
In-Reply-To: <20180314112021.60224-2-maarten.lankhorst@linux.intel.com>

On Wed, Mar 14, 2018 at 12:20:17PM +0100, Maarten Lankhorst wrote:
> 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;
> +			}

I think this might not be find the optimal solution in some cases since
it always picks the first available pipe. So in theory we might not pick
as many outputs that are actually available. But I suppose such
configurations shouldn't be commoin so probably will do fine for most
cases.

> +
> +			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))

That requires quite a sophisticated parser :) But it does look correct to me.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +
>  /**
>   * 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

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

  reply	other threads:[~2018-03-14 14:43 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 ` [igt-dev] [PATCH i-g-t 1/5] lib/igt_kms: Add functions to get only a single output for a pipe Maarten Lankhorst
2018-03-14 14:43   ` Ville Syrjälä [this message]
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=20180314144319.GE5453@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=maarten.lankhorst@linux.intel.com \
    /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