1 /* 2 * Copyright 2015 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 "dc_bios_types.h" 29 #include "core_types.h" 30 #include "core_status.h" 31 #include "resource.h" 32 #include "dm_helpers.h" 33 #include "dce110_hwseq.h" 34 #include "dce110/dce110_timing_generator.h" 35 #include "dce/dce_hwseq.h" 36 #include "dce100/dce100_hwseq.h" 37 #include "gpio_service_interface.h" 38 39 #include "dce110/dce110_compressor.h" 40 41 #include "bios/bios_parser_helper.h" 42 #include "timing_generator.h" 43 #include "mem_input.h" 44 #include "opp.h" 45 #include "ipp.h" 46 #include "transform.h" 47 #include "stream_encoder.h" 48 #include "link_encoder.h" 49 #include "link_enc_cfg.h" 50 #include "link_hwss.h" 51 #include "link.h" 52 #include "dccg.h" 53 #include "clock_source.h" 54 #include "clk_mgr.h" 55 #include "abm.h" 56 #include "audio.h" 57 #include "reg_helper.h" 58 #include "panel_cntl.h" 59 #include "dc_state_priv.h" 60 #include "dpcd_defs.h" 61 #include "dsc.h" 62 /* include DCE11 register header files */ 63 #include "dce/dce_11_0_d.h" 64 #include "dce/dce_11_0_sh_mask.h" 65 #include "custom_float.h" 66 67 #include "atomfirmware.h" 68 69 #include "dcn10/dcn10_hwseq.h" 70 71 #define GAMMA_HW_POINTS_NUM 256 72 73 /* 74 * All values are in milliseconds; 75 * For eDP, after power-up/power/down, 76 * 300/500 msec max. delay from LCDVCC to black video generation 77 */ 78 #define PANEL_POWER_UP_TIMEOUT 300 79 #define PANEL_POWER_DOWN_TIMEOUT 500 80 #define HPD_CHECK_INTERVAL 10 81 #define OLED_POST_T7_DELAY 100 82 #define OLED_PRE_T11_DELAY 150 83 84 #define CTX \ 85 hws->ctx 86 87 #define DC_LOGGER \ 88 ctx->logger 89 #define DC_LOGGER_INIT() \ 90 struct dc_context *ctx = dc->ctx 91 92 #define REG(reg)\ 93 hws->regs->reg 94 95 #undef FN 96 #define FN(reg_name, field_name) \ 97 hws->shifts->field_name, hws->masks->field_name 98 99 struct dce110_hw_seq_reg_offsets { 100 uint32_t crtc; 101 }; 102 103 static const struct dce110_hw_seq_reg_offsets reg_offsets[] = { 104 { 105 .crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 106 }, 107 { 108 .crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 109 }, 110 { 111 .crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC_GSL_CONTROL), 112 }, 113 { 114 .crtc = (mmCRTCV_GSL_CONTROL - mmCRTC_GSL_CONTROL), 115 } 116 }; 117 118 #define HW_REG_BLND(reg, id)\ 119 (reg + reg_offsets[id].blnd) 120 121 #define HW_REG_CRTC(reg, id)\ 122 (reg + reg_offsets[id].crtc) 123 124 #define MAX_WATERMARK 0xFFFF 125 #define SAFE_NBP_MARK 0x7FFF 126 127 /******************************************************************************* 128 * Private definitions 129 ******************************************************************************/ 130 /***************************PIPE_CONTROL***********************************/ 131 static void dce110_init_pte(struct dc_context *ctx) 132 { 133 uint32_t addr; 134 uint32_t value = 0; 135 uint32_t chunk_int = 0; 136 uint32_t chunk_mul = 0; 137 138 addr = mmUNP_DVMM_PTE_CONTROL; 139 value = dm_read_reg(ctx, addr); 140 141 set_reg_field_value( 142 value, 143 0, 144 DVMM_PTE_CONTROL, 145 DVMM_USE_SINGLE_PTE); 146 147 set_reg_field_value( 148 value, 149 1, 150 DVMM_PTE_CONTROL, 151 DVMM_PTE_BUFFER_MODE0); 152 153 set_reg_field_value( 154 value, 155 1, 156 DVMM_PTE_CONTROL, 157 DVMM_PTE_BUFFER_MODE1); 158 159 dm_write_reg(ctx, addr, value); 160 161 addr = mmDVMM_PTE_REQ; 162 value = dm_read_reg(ctx, addr); 163 164 chunk_int = get_reg_field_value( 165 value, 166 DVMM_PTE_REQ, 167 HFLIP_PTEREQ_PER_CHUNK_INT); 168 169 chunk_mul = get_reg_field_value( 170 value, 171 DVMM_PTE_REQ, 172 HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 173 174 if (chunk_int != 0x4 || chunk_mul != 0x4) { 175 176 set_reg_field_value( 177 value, 178 255, 179 DVMM_PTE_REQ, 180 MAX_PTEREQ_TO_ISSUE); 181 182 set_reg_field_value( 183 value, 184 4, 185 DVMM_PTE_REQ, 186 HFLIP_PTEREQ_PER_CHUNK_INT); 187 188 set_reg_field_value( 189 value, 190 4, 191 DVMM_PTE_REQ, 192 HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER); 193 194 dm_write_reg(ctx, addr, value); 195 } 196 } 197 /**************************************************************************/ 198 199 static void enable_display_pipe_clock_gating( 200 struct dc_context *ctx, 201 bool clock_gating) 202 { 203 /*TODO*/ 204 } 205 206 static bool dce110_enable_display_power_gating( 207 struct dc *dc, 208 uint8_t controller_id, 209 struct dc_bios *dcb, 210 enum pipe_gating_control power_gating) 211 { 212 enum bp_result bp_result = BP_RESULT_OK; 213 enum bp_pipe_control_action cntl; 214 struct dc_context *ctx = dc->ctx; 215 unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 216 217 if (power_gating == PIPE_GATING_CONTROL_INIT) 218 cntl = ASIC_PIPE_INIT; 219 else if (power_gating == PIPE_GATING_CONTROL_ENABLE) 220 cntl = ASIC_PIPE_ENABLE; 221 else 222 cntl = ASIC_PIPE_DISABLE; 223 224 if (controller_id == underlay_idx) 225 controller_id = CONTROLLER_ID_UNDERLAY0 - 1; 226 227 if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) { 228 229 bp_result = dcb->funcs->enable_disp_power_gating( 230 dcb, controller_id + 1, cntl); 231 232 /* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2 233 * by default when command table is called 234 * 235 * Bios parser accepts controller_id = 6 as indicative of 236 * underlay pipe in dce110. But we do not support more 237 * than 3. 238 */ 239 if (controller_id < CONTROLLER_ID_MAX - 1) 240 dm_write_reg(ctx, 241 HW_REG_CRTC(mmCRTC_MASTER_UPDATE_MODE, controller_id), 242 0); 243 } 244 245 if (power_gating != PIPE_GATING_CONTROL_ENABLE) 246 dce110_init_pte(ctx); 247 248 if (bp_result == BP_RESULT_OK) 249 return true; 250 else 251 return false; 252 } 253 254 static void dce110_prescale_params(struct ipp_prescale_params *prescale_params, 255 const struct dc_plane_state *plane_state) 256 { 257 prescale_params->mode = IPP_PRESCALE_MODE_FIXED_UNSIGNED; 258 259 switch (plane_state->format) { 260 case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 261 prescale_params->scale = 0x2082; 262 break; 263 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 264 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 265 prescale_params->scale = 0x2020; 266 break; 267 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 268 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 269 prescale_params->scale = 0x2008; 270 break; 271 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 272 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: 273 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 274 prescale_params->scale = 0x2000; 275 break; 276 default: 277 ASSERT(false); 278 break; 279 } 280 } 281 282 static bool 283 dce110_set_input_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, 284 const struct dc_plane_state *plane_state) 285 { 286 struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 287 const struct dc_transfer_func *tf = NULL; 288 struct ipp_prescale_params prescale_params = { 0 }; 289 bool result = true; 290 291 if (ipp == NULL) 292 return false; 293 294 tf = &plane_state->in_transfer_func; 295 296 dce110_prescale_params(&prescale_params, plane_state); 297 ipp->funcs->ipp_program_prescale(ipp, &prescale_params); 298 299 if (!plane_state->gamma_correction.is_identity && 300 dce_use_lut(plane_state->format)) 301 ipp->funcs->ipp_program_input_lut(ipp, &plane_state->gamma_correction); 302 303 if (tf->type == TF_TYPE_PREDEFINED) { 304 switch (tf->tf) { 305 case TRANSFER_FUNCTION_SRGB: 306 ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_sRGB); 307 break; 308 case TRANSFER_FUNCTION_BT709: 309 ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_HW_xvYCC); 310 break; 311 case TRANSFER_FUNCTION_LINEAR: 312 ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 313 break; 314 case TRANSFER_FUNCTION_PQ: 315 default: 316 result = false; 317 break; 318 } 319 } else if (tf->type == TF_TYPE_BYPASS) { 320 ipp->funcs->ipp_set_degamma(ipp, IPP_DEGAMMA_MODE_BYPASS); 321 } else { 322 /*TF_TYPE_DISTRIBUTED_POINTS - Not supported in DCE 11*/ 323 result = false; 324 } 325 326 return result; 327 } 328 329 static bool convert_to_custom_float(struct pwl_result_data *rgb_resulted, 330 struct curve_points *arr_points, 331 uint32_t hw_points_num) 332 { 333 struct custom_float_format fmt; 334 335 struct pwl_result_data *rgb = rgb_resulted; 336 337 uint32_t i = 0; 338 339 fmt.exponenta_bits = 6; 340 fmt.mantissa_bits = 12; 341 fmt.sign = true; 342 343 if (!convert_to_custom_float_format(arr_points[0].x, &fmt, 344 &arr_points[0].custom_float_x)) { 345 BREAK_TO_DEBUGGER(); 346 return false; 347 } 348 349 if (!convert_to_custom_float_format(arr_points[0].offset, &fmt, 350 &arr_points[0].custom_float_offset)) { 351 BREAK_TO_DEBUGGER(); 352 return false; 353 } 354 355 if (!convert_to_custom_float_format(arr_points[0].slope, &fmt, 356 &arr_points[0].custom_float_slope)) { 357 BREAK_TO_DEBUGGER(); 358 return false; 359 } 360 361 fmt.mantissa_bits = 10; 362 fmt.sign = false; 363 364 if (!convert_to_custom_float_format(arr_points[1].x, &fmt, 365 &arr_points[1].custom_float_x)) { 366 BREAK_TO_DEBUGGER(); 367 return false; 368 } 369 370 if (!convert_to_custom_float_format(arr_points[1].y, &fmt, 371 &arr_points[1].custom_float_y)) { 372 BREAK_TO_DEBUGGER(); 373 return false; 374 } 375 376 if (!convert_to_custom_float_format(arr_points[1].slope, &fmt, 377 &arr_points[1].custom_float_slope)) { 378 BREAK_TO_DEBUGGER(); 379 return false; 380 } 381 382 fmt.mantissa_bits = 12; 383 fmt.sign = true; 384 385 while (i != hw_points_num) { 386 if (!convert_to_custom_float_format(rgb->red, &fmt, 387 &rgb->red_reg)) { 388 BREAK_TO_DEBUGGER(); 389 return false; 390 } 391 392 if (!convert_to_custom_float_format(rgb->green, &fmt, 393 &rgb->green_reg)) { 394 BREAK_TO_DEBUGGER(); 395 return false; 396 } 397 398 if (!convert_to_custom_float_format(rgb->blue, &fmt, 399 &rgb->blue_reg)) { 400 BREAK_TO_DEBUGGER(); 401 return false; 402 } 403 404 if (!convert_to_custom_float_format(rgb->delta_red, &fmt, 405 &rgb->delta_red_reg)) { 406 BREAK_TO_DEBUGGER(); 407 return false; 408 } 409 410 if (!convert_to_custom_float_format(rgb->delta_green, &fmt, 411 &rgb->delta_green_reg)) { 412 BREAK_TO_DEBUGGER(); 413 return false; 414 } 415 416 if (!convert_to_custom_float_format(rgb->delta_blue, &fmt, 417 &rgb->delta_blue_reg)) { 418 BREAK_TO_DEBUGGER(); 419 return false; 420 } 421 422 ++rgb; 423 ++i; 424 } 425 426 return true; 427 } 428 429 #define MAX_LOW_POINT 25 430 #define NUMBER_REGIONS 16 431 #define NUMBER_SW_SEGMENTS 16 432 433 static bool 434 dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf, 435 struct pwl_params *regamma_params) 436 { 437 struct curve_points *arr_points; 438 struct pwl_result_data *rgb_resulted; 439 struct pwl_result_data *rgb; 440 struct pwl_result_data *rgb_plus_1; 441 struct fixed31_32 y_r; 442 struct fixed31_32 y_g; 443 struct fixed31_32 y_b; 444 struct fixed31_32 y1_min; 445 struct fixed31_32 y3_max; 446 447 int32_t region_start, region_end; 448 uint32_t i, j, k, seg_distr[NUMBER_REGIONS], increment, start_index, hw_points; 449 450 if (output_tf == NULL || regamma_params == NULL || output_tf->type == TF_TYPE_BYPASS) 451 return false; 452 453 arr_points = regamma_params->arr_points; 454 rgb_resulted = regamma_params->rgb_resulted; 455 hw_points = 0; 456 457 memset(regamma_params, 0, sizeof(struct pwl_params)); 458 459 if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 460 /* 16 segments 461 * segments are from 2^-11 to 2^5 462 */ 463 region_start = -11; 464 region_end = region_start + NUMBER_REGIONS; 465 466 for (i = 0; i < NUMBER_REGIONS; i++) 467 seg_distr[i] = 4; 468 469 } else { 470 /* 10 segments 471 * segment is from 2^-10 to 2^1 472 * We include an extra segment for range [2^0, 2^1). This is to 473 * ensure that colors with normalized values of 1 don't miss the 474 * LUT. 475 */ 476 region_start = -10; 477 region_end = 1; 478 479 seg_distr[0] = 4; 480 seg_distr[1] = 4; 481 seg_distr[2] = 4; 482 seg_distr[3] = 4; 483 seg_distr[4] = 4; 484 seg_distr[5] = 4; 485 seg_distr[6] = 4; 486 seg_distr[7] = 4; 487 seg_distr[8] = 4; 488 seg_distr[9] = 4; 489 seg_distr[10] = 0; 490 seg_distr[11] = -1; 491 seg_distr[12] = -1; 492 seg_distr[13] = -1; 493 seg_distr[14] = -1; 494 seg_distr[15] = -1; 495 } 496 497 for (k = 0; k < 16; k++) { 498 if (seg_distr[k] != -1) 499 hw_points += (1 << seg_distr[k]); 500 } 501 502 j = 0; 503 for (k = 0; k < (region_end - region_start); k++) { 504 increment = NUMBER_SW_SEGMENTS / (1 << seg_distr[k]); 505 start_index = (region_start + k + MAX_LOW_POINT) * 506 NUMBER_SW_SEGMENTS; 507 for (i = start_index; i < start_index + NUMBER_SW_SEGMENTS; 508 i += increment) { 509 if (j == hw_points - 1) 510 break; 511 rgb_resulted[j].red = output_tf->tf_pts.red[i]; 512 rgb_resulted[j].green = output_tf->tf_pts.green[i]; 513 rgb_resulted[j].blue = output_tf->tf_pts.blue[i]; 514 j++; 515 } 516 } 517 518 /* last point */ 519 start_index = (region_end + MAX_LOW_POINT) * NUMBER_SW_SEGMENTS; 520 rgb_resulted[hw_points - 1].red = output_tf->tf_pts.red[start_index]; 521 rgb_resulted[hw_points - 1].green = output_tf->tf_pts.green[start_index]; 522 rgb_resulted[hw_points - 1].blue = output_tf->tf_pts.blue[start_index]; 523 524 arr_points[0].x = dc_fixpt_pow(dc_fixpt_from_int(2), 525 dc_fixpt_from_int(region_start)); 526 arr_points[1].x = dc_fixpt_pow(dc_fixpt_from_int(2), 527 dc_fixpt_from_int(region_end)); 528 529 y_r = rgb_resulted[0].red; 530 y_g = rgb_resulted[0].green; 531 y_b = rgb_resulted[0].blue; 532 533 y1_min = dc_fixpt_min(y_r, dc_fixpt_min(y_g, y_b)); 534 535 arr_points[0].y = y1_min; 536 arr_points[0].slope = dc_fixpt_div(arr_points[0].y, 537 arr_points[0].x); 538 539 y_r = rgb_resulted[hw_points - 1].red; 540 y_g = rgb_resulted[hw_points - 1].green; 541 y_b = rgb_resulted[hw_points - 1].blue; 542 543 /* see comment above, m_arrPoints[1].y should be the Y value for the 544 * region end (m_numOfHwPoints), not last HW point(m_numOfHwPoints - 1) 545 */ 546 y3_max = dc_fixpt_max(y_r, dc_fixpt_max(y_g, y_b)); 547 548 arr_points[1].y = y3_max; 549 550 arr_points[1].slope = dc_fixpt_zero; 551 552 if (output_tf->tf == TRANSFER_FUNCTION_PQ) { 553 /* for PQ, we want to have a straight line from last HW X point, 554 * and the slope to be such that we hit 1.0 at 10000 nits. 555 */ 556 const struct fixed31_32 end_value = dc_fixpt_from_int(125); 557 558 arr_points[1].slope = dc_fixpt_div( 559 dc_fixpt_sub(dc_fixpt_one, arr_points[1].y), 560 dc_fixpt_sub(end_value, arr_points[1].x)); 561 } 562 563 regamma_params->hw_points_num = hw_points; 564 565 k = 0; 566 for (i = 1; i < 16; i++) { 567 if (seg_distr[k] != -1) { 568 regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 569 regamma_params->arr_curve_points[i].offset = 570 regamma_params->arr_curve_points[k].offset + (1 << seg_distr[k]); 571 } 572 k++; 573 } 574 575 if (seg_distr[k] != -1) 576 regamma_params->arr_curve_points[k].segments_num = seg_distr[k]; 577 578 rgb = rgb_resulted; 579 rgb_plus_1 = rgb_resulted + 1; 580 581 i = 1; 582 583 while (i != hw_points + 1) { 584 if (dc_fixpt_lt(rgb_plus_1->red, rgb->red)) 585 rgb_plus_1->red = rgb->red; 586 if (dc_fixpt_lt(rgb_plus_1->green, rgb->green)) 587 rgb_plus_1->green = rgb->green; 588 if (dc_fixpt_lt(rgb_plus_1->blue, rgb->blue)) 589 rgb_plus_1->blue = rgb->blue; 590 591 rgb->delta_red = dc_fixpt_sub(rgb_plus_1->red, rgb->red); 592 rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green); 593 rgb->delta_blue = dc_fixpt_sub(rgb_plus_1->blue, rgb->blue); 594 595 ++rgb_plus_1; 596 ++rgb; 597 ++i; 598 } 599 600 convert_to_custom_float(rgb_resulted, arr_points, hw_points); 601 602 return true; 603 } 604 605 static bool 606 dce110_set_output_transfer_func(struct dc *dc, struct pipe_ctx *pipe_ctx, 607 const struct dc_stream_state *stream) 608 { 609 struct transform *xfm = pipe_ctx->plane_res.xfm; 610 611 xfm->funcs->opp_power_on_regamma_lut(xfm, true); 612 xfm->regamma_params.hw_points_num = GAMMA_HW_POINTS_NUM; 613 614 if (stream->out_transfer_func.type == TF_TYPE_PREDEFINED && 615 stream->out_transfer_func.tf == TRANSFER_FUNCTION_SRGB) { 616 xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_SRGB); 617 } else if (dce110_translate_regamma_to_hw_format(&stream->out_transfer_func, 618 &xfm->regamma_params)) { 619 xfm->funcs->opp_program_regamma_pwl(xfm, &xfm->regamma_params); 620 xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_USER); 621 } else { 622 xfm->funcs->opp_set_regamma_mode(xfm, OPP_REGAMMA_BYPASS); 623 } 624 625 xfm->funcs->opp_power_on_regamma_lut(xfm, false); 626 627 return true; 628 } 629 630 void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) 631 { 632 bool is_hdmi_tmds; 633 bool is_dp; 634 635 ASSERT(pipe_ctx->stream); 636 637 if (pipe_ctx->stream_res.stream_enc == NULL) 638 return; /* this is not root pipe */ 639 640 is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal); 641 is_dp = dc_is_dp_signal(pipe_ctx->stream->signal); 642 643 if (!is_hdmi_tmds && !is_dp) 644 return; 645 646 if (is_hdmi_tmds) 647 pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets( 648 pipe_ctx->stream_res.stream_enc, 649 &pipe_ctx->stream_res.encoder_info_frame); 650 else { 651 if (pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num) 652 pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num( 653 pipe_ctx->stream_res.stream_enc, 654 &pipe_ctx->stream_res.encoder_info_frame); 655 656 pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets( 657 pipe_ctx->stream_res.stream_enc, 658 &pipe_ctx->stream_res.encoder_info_frame); 659 } 660 } 661 662 void dce110_enable_stream(struct pipe_ctx *pipe_ctx) 663 { 664 enum dc_lane_count lane_count = 665 pipe_ctx->stream->link->cur_link_settings.lane_count; 666 struct dc_crtc_timing *timing = &pipe_ctx->stream->timing; 667 struct dc_link *link = pipe_ctx->stream->link; 668 const struct dc *dc = link->dc; 669 const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); 670 uint32_t active_total_with_borders; 671 uint32_t early_control = 0; 672 struct timing_generator *tg = pipe_ctx->stream_res.tg; 673 674 link_hwss->setup_stream_encoder(pipe_ctx); 675 676 dc->hwss.update_info_frame(pipe_ctx); 677 678 /* enable early control to avoid corruption on DP monitor*/ 679 active_total_with_borders = 680 timing->h_addressable 681 + timing->h_border_left 682 + timing->h_border_right; 683 684 if (lane_count != 0) 685 early_control = active_total_with_borders % lane_count; 686 687 if (early_control == 0) 688 early_control = lane_count; 689 690 tg->funcs->set_early_control(tg, early_control); 691 } 692 693 static enum bp_result link_transmitter_control( 694 struct dc_bios *bios, 695 struct bp_transmitter_control *cntl) 696 { 697 enum bp_result result; 698 699 result = bios->funcs->transmitter_control(bios, cntl); 700 701 return result; 702 } 703 704 /* 705 * @brief 706 * eDP only. 707 */ 708 void dce110_edp_wait_for_hpd_ready( 709 struct dc_link *link, 710 bool power_up) 711 { 712 struct dc_context *ctx = link->ctx; 713 struct graphics_object_id connector = link->link_enc->connector; 714 struct gpio *hpd; 715 bool edp_hpd_high = false; 716 uint32_t time_elapsed = 0; 717 uint32_t timeout = power_up ? 718 PANEL_POWER_UP_TIMEOUT : PANEL_POWER_DOWN_TIMEOUT; 719 720 if (dal_graphics_object_id_get_connector_id(connector) 721 != CONNECTOR_ID_EDP) { 722 BREAK_TO_DEBUGGER(); 723 return; 724 } 725 726 if (!power_up) 727 /* 728 * From KV, we will not HPD low after turning off VCC - 729 * instead, we will check the SW timer in power_up(). 730 */ 731 return; 732 733 /* 734 * When we power on/off the eDP panel, 735 * we need to wait until SENSE bit is high/low. 736 */ 737 738 /* obtain HPD */ 739 /* TODO what to do with this? */ 740 hpd = ctx->dc->link_srv->get_hpd_gpio(ctx->dc_bios, connector, ctx->gpio_service); 741 742 if (!hpd) { 743 BREAK_TO_DEBUGGER(); 744 return; 745 } 746 747 if (link->panel_config.pps.extra_t3_ms > 0) { 748 int extra_t3_in_ms = link->panel_config.pps.extra_t3_ms; 749 750 msleep(extra_t3_in_ms); 751 } 752 753 dal_gpio_open(hpd, GPIO_MODE_INTERRUPT); 754 755 /* wait until timeout or panel detected */ 756 757 do { 758 uint32_t detected = 0; 759 760 dal_gpio_get_value(hpd, &detected); 761 762 if (!(detected ^ power_up)) { 763 edp_hpd_high = true; 764 break; 765 } 766 767 msleep(HPD_CHECK_INTERVAL); 768 769 time_elapsed += HPD_CHECK_INTERVAL; 770 } while (time_elapsed < timeout); 771 772 dal_gpio_close(hpd); 773 774 dal_gpio_destroy_irq(&hpd); 775 776 /* ensure that the panel is detected */ 777 if (!edp_hpd_high) 778 DC_LOG_DC("%s: wait timed out!\n", __func__); 779 } 780 781 void dce110_edp_power_control( 782 struct dc_link *link, 783 bool power_up) 784 { 785 struct dc_context *ctx = link->ctx; 786 struct bp_transmitter_control cntl = { 0 }; 787 enum bp_result bp_result; 788 uint8_t pwrseq_instance; 789 790 791 if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 792 != CONNECTOR_ID_EDP) { 793 BREAK_TO_DEBUGGER(); 794 return; 795 } 796 797 if (!link->panel_cntl) 798 return; 799 if (power_up != 800 link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl)) { 801 802 unsigned long long current_ts = dm_get_timestamp(ctx); 803 unsigned long long time_since_edp_poweroff_ms = 804 div64_u64(dm_get_elapse_time_in_ns( 805 ctx, 806 current_ts, 807 ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000); 808 unsigned long long time_since_edp_poweron_ms = 809 div64_u64(dm_get_elapse_time_in_ns( 810 ctx, 811 current_ts, 812 ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link)), 1000000); 813 DC_LOG_HW_RESUME_S3( 814 "%s: transition: power_up=%d current_ts=%llu edp_poweroff=%llu edp_poweron=%llu time_since_edp_poweroff_ms=%llu time_since_edp_poweron_ms=%llu", 815 __func__, 816 power_up, 817 current_ts, 818 ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link), 819 ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link), 820 time_since_edp_poweroff_ms, 821 time_since_edp_poweron_ms); 822 823 /* Send VBIOS command to prompt eDP panel power */ 824 if (power_up) { 825 /* edp requires a min of 500ms from LCDVDD off to on */ 826 unsigned long long remaining_min_edp_poweroff_time_ms = 500; 827 828 /* add time defined by a patch, if any (usually patch extra_t12_ms is 0) */ 829 if (link->local_sink != NULL) 830 remaining_min_edp_poweroff_time_ms += 831 link->panel_config.pps.extra_t12_ms; 832 833 /* Adjust remaining_min_edp_poweroff_time_ms if this is not the first time. */ 834 if (ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) { 835 if (time_since_edp_poweroff_ms < remaining_min_edp_poweroff_time_ms) 836 remaining_min_edp_poweroff_time_ms = 837 remaining_min_edp_poweroff_time_ms - time_since_edp_poweroff_ms; 838 else 839 remaining_min_edp_poweroff_time_ms = 0; 840 } 841 842 if (remaining_min_edp_poweroff_time_ms) { 843 DC_LOG_HW_RESUME_S3( 844 "%s: remaining_min_edp_poweroff_time_ms=%llu: begin wait.\n", 845 __func__, remaining_min_edp_poweroff_time_ms); 846 msleep(remaining_min_edp_poweroff_time_ms); 847 DC_LOG_HW_RESUME_S3( 848 "%s: remaining_min_edp_poweroff_time_ms=%llu: end wait.\n", 849 __func__, remaining_min_edp_poweroff_time_ms); 850 dm_output_to_console("%s: wait %lld ms to power on eDP.\n", 851 __func__, remaining_min_edp_poweroff_time_ms); 852 } else { 853 DC_LOG_HW_RESUME_S3( 854 "%s: remaining_min_edp_poweroff_time_ms=%llu: no wait required.\n", 855 __func__, remaining_min_edp_poweroff_time_ms); 856 } 857 } 858 859 DC_LOG_HW_RESUME_S3( 860 "%s: BEGIN: Panel Power action: %s\n", 861 __func__, (power_up ? "On":"Off")); 862 863 cntl.action = power_up ? 864 TRANSMITTER_CONTROL_POWER_ON : 865 TRANSMITTER_CONTROL_POWER_OFF; 866 cntl.transmitter = link->link_enc->transmitter; 867 cntl.connector_obj_id = link->link_enc->connector; 868 cntl.coherent = false; 869 cntl.lanes_number = LANE_COUNT_FOUR; 870 cntl.hpd_sel = link->link_enc->hpd_source; 871 pwrseq_instance = link->panel_cntl->pwrseq_inst; 872 873 if (ctx->dc->ctx->dmub_srv && 874 ctx->dc->debug.dmub_command_table) { 875 876 if (cntl.action == TRANSMITTER_CONTROL_POWER_ON) { 877 bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 878 LVTMA_CONTROL_POWER_ON, 879 pwrseq_instance, link->link_powered_externally); 880 } else { 881 bp_result = ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 882 LVTMA_CONTROL_POWER_OFF, 883 pwrseq_instance, link->link_powered_externally); 884 } 885 } 886 887 bp_result = link_transmitter_control(ctx->dc_bios, &cntl); 888 889 DC_LOG_HW_RESUME_S3( 890 "%s: END: Panel Power action: %s bp_result=%u\n", 891 __func__, (power_up ? "On":"Off"), 892 bp_result); 893 894 ctx->dc->link_srv->dp_trace_set_edp_power_timestamp(link, power_up); 895 896 DC_LOG_HW_RESUME_S3( 897 "%s: updated values: edp_poweroff=%llu edp_poweron=%llu\n", 898 __func__, 899 ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link), 900 ctx->dc->link_srv->dp_trace_get_edp_poweron_timestamp(link)); 901 902 if (bp_result != BP_RESULT_OK) 903 DC_LOG_ERROR( 904 "%s: Panel Power bp_result: %d\n", 905 __func__, bp_result); 906 } else { 907 DC_LOG_HW_RESUME_S3( 908 "%s: Skipping Panel Power action: %s\n", 909 __func__, (power_up ? "On":"Off")); 910 } 911 } 912 913 void dce110_edp_wait_for_T12( 914 struct dc_link *link) 915 { 916 struct dc_context *ctx = link->ctx; 917 918 if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 919 != CONNECTOR_ID_EDP) { 920 BREAK_TO_DEBUGGER(); 921 return; 922 } 923 924 if (!link->panel_cntl) 925 return; 926 927 if (!link->panel_cntl->funcs->is_panel_powered_on(link->panel_cntl) && 928 ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link) != 0) { 929 unsigned int t12_duration = 500; // Default T12 as per spec 930 unsigned long long current_ts = dm_get_timestamp(ctx); 931 unsigned long long time_since_edp_poweroff_ms = 932 div64_u64(dm_get_elapse_time_in_ns( 933 ctx, 934 current_ts, 935 ctx->dc->link_srv->dp_trace_get_edp_poweroff_timestamp(link)), 1000000); 936 937 t12_duration += link->panel_config.pps.extra_t12_ms; // Add extra T12 938 939 if (time_since_edp_poweroff_ms < t12_duration) 940 msleep(t12_duration - time_since_edp_poweroff_ms); 941 } 942 } 943 /*todo: cloned in stream enc, fix*/ 944 /* 945 * @brief 946 * eDP only. Control the backlight of the eDP panel 947 */ 948 void dce110_edp_backlight_control( 949 struct dc_link *link, 950 bool enable) 951 { 952 struct dc_context *ctx = link->ctx; 953 struct bp_transmitter_control cntl = { 0 }; 954 uint8_t pwrseq_instance = 0; 955 unsigned int pre_T11_delay = OLED_PRE_T11_DELAY; 956 unsigned int post_T7_delay = OLED_POST_T7_DELAY; 957 958 if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) 959 != CONNECTOR_ID_EDP) { 960 BREAK_TO_DEBUGGER(); 961 return; 962 } 963 964 if (link->panel_cntl && !(link->dpcd_sink_ext_caps.bits.oled || 965 link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || 966 link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) { 967 bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl); 968 969 if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) { 970 DC_LOG_HW_RESUME_S3( 971 "%s: panel already powered up/off. Do nothing.\n", 972 __func__); 973 return; 974 } 975 } 976 977 /* Send VBIOS command to control eDP panel backlight */ 978 979 DC_LOG_HW_RESUME_S3( 980 "%s: backlight action: %s\n", 981 __func__, (enable ? "On":"Off")); 982 983 cntl.action = enable ? 984 TRANSMITTER_CONTROL_BACKLIGHT_ON : 985 TRANSMITTER_CONTROL_BACKLIGHT_OFF; 986 987 /*cntl.engine_id = ctx->engine;*/ 988 cntl.transmitter = link->link_enc->transmitter; 989 cntl.connector_obj_id = link->link_enc->connector; 990 /*todo: unhardcode*/ 991 cntl.lanes_number = LANE_COUNT_FOUR; 992 cntl.hpd_sel = link->link_enc->hpd_source; 993 cntl.signal = SIGNAL_TYPE_EDP; 994 995 /* For eDP, the following delays might need to be considered 996 * after link training completed: 997 * idle period - min. accounts for required BS-Idle pattern, 998 * max. allows for source frame synchronization); 999 * 50 msec max. delay from valid video data from source 1000 * to video on dislpay or backlight enable. 1001 * 1002 * Disable the delay for now. 1003 * Enable it in the future if necessary. 1004 */ 1005 /* dc_service_sleep_in_milliseconds(50); */ 1006 /*edp 1.2*/ 1007 if (link->panel_cntl) 1008 pwrseq_instance = link->panel_cntl->pwrseq_inst; 1009 1010 if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) { 1011 if (!link->dc->config.edp_no_power_sequencing) 1012 /* 1013 * Sometimes, DP receiver chip power-controlled externally by an 1014 * Embedded Controller could be treated and used as eDP, 1015 * if it drives mobile display. In this case, 1016 * we shouldn't be doing power-sequencing, hence we can skip 1017 * waiting for T7-ready. 1018 */ 1019 ctx->dc->link_srv->edp_receiver_ready_T7(link); 1020 else 1021 DC_LOG_DC("edp_receiver_ready_T7 skipped\n"); 1022 } 1023 1024 /* Setting link_powered_externally will bypass delays in the backlight 1025 * as they are not required if the link is being powered by a different 1026 * source. 1027 */ 1028 if (ctx->dc->ctx->dmub_srv && 1029 ctx->dc->debug.dmub_command_table) { 1030 if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_ON) 1031 ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 1032 LVTMA_CONTROL_LCD_BLON, 1033 pwrseq_instance, link->link_powered_externally); 1034 else 1035 ctx->dc_bios->funcs->enable_lvtma_control(ctx->dc_bios, 1036 LVTMA_CONTROL_LCD_BLOFF, 1037 pwrseq_instance, link->link_powered_externally); 1038 } 1039 1040 link_transmitter_control(ctx->dc_bios, &cntl); 1041 1042 if (enable && link->dpcd_sink_ext_caps.bits.oled && 1043 !link->dc->config.edp_no_power_sequencing && 1044 !link->local_sink->edid_caps.panel_patch.oled_optimize_display_on) { 1045 post_T7_delay += link->panel_config.pps.extra_post_t7_ms; 1046 msleep(post_T7_delay); 1047 } 1048 1049 if (link->dpcd_sink_ext_caps.bits.oled || 1050 link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || 1051 link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1) 1052 ctx->dc->link_srv->edp_backlight_enable_aux(link, enable); 1053 1054 /*edp 1.2*/ 1055 if (cntl.action == TRANSMITTER_CONTROL_BACKLIGHT_OFF) { 1056 if (!link->dc->config.edp_no_power_sequencing) 1057 /* 1058 * Sometimes, DP receiver chip power-controlled externally by an 1059 * Embedded Controller could be treated and used as eDP, 1060 * if it drives mobile display. In this case, 1061 * we shouldn't be doing power-sequencing, hence we can skip 1062 * waiting for T9-ready. 1063 */ 1064 ctx->dc->link_srv->edp_add_delay_for_T9(link); 1065 else 1066 DC_LOG_DC("edp_receiver_ready_T9 skipped\n"); 1067 } 1068 1069 if (!enable) { 1070 /*follow oem panel config's requirement*/ 1071 pre_T11_delay += link->panel_config.pps.extra_pre_t11_ms; 1072 msleep(pre_T11_delay); 1073 } 1074 } 1075 1076 void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) 1077 { 1078 /* notify audio driver for audio modes of monitor */ 1079 struct dc *dc; 1080 struct clk_mgr *clk_mgr; 1081 unsigned int i, num_audio = 1; 1082 const struct link_hwss *link_hwss; 1083 1084 if (!pipe_ctx->stream) 1085 return; 1086 1087 dc = pipe_ctx->stream->ctx->dc; 1088 clk_mgr = dc->clk_mgr; 1089 link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res); 1090 1091 if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == true) 1092 return; 1093 1094 if (pipe_ctx->stream_res.audio) { 1095 for (i = 0; i < MAX_PIPES; i++) { 1096 /*current_state not updated yet*/ 1097 if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) 1098 num_audio++; 1099 } 1100 1101 pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); 1102 1103 if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) 1104 /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 1105 clk_mgr->funcs->enable_pme_wa(clk_mgr); 1106 1107 link_hwss->enable_audio_packet(pipe_ctx); 1108 1109 if (pipe_ctx->stream_res.audio) 1110 pipe_ctx->stream_res.audio->enabled = true; 1111 } 1112 } 1113 1114 void dce110_disable_audio_stream(struct pipe_ctx *pipe_ctx) 1115 { 1116 struct dc *dc; 1117 struct clk_mgr *clk_mgr; 1118 const struct link_hwss *link_hwss; 1119 1120 if (!pipe_ctx || !pipe_ctx->stream) 1121 return; 1122 1123 dc = pipe_ctx->stream->ctx->dc; 1124 clk_mgr = dc->clk_mgr; 1125 link_hwss = get_link_hwss(pipe_ctx->stream->link, &pipe_ctx->link_res); 1126 1127 if (pipe_ctx->stream_res.audio && pipe_ctx->stream_res.audio->enabled == false) 1128 return; 1129 1130 link_hwss->disable_audio_packet(pipe_ctx); 1131 1132 if (pipe_ctx->stream_res.audio) { 1133 pipe_ctx->stream_res.audio->enabled = false; 1134 1135 if (clk_mgr->funcs->enable_pme_wa) 1136 /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ 1137 clk_mgr->funcs->enable_pme_wa(clk_mgr); 1138 1139 /* TODO: notify audio driver for if audio modes list changed 1140 * add audio mode list change flag */ 1141 /* dal_audio_disable_azalia_audio_jack_presence(stream->audio, 1142 * stream->stream_engine_id); 1143 */ 1144 } 1145 } 1146 1147 void dce110_disable_stream(struct pipe_ctx *pipe_ctx) 1148 { 1149 struct dc_stream_state *stream = pipe_ctx->stream; 1150 struct dc_link *link = stream->link; 1151 struct dc *dc = pipe_ctx->stream->ctx->dc; 1152 const struct link_hwss *link_hwss = get_link_hwss(link, &pipe_ctx->link_res); 1153 struct dccg *dccg = dc->res_pool->dccg; 1154 struct timing_generator *tg = pipe_ctx->stream_res.tg; 1155 struct dtbclk_dto_params dto_params = {0}; 1156 int dp_hpo_inst; 1157 struct link_encoder *link_enc = pipe_ctx->link_res.dio_link_enc; 1158 struct stream_encoder *stream_enc = pipe_ctx->stream_res.stream_enc; 1159 1160 if (!dc->config.unify_link_enc_assignment) 1161 link_enc = link_enc_cfg_get_link_enc(link); 1162 1163 if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) { 1164 pipe_ctx->stream_res.stream_enc->funcs->stop_hdmi_info_packets( 1165 pipe_ctx->stream_res.stream_enc); 1166 pipe_ctx->stream_res.stream_enc->funcs->hdmi_reset_stream_attribute( 1167 pipe_ctx->stream_res.stream_enc); 1168 } 1169 1170 if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 1171 pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->stop_dp_info_packets( 1172 pipe_ctx->stream_res.hpo_dp_stream_enc); 1173 } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) 1174 pipe_ctx->stream_res.stream_enc->funcs->stop_dp_info_packets( 1175 pipe_ctx->stream_res.stream_enc); 1176 1177 dc->hwss.disable_audio_stream(pipe_ctx); 1178 1179 link_hwss->reset_stream_encoder(pipe_ctx); 1180 1181 if (dc->link_srv->dp_is_128b_132b_signal(pipe_ctx) && dccg) { 1182 dto_params.otg_inst = tg->inst; 1183 dto_params.timing = &pipe_ctx->stream->timing; 1184 dp_hpo_inst = pipe_ctx->stream_res.hpo_dp_stream_enc->inst; 1185 if (dccg) { 1186 dccg->funcs->disable_symclk32_se(dccg, dp_hpo_inst); 1187 dccg->funcs->set_dpstreamclk(dccg, REFCLK, tg->inst, dp_hpo_inst); 1188 if (dccg && dccg->funcs->set_dtbclk_dto) 1189 dccg->funcs->set_dtbclk_dto(dccg, &dto_params); 1190 } 1191 } else if (dccg && dccg->funcs->disable_symclk_se) { 1192 dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, 1193 link_enc->transmitter - TRANSMITTER_UNIPHY_A); 1194 } 1195 } 1196 1197 void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, 1198 struct dc_link_settings *link_settings) 1199 { 1200 struct encoder_unblank_param params = { { 0 } }; 1201 struct dc_stream_state *stream = pipe_ctx->stream; 1202 struct dc_link *link = stream->link; 1203 struct dce_hwseq *hws = link->dc->hwseq; 1204 1205 /* only 3 items below are used by unblank */ 1206 params.timing = pipe_ctx->stream->timing; 1207 params.link_settings.link_rate = link_settings->link_rate; 1208 1209 if (dc_is_dp_signal(pipe_ctx->stream->signal)) 1210 pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, ¶ms); 1211 1212 if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1213 hws->funcs.edp_backlight_control(link, true); 1214 } 1215 } 1216 1217 void dce110_blank_stream(struct pipe_ctx *pipe_ctx) 1218 { 1219 struct dc_stream_state *stream = pipe_ctx->stream; 1220 struct dc_link *link = stream->link; 1221 struct dce_hwseq *hws = link->dc->hwseq; 1222 1223 if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1224 if (!link->skip_implict_edp_power_control) 1225 hws->funcs.edp_backlight_control(link, false); 1226 link->dc->hwss.set_abm_immediate_disable(pipe_ctx); 1227 } 1228 1229 if (link->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 1230 /* TODO - DP2.0 HW: Set ODM mode in dp hpo encoder here */ 1231 pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_blank( 1232 pipe_ctx->stream_res.hpo_dp_stream_enc); 1233 } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) { 1234 pipe_ctx->stream_res.stream_enc->funcs->dp_blank(link, pipe_ctx->stream_res.stream_enc); 1235 1236 if (!dc_is_embedded_signal(pipe_ctx->stream->signal)) { 1237 /* 1238 * After output is idle pattern some sinks need time to recognize the stream 1239 * has changed or they enter protection state and hang. 1240 */ 1241 msleep(60); 1242 } 1243 } 1244 1245 if (pipe_ctx->stream->signal == SIGNAL_TYPE_EDP && 1246 !link->dc->config.edp_no_power_sequencing) { 1247 /* 1248 * Sometimes, DP receiver chip power-controlled externally by an 1249 * Embedded Controller could be treated and used as eDP, 1250 * if it drives mobile display. In this case, 1251 * we shouldn't be doing power-sequencing, hence we can skip 1252 * waiting for T9-ready. 1253 */ 1254 link->dc->link_srv->edp_receiver_ready_T9(link); 1255 } 1256 1257 } 1258 1259 1260 void dce110_set_avmute(struct pipe_ctx *pipe_ctx, bool enable) 1261 { 1262 if (pipe_ctx != NULL && pipe_ctx->stream_res.stream_enc != NULL) 1263 pipe_ctx->stream_res.stream_enc->funcs->set_avmute(pipe_ctx->stream_res.stream_enc, enable); 1264 } 1265 1266 static enum audio_dto_source translate_to_dto_source(enum controller_id crtc_id) 1267 { 1268 switch (crtc_id) { 1269 case CONTROLLER_ID_D0: 1270 return DTO_SOURCE_ID0; 1271 case CONTROLLER_ID_D1: 1272 return DTO_SOURCE_ID1; 1273 case CONTROLLER_ID_D2: 1274 return DTO_SOURCE_ID2; 1275 case CONTROLLER_ID_D3: 1276 return DTO_SOURCE_ID3; 1277 case CONTROLLER_ID_D4: 1278 return DTO_SOURCE_ID4; 1279 case CONTROLLER_ID_D5: 1280 return DTO_SOURCE_ID5; 1281 default: 1282 return DTO_SOURCE_UNKNOWN; 1283 } 1284 } 1285 1286 static void populate_audio_dp_link_info( 1287 const struct pipe_ctx *pipe_ctx, 1288 struct audio_dp_link_info *dp_link_info) 1289 { 1290 const struct dc_stream_state *stream = pipe_ctx->stream; 1291 const struct dc_link *link = stream->link; 1292 struct fixed31_32 link_bw_kbps; 1293 1294 dp_link_info->encoding = link->dc->link_srv->dp_get_encoding_format( 1295 &pipe_ctx->link_config.dp_link_settings); 1296 dp_link_info->is_mst = (stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST); 1297 dp_link_info->lane_count = pipe_ctx->link_config.dp_link_settings.lane_count; 1298 dp_link_info->link_rate = pipe_ctx->link_config.dp_link_settings.link_rate; 1299 1300 link_bw_kbps = dc_fixpt_from_int(dc_link_bandwidth_kbps(link, 1301 &pipe_ctx->link_config.dp_link_settings)); 1302 1303 /* For audio stream calculations, the video stream should not include FEC or SSC 1304 * in order to get the most pessimistic values. 1305 */ 1306 if (dp_link_info->encoding == DP_8b_10b_ENCODING && 1307 link->dc->link_srv->dp_is_fec_supported(link)) { 1308 link_bw_kbps = dc_fixpt_mul(link_bw_kbps, 1309 dc_fixpt_from_fraction(100, DATA_EFFICIENCY_8b_10b_FEC_EFFICIENCY_x100)); 1310 } else if (dp_link_info->encoding == DP_128b_132b_ENCODING) { 1311 link_bw_kbps = dc_fixpt_mul(link_bw_kbps, 1312 dc_fixpt_from_fraction(10000, 9975)); /* 99.75% SSC overhead*/ 1313 } 1314 1315 dp_link_info->link_bandwidth_kbps = dc_fixpt_floor(link_bw_kbps); 1316 1317 /* Calculates hblank_min_symbol_width for 128b/132b 1318 * Corresponding HBLANK_MIN_SYMBOL_WIDTH register is calculated as: 1319 * floor(h_blank * bits_per_pixel / 128) 1320 */ 1321 if (dp_link_info->encoding == DP_128b_132b_ENCODING) { 1322 struct dc_crtc_timing *crtc_timing = &pipe_ctx->stream->timing; 1323 1324 uint32_t h_active = crtc_timing->h_addressable + crtc_timing->h_border_left 1325 + crtc_timing->h_border_right; 1326 uint32_t h_blank = crtc_timing->h_total - h_active; 1327 1328 uint32_t bpp; 1329 1330 if (crtc_timing->flags.DSC) { 1331 bpp = crtc_timing->dsc_cfg.bits_per_pixel; 1332 } else { 1333 /* When the timing is using DSC, dsc_cfg.bits_per_pixel is in 16th bits. 1334 * The bpp in this path is scaled to 16th bits so the final calculation 1335 * is correct for both cases. 1336 */ 1337 bpp = 16; 1338 switch (crtc_timing->display_color_depth) { 1339 case COLOR_DEPTH_666: 1340 bpp *= 18; 1341 break; 1342 case COLOR_DEPTH_888: 1343 bpp *= 24; 1344 break; 1345 case COLOR_DEPTH_101010: 1346 bpp *= 30; 1347 break; 1348 case COLOR_DEPTH_121212: 1349 bpp *= 36; 1350 break; 1351 default: 1352 bpp = 0; 1353 break; 1354 } 1355 1356 switch (crtc_timing->pixel_encoding) { 1357 case PIXEL_ENCODING_YCBCR422: 1358 bpp = bpp * 2 / 3; 1359 break; 1360 case PIXEL_ENCODING_YCBCR420: 1361 bpp /= 2; 1362 break; 1363 default: 1364 break; 1365 } 1366 } 1367 1368 /* Min symbol width = floor(h_blank * (bpp/16) / 128) */ 1369 dp_link_info->hblank_min_symbol_width = dc_fixpt_floor( 1370 dc_fixpt_div(dc_fixpt_from_int(h_blank * bpp), 1371 dc_fixpt_from_int(128 / 16))); 1372 1373 } else { 1374 dp_link_info->hblank_min_symbol_width = 0; 1375 } 1376 } 1377 1378 static void build_audio_output( 1379 struct dc_state *state, 1380 const struct pipe_ctx *pipe_ctx, 1381 struct audio_output *audio_output) 1382 { 1383 const struct dc_stream_state *stream = pipe_ctx->stream; 1384 audio_output->engine_id = pipe_ctx->stream_res.stream_enc->id; 1385 1386 audio_output->signal = pipe_ctx->stream->signal; 1387 1388 /* audio_crtc_info */ 1389 1390 audio_output->crtc_info.h_total = 1391 stream->timing.h_total; 1392 1393 /* 1394 * Audio packets are sent during actual CRTC blank physical signal, we 1395 * need to specify actual active signal portion 1396 */ 1397 audio_output->crtc_info.h_active = 1398 stream->timing.h_addressable 1399 + stream->timing.h_border_left 1400 + stream->timing.h_border_right; 1401 1402 audio_output->crtc_info.v_active = 1403 stream->timing.v_addressable 1404 + stream->timing.v_border_top 1405 + stream->timing.v_border_bottom; 1406 1407 audio_output->crtc_info.pixel_repetition = 1; 1408 1409 audio_output->crtc_info.interlaced = 1410 stream->timing.flags.INTERLACE; 1411 1412 audio_output->crtc_info.refresh_rate = 1413 (stream->timing.pix_clk_100hz*100)/ 1414 (stream->timing.h_total*stream->timing.v_total); 1415 1416 audio_output->crtc_info.color_depth = 1417 stream->timing.display_color_depth; 1418 1419 audio_output->crtc_info.requested_pixel_clock_100Hz = 1420 pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz; 1421 1422 audio_output->crtc_info.calculated_pixel_clock_100Hz = 1423 pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz; 1424 1425 audio_output->crtc_info.pixel_encoding = 1426 stream->timing.pixel_encoding; 1427 1428 audio_output->crtc_info.dsc_bits_per_pixel = 1429 stream->timing.dsc_cfg.bits_per_pixel; 1430 1431 audio_output->crtc_info.dsc_num_slices = 1432 stream->timing.dsc_cfg.num_slices_h; 1433 1434 /*for HDMI, audio ACR is with deep color ratio factor*/ 1435 if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) && 1436 audio_output->crtc_info.requested_pixel_clock_100Hz == 1437 (stream->timing.pix_clk_100hz)) { 1438 if (pipe_ctx->stream_res.pix_clk_params.pixel_encoding == PIXEL_ENCODING_YCBCR420) { 1439 audio_output->crtc_info.requested_pixel_clock_100Hz = 1440 audio_output->crtc_info.requested_pixel_clock_100Hz/2; 1441 audio_output->crtc_info.calculated_pixel_clock_100Hz = 1442 pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz/2; 1443 1444 } 1445 } 1446 1447 if (state->clk_mgr && 1448 (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT || 1449 pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)) { 1450 audio_output->pll_info.audio_dto_source_clock_in_khz = 1451 state->clk_mgr->funcs->get_dp_ref_clk_frequency( 1452 state->clk_mgr); 1453 } 1454 1455 audio_output->pll_info.feed_back_divider = 1456 pipe_ctx->pll_settings.feedback_divider; 1457 1458 audio_output->pll_info.dto_source = 1459 translate_to_dto_source( 1460 pipe_ctx->stream_res.tg->inst + 1); 1461 1462 /* TODO hard code to enable for now. Need get from stream */ 1463 audio_output->pll_info.ss_enabled = true; 1464 1465 audio_output->pll_info.ss_percentage = 1466 pipe_ctx->pll_settings.ss_percentage; 1467 1468 if (dc_is_dp_signal(pipe_ctx->stream->signal)) { 1469 populate_audio_dp_link_info(pipe_ctx, &audio_output->dp_link_info); 1470 } 1471 } 1472 1473 static void program_scaler(const struct dc *dc, 1474 const struct pipe_ctx *pipe_ctx) 1475 { 1476 struct tg_color color = {0}; 1477 1478 /* TOFPGA */ 1479 if (pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth == NULL) 1480 return; 1481 1482 if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) 1483 get_surface_visual_confirm_color(pipe_ctx, &color); 1484 else 1485 color_space_to_black_color(dc, 1486 pipe_ctx->stream->output_color_space, 1487 &color); 1488 1489 pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth( 1490 pipe_ctx->plane_res.xfm, 1491 pipe_ctx->plane_res.scl_data.lb_params.depth, 1492 &pipe_ctx->stream->bit_depth_params); 1493 1494 if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) { 1495 /* 1496 * The way 420 is packed, 2 channels carry Y component, 1 channel 1497 * alternate between Cb and Cr, so both channels need the pixel 1498 * value for Y 1499 */ 1500 if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) 1501 color.color_r_cr = color.color_g_y; 1502 1503 pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( 1504 pipe_ctx->stream_res.tg, 1505 &color); 1506 } 1507 1508 pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, 1509 &pipe_ctx->plane_res.scl_data); 1510 } 1511 1512 static enum dc_status dce110_enable_stream_timing( 1513 struct pipe_ctx *pipe_ctx, 1514 struct dc_state *context, 1515 struct dc *dc) 1516 { 1517 struct dc_stream_state *stream = pipe_ctx->stream; 1518 struct pipe_ctx *pipe_ctx_old = &dc->current_state->res_ctx. 1519 pipe_ctx[pipe_ctx->pipe_idx]; 1520 struct tg_color black_color = {0}; 1521 1522 if (!pipe_ctx_old->stream) { 1523 1524 /* program blank color */ 1525 color_space_to_black_color(dc, 1526 stream->output_color_space, &black_color); 1527 pipe_ctx->stream_res.tg->funcs->set_blank_color( 1528 pipe_ctx->stream_res.tg, 1529 &black_color); 1530 1531 /* 1532 * Must blank CRTC after disabling power gating and before any 1533 * programming, otherwise CRTC will be hung in bad state 1534 */ 1535 pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, true); 1536 1537 if (false == pipe_ctx->clock_source->funcs->program_pix_clk( 1538 pipe_ctx->clock_source, 1539 &pipe_ctx->stream_res.pix_clk_params, 1540 dc->link_srv->dp_get_encoding_format(&pipe_ctx->link_config.dp_link_settings), 1541 &pipe_ctx->pll_settings)) { 1542 BREAK_TO_DEBUGGER(); 1543 return DC_ERROR_UNEXPECTED; 1544 } 1545 1546 if (dc_is_hdmi_tmds_signal(stream->signal)) { 1547 stream->link->phy_state.symclk_ref_cnts.otg = 1; 1548 if (stream->link->phy_state.symclk_state == SYMCLK_OFF_TX_OFF) 1549 stream->link->phy_state.symclk_state = SYMCLK_ON_TX_OFF; 1550 else 1551 stream->link->phy_state.symclk_state = SYMCLK_ON_TX_ON; 1552 } 1553 1554 pipe_ctx->stream_res.tg->funcs->program_timing( 1555 pipe_ctx->stream_res.tg, 1556 &stream->timing, 1557 0, 1558 0, 1559 0, 1560 0, 1561 0, 1562 pipe_ctx->stream->signal, 1563 true); 1564 } 1565 1566 if (!pipe_ctx_old->stream) { 1567 if (false == pipe_ctx->stream_res.tg->funcs->enable_crtc( 1568 pipe_ctx->stream_res.tg)) { 1569 BREAK_TO_DEBUGGER(); 1570 return DC_ERROR_UNEXPECTED; 1571 } 1572 } 1573 1574 return DC_OK; 1575 } 1576 1577 enum dc_status dce110_apply_single_controller_ctx_to_hw( 1578 struct pipe_ctx *pipe_ctx, 1579 struct dc_state *context, 1580 struct dc *dc) 1581 { 1582 struct dc_stream_state *stream = pipe_ctx->stream; 1583 struct dc_link *link = stream->link; 1584 struct drr_params params = {0}; 1585 unsigned int event_triggers = 0; 1586 struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe; 1587 struct dce_hwseq *hws = dc->hwseq; 1588 const struct link_hwss *link_hwss = get_link_hwss( 1589 link, &pipe_ctx->link_res); 1590 1591 1592 if (hws->funcs.disable_stream_gating) { 1593 hws->funcs.disable_stream_gating(dc, pipe_ctx); 1594 } 1595 1596 if (pipe_ctx->stream_res.audio != NULL) { 1597 struct audio_output audio_output = {0}; 1598 1599 build_audio_output(context, pipe_ctx, &audio_output); 1600 1601 link_hwss->setup_audio_output(pipe_ctx, &audio_output, 1602 pipe_ctx->stream_res.audio->inst); 1603 1604 pipe_ctx->stream_res.audio->funcs->az_configure( 1605 pipe_ctx->stream_res.audio, 1606 pipe_ctx->stream->signal, 1607 &audio_output.crtc_info, 1608 &pipe_ctx->stream->audio_info, 1609 &audio_output.dp_link_info); 1610 1611 if (dc->config.disable_hbr_audio_dp2) 1612 if (pipe_ctx->stream_res.audio->funcs->az_disable_hbr_audio && 1613 dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) 1614 pipe_ctx->stream_res.audio->funcs->az_disable_hbr_audio(pipe_ctx->stream_res.audio); 1615 } 1616 1617 /* make sure no pipes syncd to the pipe being enabled */ 1618 if (!pipe_ctx->stream->apply_seamless_boot_optimization && dc->config.use_pipe_ctx_sync_logic) 1619 check_syncd_pipes_for_disabled_master_pipe(dc, context, pipe_ctx->pipe_idx); 1620 1621 pipe_ctx->stream_res.opp->funcs->opp_program_fmt( 1622 pipe_ctx->stream_res.opp, 1623 &stream->bit_depth_params, 1624 &stream->clamping); 1625 1626 pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 1627 pipe_ctx->stream_res.opp, 1628 COLOR_SPACE_YCBCR601, 1629 stream->timing.display_color_depth, 1630 stream->signal); 1631 1632 while (odm_pipe) { 1633 odm_pipe->stream_res.opp->funcs->opp_set_dyn_expansion( 1634 odm_pipe->stream_res.opp, 1635 COLOR_SPACE_YCBCR601, 1636 stream->timing.display_color_depth, 1637 stream->signal); 1638 1639 odm_pipe->stream_res.opp->funcs->opp_program_fmt( 1640 odm_pipe->stream_res.opp, 1641 &stream->bit_depth_params, 1642 &stream->clamping); 1643 odm_pipe = odm_pipe->next_odm_pipe; 1644 } 1645 1646 /* DCN3.1 FPGA Workaround 1647 * Need to enable HPO DP Stream Encoder before setting OTG master enable. 1648 * To do so, move calling function enable_stream_timing to only be done AFTER calling 1649 * function core_link_enable_stream 1650 */ 1651 if (!(hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx))) 1652 /* */ 1653 /* Do not touch stream timing on seamless boot optimization. */ 1654 if (!pipe_ctx->stream->apply_seamless_boot_optimization) 1655 hws->funcs.enable_stream_timing(pipe_ctx, context, dc); 1656 1657 if (hws->funcs.setup_vupdate_interrupt) 1658 hws->funcs.setup_vupdate_interrupt(dc, pipe_ctx); 1659 1660 params.vertical_total_min = stream->adjust.v_total_min; 1661 params.vertical_total_max = stream->adjust.v_total_max; 1662 set_drr_and_clear_adjust_pending(pipe_ctx, stream, ¶ms); 1663 1664 // DRR should set trigger event to monitor surface update event 1665 if (stream->adjust.v_total_min != 0 && stream->adjust.v_total_max != 0) 1666 event_triggers = 0x80; 1667 /* Event triggers and num frames initialized for DRR, but can be 1668 * later updated for PSR use. Note DRR trigger events are generated 1669 * regardless of whether num frames met. 1670 */ 1671 if (pipe_ctx->stream_res.tg->funcs->set_static_screen_control) 1672 pipe_ctx->stream_res.tg->funcs->set_static_screen_control( 1673 pipe_ctx->stream_res.tg, event_triggers, 2); 1674 1675 if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) 1676 pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg( 1677 pipe_ctx->stream_res.stream_enc, 1678 pipe_ctx->stream_res.tg->inst); 1679 1680 if (dc_is_dp_signal(pipe_ctx->stream->signal)) 1681 dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_CONNECT_DIG_FE_OTG); 1682 1683 if (!stream->dpms_off) 1684 dc->link_srv->set_dpms_on(context, pipe_ctx); 1685 1686 /* DCN3.1 FPGA Workaround 1687 * Need to enable HPO DP Stream Encoder before setting OTG master enable. 1688 * To do so, move calling function enable_stream_timing to only be done AFTER calling 1689 * function core_link_enable_stream 1690 */ 1691 if (hws->wa.dp_hpo_and_otg_sequence && dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) { 1692 if (!pipe_ctx->stream->apply_seamless_boot_optimization) 1693 hws->funcs.enable_stream_timing(pipe_ctx, context, dc); 1694 } 1695 1696 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL; 1697 1698 /* Phantom and main stream share the same link (because the stream 1699 * is constructed with the same sink). Make sure not to override 1700 * and link programming on the main. 1701 */ 1702 if (dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM) { 1703 pipe_ctx->stream->link->psr_settings.psr_feature_enabled = false; 1704 pipe_ctx->stream->link->replay_settings.replay_feature_enabled = false; 1705 } 1706 return DC_OK; 1707 } 1708 1709 /******************************************************************************/ 1710 1711 static void power_down_encoders(struct dc *dc) 1712 { 1713 int i; 1714 1715 for (i = 0; i < dc->link_count; i++) { 1716 enum signal_type signal = dc->links[i]->connector_signal; 1717 1718 dc->link_srv->blank_dp_stream(dc->links[i], false); 1719 1720 if (signal != SIGNAL_TYPE_EDP) 1721 signal = SIGNAL_TYPE_NONE; 1722 1723 if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY) 1724 dc->links[i]->link_enc->funcs->disable_output( 1725 dc->links[i]->link_enc, signal); 1726 1727 dc->links[i]->link_status.link_active = false; 1728 memset(&dc->links[i]->cur_link_settings, 0, 1729 sizeof(dc->links[i]->cur_link_settings)); 1730 } 1731 } 1732 1733 static void power_down_controllers(struct dc *dc) 1734 { 1735 int i; 1736 1737 for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 1738 dc->res_pool->timing_generators[i]->funcs->disable_crtc( 1739 dc->res_pool->timing_generators[i]); 1740 } 1741 } 1742 1743 static void power_down_clock_sources(struct dc *dc) 1744 { 1745 int i; 1746 1747 if (dc->res_pool->dp_clock_source->funcs->cs_power_down( 1748 dc->res_pool->dp_clock_source) == false) 1749 dm_error("Failed to power down pll! (dp clk src)\n"); 1750 1751 for (i = 0; i < dc->res_pool->clk_src_count; i++) { 1752 if (dc->res_pool->clock_sources[i]->funcs->cs_power_down( 1753 dc->res_pool->clock_sources[i]) == false) 1754 dm_error("Failed to power down pll! (clk src index=%d)\n", i); 1755 } 1756 } 1757 1758 static void power_down_all_hw_blocks(struct dc *dc) 1759 { 1760 power_down_encoders(dc); 1761 1762 power_down_controllers(dc); 1763 1764 power_down_clock_sources(dc); 1765 1766 if (dc->fbc_compressor) 1767 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 1768 } 1769 1770 static void disable_vga_and_power_gate_all_controllers( 1771 struct dc *dc) 1772 { 1773 int i; 1774 struct timing_generator *tg; 1775 struct dc_context *ctx = dc->ctx; 1776 1777 for (i = 0; i < dc->res_pool->timing_generator_count; i++) { 1778 tg = dc->res_pool->timing_generators[i]; 1779 1780 if (tg->funcs->disable_vga) 1781 tg->funcs->disable_vga(tg); 1782 } 1783 for (i = 0; i < dc->res_pool->pipe_count; i++) { 1784 /* Enable CLOCK gating for each pipe BEFORE controller 1785 * powergating. */ 1786 enable_display_pipe_clock_gating(ctx, 1787 true); 1788 1789 dc->current_state->res_ctx.pipe_ctx[i].pipe_idx = i; 1790 dc->hwss.disable_plane(dc, dc->current_state, 1791 &dc->current_state->res_ctx.pipe_ctx[i]); 1792 } 1793 } 1794 1795 1796 static void get_edp_streams(struct dc_state *context, 1797 struct dc_stream_state **edp_streams, 1798 int *edp_stream_num) 1799 { 1800 int i; 1801 1802 *edp_stream_num = 0; 1803 for (i = 0; i < context->stream_count; i++) { 1804 if (context->streams[i]->signal == SIGNAL_TYPE_EDP) { 1805 edp_streams[*edp_stream_num] = context->streams[i]; 1806 if (++(*edp_stream_num) == MAX_NUM_EDP) 1807 return; 1808 } 1809 } 1810 } 1811 1812 static void get_edp_links_with_sink( 1813 struct dc *dc, 1814 struct dc_link **edp_links_with_sink, 1815 int *edp_with_sink_num) 1816 { 1817 int i; 1818 1819 /* check if there is an eDP panel not in use */ 1820 *edp_with_sink_num = 0; 1821 for (i = 0; i < dc->link_count; i++) { 1822 if (dc->links[i]->local_sink && 1823 dc->links[i]->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1824 edp_links_with_sink[*edp_with_sink_num] = dc->links[i]; 1825 if (++(*edp_with_sink_num) == MAX_NUM_EDP) 1826 return; 1827 } 1828 } 1829 } 1830 1831 static void clean_up_dsc_blocks(struct dc *dc) 1832 { 1833 struct display_stream_compressor *dsc = NULL; 1834 struct timing_generator *tg = NULL; 1835 struct stream_encoder *se = NULL; 1836 struct dccg *dccg = dc->res_pool->dccg; 1837 struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl; 1838 int i; 1839 1840 if (!dc->caps.is_apu || 1841 dc->ctx->dce_version < DCN_VERSION_3_15) 1842 return; 1843 /*VBIOS supports dsc starts from dcn315*/ 1844 for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) { 1845 struct dcn_dsc_state s = {0}; 1846 1847 dsc = dc->res_pool->dscs[i]; 1848 dsc->funcs->dsc_read_state(dsc, &s); 1849 if (s.dsc_fw_en) { 1850 /* disable DSC in OPTC */ 1851 if (i < dc->res_pool->timing_generator_count) { 1852 tg = dc->res_pool->timing_generators[i]; 1853 tg->funcs->set_dsc_config(tg, OPTC_DSC_DISABLED, 0, 0); 1854 } 1855 /* disable DSC in stream encoder */ 1856 if (i < dc->res_pool->stream_enc_count) { 1857 se = dc->res_pool->stream_enc[i]; 1858 se->funcs->dp_set_dsc_config(se, OPTC_DSC_DISABLED, 0, 0); 1859 se->funcs->dp_set_dsc_pps_info_packet(se, false, NULL, true); 1860 } 1861 /* disable DSC block */ 1862 if (dccg->funcs->set_ref_dscclk) 1863 dccg->funcs->set_ref_dscclk(dccg, dsc->inst); 1864 dsc->funcs->dsc_disable(dsc); 1865 1866 /* power down DSC */ 1867 if (pg_cntl != NULL) 1868 pg_cntl->funcs->dsc_pg_control(pg_cntl, dsc->inst, false); 1869 } 1870 } 1871 } 1872 1873 /* 1874 * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need: 1875 * 1. Power down all DC HW blocks 1876 * 2. Disable VGA engine on all controllers 1877 * 3. Enable power gating for controller 1878 * 4. Set acc_mode_change bit (VBIOS will clear this bit when going to FSDOS) 1879 */ 1880 void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) 1881 { 1882 struct dc_link *edp_links_with_sink[MAX_NUM_EDP]; 1883 struct dc_link *edp_links[MAX_NUM_EDP]; 1884 struct dc_stream_state *edp_streams[MAX_NUM_EDP]; 1885 struct dc_link *edp_link_with_sink = NULL; 1886 struct dc_link *edp_link = NULL; 1887 struct pipe_ctx *pipe_ctx = NULL; 1888 struct dce_hwseq *hws = dc->hwseq; 1889 int edp_with_sink_num; 1890 int edp_num; 1891 int edp_stream_num; 1892 int i; 1893 bool can_apply_edp_fast_boot = false; 1894 bool can_apply_seamless_boot = false; 1895 bool keep_edp_vdd_on = false; 1896 struct dc_bios *dcb = dc->ctx->dc_bios; 1897 DC_LOGGER_INIT(); 1898 1899 1900 get_edp_links_with_sink(dc, edp_links_with_sink, &edp_with_sink_num); 1901 dc_get_edp_links(dc, edp_links, &edp_num); 1902 1903 if (hws->funcs.init_pipes) 1904 hws->funcs.init_pipes(dc, context); 1905 1906 get_edp_streams(context, edp_streams, &edp_stream_num); 1907 1908 // Check fastboot support, disable on DCE8 because of blank screens 1909 if (edp_num && edp_stream_num && dc->ctx->dce_version != DCE_VERSION_8_0 && 1910 dc->ctx->dce_version != DCE_VERSION_8_1 && 1911 dc->ctx->dce_version != DCE_VERSION_8_3) { 1912 for (i = 0; i < edp_num; i++) { 1913 edp_link = edp_links[i]; 1914 if (edp_link != edp_streams[0]->link) 1915 continue; 1916 // enable fastboot if backend is enabled on eDP 1917 if (edp_link->link_enc->funcs->is_dig_enabled && 1918 edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) && 1919 edp_link->link_status.link_active) { 1920 struct dc_stream_state *edp_stream = edp_streams[0]; 1921 1922 can_apply_edp_fast_boot = dc_validate_boot_timing(dc, 1923 edp_stream->sink, &edp_stream->timing); 1924 edp_stream->apply_edp_fast_boot_optimization = can_apply_edp_fast_boot; 1925 if (can_apply_edp_fast_boot) { 1926 DC_LOG_EVENT_LINK_TRAINING("eDP fast boot Enable\n"); 1927 1928 // Vbios & Driver support different pixel rate div policy. 1929 pipe_ctx = resource_get_otg_master_for_stream(&context->res_ctx, edp_stream); 1930 if (pipe_ctx && 1931 hws->funcs.is_dp_dig_pixel_rate_div_policy && 1932 hws->funcs.is_dp_dig_pixel_rate_div_policy(pipe_ctx)) { 1933 // Get Vbios div factor from register 1934 dc->res_pool->dccg->funcs->get_pixel_rate_div( 1935 dc->res_pool->dccg, 1936 pipe_ctx->stream_res.tg->inst, 1937 &pipe_ctx->pixel_rate_divider.div_factor1, 1938 &pipe_ctx->pixel_rate_divider.div_factor2); 1939 1940 // VBios doesn't support pixel rate div, so force it. 1941 // If VBios supports it, we check it from reigster or other flags. 1942 pipe_ctx->stream_res.pix_clk_params.dio_se_pix_per_cycle = 1; 1943 } 1944 } 1945 break; 1946 } 1947 } 1948 // We are trying to enable eDP, don't power down VDD 1949 if (can_apply_edp_fast_boot) 1950 keep_edp_vdd_on = true; 1951 } 1952 1953 // Check seamless boot support 1954 for (i = 0; i < context->stream_count; i++) { 1955 if (context->streams[i]->apply_seamless_boot_optimization) { 1956 can_apply_seamless_boot = true; 1957 break; 1958 } 1959 } 1960 1961 /* eDP should not have stream in resume from S4 and so even with VBios post 1962 * it should get turned off 1963 */ 1964 if (edp_with_sink_num) 1965 edp_link_with_sink = edp_links_with_sink[0]; 1966 1967 if (!can_apply_edp_fast_boot && !can_apply_seamless_boot) { 1968 if (edp_link_with_sink && !keep_edp_vdd_on) { 1969 /*turn off backlight before DP_blank and encoder powered down*/ 1970 hws->funcs.edp_backlight_control(edp_link_with_sink, false); 1971 } 1972 /*resume from S3, no vbios posting, no need to power down again*/ 1973 if (dcb && dcb->funcs && !dcb->funcs->is_accelerated_mode(dcb)) 1974 clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); 1975 1976 power_down_all_hw_blocks(dc); 1977 1978 /* DSC could be enabled on eDP during VBIOS post. 1979 * To clean up dsc blocks if eDP is in link but not active. 1980 */ 1981 if (edp_link_with_sink && (edp_stream_num == 0)) 1982 clean_up_dsc_blocks(dc); 1983 1984 disable_vga_and_power_gate_all_controllers(dc); 1985 if (edp_link_with_sink && !keep_edp_vdd_on) 1986 dc->hwss.edp_power_control(edp_link_with_sink, false); 1987 if (dcb && dcb->funcs && !dcb->funcs->is_accelerated_mode(dcb)) 1988 clk_mgr_optimize_pwr_state(dc, dc->clk_mgr); 1989 } 1990 bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1); 1991 } 1992 1993 static uint32_t compute_pstate_blackout_duration( 1994 struct bw_fixed blackout_duration, 1995 const struct dc_stream_state *stream) 1996 { 1997 uint32_t total_dest_line_time_ns; 1998 uint32_t pstate_blackout_duration_ns; 1999 2000 pstate_blackout_duration_ns = 1000 * blackout_duration.value >> 24; 2001 2002 total_dest_line_time_ns = 1000000UL * 2003 (stream->timing.h_total * 10) / 2004 stream->timing.pix_clk_100hz + 2005 pstate_blackout_duration_ns; 2006 2007 return total_dest_line_time_ns; 2008 } 2009 2010 static void dce110_set_displaymarks( 2011 const struct dc *dc, 2012 struct dc_state *context) 2013 { 2014 uint8_t i, num_pipes; 2015 unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 2016 2017 for (i = 0, num_pipes = 0; i < MAX_PIPES; i++) { 2018 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2019 uint32_t total_dest_line_time_ns; 2020 2021 if (pipe_ctx->stream == NULL) 2022 continue; 2023 2024 total_dest_line_time_ns = compute_pstate_blackout_duration( 2025 dc->bw_vbios->blackout_duration, pipe_ctx->stream); 2026 pipe_ctx->plane_res.mi->funcs->mem_input_program_display_marks( 2027 pipe_ctx->plane_res.mi, 2028 context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes], 2029 context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes], 2030 context->bw_ctx.bw.dce.stutter_entry_wm_ns[num_pipes], 2031 context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes], 2032 total_dest_line_time_ns); 2033 if (i == underlay_idx) { 2034 num_pipes++; 2035 pipe_ctx->plane_res.mi->funcs->mem_input_program_chroma_display_marks( 2036 pipe_ctx->plane_res.mi, 2037 context->bw_ctx.bw.dce.nbp_state_change_wm_ns[num_pipes], 2038 context->bw_ctx.bw.dce.stutter_exit_wm_ns[num_pipes], 2039 context->bw_ctx.bw.dce.urgent_wm_ns[num_pipes], 2040 total_dest_line_time_ns); 2041 } 2042 num_pipes++; 2043 } 2044 } 2045 2046 void dce110_set_safe_displaymarks( 2047 struct resource_context *res_ctx, 2048 const struct resource_pool *pool) 2049 { 2050 int i; 2051 int underlay_idx = pool->underlay_pipe_index; 2052 struct dce_watermarks max_marks = { 2053 MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK, MAX_WATERMARK }; 2054 struct dce_watermarks nbp_marks = { 2055 SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK, SAFE_NBP_MARK }; 2056 struct dce_watermarks min_marks = { 0, 0, 0, 0}; 2057 2058 for (i = 0; i < MAX_PIPES; i++) { 2059 if (res_ctx->pipe_ctx[i].stream == NULL || res_ctx->pipe_ctx[i].plane_res.mi == NULL) 2060 continue; 2061 2062 res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_display_marks( 2063 res_ctx->pipe_ctx[i].plane_res.mi, 2064 nbp_marks, 2065 max_marks, 2066 min_marks, 2067 max_marks, 2068 MAX_WATERMARK); 2069 2070 if (i == underlay_idx) 2071 res_ctx->pipe_ctx[i].plane_res.mi->funcs->mem_input_program_chroma_display_marks( 2072 res_ctx->pipe_ctx[i].plane_res.mi, 2073 nbp_marks, 2074 max_marks, 2075 max_marks, 2076 MAX_WATERMARK); 2077 2078 } 2079 } 2080 2081 /******************************************************************************* 2082 * Public functions 2083 ******************************************************************************/ 2084 2085 static void set_drr(struct pipe_ctx **pipe_ctx, 2086 int num_pipes, struct dc_crtc_timing_adjust adjust) 2087 { 2088 int i = 0; 2089 struct drr_params params = {0}; 2090 // DRR should set trigger event to monitor surface update event 2091 unsigned int event_triggers = 0x80; 2092 // Note DRR trigger events are generated regardless of whether num frames met. 2093 unsigned int num_frames = 2; 2094 2095 params.vertical_total_max = adjust.v_total_max; 2096 params.vertical_total_min = adjust.v_total_min; 2097 2098 /* TODO: If multiple pipes are to be supported, you need 2099 * some GSL stuff. Static screen triggers may be programmed differently 2100 * as well. 2101 */ 2102 for (i = 0; i < num_pipes; i++) { 2103 /* dc_state_destruct() might null the stream resources, so fetch tg 2104 * here first to avoid a race condition. The lifetime of the pointee 2105 * itself (the timing_generator object) is not a problem here. 2106 */ 2107 struct timing_generator *tg = pipe_ctx[i]->stream_res.tg; 2108 2109 if ((tg != NULL) && tg->funcs) { 2110 set_drr_and_clear_adjust_pending(pipe_ctx[i], pipe_ctx[i]->stream, ¶ms); 2111 if (adjust.v_total_max != 0 && adjust.v_total_min != 0) 2112 if (tg->funcs->set_static_screen_control) 2113 tg->funcs->set_static_screen_control( 2114 tg, event_triggers, num_frames); 2115 } 2116 } 2117 } 2118 2119 static void get_position(struct pipe_ctx **pipe_ctx, 2120 int num_pipes, 2121 struct crtc_position *position) 2122 { 2123 int i = 0; 2124 2125 /* TODO: handle pipes > 1 2126 */ 2127 for (i = 0; i < num_pipes; i++) 2128 pipe_ctx[i]->stream_res.tg->funcs->get_position(pipe_ctx[i]->stream_res.tg, position); 2129 } 2130 2131 static void set_static_screen_control(struct pipe_ctx **pipe_ctx, 2132 int num_pipes, const struct dc_static_screen_params *params) 2133 { 2134 unsigned int i; 2135 unsigned int triggers = 0; 2136 2137 if (params->triggers.overlay_update) 2138 triggers |= 0x100; 2139 if (params->triggers.surface_update) 2140 triggers |= 0x80; 2141 if (params->triggers.cursor_update) 2142 triggers |= 0x2; 2143 if (params->triggers.force_trigger) 2144 triggers |= 0x1; 2145 2146 if (num_pipes) { 2147 struct dc *dc = pipe_ctx[0]->stream->ctx->dc; 2148 2149 if (dc->fbc_compressor) 2150 triggers |= 0x84; 2151 } 2152 2153 for (i = 0; i < num_pipes; i++) 2154 pipe_ctx[i]->stream_res.tg->funcs-> 2155 set_static_screen_control(pipe_ctx[i]->stream_res.tg, 2156 triggers, params->num_frames); 2157 } 2158 2159 /* 2160 * Check if FBC can be enabled 2161 */ 2162 static bool should_enable_fbc(struct dc *dc, 2163 struct dc_state *context, 2164 uint32_t *pipe_idx) 2165 { 2166 uint32_t i; 2167 struct pipe_ctx *pipe_ctx = NULL; 2168 struct resource_context *res_ctx = &context->res_ctx; 2169 unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 2170 2171 2172 ASSERT(dc->fbc_compressor); 2173 2174 /* FBC memory should be allocated */ 2175 if (!dc->ctx->fbc_gpu_addr) 2176 return false; 2177 2178 /* Only supports single display */ 2179 if (context->stream_count != 1) 2180 return false; 2181 2182 for (i = 0; i < dc->res_pool->pipe_count; i++) { 2183 if (res_ctx->pipe_ctx[i].stream) { 2184 2185 pipe_ctx = &res_ctx->pipe_ctx[i]; 2186 2187 /* fbc not applicable on underlay pipe */ 2188 if (pipe_ctx->pipe_idx != underlay_idx) { 2189 *pipe_idx = i; 2190 break; 2191 } 2192 } 2193 } 2194 2195 if (i == dc->res_pool->pipe_count) 2196 return false; 2197 2198 if (!pipe_ctx->stream->link) 2199 return false; 2200 2201 /* Only supports eDP */ 2202 if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP) 2203 return false; 2204 2205 /* PSR should not be enabled */ 2206 if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled) 2207 return false; 2208 2209 /* Replay should not be enabled */ 2210 if (pipe_ctx->stream->link->replay_settings.replay_feature_enabled) 2211 return false; 2212 2213 /* Nothing to compress */ 2214 if (!pipe_ctx->plane_state) 2215 return false; 2216 2217 /* Only for non-linear tiling */ 2218 if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) 2219 return false; 2220 2221 return true; 2222 } 2223 2224 /* 2225 * Enable FBC 2226 */ 2227 static void enable_fbc( 2228 struct dc *dc, 2229 struct dc_state *context) 2230 { 2231 uint32_t pipe_idx = 0; 2232 2233 if (should_enable_fbc(dc, context, &pipe_idx)) { 2234 /* Program GRPH COMPRESSED ADDRESS and PITCH */ 2235 struct compr_addr_and_pitch_params params = {0, 0, 0}; 2236 struct compressor *compr = dc->fbc_compressor; 2237 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; 2238 2239 params.source_view_width = pipe_ctx->stream->timing.h_addressable; 2240 params.source_view_height = pipe_ctx->stream->timing.v_addressable; 2241 params.inst = pipe_ctx->stream_res.tg->inst; 2242 compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr; 2243 2244 compr->funcs->surface_address_and_pitch(compr, ¶ms); 2245 compr->funcs->set_fbc_invalidation_triggers(compr, 1); 2246 2247 compr->funcs->enable_fbc(compr, ¶ms); 2248 } 2249 } 2250 2251 static void dce110_reset_hw_ctx_wrap( 2252 struct dc *dc, 2253 struct dc_state *context) 2254 { 2255 int i; 2256 2257 /* Reset old context */ 2258 /* look up the targets that have been removed since last commit */ 2259 for (i = 0; i < MAX_PIPES; i++) { 2260 struct pipe_ctx *pipe_ctx_old = 2261 &dc->current_state->res_ctx.pipe_ctx[i]; 2262 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2263 2264 /* Note: We need to disable output if clock sources change, 2265 * since bios does optimization and doesn't apply if changing 2266 * PHY when not already disabled. 2267 */ 2268 2269 /* Skip underlay pipe since it will be handled in commit surface*/ 2270 if (!pipe_ctx_old->stream || pipe_ctx_old->top_pipe) 2271 continue; 2272 2273 if (!pipe_ctx->stream || 2274 pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) { 2275 struct clock_source *old_clk = pipe_ctx_old->clock_source; 2276 2277 /* Disable if new stream is null. O/w, if stream is 2278 * disabled already, no need to disable again. 2279 */ 2280 if (!pipe_ctx->stream || !pipe_ctx->stream->dpms_off) { 2281 dc->link_srv->set_dpms_off(pipe_ctx_old); 2282 2283 /* free acquired resources*/ 2284 if (pipe_ctx_old->stream_res.audio) { 2285 /*disable az_endpoint*/ 2286 pipe_ctx_old->stream_res.audio->funcs-> 2287 az_disable(pipe_ctx_old->stream_res.audio); 2288 2289 /*free audio*/ 2290 if (dc->caps.dynamic_audio == true) { 2291 /*we have to dynamic arbitrate the audio endpoints*/ 2292 /*we free the resource, need reset is_audio_acquired*/ 2293 update_audio_usage(&dc->current_state->res_ctx, dc->res_pool, 2294 pipe_ctx_old->stream_res.audio, false); 2295 pipe_ctx_old->stream_res.audio = NULL; 2296 } 2297 } 2298 } 2299 2300 pipe_ctx_old->stream_res.tg->funcs->set_blank(pipe_ctx_old->stream_res.tg, true); 2301 if (!hwss_wait_for_blank_complete(pipe_ctx_old->stream_res.tg)) { 2302 dm_error("DC: failed to blank crtc!\n"); 2303 BREAK_TO_DEBUGGER(); 2304 } 2305 pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg); 2306 if (dc_is_hdmi_tmds_signal(pipe_ctx_old->stream->signal)) 2307 pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0; 2308 pipe_ctx_old->plane_res.mi->funcs->free_mem_input( 2309 pipe_ctx_old->plane_res.mi, dc->current_state->stream_count); 2310 2311 if (old_clk && 0 == resource_get_clock_source_reference(&context->res_ctx, 2312 dc->res_pool, 2313 old_clk)) 2314 old_clk->funcs->cs_power_down(old_clk); 2315 2316 dc->hwss.disable_plane(dc, dc->current_state, pipe_ctx_old); 2317 2318 pipe_ctx_old->stream = NULL; 2319 } 2320 } 2321 } 2322 2323 static void dce110_setup_audio_dto( 2324 struct dc *dc, 2325 struct dc_state *context) 2326 { 2327 unsigned int i; 2328 2329 /* program audio wall clock. use HDMI as clock source if HDMI 2330 * audio active. Otherwise, use DP as clock source 2331 * first, loop to find any HDMI audio, if not, loop find DP audio 2332 */ 2333 /* Setup audio rate clock source */ 2334 /* Issue: 2335 * Audio lag happened on DP monitor when unplug a HDMI monitor 2336 * 2337 * Cause: 2338 * In case of DP and HDMI connected or HDMI only, DCCG_AUDIO_DTO_SEL 2339 * is set to either dto0 or dto1, audio should work fine. 2340 * In case of DP connected only, DCCG_AUDIO_DTO_SEL should be dto1, 2341 * set to dto0 will cause audio lag. 2342 * 2343 * Solution: 2344 * Not optimized audio wall dto setup. When mode set, iterate pipe_ctx, 2345 * find first available pipe with audio, setup audio wall DTO per topology 2346 * instead of per pipe. 2347 */ 2348 for (i = 0; i < dc->res_pool->pipe_count; i++) { 2349 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2350 2351 if (pipe_ctx->stream == NULL) 2352 continue; 2353 2354 if (pipe_ctx->top_pipe) 2355 continue; 2356 if (pipe_ctx->stream->signal != SIGNAL_TYPE_HDMI_TYPE_A) 2357 continue; 2358 if (pipe_ctx->stream_res.audio != NULL) { 2359 struct audio_output audio_output; 2360 2361 build_audio_output(context, pipe_ctx, &audio_output); 2362 2363 if (dc->res_pool->dccg && dc->res_pool->dccg->funcs->set_audio_dtbclk_dto) { 2364 struct dtbclk_dto_params dto_params = {0}; 2365 2366 dc->res_pool->dccg->funcs->set_audio_dtbclk_dto( 2367 dc->res_pool->dccg, &dto_params); 2368 2369 pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 2370 pipe_ctx->stream_res.audio, 2371 pipe_ctx->stream->signal, 2372 &audio_output.crtc_info, 2373 &audio_output.pll_info); 2374 } else 2375 pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 2376 pipe_ctx->stream_res.audio, 2377 pipe_ctx->stream->signal, 2378 &audio_output.crtc_info, 2379 &audio_output.pll_info); 2380 break; 2381 } 2382 } 2383 2384 /* no HDMI audio is found, try DP audio */ 2385 if (i == dc->res_pool->pipe_count) { 2386 for (i = 0; i < dc->res_pool->pipe_count; i++) { 2387 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2388 2389 if (pipe_ctx->stream == NULL) 2390 continue; 2391 2392 if (pipe_ctx->top_pipe) 2393 continue; 2394 2395 if (!dc_is_dp_signal(pipe_ctx->stream->signal)) 2396 continue; 2397 2398 if (pipe_ctx->stream_res.audio != NULL) { 2399 struct audio_output audio_output = {0}; 2400 2401 build_audio_output(context, pipe_ctx, &audio_output); 2402 2403 pipe_ctx->stream_res.audio->funcs->wall_dto_setup( 2404 pipe_ctx->stream_res.audio, 2405 pipe_ctx->stream->signal, 2406 &audio_output.crtc_info, 2407 &audio_output.pll_info); 2408 break; 2409 } 2410 } 2411 } 2412 } 2413 2414 enum dc_status dce110_apply_ctx_to_hw( 2415 struct dc *dc, 2416 struct dc_state *context) 2417 { 2418 struct dce_hwseq *hws = dc->hwseq; 2419 struct dc_bios *dcb = dc->ctx->dc_bios; 2420 enum dc_status status; 2421 int i; 2422 bool was_hpo_acquired = resource_is_hpo_acquired(dc->current_state); 2423 bool is_hpo_acquired = resource_is_hpo_acquired(context); 2424 2425 /* reset syncd pipes from disabled pipes */ 2426 if (dc->config.use_pipe_ctx_sync_logic) 2427 reset_syncd_pipes_from_disabled_pipes(dc, context); 2428 2429 /* Reset old context */ 2430 /* look up the targets that have been removed since last commit */ 2431 hws->funcs.reset_hw_ctx_wrap(dc, context); 2432 2433 /* Skip applying if no targets */ 2434 if (context->stream_count <= 0) 2435 return DC_OK; 2436 2437 /* Apply new context */ 2438 dcb->funcs->set_scratch_critical_state(dcb, true); 2439 2440 /* below is for real asic only */ 2441 for (i = 0; i < dc->res_pool->pipe_count; i++) { 2442 struct pipe_ctx *pipe_ctx_old = 2443 &dc->current_state->res_ctx.pipe_ctx[i]; 2444 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2445 2446 if (pipe_ctx->stream == NULL || pipe_ctx->top_pipe) 2447 continue; 2448 2449 if (pipe_ctx->stream == pipe_ctx_old->stream) { 2450 if (pipe_ctx_old->clock_source != pipe_ctx->clock_source) 2451 dce_crtc_switch_to_clk_src(dc->hwseq, 2452 pipe_ctx->clock_source, i); 2453 continue; 2454 } 2455 2456 hws->funcs.enable_display_power_gating( 2457 dc, i, dc->ctx->dc_bios, 2458 PIPE_GATING_CONTROL_DISABLE); 2459 } 2460 2461 if (dc->fbc_compressor) 2462 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 2463 2464 dce110_setup_audio_dto(dc, context); 2465 2466 if (dc->hwseq->funcs.setup_hpo_hw_control && was_hpo_acquired != is_hpo_acquired) { 2467 dc->hwseq->funcs.setup_hpo_hw_control(dc->hwseq, is_hpo_acquired); 2468 } 2469 2470 for (i = 0; i < dc->res_pool->pipe_count; i++) { 2471 struct pipe_ctx *pipe_ctx_old = 2472 &dc->current_state->res_ctx.pipe_ctx[i]; 2473 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 2474 2475 if (pipe_ctx->stream == NULL) 2476 continue; 2477 2478 if (pipe_ctx->stream == pipe_ctx_old->stream && 2479 pipe_ctx->stream->link->link_state_valid) { 2480 continue; 2481 } 2482 2483 if (pipe_ctx_old->stream && !pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) 2484 continue; 2485 2486 if (pipe_ctx->top_pipe || pipe_ctx->prev_odm_pipe) 2487 continue; 2488 2489 status = dce110_apply_single_controller_ctx_to_hw( 2490 pipe_ctx, 2491 context, 2492 dc); 2493 2494 if (DC_OK != status) 2495 return status; 2496 2497 #ifdef CONFIG_DRM_AMD_DC_FP 2498 if (hws->funcs.resync_fifo_dccg_dio) 2499 hws->funcs.resync_fifo_dccg_dio(hws, dc, context, i); 2500 #endif 2501 } 2502 2503 if (dc->fbc_compressor) 2504 enable_fbc(dc, dc->current_state); 2505 2506 dcb->funcs->set_scratch_critical_state(dcb, false); 2507 2508 return DC_OK; 2509 } 2510 2511 /******************************************************************************* 2512 * Front End programming 2513 ******************************************************************************/ 2514 static void set_default_colors(struct pipe_ctx *pipe_ctx) 2515 { 2516 struct default_adjustment default_adjust = { 0 }; 2517 2518 default_adjust.force_hw_default = false; 2519 default_adjust.in_color_space = pipe_ctx->plane_state->color_space; 2520 default_adjust.out_color_space = pipe_ctx->stream->output_color_space; 2521 default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; 2522 default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format; 2523 2524 /* display color depth */ 2525 default_adjust.color_depth = 2526 pipe_ctx->stream->timing.display_color_depth; 2527 2528 /* Lb color depth */ 2529 default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth; 2530 2531 pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default( 2532 pipe_ctx->plane_res.xfm, &default_adjust); 2533 } 2534 2535 2536 /******************************************************************************* 2537 * In order to turn on/off specific surface we will program 2538 * Blender + CRTC 2539 * 2540 * In case that we have two surfaces and they have a different visibility 2541 * we can't turn off the CRTC since it will turn off the entire display 2542 * 2543 * |----------------------------------------------- | 2544 * |bottom pipe|curr pipe | | | 2545 * |Surface |Surface | Blender | CRCT | 2546 * |visibility |visibility | Configuration| | 2547 * |------------------------------------------------| 2548 * | off | off | CURRENT_PIPE | blank | 2549 * | off | on | CURRENT_PIPE | unblank | 2550 * | on | off | OTHER_PIPE | unblank | 2551 * | on | on | BLENDING | unblank | 2552 * -------------------------------------------------| 2553 * 2554 ******************************************************************************/ 2555 static void program_surface_visibility(const struct dc *dc, 2556 struct pipe_ctx *pipe_ctx) 2557 { 2558 enum blnd_mode blender_mode = BLND_MODE_CURRENT_PIPE; 2559 bool blank_target = false; 2560 2561 if (pipe_ctx->bottom_pipe) { 2562 2563 /* For now we are supporting only two pipes */ 2564 ASSERT(pipe_ctx->bottom_pipe->bottom_pipe == NULL); 2565 2566 if (pipe_ctx->bottom_pipe->plane_state->visible) { 2567 if (pipe_ctx->plane_state->visible) 2568 blender_mode = BLND_MODE_BLENDING; 2569 else 2570 blender_mode = BLND_MODE_OTHER_PIPE; 2571 2572 } else if (!pipe_ctx->plane_state->visible) 2573 blank_target = true; 2574 2575 } else if (!pipe_ctx->plane_state->visible) 2576 blank_target = true; 2577 2578 dce_set_blender_mode(dc->hwseq, pipe_ctx->stream_res.tg->inst, blender_mode); 2579 pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target); 2580 2581 } 2582 2583 static void program_gamut_remap(struct pipe_ctx *pipe_ctx) 2584 { 2585 int i = 0; 2586 struct xfm_grph_csc_adjustment adjust; 2587 memset(&adjust, 0, sizeof(adjust)); 2588 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 2589 2590 2591 if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 2592 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2593 2594 for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2595 adjust.temperature_matrix[i] = 2596 pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 2597 } 2598 2599 pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 2600 } 2601 static void update_plane_addr(const struct dc *dc, 2602 struct pipe_ctx *pipe_ctx) 2603 { 2604 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 2605 2606 if (plane_state == NULL) 2607 return; 2608 2609 pipe_ctx->plane_res.mi->funcs->mem_input_program_surface_flip_and_addr( 2610 pipe_ctx->plane_res.mi, 2611 &plane_state->address, 2612 plane_state->flip_immediate); 2613 2614 plane_state->status.requested_address = plane_state->address; 2615 } 2616 2617 static void dce110_update_pending_status(struct pipe_ctx *pipe_ctx) 2618 { 2619 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 2620 2621 if (plane_state == NULL) 2622 return; 2623 2624 plane_state->status.is_flip_pending = 2625 pipe_ctx->plane_res.mi->funcs->mem_input_is_flip_pending( 2626 pipe_ctx->plane_res.mi); 2627 2628 if (plane_state->status.is_flip_pending && !plane_state->visible) 2629 pipe_ctx->plane_res.mi->current_address = pipe_ctx->plane_res.mi->request_address; 2630 2631 plane_state->status.current_address = pipe_ctx->plane_res.mi->current_address; 2632 if (pipe_ctx->plane_res.mi->current_address.type == PLN_ADDR_TYPE_GRPH_STEREO && 2633 pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye) { 2634 plane_state->status.is_right_eye =\ 2635 !pipe_ctx->stream_res.tg->funcs->is_stereo_left_eye(pipe_ctx->stream_res.tg); 2636 } 2637 } 2638 2639 void dce110_power_down(struct dc *dc) 2640 { 2641 power_down_all_hw_blocks(dc); 2642 disable_vga_and_power_gate_all_controllers(dc); 2643 } 2644 2645 static bool wait_for_reset_trigger_to_occur( 2646 struct dc_context *dc_ctx, 2647 struct timing_generator *tg) 2648 { 2649 struct dc_context *ctx = dc_ctx; 2650 bool rc = false; 2651 2652 /* To avoid endless loop we wait at most 2653 * frames_to_wait_on_triggered_reset frames for the reset to occur. */ 2654 const uint32_t frames_to_wait_on_triggered_reset = 10; 2655 uint32_t i; 2656 2657 for (i = 0; i < frames_to_wait_on_triggered_reset; i++) { 2658 2659 if (!tg->funcs->is_counter_moving(tg)) { 2660 DC_ERROR("TG counter is not moving!\n"); 2661 break; 2662 } 2663 2664 if (tg->funcs->did_triggered_reset_occur(tg)) { 2665 rc = true; 2666 /* usually occurs at i=1 */ 2667 DC_SYNC_INFO("GSL: reset occurred at wait count: %d\n", 2668 i); 2669 break; 2670 } 2671 2672 /* Wait for one frame. */ 2673 tg->funcs->wait_for_state(tg, CRTC_STATE_VACTIVE); 2674 tg->funcs->wait_for_state(tg, CRTC_STATE_VBLANK); 2675 } 2676 2677 if (false == rc) 2678 DC_ERROR("GSL: Timeout on reset trigger!\n"); 2679 2680 return rc; 2681 } 2682 2683 /* Enable timing synchronization for a group of Timing Generators. */ 2684 static void dce110_enable_timing_synchronization( 2685 struct dc *dc, 2686 struct dc_state *state, 2687 int group_index, 2688 int group_size, 2689 struct pipe_ctx *grouped_pipes[]) 2690 { 2691 struct dc_context *dc_ctx = dc->ctx; 2692 struct dcp_gsl_params gsl_params = { 0 }; 2693 int i; 2694 DC_LOGGER_INIT(); 2695 2696 DC_SYNC_INFO("GSL: Setting-up...\n"); 2697 2698 /* Designate a single TG in the group as a master. 2699 * Since HW doesn't care which one, we always assign 2700 * the 1st one in the group. */ 2701 gsl_params.gsl_group = 0; 2702 gsl_params.gsl_master = grouped_pipes[0]->stream_res.tg->inst; 2703 2704 for (i = 0; i < group_size; i++) 2705 grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 2706 grouped_pipes[i]->stream_res.tg, &gsl_params); 2707 2708 /* Reset slave controllers on master VSync */ 2709 DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 2710 2711 for (i = 1 /* skip the master */; i < group_size; i++) 2712 grouped_pipes[i]->stream_res.tg->funcs->enable_reset_trigger( 2713 grouped_pipes[i]->stream_res.tg, 2714 gsl_params.gsl_group); 2715 2716 for (i = 1 /* skip the master */; i < group_size; i++) { 2717 DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 2718 wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2719 grouped_pipes[i]->stream_res.tg->funcs->disable_reset_trigger( 2720 grouped_pipes[i]->stream_res.tg); 2721 } 2722 2723 /* GSL Vblank synchronization is a one time sync mechanism, assumption 2724 * is that the sync'ed displays will not drift out of sync over time*/ 2725 DC_SYNC_INFO("GSL: Restoring register states.\n"); 2726 for (i = 0; i < group_size; i++) 2727 grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 2728 2729 DC_SYNC_INFO("GSL: Set-up complete.\n"); 2730 } 2731 2732 static void dce110_enable_per_frame_crtc_position_reset( 2733 struct dc *dc, 2734 int group_size, 2735 struct pipe_ctx *grouped_pipes[]) 2736 { 2737 struct dc_context *dc_ctx = dc->ctx; 2738 struct dcp_gsl_params gsl_params = { 0 }; 2739 int i; 2740 DC_LOGGER_INIT(); 2741 2742 gsl_params.gsl_group = 0; 2743 gsl_params.gsl_master = 0; 2744 2745 for (i = 0; i < group_size; i++) 2746 grouped_pipes[i]->stream_res.tg->funcs->setup_global_swap_lock( 2747 grouped_pipes[i]->stream_res.tg, &gsl_params); 2748 2749 DC_SYNC_INFO("GSL: enabling trigger-reset\n"); 2750 2751 for (i = 1; i < group_size; i++) 2752 grouped_pipes[i]->stream_res.tg->funcs->enable_crtc_reset( 2753 grouped_pipes[i]->stream_res.tg, 2754 gsl_params.gsl_master, 2755 &grouped_pipes[i]->stream->triggered_crtc_reset); 2756 2757 DC_SYNC_INFO("GSL: waiting for reset to occur.\n"); 2758 for (i = 1; i < group_size; i++) 2759 wait_for_reset_trigger_to_occur(dc_ctx, grouped_pipes[i]->stream_res.tg); 2760 2761 for (i = 0; i < group_size; i++) 2762 grouped_pipes[i]->stream_res.tg->funcs->tear_down_global_swap_lock(grouped_pipes[i]->stream_res.tg); 2763 2764 } 2765 2766 static void init_pipes(struct dc *dc, struct dc_state *context) 2767 { 2768 // Do nothing 2769 } 2770 2771 static void init_hw(struct dc *dc) 2772 { 2773 int i; 2774 struct dc_bios *bp; 2775 struct transform *xfm; 2776 struct abm *abm; 2777 struct dmcu *dmcu; 2778 struct dce_hwseq *hws = dc->hwseq; 2779 uint32_t backlight = MAX_BACKLIGHT_LEVEL; 2780 uint32_t user_level = MAX_BACKLIGHT_LEVEL; 2781 2782 bp = dc->ctx->dc_bios; 2783 for (i = 0; i < dc->res_pool->pipe_count; i++) { 2784 xfm = dc->res_pool->transforms[i]; 2785 xfm->funcs->transform_reset(xfm); 2786 2787 hws->funcs.enable_display_power_gating( 2788 dc, i, bp, 2789 PIPE_GATING_CONTROL_INIT); 2790 hws->funcs.enable_display_power_gating( 2791 dc, i, bp, 2792 PIPE_GATING_CONTROL_DISABLE); 2793 hws->funcs.enable_display_pipe_clock_gating( 2794 dc->ctx, 2795 true); 2796 } 2797 2798 dce_clock_gating_power_up(dc->hwseq, false); 2799 /***************************************/ 2800 2801 for (i = 0; i < dc->link_count; i++) { 2802 /****************************************/ 2803 /* Power up AND update implementation according to the 2804 * required signal (which may be different from the 2805 * default signal on connector). */ 2806 struct dc_link *link = dc->links[i]; 2807 2808 link->link_enc->funcs->hw_init(link->link_enc); 2809 } 2810 2811 for (i = 0; i < dc->res_pool->pipe_count; i++) { 2812 struct timing_generator *tg = dc->res_pool->timing_generators[i]; 2813 2814 tg->funcs->disable_vga(tg); 2815 2816 /* Blank controller using driver code instead of 2817 * command table. */ 2818 tg->funcs->set_blank(tg, true); 2819 hwss_wait_for_blank_complete(tg); 2820 } 2821 2822 for (i = 0; i < dc->res_pool->audio_count; i++) { 2823 struct audio *audio = dc->res_pool->audios[i]; 2824 audio->funcs->hw_init(audio); 2825 } 2826 2827 for (i = 0; i < dc->link_count; i++) { 2828 struct dc_link *link = dc->links[i]; 2829 2830 if (link->panel_cntl) { 2831 backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl); 2832 user_level = link->panel_cntl->stored_backlight_registers.USER_LEVEL; 2833 } 2834 } 2835 2836 abm = dc->res_pool->abm; 2837 if (abm != NULL) 2838 abm->funcs->abm_init(abm, backlight, user_level); 2839 2840 dmcu = dc->res_pool->dmcu; 2841 if (dmcu != NULL && abm != NULL) 2842 abm->dmcu_is_running = dmcu->funcs->is_dmcu_initialized(dmcu); 2843 2844 if (dc->fbc_compressor) 2845 dc->fbc_compressor->funcs->power_up_fbc(dc->fbc_compressor); 2846 2847 } 2848 2849 2850 void dce110_prepare_bandwidth( 2851 struct dc *dc, 2852 struct dc_state *context) 2853 { 2854 struct clk_mgr *dccg = dc->clk_mgr; 2855 2856 dce110_set_safe_displaymarks(&context->res_ctx, dc->res_pool); 2857 if (dccg) 2858 dccg->funcs->update_clocks( 2859 dccg, 2860 context, 2861 false); 2862 } 2863 2864 void dce110_optimize_bandwidth( 2865 struct dc *dc, 2866 struct dc_state *context) 2867 { 2868 struct clk_mgr *dccg = dc->clk_mgr; 2869 2870 dce110_set_displaymarks(dc, context); 2871 2872 if (dccg) 2873 dccg->funcs->update_clocks( 2874 dccg, 2875 context, 2876 true); 2877 } 2878 2879 static void dce110_program_front_end_for_pipe( 2880 struct dc *dc, struct pipe_ctx *pipe_ctx) 2881 { 2882 struct mem_input *mi = pipe_ctx->plane_res.mi; 2883 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 2884 struct xfm_grph_csc_adjustment adjust; 2885 struct out_csc_color_matrix tbl_entry; 2886 unsigned int i; 2887 struct dce_hwseq *hws = dc->hwseq; 2888 2889 memset(&tbl_entry, 0, sizeof(tbl_entry)); 2890 2891 memset(&adjust, 0, sizeof(adjust)); 2892 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 2893 2894 dce_enable_fe_clock(dc->hwseq, mi->inst, true); 2895 2896 set_default_colors(pipe_ctx); 2897 if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 2898 == true) { 2899 tbl_entry.color_space = 2900 pipe_ctx->stream->output_color_space; 2901 2902 for (i = 0; i < 12; i++) 2903 tbl_entry.regval[i] = 2904 pipe_ctx->stream->csc_color_matrix.matrix[i]; 2905 2906 pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment 2907 (pipe_ctx->plane_res.xfm, &tbl_entry); 2908 } 2909 2910 if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 2911 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 2912 2913 for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 2914 adjust.temperature_matrix[i] = 2915 pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 2916 } 2917 2918 pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 2919 2920 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != NULL; 2921 2922 program_scaler(dc, pipe_ctx); 2923 2924 mi->funcs->mem_input_program_surface_config( 2925 mi, 2926 plane_state->format, 2927 &plane_state->tiling_info, 2928 &plane_state->plane_size, 2929 plane_state->rotation, 2930 NULL, 2931 false); 2932 if (mi->funcs->set_blank) 2933 mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); 2934 2935 if (dc->config.gpu_vm_support) 2936 mi->funcs->mem_input_program_pte_vm( 2937 pipe_ctx->plane_res.mi, 2938 plane_state->format, 2939 &plane_state->tiling_info, 2940 plane_state->rotation); 2941 2942 /* Moved programming gamma from dc to hwss */ 2943 if (pipe_ctx->plane_state->update_flags.bits.full_update || 2944 pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || 2945 pipe_ctx->plane_state->update_flags.bits.gamma_change) 2946 hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state); 2947 2948 if (pipe_ctx->plane_state->update_flags.bits.full_update) 2949 hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream); 2950 2951 DC_LOG_SURFACE( 2952 "Pipe:%d %p: addr hi:0x%x, " 2953 "addr low:0x%x, " 2954 "src: %d, %d, %d," 2955 " %d; dst: %d, %d, %d, %d;" 2956 "clip: %d, %d, %d, %d\n", 2957 pipe_ctx->pipe_idx, 2958 (void *) pipe_ctx->plane_state, 2959 pipe_ctx->plane_state->address.grph.addr.high_part, 2960 pipe_ctx->plane_state->address.grph.addr.low_part, 2961 pipe_ctx->plane_state->src_rect.x, 2962 pipe_ctx->plane_state->src_rect.y, 2963 pipe_ctx->plane_state->src_rect.width, 2964 pipe_ctx->plane_state->src_rect.height, 2965 pipe_ctx->plane_state->dst_rect.x, 2966 pipe_ctx->plane_state->dst_rect.y, 2967 pipe_ctx->plane_state->dst_rect.width, 2968 pipe_ctx->plane_state->dst_rect.height, 2969 pipe_ctx->plane_state->clip_rect.x, 2970 pipe_ctx->plane_state->clip_rect.y, 2971 pipe_ctx->plane_state->clip_rect.width, 2972 pipe_ctx->plane_state->clip_rect.height); 2973 2974 DC_LOG_SURFACE( 2975 "Pipe %d: width, height, x, y\n" 2976 "viewport:%d, %d, %d, %d\n" 2977 "recout: %d, %d, %d, %d\n", 2978 pipe_ctx->pipe_idx, 2979 pipe_ctx->plane_res.scl_data.viewport.width, 2980 pipe_ctx->plane_res.scl_data.viewport.height, 2981 pipe_ctx->plane_res.scl_data.viewport.x, 2982 pipe_ctx->plane_res.scl_data.viewport.y, 2983 pipe_ctx->plane_res.scl_data.recout.width, 2984 pipe_ctx->plane_res.scl_data.recout.height, 2985 pipe_ctx->plane_res.scl_data.recout.x, 2986 pipe_ctx->plane_res.scl_data.recout.y); 2987 } 2988 2989 static void dce110_apply_ctx_for_surface( 2990 struct dc *dc, 2991 const struct dc_stream_state *stream, 2992 int num_planes, 2993 struct dc_state *context) 2994 { 2995 int i; 2996 2997 if (num_planes == 0) 2998 return; 2999 3000 if (dc->fbc_compressor) 3001 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 3002 3003 for (i = 0; i < dc->res_pool->pipe_count; i++) { 3004 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 3005 3006 if (pipe_ctx->stream != stream) 3007 continue; 3008 3009 /* Need to allocate mem before program front end for Fiji */ 3010 pipe_ctx->plane_res.mi->funcs->allocate_mem_input( 3011 pipe_ctx->plane_res.mi, 3012 pipe_ctx->stream->timing.h_total, 3013 pipe_ctx->stream->timing.v_total, 3014 pipe_ctx->stream->timing.pix_clk_100hz / 10, 3015 context->stream_count); 3016 3017 dce110_program_front_end_for_pipe(dc, pipe_ctx); 3018 3019 dc->hwss.update_plane_addr(dc, pipe_ctx); 3020 3021 program_surface_visibility(dc, pipe_ctx); 3022 3023 } 3024 3025 if (dc->fbc_compressor) 3026 enable_fbc(dc, context); 3027 } 3028 3029 static void dce110_post_unlock_program_front_end( 3030 struct dc *dc, 3031 struct dc_state *context) 3032 { 3033 } 3034 3035 static void dce110_power_down_fe(struct dc *dc, struct dc_state *state, struct pipe_ctx *pipe_ctx) 3036 { 3037 struct dce_hwseq *hws = dc->hwseq; 3038 int fe_idx = pipe_ctx->plane_res.mi ? 3039 pipe_ctx->plane_res.mi->inst : pipe_ctx->pipe_idx; 3040 3041 /* Do not power down fe when stream is active on dce*/ 3042 if (dc->current_state->res_ctx.pipe_ctx[fe_idx].stream) 3043 return; 3044 3045 hws->funcs.enable_display_power_gating( 3046 dc, fe_idx, dc->ctx->dc_bios, PIPE_GATING_CONTROL_ENABLE); 3047 3048 dc->res_pool->transforms[fe_idx]->funcs->transform_reset( 3049 dc->res_pool->transforms[fe_idx]); 3050 } 3051 3052 static void dce110_wait_for_mpcc_disconnect( 3053 struct dc *dc, 3054 struct resource_pool *res_pool, 3055 struct pipe_ctx *pipe_ctx) 3056 { 3057 /* do nothing*/ 3058 } 3059 3060 static void program_output_csc(struct dc *dc, 3061 struct pipe_ctx *pipe_ctx, 3062 enum dc_color_space colorspace, 3063 uint16_t *matrix, 3064 int opp_id) 3065 { 3066 int i; 3067 struct out_csc_color_matrix tbl_entry; 3068 3069 if (pipe_ctx->stream->csc_color_matrix.enable_adjustment == true) { 3070 enum dc_color_space color_space = pipe_ctx->stream->output_color_space; 3071 3072 for (i = 0; i < 12; i++) 3073 tbl_entry.regval[i] = pipe_ctx->stream->csc_color_matrix.matrix[i]; 3074 3075 tbl_entry.color_space = color_space; 3076 3077 pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment( 3078 pipe_ctx->plane_res.xfm, &tbl_entry); 3079 } 3080 } 3081 3082 static void dce110_set_cursor_position(struct pipe_ctx *pipe_ctx) 3083 { 3084 struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position; 3085 struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp; 3086 struct mem_input *mi = pipe_ctx->plane_res.mi; 3087 struct dc_cursor_mi_param param = { 3088 .pixel_clk_khz = pipe_ctx->stream->timing.pix_clk_100hz / 10, 3089 .ref_clk_khz = pipe_ctx->stream->ctx->dc->res_pool->ref_clocks.xtalin_clock_inKhz, 3090 .viewport = pipe_ctx->plane_res.scl_data.viewport, 3091 .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz, 3092 .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert, 3093 .rotation = pipe_ctx->plane_state->rotation, 3094 .mirror = pipe_ctx->plane_state->horizontal_mirror 3095 }; 3096 3097 /** 3098 * If the cursor's source viewport is clipped then we need to 3099 * translate the cursor to appear in the correct position on 3100 * the screen. 3101 * 3102 * This translation isn't affected by scaling so it needs to be 3103 * done *after* we adjust the position for the scale factor. 3104 * 3105 * This is only done by opt-in for now since there are still 3106 * some usecases like tiled display that might enable the 3107 * cursor on both streams while expecting dc to clip it. 3108 */ 3109 if (pos_cpy.translate_by_source) { 3110 pos_cpy.x += pipe_ctx->plane_state->src_rect.x; 3111 pos_cpy.y += pipe_ctx->plane_state->src_rect.y; 3112 } 3113 3114 if (pipe_ctx->plane_state->address.type 3115 == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) 3116 pos_cpy.enable = false; 3117 3118 if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state) 3119 pos_cpy.enable = false; 3120 3121 if (ipp->funcs->ipp_cursor_set_position) 3122 ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); 3123 if (mi->funcs->set_cursor_position) 3124 mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); 3125 } 3126 3127 static void dce110_set_cursor_attribute(struct pipe_ctx *pipe_ctx) 3128 { 3129 struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes; 3130 3131 if (pipe_ctx->plane_res.ipp && 3132 pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes) 3133 pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes( 3134 pipe_ctx->plane_res.ipp, attributes); 3135 3136 if (pipe_ctx->plane_res.mi && 3137 pipe_ctx->plane_res.mi->funcs->set_cursor_attributes) 3138 pipe_ctx->plane_res.mi->funcs->set_cursor_attributes( 3139 pipe_ctx->plane_res.mi, attributes); 3140 3141 if (pipe_ctx->plane_res.xfm && 3142 pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes) 3143 pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes( 3144 pipe_ctx->plane_res.xfm, attributes); 3145 } 3146 3147 bool dce110_set_backlight_level(struct pipe_ctx *pipe_ctx, 3148 struct set_backlight_level_params *backlight_level_params) 3149 { 3150 uint32_t backlight_pwm_u16_16 = backlight_level_params->backlight_pwm_u16_16; 3151 uint32_t frame_ramp = backlight_level_params->frame_ramp; 3152 struct dc_link *link = pipe_ctx->stream->link; 3153 struct dc *dc = link->ctx->dc; 3154 struct abm *abm = pipe_ctx->stream_res.abm; 3155 struct panel_cntl *panel_cntl = link->panel_cntl; 3156 struct dmcu *dmcu = dc->res_pool->dmcu; 3157 bool fw_set_brightness = true; 3158 /* DMCU -1 for all controller id values, 3159 * therefore +1 here 3160 */ 3161 uint32_t controller_id = pipe_ctx->stream_res.tg->inst + 1; 3162 3163 if (abm == NULL || panel_cntl == NULL || (abm->funcs->set_backlight_level_pwm == NULL)) 3164 return false; 3165 3166 if (dmcu) 3167 fw_set_brightness = dmcu->funcs->is_dmcu_initialized(dmcu); 3168 3169 if (!fw_set_brightness && panel_cntl->funcs->driver_set_backlight) 3170 panel_cntl->funcs->driver_set_backlight(panel_cntl, backlight_pwm_u16_16); 3171 else 3172 abm->funcs->set_backlight_level_pwm( 3173 abm, 3174 backlight_pwm_u16_16, 3175 frame_ramp, 3176 controller_id, 3177 link->panel_cntl->inst); 3178 3179 return true; 3180 } 3181 3182 void dce110_set_abm_immediate_disable(struct pipe_ctx *pipe_ctx) 3183 { 3184 struct abm *abm = pipe_ctx->stream_res.abm; 3185 struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; 3186 3187 if (abm) 3188 abm->funcs->set_abm_immediate_disable(abm, 3189 pipe_ctx->stream->link->panel_cntl->inst); 3190 3191 if (panel_cntl) 3192 panel_cntl->funcs->store_backlight_level(panel_cntl); 3193 } 3194 3195 void dce110_set_pipe(struct pipe_ctx *pipe_ctx) 3196 { 3197 struct abm *abm = pipe_ctx->stream_res.abm; 3198 struct panel_cntl *panel_cntl = pipe_ctx->stream->link->panel_cntl; 3199 uint32_t otg_inst = pipe_ctx->stream_res.tg->inst + 1; 3200 3201 if (abm && panel_cntl) 3202 abm->funcs->set_pipe(abm, otg_inst, panel_cntl->inst); 3203 } 3204 3205 void dce110_enable_lvds_link_output(struct dc_link *link, 3206 const struct link_resource *link_res, 3207 enum clock_source_id clock_source, 3208 uint32_t pixel_clock) 3209 { 3210 link->link_enc->funcs->enable_lvds_output( 3211 link->link_enc, 3212 clock_source, 3213 pixel_clock); 3214 link->phy_state.symclk_state = SYMCLK_ON_TX_ON; 3215 } 3216 3217 void dce110_enable_tmds_link_output(struct dc_link *link, 3218 const struct link_resource *link_res, 3219 enum signal_type signal, 3220 enum clock_source_id clock_source, 3221 enum dc_color_depth color_depth, 3222 uint32_t pixel_clock) 3223 { 3224 link->link_enc->funcs->enable_tmds_output( 3225 link->link_enc, 3226 clock_source, 3227 color_depth, 3228 signal, 3229 pixel_clock); 3230 link->phy_state.symclk_state = SYMCLK_ON_TX_ON; 3231 } 3232 3233 void dce110_enable_dp_link_output( 3234 struct dc_link *link, 3235 const struct link_resource *link_res, 3236 enum signal_type signal, 3237 enum clock_source_id clock_source, 3238 const struct dc_link_settings *link_settings) 3239 { 3240 struct dc *dc = link->ctx->dc; 3241 struct dmcu *dmcu = dc->res_pool->dmcu; 3242 struct pipe_ctx *pipes = 3243 link->dc->current_state->res_ctx.pipe_ctx; 3244 struct clock_source *dp_cs = 3245 link->dc->res_pool->dp_clock_source; 3246 const struct link_hwss *link_hwss = get_link_hwss(link, link_res); 3247 unsigned int i; 3248 3249 /* 3250 * Add the logic to extract BOTH power up and power down sequences 3251 * from enable/disable link output and only call edp panel control 3252 * in enable_link_dp and disable_link_dp once. 3253 */ 3254 if (link->connector_signal == SIGNAL_TYPE_EDP) { 3255 link->dc->hwss.edp_wait_for_hpd_ready(link, true); 3256 } 3257 3258 /* If the current pixel clock source is not DTO(happens after 3259 * switching from HDMI passive dongle to DP on the same connector), 3260 * switch the pixel clock source to DTO. 3261 */ 3262 3263 for (i = 0; i < MAX_PIPES; i++) { 3264 if (pipes[i].stream != NULL && 3265 pipes[i].stream->link == link) { 3266 if (pipes[i].clock_source != NULL && 3267 pipes[i].clock_source->id != CLOCK_SOURCE_ID_DP_DTO) { 3268 pipes[i].clock_source = dp_cs; 3269 pipes[i].stream_res.pix_clk_params.requested_pix_clk_100hz = 3270 pipes[i].stream->timing.pix_clk_100hz; 3271 pipes[i].clock_source->funcs->program_pix_clk( 3272 pipes[i].clock_source, 3273 &pipes[i].stream_res.pix_clk_params, 3274 dc->link_srv->dp_get_encoding_format(link_settings), 3275 &pipes[i].pll_settings); 3276 } 3277 } 3278 } 3279 3280 if (dc->link_srv->dp_get_encoding_format(link_settings) == DP_8b_10b_ENCODING) { 3281 if (dc->clk_mgr->funcs->notify_link_rate_change) 3282 dc->clk_mgr->funcs->notify_link_rate_change(dc->clk_mgr, link); 3283 } 3284 3285 if (dmcu != NULL && dmcu->funcs->lock_phy) 3286 dmcu->funcs->lock_phy(dmcu); 3287 3288 if (link_hwss->ext.enable_dp_link_output) 3289 link_hwss->ext.enable_dp_link_output(link, link_res, signal, 3290 clock_source, link_settings); 3291 3292 link->phy_state.symclk_state = SYMCLK_ON_TX_ON; 3293 3294 if (dmcu != NULL && dmcu->funcs->unlock_phy) 3295 dmcu->funcs->unlock_phy(dmcu); 3296 3297 dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_ENABLE_LINK_PHY); 3298 } 3299 3300 void dce110_disable_link_output(struct dc_link *link, 3301 const struct link_resource *link_res, 3302 enum signal_type signal) 3303 { 3304 struct dc *dc = link->ctx->dc; 3305 const struct link_hwss *link_hwss = get_link_hwss(link, link_res); 3306 struct dmcu *dmcu = dc->res_pool->dmcu; 3307 3308 if (signal == SIGNAL_TYPE_EDP && 3309 link->dc->hwss.edp_backlight_control && 3310 !link->skip_implict_edp_power_control) 3311 link->dc->hwss.edp_backlight_control(link, false); 3312 else if (dmcu != NULL && dmcu->funcs->lock_phy) 3313 dmcu->funcs->lock_phy(dmcu); 3314 3315 link_hwss->disable_link_output(link, link_res, signal); 3316 link->phy_state.symclk_state = SYMCLK_OFF_TX_OFF; 3317 /* 3318 * Add the logic to extract BOTH power up and power down sequences 3319 * from enable/disable link output and only call edp panel control 3320 * in enable_link_dp and disable_link_dp once. 3321 */ 3322 if (dmcu != NULL && dmcu->funcs->unlock_phy) 3323 dmcu->funcs->unlock_phy(dmcu); 3324 dc->link_srv->dp_trace_source_sequence(link, DPCD_SOURCE_SEQ_AFTER_DISABLE_LINK_PHY); 3325 } 3326 3327 static const struct hw_sequencer_funcs dce110_funcs = { 3328 .program_gamut_remap = program_gamut_remap, 3329 .program_output_csc = program_output_csc, 3330 .init_hw = init_hw, 3331 .apply_ctx_to_hw = dce110_apply_ctx_to_hw, 3332 .apply_ctx_for_surface = dce110_apply_ctx_for_surface, 3333 .post_unlock_program_front_end = dce110_post_unlock_program_front_end, 3334 .update_plane_addr = update_plane_addr, 3335 .update_pending_status = dce110_update_pending_status, 3336 .clear_surface_dcc_and_tiling = dce100_reset_surface_dcc_and_tiling, 3337 .enable_accelerated_mode = dce110_enable_accelerated_mode, 3338 .enable_timing_synchronization = dce110_enable_timing_synchronization, 3339 .enable_per_frame_crtc_position_reset = dce110_enable_per_frame_crtc_position_reset, 3340 .update_info_frame = dce110_update_info_frame, 3341 .enable_stream = dce110_enable_stream, 3342 .disable_stream = dce110_disable_stream, 3343 .unblank_stream = dce110_unblank_stream, 3344 .blank_stream = dce110_blank_stream, 3345 .enable_audio_stream = dce110_enable_audio_stream, 3346 .disable_audio_stream = dce110_disable_audio_stream, 3347 .disable_plane = dce110_power_down_fe, 3348 .pipe_control_lock = dce_pipe_control_lock, 3349 .interdependent_update_lock = NULL, 3350 .cursor_lock = dce_pipe_control_lock, 3351 .prepare_bandwidth = dce110_prepare_bandwidth, 3352 .optimize_bandwidth = dce110_optimize_bandwidth, 3353 .set_drr = set_drr, 3354 .get_position = get_position, 3355 .set_static_screen_control = set_static_screen_control, 3356 .setup_stereo = NULL, 3357 .set_avmute = dce110_set_avmute, 3358 .wait_for_mpcc_disconnect = dce110_wait_for_mpcc_disconnect, 3359 .edp_backlight_control = dce110_edp_backlight_control, 3360 .edp_power_control = dce110_edp_power_control, 3361 .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, 3362 .set_cursor_position = dce110_set_cursor_position, 3363 .set_cursor_attribute = dce110_set_cursor_attribute, 3364 .set_backlight_level = dce110_set_backlight_level, 3365 .set_abm_immediate_disable = dce110_set_abm_immediate_disable, 3366 .set_pipe = dce110_set_pipe, 3367 .enable_lvds_link_output = dce110_enable_lvds_link_output, 3368 .enable_tmds_link_output = dce110_enable_tmds_link_output, 3369 .enable_dp_link_output = dce110_enable_dp_link_output, 3370 .disable_link_output = dce110_disable_link_output, 3371 }; 3372 3373 static const struct hwseq_private_funcs dce110_private_funcs = { 3374 .init_pipes = init_pipes, 3375 .set_input_transfer_func = dce110_set_input_transfer_func, 3376 .set_output_transfer_func = dce110_set_output_transfer_func, 3377 .power_down = dce110_power_down, 3378 .enable_display_pipe_clock_gating = enable_display_pipe_clock_gating, 3379 .enable_display_power_gating = dce110_enable_display_power_gating, 3380 .reset_hw_ctx_wrap = dce110_reset_hw_ctx_wrap, 3381 .enable_stream_timing = dce110_enable_stream_timing, 3382 .disable_stream_gating = NULL, 3383 .enable_stream_gating = NULL, 3384 .edp_backlight_control = dce110_edp_backlight_control, 3385 }; 3386 3387 void dce110_hw_sequencer_construct(struct dc *dc) 3388 { 3389 dc->hwss = dce110_funcs; 3390 dc->hwseq->funcs = dce110_private_funcs; 3391 } 3392 3393