diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-08-19 08:20:26 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-12-02 15:37:19 +1000 |
commit | a3721c21ed8ce921210932aeb56fb762708b028a (patch) | |
tree | d8740a088b8ecb82496b0d7d4d0bea06af27b86b /nvkm | |
parent | a30656ee5dba9437854206b9905db66e17017313 (diff) | |
download | nouveau-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.h | 13 | ||||
-rw-r--r-- | nvkm/subdev/bios/i2c.c | 19 |
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; |