summaryrefslogtreecommitdiff
path: root/nvkm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-08-19 08:20:26 +1000
committerBen Skeggs <bskeggs@redhat.com>2014-12-02 15:37:19 +1000
commita3721c21ed8ce921210932aeb56fb762708b028a (patch)
treed8740a088b8ecb82496b0d7d4d0bea06af27b86b /nvkm
parenta30656ee5dba9437854206b9905db66e17017313 (diff)
downloadnouveau-a3721c21ed8ce921210932aeb56fb762708b028a.tar.gz
bios: add support for ccb 4.1
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'nvkm')
-rw-r--r--nvkm/include/subdev/bios/i2c.h13
-rw-r--r--nvkm/subdev/bios/i2c.c19
2 files changed, 25 insertions, 7 deletions
diff --git a/nvkm/include/subdev/bios/i2c.h b/nvkm/include/subdev/bios/i2c.h
index 79c1252e5..c9bb11289 100644
--- a/nvkm/include/subdev/bios/i2c.h
+++ b/nvkm/include/subdev/bios/i2c.h
@@ -4,11 +4,14 @@
struct nouveau_bios;
enum dcb_i2c_type {
- DCB_I2C_NV04_BIT = 0,
- DCB_I2C_NV4E_BIT = 4,
- DCB_I2C_NVIO_BIT = 5,
- DCB_I2C_NVIO_AUX = 6,
- DCB_I2C_UNUSED = 0xff
+ /* matches bios type field prior to ccb 4.1 */
+ DCB_I2C_NV04_BIT = 0x00,
+ DCB_I2C_NV4E_BIT = 0x04,
+ DCB_I2C_NVIO_BIT = 0x05,
+ DCB_I2C_NVIO_AUX = 0x06,
+ /* made up - mostly */
+ DCB_I2C_PMGR = 0x80,
+ DCB_I2C_UNUSED = 0xff
};
struct dcb_i2c_entry {
diff --git a/nvkm/subdev/bios/i2c.c b/nvkm/subdev/bios/i2c.c
index 19ac30b28..282320ba9 100644
--- a/nvkm/subdev/bios/i2c.c
+++ b/nvkm/subdev/bios/i2c.c
@@ -39,7 +39,7 @@ dcb_i2c_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
i2c = nv_ro16(bios, dcb + 4);
}
- if (i2c && *ver >= 0x41) {
+ if (i2c && *ver >= 0x42) {
nv_warn(bios, "ccb %02x not supported\n", *ver);
return 0x0000;
}
@@ -75,6 +75,12 @@ dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info)
u8 ver, len;
u16 ent = dcb_i2c_entry(bios, idx, &ver, &len);
if (ent) {
+ if (ver >= 0x41) {
+ if (!(nv_ro32(bios, ent) & 0x80000000))
+ info->type = DCB_I2C_UNUSED;
+ else
+ info->type = DCB_I2C_PMGR;
+ } else
if (ver >= 0x30) {
info->type = nv_ro08(bios, ent + 0x03);
} else {
@@ -104,7 +110,16 @@ dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info)
case DCB_I2C_NVIO_AUX:
info->auxch = nv_ro08(bios, ent + 0) & 0x0f;
if (nv_ro08(bios, ent + 1) & 0x01)
- info->share = info->auxch;
+ info->share = info->auxch;
+ return 0;
+ case DCB_I2C_PMGR:
+ info->drive = (nv_ro16(bios, ent + 0) & 0x01f) >> 0;
+ if (info->drive == 0x1f)
+ info->drive = DCB_I2C_UNUSED;
+ info->auxch = (nv_ro16(bios, ent + 0) & 0x3e0) >> 5;
+ if (info->auxch == 0x1f)
+ info->auxch = DCB_I2C_UNUSED;
+ info->share = info->auxch;
return 0;
case DCB_I2C_UNUSED:
return 0;