[igt-dev] [RFC incomplete PATCH i-g-t] lib/igt_kms: Reduce probing and allow initial hotplug during igt_display_init()

Ville Syrjälä ville.syrjala at linux.intel.com
Fri Mar 23 13:03:25 UTC 2018


On Fri, Mar 23, 2018 at 01:48:28PM +0100, Maarten Lankhorst wrote:
> When booting with fbdev disabled, all outputs are set to UNKNOWNCONNECTION.
> In this case we have to reprobe, but in all others we can safely assume that
> the output connector status is valid.
> 
> Enumerate all outputs, and for good measure recheck after we probed, to add
> and DP-MST we may have missed.
> 
> Signed-off-by: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
> Cc: Lyude <lyude at redhat.com>
> Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
> ---
> Unfortunately we lack a way to determine whether the probing will enumerate
> additional DP-MST displays, so the only way right now to test DP-MST would be
> to add a sleep(5) in igt_display_check_hotplug.
> 
> Any thoughts how we can make this more reliable for DP-MST?

When do we fill out the debugfs mst topology information?

> 
> ~Maarten
> 
> lib/igt_kms.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++-----------
>  lib/igt_kms.h |   2 +-
>  2 files changed, 99 insertions(+), 23 deletions(-)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index 9e32f40673bb..2417af2fc082 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -974,7 +974,7 @@ _kmstest_connector_config_find_encoder(int drm_fd, drmModeConnector *connector,
>  static bool _kmstest_connector_config(int drm_fd, uint32_t connector_id,
>  				      unsigned long crtc_idx_mask,
>  				      struct kmstest_connector_config *config,
> -				      bool probe)
> +				      int probe)
>  {
>  	drmModeRes *resources;
>  	drmModeConnector *connector;
> @@ -988,11 +988,19 @@ static bool _kmstest_connector_config(int drm_fd, uint32_t connector_id,
>  	}
>  
>  	/* First, find the connector & mode */
> -	if (probe)
> +	if (probe > 0)
>  		connector = drmModeGetConnector(drm_fd, connector_id);
> -	else
> +	else {
>  		connector = drmModeGetConnectorCurrent(drm_fd, connector_id);
>  
> +		if (probe < 0 && connector &&
> +		    connector->connection == DRM_MODE_UNKNOWNCONNECTION) {
> +			drmModeFreeConnector(connector);
> +
> +			connector = drmModeGetConnector(drm_fd, connector_id);
> +		}
> +	}
> +
>  	if (!connector)
>  		goto err2;
>  
> @@ -1802,6 +1810,87 @@ void igt_display_reset(igt_display_t *display)
>  	}
>  }
>  
> +static void __igt_display_append_output(igt_display_t *display, unsigned id)
> +{
> +	igt_output_t *output;
> +
> +	output = &display->outputs[display->n_outputs++];
> +	memset(output, 0, sizeof(*output));
> +
> +	/*
> +	 * We don't assign each output a pipe unless
> +	 * a pipe is set with igt_output_set_pipe().
> +	 */
> +	output->id = id;
> +	output->display = display;
> +	output->pending_pipe = PIPE_NONE;
> +	output->force_reprobe = -1;
> +
> +	igt_output_refresh(output);
> +}
> +
> +static void igt_display_append_output(igt_display_t *display, unsigned id)
> +{
> +	display->outputs = realloc(display->outputs, sizeof(*display->outputs) * (1 + display->n_outputs));
> +	igt_assert(display->outputs);
> +
> +	__igt_display_append_output(display, id);
> +
> +	igt_info("HOTPLUG! Added new output %s\n", output->name);
> +}
> +
> +static void igt_display_check_hotplug(igt_display_t *display)
> +{
> +	int i, j, num_outputs;
> +	uint64_t connector_mask = 0;
> +	igt_output_t *new_outputs;
> +	drmModeRes *resources;
> +
> +	/* Outputs may have been discovered by igt_output_refresh(), retry.. */
> +	resources = drmModeGetResources(display->drm_fd);
> +
> +	for (i = 0; i < resources->count_connectors; i++) {
> +		unsigned id = resources->connectors[i];
> +		bool found = false;
> +
> +		for (j = 0; j < display->n_outputs; j++) {
> +			igt_output_t *output = &display->outputs[j];
> +
> +			if (output->id != id)
> +				continue;
> +
> +			found = true;
> +			break;
> +		}
> +
> +		if (!found)
> +			igt_display_append_output(display, id);
> +
> +		connector_mask |= 1ULL << j;
> +	}
> +
> +	drmModeFreeResources(resources);
> +
> +	num_outputs = __builtin_popcountll(connector_mask);
> +	if (num_outputs == display->n_outputs)
> +		return;
> +
> +	new_outputs = malloc(sizeof(*new_outputs) * num_outputs);
> +
> +	/* Garbage collect dead outputs. */
> +	for (i = j = 0; i < display->n_outputs; i++) {
> +		if (!(connector_mask & (1ULL << i))) {
> +			igt_info("Output %s disappeared!\n", display->outputs[i].name);
> +			continue;
> +		}
> +
> +		new_outputs[j++] = display->outputs[i];
> +	}
> +
> +	free(display->outputs);
> +	display->outputs = new_outputs;
> +}
> +
>  static void igt_fill_plane_format_mod(igt_display_t *display, igt_plane_t *plane);
>  static void igt_fill_display_format_mod(igt_display_t *display);
>  
> @@ -2012,31 +2101,18 @@ void igt_display_init(igt_display_t *display, int drm_fd)
>  
>  	igt_fill_display_format_mod(display);
>  
> -	/*
> -	 * The number of connectors is set, so we just initialize the outputs
> -	 * array in _init(). This may change when we need dynamic connectors
> -	 * (say DisplayPort MST).
> -	 */
> -	display->n_outputs = resources->count_connectors;
> -	display->outputs = calloc(display->n_outputs, sizeof(igt_output_t));
> +	display->n_outputs = 0;
> +	display->outputs = malloc(display->n_outputs * sizeof(igt_output_t));
>  	igt_assert_f(display->outputs, "Failed to allocate memory for %d outputs\n", display->n_outputs);
>  
> -	for (i = 0; i < display->n_outputs; i++) {
> -		igt_output_t *output = &display->outputs[i];
> -
> -		/*
> -		 * We don't assign each output a pipe unless
> -		 * a pipe is set with igt_output_set_pipe().
> -		 */
> -		output->id = resources->connectors[i];
> -		output->display = display;
> -
> -		igt_output_refresh(output);
> -	}
> +	for (i = 0; i < display->n_outputs; i++)
> +		__igt_display_append_output(display, resources->connectors[i]);
>  
>  	drmModeFreePlaneResources(plane_resources);
>  	drmModeFreeResources(resources);
>  
> +	igt_display_check_hotplug(display);
> +
>  	/* Set reasonable default values for every object in the display. */
>  	igt_display_reset(display);
>  
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index 6f16dc8cf85e..9e734ab1a5b8 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -340,7 +340,7 @@ typedef struct {
>  	uint32_t id;					/* KMS id */
>  	struct kmstest_connector_config config;
>  	char *name;
> -	bool force_reprobe;
> +	int force_reprobe;
>  	enum pipe pending_pipe;
>  	bool use_override_mode;
>  	drmModeModeInfo override_mode;
> -- 
> 2.16.2
> 
> _______________________________________________
> igt-dev mailing list
> igt-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/igt-dev

-- 
Ville Syrjälä
Intel OTC


More information about the igt-dev mailing list