diff --git a/lib/igt_debugfs.c b/lib/igt_debugfs.c
index afb83617b85b..1bbbabc9f1c9 100644
--- a/lib/igt_debugfs.c
+++ b/lib/igt_debugfs.c
@@ -25,6 +25,7 @@
 #include <inttypes.h>
 #include <sys/stat.h>
 #include <sys/mount.h>
+#include <dirent.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -247,6 +248,10 @@ bool igt_debugfs_search(const char *filename, const char *substring)
  * Pipe CRC
  */
 
+#define CRC_DEFAULTS		0
+#define CRC_FORCE_LEGACY	(1 << 0)
+#define CRC_NONBLOCK		(1 << 1)
+
 /**
  * igt_assert_crc_equal:
  * @a: first pipe CRC value
@@ -280,25 +285,23 @@ char *igt_crc_to_string(igt_crc_t *crc)
 {
 	char buf[128];
 
-	igt_assert_eq(crc->n_words, 5);
-
 	sprintf(buf, "%08x %08x %08x %08x %08x", crc->crc[0],
 		crc->crc[1], crc->crc[2], crc->crc[3], crc->crc[4]);
 
 	return strdup(buf);
 }
 
+#define MAX_CRC_ENTRIES 10
+#define MAX_LINE_LEN (10 + 11 * MAX_CRC_ENTRIES + 1)
+
 /* (6 fields, 8 chars each, space separated (5) + '\n') */
-#define PIPE_CRC_LINE_LEN       (6 * 8 + 5 + 1)
-/* account for \'0' */
-#define PIPE_CRC_BUFFER_LEN     (PIPE_CRC_LINE_LEN + 1)
+#define LEGACY_LINE_LEN       (6 * 8 + 5 + 1)
 
 struct _igt_pipe_crc {
 	int ctl_fd;
 	int crc_fd;
-	int line_len;
-	int buffer_len;
 	int flags;
+	bool is_legacy;
 
 	enum pipe pipe;
 	enum intel_pipe_crc_source source;
@@ -319,23 +322,39 @@ static const char *pipe_crc_sources[] = {
 
 static const char *pipe_crc_source_name(enum intel_pipe_crc_source source)
 {
-        return pipe_crc_sources[source];
+	return pipe_crc_sources[source];
 }
 
 static bool igt_pipe_crc_do_start(igt_pipe_crc_t *pipe_crc)
 {
 	char buf[64];
+	int mode = O_RDONLY;
 
 	/* Stop first just to make sure we don't have lingering state left. */
 	igt_pipe_crc_stop(pipe_crc);
 
-	sprintf(buf, "pipe %s %s", kmstest_pipe_name(pipe_crc->pipe),
-		pipe_crc_source_name(pipe_crc->source));
+	if (pipe_crc->is_legacy)
+		sprintf(buf, "pipe %s %s", kmstest_pipe_name(pipe_crc->pipe),
+			pipe_crc_source_name(pipe_crc->source));
+	else
+		sprintf(buf, "%s", pipe_crc_source_name(pipe_crc->source));
+
 	errno = 0;
 	igt_assert_eq(write(pipe_crc->ctl_fd, buf, strlen(buf)), strlen(buf));
 	if (errno != 0)
 		return false;
 
+	if (!pipe_crc->is_legacy) {
+		sprintf(buf, "crtc-%d/crc/data", pipe_crc->pipe);
+		errno = 0;
+		if (pipe_crc->flags & CRC_NONBLOCK)
+			mode |= O_NONBLOCK;
+		pipe_crc->crc_fd = igt_debugfs_open(buf, mode);
+		if (pipe_crc->crc_fd == -1 && errno == EINVAL)
+			return false;
+		igt_assert_eq(errno, 0);
+	}
+
 	return true;
 }
 
@@ -349,15 +368,38 @@ static void igt_pipe_crc_pipe_off(int fd, enum pipe pipe)
 
 static void igt_pipe_crc_reset(void)
 {
+	igt_debugfs_t *debugfs = __igt_debugfs_singleton();
 	int fd;
+	struct dirent *dirent;
+	char buf[128];
+	const char *cmd = "none";
+	DIR *dir;
 
 	fd = igt_debugfs_open("i915_display_crc_ctl", O_WRONLY);
+	if (fd != -1) {
+		igt_pipe_crc_pipe_off(fd, PIPE_A);
+		igt_pipe_crc_pipe_off(fd, PIPE_B);
+		igt_pipe_crc_pipe_off(fd, PIPE_C);
+
+		close(fd);
+	}
 
-	igt_pipe_crc_pipe_off(fd, PIPE_A);
-	igt_pipe_crc_pipe_off(fd, PIPE_B);
-	igt_pipe_crc_pipe_off(fd, PIPE_C);
+	dir = opendir(debugfs->dri_path);
+	if (dir) {
+		while ((dirent = readdir(dir))) {
+			if (strcmp(dirent->d_name, "crtc-") != 0)
+				continue;
 
-	close(fd);
+			sprintf(buf, "%s/%s/crc/control", debugfs->dri_path,
+				dirent->d_name);
+			fd = open(buf, O_WRONLY);
+
+			igt_assert_eq(write(fd, cmd, strlen(cmd)), strlen(cmd));
+
+			close(fd);
+		}
+		closedir(dir);
+	}
 }
 
 static void pipe_crc_exit_handler(int sig)
@@ -379,13 +421,16 @@ void igt_require_pipe_crc(void)
 	size_t written;
 	int ret;
 
-	ctl = igt_debugfs_fopen("i915_display_crc_ctl", "r+");
-	igt_require_f(ctl,
-		      "No display_crc_ctl found, kernel too old\n");
-	written = fwrite(cmd, 1, strlen(cmd), ctl);
-	ret = fflush(ctl);
-	igt_require_f((written == strlen(cmd) && ret == 0) || errno != ENODEV,
-		      "CRCs not supported on this platform\n");
+	ctl = igt_debugfs_fopen("crtc-0/crc/control", "r+");
+	if (!ctl) {
+		ctl = igt_debugfs_fopen("i915_display_crc_ctl", "r+");
+		igt_require_f(ctl,
+			      "No display_crc_ctl found, kernel too old\n");
+		written = fwrite(cmd, 1, strlen(cmd), ctl);
+		ret = fflush(ctl);
+		igt_require_f((written == strlen(cmd) && ret == 0) || errno != ENODEV,
+			      "CRCs not supported on this platform\n");
+	}
 
 	fclose(ctl);
 }
@@ -395,20 +440,34 @@ pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source, int flags)
 {
 	igt_pipe_crc_t *pipe_crc;
 	char buf[128];
+	int mode = O_RDONLY;
 
 	igt_install_exit_handler(pipe_crc_exit_handler);
 
 	pipe_crc = calloc(1, sizeof(struct _igt_pipe_crc));
 
-	pipe_crc->ctl_fd = igt_debugfs_open("i915_display_crc_ctl", O_WRONLY);
-	igt_assert(pipe_crc->ctl_fd != -1);
+	if (!(flags & CRC_FORCE_LEGACY)) {
+		sprintf(buf, "crtc-%d/crc/control", pipe);
+		pipe_crc->ctl_fd = igt_debugfs_open(buf, O_WRONLY);
+	}
+
+	if (pipe_crc->ctl_fd == -1 || flags & CRC_FORCE_LEGACY) {
+		pipe_crc->ctl_fd = igt_debugfs_open("i915_display_crc_ctl",
+						    O_WRONLY);
+		igt_assert(pipe_crc->ctl_fd != -1);
+		pipe_crc->is_legacy = true;
+	}
 
-	sprintf(buf, "i915_pipe_%s_crc", kmstest_pipe_name(pipe));
-	pipe_crc->crc_fd = igt_debugfs_open(buf, flags);
-	igt_assert(pipe_crc->crc_fd != -1);
+	if (pipe_crc->is_legacy) {
+		sprintf(buf, "i915_pipe_%s_crc", kmstest_pipe_name(pipe));
+		if (flags & CRC_NONBLOCK)
+			mode |= O_NONBLOCK;
+		pipe_crc->crc_fd = igt_debugfs_open(buf, mode);
+		igt_assert(pipe_crc->crc_fd != -1);
+	} else {
+		pipe_crc->crc_fd = -1;
+	}
 
-	pipe_crc->line_len = PIPE_CRC_LINE_LEN;
-	pipe_crc->buffer_len = PIPE_CRC_BUFFER_LEN;
 	pipe_crc->pipe = pipe;
 	pipe_crc->source = source;
 	pipe_crc->flags = flags;
@@ -431,7 +490,7 @@ pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source, int flags)
 igt_pipe_crc_t *
 igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
 {
-	return pipe_crc_new(pipe, source, O_RDONLY);
+	return pipe_crc_new(pipe, source, CRC_DEFAULTS);
 }
 
 /**
@@ -449,7 +508,43 @@ igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source)
 igt_pipe_crc_t *
 igt_pipe_crc_new_nonblock(enum pipe pipe, enum intel_pipe_crc_source source)
 {
-	return pipe_crc_new(pipe, source, O_RDONLY | O_NONBLOCK);
+	return pipe_crc_new(pipe, source, CRC_NONBLOCK);
+}
+
+/**
+ * igt_pipe_crc_new_legacy:
+ * @pipe: display pipe to use as source
+ * @source: CRC tap point to use as source
+ *
+ * This sets up a new pipe CRC capture object for the given @pipe and @source
+ * in blocking mode. The old i915-specific ABI will be used.
+ *
+ * Returns: A pipe CRC object for the given @pipe and @source. The library
+ * assumes that the source is always available since recent kernels support at
+ * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
+ */
+igt_pipe_crc_t *igt_pipe_crc_new_legacy(enum pipe pipe,
+					enum intel_pipe_crc_source source)
+{
+	return pipe_crc_new(pipe, source, CRC_FORCE_LEGACY);
+}
+
+/**
+ * igt_pipe_crc_new_nonblock_legacy:
+ * @pipe: display pipe to use as source
+ * @source: CRC tap point to use as source
+ *
+ * This sets up a new pipe CRC capture object for the given @pipe and @source
+ * in nonblocking mode. The old i915-specific ABI will be used.
+ *
+ * Returns: A pipe CRC object for the given @pipe and @source. The library
+ * assumes that the source is always available since recent kernels support at
+ * least INTEL_PIPE_CRC_SOURCE_AUTO everywhere.
+ */
+igt_pipe_crc_t *igt_pipe_crc_new_nonblock_legacy(enum pipe pipe,
+						 enum intel_pipe_crc_source source)
+{
+	return pipe_crc_new(pipe, source, CRC_NONBLOCK | CRC_FORCE_LEGACY);
 }
 
 /**
@@ -468,34 +563,59 @@ void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc)
 	free(pipe_crc);
 }
 
-static bool pipe_crc_init_from_string(igt_crc_t *crc, const char *line)
+static bool pipe_crc_init_from_string(igt_pipe_crc_t *pipe_crc, igt_crc_t *crc,
+				      const char *line)
 {
-	int n;
+	int n, i;
+	const char *buf;
+
+	if (pipe_crc->is_legacy) {
+		crc->has_valid_frame = true;
+		crc->n_words = 5;
+		n = sscanf(line, "%8u %8x %8x %8x %8x %8x", &crc->frame,
+			   &crc->crc[0], &crc->crc[1], &crc->crc[2],
+			   &crc->crc[3], &crc->crc[4]);
+		return n == 6;
+	}
+
+	if (strncmp(line, "XXXXXXXXXX", 10) == 0)
+		crc->has_valid_frame = false;
+	else {
+		crc->has_valid_frame = true;
+		crc->frame = strtoul(line, NULL, 16);
+	}
+
+	buf = line + 10;
+	for (i = 0; *buf != '\n'; i++, buf += 11)
+		crc->crc[i] = strtoul(buf, NULL, 16);
 
-	crc->n_words = 5;
-	n = sscanf(line, "%8u %8x %8x %8x %8x %8x", &crc->frame, &crc->crc[0],
-		   &crc->crc[1], &crc->crc[2], &crc->crc[3], &crc->crc[4]);
-	return n == 6;
+	crc->n_words = i;
+
+	return true;
 }
 
 static int read_crc(igt_pipe_crc_t *pipe_crc, igt_crc_t *out)
 {
 	ssize_t bytes_read;
-	char buf[pipe_crc->buffer_len];
+	char buf[MAX_LINE_LEN + 1];
+	size_t read_len;
+
+	if (pipe_crc->is_legacy)
+		read_len = LEGACY_LINE_LEN;
+	else
+		read_len = MAX_LINE_LEN;
 
 	igt_set_timeout(5, "CRC reading");
-	bytes_read = read(pipe_crc->crc_fd, &buf, pipe_crc->line_len);
+	bytes_read = read(pipe_crc->crc_fd, &buf, read_len);
 	igt_reset_timeout();
 
 	if (bytes_read < 0 && errno == EAGAIN) {
-		igt_assert(pipe_crc->flags & O_NONBLOCK);
+		igt_assert(pipe_crc->flags & CRC_NONBLOCK);
 		bytes_read = 0;
-	} else {
-		igt_assert_eq(bytes_read, pipe_crc->line_len);
 	}
 	buf[bytes_read] = '\0';
 
-	if (bytes_read && !pipe_crc_init_from_string(out, buf))
+	if (bytes_read && !pipe_crc_init_from_string(pipe_crc, out, buf))
 		return -EINVAL;
 
 	return bytes_read;
@@ -519,15 +639,18 @@ void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc)
 
 	igt_assert(igt_pipe_crc_do_start(pipe_crc));
 
-	/*
-	 * For some no yet identified reason, the first CRC is bonkers. So
-	 * let's just wait for the next vblank and read out the buggy result.
-	 *
-	 * On CHV sometimes the second CRC is bonkers as well, so don't trust
-	 * that one either.
-	 */
-	read_one_crc(pipe_crc, &crc);
-	read_one_crc(pipe_crc, &crc);
+	if (pipe_crc->is_legacy) {
+		/*
+		 * For some no yet identified reason, the first CRC is
+		 * bonkers. So let's just wait for the next vblank and read
+		 * out the buggy result.
+		 *
+		 * On CHV sometimes the second CRC is bonkers as well, so
+		 * don't trust that one either.
+		 */
+		read_one_crc(pipe_crc, &crc);
+		read_one_crc(pipe_crc, &crc);
+	}
 }
 
 /**
@@ -540,8 +663,15 @@ void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc)
 {
 	char buf[32];
 
-	sprintf(buf, "pipe %s none", kmstest_pipe_name(pipe_crc->pipe));
-	igt_assert_eq(write(pipe_crc->ctl_fd, buf, strlen(buf)), strlen(buf));
+	if (pipe_crc->is_legacy) {
+		sprintf(buf, "pipe %s none",
+			kmstest_pipe_name(pipe_crc->pipe));
+		igt_assert_eq(write(pipe_crc->ctl_fd, buf, strlen(buf)),
+			      strlen(buf));
+	} else {
+		close(pipe_crc->crc_fd);
+		pipe_crc->crc_fd = -1;
+	}
 }
 
 /**
diff --git a/lib/igt_debugfs.h b/lib/igt_debugfs.h
index 1a757b84a19a..84d5c0a0a84b 100644
--- a/lib/igt_debugfs.h
+++ b/lib/igt_debugfs.h
@@ -60,6 +60,7 @@ bool igt_debugfs_search(const char *filename, const char *substring);
  */
 typedef struct _igt_pipe_crc igt_pipe_crc_t;
 
+#define DRM_MAX_CRC_NR 10
 /**
  * igt_crc_t:
  * @frame: frame number of the capture CRC
@@ -71,8 +72,9 @@ typedef struct _igt_pipe_crc igt_pipe_crc_t;
  */
 typedef struct {
 	uint32_t frame;
+	bool has_valid_frame;
 	int n_words;
-	uint32_t crc[5];
+	uint32_t crc[DRM_MAX_CRC_NR];
 } igt_crc_t;
 
 /**
@@ -117,6 +119,10 @@ igt_pipe_crc_t *
 igt_pipe_crc_new(enum pipe pipe, enum intel_pipe_crc_source source);
 igt_pipe_crc_t *
 igt_pipe_crc_new_nonblock(enum pipe pipe, enum intel_pipe_crc_source source);
+igt_pipe_crc_t *
+igt_pipe_crc_new_legacy(enum pipe pipe, enum intel_pipe_crc_source source);
+igt_pipe_crc_t *
+igt_pipe_crc_new_nonblock_legacy(enum pipe pipe, enum intel_pipe_crc_source source);
 void igt_pipe_crc_free(igt_pipe_crc_t *pipe_crc);
 void igt_pipe_crc_start(igt_pipe_crc_t *pipe_crc);
 void igt_pipe_crc_stop(igt_pipe_crc_t *pipe_crc);
diff --git a/tests/kms_pipe_crc_basic.c b/tests/kms_pipe_crc_basic.c
index 4de53bc77a3a..3de974c315e7 100644
--- a/tests/kms_pipe_crc_basic.c
+++ b/tests/kms_pipe_crc_basic.c
@@ -58,10 +58,31 @@ static void test_bad_command(data_t *data, const char *cmd)
 	fclose(ctl);
 }
 
+static void test_bad_source(data_t *data)
+{
+	FILE *f;
+	size_t written;
+	const char *source = "foo";
+
+	f = igt_debugfs_fopen("crtc-0/crc/control", "w");
+	igt_require(f);
+	written = fwrite(source, 1, strlen(source), f);
+	fflush(f);
+	igt_assert_eq(written, strlen(source));
+	igt_assert(!ferror(f));
+	igt_assert(!errno);
+	fclose(f);
+
+	f = igt_debugfs_fopen("crtc-0/crc/data", "w");
+	igt_assert(!f);
+	igt_assert_eq(errno, EINVAL);
+}
+
 #define N_CRCS	3
 
 #define TEST_SEQUENCE (1<<0)
 #define TEST_NONBLOCK (1<<1)
+#define TEST_LEGACY (1<<2)
 
 static int
 test_read_crc_for_output(data_t *data, int pipe, igt_output_t *output,
@@ -104,10 +125,22 @@ test_read_crc_for_output(data_t *data, int pipe, igt_output_t *output,
 
 		igt_display_commit(display);
 
-		if (flags & TEST_NONBLOCK)
-			pipe_crc = igt_pipe_crc_new_nonblock(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
-		else
-			pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);
+		if (flags & TEST_LEGACY) {
+			if (flags & TEST_NONBLOCK)
+				pipe_crc = igt_pipe_crc_new_nonblock_legacy(
+						pipe,
+						INTEL_PIPE_CRC_SOURCE_AUTO);
+			else
+				pipe_crc = igt_pipe_crc_new_legacy(pipe,
+						INTEL_PIPE_CRC_SOURCE_AUTO);
+		} else {
+			if (flags & TEST_NONBLOCK)
+				pipe_crc = igt_pipe_crc_new_nonblock(pipe,
+						INTEL_PIPE_CRC_SOURCE_AUTO);
+			else
+				pipe_crc = igt_pipe_crc_new(pipe,
+						INTEL_PIPE_CRC_SOURCE_AUTO);
+		}
 
 		igt_pipe_crc_start(pipe_crc);
 
@@ -143,9 +176,16 @@ test_read_crc_for_output(data_t *data, int pipe, igt_output_t *output,
 		for (j = 0; j < (n_crcs - 1); j++)
 			igt_assert_crc_equal(&crcs[j], &crcs[j + 1]);
 
-		if (flags & TEST_SEQUENCE)
-			for (j = 0; j < (n_crcs - 1); j++)
-				igt_assert_eq(crcs[j].frame + 1, crcs[j + 1].frame);
+		if (flags & TEST_SEQUENCE) {
+			if (!crcs[0].has_valid_frame) {
+				igt_info("Skipping connector, its 'auto' source doesn't give us frame numbers.\n");
+				goto skip;
+			} else {
+				for (j = 0; j < (n_crcs - 1); j++)
+					igt_assert_eq(crcs[j].frame + 1,
+						      crcs[j + 1].frame);
+			}
+		}
 
 		free(crcs);
 		igt_pipe_crc_free(pipe_crc);
@@ -156,6 +196,17 @@ test_read_crc_for_output(data_t *data, int pipe, igt_output_t *output,
 	}
 
 	return 1;
+
+skip:
+	if (crcs)
+		free(crcs);
+	igt_pipe_crc_free(pipe_crc);
+	igt_remove_fb(data->drm_fd, &data->fb);
+	igt_plane_set_fb(primary, NULL);
+
+	igt_output_set_pipe(output, PIPE_ANY);
+
+	return 0;
 }
 
 static void test_read_crc(data_t *data, int pipe, unsigned flags)
@@ -166,8 +217,10 @@ static void test_read_crc(data_t *data, int pipe, unsigned flags)
 
 	igt_skip_on(pipe >= data->display.n_pipes);
 
-	for_each_connected_output(display, output) {
+	if (flags & TEST_LEGACY)
+		igt_require_intel(data->drm_fd);
 
+	for_each_connected_output(display, output) {
 		igt_info("%s: Testing connector %s using pipe %s\n",
 			 igt_subtest_name(), igt_output_name(output),
 			 kmstest_pipe_name(pipe));
@@ -178,6 +231,46 @@ static void test_read_crc(data_t *data, int pipe, unsigned flags)
 	igt_require_f(valid_connectors, "No connector found for pipe %i\n", pipe);
 }
 
+static void test_read_crcs(data_t *data, unsigned flags)
+{
+	const char *postfix;
+
+	if (flags & TEST_LEGACY)
+		postfix = "-legacy";
+	else
+		postfix = "";
+
+	for (int i = 0; i < 3; i++) {
+		igt_subtest_f("read-crc-pipe-%c%s", 'A'+i, postfix)
+			test_read_crc(data, i, 0 | flags);
+
+		igt_subtest_f("read-crc-pipe-%c-frame-sequence%s", 'A'+i, postfix)
+			test_read_crc(data, i, TEST_SEQUENCE | flags);
+
+		igt_subtest_f("nonblocking-crc-pipe-%c%s", 'A'+i, postfix)
+			test_read_crc(data, i, TEST_NONBLOCK | flags);
+
+		igt_subtest_f("nonblocking-crc-pipe-%c-frame-sequence%s",
+			      'A'+i, postfix)
+			test_read_crc(data, i, TEST_SEQUENCE | TEST_NONBLOCK | flags);
+
+		igt_subtest_f("suspend-read-crc-pipe-%c%s", 'A'+i, postfix) {
+			igt_skip_on(i >= data->display.n_pipes);
+			igt_system_suspend_autoresume();
+
+			test_read_crc(data, i, flags);
+		}
+
+		igt_subtest_f("hang-read-crc-pipe-%c%s", 'A'+i, postfix) {
+			igt_hang_ring_t hang =
+				igt_hang_ring(data->drm_fd, I915_EXEC_RENDER);
+			test_read_crc(data, i, flags);
+			igt_post_hang_ring(data->drm_fd, hang);
+			test_read_crc(data, i, flags);
+		}
+	}
+}
+
 data_t data = {0, };
 
 igt_main
@@ -185,7 +278,7 @@ igt_main
 	igt_skip_on_simulation();
 
 	igt_fixture {
-		data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
+		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
 
 		igt_enable_connectors();
 
@@ -196,47 +289,34 @@ igt_main
 		igt_display_init(&data.display, data.drm_fd);
 	}
 
-	igt_subtest("bad-pipe")
+	igt_subtest("bad-source") {
+		test_bad_source(&data);
+	}
+
+	test_read_crcs(&data, 0);
+
+	igt_subtest("bad-pipe-legacy") {
+		igt_require_intel(data.drm_fd);
 		test_bad_command(&data, "pipe D none");
+	}
 
-	igt_subtest("bad-source")
+	igt_subtest("bad-source-legacy") {
+		igt_require_intel(data.drm_fd);
 		test_bad_command(&data, "pipe A foo");
+	}
 
-	igt_subtest("bad-nb-words-1")
+	igt_subtest("bad-nb-words-1-legacy") {
+		igt_require_intel(data.drm_fd);
 		test_bad_command(&data, "pipe foo");
+	}
 
-	igt_subtest("bad-nb-words-3")
+	igt_subtest("bad-nb-words-3-legacy") {
+		igt_require_intel(data.drm_fd);
 		test_bad_command(&data, "pipe A none option");
-
-	for (int i = 0; i < 3; i++) {
-		igt_subtest_f("read-crc-pipe-%c", 'A'+i)
-			test_read_crc(&data, i, 0);
-
-		igt_subtest_f("read-crc-pipe-%c-frame-sequence", 'A'+i)
-			test_read_crc(&data, i, TEST_SEQUENCE);
-
-		igt_subtest_f("nonblocking-crc-pipe-%c", 'A'+i)
-			test_read_crc(&data, i, TEST_NONBLOCK);
-
-		igt_subtest_f("nonblocking-crc-pipe-%c-frame-sequence", 'A'+i)
-			test_read_crc(&data, i, TEST_SEQUENCE | TEST_NONBLOCK);
-
-		igt_subtest_f("suspend-read-crc-pipe-%c", 'A'+i) {
-			igt_skip_on(i >= data.display.n_pipes);
-			igt_system_suspend_autoresume();
-
-			test_read_crc(&data, i, 0);
-		}
-
-		igt_subtest_f("hang-read-crc-pipe-%c", 'A'+i) {
-			igt_hang_ring_t hang =
-				igt_hang_ring(data.drm_fd, I915_EXEC_RENDER);
-			test_read_crc(&data, i, 0);
-			igt_post_hang_ring(data.drm_fd, hang);
-			test_read_crc(&data, i, 0);
-		}
 	}
 
+	test_read_crcs(&data, TEST_LEGACY);
+
 	igt_fixture {
 		igt_display_fini(&data.display);
 	}
