diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_connector.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_connector.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 266b0ff441af..149ed224c3cb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -432,24 +432,27 @@ nouveau_connector_set_property(struct drm_connector *connector, | |||
432 | } | 432 | } |
433 | 433 | ||
434 | static struct drm_display_mode * | 434 | static struct drm_display_mode * |
435 | nouveau_connector_native_mode(struct nouveau_connector *connector) | 435 | nouveau_connector_native_mode(struct drm_connector *connector) |
436 | { | 436 | { |
437 | struct drm_device *dev = connector->base.dev; | 437 | struct drm_connector_helper_funcs *helper = connector->helper_private; |
438 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | ||
439 | struct drm_device *dev = connector->dev; | ||
438 | struct drm_display_mode *mode, *largest = NULL; | 440 | struct drm_display_mode *mode, *largest = NULL; |
439 | int high_w = 0, high_h = 0, high_v = 0; | 441 | int high_w = 0, high_h = 0, high_v = 0; |
440 | 442 | ||
441 | /* Use preferred mode if there is one.. */ | 443 | list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { |
442 | list_for_each_entry(mode, &connector->base.probed_modes, head) { | 444 | if (helper->mode_valid(connector, mode) != MODE_OK) |
445 | continue; | ||
446 | |||
447 | /* Use preferred mode if there is one.. */ | ||
443 | if (mode->type & DRM_MODE_TYPE_PREFERRED) { | 448 | if (mode->type & DRM_MODE_TYPE_PREFERRED) { |
444 | NV_DEBUG_KMS(dev, "native mode from preferred\n"); | 449 | NV_DEBUG_KMS(dev, "native mode from preferred\n"); |
445 | return drm_mode_duplicate(dev, mode); | 450 | return drm_mode_duplicate(dev, mode); |
446 | } | 451 | } |
447 | } | ||
448 | 452 | ||
449 | /* Otherwise, take the resolution with the largest width, then height, | 453 | /* Otherwise, take the resolution with the largest width, then |
450 | * then vertical refresh | 454 | * height, then vertical refresh |
451 | */ | 455 | */ |
452 | list_for_each_entry(mode, &connector->base.probed_modes, head) { | ||
453 | if (mode->hdisplay < high_w) | 456 | if (mode->hdisplay < high_w) |
454 | continue; | 457 | continue; |
455 | 458 | ||
@@ -553,7 +556,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) | |||
553 | */ | 556 | */ |
554 | if (!nv_connector->native_mode) | 557 | if (!nv_connector->native_mode) |
555 | nv_connector->native_mode = | 558 | nv_connector->native_mode = |
556 | nouveau_connector_native_mode(nv_connector); | 559 | nouveau_connector_native_mode(connector); |
557 | if (ret == 0 && nv_connector->native_mode) { | 560 | if (ret == 0 && nv_connector->native_mode) { |
558 | struct drm_display_mode *mode; | 561 | struct drm_display_mode *mode; |
559 | 562 | ||
@@ -584,9 +587,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector, | |||
584 | 587 | ||
585 | switch (nv_encoder->dcb->type) { | 588 | switch (nv_encoder->dcb->type) { |
586 | case OUTPUT_LVDS: | 589 | case OUTPUT_LVDS: |
587 | BUG_ON(!nv_connector->native_mode); | 590 | if (nv_connector->native_mode && |
588 | if (mode->hdisplay > nv_connector->native_mode->hdisplay || | 591 | (mode->hdisplay > nv_connector->native_mode->hdisplay || |
589 | mode->vdisplay > nv_connector->native_mode->vdisplay) | 592 | mode->vdisplay > nv_connector->native_mode->vdisplay)) |
590 | return MODE_PANEL; | 593 | return MODE_PANEL; |
591 | 594 | ||
592 | min_clock = 0; | 595 | min_clock = 0; |
@@ -594,8 +597,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector, | |||
594 | break; | 597 | break; |
595 | case OUTPUT_TMDS: | 598 | case OUTPUT_TMDS: |
596 | if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) || | 599 | if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) || |
597 | (dev_priv->card_type < NV_50 && | 600 | !nv_encoder->dcb->duallink_possible) |
598 | !nv_encoder->dcb->duallink_possible)) | ||
599 | max_clock = 165000; | 601 | max_clock = 165000; |
600 | else | 602 | else |
601 | max_clock = 330000; | 603 | max_clock = 330000; |
@@ -729,7 +731,7 @@ nouveau_connector_create_lvds(struct drm_device *dev, | |||
729 | if (ret == 0) | 731 | if (ret == 0) |
730 | goto out; | 732 | goto out; |
731 | nv_connector->detected_encoder = nv_encoder; | 733 | nv_connector->detected_encoder = nv_encoder; |
732 | nv_connector->native_mode = nouveau_connector_native_mode(nv_connector); | 734 | nv_connector->native_mode = nouveau_connector_native_mode(connector); |
733 | list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) | 735 | list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) |
734 | drm_mode_remove(connector, mode); | 736 | drm_mode_remove(connector, mode); |
735 | 737 | ||