Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: fix dp link rate selection (v2)

Need to properly handle the max link rate in the dpcd.
This prevents some cases where 5.4 Ghz is selected when
it shouldn't be.

v2: simplify logic, add array bounds check

Reviewed-by: Tom St Denis <tom.stdenis@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

+48 -76
+35 -71
drivers/gpu/drm/radeon/atombios_dp.c
··· 302 302 return bpc * 3; 303 303 } 304 304 305 - /* get the max pix clock supported by the link rate and lane num */ 306 - static int dp_get_max_dp_pix_clock(int link_rate, 307 - int lane_num, 308 - int bpp) 309 - { 310 - return (link_rate * lane_num * 8) / bpp; 311 - } 312 - 313 305 /***** radeon specific DP functions *****/ 314 306 315 - int radeon_dp_get_max_link_rate(struct drm_connector *connector, 316 - const u8 dpcd[DP_DPCD_SIZE]) 317 - { 318 - int max_link_rate; 319 - 320 - if (radeon_connector_is_dp12_capable(connector)) 321 - max_link_rate = min(drm_dp_max_link_rate(dpcd), 540000); 322 - else 323 - max_link_rate = min(drm_dp_max_link_rate(dpcd), 270000); 324 - 325 - return max_link_rate; 326 - } 327 - 328 - /* First get the min lane# when low rate is used according to pixel clock 329 - * (prefer low rate), second check max lane# supported by DP panel, 330 - * if the max lane# < low rate lane# then use max lane# instead. 331 - */ 332 - static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, 333 - const u8 dpcd[DP_DPCD_SIZE], 334 - int pix_clock) 307 + int radeon_dp_get_dp_link_config(struct drm_connector *connector, 308 + const u8 dpcd[DP_DPCD_SIZE], 309 + unsigned pix_clock, 310 + unsigned *dp_lanes, unsigned *dp_rate) 335 311 { 336 312 int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); 337 - int max_link_rate = radeon_dp_get_max_link_rate(connector, dpcd); 338 - int max_lane_num = drm_dp_max_lane_count(dpcd); 339 - int lane_num; 340 - int max_dp_pix_clock; 313 + static const unsigned link_rates[3] = { 162000, 270000, 540000 }; 314 + unsigned max_link_rate = drm_dp_max_link_rate(dpcd); 315 + unsigned max_lane_num = drm_dp_max_lane_count(dpcd); 316 + unsigned lane_num, i, max_pix_clock; 341 317 342 - for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) { 343 - max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp); 344 - if (pix_clock <= max_dp_pix_clock) 345 - break; 318 + for (lane_num = 1; lane_num <= max_lane_num; lane_num <<= 1) { 319 + for (i = 0; i < ARRAY_SIZE(link_rates) && link_rates[i] <= max_link_rate; i++) { 320 + max_pix_clock = (lane_num * link_rates[i] * 8) / bpp; 321 + if (max_pix_clock >= pix_clock) { 322 + *dp_lanes = lane_num; 323 + *dp_rate = link_rates[i]; 324 + return 0; 325 + } 326 + } 346 327 } 347 328 348 - return lane_num; 349 - } 350 - 351 - static int radeon_dp_get_dp_link_clock(struct drm_connector *connector, 352 - const u8 dpcd[DP_DPCD_SIZE], 353 - int pix_clock) 354 - { 355 - int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); 356 - int lane_num, max_pix_clock; 357 - 358 - if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) == 359 - ENCODER_OBJECT_ID_NUTMEG) 360 - return 270000; 361 - 362 - lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock); 363 - max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp); 364 - if (pix_clock <= max_pix_clock) 365 - return 162000; 366 - max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp); 367 - if (pix_clock <= max_pix_clock) 368 - return 270000; 369 - if (radeon_connector_is_dp12_capable(connector)) { 370 - max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp); 371 - if (pix_clock <= max_pix_clock) 372 - return 540000; 373 - } 374 - 375 - return radeon_dp_get_max_link_rate(connector, dpcd); 329 + return -EINVAL; 376 330 } 377 331 378 332 static u8 radeon_dp_encoder_service(struct radeon_device *rdev, ··· 445 491 { 446 492 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 447 493 struct radeon_connector_atom_dig *dig_connector; 494 + int ret; 448 495 449 496 if (!radeon_connector->con_priv) 450 497 return; ··· 453 498 454 499 if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 455 500 (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { 456 - dig_connector->dp_clock = 457 - radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); 458 - dig_connector->dp_lane_count = 459 - radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock); 501 + ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd, 502 + mode->clock, 503 + &dig_connector->dp_lane_count, 504 + &dig_connector->dp_clock); 505 + if (ret) { 506 + dig_connector->dp_clock = 0; 507 + dig_connector->dp_lane_count = 0; 508 + } 460 509 } 461 510 } 462 511 ··· 469 510 { 470 511 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 471 512 struct radeon_connector_atom_dig *dig_connector; 472 - int dp_clock; 513 + unsigned dp_clock, dp_lanes; 514 + int ret; 473 515 474 516 if ((mode->clock > 340000) && 475 517 (!radeon_connector_is_dp12_capable(connector))) ··· 480 520 return MODE_CLOCK_HIGH; 481 521 dig_connector = radeon_connector->con_priv; 482 522 483 - dp_clock = 484 - radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); 523 + ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd, 524 + mode->clock, 525 + &dp_lanes, 526 + &dp_clock); 527 + if (ret) 528 + return MODE_CLOCK_HIGH; 485 529 486 530 if ((dp_clock == 540000) && 487 531 (!radeon_connector_is_dp12_capable(connector)))
+9 -3
drivers/gpu/drm/radeon/radeon_dp_mst.c
··· 525 525 drm_mode_set_crtcinfo(adjusted_mode, 0); 526 526 { 527 527 struct radeon_connector_atom_dig *dig_connector; 528 + int ret; 528 529 529 530 dig_connector = mst_enc->connector->con_priv; 530 - dig_connector->dp_lane_count = drm_dp_max_lane_count(dig_connector->dpcd); 531 - dig_connector->dp_clock = radeon_dp_get_max_link_rate(&mst_enc->connector->base, 532 - dig_connector->dpcd); 531 + ret = radeon_dp_get_dp_link_config(&mst_enc->connector->base, 532 + dig_connector->dpcd, adjusted_mode->clock, 533 + &dig_connector->dp_lane_count, 534 + &dig_connector->dp_clock); 535 + if (ret) { 536 + dig_connector->dp_lane_count = 0; 537 + dig_connector->dp_clock = 0; 538 + } 533 539 DRM_DEBUG_KMS("dig clock %p %d %d\n", dig_connector, 534 540 dig_connector->dp_lane_count, dig_connector->dp_clock); 535 541 }
+4 -2
drivers/gpu/drm/radeon/radeon_mode.h
··· 756 756 extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector); 757 757 extern int radeon_dp_get_panel_mode(struct drm_encoder *encoder, 758 758 struct drm_connector *connector); 759 - int radeon_dp_get_max_link_rate(struct drm_connector *connector, 760 - const u8 *dpcd); 759 + extern int radeon_dp_get_dp_link_config(struct drm_connector *connector, 760 + const u8 *dpcd, 761 + unsigned pix_clock, 762 + unsigned *dp_lanes, unsigned *dp_rate); 761 763 extern void radeon_dp_set_rx_power_state(struct drm_connector *connector, 762 764 u8 power_state); 763 765 extern void radeon_dp_aux_init(struct radeon_connector *radeon_connector);