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