[i-g-t V2 1/5] lib/igt_kms: Add infra to handle crtc arbitrary attributes

Kamil Konieczny kamil.konieczny at linux.intel.com
Fri Nov 15 17:20:45 UTC 2024


Hi Bhanuprakash,
On 2024-09-24 at 19:56:34 +0530, Bhanuprakash Modem wrote:
> We may want to poke at various other crtc attributes
> via sysfs/debugfs. Add a mechamisn to handle crtc
> arbitrary attributes.
> 
> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem at intel.com>
> ---
>  lib/igt_kms.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_kms.h |   3 +
>  2 files changed, 153 insertions(+)
> 
> diff --git a/lib/igt_kms.c b/lib/igt_kms.c
> index b40470c02..c22cdb602 100644
> --- a/lib/igt_kms.c
> +++ b/lib/igt_kms.c
> @@ -92,6 +92,7 @@
>  #define DISPLAY_TILE_BLOCK 0x12
>  
>  typedef bool (*igt_connector_attr_set)(int dir, const char *attr, const char *value);
> +typedef bool (*igt_crtc_attr_set)(int dir, const char *attr, const char *value);
>  
>  struct igt_connector_attr {
>  	uint32_t connector_type;
> @@ -102,7 +103,16 @@ struct igt_connector_attr {
>  	const char *attr, *value, *reset_value;
>  };
>  
> +struct igt_crtc_attr {
> +	int pipe;
> +	int idx;
> +	int dir;
> +	igt_crtc_attr_set set;
> +	const char *attr, *value, *reset_value;
> +};
> +
>  static struct igt_connector_attr connector_attrs[MAX_CONNECTORS];
> +static struct igt_crtc_attr crtc_attrs[IGT_MAX_PIPES];
>  
>  /**
>   * igt_kms_get_base_edid:
> @@ -1802,6 +1812,125 @@ void kmstest_force_edid(int drm_fd, drmModeConnector *connector,
>  	igt_assert(ret != -1);
>  }
>  
> +static struct igt_crtc_attr *crtc_attr_find(int idx, enum pipe pipe,
> +					    igt_crtc_attr_set set,
> +					    const char *attr)
> +{
> +	igt_assert(pipe != PIPE_NONE || pipe >= IGT_MAX_PIPES);

Why not return NULL for PIPE_NONE?
Also imho better:

	igt_assert(pipe >= 0 && pipe < ARRAY_SIZE());

> +
> +	for (int i = 0; i < ARRAY_SIZE(crtc_attrs); i++) {
> +		struct igt_crtc_attr *c = &crtc_attrs[i];
> +
> +		if (c->idx == idx &&
> +		    c->pipe == pipe &&
> +		    c->set == set && !strcmp(c->attr, attr))
> +			return c;
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct igt_crtc_attr *crtc_attr_find_free(void)
> +{
> +	for (int i = 0; i < ARRAY_SIZE(crtc_attrs); i++) {
> +		struct igt_crtc_attr *c = &crtc_attrs[i];
> +
> +		if (!c->attr)
> +			return c;
> +	}
> +
> +	return NULL;
> +}
> +
> +static struct igt_crtc_attr *crtc_attr_alloc(int idx, enum pipe pipe,
> +					     int dir, igt_crtc_attr_set set,
> +					     const char *attr, const char *reset_value)
> +{
> +	struct igt_crtc_attr *c = crtc_attr_find_free();

c could be NULL here, if find_free() failed.

Regards,
Kamil

> +
> +	c->idx = idx;
> +	c->pipe = pipe;
> +
> +	c->dir = dir;
> +	c->set = set;
> +	c->attr = attr;
> +	c->reset_value = reset_value;
> +
> +	return c;
> +}
> +
> +static void crtc_attr_free(struct igt_crtc_attr *c)
> +{
> +	memset(c, 0, sizeof(*c));
> +}
> +
> +static bool crtc_attr_set(int idx, enum pipe pipe,
> +			  int dir, igt_crtc_attr_set set,
> +			  const char *attr, const char *value,
> +			  const char *reset_value)
> +{
> +	struct igt_crtc_attr *c;
> +
> +	c = crtc_attr_find(idx, pipe, set, attr);
> +	if (!c)
> +		c = crtc_attr_alloc(idx, pipe, dir, set, attr, reset_value);
> +
> +	c->value = value;
> +
> +	if (!c->set(c->dir, c->attr, c->value)) {
> +		crtc_attr_free(c);
> +		return false;
> +	}
> +
> +	if (!strcmp(c->value, c->reset_value))
> +		crtc_attr_free(c);
> +
> +	return true;
> +}
> +
> +static bool crtc_attr_set_debugfs(int drm_fd, enum pipe pipe,
> +				  const char *attr, const char *value,
> +				  const char *reset_value)
> +{
> +	int idx, dir;
> +
> +	idx = igt_device_get_card_index(drm_fd);
> +	if (idx < 0 || idx > 63)
> +		return false;
> +
> +	dir = igt_debugfs_pipe_dir(drm_fd, pipe, O_DIRECTORY);
> +	if (dir < 0)
> +		return false;
> +
> +	if (!crtc_attr_set(idx, pipe, dir,
> +			   igt_sysfs_set, attr,
> +			   value, reset_value))
> +		return false;
> +
> +	igt_info("Crtc-%d/%s is now %s\n", pipe, attr, value);
> +
> +	return true;
> +}
> +
> +/**
> + * kmstest_set_connector_dpms:
> + *
> + * Dump all attr state on all crtcs.
> + */
> +void dump_crtc_attrs(void)
> +{
> +	igt_debug("Current crtc attrs:\n");
> +
> +	for (int i = 0; i < ARRAY_SIZE(crtc_attrs); i++) {
> +		struct igt_crtc_attr *c = &crtc_attrs[i];
> +
> +		if (!c->attr)
> +			continue;
> +
> +		igt_debug("\tcrtc-%d/%s: %s\n", c->pipe, c->attr, c->value);
> +	}
> +}
> +
>  /**
>   * sort_drm_modes_by_clk_dsc:
>   * @a: first element
> @@ -5459,6 +5588,27 @@ void igt_reset_connectors(void)
>  	}
>  }
>  
> +/**
> + * igt_reset_crtcs:
> + *
> + * Remove any forced state from the crtcs.
> + */
> +void igt_reset_crtcs(void)
> +{
> +	/*
> +	 * Reset the crtcs stored in crtc_attrs, avoiding any
> +	 * functions that are not safe to call in signal handlers
> +	 */
> +	for (int i = 0; i < ARRAY_SIZE(crtc_attrs); i++) {
> +		struct igt_crtc_attr *c = &crtc_attrs[i];
> +
> +		if (!c->attr)
> +			continue;
> +
> +		c->set(c->dir, c->attr, c->reset_value);
> +	}
> +}
> +
>  /**
>   * igt_watch_uevents:
>   *
> diff --git a/lib/igt_kms.h b/lib/igt_kms.h
> index 25ba50916..97efbefa5 100644
> --- a/lib/igt_kms.h
> +++ b/lib/igt_kms.h
> @@ -1085,6 +1085,9 @@ void igt_pipe_refresh(igt_display_t *display, enum pipe pipe, bool force);
>  void igt_enable_connectors(int drm_fd);
>  void igt_reset_connectors(void);
>  
> +void igt_reset_crtcs(void);
> +void dump_crtc_attrs(void);
> +
>  uint32_t kmstest_get_vbl_flag(int crtc_offset);
>  
>  const struct edid *igt_kms_get_base_edid(void);
> -- 
> 2.43.0
> 


More information about the igt-dev mailing list