// SPDX-License-Identifier: GPL-2.0
/*
 * Test cases for the drm_atomic_commit helpers
 *
 * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_kunit_helpers.h>
#include <drm/drm_probe_helper.h>

#define DRM_TEST_ENC_0 BIT(0)
#define DRM_TEST_ENC_1 BIT(1)
#define DRM_TEST_ENC_2 BIT(2)

#define DRM_TEST_CONN_0 BIT(0)

struct drm_clone_mode_test {
	const char *name;
	u32 encoder_mask;
	int expected_result;
};

static const struct drm_display_mode drm_atomic_test_mode = {
	DRM_MODE("1024x768", 0, 65000, 1024, 1048,
		 1184, 1344, 0, 768, 771, 777, 806, 0,
		 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
};

struct drm_atomic_test_priv {
	struct drm_device drm;
	struct drm_plane *plane;
	struct drm_crtc *crtc;
	struct drm_encoder encoders[3];
	struct drm_connector connectors[2];
};

static int modeset_counter;

static void drm_test_encoder_mode_set(struct drm_encoder *encoder,
				      struct drm_crtc_state *crtc_state,
				      struct drm_connector_state *conn_state)
{
	modeset_counter++;
}

static const struct drm_encoder_helper_funcs drm_atomic_test_encoder_funcs = {
	.atomic_mode_set	= drm_test_encoder_mode_set,
};

static const struct drm_connector_funcs dummy_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_atomic_test_dummy_get_modes(struct drm_connector *connector)
{
	return drm_connector_helper_get_modes_fixed(connector,
						    &drm_atomic_test_mode);
}

static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = {
	.get_modes	= drm_atomic_test_dummy_get_modes,
};

static struct drm_atomic_test_priv *
drm_atomic_test_init_drm_components(struct kunit *test, bool has_connectors)
{
	struct drm_atomic_test_priv *priv;
	struct drm_encoder *enc;
	struct drm_connector *conn;
	struct drm_device *drm;
	struct device *dev;
	int ret;

	dev = drm_kunit_helper_alloc_device(test);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);

	priv = drm_kunit_helper_alloc_drm_device(test, dev,
						 struct drm_atomic_test_priv,
						 drm,
						 DRIVER_MODESET | DRIVER_ATOMIC);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
	test->priv = priv;

	drm = &priv->drm;
	priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
							    NULL,
							    NULL,
							    NULL, 0,
							    NULL);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->plane);

	priv->crtc = drm_kunit_helper_create_crtc(test, drm,
						  priv->plane, NULL,
						  NULL,
						  NULL);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->crtc);

	for (int i = 0; i < ARRAY_SIZE(priv->encoders); i++) {
		enc = &priv->encoders[i];

		ret = drmm_encoder_init(drm, enc, NULL,
					DRM_MODE_ENCODER_DSI, NULL);
		KUNIT_ASSERT_EQ(test, ret, 0);

		enc->possible_crtcs = drm_crtc_mask(priv->crtc);
	}

	priv->encoders[0].possible_clones = DRM_TEST_ENC_0 | DRM_TEST_ENC_1;
	priv->encoders[1].possible_clones = DRM_TEST_ENC_0 | DRM_TEST_ENC_1;
	priv->encoders[2].possible_clones = DRM_TEST_ENC_2;

	if (!has_connectors)
		goto done;

	BUILD_BUG_ON(ARRAY_SIZE(priv->connectors) > ARRAY_SIZE(priv->encoders));

	for (int i = 0; i < ARRAY_SIZE(priv->connectors); i++) {
		conn = &priv->connectors[i];

		ret = drmm_connector_init(drm, conn, &dummy_connector_funcs,
					  DRM_MODE_CONNECTOR_DSI, NULL);
		KUNIT_ASSERT_EQ(test, ret, 0);

		drm_connector_helper_add(conn, &dummy_connector_helper_funcs);
		drm_encoder_helper_add(&priv->encoders[i],
				       &drm_atomic_test_encoder_funcs);

		drm_connector_attach_encoder(conn, &priv->encoders[i]);
	}

done:
	drm_mode_config_reset(drm);

	return priv;
}

static int set_up_atomic_state(struct kunit *test,
			       struct drm_atomic_test_priv *priv,
			       struct drm_connector *connector,
			       struct drm_modeset_acquire_ctx *ctx)
{
	struct drm_device *drm = &priv->drm;
	struct drm_crtc *crtc = priv->crtc;
	struct drm_atomic_commit *state;
	struct drm_connector_state *conn_state;
	struct drm_crtc_state *crtc_state;
	int ret;

	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);

	if (connector) {
		conn_state = drm_atomic_get_connector_state(state, connector);
		if (IS_ERR(conn_state))
			return PTR_ERR(conn_state);

		ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
		if (ret)
			return ret;
	}

	crtc_state = drm_atomic_get_crtc_state(state, crtc);
	if (IS_ERR(crtc_state))
		return PTR_ERR(crtc_state);

	ret = drm_atomic_set_mode_for_crtc(crtc_state, &drm_atomic_test_mode);
	if (ret)
		return ret;

	crtc_state->enable = true;
	crtc_state->active = true;

	if (connector) {
		ret = drm_atomic_commit(state);
		if (ret)
			return ret;
	} else {
		// dummy connector mask
		crtc_state->connector_mask = DRM_TEST_CONN_0;
	}

	return 0;
}

/*
 * Test that the DRM encoder mode_set() is called when the atomic state
 * connectors are changed but the CRTC mode is not.
 */
static void drm_test_check_connector_changed_modeset(struct kunit *test)
{
	struct drm_atomic_test_priv *priv;
	struct drm_modeset_acquire_ctx ctx;
	struct drm_connector *old_conn, *new_conn;
	struct drm_atomic_commit *state;
	struct drm_device *drm;
	struct drm_connector_state *new_conn_state, *old_conn_state;
	int ret, initial_modeset_count;

	priv = drm_atomic_test_init_drm_components(test, true);
	KUNIT_ASSERT_NOT_NULL(test, priv);

	drm = &priv->drm;
	old_conn = &priv->connectors[0];
	new_conn = &priv->connectors[1];

	drm_modeset_acquire_init(&ctx, 0);

	// first modeset to enable
retry_set_up:
	ret = set_up_atomic_state(test, priv, old_conn, &ctx);
	if (ret == -EDEADLK) {
		ret = drm_modeset_backoff(&ctx);
		if (!ret)
			goto retry_set_up;
	}
	KUNIT_ASSERT_EQ(test, ret, 0);

	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);

	new_conn_state = drm_atomic_get_connector_state(state, new_conn);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);

	old_conn_state = drm_atomic_get_connector_state(state, old_conn);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);

	ret = drm_atomic_set_crtc_for_connector(old_conn_state, NULL);
	KUNIT_EXPECT_EQ(test, ret, 0);

	ret = drm_atomic_set_crtc_for_connector(new_conn_state, priv->crtc);
	KUNIT_EXPECT_EQ(test, ret, 0);

	initial_modeset_count = modeset_counter;

	// modeset_disables is called as part of the atomic commit tail
	ret = drm_atomic_commit(state);
	KUNIT_ASSERT_EQ(test, ret, 0);
	KUNIT_ASSERT_EQ(test, modeset_counter, initial_modeset_count + 1);

	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);
}

/*
 * Test that the drm_crtc_in_clone_mode() helper can detect if a given CRTC
 * state is in clone mode
 */
static void drm_test_check_in_clone_mode(struct kunit *test)
{
	bool ret;
	const struct drm_clone_mode_test *param = test->param_value;
	struct drm_crtc_state *crtc_state;

	crtc_state = kunit_kzalloc(test, sizeof(*crtc_state), GFP_KERNEL);
	KUNIT_ASSERT_NOT_NULL(test, crtc_state);

	crtc_state->encoder_mask = param->encoder_mask;

	ret = drm_crtc_in_clone_mode(crtc_state);

	KUNIT_ASSERT_EQ(test, ret, param->expected_result);
}

/*
 * Test that the atomic commit path will succeed for valid clones (or non-cloned
 * states) and fail for states where the cloned encoders are not possible_clones
 * of each other.
 */
static void drm_test_check_valid_clones(struct kunit *test)
{
	int ret;
	const struct drm_clone_mode_test *param = test->param_value;
	struct drm_atomic_test_priv *priv;
	struct drm_modeset_acquire_ctx ctx;
	struct drm_device *drm;
	struct drm_atomic_commit *state;
	struct drm_crtc_state *crtc_state;

	priv = drm_atomic_test_init_drm_components(test, false);
	KUNIT_ASSERT_NOT_NULL(test, priv);

	drm = &priv->drm;

	drm_modeset_acquire_init(&ctx, 0);

retry_set_up:
	ret = set_up_atomic_state(test, priv, NULL, &ctx);
	if (ret == -EDEADLK) {
		ret = drm_modeset_backoff(&ctx);
		if (!ret)
			goto retry_set_up;
	}
	KUNIT_ASSERT_EQ(test, ret, 0);

	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);

retry:
	crtc_state = drm_atomic_get_crtc_state(state, priv->crtc);
	if (PTR_ERR(crtc_state) == -EDEADLK) {
		drm_atomic_commit_clear(state);
		ret = drm_modeset_backoff(&ctx);
		if (!ret)
			goto retry;
	}
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);

	crtc_state->encoder_mask = param->encoder_mask;

	// force modeset
	crtc_state->mode_changed = true;

	ret = drm_atomic_helper_check_modeset(drm, state);
	if (ret == -EDEADLK) {
		drm_atomic_commit_clear(state);
		ret = drm_modeset_backoff(&ctx);
		if (!ret)
			goto retry;
	}
	KUNIT_ASSERT_EQ(test, ret, param->expected_result);

	drm_modeset_drop_locks(&ctx);
	drm_modeset_acquire_fini(&ctx);
}

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

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

static const struct drm_clone_mode_test drm_clone_mode_tests[] = {
	{
		.name = "in_clone_mode",
		.encoder_mask = DRM_TEST_ENC_0 | DRM_TEST_ENC_1,
		.expected_result = true,
	},
	{
		.name = "not_in_clone_mode",
		.encoder_mask = DRM_TEST_ENC_0,
		.expected_result = false,
	},
};

static const struct drm_clone_mode_test drm_valid_clone_mode_tests[] = {
	{
		.name = "not_in_clone_mode",
		.encoder_mask = DRM_TEST_ENC_0,
		.expected_result = 0,
	},

	{
		.name = "valid_clone",
		.encoder_mask = DRM_TEST_ENC_0 | DRM_TEST_ENC_1,
		.expected_result = 0,
	},
	{
		.name = "invalid_clone",
		.encoder_mask = DRM_TEST_ENC_0 | DRM_TEST_ENC_2,
		.expected_result = -EINVAL,
	},
};

KUNIT_ARRAY_PARAM(drm_check_in_clone_mode, drm_clone_mode_tests,
		  drm_check_in_clone_mode_desc);

KUNIT_ARRAY_PARAM(drm_check_valid_clones, drm_valid_clone_mode_tests,
		  drm_check_valid_clones_desc);

static struct kunit_case drm_test_check_modeset_test[] = {
	KUNIT_CASE(drm_test_check_connector_changed_modeset),
	{}
};

static struct kunit_case drm_in_clone_mode_check_test[] = {
	KUNIT_CASE_PARAM(drm_test_check_in_clone_mode,
			 drm_check_in_clone_mode_gen_params),
	KUNIT_CASE_PARAM(drm_test_check_valid_clones,
			 drm_check_valid_clones_gen_params),
	{}
};

static struct kunit_suite drm_test_check_modeset_test_suite = {
	.name = "drm_validate_modeset",
	.test_cases = drm_test_check_modeset_test,
};

static struct kunit_suite drm_in_clone_mode_check_test_suite = {
	.name = "drm_validate_clone_mode",
	.test_cases = drm_in_clone_mode_check_test,
};

kunit_test_suites(&drm_in_clone_mode_check_test_suite,
		  &drm_test_check_modeset_test_suite);

MODULE_AUTHOR("Jessica Zhang <quic_jesszhan@quicinc.com");
MODULE_DESCRIPTION("Test cases for the drm_atomic_helper functions");
MODULE_LICENSE("GPL");
