diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c | 39 |
1 files changed, 24 insertions, 15 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c index 6e0a33648be9..a7797a9e9cbc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/volt.c @@ -25,18 +25,18 @@ #include <subdev/bios/bit.h> #include <subdev/bios/volt.h> -u16 +u32 nvbios_volt_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) { struct bit_entry bit_P; - u16 volt = 0x0000; + u32 volt = 0; if (!bit_entry(bios, 'P', &bit_P)) { if (bit_P.version == 2) - volt = nvbios_rd16(bios, bit_P.offset + 0x0c); + volt = nvbios_rd32(bios, bit_P.offset + 0x0c); else if (bit_P.version == 1) - volt = nvbios_rd16(bios, bit_P.offset + 0x10); + volt = nvbios_rd32(bios, bit_P.offset + 0x10); if (volt) { *ver = nvbios_rd08(bios, volt + 0); @@ -62,33 +62,37 @@ nvbios_volt_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) } } - return 0x0000; + return 0; } -u16 +u32 nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_volt *info) { - u16 volt = nvbios_volt_table(bios, ver, hdr, cnt, len); + u32 volt = nvbios_volt_table(bios, ver, hdr, cnt, len); memset(info, 0x00, sizeof(*info)); switch (!!volt * *ver) { case 0x12: info->type = NVBIOS_VOLT_GPIO; info->vidmask = nvbios_rd08(bios, volt + 0x04); + info->ranged = false; break; case 0x20: info->type = NVBIOS_VOLT_GPIO; info->vidmask = nvbios_rd08(bios, volt + 0x05); + info->ranged = false; break; case 0x30: info->type = NVBIOS_VOLT_GPIO; info->vidmask = nvbios_rd08(bios, volt + 0x04); + info->ranged = false; break; case 0x40: info->type = NVBIOS_VOLT_GPIO; info->base = nvbios_rd32(bios, volt + 0x04); info->step = nvbios_rd16(bios, volt + 0x08); info->vidmask = nvbios_rd08(bios, volt + 0x0b); + info->ranged = true; /* XXX: find the flag byte */ /*XXX*/ info->min = 0; info->max = info->base; @@ -104,32 +108,34 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, info->pwm_freq = nvbios_rd32(bios, volt + 0x5) / 1000; info->pwm_range = nvbios_rd32(bios, volt + 0x16); } else { - info->type = NVBIOS_VOLT_GPIO; - info->vidmask = nvbios_rd08(bios, volt + 0x06); - info->step = nvbios_rd16(bios, volt + 0x16); + info->type = NVBIOS_VOLT_GPIO; + info->vidmask = nvbios_rd08(bios, volt + 0x06); + info->step = nvbios_rd16(bios, volt + 0x16); + info->ranged = + !!(nvbios_rd08(bios, volt + 0x4) & 0x2); } break; } return volt; } -u16 +u32 nvbios_volt_entry(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len) { u8 hdr, cnt; - u16 volt = nvbios_volt_table(bios, ver, &hdr, &cnt, len); + u32 volt = nvbios_volt_table(bios, ver, &hdr, &cnt, len); if (volt && idx < cnt) { volt = volt + hdr + (idx * *len); return volt; } - return 0x0000; + return 0; } -u16 +u32 nvbios_volt_entry_parse(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len, struct nvbios_volt_entry *info) { - u16 volt = nvbios_volt_entry(bios, idx, ver, len); + u32 volt = nvbios_volt_entry(bios, idx, ver, len); memset(info, 0x00, sizeof(*info)); switch (!!volt * *ver) { case 0x12: @@ -142,7 +148,10 @@ nvbios_volt_entry_parse(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len, info->vid = nvbios_rd08(bios, volt + 0x01) >> 2; break; case 0x40: + break; case 0x50: + info->voltage = nvbios_rd32(bios, volt) & 0x001fffff; + info->vid = (nvbios_rd32(bios, volt) >> 23) & 0xff; break; } return volt; |