1 /* 2 * Copyright 2012-15 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include <drm/drm_atomic.h> 27 #include <drm/drm_atomic_helper.h> 28 #include <drm/drm_dp_mst_helper.h> 29 #include <drm/drm_dp_helper.h> 30 #include "dm_services.h" 31 #include "amdgpu.h" 32 #include "amdgpu_dm.h" 33 #include "amdgpu_dm_mst_types.h" 34 35 #include "dc.h" 36 #include "dm_helpers.h" 37 38 #include "dc_link_ddc.h" 39 40 #include "i2caux_interface.h" 41 #if defined(CONFIG_DEBUG_FS) 42 #include "amdgpu_dm_debugfs.h" 43 #endif 44 45 #if defined(CONFIG_DRM_AMD_DC_DCN) 46 #include "dc/dcn20/dcn20_resource.h" 47 #endif 48 49 static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux, 50 struct drm_dp_aux_msg *msg) 51 { 52 ssize_t result = 0; 53 struct aux_payload payload; 54 enum aux_channel_operation_result operation_result; 55 56 if (WARN_ON(msg->size > 16)) 57 return -E2BIG; 58 59 payload.address = msg->address; 60 payload.data = msg->buffer; 61 payload.length = msg->size; 62 payload.reply = &msg->reply; 63 payload.i2c_over_aux = (msg->request & DP_AUX_NATIVE_WRITE) == 0; 64 payload.write = (msg->request & DP_AUX_I2C_READ) == 0; 65 payload.mot = (msg->request & DP_AUX_I2C_MOT) != 0; 66 payload.defer_delay = 0; 67 68 result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload, 69 &operation_result); 70 71 if (payload.write && result >= 0) 72 result = msg->size; 73 74 if (result < 0) 75 switch (operation_result) { 76 case AUX_CHANNEL_OPERATION_SUCCEEDED: 77 break; 78 case AUX_CHANNEL_OPERATION_FAILED_HPD_DISCON: 79 case AUX_CHANNEL_OPERATION_FAILED_REASON_UNKNOWN: 80 result = -EIO; 81 break; 82 case AUX_CHANNEL_OPERATION_FAILED_INVALID_REPLY: 83 case AUX_CHANNEL_OPERATION_FAILED_ENGINE_ACQUIRE: 84 result = -EBUSY; 85 break; 86 case AUX_CHANNEL_OPERATION_FAILED_TIMEOUT: 87 result = -ETIMEDOUT; 88 break; 89 } 90 91 return result; 92 } 93 94 static void 95 dm_dp_mst_connector_destroy(struct drm_connector *connector) 96 { 97 struct amdgpu_dm_connector *aconnector = 98 to_amdgpu_dm_connector(connector); 99 100 if (aconnector->dc_sink) { 101 dc_link_remove_remote_sink(aconnector->dc_link, 102 aconnector->dc_sink); 103 dc_sink_release(aconnector->dc_sink); 104 } 105 106 kfree(aconnector->edid); 107 108 drm_connector_cleanup(connector); 109 drm_dp_mst_put_port_malloc(aconnector->port); 110 kfree(aconnector); 111 } 112 113 static int 114 amdgpu_dm_mst_connector_late_register(struct drm_connector *connector) 115 { 116 struct amdgpu_dm_connector *amdgpu_dm_connector = 117 to_amdgpu_dm_connector(connector); 118 int r; 119 120 r = drm_dp_mst_connector_late_register(connector, 121 amdgpu_dm_connector->port); 122 if (r < 0) 123 return r; 124 125 #if defined(CONFIG_DEBUG_FS) 126 connector_debugfs_init(amdgpu_dm_connector); 127 #endif 128 129 return 0; 130 } 131 132 static void 133 amdgpu_dm_mst_connector_early_unregister(struct drm_connector *connector) 134 { 135 struct amdgpu_dm_connector *amdgpu_dm_connector = 136 to_amdgpu_dm_connector(connector); 137 struct drm_dp_mst_port *port = amdgpu_dm_connector->port; 138 139 drm_dp_mst_connector_early_unregister(connector, port); 140 } 141 142 static const struct drm_connector_funcs dm_dp_mst_connector_funcs = { 143 .fill_modes = drm_helper_probe_single_connector_modes, 144 .destroy = dm_dp_mst_connector_destroy, 145 .reset = amdgpu_dm_connector_funcs_reset, 146 .atomic_duplicate_state = amdgpu_dm_connector_atomic_duplicate_state, 147 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 148 .atomic_set_property = amdgpu_dm_connector_atomic_set_property, 149 .atomic_get_property = amdgpu_dm_connector_atomic_get_property, 150 .late_register = amdgpu_dm_mst_connector_late_register, 151 .early_unregister = amdgpu_dm_mst_connector_early_unregister, 152 }; 153 154 #if defined(CONFIG_DRM_AMD_DC_DCN) 155 static bool validate_dsc_caps_on_connector(struct amdgpu_dm_connector *aconnector) 156 { 157 struct dc_sink *dc_sink = aconnector->dc_sink; 158 struct drm_dp_mst_port *port = aconnector->port; 159 u8 dsc_caps[16] = { 0 }; 160 161 aconnector->dsc_aux = drm_dp_mst_dsc_aux_for_port(port); 162 #if defined(CONFIG_HP_HOOK_WORKAROUND) 163 /* 164 * drm_dp_mst_dsc_aux_for_port() will return NULL for certain configs 165 * because it only check the dsc/fec caps of the "port variable" and not the dock 166 * 167 * This case will return NULL: DSC capabe MST dock connected to a non fec/dsc capable display 168 * 169 * Workaround: explicitly check the use case above and use the mst dock's aux as dsc_aux 170 * 171 */ 172 173 if (!aconnector->dsc_aux && !port->parent->port_parent) 174 aconnector->dsc_aux = &aconnector->mst_port->dm_dp_aux.aux; 175 #endif 176 if (!aconnector->dsc_aux) 177 return false; 178 179 if (drm_dp_dpcd_read(aconnector->dsc_aux, DP_DSC_SUPPORT, dsc_caps, 16) < 0) 180 return false; 181 182 if (!dc_dsc_parse_dsc_dpcd(aconnector->dc_link->ctx->dc, 183 dsc_caps, NULL, 184 &dc_sink->dsc_caps.dsc_dec_caps)) 185 return false; 186 187 return true; 188 } 189 #endif 190 191 static int dm_dp_mst_get_modes(struct drm_connector *connector) 192 { 193 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 194 int ret = 0; 195 196 if (!aconnector) 197 return drm_add_edid_modes(connector, NULL); 198 199 if (!aconnector->edid) { 200 struct edid *edid; 201 edid = drm_dp_mst_get_edid(connector, &aconnector->mst_port->mst_mgr, aconnector->port); 202 203 if (!edid) { 204 drm_connector_update_edid_property( 205 &aconnector->base, 206 NULL); 207 return ret; 208 } 209 210 aconnector->edid = edid; 211 } 212 213 if (aconnector->dc_sink && aconnector->dc_sink->sink_signal == SIGNAL_TYPE_VIRTUAL) { 214 dc_sink_release(aconnector->dc_sink); 215 aconnector->dc_sink = NULL; 216 } 217 218 if (!aconnector->dc_sink) { 219 struct dc_sink *dc_sink; 220 struct dc_sink_init_data init_params = { 221 .link = aconnector->dc_link, 222 .sink_signal = SIGNAL_TYPE_DISPLAY_PORT_MST }; 223 dc_sink = dc_link_add_remote_sink( 224 aconnector->dc_link, 225 (uint8_t *)aconnector->edid, 226 (aconnector->edid->extensions + 1) * EDID_LENGTH, 227 &init_params); 228 229 dc_sink->priv = aconnector; 230 /* dc_link_add_remote_sink returns a new reference */ 231 aconnector->dc_sink = dc_sink; 232 233 if (aconnector->dc_sink) { 234 amdgpu_dm_update_freesync_caps( 235 connector, aconnector->edid); 236 237 #if defined(CONFIG_DRM_AMD_DC_DCN) 238 if (!validate_dsc_caps_on_connector(aconnector)) 239 memset(&aconnector->dc_sink->dsc_caps, 240 0, sizeof(aconnector->dc_sink->dsc_caps)); 241 #endif 242 } 243 } 244 245 drm_connector_update_edid_property( 246 &aconnector->base, aconnector->edid); 247 248 ret = drm_add_edid_modes(connector, aconnector->edid); 249 250 return ret; 251 } 252 253 static struct drm_encoder * 254 dm_mst_atomic_best_encoder(struct drm_connector *connector, 255 struct drm_atomic_state *state) 256 { 257 struct drm_connector_state *connector_state = drm_atomic_get_new_connector_state(state, 258 connector); 259 struct drm_device *dev = connector->dev; 260 struct amdgpu_device *adev = drm_to_adev(dev); 261 struct amdgpu_crtc *acrtc = to_amdgpu_crtc(connector_state->crtc); 262 263 return &adev->dm.mst_encoders[acrtc->crtc_id].base; 264 } 265 266 static int 267 dm_dp_mst_detect(struct drm_connector *connector, 268 struct drm_modeset_acquire_ctx *ctx, bool force) 269 { 270 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 271 struct amdgpu_dm_connector *master = aconnector->mst_port; 272 273 return drm_dp_mst_detect_port(connector, ctx, &master->mst_mgr, 274 aconnector->port); 275 } 276 277 static int dm_dp_mst_atomic_check(struct drm_connector *connector, 278 struct drm_atomic_state *state) 279 { 280 struct drm_connector_state *new_conn_state = 281 drm_atomic_get_new_connector_state(state, connector); 282 struct drm_connector_state *old_conn_state = 283 drm_atomic_get_old_connector_state(state, connector); 284 struct amdgpu_dm_connector *aconnector = to_amdgpu_dm_connector(connector); 285 struct drm_crtc_state *new_crtc_state; 286 struct drm_dp_mst_topology_mgr *mst_mgr; 287 struct drm_dp_mst_port *mst_port; 288 289 mst_port = aconnector->port; 290 mst_mgr = &aconnector->mst_port->mst_mgr; 291 292 if (!old_conn_state->crtc) 293 return 0; 294 295 if (new_conn_state->crtc) { 296 new_crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc); 297 if (!new_crtc_state || 298 !drm_atomic_crtc_needs_modeset(new_crtc_state) || 299 new_crtc_state->enable) 300 return 0; 301 } 302 303 return drm_dp_atomic_release_vcpi_slots(state, 304 mst_mgr, 305 mst_port); 306 } 307 308 static const struct drm_connector_helper_funcs dm_dp_mst_connector_helper_funcs = { 309 .get_modes = dm_dp_mst_get_modes, 310 .mode_valid = amdgpu_dm_connector_mode_valid, 311 .atomic_best_encoder = dm_mst_atomic_best_encoder, 312 .detect_ctx = dm_dp_mst_detect, 313 .atomic_check = dm_dp_mst_atomic_check, 314 }; 315 316 static void amdgpu_dm_encoder_destroy(struct drm_encoder *encoder) 317 { 318 drm_encoder_cleanup(encoder); 319 kfree(encoder); 320 } 321 322 static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = { 323 .destroy = amdgpu_dm_encoder_destroy, 324 }; 325 326 void 327 dm_dp_create_fake_mst_encoders(struct amdgpu_device *adev) 328 { 329 struct drm_device *dev = adev_to_drm(adev); 330 int i; 331 332 for (i = 0; i < adev->dm.display_indexes_num; i++) { 333 struct amdgpu_encoder *amdgpu_encoder = &adev->dm.mst_encoders[i]; 334 struct drm_encoder *encoder = &amdgpu_encoder->base; 335 336 encoder->possible_crtcs = amdgpu_dm_get_encoder_crtc_mask(adev); 337 338 drm_encoder_init( 339 dev, 340 &amdgpu_encoder->base, 341 &amdgpu_dm_encoder_funcs, 342 DRM_MODE_ENCODER_DPMST, 343 NULL); 344 345 drm_encoder_helper_add(encoder, &amdgpu_dm_encoder_helper_funcs); 346 } 347 } 348 349 static struct drm_connector * 350 dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, 351 struct drm_dp_mst_port *port, 352 const char *pathprop) 353 { 354 struct amdgpu_dm_connector *master = container_of(mgr, struct amdgpu_dm_connector, mst_mgr); 355 struct drm_device *dev = master->base.dev; 356 struct amdgpu_device *adev = drm_to_adev(dev); 357 struct amdgpu_dm_connector *aconnector; 358 struct drm_connector *connector; 359 int i; 360 361 aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); 362 if (!aconnector) 363 return NULL; 364 365 connector = &aconnector->base; 366 aconnector->port = port; 367 aconnector->mst_port = master; 368 369 if (drm_connector_init( 370 dev, 371 connector, 372 &dm_dp_mst_connector_funcs, 373 DRM_MODE_CONNECTOR_DisplayPort)) { 374 kfree(aconnector); 375 return NULL; 376 } 377 drm_connector_helper_add(connector, &dm_dp_mst_connector_helper_funcs); 378 379 amdgpu_dm_connector_init_helper( 380 &adev->dm, 381 aconnector, 382 DRM_MODE_CONNECTOR_DisplayPort, 383 master->dc_link, 384 master->connector_id); 385 386 for (i = 0; i < adev->dm.display_indexes_num; i++) { 387 drm_connector_attach_encoder(&aconnector->base, 388 &adev->dm.mst_encoders[i].base); 389 } 390 391 connector->max_bpc_property = master->base.max_bpc_property; 392 if (connector->max_bpc_property) 393 drm_connector_attach_max_bpc_property(connector, 8, 16); 394 395 connector->vrr_capable_property = master->base.vrr_capable_property; 396 if (connector->vrr_capable_property) 397 drm_connector_attach_vrr_capable_property(connector); 398 399 drm_object_attach_property( 400 &connector->base, 401 dev->mode_config.path_property, 402 0); 403 drm_object_attach_property( 404 &connector->base, 405 dev->mode_config.tile_property, 406 0); 407 408 drm_connector_set_path_property(connector, pathprop); 409 410 /* 411 * Initialize connector state before adding the connectror to drm and 412 * framebuffer lists 413 */ 414 amdgpu_dm_connector_funcs_reset(connector); 415 416 drm_dp_mst_get_port_malloc(port); 417 418 return connector; 419 } 420 421 static const struct drm_dp_mst_topology_cbs dm_mst_cbs = { 422 .add_connector = dm_dp_add_mst_connector, 423 }; 424 425 void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, 426 struct amdgpu_dm_connector *aconnector, 427 int link_index) 428 { 429 aconnector->dm_dp_aux.aux.name = 430 kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d", 431 link_index); 432 aconnector->dm_dp_aux.aux.transfer = dm_dp_aux_transfer; 433 aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc; 434 435 drm_dp_aux_init(&aconnector->dm_dp_aux.aux); 436 drm_dp_cec_register_connector(&aconnector->dm_dp_aux.aux, 437 &aconnector->base); 438 439 if (aconnector->base.connector_type == DRM_MODE_CONNECTOR_eDP) 440 return; 441 442 aconnector->mst_mgr.cbs = &dm_mst_cbs; 443 drm_dp_mst_topology_mgr_init( 444 &aconnector->mst_mgr, 445 adev_to_drm(dm->adev), 446 &aconnector->dm_dp_aux.aux, 447 16, 448 4, 449 aconnector->connector_id); 450 451 drm_connector_attach_dp_subconnector_property(&aconnector->base); 452 } 453 454 int dm_mst_get_pbn_divider(struct dc_link *link) 455 { 456 if (!link) 457 return 0; 458 459 return dc_link_bandwidth_kbps(link, 460 dc_link_get_link_cap(link)) / (8 * 1000 * 54); 461 } 462 463 #if defined(CONFIG_DRM_AMD_DC_DCN) 464 465 struct dsc_mst_fairness_params { 466 struct dc_crtc_timing *timing; 467 struct dc_sink *sink; 468 struct dc_dsc_bw_range bw_range; 469 bool compression_possible; 470 struct drm_dp_mst_port *port; 471 enum dsc_clock_force_state clock_force_enable; 472 uint32_t num_slices_h; 473 uint32_t num_slices_v; 474 uint32_t bpp_overwrite; 475 }; 476 477 struct dsc_mst_fairness_vars { 478 int pbn; 479 bool dsc_enabled; 480 int bpp_x16; 481 }; 482 483 static int kbps_to_peak_pbn(int kbps) 484 { 485 u64 peak_kbps = kbps; 486 487 peak_kbps *= 1006; 488 peak_kbps = div_u64(peak_kbps, 1000); 489 return (int) DIV64_U64_ROUND_UP(peak_kbps * 64, (54 * 8 * 1000)); 490 } 491 492 static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *params, 493 struct dsc_mst_fairness_vars *vars, 494 int count) 495 { 496 int i; 497 498 for (i = 0; i < count; i++) { 499 memset(¶ms[i].timing->dsc_cfg, 0, sizeof(params[i].timing->dsc_cfg)); 500 if (vars[i].dsc_enabled && dc_dsc_compute_config( 501 params[i].sink->ctx->dc->res_pool->dscs[0], 502 ¶ms[i].sink->dsc_caps.dsc_dec_caps, 503 params[i].sink->ctx->dc->debug.dsc_min_slice_height_override, 504 0, 505 0, 506 params[i].timing, 507 ¶ms[i].timing->dsc_cfg)) { 508 params[i].timing->flags.DSC = 1; 509 510 if (params[i].bpp_overwrite) 511 params[i].timing->dsc_cfg.bits_per_pixel = params[i].bpp_overwrite; 512 else 513 params[i].timing->dsc_cfg.bits_per_pixel = vars[i].bpp_x16; 514 515 if (params[i].num_slices_h) 516 params[i].timing->dsc_cfg.num_slices_h = params[i].num_slices_h; 517 518 if (params[i].num_slices_v) 519 params[i].timing->dsc_cfg.num_slices_v = params[i].num_slices_v; 520 } else { 521 params[i].timing->flags.DSC = 0; 522 } 523 } 524 } 525 526 static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn) 527 { 528 struct dc_dsc_config dsc_config; 529 u64 kbps; 530 531 kbps = div_u64((u64)pbn * 994 * 8 * 54, 64); 532 dc_dsc_compute_config( 533 param.sink->ctx->dc->res_pool->dscs[0], 534 ¶m.sink->dsc_caps.dsc_dec_caps, 535 param.sink->ctx->dc->debug.dsc_min_slice_height_override, 536 0, 537 (int) kbps, param.timing, &dsc_config); 538 539 return dsc_config.bits_per_pixel; 540 } 541 542 static void increase_dsc_bpp(struct drm_atomic_state *state, 543 struct dc_link *dc_link, 544 struct dsc_mst_fairness_params *params, 545 struct dsc_mst_fairness_vars *vars, 546 int count) 547 { 548 int i; 549 bool bpp_increased[MAX_PIPES]; 550 int initial_slack[MAX_PIPES]; 551 int min_initial_slack; 552 int next_index; 553 int remaining_to_increase = 0; 554 int pbn_per_timeslot; 555 int link_timeslots_used; 556 int fair_pbn_alloc; 557 558 pbn_per_timeslot = dm_mst_get_pbn_divider(dc_link); 559 560 for (i = 0; i < count; i++) { 561 if (vars[i].dsc_enabled) { 562 initial_slack[i] = kbps_to_peak_pbn(params[i].bw_range.max_kbps) - vars[i].pbn; 563 bpp_increased[i] = false; 564 remaining_to_increase += 1; 565 } else { 566 initial_slack[i] = 0; 567 bpp_increased[i] = true; 568 } 569 } 570 571 while (remaining_to_increase) { 572 next_index = -1; 573 min_initial_slack = -1; 574 for (i = 0; i < count; i++) { 575 if (!bpp_increased[i]) { 576 if (min_initial_slack == -1 || min_initial_slack > initial_slack[i]) { 577 min_initial_slack = initial_slack[i]; 578 next_index = i; 579 } 580 } 581 } 582 583 if (next_index == -1) 584 break; 585 586 link_timeslots_used = 0; 587 588 for (i = 0; i < count; i++) 589 link_timeslots_used += DIV_ROUND_UP(vars[i].pbn, pbn_per_timeslot); 590 591 fair_pbn_alloc = (63 - link_timeslots_used) / remaining_to_increase * pbn_per_timeslot; 592 593 if (initial_slack[next_index] > fair_pbn_alloc) { 594 vars[next_index].pbn += fair_pbn_alloc; 595 if (drm_dp_atomic_find_vcpi_slots(state, 596 params[next_index].port->mgr, 597 params[next_index].port, 598 vars[next_index].pbn, 599 pbn_per_timeslot) < 0) 600 return; 601 if (!drm_dp_mst_atomic_check(state)) { 602 vars[next_index].bpp_x16 = bpp_x16_from_pbn(params[next_index], vars[next_index].pbn); 603 } else { 604 vars[next_index].pbn -= fair_pbn_alloc; 605 if (drm_dp_atomic_find_vcpi_slots(state, 606 params[next_index].port->mgr, 607 params[next_index].port, 608 vars[next_index].pbn, 609 pbn_per_timeslot) < 0) 610 return; 611 } 612 } else { 613 vars[next_index].pbn += initial_slack[next_index]; 614 if (drm_dp_atomic_find_vcpi_slots(state, 615 params[next_index].port->mgr, 616 params[next_index].port, 617 vars[next_index].pbn, 618 pbn_per_timeslot) < 0) 619 return; 620 if (!drm_dp_mst_atomic_check(state)) { 621 vars[next_index].bpp_x16 = params[next_index].bw_range.max_target_bpp_x16; 622 } else { 623 vars[next_index].pbn -= initial_slack[next_index]; 624 if (drm_dp_atomic_find_vcpi_slots(state, 625 params[next_index].port->mgr, 626 params[next_index].port, 627 vars[next_index].pbn, 628 pbn_per_timeslot) < 0) 629 return; 630 } 631 } 632 633 bpp_increased[next_index] = true; 634 remaining_to_increase--; 635 } 636 } 637 638 static void try_disable_dsc(struct drm_atomic_state *state, 639 struct dc_link *dc_link, 640 struct dsc_mst_fairness_params *params, 641 struct dsc_mst_fairness_vars *vars, 642 int count) 643 { 644 int i; 645 bool tried[MAX_PIPES]; 646 int kbps_increase[MAX_PIPES]; 647 int max_kbps_increase; 648 int next_index; 649 int remaining_to_try = 0; 650 651 for (i = 0; i < count; i++) { 652 if (vars[i].dsc_enabled 653 && vars[i].bpp_x16 == params[i].bw_range.max_target_bpp_x16 654 && params[i].clock_force_enable == DSC_CLK_FORCE_DEFAULT) { 655 kbps_increase[i] = params[i].bw_range.stream_kbps - params[i].bw_range.max_kbps; 656 tried[i] = false; 657 remaining_to_try += 1; 658 } else { 659 kbps_increase[i] = 0; 660 tried[i] = true; 661 } 662 } 663 664 while (remaining_to_try) { 665 next_index = -1; 666 max_kbps_increase = -1; 667 for (i = 0; i < count; i++) { 668 if (!tried[i]) { 669 if (max_kbps_increase == -1 || max_kbps_increase < kbps_increase[i]) { 670 max_kbps_increase = kbps_increase[i]; 671 next_index = i; 672 } 673 } 674 } 675 676 if (next_index == -1) 677 break; 678 679 vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.stream_kbps); 680 if (drm_dp_atomic_find_vcpi_slots(state, 681 params[next_index].port->mgr, 682 params[next_index].port, 683 vars[next_index].pbn, 684 dm_mst_get_pbn_divider(dc_link)) < 0) 685 return; 686 687 if (!drm_dp_mst_atomic_check(state)) { 688 vars[next_index].dsc_enabled = false; 689 vars[next_index].bpp_x16 = 0; 690 } else { 691 vars[next_index].pbn = kbps_to_peak_pbn(params[next_index].bw_range.max_kbps); 692 if (drm_dp_atomic_find_vcpi_slots(state, 693 params[next_index].port->mgr, 694 params[next_index].port, 695 vars[next_index].pbn, 696 dm_mst_get_pbn_divider(dc_link)) < 0) 697 return; 698 } 699 700 tried[next_index] = true; 701 remaining_to_try--; 702 } 703 } 704 705 static bool compute_mst_dsc_configs_for_link(struct drm_atomic_state *state, 706 struct dc_state *dc_state, 707 struct dc_link *dc_link) 708 { 709 int i; 710 struct dc_stream_state *stream; 711 struct dsc_mst_fairness_params params[MAX_PIPES]; 712 struct dsc_mst_fairness_vars vars[MAX_PIPES]; 713 struct amdgpu_dm_connector *aconnector; 714 int count = 0; 715 bool debugfs_overwrite = false; 716 717 memset(params, 0, sizeof(params)); 718 719 /* Set up params */ 720 for (i = 0; i < dc_state->stream_count; i++) { 721 struct dc_dsc_policy dsc_policy = {0}; 722 723 stream = dc_state->streams[i]; 724 725 if (stream->link != dc_link) 726 continue; 727 728 stream->timing.flags.DSC = 0; 729 730 params[count].timing = &stream->timing; 731 params[count].sink = stream->sink; 732 aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; 733 params[count].port = aconnector->port; 734 params[count].clock_force_enable = aconnector->dsc_settings.dsc_force_enable; 735 if (params[count].clock_force_enable == DSC_CLK_FORCE_ENABLE) 736 debugfs_overwrite = true; 737 params[count].num_slices_h = aconnector->dsc_settings.dsc_num_slices_h; 738 params[count].num_slices_v = aconnector->dsc_settings.dsc_num_slices_v; 739 params[count].bpp_overwrite = aconnector->dsc_settings.dsc_bits_per_pixel; 740 params[count].compression_possible = stream->sink->dsc_caps.dsc_dec_caps.is_dsc_supported; 741 dc_dsc_get_policy_for_timing(params[count].timing, 0, &dsc_policy); 742 if (!dc_dsc_compute_bandwidth_range( 743 stream->sink->ctx->dc->res_pool->dscs[0], 744 stream->sink->ctx->dc->debug.dsc_min_slice_height_override, 745 dsc_policy.min_target_bpp, 746 dsc_policy.max_target_bpp, 747 &stream->sink->dsc_caps.dsc_dec_caps, 748 &stream->timing, ¶ms[count].bw_range)) 749 params[count].bw_range.stream_kbps = dc_bandwidth_in_kbps_from_timing(&stream->timing); 750 751 count++; 752 } 753 /* Try no compression */ 754 for (i = 0; i < count; i++) { 755 vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); 756 vars[i].dsc_enabled = false; 757 vars[i].bpp_x16 = 0; 758 if (drm_dp_atomic_find_vcpi_slots(state, 759 params[i].port->mgr, 760 params[i].port, 761 vars[i].pbn, 762 dm_mst_get_pbn_divider(dc_link)) < 0) 763 return false; 764 } 765 if (!drm_dp_mst_atomic_check(state) && !debugfs_overwrite) { 766 set_dsc_configs_from_fairness_vars(params, vars, count); 767 return true; 768 } 769 770 /* Try max compression */ 771 for (i = 0; i < count; i++) { 772 if (params[i].compression_possible && params[i].clock_force_enable != DSC_CLK_FORCE_DISABLE) { 773 vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.min_kbps); 774 vars[i].dsc_enabled = true; 775 vars[i].bpp_x16 = params[i].bw_range.min_target_bpp_x16; 776 if (drm_dp_atomic_find_vcpi_slots(state, 777 params[i].port->mgr, 778 params[i].port, 779 vars[i].pbn, 780 dm_mst_get_pbn_divider(dc_link)) < 0) 781 return false; 782 } else { 783 vars[i].pbn = kbps_to_peak_pbn(params[i].bw_range.stream_kbps); 784 vars[i].dsc_enabled = false; 785 vars[i].bpp_x16 = 0; 786 if (drm_dp_atomic_find_vcpi_slots(state, 787 params[i].port->mgr, 788 params[i].port, 789 vars[i].pbn, 790 dm_mst_get_pbn_divider(dc_link)) < 0) 791 return false; 792 } 793 } 794 if (drm_dp_mst_atomic_check(state)) 795 return false; 796 797 /* Optimize degree of compression */ 798 increase_dsc_bpp(state, dc_link, params, vars, count); 799 800 try_disable_dsc(state, dc_link, params, vars, count); 801 802 set_dsc_configs_from_fairness_vars(params, vars, count); 803 804 return true; 805 } 806 807 bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state, 808 struct dc_state *dc_state) 809 { 810 int i, j; 811 struct dc_stream_state *stream; 812 bool computed_streams[MAX_PIPES]; 813 struct amdgpu_dm_connector *aconnector; 814 815 for (i = 0; i < dc_state->stream_count; i++) 816 computed_streams[i] = false; 817 818 for (i = 0; i < dc_state->stream_count; i++) { 819 stream = dc_state->streams[i]; 820 821 if (stream->signal != SIGNAL_TYPE_DISPLAY_PORT_MST) 822 continue; 823 824 aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context; 825 826 if (!aconnector || !aconnector->dc_sink) 827 continue; 828 829 if (!aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported) 830 continue; 831 832 if (computed_streams[i]) 833 continue; 834 835 if (dcn20_remove_stream_from_ctx(stream->ctx->dc, dc_state, stream) != DC_OK) 836 return false; 837 838 mutex_lock(&aconnector->mst_mgr.lock); 839 if (!compute_mst_dsc_configs_for_link(state, dc_state, stream->link)) { 840 mutex_unlock(&aconnector->mst_mgr.lock); 841 return false; 842 } 843 mutex_unlock(&aconnector->mst_mgr.lock); 844 845 for (j = 0; j < dc_state->stream_count; j++) { 846 if (dc_state->streams[j]->link == stream->link) 847 computed_streams[j] = true; 848 } 849 } 850 851 for (i = 0; i < dc_state->stream_count; i++) { 852 stream = dc_state->streams[i]; 853 854 if (stream->timing.flags.DSC == 1) 855 if (dc_stream_add_dsc_to_resource(stream->ctx->dc, dc_state, stream) != DC_OK) 856 return false; 857 } 858 859 return true; 860 } 861 862 #endif 863