1848b3c0bSMaíra Canal // SPDX-License-Identifier: GPL-2.0-only
2848b3c0bSMaíra Canal /*
3848b3c0bSMaíra Canal  * Test cases for the DRM DP MST helpers
4848b3c0bSMaíra Canal  *
5848b3c0bSMaíra Canal  * Copyright (c) 2022 Maíra Canal <mairacanal@riseup.net>
6848b3c0bSMaíra Canal  */
7848b3c0bSMaíra Canal 
8848b3c0bSMaíra Canal #include <kunit/test.h>
9848b3c0bSMaíra Canal 
10848b3c0bSMaíra Canal #include <drm/display/drm_dp_mst_helper.h>
11848b3c0bSMaíra Canal #include <drm/drm_print.h>
12848b3c0bSMaíra Canal 
13848b3c0bSMaíra Canal #include "../display/drm_dp_mst_topology_internal.h"
14848b3c0bSMaíra Canal 
15d32f7960SMaíra Canal struct drm_dp_mst_calc_pbn_mode_test {
16d32f7960SMaíra Canal 	const int clock;
17d32f7960SMaíra Canal 	const int bpp;
18d32f7960SMaíra Canal 	const bool dsc;
19d32f7960SMaíra Canal 	const int expected;
20848b3c0bSMaíra Canal };
21848b3c0bSMaíra Canal 
22d32f7960SMaíra Canal static const struct drm_dp_mst_calc_pbn_mode_test drm_dp_mst_calc_pbn_mode_cases[] = {
23d32f7960SMaíra Canal 	{
24d32f7960SMaíra Canal 		.clock = 154000,
25d32f7960SMaíra Canal 		.bpp = 30,
26d32f7960SMaíra Canal 		.dsc = false,
27d32f7960SMaíra Canal 		.expected = 689
28d32f7960SMaíra Canal 	},
29d32f7960SMaíra Canal 	{
30d32f7960SMaíra Canal 		.clock = 234000,
31d32f7960SMaíra Canal 		.bpp = 30,
32d32f7960SMaíra Canal 		.dsc = false,
33d32f7960SMaíra Canal 		.expected = 1047
34d32f7960SMaíra Canal 	},
35d32f7960SMaíra Canal 	{
36d32f7960SMaíra Canal 		.clock = 297000,
37d32f7960SMaíra Canal 		.bpp = 24,
38d32f7960SMaíra Canal 		.dsc = false,
39d32f7960SMaíra Canal 		.expected = 1063
40d32f7960SMaíra Canal 	},
41d32f7960SMaíra Canal 	{
42d32f7960SMaíra Canal 		.clock = 332880,
43d32f7960SMaíra Canal 		.bpp = 24,
44d32f7960SMaíra Canal 		.dsc = true,
45*4e042f02SVille Syrjälä 		.expected = 1191
46d32f7960SMaíra Canal 	},
47d32f7960SMaíra Canal 	{
48d32f7960SMaíra Canal 		.clock = 324540,
49d32f7960SMaíra Canal 		.bpp = 24,
50d32f7960SMaíra Canal 		.dsc = true,
51*4e042f02SVille Syrjälä 		.expected = 1161
52d32f7960SMaíra Canal 	},
53d32f7960SMaíra Canal };
54d32f7960SMaíra Canal 
drm_test_dp_mst_calc_pbn_mode(struct kunit * test)55d32f7960SMaíra Canal static void drm_test_dp_mst_calc_pbn_mode(struct kunit *test)
56d32f7960SMaíra Canal {
57d32f7960SMaíra Canal 	const struct drm_dp_mst_calc_pbn_mode_test *params = test->param_value;
58d32f7960SMaíra Canal 
59*4e042f02SVille Syrjälä 	KUNIT_EXPECT_EQ(test, drm_dp_calc_pbn_mode(params->clock, params->bpp << 4),
60d32f7960SMaíra Canal 			params->expected);
61848b3c0bSMaíra Canal }
62d32f7960SMaíra Canal 
dp_mst_calc_pbn_mode_desc(const struct drm_dp_mst_calc_pbn_mode_test * t,char * desc)63d32f7960SMaíra Canal static void dp_mst_calc_pbn_mode_desc(const struct drm_dp_mst_calc_pbn_mode_test *t, char *desc)
64d32f7960SMaíra Canal {
65d32f7960SMaíra Canal 	sprintf(desc, "Clock %d BPP %d DSC %s", t->clock, t->bpp, t->dsc ? "enabled" : "disabled");
66848b3c0bSMaíra Canal }
67848b3c0bSMaíra Canal 
68d32f7960SMaíra Canal KUNIT_ARRAY_PARAM(drm_dp_mst_calc_pbn_mode, drm_dp_mst_calc_pbn_mode_cases,
69d32f7960SMaíra Canal 		  dp_mst_calc_pbn_mode_desc);
70d32f7960SMaíra Canal 
71530f7897SMaíra Canal static u8 data[] = { 0xff, 0x00, 0xdd };
72530f7897SMaíra Canal 
73530f7897SMaíra Canal struct drm_dp_mst_sideband_msg_req_test {
74530f7897SMaíra Canal 	const char *desc;
75530f7897SMaíra Canal 	const struct drm_dp_sideband_msg_req_body in;
76530f7897SMaíra Canal };
77530f7897SMaíra Canal 
78530f7897SMaíra Canal static const struct drm_dp_mst_sideband_msg_req_test drm_dp_mst_sideband_msg_req_cases[] = {
79530f7897SMaíra Canal 	{
80530f7897SMaíra Canal 		.desc = "DP_ENUM_PATH_RESOURCES with port number",
81530f7897SMaíra Canal 		.in = {
82530f7897SMaíra Canal 			.req_type = DP_ENUM_PATH_RESOURCES,
83530f7897SMaíra Canal 			.u.port_num.port_number = 5,
84530f7897SMaíra Canal 		},
85530f7897SMaíra Canal 	},
86530f7897SMaíra Canal 	{
87530f7897SMaíra Canal 		.desc = "DP_POWER_UP_PHY with port number",
88530f7897SMaíra Canal 		.in = {
89530f7897SMaíra Canal 			.req_type = DP_POWER_UP_PHY,
90530f7897SMaíra Canal 			.u.port_num.port_number = 5,
91530f7897SMaíra Canal 		},
92530f7897SMaíra Canal 	},
93530f7897SMaíra Canal 	{
94530f7897SMaíra Canal 		.desc = "DP_POWER_DOWN_PHY with port number",
95530f7897SMaíra Canal 		.in = {
96530f7897SMaíra Canal 			.req_type = DP_POWER_DOWN_PHY,
97530f7897SMaíra Canal 			.u.port_num.port_number = 5,
98530f7897SMaíra Canal 		},
99530f7897SMaíra Canal 	},
100530f7897SMaíra Canal 	{
101530f7897SMaíra Canal 		.desc = "DP_ALLOCATE_PAYLOAD with SDP stream sinks",
102530f7897SMaíra Canal 		.in = {
103530f7897SMaíra Canal 			.req_type = DP_ALLOCATE_PAYLOAD,
104530f7897SMaíra Canal 			.u.allocate_payload.number_sdp_streams = 3,
105530f7897SMaíra Canal 			.u.allocate_payload.sdp_stream_sink = { 1, 2, 3 },
106530f7897SMaíra Canal 		},
107530f7897SMaíra Canal 	},
108530f7897SMaíra Canal 	{
109530f7897SMaíra Canal 		.desc = "DP_ALLOCATE_PAYLOAD with port number",
110530f7897SMaíra Canal 		.in = {
111530f7897SMaíra Canal 			.req_type = DP_ALLOCATE_PAYLOAD,
112530f7897SMaíra Canal 			.u.allocate_payload.port_number = 0xf,
113530f7897SMaíra Canal 		},
114530f7897SMaíra Canal 	},
115530f7897SMaíra Canal 	{
116530f7897SMaíra Canal 		.desc = "DP_ALLOCATE_PAYLOAD with VCPI",
117530f7897SMaíra Canal 		.in = {
118530f7897SMaíra Canal 			.req_type = DP_ALLOCATE_PAYLOAD,
119530f7897SMaíra Canal 			.u.allocate_payload.vcpi = 0x7f,
120530f7897SMaíra Canal 		},
121530f7897SMaíra Canal 	},
122530f7897SMaíra Canal 	{
123530f7897SMaíra Canal 		.desc = "DP_ALLOCATE_PAYLOAD with PBN",
124530f7897SMaíra Canal 		.in = {
125530f7897SMaíra Canal 			.req_type = DP_ALLOCATE_PAYLOAD,
126530f7897SMaíra Canal 			.u.allocate_payload.pbn = U16_MAX,
127530f7897SMaíra Canal 		},
128530f7897SMaíra Canal 	},
129530f7897SMaíra Canal 	{
130530f7897SMaíra Canal 		.desc = "DP_QUERY_PAYLOAD with port number",
131530f7897SMaíra Canal 		.in = {
132530f7897SMaíra Canal 			.req_type = DP_QUERY_PAYLOAD,
133530f7897SMaíra Canal 			.u.query_payload.port_number = 0xf,
134530f7897SMaíra Canal 		},
135530f7897SMaíra Canal 	},
136530f7897SMaíra Canal 	{
137530f7897SMaíra Canal 		.desc = "DP_QUERY_PAYLOAD with VCPI",
138530f7897SMaíra Canal 		.in = {
139530f7897SMaíra Canal 			.req_type = DP_QUERY_PAYLOAD,
140530f7897SMaíra Canal 			.u.query_payload.vcpi = 0x7f,
141530f7897SMaíra Canal 		},
142530f7897SMaíra Canal 	},
143530f7897SMaíra Canal 	{
144530f7897SMaíra Canal 		.desc = "DP_REMOTE_DPCD_READ with port number",
145530f7897SMaíra Canal 		.in = {
146530f7897SMaíra Canal 			.req_type = DP_REMOTE_DPCD_READ,
147530f7897SMaíra Canal 			.u.dpcd_read.port_number = 0xf,
148530f7897SMaíra Canal 		},
149530f7897SMaíra Canal 	},
150530f7897SMaíra Canal 	{
151530f7897SMaíra Canal 		.desc = "DP_REMOTE_DPCD_READ with DPCD address",
152530f7897SMaíra Canal 		.in = {
153530f7897SMaíra Canal 			.req_type = DP_REMOTE_DPCD_READ,
154530f7897SMaíra Canal 			.u.dpcd_read.dpcd_address = 0xfedcb,
155530f7897SMaíra Canal 		},
156530f7897SMaíra Canal 	},
157530f7897SMaíra Canal 	{
158530f7897SMaíra Canal 		.desc = "DP_REMOTE_DPCD_READ with max number of bytes",
159530f7897SMaíra Canal 		.in = {
160530f7897SMaíra Canal 			.req_type = DP_REMOTE_DPCD_READ,
161530f7897SMaíra Canal 			.u.dpcd_read.num_bytes = U8_MAX,
162530f7897SMaíra Canal 		},
163530f7897SMaíra Canal 	},
164530f7897SMaíra Canal 	{
165530f7897SMaíra Canal 		.desc = "DP_REMOTE_DPCD_WRITE with port number",
166530f7897SMaíra Canal 		.in = {
167530f7897SMaíra Canal 			.req_type = DP_REMOTE_DPCD_WRITE,
168530f7897SMaíra Canal 			.u.dpcd_write.port_number = 0xf,
169530f7897SMaíra Canal 		},
170530f7897SMaíra Canal 	},
171530f7897SMaíra Canal 	{
172530f7897SMaíra Canal 		.desc = "DP_REMOTE_DPCD_WRITE with DPCD address",
173530f7897SMaíra Canal 		.in = {
174530f7897SMaíra Canal 			.req_type = DP_REMOTE_DPCD_WRITE,
175530f7897SMaíra Canal 			.u.dpcd_write.dpcd_address = 0xfedcb,
176530f7897SMaíra Canal 		},
177530f7897SMaíra Canal 	},
178530f7897SMaíra Canal 	{
179530f7897SMaíra Canal 		.desc = "DP_REMOTE_DPCD_WRITE with data array",
180530f7897SMaíra Canal 		.in = {
181530f7897SMaíra Canal 			.req_type = DP_REMOTE_DPCD_WRITE,
182530f7897SMaíra Canal 			.u.dpcd_write.num_bytes = ARRAY_SIZE(data),
183530f7897SMaíra Canal 			.u.dpcd_write.bytes = data,
184530f7897SMaíra Canal 		},
185530f7897SMaíra Canal 	},
186530f7897SMaíra Canal 	{
187530f7897SMaíra Canal 		.desc = "DP_REMOTE_I2C_READ with port number",
188530f7897SMaíra Canal 		.in = {
189530f7897SMaíra Canal 			.req_type = DP_REMOTE_I2C_READ,
190530f7897SMaíra Canal 			.u.i2c_read.port_number = 0xf,
191530f7897SMaíra Canal 		},
192530f7897SMaíra Canal 	},
193530f7897SMaíra Canal 	{
194530f7897SMaíra Canal 		.desc = "DP_REMOTE_I2C_READ with I2C device ID",
195530f7897SMaíra Canal 		.in = {
196530f7897SMaíra Canal 			.req_type = DP_REMOTE_I2C_READ,
197530f7897SMaíra Canal 			.u.i2c_read.read_i2c_device_id = 0x7f,
198530f7897SMaíra Canal 		},
199530f7897SMaíra Canal 	},
200530f7897SMaíra Canal 	{
201530f7897SMaíra Canal 		.desc = "DP_REMOTE_I2C_READ with transactions array",
202530f7897SMaíra Canal 		.in = {
203530f7897SMaíra Canal 			.req_type = DP_REMOTE_I2C_READ,
204530f7897SMaíra Canal 			.u.i2c_read.num_transactions = 3,
205530f7897SMaíra Canal 			.u.i2c_read.num_bytes_read = ARRAY_SIZE(data) * 3,
206530f7897SMaíra Canal 			.u.i2c_read.transactions = {
207530f7897SMaíra Canal 				{ .bytes = data, .num_bytes = ARRAY_SIZE(data), .i2c_dev_id = 0x7f,
208530f7897SMaíra Canal 				  .i2c_transaction_delay = 0xf, },
209530f7897SMaíra Canal 				{ .bytes = data, .num_bytes = ARRAY_SIZE(data), .i2c_dev_id = 0x7e,
210530f7897SMaíra Canal 				  .i2c_transaction_delay = 0xe, },
211530f7897SMaíra Canal 				{ .bytes = data, .num_bytes = ARRAY_SIZE(data), .i2c_dev_id = 0x7d,
212530f7897SMaíra Canal 				  .i2c_transaction_delay = 0xd, },
213530f7897SMaíra Canal 			},
214530f7897SMaíra Canal 		},
215530f7897SMaíra Canal 	},
216530f7897SMaíra Canal 	{
217530f7897SMaíra Canal 		.desc = "DP_REMOTE_I2C_WRITE with port number",
218530f7897SMaíra Canal 		.in = {
219530f7897SMaíra Canal 			.req_type = DP_REMOTE_I2C_WRITE,
220530f7897SMaíra Canal 			.u.i2c_write.port_number = 0xf,
221530f7897SMaíra Canal 		},
222530f7897SMaíra Canal 	},
223530f7897SMaíra Canal 	{
224530f7897SMaíra Canal 		.desc = "DP_REMOTE_I2C_WRITE with I2C device ID",
225530f7897SMaíra Canal 		.in = {
226530f7897SMaíra Canal 			.req_type = DP_REMOTE_I2C_WRITE,
227530f7897SMaíra Canal 			.u.i2c_write.write_i2c_device_id = 0x7f,
228530f7897SMaíra Canal 		},
229530f7897SMaíra Canal 	},
230530f7897SMaíra Canal 	{
231530f7897SMaíra Canal 		.desc = "DP_REMOTE_I2C_WRITE with data array",
232530f7897SMaíra Canal 		.in = {
233530f7897SMaíra Canal 			.req_type = DP_REMOTE_I2C_WRITE,
234530f7897SMaíra Canal 			.u.i2c_write.num_bytes = ARRAY_SIZE(data),
235530f7897SMaíra Canal 			.u.i2c_write.bytes = data,
236530f7897SMaíra Canal 		},
237530f7897SMaíra Canal 	},
238530f7897SMaíra Canal 	{
239530f7897SMaíra Canal 		.desc = "DP_QUERY_STREAM_ENC_STATUS with stream ID",
240530f7897SMaíra Canal 		.in = {
241530f7897SMaíra Canal 			.req_type = DP_QUERY_STREAM_ENC_STATUS,
242530f7897SMaíra Canal 			.u.enc_status.stream_id = 1,
243530f7897SMaíra Canal 		},
244530f7897SMaíra Canal 	},
245530f7897SMaíra Canal 	{
246530f7897SMaíra Canal 		.desc = "DP_QUERY_STREAM_ENC_STATUS with client ID",
247530f7897SMaíra Canal 		.in = {
248530f7897SMaíra Canal 			.req_type = DP_QUERY_STREAM_ENC_STATUS,
249530f7897SMaíra Canal 			.u.enc_status.client_id = { 0x4f, 0x7f, 0xb4, 0x00, 0x8c, 0x0d, 0x67 },
250530f7897SMaíra Canal 		},
251530f7897SMaíra Canal 	},
252530f7897SMaíra Canal 	{
253530f7897SMaíra Canal 		.desc = "DP_QUERY_STREAM_ENC_STATUS with stream event",
254530f7897SMaíra Canal 		.in = {
255530f7897SMaíra Canal 			.req_type = DP_QUERY_STREAM_ENC_STATUS,
256530f7897SMaíra Canal 			.u.enc_status.stream_event = 3,
257530f7897SMaíra Canal 		},
258530f7897SMaíra Canal 	},
259530f7897SMaíra Canal 	{
260530f7897SMaíra Canal 		.desc = "DP_QUERY_STREAM_ENC_STATUS with valid stream event",
261530f7897SMaíra Canal 		.in = {
262530f7897SMaíra Canal 			.req_type = DP_QUERY_STREAM_ENC_STATUS,
263530f7897SMaíra Canal 			.u.enc_status.valid_stream_event = 0,
264530f7897SMaíra Canal 		},
265530f7897SMaíra Canal 	},
266530f7897SMaíra Canal 	{
267530f7897SMaíra Canal 		.desc = "DP_QUERY_STREAM_ENC_STATUS with stream behavior",
268530f7897SMaíra Canal 		.in = {
269530f7897SMaíra Canal 			.req_type = DP_QUERY_STREAM_ENC_STATUS,
270530f7897SMaíra Canal 			.u.enc_status.stream_behavior = 3,
271530f7897SMaíra Canal 		},
272530f7897SMaíra Canal 	},
273530f7897SMaíra Canal 	{
274530f7897SMaíra Canal 		.desc = "DP_QUERY_STREAM_ENC_STATUS with a valid stream behavior",
275530f7897SMaíra Canal 		.in = {
276530f7897SMaíra Canal 			.req_type = DP_QUERY_STREAM_ENC_STATUS,
277530f7897SMaíra Canal 			.u.enc_status.valid_stream_behavior = 1,
278530f7897SMaíra Canal 		}
279530f7897SMaíra Canal 	},
280530f7897SMaíra Canal };
281530f7897SMaíra Canal 
282848b3c0bSMaíra Canal static bool
sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body * in,const struct drm_dp_sideband_msg_req_body * out)283848b3c0bSMaíra Canal sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in,
284848b3c0bSMaíra Canal 		       const struct drm_dp_sideband_msg_req_body *out)
285848b3c0bSMaíra Canal {
286848b3c0bSMaíra Canal 	const struct drm_dp_remote_i2c_read_tx *txin, *txout;
287848b3c0bSMaíra Canal 	int i;
288848b3c0bSMaíra Canal 
289848b3c0bSMaíra Canal 	if (in->req_type != out->req_type)
290848b3c0bSMaíra Canal 		return false;
291848b3c0bSMaíra Canal 
292848b3c0bSMaíra Canal 	switch (in->req_type) {
293848b3c0bSMaíra Canal 	/*
294848b3c0bSMaíra Canal 	 * Compare struct members manually for request types which can't be
295848b3c0bSMaíra Canal 	 * compared simply using memcmp(). This is because said request types
296848b3c0bSMaíra Canal 	 * contain pointers to other allocated structs
297848b3c0bSMaíra Canal 	 */
298848b3c0bSMaíra Canal 	case DP_REMOTE_I2C_READ:
299848b3c0bSMaíra Canal #define IN in->u.i2c_read
300848b3c0bSMaíra Canal #define OUT out->u.i2c_read
301848b3c0bSMaíra Canal 		if (IN.num_bytes_read != OUT.num_bytes_read ||
302848b3c0bSMaíra Canal 		    IN.num_transactions != OUT.num_transactions ||
303848b3c0bSMaíra Canal 		    IN.port_number != OUT.port_number ||
304848b3c0bSMaíra Canal 		    IN.read_i2c_device_id != OUT.read_i2c_device_id)
305848b3c0bSMaíra Canal 			return false;
306848b3c0bSMaíra Canal 
307848b3c0bSMaíra Canal 		for (i = 0; i < IN.num_transactions; i++) {
308848b3c0bSMaíra Canal 			txin = &IN.transactions[i];
309848b3c0bSMaíra Canal 			txout = &OUT.transactions[i];
310848b3c0bSMaíra Canal 
311848b3c0bSMaíra Canal 			if (txin->i2c_dev_id != txout->i2c_dev_id ||
312848b3c0bSMaíra Canal 			    txin->no_stop_bit != txout->no_stop_bit ||
313848b3c0bSMaíra Canal 			    txin->num_bytes != txout->num_bytes ||
314848b3c0bSMaíra Canal 			    txin->i2c_transaction_delay !=
315848b3c0bSMaíra Canal 			    txout->i2c_transaction_delay)
316848b3c0bSMaíra Canal 				return false;
317848b3c0bSMaíra Canal 
318848b3c0bSMaíra Canal 			if (memcmp(txin->bytes, txout->bytes,
319848b3c0bSMaíra Canal 				   txin->num_bytes) != 0)
320848b3c0bSMaíra Canal 				return false;
321848b3c0bSMaíra Canal 		}
322848b3c0bSMaíra Canal 		break;
323848b3c0bSMaíra Canal #undef IN
324848b3c0bSMaíra Canal #undef OUT
325848b3c0bSMaíra Canal 
326848b3c0bSMaíra Canal 	case DP_REMOTE_DPCD_WRITE:
327848b3c0bSMaíra Canal #define IN in->u.dpcd_write
328848b3c0bSMaíra Canal #define OUT out->u.dpcd_write
329848b3c0bSMaíra Canal 		if (IN.dpcd_address != OUT.dpcd_address ||
330848b3c0bSMaíra Canal 		    IN.num_bytes != OUT.num_bytes ||
331848b3c0bSMaíra Canal 		    IN.port_number != OUT.port_number)
332848b3c0bSMaíra Canal 			return false;
333848b3c0bSMaíra Canal 
334848b3c0bSMaíra Canal 		return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0;
335848b3c0bSMaíra Canal #undef IN
336848b3c0bSMaíra Canal #undef OUT
337848b3c0bSMaíra Canal 
338848b3c0bSMaíra Canal 	case DP_REMOTE_I2C_WRITE:
339848b3c0bSMaíra Canal #define IN in->u.i2c_write
340848b3c0bSMaíra Canal #define OUT out->u.i2c_write
341848b3c0bSMaíra Canal 		if (IN.port_number != OUT.port_number ||
342848b3c0bSMaíra Canal 		    IN.write_i2c_device_id != OUT.write_i2c_device_id ||
343848b3c0bSMaíra Canal 		    IN.num_bytes != OUT.num_bytes)
344848b3c0bSMaíra Canal 			return false;
345848b3c0bSMaíra Canal 
346848b3c0bSMaíra Canal 		return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0;
347848b3c0bSMaíra Canal #undef IN
348848b3c0bSMaíra Canal #undef OUT
349848b3c0bSMaíra Canal 
350848b3c0bSMaíra Canal 	default:
351848b3c0bSMaíra Canal 		return memcmp(in, out, sizeof(*in)) == 0;
352848b3c0bSMaíra Canal 	}
353848b3c0bSMaíra Canal 
354848b3c0bSMaíra Canal 	return true;
355848b3c0bSMaíra Canal }
356848b3c0bSMaíra Canal 
drm_test_dp_mst_msg_printf(struct drm_printer * p,struct va_format * vaf)357530f7897SMaíra Canal static void drm_test_dp_mst_msg_printf(struct drm_printer *p, struct va_format *vaf)
358848b3c0bSMaíra Canal {
359530f7897SMaíra Canal 	struct kunit *test = p->arg;
360848b3c0bSMaíra Canal 
361530f7897SMaíra Canal 	kunit_err(test, "%pV", vaf);
362848b3c0bSMaíra Canal }
363848b3c0bSMaíra Canal 
drm_test_dp_mst_sideband_msg_req_decode(struct kunit * test)364530f7897SMaíra Canal static void drm_test_dp_mst_sideband_msg_req_decode(struct kunit *test)
365530f7897SMaíra Canal {
366530f7897SMaíra Canal 	const struct drm_dp_mst_sideband_msg_req_test *params = test->param_value;
367530f7897SMaíra Canal 	const struct drm_dp_sideband_msg_req_body *in = &params->in;
368530f7897SMaíra Canal 	struct drm_dp_sideband_msg_req_body *out;
369530f7897SMaíra Canal 	struct drm_dp_sideband_msg_tx *txmsg;
370530f7897SMaíra Canal 	struct drm_printer p = {
371530f7897SMaíra Canal 		.printfn = drm_test_dp_mst_msg_printf,
372530f7897SMaíra Canal 		.arg = test
373530f7897SMaíra Canal 	};
374530f7897SMaíra Canal 	int i;
375530f7897SMaíra Canal 
376530f7897SMaíra Canal 	out = kunit_kzalloc(test, sizeof(*out), GFP_KERNEL);
377530f7897SMaíra Canal 	KUNIT_ASSERT_NOT_NULL(test, out);
378530f7897SMaíra Canal 
379530f7897SMaíra Canal 	txmsg = kunit_kzalloc(test, sizeof(*txmsg), GFP_KERNEL);
380530f7897SMaíra Canal 	KUNIT_ASSERT_NOT_NULL(test, txmsg);
381530f7897SMaíra Canal 
382848b3c0bSMaíra Canal 	drm_dp_encode_sideband_req(in, txmsg);
383530f7897SMaíra Canal 	KUNIT_EXPECT_GE_MSG(test, drm_dp_decode_sideband_req(txmsg, out), 0,
384530f7897SMaíra Canal 			    "Failed to decode sideband request");
385848b3c0bSMaíra Canal 
386848b3c0bSMaíra Canal 	if (!sideband_msg_req_equal(in, out)) {
387530f7897SMaíra Canal 		KUNIT_FAIL(test, "Encode/decode failed");
388530f7897SMaíra Canal 		kunit_err(test, "Expected:");
389848b3c0bSMaíra Canal 		drm_dp_dump_sideband_msg_req_body(in, 1, &p);
390530f7897SMaíra Canal 		kunit_err(test, "Got:");
391848b3c0bSMaíra Canal 		drm_dp_dump_sideband_msg_req_body(out, 1, &p);
392848b3c0bSMaíra Canal 	}
393848b3c0bSMaíra Canal 
394848b3c0bSMaíra Canal 	switch (in->req_type) {
395848b3c0bSMaíra Canal 	case DP_REMOTE_DPCD_WRITE:
396848b3c0bSMaíra Canal 		kfree(out->u.dpcd_write.bytes);
397848b3c0bSMaíra Canal 		break;
398848b3c0bSMaíra Canal 	case DP_REMOTE_I2C_READ:
399848b3c0bSMaíra Canal 		for (i = 0; i < out->u.i2c_read.num_transactions; i++)
400848b3c0bSMaíra Canal 			kfree(out->u.i2c_read.transactions[i].bytes);
401848b3c0bSMaíra Canal 		break;
402848b3c0bSMaíra Canal 	case DP_REMOTE_I2C_WRITE:
403848b3c0bSMaíra Canal 		kfree(out->u.i2c_write.bytes);
404848b3c0bSMaíra Canal 		break;
405848b3c0bSMaíra Canal 	}
406848b3c0bSMaíra Canal }
407848b3c0bSMaíra Canal 
408530f7897SMaíra Canal static void
drm_dp_mst_sideband_msg_req_desc(const struct drm_dp_mst_sideband_msg_req_test * t,char * desc)409530f7897SMaíra Canal drm_dp_mst_sideband_msg_req_desc(const struct drm_dp_mst_sideband_msg_req_test *t, char *desc)
410848b3c0bSMaíra Canal {
411530f7897SMaíra Canal 	strcpy(desc, t->desc);
412848b3c0bSMaíra Canal }
413848b3c0bSMaíra Canal 
414530f7897SMaíra Canal KUNIT_ARRAY_PARAM(drm_dp_mst_sideband_msg_req, drm_dp_mst_sideband_msg_req_cases,
415530f7897SMaíra Canal 		  drm_dp_mst_sideband_msg_req_desc);
416848b3c0bSMaíra Canal 
417848b3c0bSMaíra Canal static struct kunit_case drm_dp_mst_helper_tests[] = {
418d32f7960SMaíra Canal 	KUNIT_CASE_PARAM(drm_test_dp_mst_calc_pbn_mode, drm_dp_mst_calc_pbn_mode_gen_params),
419530f7897SMaíra Canal 	KUNIT_CASE_PARAM(drm_test_dp_mst_sideband_msg_req_decode,
420530f7897SMaíra Canal 			 drm_dp_mst_sideband_msg_req_gen_params),
421848b3c0bSMaíra Canal 	{ }
422848b3c0bSMaíra Canal };
423848b3c0bSMaíra Canal 
424848b3c0bSMaíra Canal static struct kunit_suite drm_dp_mst_helper_test_suite = {
425848b3c0bSMaíra Canal 	.name = "drm_dp_mst_helper",
426848b3c0bSMaíra Canal 	.test_cases = drm_dp_mst_helper_tests,
427848b3c0bSMaíra Canal };
428848b3c0bSMaíra Canal 
429848b3c0bSMaíra Canal kunit_test_suite(drm_dp_mst_helper_test_suite);
430848b3c0bSMaíra Canal 
431848b3c0bSMaíra Canal MODULE_LICENSE("GPL");
432