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