162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Kunit test for drm_modes functions 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <drm/drm_drv.h> 762306a36Sopenharmony_ci#include <drm/drm_kunit_helpers.h> 862306a36Sopenharmony_ci#include <drm/drm_modes.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <kunit/test.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/units.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_cistruct drm_test_modes_priv { 1562306a36Sopenharmony_ci struct drm_device *drm; 1662306a36Sopenharmony_ci struct device *dev; 1762306a36Sopenharmony_ci}; 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_cistatic int drm_test_modes_init(struct kunit *test) 2062306a36Sopenharmony_ci{ 2162306a36Sopenharmony_ci struct drm_test_modes_priv *priv; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); 2462306a36Sopenharmony_ci KUNIT_ASSERT_NOT_NULL(test, priv); 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci priv->dev = drm_kunit_helper_alloc_device(test); 2762306a36Sopenharmony_ci KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev); 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev, 3062306a36Sopenharmony_ci sizeof(*priv->drm), 0, 3162306a36Sopenharmony_ci DRIVER_MODESET); 3262306a36Sopenharmony_ci KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci test->priv = priv; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci return 0; 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic void drm_test_modes_analog_tv_ntsc_480i(struct kunit *test) 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci struct drm_test_modes_priv *priv = test->priv; 4262306a36Sopenharmony_ci struct drm_display_mode *mode; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci mode = drm_analog_tv_mode(priv->drm, 4562306a36Sopenharmony_ci DRM_MODE_TV_MODE_NTSC, 4662306a36Sopenharmony_ci 13500 * HZ_PER_KHZ, 720, 480, 4762306a36Sopenharmony_ci true); 4862306a36Sopenharmony_ci KUNIT_ASSERT_NOT_NULL(test, mode); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 60); 5162306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, mode->hdisplay, 720); 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /* BT.601 defines hsync_start at 736 for 480i */ 5462306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, mode->hsync_start, 736); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci /* 5762306a36Sopenharmony_ci * The NTSC standard expects a line to take 63.556us. With a 5862306a36Sopenharmony_ci * pixel clock of 13.5 MHz, a pixel takes around 74ns, so we 5962306a36Sopenharmony_ci * need to have 63556ns / 74ns = 858. 6062306a36Sopenharmony_ci * 6162306a36Sopenharmony_ci * This is also mandated by BT.601. 6262306a36Sopenharmony_ci */ 6362306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, mode->htotal, 858); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, mode->vdisplay, 480); 6662306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, mode->vtotal, 525); 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic void drm_test_modes_analog_tv_ntsc_480i_inlined(struct kunit *test) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci struct drm_test_modes_priv *priv = test->priv; 7262306a36Sopenharmony_ci struct drm_display_mode *expected, *mode; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci expected = drm_analog_tv_mode(priv->drm, 7562306a36Sopenharmony_ci DRM_MODE_TV_MODE_NTSC, 7662306a36Sopenharmony_ci 13500 * HZ_PER_KHZ, 720, 480, 7762306a36Sopenharmony_ci true); 7862306a36Sopenharmony_ci KUNIT_ASSERT_NOT_NULL(test, expected); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci mode = drm_mode_analog_ntsc_480i(priv->drm); 8162306a36Sopenharmony_ci KUNIT_ASSERT_NOT_NULL(test, mode); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode)); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistatic void drm_test_modes_analog_tv_pal_576i(struct kunit *test) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci struct drm_test_modes_priv *priv = test->priv; 8962306a36Sopenharmony_ci struct drm_display_mode *mode; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci mode = drm_analog_tv_mode(priv->drm, 9262306a36Sopenharmony_ci DRM_MODE_TV_MODE_PAL, 9362306a36Sopenharmony_ci 13500 * HZ_PER_KHZ, 720, 576, 9462306a36Sopenharmony_ci true); 9562306a36Sopenharmony_ci KUNIT_ASSERT_NOT_NULL(test, mode); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 50); 9862306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, mode->hdisplay, 720); 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci /* BT.601 defines hsync_start at 732 for 576i */ 10162306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, mode->hsync_start, 732); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci /* 10462306a36Sopenharmony_ci * The PAL standard expects a line to take 64us. With a pixel 10562306a36Sopenharmony_ci * clock of 13.5 MHz, a pixel takes around 74ns, so we need to 10662306a36Sopenharmony_ci * have 64000ns / 74ns = 864. 10762306a36Sopenharmony_ci * 10862306a36Sopenharmony_ci * This is also mandated by BT.601. 10962306a36Sopenharmony_ci */ 11062306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, mode->htotal, 864); 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, mode->vdisplay, 576); 11362306a36Sopenharmony_ci KUNIT_EXPECT_EQ(test, mode->vtotal, 625); 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_cistatic void drm_test_modes_analog_tv_pal_576i_inlined(struct kunit *test) 11762306a36Sopenharmony_ci{ 11862306a36Sopenharmony_ci struct drm_test_modes_priv *priv = test->priv; 11962306a36Sopenharmony_ci struct drm_display_mode *expected, *mode; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci expected = drm_analog_tv_mode(priv->drm, 12262306a36Sopenharmony_ci DRM_MODE_TV_MODE_PAL, 12362306a36Sopenharmony_ci 13500 * HZ_PER_KHZ, 720, 576, 12462306a36Sopenharmony_ci true); 12562306a36Sopenharmony_ci KUNIT_ASSERT_NOT_NULL(test, expected); 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci mode = drm_mode_analog_pal_576i(priv->drm); 12862306a36Sopenharmony_ci KUNIT_ASSERT_NOT_NULL(test, mode); 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode)); 13162306a36Sopenharmony_ci} 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_cistatic struct kunit_case drm_modes_analog_tv_tests[] = { 13462306a36Sopenharmony_ci KUNIT_CASE(drm_test_modes_analog_tv_ntsc_480i), 13562306a36Sopenharmony_ci KUNIT_CASE(drm_test_modes_analog_tv_ntsc_480i_inlined), 13662306a36Sopenharmony_ci KUNIT_CASE(drm_test_modes_analog_tv_pal_576i), 13762306a36Sopenharmony_ci KUNIT_CASE(drm_test_modes_analog_tv_pal_576i_inlined), 13862306a36Sopenharmony_ci { } 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic struct kunit_suite drm_modes_analog_tv_test_suite = { 14262306a36Sopenharmony_ci .name = "drm_modes_analog_tv", 14362306a36Sopenharmony_ci .init = drm_test_modes_init, 14462306a36Sopenharmony_ci .test_cases = drm_modes_analog_tv_tests, 14562306a36Sopenharmony_ci}; 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_cikunit_test_suite(drm_modes_analog_tv_test_suite); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ciMODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); 15062306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 151