brintos

brintos / linux-shallow public Read only

0
0
Text · 5.3 KiB · 7516f6c Raw
193 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright (c) 2022 Maxime Ripard <mripard@kernel.org>4 */5 6#include <kunit/test.h>7 8#include <drm/drm_connector.h>9#include <drm/drm_edid.h>10#include <drm/drm_drv.h>11#include <drm/drm_kunit_helpers.h>12#include <drm/drm_modes.h>13#include <drm/drm_modeset_helper_vtables.h>14#include <drm/drm_probe_helper.h>15 16struct drm_client_modeset_test_priv {17	struct drm_device *drm;18	struct device *dev;19	struct drm_connector connector;20};21 22static int drm_client_modeset_connector_get_modes(struct drm_connector *connector)23{24	struct drm_display_mode *mode;25	int count;26 27	count = drm_add_modes_noedid(connector, 1920, 1200);28 29	mode = drm_mode_analog_ntsc_480i(connector->dev);30	if (!mode)31		return count;32 33	drm_mode_probed_add(connector, mode);34	count += 1;35 36	mode = drm_mode_analog_pal_576i(connector->dev);37	if (!mode)38		return count;39 40	drm_mode_probed_add(connector, mode);41	count += 1;42 43	return count;44}45 46static const struct drm_connector_helper_funcs drm_client_modeset_connector_helper_funcs = {47	.get_modes = drm_client_modeset_connector_get_modes,48};49 50static const struct drm_connector_funcs drm_client_modeset_connector_funcs = {51};52 53static int drm_client_modeset_test_init(struct kunit *test)54{55	struct drm_client_modeset_test_priv *priv;56	int ret;57 58	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);59	KUNIT_ASSERT_NOT_NULL(test, priv);60 61	test->priv = priv;62 63	priv->dev = drm_kunit_helper_alloc_device(test);64	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev);65 66	priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev,67							sizeof(*priv->drm), 0,68							DRIVER_MODESET);69	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);70 71	ret = drmm_connector_init(priv->drm, &priv->connector,72				  &drm_client_modeset_connector_funcs,73				  DRM_MODE_CONNECTOR_Unknown,74				  NULL);75	KUNIT_ASSERT_EQ(test, ret, 0);76 77	drm_connector_helper_add(&priv->connector, &drm_client_modeset_connector_helper_funcs);78 79	priv->connector.interlace_allowed = true;80	priv->connector.doublescan_allowed = true;81 82	return 0;83}84 85static void drm_test_pick_cmdline_res_1920_1080_60(struct kunit *test)86{87	struct drm_client_modeset_test_priv *priv = test->priv;88	struct drm_device *drm = priv->drm;89	struct drm_connector *connector = &priv->connector;90	struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;91	struct drm_display_mode *expected_mode, *mode;92	const char *cmdline = "1920x1080@60";93	int ret;94 95	expected_mode = drm_mode_find_dmt(priv->drm, 1920, 1080, 60, false);96	KUNIT_ASSERT_NOT_NULL(test, expected_mode);97 98	KUNIT_ASSERT_TRUE(test,99			  drm_mode_parse_command_line_for_connector(cmdline,100								    connector,101								    cmdline_mode));102 103	mutex_lock(&drm->mode_config.mutex);104	ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);105	mutex_unlock(&drm->mode_config.mutex);106	KUNIT_ASSERT_GT(test, ret, 0);107 108	mode = drm_connector_pick_cmdline_mode(connector);109	KUNIT_ASSERT_NOT_NULL(test, mode);110 111	KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode));112}113 114struct drm_connector_pick_cmdline_mode_test {115	const char *cmdline;116	struct drm_display_mode *(*func)(struct drm_device *drm);117};118 119#define TEST_CMDLINE(_cmdline, _fn)		\120	{					\121		.cmdline = _cmdline,		\122		.func = _fn,			\123	}124 125static void drm_test_pick_cmdline_named(struct kunit *test)126{127	const struct drm_connector_pick_cmdline_mode_test *params = test->param_value;128	struct drm_client_modeset_test_priv *priv = test->priv;129	struct drm_device *drm = priv->drm;130	struct drm_connector *connector = &priv->connector;131	struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode;132	const struct drm_display_mode *expected_mode, *mode;133	const char *cmdline = params->cmdline;134	int ret;135 136	KUNIT_ASSERT_TRUE(test,137			  drm_mode_parse_command_line_for_connector(cmdline,138								    connector,139								    cmdline_mode));140 141	mutex_lock(&drm->mode_config.mutex);142	ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080);143	mutex_unlock(&drm->mode_config.mutex);144	KUNIT_ASSERT_GT(test, ret, 0);145 146	mode = drm_connector_pick_cmdline_mode(connector);147	KUNIT_ASSERT_NOT_NULL(test, mode);148 149	expected_mode = params->func(drm);150	KUNIT_ASSERT_NOT_NULL(test, expected_mode);151 152	KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode));153}154 155static const156struct drm_connector_pick_cmdline_mode_test drm_connector_pick_cmdline_mode_tests[] = {157	TEST_CMDLINE("NTSC", drm_mode_analog_ntsc_480i),158	TEST_CMDLINE("NTSC-J", drm_mode_analog_ntsc_480i),159	TEST_CMDLINE("PAL", drm_mode_analog_pal_576i),160	TEST_CMDLINE("PAL-M", drm_mode_analog_ntsc_480i),161};162 163static void164drm_connector_pick_cmdline_mode_desc(const struct drm_connector_pick_cmdline_mode_test *t,165				     char *desc)166{167	sprintf(desc, "%s", t->cmdline);168}169 170KUNIT_ARRAY_PARAM(drm_connector_pick_cmdline_mode,171		  drm_connector_pick_cmdline_mode_tests,172		  drm_connector_pick_cmdline_mode_desc);173 174static struct kunit_case drm_test_pick_cmdline_tests[] = {175	KUNIT_CASE(drm_test_pick_cmdline_res_1920_1080_60),176	KUNIT_CASE_PARAM(drm_test_pick_cmdline_named,177			 drm_connector_pick_cmdline_mode_gen_params),178	{}179};180 181static struct kunit_suite drm_test_pick_cmdline_test_suite = {182	.name = "drm_test_pick_cmdline",183	.init = drm_client_modeset_test_init,184	.test_cases = drm_test_pick_cmdline_tests185};186 187kunit_test_suite(drm_test_pick_cmdline_test_suite);188 189/*190 * This file is included directly by drm_client_modeset.c so we can't191 * use any MODULE_* macro here.192 */193