0001
0002
0003
0004
0005
0006 #define PREFIX_STR "[drm_dp_mst_helper]"
0007
0008 #include <linux/random.h>
0009
0010 #include <drm/display/drm_dp_mst_helper.h>
0011 #include <drm/drm_print.h>
0012
0013 #include "../display/drm_dp_mst_topology_internal.h"
0014 #include "test-drm_modeset_common.h"
0015
0016 int igt_dp_mst_calc_pbn_mode(void *ignored)
0017 {
0018 int pbn, i;
0019 const struct {
0020 int rate;
0021 int bpp;
0022 int expected;
0023 bool dsc;
0024 } test_params[] = {
0025 { 154000, 30, 689, false },
0026 { 234000, 30, 1047, false },
0027 { 297000, 24, 1063, false },
0028 { 332880, 24, 50, true },
0029 { 324540, 24, 49, true },
0030 };
0031
0032 for (i = 0; i < ARRAY_SIZE(test_params); i++) {
0033 pbn = drm_dp_calc_pbn_mode(test_params[i].rate,
0034 test_params[i].bpp,
0035 test_params[i].dsc);
0036 FAIL(pbn != test_params[i].expected,
0037 "Expected PBN %d for clock %d bpp %d, got %d\n",
0038 test_params[i].expected, test_params[i].rate,
0039 test_params[i].bpp, pbn);
0040 }
0041
0042 return 0;
0043 }
0044
0045 static bool
0046 sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in,
0047 const struct drm_dp_sideband_msg_req_body *out)
0048 {
0049 const struct drm_dp_remote_i2c_read_tx *txin, *txout;
0050 int i;
0051
0052 if (in->req_type != out->req_type)
0053 return false;
0054
0055 switch (in->req_type) {
0056
0057
0058
0059
0060
0061 case DP_REMOTE_I2C_READ:
0062 #define IN in->u.i2c_read
0063 #define OUT out->u.i2c_read
0064 if (IN.num_bytes_read != OUT.num_bytes_read ||
0065 IN.num_transactions != OUT.num_transactions ||
0066 IN.port_number != OUT.port_number ||
0067 IN.read_i2c_device_id != OUT.read_i2c_device_id)
0068 return false;
0069
0070 for (i = 0; i < IN.num_transactions; i++) {
0071 txin = &IN.transactions[i];
0072 txout = &OUT.transactions[i];
0073
0074 if (txin->i2c_dev_id != txout->i2c_dev_id ||
0075 txin->no_stop_bit != txout->no_stop_bit ||
0076 txin->num_bytes != txout->num_bytes ||
0077 txin->i2c_transaction_delay !=
0078 txout->i2c_transaction_delay)
0079 return false;
0080
0081 if (memcmp(txin->bytes, txout->bytes,
0082 txin->num_bytes) != 0)
0083 return false;
0084 }
0085 break;
0086 #undef IN
0087 #undef OUT
0088
0089 case DP_REMOTE_DPCD_WRITE:
0090 #define IN in->u.dpcd_write
0091 #define OUT out->u.dpcd_write
0092 if (IN.dpcd_address != OUT.dpcd_address ||
0093 IN.num_bytes != OUT.num_bytes ||
0094 IN.port_number != OUT.port_number)
0095 return false;
0096
0097 return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0;
0098 #undef IN
0099 #undef OUT
0100
0101 case DP_REMOTE_I2C_WRITE:
0102 #define IN in->u.i2c_write
0103 #define OUT out->u.i2c_write
0104 if (IN.port_number != OUT.port_number ||
0105 IN.write_i2c_device_id != OUT.write_i2c_device_id ||
0106 IN.num_bytes != OUT.num_bytes)
0107 return false;
0108
0109 return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0;
0110 #undef IN
0111 #undef OUT
0112
0113 default:
0114 return memcmp(in, out, sizeof(*in)) == 0;
0115 }
0116
0117 return true;
0118 }
0119
0120 static bool
0121 sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in)
0122 {
0123 struct drm_dp_sideband_msg_req_body *out;
0124 struct drm_printer p = drm_err_printer(PREFIX_STR);
0125 struct drm_dp_sideband_msg_tx *txmsg;
0126 int i, ret;
0127 bool result = true;
0128
0129 out = kzalloc(sizeof(*out), GFP_KERNEL);
0130 if (!out)
0131 return false;
0132
0133 txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
0134 if (!txmsg) {
0135 kfree(out);
0136 return false;
0137 }
0138
0139 drm_dp_encode_sideband_req(in, txmsg);
0140 ret = drm_dp_decode_sideband_req(txmsg, out);
0141 if (ret < 0) {
0142 drm_printf(&p, "Failed to decode sideband request: %d\n",
0143 ret);
0144 result = false;
0145 goto out;
0146 }
0147
0148 if (!sideband_msg_req_equal(in, out)) {
0149 drm_printf(&p, "Encode/decode failed, expected:\n");
0150 drm_dp_dump_sideband_msg_req_body(in, 1, &p);
0151 drm_printf(&p, "Got:\n");
0152 drm_dp_dump_sideband_msg_req_body(out, 1, &p);
0153 result = false;
0154 goto out;
0155 }
0156
0157 switch (in->req_type) {
0158 case DP_REMOTE_DPCD_WRITE:
0159 kfree(out->u.dpcd_write.bytes);
0160 break;
0161 case DP_REMOTE_I2C_READ:
0162 for (i = 0; i < out->u.i2c_read.num_transactions; i++)
0163 kfree(out->u.i2c_read.transactions[i].bytes);
0164 break;
0165 case DP_REMOTE_I2C_WRITE:
0166 kfree(out->u.i2c_write.bytes);
0167 break;
0168 }
0169
0170
0171 memset(&in->u, 0, sizeof(in->u));
0172
0173 out:
0174 kfree(out);
0175 kfree(txmsg);
0176 return result;
0177 }
0178
0179 int igt_dp_mst_sideband_msg_req_decode(void *unused)
0180 {
0181 struct drm_dp_sideband_msg_req_body in = { 0 };
0182 u8 data[] = { 0xff, 0x0, 0xdd };
0183 int i;
0184
0185 #define DO_TEST() FAIL_ON(!sideband_msg_req_encode_decode(&in))
0186
0187 in.req_type = DP_ENUM_PATH_RESOURCES;
0188 in.u.port_num.port_number = 5;
0189 DO_TEST();
0190
0191 in.req_type = DP_POWER_UP_PHY;
0192 in.u.port_num.port_number = 5;
0193 DO_TEST();
0194
0195 in.req_type = DP_POWER_DOWN_PHY;
0196 in.u.port_num.port_number = 5;
0197 DO_TEST();
0198
0199 in.req_type = DP_ALLOCATE_PAYLOAD;
0200 in.u.allocate_payload.number_sdp_streams = 3;
0201 for (i = 0; i < in.u.allocate_payload.number_sdp_streams; i++)
0202 in.u.allocate_payload.sdp_stream_sink[i] = i + 1;
0203 DO_TEST();
0204 in.u.allocate_payload.port_number = 0xf;
0205 DO_TEST();
0206 in.u.allocate_payload.vcpi = 0x7f;
0207 DO_TEST();
0208 in.u.allocate_payload.pbn = U16_MAX;
0209 DO_TEST();
0210
0211 in.req_type = DP_QUERY_PAYLOAD;
0212 in.u.query_payload.port_number = 0xf;
0213 DO_TEST();
0214 in.u.query_payload.vcpi = 0x7f;
0215 DO_TEST();
0216
0217 in.req_type = DP_REMOTE_DPCD_READ;
0218 in.u.dpcd_read.port_number = 0xf;
0219 DO_TEST();
0220 in.u.dpcd_read.dpcd_address = 0xfedcb;
0221 DO_TEST();
0222 in.u.dpcd_read.num_bytes = U8_MAX;
0223 DO_TEST();
0224
0225 in.req_type = DP_REMOTE_DPCD_WRITE;
0226 in.u.dpcd_write.port_number = 0xf;
0227 DO_TEST();
0228 in.u.dpcd_write.dpcd_address = 0xfedcb;
0229 DO_TEST();
0230 in.u.dpcd_write.num_bytes = ARRAY_SIZE(data);
0231 in.u.dpcd_write.bytes = data;
0232 DO_TEST();
0233
0234 in.req_type = DP_REMOTE_I2C_READ;
0235 in.u.i2c_read.port_number = 0xf;
0236 DO_TEST();
0237 in.u.i2c_read.read_i2c_device_id = 0x7f;
0238 DO_TEST();
0239 in.u.i2c_read.num_transactions = 3;
0240 in.u.i2c_read.num_bytes_read = ARRAY_SIZE(data) * 3;
0241 for (i = 0; i < in.u.i2c_read.num_transactions; i++) {
0242 in.u.i2c_read.transactions[i].bytes = data;
0243 in.u.i2c_read.transactions[i].num_bytes = ARRAY_SIZE(data);
0244 in.u.i2c_read.transactions[i].i2c_dev_id = 0x7f & ~i;
0245 in.u.i2c_read.transactions[i].i2c_transaction_delay = 0xf & ~i;
0246 }
0247 DO_TEST();
0248
0249 in.req_type = DP_REMOTE_I2C_WRITE;
0250 in.u.i2c_write.port_number = 0xf;
0251 DO_TEST();
0252 in.u.i2c_write.write_i2c_device_id = 0x7f;
0253 DO_TEST();
0254 in.u.i2c_write.num_bytes = ARRAY_SIZE(data);
0255 in.u.i2c_write.bytes = data;
0256 DO_TEST();
0257
0258 in.req_type = DP_QUERY_STREAM_ENC_STATUS;
0259 in.u.enc_status.stream_id = 1;
0260 DO_TEST();
0261 get_random_bytes(in.u.enc_status.client_id,
0262 sizeof(in.u.enc_status.client_id));
0263 DO_TEST();
0264 in.u.enc_status.stream_event = 3;
0265 DO_TEST();
0266 in.u.enc_status.valid_stream_event = 0;
0267 DO_TEST();
0268 in.u.enc_status.stream_behavior = 3;
0269 DO_TEST();
0270 in.u.enc_status.valid_stream_behavior = 1;
0271 DO_TEST();
0272
0273 #undef DO_TEST
0274 return 0;
0275 }