[i-g-t V2 1/5] lib/igt_kms: Add infra to handle crtc arbitrary attributes
Modem, Bhanuprakash
bhanuprakash.modem at intel.com
Mon Nov 18 09:48:04 UTC 2024
Hi Kamil,
On 15-11-2024 10:50 pm, Kamil Konieczny wrote:
> 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?
If we return NULL from here, crtc_attr_set() will allocate some memory
which is not an valid case. So we must need this check either here or in
crtc_attr_set().
> Also imho better:
>
> igt_assert(pipe >= 0 && pipe < ARRAY_SIZE());
Sure, will do that in next rev.
>
>> +
>> + 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.
I'll fix this in next rev.
- Bhanu
>
> 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