aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-06-28 00:35:50 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-07-12 20:13:09 -0400
commit8f1a60868f4594bc5576cca8952635f475e8bec6 (patch)
tree23eeab5d99ecaee1f6c8c94e21911cfa8fc47de1
parent3195c5f9784aa8ec27a7bb19a6840dc67e9e90f1 (diff)
drm/nouveau: tidy connector/encoder creation a little
Create connectors before encoders to avoid having to do another loop across encoder list whenever we create a new connector. This allows us to pass the connector to the encoder creation functions, and avoid using a create_resources() callback since we can now call it directly. This can also potentially modify the connector ordering on nv50. On cards where the DCB connector and encoder tables are in the same order, things will be unchanged. However, there's some cards where the ordering between the tables differ, and in one case, leads us to naming the connectors "wrongly". Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c51
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_encoder.h4
-rw-r--r--drivers/gpu/drm/nouveau/nv04_dac.c7
-rw-r--r--drivers/gpu/drm/nouveau/nv04_dfp.c8
-rw-r--r--drivers/gpu/drm/nouveau/nv04_display.c23
-rw-r--r--drivers/gpu/drm/nouveau/nv04_tv.c8
-rw-r--r--drivers/gpu/drm/nouveau/nv17_tv.c6
-rw-r--r--drivers/gpu/drm/nouveau/nv50_dac.c9
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c21
-rw-r--r--drivers/gpu/drm/nouveau/nv50_sor.c17
13 files changed, 84 insertions, 83 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index adf4ec2d06c0..bd33a54f7deb 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -81,6 +81,7 @@ struct dcb_connector_table_entry {
81 enum dcb_connector_type type; 81 enum dcb_connector_type type;
82 uint8_t index2; 82 uint8_t index2;
83 uint8_t gpio_tag; 83 uint8_t gpio_tag;
84 void *drm;
84}; 85};
85 86
86struct dcb_connector_table { 87struct dcb_connector_table {
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c
index 53700f8cd499..13f2e1ea2d79 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -729,66 +729,62 @@ nouveau_connector_funcs_lvds = {
729 .force = nouveau_connector_force 729 .force = nouveau_connector_force
730}; 730};
731 731
732int 732struct drm_connector *
733nouveau_connector_create(struct drm_device *dev, 733nouveau_connector_create(struct drm_device *dev, int index)
734 struct dcb_connector_table_entry *dcb)
735{ 734{
736 const struct drm_connector_funcs *funcs = &nouveau_connector_funcs; 735 const struct drm_connector_funcs *funcs = &nouveau_connector_funcs;
737 struct drm_nouveau_private *dev_priv = dev->dev_private; 736 struct drm_nouveau_private *dev_priv = dev->dev_private;
738 struct nouveau_connector *nv_connector = NULL; 737 struct nouveau_connector *nv_connector = NULL;
738 struct dcb_connector_table_entry *dcb = NULL;
739 struct drm_connector *connector; 739 struct drm_connector *connector;
740 struct drm_encoder *encoder;
741 int type, ret = 0; 740 int type, ret = 0;
742 741
743 NV_DEBUG_KMS(dev, "\n"); 742 NV_DEBUG_KMS(dev, "\n");
744 743
744 if (index >= dev_priv->vbios.dcb.connector.entries)
745 return ERR_PTR(-EINVAL);
746
747 dcb = &dev_priv->vbios.dcb.connector.entry[index];
748 if (dcb->drm)
749 return dcb->drm;
750
745 switch (dcb->type) { 751 switch (dcb->type) {
746 case DCB_CONNECTOR_NONE:
747 return 0;
748 case DCB_CONNECTOR_VGA: 752 case DCB_CONNECTOR_VGA:
749 NV_INFO(dev, "Detected a VGA connector\n");
750 type = DRM_MODE_CONNECTOR_VGA; 753 type = DRM_MODE_CONNECTOR_VGA;
751 break; 754 break;
752 case DCB_CONNECTOR_TV_0: 755 case DCB_CONNECTOR_TV_0:
753 case DCB_CONNECTOR_TV_1: 756 case DCB_CONNECTOR_TV_1:
754 case DCB_CONNECTOR_TV_3: 757 case DCB_CONNECTOR_TV_3:
755 NV_INFO(dev, "Detected a TV connector\n");
756 type = DRM_MODE_CONNECTOR_TV; 758 type = DRM_MODE_CONNECTOR_TV;
757 break; 759 break;
758 case DCB_CONNECTOR_DVI_I: 760 case DCB_CONNECTOR_DVI_I:
759 NV_INFO(dev, "Detected a DVI-I connector\n");
760 type = DRM_MODE_CONNECTOR_DVII; 761 type = DRM_MODE_CONNECTOR_DVII;
761 break; 762 break;
762 case DCB_CONNECTOR_DVI_D: 763 case DCB_CONNECTOR_DVI_D:
763 NV_INFO(dev, "Detected a DVI-D connector\n");
764 type = DRM_MODE_CONNECTOR_DVID; 764 type = DRM_MODE_CONNECTOR_DVID;
765 break; 765 break;
766 case DCB_CONNECTOR_HDMI_0: 766 case DCB_CONNECTOR_HDMI_0:
767 case DCB_CONNECTOR_HDMI_1: 767 case DCB_CONNECTOR_HDMI_1:
768 NV_INFO(dev, "Detected a HDMI connector\n");
769 type = DRM_MODE_CONNECTOR_HDMIA; 768 type = DRM_MODE_CONNECTOR_HDMIA;
770 break; 769 break;
771 case DCB_CONNECTOR_LVDS: 770 case DCB_CONNECTOR_LVDS:
772 NV_INFO(dev, "Detected a LVDS connector\n");
773 type = DRM_MODE_CONNECTOR_LVDS; 771 type = DRM_MODE_CONNECTOR_LVDS;
774 funcs = &nouveau_connector_funcs_lvds; 772 funcs = &nouveau_connector_funcs_lvds;
775 break; 773 break;
776 case DCB_CONNECTOR_DP: 774 case DCB_CONNECTOR_DP:
777 NV_INFO(dev, "Detected a DisplayPort connector\n");
778 type = DRM_MODE_CONNECTOR_DisplayPort; 775 type = DRM_MODE_CONNECTOR_DisplayPort;
779 break; 776 break;
780 case DCB_CONNECTOR_eDP: 777 case DCB_CONNECTOR_eDP:
781 NV_INFO(dev, "Detected an eDP connector\n");
782 type = DRM_MODE_CONNECTOR_eDP; 778 type = DRM_MODE_CONNECTOR_eDP;
783 break; 779 break;
784 default: 780 default:
785 NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type); 781 NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type);
786 return -EINVAL; 782 return ERR_PTR(-EINVAL);
787 } 783 }
788 784
789 nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); 785 nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
790 if (!nv_connector) 786 if (!nv_connector)
791 return -ENOMEM; 787 return ERR_PTR(-ENOMEM);
792 nv_connector->dcb = dcb; 788 nv_connector->dcb = dcb;
793 connector = &nv_connector->base; 789 connector = &nv_connector->base;
794 790
@@ -799,24 +795,6 @@ nouveau_connector_create(struct drm_device *dev,
799 drm_connector_init(dev, connector, funcs, type); 795 drm_connector_init(dev, connector, funcs, type);
800 drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); 796 drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
801 797
802 /* attach encoders */
803 list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
804 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
805
806 if (nv_encoder->dcb->connector != dcb->index)
807 continue;
808
809 if (get_slave_funcs(nv_encoder))
810 get_slave_funcs(nv_encoder)->create_resources(encoder, connector);
811
812 drm_mode_connector_attach_encoder(connector, encoder);
813 }
814
815 if (!connector->encoder_ids[0]) {
816 NV_WARN(dev, " no encoders, ignoring\n");
817 goto fail;
818 }
819
820 /* Check if we need dithering enabled */ 798 /* Check if we need dithering enabled */
821 if (dcb->type == DCB_CONNECTOR_LVDS) { 799 if (dcb->type == DCB_CONNECTOR_LVDS) {
822 bool dummy, is_24bit = false; 800 bool dummy, is_24bit = false;
@@ -877,11 +855,12 @@ nouveau_connector_create(struct drm_device *dev,
877 } 855 }
878 856
879 drm_sysfs_connector_add(connector); 857 drm_sysfs_connector_add(connector);
880 return 0; 858 dcb->drm = connector;
859 return dcb->drm;
881 860
882fail: 861fail:
883 drm_connector_cleanup(connector); 862 drm_connector_cleanup(connector);
884 kfree(connector); 863 kfree(connector);
885 return ret; 864 return ERR_PTR(ret);
886 865
887} 866}
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h
index 4ef38abc2d9c..1ce3d913867e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_connector.h
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.h
@@ -49,7 +49,7 @@ static inline struct nouveau_connector *nouveau_connector(
49 return container_of(con, struct nouveau_connector, base); 49 return container_of(con, struct nouveau_connector, base);
50} 50}
51 51
52int nouveau_connector_create(struct drm_device *, 52struct drm_connector *
53 struct dcb_connector_table_entry *); 53nouveau_connector_create(struct drm_device *, int index);
54 54
55#endif /* __NOUVEAU_CONNECTOR_H__ */ 55#endif /* __NOUVEAU_CONNECTOR_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 20c54884dcb7..e3c8bd4f99c9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1072,13 +1072,13 @@ extern long nouveau_compat_ioctl(struct file *file, unsigned int cmd,
1072 unsigned long arg); 1072 unsigned long arg);
1073 1073
1074/* nv04_dac.c */ 1074/* nv04_dac.c */
1075extern int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry); 1075extern int nv04_dac_create(struct drm_connector *, struct dcb_entry *);
1076extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder); 1076extern uint32_t nv17_dac_sample_load(struct drm_encoder *encoder);
1077extern int nv04_dac_output_offset(struct drm_encoder *encoder); 1077extern int nv04_dac_output_offset(struct drm_encoder *encoder);
1078extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable); 1078extern void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable);
1079 1079
1080/* nv04_dfp.c */ 1080/* nv04_dfp.c */
1081extern int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry); 1081extern int nv04_dfp_create(struct drm_connector *, struct dcb_entry *);
1082extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent); 1082extern int nv04_dfp_get_bound_head(struct drm_device *dev, struct dcb_entry *dcbent);
1083extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent, 1083extern void nv04_dfp_bind_head(struct drm_device *dev, struct dcb_entry *dcbent,
1084 int head, bool dl); 1084 int head, bool dl);
@@ -1087,10 +1087,10 @@ extern void nv04_dfp_update_fp_control(struct drm_encoder *encoder, int mode);
1087 1087
1088/* nv04_tv.c */ 1088/* nv04_tv.c */
1089extern int nv04_tv_identify(struct drm_device *dev, int i2c_index); 1089extern int nv04_tv_identify(struct drm_device *dev, int i2c_index);
1090extern int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry); 1090extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *);
1091 1091
1092/* nv17_tv.c */ 1092/* nv17_tv.c */
1093extern int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry); 1093extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *);
1094 1094
1095/* nv04_display.c */ 1095/* nv04_display.c */
1096extern int nv04_display_create(struct drm_device *); 1096extern int nv04_display_create(struct drm_device *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h
index e1df8209cd0f..e4442e28b568 100644
--- a/drivers/gpu/drm/nouveau/nouveau_encoder.h
+++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h
@@ -71,8 +71,8 @@ static inline struct drm_encoder *to_drm_encoder(struct nouveau_encoder *enc)
71 71
72struct nouveau_connector * 72struct nouveau_connector *
73nouveau_encoder_connector_get(struct nouveau_encoder *encoder); 73nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
74int nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry); 74int nv50_sor_create(struct drm_connector *, struct dcb_entry *);
75int nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry); 75int nv50_dac_create(struct drm_connector *, struct dcb_entry *);
76 76
77struct bit_displayport_encoder_table { 77struct bit_displayport_encoder_table {
78 uint32_t match; 78 uint32_t match;
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c
index 1cb19e3acb55..8066c56afa34 100644
--- a/drivers/gpu/drm/nouveau/nv04_dac.c
+++ b/drivers/gpu/drm/nouveau/nv04_dac.c
@@ -501,11 +501,13 @@ static const struct drm_encoder_funcs nv04_dac_funcs = {
501 .destroy = nv04_dac_destroy, 501 .destroy = nv04_dac_destroy,
502}; 502};
503 503
504int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry) 504int
505nv04_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
505{ 506{
506 const struct drm_encoder_helper_funcs *helper; 507 const struct drm_encoder_helper_funcs *helper;
507 struct drm_encoder *encoder;
508 struct nouveau_encoder *nv_encoder = NULL; 508 struct nouveau_encoder *nv_encoder = NULL;
509 struct drm_device *dev = connector->dev;
510 struct drm_encoder *encoder;
509 511
510 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); 512 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
511 if (!nv_encoder) 513 if (!nv_encoder)
@@ -527,5 +529,6 @@ int nv04_dac_create(struct drm_device *dev, struct dcb_entry *entry)
527 encoder->possible_crtcs = entry->heads; 529 encoder->possible_crtcs = entry->heads;
528 encoder->possible_clones = 0; 530 encoder->possible_clones = 0;
529 531
532 drm_mode_connector_attach_encoder(connector, encoder);
530 return 0; 533 return 0;
531} 534}
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c
index 41634d4752fe..3559d8972c74 100644
--- a/drivers/gpu/drm/nouveau/nv04_dfp.c
+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
@@ -584,11 +584,12 @@ static const struct drm_encoder_funcs nv04_dfp_funcs = {
584 .destroy = nv04_dfp_destroy, 584 .destroy = nv04_dfp_destroy,
585}; 585};
586 586
587int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry) 587int
588nv04_dfp_create(struct drm_connector *connector, struct dcb_entry *entry)
588{ 589{
589 const struct drm_encoder_helper_funcs *helper; 590 const struct drm_encoder_helper_funcs *helper;
590 struct drm_encoder *encoder;
591 struct nouveau_encoder *nv_encoder = NULL; 591 struct nouveau_encoder *nv_encoder = NULL;
592 struct drm_encoder *encoder;
592 int type; 593 int type;
593 594
594 switch (entry->type) { 595 switch (entry->type) {
@@ -613,11 +614,12 @@ int nv04_dfp_create(struct drm_device *dev, struct dcb_entry *entry)
613 nv_encoder->dcb = entry; 614 nv_encoder->dcb = entry;
614 nv_encoder->or = ffs(entry->or) - 1; 615 nv_encoder->or = ffs(entry->or) - 1;
615 616
616 drm_encoder_init(dev, encoder, &nv04_dfp_funcs, type); 617 drm_encoder_init(connector->dev, encoder, &nv04_dfp_funcs, type);
617 drm_encoder_helper_add(encoder, helper); 618 drm_encoder_helper_add(encoder, helper);
618 619
619 encoder->possible_crtcs = entry->heads; 620 encoder->possible_crtcs = entry->heads;
620 encoder->possible_clones = 0; 621 encoder->possible_clones = 0;
621 622
623 drm_mode_connector_attach_encoder(connector, encoder);
622 return 0; 624 return 0;
623} 625}
diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c
index c7898b4f6dfb..b35b7ed0833b 100644
--- a/drivers/gpu/drm/nouveau/nv04_display.c
+++ b/drivers/gpu/drm/nouveau/nv04_display.c
@@ -94,6 +94,7 @@ nv04_display_create(struct drm_device *dev)
94{ 94{
95 struct drm_nouveau_private *dev_priv = dev->dev_private; 95 struct drm_nouveau_private *dev_priv = dev->dev_private;
96 struct dcb_table *dcb = &dev_priv->vbios.dcb; 96 struct dcb_table *dcb = &dev_priv->vbios.dcb;
97 struct drm_connector *connector, *ct;
97 struct drm_encoder *encoder; 98 struct drm_encoder *encoder;
98 struct drm_crtc *crtc; 99 struct drm_crtc *crtc;
99 int i, ret; 100 int i, ret;
@@ -132,19 +133,23 @@ nv04_display_create(struct drm_device *dev)
132 for (i = 0; i < dcb->entries; i++) { 133 for (i = 0; i < dcb->entries; i++) {
133 struct dcb_entry *dcbent = &dcb->entry[i]; 134 struct dcb_entry *dcbent = &dcb->entry[i];
134 135
136 connector = nouveau_connector_create(dev, dcbent->connector);
137 if (IS_ERR(connector))
138 continue;
139
135 switch (dcbent->type) { 140 switch (dcbent->type) {
136 case OUTPUT_ANALOG: 141 case OUTPUT_ANALOG:
137 ret = nv04_dac_create(dev, dcbent); 142 ret = nv04_dac_create(connector, dcbent);
138 break; 143 break;
139 case OUTPUT_LVDS: 144 case OUTPUT_LVDS:
140 case OUTPUT_TMDS: 145 case OUTPUT_TMDS:
141 ret = nv04_dfp_create(dev, dcbent); 146 ret = nv04_dfp_create(connector, dcbent);
142 break; 147 break;
143 case OUTPUT_TV: 148 case OUTPUT_TV:
144 if (dcbent->location == DCB_LOC_ON_CHIP) 149 if (dcbent->location == DCB_LOC_ON_CHIP)
145 ret = nv17_tv_create(dev, dcbent); 150 ret = nv17_tv_create(connector, dcbent);
146 else 151 else
147 ret = nv04_tv_create(dev, dcbent); 152 ret = nv04_tv_create(connector, dcbent);
148 break; 153 break;
149 default: 154 default:
150 NV_WARN(dev, "DCB type %d not known\n", dcbent->type); 155 NV_WARN(dev, "DCB type %d not known\n", dcbent->type);
@@ -155,8 +160,14 @@ nv04_display_create(struct drm_device *dev)
155 continue; 160 continue;
156 } 161 }
157 162
158 for (i = 0; i < dcb->connector.entries; i++) 163 list_for_each_entry_safe(connector, ct,
159 nouveau_connector_create(dev, &dcb->connector.entry[i]); 164 &dev->mode_config.connector_list, head) {
165 if (!connector->encoder_ids[0]) {
166 NV_WARN(dev, "%s has no encoders, removing\n",
167 drm_get_connector_name(connector));
168 connector->funcs->destroy(connector);
169 }
170 }
160 171
161 /* Save previous state */ 172 /* Save previous state */
162 NVLockVgaCrtcs(dev, false); 173 NVLockVgaCrtcs(dev, false);
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c
index c4e3404337d4..84b5954a8efb 100644
--- a/drivers/gpu/drm/nouveau/nv04_tv.c
+++ b/drivers/gpu/drm/nouveau/nv04_tv.c
@@ -223,10 +223,12 @@ static void nv04_tv_destroy(struct drm_encoder *encoder)
223 kfree(nv_encoder); 223 kfree(nv_encoder);
224} 224}
225 225
226int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) 226int
227nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
227{ 228{
228 struct nouveau_encoder *nv_encoder; 229 struct nouveau_encoder *nv_encoder;
229 struct drm_encoder *encoder; 230 struct drm_encoder *encoder;
231 struct drm_device *dev = connector->dev;
230 struct drm_nouveau_private *dev_priv = dev->dev_private; 232 struct drm_nouveau_private *dev_priv = dev->dev_private;
231 struct i2c_adapter *adap; 233 struct i2c_adapter *adap;
232 struct drm_encoder_funcs *funcs = NULL; 234 struct drm_encoder_funcs *funcs = NULL;
@@ -266,7 +268,7 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
266 268
267 was_locked = NVLockVgaCrtcs(dev, false); 269 was_locked = NVLockVgaCrtcs(dev, false);
268 270
269 ret = drm_i2c_encoder_init(encoder->dev, to_encoder_slave(encoder), adap, 271 ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), adap,
270 &nv04_tv_encoder_info[type].board_info); 272 &nv04_tv_encoder_info[type].board_info);
271 273
272 NVLockVgaCrtcs(dev, was_locked); 274 NVLockVgaCrtcs(dev, was_locked);
@@ -294,7 +296,9 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry)
294 296
295 /* Set the slave encoder configuration */ 297 /* Set the slave encoder configuration */
296 sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params); 298 sfuncs->set_config(encoder, nv04_tv_encoder_info[type].params);
299 sfuncs->create_resources(encoder, connector);
297 300
301 drm_mode_connector_attach_encoder(connector, encoder);
298 return 0; 302 return 0;
299 303
300fail: 304fail:
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c
index 74c880374fb9..44437ff46394 100644
--- a/drivers/gpu/drm/nouveau/nv17_tv.c
+++ b/drivers/gpu/drm/nouveau/nv17_tv.c
@@ -744,8 +744,10 @@ static struct drm_encoder_funcs nv17_tv_funcs = {
744 .destroy = nv17_tv_destroy, 744 .destroy = nv17_tv_destroy,
745}; 745};
746 746
747int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry) 747int
748nv17_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
748{ 749{
750 struct drm_device *dev = connector->dev;
749 struct drm_encoder *encoder; 751 struct drm_encoder *encoder;
750 struct nv17_tv_encoder *tv_enc = NULL; 752 struct nv17_tv_encoder *tv_enc = NULL;
751 753
@@ -774,5 +776,7 @@ int nv17_tv_create(struct drm_device *dev, struct dcb_entry *entry)
774 encoder->possible_crtcs = entry->heads; 776 encoder->possible_crtcs = entry->heads;
775 encoder->possible_clones = 0; 777 encoder->possible_clones = 0;
776 778
779 nv17_tv_create_resources(encoder, connector);
780 drm_mode_connector_attach_encoder(connector, encoder);
777 return 0; 781 return 0;
778} 782}
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c
index 1fd9537beff6..e114f818751d 100644
--- a/drivers/gpu/drm/nouveau/nv50_dac.c
+++ b/drivers/gpu/drm/nouveau/nv50_dac.c
@@ -275,14 +275,11 @@ static const struct drm_encoder_funcs nv50_dac_encoder_funcs = {
275}; 275};
276 276
277int 277int
278nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry) 278nv50_dac_create(struct drm_connector *connector, struct dcb_entry *entry)
279{ 279{
280 struct nouveau_encoder *nv_encoder; 280 struct nouveau_encoder *nv_encoder;
281 struct drm_encoder *encoder; 281 struct drm_encoder *encoder;
282 282
283 NV_DEBUG_KMS(dev, "\n");
284 NV_INFO(dev, "Detected a DAC output\n");
285
286 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); 283 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
287 if (!nv_encoder) 284 if (!nv_encoder)
288 return -ENOMEM; 285 return -ENOMEM;
@@ -293,12 +290,14 @@ nv50_dac_create(struct drm_device *dev, struct dcb_entry *entry)
293 290
294 nv_encoder->disconnect = nv50_dac_disconnect; 291 nv_encoder->disconnect = nv50_dac_disconnect;
295 292
296 drm_encoder_init(dev, encoder, &nv50_dac_encoder_funcs, 293 drm_encoder_init(connector->dev, encoder, &nv50_dac_encoder_funcs,
297 DRM_MODE_ENCODER_DAC); 294 DRM_MODE_ENCODER_DAC);
298 drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs); 295 drm_encoder_helper_add(encoder, &nv50_dac_helper_funcs);
299 296
300 encoder->possible_crtcs = entry->heads; 297 encoder->possible_crtcs = entry->heads;
301 encoder->possible_clones = 0; 298 encoder->possible_clones = 0;
299
300 drm_mode_connector_attach_encoder(connector, encoder);
302 return 0; 301 return 0;
303} 302}
304 303
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 515edde2c59f..e031904ef7a7 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -465,6 +465,7 @@ int nv50_display_create(struct drm_device *dev)
465{ 465{
466 struct drm_nouveau_private *dev_priv = dev->dev_private; 466 struct drm_nouveau_private *dev_priv = dev->dev_private;
467 struct dcb_table *dcb = &dev_priv->vbios.dcb; 467 struct dcb_table *dcb = &dev_priv->vbios.dcb;
468 struct drm_connector *connector, *ct;
468 int ret, i; 469 int ret, i;
469 470
470 NV_DEBUG_KMS(dev, "\n"); 471 NV_DEBUG_KMS(dev, "\n");
@@ -507,14 +508,18 @@ int nv50_display_create(struct drm_device *dev)
507 continue; 508 continue;
508 } 509 }
509 510
511 connector = nouveau_connector_create(dev, entry->connector);
512 if (IS_ERR(connector))
513 continue;
514
510 switch (entry->type) { 515 switch (entry->type) {
511 case OUTPUT_TMDS: 516 case OUTPUT_TMDS:
512 case OUTPUT_LVDS: 517 case OUTPUT_LVDS:
513 case OUTPUT_DP: 518 case OUTPUT_DP:
514 nv50_sor_create(dev, entry); 519 nv50_sor_create(connector, entry);
515 break; 520 break;
516 case OUTPUT_ANALOG: 521 case OUTPUT_ANALOG:
517 nv50_dac_create(dev, entry); 522 nv50_dac_create(connector, entry);
518 break; 523 break;
519 default: 524 default:
520 NV_WARN(dev, "DCB encoder %d unknown\n", entry->type); 525 NV_WARN(dev, "DCB encoder %d unknown\n", entry->type);
@@ -522,11 +527,13 @@ int nv50_display_create(struct drm_device *dev)
522 } 527 }
523 } 528 }
524 529
525 for (i = 0 ; i < dcb->connector.entries; i++) { 530 list_for_each_entry_safe(connector, ct,
526 if (i != 0 && dcb->connector.entry[i].index2 == 531 &dev->mode_config.connector_list, head) {
527 dcb->connector.entry[i - 1].index2) 532 if (!connector->encoder_ids[0]) {
528 continue; 533 NV_WARN(dev, "%s has no encoders, removing\n",
529 nouveau_connector_create(dev, &dcb->connector.entry[i]); 534 drm_get_connector_name(connector));
535 connector->funcs->destroy(connector);
536 }
530 } 537 }
531 538
532 ret = nv50_display_init(dev); 539 ret = nv50_display_init(dev);
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c
index 812778db76ac..4832bba7c43a 100644
--- a/drivers/gpu/drm/nouveau/nv50_sor.c
+++ b/drivers/gpu/drm/nouveau/nv50_sor.c
@@ -272,32 +272,22 @@ static const struct drm_encoder_funcs nv50_sor_encoder_funcs = {
272}; 272};
273 273
274int 274int
275nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry) 275nv50_sor_create(struct drm_connector *connector, struct dcb_entry *entry)
276{ 276{
277 struct nouveau_encoder *nv_encoder = NULL; 277 struct nouveau_encoder *nv_encoder = NULL;
278 struct drm_device *dev = connector->dev;
278 struct drm_encoder *encoder; 279 struct drm_encoder *encoder;
279 bool dum;
280 int type; 280 int type;
281 281
282 NV_DEBUG_KMS(dev, "\n"); 282 NV_DEBUG_KMS(dev, "\n");
283 283
284 switch (entry->type) { 284 switch (entry->type) {
285 case OUTPUT_TMDS: 285 case OUTPUT_TMDS:
286 NV_INFO(dev, "Detected a TMDS output\n"); 286 case OUTPUT_DP:
287 type = DRM_MODE_ENCODER_TMDS; 287 type = DRM_MODE_ENCODER_TMDS;
288 break; 288 break;
289 case OUTPUT_LVDS: 289 case OUTPUT_LVDS:
290 NV_INFO(dev, "Detected a LVDS output\n");
291 type = DRM_MODE_ENCODER_LVDS; 290 type = DRM_MODE_ENCODER_LVDS;
292
293 if (nouveau_bios_parse_lvds_table(dev, 0, &dum, &dum)) {
294 NV_ERROR(dev, "Failed parsing LVDS table\n");
295 return -EINVAL;
296 }
297 break;
298 case OUTPUT_DP:
299 NV_INFO(dev, "Detected a DP output\n");
300 type = DRM_MODE_ENCODER_TMDS;
301 break; 291 break;
302 default: 292 default:
303 return -EINVAL; 293 return -EINVAL;
@@ -342,5 +332,6 @@ nv50_sor_create(struct drm_device *dev, struct dcb_entry *entry)
342 nv_encoder->dp.mc_unknown = 5; 332 nv_encoder->dp.mc_unknown = 5;
343 } 333 }
344 334
335 drm_mode_connector_attach_encoder(connector, encoder);
345 return 0; 336 return 0;
346} 337}