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.6 242 lines 6.1 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 <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 14int 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 bool dsc; 22 } test_params[] = { 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 }, 28 }; 29 30 for (i = 0; i < ARRAY_SIZE(test_params); i++) { 31 pbn = drm_dp_calc_pbn_mode(test_params[i].rate, 32 test_params[i].bpp, 33 test_params[i].dsc); 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); 38 } 39 40 return 0; 41} 42 43static bool 44sideband_msg_req_equal(const struct drm_dp_sideband_msg_req_body *in, 45 const struct drm_dp_sideband_msg_req_body *out) 46{ 47 const struct drm_dp_remote_i2c_read_tx *txin, *txout; 48 int i; 49 50 if (in->req_type != out->req_type) 51 return false; 52 53 switch (in->req_type) { 54 /* 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 58 */ 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) 66 return false; 67 68 for (i = 0; i < IN.num_transactions; i++) { 69 txin = &IN.transactions[i]; 70 txout = &OUT.transactions[i]; 71 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) 77 return false; 78 79 if (memcmp(txin->bytes, txout->bytes, 80 txin->num_bytes) != 0) 81 return false; 82 } 83 break; 84#undef IN 85#undef OUT 86 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) 93 return false; 94 95 return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0; 96#undef IN 97#undef OUT 98 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) 105 return false; 106 107 return memcmp(IN.bytes, OUT.bytes, IN.num_bytes) == 0; 108#undef IN 109#undef OUT 110 111 default: 112 return memcmp(in, out, sizeof(*in)) == 0; 113 } 114 115 return true; 116} 117 118static bool 119sideband_msg_req_encode_decode(struct drm_dp_sideband_msg_req_body *in) 120{ 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; 124 int i, ret; 125 126 drm_dp_encode_sideband_req(in, &txmsg); 127 ret = drm_dp_decode_sideband_req(&txmsg, &out); 128 if (ret < 0) { 129 drm_printf(&p, "Failed to decode sideband request: %d\n", 130 ret); 131 return false; 132 } 133 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); 139 return false; 140 } 141 142 switch (in->req_type) { 143 case DP_REMOTE_DPCD_WRITE: 144 kfree(out.u.dpcd_write.bytes); 145 break; 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); 149 break; 150 case DP_REMOTE_I2C_WRITE: 151 kfree(out.u.i2c_write.bytes); 152 break; 153 } 154 155 /* Clear everything but the req_type for the input */ 156 memset(&in->u, 0, sizeof(in->u)); 157 158 return true; 159} 160 161int igt_dp_mst_sideband_msg_req_decode(void *unused) 162{ 163 struct drm_dp_sideband_msg_req_body in = { 0 }; 164 u8 data[] = { 0xff, 0x0, 0xdd }; 165 int i; 166 167#define DO_TEST() FAIL_ON(!sideband_msg_req_encode_decode(&in)) 168 169 in.req_type = DP_ENUM_PATH_RESOURCES; 170 in.u.port_num.port_number = 5; 171 DO_TEST(); 172 173 in.req_type = DP_POWER_UP_PHY; 174 in.u.port_num.port_number = 5; 175 DO_TEST(); 176 177 in.req_type = DP_POWER_DOWN_PHY; 178 in.u.port_num.port_number = 5; 179 DO_TEST(); 180 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; 185 DO_TEST(); 186 in.u.allocate_payload.port_number = 0xf; 187 DO_TEST(); 188 in.u.allocate_payload.vcpi = 0x7f; 189 DO_TEST(); 190 in.u.allocate_payload.pbn = U16_MAX; 191 DO_TEST(); 192 193 in.req_type = DP_QUERY_PAYLOAD; 194 in.u.query_payload.port_number = 0xf; 195 DO_TEST(); 196 in.u.query_payload.vcpi = 0x7f; 197 DO_TEST(); 198 199 in.req_type = DP_REMOTE_DPCD_READ; 200 in.u.dpcd_read.port_number = 0xf; 201 DO_TEST(); 202 in.u.dpcd_read.dpcd_address = 0xfedcb; 203 DO_TEST(); 204 in.u.dpcd_read.num_bytes = U8_MAX; 205 DO_TEST(); 206 207 in.req_type = DP_REMOTE_DPCD_WRITE; 208 in.u.dpcd_write.port_number = 0xf; 209 DO_TEST(); 210 in.u.dpcd_write.dpcd_address = 0xfedcb; 211 DO_TEST(); 212 in.u.dpcd_write.num_bytes = ARRAY_SIZE(data); 213 in.u.dpcd_write.bytes = data; 214 DO_TEST(); 215 216 in.req_type = DP_REMOTE_I2C_READ; 217 in.u.i2c_read.port_number = 0xf; 218 DO_TEST(); 219 in.u.i2c_read.read_i2c_device_id = 0x7f; 220 DO_TEST(); 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; 228 } 229 DO_TEST(); 230 231 in.req_type = DP_REMOTE_I2C_WRITE; 232 in.u.i2c_write.port_number = 0xf; 233 DO_TEST(); 234 in.u.i2c_write.write_i2c_device_id = 0x7f; 235 DO_TEST(); 236 in.u.i2c_write.num_bytes = ARRAY_SIZE(data); 237 in.u.i2c_write.bytes = data; 238 DO_TEST(); 239 240#undef DO_TEST 241 return 0; 242}