| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Kunit test for drm_modes functions |
| */ |
| |
| #include <drm/drm_drv.h> |
| #include <drm/drm_kunit_helpers.h> |
| #include <drm/drm_modes.h> |
| |
| #include <kunit/test.h> |
| |
| #include <linux/units.h> |
| |
| struct drm_test_modes_priv { |
| struct drm_device *drm; |
| struct device *dev; |
| }; |
| |
| static int drm_test_modes_init(struct kunit *test) |
| { |
| struct drm_test_modes_priv *priv; |
| |
| priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); |
| KUNIT_ASSERT_NOT_NULL(test, priv); |
| |
| priv->dev = drm_kunit_helper_alloc_device(test); |
| KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev); |
| |
| priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev, |
| sizeof(*priv->drm), 0, |
| DRIVER_MODESET); |
| KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); |
| |
| test->priv = priv; |
| |
| return 0; |
| } |
| |
| static void drm_test_modes_analog_tv_ntsc_480i(struct kunit *test) |
| { |
| struct drm_test_modes_priv *priv = test->priv; |
| struct drm_display_mode *mode; |
| |
| mode = drm_analog_tv_mode(priv->drm, |
| DRM_MODE_TV_MODE_NTSC, |
| 13500 * HZ_PER_KHZ, 720, 480, |
| true); |
| KUNIT_ASSERT_NOT_NULL(test, mode); |
| |
| KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 60); |
| KUNIT_EXPECT_EQ(test, mode->hdisplay, 720); |
| |
| /* BT.601 defines hsync_start at 736 for 480i */ |
| KUNIT_EXPECT_EQ(test, mode->hsync_start, 736); |
| |
| /* |
| * The NTSC standard expects a line to take 63.556us. With a |
| * pixel clock of 13.5 MHz, a pixel takes around 74ns, so we |
| * need to have 63556ns / 74ns = 858. |
| * |
| * This is also mandated by BT.601. |
| */ |
| KUNIT_EXPECT_EQ(test, mode->htotal, 858); |
| |
| KUNIT_EXPECT_EQ(test, mode->vdisplay, 480); |
| KUNIT_EXPECT_EQ(test, mode->vtotal, 525); |
| } |
| |
| static void drm_test_modes_analog_tv_ntsc_480i_inlined(struct kunit *test) |
| { |
| struct drm_test_modes_priv *priv = test->priv; |
| struct drm_display_mode *expected, *mode; |
| |
| expected = drm_analog_tv_mode(priv->drm, |
| DRM_MODE_TV_MODE_NTSC, |
| 13500 * HZ_PER_KHZ, 720, 480, |
| true); |
| KUNIT_ASSERT_NOT_NULL(test, expected); |
| |
| mode = drm_mode_analog_ntsc_480i(priv->drm); |
| KUNIT_ASSERT_NOT_NULL(test, mode); |
| |
| KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode)); |
| } |
| |
| static void drm_test_modes_analog_tv_pal_576i(struct kunit *test) |
| { |
| struct drm_test_modes_priv *priv = test->priv; |
| struct drm_display_mode *mode; |
| |
| mode = drm_analog_tv_mode(priv->drm, |
| DRM_MODE_TV_MODE_PAL, |
| 13500 * HZ_PER_KHZ, 720, 576, |
| true); |
| KUNIT_ASSERT_NOT_NULL(test, mode); |
| |
| KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 50); |
| KUNIT_EXPECT_EQ(test, mode->hdisplay, 720); |
| |
| /* BT.601 defines hsync_start at 732 for 576i */ |
| KUNIT_EXPECT_EQ(test, mode->hsync_start, 732); |
| |
| /* |
| * The PAL standard expects a line to take 64us. With a pixel |
| * clock of 13.5 MHz, a pixel takes around 74ns, so we need to |
| * have 64000ns / 74ns = 864. |
| * |
| * This is also mandated by BT.601. |
| */ |
| KUNIT_EXPECT_EQ(test, mode->htotal, 864); |
| |
| KUNIT_EXPECT_EQ(test, mode->vdisplay, 576); |
| KUNIT_EXPECT_EQ(test, mode->vtotal, 625); |
| } |
| |
| static void drm_test_modes_analog_tv_pal_576i_inlined(struct kunit *test) |
| { |
| struct drm_test_modes_priv *priv = test->priv; |
| struct drm_display_mode *expected, *mode; |
| |
| expected = drm_analog_tv_mode(priv->drm, |
| DRM_MODE_TV_MODE_PAL, |
| 13500 * HZ_PER_KHZ, 720, 576, |
| true); |
| KUNIT_ASSERT_NOT_NULL(test, expected); |
| |
| mode = drm_mode_analog_pal_576i(priv->drm); |
| KUNIT_ASSERT_NOT_NULL(test, mode); |
| |
| KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode)); |
| } |
| |
| static struct kunit_case drm_modes_analog_tv_tests[] = { |
| KUNIT_CASE(drm_test_modes_analog_tv_ntsc_480i), |
| KUNIT_CASE(drm_test_modes_analog_tv_ntsc_480i_inlined), |
| KUNIT_CASE(drm_test_modes_analog_tv_pal_576i), |
| KUNIT_CASE(drm_test_modes_analog_tv_pal_576i_inlined), |
| { } |
| }; |
| |
| static struct kunit_suite drm_modes_analog_tv_test_suite = { |
| .name = "drm_modes_analog_tv", |
| .init = drm_test_modes_init, |
| .test_cases = drm_modes_analog_tv_tests, |
| }; |
| |
| kunit_test_suite(drm_modes_analog_tv_test_suite); |
| |
| MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); |
| MODULE_LICENSE("GPL"); |