From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0.riseup.net (mx0.riseup.net [198.252.153.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 753511E9F8 for ; Thu, 10 Nov 2022 23:30:06 +0000 (UTC) Received: from fews2.riseup.net (fews2-pn.riseup.net [10.0.1.84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "mail.riseup.net", Issuer "R3" (not verified)) by mx0.riseup.net (Postfix) with ESMTPS id 4N7dNX4dZwz9svR; Thu, 10 Nov 2022 23:30:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=riseup.net; s=squak; t=1668123005; bh=fjuKmXRTkwtod6IBPhwlZ1iFXytpH70PXN+uyAnvcJU=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=bXuDGCl8gu5dbDhZxNCxNGU6m3awVbK/pl9drcFPGlU06RjvGwCTgKLdPJ+49/BLg eSp0z/ipegAp4Gs5LVSt/xvRD8PtbyXf9jQHoIJsy9S/uYK9IxCXYXo7L1lle/OaAD OiK5LcDol8WaOacjUFveKpKTPwQu8PeKxOV9ZZko= X-Riseup-User-ID: 6A1C41D0E4C101BEC78841C4EA042529A6EBD75A5D224DDA08027C25E4B89A87 Received: from [127.0.0.1] (localhost [127.0.0.1]) by fews2.riseup.net (Postfix) with ESMTPSA id 4N7dNM3v56z1yQc; Thu, 10 Nov 2022 23:29:55 +0000 (UTC) Message-ID: <4e35ba53-ee3d-31b1-cf70-6d8279e25297@riseup.net> Date: Thu, 10 Nov 2022 20:29:53 -0300 Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: Re: [PATCH v8 17/24] drm/probe-helper: Provide a TV get_modes helper Content-Language: en-US To: Maxime Ripard , 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 Cc: Dom Cobley , Dave Stevenson , nouveau@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Phil Elwell , Hans de Goede , =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= , Geert Uytterhoeven , Mateusz Kwiatkowski , linux-sunxi@lists.linux.dev, linux-arm-kernel@lists.infradead.org References: <20220728-rpi-analog-tv-properties-v8-0-09ce1466967c@cerno.tech> <20220728-rpi-analog-tv-properties-v8-17-09ce1466967c@cerno.tech> From: =?UTF-8?Q?Ma=c3=adra_Canal?= In-Reply-To: <20220728-rpi-analog-tv-properties-v8-17-09ce1466967c@cerno.tech> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hi Maxime, On 11/10/22 08:07, Maxime Ripard wrote: > From: Noralf Trønnes > > Most of the TV connectors will need a similar get_modes implementation > that will, depending on the drivers' capabilities, register the 480i and > 576i modes. > > That implementation will also need to set the preferred flag and order > the modes based on the driver and users preferrence. > > This is especially important to guarantee that a userspace stack such as > Xorg can start and pick up the preferred mode while maintaining a > working output. > > Signed-off-by: Noralf Trønnes > Tested-by: Mateusz Kwiatkowski > Signed-off-by: Maxime Ripard > > --- > Changes in v8: > - Remove unused tv_mode_support function > - Add unit tests > > Changes in v7: > - Used Noralf's implementation > > Changes in v6: > - New patch > --- > drivers/gpu/drm/drm_probe_helper.c | 82 ++++++++++ > drivers/gpu/drm/tests/Makefile | 1 + > drivers/gpu/drm/tests/drm_probe_helper_test.c | 209 ++++++++++++++++++++++++++ > include/drm/drm_probe_helper.h | 1 + > 4 files changed, 293 insertions(+) > > diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c b/drivers/gpu/drm/tests/drm_probe_helper_test.c > new file mode 100644 > index 000000000000..4f295b39f746 > --- /dev/null > +++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c > @@ -0,0 +1,209 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Kunit test for drm_probe_helper functions > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include "drm_kunit_helpers.h" > + > +static const struct drm_display_mode ntsc_mode = { > + DRM_MODE("720x480i", 0, 13500, > + 720, 736, 800, 858, 0, > + 480, 486, 492, 525, 0, > + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE) > +}; > + > +static const struct drm_display_mode pal_mode = { > + DRM_MODE("720x576i", 0, 13500, > + 720, 732, 796, 864, 0, > + 576, 581, 587, 625, 0, > + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE) > +}; > + > +struct drm_probe_helper_test_priv { > + struct drm_device *drm; > + struct drm_connector connector; > +}; > + > +static const struct drm_connector_helper_funcs drm_probe_helper_connector_helper_funcs = { > +}; > + > +static const struct drm_connector_funcs drm_probe_helper_connector_funcs = { > + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > + .reset = drm_atomic_helper_connector_reset, > +}; > + > +static int drm_probe_helper_test_init(struct kunit *test) > +{ > + struct drm_probe_helper_test_priv *priv; > + struct drm_connector *connector; > + int ret; > + > + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); > + KUNIT_ASSERT_NOT_NULL(test, priv); > + test->priv = priv; > + > + priv->drm = drm_kunit_device_init(test, DRIVER_MODESET | DRIVER_ATOMIC, > + "drm-probe-helper-test"); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > + > + connector = &priv->connector; > + ret = drmm_connector_init(priv->drm, connector, > + &drm_probe_helper_connector_funcs, > + DRM_MODE_CONNECTOR_Unknown, > + NULL); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + drm_connector_helper_add(connector, &drm_probe_helper_connector_helper_funcs); > + > + return 0; > +} > + > +struct drm_connector_helper_tv_get_modes_test { > + const char *name; > + unsigned int supported_tv_modes; > + enum drm_connector_tv_mode default_mode; > + bool cmdline; > + enum drm_connector_tv_mode cmdline_mode; > + const struct drm_display_mode **expected_modes; > + unsigned int num_expected_modes; > +}; > + > +#define _TV_MODE_TEST(_name, _supported, _default, _cmdline, _cmdline_mode, ...) \ > + { \ > + .name = _name, \ > + .supported_tv_modes = _supported, \ > + .default_mode = _default, \ > + .cmdline = _cmdline, \ > + .cmdline_mode = _cmdline_mode, \ > + .expected_modes = (const struct drm_display_mode*[]) { __VA_ARGS__ }, \ > + .num_expected_modes = sizeof((const struct drm_display_mode*[]) { __VA_ARGS__ }) / \ > + (sizeof(const struct drm_display_mode*)), \ > + } > + > +#define TV_MODE_TEST(_name, _supported, _default, ...) \ > + _TV_MODE_TEST(_name, _supported, _default, false, 0, __VA_ARGS__) > + > +#define TV_MODE_TEST_CMDLINE(_name, _supported, _default, _cmdline, ...) \ > + _TV_MODE_TEST(_name, _supported, _default, true, _cmdline, __VA_ARGS__) > + > +static void > +drm_test_connector_helper_tv_get_modes_check(struct kunit *test) > +{ > + const struct drm_connector_helper_tv_get_modes_test *params = test->param_value; > + struct drm_probe_helper_test_priv *priv = test->priv; > + struct drm_connector *connector = &priv->connector; > + struct drm_cmdline_mode *cmdline = &connector->cmdline_mode; > + struct drm_display_mode *mode; > + const struct drm_display_mode *expected; > + size_t len; > + int ret; > + > + if (params->cmdline) { > + cmdline->tv_mode_specified = true; > + cmdline->tv_mode = params->cmdline_mode; > + } > + > + ret = drm_mode_create_tv_properties(priv->drm, params->supported_tv_modes); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + drm_object_attach_property(&connector->base, > + priv->drm->mode_config.tv_mode_property, > + params->default_mode); > + > + mutex_lock(&priv->drm->mode_config.mutex); > + > + ret = drm_connector_helper_tv_get_modes(connector); > + KUNIT_EXPECT_EQ(test, ret, params->num_expected_modes); > + > + list_for_each_entry(mode, &connector->probed_modes, head) > + len++; > + KUNIT_EXPECT_EQ(test, len, params->num_expected_modes); > + > + if (params->num_expected_modes >= 1) { > + mode = list_first_entry_or_null(&connector->probed_modes, > + struct drm_display_mode, head); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); > + > + expected = params->expected_modes[0]; > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected); > + > + KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected)); > + KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED); > + } > + > + if (params->num_expected_modes >= 2) { > + mode = list_next_entry(mode, head); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); > + > + expected = params->expected_modes[1]; > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected); > + > + KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected)); > + KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED); > + } > + > + mutex_unlock(&priv->drm->mode_config.mutex); > +} > + > +static const > +struct drm_connector_helper_tv_get_modes_test drm_connector_helper_tv_get_modes_tests[] = { > + { .name = "None" }, > + TV_MODE_TEST("PAL", BIT(DRM_MODE_TV_MODE_PAL), DRM_MODE_TV_MODE_PAL, &pal_mode), > + TV_MODE_TEST("NTSC", BIT(DRM_MODE_TV_MODE_NTSC), DRM_MODE_TV_MODE_NTSC, &ntsc_mode), > + TV_MODE_TEST("Both, NTSC Default", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_NTSC, > + &ntsc_mode, &pal_mode), > + TV_MODE_TEST("Both, PAL Default", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_PAL, > + &pal_mode, &ntsc_mode), > + TV_MODE_TEST_CMDLINE("Both, NTSC Default, with PAL on command-line", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_NTSC, > + DRM_MODE_TV_MODE_PAL, > + &pal_mode, &ntsc_mode), > + TV_MODE_TEST_CMDLINE("Both, PAL Default, with NTSC on command-line", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_PAL, > + DRM_MODE_TV_MODE_NTSC, > + &ntsc_mode, &pal_mode), > +}; > + > +static void > +drm_connector_helper_tv_get_modes_desc(const struct drm_connector_helper_tv_get_modes_test *t, > + char *desc) > +{ > + sprintf(desc, "%s", t->name); > +} > +KUNIT_ARRAY_PARAM(drm_connector_helper_tv_get_modes, > + drm_connector_helper_tv_get_modes_tests, > + drm_connector_helper_tv_get_modes_desc); > + > +static struct kunit_case drm_test_connector_helper_tv_get_modes_tests[] = { > + KUNIT_CASE_PARAM(drm_test_connector_helper_tv_get_modes_check, > + drm_connector_helper_tv_get_modes_gen_params), > + { } > +}; > + > +static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = { > + .name = "drm_test_connector_helper_tv_get_modes", > + .init = drm_probe_helper_test_init, > + .test_cases = drm_test_connector_helper_tv_get_modes_tests, > +}; > + > +kunit_test_suites( > + &drm_test_connector_helper_tv_get_modes_suite > +); Considering that there is only one suite, you could use the kunit_test_suite macro instead. Moreover, it would be nice to run the checkpatch script on this test, as there are a couple of problems with the code style. Best Regards, - Maíra Canal 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 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 5D450C433FE for ; Thu, 10 Nov 2022 23:30:10 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B1F3010E11B; Thu, 10 Nov 2022 23:30:09 +0000 (UTC) X-Greylist: delayed 1076 seconds by postgrey-1.36 at gabe; Thu, 10 Nov 2022 23:30:06 UTC Received: from mx0.riseup.net (mx0.riseup.net [198.252.153.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5ED7610E11B; Thu, 10 Nov 2022 23:30:06 +0000 (UTC) Received: from fews2.riseup.net (fews2-pn.riseup.net [10.0.1.84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "mail.riseup.net", Issuer "R3" (not verified)) by mx0.riseup.net (Postfix) with ESMTPS id 4N7dNX4dZwz9svR; Thu, 10 Nov 2022 23:30:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=riseup.net; s=squak; t=1668123005; bh=fjuKmXRTkwtod6IBPhwlZ1iFXytpH70PXN+uyAnvcJU=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=bXuDGCl8gu5dbDhZxNCxNGU6m3awVbK/pl9drcFPGlU06RjvGwCTgKLdPJ+49/BLg eSp0z/ipegAp4Gs5LVSt/xvRD8PtbyXf9jQHoIJsy9S/uYK9IxCXYXo7L1lle/OaAD OiK5LcDol8WaOacjUFveKpKTPwQu8PeKxOV9ZZko= X-Riseup-User-ID: 6A1C41D0E4C101BEC78841C4EA042529A6EBD75A5D224DDA08027C25E4B89A87 Received: from [127.0.0.1] (localhost [127.0.0.1]) by fews2.riseup.net (Postfix) with ESMTPSA id 4N7dNM3v56z1yQc; Thu, 10 Nov 2022 23:29:55 +0000 (UTC) Message-ID: <4e35ba53-ee3d-31b1-cf70-6d8279e25297@riseup.net> Date: Thu, 10 Nov 2022 20:29:53 -0300 MIME-Version: 1.0 Content-Language: en-US To: Maxime Ripard , 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 References: <20220728-rpi-analog-tv-properties-v8-0-09ce1466967c@cerno.tech> <20220728-rpi-analog-tv-properties-v8-17-09ce1466967c@cerno.tech> From: =?UTF-8?Q?Ma=c3=adra_Canal?= In-Reply-To: <20220728-rpi-analog-tv-properties-v8-17-09ce1466967c@cerno.tech> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: Re: [Nouveau] [PATCH v8 17/24] drm/probe-helper: Provide a TV get_modes helper X-BeenThere: nouveau@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Nouveau development list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dom Cobley , nouveau@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Mateusz Kwiatkowski , Hans de Goede , =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= , Geert Uytterhoeven , linux-sunxi@lists.linux.dev, Phil Elwell , linux-arm-kernel@lists.infradead.org Errors-To: nouveau-bounces@lists.freedesktop.org Sender: "Nouveau" Hi Maxime, On 11/10/22 08:07, Maxime Ripard wrote: > From: Noralf Trønnes > > Most of the TV connectors will need a similar get_modes implementation > that will, depending on the drivers' capabilities, register the 480i and > 576i modes. > > That implementation will also need to set the preferred flag and order > the modes based on the driver and users preferrence. > > This is especially important to guarantee that a userspace stack such as > Xorg can start and pick up the preferred mode while maintaining a > working output. > > Signed-off-by: Noralf Trønnes > Tested-by: Mateusz Kwiatkowski > Signed-off-by: Maxime Ripard > > --- > Changes in v8: > - Remove unused tv_mode_support function > - Add unit tests > > Changes in v7: > - Used Noralf's implementation > > Changes in v6: > - New patch > --- > drivers/gpu/drm/drm_probe_helper.c | 82 ++++++++++ > drivers/gpu/drm/tests/Makefile | 1 + > drivers/gpu/drm/tests/drm_probe_helper_test.c | 209 ++++++++++++++++++++++++++ > include/drm/drm_probe_helper.h | 1 + > 4 files changed, 293 insertions(+) > > diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c b/drivers/gpu/drm/tests/drm_probe_helper_test.c > new file mode 100644 > index 000000000000..4f295b39f746 > --- /dev/null > +++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c > @@ -0,0 +1,209 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Kunit test for drm_probe_helper functions > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include "drm_kunit_helpers.h" > + > +static const struct drm_display_mode ntsc_mode = { > + DRM_MODE("720x480i", 0, 13500, > + 720, 736, 800, 858, 0, > + 480, 486, 492, 525, 0, > + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE) > +}; > + > +static const struct drm_display_mode pal_mode = { > + DRM_MODE("720x576i", 0, 13500, > + 720, 732, 796, 864, 0, > + 576, 581, 587, 625, 0, > + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE) > +}; > + > +struct drm_probe_helper_test_priv { > + struct drm_device *drm; > + struct drm_connector connector; > +}; > + > +static const struct drm_connector_helper_funcs drm_probe_helper_connector_helper_funcs = { > +}; > + > +static const struct drm_connector_funcs drm_probe_helper_connector_funcs = { > + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > + .reset = drm_atomic_helper_connector_reset, > +}; > + > +static int drm_probe_helper_test_init(struct kunit *test) > +{ > + struct drm_probe_helper_test_priv *priv; > + struct drm_connector *connector; > + int ret; > + > + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); > + KUNIT_ASSERT_NOT_NULL(test, priv); > + test->priv = priv; > + > + priv->drm = drm_kunit_device_init(test, DRIVER_MODESET | DRIVER_ATOMIC, > + "drm-probe-helper-test"); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > + > + connector = &priv->connector; > + ret = drmm_connector_init(priv->drm, connector, > + &drm_probe_helper_connector_funcs, > + DRM_MODE_CONNECTOR_Unknown, > + NULL); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + drm_connector_helper_add(connector, &drm_probe_helper_connector_helper_funcs); > + > + return 0; > +} > + > +struct drm_connector_helper_tv_get_modes_test { > + const char *name; > + unsigned int supported_tv_modes; > + enum drm_connector_tv_mode default_mode; > + bool cmdline; > + enum drm_connector_tv_mode cmdline_mode; > + const struct drm_display_mode **expected_modes; > + unsigned int num_expected_modes; > +}; > + > +#define _TV_MODE_TEST(_name, _supported, _default, _cmdline, _cmdline_mode, ...) \ > + { \ > + .name = _name, \ > + .supported_tv_modes = _supported, \ > + .default_mode = _default, \ > + .cmdline = _cmdline, \ > + .cmdline_mode = _cmdline_mode, \ > + .expected_modes = (const struct drm_display_mode*[]) { __VA_ARGS__ }, \ > + .num_expected_modes = sizeof((const struct drm_display_mode*[]) { __VA_ARGS__ }) / \ > + (sizeof(const struct drm_display_mode*)), \ > + } > + > +#define TV_MODE_TEST(_name, _supported, _default, ...) \ > + _TV_MODE_TEST(_name, _supported, _default, false, 0, __VA_ARGS__) > + > +#define TV_MODE_TEST_CMDLINE(_name, _supported, _default, _cmdline, ...) \ > + _TV_MODE_TEST(_name, _supported, _default, true, _cmdline, __VA_ARGS__) > + > +static void > +drm_test_connector_helper_tv_get_modes_check(struct kunit *test) > +{ > + const struct drm_connector_helper_tv_get_modes_test *params = test->param_value; > + struct drm_probe_helper_test_priv *priv = test->priv; > + struct drm_connector *connector = &priv->connector; > + struct drm_cmdline_mode *cmdline = &connector->cmdline_mode; > + struct drm_display_mode *mode; > + const struct drm_display_mode *expected; > + size_t len; > + int ret; > + > + if (params->cmdline) { > + cmdline->tv_mode_specified = true; > + cmdline->tv_mode = params->cmdline_mode; > + } > + > + ret = drm_mode_create_tv_properties(priv->drm, params->supported_tv_modes); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + drm_object_attach_property(&connector->base, > + priv->drm->mode_config.tv_mode_property, > + params->default_mode); > + > + mutex_lock(&priv->drm->mode_config.mutex); > + > + ret = drm_connector_helper_tv_get_modes(connector); > + KUNIT_EXPECT_EQ(test, ret, params->num_expected_modes); > + > + list_for_each_entry(mode, &connector->probed_modes, head) > + len++; > + KUNIT_EXPECT_EQ(test, len, params->num_expected_modes); > + > + if (params->num_expected_modes >= 1) { > + mode = list_first_entry_or_null(&connector->probed_modes, > + struct drm_display_mode, head); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); > + > + expected = params->expected_modes[0]; > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected); > + > + KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected)); > + KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED); > + } > + > + if (params->num_expected_modes >= 2) { > + mode = list_next_entry(mode, head); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); > + > + expected = params->expected_modes[1]; > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected); > + > + KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected)); > + KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED); > + } > + > + mutex_unlock(&priv->drm->mode_config.mutex); > +} > + > +static const > +struct drm_connector_helper_tv_get_modes_test drm_connector_helper_tv_get_modes_tests[] = { > + { .name = "None" }, > + TV_MODE_TEST("PAL", BIT(DRM_MODE_TV_MODE_PAL), DRM_MODE_TV_MODE_PAL, &pal_mode), > + TV_MODE_TEST("NTSC", BIT(DRM_MODE_TV_MODE_NTSC), DRM_MODE_TV_MODE_NTSC, &ntsc_mode), > + TV_MODE_TEST("Both, NTSC Default", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_NTSC, > + &ntsc_mode, &pal_mode), > + TV_MODE_TEST("Both, PAL Default", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_PAL, > + &pal_mode, &ntsc_mode), > + TV_MODE_TEST_CMDLINE("Both, NTSC Default, with PAL on command-line", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_NTSC, > + DRM_MODE_TV_MODE_PAL, > + &pal_mode, &ntsc_mode), > + TV_MODE_TEST_CMDLINE("Both, PAL Default, with NTSC on command-line", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_PAL, > + DRM_MODE_TV_MODE_NTSC, > + &ntsc_mode, &pal_mode), > +}; > + > +static void > +drm_connector_helper_tv_get_modes_desc(const struct drm_connector_helper_tv_get_modes_test *t, > + char *desc) > +{ > + sprintf(desc, "%s", t->name); > +} > +KUNIT_ARRAY_PARAM(drm_connector_helper_tv_get_modes, > + drm_connector_helper_tv_get_modes_tests, > + drm_connector_helper_tv_get_modes_desc); > + > +static struct kunit_case drm_test_connector_helper_tv_get_modes_tests[] = { > + KUNIT_CASE_PARAM(drm_test_connector_helper_tv_get_modes_check, > + drm_connector_helper_tv_get_modes_gen_params), > + { } > +}; > + > +static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = { > + .name = "drm_test_connector_helper_tv_get_modes", > + .init = drm_probe_helper_test_init, > + .test_cases = drm_test_connector_helper_tv_get_modes_tests, > +}; > + > +kunit_test_suites( > + &drm_test_connector_helper_tv_get_modes_suite > +); Considering that there is only one suite, you could use the kunit_test_suite macro instead. Moreover, it would be nice to run the checkpatch script on this test, as there are a couple of problems with the code style. Best Regards, - Maíra Canal 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 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 E2E59C4332F for ; Thu, 10 Nov 2022 23:30:16 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F310010E125; Thu, 10 Nov 2022 23:30:12 +0000 (UTC) X-Greylist: delayed 1076 seconds by postgrey-1.36 at gabe; Thu, 10 Nov 2022 23:30:06 UTC Received: from mx0.riseup.net (mx0.riseup.net [198.252.153.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5ED7610E11B; Thu, 10 Nov 2022 23:30:06 +0000 (UTC) Received: from fews2.riseup.net (fews2-pn.riseup.net [10.0.1.84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "mail.riseup.net", Issuer "R3" (not verified)) by mx0.riseup.net (Postfix) with ESMTPS id 4N7dNX4dZwz9svR; Thu, 10 Nov 2022 23:30:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=riseup.net; s=squak; t=1668123005; bh=fjuKmXRTkwtod6IBPhwlZ1iFXytpH70PXN+uyAnvcJU=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=bXuDGCl8gu5dbDhZxNCxNGU6m3awVbK/pl9drcFPGlU06RjvGwCTgKLdPJ+49/BLg eSp0z/ipegAp4Gs5LVSt/xvRD8PtbyXf9jQHoIJsy9S/uYK9IxCXYXo7L1lle/OaAD OiK5LcDol8WaOacjUFveKpKTPwQu8PeKxOV9ZZko= X-Riseup-User-ID: 6A1C41D0E4C101BEC78841C4EA042529A6EBD75A5D224DDA08027C25E4B89A87 Received: from [127.0.0.1] (localhost [127.0.0.1]) by fews2.riseup.net (Postfix) with ESMTPSA id 4N7dNM3v56z1yQc; Thu, 10 Nov 2022 23:29:55 +0000 (UTC) Message-ID: <4e35ba53-ee3d-31b1-cf70-6d8279e25297@riseup.net> Date: Thu, 10 Nov 2022 20:29:53 -0300 MIME-Version: 1.0 Subject: Re: [PATCH v8 17/24] drm/probe-helper: Provide a TV get_modes helper Content-Language: en-US To: Maxime Ripard , 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 References: <20220728-rpi-analog-tv-properties-v8-0-09ce1466967c@cerno.tech> <20220728-rpi-analog-tv-properties-v8-17-09ce1466967c@cerno.tech> From: =?UTF-8?Q?Ma=c3=adra_Canal?= In-Reply-To: <20220728-rpi-analog-tv-properties-v8-17-09ce1466967c@cerno.tech> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dom Cobley , Dave Stevenson , nouveau@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Mateusz Kwiatkowski , Hans de Goede , =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= , Geert Uytterhoeven , linux-sunxi@lists.linux.dev, Phil Elwell , linux-arm-kernel@lists.infradead.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Hi Maxime, On 11/10/22 08:07, Maxime Ripard wrote: > From: Noralf Trønnes > > Most of the TV connectors will need a similar get_modes implementation > that will, depending on the drivers' capabilities, register the 480i and > 576i modes. > > That implementation will also need to set the preferred flag and order > the modes based on the driver and users preferrence. > > This is especially important to guarantee that a userspace stack such as > Xorg can start and pick up the preferred mode while maintaining a > working output. > > Signed-off-by: Noralf Trønnes > Tested-by: Mateusz Kwiatkowski > Signed-off-by: Maxime Ripard > > --- > Changes in v8: > - Remove unused tv_mode_support function > - Add unit tests > > Changes in v7: > - Used Noralf's implementation > > Changes in v6: > - New patch > --- > drivers/gpu/drm/drm_probe_helper.c | 82 ++++++++++ > drivers/gpu/drm/tests/Makefile | 1 + > drivers/gpu/drm/tests/drm_probe_helper_test.c | 209 ++++++++++++++++++++++++++ > include/drm/drm_probe_helper.h | 1 + > 4 files changed, 293 insertions(+) > > diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c b/drivers/gpu/drm/tests/drm_probe_helper_test.c > new file mode 100644 > index 000000000000..4f295b39f746 > --- /dev/null > +++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c > @@ -0,0 +1,209 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Kunit test for drm_probe_helper functions > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include "drm_kunit_helpers.h" > + > +static const struct drm_display_mode ntsc_mode = { > + DRM_MODE("720x480i", 0, 13500, > + 720, 736, 800, 858, 0, > + 480, 486, 492, 525, 0, > + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE) > +}; > + > +static const struct drm_display_mode pal_mode = { > + DRM_MODE("720x576i", 0, 13500, > + 720, 732, 796, 864, 0, > + 576, 581, 587, 625, 0, > + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE) > +}; > + > +struct drm_probe_helper_test_priv { > + struct drm_device *drm; > + struct drm_connector connector; > +}; > + > +static const struct drm_connector_helper_funcs drm_probe_helper_connector_helper_funcs = { > +}; > + > +static const struct drm_connector_funcs drm_probe_helper_connector_funcs = { > + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > + .reset = drm_atomic_helper_connector_reset, > +}; > + > +static int drm_probe_helper_test_init(struct kunit *test) > +{ > + struct drm_probe_helper_test_priv *priv; > + struct drm_connector *connector; > + int ret; > + > + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); > + KUNIT_ASSERT_NOT_NULL(test, priv); > + test->priv = priv; > + > + priv->drm = drm_kunit_device_init(test, DRIVER_MODESET | DRIVER_ATOMIC, > + "drm-probe-helper-test"); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > + > + connector = &priv->connector; > + ret = drmm_connector_init(priv->drm, connector, > + &drm_probe_helper_connector_funcs, > + DRM_MODE_CONNECTOR_Unknown, > + NULL); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + drm_connector_helper_add(connector, &drm_probe_helper_connector_helper_funcs); > + > + return 0; > +} > + > +struct drm_connector_helper_tv_get_modes_test { > + const char *name; > + unsigned int supported_tv_modes; > + enum drm_connector_tv_mode default_mode; > + bool cmdline; > + enum drm_connector_tv_mode cmdline_mode; > + const struct drm_display_mode **expected_modes; > + unsigned int num_expected_modes; > +}; > + > +#define _TV_MODE_TEST(_name, _supported, _default, _cmdline, _cmdline_mode, ...) \ > + { \ > + .name = _name, \ > + .supported_tv_modes = _supported, \ > + .default_mode = _default, \ > + .cmdline = _cmdline, \ > + .cmdline_mode = _cmdline_mode, \ > + .expected_modes = (const struct drm_display_mode*[]) { __VA_ARGS__ }, \ > + .num_expected_modes = sizeof((const struct drm_display_mode*[]) { __VA_ARGS__ }) / \ > + (sizeof(const struct drm_display_mode*)), \ > + } > + > +#define TV_MODE_TEST(_name, _supported, _default, ...) \ > + _TV_MODE_TEST(_name, _supported, _default, false, 0, __VA_ARGS__) > + > +#define TV_MODE_TEST_CMDLINE(_name, _supported, _default, _cmdline, ...) \ > + _TV_MODE_TEST(_name, _supported, _default, true, _cmdline, __VA_ARGS__) > + > +static void > +drm_test_connector_helper_tv_get_modes_check(struct kunit *test) > +{ > + const struct drm_connector_helper_tv_get_modes_test *params = test->param_value; > + struct drm_probe_helper_test_priv *priv = test->priv; > + struct drm_connector *connector = &priv->connector; > + struct drm_cmdline_mode *cmdline = &connector->cmdline_mode; > + struct drm_display_mode *mode; > + const struct drm_display_mode *expected; > + size_t len; > + int ret; > + > + if (params->cmdline) { > + cmdline->tv_mode_specified = true; > + cmdline->tv_mode = params->cmdline_mode; > + } > + > + ret = drm_mode_create_tv_properties(priv->drm, params->supported_tv_modes); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + drm_object_attach_property(&connector->base, > + priv->drm->mode_config.tv_mode_property, > + params->default_mode); > + > + mutex_lock(&priv->drm->mode_config.mutex); > + > + ret = drm_connector_helper_tv_get_modes(connector); > + KUNIT_EXPECT_EQ(test, ret, params->num_expected_modes); > + > + list_for_each_entry(mode, &connector->probed_modes, head) > + len++; > + KUNIT_EXPECT_EQ(test, len, params->num_expected_modes); > + > + if (params->num_expected_modes >= 1) { > + mode = list_first_entry_or_null(&connector->probed_modes, > + struct drm_display_mode, head); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); > + > + expected = params->expected_modes[0]; > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected); > + > + KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected)); > + KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED); > + } > + > + if (params->num_expected_modes >= 2) { > + mode = list_next_entry(mode, head); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); > + > + expected = params->expected_modes[1]; > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected); > + > + KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected)); > + KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED); > + } > + > + mutex_unlock(&priv->drm->mode_config.mutex); > +} > + > +static const > +struct drm_connector_helper_tv_get_modes_test drm_connector_helper_tv_get_modes_tests[] = { > + { .name = "None" }, > + TV_MODE_TEST("PAL", BIT(DRM_MODE_TV_MODE_PAL), DRM_MODE_TV_MODE_PAL, &pal_mode), > + TV_MODE_TEST("NTSC", BIT(DRM_MODE_TV_MODE_NTSC), DRM_MODE_TV_MODE_NTSC, &ntsc_mode), > + TV_MODE_TEST("Both, NTSC Default", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_NTSC, > + &ntsc_mode, &pal_mode), > + TV_MODE_TEST("Both, PAL Default", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_PAL, > + &pal_mode, &ntsc_mode), > + TV_MODE_TEST_CMDLINE("Both, NTSC Default, with PAL on command-line", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_NTSC, > + DRM_MODE_TV_MODE_PAL, > + &pal_mode, &ntsc_mode), > + TV_MODE_TEST_CMDLINE("Both, PAL Default, with NTSC on command-line", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_PAL, > + DRM_MODE_TV_MODE_NTSC, > + &ntsc_mode, &pal_mode), > +}; > + > +static void > +drm_connector_helper_tv_get_modes_desc(const struct drm_connector_helper_tv_get_modes_test *t, > + char *desc) > +{ > + sprintf(desc, "%s", t->name); > +} > +KUNIT_ARRAY_PARAM(drm_connector_helper_tv_get_modes, > + drm_connector_helper_tv_get_modes_tests, > + drm_connector_helper_tv_get_modes_desc); > + > +static struct kunit_case drm_test_connector_helper_tv_get_modes_tests[] = { > + KUNIT_CASE_PARAM(drm_test_connector_helper_tv_get_modes_check, > + drm_connector_helper_tv_get_modes_gen_params), > + { } > +}; > + > +static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = { > + .name = "drm_test_connector_helper_tv_get_modes", > + .init = drm_probe_helper_test_init, > + .test_cases = drm_test_connector_helper_tv_get_modes_tests, > +}; > + > +kunit_test_suites( > + &drm_test_connector_helper_tv_get_modes_suite > +); Considering that there is only one suite, you could use the kunit_test_suite macro instead. Moreover, it would be nice to run the checkpatch script on this test, as there are a couple of problems with the code style. Best Regards, - Maíra Canal 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 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 BD959C4332F for ; Thu, 10 Nov 2022 23:30:12 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0AA4A10E129; Thu, 10 Nov 2022 23:30:11 +0000 (UTC) X-Greylist: delayed 1076 seconds by postgrey-1.36 at gabe; Thu, 10 Nov 2022 23:30:06 UTC Received: from mx0.riseup.net (mx0.riseup.net [198.252.153.6]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5ED7610E11B; Thu, 10 Nov 2022 23:30:06 +0000 (UTC) Received: from fews2.riseup.net (fews2-pn.riseup.net [10.0.1.84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "mail.riseup.net", Issuer "R3" (not verified)) by mx0.riseup.net (Postfix) with ESMTPS id 4N7dNX4dZwz9svR; Thu, 10 Nov 2022 23:30:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=riseup.net; s=squak; t=1668123005; bh=fjuKmXRTkwtod6IBPhwlZ1iFXytpH70PXN+uyAnvcJU=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=bXuDGCl8gu5dbDhZxNCxNGU6m3awVbK/pl9drcFPGlU06RjvGwCTgKLdPJ+49/BLg eSp0z/ipegAp4Gs5LVSt/xvRD8PtbyXf9jQHoIJsy9S/uYK9IxCXYXo7L1lle/OaAD OiK5LcDol8WaOacjUFveKpKTPwQu8PeKxOV9ZZko= X-Riseup-User-ID: 6A1C41D0E4C101BEC78841C4EA042529A6EBD75A5D224DDA08027C25E4B89A87 Received: from [127.0.0.1] (localhost [127.0.0.1]) by fews2.riseup.net (Postfix) with ESMTPSA id 4N7dNM3v56z1yQc; Thu, 10 Nov 2022 23:29:55 +0000 (UTC) Message-ID: <4e35ba53-ee3d-31b1-cf70-6d8279e25297@riseup.net> Date: Thu, 10 Nov 2022 20:29:53 -0300 MIME-Version: 1.0 Content-Language: en-US To: Maxime Ripard , 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 References: <20220728-rpi-analog-tv-properties-v8-0-09ce1466967c@cerno.tech> <20220728-rpi-analog-tv-properties-v8-17-09ce1466967c@cerno.tech> From: =?UTF-8?Q?Ma=c3=adra_Canal?= In-Reply-To: <20220728-rpi-analog-tv-properties-v8-17-09ce1466967c@cerno.tech> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: Re: [Intel-gfx] [PATCH v8 17/24] drm/probe-helper: Provide a TV get_modes helper 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: Dom Cobley , Dave Stevenson , nouveau@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Mateusz Kwiatkowski , Hans de Goede , =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= , Geert Uytterhoeven , linux-sunxi@lists.linux.dev, Phil Elwell , linux-arm-kernel@lists.infradead.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" Hi Maxime, On 11/10/22 08:07, Maxime Ripard wrote: > From: Noralf Trønnes > > Most of the TV connectors will need a similar get_modes implementation > that will, depending on the drivers' capabilities, register the 480i and > 576i modes. > > That implementation will also need to set the preferred flag and order > the modes based on the driver and users preferrence. > > This is especially important to guarantee that a userspace stack such as > Xorg can start and pick up the preferred mode while maintaining a > working output. > > Signed-off-by: Noralf Trønnes > Tested-by: Mateusz Kwiatkowski > Signed-off-by: Maxime Ripard > > --- > Changes in v8: > - Remove unused tv_mode_support function > - Add unit tests > > Changes in v7: > - Used Noralf's implementation > > Changes in v6: > - New patch > --- > drivers/gpu/drm/drm_probe_helper.c | 82 ++++++++++ > drivers/gpu/drm/tests/Makefile | 1 + > drivers/gpu/drm/tests/drm_probe_helper_test.c | 209 ++++++++++++++++++++++++++ > include/drm/drm_probe_helper.h | 1 + > 4 files changed, 293 insertions(+) > > diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c b/drivers/gpu/drm/tests/drm_probe_helper_test.c > new file mode 100644 > index 000000000000..4f295b39f746 > --- /dev/null > +++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c > @@ -0,0 +1,209 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Kunit test for drm_probe_helper functions > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +#include "drm_kunit_helpers.h" > + > +static const struct drm_display_mode ntsc_mode = { > + DRM_MODE("720x480i", 0, 13500, > + 720, 736, 800, 858, 0, > + 480, 486, 492, 525, 0, > + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE) > +}; > + > +static const struct drm_display_mode pal_mode = { > + DRM_MODE("720x576i", 0, 13500, > + 720, 732, 796, 864, 0, > + 576, 581, 587, 625, 0, > + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_INTERLACE) > +}; > + > +struct drm_probe_helper_test_priv { > + struct drm_device *drm; > + struct drm_connector connector; > +}; > + > +static const struct drm_connector_helper_funcs drm_probe_helper_connector_helper_funcs = { > +}; > + > +static const struct drm_connector_funcs drm_probe_helper_connector_funcs = { > + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, > + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, > + .reset = drm_atomic_helper_connector_reset, > +}; > + > +static int drm_probe_helper_test_init(struct kunit *test) > +{ > + struct drm_probe_helper_test_priv *priv; > + struct drm_connector *connector; > + int ret; > + > + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); > + KUNIT_ASSERT_NOT_NULL(test, priv); > + test->priv = priv; > + > + priv->drm = drm_kunit_device_init(test, DRIVER_MODESET | DRIVER_ATOMIC, > + "drm-probe-helper-test"); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); > + > + connector = &priv->connector; > + ret = drmm_connector_init(priv->drm, connector, > + &drm_probe_helper_connector_funcs, > + DRM_MODE_CONNECTOR_Unknown, > + NULL); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + drm_connector_helper_add(connector, &drm_probe_helper_connector_helper_funcs); > + > + return 0; > +} > + > +struct drm_connector_helper_tv_get_modes_test { > + const char *name; > + unsigned int supported_tv_modes; > + enum drm_connector_tv_mode default_mode; > + bool cmdline; > + enum drm_connector_tv_mode cmdline_mode; > + const struct drm_display_mode **expected_modes; > + unsigned int num_expected_modes; > +}; > + > +#define _TV_MODE_TEST(_name, _supported, _default, _cmdline, _cmdline_mode, ...) \ > + { \ > + .name = _name, \ > + .supported_tv_modes = _supported, \ > + .default_mode = _default, \ > + .cmdline = _cmdline, \ > + .cmdline_mode = _cmdline_mode, \ > + .expected_modes = (const struct drm_display_mode*[]) { __VA_ARGS__ }, \ > + .num_expected_modes = sizeof((const struct drm_display_mode*[]) { __VA_ARGS__ }) / \ > + (sizeof(const struct drm_display_mode*)), \ > + } > + > +#define TV_MODE_TEST(_name, _supported, _default, ...) \ > + _TV_MODE_TEST(_name, _supported, _default, false, 0, __VA_ARGS__) > + > +#define TV_MODE_TEST_CMDLINE(_name, _supported, _default, _cmdline, ...) \ > + _TV_MODE_TEST(_name, _supported, _default, true, _cmdline, __VA_ARGS__) > + > +static void > +drm_test_connector_helper_tv_get_modes_check(struct kunit *test) > +{ > + const struct drm_connector_helper_tv_get_modes_test *params = test->param_value; > + struct drm_probe_helper_test_priv *priv = test->priv; > + struct drm_connector *connector = &priv->connector; > + struct drm_cmdline_mode *cmdline = &connector->cmdline_mode; > + struct drm_display_mode *mode; > + const struct drm_display_mode *expected; > + size_t len; > + int ret; > + > + if (params->cmdline) { > + cmdline->tv_mode_specified = true; > + cmdline->tv_mode = params->cmdline_mode; > + } > + > + ret = drm_mode_create_tv_properties(priv->drm, params->supported_tv_modes); > + KUNIT_ASSERT_EQ(test, ret, 0); > + > + drm_object_attach_property(&connector->base, > + priv->drm->mode_config.tv_mode_property, > + params->default_mode); > + > + mutex_lock(&priv->drm->mode_config.mutex); > + > + ret = drm_connector_helper_tv_get_modes(connector); > + KUNIT_EXPECT_EQ(test, ret, params->num_expected_modes); > + > + list_for_each_entry(mode, &connector->probed_modes, head) > + len++; > + KUNIT_EXPECT_EQ(test, len, params->num_expected_modes); > + > + if (params->num_expected_modes >= 1) { > + mode = list_first_entry_or_null(&connector->probed_modes, > + struct drm_display_mode, head); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); > + > + expected = params->expected_modes[0]; > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected); > + > + KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected)); > + KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED); > + } > + > + if (params->num_expected_modes >= 2) { > + mode = list_next_entry(mode, head); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); > + > + expected = params->expected_modes[1]; > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected); > + > + KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected)); > + KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED); > + } > + > + mutex_unlock(&priv->drm->mode_config.mutex); > +} > + > +static const > +struct drm_connector_helper_tv_get_modes_test drm_connector_helper_tv_get_modes_tests[] = { > + { .name = "None" }, > + TV_MODE_TEST("PAL", BIT(DRM_MODE_TV_MODE_PAL), DRM_MODE_TV_MODE_PAL, &pal_mode), > + TV_MODE_TEST("NTSC", BIT(DRM_MODE_TV_MODE_NTSC), DRM_MODE_TV_MODE_NTSC, &ntsc_mode), > + TV_MODE_TEST("Both, NTSC Default", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_NTSC, > + &ntsc_mode, &pal_mode), > + TV_MODE_TEST("Both, PAL Default", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_PAL, > + &pal_mode, &ntsc_mode), > + TV_MODE_TEST_CMDLINE("Both, NTSC Default, with PAL on command-line", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_NTSC, > + DRM_MODE_TV_MODE_PAL, > + &pal_mode, &ntsc_mode), > + TV_MODE_TEST_CMDLINE("Both, PAL Default, with NTSC on command-line", > + BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL), > + DRM_MODE_TV_MODE_PAL, > + DRM_MODE_TV_MODE_NTSC, > + &ntsc_mode, &pal_mode), > +}; > + > +static void > +drm_connector_helper_tv_get_modes_desc(const struct drm_connector_helper_tv_get_modes_test *t, > + char *desc) > +{ > + sprintf(desc, "%s", t->name); > +} > +KUNIT_ARRAY_PARAM(drm_connector_helper_tv_get_modes, > + drm_connector_helper_tv_get_modes_tests, > + drm_connector_helper_tv_get_modes_desc); > + > +static struct kunit_case drm_test_connector_helper_tv_get_modes_tests[] = { > + KUNIT_CASE_PARAM(drm_test_connector_helper_tv_get_modes_check, > + drm_connector_helper_tv_get_modes_gen_params), > + { } > +}; > + > +static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = { > + .name = "drm_test_connector_helper_tv_get_modes", > + .init = drm_probe_helper_test_init, > + .test_cases = drm_test_connector_helper_tv_get_modes_tests, > +}; > + > +kunit_test_suites( > + &drm_test_connector_helper_tv_get_modes_suite > +); Considering that there is only one suite, you could use the kunit_test_suite macro instead. Moreover, it would be nice to run the checkpatch script on this test, as there are a couple of problems with the code style. Best Regards, - Maíra Canal 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 3D517C433FE for ; Thu, 10 Nov 2022 23:31:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:From:References:Cc:To: Subject:MIME-Version:Date:Message-ID:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=PNnUNEbImecmyTUiU+MJ72JqRj/dI8Xto3pYQcb3GbU=; b=REPFPDRx9IDAHH KZkBJYWV1lurtCcw3UaQsKHE4EoV29S8pI/YfYVwm61GDXRRUSFspX/la3aDM3vem4ir91E65riXV mw0S/F7fM/ZJqZu/sJURqLwU9hSJ5aBwS8leNRw3n+BNZuy76x4xL9KFTCGVt7eMwTzLElJhoIlj7 PLrs8VNV+MiEae0W2WJPjQ0rOjrijMWnAvTvyc5Hl4X+svCRE847CmqWrvBqt+7DcZpdNLS2a6aga Ek0M2q75Rz69QJwPYqqCNWo/80FoN6ApnMLTnA2YWZm86ruv5K4LB0F1q86DEDFygrN0OSDzwUKGx 0WSvS8OA3kjk+bQQFBJg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1otGzv-00BBzA-Hj; Thu, 10 Nov 2022 23:30:15 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1otGzt-00BByH-Rg for linux-arm-kernel@bombadil.infradead.org; Thu, 10 Nov 2022 23:30:14 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:Content-Type: In-Reply-To:From:References:Cc:To:Subject:MIME-Version:Date:Message-ID:Sender :Reply-To:Content-ID:Content-Description; bh=fbdYznhkmsjpxrG0c1tEbJqyVcKnDFYEuHReJvldEUA=; b=LAtcbfJBB2R0BLdbeW/rfw9b7t rqy7ShekOABWp7rNeHg2ErysPG8oAR/T8gnbw1DZFIWt+7w/MWw9qhd0sdVsvOM1h9gpjkjJDiZ5H A+XEEyNGVlofcPSNHJCW9mEfoEgyo5PjSzoh38zjyKEF5jQvw+UxBi5GENwE3nHtnhZ3ayuy3LxWU DNJApJKOy34wL3y1TrAZFx6r5PU09VC+dtTFAyiRelMKCWIbU4W092XbSwVp39UL+BTd7hxYlItaK xaIuFWixmY9yNAKJGDML1euVDe2rgvurluFmUvMChOOTJxiJ7rOlHIkp0POLNmuM99D22xEs0iVPh rQpNUb5A==; Received: from mx0.riseup.net ([198.252.153.6]) by casper.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1otGzu-00CUey-Dw for linux-arm-kernel@lists.infradead.org; Thu, 10 Nov 2022 23:30:17 +0000 Received: from fews2.riseup.net (fews2-pn.riseup.net [10.0.1.84]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "mail.riseup.net", Issuer "R3" (not verified)) by mx0.riseup.net (Postfix) with ESMTPS id 4N7dNX4dZwz9svR; Thu, 10 Nov 2022 23:30:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=riseup.net; s=squak; t=1668123005; bh=fjuKmXRTkwtod6IBPhwlZ1iFXytpH70PXN+uyAnvcJU=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=bXuDGCl8gu5dbDhZxNCxNGU6m3awVbK/pl9drcFPGlU06RjvGwCTgKLdPJ+49/BLg eSp0z/ipegAp4Gs5LVSt/xvRD8PtbyXf9jQHoIJsy9S/uYK9IxCXYXo7L1lle/OaAD OiK5LcDol8WaOacjUFveKpKTPwQu8PeKxOV9ZZko= X-Riseup-User-ID: 6A1C41D0E4C101BEC78841C4EA042529A6EBD75A5D224DDA08027C25E4B89A87 Received: from [127.0.0.1] (localhost [127.0.0.1]) by fews2.riseup.net (Postfix) with ESMTPSA id 4N7dNM3v56z1yQc; Thu, 10 Nov 2022 23:29:55 +0000 (UTC) Message-ID: <4e35ba53-ee3d-31b1-cf70-6d8279e25297@riseup.net> Date: Thu, 10 Nov 2022 20:29:53 -0300 MIME-Version: 1.0 Subject: Re: [PATCH v8 17/24] drm/probe-helper: Provide a TV get_modes helper Content-Language: en-US To: Maxime Ripard , 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 Cc: Dom Cobley , Dave Stevenson , nouveau@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Phil Elwell , Hans de Goede , =?UTF-8?Q?Noralf_Tr=c3=b8nnes?= , Geert Uytterhoeven , Mateusz Kwiatkowski , linux-sunxi@lists.linux.dev, linux-arm-kernel@lists.infradead.org References: <20220728-rpi-analog-tv-properties-v8-0-09ce1466967c@cerno.tech> <20220728-rpi-analog-tv-properties-v8-17-09ce1466967c@cerno.tech> From: =?UTF-8?Q?Ma=c3=adra_Canal?= In-Reply-To: <20220728-rpi-analog-tv-properties-v8-17-09ce1466967c@cerno.tech> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221110_233015_253784_23F3E940 X-CRM114-Status: GOOD ( 27.41 ) 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: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org SGkgTWF4aW1lLAoKT24gMTEvMTAvMjIgMDg6MDcsIE1heGltZSBSaXBhcmQgd3JvdGU6Cj4gRnJv bTogTm9yYWxmIFRyw7hubmVzIDxub3JhbGZAdHJvbm5lcy5vcmc+Cj4gCj4gTW9zdCBvZiB0aGUg VFYgY29ubmVjdG9ycyB3aWxsIG5lZWQgYSBzaW1pbGFyIGdldF9tb2RlcyBpbXBsZW1lbnRhdGlv bgo+IHRoYXQgd2lsbCwgZGVwZW5kaW5nIG9uIHRoZSBkcml2ZXJzJyBjYXBhYmlsaXRpZXMsIHJl Z2lzdGVyIHRoZSA0ODBpIGFuZAo+IDU3NmkgbW9kZXMuCj4gCj4gVGhhdCBpbXBsZW1lbnRhdGlv biB3aWxsIGFsc28gbmVlZCB0byBzZXQgdGhlIHByZWZlcnJlZCBmbGFnIGFuZCBvcmRlcgo+IHRo ZSBtb2RlcyBiYXNlZCBvbiB0aGUgZHJpdmVyIGFuZCB1c2VycyBwcmVmZXJyZW5jZS4KPiAKPiBU aGlzIGlzIGVzcGVjaWFsbHkgaW1wb3J0YW50IHRvIGd1YXJhbnRlZSB0aGF0IGEgdXNlcnNwYWNl IHN0YWNrIHN1Y2ggYXMKPiBYb3JnIGNhbiBzdGFydCBhbmQgcGljayB1cCB0aGUgcHJlZmVycmVk IG1vZGUgd2hpbGUgbWFpbnRhaW5pbmcgYQo+IHdvcmtpbmcgb3V0cHV0Lgo+IAo+IFNpZ25lZC1v ZmYtYnk6IE5vcmFsZiBUcsO4bm5lcyA8bm9yYWxmQHRyb25uZXMub3JnPgo+IFRlc3RlZC1ieTog TWF0ZXVzeiBLd2lhdGtvd3NraSA8a2Z5YXRlaytwdWJsaWNnaXRAZ21haWwuY29tPgo+IFNpZ25l ZC1vZmYtYnk6IE1heGltZSBSaXBhcmQgPG1heGltZUBjZXJuby50ZWNoPgo+IAo+IC0tLQo+IENo YW5nZXMgaW4gdjg6Cj4gLSBSZW1vdmUgdW51c2VkIHR2X21vZGVfc3VwcG9ydCBmdW5jdGlvbgo+ IC0gQWRkIHVuaXQgdGVzdHMKPiAKPiBDaGFuZ2VzIGluIHY3Ogo+IC0gVXNlZCBOb3JhbGYncyBp bXBsZW1lbnRhdGlvbgo+IAo+IENoYW5nZXMgaW4gdjY6Cj4gLSBOZXcgcGF0Y2gKPiAtLS0KPiAg ZHJpdmVycy9ncHUvZHJtL2RybV9wcm9iZV9oZWxwZXIuYyAgICAgICAgICAgIHwgIDgyICsrKysr KysrKysKPiAgZHJpdmVycy9ncHUvZHJtL3Rlc3RzL01ha2VmaWxlICAgICAgICAgICAgICAgIHwg ICAxICsKPiAgZHJpdmVycy9ncHUvZHJtL3Rlc3RzL2RybV9wcm9iZV9oZWxwZXJfdGVzdC5jIHwg MjA5ICsrKysrKysrKysrKysrKysrKysrKysrKysrCj4gIGluY2x1ZGUvZHJtL2RybV9wcm9iZV9o ZWxwZXIuaCAgICAgICAgICAgICAgICB8ICAgMSArCj4gIDQgZmlsZXMgY2hhbmdlZCwgMjkzIGlu c2VydGlvbnMoKykKPiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL3Rlc3RzL2RybV9w cm9iZV9oZWxwZXJfdGVzdC5jIGIvZHJpdmVycy9ncHUvZHJtL3Rlc3RzL2RybV9wcm9iZV9oZWxw ZXJfdGVzdC5jCj4gbmV3IGZpbGUgbW9kZSAxMDA2NDQKPiBpbmRleCAwMDAwMDAwMDAwMDAuLjRm Mjk1YjM5Zjc0Ngo+IC0tLSAvZGV2L251bGwKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vdGVzdHMv ZHJtX3Byb2JlX2hlbHBlcl90ZXN0LmMKPiBAQCAtMCwwICsxLDIwOSBAQAo+ICsvLyBTUERYLUxp Y2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAo+ICsvKgo+ICsgKiBLdW5pdCB0ZXN0IGZvciBkcm1f cHJvYmVfaGVscGVyIGZ1bmN0aW9ucwo+ICsgKi8KPiArCj4gKyNpbmNsdWRlIDxkcm0vZHJtX2F0 b21pY19zdGF0ZV9oZWxwZXIuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1fY29ubmVjdG9yLmg+Cj4g KyNpbmNsdWRlIDxkcm0vZHJtX2RldmljZS5oPgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9kcnYuaD4K PiArI2luY2x1ZGUgPGRybS9kcm1fbW9kZS5oPgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9tb2Rlcy5o Pgo+ICsjaW5jbHVkZSA8ZHJtL2RybV9tb2Rlc2V0X2hlbHBlcl92dGFibGVzLmg+Cj4gKyNpbmNs dWRlIDxkcm0vZHJtX3Byb2JlX2hlbHBlci5oPgo+ICsKPiArI2luY2x1ZGUgPGt1bml0L3Rlc3Qu aD4KPiArCj4gKyNpbmNsdWRlICJkcm1fa3VuaXRfaGVscGVycy5oIgo+ICsKPiArc3RhdGljIGNv bnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlIG50c2NfbW9kZSA9IHsKPiArCURSTV9NT0RFKCI3 MjB4NDgwaSIsIDAsIDEzNTAwLAo+ICsJCSA3MjAsIDczNiwgODAwLCA4NTgsIDAsCj4gKwkJIDQ4 MCwgNDg2LCA0OTIsIDUyNSwgMCwKPiArCQkgRFJNX01PREVfRkxBR19OSFNZTkMgfCBEUk1fTU9E RV9GTEFHX05WU1lOQyB8IERSTV9NT0RFX0ZMQUdfSU5URVJMQUNFKQo+ICt9Owo+ICsKPiArc3Rh dGljIGNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlIHBhbF9tb2RlID0gewo+ICsJRFJNX01P REUoIjcyMHg1NzZpIiwgMCwgMTM1MDAsCj4gKwkJIDcyMCwgNzMyLCA3OTYsIDg2NCwgMCwKPiAr CQkgNTc2LCA1ODEsIDU4NywgNjI1LCAwLAo+ICsJCSBEUk1fTU9ERV9GTEFHX05IU1lOQyB8IERS TV9NT0RFX0ZMQUdfTlZTWU5DIHwgRFJNX01PREVfRkxBR19JTlRFUkxBQ0UpCj4gK307Cj4gKwo+ ICtzdHJ1Y3QgZHJtX3Byb2JlX2hlbHBlcl90ZXN0X3ByaXYgewo+ICsJc3RydWN0IGRybV9kZXZp Y2UgKmRybTsKPiArCXN0cnVjdCBkcm1fY29ubmVjdG9yIGNvbm5lY3RvcjsKPiArfTsKPiArCj4g K3N0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9oZWxwZXJfZnVuY3MgZHJtX3Byb2Jl X2hlbHBlcl9jb25uZWN0b3JfaGVscGVyX2Z1bmNzID0gewo+ICt9Owo+ICsKPiArc3RhdGljIGNv bnN0IHN0cnVjdCBkcm1fY29ubmVjdG9yX2Z1bmNzIGRybV9wcm9iZV9oZWxwZXJfY29ubmVjdG9y X2Z1bmNzID0gewo+ICsJLmF0b21pY19kZXN0cm95X3N0YXRlCT0gZHJtX2F0b21pY19oZWxwZXJf Y29ubmVjdG9yX2Rlc3Ryb3lfc3RhdGUsCj4gKwkuYXRvbWljX2R1cGxpY2F0ZV9zdGF0ZQk9IGRy bV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9kdXBsaWNhdGVfc3RhdGUsCj4gKwkucmVzZXQJCQk9 IGRybV9hdG9taWNfaGVscGVyX2Nvbm5lY3Rvcl9yZXNldCwKPiArfTsKPiArCj4gK3N0YXRpYyBp bnQgZHJtX3Byb2JlX2hlbHBlcl90ZXN0X2luaXQoc3RydWN0IGt1bml0ICp0ZXN0KQo+ICt7Cj4g KwlzdHJ1Y3QgZHJtX3Byb2JlX2hlbHBlcl90ZXN0X3ByaXYgKnByaXY7Cj4gKwlzdHJ1Y3QgZHJt X2Nvbm5lY3RvciAqY29ubmVjdG9yOwo+ICsJaW50IHJldDsKPiArCj4gKwlwcml2ID0ga3VuaXRf a3phbGxvYyh0ZXN0LCBzaXplb2YoKnByaXYpLCBHRlBfS0VSTkVMKTsKPiArCUtVTklUX0FTU0VS VF9OT1RfTlVMTCh0ZXN0LCBwcml2KTsKPiArCXRlc3QtPnByaXYgPSBwcml2Owo+ICsKPiArCXBy aXYtPmRybSA9IGRybV9rdW5pdF9kZXZpY2VfaW5pdCh0ZXN0LCBEUklWRVJfTU9ERVNFVCB8IERS SVZFUl9BVE9NSUMsCj4gKwkJCQkJICAiZHJtLXByb2JlLWhlbHBlci10ZXN0Iik7Cj4gKwlLVU5J VF9BU1NFUlRfTk9UX0VSUl9PUl9OVUxMKHRlc3QsIHByaXYtPmRybSk7Cj4gKwo+ICsJY29ubmVj dG9yID0gJnByaXYtPmNvbm5lY3RvcjsKPiArCXJldCA9IGRybW1fY29ubmVjdG9yX2luaXQocHJp di0+ZHJtLCBjb25uZWN0b3IsCj4gKwkJCQkgICZkcm1fcHJvYmVfaGVscGVyX2Nvbm5lY3Rvcl9m dW5jcywKPiArCQkJCSAgRFJNX01PREVfQ09OTkVDVE9SX1Vua25vd24sCj4gKwkJCQkgIE5VTEwp Owo+ICsJS1VOSVRfQVNTRVJUX0VRKHRlc3QsIHJldCwgMCk7Cj4gKwo+ICsJZHJtX2Nvbm5lY3Rv cl9oZWxwZXJfYWRkKGNvbm5lY3RvciwgJmRybV9wcm9iZV9oZWxwZXJfY29ubmVjdG9yX2hlbHBl cl9mdW5jcyk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0cnVjdCBkcm1fY29ubmVj dG9yX2hlbHBlcl90dl9nZXRfbW9kZXNfdGVzdCB7Cj4gKwljb25zdCBjaGFyICpuYW1lOwo+ICsJ dW5zaWduZWQgaW50IHN1cHBvcnRlZF90dl9tb2RlczsKPiArCWVudW0gZHJtX2Nvbm5lY3Rvcl90 dl9tb2RlIGRlZmF1bHRfbW9kZTsKPiArCWJvb2wgY21kbGluZTsKPiArCWVudW0gZHJtX2Nvbm5l Y3Rvcl90dl9tb2RlIGNtZGxpbmVfbW9kZTsKPiArCWNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9t b2RlICoqZXhwZWN0ZWRfbW9kZXM7Cj4gKwl1bnNpZ25lZCBpbnQgbnVtX2V4cGVjdGVkX21vZGVz Owo+ICt9Owo+ICsKPiArI2RlZmluZSBfVFZfTU9ERV9URVNUKF9uYW1lLCBfc3VwcG9ydGVkLCBf ZGVmYXVsdCwgX2NtZGxpbmUsIF9jbWRsaW5lX21vZGUsIC4uLikgCQkJXAo+ICsJewkJCQkJCQkJ CQkJCVwKPiArCQkubmFtZSA9IF9uYW1lLAkJCQkJCQkJCQlcCj4gKwkJLnN1cHBvcnRlZF90dl9t b2RlcyA9IF9zdXBwb3J0ZWQsCQkJCQkJCVwKPiArCQkuZGVmYXVsdF9tb2RlID0gX2RlZmF1bHQs CQkJCQkJCQlcCj4gKwkJLmNtZGxpbmUgPSBfY21kbGluZSwJCQkJCQkJCQlcCj4gKwkJLmNtZGxp bmVfbW9kZSA9IF9jbWRsaW5lX21vZGUsCQkJCQkJCQlcCj4gKwkJLmV4cGVjdGVkX21vZGVzID0g KGNvbnN0IHN0cnVjdCBkcm1fZGlzcGxheV9tb2RlKltdKSB7IF9fVkFfQVJHU19fIH0sIAkJCVwK PiArCQkubnVtX2V4cGVjdGVkX21vZGVzID0gc2l6ZW9mKChjb25zdCBzdHJ1Y3QgZHJtX2Rpc3Bs YXlfbW9kZSpbXSkgeyBfX1ZBX0FSR1NfXyB9KSAvCVwKPiArCQkJCSAgICAgIChzaXplb2YoY29u c3Qgc3RydWN0IGRybV9kaXNwbGF5X21vZGUqKSksCQkJCVwKPiArCX0KPiArCj4gKyNkZWZpbmUg VFZfTU9ERV9URVNUKF9uYW1lLCBfc3VwcG9ydGVkLCBfZGVmYXVsdCwgLi4uKQkJCVwKPiArCV9U Vl9NT0RFX1RFU1QoX25hbWUsIF9zdXBwb3J0ZWQsIF9kZWZhdWx0LCBmYWxzZSwgMCwgX19WQV9B UkdTX18pCj4gKwo+ICsjZGVmaW5lIFRWX01PREVfVEVTVF9DTURMSU5FKF9uYW1lLCBfc3VwcG9y dGVkLCBfZGVmYXVsdCwgX2NtZGxpbmUsIC4uLikgXAo+ICsJX1RWX01PREVfVEVTVChfbmFtZSwg X3N1cHBvcnRlZCwgX2RlZmF1bHQsIHRydWUsIF9jbWRsaW5lLCBfX1ZBX0FSR1NfXykKPiArCj4g K3N0YXRpYyB2b2lkCj4gK2RybV90ZXN0X2Nvbm5lY3Rvcl9oZWxwZXJfdHZfZ2V0X21vZGVzX2No ZWNrKHN0cnVjdCBrdW5pdCAqdGVzdCkKPiArewo+ICsJY29uc3Qgc3RydWN0IGRybV9jb25uZWN0 b3JfaGVscGVyX3R2X2dldF9tb2Rlc190ZXN0ICpwYXJhbXMgPSB0ZXN0LT5wYXJhbV92YWx1ZTsK PiArCXN0cnVjdCBkcm1fcHJvYmVfaGVscGVyX3Rlc3RfcHJpdiAqcHJpdiA9IHRlc3QtPnByaXY7 Cj4gKwlzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubmVjdG9yID0gJnByaXYtPmNvbm5lY3RvcjsK PiArCXN0cnVjdCBkcm1fY21kbGluZV9tb2RlICpjbWRsaW5lID0gJmNvbm5lY3Rvci0+Y21kbGlu ZV9tb2RlOwo+ICsJc3RydWN0IGRybV9kaXNwbGF5X21vZGUgKm1vZGU7Cj4gKwljb25zdCBzdHJ1 Y3QgZHJtX2Rpc3BsYXlfbW9kZSAqZXhwZWN0ZWQ7Cj4gKwlzaXplX3QgbGVuOwo+ICsJaW50IHJl dDsKPiArCj4gKwlpZiAocGFyYW1zLT5jbWRsaW5lKSB7Cj4gKwkJY21kbGluZS0+dHZfbW9kZV9z cGVjaWZpZWQgPSB0cnVlOwo+ICsJCWNtZGxpbmUtPnR2X21vZGUgPSBwYXJhbXMtPmNtZGxpbmVf bW9kZTsKPiArCX0KPiArCj4gKwlyZXQgPSBkcm1fbW9kZV9jcmVhdGVfdHZfcHJvcGVydGllcyhw cml2LT5kcm0sIHBhcmFtcy0+c3VwcG9ydGVkX3R2X21vZGVzKTsKPiArCUtVTklUX0FTU0VSVF9F USh0ZXN0LCByZXQsIDApOwo+ICsKPiArCWRybV9vYmplY3RfYXR0YWNoX3Byb3BlcnR5KCZjb25u ZWN0b3ItPmJhc2UsCj4gKwkJCQkgICBwcml2LT5kcm0tPm1vZGVfY29uZmlnLnR2X21vZGVfcHJv cGVydHksCj4gKwkJIAkJICAgcGFyYW1zLT5kZWZhdWx0X21vZGUpOwo+ICsKPiArCW11dGV4X2xv Y2soJnByaXYtPmRybS0+bW9kZV9jb25maWcubXV0ZXgpOwo+ICsKPiArCXJldCA9IGRybV9jb25u ZWN0b3JfaGVscGVyX3R2X2dldF9tb2Rlcyhjb25uZWN0b3IpOwo+ICsJS1VOSVRfRVhQRUNUX0VR KHRlc3QsIHJldCwgcGFyYW1zLT5udW1fZXhwZWN0ZWRfbW9kZXMpOwo+ICsKPiArCWxpc3RfZm9y X2VhY2hfZW50cnkobW9kZSwgJmNvbm5lY3Rvci0+cHJvYmVkX21vZGVzLCBoZWFkKQo+ICsJCWxl bisrOwo+ICsJS1VOSVRfRVhQRUNUX0VRKHRlc3QsIGxlbiwgcGFyYW1zLT5udW1fZXhwZWN0ZWRf bW9kZXMpOwo+ICsKPiArCWlmIChwYXJhbXMtPm51bV9leHBlY3RlZF9tb2RlcyA+PSAxKSB7Cj4g KwkJbW9kZSA9IGxpc3RfZmlyc3RfZW50cnlfb3JfbnVsbCgmY29ubmVjdG9yLT5wcm9iZWRfbW9k ZXMsCj4gKwkJCQkJCXN0cnVjdCBkcm1fZGlzcGxheV9tb2RlLCBoZWFkKTsKPiArCQlLVU5JVF9B U1NFUlRfTk9UX0VSUl9PUl9OVUxMKHRlc3QsIG1vZGUpOwo+ICsKPiArCQlleHBlY3RlZCA9IHBh cmFtcy0+ZXhwZWN0ZWRfbW9kZXNbMF07Cj4gKwkJS1VOSVRfQVNTRVJUX05PVF9FUlJfT1JfTlVM TCh0ZXN0LCBleHBlY3RlZCk7Cj4gKwo+ICsJCUtVTklUX0VYUEVDVF9UUlVFKHRlc3QsIGRybV9t b2RlX2VxdWFsKG1vZGUsIGV4cGVjdGVkKSk7Cj4gKwkJS1VOSVRfRVhQRUNUX1RSVUUodGVzdCwg bW9kZS0+dHlwZSAmIERSTV9NT0RFX1RZUEVfUFJFRkVSUkVEKTsKPiArCX0KPiArCj4gKwlpZiAo cGFyYW1zLT5udW1fZXhwZWN0ZWRfbW9kZXMgPj0gMikgewo+ICsJCW1vZGUgPSBsaXN0X25leHRf ZW50cnkobW9kZSwgaGVhZCk7Cj4gKwkJS1VOSVRfQVNTRVJUX05PVF9FUlJfT1JfTlVMTCh0ZXN0 LCBtb2RlKTsKPiArCj4gKwkJZXhwZWN0ZWQgPSBwYXJhbXMtPmV4cGVjdGVkX21vZGVzWzFdOwo+ ICsJCUtVTklUX0FTU0VSVF9OT1RfRVJSX09SX05VTEwodGVzdCwgZXhwZWN0ZWQpOwo+ICsKPiAr CQlLVU5JVF9FWFBFQ1RfVFJVRSh0ZXN0LCBkcm1fbW9kZV9lcXVhbChtb2RlLCBleHBlY3RlZCkp Owo+ICsJCUtVTklUX0VYUEVDVF9GQUxTRSh0ZXN0LCBtb2RlLT50eXBlICYgRFJNX01PREVfVFlQ RV9QUkVGRVJSRUQpOwo+ICsJfQo+ICsKPiArCW11dGV4X3VubG9jaygmcHJpdi0+ZHJtLT5tb2Rl X2NvbmZpZy5tdXRleCk7Cj4gK30KPiArCj4gK3N0YXRpYyBjb25zdAo+ICtzdHJ1Y3QgZHJtX2Nv bm5lY3Rvcl9oZWxwZXJfdHZfZ2V0X21vZGVzX3Rlc3QgZHJtX2Nvbm5lY3Rvcl9oZWxwZXJfdHZf Z2V0X21vZGVzX3Rlc3RzW10gPSB7Cj4gKwl7IC5uYW1lID0gIk5vbmUiIH0sCj4gKwlUVl9NT0RF X1RFU1QoIlBBTCIsIEJJVChEUk1fTU9ERV9UVl9NT0RFX1BBTCksIERSTV9NT0RFX1RWX01PREVf UEFMLCAmcGFsX21vZGUpLAo+ICsJVFZfTU9ERV9URVNUKCJOVFNDIiwgQklUKERSTV9NT0RFX1RW X01PREVfTlRTQyksIERSTV9NT0RFX1RWX01PREVfTlRTQywgJm50c2NfbW9kZSksCj4gKwlUVl9N T0RFX1RFU1QoIkJvdGgsIE5UU0MgRGVmYXVsdCIsCj4gKwkJICAgICBCSVQoRFJNX01PREVfVFZf TU9ERV9OVFNDKSB8IEJJVChEUk1fTU9ERV9UVl9NT0RFX1BBTCksCj4gKwkJICAgICBEUk1fTU9E RV9UVl9NT0RFX05UU0MsCj4gKwkJICAgICAmbnRzY19tb2RlLCAmcGFsX21vZGUpLAo+ICsJVFZf TU9ERV9URVNUKCJCb3RoLCBQQUwgRGVmYXVsdCIsCj4gKwkJICAgICBCSVQoRFJNX01PREVfVFZf TU9ERV9OVFNDKSB8IEJJVChEUk1fTU9ERV9UVl9NT0RFX1BBTCksCj4gKwkJICAgICBEUk1fTU9E RV9UVl9NT0RFX1BBTCwKPiArCQkgICAgICZwYWxfbW9kZSwgJm50c2NfbW9kZSksCj4gKwlUVl9N T0RFX1RFU1RfQ01ETElORSgiQm90aCwgTlRTQyBEZWZhdWx0LCB3aXRoIFBBTCBvbiBjb21tYW5k LWxpbmUiLAo+ICsJCQkgICAgIEJJVChEUk1fTU9ERV9UVl9NT0RFX05UU0MpIHwgQklUKERSTV9N T0RFX1RWX01PREVfUEFMKSwKPiArCQkJICAgICBEUk1fTU9ERV9UVl9NT0RFX05UU0MsCj4gKwkJ CSAgICAgRFJNX01PREVfVFZfTU9ERV9QQUwsCj4gKwkJCSAgICAgJnBhbF9tb2RlLCAmbnRzY19t b2RlKSwKPiArCVRWX01PREVfVEVTVF9DTURMSU5FKCJCb3RoLCBQQUwgRGVmYXVsdCwgd2l0aCBO VFNDIG9uIGNvbW1hbmQtbGluZSIsCj4gKwkJCSAgICAgQklUKERSTV9NT0RFX1RWX01PREVfTlRT QykgfCBCSVQoRFJNX01PREVfVFZfTU9ERV9QQUwpLAo+ICsJCQkgICAgIERSTV9NT0RFX1RWX01P REVfUEFMLAo+ICsJCQkgICAgIERSTV9NT0RFX1RWX01PREVfTlRTQywKPiArCQkJICAgICAmbnRz Y19tb2RlLCAmcGFsX21vZGUpLAo+ICt9Owo+ICsKPiArc3RhdGljIHZvaWQKPiArZHJtX2Nvbm5l Y3Rvcl9oZWxwZXJfdHZfZ2V0X21vZGVzX2Rlc2MoY29uc3Qgc3RydWN0IGRybV9jb25uZWN0b3Jf aGVscGVyX3R2X2dldF9tb2Rlc190ZXN0ICp0LAo+ICsJCQkJICAgICAgIGNoYXIgKmRlc2MpCj4g K3sKPiArCXNwcmludGYoZGVzYywgIiVzIiwgdC0+bmFtZSk7Cj4gK30KPiArS1VOSVRfQVJSQVlf UEFSQU0oZHJtX2Nvbm5lY3Rvcl9oZWxwZXJfdHZfZ2V0X21vZGVzLAo+ICsJCSAgZHJtX2Nvbm5l Y3Rvcl9oZWxwZXJfdHZfZ2V0X21vZGVzX3Rlc3RzLAo+ICsJCSAgZHJtX2Nvbm5lY3Rvcl9oZWxw ZXJfdHZfZ2V0X21vZGVzX2Rlc2MpOwo+ICsKPiArc3RhdGljIHN0cnVjdCBrdW5pdF9jYXNlIGRy bV90ZXN0X2Nvbm5lY3Rvcl9oZWxwZXJfdHZfZ2V0X21vZGVzX3Rlc3RzW10gPSB7Cj4gKwlLVU5J VF9DQVNFX1BBUkFNKGRybV90ZXN0X2Nvbm5lY3Rvcl9oZWxwZXJfdHZfZ2V0X21vZGVzX2NoZWNr LAo+ICsJCQkgZHJtX2Nvbm5lY3Rvcl9oZWxwZXJfdHZfZ2V0X21vZGVzX2dlbl9wYXJhbXMpLAo+ ICsJeyB9Cj4gK307Cj4gKwo+ICtzdGF0aWMgc3RydWN0IGt1bml0X3N1aXRlIGRybV90ZXN0X2Nv bm5lY3Rvcl9oZWxwZXJfdHZfZ2V0X21vZGVzX3N1aXRlID0gewo+ICsJLm5hbWUgPSAiZHJtX3Rl c3RfY29ubmVjdG9yX2hlbHBlcl90dl9nZXRfbW9kZXMiLAo+ICsJLmluaXQgPSBkcm1fcHJvYmVf aGVscGVyX3Rlc3RfaW5pdCwKPiArCS50ZXN0X2Nhc2VzID0gZHJtX3Rlc3RfY29ubmVjdG9yX2hl bHBlcl90dl9nZXRfbW9kZXNfdGVzdHMsCj4gK307Cj4gKwo+ICtrdW5pdF90ZXN0X3N1aXRlcygK PiArCSZkcm1fdGVzdF9jb25uZWN0b3JfaGVscGVyX3R2X2dldF9tb2Rlc19zdWl0ZQo+ICspOwoK Q29uc2lkZXJpbmcgdGhhdCB0aGVyZSBpcyBvbmx5IG9uZSBzdWl0ZSwgeW91IGNvdWxkIHVzZSB0 aGUKa3VuaXRfdGVzdF9zdWl0ZSBtYWNybyBpbnN0ZWFkLgoKTW9yZW92ZXIsIGl0IHdvdWxkIGJl IG5pY2UgdG8gcnVuIHRoZSBjaGVja3BhdGNoIHNjcmlwdCBvbiB0aGlzIHRlc3QsIGFzCnRoZXJl IGFyZSBhIGNvdXBsZSBvZiBwcm9ibGVtcyB3aXRoIHRoZSBjb2RlIHN0eWxlLgoKQmVzdCBSZWdh cmRzLAotIE1hw61yYSBDYW5hbAoKX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX18KbGludXgtYXJtLWtlcm5lbCBtYWlsaW5nIGxpc3QKbGludXgtYXJtLWtlcm5l bEBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3JnL21haWxtYW4v bGlzdGluZm8vbGludXgtYXJtLWtlcm5lbAo=