1 /* 2 * Copyright 2016 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 "dm_services.h" 27 #include "dc.h" 28 #include "mod_power.h" 29 #include "core_types.h" 30 #include "dmcu.h" 31 #include "abm.h" 32 #include "power_helpers.h" 33 #include "dce/dmub_psr.h" 34 #include "dal_asic_id.h" 35 #include "link_service.h" 36 #include <linux/math.h> 37 38 #define DC_TRACE_LEVEL_MESSAGE(...) /* do nothing */ 39 #define DC_TRACE_LEVEL_MESSAGEP(...) /* do nothing */ 40 41 #define MOD_POWER_MAX_CONCURRENT_STREAMS 32 42 #define SMOOTH_BRIGHTNESS_ADJUSTMENT_TIME_IN_MS 500 43 #define LOW_REFRESH_RATE_DURATION_US_UPPER_BOUND 25000 44 45 46 struct backlight_state { 47 /* HW uses u16.16 format for backlight PWM */ 48 unsigned int backlight_pwm; 49 /* DM may call power module to set backlight 50 * targeting percent brightness 51 */ 52 unsigned int backlight_millipercent; 53 /* DM may call power module to set backlight based on an explicit 54 * nits value. 55 */ 56 unsigned int backlight_millinit; 57 unsigned int frame_ramp; 58 bool smooth_brightness_enabled; 59 bool isHDR; 60 }; 61 struct power_entity { 62 struct dc_stream_state *stream; 63 struct psr_caps *caps; 64 struct mod_power_psr_context *psr_context; 65 66 /*PSR cached properties*/ 67 bool psr_enabled; 68 unsigned int psr_events; 69 unsigned int psr_power_opt; 70 unsigned int replay_events; 71 }; 72 73 struct pwr_backlight_properties { 74 bool use_nits_based_brightness; 75 bool disable_fractional_pwm; 76 77 unsigned int min_abm_backlight; 78 unsigned int num_backlight_levels; 79 80 bool backlight_ramping_override; 81 unsigned int backlight_ramping_reduction; 82 unsigned int backlight_ramping_start; 83 84 /* Backlight cached properties */ 85 unsigned int ac_backlight_percent; 86 unsigned int dc_backlight_percent; 87 88 /* backlight LUT stored in HW u16.16 format*/ 89 unsigned int *backlight_lut; 90 unsigned int min_backlight_pwm; 91 unsigned int max_backlight_pwm; 92 unsigned int backlight_range; 93 94 /* Describes the panel's min and max luminance in millinits measured 95 * on full white screen, in min and max backlight settings. 96 */ 97 unsigned int min_brightness_millinits; 98 unsigned int max_brightness_millinits; 99 unsigned int nits_range; 100 101 bool backlight_caps_valid; 102 bool use_custom_backlight_caps; 103 unsigned int custom_backlight_caps_config_no; 104 bool use_linear_backlight_curve; 105 }; 106 107 struct dmcu_varibright_cached_properties { 108 unsigned int varibright_config_setting; 109 unsigned int varibright_level; 110 unsigned int varibright_hw_level; 111 unsigned int def_varibright_level; 112 bool varibright_user_enable; 113 bool varibright_active; 114 }; 115 116 struct core_power { 117 struct mod_power mod_public; 118 struct dc *dc; 119 struct power_entity *map; 120 struct dmcu_varibright_cached_properties varibright_prop; 121 struct pwr_backlight_properties bl_prop[MAX_NUM_EDP]; 122 struct backlight_state bl_state[MAX_NUM_EDP]; 123 unsigned int edp_num; 124 125 bool psr_smu_optimizations_support; 126 bool multi_disp_optimizations_support; 127 128 unsigned int num_entities; 129 }; 130 131 union dmcu_abm_set_bl_params { 132 struct { 133 unsigned int gradual_change : 1; /* [0:0] */ 134 unsigned int reserved : 15; /* [15:1] */ 135 unsigned int frame_ramp : 16; /* [31:16] */ 136 } bits; 137 unsigned int u32All; 138 }; 139 140 /* If system or panel does not report some sort of brightness percent to nits 141 * mapping, we will use following default values so backlight control using 142 * nits based interfaces will still work, but might not describe panel 143 * correctly. In this case percentage based backlight control should ideally 144 * be used. 145 * Min = 5 nits 146 * Max = 300 nits 147 */ 148 149 static const unsigned int pwr_default_min_brightness_millinits = 1000; 150 static const unsigned int pwr_default_sdr_brightness_millinits = 270000; 151 152 static const unsigned int default_ac_backlight_percent = 100; 153 static const unsigned int default_dc_backlight_percent = 70; 154 155 #define MOD_POWER_TO_CORE(mod_power)\ 156 container_of(mod_power, struct core_power, mod_public) 157 158 static unsigned int calc_psr_num_static_frames(unsigned int vsync_rate_hz) 159 { 160 /* Initialize fail-safe to 2 static frames. */ 161 unsigned int num_frames_static = 2; 162 163 /* Calculate number of frames such that at least 30 ms has passed. 164 * Round up to ensure the static period is not shorter than 30 ms. 165 */ 166 if (vsync_rate_hz != 0) 167 num_frames_static = DIV_ROUND_UP(30000 * vsync_rate_hz, 1000000); 168 169 return num_frames_static; 170 } 171 172 /* Given a specific dc_stream* this function finds its equivalent 173 * on the core_freesync->map and returns the corresponding index 174 */ 175 static unsigned int map_index_from_stream(struct core_power *core_power, 176 const struct dc_stream_state *stream) 177 { 178 unsigned int index = 0; 179 180 for (index = 0; index < core_power->num_entities; index++) { 181 if (core_power->map[index].stream == stream) 182 return index; 183 } 184 /* Could not find stream requested, this is not trivial, fix when hit*/ 185 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 186 WPP_BIT_FLAG_Firmware_PsrState, 187 "map index from stream: ERROR: core_power=%p stream=%p", 188 core_power, 189 stream); 190 ASSERT(false); 191 /* We come here only when we can't map stream index. 192 * In good cases, this would happen when we attempt to change 193 * brightness before stream creation, in which case we create a 194 * dummy stream with index 0. 195 * With external monitor connected, the index passed from this return 196 * is 1. Passing anything greater than 0 from here would always point 197 * to bad memory. 198 */ 199 return 0; 200 } 201 202 bool mod_power_hw_init(struct mod_power *mod_power) 203 { 204 /* Call backlight initialization */ 205 return mod_power_hw_init_backlight(mod_power); 206 207 /* Future: Add other HW init here */ 208 } 209 210 struct mod_power *mod_power_create(struct dc *dc, 211 struct mod_power_init_params *init_params, 212 unsigned int edp_num) 213 { 214 struct core_power *core_power = NULL; 215 int i = 0; 216 unsigned int abm_max_config = 0; 217 unsigned int inst = 0; 218 bool is_brightness_range_valid = false; 219 220 if (dc == NULL) 221 goto fail_dc_null; 222 223 core_power = kzalloc(sizeof(struct core_power), GFP_KERNEL); 224 225 if (core_power == NULL) 226 goto fail_alloc_context; 227 228 core_power->edp_num = edp_num; 229 core_power->map = kzalloc(sizeof(struct power_entity) * MOD_POWER_MAX_CONCURRENT_STREAMS, 230 GFP_KERNEL); 231 232 if (core_power->map == NULL) 233 goto fail_alloc_map; 234 235 for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) { 236 core_power->map[i].stream = NULL; 237 } 238 239 for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) { 240 core_power->map[i].psr_context = 241 kzalloc(sizeof(struct mod_power_psr_context), 242 GFP_KERNEL); 243 if (core_power->map[i].psr_context == NULL) 244 goto fail_construct; 245 } 246 247 core_power->psr_smu_optimizations_support = init_params->allow_psr_smu_optimizations; 248 core_power->multi_disp_optimizations_support = init_params->allow_psr_multi_disp_optimizations; 249 250 for (inst = 0; inst < edp_num; inst++) { 251 core_power->bl_prop[inst].min_abm_backlight = 252 init_params[inst].min_abm_backlight; 253 core_power->bl_prop[inst].disable_fractional_pwm = 254 init_params[inst].disable_fractional_pwm; 255 core_power->bl_prop[inst].use_linear_backlight_curve = 256 init_params[inst].use_linear_backlight_curve; 257 core_power->bl_prop[inst].use_nits_based_brightness = 258 init_params[inst].use_nits_based_brightness; 259 core_power->bl_prop[inst].backlight_ramping_override = 260 init_params[inst].backlight_ramping_override; 261 core_power->bl_prop[inst].backlight_ramping_reduction = 262 init_params[inst].backlight_ramping_reduction; 263 core_power->bl_prop[inst].backlight_ramping_start = 264 init_params[inst].backlight_ramping_start; 265 core_power->bl_prop[inst].use_custom_backlight_caps = 266 init_params[inst].use_custom_backlight_caps; 267 core_power->bl_prop[inst].custom_backlight_caps_config_no = 268 init_params[inst].custom_backlight_caps_config_no; 269 270 // Do not allow less than 101 backlight levels 271 if (init_params[inst].num_backlight_levels < 101) 272 core_power->bl_prop[inst].num_backlight_levels = 101; 273 else 274 core_power->bl_prop[inst].num_backlight_levels = 275 init_params[inst].num_backlight_levels; 276 277 core_power->bl_prop[inst].backlight_lut = (unsigned int *) 278 (kzalloc(sizeof(unsigned int) * 279 core_power->bl_prop[inst].num_backlight_levels, GFP_KERNEL)); 280 if (core_power->bl_prop[inst].backlight_lut == NULL) 281 goto fail_alloc_backlight_array; 282 } 283 284 core_power->varibright_prop.varibright_active = false; 285 286 core_power->varibright_prop.varibright_user_enable = 287 init_params->def_varibright_enable; 288 289 // Table of ABM levels here is 1-4, but level 0 also exists as 'off' 290 if (init_params->varibright_level <= abm_defines_max_level) { 291 core_power->varibright_prop.varibright_level = 292 init_params->varibright_level; 293 294 } else { 295 core_power->varibright_prop.varibright_level = 3; 296 } 297 if (init_params->def_varibright_level <= abm_defines_max_level) { 298 core_power->varibright_prop.def_varibright_level = 299 init_params->def_varibright_level; 300 } else { 301 core_power->varibright_prop.def_varibright_level = 3; 302 } 303 304 // ABM used to contain 4 different configs. There is only 3 since ABM 2.3. 305 if ((dc->res_pool->dmcu != NULL) && (dc->res_pool->dmcu->dmcu_version.abm_version < 0x23)) 306 abm_max_config = 4; 307 else 308 abm_max_config = 3; 309 310 if (init_params->abm_config_setting < abm_max_config) 311 core_power->varibright_prop.varibright_config_setting = 312 init_params->abm_config_setting; 313 else 314 core_power->varibright_prop.varibright_config_setting = 0; 315 316 for (inst = 0; inst < edp_num; inst++) { 317 core_power->bl_prop[inst].backlight_lut[0] = init_params[inst].min_backlight_pwm; 318 core_power->bl_prop[inst].backlight_lut[ 319 core_power->bl_prop[inst].num_backlight_levels-1] = 320 init_params[inst].max_backlight_pwm; 321 core_power->bl_prop[inst].min_backlight_pwm = init_params[inst].min_backlight_pwm; 322 core_power->bl_prop[inst].max_backlight_pwm = init_params[inst].max_backlight_pwm; 323 core_power->bl_prop[inst].ac_backlight_percent = 324 default_ac_backlight_percent; 325 core_power->bl_prop[inst].dc_backlight_percent = 326 default_dc_backlight_percent; 327 core_power->bl_prop[inst].backlight_caps_valid = false; 328 329 if (core_power->bl_prop[inst].use_nits_based_brightness) { 330 core_power->bl_prop[inst].min_brightness_millinits = 331 init_params[inst].panel_min_millinits; 332 core_power->bl_prop[inst].max_brightness_millinits = 333 init_params[inst].panel_max_millinits; 334 } else { 335 336 core_power->bl_prop[inst].min_brightness_millinits = 337 pwr_default_min_brightness_millinits; 338 core_power->bl_prop[inst].max_brightness_millinits = 339 pwr_default_sdr_brightness_millinits; 340 } 341 342 core_power->bl_prop[inst].backlight_range = 343 core_power->bl_prop[inst].max_backlight_pwm- 344 core_power->bl_prop[inst].min_backlight_pwm; 345 346 core_power->bl_prop[inst].nits_range = 347 core_power->bl_prop[inst].max_brightness_millinits - 348 core_power->bl_prop[inst].min_brightness_millinits; 349 350 core_power->bl_state[inst].smooth_brightness_enabled = true; 351 } 352 353 /* Check if at least 1 instance in core_power is populated before failing */ 354 for (inst = 0; inst < edp_num; inst++) { 355 if (core_power->bl_prop[inst].nits_range != 0 && core_power->bl_prop[inst].backlight_range != 0) { 356 is_brightness_range_valid = true; 357 break; 358 } 359 360 } 361 if (!is_brightness_range_valid) 362 goto fail_bad_brightness_range; 363 364 core_power->num_entities = 0; 365 366 core_power->dc = dc; 367 for (inst = 0; inst < edp_num; inst++) { 368 initialize_backlight_caps(core_power, inst); 369 core_power->bl_state[inst].backlight_millipercent = 370 core_power->bl_prop[inst].dc_backlight_percent * 1000; 371 core_power->bl_state[inst].backlight_pwm = backlight_millipercent_to_pwm(core_power, 372 core_power->bl_state[inst].backlight_millipercent, inst); 373 core_power->bl_state[inst].backlight_millinit = backlight_millipercent_to_millinit(core_power, 374 core_power->bl_state[inst].backlight_millipercent, inst); 375 } 376 377 return &core_power->mod_public; 378 379 fail_bad_brightness_range: 380 fail_alloc_backlight_array: 381 for (inst = 0; inst < edp_num; inst++) 382 if (core_power->bl_prop[inst].backlight_lut) 383 kfree(core_power->bl_prop[inst].backlight_lut); 384 fail_construct: 385 for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) { 386 if (core_power->map[i].psr_context) 387 kfree(core_power->map[i].psr_context); 388 } 389 kfree(core_power->map); 390 391 fail_alloc_map: 392 kfree(core_power); 393 394 fail_alloc_context: 395 fail_dc_null: 396 return NULL; 397 } 398 399 void mod_power_destroy(struct mod_power *mod_power) 400 { 401 if (mod_power != NULL) { 402 unsigned int i; 403 struct core_power *core_power = 404 MOD_POWER_TO_CORE(mod_power); 405 406 for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) 407 if (core_power->map[i].psr_context) 408 kfree(core_power->map[i].psr_context); 409 410 for (i = 0; i < core_power->num_entities; i++) 411 if (core_power->map[i].stream) 412 dc_stream_release(core_power->map[i].stream); 413 414 kfree(core_power->map); 415 416 for (i = 0; i < MAX_NUM_EDP; i++) 417 if (core_power->bl_prop[i].backlight_lut) 418 kfree(core_power->bl_prop[i].backlight_lut); 419 420 kfree(core_power); 421 } 422 } 423 424 bool mod_power_add_stream(struct mod_power *mod_power, 425 struct dc_stream_state *stream, struct psr_caps *caps) 426 { 427 struct core_power *core_power = NULL; 428 429 if (mod_power == NULL) 430 return false; 431 432 core_power = MOD_POWER_TO_CORE(mod_power); 433 434 if (core_power->num_entities < MOD_POWER_MAX_CONCURRENT_STREAMS) { 435 dc_stream_retain(stream); 436 437 core_power->map[core_power->num_entities].stream = stream; 438 core_power->map[core_power->num_entities].caps = caps; 439 440 // initialize cached PSR params to something "safe" (something that is 441 // consistent with disabled PSR state) 442 core_power->map[core_power->num_entities].psr_enabled = 0; 443 core_power->map[core_power->num_entities].psr_events = psr_event_vsync; 444 core_power->map[core_power->num_entities].psr_power_opt = 0; 445 core_power->num_entities++; 446 return true; 447 } 448 449 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 450 WPP_BIT_FLAG_Firmware_PsrState, 451 "mod_power: add_stream: ERROR: stream=%p num_entities=%u >= MOD_POWER_MAX_CONCURRENT_STREAMS", 452 stream, 453 core_power->num_entities); 454 455 return false; 456 } 457 458 bool mod_power_remove_stream(struct mod_power *mod_power, 459 const struct dc_stream_state *stream) 460 { 461 unsigned int i = 0; 462 struct core_power *core_power = NULL; 463 unsigned int index = 0; 464 465 if (mod_power == NULL) 466 return false; 467 468 core_power = MOD_POWER_TO_CORE(mod_power); 469 if (core_power->num_entities == 0) { 470 /* trying to remove a stream a second time or have not added yet */ 471 BREAK_TO_DEBUGGER(); 472 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 473 WPP_BIT_FLAG_Firmware_PsrState, 474 "mod_power: remove_stream: ERROR: num_entities=0 stream=%p", 475 stream); 476 return false; 477 } 478 479 index = map_index_from_stream(core_power, stream); 480 481 if (index >= core_power->num_entities) { 482 /* trying to remove a stream a second time or have not added yet */ 483 BREAK_TO_DEBUGGER(); 484 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 485 WPP_BIT_FLAG_Firmware_PsrState, 486 "mod_power: remove_stream: ERROR: index=%u >= num_entities=%u stream=%p", 487 index, 488 core_power->num_entities, 489 stream); 490 return false; 491 } 492 493 dc_stream_release(core_power->map[index].stream); 494 core_power->map[index].stream = NULL; 495 /* To remove this entity, shift everything after down */ 496 for (i = index; i < core_power->num_entities - 1; i++) { 497 core_power->map[i].stream = core_power->map[i + 1].stream; 498 core_power->map[i].caps = core_power->map[i + 1].caps; 499 500 // copy over cached parameters in case they map to PSR capable display 501 core_power->map[i].psr_enabled = core_power->map[i + 1].psr_enabled; 502 core_power->map[i].psr_events = core_power->map[i + 1].psr_events; 503 core_power->map[i].psr_power_opt = core_power->map[i + 1].psr_power_opt; 504 505 memcpy(core_power->map[i].psr_context, core_power->map[i + 1].psr_context, sizeof(struct mod_power_psr_context)); 506 memset(core_power->map[i + 1].psr_context, 0, sizeof(struct mod_power_psr_context)); 507 } 508 core_power->num_entities--; 509 510 return true; 511 } 512 513 /* 514 * Replace_stream should be used when there is a mode set for existing 515 * display target with a valid stream. In this case might need to retain 516 * cached PSR state (events, power opt, en/dis) if we are dealing with PSR 517 * capable display. If mod_power_remove and mod_power_add are used instead, 518 * then stream may be assigned to a different slot and may end up with 519 * wrong cached PSR state. It is hard to tell which PSR events should 520 * persist through mode set or what psr_events should be initialized to, so 521 * it might be better just to retain them all. 522 */ 523 bool mod_power_replace_stream(struct mod_power *mod_power, 524 const struct dc_stream_state *current_stream, 525 struct dc_stream_state *new_stream, 526 struct psr_caps *new_caps) 527 { 528 struct core_power *core_power = NULL; 529 unsigned int index = 0; 530 531 if (mod_power == NULL) 532 return false; 533 534 core_power = MOD_POWER_TO_CORE(mod_power); 535 if (core_power->num_entities == 0) { 536 /* no streams exist in the table yet */ 537 BREAK_TO_DEBUGGER(); 538 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 539 WPP_BIT_FLAG_Firmware_PsrState, 540 "mod_power: replace_stream: ERROR: num_entities=0 stream=%p", 541 current_stream); 542 return false; 543 } 544 545 index = map_index_from_stream(core_power, current_stream); 546 547 if (index >= core_power->num_entities) { 548 /* trying to replace a non-existent stream */ 549 BREAK_TO_DEBUGGER(); 550 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 551 WPP_BIT_FLAG_Firmware_PsrState, 552 "mod_power: replace_stream: ERROR: index=%u >= num_entities=%u stream=%p", 553 index, 554 core_power->num_entities, 555 current_stream); 556 return false; 557 } 558 559 dc_stream_release(core_power->map[index].stream); 560 dc_stream_retain(new_stream); 561 core_power->map[index].stream = new_stream; 562 core_power->map[index].caps = new_caps; 563 memset(core_power->map[index].psr_context, 0, sizeof(struct mod_power_psr_context)); 564 565 return true; 566 } 567 568 bool mod_power_notify_mode_change(struct mod_power *mod_power, 569 const struct dc_stream_state *stream, 570 bool is_hdr) 571 { 572 unsigned int stream_index = 0; 573 struct core_power *core_power = NULL; 574 struct dc_link *link = NULL; 575 struct psr_config psr_config = {0}; 576 struct psr_context psr_context = {0}; 577 struct dc *dc = NULL; 578 unsigned int panel_inst = 0; 579 int active_psr_events = 0; 580 int active_replay_events = 0; 581 582 if ((mod_power == NULL) || (stream == NULL)) 583 return false; 584 585 core_power = MOD_POWER_TO_CORE(mod_power); 586 587 if (core_power->num_entities == 0) 588 return false; 589 590 stream_index = map_index_from_stream(core_power, stream); 591 592 if (stream_index >= core_power->num_entities) 593 return false; 594 595 dc = core_power->dc; 596 link = dc_stream_get_link(stream); 597 active_psr_events = core_power->map[stream_index].psr_events; 598 active_replay_events = core_power->map[stream_index].replay_events; 599 if (link != NULL && dc_get_edp_link_panel_inst(dc, link, &panel_inst)) { 600 ASSERT(link->ddc->ddc_pin->hw_info.ddc_channel <= 0xFF); 601 uint8_t aux_inst = (uint8_t)link->ddc->ddc_pin->hw_info.ddc_channel; 602 603 mod_power_update_backlight_on_mode_change(core_power, link, panel_inst, aux_inst, is_hdr); 604 605 mod_power_calc_psr_configs(&psr_config, link, stream); 606 607 psr_config.psr_exit_link_training_required = core_power->map[stream_index].caps->psr_exit_link_training_required; 608 609 if (dc->ctx->asic_id.chip_family >= AMDGPU_FAMILY_GC_11_0_1) 610 psr_config.allow_smu_optimizations = 611 core_power->psr_smu_optimizations_support && dc_is_embedded_signal(stream->signal); 612 else 613 psr_config.allow_smu_optimizations = 614 core_power->psr_smu_optimizations_support && mod_power_only_edp(dc->current_state, stream); 615 616 psr_config.allow_multi_disp_optimizations = core_power->multi_disp_optimizations_support; 617 618 psr_config.rate_control_caps = core_power->map[stream_index].caps->rate_control_caps; 619 620 if (active_psr_events & psr_event_os_request_force_ffu) { 621 psr_config.os_request_force_ffu = true; 622 } 623 /* 624 * DSC support: 625 * DSC slice height value must be 'mod' by su_y_granularity. 626 * According to Panel Vendor, there might be varied conditions to fulfill. 627 * Right now, DSC slice height value must be multiple of su_y_granularity. 628 * 629 * The value of DSC slice height is determined in DSC Driver but it does not 630 * propagated out here, so we need to calculate it as below 'slice_height'. 631 */ 632 psr_su_set_dsc_slice_height(dc, link, 633 (struct dc_stream_state *) stream, 634 &psr_config); 635 636 dc_link_setup_psr(link, stream, &psr_config, &psr_context); 637 638 link->replay_settings.replay_smu_opt_enable = 639 (link->replay_settings.config.replay_smu_opt_supported && 640 mod_power_only_edp(dc->current_state, stream)); 641 642 if (active_replay_events & replay_event_os_request_force_ffu) { 643 link->replay_settings.config.os_request_force_ffu = true; 644 } 645 646 if (dc_is_embedded_signal(stream->signal)) 647 dc->link_srv->dp_setup_replay(link, stream); 648 } 649 650 return true; 651 } 652 653 static void mod_power_psr_set_power_opt(struct mod_power *mod_power, 654 struct dc_stream_state *stream, 655 unsigned int active_psr_events, 656 bool psr_enable_request) 657 { 658 (void)psr_enable_request; 659 struct core_power *core_power = NULL; 660 struct dc_link *link = NULL; 661 unsigned int stream_index = 0; 662 unsigned int power_opt = 0; 663 664 if (!stream) 665 return; 666 667 core_power = MOD_POWER_TO_CORE(mod_power); 668 stream_index = map_index_from_stream(core_power, stream); 669 if (!core_power->map[stream_index].caps->psr_version) 670 return; 671 672 link = dc_stream_get_link(stream); 673 674 if (active_psr_events == 0) { 675 /* Static Screen */ 676 power_opt |= (psr_power_opt_smu_opt_static_screen | psr_power_opt_z10_static_screen | 677 psr_power_opt_ds_disable_allow); 678 } 679 680 /* psr_power_opt_flag is a configuration parameter into the module that determines 681 * which optimizations to enable during psr 682 */ 683 power_opt &= core_power->map[stream_index].caps->psr_power_opt_flag; 684 if (core_power->map[stream_index].psr_power_opt != power_opt) { 685 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_VERBOSE, 686 WPP_BIT_FLAG_Firmware_PsrState, 687 "mod_power set_power_opt: psr_power_opt=0x%04x, power_opt=0x%04x" 688 "active_psr_events=0x%04x, psr_power_opt_flag=0x%04x", 689 core_power->map[stream_index].psr_power_opt, 690 power_opt, 691 active_psr_events, 692 core_power->map[stream_index].caps->psr_power_opt_flag); 693 dc_link_set_psr_allow_active(link, NULL, false, false, &power_opt); 694 core_power->map[stream_index].psr_power_opt = power_opt; 695 } 696 } 697 698 static bool set_psr_enable(struct mod_power *mod_power, 699 struct dc_stream_state *stream, 700 bool psr_enable, 701 bool wait, 702 bool force_static) 703 { 704 struct core_power *core_power = NULL; 705 enum dc_psr_state state = PSR_STATE0; 706 unsigned int retry_count; 707 const unsigned int max_retry = 1000; 708 struct dc_link *link = NULL; 709 710 if (mod_power == NULL) 711 return false; 712 713 core_power = MOD_POWER_TO_CORE(mod_power); 714 715 if (core_power->num_entities == 0) { 716 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 717 WPP_BIT_FLAG_Firmware_PsrState, 718 "set psr enable: ERROR: stream=%p num_entities=%u", 719 stream, 720 core_power->num_entities); 721 return false; 722 } 723 724 if (psr_enable) { 725 unsigned int vsync_rate_hz; 726 struct dc_static_screen_params params = {0}; 727 728 vsync_rate_hz = (unsigned int)div_u64(div_u64(( 729 stream->timing.pix_clk_100hz * 100), 730 stream->timing.v_total), 731 stream->timing.h_total); 732 733 params.triggers.cursor_update = true; 734 params.triggers.overlay_update = true; 735 params.triggers.surface_update = true; 736 params.num_frames = calc_psr_num_static_frames(vsync_rate_hz); 737 738 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 739 WPP_BIT_FLAG_Firmware_PsrState, 740 "set psr enable: CALCS: pix_clk_100hz=%u v_total=%u h_total=%u vsync_rate_hz=%u num_frames=%u", 741 stream->timing.pix_clk_100hz, 742 stream->timing.v_total, 743 stream->timing.h_total, 744 vsync_rate_hz, 745 params.num_frames); 746 747 dc_stream_set_static_screen_params(core_power->dc, 748 &stream, 1, 749 ¶ms); 750 } 751 752 link = dc_stream_get_link(stream); 753 754 if (!dc_link_set_psr_allow_active(link, &psr_enable, false, force_static, NULL)) { 755 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 756 WPP_BIT_FLAG_Firmware_PsrState, 757 "set psr enable: ERROR: stream=%p link=%p psr_enable=%d", 758 stream, 759 link, 760 psr_enable); 761 return false; 762 } 763 764 if (wait == true) { 765 766 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 767 WPP_BIT_FLAG_Firmware_PsrState, 768 "set psr enable: BEGIN WAIT: psr_enable=%d", 769 (int)psr_enable); 770 771 for (retry_count = 0; retry_count <= max_retry; retry_count++) { 772 dc_link_get_psr_state(link, &state); 773 if (psr_enable) { 774 if (state != PSR_STATE0 && 775 (!force_static || state == PSR_STATE3)) 776 break; 777 } else { 778 if (state == PSR_STATE0) 779 break; 780 } 781 udelay(500); 782 } 783 784 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 785 WPP_BIT_FLAG_Firmware_PsrState, 786 "set psr enable: END WAIT: psr_enable=%d", 787 (int)psr_enable); 788 789 /* assert if max retry hit */ 790 if (retry_count >= max_retry) { 791 ASSERT(0); 792 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 793 WPP_BIT_FLAG_Firmware_PsrState, 794 "set psr enable: ERROR: retry_count=%u: Unexpectedly long wait for PSR state change.", 795 retry_count); 796 } 797 } else { 798 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 799 WPP_BIT_FLAG_Firmware_PsrState, 800 "set psr enable: PSR state change initiated (wait=false): psr_enable=%d", 801 (int)psr_enable); 802 } 803 804 return true; 805 } 806 807 bool mod_power_get_psr_event(struct mod_power *mod_power, 808 struct dc_stream_state *stream, 809 unsigned int *active_psr_events) 810 { 811 struct core_power *core_power = NULL; 812 unsigned int stream_index = 0; 813 814 if (mod_power == NULL) 815 return false; 816 817 core_power = MOD_POWER_TO_CORE(mod_power); 818 819 if (core_power->num_entities == 0) 820 return false; 821 822 stream_index = map_index_from_stream(core_power, stream); 823 824 if (!core_power->map[stream_index].caps->psr_version) 825 return false; 826 827 *active_psr_events = core_power->map[stream_index].psr_events; 828 829 return true; 830 } 831 832 bool mod_power_set_psr_event(struct mod_power *mod_power, 833 struct dc_stream_state *stream, bool set_event, 834 enum psr_event event, bool wait) 835 { 836 struct core_power *core_power = NULL; 837 unsigned int stream_index = 0; 838 unsigned int active_psr_events = 0; 839 bool psr_enable_request = false; 840 bool force_static = false; 841 842 if (mod_power == NULL || stream == NULL) 843 return false; 844 845 core_power = MOD_POWER_TO_CORE(mod_power); 846 stream_index = map_index_from_stream(core_power, stream); 847 848 if (core_power->num_entities == 0) { 849 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 850 WPP_BIT_FLAG_Firmware_PsrState, 851 "mod_power set_psr_event: ERROR: stream=%p event=%d num_entities=%u", 852 stream, 853 (int)event, 854 core_power->num_entities); 855 return false; 856 } 857 858 if (!core_power->map[stream_index].caps->psr_version) 859 return false; 860 861 if (set_event) 862 core_power->map[stream_index].psr_events |= event; 863 else 864 core_power->map[stream_index].psr_events &= ~event; 865 866 active_psr_events = core_power->map[stream_index].psr_events; 867 868 // ignore other events when we're in forced psr enabled state 869 if (active_psr_events & psr_event_dynamic_display_switch && 870 event != psr_event_dynamic_display_switch) 871 return false; 872 873 // ignore other events when we're in forced psr enabled state 874 if (active_psr_events & psr_event_os_override_hold && 875 event != psr_event_os_override_hold) 876 return false; 877 878 // ignore other events when we're in forced psr enabled state 879 // dds events need to be processed while in dynamic_link_rate_control 880 if (active_psr_events & psr_event_dynamic_link_rate_control && 881 event != psr_event_dynamic_link_rate_control && 882 event != psr_event_dds_defer_stream_enable && 883 event != psr_event_dynamic_display_switch) 884 return false; 885 886 if (active_psr_events & (psr_event_test_harness_disable_psr | psr_event_os_request_disable)) 887 psr_enable_request = false; 888 else if (active_psr_events & psr_event_pause) 889 psr_enable_request = false; 890 else if (active_psr_events & psr_event_test_harness_enable_psr) 891 psr_enable_request = true; 892 else if (active_psr_events & psr_event_dynamic_display_switch) { 893 psr_enable_request = true; 894 force_static = true; 895 } else if (active_psr_events & psr_event_dynamic_link_rate_control) { 896 psr_enable_request = true; 897 force_static = true; 898 } else if (active_psr_events & psr_event_edp_panel_off_disable_psr) 899 psr_enable_request = false; 900 else if (active_psr_events & (psr_event_hw_programming | 901 psr_event_defer_enable | 902 psr_event_dds_defer_stream_enable | 903 psr_event_vrr_transition | 904 psr_event_immediate_flip)) 905 psr_enable_request = false; 906 else if (active_psr_events & psr_event_big_screen_video) 907 psr_enable_request = true; 908 else if (active_psr_events & psr_event_full_screen) 909 psr_enable_request = false; 910 else if (active_psr_events & psr_event_mpo_video_selective_update) 911 psr_enable_request = true; 912 else if (active_psr_events & psr_event_vsync) 913 psr_enable_request = false; 914 else if (active_psr_events & psr_event_crc_window_active) 915 psr_enable_request = false; 916 else 917 psr_enable_request = true; 918 919 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_VERBOSE, 920 WPP_BIT_FLAG_Firmware_PsrState, 921 "mod_power set_psr_event: before: psr_enabled=%d -> request: set_event=%d event=0x%04x -> result: psr_events=0x%04x psr_enable_request=%d", 922 (int)core_power->map[stream_index].psr_enabled, 923 (int)set_event, 924 (unsigned int)event, 925 (unsigned int)core_power->map[stream_index].psr_events, 926 (int)psr_enable_request); 927 mod_power_psr_set_power_opt(mod_power, stream, active_psr_events, psr_enable_request); 928 929 if (core_power->map[stream_index].psr_enabled != psr_enable_request || force_static) { 930 if (set_psr_enable(mod_power, stream, psr_enable_request, wait, force_static)) { 931 core_power->map[stream_index].psr_enabled = psr_enable_request; 932 } 933 } 934 935 return true; 936 } 937 938 bool mod_power_get_psr_state(struct mod_power *mod_power, 939 const struct dc_stream_state *stream, 940 enum dc_psr_state *state) 941 { 942 struct core_power *core_power = NULL; 943 const struct dc_link *link = NULL; 944 945 if (!stream) 946 return false; 947 948 if (mod_power == NULL) 949 return false; 950 951 core_power = MOD_POWER_TO_CORE(mod_power); 952 953 if (core_power->num_entities == 0) 954 return false; 955 956 link = dc_stream_get_link(stream); 957 return dc_link_get_psr_state(link, state); 958 } 959 960 bool mod_power_get_psr_enabled_status(struct mod_power *mod_power, 961 const struct dc_stream_state *stream, 962 bool *psr_enabled) 963 { 964 struct core_power *core_power = NULL; 965 unsigned int stream_index = 0; 966 967 if (mod_power == NULL) 968 return false; 969 970 core_power = MOD_POWER_TO_CORE(mod_power); 971 972 if (core_power->num_entities == 0) 973 return false; 974 975 stream_index = map_index_from_stream(core_power, stream); 976 977 if (!core_power->map[stream_index].caps->psr_version) 978 return false; 979 980 *psr_enabled = core_power->map[stream_index].psr_enabled; 981 982 return true; 983 } 984 985 void mod_power_psr_residency(struct mod_power *mod_power, 986 const struct dc_stream_state *stream, 987 unsigned int *residency, 988 const uint8_t mode) 989 { 990 struct core_power *core_power = NULL; 991 const struct dc_link *link = NULL; 992 993 if (!stream) 994 return; 995 996 if (mod_power == NULL) 997 return; 998 999 core_power = MOD_POWER_TO_CORE(mod_power); 1000 1001 if (core_power->num_entities == 0) 1002 return; 1003 1004 link = dc_stream_get_link(stream); 1005 1006 if (link != NULL) 1007 link->dc->link_srv->edp_get_psr_residency(link, residency, mode); 1008 } 1009 bool mod_power_psr_get_active_psr_events(struct mod_power *mod_power, 1010 const struct dc_stream_state *stream, unsigned int *active_psr_events) 1011 { 1012 struct core_power *core_power = NULL; 1013 unsigned int stream_index = 0; 1014 1015 if (!stream) 1016 return false; 1017 1018 if (mod_power == NULL) 1019 return false; 1020 1021 if (active_psr_events == NULL) 1022 return false; 1023 1024 core_power = MOD_POWER_TO_CORE(mod_power); 1025 1026 if (core_power->num_entities == 0) 1027 return false; 1028 1029 stream_index = map_index_from_stream(core_power, stream); 1030 1031 *active_psr_events = core_power->map[stream_index].psr_events; 1032 return true; 1033 } 1034 1035 bool mod_power_psr_set_sink_vtotal_in_psr_active(struct mod_power *mod_power, 1036 const struct dc_stream_state *stream, 1037 uint16_t psr_vtotal_idle, 1038 uint16_t psr_vtotal_su) 1039 { 1040 struct core_power *core_power = NULL; 1041 unsigned int stream_index = 0; 1042 const struct dc_link *link = NULL; 1043 1044 if (!stream) 1045 return false; 1046 1047 if (mod_power == NULL) 1048 return false; 1049 1050 core_power = MOD_POWER_TO_CORE(mod_power); 1051 1052 if (core_power->num_entities == 0) 1053 return false; 1054 1055 stream_index = map_index_from_stream(core_power, stream); 1056 1057 if (!core_power->map[stream_index].caps->psr_version) 1058 return false; 1059 1060 link = dc_stream_get_link(stream); 1061 1062 return link->dc->link_srv->edp_set_sink_vtotal_in_psr_active( 1063 link, psr_vtotal_idle, psr_vtotal_su); 1064 } 1065 1066 static bool mod_power_set_replay_active(struct dc_stream_state *stream, 1067 bool replay_active, 1068 bool wait, 1069 bool force_static) 1070 { 1071 uint64_t state; 1072 unsigned int retry_count; 1073 const unsigned int max_retry = 1000; 1074 struct dc_link *link = NULL; 1075 1076 if (!stream) 1077 return false; 1078 1079 link = dc_stream_get_link(stream); 1080 1081 if (!link) 1082 return false; 1083 1084 if (!dc_link_set_replay_allow_active(link, &replay_active, false, force_static, NULL)) 1085 return false; 1086 1087 if (wait == true) { 1088 1089 for (retry_count = 0; retry_count <= max_retry; retry_count++) { 1090 dc_link_get_replay_state(link, &state); 1091 if (replay_active) { 1092 if (state != REPLAY_STATE_0 && 1093 (!force_static || state == REPLAY_STATE_3)) 1094 break; 1095 } else { 1096 if (state == REPLAY_STATE_0) 1097 break; 1098 } 1099 udelay(500); 1100 } 1101 1102 /* assert if max retry hit */ 1103 if (retry_count >= max_retry) 1104 ASSERT(0); 1105 } else { 1106 /* To-do: Add trace log */ 1107 } 1108 1109 return true; 1110 } 1111 1112 static unsigned int mod_power_replay_setup_power_opt(struct dc_link *link, 1113 unsigned int active_replay_events, bool is_ultra_sleep_mode) 1114 { 1115 unsigned int power_opt = 0; 1116 1117 if (is_ultra_sleep_mode) { 1118 /* Static Screen */ 1119 power_opt |= (replay_power_opt_smu_opt_static_screen | replay_power_opt_z10_static_screen); 1120 } else if (active_replay_events & replay_event_test_harness_ultra_sleep) { 1121 power_opt |= replay_power_opt_z10_static_screen; 1122 } 1123 1124 /* replay_power_opt_flag is a configuration parameter into the module that determines 1125 * which optimizations to enable during replay 1126 */ 1127 power_opt &= link->replay_settings.config.replay_power_opt_supported; 1128 1129 return power_opt; 1130 } 1131 1132 static bool mod_power_replay_set_power_opt(struct mod_power *mod_power, 1133 struct dc_stream_state *stream, 1134 unsigned int active_replay_events, 1135 bool is_ultra_sleep_mode) 1136 { 1137 (void)mod_power; 1138 struct dc_link *link = NULL; 1139 unsigned int power_opt = 0; 1140 1141 if (!stream) 1142 return false; 1143 1144 link = dc_stream_get_link(stream); 1145 1146 if (!link || !link->replay_settings.replay_feature_enabled) 1147 return false; 1148 1149 power_opt = mod_power_replay_setup_power_opt(link, active_replay_events, is_ultra_sleep_mode); 1150 1151 if (!dc_link_set_replay_allow_active(link, NULL, false, false, &power_opt)) 1152 return false; 1153 1154 return true; 1155 } 1156 1157 bool mod_power_get_replay_event(struct mod_power *mod_power, 1158 struct dc_stream_state *stream, 1159 unsigned int *active_replay_events) 1160 { 1161 struct core_power *core_power = NULL; 1162 unsigned int stream_index = 0; 1163 1164 if (mod_power == NULL) 1165 return false; 1166 1167 core_power = MOD_POWER_TO_CORE(mod_power); 1168 1169 if (core_power->num_entities == 0) 1170 return false; 1171 1172 stream_index = map_index_from_stream(core_power, stream); 1173 1174 *active_replay_events = core_power->map[stream_index].replay_events; 1175 1176 return true; 1177 } 1178 1179 static bool mod_power_update_replay_active_status(unsigned int active_replay_events, 1180 struct dc_link *link, uint32_t *coasting_vtotal, bool *is_full_screen_video, bool *is_ultra_sleep_mode, uint16_t *frame_skip_number, bool *is_video_playback) 1181 { 1182 if (!link || !coasting_vtotal || !is_full_screen_video || !is_video_playback) 1183 return false; 1184 1185 // Check coasting_vtotal_table has been updated. 1186 if (!link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_STATIC] 1187 || !link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM]) 1188 return false; 1189 1190 unsigned int replay_enable_option = 1191 link->replay_settings.config.replay_enable_option; 1192 1193 /* TODO: To support test harness and DDS event */ 1194 1195 *coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM]; 1196 ASSERT(link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM] <= 0xFFFF); 1197 *frame_skip_number = (uint16_t)link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM]; 1198 1199 link->replay_settings.config.replay_timing_sync_supported = false; 1200 1201 *is_full_screen_video = false; 1202 1203 *is_ultra_sleep_mode = false; 1204 1205 *is_video_playback = false; 1206 1207 /* DSAT test scenario */ 1208 if (active_replay_events & replay_event_test_harness_mode) { 1209 if (link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]) 1210 *coasting_vtotal = 1211 link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]; 1212 if (link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]) { 1213 ASSERT(link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS] <= 0xFFFF); 1214 *frame_skip_number = 1215 (uint16_t)link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]; 1216 } 1217 1218 /* During the ultra sleep mode testing, disable the timing sync in short vblank mode */ 1219 if (active_replay_events & (replay_event_test_harness_enable_replay)) { 1220 if ((active_replay_events & replay_event_test_harness_ultra_sleep) && 1221 !link->replay_settings.config.replay_support_fast_resync_in_ultra_sleep_mode) 1222 link->replay_settings.config.replay_timing_sync_supported = false; 1223 return true; 1224 } else 1225 return false; 1226 } else if (active_replay_events & (replay_event_test_harness_enable_replay)) { 1227 if (link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]) 1228 *coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]; 1229 if (link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]) { 1230 uint32_t frame_skip_val = 1231 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]; 1232 1233 ASSERT(frame_skip_val <= 0xFFFF); 1234 *frame_skip_number = (uint16_t)frame_skip_val; 1235 } 1236 1237 /* During the ultra sleep mode testing, disable the timing sync in short vblank mode */ 1238 if ((active_replay_events & replay_event_test_harness_ultra_sleep) && 1239 !link->replay_settings.config.replay_support_fast_resync_in_ultra_sleep_mode) 1240 link->replay_settings.config.replay_timing_sync_supported = false; 1241 return true; 1242 } else if (active_replay_events & (replay_event_test_harness_disable_replay | replay_event_os_request_disable)) { 1243 // set last set coasting vtotal 1244 if (link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]) 1245 *coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]; 1246 if (link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]) { 1247 uint32_t frame_skip_val = 1248 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]; 1249 1250 ASSERT(frame_skip_val <= 0xFFFF); 1251 *frame_skip_number = (uint16_t)frame_skip_val; 1252 } 1253 return false; 1254 } 1255 1256 /* Inactive conditions */ 1257 if (active_replay_events & (replay_event_edp_panel_off_disable_psr | 1258 replay_event_hw_programming | 1259 replay_event_vrr | 1260 replay_event_immediate_flip | 1261 replay_event_prepare_vtotal | 1262 replay_event_vrr_transition | 1263 replay_event_pause | 1264 replay_event_disable_replay_while_DPMS | 1265 replay_event_sleep_resume | 1266 replay_event_disable_in_AC | 1267 replay_event_disable_replay_while_detect_display | 1268 replay_event_infopacket | 1269 replay_event_crc_window_active)) 1270 return false; 1271 1272 // Full screen scenario 1273 if (active_replay_events & replay_event_full_screen) { 1274 if (!(replay_enable_option & pr_enable_option_full_screen)) 1275 return false; 1276 } 1277 1278 /* Full screen video scenario */ 1279 if (active_replay_events & replay_event_big_screen_video) { 1280 1281 link->replay_settings.config.replay_timing_sync_supported = false; 1282 1283 if (replay_enable_option & pr_enable_option_full_screen_video_coasting) { 1284 unsigned int fsn_vid = 1285 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_FULL_SCREEN_VIDEO]; 1286 1287 *coasting_vtotal = 1288 link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_FULL_SCREEN_VIDEO]; 1289 ASSERT(fsn_vid <= 0xFFFF); 1290 *frame_skip_number = (uint16_t)fsn_vid; 1291 } 1292 1293 *is_video_playback = true; 1294 1295 if ((replay_enable_option & pr_enable_option_full_screen_video) && 1296 (replay_enable_option & pr_enable_option_full_screen_video_coasting)) { 1297 *is_full_screen_video = true; 1298 return true; 1299 } else 1300 return false; 1301 } 1302 1303 /* MPO video scenario 1304 * Some of the cases may contain a full screen UI layer in MPO video scenario which is 1305 * not the expected case to enable Replay. 1306 */ 1307 if ((active_replay_events & replay_event_mpo_video_selective_update) && 1308 !(active_replay_events & replay_event_full_screen)) { 1309 1310 link->replay_settings.config.replay_timing_sync_supported = false; 1311 1312 if (replay_enable_option & pr_enable_option_mpo_video_coasting) { 1313 *coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM]; 1314 { 1315 uint32_t frame_skip_val = 1316 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM]; 1317 1318 ASSERT(frame_skip_val <= 0xFFFF); 1319 *frame_skip_number = (uint16_t)frame_skip_val; 1320 } 1321 } 1322 1323 *is_video_playback = true; 1324 1325 if (replay_enable_option & pr_enable_option_mpo_video) 1326 return true; 1327 else 1328 return false; 1329 } 1330 1331 /* Static screen scenario */ 1332 if (!(active_replay_events & replay_event_vsync)) { 1333 1334 if (replay_enable_option & pr_enable_option_static_screen_coasting) { 1335 // Do not adjust eDP refresh rate if static screen + normal sleep mode 1336 if ((!(link->replay_settings.config.replay_power_opt_supported & 1337 replay_power_opt_z10_static_screen)) || 1338 (active_replay_events & replay_event_cursor_updating)) { 1339 // normal sleep mode 1340 *coasting_vtotal = 1341 link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM]; 1342 { 1343 uint32_t frame_skip_val = 1344 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM]; 1345 1346 ASSERT(frame_skip_val <= 0xFFFF); 1347 *frame_skip_number = (uint16_t)frame_skip_val; 1348 } 1349 } else { 1350 // ultra sleep mode 1351 *coasting_vtotal = 1352 link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_STATIC]; 1353 { 1354 uint32_t frame_skip_val = 1355 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_STATIC]; 1356 1357 ASSERT(frame_skip_val <= 0xFFFF); 1358 *frame_skip_number = (uint16_t)frame_skip_val; 1359 } 1360 *is_ultra_sleep_mode = true; 1361 } 1362 } 1363 1364 if (replay_enable_option & pr_enable_option_static_screen) { 1365 if (!link->replay_settings.config.replay_support_fast_resync_in_ultra_sleep_mode) 1366 link->replay_settings.config.replay_timing_sync_supported = false; 1367 return true; 1368 } else 1369 return false; 1370 } 1371 1372 /* General UI scenario */ 1373 if (active_replay_events & replay_event_general_ui) { 1374 if (replay_enable_option & pr_enable_option_general_ui) 1375 return true; 1376 else 1377 return false; 1378 } 1379 1380 return false; 1381 } 1382 1383 bool mod_power_replay_set_coasting_vtotal(struct mod_power *mod_power, 1384 const struct dc_stream_state *stream, 1385 uint32_t coasting_vtotal, 1386 uint16_t frame_skip_number) 1387 { 1388 struct core_power *core_power = NULL; 1389 struct dc_link *link = NULL; 1390 1391 if (!stream) 1392 return false; 1393 1394 link = dc_stream_get_link(stream); 1395 if (!link || !link->replay_settings.replay_feature_enabled) 1396 return false; 1397 1398 if (mod_power == NULL) 1399 return false; 1400 1401 core_power = MOD_POWER_TO_CORE(mod_power); 1402 1403 if (core_power->num_entities == 0) 1404 return false; 1405 1406 return link->dc->link_srv->edp_set_coasting_vtotal(link, coasting_vtotal, frame_skip_number); 1407 } 1408 1409 void mod_power_replay_set_timing_sync_supported(struct mod_power *mod_power, 1410 const struct dc_stream_state *stream) 1411 { 1412 struct core_power *core_power = NULL; 1413 struct dc_link *link = NULL; 1414 unsigned int stream_index = 0; 1415 union dmub_replay_cmd_set cmd_data = { 0 }; 1416 1417 if (!stream || mod_power == NULL) 1418 return; 1419 1420 core_power = MOD_POWER_TO_CORE(mod_power); 1421 if (core_power->num_entities == 0) 1422 return; 1423 1424 stream_index = map_index_from_stream(core_power, stream); 1425 if (stream_index > core_power->num_entities) //invalid index 1426 return; 1427 1428 link = dc_stream_get_link(stream); 1429 if (!link || !link->replay_settings.replay_feature_enabled) 1430 return; 1431 1432 cmd_data.sync_data.timing_sync_supported = link->replay_settings.config.replay_timing_sync_supported; 1433 1434 link->dc->link_srv->edp_send_replay_cmd(link, Replay_Set_Timing_Sync_Supported, 1435 &cmd_data); 1436 } 1437 1438 void mod_power_replay_disabled_adaptive_sync_sdp(struct mod_power *mod_power, 1439 const struct dc_stream_state *stream, bool force_disabled) 1440 { 1441 struct core_power *core_power = NULL; 1442 struct dc_link *link = NULL; 1443 unsigned int stream_index = 0; 1444 union dmub_replay_cmd_set cmd_data = { 0 }; 1445 1446 if (!stream || mod_power == NULL) 1447 return; 1448 1449 core_power = MOD_POWER_TO_CORE(mod_power); 1450 if (core_power->num_entities == 0) 1451 return; 1452 1453 stream_index = map_index_from_stream(core_power, stream); 1454 if (stream_index > core_power->num_entities) //invalid index 1455 return; 1456 1457 link = dc_stream_get_link(stream); 1458 if (!link || !link->replay_settings.replay_feature_enabled) 1459 return; 1460 1461 cmd_data.disabled_adaptive_sync_sdp_data.force_disabled = force_disabled; 1462 1463 link->dc->link_srv->edp_send_replay_cmd(link, Replay_Disabled_Adaptive_Sync_SDP, 1464 &cmd_data); 1465 } 1466 1467 static void mod_power_replay_set_general_cmd(struct mod_power *mod_power, 1468 const struct dc_stream_state *stream, 1469 const enum dmub_cmd_replay_general_subtype general_cmd_type, 1470 const uint32_t param1, const uint32_t param2) 1471 { 1472 struct core_power *core_power = NULL; 1473 struct dc_link *link = NULL; 1474 unsigned int stream_index = 0; 1475 union dmub_replay_cmd_set cmd_data = { 0 }; 1476 1477 if (!stream || mod_power == NULL) 1478 return; 1479 1480 core_power = MOD_POWER_TO_CORE(mod_power); 1481 if (core_power->num_entities == 0) 1482 return; 1483 1484 stream_index = map_index_from_stream(core_power, stream); 1485 if (stream_index > core_power->num_entities) //invalid index 1486 return; 1487 1488 link = dc_stream_get_link(stream); 1489 if (!link || !link->replay_settings.replay_feature_enabled) 1490 return; 1491 1492 cmd_data.set_general_cmd_data.subtype = general_cmd_type; 1493 cmd_data.set_general_cmd_data.param1 = param1; 1494 cmd_data.set_general_cmd_data.param2 = param2; 1495 link->dc->link_srv->edp_send_replay_cmd(link, Replay_Set_General_Cmd, 1496 &cmd_data); 1497 } 1498 1499 void mod_power_replay_disabled_desync_error_detection(struct mod_power *mod_power, 1500 const struct dc_stream_state *stream, bool force_disabled) 1501 { 1502 mod_power_replay_set_general_cmd(mod_power, stream, 1503 REPLAY_GENERAL_CMD_DISABLED_DESYNC_ERROR_DETECTION, 1504 force_disabled, 0); 1505 } 1506 1507 static void mod_power_replay_set_pseudo_vtotal(struct mod_power *mod_power, 1508 const struct dc_stream_state *stream, uint16_t vtotal) 1509 { 1510 struct core_power *core_power = NULL; 1511 struct dc_link *link = NULL; 1512 unsigned int stream_index = 0; 1513 union dmub_replay_cmd_set cmd_data = { 0 }; 1514 1515 if (!stream || mod_power == NULL) 1516 return; 1517 1518 core_power = MOD_POWER_TO_CORE(mod_power); 1519 if (core_power->num_entities == 0) 1520 return; 1521 1522 stream_index = map_index_from_stream(core_power, stream); 1523 if (stream_index > core_power->num_entities) //invalid index 1524 return; 1525 1526 link = dc_stream_get_link(stream); 1527 if (!link || !link->replay_settings.replay_feature_enabled) 1528 return; 1529 1530 cmd_data.pseudo_vtotal_data.vtotal = vtotal; 1531 1532 if (link->replay_settings.last_pseudo_vtotal != vtotal) { 1533 link->replay_settings.last_pseudo_vtotal = vtotal; 1534 link->dc->link_srv->edp_send_replay_cmd(link, Replay_Set_Pseudo_VTotal, &cmd_data); 1535 } 1536 } 1537 1538 static void mod_power_update_error_status(struct mod_power *mod_power, 1539 const struct dc_stream_state *stream) 1540 { 1541 struct dc_link *link = NULL; 1542 union replay_debug_flags *pDebug = NULL; 1543 1544 if (mod_power == NULL || stream == NULL) 1545 return; 1546 1547 link = dc_stream_get_link(stream); 1548 1549 if (!link) 1550 return; 1551 1552 pDebug = (union replay_debug_flags *)&link->replay_settings.config.debug_flags; 1553 1554 if (0 == pDebug->bitfields.enable_visual_confirm_debug) 1555 return; 1556 1557 mod_power_replay_set_general_cmd(mod_power, stream, 1558 REPLAY_GENERAL_CMD_UPDATE_ERROR_STATUS, 1559 link->replay_settings.config.replay_error_status.raw, 0); 1560 } 1561 1562 void mod_power_set_low_rr_activate(struct mod_power *mod_power, 1563 const struct dc_stream_state *stream, bool low_rr_supported) 1564 { 1565 struct dc_link *link = NULL; 1566 1567 if (mod_power == NULL || stream == NULL) 1568 return; 1569 1570 link = dc_stream_get_link(stream); 1571 1572 if (!link) 1573 return; 1574 1575 mod_power_replay_set_general_cmd(mod_power, stream, 1576 REPLAY_GENERAL_CMD_SET_LOW_RR_ACTIVATE, 1577 low_rr_supported, 0); 1578 } 1579 1580 void mod_power_set_video_conferencing_activate(struct mod_power *mod_power, 1581 const struct dc_stream_state *stream, bool video_conferencing_activate) 1582 { 1583 struct dc_link *link = NULL; 1584 1585 if (mod_power == NULL || stream == NULL) 1586 return; 1587 1588 link = dc_stream_get_link(stream); 1589 if (!link || !link->replay_settings.replay_feature_enabled) 1590 return; 1591 1592 mod_power_replay_set_general_cmd(mod_power, stream, 1593 REPLAY_GENERAL_CMD_VIDEO_CONFERENCING, 1594 video_conferencing_activate, 0); 1595 } 1596 1597 void mod_power_set_coasting_vtotal_without_frame_update(struct mod_power *mod_power, 1598 const struct dc_stream_state *stream, uint32_t coasting_vtotal) 1599 { 1600 struct dc_link *link = NULL; 1601 1602 if (mod_power == NULL || stream == NULL) 1603 return; 1604 1605 link = dc_stream_get_link(stream); 1606 if (!link || !link->replay_settings.replay_feature_enabled) 1607 return; 1608 1609 mod_power_replay_set_general_cmd(mod_power, stream, 1610 REPLAY_GENERAL_CMD_SET_COASTING_VTOTAL_WITHOUT_FRAME_UPDATE, 1611 coasting_vtotal, 0); 1612 } 1613 1614 void mod_power_set_replay_continuously_resync(struct mod_power *mod_power, 1615 const struct dc_stream_state *stream, bool enable) 1616 { 1617 struct dc_link *link = NULL; 1618 1619 if (mod_power == NULL || stream == NULL) 1620 return; 1621 1622 link = dc_stream_get_link(stream); 1623 if (!link || !link->replay_settings.replay_feature_enabled) 1624 return; 1625 1626 mod_power_replay_set_general_cmd(mod_power, stream, 1627 REPLAY_GENERAL_CMD_SET_CONTINUOUSLY_RESYNC, 1628 enable, 0); 1629 } 1630 1631 void mod_power_set_live_capture_with_cvt_activate(struct mod_power *mod_power, 1632 const struct dc_stream_state *stream, bool live_capture_with_cvt_activate) 1633 { 1634 struct dc_link *link = NULL; 1635 1636 if (mod_power == NULL || stream == NULL) 1637 return; 1638 1639 link = dc_stream_get_link(stream); 1640 if (!link || !link->replay_settings.replay_feature_enabled) 1641 return; 1642 1643 // Check if LIVE_CAPTURE_WITH_CVT bit is enabled in DalRegKey_ReplayOptimization 1644 if (!link->replay_settings.config.replay_optimization.bits.LIVE_CAPTURE_WITH_CVT) 1645 return; 1646 1647 if (link->replay_settings.config.live_capture_with_cvt_activated != live_capture_with_cvt_activate) { 1648 link->replay_settings.config.live_capture_with_cvt_activated = live_capture_with_cvt_activate; 1649 mod_power_replay_set_general_cmd(mod_power, stream, 1650 REPLAY_GENERAL_CMD_LIVE_CAPTURE_WITH_CVT, 1651 live_capture_with_cvt_activate, 0); 1652 } 1653 } 1654 1655 bool mod_power_set_replay_event(struct mod_power *mod_power, 1656 struct dc_stream_state *stream, bool set_event, 1657 enum replay_event event, bool wait_for_disable) 1658 { 1659 struct core_power *core_power = NULL; 1660 struct dc_link *link = NULL; 1661 unsigned int stream_index = 0; 1662 unsigned int active_replay_events = 0; 1663 bool replay_active_request = false; 1664 bool force_static = false; 1665 uint32_t coasting_vtotal = 0; 1666 bool current_timing_sync_status = false; 1667 bool is_full_screen_video = false; 1668 bool is_ultra_sleep_mode = false; 1669 unsigned int sink_duration_us = 0; 1670 bool low_rr_active = false; 1671 uint16_t frame_skip_number = 0; 1672 bool is_video_playback = false; 1673 1674 if (!stream) 1675 return false; 1676 1677 if (mod_power == NULL) 1678 return false; 1679 1680 core_power = MOD_POWER_TO_CORE(mod_power); 1681 1682 if (core_power->num_entities == 0) 1683 return false; 1684 1685 stream_index = map_index_from_stream(core_power, stream); 1686 1687 if (set_event) 1688 core_power->map[stream_index].replay_events |= event; 1689 else 1690 core_power->map[stream_index].replay_events &= ~event; 1691 1692 link = dc_stream_get_link(stream); 1693 if (!link || !link->replay_settings.replay_feature_enabled) 1694 return false; 1695 1696 if ((core_power->map[stream_index].replay_events & replay_event_disable_replay_while_switching_mux) != 0) 1697 return false; 1698 1699 if ((core_power->map[stream_index].replay_events & replay_event_os_override_hold) != 0) 1700 return false; 1701 1702 active_replay_events = core_power->map[stream_index].replay_events; 1703 1704 current_timing_sync_status = 1705 link->replay_settings.config.replay_timing_sync_supported; 1706 1707 replay_active_request = mod_power_update_replay_active_status(active_replay_events, 1708 link, &coasting_vtotal, &is_full_screen_video, &is_ultra_sleep_mode, &frame_skip_number, &is_video_playback); 1709 1710 if (is_full_screen_video) 1711 mod_power_replay_set_pseudo_vtotal(mod_power, stream, 1712 link->replay_settings.low_rr_full_screen_video_pseudo_vtotal); 1713 else 1714 mod_power_replay_set_pseudo_vtotal(mod_power, stream, 0); 1715 1716 //If timing_sync_status change, then re-enabled set timing_sync_supported value and re-enabled replay 1717 if (current_timing_sync_status != link->replay_settings.config.replay_timing_sync_supported) 1718 mod_power_replay_set_timing_sync_supported(mod_power, stream); 1719 1720 if (link->replay_settings.config.low_rr_supported) { 1721 sink_duration_us = 1722 (unsigned int)(div_u64(((unsigned long long)(coasting_vtotal) 1723 * 10000) * stream->timing.h_total, 1724 stream->timing.pix_clk_100hz)); 1725 low_rr_active = sink_duration_us < LOW_REFRESH_RATE_DURATION_US_UPPER_BOUND ? false : true; 1726 if (low_rr_active != link->replay_settings.config.low_rr_activated) { 1727 mod_power_set_low_rr_activate(mod_power, stream, low_rr_active); 1728 link->replay_settings.config.low_rr_activated = low_rr_active; 1729 } 1730 } 1731 1732 // The function return fail when 1733 // 1. DMUB function is not support (for backward compatible). 1734 // 2. active_replay_events or coasting_vtotal is not updated in the same time 1735 if (!mod_power_replay_set_power_opt_and_coasting_vtotal(mod_power, 1736 stream, active_replay_events, coasting_vtotal, is_ultra_sleep_mode, frame_skip_number)) { 1737 if (!mod_power_replay_set_power_opt(mod_power, stream, active_replay_events, is_ultra_sleep_mode)) 1738 return false; 1739 1740 if (!mod_power_replay_set_coasting_vtotal(mod_power, stream, coasting_vtotal, frame_skip_number)) 1741 return false; 1742 } 1743 1744 mod_power_set_live_capture_with_cvt_activate(mod_power, stream, is_video_playback); 1745 1746 mod_power_update_error_status(mod_power, stream); 1747 1748 // If Replay is going to be enable (No matter is disable -> enable or enable -> enable), we don't need to wait. 1749 // If Replay is going to be disable 1750 // if disable -> disable 1751 // -> Replay DMUB state should be state 0. 1752 // So no matter wait_for_disable is true or not, it should makes no difference. 1753 // if enable -> disable -> We should wait if wait_for_disable is true. 1754 if (replay_active_request) 1755 wait_for_disable = false; 1756 1757 if (!mod_power_set_replay_active(stream, replay_active_request, wait_for_disable, force_static)) 1758 return false; 1759 1760 return true; 1761 } 1762 1763 bool mod_power_get_replay_active_status(const struct dc_stream_state *stream, 1764 bool *replay_active) 1765 { 1766 const struct dc_link *link = NULL; 1767 1768 if (!stream) 1769 return false; 1770 1771 link = dc_stream_get_link(stream); 1772 *replay_active = link->replay_settings.replay_allow_active; 1773 1774 return true; 1775 } 1776 1777 void mod_power_replay_residency(const struct dc_stream_state *stream, 1778 unsigned int *residency, const bool is_start, const bool is_alpm) 1779 { 1780 const struct dc_link *link = NULL; 1781 enum pr_residency_mode mode; 1782 1783 if (!stream) 1784 return; 1785 1786 link = dc_stream_get_link(stream); 1787 1788 if (is_alpm) 1789 mode = PR_RESIDENCY_MODE_ALPM; 1790 else 1791 mode = PR_RESIDENCY_MODE_PHY; 1792 1793 if (link && link->dc && link->dc->link_srv) 1794 link->dc->link_srv->edp_replay_residency(link, residency, is_start, mode); 1795 } 1796 1797 bool mod_power_replay_set_power_opt_and_coasting_vtotal(struct mod_power *mod_power, 1798 const struct dc_stream_state *stream, unsigned int active_replay_events, uint32_t coasting_vtotal, 1799 bool is_ultra_sleep_mode, uint16_t frame_skip_number) 1800 { 1801 struct core_power *core_power = NULL; 1802 struct dc_link *link = NULL; 1803 unsigned int power_opt = 0; 1804 1805 if (!stream) 1806 return false; 1807 1808 if (mod_power == NULL) 1809 return false; 1810 1811 core_power = MOD_POWER_TO_CORE(mod_power); 1812 1813 if (core_power->num_entities == 0) 1814 return false; 1815 1816 link = dc_stream_get_link(stream); 1817 1818 if (!link || !link->replay_settings.replay_feature_enabled) 1819 return false; 1820 1821 power_opt = mod_power_replay_setup_power_opt(link, active_replay_events, is_ultra_sleep_mode); 1822 1823 return link->dc->link_srv->edp_set_replay_power_opt_and_coasting_vtotal(link, &power_opt, coasting_vtotal, frame_skip_number); 1824 } 1825 1826 1827 1828 1829 1830