aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-07-10 03:26:46 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-10-02 23:12:47 -0400
commit70790f4f819875e8f390871fd15bbbf823f28e1b (patch)
tree47949ac5a0af23a9fe1ace1ac5fd8b8823b8e055 /drivers/gpu/drm
parent8aceb7de47ea2491abc1a577dc875b19e9947a54 (diff)
drm/nouveau/clock: pull in the implementation from all over the place
Still missing the main bits we use to change performance levels, I'll get to it after all the hard yakka has been finished. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/Makefile4
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h77
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/clock.h21
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/vga.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/pll.c417
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c296
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c12
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c44
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c34
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c33
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pll.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c242
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c (renamed from drivers/gpu/drm/nouveau/nv50_calc.c)69
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c519
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h52
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_calc.c216
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_compat.c75
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_compat.h12
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h31
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hw.c280
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_hw.h10
-rw-r--r--drivers/gpu/drm/nouveau/nv04_crtc.c4
-rw-r--r--drivers/gpu/drm/nouveau/nv04_pm.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv40_pm.c12
-rw-r--r--drivers/gpu/drm/nouveau/nv50_crtc.c50
-rw-r--r--drivers/gpu/drm/nouveau/nv50_pm.c12
-rw-r--r--drivers/gpu/drm/nouveau/nva3_pm.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvc0_pm.c4
28 files changed, 1328 insertions, 1213 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile
index 2964d71d3996..2574fd35122a 100644
--- a/drivers/gpu/drm/nouveau/Makefile
+++ b/drivers/gpu/drm/nouveau/Makefile
@@ -23,11 +23,14 @@ nouveau-y += core/subdev/bios/bit.o
23nouveau-y += core/subdev/bios/dcb.o 23nouveau-y += core/subdev/bios/dcb.o
24nouveau-y += core/subdev/bios/gpio.o 24nouveau-y += core/subdev/bios/gpio.o
25nouveau-y += core/subdev/bios/i2c.o 25nouveau-y += core/subdev/bios/i2c.o
26nouveau-y += core/subdev/bios/pll.o
26nouveau-y += core/subdev/clock/nv04.o 27nouveau-y += core/subdev/clock/nv04.o
27nouveau-y += core/subdev/clock/nv40.o 28nouveau-y += core/subdev/clock/nv40.o
28nouveau-y += core/subdev/clock/nv50.o 29nouveau-y += core/subdev/clock/nv50.o
29nouveau-y += core/subdev/clock/nva3.o 30nouveau-y += core/subdev/clock/nva3.o
30nouveau-y += core/subdev/clock/nvc0.o 31nouveau-y += core/subdev/clock/nvc0.o
32nouveau-y += core/subdev/clock/pllnv04.o
33nouveau-y += core/subdev/clock/pllnva3.o
31nouveau-y += core/subdev/device/base.o 34nouveau-y += core/subdev/device/base.o
32nouveau-y += core/subdev/device/nv04.o 35nouveau-y += core/subdev/device/nv04.o
33nouveau-y += core/subdev/device/nv10.o 36nouveau-y += core/subdev/device/nv10.o
@@ -114,7 +117,6 @@ nouveau-y += nouveau_drm.o nouveau_compat.o \
114 nv50_cursor.o nv50_display.o \ 117 nv50_cursor.o nv50_display.o \
115 nvd0_display.o \ 118 nvd0_display.o \
116 nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o \ 119 nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o \
117 nv50_calc.o \
118 nv04_pm.o nv40_pm.o nv50_pm.o nva3_pm.o nvc0_pm.o \ 120 nv04_pm.o nv40_pm.o nv50_pm.o nva3_pm.o nvc0_pm.o \
119 nouveau_prime.o 121 nouveau_prime.o
120 122
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h
new file mode 100644
index 000000000000..c345097592f2
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pll.h
@@ -0,0 +1,77 @@
1#ifndef __NVBIOS_PLL_H__
2#define __NVBIOS_PLL_H__
3
4/*XXX: kill me */
5struct nouveau_pll_vals {
6 union {
7 struct {
8#ifdef __BIG_ENDIAN
9 uint8_t N1, M1, N2, M2;
10#else
11 uint8_t M1, N1, M2, N2;
12#endif
13 };
14 struct {
15 uint16_t NM1, NM2;
16 } __attribute__((packed));
17 };
18 int log2P;
19
20 int refclk;
21};
22
23struct nouveau_bios;
24
25/* these match types in pll limits table version 0x40,
26 * nouveau uses them on all chipsets internally where a
27 * specific pll needs to be referenced, but the exact
28 * register isn't known.
29 */
30enum nvbios_pll_type {
31 PLL_CORE = 0x01,
32 PLL_SHADER = 0x02,
33 PLL_UNK03 = 0x03,
34 PLL_MEMORY = 0x04,
35 PLL_VDEC = 0x05,
36 PLL_UNK40 = 0x40,
37 PLL_UNK41 = 0x41,
38 PLL_UNK42 = 0x42,
39 PLL_VPLL0 = 0x80,
40 PLL_VPLL1 = 0x81,
41 PLL_MAX = 0xff
42};
43
44struct nvbios_pll {
45 enum nvbios_pll_type type;
46 u32 reg;
47 u32 refclk;
48
49 u8 min_p;
50 u8 max_p;
51 u8 bias_p;
52
53 /*
54 * for most pre nv50 cards setting a log2P of 7 (the common max_log2p
55 * value) is no different to 6 (at least for vplls) so allowing the MNP
56 * calc to use 7 causes the generated clock to be out by a factor of 2.
57 * however, max_log2p cannot be fixed-up during parsing as the
58 * unmodified max_log2p value is still needed for setting mplls, hence
59 * an additional max_usable_log2p member
60 */
61 u8 max_p_usable;
62
63 struct {
64 u32 min_freq;
65 u32 max_freq;
66 u32 min_inputfreq;
67 u32 max_inputfreq;
68 u8 min_m;
69 u8 max_m;
70 u8 min_n;
71 u8 max_n;
72 } vco1, vco2;
73};
74
75int nvbios_pll_parse(struct nouveau_bios *, u32 type, struct nvbios_pll *);
76
77#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
index 137c4598a1b6..39e73b91d360 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h
@@ -4,9 +4,21 @@
4#include <core/device.h> 4#include <core/device.h>
5#include <core/subdev.h> 5#include <core/subdev.h>
6 6
7struct nouveau_pll_vals;
8struct nvbios_pll;
9
7struct nouveau_clock { 10struct nouveau_clock {
8 struct nouveau_subdev base; 11 struct nouveau_subdev base;
9 void (*pll_set)(struct nouveau_clock *, u32 type, u32 freq); 12
13 int (*pll_set)(struct nouveau_clock *, u32 type, u32 freq);
14
15 /*XXX: die, these are here *only* to support the completely
16 * bat-shit insane what-was-nouveau_hw.c code
17 */
18 int (*pll_calc)(struct nouveau_clock *, struct nvbios_pll *,
19 int clk, struct nouveau_pll_vals *pv);
20 int (*pll_prog)(struct nouveau_clock *, u32 reg1,
21 struct nouveau_pll_vals *pv);
10}; 22};
11 23
12static inline struct nouveau_clock * 24static inline struct nouveau_clock *
@@ -37,4 +49,11 @@ extern struct nouveau_oclass nv50_clock_oclass;
37extern struct nouveau_oclass nva3_clock_oclass; 49extern struct nouveau_oclass nva3_clock_oclass;
38extern struct nouveau_oclass nvc0_clock_oclass; 50extern struct nouveau_oclass nvc0_clock_oclass;
39 51
52int nv04_clock_pll_set(struct nouveau_clock *, u32 type, u32 freq);
53int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *,
54 int clk, struct nouveau_pll_vals *);
55int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1,
56 struct nouveau_pll_vals *);
57
58
40#endif 59#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/vga.h b/drivers/gpu/drm/nouveau/core/include/subdev/vga.h
index d81df1ae442d..fee09ad818e4 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/vga.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/vga.h
@@ -1,6 +1,8 @@
1#ifndef __NOUVEAU_VGA_H__ 1#ifndef __NOUVEAU_VGA_H__
2#define __NOUVEAU_VGA_H__ 2#define __NOUVEAU_VGA_H__
3 3
4#include <core/os.h>
5
4/* access to various legacy io ports */ 6/* access to various legacy io ports */
5u8 nv_rdport(void *obj, int head, u16 port); 7u8 nv_rdport(void *obj, int head, u16 port);
6void nv_wrport(void *obj, int head, u16 port, u8 value); 8void nv_wrport(void *obj, int head, u16 port, u8 value);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
new file mode 100644
index 000000000000..5e5f4cddae3c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
@@ -0,0 +1,417 @@
1/*
2 * Copyright 2005-2006 Erik Waling
3 * Copyright 2006 Stephane Marchesin
4 * Copyright 2007-2009 Stuart Bennett
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
21 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#include <subdev/vga.h>
26#include <subdev/bios.h>
27#include <subdev/bios/bit.h>
28#include <subdev/bios/bmp.h>
29#include <subdev/bios/pll.h>
30
31struct pll_mapping {
32 u8 type;
33 u32 reg;
34};
35
36static struct pll_mapping
37nv04_pll_mapping[] = {
38 { PLL_CORE , 0x680500 },
39 { PLL_MEMORY, 0x680504 },
40 { PLL_VPLL0 , 0x680508 },
41 { PLL_VPLL1 , 0x680520 },
42 {}
43};
44
45static struct pll_mapping
46nv40_pll_mapping[] = {
47 { PLL_CORE , 0x004000 },
48 { PLL_MEMORY, 0x004020 },
49 { PLL_VPLL0 , 0x680508 },
50 { PLL_VPLL1 , 0x680520 },
51 {}
52};
53
54static struct pll_mapping
55nv50_pll_mapping[] = {
56 { PLL_CORE , 0x004028 },
57 { PLL_SHADER, 0x004020 },
58 { PLL_UNK03 , 0x004000 },
59 { PLL_MEMORY, 0x004008 },
60 { PLL_UNK40 , 0x00e810 },
61 { PLL_UNK41 , 0x00e818 },
62 { PLL_UNK42 , 0x00e824 },
63 { PLL_VPLL0 , 0x614100 },
64 { PLL_VPLL1 , 0x614900 },
65 {}
66};
67
68static struct pll_mapping
69nv84_pll_mapping[] = {
70 { PLL_CORE , 0x004028 },
71 { PLL_SHADER, 0x004020 },
72 { PLL_MEMORY, 0x004008 },
73 { PLL_VDEC , 0x004030 },
74 { PLL_UNK41 , 0x00e818 },
75 { PLL_VPLL0 , 0x614100 },
76 { PLL_VPLL1 , 0x614900 },
77 {}
78};
79
80static u16
81pll_limits_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
82{
83 struct bit_entry bit_C;
84
85 if (!bit_entry(bios, 'C', &bit_C) && bit_C.length >= 10) {
86 u16 data = nv_ro16(bios, bit_C.offset + 8);
87 if (data) {
88 *ver = nv_ro08(bios, data + 0);
89 *hdr = nv_ro08(bios, data + 1);
90 *len = nv_ro08(bios, data + 2);
91 *cnt = nv_ro08(bios, data + 3);
92 return data;
93 }
94 }
95
96 if (bmp_version(bios) >= 0x0524) {
97 u16 data = nv_ro16(bios, bios->bmp_offset + 142);
98 if (data) {
99 *ver = nv_ro08(bios, data + 0);
100 *hdr = 1;
101 *cnt = 1;
102 *len = 0x18;
103 return data;
104 }
105 }
106
107 *ver = 0x00;
108 return 0x0000;
109}
110
111static struct pll_mapping *
112pll_map(struct nouveau_bios *bios)
113{
114 switch (nv_device(bios)->card_type) {
115 case NV_04:
116 case NV_10:
117 case NV_20:
118 case NV_30:
119 return nv04_pll_mapping;
120 break;
121 case NV_40:
122 return nv40_pll_mapping;
123 case NV_50:
124 if (nv_device(bios)->chipset == 0x50)
125 return nv50_pll_mapping;
126 else
127 if (nv_device(bios)->chipset < 0xa3 ||
128 nv_device(bios)->chipset == 0xaa ||
129 nv_device(bios)->chipset == 0xac)
130 return nv84_pll_mapping;
131 default:
132 return NULL;
133 }
134}
135
136static u16
137pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
138{
139 struct pll_mapping *map;
140 u8 hdr, cnt;
141 u16 data;
142
143 data = pll_limits_table(bios, ver, &hdr, &cnt, len);
144 if (data && *ver >= 0x30) {
145 data += hdr;
146 while (cnt--) {
147 if (nv_ro32(bios, data + 3) == reg) {
148 *type = nv_ro08(bios, data + 0);
149 return data;
150 }
151 data += *len;
152 }
153 return 0x0000;
154 }
155
156 map = pll_map(bios);
157 while (map->reg) {
158 if (map->reg == reg && *ver >= 0x20) {
159 u16 addr = (data += hdr);
160 while (cnt--) {
161 if (nv_ro32(bios, data) == map->reg) {
162 *type = map->type;
163 return data;
164 }
165 data += *len;
166 }
167 return addr;
168 } else
169 if (map->reg == reg) {
170 *type = map->type;
171 return data + 1;
172 }
173 map++;
174 }
175
176 return 0x0000;
177}
178
179static u16
180pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
181{
182 struct pll_mapping *map;
183 u8 hdr, cnt;
184 u16 data;
185
186 data = pll_limits_table(bios, ver, &hdr, &cnt, len);
187 if (data && *ver >= 0x30) {
188 data += hdr;
189 while (cnt--) {
190 if (nv_ro08(bios, data + 0) == type) {
191 *reg = nv_ro32(bios, data + 3);
192 return data;
193 }
194 data += *len;
195 }
196 return 0x0000;
197 }
198
199 map = pll_map(bios);
200 while (map->reg) {
201 if (map->type == type && *ver >= 0x20) {
202 u16 addr = (data += hdr);
203 while (cnt--) {
204 if (nv_ro32(bios, data) == map->reg) {
205 *reg = map->reg;
206 return data;
207 }
208 data += *len;
209 }
210 return addr;
211 } else
212 if (map->type == type) {
213 *reg = map->reg;
214 return data + 1;
215 }
216 map++;
217 }
218
219 return 0x0000;
220}
221
222int
223nvbios_pll_parse(struct nouveau_bios *bios, u32 type, struct nvbios_pll *info)
224{
225 u8 ver, len;
226 u32 reg = type;
227 u16 data;
228
229 if (type > PLL_MAX) {
230 reg = type;
231 data = pll_map_reg(bios, reg, &type, &ver, &len);
232 } else {
233 data = pll_map_type(bios, type, &reg, &ver, &len);
234 }
235
236 if (ver && !data)
237 return -ENOENT;
238
239 memset(info, 0, sizeof(*info));
240 info->type = type;
241 info->reg = reg;
242
243 switch (ver) {
244 case 0x00:
245 break;
246 case 0x10:
247 case 0x11:
248 info->vco1.min_freq = nv_ro32(bios, data + 0);
249 info->vco1.max_freq = nv_ro32(bios, data + 4);
250 info->vco2.min_freq = nv_ro32(bios, data + 8);
251 info->vco2.max_freq = nv_ro32(bios, data + 12);
252 info->vco1.min_inputfreq = nv_ro32(bios, data + 16);
253 info->vco2.min_inputfreq = nv_ro32(bios, data + 20);
254 info->vco1.max_inputfreq = INT_MAX;
255 info->vco2.max_inputfreq = INT_MAX;
256
257 info->max_p = 0x7;
258 info->max_p_usable = 0x6;
259
260 /* these values taken from nv30/31/36 */
261 switch (bios->version.chip) {
262 case 0x36:
263 info->vco1.min_n = 0x5;
264 break;
265 default:
266 info->vco1.min_n = 0x1;
267 break;
268 }
269 info->vco1.max_n = 0xff;
270 info->vco1.min_m = 0x1;
271 info->vco1.max_m = 0xd;
272
273 /*
274 * On nv30, 31, 36 (i.e. all cards with two stage PLLs with this
275 * table version (apart from nv35)), N2 is compared to
276 * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and
277 * save a comparison
278 */
279 info->vco2.min_n = 0x4;
280 switch (bios->version.chip) {
281 case 0x30:
282 case 0x35:
283 info->vco2.max_n = 0x1f;
284 break;
285 default:
286 info->vco2.max_n = 0x28;
287 break;
288 }
289 info->vco2.min_m = 0x1;
290 info->vco2.max_m = 0x4;
291 break;
292 case 0x20:
293 case 0x21:
294 info->vco1.min_freq = nv_ro16(bios, data + 4) * 1000;
295 info->vco1.max_freq = nv_ro16(bios, data + 6) * 1000;
296 info->vco2.min_freq = nv_ro16(bios, data + 8) * 1000;
297 info->vco2.max_freq = nv_ro16(bios, data + 10) * 1000;
298 info->vco1.min_inputfreq = nv_ro16(bios, data + 12) * 1000;
299 info->vco2.min_inputfreq = nv_ro16(bios, data + 14) * 1000;
300 info->vco1.max_inputfreq = nv_ro16(bios, data + 16) * 1000;
301 info->vco2.max_inputfreq = nv_ro16(bios, data + 18) * 1000;
302 info->vco1.min_n = nv_ro08(bios, data + 20);
303 info->vco1.max_n = nv_ro08(bios, data + 21);
304 info->vco1.min_m = nv_ro08(bios, data + 22);
305 info->vco1.max_m = nv_ro08(bios, data + 23);
306 info->vco2.min_n = nv_ro08(bios, data + 24);
307 info->vco2.max_n = nv_ro08(bios, data + 25);
308 info->vco2.min_m = nv_ro08(bios, data + 26);
309 info->vco2.max_m = nv_ro08(bios, data + 27);
310
311 info->max_p = nv_ro08(bios, data + 29);
312 info->max_p_usable = info->max_p;
313 if (bios->version.chip < 0x60)
314 info->max_p_usable = 0x6;
315 info->bias_p = nv_ro08(bios, data + 30);
316
317 if (len > 0x22)
318 info->refclk = nv_ro32(bios, data + 31);
319 break;
320 case 0x30:
321 data = nv_ro16(bios, data + 1);
322
323 info->vco1.min_freq = nv_ro16(bios, data + 0) * 1000;
324 info->vco1.max_freq = nv_ro16(bios, data + 2) * 1000;
325 info->vco2.min_freq = nv_ro16(bios, data + 4) * 1000;
326 info->vco2.max_freq = nv_ro16(bios, data + 6) * 1000;
327 info->vco1.min_inputfreq = nv_ro16(bios, data + 8) * 1000;
328 info->vco2.min_inputfreq = nv_ro16(bios, data + 10) * 1000;
329 info->vco1.max_inputfreq = nv_ro16(bios, data + 12) * 1000;
330 info->vco2.max_inputfreq = nv_ro16(bios, data + 14) * 1000;
331 info->vco1.min_n = nv_ro08(bios, data + 16);
332 info->vco1.max_n = nv_ro08(bios, data + 17);
333 info->vco1.min_m = nv_ro08(bios, data + 18);
334 info->vco1.max_m = nv_ro08(bios, data + 19);
335 info->vco2.min_n = nv_ro08(bios, data + 20);
336 info->vco2.max_n = nv_ro08(bios, data + 21);
337 info->vco2.min_m = nv_ro08(bios, data + 22);
338 info->vco2.max_m = nv_ro08(bios, data + 23);
339 info->max_p_usable = info->max_p = nv_ro08(bios, data + 25);
340 info->bias_p = nv_ro08(bios, data + 27);
341 info->refclk = nv_ro32(bios, data + 28);
342 break;
343 case 0x40:
344 info->refclk = nv_ro16(bios, data + 9) * 1000;
345 data = nv_ro16(bios, data + 1);
346
347 info->vco1.min_freq = nv_ro16(bios, data + 0) * 1000;
348 info->vco1.max_freq = nv_ro16(bios, data + 2) * 1000;
349 info->vco1.min_inputfreq = nv_ro16(bios, data + 4) * 1000;
350 info->vco1.max_inputfreq = nv_ro16(bios, data + 6) * 1000;
351 info->vco1.min_m = nv_ro08(bios, data + 8);
352 info->vco1.max_m = nv_ro08(bios, data + 9);
353 info->vco1.min_n = nv_ro08(bios, data + 10);
354 info->vco1.max_n = nv_ro08(bios, data + 11);
355 info->min_p = nv_ro08(bios, data + 12);
356 info->max_p = nv_ro08(bios, data + 13);
357 break;
358 default:
359 nv_error(bios, "unknown pll limits version 0x%02x\n", ver);
360 return -EINVAL;
361 }
362
363 if (!info->refclk) {
364 info->refclk = nv_device(bios)->crystal;
365 if (bios->version.chip == 0x51) {
366 u32 sel_clk = nv_rd32(bios, 0x680524);
367 if ((info->reg == 0x680508 && sel_clk & 0x20) ||
368 (info->reg == 0x680520 && sel_clk & 0x80)) {
369 if (nv_rdvgac(bios, 0, 0x27) < 0xa3)
370 info->refclk = 200000;
371 else
372 info->refclk = 25000;
373 }
374 }
375 }
376
377 /*
378 * By now any valid limit table ought to have set a max frequency for
379 * vco1, so if it's zero it's either a pre limit table bios, or one
380 * with an empty limit table (seen on nv18)
381 */
382 if (!info->vco1.max_freq) {
383 info->vco1.max_freq = nv_ro32(bios, bios->bmp_offset + 67);
384 info->vco1.min_freq = nv_ro32(bios, bios->bmp_offset + 71);
385 if (bmp_version(bios) < 0x0506) {
386 info->vco1.max_freq = 256000;
387 info->vco1.min_freq = 128000;
388 }
389
390 info->vco1.min_inputfreq = 0;
391 info->vco1.max_inputfreq = INT_MAX;
392 info->vco1.min_n = 0x1;
393 info->vco1.max_n = 0xff;
394 info->vco1.min_m = 0x1;
395
396 if (nv_device(bios)->crystal == 13500) {
397 /* nv05 does this, nv11 doesn't, nv10 unknown */
398 if (bios->version.chip < 0x11)
399 info->vco1.min_m = 0x7;
400 info->vco1.max_m = 0xd;
401 } else {
402 if (bios->version.chip < 0x11)
403 info->vco1.min_m = 0x8;
404 info->vco1.max_m = 0xe;
405 }
406
407 if (bios->version.chip < 0x17 ||
408 bios->version.chip == 0x1a ||
409 bios->version.chip == 0x20)
410 info->max_p = 4;
411 else
412 info->max_p = 5;
413 info->max_p_usable = info->max_p;
414 }
415
416 return 0;
417}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
index 3a3b3b149690..b7fd1151166e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c
@@ -23,17 +23,309 @@
23 */ 23 */
24 24
25#include <subdev/clock.h> 25#include <subdev/clock.h>
26#include <subdev/bios.h>
27#include <subdev/bios/pll.h>
28
29#include "pll.h"
26 30
27struct nv04_clock_priv { 31struct nv04_clock_priv {
28 struct nouveau_clock base; 32 struct nouveau_clock base;
29}; 33};
30 34
35static int
36powerctrl_1_shift(int chip_version, int reg)
37{
38 int shift = -4;
39
40 if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20)
41 return shift;
42
43 switch (reg) {
44 case 0x680520:
45 shift += 4;
46 case 0x680508:
47 shift += 4;
48 case 0x680504:
49 shift += 4;
50 case 0x680500:
51 shift += 4;
52 }
53
54 /*
55 * the shift for vpll regs is only used for nv3x chips with a single
56 * stage pll
57 */
58 if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 ||
59 chip_version == 0x36 || chip_version >= 0x40))
60 shift = -4;
61
62 return shift;
63}
64
31static void 65static void
66setPLL_single(struct nv04_clock_priv *priv, u32 reg,
67 struct nouveau_pll_vals *pv)
68{
69 int chip_version = nouveau_bios(priv)->version.chip;
70 uint32_t oldpll = nv_rd32(priv, reg);
71 int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
72 uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
73 uint32_t saved_powerctrl_1 = 0;
74 int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg);
75
76 if (oldpll == pll)
77 return; /* already set */
78
79 if (shift_powerctrl_1 >= 0) {
80 saved_powerctrl_1 = nv_rd32(priv, 0x001584);
81 nv_wr32(priv, 0x001584,
82 (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
83 1 << shift_powerctrl_1);
84 }
85
86 if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1))
87 /* upclock -- write new post divider first */
88 nv_wr32(priv, reg, pv->log2P << 16 | (oldpll & 0xffff));
89 else
90 /* downclock -- write new NM first */
91 nv_wr32(priv, reg, (oldpll & 0xffff0000) | pv->NM1);
92
93 if (chip_version < 0x17 && chip_version != 0x11)
94 /* wait a bit on older chips */
95 msleep(64);
96 nv_rd32(priv, reg);
97
98 /* then write the other half as well */
99 nv_wr32(priv, reg, pll);
100
101 if (shift_powerctrl_1 >= 0)
102 nv_wr32(priv, 0x001584, saved_powerctrl_1);
103}
104
105static uint32_t
106new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
107{
108 bool head_a = (reg1 == 0x680508);
109
110 if (ss) /* single stage pll mode */
111 ramdac580 |= head_a ? 0x00000100 : 0x10000000;
112 else
113 ramdac580 &= head_a ? 0xfffffeff : 0xefffffff;
114
115 return ramdac580;
116}
117
118static void
119setPLL_double_highregs(struct nv04_clock_priv *priv, u32 reg1,
120 struct nouveau_pll_vals *pv)
121{
122 int chip_version = nouveau_bios(priv)->version.chip;
123 bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
124 uint32_t reg2 = reg1 + ((reg1 == 0x680520) ? 0x5c : 0x70);
125 uint32_t oldpll1 = nv_rd32(priv, reg1);
126 uint32_t oldpll2 = !nv3035 ? nv_rd32(priv, reg2) : 0;
127 uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1;
128 uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2;
129 uint32_t oldramdac580 = 0, ramdac580 = 0;
130 bool single_stage = !pv->NM2 || pv->N2 == pv->M2; /* nv41+ only */
131 uint32_t saved_powerctrl_1 = 0, savedc040 = 0;
132 int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1);
133
134 /* model specific additions to generic pll1 and pll2 set up above */
135 if (nv3035) {
136 pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 |
137 (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4;
138 pll2 = 0;
139 }
140 if (chip_version > 0x40 && reg1 >= 0x680508) { /* !nv40 */
141 oldramdac580 = nv_rd32(priv, 0x680580);
142 ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580);
143 if (oldramdac580 != ramdac580)
144 oldpll1 = ~0; /* force mismatch */
145 if (single_stage)
146 /* magic value used by nvidia in single stage mode */
147 pll2 |= 0x011f;
148 }
149 if (chip_version > 0x70)
150 /* magic bits set by the blob (but not the bios) on g71-73 */
151 pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28;
152
153 if (oldpll1 == pll1 && oldpll2 == pll2)
154 return; /* already set */
155
156 if (shift_powerctrl_1 >= 0) {
157 saved_powerctrl_1 = nv_rd32(priv, 0x001584);
158 nv_wr32(priv, 0x001584,
159 (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
160 1 << shift_powerctrl_1);
161 }
162
163 if (chip_version >= 0x40) {
164 int shift_c040 = 14;
165
166 switch (reg1) {
167 case 0x680504:
168 shift_c040 += 2;
169 case 0x680500:
170 shift_c040 += 2;
171 case 0x680520:
172 shift_c040 += 2;
173 case 0x680508:
174 shift_c040 += 2;
175 }
176
177 savedc040 = nv_rd32(priv, 0xc040);
178 if (shift_c040 != 14)
179 nv_wr32(priv, 0xc040, savedc040 & ~(3 << shift_c040));
180 }
181
182 if (oldramdac580 != ramdac580)
183 nv_wr32(priv, 0x680580, ramdac580);
184
185 if (!nv3035)
186 nv_wr32(priv, reg2, pll2);
187 nv_wr32(priv, reg1, pll1);
188
189 if (shift_powerctrl_1 >= 0)
190 nv_wr32(priv, 0x001584, saved_powerctrl_1);
191 if (chip_version >= 0x40)
192 nv_wr32(priv, 0xc040, savedc040);
193}
194
195static void
196setPLL_double_lowregs(struct nv04_clock_priv *priv, u32 NMNMreg,
197 struct nouveau_pll_vals *pv)
198{
199 /* When setting PLLs, there is a merry game of disabling and enabling
200 * various bits of hardware during the process. This function is a
201 * synthesis of six nv4x traces, nearly each card doing a subtly
202 * different thing. With luck all the necessary bits for each card are
203 * combined herein. Without luck it deviates from each card's formula
204 * so as to not work on any :)
205 */
206
207 uint32_t Preg = NMNMreg - 4;
208 bool mpll = Preg == 0x4020;
209 uint32_t oldPval = nv_rd32(priv, Preg);
210 uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
211 uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) |
212 0xc << 28 | pv->log2P << 16;
213 uint32_t saved4600 = 0;
214 /* some cards have different maskc040s */
215 uint32_t maskc040 = ~(3 << 14), savedc040;
216 bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
217
218 if (nv_rd32(priv, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
219 return;
220
221 if (Preg == 0x4000)
222 maskc040 = ~0x333;
223 if (Preg == 0x4058)
224 maskc040 = ~(0xc << 24);
225
226 if (mpll) {
227 struct nvbios_pll info;
228 uint8_t Pval2;
229
230 if (nvbios_pll_parse(nouveau_bios(priv), Preg, &info))
231 return;
232
233 Pval2 = pv->log2P + info.bias_p;
234 if (Pval2 > info.max_p)
235 Pval2 = info.max_p;
236 Pval |= 1 << 28 | Pval2 << 20;
237
238 saved4600 = nv_rd32(priv, 0x4600);
239 nv_wr32(priv, 0x4600, saved4600 | 8 << 28);
240 }
241 if (single_stage)
242 Pval |= mpll ? 1 << 12 : 1 << 8;
243
244 nv_wr32(priv, Preg, oldPval | 1 << 28);
245 nv_wr32(priv, Preg, Pval & ~(4 << 28));
246 if (mpll) {
247 Pval |= 8 << 20;
248 nv_wr32(priv, 0x4020, Pval & ~(0xc << 28));
249 nv_wr32(priv, 0x4038, Pval & ~(0xc << 28));
250 }
251
252 savedc040 = nv_rd32(priv, 0xc040);
253 nv_wr32(priv, 0xc040, savedc040 & maskc040);
254
255 nv_wr32(priv, NMNMreg, NMNM);
256 if (NMNMreg == 0x4024)
257 nv_wr32(priv, 0x403c, NMNM);
258
259 nv_wr32(priv, Preg, Pval);
260 if (mpll) {
261 Pval &= ~(8 << 20);
262 nv_wr32(priv, 0x4020, Pval);
263 nv_wr32(priv, 0x4038, Pval);
264 nv_wr32(priv, 0x4600, saved4600);
265 }
266
267 nv_wr32(priv, 0xc040, savedc040);
268
269 if (mpll) {
270 nv_wr32(priv, 0x4020, Pval & ~(1 << 28));
271 nv_wr32(priv, 0x4038, Pval & ~(1 << 28));
272 }
273}
274
275int
32nv04_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) 276nv04_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
33{ 277{
34 struct nv04_clock_priv *priv = (void *)clk; 278 struct nv04_clock_priv *priv = (void *)clk;
279 struct nouveau_pll_vals pv;
280 struct nvbios_pll info;
281 int ret;
282
283 ret = nvbios_pll_parse(nouveau_bios(priv), type > 0x405c ?
284 type : type - 4, &info);
285 if (ret)
286 return ret;
287
288 ret = clk->pll_calc(clk, &info, freq, &pv);
289 if (!ret)
290 return ret;
291
292 return clk->pll_prog(clk, type, &pv);
293}
35 294
36 nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq); 295int
296nv04_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
297 int clk, struct nouveau_pll_vals *pv)
298{
299 int N1, M1, N2, M2, P;
300 int ret = nv04_pll_calc(clock, info, clk, &N1, &M1, &N2, &M2, &P);
301 if (ret) {
302 pv->refclk = info->refclk;
303 pv->N1 = N1;
304 pv->M1 = M1;
305 pv->N2 = N2;
306 pv->M2 = M2;
307 pv->log2P = P;
308 }
309 return ret;
310}
311
312int
313nv04_clock_pll_prog(struct nouveau_clock *clk, u32 reg1,
314 struct nouveau_pll_vals *pv)
315{
316 struct nv04_clock_priv *priv = (void *)clk;
317 int cv = nouveau_bios(clk)->version.chip;
318
319 if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
320 cv >= 0x40) {
321 if (reg1 > 0x405c)
322 setPLL_double_highregs(priv, reg1, pv);
323 else
324 setPLL_double_lowregs(priv, reg1, pv);
325 } else
326 setPLL_single(priv, reg1, pv);
327
328 return 0;
37} 329}
38 330
39static int 331static int
@@ -50,6 +342,8 @@ nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
50 return ret; 342 return ret;
51 343
52 priv->base.pll_set = nv04_clock_pll_set; 344 priv->base.pll_set = nv04_clock_pll_set;
345 priv->base.pll_calc = nv04_clock_pll_calc;
346 priv->base.pll_prog = nv04_clock_pll_prog;
53 return 0; 347 return 0;
54} 348}
55 349
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
index 60d1ca44e39c..a4b2b7ebf9af 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c
@@ -28,14 +28,6 @@ struct nv40_clock_priv {
28 struct nouveau_clock base; 28 struct nouveau_clock base;
29}; 29};
30 30
31static void
32nv40_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
33{
34 struct nv40_clock_priv *priv = (void *)clk;
35
36 nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
37}
38
39static int 31static int
40nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 32nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
41 struct nouveau_oclass *oclass, void *data, u32 size, 33 struct nouveau_oclass *oclass, void *data, u32 size,
@@ -49,7 +41,9 @@ nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
49 if (ret) 41 if (ret)
50 return ret; 42 return ret;
51 43
52 priv->base.pll_set = nv40_clock_pll_set; 44 priv->base.pll_set = nv04_clock_pll_set;
45 priv->base.pll_calc = nv04_clock_pll_calc;
46 priv->base.pll_prog = nv04_clock_pll_prog;
53 return 0; 47 return 0;
54} 48}
55 49
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
index 82804bdcec31..fd181fbceddb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c
@@ -23,17 +23,57 @@
23 */ 23 */
24 24
25#include <subdev/clock.h> 25#include <subdev/clock.h>
26#include <subdev/bios.h>
27#include <subdev/bios/pll.h>
28
29#include "pll.h"
26 30
27struct nv50_clock_priv { 31struct nv50_clock_priv {
28 struct nouveau_clock base; 32 struct nouveau_clock base;
29}; 33};
30 34
31static void 35static int
32nv50_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) 36nv50_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
33{ 37{
34 struct nv50_clock_priv *priv = (void *)clk; 38 struct nv50_clock_priv *priv = (void *)clk;
39 struct nouveau_bios *bios = nouveau_bios(priv);
40 struct nvbios_pll info;
41 int N1, M1, N2, M2, P;
42 int ret;
43
44 ret = nvbios_pll_parse(bios, type, &info);
45 if (ret) {
46 nv_error(clk, "failed to retrieve pll data, %d\n", ret);
47 return ret;
48 }
35 49
36 nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq); 50 ret = nv04_pll_calc(clk, &info, freq, &N1, &M1, &N2, &M2, &P);
51 if (!ret) {
52 nv_error(clk, "failed pll calculation\n");
53 return ret;
54 }
55
56 switch (info.type) {
57 case PLL_VPLL0:
58 case PLL_VPLL1:
59 nv_wr32(priv, info.reg + 0, 0x10000611);
60 nv_mask(priv, info.reg + 4, 0x00ff00ff, (M1 << 16) | N1);
61 nv_mask(priv, info.reg + 8, 0x7fff00ff, (P << 28) |
62 (M2 << 16) | N2);
63 break;
64 case PLL_MEMORY:
65 nv_mask(priv, info.reg + 0, 0x01ff0000, (P << 22) |
66 (info.bias_p << 19) |
67 (P << 16));
68 nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
69 break;
70 default:
71 nv_mask(priv, info.reg + 0, 0x00070000, (P << 16));
72 nv_wr32(priv, info.reg + 4, (N1 << 8) | M1);
73 break;
74 }
75
76 return 0;
37} 77}
38 78
39static int 79static int
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
index 876ec46e2b41..cc8d7d162d7c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
@@ -23,17 +23,47 @@
23 */ 23 */
24 24
25#include <subdev/clock.h> 25#include <subdev/clock.h>
26#include <subdev/bios.h>
27#include <subdev/bios/pll.h>
28
29#include "pll.h"
26 30
27struct nva3_clock_priv { 31struct nva3_clock_priv {
28 struct nouveau_clock base; 32 struct nouveau_clock base;
29}; 33};
30 34
31static void 35static int
32nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) 36nva3_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
33{ 37{
34 struct nva3_clock_priv *priv = (void *)clk; 38 struct nva3_clock_priv *priv = (void *)clk;
39 struct nouveau_bios *bios = nouveau_bios(priv);
40 struct nvbios_pll info;
41 int N, fN, M, P;
42 int ret;
43
44 ret = nvbios_pll_parse(bios, type, &info);
45 if (ret)
46 return ret;
47
48 ret = nva3_pll_calc(clk, &info, freq, &N, &fN, &M, &P);
49 if (ret < 0)
50 return ret;
51
52 switch (info.type) {
53 case PLL_VPLL0:
54 case PLL_VPLL1:
55 nv_wr32(priv, info.reg + 0, 0x50000610);
56 nv_mask(priv, info.reg + 4, 0x003fffff,
57 (P << 16) | (M << 8) | N);
58 nv_wr32(priv, info.reg + 8, fN);
59 break;
60 default:
61 nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
62 ret = -EINVAL;
63 break;
64 }
35 65
36 nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq); 66 return ret;
37} 67}
38 68
39static int 69static int
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
index 00641566f2e7..5ccce0b17bf3 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c
@@ -23,17 +23,46 @@
23 */ 23 */
24 24
25#include <subdev/clock.h> 25#include <subdev/clock.h>
26#include <subdev/bios.h>
27#include <subdev/bios/pll.h>
28
29#include "pll.h"
26 30
27struct nvc0_clock_priv { 31struct nvc0_clock_priv {
28 struct nouveau_clock base; 32 struct nouveau_clock base;
29}; 33};
30 34
31static void 35static int
32nvc0_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq) 36nvc0_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
33{ 37{
34 struct nvc0_clock_priv *priv = (void *)clk; 38 struct nvc0_clock_priv *priv = (void *)clk;
39 struct nouveau_bios *bios = nouveau_bios(priv);
40 struct nvbios_pll info;
41 int N, fN, M, P;
42 int ret;
43
44 ret = nvbios_pll_parse(bios, type, &info);
45 if (ret)
46 return ret;
47
48 ret = nva3_pll_calc(clk, &info, freq, &N, &fN, &M, &P);
49 if (ret < 0)
50 return ret;
51
52 switch (info.type) {
53 case PLL_VPLL0:
54 case PLL_VPLL1:
55 nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100);
56 nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M);
57 nv_wr32(priv, info.reg + 0x10, fN << 16);
58 break;
59 default:
60 nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq);
61 ret = -EINVAL;
62 break;
63 }
35 64
36 nv_warn(priv, "0x%08x/%dKhz unimplemented\n", type, freq); 65 return ret;
37} 66}
38 67
39static int 68static int
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h b/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h
new file mode 100644
index 000000000000..ef2c0078f337
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pll.h
@@ -0,0 +1,9 @@
1#ifndef __NOUVEAU_PLL_H__
2#define __NOUVEAU_PLL_H__
3
4int nv04_pll_calc(struct nouveau_clock *, struct nvbios_pll *, u32 freq,
5 int *N1, int *M1, int *N2, int *M2, int *P);
6int nva3_pll_calc(struct nouveau_clock *, struct nvbios_pll *, u32 freq,
7 int *N, int *fN, int *M, int *P);
8
9#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
new file mode 100644
index 000000000000..a2ab6d051ba8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c
@@ -0,0 +1,242 @@
1/*
2 * Copyright 1993-2003 NVIDIA, Corporation
3 * Copyright 2007-2009 Stuart Bennett
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#include <subdev/clock.h>
25#include <subdev/bios.h>
26#include <subdev/bios/pll.h>
27
28#include "pll.h"
29
30static int
31getMNP_single(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
32 int *pN, int *pM, int *pP)
33{
34 /* Find M, N and P for a single stage PLL
35 *
36 * Note that some bioses (NV3x) have lookup tables of precomputed MNP
37 * values, but we're too lazy to use those atm
38 *
39 * "clk" parameter in kHz
40 * returns calculated clock
41 */
42 int cv = nouveau_bios(clock)->version.chip;
43 int minvco = info->vco1.min_freq, maxvco = info->vco1.max_freq;
44 int minM = info->vco1.min_m, maxM = info->vco1.max_m;
45 int minN = info->vco1.min_n, maxN = info->vco1.max_n;
46 int minU = info->vco1.min_inputfreq;
47 int maxU = info->vco1.max_inputfreq;
48 int minP = info->min_p;
49 int maxP = info->max_p_usable;
50 int crystal = info->refclk;
51 int M, N, thisP, P;
52 int clkP, calcclk;
53 int delta, bestdelta = INT_MAX;
54 int bestclk = 0;
55
56 /* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */
57 /* possibly correlated with introduction of 27MHz crystal */
58 if (cv < 0x17 || cv == 0x1a || cv == 0x20) {
59 if (clk > 250000)
60 maxM = 6;
61 if (clk > 340000)
62 maxM = 2;
63 } else if (cv < 0x40) {
64 if (clk > 150000)
65 maxM = 6;
66 if (clk > 200000)
67 maxM = 4;
68 if (clk > 340000)
69 maxM = 2;
70 }
71
72 P = 1 << maxP;
73 if ((clk * P) < minvco) {
74 minvco = clk * maxP;
75 maxvco = minvco * 2;
76 }
77
78 if (clk + clk/200 > maxvco) /* +0.5% */
79 maxvco = clk + clk/200;
80
81 /* NV34 goes maxlog2P->0, NV20 goes 0->maxlog2P */
82 for (thisP = minP; thisP <= maxP; thisP++) {
83 P = 1 << thisP;
84 clkP = clk * P;
85
86 if (clkP < minvco)
87 continue;
88 if (clkP > maxvco)
89 return bestclk;
90
91 for (M = minM; M <= maxM; M++) {
92 if (crystal/M < minU)
93 return bestclk;
94 if (crystal/M > maxU)
95 continue;
96
97 /* add crystal/2 to round better */
98 N = (clkP * M + crystal/2) / crystal;
99
100 if (N < minN)
101 continue;
102 if (N > maxN)
103 break;
104
105 /* more rounding additions */
106 calcclk = ((N * crystal + P/2) / P + M/2) / M;
107 delta = abs(calcclk - clk);
108 /* we do an exhaustive search rather than terminating
109 * on an optimality condition...
110 */
111 if (delta < bestdelta) {
112 bestdelta = delta;
113 bestclk = calcclk;
114 *pN = N;
115 *pM = M;
116 *pP = thisP;
117 if (delta == 0) /* except this one */
118 return bestclk;
119 }
120 }
121 }
122
123 return bestclk;
124}
125
126static int
127getMNP_double(struct nouveau_clock *clock, struct nvbios_pll *info, int clk,
128 int *pN1, int *pM1, int *pN2, int *pM2, int *pP)
129{
130 /* Find M, N and P for a two stage PLL
131 *
132 * Note that some bioses (NV30+) have lookup tables of precomputed MNP
133 * values, but we're too lazy to use those atm
134 *
135 * "clk" parameter in kHz
136 * returns calculated clock
137 */
138 int chip_version = nouveau_bios(clock)->version.chip;
139 int minvco1 = info->vco1.min_freq, maxvco1 = info->vco1.max_freq;
140 int minvco2 = info->vco2.min_freq, maxvco2 = info->vco2.max_freq;
141 int minU1 = info->vco1.min_inputfreq, minU2 = info->vco2.min_inputfreq;
142 int maxU1 = info->vco1.max_inputfreq, maxU2 = info->vco2.max_inputfreq;
143 int minM1 = info->vco1.min_m, maxM1 = info->vco1.max_m;
144 int minN1 = info->vco1.min_n, maxN1 = info->vco1.max_n;
145 int minM2 = info->vco2.min_m, maxM2 = info->vco2.max_m;
146 int minN2 = info->vco2.min_n, maxN2 = info->vco2.max_n;
147 int maxlog2P = info->max_p_usable;
148 int crystal = info->refclk;
149 bool fixedgain2 = (minM2 == maxM2 && minN2 == maxN2);
150 int M1, N1, M2, N2, log2P;
151 int clkP, calcclk1, calcclk2, calcclkout;
152 int delta, bestdelta = INT_MAX;
153 int bestclk = 0;
154
155 int vco2 = (maxvco2 - maxvco2/200) / 2;
156 for (log2P = 0; clk && log2P < maxlog2P && clk <= (vco2 >> log2P); log2P++)
157 ;
158 clkP = clk << log2P;
159
160 if (maxvco2 < clk + clk/200) /* +0.5% */
161 maxvco2 = clk + clk/200;
162
163 for (M1 = minM1; M1 <= maxM1; M1++) {
164 if (crystal/M1 < minU1)
165 return bestclk;
166 if (crystal/M1 > maxU1)
167 continue;
168
169 for (N1 = minN1; N1 <= maxN1; N1++) {
170 calcclk1 = crystal * N1 / M1;
171 if (calcclk1 < minvco1)
172 continue;
173 if (calcclk1 > maxvco1)
174 break;
175
176 for (M2 = minM2; M2 <= maxM2; M2++) {
177 if (calcclk1/M2 < minU2)
178 break;
179 if (calcclk1/M2 > maxU2)
180 continue;
181
182 /* add calcclk1/2 to round better */
183 N2 = (clkP * M2 + calcclk1/2) / calcclk1;
184 if (N2 < minN2)
185 continue;
186 if (N2 > maxN2)
187 break;
188
189 if (!fixedgain2) {
190 if (chip_version < 0x60)
191 if (N2/M2 < 4 || N2/M2 > 10)
192 continue;
193
194 calcclk2 = calcclk1 * N2 / M2;
195 if (calcclk2 < minvco2)
196 break;
197 if (calcclk2 > maxvco2)
198 continue;
199 } else
200 calcclk2 = calcclk1;
201
202 calcclkout = calcclk2 >> log2P;
203 delta = abs(calcclkout - clk);
204 /* we do an exhaustive search rather than terminating
205 * on an optimality condition...
206 */
207 if (delta < bestdelta) {
208 bestdelta = delta;
209 bestclk = calcclkout;
210 *pN1 = N1;
211 *pM1 = M1;
212 *pN2 = N2;
213 *pM2 = M2;
214 *pP = log2P;
215 if (delta == 0) /* except this one */
216 return bestclk;
217 }
218 }
219 }
220 }
221
222 return bestclk;
223}
224
225int
226nv04_pll_calc(struct nouveau_clock *clk, struct nvbios_pll *info, u32 freq,
227 int *N1, int *M1, int *N2, int *M2, int *P)
228{
229 int ret;
230
231 if (!info->vco2.max_freq) {
232 ret = getMNP_single(clk, info, freq, N1, M1, P);
233 *N2 = 1;
234 *M2 = 1;
235 } else {
236 ret = getMNP_double(clk, info, freq, N1, M1, N2, M2, P);
237 }
238
239 if (!ret)
240 nv_error(clk, "unable to compute acceptable pll values\n");
241 return ret;
242}
diff --git a/drivers/gpu/drm/nouveau/nv50_calc.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
index 8cf63a8b30cd..eed5c16cf610 100644
--- a/drivers/gpu/drm/nouveau/nv50_calc.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c
@@ -22,60 +22,43 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24 24
25#include "drmP.h" 25#include <subdev/clock.h>
26#include "nouveau_drv.h" 26#include <subdev/bios.h>
27#include "nouveau_hw.h" 27#include <subdev/bios/pll.h>
28 28
29int 29#include "pll.h"
30nv50_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk,
31 int *N1, int *M1, int *N2, int *M2, int *P)
32{
33 struct nouveau_pll_vals pll_vals;
34 int ret;
35
36 ret = nouveau_calc_pll_mnp(dev, pll, clk, &pll_vals);
37 if (ret <= 0)
38 return ret;
39
40 *N1 = pll_vals.N1;
41 *M1 = pll_vals.M1;
42 *N2 = pll_vals.N2;
43 *M2 = pll_vals.M2;
44 *P = pll_vals.log2P;
45 return ret;
46}
47 30
48int 31int
49nva3_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk, 32nva3_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info,
50 int *pN, int *pfN, int *pM, int *P) 33 u32 freq, int *pN, int *pfN, int *pM, int *P)
51{ 34{
52 u32 best_err = ~0, err; 35 u32 best_err = ~0, err;
53 int M, lM, hM, N, fN; 36 int M, lM, hM, N, fN;
54 37
55 *P = pll->vco1.maxfreq / clk; 38 *P = info->vco1.max_freq / freq;
56 if (*P > pll->max_p) 39 if (*P > info->max_p)
57 *P = pll->max_p; 40 *P = info->max_p;
58 if (*P < pll->min_p) 41 if (*P < info->min_p)
59 *P = pll->min_p; 42 *P = info->min_p;
60 43
61 lM = (pll->refclk + pll->vco1.max_inputfreq) / pll->vco1.max_inputfreq; 44 lM = (info->refclk + info->vco1.max_inputfreq) / info->vco1.max_inputfreq;
62 lM = max(lM, (int)pll->vco1.min_m); 45 lM = max(lM, (int)info->vco1.min_m);
63 hM = (pll->refclk + pll->vco1.min_inputfreq) / pll->vco1.min_inputfreq; 46 hM = (info->refclk + info->vco1.min_inputfreq) / info->vco1.min_inputfreq;
64 hM = min(hM, (int)pll->vco1.max_m); 47 hM = min(hM, (int)info->vco1.max_m);
65 48
66 for (M = lM; M <= hM; M++) { 49 for (M = lM; M <= hM; M++) {
67 u32 tmp = clk * *P * M; 50 u32 tmp = freq * *P * M;
68 N = tmp / pll->refclk; 51 N = tmp / info->refclk;
69 fN = tmp % pll->refclk; 52 fN = tmp % info->refclk;
70 if (!pfN && fN >= pll->refclk / 2) 53 if (!pfN && fN >= info->refclk / 2)
71 N++; 54 N++;
72 55
73 if (N < pll->vco1.min_n) 56 if (N < info->vco1.min_n)
74 continue; 57 continue;
75 if (N > pll->vco1.max_n) 58 if (N > info->vco1.max_n)
76 break; 59 break;
77 60
78 err = abs(clk - (pll->refclk * N / M / *P)); 61 err = abs(freq - (info->refclk * N / M / *P));
79 if (err < best_err) { 62 if (err < best_err) {
80 best_err = err; 63 best_err = err;
81 *pN = N; 64 *pN = N;
@@ -83,15 +66,15 @@ nva3_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk,
83 } 66 }
84 67
85 if (pfN) { 68 if (pfN) {
86 *pfN = (((fN << 13) / pll->refclk) - 4096) & 0xffff; 69 *pfN = (((fN << 13) / info->refclk) - 4096) & 0xffff;
87 return clk; 70 return freq;
88 } 71 }
89 } 72 }
90 73
91 if (unlikely(best_err == ~0)) { 74 if (unlikely(best_err == ~0)) {
92 NV_ERROR(dev, "unable to find matching pll values\n"); 75 nv_error(clock, "unable to find matching pll values\n");
93 return -EINVAL; 76 return -EINVAL;
94 } 77 }
95 78
96 return pll->refclk * *pN / *pM / *P; 79 return info->refclk * *pN / *pM / *P;
97} 80}
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 35b0a8f9c008..98eaac9da30e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -441,70 +441,6 @@ io_condition_met(struct nvbios *bios, uint16_t offset, uint8_t cond)
441 return (data == cmpval); 441 return (data == cmpval);
442} 442}
443 443
444static int
445nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk)
446{
447 struct drm_nouveau_private *dev_priv = dev->dev_private;
448 struct nouveau_pll_vals pll;
449 struct pll_lims pll_limits;
450 u32 ctrl, mask, coef;
451 int ret;
452
453 ret = get_pll_limits(dev, reg, &pll_limits);
454 if (ret)
455 return ret;
456
457 clk = nouveau_calc_pll_mnp(dev, &pll_limits, clk, &pll);
458 if (!clk)
459 return -ERANGE;
460
461 coef = pll.N1 << 8 | pll.M1;
462 ctrl = pll.log2P << 16;
463 mask = 0x00070000;
464 if (reg == 0x004008) {
465 mask |= 0x01f80000;
466 ctrl |= (pll_limits.log2p_bias << 19);
467 ctrl |= (pll.log2P << 22);
468 }
469
470 if (!dev_priv->vbios.execute)
471 return 0;
472
473 nv_mask(dev, reg + 0, mask, ctrl);
474 nv_wr32(dev, reg + 4, coef);
475 return 0;
476}
477
478static int
479setPLL(struct nvbios *bios, uint32_t reg, uint32_t clk)
480{
481 struct drm_device *dev = bios->dev;
482 struct drm_nouveau_private *dev_priv = dev->dev_private;
483 /* clk in kHz */
484 struct pll_lims pll_lim;
485 struct nouveau_pll_vals pllvals;
486 int ret;
487
488 if (dev_priv->card_type >= NV_50)
489 return nv50_pll_set(dev, reg, clk);
490
491 /* high regs (such as in the mac g5 table) are not -= 4 */
492 ret = get_pll_limits(dev, reg > 0x405c ? reg : reg - 4, &pll_lim);
493 if (ret)
494 return ret;
495
496 clk = nouveau_calc_pll_mnp(dev, &pll_lim, clk, &pllvals);
497 if (!clk)
498 return -ERANGE;
499
500 if (bios->execute) {
501 still_alive();
502 nouveau_hw_setpll(dev, reg, &pllvals);
503 }
504
505 return 0;
506}
507
508static int dcb_entry_idx_from_crtchead(struct drm_device *dev) 444static int dcb_entry_idx_from_crtchead(struct drm_device *dev)
509{ 445{
510 struct drm_nouveau_private *dev_priv = dev->dev_private; 446 struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -752,7 +688,7 @@ init_io_restrict_pll(struct nvbios *bios, uint16_t offset,
752 BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n", 688 BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %d0kHz\n",
753 offset, reg, config, freq); 689 offset, reg, config, freq);
754 690
755 setPLL(bios, reg, freq * 10); 691 setPLL(bios->dev, reg, freq * 10);
756 692
757 return len; 693 return len;
758} 694}
@@ -1110,7 +1046,7 @@ init_io_restrict_pll2(struct nvbios *bios, uint16_t offset,
1110 BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n", 1046 BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Config: 0x%02X, Freq: %dkHz\n",
1111 offset, reg, config, freq); 1047 offset, reg, config, freq);
1112 1048
1113 setPLL(bios, reg, freq); 1049 setPLL(bios->dev, reg, freq);
1114 1050
1115 return len; 1051 return len;
1116} 1052}
@@ -1137,7 +1073,7 @@ init_pll2(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
1137 BIOSLOG(bios, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n", 1073 BIOSLOG(bios, "0x%04X: Reg: 0x%04X, Freq: %dkHz\n",
1138 offset, reg, freq); 1074 offset, reg, freq);
1139 1075
1140 setPLL(bios, reg, freq); 1076 setPLL(bios->dev, reg, freq);
1141 return 9; 1077 return 9;
1142} 1078}
1143 1079
@@ -2376,12 +2312,12 @@ init_configure_clk(struct nvbios *bios, uint16_t offset,
2376 return 0; 2312 return 0;
2377 2313
2378 clock = ROM16(bios->data[meminitoffs + 4]) * 10; 2314 clock = ROM16(bios->data[meminitoffs + 4]) * 10;
2379 setPLL(bios, NV_PRAMDAC_NVPLL_COEFF, clock); 2315 setPLL(bios->dev, NV_PRAMDAC_NVPLL_COEFF, clock);
2380 2316
2381 clock = ROM16(bios->data[meminitoffs + 2]) * 10; 2317 clock = ROM16(bios->data[meminitoffs + 2]) * 10;
2382 if (bios->data[meminitoffs] & 1) /* DDR */ 2318 if (bios->data[meminitoffs] & 1) /* DDR */
2383 clock *= 2; 2319 clock *= 2;
2384 setPLL(bios, NV_PRAMDAC_MPLL_COEFF, clock); 2320 setPLL(bios->dev, NV_PRAMDAC_MPLL_COEFF, clock);
2385 2321
2386 return 1; 2322 return 1;
2387} 2323}
@@ -2820,7 +2756,7 @@ init_pll(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
2820 2756
2821 BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq); 2757 BIOSLOG(bios, "0x%04X: Reg: 0x%08X, Freq: %d0kHz\n", offset, reg, freq);
2822 2758
2823 setPLL(bios, reg, freq * 10); 2759 setPLL(bios->dev, reg, freq * 10);
2824 2760
2825 return 7; 2761 return 7;
2826} 2762}
@@ -2898,7 +2834,7 @@ init_ram_restrict_pll(struct nvbios *bios, uint16_t offset,
2898 "Type %02x Reg 0x%08x Freq %dKHz\n", 2834 "Type %02x Reg 0x%08x Freq %dKHz\n",
2899 offset, type, reg, freq); 2835 offset, type, reg, freq);
2900 2836
2901 setPLL(bios, reg, freq); 2837 setPLL(bios->dev, reg, freq);
2902 return len; 2838 return len;
2903 } 2839 }
2904 } 2840 }
@@ -4305,447 +4241,6 @@ int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, i
4305 return 0; 4241 return 0;
4306} 4242}
4307 4243
4308struct pll_mapping {
4309 u8 type;
4310 u32 reg;
4311};
4312
4313static struct pll_mapping nv04_pll_mapping[] = {
4314 { PLL_CORE , NV_PRAMDAC_NVPLL_COEFF },
4315 { PLL_MEMORY, NV_PRAMDAC_MPLL_COEFF },
4316 { PLL_VPLL0 , NV_PRAMDAC_VPLL_COEFF },
4317 { PLL_VPLL1 , NV_RAMDAC_VPLL2 },
4318 {}
4319};
4320
4321static struct pll_mapping nv40_pll_mapping[] = {
4322 { PLL_CORE , 0x004000 },
4323 { PLL_MEMORY, 0x004020 },
4324 { PLL_VPLL0 , NV_PRAMDAC_VPLL_COEFF },
4325 { PLL_VPLL1 , NV_RAMDAC_VPLL2 },
4326 {}
4327};
4328
4329static struct pll_mapping nv50_pll_mapping[] = {
4330 { PLL_CORE , 0x004028 },
4331 { PLL_SHADER, 0x004020 },
4332 { PLL_UNK03 , 0x004000 },
4333 { PLL_MEMORY, 0x004008 },
4334 { PLL_UNK40 , 0x00e810 },
4335 { PLL_UNK41 , 0x00e818 },
4336 { PLL_UNK42 , 0x00e824 },
4337 { PLL_VPLL0 , 0x614100 },
4338 { PLL_VPLL1 , 0x614900 },
4339 {}
4340};
4341
4342static struct pll_mapping nv84_pll_mapping[] = {
4343 { PLL_CORE , 0x004028 },
4344 { PLL_SHADER, 0x004020 },
4345 { PLL_MEMORY, 0x004008 },
4346 { PLL_VDEC , 0x004030 },
4347 { PLL_UNK41 , 0x00e818 },
4348 { PLL_VPLL0 , 0x614100 },
4349 { PLL_VPLL1 , 0x614900 },
4350 {}
4351};
4352
4353u32
4354get_pll_register(struct drm_device *dev, enum pll_types type)
4355{
4356 struct drm_nouveau_private *dev_priv = dev->dev_private;
4357 struct nvbios *bios = &dev_priv->vbios;
4358 struct pll_mapping *map;
4359 int i;
4360
4361 if (dev_priv->card_type < NV_40)
4362 map = nv04_pll_mapping;
4363 else
4364 if (dev_priv->card_type < NV_50)
4365 map = nv40_pll_mapping;
4366 else {
4367 u8 *plim = &bios->data[bios->pll_limit_tbl_ptr];
4368
4369 if (plim[0] >= 0x30) {
4370 u8 *entry = plim + plim[1];
4371 for (i = 0; i < plim[3]; i++, entry += plim[2]) {
4372 if (entry[0] == type)
4373 return ROM32(entry[3]);
4374 }
4375
4376 return 0;
4377 }
4378
4379 if (dev_priv->chipset == 0x50)
4380 map = nv50_pll_mapping;
4381 else
4382 map = nv84_pll_mapping;
4383 }
4384
4385 while (map->reg) {
4386 if (map->type == type)
4387 return map->reg;
4388 map++;
4389 }
4390
4391 return 0;
4392}
4393
4394int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims *pll_lim)
4395{
4396 /*
4397 * PLL limits table
4398 *
4399 * Version 0x10: NV30, NV31
4400 * One byte header (version), one record of 24 bytes
4401 * Version 0x11: NV36 - Not implemented
4402 * Seems to have same record style as 0x10, but 3 records rather than 1
4403 * Version 0x20: Found on Geforce 6 cards
4404 * Trivial 4 byte BIT header. 31 (0x1f) byte record length
4405 * Version 0x21: Found on Geforce 7, 8 and some Geforce 6 cards
4406 * 5 byte header, fifth byte of unknown purpose. 35 (0x23) byte record
4407 * length in general, some (integrated) have an extra configuration byte
4408 * Version 0x30: Found on Geforce 8, separates the register mapping
4409 * from the limits tables.
4410 */
4411
4412 struct drm_nouveau_private *dev_priv = dev->dev_private;
4413 struct nvbios *bios = &dev_priv->vbios;
4414 int cv = bios->chip_version, pllindex = 0;
4415 uint8_t pll_lim_ver = 0, headerlen = 0, recordlen = 0, entries = 0;
4416 uint32_t crystal_strap_mask, crystal_straps;
4417
4418 if (!bios->pll_limit_tbl_ptr) {
4419 if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
4420 cv >= 0x40) {
4421 NV_ERROR(dev, "Pointer to PLL limits table invalid\n");
4422 return -EINVAL;
4423 }
4424 } else
4425 pll_lim_ver = bios->data[bios->pll_limit_tbl_ptr];
4426
4427 crystal_strap_mask = 1 << 6;
4428 /* open coded dev->twoHeads test */
4429 if (cv > 0x10 && cv != 0x15 && cv != 0x1a && cv != 0x20)
4430 crystal_strap_mask |= 1 << 22;
4431 crystal_straps = nvReadEXTDEV(dev, NV_PEXTDEV_BOOT_0) &
4432 crystal_strap_mask;
4433
4434 switch (pll_lim_ver) {
4435 /*
4436 * We use version 0 to indicate a pre limit table bios (single stage
4437 * pll) and load the hard coded limits instead.
4438 */
4439 case 0:
4440 break;
4441 case 0x10:
4442 case 0x11:
4443 /*
4444 * Strictly v0x11 has 3 entries, but the last two don't seem
4445 * to get used.
4446 */
4447 headerlen = 1;
4448 recordlen = 0x18;
4449 entries = 1;
4450 pllindex = 0;
4451 break;
4452 case 0x20:
4453 case 0x21:
4454 case 0x30:
4455 case 0x40:
4456 headerlen = bios->data[bios->pll_limit_tbl_ptr + 1];
4457 recordlen = bios->data[bios->pll_limit_tbl_ptr + 2];
4458 entries = bios->data[bios->pll_limit_tbl_ptr + 3];
4459 break;
4460 default:
4461 NV_ERROR(dev, "PLL limits table revision 0x%X not currently "
4462 "supported\n", pll_lim_ver);
4463 return -ENOSYS;
4464 }
4465
4466 /* initialize all members to zero */
4467 memset(pll_lim, 0, sizeof(struct pll_lims));
4468
4469 /* if we were passed a type rather than a register, figure
4470 * out the register and store it
4471 */
4472 if (limit_match > PLL_MAX)
4473 pll_lim->reg = limit_match;
4474 else {
4475 pll_lim->reg = get_pll_register(dev, limit_match);
4476 if (!pll_lim->reg)
4477 return -ENOENT;
4478 }
4479
4480 if (pll_lim_ver == 0x10 || pll_lim_ver == 0x11) {
4481 uint8_t *pll_rec = &bios->data[bios->pll_limit_tbl_ptr + headerlen + recordlen * pllindex];
4482
4483 pll_lim->vco1.minfreq = ROM32(pll_rec[0]);
4484 pll_lim->vco1.maxfreq = ROM32(pll_rec[4]);
4485 pll_lim->vco2.minfreq = ROM32(pll_rec[8]);
4486 pll_lim->vco2.maxfreq = ROM32(pll_rec[12]);
4487 pll_lim->vco1.min_inputfreq = ROM32(pll_rec[16]);
4488 pll_lim->vco2.min_inputfreq = ROM32(pll_rec[20]);
4489 pll_lim->vco1.max_inputfreq = pll_lim->vco2.max_inputfreq = INT_MAX;
4490
4491 /* these values taken from nv30/31/36 */
4492 pll_lim->vco1.min_n = 0x1;
4493 if (cv == 0x36)
4494 pll_lim->vco1.min_n = 0x5;
4495 pll_lim->vco1.max_n = 0xff;
4496 pll_lim->vco1.min_m = 0x1;
4497 pll_lim->vco1.max_m = 0xd;
4498 pll_lim->vco2.min_n = 0x4;
4499 /*
4500 * On nv30, 31, 36 (i.e. all cards with two stage PLLs with this
4501 * table version (apart from nv35)), N2 is compared to
4502 * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and
4503 * save a comparison
4504 */
4505 pll_lim->vco2.max_n = 0x28;
4506 if (cv == 0x30 || cv == 0x35)
4507 /* only 5 bits available for N2 on nv30/35 */
4508 pll_lim->vco2.max_n = 0x1f;
4509 pll_lim->vco2.min_m = 0x1;
4510 pll_lim->vco2.max_m = 0x4;
4511 pll_lim->max_log2p = 0x7;
4512 pll_lim->max_usable_log2p = 0x6;
4513 } else if (pll_lim_ver == 0x20 || pll_lim_ver == 0x21) {
4514 uint16_t plloffs = bios->pll_limit_tbl_ptr + headerlen;
4515 uint8_t *pll_rec;
4516 int i;
4517
4518 /*
4519 * First entry is default match, if nothing better. warn if
4520 * reg field nonzero
4521 */
4522 if (ROM32(bios->data[plloffs]))
4523 NV_WARN(dev, "Default PLL limit entry has non-zero "
4524 "register field\n");
4525
4526 for (i = 1; i < entries; i++)
4527 if (ROM32(bios->data[plloffs + recordlen * i]) == pll_lim->reg) {
4528 pllindex = i;
4529 break;
4530 }
4531
4532 if ((dev_priv->card_type >= NV_50) && (pllindex == 0)) {
4533 NV_ERROR(dev, "Register 0x%08x not found in PLL "
4534 "limits table", pll_lim->reg);
4535 return -ENOENT;
4536 }
4537
4538 pll_rec = &bios->data[plloffs + recordlen * pllindex];
4539
4540 BIOSLOG(bios, "Loading PLL limits for reg 0x%08x\n",
4541 pllindex ? pll_lim->reg : 0);
4542
4543 /*
4544 * Frequencies are stored in tables in MHz, kHz are more
4545 * useful, so we convert.
4546 */
4547
4548 /* What output frequencies can each VCO generate? */
4549 pll_lim->vco1.minfreq = ROM16(pll_rec[4]) * 1000;
4550 pll_lim->vco1.maxfreq = ROM16(pll_rec[6]) * 1000;
4551 pll_lim->vco2.minfreq = ROM16(pll_rec[8]) * 1000;
4552 pll_lim->vco2.maxfreq = ROM16(pll_rec[10]) * 1000;
4553
4554 /* What input frequencies they accept (past the m-divider)? */
4555 pll_lim->vco1.min_inputfreq = ROM16(pll_rec[12]) * 1000;
4556 pll_lim->vco2.min_inputfreq = ROM16(pll_rec[14]) * 1000;
4557 pll_lim->vco1.max_inputfreq = ROM16(pll_rec[16]) * 1000;
4558 pll_lim->vco2.max_inputfreq = ROM16(pll_rec[18]) * 1000;
4559
4560 /* What values are accepted as multiplier and divider? */
4561 pll_lim->vco1.min_n = pll_rec[20];
4562 pll_lim->vco1.max_n = pll_rec[21];
4563 pll_lim->vco1.min_m = pll_rec[22];
4564 pll_lim->vco1.max_m = pll_rec[23];
4565 pll_lim->vco2.min_n = pll_rec[24];
4566 pll_lim->vco2.max_n = pll_rec[25];
4567 pll_lim->vco2.min_m = pll_rec[26];
4568 pll_lim->vco2.max_m = pll_rec[27];
4569
4570 pll_lim->max_usable_log2p = pll_lim->max_log2p = pll_rec[29];
4571 if (pll_lim->max_log2p > 0x7)
4572 /* pll decoding in nv_hw.c assumes never > 7 */
4573 NV_WARN(dev, "Max log2 P value greater than 7 (%d)\n",
4574 pll_lim->max_log2p);
4575 if (cv < 0x60)
4576 pll_lim->max_usable_log2p = 0x6;
4577 pll_lim->log2p_bias = pll_rec[30];
4578
4579 if (recordlen > 0x22)
4580 pll_lim->refclk = ROM32(pll_rec[31]);
4581
4582 if (recordlen > 0x23 && pll_rec[35])
4583 NV_WARN(dev,
4584 "Bits set in PLL configuration byte (%x)\n",
4585 pll_rec[35]);
4586
4587 /* C51 special not seen elsewhere */
4588 if (cv == 0x51 && !pll_lim->refclk) {
4589 uint32_t sel_clk = bios_rd32(bios, NV_PRAMDAC_SEL_CLK);
4590
4591 if ((pll_lim->reg == NV_PRAMDAC_VPLL_COEFF && sel_clk & 0x20) ||
4592 (pll_lim->reg == NV_RAMDAC_VPLL2 && sel_clk & 0x80)) {
4593 if (bios_idxprt_rd(bios, NV_CIO_CRX__COLOR, NV_CIO_CRE_CHIP_ID_INDEX) < 0xa3)
4594 pll_lim->refclk = 200000;
4595 else
4596 pll_lim->refclk = 25000;
4597 }
4598 }
4599 } else if (pll_lim_ver == 0x30) { /* ver 0x30 */
4600 uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen];
4601 uint8_t *record = NULL;
4602 int i;
4603
4604 BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n",
4605 pll_lim->reg);
4606
4607 for (i = 0; i < entries; i++, entry += recordlen) {
4608 if (ROM32(entry[3]) == pll_lim->reg) {
4609 record = &bios->data[ROM16(entry[1])];
4610 break;
4611 }
4612 }
4613
4614 if (!record) {
4615 NV_ERROR(dev, "Register 0x%08x not found in PLL "
4616 "limits table", pll_lim->reg);
4617 return -ENOENT;
4618 }
4619
4620 pll_lim->vco1.minfreq = ROM16(record[0]) * 1000;
4621 pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000;
4622 pll_lim->vco2.minfreq = ROM16(record[4]) * 1000;
4623 pll_lim->vco2.maxfreq = ROM16(record[6]) * 1000;
4624 pll_lim->vco1.min_inputfreq = ROM16(record[8]) * 1000;
4625 pll_lim->vco2.min_inputfreq = ROM16(record[10]) * 1000;
4626 pll_lim->vco1.max_inputfreq = ROM16(record[12]) * 1000;
4627 pll_lim->vco2.max_inputfreq = ROM16(record[14]) * 1000;
4628 pll_lim->vco1.min_n = record[16];
4629 pll_lim->vco1.max_n = record[17];
4630 pll_lim->vco1.min_m = record[18];
4631 pll_lim->vco1.max_m = record[19];
4632 pll_lim->vco2.min_n = record[20];
4633 pll_lim->vco2.max_n = record[21];
4634 pll_lim->vco2.min_m = record[22];
4635 pll_lim->vco2.max_m = record[23];
4636 pll_lim->max_usable_log2p = pll_lim->max_log2p = record[25];
4637 pll_lim->log2p_bias = record[27];
4638 pll_lim->refclk = ROM32(record[28]);
4639 } else if (pll_lim_ver) { /* ver 0x40 */
4640 uint8_t *entry = &bios->data[bios->pll_limit_tbl_ptr + headerlen];
4641 uint8_t *record = NULL;
4642 int i;
4643
4644 BIOSLOG(bios, "Loading PLL limits for register 0x%08x\n",
4645 pll_lim->reg);
4646
4647 for (i = 0; i < entries; i++, entry += recordlen) {
4648 if (ROM32(entry[3]) == pll_lim->reg) {
4649 record = &bios->data[ROM16(entry[1])];
4650 break;
4651 }
4652 }
4653
4654 if (!record) {
4655 NV_ERROR(dev, "Register 0x%08x not found in PLL "
4656 "limits table", pll_lim->reg);
4657 return -ENOENT;
4658 }
4659
4660 pll_lim->vco1.minfreq = ROM16(record[0]) * 1000;
4661 pll_lim->vco1.maxfreq = ROM16(record[2]) * 1000;
4662 pll_lim->vco1.min_inputfreq = ROM16(record[4]) * 1000;
4663 pll_lim->vco1.max_inputfreq = ROM16(record[6]) * 1000;
4664 pll_lim->vco1.min_m = record[8];
4665 pll_lim->vco1.max_m = record[9];
4666 pll_lim->vco1.min_n = record[10];
4667 pll_lim->vco1.max_n = record[11];
4668 pll_lim->min_p = record[12];
4669 pll_lim->max_p = record[13];
4670 pll_lim->refclk = ROM16(entry[9]) * 1000;
4671 }
4672
4673 /*
4674 * By now any valid limit table ought to have set a max frequency for
4675 * vco1, so if it's zero it's either a pre limit table bios, or one
4676 * with an empty limit table (seen on nv18)
4677 */
4678 if (!pll_lim->vco1.maxfreq) {
4679 pll_lim->vco1.minfreq = bios->fminvco;
4680 pll_lim->vco1.maxfreq = bios->fmaxvco;
4681 pll_lim->vco1.min_inputfreq = 0;
4682 pll_lim->vco1.max_inputfreq = INT_MAX;
4683 pll_lim->vco1.min_n = 0x1;
4684 pll_lim->vco1.max_n = 0xff;
4685 pll_lim->vco1.min_m = 0x1;
4686 if (crystal_straps == 0) {
4687 /* nv05 does this, nv11 doesn't, nv10 unknown */
4688 if (cv < 0x11)
4689 pll_lim->vco1.min_m = 0x7;
4690 pll_lim->vco1.max_m = 0xd;
4691 } else {
4692 if (cv < 0x11)
4693 pll_lim->vco1.min_m = 0x8;
4694 pll_lim->vco1.max_m = 0xe;
4695 }
4696 if (cv < 0x17 || cv == 0x1a || cv == 0x20)
4697 pll_lim->max_log2p = 4;
4698 else
4699 pll_lim->max_log2p = 5;
4700 pll_lim->max_usable_log2p = pll_lim->max_log2p;
4701 }
4702
4703 if (!pll_lim->refclk)
4704 switch (crystal_straps) {
4705 case 0:
4706 pll_lim->refclk = 13500;
4707 break;
4708 case (1 << 6):
4709 pll_lim->refclk = 14318;
4710 break;
4711 case (1 << 22):
4712 pll_lim->refclk = 27000;
4713 break;
4714 case (1 << 22 | 1 << 6):
4715 pll_lim->refclk = 25000;
4716 break;
4717 }
4718
4719 NV_DEBUG(dev, "pll.vco1.minfreq: %d\n", pll_lim->vco1.minfreq);
4720 NV_DEBUG(dev, "pll.vco1.maxfreq: %d\n", pll_lim->vco1.maxfreq);
4721 NV_DEBUG(dev, "pll.vco1.min_inputfreq: %d\n", pll_lim->vco1.min_inputfreq);
4722 NV_DEBUG(dev, "pll.vco1.max_inputfreq: %d\n", pll_lim->vco1.max_inputfreq);
4723 NV_DEBUG(dev, "pll.vco1.min_n: %d\n", pll_lim->vco1.min_n);
4724 NV_DEBUG(dev, "pll.vco1.max_n: %d\n", pll_lim->vco1.max_n);
4725 NV_DEBUG(dev, "pll.vco1.min_m: %d\n", pll_lim->vco1.min_m);
4726 NV_DEBUG(dev, "pll.vco1.max_m: %d\n", pll_lim->vco1.max_m);
4727 if (pll_lim->vco2.maxfreq) {
4728 NV_DEBUG(dev, "pll.vco2.minfreq: %d\n", pll_lim->vco2.minfreq);
4729 NV_DEBUG(dev, "pll.vco2.maxfreq: %d\n", pll_lim->vco2.maxfreq);
4730 NV_DEBUG(dev, "pll.vco2.min_inputfreq: %d\n", pll_lim->vco2.min_inputfreq);
4731 NV_DEBUG(dev, "pll.vco2.max_inputfreq: %d\n", pll_lim->vco2.max_inputfreq);
4732 NV_DEBUG(dev, "pll.vco2.min_n: %d\n", pll_lim->vco2.min_n);
4733 NV_DEBUG(dev, "pll.vco2.max_n: %d\n", pll_lim->vco2.max_n);
4734 NV_DEBUG(dev, "pll.vco2.min_m: %d\n", pll_lim->vco2.min_m);
4735 NV_DEBUG(dev, "pll.vco2.max_m: %d\n", pll_lim->vco2.max_m);
4736 }
4737 if (!pll_lim->max_p) {
4738 NV_DEBUG(dev, "pll.max_log2p: %d\n", pll_lim->max_log2p);
4739 NV_DEBUG(dev, "pll.log2p_bias: %d\n", pll_lim->log2p_bias);
4740 } else {
4741 NV_DEBUG(dev, "pll.min_p: %d\n", pll_lim->min_p);
4742 NV_DEBUG(dev, "pll.max_p: %d\n", pll_lim->max_p);
4743 }
4744 NV_DEBUG(dev, "pll.refclk: %d\n", pll_lim->refclk);
4745
4746 return 0;
4747}
4748
4749static void parse_bios_version(struct drm_device *dev, struct nvbios *bios, uint16_t offset) 4244static void parse_bios_version(struct drm_device *dev, struct nvbios *bios, uint16_t offset)
4750{ 4245{
4751 /* 4246 /*
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index 52fce11e9d26..e9bb14ec8c3b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -144,58 +144,6 @@ enum LVDS_script {
144 LVDS_PANEL_OFF 144 LVDS_PANEL_OFF
145}; 145};
146 146
147/* these match types in pll limits table version 0x40,
148 * nouveau uses them on all chipsets internally where a
149 * specific pll needs to be referenced, but the exact
150 * register isn't known.
151 */
152enum pll_types {
153 PLL_CORE = 0x01,
154 PLL_SHADER = 0x02,
155 PLL_UNK03 = 0x03,
156 PLL_MEMORY = 0x04,
157 PLL_VDEC = 0x05,
158 PLL_UNK40 = 0x40,
159 PLL_UNK41 = 0x41,
160 PLL_UNK42 = 0x42,
161 PLL_VPLL0 = 0x80,
162 PLL_VPLL1 = 0x81,
163 PLL_MAX = 0xff
164};
165
166struct pll_lims {
167 u32 reg;
168
169 struct {
170 int minfreq;
171 int maxfreq;
172 int min_inputfreq;
173 int max_inputfreq;
174
175 uint8_t min_m;
176 uint8_t max_m;
177 uint8_t min_n;
178 uint8_t max_n;
179 } vco1, vco2;
180
181 uint8_t max_log2p;
182 /*
183 * for most pre nv50 cards setting a log2P of 7 (the common max_log2p
184 * value) is no different to 6 (at least for vplls) so allowing the MNP
185 * calc to use 7 causes the generated clock to be out by a factor of 2.
186 * however, max_log2p cannot be fixed-up during parsing as the
187 * unmodified max_log2p value is still needed for setting mplls, hence
188 * an additional max_usable_log2p member
189 */
190 uint8_t max_usable_log2p;
191 uint8_t log2p_bias;
192
193 uint8_t min_p;
194 uint8_t max_p;
195
196 int refclk;
197};
198
199struct nvbios { 147struct nvbios {
200 struct drm_device *dev; 148 struct drm_device *dev;
201 enum { 149 enum {
diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c
index dad96cce5e39..5b487655d6b8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_calc.c
+++ b/drivers/gpu/drm/nouveau/nouveau_calc.c
@@ -260,219 +260,3 @@ nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm
260 } else 260 } else
261 nv20_update_arb(burst, lwm); 261 nv20_update_arb(burst, lwm);
262} 262}
263
264static int
265getMNP_single(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
266 struct nouveau_pll_vals *bestpv)
267{
268 /* Find M, N and P for a single stage PLL
269 *
270 * Note that some bioses (NV3x) have lookup tables of precomputed MNP
271 * values, but we're too lazy to use those atm
272 *
273 * "clk" parameter in kHz
274 * returns calculated clock
275 */
276 struct drm_nouveau_private *dev_priv = dev->dev_private;
277 int cv = dev_priv->vbios.chip_version;
278 int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq;
279 int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m;
280 int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n;
281 int minU = pll_lim->vco1.min_inputfreq;
282 int maxU = pll_lim->vco1.max_inputfreq;
283 int minP = pll_lim->max_p ? pll_lim->min_p : 0;
284 int maxP = pll_lim->max_p ? pll_lim->max_p : pll_lim->max_usable_log2p;
285 int crystal = pll_lim->refclk;
286 int M, N, thisP, P;
287 int clkP, calcclk;
288 int delta, bestdelta = INT_MAX;
289 int bestclk = 0;
290
291 /* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */
292 /* possibly correlated with introduction of 27MHz crystal */
293 if (dev_priv->card_type < NV_50) {
294 if (cv < 0x17 || cv == 0x1a || cv == 0x20) {
295 if (clk > 250000)
296 maxM = 6;
297 if (clk > 340000)
298 maxM = 2;
299 } else if (cv < 0x40) {
300 if (clk > 150000)
301 maxM = 6;
302 if (clk > 200000)
303 maxM = 4;
304 if (clk > 340000)
305 maxM = 2;
306 }
307 }
308
309 P = pll_lim->max_p ? maxP : (1 << maxP);
310 if ((clk * P) < minvco) {
311 minvco = clk * maxP;
312 maxvco = minvco * 2;
313 }
314
315 if (clk + clk/200 > maxvco) /* +0.5% */
316 maxvco = clk + clk/200;
317
318 /* NV34 goes maxlog2P->0, NV20 goes 0->maxlog2P */
319 for (thisP = minP; thisP <= maxP; thisP++) {
320 P = pll_lim->max_p ? thisP : (1 << thisP);
321 clkP = clk * P;
322
323 if (clkP < minvco)
324 continue;
325 if (clkP > maxvco)
326 return bestclk;
327
328 for (M = minM; M <= maxM; M++) {
329 if (crystal/M < minU)
330 return bestclk;
331 if (crystal/M > maxU)
332 continue;
333
334 /* add crystal/2 to round better */
335 N = (clkP * M + crystal/2) / crystal;
336
337 if (N < minN)
338 continue;
339 if (N > maxN)
340 break;
341
342 /* more rounding additions */
343 calcclk = ((N * crystal + P/2) / P + M/2) / M;
344 delta = abs(calcclk - clk);
345 /* we do an exhaustive search rather than terminating
346 * on an optimality condition...
347 */
348 if (delta < bestdelta) {
349 bestdelta = delta;
350 bestclk = calcclk;
351 bestpv->N1 = N;
352 bestpv->M1 = M;
353 bestpv->log2P = thisP;
354 if (delta == 0) /* except this one */
355 return bestclk;
356 }
357 }
358 }
359
360 return bestclk;
361}
362
363static int
364getMNP_double(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
365 struct nouveau_pll_vals *bestpv)
366{
367 /* Find M, N and P for a two stage PLL
368 *
369 * Note that some bioses (NV30+) have lookup tables of precomputed MNP
370 * values, but we're too lazy to use those atm
371 *
372 * "clk" parameter in kHz
373 * returns calculated clock
374 */
375 struct drm_nouveau_private *dev_priv = dev->dev_private;
376 int chip_version = dev_priv->vbios.chip_version;
377 int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq;
378 int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq;
379 int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq;
380 int maxU1 = pll_lim->vco1.max_inputfreq, maxU2 = pll_lim->vco2.max_inputfreq;
381 int minM1 = pll_lim->vco1.min_m, maxM1 = pll_lim->vco1.max_m;
382 int minN1 = pll_lim->vco1.min_n, maxN1 = pll_lim->vco1.max_n;
383 int minM2 = pll_lim->vco2.min_m, maxM2 = pll_lim->vco2.max_m;
384 int minN2 = pll_lim->vco2.min_n, maxN2 = pll_lim->vco2.max_n;
385 int maxlog2P = pll_lim->max_usable_log2p;
386 int crystal = pll_lim->refclk;
387 bool fixedgain2 = (minM2 == maxM2 && minN2 == maxN2);
388 int M1, N1, M2, N2, log2P;
389 int clkP, calcclk1, calcclk2, calcclkout;
390 int delta, bestdelta = INT_MAX;
391 int bestclk = 0;
392
393 int vco2 = (maxvco2 - maxvco2/200) / 2;
394 for (log2P = 0; clk && log2P < maxlog2P && clk <= (vco2 >> log2P); log2P++)
395 ;
396 clkP = clk << log2P;
397
398 if (maxvco2 < clk + clk/200) /* +0.5% */
399 maxvco2 = clk + clk/200;
400
401 for (M1 = minM1; M1 <= maxM1; M1++) {
402 if (crystal/M1 < minU1)
403 return bestclk;
404 if (crystal/M1 > maxU1)
405 continue;
406
407 for (N1 = minN1; N1 <= maxN1; N1++) {
408 calcclk1 = crystal * N1 / M1;
409 if (calcclk1 < minvco1)
410 continue;
411 if (calcclk1 > maxvco1)
412 break;
413
414 for (M2 = minM2; M2 <= maxM2; M2++) {
415 if (calcclk1/M2 < minU2)
416 break;
417 if (calcclk1/M2 > maxU2)
418 continue;
419
420 /* add calcclk1/2 to round better */
421 N2 = (clkP * M2 + calcclk1/2) / calcclk1;
422 if (N2 < minN2)
423 continue;
424 if (N2 > maxN2)
425 break;
426
427 if (!fixedgain2) {
428 if (chip_version < 0x60)
429 if (N2/M2 < 4 || N2/M2 > 10)
430 continue;
431
432 calcclk2 = calcclk1 * N2 / M2;
433 if (calcclk2 < minvco2)
434 break;
435 if (calcclk2 > maxvco2)
436 continue;
437 } else
438 calcclk2 = calcclk1;
439
440 calcclkout = calcclk2 >> log2P;
441 delta = abs(calcclkout - clk);
442 /* we do an exhaustive search rather than terminating
443 * on an optimality condition...
444 */
445 if (delta < bestdelta) {
446 bestdelta = delta;
447 bestclk = calcclkout;
448 bestpv->N1 = N1;
449 bestpv->M1 = M1;
450 bestpv->N2 = N2;
451 bestpv->M2 = M2;
452 bestpv->log2P = log2P;
453 if (delta == 0) /* except this one */
454 return bestclk;
455 }
456 }
457 }
458 }
459
460 return bestclk;
461}
462
463int
464nouveau_calc_pll_mnp(struct drm_device *dev, struct pll_lims *pll_lim, int clk,
465 struct nouveau_pll_vals *pv)
466{
467 int outclk;
468
469 if (!pll_lim->vco2.maxfreq)
470 outclk = getMNP_single(dev, pll_lim, clk, pv);
471 else
472 outclk = getMNP_double(dev, pll_lim, clk, pv);
473
474 if (!outclk)
475 NV_ERROR(dev, "Could not find a compatible set of PLL values\n");
476
477 return outclk;
478}
diff --git a/drivers/gpu/drm/nouveau/nouveau_compat.c b/drivers/gpu/drm/nouveau/nouveau_compat.c
index 76582b0a9df8..30431c820bb3 100644
--- a/drivers/gpu/drm/nouveau/nouveau_compat.c
+++ b/drivers/gpu/drm/nouveau/nouveau_compat.c
@@ -2,8 +2,10 @@
2#include "nouveau_compat.h" 2#include "nouveau_compat.h"
3 3
4#include <subdev/bios.h> 4#include <subdev/bios.h>
5#include <subdev/bios/pll.h>
5#include <subdev/gpio.h> 6#include <subdev/gpio.h>
6#include <subdev/i2c.h> 7#include <subdev/i2c.h>
8#include <subdev/clock.h>
7 9
8void *nouveau_newpriv(struct drm_device *); 10void *nouveau_newpriv(struct drm_device *);
9 11
@@ -180,3 +182,76 @@ auxch_wr(struct drm_device *dev, struct nouveau_i2c_port *port,
180{ 182{
181 return nv_wraux(port, addr, data, size); 183 return nv_wraux(port, addr, data, size);
182} 184}
185
186u32
187get_pll_register(struct drm_device *dev, u32 type)
188{
189 struct nouveau_drm *drm = nouveau_newpriv(dev);
190 struct nouveau_bios *bios = nouveau_bios(drm->device);
191 struct nvbios_pll info;
192
193 if (nvbios_pll_parse(bios, type, &info))
194 return 0;
195 return info.reg;
196}
197
198int
199get_pll_limits(struct drm_device *dev, u32 type, struct nvbios_pll *info)
200{
201 struct nouveau_drm *drm = nouveau_newpriv(dev);
202 struct nouveau_bios *bios = nouveau_bios(drm->device);
203
204 return nvbios_pll_parse(bios, type, info);
205}
206
207int
208setPLL(struct drm_device *dev, u32 reg, u32 freq)
209{
210 struct nouveau_drm *drm = nouveau_newpriv(dev);
211 struct nouveau_clock *clk = nouveau_clock(drm->device);
212 int ret = -ENODEV;
213
214 if (clk->pll_set)
215 ret = clk->pll_set(clk, reg, freq);
216 return ret;
217}
218
219
220int
221nouveau_calc_pll_mnp(struct drm_device *dev, struct nvbios_pll *info,
222 int freq, struct nouveau_pll_vals *pv)
223{
224 struct nouveau_drm *drm = nouveau_newpriv(dev);
225 struct nouveau_clock *clk = nouveau_clock(drm->device);
226 int ret = 0;
227
228 if (clk->pll_calc)
229 ret = clk->pll_calc(clk, info, freq, pv);
230 return ret;
231}
232
233int
234nouveau_hw_setpll(struct drm_device *dev, u32 reg1,
235 struct nouveau_pll_vals *pv)
236{
237 struct nouveau_drm *drm = nouveau_newpriv(dev);
238 struct nouveau_clock *clk = nouveau_clock(drm->device);
239 int ret = -ENODEV;
240
241 if (clk->pll_prog)
242 ret = clk->pll_prog(clk, reg1, pv);
243 return ret;
244}
245
246int nva3_pll_calc(struct nouveau_clock *, struct nvbios_pll *, u32 freq,
247 int *N, int *fN, int *M, int *P);
248
249int
250nva3_calc_pll(struct drm_device *dev, struct nvbios_pll *info, u32 freq,
251 int *N, int *fN, int *M, int *P)
252{
253 struct nouveau_drm *drm = nouveau_newpriv(dev);
254 struct nouveau_clock *clk = nouveau_clock(drm->device);
255
256 return nva3_pll_calc(clk, info, freq, N, fN, M, P);
257}
diff --git a/drivers/gpu/drm/nouveau/nouveau_compat.h b/drivers/gpu/drm/nouveau/nouveau_compat.h
index 9b3298bfe4ed..8bf5bec81710 100644
--- a/drivers/gpu/drm/nouveau/nouveau_compat.h
+++ b/drivers/gpu/drm/nouveau/nouveau_compat.h
@@ -32,5 +32,17 @@ int nouveau_i2c_identify(struct drm_device *dev, const char *what,
32int auxch_rd(struct drm_device *, struct nouveau_i2c_port *, u32, u8 *, u8); 32int auxch_rd(struct drm_device *, struct nouveau_i2c_port *, u32, u8 *, u8);
33int auxch_wr(struct drm_device *, struct nouveau_i2c_port *, u32, u8 *, u8); 33int auxch_wr(struct drm_device *, struct nouveau_i2c_port *, u32, u8 *, u8);
34 34
35struct nvbios_pll;
36struct nouveau_pll_vals;
37
38u32 get_pll_register(struct drm_device *dev, u32 type);
39int get_pll_limits(struct drm_device *, u32, struct nvbios_pll *);
40int setPLL(struct drm_device *, u32 reg, u32 clk);
41
42int nouveau_calc_pll_mnp(struct drm_device *, struct nvbios_pll *,
43 int, struct nouveau_pll_vals *);
44int nva3_calc_pll(struct drm_device *dev, struct nvbios_pll *info, u32 freq,
45 int *N, int *fN, int *M, int *P);
46int nouveau_hw_setpll(struct drm_device *, u32, struct nouveau_pll_vals *);
35 47
36#endif 48#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index afe978702097..2b519b5cfac9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -68,6 +68,9 @@ struct nouveau_grctx;
68struct nouveau_mem; 68struct nouveau_mem;
69#include <subdev/vm.h> 69#include <subdev/vm.h>
70 70
71#include <subdev/bios/pll.h>
72#include "nouveau_compat.h"
73
71#define MAX_NUM_DCB_ENTRIES 16 74#define MAX_NUM_DCB_ENTRIES 16
72 75
73#define NOUVEAU_MAX_CHANNEL_NR 4096 76#define NOUVEAU_MAX_CHANNEL_NR 4096
@@ -549,24 +552,6 @@ struct nouveau_engine {
549 struct nouveau_vram_engine vram; 552 struct nouveau_vram_engine vram;
550}; 553};
551 554
552struct nouveau_pll_vals {
553 union {
554 struct {
555#ifdef __BIG_ENDIAN
556 uint8_t N1, M1, N2, M2;
557#else
558 uint8_t M1, N1, M2, N2;
559#endif
560 };
561 struct {
562 uint16_t NM1, NM2;
563 } __attribute__((packed));
564 };
565 int log2P;
566
567 int refclk;
568};
569
570enum nv04_fp_display_regs { 555enum nv04_fp_display_regs {
571 FP_DISPLAY_END, 556 FP_DISPLAY_END,
572 FP_TOTAL, 557 FP_TOTAL,
@@ -1060,9 +1045,6 @@ extern void nouveau_bios_run_init_table(struct drm_device *, uint16_t table,
1060extern void nouveau_bios_init_exec(struct drm_device *, uint16_t table); 1045extern void nouveau_bios_init_exec(struct drm_device *, uint16_t table);
1061extern struct dcb_connector_table_entry * 1046extern struct dcb_connector_table_entry *
1062nouveau_bios_connector_entry(struct drm_device *, int index); 1047nouveau_bios_connector_entry(struct drm_device *, int index);
1063extern u32 get_pll_register(struct drm_device *, enum pll_types);
1064extern int get_pll_limits(struct drm_device *, uint32_t limit_match,
1065 struct pll_lims *);
1066extern int nouveau_bios_run_display_table(struct drm_device *, u16 id, int clk, 1048extern int nouveau_bios_run_display_table(struct drm_device *, u16 id, int clk,
1067 struct dcb_entry *, int crtc); 1049 struct dcb_entry *, int crtc);
1068extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *); 1050extern bool nouveau_bios_fp_mode(struct drm_device *, struct drm_display_mode *);
@@ -1365,12 +1347,6 @@ int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *,
1365int nouveau_display_dumb_destroy(struct drm_file *, struct drm_device *, 1347int nouveau_display_dumb_destroy(struct drm_file *, struct drm_device *,
1366 uint32_t handle); 1348 uint32_t handle);
1367 1349
1368/* nv50_calc.c */
1369int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk,
1370 int *N1, int *M1, int *N2, int *M2, int *P);
1371int nva3_calc_pll(struct drm_device *, struct pll_lims *,
1372 int clk, int *N, int *fN, int *M, int *P);
1373
1374#ifndef ioread32_native 1350#ifndef ioread32_native
1375#ifdef __BIG_ENDIAN 1351#ifdef __BIG_ENDIAN
1376#define ioread16_native ioread16be 1352#define ioread16_native ioread16be
@@ -1398,7 +1374,6 @@ static inline void nvchan_wr32(struct nouveau_channel *chan,
1398} 1374}
1399 1375
1400/* register access */ 1376/* register access */
1401#include "nouveau_compat.h"
1402#define nv_rd08 _nv_rd08 1377#define nv_rd08 _nv_rd08
1403#define nv_wr08 _nv_wr08 1378#define nv_wr08 _nv_wr08
1404#define nv_rd32 _nv_rd32 1379#define nv_rd32 _nv_rd32
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c
index b87ad3bd7739..fdd667b70528 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.c
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.c
@@ -26,6 +26,8 @@
26#include "nouveau_drv.h" 26#include "nouveau_drv.h"
27#include "nouveau_hw.h" 27#include "nouveau_hw.h"
28 28
29#include <subdev/bios/pll.h>
30
29#define CHIPSET_NFORCE 0x01a0 31#define CHIPSET_NFORCE 0x01a0
30#define CHIPSET_NFORCE2 0x01f0 32#define CHIPSET_NFORCE2 0x01f0
31 33
@@ -123,270 +125,6 @@ NVBlankScreen(struct drm_device *dev, int head, bool blank)
123} 125}
124 126
125/* 127/*
126 * PLL setting
127 */
128
129static int
130powerctrl_1_shift(int chip_version, int reg)
131{
132 int shift = -4;
133
134 if (chip_version < 0x17 || chip_version == 0x1a || chip_version == 0x20)
135 return shift;
136
137 switch (reg) {
138 case NV_RAMDAC_VPLL2:
139 shift += 4;
140 case NV_PRAMDAC_VPLL_COEFF:
141 shift += 4;
142 case NV_PRAMDAC_MPLL_COEFF:
143 shift += 4;
144 case NV_PRAMDAC_NVPLL_COEFF:
145 shift += 4;
146 }
147
148 /*
149 * the shift for vpll regs is only used for nv3x chips with a single
150 * stage pll
151 */
152 if (shift > 4 && (chip_version < 0x32 || chip_version == 0x35 ||
153 chip_version == 0x36 || chip_version >= 0x40))
154 shift = -4;
155
156 return shift;
157}
158
159static void
160setPLL_single(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv)
161{
162 struct drm_nouveau_private *dev_priv = dev->dev_private;
163 int chip_version = dev_priv->vbios.chip_version;
164 uint32_t oldpll = NVReadRAMDAC(dev, 0, reg);
165 int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff;
166 uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1;
167 uint32_t saved_powerctrl_1 = 0;
168 int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg);
169
170 if (oldpll == pll)
171 return; /* already set */
172
173 if (shift_powerctrl_1 >= 0) {
174 saved_powerctrl_1 = nvReadMC(dev, NV_PBUS_POWERCTRL_1);
175 nvWriteMC(dev, NV_PBUS_POWERCTRL_1,
176 (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
177 1 << shift_powerctrl_1);
178 }
179
180 if (oldM && pv->M1 && (oldN / oldM < pv->N1 / pv->M1))
181 /* upclock -- write new post divider first */
182 NVWriteRAMDAC(dev, 0, reg, pv->log2P << 16 | (oldpll & 0xffff));
183 else
184 /* downclock -- write new NM first */
185 NVWriteRAMDAC(dev, 0, reg, (oldpll & 0xffff0000) | pv->NM1);
186
187 if (chip_version < 0x17 && chip_version != 0x11)
188 /* wait a bit on older chips */
189 msleep(64);
190 NVReadRAMDAC(dev, 0, reg);
191
192 /* then write the other half as well */
193 NVWriteRAMDAC(dev, 0, reg, pll);
194
195 if (shift_powerctrl_1 >= 0)
196 nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1);
197}
198
199static uint32_t
200new_ramdac580(uint32_t reg1, bool ss, uint32_t ramdac580)
201{
202 bool head_a = (reg1 == NV_PRAMDAC_VPLL_COEFF);
203
204 if (ss) /* single stage pll mode */
205 ramdac580 |= head_a ? NV_RAMDAC_580_VPLL1_ACTIVE :
206 NV_RAMDAC_580_VPLL2_ACTIVE;
207 else
208 ramdac580 &= head_a ? ~NV_RAMDAC_580_VPLL1_ACTIVE :
209 ~NV_RAMDAC_580_VPLL2_ACTIVE;
210
211 return ramdac580;
212}
213
214static void
215setPLL_double_highregs(struct drm_device *dev, uint32_t reg1,
216 struct nouveau_pll_vals *pv)
217{
218 struct drm_nouveau_private *dev_priv = dev->dev_private;
219 int chip_version = dev_priv->vbios.chip_version;
220 bool nv3035 = chip_version == 0x30 || chip_version == 0x35;
221 uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70);
222 uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1);
223 uint32_t oldpll2 = !nv3035 ? NVReadRAMDAC(dev, 0, reg2) : 0;
224 uint32_t pll1 = (oldpll1 & 0xfff80000) | pv->log2P << 16 | pv->NM1;
225 uint32_t pll2 = (oldpll2 & 0x7fff0000) | 1 << 31 | pv->NM2;
226 uint32_t oldramdac580 = 0, ramdac580 = 0;
227 bool single_stage = !pv->NM2 || pv->N2 == pv->M2; /* nv41+ only */
228 uint32_t saved_powerctrl_1 = 0, savedc040 = 0;
229 int shift_powerctrl_1 = powerctrl_1_shift(chip_version, reg1);
230
231 /* model specific additions to generic pll1 and pll2 set up above */
232 if (nv3035) {
233 pll1 = (pll1 & 0xfcc7ffff) | (pv->N2 & 0x18) << 21 |
234 (pv->N2 & 0x7) << 19 | 8 << 4 | (pv->M2 & 7) << 4;
235 pll2 = 0;
236 }
237 if (chip_version > 0x40 && reg1 >= NV_PRAMDAC_VPLL_COEFF) { /* !nv40 */
238 oldramdac580 = NVReadRAMDAC(dev, 0, NV_PRAMDAC_580);
239 ramdac580 = new_ramdac580(reg1, single_stage, oldramdac580);
240 if (oldramdac580 != ramdac580)
241 oldpll1 = ~0; /* force mismatch */
242 if (single_stage)
243 /* magic value used by nvidia in single stage mode */
244 pll2 |= 0x011f;
245 }
246 if (chip_version > 0x70)
247 /* magic bits set by the blob (but not the bios) on g71-73 */
248 pll1 = (pll1 & 0x7fffffff) | (single_stage ? 0x4 : 0xc) << 28;
249
250 if (oldpll1 == pll1 && oldpll2 == pll2)
251 return; /* already set */
252
253 if (shift_powerctrl_1 >= 0) {
254 saved_powerctrl_1 = nvReadMC(dev, NV_PBUS_POWERCTRL_1);
255 nvWriteMC(dev, NV_PBUS_POWERCTRL_1,
256 (saved_powerctrl_1 & ~(0xf << shift_powerctrl_1)) |
257 1 << shift_powerctrl_1);
258 }
259
260 if (chip_version >= 0x40) {
261 int shift_c040 = 14;
262
263 switch (reg1) {
264 case NV_PRAMDAC_MPLL_COEFF:
265 shift_c040 += 2;
266 case NV_PRAMDAC_NVPLL_COEFF:
267 shift_c040 += 2;
268 case NV_RAMDAC_VPLL2:
269 shift_c040 += 2;
270 case NV_PRAMDAC_VPLL_COEFF:
271 shift_c040 += 2;
272 }
273
274 savedc040 = nvReadMC(dev, 0xc040);
275 if (shift_c040 != 14)
276 nvWriteMC(dev, 0xc040, savedc040 & ~(3 << shift_c040));
277 }
278
279 if (oldramdac580 != ramdac580)
280 NVWriteRAMDAC(dev, 0, NV_PRAMDAC_580, ramdac580);
281
282 if (!nv3035)
283 NVWriteRAMDAC(dev, 0, reg2, pll2);
284 NVWriteRAMDAC(dev, 0, reg1, pll1);
285
286 if (shift_powerctrl_1 >= 0)
287 nvWriteMC(dev, NV_PBUS_POWERCTRL_1, saved_powerctrl_1);
288 if (chip_version >= 0x40)
289 nvWriteMC(dev, 0xc040, savedc040);
290}
291
292static void
293setPLL_double_lowregs(struct drm_device *dev, uint32_t NMNMreg,
294 struct nouveau_pll_vals *pv)
295{
296 /* When setting PLLs, there is a merry game of disabling and enabling
297 * various bits of hardware during the process. This function is a
298 * synthesis of six nv4x traces, nearly each card doing a subtly
299 * different thing. With luck all the necessary bits for each card are
300 * combined herein. Without luck it deviates from each card's formula
301 * so as to not work on any :)
302 */
303
304 uint32_t Preg = NMNMreg - 4;
305 bool mpll = Preg == 0x4020;
306 uint32_t oldPval = nvReadMC(dev, Preg);
307 uint32_t NMNM = pv->NM2 << 16 | pv->NM1;
308 uint32_t Pval = (oldPval & (mpll ? ~(0x77 << 16) : ~(7 << 16))) |
309 0xc << 28 | pv->log2P << 16;
310 uint32_t saved4600 = 0;
311 /* some cards have different maskc040s */
312 uint32_t maskc040 = ~(3 << 14), savedc040;
313 bool single_stage = !pv->NM2 || pv->N2 == pv->M2;
314
315 if (nvReadMC(dev, NMNMreg) == NMNM && (oldPval & 0xc0070000) == Pval)
316 return;
317
318 if (Preg == 0x4000)
319 maskc040 = ~0x333;
320 if (Preg == 0x4058)
321 maskc040 = ~(0xc << 24);
322
323 if (mpll) {
324 struct pll_lims pll_lim;
325 uint8_t Pval2;
326
327 if (get_pll_limits(dev, Preg, &pll_lim))
328 return;
329
330 Pval2 = pv->log2P + pll_lim.log2p_bias;
331 if (Pval2 > pll_lim.max_log2p)
332 Pval2 = pll_lim.max_log2p;
333 Pval |= 1 << 28 | Pval2 << 20;
334
335 saved4600 = nvReadMC(dev, 0x4600);
336 nvWriteMC(dev, 0x4600, saved4600 | 8 << 28);
337 }
338 if (single_stage)
339 Pval |= mpll ? 1 << 12 : 1 << 8;
340
341 nvWriteMC(dev, Preg, oldPval | 1 << 28);
342 nvWriteMC(dev, Preg, Pval & ~(4 << 28));
343 if (mpll) {
344 Pval |= 8 << 20;
345 nvWriteMC(dev, 0x4020, Pval & ~(0xc << 28));
346 nvWriteMC(dev, 0x4038, Pval & ~(0xc << 28));
347 }
348
349 savedc040 = nvReadMC(dev, 0xc040);
350 nvWriteMC(dev, 0xc040, savedc040 & maskc040);
351
352 nvWriteMC(dev, NMNMreg, NMNM);
353 if (NMNMreg == 0x4024)
354 nvWriteMC(dev, 0x403c, NMNM);
355
356 nvWriteMC(dev, Preg, Pval);
357 if (mpll) {
358 Pval &= ~(8 << 20);
359 nvWriteMC(dev, 0x4020, Pval);
360 nvWriteMC(dev, 0x4038, Pval);
361 nvWriteMC(dev, 0x4600, saved4600);
362 }
363
364 nvWriteMC(dev, 0xc040, savedc040);
365
366 if (mpll) {
367 nvWriteMC(dev, 0x4020, Pval & ~(1 << 28));
368 nvWriteMC(dev, 0x4038, Pval & ~(1 << 28));
369 }
370}
371
372void
373nouveau_hw_setpll(struct drm_device *dev, uint32_t reg1,
374 struct nouveau_pll_vals *pv)
375{
376 struct drm_nouveau_private *dev_priv = dev->dev_private;
377 int cv = dev_priv->vbios.chip_version;
378
379 if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 ||
380 cv >= 0x40) {
381 if (reg1 > 0x405c)
382 setPLL_double_highregs(dev, reg1, pv);
383 else
384 setPLL_double_lowregs(dev, reg1, pv);
385 } else
386 setPLL_single(dev, reg1, pv);
387}
388
389/*
390 * PLL getting 128 * PLL getting
391 */ 129 */
392 130
@@ -423,12 +161,12 @@ nouveau_hw_decode_pll(struct drm_device *dev, uint32_t reg1, uint32_t pll1,
423} 161}
424 162
425int 163int
426nouveau_hw_get_pllvals(struct drm_device *dev, enum pll_types plltype, 164nouveau_hw_get_pllvals(struct drm_device *dev, enum nvbios_pll_type plltype,
427 struct nouveau_pll_vals *pllvals) 165 struct nouveau_pll_vals *pllvals)
428{ 166{
429 struct drm_nouveau_private *dev_priv = dev->dev_private; 167 struct drm_nouveau_private *dev_priv = dev->dev_private;
430 uint32_t reg1 = get_pll_register(dev, plltype), pll1, pll2 = 0; 168 uint32_t reg1 = get_pll_register(dev, plltype), pll1, pll2 = 0;
431 struct pll_lims pll_lim; 169 struct nvbios_pll pll_lim;
432 int ret; 170 int ret;
433 171
434 if (reg1 == 0) 172 if (reg1 == 0)
@@ -478,7 +216,7 @@ nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pv)
478} 216}
479 217
480int 218int
481nouveau_hw_get_clock(struct drm_device *dev, enum pll_types plltype) 219nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype)
482{ 220{
483 struct nouveau_pll_vals pllvals; 221 struct nouveau_pll_vals pllvals;
484 int ret; 222 int ret;
@@ -517,9 +255,9 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
517 * when such a condition detected. only seen on nv11 to date 255 * when such a condition detected. only seen on nv11 to date
518 */ 256 */
519 257
520 struct pll_lims pll_lim; 258 struct nvbios_pll pll_lim;
521 struct nouveau_pll_vals pv; 259 struct nouveau_pll_vals pv;
522 enum pll_types pll = head ? PLL_VPLL1 : PLL_VPLL0; 260 enum nvbios_pll_type pll = head ? PLL_VPLL1 : PLL_VPLL0;
523 261
524 if (get_pll_limits(dev, pll, &pll_lim)) 262 if (get_pll_limits(dev, pll, &pll_lim))
525 return; 263 return;
@@ -527,7 +265,7 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
527 265
528 if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m && 266 if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m &&
529 pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n && 267 pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n &&
530 pv.log2P <= pll_lim.max_log2p) 268 pv.log2P <= pll_lim.max_p)
531 return; 269 return;
532 270
533 NV_WARN(dev, "VPLL %d outwith limits, attempting to fix\n", head + 1); 271 NV_WARN(dev, "VPLL %d outwith limits, attempting to fix\n", head + 1);
@@ -535,7 +273,7 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head)
535 /* set lowest clock within static limits */ 273 /* set lowest clock within static limits */
536 pv.M1 = pll_lim.vco1.max_m; 274 pv.M1 = pll_lim.vco1.max_m;
537 pv.N1 = pll_lim.vco1.min_n; 275 pv.N1 = pll_lim.vco1.min_n;
538 pv.log2P = pll_lim.max_usable_log2p; 276 pv.log2P = pll_lim.max_p_usable;
539 nouveau_hw_setpll(dev, pll_lim.reg, &pv); 277 nouveau_hw_setpll(dev, pll_lim.reg, &pv);
540} 278}
541 279
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/nouveau_hw.h
index 2989090b9434..ff7f31c279d8 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.h
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.h
@@ -26,6 +26,8 @@
26#include "drmP.h" 26#include "drmP.h"
27#include "nouveau_drv.h" 27#include "nouveau_drv.h"
28 28
29#include <subdev/bios/pll.h>
30
29#define MASK(field) ( \ 31#define MASK(field) ( \
30 (0xffffffff >> (31 - ((1 ? field) - (0 ? field)))) << (0 ? field)) 32 (0xffffffff >> (31 - ((1 ? field) - (0 ? field)))) << (0 ? field))
31 33
@@ -38,12 +40,10 @@ void NVWriteVgaGr(struct drm_device *, int head, uint8_t index, uint8_t value);
38uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index); 40uint8_t NVReadVgaGr(struct drm_device *, int head, uint8_t index);
39void NVSetOwner(struct drm_device *, int owner); 41void NVSetOwner(struct drm_device *, int owner);
40void NVBlankScreen(struct drm_device *, int head, bool blank); 42void NVBlankScreen(struct drm_device *, int head, bool blank);
41void nouveau_hw_setpll(struct drm_device *, uint32_t reg1, 43int nouveau_hw_get_pllvals(struct drm_device *, enum nvbios_pll_type plltype,
42 struct nouveau_pll_vals *pv);
43int nouveau_hw_get_pllvals(struct drm_device *, enum pll_types plltype,
44 struct nouveau_pll_vals *pllvals); 44 struct nouveau_pll_vals *pllvals);
45int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals); 45int nouveau_hw_pllvals_to_clk(struct nouveau_pll_vals *pllvals);
46int nouveau_hw_get_clock(struct drm_device *, enum pll_types plltype); 46int nouveau_hw_get_clock(struct drm_device *, enum nvbios_pll_type plltype);
47void nouveau_hw_save_vga_fonts(struct drm_device *, bool save); 47void nouveau_hw_save_vga_fonts(struct drm_device *, bool save);
48void nouveau_hw_save_state(struct drm_device *, int head, 48void nouveau_hw_save_state(struct drm_device *, int head,
49 struct nv04_mode_state *state); 49 struct nv04_mode_state *state);
@@ -55,8 +55,6 @@ void nouveau_hw_load_state_palette(struct drm_device *, int head,
55/* nouveau_calc.c */ 55/* nouveau_calc.c */
56extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp, 56extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp,
57 int *burst, int *lwm); 57 int *burst, int *lwm);
58extern int nouveau_calc_pll_mnp(struct drm_device *, struct pll_lims *pll_lim,
59 int clk, struct nouveau_pll_vals *pv);
60 58
61static inline uint32_t 59static inline uint32_t
62nvReadMC(struct drm_device *dev, uint32_t reg) 60nvReadMC(struct drm_device *dev, uint32_t reg)
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c
index 43accc11102f..93ca09b90da5 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -108,7 +108,7 @@ static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mod
108 struct nv04_mode_state *state = &dev_priv->mode_reg; 108 struct nv04_mode_state *state = &dev_priv->mode_reg;
109 struct nv04_crtc_reg *regp = &state->crtc_reg[nv_crtc->index]; 109 struct nv04_crtc_reg *regp = &state->crtc_reg[nv_crtc->index];
110 struct nouveau_pll_vals *pv = &regp->pllvals; 110 struct nouveau_pll_vals *pv = &regp->pllvals;
111 struct pll_lims pll_lim; 111 struct nvbios_pll pll_lim;
112 112
113 if (get_pll_limits(dev, nv_crtc->index ? PLL_VPLL1 : PLL_VPLL0, &pll_lim)) 113 if (get_pll_limits(dev, nv_crtc->index ? PLL_VPLL1 : PLL_VPLL0, &pll_lim))
114 return; 114 return;
@@ -126,7 +126,7 @@ static void nv_crtc_calc_state_ext(struct drm_crtc *crtc, struct drm_display_mod
126 * has yet been observed in allowing the use a single stage pll on all 126 * has yet been observed in allowing the use a single stage pll on all
127 * nv43 however. the behaviour of single stage use is untested on nv40 127 * nv43 however. the behaviour of single stage use is untested on nv40
128 */ 128 */
129 if (dev_priv->chipset > 0x40 && dot_clock <= (pll_lim.vco1.maxfreq / 2)) 129 if (dev_priv->chipset > 0x40 && dot_clock <= (pll_lim.vco1.max_freq / 2))
130 memset(&pll_lim.vco2, 0, sizeof(pll_lim.vco2)); 130 memset(&pll_lim.vco2, 0, sizeof(pll_lim.vco2));
131 131
132 if (!nouveau_calc_pll_mnp(dev, &pll_lim, dot_clock, pv)) 132 if (!nouveau_calc_pll_mnp(dev, &pll_lim, dot_clock, pv))
diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c
index 6e7589918fa9..4528d48dc52b 100644
--- a/drivers/gpu/drm/nouveau/nv04_pm.c
+++ b/drivers/gpu/drm/nouveau/nv04_pm.c
@@ -46,7 +46,7 @@ nv04_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
46} 46}
47 47
48struct nv04_pm_clock { 48struct nv04_pm_clock {
49 struct pll_lims pll; 49 struct nvbios_pll pll;
50 struct nouveau_pll_vals calc; 50 struct nouveau_pll_vals calc;
51}; 51};
52 52
diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c
index 661d9cfd980d..d857525666ee 100644
--- a/drivers/gpu/drm/nouveau/nv40_pm.c
+++ b/drivers/gpu/drm/nouveau/nv40_pm.c
@@ -107,7 +107,7 @@ struct nv40_pm_state {
107}; 107};
108 108
109static int 109static int
110nv40_calc_pll(struct drm_device *dev, u32 reg, struct pll_lims *pll, 110nv40_calc_pll(struct drm_device *dev, u32 reg, struct nvbios_pll *pll,
111 u32 clk, int *N1, int *M1, int *N2, int *M2, int *log2P) 111 u32 clk, int *N1, int *M1, int *N2, int *M2, int *log2P)
112{ 112{
113 struct nouveau_pll_vals coef; 113 struct nouveau_pll_vals coef;
@@ -117,8 +117,8 @@ nv40_calc_pll(struct drm_device *dev, u32 reg, struct pll_lims *pll,
117 if (ret) 117 if (ret)
118 return ret; 118 return ret;
119 119
120 if (clk < pll->vco1.maxfreq) 120 if (clk < pll->vco1.max_freq)
121 pll->vco2.maxfreq = 0; 121 pll->vco2.max_freq = 0;
122 122
123 ret = nouveau_calc_pll_mnp(dev, pll, clk, &coef); 123 ret = nouveau_calc_pll_mnp(dev, pll, clk, &coef);
124 if (ret == 0) 124 if (ret == 0)
@@ -127,7 +127,7 @@ nv40_calc_pll(struct drm_device *dev, u32 reg, struct pll_lims *pll,
127 *N1 = coef.N1; 127 *N1 = coef.N1;
128 *M1 = coef.M1; 128 *M1 = coef.M1;
129 if (N2 && M2) { 129 if (N2 && M2) {
130 if (pll->vco2.maxfreq) { 130 if (pll->vco2.max_freq) {
131 *N2 = coef.N2; 131 *N2 = coef.N2;
132 *M2 = coef.M2; 132 *M2 = coef.M2;
133 } else { 133 } else {
@@ -143,7 +143,7 @@ void *
143nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) 143nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
144{ 144{
145 struct nv40_pm_state *info; 145 struct nv40_pm_state *info;
146 struct pll_lims pll; 146 struct nvbios_pll pll;
147 int N1, N2, M1, M2, log2P; 147 int N1, N2, M1, M2, log2P;
148 int ret; 148 int ret;
149 149
@@ -191,7 +191,7 @@ nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
191 goto out; 191 goto out;
192 192
193 info->mpll_ctrl = 0x80000000 | (log2P << 16); 193 info->mpll_ctrl = 0x80000000 | (log2P << 16);
194 info->mpll_ctrl |= min2(pll.log2p_bias + log2P, pll.max_log2p) << 20; 194 info->mpll_ctrl |= min2(pll.bias_p + log2P, pll.max_p) << 20;
195 if (N2 == M2) { 195 if (N2 == M2) {
196 info->mpll_ctrl |= 0x00000100; 196 info->mpll_ctrl |= 0x00000100;
197 info->mpll_coef = (N1 << 8) | M1; 197 info->mpll_coef = (N1 << 8) | M1;
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c
index 22cebd5dd694..40042c1bbc6e 100644
--- a/drivers/gpu/drm/nouveau/nv50_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv50_crtc.c
@@ -329,55 +329,7 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
329int 329int
330nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk) 330nv50_crtc_set_clock(struct drm_device *dev, int head, int pclk)
331{ 331{
332 struct drm_nouveau_private *dev_priv = dev->dev_private; 332 return setPLL(dev, PLL_VPLL0 + head, pclk);
333 struct pll_lims pll;
334 uint32_t reg1, reg2;
335 int ret, N1, M1, N2, M2, P;
336
337 ret = get_pll_limits(dev, PLL_VPLL0 + head, &pll);
338 if (ret)
339 return ret;
340
341 if (pll.vco2.maxfreq) {
342 ret = nv50_calc_pll(dev, &pll, pclk, &N1, &M1, &N2, &M2, &P);
343 if (ret <= 0)
344 return 0;
345
346 NV_DEBUG(dev, "pclk %d out %d NM1 %d %d NM2 %d %d P %d\n",
347 pclk, ret, N1, M1, N2, M2, P);
348
349 reg1 = nv_rd32(dev, pll.reg + 4) & 0xff00ff00;
350 reg2 = nv_rd32(dev, pll.reg + 8) & 0x8000ff00;
351 nv_wr32(dev, pll.reg + 0, 0x10000611);
352 nv_wr32(dev, pll.reg + 4, reg1 | (M1 << 16) | N1);
353 nv_wr32(dev, pll.reg + 8, reg2 | (P << 28) | (M2 << 16) | N2);
354 } else
355 if (dev_priv->chipset < NV_C0) {
356 ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P);
357 if (ret <= 0)
358 return 0;
359
360 NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n",
361 pclk, ret, N1, N2, M1, P);
362
363 reg1 = nv_rd32(dev, pll.reg + 4) & 0xffc00000;
364 nv_wr32(dev, pll.reg + 0, 0x50000610);
365 nv_wr32(dev, pll.reg + 4, reg1 | (P << 16) | (M1 << 8) | N1);
366 nv_wr32(dev, pll.reg + 8, N2);
367 } else {
368 ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P);
369 if (ret <= 0)
370 return 0;
371
372 NV_DEBUG(dev, "pclk %d out %d N %d fN 0x%04x M %d P %d\n",
373 pclk, ret, N1, N2, M1, P);
374
375 nv_mask(dev, pll.reg + 0x0c, 0x00000000, 0x00000100);
376 nv_wr32(dev, pll.reg + 0x04, (P << 16) | (N1 << 8) | M1);
377 nv_wr32(dev, pll.reg + 0x10, N2 << 16);
378 }
379
380 return 0;
381} 333}
382 334
383static void 335static void
diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c
index be5704fd4a86..378ca8ca9d6a 100644
--- a/drivers/gpu/drm/nouveau/nv50_pm.c
+++ b/drivers/gpu/drm/nouveau/nv50_pm.c
@@ -363,7 +363,7 @@ struct nv50_pm_state {
363}; 363};
364 364
365static u32 365static u32
366calc_pll(struct drm_device *dev, u32 reg, struct pll_lims *pll, 366calc_pll(struct drm_device *dev, u32 reg, struct nvbios_pll *pll,
367 u32 clk, int *N1, int *M1, int *log2P) 367 u32 clk, int *N1, int *M1, int *log2P)
368{ 368{
369 struct nouveau_pll_vals coef; 369 struct nouveau_pll_vals coef;
@@ -373,7 +373,7 @@ calc_pll(struct drm_device *dev, u32 reg, struct pll_lims *pll,
373 if (ret) 373 if (ret)
374 return 0; 374 return 0;
375 375
376 pll->vco2.maxfreq = 0; 376 pll->vco2.max_freq = 0;
377 pll->refclk = read_pll_ref(dev, reg); 377 pll->refclk = read_pll_ref(dev, reg);
378 if (!pll->refclk) 378 if (!pll->refclk)
379 return 0; 379 return 0;
@@ -542,7 +542,7 @@ calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl,
542 .priv = info 542 .priv = info
543 }; 543 };
544 struct hwsq_ucode *hwsq = &info->mclk_hwsq; 544 struct hwsq_ucode *hwsq = &info->mclk_hwsq;
545 struct pll_lims pll; 545 struct nvbios_pll pll;
546 int N, M, P; 546 int N, M, P;
547 int ret; 547 int ret;
548 548
@@ -550,14 +550,14 @@ calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl,
550 info->mctrl = nv_rd32(dev, 0x004008); 550 info->mctrl = nv_rd32(dev, 0x004008);
551 info->mctrl &= ~0x81ff0200; 551 info->mctrl &= ~0x81ff0200;
552 if (clk_same(perflvl->memory, read_clk(dev, clk_src_href))) { 552 if (clk_same(perflvl->memory, read_clk(dev, clk_src_href))) {
553 info->mctrl |= 0x00000200 | (pll.log2p_bias << 19); 553 info->mctrl |= 0x00000200 | (pll.bias_p << 19);
554 } else { 554 } else {
555 ret = calc_pll(dev, 0x4008, &pll, perflvl->memory, &N, &M, &P); 555 ret = calc_pll(dev, 0x4008, &pll, perflvl->memory, &N, &M, &P);
556 if (ret == 0) 556 if (ret == 0)
557 return -EINVAL; 557 return -EINVAL;
558 558
559 info->mctrl |= 0x80000000 | (P << 22) | (P << 16); 559 info->mctrl |= 0x80000000 | (P << 22) | (P << 16);
560 info->mctrl |= pll.log2p_bias << 19; 560 info->mctrl |= pll.bias_p << 19;
561 info->mcoef = (N << 8) | M; 561 info->mcoef = (N << 8) | M;
562 } 562 }
563 563
@@ -590,7 +590,7 @@ nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
590 struct drm_nouveau_private *dev_priv = dev->dev_private; 590 struct drm_nouveau_private *dev_priv = dev->dev_private;
591 struct nv50_pm_state *info; 591 struct nv50_pm_state *info;
592 struct hwsq_ucode *hwsq; 592 struct hwsq_ucode *hwsq;
593 struct pll_lims pll; 593 struct nvbios_pll pll;
594 u32 out, mast, divs, ctrl; 594 u32 out, mast, divs, ctrl;
595 int clk, ret = -EINVAL; 595 int clk, ret = -EINVAL;
596 int N, M, P1, P2; 596 int N, M, P1, P2;
diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c
index ff0fafbfe621..847c616de12f 100644
--- a/drivers/gpu/drm/nouveau/nva3_pm.c
+++ b/drivers/gpu/drm/nouveau/nva3_pm.c
@@ -111,7 +111,7 @@ struct creg {
111static int 111static int
112calc_clk(struct drm_device *dev, int clk, u32 pll, u32 khz, struct creg *reg) 112calc_clk(struct drm_device *dev, int clk, u32 pll, u32 khz, struct creg *reg)
113{ 113{
114 struct pll_lims limits; 114 struct nvbios_pll limits;
115 u32 oclk, sclk, sdiv; 115 u32 oclk, sclk, sdiv;
116 int P, N, M, diff; 116 int P, N, M, diff;
117 int ret; 117 int ret;
diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c
index 81b649864fa1..4a21a7264c3c 100644
--- a/drivers/gpu/drm/nouveau/nvc0_pm.c
+++ b/drivers/gpu/drm/nouveau/nvc0_pm.c
@@ -212,7 +212,7 @@ calc_src(struct drm_device *dev, int clk, u32 freq, u32 *dsrc, u32 *ddiv)
212static u32 212static u32
213calc_pll(struct drm_device *dev, int clk, u32 freq, u32 *coef) 213calc_pll(struct drm_device *dev, int clk, u32 freq, u32 *coef)
214{ 214{
215 struct pll_lims limits; 215 struct nvbios_pll limits;
216 int N, M, P, ret; 216 int N, M, P, ret;
217 217
218 ret = get_pll_limits(dev, 0x137000 + (clk * 0x20), &limits); 218 ret = get_pll_limits(dev, 0x137000 + (clk * 0x20), &limits);
@@ -308,7 +308,7 @@ calc_clk(struct drm_device *dev, int clk, struct nvc0_pm_clock *info, u32 freq)
308static int 308static int
309calc_mem(struct drm_device *dev, struct nvc0_pm_clock *info, u32 freq) 309calc_mem(struct drm_device *dev, struct nvc0_pm_clock *info, u32 freq)
310{ 310{
311 struct pll_lims pll; 311 struct nvbios_pll pll;
312 int N, M, P, ret; 312 int N, M, P, ret;
313 u32 ctrl; 313 u32 ctrl;
314 314