1 /* 2 * Copyright 2019 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include "dc_bios_types.h" 27 #include "dcn31_hpo_dp_link_encoder.h" 28 #include "reg_helper.h" 29 #include "dc_link.h" 30 #include "stream_encoder.h" 31 32 #define DC_LOGGER \ 33 enc3->base.ctx->logger 34 35 #define REG(reg)\ 36 (enc3->regs->reg) 37 38 #undef FN 39 #define FN(reg_name, field_name) \ 40 enc3->hpo_le_shift->field_name, enc3->hpo_le_mask->field_name 41 42 43 #define CTX \ 44 enc3->base.ctx 45 46 enum { 47 DP_SAT_UPDATE_MAX_RETRY = 200 48 }; 49 50 void dcn31_hpo_dp_link_enc_enable( 51 struct hpo_dp_link_encoder *enc, 52 enum dc_lane_count num_lanes) 53 { 54 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); 55 uint32_t dp_link_enabled; 56 57 /* get current status of link enabled */ 58 REG_GET(DP_DPHY_SYM32_STATUS, 59 STATUS, &dp_link_enabled); 60 61 /* Enable clocks first */ 62 REG_UPDATE(DP_LINK_ENC_CLOCK_CONTROL, DP_LINK_ENC_CLOCK_EN, 1); 63 64 /* Reset DPHY. Only reset if going from disable to enable */ 65 if (!dp_link_enabled) { 66 REG_UPDATE(DP_DPHY_SYM32_CONTROL, DPHY_RESET, 1); 67 REG_UPDATE(DP_DPHY_SYM32_CONTROL, DPHY_RESET, 0); 68 } 69 70 /* Configure DPHY settings */ 71 REG_UPDATE_3(DP_DPHY_SYM32_CONTROL, 72 DPHY_ENABLE, 1, 73 PRECODER_ENABLE, 1, 74 NUM_LANES, num_lanes == LANE_COUNT_ONE ? 0 : num_lanes == LANE_COUNT_TWO ? 1 : 3); 75 } 76 77 void dcn31_hpo_dp_link_enc_disable( 78 struct hpo_dp_link_encoder *enc) 79 { 80 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); 81 82 /* Configure DPHY settings */ 83 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 84 DPHY_ENABLE, 0); 85 86 /* Shut down clock last */ 87 REG_UPDATE(DP_LINK_ENC_CLOCK_CONTROL, DP_LINK_ENC_CLOCK_EN, 0); 88 } 89 90 void dcn31_hpo_dp_link_enc_set_link_test_pattern( 91 struct hpo_dp_link_encoder *enc, 92 struct encoder_set_dp_phy_pattern_param *tp_params) 93 { 94 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); 95 uint32_t tp_custom; 96 97 switch (tp_params->dp_phy_pattern) { 98 case DP_TEST_PATTERN_VIDEO_MODE: 99 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 100 MODE, DP2_LINK_ACTIVE); 101 break; 102 case DP_TEST_PATTERN_128b_132b_TPS1_TRAINING_MODE: 103 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 104 MODE, DP2_LINK_TRAINING_TPS1); 105 break; 106 case DP_TEST_PATTERN_128b_132b_TPS2_TRAINING_MODE: 107 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 108 MODE, DP2_LINK_TRAINING_TPS2); 109 break; 110 case DP_TEST_PATTERN_128b_132b_TPS1: 111 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 112 TP_SELECT0, DP_DPHY_TP_SELECT_TPS1, 113 TP_SELECT1, DP_DPHY_TP_SELECT_TPS1, 114 TP_SELECT2, DP_DPHY_TP_SELECT_TPS1, 115 TP_SELECT3, DP_DPHY_TP_SELECT_TPS1); 116 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 117 MODE, DP2_TEST_PATTERN); 118 break; 119 case DP_TEST_PATTERN_128b_132b_TPS2: 120 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 121 TP_SELECT0, DP_DPHY_TP_SELECT_TPS2, 122 TP_SELECT1, DP_DPHY_TP_SELECT_TPS2, 123 TP_SELECT2, DP_DPHY_TP_SELECT_TPS2, 124 TP_SELECT3, DP_DPHY_TP_SELECT_TPS2); 125 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 126 MODE, DP2_TEST_PATTERN); 127 break; 128 case DP_TEST_PATTERN_PRBS7: 129 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 130 TP_PRBS_SEL0, DP_DPHY_TP_PRBS7, 131 TP_PRBS_SEL1, DP_DPHY_TP_PRBS7, 132 TP_PRBS_SEL2, DP_DPHY_TP_PRBS7, 133 TP_PRBS_SEL3, DP_DPHY_TP_PRBS7); 134 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 135 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS, 136 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS, 137 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS, 138 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS); 139 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 140 MODE, DP2_TEST_PATTERN); 141 break; 142 case DP_TEST_PATTERN_PRBS9: 143 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 144 TP_PRBS_SEL0, DP_DPHY_TP_PRBS9, 145 TP_PRBS_SEL1, DP_DPHY_TP_PRBS9, 146 TP_PRBS_SEL2, DP_DPHY_TP_PRBS9, 147 TP_PRBS_SEL3, DP_DPHY_TP_PRBS9); 148 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 149 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS, 150 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS, 151 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS, 152 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS); 153 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 154 MODE, DP2_TEST_PATTERN); 155 break; 156 case DP_TEST_PATTERN_PRBS11: 157 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 158 TP_PRBS_SEL0, DP_DPHY_TP_PRBS11, 159 TP_PRBS_SEL1, DP_DPHY_TP_PRBS11, 160 TP_PRBS_SEL2, DP_DPHY_TP_PRBS11, 161 TP_PRBS_SEL3, DP_DPHY_TP_PRBS11); 162 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 163 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS, 164 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS, 165 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS, 166 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS); 167 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 168 MODE, DP2_TEST_PATTERN); 169 break; 170 case DP_TEST_PATTERN_PRBS15: 171 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 172 TP_PRBS_SEL0, DP_DPHY_TP_PRBS15, 173 TP_PRBS_SEL1, DP_DPHY_TP_PRBS15, 174 TP_PRBS_SEL2, DP_DPHY_TP_PRBS15, 175 TP_PRBS_SEL3, DP_DPHY_TP_PRBS15); 176 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 177 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS, 178 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS, 179 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS, 180 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS); 181 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 182 MODE, DP2_TEST_PATTERN); 183 break; 184 case DP_TEST_PATTERN_PRBS23: 185 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 186 TP_PRBS_SEL0, DP_DPHY_TP_PRBS23, 187 TP_PRBS_SEL1, DP_DPHY_TP_PRBS23, 188 TP_PRBS_SEL2, DP_DPHY_TP_PRBS23, 189 TP_PRBS_SEL3, DP_DPHY_TP_PRBS23); 190 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 191 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS, 192 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS, 193 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS, 194 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS); 195 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 196 MODE, DP2_TEST_PATTERN); 197 break; 198 case DP_TEST_PATTERN_PRBS31: 199 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 200 TP_PRBS_SEL0, DP_DPHY_TP_PRBS31, 201 TP_PRBS_SEL1, DP_DPHY_TP_PRBS31, 202 TP_PRBS_SEL2, DP_DPHY_TP_PRBS31, 203 TP_PRBS_SEL3, DP_DPHY_TP_PRBS31); 204 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 205 TP_SELECT0, DP_DPHY_TP_SELECT_PRBS, 206 TP_SELECT1, DP_DPHY_TP_SELECT_PRBS, 207 TP_SELECT2, DP_DPHY_TP_SELECT_PRBS, 208 TP_SELECT3, DP_DPHY_TP_SELECT_PRBS); 209 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 210 MODE, DP2_TEST_PATTERN); 211 break; 212 case DP_TEST_PATTERN_264BIT_CUSTOM: 213 tp_custom = (tp_params->custom_pattern[2] << 16) | (tp_params->custom_pattern[1] << 8) | tp_params->custom_pattern[0]; 214 REG_SET(DP_DPHY_SYM32_TP_CUSTOM0, 0, TP_CUSTOM, tp_custom); 215 tp_custom = (tp_params->custom_pattern[5] << 16) | (tp_params->custom_pattern[4] << 8) | tp_params->custom_pattern[3]; 216 REG_SET(DP_DPHY_SYM32_TP_CUSTOM1, 0, TP_CUSTOM, tp_custom); 217 tp_custom = (tp_params->custom_pattern[8] << 16) | (tp_params->custom_pattern[7] << 8) | tp_params->custom_pattern[6]; 218 REG_SET(DP_DPHY_SYM32_TP_CUSTOM2, 0, TP_CUSTOM, tp_custom); 219 tp_custom = (tp_params->custom_pattern[11] << 16) | (tp_params->custom_pattern[10] << 8) | tp_params->custom_pattern[9]; 220 REG_SET(DP_DPHY_SYM32_TP_CUSTOM3, 0, TP_CUSTOM, tp_custom); 221 tp_custom = (tp_params->custom_pattern[14] << 16) | (tp_params->custom_pattern[13] << 8) | tp_params->custom_pattern[12]; 222 REG_SET(DP_DPHY_SYM32_TP_CUSTOM4, 0, TP_CUSTOM, tp_custom); 223 tp_custom = (tp_params->custom_pattern[17] << 16) | (tp_params->custom_pattern[16] << 8) | tp_params->custom_pattern[15]; 224 REG_SET(DP_DPHY_SYM32_TP_CUSTOM5, 0, TP_CUSTOM, tp_custom); 225 tp_custom = (tp_params->custom_pattern[20] << 16) | (tp_params->custom_pattern[19] << 8) | tp_params->custom_pattern[18]; 226 REG_SET(DP_DPHY_SYM32_TP_CUSTOM6, 0, TP_CUSTOM, tp_custom); 227 tp_custom = (tp_params->custom_pattern[23] << 16) | (tp_params->custom_pattern[22] << 8) | tp_params->custom_pattern[21]; 228 REG_SET(DP_DPHY_SYM32_TP_CUSTOM7, 0, TP_CUSTOM, tp_custom); 229 tp_custom = (tp_params->custom_pattern[26] << 16) | (tp_params->custom_pattern[25] << 8) | tp_params->custom_pattern[24]; 230 REG_SET(DP_DPHY_SYM32_TP_CUSTOM8, 0, TP_CUSTOM, tp_custom); 231 tp_custom = (tp_params->custom_pattern[29] << 16) | (tp_params->custom_pattern[28] << 8) | tp_params->custom_pattern[27]; 232 REG_SET(DP_DPHY_SYM32_TP_CUSTOM9, 0, TP_CUSTOM, tp_custom); 233 tp_custom = (tp_params->custom_pattern[32] << 16) | (tp_params->custom_pattern[31] << 8) | tp_params->custom_pattern[30]; 234 REG_SET(DP_DPHY_SYM32_TP_CUSTOM10, 0, TP_CUSTOM, tp_custom); 235 236 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 237 TP_SELECT0, DP_DPHY_TP_SELECT_CUSTOM, 238 TP_SELECT1, DP_DPHY_TP_SELECT_CUSTOM, 239 TP_SELECT2, DP_DPHY_TP_SELECT_CUSTOM, 240 TP_SELECT3, DP_DPHY_TP_SELECT_CUSTOM); 241 242 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 243 MODE, DP2_TEST_PATTERN); 244 break; 245 case DP_TEST_PATTERN_SQUARE: 246 case DP_TEST_PATTERN_SQUARE_PRESHOOT_DISABLED: 247 case DP_TEST_PATTERN_SQUARE_DEEMPHASIS_DISABLED: 248 case DP_TEST_PATTERN_SQUARE_PRESHOOT_DEEMPHASIS_DISABLED: 249 REG_SET(DP_DPHY_SYM32_TP_SQ_PULSE, 0, 250 TP_SQ_PULSE_WIDTH, tp_params->custom_pattern[0]); 251 252 REG_UPDATE_4(DP_DPHY_SYM32_TP_CONFIG, 253 TP_SELECT0, DP_DPHY_TP_SELECT_SQUARE, 254 TP_SELECT1, DP_DPHY_TP_SELECT_SQUARE, 255 TP_SELECT2, DP_DPHY_TP_SELECT_SQUARE, 256 TP_SELECT3, DP_DPHY_TP_SELECT_SQUARE); 257 258 REG_UPDATE(DP_DPHY_SYM32_CONTROL, 259 MODE, DP2_TEST_PATTERN); 260 break; 261 default: 262 break; 263 } 264 } 265 266 static void fill_stream_allocation_row_info( 267 const struct link_mst_stream_allocation *stream_allocation, 268 uint32_t *src, 269 uint32_t *slots) 270 { 271 const struct hpo_dp_stream_encoder *stream_enc = stream_allocation->hpo_dp_stream_enc; 272 273 if (stream_enc && (stream_enc->id >= ENGINE_ID_HPO_DP_0)) { 274 *src = stream_enc->id - ENGINE_ID_HPO_DP_0; 275 *slots = stream_allocation->slot_count; 276 } else { 277 *src = 0; 278 *slots = 0; 279 } 280 } 281 282 /* programs DP VC payload allocation */ 283 void dcn31_hpo_dp_link_enc_update_stream_allocation_table( 284 struct hpo_dp_link_encoder *enc, 285 const struct link_mst_stream_allocation_table *table) 286 { 287 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); 288 uint32_t slots = 0; 289 uint32_t src = 0; 290 291 /* --- Set MSE Stream Attribute - 292 * Setup VC Payload Table on Tx Side, 293 * Issue allocation change trigger 294 * to commit payload on both tx and rx side 295 */ 296 297 /* we should clean-up table each time */ 298 299 if (table->stream_count >= 1) { 300 fill_stream_allocation_row_info( 301 &table->stream_allocations[0], 302 &src, 303 &slots); 304 } else { 305 src = 0; 306 slots = 0; 307 } 308 309 REG_UPDATE_2(DP_DPHY_SYM32_SAT_VC0, 310 SAT_STREAM_SOURCE, src, 311 SAT_SLOT_COUNT, slots); 312 313 if (table->stream_count >= 2) { 314 fill_stream_allocation_row_info( 315 &table->stream_allocations[1], 316 &src, 317 &slots); 318 } else { 319 src = 0; 320 slots = 0; 321 } 322 323 REG_UPDATE_2(DP_DPHY_SYM32_SAT_VC1, 324 SAT_STREAM_SOURCE, src, 325 SAT_SLOT_COUNT, slots); 326 327 if (table->stream_count >= 3) { 328 fill_stream_allocation_row_info( 329 &table->stream_allocations[2], 330 &src, 331 &slots); 332 } else { 333 src = 0; 334 slots = 0; 335 } 336 337 REG_UPDATE_2(DP_DPHY_SYM32_SAT_VC2, 338 SAT_STREAM_SOURCE, src, 339 SAT_SLOT_COUNT, slots); 340 341 if (table->stream_count >= 4) { 342 fill_stream_allocation_row_info( 343 &table->stream_allocations[3], 344 &src, 345 &slots); 346 } else { 347 src = 0; 348 slots = 0; 349 } 350 351 REG_UPDATE_2(DP_DPHY_SYM32_SAT_VC3, 352 SAT_STREAM_SOURCE, src, 353 SAT_SLOT_COUNT, slots); 354 355 /* --- wait for transaction finish */ 356 357 /* send allocation change trigger (ACT) 358 * this step first sends the ACT, 359 * then double buffers the SAT into the hardware 360 * making the new allocation active on the DP MST mode link 361 */ 362 363 /* SAT_UPDATE: 364 * 0 - No Action 365 * 1 - Update SAT with trigger 366 * 2 - Update SAT without trigger 367 */ 368 REG_UPDATE(DP_DPHY_SYM32_SAT_UPDATE, 369 SAT_UPDATE, 1); 370 371 /* wait for update to complete 372 * (i.e. SAT_UPDATE_PENDING field is set to 0) 373 * No need for HW to enforce keepout. 374 */ 375 /* Best case and worst case wait time for SAT_UPDATE_PENDING 376 * best: 109 us 377 * worst: 868 us 378 */ 379 REG_WAIT(DP_DPHY_SYM32_STATUS, 380 SAT_UPDATE_PENDING, 0, 381 10, DP_SAT_UPDATE_MAX_RETRY); 382 } 383 384 void dcn31_hpo_dp_link_enc_set_throttled_vcp_size( 385 struct hpo_dp_link_encoder *enc, 386 uint32_t stream_encoder_inst, 387 struct fixed31_32 avg_time_slots_per_mtp) 388 { 389 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); 390 uint32_t x = dc_fixpt_floor( 391 avg_time_slots_per_mtp); 392 uint32_t y = dc_fixpt_ceil( 393 dc_fixpt_shl( 394 dc_fixpt_sub_int( 395 avg_time_slots_per_mtp, 396 x), 397 25)); 398 399 switch (stream_encoder_inst) { 400 case 0: 401 REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL0, 0, 402 STREAM_VC_RATE_X, x, 403 STREAM_VC_RATE_Y, y); 404 break; 405 case 1: 406 REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL1, 0, 407 STREAM_VC_RATE_X, x, 408 STREAM_VC_RATE_Y, y); 409 break; 410 case 2: 411 REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL2, 0, 412 STREAM_VC_RATE_X, x, 413 STREAM_VC_RATE_Y, y); 414 break; 415 case 3: 416 REG_SET_2(DP_DPHY_SYM32_VC_RATE_CNTL3, 0, 417 STREAM_VC_RATE_X, x, 418 STREAM_VC_RATE_Y, y); 419 break; 420 default: 421 ASSERT(0); 422 } 423 424 /* Best case and worst case wait time for RATE_UPDATE_PENDING 425 * best: 116 ns 426 * worst: 903 ns 427 */ 428 /* wait for update to be completed on the link */ 429 REG_WAIT(DP_DPHY_SYM32_STATUS, 430 RATE_UPDATE_PENDING, 0, 431 1, 10); 432 } 433 434 static bool dcn31_hpo_dp_link_enc_is_in_alt_mode( 435 struct hpo_dp_link_encoder *enc) 436 { 437 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); 438 uint32_t dp_alt_mode_disable = 0; 439 440 ASSERT((enc->transmitter >= TRANSMITTER_UNIPHY_A) && (enc->transmitter <= TRANSMITTER_UNIPHY_E)); 441 442 /* if value == 1 alt mode is disabled, otherwise it is enabled */ 443 REG_GET(RDPCSTX_PHY_CNTL6[enc->transmitter], RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable); 444 return (dp_alt_mode_disable == 0); 445 } 446 447 void dcn31_hpo_dp_link_enc_read_state( 448 struct hpo_dp_link_encoder *enc, 449 struct hpo_dp_link_enc_state *state) 450 { 451 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); 452 453 ASSERT(state); 454 455 REG_GET(DP_DPHY_SYM32_STATUS, 456 STATUS, &state->link_enc_enabled); 457 REG_GET(DP_DPHY_SYM32_CONTROL, 458 NUM_LANES, &state->lane_count); 459 REG_GET(DP_DPHY_SYM32_CONTROL, 460 MODE, (uint32_t *)&state->link_mode); 461 462 REG_GET_2(DP_DPHY_SYM32_SAT_VC0, 463 SAT_STREAM_SOURCE, &state->stream_src[0], 464 SAT_SLOT_COUNT, &state->slot_count[0]); 465 REG_GET_2(DP_DPHY_SYM32_SAT_VC1, 466 SAT_STREAM_SOURCE, &state->stream_src[1], 467 SAT_SLOT_COUNT, &state->slot_count[1]); 468 REG_GET_2(DP_DPHY_SYM32_SAT_VC2, 469 SAT_STREAM_SOURCE, &state->stream_src[2], 470 SAT_SLOT_COUNT, &state->slot_count[2]); 471 REG_GET_2(DP_DPHY_SYM32_SAT_VC3, 472 SAT_STREAM_SOURCE, &state->stream_src[3], 473 SAT_SLOT_COUNT, &state->slot_count[3]); 474 475 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL0, 476 STREAM_VC_RATE_X, &state->vc_rate_x[0], 477 STREAM_VC_RATE_Y, &state->vc_rate_y[0]); 478 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL1, 479 STREAM_VC_RATE_X, &state->vc_rate_x[1], 480 STREAM_VC_RATE_Y, &state->vc_rate_y[1]); 481 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL2, 482 STREAM_VC_RATE_X, &state->vc_rate_x[2], 483 STREAM_VC_RATE_Y, &state->vc_rate_y[2]); 484 REG_GET_2(DP_DPHY_SYM32_VC_RATE_CNTL3, 485 STREAM_VC_RATE_X, &state->vc_rate_x[3], 486 STREAM_VC_RATE_Y, &state->vc_rate_y[3]); 487 } 488 489 static enum bp_result link_transmitter_control( 490 struct dcn31_hpo_dp_link_encoder *enc3, 491 struct bp_transmitter_control *cntl) 492 { 493 enum bp_result result; 494 struct dc_bios *bp = enc3->base.ctx->dc_bios; 495 496 result = bp->funcs->transmitter_control(bp, cntl); 497 498 return result; 499 } 500 501 /* enables DP PHY output for 128b132b encoding */ 502 void dcn31_hpo_dp_link_enc_enable_dp_output( 503 struct hpo_dp_link_encoder *enc, 504 const struct dc_link_settings *link_settings, 505 enum transmitter transmitter, 506 enum hpd_source_id hpd_source) 507 { 508 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); 509 struct bp_transmitter_control cntl = { 0 }; 510 enum bp_result result; 511 512 /* Set the transmitter */ 513 enc3->base.transmitter = transmitter; 514 515 /* Set the hpd source */ 516 enc3->base.hpd_source = hpd_source; 517 518 /* Enable the PHY */ 519 cntl.action = TRANSMITTER_CONTROL_ENABLE; 520 cntl.engine_id = ENGINE_ID_UNKNOWN; 521 cntl.transmitter = enc3->base.transmitter; 522 //cntl.pll_id = clock_source; 523 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST; 524 cntl.lanes_number = link_settings->lane_count; 525 cntl.hpd_sel = enc3->base.hpd_source; 526 cntl.pixel_clock = link_settings->link_rate * 1000; 527 cntl.color_depth = COLOR_DEPTH_UNDEFINED; 528 cntl.hpo_engine_id = enc->inst + ENGINE_ID_HPO_DP_0; 529 530 result = link_transmitter_control(enc3, &cntl); 531 532 if (result != BP_RESULT_OK) { 533 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 534 __func__); 535 BREAK_TO_DEBUGGER(); 536 } 537 } 538 539 void dcn31_hpo_dp_link_enc_disable_output( 540 struct hpo_dp_link_encoder *enc, 541 enum signal_type signal) 542 { 543 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); 544 struct bp_transmitter_control cntl = { 0 }; 545 enum bp_result result; 546 547 /* disable transmitter */ 548 cntl.action = TRANSMITTER_CONTROL_DISABLE; 549 cntl.transmitter = enc3->base.transmitter; 550 cntl.hpd_sel = enc3->base.hpd_source; 551 cntl.signal = signal; 552 553 result = link_transmitter_control(enc3, &cntl); 554 555 if (result != BP_RESULT_OK) { 556 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 557 __func__); 558 BREAK_TO_DEBUGGER(); 559 return; 560 } 561 562 /* disable encoder */ 563 dcn31_hpo_dp_link_enc_disable(enc); 564 } 565 566 void dcn31_hpo_dp_link_enc_set_ffe( 567 struct hpo_dp_link_encoder *enc, 568 const struct dc_link_settings *link_settings, 569 uint8_t ffe_preset) 570 { 571 struct dcn31_hpo_dp_link_encoder *enc3 = DCN3_1_HPO_DP_LINK_ENC_FROM_HPO_LINK_ENC(enc); 572 struct bp_transmitter_control cntl = { 0 }; 573 enum bp_result result; 574 575 /* disable transmitter */ 576 cntl.transmitter = enc3->base.transmitter; 577 cntl.action = TRANSMITTER_CONTROL_SET_VOLTAGE_AND_PREEMPASIS; 578 cntl.signal = SIGNAL_TYPE_DISPLAY_PORT_MST; 579 cntl.lanes_number = link_settings->lane_count; 580 cntl.pixel_clock = link_settings->link_rate * 1000; 581 cntl.lane_settings = ffe_preset; 582 583 result = link_transmitter_control(enc3, &cntl); 584 585 if (result != BP_RESULT_OK) { 586 DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", 587 __func__); 588 BREAK_TO_DEBUGGER(); 589 return; 590 } 591 } 592 593 static struct hpo_dp_link_encoder_funcs dcn31_hpo_dp_link_encoder_funcs = { 594 .enable_link_phy = dcn31_hpo_dp_link_enc_enable_dp_output, 595 .disable_link_phy = dcn31_hpo_dp_link_enc_disable_output, 596 .link_enable = dcn31_hpo_dp_link_enc_enable, 597 .link_disable = dcn31_hpo_dp_link_enc_disable, 598 .set_link_test_pattern = dcn31_hpo_dp_link_enc_set_link_test_pattern, 599 .update_stream_allocation_table = dcn31_hpo_dp_link_enc_update_stream_allocation_table, 600 .set_throttled_vcp_size = dcn31_hpo_dp_link_enc_set_throttled_vcp_size, 601 .is_in_alt_mode = dcn31_hpo_dp_link_enc_is_in_alt_mode, 602 .read_state = dcn31_hpo_dp_link_enc_read_state, 603 .set_ffe = dcn31_hpo_dp_link_enc_set_ffe, 604 }; 605 606 void hpo_dp_link_encoder31_construct(struct dcn31_hpo_dp_link_encoder *enc31, 607 struct dc_context *ctx, 608 uint32_t inst, 609 const struct dcn31_hpo_dp_link_encoder_registers *hpo_le_regs, 610 const struct dcn31_hpo_dp_link_encoder_shift *hpo_le_shift, 611 const struct dcn31_hpo_dp_link_encoder_mask *hpo_le_mask) 612 { 613 enc31->base.ctx = ctx; 614 615 enc31->base.inst = inst; 616 enc31->base.funcs = &dcn31_hpo_dp_link_encoder_funcs; 617 enc31->base.hpd_source = HPD_SOURCEID_UNKNOWN; 618 enc31->base.transmitter = TRANSMITTER_UNKNOWN; 619 620 enc31->regs = hpo_le_regs; 621 enc31->hpo_le_shift = hpo_le_shift; 622 enc31->hpo_le_mask = hpo_le_mask; 623 } 624