From patchwork Mon Jun 17 14:51:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999369 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D655314DB for ; Mon, 17 Jun 2019 14:51:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C6C07283A8 for ; Mon, 17 Jun 2019 14:51:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BACD328846; Mon, 17 Jun 2019 14:51:48 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 5C5E62882F for ; Mon, 17 Jun 2019 14:51:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 38B9E892E2; Mon, 17 Jun 2019 14:51:47 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net [217.70.183.199]) by gabe.freedesktop.org (Postfix) with ESMTPS id E2CB7892E2 for ; Mon, 17 Jun 2019 14:51:45 +0000 (UTC) X-Originating-IP: 90.88.23.150 Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 140A3FF802; Mon, 17 Jun 2019 14:51:40 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 01/12] drm/connector: Add documentation for drm_cmdline_mode Date: Mon, 17 Jun 2019 16:51:28 +0200 Message-Id: <963c893c16c6a25fc469b53c726f493d99bdc578.1560783090.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The struct drm_cmdline_mode holds the result of the command line parsers. However, it wasn't documented so far, so let's do that. Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- include/drm/drm_connector.h | 86 +++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index c6f8486d8b8f..c802780b0bfc 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -923,18 +923,100 @@ struct drm_connector_funcs { const struct drm_connector_state *state); }; -/* mode specified on the command line */ +/** + * struct drm_cmdline_mode - DRM Mode passed through the kernel command-line + * + * Each connector can have an initial mode with additional options + * passed through the kernel command line. This structure allows to + * express those parameters and will be filled by the command-line + * parser. + */ struct drm_cmdline_mode { + /** + * @specified: + * + * Has a mode been read from the command-line? + */ bool specified; + + /** + * @refresh_specified: + * + * Did the mode have a preferred refresh rate? + */ bool refresh_specified; + + /** + * @bpp_specified: + * + * Did the mode have a preferred BPP? + */ bool bpp_specified; - int xres, yres; + + /** + * @xres: + * + * Active resolution on the X axis, in pixels. + */ + int xres; + + /** + * @yres: + * + * Active resolution on the Y axis, in pixels. + */ + int yres; + + /** + * @bpp: + * + * Bits per pixels for the mode. + */ int bpp; + + /** + * @refresh: + * + * Refresh rate, in Hertz. + */ int refresh; + + /** + * @rb: + * + * Do we need to use reduced blanking? + */ bool rb; + + /** + * @interlace: + * + * The mode is interlaced. + */ bool interlace; + + /** + * @cvt: + * + * The timings will be calculated using the VESA Coordinated + * Video Timings instead of looking up the mode from a table. + */ bool cvt; + + /** + * @margins: + * + * Add margins to the mode calculation (1.8% of xres rounded + * down to 8 pixels and 1.8% of yres). + */ bool margins; + + /** + * @force: + * + * Ignore the hotplug state of the connector, and force its + * state to one of the DRM_FORCE_* values. + */ enum drm_connector_force force; }; From patchwork Mon Jun 17 14:51:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999383 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E5A8B14DB for ; Mon, 17 Jun 2019 14:52:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D6AC928872 for ; Mon, 17 Jun 2019 14:52:11 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CAFF228754; Mon, 17 Jun 2019 14:52:11 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 7664C2880C for ; Mon, 17 Jun 2019 14:52:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5809C892FA; Mon, 17 Jun 2019 14:52:10 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id C5230892FA for ; Mon, 17 Jun 2019 14:52:08 +0000 (UTC) X-Originating-IP: 90.88.23.150 Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id CFC634000B; Mon, 17 Jun 2019 14:51:57 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 02/12] drm/client: Restrict the plane_state scope Date: Mon, 17 Jun 2019 16:51:29 +0200 Message-Id: <8bd9696ea915a4ad08be6d93a4d9565e8d6aa2f3.1560783090.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The drm_client_modeset_commit_atomic function uses two times the plane_state variable in inner blocks of code, but the variable has a scope global to this function. This will lead to inadvertent devs to reuse the variable in the second block with the value left by the first, without any warning from the compiler since value would have been initialized. Fix this by moving the variable declaration to the proper scope. Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_client_modeset.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 006bf7390e7d..8264c3a732b0 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -861,7 +861,6 @@ EXPORT_SYMBOL(drm_client_panel_rotation); static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool active) { struct drm_device *dev = client->dev; - struct drm_plane_state *plane_state; struct drm_plane *plane; struct drm_atomic_state *state; struct drm_modeset_acquire_ctx ctx; @@ -879,6 +878,8 @@ static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool state->acquire_ctx = &ctx; retry: drm_for_each_plane(plane, dev) { + struct drm_plane_state *plane_state; + plane_state = drm_atomic_get_plane_state(state, plane); if (IS_ERR(plane_state)) { ret = PTR_ERR(plane_state); @@ -901,6 +902,8 @@ static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool unsigned int rotation; if (drm_client_panel_rotation(mode_set, &rotation)) { + struct drm_plane_state *plane_state; + /* Cannot fail as we've already gotten the plane state above */ plane_state = drm_atomic_get_new_plane_state(state, primary); plane_state->rotation = rotation; From patchwork Mon Jun 17 14:51:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999385 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8978F6C5 for ; Mon, 17 Jun 2019 14:52:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7AD74283A8 for ; Mon, 17 Jun 2019 14:52:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6EE2E28870; Mon, 17 Jun 2019 14:52:15 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 2044028814 for ; Mon, 17 Jun 2019 14:52:15 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 8072489301; Mon, 17 Jun 2019 14:52:14 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id DACA089301 for ; Mon, 17 Jun 2019 14:52:10 +0000 (UTC) X-Originating-IP: 90.88.23.150 Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id B574040022; Mon, 17 Jun 2019 14:52:07 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 03/12] drm/client: Restrict the rotation check to the rotation itself Date: Mon, 17 Jun 2019 16:51:30 +0200 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The drm_client_rotation has a check on the rotation value, but the reflections are also stored in the same variable, and the check doesn't take this into account. Therefore, even though we might have a valid rotation, if we're also using a reflection parameter, the test will fail for no particular reason. Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_client_modeset.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 8264c3a732b0..b4e5fb0a17cf 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -845,7 +845,8 @@ bool drm_client_panel_rotation(struct drm_mode_set *modeset, unsigned int *rotat * depending on the hardware this may require the framebuffer * to be in a specific tiling format. */ - if (*rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property) + if ((*rotation & DRM_MODE_ROTATE_MASK) != DRM_MODE_ROTATE_180 || + !plane->rotation_property) return false; for (i = 0; i < plane->rotation_property->num_values; i++) From patchwork Mon Jun 17 14:51:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999389 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 907FA14DB for ; Mon, 17 Jun 2019 14:52:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7C6142881A for ; Mon, 17 Jun 2019 14:52:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7A72B2882F; Mon, 17 Jun 2019 14:52:21 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 1EA3028892 for ; Mon, 17 Jun 2019 14:52:21 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id C9F1D8930F; Mon, 17 Jun 2019 14:52:18 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by gabe.freedesktop.org (Postfix) with ESMTPS id 0D80A89308 for ; Mon, 17 Jun 2019 14:52:16 +0000 (UTC) Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id EE357200017; Mon, 17 Jun 2019 14:52:09 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 04/12] drm/client: Change drm_client_panel_rotation name Date: Mon, 17 Jun 2019 16:51:31 +0200 Message-Id: <8cb0f0d9569d41685bbf30a1538da6578cd2769b.1560783090.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The drm_client_panel_rotation function has been used so far to set the default rotation based on the panel orientation. However, we can have more sources of information to make that decision, starting with the command line that we will introduce later in this series. Change the name to remove the panel mention. Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_client_modeset.c | 12 ++++++------ drivers/gpu/drm/drm_fb_helper.c | 2 +- include/drm/drm_client.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index b4e5fb0a17cf..4869a0170bec 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -804,19 +804,19 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, EXPORT_SYMBOL(drm_client_modeset_probe); /** - * drm_client_panel_rotation() - Check panel orientation + * drm_client_rotation() - Check the initial rotation value * @modeset: DRM modeset * @rotation: Returned rotation value * - * This function checks if the primary plane in @modeset can hw rotate to match - * the panel orientation on its connector. + * This function checks if the primary plane in @modeset can hw rotate + * to match the rotation needed on its connector. * * Note: Currently only 0 and 180 degrees are supported. * * Return: * True if the plane can do the rotation, false otherwise. */ -bool drm_client_panel_rotation(struct drm_mode_set *modeset, unsigned int *rotation) +bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation) { struct drm_connector *connector = modeset->connectors[0]; struct drm_plane *plane = modeset->crtc->primary; @@ -857,7 +857,7 @@ bool drm_client_panel_rotation(struct drm_mode_set *modeset, unsigned int *rotat return true; } -EXPORT_SYMBOL(drm_client_panel_rotation); +EXPORT_SYMBOL(drm_client_rotation); static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool active) { @@ -902,7 +902,7 @@ static int drm_client_modeset_commit_atomic(struct drm_client_dev *client, bool struct drm_plane *primary = mode_set->crtc->primary; unsigned int rotation; - if (drm_client_panel_rotation(mode_set, &rotation)) { + if (drm_client_rotation(mode_set, &rotation)) { struct drm_plane_state *plane_state; /* Cannot fail as we've already gotten the plane state above */ diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 42852cae749b..1984e5c54d58 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1722,7 +1722,7 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) modeset->fb = fb_helper->fb; - if (drm_client_panel_rotation(modeset, &rotation)) + if (drm_client_rotation(modeset, &rotation)) /* Rotating in hardware, fbcon should not rotate */ sw_rotations |= DRM_MODE_ROTATE_0; else diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h index f2d5ed745733..72d51d1e9dd9 100644 --- a/include/drm/drm_client.h +++ b/include/drm/drm_client.h @@ -153,7 +153,7 @@ void drm_client_framebuffer_delete(struct drm_client_buffer *buffer); int drm_client_modeset_create(struct drm_client_dev *client); void drm_client_modeset_free(struct drm_client_dev *client); int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, unsigned int height); -bool drm_client_panel_rotation(struct drm_mode_set *modeset, unsigned int *rotation); +bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation); int drm_client_modeset_commit_force(struct drm_client_dev *client); int drm_client_modeset_commit(struct drm_client_dev *client); int drm_client_modeset_dpms(struct drm_client_dev *client, int mode); From patchwork Mon Jun 17 14:51:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999387 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 69F8414DB for ; Mon, 17 Jun 2019 14:52:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 59010286A8 for ; Mon, 17 Jun 2019 14:52:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D5882882F; Mon, 17 Jun 2019 14:52:20 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 9FFAD286A8 for ; Mon, 17 Jun 2019 14:52:19 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 702A489308; Mon, 17 Jun 2019 14:52:18 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by gabe.freedesktop.org (Postfix) with ESMTPS id 96A1D8930F for ; Mon, 17 Jun 2019 14:52:17 +0000 (UTC) X-Originating-IP: 90.88.23.150 Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay2-d.mail.gandi.net (Postfix) with ESMTPSA id 7856040005; Mon, 17 Jun 2019 14:52:14 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 05/12] drm/modes: Rewrite the command line parser Date: Mon, 17 Jun 2019 16:51:32 +0200 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , Maxime Ripard , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Maxime Ripard Rewrite the command line parser in order to get away from the state machine parsing the video mode lines. Hopefully, this will allow to extend it more easily to support named modes and / or properties set directly on the command line. Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_modes.c | 325 +++++++++++++++++++++++-------------- 1 file changed, 210 insertions(+), 115 deletions(-) diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 5a07a28fec6d..6debbd6c1763 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -30,6 +30,7 @@ * authorization from the copyright holder(s) and author(s). */ +#include #include #include #include @@ -1408,6 +1409,151 @@ void drm_connector_list_update(struct drm_connector *connector) } EXPORT_SYMBOL(drm_connector_list_update); +static int drm_mode_parse_cmdline_bpp(const char *str, char **end_ptr, + struct drm_cmdline_mode *mode) +{ + unsigned int bpp; + + if (str[0] != '-') + return -EINVAL; + + str++; + bpp = simple_strtol(str, end_ptr, 10); + if (*end_ptr == str) + return -EINVAL; + + mode->bpp = bpp; + mode->bpp_specified = true; + + return 0; +} + +static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr, + struct drm_cmdline_mode *mode) +{ + unsigned int refresh; + + if (str[0] != '@') + return -EINVAL; + + str++; + refresh = simple_strtol(str, end_ptr, 10); + if (*end_ptr == str) + return -EINVAL; + + mode->refresh = refresh; + mode->refresh_specified = true; + + return 0; +} + +static int drm_mode_parse_cmdline_extra(const char *str, int length, + struct drm_connector *connector, + struct drm_cmdline_mode *mode) +{ + int i; + + for (i = 0; i < length; i++) { + switch (str[i]) { + case 'i': + mode->interlace = true; + break; + case 'm': + mode->margins = true; + break; + case 'D': + if (mode->force != DRM_FORCE_UNSPECIFIED) + return -EINVAL; + + if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && + (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) + mode->force = DRM_FORCE_ON; + else + mode->force = DRM_FORCE_ON_DIGITAL; + break; + case 'd': + if (mode->force != DRM_FORCE_UNSPECIFIED) + return -EINVAL; + + mode->force = DRM_FORCE_OFF; + break; + case 'e': + if (mode->force != DRM_FORCE_UNSPECIFIED) + return -EINVAL; + + mode->force = DRM_FORCE_ON; + break; + default: + return -EINVAL; + } + } + + return 0; +} + +static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length, + bool extras, + struct drm_connector *connector, + struct drm_cmdline_mode *mode) +{ + const char *str_start = str; + bool rb = false, cvt = false; + int xres = 0, yres = 0; + int remaining, i; + char *end_ptr; + + xres = simple_strtol(str, &end_ptr, 10); + if (end_ptr == str) + return -EINVAL; + + if (end_ptr[0] != 'x') + return -EINVAL; + end_ptr++; + + str = end_ptr; + yres = simple_strtol(str, &end_ptr, 10); + if (end_ptr == str) + return -EINVAL; + + remaining = length - (end_ptr - str_start); + if (remaining < 0) + return -EINVAL; + + for (i = 0; i < remaining; i++) { + switch (end_ptr[i]) { + case 'M': + cvt = true; + break; + case 'R': + rb = true; + break; + default: + /* + * Try to pass that to our extras parsing + * function to handle the case where the + * extras are directly after the resolution + */ + if (extras) { + int ret = drm_mode_parse_cmdline_extra(end_ptr + i, + 1, + connector, + mode); + if (ret) + return ret; + } else { + return -EINVAL; + } + } + } + + mode->xres = xres; + mode->yres = yres; + mode->cvt = cvt; + mode->rb = rb; + + return 0; +} + /** * drm_mode_parse_command_line_for_connector - parse command line modeline for connector * @mode_option: optional per connector mode option @@ -1434,13 +1580,12 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, struct drm_cmdline_mode *mode) { const char *name; - unsigned int namelen; - bool res_specified = false, bpp_specified = false, refresh_specified = false; - unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; - bool yres_specified = false, cvt = false, rb = false; - bool interlace = false, margins = false, was_digit = false; - int i; - enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; + bool parse_extras = false; + unsigned int bpp_off = 0, refresh_off = 0; + unsigned int mode_end = 0; + char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL; + char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL; + int ret; #ifdef CONFIG_FB if (!mode_option) @@ -1453,127 +1598,77 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, } name = mode_option; - namelen = strlen(name); - for (i = namelen-1; i >= 0; i--) { - switch (name[i]) { - case '@': - if (!refresh_specified && !bpp_specified && - !yres_specified && !cvt && !rb && was_digit) { - refresh = simple_strtol(&name[i+1], NULL, 10); - refresh_specified = true; - was_digit = false; - } else - goto done; - break; - case '-': - if (!bpp_specified && !yres_specified && !cvt && - !rb && was_digit) { - bpp = simple_strtol(&name[i+1], NULL, 10); - bpp_specified = true; - was_digit = false; - } else - goto done; - break; - case 'x': - if (!yres_specified && was_digit) { - yres = simple_strtol(&name[i+1], NULL, 10); - yres_specified = true; - was_digit = false; - } else - goto done; - break; - case '0' ... '9': - was_digit = true; - break; - case 'M': - if (yres_specified || cvt || was_digit) - goto done; - cvt = true; - break; - case 'R': - if (yres_specified || cvt || rb || was_digit) - goto done; - rb = true; - break; - case 'm': - if (cvt || yres_specified || was_digit) - goto done; - margins = true; - break; - case 'i': - if (cvt || yres_specified || was_digit) - goto done; - interlace = true; - break; - case 'e': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; - force = DRM_FORCE_ON; - break; - case 'D': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; + if (!isdigit(name[0])) + return false; - if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) && - (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) - force = DRM_FORCE_ON; - else - force = DRM_FORCE_ON_DIGITAL; - break; - case 'd': - if (yres_specified || bpp_specified || refresh_specified || - was_digit || (force != DRM_FORCE_UNSPECIFIED)) - goto done; + /* Try to locate the bpp and refresh specifiers, if any */ + bpp_ptr = strchr(name, '-'); + if (bpp_ptr) { + bpp_off = bpp_ptr - name; + mode->bpp_specified = true; + } - force = DRM_FORCE_OFF; - break; - default: - goto done; - } + refresh_ptr = strchr(name, '@'); + if (refresh_ptr) { + refresh_off = refresh_ptr - name; + mode->refresh_specified = true; } - if (i < 0 && yres_specified) { - char *ch; - xres = simple_strtol(name, &ch, 10); - if ((ch != NULL) && (*ch == 'x')) - res_specified = true; - else - i = ch - name; - } else if (!yres_specified && was_digit) { - /* catch mode that begins with digits but has no 'x' */ - i = 0; + /* Locate the end of the name / resolution, and parse it */ + if (bpp_ptr && refresh_ptr) { + mode_end = min(bpp_off, refresh_off); + } else if (bpp_ptr) { + mode_end = bpp_off; + } else if (refresh_ptr) { + mode_end = refresh_off; + } else { + mode_end = strlen(name); + parse_extras = true; } -done: - if (i >= 0) { - pr_warn("[drm] parse error at position %i in video mode '%s'\n", - i, name); - mode->specified = false; + + ret = drm_mode_parse_cmdline_res_mode(name, mode_end, + parse_extras, + connector, + mode); + if (ret) return false; - } + mode->specified = true; - if (res_specified) { - mode->specified = true; - mode->xres = xres; - mode->yres = yres; + if (bpp_ptr) { + ret = drm_mode_parse_cmdline_bpp(bpp_ptr, &bpp_end_ptr, mode); + if (ret) + return false; } - if (refresh_specified) { - mode->refresh_specified = true; - mode->refresh = refresh; + if (refresh_ptr) { + ret = drm_mode_parse_cmdline_refresh(refresh_ptr, + &refresh_end_ptr, mode); + if (ret) + return false; } - if (bpp_specified) { - mode->bpp_specified = true; - mode->bpp = bpp; + /* + * Locate the end of the bpp / refresh, and parse the extras + * if relevant + */ + if (bpp_ptr && refresh_ptr) + extra_ptr = max(bpp_end_ptr, refresh_end_ptr); + else if (bpp_ptr) + extra_ptr = bpp_end_ptr; + else if (refresh_ptr) + extra_ptr = refresh_end_ptr; + + if (extra_ptr) { + int remaining = strlen(name) - (extra_ptr - name); + + /* + * We still have characters to process, while + * we shouldn't have any + */ + if (remaining > 0) + return false; } - mode->rb = rb; - mode->cvt = cvt; - mode->interlace = interlace; - mode->margins = margins; - mode->force = force; return true; } From patchwork Mon Jun 17 14:51:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999393 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F05806C5 for ; Mon, 17 Jun 2019 14:52:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E139C2675C for ; Mon, 17 Jun 2019 14:52:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D56F3288B3; Mon, 17 Jun 2019 14:52:25 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 577B528892 for ; Mon, 17 Jun 2019 14:52:25 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5BEB489310; Mon, 17 Jun 2019 14:52:24 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2794689310 for ; Mon, 17 Jun 2019 14:52:19 +0000 (UTC) Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 9D57420001A; Mon, 17 Jun 2019 14:52:16 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 06/12] drm/modes: Support modes names on the command line Date: Mon, 17 Jun 2019 16:51:33 +0200 Message-Id: <18443e0c3bdbbd16cea4ec63bc7f2079b820b43b.1560783090.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , Maxime Ripard , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Maxime Ripard The drm subsystem also uses the video= kernel parameter, and in the documentation refers to the fbdev documentation for that parameter. However, that documentation also says that instead of giving the mode using its resolution we can also give a name. However, DRM doesn't handle that case at the moment. Even though in most case it shouldn't make any difference, it might be useful for analog modes, where different standards might have the same resolution, but still have a few different parameters that are not encoded in the modes (NTSC vs NTSC-J vs PAL-M for example). Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_client_modeset.c | 4 ++- drivers/gpu/drm/drm_connector.c | 3 +- drivers/gpu/drm/drm_modes.c | 62 +++++++++++++++++++++-------- include/drm/drm_connector.h | 7 +++- 4 files changed, 59 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 4869a0170bec..33d4988f22ae 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -149,6 +149,10 @@ drm_connector_pick_cmdline_mode(struct drm_connector *connector) prefer_non_interlace = !cmdline_mode->interlace; again: list_for_each_entry(mode, &connector->modes, head) { + /* Check (optional) mode name first */ + if (!strcmp(mode->name, cmdline_mode->name)) + return mode; + /* check width/height */ if (mode->hdisplay != cmdline_mode->xres || mode->vdisplay != cmdline_mode->yres) diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 3ccdcf3dfcde..3afed5677946 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -139,8 +139,9 @@ static void drm_connector_get_cmdline_mode(struct drm_connector *connector) connector->force = mode->force; } - DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", + DRM_DEBUG_KMS("cmdline mode for connector %s %s %dx%d@%dHz%s%s%s\n", connector->name, + mode->name ? mode->name : "", mode->xres, mode->yres, mode->refresh_specified ? mode->refresh : 60, mode->rb ? " reduced blanking" : "", diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 6debbd6c1763..429d3be17800 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -1580,7 +1580,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, struct drm_cmdline_mode *mode) { const char *name; - bool parse_extras = false; + bool named_mode = false, parse_extras = false; unsigned int bpp_off = 0, refresh_off = 0; unsigned int mode_end = 0; char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL; @@ -1599,8 +1599,22 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, name = mode_option; - if (!isdigit(name[0])) - return false; + /* + * This is a bit convoluted. To differentiate between the + * named modes and poorly formatted resolutions, we need a + * bunch of things: + * - We need to make sure that the first character (which + * would be our resolution in X) is a digit. + * - However, if the X resolution is missing, then we end up + * with something like x, with our first character + * being an alpha-numerical character, which would be + * considered a named mode. + * + * If this isn't enough, we should add more heuristics here, + * and matching unit-tests. + */ + if (!isdigit(name[0]) && name[0] != 'x') + named_mode = true; /* Try to locate the bpp and refresh specifiers, if any */ bpp_ptr = strchr(name, '-'); @@ -1611,6 +1625,9 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, refresh_ptr = strchr(name, '@'); if (refresh_ptr) { + if (named_mode) + return false; + refresh_off = refresh_ptr - name; mode->refresh_specified = true; } @@ -1627,12 +1644,16 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, parse_extras = true; } - ret = drm_mode_parse_cmdline_res_mode(name, mode_end, - parse_extras, - connector, - mode); - if (ret) - return false; + if (named_mode) { + strncpy(mode->name, name, mode_end); + } else { + ret = drm_mode_parse_cmdline_res_mode(name, mode_end, + parse_extras, + connector, + mode); + if (ret) + return false; + } mode->specified = true; if (bpp_ptr) { @@ -1660,14 +1681,23 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, extra_ptr = refresh_end_ptr; if (extra_ptr) { - int remaining = strlen(name) - (extra_ptr - name); + if (!named_mode) { + int len = strlen(name) - (extra_ptr - name); - /* - * We still have characters to process, while - * we shouldn't have any - */ - if (remaining > 0) - return false; + ret = drm_mode_parse_cmdline_extra(extra_ptr, len, + connector, mode); + if (ret) + return false; + } else { + int remaining = strlen(name) - (extra_ptr - name); + + /* + * We still have characters to process, while + * we shouldn't have any + */ + if (remaining > 0) + return false; + } } return true; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index c802780b0bfc..cdf2fb910010 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -933,6 +933,13 @@ struct drm_connector_funcs { */ struct drm_cmdline_mode { /** + * @name: + * + * Name of the mode. + */ + char name[DRM_DISPLAY_MODE_LEN]; + + /** * @specified: * * Has a mode been read from the command-line? From patchwork Mon Jun 17 14:51:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999395 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C8EC91902 for ; Mon, 17 Jun 2019 14:52:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B94A226538 for ; Mon, 17 Jun 2019 14:52:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ACF2E28892; Mon, 17 Jun 2019 14:52:29 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 38B8F26538 for ; Mon, 17 Jun 2019 14:52:28 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2C86F89319; Mon, 17 Jun 2019 14:52:27 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by gabe.freedesktop.org (Postfix) with ESMTPS id 311388931E for ; Mon, 17 Jun 2019 14:52:24 +0000 (UTC) Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 26DDF24000B; Mon, 17 Jun 2019 14:52:18 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 07/12] drm/modes: Allow to specify rotation and reflection on the commandline Date: Mon, 17 Jun 2019 16:51:34 +0200 Message-Id: <777da16e42db757c1f5b414b5ca34507097fed5c.1560783090.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Rotations and reflections setup are needed in some scenarios to initialise properly the initial framebuffer. Some drivers already had a bunch of quirks to deal with this, such as either a private kernel command line parameter (omapdss) or on the device tree (various panels). In order to accomodate this, let's create a video mode parameter to deal with the rotation and reflexion. Signed-off-by: Maxime Ripard Reviewed-by: Noralf Trønnes --- Documentation/fb/modedb.rst | 11 +++- drivers/gpu/drm/drm_client_modeset.c | 30 +++++++- drivers/gpu/drm/drm_modes.c | 114 +++++++++++++++++++++++----- include/drm/drm_connector.h | 10 ++- 4 files changed, 145 insertions(+), 20 deletions(-) diff --git a/Documentation/fb/modedb.rst b/Documentation/fb/modedb.rst index 3c2397293977..3e8a6f79dcd7 100644 --- a/Documentation/fb/modedb.rst +++ b/Documentation/fb/modedb.rst @@ -53,6 +53,17 @@ Specifying the option multiple times for different ports is possible, e.g.:: video=LVDS-1:d video=HDMI-1:D +Options can also be passed after the mode, using commas as separator. + + Sample usage: 720x480,rotate=180 - 720x480 mode, rotated by 180 degrees + +Valid options are: + + - reflect_x (boolean): Perform an axial symetry on the X axis + - reflect_y (boolean): Perform an axial symetry on the Y axis + - rotate (integer): Rotate the initial framebuffer by x + degrees. Valid values are 0, 90, 180 and 270. + ----------------------------------------------------------------------------- What is the VESA(TM) Coordinated Video Timings (CVT)? diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index 33d4988f22ae..e95fceac8f8b 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -824,6 +824,7 @@ bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation) { struct drm_connector *connector = modeset->connectors[0]; struct drm_plane *plane = modeset->crtc->primary; + struct drm_cmdline_mode *cmdline; u64 valid_mask = 0; unsigned int i; @@ -844,6 +845,35 @@ bool drm_client_rotation(struct drm_mode_set *modeset, unsigned int *rotation) *rotation = DRM_MODE_ROTATE_0; } + /** + * The panel already defined the default rotation + * through its orientation. Whatever has been provided + * on the command line needs to be added to that. + * + * Unfortunately, the rotations are at different bit + * indices, so the math to add them up are not as + * trivial as they could. + * + * Reflections on the other hand are pretty trivial to deal with, a + * simple XOR between the two handle the addition nicely. + */ + cmdline = &connector->cmdline_mode; + if (cmdline->specified) { + unsigned int cmdline_rest, panel_rest; + unsigned int cmdline_rot, panel_rot; + unsigned int sum_rot, sum_rest; + + panel_rot = ilog2(*rotation & DRM_MODE_ROTATE_MASK); + cmdline_rot = ilog2(cmdline->rotation_reflection & DRM_MODE_ROTATE_MASK); + sum_rot = (panel_rot + cmdline_rot) % 4; + + panel_rest = *rotation & ~DRM_MODE_ROTATE_MASK; + cmdline_rest = cmdline->rotation_reflection & ~DRM_MODE_ROTATE_MASK; + sum_rest = panel_rest ^ cmdline_rest; + + *rotation = (1 << sum_rot) | sum_rest; + } + /* * TODO: support 90 / 270 degree hardware rotation, * depending on the hardware this may require the framebuffer diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 429d3be17800..dc6d11292685 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -1554,6 +1554,71 @@ static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length, return 0; } +static int drm_mode_parse_cmdline_options(char *str, size_t len, + struct drm_connector *connector, + struct drm_cmdline_mode *mode) +{ + unsigned int rotation = 0; + char *sep = str; + + while ((sep = strchr(sep, ','))) { + char *delim, *option; + + option = sep + 1; + delim = strchr(option, '='); + if (!delim) { + delim = strchr(option, ','); + + if (!delim) + delim = str + len; + } + + if (!strncmp(option, "rotate", delim - option)) { + const char *value = delim + 1; + unsigned int deg; + + deg = simple_strtol(value, &sep, 10); + + /* Make sure we have parsed something */ + if (sep == value) + return -EINVAL; + + switch (deg) { + case 0: + rotation |= DRM_MODE_ROTATE_0; + break; + + case 90: + rotation |= DRM_MODE_ROTATE_90; + break; + + case 180: + rotation |= DRM_MODE_ROTATE_180; + break; + + case 270: + rotation |= DRM_MODE_ROTATE_270; + break; + + default: + return -EINVAL; + } + } else if (!strncmp(option, "reflect_x", delim - option)) { + rotation |= DRM_MODE_REFLECT_X; + sep = delim; + } else if (!strncmp(option, "reflect_y", delim - option)) { + rotation |= DRM_MODE_REFLECT_Y; + sep = delim; + } else { + return -EINVAL; + } + } + + mode->rotation_reflection = rotation; + + return 0; +} + /** * drm_mode_parse_command_line_for_connector - parse command line modeline for connector * @mode_option: optional per connector mode option @@ -1569,6 +1634,10 @@ static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length, * * x[M][R][-][@][i][m][eDd] * + * Additionals options can be provided following the mode, using a comma to + * separate each option. Valid options can be found in + * Documentation/fb/modedb.txt. + * * The intermediate drm_cmdline_mode structure is required to store additional * options from the command line modline like the force-enable/disable flag. * @@ -1581,9 +1650,10 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, { const char *name; bool named_mode = false, parse_extras = false; - unsigned int bpp_off = 0, refresh_off = 0; + unsigned int bpp_off = 0, refresh_off = 0, options_off = 0; unsigned int mode_end = 0; char *bpp_ptr = NULL, *refresh_ptr = NULL, *extra_ptr = NULL; + char *options_ptr = NULL; char *bpp_end_ptr = NULL, *refresh_end_ptr = NULL; int ret; @@ -1632,13 +1702,18 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, mode->refresh_specified = true; } + /* Locate the start of named options */ + options_ptr = strchr(name, ','); + if (options_ptr) + options_off = options_ptr - name; + /* Locate the end of the name / resolution, and parse it */ - if (bpp_ptr && refresh_ptr) { - mode_end = min(bpp_off, refresh_off); - } else if (bpp_ptr) { + if (bpp_ptr) { mode_end = bpp_off; } else if (refresh_ptr) { mode_end = refresh_off; + } else if (options_ptr) { + mode_end = options_off; } else { mode_end = strlen(name); parse_extras = true; @@ -1680,24 +1755,23 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, else if (refresh_ptr) extra_ptr = refresh_end_ptr; - if (extra_ptr) { - if (!named_mode) { - int len = strlen(name) - (extra_ptr - name); + if (extra_ptr && + extra_ptr != options_ptr) { + int len = strlen(name) - (extra_ptr - name); - ret = drm_mode_parse_cmdline_extra(extra_ptr, len, - connector, mode); - if (ret) - return false; - } else { - int remaining = strlen(name) - (extra_ptr - name); + ret = drm_mode_parse_cmdline_extra(extra_ptr, len, + connector, mode); + if (ret) + return false; + } - /* - * We still have characters to process, while - * we shouldn't have any - */ - if (remaining > 0) - return false; - } + if (options_ptr) { + int len = strlen(name) - (options_ptr - name); + + ret = drm_mode_parse_cmdline_options(options_ptr, len, + connector, mode); + if (ret) + return false; } return true; diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index cdf2fb910010..8eebe0432c73 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1025,6 +1025,16 @@ struct drm_cmdline_mode { * state to one of the DRM_FORCE_* values. */ enum drm_connector_force force; + + /** + * @rotation_reflection: + * + * Initial rotation and reflection of the mode setup from the + * command line. See DRM_MODE_ROTATE_* and + * DRM_MODE_REFLECT_*. The only rotations supported are + * DRM_MODE_ROTATE_0 and DRM_MODE_ROTATE_180. + */ + unsigned int rotation_reflection; }; /** From patchwork Mon Jun 17 14:51:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999399 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A85F414B6 for ; Mon, 17 Jun 2019 14:52:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9A741288B3 for ; Mon, 17 Jun 2019 14:52:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 842F7288B4; Mon, 17 Jun 2019 14:52: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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 40119288B3 for ; Mon, 17 Jun 2019 14:52:30 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id D6E0E8931F; Mon, 17 Jun 2019 14:52:27 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay12.mail.gandi.net (relay12.mail.gandi.net [217.70.178.232]) by gabe.freedesktop.org (Postfix) with ESMTPS id AC6CC8931F for ; Mon, 17 Jun 2019 14:52:25 +0000 (UTC) Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id A7983200012; Mon, 17 Jun 2019 14:52:22 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 08/12] drm/connector: Introduce a TV margins structure Date: Mon, 17 Jun 2019 16:51:35 +0200 Message-Id: <38b773b03f15ec7a135cdf8f7db669e5ada20cf2.1560783090.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The TV margins has been defined as a structure inside the drm_connector_state structure so far. However, we will need it in other structures as well, so let's move that structure definition so that it can be reused. Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- include/drm/drm_connector.h | 41 +++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index 8eebe0432c73..b22e3150e33d 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -464,13 +464,37 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info, unsigned int num_formats); /** + * struct drm_connector_tv_margins - TV connector related margins + * + * Describes the margins in pixels to put around the image on TV + * connectors to deal with overscan. + */ +struct drm_connector_tv_margins { + /** + * @bottom: Bottom margin in pixels. + */ + unsigned int bottom; + + /** + * @left: Left margin in pixels. + */ + unsigned int left; + + /** + * @right: Right margin in pixels. + */ + unsigned int right; + + /** + * @top: Top margin in pixels. + */ + unsigned int top; +}; + +/** * struct drm_tv_connector_state - TV connector related states * @subconnector: selected subconnector - * @margins: margins (all margins are expressed in pixels) - * @margins.left: left margin - * @margins.right: right margin - * @margins.top: top margin - * @margins.bottom: bottom margin + * @margins: TV margins * @mode: TV mode * @brightness: brightness in percent * @contrast: contrast in percent @@ -481,12 +505,7 @@ int drm_display_info_set_bus_formats(struct drm_display_info *info, */ struct drm_tv_connector_state { enum drm_mode_subconnector subconnector; - struct { - unsigned int left; - unsigned int right; - unsigned int top; - unsigned int bottom; - } margins; + struct drm_connector_tv_margins margins; unsigned int mode; unsigned int brightness; unsigned int contrast; From patchwork Mon Jun 17 14:51:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999401 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A961614B6 for ; Mon, 17 Jun 2019 14:52:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 99F162892E for ; Mon, 17 Jun 2019 14:52:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 946D728872; Mon, 17 Jun 2019 14:52:34 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 196CC28870 for ; Mon, 17 Jun 2019 14:52:34 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 2C262892E2; Mon, 17 Jun 2019 14:52:33 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay10.mail.gandi.net (relay10.mail.gandi.net [217.70.178.230]) by gabe.freedesktop.org (Postfix) with ESMTPS id DE51089322 for ; Mon, 17 Jun 2019 14:52:27 +0000 (UTC) Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay10.mail.gandi.net (Postfix) with ESMTPSA id B693E240010; Mon, 17 Jun 2019 14:52:24 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 09/12] drm/modes: Parse overscan properties Date: Mon, 17 Jun 2019 16:51:36 +0200 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Properly configuring the overscan properties might be needed for the initial setup of the framebuffer for display that still have overscan. Let's allow for more properties on the kernel command line to setup each margin. Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- Documentation/fb/modedb.rst | 2 ++- drivers/gpu/drm/drm_modes.c | 44 ++++++++++++++++++++++++++++++++++++++- include/drm/drm_connector.h | 5 ++++- 3 files changed, 51 insertions(+) diff --git a/Documentation/fb/modedb.rst b/Documentation/fb/modedb.rst index 3e8a6f79dcd7..444bc329e5a8 100644 --- a/Documentation/fb/modedb.rst +++ b/Documentation/fb/modedb.rst @@ -59,6 +59,8 @@ Options can also be passed after the mode, using commas as separator. Valid options are: + - margin_top, margin_bottom, margin_left, margin_right (integer): + Number of pixels in the margins, typically to deal with overscan on TVs - reflect_x (boolean): Perform an axial symetry on the X axis - reflect_y (boolean): Perform an axial symetry on the Y axis - rotate (integer): Rotate the initial framebuffer by x diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index dc6d11292685..57e6408288c8 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -1609,6 +1609,50 @@ static int drm_mode_parse_cmdline_options(char *str, size_t len, } else if (!strncmp(option, "reflect_y", delim - option)) { rotation |= DRM_MODE_REFLECT_Y; sep = delim; + } else if (!strncmp(option, "margin_right", delim - option)) { + const char *value = delim + 1; + unsigned int margin; + + margin = simple_strtol(value, &sep, 10); + + /* Make sure we have parsed something */ + if (sep == value) + return -EINVAL; + + mode->tv_margins.right = margin; + } else if (!strncmp(option, "margin_left", delim - option)) { + const char *value = delim + 1; + unsigned int margin; + + margin = simple_strtol(value, &sep, 10); + + /* Make sure we have parsed something */ + if (sep == value) + return -EINVAL; + + mode->tv_margins.left = margin; + } else if (!strncmp(option, "margin_top", delim - option)) { + const char *value = delim + 1; + unsigned int margin; + + margin = simple_strtol(value, &sep, 10); + + /* Make sure we have parsed something */ + if (sep == value) + return -EINVAL; + + mode->tv_margins.top = margin; + } else if (!strncmp(option, "margin_bottom", delim - option)) { + const char *value = delim + 1; + unsigned int margin; + + margin = simple_strtol(value, &sep, 10); + + /* Make sure we have parsed something */ + if (sep == value) + return -EINVAL; + + mode->tv_margins.bottom = margin; } else { return -EINVAL; } diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h index b22e3150e33d..ca745d9feaf5 100644 --- a/include/drm/drm_connector.h +++ b/include/drm/drm_connector.h @@ -1054,6 +1054,11 @@ struct drm_cmdline_mode { * DRM_MODE_ROTATE_0 and DRM_MODE_ROTATE_180. */ unsigned int rotation_reflection; + + /** + * @tv_margins: TV margins to apply to the mode. + */ + struct drm_connector_tv_margins tv_margins; }; /** From patchwork Mon Jun 17 14:51:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999375 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 27E5C14DB for ; Mon, 17 Jun 2019 14:51:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 18E9E286BC for ; Mon, 17 Jun 2019 14:51:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0CCF528870; Mon, 17 Jun 2019 14:51:58 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 98870286BC for ; Mon, 17 Jun 2019 14:51:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 9DBA3892EE; Mon, 17 Jun 2019 14:51:56 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id 591C9892EA for ; Mon, 17 Jun 2019 14:51:55 +0000 (UTC) X-Originating-IP: 90.88.23.150 Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id DF809E0017; Mon, 17 Jun 2019 14:51:47 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 10/12] drm/atomic: Add a function to reset connector TV properties Date: Mon, 17 Jun 2019 16:51:37 +0200 Message-Id: <84a7b657f09303a2850e1cc79e68f623547f3fdd.1560783090.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP During the connector reset, if that connector has a TV property, it needs to be reset to the value provided on the command line. Provide a helper to do that. Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- drivers/gpu/drm/drm_atomic_state_helper.c | 18 ++++++++++++++++++ include/drm/drm_atomic_state_helper.h | 1 + 2 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 7d7347a6f194..46dc264a248b 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -380,6 +380,24 @@ void drm_atomic_helper_connector_reset(struct drm_connector *connector) EXPORT_SYMBOL(drm_atomic_helper_connector_reset); /** + * drm_atomic_helper_connector_tv_reset - Resets TV connector properties + * @connector: DRM connector + * + * Resets the TV-related properties attached to a connector. + */ +void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector) +{ + struct drm_cmdline_mode *cmdline = &connector->cmdline_mode; + struct drm_connector_state *state = connector->state; + + state->tv.margins.left = cmdline->tv_margins.left; + state->tv.margins.right = cmdline->tv_margins.right; + state->tv.margins.top = cmdline->tv_margins.top; + state->tv.margins.bottom = cmdline->tv_margins.bottom; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset); + +/** * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state * @connector: connector object * @state: atomic connector state diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h index 4e6d2e7a40b8..e4577cc11689 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -62,6 +62,7 @@ void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, void __drm_atomic_helper_connector_reset(struct drm_connector *connector, struct drm_connector_state *conn_state); void drm_atomic_helper_connector_reset(struct drm_connector *connector); +void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector); void __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, struct drm_connector_state *state); From patchwork Mon Jun 17 14:51:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999379 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 49E5614DB for ; Mon, 17 Jun 2019 14:52:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 38DA628754 for ; Mon, 17 Jun 2019 14:52:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2AB91283A8; Mon, 17 Jun 2019 14:52:04 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 BDB7828872 for ; Mon, 17 Jun 2019 14:52:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 939BA892FB; Mon, 17 Jun 2019 14:52:00 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id 4CE0F892EA for ; Mon, 17 Jun 2019 14:51:56 +0000 (UTC) X-Originating-IP: 90.88.23.150 Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id 16AD7E0008; Mon, 17 Jun 2019 14:51:52 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 11/12] drm/selftests: Add command line parser selftests Date: Mon, 17 Jun 2019 16:51:38 +0200 Message-Id: <735348d3a475ce0bcc88b46e093ab149023bb202.1560783090.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP The command line parser is pretty tough to get right and very error prone, so let's add a selftest to try to catch any regression. Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard --- drivers/gpu/drm/selftests/Makefile | 2 +- drivers/gpu/drm/selftests/drm_cmdline_selftests.h | 55 +- drivers/gpu/drm/selftests/test-drm_cmdline_parser.c | 918 +++++++++++++- 3 files changed, 974 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/selftests/drm_cmdline_selftests.h create mode 100644 drivers/gpu/drm/selftests/test-drm_cmdline_parser.c diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 8ec64ecf0e36..aae88f8a016c 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -3,4 +3,4 @@ test-drm_modeset-y := test-drm_modeset_common.o test-drm_plane_helper.o \ test-drm_format.o test-drm_framebuffer.o \ test-drm_damage_helper.o -obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o +obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o test-drm_cmdline_parser.o diff --git a/drivers/gpu/drm/selftests/drm_cmdline_selftests.h b/drivers/gpu/drm/selftests/drm_cmdline_selftests.h new file mode 100644 index 000000000000..b45824ec7c8f --- /dev/null +++ b/drivers/gpu/drm/selftests/drm_cmdline_selftests.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* List each unit test as selftest(function) + * + * The name is used as both an enum and expanded as igt__name to create + * a module parameter. It must be unique and legal for a C identifier. + * + * Tests are executed in order by igt/drm_mm + */ + +#define cmdline_test(test) selftest(test, test) + +cmdline_test(drm_cmdline_test_res) +cmdline_test(drm_cmdline_test_res_missing_x) +cmdline_test(drm_cmdline_test_res_missing_y) +cmdline_test(drm_cmdline_test_res_bad_y) +cmdline_test(drm_cmdline_test_res_missing_y_bpp) +cmdline_test(drm_cmdline_test_res_vesa) +cmdline_test(drm_cmdline_test_res_vesa_rblank) +cmdline_test(drm_cmdline_test_res_rblank) +cmdline_test(drm_cmdline_test_res_bpp) +cmdline_test(drm_cmdline_test_res_bad_bpp) +cmdline_test(drm_cmdline_test_res_refresh) +cmdline_test(drm_cmdline_test_res_bad_refresh) +cmdline_test(drm_cmdline_test_res_bpp_refresh) +cmdline_test(drm_cmdline_test_res_bpp_refresh_interlaced) +cmdline_test(drm_cmdline_test_res_bpp_refresh_margins) +cmdline_test(drm_cmdline_test_res_bpp_refresh_force_off) +cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on_off) +cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on) +cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on_analog) +cmdline_test(drm_cmdline_test_res_bpp_refresh_force_on_digital) +cmdline_test(drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on) +cmdline_test(drm_cmdline_test_res_margins_force_on) +cmdline_test(drm_cmdline_test_res_vesa_margins) +cmdline_test(drm_cmdline_test_res_invalid_mode) +cmdline_test(drm_cmdline_test_res_bpp_wrong_place_mode) +cmdline_test(drm_cmdline_test_name) +cmdline_test(drm_cmdline_test_name_bpp) +cmdline_test(drm_cmdline_test_name_refresh) +cmdline_test(drm_cmdline_test_name_bpp_refresh) +cmdline_test(drm_cmdline_test_name_refresh_wrong_mode) +cmdline_test(drm_cmdline_test_name_refresh_invalid_mode) +cmdline_test(drm_cmdline_test_name_option) +cmdline_test(drm_cmdline_test_name_bpp_option) +cmdline_test(drm_cmdline_test_rotate_0) +cmdline_test(drm_cmdline_test_rotate_90) +cmdline_test(drm_cmdline_test_rotate_180) +cmdline_test(drm_cmdline_test_rotate_270) +cmdline_test(drm_cmdline_test_rotate_invalid_val) +cmdline_test(drm_cmdline_test_rotate_truncated) +cmdline_test(drm_cmdline_test_hmirror) +cmdline_test(drm_cmdline_test_vmirror) +cmdline_test(drm_cmdline_test_margin_options) +cmdline_test(drm_cmdline_test_multiple_options) +cmdline_test(drm_cmdline_test_invalid_option) diff --git a/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c new file mode 100644 index 000000000000..bef4edde6f9f --- /dev/null +++ b/drivers/gpu/drm/selftests/test-drm_cmdline_parser.c @@ -0,0 +1,918 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019 Bootlin + */ + +#define pr_fmt(fmt) "drm_cmdline: " fmt + +#include +#include + +#include +#include + +#define TESTS "drm_cmdline_selftests.h" +#include "drm_selftest.h" +#include "test-drm_modeset_common.h" + +static int drm_cmdline_test_res(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_res_missing_x(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("x480", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_res_missing_y(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("1024x", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_res_bad_y(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("1024xtest", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_res_missing_y_bpp(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("1024x-24", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_res_vesa(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480M", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(!mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_res_vesa_rblank(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480MR", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(!mode.rb); + FAIL_ON(!mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_res_rblank(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480R", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(!mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_res_bpp(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_res_bad_bpp(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("720x480-test", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_res_refresh(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480@60", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(!mode.refresh_specified); + FAIL_ON(mode.refresh != 60); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_res_bad_refresh(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("720x480@refresh", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_res_bpp_refresh(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(!mode.refresh_specified); + FAIL_ON(mode.refresh != 60); + + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_res_bpp_refresh_interlaced(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60i", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(!mode.refresh_specified); + FAIL_ON(mode.refresh != 60); + + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(!mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_res_bpp_refresh_margins(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60m", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(!mode.refresh_specified); + FAIL_ON(mode.refresh != 60); + + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(!mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_res_bpp_refresh_force_off(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60d", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(!mode.refresh_specified); + FAIL_ON(mode.refresh != 60); + + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_OFF); + + return 0; +} + +static int drm_cmdline_test_res_bpp_refresh_force_on_off(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("720x480-24@60de", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_res_bpp_refresh_force_on(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60e", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(!mode.refresh_specified); + FAIL_ON(mode.refresh != 60); + + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_ON); + + return 0; +} + +static int drm_cmdline_test_res_bpp_refresh_force_on_analog(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60D", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(!mode.refresh_specified); + FAIL_ON(mode.refresh != 60); + + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_ON); + + return 0; +} + +static int drm_cmdline_test_res_bpp_refresh_force_on_digital(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + connector.connector_type = DRM_MODE_CONNECTOR_DVII; + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60D", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(!mode.refresh_specified); + FAIL_ON(mode.refresh != 60); + + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL); + + return 0; +} + +static int drm_cmdline_test_res_bpp_refresh_interlaced_margins_force_on(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480-24@60ime", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(!mode.refresh_specified); + FAIL_ON(mode.refresh != 60); + + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(!mode.interlace); + FAIL_ON(!mode.margins); + FAIL_ON(mode.force != DRM_FORCE_ON); + + return 0; +} + +static int drm_cmdline_test_res_margins_force_on(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480me", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(!mode.margins); + FAIL_ON(mode.force != DRM_FORCE_ON); + + return 0; +} + +static int drm_cmdline_test_res_vesa_margins(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480Mm", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(!mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(!mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_res_invalid_mode(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("720x480f", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_res_bpp_wrong_place_mode(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("720x480e-24", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_name(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC", + &connector, + &mode)); + FAIL_ON(strcmp(mode.name, "NTSC")); + FAIL_ON(mode.refresh_specified); + FAIL_ON(mode.bpp_specified); + + return 0; +} + +static int drm_cmdline_test_name_bpp(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC-24", + &connector, + &mode)); + FAIL_ON(strcmp(mode.name, "NTSC")); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + return 0; +} + +static int drm_cmdline_test_name_bpp_refresh(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC-24@60", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_name_refresh(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC@60", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_name_refresh_wrong_mode(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC@60m", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_name_refresh_invalid_mode(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("NTSC@60f", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_name_option(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC,rotate=180", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(strcmp(mode.name, "NTSC")); + FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180); + + return 0; +} + +static int drm_cmdline_test_name_bpp_option(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("NTSC-24,rotate=180", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(strcmp(mode.name, "NTSC")); + FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180); + FAIL_ON(!mode.bpp_specified); + FAIL_ON(mode.bpp != 24); + + return 0; +} + +static int drm_cmdline_test_rotate_0(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=0", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_0); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_rotate_90(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=90", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_90); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_rotate_180(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=180", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_180); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_rotate_270(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=270", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + FAIL_ON(mode.rotation_reflection != DRM_MODE_ROTATE_270); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_rotate_invalid_val(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=42", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_rotate_truncated(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,rotate=", + &connector, + &mode)); + + return 0; +} + +static int drm_cmdline_test_hmirror(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,reflect_x", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + FAIL_ON(mode.rotation_reflection != DRM_MODE_REFLECT_X); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_vmirror(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,reflect_y", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + FAIL_ON(mode.rotation_reflection != DRM_MODE_REFLECT_Y); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_margin_options(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,margin_right=14,margin_left=24,margin_bottom=36,margin_top=42", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + FAIL_ON(mode.tv_margins.right != 14); + FAIL_ON(mode.tv_margins.left != 24); + FAIL_ON(mode.tv_margins.bottom != 36); + FAIL_ON(mode.tv_margins.top != 42); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_multiple_options(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(!drm_mode_parse_command_line_for_connector("720x480,rotate=270,reflect_x", + &connector, + &mode)); + FAIL_ON(!mode.specified); + FAIL_ON(mode.xres != 720); + FAIL_ON(mode.yres != 480); + FAIL_ON(mode.rotation_reflection != (DRM_MODE_ROTATE_270 | DRM_MODE_REFLECT_X)); + + FAIL_ON(mode.refresh_specified); + + FAIL_ON(mode.bpp_specified); + + FAIL_ON(mode.rb); + FAIL_ON(mode.cvt); + FAIL_ON(mode.interlace); + FAIL_ON(mode.margins); + FAIL_ON(mode.force != DRM_FORCE_UNSPECIFIED); + + return 0; +} + +static int drm_cmdline_test_invalid_option(void *ignored) +{ + struct drm_connector connector = { }; + struct drm_cmdline_mode mode = { }; + + FAIL_ON(drm_mode_parse_command_line_for_connector("720x480,test=42", + &connector, + &mode)); + + return 0; +} + +#include "drm_selftest.c" + +static int __init test_drm_cmdline_init(void) +{ + int err; + + err = run_selftests(selftests, ARRAY_SIZE(selftests), NULL); + + return err > 0 ? 0 : err; +} +module_init(test_drm_cmdline_init); + +MODULE_AUTHOR("Maxime Ripard "); +MODULE_LICENSE("GPL"); From patchwork Mon Jun 17 14:51:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 10999377 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1F9BE14DB for ; Mon, 17 Jun 2019 14:52:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 110B728689 for ; Mon, 17 Jun 2019 14:52:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 04C1328872; Mon, 17 Jun 2019 14:52:01 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, 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 B89B5286A8 for ; Mon, 17 Jun 2019 14:52:00 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id DFC38892EA; Mon, 17 Jun 2019 14:51:59 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from relay4-d.mail.gandi.net (relay4-d.mail.gandi.net [217.70.183.196]) by gabe.freedesktop.org (Postfix) with ESMTPS id C9EE6892EA for ; Mon, 17 Jun 2019 14:51:58 +0000 (UTC) X-Originating-IP: 90.88.23.150 Received: from localhost (aaubervilliers-681-1-81-150.w90-88.abo.wanadoo.fr [90.88.23.150]) (Authenticated sender: maxime.ripard@bootlin.com) by relay4-d.mail.gandi.net (Postfix) with ESMTPSA id 439E6E0011; Mon, 17 Jun 2019 14:51:55 +0000 (UTC) From: Maxime Ripard To: Maarten Lankhorst , Sean Paul , Maxime Ripard , Daniel Vetter , David Airlie Subject: [PATCH v5 12/12] drm/vc4: hdmi: Set default state margin at reset Date: Mon, 17 Jun 2019 16:51:39 +0200 Message-Id: <44e24172e300be6a41578517021ef6a6e90ed682.1560783090.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: eben@raspberrypi.org, dri-devel@lists.freedesktop.org, Paul Kocialkowski , Thomas Petazzoni , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Now that the TV margins are properly parsed and filled into drm_cmdline_mode, we just need to initialise the first state at reset to get those values and start using them. Reviewed-by: Noralf Trønnes Signed-off-by: Maxime Ripard Acked-by: Eric Anholt --- drivers/gpu/drm/vc4/vc4_hdmi.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 6beac1ca1f27..4a9c8c9fe2b1 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -258,11 +258,17 @@ static int vc4_hdmi_connector_get_modes(struct drm_connector *connector) return ret; } +static void vc4_hdmi_connector_reset(struct drm_connector *connector) +{ + drm_atomic_helper_connector_reset(connector); + drm_atomic_helper_connector_tv_reset(connector); +} + static const struct drm_connector_funcs vc4_hdmi_connector_funcs = { .detect = vc4_hdmi_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = vc4_hdmi_connector_destroy, - .reset = drm_atomic_helper_connector_reset, + .reset = vc4_hdmi_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, };