Signed-off-by: Brian Starkey <brian.starkey@xxxxxxx>
---
lib/igt_kms.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 135 insertions(+)
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 474aa005b9fa..97f80a46354d 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -766,6 +766,131 @@ void kmstest_force_edid(int drm_fd, drmModeConnector *connector,
igt_assert(ret != -1);
}
+/*
+ * Extract xres, yres, refresh and interlaced from a string of the form:
+ * <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
+ * xres and yres must be specified, refresh is optional and will be set to
+ * -1 if not present. interlaced defaults to false.
+ */
+static int parse_cmdline_mode(char *video_str, unsigned int *xres,
+ unsigned int *yres,
+ int *refresh, bool *interlaced)
+{
+ int match, len = strlen(video_str);
+ char *token = strtok(video_str, "@");
+
+ if (!token)
+ return -1;
+
+ *interlaced = false;
+ *refresh = -1;
+
+ match = sscanf(token, "%dx%d", xres, yres);
+ if (match != 2)
+ return -1;
+
+ if (strlen(token) < len - 1) {
+ token += strlen(token) + 1;
+
+ match = sscanf(token, "%d", refresh);
+ if (match != 1 || (*refresh < 0))
+ return -1;
+
+ if (strchr(token, 'i'))
+ *interlaced = true;
+ }
+
+ return 0;
+}
+
+static const drmModeModeInfo *
+connector_match_cmdline_mode(const drmModeConnector *connector,
+ unsigned int xres, unsigned int yres, int refresh,
+ bool interlaced)
+{
+ const drmModeModeInfo *mode = NULL;
+ int i;
+
+ for (i = 0; i < connector->count_modes; i++) {
+ mode = &connector->modes[i];
+ if (mode->hdisplay == xres &&
+ mode->vdisplay == yres &&
+ (refresh < 0 || refresh == mode->vrefresh) &&
+ interlaced == !!(mode->flags & DRM_MODE_FLAG_INTERLACE))
+ return mode;
+ }
+
+ return NULL;
+}
+
+static const drmModeModeInfo *
+kmstest_get_cmdline_mode(int drm_fd, drmModeConnector *connector)
+{
+ char c, *str = NULL, *cursor, *conn_name = NULL;
+ const drmModeModeInfo *mode = NULL;
+ unsigned int size = 0;
+ FILE *fp = NULL;
+
+ fp = fopen("/proc/cmdline", "r");
+ if (!fp)
+ return NULL;
+
+ /* lseek/fseek+ftell/stat don't work on /proc/cmdline */
+ while (fread(&c, 1, 1, fp))
+ size++;
+ rewind(fp);
+
+ str = calloc(1, size + 1);
+ if (!str)
+ goto done;
+
+ if (fread(str, 1, size, fp) != size)
+ goto done;
+
+ if (!asprintf(&conn_name, "%s-%d:",
+ kmstest_connector_type_str(connector->connector_type),
+ connector->connector_type_id))
+ goto done;
+
+ cursor = str;
+ while ((cursor = strstr(cursor, "video="))) {
+ unsigned int xres, yres;
+ bool interlaced;
+ int refresh;
+
+ cursor += strlen("video=");
+ cursor = strtok(cursor, " \n");
+ if (!cursor)
+ break;
+
+ /* Strip the name if it matches ours */
+ if (!strncmp(cursor, conn_name, strlen(conn_name)))
+ cursor += strlen(conn_name);
+
+ /*
+ * Consider this "video=" specification only if it has no
+ * name. If the name matched, we would have already stripped it
+ * above
+ */
+ if (!strstr(cursor, ":") &&
+ !parse_cmdline_mode(cursor, &xres, &yres, &refresh, &interlaced)) {
+ mode = connector_match_cmdline_mode(connector, xres,
+ yres, refresh,
+ interlaced);
+ if (mode)
+ break;
+ }
+
+ cursor += strlen(cursor) + 1;
+ }
+
+done:
+ free(conn_name);
+ free(str);
+ fclose(fp);
+ return mode;
+}
+
/**
* kmstest_get_connector_default_mode:
* @drm_fd: DRM fd
@@ -773,6 +898,8 @@ void kmstest_force_edid(int drm_fd, drmModeConnector *connector,
* @mode: libdrm mode
*
* Retrieves the default mode for @connector and stores it in @mode.
+ * If video= is specified (optionally for this specific connector) on the
+ * kernel command line, then it is used as the default.
*
* Returns: true on success, false on failure
*/
@@ -780,6 +907,7 @@ bool kmstest_get_connector_default_mode(int drm_fd, drmModeConnector *connector,
drmModeModeInfo *mode)
{
int i;
+ const drmModeModeInfo *cmdline_mode;
if (!connector->count_modes) {
igt_warn("no modes for connector %d\n",
@@ -787,6 +915,13 @@ bool kmstest_get_connector_default_mode(int drm_fd, drmModeConnector *connector,
return false;
}
+ cmdline_mode = kmstest_get_cmdline_mode(drm_fd, connector);
+ if (cmdline_mode) {
+ *mode = *cmdline_mode;
+ igt_debug("Using cmdline mode\n");
+ return true;
+ }
+
for (i = 0; i < connector->count_modes; i++) {
if (i == 0 ||
connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) {
--
1.7.9.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://lists.freedesktop.org/mailman/listinfo/intel-gfx