diff options
author | Vince Hsu <vinceh@nvidia.com> | 2014-12-01 23:50:33 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-12-02 00:44:07 -0500 |
commit | 08c7f248be2a17a025e8a0dc1bc9e14231f0ff28 (patch) | |
tree | 5c8e97ce8cea386131bd55a8fd80a72fc130b815 /drivers/gpu/drm/nouveau | |
parent | c6f37e0ce658a3a7a272c58334974e36398bab7b (diff) |
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/volt/base.c | 67 |
1 files changed, 38 insertions, 29 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c b/drivers/gpu/drm/nouveau/core/subdev/volt/base.c index 32794a999106..26ccd8df193f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/volt/base.c | |||
@@ -101,6 +101,41 @@ nouveau_volt_set_id(struct nouveau_volt *volt, u8 id, int condition) | |||
101 | return ret; | 101 | return ret; |
102 | } | 102 | } |
103 | 103 | ||
104 | static void nouveau_volt_parse_bios(struct nouveau_bios *bios, | ||
105 | struct nouveau_volt *volt) | ||
106 | { | ||
107 | struct nvbios_volt_entry ivid; | ||
108 | struct nvbios_volt info; | ||
109 | u8 ver, hdr, cnt, len; | ||
110 | u16 data; | ||
111 | int i; | ||
112 | |||
113 | data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info); | ||
114 | if (data && info.vidmask && info.base && info.step) { | ||
115 | for (i = 0; i < info.vidmask + 1; i++) { | ||
116 | if (info.base >= info.min && | ||
117 | info.base <= info.max) { | ||
118 | volt->vid[volt->vid_nr].uv = info.base; | ||
119 | volt->vid[volt->vid_nr].vid = i; | ||
120 | volt->vid_nr++; | ||
121 | } | ||
122 | info.base += info.step; | ||
123 | } | ||
124 | volt->vid_mask = info.vidmask; | ||
125 | } else if (data && info.vidmask) { | ||
126 | for (i = 0; i < cnt; i++) { | ||
127 | data = nvbios_volt_entry_parse(bios, i, &ver, &hdr, | ||
128 | &ivid); | ||
129 | if (data) { | ||
130 | volt->vid[volt->vid_nr].uv = ivid.voltage; | ||
131 | volt->vid[volt->vid_nr].vid = ivid.vid; | ||
132 | volt->vid_nr++; | ||
133 | } | ||
134 | } | ||
135 | volt->vid_mask = info.vidmask; | ||
136 | } | ||
137 | } | ||
138 | |||
104 | int | 139 | int |
105 | _nouveau_volt_init(struct nouveau_object *object) | 140 | _nouveau_volt_init(struct nouveau_object *object) |
106 | { | 141 | { |
@@ -136,10 +171,6 @@ nouveau_volt_create_(struct nouveau_object *parent, | |||
136 | { | 171 | { |
137 | struct nouveau_bios *bios = nouveau_bios(parent); | 172 | struct nouveau_bios *bios = nouveau_bios(parent); |
138 | struct nouveau_volt *volt; | 173 | struct nouveau_volt *volt; |
139 | struct nvbios_volt_entry ivid; | ||
140 | struct nvbios_volt info; | ||
141 | u8 ver, hdr, cnt, len; | ||
142 | u16 data; | ||
143 | int ret, i; | 174 | int ret, i; |
144 | 175 | ||
145 | ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT", | 176 | ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT", |
@@ -152,31 +183,9 @@ nouveau_volt_create_(struct nouveau_object *parent, | |||
152 | volt->set = nouveau_volt_set; | 183 | volt->set = nouveau_volt_set; |
153 | volt->set_id = nouveau_volt_set_id; | 184 | volt->set_id = nouveau_volt_set_id; |
154 | 185 | ||
155 | data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info); | 186 | /* Assuming the non-bios device should build the voltage table later */ |
156 | if (data && info.vidmask && info.base && info.step) { | 187 | if (bios) |
157 | for (i = 0; i < info.vidmask + 1; i++) { | 188 | nouveau_volt_parse_bios(bios, volt); |
158 | if (info.base >= info.min && | ||
159 | info.base <= info.max) { | ||
160 | volt->vid[volt->vid_nr].uv = info.base; | ||
161 | volt->vid[volt->vid_nr].vid = i; | ||
162 | volt->vid_nr++; | ||
163 | } | ||
164 | info.base += info.step; | ||
165 | } | ||
166 | volt->vid_mask = info.vidmask; | ||
167 | } else | ||
168 | if (data && info.vidmask) { | ||
169 | for (i = 0; i < cnt; i++) { | ||
170 | data = nvbios_volt_entry_parse(bios, i, &ver, &hdr, | ||
171 | &ivid); | ||
172 | if (data) { | ||
173 | volt->vid[volt->vid_nr].uv = ivid.voltage; | ||
174 | volt->vid[volt->vid_nr].vid = ivid.vid; | ||
175 | volt->vid_nr++; | ||
176 | } | ||
177 | } | ||
178 | volt->vid_mask = info.vidmask; | ||
179 | } | ||
180 | 189 | ||
181 | if (volt->vid_nr) { | 190 | if (volt->vid_nr) { |
182 | for (i = 0; i < volt->vid_nr; i++) { | 191 | for (i = 0; i < volt->vid_nr; i++) { |