Karol Herbst
2016-Mar-16 18:17 UTC
[Nouveau] [PATCH v2 2/2] volt: properly detect entry based voltage tables
there is a field in the voltage table which tells us if the VIDs are taken from the entries or calculated through the header v2: don't break older versions of the table Signed-off-by: Karol Herbst <nouveau at karolherbst.de> --- drm/nouveau/include/nvkm/subdev/bios/volt.h | 5 +-- drm/nouveau/nvkm/subdev/bios/volt.c | 47 ++++++++++++++++------------- drm/nouveau/nvkm/subdev/volt/base.c | 7 +++-- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/drm/nouveau/include/nvkm/subdev/bios/volt.h b/drm/nouveau/include/nvkm/subdev/bios/volt.h index b0df610..0d91c24 100644 --- a/drm/nouveau/include/nvkm/subdev/bios/volt.h +++ b/drm/nouveau/include/nvkm/subdev/bios/volt.h @@ -13,8 +13,9 @@ struct nvbios_volt { u32 base; /* GPIO mode */ - u8 vidmask; - s16 step; + bool entry_based; + u8 vidmask; + s16 step; /* PWM mode */ u32 pwm_freq; diff --git a/drm/nouveau/nvkm/subdev/bios/volt.c b/drm/nouveau/nvkm/subdev/bios/volt.c index 81a47b2..77e7b75 100644 --- a/drm/nouveau/nvkm/subdev/bios/volt.c +++ b/drm/nouveau/nvkm/subdev/bios/volt.c @@ -73,40 +73,45 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, memset(info, 0x00, sizeof(*info)); switch (!!volt * *ver) { case 0x12: - info->type = NVBIOS_VOLT_GPIO; - info->vidmask = nvbios_rd08(bios, volt + 0x04); + info->type = NVBIOS_VOLT_GPIO; + info->vidmask = nvbios_rd08(bios, volt + 0x04); + info->entry_based = true; break; case 0x20: - info->type = NVBIOS_VOLT_GPIO; - info->vidmask = nvbios_rd08(bios, volt + 0x05); + info->type = NVBIOS_VOLT_GPIO; + info->vidmask = nvbios_rd08(bios, volt + 0x05); + info->entry_based = true; break; case 0x30: - info->type = NVBIOS_VOLT_GPIO; - info->vidmask = nvbios_rd08(bios, volt + 0x04); + info->type = NVBIOS_VOLT_GPIO; + info->vidmask = nvbios_rd08(bios, volt + 0x04); + info->entry_based = true; 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->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->entry_based = false; /* XXX: check for it */ /*XXX*/ - info->min = 0; - info->max = info->base; + info->min = 0; + info->max = info->base; break; case 0x50: - info->min = nvbios_rd32(bios, volt + 0x0a); - info->max = nvbios_rd32(bios, volt + 0x0e); - info->base = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff; + info->min = nvbios_rd32(bios, volt + 0x0a); + info->max = nvbios_rd32(bios, volt + 0x0e); + info->base = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff; /* offset 4 seems to be a flag byte */ if (nvbios_rd32(bios, volt + 0x4) & 1) { - info->type = NVBIOS_VOLT_PWM; - info->pwm_freq = nvbios_rd32(bios, volt + 0x5) / 1000; - info->pwm_range = nvbios_rd32(bios, volt + 0x16); + info->type = NVBIOS_VOLT_PWM; + 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->entry_based = !(nvbios_rd08(bios, volt + 0x4) & 0x2); } break; } diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c index 50b5649..4653f3f 100644 --- a/drm/nouveau/nvkm/subdev/volt/base.c +++ b/drm/nouveau/nvkm/subdev/volt/base.c @@ -112,6 +112,7 @@ nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, int condition) static void nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt) { + struct nvkm_subdev *subdev = &bios->subdev; struct nvbios_volt_entry ivid; struct nvbios_volt info; u8 ver, hdr, cnt, len; @@ -119,7 +120,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt) int i; data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info); - if (data && info.vidmask && info.base && info.step) { + if (data && info.vidmask && info.base && info.step && !info.entry_based) { + nvkm_debug(subdev, "found header based VIDs\n"); for (i = 0; i < info.vidmask + 1; i++) { if (info.base >= info.min && info.base <= info.max) { @@ -130,7 +132,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt) info.base += info.step; } volt->vid_mask = info.vidmask; - } else if (data && info.vidmask) { + } else if (data && info.vidmask && info.entry_based) { + nvkm_debug(subdev, "found entry based VIDs\n"); for (i = 0; i < cnt; i++) { data = nvbios_volt_entry_parse(bios, i, &ver, &hdr, &ivid); -- 2.7.3
Martin Peres
2016-Mar-16 22:36 UTC
[Nouveau] [PATCH v2 2/2] volt: properly detect entry based voltage tables
On 16/03/16 20:17, Karol Herbst wrote:> there is a field in the voltage table which tells us if the VIDs are taken from > the entries or calculated through the header > > v2: don't break older versions of the table > > Signed-off-by: Karol Herbst <nouveau at karolherbst.de> > --- > drm/nouveau/include/nvkm/subdev/bios/volt.h | 5 +-- > drm/nouveau/nvkm/subdev/bios/volt.c | 47 ++++++++++++++++------------- > drm/nouveau/nvkm/subdev/volt/base.c | 7 +++-- > 3 files changed, 34 insertions(+), 25 deletions(-) > > diff --git a/drm/nouveau/include/nvkm/subdev/bios/volt.h b/drm/nouveau/include/nvkm/subdev/bios/volt.h > index b0df610..0d91c24 100644 > --- a/drm/nouveau/include/nvkm/subdev/bios/volt.h > +++ b/drm/nouveau/include/nvkm/subdev/bios/volt.h > @@ -13,8 +13,9 @@ struct nvbios_volt { > u32 base; > > /* GPIO mode */ > - u8 vidmask; > - s16 step; > + bool entry_based; > + u8 vidmask; > + s16 step; > > /* PWM mode */ > u32 pwm_freq; > diff --git a/drm/nouveau/nvkm/subdev/bios/volt.c b/drm/nouveau/nvkm/subdev/bios/volt.c > index 81a47b2..77e7b75 100644 > --- a/drm/nouveau/nvkm/subdev/bios/volt.c > +++ b/drm/nouveau/nvkm/subdev/bios/volt.c > @@ -73,40 +73,45 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, > memset(info, 0x00, sizeof(*info)); > switch (!!volt * *ver) { > case 0x12: > - info->type = NVBIOS_VOLT_GPIO; > - info->vidmask = nvbios_rd08(bios, volt + 0x04); > + info->type = NVBIOS_VOLT_GPIO; > + info->vidmask = nvbios_rd08(bios, volt + 0x04); > + info->entry_based = true; > break; > case 0x20: > - info->type = NVBIOS_VOLT_GPIO; > - info->vidmask = nvbios_rd08(bios, volt + 0x05); > + info->type = NVBIOS_VOLT_GPIO; > + info->vidmask = nvbios_rd08(bios, volt + 0x05); > + info->entry_based = true; > break; > case 0x30: > - info->type = NVBIOS_VOLT_GPIO; > - info->vidmask = nvbios_rd08(bios, volt + 0x04); > + info->type = NVBIOS_VOLT_GPIO; > + info->vidmask = nvbios_rd08(bios, volt + 0x04); > + info->entry_based = true; > 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->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->entry_based = false; /* XXX: check for it *//* Overridden when parsing the flag byte */> /*XXX*/ > - info->min = 0; > - info->max = info->base; > + info->min = 0; > + info->max = info->base; > break; > case 0x50: > - info->min = nvbios_rd32(bios, volt + 0x0a); > - info->max = nvbios_rd32(bios, volt + 0x0e); > - info->base = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff; > + info->min = nvbios_rd32(bios, volt + 0x0a); > + info->max = nvbios_rd32(bios, volt + 0x0e); > + info->base = nvbios_rd32(bios, volt + 0x12) & 0x00ffffff; > > /* offset 4 seems to be a flag byte */ > if (nvbios_rd32(bios, volt + 0x4) & 1) { > - info->type = NVBIOS_VOLT_PWM; > - info->pwm_freq = nvbios_rd32(bios, volt + 0x5) / 1000; > - info->pwm_range = nvbios_rd32(bios, volt + 0x16); > + info->type = NVBIOS_VOLT_PWM; > + 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->entry_based = !(nvbios_rd08(bios, volt + 0x4) & 0x2); > } > break; > } > diff --git a/drm/nouveau/nvkm/subdev/volt/base.c b/drm/nouveau/nvkm/subdev/volt/base.c > index 50b5649..4653f3f 100644 > --- a/drm/nouveau/nvkm/subdev/volt/base.c > +++ b/drm/nouveau/nvkm/subdev/volt/base.c > @@ -112,6 +112,7 @@ nvkm_volt_set_id(struct nvkm_volt *volt, u8 id, int condition) > static void > nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt) > { > + struct nvkm_subdev *subdev = &bios->subdev; > struct nvbios_volt_entry ivid; > struct nvbios_volt info; > u8 ver, hdr, cnt, len; > @@ -119,7 +120,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt) > int i; > > data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info); > - if (data && info.vidmask && info.base && info.step) { > + if (data && info.vidmask && info.base && info.step && !info.entry_based) { > + nvkm_debug(subdev, "found header based VIDs\n"); > for (i = 0; i < info.vidmask + 1; i++) { > if (info.base >= info.min && > info.base <= info.max) { > @@ -130,7 +132,8 @@ nvkm_volt_parse_bios(struct nvkm_bios *bios, struct nvkm_volt *volt) > info.base += info.step; > } > volt->vid_mask = info.vidmask; > - } else if (data && info.vidmask) { > + } else if (data && info.vidmask && info.entry_based) { > + nvkm_debug(subdev, "found entry based VIDs\n"); > for (i = 0; i < cnt; i++) { > data = nvbios_volt_entry_parse(bios, i, &ver, &hdr, > &ivid);Both patches are: Reviewed-by: Martin Peres <martin.peres at free.fr>
Maybe Matching Threads
- [PATCH 0/2] Fix some VID parsing in the voltage table version 0x50
- [PATCH 00/19] Volting/Clocking improvements for Fermi and newer
- [PATCH v2 00/22] Volting/Clocking improvements for Fermi and newer
- [PATCH v3 00/29] Volting/Clocking improvements for Fermi and newer
- [PATCH v5 00/20] Engine Reclocking Fixes for Fermi-Maxwell2