Rev 6104 | Rev 6938 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6104 | Rev 6661 | ||
---|---|---|---|
Line 300... | Line 300... | ||
300 | return 24; |
300 | return 24; |
301 | else |
301 | else |
302 | return bpc * 3; |
302 | return bpc * 3; |
303 | } |
303 | } |
Line 304... | Line -... | ||
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 | 304 | ||
Line 313... | Line 305... | ||
313 | /***** radeon specific DP functions *****/ |
305 | /***** radeon specific DP functions *****/ |
314 | - | ||
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 | */ |
306 | |
332 | static int radeon_dp_get_dp_lane_number(struct drm_connector *connector, |
307 | int radeon_dp_get_dp_link_config(struct drm_connector *connector, |
- | 308 | const u8 dpcd[DP_DPCD_SIZE], |
|
333 | const u8 dpcd[DP_DPCD_SIZE], |
309 | unsigned pix_clock, |
334 | int pix_clock) |
310 | unsigned *dp_lanes, unsigned *dp_rate) |
- | 311 | { |
|
335 | { |
312 | int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); |
336 | int bpp = convert_bpc_to_bpp(radeon_get_monitor_bpc(connector)); |
313 | static const unsigned link_rates[3] = { 162000, 270000, 540000 }; |
337 | int max_link_rate = radeon_dp_get_max_link_rate(connector, dpcd); |
- | |
338 | int max_lane_num = drm_dp_max_lane_count(dpcd); |
314 | unsigned max_link_rate = drm_dp_max_link_rate(dpcd); |
Line 339... | Line 315... | ||
339 | int lane_num; |
315 | unsigned max_lane_num = drm_dp_max_lane_count(dpcd); |
- | 316 | unsigned lane_num, i, max_pix_clock; |
|
340 | int max_dp_pix_clock; |
317 | |
341 | 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; |
|
342 | for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) { |
321 | if (max_pix_clock >= pix_clock) { |
343 | max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp); |
322 | *dp_lanes = lane_num; |
344 | if (pix_clock <= max_dp_pix_clock) |
- | |
345 | break; |
- | |
346 | } |
323 | *dp_rate = link_rates[i]; |
347 | - | ||
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); |
324 | return 0; |
Line 371... | Line 325... | ||
371 | if (pix_clock <= max_pix_clock) |
325 | } |
372 | return 540000; |
326 | } |
Line 373... | Line 327... | ||
373 | } |
327 | } |
374 | 328 | ||
375 | return radeon_dp_get_max_link_rate(connector, dpcd); |
329 | return -EINVAL; |
Line 489... | Line 443... | ||
489 | void radeon_dp_set_link_config(struct drm_connector *connector, |
443 | void radeon_dp_set_link_config(struct drm_connector *connector, |
490 | const struct drm_display_mode *mode) |
444 | const struct drm_display_mode *mode) |
491 | { |
445 | { |
492 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
446 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
493 | struct radeon_connector_atom_dig *dig_connector; |
447 | struct radeon_connector_atom_dig *dig_connector; |
- | 448 | int ret; |
|
Line 494... | Line 449... | ||
494 | 449 | ||
495 | if (!radeon_connector->con_priv) |
450 | if (!radeon_connector->con_priv) |
496 | return; |
451 | return; |
Line 497... | Line 452... | ||
497 | dig_connector = radeon_connector->con_priv; |
452 | dig_connector = radeon_connector->con_priv; |
498 | 453 | ||
- | 454 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
|
- | 455 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { |
|
499 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
456 | ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd, |
500 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) { |
457 | mode->clock, |
- | 458 | &dig_connector->dp_lane_count, |
|
501 | dig_connector->dp_clock = |
459 | &dig_connector->dp_clock); |
502 | radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock); |
460 | if (ret) { |
- | 461 | dig_connector->dp_clock = 0; |
|
503 | dig_connector->dp_lane_count = |
462 | dig_connector->dp_lane_count = 0; |
504 | radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock); |
463 | } |
Line 505... | Line 464... | ||
505 | } |
464 | } |
506 | } |
465 | } |
507 | 466 | ||
508 | int radeon_dp_mode_valid_helper(struct drm_connector *connector, |
467 | int radeon_dp_mode_valid_helper(struct drm_connector *connector, |
509 | struct drm_display_mode *mode) |
468 | struct drm_display_mode *mode) |
- | 469 | { |
|
510 | { |
470 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
Line 511... | Line 471... | ||
511 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
471 | struct radeon_connector_atom_dig *dig_connector; |
512 | struct radeon_connector_atom_dig *dig_connector; |
472 | unsigned dp_clock, dp_lanes; |
513 | int dp_clock; |
473 | int ret; |
Line 514... | Line 474... | ||
514 | 474 | ||
515 | if ((mode->clock > 340000) && |
475 | if ((mode->clock > 340000) && |
516 | (!radeon_connector_is_dp12_capable(connector))) |
476 | (!radeon_connector_is_dp12_capable(connector))) |
Line -... | Line 477... | ||
- | 477 | return MODE_CLOCK_HIGH; |
|
- | 478 | ||
- | 479 | if (!radeon_connector->con_priv) |
|
517 | return MODE_CLOCK_HIGH; |
480 | return MODE_CLOCK_HIGH; |
- | 481 | dig_connector = radeon_connector->con_priv; |
|
518 | 482 | ||
Line 519... | Line 483... | ||
519 | if (!radeon_connector->con_priv) |
483 | ret = radeon_dp_get_dp_link_config(connector, dig_connector->dpcd, |
520 | return MODE_CLOCK_HIGH; |
484 | mode->clock, |
521 | dig_connector = radeon_connector->con_priv; |
485 | &dp_lanes, |