switch (in->req_type) {
/*
@@ -65,7 +108,7 @@ sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in,
IN.num_transactions != OUT.num_transactions ||
IN.port_number != OUT.port_number ||
IN.read_i2c_device_id != OUT.read_i2c_device_id)
- return false;
+ goto fail;
for (i = 0; i < IN.num_transactions; i++) {
txin = &IN.transactions[i];
@@ -76,11 +119,11 @@ sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in,
txin->num_bytes != txout->num_bytes ||
txin->i2c_transaction_delay !=
txout->i2c_transaction_delay)
- return false;
+ goto fail;
if (memcmp(txin->bytes, txout->bytes,
txin->num_bytes) != 0)
- return false;
+ goto fail;
}
break;
#undef IN
@@ -92,9 +135,12 @@ sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in,
if (IN.dpcd_address != OUT.dpcd_address ||
IN.num_bytes != OUT.num_bytes ||
IN.port_number != OUT.port_number)
- return false;
+ goto fail;
- return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0;
+ if (memcmp(IN.bytes, OUT.bytes, IN.num_bytes) != 0)
+ goto fail;
+
+ break;
#undef IN
#undef OUT
@@ -104,55 +150,65 @@ sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in,
if (IN.port_number != OUT.port_number ||
IN.write_i2c_device_id != OUT.write_i2c_device_id ||
IN.num_bytes != OUT.num_bytes)
- return false;
+ goto fail;
- return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0;
+ if (memcmp(IN.bytes, OUT.bytes, IN.num_bytes) != 0)
+ goto fail;
+
+ break;
#undef IN
#undef OUT
default:
- return memcmp(in, out, sizeof(*in)) == 0;
+ if (memcmp(in, out, sizeof(*in)) != 0)
+ goto fail;
}
- return true;
+ return;
+
+fail:
+ drm_printf(&p, "Expected:\n");
+ drm_dp_dump_sideband_msg_req_body(in, 1, &p);
+ drm_printf(&p, "Got:\n");
+ drm_dp_dump_sideband_msg_req_body(out, 1, &p);
+ KUNIT_FAIL(test, "Encode/decode failed");
+}
+
+struct dp_mst_sideband_msg_req_decode_test {
+ const struct drm_dp_sideband_msg_req_body req;
+ const struct drm_dp_sideband_msg_req_body
+ (*f)(const struct drm_dp_sideband_msg_req_body *in);
+};
+
+const struct drm_dp_sideband_msg_req_body
+param_to_dp_mst_sideband_msg_req_body(const struct dp_mst_sideband_msg_req_decode_test *t)
+{
+ if (t->f)
+ return t->f(&t->req);
+
+ return t->req;
}
-static bool
-sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in)
+static void dp_mst_sideband_msg_req_decode(struct kunit *test)
{
+ const struct drm_dp_sideband_msg_req_body in =
+ param_to_dp_mst_sideband_msg_req_body(test->param_value);
struct drm_dp_sideband_msg_req_body *out;
- struct drm_printer p = drm_err_printer(PREFIX_STR);
struct drm_dp_sideband_msg_tx *txmsg;
- int i, ret;
- bool result = true;
-
- out = kzalloc(sizeof(*out), GFP_KERNEL);
- if (!out)
- return false;
-
- txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
- if (!txmsg)
- return false;
-
- drm_dp_encode_sideband_req(in, txmsg);
- ret = drm_dp_decode_sideband_req(txmsg, out);
- if (ret < 0) {
- drm_printf(&p, "Failed to decode sideband request: %d\n",
- ret);
- result = false;
- goto out;
- }
+ int i;
- if (!sideband_msg_req_equal(in, out)) {
- drm_printf(&p, "Encode/decode failed, expected:\n");
- drm_dp_dump_sideband_msg_req_body(in, 1, &p);
- drm_printf(&p, "Got:\n");
- drm_dp_dump_sideband_msg_req_body(out, 1, &p);
- result = false;
- goto out;
- }
+ out = kunit_kzalloc(test, sizeof(*out), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, out);
- switch (in->req_type) {
+ txmsg = kunit_kzalloc(test, sizeof(*txmsg), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, txmsg);
+
+ drm_dp_encode_sideband_req(&in, txmsg);
+ KUNIT_ASSERT_EQ(test, drm_dp_decode_sideband_req(txmsg, out), 0);
+
+ expect_sideband_msg_req_equal(test, &in, out);
+
+ switch (in.req_type) {
case DP_REMOTE_DPCD_WRITE:
kfree(out->u.dpcd_write.bytes);
break;
@@ -164,110 +220,210 @@ sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in)
kfree(out->u.i2c_write.bytes);
break;
}
-
- /* Clear everything but the req_type for the input */
- memset(&in->u, 0, sizeof(in->u));
-
-out:
- kfree(out);
- kfree(txmsg);
- return result;
}
-int igt_dp_mst_sideband_msg_req_decode(void *unused)
+static u8 data[] = { 0xff, 0x0, 0xdd };
+
+const struct drm_dp_sideband_msg_req_body
+random_dp_query_enc_client_id(const struct drm_dp_sideband_msg_req_body *in)
{
- struct drm_dp_sideband_msg_req_body in = { 0 };
- u8 data[] = { 0xff, 0x0, 0xdd };
- int i;
+ struct drm_dp_query_stream_enc_status enc_status = { };
-#define DO_TEST() FAIL_ON(!sideband_msg_req_encode_decode(&in))
-
- in.req_type = DP_ENUM_PATH_RESOURCES;
- in.u.port_num.port_number = 5;
- DO_TEST();
-
- in.req_type = DP_POWER_UP_PHY;
- in.u.port_num.port_number = 5;
- DO_TEST();
-
- in.req_type = DP_POWER_DOWN_PHY;
- in.u.port_num.port_number = 5;
- DO_TEST();
-
- in.req_type = DP_ALLOCATE_PAYLOAD;
- in.u.allocate_payload.number_sdp_streams = 3;
- for (i = 0; i < in.u.allocate_payload.number_sdp_streams; i++)
- in.u.allocate_payload.sdp_stream_sink[i] = i + 1;
- DO_TEST();
- in.u.allocate_payload.port_number = 0xf;
- DO_TEST();
- in.u.allocate_payload.vcpi = 0x7f;
- DO_TEST();
- in.u.allocate_payload.pbn = U16_MAX;
- DO_TEST();
-
- in.req_type = DP_QUERY_PAYLOAD;
- in.u.query_payload.port_number = 0xf;
- DO_TEST();
- in.u.query_payload.vcpi = 0x7f;
- DO_TEST();
-
- in.req_type = DP_REMOTE_DPCD_READ;
- in.u.dpcd_read.port_number = 0xf;
- DO_TEST();
- in.u.dpcd_read.dpcd_address = 0xfedcb;
- DO_TEST();
- in.u.dpcd_read.num_bytes = U8_MAX;
- DO_TEST();
-
- in.req_type = DP_REMOTE_DPCD_WRITE;
- in.u.dpcd_write.port_number = 0xf;
- DO_TEST();
- in.u.dpcd_write.dpcd_address = 0xfedcb;
- DO_TEST();
- in.u.dpcd_write.num_bytes = ARRAY_SIZE(data);
- in.u.dpcd_write.bytes = data;
- DO_TEST();
-
- in.req_type = DP_REMOTE_I2C_READ;
- in.u.i2c_read.port_number = 0xf;
- DO_TEST();
- in.u.i2c_read.read_i2c_device_id = 0x7f;
- DO_TEST();
- in.u.i2c_read.num_transactions = 3;
- in.u.i2c_read.num_bytes_read = ARRAY_SIZE(data) * 3;
- for (i = 0; i < in.u.i2c_read.num_transactions; i++) {
- in.u.i2c_read.transactions[i].bytes = data;
- in.u.i2c_read.transactions[i].num_bytes = ARRAY_SIZE(data);
- in.u.i2c_read.transactions[i].i2c_dev_id = 0x7f & ~i;
- in.u.i2c_read.transactions[i].i2c_transaction_delay = 0xf & ~i;
- }
- DO_TEST();
-
- in.req_type = DP_REMOTE_I2C_WRITE;
- in.u.i2c_write.port_number = 0xf;
- DO_TEST();
- in.u.i2c_write.write_i2c_device_id = 0x7f;
- DO_TEST();
- in.u.i2c_write.num_bytes = ARRAY_SIZE(data);
- in.u.i2c_write.bytes = data;
- DO_TEST();
-
- in.req_type = DP_QUERY_STREAM_ENC_STATUS;
- in.u.enc_status.stream_id = 1;
- DO_TEST();
- get_random_bytes(in.u.enc_status.client_id,
- sizeof(in.u.enc_status.client_id));
- DO_TEST();
- in.u.enc_status.stream_event = 3;
- DO_TEST();
- in.u.enc_status.valid_stream_event = 0;
- DO_TEST();
- in.u.enc_status.stream_behavior = 3;
- DO_TEST();
- in.u.enc_status.valid_stream_behavior = 1;
- DO_TEST();
-
-#undef DO_TEST
- return 0;
+ get_random_bytes(enc_status.client_id, sizeof(enc_status.client_id));
+
+ return (const struct drm_dp_sideband_msg_req_body) { .req_type = in->req_type,
+ .u.enc_status = enc_status
+ };
}
+
+static const struct dp_mst_sideband_msg_req_decode_test dp_msg_sideband_msg_req_decode_tests[] = {
+ {
+ .req = {
+ .req_type = DP_ENUM_PATH_RESOURCES,
+ .u.port_num.port_number = 5,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_POWER_UP_PHY,
+ .u.port_num.port_number = 5,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_POWER_DOWN_PHY,
+ .u.port_num.port_number = 5,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_ALLOCATE_PAYLOAD,
+ .u.allocate_payload.number_sdp_streams = 3,
+ .u.allocate_payload.sdp_stream_sink = { 1, 2, 3 },
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_ALLOCATE_PAYLOAD,
+ .u.allocate_payload.port_number = 0xf,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_ALLOCATE_PAYLOAD,
+ .u.allocate_payload.vcpi = 0x7f,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_ALLOCATE_PAYLOAD,
+ .u.allocate_payload.pbn = U16_MAX,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_QUERY_PAYLOAD,
+ .u.query_payload.port_number = 0xf,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_QUERY_PAYLOAD,
+ .u.query_payload.vcpi = 0x7f,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_DPCD_READ,
+ .u.dpcd_read.port_number = 0xf,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_DPCD_READ,
+ .u.dpcd_read.dpcd_address = 0xfedcb,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_DPCD_READ,
+ .u.dpcd_read.num_bytes = U8_MAX,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_DPCD_WRITE,
+ .u.dpcd_write.port_number = 0xf,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_DPCD_WRITE,
+ .u.dpcd_write.dpcd_address = 0xfedcb,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_DPCD_WRITE,
+ .u.dpcd_write.num_bytes = ARRAY_SIZE(data),
+ .u.dpcd_write.bytes = data,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_I2C_READ,
+ .u.i2c_read.port_number = 0xf,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_I2C_READ,
+ .u.i2c_read.read_i2c_device_id = 0x7f,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_I2C_READ,
+ .u.i2c_read.num_transactions = 3,
+ .u.i2c_read.num_bytes_read = ARRAY_SIZE(data) * 3,
+ .u.i2c_read.transactions = {
+ { .bytes = data, .num_bytes = ARRAY_SIZE(data),
+ .i2c_dev_id = 0x7f, .i2c_transaction_delay = 0xf, },
+ { .bytes = data, .num_bytes = ARRAY_SIZE(data),
+ .i2c_dev_id = 0x7e, .i2c_transaction_delay = 0xe, },
+ { .bytes = data, .num_bytes = ARRAY_SIZE(data),
+ .i2c_dev_id = 0x7d, .i2c_transaction_delay = 0xd, },
+ },
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_I2C_WRITE,
+ .u.i2c_write.port_number = 0xf,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_I2C_WRITE,
+ .u.i2c_write.write_i2c_device_id = 0x7f,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_REMOTE_I2C_WRITE,
+ .u.i2c_write.num_bytes = ARRAY_SIZE(data),
+ .u.i2c_write.bytes = data,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
+ .u.enc_status.stream_id = 1,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
+ },
+ .f = random_dp_query_enc_client_id,
+ },
+ {
+ .req = {
+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
+ .u.enc_status.stream_event = 3,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
+ .u.enc_status.valid_stream_event = 0,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
+ .u.enc_status.stream_behavior = 3,
+ },
+ },
+ {
+ .req = {
+ .req_type = DP_QUERY_STREAM_ENC_STATUS,
+ .u.enc_status.valid_stream_behavior = 1,
+ },
+ },
+};
+
+KUNIT_ARRAY_PARAM(dp_mst_sideband_msg_req, dp_msg_sideband_msg_req_decode_tests, NULL);
+
+static struct kunit_case drm_dp_mst_helper_tests[] = {
+ KUNIT_CASE_PARAM(dp_mst_calc_pbn_mode, dp_mst_calc_pbn_mode_gen_params),
+ KUNIT_CASE_PARAM(dp_mst_sideband_msg_req_decode, dp_mst_sideband_msg_req_gen_params),
+ {}
+};
+
+static struct kunit_suite drm_dp_mst_helper_test_suite = {
+ .name = "drm_dp_mst_helper_tests",
+ .test_cases = drm_dp_mst_helper_tests,
+};
+
+kunit_test_suite(drm_dp_mst_helper_test_suite);
diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
index 1501d99aee2f..c7cc5edc65f1 100644
--- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h
+++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h
@@ -20,7 +20,5 @@ int igt_drm_rect_clip_scaled_div_by_zero(void *ignored);
int igt_drm_rect_clip_scaled_not_clipped(void *ignored);
int igt_drm_rect_clip_scaled_clipped(void *ignored);
int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored);
-int igt_dp_mst_calc_pbn_mode(void *ignored);
-int igt_dp_mst_sideband_msg_req_decode(void *ignored);
#endif
--
2.34.1