treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / gpu / drm / selftests / test-drm_dp_mst_helper.c
blobbd990d17876576b2651ae0d689b1c655a8cdfb2c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Test cases for for the DRM DP MST helpers
4 */
6 #define PREFIX_STR "[drm_dp_mst_helper]"
8 #include <drm/drm_dp_mst_helper.h>
9 #include <drm/drm_print.h>
11 #include "../drm_dp_mst_topology_internal.h"
12 #include "test-drm_modeset_common.h"
14 int igt_dp_mst_calc_pbn_mode(void *ignored)
16 int pbn, i;
17 const struct {
18 int rate;
19 int bpp;
20 int expected;
21 bool dsc;
22 } test_params[] = {
23 { 154000, 30, 689, false },
24 { 234000, 30, 1047, false },
25 { 297000, 24, 1063, false },
26 { 332880, 24, 50, true },
27 { 324540, 24, 49, true },
30 for (i = 0; i < ARRAY_SIZE(test_params); i++) {
31 pbn = drm_dp_calc_pbn_mode(test_params[i].rate,
32 test_params[i].bpp,
33 test_params[i].dsc);
34 FAIL(pbn != test_params[i].expected,
35 "Expected PBN %d for clock %d bpp %d, got %d\n",
36 test_params[i].expected, test_params[i].rate,
37 test_params[i].bpp, pbn);
40 return 0;
43 static bool
44 sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in,
45 const struct drm_dp_sideband_msg_req_body *out)
47 const struct drm_dp_remote_i2c_read_tx *txin, *txout;
48 int i;
50 if (in->req_type != out->req_type)
51 return false;
53 switch (in->req_type) {
55 * Compare struct members manually for request types which can't be
56 * compared simply using memcmp(). This is because said request types
57 * contain pointers to other allocated structs
59 case DP_REMOTE_I2C_READ:
60 #define IN in->u.i2c_read
61 #define OUT out->u.i2c_read
62 if (IN.num_bytes_read != OUT.num_bytes_read ||
63 IN.num_transactions != OUT.num_transactions ||
64 IN.port_number != OUT.port_number ||
65 IN.read_i2c_device_id != OUT.read_i2c_device_id)
66 return false;
68 for (i = 0; i < IN.num_transactions; i++) {
69 txin = &IN.transactions[i];
70 txout = &OUT.transactions[i];
72 if (txin->i2c_dev_id != txout->i2c_dev_id ||
73 txin->no_stop_bit != txout->no_stop_bit ||
74 txin->num_bytes != txout->num_bytes ||
75 txin->i2c_transaction_delay !=
76 txout->i2c_transaction_delay)
77 return false;
79 if (memcmp(txin->bytes, txout->bytes,
80 txin->num_bytes) != 0)
81 return false;
83 break;
84 #undef IN
85 #undef OUT
87 case DP_REMOTE_DPCD_WRITE:
88 #define IN in->u.dpcd_write
89 #define OUT out->u.dpcd_write
90 if (IN.dpcd_address != OUT.dpcd_address ||
91 IN.num_bytes != OUT.num_bytes ||
92 IN.port_number != OUT.port_number)
93 return false;
95 return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0;
96 #undef IN
97 #undef OUT
99 case DP_REMOTE_I2C_WRITE:
100 #define IN in->u.i2c_write
101 #define OUT out->u.i2c_write
102 if (IN.port_number != OUT.port_number ||
103 IN.write_i2c_device_id != OUT.write_i2c_device_id ||
104 IN.num_bytes != OUT.num_bytes)
105 return false;
107 return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0;
108 #undef IN
109 #undef OUT
111 default:
112 return memcmp(in, out, sizeof(*in)) == 0;
115 return true;
118 static bool
119 sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in)
121 struct drm_dp_sideband_msg_req_body out = {0};
122 struct drm_printer p = drm_err_printer(PREFIX_STR);
123 struct drm_dp_sideband_msg_tx txmsg;
124 int i, ret;
126 drm_dp_encode_sideband_req(in, &txmsg);
127 ret = drm_dp_decode_sideband_req(&txmsg, &out);
128 if (ret < 0) {
129 drm_printf(&p, "Failed to decode sideband request: %d\n",
130 ret);
131 return false;
134 if (!sideband_msg_req_equal(in, &out)) {
135 drm_printf(&p, "Encode/decode failed, expected:\n");
136 drm_dp_dump_sideband_msg_req_body(in, 1, &p);
137 drm_printf(&p, "Got:\n");
138 drm_dp_dump_sideband_msg_req_body(&out, 1, &p);
139 return false;
142 switch (in->req_type) {
143 case DP_REMOTE_DPCD_WRITE:
144 kfree(out.u.dpcd_write.bytes);
145 break;
146 case DP_REMOTE_I2C_READ:
147 for (i = 0; i < out.u.i2c_read.num_transactions; i++)
148 kfree(out.u.i2c_read.transactions[i].bytes);
149 break;
150 case DP_REMOTE_I2C_WRITE:
151 kfree(out.u.i2c_write.bytes);
152 break;
155 /* Clear everything but the req_type for the input */
156 memset(&in->u, 0, sizeof(in->u));
158 return true;
161 int igt_dp_mst_sideband_msg_req_decode(void *unused)
163 struct drm_dp_sideband_msg_req_body in = { 0 };
164 u8 data[] = { 0xff, 0x0, 0xdd };
165 int i;
167 #define DO_TEST() FAIL_ON(!sideband_msg_req_encode_decode(&in))
169 in.req_type = DP_ENUM_PATH_RESOURCES;
170 in.u.port_num.port_number = 5;
171 DO_TEST();
173 in.req_type = DP_POWER_UP_PHY;
174 in.u.port_num.port_number = 5;
175 DO_TEST();
177 in.req_type = DP_POWER_DOWN_PHY;
178 in.u.port_num.port_number = 5;
179 DO_TEST();
181 in.req_type = DP_ALLOCATE_PAYLOAD;
182 in.u.allocate_payload.number_sdp_streams = 3;
183 for (i = 0; i < in.u.allocate_payload.number_sdp_streams; i++)
184 in.u.allocate_payload.sdp_stream_sink[i] = i + 1;
185 DO_TEST();
186 in.u.allocate_payload.port_number = 0xf;
187 DO_TEST();
188 in.u.allocate_payload.vcpi = 0x7f;
189 DO_TEST();
190 in.u.allocate_payload.pbn = U16_MAX;
191 DO_TEST();
193 in.req_type = DP_QUERY_PAYLOAD;
194 in.u.query_payload.port_number = 0xf;
195 DO_TEST();
196 in.u.query_payload.vcpi = 0x7f;
197 DO_TEST();
199 in.req_type = DP_REMOTE_DPCD_READ;
200 in.u.dpcd_read.port_number = 0xf;
201 DO_TEST();
202 in.u.dpcd_read.dpcd_address = 0xfedcb;
203 DO_TEST();
204 in.u.dpcd_read.num_bytes = U8_MAX;
205 DO_TEST();
207 in.req_type = DP_REMOTE_DPCD_WRITE;
208 in.u.dpcd_write.port_number = 0xf;
209 DO_TEST();
210 in.u.dpcd_write.dpcd_address = 0xfedcb;
211 DO_TEST();
212 in.u.dpcd_write.num_bytes = ARRAY_SIZE(data);
213 in.u.dpcd_write.bytes = data;
214 DO_TEST();
216 in.req_type = DP_REMOTE_I2C_READ;
217 in.u.i2c_read.port_number = 0xf;
218 DO_TEST();
219 in.u.i2c_read.read_i2c_device_id = 0x7f;
220 DO_TEST();
221 in.u.i2c_read.num_transactions = 3;
222 in.u.i2c_read.num_bytes_read = ARRAY_SIZE(data) * 3;
223 for (i = 0; i < in.u.i2c_read.num_transactions; i++) {
224 in.u.i2c_read.transactions[i].bytes = data;
225 in.u.i2c_read.transactions[i].num_bytes = ARRAY_SIZE(data);
226 in.u.i2c_read.transactions[i].i2c_dev_id = 0x7f & ~i;
227 in.u.i2c_read.transactions[i].i2c_transaction_delay = 0xf & ~i;
229 DO_TEST();
231 in.req_type = DP_REMOTE_I2C_WRITE;
232 in.u.i2c_write.port_number = 0xf;
233 DO_TEST();
234 in.u.i2c_write.write_i2c_device_id = 0x7f;
235 DO_TEST();
236 in.u.i2c_write.num_bytes = ARRAY_SIZE(data);
237 in.u.i2c_write.bytes = data;
238 DO_TEST();
240 #undef DO_TEST
241 return 0;