aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_connector.c
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 /drivers/gpu/drm/nouveau/nouveau_connector.c
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_connector.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_connector.c51
1 files changed, 15 insertions, 36 deletions
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}