aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/gpu/drm/tests/drm_modes_test.c
blob: bc4aa2ce78beb97d9c6645c211595c4b17f40c2d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// 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_exit(struct kunit *test)
{
	struct drm_test_modes_priv *priv = test->priv;

	drm_kunit_helper_free_device(test, priv->dev);
}

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,
	.exit = drm_test_modes_exit,
	.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");