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