enum dcb_connector_type type;
        uint8_t index2;
        uint8_t gpio_tag;
+       void *drm;
 };
 
 struct dcb_connector_table {
 
        .force = nouveau_connector_force
 };
 
-int
-nouveau_connector_create(struct drm_device *dev,
-                        struct dcb_connector_table_entry *dcb)
+struct drm_connector *
+nouveau_connector_create(struct drm_device *dev, int index)
 {
        const struct drm_connector_funcs *funcs = &nouveau_connector_funcs;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_connector *nv_connector = NULL;
+       struct dcb_connector_table_entry *dcb = NULL;
        struct drm_connector *connector;
-       struct drm_encoder *encoder;
        int type, ret = 0;
 
        NV_DEBUG_KMS(dev, "\n");
 
+       if (index >= dev_priv->vbios.dcb.connector.entries)
+               return ERR_PTR(-EINVAL);
+
+       dcb = &dev_priv->vbios.dcb.connector.entry[index];
+       if (dcb->drm)
+               return dcb->drm;
+
        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 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 DCB_CONNECTOR_DVI_I:
-               NV_INFO(dev, "Detected a DVI-I connector\n");
                type = DRM_MODE_CONNECTOR_DVII;
                break;
        case DCB_CONNECTOR_DVI_D:
-               NV_INFO(dev, "Detected a DVI-D connector\n");
                type = DRM_MODE_CONNECTOR_DVID;
                break;
        case DCB_CONNECTOR_HDMI_0:
        case DCB_CONNECTOR_HDMI_1:
-               NV_INFO(dev, "Detected a HDMI connector\n");
                type = DRM_MODE_CONNECTOR_HDMIA;
                break;
        case DCB_CONNECTOR_LVDS:
-               NV_INFO(dev, "Detected a LVDS connector\n");
                type = DRM_MODE_CONNECTOR_LVDS;
                funcs = &nouveau_connector_funcs_lvds;
                break;
        case DCB_CONNECTOR_DP:
-               NV_INFO(dev, "Detected a DisplayPort connector\n");
                type = DRM_MODE_CONNECTOR_DisplayPort;
                break;
        case DCB_CONNECTOR_eDP:
-               NV_INFO(dev, "Detected an eDP connector\n");
                type = DRM_MODE_CONNECTOR_eDP;
                break;
        default:
                NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type);
-               return -EINVAL;
+               return ERR_PTR(-EINVAL);
        }
 
        nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
        if (!nv_connector)
-               return -ENOMEM;
+               return ERR_PTR(-ENOMEM);
        nv_connector->dcb = dcb;
        connector = &nv_connector->base;
 
        drm_connector_init(dev, 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");
-               goto fail;
-       }
-
        /* Check if we need dithering enabled */
        if (dcb->type == DCB_CONNECTOR_LVDS) {
                bool dummy, is_24bit = false;
        }
 
        drm_sysfs_connector_add(connector);
-       return 0;
+       dcb->drm = connector;
+       return dcb->drm;
 
 fail:
        drm_connector_cleanup(connector);
        kfree(connector);
-       return ret;
+       return ERR_PTR(ret);
 
 }
 
        return container_of(con, struct nouveau_connector, base);
 }
 
-int nouveau_connector_create(struct drm_device *,
-                            struct dcb_connector_table_entry *);
+struct drm_connector *
+nouveau_connector_create(struct drm_device *, int index);
 
 #endif /* __NOUVEAU_CONNECTOR_H__ */
 
                                 unsigned long arg);
 
 /* nv04_dac.c */
-extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry);
+extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *);
 extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder);
 extern int nv04_dac_output_offset(struct drm_encoder *encoder);
 extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
 
 /* nv04_dfp.c */
-extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry);
+extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *);
 extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent);
 extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
                               int head, bool dl);
 
 /* nv04_tv.c */
 extern int nv04_tv_identify(struct drm_device *dev, int i2c_index);
-extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry);
+extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *);
 
 /* nv17_tv.c */
-extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry);
+extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *);
 
 /* nv04_display.c */
 extern int nv04_display_create(struct drm_device *);
 
 
 struct nouveau_connector *
 nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
-int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry);
-int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry);
+int nv50_sor_create(struct drm_connector *, struct dcb_entry *);
+int nv50_dac_create(struct drm_connector *, struct dcb_entry *);
 
 struct bit_displayport_encoder_table {
        uint32_t match;
 
        .destroy = nv04_dac_destroy,
 };
 
-int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry)
+int
+nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
        const struct drm_encoder_helper_funcs *helper;
-       struct drm_encoder *encoder;
        struct nouveau_encoder *nv_encoder = NULL;
+       struct drm_device *dev = connector->dev;
+       struct drm_encoder *encoder;
 
        nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
        if (!nv_encoder)
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
 
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }
 
        .destroy = nv04_dfp_destroy,
 };
 
-int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry)
+int
+nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
        const struct drm_encoder_helper_funcs *helper;
-       struct drm_encoder *encoder;
        struct nouveau_encoder *nv_encoder = NULL;
+       struct drm_encoder *encoder;
        int type;
 
        switch (entry->type) {
        nv_encoder->dcb = entry;
        nv_encoder->or = ffs(entry->or) - 1;
 
-       drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type);
+       drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type);
        drm_encoder_helper_add(encoder, helper);
 
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
 
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }
 
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct dcb_table *dcb = &dev_priv->vbios.dcb;
+       struct drm_connector *connector, *ct;
        struct drm_encoder *encoder;
        struct drm_crtc *crtc;
        int i, ret;
        for (i = 0; i < dcb->entries; i++) {
                struct dcb_entry *dcbent = &dcb->entry[i];
 
+               connector = nouveau_connector_create(dev, dcbent->connector);
+               if (IS_ERR(connector))
+                       continue;
+
                switch (dcbent->type) {
                case OUTPUT_ANALOG:
-                       ret = nv04_dac_create(dev, dcbent);
+                       ret = nv04_dac_create(connector, dcbent);
                        break;
                case OUTPUT_LVDS:
                case OUTPUT_TMDS:
-                       ret = nv04_dfp_create(dev, dcbent);
+                       ret = nv04_dfp_create(connector, dcbent);
                        break;
                case OUTPUT_TV:
                        if (dcbent->location == DCB_LOC_ON_CHIP)
-                               ret = nv17_tv_create(dev, dcbent);
+                               ret = nv17_tv_create(connector, dcbent);
                        else
-                               ret = nv04_tv_create(dev, dcbent);
+                               ret = nv04_tv_create(connector, dcbent);
                        break;
                default:
                        NV_WARN(dev, "DCB type %d not known\n", dcbent->type);
                        continue;
        }
 
-       for (i = 0; i < dcb->connector.entries; i++)
-               nouveau_connector_create(dev, &dcb->connector.entry[i]);
+       list_for_each_entry_safe(connector, ct,
+                                &dev->mode_config.connector_list, head) {
+               if (!connector->encoder_ids[0]) {
+                       NV_WARN(dev, "%s has no encoders, removing\n",
+                               drm_get_connector_name(connector));
+                       connector->funcs->destroy(connector);
+               }
+       }
 
        /* Save previous state */
        NVLockVgaCrtcs(dev, false);
 
        kfree(nv_encoder);
 }
 
-int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
+int
+nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
        struct nouveau_encoder *nv_encoder;
        struct drm_encoder *encoder;
+       struct drm_device *dev = connector->dev;
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct i2c_adapter *adap;
        struct drm_encoder_funcs *funcs = NULL;
 
        was_locked = NVLockVgaCrtcs(dev, false);
 
-       ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap,
+       ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), adap,
                                   &nv04_tv_encoder_info[type].board_info);
 
        NVLockVgaCrtcs(dev, was_locked);
 
        /* Set the slave encoder configuration */
        sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params);
+       sfuncs->create_resources(encoder, connector);
 
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 
 fail:
 
        .destroy = nv17_tv_destroy,
 };
 
-int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry)
+int
+nv17_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
+       struct drm_device *dev = connector->dev;
        struct drm_encoder *encoder;
        struct nv17_tv_encoder *tv_enc = NULL;
 
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
 
+       nv17_tv_create_resources(encoder, connector);
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }
 
 };
 
 int
-nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry)
+nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
        struct nouveau_encoder *nv_encoder;
        struct drm_encoder *encoder;
 
-       NV_DEBUG_KMS(dev, "\n");
-       NV_INFO(dev, "Detected a DAC output\n");
-
        nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
        if (!nv_encoder)
                return -ENOMEM;
 
        nv_encoder->disconnect = nv50_dac_disconnect;
 
-       drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs,
+       drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs,
                         DRM_MODE_ENCODER_DAC);
        drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs);
 
        encoder->possible_crtcs = entry->heads;
        encoder->possible_clones = 0;
+
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }
 
 
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct dcb_table *dcb = &dev_priv->vbios.dcb;
+       struct drm_connector *connector, *ct;
        int ret, i;
 
        NV_DEBUG_KMS(dev, "\n");
                        continue;
                }
 
+               connector = nouveau_connector_create(dev, entry->connector);
+               if (IS_ERR(connector))
+                       continue;
+
                switch (entry->type) {
                case OUTPUT_TMDS:
                case OUTPUT_LVDS:
                case OUTPUT_DP:
-                       nv50_sor_create(dev, entry);
+                       nv50_sor_create(connector, entry);
                        break;
                case OUTPUT_ANALOG:
-                       nv50_dac_create(dev, entry);
+                       nv50_dac_create(connector, entry);
                        break;
                default:
                        NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
                }
        }
 
-       for (i = 0 ; i < dcb->connector.entries; i++) {
-               if (i != 0 && dcb->connector.entry[i].index2 ==
-                             dcb->connector.entry[i - 1].index2)
-                       continue;
-               nouveau_connector_create(dev, &dcb->connector.entry[i]);
+       list_for_each_entry_safe(connector, ct,
+                                &dev->mode_config.connector_list, head) {
+               if (!connector->encoder_ids[0]) {
+                       NV_WARN(dev, "%s has no encoders, removing\n",
+                               drm_get_connector_name(connector));
+                       connector->funcs->destroy(connector);
+               }
        }
 
        ret = nv50_display_init(dev);
 
 };
 
 int
-nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
+nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry)
 {
        struct nouveau_encoder *nv_encoder = NULL;
+       struct drm_device *dev = connector->dev;
        struct drm_encoder *encoder;
-       bool dum;
        int type;
 
        NV_DEBUG_KMS(dev, "\n");
 
        switch (entry->type) {
        case OUTPUT_TMDS:
-               NV_INFO(dev, "Detected a TMDS output\n");
+       case OUTPUT_DP:
                type = DRM_MODE_ENCODER_TMDS;
                break;
        case OUTPUT_LVDS:
-               NV_INFO(dev, "Detected a LVDS output\n");
                type = DRM_MODE_ENCODER_LVDS;
-
-               if (nouveau_bios_parse_lvds_table(dev, 0, &dum, &dum)) {
-                       NV_ERROR(dev, "Failed parsing LVDS table\n");
-                       return -EINVAL;
-               }
-               break;
-       case OUTPUT_DP:
-               NV_INFO(dev, "Detected a DP output\n");
-               type = DRM_MODE_ENCODER_TMDS;
                break;
        default:
                return -EINVAL;
                        nv_encoder->dp.mc_unknown = 5;
        }
 
+       drm_mode_connector_attach_encoder(connector, encoder);
        return 0;
 }