diff options
Diffstat (limited to 'drivers/gpu/drm/tests')
-rw-r--r-- | drivers/gpu/drm/tests/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/tests/drm_atomic_state_test.c | 379 | ||||
-rw-r--r-- | drivers/gpu/drm/tests/drm_buddy_test.c | 30 | ||||
-rw-r--r-- | drivers/gpu/drm/tests/drm_connector_test.c | 523 | ||||
-rw-r--r-- | drivers/gpu/drm/tests/drm_dp_mst_helper_test.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/tests/drm_format_helper_test.c | 81 | ||||
-rw-r--r-- | drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c | 829 | ||||
-rw-r--r-- | drivers/gpu/drm/tests/drm_kunit_edid.h | 102 | ||||
-rw-r--r-- | drivers/gpu/drm/tests/drm_kunit_helpers.c | 44 |
9 files changed, 1659 insertions, 347 deletions
diff --git a/drivers/gpu/drm/tests/Makefile b/drivers/gpu/drm/tests/Makefile index 56dab563abd7..0109bcf7faa5 100644 --- a/drivers/gpu/drm/tests/Makefile +++ b/drivers/gpu/drm/tests/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_DRM_KUNIT_TEST_HELPERS) += \ drm_kunit_helpers.o obj-$(CONFIG_DRM_KUNIT_TEST) += \ + drm_atomic_state_test.o \ drm_buddy_test.o \ drm_cmdline_parser_test.o \ drm_connector_test.o \ diff --git a/drivers/gpu/drm/tests/drm_atomic_state_test.c b/drivers/gpu/drm/tests/drm_atomic_state_test.c new file mode 100644 index 000000000000..2f6ac7a09f44 --- /dev/null +++ b/drivers/gpu/drm/tests/drm_atomic_state_test.c @@ -0,0 +1,379 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test cases for the drm_atomic_state 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_state *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); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + ret = drm_atomic_set_crtc_for_connector(conn_state, crtc); + KUNIT_EXPECT_EQ(test, ret, 0); + } + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + ret = drm_atomic_set_mode_for_crtc(crtc_state, &drm_atomic_test_mode); + KUNIT_EXPECT_EQ(test, ret, 0); + + crtc_state->enable = true; + crtc_state->active = true; + + if (connector) { + ret = drm_atomic_commit(state); + KUNIT_ASSERT_EQ(test, ret, 0); + } 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_state *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 + ret = set_up_atomic_state(test, priv, old_conn, &ctx); + 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_state *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); + + ret = set_up_atomic_state(test, priv, NULL, &ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + crtc_state = drm_atomic_get_crtc_state(state, priv->crtc); + 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); + 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"); diff --git a/drivers/gpu/drm/tests/drm_buddy_test.c b/drivers/gpu/drm/tests/drm_buddy_test.c index 9662c949d0e3..7a0e523651f0 100644 --- a/drivers/gpu/drm/tests/drm_buddy_test.c +++ b/drivers/gpu/drm/tests/drm_buddy_test.c @@ -261,7 +261,6 @@ static void drm_test_buddy_alloc_range_bias(struct kunit *test) static void drm_test_buddy_alloc_clear(struct kunit *test) { unsigned long n_pages, total, i = 0; - DRM_RND_STATE(prng, random_seed); const unsigned long ps = SZ_4K; struct drm_buddy_block *block; const int max_order = 12; @@ -385,17 +384,28 @@ static void drm_test_buddy_alloc_clear(struct kunit *test) drm_buddy_fini(&mm); /* - * Create a new mm with a non power-of-two size. Allocate a random size, free as - * cleared and then call fini. This will ensure the multi-root force merge during - * fini. + * Create a new mm with a non power-of-two size. Allocate a random size from each + * root, free as cleared and then call fini. This will ensure the multi-root + * force merge during fini. */ - mm_size = 12 * SZ_4K; - size = max(round_up(prandom_u32_state(&prng) % mm_size, ps), ps); + mm_size = (SZ_4K << max_order) + (SZ_4K << (max_order - 2)); + KUNIT_EXPECT_FALSE(test, drm_buddy_init(&mm, mm_size, ps)); - KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, mm_size, - size, ps, &allocated, - DRM_BUDDY_TOPDOWN_ALLOCATION), - "buddy_alloc hit an error size=%u\n", size); + KUNIT_EXPECT_EQ(test, mm.max_order, max_order); + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, SZ_4K << max_order, + 4 * ps, ps, &allocated, + DRM_BUDDY_RANGE_ALLOCATION), + "buddy_alloc hit an error size=%lu\n", 4 * ps); + drm_buddy_free_list(&mm, &allocated, DRM_BUDDY_CLEARED); + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, 0, SZ_4K << max_order, + 2 * ps, ps, &allocated, + DRM_BUDDY_CLEAR_ALLOCATION), + "buddy_alloc hit an error size=%lu\n", 2 * ps); + drm_buddy_free_list(&mm, &allocated, DRM_BUDDY_CLEARED); + KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_alloc_blocks(&mm, SZ_4K << max_order, mm_size, + ps, ps, &allocated, + DRM_BUDDY_RANGE_ALLOCATION), + "buddy_alloc hit an error size=%lu\n", ps); drm_buddy_free_list(&mm, &allocated, DRM_BUDDY_CLEARED); drm_buddy_fini(&mm); } diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index 6bba97d0be88..22e2d959eb31 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -9,6 +9,7 @@ #include <drm/drm_connector.h> #include <drm/drm_drv.h> #include <drm/drm_edid.h> +#include <drm/drm_file.h> #include <drm/drm_kunit_helpers.h> #include <drm/drm_modes.h> @@ -181,6 +182,465 @@ static struct kunit_suite drmm_connector_init_test_suite = { .test_cases = drmm_connector_init_tests, }; +static const struct drm_connector_funcs dummy_dynamic_init_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, + .destroy = drm_connector_cleanup, +}; + +/* + * Test that the initialization of a bog standard dynamic connector works + * as expected and doesn't report any error. + */ +static void drm_test_drm_connector_dynamic_init(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + DRM_MODE_CONNECTOR_DisplayPort, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); +} + +static void drm_test_connector_dynamic_init_cleanup(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + + drm_connector_cleanup(connector); +} + +/* + * Test that the initialization of a dynamic connector without a DDC adapter + * doesn't report any error. + */ +static void drm_test_drm_connector_dynamic_init_null_ddc(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + DRM_MODE_CONNECTOR_DisplayPort, + NULL); + KUNIT_ASSERT_EQ(test, ret, 0); +} + +/* + * Test that the initialization of a dynamic connector doesn't add the + * connector to the connector list. + */ +static void drm_test_drm_connector_dynamic_init_not_added(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + DRM_MODE_CONNECTOR_DisplayPort, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &connector->head); +} + +static void test_connector_property(struct kunit *test, + struct drm_connector *connector, + const struct drm_property *expected_prop) +{ + struct drm_property *prop; + uint64_t val; + int ret; + + KUNIT_ASSERT_NOT_NULL(test, expected_prop); + prop = drm_mode_obj_find_prop_id(&connector->base, expected_prop->base.id); + KUNIT_ASSERT_PTR_EQ_MSG(test, prop, expected_prop, + "Can't find property %s", expected_prop->name); + + ret = drm_object_property_get_default_value(&connector->base, prop, &val); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, val, 0); + + /* TODO: Check property value in the connector state. */ +} + +/* + * Test that the initialization of a dynamic connector adds all the expected + * properties to it. + */ +static void drm_test_drm_connector_dynamic_init_properties(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_mode_config *config = &priv->drm.mode_config; + const struct drm_property *props[] = { + config->edid_property, + config->dpms_property, + config->link_status_property, + config->non_desktop_property, + config->tile_property, + config->prop_crtc_id, + }; + int ret; + int i; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + DRM_MODE_CONNECTOR_DisplayPort, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + + for (i = 0; i < ARRAY_SIZE(props); i++) + test_connector_property(test, connector, props[i]); +} + +/* + * Test that the initialization of a dynamic connector succeeds for all + * possible connector types. + */ +static void drm_test_drm_connector_dynamic_init_type_valid(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + unsigned int connector_type = *(unsigned int *)test->param_value; + int ret; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + connector_type, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); +} + +/* + * Test that the initialization of a dynamic connector sets the expected name + * for it for all possible connector types. + */ +static void drm_test_drm_connector_dynamic_init_name(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + unsigned int connector_type = *(unsigned int *)test->param_value; + char expected_name[128]; + int ret; + + ret = drm_connector_dynamic_init(&priv->drm, connector, + &dummy_dynamic_init_funcs, + connector_type, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + + snprintf(expected_name, sizeof(expected_name), "%s-%d", + drm_get_connector_type_name(connector_type), connector->connector_type_id); + KUNIT_ASSERT_STREQ(test, connector->name, expected_name); +} + +static struct kunit_case drm_connector_dynamic_init_tests[] = { + KUNIT_CASE(drm_test_drm_connector_dynamic_init), + KUNIT_CASE(drm_test_drm_connector_dynamic_init_null_ddc), + KUNIT_CASE(drm_test_drm_connector_dynamic_init_not_added), + KUNIT_CASE(drm_test_drm_connector_dynamic_init_properties), + KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_type_valid, + drm_connector_init_type_valid_gen_params), + KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_name, + drm_connector_init_type_valid_gen_params), + {} +}; + +static struct kunit_suite drm_connector_dynamic_init_test_suite = { + .name = "drm_connector_dynamic_init", + .init = drm_test_connector_init, + .exit = drm_test_connector_dynamic_init_cleanup, + .test_cases = drm_connector_dynamic_init_tests, +}; + +static int drm_test_connector_dynamic_register_early_init(struct kunit *test) +{ + struct drm_connector_init_priv *priv; + int ret; + + ret = drm_test_connector_init(test); + KUNIT_ASSERT_EQ(test, ret, 0); + + priv = test->priv; + + ret = drm_connector_dynamic_init(&priv->drm, &priv->connector, + &dummy_dynamic_init_funcs, + DRM_MODE_CONNECTOR_DisplayPort, + &priv->ddc); + KUNIT_ASSERT_EQ(test, ret, 0); + + return 0; +} + +static void drm_test_connector_dynamic_register_early_cleanup(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + + drm_connector_unregister(connector); + drm_connector_put(connector); +} + +/* + * Test that registration of a dynamic connector adds it to the connector list. + */ +static void drm_test_drm_connector_dynamic_register_early_on_list(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + KUNIT_ASSERT_TRUE(test, list_empty(&connector->head)); + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &priv->drm.mode_config.connector_list); +} + +/* + * Test that the registration of a dynamic connector before the drm device is + * registered results in deferring the connector's user interface registration. + */ +static void drm_test_drm_connector_dynamic_register_early_defer(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_ASSERT_EQ(test, connector->registration_state, DRM_CONNECTOR_INITIALIZING); +} + +/* + * Test that the registration of a dynamic connector fails, if this is done before + * the connector is initialized. + */ +static void drm_test_drm_connector_dynamic_register_early_no_init(struct kunit *test) +{ + struct drm_connector *connector; + int ret; + + connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */ + KUNIT_ASSERT_NOT_NULL(test, connector); + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, -EINVAL); +} + +/* + * Test that the registration of a dynamic connector before the drm device is + * registered results in deferring adding a mode object for the connector. + */ +static void drm_test_drm_connector_dynamic_register_early_no_mode_object(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_connector *tmp_connector; + int ret; + + ret = drm_connector_dynamic_register(&priv->connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id); + KUNIT_ASSERT_NULL(test, tmp_connector); +} + +static struct kunit_case drm_connector_dynamic_register_early_tests[] = { + KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_on_list), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_defer), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_init), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_mode_object), + { } +}; + +static struct kunit_suite drm_connector_dynamic_register_early_test_suite = { + .name = "drm_connector_dynamic_register_early", + .init = drm_test_connector_dynamic_register_early_init, + .exit = drm_test_connector_dynamic_register_early_cleanup, + .test_cases = drm_connector_dynamic_register_early_tests, +}; + +static int drm_test_connector_dynamic_register_init(struct kunit *test) +{ + struct drm_connector_init_priv *priv; + int ret; + + ret = drm_test_connector_dynamic_register_early_init(test); + KUNIT_ASSERT_EQ(test, ret, 0); + + priv = test->priv; + + ret = drm_dev_register(priv->connector.dev, 0); + KUNIT_ASSERT_EQ(test, ret, 0); + + return 0; +} + +static void drm_test_connector_dynamic_register_cleanup(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_device *dev = priv->connector.dev; + + drm_connector_unregister(&priv->connector); + drm_connector_put(&priv->connector); + + drm_dev_unregister(dev); + + drm_test_connector_dynamic_register_early_cleanup(test); +} + +static void drm_test_drm_connector_dynamic_register_on_list(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + KUNIT_ASSERT_TRUE(test, list_empty(&priv->connector.head)); + + ret = drm_connector_dynamic_register(&priv->connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_ASSERT_PTR_EQ(test, priv->connector.head.next, &priv->drm.mode_config.connector_list); +} + +/* + * Test that the registration of a dynamic connector doesn't get deferred if + * this is done after the drm device is registered. + */ +static void drm_test_drm_connector_dynamic_register_no_defer(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_INITIALIZING); + + ret = drm_connector_dynamic_register(&priv->connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_REGISTERED); +} + +/* + * Test that the registration of a dynamic connector fails if this is done after the + * drm device is registered, but before the connector is initialized. + */ +static void drm_test_drm_connector_dynamic_register_no_init(struct kunit *test) +{ + struct drm_connector *connector; + int ret; + + connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */ + KUNIT_ASSERT_NOT_NULL(test, connector); + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, -EINVAL); +} + +/* + * Test that the registration of a dynamic connector after the drm device is + * registered adds the mode object for the connector. + */ +static void drm_test_drm_connector_dynamic_register_mode_object(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + struct drm_connector *tmp_connector; + int ret; + + tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id); + KUNIT_ASSERT_NULL(test, tmp_connector); + + ret = drm_connector_dynamic_register(&priv->connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id); + KUNIT_ASSERT_PTR_EQ(test, tmp_connector, connector); +} + +/* + * Test that the registration of a dynamic connector after the drm device is + * registered adds the connector to sysfs. + */ +static void drm_test_drm_connector_dynamic_register_sysfs(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + int ret; + + KUNIT_ASSERT_NULL(test, connector->kdev); + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + KUNIT_ASSERT_NOT_NULL(test, connector->kdev); +} + +/* + * Test that the registration of a dynamic connector after the drm device is + * registered sets the connector's sysfs name as expected. + */ +static void drm_test_drm_connector_dynamic_register_sysfs_name(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector *connector = &priv->connector; + char expected_name[128]; + int ret; + + ret = drm_connector_dynamic_register(connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + snprintf(expected_name, sizeof(expected_name), "card%d-%s", + connector->dev->primary->index, connector->name); + + KUNIT_ASSERT_STREQ(test, dev_name(connector->kdev), expected_name); +} + +/* + * Test that the registration of a dynamic connector after the drm device is + * registered adds the connector to debugfs. + */ +static void drm_test_drm_connector_dynamic_register_debugfs(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry); + + ret = drm_connector_dynamic_register(&priv->connector); + KUNIT_ASSERT_EQ(test, ret, 0); + + if (IS_ENABLED(CONFIG_DEBUG_FS)) + KUNIT_ASSERT_NOT_NULL(test, priv->connector.debugfs_entry); + else + KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry); +} + +static struct kunit_case drm_connector_dynamic_register_tests[] = { + KUNIT_CASE(drm_test_drm_connector_dynamic_register_on_list), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_defer), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_init), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_mode_object), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs_name), + KUNIT_CASE(drm_test_drm_connector_dynamic_register_debugfs), + { } +}; + +static struct kunit_suite drm_connector_dynamic_register_test_suite = { + .name = "drm_connector_dynamic_register", + .init = drm_test_connector_dynamic_register_init, + .exit = drm_test_connector_dynamic_register_cleanup, + .test_cases = drm_connector_dynamic_register_tests, +}; + /* * Test that the registration of a bog standard connector works as * expected and doesn't report any error. @@ -635,6 +1095,64 @@ static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test) KUNIT_EXPECT_LT(test, ret, 0); } +struct drm_connector_hdmi_init_formats_yuv420_allowed_test { + unsigned long supported_formats; + bool yuv420_allowed; + int expected_result; +}; + +#define YUV420_ALLOWED_TEST(_formats, _allowed, _result) \ + { \ + .supported_formats = BIT(HDMI_COLORSPACE_RGB) | (_formats), \ + .yuv420_allowed = _allowed, \ + .expected_result = _result, \ + } + +static const struct drm_connector_hdmi_init_formats_yuv420_allowed_test +drm_connector_hdmi_init_formats_yuv420_allowed_tests[] = { + YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), true, 0), + YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), false, -EINVAL), + YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), true, -EINVAL), + YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), false, 0), +}; + +static void +drm_connector_hdmi_init_formats_yuv420_allowed_desc(const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *t, + char *desc) +{ + sprintf(desc, "supported_formats=0x%lx yuv420_allowed=%d", + t->supported_formats, t->yuv420_allowed); +} + +KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_formats_yuv420_allowed, + drm_connector_hdmi_init_formats_yuv420_allowed_tests, + drm_connector_hdmi_init_formats_yuv420_allowed_desc); + +/* + * Test that the registration of an HDMI connector succeeds only when + * the presence of YUV420 in the supported formats matches the value + * of the ycbcr_420_allowed flag. + */ +static void drm_test_connector_hdmi_init_formats_yuv420_allowed(struct kunit *test) +{ + const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *params; + struct drm_connector_init_priv *priv = test->priv; + int ret; + + params = test->param_value; + priv->connector.ycbcr_420_allowed = params->yuv420_allowed; + + ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, + "Vendor", "Product", + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + params->supported_formats, + 8); + KUNIT_EXPECT_EQ(test, ret, params->expected_result); +} + /* * Test that the registration of an HDMI connector with an HDMI * connector type succeeds. @@ -726,6 +1244,8 @@ static struct kunit_case drmm_connector_hdmi_init_tests[] = { KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null), KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty), KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb), + KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_formats_yuv420_allowed, + drm_connector_hdmi_init_formats_yuv420_allowed_gen_params), KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc), KUNIT_CASE(drm_test_connector_hdmi_init_null_product), KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor), @@ -1283,6 +1803,9 @@ static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = { kunit_test_suites( &drmm_connector_hdmi_init_test_suite, &drmm_connector_init_test_suite, + &drm_connector_dynamic_init_test_suite, + &drm_connector_dynamic_register_early_test_suite, + &drm_connector_dynamic_register_test_suite, &drm_connector_attach_broadcast_rgb_property_test_suite, &drm_get_tv_mode_from_name_test_suite, &drm_hdmi_compute_mode_clock_test_suite, diff --git a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c index 89cd9e4f4d32..9e0e2fb65944 100644 --- a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c +++ b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c @@ -199,10 +199,8 @@ static const struct drm_dp_mst_calc_pbn_div_test drm_dp_mst_calc_pbn_div_dp1_4_c static void drm_test_dp_mst_calc_pbn_div(struct kunit *test) { const struct drm_dp_mst_calc_pbn_div_test *params = test->param_value; - /* mgr->dev is only needed by drm_dbg_kms(), but it's not called for the test cases. */ - struct drm_dp_mst_topology_mgr *mgr = test->priv; - KUNIT_EXPECT_EQ(test, drm_dp_get_vc_payload_bw(mgr, params->link_rate, params->lane_count).full, + KUNIT_EXPECT_EQ(test, drm_dp_get_vc_payload_bw(params->link_rate, params->lane_count).full, params->expected.full); } @@ -568,21 +566,8 @@ static struct kunit_case drm_dp_mst_helper_tests[] = { { } }; -static int drm_dp_mst_helper_tests_init(struct kunit *test) -{ - struct drm_dp_mst_topology_mgr *mgr; - - mgr = kunit_kzalloc(test, sizeof(*mgr), GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mgr); - - test->priv = mgr; - - return 0; -} - static struct kunit_suite drm_dp_mst_helper_test_suite = { .name = "drm_dp_mst_helper", - .init = drm_dp_mst_helper_tests_init, .test_cases = drm_dp_mst_helper_tests, }; diff --git a/drivers/gpu/drm/tests/drm_format_helper_test.c b/drivers/gpu/drm/tests/drm_format_helper_test.c index 08992636ec05..35cd3405d045 100644 --- a/drivers/gpu/drm/tests/drm_format_helper_test.c +++ b/drivers/gpu/drm/tests/drm_format_helper_test.c @@ -60,6 +60,11 @@ struct convert_to_rgb888_result { const u8 expected[TEST_BUF_SIZE]; }; +struct convert_to_bgr888_result { + unsigned int dst_pitch; + const u8 expected[TEST_BUF_SIZE]; +}; + struct convert_to_argb8888_result { unsigned int dst_pitch; const u32 expected[TEST_BUF_SIZE]; @@ -107,6 +112,7 @@ struct convert_xrgb8888_case { struct convert_to_argb1555_result argb1555_result; struct convert_to_rgba5551_result rgba5551_result; struct convert_to_rgb888_result rgb888_result; + struct convert_to_bgr888_result bgr888_result; struct convert_to_argb8888_result argb8888_result; struct convert_to_xrgb2101010_result xrgb2101010_result; struct convert_to_argb2101010_result argb2101010_result; @@ -151,6 +157,10 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { .dst_pitch = TEST_USE_DEFAULT_PITCH, .expected = { 0x00, 0x00, 0xFF }, }, + .bgr888_result = { + .dst_pitch = TEST_USE_DEFAULT_PITCH, + .expected = { 0xFF, 0x00, 0x00 }, + }, .argb8888_result = { .dst_pitch = TEST_USE_DEFAULT_PITCH, .expected = { 0xFFFF0000 }, @@ -217,6 +227,10 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { .dst_pitch = TEST_USE_DEFAULT_PITCH, .expected = { 0x00, 0x00, 0xFF }, }, + .bgr888_result = { + .dst_pitch = TEST_USE_DEFAULT_PITCH, + .expected = { 0xFF, 0x00, 0x00 }, + }, .argb8888_result = { .dst_pitch = TEST_USE_DEFAULT_PITCH, .expected = { 0xFFFF0000 }, @@ -330,6 +344,15 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, }, }, + .bgr888_result = { + .dst_pitch = TEST_USE_DEFAULT_PITCH, + .expected = { + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, + 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, + }, + }, .argb8888_result = { .dst_pitch = TEST_USE_DEFAULT_PITCH, .expected = { @@ -468,6 +491,17 @@ static struct convert_xrgb8888_case convert_xrgb8888_cases[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, + .bgr888_result = { + .dst_pitch = 15, + .expected = { + 0x0E, 0x44, 0x9C, 0x11, 0x4D, 0x05, 0xA8, 0xF3, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6C, 0xF0, 0x73, 0x0E, 0x44, 0x9C, 0x11, 0x4D, 0x05, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xA8, 0x03, 0x03, 0x6C, 0xF0, 0x73, 0x0E, 0x44, 0x9C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + }, .argb8888_result = { .dst_pitch = 20, .expected = { @@ -914,6 +948,52 @@ static void drm_test_fb_xrgb8888_to_rgb888(struct kunit *test) KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); } +static void drm_test_fb_xrgb8888_to_bgr888(struct kunit *test) +{ + const struct convert_xrgb8888_case *params = test->param_value; + const struct convert_to_bgr888_result *result = ¶ms->bgr888_result; + size_t dst_size; + u8 *buf = NULL; + __le32 *xrgb8888 = NULL; + struct iosys_map dst, src; + + struct drm_framebuffer fb = { + .format = drm_format_info(DRM_FORMAT_XRGB8888), + .pitches = { params->pitch, 0, 0 }, + }; + + dst_size = conversion_buf_size(DRM_FORMAT_BGR888, result->dst_pitch, + ¶ms->clip, 0); + KUNIT_ASSERT_GT(test, dst_size, 0); + + buf = kunit_kzalloc(test, dst_size, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buf); + iosys_map_set_vaddr(&dst, buf); + + xrgb8888 = cpubuf_to_le32(test, params->xrgb8888, TEST_BUF_SIZE); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xrgb8888); + iosys_map_set_vaddr(&src, xrgb8888); + + /* + * BGR888 expected results are already in little-endian + * order, so there's no need to convert the test output. + */ + drm_fb_xrgb8888_to_bgr888(&dst, &result->dst_pitch, &src, &fb, ¶ms->clip, + &fmtcnv_state); + KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); + + buf = dst.vaddr; /* restore original value of buf */ + memset(buf, 0, dst_size); + + int blit_result = 0; + + blit_result = drm_fb_blit(&dst, &result->dst_pitch, DRM_FORMAT_BGR888, &src, &fb, ¶ms->clip, + &fmtcnv_state); + + KUNIT_EXPECT_FALSE(test, blit_result); + KUNIT_EXPECT_MEMEQ(test, buf, result->expected, dst_size); +} + static void drm_test_fb_xrgb8888_to_argb8888(struct kunit *test) { const struct convert_xrgb8888_case *params = test->param_value; @@ -1851,6 +1931,7 @@ static struct kunit_case drm_format_helper_test_cases[] = { KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb1555, convert_xrgb8888_gen_params), KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgba5551, convert_xrgb8888_gen_params), KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_rgb888, convert_xrgb8888_gen_params), + KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_bgr888, convert_xrgb8888_gen_params), KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb8888, convert_xrgb8888_gen_params), KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_xrgb2101010, convert_xrgb8888_gen_params), KUNIT_CASE_PARAM(drm_test_fb_xrgb8888_to_argb2101010, convert_xrgb8888_gen_params), diff --git a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c index 294773342e71..e97efd3af9ed 100644 --- a/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c +++ b/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c @@ -46,7 +46,7 @@ static struct drm_display_mode *find_preferred_mode(struct drm_connector *connec struct drm_display_mode *mode, *preferred; mutex_lock(&drm->mode_config.mutex); - preferred = list_first_entry(&connector->modes, struct drm_display_mode, head); + preferred = list_first_entry_or_null(&connector->modes, struct drm_display_mode, head); list_for_each_entry(mode, &connector->modes, head) if (mode->type & DRM_MODE_TYPE_PREFERRED) preferred = mode; @@ -70,10 +70,17 @@ static int light_up_connector(struct kunit *test, state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); +retry: conn_state = drm_atomic_get_connector_state(state, connector); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); ret = drm_atomic_set_crtc_for_connector(conn_state, crtc); + if (ret == -EDEADLK) { + drm_atomic_state_clear(state); + ret = drm_modeset_backoff(ctx); + if (!ret) + goto retry; + } KUNIT_EXPECT_EQ(test, ret, 0); crtc_state = drm_atomic_get_crtc_state(state, crtc); @@ -105,9 +112,8 @@ static int set_connector_edid(struct kunit *test, struct drm_connector *connecto mutex_lock(&drm->mode_config.mutex); ret = connector->funcs->fill_modes(connector, 4096, 4096); mutex_unlock(&drm->mode_config.mutex); - KUNIT_ASSERT_GT(test, ret, 0); - return 0; + return ret; } static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = { @@ -125,6 +131,18 @@ static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = { .tmds_char_rate_valid = reject_connector_tmds_char_rate_valid, }; +static enum drm_mode_status +reject_100MHz_connector_tmds_char_rate_valid(const struct drm_connector *connector, + const struct drm_display_mode *mode, + unsigned long long tmds_rate) +{ + return (tmds_rate > 100ULL * 1000 * 1000) ? MODE_BAD : MODE_OK; +} + +static const struct drm_connector_hdmi_funcs reject_100_MHz_connector_hdmi_funcs = { + .tmds_char_rate_valid = reject_100MHz_connector_tmds_char_rate_valid, +}; + static int dummy_connector_get_modes(struct drm_connector *connector) { struct drm_atomic_helper_connector_hdmi_priv *priv = @@ -147,6 +165,7 @@ static int dummy_connector_get_modes(struct drm_connector *connector) static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = { .atomic_check = drm_atomic_helper_connector_hdmi_check, .get_modes = dummy_connector_get_modes, + .mode_valid = drm_hdmi_connector_mode_valid, }; static void dummy_hdmi_connector_reset(struct drm_connector *connector) @@ -164,9 +183,10 @@ static const struct drm_connector_funcs dummy_connector_funcs = { static struct drm_atomic_helper_connector_hdmi_priv * -drm_atomic_helper_connector_hdmi_init(struct kunit *test, - unsigned int formats, - unsigned int max_bpc) +drm_kunit_helper_connector_hdmi_init_funcs(struct kunit *test, + unsigned int formats, + unsigned int max_bpc, + const struct drm_connector_hdmi_funcs *hdmi_funcs) { struct drm_atomic_helper_connector_hdmi_priv *priv; struct drm_connector *conn; @@ -208,7 +228,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, ret = drmm_connector_hdmi_init(drm, conn, "Vendor", "Product", &dummy_connector_funcs, - &dummy_connector_hdmi_funcs, + hdmi_funcs, DRM_MODE_CONNECTOR_HDMIA, NULL, formats, @@ -220,10 +240,27 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, drm_mode_config_reset(drm); - ret = set_connector_edid(test, conn, + return priv; +} + +static +struct drm_atomic_helper_connector_hdmi_priv * +drm_kunit_helper_connector_hdmi_init(struct kunit *test, + unsigned int formats, + unsigned int max_bpc) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + int ret; + + priv = drm_kunit_helper_connector_hdmi_init_funcs(test, + formats, max_bpc, + &dummy_connector_hdmi_funcs); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + + ret = set_connector_edid(test, &priv->connector, test_edid_hdmi_1080p_rgb_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0); return priv; } @@ -236,7 +273,7 @@ drm_atomic_helper_connector_hdmi_init(struct kunit *test, static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *old_conn_state; struct drm_connector_state *new_conn_state; struct drm_crtc_state *crtc_state; @@ -247,24 +284,24 @@ static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; + preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + 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, conn); @@ -289,6 +326,9 @@ static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test) crtc_state = drm_atomic_get_new_crtc_state(state, crtc); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -299,7 +339,7 @@ static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test) static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *old_conn_state; struct drm_connector_state *new_conn_state; struct drm_crtc_state *crtc_state; @@ -310,24 +350,24 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; + preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + 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, conn); @@ -354,6 +394,9 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes crtc_state = drm_atomic_get_new_crtc_state(state, crtc); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -364,7 +407,7 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_atomic_state *state; struct drm_display_mode *preferred; @@ -373,27 +416,26 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); conn_state = drm_atomic_get_connector_state(state, conn); @@ -410,6 +452,9 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test) KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -420,7 +465,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test) static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_atomic_state *state; struct drm_display_mode *mode; @@ -429,27 +474,25 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); drm = &priv->drm; conn = &priv->connector; KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + drm_modeset_acquire_init(&ctx, 0); mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); KUNIT_ASSERT_NOT_NULL(test, mode); - drm = &priv->drm; crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, mode, ctx); + ret = light_up_connector(test, drm, crtc, conn, mode, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); conn_state = drm_atomic_get_connector_state(state, conn); @@ -466,6 +509,9 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test) KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -476,7 +522,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test) static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_atomic_state *state; struct drm_display_mode *preferred; @@ -485,27 +531,26 @@ static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); conn_state = drm_atomic_get_connector_state(state, conn); @@ -524,6 +569,9 @@ static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test) DRM_HDMI_BROADCAST_RGB_FULL); KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -534,7 +582,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test) static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_atomic_state *state; struct drm_display_mode *mode; @@ -543,27 +591,25 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); drm = &priv->drm; conn = &priv->connector; KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + drm_modeset_acquire_init(&ctx, 0); mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); KUNIT_ASSERT_NOT_NULL(test, mode); - drm = &priv->drm; crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, mode, ctx); + ret = light_up_connector(test, drm, crtc, conn, mode, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); conn_state = drm_atomic_get_connector_state(state, conn); @@ -582,6 +628,9 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test) DRM_HDMI_BROADCAST_RGB_FULL); KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -592,7 +641,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test) static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_atomic_state *state; struct drm_display_mode *preferred; @@ -601,27 +650,26 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); conn_state = drm_atomic_get_connector_state(state, conn); @@ -640,6 +688,9 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test) DRM_HDMI_BROADCAST_RGB_LIMITED); KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -650,7 +701,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test) static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_atomic_state *state; struct drm_display_mode *mode; @@ -659,27 +710,25 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); drm = &priv->drm; conn = &priv->connector; KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + drm_modeset_acquire_init(&ctx, 0); mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); KUNIT_ASSERT_NOT_NULL(test, mode); - drm = &priv->drm; crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, mode, ctx); + ret = light_up_connector(test, drm, crtc, conn, mode, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); conn_state = drm_atomic_get_connector_state(state, conn); @@ -698,6 +747,9 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te DRM_HDMI_BROADCAST_RGB_LIMITED); KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -708,7 +760,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *old_conn_state; struct drm_connector_state *new_conn_state; struct drm_crtc_state *crtc_state; @@ -719,29 +771,28 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 10); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); - - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + KUNIT_ASSERT_GT(test, ret, 0); preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + 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, conn); @@ -772,6 +823,9 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) crtc_state = drm_atomic_get_new_crtc_state(state, crtc); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -782,7 +836,7 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *old_conn_state; struct drm_connector_state *new_conn_state; struct drm_crtc_state *crtc_state; @@ -793,29 +847,28 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 10); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); - - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + KUNIT_ASSERT_GT(test, ret, 0); preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + 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, conn); @@ -844,6 +897,9 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) crtc_state = drm_atomic_get_new_crtc_state(state, crtc); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -853,7 +909,7 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) static void drm_test_check_output_bpc_dvi(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_info *info; struct drm_display_mode *preferred; @@ -862,31 +918,30 @@ static void drm_test_check_output_bpc_dvi(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB) | - BIT(HDMI_COLORSPACE_YUV422) | - BIT(HDMI_COLORSPACE_YUV444), - 12); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_dvi_1080p, ARRAY_SIZE(test_edid_dvi_1080p)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0); info = &conn->display_info; KUNIT_ASSERT_FALSE(test, info->is_hdmi); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); conn_state = conn->state; @@ -894,6 +949,9 @@ static void drm_test_check_output_bpc_dvi(struct kunit *test) KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -903,7 +961,7 @@ static void drm_test_check_output_bpc_dvi(struct kunit *test) static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_mode *preferred; struct drm_connector *conn; @@ -911,27 +969,26 @@ static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); - - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + KUNIT_ASSERT_GT(test, ret, 0); preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); conn_state = conn->state; @@ -940,6 +997,9 @@ static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test) KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8); KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -950,7 +1010,7 @@ static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test) static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_mode *preferred; struct drm_connector *conn; @@ -958,27 +1018,26 @@ static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 10); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); - - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + KUNIT_ASSERT_GT(test, ret, 0); preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); conn_state = conn->state; @@ -987,6 +1046,9 @@ static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test) KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10); KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -997,7 +1059,7 @@ static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test) static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_mode *preferred; struct drm_connector *conn; @@ -1005,27 +1067,26 @@ static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 12); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); - - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + KUNIT_ASSERT_GT(test, ret, 0); preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); conn_state = conn->state; @@ -1034,6 +1095,9 @@ static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test) KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12); KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -1047,7 +1111,7 @@ static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test) static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_atomic_state *state; struct drm_display_mode *preferred; struct drm_crtc_state *crtc_state; @@ -1056,27 +1120,27 @@ static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; + preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_ASSERT_EQ(test, ret, 0); /* You shouldn't be doing that at home. */ conn->hdmi.funcs = &reject_connector_hdmi_funcs; - state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx); + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); crtc_state = drm_atomic_get_crtc_state(state, crtc); @@ -1086,6 +1150,9 @@ static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test) ret = drm_atomic_check_only(state); KUNIT_EXPECT_LT(test, ret, 0); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -1102,7 +1169,7 @@ static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test) static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_info *info; struct drm_display_mode *preferred; @@ -1112,24 +1179,23 @@ static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 12); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0); info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); @@ -1140,9 +1206,9 @@ static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test) rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB); KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_EXPECT_EQ(test, ret, 0); conn_state = conn->state; @@ -1151,6 +1217,9 @@ static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test) KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10); KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -1169,7 +1238,7 @@ static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test) static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_info *info; struct drm_display_mode *preferred; @@ -1179,26 +1248,25 @@ static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB) | - BIT(HDMI_COLORSPACE_YUV422) | - BIT(HDMI_COLORSPACE_YUV444), - 12); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0); info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); @@ -1212,9 +1280,9 @@ static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test) rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422); KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_EXPECT_EQ(test, ret, 0); conn_state = conn->state; @@ -1222,6 +1290,9 @@ static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test) KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10); KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -1232,7 +1303,7 @@ static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test) static void drm_test_check_output_bpc_format_vic_1(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_info *info; struct drm_display_mode *mode; @@ -1242,11 +1313,11 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB) | - BIT(HDMI_COLORSPACE_YUV422) | - BIT(HDMI_COLORSPACE_YUV444), - 12); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); drm = &priv->drm; @@ -1254,15 +1325,12 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test) ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0); info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); KUNIT_ASSERT_NOT_NULL(test, mode); @@ -1276,9 +1344,10 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test) rate = mode->clock * 1500; KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); - drm = &priv->drm; + drm_modeset_acquire_init(&ctx, 0); + crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, mode, ctx); + ret = light_up_connector(test, drm, crtc, conn, mode, &ctx); KUNIT_EXPECT_EQ(test, ret, 0); conn_state = conn->state; @@ -1286,6 +1355,9 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test) KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -1295,7 +1367,7 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test) static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_info *info; struct drm_display_mode *preferred; @@ -1305,24 +1377,23 @@ static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test) struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 12); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0); info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); @@ -1341,9 +1412,9 @@ static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test) rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422); KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_EXPECT_EQ(test, ret, 0); conn_state = conn->state; @@ -1351,6 +1422,9 @@ static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test) KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12); KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -1360,7 +1434,7 @@ static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test) static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_info *info; struct drm_display_mode *preferred; @@ -1370,26 +1444,25 @@ static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB) | - BIT(HDMI_COLORSPACE_YUV422) | - BIT(HDMI_COLORSPACE_YUV444), - 12); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_max_200mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0); info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); @@ -1408,9 +1481,9 @@ static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422); KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_EXPECT_EQ(test, ret, 0); conn_state = conn->state; @@ -1418,6 +1491,9 @@ static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12); KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -1428,7 +1504,7 @@ static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_info *info; struct drm_display_mode *preferred; @@ -1438,24 +1514,23 @@ static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0); info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); @@ -1466,9 +1541,9 @@ static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_EXPECT_EQ(test, ret, 0); conn_state = conn->state; @@ -1476,6 +1551,9 @@ static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } /* @@ -1486,7 +1564,7 @@ static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *test) { struct drm_atomic_helper_connector_hdmi_priv *priv; - struct drm_modeset_acquire_ctx *ctx; + struct drm_modeset_acquire_ctx ctx; struct drm_connector_state *conn_state; struct drm_display_info *info; struct drm_display_mode *preferred; @@ -1496,26 +1574,25 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes struct drm_crtc *crtc; int ret; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB) | - BIT(HDMI_COLORSPACE_YUV422) | - BIT(HDMI_COLORSPACE_YUV444), - 12); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); + drm = &priv->drm; + crtc = priv->crtc; conn = &priv->connector; ret = set_connector_edid(test, conn, test_edid_hdmi_1080p_rgb_max_340mhz, ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz)); - KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_ASSERT_GT(test, ret, 0); info = &conn->display_info; KUNIT_ASSERT_TRUE(test, info->is_hdmi); KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); - ctx = drm_kunit_helper_acquire_ctx_alloc(test); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); - preferred = find_preferred_mode(conn); KUNIT_ASSERT_NOT_NULL(test, preferred); @@ -1526,9 +1603,9 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); - drm = &priv->drm; - crtc = priv->crtc; - ret = light_up_connector(test, drm, crtc, conn, preferred, ctx); + drm_modeset_acquire_init(&ctx, 0); + + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); KUNIT_EXPECT_EQ(test, ret, 0); conn_state = conn->state; @@ -1536,6 +1613,62 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +/* Test that atomic check succeeds when disabling a connector. */ +static void drm_test_check_disable_connector(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_modeset_acquire_ctx ctx; + struct drm_connector_state *conn_state; + struct drm_crtc_state *crtc_state; + struct drm_atomic_state *state; + struct drm_display_mode *preferred; + struct drm_connector *conn; + struct drm_device *drm; + struct drm_crtc *crtc; + int ret; + + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_ASSERT_NOT_NULL(test, priv); + + drm_modeset_acquire_init(&ctx, 0); + + conn = &priv->connector; + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + drm = &priv->drm; + crtc = priv->crtc; + ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx); + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + crtc_state = drm_atomic_get_crtc_state(state, crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); + + crtc_state->active = false; + ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL); + KUNIT_EXPECT_EQ(test, ret, 0); + + conn_state = drm_atomic_get_connector_state(state, conn); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); + + ret = drm_atomic_set_crtc_for_connector(conn_state, NULL); + KUNIT_EXPECT_EQ(test, ret, 0); + + ret = drm_atomic_check_only(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); } static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { @@ -1552,6 +1685,7 @@ static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { */ KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed), KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed), + KUNIT_CASE(drm_test_check_disable_connector), KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate), KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback), KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback), @@ -1593,9 +1727,9 @@ static void drm_test_check_broadcast_rgb_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -1615,9 +1749,9 @@ static void drm_test_check_bpc_8_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -1639,9 +1773,9 @@ static void drm_test_check_bpc_10_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 10); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 10); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -1663,9 +1797,9 @@ static void drm_test_check_bpc_12_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB), - 12); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -1685,11 +1819,11 @@ static void drm_test_check_format_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB) | - BIT(HDMI_COLORSPACE_YUV422) | - BIT(HDMI_COLORSPACE_YUV444), - 8); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 8); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -1707,11 +1841,11 @@ static void drm_test_check_tmds_char_value(struct kunit *test) struct drm_connector_state *conn_state; struct drm_connector *conn; - priv = drm_atomic_helper_connector_hdmi_init(test, - BIT(HDMI_COLORSPACE_RGB) | - BIT(HDMI_COLORSPACE_YUV422) | - BIT(HDMI_COLORSPACE_YUV444), - 12); + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB) | + BIT(HDMI_COLORSPACE_YUV422) | + BIT(HDMI_COLORSPACE_YUV444), + 12); KUNIT_ASSERT_NOT_NULL(test, priv); conn = &priv->connector; @@ -1734,9 +1868,148 @@ static struct kunit_suite drm_atomic_helper_connector_hdmi_reset_test_suite = { .test_cases = drm_atomic_helper_connector_hdmi_reset_tests, }; +/* + * Test that the default behaviour for drm_hdmi_connector_mode_valid() is not + * to reject any modes. Pass a correct EDID and verify that preferred mode + * matches the expectations (1080p). + */ +static void drm_test_check_mode_valid(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector *conn; + struct drm_display_mode *preferred; + + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + + KUNIT_EXPECT_EQ(test, preferred->hdisplay, 1920); + KUNIT_EXPECT_EQ(test, preferred->vdisplay, 1080); + KUNIT_EXPECT_EQ(test, preferred->clock, 148500); +} + +/* + * Test that the drm_hdmi_connector_mode_valid() will reject modes depending on + * the .tmds_char_rate_valid() behaviour. + * Pass a correct EDID and verify that high-rate modes are filtered. + */ +static void drm_test_check_mode_valid_reject_rate(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector *conn; + struct drm_display_mode *preferred; + int ret; + + priv = drm_kunit_helper_connector_hdmi_init_funcs(test, + BIT(HDMI_COLORSPACE_RGB), + 8, + &reject_100_MHz_connector_hdmi_funcs); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); + KUNIT_ASSERT_GT(test, ret, 0); + + /* + * Unlike the drm_test_check_mode_valid() here 1080p is rejected, but + * 480p is allowed. + */ + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + KUNIT_EXPECT_EQ(test, preferred->hdisplay, 640); + KUNIT_EXPECT_EQ(test, preferred->vdisplay, 480); + KUNIT_EXPECT_EQ(test, preferred->clock, 25200); +} + +/* + * Test that the drm_hdmi_connector_mode_valid() will not mark any modes as + * valid if .tmds_char_rate_valid() rejects all of them. Pass a correct EDID + * and verify that there is no preferred mode and no modes were set for the + * connector. + */ +static void drm_test_check_mode_valid_reject(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector *conn; + struct drm_display_mode *preferred; + int ret; + + priv = drm_kunit_helper_connector_hdmi_init_funcs(test, + BIT(HDMI_COLORSPACE_RGB), + 8, + &reject_connector_hdmi_funcs); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + + /* should reject all modes */ + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_max_200mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); + KUNIT_ASSERT_EQ(test, ret, 0); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NULL(test, preferred); +} + +/* + * Test that the drm_hdmi_connector_mode_valid() will reject modes that don't + * pass the info.max_tmds_clock filter. Pass crafted EDID and verify that + * high-rate modes are filtered. + */ +static void drm_test_check_mode_valid_reject_max_clock(struct kunit *test) +{ + struct drm_atomic_helper_connector_hdmi_priv *priv; + struct drm_connector *conn; + struct drm_display_mode *preferred; + int ret; + + priv = drm_kunit_helper_connector_hdmi_init(test, + BIT(HDMI_COLORSPACE_RGB), + 8); + KUNIT_ASSERT_NOT_NULL(test, priv); + + conn = &priv->connector; + + ret = set_connector_edid(test, conn, + test_edid_hdmi_1080p_rgb_max_100mhz, + ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_100mhz)); + KUNIT_ASSERT_GT(test, ret, 0); + + KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 100 * 1000); + + preferred = find_preferred_mode(conn); + KUNIT_ASSERT_NOT_NULL(test, preferred); + KUNIT_EXPECT_EQ(test, preferred->hdisplay, 640); + KUNIT_EXPECT_EQ(test, preferred->vdisplay, 480); + KUNIT_EXPECT_EQ(test, preferred->clock, 25200); +} + +static struct kunit_case drm_atomic_helper_connector_hdmi_mode_valid_tests[] = { + KUNIT_CASE(drm_test_check_mode_valid), + KUNIT_CASE(drm_test_check_mode_valid_reject), + KUNIT_CASE(drm_test_check_mode_valid_reject_rate), + KUNIT_CASE(drm_test_check_mode_valid_reject_max_clock), + { } +}; + +static struct kunit_suite drm_atomic_helper_connector_hdmi_mode_valid_test_suite = { + .name = "drm_atomic_helper_connector_hdmi_mode_valid", + .test_cases = drm_atomic_helper_connector_hdmi_mode_valid_tests, +}; + kunit_test_suites( &drm_atomic_helper_connector_hdmi_check_test_suite, &drm_atomic_helper_connector_hdmi_reset_test_suite, + &drm_atomic_helper_connector_hdmi_mode_valid_test_suite, ); MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>"); diff --git a/drivers/gpu/drm/tests/drm_kunit_edid.h b/drivers/gpu/drm/tests/drm_kunit_edid.h index 107559900e97..6358397a5d7a 100644 --- a/drivers/gpu/drm/tests/drm_kunit_edid.h +++ b/drivers/gpu/drm/tests/drm_kunit_edid.h @@ -74,6 +74,108 @@ static const unsigned char test_edid_dvi_1080p[] = { * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92 * * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c + * 00 12 34 00 14 20 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 e4 + * + * ---------------- + * + * Block 0, Base EDID: + * EDID Structure Version & Revision: 1.3 + * Vendor & Product Identification: + * Manufacturer: LNX + * Model: 42 + * Made in: 2023 + * Basic Display Parameters & Features: + * Digital display + * DFP 1.x compatible TMDS + * Maximum image size: 160 cm x 90 cm + * Gamma: 2.20 + * Monochrome or grayscale display + * First detailed timing is the preferred timing + * Color Characteristics: + * Red : 0.0000, 0.0000 + * Green: 0.0000, 0.0000 + * Blue : 0.0000, 0.0000 + * White: 0.0000, 0.0000 + * Established Timings I & II: + * DMT 0x04: 640x480 59.940476 Hz 4:3 31.469 kHz 25.175000 MHz + * Standard Timings: none + * Detailed Timing Descriptors: + * DTD 1: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz (1600 mm x 900 mm) + * Hfront 88 Hsync 44 Hback 148 Hpol P + * Vfront 4 Vsync 5 Vback 36 Vpol P + * Display Product Name: 'Test EDID' + * Display Range Limits: + * Monitor ranges (GTF): 50-70 Hz V, 30-70 kHz H, max dotclock 150 MHz + * Dummy Descriptor: + * Extension blocks: 1 + * Checksum: 0x92 + * + * ---------------- + * + * Block 1, CTA-861 Extension Block: + * Revision: 3 + * Underscans IT Video Formats by default + * Native detailed modes: 1 + * Colorimetry Data Block: + * sRGB + * Video Data Block: + * VIC 16: 1920x1080 60.000000 Hz 16:9 67.500 kHz 148.500000 MHz + * Video Capability Data Block: + * YCbCr quantization: No Data + * RGB quantization: Selectable (via AVI Q) + * PT scan behavior: No Data + * IT scan behavior: Always Underscanned + * CE scan behavior: Always Underscanned + * Vendor-Specific Data Block (HDMI), OUI 00-0C-03: + * Source physical address: 1.2.3.4 + * Maximum TMDS clock: 100 MHz + * Extended HDMI video details: + * Checksum: 0xe4 Unused space in Extension Block: 100 bytes + */ +static const unsigned char test_edid_hdmi_1080p_rgb_max_100mhz[] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x31, 0xd8, 0x2a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x01, 0x03, 0x81, 0xa0, 0x5a, 0x78, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, + 0x2d, 0x40, 0x58, 0x2c, 0x45, 0x00, 0x40, 0x84, 0x63, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0xfc, 0x00, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x44, + 0x49, 0x44, 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x32, + 0x46, 0x00, 0x00, 0xc4, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x02, 0x03, 0x1b, 0x81, + 0xe3, 0x05, 0x00, 0x20, 0x41, 0x10, 0xe2, 0x00, 0x4a, 0x6d, 0x03, 0x0c, + 0x00, 0x12, 0x34, 0x00, 0x14, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xe4 +}; + +/* + * edid-decode (hex): + * + * 00 ff ff ff ff ff ff 00 31 d8 2a 00 00 00 00 00 + * 00 21 01 03 81 a0 5a 78 02 00 00 00 00 00 00 00 + * 00 00 00 20 00 00 01 01 01 01 01 01 01 01 01 01 + * 01 01 01 01 01 01 02 3a 80 18 71 38 2d 40 58 2c + * 45 00 40 84 63 00 00 1e 00 00 00 fc 00 54 65 73 + * 74 20 45 44 49 44 0a 20 20 20 00 00 00 fd 00 32 + * 46 1e 46 0f 00 0a 20 20 20 20 20 20 00 00 00 10 + * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 92 + * + * 02 03 1b 81 e3 05 00 20 41 10 e2 00 4a 6d 03 0c * 00 12 34 00 28 20 00 00 00 00 00 00 00 00 00 00 * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 * 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c index 04a6b8cc62ac..a4eb68f0decc 100644 --- a/drivers/gpu/drm/tests/drm_kunit_helpers.c +++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c @@ -80,47 +80,6 @@ __drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test, } EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver); -static void action_drm_release_context(void *ptr) -{ - struct drm_modeset_acquire_ctx *ctx = ptr; - - drm_modeset_drop_locks(ctx); - drm_modeset_acquire_fini(ctx); -} - -/** - * drm_kunit_helper_acquire_ctx_alloc - Allocates an acquire context - * @test: The test context object - * - * Allocates and initializes a modeset acquire context. - * - * The context is tied to the kunit test context, so we must not call - * drm_modeset_acquire_fini() on it, it will be done so automatically. - * - * Returns: - * An ERR_PTR on error, a pointer to the newly allocated context otherwise - */ -struct drm_modeset_acquire_ctx * -drm_kunit_helper_acquire_ctx_alloc(struct kunit *test) -{ - struct drm_modeset_acquire_ctx *ctx; - int ret; - - ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); - KUNIT_ASSERT_NOT_NULL(test, ctx); - - drm_modeset_acquire_init(ctx, 0); - - ret = kunit_add_action_or_reset(test, - action_drm_release_context, - ctx); - if (ret) - return ERR_PTR(ret); - - return ctx; -} -EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc); - static void kunit_action_drm_atomic_state_put(void *ptr) { struct drm_atomic_state *state = ptr; @@ -320,8 +279,7 @@ static void kunit_action_drm_mode_destroy(void *ptr) } /** - * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC - for a KUnit test + * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC for a KUnit test * @test: The test context object * @dev: DRM device * @video_code: CEA VIC of the mode |