}
 
 int
-nouveau_connector_create(struct drm_device *dev, int index, int type)
+nouveau_connector_create(struct drm_device *dev,
+                        struct dcb_connector_table_entry *dcb)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_connector *nv_connector = NULL;
        struct drm_connector *connector;
        struct drm_encoder *encoder;
-       int ret;
+       int ret, type;
 
        NV_DEBUG_KMS(dev, "\n");
 
-       nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
-       if (!nv_connector)
-               return -ENOMEM;
-       nv_connector->dcb = nouveau_bios_connector_entry(dev, index);
-       connector = &nv_connector->base;
-
-       switch (type) {
-       case DRM_MODE_CONNECTOR_VGA:
+       switch (dcb->type) {
+       case DCB_CONNECTOR_NONE:
+               return 0;
+       case DCB_CONNECTOR_VGA:
                NV_INFO(dev, "Detected a VGA connector\n");
+               type = DRM_MODE_CONNECTOR_VGA;
                break;
-       case DRM_MODE_CONNECTOR_DVID:
-               NV_INFO(dev, "Detected a DVI-D connector\n");
+       case DCB_CONNECTOR_TV_0:
+       case DCB_CONNECTOR_TV_1:
+       case DCB_CONNECTOR_TV_3:
+               NV_INFO(dev, "Detected a TV connector\n");
+               type = DRM_MODE_CONNECTOR_TV;
                break;
-       case DRM_MODE_CONNECTOR_DVII:
+       case DCB_CONNECTOR_DVI_I:
                NV_INFO(dev, "Detected a DVI-I connector\n");
+               type = DRM_MODE_CONNECTOR_DVII;
                break;
-       case DRM_MODE_CONNECTOR_LVDS:
-               NV_INFO(dev, "Detected a LVDS connector\n");
+       case DCB_CONNECTOR_DVI_D:
+       case DCB_CONNECTOR_HDMI_0:
+       case DCB_CONNECTOR_HDMI_1:
+               NV_INFO(dev, "Detected a DVI-D connector\n");
+               type = DRM_MODE_CONNECTOR_DVID;
                break;
-       case DRM_MODE_CONNECTOR_TV:
-               NV_INFO(dev, "Detected a TV connector\n");
+       case DCB_CONNECTOR_LVDS:
+               NV_INFO(dev, "Detected a LVDS connector\n");
+               type = DRM_MODE_CONNECTOR_LVDS;
                break;
-       case DRM_MODE_CONNECTOR_DisplayPort:
+       case DCB_CONNECTOR_DP:
+       case DCB_CONNECTOR_eDP:
                NV_INFO(dev, "Detected a DisplayPort connector\n");
+               type = DRM_MODE_CONNECTOR_DisplayPort;
                break;
        default:
-               NV_ERROR(dev, "Unknown connector, this is not good.\n");
-               break;
+               NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type);
+               return -EINVAL;
        }
 
+       nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
+       if (!nv_connector)
+               return -ENOMEM;
+       nv_connector->dcb = dcb;
+       connector = &nv_connector->base;
+
        /* defaults, will get overridden in detect() */
        connector->interlace_allowed = false;
        connector->doublescan_allowed = false;
        drm_connector_init(dev, connector, &nouveau_connector_funcs, type);
        drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
 
+       /* attach encoders */
+       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+               struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
+
+               if (nv_encoder->dcb->connector != dcb->index)
+                       continue;
+
+               if (get_slave_funcs(nv_encoder))
+                       get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
+
+               drm_mode_connector_attach_encoder(connector, encoder);
+       }
+
+       if (!connector->encoder_ids[0]) {
+               NV_WARN(dev, "  no encoders, ignoring\n");
+               drm_connector_cleanup(connector);
+               kfree(connector);
+               return 0;
+       }
+
        /* Init DVI-I specific properties */
        if (type == DRM_MODE_CONNECTOR_DVII) {
                drm_mode_create_dvi_i_properties(dev);
                }
        }
 
-       /* attach encoders */
-       list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-               struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
-
-               if (nv_encoder->dcb->connector != index)
-                       continue;
-
-               if (get_slave_funcs(nv_encoder))
-                       get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
-
-               drm_mode_connector_attach_encoder(connector, encoder);
-       }
-
        drm_sysfs_connector_add(connector);
 
        if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
 
        struct dcb_table *dcb = &dev_priv->vbios.dcb;
        struct drm_encoder *encoder;
        struct drm_crtc *crtc;
-       uint16_t connector[16] = { 0 };
        int i, ret;
 
        NV_DEBUG_KMS(dev, "\n");
 
                if (ret)
                        continue;
-
-               connector[dcbent->connector] |= (1 << dcbent->type);
        }
 
-       for (i = 0; i < dcb->entries; i++) {
-               struct dcb_entry *dcbent = &dcb->entry[i];
-               uint16_t encoders;
-               int type;
-
-               encoders = connector[dcbent->connector];
-               if (!(encoders & (1 << dcbent->type)))
-                       continue;
-               connector[dcbent->connector] = 0;
-
-               switch (dcbent->type) {
-               case OUTPUT_ANALOG:
-                       if (!MULTIPLE_ENCODERS(encoders))
-                               type = DRM_MODE_CONNECTOR_VGA;
-                       else
-                               type = DRM_MODE_CONNECTOR_DVII;
-                       break;
-               case OUTPUT_TMDS:
-                       if (!MULTIPLE_ENCODERS(encoders))
-                               type = DRM_MODE_CONNECTOR_DVID;
-                       else
-                               type = DRM_MODE_CONNECTOR_DVII;
-                       break;
-               case OUTPUT_LVDS:
-                       type = DRM_MODE_CONNECTOR_LVDS;
-#if 0
-                       /* don't create i2c adapter when lvds ddc not allowed */
-                       if (dcbent->lvdsconf.use_straps_for_mode ||
-                           dev_priv->vbios->fp_no_ddc)
-                               i2c_index = 0xf;
-#endif
-                       break;
-               case OUTPUT_TV:
-                       type = DRM_MODE_CONNECTOR_TV;
-                       break;
-               default:
-                       type = DRM_MODE_CONNECTOR_Unknown;
-                       continue;
-               }
-
-               nouveau_connector_create(dev, dcbent->connector, type);
-       }
+       for (i = 0; i < dcb->connector.entries; i++)
+               nouveau_connector_create(dev, &dcb->connector.entry[i]);
 
        /* Save previous state */
        NVLockVgaCrtcs(dev, false);
 
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct dcb_table *dcb = &dev_priv->vbios.dcb;
-       uint32_t connector[16] = {};
        int ret, i;
 
        NV_DEBUG_KMS(dev, "\n");
                        NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
                        continue;
                }
-
-               connector[entry->connector] |= (1 << entry->type);
        }
 
-       /* It appears that DCB 3.0+ vbios has a connector table, however,
-        * I'm not 100% certain how to decode it correctly yet so just
-        * look at what encoders are present on each connector index and
-        * attempt to derive the connector type from that.
-        */
-       for (i = 0 ; i < dcb->entries; i++) {
-               struct dcb_entry *entry = &dcb->entry[i];
-               uint16_t encoders;
-               int type;
-
-               encoders = connector[entry->connector];
-               if (!(encoders & (1 << entry->type)))
+       for (i = 0 ; i < dcb->connector.entries; i++) {
+               if (i != 0 && dcb->connector.entry[i].index ==
+                             dcb->connector.entry[i - 1].index)
                        continue;
-               connector[entry->connector] = 0;
-
-               if (encoders & (1 << OUTPUT_DP)) {
-                       type = DRM_MODE_CONNECTOR_DisplayPort;
-               } else if (encoders & (1 << OUTPUT_TMDS)) {
-                       if (encoders & (1 << OUTPUT_ANALOG))
-                               type = DRM_MODE_CONNECTOR_DVII;
-                       else
-                               type = DRM_MODE_CONNECTOR_DVID;
-               } else if (encoders & (1 << OUTPUT_ANALOG)) {
-                       type = DRM_MODE_CONNECTOR_VGA;
-               } else if (encoders & (1 << OUTPUT_LVDS)) {
-                       type = DRM_MODE_CONNECTOR_LVDS;
-               } else {
-                       type = DRM_MODE_CONNECTOR_Unknown;
-               }
-
-               if (type == DRM_MODE_CONNECTOR_Unknown)
-                       continue;
-
-               nouveau_connector_create(dev, entry->connector, type);
+               nouveau_connector_create(dev, &dcb->connector.entry[i]);
        }
 
        ret = nv50_display_init(dev);