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