Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 185514
b: refs/heads/master
c: 7f612d8
h: refs/heads/master
v: v3
  • Loading branch information
Ben Skeggs committed Feb 25, 2010
1 parent 6a2642c commit 6f2240a
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 116 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: dc5bc4ed3815dfec2f3ecfbf6f7983440040fe22
refs/heads/master: 7f612d87f8b4b1ddbcee04264a93e5af7b9f21c7
87 changes: 54 additions & 33 deletions trunk/drivers/gpu/drm/nouveau/nouveau_connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -742,53 +742,87 @@ nouveau_connector_create_lvds(struct drm_device *dev,
}

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);
Expand Down Expand Up @@ -822,19 +856,6 @@ nouveau_connector_create(struct drm_device *dev, int index, int type)
}
}

/* 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) {
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/gpu/drm/nouveau/nouveau_connector.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static inline struct nouveau_connector *nouveau_connector(
return container_of(con, struct nouveau_connector, base);
}

int nouveau_connector_create(struct drm_device *dev, int i2c_index, int type);
int nouveau_connector_create(struct drm_device *,
struct dcb_connector_table_entry *);

#endif /* __NOUVEAU_CONNECTOR_H__ */
47 changes: 2 additions & 45 deletions trunk/drivers/gpu/drm/nouveau/nv04_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ nv04_display_create(struct drm_device *dev)
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");
Expand Down Expand Up @@ -154,52 +153,10 @@ nv04_display_create(struct drm_device *dev)

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);
Expand Down
40 changes: 4 additions & 36 deletions trunk/drivers/gpu/drm/nouveau/nv50_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,6 @@ int nv50_display_create(struct drm_device *dev)
{
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");
Expand Down Expand Up @@ -522,44 +521,13 @@ int nv50_display_create(struct drm_device *dev)
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);
Expand Down

0 comments on commit 6f2240a

Please sign in to comment.