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