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