From patchwork Thu Nov 10 11:07:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 13038663 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EFFECC4332F for ; Thu, 10 Nov 2022 11:09:39 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 83EFA10E703; Thu, 10 Nov 2022 11:08:03 +0000 (UTC) Received: from new4-smtp.messagingengine.com (new4-smtp.messagingengine.com [66.111.4.230]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1D17110E6F7; Thu, 10 Nov 2022 11:07:47 +0000 (UTC) Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailnew.nyi.internal (Postfix) with ESMTP id 7CAB058026A; Thu, 10 Nov 2022 06:07:46 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Thu, 10 Nov 2022 06:07:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h=cc :cc:content-transfer-encoding:content-type:date:date:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to; s=fm2; t=1668078466; x= 1668085666; bh=AL/cMonwmwqHXoVQmiM6JW3/jlxwxICW6TDM6MsQRFs=; b=P n9KEQV7dvZ1PSGlQ/MMdxJx8/qZdusKzJlys/aw9GMmslQ+Nnc+m64/1hRxBEa2D qMWYrrPciIdK9Dgx7S/KAFmM0bgNe76Tko2/W0ZPi74aCiNVYRBTvIL/kdQxhyxy 5IWy1i4DLXSOC1bD16J/8HvJu8wHbpNhMc5qI0dPItBPmF9lDP2HdtcnvDMAybon C9lfNGapQuec/wsdNetNx/yczs48cK+ZO0MyShElMJMNcddvhKxkA92yNfbucb70 x+OiVIj/NBSSsVrWH+e0o0uLR4JMkppcop7wlI8+u+5TPLdQuNDtdfWTv/r1iMbV Q5QCKXS34PhT34rJ+/tTw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:sender:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1668078466; x= 1668085666; bh=AL/cMonwmwqHXoVQmiM6JW3/jlxwxICW6TDM6MsQRFs=; b=d HQwhqUdQAntNnBpynygpll6aN+8QDUDFB/9WntiwC+0j4pxCQ8+9aSZsO7t2SKA8 ZD2DMDy4KsAHSl6ujagSOo0VAtTapv2E8KvUH8pzuOwW6dXoc1n6MFWHeUyWxqKC aiFRlGbD9hWkUDhxaF9fZPSUiMbBfjQr070KWwiNIZDyr6J7KJDY0uIPh/36Cvp5 r0fUeKRHEmefsrr4qYfIFkX5kVXj+CTsXrO6gG7yXGi4FjrP4cknUbm4OW38jeug E2NK/il+cLHAe6LxuRagzZY8s8XH4bKUEY3zj31wZAbjHUobK0B1M35Wo+DQ/AXX mg/HMggPNtKB9KhPiJdJg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvgedrfeeggddvhecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhfffugggtgffkfhgjvfevofesthekredtredtjeenucfhrhhomhepofgrgihi mhgvucftihhprghrugcuoehmrgigihhmvgestggvrhhnohdrthgvtghhqeenucggtffrrg htthgvrhhnpeduudduhfevjeetfeegvdffvdevvdejudegudekjeehtdelhfffveethfej ledtveenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpe hmrgigihhmvgestggvrhhnohdrthgvtghh X-ME-Proxy: Feedback-ID: i8771445c:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 10 Nov 2022 06:07:45 -0500 (EST) From: Maxime Ripard Date: Thu, 10 Nov 2022 12:07:26 +0100 MIME-Version: 1.0 Message-Id: <20220728-rpi-analog-tv-properties-v8-14-09ce1466967c@cerno.tech> References: <20220728-rpi-analog-tv-properties-v8-0-09ce1466967c@cerno.tech> In-Reply-To: <20220728-rpi-analog-tv-properties-v8-0-09ce1466967c@cerno.tech> To: Maarten Lankhorst , Chen-Yu Tsai , Maxime Ripard , Jernej Skrabec , Karol Herbst , Jani Nikula , Daniel Vetter , Lyude Paul , Samuel Holland , Joonas Lahtinen , Thomas Zimmermann , Emma Anholt , Rodrigo Vivi , Tvrtko Ursulin , David Airlie , Ben Skeggs X-Mailer: b4 0.11.0-dev-99e3a X-Developer-Signature: v=1; a=openpgp-sha256; l=6199; i=maxime@cerno.tech; h=from:subject:message-id; bh=uITVgo93AFDus9oNMAs9Sx3nPNxfPVD3ewjXuKkrqGg=; b=owGbwMvMwCX2+D1vfrpE4FHG02pJDMk5t1NfernsUjla3jd93h/OTVYuoWdyzIOWG5RU2U2rWWpr H9vRUcrCIMbFICumyBIjbL4k7tSs151sfPNg5rAygQxh4OIUgInwdTIy7JHY4rx7Cif7xh0HtF5z8c /mjVBQTtoR/8vwXfiixd8OBTP8FfmzdVLVyuw5Z2/zzwyeuPnt6eBK+8dbDy/ecNZWa1vBJn4A X-Developer-Key: i=maxime@cerno.tech; a=openpgp; fpr=BE5675C37E818C8B5764241C254BCFC56BF6CE8D Subject: [Intel-gfx] [PATCH v8 14/24] drm/modes: Properly generate a drm_display_mode from a named mode X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?unknown-8bit?q?Dom_Cobley_=3Cdom=40raspberrypi=2Ecom=3E=2C_Dave_Steven?= =?unknown-8bit?q?son_=3Cdave=2Estevenson=40raspberrypi=2Ecom=3E=2C_nouveau?= =?unknown-8bit?q?=40lists=2Efreedesktop=2Eorg=2C_intel-gfx=40lists=2Efreede?= =?unknown-8bit?q?sktop=2Eorg=2C_linux-kernel=40vger=2Ekernel=2Eorg=2C_dri-d?= =?unknown-8bit?q?evel=40lists=2Efreedesktop=2Eorg=2C_Phil_Elwell_=3Cphil=40?= =?unknown-8bit?q?raspberrypi=2Ecom=3E=2C_Hans_de_Goede_=3Chdegoede=40redhat?= =?unknown-8bit?q?=2Ecom=3E=2C_Noralf_Tr=C3=B8nnes_=3Cnoralf=40tronnes=2Eorg?= =?unknown-8bit?q?=3E=2C_Geert_Uytterhoeven_=3Cgeert=40linux-m68k=2Eorg=3E?= =?unknown-8bit?q?=2C_Maxime_Ripard_=3Cmaxime=40cerno=2Etech=3E=2C_Mateusz_K?= =?unknown-8bit?q?wiatkowski_=3Ckfyatek+publicgit=40gmail=2Ecom=3E=2C_linux-?= =?unknown-8bit?q?sunxi=40lists=2Elinux=2Edev=2C_linux-arm-kernel=40lists=2E?= =?unknown-8bit?q?infradead=2Eorg?= Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" The framework will get the drm_display_mode from the drm_cmdline_mode it got by parsing the video command line argument by calling drm_connector_pick_cmdline_mode(). The heavy lifting will then be done by the drm_mode_create_from_cmdline_mode() function. In the case of the named modes though, there's no real code to make that translation and we rely on the drivers to guess which actual display mode we meant. Let's modify drm_mode_create_from_cmdline_mode() to properly generate the drm_display_mode we mean when passing a named mode. Tested-by: Mateusz Kwiatkowski Signed-off-by: Maxime Ripard Reviewed-by: Noralf Trønnes --- Changes in v8: - Return the result of drm_analog_tv_mode directly Changes in v7: - Use tv_mode_specified in drm_mode_parse_command_line_for_connector Changes in v6: - Fix get_modes to return 0 instead of an error code - Rename the tests to follow the DRM test naming convention Changes in v5: - Switched to KUNIT_ASSERT_NOT_NULL --- drivers/gpu/drm/drm_modes.c | 29 +++++++++- drivers/gpu/drm/tests/drm_client_modeset_test.c | 77 ++++++++++++++++++++++++- 2 files changed, 104 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index dc037f7ceb37..d3f0a3559812 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -2497,6 +2497,31 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option, } EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector); +static struct drm_display_mode *drm_named_mode(struct drm_device *dev, + struct drm_cmdline_mode *cmd) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(drm_named_modes); i++) { + const struct drm_named_mode *named_mode = &drm_named_modes[i]; + + if (strcmp(cmd->name, named_mode->name)) + continue; + + if (!cmd->tv_mode_specified) + continue; + + return drm_analog_tv_mode(dev, + named_mode->tv_mode, + named_mode->pixel_clock_khz * 1000, + named_mode->xres, + named_mode->yres, + named_mode->flags & DRM_MODE_FLAG_INTERLACE); + } + + return NULL; +} + /** * drm_mode_create_from_cmdline_mode - convert a command line modeline into a DRM display mode * @dev: DRM device to create the new mode for @@ -2514,7 +2539,9 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev, if (cmd->xres == 0 || cmd->yres == 0) return NULL; - if (cmd->cvt) + if (strlen(cmd->name)) + mode = drm_named_mode(dev, cmd); + else if (cmd->cvt) mode = drm_cvt_mode(dev, cmd->xres, cmd->yres, cmd->refresh_specified ? cmd->refresh : 60, diff --git a/drivers/gpu/drm/tests/drm_client_modeset_test.c b/drivers/gpu/drm/tests/drm_client_modeset_test.c index 558c098b0384..768e8efb2f52 100644 --- a/drivers/gpu/drm/tests/drm_client_modeset_test.c +++ b/drivers/gpu/drm/tests/drm_client_modeset_test.c @@ -21,7 +21,26 @@ struct drm_client_modeset_test_priv { static int drm_client_modeset_connector_get_modes(struct drm_connector *connector) { - return drm_add_modes_noedid(connector, 1920, 1200); + struct drm_display_mode *mode; + int count; + + count = drm_add_modes_noedid(connector, 1920, 1200); + + mode = drm_mode_analog_ntsc_480i(connector->dev); + if (!mode) + return count; + + drm_mode_probed_add(connector, mode); + count += 1; + + mode = drm_mode_analog_pal_576i(connector->dev); + if (!mode) + return count; + + drm_mode_probed_add(connector, mode); + count += 1; + + return count; } static const struct drm_connector_helper_funcs drm_client_modeset_connector_helper_funcs = { @@ -52,6 +71,9 @@ static int drm_client_modeset_test_init(struct kunit *test) drm_connector_helper_add(&priv->connector, &drm_client_modeset_connector_helper_funcs); + priv->connector.interlace_allowed = true; + priv->connector.doublescan_allowed = true; + return 0; } @@ -85,9 +107,62 @@ static void drm_test_pick_cmdline_res_1920_1080_60(struct kunit *test) KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode)); } +static void drm_test_pick_cmdline_named_ntsc(struct kunit *test) +{ + struct drm_client_modeset_test_priv *priv = test->priv; + struct drm_device *drm = priv->drm; + struct drm_connector *connector = &priv->connector; + struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode; + struct drm_display_mode *mode; + const char *cmdline = "NTSC"; + int ret; + + KUNIT_ASSERT_TRUE(test, + drm_mode_parse_command_line_for_connector(cmdline, + connector, + cmdline_mode)); + + mutex_lock(&drm->mode_config.mutex); + ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080); + mutex_unlock(&drm->mode_config.mutex); + KUNIT_ASSERT_GT(test, ret, 0); + + mode = drm_connector_pick_cmdline_mode(connector); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_EXPECT_TRUE(test, drm_mode_equal(drm_mode_analog_ntsc_480i(drm), mode)); +} + +static void drm_test_pick_cmdline_named_pal(struct kunit *test) +{ + struct drm_client_modeset_test_priv *priv = test->priv; + struct drm_device *drm = priv->drm; + struct drm_connector *connector = &priv->connector; + struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode; + struct drm_display_mode *mode; + const char *cmdline = "PAL"; + int ret; + + KUNIT_ASSERT_TRUE(test, + drm_mode_parse_command_line_for_connector(cmdline, + connector, + cmdline_mode)); + + mutex_lock(&drm->mode_config.mutex); + ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080); + mutex_unlock(&drm->mode_config.mutex); + KUNIT_ASSERT_GT(test, ret, 0); + + mode = drm_connector_pick_cmdline_mode(connector); + KUNIT_ASSERT_NOT_NULL(test, mode); + + KUNIT_EXPECT_TRUE(test, drm_mode_equal(drm_mode_analog_pal_576i(drm), mode)); +} static struct kunit_case drm_test_pick_cmdline_tests[] = { KUNIT_CASE(drm_test_pick_cmdline_res_1920_1080_60), + KUNIT_CASE(drm_test_pick_cmdline_named_ntsc), + KUNIT_CASE(drm_test_pick_cmdline_named_pal), {} };