[Intel-gfx] [PATCH i-g-t] tests/kms_frontbuffer_tracking: Idleness DRRS coverage

Ramalingam C ramalingam.c at intel.com
Tue Oct 31 09:20:44 UTC 2017


From: Lohith BS <lohith.bs at intel.com>

By default the DRRS state will be at DRRS_HIGH_RR. When a Display
content is Idle for more than 1Sec Idleness will be declared and
DRRS_LOW_RR will be invoked, changing the refresh rate to the
lower most refresh rate supported by the panel. As soon as there
is a display content change there will be a DRRS state transition
as DRRS_LOW_RR--> DRRS_HIGH_RR, changing the refresh rate to the
highest refresh rate supported by the panel.

To test this, Idleness DRRS IGT will probe the DRRS state at below
instances and compare with the expected state.

        Instance                                        Expected State
    1. Immediately after rendering the still image      DRRS_HIGH_RR
    2. After a delay of 1.2Sec                          DRRS_LOW_RR
    3. After changing the frame buffer                  DRRS_HIGH_RR
    4. After a delay of 1.2Sec                          DRRS_LOW_RR
    5. After changing the frame buffer                  DRRS_HIGH_RR
    6. After a delay of 1.2Sec                          DRRS_LOW_RR

The test checks the driver DRRS state from the debugfs entry.
To check the actual refresh-rate, the number of vblanks received
per sec.
The refresh-rate calculated is checked against the expected refresh-rate
with a tolerance value of 2.

This patch is a continuation of the earlier work
https://patchwork.freedesktop.org/patch/45472/ towards igt for idleness
DRRS. The code is tested on Broxton BXT_T platform.

    v2: Addressed the comments and suggestions from Vlad, Marius.
	The signoff details from the earlier work are also included.

    v3: Modified vblank rate calculation by using reply-sequence,
	provided by drmWaitVBlank, as suggested by Chris Wilson.

    v4: As suggested from Chris Wilson and Daniel Vetter
        1) Avoided using pthread for calculating vblank refresh rate,
           instead used drmWaitVBlank reply sequence.
        2) Avoided using kernel-specific info like transitional delays,
           instead polling mechanism with timeout is used.
        3) Included edp-DRRS as a subtest in kms_frontbuffer_tracking.c,
           instead of having a separate test.

    v5: This patch adds DRRS as a new feature in the
	kms_frontbuffer_tracking IGT.
	DRRS switch to lower vrefresh rate is tested at slow-draw
	subtest. This is in continuation of last patch
	"https://patchwork.freedesktop.org/patch/162726/"

    v6: This patch adds runtime enable and disable feature for
	testing DRRS

Signed-off-by: Lohith BS <lohith.bs at intel.com>
Signed-off-by: aknautiy <ankit.k.nautiyal at intel.com>
---
 tests/kms_frontbuffer_tracking.c | 134 +++++++++++++++++++++++++++++++++++----
 1 file changed, 123 insertions(+), 11 deletions(-)

diff --git a/tests/kms_frontbuffer_tracking.c b/tests/kms_frontbuffer_tracking.c
index a068c8afb6d8..fdb4f57d4698 100644
--- a/tests/kms_frontbuffer_tracking.c
+++ b/tests/kms_frontbuffer_tracking.c
@@ -34,7 +34,7 @@
 
 
 IGT_TEST_DESCRIPTION("Test the Kernel's frontbuffer tracking mechanism and "
-		     "its related features: FBC and PSR");
+		     "its related features: FBC, DRRS and PSR");
 
 /*
  * One of the aspects of this test is that, for every subtest, we try different
@@ -105,8 +105,9 @@ struct test_mode {
 		FEATURE_NONE  = 0,
 		FEATURE_FBC   = 1,
 		FEATURE_PSR   = 2,
-		FEATURE_COUNT = 4,
-		FEATURE_DEFAULT = 4,
+		FEATURE_DRRS  = 4,
+		FEATURE_COUNT = 6,
+		FEATURE_DEFAULT = 6,
 	} feature;
 
 	/* Possible pixel formats. We just use FORMAT_DEFAULT for most tests and
@@ -178,10 +179,8 @@ struct {
 
 struct {
 	bool can_test;
-} psr = {
-	.can_test = false,
-};
-
+} psr = { .can_test = false,},
+drrs = { .can_test = false,};
 
 #define SINK_CRC_SIZE 12
 typedef struct {
@@ -822,6 +821,54 @@ static void psr_print_status(void)
 	igt_info("PSR status:\n%s\n", buf);
 }
 
+static bool is_drrs_high(void)
+{
+	char buf[256];
+
+	debugfs_read("i915_drrs_status", buf);
+	return strstr(buf, "DRRS_HIGH_RR");
+}
+
+static bool is_drrs_low(void)
+{
+	char buf[256];
+
+	debugfs_read("i915_drrs_status", buf);
+	return strstr(buf, "DRRS_LOW_RR");
+}
+
+static bool is_drrs_supported(void)
+{
+	char buf[256];
+
+	debugfs_read("i915_drrs_status", buf);
+	return strstr(buf, "DRRS Supported: Yes");
+}
+
+static bool is_drrs_inactive(void)
+{
+	char buf[256];
+
+	debugfs_read("i915_drrs_status", buf);
+
+	if (strstr(buf, "No active crtc found"))
+		return true;
+	if (strstr(buf, "Idleness DRRS: Disabled"))
+		return true;
+	if (strstr(buf, "DRRS Supported : No"))
+		return true;
+
+	return false;
+}
+
+static void drrs_print_status(void)
+{
+	char buf[256];
+
+	debugfs_read("i915_drrs_status", buf);
+	igt_info("DRRS STATUS :\n%s\n", buf);
+}
+
 static struct timespec fbc_get_last_action(void)
 {
 	struct timespec ret = { 0, 0 };
@@ -932,10 +979,17 @@ static bool psr_wait_until_enabled(void)
 	return igt_wait(psr_is_enabled(), 5000, 1);
 }
 
+static bool drrs_wait_until_rr_switch_to_low(void)
+{
+	return igt_wait(is_drrs_low(), 5000, 1);
+}
+
 #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() igt_set_module_param("enable_drrs", "Y")
+#define drrs_disable() igt_set_module_param("enable_drrs", "N")
 
 static void get_sink_crc(sink_crc_t *crc, bool mandatory)
 {
@@ -1182,6 +1236,7 @@ static void disable_features(const struct test_mode *t)
 
 	fbc_disable();
 	psr_disable();
+	drrs_disable();
 }
 
 static void *busy_thread_func(void *data)
@@ -1575,6 +1630,21 @@ static void teardown_psr(void)
 {
 }
 
+static void setup_drrs(void)
+{
+	if (get_connector(prim_mode_params.connector_id)->connector_type !=
+			DRM_MODE_CONNECTOR_eDP) {
+		igt_info("Can't test DRRS: no usable eDP screen.\n");
+		return;
+	}
+
+	if (!is_drrs_supported()) {
+		igt_info("Can't test DRRS: Not supported.\n");
+		return;
+	}
+	drrs.can_test = true;
+}
+
 static void setup_environment(void)
 {
 	setup_drm();
@@ -1582,7 +1652,7 @@ static void setup_environment(void)
 
 	setup_fbc();
 	setup_psr();
-
+	setup_drrs();
 	setup_crcs();
 }
 
@@ -1660,6 +1730,11 @@ static void do_flush(const struct test_mode *t)
 #define ASSERT_PSR_ENABLED		(1 << 6)
 #define ASSERT_PSR_DISABLED		(1 << 7)
 
+#define DRRS_ASSERT_FLAGS               (7 << 8)
+#define ASSERT_DRRS_HIGH                (1 << 8)
+#define ASSERT_DRRS_LOW                 (1 << 9)
+#define ASSERT_DRRS_INACTIVE            (1 << 10)
+
 static int adjust_assertion_flags(const struct test_mode *t, int flags)
 {
 	if (!(flags & DONT_ASSERT_FEATURE_STATUS)) {
@@ -1667,12 +1742,17 @@ static int adjust_assertion_flags(const struct test_mode *t, int flags)
 			flags |= ASSERT_FBC_ENABLED;
 		if (!(flags & ASSERT_PSR_DISABLED))
 			flags |= ASSERT_PSR_ENABLED;
+		if (!((flags & ASSERT_DRRS_LOW) ||
+			(flags & ASSERT_DRRS_INACTIVE)))
+			flags |= ASSERT_DRRS_HIGH;
 	}
 
 	if ((t->feature & FEATURE_FBC) == 0)
 		flags &= ~FBC_ASSERT_FLAGS;
 	if ((t->feature & FEATURE_PSR) == 0)
 		flags &= ~PSR_ASSERT_FLAGS;
+	if ((t->feature & FEATURE_DRRS) == 0)
+		flags &= ~DRRS_ASSERT_FLAGS;
 
 	return flags;
 }
@@ -1704,6 +1784,23 @@ static void do_status_assertions(int flags)
 		return;
 	}
 
+	if (flags & ASSERT_DRRS_HIGH) {
+		if (!is_drrs_high()) {
+			drrs_print_status();
+			igt_assert_f(false, "DRRS HIGH\n");
+		}
+	} else if (flags & ASSERT_DRRS_LOW) {
+		if (!drrs_wait_until_rr_switch_to_low()) {
+			drrs_print_status();
+			igt_assert_f(false, "DRRS LOW\n");
+		}
+	} else if (flags & ASSERT_DRRS_INACTIVE) {
+		if (!is_drrs_inactive()) {
+			drrs_print_status();
+			igt_assert_f(false, "DRRS INACTIVE\n");
+		}
+	}
+
 	if (flags & ASSERT_FBC_ENABLED) {
 		igt_require(!fbc_not_enough_stolen());
 		igt_require(!fbc_stride_not_supported());
@@ -1831,6 +1928,8 @@ static void enable_features_for_test(const struct test_mode *t)
 		fbc_enable();
 	if (t->feature & FEATURE_PSR)
 		psr_enable();
+	if (t->feature & FEATURE_DRRS)
+		drrs_enable();
 }
 
 static void check_test_requirements(const struct test_mode *t)
@@ -1850,6 +1949,10 @@ static void check_test_requirements(const struct test_mode *t)
 			      "Can't test PSR without sink CRCs\n");
 	}
 
+	if (t->feature & FEATURE_DRRS)
+		igt_require_f(drrs.can_test,
+				"Can't test DRRS with the current outputs\n");
+
 	if (opt.only_pipes != PIPE_COUNT)
 		igt_require(t->pipes == opt.only_pipes);
 }
@@ -1971,7 +2074,7 @@ static void rte_subtest(const struct test_mode *t)
 
 	unset_all_crtcs();
 	do_assertions(ASSERT_FBC_DISABLED | ASSERT_PSR_DISABLED |
-		      DONT_ASSERT_CRC);
+		      DONT_ASSERT_CRC | ASSERT_DRRS_INACTIVE);
 
 	enable_prim_screen_and_wait(t);
 	set_cursor_for_test(t, &prim_mode_params);
@@ -2219,6 +2322,7 @@ static void badformat_subtest(const struct test_mode *t)
 		assertions |= ASSERT_FBC_DISABLED;
 	if (!psr_valid)
 		assertions |= ASSERT_PSR_DISABLED;
+
 	do_assertions(assertions);
 }
 
@@ -2277,7 +2381,11 @@ static void slow_draw_subtest(const struct test_mode *t)
 		sleep(2);
 
 		update_wanted_crc(t, &pattern->crcs[t->format][r]);
-		do_assertions(0);
+
+		if (t->feature & FEATURE_DRRS)
+			do_assertions(ASSERT_DRRS_LOW);
+		else
+			do_assertions(0);
 	}
 }
 
@@ -3375,6 +3483,10 @@ static const char *feature_str(int feature)
 		return "psr";
 	case FEATURE_FBC | FEATURE_PSR:
 		return "fbcpsr";
+	case FEATURE_DRRS:
+		return "drrs";
+	case FEATURE_FBC | FEATURE_DRRS:
+		return "fbcdrrs";
 	default:
 		igt_assert(false);
 	}
@@ -3639,7 +3751,7 @@ int main(int argc, char *argv[])
 				tilingchange_subtest(&t);
 		}
 
-		if (t.feature & FEATURE_PSR)
+		if ((t.feature & FEATURE_PSR) || (t.feature & FEATURE_DRRS))
 			igt_subtest_f("%s-slowdraw", feature_str(t.feature))
 				slow_draw_subtest(&t);
 
-- 
2.7.4



More information about the Intel-gfx mailing list