Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/hch/vfs...
[pandora-kernel.git] / drivers / gpu / drm / nouveau / nv50_sor.c
index ffe8b48..2633aa8 100644 (file)
@@ -124,7 +124,7 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode)
                if (mode == DRM_MODE_DPMS_ON) {
                        u8 status = DP_SET_POWER_D0;
                        nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1);
-                       nouveau_dp_link_train(encoder);
+                       nouveau_dp_link_train(encoder, nv_encoder->dp.datarate);
                } else {
                        u8 status = DP_SET_POWER_D3;
                        nouveau_dp_auxch(auxch, 8, DP_SET_POWER, &status, 1);
@@ -187,14 +187,13 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
        struct drm_device *dev = encoder->dev;
        struct nouveau_crtc *crtc = nouveau_crtc(encoder->crtc);
+       struct nouveau_connector *nv_connector;
        uint32_t mode_ctl = 0;
        int ret;
 
        NV_DEBUG_KMS(dev, "or %d type %d -> crtc %d\n",
                     nv_encoder->or, nv_encoder->dcb->type, crtc->index);
 
-       nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON);
-
        switch (nv_encoder->dcb->type) {
        case OUTPUT_TMDS:
                if (nv_encoder->dcb->sorconf.link & 1) {
@@ -206,7 +205,15 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
                        mode_ctl = 0x0200;
                break;
        case OUTPUT_DP:
-               mode_ctl |= (nv_encoder->dp.mc_unknown << 16);
+               nv_connector = nouveau_encoder_connector_get(nv_encoder);
+               if (nv_connector && nv_connector->base.display_info.bpc == 6) {
+                       nv_encoder->dp.datarate = crtc->mode->clock * 18 / 8;
+                       mode_ctl |= 0x00020000;
+               } else {
+                       nv_encoder->dp.datarate = crtc->mode->clock * 24 / 8;
+                       mode_ctl |= 0x00050000;
+               }
+
                if (nv_encoder->dcb->sorconf.link & 1)
                        mode_ctl |= 0x00000800;
                else
@@ -227,6 +234,8 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
        if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
                mode_ctl |= NV50_EVO_SOR_MODE_CTRL_NVSYNC;
 
+       nv50_sor_dpms(encoder, DRM_MODE_DPMS_ON);
+
        ret = RING_SPACE(evo, 2);
        if (ret) {
                NV_ERROR(dev, "no space while connecting SOR\n");
@@ -313,31 +322,6 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry)
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
 
-       if (nv_encoder->dcb->type == OUTPUT_DP) {
-               int or = nv_encoder->or, link = !(entry->dpconf.sor.link & 1);
-               uint32_t tmp;
-
-               tmp = nv_rd32(dev, 0x61c700 + (or * 0x800));
-               if (!tmp)
-                       tmp = nv_rd32(dev, 0x610798 + (or * 8));
-
-               switch ((tmp & 0x00000f00) >> 8) {
-               case 8:
-               case 9:
-                       nv_encoder->dp.mc_unknown = (tmp & 0x000f0000) >> 16;
-                       tmp = nv_rd32(dev, NV50_SOR_DP_CTRL(or, link));
-                       nv_encoder->dp.unk0 = tmp & 0x000001fc;
-                       tmp = nv_rd32(dev, NV50_SOR_DP_UNK128(or, link));
-                       nv_encoder->dp.unk1 = tmp & 0x010f7f3f;
-                       break;
-               default:
-                       break;
-               }
-
-               if (!nv_encoder->dp.mc_unknown)
-                       nv_encoder->dp.mc_unknown = 5;
-       }
-
        drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }