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 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 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, 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 static uint16_t backlight_8_to_16(unsigned int backlight_8bit) 203 { 204 return (uint16_t)(backlight_8bit * 0x101); 205 } 206 207 208 static unsigned int backlight_millipercent_to_millinit( 209 struct core_power *core_power, unsigned int millipercent, unsigned int inst) 210 { 211 unsigned int millinit = 0; 212 unsigned long long numerator = 0; 213 214 if (core_power == NULL) 215 return 0; 216 217 numerator = ((unsigned long long)millipercent) * 218 core_power->bl_prop[inst].nits_range; 219 millinit = ((unsigned int)div_u64(numerator, 100000)) + 220 core_power->bl_prop[inst].min_brightness_millinits; 221 222 return millinit; 223 } 224 225 static unsigned int backlight_millinit_to_millipercent( 226 struct core_power *core_power, unsigned int millinit, unsigned int inst) 227 { 228 unsigned int millipercent = 0; 229 unsigned long long numerator = 0; 230 231 if (core_power == NULL) 232 return 0; 233 234 if (millinit <= core_power->bl_prop[inst].min_brightness_millinits) 235 return 0; 236 237 if (millinit >= core_power->bl_prop[inst].max_brightness_millinits) 238 return (100 * 1000); 239 240 numerator = (((unsigned long long)millinit) - 241 core_power->bl_prop[inst].min_brightness_millinits) * 100000; 242 millipercent = ((unsigned int)div_u64(numerator, 243 core_power->bl_prop[inst].nits_range)); 244 245 return millipercent; 246 } 247 248 static unsigned int backlight_pwm_to_millipercent( 249 struct core_power *core_power, unsigned int pwm, unsigned int inst) 250 { 251 unsigned int millipercent = 0; 252 unsigned int max_index = 0; 253 254 if (core_power == NULL) 255 return 0; 256 257 if (!core_power->bl_prop[inst].backlight_caps_valid) 258 return 0; 259 260 /* Doesn't really make sense to have one single backlight level 261 * possible... 262 */ 263 if (core_power->bl_prop[inst].num_backlight_levels < 2) 264 return 0; 265 266 max_index = core_power->bl_prop[inst].num_backlight_levels - 1; 267 268 if (pwm <= core_power->bl_prop[inst].backlight_lut[0]) 269 return 0; 270 271 if (pwm > core_power->bl_prop[inst].backlight_lut[max_index]) 272 return (100 * 1000); 273 274 /* We need to do a binary search over the array for where the pwm level 275 * is in the lut. Based on the index we can determine percentage. 276 */ 277 unsigned int min = 0; 278 unsigned int max = max_index; 279 unsigned int mid = 0; 280 281 while (max >= min) { 282 mid = (min + max) / 2; /* floor of half range */ 283 284 if (core_power->bl_prop[inst].backlight_lut[mid] < pwm) 285 min = mid + 1; 286 else if (core_power->bl_prop[inst].backlight_lut[mid] > pwm) 287 max = mid - 1; 288 else 289 break; 290 } 291 292 /* In this case, exact match is not found. Check if mid/min/max 293 * value is actually closer. 294 */ 295 if (max < min) { 296 unsigned int min_delta; 297 unsigned int mid_delta; 298 unsigned int max_delta; 299 300 min_delta = (core_power->bl_prop[inst].backlight_lut[min] > pwm) ? 301 core_power->bl_prop[inst].backlight_lut[min] - pwm : 302 pwm - core_power->bl_prop[inst].backlight_lut[min]; 303 304 mid_delta = (core_power->bl_prop[inst].backlight_lut[mid] > pwm) ? 305 core_power->bl_prop[inst].backlight_lut[mid] - pwm : 306 pwm - core_power->bl_prop[inst].backlight_lut[mid]; 307 308 max_delta = (core_power->bl_prop[inst].backlight_lut[max] > pwm) ? 309 core_power->bl_prop[inst].backlight_lut[max] - pwm : 310 pwm - core_power->bl_prop[inst].backlight_lut[max]; 311 312 if ((min_delta < mid_delta) && (min_delta < max_delta)) 313 mid = min; 314 315 if ((max_delta < mid_delta) && (max_delta < min_delta)) 316 mid = max; 317 } 318 319 /* No interpolation, just take closest index */ 320 millipercent = 1000 * 100 * mid / max_index; 321 322 return millipercent; 323 } 324 325 static unsigned int backlight_pwm_to_millinit( 326 struct core_power *core_power, unsigned int pwm, unsigned int inst) 327 { 328 unsigned int millinit = 0; 329 330 if (core_power == NULL) 331 return 0; 332 333 if (pwm <= core_power->bl_prop[inst].min_backlight_pwm) 334 return core_power->bl_prop[inst].min_brightness_millinits; 335 336 if (pwm >= core_power->bl_prop[inst].max_backlight_pwm) 337 return core_power->bl_prop[inst].max_brightness_millinits; 338 339 millinit = ((unsigned int)div_u64(((unsigned long long)pwm - 340 core_power->bl_prop[inst].min_backlight_pwm) * 341 core_power->bl_prop[inst].nits_range, 342 core_power->bl_prop[inst].backlight_range)); 343 344 millinit += core_power->bl_prop[inst].min_brightness_millinits; 345 346 if (millinit > core_power->bl_prop[inst].max_brightness_millinits) 347 millinit = core_power->bl_prop[inst].max_brightness_millinits; 348 349 return millinit; 350 } 351 352 static unsigned int backlight_millipercent_to_pwm( 353 struct core_power *core_power, unsigned int millipercent, unsigned int inst) 354 { 355 unsigned int pwm = (unsigned int)-1; 356 unsigned int index = 0; 357 358 if (core_power == NULL) 359 return 0; 360 361 // Bypass the brightness mapping LUT 362 if (core_power->bl_prop->use_linear_backlight_curve) { 363 pwm = core_power->bl_prop[inst].min_backlight_pwm + 364 (unsigned int) div_u64((unsigned long long) millipercent * 365 core_power->bl_prop[inst].backlight_range, 366 100000); 367 368 if (pwm > core_power->bl_prop[inst].max_backlight_pwm) 369 pwm = core_power->bl_prop[inst].max_backlight_pwm; 370 371 return pwm; 372 } 373 374 if (millipercent >= (100 * 1000)) 375 return core_power->bl_prop[inst].backlight_lut[core_power->bl_prop[inst].num_backlight_levels - 1]; 376 377 /* This will give the floor index. */ 378 index = ((core_power->bl_prop[inst].num_backlight_levels - 1) * 379 millipercent) / 100000; 380 /* Null check otherwise eDP doesn't lightup when connected to DP1 */ 381 if (core_power->bl_prop[inst].backlight_lut == NULL) 382 return pwm; 383 384 pwm = core_power->bl_prop[inst].backlight_lut[index]; 385 386 return pwm; 387 } 388 389 static unsigned int backlight_millinit_to_pwm( 390 struct core_power *core_power, unsigned int millinit, unsigned int inst) 391 { 392 unsigned int pwm = 0; 393 394 if (core_power == NULL) 395 return 0; 396 397 /* For nits based brightness, the signal will be a value 398 * between the minimum and maximum value. 399 */ 400 if (millinit >= core_power->bl_prop[inst].max_brightness_millinits) 401 return core_power->bl_prop[inst].max_backlight_pwm; 402 else if (millinit <= core_power->bl_prop[inst].min_brightness_millinits) 403 return core_power->bl_prop[inst].min_backlight_pwm; 404 405 pwm = ((unsigned int)div_u64(((unsigned long long)millinit - 406 core_power->bl_prop[inst].min_brightness_millinits) * 407 core_power->bl_prop[inst].backlight_range, 408 core_power->bl_prop[inst].nits_range)); 409 410 pwm += core_power->bl_prop[inst].min_backlight_pwm; 411 412 if (pwm > core_power->bl_prop[inst].max_backlight_pwm) 413 pwm = core_power->bl_prop[inst].max_backlight_pwm; 414 415 return pwm; 416 } 417 418 static bool validate_ext_backlight_caps( 419 struct dm_acpi_atif_backlight_caps *ext_backlight_caps) 420 { 421 unsigned int i; 422 unsigned int num_of_data_points = 0; 423 unsigned int last_signal_level = 0; 424 unsigned int last_luminance = 0; 425 426 num_of_data_points = ext_backlight_caps->num_data_points; 427 428 /* Validation rules: 429 * 1. BIOS should carry customized data points and 430 * the number of data points should not be larger than 99. 431 * 2. The max_input_signal should be larger than min_input_signal. 432 * 3. For each data point: 433 * a. luminance should be in ascending order and 434 * should not be 0 or 100 since the corresponding signal_level 435 * are assigned by min_input_signal and max_input_signal. 436 * b. signal_level should be in ascending order and 437 * be within the range of min/max_input_signal. 438 */ 439 if (num_of_data_points > BL_DATA_POINTS) 440 return false; 441 442 if (ext_backlight_caps->min_input_signal >= ext_backlight_caps->max_input_signal) 443 return false; 444 445 last_signal_level = ext_backlight_caps->min_input_signal; 446 for (i = 0; i < num_of_data_points; i++) { 447 unsigned int luminance = ext_backlight_caps->data_points[i].luminance; 448 unsigned int signal_level = ext_backlight_caps->data_points[i].signal_level; 449 450 if ((luminance <= last_luminance) || (luminance > BL_DATA_POINTS)) 451 return false; 452 453 if ((signal_level <= last_signal_level) || (signal_level >= ext_backlight_caps->max_input_signal)) 454 return false; 455 456 last_signal_level = signal_level; 457 last_luminance = luminance; 458 } 459 460 return true; 461 } 462 463 /* hard coded to default backlight curve. */ 464 static void initialize_backlight_caps(struct core_power *core_power, unsigned int inst) 465 { 466 unsigned int i; 467 struct dm_acpi_atif_backlight_caps *ext_backlight_caps = NULL; 468 bool custom_curve_present = false; 469 unsigned int num_levels = 0; 470 struct dc *dc = NULL; 471 enum dm_acpi_display_type acpi_display_type = 472 (inst == 0) ? AcpiDisplayType_LCD1 : AcpiDisplayType_LCD2; 473 474 if (core_power == NULL) 475 return; 476 dc = core_power->dc; 477 478 num_levels = core_power->bl_prop[inst].num_backlight_levels; 479 480 /* Allocate memory for ATIF output 481 * (do not want to use 256 bytes on the stack) 482 */ 483 ext_backlight_caps = (struct dm_acpi_atif_backlight_caps *) 484 (kzalloc(sizeof(struct dm_acpi_atif_backlight_caps), 485 GFP_KERNEL)); 486 487 if (ext_backlight_caps == NULL) 488 return; 489 490 /* Retrieve ACPI extended brightness caps */ 491 if (dm_query_extended_brightness_caps 492 (dc->ctx, acpi_display_type, ext_backlight_caps)) { 493 custom_curve_present = validate_ext_backlight_caps(ext_backlight_caps); 494 } 495 496 if (core_power->bl_prop[inst].use_custom_backlight_caps && 497 fill_custom_backlight_caps( 498 core_power->bl_prop[inst].custom_backlight_caps_config_no, 499 ext_backlight_caps)) { 500 custom_curve_present = validate_ext_backlight_caps(ext_backlight_caps); 501 } 502 503 if (custom_curve_present) { 504 unsigned int index = 1; 505 unsigned int num_of_data_points = ext_backlight_caps->num_data_points; 506 507 core_power->bl_prop[inst].ac_backlight_percent = 508 ext_backlight_caps->ac_level_percentage; 509 core_power->bl_prop[inst].dc_backlight_percent = 510 ext_backlight_caps->dc_level_percentage; 511 core_power->bl_prop[inst].backlight_lut[0] = 512 backlight_8_to_16( 513 ext_backlight_caps->min_input_signal); 514 core_power->bl_prop[inst].backlight_lut[num_levels - 1] = 515 backlight_8_to_16( 516 ext_backlight_caps->max_input_signal); 517 518 /* Filling translation table from data points - 519 * between every two provided data points we 520 * lineary interpolate missing values 521 */ 522 for (i = 0; i < num_of_data_points; i++) { 523 unsigned int luminance = 524 ext_backlight_caps->data_points[i].luminance; 525 unsigned int signal_level = 526 backlight_8_to_16( 527 ext_backlight_caps->data_points[i].signal_level); 528 529 /* Since luminance is a percentage, scale it by num_levels*/ 530 luminance = (luminance * num_levels) / 101; 531 532 /* Lineary interpolate missing values */ 533 if (index < luminance) { 534 unsigned int base_value = 535 core_power->bl_prop[inst].backlight_lut[index-1]; 536 unsigned int delta_signal = 537 signal_level - base_value; 538 unsigned int delta_luma = 539 luminance - index + 1; 540 unsigned int step = delta_signal; 541 542 for (; index < luminance; index++) { 543 core_power->bl_prop[inst].backlight_lut[index] = 544 base_value + (step / delta_luma); 545 step += delta_signal; 546 } 547 } 548 549 /* Now [index == luminance], 550 * so we can add data point to the translation table 551 */ 552 core_power->bl_prop[inst].backlight_lut[index++] = signal_level; 553 } 554 555 /* Complete the final segment of interpolation - 556 * between last datapoint and maximum value 557 */ 558 if (index < num_levels - 1) { 559 unsigned int base_value = 560 core_power->bl_prop[inst].backlight_lut[index-1]; 561 unsigned int delta_signal = 562 core_power->bl_prop[inst].backlight_lut[num_levels - 1] - 563 base_value; 564 unsigned int delta_luma = num_levels - index; 565 unsigned int step = delta_signal; 566 567 for (; index < num_levels - 1; index++) { 568 core_power->bl_prop[inst].backlight_lut[index] = 569 base_value + (step / delta_luma); 570 step += delta_signal; 571 } 572 } 573 /* Build backlight translation table based on default curve */ 574 } else { 575 /* Defines default backlight curve F(x) = A(x*x) + Bx + C. 576 * 577 * Backlight curve should always satisfy: 578 * F(0) = min, F(100) = max, 579 * So polynom coefficients are: 580 * A is 0.0255 - B/100 - min/10000 - (255-max)/10000 = 581 * (max - min)/10000 - B/100 582 * B is adjustable factor to modify the curve. 583 * Bigger B results in less concave curve. 584 * B range is [0..(max-min)/100] 585 * C is backlight minimum 586 */ 587 unsigned int backlight_curve_coeff_a_factor = 588 num_levels * num_levels; 589 unsigned int backlight_curve_coeff_b = num_levels; 590 unsigned int delta = 591 core_power->bl_prop[inst].backlight_lut[num_levels - 1] - 592 core_power->bl_prop[inst].backlight_lut[0]; 593 unsigned int coeffC = core_power->bl_prop[inst].backlight_lut[0]; 594 unsigned int coeffB = 595 (backlight_curve_coeff_b < delta ? 596 backlight_curve_coeff_b : delta); 597 unsigned long long coeffA = delta - coeffB; /* coeffB is B*100 */ 598 599 for (i = 1; i < num_levels - 1; i++) { 600 uint64_t lut_val = div_u64(coeffA * i * i, backlight_curve_coeff_a_factor) + 601 div_u64((uint64_t)coeffB * i, backlight_curve_coeff_b) + coeffC; 602 603 ASSERT(lut_val <= 0xFFFFFFFF); 604 core_power->bl_prop[inst].backlight_lut[i] = (unsigned int)lut_val; 605 } 606 } 607 608 if (ext_backlight_caps != NULL) 609 kfree(ext_backlight_caps); 610 611 /* Successfully initialized */ 612 core_power->bl_prop[inst].backlight_caps_valid = true; 613 } 614 615 static void varibright_set_level(struct core_power *core_power) 616 { 617 if (!core_power->varibright_prop.varibright_active || 618 !core_power->varibright_prop.varibright_user_enable) 619 core_power->varibright_prop.varibright_hw_level = 0; 620 else 621 core_power->varibright_prop.varibright_hw_level = 622 core_power->varibright_prop.varibright_level; 623 } 624 625 bool mod_power_hw_init(struct mod_power *mod_power) 626 { 627 struct core_power *core_power = NULL; 628 struct dc *dc = NULL; 629 struct dmcu *dmcu = NULL; 630 struct dmcu_iram_parameters params; 631 int i; 632 633 if (mod_power == NULL) 634 return false; 635 636 core_power = MOD_POWER_TO_CORE(mod_power); 637 dc = core_power->dc; 638 639 for (i = 0; i < core_power->edp_num; i++) { 640 params.set = core_power->varibright_prop.varibright_config_setting; 641 params.backlight_ramping_override = core_power->bl_prop[i].backlight_ramping_override; 642 params.backlight_ramping_reduction = core_power->bl_prop[i].backlight_ramping_reduction; 643 params.backlight_ramping_start = core_power->bl_prop[i].backlight_ramping_start; 644 params.backlight_lut_array = core_power->bl_prop[i].backlight_lut; 645 params.backlight_lut_array_size = core_power->bl_prop[i].num_backlight_levels; 646 params.min_abm_backlight = core_power->bl_prop[i].min_abm_backlight; 647 648 dmcu = dc->res_pool->dmcu; 649 650 // In the case where abm is implemented on dmcub, 651 // dmcu object will be null. 652 // ABM 2.4 and up are implemented on dmcub. 653 if (dmcu) { 654 //DMCU does not support multiple eDP 655 return dmcu_load_iram(dmcu, params); 656 } else if (dc->ctx->dmub_srv) { 657 if (!dmub_init_abm_config(dc->res_pool, params, i)) 658 return false; 659 } else 660 return false; 661 } 662 return true; 663 } 664 665 struct mod_power *mod_power_create(struct dc *dc, 666 struct mod_power_init_params *init_params, 667 unsigned int edp_num) 668 { 669 struct core_power *core_power = NULL; 670 int i = 0; 671 int abm_max_config = 0; 672 unsigned int inst = 0; 673 bool is_brightness_range_valid = false; 674 675 if (dc == NULL) 676 goto fail_dc_null; 677 678 core_power = kzalloc(sizeof(struct core_power), GFP_KERNEL); 679 680 if (core_power == NULL) 681 goto fail_alloc_context; 682 683 core_power->edp_num = edp_num; 684 core_power->map = kzalloc(sizeof(struct power_entity) * MOD_POWER_MAX_CONCURRENT_STREAMS, 685 GFP_KERNEL); 686 687 if (core_power->map == NULL) 688 goto fail_alloc_map; 689 690 for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) { 691 core_power->map[i].stream = NULL; 692 } 693 694 for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) { 695 core_power->map[i].psr_context = 696 kzalloc(sizeof(struct mod_power_psr_context), 697 GFP_KERNEL); 698 if (core_power->map[i].psr_context == NULL) 699 goto fail_construct; 700 } 701 702 core_power->psr_smu_optimizations_support = init_params->allow_psr_smu_optimizations; 703 core_power->multi_disp_optimizations_support = init_params->allow_psr_multi_disp_optimizations; 704 705 for (inst = 0; inst < edp_num; inst++) { 706 core_power->bl_prop[inst].min_abm_backlight = 707 init_params[inst].min_abm_backlight; 708 core_power->bl_prop[inst].disable_fractional_pwm = 709 init_params[inst].disable_fractional_pwm; 710 core_power->bl_prop[inst].use_linear_backlight_curve = 711 init_params[inst].use_linear_backlight_curve; 712 core_power->bl_prop[inst].use_nits_based_brightness = 713 init_params[inst].use_nits_based_brightness; 714 core_power->bl_prop[inst].backlight_ramping_override = 715 init_params[inst].backlight_ramping_override; 716 core_power->bl_prop[inst].backlight_ramping_reduction = 717 init_params[inst].backlight_ramping_reduction; 718 core_power->bl_prop[inst].backlight_ramping_start = 719 init_params[inst].backlight_ramping_start; 720 core_power->bl_prop[inst].use_custom_backlight_caps = 721 init_params[inst].use_custom_backlight_caps; 722 core_power->bl_prop[inst].custom_backlight_caps_config_no = 723 init_params[inst].custom_backlight_caps_config_no; 724 725 // Do not allow less than 101 backlight levels 726 if (init_params[inst].num_backlight_levels < 101) 727 core_power->bl_prop[inst].num_backlight_levels = 101; 728 else 729 core_power->bl_prop[inst].num_backlight_levels = 730 init_params[inst].num_backlight_levels; 731 732 core_power->bl_prop[inst].backlight_lut = (unsigned int *) 733 (kzalloc(sizeof(unsigned int) * 734 core_power->bl_prop[inst].num_backlight_levels, GFP_KERNEL)); 735 if (core_power->bl_prop[inst].backlight_lut == NULL) 736 goto fail_alloc_backlight_array; 737 } 738 739 core_power->varibright_prop.varibright_active = false; 740 741 core_power->varibright_prop.varibright_user_enable = 742 init_params->def_varibright_enable; 743 744 // Table of ABM levels here is 1-4, but level 0 also exists as 'off' 745 if (init_params->varibright_level <= abm_defines_max_level) { 746 core_power->varibright_prop.varibright_level = 747 init_params->varibright_level; 748 749 } else { 750 core_power->varibright_prop.varibright_level = 3; 751 } 752 if (init_params->def_varibright_level <= abm_defines_max_level) { 753 core_power->varibright_prop.def_varibright_level = 754 init_params->def_varibright_level; 755 } else { 756 core_power->varibright_prop.def_varibright_level = 3; 757 } 758 759 // ABM used to contain 4 different configs. There is only 3 since ABM 2.3. 760 if ((dc->res_pool->dmcu != NULL) && (dc->res_pool->dmcu->dmcu_version.abm_version < 0x23)) 761 abm_max_config = 4; 762 else 763 abm_max_config = 3; 764 765 if (init_params->abm_config_setting < abm_max_config) 766 core_power->varibright_prop.varibright_config_setting = 767 init_params->abm_config_setting; 768 else 769 core_power->varibright_prop.varibright_config_setting = 0; 770 771 for (inst = 0; inst < edp_num; inst++) { 772 core_power->bl_prop[inst].backlight_lut[0] = init_params[inst].min_backlight_pwm; 773 core_power->bl_prop[inst].backlight_lut[ 774 core_power->bl_prop[inst].num_backlight_levels-1] = 775 init_params[inst].max_backlight_pwm; 776 core_power->bl_prop[inst].min_backlight_pwm = init_params[inst].min_backlight_pwm; 777 core_power->bl_prop[inst].max_backlight_pwm = init_params[inst].max_backlight_pwm; 778 core_power->bl_prop[inst].ac_backlight_percent = 779 default_ac_backlight_percent; 780 core_power->bl_prop[inst].dc_backlight_percent = 781 default_dc_backlight_percent; 782 core_power->bl_prop[inst].backlight_caps_valid = false; 783 784 if (core_power->bl_prop[inst].use_nits_based_brightness) { 785 core_power->bl_prop[inst].min_brightness_millinits = 786 init_params[inst].panel_min_millinits; 787 core_power->bl_prop[inst].max_brightness_millinits = 788 init_params[inst].panel_max_millinits; 789 } else { 790 791 core_power->bl_prop[inst].min_brightness_millinits = 792 pwr_default_min_brightness_millinits; 793 core_power->bl_prop[inst].max_brightness_millinits = 794 pwr_default_sdr_brightness_millinits; 795 } 796 797 core_power->bl_prop[inst].backlight_range = 798 core_power->bl_prop[inst].max_backlight_pwm- 799 core_power->bl_prop[inst].min_backlight_pwm; 800 801 core_power->bl_prop[inst].nits_range = 802 core_power->bl_prop[inst].max_brightness_millinits - 803 core_power->bl_prop[inst].min_brightness_millinits; 804 805 core_power->bl_state[inst].smooth_brightness_enabled = true; 806 } 807 808 /* Check if at least 1 instance in core_power is populated before failing */ 809 for (inst = 0; inst < edp_num; inst++) { 810 if (core_power->bl_prop[inst].nits_range != 0 && core_power->bl_prop[inst].backlight_range != 0) { 811 is_brightness_range_valid = true; 812 break; 813 } 814 815 } 816 if (!is_brightness_range_valid) 817 goto fail_bad_brightness_range; 818 819 core_power->num_entities = 0; 820 821 core_power->dc = dc; 822 for (inst = 0; inst < edp_num; inst++) { 823 initialize_backlight_caps(core_power, inst); 824 core_power->bl_state[inst].backlight_millipercent = 825 core_power->bl_prop[inst].dc_backlight_percent * 1000; 826 core_power->bl_state[inst].backlight_pwm = backlight_millipercent_to_pwm(core_power, 827 core_power->bl_state[inst].backlight_millipercent, inst); 828 core_power->bl_state[inst].backlight_millinit = backlight_millipercent_to_millinit(core_power, 829 core_power->bl_state[inst].backlight_millipercent, inst); 830 } 831 832 return &core_power->public; 833 834 fail_bad_brightness_range: 835 fail_alloc_backlight_array: 836 for (inst = 0; inst < edp_num; inst++) 837 if (core_power->bl_prop[inst].backlight_lut) 838 kfree(core_power->bl_prop[inst].backlight_lut); 839 fail_construct: 840 for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) { 841 if (core_power->map[i].psr_context) 842 kfree(core_power->map[i].psr_context); 843 } 844 kfree(core_power->map); 845 846 fail_alloc_map: 847 kfree(core_power); 848 849 fail_alloc_context: 850 fail_dc_null: 851 return NULL; 852 } 853 854 void mod_power_destroy(struct mod_power *mod_power) 855 { 856 if (mod_power != NULL) { 857 int i; 858 struct core_power *core_power = 859 MOD_POWER_TO_CORE(mod_power); 860 861 for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) 862 if (core_power->map[i].psr_context) 863 kfree(core_power->map[i].psr_context); 864 865 for (i = 0; i < core_power->num_entities; i++) 866 if (core_power->map[i].stream) 867 dc_stream_release(core_power->map[i].stream); 868 869 kfree(core_power->map); 870 871 for (i = 0; i < MAX_NUM_EDP; i++) 872 if (core_power->bl_prop[i].backlight_lut) 873 kfree(core_power->bl_prop[i].backlight_lut); 874 875 kfree(core_power); 876 } 877 } 878 879 bool mod_power_add_stream(struct mod_power *mod_power, 880 struct dc_stream_state *stream, struct psr_caps *caps) 881 { 882 struct core_power *core_power = NULL; 883 884 if (mod_power == NULL) 885 return false; 886 887 core_power = MOD_POWER_TO_CORE(mod_power); 888 889 if (core_power->num_entities < MOD_POWER_MAX_CONCURRENT_STREAMS) { 890 dc_stream_retain(stream); 891 892 core_power->map[core_power->num_entities].stream = stream; 893 core_power->map[core_power->num_entities].caps = caps; 894 895 // initialize cached PSR params to something "safe" (something that is 896 // consistent with disabled PSR state) 897 core_power->map[core_power->num_entities].psr_enabled = 0; 898 core_power->map[core_power->num_entities].psr_events = psr_event_vsync; 899 core_power->map[core_power->num_entities].psr_power_opt = 0; 900 core_power->num_entities++; 901 return true; 902 } 903 904 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 905 WPP_BIT_FLAG_Firmware_PsrState, 906 "mod_power: add_stream: ERROR: stream=%p num_entities=%d >= MOD_POWER_MAX_CONCURRENT_STREAMS", 907 stream, 908 core_power->num_entities); 909 910 return false; 911 } 912 913 bool mod_power_remove_stream(struct mod_power *mod_power, 914 const struct dc_stream_state *stream) 915 { 916 int i = 0; 917 struct core_power *core_power = NULL; 918 unsigned int index = 0; 919 920 if (mod_power == NULL) 921 return false; 922 923 core_power = MOD_POWER_TO_CORE(mod_power); 924 if (core_power->num_entities == 0) { 925 /* trying to remove a stream a second time or have not added yet */ 926 BREAK_TO_DEBUGGER(); 927 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 928 WPP_BIT_FLAG_Firmware_PsrState, 929 "mod_power: remove_stream: ERROR: num_entities=0 stream=%p", 930 stream); 931 return false; 932 } 933 934 index = map_index_from_stream(core_power, stream); 935 936 if (index >= core_power->num_entities) { 937 /* trying to remove a stream a second time or have not added yet */ 938 BREAK_TO_DEBUGGER(); 939 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 940 WPP_BIT_FLAG_Firmware_PsrState, 941 "mod_power: remove_stream: ERROR: index=%u >= num_entities=%d stream=%p", 942 index, 943 core_power->num_entities, 944 stream); 945 return false; 946 } 947 948 dc_stream_release(core_power->map[index].stream); 949 core_power->map[index].stream = NULL; 950 /* To remove this entity, shift everything after down */ 951 for (i = index; i < core_power->num_entities - 1; i++) { 952 core_power->map[i].stream = core_power->map[i + 1].stream; 953 core_power->map[i].caps = core_power->map[i + 1].caps; 954 955 // copy over cached parameters in case they map to PSR capable display 956 core_power->map[i].psr_enabled = core_power->map[i + 1].psr_enabled; 957 core_power->map[i].psr_events = core_power->map[i + 1].psr_events; 958 core_power->map[i].psr_power_opt = core_power->map[i + 1].psr_power_opt; 959 960 memcpy(core_power->map[i].psr_context, core_power->map[i + 1].psr_context, sizeof(struct mod_power_psr_context)); 961 memset(core_power->map[i + 1].psr_context, 0, sizeof(struct mod_power_psr_context)); 962 } 963 core_power->num_entities--; 964 965 return true; 966 } 967 968 /* 969 * Replace_stream should be used when there is a mode set for existing 970 * display target with a valid stream. In this case might need to retain 971 * cached PSR state (events, power opt, en/dis) if we are dealing with PSR 972 * capable display. If mod_power_remove and mod_power_add are used instead, 973 * then stream may be assigned to a different slot and may end up with 974 * wrong cached PSR state. It is hard to tell which PSR events should 975 * persist through mode set or what psr_events should be initialized to, so 976 * it might be better just to retain them all. 977 */ 978 bool mod_power_replace_stream(struct mod_power *mod_power, 979 const struct dc_stream_state *current_stream, 980 struct dc_stream_state *new_stream, 981 struct psr_caps *new_caps) 982 { 983 struct core_power *core_power = NULL; 984 unsigned int index = 0; 985 986 if (mod_power == NULL) 987 return false; 988 989 core_power = MOD_POWER_TO_CORE(mod_power); 990 if (core_power->num_entities == 0) { 991 /* no streams exist in the table yet */ 992 BREAK_TO_DEBUGGER(); 993 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 994 WPP_BIT_FLAG_Firmware_PsrState, 995 "mod_power: replace_stream: ERROR: num_entities=0 stream=%p", 996 current_stream); 997 return false; 998 } 999 1000 index = map_index_from_stream(core_power, current_stream); 1001 1002 if (index >= core_power->num_entities) { 1003 /* trying to replace a non-existent stream */ 1004 BREAK_TO_DEBUGGER(); 1005 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 1006 WPP_BIT_FLAG_Firmware_PsrState, 1007 "mod_power: replace_stream: ERROR: index=%u >= num_entities=%d stream=%p", 1008 index, 1009 core_power->num_entities, 1010 current_stream); 1011 return false; 1012 } 1013 1014 dc_stream_release(core_power->map[index].stream); 1015 dc_stream_retain(new_stream); 1016 core_power->map[index].stream = new_stream; 1017 core_power->map[index].caps = new_caps; 1018 memset(core_power->map[index].psr_context, 0, sizeof(struct mod_power_psr_context)); 1019 1020 return true; 1021 } 1022 1023 static bool set_backlight_millinits_aux(struct core_power *core_power, 1024 struct dc_stream_state *stream, 1025 unsigned int backlight_millinits, 1026 unsigned int transition_time_millisec, 1027 unsigned int inst) 1028 { 1029 struct dc_link *link = NULL; 1030 1031 if (core_power == NULL) 1032 return false; 1033 1034 if (stream == NULL) 1035 return true; 1036 1037 link = dc_stream_get_link(stream); 1038 1039 return dc_link_set_backlight_level_nits(link, core_power->bl_state[inst].isHDR, 1040 backlight_millinits, transition_time_millisec); 1041 } 1042 1043 static bool set_backlight(struct core_power *core_power, 1044 struct dc_stream_state *stream, 1045 struct set_backlight_level_params *backlight_level_params, 1046 unsigned int inst) 1047 { 1048 bool retv = false; 1049 unsigned int frame_ramp = 0; 1050 unsigned int vsync_rate_hz; 1051 union dmcu_abm_set_bl_params params; 1052 const struct dc_link *link = NULL; 1053 unsigned int backlight_pwm_u16_16 = backlight_level_params->backlight_pwm_u16_16; 1054 unsigned int transition_time_millisec = backlight_level_params->transition_time_in_ms; 1055 1056 if (core_power == NULL) 1057 return false; 1058 1059 core_power->bl_state[inst].backlight_pwm = backlight_pwm_u16_16; 1060 1061 if (stream == NULL) 1062 return true; 1063 1064 if (stream->link->connector_signal != SIGNAL_TYPE_EDP) 1065 return false; 1066 1067 if (transition_time_millisec != 0) { 1068 unsigned int v_total = 1069 (stream->adjust.v_total_max == 0) ? stream->timing.v_total : stream->adjust.v_total_max; 1070 1071 vsync_rate_hz = (unsigned int)div_u64(div_u64((stream-> 1072 timing.pix_clk_100hz * 100), 1073 v_total), 1074 stream->timing.h_total); 1075 1076 if (core_power->bl_state[inst].smooth_brightness_enabled) 1077 frame_ramp = ((vsync_rate_hz * 1078 transition_time_millisec) + 500) / 1000; 1079 } 1080 1081 core_power->bl_state[inst].frame_ramp = frame_ramp; 1082 params.u32All = 0; 1083 params.bits.gradual_change = (frame_ramp > 0); 1084 params.bits.frame_ramp = frame_ramp; 1085 link = dc_stream_get_link(stream); 1086 1087 mod_power_set_psr_event(&core_power->public, stream, true, psr_event_hw_programming, true); 1088 mod_power_set_replay_event(&core_power->public, stream, true, replay_event_hw_programming, true); 1089 1090 backlight_level_params->frame_ramp = params.u32All; 1091 retv = dc_link_set_backlight_level(link, backlight_level_params); 1092 1093 mod_power_set_psr_event(&core_power->public, stream, false, psr_event_hw_programming, false); 1094 mod_power_set_replay_event(&core_power->public, stream, false, replay_event_hw_programming, false); 1095 1096 return retv; 1097 } 1098 1099 static void fill_backlight_level_params(struct core_power *core_power, 1100 struct set_backlight_level_params *backlight_level_params, 1101 int panel_inst, uint8_t aux_inst, unsigned int backlight_pwm, 1102 enum backlight_control_type backlight_control_type, 1103 unsigned int backlight_millinit, unsigned int transition_time_millisec, 1104 bool is_hdr) 1105 { 1106 struct pwr_backlight_properties *bl_prop = &core_power->bl_prop[panel_inst]; 1107 1108 backlight_level_params->aux_inst = aux_inst; 1109 backlight_level_params->backlight_pwm_u16_16 = backlight_pwm; 1110 backlight_level_params->control_type = backlight_control_type; 1111 backlight_level_params->backlight_millinits = backlight_millinit; 1112 backlight_level_params->transition_time_in_ms = transition_time_millisec; 1113 backlight_level_params->min_luminance = bl_prop->min_brightness_millinits; 1114 backlight_level_params->max_luminance = bl_prop->max_brightness_millinits; 1115 backlight_level_params->min_backlight_pwm = bl_prop->min_backlight_pwm; 1116 backlight_level_params->max_backlight_pwm = bl_prop->max_backlight_pwm; 1117 1118 if (backlight_control_type == BACKLIGHT_CONTROL_AMD_AUX && !is_hdr) 1119 backlight_level_params->control_type = BACKLIGHT_CONTROL_PWM; 1120 } 1121 1122 bool mod_power_set_backlight_nits(struct mod_power *mod_power, 1123 struct dc_stream_state *stream, 1124 unsigned int backlight_millinit, 1125 unsigned int transition_time_millisec, 1126 bool skip_aux, 1127 bool is_hdr) 1128 { 1129 struct core_power *core_power = NULL; 1130 unsigned int backlight_pwm; 1131 unsigned int panel_inst = 0; 1132 struct set_backlight_level_params backlight_level_params = { 0 }; 1133 const struct dc_link *link = NULL; 1134 uint8_t aux_inst = 0; 1135 1136 if (mod_power == NULL) 1137 return false; 1138 1139 core_power = MOD_POWER_TO_CORE(mod_power); 1140 link = dc_stream_get_link(stream); 1141 1142 ASSERT(link->ddc->ddc_pin->hw_info.ddc_channel <= 0xFF); 1143 aux_inst = (uint8_t)link->ddc->ddc_pin->hw_info.ddc_channel; 1144 1145 if (!dc_get_edp_link_panel_inst(core_power->dc, stream->link, &panel_inst)) 1146 return false; 1147 1148 if (!skip_aux) { 1149 if (!set_backlight_millinits_aux(core_power, stream, 1150 backlight_millinit, transition_time_millisec, panel_inst)) 1151 return false; 1152 } 1153 // always send both AUX (above) and PWM (below) 1154 core_power->bl_state[panel_inst].backlight_millinit = backlight_millinit; 1155 1156 core_power->bl_state[panel_inst].backlight_millipercent = 1157 backlight_millinit_to_millipercent( 1158 core_power, backlight_millinit, panel_inst); 1159 1160 backlight_pwm = backlight_millinit_to_pwm( 1161 core_power, backlight_millinit, panel_inst); 1162 1163 fill_backlight_level_params(core_power, &backlight_level_params, panel_inst, aux_inst, backlight_pwm, 1164 link->backlight_control_type, backlight_millinit, transition_time_millisec, is_hdr); 1165 1166 return set_backlight(core_power, stream, 1167 &backlight_level_params, panel_inst); 1168 } 1169 1170 1171 bool mod_power_backlight_percent_to_nits(struct mod_power *mod_power, 1172 struct dc_stream_state *stream, 1173 unsigned int backlight_millipercent, 1174 unsigned int *backlight_millinit) 1175 { 1176 struct core_power *core_power = NULL; 1177 unsigned int inst = 0; 1178 1179 if (mod_power == NULL) 1180 return false; 1181 1182 core_power = MOD_POWER_TO_CORE(mod_power); 1183 1184 if (!dc_get_edp_link_panel_inst(core_power->dc, stream->link, &inst)) 1185 return false; 1186 1187 *backlight_millinit = backlight_millipercent_to_millinit( 1188 core_power, backlight_millipercent, inst); 1189 return true; 1190 } 1191 1192 bool mod_power_backlight_nits_to_percent(struct mod_power *mod_power, 1193 struct dc_stream_state *stream, 1194 unsigned int backlight_millinit, 1195 unsigned int *backlight_millipercent) 1196 { 1197 struct core_power *core_power = NULL; 1198 unsigned int inst = 0; 1199 1200 if (mod_power == NULL) 1201 return false; 1202 1203 core_power = MOD_POWER_TO_CORE(mod_power); 1204 1205 if (!dc_get_edp_link_panel_inst(core_power->dc, stream->link, &inst)) 1206 return false; 1207 1208 *backlight_millipercent = backlight_millinit_to_millipercent( 1209 core_power, backlight_millinit, inst); 1210 return true; 1211 } 1212 1213 bool mod_power_set_backlight_percent(struct mod_power *mod_power, 1214 struct dc_stream_state *stream, 1215 unsigned int backlight_millipercent, 1216 unsigned int transition_time_millisec, 1217 bool is_hdr) 1218 { 1219 struct core_power *core_power = NULL; 1220 struct set_backlight_level_params backlight_level_params = { 0 }; 1221 const struct dc_link *link = NULL; 1222 unsigned int backlight_pwm; 1223 unsigned int panel_inst = 0; 1224 uint8_t aux_inst = 0; 1225 1226 if (mod_power == NULL) 1227 return false; 1228 1229 core_power = MOD_POWER_TO_CORE(mod_power); 1230 link = dc_stream_get_link(stream); 1231 ASSERT(link->ddc->ddc_pin->hw_info.ddc_channel <= 0xFF); 1232 aux_inst = (uint8_t)link->ddc->ddc_pin->hw_info.ddc_channel; 1233 1234 if (!dc_get_edp_link_panel_inst(core_power->dc, stream->link, &panel_inst)) 1235 return false; 1236 core_power->bl_state[panel_inst].backlight_millipercent = backlight_millipercent; 1237 1238 core_power->bl_state[panel_inst].backlight_millinit = 1239 backlight_millipercent_to_millinit( 1240 core_power, backlight_millipercent, panel_inst); 1241 1242 backlight_pwm = backlight_millipercent_to_pwm( 1243 core_power, backlight_millipercent, panel_inst); 1244 1245 fill_backlight_level_params(core_power, &backlight_level_params, panel_inst, 1246 aux_inst, backlight_pwm, link->backlight_control_type, 1247 core_power->bl_state[panel_inst].backlight_millinit, transition_time_millisec, is_hdr); 1248 1249 return set_backlight(core_power, stream, 1250 &backlight_level_params, panel_inst); 1251 } 1252 1253 void mod_power_update_backlight(struct mod_power *mod_power, 1254 struct dc_stream_state *stream, 1255 unsigned int backlight_millipercent) 1256 { 1257 struct core_power *core_power = NULL; 1258 unsigned int inst = 0; 1259 1260 if (mod_power == NULL) 1261 return; 1262 1263 core_power = MOD_POWER_TO_CORE(mod_power); 1264 1265 if (!dc_get_edp_link_panel_inst(core_power->dc, stream->link, &inst)) 1266 return; 1267 core_power->bl_state[inst].backlight_millipercent = backlight_millipercent; 1268 1269 core_power->bl_state[inst].backlight_millinit = 1270 backlight_millipercent_to_millinit( 1271 core_power, backlight_millipercent, inst); 1272 1273 core_power->bl_state[inst].backlight_pwm = backlight_millipercent_to_pwm( 1274 core_power, backlight_millipercent, inst); 1275 } 1276 1277 void mod_power_update_backlight_nits(struct mod_power *mod_power, 1278 struct dc_stream_state *stream, 1279 unsigned int backlight_millinit) 1280 { 1281 struct core_power *core_power = NULL; 1282 unsigned int inst = 0; 1283 1284 if (mod_power == NULL) 1285 return; 1286 1287 core_power = MOD_POWER_TO_CORE(mod_power); 1288 1289 if (!dc_get_edp_link_panel_inst(core_power->dc, stream->link, &inst)) 1290 return; 1291 1292 core_power->bl_state[inst].backlight_millinit = backlight_millinit; 1293 1294 core_power->bl_state[inst].backlight_millipercent = backlight_millinit_to_millipercent( 1295 core_power, backlight_millinit, inst); 1296 core_power->bl_state[inst].backlight_pwm = backlight_millinit_to_pwm( 1297 core_power, backlight_millinit, inst); 1298 } 1299 1300 bool mod_power_get_backlight_pwm(struct mod_power *mod_power, 1301 unsigned int *backlight_pwm, 1302 unsigned int inst) 1303 { 1304 struct core_power *core_power = NULL; 1305 1306 if (mod_power == NULL) 1307 return false; 1308 1309 core_power = MOD_POWER_TO_CORE(mod_power); 1310 1311 *backlight_pwm = core_power->bl_state[inst].backlight_pwm; 1312 1313 return true; 1314 } 1315 1316 bool mod_power_get_backlight_nits(struct mod_power *mod_power, 1317 unsigned int *backlight_millinit, 1318 unsigned int inst) 1319 { 1320 struct core_power *core_power = NULL; 1321 1322 if (mod_power == NULL) 1323 return false; 1324 1325 core_power = MOD_POWER_TO_CORE(mod_power); 1326 1327 *backlight_millinit = core_power->bl_state[inst].backlight_millinit; 1328 1329 return true; 1330 } 1331 1332 bool mod_power_get_backlight_percent(struct mod_power *mod_power, 1333 unsigned int *backlight_millipercent, 1334 unsigned int inst) 1335 { 1336 struct core_power *core_power = NULL; 1337 1338 if (mod_power == NULL) 1339 return false; 1340 1341 core_power = MOD_POWER_TO_CORE(mod_power); 1342 1343 *backlight_millipercent = core_power->bl_state[inst].backlight_millipercent; 1344 1345 return true; 1346 } 1347 1348 bool mod_power_get_hw_target_backlight_pwm_nits(struct mod_power *mod_power, 1349 const struct dc_link *link, 1350 unsigned int *backlight_millinit, 1351 unsigned int inst) 1352 { 1353 struct core_power *core_power = NULL; 1354 unsigned int backlight_u16_16 = 0; 1355 1356 if (mod_power == NULL) 1357 return false; 1358 1359 core_power = MOD_POWER_TO_CORE(mod_power); 1360 1361 if (mod_power_get_hw_target_backlight_pwm(mod_power, link, 1362 &backlight_u16_16)) { 1363 *backlight_millinit = 1364 backlight_pwm_to_millinit(core_power, 1365 backlight_u16_16, inst); 1366 return true; 1367 } 1368 return false; 1369 } 1370 1371 bool mod_power_get_hw_target_backlight_pwm_percent(struct mod_power *mod_power, 1372 const struct dc_link *link, 1373 unsigned int *backlight_millipercent, 1374 unsigned int inst) 1375 { 1376 struct core_power *core_power = NULL; 1377 unsigned int backlight_u16_16 = 0; 1378 1379 if (mod_power == NULL) 1380 return false; 1381 1382 core_power = MOD_POWER_TO_CORE(mod_power); 1383 1384 if (mod_power_get_hw_target_backlight_pwm(mod_power, link, 1385 &backlight_u16_16)) { 1386 *backlight_millipercent = 1387 backlight_pwm_to_millipercent(core_power, 1388 backlight_u16_16, inst); 1389 return true; 1390 } 1391 return false; 1392 } 1393 1394 bool mod_power_get_hw_target_backlight_pwm(struct mod_power *mod_power, 1395 const struct dc_link *link, 1396 unsigned int *backlight_u16_16) 1397 { 1398 if (mod_power == NULL) 1399 return false; 1400 1401 *backlight_u16_16 = dc_link_get_target_backlight_pwm(link); 1402 1403 return true; 1404 } 1405 1406 bool mod_power_get_hw_backlight_pwm_nits(struct mod_power *mod_power, 1407 const struct dc_link *link, 1408 unsigned int *backlight_millinit, 1409 unsigned int inst) 1410 { 1411 struct core_power *core_power = NULL; 1412 unsigned int backlight_u16_16 = 0; 1413 1414 if (mod_power == NULL) 1415 return false; 1416 1417 core_power = MOD_POWER_TO_CORE(mod_power); 1418 1419 if (mod_power_get_hw_backlight_pwm(mod_power, link, &backlight_u16_16)) { 1420 *backlight_millinit = 1421 backlight_pwm_to_millinit(core_power, 1422 backlight_u16_16, inst); 1423 return true; 1424 } 1425 return false; 1426 } 1427 1428 bool mod_power_get_hw_backlight_aux_nits(struct mod_power *mod_power, 1429 struct dc_stream_state **streams, int num_streams, 1430 unsigned int *backlight_millinit_avg, 1431 unsigned int *backlight_millinit_peak) 1432 { 1433 struct core_power *core_power = NULL; 1434 struct dc_link *link = NULL; 1435 unsigned int stream_index; 1436 1437 if (mod_power == NULL) 1438 return false; 1439 1440 core_power = MOD_POWER_TO_CORE(mod_power); 1441 1442 if (core_power == NULL) 1443 return false; 1444 1445 if (num_streams < 1) 1446 return true; 1447 1448 for (stream_index = 0; stream_index < num_streams; stream_index++) 1449 if (streams[stream_index]->link->connector_signal == SIGNAL_TYPE_EDP || 1450 streams[stream_index]->link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT) 1451 break; 1452 1453 if (stream_index == num_streams) 1454 return false; 1455 1456 link = dc_stream_get_link(streams[stream_index]); 1457 if (link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 0) 1458 return false; 1459 1460 return dc_link_get_backlight_level_nits(link, backlight_millinit_avg, 1461 backlight_millinit_peak); 1462 } 1463 1464 bool mod_power_get_hw_backlight_pwm_percent(struct mod_power *mod_power, 1465 const struct dc_link *link, 1466 unsigned int *backlight_millipercent, 1467 unsigned int inst) 1468 { 1469 struct core_power *core_power = NULL; 1470 unsigned int backlight_u16_16 = 0; 1471 1472 if (mod_power == NULL) 1473 return false; 1474 1475 core_power = MOD_POWER_TO_CORE(mod_power); 1476 1477 if (mod_power_get_hw_backlight_pwm(mod_power, link, &backlight_u16_16)) { 1478 *backlight_millipercent = 1479 backlight_pwm_to_millipercent(core_power, 1480 backlight_u16_16, inst); 1481 return true; 1482 } 1483 return false; 1484 } 1485 1486 bool mod_power_get_hw_backlight_pwm(struct mod_power *mod_power, 1487 const struct dc_link *link, 1488 unsigned int *backlight_u16_16) 1489 { 1490 if (mod_power == NULL) 1491 return false; 1492 1493 *backlight_u16_16 = dc_link_get_backlight_level(link); 1494 1495 return true; 1496 } 1497 1498 bool mod_power_get_panel_backlight_boundaries( 1499 struct mod_power *mod_power, 1500 unsigned int *out_min_backlight, 1501 unsigned int *out_max_backlight, 1502 unsigned int *out_ac_backlight_percent, 1503 unsigned int *out_dc_backlight_percent, 1504 unsigned int inst) 1505 { 1506 struct core_power *core_power = NULL; 1507 1508 if (mod_power == NULL) 1509 return false; 1510 1511 core_power = MOD_POWER_TO_CORE(mod_power); 1512 1513 /* If cache was successfully updated, 1514 * copy the values to output structure and return success 1515 */ 1516 if (core_power->bl_prop[inst].backlight_caps_valid) { 1517 *out_min_backlight = core_power->bl_prop[inst].backlight_lut[0]; 1518 *out_max_backlight = 1519 core_power->bl_prop[inst].backlight_lut[ 1520 core_power->bl_prop[inst].num_backlight_levels - 1]; 1521 *out_ac_backlight_percent = 1522 core_power->bl_prop[inst].ac_backlight_percent; 1523 *out_dc_backlight_percent = 1524 core_power->bl_prop[inst].dc_backlight_percent; 1525 1526 return true; 1527 } 1528 1529 return false; 1530 } 1531 1532 bool mod_power_set_smooth_brightness(struct mod_power *mod_power, 1533 bool enable_brightness, 1534 unsigned int inst) 1535 { 1536 struct core_power *core_power = NULL; 1537 1538 if (mod_power == NULL) 1539 return false; 1540 1541 core_power = MOD_POWER_TO_CORE(mod_power); 1542 1543 core_power->bl_state[inst].smooth_brightness_enabled = enable_brightness; 1544 1545 return true; 1546 } 1547 1548 bool mod_power_notify_mode_change(struct mod_power *mod_power, 1549 const struct dc_stream_state *stream, 1550 bool is_hdr) 1551 { 1552 unsigned int stream_index = 0; 1553 struct core_power *core_power = NULL; 1554 struct dc_link *link = NULL; 1555 struct psr_config psr_config = {0}; 1556 struct psr_context psr_context = {0}; 1557 struct dc *dc = NULL; 1558 unsigned int panel_inst = 0; 1559 int active_psr_events = 0; 1560 int active_replay_events = 0; 1561 1562 if ((mod_power == NULL) || (stream == NULL)) 1563 return false; 1564 1565 core_power = MOD_POWER_TO_CORE(mod_power); 1566 1567 if (core_power->num_entities == 0) 1568 return false; 1569 1570 stream_index = map_index_from_stream(core_power, stream); 1571 1572 if (stream_index >= core_power->num_entities) 1573 return false; 1574 1575 dc = core_power->dc; 1576 link = dc_stream_get_link(stream); 1577 active_psr_events = core_power->map[stream_index].psr_events; 1578 active_replay_events = core_power->map[stream_index].replay_events; 1579 if (link != NULL && dc_get_edp_link_panel_inst(dc, link, &panel_inst)) { 1580 struct set_backlight_level_params backlight_level_params = { 0 }; 1581 1582 ASSERT(link->ddc->ddc_pin->hw_info.ddc_channel <= 0xFF); 1583 uint8_t aux_inst = (uint8_t)link->ddc->ddc_pin->hw_info.ddc_channel; 1584 1585 if (link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || 1586 link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1) 1587 dc_link_set_backlight_level_nits(link, core_power->bl_state[panel_inst].isHDR, 1588 core_power->bl_state[panel_inst].backlight_millinit, 0); 1589 1590 backlight_level_params.frame_ramp = 0; 1591 1592 fill_backlight_level_params(core_power, &backlight_level_params, panel_inst, aux_inst, 1593 core_power->bl_state[panel_inst].backlight_pwm, link->backlight_control_type, 1594 core_power->bl_state[panel_inst].backlight_millinit, 0, is_hdr); 1595 1596 dc_link_set_backlight_level(link, &backlight_level_params); 1597 1598 mod_power_calc_psr_configs(&psr_config, link, stream); 1599 1600 psr_config.psr_exit_link_training_required = core_power->map[stream_index].caps->psr_exit_link_training_required; 1601 1602 if (dc->ctx->asic_id.chip_family >= AMDGPU_FAMILY_GC_11_0_1) 1603 psr_config.allow_smu_optimizations = 1604 core_power->psr_smu_optimizations_support && dc_is_embedded_signal(stream->signal); 1605 else 1606 psr_config.allow_smu_optimizations = 1607 core_power->psr_smu_optimizations_support && mod_power_only_edp(dc->current_state, stream); 1608 1609 psr_config.allow_multi_disp_optimizations = core_power->multi_disp_optimizations_support; 1610 1611 psr_config.rate_control_caps = core_power->map[stream_index].caps->rate_control_caps; 1612 1613 if (active_psr_events & psr_event_os_request_force_ffu) { 1614 psr_config.os_request_force_ffu = true; 1615 } 1616 /* 1617 * DSC support: 1618 * DSC slice height value must be 'mod' by su_y_granularity. 1619 * According to Panel Vendor, there might be varied conditions to fulfill. 1620 * Right now, DSC slice height value must be multiple of su_y_granularity. 1621 * 1622 * The value of DSC slice height is determined in DSC Driver but it does not 1623 * propagated out here, so we need to calculate it as below 'slice_height'. 1624 */ 1625 psr_su_set_dsc_slice_height(dc, link, 1626 (struct dc_stream_state *) stream, 1627 &psr_config); 1628 1629 dc_link_setup_psr(link, stream, &psr_config, &psr_context); 1630 1631 link->replay_settings.replay_smu_opt_enable = 1632 (link->replay_settings.config.replay_smu_opt_supported && 1633 mod_power_only_edp(dc->current_state, stream)); 1634 1635 if (active_replay_events & replay_event_os_request_force_ffu) { 1636 link->replay_settings.config.os_request_force_ffu = true; 1637 } 1638 1639 if (dc_is_embedded_signal(stream->signal)) 1640 dc->link_srv->dp_setup_replay(link, stream); 1641 } 1642 1643 return true; 1644 } 1645 1646 bool mod_power_varibright_feature_enable(struct mod_power *mod_power, bool enable, 1647 struct dc_stream_update *stream_update) 1648 { 1649 struct core_power *core_power = NULL; 1650 1651 if (mod_power == NULL) 1652 return false; 1653 1654 core_power = MOD_POWER_TO_CORE(mod_power); 1655 core_power->varibright_prop.varibright_user_enable = enable; 1656 1657 /* find abm hw level to program, and save in stream update */ 1658 varibright_set_level(core_power); 1659 *stream_update->abm_level = core_power->varibright_prop.varibright_hw_level; 1660 1661 DC_TRACE_LEVEL_MESSAGEP(DAL_TRACE_LEVEL_INFORMATION, 1662 WPP_BIT_FLAG_Backlight_ABM, 1663 ">ABM feature enable: enable=%u su->varibright_level=%u varibright_hw_level=%u", 1664 (unsigned int) enable, 1665 *stream_update->abm_level, 1666 core_power->varibright_prop.varibright_hw_level); 1667 return true; 1668 } 1669 1670 bool mod_power_varibright_activate(struct mod_power *mod_power, 1671 bool activate, 1672 struct dc_stream_update *stream_update) 1673 { 1674 struct core_power *core_power = NULL; 1675 1676 if (mod_power == NULL) 1677 return false; 1678 1679 core_power = MOD_POWER_TO_CORE(mod_power); 1680 core_power->varibright_prop.varibright_active = activate; 1681 1682 /* find abm hw level to program, and save in stream update */ 1683 varibright_set_level(core_power); 1684 *stream_update->abm_level = core_power->varibright_prop.varibright_hw_level; 1685 1686 DC_TRACE_LEVEL_MESSAGEP(DAL_TRACE_LEVEL_INFORMATION, 1687 WPP_BIT_FLAG_Backlight_ABM, 1688 ">ABM activate: activate=%u su->varibright_level=%u", 1689 (unsigned int) activate, 1690 *stream_update->abm_level); 1691 return true; 1692 } 1693 bool mod_power_varibright_set_level(struct mod_power *mod_power, unsigned int level, 1694 struct dc_stream_update *stream_update) 1695 { 1696 struct core_power *core_power = NULL; 1697 1698 if (mod_power == NULL) 1699 return false; 1700 1701 core_power = MOD_POWER_TO_CORE(mod_power); 1702 core_power->varibright_prop.varibright_level = level; 1703 core_power->varibright_prop.varibright_hw_level = level; 1704 1705 /* find abm hw level to program, and save in stream update */ 1706 varibright_set_level(core_power); 1707 *stream_update->abm_level = core_power->varibright_prop.varibright_hw_level; 1708 1709 DC_TRACE_LEVEL_MESSAGEP(DAL_TRACE_LEVEL_INFORMATION, 1710 WPP_BIT_FLAG_Backlight_ABM, 1711 ">ABM set level: level=%u -> (varibright_level=%u varibright_hw_level=%u) -> su->varibright_level=%u", 1712 level, 1713 core_power->varibright_prop.varibright_level, 1714 core_power->varibright_prop.varibright_hw_level, 1715 *stream_update->abm_level); 1716 return true; 1717 } 1718 1719 bool mod_power_varibright_set_hw_level(struct mod_power *mod_power, unsigned int level, 1720 struct dc_stream_update *stream_update) 1721 { 1722 struct core_power *core_power = NULL; 1723 1724 if (mod_power == NULL) 1725 return false; 1726 1727 core_power = MOD_POWER_TO_CORE(mod_power); 1728 1729 if (level == 0 || level == ABM_LEVEL_IMMEDIATE_DISABLE) 1730 core_power->varibright_prop.varibright_active = 0; 1731 else 1732 core_power->varibright_prop.varibright_active = 1; 1733 core_power->varibright_prop.varibright_hw_level = level; 1734 *stream_update->abm_level = core_power->varibright_prop.varibright_hw_level; 1735 1736 DC_TRACE_LEVEL_MESSAGEP(DAL_TRACE_LEVEL_INFORMATION, 1737 WPP_BIT_FLAG_Backlight_ABM, 1738 ">ABM set level: level=%u -> (varibright_level=%u varibright_hw_level=%u) -> su->varibright_level=%u", 1739 level, 1740 core_power->varibright_prop.varibright_level, 1741 core_power->varibright_prop.varibright_hw_level, 1742 *stream_update->abm_level); 1743 return true; 1744 } 1745 1746 bool mod_power_get_varibright_level(struct mod_power *mod_power, 1747 unsigned int *varibright_level) 1748 { 1749 struct core_power *core_power = NULL; 1750 1751 if (mod_power == NULL) 1752 return false; 1753 1754 core_power = MOD_POWER_TO_CORE(mod_power); 1755 1756 *varibright_level = core_power->varibright_prop.varibright_level; 1757 1758 DC_TRACE_LEVEL_MESSAGEP(DAL_TRACE_LEVEL_INFORMATION, 1759 WPP_BIT_FLAG_Backlight_ABM, 1760 ">get varibright level: cp->varibright_level=%u", 1761 *varibright_level); 1762 return true; 1763 1764 } 1765 1766 bool mod_power_get_varibright_hw_level(struct mod_power *mod_power, 1767 unsigned int *varibright_level) 1768 { 1769 struct core_power *core_power = NULL; 1770 1771 if (mod_power == NULL) 1772 return false; 1773 1774 core_power = MOD_POWER_TO_CORE(mod_power); 1775 1776 *varibright_level = core_power->varibright_prop.varibright_hw_level; 1777 DC_TRACE_LEVEL_MESSAGEP(DAL_TRACE_LEVEL_INFORMATION, 1778 WPP_BIT_FLAG_Backlight_ABM, 1779 ">get varibright HW level: hw_level=%u", 1780 *varibright_level); 1781 return true; 1782 } 1783 1784 bool mod_power_get_varibright_default_level(struct mod_power *mod_power, 1785 unsigned int *varibright_level) 1786 { 1787 struct core_power *core_power = NULL; 1788 1789 if (mod_power == NULL) 1790 return false; 1791 1792 core_power = MOD_POWER_TO_CORE(mod_power); 1793 1794 *varibright_level = core_power->varibright_prop.def_varibright_level; 1795 DC_TRACE_LEVEL_MESSAGEP(DAL_TRACE_LEVEL_INFORMATION, 1796 WPP_BIT_FLAG_Backlight_ABM, 1797 ">get varibright default level: def_varibright_level=%u", 1798 *varibright_level); 1799 return true; 1800 } 1801 1802 bool mod_power_get_varibright_enable(struct mod_power *mod_power, 1803 bool *varibright_enable) 1804 { 1805 struct core_power *core_power = NULL; 1806 1807 if (mod_power == NULL) 1808 return false; 1809 1810 core_power = MOD_POWER_TO_CORE(mod_power); 1811 1812 *varibright_enable = core_power->varibright_prop.varibright_user_enable; 1813 DC_TRACE_LEVEL_MESSAGEP(DAL_TRACE_LEVEL_INFORMATION, 1814 WPP_BIT_FLAG_Backlight_ABM, 1815 ">get varibright enable state: varibright_user_enable=%u", 1816 (unsigned int) (*varibright_enable)); 1817 return true; 1818 } 1819 1820 bool mod_power_is_abm_active(struct mod_power *mod_power, 1821 const struct dc_link *link, 1822 unsigned int inst) 1823 { 1824 unsigned int user_backlight = 0; 1825 unsigned int current_backlight = 0; 1826 bool is_active = false; 1827 1828 if (mod_power == NULL) 1829 return false; 1830 1831 mod_power_get_backlight_pwm(mod_power, &user_backlight, inst); 1832 mod_power_get_hw_backlight_pwm(mod_power, link, ¤t_backlight); 1833 1834 if (user_backlight != current_backlight) 1835 is_active = true; 1836 else 1837 is_active = false; 1838 DC_TRACE_LEVEL_MESSAGEP(DAL_TRACE_LEVEL_INFORMATION, 1839 WPP_BIT_FLAG_Backlight_ABM, 1840 ">get ABM active state: is_active=%u (user_backlight_pwm=%u, current_backlight_pwm=%u)", 1841 (unsigned int)is_active, 1842 user_backlight, 1843 current_backlight); 1844 return is_active; 1845 } 1846 1847 1848 static void mod_power_psr_set_power_opt(struct mod_power *mod_power, 1849 struct dc_stream_state *stream, 1850 unsigned int active_psr_events, 1851 bool psr_enable_request) 1852 { 1853 (void)psr_enable_request; 1854 struct core_power *core_power = NULL; 1855 struct dc_link *link = NULL; 1856 unsigned int stream_index = 0; 1857 unsigned int power_opt = 0; 1858 1859 if (!stream) 1860 return; 1861 1862 core_power = MOD_POWER_TO_CORE(mod_power); 1863 stream_index = map_index_from_stream(core_power, stream); 1864 if (!core_power->map[stream_index].caps->psr_version) 1865 return; 1866 1867 link = dc_stream_get_link(stream); 1868 1869 if (active_psr_events == 0) { 1870 /* Static Screen */ 1871 power_opt |= (psr_power_opt_smu_opt_static_screen | psr_power_opt_z10_static_screen | 1872 psr_power_opt_ds_disable_allow); 1873 } 1874 1875 /* psr_power_opt_flag is a configuration parameter into the module that determines 1876 * which optimizations to enable during psr 1877 */ 1878 power_opt &= core_power->map[stream_index].caps->psr_power_opt_flag; 1879 if (core_power->map[stream_index].psr_power_opt != power_opt) { 1880 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_VERBOSE, 1881 WPP_BIT_FLAG_Firmware_PsrState, 1882 "mod_power set_power_opt: psr_power_opt=0x%04x, power_opt=0x%04x" 1883 "active_psr_events=0x%04x, psr_power_opt_flag=0x%04x", 1884 core_power->map[stream_index].psr_power_opt, 1885 power_opt, 1886 active_psr_events, 1887 core_power->map[stream_index].caps->psr_power_opt_flag); 1888 dc_link_set_psr_allow_active(link, NULL, false, false, &power_opt); 1889 core_power->map[stream_index].psr_power_opt = power_opt; 1890 } 1891 } 1892 1893 static bool set_psr_enable(struct mod_power *mod_power, 1894 struct dc_stream_state *stream, 1895 bool psr_enable, 1896 bool wait, 1897 bool force_static) 1898 { 1899 struct core_power *core_power = NULL; 1900 enum dc_psr_state state = PSR_STATE0; 1901 unsigned int retry_count; 1902 const unsigned int max_retry = 1000; 1903 struct dc_link *link = NULL; 1904 1905 if (mod_power == NULL) 1906 return false; 1907 1908 core_power = MOD_POWER_TO_CORE(mod_power); 1909 1910 if (core_power->num_entities == 0) { 1911 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 1912 WPP_BIT_FLAG_Firmware_PsrState, 1913 "set psr enable: ERROR: stream=%p num_entities=%d", 1914 stream, 1915 core_power->num_entities); 1916 return false; 1917 } 1918 1919 if (psr_enable) { 1920 unsigned int vsync_rate_hz; 1921 struct dc_static_screen_params params = {0}; 1922 1923 vsync_rate_hz = (unsigned int)div_u64(div_u64(( 1924 stream->timing.pix_clk_100hz * 100), 1925 stream->timing.v_total), 1926 stream->timing.h_total); 1927 1928 params.triggers.cursor_update = true; 1929 params.triggers.overlay_update = true; 1930 params.triggers.surface_update = true; 1931 params.num_frames = calc_psr_num_static_frames(vsync_rate_hz); 1932 1933 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 1934 WPP_BIT_FLAG_Firmware_PsrState, 1935 "set psr enable: CALCS: pix_clk_100hz=%u v_total=%u h_total=%u vsync_rate_hz=%u num_frames=%u", 1936 stream->timing.pix_clk_100hz, 1937 stream->timing.v_total, 1938 stream->timing.h_total, 1939 vsync_rate_hz, 1940 params.num_frames); 1941 1942 dc_stream_set_static_screen_params(core_power->dc, 1943 &stream, 1, 1944 ¶ms); 1945 } 1946 1947 link = dc_stream_get_link(stream); 1948 1949 if (!dc_link_set_psr_allow_active(link, &psr_enable, false, force_static, NULL)) { 1950 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 1951 WPP_BIT_FLAG_Firmware_PsrState, 1952 "set psr enable: ERROR: stream=%p link=%p psr_enable=%d", 1953 stream, 1954 link, 1955 psr_enable); 1956 return false; 1957 } 1958 1959 if (wait == true) { 1960 1961 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 1962 WPP_BIT_FLAG_Firmware_PsrState, 1963 "set psr enable: BEGIN WAIT: psr_enable=%d", 1964 (int)psr_enable); 1965 1966 for (retry_count = 0; retry_count <= max_retry; retry_count++) { 1967 dc_link_get_psr_state(link, &state); 1968 if (psr_enable) { 1969 if (state != PSR_STATE0 && 1970 (!force_static || state == PSR_STATE3)) 1971 break; 1972 } else { 1973 if (state == PSR_STATE0) 1974 break; 1975 } 1976 udelay(500); 1977 } 1978 1979 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 1980 WPP_BIT_FLAG_Firmware_PsrState, 1981 "set psr enable: END WAIT: psr_enable=%d", 1982 (int)psr_enable); 1983 1984 /* assert if max retry hit */ 1985 if (retry_count >= max_retry) { 1986 ASSERT(0); 1987 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 1988 WPP_BIT_FLAG_Firmware_PsrState, 1989 "set psr enable: ERROR: retry_count=%u: Unexpectedly long wait for PSR state change.", 1990 retry_count); 1991 } 1992 } else { 1993 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_INFORMATION, 1994 WPP_BIT_FLAG_Firmware_PsrState, 1995 "set psr enable: PSR state change initiated (wait=false): psr_enable=%d", 1996 (int)psr_enable); 1997 } 1998 1999 return true; 2000 } 2001 2002 bool mod_power_get_psr_event(struct mod_power *mod_power, 2003 struct dc_stream_state *stream, 2004 unsigned int *active_psr_events) 2005 { 2006 struct core_power *core_power = NULL; 2007 unsigned int stream_index = 0; 2008 2009 if (mod_power == NULL) 2010 return false; 2011 2012 core_power = MOD_POWER_TO_CORE(mod_power); 2013 2014 if (core_power->num_entities == 0) 2015 return false; 2016 2017 stream_index = map_index_from_stream(core_power, stream); 2018 2019 if (!core_power->map[stream_index].caps->psr_version) 2020 return false; 2021 2022 *active_psr_events = core_power->map[stream_index].psr_events; 2023 2024 return true; 2025 } 2026 2027 bool mod_power_set_psr_event(struct mod_power *mod_power, 2028 struct dc_stream_state *stream, bool set_event, 2029 enum psr_event event, bool wait) 2030 { 2031 struct core_power *core_power = NULL; 2032 unsigned int stream_index = 0; 2033 unsigned int active_psr_events = 0; 2034 bool psr_enable_request = false; 2035 bool force_static = false; 2036 2037 if (mod_power == NULL || stream == NULL) 2038 return false; 2039 2040 core_power = MOD_POWER_TO_CORE(mod_power); 2041 stream_index = map_index_from_stream(core_power, stream); 2042 2043 if (core_power->num_entities == 0) { 2044 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_ERROR, 2045 WPP_BIT_FLAG_Firmware_PsrState, 2046 "mod_power set_psr_event: ERROR: stream=%p event=%d num_entities=%d", 2047 stream, 2048 (int)event, 2049 core_power->num_entities); 2050 return false; 2051 } 2052 2053 if (!core_power->map[stream_index].caps->psr_version) 2054 return false; 2055 2056 if (set_event) 2057 core_power->map[stream_index].psr_events |= event; 2058 else 2059 core_power->map[stream_index].psr_events &= ~event; 2060 2061 active_psr_events = core_power->map[stream_index].psr_events; 2062 2063 // ignore other events when we're in forced psr enabled state 2064 if (active_psr_events & psr_event_dynamic_display_switch && 2065 event != psr_event_dynamic_display_switch) 2066 return false; 2067 2068 // ignore other events when we're in forced psr enabled state 2069 if (active_psr_events & psr_event_os_override_hold && 2070 event != psr_event_os_override_hold) 2071 return false; 2072 2073 // ignore other events when we're in forced psr enabled state 2074 // dds events need to be processed while in dynamic_link_rate_control 2075 if (active_psr_events & psr_event_dynamic_link_rate_control && 2076 event != psr_event_dynamic_link_rate_control && 2077 event != psr_event_dds_defer_stream_enable && 2078 event != psr_event_dynamic_display_switch) 2079 return false; 2080 2081 if (active_psr_events & (psr_event_test_harness_disable_psr | psr_event_os_request_disable)) 2082 psr_enable_request = false; 2083 else if (active_psr_events & psr_event_pause) 2084 psr_enable_request = false; 2085 else if (active_psr_events & psr_event_test_harness_enable_psr) 2086 psr_enable_request = true; 2087 else if (active_psr_events & psr_event_dynamic_display_switch) { 2088 psr_enable_request = true; 2089 force_static = true; 2090 } else if (active_psr_events & psr_event_dynamic_link_rate_control) { 2091 psr_enable_request = true; 2092 force_static = true; 2093 } else if (active_psr_events & psr_event_edp_panel_off_disable_psr) 2094 psr_enable_request = false; 2095 else if (active_psr_events & (psr_event_hw_programming | 2096 psr_event_defer_enable | 2097 psr_event_dds_defer_stream_enable | 2098 psr_event_vrr_transition | 2099 psr_event_immediate_flip)) 2100 psr_enable_request = false; 2101 else if (active_psr_events & psr_event_big_screen_video) 2102 psr_enable_request = true; 2103 else if (active_psr_events & psr_event_full_screen) 2104 psr_enable_request = false; 2105 else if (active_psr_events & psr_event_mpo_video_selective_update) 2106 psr_enable_request = true; 2107 else if (active_psr_events & psr_event_vsync) 2108 psr_enable_request = false; 2109 else if (active_psr_events & psr_event_crc_window_active) 2110 psr_enable_request = false; 2111 else 2112 psr_enable_request = true; 2113 2114 DC_TRACE_LEVEL_MESSAGE(DAL_TRACE_LEVEL_VERBOSE, 2115 WPP_BIT_FLAG_Firmware_PsrState, 2116 "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", 2117 (int)core_power->map[stream_index].psr_enabled, 2118 (int)set_event, 2119 (unsigned int)event, 2120 (unsigned int)core_power->map[stream_index].psr_events, 2121 (int)psr_enable_request); 2122 mod_power_psr_set_power_opt(mod_power, stream, active_psr_events, psr_enable_request); 2123 2124 if (core_power->map[stream_index].psr_enabled != psr_enable_request || force_static) { 2125 if (set_psr_enable(mod_power, stream, psr_enable_request, wait, force_static)) { 2126 core_power->map[stream_index].psr_enabled = psr_enable_request; 2127 } 2128 } 2129 2130 return true; 2131 } 2132 2133 bool mod_power_get_psr_state(struct mod_power *mod_power, 2134 const struct dc_stream_state *stream, 2135 enum dc_psr_state *state) 2136 { 2137 struct core_power *core_power = NULL; 2138 const struct dc_link *link = NULL; 2139 2140 if (!stream) 2141 return false; 2142 2143 if (mod_power == NULL) 2144 return false; 2145 2146 core_power = MOD_POWER_TO_CORE(mod_power); 2147 2148 if (core_power->num_entities == 0) 2149 return false; 2150 2151 link = dc_stream_get_link(stream); 2152 return dc_link_get_psr_state(link, state); 2153 } 2154 2155 bool mod_power_get_psr_enabled_status(struct mod_power *mod_power, 2156 const struct dc_stream_state *stream, 2157 bool *psr_enabled) 2158 { 2159 struct core_power *core_power = NULL; 2160 unsigned int stream_index = 0; 2161 2162 if (mod_power == NULL) 2163 return false; 2164 2165 core_power = MOD_POWER_TO_CORE(mod_power); 2166 2167 if (core_power->num_entities == 0) 2168 return false; 2169 2170 stream_index = map_index_from_stream(core_power, stream); 2171 2172 if (!core_power->map[stream_index].caps->psr_version) 2173 return false; 2174 2175 *psr_enabled = core_power->map[stream_index].psr_enabled; 2176 2177 return true; 2178 } 2179 2180 void mod_power_psr_residency(struct mod_power *mod_power, 2181 const struct dc_stream_state *stream, 2182 unsigned int *residency, 2183 const uint8_t mode) 2184 { 2185 struct core_power *core_power = NULL; 2186 const struct dc_link *link = NULL; 2187 2188 if (!stream) 2189 return; 2190 2191 if (mod_power == NULL) 2192 return; 2193 2194 core_power = MOD_POWER_TO_CORE(mod_power); 2195 2196 if (core_power->num_entities == 0) 2197 return; 2198 2199 link = dc_stream_get_link(stream); 2200 2201 if (link != NULL) 2202 link->dc->link_srv->edp_get_psr_residency(link, residency, mode); 2203 } 2204 bool mod_power_psr_get_active_psr_events(struct mod_power *mod_power, 2205 const struct dc_stream_state *stream, unsigned int *active_psr_events) 2206 { 2207 struct core_power *core_power = NULL; 2208 unsigned int stream_index = 0; 2209 2210 if (!stream) 2211 return false; 2212 2213 if (mod_power == NULL) 2214 return false; 2215 2216 if (active_psr_events == NULL) 2217 return false; 2218 2219 core_power = MOD_POWER_TO_CORE(mod_power); 2220 2221 if (core_power->num_entities == 0) 2222 return false; 2223 2224 stream_index = map_index_from_stream(core_power, stream); 2225 2226 *active_psr_events = core_power->map[stream_index].psr_events; 2227 return true; 2228 } 2229 2230 bool mod_power_psr_set_sink_vtotal_in_psr_active(struct mod_power *mod_power, 2231 const struct dc_stream_state *stream, 2232 uint16_t psr_vtotal_idle, 2233 uint16_t psr_vtotal_su) 2234 { 2235 struct core_power *core_power = NULL; 2236 unsigned int stream_index = 0; 2237 const struct dc_link *link = NULL; 2238 2239 if (!stream) 2240 return false; 2241 2242 if (mod_power == NULL) 2243 return false; 2244 2245 core_power = MOD_POWER_TO_CORE(mod_power); 2246 2247 if (core_power->num_entities == 0) 2248 return false; 2249 2250 stream_index = map_index_from_stream(core_power, stream); 2251 2252 if (!core_power->map[stream_index].caps->psr_version) 2253 return false; 2254 2255 link = dc_stream_get_link(stream); 2256 2257 return link->dc->link_srv->edp_set_sink_vtotal_in_psr_active( 2258 link, psr_vtotal_idle, psr_vtotal_su); 2259 } 2260 2261 static bool mod_power_set_replay_active(struct dc_stream_state *stream, 2262 bool replay_active, 2263 bool wait, 2264 bool force_static) 2265 { 2266 uint64_t state; 2267 unsigned int retry_count; 2268 const unsigned int max_retry = 1000; 2269 struct dc_link *link = NULL; 2270 2271 if (!stream) 2272 return false; 2273 2274 link = dc_stream_get_link(stream); 2275 2276 if (!link) 2277 return false; 2278 2279 if (!dc_link_set_replay_allow_active(link, &replay_active, false, force_static, NULL)) 2280 return false; 2281 2282 if (wait == true) { 2283 2284 for (retry_count = 0; retry_count <= max_retry; retry_count++) { 2285 dc_link_get_replay_state(link, &state); 2286 if (replay_active) { 2287 if (state != REPLAY_STATE_0 && 2288 (!force_static || state == REPLAY_STATE_3)) 2289 break; 2290 } else { 2291 if (state == REPLAY_STATE_0) 2292 break; 2293 } 2294 udelay(500); 2295 } 2296 2297 /* assert if max retry hit */ 2298 if (retry_count >= max_retry) 2299 ASSERT(0); 2300 } else { 2301 /* To-do: Add trace log */ 2302 } 2303 2304 return true; 2305 } 2306 2307 static unsigned int mod_power_replay_setup_power_opt(struct dc_link *link, 2308 unsigned int active_replay_events, bool is_ultra_sleep_mode) 2309 { 2310 unsigned int power_opt = 0; 2311 2312 if (is_ultra_sleep_mode) { 2313 /* Static Screen */ 2314 power_opt |= (replay_power_opt_smu_opt_static_screen | replay_power_opt_z10_static_screen); 2315 } else if (active_replay_events & replay_event_test_harness_ultra_sleep) { 2316 power_opt |= replay_power_opt_z10_static_screen; 2317 } 2318 2319 /* replay_power_opt_flag is a configuration parameter into the module that determines 2320 * which optimizations to enable during replay 2321 */ 2322 power_opt &= link->replay_settings.config.replay_power_opt_supported; 2323 2324 return power_opt; 2325 } 2326 2327 static bool mod_power_replay_set_power_opt(struct mod_power *mod_power, 2328 struct dc_stream_state *stream, 2329 unsigned int active_replay_events, 2330 bool is_ultra_sleep_mode) 2331 { 2332 (void)mod_power; 2333 struct dc_link *link = NULL; 2334 unsigned int power_opt = 0; 2335 2336 if (!stream) 2337 return false; 2338 2339 link = dc_stream_get_link(stream); 2340 2341 if (!link || !link->replay_settings.replay_feature_enabled) 2342 return false; 2343 2344 power_opt = mod_power_replay_setup_power_opt(link, active_replay_events, is_ultra_sleep_mode); 2345 2346 if (!dc_link_set_replay_allow_active(link, NULL, false, false, &power_opt)) 2347 return false; 2348 2349 return true; 2350 } 2351 2352 bool mod_power_get_replay_event(struct mod_power *mod_power, 2353 struct dc_stream_state *stream, 2354 unsigned int *active_replay_events) 2355 { 2356 struct core_power *core_power = NULL; 2357 unsigned int stream_index = 0; 2358 2359 if (mod_power == NULL) 2360 return false; 2361 2362 core_power = MOD_POWER_TO_CORE(mod_power); 2363 2364 if (core_power->num_entities == 0) 2365 return false; 2366 2367 stream_index = map_index_from_stream(core_power, stream); 2368 2369 *active_replay_events = core_power->map[stream_index].replay_events; 2370 2371 return true; 2372 } 2373 2374 static bool mod_power_update_replay_active_status(unsigned int active_replay_events, 2375 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) 2376 { 2377 if (!link || !coasting_vtotal || !is_full_screen_video || !is_video_playback) 2378 return false; 2379 2380 // Check coasting_vtotal_table has been updated. 2381 if (!link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_STATIC] 2382 || !link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM]) 2383 return false; 2384 2385 unsigned int replay_enable_option = 2386 link->replay_settings.config.replay_enable_option; 2387 2388 /* TODO: To support test harness and DDS event */ 2389 2390 *coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM]; 2391 ASSERT(link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM] <= 0xFFFF); 2392 *frame_skip_number = (uint16_t)link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM]; 2393 2394 link->replay_settings.config.replay_timing_sync_supported = false; 2395 2396 *is_full_screen_video = false; 2397 2398 *is_ultra_sleep_mode = false; 2399 2400 *is_video_playback = false; 2401 2402 /* DSAT test scenario */ 2403 if (active_replay_events & replay_event_test_harness_mode) { 2404 if (link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]) 2405 *coasting_vtotal = 2406 link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]; 2407 if (link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]) { 2408 ASSERT(link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS] <= 0xFFFF); 2409 *frame_skip_number = 2410 (uint16_t)link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]; 2411 } 2412 2413 /* During the ultra sleep mode testing, disable the timing sync in short vblank mode */ 2414 if (active_replay_events & (replay_event_test_harness_enable_replay)) { 2415 if ((active_replay_events & replay_event_test_harness_ultra_sleep) && 2416 !link->replay_settings.config.replay_support_fast_resync_in_ultra_sleep_mode) 2417 link->replay_settings.config.replay_timing_sync_supported = false; 2418 return true; 2419 } else 2420 return false; 2421 } else if (active_replay_events & (replay_event_test_harness_enable_replay)) { 2422 if (link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]) 2423 *coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]; 2424 if (link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]) { 2425 uint32_t frame_skip_val = 2426 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]; 2427 2428 ASSERT(frame_skip_val <= 0xFFFF); 2429 *frame_skip_number = (uint16_t)frame_skip_val; 2430 } 2431 2432 /* During the ultra sleep mode testing, disable the timing sync in short vblank mode */ 2433 if ((active_replay_events & replay_event_test_harness_ultra_sleep) && 2434 !link->replay_settings.config.replay_support_fast_resync_in_ultra_sleep_mode) 2435 link->replay_settings.config.replay_timing_sync_supported = false; 2436 return true; 2437 } else if (active_replay_events & (replay_event_test_harness_disable_replay | replay_event_os_request_disable)) { 2438 // set last set coasting vtotal 2439 if (link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]) 2440 *coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_TEST_HARNESS]; 2441 if (link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]) { 2442 uint32_t frame_skip_val = 2443 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_TEST_HARNESS]; 2444 2445 ASSERT(frame_skip_val <= 0xFFFF); 2446 *frame_skip_number = (uint16_t)frame_skip_val; 2447 } 2448 return false; 2449 } 2450 2451 /* Inactive conditions */ 2452 if (active_replay_events & (replay_event_edp_panel_off_disable_psr | 2453 replay_event_hw_programming | 2454 replay_event_vrr | 2455 replay_event_immediate_flip | 2456 replay_event_prepare_vtotal | 2457 replay_event_vrr_transition | 2458 replay_event_pause | 2459 replay_event_disable_replay_while_DPMS | 2460 replay_event_sleep_resume | 2461 replay_event_disable_in_AC | 2462 replay_event_disable_replay_while_detect_display | 2463 replay_event_infopacket | 2464 replay_event_crc_window_active)) 2465 return false; 2466 2467 // Full screen scenario 2468 if (active_replay_events & replay_event_full_screen) { 2469 if (!(replay_enable_option & pr_enable_option_full_screen)) 2470 return false; 2471 } 2472 2473 /* Full screen video scenario */ 2474 if (active_replay_events & replay_event_big_screen_video) { 2475 2476 link->replay_settings.config.replay_timing_sync_supported = false; 2477 2478 if (replay_enable_option & pr_enable_option_full_screen_video_coasting) { 2479 unsigned int fsn_vid = 2480 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_FULL_SCREEN_VIDEO]; 2481 2482 *coasting_vtotal = 2483 link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_FULL_SCREEN_VIDEO]; 2484 ASSERT(fsn_vid <= 0xFFFF); 2485 *frame_skip_number = (uint16_t)fsn_vid; 2486 } 2487 2488 *is_video_playback = true; 2489 2490 if ((replay_enable_option & pr_enable_option_full_screen_video) && 2491 (replay_enable_option & pr_enable_option_full_screen_video_coasting)) { 2492 *is_full_screen_video = true; 2493 return true; 2494 } else 2495 return false; 2496 } 2497 2498 /* MPO video scenario 2499 * Some of the cases may contain a full screen UI layer in MPO video scenario which is 2500 * not the expected case to enable Replay. 2501 */ 2502 if ((active_replay_events & replay_event_mpo_video_selective_update) && 2503 !(active_replay_events & replay_event_full_screen)) { 2504 2505 link->replay_settings.config.replay_timing_sync_supported = false; 2506 2507 if (replay_enable_option & pr_enable_option_mpo_video_coasting) { 2508 *coasting_vtotal = link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM]; 2509 { 2510 uint32_t frame_skip_val = 2511 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM]; 2512 2513 ASSERT(frame_skip_val <= 0xFFFF); 2514 *frame_skip_number = (uint16_t)frame_skip_val; 2515 } 2516 } 2517 2518 *is_video_playback = true; 2519 2520 if (replay_enable_option & pr_enable_option_mpo_video) 2521 return true; 2522 else 2523 return false; 2524 } 2525 2526 /* Static screen scenario */ 2527 if (!(active_replay_events & replay_event_vsync)) { 2528 2529 if (replay_enable_option & pr_enable_option_static_screen_coasting) { 2530 // Do not adjust eDP refresh rate if static screen + normal sleep mode 2531 if ((!(link->replay_settings.config.replay_power_opt_supported & 2532 replay_power_opt_z10_static_screen)) || 2533 (active_replay_events & replay_event_cursor_updating)) { 2534 // normal sleep mode 2535 *coasting_vtotal = 2536 link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_NOM]; 2537 { 2538 uint32_t frame_skip_val = 2539 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_NOM]; 2540 2541 ASSERT(frame_skip_val <= 0xFFFF); 2542 *frame_skip_number = (uint16_t)frame_skip_val; 2543 } 2544 } else { 2545 // ultra sleep mode 2546 *coasting_vtotal = 2547 link->replay_settings.coasting_vtotal_table[PR_COASTING_TYPE_STATIC]; 2548 { 2549 uint32_t frame_skip_val = 2550 link->replay_settings.frame_skip_number_table[PR_COASTING_TYPE_STATIC]; 2551 2552 ASSERT(frame_skip_val <= 0xFFFF); 2553 *frame_skip_number = (uint16_t)frame_skip_val; 2554 } 2555 *is_ultra_sleep_mode = true; 2556 } 2557 } 2558 2559 if (replay_enable_option & pr_enable_option_static_screen) { 2560 if (!link->replay_settings.config.replay_support_fast_resync_in_ultra_sleep_mode) 2561 link->replay_settings.config.replay_timing_sync_supported = false; 2562 return true; 2563 } else 2564 return false; 2565 } 2566 2567 /* General UI scenario */ 2568 if (active_replay_events & replay_event_general_ui) { 2569 if (replay_enable_option & pr_enable_option_general_ui) 2570 return true; 2571 else 2572 return false; 2573 } 2574 2575 return false; 2576 } 2577 2578 bool mod_power_replay_set_coasting_vtotal(struct mod_power *mod_power, 2579 const struct dc_stream_state *stream, 2580 uint32_t coasting_vtotal, 2581 uint16_t frame_skip_number) 2582 { 2583 struct core_power *core_power = NULL; 2584 struct dc_link *link = NULL; 2585 2586 if (!stream) 2587 return false; 2588 2589 link = dc_stream_get_link(stream); 2590 if (!link || !link->replay_settings.replay_feature_enabled) 2591 return false; 2592 2593 if (mod_power == NULL) 2594 return false; 2595 2596 core_power = MOD_POWER_TO_CORE(mod_power); 2597 2598 if (core_power->num_entities == 0) 2599 return false; 2600 2601 return link->dc->link_srv->edp_set_coasting_vtotal(link, coasting_vtotal, frame_skip_number); 2602 } 2603 2604 void mod_power_replay_set_timing_sync_supported(struct mod_power *mod_power, 2605 const struct dc_stream_state *stream) 2606 { 2607 struct core_power *core_power = NULL; 2608 struct dc_link *link = NULL; 2609 unsigned int stream_index = 0; 2610 union dmub_replay_cmd_set cmd_data = { 0 }; 2611 2612 if (!stream || mod_power == NULL) 2613 return; 2614 2615 core_power = MOD_POWER_TO_CORE(mod_power); 2616 if (core_power->num_entities == 0) 2617 return; 2618 2619 stream_index = map_index_from_stream(core_power, stream); 2620 if (stream_index > core_power->num_entities) //invalid index 2621 return; 2622 2623 link = dc_stream_get_link(stream); 2624 if (!link || !link->replay_settings.replay_feature_enabled) 2625 return; 2626 2627 cmd_data.sync_data.timing_sync_supported = link->replay_settings.config.replay_timing_sync_supported; 2628 2629 link->dc->link_srv->edp_send_replay_cmd(link, Replay_Set_Timing_Sync_Supported, 2630 &cmd_data); 2631 } 2632 2633 void mod_power_replay_disabled_adaptive_sync_sdp(struct mod_power *mod_power, 2634 const struct dc_stream_state *stream, bool force_disabled) 2635 { 2636 struct core_power *core_power = NULL; 2637 struct dc_link *link = NULL; 2638 unsigned int stream_index = 0; 2639 union dmub_replay_cmd_set cmd_data = { 0 }; 2640 2641 if (!stream || mod_power == NULL) 2642 return; 2643 2644 core_power = MOD_POWER_TO_CORE(mod_power); 2645 if (core_power->num_entities == 0) 2646 return; 2647 2648 stream_index = map_index_from_stream(core_power, stream); 2649 if (stream_index > core_power->num_entities) //invalid index 2650 return; 2651 2652 link = dc_stream_get_link(stream); 2653 if (!link || !link->replay_settings.replay_feature_enabled) 2654 return; 2655 2656 cmd_data.disabled_adaptive_sync_sdp_data.force_disabled = force_disabled; 2657 2658 link->dc->link_srv->edp_send_replay_cmd(link, Replay_Disabled_Adaptive_Sync_SDP, 2659 &cmd_data); 2660 } 2661 2662 static void mod_power_replay_set_general_cmd(struct mod_power *mod_power, 2663 const struct dc_stream_state *stream, 2664 const enum dmub_cmd_replay_general_subtype general_cmd_type, 2665 const uint32_t param1, const uint32_t param2) 2666 { 2667 struct core_power *core_power = NULL; 2668 struct dc_link *link = NULL; 2669 unsigned int stream_index = 0; 2670 union dmub_replay_cmd_set cmd_data = { 0 }; 2671 2672 if (!stream || mod_power == NULL) 2673 return; 2674 2675 core_power = MOD_POWER_TO_CORE(mod_power); 2676 if (core_power->num_entities == 0) 2677 return; 2678 2679 stream_index = map_index_from_stream(core_power, stream); 2680 if (stream_index > core_power->num_entities) //invalid index 2681 return; 2682 2683 link = dc_stream_get_link(stream); 2684 if (!link || !link->replay_settings.replay_feature_enabled) 2685 return; 2686 2687 cmd_data.set_general_cmd_data.subtype = general_cmd_type; 2688 cmd_data.set_general_cmd_data.param1 = param1; 2689 cmd_data.set_general_cmd_data.param2 = param2; 2690 link->dc->link_srv->edp_send_replay_cmd(link, Replay_Set_General_Cmd, 2691 &cmd_data); 2692 } 2693 2694 void mod_power_replay_disabled_desync_error_detection(struct mod_power *mod_power, 2695 const struct dc_stream_state *stream, bool force_disabled) 2696 { 2697 mod_power_replay_set_general_cmd(mod_power, stream, 2698 REPLAY_GENERAL_CMD_DISABLED_DESYNC_ERROR_DETECTION, 2699 force_disabled, 0); 2700 } 2701 2702 static void mod_power_replay_set_pseudo_vtotal(struct mod_power *mod_power, 2703 const struct dc_stream_state *stream, uint16_t vtotal) 2704 { 2705 struct core_power *core_power = NULL; 2706 struct dc_link *link = NULL; 2707 unsigned int stream_index = 0; 2708 union dmub_replay_cmd_set cmd_data = { 0 }; 2709 2710 if (!stream || mod_power == NULL) 2711 return; 2712 2713 core_power = MOD_POWER_TO_CORE(mod_power); 2714 if (core_power->num_entities == 0) 2715 return; 2716 2717 stream_index = map_index_from_stream(core_power, stream); 2718 if (stream_index > core_power->num_entities) //invalid index 2719 return; 2720 2721 link = dc_stream_get_link(stream); 2722 if (!link || !link->replay_settings.replay_feature_enabled) 2723 return; 2724 2725 cmd_data.pseudo_vtotal_data.vtotal = vtotal; 2726 2727 if (link->replay_settings.last_pseudo_vtotal != vtotal) { 2728 link->replay_settings.last_pseudo_vtotal = vtotal; 2729 link->dc->link_srv->edp_send_replay_cmd(link, Replay_Set_Pseudo_VTotal, &cmd_data); 2730 } 2731 } 2732 2733 static void mod_power_update_error_status(struct mod_power *mod_power, 2734 const struct dc_stream_state *stream) 2735 { 2736 struct dc_link *link = NULL; 2737 union replay_debug_flags *pDebug = NULL; 2738 2739 if (mod_power == NULL || stream == NULL) 2740 return; 2741 2742 link = dc_stream_get_link(stream); 2743 2744 if (!link) 2745 return; 2746 2747 pDebug = (union replay_debug_flags *)&link->replay_settings.config.debug_flags; 2748 2749 if (0 == pDebug->bitfields.enable_visual_confirm_debug) 2750 return; 2751 2752 mod_power_replay_set_general_cmd(mod_power, stream, 2753 REPLAY_GENERAL_CMD_UPDATE_ERROR_STATUS, 2754 link->replay_settings.config.replay_error_status.raw, 0); 2755 } 2756 2757 void mod_power_set_low_rr_activate(struct mod_power *mod_power, 2758 const struct dc_stream_state *stream, bool low_rr_supported) 2759 { 2760 struct dc_link *link = NULL; 2761 2762 if (mod_power == NULL || stream == NULL) 2763 return; 2764 2765 link = dc_stream_get_link(stream); 2766 2767 if (!link) 2768 return; 2769 2770 mod_power_replay_set_general_cmd(mod_power, stream, 2771 REPLAY_GENERAL_CMD_SET_LOW_RR_ACTIVATE, 2772 low_rr_supported, 0); 2773 } 2774 2775 void mod_power_set_video_conferencing_activate(struct mod_power *mod_power, 2776 const struct dc_stream_state *stream, bool video_conferencing_activate) 2777 { 2778 struct dc_link *link = NULL; 2779 2780 if (mod_power == NULL || stream == NULL) 2781 return; 2782 2783 link = dc_stream_get_link(stream); 2784 if (!link || !link->replay_settings.replay_feature_enabled) 2785 return; 2786 2787 mod_power_replay_set_general_cmd(mod_power, stream, 2788 REPLAY_GENERAL_CMD_VIDEO_CONFERENCING, 2789 video_conferencing_activate, 0); 2790 } 2791 2792 void mod_power_set_coasting_vtotal_without_frame_update(struct mod_power *mod_power, 2793 const struct dc_stream_state *stream, uint32_t coasting_vtotal) 2794 { 2795 struct dc_link *link = NULL; 2796 2797 if (mod_power == NULL || stream == NULL) 2798 return; 2799 2800 link = dc_stream_get_link(stream); 2801 if (!link || !link->replay_settings.replay_feature_enabled) 2802 return; 2803 2804 mod_power_replay_set_general_cmd(mod_power, stream, 2805 REPLAY_GENERAL_CMD_SET_COASTING_VTOTAL_WITHOUT_FRAME_UPDATE, 2806 coasting_vtotal, 0); 2807 } 2808 2809 void mod_power_set_replay_continuously_resync(struct mod_power *mod_power, 2810 const struct dc_stream_state *stream, bool enable) 2811 { 2812 struct dc_link *link = NULL; 2813 2814 if (mod_power == NULL || stream == NULL) 2815 return; 2816 2817 link = dc_stream_get_link(stream); 2818 if (!link || !link->replay_settings.replay_feature_enabled) 2819 return; 2820 2821 mod_power_replay_set_general_cmd(mod_power, stream, 2822 REPLAY_GENERAL_CMD_SET_CONTINUOUSLY_RESYNC, 2823 enable, 0); 2824 } 2825 2826 void mod_power_set_live_capture_with_cvt_activate(struct mod_power *mod_power, 2827 const struct dc_stream_state *stream, bool live_capture_with_cvt_activate) 2828 { 2829 struct dc_link *link = NULL; 2830 2831 if (mod_power == NULL || stream == NULL) 2832 return; 2833 2834 link = dc_stream_get_link(stream); 2835 if (!link || !link->replay_settings.replay_feature_enabled) 2836 return; 2837 2838 // Check if LIVE_CAPTURE_WITH_CVT bit is enabled in DalRegKey_ReplayOptimization 2839 if (!link->replay_settings.config.replay_optimization.bits.LIVE_CAPTURE_WITH_CVT) 2840 return; 2841 2842 if (link->replay_settings.config.live_capture_with_cvt_activated != live_capture_with_cvt_activate) { 2843 link->replay_settings.config.live_capture_with_cvt_activated = live_capture_with_cvt_activate; 2844 mod_power_replay_set_general_cmd(mod_power, stream, 2845 REPLAY_GENERAL_CMD_LIVE_CAPTURE_WITH_CVT, 2846 live_capture_with_cvt_activate, 0); 2847 } 2848 } 2849 2850 bool mod_power_set_replay_event(struct mod_power *mod_power, 2851 struct dc_stream_state *stream, bool set_event, 2852 enum replay_event event, bool wait_for_disable) 2853 { 2854 struct core_power *core_power = NULL; 2855 struct dc_link *link = NULL; 2856 unsigned int stream_index = 0; 2857 unsigned int active_replay_events = 0; 2858 bool replay_active_request = false; 2859 bool force_static = false; 2860 uint32_t coasting_vtotal = 0; 2861 bool current_timing_sync_status = false; 2862 bool is_full_screen_video = false; 2863 bool is_ultra_sleep_mode = false; 2864 unsigned int sink_duration_us = 0; 2865 bool low_rr_active = false; 2866 uint16_t frame_skip_number = 0; 2867 bool is_video_playback = false; 2868 2869 if (!stream) 2870 return false; 2871 2872 if (mod_power == NULL) 2873 return false; 2874 2875 core_power = MOD_POWER_TO_CORE(mod_power); 2876 2877 if (core_power->num_entities == 0) 2878 return false; 2879 2880 stream_index = map_index_from_stream(core_power, stream); 2881 2882 if (set_event) 2883 core_power->map[stream_index].replay_events |= event; 2884 else 2885 core_power->map[stream_index].replay_events &= ~event; 2886 2887 link = dc_stream_get_link(stream); 2888 if (!link || !link->replay_settings.replay_feature_enabled) 2889 return false; 2890 2891 if ((core_power->map[stream_index].replay_events & replay_event_disable_replay_while_switching_mux) != 0) 2892 return false; 2893 2894 if ((core_power->map[stream_index].replay_events & replay_event_os_override_hold) != 0) 2895 return false; 2896 2897 active_replay_events = core_power->map[stream_index].replay_events; 2898 2899 current_timing_sync_status = 2900 link->replay_settings.config.replay_timing_sync_supported; 2901 2902 replay_active_request = mod_power_update_replay_active_status(active_replay_events, 2903 link, &coasting_vtotal, &is_full_screen_video, &is_ultra_sleep_mode, &frame_skip_number, &is_video_playback); 2904 2905 if (is_full_screen_video) 2906 mod_power_replay_set_pseudo_vtotal(mod_power, stream, 2907 link->replay_settings.low_rr_full_screen_video_pseudo_vtotal); 2908 else 2909 mod_power_replay_set_pseudo_vtotal(mod_power, stream, 0); 2910 2911 //If timing_sync_status change, then re-enabled set timing_sync_supported value and re-enabled replay 2912 if (current_timing_sync_status != link->replay_settings.config.replay_timing_sync_supported) 2913 mod_power_replay_set_timing_sync_supported(mod_power, stream); 2914 2915 if (link->replay_settings.config.low_rr_supported) { 2916 sink_duration_us = 2917 (unsigned int)(div_u64(((unsigned long long)(coasting_vtotal) 2918 * 10000) * stream->timing.h_total, 2919 stream->timing.pix_clk_100hz)); 2920 low_rr_active = sink_duration_us < LOW_REFRESH_RATE_DURATION_US_UPPER_BOUND ? false : true; 2921 if (low_rr_active != link->replay_settings.config.low_rr_activated) { 2922 mod_power_set_low_rr_activate(mod_power, stream, low_rr_active); 2923 link->replay_settings.config.low_rr_activated = low_rr_active; 2924 } 2925 } 2926 2927 // The function return fail when 2928 // 1. DMUB function is not support (for backward compatible). 2929 // 2. active_replay_events or coasting_vtotal is not updated in the same time 2930 if (!mod_power_replay_set_power_opt_and_coasting_vtotal(mod_power, 2931 stream, active_replay_events, coasting_vtotal, is_ultra_sleep_mode, frame_skip_number)) { 2932 if (!mod_power_replay_set_power_opt(mod_power, stream, active_replay_events, is_ultra_sleep_mode)) 2933 return false; 2934 2935 if (!mod_power_replay_set_coasting_vtotal(mod_power, stream, coasting_vtotal, frame_skip_number)) 2936 return false; 2937 } 2938 2939 mod_power_set_live_capture_with_cvt_activate(mod_power, stream, is_video_playback); 2940 2941 mod_power_update_error_status(mod_power, stream); 2942 2943 // If Replay is going to be enable (No matter is disable -> enable or enable -> enable), we don't need to wait. 2944 // If Replay is going to be disable 2945 // if disable -> disable 2946 // -> Replay DMUB state should be state 0. 2947 // So no matter wait_for_disable is true or not, it should makes no difference. 2948 // if enable -> disable -> We should wait if wait_for_disable is true. 2949 if (replay_active_request) 2950 wait_for_disable = false; 2951 2952 if (!mod_power_set_replay_active(stream, replay_active_request, wait_for_disable, force_static)) 2953 return false; 2954 2955 return true; 2956 } 2957 2958 bool mod_power_get_replay_active_status(const struct dc_stream_state *stream, 2959 bool *replay_active) 2960 { 2961 const struct dc_link *link = NULL; 2962 2963 if (!stream) 2964 return false; 2965 2966 link = dc_stream_get_link(stream); 2967 *replay_active = link->replay_settings.replay_allow_active; 2968 2969 return true; 2970 } 2971 2972 void mod_power_replay_residency(const struct dc_stream_state *stream, 2973 unsigned int *residency, const bool is_start, const bool is_alpm) 2974 { 2975 const struct dc_link *link = NULL; 2976 enum pr_residency_mode mode; 2977 2978 if (!stream) 2979 return; 2980 2981 link = dc_stream_get_link(stream); 2982 2983 if (is_alpm) 2984 mode = PR_RESIDENCY_MODE_ALPM; 2985 else 2986 mode = PR_RESIDENCY_MODE_PHY; 2987 2988 if (link && link->dc && link->dc->link_srv) 2989 link->dc->link_srv->edp_replay_residency(link, residency, is_start, mode); 2990 } 2991 2992 bool mod_power_replay_set_power_opt_and_coasting_vtotal(struct mod_power *mod_power, 2993 const struct dc_stream_state *stream, unsigned int active_replay_events, uint32_t coasting_vtotal, 2994 bool is_ultra_sleep_mode, uint16_t frame_skip_number) 2995 { 2996 struct core_power *core_power = NULL; 2997 struct dc_link *link = NULL; 2998 unsigned int power_opt = 0; 2999 3000 if (!stream) 3001 return false; 3002 3003 if (mod_power == NULL) 3004 return false; 3005 3006 core_power = MOD_POWER_TO_CORE(mod_power); 3007 3008 if (core_power->num_entities == 0) 3009 return false; 3010 3011 link = dc_stream_get_link(stream); 3012 3013 if (!link || !link->replay_settings.replay_feature_enabled) 3014 return false; 3015 3016 power_opt = mod_power_replay_setup_power_opt(link, active_replay_events, is_ultra_sleep_mode); 3017 3018 return link->dc->link_srv->edp_set_replay_power_opt_and_coasting_vtotal(link, &power_opt, coasting_vtotal, frame_skip_number); 3019 } 3020 3021 3022 3023 3024 3025