Message ID | 1493138713-2319-8-git-send-email-brian.starkey@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Apr 25, 2017 at 05:45:13PM +0100, Brian Starkey wrote: > If "video=" is specified on the kernel command-line, use it to override > the default mode in kmstest_get_connector_default_mode. > > If a mode override was provided on the command-line, it was probably for > good reason so we should honor it. Isn't the kernel marking the cmdline mode as preferred already? And if not, maybe it should. > > Signed-off-by: Brian Starkey <brian.starkey@arm.com> > --- > 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@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Tue, Apr 25, 2017 at 07:58:18PM +0300, Ville Syrjälä wrote: >On Tue, Apr 25, 2017 at 05:45:13PM +0100, Brian Starkey wrote: >> If "video=" is specified on the kernel command-line, use it to override >> the default mode in kmstest_get_connector_default_mode. >> >> If a mode override was provided on the command-line, it was probably for >> good reason so we should honor it. > >Isn't the kernel marking the cmdline mode as preferred already? And if >not, maybe it should. > It doesn't as far as I've seen. It uses the cmdline mode for setting up the fbdev emulation but I don't think it marks the mode list (or we aren't calling the helper that does it). I'll have a look at what it would take to do that. -Brian >> >> Signed-off-by: Brian Starkey <brian.starkey@arm.com> >> --- >> 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@lists.freedesktop.org >> https://lists.freedesktop.org/mailman/listinfo/intel-gfx > >-- >Ville Syrjälä >Intel OTC
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) {
If "video=" is specified on the kernel command-line, use it to override the default mode in kmstest_get_connector_default_mode. If a mode override was provided on the command-line, it was probably for good reason so we should honor it. Signed-off-by: Brian Starkey <brian.starkey@arm.com> --- lib/igt_kms.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+)