1 // SPDX-License-Identifier: GPL-2.0-only
3 * Test cases for for the DRM DP MST helpers
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
)
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
,
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
);
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
;
50 if (in
->req_type
!= out
->req_type
)
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
)
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
)
79 if (memcmp(txin
->bytes
, txout
->bytes
,
80 txin
->num_bytes
) != 0)
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
)
95 return memcmp(IN
.bytes
, OUT
.bytes
, IN
.num_bytes
) == 0;
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
)
107 return memcmp(IN
.bytes
, OUT
.bytes
, IN
.num_bytes
) == 0;
112 return memcmp(in
, out
, sizeof(*in
)) == 0;
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
;
126 drm_dp_encode_sideband_req(in
, &txmsg
);
127 ret
= drm_dp_decode_sideband_req(&txmsg
, &out
);
129 drm_printf(&p
, "Failed to decode sideband request: %d\n",
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
);
142 switch (in
->req_type
) {
143 case DP_REMOTE_DPCD_WRITE
:
144 kfree(out
.u
.dpcd_write
.bytes
);
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
);
150 case DP_REMOTE_I2C_WRITE
:
151 kfree(out
.u
.i2c_write
.bytes
);
155 /* Clear everything but the req_type for the input */
156 memset(&in
->u
, 0, sizeof(in
->u
));
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 };
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;
173 in
.req_type
= DP_POWER_UP_PHY
;
174 in
.u
.port_num
.port_number
= 5;
177 in
.req_type
= DP_POWER_DOWN_PHY
;
178 in
.u
.port_num
.port_number
= 5;
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;
186 in
.u
.allocate_payload
.port_number
= 0xf;
188 in
.u
.allocate_payload
.vcpi
= 0x7f;
190 in
.u
.allocate_payload
.pbn
= U16_MAX
;
193 in
.req_type
= DP_QUERY_PAYLOAD
;
194 in
.u
.query_payload
.port_number
= 0xf;
196 in
.u
.query_payload
.vcpi
= 0x7f;
199 in
.req_type
= DP_REMOTE_DPCD_READ
;
200 in
.u
.dpcd_read
.port_number
= 0xf;
202 in
.u
.dpcd_read
.dpcd_address
= 0xfedcb;
204 in
.u
.dpcd_read
.num_bytes
= U8_MAX
;
207 in
.req_type
= DP_REMOTE_DPCD_WRITE
;
208 in
.u
.dpcd_write
.port_number
= 0xf;
210 in
.u
.dpcd_write
.dpcd_address
= 0xfedcb;
212 in
.u
.dpcd_write
.num_bytes
= ARRAY_SIZE(data
);
213 in
.u
.dpcd_write
.bytes
= data
;
216 in
.req_type
= DP_REMOTE_I2C_READ
;
217 in
.u
.i2c_read
.port_number
= 0xf;
219 in
.u
.i2c_read
.read_i2c_device_id
= 0x7f;
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
;
231 in
.req_type
= DP_REMOTE_I2C_WRITE
;
232 in
.u
.i2c_write
.port_number
= 0xf;
234 in
.u
.i2c_write
.write_i2c_device_id
= 0x7f;
236 in
.u
.i2c_write
.num_bytes
= ARRAY_SIZE(data
);
237 in
.u
.i2c_write
.bytes
= data
;