diff mbox

[i-g-t] igt/psr: Test vblank continuity with PSR enabled

Message ID 20171212010513.2689-1-dhinakaran.pandiyan@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dhinakaran Pandiyan Dec. 12, 2017, 1:05 a.m. UTC
PSR allows DMC to put the system to low power states when active, but
this can reset the frame counter on some platforms. The frame counter reset
leads to a negative diff applied to vblank count. This subtest checks
for that.

Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
---
 tests/kms_psr_sink_crc.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
diff mbox

Patch

diff --git a/tests/kms_psr_sink_crc.c b/tests/kms_psr_sink_crc.c
index 83a69f0b..f76c3041 100644
--- a/tests/kms_psr_sink_crc.c
+++ b/tests/kms_psr_sink_crc.c
@@ -69,6 +69,7 @@  typedef struct {
 	enum operations op;
 	uint32_t devid;
 	uint32_t crtc_id;
+	enum pipe pipe;
 	igt_display_t display;
 	drm_intel_bufmgr *bufmgr;
 	struct igt_fb fb_green, fb_white;
@@ -107,6 +108,7 @@  static void setup_output(data_t *data)
 		if (c->connector_type != DRM_MODE_CONNECTOR_eDP)
 			continue;
 
+		data->pipe = pipe;
 		igt_output_set_pipe(output, pipe);
 		data->crtc_id = output->config.crtc->crtc_id;
 		data->output = output;
@@ -285,6 +287,68 @@  static void assert_or_manual(bool condition, const char *expected)
 	igt_assert(igt_interactive_debug || condition);
 }
 
+static unsigned int get_vblank(int fd, unsigned int pipe)
+{
+	union drm_wait_vblank vbl;
+
+	memset(&vbl, 0, sizeof(vbl));
+	vbl.request.type = DRM_VBLANK_RELATIVE | kmstest_get_vbl_flag(pipe);
+	igt_ioctl(fd, DRM_IOCTL_WAIT_VBLANK, &vbl);
+
+	return vbl.reply.sequence;
+}
+
+static void dmc_read_counts(unsigned int fd, unsigned int *count)
+{
+	char buf[512];
+
+	igt_debugfs_read(fd, "i915_dmc_info", buf);
+	igt_assert_eq(sscanf(strstr(buf, "DC3 -> DC5"), "DC3 -> DC5 count: %u", &count[0]),
+		      1);
+	igt_assert_eq(sscanf(strstr(buf, "DC5 -> DC6"), "DC5 -> DC6 count: %u", &count[1]),
+		      1);
+	igt_debug("DC3->DC5 count=%d, DC5->DC6 count=%d\n", count[0], count[1]);
+}
+
+static bool has_dmc(unsigned int fd)
+{
+	char buf[512];
+
+	igt_debugfs_read(fd, "i915_dmc_info", buf);
+	return strstr(buf, "fw loaded: yes");
+}
+
+static void check_vblanks(data_t *data)
+{
+	unsigned int first_vblank, second_vblank;
+	int wait = 30; /* Takes about 2.5 seconds for DC_OFF disable */
+
+	first_vblank = get_vblank(data->drm_fd, data->pipe);
+
+	if (has_dmc(data->drm_fd)) {
+		unsigned int new_dc[2], old_dc[2];
+
+		dmc_read_counts(data->drm_fd, new_dc);
+		do {
+			memcpy(old_dc, new_dc, sizeof(new_dc));
+			usleep(100 * 1000);
+			dmc_read_counts(data->drm_fd, new_dc);
+		} while (!memcmp(old_dc, new_dc, sizeof(new_dc)) && --wait);
+
+		igt_assert(wait);
+
+	} else {
+		sleep(3);
+	}
+
+	second_vblank = get_vblank(data->drm_fd, data->pipe);
+	igt_debug("vblank count went from %d to %d in %d ms.\n",
+		  first_vblank, second_vblank,
+		  has_dmc(data->drm_fd) ? (30 - wait) * 100 : 3000);
+
+	igt_assert_lt(first_vblank, second_vblank);
+}
+
 static bool drrs_disabled(data_t *data)
 {
 	char buf[512];
@@ -572,6 +636,13 @@  int main(int argc, char *argv[])
 		}
 	}
 
+	igt_subtest("vblank") {
+		setup_test_plane(&data);
+		igt_assert(wait_psr_entry(&data));
+		check_vblanks(&data);
+		test_cleanup(&data);
+	}
+
 	igt_subtest_f("dpms_off_psr_active") {
 		data.test_plane = DRM_PLANE_TYPE_PRIMARY;
 		data.op = RENDER;