Skip to content

Commit

Permalink
drm/tests: Add RGB Quantization tests
Browse files Browse the repository at this point in the history
The previous commit added the infrastructure to the connector state to
track what RGB Quantization should be used in a given state for an HDMI
connector.

Let's add some kunit tests to make sure it works as expected.

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-21-c5af16c3aae2@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>
  • Loading branch information
Maxime Ripard committed May 28, 2024
1 parent 027d435 commit 4af70f1
Showing 1 changed file with 355 additions and 0 deletions.
355 changes: 355 additions & 0 deletions drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,350 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes
KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
}

/*
* Test that for an HDMI connector, with an HDMI monitor, if the
* Broadcast RGB property is set to auto with a mode that isn't the
* VIC-1 mode, we will get a limited RGB Quantization Range.
*/
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_connector_state *conn_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_atomic_helper_connector_hdmi_init(test,
BIT(HDMI_COLORSPACE_RGB),
8);
KUNIT_ASSERT_NOT_NULL(test, priv);

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);
KUNIT_ASSERT_EQ(test, ret, 0);

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);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

KUNIT_ASSERT_EQ(test,
conn_state->hdmi.broadcast_rgb,
DRM_HDMI_BROADCAST_RGB_AUTO);

ret = drm_atomic_check_only(state);
KUNIT_ASSERT_EQ(test, ret, 0);

conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
}

/*
* Test that for an HDMI connector, with an HDMI monitor, if the
* Broadcast RGB property is set to auto with a VIC-1 mode, we will get
* a full RGB Quantization Range.
*/
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_connector_state *conn_state;
struct drm_atomic_state *state;
struct drm_display_mode *mode;
struct drm_connector *conn;
struct drm_device *drm;
struct drm_crtc *crtc;
int ret;

priv = drm_atomic_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);

mode = drm_display_mode_from_cea_vic(drm, 1);
KUNIT_ASSERT_NOT_NULL(test, mode);

drm = &priv->drm;
crtc = priv->crtc;
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);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);

conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

KUNIT_ASSERT_EQ(test,
conn_state->hdmi.broadcast_rgb,
DRM_HDMI_BROADCAST_RGB_AUTO);

ret = drm_atomic_check_only(state);
KUNIT_ASSERT_EQ(test, ret, 0);

conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
}

/*
* Test that for an HDMI connector, with an HDMI monitor, if the
* Broadcast RGB property is set to full with a mode that isn't the
* VIC-1 mode, we will get a full RGB Quantization Range.
*/
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_connector_state *conn_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_atomic_helper_connector_hdmi_init(test,
BIT(HDMI_COLORSPACE_RGB),
8);
KUNIT_ASSERT_NOT_NULL(test, priv);

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);
KUNIT_ASSERT_EQ(test, ret, 0);

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);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;

ret = drm_atomic_check_only(state);
KUNIT_ASSERT_EQ(test, ret, 0);

conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

KUNIT_ASSERT_EQ(test,
conn_state->hdmi.broadcast_rgb,
DRM_HDMI_BROADCAST_RGB_FULL);

KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
}

/*
* Test that for an HDMI connector, with an HDMI monitor, if the
* Broadcast RGB property is set to full with a VIC-1 mode, we will get
* a full RGB Quantization Range.
*/
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_connector_state *conn_state;
struct drm_atomic_state *state;
struct drm_display_mode *mode;
struct drm_connector *conn;
struct drm_device *drm;
struct drm_crtc *crtc;
int ret;

priv = drm_atomic_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);

mode = drm_display_mode_from_cea_vic(drm, 1);
KUNIT_ASSERT_NOT_NULL(test, mode);

drm = &priv->drm;
crtc = priv->crtc;
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);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);

conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;

ret = drm_atomic_check_only(state);
KUNIT_ASSERT_EQ(test, ret, 0);

conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

KUNIT_ASSERT_EQ(test,
conn_state->hdmi.broadcast_rgb,
DRM_HDMI_BROADCAST_RGB_FULL);

KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
}

/*
* Test that for an HDMI connector, with an HDMI monitor, if the
* Broadcast RGB property is set to limited with a mode that isn't the
* VIC-1 mode, we will get a limited RGB Quantization Range.
*/
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_connector_state *conn_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_atomic_helper_connector_hdmi_init(test,
BIT(HDMI_COLORSPACE_RGB),
8);
KUNIT_ASSERT_NOT_NULL(test, priv);

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);
KUNIT_ASSERT_EQ(test, ret, 0);

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);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;

ret = drm_atomic_check_only(state);
KUNIT_ASSERT_EQ(test, ret, 0);

conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

KUNIT_ASSERT_EQ(test,
conn_state->hdmi.broadcast_rgb,
DRM_HDMI_BROADCAST_RGB_LIMITED);

KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
}

/*
* Test that for an HDMI connector, with an HDMI monitor, if the
* Broadcast RGB property is set to limited with a VIC-1 mode, we will
* get a limited RGB Quantization Range.
*/
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_connector_state *conn_state;
struct drm_atomic_state *state;
struct drm_display_mode *mode;
struct drm_connector *conn;
struct drm_device *drm;
struct drm_crtc *crtc;
int ret;

priv = drm_atomic_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);

mode = drm_display_mode_from_cea_vic(drm, 1);
KUNIT_ASSERT_NOT_NULL(test, mode);

drm = &priv->drm;
crtc = priv->crtc;
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);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);

conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;

ret = drm_atomic_check_only(state);
KUNIT_ASSERT_EQ(test, ret, 0);

conn_state = drm_atomic_get_connector_state(state, conn);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);

KUNIT_ASSERT_EQ(test,
conn_state->hdmi.broadcast_rgb,
DRM_HDMI_BROADCAST_RGB_LIMITED);

KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
}

/*
* Test that if we change the maximum bpc property to a different value,
* we trigger a mode change on the connector's CRTC, which will in turn
Expand Down Expand Up @@ -1194,6 +1538,17 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes
}

static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode),
KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1),
KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode),
KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1),
/*
* TODO: When we'll have YUV output support, we need to check
* that the limited range is always set to limited no matter
* what the value of Broadcast RGB is.
*/
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_hdmi_funcs_reject_rate),
Expand Down

0 comments on commit 4af70f1

Please sign in to comment.