aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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