|
@@ -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);
|
|
|
|
- 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;
|
|
|
|
- }
|
|
|
|
|
|
+ /* Assuming the non-bios device should build the voltage table later */
|
|
|
|
+ if (bios)
|
|
|
|
+ nouveau_volt_parse_bios(bios, volt);
|
|
|
|
|
|
if (volt->vid_nr) {
|
|
if (volt->vid_nr) {
|
|
for (i = 0; i < volt->vid_nr; i++) {
|
|
for (i = 0; i < volt->vid_nr; i++) {
|