diff options
-rw-r--r-- | lib/igt_psr.c | 86 | ||||
-rw-r--r-- | lib/igt_psr.h | 2 | ||||
-rw-r--r-- | tests/kms_frontbuffer_tracking.c | 6 |
3 files changed, 89 insertions, 5 deletions
diff --git a/lib/igt_psr.c b/lib/igt_psr.c index c979b0b5..bc142632 100644 --- a/lib/igt_psr.c +++ b/lib/igt_psr.c @@ -21,7 +21,9 @@ * IN THE SOFTWARE. */ -#include "igt_psr.h" +#include "igt_psr.h" +#include "igt_sysfs.h" +#include <errno.h> bool psr_active(int fd, bool check_active) { @@ -38,3 +40,85 @@ bool psr_wait_entry(int fd) { return igt_wait(psr_active(fd, true), 500, 1); } + +static ssize_t psr_write(int fd, const char *buf) +{ + return igt_sysfs_write(fd, "i915_edp_psr_debug", buf, strlen(buf)); +} + +static int has_psr_debugfs(int fd) +{ + int ret; + + /* + * Check if new PSR debugfs api is usable by writing an invalid value. + * Legacy mode will return OK here, debugfs api will return -EINVAL. + * -ENODEV is returned when PSR is unavailable. + */ + ret = psr_write(fd, "0xf"); + if (ret == -EINVAL) + return 0; + else if (ret < 0) + return ret; + + /* legacy debugfs api, we enabled irqs by writing, disable them. */ + psr_write(fd, "0"); + return -EINVAL; +} + +static bool psr_modparam_set(int val) +{ + static int oldval = -1; + + igt_set_module_param_int("enable_psr", val); + + if (val == oldval) + return false; + + oldval = val; + return true; +} + +static int psr_restore_debugfs_fd = -1; + +static void restore_psr_debugfs(int sig) +{ + psr_write(psr_restore_debugfs_fd, "0"); +} + +static bool psr_set(int fd, bool enable) +{ + int ret; + + ret = has_psr_debugfs(fd); + if (ret == -ENODEV) { + igt_skip_on_f(enable, "PSR not available\n"); + return false; + } + + if (ret == -EINVAL) { + ret = psr_modparam_set(enable); + } else { + ret = psr_write(fd, enable ? "0x3" : "0x1"); + igt_assert(ret > 0); + } + + /* Restore original value on exit */ + if (psr_restore_debugfs_fd == -1) { + psr_restore_debugfs_fd = dup(fd); + igt_assert(psr_restore_debugfs_fd >= 0); + igt_install_exit_handler(restore_psr_debugfs); + } + + return ret; +} + +bool psr_enable(int fd) +{ + return psr_set(fd, true); +} + +bool psr_disable(int fd) +{ + return psr_set(fd, false); +} diff --git a/lib/igt_psr.h b/lib/igt_psr.h index 980f85e0..0ef22c3d 100644 --- a/lib/igt_psr.h +++ b/lib/igt_psr.h @@ -30,5 +30,7 @@ bool psr_wait_entry(int fd); bool psr_active(int fd, bool check_active); +bool psr_enable(int fd); +bool psr_disable(int fd); #endif diff --git a/tests/kms_frontbuffer_tracking.c b/tests/kms_frontbuffer_tracking.c index 1dfd7c1c..7ea2f697 100644 --- a/tests/kms_frontbuffer_tracking.c +++ b/tests/kms_frontbuffer_tracking.c @@ -941,8 +941,6 @@ static bool drrs_wait_until_rr_switch_to_low(void) #define fbc_enable() igt_set_module_param_int("enable_fbc", 1) #define fbc_disable() igt_set_module_param_int("enable_fbc", 0) -#define psr_enable() igt_set_module_param_int("enable_psr", 1) -#define psr_disable() igt_set_module_param_int("enable_psr", 0) #define drrs_enable() drrs_set(1) #define drrs_disable() drrs_set(0) @@ -1137,7 +1135,7 @@ static void disable_features(const struct test_mode *t) return; fbc_disable(); - psr_disable(); + psr_disable(drm.debugfs); drrs_disable(); } @@ -1719,7 +1717,7 @@ static void enable_features_for_test(const struct test_mode *t) if (t->feature & FEATURE_FBC) fbc_enable(); if (t->feature & FEATURE_PSR) - psr_enable(); + psr_enable(drm.debugfs); if (t->feature & FEATURE_DRRS) drrs_enable(); } |