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 <[email protected]>
> ---
>  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
> [email protected]
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to