@@ -90,6 +90,51 @@ static int backlight_write(int value, const char *fname)
return 0;
}
+/* If we want to actually reach PC8+ states, we need to properly configure all
+ * the devices on the system to allow this. This function will try to setup the
+ * things we know we need, but won't scream in case anything fails: we don't
+ * know which devices are present on your machine, so we can't really expect
+ * anything, just try to help with the more common problems. */
+static void setup_non_graphics_runtime_pm(void)
+{
+ int fd, i;
+ char *file_name;
+
+ /* Disk runtime PM policies. */
+ file_name = malloc(PATH_MAX);
+ for (i = 0; ; i++) {
+
+ snprintf(file_name, PATH_MAX,
+ "/sys/class/scsi_host/host%d/link_power_management_policy",
+ i);
+
+ fd = open(file_name, O_WRONLY);
+ if (fd < 0)
+ break;
+
+ igt_assert(write(fd, "min_power\n", 10) == 10);
+ close(fd);
+ }
+ free(file_name);
+}
+static void disable_all_screens_dpms(int drm_fd, drmModeResPtr res_ptr)
+{
+ int i;
+ for (i = 0; i < res_ptr->count_connectors; i++) {
+ drmModeConnectorPtr c = drmModeGetConnector(drm_fd,
+ res_ptr->connectors[i]);
+ kmstest_set_connector_dpms(drm_fd, c, DRM_MODE_DPMS_OFF);
+ }
+}
+static void enable_all_screens_dpms(int drm_fd, drmModeResPtr res_ptr)
+{
+ int i;
+ for (i = 0; i < res_ptr->count_connectors; i++) {
+ drmModeConnectorPtr c = drmModeGetConnector(drm_fd,
+ res_ptr->connectors[i]);
+ kmstest_set_connector_dpms(drm_fd, c, DRM_MODE_DPMS_ON);
+ }
+}
static void test_and_verify(int val)
{
@@ -145,9 +190,52 @@ static void test_fade(int max)
}
}
+
+static void test_fade_with_dpms(int max , int drm_fd, drmModeResPtr res_ptr)
+{
+ int i;
+ static const struct timespec ts = { .tv_sec = 0, .tv_nsec = FADESPEED*1000000 };
+ bool has_runtime_pm;
+ has_runtime_pm = igt_setup_runtime_pm();
+ igt_info("Runtime PM support: %d\n", has_runtime_pm);
+ igt_assert(has_runtime_pm);
+ disable_all_screens_dpms(drm_fd, res_ptr);
+ igt_assert(igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_SUSPENDED));
+ enable_all_screens_dpms(drm_fd, res_ptr);
+ igt_assert(igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_ACTIVE));
+ /* Fade out, then in */
+ for (i = max; i > 0; i -= max / FADESTEPS) {
+ test_and_verify(i);
+ nanosleep(&ts, NULL);
+ }
+ for (i = 0; i <= max; i += max / FADESTEPS) {
+ test_and_verify(i);
+ nanosleep(&ts, NULL);
+ }
+}
+static void test_fade_with_suspend(int max, int drm_fd, drmModeResPtr res_ptr )
+{
+ int i;
+ static const struct timespec ts = { .tv_sec = 0, .tv_nsec = FADESPEED*1000000 };
+ disable_all_screens_dpms(drm_fd, res_ptr);
+ igt_system_suspend_autoresume();
+ igt_assert(igt_wait_for_pm_status(IGT_RUNTIME_PM_STATUS_SUSPENDED));
+
+ /* Fade out, then in */
+ for (i = max; i > 0; i -= max / FADESTEPS) {
+ test_and_verify(i);
+ nanosleep(&ts, NULL);
+ }
+ for (i = 0; i <= max; i += max / FADESTEPS) {
+ test_and_verify(i);
+ nanosleep(&ts, NULL);
+ }
+}
+
igt_main
{
- int max, old;
+ int drm_fd, max, old;
+ drmModeResPtr res;
igt_skip_on_simulation();
@@ -155,6 +243,10 @@ igt_main
/* Get the max value and skip the whole test if sysfs interface not available */
igt_skip_on(backlight_read(&old, "brightness"));
igt_assert(backlight_read(&max, "max_brightness") > -1);
+ drm_fd = drm_open_any_master();
+ res = drmModeGetResources(drm_fd);
+ igt_assert(res);
+ setup_non_graphics_runtime_pm();
}
igt_subtest("basic-brightness")
@@ -163,9 +255,14 @@ igt_main
test_bad_brightness(max);
igt_subtest("fade")
test_fade(max);
+ igt_subtest("fade-with-dpms")
+ test_fade_with_dpms(max, drm_fd, res);
+ igt_subtest("fade-with-suspend")
+ test_fade_with_suspend(max, drm_fd, res);
igt_fixture {
/* Restore old brightness */
backlight_write(old, "brightness");
+ drmClose(drm_fd);
}
}