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