diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 5e628127a130..6042aaae7cca 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -901,7 +901,9 @@ static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe)
 	drmModeModeInfo *mode = NULL;
 	int i;
 
-	pipe->mode = NULL;
+	/* If set_preferred is used, a mode is already set. */
+	if (pipe->mode)
+		goto find_crtc;
 
 	for (i = 0; i < (int)pipe->num_cons; i++) {
 		mode = connector_find_mode(dev, pipe->con_ids[i],
@@ -913,7 +915,9 @@ static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe)
 			return -EINVAL;
 		}
 	}
+	pipe->mode = mode;
 
+find_crtc:
 	/* If the CRTC ID was specified, get the corresponding CRTC. Otherwise
 	 * locate a CRTC that can be attached to all the connectors.
 	 */
@@ -935,7 +939,6 @@ static int pipe_find_crtc_and_mode(struct device *dev, struct pipe_arg *pipe)
 		return -EINVAL;
 	}
 
-	pipe->mode = mode;
 	pipe->crtc->mode = mode;
 
 	return 0;
@@ -1813,7 +1816,7 @@ static void parse_fill_patterns(char *arg)
 
 static void usage(char *name)
 {
-	fprintf(stderr, "usage: %s [-acDdefMPpsCvw]\n", name);
+	fprintf(stderr, "usage: %s [-acDdefMPpsCvrw]\n", name);
 
 	fprintf(stderr, "\n Query options:\n\n");
 	fprintf(stderr, "\t-c\tlist connectors\n");
@@ -1826,6 +1829,7 @@ static void usage(char *name)
 	fprintf(stderr, "\t-s <connector_id>[,<connector_id>][@<crtc_id>]:<mode>[-<vrefresh>][@<format>]\tset a mode\n");
 	fprintf(stderr, "\t-C\ttest hw cursor\n");
 	fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
+	fprintf(stderr, "\t-r\tset the preferred mode\n");
 	fprintf(stderr, "\t-w <obj_id>:<prop_name>:<value>\tset property\n");
 	fprintf(stderr, "\t-a \tuse atomic API\n");
 	fprintf(stderr, "\t-F pattern1,pattern2\tspecify fill patterns\n");
@@ -1874,6 +1878,9 @@ static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
 	char *endp;
 
 	for (i = 0; i < pipe->num_cons; i++) {
+		/* If set_preferred is used, the connector is already resolved. */
+		if (pipe->con_ids[i])
+			continue;
 		id = strtoul(pipe->cons[i], &endp, 10);
 		if (endp == pipe->cons[i]) {
 			connector = get_connector_by_name(dev, pipe->cons[i]);
@@ -1885,14 +1892,62 @@ static int pipe_resolve_connectors(struct device *dev, struct pipe_arg *pipe)
 
 			id = connector->connector_id;
 		}
-
 		pipe->con_ids[i] = id;
 	}
 
 	return 0;
 }
 
-static char optstr[] = "acdD:efF:M:P:ps:Cvw:";
+static char optstr[] = "acdD:efF:M:P:ps:Cvrw:";
+
+static int pipe_find_preferred(struct device *dev, struct pipe_arg *pipe)
+{
+	drmModeRes *res = dev->resources->res;
+	drmModeConnector *con = NULL;
+	char *con_str;
+	int i;
+
+	for (i = 0; i < res->count_connectors; i++) {
+		con = drmModeGetConnector(dev->fd, res->connectors[i]);
+		if (con->connection == DRM_MODE_CONNECTED)
+			break;
+		drmModeFreeConnector(con);
+		con = NULL;
+	}
+
+	if (!con) {
+		printf("no connected connector!\n");
+		return -1;
+	}
+
+	con_str = malloc(8);
+	sprintf(con_str, "%d", con->connector_id);
+	strcpy(pipe->format_str, "XR24");
+	pipe->fourcc = util_format_fourcc(pipe->format_str);
+	pipe->num_cons = 1;
+	pipe->con_ids = calloc(1, sizeof(*pipe->con_ids));
+	pipe->cons = calloc(1, sizeof(*pipe->cons));
+	pipe->con_ids[0] = con->connector_id;
+	pipe->cons[0] = (const char*)con_str;
+
+	/* A CRTC possible will be chosen by pipe_find_crtc_and_mode. */
+	pipe->crtc_id = (uint32_t)-1;
+
+	/* Return the first mode if no preferred. */
+	pipe->mode = &con->modes[0];
+	for (i = 0; i < con->count_modes; i++) {
+		drmModeModeInfo *current_mode = &con->modes[i];
+
+		if (current_mode->type & DRM_MODE_TYPE_PREFERRED) {
+			pipe->mode = current_mode;
+			break;
+		}
+	}
+
+	sprintf(pipe->mode_str, "%dx%d", pipe->mode->hdisplay, pipe->mode->vdisplay);
+
+	return 0;
+}
 
 int main(int argc, char **argv)
 {
@@ -1903,6 +1958,7 @@ int main(int argc, char **argv)
 	int drop_master = 0;
 	int test_vsync = 0;
 	int test_cursor = 0;
+	int set_preferred = 0;
 	int use_atomic = 0;
 	char *device = NULL;
 	char *module = NULL;
@@ -1987,6 +2043,9 @@ int main(int argc, char **argv)
 		case 'v':
 			test_vsync = 1;
 			break;
+		case 'r':
+			set_preferred = 1;
+			break;
 		case 'w':
 			prop_args = realloc(prop_args,
 					   (prop_count + 1) * sizeof *prop_args);
@@ -2008,7 +2067,7 @@ int main(int argc, char **argv)
 	}
 
 	if (!args || (args == 1 && use_atomic))
-		encoders = connectors = crtcs = planes = framebuffers = 1;
+		set_preferred = encoders = connectors = crtcs = planes = framebuffers = 1;
 
 	dev.fd = util_open(device, module);
 	if (dev.fd < 0)
@@ -2044,6 +2103,16 @@ int main(int argc, char **argv)
 		return 1;
 	}
 
+	if (set_preferred) {
+		count = 1;
+		pipe_args = calloc(1, sizeof(*pipe_args));
+		ret = pipe_find_preferred(&dev, &pipe_args[0]);
+		if (ret) {
+			fprintf(stderr, "can't get preferred connector and mode: %s\n", strerror(errno));
+			return 1;
+		}
+	}
+
 	for (i = 0; i < count; i++) {
 		if (pipe_resolve_connectors(&dev, &pipe_args[i]) < 0) {
 			free_resources(dev.resources);
