// SPDX-License-Identifier: GPL-2.0
/*
 * Kunit test for drm_probe_helper functions
 */

#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_connector.h>
#include <drm/drm_device.h>
#include <drm/drm_drv.h>
#include <drm/drm_kunit_helpers.h>
#include <drm/drm_mode.h>
#include <drm/drm_modes.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <drm/drm_probe_helper.h>

#include <kunit/test.h>

struct drm_probe_helper_test_priv {
	struct drm_device *drm;
	struct device *dev;
	struct drm_connector connector;
};

static const struct drm_connector_helper_funcs drm_probe_helper_connector_helper_funcs = {
};

static const struct drm_connector_funcs drm_probe_helper_connector_funcs = {
	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
	.reset			= drm_atomic_helper_connector_reset,
};

static int drm_probe_helper_test_init(struct kunit *test)
{
	struct drm_probe_helper_test_priv *priv;
	struct drm_connector *connector;
	int ret;

	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
	KUNIT_ASSERT_NOT_NULL(test, priv);
	test->priv = 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 | DRIVER_ATOMIC);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);

	connector = &priv->connector;
	ret = drmm_connector_init(priv->drm, connector,
				  &drm_probe_helper_connector_funcs,
				  DRM_MODE_CONNECTOR_Unknown,
				  NULL);
	KUNIT_ASSERT_EQ(test, ret, 0);

	drm_connector_helper_add(connector, &drm_probe_helper_connector_helper_funcs);

	return 0;
}

typedef struct drm_display_mode *(*expected_mode_func_t)(struct drm_device *);

struct drm_connector_helper_tv_get_modes_test {
	const char *name;
	unsigned int supported_tv_modes;
	enum drm_connector_tv_mode default_mode;
	bool cmdline;
	enum drm_connector_tv_mode cmdline_mode;
	expected_mode_func_t *expected_modes;
	unsigned int num_expected_modes;
};

#define _TV_MODE_TEST(_name, _supported, _default, _cmdline, _cmdline_mode, ...)		\
	{											\
		.name = _name,									\
		.supported_tv_modes = _supported,						\
		.default_mode = _default,							\
		.cmdline = _cmdline,								\
		.cmdline_mode = _cmdline_mode,							\
		.expected_modes = (expected_mode_func_t[]) { __VA_ARGS__ },			\
		.num_expected_modes = sizeof((expected_mode_func_t[]) { __VA_ARGS__ }) /	\
				      (sizeof(expected_mode_func_t)),				\
	}

#define TV_MODE_TEST(_name, _supported, _default, ...)			\
	_TV_MODE_TEST(_name, _supported, _default, false, 0, __VA_ARGS__)

#define TV_MODE_TEST_CMDLINE(_name, _supported, _default, _cmdline, ...) \
	_TV_MODE_TEST(_name, _supported, _default, true, _cmdline, __VA_ARGS__)

static void
drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
{
	const struct drm_connector_helper_tv_get_modes_test *params = test->param_value;
	struct drm_probe_helper_test_priv *priv = test->priv;
	struct drm_connector *connector = &priv->connector;
	struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
	struct drm_display_mode *mode;
	const struct drm_display_mode *expected;
	size_t len;
	int ret;

	if (params->cmdline) {
		cmdline->tv_mode_specified = true;
		cmdline->tv_mode = params->cmdline_mode;
	}

	ret = drm_mode_create_tv_properties(priv->drm, params->supported_tv_modes);
	KUNIT_ASSERT_EQ(test, ret, 0);

	drm_object_attach_property(&connector->base,
				   priv->drm->mode_config.tv_mode_property,
				   params->default_mode);

	mutex_lock(&priv->drm->mode_config.mutex);

	ret = drm_connector_helper_tv_get_modes(connector);
	KUNIT_EXPECT_EQ(test, ret, params->num_expected_modes);

	len = 0;
	list_for_each_entry(mode, &connector->probed_modes, head)
		len++;
	KUNIT_EXPECT_EQ(test, len, params->num_expected_modes);

	if (params->num_expected_modes >= 1) {
		mode = list_first_entry_or_null(&connector->probed_modes,
						struct drm_display_mode, head);
		KUNIT_ASSERT_NOT_NULL(test, mode);

		expected = params->expected_modes[0](priv->drm);
		KUNIT_ASSERT_NOT_NULL(test, expected);

		KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
		KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
	}

	if (params->num_expected_modes >= 2) {
		mode = list_next_entry(mode, head);
		KUNIT_ASSERT_NOT_NULL(test, mode);

		expected = params->expected_modes[1](priv->drm);
		KUNIT_ASSERT_NOT_NULL(test, expected);

		KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
		KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
	}

	mutex_unlock(&priv->drm->mode_config.mutex);
}

static const
struct drm_connector_helper_tv_get_modes_test drm_connector_helper_tv_get_modes_tests[] = {
	{ .name = "None" },
	TV_MODE_TEST("PAL",
		     BIT(DRM_MODE_TV_MODE_PAL),
		     DRM_MODE_TV_MODE_PAL,
		     drm_mode_analog_pal_576i),
	TV_MODE_TEST("NTSC",
		     BIT(DRM_MODE_TV_MODE_NTSC),
		     DRM_MODE_TV_MODE_NTSC,
		     drm_mode_analog_ntsc_480i),
	TV_MODE_TEST("Both, NTSC Default",
		     BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
		     DRM_MODE_TV_MODE_NTSC,
		     drm_mode_analog_ntsc_480i, drm_mode_analog_pal_576i),
	TV_MODE_TEST("Both, PAL Default",
		     BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
		     DRM_MODE_TV_MODE_PAL,
		     drm_mode_analog_pal_576i, drm_mode_analog_ntsc_480i),
	TV_MODE_TEST_CMDLINE("Both, NTSC Default, with PAL on command-line",
			     BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
			     DRM_MODE_TV_MODE_NTSC,
			     DRM_MODE_TV_MODE_PAL,
			     drm_mode_analog_pal_576i, drm_mode_analog_ntsc_480i),
	TV_MODE_TEST_CMDLINE("Both, PAL Default, with NTSC on command-line",
			     BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
			     DRM_MODE_TV_MODE_PAL,
			     DRM_MODE_TV_MODE_NTSC,
			     drm_mode_analog_ntsc_480i, drm_mode_analog_pal_576i),
};

static void
drm_connector_helper_tv_get_modes_desc(const struct drm_connector_helper_tv_get_modes_test *t,
				       char *desc)
{
	sprintf(desc, "%s", t->name);
}

KUNIT_ARRAY_PARAM(drm_connector_helper_tv_get_modes,
		  drm_connector_helper_tv_get_modes_tests,
		  drm_connector_helper_tv_get_modes_desc);

static struct kunit_case drm_test_connector_helper_tv_get_modes_tests[] = {
	KUNIT_CASE_PARAM(drm_test_connector_helper_tv_get_modes_check,
			 drm_connector_helper_tv_get_modes_gen_params),
	{ }
};

static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = {
	.name = "drm_connector_helper_tv_get_modes",
	.init = drm_probe_helper_test_init,
	.test_cases = drm_test_connector_helper_tv_get_modes_tests,
};

kunit_test_suite(drm_test_connector_helper_tv_get_modes_suite);

MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
MODULE_DESCRIPTION("Kunit test for drm_probe_helper functions");
MODULE_LICENSE("GPL");
