1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Kunit test for drm_modes functions |
4 | */ |
5 | |
6 | #include <drm/drm_drv.h> |
7 | #include <drm/drm_kunit_helpers.h> |
8 | #include <drm/drm_modes.h> |
9 | |
10 | #include <kunit/test.h> |
11 | |
12 | #include <linux/units.h> |
13 | |
14 | struct drm_test_modes_priv { |
15 | struct drm_device *drm; |
16 | struct device *dev; |
17 | }; |
18 | |
19 | static int drm_test_modes_init(struct kunit *test) |
20 | { |
21 | struct drm_test_modes_priv *priv; |
22 | |
23 | priv = kunit_kzalloc(test, size: sizeof(*priv), GFP_KERNEL); |
24 | KUNIT_ASSERT_NOT_NULL(test, priv); |
25 | |
26 | priv->dev = drm_kunit_helper_alloc_device(test); |
27 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev); |
28 | |
29 | priv->drm = __drm_kunit_helper_alloc_drm_device(test, dev: priv->dev, |
30 | size: sizeof(*priv->drm), offset: 0, |
31 | features: DRIVER_MODESET); |
32 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm); |
33 | |
34 | test->priv = priv; |
35 | |
36 | return 0; |
37 | } |
38 | |
39 | static void drm_test_modes_analog_tv_ntsc_480i(struct kunit *test) |
40 | { |
41 | struct drm_test_modes_priv *priv = test->priv; |
42 | struct drm_display_mode *mode; |
43 | |
44 | mode = drm_analog_tv_mode(dev: priv->drm, |
45 | mode: DRM_MODE_TV_MODE_NTSC, |
46 | pixel_clock_hz: 13500 * HZ_PER_KHZ, hdisplay: 720, vdisplay: 480, |
47 | interlace: true); |
48 | KUNIT_ASSERT_NOT_NULL(test, mode); |
49 | |
50 | KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 60); |
51 | KUNIT_EXPECT_EQ(test, mode->hdisplay, 720); |
52 | |
53 | /* BT.601 defines hsync_start at 736 for 480i */ |
54 | KUNIT_EXPECT_EQ(test, mode->hsync_start, 736); |
55 | |
56 | /* |
57 | * The NTSC standard expects a line to take 63.556us. With a |
58 | * pixel clock of 13.5 MHz, a pixel takes around 74ns, so we |
59 | * need to have 63556ns / 74ns = 858. |
60 | * |
61 | * This is also mandated by BT.601. |
62 | */ |
63 | KUNIT_EXPECT_EQ(test, mode->htotal, 858); |
64 | |
65 | KUNIT_EXPECT_EQ(test, mode->vdisplay, 480); |
66 | KUNIT_EXPECT_EQ(test, mode->vtotal, 525); |
67 | } |
68 | |
69 | static void drm_test_modes_analog_tv_ntsc_480i_inlined(struct kunit *test) |
70 | { |
71 | struct drm_test_modes_priv *priv = test->priv; |
72 | struct drm_display_mode *expected, *mode; |
73 | |
74 | expected = drm_analog_tv_mode(dev: priv->drm, |
75 | mode: DRM_MODE_TV_MODE_NTSC, |
76 | pixel_clock_hz: 13500 * HZ_PER_KHZ, hdisplay: 720, vdisplay: 480, |
77 | interlace: true); |
78 | KUNIT_ASSERT_NOT_NULL(test, expected); |
79 | |
80 | mode = drm_mode_analog_ntsc_480i(dev: priv->drm); |
81 | KUNIT_ASSERT_NOT_NULL(test, mode); |
82 | |
83 | KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode)); |
84 | } |
85 | |
86 | static void drm_test_modes_analog_tv_pal_576i(struct kunit *test) |
87 | { |
88 | struct drm_test_modes_priv *priv = test->priv; |
89 | struct drm_display_mode *mode; |
90 | |
91 | mode = drm_analog_tv_mode(dev: priv->drm, |
92 | mode: DRM_MODE_TV_MODE_PAL, |
93 | pixel_clock_hz: 13500 * HZ_PER_KHZ, hdisplay: 720, vdisplay: 576, |
94 | interlace: true); |
95 | KUNIT_ASSERT_NOT_NULL(test, mode); |
96 | |
97 | KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 50); |
98 | KUNIT_EXPECT_EQ(test, mode->hdisplay, 720); |
99 | |
100 | /* BT.601 defines hsync_start at 732 for 576i */ |
101 | KUNIT_EXPECT_EQ(test, mode->hsync_start, 732); |
102 | |
103 | /* |
104 | * The PAL standard expects a line to take 64us. With a pixel |
105 | * clock of 13.5 MHz, a pixel takes around 74ns, so we need to |
106 | * have 64000ns / 74ns = 864. |
107 | * |
108 | * This is also mandated by BT.601. |
109 | */ |
110 | KUNIT_EXPECT_EQ(test, mode->htotal, 864); |
111 | |
112 | KUNIT_EXPECT_EQ(test, mode->vdisplay, 576); |
113 | KUNIT_EXPECT_EQ(test, mode->vtotal, 625); |
114 | } |
115 | |
116 | static void drm_test_modes_analog_tv_pal_576i_inlined(struct kunit *test) |
117 | { |
118 | struct drm_test_modes_priv *priv = test->priv; |
119 | struct drm_display_mode *expected, *mode; |
120 | |
121 | expected = drm_analog_tv_mode(dev: priv->drm, |
122 | mode: DRM_MODE_TV_MODE_PAL, |
123 | pixel_clock_hz: 13500 * HZ_PER_KHZ, hdisplay: 720, vdisplay: 576, |
124 | interlace: true); |
125 | KUNIT_ASSERT_NOT_NULL(test, expected); |
126 | |
127 | mode = drm_mode_analog_pal_576i(dev: priv->drm); |
128 | KUNIT_ASSERT_NOT_NULL(test, mode); |
129 | |
130 | KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode)); |
131 | } |
132 | |
133 | static struct kunit_case drm_modes_analog_tv_tests[] = { |
134 | KUNIT_CASE(drm_test_modes_analog_tv_ntsc_480i), |
135 | KUNIT_CASE(drm_test_modes_analog_tv_ntsc_480i_inlined), |
136 | KUNIT_CASE(drm_test_modes_analog_tv_pal_576i), |
137 | KUNIT_CASE(drm_test_modes_analog_tv_pal_576i_inlined), |
138 | { } |
139 | }; |
140 | |
141 | static struct kunit_suite drm_modes_analog_tv_test_suite = { |
142 | .name = "drm_modes_analog_tv" , |
143 | .init = drm_test_modes_init, |
144 | .test_cases = drm_modes_analog_tv_tests, |
145 | }; |
146 | |
147 | kunit_test_suite(drm_modes_analog_tv_test_suite); |
148 | |
149 | MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>" ); |
150 | MODULE_LICENSE("GPL" ); |
151 | |