Add KUnit tests for drmm_connector_hdmi_init_with_caps() covering NULL caps rejection, the max_tmds_char_rate inferred from each advertised HDMI specification version, and the validation of a driver-provided max_tmds_char_rate against the version-inferred limit: override below, accept at, reject above, reject when no version is advertised.
Signed-off-by: Cristian Ciocaltea <[email protected]> --- drivers/gpu/drm/tests/drm_connector_test.c | 189 +++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/drivers/gpu/drm/tests/drm_connector_test.c b/drivers/gpu/drm/tests/drm_connector_test.c index beb1d50a6646..1fb1d83aec1a 100644 --- a/drivers/gpu/drm/tests/drm_connector_test.c +++ b/drivers/gpu/drm/tests/drm_connector_test.c @@ -1254,6 +1254,188 @@ KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid, drm_connector_hdmi_init_type_invalid_tests, drm_connector_hdmi_init_type_desc); +/* + * Test that the registration of an HDMI connector with a NULL caps fails. + */ +static void drm_test_connector_hdmi_init_null_caps(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + int ret; + + ret = drmm_connector_hdmi_init_with_caps(&priv->drm, &priv->connector, + "Vendor", "Product", + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + NULL); + KUNIT_EXPECT_LT(test, ret, 0); +} + +/* + * Test that the registration of an HDMI connector without an explicit max TMDS + * character rate being provided succeeds, and the connector limit is inferred + * from the advertised HDMI specification version. + */ +struct drm_connector_hdmi_init_max_tmds_rate_inferred_case { + const char *desc; + enum hdmi_version ver; + unsigned long long expected; +}; + +static void drm_test_connector_hdmi_init_max_tmds_rate_inferred(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + const struct drm_connector_hdmi_init_max_tmds_rate_inferred_case *param = + test->param_value; + struct drm_connector_hdmi_caps caps = { + .supported_hdmi_ver = param->ver, + .supported_formats = BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444), + .max_bpc = 8, + }; + int ret; + + ret = drmm_connector_hdmi_init_with_caps(&priv->drm, &priv->connector, + "Vendor", "Product", + &dummy_funcs, + &dummy_hdmi_funcs_scrambler, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + &caps); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, priv->connector.hdmi.max_tmds_char_rate, + param->expected); +} + +static const struct drm_connector_hdmi_init_max_tmds_rate_inferred_case +drm_connector_hdmi_init_max_tmds_rate_inferred_tests[] = { + { "unknown", HDMI_VERSION_UNKNOWN, 0 }, + { "1.0", HDMI_VERSION_1_0, HDMI_1_0_TMDS_CHAR_RATE_MAX_HZ }, + { "1.2", HDMI_VERSION_1_2, HDMI_1_0_TMDS_CHAR_RATE_MAX_HZ }, + { "1.3", HDMI_VERSION_1_3, HDMI_1_3_TMDS_CHAR_RATE_MAX_HZ }, + { "1.4", HDMI_VERSION_1_4, HDMI_1_3_TMDS_CHAR_RATE_MAX_HZ }, + { "2.0", HDMI_VERSION_2_0, HDMI_2_0_TMDS_CHAR_RATE_MAX_HZ }, +}; + +static void drm_connector_hdmi_init_max_tmds_rate_inferred_desc( + const struct drm_connector_hdmi_init_max_tmds_rate_inferred_case *t, + char *desc) +{ + strscpy(desc, t->desc, KUNIT_PARAM_DESC_SIZE); +} + +KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_max_tmds_rate_inferred, + drm_connector_hdmi_init_max_tmds_rate_inferred_tests, + drm_connector_hdmi_init_max_tmds_rate_inferred_desc); + +/* + * Test that the registration of an HDMI connector providing a max TMDS + * character rate strictly below the version-inferred limit succeeds, and + * the connector limit is overridden. + */ +static void drm_test_connector_hdmi_init_max_tmds_rate_override(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector_hdmi_caps caps = { + .supported_hdmi_ver = HDMI_VERSION_2_0, + .supported_formats = BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444), + .max_bpc = 8, + .max_tmds_char_rate = HDMI_1_3_TMDS_CHAR_RATE_MAX_HZ, + }; + int ret; + + ret = drmm_connector_hdmi_init_with_caps(&priv->drm, &priv->connector, + "Vendor", "Product", + &dummy_funcs, + &dummy_hdmi_funcs_scrambler, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + &caps); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, priv->connector.hdmi.max_tmds_char_rate, + HDMI_1_3_TMDS_CHAR_RATE_MAX_HZ); +} + +/* + * Test that the registration of an HDMI connector providing a max TMDS + * character rate equal to the version-inferred limit succeeds. + */ +static void drm_test_connector_hdmi_init_max_tmds_rate_at_limit(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector_hdmi_caps caps = { + .supported_hdmi_ver = HDMI_VERSION_2_0, + .supported_formats = BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444), + .max_bpc = 8, + .max_tmds_char_rate = HDMI_2_0_TMDS_CHAR_RATE_MAX_HZ, + }; + int ret; + + ret = drmm_connector_hdmi_init_with_caps(&priv->drm, &priv->connector, + "Vendor", "Product", + &dummy_funcs, + &dummy_hdmi_funcs_scrambler, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + &caps); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, priv->connector.hdmi.max_tmds_char_rate, + HDMI_2_0_TMDS_CHAR_RATE_MAX_HZ); +} + +/* + * Test that the registration of an HDMI connector providing a max TMDS + * character rate that exceeds the limit inferred from the advertised HDMI + * specification version fails. + */ +static void drm_test_connector_hdmi_init_max_tmds_rate_exceeds(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector_hdmi_caps caps = { + .supported_hdmi_ver = HDMI_VERSION_1_4, + .supported_formats = BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444), + .max_bpc = 8, + .max_tmds_char_rate = HDMI_2_0_TMDS_CHAR_RATE_MAX_HZ, + }; + int ret; + + ret = drmm_connector_hdmi_init_with_caps(&priv->drm, &priv->connector, + "Vendor", "Product", + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + &caps); + KUNIT_EXPECT_LT(test, ret, 0); +} + +/* + * Test that the registration of an HDMI connector providing a non-zero max + * TMDS character rate without an HDMI specification version fails, as the + * version-inferred limit defaults to zero and any positive override would + * exceed it. + */ +static void drm_test_connector_hdmi_init_max_tmds_rate_no_version(struct kunit *test) +{ + struct drm_connector_init_priv *priv = test->priv; + struct drm_connector_hdmi_caps caps = { + .supported_hdmi_ver = HDMI_VERSION_UNKNOWN, + .supported_formats = BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444), + .max_bpc = 8, + .max_tmds_char_rate = HDMI_1_0_TMDS_CHAR_RATE_MAX_HZ, + }; + int ret; + + ret = drmm_connector_hdmi_init_with_caps(&priv->drm, &priv->connector, + "Vendor", "Product", + &dummy_funcs, + &dummy_hdmi_funcs, + DRM_MODE_CONNECTOR_HDMIA, + &priv->ddc, + &caps); + KUNIT_EXPECT_LT(test, ret, 0); +} + static struct kunit_case drmm_connector_hdmi_init_tests[] = { KUNIT_CASE(drm_test_connector_hdmi_init_valid), KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8), @@ -1278,6 +1460,13 @@ static struct kunit_case drmm_connector_hdmi_init_tests[] = { drm_connector_hdmi_init_type_valid_gen_params), KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid, drm_connector_hdmi_init_type_invalid_gen_params), + KUNIT_CASE(drm_test_connector_hdmi_init_null_caps), + KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_max_tmds_rate_inferred, + drm_connector_hdmi_init_max_tmds_rate_inferred_gen_params), + KUNIT_CASE(drm_test_connector_hdmi_init_max_tmds_rate_override), + KUNIT_CASE(drm_test_connector_hdmi_init_max_tmds_rate_at_limit), + KUNIT_CASE(drm_test_connector_hdmi_init_max_tmds_rate_exceeds), + KUNIT_CASE(drm_test_connector_hdmi_init_max_tmds_rate_no_version), { } }; -- 2.54.0
