FILE
link_edp_panel_control.c
File preview with syntax highlighting.
linux-6.19.14/drivers/gpu/drm/amd/display/dc/link/protocols/link_edp_panel_control.c
1/* 2 * Copyright 2022 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/* FILE POLICY AND INTENDED USAGE: 27 * This file implements retrieval and configuration of eDP panel features such 28 * as PSR and ABM and it also manages specs defined eDP panel power sequences. 29 */ 30 31#include "link_edp_panel_control.h" 32#include "link_dpcd.h" 33#include "link_dp_capability.h" 34#include "dm_helpers.h" 35#include "dal_asic_id.h" 36#include "link_dp_phy.h" 37#include "dce/dmub_psr.h" 38#include "dc/dc_dmub_srv.h" 39#include "dce/dmub_replay.h" 40#include "abm.h" 41#include "resource.h" 42#define DC_LOGGER \ 43 link->ctx->logger 44#define DC_LOGGER_INIT(logger) 45 46#define DP_SINK_PR_ENABLE_AND_CONFIGURATION 0x37B 47 48/* Travis */ 49static const uint8_t DP_VGA_LVDS_CONVERTER_ID_2[] = "sivarT"; 50/* Nutmeg */ 51static const uint8_t DP_VGA_LVDS_CONVERTER_ID_3[] = "dnomlA"; 52 53void dp_set_panel_mode(struct dc_link *link, enum dp_panel_mode panel_mode) 54{ 55 union dpcd_edp_config edp_config_set; 56 bool panel_mode_edp = false; 57 enum dc_status result; 58 59 memset(&edp_config_set, '\0', sizeof(union dpcd_edp_config)); 60 61 switch (panel_mode) { 62 case DP_PANEL_MODE_EDP: 63 case DP_PANEL_MODE_SPECIAL: 64 panel_mode_edp = true; 65 break; 66 67 default: 68 break; 69 } 70 71 /*set edp panel mode in receiver*/ 72 result = core_link_read_dpcd( 73 link, 74 DP_EDP_CONFIGURATION_SET, 75 &edp_config_set.raw, 76 sizeof(edp_config_set.raw)); 77 78 if (result == DC_OK && 79 edp_config_set.bits.PANEL_MODE_EDP 80 != panel_mode_edp) { 81 82 edp_config_set.bits.PANEL_MODE_EDP = 83 panel_mode_edp; 84 result = core_link_write_dpcd( 85 link, 86 DP_EDP_CONFIGURATION_SET, 87 &edp_config_set.raw, 88 sizeof(edp_config_set.raw)); 89 90 ASSERT(result == DC_OK); 91 } 92 93 link->panel_mode = panel_mode; 94 DC_LOG_DETECTION_DP_CAPS("Link: %d eDP panel mode supported: %d " 95 "eDP panel mode enabled: %d \n", 96 link->link_index, 97 link->dpcd_caps.panel_mode_edp, 98 panel_mode_edp); 99} 100 101enum dp_panel_mode dp_get_panel_mode(struct dc_link *link) 102{ 103 /* We need to explicitly check that connector 104 * is not DP. Some Travis_VGA get reported 105 * by video bios as DP. 106 */ 107 if (link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT) { 108 109 switch (link->dpcd_caps.branch_dev_id) { 110 case DP_BRANCH_DEVICE_ID_0022B9: 111 /* alternate scrambler reset is required for Travis 112 * for the case when external chip does not 113 * provide sink device id, alternate scrambler 114 * scheme will be overriden later by querying 115 * Encoder features 116 */ 117 if (strncmp( 118 link->dpcd_caps.branch_dev_name, 119 DP_VGA_LVDS_CONVERTER_ID_2, 120 sizeof( 121 link->dpcd_caps. 122 branch_dev_name)) == 0) { 123 return DP_PANEL_MODE_SPECIAL; 124 } 125 break; 126 case DP_BRANCH_DEVICE_ID_00001A: 127 /* alternate scrambler reset is required for Travis 128 * for the case when external chip does not provide 129 * sink device id, alternate scrambler scheme will 130 * be overriden later by querying Encoder feature 131 */ 132 if (strncmp(link->dpcd_caps.branch_dev_name, 133 DP_VGA_LVDS_CONVERTER_ID_3, 134 sizeof( 135 link->dpcd_caps. 136 branch_dev_name)) == 0) { 137 return DP_PANEL_MODE_SPECIAL; 138 } 139 break; 140 default: 141 break; 142 } 143 } 144 145 if (link->dpcd_caps.panel_mode_edp && 146 (link->connector_signal == SIGNAL_TYPE_EDP || 147 (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT && 148 link->is_internal_display))) { 149 return DP_PANEL_MODE_EDP; 150 } 151 152 return DP_PANEL_MODE_DEFAULT; 153} 154 155bool edp_set_backlight_level_nits(struct dc_link *link, 156 bool isHDR, 157 uint32_t backlight_millinits, 158 uint32_t transition_time_in_ms) 159{ 160 if (!link || (link->connector_signal != SIGNAL_TYPE_EDP && 161 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)) 162 return false; 163 164 if (link->is_dds && !link->dpcd_caps.panel_luminance_control) 165 return true; 166 167 // use internal backlight control if dmub capabilities are not present 168 if (link->backlight_control_type == BACKLIGHT_CONTROL_VESA_AUX && 169 !link->dc->caps.dmub_caps.aux_backlight_support) { 170 uint8_t backlight_enable = 0; 171 struct target_luminance_value *target_luminance = NULL; 172 173 //if target luminance value is greater than 24 bits, clip the value to 24 bits 174 if (backlight_millinits > 0xFFFFFF) 175 backlight_millinits = 0xFFFFFF; 176 177 target_luminance = (struct target_luminance_value *)&backlight_millinits; 178 179 //make sure we disable AMD ABC first. 180 core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL, 181 &backlight_enable, sizeof(uint8_t)); 182 if (backlight_enable) { 183 backlight_enable = 0; 184 core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL, 185 &backlight_enable, 1); 186 } 187 188 core_link_read_dpcd(link, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, 189 &backlight_enable, sizeof(uint8_t)); 190 191 backlight_enable |= DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE; 192 193 if (core_link_write_dpcd(link, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, 194 &backlight_enable, 195 sizeof(backlight_enable)) != DC_OK) 196 return false; 197 198 if (core_link_write_dpcd(link, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, 199 (uint8_t *)(target_luminance), 200 sizeof(struct target_luminance_value)) != DC_OK) 201 return false; 202 } else if (link->backlight_control_type == BACKLIGHT_CONTROL_AMD_AUX) { 203 struct dpcd_source_backlight_set dpcd_backlight_set; 204 *(uint32_t *)&dpcd_backlight_set.backlight_level_millinits = backlight_millinits; 205 *(uint16_t *)&dpcd_backlight_set.backlight_transition_time_ms = (uint16_t)transition_time_in_ms; 206 207 uint8_t backlight_control = isHDR ? 1 : 0; 208 uint8_t backlight_enable = 0; 209 210 // OLEDs have no PWM, they can only use AUX 211 if (link->dpcd_sink_ext_caps.bits.oled == 1) 212 backlight_control = 1; 213 214 //make sure we disable VESA ABC first. 215 core_link_read_dpcd(link, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, 216 &backlight_enable, sizeof(uint8_t)); 217 218 if (backlight_enable & DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE) { 219 backlight_enable &= ~DP_EDP_PANEL_LUMINANCE_CONTROL_ENABLE; 220 core_link_write_dpcd(link, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, 221 &backlight_enable, sizeof(backlight_enable)); 222 } 223 224 if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL, 225 (uint8_t *)(&dpcd_backlight_set), 226 sizeof(dpcd_backlight_set)) != DC_OK) 227 return false; 228 229 if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_CONTROL, 230 &backlight_control, 1) != DC_OK) 231 return false; 232 } 233 234 return true; 235} 236 237bool edp_get_backlight_level_nits(struct dc_link *link, 238 uint32_t *backlight_millinits_avg, 239 uint32_t *backlight_millinits_peak) 240{ 241 union dpcd_source_backlight_get dpcd_backlight_get; 242 243 memset(&dpcd_backlight_get, 0, sizeof(union dpcd_source_backlight_get)); 244 245 if (!link || (link->connector_signal != SIGNAL_TYPE_EDP && 246 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)) 247 return false; 248 249 if (link->is_dds) 250 return false; 251 if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CURRENT_PEAK, 252 dpcd_backlight_get.raw, 253 sizeof(union dpcd_source_backlight_get))) 254 return false; 255 256 *backlight_millinits_avg = 257 dpcd_backlight_get.bytes.backlight_millinits_avg; 258 *backlight_millinits_peak = 259 dpcd_backlight_get.bytes.backlight_millinits_peak; 260 261 /* On non-supported panels dpcd_read usually succeeds with 0 returned */ 262 if (*backlight_millinits_avg == 0 || 263 *backlight_millinits_avg > *backlight_millinits_peak) 264 return false; 265 266 return true; 267} 268 269bool edp_backlight_enable_aux(struct dc_link *link, bool enable) 270{ 271 uint8_t backlight_enable = enable ? 1 : 0; 272 273 if (!link || (link->connector_signal != SIGNAL_TYPE_EDP && 274 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)) 275 return false; 276 277 if (link->is_dds) 278 return true; 279 if (core_link_write_dpcd(link, DP_SOURCE_BACKLIGHT_ENABLE, 280 &backlight_enable, 1) != DC_OK) 281 return false; 282 283 return true; 284} 285 286// we read default from 0x320 because we expect BIOS wrote it there 287// regular get_backlight_nit reads from panel set at 0x326 288static bool read_default_bl_aux(struct dc_link *link, uint32_t *backlight_millinits) 289{ 290 if (!link || (link->connector_signal != SIGNAL_TYPE_EDP && 291 link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT)) 292 return false; 293 294 if (!link->dpcd_caps.panel_luminance_control) { 295 if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL, 296 (uint8_t *)backlight_millinits, 297 sizeof(uint32_t))) 298 return false; 299 } else { 300 //setting to 0 as a precaution, since target_luminance_value is 3 bytes 301 memset(backlight_millinits, 0, sizeof(uint32_t)); 302 303 if (!core_link_read_dpcd(link, DP_EDP_PANEL_TARGET_LUMINANCE_VALUE, 304 (uint8_t *)backlight_millinits, 305 sizeof(struct target_luminance_value))) 306 return false; 307 } 308 309 return true; 310} 311 312bool set_default_brightness_aux(struct dc_link *link) 313{ 314 uint32_t default_backlight; 315 316 if (link && link->dpcd_sink_ext_caps.bits.oled == 1) { 317 if (!read_default_bl_aux(link, &default_backlight)) 318 default_backlight = 150000; 319 // if > 5000, it might be wrong readback. 0 nits is a valid default value for OLED panel. 320 if (default_backlight < 1000 || default_backlight > 5000000) 321 default_backlight = 150000; 322 323 return edp_set_backlight_level_nits(link, true, 324 default_backlight, 0); 325 } 326 return false; 327} 328 329bool edp_is_ilr_optimization_enabled(struct dc_link *link) 330{ 331 if (link->dpcd_caps.edp_supported_link_rates_count == 0 || !link->panel_config.ilr.optimize_edp_link_rate) 332 return false; 333 return true; 334} 335 336enum dc_link_rate get_max_edp_link_rate(struct dc_link *link) 337{ 338 enum dc_link_rate max_ilr_rate = LINK_RATE_UNKNOWN; 339 enum dc_link_rate max_non_ilr_rate = dp_get_max_link_cap(link).link_rate; 340 341 for (int i = 0; i < link->dpcd_caps.edp_supported_link_rates_count; i++) { 342 if (max_ilr_rate < link->dpcd_caps.edp_supported_link_rates[i]) 343 max_ilr_rate = link->dpcd_caps.edp_supported_link_rates[i]; 344 } 345 346 return (max_ilr_rate > max_non_ilr_rate ? max_ilr_rate : max_non_ilr_rate); 347} 348 349bool edp_is_ilr_optimization_required(struct dc_link *link, 350 struct dc_crtc_timing *crtc_timing) 351{ 352 struct dc_link_settings link_setting; 353 uint8_t link_bw_set = 0; 354 uint8_t link_rate_set = 0; 355 uint32_t req_bw; 356 union lane_count_set lane_count_set = {0}; 357 358 ASSERT(link || crtc_timing); // invalid input 359 360 if (!edp_is_ilr_optimization_enabled(link)) 361 return false; 362 363 364 // Read DPCD 00100h to find if standard link rates are set 365 core_link_read_dpcd(link, DP_LINK_BW_SET, 366 &link_bw_set, sizeof(link_bw_set)); 367 368 if (link_bw_set) { 369 DC_LOG_EVENT_LINK_TRAINING("eDP ILR: Optimization required, VBIOS used link_bw_set\n"); 370 return true; 371 } 372 373 // Read DPCD 00115h to find the edp link rate set used 374 core_link_read_dpcd(link, DP_LINK_RATE_SET, 375 &link_rate_set, sizeof(link_rate_set)); 376 377 // Read DPCD 00101h to find out the number of lanes currently set 378 core_link_read_dpcd(link, DP_LANE_COUNT_SET, 379 &lane_count_set.raw, sizeof(lane_count_set)); 380 381 req_bw = dc_bandwidth_in_kbps_from_timing(crtc_timing, dc_link_get_highest_encoding_format(link)); 382 383 if (!crtc_timing->flags.DSC) 384 edp_decide_link_settings(link, &link_setting, req_bw); 385 else 386 decide_edp_link_settings_with_dsc(link, &link_setting, req_bw, LINK_RATE_UNKNOWN); 387 388 if (link->dpcd_caps.edp_supported_link_rates[link_rate_set] != link_setting.link_rate || 389 lane_count_set.bits.LANE_COUNT_SET != link_setting.lane_count) { 390 DC_LOG_EVENT_LINK_TRAINING("eDP ILR: Optimization required, VBIOS link_rate_set not optimal\n"); 391 return true; 392 } 393 394 DC_LOG_EVENT_LINK_TRAINING("eDP ILR: No optimization required, VBIOS set optimal link_rate_set\n"); 395 return false; 396} 397 398void edp_panel_backlight_power_on(struct dc_link *link, bool wait_for_hpd) 399{ 400 if (link->connector_signal != SIGNAL_TYPE_EDP) 401 return; 402 403 link->dc->hwss.edp_power_control(link, true); 404 if (wait_for_hpd) 405 link->dc->hwss.edp_wait_for_hpd_ready(link, true); 406 if (link->dc->hwss.edp_backlight_control) 407 link->dc->hwss.edp_backlight_control(link, true); 408} 409 410void edp_set_panel_power(struct dc_link *link, bool powerOn) 411{ 412 if (powerOn) { 413 // 1. panel VDD on 414 if (!link->dc->config.edp_no_power_sequencing) 415 link->dc->hwss.edp_power_control(link, true); 416 link->dc->hwss.edp_wait_for_hpd_ready(link, true); 417 418 // 2. panel BL on 419 if (link->dc->hwss.edp_backlight_control) 420 link->dc->hwss.edp_backlight_control(link, true); 421 422 // 3. Rx power on 423 dpcd_write_rx_power_ctrl(link, true); 424 } else { 425 // 3. Rx power off 426 dpcd_write_rx_power_ctrl(link, false); 427 428 // 2. panel BL off 429 if (link->dc->hwss.edp_backlight_control) 430 link->dc->hwss.edp_backlight_control(link, false); 431 432 // 1. panel VDD off 433 if (!link->dc->config.edp_no_power_sequencing) 434 link->dc->hwss.edp_power_control(link, false); 435 } 436} 437 438bool edp_wait_for_t12(struct dc_link *link) 439{ 440 if (link->connector_signal == SIGNAL_TYPE_EDP && link->dc->hwss.edp_wait_for_T12) { 441 link->dc->hwss.edp_wait_for_T12(link); 442 443 return true; 444 } 445 446 return false; 447} 448 449void edp_add_delay_for_T9(struct dc_link *link) 450{ 451 if (link && link->panel_config.pps.extra_delay_backlight_off > 0) 452 fsleep(link->panel_config.pps.extra_delay_backlight_off * 1000); 453} 454 455bool edp_receiver_ready_T9(struct dc_link *link) 456{ 457 unsigned int tries = 0; 458 unsigned char sinkstatus = 0; 459 unsigned char edpRev = 0; 460 enum dc_status result = DC_OK; 461 462 result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev)); 463 464 /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/ 465 if (result == DC_OK && edpRev >= DP_EDP_12) { 466 do { 467 sinkstatus = 1; 468 result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus)); 469 if (sinkstatus == 0) 470 break; 471 if (result != DC_OK) 472 break; 473 udelay(100); //MAx T9 474 } while (++tries < 50); 475 } 476 477 return result; 478} 479 480bool edp_receiver_ready_T7(struct dc_link *link) 481{ 482 unsigned char sinkstatus = 0; 483 unsigned char edpRev = 0; 484 enum dc_status result = DC_OK; 485 486 /* use absolute time stamp to constrain max T7*/ 487 unsigned long long enter_timestamp = 0; 488 unsigned long long finish_timestamp = 0; 489 unsigned long long time_taken_in_ns = 0; 490 491 result = core_link_read_dpcd(link, DP_EDP_DPCD_REV, &edpRev, sizeof(edpRev)); 492 493 if (result == DC_OK && edpRev >= DP_EDP_12) { 494 /* start from eDP version 1.2, SINK_STAUS indicate the sink is ready.*/ 495 enter_timestamp = dm_get_timestamp(link->ctx); 496 do { 497 sinkstatus = 0; 498 result = core_link_read_dpcd(link, DP_SINK_STATUS, &sinkstatus, sizeof(sinkstatus)); 499 if (sinkstatus == 1) 500 break; 501 if (result != DC_OK) 502 break; 503 udelay(25); 504 finish_timestamp = dm_get_timestamp(link->ctx); 505 time_taken_in_ns = dm_get_elapse_time_in_ns(link->ctx, finish_timestamp, enter_timestamp); 506 } while (time_taken_in_ns < 50 * 1000000); //MAx T7 is 50ms 507 } 508 509 if (link && link->panel_config.pps.extra_t7_ms > 0) 510 fsleep(link->panel_config.pps.extra_t7_ms * 1000); 511 512 return result; 513} 514 515bool edp_power_alpm_dpcd_enable(struct dc_link *link, bool enable) 516{ 517 bool ret = false; 518 union dpcd_alpm_configuration alpm_config; 519 520 if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) { 521 memset(&alpm_config, 0, sizeof(alpm_config)); 522 523 alpm_config.bits.ENABLE = (enable ? true : false); 524 ret = dm_helpers_dp_write_dpcd(link->ctx, link, 525 DP_RECEIVER_ALPM_CONFIG, &alpm_config.raw, 526 sizeof(alpm_config.raw)); 527 } 528 return ret; 529} 530 531static struct pipe_ctx *get_pipe_from_link(const struct dc_link *link) 532{ 533 int i; 534 struct dc *dc = link->ctx->dc; 535 struct pipe_ctx *pipe_ctx = NULL; 536 537 for (i = 0; i < MAX_PIPES; i++) { 538 if (dc->current_state->res_ctx.pipe_ctx[i].stream) { 539 if (dc->current_state->res_ctx.pipe_ctx[i].stream->link == link) { 540 pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; 541 break; 542 } 543 } 544 } 545 546 return pipe_ctx; 547} 548 549bool edp_set_backlight_level(const struct dc_link *link, 550 struct set_backlight_level_params *backlight_level_params) 551{ 552 struct dc *dc = link->ctx->dc; 553 uint32_t backlight_pwm_u16_16 = backlight_level_params->backlight_pwm_u16_16; 554 uint32_t frame_ramp = backlight_level_params->frame_ramp; 555 556 DC_LOG_BACKLIGHT("New Backlight level: %d (0x%X)\n", 557 backlight_pwm_u16_16, backlight_pwm_u16_16); 558 559 if (dc_is_embedded_signal(link->connector_signal)) { 560 struct pipe_ctx *pipe_ctx = get_pipe_from_link(link); 561 562 if (link->panel_cntl) 563 link->panel_cntl->stored_backlight_registers.USER_LEVEL = backlight_pwm_u16_16; 564 565 if (pipe_ctx) { 566 /* Disable brightness ramping when the display is blanked 567 * as it can hang the DMCU 568 */ 569 if (pipe_ctx->plane_state == NULL) 570 frame_ramp = 0; 571 } else { 572 return false; 573 } 574 575 backlight_level_params->frame_ramp = frame_ramp; 576 577 dc->hwss.set_backlight_level( 578 pipe_ctx, 579 backlight_level_params); 580 } 581 return true; 582} 583 584bool edp_set_psr_allow_active(struct dc_link *link, const bool *allow_active, 585 bool wait, bool force_static, const unsigned int *power_opts) 586{ 587 struct dc *dc = link->ctx->dc; 588 struct dmcu *dmcu = dc->res_pool->dmcu; 589 struct dmub_psr *psr = dc->res_pool->psr; 590 unsigned int panel_inst; 591 592 if (psr == NULL && force_static) 593 return false; 594 595 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 596 return false; 597 598 if ((allow_active != NULL) && (*allow_active == true) && (link->type == dc_connection_none)) { 599 // Don't enter PSR if panel is not connected 600 return false; 601 } 602 603 /* Set power optimization flag */ 604 if (power_opts && link->psr_settings.psr_power_opt != *power_opts) { 605 link->psr_settings.psr_power_opt = *power_opts; 606 607 if (psr != NULL && link->psr_settings.psr_feature_enabled && psr->funcs->psr_set_power_opt) 608 psr->funcs->psr_set_power_opt(psr, link->psr_settings.psr_power_opt, panel_inst); 609 } 610 611 if (psr != NULL && link->psr_settings.psr_feature_enabled && 612 force_static && psr->funcs->psr_force_static) 613 psr->funcs->psr_force_static(psr, panel_inst); 614 615 /* Enable or Disable PSR */ 616 if (allow_active && link->psr_settings.psr_allow_active != *allow_active) { 617 link->psr_settings.psr_allow_active = *allow_active; 618 619 if (!link->psr_settings.psr_allow_active) 620 dc_z10_restore(dc); 621 622 if (psr != NULL && link->psr_settings.psr_feature_enabled) { 623 psr->funcs->psr_enable(psr, link->psr_settings.psr_allow_active, wait, panel_inst); 624 } else if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu)) && 625 link->psr_settings.psr_feature_enabled) 626 dmcu->funcs->set_psr_enable(dmcu, link->psr_settings.psr_allow_active, wait); 627 else 628 return false; 629 } 630 return true; 631} 632 633bool edp_get_psr_state(const struct dc_link *link, enum dc_psr_state *state) 634{ 635 struct dc *dc = link->ctx->dc; 636 struct dmcu *dmcu = dc->res_pool->dmcu; 637 struct dmub_psr *psr = dc->res_pool->psr; 638 unsigned int panel_inst; 639 640 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 641 return false; 642 643 if (psr != NULL && link->psr_settings.psr_feature_enabled) 644 psr->funcs->psr_get_state(psr, state, panel_inst); 645 else if (dmcu != NULL && link->psr_settings.psr_feature_enabled) 646 dmcu->funcs->get_psr_state(dmcu, state); 647 648 return true; 649} 650 651static inline enum physical_phy_id 652transmitter_to_phy_id(struct dc_link *link) 653{ 654 struct dc_context *dc_ctx = link->ctx; 655 enum transmitter transmitter_value = link->link_enc->transmitter; 656 657 switch (transmitter_value) { 658 case TRANSMITTER_UNIPHY_A: 659 return PHYLD_0; 660 case TRANSMITTER_UNIPHY_B: 661 return PHYLD_1; 662 case TRANSMITTER_UNIPHY_C: 663 return PHYLD_2; 664 case TRANSMITTER_UNIPHY_D: 665 return PHYLD_3; 666 case TRANSMITTER_UNIPHY_E: 667 return PHYLD_4; 668 case TRANSMITTER_UNIPHY_F: 669 return PHYLD_5; 670 case TRANSMITTER_NUTMEG_CRT: 671 return PHYLD_6; 672 case TRANSMITTER_TRAVIS_CRT: 673 return PHYLD_7; 674 case TRANSMITTER_TRAVIS_LCD: 675 return PHYLD_8; 676 case TRANSMITTER_UNIPHY_G: 677 return PHYLD_9; 678 case TRANSMITTER_COUNT: 679 return PHYLD_COUNT; 680 case TRANSMITTER_UNKNOWN: 681 return PHYLD_UNKNOWN; 682 default: 683 DC_ERROR("Unknown transmitter value %d\n", transmitter_value); 684 return PHYLD_UNKNOWN; 685 } 686} 687 688bool edp_setup_psr(struct dc_link *link, 689 const struct dc_stream_state *stream, struct psr_config *psr_config, 690 struct psr_context *psr_context) 691{ 692 struct dc *dc; 693 struct dmcu *dmcu; 694 struct dmub_psr *psr; 695 int i; 696 unsigned int panel_inst; 697 /* updateSinkPsrDpcdConfig*/ 698 union dpcd_psr_configuration psr_configuration; 699 union dpcd_sink_active_vtotal_control_mode vtotal_control = {0}; 700 701 psr_context->controllerId = CONTROLLER_ID_UNDEFINED; 702 703 if (!link) 704 return false; 705 706 /* This is a workaround: some vendors require the source to 707 * read the PSR cap; otherwise, the vendor's PSR feature will 708 * fall back to its default behavior, causing a misconfiguration 709 * of this feature. 710 */ 711 if (link->panel_config.psr.read_psrcap_again) { 712 dm_helpers_dp_read_dpcd( 713 link->ctx, 714 link, 715 DP_PSR_SUPPORT, 716 &link->dpcd_caps.psr_info.psr_version, 717 sizeof(link->dpcd_caps.psr_info.psr_version)); 718 } 719 720 //Clear PSR cfg 721 memset(&psr_configuration, 0, sizeof(psr_configuration)); 722 dm_helpers_dp_write_dpcd( 723 link->ctx, 724 link, 725 DP_PSR_EN_CFG, 726 &psr_configuration.raw, 727 sizeof(psr_configuration.raw)); 728 729 if (link->psr_settings.psr_version == DC_PSR_VERSION_UNSUPPORTED) 730 return false; 731 732 dc = link->ctx->dc; 733 dmcu = dc->res_pool->dmcu; 734 psr = dc->res_pool->psr; 735 736 if (!dmcu && !psr) 737 return false; 738 739 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 740 return false; 741 742 psr_configuration.bits.ENABLE = 1; 743 psr_configuration.bits.CRC_VERIFICATION = 1; 744 psr_configuration.bits.FRAME_CAPTURE_INDICATION = 745 psr_config->psr_frame_capture_indication_req; 746 747 /* Check for PSR v2*/ 748 if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) { 749 /* For PSR v2 selective update. 750 * Indicates whether sink should start capturing 751 * immediately following active scan line, 752 * or starting with the 2nd active scan line. 753 */ 754 psr_configuration.bits.LINE_CAPTURE_INDICATION = 0; 755 /*For PSR v2, determines whether Sink should generate 756 * IRQ_HPD when CRC mismatch is detected. 757 */ 758 psr_configuration.bits.IRQ_HPD_WITH_CRC_ERROR = 1; 759 /* For PSR v2, set the bit when the Source device will 760 * be enabling PSR2 operation. 761 */ 762 psr_configuration.bits.ENABLE_PSR2 = 1; 763 /* For PSR v2, the Sink device must be able to receive 764 * SU region updates early in the frame time. 765 */ 766 psr_configuration.bits.EARLY_TRANSPORT_ENABLE = 1; 767 } 768 769 dm_helpers_dp_write_dpcd( 770 link->ctx, 771 link, 772 368, 773 &psr_configuration.raw, 774 sizeof(psr_configuration.raw)); 775 776 if (link->psr_settings.psr_version == DC_PSR_VERSION_SU_1) { 777 edp_power_alpm_dpcd_enable(link, true); 778 psr_context->su_granularity_required = 779 psr_config->su_granularity_required; 780 psr_context->su_y_granularity = 781 psr_config->su_y_granularity; 782 psr_context->line_time_in_us = psr_config->line_time_in_us; 783 784 /* linux must be able to expose AMD Source DPCD definition 785 * in order to support FreeSync PSR 786 */ 787 if (link->psr_settings.psr_vtotal_control_support) { 788 psr_context->rate_control_caps = psr_config->rate_control_caps; 789 vtotal_control.bits.ENABLE = true; 790 core_link_write_dpcd(link, DP_SINK_PSR_ACTIVE_VTOTAL_CONTROL_MODE, 791 &vtotal_control.raw, sizeof(vtotal_control.raw)); 792 } 793 } 794 795 psr_context->channel = link->ddc->ddc_pin->hw_info.ddc_channel; 796 psr_context->transmitterId = link->link_enc->transmitter; 797 psr_context->engineId = link->link_enc->preferred_engine; 798 799 for (i = 0; i < MAX_PIPES; i++) { 800 if (dc->current_state->res_ctx.pipe_ctx[i].stream 801 == stream) { 802 /* dmcu -1 for all controller id values, 803 * therefore +1 here 804 */ 805 psr_context->controllerId = 806 dc->current_state->res_ctx. 807 pipe_ctx[i].stream_res.tg->inst + 1; 808 break; 809 } 810 } 811 812 /* Hardcoded for now. Can be Pcie or Uniphy (or Unknown)*/ 813 psr_context->phyType = PHY_TYPE_UNIPHY; 814 /*PhyId is associated with the transmitter id*/ 815 psr_context->smuPhyId = transmitter_to_phy_id(link); 816 817 psr_context->crtcTimingVerticalTotal = stream->timing.v_total; 818 psr_context->vsync_rate_hz = div64_u64(div64_u64((stream-> 819 timing.pix_clk_100hz * (u64)100), 820 stream->timing.v_total), 821 stream->timing.h_total); 822 823 psr_context->psrSupportedDisplayConfig = true; 824 psr_context->psrExitLinkTrainingRequired = 825 psr_config->psr_exit_link_training_required; 826 psr_context->sdpTransmitLineNumDeadline = 827 psr_config->psr_sdp_transmit_line_num_deadline; 828 psr_context->psrFrameCaptureIndicationReq = 829 psr_config->psr_frame_capture_indication_req; 830 831 psr_context->skipPsrWaitForPllLock = 0; /* only = 1 in KV */ 832 833 psr_context->numberOfControllers = 834 link->dc->res_pool->timing_generator_count; 835 836 psr_context->rfb_update_auto_en = true; 837 838 /* 2 frames before enter PSR. */ 839 psr_context->timehyst_frames = 2; 840 /* half a frame 841 * (units in 100 lines, i.e. a value of 1 represents 100 lines) 842 */ 843 psr_context->hyst_lines = stream->timing.v_total / 2 / 100; 844 psr_context->aux_repeats = 10; 845 846 psr_context->psr_level.u32all = 0; 847 848 /*skip power down the single pipe since it blocks the cstate*/ 849 if (link->ctx->asic_id.chip_family >= FAMILY_RV) { 850 switch (link->ctx->asic_id.chip_family) { 851 case FAMILY_YELLOW_CARP: 852 case AMDGPU_FAMILY_GC_10_3_6: 853 case AMDGPU_FAMILY_GC_11_0_1: 854 if (dc->debug.disable_z10 || dc->debug.psr_skip_crtc_disable) 855 psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true; 856 break; 857 default: 858 psr_context->psr_level.bits.SKIP_CRTC_DISABLE = true; 859 break; 860 } 861 } 862 863 /* SMU will perform additional powerdown sequence. 864 * For unsupported ASICs, set psr_level flag to skip PSR 865 * static screen notification to SMU. 866 * (Always set for DAL2, did not check ASIC) 867 */ 868 psr_context->allow_smu_optimizations = psr_config->allow_smu_optimizations; 869 psr_context->allow_multi_disp_optimizations = psr_config->allow_multi_disp_optimizations; 870 871 /* Complete PSR entry before aborting to prevent intermittent 872 * freezes on certain eDPs 873 */ 874 psr_context->psr_level.bits.DISABLE_PSR_ENTRY_ABORT = 1; 875 876 /* Disable ALPM first for compatible non-ALPM panel now */ 877 psr_context->psr_level.bits.DISABLE_ALPM = 0; 878 psr_context->psr_level.bits.ALPM_DEFAULT_PD_MODE = 1; 879 880 /* Controls additional delay after remote frame capture before 881 * continuing power down, default = 0 882 */ 883 psr_context->frame_delay = 0; 884 885 psr_context->dsc_slice_height = psr_config->dsc_slice_height; 886 887 psr_context->os_request_force_ffu = psr_config->os_request_force_ffu; 888 889 if (psr) { 890 link->psr_settings.psr_feature_enabled = psr->funcs->psr_copy_settings(psr, 891 link, psr_context, panel_inst); 892 link->psr_settings.psr_power_opt = 0; 893 link->psr_settings.psr_allow_active = 0; 894 } else { 895 link->psr_settings.psr_feature_enabled = dmcu->funcs->setup_psr(dmcu, link, psr_context); 896 } 897 898 /* psr_enabled == 0 indicates setup_psr did not succeed, but this 899 * should not happen since firmware should be running at this point 900 */ 901 if (link->psr_settings.psr_feature_enabled == 0) 902 ASSERT(0); 903 904 return true; 905 906} 907 908void edp_get_psr_residency(const struct dc_link *link, uint32_t *residency, enum psr_residency_mode mode) 909{ 910 struct dc *dc = link->ctx->dc; 911 struct dmub_psr *psr = dc->res_pool->psr; 912 unsigned int panel_inst; 913 914 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 915 return; 916 917 // PSR residency measurements only supported on DMCUB 918 if (psr != NULL && link->psr_settings.psr_feature_enabled) 919 psr->funcs->psr_get_residency(psr, residency, panel_inst, mode); 920 else 921 *residency = 0; 922} 923bool edp_set_sink_vtotal_in_psr_active(const struct dc_link *link, uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su) 924{ 925 struct dc *dc = link->ctx->dc; 926 struct dmub_psr *psr = dc->res_pool->psr; 927 928 if (psr == NULL || !link->psr_settings.psr_feature_enabled || !link->psr_settings.psr_vtotal_control_support) 929 return false; 930 931 psr->funcs->psr_set_sink_vtotal_in_psr_active(psr, psr_vtotal_idle, psr_vtotal_su); 932 933 return true; 934} 935 936bool edp_set_replay_allow_active(struct dc_link *link, const bool *allow_active, 937 bool wait, bool force_static, const unsigned int *power_opts) 938{ 939 struct dc *dc = link->ctx->dc; 940 struct dmub_replay *replay = dc->res_pool->replay; 941 unsigned int panel_inst; 942 943 if (replay == NULL && force_static) 944 return false; 945 946 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 947 return false; 948 949 /* Set power optimization flag */ 950 if (power_opts && link->replay_settings.replay_power_opt_active != *power_opts) { 951 if (replay != NULL && link->replay_settings.replay_feature_enabled && 952 replay->funcs->replay_set_power_opt) { 953 replay->funcs->replay_set_power_opt(replay, *power_opts, panel_inst); 954 link->replay_settings.replay_power_opt_active = *power_opts; 955 } 956 } 957 958 /* Activate or deactivate Replay */ 959 if (allow_active && link->replay_settings.replay_allow_active != *allow_active) { 960 // TODO: Handle mux change case if force_static is set 961 // If force_static is set, just change the replay_allow_active state directly 962 if (replay != NULL && link->replay_settings.replay_feature_enabled) 963 replay->funcs->replay_enable(replay, *allow_active, wait, panel_inst); 964 link->replay_settings.replay_allow_active = *allow_active; 965 } 966 967 return true; 968} 969 970bool edp_get_replay_state(const struct dc_link *link, uint64_t *state) 971{ 972 struct dc *dc = link->ctx->dc; 973 struct dmub_replay *replay = dc->res_pool->replay; 974 unsigned int panel_inst; 975 enum replay_state pr_state = REPLAY_STATE_0; 976 977 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 978 return false; 979 980 if (replay != NULL && link->replay_settings.replay_feature_enabled) 981 replay->funcs->replay_get_state(replay, &pr_state, panel_inst); 982 *state = pr_state; 983 984 return true; 985} 986 987static bool edp_setup_panel_replay(struct dc_link *link, const struct dc_stream_state *stream) 988{ 989 /* To-do: Setup Replay */ 990 struct dc *dc; 991 struct dmub_replay *replay; 992 int i; 993 unsigned int panel_inst; 994 struct replay_context replay_context = { 0 }; 995 unsigned int lineTimeInNs = 0; 996 997 union panel_replay_enable_and_configuration_1 pr_config_1 = { 0 }; 998 union panel_replay_enable_and_configuration_2 pr_config_2 = { 0 }; 999 1000 union dpcd_alpm_configuration alpm_config; 1001 1002 replay_context.controllerId = CONTROLLER_ID_UNDEFINED; 1003 1004 if (!link) 1005 return false; 1006 1007 //Clear Panel Replay enable & config 1008 dm_helpers_dp_write_dpcd(link->ctx, link, 1009 DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_1, 1010 (uint8_t *)&(pr_config_1.raw), sizeof(uint8_t)); 1011 1012 dm_helpers_dp_write_dpcd(link->ctx, link, 1013 DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_2, 1014 (uint8_t *)&(pr_config_2.raw), sizeof(uint8_t)); 1015 1016 if (!(link->replay_settings.config.replay_supported)) 1017 return false; 1018 1019 dc = link->ctx->dc; 1020 1021 //not sure should keep or not 1022 replay = dc->res_pool->replay; 1023 1024 if (!replay) 1025 return false; 1026 1027 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 1028 return false; 1029 1030 replay_context.aux_inst = link->ddc->ddc_pin->hw_info.ddc_channel; 1031 replay_context.digbe_inst = link->link_enc->transmitter; 1032 replay_context.digfe_inst = link->link_enc->preferred_engine; 1033 1034 for (i = 0; i < MAX_PIPES; i++) { 1035 if (dc->current_state->res_ctx.pipe_ctx[i].stream 1036 == stream) { 1037 /* dmcu -1 for all controller id values, 1038 * therefore +1 here 1039 */ 1040 replay_context.controllerId = 1041 dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg->inst + 1; 1042 break; 1043 } 1044 } 1045 1046 lineTimeInNs = 1047 ((stream->timing.h_total * 1000000) / 1048 (stream->timing.pix_clk_100hz / 10)) + 1; 1049 1050 replay_context.line_time_in_ns = lineTimeInNs; 1051 1052 link->replay_settings.replay_feature_enabled = 1053 replay->funcs->replay_copy_settings(replay, link, &replay_context, panel_inst); 1054 1055 if (link->replay_settings.replay_feature_enabled) { 1056 pr_config_1.bits.PANEL_REPLAY_ENABLE = 1; 1057 pr_config_1.bits.PANEL_REPLAY_CRC_ENABLE = 1; 1058 pr_config_1.bits.IRQ_HPD_ASSDP_MISSING = 1; 1059 pr_config_1.bits.IRQ_HPD_VSCSDP_UNCORRECTABLE_ERROR = 1; 1060 pr_config_1.bits.IRQ_HPD_RFB_ERROR = 1; 1061 pr_config_1.bits.IRQ_HPD_ACTIVE_FRAME_CRC_ERROR = 1; 1062 pr_config_1.bits.PANEL_REPLAY_SELECTIVE_UPDATE_ENABLE = 1; 1063 pr_config_1.bits.PANEL_REPLAY_EARLY_TRANSPORT_ENABLE = 1; 1064 1065 pr_config_2.bits.SINK_REFRESH_RATE_UNLOCK_GRANTED = 0; 1066 pr_config_2.bits.SU_Y_GRANULARITY_EXT_VALUE_ENABLED = 0; 1067 pr_config_2.bits.SU_REGION_SCAN_LINE_CAPTURE_INDICATION = 0; 1068 1069 dm_helpers_dp_write_dpcd(link->ctx, link, 1070 DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_1, 1071 (uint8_t *)&(pr_config_1.raw), sizeof(uint8_t)); 1072 1073 dm_helpers_dp_write_dpcd(link->ctx, link, 1074 DP_PANEL_REPLAY_ENABLE_AND_CONFIGURATION_2, 1075 (uint8_t *)&(pr_config_2.raw), sizeof(uint8_t)); 1076 1077 //ALPM Setup 1078 memset(&alpm_config, 0, sizeof(alpm_config)); 1079 alpm_config.bits.ENABLE = link->replay_settings.config.alpm_mode != DC_ALPM_UNSUPPORTED ? 1 : 0; 1080 1081 if (link->replay_settings.config.alpm_mode == DC_ALPM_AUXLESS) { 1082 alpm_config.bits.ALPM_MODE_SEL = 1; 1083 alpm_config.bits.ACDS_PERIOD_DURATION = 1; 1084 } 1085 1086 dm_helpers_dp_write_dpcd( 1087 link->ctx, 1088 link, 1089 DP_RECEIVER_ALPM_CONFIG, 1090 &alpm_config.raw, 1091 sizeof(alpm_config.raw)); 1092 } 1093 1094 return true; 1095} 1096 1097static bool edp_setup_freesync_replay(struct dc_link *link, const struct dc_stream_state *stream) 1098{ 1099 /* To-do: Setup Replay */ 1100 struct dc *dc; 1101 struct dmub_replay *replay; 1102 int i; 1103 unsigned int panel_inst; 1104 struct replay_context replay_context = { 0 }; 1105 unsigned int lineTimeInNs = 0; 1106 1107 union replay_enable_and_configuration replay_config = { 0 }; 1108 1109 union dpcd_alpm_configuration alpm_config; 1110 1111 replay_context.controllerId = CONTROLLER_ID_UNDEFINED; 1112 1113 if (!link) 1114 return false; 1115 1116 //Clear Replay config 1117 dm_helpers_dp_write_dpcd(link->ctx, link, 1118 DP_SINK_PR_ENABLE_AND_CONFIGURATION, 1119 (uint8_t *)&(replay_config.raw), sizeof(uint8_t)); 1120 1121 if (!(link->replay_settings.config.replay_supported)) 1122 return false; 1123 1124 link->replay_settings.config.replay_error_status.raw = 0; 1125 1126 dc = link->ctx->dc; 1127 1128 replay = dc->res_pool->replay; 1129 1130 if (!replay) 1131 return false; 1132 1133 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 1134 return false; 1135 1136 replay_context.aux_inst = link->ddc->ddc_pin->hw_info.ddc_channel; 1137 replay_context.digbe_inst = link->link_enc->transmitter; 1138 replay_context.digfe_inst = link->link_enc->preferred_engine; 1139 1140 for (i = 0; i < MAX_PIPES; i++) { 1141 if (dc->current_state->res_ctx.pipe_ctx[i].stream 1142 == stream) { 1143 /* dmcu -1 for all controller id values, 1144 * therefore +1 here 1145 */ 1146 replay_context.controllerId = 1147 dc->current_state->res_ctx.pipe_ctx[i].stream_res.tg->inst + 1; 1148 break; 1149 } 1150 } 1151 1152 lineTimeInNs = 1153 ((stream->timing.h_total * 1000000) / 1154 (stream->timing.pix_clk_100hz / 10)) + 1; 1155 1156 replay_context.line_time_in_ns = lineTimeInNs; 1157 1158 replay_context.os_request_force_ffu = link->replay_settings.config.os_request_force_ffu; 1159 1160 link->replay_settings.replay_feature_enabled = 1161 replay->funcs->replay_copy_settings(replay, link, &replay_context, panel_inst); 1162 if (link->replay_settings.replay_feature_enabled) { 1163 1164 replay_config.bits.FREESYNC_PANEL_REPLAY_MODE = 1; 1165 replay_config.bits.TIMING_DESYNC_ERROR_VERIFICATION = 1166 link->replay_settings.config.replay_timing_sync_supported; 1167 replay_config.bits.STATE_TRANSITION_ERROR_DETECTION = 1; 1168 dm_helpers_dp_write_dpcd(link->ctx, link, 1169 DP_SINK_PR_ENABLE_AND_CONFIGURATION, 1170 (uint8_t *)&(replay_config.raw), sizeof(uint8_t)); 1171 1172 memset(&alpm_config, 0, sizeof(alpm_config)); 1173 alpm_config.bits.ENABLE = link->replay_settings.config.alpm_mode != DC_ALPM_UNSUPPORTED ? 1 : 0; 1174 1175 if (link->replay_settings.config.alpm_mode == DC_ALPM_AUXLESS) { 1176 alpm_config.bits.ALPM_MODE_SEL = 1; 1177 alpm_config.bits.ACDS_PERIOD_DURATION = 0; 1178 } 1179 1180 dm_helpers_dp_write_dpcd( 1181 link->ctx, 1182 link, 1183 DP_RECEIVER_ALPM_CONFIG, 1184 &alpm_config.raw, 1185 sizeof(alpm_config.raw)); 1186 } 1187 1188 link->replay_settings.config.replay_video_conferencing_optimization_enabled = false; 1189 1190 return true; 1191} 1192 1193bool edp_setup_replay(struct dc_link *link, const struct dc_stream_state *stream) 1194{ 1195 if (!link) 1196 return false; 1197 if (link->replay_settings.config.replay_version == DC_VESA_PANEL_REPLAY) 1198 return edp_setup_panel_replay(link, stream); 1199 else if (link->replay_settings.config.replay_version == DC_FREESYNC_REPLAY) 1200 return edp_setup_freesync_replay(link, stream); 1201 else 1202 return false; 1203} 1204 1205/* 1206 * This is general Interface for Replay to set an 32 bit variable to dmub 1207 * replay_FW_Message_type: Indicates which instruction or variable pass to DMUB 1208 * cmd_data: Value of the config. 1209 */ 1210bool edp_send_replay_cmd(struct dc_link *link, 1211 enum replay_FW_Message_type msg, 1212 union dmub_replay_cmd_set *cmd_data) 1213{ 1214 struct dc *dc = link->ctx->dc; 1215 struct dmub_replay *replay = dc->res_pool->replay; 1216 unsigned int panel_inst; 1217 1218 if (!replay) 1219 return false; 1220 1221 DC_LOGGER_INIT(link->ctx->logger); 1222 1223 if (dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 1224 cmd_data->panel_inst = panel_inst; 1225 else { 1226 DC_LOG_DC("%s(): get edp panel inst fail ", __func__); 1227 return false; 1228 } 1229 1230 replay->funcs->replay_send_cmd(replay, msg, cmd_data); 1231 1232 return true; 1233} 1234 1235bool edp_set_coasting_vtotal(struct dc_link *link, uint32_t coasting_vtotal, uint16_t frame_skip_number) 1236{ 1237 struct dc *dc = link->ctx->dc; 1238 struct dmub_replay *replay = dc->res_pool->replay; 1239 unsigned int panel_inst; 1240 1241 if (!replay) 1242 return false; 1243 1244 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 1245 return false; 1246 1247 if (coasting_vtotal && (link->replay_settings.coasting_vtotal != coasting_vtotal || 1248 link->replay_settings.frame_skip_number != frame_skip_number)) { 1249 replay->funcs->replay_set_coasting_vtotal(replay, coasting_vtotal, panel_inst, frame_skip_number); 1250 link->replay_settings.coasting_vtotal = coasting_vtotal; 1251 link->replay_settings.frame_skip_number = frame_skip_number; 1252 } 1253 1254 return true; 1255} 1256 1257bool edp_replay_residency(const struct dc_link *link, 1258 unsigned int *residency, const bool is_start, const enum pr_residency_mode mode) 1259{ 1260 struct dc *dc = link->ctx->dc; 1261 struct dmub_replay *replay = dc->res_pool->replay; 1262 unsigned int panel_inst; 1263 1264 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 1265 return false; 1266 1267 if (!residency) 1268 return false; 1269 1270 if (replay != NULL && link->replay_settings.replay_feature_enabled) 1271 replay->funcs->replay_residency(replay, panel_inst, residency, is_start, mode); 1272 else 1273 *residency = 0; 1274 1275 return true; 1276} 1277 1278bool edp_set_replay_power_opt_and_coasting_vtotal(struct dc_link *link, 1279 const unsigned int *power_opts, uint32_t coasting_vtotal, uint16_t frame_skip_number) 1280{ 1281 struct dc *dc = link->ctx->dc; 1282 struct dmub_replay *replay = dc->res_pool->replay; 1283 unsigned int panel_inst; 1284 1285 if (!dc_get_edp_link_panel_inst(dc, link, &panel_inst)) 1286 return false; 1287 1288 /* Only both power and coasting vtotal changed, this func could return true */ 1289 if (power_opts && link->replay_settings.replay_power_opt_active != *power_opts && 1290 (coasting_vtotal && 1291 (link->replay_settings.coasting_vtotal != coasting_vtotal || 1292 link->replay_settings.frame_skip_number != frame_skip_number))) { 1293 if (link->replay_settings.replay_feature_enabled && 1294 replay->funcs->replay_set_power_opt_and_coasting_vtotal) { 1295 replay->funcs->replay_set_power_opt_and_coasting_vtotal(replay, 1296 *power_opts, panel_inst, coasting_vtotal, frame_skip_number); 1297 link->replay_settings.replay_power_opt_active = *power_opts; 1298 link->replay_settings.coasting_vtotal = coasting_vtotal; 1299 link->replay_settings.frame_skip_number = frame_skip_number; 1300 } else 1301 return false; 1302 } else 1303 return false; 1304 1305 return true; 1306} 1307 1308static struct abm *get_abm_from_stream_res(const struct dc_link *link) 1309{ 1310 int i; 1311 struct dc *dc = link->ctx->dc; 1312 struct abm *abm = NULL; 1313 1314 for (i = 0; i < MAX_PIPES; i++) { 1315 struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; 1316 struct dc_stream_state *stream = pipe_ctx->stream; 1317 1318 if (stream && stream->link == link) { 1319 abm = pipe_ctx->stream_res.abm; 1320 break; 1321 } 1322 } 1323 return abm; 1324} 1325 1326int edp_get_backlight_level(const struct dc_link *link) 1327{ 1328 struct abm *abm = get_abm_from_stream_res(link); 1329 struct panel_cntl *panel_cntl = link->panel_cntl; 1330 struct dc *dc = link->ctx->dc; 1331 struct dmcu *dmcu = dc->res_pool->dmcu; 1332 bool fw_set_brightness = true; 1333 1334 if (dmcu) 1335 fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); 1336 1337 if (!fw_set_brightness && panel_cntl->funcs->get_current_backlight) 1338 return panel_cntl->funcs->get_current_backlight(panel_cntl); 1339 else if (abm != NULL && abm->funcs->get_current_backlight != NULL) 1340 return (int) abm->funcs->get_current_backlight(abm); 1341 else 1342 return DC_ERROR_UNEXPECTED; 1343} 1344 1345int edp_get_target_backlight_pwm(const struct dc_link *link) 1346{ 1347 struct abm *abm = get_abm_from_stream_res(link); 1348 1349 if (abm == NULL || abm->funcs->get_target_backlight == NULL) 1350 return DC_ERROR_UNEXPECTED; 1351 1352 return (int) abm->funcs->get_target_backlight(abm); 1353} 1354 1355bool is_smartmux_suported(struct dc_link *link) 1356{ 1357 if (link->dc->caps.is_apu) 1358 return false; 1359 if (!link->dc->config.smart_mux_version) 1360 return false; 1361 1362 return true; 1363} 1364 1365static void edp_set_assr_enable(const struct dc *pDC, struct dc_link *link, 1366 struct link_resource *link_res, bool enable) 1367{ 1368 union dmub_rb_cmd cmd; 1369 bool use_hpo_dp_link_enc = false; 1370 uint8_t link_enc_index = 0; 1371 uint8_t phy_type = 0; 1372 uint8_t phy_id = 0; 1373 1374 if (!pDC->config.use_assr_psp_message) 1375 return; 1376 1377 memset(&cmd, 0, sizeof(cmd)); 1378 1379 link_enc_index = link->link_enc->transmitter - TRANSMITTER_UNIPHY_A; 1380 1381 if (link_res->hpo_dp_link_enc) { 1382 link_enc_index = link_res->hpo_dp_link_enc->inst; 1383 use_hpo_dp_link_enc = true; 1384 } 1385 1386 if (enable) 1387 phy_type = ((dp_get_panel_mode(link) == DP_PANEL_MODE_EDP) ? 1 : 0); 1388 1389 phy_id = resource_transmitter_to_phy_idx(pDC, link->link_enc->transmitter); 1390 1391 cmd.assr_enable.header.type = DMUB_CMD__PSP; 1392 cmd.assr_enable.header.sub_type = DMUB_CMD__PSP_ASSR_ENABLE; 1393 cmd.assr_enable.assr_data.enable = enable; 1394 cmd.assr_enable.assr_data.phy_port_type = phy_type; 1395 cmd.assr_enable.assr_data.phy_port_id = phy_id; 1396 cmd.assr_enable.assr_data.link_enc_index = link_enc_index; 1397 cmd.assr_enable.assr_data.hpo_mode = use_hpo_dp_link_enc; 1398 1399 dc_wake_and_execute_dmub_cmd(pDC->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); 1400} 1401 1402void edp_set_panel_assr(struct dc_link *link, struct pipe_ctx *pipe_ctx, 1403 enum dp_panel_mode *panel_mode, bool enable) 1404{ 1405 struct link_resource *link_res = &pipe_ctx->link_res; 1406 struct cp_psp *cp_psp = &pipe_ctx->stream->ctx->cp_psp; 1407 1408 if (*panel_mode != DP_PANEL_MODE_EDP) 1409 return; 1410 1411 if (link->dc->config.use_assr_psp_message) { 1412 edp_set_assr_enable(link->dc, link, link_res, enable); 1413 } else if (cp_psp && cp_psp->funcs.enable_assr && enable) { 1414 /* ASSR is bound to fail with unsigned PSP 1415 * verstage used during devlopment phase. 1416 * Report and continue with eDP panel mode to 1417 * perform eDP link training with right settings 1418 */ 1419 bool result; 1420 1421 result = cp_psp->funcs.enable_assr(cp_psp->handle, link); 1422 1423 if (!result && link->panel_mode != DP_PANEL_MODE_EDP) 1424 *panel_mode = DP_PANEL_MODE_DEFAULT; 1425 } 1426}
~/
Read-only file preview.