Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Test cases for the DRM DP MST helpers
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      * Compare struct members manually for request types which can't be
0058      * compared simply using memcmp(). This is because said request types
0059      * contain pointers to other allocated structs
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     /* Clear everything but the req_type for the input */
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 }