From: Imre Deak <imre.d...@intel.com>

Add a helper to query the supported and currently selected
suspend-to-mem modes.

v2:
- Fix for old kernels where the mem_sleep sysfs file didn't yet exist.

Signed-off-by: Imre Deak <imre.d...@intel.com>
---
 lib/igt_aux.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/igt_aux.h | 24 +++++++++++++++
 2 files changed, 105 insertions(+)

diff --git a/lib/igt_aux.c b/lib/igt_aux.c
index 578f8579..f2cb3247 100644
--- a/lib/igt_aux.c
+++ b/lib/igt_aux.c
@@ -827,6 +827,87 @@ static uint32_t get_supported_suspend_states(int power_dir)
        return state_mask;
 }
 
+static const char *suspend_to_mem_mode_name[] = {
+       [SUSPEND_TO_MEM_S2IDLE] = "s2idle",
+       [SUSPEND_TO_MEM_SHALLOW] = "shallow",
+       [SUSPEND_TO_MEM_DEEP] = "deep",
+};
+
+static uint32_t
+get_supported_suspend_to_mem_modes(int power_dir,
+                                  enum igt_suspend_to_mem_mode *selected_mode)
+{
+       char *modes;
+       char *mode_name;
+       uint32_t mode_mask;
+       bool selected_found = false;
+
+       /*
+        * Other modes than deep sleep were only introduced with the mem_sleep
+        * sysfs file.
+        */
+       modes = igt_sysfs_get(power_dir, "mem_sleep");
+       if (!modes) {
+               *selected_mode = SUSPEND_TO_MEM_DEEP;
+               return 1 << SUSPEND_TO_MEM_DEEP;
+       }
+
+       mode_mask = 0;
+       for (mode_name = strtok(modes, " "); mode_name;
+            mode_name = strtok(NULL, " ")) {
+               enum igt_suspend_to_mem_mode mode;
+               bool selected = false;
+
+               if (mode_name[0] == '[') {
+                       char *e = &mode_name[strlen(mode_name) - 1];
+
+                       igt_assert(!selected_found);
+                       igt_assert(*e == ']');
+                       mode_name++;
+                       *e = '\0';
+
+                       selected = true;
+               }
+
+               for (mode = SUSPEND_TO_MEM_S2IDLE;
+                    mode < SUSPEND_TO_MEM_NUM;
+                    mode++)
+                       if (strcmp(mode_name,
+                                  suspend_to_mem_mode_name[mode]) == 0)
+                               break;
+               igt_assert(mode < SUSPEND_TO_MEM_NUM);
+               mode_mask |= 1 << mode;
+               if (selected) {
+                       selected_found = true;
+                       if (selected_mode)
+                               *selected_mode = mode;
+               }
+       }
+
+       igt_assert(selected_found);
+
+       free(modes);
+
+       return mode_mask;
+}
+
+/**
+ * igt_get_suspend_to_mem_mode:
+ *
+ * Returns the currently selected @igt_suspend_to_mem_mode.
+ */
+enum igt_suspend_to_mem_mode igt_get_suspend_to_mem_mode(void)
+{
+       int power_dir;
+       enum igt_suspend_to_mem_mode mode;
+
+       igt_require((power_dir = open("/sys/power", O_RDONLY)) >= 0);
+       (void)get_supported_suspend_to_mem_modes(power_dir, &mode);
+       close(power_dir);
+
+       return mode;
+}
+
 /**
  * igt_system_suspend_autoresume:
  * @state: an #igt_suspend_state, the target suspend state
diff --git a/lib/igt_aux.h b/lib/igt_aux.h
index 04d22904..7ccaa8c4 100644
--- a/lib/igt_aux.h
+++ b/lib/igt_aux.h
@@ -184,10 +184,34 @@ enum igt_suspend_test {
        SUSPEND_TEST_NUM,
 };
 
+/**
+ * igt_suspend_to_mem_mode:
+ * @SUSPEND_TO_MEM_S2IDLE: suspend to mem maps to @SUSPEND_STATE_FREEZE
+ * @SUSPEND_TO_MEM_SHALLOW: suspend to mem maps to @SUSPEND_STATE_STANDBY
+ * @SUSPEND_TO_MEM_DEEP: suspend to mem will target the ACPI S3 state
+ *
+ * The target system state when suspending to mem:
+ * - Suspending with @SUSPEND_STATE_MEM/@SUSPEND_TO_MEM_S2IDLE is equivalent to
+ *   suspending with @SUSPEND_STATE_FREEZE.
+ * - Suspending with @SUSPEND_STATE_MEM/@SUSPEND_TO_MEM_SHALLOW is equivalent 
to
+ *   suspending with @SUSPEND_STATE_STANDBY.
+ * - Suspending with @SUSPEND_STATE_MEM/@SUSPEND_TO_MEM_DEEP will target the
+ *   ACPI S3 state.
+ */
+enum igt_suspend_to_mem_mode {
+       SUSPEND_TO_MEM_S2IDLE,
+       SUSPEND_TO_MEM_SHALLOW,
+       SUSPEND_TO_MEM_DEEP,
+
+       /*< private >*/
+       SUSPEND_TO_MEM_NUM,
+};
+
 void igt_system_suspend_autoresume(enum igt_suspend_state state,
                                   enum igt_suspend_test test);
 void igt_set_autoresume_delay(int delay_secs);
 int igt_get_autoresume_delay(enum igt_suspend_state state);
+enum igt_suspend_to_mem_mode igt_get_suspend_to_mem_mode(void);
 
 /* dropping priviledges */
 void igt_drop_root(void);
-- 
2.17.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to