drm/nouveau: Reject modes exceeding the integrated TMDS maximum bandwidth.
Reported-by: Grzesiek Sójka <pld@pfu.pl> Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
committed by
Ben Skeggs
parent
907af60b93
commit
1f5bd44354
@@ -641,11 +641,28 @@ nouveau_connector_get_modes(struct drm_connector *connector)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
get_tmds_link_bandwidth(struct drm_connector *connector)
|
||||||
|
{
|
||||||
|
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||||
|
struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
|
||||||
|
struct dcb_entry *dcb = nv_connector->detected_encoder->dcb;
|
||||||
|
|
||||||
|
if (dcb->location != DCB_LOC_ON_CHIP ||
|
||||||
|
dev_priv->chipset >= 0x46)
|
||||||
|
return 165000;
|
||||||
|
else if (dev_priv->chipset >= 0x40)
|
||||||
|
return 155000;
|
||||||
|
else if (dev_priv->chipset >= 0x18)
|
||||||
|
return 135000;
|
||||||
|
else
|
||||||
|
return 112000;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nouveau_connector_mode_valid(struct drm_connector *connector,
|
nouveau_connector_mode_valid(struct drm_connector *connector,
|
||||||
struct drm_display_mode *mode)
|
struct drm_display_mode *mode)
|
||||||
{
|
{
|
||||||
struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
|
|
||||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||||
struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
|
struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder;
|
||||||
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
|
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
|
||||||
@@ -663,11 +680,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
|
|||||||
max_clock = 400000;
|
max_clock = 400000;
|
||||||
break;
|
break;
|
||||||
case OUTPUT_TMDS:
|
case OUTPUT_TMDS:
|
||||||
if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) ||
|
max_clock = get_tmds_link_bandwidth(connector);
|
||||||
!nv_encoder->dcb->duallink_possible)
|
if (nouveau_duallink && nv_encoder->dcb->duallink_possible)
|
||||||
max_clock = 165000;
|
max_clock *= 2;
|
||||||
else
|
|
||||||
max_clock = 330000;
|
|
||||||
break;
|
break;
|
||||||
case OUTPUT_ANALOG:
|
case OUTPUT_ANALOG:
|
||||||
max_clock = nv_encoder->dcb->crtconf.maxfreq;
|
max_clock = nv_encoder->dcb->crtconf.maxfreq;
|
||||||
|
Reference in New Issue
Block a user