提交 6f335a7a 编写于 作者: B Ben Skeggs

drm/nv50: preserve an unknown SOR_MODECTRL value for DP encoders

This value interacts with some registers we don't currently know how to
program properly ourselves.  The default of 5 that we were using matches
what the VBIOS on early DP cards do, but later ones use 6, which would
cause nouveau to program an incorrect mode on these chips.
Signed-off-by: NBen Skeggs <bskeggs@redhat.com>
上级 d327dd4e
...@@ -47,6 +47,7 @@ struct nouveau_encoder { ...@@ -47,6 +47,7 @@ struct nouveau_encoder {
union { union {
struct { struct {
int mc_unknown;
int dpcd_version; int dpcd_version;
int link_nr; int link_nr;
int link_bw; int link_bw;
......
...@@ -211,7 +211,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, ...@@ -211,7 +211,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
mode_ctl = 0x0200; mode_ctl = 0x0200;
break; break;
case OUTPUT_DP: case OUTPUT_DP:
mode_ctl |= 0x00050000; mode_ctl |= (nv_encoder->dp.mc_unknown << 16);
if (nv_encoder->dcb->sorconf.link & 1) if (nv_encoder->dcb->sorconf.link & 1)
mode_ctl |= 0x00000800; mode_ctl |= 0x00000800;
else else
...@@ -274,6 +274,7 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = { ...@@ -274,6 +274,7 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
int int
nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_encoder *nv_encoder = NULL; struct nouveau_encoder *nv_encoder = NULL;
struct drm_encoder *encoder; struct drm_encoder *encoder;
bool dum; bool dum;
...@@ -319,5 +320,24 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) ...@@ -319,5 +320,24 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
encoder->possible_crtcs = entry->heads; encoder->possible_crtcs = entry->heads;
encoder->possible_clones = 0; encoder->possible_clones = 0;
if (nv_encoder->dcb->type == OUTPUT_DP) {
uint32_t mc, or = nv_encoder->or;
if (dev_priv->chipset < 0x90 ||
dev_priv->chipset == 0x92 || dev_priv->chipset == 0xa0)
mc = nv_rd32(dev, NV50_PDISPLAY_SOR_MODE_CTRL_C(or));
else
mc = nv_rd32(dev, NV90_PDISPLAY_SOR_MODE_CTRL_C(or));
switch ((mc & 0x00000f00) >> 8) {
case 8:
case 9:
nv_encoder->dp.mc_unknown = (mc & 0x000f0000) >> 16;
break;
default:
break;
}
}
return 0; return 0;
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册