aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorVince Hsu <vinceh@nvidia.com>2014-12-01 23:50:33 -0500
committerBen Skeggs <bskeggs@redhat.com>2014-12-02 00:44:07 -0500
commit08c7f248be2a17a025e8a0dc1bc9e14231f0ff28 (patch)
tree5c8e97ce8cea386131bd55a8fd80a72fc130b815 /drivers/gpu/drm/nouveau
parentc6f37e0ce658a3a7a272c58334974e36398bab7b (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.c67
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
104static 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
104int 139int
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++) {