diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2022-09-06 10:56:03 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2022-09-06 10:56:04 +0200 |
commit | 8284bae723f025cb6a8431566757a3854a3c53eb (patch) | |
tree | 91c86c11413d12add21973c46b0a58f72ad103e0 /drivers/gpu/drm/tests/drm_dp_mst_helper_test.c | |
parent | 2c2d7a67defa198a8b8148dbaddc9e5554efebc8 (diff) | |
parent | 8869fa666a9e6782c3c896c1fa57d65adca23249 (diff) |
Merge tag 'drm-misc-next-2022-08-20-1' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v6.1:
UAPI Changes:
Cross-subsystem Changes:
- DMA-buf: documentation updates.
- Assorted small fixes to vga16fb
- Fix fbdev drivers to use the aperture helpers.
- Make removal of conflicting drivers work correctly without fbdev enabled.
Core Changes:
- bridge, scheduler, dp-mst: Assorted small fixes.
- Add more format helpers to fourcc, and use it to replace the cpp usage.
- Add DRM_FORMAT_Cxx, DRM_FORMAT_Rxx (single channel), and DRM_FORMAT_Dxx
("darkness", inverted single channel)
- Add packed AYUV8888 and XYUV8888 formats.
- Assorted documentation updates.
- Rename ttm_bo_init to ttm_bo_init_validate.
- Allow TTM bo's to exist without backing store.
- Convert drm selftests to kunit.
- Add managed init functions for (panel) bridge, crtc, encoder and connector.
- Fix endianness handling in various format conversion helpers.
- Make tests pass on big-endian platforms, and add test for rgb888 -> rgb565
- Move DRM_PLANE_HELPER_NO_SCALING to atomic helpers and rename, so
drm_plane_helper is no longer needed in most drivers.
- Use idr_init_base instead of idr_init.
- Rename FB and GEM CMA helpers to DMA helpers.
- Rework XRGB8888 related conversion helpers, and add drm_fb_blit() that
takes a iosys_map. Make drm_fb_memcpy take an iosys_map too.
- Move edid luminance calculation to core, and use it in i915.
Driver Changes:
- bridge/{adv7511,ti-sn65dsi86,parade-ps8640}, panel/{simple,nt35510,tc358767},
nouveau, sun4i, mipi-dsi, mgag200, bochs, arm, komeda, vmwgfx, pl111:
Assorted small fixes and doc updates.
- vc4: Rework hdmi power up, and depend on PM.
- panel/simple: Add Samsung LTL101AL01.
- ingenic: Add JZ4760(B) support, avoid a modeset when sharpness property
is unchanged, and use the new PM ops.
- Revert some amdgpu commits that cause garbaged graphics when starting
X, and reapply them with the real problem fixed.
- Completely rework vc4 init to use managed helpers.
- Rename via_drv to via_dri1, and move all stuff there only used by the
dri1 implementation in preperation for atomic modeset.
- Use regmap bulk write in ssd130x.
- Power sequence and clock updates to it6505.
- Split panel-sitrox-st7701 init sequence and rework mode programming code.
- virtio: Improve error and edge conditions handling, and convert to use managed
helpers.
- Add Samsung LTL101AL01, B120XAN01.0, R140NWF5 RH, DMT028VGHMCMI-1A T, panels.
- Add generic fbdev support to komeda.
- Split mgag200 modeset handling to make it more model-specific.
- Convert simpledrm to use atomic helpers.
- Improve udl suspend/disconnect handling.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/f0c71766-61e8-19b7-763a-5fbcdefc633d@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/tests/drm_dp_mst_helper_test.c')
-rw-r--r-- | drivers/gpu/drm/tests/drm_dp_mst_helper_test.c | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c new file mode 100644 index 000000000000..1d2fade56227 --- /dev/null +++ b/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Test cases for the DRM DP MST helpers + * + * Copyright (c) 2022 MaĆra Canal <mairacanal@riseup.net> + */ + +#define PREFIX_STR "[drm_dp_mst_helper]" + +#include <kunit/test.h> + +#include <linux/random.h> + +#include <drm/display/drm_dp_mst_helper.h> +#include <drm/drm_print.h> + +#include "../display/drm_dp_mst_topology_internal.h" + +static void igt_dp_mst_calc_pbn_mode(struct kunit *test) +{ + int pbn, i; + const struct { + int rate; + int bpp; + int expected; + bool dsc; + } test_params[] = { + { 154000, 30, 689, false }, + { 234000, 30, 1047, false }, + { 297000, 24, 1063, false }, + { 332880, 24, 50, true }, + { 324540, 24, 49, true }, + }; + + for (i = 0; i < ARRAY_SIZE(test_params); i++) { + pbn = drm_dp_calc_pbn_mode(test_params[i].rate, + test_params[i].bpp, + test_params[i].dsc); + KUNIT_EXPECT_EQ_MSG(test, pbn, test_params[i].expected, + "Expected PBN %d for clock %d bpp %d, got %d\n", + test_params[i].expected, test_params[i].rate, + test_params[i].bpp, pbn); + } +} + +static bool +sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in, + const struct drm_dp_sideband_msg_req_body *out) +{ + const struct drm_dp_remote_i2c_read_tx *txin, *txout; + int i; + + if (in->req_type != out->req_type) + return false; + + switch (in->req_type) { + /* + * Compare struct members manually for request types which can't be + * compared simply using memcmp(). This is because said request types + * contain pointers to other allocated structs + */ + case DP_REMOTE_I2C_READ: +#define IN in->u.i2c_read +#define OUT out->u.i2c_read + if (IN.num_bytes_read != OUT.num_bytes_read || + IN.num_transactions != OUT.num_transactions || + IN.port_number != OUT.port_number || + IN.read_i2c_device_id != OUT.read_i2c_device_id) + return false; + + for (i = 0; i < IN.num_transactions; i++) { + txin = &IN.transactions[i]; + txout = &OUT.transactions[i]; + + if (txin->i2c_dev_id != txout->i2c_dev_id || + txin->no_stop_bit != txout->no_stop_bit || + txin->num_bytes != txout->num_bytes || + txin->i2c_transaction_delay != + txout->i2c_transaction_delay) + return false; + + if (memcmp(txin->bytes, txout->bytes, + txin->num_bytes) != 0) + return false; + } + break; +#undef IN +#undef OUT + + case DP_REMOTE_DPCD_WRITE: +#define IN in->u.dpcd_write +#define OUT out->u.dpcd_write + if (IN.dpcd_address != OUT.dpcd_address || + IN.num_bytes != OUT.num_bytes || + IN.port_number != OUT.port_number) + return false; + + return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0; +#undef IN +#undef OUT + + case DP_REMOTE_I2C_WRITE: +#define IN in->u.i2c_write +#define OUT out->u.i2c_write + 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; + + return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0; +#undef IN +#undef OUT + + default: + return memcmp(in, out, sizeof(*in)) == 0; + } + + return true; +} + +static bool +sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in) +{ + 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) { + kfree(out); + 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; + } + + 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; + } + + switch (in->req_type) { + case DP_REMOTE_DPCD_WRITE: + kfree(out->u.dpcd_write.bytes); + break; + case DP_REMOTE_I2C_READ: + for (i = 0; i < out->u.i2c_read.num_transactions; i++) + kfree(out->u.i2c_read.transactions[i].bytes); + break; + case DP_REMOTE_I2C_WRITE: + 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; +} + +static void igt_dp_mst_sideband_msg_req_decode(struct kunit *test) +{ + struct drm_dp_sideband_msg_req_body in = { 0 }; + u8 data[] = { 0xff, 0x0, 0xdd }; + int i; + + in.req_type = DP_ENUM_PATH_RESOURCES; + in.u.port_num.port_number = 5; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + + in.req_type = DP_POWER_UP_PHY; + in.u.port_num.port_number = 5; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + + in.req_type = DP_POWER_DOWN_PHY; + in.u.port_num.port_number = 5; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + + 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; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.allocate_payload.port_number = 0xf; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.allocate_payload.vcpi = 0x7f; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.allocate_payload.pbn = U16_MAX; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + + in.req_type = DP_QUERY_PAYLOAD; + in.u.query_payload.port_number = 0xf; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.query_payload.vcpi = 0x7f; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + + in.req_type = DP_REMOTE_DPCD_READ; + in.u.dpcd_read.port_number = 0xf; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.dpcd_read.dpcd_address = 0xfedcb; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.dpcd_read.num_bytes = U8_MAX; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + + in.req_type = DP_REMOTE_DPCD_WRITE; + in.u.dpcd_write.port_number = 0xf; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.dpcd_write.dpcd_address = 0xfedcb; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.dpcd_write.num_bytes = ARRAY_SIZE(data); + in.u.dpcd_write.bytes = data; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + + in.req_type = DP_REMOTE_I2C_READ; + in.u.i2c_read.port_number = 0xf; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.i2c_read.read_i2c_device_id = 0x7f; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + 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; + } + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + + in.req_type = DP_REMOTE_I2C_WRITE; + in.u.i2c_write.port_number = 0xf; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.i2c_write.write_i2c_device_id = 0x7f; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.i2c_write.num_bytes = ARRAY_SIZE(data); + in.u.i2c_write.bytes = data; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + + in.req_type = DP_QUERY_STREAM_ENC_STATUS; + in.u.enc_status.stream_id = 1; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + get_random_bytes(in.u.enc_status.client_id, + sizeof(in.u.enc_status.client_id)); + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.enc_status.stream_event = 3; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.enc_status.valid_stream_event = 0; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.enc_status.stream_behavior = 3; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); + in.u.enc_status.valid_stream_behavior = 1; + KUNIT_EXPECT_TRUE(test, sideband_msg_req_encode_decode(&in)); +} + +static struct kunit_case drm_dp_mst_helper_tests[] = { + KUNIT_CASE(igt_dp_mst_calc_pbn_mode), + KUNIT_CASE(igt_dp_mst_sideband_msg_req_decode), + { } +}; + +static struct kunit_suite drm_dp_mst_helper_test_suite = { + .name = "drm_dp_mst_helper", + .test_cases = drm_dp_mst_helper_tests, +}; + +kunit_test_suite(drm_dp_mst_helper_test_suite); + +MODULE_LICENSE("GPL"); |