From 7e99a9b2b5386c0ea4234d2845932ff4ab8e4829 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 24 Apr 2010 03:53:14 +1000 Subject: [PATCH] drm/nv50: fix monitor detection on certain chipsets There appears to be some kind of switch on certain chips to control whether the DP auxch or traditional i2c bus will be operational on a connector, this commit hopefully fixes nouveau to do the right thing. Likely only relevent on chips with DP outputs. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_i2c.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 88583e7bf651..316a3c7e6eb4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c @@ -254,16 +254,27 @@ struct nouveau_i2c_chan * nouveau_i2c_find(struct drm_device *dev, int index) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nvbios *bios = &dev_priv->vbios; + struct dcb_i2c_entry *i2c = &dev_priv->vbios.dcb.i2c[index]; if (index >= DCB_MAX_NUM_I2C_ENTRIES) return NULL; - if (!bios->dcb.i2c[index].chan) { - if (nouveau_i2c_init(dev, &bios->dcb.i2c[index], index)) - return NULL; + if (dev_priv->chipset >= NV_50 && (i2c->entry & 0x00000100)) { + uint32_t reg = 0xe500, val; + + if (i2c->port_type == 6) { + reg += i2c->read * 0x50; + val = 0x2002; + } else { + reg += ((i2c->entry & 0x1e00) >> 9) * 0x50; + val = 0xe001; + } + + nv_wr32(dev, reg, (nv_rd32(dev, reg) & ~0xf003) | val); } - return bios->dcb.i2c[index].chan; + if (!i2c->chan && nouveau_i2c_init(dev, i2c, index)) + return NULL; + return i2c->chan; }