Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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