From patchwork Tue Apr 25 16:45:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Starkey X-Patchwork-Id: 9698775 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AA5E16020A for ; Tue, 25 Apr 2017 16:45:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 98C102865D for ; Tue, 25 Apr 2017 16:45:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8C2A928663; Tue, 25 Apr 2017 16:45:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 138942865D for ; Tue, 25 Apr 2017 16:45:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 78FAA6E5BF; Tue, 25 Apr 2017 16:45:27 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from foss.arm.com (foss.arm.com [217.140.101.70]) by gabe.freedesktop.org (Postfix) with ESMTP id 8D2016E5B1 for ; Tue, 25 Apr 2017 16:45:26 +0000 (UTC) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 745511684; Tue, 25 Apr 2017 09:45:26 -0700 (PDT) Received: from e106950-lin.cambridge.arm.com (e106950-lin.cambridge.arm.com [10.2.139.56]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D80E53F4FF; Tue, 25 Apr 2017 09:45:25 -0700 (PDT) From: Brian Starkey To: intel-gfx@lists.freedesktop.org Date: Tue, 25 Apr 2017 17:45:13 +0100 Message-Id: <1493138713-2319-8-git-send-email-brian.starkey@arm.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1493138713-2319-1-git-send-email-brian.starkey@arm.com> References: <1493138713-2319-1-git-send-email-brian.starkey@arm.com> Cc: liviu.dudau@arm.com Subject: [Intel-gfx] [PATCH i-g-t 7/7] lib/igt_kms: Use kernel command line mode if specified X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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: + * x[M][R][-][@][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) {