[i-g-t 1/5] lib/igt_kms: Add infra to handle crtc arbitrary attributes
Bhanuprakash Modem
bhanuprakash.modem at intel.com
Tue Aug 13 12:06:14 UTC 2024
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 e030b35a6..a8e535a8b 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);
+
+ 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->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 e8582a45b..6cfa6230a 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.2
More information about the igt-dev
mailing list