mirror of https://gitee.com/openkylin/linux.git
drm/nouveau/volt: allow non-bios voltage scaling
Move the vbios parsing out of init() and call it conditionally if the platform has a vbios. Non-vbios platforms can use the ctor() to init the data structures. Signed-off-by: Vince Hsu <vinceh@nvidia.com> Acked-by: Alexandre Courbot <acourbot@nvidia.com> Acked-by: Martin Peres <martin.peres@free.fr> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
c6f37e0ce6
commit
08c7f248be
|
@ -101,6 +101,41 @@ nouveau_volt_set_id(struct nouveau_volt *volt, u8 id, int condition)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nouveau_volt_parse_bios(struct nouveau_bios *bios,
|
||||||
|
struct nouveau_volt *volt)
|
||||||
|
{
|
||||||
|
struct nvbios_volt_entry ivid;
|
||||||
|
struct nvbios_volt info;
|
||||||
|
u8 ver, hdr, cnt, len;
|
||||||
|
u16 data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
|
||||||
|
if (data && info.vidmask && info.base && info.step) {
|
||||||
|
for (i = 0; i < info.vidmask + 1; i++) {
|
||||||
|
if (info.base >= info.min &&
|
||||||
|
info.base <= info.max) {
|
||||||
|
volt->vid[volt->vid_nr].uv = info.base;
|
||||||
|
volt->vid[volt->vid_nr].vid = i;
|
||||||
|
volt->vid_nr++;
|
||||||
|
}
|
||||||
|
info.base += info.step;
|
||||||
|
}
|
||||||
|
volt->vid_mask = info.vidmask;
|
||||||
|
} else if (data && info.vidmask) {
|
||||||
|
for (i = 0; i < cnt; i++) {
|
||||||
|
data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
|
||||||
|
&ivid);
|
||||||
|
if (data) {
|
||||||
|
volt->vid[volt->vid_nr].uv = ivid.voltage;
|
||||||
|
volt->vid[volt->vid_nr].vid = ivid.vid;
|
||||||
|
volt->vid_nr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
volt->vid_mask = info.vidmask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_nouveau_volt_init(struct nouveau_object *object)
|
_nouveau_volt_init(struct nouveau_object *object)
|
||||||
{
|
{
|
||||||
|
@ -136,10 +171,6 @@ nouveau_volt_create_(struct nouveau_object *parent,
|
||||||
{
|
{
|
||||||
struct nouveau_bios *bios = nouveau_bios(parent);
|
struct nouveau_bios *bios = nouveau_bios(parent);
|
||||||
struct nouveau_volt *volt;
|
struct nouveau_volt *volt;
|
||||||
struct nvbios_volt_entry ivid;
|
|
||||||
struct nvbios_volt info;
|
|
||||||
u8 ver, hdr, cnt, len;
|
|
||||||
u16 data;
|
|
||||||
int ret, i;
|
int ret, i;
|
||||||
|
|
||||||
ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT",
|
ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT",
|
||||||
|
@ -152,31 +183,9 @@ nouveau_volt_create_(struct nouveau_object *parent,
|
||||||
volt->set = nouveau_volt_set;
|
volt->set = nouveau_volt_set;
|
||||||
volt->set_id = nouveau_volt_set_id;
|
volt->set_id = nouveau_volt_set_id;
|
||||||
|
|
||||||
data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
|
/* Assuming the non-bios device should build the voltage table later */
|
||||||
if (data && info.vidmask && info.base && info.step) {
|
if (bios)
|
||||||
for (i = 0; i < info.vidmask + 1; i++) {
|
nouveau_volt_parse_bios(bios, volt);
|
||||||
if (info.base >= info.min &&
|
|
||||||
info.base <= info.max) {
|
|
||||||
volt->vid[volt->vid_nr].uv = info.base;
|
|
||||||
volt->vid[volt->vid_nr].vid = i;
|
|
||||||
volt->vid_nr++;
|
|
||||||
}
|
|
||||||
info.base += info.step;
|
|
||||||
}
|
|
||||||
volt->vid_mask = info.vidmask;
|
|
||||||
} else
|
|
||||||
if (data && info.vidmask) {
|
|
||||||
for (i = 0; i < cnt; i++) {
|
|
||||||
data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
|
|
||||||
&ivid);
|
|
||||||
if (data) {
|
|
||||||
volt->vid[volt->vid_nr].uv = ivid.voltage;
|
|
||||||
volt->vid[volt->vid_nr].vid = ivid.vid;
|
|
||||||
volt->vid_nr++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
volt->vid_mask = info.vidmask;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (volt->vid_nr) {
|
if (volt->vid_nr) {
|
||||||
for (i = 0; i < volt->vid_nr; i++) {
|
for (i = 0; i < volt->vid_nr; i++) {
|
||||||
|
|
Loading…
Reference in New Issue