From mboxrd@z Thu Jan 1 00:00:00 1970 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 B5CDBF31E44 for ; Thu, 9 Apr 2026 15:49:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References :Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=mW0Ja2FbkQHM1K+7Np14cKRo9Q3SNA4jFH3nNeqjQjs=; b=0EhmWq6wU7fUNvKo4A7D8NujIP ICs7F0EyqOSOX9WbPtQfbRZi7iNTowJHikApAZ94rpGpFjXNzBJYoBn5B1gYRei9QyMjREcDNzK9U KbAB8fG3lAboBl82CSsLmt6z6kqIgUEad7o/RIPNVuPQa/56ff9m3zIKTOxEW4m0eCbdZ3hAWYlyS NaM2q4+Z1+LW0EKfaI22X3bg96wsaVmFeyYZfwC8TSes59n6DEVzwSVLuFkxkZtgEYUps78BKdDIJ qDcgwSRNbEeeaLeTGGiaeEamFhib5k6p+NvgLvuJrT+sc4v0r6AlSB8UU79HBJH4iM8gAnx73nvdf gGv51VLg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1wArdg-0000000Arzr-3ZTC; Thu, 09 Apr 2026 15:49:53 +0000 Received: from sender4-pp-f112.zoho.com ([136.143.188.112]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1wArda-0000000Arxh-0qAd; Thu, 09 Apr 2026 15:49:51 +0000 ARC-Seal: i=1; a=rsa-sha256; t=1775749694; cv=none; d=zohomail.com; s=zohoarc; b=MtRqE8wElnZz7FpuA2N2abip777ykRAM2BI+aU3eOPb/vaw47PT+BDaQ7Q8/4P9cWiib5jvzNZJUgdFWdxW4yQzE6m42KBlDH/EGDE+Z+zJzbaFAQ5hj1xkKab4xWt2zhkDZm5ojlFwgUhyHEXlLx0Q4pxtnbtsUq26Oyvvc+/0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1775749694; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=mW0Ja2FbkQHM1K+7Np14cKRo9Q3SNA4jFH3nNeqjQjs=; b=nYdJUmwAmm3RgAIEG6JewptjM+37/KR5RCIUIEuN4+xhAJh75HZPZhfj2Ph7LUoAvXzRFKfqwNrtASADv6R4A2lFADcGsQLlV+N6B5KYaq1NTGdjaoral1OP+JBWz4q4a9hWfb/yFcFwHcBZ6FK64qjRYX3PkcR/CAeJLuqfivo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1775749694; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=mW0Ja2FbkQHM1K+7Np14cKRo9Q3SNA4jFH3nNeqjQjs=; b=OIPN4aFRfa+Enh6G8v3ad77+C/hkPIO2RxCXm4CJqUXkqC0U0bQ9s7xhM80sS9NS ZZclZRtWAOBvPetrFJbplnbf7SxdkArwO1jNH0NbrtVMOQcuA5DeFx7aaYOG8l19B7E oGK+uYXesEgwfjFIbKaTyc5qgYWxaw+SJxrVxEX0= Received: by mx.zohomail.com with SMTPS id 1775749692548354.23548498457376; Thu, 9 Apr 2026 08:48:12 -0700 (PDT) From: Nicolas Frattaroli Date: Thu, 09 Apr 2026 17:45:13 +0200 Subject: [PATCH v12 23/25] drm/tests: bridge: Add test for HDMI output bus formats helper MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260409-color-format-v12-23-ce84e1817a27@collabora.com> References: <20260409-color-format-v12-0-ce84e1817a27@collabora.com> In-Reply-To: <20260409-color-format-v12-0-ce84e1817a27@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet , Shuah Khan Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.15.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260409_084946_298134_5AC31C4F X-CRM114-Status: GOOD ( 18.13 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The common atomic_get_output_bus_fmts helper for HDMI bridge connectors, called drm_atomic_helper_bridge_get_hdmi_output_bus_fmts, should return an array of output bus formats depending on the supported formats of the connector, and the current output BPC. Add a test to exercise some of this helper. Reviewed-by: Maxime Ripard Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/tests/drm_bridge_test.c | 184 ++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_bridge_test.c b/drivers/gpu/drm/tests/drm_bridge_test.c index cb821c606070..d9bd930b1197 100644 --- a/drivers/gpu/drm/tests/drm_bridge_test.c +++ b/drivers/gpu/drm/tests/drm_bridge_test.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -118,6 +119,28 @@ static const struct drm_bridge_funcs drm_test_bridge_atomic_funcs = { .atomic_reset = drm_atomic_helper_bridge_reset, }; +static int dummy_clear_infoframe(struct drm_bridge *bridge) +{ + return 0; +} + +static int dummy_write_infoframe(struct drm_bridge *bridge, const u8 *buffer, + size_t len) +{ + return 0; +} + +static const struct drm_bridge_funcs drm_test_bridge_bus_fmts_funcs = { + .atomic_get_output_bus_fmts = drm_atomic_helper_bridge_get_hdmi_output_bus_fmts, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + .hdmi_write_avi_infoframe = dummy_write_infoframe, + .hdmi_write_hdmi_infoframe = dummy_write_infoframe, + .hdmi_clear_avi_infoframe = dummy_clear_infoframe, + .hdmi_clear_hdmi_infoframe = dummy_clear_infoframe, +}; + /** * struct fmt_tuple - a tuple of input/output MEDIA_BUS_FMT_* */ @@ -539,6 +562,83 @@ drm_test_bridge_chain_init(struct kunit *test, unsigned int num_bridges, return priv; } +static struct drm_bridge_init_priv * +drm_test_bridge_hdmi_init(struct kunit *test, const struct drm_bridge_funcs *funcs, + unsigned int supported_formats, int max_bpc) +{ + struct drm_bridge_init_priv *priv; + struct drm_encoder *enc; + struct drm_bridge *bridge; + struct drm_device *drm; + struct device *dev; + int ret; + + dev = drm_kunit_helper_alloc_device(test); + if (IS_ERR(dev)) + return ERR_CAST(dev); + + priv = drm_kunit_helper_alloc_drm_device(test, dev, + struct drm_bridge_init_priv, drm, + DRIVER_MODESET | DRIVER_ATOMIC); + if (IS_ERR(priv)) + return ERR_CAST(priv); + + priv->test_bridge = devm_drm_bridge_alloc(dev, struct drm_bridge_priv, bridge, funcs); + if (IS_ERR(priv->test_bridge)) + return ERR_CAST(priv->test_bridge); + + priv->test_bridge->data = priv; + + drm = &priv->drm; + priv->plane = drm_kunit_helper_create_primary_plane(test, drm, + NULL, + NULL, + NULL, 0, + NULL); + if (IS_ERR(priv->plane)) + return ERR_CAST(priv->plane); + + priv->crtc = drm_kunit_helper_create_crtc(test, drm, + priv->plane, NULL, + NULL, + NULL); + if (IS_ERR(priv->crtc)) + return ERR_CAST(priv->crtc); + + enc = &priv->encoder; + ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL); + if (ret) + return ERR_PTR(ret); + + enc->possible_crtcs = drm_crtc_mask(priv->crtc); + + bridge = &priv->test_bridge->bridge; + bridge->type = DRM_MODE_CONNECTOR_HDMIA; + bridge->supported_formats = supported_formats; + bridge->max_bpc = max_bpc; + bridge->ops |= DRM_BRIDGE_OP_HDMI; + bridge->vendor = "LNX"; + bridge->product = "KUnit"; + + ret = drm_kunit_bridge_add(test, bridge); + if (ret) + return ERR_PTR(ret); + + ret = drm_bridge_attach(enc, bridge, NULL, 0); + if (ret) + return ERR_PTR(ret); + + priv->connector = drm_bridge_connector_init(drm, enc); + if (IS_ERR(priv->connector)) + return ERR_CAST(priv->connector); + + drm_connector_attach_encoder(priv->connector, enc); + + drm_mode_config_reset(drm); + + return priv; +} + /* * Test that drm_bridge_get_current_state() returns the last committed * state for an atomic bridge. @@ -786,10 +886,94 @@ static void drm_test_drm_bridge_helper_reset_crtc_legacy(struct kunit *test) KUNIT_EXPECT_EQ(test, bridge_priv->disable_count, 1); } +/* + * Test that a bridge using the drm_atomic_helper_bridge_get_hdmi_output_bus_fmts() + * function for &drm_bridge_funcs.atomic_get_output_bus_fmts behaves as expected + * for an HDMI connector bridge. Does so by creating an HDMI bridge connector + * with RGB444, YCBCR444, and YCBCR420 (but not YCBCR422) as supported formats, + * sets the output depth to 8 bits per component, and then validates the returned + * list of bus formats. + */ +static void drm_test_drm_bridge_helper_hdmi_output_bus_fmts(struct kunit *test) +{ + struct drm_connector_state *conn_state; + struct drm_bridge_state *bridge_state; + struct drm_modeset_acquire_ctx ctx; + struct drm_bridge_init_priv *priv; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *mode; + unsigned int num_output_fmts; + struct drm_bridge *bridge; + u32 *out_bus_fmts; + int ret; + + priv = drm_test_bridge_hdmi_init(test, &drm_test_bridge_bus_fmts_funcs, + BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) | + BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444) | + BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420), + 12); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + + bridge = &priv->test_bridge->bridge; + + drm_modeset_acquire_init(&ctx, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + +retry_commit: + conn_state = drm_atomic_get_connector_state(state, priv->connector); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + conn_state->hdmi.output_bpc = 8; + + mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); + + ret = drm_atomic_set_crtc_for_connector(conn_state, priv->crtc); + if (ret == -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state = drm_atomic_get_crtc_state(state, priv->crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + ret = drm_atomic_set_mode_for_crtc(crtc_state, mode); + if (ret == -EDEADLK) { + drm_modeset_backoff(&ctx); + goto retry_commit; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + crtc_state->enable = true; + crtc_state->active = true; + + bridge_state = drm_atomic_get_bridge_state(state, bridge); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bridge_state); + + out_bus_fmts = bridge->funcs->atomic_get_output_bus_fmts( + bridge, bridge_state, crtc_state, conn_state, &num_output_fmts); + KUNIT_EXPECT_NOT_NULL(test, out_bus_fmts); + KUNIT_EXPECT_EQ(test, num_output_fmts, 3); + + KUNIT_EXPECT_EQ(test, out_bus_fmts[0], MEDIA_BUS_FMT_RGB888_1X24); + KUNIT_EXPECT_EQ(test, out_bus_fmts[1], MEDIA_BUS_FMT_YUV8_1X24); + KUNIT_EXPECT_EQ(test, out_bus_fmts[2], MEDIA_BUS_FMT_UYYVYY8_0_5X24); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); + + kfree(out_bus_fmts); +} + static struct kunit_case drm_bridge_helper_reset_crtc_tests[] = { KUNIT_CASE(drm_test_drm_bridge_helper_reset_crtc_atomic), KUNIT_CASE(drm_test_drm_bridge_helper_reset_crtc_atomic_disabled), KUNIT_CASE(drm_test_drm_bridge_helper_reset_crtc_legacy), + KUNIT_CASE(drm_test_drm_bridge_helper_hdmi_output_bus_fmts), { } }; -- 2.53.0