1 /* $NetBSD: radeon_ni_dpm.c,v 1.2 2021/12/18 23:45:43 riastradh Exp $ */
2
3 /*
4 * Copyright 2012 Advanced Micro Devices, Inc.
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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25
26 #include <sys/cdefs.h>
27 __KERNEL_RCSID(0, "$NetBSD: radeon_ni_dpm.c,v 1.2 2021/12/18 23:45:43 riastradh Exp $");
28
29 #include <linux/math64.h>
30 #include <linux/pci.h>
31 #include <linux/seq_file.h>
32
33 #include "atom.h"
34 #include "ni_dpm.h"
35 #include "nid.h"
36 #include "r600_dpm.h"
37 #include "radeon.h"
38 #include "radeon_asic.h"
39
40 #define MC_CG_ARB_FREQ_F0 0x0a
41 #define MC_CG_ARB_FREQ_F1 0x0b
42 #define MC_CG_ARB_FREQ_F2 0x0c
43 #define MC_CG_ARB_FREQ_F3 0x0d
44
45 #define SMC_RAM_END 0xC000
46
47 static const struct ni_cac_weights cac_weights_cayman_xt =
48 {
49 0x15,
50 0x2,
51 0x19,
52 0x2,
53 0x8,
54 0x14,
55 0x2,
56 0x16,
57 0xE,
58 0x17,
59 0x13,
60 0x2B,
61 0x10,
62 0x7,
63 0x5,
64 0x5,
65 0x5,
66 0x2,
67 0x3,
68 0x9,
69 0x10,
70 0x10,
71 0x2B,
72 0xA,
73 0x9,
74 0x4,
75 0xD,
76 0xD,
77 0x3E,
78 0x18,
79 0x14,
80 0,
81 0x3,
82 0x3,
83 0x5,
84 0,
85 0x2,
86 0,
87 0,
88 0,
89 0,
90 0,
91 0,
92 0,
93 0,
94 0,
95 0x1CC,
96 0,
97 0x164,
98 1,
99 1,
100 1,
101 1,
102 12,
103 12,
104 12,
105 0x12,
106 0x1F,
107 132,
108 5,
109 7,
110 0,
111 { 0, 0, 0, 0, 0, 0, 0, 0 },
112 { 0, 0, 0, 0 },
113 true
114 };
115
116 static const struct ni_cac_weights cac_weights_cayman_pro =
117 {
118 0x16,
119 0x4,
120 0x10,
121 0x2,
122 0xA,
123 0x16,
124 0x2,
125 0x18,
126 0x10,
127 0x1A,
128 0x16,
129 0x2D,
130 0x12,
131 0xA,
132 0x6,
133 0x6,
134 0x6,
135 0x2,
136 0x4,
137 0xB,
138 0x11,
139 0x11,
140 0x2D,
141 0xC,
142 0xC,
143 0x7,
144 0x10,
145 0x10,
146 0x3F,
147 0x1A,
148 0x16,
149 0,
150 0x7,
151 0x4,
152 0x6,
153 1,
154 0x2,
155 0x1,
156 0,
157 0,
158 0,
159 0,
160 0,
161 0,
162 0x30,
163 0,
164 0x1CF,
165 0,
166 0x166,
167 1,
168 1,
169 1,
170 1,
171 12,
172 12,
173 12,
174 0x15,
175 0x1F,
176 132,
177 6,
178 6,
179 0,
180 { 0, 0, 0, 0, 0, 0, 0, 0 },
181 { 0, 0, 0, 0 },
182 true
183 };
184
185 static const struct ni_cac_weights cac_weights_cayman_le =
186 {
187 0x7,
188 0xE,
189 0x1,
190 0xA,
191 0x1,
192 0x3F,
193 0x2,
194 0x18,
195 0x10,
196 0x1A,
197 0x1,
198 0x3F,
199 0x1,
200 0xE,
201 0x6,
202 0x6,
203 0x6,
204 0x2,
205 0x4,
206 0x9,
207 0x1A,
208 0x1A,
209 0x2C,
210 0xA,
211 0x11,
212 0x8,
213 0x19,
214 0x19,
215 0x1,
216 0x1,
217 0x1A,
218 0,
219 0x8,
220 0x5,
221 0x8,
222 0x1,
223 0x3,
224 0x1,
225 0,
226 0,
227 0,
228 0,
229 0,
230 0,
231 0x38,
232 0x38,
233 0x239,
234 0x3,
235 0x18A,
236 1,
237 1,
238 1,
239 1,
240 12,
241 12,
242 12,
243 0x15,
244 0x22,
245 132,
246 6,
247 6,
248 0,
249 { 0, 0, 0, 0, 0, 0, 0, 0 },
250 { 0, 0, 0, 0 },
251 true
252 };
253
254 #define NISLANDS_MGCG_SEQUENCE 300
255
256 static const u32 cayman_cgcg_cgls_default[] =
257 {
258 0x000008f8, 0x00000010, 0xffffffff,
259 0x000008fc, 0x00000000, 0xffffffff,
260 0x000008f8, 0x00000011, 0xffffffff,
261 0x000008fc, 0x00000000, 0xffffffff,
262 0x000008f8, 0x00000012, 0xffffffff,
263 0x000008fc, 0x00000000, 0xffffffff,
264 0x000008f8, 0x00000013, 0xffffffff,
265 0x000008fc, 0x00000000, 0xffffffff,
266 0x000008f8, 0x00000014, 0xffffffff,
267 0x000008fc, 0x00000000, 0xffffffff,
268 0x000008f8, 0x00000015, 0xffffffff,
269 0x000008fc, 0x00000000, 0xffffffff,
270 0x000008f8, 0x00000016, 0xffffffff,
271 0x000008fc, 0x00000000, 0xffffffff,
272 0x000008f8, 0x00000017, 0xffffffff,
273 0x000008fc, 0x00000000, 0xffffffff,
274 0x000008f8, 0x00000018, 0xffffffff,
275 0x000008fc, 0x00000000, 0xffffffff,
276 0x000008f8, 0x00000019, 0xffffffff,
277 0x000008fc, 0x00000000, 0xffffffff,
278 0x000008f8, 0x0000001a, 0xffffffff,
279 0x000008fc, 0x00000000, 0xffffffff,
280 0x000008f8, 0x0000001b, 0xffffffff,
281 0x000008fc, 0x00000000, 0xffffffff,
282 0x000008f8, 0x00000020, 0xffffffff,
283 0x000008fc, 0x00000000, 0xffffffff,
284 0x000008f8, 0x00000021, 0xffffffff,
285 0x000008fc, 0x00000000, 0xffffffff,
286 0x000008f8, 0x00000022, 0xffffffff,
287 0x000008fc, 0x00000000, 0xffffffff,
288 0x000008f8, 0x00000023, 0xffffffff,
289 0x000008fc, 0x00000000, 0xffffffff,
290 0x000008f8, 0x00000024, 0xffffffff,
291 0x000008fc, 0x00000000, 0xffffffff,
292 0x000008f8, 0x00000025, 0xffffffff,
293 0x000008fc, 0x00000000, 0xffffffff,
294 0x000008f8, 0x00000026, 0xffffffff,
295 0x000008fc, 0x00000000, 0xffffffff,
296 0x000008f8, 0x00000027, 0xffffffff,
297 0x000008fc, 0x00000000, 0xffffffff,
298 0x000008f8, 0x00000028, 0xffffffff,
299 0x000008fc, 0x00000000, 0xffffffff,
300 0x000008f8, 0x00000029, 0xffffffff,
301 0x000008fc, 0x00000000, 0xffffffff,
302 0x000008f8, 0x0000002a, 0xffffffff,
303 0x000008fc, 0x00000000, 0xffffffff,
304 0x000008f8, 0x0000002b, 0xffffffff,
305 0x000008fc, 0x00000000, 0xffffffff
306 };
307 #define CAYMAN_CGCG_CGLS_DEFAULT_LENGTH sizeof(cayman_cgcg_cgls_default) / (3 * sizeof(u32))
308
309 static const u32 cayman_cgcg_cgls_disable[] =
310 {
311 0x000008f8, 0x00000010, 0xffffffff,
312 0x000008fc, 0xffffffff, 0xffffffff,
313 0x000008f8, 0x00000011, 0xffffffff,
314 0x000008fc, 0xffffffff, 0xffffffff,
315 0x000008f8, 0x00000012, 0xffffffff,
316 0x000008fc, 0xffffffff, 0xffffffff,
317 0x000008f8, 0x00000013, 0xffffffff,
318 0x000008fc, 0xffffffff, 0xffffffff,
319 0x000008f8, 0x00000014, 0xffffffff,
320 0x000008fc, 0xffffffff, 0xffffffff,
321 0x000008f8, 0x00000015, 0xffffffff,
322 0x000008fc, 0xffffffff, 0xffffffff,
323 0x000008f8, 0x00000016, 0xffffffff,
324 0x000008fc, 0xffffffff, 0xffffffff,
325 0x000008f8, 0x00000017, 0xffffffff,
326 0x000008fc, 0xffffffff, 0xffffffff,
327 0x000008f8, 0x00000018, 0xffffffff,
328 0x000008fc, 0xffffffff, 0xffffffff,
329 0x000008f8, 0x00000019, 0xffffffff,
330 0x000008fc, 0xffffffff, 0xffffffff,
331 0x000008f8, 0x0000001a, 0xffffffff,
332 0x000008fc, 0xffffffff, 0xffffffff,
333 0x000008f8, 0x0000001b, 0xffffffff,
334 0x000008fc, 0xffffffff, 0xffffffff,
335 0x000008f8, 0x00000020, 0xffffffff,
336 0x000008fc, 0x00000000, 0xffffffff,
337 0x000008f8, 0x00000021, 0xffffffff,
338 0x000008fc, 0x00000000, 0xffffffff,
339 0x000008f8, 0x00000022, 0xffffffff,
340 0x000008fc, 0x00000000, 0xffffffff,
341 0x000008f8, 0x00000023, 0xffffffff,
342 0x000008fc, 0x00000000, 0xffffffff,
343 0x000008f8, 0x00000024, 0xffffffff,
344 0x000008fc, 0x00000000, 0xffffffff,
345 0x000008f8, 0x00000025, 0xffffffff,
346 0x000008fc, 0x00000000, 0xffffffff,
347 0x000008f8, 0x00000026, 0xffffffff,
348 0x000008fc, 0x00000000, 0xffffffff,
349 0x000008f8, 0x00000027, 0xffffffff,
350 0x000008fc, 0x00000000, 0xffffffff,
351 0x000008f8, 0x00000028, 0xffffffff,
352 0x000008fc, 0x00000000, 0xffffffff,
353 0x000008f8, 0x00000029, 0xffffffff,
354 0x000008fc, 0x00000000, 0xffffffff,
355 0x000008f8, 0x0000002a, 0xffffffff,
356 0x000008fc, 0x00000000, 0xffffffff,
357 0x000008f8, 0x0000002b, 0xffffffff,
358 0x000008fc, 0x00000000, 0xffffffff,
359 0x00000644, 0x000f7902, 0x001f4180,
360 0x00000644, 0x000f3802, 0x001f4180
361 };
362 #define CAYMAN_CGCG_CGLS_DISABLE_LENGTH sizeof(cayman_cgcg_cgls_disable) / (3 * sizeof(u32))
363
364 static const u32 cayman_cgcg_cgls_enable[] =
365 {
366 0x00000644, 0x000f7882, 0x001f4080,
367 0x000008f8, 0x00000010, 0xffffffff,
368 0x000008fc, 0x00000000, 0xffffffff,
369 0x000008f8, 0x00000011, 0xffffffff,
370 0x000008fc, 0x00000000, 0xffffffff,
371 0x000008f8, 0x00000012, 0xffffffff,
372 0x000008fc, 0x00000000, 0xffffffff,
373 0x000008f8, 0x00000013, 0xffffffff,
374 0x000008fc, 0x00000000, 0xffffffff,
375 0x000008f8, 0x00000014, 0xffffffff,
376 0x000008fc, 0x00000000, 0xffffffff,
377 0x000008f8, 0x00000015, 0xffffffff,
378 0x000008fc, 0x00000000, 0xffffffff,
379 0x000008f8, 0x00000016, 0xffffffff,
380 0x000008fc, 0x00000000, 0xffffffff,
381 0x000008f8, 0x00000017, 0xffffffff,
382 0x000008fc, 0x00000000, 0xffffffff,
383 0x000008f8, 0x00000018, 0xffffffff,
384 0x000008fc, 0x00000000, 0xffffffff,
385 0x000008f8, 0x00000019, 0xffffffff,
386 0x000008fc, 0x00000000, 0xffffffff,
387 0x000008f8, 0x0000001a, 0xffffffff,
388 0x000008fc, 0x00000000, 0xffffffff,
389 0x000008f8, 0x0000001b, 0xffffffff,
390 0x000008fc, 0x00000000, 0xffffffff,
391 0x000008f8, 0x00000020, 0xffffffff,
392 0x000008fc, 0xffffffff, 0xffffffff,
393 0x000008f8, 0x00000021, 0xffffffff,
394 0x000008fc, 0xffffffff, 0xffffffff,
395 0x000008f8, 0x00000022, 0xffffffff,
396 0x000008fc, 0xffffffff, 0xffffffff,
397 0x000008f8, 0x00000023, 0xffffffff,
398 0x000008fc, 0xffffffff, 0xffffffff,
399 0x000008f8, 0x00000024, 0xffffffff,
400 0x000008fc, 0xffffffff, 0xffffffff,
401 0x000008f8, 0x00000025, 0xffffffff,
402 0x000008fc, 0xffffffff, 0xffffffff,
403 0x000008f8, 0x00000026, 0xffffffff,
404 0x000008fc, 0xffffffff, 0xffffffff,
405 0x000008f8, 0x00000027, 0xffffffff,
406 0x000008fc, 0xffffffff, 0xffffffff,
407 0x000008f8, 0x00000028, 0xffffffff,
408 0x000008fc, 0xffffffff, 0xffffffff,
409 0x000008f8, 0x00000029, 0xffffffff,
410 0x000008fc, 0xffffffff, 0xffffffff,
411 0x000008f8, 0x0000002a, 0xffffffff,
412 0x000008fc, 0xffffffff, 0xffffffff,
413 0x000008f8, 0x0000002b, 0xffffffff,
414 0x000008fc, 0xffffffff, 0xffffffff
415 };
416 #define CAYMAN_CGCG_CGLS_ENABLE_LENGTH sizeof(cayman_cgcg_cgls_enable) / (3 * sizeof(u32))
417
418 static const u32 cayman_mgcg_default[] =
419 {
420 0x0000802c, 0xc0000000, 0xffffffff,
421 0x00003fc4, 0xc0000000, 0xffffffff,
422 0x00005448, 0x00000100, 0xffffffff,
423 0x000055e4, 0x00000100, 0xffffffff,
424 0x0000160c, 0x00000100, 0xffffffff,
425 0x00008984, 0x06000100, 0xffffffff,
426 0x0000c164, 0x00000100, 0xffffffff,
427 0x00008a18, 0x00000100, 0xffffffff,
428 0x0000897c, 0x06000100, 0xffffffff,
429 0x00008b28, 0x00000100, 0xffffffff,
430 0x00009144, 0x00800200, 0xffffffff,
431 0x00009a60, 0x00000100, 0xffffffff,
432 0x00009868, 0x00000100, 0xffffffff,
433 0x00008d58, 0x00000100, 0xffffffff,
434 0x00009510, 0x00000100, 0xffffffff,
435 0x0000949c, 0x00000100, 0xffffffff,
436 0x00009654, 0x00000100, 0xffffffff,
437 0x00009030, 0x00000100, 0xffffffff,
438 0x00009034, 0x00000100, 0xffffffff,
439 0x00009038, 0x00000100, 0xffffffff,
440 0x0000903c, 0x00000100, 0xffffffff,
441 0x00009040, 0x00000100, 0xffffffff,
442 0x0000a200, 0x00000100, 0xffffffff,
443 0x0000a204, 0x00000100, 0xffffffff,
444 0x0000a208, 0x00000100, 0xffffffff,
445 0x0000a20c, 0x00000100, 0xffffffff,
446 0x00009744, 0x00000100, 0xffffffff,
447 0x00003f80, 0x00000100, 0xffffffff,
448 0x0000a210, 0x00000100, 0xffffffff,
449 0x0000a214, 0x00000100, 0xffffffff,
450 0x000004d8, 0x00000100, 0xffffffff,
451 0x00009664, 0x00000100, 0xffffffff,
452 0x00009698, 0x00000100, 0xffffffff,
453 0x000004d4, 0x00000200, 0xffffffff,
454 0x000004d0, 0x00000000, 0xffffffff,
455 0x000030cc, 0x00000104, 0xffffffff,
456 0x0000d0c0, 0x00000100, 0xffffffff,
457 0x0000d8c0, 0x00000100, 0xffffffff,
458 0x0000802c, 0x40000000, 0xffffffff,
459 0x00003fc4, 0x40000000, 0xffffffff,
460 0x0000915c, 0x00010000, 0xffffffff,
461 0x00009160, 0x00030002, 0xffffffff,
462 0x00009164, 0x00050004, 0xffffffff,
463 0x00009168, 0x00070006, 0xffffffff,
464 0x00009178, 0x00070000, 0xffffffff,
465 0x0000917c, 0x00030002, 0xffffffff,
466 0x00009180, 0x00050004, 0xffffffff,
467 0x0000918c, 0x00010006, 0xffffffff,
468 0x00009190, 0x00090008, 0xffffffff,
469 0x00009194, 0x00070000, 0xffffffff,
470 0x00009198, 0x00030002, 0xffffffff,
471 0x0000919c, 0x00050004, 0xffffffff,
472 0x000091a8, 0x00010006, 0xffffffff,
473 0x000091ac, 0x00090008, 0xffffffff,
474 0x000091b0, 0x00070000, 0xffffffff,
475 0x000091b4, 0x00030002, 0xffffffff,
476 0x000091b8, 0x00050004, 0xffffffff,
477 0x000091c4, 0x00010006, 0xffffffff,
478 0x000091c8, 0x00090008, 0xffffffff,
479 0x000091cc, 0x00070000, 0xffffffff,
480 0x000091d0, 0x00030002, 0xffffffff,
481 0x000091d4, 0x00050004, 0xffffffff,
482 0x000091e0, 0x00010006, 0xffffffff,
483 0x000091e4, 0x00090008, 0xffffffff,
484 0x000091e8, 0x00000000, 0xffffffff,
485 0x000091ec, 0x00070000, 0xffffffff,
486 0x000091f0, 0x00030002, 0xffffffff,
487 0x000091f4, 0x00050004, 0xffffffff,
488 0x00009200, 0x00010006, 0xffffffff,
489 0x00009204, 0x00090008, 0xffffffff,
490 0x00009208, 0x00070000, 0xffffffff,
491 0x0000920c, 0x00030002, 0xffffffff,
492 0x00009210, 0x00050004, 0xffffffff,
493 0x0000921c, 0x00010006, 0xffffffff,
494 0x00009220, 0x00090008, 0xffffffff,
495 0x00009224, 0x00070000, 0xffffffff,
496 0x00009228, 0x00030002, 0xffffffff,
497 0x0000922c, 0x00050004, 0xffffffff,
498 0x00009238, 0x00010006, 0xffffffff,
499 0x0000923c, 0x00090008, 0xffffffff,
500 0x00009240, 0x00070000, 0xffffffff,
501 0x00009244, 0x00030002, 0xffffffff,
502 0x00009248, 0x00050004, 0xffffffff,
503 0x00009254, 0x00010006, 0xffffffff,
504 0x00009258, 0x00090008, 0xffffffff,
505 0x0000925c, 0x00070000, 0xffffffff,
506 0x00009260, 0x00030002, 0xffffffff,
507 0x00009264, 0x00050004, 0xffffffff,
508 0x00009270, 0x00010006, 0xffffffff,
509 0x00009274, 0x00090008, 0xffffffff,
510 0x00009278, 0x00070000, 0xffffffff,
511 0x0000927c, 0x00030002, 0xffffffff,
512 0x00009280, 0x00050004, 0xffffffff,
513 0x0000928c, 0x00010006, 0xffffffff,
514 0x00009290, 0x00090008, 0xffffffff,
515 0x000092a8, 0x00070000, 0xffffffff,
516 0x000092ac, 0x00030002, 0xffffffff,
517 0x000092b0, 0x00050004, 0xffffffff,
518 0x000092bc, 0x00010006, 0xffffffff,
519 0x000092c0, 0x00090008, 0xffffffff,
520 0x000092c4, 0x00070000, 0xffffffff,
521 0x000092c8, 0x00030002, 0xffffffff,
522 0x000092cc, 0x00050004, 0xffffffff,
523 0x000092d8, 0x00010006, 0xffffffff,
524 0x000092dc, 0x00090008, 0xffffffff,
525 0x00009294, 0x00000000, 0xffffffff,
526 0x0000802c, 0x40010000, 0xffffffff,
527 0x00003fc4, 0x40010000, 0xffffffff,
528 0x0000915c, 0x00010000, 0xffffffff,
529 0x00009160, 0x00030002, 0xffffffff,
530 0x00009164, 0x00050004, 0xffffffff,
531 0x00009168, 0x00070006, 0xffffffff,
532 0x00009178, 0x00070000, 0xffffffff,
533 0x0000917c, 0x00030002, 0xffffffff,
534 0x00009180, 0x00050004, 0xffffffff,
535 0x0000918c, 0x00010006, 0xffffffff,
536 0x00009190, 0x00090008, 0xffffffff,
537 0x00009194, 0x00070000, 0xffffffff,
538 0x00009198, 0x00030002, 0xffffffff,
539 0x0000919c, 0x00050004, 0xffffffff,
540 0x000091a8, 0x00010006, 0xffffffff,
541 0x000091ac, 0x00090008, 0xffffffff,
542 0x000091b0, 0x00070000, 0xffffffff,
543 0x000091b4, 0x00030002, 0xffffffff,
544 0x000091b8, 0x00050004, 0xffffffff,
545 0x000091c4, 0x00010006, 0xffffffff,
546 0x000091c8, 0x00090008, 0xffffffff,
547 0x000091cc, 0x00070000, 0xffffffff,
548 0x000091d0, 0x00030002, 0xffffffff,
549 0x000091d4, 0x00050004, 0xffffffff,
550 0x000091e0, 0x00010006, 0xffffffff,
551 0x000091e4, 0x00090008, 0xffffffff,
552 0x000091e8, 0x00000000, 0xffffffff,
553 0x000091ec, 0x00070000, 0xffffffff,
554 0x000091f0, 0x00030002, 0xffffffff,
555 0x000091f4, 0x00050004, 0xffffffff,
556 0x00009200, 0x00010006, 0xffffffff,
557 0x00009204, 0x00090008, 0xffffffff,
558 0x00009208, 0x00070000, 0xffffffff,
559 0x0000920c, 0x00030002, 0xffffffff,
560 0x00009210, 0x00050004, 0xffffffff,
561 0x0000921c, 0x00010006, 0xffffffff,
562 0x00009220, 0x00090008, 0xffffffff,
563 0x00009224, 0x00070000, 0xffffffff,
564 0x00009228, 0x00030002, 0xffffffff,
565 0x0000922c, 0x00050004, 0xffffffff,
566 0x00009238, 0x00010006, 0xffffffff,
567 0x0000923c, 0x00090008, 0xffffffff,
568 0x00009240, 0x00070000, 0xffffffff,
569 0x00009244, 0x00030002, 0xffffffff,
570 0x00009248, 0x00050004, 0xffffffff,
571 0x00009254, 0x00010006, 0xffffffff,
572 0x00009258, 0x00090008, 0xffffffff,
573 0x0000925c, 0x00070000, 0xffffffff,
574 0x00009260, 0x00030002, 0xffffffff,
575 0x00009264, 0x00050004, 0xffffffff,
576 0x00009270, 0x00010006, 0xffffffff,
577 0x00009274, 0x00090008, 0xffffffff,
578 0x00009278, 0x00070000, 0xffffffff,
579 0x0000927c, 0x00030002, 0xffffffff,
580 0x00009280, 0x00050004, 0xffffffff,
581 0x0000928c, 0x00010006, 0xffffffff,
582 0x00009290, 0x00090008, 0xffffffff,
583 0x000092a8, 0x00070000, 0xffffffff,
584 0x000092ac, 0x00030002, 0xffffffff,
585 0x000092b0, 0x00050004, 0xffffffff,
586 0x000092bc, 0x00010006, 0xffffffff,
587 0x000092c0, 0x00090008, 0xffffffff,
588 0x000092c4, 0x00070000, 0xffffffff,
589 0x000092c8, 0x00030002, 0xffffffff,
590 0x000092cc, 0x00050004, 0xffffffff,
591 0x000092d8, 0x00010006, 0xffffffff,
592 0x000092dc, 0x00090008, 0xffffffff,
593 0x00009294, 0x00000000, 0xffffffff,
594 0x0000802c, 0xc0000000, 0xffffffff,
595 0x00003fc4, 0xc0000000, 0xffffffff,
596 0x000008f8, 0x00000010, 0xffffffff,
597 0x000008fc, 0x00000000, 0xffffffff,
598 0x000008f8, 0x00000011, 0xffffffff,
599 0x000008fc, 0x00000000, 0xffffffff,
600 0x000008f8, 0x00000012, 0xffffffff,
601 0x000008fc, 0x00000000, 0xffffffff,
602 0x000008f8, 0x00000013, 0xffffffff,
603 0x000008fc, 0x00000000, 0xffffffff,
604 0x000008f8, 0x00000014, 0xffffffff,
605 0x000008fc, 0x00000000, 0xffffffff,
606 0x000008f8, 0x00000015, 0xffffffff,
607 0x000008fc, 0x00000000, 0xffffffff,
608 0x000008f8, 0x00000016, 0xffffffff,
609 0x000008fc, 0x00000000, 0xffffffff,
610 0x000008f8, 0x00000017, 0xffffffff,
611 0x000008fc, 0x00000000, 0xffffffff,
612 0x000008f8, 0x00000018, 0xffffffff,
613 0x000008fc, 0x00000000, 0xffffffff,
614 0x000008f8, 0x00000019, 0xffffffff,
615 0x000008fc, 0x00000000, 0xffffffff,
616 0x000008f8, 0x0000001a, 0xffffffff,
617 0x000008fc, 0x00000000, 0xffffffff,
618 0x000008f8, 0x0000001b, 0xffffffff,
619 0x000008fc, 0x00000000, 0xffffffff
620 };
621 #define CAYMAN_MGCG_DEFAULT_LENGTH sizeof(cayman_mgcg_default) / (3 * sizeof(u32))
622
623 static const u32 cayman_mgcg_disable[] =
624 {
625 0x0000802c, 0xc0000000, 0xffffffff,
626 0x000008f8, 0x00000000, 0xffffffff,
627 0x000008fc, 0xffffffff, 0xffffffff,
628 0x000008f8, 0x00000001, 0xffffffff,
629 0x000008fc, 0xffffffff, 0xffffffff,
630 0x000008f8, 0x00000002, 0xffffffff,
631 0x000008fc, 0xffffffff, 0xffffffff,
632 0x000008f8, 0x00000003, 0xffffffff,
633 0x000008fc, 0xffffffff, 0xffffffff,
634 0x00009150, 0x00600000, 0xffffffff
635 };
636 #define CAYMAN_MGCG_DISABLE_LENGTH sizeof(cayman_mgcg_disable) / (3 * sizeof(u32))
637
638 static const u32 cayman_mgcg_enable[] =
639 {
640 0x0000802c, 0xc0000000, 0xffffffff,
641 0x000008f8, 0x00000000, 0xffffffff,
642 0x000008fc, 0x00000000, 0xffffffff,
643 0x000008f8, 0x00000001, 0xffffffff,
644 0x000008fc, 0x00000000, 0xffffffff,
645 0x000008f8, 0x00000002, 0xffffffff,
646 0x000008fc, 0x00600000, 0xffffffff,
647 0x000008f8, 0x00000003, 0xffffffff,
648 0x000008fc, 0x00000000, 0xffffffff,
649 0x00009150, 0x96944200, 0xffffffff
650 };
651
652 #define CAYMAN_MGCG_ENABLE_LENGTH sizeof(cayman_mgcg_enable) / (3 * sizeof(u32))
653
654 #define NISLANDS_SYSLS_SEQUENCE 100
655
656 static const u32 cayman_sysls_default[] =
657 {
658 /* Register, Value, Mask bits */
659 0x000055e8, 0x00000000, 0xffffffff,
660 0x0000d0bc, 0x00000000, 0xffffffff,
661 0x0000d8bc, 0x00000000, 0xffffffff,
662 0x000015c0, 0x000c1401, 0xffffffff,
663 0x0000264c, 0x000c0400, 0xffffffff,
664 0x00002648, 0x000c0400, 0xffffffff,
665 0x00002650, 0x000c0400, 0xffffffff,
666 0x000020b8, 0x000c0400, 0xffffffff,
667 0x000020bc, 0x000c0400, 0xffffffff,
668 0x000020c0, 0x000c0c80, 0xffffffff,
669 0x0000f4a0, 0x000000c0, 0xffffffff,
670 0x0000f4a4, 0x00680fff, 0xffffffff,
671 0x00002f50, 0x00000404, 0xffffffff,
672 0x000004c8, 0x00000001, 0xffffffff,
673 0x000064ec, 0x00000000, 0xffffffff,
674 0x00000c7c, 0x00000000, 0xffffffff,
675 0x00008dfc, 0x00000000, 0xffffffff
676 };
677 #define CAYMAN_SYSLS_DEFAULT_LENGTH sizeof(cayman_sysls_default) / (3 * sizeof(u32))
678
679 static const u32 cayman_sysls_disable[] =
680 {
681 /* Register, Value, Mask bits */
682 0x0000d0c0, 0x00000000, 0xffffffff,
683 0x0000d8c0, 0x00000000, 0xffffffff,
684 0x000055e8, 0x00000000, 0xffffffff,
685 0x0000d0bc, 0x00000000, 0xffffffff,
686 0x0000d8bc, 0x00000000, 0xffffffff,
687 0x000015c0, 0x00041401, 0xffffffff,
688 0x0000264c, 0x00040400, 0xffffffff,
689 0x00002648, 0x00040400, 0xffffffff,
690 0x00002650, 0x00040400, 0xffffffff,
691 0x000020b8, 0x00040400, 0xffffffff,
692 0x000020bc, 0x00040400, 0xffffffff,
693 0x000020c0, 0x00040c80, 0xffffffff,
694 0x0000f4a0, 0x000000c0, 0xffffffff,
695 0x0000f4a4, 0x00680000, 0xffffffff,
696 0x00002f50, 0x00000404, 0xffffffff,
697 0x000004c8, 0x00000001, 0xffffffff,
698 0x000064ec, 0x00007ffd, 0xffffffff,
699 0x00000c7c, 0x0000ff00, 0xffffffff,
700 0x00008dfc, 0x0000007f, 0xffffffff
701 };
702 #define CAYMAN_SYSLS_DISABLE_LENGTH sizeof(cayman_sysls_disable) / (3 * sizeof(u32))
703
704 static const u32 cayman_sysls_enable[] =
705 {
706 /* Register, Value, Mask bits */
707 0x000055e8, 0x00000001, 0xffffffff,
708 0x0000d0bc, 0x00000100, 0xffffffff,
709 0x0000d8bc, 0x00000100, 0xffffffff,
710 0x000015c0, 0x000c1401, 0xffffffff,
711 0x0000264c, 0x000c0400, 0xffffffff,
712 0x00002648, 0x000c0400, 0xffffffff,
713 0x00002650, 0x000c0400, 0xffffffff,
714 0x000020b8, 0x000c0400, 0xffffffff,
715 0x000020bc, 0x000c0400, 0xffffffff,
716 0x000020c0, 0x000c0c80, 0xffffffff,
717 0x0000f4a0, 0x000000c0, 0xffffffff,
718 0x0000f4a4, 0x00680fff, 0xffffffff,
719 0x00002f50, 0x00000903, 0xffffffff,
720 0x000004c8, 0x00000000, 0xffffffff,
721 0x000064ec, 0x00000000, 0xffffffff,
722 0x00000c7c, 0x00000000, 0xffffffff,
723 0x00008dfc, 0x00000000, 0xffffffff
724 };
725 #define CAYMAN_SYSLS_ENABLE_LENGTH sizeof(cayman_sysls_enable) / (3 * sizeof(u32))
726
727 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
728 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
729
730 extern int ni_mc_load_microcode(struct radeon_device *rdev);
731
ni_get_pi(struct radeon_device * rdev)732 struct ni_power_info *ni_get_pi(struct radeon_device *rdev)
733 {
734 struct ni_power_info *pi = rdev->pm.dpm.priv;
735
736 return pi;
737 }
738
ni_get_ps(struct radeon_ps * rps)739 struct ni_ps *ni_get_ps(struct radeon_ps *rps)
740 {
741 struct ni_ps *ps = rps->ps_priv;
742
743 return ps;
744 }
745
ni_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coeffients * coeff,u16 v,s32 t,u32 ileakage,u32 * leakage)746 static void ni_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coeffients *coeff,
747 u16 v, s32 t,
748 u32 ileakage,
749 u32 *leakage)
750 {
751 s64 kt, kv, leakage_w, i_leakage, vddc, temperature;
752
753 i_leakage = div64_s64(drm_int2fixp(ileakage), 1000);
754 vddc = div64_s64(drm_int2fixp(v), 1000);
755 temperature = div64_s64(drm_int2fixp(t), 1000);
756
757 kt = drm_fixp_mul(div64_s64(drm_int2fixp(coeff->at), 1000),
758 drm_fixp_exp(drm_fixp_mul(div64_s64(drm_int2fixp(coeff->bt), 1000), temperature)));
759 kv = drm_fixp_mul(div64_s64(drm_int2fixp(coeff->av), 1000),
760 drm_fixp_exp(drm_fixp_mul(div64_s64(drm_int2fixp(coeff->bv), 1000), vddc)));
761
762 leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc);
763
764 *leakage = drm_fixp2int(leakage_w * 1000);
765 }
766
ni_calculate_leakage_for_v_and_t(struct radeon_device * rdev,const struct ni_leakage_coeffients * coeff,u16 v,s32 t,u32 i_leakage,u32 * leakage)767 static void ni_calculate_leakage_for_v_and_t(struct radeon_device *rdev,
768 const struct ni_leakage_coeffients *coeff,
769 u16 v,
770 s32 t,
771 u32 i_leakage,
772 u32 *leakage)
773 {
774 ni_calculate_leakage_for_v_and_t_formula(coeff, v, t, i_leakage, leakage);
775 }
776
ni_dpm_vblank_too_short(struct radeon_device * rdev)777 bool ni_dpm_vblank_too_short(struct radeon_device *rdev)
778 {
779 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
780 u32 vblank_time = r600_dpm_get_vblank_time(rdev);
781 /* we never hit the non-gddr5 limit so disable it */
782 u32 switch_limit = pi->mem_gddr5 ? 450 : 0;
783
784 if (vblank_time < switch_limit)
785 return true;
786 else
787 return false;
788
789 }
790
ni_apply_state_adjust_rules(struct radeon_device * rdev,struct radeon_ps * rps)791 static void ni_apply_state_adjust_rules(struct radeon_device *rdev,
792 struct radeon_ps *rps)
793 {
794 struct ni_ps *ps = ni_get_ps(rps);
795 struct radeon_clock_and_voltage_limits *max_limits;
796 bool disable_mclk_switching;
797 u32 mclk;
798 u16 vddci;
799 int i;
800
801 if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
802 ni_dpm_vblank_too_short(rdev))
803 disable_mclk_switching = true;
804 else
805 disable_mclk_switching = false;
806
807 if (rdev->pm.dpm.ac_power)
808 max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
809 else
810 max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
811
812 if (rdev->pm.dpm.ac_power == false) {
813 for (i = 0; i < ps->performance_level_count; i++) {
814 if (ps->performance_levels[i].mclk > max_limits->mclk)
815 ps->performance_levels[i].mclk = max_limits->mclk;
816 if (ps->performance_levels[i].sclk > max_limits->sclk)
817 ps->performance_levels[i].sclk = max_limits->sclk;
818 if (ps->performance_levels[i].vddc > max_limits->vddc)
819 ps->performance_levels[i].vddc = max_limits->vddc;
820 if (ps->performance_levels[i].vddci > max_limits->vddci)
821 ps->performance_levels[i].vddci = max_limits->vddci;
822 }
823 }
824
825 /* XXX validate the min clocks required for display */
826
827 /* adjust low state */
828 if (disable_mclk_switching) {
829 ps->performance_levels[0].mclk =
830 ps->performance_levels[ps->performance_level_count - 1].mclk;
831 ps->performance_levels[0].vddci =
832 ps->performance_levels[ps->performance_level_count - 1].vddci;
833 }
834
835 btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
836 &ps->performance_levels[0].sclk,
837 &ps->performance_levels[0].mclk);
838
839 for (i = 1; i < ps->performance_level_count; i++) {
840 if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
841 ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
842 if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
843 ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
844 }
845
846 /* adjust remaining states */
847 if (disable_mclk_switching) {
848 mclk = ps->performance_levels[0].mclk;
849 vddci = ps->performance_levels[0].vddci;
850 for (i = 1; i < ps->performance_level_count; i++) {
851 if (mclk < ps->performance_levels[i].mclk)
852 mclk = ps->performance_levels[i].mclk;
853 if (vddci < ps->performance_levels[i].vddci)
854 vddci = ps->performance_levels[i].vddci;
855 }
856 for (i = 0; i < ps->performance_level_count; i++) {
857 ps->performance_levels[i].mclk = mclk;
858 ps->performance_levels[i].vddci = vddci;
859 }
860 } else {
861 for (i = 1; i < ps->performance_level_count; i++) {
862 if (ps->performance_levels[i].mclk < ps->performance_levels[i - 1].mclk)
863 ps->performance_levels[i].mclk = ps->performance_levels[i - 1].mclk;
864 if (ps->performance_levels[i].vddci < ps->performance_levels[i - 1].vddci)
865 ps->performance_levels[i].vddci = ps->performance_levels[i - 1].vddci;
866 }
867 }
868
869 for (i = 1; i < ps->performance_level_count; i++)
870 btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
871 &ps->performance_levels[i].sclk,
872 &ps->performance_levels[i].mclk);
873
874 for (i = 0; i < ps->performance_level_count; i++)
875 btc_adjust_clock_combinations(rdev, max_limits,
876 &ps->performance_levels[i]);
877
878 for (i = 0; i < ps->performance_level_count; i++) {
879 btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
880 ps->performance_levels[i].sclk,
881 max_limits->vddc, &ps->performance_levels[i].vddc);
882 btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
883 ps->performance_levels[i].mclk,
884 max_limits->vddci, &ps->performance_levels[i].vddci);
885 btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
886 ps->performance_levels[i].mclk,
887 max_limits->vddc, &ps->performance_levels[i].vddc);
888 btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
889 rdev->clock.current_dispclk,
890 max_limits->vddc, &ps->performance_levels[i].vddc);
891 }
892
893 for (i = 0; i < ps->performance_level_count; i++) {
894 btc_apply_voltage_delta_rules(rdev,
895 max_limits->vddc, max_limits->vddci,
896 &ps->performance_levels[i].vddc,
897 &ps->performance_levels[i].vddci);
898 }
899
900 ps->dc_compatible = true;
901 for (i = 0; i < ps->performance_level_count; i++) {
902 if (ps->performance_levels[i].vddc > rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc)
903 ps->dc_compatible = false;
904
905 if (ps->performance_levels[i].vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
906 ps->performance_levels[i].flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
907 }
908 }
909
ni_cg_clockgating_default(struct radeon_device * rdev)910 static void ni_cg_clockgating_default(struct radeon_device *rdev)
911 {
912 u32 count;
913 const u32 *ps = NULL;
914
915 ps = (const u32 *)&cayman_cgcg_cgls_default;
916 count = CAYMAN_CGCG_CGLS_DEFAULT_LENGTH;
917
918 btc_program_mgcg_hw_sequence(rdev, ps, count);
919 }
920
ni_gfx_clockgating_enable(struct radeon_device * rdev,bool enable)921 static void ni_gfx_clockgating_enable(struct radeon_device *rdev,
922 bool enable)
923 {
924 u32 count;
925 const u32 *ps = NULL;
926
927 if (enable) {
928 ps = (const u32 *)&cayman_cgcg_cgls_enable;
929 count = CAYMAN_CGCG_CGLS_ENABLE_LENGTH;
930 } else {
931 ps = (const u32 *)&cayman_cgcg_cgls_disable;
932 count = CAYMAN_CGCG_CGLS_DISABLE_LENGTH;
933 }
934
935 btc_program_mgcg_hw_sequence(rdev, ps, count);
936 }
937
ni_mg_clockgating_default(struct radeon_device * rdev)938 static void ni_mg_clockgating_default(struct radeon_device *rdev)
939 {
940 u32 count;
941 const u32 *ps = NULL;
942
943 ps = (const u32 *)&cayman_mgcg_default;
944 count = CAYMAN_MGCG_DEFAULT_LENGTH;
945
946 btc_program_mgcg_hw_sequence(rdev, ps, count);
947 }
948
ni_mg_clockgating_enable(struct radeon_device * rdev,bool enable)949 static void ni_mg_clockgating_enable(struct radeon_device *rdev,
950 bool enable)
951 {
952 u32 count;
953 const u32 *ps = NULL;
954
955 if (enable) {
956 ps = (const u32 *)&cayman_mgcg_enable;
957 count = CAYMAN_MGCG_ENABLE_LENGTH;
958 } else {
959 ps = (const u32 *)&cayman_mgcg_disable;
960 count = CAYMAN_MGCG_DISABLE_LENGTH;
961 }
962
963 btc_program_mgcg_hw_sequence(rdev, ps, count);
964 }
965
ni_ls_clockgating_default(struct radeon_device * rdev)966 static void ni_ls_clockgating_default(struct radeon_device *rdev)
967 {
968 u32 count;
969 const u32 *ps = NULL;
970
971 ps = (const u32 *)&cayman_sysls_default;
972 count = CAYMAN_SYSLS_DEFAULT_LENGTH;
973
974 btc_program_mgcg_hw_sequence(rdev, ps, count);
975 }
976
ni_ls_clockgating_enable(struct radeon_device * rdev,bool enable)977 static void ni_ls_clockgating_enable(struct radeon_device *rdev,
978 bool enable)
979 {
980 u32 count;
981 const u32 *ps = NULL;
982
983 if (enable) {
984 ps = (const u32 *)&cayman_sysls_enable;
985 count = CAYMAN_SYSLS_ENABLE_LENGTH;
986 } else {
987 ps = (const u32 *)&cayman_sysls_disable;
988 count = CAYMAN_SYSLS_DISABLE_LENGTH;
989 }
990
991 btc_program_mgcg_hw_sequence(rdev, ps, count);
992
993 }
994
ni_patch_single_dependency_table_based_on_leakage(struct radeon_device * rdev,struct radeon_clock_voltage_dependency_table * table)995 static int ni_patch_single_dependency_table_based_on_leakage(struct radeon_device *rdev,
996 struct radeon_clock_voltage_dependency_table *table)
997 {
998 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
999 u32 i;
1000
1001 if (table) {
1002 for (i = 0; i < table->count; i++) {
1003 if (0xff01 == table->entries[i].v) {
1004 if (pi->max_vddc == 0)
1005 return -EINVAL;
1006 table->entries[i].v = pi->max_vddc;
1007 }
1008 }
1009 }
1010 return 0;
1011 }
1012
ni_patch_dependency_tables_based_on_leakage(struct radeon_device * rdev)1013 static int ni_patch_dependency_tables_based_on_leakage(struct radeon_device *rdev)
1014 {
1015 int ret = 0;
1016
1017 ret = ni_patch_single_dependency_table_based_on_leakage(rdev,
1018 &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk);
1019
1020 ret = ni_patch_single_dependency_table_based_on_leakage(rdev,
1021 &rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk);
1022 return ret;
1023 }
1024
ni_stop_dpm(struct radeon_device * rdev)1025 static void ni_stop_dpm(struct radeon_device *rdev)
1026 {
1027 WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
1028 }
1029
1030 #if 0
1031 static int ni_notify_hw_of_power_source(struct radeon_device *rdev,
1032 bool ac_power)
1033 {
1034 if (ac_power)
1035 return (rv770_send_msg_to_smc(rdev, PPSMC_MSG_RunningOnAC) == PPSMC_Result_OK) ?
1036 0 : -EINVAL;
1037
1038 return 0;
1039 }
1040 #endif
1041
ni_send_msg_to_smc_with_parameter(struct radeon_device * rdev,PPSMC_Msg msg,u32 parameter)1042 static PPSMC_Result ni_send_msg_to_smc_with_parameter(struct radeon_device *rdev,
1043 PPSMC_Msg msg, u32 parameter)
1044 {
1045 WREG32(SMC_SCRATCH0, parameter);
1046 return rv770_send_msg_to_smc(rdev, msg);
1047 }
1048
ni_restrict_performance_levels_before_switch(struct radeon_device * rdev)1049 static int ni_restrict_performance_levels_before_switch(struct radeon_device *rdev)
1050 {
1051 if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
1052 return -EINVAL;
1053
1054 return (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) == PPSMC_Result_OK) ?
1055 0 : -EINVAL;
1056 }
1057
ni_dpm_force_performance_level(struct radeon_device * rdev,enum radeon_dpm_forced_level level)1058 int ni_dpm_force_performance_level(struct radeon_device *rdev,
1059 enum radeon_dpm_forced_level level)
1060 {
1061 if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
1062 if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK)
1063 return -EINVAL;
1064
1065 if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK)
1066 return -EINVAL;
1067 } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
1068 if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
1069 return -EINVAL;
1070
1071 if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK)
1072 return -EINVAL;
1073 } else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) {
1074 if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
1075 return -EINVAL;
1076
1077 if (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 0) != PPSMC_Result_OK)
1078 return -EINVAL;
1079 }
1080
1081 rdev->pm.dpm.forced_level = level;
1082
1083 return 0;
1084 }
1085
ni_stop_smc(struct radeon_device * rdev)1086 static void ni_stop_smc(struct radeon_device *rdev)
1087 {
1088 u32 tmp;
1089 int i;
1090
1091 for (i = 0; i < rdev->usec_timeout; i++) {
1092 tmp = RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK;
1093 if (tmp != 1)
1094 break;
1095 udelay(1);
1096 }
1097
1098 udelay(100);
1099
1100 r7xx_stop_smc(rdev);
1101 }
1102
ni_process_firmware_header(struct radeon_device * rdev)1103 static int ni_process_firmware_header(struct radeon_device *rdev)
1104 {
1105 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1106 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1107 struct ni_power_info *ni_pi = ni_get_pi(rdev);
1108 u32 tmp;
1109 int ret;
1110
1111 ret = rv770_read_smc_sram_dword(rdev,
1112 NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
1113 NISLANDS_SMC_FIRMWARE_HEADER_stateTable,
1114 &tmp, pi->sram_end);
1115
1116 if (ret)
1117 return ret;
1118
1119 pi->state_table_start = (u16)tmp;
1120
1121 ret = rv770_read_smc_sram_dword(rdev,
1122 NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
1123 NISLANDS_SMC_FIRMWARE_HEADER_softRegisters,
1124 &tmp, pi->sram_end);
1125
1126 if (ret)
1127 return ret;
1128
1129 pi->soft_regs_start = (u16)tmp;
1130
1131 ret = rv770_read_smc_sram_dword(rdev,
1132 NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
1133 NISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable,
1134 &tmp, pi->sram_end);
1135
1136 if (ret)
1137 return ret;
1138
1139 eg_pi->mc_reg_table_start = (u16)tmp;
1140
1141 ret = rv770_read_smc_sram_dword(rdev,
1142 NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
1143 NISLANDS_SMC_FIRMWARE_HEADER_fanTable,
1144 &tmp, pi->sram_end);
1145
1146 if (ret)
1147 return ret;
1148
1149 ni_pi->fan_table_start = (u16)tmp;
1150
1151 ret = rv770_read_smc_sram_dword(rdev,
1152 NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
1153 NISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable,
1154 &tmp, pi->sram_end);
1155
1156 if (ret)
1157 return ret;
1158
1159 ni_pi->arb_table_start = (u16)tmp;
1160
1161 ret = rv770_read_smc_sram_dword(rdev,
1162 NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
1163 NISLANDS_SMC_FIRMWARE_HEADER_cacTable,
1164 &tmp, pi->sram_end);
1165
1166 if (ret)
1167 return ret;
1168
1169 ni_pi->cac_table_start = (u16)tmp;
1170
1171 ret = rv770_read_smc_sram_dword(rdev,
1172 NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
1173 NISLANDS_SMC_FIRMWARE_HEADER_spllTable,
1174 &tmp, pi->sram_end);
1175
1176 if (ret)
1177 return ret;
1178
1179 ni_pi->spll_table_start = (u16)tmp;
1180
1181
1182 return ret;
1183 }
1184
ni_read_clock_registers(struct radeon_device * rdev)1185 static void ni_read_clock_registers(struct radeon_device *rdev)
1186 {
1187 struct ni_power_info *ni_pi = ni_get_pi(rdev);
1188
1189 ni_pi->clock_registers.cg_spll_func_cntl = RREG32(CG_SPLL_FUNC_CNTL);
1190 ni_pi->clock_registers.cg_spll_func_cntl_2 = RREG32(CG_SPLL_FUNC_CNTL_2);
1191 ni_pi->clock_registers.cg_spll_func_cntl_3 = RREG32(CG_SPLL_FUNC_CNTL_3);
1192 ni_pi->clock_registers.cg_spll_func_cntl_4 = RREG32(CG_SPLL_FUNC_CNTL_4);
1193 ni_pi->clock_registers.cg_spll_spread_spectrum = RREG32(CG_SPLL_SPREAD_SPECTRUM);
1194 ni_pi->clock_registers.cg_spll_spread_spectrum_2 = RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
1195 ni_pi->clock_registers.mpll_ad_func_cntl = RREG32(MPLL_AD_FUNC_CNTL);
1196 ni_pi->clock_registers.mpll_ad_func_cntl_2 = RREG32(MPLL_AD_FUNC_CNTL_2);
1197 ni_pi->clock_registers.mpll_dq_func_cntl = RREG32(MPLL_DQ_FUNC_CNTL);
1198 ni_pi->clock_registers.mpll_dq_func_cntl_2 = RREG32(MPLL_DQ_FUNC_CNTL_2);
1199 ni_pi->clock_registers.mclk_pwrmgt_cntl = RREG32(MCLK_PWRMGT_CNTL);
1200 ni_pi->clock_registers.dll_cntl = RREG32(DLL_CNTL);
1201 ni_pi->clock_registers.mpll_ss1 = RREG32(MPLL_SS1);
1202 ni_pi->clock_registers.mpll_ss2 = RREG32(MPLL_SS2);
1203 }
1204
1205 #if 0
1206 static int ni_enter_ulp_state(struct radeon_device *rdev)
1207 {
1208 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1209
1210 if (pi->gfx_clock_gating) {
1211 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
1212 WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
1213 WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
1214 RREG32(GB_ADDR_CONFIG);
1215 }
1216
1217 WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_SwitchToMinimumPower),
1218 ~HOST_SMC_MSG_MASK);
1219
1220 udelay(25000);
1221
1222 return 0;
1223 }
1224 #endif
1225
ni_program_response_times(struct radeon_device * rdev)1226 static void ni_program_response_times(struct radeon_device *rdev)
1227 {
1228 u32 voltage_response_time, backbias_response_time, acpi_delay_time, vbi_time_out;
1229 u32 vddc_dly, bb_dly, acpi_dly, vbi_dly, mclk_switch_limit;
1230 u32 reference_clock;
1231
1232 rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mvdd_chg_time, 1);
1233
1234 voltage_response_time = (u32)rdev->pm.dpm.voltage_response_time;
1235 backbias_response_time = (u32)rdev->pm.dpm.backbias_response_time;
1236
1237 if (voltage_response_time == 0)
1238 voltage_response_time = 1000;
1239
1240 if (backbias_response_time == 0)
1241 backbias_response_time = 1000;
1242
1243 acpi_delay_time = 15000;
1244 vbi_time_out = 100000;
1245
1246 reference_clock = radeon_get_xclk(rdev);
1247
1248 vddc_dly = (voltage_response_time * reference_clock) / 1600;
1249 bb_dly = (backbias_response_time * reference_clock) / 1600;
1250 acpi_dly = (acpi_delay_time * reference_clock) / 1600;
1251 vbi_dly = (vbi_time_out * reference_clock) / 1600;
1252
1253 mclk_switch_limit = (460 * reference_clock) / 100;
1254
1255 rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_delay_vreg, vddc_dly);
1256 rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_delay_bbias, bb_dly);
1257 rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_delay_acpi, acpi_dly);
1258 rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);
1259 rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mc_block_delay, 0xAA);
1260 rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mclk_switch_lim, mclk_switch_limit);
1261 }
1262
ni_populate_smc_voltage_table(struct radeon_device * rdev,struct atom_voltage_table * voltage_table,NISLANDS_SMC_STATETABLE * table)1263 static void ni_populate_smc_voltage_table(struct radeon_device *rdev,
1264 struct atom_voltage_table *voltage_table,
1265 NISLANDS_SMC_STATETABLE *table)
1266 {
1267 unsigned int i;
1268
1269 for (i = 0; i < voltage_table->count; i++) {
1270 table->highSMIO[i] = 0;
1271 table->lowSMIO[i] |= cpu_to_be32(voltage_table->entries[i].smio_low);
1272 }
1273 }
1274
ni_populate_smc_voltage_tables(struct radeon_device * rdev,NISLANDS_SMC_STATETABLE * table)1275 static void ni_populate_smc_voltage_tables(struct radeon_device *rdev,
1276 NISLANDS_SMC_STATETABLE *table)
1277 {
1278 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1279 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1280 unsigned char i;
1281
1282 if (eg_pi->vddc_voltage_table.count) {
1283 ni_populate_smc_voltage_table(rdev, &eg_pi->vddc_voltage_table, table);
1284 table->voltageMaskTable.highMask[NISLANDS_SMC_VOLTAGEMASK_VDDC] = 0;
1285 table->voltageMaskTable.lowMask[NISLANDS_SMC_VOLTAGEMASK_VDDC] =
1286 cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
1287
1288 for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {
1289 if (pi->max_vddc_in_table <= eg_pi->vddc_voltage_table.entries[i].value) {
1290 table->maxVDDCIndexInPPTable = i;
1291 break;
1292 }
1293 }
1294 }
1295
1296 if (eg_pi->vddci_voltage_table.count) {
1297 ni_populate_smc_voltage_table(rdev, &eg_pi->vddci_voltage_table, table);
1298
1299 table->voltageMaskTable.highMask[NISLANDS_SMC_VOLTAGEMASK_VDDCI] = 0;
1300 table->voltageMaskTable.lowMask[NISLANDS_SMC_VOLTAGEMASK_VDDCI] =
1301 cpu_to_be32(eg_pi->vddci_voltage_table.mask_low);
1302 }
1303 }
1304
ni_populate_voltage_value(struct radeon_device * rdev,struct atom_voltage_table * table,u16 value,NISLANDS_SMC_VOLTAGE_VALUE * voltage)1305 static int ni_populate_voltage_value(struct radeon_device *rdev,
1306 struct atom_voltage_table *table,
1307 u16 value,
1308 NISLANDS_SMC_VOLTAGE_VALUE *voltage)
1309 {
1310 unsigned int i;
1311
1312 for (i = 0; i < table->count; i++) {
1313 if (value <= table->entries[i].value) {
1314 voltage->index = (u8)i;
1315 voltage->value = cpu_to_be16(table->entries[i].value);
1316 break;
1317 }
1318 }
1319
1320 if (i >= table->count)
1321 return -EINVAL;
1322
1323 return 0;
1324 }
1325
ni_populate_mvdd_value(struct radeon_device * rdev,u32 mclk,NISLANDS_SMC_VOLTAGE_VALUE * voltage)1326 static void ni_populate_mvdd_value(struct radeon_device *rdev,
1327 u32 mclk,
1328 NISLANDS_SMC_VOLTAGE_VALUE *voltage)
1329 {
1330 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1331 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1332
1333 if (!pi->mvdd_control) {
1334 voltage->index = eg_pi->mvdd_high_index;
1335 voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
1336 return;
1337 }
1338
1339 if (mclk <= pi->mvdd_split_frequency) {
1340 voltage->index = eg_pi->mvdd_low_index;
1341 voltage->value = cpu_to_be16(MVDD_LOW_VALUE);
1342 } else {
1343 voltage->index = eg_pi->mvdd_high_index;
1344 voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
1345 }
1346 }
1347
ni_get_std_voltage_value(struct radeon_device * rdev,NISLANDS_SMC_VOLTAGE_VALUE * voltage,u16 * std_voltage)1348 static int ni_get_std_voltage_value(struct radeon_device *rdev,
1349 NISLANDS_SMC_VOLTAGE_VALUE *voltage,
1350 u16 *std_voltage)
1351 {
1352 if (rdev->pm.dpm.dyn_state.cac_leakage_table.entries &&
1353 ((u32)voltage->index < rdev->pm.dpm.dyn_state.cac_leakage_table.count))
1354 *std_voltage = rdev->pm.dpm.dyn_state.cac_leakage_table.entries[voltage->index].vddc;
1355 else
1356 *std_voltage = be16_to_cpu(voltage->value);
1357
1358 return 0;
1359 }
1360
ni_populate_std_voltage_value(struct radeon_device * rdev,u16 value,u8 index,NISLANDS_SMC_VOLTAGE_VALUE * voltage)1361 static void ni_populate_std_voltage_value(struct radeon_device *rdev,
1362 u16 value, u8 index,
1363 NISLANDS_SMC_VOLTAGE_VALUE *voltage)
1364 {
1365 voltage->index = index;
1366 voltage->value = cpu_to_be16(value);
1367 }
1368
ni_get_smc_power_scaling_factor(struct radeon_device * rdev)1369 static u32 ni_get_smc_power_scaling_factor(struct radeon_device *rdev)
1370 {
1371 u32 xclk_period;
1372 u32 xclk = radeon_get_xclk(rdev);
1373 u32 tmp = RREG32(CG_CAC_CTRL) & TID_CNT_MASK;
1374
1375 xclk_period = (1000000000UL / xclk);
1376 xclk_period /= 10000UL;
1377
1378 return tmp * xclk_period;
1379 }
1380
ni_scale_power_for_smc(u32 power_in_watts,u32 scaling_factor)1381 static u32 ni_scale_power_for_smc(u32 power_in_watts, u32 scaling_factor)
1382 {
1383 return (power_in_watts * scaling_factor) << 2;
1384 }
1385
ni_calculate_power_boost_limit(struct radeon_device * rdev,struct radeon_ps * radeon_state,u32 near_tdp_limit)1386 static u32 ni_calculate_power_boost_limit(struct radeon_device *rdev,
1387 struct radeon_ps *radeon_state,
1388 u32 near_tdp_limit)
1389 {
1390 struct ni_ps *state = ni_get_ps(radeon_state);
1391 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1392 struct ni_power_info *ni_pi = ni_get_pi(rdev);
1393 u32 power_boost_limit = 0;
1394 int ret;
1395
1396 if (ni_pi->enable_power_containment &&
1397 ni_pi->use_power_boost_limit) {
1398 NISLANDS_SMC_VOLTAGE_VALUE vddc;
1399 u16 std_vddc_med;
1400 u16 std_vddc_high;
1401 u64 tmp, n, d;
1402
1403 if (state->performance_level_count < 3)
1404 return 0;
1405
1406 ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
1407 state->performance_levels[state->performance_level_count - 2].vddc,
1408 &vddc);
1409 if (ret)
1410 return 0;
1411
1412 ret = ni_get_std_voltage_value(rdev, &vddc, &std_vddc_med);
1413 if (ret)
1414 return 0;
1415
1416 ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
1417 state->performance_levels[state->performance_level_count - 1].vddc,
1418 &vddc);
1419 if (ret)
1420 return 0;
1421
1422 ret = ni_get_std_voltage_value(rdev, &vddc, &std_vddc_high);
1423 if (ret)
1424 return 0;
1425
1426 n = ((u64)near_tdp_limit * ((u64)std_vddc_med * (u64)std_vddc_med) * 90);
1427 d = ((u64)std_vddc_high * (u64)std_vddc_high * 100);
1428 tmp = div64_u64(n, d);
1429
1430 if (tmp >> 32)
1431 return 0;
1432 power_boost_limit = (u32)tmp;
1433 }
1434
1435 return power_boost_limit;
1436 }
1437
ni_calculate_adjusted_tdp_limits(struct radeon_device * rdev,bool adjust_polarity,u32 tdp_adjustment,u32 * tdp_limit,u32 * near_tdp_limit)1438 static int ni_calculate_adjusted_tdp_limits(struct radeon_device *rdev,
1439 bool adjust_polarity,
1440 u32 tdp_adjustment,
1441 u32 *tdp_limit,
1442 u32 *near_tdp_limit)
1443 {
1444 if (tdp_adjustment > (u32)rdev->pm.dpm.tdp_od_limit)
1445 return -EINVAL;
1446
1447 if (adjust_polarity) {
1448 *tdp_limit = ((100 + tdp_adjustment) * rdev->pm.dpm.tdp_limit) / 100;
1449 *near_tdp_limit = rdev->pm.dpm.near_tdp_limit + (*tdp_limit - rdev->pm.dpm.tdp_limit);
1450 } else {
1451 *tdp_limit = ((100 - tdp_adjustment) * rdev->pm.dpm.tdp_limit) / 100;
1452 *near_tdp_limit = rdev->pm.dpm.near_tdp_limit - (rdev->pm.dpm.tdp_limit - *tdp_limit);
1453 }
1454
1455 return 0;
1456 }
1457
ni_populate_smc_tdp_limits(struct radeon_device * rdev,struct radeon_ps * radeon_state)1458 static int ni_populate_smc_tdp_limits(struct radeon_device *rdev,
1459 struct radeon_ps *radeon_state)
1460 {
1461 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1462 struct ni_power_info *ni_pi = ni_get_pi(rdev);
1463
1464 if (ni_pi->enable_power_containment) {
1465 NISLANDS_SMC_STATETABLE *smc_table = &ni_pi->smc_statetable;
1466 u32 scaling_factor = ni_get_smc_power_scaling_factor(rdev);
1467 u32 tdp_limit;
1468 u32 near_tdp_limit;
1469 u32 power_boost_limit;
1470 int ret;
1471
1472 if (scaling_factor == 0)
1473 return -EINVAL;
1474
1475 memset(smc_table, 0, sizeof(NISLANDS_SMC_STATETABLE));
1476
1477 ret = ni_calculate_adjusted_tdp_limits(rdev,
1478 false, /* ??? */
1479 rdev->pm.dpm.tdp_adjustment,
1480 &tdp_limit,
1481 &near_tdp_limit);
1482 if (ret)
1483 return ret;
1484
1485 power_boost_limit = ni_calculate_power_boost_limit(rdev, radeon_state,
1486 near_tdp_limit);
1487
1488 smc_table->dpm2Params.TDPLimit =
1489 cpu_to_be32(ni_scale_power_for_smc(tdp_limit, scaling_factor));
1490 smc_table->dpm2Params.NearTDPLimit =
1491 cpu_to_be32(ni_scale_power_for_smc(near_tdp_limit, scaling_factor));
1492 smc_table->dpm2Params.SafePowerLimit =
1493 cpu_to_be32(ni_scale_power_for_smc((near_tdp_limit * NISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100,
1494 scaling_factor));
1495 smc_table->dpm2Params.PowerBoostLimit =
1496 cpu_to_be32(ni_scale_power_for_smc(power_boost_limit, scaling_factor));
1497
1498 ret = rv770_copy_bytes_to_smc(rdev,
1499 (u16)(pi->state_table_start + offsetof(NISLANDS_SMC_STATETABLE, dpm2Params) +
1500 offsetof(PP_NIslands_DPM2Parameters, TDPLimit)),
1501 (u8 *)(&smc_table->dpm2Params.TDPLimit),
1502 sizeof(u32) * 4, pi->sram_end);
1503 if (ret)
1504 return ret;
1505 }
1506
1507 return 0;
1508 }
1509
ni_copy_and_switch_arb_sets(struct radeon_device * rdev,u32 arb_freq_src,u32 arb_freq_dest)1510 int ni_copy_and_switch_arb_sets(struct radeon_device *rdev,
1511 u32 arb_freq_src, u32 arb_freq_dest)
1512 {
1513 u32 mc_arb_dram_timing;
1514 u32 mc_arb_dram_timing2;
1515 u32 burst_time;
1516 u32 mc_cg_config;
1517
1518 switch (arb_freq_src) {
1519 case MC_CG_ARB_FREQ_F0:
1520 mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING);
1521 mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
1522 burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE0_MASK) >> STATE0_SHIFT;
1523 break;
1524 case MC_CG_ARB_FREQ_F1:
1525 mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING_1);
1526 mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_1);
1527 burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE1_MASK) >> STATE1_SHIFT;
1528 break;
1529 case MC_CG_ARB_FREQ_F2:
1530 mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING_2);
1531 mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_2);
1532 burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE2_MASK) >> STATE2_SHIFT;
1533 break;
1534 case MC_CG_ARB_FREQ_F3:
1535 mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING_3);
1536 mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_3);
1537 burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE3_MASK) >> STATE3_SHIFT;
1538 break;
1539 default:
1540 return -EINVAL;
1541 }
1542
1543 switch (arb_freq_dest) {
1544 case MC_CG_ARB_FREQ_F0:
1545 WREG32(MC_ARB_DRAM_TIMING, mc_arb_dram_timing);
1546 WREG32(MC_ARB_DRAM_TIMING2, mc_arb_dram_timing2);
1547 WREG32_P(MC_ARB_BURST_TIME, STATE0(burst_time), ~STATE0_MASK);
1548 break;
1549 case MC_CG_ARB_FREQ_F1:
1550 WREG32(MC_ARB_DRAM_TIMING_1, mc_arb_dram_timing);
1551 WREG32(MC_ARB_DRAM_TIMING2_1, mc_arb_dram_timing2);
1552 WREG32_P(MC_ARB_BURST_TIME, STATE1(burst_time), ~STATE1_MASK);
1553 break;
1554 case MC_CG_ARB_FREQ_F2:
1555 WREG32(MC_ARB_DRAM_TIMING_2, mc_arb_dram_timing);
1556 WREG32(MC_ARB_DRAM_TIMING2_2, mc_arb_dram_timing2);
1557 WREG32_P(MC_ARB_BURST_TIME, STATE2(burst_time), ~STATE2_MASK);
1558 break;
1559 case MC_CG_ARB_FREQ_F3:
1560 WREG32(MC_ARB_DRAM_TIMING_3, mc_arb_dram_timing);
1561 WREG32(MC_ARB_DRAM_TIMING2_3, mc_arb_dram_timing2);
1562 WREG32_P(MC_ARB_BURST_TIME, STATE3(burst_time), ~STATE3_MASK);
1563 break;
1564 default:
1565 return -EINVAL;
1566 }
1567
1568 mc_cg_config = RREG32(MC_CG_CONFIG) | 0x0000000F;
1569 WREG32(MC_CG_CONFIG, mc_cg_config);
1570 WREG32_P(MC_ARB_CG, CG_ARB_REQ(arb_freq_dest), ~CG_ARB_REQ_MASK);
1571
1572 return 0;
1573 }
1574
ni_init_arb_table_index(struct radeon_device * rdev)1575 static int ni_init_arb_table_index(struct radeon_device *rdev)
1576 {
1577 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1578 struct ni_power_info *ni_pi = ni_get_pi(rdev);
1579 u32 tmp;
1580 int ret;
1581
1582 ret = rv770_read_smc_sram_dword(rdev, ni_pi->arb_table_start,
1583 &tmp, pi->sram_end);
1584 if (ret)
1585 return ret;
1586
1587 tmp &= 0x00FFFFFF;
1588 tmp |= ((u32)MC_CG_ARB_FREQ_F1) << 24;
1589
1590 return rv770_write_smc_sram_dword(rdev, ni_pi->arb_table_start,
1591 tmp, pi->sram_end);
1592 }
1593
ni_initial_switch_from_arb_f0_to_f1(struct radeon_device * rdev)1594 static int ni_initial_switch_from_arb_f0_to_f1(struct radeon_device *rdev)
1595 {
1596 return ni_copy_and_switch_arb_sets(rdev, MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);
1597 }
1598
ni_force_switch_to_arb_f0(struct radeon_device * rdev)1599 static int ni_force_switch_to_arb_f0(struct radeon_device *rdev)
1600 {
1601 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1602 struct ni_power_info *ni_pi = ni_get_pi(rdev);
1603 u32 tmp;
1604 int ret;
1605
1606 ret = rv770_read_smc_sram_dword(rdev, ni_pi->arb_table_start,
1607 &tmp, pi->sram_end);
1608 if (ret)
1609 return ret;
1610
1611 tmp = (tmp >> 24) & 0xff;
1612
1613 if (tmp == MC_CG_ARB_FREQ_F0)
1614 return 0;
1615
1616 return ni_copy_and_switch_arb_sets(rdev, tmp, MC_CG_ARB_FREQ_F0);
1617 }
1618
ni_populate_memory_timing_parameters(struct radeon_device * rdev,struct rv7xx_pl * pl,SMC_NIslands_MCArbDramTimingRegisterSet * arb_regs)1619 static int ni_populate_memory_timing_parameters(struct radeon_device *rdev,
1620 struct rv7xx_pl *pl,
1621 SMC_NIslands_MCArbDramTimingRegisterSet *arb_regs)
1622 {
1623 u32 dram_timing;
1624 u32 dram_timing2;
1625
1626 arb_regs->mc_arb_rfsh_rate =
1627 (u8)rv770_calculate_memory_refresh_rate(rdev, pl->sclk);
1628
1629
1630 radeon_atom_set_engine_dram_timings(rdev, pl->sclk, pl->mclk);
1631
1632 dram_timing = RREG32(MC_ARB_DRAM_TIMING);
1633 dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
1634
1635 arb_regs->mc_arb_dram_timing = cpu_to_be32(dram_timing);
1636 arb_regs->mc_arb_dram_timing2 = cpu_to_be32(dram_timing2);
1637
1638 return 0;
1639 }
1640
ni_do_program_memory_timing_parameters(struct radeon_device * rdev,struct radeon_ps * radeon_state,unsigned int first_arb_set)1641 static int ni_do_program_memory_timing_parameters(struct radeon_device *rdev,
1642 struct radeon_ps *radeon_state,
1643 unsigned int first_arb_set)
1644 {
1645 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1646 struct ni_power_info *ni_pi = ni_get_pi(rdev);
1647 struct ni_ps *state = ni_get_ps(radeon_state);
1648 SMC_NIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };
1649 int i, ret = 0;
1650
1651 for (i = 0; i < state->performance_level_count; i++) {
1652 ret = ni_populate_memory_timing_parameters(rdev, &state->performance_levels[i], &arb_regs);
1653 if (ret)
1654 break;
1655
1656 ret = rv770_copy_bytes_to_smc(rdev,
1657 (u16)(ni_pi->arb_table_start +
1658 offsetof(SMC_NIslands_MCArbDramTimingRegisters, data) +
1659 sizeof(SMC_NIslands_MCArbDramTimingRegisterSet) * (first_arb_set + i)),
1660 (u8 *)&arb_regs,
1661 (u16)sizeof(SMC_NIslands_MCArbDramTimingRegisterSet),
1662 pi->sram_end);
1663 if (ret)
1664 break;
1665 }
1666 return ret;
1667 }
1668
ni_program_memory_timing_parameters(struct radeon_device * rdev,struct radeon_ps * radeon_new_state)1669 static int ni_program_memory_timing_parameters(struct radeon_device *rdev,
1670 struct radeon_ps *radeon_new_state)
1671 {
1672 return ni_do_program_memory_timing_parameters(rdev, radeon_new_state,
1673 NISLANDS_DRIVER_STATE_ARB_INDEX);
1674 }
1675
ni_populate_initial_mvdd_value(struct radeon_device * rdev,struct NISLANDS_SMC_VOLTAGE_VALUE * voltage)1676 static void ni_populate_initial_mvdd_value(struct radeon_device *rdev,
1677 struct NISLANDS_SMC_VOLTAGE_VALUE *voltage)
1678 {
1679 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1680
1681 voltage->index = eg_pi->mvdd_high_index;
1682 voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
1683 }
1684
ni_populate_smc_initial_state(struct radeon_device * rdev,struct radeon_ps * radeon_initial_state,NISLANDS_SMC_STATETABLE * table)1685 static int ni_populate_smc_initial_state(struct radeon_device *rdev,
1686 struct radeon_ps *radeon_initial_state,
1687 NISLANDS_SMC_STATETABLE *table)
1688 {
1689 struct ni_ps *initial_state = ni_get_ps(radeon_initial_state);
1690 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1691 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1692 struct ni_power_info *ni_pi = ni_get_pi(rdev);
1693 u32 reg;
1694 int ret;
1695
1696 table->initialState.levels[0].mclk.vMPLL_AD_FUNC_CNTL =
1697 cpu_to_be32(ni_pi->clock_registers.mpll_ad_func_cntl);
1698 table->initialState.levels[0].mclk.vMPLL_AD_FUNC_CNTL_2 =
1699 cpu_to_be32(ni_pi->clock_registers.mpll_ad_func_cntl_2);
1700 table->initialState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL =
1701 cpu_to_be32(ni_pi->clock_registers.mpll_dq_func_cntl);
1702 table->initialState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL_2 =
1703 cpu_to_be32(ni_pi->clock_registers.mpll_dq_func_cntl_2);
1704 table->initialState.levels[0].mclk.vMCLK_PWRMGT_CNTL =
1705 cpu_to_be32(ni_pi->clock_registers.mclk_pwrmgt_cntl);
1706 table->initialState.levels[0].mclk.vDLL_CNTL =
1707 cpu_to_be32(ni_pi->clock_registers.dll_cntl);
1708 table->initialState.levels[0].mclk.vMPLL_SS =
1709 cpu_to_be32(ni_pi->clock_registers.mpll_ss1);
1710 table->initialState.levels[0].mclk.vMPLL_SS2 =
1711 cpu_to_be32(ni_pi->clock_registers.mpll_ss2);
1712 table->initialState.levels[0].mclk.mclk_value =
1713 cpu_to_be32(initial_state->performance_levels[0].mclk);
1714
1715 table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
1716 cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl);
1717 table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
1718 cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl_2);
1719 table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
1720 cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl_3);
1721 table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_4 =
1722 cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl_4);
1723 table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM =
1724 cpu_to_be32(ni_pi->clock_registers.cg_spll_spread_spectrum);
1725 table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =
1726 cpu_to_be32(ni_pi->clock_registers.cg_spll_spread_spectrum_2);
1727 table->initialState.levels[0].sclk.sclk_value =
1728 cpu_to_be32(initial_state->performance_levels[0].sclk);
1729 table->initialState.levels[0].arbRefreshState =
1730 NISLANDS_INITIAL_STATE_ARB_INDEX;
1731
1732 table->initialState.levels[0].ACIndex = 0;
1733
1734 ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
1735 initial_state->performance_levels[0].vddc,
1736 &table->initialState.levels[0].vddc);
1737 if (!ret) {
1738 u16 std_vddc;
1739
1740 ret = ni_get_std_voltage_value(rdev,
1741 &table->initialState.levels[0].vddc,
1742 &std_vddc);
1743 if (!ret)
1744 ni_populate_std_voltage_value(rdev, std_vddc,
1745 table->initialState.levels[0].vddc.index,
1746 &table->initialState.levels[0].std_vddc);
1747 }
1748
1749 if (eg_pi->vddci_control)
1750 ni_populate_voltage_value(rdev,
1751 &eg_pi->vddci_voltage_table,
1752 initial_state->performance_levels[0].vddci,
1753 &table->initialState.levels[0].vddci);
1754
1755 ni_populate_initial_mvdd_value(rdev, &table->initialState.levels[0].mvdd);
1756
1757 reg = CG_R(0xffff) | CG_L(0);
1758 table->initialState.levels[0].aT = cpu_to_be32(reg);
1759
1760 table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp);
1761
1762 if (pi->boot_in_gen2)
1763 table->initialState.levels[0].gen2PCIE = 1;
1764 else
1765 table->initialState.levels[0].gen2PCIE = 0;
1766
1767 if (pi->mem_gddr5) {
1768 table->initialState.levels[0].strobeMode =
1769 cypress_get_strobe_mode_settings(rdev,
1770 initial_state->performance_levels[0].mclk);
1771
1772 if (initial_state->performance_levels[0].mclk > pi->mclk_edc_enable_threshold)
1773 table->initialState.levels[0].mcFlags = NISLANDS_SMC_MC_EDC_RD_FLAG | NISLANDS_SMC_MC_EDC_WR_FLAG;
1774 else
1775 table->initialState.levels[0].mcFlags = 0;
1776 }
1777
1778 table->initialState.levelCount = 1;
1779
1780 table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
1781
1782 table->initialState.levels[0].dpm2.MaxPS = 0;
1783 table->initialState.levels[0].dpm2.NearTDPDec = 0;
1784 table->initialState.levels[0].dpm2.AboveSafeInc = 0;
1785 table->initialState.levels[0].dpm2.BelowSafeInc = 0;
1786
1787 reg = MIN_POWER_MASK | MAX_POWER_MASK;
1788 table->initialState.levels[0].SQPowerThrottle = cpu_to_be32(reg);
1789
1790 reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
1791 table->initialState.levels[0].SQPowerThrottle_2 = cpu_to_be32(reg);
1792
1793 return 0;
1794 }
1795
ni_populate_smc_acpi_state(struct radeon_device * rdev,NISLANDS_SMC_STATETABLE * table)1796 static int ni_populate_smc_acpi_state(struct radeon_device *rdev,
1797 NISLANDS_SMC_STATETABLE *table)
1798 {
1799 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1800 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1801 struct ni_power_info *ni_pi = ni_get_pi(rdev);
1802 u32 mpll_ad_func_cntl = ni_pi->clock_registers.mpll_ad_func_cntl;
1803 u32 mpll_ad_func_cntl_2 = ni_pi->clock_registers.mpll_ad_func_cntl_2;
1804 u32 mpll_dq_func_cntl = ni_pi->clock_registers.mpll_dq_func_cntl;
1805 u32 mpll_dq_func_cntl_2 = ni_pi->clock_registers.mpll_dq_func_cntl_2;
1806 u32 spll_func_cntl = ni_pi->clock_registers.cg_spll_func_cntl;
1807 u32 spll_func_cntl_2 = ni_pi->clock_registers.cg_spll_func_cntl_2;
1808 u32 spll_func_cntl_3 = ni_pi->clock_registers.cg_spll_func_cntl_3;
1809 u32 spll_func_cntl_4 = ni_pi->clock_registers.cg_spll_func_cntl_4;
1810 u32 mclk_pwrmgt_cntl = ni_pi->clock_registers.mclk_pwrmgt_cntl;
1811 u32 dll_cntl = ni_pi->clock_registers.dll_cntl;
1812 u32 reg;
1813 int ret;
1814
1815 table->ACPIState = table->initialState;
1816
1817 table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
1818
1819 if (pi->acpi_vddc) {
1820 ret = ni_populate_voltage_value(rdev,
1821 &eg_pi->vddc_voltage_table,
1822 pi->acpi_vddc, &table->ACPIState.levels[0].vddc);
1823 if (!ret) {
1824 u16 std_vddc;
1825
1826 ret = ni_get_std_voltage_value(rdev,
1827 &table->ACPIState.levels[0].vddc, &std_vddc);
1828 if (!ret)
1829 ni_populate_std_voltage_value(rdev, std_vddc,
1830 table->ACPIState.levels[0].vddc.index,
1831 &table->ACPIState.levels[0].std_vddc);
1832 }
1833
1834 if (pi->pcie_gen2) {
1835 if (pi->acpi_pcie_gen2)
1836 table->ACPIState.levels[0].gen2PCIE = 1;
1837 else
1838 table->ACPIState.levels[0].gen2PCIE = 0;
1839 } else {
1840 table->ACPIState.levels[0].gen2PCIE = 0;
1841 }
1842 } else {
1843 ret = ni_populate_voltage_value(rdev,
1844 &eg_pi->vddc_voltage_table,
1845 pi->min_vddc_in_table,
1846 &table->ACPIState.levels[0].vddc);
1847 if (!ret) {
1848 u16 std_vddc;
1849
1850 ret = ni_get_std_voltage_value(rdev,
1851 &table->ACPIState.levels[0].vddc,
1852 &std_vddc);
1853 if (!ret)
1854 ni_populate_std_voltage_value(rdev, std_vddc,
1855 table->ACPIState.levels[0].vddc.index,
1856 &table->ACPIState.levels[0].std_vddc);
1857 }
1858 table->ACPIState.levels[0].gen2PCIE = 0;
1859 }
1860
1861 if (eg_pi->acpi_vddci) {
1862 if (eg_pi->vddci_control)
1863 ni_populate_voltage_value(rdev,
1864 &eg_pi->vddci_voltage_table,
1865 eg_pi->acpi_vddci,
1866 &table->ACPIState.levels[0].vddci);
1867 }
1868
1869
1870 mpll_ad_func_cntl &= ~PDNB;
1871
1872 mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
1873
1874 if (pi->mem_gddr5)
1875 mpll_dq_func_cntl &= ~PDNB;
1876 mpll_dq_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN | BYPASS;
1877
1878
1879 mclk_pwrmgt_cntl |= (MRDCKA0_RESET |
1880 MRDCKA1_RESET |
1881 MRDCKB0_RESET |
1882 MRDCKB1_RESET |
1883 MRDCKC0_RESET |
1884 MRDCKC1_RESET |
1885 MRDCKD0_RESET |
1886 MRDCKD1_RESET);
1887
1888 mclk_pwrmgt_cntl &= ~(MRDCKA0_PDNB |
1889 MRDCKA1_PDNB |
1890 MRDCKB0_PDNB |
1891 MRDCKB1_PDNB |
1892 MRDCKC0_PDNB |
1893 MRDCKC1_PDNB |
1894 MRDCKD0_PDNB |
1895 MRDCKD1_PDNB);
1896
1897 dll_cntl |= (MRDCKA0_BYPASS |
1898 MRDCKA1_BYPASS |
1899 MRDCKB0_BYPASS |
1900 MRDCKB1_BYPASS |
1901 MRDCKC0_BYPASS |
1902 MRDCKC1_BYPASS |
1903 MRDCKD0_BYPASS |
1904 MRDCKD1_BYPASS);
1905
1906 spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
1907 spll_func_cntl_2 |= SCLK_MUX_SEL(4);
1908
1909 table->ACPIState.levels[0].mclk.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
1910 table->ACPIState.levels[0].mclk.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
1911 table->ACPIState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
1912 table->ACPIState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
1913 table->ACPIState.levels[0].mclk.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
1914 table->ACPIState.levels[0].mclk.vDLL_CNTL = cpu_to_be32(dll_cntl);
1915
1916 table->ACPIState.levels[0].mclk.mclk_value = 0;
1917
1918 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
1919 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
1920 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
1921 table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(spll_func_cntl_4);
1922
1923 table->ACPIState.levels[0].sclk.sclk_value = 0;
1924
1925 ni_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
1926
1927 if (eg_pi->dynamic_ac_timing)
1928 table->ACPIState.levels[0].ACIndex = 1;
1929
1930 table->ACPIState.levels[0].dpm2.MaxPS = 0;
1931 table->ACPIState.levels[0].dpm2.NearTDPDec = 0;
1932 table->ACPIState.levels[0].dpm2.AboveSafeInc = 0;
1933 table->ACPIState.levels[0].dpm2.BelowSafeInc = 0;
1934
1935 reg = MIN_POWER_MASK | MAX_POWER_MASK;
1936 table->ACPIState.levels[0].SQPowerThrottle = cpu_to_be32(reg);
1937
1938 reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
1939 table->ACPIState.levels[0].SQPowerThrottle_2 = cpu_to_be32(reg);
1940
1941 return 0;
1942 }
1943
ni_init_smc_table(struct radeon_device * rdev)1944 static int ni_init_smc_table(struct radeon_device *rdev)
1945 {
1946 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1947 struct ni_power_info *ni_pi = ni_get_pi(rdev);
1948 int ret;
1949 struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps;
1950 NISLANDS_SMC_STATETABLE *table = &ni_pi->smc_statetable;
1951
1952 memset(table, 0, sizeof(NISLANDS_SMC_STATETABLE));
1953
1954 ni_populate_smc_voltage_tables(rdev, table);
1955
1956 switch (rdev->pm.int_thermal_type) {
1957 case THERMAL_TYPE_NI:
1958 case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
1959 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
1960 break;
1961 case THERMAL_TYPE_NONE:
1962 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
1963 break;
1964 default:
1965 table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
1966 break;
1967 }
1968
1969 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
1970 table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
1971
1972 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT)
1973 table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
1974
1975 if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
1976 table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
1977
1978 if (pi->mem_gddr5)
1979 table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
1980
1981 ret = ni_populate_smc_initial_state(rdev, radeon_boot_state, table);
1982 if (ret)
1983 return ret;
1984
1985 ret = ni_populate_smc_acpi_state(rdev, table);
1986 if (ret)
1987 return ret;
1988
1989 table->driverState = table->initialState;
1990
1991 table->ULVState = table->initialState;
1992
1993 ret = ni_do_program_memory_timing_parameters(rdev, radeon_boot_state,
1994 NISLANDS_INITIAL_STATE_ARB_INDEX);
1995 if (ret)
1996 return ret;
1997
1998 return rv770_copy_bytes_to_smc(rdev, pi->state_table_start, (u8 *)table,
1999 sizeof(NISLANDS_SMC_STATETABLE), pi->sram_end);
2000 }
2001
ni_calculate_sclk_params(struct radeon_device * rdev,u32 engine_clock,NISLANDS_SMC_SCLK_VALUE * sclk)2002 static int ni_calculate_sclk_params(struct radeon_device *rdev,
2003 u32 engine_clock,
2004 NISLANDS_SMC_SCLK_VALUE *sclk)
2005 {
2006 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2007 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2008 struct atom_clock_dividers dividers;
2009 u32 spll_func_cntl = ni_pi->clock_registers.cg_spll_func_cntl;
2010 u32 spll_func_cntl_2 = ni_pi->clock_registers.cg_spll_func_cntl_2;
2011 u32 spll_func_cntl_3 = ni_pi->clock_registers.cg_spll_func_cntl_3;
2012 u32 spll_func_cntl_4 = ni_pi->clock_registers.cg_spll_func_cntl_4;
2013 u32 cg_spll_spread_spectrum = ni_pi->clock_registers.cg_spll_spread_spectrum;
2014 u32 cg_spll_spread_spectrum_2 = ni_pi->clock_registers.cg_spll_spread_spectrum_2;
2015 u64 tmp;
2016 u32 reference_clock = rdev->clock.spll.reference_freq;
2017 u32 reference_divider;
2018 u32 fbdiv;
2019 int ret;
2020
2021 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
2022 engine_clock, false, ÷rs);
2023 if (ret)
2024 return ret;
2025
2026 reference_divider = 1 + dividers.ref_div;
2027
2028
2029 tmp = (u64) engine_clock * reference_divider * dividers.post_div * 16834;
2030 do_div(tmp, reference_clock);
2031 fbdiv = (u32) tmp;
2032
2033 spll_func_cntl &= ~(SPLL_PDIV_A_MASK | SPLL_REF_DIV_MASK);
2034 spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
2035 spll_func_cntl |= SPLL_PDIV_A(dividers.post_div);
2036
2037 spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
2038 spll_func_cntl_2 |= SCLK_MUX_SEL(2);
2039
2040 spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
2041 spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
2042 spll_func_cntl_3 |= SPLL_DITHEN;
2043
2044 if (pi->sclk_ss) {
2045 struct radeon_atom_ss ss;
2046 u32 vco_freq = engine_clock * dividers.post_div;
2047
2048 if (radeon_atombios_get_asic_ss_info(rdev, &ss,
2049 ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
2050 u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
2051 u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000);
2052
2053 cg_spll_spread_spectrum &= ~CLK_S_MASK;
2054 cg_spll_spread_spectrum |= CLK_S(clk_s);
2055 cg_spll_spread_spectrum |= SSEN;
2056
2057 cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
2058 cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
2059 }
2060 }
2061
2062 sclk->sclk_value = engine_clock;
2063 sclk->vCG_SPLL_FUNC_CNTL = spll_func_cntl;
2064 sclk->vCG_SPLL_FUNC_CNTL_2 = spll_func_cntl_2;
2065 sclk->vCG_SPLL_FUNC_CNTL_3 = spll_func_cntl_3;
2066 sclk->vCG_SPLL_FUNC_CNTL_4 = spll_func_cntl_4;
2067 sclk->vCG_SPLL_SPREAD_SPECTRUM = cg_spll_spread_spectrum;
2068 sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cg_spll_spread_spectrum_2;
2069
2070 return 0;
2071 }
2072
ni_populate_sclk_value(struct radeon_device * rdev,u32 engine_clock,NISLANDS_SMC_SCLK_VALUE * sclk)2073 static int ni_populate_sclk_value(struct radeon_device *rdev,
2074 u32 engine_clock,
2075 NISLANDS_SMC_SCLK_VALUE *sclk)
2076 {
2077 NISLANDS_SMC_SCLK_VALUE sclk_tmp;
2078 int ret;
2079
2080 ret = ni_calculate_sclk_params(rdev, engine_clock, &sclk_tmp);
2081 if (!ret) {
2082 sclk->sclk_value = cpu_to_be32(sclk_tmp.sclk_value);
2083 sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL);
2084 sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_2);
2085 sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_3);
2086 sclk->vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_4);
2087 sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM);
2088 sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM_2);
2089 }
2090
2091 return ret;
2092 }
2093
ni_init_smc_spll_table(struct radeon_device * rdev)2094 static int ni_init_smc_spll_table(struct radeon_device *rdev)
2095 {
2096 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2097 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2098 SMC_NISLANDS_SPLL_DIV_TABLE *spll_table;
2099 NISLANDS_SMC_SCLK_VALUE sclk_params;
2100 u32 fb_div;
2101 u32 p_div;
2102 u32 clk_s;
2103 u32 clk_v;
2104 u32 sclk = 0;
2105 int i, ret;
2106 u32 tmp;
2107
2108 if (ni_pi->spll_table_start == 0)
2109 return -EINVAL;
2110
2111 spll_table = kzalloc(sizeof(SMC_NISLANDS_SPLL_DIV_TABLE), GFP_KERNEL);
2112 if (spll_table == NULL)
2113 return -ENOMEM;
2114
2115 for (i = 0; i < 256; i++) {
2116 ret = ni_calculate_sclk_params(rdev, sclk, &sclk_params);
2117 if (ret)
2118 break;
2119
2120 p_div = (sclk_params.vCG_SPLL_FUNC_CNTL & SPLL_PDIV_A_MASK) >> SPLL_PDIV_A_SHIFT;
2121 fb_div = (sclk_params.vCG_SPLL_FUNC_CNTL_3 & SPLL_FB_DIV_MASK) >> SPLL_FB_DIV_SHIFT;
2122 clk_s = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM & CLK_S_MASK) >> CLK_S_SHIFT;
2123 clk_v = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM_2 & CLK_V_MASK) >> CLK_V_SHIFT;
2124
2125 fb_div &= ~0x00001FFF;
2126 fb_div >>= 1;
2127 clk_v >>= 6;
2128
2129 if (p_div & ~(SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT))
2130 ret = -EINVAL;
2131
2132 if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT))
2133 ret = -EINVAL;
2134
2135 if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT))
2136 ret = -EINVAL;
2137
2138 if (clk_v & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT))
2139 ret = -EINVAL;
2140
2141 if (ret)
2142 break;
2143
2144 tmp = ((fb_div << SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_MASK) |
2145 ((p_div << SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_MASK);
2146 spll_table->freq[i] = cpu_to_be32(tmp);
2147
2148 tmp = ((clk_v << SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK) |
2149 ((clk_s << SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK);
2150 spll_table->ss[i] = cpu_to_be32(tmp);
2151
2152 sclk += 512;
2153 }
2154
2155 if (!ret)
2156 ret = rv770_copy_bytes_to_smc(rdev, ni_pi->spll_table_start, (u8 *)spll_table,
2157 sizeof(SMC_NISLANDS_SPLL_DIV_TABLE), pi->sram_end);
2158
2159 kfree(spll_table);
2160
2161 return ret;
2162 }
2163
ni_populate_mclk_value(struct radeon_device * rdev,u32 engine_clock,u32 memory_clock,NISLANDS_SMC_MCLK_VALUE * mclk,bool strobe_mode,bool dll_state_on)2164 static int ni_populate_mclk_value(struct radeon_device *rdev,
2165 u32 engine_clock,
2166 u32 memory_clock,
2167 NISLANDS_SMC_MCLK_VALUE *mclk,
2168 bool strobe_mode,
2169 bool dll_state_on)
2170 {
2171 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2172 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2173 u32 mpll_ad_func_cntl = ni_pi->clock_registers.mpll_ad_func_cntl;
2174 u32 mpll_ad_func_cntl_2 = ni_pi->clock_registers.mpll_ad_func_cntl_2;
2175 u32 mpll_dq_func_cntl = ni_pi->clock_registers.mpll_dq_func_cntl;
2176 u32 mpll_dq_func_cntl_2 = ni_pi->clock_registers.mpll_dq_func_cntl_2;
2177 u32 mclk_pwrmgt_cntl = ni_pi->clock_registers.mclk_pwrmgt_cntl;
2178 u32 dll_cntl = ni_pi->clock_registers.dll_cntl;
2179 u32 mpll_ss1 = ni_pi->clock_registers.mpll_ss1;
2180 u32 mpll_ss2 = ni_pi->clock_registers.mpll_ss2;
2181 struct atom_clock_dividers dividers;
2182 u32 ibias;
2183 u32 dll_speed;
2184 int ret;
2185 u32 mc_seq_misc7;
2186
2187 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
2188 memory_clock, strobe_mode, ÷rs);
2189 if (ret)
2190 return ret;
2191
2192 if (!strobe_mode) {
2193 mc_seq_misc7 = RREG32(MC_SEQ_MISC7);
2194
2195 if (mc_seq_misc7 & 0x8000000)
2196 dividers.post_div = 1;
2197 }
2198
2199 ibias = cypress_map_clkf_to_ibias(rdev, dividers.whole_fb_div);
2200
2201 mpll_ad_func_cntl &= ~(CLKR_MASK |
2202 YCLK_POST_DIV_MASK |
2203 CLKF_MASK |
2204 CLKFRAC_MASK |
2205 IBIAS_MASK);
2206 mpll_ad_func_cntl |= CLKR(dividers.ref_div);
2207 mpll_ad_func_cntl |= YCLK_POST_DIV(dividers.post_div);
2208 mpll_ad_func_cntl |= CLKF(dividers.whole_fb_div);
2209 mpll_ad_func_cntl |= CLKFRAC(dividers.frac_fb_div);
2210 mpll_ad_func_cntl |= IBIAS(ibias);
2211
2212 if (dividers.vco_mode)
2213 mpll_ad_func_cntl_2 |= VCO_MODE;
2214 else
2215 mpll_ad_func_cntl_2 &= ~VCO_MODE;
2216
2217 if (pi->mem_gddr5) {
2218 mpll_dq_func_cntl &= ~(CLKR_MASK |
2219 YCLK_POST_DIV_MASK |
2220 CLKF_MASK |
2221 CLKFRAC_MASK |
2222 IBIAS_MASK);
2223 mpll_dq_func_cntl |= CLKR(dividers.ref_div);
2224 mpll_dq_func_cntl |= YCLK_POST_DIV(dividers.post_div);
2225 mpll_dq_func_cntl |= CLKF(dividers.whole_fb_div);
2226 mpll_dq_func_cntl |= CLKFRAC(dividers.frac_fb_div);
2227 mpll_dq_func_cntl |= IBIAS(ibias);
2228
2229 if (strobe_mode)
2230 mpll_dq_func_cntl &= ~PDNB;
2231 else
2232 mpll_dq_func_cntl |= PDNB;
2233
2234 if (dividers.vco_mode)
2235 mpll_dq_func_cntl_2 |= VCO_MODE;
2236 else
2237 mpll_dq_func_cntl_2 &= ~VCO_MODE;
2238 }
2239
2240 if (pi->mclk_ss) {
2241 struct radeon_atom_ss ss;
2242 u32 vco_freq = memory_clock * dividers.post_div;
2243
2244 if (radeon_atombios_get_asic_ss_info(rdev, &ss,
2245 ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
2246 u32 reference_clock = rdev->clock.mpll.reference_freq;
2247 u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
2248 u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
2249 u32 clk_v = ss.percentage *
2250 (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
2251
2252 mpll_ss1 &= ~CLKV_MASK;
2253 mpll_ss1 |= CLKV(clk_v);
2254
2255 mpll_ss2 &= ~CLKS_MASK;
2256 mpll_ss2 |= CLKS(clk_s);
2257 }
2258 }
2259
2260 dll_speed = rv740_get_dll_speed(pi->mem_gddr5,
2261 memory_clock);
2262
2263 mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;
2264 mclk_pwrmgt_cntl |= DLL_SPEED(dll_speed);
2265 if (dll_state_on)
2266 mclk_pwrmgt_cntl |= (MRDCKA0_PDNB |
2267 MRDCKA1_PDNB |
2268 MRDCKB0_PDNB |
2269 MRDCKB1_PDNB |
2270 MRDCKC0_PDNB |
2271 MRDCKC1_PDNB |
2272 MRDCKD0_PDNB |
2273 MRDCKD1_PDNB);
2274 else
2275 mclk_pwrmgt_cntl &= ~(MRDCKA0_PDNB |
2276 MRDCKA1_PDNB |
2277 MRDCKB0_PDNB |
2278 MRDCKB1_PDNB |
2279 MRDCKC0_PDNB |
2280 MRDCKC1_PDNB |
2281 MRDCKD0_PDNB |
2282 MRDCKD1_PDNB);
2283
2284
2285 mclk->mclk_value = cpu_to_be32(memory_clock);
2286 mclk->vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
2287 mclk->vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
2288 mclk->vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
2289 mclk->vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
2290 mclk->vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
2291 mclk->vDLL_CNTL = cpu_to_be32(dll_cntl);
2292 mclk->vMPLL_SS = cpu_to_be32(mpll_ss1);
2293 mclk->vMPLL_SS2 = cpu_to_be32(mpll_ss2);
2294
2295 return 0;
2296 }
2297
ni_populate_smc_sp(struct radeon_device * rdev,struct radeon_ps * radeon_state,NISLANDS_SMC_SWSTATE * smc_state)2298 static void ni_populate_smc_sp(struct radeon_device *rdev,
2299 struct radeon_ps *radeon_state,
2300 NISLANDS_SMC_SWSTATE *smc_state)
2301 {
2302 struct ni_ps *ps = ni_get_ps(radeon_state);
2303 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2304 int i;
2305
2306 for (i = 0; i < ps->performance_level_count - 1; i++)
2307 smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);
2308
2309 smc_state->levels[ps->performance_level_count - 1].bSP =
2310 cpu_to_be32(pi->psp);
2311 }
2312
ni_convert_power_level_to_smc(struct radeon_device * rdev,struct rv7xx_pl * pl,NISLANDS_SMC_HW_PERFORMANCE_LEVEL * level)2313 static int ni_convert_power_level_to_smc(struct radeon_device *rdev,
2314 struct rv7xx_pl *pl,
2315 NISLANDS_SMC_HW_PERFORMANCE_LEVEL *level)
2316 {
2317 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2318 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2319 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2320 int ret;
2321 bool dll_state_on;
2322 u16 std_vddc;
2323 u32 tmp = RREG32(DC_STUTTER_CNTL);
2324
2325 level->gen2PCIE = pi->pcie_gen2 ?
2326 ((pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0) : 0;
2327
2328 ret = ni_populate_sclk_value(rdev, pl->sclk, &level->sclk);
2329 if (ret)
2330 return ret;
2331
2332 level->mcFlags = 0;
2333 if (pi->mclk_stutter_mode_threshold &&
2334 (pl->mclk <= pi->mclk_stutter_mode_threshold) &&
2335 !eg_pi->uvd_enabled &&
2336 (tmp & DC_STUTTER_ENABLE_A) &&
2337 (tmp & DC_STUTTER_ENABLE_B))
2338 level->mcFlags |= NISLANDS_SMC_MC_STUTTER_EN;
2339
2340 if (pi->mem_gddr5) {
2341 if (pl->mclk > pi->mclk_edc_enable_threshold)
2342 level->mcFlags |= NISLANDS_SMC_MC_EDC_RD_FLAG;
2343 if (pl->mclk > eg_pi->mclk_edc_wr_enable_threshold)
2344 level->mcFlags |= NISLANDS_SMC_MC_EDC_WR_FLAG;
2345
2346 level->strobeMode = cypress_get_strobe_mode_settings(rdev, pl->mclk);
2347
2348 if (level->strobeMode & NISLANDS_SMC_STROBE_ENABLE) {
2349 if (cypress_get_mclk_frequency_ratio(rdev, pl->mclk, true) >=
2350 ((RREG32(MC_SEQ_MISC7) >> 16) & 0xf))
2351 dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;
2352 else
2353 dll_state_on = ((RREG32(MC_SEQ_MISC6) >> 1) & 0x1) ? true : false;
2354 } else {
2355 dll_state_on = false;
2356 if (pl->mclk > ni_pi->mclk_rtt_mode_threshold)
2357 level->mcFlags |= NISLANDS_SMC_MC_RTT_ENABLE;
2358 }
2359
2360 ret = ni_populate_mclk_value(rdev, pl->sclk, pl->mclk,
2361 &level->mclk,
2362 (level->strobeMode & NISLANDS_SMC_STROBE_ENABLE) != 0,
2363 dll_state_on);
2364 } else
2365 ret = ni_populate_mclk_value(rdev, pl->sclk, pl->mclk, &level->mclk, 1, 1);
2366
2367 if (ret)
2368 return ret;
2369
2370 ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
2371 pl->vddc, &level->vddc);
2372 if (ret)
2373 return ret;
2374
2375 ret = ni_get_std_voltage_value(rdev, &level->vddc, &std_vddc);
2376 if (ret)
2377 return ret;
2378
2379 ni_populate_std_voltage_value(rdev, std_vddc,
2380 level->vddc.index, &level->std_vddc);
2381
2382 if (eg_pi->vddci_control) {
2383 ret = ni_populate_voltage_value(rdev, &eg_pi->vddci_voltage_table,
2384 pl->vddci, &level->vddci);
2385 if (ret)
2386 return ret;
2387 }
2388
2389 ni_populate_mvdd_value(rdev, pl->mclk, &level->mvdd);
2390
2391 return ret;
2392 }
2393
ni_populate_smc_t(struct radeon_device * rdev,struct radeon_ps * radeon_state,NISLANDS_SMC_SWSTATE * smc_state)2394 static int ni_populate_smc_t(struct radeon_device *rdev,
2395 struct radeon_ps *radeon_state,
2396 NISLANDS_SMC_SWSTATE *smc_state)
2397 {
2398 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2399 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2400 struct ni_ps *state = ni_get_ps(radeon_state);
2401 u32 a_t;
2402 u32 t_l, t_h;
2403 u32 high_bsp;
2404 int i, ret;
2405
2406 if (state->performance_level_count >= 9)
2407 return -EINVAL;
2408
2409 if (state->performance_level_count < 2) {
2410 a_t = CG_R(0xffff) | CG_L(0);
2411 smc_state->levels[0].aT = cpu_to_be32(a_t);
2412 return 0;
2413 }
2414
2415 smc_state->levels[0].aT = cpu_to_be32(0);
2416
2417 for (i = 0; i <= state->performance_level_count - 2; i++) {
2418 if (eg_pi->uvd_enabled)
2419 ret = r600_calculate_at(
2420 1000 * (i * (eg_pi->smu_uvd_hs ? 2 : 8) + 2),
2421 100 * R600_AH_DFLT,
2422 state->performance_levels[i + 1].sclk,
2423 state->performance_levels[i].sclk,
2424 &t_l,
2425 &t_h);
2426 else
2427 ret = r600_calculate_at(
2428 1000 * (i + 1),
2429 100 * R600_AH_DFLT,
2430 state->performance_levels[i + 1].sclk,
2431 state->performance_levels[i].sclk,
2432 &t_l,
2433 &t_h);
2434
2435 if (ret) {
2436 t_h = (i + 1) * 1000 - 50 * R600_AH_DFLT;
2437 t_l = (i + 1) * 1000 + 50 * R600_AH_DFLT;
2438 }
2439
2440 a_t = be32_to_cpu(smc_state->levels[i].aT) & ~CG_R_MASK;
2441 a_t |= CG_R(t_l * pi->bsp / 20000);
2442 smc_state->levels[i].aT = cpu_to_be32(a_t);
2443
2444 high_bsp = (i == state->performance_level_count - 2) ?
2445 pi->pbsp : pi->bsp;
2446
2447 a_t = CG_R(0xffff) | CG_L(t_h * high_bsp / 20000);
2448 smc_state->levels[i + 1].aT = cpu_to_be32(a_t);
2449 }
2450
2451 return 0;
2452 }
2453
ni_populate_power_containment_values(struct radeon_device * rdev,struct radeon_ps * radeon_state,NISLANDS_SMC_SWSTATE * smc_state)2454 static int ni_populate_power_containment_values(struct radeon_device *rdev,
2455 struct radeon_ps *radeon_state,
2456 NISLANDS_SMC_SWSTATE *smc_state)
2457 {
2458 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2459 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2460 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2461 struct ni_ps *state = ni_get_ps(radeon_state);
2462 u32 prev_sclk;
2463 u32 max_sclk;
2464 u32 min_sclk;
2465 int i, ret;
2466 u32 tdp_limit;
2467 u32 near_tdp_limit;
2468 u32 power_boost_limit;
2469 u8 max_ps_percent;
2470
2471 if (ni_pi->enable_power_containment == false)
2472 return 0;
2473
2474 if (state->performance_level_count == 0)
2475 return -EINVAL;
2476
2477 if (smc_state->levelCount != state->performance_level_count)
2478 return -EINVAL;
2479
2480 ret = ni_calculate_adjusted_tdp_limits(rdev,
2481 false, /* ??? */
2482 rdev->pm.dpm.tdp_adjustment,
2483 &tdp_limit,
2484 &near_tdp_limit);
2485 if (ret)
2486 return ret;
2487
2488 power_boost_limit = ni_calculate_power_boost_limit(rdev, radeon_state, near_tdp_limit);
2489
2490 ret = rv770_write_smc_sram_dword(rdev,
2491 pi->state_table_start +
2492 offsetof(NISLANDS_SMC_STATETABLE, dpm2Params) +
2493 offsetof(PP_NIslands_DPM2Parameters, PowerBoostLimit),
2494 ni_scale_power_for_smc(power_boost_limit, ni_get_smc_power_scaling_factor(rdev)),
2495 pi->sram_end);
2496 if (ret)
2497 power_boost_limit = 0;
2498
2499 smc_state->levels[0].dpm2.MaxPS = 0;
2500 smc_state->levels[0].dpm2.NearTDPDec = 0;
2501 smc_state->levels[0].dpm2.AboveSafeInc = 0;
2502 smc_state->levels[0].dpm2.BelowSafeInc = 0;
2503 smc_state->levels[0].stateFlags |= power_boost_limit ? PPSMC_STATEFLAG_POWERBOOST : 0;
2504
2505 for (i = 1; i < state->performance_level_count; i++) {
2506 prev_sclk = state->performance_levels[i-1].sclk;
2507 max_sclk = state->performance_levels[i].sclk;
2508 max_ps_percent = (i != (state->performance_level_count - 1)) ?
2509 NISLANDS_DPM2_MAXPS_PERCENT_M : NISLANDS_DPM2_MAXPS_PERCENT_H;
2510
2511 if (max_sclk < prev_sclk)
2512 return -EINVAL;
2513
2514 if ((max_ps_percent == 0) || (prev_sclk == max_sclk) || eg_pi->uvd_enabled)
2515 min_sclk = max_sclk;
2516 else if (1 == i)
2517 min_sclk = prev_sclk;
2518 else
2519 min_sclk = (prev_sclk * (u32)max_ps_percent) / 100;
2520
2521 if (min_sclk < state->performance_levels[0].sclk)
2522 min_sclk = state->performance_levels[0].sclk;
2523
2524 if (min_sclk == 0)
2525 return -EINVAL;
2526
2527 smc_state->levels[i].dpm2.MaxPS =
2528 (u8)((NISLANDS_DPM2_MAX_PULSE_SKIP * (max_sclk - min_sclk)) / max_sclk);
2529 smc_state->levels[i].dpm2.NearTDPDec = NISLANDS_DPM2_NEAR_TDP_DEC;
2530 smc_state->levels[i].dpm2.AboveSafeInc = NISLANDS_DPM2_ABOVE_SAFE_INC;
2531 smc_state->levels[i].dpm2.BelowSafeInc = NISLANDS_DPM2_BELOW_SAFE_INC;
2532 smc_state->levels[i].stateFlags |=
2533 ((i != (state->performance_level_count - 1)) && power_boost_limit) ?
2534 PPSMC_STATEFLAG_POWERBOOST : 0;
2535 }
2536
2537 return 0;
2538 }
2539
ni_populate_sq_ramping_values(struct radeon_device * rdev,struct radeon_ps * radeon_state,NISLANDS_SMC_SWSTATE * smc_state)2540 static int ni_populate_sq_ramping_values(struct radeon_device *rdev,
2541 struct radeon_ps *radeon_state,
2542 NISLANDS_SMC_SWSTATE *smc_state)
2543 {
2544 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2545 struct ni_ps *state = ni_get_ps(radeon_state);
2546 u32 sq_power_throttle;
2547 u32 sq_power_throttle2;
2548 bool enable_sq_ramping = ni_pi->enable_sq_ramping;
2549 int i;
2550
2551 if (state->performance_level_count == 0)
2552 return -EINVAL;
2553
2554 if (smc_state->levelCount != state->performance_level_count)
2555 return -EINVAL;
2556
2557 if (rdev->pm.dpm.sq_ramping_threshold == 0)
2558 return -EINVAL;
2559
2560 if (NISLANDS_DPM2_SQ_RAMP_MAX_POWER > (MAX_POWER_MASK >> MAX_POWER_SHIFT))
2561 enable_sq_ramping = false;
2562
2563 if (NISLANDS_DPM2_SQ_RAMP_MIN_POWER > (MIN_POWER_MASK >> MIN_POWER_SHIFT))
2564 enable_sq_ramping = false;
2565
2566 if (NISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA > (MAX_POWER_DELTA_MASK >> MAX_POWER_DELTA_SHIFT))
2567 enable_sq_ramping = false;
2568
2569 if (NISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT))
2570 enable_sq_ramping = false;
2571
2572 if (NISLANDS_DPM2_SQ_RAMP_LTI_RATIO > (LTI_RATIO_MASK >> LTI_RATIO_SHIFT))
2573 enable_sq_ramping = false;
2574
2575 for (i = 0; i < state->performance_level_count; i++) {
2576 sq_power_throttle = 0;
2577 sq_power_throttle2 = 0;
2578
2579 if ((state->performance_levels[i].sclk >= rdev->pm.dpm.sq_ramping_threshold) &&
2580 enable_sq_ramping) {
2581 sq_power_throttle |= MAX_POWER(NISLANDS_DPM2_SQ_RAMP_MAX_POWER);
2582 sq_power_throttle |= MIN_POWER(NISLANDS_DPM2_SQ_RAMP_MIN_POWER);
2583 sq_power_throttle2 |= MAX_POWER_DELTA(NISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA);
2584 sq_power_throttle2 |= STI_SIZE(NISLANDS_DPM2_SQ_RAMP_STI_SIZE);
2585 sq_power_throttle2 |= LTI_RATIO(NISLANDS_DPM2_SQ_RAMP_LTI_RATIO);
2586 } else {
2587 sq_power_throttle |= MAX_POWER_MASK | MIN_POWER_MASK;
2588 sq_power_throttle2 |= MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
2589 }
2590
2591 smc_state->levels[i].SQPowerThrottle = cpu_to_be32(sq_power_throttle);
2592 smc_state->levels[i].SQPowerThrottle_2 = cpu_to_be32(sq_power_throttle2);
2593 }
2594
2595 return 0;
2596 }
2597
ni_enable_power_containment(struct radeon_device * rdev,struct radeon_ps * radeon_new_state,bool enable)2598 static int ni_enable_power_containment(struct radeon_device *rdev,
2599 struct radeon_ps *radeon_new_state,
2600 bool enable)
2601 {
2602 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2603 PPSMC_Result smc_result;
2604 int ret = 0;
2605
2606 if (ni_pi->enable_power_containment) {
2607 if (enable) {
2608 if (!r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
2609 smc_result = rv770_send_msg_to_smc(rdev, PPSMC_TDPClampingActive);
2610 if (smc_result != PPSMC_Result_OK) {
2611 ret = -EINVAL;
2612 ni_pi->pc_enabled = false;
2613 } else {
2614 ni_pi->pc_enabled = true;
2615 }
2616 }
2617 } else {
2618 smc_result = rv770_send_msg_to_smc(rdev, PPSMC_TDPClampingInactive);
2619 if (smc_result != PPSMC_Result_OK)
2620 ret = -EINVAL;
2621 ni_pi->pc_enabled = false;
2622 }
2623 }
2624
2625 return ret;
2626 }
2627
ni_convert_power_state_to_smc(struct radeon_device * rdev,struct radeon_ps * radeon_state,NISLANDS_SMC_SWSTATE * smc_state)2628 static int ni_convert_power_state_to_smc(struct radeon_device *rdev,
2629 struct radeon_ps *radeon_state,
2630 NISLANDS_SMC_SWSTATE *smc_state)
2631 {
2632 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2633 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2634 struct ni_ps *state = ni_get_ps(radeon_state);
2635 int i, ret;
2636 u32 threshold = state->performance_levels[state->performance_level_count - 1].sclk * 100 / 100;
2637
2638 if (!(radeon_state->caps & ATOM_PPLIB_DISALLOW_ON_DC))
2639 smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;
2640
2641 smc_state->levelCount = 0;
2642
2643 if (state->performance_level_count > NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE)
2644 return -EINVAL;
2645
2646 for (i = 0; i < state->performance_level_count; i++) {
2647 ret = ni_convert_power_level_to_smc(rdev, &state->performance_levels[i],
2648 &smc_state->levels[i]);
2649 smc_state->levels[i].arbRefreshState =
2650 (u8)(NISLANDS_DRIVER_STATE_ARB_INDEX + i);
2651
2652 if (ret)
2653 return ret;
2654
2655 if (ni_pi->enable_power_containment)
2656 smc_state->levels[i].displayWatermark =
2657 (state->performance_levels[i].sclk < threshold) ?
2658 PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
2659 else
2660 smc_state->levels[i].displayWatermark = (i < 2) ?
2661 PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
2662
2663 if (eg_pi->dynamic_ac_timing)
2664 smc_state->levels[i].ACIndex = NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i;
2665 else
2666 smc_state->levels[i].ACIndex = 0;
2667
2668 smc_state->levelCount++;
2669 }
2670
2671 rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_watermark_threshold,
2672 cpu_to_be32(threshold / 512));
2673
2674 ni_populate_smc_sp(rdev, radeon_state, smc_state);
2675
2676 ret = ni_populate_power_containment_values(rdev, radeon_state, smc_state);
2677 if (ret)
2678 ni_pi->enable_power_containment = false;
2679
2680 ret = ni_populate_sq_ramping_values(rdev, radeon_state, smc_state);
2681 if (ret)
2682 ni_pi->enable_sq_ramping = false;
2683
2684 return ni_populate_smc_t(rdev, radeon_state, smc_state);
2685 }
2686
ni_upload_sw_state(struct radeon_device * rdev,struct radeon_ps * radeon_new_state)2687 static int ni_upload_sw_state(struct radeon_device *rdev,
2688 struct radeon_ps *radeon_new_state)
2689 {
2690 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2691 u16 address = pi->state_table_start +
2692 offsetof(NISLANDS_SMC_STATETABLE, driverState);
2693 u16 state_size = sizeof(NISLANDS_SMC_SWSTATE) +
2694 ((NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1) * sizeof(NISLANDS_SMC_HW_PERFORMANCE_LEVEL));
2695 int ret;
2696 NISLANDS_SMC_SWSTATE *smc_state = kzalloc(state_size, GFP_KERNEL);
2697
2698 if (smc_state == NULL)
2699 return -ENOMEM;
2700
2701 ret = ni_convert_power_state_to_smc(rdev, radeon_new_state, smc_state);
2702 if (ret)
2703 goto done;
2704
2705 ret = rv770_copy_bytes_to_smc(rdev, address, (u8 *)smc_state, state_size, pi->sram_end);
2706
2707 done:
2708 kfree(smc_state);
2709
2710 return ret;
2711 }
2712
ni_set_mc_special_registers(struct radeon_device * rdev,struct ni_mc_reg_table * table)2713 static int ni_set_mc_special_registers(struct radeon_device *rdev,
2714 struct ni_mc_reg_table *table)
2715 {
2716 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2717 u8 i, j, k;
2718 u32 temp_reg;
2719
2720 for (i = 0, j = table->last; i < table->last; i++) {
2721 switch (table->mc_reg_address[i].s1) {
2722 case MC_SEQ_MISC1 >> 2:
2723 if (j >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
2724 return -EINVAL;
2725 temp_reg = RREG32(MC_PMG_CMD_EMRS);
2726 table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2;
2727 table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
2728 for (k = 0; k < table->num_entries; k++)
2729 table->mc_reg_table_entry[k].mc_data[j] =
2730 ((temp_reg & 0xffff0000)) |
2731 ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
2732 j++;
2733 if (j >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
2734 return -EINVAL;
2735
2736 temp_reg = RREG32(MC_PMG_CMD_MRS);
2737 table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2;
2738 table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
2739 for(k = 0; k < table->num_entries; k++) {
2740 table->mc_reg_table_entry[k].mc_data[j] =
2741 (temp_reg & 0xffff0000) |
2742 (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
2743 if (!pi->mem_gddr5)
2744 table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
2745 }
2746 j++;
2747 if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
2748 return -EINVAL;
2749 break;
2750 case MC_SEQ_RESERVE_M >> 2:
2751 temp_reg = RREG32(MC_PMG_CMD_MRS1);
2752 table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
2753 table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
2754 for (k = 0; k < table->num_entries; k++)
2755 table->mc_reg_table_entry[k].mc_data[j] =
2756 (temp_reg & 0xffff0000) |
2757 (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
2758 j++;
2759 if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
2760 return -EINVAL;
2761 break;
2762 default:
2763 break;
2764 }
2765 }
2766
2767 table->last = j;
2768
2769 return 0;
2770 }
2771
ni_check_s0_mc_reg_index(u16 in_reg,u16 * out_reg)2772 static bool ni_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
2773 {
2774 bool result = true;
2775
2776 switch (in_reg) {
2777 case MC_SEQ_RAS_TIMING >> 2:
2778 *out_reg = MC_SEQ_RAS_TIMING_LP >> 2;
2779 break;
2780 case MC_SEQ_CAS_TIMING >> 2:
2781 *out_reg = MC_SEQ_CAS_TIMING_LP >> 2;
2782 break;
2783 case MC_SEQ_MISC_TIMING >> 2:
2784 *out_reg = MC_SEQ_MISC_TIMING_LP >> 2;
2785 break;
2786 case MC_SEQ_MISC_TIMING2 >> 2:
2787 *out_reg = MC_SEQ_MISC_TIMING2_LP >> 2;
2788 break;
2789 case MC_SEQ_RD_CTL_D0 >> 2:
2790 *out_reg = MC_SEQ_RD_CTL_D0_LP >> 2;
2791 break;
2792 case MC_SEQ_RD_CTL_D1 >> 2:
2793 *out_reg = MC_SEQ_RD_CTL_D1_LP >> 2;
2794 break;
2795 case MC_SEQ_WR_CTL_D0 >> 2:
2796 *out_reg = MC_SEQ_WR_CTL_D0_LP >> 2;
2797 break;
2798 case MC_SEQ_WR_CTL_D1 >> 2:
2799 *out_reg = MC_SEQ_WR_CTL_D1_LP >> 2;
2800 break;
2801 case MC_PMG_CMD_EMRS >> 2:
2802 *out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
2803 break;
2804 case MC_PMG_CMD_MRS >> 2:
2805 *out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2;
2806 break;
2807 case MC_PMG_CMD_MRS1 >> 2:
2808 *out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
2809 break;
2810 case MC_SEQ_PMG_TIMING >> 2:
2811 *out_reg = MC_SEQ_PMG_TIMING_LP >> 2;
2812 break;
2813 case MC_PMG_CMD_MRS2 >> 2:
2814 *out_reg = MC_SEQ_PMG_CMD_MRS2_LP >> 2;
2815 break;
2816 default:
2817 result = false;
2818 break;
2819 }
2820
2821 return result;
2822 }
2823
ni_set_valid_flag(struct ni_mc_reg_table * table)2824 static void ni_set_valid_flag(struct ni_mc_reg_table *table)
2825 {
2826 u8 i, j;
2827
2828 for (i = 0; i < table->last; i++) {
2829 for (j = 1; j < table->num_entries; j++) {
2830 if (table->mc_reg_table_entry[j-1].mc_data[i] != table->mc_reg_table_entry[j].mc_data[i]) {
2831 table->valid_flag |= 1 << i;
2832 break;
2833 }
2834 }
2835 }
2836 }
2837
ni_set_s0_mc_reg_index(struct ni_mc_reg_table * table)2838 static void ni_set_s0_mc_reg_index(struct ni_mc_reg_table *table)
2839 {
2840 u32 i;
2841 u16 address;
2842
2843 for (i = 0; i < table->last; i++)
2844 table->mc_reg_address[i].s0 =
2845 ni_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
2846 address : table->mc_reg_address[i].s1;
2847 }
2848
ni_copy_vbios_mc_reg_table(struct atom_mc_reg_table * table,struct ni_mc_reg_table * ni_table)2849 static int ni_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
2850 struct ni_mc_reg_table *ni_table)
2851 {
2852 u8 i, j;
2853
2854 if (table->last > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
2855 return -EINVAL;
2856 if (table->num_entries > MAX_AC_TIMING_ENTRIES)
2857 return -EINVAL;
2858
2859 for (i = 0; i < table->last; i++)
2860 ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
2861 ni_table->last = table->last;
2862
2863 for (i = 0; i < table->num_entries; i++) {
2864 ni_table->mc_reg_table_entry[i].mclk_max =
2865 table->mc_reg_table_entry[i].mclk_max;
2866 for (j = 0; j < table->last; j++)
2867 ni_table->mc_reg_table_entry[i].mc_data[j] =
2868 table->mc_reg_table_entry[i].mc_data[j];
2869 }
2870 ni_table->num_entries = table->num_entries;
2871
2872 return 0;
2873 }
2874
ni_initialize_mc_reg_table(struct radeon_device * rdev)2875 static int ni_initialize_mc_reg_table(struct radeon_device *rdev)
2876 {
2877 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2878 int ret;
2879 struct atom_mc_reg_table *table;
2880 struct ni_mc_reg_table *ni_table = &ni_pi->mc_reg_table;
2881 u8 module_index = rv770_get_memory_module_index(rdev);
2882
2883 table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
2884 if (!table)
2885 return -ENOMEM;
2886
2887 WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
2888 WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
2889 WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
2890 WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
2891 WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
2892 WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
2893 WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
2894 WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
2895 WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
2896 WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
2897 WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
2898 WREG32(MC_SEQ_PMG_TIMING_LP, RREG32(MC_SEQ_PMG_TIMING));
2899 WREG32(MC_SEQ_PMG_CMD_MRS2_LP, RREG32(MC_PMG_CMD_MRS2));
2900
2901 ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
2902
2903 if (ret)
2904 goto init_mc_done;
2905
2906 ret = ni_copy_vbios_mc_reg_table(table, ni_table);
2907
2908 if (ret)
2909 goto init_mc_done;
2910
2911 ni_set_s0_mc_reg_index(ni_table);
2912
2913 ret = ni_set_mc_special_registers(rdev, ni_table);
2914
2915 if (ret)
2916 goto init_mc_done;
2917
2918 ni_set_valid_flag(ni_table);
2919
2920 init_mc_done:
2921 kfree(table);
2922
2923 return ret;
2924 }
2925
ni_populate_mc_reg_addresses(struct radeon_device * rdev,SMC_NIslands_MCRegisters * mc_reg_table)2926 static void ni_populate_mc_reg_addresses(struct radeon_device *rdev,
2927 SMC_NIslands_MCRegisters *mc_reg_table)
2928 {
2929 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2930 u32 i, j;
2931
2932 for (i = 0, j = 0; j < ni_pi->mc_reg_table.last; j++) {
2933 if (ni_pi->mc_reg_table.valid_flag & (1 << j)) {
2934 if (i >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
2935 break;
2936 mc_reg_table->address[i].s0 =
2937 cpu_to_be16(ni_pi->mc_reg_table.mc_reg_address[j].s0);
2938 mc_reg_table->address[i].s1 =
2939 cpu_to_be16(ni_pi->mc_reg_table.mc_reg_address[j].s1);
2940 i++;
2941 }
2942 }
2943 mc_reg_table->last = (u8)i;
2944 }
2945
2946
ni_convert_mc_registers(struct ni_mc_reg_entry * entry,SMC_NIslands_MCRegisterSet * data,u32 num_entries,u32 valid_flag)2947 static void ni_convert_mc_registers(struct ni_mc_reg_entry *entry,
2948 SMC_NIslands_MCRegisterSet *data,
2949 u32 num_entries, u32 valid_flag)
2950 {
2951 u32 i, j;
2952
2953 for (i = 0, j = 0; j < num_entries; j++) {
2954 if (valid_flag & (1 << j)) {
2955 data->value[i] = cpu_to_be32(entry->mc_data[j]);
2956 i++;
2957 }
2958 }
2959 }
2960
ni_convert_mc_reg_table_entry_to_smc(struct radeon_device * rdev,struct rv7xx_pl * pl,SMC_NIslands_MCRegisterSet * mc_reg_table_data)2961 static void ni_convert_mc_reg_table_entry_to_smc(struct radeon_device *rdev,
2962 struct rv7xx_pl *pl,
2963 SMC_NIslands_MCRegisterSet *mc_reg_table_data)
2964 {
2965 struct ni_power_info *ni_pi = ni_get_pi(rdev);
2966 u32 i = 0;
2967
2968 for (i = 0; i < ni_pi->mc_reg_table.num_entries; i++) {
2969 if (pl->mclk <= ni_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max)
2970 break;
2971 }
2972
2973 if ((i == ni_pi->mc_reg_table.num_entries) && (i > 0))
2974 --i;
2975
2976 ni_convert_mc_registers(&ni_pi->mc_reg_table.mc_reg_table_entry[i],
2977 mc_reg_table_data,
2978 ni_pi->mc_reg_table.last,
2979 ni_pi->mc_reg_table.valid_flag);
2980 }
2981
ni_convert_mc_reg_table_to_smc(struct radeon_device * rdev,struct radeon_ps * radeon_state,SMC_NIslands_MCRegisters * mc_reg_table)2982 static void ni_convert_mc_reg_table_to_smc(struct radeon_device *rdev,
2983 struct radeon_ps *radeon_state,
2984 SMC_NIslands_MCRegisters *mc_reg_table)
2985 {
2986 struct ni_ps *state = ni_get_ps(radeon_state);
2987 int i;
2988
2989 for (i = 0; i < state->performance_level_count; i++) {
2990 ni_convert_mc_reg_table_entry_to_smc(rdev,
2991 &state->performance_levels[i],
2992 &mc_reg_table->data[NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i]);
2993 }
2994 }
2995
ni_populate_mc_reg_table(struct radeon_device * rdev,struct radeon_ps * radeon_boot_state)2996 static int ni_populate_mc_reg_table(struct radeon_device *rdev,
2997 struct radeon_ps *radeon_boot_state)
2998 {
2999 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
3000 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3001 struct ni_power_info *ni_pi = ni_get_pi(rdev);
3002 struct ni_ps *boot_state = ni_get_ps(radeon_boot_state);
3003 SMC_NIslands_MCRegisters *mc_reg_table = &ni_pi->smc_mc_reg_table;
3004
3005 memset(mc_reg_table, 0, sizeof(SMC_NIslands_MCRegisters));
3006
3007 rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_seq_index, 1);
3008
3009 ni_populate_mc_reg_addresses(rdev, mc_reg_table);
3010
3011 ni_convert_mc_reg_table_entry_to_smc(rdev, &boot_state->performance_levels[0],
3012 &mc_reg_table->data[0]);
3013
3014 ni_convert_mc_registers(&ni_pi->mc_reg_table.mc_reg_table_entry[0],
3015 &mc_reg_table->data[1],
3016 ni_pi->mc_reg_table.last,
3017 ni_pi->mc_reg_table.valid_flag);
3018
3019 ni_convert_mc_reg_table_to_smc(rdev, radeon_boot_state, mc_reg_table);
3020
3021 return rv770_copy_bytes_to_smc(rdev, eg_pi->mc_reg_table_start,
3022 (u8 *)mc_reg_table,
3023 sizeof(SMC_NIslands_MCRegisters),
3024 pi->sram_end);
3025 }
3026
ni_upload_mc_reg_table(struct radeon_device * rdev,struct radeon_ps * radeon_new_state)3027 static int ni_upload_mc_reg_table(struct radeon_device *rdev,
3028 struct radeon_ps *radeon_new_state)
3029 {
3030 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
3031 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3032 struct ni_power_info *ni_pi = ni_get_pi(rdev);
3033 struct ni_ps *ni_new_state = ni_get_ps(radeon_new_state);
3034 SMC_NIslands_MCRegisters *mc_reg_table = &ni_pi->smc_mc_reg_table;
3035 u16 address;
3036
3037 memset(mc_reg_table, 0, sizeof(SMC_NIslands_MCRegisters));
3038
3039 ni_convert_mc_reg_table_to_smc(rdev, radeon_new_state, mc_reg_table);
3040
3041 address = eg_pi->mc_reg_table_start +
3042 (u16)offsetof(SMC_NIslands_MCRegisters, data[NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT]);
3043
3044 return rv770_copy_bytes_to_smc(rdev, address,
3045 (u8 *)&mc_reg_table->data[NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT],
3046 sizeof(SMC_NIslands_MCRegisterSet) * ni_new_state->performance_level_count,
3047 pi->sram_end);
3048 }
3049
ni_init_driver_calculated_leakage_table(struct radeon_device * rdev,PP_NIslands_CACTABLES * cac_tables)3050 static int ni_init_driver_calculated_leakage_table(struct radeon_device *rdev,
3051 PP_NIslands_CACTABLES *cac_tables)
3052 {
3053 struct ni_power_info *ni_pi = ni_get_pi(rdev);
3054 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3055 u32 leakage = 0;
3056 unsigned int i, j, table_size;
3057 s32 t;
3058 u32 smc_leakage, max_leakage = 0;
3059 u32 scaling_factor;
3060
3061 table_size = eg_pi->vddc_voltage_table.count;
3062
3063 if (SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES < table_size)
3064 table_size = SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES;
3065
3066 scaling_factor = ni_get_smc_power_scaling_factor(rdev);
3067
3068 for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++) {
3069 for (j = 0; j < table_size; j++) {
3070 t = (1000 * ((i + 1) * 8));
3071
3072 if (t < ni_pi->cac_data.leakage_minimum_temperature)
3073 t = ni_pi->cac_data.leakage_minimum_temperature;
3074
3075 ni_calculate_leakage_for_v_and_t(rdev,
3076 &ni_pi->cac_data.leakage_coefficients,
3077 eg_pi->vddc_voltage_table.entries[j].value,
3078 t,
3079 ni_pi->cac_data.i_leakage,
3080 &leakage);
3081
3082 smc_leakage = ni_scale_power_for_smc(leakage, scaling_factor) / 1000;
3083 if (smc_leakage > max_leakage)
3084 max_leakage = smc_leakage;
3085
3086 cac_tables->cac_lkge_lut[i][j] = cpu_to_be32(smc_leakage);
3087 }
3088 }
3089
3090 for (j = table_size; j < SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
3091 for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++)
3092 cac_tables->cac_lkge_lut[i][j] = cpu_to_be32(max_leakage);
3093 }
3094 return 0;
3095 }
3096
ni_init_simplified_leakage_table(struct radeon_device * rdev,PP_NIslands_CACTABLES * cac_tables)3097 static int ni_init_simplified_leakage_table(struct radeon_device *rdev,
3098 PP_NIslands_CACTABLES *cac_tables)
3099 {
3100 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3101 struct radeon_cac_leakage_table *leakage_table =
3102 &rdev->pm.dpm.dyn_state.cac_leakage_table;
3103 u32 i, j, table_size;
3104 u32 smc_leakage, max_leakage = 0;
3105 u32 scaling_factor;
3106
3107 if (!leakage_table)
3108 return -EINVAL;
3109
3110 table_size = leakage_table->count;
3111
3112 if (eg_pi->vddc_voltage_table.count != table_size)
3113 table_size = (eg_pi->vddc_voltage_table.count < leakage_table->count) ?
3114 eg_pi->vddc_voltage_table.count : leakage_table->count;
3115
3116 if (SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES < table_size)
3117 table_size = SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES;
3118
3119 if (table_size == 0)
3120 return -EINVAL;
3121
3122 scaling_factor = ni_get_smc_power_scaling_factor(rdev);
3123
3124 for (j = 0; j < table_size; j++) {
3125 smc_leakage = leakage_table->entries[j].leakage;
3126
3127 if (smc_leakage > max_leakage)
3128 max_leakage = smc_leakage;
3129
3130 for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++)
3131 cac_tables->cac_lkge_lut[i][j] =
3132 cpu_to_be32(ni_scale_power_for_smc(smc_leakage, scaling_factor));
3133 }
3134
3135 for (j = table_size; j < SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
3136 for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++)
3137 cac_tables->cac_lkge_lut[i][j] =
3138 cpu_to_be32(ni_scale_power_for_smc(max_leakage, scaling_factor));
3139 }
3140 return 0;
3141 }
3142
ni_initialize_smc_cac_tables(struct radeon_device * rdev)3143 static int ni_initialize_smc_cac_tables(struct radeon_device *rdev)
3144 {
3145 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
3146 struct ni_power_info *ni_pi = ni_get_pi(rdev);
3147 PP_NIslands_CACTABLES *cac_tables = NULL;
3148 int i, ret;
3149 u32 reg;
3150
3151 if (ni_pi->enable_cac == false)
3152 return 0;
3153
3154 cac_tables = kzalloc(sizeof(PP_NIslands_CACTABLES), GFP_KERNEL);
3155 if (!cac_tables)
3156 return -ENOMEM;
3157
3158 reg = RREG32(CG_CAC_CTRL) & ~(TID_CNT_MASK | TID_UNIT_MASK);
3159 reg |= (TID_CNT(ni_pi->cac_weights->tid_cnt) |
3160 TID_UNIT(ni_pi->cac_weights->tid_unit));
3161 WREG32(CG_CAC_CTRL, reg);
3162
3163 for (i = 0; i < NISLANDS_DCCAC_MAX_LEVELS; i++)
3164 ni_pi->dc_cac_table[i] = ni_pi->cac_weights->dc_cac[i];
3165
3166 for (i = 0; i < SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES; i++)
3167 cac_tables->cac_bif_lut[i] = ni_pi->cac_weights->pcie_cac[i];
3168
3169 ni_pi->cac_data.i_leakage = rdev->pm.dpm.cac_leakage;
3170 ni_pi->cac_data.pwr_const = 0;
3171 ni_pi->cac_data.dc_cac_value = ni_pi->dc_cac_table[NISLANDS_DCCAC_LEVEL_0];
3172 ni_pi->cac_data.bif_cac_value = 0;
3173 ni_pi->cac_data.mc_wr_weight = ni_pi->cac_weights->mc_write_weight;
3174 ni_pi->cac_data.mc_rd_weight = ni_pi->cac_weights->mc_read_weight;
3175 ni_pi->cac_data.allow_ovrflw = 0;
3176 ni_pi->cac_data.l2num_win_tdp = ni_pi->lta_window_size;
3177 ni_pi->cac_data.num_win_tdp = 0;
3178 ni_pi->cac_data.lts_truncate_n = ni_pi->lts_truncate;
3179
3180 if (ni_pi->driver_calculate_cac_leakage)
3181 ret = ni_init_driver_calculated_leakage_table(rdev, cac_tables);
3182 else
3183 ret = ni_init_simplified_leakage_table(rdev, cac_tables);
3184
3185 if (ret)
3186 goto done_free;
3187
3188 cac_tables->pwr_const = cpu_to_be32(ni_pi->cac_data.pwr_const);
3189 cac_tables->dc_cacValue = cpu_to_be32(ni_pi->cac_data.dc_cac_value);
3190 cac_tables->bif_cacValue = cpu_to_be32(ni_pi->cac_data.bif_cac_value);
3191 cac_tables->AllowOvrflw = ni_pi->cac_data.allow_ovrflw;
3192 cac_tables->MCWrWeight = ni_pi->cac_data.mc_wr_weight;
3193 cac_tables->MCRdWeight = ni_pi->cac_data.mc_rd_weight;
3194 cac_tables->numWin_TDP = ni_pi->cac_data.num_win_tdp;
3195 cac_tables->l2numWin_TDP = ni_pi->cac_data.l2num_win_tdp;
3196 cac_tables->lts_truncate_n = ni_pi->cac_data.lts_truncate_n;
3197
3198 ret = rv770_copy_bytes_to_smc(rdev, ni_pi->cac_table_start, (u8 *)cac_tables,
3199 sizeof(PP_NIslands_CACTABLES), pi->sram_end);
3200
3201 done_free:
3202 if (ret) {
3203 ni_pi->enable_cac = false;
3204 ni_pi->enable_power_containment = false;
3205 }
3206
3207 kfree(cac_tables);
3208
3209 return 0;
3210 }
3211
ni_initialize_hardware_cac_manager(struct radeon_device * rdev)3212 static int ni_initialize_hardware_cac_manager(struct radeon_device *rdev)
3213 {
3214 struct ni_power_info *ni_pi = ni_get_pi(rdev);
3215 u32 reg;
3216
3217 if (!ni_pi->enable_cac ||
3218 !ni_pi->cac_configuration_required)
3219 return 0;
3220
3221 if (ni_pi->cac_weights == NULL)
3222 return -EINVAL;
3223
3224 reg = RREG32_CG(CG_CAC_REGION_1_WEIGHT_0) & ~(WEIGHT_TCP_SIG0_MASK |
3225 WEIGHT_TCP_SIG1_MASK |
3226 WEIGHT_TA_SIG_MASK);
3227 reg |= (WEIGHT_TCP_SIG0(ni_pi->cac_weights->weight_tcp_sig0) |
3228 WEIGHT_TCP_SIG1(ni_pi->cac_weights->weight_tcp_sig1) |
3229 WEIGHT_TA_SIG(ni_pi->cac_weights->weight_ta_sig));
3230 WREG32_CG(CG_CAC_REGION_1_WEIGHT_0, reg);
3231
3232 reg = RREG32_CG(CG_CAC_REGION_1_WEIGHT_1) & ~(WEIGHT_TCC_EN0_MASK |
3233 WEIGHT_TCC_EN1_MASK |
3234 WEIGHT_TCC_EN2_MASK);
3235 reg |= (WEIGHT_TCC_EN0(ni_pi->cac_weights->weight_tcc_en0) |
3236 WEIGHT_TCC_EN1(ni_pi->cac_weights->weight_tcc_en1) |
3237 WEIGHT_TCC_EN2(ni_pi->cac_weights->weight_tcc_en2));
3238 WREG32_CG(CG_CAC_REGION_1_WEIGHT_1, reg);
3239
3240 reg = RREG32_CG(CG_CAC_REGION_2_WEIGHT_0) & ~(WEIGHT_CB_EN0_MASK |
3241 WEIGHT_CB_EN1_MASK |
3242 WEIGHT_CB_EN2_MASK |
3243 WEIGHT_CB_EN3_MASK);
3244 reg |= (WEIGHT_CB_EN0(ni_pi->cac_weights->weight_cb_en0) |
3245 WEIGHT_CB_EN1(ni_pi->cac_weights->weight_cb_en1) |
3246 WEIGHT_CB_EN2(ni_pi->cac_weights->weight_cb_en2) |
3247 WEIGHT_CB_EN3(ni_pi->cac_weights->weight_cb_en3));
3248 WREG32_CG(CG_CAC_REGION_2_WEIGHT_0, reg);
3249
3250 reg = RREG32_CG(CG_CAC_REGION_2_WEIGHT_1) & ~(WEIGHT_DB_SIG0_MASK |
3251 WEIGHT_DB_SIG1_MASK |
3252 WEIGHT_DB_SIG2_MASK |
3253 WEIGHT_DB_SIG3_MASK);
3254 reg |= (WEIGHT_DB_SIG0(ni_pi->cac_weights->weight_db_sig0) |
3255 WEIGHT_DB_SIG1(ni_pi->cac_weights->weight_db_sig1) |
3256 WEIGHT_DB_SIG2(ni_pi->cac_weights->weight_db_sig2) |
3257 WEIGHT_DB_SIG3(ni_pi->cac_weights->weight_db_sig3));
3258 WREG32_CG(CG_CAC_REGION_2_WEIGHT_1, reg);
3259
3260 reg = RREG32_CG(CG_CAC_REGION_2_WEIGHT_2) & ~(WEIGHT_SXM_SIG0_MASK |
3261 WEIGHT_SXM_SIG1_MASK |
3262 WEIGHT_SXM_SIG2_MASK |
3263 WEIGHT_SXS_SIG0_MASK |
3264 WEIGHT_SXS_SIG1_MASK);
3265 reg |= (WEIGHT_SXM_SIG0(ni_pi->cac_weights->weight_sxm_sig0) |
3266 WEIGHT_SXM_SIG1(ni_pi->cac_weights->weight_sxm_sig1) |
3267 WEIGHT_SXM_SIG2(ni_pi->cac_weights->weight_sxm_sig2) |
3268 WEIGHT_SXS_SIG0(ni_pi->cac_weights->weight_sxs_sig0) |
3269 WEIGHT_SXS_SIG1(ni_pi->cac_weights->weight_sxs_sig1));
3270 WREG32_CG(CG_CAC_REGION_2_WEIGHT_2, reg);
3271
3272 reg = RREG32_CG(CG_CAC_REGION_3_WEIGHT_0) & ~(WEIGHT_XBR_0_MASK |
3273 WEIGHT_XBR_1_MASK |
3274 WEIGHT_XBR_2_MASK |
3275 WEIGHT_SPI_SIG0_MASK);
3276 reg |= (WEIGHT_XBR_0(ni_pi->cac_weights->weight_xbr_0) |
3277 WEIGHT_XBR_1(ni_pi->cac_weights->weight_xbr_1) |
3278 WEIGHT_XBR_2(ni_pi->cac_weights->weight_xbr_2) |
3279 WEIGHT_SPI_SIG0(ni_pi->cac_weights->weight_spi_sig0));
3280 WREG32_CG(CG_CAC_REGION_3_WEIGHT_0, reg);
3281
3282 reg = RREG32_CG(CG_CAC_REGION_3_WEIGHT_1) & ~(WEIGHT_SPI_SIG1_MASK |
3283 WEIGHT_SPI_SIG2_MASK |
3284 WEIGHT_SPI_SIG3_MASK |
3285 WEIGHT_SPI_SIG4_MASK |
3286 WEIGHT_SPI_SIG5_MASK);
3287 reg |= (WEIGHT_SPI_SIG1(ni_pi->cac_weights->weight_spi_sig1) |
3288 WEIGHT_SPI_SIG2(ni_pi->cac_weights->weight_spi_sig2) |
3289 WEIGHT_SPI_SIG3(ni_pi->cac_weights->weight_spi_sig3) |
3290 WEIGHT_SPI_SIG4(ni_pi->cac_weights->weight_spi_sig4) |
3291 WEIGHT_SPI_SIG5(ni_pi->cac_weights->weight_spi_sig5));
3292 WREG32_CG(CG_CAC_REGION_3_WEIGHT_1, reg);
3293
3294 reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_0) & ~(WEIGHT_LDS_SIG0_MASK |
3295 WEIGHT_LDS_SIG1_MASK |
3296 WEIGHT_SC_MASK);
3297 reg |= (WEIGHT_LDS_SIG0(ni_pi->cac_weights->weight_lds_sig0) |
3298 WEIGHT_LDS_SIG1(ni_pi->cac_weights->weight_lds_sig1) |
3299 WEIGHT_SC(ni_pi->cac_weights->weight_sc));
3300 WREG32_CG(CG_CAC_REGION_4_WEIGHT_0, reg);
3301
3302 reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_1) & ~(WEIGHT_BIF_MASK |
3303 WEIGHT_CP_MASK |
3304 WEIGHT_PA_SIG0_MASK |
3305 WEIGHT_PA_SIG1_MASK |
3306 WEIGHT_VGT_SIG0_MASK);
3307 reg |= (WEIGHT_BIF(ni_pi->cac_weights->weight_bif) |
3308 WEIGHT_CP(ni_pi->cac_weights->weight_cp) |
3309 WEIGHT_PA_SIG0(ni_pi->cac_weights->weight_pa_sig0) |
3310 WEIGHT_PA_SIG1(ni_pi->cac_weights->weight_pa_sig1) |
3311 WEIGHT_VGT_SIG0(ni_pi->cac_weights->weight_vgt_sig0));
3312 WREG32_CG(CG_CAC_REGION_4_WEIGHT_1, reg);
3313
3314 reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_2) & ~(WEIGHT_VGT_SIG1_MASK |
3315 WEIGHT_VGT_SIG2_MASK |
3316 WEIGHT_DC_SIG0_MASK |
3317 WEIGHT_DC_SIG1_MASK |
3318 WEIGHT_DC_SIG2_MASK);
3319 reg |= (WEIGHT_VGT_SIG1(ni_pi->cac_weights->weight_vgt_sig1) |
3320 WEIGHT_VGT_SIG2(ni_pi->cac_weights->weight_vgt_sig2) |
3321 WEIGHT_DC_SIG0(ni_pi->cac_weights->weight_dc_sig0) |
3322 WEIGHT_DC_SIG1(ni_pi->cac_weights->weight_dc_sig1) |
3323 WEIGHT_DC_SIG2(ni_pi->cac_weights->weight_dc_sig2));
3324 WREG32_CG(CG_CAC_REGION_4_WEIGHT_2, reg);
3325
3326 reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_3) & ~(WEIGHT_DC_SIG3_MASK |
3327 WEIGHT_UVD_SIG0_MASK |
3328 WEIGHT_UVD_SIG1_MASK |
3329 WEIGHT_SPARE0_MASK |
3330 WEIGHT_SPARE1_MASK);
3331 reg |= (WEIGHT_DC_SIG3(ni_pi->cac_weights->weight_dc_sig3) |
3332 WEIGHT_UVD_SIG0(ni_pi->cac_weights->weight_uvd_sig0) |
3333 WEIGHT_UVD_SIG1(ni_pi->cac_weights->weight_uvd_sig1) |
3334 WEIGHT_SPARE0(ni_pi->cac_weights->weight_spare0) |
3335 WEIGHT_SPARE1(ni_pi->cac_weights->weight_spare1));
3336 WREG32_CG(CG_CAC_REGION_4_WEIGHT_3, reg);
3337
3338 reg = RREG32_CG(CG_CAC_REGION_5_WEIGHT_0) & ~(WEIGHT_SQ_VSP_MASK |
3339 WEIGHT_SQ_VSP0_MASK);
3340 reg |= (WEIGHT_SQ_VSP(ni_pi->cac_weights->weight_sq_vsp) |
3341 WEIGHT_SQ_VSP0(ni_pi->cac_weights->weight_sq_vsp0));
3342 WREG32_CG(CG_CAC_REGION_5_WEIGHT_0, reg);
3343
3344 reg = RREG32_CG(CG_CAC_REGION_5_WEIGHT_1) & ~(WEIGHT_SQ_GPR_MASK);
3345 reg |= WEIGHT_SQ_GPR(ni_pi->cac_weights->weight_sq_gpr);
3346 WREG32_CG(CG_CAC_REGION_5_WEIGHT_1, reg);
3347
3348 reg = RREG32_CG(CG_CAC_REGION_4_OVERRIDE_4) & ~(OVR_MODE_SPARE_0_MASK |
3349 OVR_VAL_SPARE_0_MASK |
3350 OVR_MODE_SPARE_1_MASK |
3351 OVR_VAL_SPARE_1_MASK);
3352 reg |= (OVR_MODE_SPARE_0(ni_pi->cac_weights->ovr_mode_spare_0) |
3353 OVR_VAL_SPARE_0(ni_pi->cac_weights->ovr_val_spare_0) |
3354 OVR_MODE_SPARE_1(ni_pi->cac_weights->ovr_mode_spare_1) |
3355 OVR_VAL_SPARE_1(ni_pi->cac_weights->ovr_val_spare_1));
3356 WREG32_CG(CG_CAC_REGION_4_OVERRIDE_4, reg);
3357
3358 reg = RREG32(SQ_CAC_THRESHOLD) & ~(VSP_MASK |
3359 VSP0_MASK |
3360 GPR_MASK);
3361 reg |= (VSP(ni_pi->cac_weights->vsp) |
3362 VSP0(ni_pi->cac_weights->vsp0) |
3363 GPR(ni_pi->cac_weights->gpr));
3364 WREG32(SQ_CAC_THRESHOLD, reg);
3365
3366 reg = (MCDW_WR_ENABLE |
3367 MCDX_WR_ENABLE |
3368 MCDY_WR_ENABLE |
3369 MCDZ_WR_ENABLE |
3370 INDEX(0x09D4));
3371 WREG32(MC_CG_CONFIG, reg);
3372
3373 reg = (READ_WEIGHT(ni_pi->cac_weights->mc_read_weight) |
3374 WRITE_WEIGHT(ni_pi->cac_weights->mc_write_weight) |
3375 ALLOW_OVERFLOW);
3376 WREG32(MC_CG_DATAPORT, reg);
3377
3378 return 0;
3379 }
3380
ni_enable_smc_cac(struct radeon_device * rdev,struct radeon_ps * radeon_new_state,bool enable)3381 static int ni_enable_smc_cac(struct radeon_device *rdev,
3382 struct radeon_ps *radeon_new_state,
3383 bool enable)
3384 {
3385 struct ni_power_info *ni_pi = ni_get_pi(rdev);
3386 int ret = 0;
3387 PPSMC_Result smc_result;
3388
3389 if (ni_pi->enable_cac) {
3390 if (enable) {
3391 if (!r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
3392 smc_result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_CollectCAC_PowerCorreln);
3393
3394 if (ni_pi->support_cac_long_term_average) {
3395 smc_result = rv770_send_msg_to_smc(rdev, PPSMC_CACLongTermAvgEnable);
3396 if (PPSMC_Result_OK != smc_result)
3397 ni_pi->support_cac_long_term_average = false;
3398 }
3399
3400 smc_result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableCac);
3401 if (PPSMC_Result_OK != smc_result)
3402 ret = -EINVAL;
3403
3404 ni_pi->cac_enabled = (PPSMC_Result_OK == smc_result) ? true : false;
3405 }
3406 } else if (ni_pi->cac_enabled) {
3407 smc_result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_DisableCac);
3408
3409 ni_pi->cac_enabled = false;
3410
3411 if (ni_pi->support_cac_long_term_average) {
3412 smc_result = rv770_send_msg_to_smc(rdev, PPSMC_CACLongTermAvgDisable);
3413 if (PPSMC_Result_OK != smc_result)
3414 ni_pi->support_cac_long_term_average = false;
3415 }
3416 }
3417 }
3418
3419 return ret;
3420 }
3421
ni_pcie_performance_request(struct radeon_device * rdev,u8 perf_req,bool advertise)3422 static int ni_pcie_performance_request(struct radeon_device *rdev,
3423 u8 perf_req, bool advertise)
3424 {
3425 #if defined(CONFIG_ACPI)
3426 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3427
3428 if ((perf_req == PCIE_PERF_REQ_PECI_GEN1) ||
3429 (perf_req == PCIE_PERF_REQ_PECI_GEN2)) {
3430 if (eg_pi->pcie_performance_request_registered == false)
3431 radeon_acpi_pcie_notify_device_ready(rdev);
3432 eg_pi->pcie_performance_request_registered = true;
3433 return radeon_acpi_pcie_performance_request(rdev, perf_req, advertise);
3434 } else if ((perf_req == PCIE_PERF_REQ_REMOVE_REGISTRY) &&
3435 eg_pi->pcie_performance_request_registered) {
3436 eg_pi->pcie_performance_request_registered = false;
3437 return radeon_acpi_pcie_performance_request(rdev, perf_req, advertise);
3438 }
3439 #endif
3440 return 0;
3441 }
3442
ni_advertise_gen2_capability(struct radeon_device * rdev)3443 static int ni_advertise_gen2_capability(struct radeon_device *rdev)
3444 {
3445 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
3446 u32 tmp;
3447
3448 tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
3449
3450 if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
3451 (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
3452 pi->pcie_gen2 = true;
3453 else
3454 pi->pcie_gen2 = false;
3455
3456 if (!pi->pcie_gen2)
3457 ni_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, true);
3458
3459 return 0;
3460 }
3461
ni_enable_bif_dynamic_pcie_gen2(struct radeon_device * rdev,bool enable)3462 static void ni_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
3463 bool enable)
3464 {
3465 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
3466 u32 tmp, bif;
3467
3468 tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
3469
3470 if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
3471 (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
3472 if (enable) {
3473 if (!pi->boot_in_gen2) {
3474 bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
3475 bif |= CG_CLIENT_REQ(0xd);
3476 WREG32(CG_BIF_REQ_AND_RSP, bif);
3477 }
3478 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
3479 tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
3480 tmp |= LC_GEN2_EN_STRAP;
3481
3482 tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT;
3483 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
3484 udelay(10);
3485 tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
3486 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
3487 } else {
3488 if (!pi->boot_in_gen2) {
3489 bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
3490 bif |= CG_CLIENT_REQ(0xd);
3491 WREG32(CG_BIF_REQ_AND_RSP, bif);
3492
3493 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
3494 tmp &= ~LC_GEN2_EN_STRAP;
3495 }
3496 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
3497 }
3498 }
3499 }
3500
ni_enable_dynamic_pcie_gen2(struct radeon_device * rdev,bool enable)3501 static void ni_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
3502 bool enable)
3503 {
3504 ni_enable_bif_dynamic_pcie_gen2(rdev, enable);
3505
3506 if (enable)
3507 WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
3508 else
3509 WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
3510 }
3511
ni_set_uvd_clock_before_set_eng_clock(struct radeon_device * rdev,struct radeon_ps * new_ps,struct radeon_ps * old_ps)3512 void ni_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
3513 struct radeon_ps *new_ps,
3514 struct radeon_ps *old_ps)
3515 {
3516 struct ni_ps *new_state = ni_get_ps(new_ps);
3517 struct ni_ps *current_state = ni_get_ps(old_ps);
3518
3519 if ((new_ps->vclk == old_ps->vclk) &&
3520 (new_ps->dclk == old_ps->dclk))
3521 return;
3522
3523 if (new_state->performance_levels[new_state->performance_level_count - 1].sclk >=
3524 current_state->performance_levels[current_state->performance_level_count - 1].sclk)
3525 return;
3526
3527 radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
3528 }
3529
ni_set_uvd_clock_after_set_eng_clock(struct radeon_device * rdev,struct radeon_ps * new_ps,struct radeon_ps * old_ps)3530 void ni_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
3531 struct radeon_ps *new_ps,
3532 struct radeon_ps *old_ps)
3533 {
3534 struct ni_ps *new_state = ni_get_ps(new_ps);
3535 struct ni_ps *current_state = ni_get_ps(old_ps);
3536
3537 if ((new_ps->vclk == old_ps->vclk) &&
3538 (new_ps->dclk == old_ps->dclk))
3539 return;
3540
3541 if (new_state->performance_levels[new_state->performance_level_count - 1].sclk <
3542 current_state->performance_levels[current_state->performance_level_count - 1].sclk)
3543 return;
3544
3545 radeon_set_uvd_clocks(rdev, new_ps->vclk, new_ps->dclk);
3546 }
3547
ni_dpm_setup_asic(struct radeon_device * rdev)3548 void ni_dpm_setup_asic(struct radeon_device *rdev)
3549 {
3550 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3551 int r;
3552
3553 r = ni_mc_load_microcode(rdev);
3554 if (r)
3555 DRM_ERROR("Failed to load MC firmware!\n");
3556 ni_read_clock_registers(rdev);
3557 btc_read_arb_registers(rdev);
3558 rv770_get_memory_type(rdev);
3559 if (eg_pi->pcie_performance_request)
3560 ni_advertise_gen2_capability(rdev);
3561 rv770_get_pcie_gen2_status(rdev);
3562 rv770_enable_acpi_pm(rdev);
3563 }
3564
ni_update_current_ps(struct radeon_device * rdev,struct radeon_ps * rps)3565 void ni_update_current_ps(struct radeon_device *rdev,
3566 struct radeon_ps *rps)
3567 {
3568 struct ni_ps *new_ps = ni_get_ps(rps);
3569 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3570 struct ni_power_info *ni_pi = ni_get_pi(rdev);
3571
3572 eg_pi->current_rps = *rps;
3573 ni_pi->current_ps = *new_ps;
3574 eg_pi->current_rps.ps_priv = &ni_pi->current_ps;
3575 }
3576
ni_update_requested_ps(struct radeon_device * rdev,struct radeon_ps * rps)3577 void ni_update_requested_ps(struct radeon_device *rdev,
3578 struct radeon_ps *rps)
3579 {
3580 struct ni_ps *new_ps = ni_get_ps(rps);
3581 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3582 struct ni_power_info *ni_pi = ni_get_pi(rdev);
3583
3584 eg_pi->requested_rps = *rps;
3585 ni_pi->requested_ps = *new_ps;
3586 eg_pi->requested_rps.ps_priv = &ni_pi->requested_ps;
3587 }
3588
ni_dpm_enable(struct radeon_device * rdev)3589 int ni_dpm_enable(struct radeon_device *rdev)
3590 {
3591 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
3592 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3593 struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
3594 int ret;
3595
3596 if (pi->gfx_clock_gating)
3597 ni_cg_clockgating_default(rdev);
3598 if (btc_dpm_enabled(rdev))
3599 return -EINVAL;
3600 if (pi->mg_clock_gating)
3601 ni_mg_clockgating_default(rdev);
3602 if (eg_pi->ls_clock_gating)
3603 ni_ls_clockgating_default(rdev);
3604 if (pi->voltage_control) {
3605 rv770_enable_voltage_control(rdev, true);
3606 ret = cypress_construct_voltage_tables(rdev);
3607 if (ret) {
3608 DRM_ERROR("cypress_construct_voltage_tables failed\n");
3609 return ret;
3610 }
3611 }
3612 if (eg_pi->dynamic_ac_timing) {
3613 ret = ni_initialize_mc_reg_table(rdev);
3614 if (ret)
3615 eg_pi->dynamic_ac_timing = false;
3616 }
3617 if (pi->dynamic_ss)
3618 cypress_enable_spread_spectrum(rdev, true);
3619 if (pi->thermal_protection)
3620 rv770_enable_thermal_protection(rdev, true);
3621 rv770_setup_bsp(rdev);
3622 rv770_program_git(rdev);
3623 rv770_program_tp(rdev);
3624 rv770_program_tpp(rdev);
3625 rv770_program_sstp(rdev);
3626 cypress_enable_display_gap(rdev);
3627 rv770_program_vc(rdev);
3628 if (pi->dynamic_pcie_gen2)
3629 ni_enable_dynamic_pcie_gen2(rdev, true);
3630 ret = rv770_upload_firmware(rdev);
3631 if (ret) {
3632 DRM_ERROR("rv770_upload_firmware failed\n");
3633 return ret;
3634 }
3635 ret = ni_process_firmware_header(rdev);
3636 if (ret) {
3637 DRM_ERROR("ni_process_firmware_header failed\n");
3638 return ret;
3639 }
3640 ret = ni_initial_switch_from_arb_f0_to_f1(rdev);
3641 if (ret) {
3642 DRM_ERROR("ni_initial_switch_from_arb_f0_to_f1 failed\n");
3643 return ret;
3644 }
3645 ret = ni_init_smc_table(rdev);
3646 if (ret) {
3647 DRM_ERROR("ni_init_smc_table failed\n");
3648 return ret;
3649 }
3650 ret = ni_init_smc_spll_table(rdev);
3651 if (ret) {
3652 DRM_ERROR("ni_init_smc_spll_table failed\n");
3653 return ret;
3654 }
3655 ret = ni_init_arb_table_index(rdev);
3656 if (ret) {
3657 DRM_ERROR("ni_init_arb_table_index failed\n");
3658 return ret;
3659 }
3660 if (eg_pi->dynamic_ac_timing) {
3661 ret = ni_populate_mc_reg_table(rdev, boot_ps);
3662 if (ret) {
3663 DRM_ERROR("ni_populate_mc_reg_table failed\n");
3664 return ret;
3665 }
3666 }
3667 ret = ni_initialize_smc_cac_tables(rdev);
3668 if (ret) {
3669 DRM_ERROR("ni_initialize_smc_cac_tables failed\n");
3670 return ret;
3671 }
3672 ret = ni_initialize_hardware_cac_manager(rdev);
3673 if (ret) {
3674 DRM_ERROR("ni_initialize_hardware_cac_manager failed\n");
3675 return ret;
3676 }
3677 ret = ni_populate_smc_tdp_limits(rdev, boot_ps);
3678 if (ret) {
3679 DRM_ERROR("ni_populate_smc_tdp_limits failed\n");
3680 return ret;
3681 }
3682 ni_program_response_times(rdev);
3683 r7xx_start_smc(rdev);
3684 ret = cypress_notify_smc_display_change(rdev, false);
3685 if (ret) {
3686 DRM_ERROR("cypress_notify_smc_display_change failed\n");
3687 return ret;
3688 }
3689 cypress_enable_sclk_control(rdev, true);
3690 if (eg_pi->memory_transition)
3691 cypress_enable_mclk_control(rdev, true);
3692 cypress_start_dpm(rdev);
3693 if (pi->gfx_clock_gating)
3694 ni_gfx_clockgating_enable(rdev, true);
3695 if (pi->mg_clock_gating)
3696 ni_mg_clockgating_enable(rdev, true);
3697 if (eg_pi->ls_clock_gating)
3698 ni_ls_clockgating_enable(rdev, true);
3699
3700 rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
3701
3702 ni_update_current_ps(rdev, boot_ps);
3703
3704 return 0;
3705 }
3706
ni_dpm_disable(struct radeon_device * rdev)3707 void ni_dpm_disable(struct radeon_device *rdev)
3708 {
3709 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
3710 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3711 struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
3712
3713 if (!btc_dpm_enabled(rdev))
3714 return;
3715 rv770_clear_vc(rdev);
3716 if (pi->thermal_protection)
3717 rv770_enable_thermal_protection(rdev, false);
3718 ni_enable_power_containment(rdev, boot_ps, false);
3719 ni_enable_smc_cac(rdev, boot_ps, false);
3720 cypress_enable_spread_spectrum(rdev, false);
3721 rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, false);
3722 if (pi->dynamic_pcie_gen2)
3723 ni_enable_dynamic_pcie_gen2(rdev, false);
3724
3725 if (rdev->irq.installed &&
3726 r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
3727 rdev->irq.dpm_thermal = false;
3728 radeon_irq_set(rdev);
3729 }
3730
3731 if (pi->gfx_clock_gating)
3732 ni_gfx_clockgating_enable(rdev, false);
3733 if (pi->mg_clock_gating)
3734 ni_mg_clockgating_enable(rdev, false);
3735 if (eg_pi->ls_clock_gating)
3736 ni_ls_clockgating_enable(rdev, false);
3737 ni_stop_dpm(rdev);
3738 btc_reset_to_default(rdev);
3739 ni_stop_smc(rdev);
3740 ni_force_switch_to_arb_f0(rdev);
3741
3742 ni_update_current_ps(rdev, boot_ps);
3743 }
3744
ni_power_control_set_level(struct radeon_device * rdev)3745 static int ni_power_control_set_level(struct radeon_device *rdev)
3746 {
3747 struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
3748 int ret;
3749
3750 ret = ni_restrict_performance_levels_before_switch(rdev);
3751 if (ret)
3752 return ret;
3753 ret = rv770_halt_smc(rdev);
3754 if (ret)
3755 return ret;
3756 ret = ni_populate_smc_tdp_limits(rdev, new_ps);
3757 if (ret)
3758 return ret;
3759 ret = rv770_resume_smc(rdev);
3760 if (ret)
3761 return ret;
3762 ret = rv770_set_sw_state(rdev);
3763 if (ret)
3764 return ret;
3765
3766 return 0;
3767 }
3768
ni_dpm_pre_set_power_state(struct radeon_device * rdev)3769 int ni_dpm_pre_set_power_state(struct radeon_device *rdev)
3770 {
3771 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3772 struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
3773 struct radeon_ps *new_ps = &requested_ps;
3774
3775 ni_update_requested_ps(rdev, new_ps);
3776
3777 ni_apply_state_adjust_rules(rdev, &eg_pi->requested_rps);
3778
3779 return 0;
3780 }
3781
ni_dpm_set_power_state(struct radeon_device * rdev)3782 int ni_dpm_set_power_state(struct radeon_device *rdev)
3783 {
3784 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3785 struct radeon_ps *new_ps = &eg_pi->requested_rps;
3786 struct radeon_ps *old_ps = &eg_pi->current_rps;
3787 int ret;
3788
3789 ret = ni_restrict_performance_levels_before_switch(rdev);
3790 if (ret) {
3791 DRM_ERROR("ni_restrict_performance_levels_before_switch failed\n");
3792 return ret;
3793 }
3794 ni_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
3795 ret = ni_enable_power_containment(rdev, new_ps, false);
3796 if (ret) {
3797 DRM_ERROR("ni_enable_power_containment failed\n");
3798 return ret;
3799 }
3800 ret = ni_enable_smc_cac(rdev, new_ps, false);
3801 if (ret) {
3802 DRM_ERROR("ni_enable_smc_cac failed\n");
3803 return ret;
3804 }
3805 ret = rv770_halt_smc(rdev);
3806 if (ret) {
3807 DRM_ERROR("rv770_halt_smc failed\n");
3808 return ret;
3809 }
3810 if (eg_pi->smu_uvd_hs)
3811 btc_notify_uvd_to_smc(rdev, new_ps);
3812 ret = ni_upload_sw_state(rdev, new_ps);
3813 if (ret) {
3814 DRM_ERROR("ni_upload_sw_state failed\n");
3815 return ret;
3816 }
3817 if (eg_pi->dynamic_ac_timing) {
3818 ret = ni_upload_mc_reg_table(rdev, new_ps);
3819 if (ret) {
3820 DRM_ERROR("ni_upload_mc_reg_table failed\n");
3821 return ret;
3822 }
3823 }
3824 ret = ni_program_memory_timing_parameters(rdev, new_ps);
3825 if (ret) {
3826 DRM_ERROR("ni_program_memory_timing_parameters failed\n");
3827 return ret;
3828 }
3829 ret = rv770_resume_smc(rdev);
3830 if (ret) {
3831 DRM_ERROR("rv770_resume_smc failed\n");
3832 return ret;
3833 }
3834 ret = rv770_set_sw_state(rdev);
3835 if (ret) {
3836 DRM_ERROR("rv770_set_sw_state failed\n");
3837 return ret;
3838 }
3839 ni_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
3840 ret = ni_enable_smc_cac(rdev, new_ps, true);
3841 if (ret) {
3842 DRM_ERROR("ni_enable_smc_cac failed\n");
3843 return ret;
3844 }
3845 ret = ni_enable_power_containment(rdev, new_ps, true);
3846 if (ret) {
3847 DRM_ERROR("ni_enable_power_containment failed\n");
3848 return ret;
3849 }
3850
3851 /* update tdp */
3852 ret = ni_power_control_set_level(rdev);
3853 if (ret) {
3854 DRM_ERROR("ni_power_control_set_level failed\n");
3855 return ret;
3856 }
3857
3858 return 0;
3859 }
3860
ni_dpm_post_set_power_state(struct radeon_device * rdev)3861 void ni_dpm_post_set_power_state(struct radeon_device *rdev)
3862 {
3863 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3864 struct radeon_ps *new_ps = &eg_pi->requested_rps;
3865
3866 ni_update_current_ps(rdev, new_ps);
3867 }
3868
3869 #if 0
3870 void ni_dpm_reset_asic(struct radeon_device *rdev)
3871 {
3872 ni_restrict_performance_levels_before_switch(rdev);
3873 rv770_set_boot_state(rdev);
3874 }
3875 #endif
3876
3877 union power_info {
3878 struct _ATOM_POWERPLAY_INFO info;
3879 struct _ATOM_POWERPLAY_INFO_V2 info_2;
3880 struct _ATOM_POWERPLAY_INFO_V3 info_3;
3881 struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
3882 struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
3883 struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
3884 };
3885
3886 union pplib_clock_info {
3887 struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
3888 struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
3889 struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
3890 struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
3891 };
3892
3893 union pplib_power_state {
3894 struct _ATOM_PPLIB_STATE v1;
3895 struct _ATOM_PPLIB_STATE_V2 v2;
3896 };
3897
ni_parse_pplib_non_clock_info(struct radeon_device * rdev,struct radeon_ps * rps,struct _ATOM_PPLIB_NONCLOCK_INFO * non_clock_info,u8 table_rev)3898 static void ni_parse_pplib_non_clock_info(struct radeon_device *rdev,
3899 struct radeon_ps *rps,
3900 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
3901 u8 table_rev)
3902 {
3903 rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
3904 rps->class = le16_to_cpu(non_clock_info->usClassification);
3905 rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
3906
3907 if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
3908 rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
3909 rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
3910 } else if (r600_is_uvd_state(rps->class, rps->class2)) {
3911 rps->vclk = RV770_DEFAULT_VCLK_FREQ;
3912 rps->dclk = RV770_DEFAULT_DCLK_FREQ;
3913 } else {
3914 rps->vclk = 0;
3915 rps->dclk = 0;
3916 }
3917
3918 if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
3919 rdev->pm.dpm.boot_ps = rps;
3920 if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
3921 rdev->pm.dpm.uvd_ps = rps;
3922 }
3923
ni_parse_pplib_clock_info(struct radeon_device * rdev,struct radeon_ps * rps,int index,union pplib_clock_info * clock_info)3924 static void ni_parse_pplib_clock_info(struct radeon_device *rdev,
3925 struct radeon_ps *rps, int index,
3926 union pplib_clock_info *clock_info)
3927 {
3928 struct rv7xx_power_info *pi = rv770_get_pi(rdev);
3929 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
3930 struct ni_ps *ps = ni_get_ps(rps);
3931 struct rv7xx_pl *pl = &ps->performance_levels[index];
3932
3933 ps->performance_level_count = index + 1;
3934
3935 pl->sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
3936 pl->sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
3937 pl->mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
3938 pl->mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
3939
3940 pl->vddc = le16_to_cpu(clock_info->evergreen.usVDDC);
3941 pl->vddci = le16_to_cpu(clock_info->evergreen.usVDDCI);
3942 pl->flags = le32_to_cpu(clock_info->evergreen.ulFlags);
3943
3944 /* patch up vddc if necessary */
3945 if (pl->vddc == 0xff01) {
3946 if (pi->max_vddc)
3947 pl->vddc = pi->max_vddc;
3948 }
3949
3950 if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
3951 pi->acpi_vddc = pl->vddc;
3952 eg_pi->acpi_vddci = pl->vddci;
3953 if (ps->performance_levels[0].flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
3954 pi->acpi_pcie_gen2 = true;
3955 else
3956 pi->acpi_pcie_gen2 = false;
3957 }
3958
3959 if (rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) {
3960 eg_pi->ulv.supported = true;
3961 eg_pi->ulv.pl = pl;
3962 }
3963
3964 if (pi->min_vddc_in_table > pl->vddc)
3965 pi->min_vddc_in_table = pl->vddc;
3966
3967 if (pi->max_vddc_in_table < pl->vddc)
3968 pi->max_vddc_in_table = pl->vddc;
3969
3970 /* patch up boot state */
3971 if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
3972 u16 vddc, vddci, mvdd;
3973 radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);
3974 pl->mclk = rdev->clock.default_mclk;
3975 pl->sclk = rdev->clock.default_sclk;
3976 pl->vddc = vddc;
3977 pl->vddci = vddci;
3978 }
3979
3980 if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
3981 ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
3982 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk;
3983 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk;
3984 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc;
3985 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci;
3986 }
3987 }
3988
ni_parse_power_table(struct radeon_device * rdev)3989 static int ni_parse_power_table(struct radeon_device *rdev)
3990 {
3991 struct radeon_mode_info *mode_info = &rdev->mode_info;
3992 struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
3993 union pplib_power_state *power_state;
3994 int i, j;
3995 union pplib_clock_info *clock_info;
3996 union power_info *power_info;
3997 int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
3998 u16 data_offset;
3999 u8 frev, crev;
4000 struct ni_ps *ps;
4001
4002 if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
4003 &frev, &crev, &data_offset))
4004 return -EINVAL;
4005 power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
4006
4007 rdev->pm.dpm.ps = kcalloc(power_info->pplib.ucNumStates,
4008 sizeof(struct radeon_ps),
4009 GFP_KERNEL);
4010 if (!rdev->pm.dpm.ps)
4011 return -ENOMEM;
4012
4013 for (i = 0; i < power_info->pplib.ucNumStates; i++) {
4014 power_state = (union pplib_power_state *)
4015 (mode_info->atom_context->bios + data_offset +
4016 le16_to_cpu(power_info->pplib.usStateArrayOffset) +
4017 i * power_info->pplib.ucStateEntrySize);
4018 non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
4019 (mode_info->atom_context->bios + data_offset +
4020 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
4021 (power_state->v1.ucNonClockStateIndex *
4022 power_info->pplib.ucNonClockSize));
4023 if (power_info->pplib.ucStateEntrySize - 1) {
4024 u8 *idx;
4025 ps = kzalloc(sizeof(struct ni_ps), GFP_KERNEL);
4026 if (ps == NULL) {
4027 kfree(rdev->pm.dpm.ps);
4028 return -ENOMEM;
4029 }
4030 rdev->pm.dpm.ps[i].ps_priv = ps;
4031 ni_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
4032 non_clock_info,
4033 power_info->pplib.ucNonClockSize);
4034 idx = (u8 *)&power_state->v1.ucClockStateIndices[0];
4035 for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
4036 clock_info = (union pplib_clock_info *)
4037 (mode_info->atom_context->bios + data_offset +
4038 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
4039 (idx[j] * power_info->pplib.ucClockInfoSize));
4040 ni_parse_pplib_clock_info(rdev,
4041 &rdev->pm.dpm.ps[i], j,
4042 clock_info);
4043 }
4044 }
4045 }
4046 rdev->pm.dpm.num_ps = power_info->pplib.ucNumStates;
4047 return 0;
4048 }
4049
ni_dpm_init(struct radeon_device * rdev)4050 int ni_dpm_init(struct radeon_device *rdev)
4051 {
4052 struct rv7xx_power_info *pi;
4053 struct evergreen_power_info *eg_pi;
4054 struct ni_power_info *ni_pi;
4055 struct atom_clock_dividers dividers;
4056 int ret;
4057
4058 ni_pi = kzalloc(sizeof(struct ni_power_info), GFP_KERNEL);
4059 if (ni_pi == NULL)
4060 return -ENOMEM;
4061 rdev->pm.dpm.priv = ni_pi;
4062 eg_pi = &ni_pi->eg;
4063 pi = &eg_pi->rv7xx;
4064
4065 rv770_get_max_vddc(rdev);
4066
4067 eg_pi->ulv.supported = false;
4068 pi->acpi_vddc = 0;
4069 eg_pi->acpi_vddci = 0;
4070 pi->min_vddc_in_table = 0;
4071 pi->max_vddc_in_table = 0;
4072
4073 ret = r600_get_platform_caps(rdev);
4074 if (ret)
4075 return ret;
4076
4077 ret = ni_parse_power_table(rdev);
4078 if (ret)
4079 return ret;
4080 ret = r600_parse_extended_power_table(rdev);
4081 if (ret)
4082 return ret;
4083
4084 rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
4085 kcalloc(4,
4086 sizeof(struct radeon_clock_voltage_dependency_entry),
4087 GFP_KERNEL);
4088 if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
4089 r600_free_extended_power_table(rdev);
4090 return -ENOMEM;
4091 }
4092 rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
4093 rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
4094 rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
4095 rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
4096 rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 720;
4097 rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
4098 rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 810;
4099 rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
4100 rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 900;
4101
4102 ni_patch_dependency_tables_based_on_leakage(rdev);
4103
4104 if (rdev->pm.dpm.voltage_response_time == 0)
4105 rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
4106 if (rdev->pm.dpm.backbias_response_time == 0)
4107 rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
4108
4109 ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
4110 0, false, ÷rs);
4111 if (ret)
4112 pi->ref_div = dividers.ref_div + 1;
4113 else
4114 pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
4115
4116 pi->rlp = RV770_RLP_DFLT;
4117 pi->rmp = RV770_RMP_DFLT;
4118 pi->lhp = RV770_LHP_DFLT;
4119 pi->lmp = RV770_LMP_DFLT;
4120
4121 eg_pi->ats[0].rlp = RV770_RLP_DFLT;
4122 eg_pi->ats[0].rmp = RV770_RMP_DFLT;
4123 eg_pi->ats[0].lhp = RV770_LHP_DFLT;
4124 eg_pi->ats[0].lmp = RV770_LMP_DFLT;
4125
4126 eg_pi->ats[1].rlp = BTC_RLP_UVD_DFLT;
4127 eg_pi->ats[1].rmp = BTC_RMP_UVD_DFLT;
4128 eg_pi->ats[1].lhp = BTC_LHP_UVD_DFLT;
4129 eg_pi->ats[1].lmp = BTC_LMP_UVD_DFLT;
4130
4131 eg_pi->smu_uvd_hs = true;
4132
4133 if (rdev->pdev->device == 0x6707) {
4134 pi->mclk_strobe_mode_threshold = 55000;
4135 pi->mclk_edc_enable_threshold = 55000;
4136 eg_pi->mclk_edc_wr_enable_threshold = 55000;
4137 } else {
4138 pi->mclk_strobe_mode_threshold = 40000;
4139 pi->mclk_edc_enable_threshold = 40000;
4140 eg_pi->mclk_edc_wr_enable_threshold = 40000;
4141 }
4142 ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold;
4143
4144 pi->voltage_control =
4145 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
4146
4147 pi->mvdd_control =
4148 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
4149
4150 eg_pi->vddci_control =
4151 radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
4152
4153 rv770_get_engine_memory_ss(rdev);
4154
4155 pi->asi = RV770_ASI_DFLT;
4156 pi->pasi = CYPRESS_HASI_DFLT;
4157 pi->vrc = CYPRESS_VRC_DFLT;
4158
4159 pi->power_gating = false;
4160
4161 pi->gfx_clock_gating = true;
4162
4163 pi->mg_clock_gating = true;
4164 pi->mgcgtssm = true;
4165 eg_pi->ls_clock_gating = false;
4166 eg_pi->sclk_deep_sleep = false;
4167
4168 pi->dynamic_pcie_gen2 = true;
4169
4170 if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
4171 pi->thermal_protection = true;
4172 else
4173 pi->thermal_protection = false;
4174
4175 pi->display_gap = true;
4176
4177 pi->dcodt = true;
4178
4179 pi->ulps = true;
4180
4181 eg_pi->dynamic_ac_timing = true;
4182 eg_pi->abm = true;
4183 eg_pi->mcls = true;
4184 eg_pi->light_sleep = true;
4185 eg_pi->memory_transition = true;
4186 #if defined(CONFIG_ACPI)
4187 eg_pi->pcie_performance_request =
4188 radeon_acpi_is_pcie_performance_request_supported(rdev);
4189 #else
4190 eg_pi->pcie_performance_request = false;
4191 #endif
4192
4193 eg_pi->dll_default_on = false;
4194
4195 eg_pi->sclk_deep_sleep = false;
4196
4197 pi->mclk_stutter_mode_threshold = 0;
4198
4199 pi->sram_end = SMC_RAM_END;
4200
4201 rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 3;
4202 rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
4203 rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2 = 900;
4204 rdev->pm.dpm.dyn_state.valid_sclk_values.count = ARRAY_SIZE(btc_valid_sclk);
4205 rdev->pm.dpm.dyn_state.valid_sclk_values.values = btc_valid_sclk;
4206 rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
4207 rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
4208 rdev->pm.dpm.dyn_state.sclk_mclk_delta = 12500;
4209
4210 ni_pi->cac_data.leakage_coefficients.at = 516;
4211 ni_pi->cac_data.leakage_coefficients.bt = 18;
4212 ni_pi->cac_data.leakage_coefficients.av = 51;
4213 ni_pi->cac_data.leakage_coefficients.bv = 2957;
4214
4215 switch (rdev->pdev->device) {
4216 case 0x6700:
4217 case 0x6701:
4218 case 0x6702:
4219 case 0x6703:
4220 case 0x6718:
4221 ni_pi->cac_weights = &cac_weights_cayman_xt;
4222 break;
4223 case 0x6705:
4224 case 0x6719:
4225 case 0x671D:
4226 case 0x671C:
4227 default:
4228 ni_pi->cac_weights = &cac_weights_cayman_pro;
4229 break;
4230 case 0x6704:
4231 case 0x6706:
4232 case 0x6707:
4233 case 0x6708:
4234 case 0x6709:
4235 ni_pi->cac_weights = &cac_weights_cayman_le;
4236 break;
4237 }
4238
4239 if (ni_pi->cac_weights->enable_power_containment_by_default) {
4240 ni_pi->enable_power_containment = true;
4241 ni_pi->enable_cac = true;
4242 ni_pi->enable_sq_ramping = true;
4243 } else {
4244 ni_pi->enable_power_containment = false;
4245 ni_pi->enable_cac = false;
4246 ni_pi->enable_sq_ramping = false;
4247 }
4248
4249 ni_pi->driver_calculate_cac_leakage = false;
4250 ni_pi->cac_configuration_required = true;
4251
4252 if (ni_pi->cac_configuration_required) {
4253 ni_pi->support_cac_long_term_average = true;
4254 ni_pi->lta_window_size = ni_pi->cac_weights->l2_lta_window_size;
4255 ni_pi->lts_truncate = ni_pi->cac_weights->lts_truncate;
4256 } else {
4257 ni_pi->support_cac_long_term_average = false;
4258 ni_pi->lta_window_size = 0;
4259 ni_pi->lts_truncate = 0;
4260 }
4261
4262 ni_pi->use_power_boost_limit = true;
4263
4264 /* make sure dc limits are valid */
4265 if ((rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk == 0) ||
4266 (rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk == 0))
4267 rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
4268 rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
4269
4270 return 0;
4271 }
4272
ni_dpm_fini(struct radeon_device * rdev)4273 void ni_dpm_fini(struct radeon_device *rdev)
4274 {
4275 int i;
4276
4277 for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
4278 kfree(rdev->pm.dpm.ps[i].ps_priv);
4279 }
4280 kfree(rdev->pm.dpm.ps);
4281 kfree(rdev->pm.dpm.priv);
4282 kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
4283 r600_free_extended_power_table(rdev);
4284 }
4285
ni_dpm_print_power_state(struct radeon_device * rdev,struct radeon_ps * rps)4286 void ni_dpm_print_power_state(struct radeon_device *rdev,
4287 struct radeon_ps *rps)
4288 {
4289 struct ni_ps *ps = ni_get_ps(rps);
4290 struct rv7xx_pl *pl;
4291 int i;
4292
4293 r600_dpm_print_class_info(rps->class, rps->class2);
4294 r600_dpm_print_cap_info(rps->caps);
4295 printk("\tuvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
4296 for (i = 0; i < ps->performance_level_count; i++) {
4297 pl = &ps->performance_levels[i];
4298 if (rdev->family >= CHIP_TAHITI)
4299 printk("\t\tpower level %d sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",
4300 i, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);
4301 else
4302 printk("\t\tpower level %d sclk: %u mclk: %u vddc: %u vddci: %u\n",
4303 i, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
4304 }
4305 r600_dpm_print_ps_status(rdev, rps);
4306 }
4307
4308 #ifdef CONFIG_DEBUG_FS
ni_dpm_debugfs_print_current_performance_level(struct radeon_device * rdev,struct seq_file * m)4309 void ni_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
4310 struct seq_file *m)
4311 {
4312 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
4313 struct radeon_ps *rps = &eg_pi->current_rps;
4314 struct ni_ps *ps = ni_get_ps(rps);
4315 struct rv7xx_pl *pl;
4316 u32 current_index =
4317 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
4318 CURRENT_STATE_INDEX_SHIFT;
4319
4320 if (current_index >= ps->performance_level_count) {
4321 seq_printf(m, "invalid dpm profile %d\n", current_index);
4322 } else {
4323 pl = &ps->performance_levels[current_index];
4324 seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
4325 seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u vddci: %u\n",
4326 current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
4327 }
4328 }
4329 #endif /* CONFIG_DEBUG_FS */
4330
ni_dpm_get_current_sclk(struct radeon_device * rdev)4331 u32 ni_dpm_get_current_sclk(struct radeon_device *rdev)
4332 {
4333 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
4334 struct radeon_ps *rps = &eg_pi->current_rps;
4335 struct ni_ps *ps = ni_get_ps(rps);
4336 struct rv7xx_pl *pl;
4337 u32 current_index =
4338 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
4339 CURRENT_STATE_INDEX_SHIFT;
4340
4341 if (current_index >= ps->performance_level_count) {
4342 return 0;
4343 } else {
4344 pl = &ps->performance_levels[current_index];
4345 return pl->sclk;
4346 }
4347 }
4348
ni_dpm_get_current_mclk(struct radeon_device * rdev)4349 u32 ni_dpm_get_current_mclk(struct radeon_device *rdev)
4350 {
4351 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
4352 struct radeon_ps *rps = &eg_pi->current_rps;
4353 struct ni_ps *ps = ni_get_ps(rps);
4354 struct rv7xx_pl *pl;
4355 u32 current_index =
4356 (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
4357 CURRENT_STATE_INDEX_SHIFT;
4358
4359 if (current_index >= ps->performance_level_count) {
4360 return 0;
4361 } else {
4362 pl = &ps->performance_levels[current_index];
4363 return pl->mclk;
4364 }
4365 }
4366
ni_dpm_get_sclk(struct radeon_device * rdev,bool low)4367 u32 ni_dpm_get_sclk(struct radeon_device *rdev, bool low)
4368 {
4369 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
4370 struct ni_ps *requested_state = ni_get_ps(&eg_pi->requested_rps);
4371
4372 if (low)
4373 return requested_state->performance_levels[0].sclk;
4374 else
4375 return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk;
4376 }
4377
ni_dpm_get_mclk(struct radeon_device * rdev,bool low)4378 u32 ni_dpm_get_mclk(struct radeon_device *rdev, bool low)
4379 {
4380 struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
4381 struct ni_ps *requested_state = ni_get_ps(&eg_pi->requested_rps);
4382
4383 if (low)
4384 return requested_state->performance_levels[0].mclk;
4385 else
4386 return requested_state->performance_levels[requested_state->performance_level_count - 1].mclk;
4387 }
4388
4389