Commit 26099a74 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau: fix dual-link displays when plugged into single-link outputs

When selecting the native mode for a display we weren't taking into account
whether or not it was actually supported on that particular output.

This patch modifies our native mode selection to run all modes through
mode_valid() first.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 2c580775
...@@ -431,24 +431,27 @@ nouveau_connector_set_property(struct drm_connector *connector, ...@@ -431,24 +431,27 @@ nouveau_connector_set_property(struct drm_connector *connector,
} }
static struct drm_display_mode * static struct drm_display_mode *
nouveau_connector_native_mode(struct nouveau_connector *connector) nouveau_connector_native_mode(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->base.dev; struct drm_connector_helper_funcs *helper = connector->helper_private;
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *largest = NULL; struct drm_display_mode *mode, *largest = NULL;
int high_w = 0, high_h = 0, high_v = 0; int high_w = 0, high_h = 0, high_v = 0;
list_for_each_entry(mode, &nv_connector->base.probed_modes, head) {
if (helper->mode_valid(connector, mode) != MODE_OK)
continue;
/* Use preferred mode if there is one.. */ /* Use preferred mode if there is one.. */
list_for_each_entry(mode, &connector->base.probed_modes, head) {
if (mode->type & DRM_MODE_TYPE_PREFERRED) { if (mode->type & DRM_MODE_TYPE_PREFERRED) {
NV_DEBUG_KMS(dev, "native mode from preferred\n"); NV_DEBUG_KMS(dev, "native mode from preferred\n");
return drm_mode_duplicate(dev, mode); return drm_mode_duplicate(dev, mode);
} }
}
/* Otherwise, take the resolution with the largest width, then height, /* Otherwise, take the resolution with the largest width, then
* then vertical refresh * height, then vertical refresh
*/ */
list_for_each_entry(mode, &connector->base.probed_modes, head) {
if (mode->hdisplay < high_w) if (mode->hdisplay < high_w)
continue; continue;
...@@ -552,7 +555,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) ...@@ -552,7 +555,7 @@ nouveau_connector_get_modes(struct drm_connector *connector)
*/ */
if (!nv_connector->native_mode) if (!nv_connector->native_mode)
nv_connector->native_mode = nv_connector->native_mode =
nouveau_connector_native_mode(nv_connector); nouveau_connector_native_mode(connector);
if (ret == 0 && nv_connector->native_mode) { if (ret == 0 && nv_connector->native_mode) {
struct drm_display_mode *mode; struct drm_display_mode *mode;
...@@ -583,9 +586,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector, ...@@ -583,9 +586,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
switch (nv_encoder->dcb->type) { switch (nv_encoder->dcb->type) {
case OUTPUT_LVDS: case OUTPUT_LVDS:
BUG_ON(!nv_connector->native_mode); if (nv_connector->native_mode &&
if (mode->hdisplay > nv_connector->native_mode->hdisplay || (mode->hdisplay > nv_connector->native_mode->hdisplay ||
mode->vdisplay > nv_connector->native_mode->vdisplay) mode->vdisplay > nv_connector->native_mode->vdisplay))
return MODE_PANEL; return MODE_PANEL;
min_clock = 0; min_clock = 0;
...@@ -727,7 +730,7 @@ nouveau_connector_create_lvds(struct drm_device *dev, ...@@ -727,7 +730,7 @@ nouveau_connector_create_lvds(struct drm_device *dev,
if (ret == 0) if (ret == 0)
goto out; goto out;
nv_connector->detected_encoder = nv_encoder; nv_connector->detected_encoder = nv_encoder;
nv_connector->native_mode = nouveau_connector_native_mode(nv_connector); nv_connector->native_mode = nouveau_connector_native_mode(connector);
list_for_each_entry_safe(mode, temp, &connector->probed_modes, head) list_for_each_entry_safe(mode, temp, &connector->probed_modes, head)
drm_mode_remove(connector, mode); drm_mode_remove(connector, mode);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment