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 #include "dm_services.h" 26 27 #include "dc.h" 28 29 #include "core_status.h" 30 #include "core_types.h" 31 #include "hw_sequencer.h" 32 #include "dce/dce_hwseq.h" 33 34 #include "resource.h" 35 36 #include "clk_mgr.h" 37 #include "clock_source.h" 38 #include "dc_bios_types.h" 39 40 #include "bios_parser_interface.h" 41 #include "bios/bios_parser_helper.h" 42 #include "include/irq_service_interface.h" 43 #include "transform.h" 44 #include "dmcu.h" 45 #include "dpp.h" 46 #include "timing_generator.h" 47 #include "abm.h" 48 #include "virtual/virtual_link_encoder.h" 49 #include "hubp.h" 50 51 #include "link_hwss.h" 52 #include "link_encoder.h" 53 #include "link_enc_cfg.h" 54 55 #include "dc_link.h" 56 #include "dc_link_ddc.h" 57 #include "dm_helpers.h" 58 #include "mem_input.h" 59 60 #include "dc_link_dp.h" 61 #include "dc_dmub_srv.h" 62 63 #include "dsc.h" 64 65 #include "vm_helper.h" 66 67 #include "dce/dce_i2c.h" 68 69 #include "dmub/dmub_srv.h" 70 71 #include "i2caux_interface.h" 72 73 #include "dce/dmub_psr.h" 74 75 #include "dce/dmub_hw_lock_mgr.h" 76 77 #include "dc_trace.h" 78 79 #include "dce/dmub_outbox.h" 80 81 #define CTX \ 82 dc->ctx 83 84 #define DC_LOGGER \ 85 dc->ctx->logger 86 87 static const char DC_BUILD_ID[] = "production-build"; 88 89 /** 90 * DOC: Overview 91 * 92 * DC is the OS-agnostic component of the amdgpu DC driver. 93 * 94 * DC maintains and validates a set of structs representing the state of the 95 * driver and writes that state to AMD hardware 96 * 97 * Main DC HW structs: 98 * 99 * struct dc - The central struct. One per driver. Created on driver load, 100 * destroyed on driver unload. 101 * 102 * struct dc_context - One per driver. 103 * Used as a backpointer by most other structs in dc. 104 * 105 * struct dc_link - One per connector (the physical DP, HDMI, miniDP, or eDP 106 * plugpoints). Created on driver load, destroyed on driver unload. 107 * 108 * struct dc_sink - One per display. Created on boot or hotplug. 109 * Destroyed on shutdown or hotunplug. A dc_link can have a local sink 110 * (the display directly attached). It may also have one or more remote 111 * sinks (in the Multi-Stream Transport case) 112 * 113 * struct resource_pool - One per driver. Represents the hw blocks not in the 114 * main pipeline. Not directly accessible by dm. 115 * 116 * Main dc state structs: 117 * 118 * These structs can be created and destroyed as needed. There is a full set of 119 * these structs in dc->current_state representing the currently programmed state. 120 * 121 * struct dc_state - The global DC state to track global state information, 122 * such as bandwidth values. 123 * 124 * struct dc_stream_state - Represents the hw configuration for the pipeline from 125 * a framebuffer to a display. Maps one-to-one with dc_sink. 126 * 127 * struct dc_plane_state - Represents a framebuffer. Each stream has at least one, 128 * and may have more in the Multi-Plane Overlay case. 129 * 130 * struct resource_context - Represents the programmable state of everything in 131 * the resource_pool. Not directly accessible by dm. 132 * 133 * struct pipe_ctx - A member of struct resource_context. Represents the 134 * internal hardware pipeline components. Each dc_plane_state has either 135 * one or two (in the pipe-split case). 136 */ 137 138 /******************************************************************************* 139 * Private functions 140 ******************************************************************************/ 141 142 static inline void elevate_update_type(enum surface_update_type *original, enum surface_update_type new) 143 { 144 if (new > *original) 145 *original = new; 146 } 147 148 static void destroy_links(struct dc *dc) 149 { 150 uint32_t i; 151 152 for (i = 0; i < dc->link_count; i++) { 153 if (NULL != dc->links[i]) 154 link_destroy(&dc->links[i]); 155 } 156 } 157 158 static uint32_t get_num_of_internal_disp(struct dc_link **links, uint32_t num_links) 159 { 160 int i; 161 uint32_t count = 0; 162 163 for (i = 0; i < num_links; i++) { 164 if (links[i]->connector_signal == SIGNAL_TYPE_EDP || 165 links[i]->is_internal_display) 166 count++; 167 } 168 169 return count; 170 } 171 172 static int get_seamless_boot_stream_count(struct dc_state *ctx) 173 { 174 uint8_t i; 175 uint8_t seamless_boot_stream_count = 0; 176 177 for (i = 0; i < ctx->stream_count; i++) 178 if (ctx->streams[i]->apply_seamless_boot_optimization) 179 seamless_boot_stream_count++; 180 181 return seamless_boot_stream_count; 182 } 183 184 static bool create_links( 185 struct dc *dc, 186 uint32_t num_virtual_links) 187 { 188 int i; 189 int connectors_num; 190 struct dc_bios *bios = dc->ctx->dc_bios; 191 192 dc->link_count = 0; 193 194 connectors_num = bios->funcs->get_connectors_number(bios); 195 196 DC_LOG_DC("BIOS object table - number of connectors: %d", connectors_num); 197 198 if (connectors_num > ENUM_ID_COUNT) { 199 dm_error( 200 "DC: Number of connectors %d exceeds maximum of %d!\n", 201 connectors_num, 202 ENUM_ID_COUNT); 203 return false; 204 } 205 206 dm_output_to_console( 207 "DC: %s: connectors_num: physical:%d, virtual:%d\n", 208 __func__, 209 connectors_num, 210 num_virtual_links); 211 212 for (i = 0; i < connectors_num; i++) { 213 struct link_init_data link_init_params = {0}; 214 struct dc_link *link; 215 216 DC_LOG_DC("BIOS object table - printing link object info for connector number: %d, link_index: %d", i, dc->link_count); 217 218 link_init_params.ctx = dc->ctx; 219 /* next BIOS object table connector */ 220 link_init_params.connector_index = i; 221 link_init_params.link_index = dc->link_count; 222 link_init_params.dc = dc; 223 link = link_create(&link_init_params); 224 225 if (link) { 226 dc->links[dc->link_count] = link; 227 link->dc = dc; 228 ++dc->link_count; 229 } 230 } 231 232 DC_LOG_DC("BIOS object table - end"); 233 234 /* Create a link for each usb4 dpia port */ 235 for (i = 0; i < dc->res_pool->usb4_dpia_count; i++) { 236 struct link_init_data link_init_params = {0}; 237 struct dc_link *link; 238 239 link_init_params.ctx = dc->ctx; 240 link_init_params.connector_index = i; 241 link_init_params.link_index = dc->link_count; 242 link_init_params.dc = dc; 243 link_init_params.is_dpia_link = true; 244 245 link = link_create(&link_init_params); 246 if (link) { 247 dc->links[dc->link_count] = link; 248 link->dc = dc; 249 ++dc->link_count; 250 } 251 } 252 253 for (i = 0; i < num_virtual_links; i++) { 254 struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL); 255 struct encoder_init_data enc_init = {0}; 256 257 if (link == NULL) { 258 BREAK_TO_DEBUGGER(); 259 goto failed_alloc; 260 } 261 262 link->link_index = dc->link_count; 263 dc->links[dc->link_count] = link; 264 dc->link_count++; 265 266 link->ctx = dc->ctx; 267 link->dc = dc; 268 link->connector_signal = SIGNAL_TYPE_VIRTUAL; 269 link->link_id.type = OBJECT_TYPE_CONNECTOR; 270 link->link_id.id = CONNECTOR_ID_VIRTUAL; 271 link->link_id.enum_id = ENUM_ID_1; 272 link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL); 273 274 if (!link->link_enc) { 275 BREAK_TO_DEBUGGER(); 276 goto failed_alloc; 277 } 278 279 link->link_status.dpcd_caps = &link->dpcd_caps; 280 281 enc_init.ctx = dc->ctx; 282 enc_init.channel = CHANNEL_ID_UNKNOWN; 283 enc_init.hpd_source = HPD_SOURCEID_UNKNOWN; 284 enc_init.transmitter = TRANSMITTER_UNKNOWN; 285 enc_init.connector = link->link_id; 286 enc_init.encoder.type = OBJECT_TYPE_ENCODER; 287 enc_init.encoder.id = ENCODER_ID_INTERNAL_VIRTUAL; 288 enc_init.encoder.enum_id = ENUM_ID_1; 289 virtual_link_encoder_construct(link->link_enc, &enc_init); 290 } 291 292 dc->caps.num_of_internal_disp = get_num_of_internal_disp(dc->links, dc->link_count); 293 294 return true; 295 296 failed_alloc: 297 return false; 298 } 299 300 /* Create additional DIG link encoder objects if fewer than the platform 301 * supports were created during link construction. This can happen if the 302 * number of physical connectors is less than the number of DIGs. 303 */ 304 static bool create_link_encoders(struct dc *dc) 305 { 306 bool res = true; 307 unsigned int num_usb4_dpia = dc->res_pool->res_cap->num_usb4_dpia; 308 unsigned int num_dig_link_enc = dc->res_pool->res_cap->num_dig_link_enc; 309 int i; 310 311 /* A platform without USB4 DPIA endpoints has a fixed mapping between DIG 312 * link encoders and physical display endpoints and does not require 313 * additional link encoder objects. 314 */ 315 if (num_usb4_dpia == 0) 316 return res; 317 318 /* Create as many link encoder objects as the platform supports. DPIA 319 * endpoints can be programmably mapped to any DIG. 320 */ 321 if (num_dig_link_enc > dc->res_pool->dig_link_enc_count) { 322 for (i = 0; i < num_dig_link_enc; i++) { 323 struct link_encoder *link_enc = dc->res_pool->link_encoders[i]; 324 325 if (!link_enc && dc->res_pool->funcs->link_enc_create_minimal) { 326 link_enc = dc->res_pool->funcs->link_enc_create_minimal(dc->ctx, 327 (enum engine_id)(ENGINE_ID_DIGA + i)); 328 if (link_enc) { 329 dc->res_pool->link_encoders[i] = link_enc; 330 dc->res_pool->dig_link_enc_count++; 331 } else { 332 res = false; 333 } 334 } 335 } 336 } 337 338 return res; 339 } 340 341 /* Destroy any additional DIG link encoder objects created by 342 * create_link_encoders(). 343 * NB: Must only be called after destroy_links(). 344 */ 345 static void destroy_link_encoders(struct dc *dc) 346 { 347 unsigned int num_usb4_dpia; 348 unsigned int num_dig_link_enc; 349 int i; 350 351 if (!dc->res_pool) 352 return; 353 354 num_usb4_dpia = dc->res_pool->res_cap->num_usb4_dpia; 355 num_dig_link_enc = dc->res_pool->res_cap->num_dig_link_enc; 356 357 /* A platform without USB4 DPIA endpoints has a fixed mapping between DIG 358 * link encoders and physical display endpoints and does not require 359 * additional link encoder objects. 360 */ 361 if (num_usb4_dpia == 0) 362 return; 363 364 for (i = 0; i < num_dig_link_enc; i++) { 365 struct link_encoder *link_enc = dc->res_pool->link_encoders[i]; 366 367 if (link_enc) { 368 link_enc->funcs->destroy(&link_enc); 369 dc->res_pool->link_encoders[i] = NULL; 370 dc->res_pool->dig_link_enc_count--; 371 } 372 } 373 } 374 375 static struct dc_perf_trace *dc_perf_trace_create(void) 376 { 377 return kzalloc(sizeof(struct dc_perf_trace), GFP_KERNEL); 378 } 379 380 static void dc_perf_trace_destroy(struct dc_perf_trace **perf_trace) 381 { 382 kfree(*perf_trace); 383 *perf_trace = NULL; 384 } 385 386 /** 387 * dc_stream_adjust_vmin_vmax: 388 * 389 * Looks up the pipe context of dc_stream_state and updates the 390 * vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh 391 * Rate, which is a power-saving feature that targets reducing panel 392 * refresh rate while the screen is static 393 * 394 * @dc: dc reference 395 * @stream: Initial dc stream state 396 * @adjust: Updated parameters for vertical_total_min and vertical_total_max 397 */ 398 bool dc_stream_adjust_vmin_vmax(struct dc *dc, 399 struct dc_stream_state *stream, 400 struct dc_crtc_timing_adjust *adjust) 401 { 402 int i; 403 404 if (memcmp(adjust, &stream->adjust, sizeof(struct dc_crtc_timing_adjust)) == 0) 405 return true; 406 407 stream->adjust.v_total_max = adjust->v_total_max; 408 stream->adjust.v_total_mid = adjust->v_total_mid; 409 stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num; 410 stream->adjust.v_total_min = adjust->v_total_min; 411 412 for (i = 0; i < MAX_PIPES; i++) { 413 struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 414 415 if (pipe->stream == stream && pipe->stream_res.tg) { 416 dc->hwss.set_drr(&pipe, 417 1, 418 *adjust); 419 420 return true; 421 } 422 } 423 return false; 424 } 425 426 /** 427 ***************************************************************************** 428 * Function: dc_stream_get_last_vrr_vtotal 429 * 430 * @brief 431 * Looks up the pipe context of dc_stream_state and gets the 432 * last VTOTAL used by DRR (Dynamic Refresh Rate) 433 * 434 * @param [in] dc: dc reference 435 * @param [in] stream: Initial dc stream state 436 * @param [in] adjust: Updated parameters for vertical_total_min and 437 * vertical_total_max 438 ***************************************************************************** 439 */ 440 bool dc_stream_get_last_used_drr_vtotal(struct dc *dc, 441 struct dc_stream_state *stream, 442 uint32_t *refresh_rate) 443 { 444 bool status = false; 445 446 int i = 0; 447 448 for (i = 0; i < MAX_PIPES; i++) { 449 struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 450 451 if (pipe->stream == stream && pipe->stream_res.tg) { 452 /* Only execute if a function pointer has been defined for 453 * the DC version in question 454 */ 455 if (pipe->stream_res.tg->funcs->get_last_used_drr_vtotal) { 456 pipe->stream_res.tg->funcs->get_last_used_drr_vtotal(pipe->stream_res.tg, refresh_rate); 457 458 status = true; 459 460 break; 461 } 462 } 463 } 464 465 return status; 466 } 467 468 bool dc_stream_get_crtc_position(struct dc *dc, 469 struct dc_stream_state **streams, int num_streams, 470 unsigned int *v_pos, unsigned int *nom_v_pos) 471 { 472 /* TODO: Support multiple streams */ 473 const struct dc_stream_state *stream = streams[0]; 474 int i; 475 bool ret = false; 476 struct crtc_position position; 477 478 for (i = 0; i < MAX_PIPES; i++) { 479 struct pipe_ctx *pipe = 480 &dc->current_state->res_ctx.pipe_ctx[i]; 481 482 if (pipe->stream == stream && pipe->stream_res.stream_enc) { 483 dc->hwss.get_position(&pipe, 1, &position); 484 485 *v_pos = position.vertical_count; 486 *nom_v_pos = position.nominal_vcount; 487 ret = true; 488 } 489 } 490 return ret; 491 } 492 493 #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) 494 bool dc_stream_forward_dmcu_crc_window(struct dc *dc, struct dc_stream_state *stream, 495 struct crc_params *crc_window) 496 { 497 int i; 498 struct dmcu *dmcu = dc->res_pool->dmcu; 499 struct pipe_ctx *pipe; 500 struct crc_region tmp_win, *crc_win; 501 struct otg_phy_mux mapping_tmp, *mux_mapping; 502 503 /*crc window can't be null*/ 504 if (!crc_window) 505 return false; 506 507 if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu))) { 508 crc_win = &tmp_win; 509 mux_mapping = &mapping_tmp; 510 /*set crc window*/ 511 tmp_win.x_start = crc_window->windowa_x_start; 512 tmp_win.y_start = crc_window->windowa_y_start; 513 tmp_win.x_end = crc_window->windowa_x_end; 514 tmp_win.y_end = crc_window->windowa_y_end; 515 516 for (i = 0; i < MAX_PIPES; i++) { 517 pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 518 if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe) 519 break; 520 } 521 522 /* Stream not found */ 523 if (i == MAX_PIPES) 524 return false; 525 526 527 /*set mux routing info*/ 528 mapping_tmp.phy_output_num = stream->link->link_enc_hw_inst; 529 mapping_tmp.otg_output_num = pipe->stream_res.tg->inst; 530 531 dmcu->funcs->forward_crc_window(dmcu, crc_win, mux_mapping); 532 } else { 533 DC_LOG_DC("dmcu is not initialized"); 534 return false; 535 } 536 537 return true; 538 } 539 540 bool dc_stream_stop_dmcu_crc_win_update(struct dc *dc, struct dc_stream_state *stream) 541 { 542 int i; 543 struct dmcu *dmcu = dc->res_pool->dmcu; 544 struct pipe_ctx *pipe; 545 struct otg_phy_mux mapping_tmp, *mux_mapping; 546 547 if ((dmcu != NULL && dmcu->funcs->is_dmcu_initialized(dmcu))) { 548 mux_mapping = &mapping_tmp; 549 550 for (i = 0; i < MAX_PIPES; i++) { 551 pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 552 if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe) 553 break; 554 } 555 556 /* Stream not found */ 557 if (i == MAX_PIPES) 558 return false; 559 560 561 /*set mux routing info*/ 562 mapping_tmp.phy_output_num = stream->link->link_enc_hw_inst; 563 mapping_tmp.otg_output_num = pipe->stream_res.tg->inst; 564 565 dmcu->funcs->stop_crc_win_update(dmcu, mux_mapping); 566 } else { 567 DC_LOG_DC("dmcu is not initialized"); 568 return false; 569 } 570 571 return true; 572 } 573 #endif 574 575 /** 576 * dc_stream_configure_crc() - Configure CRC capture for the given stream. 577 * @dc: DC Object 578 * @stream: The stream to configure CRC on. 579 * @enable: Enable CRC if true, disable otherwise. 580 * @crc_window: CRC window (x/y start/end) information 581 * @continuous: Capture CRC on every frame if true. Otherwise, only capture 582 * once. 583 * 584 * By default, only CRC0 is configured, and the entire frame is used to 585 * calculate the crc. 586 */ 587 bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, 588 struct crc_params *crc_window, bool enable, bool continuous) 589 { 590 int i; 591 struct pipe_ctx *pipe; 592 struct crc_params param; 593 struct timing_generator *tg; 594 595 for (i = 0; i < MAX_PIPES; i++) { 596 pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 597 if (pipe->stream == stream && !pipe->top_pipe && !pipe->prev_odm_pipe) 598 break; 599 } 600 /* Stream not found */ 601 if (i == MAX_PIPES) 602 return false; 603 604 /* By default, capture the full frame */ 605 param.windowa_x_start = 0; 606 param.windowa_y_start = 0; 607 param.windowa_x_end = pipe->stream->timing.h_addressable; 608 param.windowa_y_end = pipe->stream->timing.v_addressable; 609 param.windowb_x_start = 0; 610 param.windowb_y_start = 0; 611 param.windowb_x_end = pipe->stream->timing.h_addressable; 612 param.windowb_y_end = pipe->stream->timing.v_addressable; 613 614 if (crc_window) { 615 param.windowa_x_start = crc_window->windowa_x_start; 616 param.windowa_y_start = crc_window->windowa_y_start; 617 param.windowa_x_end = crc_window->windowa_x_end; 618 param.windowa_y_end = crc_window->windowa_y_end; 619 param.windowb_x_start = crc_window->windowb_x_start; 620 param.windowb_y_start = crc_window->windowb_y_start; 621 param.windowb_x_end = crc_window->windowb_x_end; 622 param.windowb_y_end = crc_window->windowb_y_end; 623 } 624 625 param.dsc_mode = pipe->stream->timing.flags.DSC ? 1:0; 626 param.odm_mode = pipe->next_odm_pipe ? 1:0; 627 628 /* Default to the union of both windows */ 629 param.selection = UNION_WINDOW_A_B; 630 param.continuous_mode = continuous; 631 param.enable = enable; 632 633 tg = pipe->stream_res.tg; 634 635 /* Only call if supported */ 636 if (tg->funcs->configure_crc) 637 return tg->funcs->configure_crc(tg, ¶m); 638 DC_LOG_WARNING("CRC capture not supported."); 639 return false; 640 } 641 642 /** 643 * dc_stream_get_crc() - Get CRC values for the given stream. 644 * 645 * @dc: DC object. 646 * @stream: The DC stream state of the stream to get CRCs from. 647 * @r_cr: CRC value for the red component. 648 * @g_y: CRC value for the green component. 649 * @b_cb: CRC value for the blue component. 650 * 651 * dc_stream_configure_crc needs to be called beforehand to enable CRCs. 652 * 653 * Return: 654 * false if stream is not found, or if CRCs are not enabled. 655 */ 656 bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream, 657 uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb) 658 { 659 int i; 660 struct pipe_ctx *pipe; 661 struct timing_generator *tg; 662 663 for (i = 0; i < MAX_PIPES; i++) { 664 pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 665 if (pipe->stream == stream) 666 break; 667 } 668 /* Stream not found */ 669 if (i == MAX_PIPES) 670 return false; 671 672 tg = pipe->stream_res.tg; 673 674 if (tg->funcs->get_crc) 675 return tg->funcs->get_crc(tg, r_cr, g_y, b_cb); 676 DC_LOG_WARNING("CRC capture not supported."); 677 return false; 678 } 679 680 void dc_stream_set_dyn_expansion(struct dc *dc, struct dc_stream_state *stream, 681 enum dc_dynamic_expansion option) 682 { 683 /* OPP FMT dyn expansion updates*/ 684 int i; 685 struct pipe_ctx *pipe_ctx; 686 687 for (i = 0; i < MAX_PIPES; i++) { 688 if (dc->current_state->res_ctx.pipe_ctx[i].stream 689 == stream) { 690 pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; 691 pipe_ctx->stream_res.opp->dyn_expansion = option; 692 pipe_ctx->stream_res.opp->funcs->opp_set_dyn_expansion( 693 pipe_ctx->stream_res.opp, 694 COLOR_SPACE_YCBCR601, 695 stream->timing.display_color_depth, 696 stream->signal); 697 } 698 } 699 } 700 701 void dc_stream_set_dither_option(struct dc_stream_state *stream, 702 enum dc_dither_option option) 703 { 704 struct bit_depth_reduction_params params; 705 struct dc_link *link = stream->link; 706 struct pipe_ctx *pipes = NULL; 707 int i; 708 709 for (i = 0; i < MAX_PIPES; i++) { 710 if (link->dc->current_state->res_ctx.pipe_ctx[i].stream == 711 stream) { 712 pipes = &link->dc->current_state->res_ctx.pipe_ctx[i]; 713 break; 714 } 715 } 716 717 if (!pipes) 718 return; 719 if (option > DITHER_OPTION_MAX) 720 return; 721 722 stream->dither_option = option; 723 724 memset(¶ms, 0, sizeof(params)); 725 resource_build_bit_depth_reduction_params(stream, ¶ms); 726 stream->bit_depth_params = params; 727 728 if (pipes->plane_res.xfm && 729 pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth) { 730 pipes->plane_res.xfm->funcs->transform_set_pixel_storage_depth( 731 pipes->plane_res.xfm, 732 pipes->plane_res.scl_data.lb_params.depth, 733 &stream->bit_depth_params); 734 } 735 736 pipes->stream_res.opp->funcs-> 737 opp_program_bit_depth_reduction(pipes->stream_res.opp, ¶ms); 738 } 739 740 bool dc_stream_set_gamut_remap(struct dc *dc, const struct dc_stream_state *stream) 741 { 742 int i; 743 bool ret = false; 744 struct pipe_ctx *pipes; 745 746 for (i = 0; i < MAX_PIPES; i++) { 747 if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream) { 748 pipes = &dc->current_state->res_ctx.pipe_ctx[i]; 749 dc->hwss.program_gamut_remap(pipes); 750 ret = true; 751 } 752 } 753 754 return ret; 755 } 756 757 bool dc_stream_program_csc_matrix(struct dc *dc, struct dc_stream_state *stream) 758 { 759 int i; 760 bool ret = false; 761 struct pipe_ctx *pipes; 762 763 for (i = 0; i < MAX_PIPES; i++) { 764 if (dc->current_state->res_ctx.pipe_ctx[i].stream 765 == stream) { 766 767 pipes = &dc->current_state->res_ctx.pipe_ctx[i]; 768 dc->hwss.program_output_csc(dc, 769 pipes, 770 stream->output_color_space, 771 stream->csc_color_matrix.matrix, 772 pipes->stream_res.opp->inst); 773 ret = true; 774 } 775 } 776 777 return ret; 778 } 779 780 void dc_stream_set_static_screen_params(struct dc *dc, 781 struct dc_stream_state **streams, 782 int num_streams, 783 const struct dc_static_screen_params *params) 784 { 785 int i, j; 786 struct pipe_ctx *pipes_affected[MAX_PIPES]; 787 int num_pipes_affected = 0; 788 789 for (i = 0; i < num_streams; i++) { 790 struct dc_stream_state *stream = streams[i]; 791 792 for (j = 0; j < MAX_PIPES; j++) { 793 if (dc->current_state->res_ctx.pipe_ctx[j].stream 794 == stream) { 795 pipes_affected[num_pipes_affected++] = 796 &dc->current_state->res_ctx.pipe_ctx[j]; 797 } 798 } 799 } 800 801 dc->hwss.set_static_screen_control(pipes_affected, num_pipes_affected, params); 802 } 803 804 static void dc_destruct(struct dc *dc) 805 { 806 // reset link encoder assignment table on destruct 807 if (dc->res_pool && dc->res_pool->funcs->link_encs_assign) 808 link_enc_cfg_init(dc, dc->current_state); 809 810 if (dc->current_state) { 811 dc_release_state(dc->current_state); 812 dc->current_state = NULL; 813 } 814 815 destroy_links(dc); 816 817 destroy_link_encoders(dc); 818 819 if (dc->clk_mgr) { 820 dc_destroy_clk_mgr(dc->clk_mgr); 821 dc->clk_mgr = NULL; 822 } 823 824 dc_destroy_resource_pool(dc); 825 826 if (dc->ctx->gpio_service) 827 dal_gpio_service_destroy(&dc->ctx->gpio_service); 828 829 if (dc->ctx->created_bios) 830 dal_bios_parser_destroy(&dc->ctx->dc_bios); 831 832 dc_perf_trace_destroy(&dc->ctx->perf_trace); 833 834 kfree(dc->ctx); 835 dc->ctx = NULL; 836 837 kfree(dc->bw_vbios); 838 dc->bw_vbios = NULL; 839 840 kfree(dc->bw_dceip); 841 dc->bw_dceip = NULL; 842 843 kfree(dc->dcn_soc); 844 dc->dcn_soc = NULL; 845 846 kfree(dc->dcn_ip); 847 dc->dcn_ip = NULL; 848 849 kfree(dc->vm_helper); 850 dc->vm_helper = NULL; 851 852 } 853 854 static bool dc_construct_ctx(struct dc *dc, 855 const struct dc_init_data *init_params) 856 { 857 struct dc_context *dc_ctx; 858 enum dce_version dc_version = DCE_VERSION_UNKNOWN; 859 860 dc_ctx = kzalloc(sizeof(*dc_ctx), GFP_KERNEL); 861 if (!dc_ctx) 862 return false; 863 864 dc_ctx->cgs_device = init_params->cgs_device; 865 dc_ctx->driver_context = init_params->driver; 866 dc_ctx->dc = dc; 867 dc_ctx->asic_id = init_params->asic_id; 868 dc_ctx->dc_sink_id_count = 0; 869 dc_ctx->dc_stream_id_count = 0; 870 dc_ctx->dce_environment = init_params->dce_environment; 871 dc_ctx->dcn_reg_offsets = init_params->dcn_reg_offsets; 872 dc_ctx->nbio_reg_offsets = init_params->nbio_reg_offsets; 873 874 /* Create logger */ 875 876 dc_version = resource_parse_asic_id(init_params->asic_id); 877 dc_ctx->dce_version = dc_version; 878 879 dc_ctx->perf_trace = dc_perf_trace_create(); 880 if (!dc_ctx->perf_trace) { 881 ASSERT_CRITICAL(false); 882 return false; 883 } 884 885 dc->ctx = dc_ctx; 886 887 return true; 888 } 889 890 static bool dc_construct(struct dc *dc, 891 const struct dc_init_data *init_params) 892 { 893 struct dc_context *dc_ctx; 894 struct bw_calcs_dceip *dc_dceip; 895 struct bw_calcs_vbios *dc_vbios; 896 struct dcn_soc_bounding_box *dcn_soc; 897 struct dcn_ip_params *dcn_ip; 898 899 dc->config = init_params->flags; 900 901 // Allocate memory for the vm_helper 902 dc->vm_helper = kzalloc(sizeof(struct vm_helper), GFP_KERNEL); 903 if (!dc->vm_helper) { 904 dm_error("%s: failed to create dc->vm_helper\n", __func__); 905 goto fail; 906 } 907 908 memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides)); 909 910 dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL); 911 if (!dc_dceip) { 912 dm_error("%s: failed to create dceip\n", __func__); 913 goto fail; 914 } 915 916 dc->bw_dceip = dc_dceip; 917 918 dc_vbios = kzalloc(sizeof(*dc_vbios), GFP_KERNEL); 919 if (!dc_vbios) { 920 dm_error("%s: failed to create vbios\n", __func__); 921 goto fail; 922 } 923 924 dc->bw_vbios = dc_vbios; 925 dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL); 926 if (!dcn_soc) { 927 dm_error("%s: failed to create dcn_soc\n", __func__); 928 goto fail; 929 } 930 931 dc->dcn_soc = dcn_soc; 932 933 dcn_ip = kzalloc(sizeof(*dcn_ip), GFP_KERNEL); 934 if (!dcn_ip) { 935 dm_error("%s: failed to create dcn_ip\n", __func__); 936 goto fail; 937 } 938 939 dc->dcn_ip = dcn_ip; 940 941 if (!dc_construct_ctx(dc, init_params)) { 942 dm_error("%s: failed to create ctx\n", __func__); 943 goto fail; 944 } 945 946 dc_ctx = dc->ctx; 947 948 /* Resource should construct all asic specific resources. 949 * This should be the only place where we need to parse the asic id 950 */ 951 if (init_params->vbios_override) 952 dc_ctx->dc_bios = init_params->vbios_override; 953 else { 954 /* Create BIOS parser */ 955 struct bp_init_data bp_init_data; 956 957 bp_init_data.ctx = dc_ctx; 958 bp_init_data.bios = init_params->asic_id.atombios_base_address; 959 960 dc_ctx->dc_bios = dal_bios_parser_create( 961 &bp_init_data, dc_ctx->dce_version); 962 963 if (!dc_ctx->dc_bios) { 964 ASSERT_CRITICAL(false); 965 goto fail; 966 } 967 968 dc_ctx->created_bios = true; 969 } 970 971 dc->vendor_signature = init_params->vendor_signature; 972 973 /* Create GPIO service */ 974 dc_ctx->gpio_service = dal_gpio_service_create( 975 dc_ctx->dce_version, 976 dc_ctx->dce_environment, 977 dc_ctx); 978 979 if (!dc_ctx->gpio_service) { 980 ASSERT_CRITICAL(false); 981 goto fail; 982 } 983 984 dc->res_pool = dc_create_resource_pool(dc, init_params, dc_ctx->dce_version); 985 if (!dc->res_pool) 986 goto fail; 987 988 /* set i2c speed if not done by the respective dcnxxx__resource.c */ 989 if (dc->caps.i2c_speed_in_khz_hdcp == 0) 990 dc->caps.i2c_speed_in_khz_hdcp = dc->caps.i2c_speed_in_khz; 991 992 dc->clk_mgr = dc_clk_mgr_create(dc->ctx, dc->res_pool->pp_smu, dc->res_pool->dccg); 993 if (!dc->clk_mgr) 994 goto fail; 995 #ifdef CONFIG_DRM_AMD_DC_DCN 996 dc->clk_mgr->force_smu_not_present = init_params->force_smu_not_present; 997 998 if (dc->res_pool->funcs->update_bw_bounding_box) { 999 DC_FP_START(); 1000 dc->res_pool->funcs->update_bw_bounding_box(dc, dc->clk_mgr->bw_params); 1001 DC_FP_END(); 1002 } 1003 #endif 1004 1005 /* Creation of current_state must occur after dc->dml 1006 * is initialized in dc_create_resource_pool because 1007 * on creation it copies the contents of dc->dml 1008 */ 1009 1010 dc->current_state = dc_create_state(dc); 1011 1012 if (!dc->current_state) { 1013 dm_error("%s: failed to create validate ctx\n", __func__); 1014 goto fail; 1015 } 1016 1017 if (!create_links(dc, init_params->num_virtual_links)) 1018 goto fail; 1019 1020 /* Create additional DIG link encoder objects if fewer than the platform 1021 * supports were created during link construction. 1022 */ 1023 if (!create_link_encoders(dc)) 1024 goto fail; 1025 1026 dc_resource_state_construct(dc, dc->current_state); 1027 1028 return true; 1029 1030 fail: 1031 return false; 1032 } 1033 1034 static void disable_all_writeback_pipes_for_stream( 1035 const struct dc *dc, 1036 struct dc_stream_state *stream, 1037 struct dc_state *context) 1038 { 1039 int i; 1040 1041 for (i = 0; i < stream->num_wb_info; i++) 1042 stream->writeback_info[i].wb_enabled = false; 1043 } 1044 1045 static void apply_ctx_interdependent_lock(struct dc *dc, struct dc_state *context, 1046 struct dc_stream_state *stream, bool lock) 1047 { 1048 int i; 1049 1050 /* Checks if interdependent update function pointer is NULL or not, takes care of DCE110 case */ 1051 if (dc->hwss.interdependent_update_lock) 1052 dc->hwss.interdependent_update_lock(dc, context, lock); 1053 else { 1054 for (i = 0; i < dc->res_pool->pipe_count; i++) { 1055 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 1056 struct pipe_ctx *old_pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; 1057 1058 // Copied conditions that were previously in dce110_apply_ctx_for_surface 1059 if (stream == pipe_ctx->stream) { 1060 if (!pipe_ctx->top_pipe && 1061 (pipe_ctx->plane_state || old_pipe_ctx->plane_state)) 1062 dc->hwss.pipe_control_lock(dc, pipe_ctx, lock); 1063 } 1064 } 1065 } 1066 } 1067 1068 static void disable_dangling_plane(struct dc *dc, struct dc_state *context) 1069 { 1070 int i, j; 1071 struct dc_state *dangling_context = dc_create_state(dc); 1072 struct dc_state *current_ctx; 1073 1074 if (dangling_context == NULL) 1075 return; 1076 1077 dc_resource_state_copy_construct(dc->current_state, dangling_context); 1078 1079 for (i = 0; i < dc->res_pool->pipe_count; i++) { 1080 struct dc_stream_state *old_stream = 1081 dc->current_state->res_ctx.pipe_ctx[i].stream; 1082 bool should_disable = true; 1083 bool pipe_split_change = false; 1084 1085 if ((context->res_ctx.pipe_ctx[i].top_pipe) && 1086 (dc->current_state->res_ctx.pipe_ctx[i].top_pipe)) 1087 pipe_split_change = context->res_ctx.pipe_ctx[i].top_pipe->pipe_idx != 1088 dc->current_state->res_ctx.pipe_ctx[i].top_pipe->pipe_idx; 1089 else 1090 pipe_split_change = context->res_ctx.pipe_ctx[i].top_pipe != 1091 dc->current_state->res_ctx.pipe_ctx[i].top_pipe; 1092 1093 for (j = 0; j < context->stream_count; j++) { 1094 if (old_stream == context->streams[j]) { 1095 should_disable = false; 1096 break; 1097 } 1098 } 1099 if (!should_disable && pipe_split_change && 1100 dc->current_state->stream_count != context->stream_count) 1101 should_disable = true; 1102 1103 if (old_stream && !dc->current_state->res_ctx.pipe_ctx[i].top_pipe && 1104 !dc->current_state->res_ctx.pipe_ctx[i].prev_odm_pipe) { 1105 struct pipe_ctx *old_pipe, *new_pipe; 1106 1107 old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 1108 new_pipe = &context->res_ctx.pipe_ctx[i]; 1109 1110 if (old_pipe->plane_state && !new_pipe->plane_state) 1111 should_disable = true; 1112 } 1113 1114 if (should_disable && old_stream) { 1115 dc_rem_all_planes_for_stream(dc, old_stream, dangling_context); 1116 disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context); 1117 1118 if (dc->hwss.apply_ctx_for_surface) { 1119 apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, true); 1120 dc->hwss.apply_ctx_for_surface(dc, old_stream, 0, dangling_context); 1121 apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, false); 1122 dc->hwss.post_unlock_program_front_end(dc, dangling_context); 1123 } 1124 if (dc->hwss.program_front_end_for_ctx) { 1125 dc->hwss.interdependent_update_lock(dc, dc->current_state, true); 1126 dc->hwss.program_front_end_for_ctx(dc, dangling_context); 1127 dc->hwss.interdependent_update_lock(dc, dc->current_state, false); 1128 dc->hwss.post_unlock_program_front_end(dc, dangling_context); 1129 } 1130 } 1131 } 1132 1133 current_ctx = dc->current_state; 1134 dc->current_state = dangling_context; 1135 dc_release_state(current_ctx); 1136 } 1137 1138 static void disable_vbios_mode_if_required( 1139 struct dc *dc, 1140 struct dc_state *context) 1141 { 1142 unsigned int i, j; 1143 1144 /* check if timing_changed, disable stream*/ 1145 for (i = 0; i < dc->res_pool->pipe_count; i++) { 1146 struct dc_stream_state *stream = NULL; 1147 struct dc_link *link = NULL; 1148 struct pipe_ctx *pipe = NULL; 1149 1150 pipe = &context->res_ctx.pipe_ctx[i]; 1151 stream = pipe->stream; 1152 if (stream == NULL) 1153 continue; 1154 1155 // only looking for first odm pipe 1156 if (pipe->prev_odm_pipe) 1157 continue; 1158 1159 if (stream->link->local_sink && 1160 stream->link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { 1161 link = stream->link; 1162 } 1163 1164 if (link != NULL && link->link_enc->funcs->is_dig_enabled(link->link_enc)) { 1165 unsigned int enc_inst, tg_inst = 0; 1166 unsigned int pix_clk_100hz; 1167 1168 enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc); 1169 if (enc_inst != ENGINE_ID_UNKNOWN) { 1170 for (j = 0; j < dc->res_pool->stream_enc_count; j++) { 1171 if (dc->res_pool->stream_enc[j]->id == enc_inst) { 1172 tg_inst = dc->res_pool->stream_enc[j]->funcs->dig_source_otg( 1173 dc->res_pool->stream_enc[j]); 1174 break; 1175 } 1176 } 1177 1178 dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz( 1179 dc->res_pool->dp_clock_source, 1180 tg_inst, &pix_clk_100hz); 1181 1182 if (link->link_status.link_active) { 1183 uint32_t requested_pix_clk_100hz = 1184 pipe->stream_res.pix_clk_params.requested_pix_clk_100hz; 1185 1186 if (pix_clk_100hz != requested_pix_clk_100hz) { 1187 core_link_disable_stream(pipe); 1188 pipe->stream->dpms_off = false; 1189 } 1190 } 1191 } 1192 } 1193 } 1194 } 1195 1196 static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context) 1197 { 1198 int i; 1199 PERF_TRACE(); 1200 for (i = 0; i < MAX_PIPES; i++) { 1201 int count = 0; 1202 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; 1203 1204 if (!pipe->plane_state || pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) 1205 continue; 1206 1207 /* Timeout 100 ms */ 1208 while (count < 100000) { 1209 /* Must set to false to start with, due to OR in update function */ 1210 pipe->plane_state->status.is_flip_pending = false; 1211 dc->hwss.update_pending_status(pipe); 1212 if (!pipe->plane_state->status.is_flip_pending) 1213 break; 1214 udelay(1); 1215 count++; 1216 } 1217 ASSERT(!pipe->plane_state->status.is_flip_pending); 1218 } 1219 PERF_TRACE(); 1220 } 1221 1222 /******************************************************************************* 1223 * Public functions 1224 ******************************************************************************/ 1225 1226 struct dc *dc_create(const struct dc_init_data *init_params) 1227 { 1228 struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL); 1229 unsigned int full_pipe_count; 1230 1231 if (!dc) 1232 return NULL; 1233 1234 if (init_params->dce_environment == DCE_ENV_VIRTUAL_HW) { 1235 if (!dc_construct_ctx(dc, init_params)) 1236 goto destruct_dc; 1237 } else { 1238 if (!dc_construct(dc, init_params)) 1239 goto destruct_dc; 1240 1241 full_pipe_count = dc->res_pool->pipe_count; 1242 if (dc->res_pool->underlay_pipe_index != NO_UNDERLAY_PIPE) 1243 full_pipe_count--; 1244 dc->caps.max_streams = min( 1245 full_pipe_count, 1246 dc->res_pool->stream_enc_count); 1247 1248 dc->caps.max_links = dc->link_count; 1249 dc->caps.max_audios = dc->res_pool->audio_count; 1250 dc->caps.linear_pitch_alignment = 64; 1251 1252 dc->caps.max_dp_protocol_version = DP_VERSION_1_4; 1253 1254 dc->caps.max_otg_num = dc->res_pool->res_cap->num_timing_generator; 1255 1256 if (dc->res_pool->dmcu != NULL) 1257 dc->versions.dmcu_version = dc->res_pool->dmcu->dmcu_version; 1258 } 1259 1260 dc->dcn_reg_offsets = init_params->dcn_reg_offsets; 1261 dc->nbio_reg_offsets = init_params->nbio_reg_offsets; 1262 1263 /* Populate versioning information */ 1264 dc->versions.dc_ver = DC_VER; 1265 1266 dc->build_id = DC_BUILD_ID; 1267 1268 DC_LOG_DC("Display Core initialized\n"); 1269 1270 1271 1272 return dc; 1273 1274 destruct_dc: 1275 dc_destruct(dc); 1276 kfree(dc); 1277 return NULL; 1278 } 1279 1280 static void detect_edp_presence(struct dc *dc) 1281 { 1282 struct dc_link *edp_links[MAX_NUM_EDP]; 1283 struct dc_link *edp_link = NULL; 1284 enum dc_connection_type type; 1285 int i; 1286 int edp_num; 1287 1288 get_edp_links(dc, edp_links, &edp_num); 1289 if (!edp_num) 1290 return; 1291 1292 for (i = 0; i < edp_num; i++) { 1293 edp_link = edp_links[i]; 1294 if (dc->config.edp_not_connected) { 1295 edp_link->edp_sink_present = false; 1296 } else { 1297 dc_link_detect_sink(edp_link, &type); 1298 edp_link->edp_sink_present = (type != dc_connection_none); 1299 } 1300 } 1301 } 1302 1303 void dc_hardware_init(struct dc *dc) 1304 { 1305 1306 detect_edp_presence(dc); 1307 if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW) 1308 dc->hwss.init_hw(dc); 1309 } 1310 1311 void dc_init_callbacks(struct dc *dc, 1312 const struct dc_callback_init *init_params) 1313 { 1314 #ifdef CONFIG_DRM_AMD_DC_HDCP 1315 dc->ctx->cp_psp = init_params->cp_psp; 1316 #endif 1317 } 1318 1319 void dc_deinit_callbacks(struct dc *dc) 1320 { 1321 #ifdef CONFIG_DRM_AMD_DC_HDCP 1322 memset(&dc->ctx->cp_psp, 0, sizeof(dc->ctx->cp_psp)); 1323 #endif 1324 } 1325 1326 void dc_destroy(struct dc **dc) 1327 { 1328 dc_destruct(*dc); 1329 kfree(*dc); 1330 *dc = NULL; 1331 } 1332 1333 static void enable_timing_multisync( 1334 struct dc *dc, 1335 struct dc_state *ctx) 1336 { 1337 int i, multisync_count = 0; 1338 int pipe_count = dc->res_pool->pipe_count; 1339 struct pipe_ctx *multisync_pipes[MAX_PIPES] = { NULL }; 1340 1341 for (i = 0; i < pipe_count; i++) { 1342 if (!ctx->res_ctx.pipe_ctx[i].stream || 1343 !ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.enabled) 1344 continue; 1345 if (ctx->res_ctx.pipe_ctx[i].stream == ctx->res_ctx.pipe_ctx[i].stream->triggered_crtc_reset.event_source) 1346 continue; 1347 multisync_pipes[multisync_count] = &ctx->res_ctx.pipe_ctx[i]; 1348 multisync_count++; 1349 } 1350 1351 if (multisync_count > 0) { 1352 dc->hwss.enable_per_frame_crtc_position_reset( 1353 dc, multisync_count, multisync_pipes); 1354 } 1355 } 1356 1357 static void program_timing_sync( 1358 struct dc *dc, 1359 struct dc_state *ctx) 1360 { 1361 int i, j, k; 1362 int group_index = 0; 1363 int num_group = 0; 1364 int pipe_count = dc->res_pool->pipe_count; 1365 struct pipe_ctx *unsynced_pipes[MAX_PIPES] = { NULL }; 1366 1367 for (i = 0; i < pipe_count; i++) { 1368 if (!ctx->res_ctx.pipe_ctx[i].stream 1369 || ctx->res_ctx.pipe_ctx[i].top_pipe 1370 || ctx->res_ctx.pipe_ctx[i].prev_odm_pipe) 1371 continue; 1372 1373 unsynced_pipes[i] = &ctx->res_ctx.pipe_ctx[i]; 1374 } 1375 1376 for (i = 0; i < pipe_count; i++) { 1377 int group_size = 1; 1378 enum timing_synchronization_type sync_type = NOT_SYNCHRONIZABLE; 1379 struct pipe_ctx *pipe_set[MAX_PIPES]; 1380 1381 if (!unsynced_pipes[i]) 1382 continue; 1383 1384 pipe_set[0] = unsynced_pipes[i]; 1385 unsynced_pipes[i] = NULL; 1386 1387 /* Add tg to the set, search rest of the tg's for ones with 1388 * same timing, add all tgs with same timing to the group 1389 */ 1390 for (j = i + 1; j < pipe_count; j++) { 1391 if (!unsynced_pipes[j]) 1392 continue; 1393 if (sync_type != TIMING_SYNCHRONIZABLE && 1394 dc->hwss.enable_vblanks_synchronization && 1395 unsynced_pipes[j]->stream_res.tg->funcs->align_vblanks && 1396 resource_are_vblanks_synchronizable( 1397 unsynced_pipes[j]->stream, 1398 pipe_set[0]->stream)) { 1399 sync_type = VBLANK_SYNCHRONIZABLE; 1400 pipe_set[group_size] = unsynced_pipes[j]; 1401 unsynced_pipes[j] = NULL; 1402 group_size++; 1403 } else 1404 if (sync_type != VBLANK_SYNCHRONIZABLE && 1405 resource_are_streams_timing_synchronizable( 1406 unsynced_pipes[j]->stream, 1407 pipe_set[0]->stream)) { 1408 sync_type = TIMING_SYNCHRONIZABLE; 1409 pipe_set[group_size] = unsynced_pipes[j]; 1410 unsynced_pipes[j] = NULL; 1411 group_size++; 1412 } 1413 } 1414 1415 /* set first unblanked pipe as master */ 1416 for (j = 0; j < group_size; j++) { 1417 bool is_blanked; 1418 1419 if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked) 1420 is_blanked = 1421 pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp); 1422 else 1423 is_blanked = 1424 pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg); 1425 if (!is_blanked) { 1426 if (j == 0) 1427 break; 1428 1429 swap(pipe_set[0], pipe_set[j]); 1430 break; 1431 } 1432 } 1433 1434 for (k = 0; k < group_size; k++) { 1435 struct dc_stream_status *status = dc_stream_get_status_from_state(ctx, pipe_set[k]->stream); 1436 1437 status->timing_sync_info.group_id = num_group; 1438 status->timing_sync_info.group_size = group_size; 1439 if (k == 0) 1440 status->timing_sync_info.master = true; 1441 else 1442 status->timing_sync_info.master = false; 1443 1444 } 1445 1446 /* remove any other pipes that are already been synced */ 1447 if (dc->config.use_pipe_ctx_sync_logic) { 1448 /* check pipe's syncd to decide which pipe to be removed */ 1449 for (j = 1; j < group_size; j++) { 1450 if (pipe_set[j]->pipe_idx_syncd == pipe_set[0]->pipe_idx_syncd) { 1451 group_size--; 1452 pipe_set[j] = pipe_set[group_size]; 1453 j--; 1454 } else 1455 /* link slave pipe's syncd with master pipe */ 1456 pipe_set[j]->pipe_idx_syncd = pipe_set[0]->pipe_idx_syncd; 1457 } 1458 } else { 1459 for (j = j + 1; j < group_size; j++) { 1460 bool is_blanked; 1461 1462 if (pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked) 1463 is_blanked = 1464 pipe_set[j]->stream_res.opp->funcs->dpg_is_blanked(pipe_set[j]->stream_res.opp); 1465 else 1466 is_blanked = 1467 pipe_set[j]->stream_res.tg->funcs->is_blanked(pipe_set[j]->stream_res.tg); 1468 if (!is_blanked) { 1469 group_size--; 1470 pipe_set[j] = pipe_set[group_size]; 1471 j--; 1472 } 1473 } 1474 } 1475 1476 if (group_size > 1) { 1477 if (sync_type == TIMING_SYNCHRONIZABLE) { 1478 dc->hwss.enable_timing_synchronization( 1479 dc, group_index, group_size, pipe_set); 1480 } else 1481 if (sync_type == VBLANK_SYNCHRONIZABLE) { 1482 dc->hwss.enable_vblanks_synchronization( 1483 dc, group_index, group_size, pipe_set); 1484 } 1485 group_index++; 1486 } 1487 num_group++; 1488 } 1489 } 1490 1491 static bool context_changed( 1492 struct dc *dc, 1493 struct dc_state *context) 1494 { 1495 uint8_t i; 1496 1497 if (context->stream_count != dc->current_state->stream_count) 1498 return true; 1499 1500 for (i = 0; i < dc->current_state->stream_count; i++) { 1501 if (dc->current_state->streams[i] != context->streams[i]) 1502 return true; 1503 } 1504 1505 return false; 1506 } 1507 1508 bool dc_validate_boot_timing(const struct dc *dc, 1509 const struct dc_sink *sink, 1510 struct dc_crtc_timing *crtc_timing) 1511 { 1512 struct timing_generator *tg; 1513 struct stream_encoder *se = NULL; 1514 1515 struct dc_crtc_timing hw_crtc_timing = {0}; 1516 1517 struct dc_link *link = sink->link; 1518 unsigned int i, enc_inst, tg_inst = 0; 1519 1520 /* Support seamless boot on EDP displays only */ 1521 if (sink->sink_signal != SIGNAL_TYPE_EDP) { 1522 return false; 1523 } 1524 1525 /* Check for enabled DIG to identify enabled display */ 1526 if (!link->link_enc->funcs->is_dig_enabled(link->link_enc)) 1527 return false; 1528 1529 enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc); 1530 1531 if (enc_inst == ENGINE_ID_UNKNOWN) 1532 return false; 1533 1534 for (i = 0; i < dc->res_pool->stream_enc_count; i++) { 1535 if (dc->res_pool->stream_enc[i]->id == enc_inst) { 1536 1537 se = dc->res_pool->stream_enc[i]; 1538 1539 tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg( 1540 dc->res_pool->stream_enc[i]); 1541 break; 1542 } 1543 } 1544 1545 // tg_inst not found 1546 if (i == dc->res_pool->stream_enc_count) 1547 return false; 1548 1549 if (tg_inst >= dc->res_pool->timing_generator_count) 1550 return false; 1551 1552 tg = dc->res_pool->timing_generators[tg_inst]; 1553 1554 if (!tg->funcs->get_hw_timing) 1555 return false; 1556 1557 if (!tg->funcs->get_hw_timing(tg, &hw_crtc_timing)) 1558 return false; 1559 1560 if (crtc_timing->h_total != hw_crtc_timing.h_total) 1561 return false; 1562 1563 if (crtc_timing->h_border_left != hw_crtc_timing.h_border_left) 1564 return false; 1565 1566 if (crtc_timing->h_addressable != hw_crtc_timing.h_addressable) 1567 return false; 1568 1569 if (crtc_timing->h_border_right != hw_crtc_timing.h_border_right) 1570 return false; 1571 1572 if (crtc_timing->h_front_porch != hw_crtc_timing.h_front_porch) 1573 return false; 1574 1575 if (crtc_timing->h_sync_width != hw_crtc_timing.h_sync_width) 1576 return false; 1577 1578 if (crtc_timing->v_total != hw_crtc_timing.v_total) 1579 return false; 1580 1581 if (crtc_timing->v_border_top != hw_crtc_timing.v_border_top) 1582 return false; 1583 1584 if (crtc_timing->v_addressable != hw_crtc_timing.v_addressable) 1585 return false; 1586 1587 if (crtc_timing->v_border_bottom != hw_crtc_timing.v_border_bottom) 1588 return false; 1589 1590 if (crtc_timing->v_front_porch != hw_crtc_timing.v_front_porch) 1591 return false; 1592 1593 if (crtc_timing->v_sync_width != hw_crtc_timing.v_sync_width) 1594 return false; 1595 1596 /* block DSC for now, as VBIOS does not currently support DSC timings */ 1597 if (crtc_timing->flags.DSC) 1598 return false; 1599 1600 if (dc_is_dp_signal(link->connector_signal)) { 1601 unsigned int pix_clk_100hz; 1602 uint32_t numOdmPipes = 1; 1603 uint32_t id_src[4] = {0}; 1604 1605 dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz( 1606 dc->res_pool->dp_clock_source, 1607 tg_inst, &pix_clk_100hz); 1608 1609 if (tg->funcs->get_optc_source) 1610 tg->funcs->get_optc_source(tg, 1611 &numOdmPipes, &id_src[0], &id_src[1]); 1612 1613 if (numOdmPipes == 2) 1614 pix_clk_100hz *= 2; 1615 if (numOdmPipes == 4) 1616 pix_clk_100hz *= 4; 1617 1618 // Note: In rare cases, HW pixclk may differ from crtc's pixclk 1619 // slightly due to rounding issues in 10 kHz units. 1620 if (crtc_timing->pix_clk_100hz != pix_clk_100hz) 1621 return false; 1622 1623 if (!se->funcs->dp_get_pixel_format) 1624 return false; 1625 1626 if (!se->funcs->dp_get_pixel_format( 1627 se, 1628 &hw_crtc_timing.pixel_encoding, 1629 &hw_crtc_timing.display_color_depth)) 1630 return false; 1631 1632 if (hw_crtc_timing.display_color_depth != crtc_timing->display_color_depth) 1633 return false; 1634 1635 if (hw_crtc_timing.pixel_encoding != crtc_timing->pixel_encoding) 1636 return false; 1637 } 1638 1639 if (link->dpcd_caps.dprx_feature.bits.VSC_SDP_COLORIMETRY_SUPPORTED) { 1640 return false; 1641 } 1642 1643 if (is_edp_ilr_optimization_required(link, crtc_timing)) { 1644 DC_LOG_EVENT_LINK_TRAINING("Seamless boot disabled to optimize eDP link rate\n"); 1645 return false; 1646 } 1647 1648 return true; 1649 } 1650 1651 static inline bool should_update_pipe_for_stream( 1652 struct dc_state *context, 1653 struct pipe_ctx *pipe_ctx, 1654 struct dc_stream_state *stream) 1655 { 1656 return (pipe_ctx->stream && pipe_ctx->stream == stream); 1657 } 1658 1659 static inline bool should_update_pipe_for_plane( 1660 struct dc_state *context, 1661 struct pipe_ctx *pipe_ctx, 1662 struct dc_plane_state *plane_state) 1663 { 1664 return (pipe_ctx->plane_state == plane_state); 1665 } 1666 1667 void dc_enable_stereo( 1668 struct dc *dc, 1669 struct dc_state *context, 1670 struct dc_stream_state *streams[], 1671 uint8_t stream_count) 1672 { 1673 int i, j; 1674 struct pipe_ctx *pipe; 1675 1676 for (i = 0; i < MAX_PIPES; i++) { 1677 if (context != NULL) { 1678 pipe = &context->res_ctx.pipe_ctx[i]; 1679 } else { 1680 context = dc->current_state; 1681 pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 1682 } 1683 1684 for (j = 0; pipe && j < stream_count; j++) { 1685 if (should_update_pipe_for_stream(context, pipe, streams[j]) && 1686 dc->hwss.setup_stereo) 1687 dc->hwss.setup_stereo(pipe, dc); 1688 } 1689 } 1690 } 1691 1692 void dc_trigger_sync(struct dc *dc, struct dc_state *context) 1693 { 1694 if (context->stream_count > 1 && !dc->debug.disable_timing_sync) { 1695 enable_timing_multisync(dc, context); 1696 program_timing_sync(dc, context); 1697 } 1698 } 1699 1700 static uint8_t get_stream_mask(struct dc *dc, struct dc_state *context) 1701 { 1702 int i; 1703 unsigned int stream_mask = 0; 1704 1705 for (i = 0; i < dc->res_pool->pipe_count; i++) { 1706 if (context->res_ctx.pipe_ctx[i].stream) 1707 stream_mask |= 1 << i; 1708 } 1709 1710 return stream_mask; 1711 } 1712 1713 void dc_z10_restore(const struct dc *dc) 1714 { 1715 if (dc->hwss.z10_restore) 1716 dc->hwss.z10_restore(dc); 1717 } 1718 1719 void dc_z10_save_init(struct dc *dc) 1720 { 1721 if (dc->hwss.z10_save_init) 1722 dc->hwss.z10_save_init(dc); 1723 } 1724 1725 /* 1726 * Applies given context to HW and copy it into current context. 1727 * It's up to the user to release the src context afterwards. 1728 */ 1729 static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *context) 1730 { 1731 struct dc_bios *dcb = dc->ctx->dc_bios; 1732 enum dc_status result = DC_ERROR_UNEXPECTED; 1733 struct pipe_ctx *pipe; 1734 int i, k, l; 1735 struct dc_stream_state *dc_streams[MAX_STREAMS] = {0}; 1736 struct dc_state *old_state; 1737 bool subvp_prev_use = false; 1738 1739 dc_z10_restore(dc); 1740 dc_allow_idle_optimizations(dc, false); 1741 1742 for (i = 0; i < dc->res_pool->pipe_count; i++) { 1743 struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 1744 1745 /* Check old context for SubVP */ 1746 subvp_prev_use |= (old_pipe->stream && old_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM); 1747 if (subvp_prev_use) 1748 break; 1749 } 1750 1751 for (i = 0; i < context->stream_count; i++) 1752 dc_streams[i] = context->streams[i]; 1753 1754 if (!dcb->funcs->is_accelerated_mode(dcb)) { 1755 disable_vbios_mode_if_required(dc, context); 1756 dc->hwss.enable_accelerated_mode(dc, context); 1757 } 1758 1759 if (context->stream_count > get_seamless_boot_stream_count(context) || 1760 context->stream_count == 0) 1761 dc->hwss.prepare_bandwidth(dc, context); 1762 1763 if (dc->debug.enable_double_buffered_dsc_pg_support) 1764 dc->hwss.update_dsc_pg(dc, context, false); 1765 1766 disable_dangling_plane(dc, context); 1767 /* re-program planes for existing stream, in case we need to 1768 * free up plane resource for later use 1769 */ 1770 if (dc->hwss.apply_ctx_for_surface) { 1771 for (i = 0; i < context->stream_count; i++) { 1772 if (context->streams[i]->mode_changed) 1773 continue; 1774 apply_ctx_interdependent_lock(dc, context, context->streams[i], true); 1775 dc->hwss.apply_ctx_for_surface( 1776 dc, context->streams[i], 1777 context->stream_status[i].plane_count, 1778 context); /* use new pipe config in new context */ 1779 apply_ctx_interdependent_lock(dc, context, context->streams[i], false); 1780 dc->hwss.post_unlock_program_front_end(dc, context); 1781 } 1782 } 1783 1784 /* Program hardware */ 1785 for (i = 0; i < dc->res_pool->pipe_count; i++) { 1786 pipe = &context->res_ctx.pipe_ctx[i]; 1787 dc->hwss.wait_for_mpcc_disconnect(dc, dc->res_pool, pipe); 1788 } 1789 1790 if (dc->hwss.subvp_pipe_control_lock) 1791 dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use); 1792 1793 result = dc->hwss.apply_ctx_to_hw(dc, context); 1794 1795 if (result != DC_OK) { 1796 /* Application of dc_state to hardware stopped. */ 1797 dc->current_state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_STEADY; 1798 return result; 1799 } 1800 1801 dc_trigger_sync(dc, context); 1802 1803 /* Program all planes within new context*/ 1804 if (dc->hwss.program_front_end_for_ctx) { 1805 dc->hwss.interdependent_update_lock(dc, context, true); 1806 dc->hwss.program_front_end_for_ctx(dc, context); 1807 dc->hwss.interdependent_update_lock(dc, context, false); 1808 dc->hwss.post_unlock_program_front_end(dc, context); 1809 } 1810 1811 if (dc->hwss.commit_subvp_config) 1812 dc->hwss.commit_subvp_config(dc, context); 1813 if (dc->hwss.subvp_pipe_control_lock) 1814 dc->hwss.subvp_pipe_control_lock(dc, context, false, true, NULL, subvp_prev_use); 1815 1816 for (i = 0; i < context->stream_count; i++) { 1817 const struct dc_link *link = context->streams[i]->link; 1818 1819 if (!context->streams[i]->mode_changed) 1820 continue; 1821 1822 if (dc->hwss.apply_ctx_for_surface) { 1823 apply_ctx_interdependent_lock(dc, context, context->streams[i], true); 1824 dc->hwss.apply_ctx_for_surface( 1825 dc, context->streams[i], 1826 context->stream_status[i].plane_count, 1827 context); 1828 apply_ctx_interdependent_lock(dc, context, context->streams[i], false); 1829 dc->hwss.post_unlock_program_front_end(dc, context); 1830 } 1831 1832 /* 1833 * enable stereo 1834 * TODO rework dc_enable_stereo call to work with validation sets? 1835 */ 1836 for (k = 0; k < MAX_PIPES; k++) { 1837 pipe = &context->res_ctx.pipe_ctx[k]; 1838 1839 for (l = 0 ; pipe && l < context->stream_count; l++) { 1840 if (context->streams[l] && 1841 context->streams[l] == pipe->stream && 1842 dc->hwss.setup_stereo) 1843 dc->hwss.setup_stereo(pipe, dc); 1844 } 1845 } 1846 1847 CONN_MSG_MODE(link, "{%dx%d, %dx%d@%dKhz}", 1848 context->streams[i]->timing.h_addressable, 1849 context->streams[i]->timing.v_addressable, 1850 context->streams[i]->timing.h_total, 1851 context->streams[i]->timing.v_total, 1852 context->streams[i]->timing.pix_clk_100hz / 10); 1853 } 1854 1855 dc_enable_stereo(dc, context, dc_streams, context->stream_count); 1856 1857 if (context->stream_count > get_seamless_boot_stream_count(context) || 1858 context->stream_count == 0) { 1859 /* Must wait for no flips to be pending before doing optimize bw */ 1860 wait_for_no_pipes_pending(dc, context); 1861 /* pplib is notified if disp_num changed */ 1862 dc->hwss.optimize_bandwidth(dc, context); 1863 } 1864 1865 if (dc->debug.enable_double_buffered_dsc_pg_support) 1866 dc->hwss.update_dsc_pg(dc, context, true); 1867 1868 if (dc->ctx->dce_version >= DCE_VERSION_MAX) 1869 TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk); 1870 else 1871 TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce); 1872 1873 context->stream_mask = get_stream_mask(dc, context); 1874 1875 if (context->stream_mask != dc->current_state->stream_mask) 1876 dc_dmub_srv_notify_stream_mask(dc->ctx->dmub_srv, context->stream_mask); 1877 1878 for (i = 0; i < context->stream_count; i++) 1879 context->streams[i]->mode_changed = false; 1880 1881 old_state = dc->current_state; 1882 dc->current_state = context; 1883 1884 dc_release_state(old_state); 1885 1886 dc_retain_state(dc->current_state); 1887 1888 return result; 1889 } 1890 1891 bool dc_commit_state(struct dc *dc, struct dc_state *context) 1892 { 1893 enum dc_status result = DC_ERROR_UNEXPECTED; 1894 int i; 1895 1896 if (!context_changed(dc, context)) 1897 return DC_OK; 1898 1899 DC_LOG_DC("%s: %d streams\n", 1900 __func__, context->stream_count); 1901 1902 for (i = 0; i < context->stream_count; i++) { 1903 struct dc_stream_state *stream = context->streams[i]; 1904 1905 dc_stream_log(dc, stream); 1906 } 1907 1908 /* 1909 * Previous validation was perfomred with fast_validation = true and 1910 * the full DML state required for hardware programming was skipped. 1911 * 1912 * Re-validate here to calculate these parameters / watermarks. 1913 */ 1914 result = dc_validate_global_state(dc, context, false); 1915 if (result != DC_OK) { 1916 DC_LOG_ERROR("DC commit global validation failure: %s (%d)", 1917 dc_status_to_str(result), result); 1918 return result; 1919 } 1920 1921 result = dc_commit_state_no_check(dc, context); 1922 1923 return (result == DC_OK); 1924 } 1925 1926 bool dc_acquire_release_mpc_3dlut( 1927 struct dc *dc, bool acquire, 1928 struct dc_stream_state *stream, 1929 struct dc_3dlut **lut, 1930 struct dc_transfer_func **shaper) 1931 { 1932 int pipe_idx; 1933 bool ret = false; 1934 bool found_pipe_idx = false; 1935 const struct resource_pool *pool = dc->res_pool; 1936 struct resource_context *res_ctx = &dc->current_state->res_ctx; 1937 int mpcc_id = 0; 1938 1939 if (pool && res_ctx) { 1940 if (acquire) { 1941 /*find pipe idx for the given stream*/ 1942 for (pipe_idx = 0; pipe_idx < pool->pipe_count; pipe_idx++) { 1943 if (res_ctx->pipe_ctx[pipe_idx].stream == stream) { 1944 found_pipe_idx = true; 1945 mpcc_id = res_ctx->pipe_ctx[pipe_idx].plane_res.hubp->inst; 1946 break; 1947 } 1948 } 1949 } else 1950 found_pipe_idx = true;/*for release pipe_idx is not required*/ 1951 1952 if (found_pipe_idx) { 1953 if (acquire && pool->funcs->acquire_post_bldn_3dlut) 1954 ret = pool->funcs->acquire_post_bldn_3dlut(res_ctx, pool, mpcc_id, lut, shaper); 1955 else if (!acquire && pool->funcs->release_post_bldn_3dlut) 1956 ret = pool->funcs->release_post_bldn_3dlut(res_ctx, pool, lut, shaper); 1957 } 1958 } 1959 return ret; 1960 } 1961 1962 static bool is_flip_pending_in_pipes(struct dc *dc, struct dc_state *context) 1963 { 1964 int i; 1965 struct pipe_ctx *pipe; 1966 1967 for (i = 0; i < MAX_PIPES; i++) { 1968 pipe = &context->res_ctx.pipe_ctx[i]; 1969 1970 // Don't check flip pending on phantom pipes 1971 if (!pipe->plane_state || (pipe->stream && pipe->stream->mall_stream_config.type == SUBVP_PHANTOM)) 1972 continue; 1973 1974 /* Must set to false to start with, due to OR in update function */ 1975 pipe->plane_state->status.is_flip_pending = false; 1976 dc->hwss.update_pending_status(pipe); 1977 if (pipe->plane_state->status.is_flip_pending) 1978 return true; 1979 } 1980 return false; 1981 } 1982 1983 /* Perform updates here which need to be deferred until next vupdate 1984 * 1985 * i.e. blnd lut, 3dlut, and shaper lut bypass regs are double buffered 1986 * but forcing lut memory to shutdown state is immediate. This causes 1987 * single frame corruption as lut gets disabled mid-frame unless shutdown 1988 * is deferred until after entering bypass. 1989 */ 1990 static void process_deferred_updates(struct dc *dc) 1991 { 1992 int i = 0; 1993 1994 if (dc->debug.enable_mem_low_power.bits.cm) { 1995 ASSERT(dc->dcn_ip->max_num_dpp); 1996 for (i = 0; i < dc->dcn_ip->max_num_dpp; i++) 1997 if (dc->res_pool->dpps[i]->funcs->dpp_deferred_update) 1998 dc->res_pool->dpps[i]->funcs->dpp_deferred_update(dc->res_pool->dpps[i]); 1999 } 2000 } 2001 2002 void dc_post_update_surfaces_to_stream(struct dc *dc) 2003 { 2004 int i; 2005 struct dc_state *context = dc->current_state; 2006 2007 if ((!dc->optimized_required) || get_seamless_boot_stream_count(context) > 0) 2008 return; 2009 2010 post_surface_trace(dc); 2011 2012 if (dc->ctx->dce_version >= DCE_VERSION_MAX) 2013 TRACE_DCN_CLOCK_STATE(&context->bw_ctx.bw.dcn.clk); 2014 else 2015 TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce); 2016 2017 if (is_flip_pending_in_pipes(dc, context)) 2018 return; 2019 2020 for (i = 0; i < dc->res_pool->pipe_count; i++) 2021 if (context->res_ctx.pipe_ctx[i].stream == NULL || 2022 context->res_ctx.pipe_ctx[i].plane_state == NULL) { 2023 context->res_ctx.pipe_ctx[i].pipe_idx = i; 2024 dc->hwss.disable_plane(dc, &context->res_ctx.pipe_ctx[i]); 2025 } 2026 2027 process_deferred_updates(dc); 2028 2029 dc->hwss.optimize_bandwidth(dc, context); 2030 2031 if (dc->debug.enable_double_buffered_dsc_pg_support) 2032 dc->hwss.update_dsc_pg(dc, context, true); 2033 2034 dc->optimized_required = false; 2035 dc->wm_optimized_required = false; 2036 } 2037 2038 static void init_state(struct dc *dc, struct dc_state *context) 2039 { 2040 /* Each context must have their own instance of VBA and in order to 2041 * initialize and obtain IP and SOC the base DML instance from DC is 2042 * initially copied into every context 2043 */ 2044 memcpy(&context->bw_ctx.dml, &dc->dml, sizeof(struct display_mode_lib)); 2045 } 2046 2047 struct dc_state *dc_create_state(struct dc *dc) 2048 { 2049 struct dc_state *context = kvzalloc(sizeof(struct dc_state), 2050 GFP_KERNEL); 2051 2052 if (!context) 2053 return NULL; 2054 2055 init_state(dc, context); 2056 2057 kref_init(&context->refcount); 2058 2059 return context; 2060 } 2061 2062 struct dc_state *dc_copy_state(struct dc_state *src_ctx) 2063 { 2064 int i, j; 2065 struct dc_state *new_ctx = kvmalloc(sizeof(struct dc_state), GFP_KERNEL); 2066 2067 if (!new_ctx) 2068 return NULL; 2069 memcpy(new_ctx, src_ctx, sizeof(struct dc_state)); 2070 2071 for (i = 0; i < MAX_PIPES; i++) { 2072 struct pipe_ctx *cur_pipe = &new_ctx->res_ctx.pipe_ctx[i]; 2073 2074 if (cur_pipe->top_pipe) 2075 cur_pipe->top_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->top_pipe->pipe_idx]; 2076 2077 if (cur_pipe->bottom_pipe) 2078 cur_pipe->bottom_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->bottom_pipe->pipe_idx]; 2079 2080 if (cur_pipe->prev_odm_pipe) 2081 cur_pipe->prev_odm_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->prev_odm_pipe->pipe_idx]; 2082 2083 if (cur_pipe->next_odm_pipe) 2084 cur_pipe->next_odm_pipe = &new_ctx->res_ctx.pipe_ctx[cur_pipe->next_odm_pipe->pipe_idx]; 2085 2086 } 2087 2088 for (i = 0; i < new_ctx->stream_count; i++) { 2089 dc_stream_retain(new_ctx->streams[i]); 2090 for (j = 0; j < new_ctx->stream_status[i].plane_count; j++) 2091 dc_plane_state_retain( 2092 new_ctx->stream_status[i].plane_states[j]); 2093 } 2094 2095 kref_init(&new_ctx->refcount); 2096 2097 return new_ctx; 2098 } 2099 2100 void dc_retain_state(struct dc_state *context) 2101 { 2102 kref_get(&context->refcount); 2103 } 2104 2105 static void dc_state_free(struct kref *kref) 2106 { 2107 struct dc_state *context = container_of(kref, struct dc_state, refcount); 2108 dc_resource_state_destruct(context); 2109 kvfree(context); 2110 } 2111 2112 void dc_release_state(struct dc_state *context) 2113 { 2114 kref_put(&context->refcount, dc_state_free); 2115 } 2116 2117 bool dc_set_generic_gpio_for_stereo(bool enable, 2118 struct gpio_service *gpio_service) 2119 { 2120 enum gpio_result gpio_result = GPIO_RESULT_NON_SPECIFIC_ERROR; 2121 struct gpio_pin_info pin_info; 2122 struct gpio *generic; 2123 struct gpio_generic_mux_config *config = kzalloc(sizeof(struct gpio_generic_mux_config), 2124 GFP_KERNEL); 2125 2126 if (!config) 2127 return false; 2128 pin_info = dal_gpio_get_generic_pin_info(gpio_service, GPIO_ID_GENERIC, 0); 2129 2130 if (pin_info.mask == 0xFFFFFFFF || pin_info.offset == 0xFFFFFFFF) { 2131 kfree(config); 2132 return false; 2133 } else { 2134 generic = dal_gpio_service_create_generic_mux( 2135 gpio_service, 2136 pin_info.offset, 2137 pin_info.mask); 2138 } 2139 2140 if (!generic) { 2141 kfree(config); 2142 return false; 2143 } 2144 2145 gpio_result = dal_gpio_open(generic, GPIO_MODE_OUTPUT); 2146 2147 config->enable_output_from_mux = enable; 2148 config->mux_select = GPIO_SIGNAL_SOURCE_PASS_THROUGH_STEREO_SYNC; 2149 2150 if (gpio_result == GPIO_RESULT_OK) 2151 gpio_result = dal_mux_setup_config(generic, config); 2152 2153 if (gpio_result == GPIO_RESULT_OK) { 2154 dal_gpio_close(generic); 2155 dal_gpio_destroy_generic_mux(&generic); 2156 kfree(config); 2157 return true; 2158 } else { 2159 dal_gpio_close(generic); 2160 dal_gpio_destroy_generic_mux(&generic); 2161 kfree(config); 2162 return false; 2163 } 2164 } 2165 2166 static bool is_surface_in_context( 2167 const struct dc_state *context, 2168 const struct dc_plane_state *plane_state) 2169 { 2170 int j; 2171 2172 for (j = 0; j < MAX_PIPES; j++) { 2173 const struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 2174 2175 if (plane_state == pipe_ctx->plane_state) { 2176 return true; 2177 } 2178 } 2179 2180 return false; 2181 } 2182 2183 static enum surface_update_type get_plane_info_update_type(const struct dc_surface_update *u) 2184 { 2185 union surface_update_flags *update_flags = &u->surface->update_flags; 2186 enum surface_update_type update_type = UPDATE_TYPE_FAST; 2187 2188 if (!u->plane_info) 2189 return UPDATE_TYPE_FAST; 2190 2191 if (u->plane_info->color_space != u->surface->color_space) { 2192 update_flags->bits.color_space_change = 1; 2193 elevate_update_type(&update_type, UPDATE_TYPE_MED); 2194 } 2195 2196 if (u->plane_info->horizontal_mirror != u->surface->horizontal_mirror) { 2197 update_flags->bits.horizontal_mirror_change = 1; 2198 elevate_update_type(&update_type, UPDATE_TYPE_MED); 2199 } 2200 2201 if (u->plane_info->rotation != u->surface->rotation) { 2202 update_flags->bits.rotation_change = 1; 2203 elevate_update_type(&update_type, UPDATE_TYPE_FULL); 2204 } 2205 2206 if (u->plane_info->format != u->surface->format) { 2207 update_flags->bits.pixel_format_change = 1; 2208 elevate_update_type(&update_type, UPDATE_TYPE_FULL); 2209 } 2210 2211 if (u->plane_info->stereo_format != u->surface->stereo_format) { 2212 update_flags->bits.stereo_format_change = 1; 2213 elevate_update_type(&update_type, UPDATE_TYPE_FULL); 2214 } 2215 2216 if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha) { 2217 update_flags->bits.per_pixel_alpha_change = 1; 2218 elevate_update_type(&update_type, UPDATE_TYPE_MED); 2219 } 2220 2221 if (u->plane_info->global_alpha_value != u->surface->global_alpha_value) { 2222 update_flags->bits.global_alpha_change = 1; 2223 elevate_update_type(&update_type, UPDATE_TYPE_MED); 2224 } 2225 2226 if (u->plane_info->dcc.enable != u->surface->dcc.enable 2227 || u->plane_info->dcc.dcc_ind_blk != u->surface->dcc.dcc_ind_blk 2228 || u->plane_info->dcc.meta_pitch != u->surface->dcc.meta_pitch) { 2229 /* During DCC on/off, stutter period is calculated before 2230 * DCC has fully transitioned. This results in incorrect 2231 * stutter period calculation. Triggering a full update will 2232 * recalculate stutter period. 2233 */ 2234 update_flags->bits.dcc_change = 1; 2235 elevate_update_type(&update_type, UPDATE_TYPE_FULL); 2236 } 2237 2238 if (resource_pixel_format_to_bpp(u->plane_info->format) != 2239 resource_pixel_format_to_bpp(u->surface->format)) { 2240 /* different bytes per element will require full bandwidth 2241 * and DML calculation 2242 */ 2243 update_flags->bits.bpp_change = 1; 2244 elevate_update_type(&update_type, UPDATE_TYPE_FULL); 2245 } 2246 2247 if (u->plane_info->plane_size.surface_pitch != u->surface->plane_size.surface_pitch 2248 || u->plane_info->plane_size.chroma_pitch != u->surface->plane_size.chroma_pitch) { 2249 update_flags->bits.plane_size_change = 1; 2250 elevate_update_type(&update_type, UPDATE_TYPE_MED); 2251 } 2252 2253 2254 if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info, 2255 sizeof(union dc_tiling_info)) != 0) { 2256 update_flags->bits.swizzle_change = 1; 2257 elevate_update_type(&update_type, UPDATE_TYPE_MED); 2258 2259 /* todo: below are HW dependent, we should add a hook to 2260 * DCE/N resource and validated there. 2261 */ 2262 if (u->plane_info->tiling_info.gfx9.swizzle != DC_SW_LINEAR) { 2263 /* swizzled mode requires RQ to be setup properly, 2264 * thus need to run DML to calculate RQ settings 2265 */ 2266 update_flags->bits.bandwidth_change = 1; 2267 elevate_update_type(&update_type, UPDATE_TYPE_FULL); 2268 } 2269 } 2270 2271 /* This should be UPDATE_TYPE_FAST if nothing has changed. */ 2272 return update_type; 2273 } 2274 2275 static enum surface_update_type get_scaling_info_update_type( 2276 const struct dc_surface_update *u) 2277 { 2278 union surface_update_flags *update_flags = &u->surface->update_flags; 2279 2280 if (!u->scaling_info) 2281 return UPDATE_TYPE_FAST; 2282 2283 if (u->scaling_info->clip_rect.width != u->surface->clip_rect.width 2284 || u->scaling_info->clip_rect.height != u->surface->clip_rect.height 2285 || u->scaling_info->dst_rect.width != u->surface->dst_rect.width 2286 || u->scaling_info->dst_rect.height != u->surface->dst_rect.height 2287 || u->scaling_info->scaling_quality.integer_scaling != 2288 u->surface->scaling_quality.integer_scaling 2289 ) { 2290 update_flags->bits.scaling_change = 1; 2291 2292 if ((u->scaling_info->dst_rect.width < u->surface->dst_rect.width 2293 || u->scaling_info->dst_rect.height < u->surface->dst_rect.height) 2294 && (u->scaling_info->dst_rect.width < u->surface->src_rect.width 2295 || u->scaling_info->dst_rect.height < u->surface->src_rect.height)) 2296 /* Making dst rect smaller requires a bandwidth change */ 2297 update_flags->bits.bandwidth_change = 1; 2298 } 2299 2300 if (u->scaling_info->src_rect.width != u->surface->src_rect.width 2301 || u->scaling_info->src_rect.height != u->surface->src_rect.height) { 2302 2303 update_flags->bits.scaling_change = 1; 2304 if (u->scaling_info->src_rect.width > u->surface->src_rect.width 2305 || u->scaling_info->src_rect.height > u->surface->src_rect.height) 2306 /* Making src rect bigger requires a bandwidth change */ 2307 update_flags->bits.clock_change = 1; 2308 } 2309 2310 if (u->scaling_info->src_rect.x != u->surface->src_rect.x 2311 || u->scaling_info->src_rect.y != u->surface->src_rect.y 2312 || u->scaling_info->clip_rect.x != u->surface->clip_rect.x 2313 || u->scaling_info->clip_rect.y != u->surface->clip_rect.y 2314 || u->scaling_info->dst_rect.x != u->surface->dst_rect.x 2315 || u->scaling_info->dst_rect.y != u->surface->dst_rect.y) 2316 update_flags->bits.position_change = 1; 2317 2318 if (update_flags->bits.clock_change 2319 || update_flags->bits.bandwidth_change 2320 || update_flags->bits.scaling_change) 2321 return UPDATE_TYPE_FULL; 2322 2323 if (update_flags->bits.position_change) 2324 return UPDATE_TYPE_MED; 2325 2326 return UPDATE_TYPE_FAST; 2327 } 2328 2329 static enum surface_update_type det_surface_update(const struct dc *dc, 2330 const struct dc_surface_update *u) 2331 { 2332 const struct dc_state *context = dc->current_state; 2333 enum surface_update_type type; 2334 enum surface_update_type overall_type = UPDATE_TYPE_FAST; 2335 union surface_update_flags *update_flags = &u->surface->update_flags; 2336 2337 if (u->flip_addr) 2338 update_flags->bits.addr_update = 1; 2339 2340 if (!is_surface_in_context(context, u->surface) || u->surface->force_full_update) { 2341 update_flags->raw = 0xFFFFFFFF; 2342 return UPDATE_TYPE_FULL; 2343 } 2344 2345 update_flags->raw = 0; // Reset all flags 2346 2347 type = get_plane_info_update_type(u); 2348 elevate_update_type(&overall_type, type); 2349 2350 type = get_scaling_info_update_type(u); 2351 elevate_update_type(&overall_type, type); 2352 2353 if (u->flip_addr) { 2354 update_flags->bits.addr_update = 1; 2355 if (u->flip_addr->address.tmz_surface != u->surface->address.tmz_surface) { 2356 update_flags->bits.tmz_changed = 1; 2357 elevate_update_type(&overall_type, UPDATE_TYPE_FULL); 2358 } 2359 } 2360 if (u->in_transfer_func) 2361 update_flags->bits.in_transfer_func_change = 1; 2362 2363 if (u->input_csc_color_matrix) 2364 update_flags->bits.input_csc_change = 1; 2365 2366 if (u->coeff_reduction_factor) 2367 update_flags->bits.coeff_reduction_change = 1; 2368 2369 if (u->gamut_remap_matrix) 2370 update_flags->bits.gamut_remap_change = 1; 2371 2372 if (u->gamma) { 2373 enum surface_pixel_format format = SURFACE_PIXEL_FORMAT_GRPH_BEGIN; 2374 2375 if (u->plane_info) 2376 format = u->plane_info->format; 2377 else if (u->surface) 2378 format = u->surface->format; 2379 2380 if (dce_use_lut(format)) 2381 update_flags->bits.gamma_change = 1; 2382 } 2383 2384 if (u->lut3d_func || u->func_shaper) 2385 update_flags->bits.lut_3d = 1; 2386 2387 if (u->hdr_mult.value) 2388 if (u->hdr_mult.value != u->surface->hdr_mult.value) { 2389 update_flags->bits.hdr_mult = 1; 2390 elevate_update_type(&overall_type, UPDATE_TYPE_MED); 2391 } 2392 2393 if (update_flags->bits.in_transfer_func_change) { 2394 type = UPDATE_TYPE_MED; 2395 elevate_update_type(&overall_type, type); 2396 } 2397 2398 if (update_flags->bits.input_csc_change 2399 || update_flags->bits.coeff_reduction_change 2400 || update_flags->bits.lut_3d 2401 || update_flags->bits.gamma_change 2402 || update_flags->bits.gamut_remap_change) { 2403 type = UPDATE_TYPE_FULL; 2404 elevate_update_type(&overall_type, type); 2405 } 2406 2407 return overall_type; 2408 } 2409 2410 static enum surface_update_type check_update_surfaces_for_stream( 2411 struct dc *dc, 2412 struct dc_surface_update *updates, 2413 int surface_count, 2414 struct dc_stream_update *stream_update, 2415 const struct dc_stream_status *stream_status) 2416 { 2417 int i; 2418 enum surface_update_type overall_type = UPDATE_TYPE_FAST; 2419 2420 if (dc->idle_optimizations_allowed) 2421 overall_type = UPDATE_TYPE_FULL; 2422 2423 if (stream_status == NULL || stream_status->plane_count != surface_count) 2424 overall_type = UPDATE_TYPE_FULL; 2425 2426 if (stream_update && stream_update->pending_test_pattern) { 2427 overall_type = UPDATE_TYPE_FULL; 2428 } 2429 2430 /* some stream updates require passive update */ 2431 if (stream_update) { 2432 union stream_update_flags *su_flags = &stream_update->stream->update_flags; 2433 2434 if ((stream_update->src.height != 0 && stream_update->src.width != 0) || 2435 (stream_update->dst.height != 0 && stream_update->dst.width != 0) || 2436 stream_update->integer_scaling_update) 2437 su_flags->bits.scaling = 1; 2438 2439 if (stream_update->out_transfer_func) 2440 su_flags->bits.out_tf = 1; 2441 2442 if (stream_update->abm_level) 2443 su_flags->bits.abm_level = 1; 2444 2445 if (stream_update->dpms_off) 2446 su_flags->bits.dpms_off = 1; 2447 2448 if (stream_update->gamut_remap) 2449 su_flags->bits.gamut_remap = 1; 2450 2451 if (stream_update->wb_update) 2452 su_flags->bits.wb_update = 1; 2453 2454 if (stream_update->dsc_config) 2455 su_flags->bits.dsc_changed = 1; 2456 2457 if (stream_update->mst_bw_update) 2458 su_flags->bits.mst_bw = 1; 2459 if (stream_update->crtc_timing_adjust && dc_extended_blank_supported(dc)) 2460 su_flags->bits.crtc_timing_adjust = 1; 2461 2462 if (su_flags->raw != 0) 2463 overall_type = UPDATE_TYPE_FULL; 2464 2465 if (stream_update->output_csc_transform || stream_update->output_color_space) 2466 su_flags->bits.out_csc = 1; 2467 } 2468 2469 for (i = 0 ; i < surface_count; i++) { 2470 enum surface_update_type type = 2471 det_surface_update(dc, &updates[i]); 2472 2473 elevate_update_type(&overall_type, type); 2474 } 2475 2476 return overall_type; 2477 } 2478 2479 static bool dc_check_is_fullscreen_video(struct rect src, struct rect clip_rect) 2480 { 2481 int view_height, view_width, clip_x, clip_y, clip_width, clip_height; 2482 2483 view_height = src.height; 2484 view_width = src.width; 2485 2486 clip_x = clip_rect.x; 2487 clip_y = clip_rect.y; 2488 2489 clip_width = clip_rect.width; 2490 clip_height = clip_rect.height; 2491 2492 /* check for centered video accounting for off by 1 scaling truncation */ 2493 if ((view_height - clip_y - clip_height <= clip_y + 1) && 2494 (view_width - clip_x - clip_width <= clip_x + 1) && 2495 (view_height - clip_y - clip_height >= clip_y - 1) && 2496 (view_width - clip_x - clip_width >= clip_x - 1)) { 2497 2498 /* when OS scales up/down to letter box, it may end up 2499 * with few blank pixels on the border due to truncating. 2500 * Add offset margin to account for this 2501 */ 2502 if (clip_x <= 4 || clip_y <= 4) 2503 return true; 2504 } 2505 2506 return false; 2507 } 2508 2509 static enum surface_update_type check_boundary_crossing_for_windowed_mpo_with_odm(struct dc *dc, 2510 struct dc_surface_update *srf_updates, int surface_count, 2511 enum surface_update_type update_type) 2512 { 2513 enum surface_update_type new_update_type = update_type; 2514 int i, j; 2515 struct pipe_ctx *pipe = NULL; 2516 struct dc_stream_state *stream; 2517 2518 /* Check that we are in windowed MPO with ODM 2519 * - look for MPO pipe by scanning pipes for first pipe matching 2520 * surface that has moved ( position change ) 2521 * - MPO pipe will have top pipe 2522 * - check that top pipe has ODM pointer 2523 */ 2524 if ((surface_count > 1) && dc->config.enable_windowed_mpo_odm) { 2525 for (i = 0; i < surface_count; i++) { 2526 if (srf_updates[i].surface && srf_updates[i].scaling_info 2527 && srf_updates[i].surface->update_flags.bits.position_change) { 2528 2529 for (j = 0; j < dc->res_pool->pipe_count; j++) { 2530 if (srf_updates[i].surface == dc->current_state->res_ctx.pipe_ctx[j].plane_state) { 2531 pipe = &dc->current_state->res_ctx.pipe_ctx[j]; 2532 stream = pipe->stream; 2533 break; 2534 } 2535 } 2536 2537 if (pipe && pipe->top_pipe && (get_num_odm_splits(pipe->top_pipe) > 0) && stream 2538 && !dc_check_is_fullscreen_video(stream->src, srf_updates[i].scaling_info->clip_rect)) { 2539 struct rect old_clip_rect, new_clip_rect; 2540 bool old_clip_rect_left, old_clip_rect_right, old_clip_rect_middle; 2541 bool new_clip_rect_left, new_clip_rect_right, new_clip_rect_middle; 2542 2543 old_clip_rect = srf_updates[i].surface->clip_rect; 2544 new_clip_rect = srf_updates[i].scaling_info->clip_rect; 2545 2546 old_clip_rect_left = ((old_clip_rect.x + old_clip_rect.width) <= (stream->src.x + (stream->src.width/2))); 2547 old_clip_rect_right = (old_clip_rect.x >= (stream->src.x + (stream->src.width/2))); 2548 old_clip_rect_middle = !old_clip_rect_left && !old_clip_rect_right; 2549 2550 new_clip_rect_left = ((new_clip_rect.x + new_clip_rect.width) <= (stream->src.x + (stream->src.width/2))); 2551 new_clip_rect_right = (new_clip_rect.x >= (stream->src.x + (stream->src.width/2))); 2552 new_clip_rect_middle = !new_clip_rect_left && !new_clip_rect_right; 2553 2554 if (old_clip_rect_left && new_clip_rect_middle) 2555 new_update_type = UPDATE_TYPE_FULL; 2556 else if (old_clip_rect_middle && new_clip_rect_right) 2557 new_update_type = UPDATE_TYPE_FULL; 2558 else if (old_clip_rect_right && new_clip_rect_middle) 2559 new_update_type = UPDATE_TYPE_FULL; 2560 else if (old_clip_rect_middle && new_clip_rect_left) 2561 new_update_type = UPDATE_TYPE_FULL; 2562 } 2563 } 2564 } 2565 } 2566 return new_update_type; 2567 } 2568 2569 /* 2570 * dc_check_update_surfaces_for_stream() - Determine update type (fast, med, or full) 2571 * 2572 * See :c:type:`enum surface_update_type <surface_update_type>` for explanation of update types 2573 */ 2574 enum surface_update_type dc_check_update_surfaces_for_stream( 2575 struct dc *dc, 2576 struct dc_surface_update *updates, 2577 int surface_count, 2578 struct dc_stream_update *stream_update, 2579 const struct dc_stream_status *stream_status) 2580 { 2581 int i; 2582 enum surface_update_type type; 2583 2584 if (stream_update) 2585 stream_update->stream->update_flags.raw = 0; 2586 for (i = 0; i < surface_count; i++) 2587 updates[i].surface->update_flags.raw = 0; 2588 2589 type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status); 2590 if (type == UPDATE_TYPE_FULL) { 2591 if (stream_update) { 2592 uint32_t dsc_changed = stream_update->stream->update_flags.bits.dsc_changed; 2593 stream_update->stream->update_flags.raw = 0xFFFFFFFF; 2594 stream_update->stream->update_flags.bits.dsc_changed = dsc_changed; 2595 } 2596 for (i = 0; i < surface_count; i++) 2597 updates[i].surface->update_flags.raw = 0xFFFFFFFF; 2598 } 2599 2600 if (type == UPDATE_TYPE_MED) 2601 type = check_boundary_crossing_for_windowed_mpo_with_odm(dc, 2602 updates, surface_count, type); 2603 2604 if (type == UPDATE_TYPE_FAST) { 2605 // If there's an available clock comparator, we use that. 2606 if (dc->clk_mgr->funcs->are_clock_states_equal) { 2607 if (!dc->clk_mgr->funcs->are_clock_states_equal(&dc->clk_mgr->clks, &dc->current_state->bw_ctx.bw.dcn.clk)) 2608 dc->optimized_required = true; 2609 // Else we fallback to mem compare. 2610 } else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) { 2611 dc->optimized_required = true; 2612 } 2613 2614 dc->optimized_required |= dc->wm_optimized_required; 2615 } 2616 2617 return type; 2618 } 2619 2620 static struct dc_stream_status *stream_get_status( 2621 struct dc_state *ctx, 2622 struct dc_stream_state *stream) 2623 { 2624 uint8_t i; 2625 2626 for (i = 0; i < ctx->stream_count; i++) { 2627 if (stream == ctx->streams[i]) { 2628 return &ctx->stream_status[i]; 2629 } 2630 } 2631 2632 return NULL; 2633 } 2634 2635 static const enum surface_update_type update_surface_trace_level = UPDATE_TYPE_FULL; 2636 2637 static void copy_surface_update_to_plane( 2638 struct dc_plane_state *surface, 2639 struct dc_surface_update *srf_update) 2640 { 2641 if (srf_update->flip_addr) { 2642 surface->address = srf_update->flip_addr->address; 2643 surface->flip_immediate = 2644 srf_update->flip_addr->flip_immediate; 2645 surface->time.time_elapsed_in_us[surface->time.index] = 2646 srf_update->flip_addr->flip_timestamp_in_us - 2647 surface->time.prev_update_time_in_us; 2648 surface->time.prev_update_time_in_us = 2649 srf_update->flip_addr->flip_timestamp_in_us; 2650 surface->time.index++; 2651 if (surface->time.index >= DC_PLANE_UPDATE_TIMES_MAX) 2652 surface->time.index = 0; 2653 2654 surface->triplebuffer_flips = srf_update->flip_addr->triplebuffer_flips; 2655 } 2656 2657 if (srf_update->scaling_info) { 2658 surface->scaling_quality = 2659 srf_update->scaling_info->scaling_quality; 2660 surface->dst_rect = 2661 srf_update->scaling_info->dst_rect; 2662 surface->src_rect = 2663 srf_update->scaling_info->src_rect; 2664 surface->clip_rect = 2665 srf_update->scaling_info->clip_rect; 2666 } 2667 2668 if (srf_update->plane_info) { 2669 surface->color_space = 2670 srf_update->plane_info->color_space; 2671 surface->format = 2672 srf_update->plane_info->format; 2673 surface->plane_size = 2674 srf_update->plane_info->plane_size; 2675 surface->rotation = 2676 srf_update->plane_info->rotation; 2677 surface->horizontal_mirror = 2678 srf_update->plane_info->horizontal_mirror; 2679 surface->stereo_format = 2680 srf_update->plane_info->stereo_format; 2681 surface->tiling_info = 2682 srf_update->plane_info->tiling_info; 2683 surface->visible = 2684 srf_update->plane_info->visible; 2685 surface->per_pixel_alpha = 2686 srf_update->plane_info->per_pixel_alpha; 2687 surface->global_alpha = 2688 srf_update->plane_info->global_alpha; 2689 surface->global_alpha_value = 2690 srf_update->plane_info->global_alpha_value; 2691 surface->dcc = 2692 srf_update->plane_info->dcc; 2693 surface->layer_index = 2694 srf_update->plane_info->layer_index; 2695 } 2696 2697 if (srf_update->gamma && 2698 (surface->gamma_correction != 2699 srf_update->gamma)) { 2700 memcpy(&surface->gamma_correction->entries, 2701 &srf_update->gamma->entries, 2702 sizeof(struct dc_gamma_entries)); 2703 surface->gamma_correction->is_identity = 2704 srf_update->gamma->is_identity; 2705 surface->gamma_correction->num_entries = 2706 srf_update->gamma->num_entries; 2707 surface->gamma_correction->type = 2708 srf_update->gamma->type; 2709 } 2710 2711 if (srf_update->in_transfer_func && 2712 (surface->in_transfer_func != 2713 srf_update->in_transfer_func)) { 2714 surface->in_transfer_func->sdr_ref_white_level = 2715 srf_update->in_transfer_func->sdr_ref_white_level; 2716 surface->in_transfer_func->tf = 2717 srf_update->in_transfer_func->tf; 2718 surface->in_transfer_func->type = 2719 srf_update->in_transfer_func->type; 2720 memcpy(&surface->in_transfer_func->tf_pts, 2721 &srf_update->in_transfer_func->tf_pts, 2722 sizeof(struct dc_transfer_func_distributed_points)); 2723 } 2724 2725 if (srf_update->func_shaper && 2726 (surface->in_shaper_func != 2727 srf_update->func_shaper)) 2728 memcpy(surface->in_shaper_func, srf_update->func_shaper, 2729 sizeof(*surface->in_shaper_func)); 2730 2731 if (srf_update->lut3d_func && 2732 (surface->lut3d_func != 2733 srf_update->lut3d_func)) 2734 memcpy(surface->lut3d_func, srf_update->lut3d_func, 2735 sizeof(*surface->lut3d_func)); 2736 2737 if (srf_update->hdr_mult.value) 2738 surface->hdr_mult = 2739 srf_update->hdr_mult; 2740 2741 if (srf_update->blend_tf && 2742 (surface->blend_tf != 2743 srf_update->blend_tf)) 2744 memcpy(surface->blend_tf, srf_update->blend_tf, 2745 sizeof(*surface->blend_tf)); 2746 2747 if (srf_update->input_csc_color_matrix) 2748 surface->input_csc_color_matrix = 2749 *srf_update->input_csc_color_matrix; 2750 2751 if (srf_update->coeff_reduction_factor) 2752 surface->coeff_reduction_factor = 2753 *srf_update->coeff_reduction_factor; 2754 2755 if (srf_update->gamut_remap_matrix) 2756 surface->gamut_remap_matrix = 2757 *srf_update->gamut_remap_matrix; 2758 } 2759 2760 static void copy_stream_update_to_stream(struct dc *dc, 2761 struct dc_state *context, 2762 struct dc_stream_state *stream, 2763 struct dc_stream_update *update) 2764 { 2765 struct dc_context *dc_ctx = dc->ctx; 2766 2767 if (update == NULL || stream == NULL) 2768 return; 2769 2770 if (update->src.height && update->src.width) 2771 stream->src = update->src; 2772 2773 if (update->dst.height && update->dst.width) 2774 stream->dst = update->dst; 2775 2776 if (update->out_transfer_func && 2777 stream->out_transfer_func != update->out_transfer_func) { 2778 stream->out_transfer_func->sdr_ref_white_level = 2779 update->out_transfer_func->sdr_ref_white_level; 2780 stream->out_transfer_func->tf = update->out_transfer_func->tf; 2781 stream->out_transfer_func->type = 2782 update->out_transfer_func->type; 2783 memcpy(&stream->out_transfer_func->tf_pts, 2784 &update->out_transfer_func->tf_pts, 2785 sizeof(struct dc_transfer_func_distributed_points)); 2786 } 2787 2788 if (update->hdr_static_metadata) 2789 stream->hdr_static_metadata = *update->hdr_static_metadata; 2790 2791 if (update->abm_level) 2792 stream->abm_level = *update->abm_level; 2793 2794 if (update->periodic_interrupt) 2795 stream->periodic_interrupt = *update->periodic_interrupt; 2796 2797 if (update->gamut_remap) 2798 stream->gamut_remap_matrix = *update->gamut_remap; 2799 2800 /* Note: this being updated after mode set is currently not a use case 2801 * however if it arises OCSC would need to be reprogrammed at the 2802 * minimum 2803 */ 2804 if (update->output_color_space) 2805 stream->output_color_space = *update->output_color_space; 2806 2807 if (update->output_csc_transform) 2808 stream->csc_color_matrix = *update->output_csc_transform; 2809 2810 if (update->vrr_infopacket) 2811 stream->vrr_infopacket = *update->vrr_infopacket; 2812 2813 if (update->allow_freesync) 2814 stream->allow_freesync = *update->allow_freesync; 2815 2816 if (update->vrr_active_variable) 2817 stream->vrr_active_variable = *update->vrr_active_variable; 2818 2819 if (update->crtc_timing_adjust) 2820 stream->adjust = *update->crtc_timing_adjust; 2821 2822 if (update->dpms_off) 2823 stream->dpms_off = *update->dpms_off; 2824 2825 if (update->hfvsif_infopacket) 2826 stream->hfvsif_infopacket = *update->hfvsif_infopacket; 2827 2828 if (update->vtem_infopacket) 2829 stream->vtem_infopacket = *update->vtem_infopacket; 2830 2831 if (update->vsc_infopacket) 2832 stream->vsc_infopacket = *update->vsc_infopacket; 2833 2834 if (update->vsp_infopacket) 2835 stream->vsp_infopacket = *update->vsp_infopacket; 2836 2837 if (update->dither_option) 2838 stream->dither_option = *update->dither_option; 2839 2840 if (update->pending_test_pattern) 2841 stream->test_pattern = *update->pending_test_pattern; 2842 /* update current stream with writeback info */ 2843 if (update->wb_update) { 2844 int i; 2845 2846 stream->num_wb_info = update->wb_update->num_wb_info; 2847 ASSERT(stream->num_wb_info <= MAX_DWB_PIPES); 2848 for (i = 0; i < stream->num_wb_info; i++) 2849 stream->writeback_info[i] = 2850 update->wb_update->writeback_info[i]; 2851 } 2852 if (update->dsc_config) { 2853 struct dc_dsc_config old_dsc_cfg = stream->timing.dsc_cfg; 2854 uint32_t old_dsc_enabled = stream->timing.flags.DSC; 2855 uint32_t enable_dsc = (update->dsc_config->num_slices_h != 0 && 2856 update->dsc_config->num_slices_v != 0); 2857 2858 /* Use temporarry context for validating new DSC config */ 2859 struct dc_state *dsc_validate_context = dc_create_state(dc); 2860 2861 if (dsc_validate_context) { 2862 dc_resource_state_copy_construct(dc->current_state, dsc_validate_context); 2863 2864 stream->timing.dsc_cfg = *update->dsc_config; 2865 stream->timing.flags.DSC = enable_dsc; 2866 if (!dc->res_pool->funcs->validate_bandwidth(dc, dsc_validate_context, true)) { 2867 stream->timing.dsc_cfg = old_dsc_cfg; 2868 stream->timing.flags.DSC = old_dsc_enabled; 2869 update->dsc_config = NULL; 2870 } 2871 2872 dc_release_state(dsc_validate_context); 2873 } else { 2874 DC_ERROR("Failed to allocate new validate context for DSC change\n"); 2875 update->dsc_config = NULL; 2876 } 2877 } 2878 } 2879 2880 static bool update_planes_and_stream_state(struct dc *dc, 2881 struct dc_surface_update *srf_updates, int surface_count, 2882 struct dc_stream_state *stream, 2883 struct dc_stream_update *stream_update, 2884 enum surface_update_type *new_update_type, 2885 struct dc_state **new_context) 2886 { 2887 struct dc_state *context; 2888 int i, j; 2889 enum surface_update_type update_type; 2890 const struct dc_stream_status *stream_status; 2891 struct dc_context *dc_ctx = dc->ctx; 2892 2893 stream_status = dc_stream_get_status(stream); 2894 2895 if (!stream_status) { 2896 if (surface_count) /* Only an error condition if surf_count non-zero*/ 2897 ASSERT(false); 2898 2899 return false; /* Cannot commit surface to stream that is not committed */ 2900 } 2901 2902 context = dc->current_state; 2903 2904 update_type = dc_check_update_surfaces_for_stream( 2905 dc, srf_updates, surface_count, stream_update, stream_status); 2906 2907 /* update current stream with the new updates */ 2908 copy_stream_update_to_stream(dc, context, stream, stream_update); 2909 2910 /* do not perform surface update if surface has invalid dimensions 2911 * (all zero) and no scaling_info is provided 2912 */ 2913 if (surface_count > 0) { 2914 for (i = 0; i < surface_count; i++) { 2915 if ((srf_updates[i].surface->src_rect.width == 0 || 2916 srf_updates[i].surface->src_rect.height == 0 || 2917 srf_updates[i].surface->dst_rect.width == 0 || 2918 srf_updates[i].surface->dst_rect.height == 0) && 2919 (!srf_updates[i].scaling_info || 2920 srf_updates[i].scaling_info->src_rect.width == 0 || 2921 srf_updates[i].scaling_info->src_rect.height == 0 || 2922 srf_updates[i].scaling_info->dst_rect.width == 0 || 2923 srf_updates[i].scaling_info->dst_rect.height == 0)) { 2924 DC_ERROR("Invalid src/dst rects in surface update!\n"); 2925 return false; 2926 } 2927 } 2928 } 2929 2930 if (update_type >= update_surface_trace_level) 2931 update_surface_trace(dc, srf_updates, surface_count); 2932 2933 if (update_type >= UPDATE_TYPE_FULL) { 2934 struct dc_plane_state *new_planes[MAX_SURFACES] = {0}; 2935 2936 for (i = 0; i < surface_count; i++) 2937 new_planes[i] = srf_updates[i].surface; 2938 2939 /* initialize scratch memory for building context */ 2940 context = dc_create_state(dc); 2941 if (context == NULL) { 2942 DC_ERROR("Failed to allocate new validate context!\n"); 2943 return false; 2944 } 2945 2946 dc_resource_state_copy_construct( 2947 dc->current_state, context); 2948 2949 /* For each full update, remove all existing phantom pipes first. 2950 * Ensures that we have enough pipes for newly added MPO planes 2951 */ 2952 if (dc->res_pool->funcs->remove_phantom_pipes) 2953 dc->res_pool->funcs->remove_phantom_pipes(dc, context); 2954 2955 /*remove old surfaces from context */ 2956 if (!dc_rem_all_planes_for_stream(dc, stream, context)) { 2957 2958 BREAK_TO_DEBUGGER(); 2959 goto fail; 2960 } 2961 2962 /* add surface to context */ 2963 if (!dc_add_all_planes_for_stream(dc, stream, new_planes, surface_count, context)) { 2964 2965 BREAK_TO_DEBUGGER(); 2966 goto fail; 2967 } 2968 } 2969 2970 /* save update parameters into surface */ 2971 for (i = 0; i < surface_count; i++) { 2972 struct dc_plane_state *surface = srf_updates[i].surface; 2973 2974 copy_surface_update_to_plane(surface, &srf_updates[i]); 2975 2976 if (update_type >= UPDATE_TYPE_MED) { 2977 for (j = 0; j < dc->res_pool->pipe_count; j++) { 2978 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 2979 2980 if (pipe_ctx->plane_state != surface) 2981 continue; 2982 2983 resource_build_scaling_params(pipe_ctx); 2984 } 2985 } 2986 } 2987 2988 if (update_type == UPDATE_TYPE_FULL) { 2989 if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) { 2990 BREAK_TO_DEBUGGER(); 2991 goto fail; 2992 } 2993 } 2994 2995 *new_context = context; 2996 *new_update_type = update_type; 2997 2998 return true; 2999 3000 fail: 3001 dc_release_state(context); 3002 3003 return false; 3004 3005 } 3006 3007 static void commit_planes_do_stream_update(struct dc *dc, 3008 struct dc_stream_state *stream, 3009 struct dc_stream_update *stream_update, 3010 enum surface_update_type update_type, 3011 struct dc_state *context) 3012 { 3013 int j; 3014 3015 // Stream updates 3016 for (j = 0; j < dc->res_pool->pipe_count; j++) { 3017 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3018 3019 if (!pipe_ctx->top_pipe && !pipe_ctx->prev_odm_pipe && pipe_ctx->stream == stream) { 3020 3021 if (stream_update->periodic_interrupt && dc->hwss.setup_periodic_interrupt) 3022 dc->hwss.setup_periodic_interrupt(dc, pipe_ctx); 3023 3024 if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) || 3025 stream_update->vrr_infopacket || 3026 stream_update->vsc_infopacket || 3027 stream_update->vsp_infopacket || 3028 stream_update->hfvsif_infopacket || 3029 stream_update->vtem_infopacket) { 3030 resource_build_info_frame(pipe_ctx); 3031 dc->hwss.update_info_frame(pipe_ctx); 3032 3033 if (dc_is_dp_signal(pipe_ctx->stream->signal)) 3034 dp_source_sequence_trace(pipe_ctx->stream->link, DPCD_SOURCE_SEQ_AFTER_UPDATE_INFO_FRAME); 3035 } 3036 3037 if (stream_update->hdr_static_metadata && 3038 stream->use_dynamic_meta && 3039 dc->hwss.set_dmdata_attributes && 3040 pipe_ctx->stream->dmdata_address.quad_part != 0) 3041 dc->hwss.set_dmdata_attributes(pipe_ctx); 3042 3043 if (stream_update->gamut_remap) 3044 dc_stream_set_gamut_remap(dc, stream); 3045 3046 if (stream_update->output_csc_transform) 3047 dc_stream_program_csc_matrix(dc, stream); 3048 3049 if (stream_update->dither_option) { 3050 struct pipe_ctx *odm_pipe = pipe_ctx->next_odm_pipe; 3051 resource_build_bit_depth_reduction_params(pipe_ctx->stream, 3052 &pipe_ctx->stream->bit_depth_params); 3053 pipe_ctx->stream_res.opp->funcs->opp_program_fmt(pipe_ctx->stream_res.opp, 3054 &stream->bit_depth_params, 3055 &stream->clamping); 3056 while (odm_pipe) { 3057 odm_pipe->stream_res.opp->funcs->opp_program_fmt(odm_pipe->stream_res.opp, 3058 &stream->bit_depth_params, 3059 &stream->clamping); 3060 odm_pipe = odm_pipe->next_odm_pipe; 3061 } 3062 } 3063 3064 3065 /* Full fe update*/ 3066 if (update_type == UPDATE_TYPE_FAST) 3067 continue; 3068 3069 if (stream_update->dsc_config) 3070 dp_update_dsc_config(pipe_ctx); 3071 3072 if (stream_update->mst_bw_update) { 3073 if (stream_update->mst_bw_update->is_increase) 3074 dc_link_increase_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw); 3075 else 3076 dc_link_reduce_mst_payload(pipe_ctx, stream_update->mst_bw_update->mst_stream_bw); 3077 } 3078 3079 if (stream_update->pending_test_pattern) { 3080 dc_link_dp_set_test_pattern(stream->link, 3081 stream->test_pattern.type, 3082 stream->test_pattern.color_space, 3083 stream->test_pattern.p_link_settings, 3084 stream->test_pattern.p_custom_pattern, 3085 stream->test_pattern.cust_pattern_size); 3086 } 3087 3088 if (stream_update->dpms_off) { 3089 if (*stream_update->dpms_off) { 3090 core_link_disable_stream(pipe_ctx); 3091 /* for dpms, keep acquired resources*/ 3092 if (pipe_ctx->stream_res.audio && !dc->debug.az_endpoint_mute_only) 3093 pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio); 3094 3095 dc->optimized_required = true; 3096 3097 } else { 3098 if (get_seamless_boot_stream_count(context) == 0) 3099 dc->hwss.prepare_bandwidth(dc, dc->current_state); 3100 core_link_enable_stream(dc->current_state, pipe_ctx); 3101 } 3102 } 3103 3104 if (stream_update->abm_level && pipe_ctx->stream_res.abm) { 3105 bool should_program_abm = true; 3106 3107 // if otg funcs defined check if blanked before programming 3108 if (pipe_ctx->stream_res.tg->funcs->is_blanked) 3109 if (pipe_ctx->stream_res.tg->funcs->is_blanked(pipe_ctx->stream_res.tg)) 3110 should_program_abm = false; 3111 3112 if (should_program_abm) { 3113 if (*stream_update->abm_level == ABM_LEVEL_IMMEDIATE_DISABLE) { 3114 dc->hwss.set_abm_immediate_disable(pipe_ctx); 3115 } else { 3116 pipe_ctx->stream_res.abm->funcs->set_abm_level( 3117 pipe_ctx->stream_res.abm, stream->abm_level); 3118 } 3119 } 3120 } 3121 } 3122 } 3123 } 3124 3125 static bool dc_dmub_should_send_dirty_rect_cmd(struct dc *dc, struct dc_stream_state *stream) 3126 { 3127 if ((stream->link->psr_settings.psr_version == DC_PSR_VERSION_SU_1 3128 || stream->link->psr_settings.psr_version == DC_PSR_VERSION_1) 3129 && stream->ctx->dce_version >= DCN_VERSION_3_1) 3130 return true; 3131 3132 return false; 3133 } 3134 3135 void dc_dmub_update_dirty_rect(struct dc *dc, 3136 int surface_count, 3137 struct dc_stream_state *stream, 3138 struct dc_surface_update *srf_updates, 3139 struct dc_state *context) 3140 { 3141 union dmub_rb_cmd cmd; 3142 struct dc_context *dc_ctx = dc->ctx; 3143 struct dmub_cmd_update_dirty_rect_data *update_dirty_rect; 3144 unsigned int i, j; 3145 unsigned int panel_inst = 0; 3146 3147 if (!dc_dmub_should_send_dirty_rect_cmd(dc, stream)) 3148 return; 3149 3150 if (!dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst)) 3151 return; 3152 3153 memset(&cmd, 0x0, sizeof(cmd)); 3154 cmd.update_dirty_rect.header.type = DMUB_CMD__UPDATE_DIRTY_RECT; 3155 cmd.update_dirty_rect.header.sub_type = 0; 3156 cmd.update_dirty_rect.header.payload_bytes = 3157 sizeof(cmd.update_dirty_rect) - 3158 sizeof(cmd.update_dirty_rect.header); 3159 update_dirty_rect = &cmd.update_dirty_rect.update_dirty_rect_data; 3160 for (i = 0; i < surface_count; i++) { 3161 struct dc_plane_state *plane_state = srf_updates[i].surface; 3162 const struct dc_flip_addrs *flip_addr = srf_updates[i].flip_addr; 3163 3164 if (!srf_updates[i].surface || !flip_addr) 3165 continue; 3166 /* Do not send in immediate flip mode */ 3167 if (srf_updates[i].surface->flip_immediate) 3168 continue; 3169 3170 update_dirty_rect->dirty_rect_count = flip_addr->dirty_rect_count; 3171 memcpy(update_dirty_rect->src_dirty_rects, flip_addr->dirty_rects, 3172 sizeof(flip_addr->dirty_rects)); 3173 for (j = 0; j < dc->res_pool->pipe_count; j++) { 3174 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3175 3176 if (pipe_ctx->stream != stream) 3177 continue; 3178 if (pipe_ctx->plane_state != plane_state) 3179 continue; 3180 3181 update_dirty_rect->panel_inst = panel_inst; 3182 update_dirty_rect->pipe_idx = j; 3183 dc_dmub_srv_cmd_queue(dc_ctx->dmub_srv, &cmd); 3184 dc_dmub_srv_cmd_execute(dc_ctx->dmub_srv); 3185 } 3186 } 3187 } 3188 3189 static void commit_planes_for_stream(struct dc *dc, 3190 struct dc_surface_update *srf_updates, 3191 int surface_count, 3192 struct dc_stream_state *stream, 3193 struct dc_stream_update *stream_update, 3194 enum surface_update_type update_type, 3195 struct dc_state *context) 3196 { 3197 int i, j; 3198 struct pipe_ctx *top_pipe_to_program = NULL; 3199 bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST); 3200 bool subvp_prev_use = false; 3201 3202 // Once we apply the new subvp context to hardware it won't be in the 3203 // dc->current_state anymore, so we have to cache it before we apply 3204 // the new SubVP context 3205 subvp_prev_use = false; 3206 3207 3208 dc_z10_restore(dc); 3209 3210 if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) { 3211 /* Optimize seamless boot flag keeps clocks and watermarks high until 3212 * first flip. After first flip, optimization is required to lower 3213 * bandwidth. Important to note that it is expected UEFI will 3214 * only light up a single display on POST, therefore we only expect 3215 * one stream with seamless boot flag set. 3216 */ 3217 if (stream->apply_seamless_boot_optimization) { 3218 stream->apply_seamless_boot_optimization = false; 3219 3220 if (get_seamless_boot_stream_count(context) == 0) 3221 dc->optimized_required = true; 3222 } 3223 } 3224 3225 if (update_type == UPDATE_TYPE_FULL) { 3226 dc_allow_idle_optimizations(dc, false); 3227 3228 if (get_seamless_boot_stream_count(context) == 0) 3229 dc->hwss.prepare_bandwidth(dc, context); 3230 3231 if (dc->debug.enable_double_buffered_dsc_pg_support) 3232 dc->hwss.update_dsc_pg(dc, context, false); 3233 3234 context_clock_trace(dc, context); 3235 } 3236 3237 for (j = 0; j < dc->res_pool->pipe_count; j++) { 3238 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3239 3240 if (!pipe_ctx->top_pipe && 3241 !pipe_ctx->prev_odm_pipe && 3242 pipe_ctx->stream && 3243 pipe_ctx->stream == stream) { 3244 top_pipe_to_program = pipe_ctx; 3245 } 3246 } 3247 3248 for (i = 0; i < dc->res_pool->pipe_count; i++) { 3249 struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 3250 3251 // Check old context for SubVP 3252 subvp_prev_use |= (old_pipe->stream && old_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM); 3253 if (subvp_prev_use) 3254 break; 3255 } 3256 3257 if (stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) { 3258 struct pipe_ctx *mpcc_pipe; 3259 struct pipe_ctx *odm_pipe; 3260 3261 for (mpcc_pipe = top_pipe_to_program; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe) 3262 for (odm_pipe = mpcc_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) 3263 odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU; 3264 } 3265 3266 if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) 3267 if (top_pipe_to_program && 3268 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { 3269 if (should_use_dmub_lock(stream->link)) { 3270 union dmub_hw_lock_flags hw_locks = { 0 }; 3271 struct dmub_hw_lock_inst_flags inst_flags = { 0 }; 3272 3273 hw_locks.bits.lock_dig = 1; 3274 inst_flags.dig_inst = top_pipe_to_program->stream_res.tg->inst; 3275 3276 dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv, 3277 true, 3278 &hw_locks, 3279 &inst_flags); 3280 } else 3281 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable( 3282 top_pipe_to_program->stream_res.tg); 3283 } 3284 3285 if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { 3286 if (dc->hwss.subvp_pipe_control_lock) 3287 dc->hwss.subvp_pipe_control_lock(dc, context, true, should_lock_all_pipes, NULL, subvp_prev_use); 3288 dc->hwss.interdependent_update_lock(dc, context, true); 3289 3290 } else { 3291 if (dc->hwss.subvp_pipe_control_lock) 3292 dc->hwss.subvp_pipe_control_lock(dc, context, true, should_lock_all_pipes, top_pipe_to_program, subvp_prev_use); 3293 /* Lock the top pipe while updating plane addrs, since freesync requires 3294 * plane addr update event triggers to be synchronized. 3295 * top_pipe_to_program is expected to never be NULL 3296 */ 3297 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, true); 3298 } 3299 3300 if (update_type != UPDATE_TYPE_FAST) { 3301 for (i = 0; i < dc->res_pool->pipe_count; i++) { 3302 struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; 3303 3304 if ((new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) || 3305 subvp_prev_use) { 3306 // If old context or new context has phantom pipes, apply 3307 // the phantom timings now. We can't change the phantom 3308 // pipe configuration safely without driver acquiring 3309 // the DMCUB lock first. 3310 dc->hwss.apply_ctx_to_hw(dc, context); 3311 break; 3312 } 3313 } 3314 } 3315 3316 dc_dmub_update_dirty_rect(dc, surface_count, stream, srf_updates, context); 3317 3318 if (update_type != UPDATE_TYPE_FAST) { 3319 for (i = 0; i < dc->res_pool->pipe_count; i++) { 3320 struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; 3321 3322 if ((new_pipe->stream && new_pipe->stream->mall_stream_config.type == SUBVP_PHANTOM) || 3323 subvp_prev_use) { 3324 // If old context or new context has phantom pipes, apply 3325 // the phantom timings now. We can't change the phantom 3326 // pipe configuration safely without driver acquiring 3327 // the DMCUB lock first. 3328 dc->hwss.apply_ctx_to_hw(dc, context); 3329 break; 3330 } 3331 } 3332 } 3333 3334 // Stream updates 3335 if (stream_update) 3336 commit_planes_do_stream_update(dc, stream, stream_update, update_type, context); 3337 3338 if (surface_count == 0) { 3339 /* 3340 * In case of turning off screen, no need to program front end a second time. 3341 * just return after program blank. 3342 */ 3343 if (dc->hwss.apply_ctx_for_surface) 3344 dc->hwss.apply_ctx_for_surface(dc, stream, 0, context); 3345 if (dc->hwss.program_front_end_for_ctx) 3346 dc->hwss.program_front_end_for_ctx(dc, context); 3347 3348 if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { 3349 dc->hwss.interdependent_update_lock(dc, context, false); 3350 } else { 3351 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); 3352 } 3353 dc->hwss.post_unlock_program_front_end(dc, context); 3354 3355 if (update_type != UPDATE_TYPE_FAST) 3356 if (dc->hwss.commit_subvp_config) 3357 dc->hwss.commit_subvp_config(dc, context); 3358 3359 /* Since phantom pipe programming is moved to post_unlock_program_front_end, 3360 * move the SubVP lock to after the phantom pipes have been setup 3361 */ 3362 if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { 3363 if (dc->hwss.subvp_pipe_control_lock) 3364 dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use); 3365 } else { 3366 if (dc->hwss.subvp_pipe_control_lock) 3367 dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use); 3368 } 3369 3370 return; 3371 } 3372 3373 if (!IS_DIAG_DC(dc->ctx->dce_environment)) { 3374 for (i = 0; i < surface_count; i++) { 3375 struct dc_plane_state *plane_state = srf_updates[i].surface; 3376 /*set logical flag for lock/unlock use*/ 3377 for (j = 0; j < dc->res_pool->pipe_count; j++) { 3378 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3379 if (!pipe_ctx->plane_state) 3380 continue; 3381 if (should_update_pipe_for_plane(context, pipe_ctx, plane_state)) 3382 continue; 3383 pipe_ctx->plane_state->triplebuffer_flips = false; 3384 if (update_type == UPDATE_TYPE_FAST && 3385 dc->hwss.program_triplebuffer != NULL && 3386 !pipe_ctx->plane_state->flip_immediate && dc->debug.enable_tri_buf) { 3387 /*triple buffer for VUpdate only*/ 3388 pipe_ctx->plane_state->triplebuffer_flips = true; 3389 } 3390 } 3391 if (update_type == UPDATE_TYPE_FULL) { 3392 /* force vsync flip when reconfiguring pipes to prevent underflow */ 3393 plane_state->flip_immediate = false; 3394 } 3395 } 3396 } 3397 3398 // Update Type FULL, Surface updates 3399 for (j = 0; j < dc->res_pool->pipe_count; j++) { 3400 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3401 3402 if (!pipe_ctx->top_pipe && 3403 !pipe_ctx->prev_odm_pipe && 3404 should_update_pipe_for_stream(context, pipe_ctx, stream)) { 3405 struct dc_stream_status *stream_status = NULL; 3406 3407 if (!pipe_ctx->plane_state) 3408 continue; 3409 3410 /* Full fe update*/ 3411 if (update_type == UPDATE_TYPE_FAST) 3412 continue; 3413 3414 ASSERT(!pipe_ctx->plane_state->triplebuffer_flips); 3415 3416 if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) { 3417 /*turn off triple buffer for full update*/ 3418 dc->hwss.program_triplebuffer( 3419 dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips); 3420 } 3421 stream_status = 3422 stream_get_status(context, pipe_ctx->stream); 3423 3424 if (dc->hwss.apply_ctx_for_surface) 3425 dc->hwss.apply_ctx_for_surface( 3426 dc, pipe_ctx->stream, stream_status->plane_count, context); 3427 } 3428 } 3429 if (dc->hwss.program_front_end_for_ctx && update_type != UPDATE_TYPE_FAST) { 3430 dc->hwss.program_front_end_for_ctx(dc, context); 3431 if (dc->debug.validate_dml_output) { 3432 for (i = 0; i < dc->res_pool->pipe_count; i++) { 3433 struct pipe_ctx *cur_pipe = &context->res_ctx.pipe_ctx[i]; 3434 if (cur_pipe->stream == NULL) 3435 continue; 3436 3437 cur_pipe->plane_res.hubp->funcs->validate_dml_output( 3438 cur_pipe->plane_res.hubp, dc->ctx, 3439 &context->res_ctx.pipe_ctx[i].rq_regs, 3440 &context->res_ctx.pipe_ctx[i].dlg_regs, 3441 &context->res_ctx.pipe_ctx[i].ttu_regs); 3442 } 3443 } 3444 } 3445 3446 // Update Type FAST, Surface updates 3447 if (update_type == UPDATE_TYPE_FAST) { 3448 if (dc->hwss.set_flip_control_gsl) 3449 for (i = 0; i < surface_count; i++) { 3450 struct dc_plane_state *plane_state = srf_updates[i].surface; 3451 3452 for (j = 0; j < dc->res_pool->pipe_count; j++) { 3453 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3454 3455 if (!should_update_pipe_for_stream(context, pipe_ctx, stream)) 3456 continue; 3457 3458 if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state)) 3459 continue; 3460 3461 // GSL has to be used for flip immediate 3462 dc->hwss.set_flip_control_gsl(pipe_ctx, 3463 pipe_ctx->plane_state->flip_immediate); 3464 } 3465 } 3466 3467 /* Perform requested Updates */ 3468 for (i = 0; i < surface_count; i++) { 3469 struct dc_plane_state *plane_state = srf_updates[i].surface; 3470 3471 for (j = 0; j < dc->res_pool->pipe_count; j++) { 3472 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3473 3474 if (!should_update_pipe_for_stream(context, pipe_ctx, stream)) 3475 continue; 3476 3477 if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state)) 3478 continue; 3479 3480 /*program triple buffer after lock based on flip type*/ 3481 if (dc->hwss.program_triplebuffer != NULL && dc->debug.enable_tri_buf) { 3482 /*only enable triplebuffer for fast_update*/ 3483 dc->hwss.program_triplebuffer( 3484 dc, pipe_ctx, pipe_ctx->plane_state->triplebuffer_flips); 3485 } 3486 if (pipe_ctx->plane_state->update_flags.bits.addr_update) 3487 dc->hwss.update_plane_addr(dc, pipe_ctx); 3488 } 3489 } 3490 3491 } 3492 3493 if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { 3494 dc->hwss.interdependent_update_lock(dc, context, false); 3495 } else { 3496 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); 3497 } 3498 3499 if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) 3500 if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { 3501 top_pipe_to_program->stream_res.tg->funcs->wait_for_state( 3502 top_pipe_to_program->stream_res.tg, 3503 CRTC_STATE_VACTIVE); 3504 top_pipe_to_program->stream_res.tg->funcs->wait_for_state( 3505 top_pipe_to_program->stream_res.tg, 3506 CRTC_STATE_VBLANK); 3507 top_pipe_to_program->stream_res.tg->funcs->wait_for_state( 3508 top_pipe_to_program->stream_res.tg, 3509 CRTC_STATE_VACTIVE); 3510 3511 if (should_use_dmub_lock(stream->link)) { 3512 union dmub_hw_lock_flags hw_locks = { 0 }; 3513 struct dmub_hw_lock_inst_flags inst_flags = { 0 }; 3514 3515 hw_locks.bits.lock_dig = 1; 3516 inst_flags.dig_inst = top_pipe_to_program->stream_res.tg->inst; 3517 3518 dmub_hw_lock_mgr_cmd(dc->ctx->dmub_srv, 3519 false, 3520 &hw_locks, 3521 &inst_flags); 3522 } else 3523 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_disable( 3524 top_pipe_to_program->stream_res.tg); 3525 } 3526 3527 if (update_type != UPDATE_TYPE_FAST) 3528 dc->hwss.post_unlock_program_front_end(dc, context); 3529 if (update_type != UPDATE_TYPE_FAST) 3530 if (dc->hwss.commit_subvp_config) 3531 dc->hwss.commit_subvp_config(dc, context); 3532 3533 if (update_type != UPDATE_TYPE_FAST) 3534 if (dc->hwss.commit_subvp_config) 3535 dc->hwss.commit_subvp_config(dc, context); 3536 3537 /* Since phantom pipe programming is moved to post_unlock_program_front_end, 3538 * move the SubVP lock to after the phantom pipes have been setup 3539 */ 3540 if (should_lock_all_pipes && dc->hwss.interdependent_update_lock) { 3541 if (dc->hwss.subvp_pipe_control_lock) 3542 dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, NULL, subvp_prev_use); 3543 } else { 3544 if (dc->hwss.subvp_pipe_control_lock) 3545 dc->hwss.subvp_pipe_control_lock(dc, context, false, should_lock_all_pipes, top_pipe_to_program, subvp_prev_use); 3546 } 3547 3548 // Fire manual trigger only when bottom plane is flipped 3549 for (j = 0; j < dc->res_pool->pipe_count; j++) { 3550 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3551 3552 if (!pipe_ctx->plane_state) 3553 continue; 3554 3555 if (pipe_ctx->bottom_pipe || pipe_ctx->next_odm_pipe || 3556 !pipe_ctx->stream || !should_update_pipe_for_stream(context, pipe_ctx, stream) || 3557 !pipe_ctx->plane_state->update_flags.bits.addr_update || 3558 pipe_ctx->plane_state->skip_manual_trigger) 3559 continue; 3560 3561 if (pipe_ctx->stream_res.tg->funcs->program_manual_trigger) 3562 pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg); 3563 } 3564 } 3565 3566 /* Determines if the incoming context requires a applying transition state with unnecessary 3567 * pipe splitting and ODM disabled, due to hardware limitations. In a case where 3568 * the OPP associated with an MPCC might change due to plane additions, this function 3569 * returns true. 3570 */ 3571 static bool could_mpcc_tree_change_for_active_pipes(struct dc *dc, 3572 struct dc_stream_state *stream, 3573 int surface_count, 3574 bool *is_plane_addition) 3575 { 3576 3577 struct dc_stream_status *cur_stream_status = stream_get_status(dc->current_state, stream); 3578 bool force_minimal_pipe_splitting = false; 3579 uint32_t i; 3580 3581 *is_plane_addition = false; 3582 3583 if (cur_stream_status && 3584 dc->current_state->stream_count > 0 && 3585 dc->debug.pipe_split_policy != MPC_SPLIT_AVOID) { 3586 /* determine if minimal transition is required due to MPC*/ 3587 if (surface_count > 0) { 3588 if (cur_stream_status->plane_count > surface_count) { 3589 force_minimal_pipe_splitting = true; 3590 } else if (cur_stream_status->plane_count < surface_count) { 3591 force_minimal_pipe_splitting = true; 3592 *is_plane_addition = true; 3593 } 3594 } 3595 } 3596 3597 if (cur_stream_status && 3598 dc->current_state->stream_count == 1 && 3599 dc->debug.enable_single_display_2to1_odm_policy) { 3600 /* determine if minimal transition is required due to dynamic ODM*/ 3601 if (surface_count > 0) { 3602 if (cur_stream_status->plane_count > 2 && cur_stream_status->plane_count > surface_count) { 3603 force_minimal_pipe_splitting = true; 3604 } else if (surface_count > 2 && cur_stream_status->plane_count < surface_count) { 3605 force_minimal_pipe_splitting = true; 3606 *is_plane_addition = true; 3607 } 3608 } 3609 } 3610 3611 /* For SubVP pipe split case when adding MPO video 3612 * we need to add a minimal transition. In this case 3613 * there will be 2 streams (1 main stream, 1 phantom 3614 * stream). 3615 */ 3616 if (cur_stream_status && 3617 dc->current_state->stream_count == 2 && 3618 stream->mall_stream_config.type == SUBVP_MAIN) { 3619 bool is_pipe_split = false; 3620 3621 for (i = 0; i < dc->res_pool->pipe_count; i++) { 3622 if (dc->current_state->res_ctx.pipe_ctx[i].stream == stream && 3623 (dc->current_state->res_ctx.pipe_ctx[i].bottom_pipe || 3624 dc->current_state->res_ctx.pipe_ctx[i].next_odm_pipe)) { 3625 is_pipe_split = true; 3626 break; 3627 } 3628 } 3629 3630 /* determine if minimal transition is required due to SubVP*/ 3631 if (surface_count > 0 && is_pipe_split) { 3632 if (cur_stream_status->plane_count > surface_count) { 3633 force_minimal_pipe_splitting = true; 3634 } else if (cur_stream_status->plane_count < surface_count) { 3635 force_minimal_pipe_splitting = true; 3636 *is_plane_addition = true; 3637 } 3638 } 3639 } 3640 3641 return force_minimal_pipe_splitting; 3642 } 3643 3644 static bool commit_minimal_transition_state(struct dc *dc, 3645 struct dc_state *transition_base_context) 3646 { 3647 struct dc_state *transition_context = dc_create_state(dc); 3648 enum pipe_split_policy tmp_mpc_policy; 3649 bool temp_dynamic_odm_policy; 3650 bool temp_subvp_policy; 3651 enum dc_status ret = DC_ERROR_UNEXPECTED; 3652 unsigned int i, j; 3653 3654 if (!transition_context) 3655 return false; 3656 3657 if (!dc->config.is_vmin_only_asic) { 3658 tmp_mpc_policy = dc->debug.pipe_split_policy; 3659 dc->debug.pipe_split_policy = MPC_SPLIT_AVOID; 3660 } 3661 3662 temp_dynamic_odm_policy = dc->debug.enable_single_display_2to1_odm_policy; 3663 dc->debug.enable_single_display_2to1_odm_policy = false; 3664 3665 temp_subvp_policy = dc->debug.force_disable_subvp; 3666 dc->debug.force_disable_subvp = true; 3667 3668 dc_resource_state_copy_construct(transition_base_context, transition_context); 3669 3670 //commit minimal state 3671 if (dc->res_pool->funcs->validate_bandwidth(dc, transition_context, false)) { 3672 for (i = 0; i < transition_context->stream_count; i++) { 3673 struct dc_stream_status *stream_status = &transition_context->stream_status[i]; 3674 3675 for (j = 0; j < stream_status->plane_count; j++) { 3676 struct dc_plane_state *plane_state = stream_status->plane_states[j]; 3677 3678 /* force vsync flip when reconfiguring pipes to prevent underflow 3679 * and corruption 3680 */ 3681 plane_state->flip_immediate = false; 3682 } 3683 } 3684 3685 ret = dc_commit_state_no_check(dc, transition_context); 3686 } 3687 3688 /*always release as dc_commit_state_no_check retains in good case*/ 3689 dc_release_state(transition_context); 3690 3691 /*restore previous pipe split and odm policy*/ 3692 if (!dc->config.is_vmin_only_asic) 3693 dc->debug.pipe_split_policy = tmp_mpc_policy; 3694 3695 dc->debug.enable_single_display_2to1_odm_policy = temp_dynamic_odm_policy; 3696 dc->debug.force_disable_subvp = temp_subvp_policy; 3697 3698 if (ret != DC_OK) { 3699 /*this should never happen*/ 3700 BREAK_TO_DEBUGGER(); 3701 return false; 3702 } 3703 3704 /*force full surface update*/ 3705 for (i = 0; i < dc->current_state->stream_count; i++) { 3706 for (j = 0; j < dc->current_state->stream_status[i].plane_count; j++) { 3707 dc->current_state->stream_status[i].plane_states[j]->update_flags.raw = 0xFFFFFFFF; 3708 } 3709 } 3710 3711 return true; 3712 } 3713 3714 bool dc_update_planes_and_stream(struct dc *dc, 3715 struct dc_surface_update *srf_updates, int surface_count, 3716 struct dc_stream_state *stream, 3717 struct dc_stream_update *stream_update) 3718 { 3719 struct dc_state *context; 3720 enum surface_update_type update_type; 3721 int i; 3722 3723 /* In cases where MPO and split or ODM are used transitions can 3724 * cause underflow. Apply stream configuration with minimal pipe 3725 * split first to avoid unsupported transitions for active pipes. 3726 */ 3727 bool force_minimal_pipe_splitting; 3728 bool is_plane_addition; 3729 3730 force_minimal_pipe_splitting = could_mpcc_tree_change_for_active_pipes( 3731 dc, 3732 stream, 3733 surface_count, 3734 &is_plane_addition); 3735 3736 /* on plane addition, minimal state is the current one */ 3737 if (force_minimal_pipe_splitting && is_plane_addition && 3738 !commit_minimal_transition_state(dc, dc->current_state)) 3739 return false; 3740 3741 if (!update_planes_and_stream_state( 3742 dc, 3743 srf_updates, 3744 surface_count, 3745 stream, 3746 stream_update, 3747 &update_type, 3748 &context)) 3749 return false; 3750 3751 /* on plane removal, minimal state is the new one */ 3752 if (force_minimal_pipe_splitting && !is_plane_addition) { 3753 if (!commit_minimal_transition_state(dc, context)) { 3754 dc_release_state(context); 3755 return false; 3756 } 3757 3758 update_type = UPDATE_TYPE_FULL; 3759 } 3760 3761 commit_planes_for_stream( 3762 dc, 3763 srf_updates, 3764 surface_count, 3765 stream, 3766 stream_update, 3767 update_type, 3768 context); 3769 3770 if (dc->current_state != context) { 3771 3772 /* Since memory free requires elevated IRQL, an interrupt 3773 * request is generated by mem free. If this happens 3774 * between freeing and reassigning the context, our vsync 3775 * interrupt will call into dc and cause a memory 3776 * corruption BSOD. Hence, we first reassign the context, 3777 * then free the old context. 3778 */ 3779 3780 struct dc_state *old = dc->current_state; 3781 3782 dc->current_state = context; 3783 dc_release_state(old); 3784 3785 // clear any forced full updates 3786 for (i = 0; i < dc->res_pool->pipe_count; i++) { 3787 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 3788 3789 if (pipe_ctx->plane_state && pipe_ctx->stream == stream) 3790 pipe_ctx->plane_state->force_full_update = false; 3791 } 3792 } 3793 return true; 3794 } 3795 3796 void dc_commit_updates_for_stream(struct dc *dc, 3797 struct dc_surface_update *srf_updates, 3798 int surface_count, 3799 struct dc_stream_state *stream, 3800 struct dc_stream_update *stream_update, 3801 struct dc_state *state) 3802 { 3803 const struct dc_stream_status *stream_status; 3804 enum surface_update_type update_type; 3805 struct dc_state *context; 3806 struct dc_context *dc_ctx = dc->ctx; 3807 int i, j; 3808 3809 stream_status = dc_stream_get_status(stream); 3810 context = dc->current_state; 3811 3812 update_type = dc_check_update_surfaces_for_stream( 3813 dc, srf_updates, surface_count, stream_update, stream_status); 3814 3815 if (update_type >= update_surface_trace_level) 3816 update_surface_trace(dc, srf_updates, surface_count); 3817 3818 3819 if (update_type >= UPDATE_TYPE_FULL) { 3820 3821 /* initialize scratch memory for building context */ 3822 context = dc_create_state(dc); 3823 if (context == NULL) { 3824 DC_ERROR("Failed to allocate new validate context!\n"); 3825 return; 3826 } 3827 3828 dc_resource_state_copy_construct(state, context); 3829 3830 for (i = 0; i < dc->res_pool->pipe_count; i++) { 3831 struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; 3832 struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 3833 3834 if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state) 3835 new_pipe->plane_state->force_full_update = true; 3836 } 3837 } else if (update_type == UPDATE_TYPE_FAST && dc_ctx->dce_version >= DCE_VERSION_MAX) { 3838 /* 3839 * Previous frame finished and HW is ready for optimization. 3840 * 3841 * Only relevant for DCN behavior where we can guarantee the optimization 3842 * is safe to apply - retain the legacy behavior for DCE. 3843 */ 3844 dc_post_update_surfaces_to_stream(dc); 3845 } 3846 3847 3848 for (i = 0; i < surface_count; i++) { 3849 struct dc_plane_state *surface = srf_updates[i].surface; 3850 3851 copy_surface_update_to_plane(surface, &srf_updates[i]); 3852 3853 if (update_type >= UPDATE_TYPE_MED) { 3854 for (j = 0; j < dc->res_pool->pipe_count; j++) { 3855 struct pipe_ctx *pipe_ctx = 3856 &context->res_ctx.pipe_ctx[j]; 3857 3858 if (pipe_ctx->plane_state != surface) 3859 continue; 3860 3861 resource_build_scaling_params(pipe_ctx); 3862 } 3863 } 3864 } 3865 3866 copy_stream_update_to_stream(dc, context, stream, stream_update); 3867 3868 if (update_type >= UPDATE_TYPE_FULL) { 3869 if (!dc->res_pool->funcs->validate_bandwidth(dc, context, false)) { 3870 DC_ERROR("Mode validation failed for stream update!\n"); 3871 dc_release_state(context); 3872 return; 3873 } 3874 } 3875 3876 TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES); 3877 3878 commit_planes_for_stream( 3879 dc, 3880 srf_updates, 3881 surface_count, 3882 stream, 3883 stream_update, 3884 update_type, 3885 context); 3886 /*update current_State*/ 3887 if (dc->current_state != context) { 3888 3889 struct dc_state *old = dc->current_state; 3890 3891 dc->current_state = context; 3892 dc_release_state(old); 3893 3894 for (i = 0; i < dc->res_pool->pipe_count; i++) { 3895 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 3896 3897 if (pipe_ctx->plane_state && pipe_ctx->stream == stream) 3898 pipe_ctx->plane_state->force_full_update = false; 3899 } 3900 } 3901 3902 /* Legacy optimization path for DCE. */ 3903 if (update_type >= UPDATE_TYPE_FULL && dc_ctx->dce_version < DCE_VERSION_MAX) { 3904 dc_post_update_surfaces_to_stream(dc); 3905 TRACE_DCE_CLOCK_STATE(&context->bw_ctx.bw.dce); 3906 } 3907 3908 return; 3909 3910 } 3911 3912 uint8_t dc_get_current_stream_count(struct dc *dc) 3913 { 3914 return dc->current_state->stream_count; 3915 } 3916 3917 struct dc_stream_state *dc_get_stream_at_index(struct dc *dc, uint8_t i) 3918 { 3919 if (i < dc->current_state->stream_count) 3920 return dc->current_state->streams[i]; 3921 return NULL; 3922 } 3923 3924 enum dc_irq_source dc_interrupt_to_irq_source( 3925 struct dc *dc, 3926 uint32_t src_id, 3927 uint32_t ext_id) 3928 { 3929 return dal_irq_service_to_irq_source(dc->res_pool->irqs, src_id, ext_id); 3930 } 3931 3932 /* 3933 * dc_interrupt_set() - Enable/disable an AMD hw interrupt source 3934 */ 3935 bool dc_interrupt_set(struct dc *dc, enum dc_irq_source src, bool enable) 3936 { 3937 3938 if (dc == NULL) 3939 return false; 3940 3941 return dal_irq_service_set(dc->res_pool->irqs, src, enable); 3942 } 3943 3944 void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src) 3945 { 3946 dal_irq_service_ack(dc->res_pool->irqs, src); 3947 } 3948 3949 void dc_power_down_on_boot(struct dc *dc) 3950 { 3951 if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW && 3952 dc->hwss.power_down_on_boot) 3953 dc->hwss.power_down_on_boot(dc); 3954 } 3955 3956 void dc_set_power_state( 3957 struct dc *dc, 3958 enum dc_acpi_cm_power_state power_state) 3959 { 3960 struct kref refcount; 3961 struct display_mode_lib *dml; 3962 3963 if (!dc->current_state) 3964 return; 3965 3966 switch (power_state) { 3967 case DC_ACPI_CM_POWER_STATE_D0: 3968 dc_resource_state_construct(dc, dc->current_state); 3969 3970 dc_z10_restore(dc); 3971 3972 if (dc->ctx->dmub_srv) 3973 dc_dmub_srv_wait_phy_init(dc->ctx->dmub_srv); 3974 3975 dc->hwss.init_hw(dc); 3976 3977 if (dc->hwss.init_sys_ctx != NULL && 3978 dc->vm_pa_config.valid) { 3979 dc->hwss.init_sys_ctx(dc->hwseq, dc, &dc->vm_pa_config); 3980 } 3981 3982 break; 3983 default: 3984 ASSERT(dc->current_state->stream_count == 0); 3985 /* Zero out the current context so that on resume we start with 3986 * clean state, and dc hw programming optimizations will not 3987 * cause any trouble. 3988 */ 3989 dml = kzalloc(sizeof(struct display_mode_lib), 3990 GFP_KERNEL); 3991 3992 ASSERT(dml); 3993 if (!dml) 3994 return; 3995 3996 /* Preserve refcount */ 3997 refcount = dc->current_state->refcount; 3998 /* Preserve display mode lib */ 3999 memcpy(dml, &dc->current_state->bw_ctx.dml, sizeof(struct display_mode_lib)); 4000 4001 dc_resource_state_destruct(dc->current_state); 4002 memset(dc->current_state, 0, 4003 sizeof(*dc->current_state)); 4004 4005 dc->current_state->refcount = refcount; 4006 dc->current_state->bw_ctx.dml = *dml; 4007 4008 kfree(dml); 4009 4010 break; 4011 } 4012 } 4013 4014 void dc_resume(struct dc *dc) 4015 { 4016 uint32_t i; 4017 4018 for (i = 0; i < dc->link_count; i++) 4019 core_link_resume(dc->links[i]); 4020 } 4021 4022 bool dc_is_dmcu_initialized(struct dc *dc) 4023 { 4024 struct dmcu *dmcu = dc->res_pool->dmcu; 4025 4026 if (dmcu) 4027 return dmcu->funcs->is_dmcu_initialized(dmcu); 4028 return false; 4029 } 4030 4031 bool dc_is_oem_i2c_device_present( 4032 struct dc *dc, 4033 size_t slave_address) 4034 { 4035 if (dc->res_pool->oem_device) 4036 return dce_i2c_oem_device_present( 4037 dc->res_pool, 4038 dc->res_pool->oem_device, 4039 slave_address); 4040 4041 return false; 4042 } 4043 4044 bool dc_submit_i2c( 4045 struct dc *dc, 4046 uint32_t link_index, 4047 struct i2c_command *cmd) 4048 { 4049 4050 struct dc_link *link = dc->links[link_index]; 4051 struct ddc_service *ddc = link->ddc; 4052 return dce_i2c_submit_command( 4053 dc->res_pool, 4054 ddc->ddc_pin, 4055 cmd); 4056 } 4057 4058 bool dc_submit_i2c_oem( 4059 struct dc *dc, 4060 struct i2c_command *cmd) 4061 { 4062 struct ddc_service *ddc = dc->res_pool->oem_device; 4063 if (ddc) 4064 return dce_i2c_submit_command( 4065 dc->res_pool, 4066 ddc->ddc_pin, 4067 cmd); 4068 4069 return false; 4070 } 4071 4072 static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink) 4073 { 4074 if (dc_link->sink_count >= MAX_SINKS_PER_LINK) { 4075 BREAK_TO_DEBUGGER(); 4076 return false; 4077 } 4078 4079 dc_sink_retain(sink); 4080 4081 dc_link->remote_sinks[dc_link->sink_count] = sink; 4082 dc_link->sink_count++; 4083 4084 return true; 4085 } 4086 4087 /* 4088 * dc_link_add_remote_sink() - Create a sink and attach it to an existing link 4089 * 4090 * EDID length is in bytes 4091 */ 4092 struct dc_sink *dc_link_add_remote_sink( 4093 struct dc_link *link, 4094 const uint8_t *edid, 4095 int len, 4096 struct dc_sink_init_data *init_data) 4097 { 4098 struct dc_sink *dc_sink; 4099 enum dc_edid_status edid_status; 4100 4101 if (len > DC_MAX_EDID_BUFFER_SIZE) { 4102 dm_error("Max EDID buffer size breached!\n"); 4103 return NULL; 4104 } 4105 4106 if (!init_data) { 4107 BREAK_TO_DEBUGGER(); 4108 return NULL; 4109 } 4110 4111 if (!init_data->link) { 4112 BREAK_TO_DEBUGGER(); 4113 return NULL; 4114 } 4115 4116 dc_sink = dc_sink_create(init_data); 4117 4118 if (!dc_sink) 4119 return NULL; 4120 4121 memmove(dc_sink->dc_edid.raw_edid, edid, len); 4122 dc_sink->dc_edid.length = len; 4123 4124 if (!link_add_remote_sink_helper( 4125 link, 4126 dc_sink)) 4127 goto fail_add_sink; 4128 4129 edid_status = dm_helpers_parse_edid_caps( 4130 link, 4131 &dc_sink->dc_edid, 4132 &dc_sink->edid_caps); 4133 4134 /* 4135 * Treat device as no EDID device if EDID 4136 * parsing fails 4137 */ 4138 if (edid_status != EDID_OK && edid_status != EDID_PARTIAL_VALID) { 4139 dc_sink->dc_edid.length = 0; 4140 dm_error("Bad EDID, status%d!\n", edid_status); 4141 } 4142 4143 return dc_sink; 4144 4145 fail_add_sink: 4146 dc_sink_release(dc_sink); 4147 return NULL; 4148 } 4149 4150 /* 4151 * dc_link_remove_remote_sink() - Remove a remote sink from a dc_link 4152 * 4153 * Note that this just removes the struct dc_sink - it doesn't 4154 * program hardware or alter other members of dc_link 4155 */ 4156 void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink) 4157 { 4158 int i; 4159 4160 if (!link->sink_count) { 4161 BREAK_TO_DEBUGGER(); 4162 return; 4163 } 4164 4165 for (i = 0; i < link->sink_count; i++) { 4166 if (link->remote_sinks[i] == sink) { 4167 dc_sink_release(sink); 4168 link->remote_sinks[i] = NULL; 4169 4170 /* shrink array to remove empty place */ 4171 while (i < link->sink_count - 1) { 4172 link->remote_sinks[i] = link->remote_sinks[i+1]; 4173 i++; 4174 } 4175 link->remote_sinks[i] = NULL; 4176 link->sink_count--; 4177 return; 4178 } 4179 } 4180 } 4181 4182 void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info) 4183 { 4184 info->displayClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dispclk_khz; 4185 info->engineClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_khz; 4186 info->memoryClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dramclk_khz; 4187 info->maxSupportedDppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.max_supported_dppclk_khz; 4188 info->dppClock = (unsigned int)state->bw_ctx.bw.dcn.clk.dppclk_khz; 4189 info->socClock = (unsigned int)state->bw_ctx.bw.dcn.clk.socclk_khz; 4190 info->dcfClockDeepSleep = (unsigned int)state->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz; 4191 info->fClock = (unsigned int)state->bw_ctx.bw.dcn.clk.fclk_khz; 4192 info->phyClock = (unsigned int)state->bw_ctx.bw.dcn.clk.phyclk_khz; 4193 } 4194 enum dc_status dc_set_clock(struct dc *dc, enum dc_clock_type clock_type, uint32_t clk_khz, uint32_t stepping) 4195 { 4196 if (dc->hwss.set_clock) 4197 return dc->hwss.set_clock(dc, clock_type, clk_khz, stepping); 4198 return DC_ERROR_UNEXPECTED; 4199 } 4200 void dc_get_clock(struct dc *dc, enum dc_clock_type clock_type, struct dc_clock_config *clock_cfg) 4201 { 4202 if (dc->hwss.get_clock) 4203 dc->hwss.get_clock(dc, clock_type, clock_cfg); 4204 } 4205 4206 /* enable/disable eDP PSR without specify stream for eDP */ 4207 bool dc_set_psr_allow_active(struct dc *dc, bool enable) 4208 { 4209 int i; 4210 bool allow_active; 4211 4212 for (i = 0; i < dc->current_state->stream_count ; i++) { 4213 struct dc_link *link; 4214 struct dc_stream_state *stream = dc->current_state->streams[i]; 4215 4216 link = stream->link; 4217 if (!link) 4218 continue; 4219 4220 if (link->psr_settings.psr_feature_enabled) { 4221 if (enable && !link->psr_settings.psr_allow_active) { 4222 allow_active = true; 4223 if (!dc_link_set_psr_allow_active(link, &allow_active, false, false, NULL)) 4224 return false; 4225 } else if (!enable && link->psr_settings.psr_allow_active) { 4226 allow_active = false; 4227 if (!dc_link_set_psr_allow_active(link, &allow_active, true, false, NULL)) 4228 return false; 4229 } 4230 } 4231 } 4232 4233 return true; 4234 } 4235 4236 void dc_allow_idle_optimizations(struct dc *dc, bool allow) 4237 { 4238 if (dc->debug.disable_idle_power_optimizations) 4239 return; 4240 4241 if (dc->clk_mgr != NULL && dc->clk_mgr->funcs->is_smu_present) 4242 if (!dc->clk_mgr->funcs->is_smu_present(dc->clk_mgr)) 4243 return; 4244 4245 if (allow == dc->idle_optimizations_allowed) 4246 return; 4247 4248 if (dc->hwss.apply_idle_power_optimizations && dc->hwss.apply_idle_power_optimizations(dc, allow)) 4249 dc->idle_optimizations_allowed = allow; 4250 } 4251 4252 /* set min and max memory clock to lowest and highest DPM level, respectively */ 4253 void dc_unlock_memory_clock_frequency(struct dc *dc) 4254 { 4255 if (dc->clk_mgr->funcs->set_hard_min_memclk) 4256 dc->clk_mgr->funcs->set_hard_min_memclk(dc->clk_mgr, false); 4257 4258 if (dc->clk_mgr->funcs->set_hard_max_memclk) 4259 dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); 4260 } 4261 4262 /* set min memory clock to the min required for current mode, max to maxDPM */ 4263 void dc_lock_memory_clock_frequency(struct dc *dc) 4264 { 4265 if (dc->clk_mgr->funcs->get_memclk_states_from_smu) 4266 dc->clk_mgr->funcs->get_memclk_states_from_smu(dc->clk_mgr); 4267 4268 if (dc->clk_mgr->funcs->set_hard_min_memclk) 4269 dc->clk_mgr->funcs->set_hard_min_memclk(dc->clk_mgr, true); 4270 4271 if (dc->clk_mgr->funcs->set_hard_max_memclk) 4272 dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr); 4273 } 4274 4275 static void blank_and_force_memclk(struct dc *dc, bool apply, unsigned int memclk_mhz) 4276 { 4277 struct dc_state *context = dc->current_state; 4278 struct hubp *hubp; 4279 struct pipe_ctx *pipe; 4280 int i; 4281 4282 for (i = 0; i < dc->res_pool->pipe_count; i++) { 4283 pipe = &context->res_ctx.pipe_ctx[i]; 4284 4285 if (pipe->stream != NULL) { 4286 dc->hwss.disable_pixel_data(dc, pipe, true); 4287 4288 // wait for double buffer 4289 pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VACTIVE); 4290 pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VBLANK); 4291 pipe->stream_res.tg->funcs->wait_for_state(pipe->stream_res.tg, CRTC_STATE_VACTIVE); 4292 4293 hubp = pipe->plane_res.hubp; 4294 hubp->funcs->set_blank_regs(hubp, true); 4295 } 4296 } 4297 4298 dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, memclk_mhz); 4299 dc->clk_mgr->funcs->set_min_memclk(dc->clk_mgr, memclk_mhz); 4300 4301 for (i = 0; i < dc->res_pool->pipe_count; i++) { 4302 pipe = &context->res_ctx.pipe_ctx[i]; 4303 4304 if (pipe->stream != NULL) { 4305 dc->hwss.disable_pixel_data(dc, pipe, false); 4306 4307 hubp = pipe->plane_res.hubp; 4308 hubp->funcs->set_blank_regs(hubp, false); 4309 } 4310 } 4311 } 4312 4313 4314 /** 4315 * dc_enable_dcmode_clk_limit() - lower clocks in dc (battery) mode 4316 * @dc: pointer to dc of the dm calling this 4317 * @enable: True = transition to DC mode, false = transition back to AC mode 4318 * 4319 * Some SoCs define additional clock limits when in DC mode, DM should 4320 * invoke this function when the platform undergoes a power source transition 4321 * so DC can apply/unapply the limit. This interface may be disruptive to 4322 * the onscreen content. 4323 * 4324 * Context: Triggered by OS through DM interface, or manually by escape calls. 4325 * Need to hold a dclock when doing so. 4326 * 4327 * Return: none (void function) 4328 * 4329 */ 4330 void dc_enable_dcmode_clk_limit(struct dc *dc, bool enable) 4331 { 4332 uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev; 4333 unsigned int softMax, maxDPM, funcMin; 4334 bool p_state_change_support; 4335 4336 if (!ASICREV_IS_BEIGE_GOBY_P(hw_internal_rev)) 4337 return; 4338 4339 softMax = dc->clk_mgr->bw_params->dc_mode_softmax_memclk; 4340 maxDPM = dc->clk_mgr->bw_params->clk_table.entries[dc->clk_mgr->bw_params->clk_table.num_entries - 1].memclk_mhz; 4341 funcMin = (dc->clk_mgr->clks.dramclk_khz + 999) / 1000; 4342 p_state_change_support = dc->clk_mgr->clks.p_state_change_support; 4343 4344 if (enable && !dc->clk_mgr->dc_mode_softmax_enabled) { 4345 if (p_state_change_support) { 4346 if (funcMin <= softMax) 4347 dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, softMax); 4348 // else: No-Op 4349 } else { 4350 if (funcMin <= softMax) 4351 blank_and_force_memclk(dc, true, softMax); 4352 // else: No-Op 4353 } 4354 } else if (!enable && dc->clk_mgr->dc_mode_softmax_enabled) { 4355 if (p_state_change_support) { 4356 if (funcMin <= softMax) 4357 dc->clk_mgr->funcs->set_max_memclk(dc->clk_mgr, maxDPM); 4358 // else: No-Op 4359 } else { 4360 if (funcMin <= softMax) 4361 blank_and_force_memclk(dc, true, maxDPM); 4362 // else: No-Op 4363 } 4364 } 4365 dc->clk_mgr->dc_mode_softmax_enabled = enable; 4366 } 4367 bool dc_is_plane_eligible_for_idle_optimizations(struct dc *dc, struct dc_plane_state *plane, 4368 struct dc_cursor_attributes *cursor_attr) 4369 { 4370 if (dc->hwss.does_plane_fit_in_mall && dc->hwss.does_plane_fit_in_mall(dc, plane, cursor_attr)) 4371 return true; 4372 return false; 4373 } 4374 4375 /* cleanup on driver unload */ 4376 void dc_hardware_release(struct dc *dc) 4377 { 4378 dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(dc); 4379 4380 if (dc->hwss.hardware_release) 4381 dc->hwss.hardware_release(dc); 4382 } 4383 4384 void dc_mclk_switch_using_fw_based_vblank_stretch_shut_down(struct dc *dc) 4385 { 4386 if (dc->current_state) 4387 dc->current_state->bw_ctx.bw.dcn.clk.fw_based_mclk_switching_shut_down = true; 4388 } 4389 4390 /* 4391 ***************************************************************************** 4392 * Function: dc_is_dmub_outbox_supported - 4393 * 4394 * @brief 4395 * Checks whether DMUB FW supports outbox notifications, if supported 4396 * DM should register outbox interrupt prior to actually enabling interrupts 4397 * via dc_enable_dmub_outbox 4398 * 4399 * @param 4400 * [in] dc: dc structure 4401 * 4402 * @return 4403 * True if DMUB FW supports outbox notifications, False otherwise 4404 ***************************************************************************** 4405 */ 4406 bool dc_is_dmub_outbox_supported(struct dc *dc) 4407 { 4408 /* DCN31 B0 USB4 DPIA needs dmub notifications for interrupts */ 4409 if (dc->ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && 4410 dc->ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0 && 4411 !dc->debug.dpia_debug.bits.disable_dpia) 4412 return true; 4413 4414 if (dc->ctx->asic_id.chip_family == AMDGPU_FAMILY_GC_11_0_1 && 4415 !dc->debug.dpia_debug.bits.disable_dpia) 4416 return true; 4417 4418 /* dmub aux needs dmub notifications to be enabled */ 4419 return dc->debug.enable_dmub_aux_for_legacy_ddc; 4420 } 4421 4422 /* 4423 ***************************************************************************** 4424 * Function: dc_enable_dmub_notifications 4425 * 4426 * @brief 4427 * Calls dc_is_dmub_outbox_supported to check if dmub fw supports outbox 4428 * notifications. All DMs shall switch to dc_is_dmub_outbox_supported. 4429 * This API shall be removed after switching. 4430 * 4431 * @param 4432 * [in] dc: dc structure 4433 * 4434 * @return 4435 * True if DMUB FW supports outbox notifications, False otherwise 4436 ***************************************************************************** 4437 */ 4438 bool dc_enable_dmub_notifications(struct dc *dc) 4439 { 4440 return dc_is_dmub_outbox_supported(dc); 4441 } 4442 4443 /** 4444 ***************************************************************************** 4445 * Function: dc_enable_dmub_outbox 4446 * 4447 * @brief 4448 * Enables DMUB unsolicited notifications to x86 via outbox 4449 * 4450 * @param 4451 * [in] dc: dc structure 4452 * 4453 * @return 4454 * None 4455 ***************************************************************************** 4456 */ 4457 void dc_enable_dmub_outbox(struct dc *dc) 4458 { 4459 struct dc_context *dc_ctx = dc->ctx; 4460 4461 dmub_enable_outbox_notification(dc_ctx->dmub_srv); 4462 DC_LOG_DC("%s: dmub outbox notifications enabled\n", __func__); 4463 } 4464 4465 /** 4466 * dc_process_dmub_aux_transfer_async - Submits aux command to dmub via inbox message 4467 * Sets port index appropriately for legacy DDC 4468 * @dc: dc structure 4469 * @link_index: link index 4470 * @payload: aux payload 4471 * 4472 * Returns: True if successful, False if failure 4473 */ 4474 bool dc_process_dmub_aux_transfer_async(struct dc *dc, 4475 uint32_t link_index, 4476 struct aux_payload *payload) 4477 { 4478 uint8_t action; 4479 union dmub_rb_cmd cmd = {0}; 4480 struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv; 4481 4482 ASSERT(payload->length <= 16); 4483 4484 cmd.dp_aux_access.header.type = DMUB_CMD__DP_AUX_ACCESS; 4485 cmd.dp_aux_access.header.payload_bytes = 0; 4486 /* For dpia, ddc_pin is set to NULL */ 4487 if (!dc->links[link_index]->ddc->ddc_pin) 4488 cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_DPIA; 4489 else 4490 cmd.dp_aux_access.aux_control.type = AUX_CHANNEL_LEGACY_DDC; 4491 4492 cmd.dp_aux_access.aux_control.instance = dc->links[link_index]->ddc_hw_inst; 4493 cmd.dp_aux_access.aux_control.sw_crc_enabled = 0; 4494 cmd.dp_aux_access.aux_control.timeout = 0; 4495 cmd.dp_aux_access.aux_control.dpaux.address = payload->address; 4496 cmd.dp_aux_access.aux_control.dpaux.is_i2c_over_aux = payload->i2c_over_aux; 4497 cmd.dp_aux_access.aux_control.dpaux.length = payload->length; 4498 4499 /* set aux action */ 4500 if (payload->i2c_over_aux) { 4501 if (payload->write) { 4502 if (payload->mot) 4503 action = DP_AUX_REQ_ACTION_I2C_WRITE_MOT; 4504 else 4505 action = DP_AUX_REQ_ACTION_I2C_WRITE; 4506 } else { 4507 if (payload->mot) 4508 action = DP_AUX_REQ_ACTION_I2C_READ_MOT; 4509 else 4510 action = DP_AUX_REQ_ACTION_I2C_READ; 4511 } 4512 } else { 4513 if (payload->write) 4514 action = DP_AUX_REQ_ACTION_DPCD_WRITE; 4515 else 4516 action = DP_AUX_REQ_ACTION_DPCD_READ; 4517 } 4518 4519 cmd.dp_aux_access.aux_control.dpaux.action = action; 4520 4521 if (payload->length && payload->write) { 4522 memcpy(cmd.dp_aux_access.aux_control.dpaux.data, 4523 payload->data, 4524 payload->length 4525 ); 4526 } 4527 4528 dc_dmub_srv_cmd_queue(dmub_srv, &cmd); 4529 dc_dmub_srv_cmd_execute(dmub_srv); 4530 dc_dmub_srv_wait_idle(dmub_srv); 4531 4532 return true; 4533 } 4534 4535 uint8_t get_link_index_from_dpia_port_index(const struct dc *dc, 4536 uint8_t dpia_port_index) 4537 { 4538 uint8_t index, link_index = 0xFF; 4539 4540 for (index = 0; index < dc->link_count; index++) { 4541 /* ddc_hw_inst has dpia port index for dpia links 4542 * and ddc instance for legacy links 4543 */ 4544 if (!dc->links[index]->ddc->ddc_pin) { 4545 if (dc->links[index]->ddc_hw_inst == dpia_port_index) { 4546 link_index = index; 4547 break; 4548 } 4549 } 4550 } 4551 ASSERT(link_index != 0xFF); 4552 return link_index; 4553 } 4554 4555 /** 4556 ***************************************************************************** 4557 * Function: dc_process_dmub_set_config_async 4558 * 4559 * @brief 4560 * Submits set_config command to dmub via inbox message 4561 * 4562 * @param 4563 * [in] dc: dc structure 4564 * [in] link_index: link index 4565 * [in] payload: aux payload 4566 * [out] notify: set_config immediate reply 4567 * 4568 * @return 4569 * True if successful, False if failure 4570 ***************************************************************************** 4571 */ 4572 bool dc_process_dmub_set_config_async(struct dc *dc, 4573 uint32_t link_index, 4574 struct set_config_cmd_payload *payload, 4575 struct dmub_notification *notify) 4576 { 4577 union dmub_rb_cmd cmd = {0}; 4578 struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv; 4579 bool is_cmd_complete = true; 4580 4581 /* prepare SET_CONFIG command */ 4582 cmd.set_config_access.header.type = DMUB_CMD__DPIA; 4583 cmd.set_config_access.header.sub_type = DMUB_CMD__DPIA_SET_CONFIG_ACCESS; 4584 4585 cmd.set_config_access.set_config_control.instance = dc->links[link_index]->ddc_hw_inst; 4586 cmd.set_config_access.set_config_control.cmd_pkt.msg_type = payload->msg_type; 4587 cmd.set_config_access.set_config_control.cmd_pkt.msg_data = payload->msg_data; 4588 4589 if (!dc_dmub_srv_cmd_with_reply_data(dmub_srv, &cmd)) { 4590 /* command is not processed by dmub */ 4591 notify->sc_status = SET_CONFIG_UNKNOWN_ERROR; 4592 return is_cmd_complete; 4593 } 4594 4595 /* command processed by dmub, if ret_status is 1, it is completed instantly */ 4596 if (cmd.set_config_access.header.ret_status == 1) 4597 notify->sc_status = cmd.set_config_access.set_config_control.immed_status; 4598 else 4599 /* cmd pending, will receive notification via outbox */ 4600 is_cmd_complete = false; 4601 4602 return is_cmd_complete; 4603 } 4604 4605 /** 4606 ***************************************************************************** 4607 * Function: dc_process_dmub_set_mst_slots 4608 * 4609 * @brief 4610 * Submits mst slot allocation command to dmub via inbox message 4611 * 4612 * @param 4613 * [in] dc: dc structure 4614 * [in] link_index: link index 4615 * [in] mst_alloc_slots: mst slots to be allotted 4616 * [out] mst_slots_in_use: mst slots in use returned in failure case 4617 * 4618 * @return 4619 * DC_OK if successful, DC_ERROR if failure 4620 ***************************************************************************** 4621 */ 4622 enum dc_status dc_process_dmub_set_mst_slots(const struct dc *dc, 4623 uint32_t link_index, 4624 uint8_t mst_alloc_slots, 4625 uint8_t *mst_slots_in_use) 4626 { 4627 union dmub_rb_cmd cmd = {0}; 4628 struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv; 4629 4630 /* prepare MST_ALLOC_SLOTS command */ 4631 cmd.set_mst_alloc_slots.header.type = DMUB_CMD__DPIA; 4632 cmd.set_mst_alloc_slots.header.sub_type = DMUB_CMD__DPIA_MST_ALLOC_SLOTS; 4633 4634 cmd.set_mst_alloc_slots.mst_slots_control.instance = dc->links[link_index]->ddc_hw_inst; 4635 cmd.set_mst_alloc_slots.mst_slots_control.mst_alloc_slots = mst_alloc_slots; 4636 4637 if (!dc_dmub_srv_cmd_with_reply_data(dmub_srv, &cmd)) 4638 /* command is not processed by dmub */ 4639 return DC_ERROR_UNEXPECTED; 4640 4641 /* command processed by dmub, if ret_status is 1 */ 4642 if (cmd.set_config_access.header.ret_status != 1) 4643 /* command processing error */ 4644 return DC_ERROR_UNEXPECTED; 4645 4646 /* command processed and we have a status of 2, mst not enabled in dpia */ 4647 if (cmd.set_mst_alloc_slots.mst_slots_control.immed_status == 2) 4648 return DC_FAIL_UNSUPPORTED_1; 4649 4650 /* previously configured mst alloc and used slots did not match */ 4651 if (cmd.set_mst_alloc_slots.mst_slots_control.immed_status == 3) { 4652 *mst_slots_in_use = cmd.set_mst_alloc_slots.mst_slots_control.mst_slots_in_use; 4653 return DC_NOT_SUPPORTED; 4654 } 4655 4656 return DC_OK; 4657 } 4658 4659 /** 4660 ***************************************************************************** 4661 * Function: dc_process_dmub_dpia_hpd_int_enable 4662 * 4663 * @brief 4664 * Submits dpia hpd int enable command to dmub via inbox message 4665 * 4666 * @param 4667 * [in] dc: dc structure 4668 * [in] hpd_int_enable: 1 for hpd int enable, 0 to disable 4669 * 4670 * @return 4671 * None 4672 ***************************************************************************** 4673 */ 4674 void dc_process_dmub_dpia_hpd_int_enable(const struct dc *dc, 4675 uint32_t hpd_int_enable) 4676 { 4677 union dmub_rb_cmd cmd = {0}; 4678 struct dc_dmub_srv *dmub_srv = dc->ctx->dmub_srv; 4679 4680 cmd.dpia_hpd_int_enable.header.type = DMUB_CMD__DPIA_HPD_INT_ENABLE; 4681 cmd.dpia_hpd_int_enable.enable = hpd_int_enable; 4682 4683 dc_dmub_srv_cmd_queue(dmub_srv, &cmd); 4684 dc_dmub_srv_cmd_execute(dmub_srv); 4685 dc_dmub_srv_wait_idle(dmub_srv); 4686 4687 DC_LOG_DEBUG("%s: hpd_int_enable(%d)\n", __func__, hpd_int_enable); 4688 } 4689 4690 /** 4691 * dc_disable_accelerated_mode - disable accelerated mode 4692 * @dc: dc structure 4693 */ 4694 void dc_disable_accelerated_mode(struct dc *dc) 4695 { 4696 bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 0); 4697 } 4698 4699 4700 /** 4701 ***************************************************************************** 4702 * dc_notify_vsync_int_state() - notifies vsync enable/disable state 4703 * @dc: dc structure 4704 * @stream: stream where vsync int state changed 4705 * @enable: whether vsync is enabled or disabled 4706 * 4707 * Called when vsync is enabled/disabled 4708 * Will notify DMUB to start/stop ABM interrupts after steady state is reached 4709 * 4710 ***************************************************************************** 4711 */ 4712 void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bool enable) 4713 { 4714 int i; 4715 int edp_num; 4716 struct pipe_ctx *pipe = NULL; 4717 struct dc_link *link = stream->sink->link; 4718 struct dc_link *edp_links[MAX_NUM_EDP]; 4719 4720 4721 if (link->psr_settings.psr_feature_enabled) 4722 return; 4723 4724 /*find primary pipe associated with stream*/ 4725 for (i = 0; i < MAX_PIPES; i++) { 4726 pipe = &dc->current_state->res_ctx.pipe_ctx[i]; 4727 4728 if (pipe->stream == stream && pipe->stream_res.tg) 4729 break; 4730 } 4731 4732 if (i == MAX_PIPES) { 4733 ASSERT(0); 4734 return; 4735 } 4736 4737 get_edp_links(dc, edp_links, &edp_num); 4738 4739 /* Determine panel inst */ 4740 for (i = 0; i < edp_num; i++) { 4741 if (edp_links[i] == link) 4742 break; 4743 } 4744 4745 if (i == edp_num) { 4746 return; 4747 } 4748 4749 if (pipe->stream_res.abm && pipe->stream_res.abm->funcs->set_abm_pause) 4750 pipe->stream_res.abm->funcs->set_abm_pause(pipe->stream_res.abm, !enable, i, pipe->stream_res.tg->inst); 4751 } 4752 /* 4753 * dc_extended_blank_supported: Decide whether extended blank is supported 4754 * 4755 * Extended blank is a freesync optimization feature to be enabled in the future. 4756 * During the extra vblank period gained from freesync, we have the ability to enter z9/z10. 4757 * 4758 * @param [in] dc: Current DC state 4759 * @return: Indicate whether extended blank is supported (true or false) 4760 */ 4761 bool dc_extended_blank_supported(struct dc *dc) 4762 { 4763 return dc->debug.extended_blank_optimization && !dc->debug.disable_z10 4764 && dc->caps.zstate_support && dc->caps.is_apu; 4765 } 4766