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