summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_sor.c22
2 files changed, 22 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index bc4a240..9f28b94 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -47,6 +47,7 @@ struct nouveau_encoder {
union {
struct {
+ int mc_unknown;
int dpcd_version;
int link_nr;
int link_bw;
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
index c2fff54..e31ba31 100644
--- a/drivers/gpu/drm/nouveau/nv50_sor.c
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -211,7 +211,7 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
mode_ctl = 0x0200;
break;
case OUTPUT_DP:
- mode_ctl |= 0x00050000;
+ mode_ctl |= (nv_encoder->dp.mc_unknown << 16);
if (nv_encoder->dcb->sorconf.link & 1)
mode_ctl |= 0x00000800;
else
@@ -274,6 +274,7 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
int
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 drm_encoder *encoder;
bool dum;
@@ -319,5 +320,24 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
encoder->possible_crtcs = entry->heads;
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;
}