1 /*	$NetBSD: radeon_btc_dpm.c,v 1.3 2022/07/15 06:42:08 mrg Exp $	*/
2 
3 /*
4  * Copyright 2011 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  * Authors: Alex Deucher
25  */
26 
27 #include <sys/cdefs.h>
28 __KERNEL_RCSID(0, "$NetBSD: radeon_btc_dpm.c,v 1.3 2022/07/15 06:42:08 mrg Exp $");
29 
30 #include <linux/pci.h>
31 #include <linux/seq_file.h>
32 
33 #include "atom.h"
34 #include "btc_dpm.h"
35 #include "btcd.h"
36 #include "cypress_dpm.h"
37 #include "r600_dpm.h"
38 #include "radeon.h"
39 #include "radeon_asic.h"
40 
41 #define MC_CG_ARB_FREQ_F0           0x0a
42 #define MC_CG_ARB_FREQ_F1           0x0b
43 #define MC_CG_ARB_FREQ_F2           0x0c
44 #define MC_CG_ARB_FREQ_F3           0x0d
45 
46 #define MC_CG_SEQ_DRAMCONF_S0       0x05
47 #define MC_CG_SEQ_DRAMCONF_S1       0x06
48 #define MC_CG_SEQ_YCLK_SUSPEND      0x04
49 #define MC_CG_SEQ_YCLK_RESUME       0x0a
50 
51 #define SMC_RAM_END 0x8000
52 
53 #ifndef BTC_MGCG_SEQUENCE
54 #define BTC_MGCG_SEQUENCE  300
55 
56 struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
57 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
58 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
59 
60 extern int ni_mc_load_microcode(struct radeon_device *rdev);
61 
62 //********* BARTS **************//
63 static const u32 barts_cgcg_cgls_default[] =
64 {
65 	/* Register,   Value,     Mask bits */
66 	0x000008f8, 0x00000010, 0xffffffff,
67 	0x000008fc, 0x00000000, 0xffffffff,
68 	0x000008f8, 0x00000011, 0xffffffff,
69 	0x000008fc, 0x00000000, 0xffffffff,
70 	0x000008f8, 0x00000012, 0xffffffff,
71 	0x000008fc, 0x00000000, 0xffffffff,
72 	0x000008f8, 0x00000013, 0xffffffff,
73 	0x000008fc, 0x00000000, 0xffffffff,
74 	0x000008f8, 0x00000014, 0xffffffff,
75 	0x000008fc, 0x00000000, 0xffffffff,
76 	0x000008f8, 0x00000015, 0xffffffff,
77 	0x000008fc, 0x00000000, 0xffffffff,
78 	0x000008f8, 0x00000016, 0xffffffff,
79 	0x000008fc, 0x00000000, 0xffffffff,
80 	0x000008f8, 0x00000017, 0xffffffff,
81 	0x000008fc, 0x00000000, 0xffffffff,
82 	0x000008f8, 0x00000018, 0xffffffff,
83 	0x000008fc, 0x00000000, 0xffffffff,
84 	0x000008f8, 0x00000019, 0xffffffff,
85 	0x000008fc, 0x00000000, 0xffffffff,
86 	0x000008f8, 0x0000001a, 0xffffffff,
87 	0x000008fc, 0x00000000, 0xffffffff,
88 	0x000008f8, 0x0000001b, 0xffffffff,
89 	0x000008fc, 0x00000000, 0xffffffff,
90 	0x000008f8, 0x00000020, 0xffffffff,
91 	0x000008fc, 0x00000000, 0xffffffff,
92 	0x000008f8, 0x00000021, 0xffffffff,
93 	0x000008fc, 0x00000000, 0xffffffff,
94 	0x000008f8, 0x00000022, 0xffffffff,
95 	0x000008fc, 0x00000000, 0xffffffff,
96 	0x000008f8, 0x00000023, 0xffffffff,
97 	0x000008fc, 0x00000000, 0xffffffff,
98 	0x000008f8, 0x00000024, 0xffffffff,
99 	0x000008fc, 0x00000000, 0xffffffff,
100 	0x000008f8, 0x00000025, 0xffffffff,
101 	0x000008fc, 0x00000000, 0xffffffff,
102 	0x000008f8, 0x00000026, 0xffffffff,
103 	0x000008fc, 0x00000000, 0xffffffff,
104 	0x000008f8, 0x00000027, 0xffffffff,
105 	0x000008fc, 0x00000000, 0xffffffff,
106 	0x000008f8, 0x00000028, 0xffffffff,
107 	0x000008fc, 0x00000000, 0xffffffff,
108 	0x000008f8, 0x00000029, 0xffffffff,
109 	0x000008fc, 0x00000000, 0xffffffff,
110 	0x000008f8, 0x0000002a, 0xffffffff,
111 	0x000008fc, 0x00000000, 0xffffffff,
112 	0x000008f8, 0x0000002b, 0xffffffff,
113 	0x000008fc, 0x00000000, 0xffffffff
114 };
115 #define BARTS_CGCG_CGLS_DEFAULT_LENGTH sizeof(barts_cgcg_cgls_default) / (3 * sizeof(u32))
116 
117 static const u32 barts_cgcg_cgls_disable[] =
118 {
119 	0x000008f8, 0x00000010, 0xffffffff,
120 	0x000008fc, 0xffffffff, 0xffffffff,
121 	0x000008f8, 0x00000011, 0xffffffff,
122 	0x000008fc, 0xffffffff, 0xffffffff,
123 	0x000008f8, 0x00000012, 0xffffffff,
124 	0x000008fc, 0xffffffff, 0xffffffff,
125 	0x000008f8, 0x00000013, 0xffffffff,
126 	0x000008fc, 0xffffffff, 0xffffffff,
127 	0x000008f8, 0x00000014, 0xffffffff,
128 	0x000008fc, 0xffffffff, 0xffffffff,
129 	0x000008f8, 0x00000015, 0xffffffff,
130 	0x000008fc, 0xffffffff, 0xffffffff,
131 	0x000008f8, 0x00000016, 0xffffffff,
132 	0x000008fc, 0xffffffff, 0xffffffff,
133 	0x000008f8, 0x00000017, 0xffffffff,
134 	0x000008fc, 0xffffffff, 0xffffffff,
135 	0x000008f8, 0x00000018, 0xffffffff,
136 	0x000008fc, 0xffffffff, 0xffffffff,
137 	0x000008f8, 0x00000019, 0xffffffff,
138 	0x000008fc, 0xffffffff, 0xffffffff,
139 	0x000008f8, 0x0000001a, 0xffffffff,
140 	0x000008fc, 0xffffffff, 0xffffffff,
141 	0x000008f8, 0x0000001b, 0xffffffff,
142 	0x000008fc, 0xffffffff, 0xffffffff,
143 	0x000008f8, 0x00000020, 0xffffffff,
144 	0x000008fc, 0x00000000, 0xffffffff,
145 	0x000008f8, 0x00000021, 0xffffffff,
146 	0x000008fc, 0x00000000, 0xffffffff,
147 	0x000008f8, 0x00000022, 0xffffffff,
148 	0x000008fc, 0x00000000, 0xffffffff,
149 	0x000008f8, 0x00000023, 0xffffffff,
150 	0x000008fc, 0x00000000, 0xffffffff,
151 	0x000008f8, 0x00000024, 0xffffffff,
152 	0x000008fc, 0x00000000, 0xffffffff,
153 	0x000008f8, 0x00000025, 0xffffffff,
154 	0x000008fc, 0x00000000, 0xffffffff,
155 	0x000008f8, 0x00000026, 0xffffffff,
156 	0x000008fc, 0x00000000, 0xffffffff,
157 	0x000008f8, 0x00000027, 0xffffffff,
158 	0x000008fc, 0x00000000, 0xffffffff,
159 	0x000008f8, 0x00000028, 0xffffffff,
160 	0x000008fc, 0x00000000, 0xffffffff,
161 	0x000008f8, 0x00000029, 0xffffffff,
162 	0x000008fc, 0x00000000, 0xffffffff,
163 	0x000008f8, 0x0000002a, 0xffffffff,
164 	0x000008fc, 0x00000000, 0xffffffff,
165 	0x000008f8, 0x0000002b, 0xffffffff,
166 	0x000008fc, 0x00000000, 0xffffffff,
167 	0x00000644, 0x000f7912, 0x001f4180,
168 	0x00000644, 0x000f3812, 0x001f4180
169 };
170 #define BARTS_CGCG_CGLS_DISABLE_LENGTH sizeof(barts_cgcg_cgls_disable) / (3 * sizeof(u32))
171 
172 static const u32 barts_cgcg_cgls_enable[] =
173 {
174 	/* 0x0000c124, 0x84180000, 0x00180000, */
175 	0x00000644, 0x000f7892, 0x001f4080,
176 	0x000008f8, 0x00000010, 0xffffffff,
177 	0x000008fc, 0x00000000, 0xffffffff,
178 	0x000008f8, 0x00000011, 0xffffffff,
179 	0x000008fc, 0x00000000, 0xffffffff,
180 	0x000008f8, 0x00000012, 0xffffffff,
181 	0x000008fc, 0x00000000, 0xffffffff,
182 	0x000008f8, 0x00000013, 0xffffffff,
183 	0x000008fc, 0x00000000, 0xffffffff,
184 	0x000008f8, 0x00000014, 0xffffffff,
185 	0x000008fc, 0x00000000, 0xffffffff,
186 	0x000008f8, 0x00000015, 0xffffffff,
187 	0x000008fc, 0x00000000, 0xffffffff,
188 	0x000008f8, 0x00000016, 0xffffffff,
189 	0x000008fc, 0x00000000, 0xffffffff,
190 	0x000008f8, 0x00000017, 0xffffffff,
191 	0x000008fc, 0x00000000, 0xffffffff,
192 	0x000008f8, 0x00000018, 0xffffffff,
193 	0x000008fc, 0x00000000, 0xffffffff,
194 	0x000008f8, 0x00000019, 0xffffffff,
195 	0x000008fc, 0x00000000, 0xffffffff,
196 	0x000008f8, 0x0000001a, 0xffffffff,
197 	0x000008fc, 0x00000000, 0xffffffff,
198 	0x000008f8, 0x0000001b, 0xffffffff,
199 	0x000008fc, 0x00000000, 0xffffffff,
200 	0x000008f8, 0x00000020, 0xffffffff,
201 	0x000008fc, 0xffffffff, 0xffffffff,
202 	0x000008f8, 0x00000021, 0xffffffff,
203 	0x000008fc, 0xffffffff, 0xffffffff,
204 	0x000008f8, 0x00000022, 0xffffffff,
205 	0x000008fc, 0xffffffff, 0xffffffff,
206 	0x000008f8, 0x00000023, 0xffffffff,
207 	0x000008fc, 0xffffffff, 0xffffffff,
208 	0x000008f8, 0x00000024, 0xffffffff,
209 	0x000008fc, 0xffffffff, 0xffffffff,
210 	0x000008f8, 0x00000025, 0xffffffff,
211 	0x000008fc, 0xffffffff, 0xffffffff,
212 	0x000008f8, 0x00000026, 0xffffffff,
213 	0x000008fc, 0xffffffff, 0xffffffff,
214 	0x000008f8, 0x00000027, 0xffffffff,
215 	0x000008fc, 0xffffffff, 0xffffffff,
216 	0x000008f8, 0x00000028, 0xffffffff,
217 	0x000008fc, 0xffffffff, 0xffffffff,
218 	0x000008f8, 0x00000029, 0xffffffff,
219 	0x000008fc, 0xffffffff, 0xffffffff,
220 	0x000008f8, 0x0000002a, 0xffffffff,
221 	0x000008fc, 0xffffffff, 0xffffffff,
222 	0x000008f8, 0x0000002b, 0xffffffff,
223 	0x000008fc, 0xffffffff, 0xffffffff
224 };
225 #define BARTS_CGCG_CGLS_ENABLE_LENGTH sizeof(barts_cgcg_cgls_enable) / (3 * sizeof(u32))
226 
227 static const u32 barts_mgcg_default[] =
228 {
229 	0x0000802c, 0xc0000000, 0xffffffff,
230 	0x00005448, 0x00000100, 0xffffffff,
231 	0x000055e4, 0x00600100, 0xffffffff,
232 	0x0000160c, 0x00000100, 0xffffffff,
233 	0x0000c164, 0x00000100, 0xffffffff,
234 	0x00008a18, 0x00000100, 0xffffffff,
235 	0x0000897c, 0x06000100, 0xffffffff,
236 	0x00008b28, 0x00000100, 0xffffffff,
237 	0x00009144, 0x00000100, 0xffffffff,
238 	0x00009a60, 0x00000100, 0xffffffff,
239 	0x00009868, 0x00000100, 0xffffffff,
240 	0x00008d58, 0x00000100, 0xffffffff,
241 	0x00009510, 0x00000100, 0xffffffff,
242 	0x0000949c, 0x00000100, 0xffffffff,
243 	0x00009654, 0x00000100, 0xffffffff,
244 	0x00009030, 0x00000100, 0xffffffff,
245 	0x00009034, 0x00000100, 0xffffffff,
246 	0x00009038, 0x00000100, 0xffffffff,
247 	0x0000903c, 0x00000100, 0xffffffff,
248 	0x00009040, 0x00000100, 0xffffffff,
249 	0x0000a200, 0x00000100, 0xffffffff,
250 	0x0000a204, 0x00000100, 0xffffffff,
251 	0x0000a208, 0x00000100, 0xffffffff,
252 	0x0000a20c, 0x00000100, 0xffffffff,
253 	0x0000977c, 0x00000100, 0xffffffff,
254 	0x00003f80, 0x00000100, 0xffffffff,
255 	0x0000a210, 0x00000100, 0xffffffff,
256 	0x0000a214, 0x00000100, 0xffffffff,
257 	0x000004d8, 0x00000100, 0xffffffff,
258 	0x00009784, 0x00000100, 0xffffffff,
259 	0x00009698, 0x00000100, 0xffffffff,
260 	0x000004d4, 0x00000200, 0xffffffff,
261 	0x000004d0, 0x00000000, 0xffffffff,
262 	0x000030cc, 0x00000100, 0xffffffff,
263 	0x0000d0c0, 0xff000100, 0xffffffff,
264 	0x0000802c, 0x40000000, 0xffffffff,
265 	0x0000915c, 0x00010000, 0xffffffff,
266 	0x00009160, 0x00030002, 0xffffffff,
267 	0x00009164, 0x00050004, 0xffffffff,
268 	0x00009168, 0x00070006, 0xffffffff,
269 	0x00009178, 0x00070000, 0xffffffff,
270 	0x0000917c, 0x00030002, 0xffffffff,
271 	0x00009180, 0x00050004, 0xffffffff,
272 	0x0000918c, 0x00010006, 0xffffffff,
273 	0x00009190, 0x00090008, 0xffffffff,
274 	0x00009194, 0x00070000, 0xffffffff,
275 	0x00009198, 0x00030002, 0xffffffff,
276 	0x0000919c, 0x00050004, 0xffffffff,
277 	0x000091a8, 0x00010006, 0xffffffff,
278 	0x000091ac, 0x00090008, 0xffffffff,
279 	0x000091b0, 0x00070000, 0xffffffff,
280 	0x000091b4, 0x00030002, 0xffffffff,
281 	0x000091b8, 0x00050004, 0xffffffff,
282 	0x000091c4, 0x00010006, 0xffffffff,
283 	0x000091c8, 0x00090008, 0xffffffff,
284 	0x000091cc, 0x00070000, 0xffffffff,
285 	0x000091d0, 0x00030002, 0xffffffff,
286 	0x000091d4, 0x00050004, 0xffffffff,
287 	0x000091e0, 0x00010006, 0xffffffff,
288 	0x000091e4, 0x00090008, 0xffffffff,
289 	0x000091e8, 0x00000000, 0xffffffff,
290 	0x000091ec, 0x00070000, 0xffffffff,
291 	0x000091f0, 0x00030002, 0xffffffff,
292 	0x000091f4, 0x00050004, 0xffffffff,
293 	0x00009200, 0x00010006, 0xffffffff,
294 	0x00009204, 0x00090008, 0xffffffff,
295 	0x00009208, 0x00070000, 0xffffffff,
296 	0x0000920c, 0x00030002, 0xffffffff,
297 	0x00009210, 0x00050004, 0xffffffff,
298 	0x0000921c, 0x00010006, 0xffffffff,
299 	0x00009220, 0x00090008, 0xffffffff,
300 	0x00009224, 0x00070000, 0xffffffff,
301 	0x00009228, 0x00030002, 0xffffffff,
302 	0x0000922c, 0x00050004, 0xffffffff,
303 	0x00009238, 0x00010006, 0xffffffff,
304 	0x0000923c, 0x00090008, 0xffffffff,
305 	0x00009294, 0x00000000, 0xffffffff,
306 	0x0000802c, 0x40010000, 0xffffffff,
307 	0x0000915c, 0x00010000, 0xffffffff,
308 	0x00009160, 0x00030002, 0xffffffff,
309 	0x00009164, 0x00050004, 0xffffffff,
310 	0x00009168, 0x00070006, 0xffffffff,
311 	0x00009178, 0x00070000, 0xffffffff,
312 	0x0000917c, 0x00030002, 0xffffffff,
313 	0x00009180, 0x00050004, 0xffffffff,
314 	0x0000918c, 0x00010006, 0xffffffff,
315 	0x00009190, 0x00090008, 0xffffffff,
316 	0x00009194, 0x00070000, 0xffffffff,
317 	0x00009198, 0x00030002, 0xffffffff,
318 	0x0000919c, 0x00050004, 0xffffffff,
319 	0x000091a8, 0x00010006, 0xffffffff,
320 	0x000091ac, 0x00090008, 0xffffffff,
321 	0x000091b0, 0x00070000, 0xffffffff,
322 	0x000091b4, 0x00030002, 0xffffffff,
323 	0x000091b8, 0x00050004, 0xffffffff,
324 	0x000091c4, 0x00010006, 0xffffffff,
325 	0x000091c8, 0x00090008, 0xffffffff,
326 	0x000091cc, 0x00070000, 0xffffffff,
327 	0x000091d0, 0x00030002, 0xffffffff,
328 	0x000091d4, 0x00050004, 0xffffffff,
329 	0x000091e0, 0x00010006, 0xffffffff,
330 	0x000091e4, 0x00090008, 0xffffffff,
331 	0x000091e8, 0x00000000, 0xffffffff,
332 	0x000091ec, 0x00070000, 0xffffffff,
333 	0x000091f0, 0x00030002, 0xffffffff,
334 	0x000091f4, 0x00050004, 0xffffffff,
335 	0x00009200, 0x00010006, 0xffffffff,
336 	0x00009204, 0x00090008, 0xffffffff,
337 	0x00009208, 0x00070000, 0xffffffff,
338 	0x0000920c, 0x00030002, 0xffffffff,
339 	0x00009210, 0x00050004, 0xffffffff,
340 	0x0000921c, 0x00010006, 0xffffffff,
341 	0x00009220, 0x00090008, 0xffffffff,
342 	0x00009224, 0x00070000, 0xffffffff,
343 	0x00009228, 0x00030002, 0xffffffff,
344 	0x0000922c, 0x00050004, 0xffffffff,
345 	0x00009238, 0x00010006, 0xffffffff,
346 	0x0000923c, 0x00090008, 0xffffffff,
347 	0x00009294, 0x00000000, 0xffffffff,
348 	0x0000802c, 0xc0000000, 0xffffffff,
349 	0x000008f8, 0x00000010, 0xffffffff,
350 	0x000008fc, 0x00000000, 0xffffffff,
351 	0x000008f8, 0x00000011, 0xffffffff,
352 	0x000008fc, 0x00000000, 0xffffffff,
353 	0x000008f8, 0x00000012, 0xffffffff,
354 	0x000008fc, 0x00000000, 0xffffffff,
355 	0x000008f8, 0x00000013, 0xffffffff,
356 	0x000008fc, 0x00000000, 0xffffffff,
357 	0x000008f8, 0x00000014, 0xffffffff,
358 	0x000008fc, 0x00000000, 0xffffffff,
359 	0x000008f8, 0x00000015, 0xffffffff,
360 	0x000008fc, 0x00000000, 0xffffffff,
361 	0x000008f8, 0x00000016, 0xffffffff,
362 	0x000008fc, 0x00000000, 0xffffffff,
363 	0x000008f8, 0x00000017, 0xffffffff,
364 	0x000008fc, 0x00000000, 0xffffffff,
365 	0x000008f8, 0x00000018, 0xffffffff,
366 	0x000008fc, 0x00000000, 0xffffffff,
367 	0x000008f8, 0x00000019, 0xffffffff,
368 	0x000008fc, 0x00000000, 0xffffffff,
369 	0x000008f8, 0x0000001a, 0xffffffff,
370 	0x000008fc, 0x00000000, 0xffffffff,
371 	0x000008f8, 0x0000001b, 0xffffffff,
372 	0x000008fc, 0x00000000, 0xffffffff
373 };
374 #define BARTS_MGCG_DEFAULT_LENGTH sizeof(barts_mgcg_default) / (3 * sizeof(u32))
375 
376 static const u32 barts_mgcg_disable[] =
377 {
378 	0x0000802c, 0xc0000000, 0xffffffff,
379 	0x000008f8, 0x00000000, 0xffffffff,
380 	0x000008fc, 0xffffffff, 0xffffffff,
381 	0x000008f8, 0x00000001, 0xffffffff,
382 	0x000008fc, 0xffffffff, 0xffffffff,
383 	0x000008f8, 0x00000002, 0xffffffff,
384 	0x000008fc, 0xffffffff, 0xffffffff,
385 	0x000008f8, 0x00000003, 0xffffffff,
386 	0x000008fc, 0xffffffff, 0xffffffff,
387 	0x00009150, 0x00600000, 0xffffffff
388 };
389 #define BARTS_MGCG_DISABLE_LENGTH sizeof(barts_mgcg_disable) / (3 * sizeof(u32))
390 
391 static const u32 barts_mgcg_enable[] =
392 {
393 	0x0000802c, 0xc0000000, 0xffffffff,
394 	0x000008f8, 0x00000000, 0xffffffff,
395 	0x000008fc, 0x00000000, 0xffffffff,
396 	0x000008f8, 0x00000001, 0xffffffff,
397 	0x000008fc, 0x00000000, 0xffffffff,
398 	0x000008f8, 0x00000002, 0xffffffff,
399 	0x000008fc, 0x00000000, 0xffffffff,
400 	0x000008f8, 0x00000003, 0xffffffff,
401 	0x000008fc, 0x00000000, 0xffffffff,
402 	0x00009150, 0x81944000, 0xffffffff
403 };
404 #define BARTS_MGCG_ENABLE_LENGTH sizeof(barts_mgcg_enable) / (3 * sizeof(u32))
405 
406 //********* CAICOS **************//
407 static const u32 caicos_cgcg_cgls_default[] =
408 {
409 	0x000008f8, 0x00000010, 0xffffffff,
410 	0x000008fc, 0x00000000, 0xffffffff,
411 	0x000008f8, 0x00000011, 0xffffffff,
412 	0x000008fc, 0x00000000, 0xffffffff,
413 	0x000008f8, 0x00000012, 0xffffffff,
414 	0x000008fc, 0x00000000, 0xffffffff,
415 	0x000008f8, 0x00000013, 0xffffffff,
416 	0x000008fc, 0x00000000, 0xffffffff,
417 	0x000008f8, 0x00000014, 0xffffffff,
418 	0x000008fc, 0x00000000, 0xffffffff,
419 	0x000008f8, 0x00000015, 0xffffffff,
420 	0x000008fc, 0x00000000, 0xffffffff,
421 	0x000008f8, 0x00000016, 0xffffffff,
422 	0x000008fc, 0x00000000, 0xffffffff,
423 	0x000008f8, 0x00000017, 0xffffffff,
424 	0x000008fc, 0x00000000, 0xffffffff,
425 	0x000008f8, 0x00000018, 0xffffffff,
426 	0x000008fc, 0x00000000, 0xffffffff,
427 	0x000008f8, 0x00000019, 0xffffffff,
428 	0x000008fc, 0x00000000, 0xffffffff,
429 	0x000008f8, 0x0000001a, 0xffffffff,
430 	0x000008fc, 0x00000000, 0xffffffff,
431 	0x000008f8, 0x0000001b, 0xffffffff,
432 	0x000008fc, 0x00000000, 0xffffffff,
433 	0x000008f8, 0x00000020, 0xffffffff,
434 	0x000008fc, 0x00000000, 0xffffffff,
435 	0x000008f8, 0x00000021, 0xffffffff,
436 	0x000008fc, 0x00000000, 0xffffffff,
437 	0x000008f8, 0x00000022, 0xffffffff,
438 	0x000008fc, 0x00000000, 0xffffffff,
439 	0x000008f8, 0x00000023, 0xffffffff,
440 	0x000008fc, 0x00000000, 0xffffffff,
441 	0x000008f8, 0x00000024, 0xffffffff,
442 	0x000008fc, 0x00000000, 0xffffffff,
443 	0x000008f8, 0x00000025, 0xffffffff,
444 	0x000008fc, 0x00000000, 0xffffffff,
445 	0x000008f8, 0x00000026, 0xffffffff,
446 	0x000008fc, 0x00000000, 0xffffffff,
447 	0x000008f8, 0x00000027, 0xffffffff,
448 	0x000008fc, 0x00000000, 0xffffffff,
449 	0x000008f8, 0x00000028, 0xffffffff,
450 	0x000008fc, 0x00000000, 0xffffffff,
451 	0x000008f8, 0x00000029, 0xffffffff,
452 	0x000008fc, 0x00000000, 0xffffffff,
453 	0x000008f8, 0x0000002a, 0xffffffff,
454 	0x000008fc, 0x00000000, 0xffffffff,
455 	0x000008f8, 0x0000002b, 0xffffffff,
456 	0x000008fc, 0x00000000, 0xffffffff
457 };
458 #define CAICOS_CGCG_CGLS_DEFAULT_LENGTH sizeof(caicos_cgcg_cgls_default) / (3 * sizeof(u32))
459 
460 static const u32 caicos_cgcg_cgls_disable[] =
461 {
462 	0x000008f8, 0x00000010, 0xffffffff,
463 	0x000008fc, 0xffffffff, 0xffffffff,
464 	0x000008f8, 0x00000011, 0xffffffff,
465 	0x000008fc, 0xffffffff, 0xffffffff,
466 	0x000008f8, 0x00000012, 0xffffffff,
467 	0x000008fc, 0xffffffff, 0xffffffff,
468 	0x000008f8, 0x00000013, 0xffffffff,
469 	0x000008fc, 0xffffffff, 0xffffffff,
470 	0x000008f8, 0x00000014, 0xffffffff,
471 	0x000008fc, 0xffffffff, 0xffffffff,
472 	0x000008f8, 0x00000015, 0xffffffff,
473 	0x000008fc, 0xffffffff, 0xffffffff,
474 	0x000008f8, 0x00000016, 0xffffffff,
475 	0x000008fc, 0xffffffff, 0xffffffff,
476 	0x000008f8, 0x00000017, 0xffffffff,
477 	0x000008fc, 0xffffffff, 0xffffffff,
478 	0x000008f8, 0x00000018, 0xffffffff,
479 	0x000008fc, 0xffffffff, 0xffffffff,
480 	0x000008f8, 0x00000019, 0xffffffff,
481 	0x000008fc, 0xffffffff, 0xffffffff,
482 	0x000008f8, 0x0000001a, 0xffffffff,
483 	0x000008fc, 0xffffffff, 0xffffffff,
484 	0x000008f8, 0x0000001b, 0xffffffff,
485 	0x000008fc, 0xffffffff, 0xffffffff,
486 	0x000008f8, 0x00000020, 0xffffffff,
487 	0x000008fc, 0x00000000, 0xffffffff,
488 	0x000008f8, 0x00000021, 0xffffffff,
489 	0x000008fc, 0x00000000, 0xffffffff,
490 	0x000008f8, 0x00000022, 0xffffffff,
491 	0x000008fc, 0x00000000, 0xffffffff,
492 	0x000008f8, 0x00000023, 0xffffffff,
493 	0x000008fc, 0x00000000, 0xffffffff,
494 	0x000008f8, 0x00000024, 0xffffffff,
495 	0x000008fc, 0x00000000, 0xffffffff,
496 	0x000008f8, 0x00000025, 0xffffffff,
497 	0x000008fc, 0x00000000, 0xffffffff,
498 	0x000008f8, 0x00000026, 0xffffffff,
499 	0x000008fc, 0x00000000, 0xffffffff,
500 	0x000008f8, 0x00000027, 0xffffffff,
501 	0x000008fc, 0x00000000, 0xffffffff,
502 	0x000008f8, 0x00000028, 0xffffffff,
503 	0x000008fc, 0x00000000, 0xffffffff,
504 	0x000008f8, 0x00000029, 0xffffffff,
505 	0x000008fc, 0x00000000, 0xffffffff,
506 	0x000008f8, 0x0000002a, 0xffffffff,
507 	0x000008fc, 0x00000000, 0xffffffff,
508 	0x000008f8, 0x0000002b, 0xffffffff,
509 	0x000008fc, 0x00000000, 0xffffffff,
510 	0x00000644, 0x000f7912, 0x001f4180,
511 	0x00000644, 0x000f3812, 0x001f4180
512 };
513 #define CAICOS_CGCG_CGLS_DISABLE_LENGTH sizeof(caicos_cgcg_cgls_disable) / (3 * sizeof(u32))
514 
515 static const u32 caicos_cgcg_cgls_enable[] =
516 {
517 	/* 0x0000c124, 0x84180000, 0x00180000, */
518 	0x00000644, 0x000f7892, 0x001f4080,
519 	0x000008f8, 0x00000010, 0xffffffff,
520 	0x000008fc, 0x00000000, 0xffffffff,
521 	0x000008f8, 0x00000011, 0xffffffff,
522 	0x000008fc, 0x00000000, 0xffffffff,
523 	0x000008f8, 0x00000012, 0xffffffff,
524 	0x000008fc, 0x00000000, 0xffffffff,
525 	0x000008f8, 0x00000013, 0xffffffff,
526 	0x000008fc, 0x00000000, 0xffffffff,
527 	0x000008f8, 0x00000014, 0xffffffff,
528 	0x000008fc, 0x00000000, 0xffffffff,
529 	0x000008f8, 0x00000015, 0xffffffff,
530 	0x000008fc, 0x00000000, 0xffffffff,
531 	0x000008f8, 0x00000016, 0xffffffff,
532 	0x000008fc, 0x00000000, 0xffffffff,
533 	0x000008f8, 0x00000017, 0xffffffff,
534 	0x000008fc, 0x00000000, 0xffffffff,
535 	0x000008f8, 0x00000018, 0xffffffff,
536 	0x000008fc, 0x00000000, 0xffffffff,
537 	0x000008f8, 0x00000019, 0xffffffff,
538 	0x000008fc, 0x00000000, 0xffffffff,
539 	0x000008f8, 0x0000001a, 0xffffffff,
540 	0x000008fc, 0x00000000, 0xffffffff,
541 	0x000008f8, 0x0000001b, 0xffffffff,
542 	0x000008fc, 0x00000000, 0xffffffff,
543 	0x000008f8, 0x00000020, 0xffffffff,
544 	0x000008fc, 0xffffffff, 0xffffffff,
545 	0x000008f8, 0x00000021, 0xffffffff,
546 	0x000008fc, 0xffffffff, 0xffffffff,
547 	0x000008f8, 0x00000022, 0xffffffff,
548 	0x000008fc, 0xffffffff, 0xffffffff,
549 	0x000008f8, 0x00000023, 0xffffffff,
550 	0x000008fc, 0xffffffff, 0xffffffff,
551 	0x000008f8, 0x00000024, 0xffffffff,
552 	0x000008fc, 0xffffffff, 0xffffffff,
553 	0x000008f8, 0x00000025, 0xffffffff,
554 	0x000008fc, 0xffffffff, 0xffffffff,
555 	0x000008f8, 0x00000026, 0xffffffff,
556 	0x000008fc, 0xffffffff, 0xffffffff,
557 	0x000008f8, 0x00000027, 0xffffffff,
558 	0x000008fc, 0xffffffff, 0xffffffff,
559 	0x000008f8, 0x00000028, 0xffffffff,
560 	0x000008fc, 0xffffffff, 0xffffffff,
561 	0x000008f8, 0x00000029, 0xffffffff,
562 	0x000008fc, 0xffffffff, 0xffffffff,
563 	0x000008f8, 0x0000002a, 0xffffffff,
564 	0x000008fc, 0xffffffff, 0xffffffff,
565 	0x000008f8, 0x0000002b, 0xffffffff,
566 	0x000008fc, 0xffffffff, 0xffffffff
567 };
568 #define CAICOS_CGCG_CGLS_ENABLE_LENGTH sizeof(caicos_cgcg_cgls_enable) / (3 * sizeof(u32))
569 
570 static const u32 caicos_mgcg_default[] =
571 {
572 	0x0000802c, 0xc0000000, 0xffffffff,
573 	0x00005448, 0x00000100, 0xffffffff,
574 	0x000055e4, 0x00600100, 0xffffffff,
575 	0x0000160c, 0x00000100, 0xffffffff,
576 	0x0000c164, 0x00000100, 0xffffffff,
577 	0x00008a18, 0x00000100, 0xffffffff,
578 	0x0000897c, 0x06000100, 0xffffffff,
579 	0x00008b28, 0x00000100, 0xffffffff,
580 	0x00009144, 0x00000100, 0xffffffff,
581 	0x00009a60, 0x00000100, 0xffffffff,
582 	0x00009868, 0x00000100, 0xffffffff,
583 	0x00008d58, 0x00000100, 0xffffffff,
584 	0x00009510, 0x00000100, 0xffffffff,
585 	0x0000949c, 0x00000100, 0xffffffff,
586 	0x00009654, 0x00000100, 0xffffffff,
587 	0x00009030, 0x00000100, 0xffffffff,
588 	0x00009034, 0x00000100, 0xffffffff,
589 	0x00009038, 0x00000100, 0xffffffff,
590 	0x0000903c, 0x00000100, 0xffffffff,
591 	0x00009040, 0x00000100, 0xffffffff,
592 	0x0000a200, 0x00000100, 0xffffffff,
593 	0x0000a204, 0x00000100, 0xffffffff,
594 	0x0000a208, 0x00000100, 0xffffffff,
595 	0x0000a20c, 0x00000100, 0xffffffff,
596 	0x0000977c, 0x00000100, 0xffffffff,
597 	0x00003f80, 0x00000100, 0xffffffff,
598 	0x0000a210, 0x00000100, 0xffffffff,
599 	0x0000a214, 0x00000100, 0xffffffff,
600 	0x000004d8, 0x00000100, 0xffffffff,
601 	0x00009784, 0x00000100, 0xffffffff,
602 	0x00009698, 0x00000100, 0xffffffff,
603 	0x000004d4, 0x00000200, 0xffffffff,
604 	0x000004d0, 0x00000000, 0xffffffff,
605 	0x000030cc, 0x00000100, 0xffffffff,
606 	0x0000d0c0, 0xff000100, 0xffffffff,
607 	0x0000915c, 0x00010000, 0xffffffff,
608 	0x00009160, 0x00030002, 0xffffffff,
609 	0x00009164, 0x00050004, 0xffffffff,
610 	0x00009168, 0x00070006, 0xffffffff,
611 	0x00009178, 0x00070000, 0xffffffff,
612 	0x0000917c, 0x00030002, 0xffffffff,
613 	0x00009180, 0x00050004, 0xffffffff,
614 	0x0000918c, 0x00010006, 0xffffffff,
615 	0x00009190, 0x00090008, 0xffffffff,
616 	0x00009194, 0x00070000, 0xffffffff,
617 	0x00009198, 0x00030002, 0xffffffff,
618 	0x0000919c, 0x00050004, 0xffffffff,
619 	0x000091a8, 0x00010006, 0xffffffff,
620 	0x000091ac, 0x00090008, 0xffffffff,
621 	0x000091e8, 0x00000000, 0xffffffff,
622 	0x00009294, 0x00000000, 0xffffffff,
623 	0x000008f8, 0x00000010, 0xffffffff,
624 	0x000008fc, 0x00000000, 0xffffffff,
625 	0x000008f8, 0x00000011, 0xffffffff,
626 	0x000008fc, 0x00000000, 0xffffffff,
627 	0x000008f8, 0x00000012, 0xffffffff,
628 	0x000008fc, 0x00000000, 0xffffffff,
629 	0x000008f8, 0x00000013, 0xffffffff,
630 	0x000008fc, 0x00000000, 0xffffffff,
631 	0x000008f8, 0x00000014, 0xffffffff,
632 	0x000008fc, 0x00000000, 0xffffffff,
633 	0x000008f8, 0x00000015, 0xffffffff,
634 	0x000008fc, 0x00000000, 0xffffffff,
635 	0x000008f8, 0x00000016, 0xffffffff,
636 	0x000008fc, 0x00000000, 0xffffffff,
637 	0x000008f8, 0x00000017, 0xffffffff,
638 	0x000008fc, 0x00000000, 0xffffffff,
639 	0x000008f8, 0x00000018, 0xffffffff,
640 	0x000008fc, 0x00000000, 0xffffffff,
641 	0x000008f8, 0x00000019, 0xffffffff,
642 	0x000008fc, 0x00000000, 0xffffffff,
643 	0x000008f8, 0x0000001a, 0xffffffff,
644 	0x000008fc, 0x00000000, 0xffffffff,
645 	0x000008f8, 0x0000001b, 0xffffffff,
646 	0x000008fc, 0x00000000, 0xffffffff
647 };
648 #define CAICOS_MGCG_DEFAULT_LENGTH sizeof(caicos_mgcg_default) / (3 * sizeof(u32))
649 
650 static const u32 caicos_mgcg_disable[] =
651 {
652 	0x0000802c, 0xc0000000, 0xffffffff,
653 	0x000008f8, 0x00000000, 0xffffffff,
654 	0x000008fc, 0xffffffff, 0xffffffff,
655 	0x000008f8, 0x00000001, 0xffffffff,
656 	0x000008fc, 0xffffffff, 0xffffffff,
657 	0x000008f8, 0x00000002, 0xffffffff,
658 	0x000008fc, 0xffffffff, 0xffffffff,
659 	0x000008f8, 0x00000003, 0xffffffff,
660 	0x000008fc, 0xffffffff, 0xffffffff,
661 	0x00009150, 0x00600000, 0xffffffff
662 };
663 #define CAICOS_MGCG_DISABLE_LENGTH sizeof(caicos_mgcg_disable) / (3 * sizeof(u32))
664 
665 static const u32 caicos_mgcg_enable[] =
666 {
667 	0x0000802c, 0xc0000000, 0xffffffff,
668 	0x000008f8, 0x00000000, 0xffffffff,
669 	0x000008fc, 0x00000000, 0xffffffff,
670 	0x000008f8, 0x00000001, 0xffffffff,
671 	0x000008fc, 0x00000000, 0xffffffff,
672 	0x000008f8, 0x00000002, 0xffffffff,
673 	0x000008fc, 0x00000000, 0xffffffff,
674 	0x000008f8, 0x00000003, 0xffffffff,
675 	0x000008fc, 0x00000000, 0xffffffff,
676 	0x00009150, 0x46944040, 0xffffffff
677 };
678 #define CAICOS_MGCG_ENABLE_LENGTH sizeof(caicos_mgcg_enable) / (3 * sizeof(u32))
679 
680 //********* TURKS **************//
681 static const u32 turks_cgcg_cgls_default[] =
682 {
683 	0x000008f8, 0x00000010, 0xffffffff,
684 	0x000008fc, 0x00000000, 0xffffffff,
685 	0x000008f8, 0x00000011, 0xffffffff,
686 	0x000008fc, 0x00000000, 0xffffffff,
687 	0x000008f8, 0x00000012, 0xffffffff,
688 	0x000008fc, 0x00000000, 0xffffffff,
689 	0x000008f8, 0x00000013, 0xffffffff,
690 	0x000008fc, 0x00000000, 0xffffffff,
691 	0x000008f8, 0x00000014, 0xffffffff,
692 	0x000008fc, 0x00000000, 0xffffffff,
693 	0x000008f8, 0x00000015, 0xffffffff,
694 	0x000008fc, 0x00000000, 0xffffffff,
695 	0x000008f8, 0x00000016, 0xffffffff,
696 	0x000008fc, 0x00000000, 0xffffffff,
697 	0x000008f8, 0x00000017, 0xffffffff,
698 	0x000008fc, 0x00000000, 0xffffffff,
699 	0x000008f8, 0x00000018, 0xffffffff,
700 	0x000008fc, 0x00000000, 0xffffffff,
701 	0x000008f8, 0x00000019, 0xffffffff,
702 	0x000008fc, 0x00000000, 0xffffffff,
703 	0x000008f8, 0x0000001a, 0xffffffff,
704 	0x000008fc, 0x00000000, 0xffffffff,
705 	0x000008f8, 0x0000001b, 0xffffffff,
706 	0x000008fc, 0x00000000, 0xffffffff,
707 	0x000008f8, 0x00000020, 0xffffffff,
708 	0x000008fc, 0x00000000, 0xffffffff,
709 	0x000008f8, 0x00000021, 0xffffffff,
710 	0x000008fc, 0x00000000, 0xffffffff,
711 	0x000008f8, 0x00000022, 0xffffffff,
712 	0x000008fc, 0x00000000, 0xffffffff,
713 	0x000008f8, 0x00000023, 0xffffffff,
714 	0x000008fc, 0x00000000, 0xffffffff,
715 	0x000008f8, 0x00000024, 0xffffffff,
716 	0x000008fc, 0x00000000, 0xffffffff,
717 	0x000008f8, 0x00000025, 0xffffffff,
718 	0x000008fc, 0x00000000, 0xffffffff,
719 	0x000008f8, 0x00000026, 0xffffffff,
720 	0x000008fc, 0x00000000, 0xffffffff,
721 	0x000008f8, 0x00000027, 0xffffffff,
722 	0x000008fc, 0x00000000, 0xffffffff,
723 	0x000008f8, 0x00000028, 0xffffffff,
724 	0x000008fc, 0x00000000, 0xffffffff,
725 	0x000008f8, 0x00000029, 0xffffffff,
726 	0x000008fc, 0x00000000, 0xffffffff,
727 	0x000008f8, 0x0000002a, 0xffffffff,
728 	0x000008fc, 0x00000000, 0xffffffff,
729 	0x000008f8, 0x0000002b, 0xffffffff,
730 	0x000008fc, 0x00000000, 0xffffffff
731 };
732 #define TURKS_CGCG_CGLS_DEFAULT_LENGTH  sizeof(turks_cgcg_cgls_default) / (3 * sizeof(u32))
733 
734 static const u32 turks_cgcg_cgls_disable[] =
735 {
736 	0x000008f8, 0x00000010, 0xffffffff,
737 	0x000008fc, 0xffffffff, 0xffffffff,
738 	0x000008f8, 0x00000011, 0xffffffff,
739 	0x000008fc, 0xffffffff, 0xffffffff,
740 	0x000008f8, 0x00000012, 0xffffffff,
741 	0x000008fc, 0xffffffff, 0xffffffff,
742 	0x000008f8, 0x00000013, 0xffffffff,
743 	0x000008fc, 0xffffffff, 0xffffffff,
744 	0x000008f8, 0x00000014, 0xffffffff,
745 	0x000008fc, 0xffffffff, 0xffffffff,
746 	0x000008f8, 0x00000015, 0xffffffff,
747 	0x000008fc, 0xffffffff, 0xffffffff,
748 	0x000008f8, 0x00000016, 0xffffffff,
749 	0x000008fc, 0xffffffff, 0xffffffff,
750 	0x000008f8, 0x00000017, 0xffffffff,
751 	0x000008fc, 0xffffffff, 0xffffffff,
752 	0x000008f8, 0x00000018, 0xffffffff,
753 	0x000008fc, 0xffffffff, 0xffffffff,
754 	0x000008f8, 0x00000019, 0xffffffff,
755 	0x000008fc, 0xffffffff, 0xffffffff,
756 	0x000008f8, 0x0000001a, 0xffffffff,
757 	0x000008fc, 0xffffffff, 0xffffffff,
758 	0x000008f8, 0x0000001b, 0xffffffff,
759 	0x000008fc, 0xffffffff, 0xffffffff,
760 	0x000008f8, 0x00000020, 0xffffffff,
761 	0x000008fc, 0x00000000, 0xffffffff,
762 	0x000008f8, 0x00000021, 0xffffffff,
763 	0x000008fc, 0x00000000, 0xffffffff,
764 	0x000008f8, 0x00000022, 0xffffffff,
765 	0x000008fc, 0x00000000, 0xffffffff,
766 	0x000008f8, 0x00000023, 0xffffffff,
767 	0x000008fc, 0x00000000, 0xffffffff,
768 	0x000008f8, 0x00000024, 0xffffffff,
769 	0x000008fc, 0x00000000, 0xffffffff,
770 	0x000008f8, 0x00000025, 0xffffffff,
771 	0x000008fc, 0x00000000, 0xffffffff,
772 	0x000008f8, 0x00000026, 0xffffffff,
773 	0x000008fc, 0x00000000, 0xffffffff,
774 	0x000008f8, 0x00000027, 0xffffffff,
775 	0x000008fc, 0x00000000, 0xffffffff,
776 	0x000008f8, 0x00000028, 0xffffffff,
777 	0x000008fc, 0x00000000, 0xffffffff,
778 	0x000008f8, 0x00000029, 0xffffffff,
779 	0x000008fc, 0x00000000, 0xffffffff,
780 	0x000008f8, 0x0000002a, 0xffffffff,
781 	0x000008fc, 0x00000000, 0xffffffff,
782 	0x000008f8, 0x0000002b, 0xffffffff,
783 	0x000008fc, 0x00000000, 0xffffffff,
784 	0x00000644, 0x000f7912, 0x001f4180,
785 	0x00000644, 0x000f3812, 0x001f4180
786 };
787 #define TURKS_CGCG_CGLS_DISABLE_LENGTH sizeof(turks_cgcg_cgls_disable) / (3 * sizeof(u32))
788 
789 static const u32 turks_cgcg_cgls_enable[] =
790 {
791 	/* 0x0000c124, 0x84180000, 0x00180000, */
792 	0x00000644, 0x000f7892, 0x001f4080,
793 	0x000008f8, 0x00000010, 0xffffffff,
794 	0x000008fc, 0x00000000, 0xffffffff,
795 	0x000008f8, 0x00000011, 0xffffffff,
796 	0x000008fc, 0x00000000, 0xffffffff,
797 	0x000008f8, 0x00000012, 0xffffffff,
798 	0x000008fc, 0x00000000, 0xffffffff,
799 	0x000008f8, 0x00000013, 0xffffffff,
800 	0x000008fc, 0x00000000, 0xffffffff,
801 	0x000008f8, 0x00000014, 0xffffffff,
802 	0x000008fc, 0x00000000, 0xffffffff,
803 	0x000008f8, 0x00000015, 0xffffffff,
804 	0x000008fc, 0x00000000, 0xffffffff,
805 	0x000008f8, 0x00000016, 0xffffffff,
806 	0x000008fc, 0x00000000, 0xffffffff,
807 	0x000008f8, 0x00000017, 0xffffffff,
808 	0x000008fc, 0x00000000, 0xffffffff,
809 	0x000008f8, 0x00000018, 0xffffffff,
810 	0x000008fc, 0x00000000, 0xffffffff,
811 	0x000008f8, 0x00000019, 0xffffffff,
812 	0x000008fc, 0x00000000, 0xffffffff,
813 	0x000008f8, 0x0000001a, 0xffffffff,
814 	0x000008fc, 0x00000000, 0xffffffff,
815 	0x000008f8, 0x0000001b, 0xffffffff,
816 	0x000008fc, 0x00000000, 0xffffffff,
817 	0x000008f8, 0x00000020, 0xffffffff,
818 	0x000008fc, 0xffffffff, 0xffffffff,
819 	0x000008f8, 0x00000021, 0xffffffff,
820 	0x000008fc, 0xffffffff, 0xffffffff,
821 	0x000008f8, 0x00000022, 0xffffffff,
822 	0x000008fc, 0xffffffff, 0xffffffff,
823 	0x000008f8, 0x00000023, 0xffffffff,
824 	0x000008fc, 0xffffffff, 0xffffffff,
825 	0x000008f8, 0x00000024, 0xffffffff,
826 	0x000008fc, 0xffffffff, 0xffffffff,
827 	0x000008f8, 0x00000025, 0xffffffff,
828 	0x000008fc, 0xffffffff, 0xffffffff,
829 	0x000008f8, 0x00000026, 0xffffffff,
830 	0x000008fc, 0xffffffff, 0xffffffff,
831 	0x000008f8, 0x00000027, 0xffffffff,
832 	0x000008fc, 0xffffffff, 0xffffffff,
833 	0x000008f8, 0x00000028, 0xffffffff,
834 	0x000008fc, 0xffffffff, 0xffffffff,
835 	0x000008f8, 0x00000029, 0xffffffff,
836 	0x000008fc, 0xffffffff, 0xffffffff,
837 	0x000008f8, 0x0000002a, 0xffffffff,
838 	0x000008fc, 0xffffffff, 0xffffffff,
839 	0x000008f8, 0x0000002b, 0xffffffff,
840 	0x000008fc, 0xffffffff, 0xffffffff
841 };
842 #define TURKS_CGCG_CGLS_ENABLE_LENGTH sizeof(turks_cgcg_cgls_enable) / (3 * sizeof(u32))
843 
844 // These are the sequences for turks_mgcg_shls
845 static const u32 turks_mgcg_default[] =
846 {
847 	0x0000802c, 0xc0000000, 0xffffffff,
848 	0x00005448, 0x00000100, 0xffffffff,
849 	0x000055e4, 0x00600100, 0xffffffff,
850 	0x0000160c, 0x00000100, 0xffffffff,
851 	0x0000c164, 0x00000100, 0xffffffff,
852 	0x00008a18, 0x00000100, 0xffffffff,
853 	0x0000897c, 0x06000100, 0xffffffff,
854 	0x00008b28, 0x00000100, 0xffffffff,
855 	0x00009144, 0x00000100, 0xffffffff,
856 	0x00009a60, 0x00000100, 0xffffffff,
857 	0x00009868, 0x00000100, 0xffffffff,
858 	0x00008d58, 0x00000100, 0xffffffff,
859 	0x00009510, 0x00000100, 0xffffffff,
860 	0x0000949c, 0x00000100, 0xffffffff,
861 	0x00009654, 0x00000100, 0xffffffff,
862 	0x00009030, 0x00000100, 0xffffffff,
863 	0x00009034, 0x00000100, 0xffffffff,
864 	0x00009038, 0x00000100, 0xffffffff,
865 	0x0000903c, 0x00000100, 0xffffffff,
866 	0x00009040, 0x00000100, 0xffffffff,
867 	0x0000a200, 0x00000100, 0xffffffff,
868 	0x0000a204, 0x00000100, 0xffffffff,
869 	0x0000a208, 0x00000100, 0xffffffff,
870 	0x0000a20c, 0x00000100, 0xffffffff,
871 	0x0000977c, 0x00000100, 0xffffffff,
872 	0x00003f80, 0x00000100, 0xffffffff,
873 	0x0000a210, 0x00000100, 0xffffffff,
874 	0x0000a214, 0x00000100, 0xffffffff,
875 	0x000004d8, 0x00000100, 0xffffffff,
876 	0x00009784, 0x00000100, 0xffffffff,
877 	0x00009698, 0x00000100, 0xffffffff,
878 	0x000004d4, 0x00000200, 0xffffffff,
879 	0x000004d0, 0x00000000, 0xffffffff,
880 	0x000030cc, 0x00000100, 0xffffffff,
881 	0x0000d0c0, 0x00000100, 0xffffffff,
882 	0x0000915c, 0x00010000, 0xffffffff,
883 	0x00009160, 0x00030002, 0xffffffff,
884 	0x00009164, 0x00050004, 0xffffffff,
885 	0x00009168, 0x00070006, 0xffffffff,
886 	0x00009178, 0x00070000, 0xffffffff,
887 	0x0000917c, 0x00030002, 0xffffffff,
888 	0x00009180, 0x00050004, 0xffffffff,
889 	0x0000918c, 0x00010006, 0xffffffff,
890 	0x00009190, 0x00090008, 0xffffffff,
891 	0x00009194, 0x00070000, 0xffffffff,
892 	0x00009198, 0x00030002, 0xffffffff,
893 	0x0000919c, 0x00050004, 0xffffffff,
894 	0x000091a8, 0x00010006, 0xffffffff,
895 	0x000091ac, 0x00090008, 0xffffffff,
896 	0x000091b0, 0x00070000, 0xffffffff,
897 	0x000091b4, 0x00030002, 0xffffffff,
898 	0x000091b8, 0x00050004, 0xffffffff,
899 	0x000091c4, 0x00010006, 0xffffffff,
900 	0x000091c8, 0x00090008, 0xffffffff,
901 	0x000091cc, 0x00070000, 0xffffffff,
902 	0x000091d0, 0x00030002, 0xffffffff,
903 	0x000091d4, 0x00050004, 0xffffffff,
904 	0x000091e0, 0x00010006, 0xffffffff,
905 	0x000091e4, 0x00090008, 0xffffffff,
906 	0x000091e8, 0x00000000, 0xffffffff,
907 	0x000091ec, 0x00070000, 0xffffffff,
908 	0x000091f0, 0x00030002, 0xffffffff,
909 	0x000091f4, 0x00050004, 0xffffffff,
910 	0x00009200, 0x00010006, 0xffffffff,
911 	0x00009204, 0x00090008, 0xffffffff,
912 	0x00009208, 0x00070000, 0xffffffff,
913 	0x0000920c, 0x00030002, 0xffffffff,
914 	0x00009210, 0x00050004, 0xffffffff,
915 	0x0000921c, 0x00010006, 0xffffffff,
916 	0x00009220, 0x00090008, 0xffffffff,
917 	0x00009294, 0x00000000, 0xffffffff,
918 	0x000008f8, 0x00000010, 0xffffffff,
919 	0x000008fc, 0x00000000, 0xffffffff,
920 	0x000008f8, 0x00000011, 0xffffffff,
921 	0x000008fc, 0x00000000, 0xffffffff,
922 	0x000008f8, 0x00000012, 0xffffffff,
923 	0x000008fc, 0x00000000, 0xffffffff,
924 	0x000008f8, 0x00000013, 0xffffffff,
925 	0x000008fc, 0x00000000, 0xffffffff,
926 	0x000008f8, 0x00000014, 0xffffffff,
927 	0x000008fc, 0x00000000, 0xffffffff,
928 	0x000008f8, 0x00000015, 0xffffffff,
929 	0x000008fc, 0x00000000, 0xffffffff,
930 	0x000008f8, 0x00000016, 0xffffffff,
931 	0x000008fc, 0x00000000, 0xffffffff,
932 	0x000008f8, 0x00000017, 0xffffffff,
933 	0x000008fc, 0x00000000, 0xffffffff,
934 	0x000008f8, 0x00000018, 0xffffffff,
935 	0x000008fc, 0x00000000, 0xffffffff,
936 	0x000008f8, 0x00000019, 0xffffffff,
937 	0x000008fc, 0x00000000, 0xffffffff,
938 	0x000008f8, 0x0000001a, 0xffffffff,
939 	0x000008fc, 0x00000000, 0xffffffff,
940 	0x000008f8, 0x0000001b, 0xffffffff,
941 	0x000008fc, 0x00000000, 0xffffffff
942 };
943 #define TURKS_MGCG_DEFAULT_LENGTH sizeof(turks_mgcg_default) / (3 * sizeof(u32))
944 
945 static const u32 turks_mgcg_disable[] =
946 {
947 	0x0000802c, 0xc0000000, 0xffffffff,
948 	0x000008f8, 0x00000000, 0xffffffff,
949 	0x000008fc, 0xffffffff, 0xffffffff,
950 	0x000008f8, 0x00000001, 0xffffffff,
951 	0x000008fc, 0xffffffff, 0xffffffff,
952 	0x000008f8, 0x00000002, 0xffffffff,
953 	0x000008fc, 0xffffffff, 0xffffffff,
954 	0x000008f8, 0x00000003, 0xffffffff,
955 	0x000008fc, 0xffffffff, 0xffffffff,
956 	0x00009150, 0x00600000, 0xffffffff
957 };
958 #define TURKS_MGCG_DISABLE_LENGTH sizeof(turks_mgcg_disable) / (3 * sizeof(u32))
959 
960 static const u32 turks_mgcg_enable[] =
961 {
962 	0x0000802c, 0xc0000000, 0xffffffff,
963 	0x000008f8, 0x00000000, 0xffffffff,
964 	0x000008fc, 0x00000000, 0xffffffff,
965 	0x000008f8, 0x00000001, 0xffffffff,
966 	0x000008fc, 0x00000000, 0xffffffff,
967 	0x000008f8, 0x00000002, 0xffffffff,
968 	0x000008fc, 0x00000000, 0xffffffff,
969 	0x000008f8, 0x00000003, 0xffffffff,
970 	0x000008fc, 0x00000000, 0xffffffff,
971 	0x00009150, 0x6e944000, 0xffffffff
972 };
973 #define TURKS_MGCG_ENABLE_LENGTH sizeof(turks_mgcg_enable) / (3 * sizeof(u32))
974 
975 #endif
976 
977 #ifndef BTC_SYSLS_SEQUENCE
978 #define BTC_SYSLS_SEQUENCE  100
979 
980 
981 //********* BARTS **************//
982 static const u32 barts_sysls_default[] =
983 {
984 	/* Register,   Value,     Mask bits */
985 	0x000055e8, 0x00000000, 0xffffffff,
986 	0x0000d0bc, 0x00000000, 0xffffffff,
987 	0x000015c0, 0x000c1401, 0xffffffff,
988 	0x0000264c, 0x000c0400, 0xffffffff,
989 	0x00002648, 0x000c0400, 0xffffffff,
990 	0x00002650, 0x000c0400, 0xffffffff,
991 	0x000020b8, 0x000c0400, 0xffffffff,
992 	0x000020bc, 0x000c0400, 0xffffffff,
993 	0x000020c0, 0x000c0c80, 0xffffffff,
994 	0x0000f4a0, 0x000000c0, 0xffffffff,
995 	0x0000f4a4, 0x00680fff, 0xffffffff,
996 	0x000004c8, 0x00000001, 0xffffffff,
997 	0x000064ec, 0x00000000, 0xffffffff,
998 	0x00000c7c, 0x00000000, 0xffffffff,
999 	0x00006dfc, 0x00000000, 0xffffffff
1000 };
1001 #define BARTS_SYSLS_DEFAULT_LENGTH sizeof(barts_sysls_default) / (3 * sizeof(u32))
1002 
1003 static const u32 barts_sysls_disable[] =
1004 {
1005 	0x000055e8, 0x00000000, 0xffffffff,
1006 	0x0000d0bc, 0x00000000, 0xffffffff,
1007 	0x000015c0, 0x00041401, 0xffffffff,
1008 	0x0000264c, 0x00040400, 0xffffffff,
1009 	0x00002648, 0x00040400, 0xffffffff,
1010 	0x00002650, 0x00040400, 0xffffffff,
1011 	0x000020b8, 0x00040400, 0xffffffff,
1012 	0x000020bc, 0x00040400, 0xffffffff,
1013 	0x000020c0, 0x00040c80, 0xffffffff,
1014 	0x0000f4a0, 0x000000c0, 0xffffffff,
1015 	0x0000f4a4, 0x00680000, 0xffffffff,
1016 	0x000004c8, 0x00000001, 0xffffffff,
1017 	0x000064ec, 0x00007ffd, 0xffffffff,
1018 	0x00000c7c, 0x0000ff00, 0xffffffff,
1019 	0x00006dfc, 0x0000007f, 0xffffffff
1020 };
1021 #define BARTS_SYSLS_DISABLE_LENGTH sizeof(barts_sysls_disable) / (3 * sizeof(u32))
1022 
1023 static const u32 barts_sysls_enable[] =
1024 {
1025 	0x000055e8, 0x00000001, 0xffffffff,
1026 	0x0000d0bc, 0x00000100, 0xffffffff,
1027 	0x000015c0, 0x000c1401, 0xffffffff,
1028 	0x0000264c, 0x000c0400, 0xffffffff,
1029 	0x00002648, 0x000c0400, 0xffffffff,
1030 	0x00002650, 0x000c0400, 0xffffffff,
1031 	0x000020b8, 0x000c0400, 0xffffffff,
1032 	0x000020bc, 0x000c0400, 0xffffffff,
1033 	0x000020c0, 0x000c0c80, 0xffffffff,
1034 	0x0000f4a0, 0x000000c0, 0xffffffff,
1035 	0x0000f4a4, 0x00680fff, 0xffffffff,
1036 	0x000004c8, 0x00000000, 0xffffffff,
1037 	0x000064ec, 0x00000000, 0xffffffff,
1038 	0x00000c7c, 0x00000000, 0xffffffff,
1039 	0x00006dfc, 0x00000000, 0xffffffff
1040 };
1041 #define BARTS_SYSLS_ENABLE_LENGTH sizeof(barts_sysls_enable) / (3 * sizeof(u32))
1042 
1043 //********* CAICOS **************//
1044 static const u32 caicos_sysls_default[] =
1045 {
1046 	0x000055e8, 0x00000000, 0xffffffff,
1047 	0x0000d0bc, 0x00000000, 0xffffffff,
1048 	0x000015c0, 0x000c1401, 0xffffffff,
1049 	0x0000264c, 0x000c0400, 0xffffffff,
1050 	0x00002648, 0x000c0400, 0xffffffff,
1051 	0x00002650, 0x000c0400, 0xffffffff,
1052 	0x000020b8, 0x000c0400, 0xffffffff,
1053 	0x000020bc, 0x000c0400, 0xffffffff,
1054 	0x0000f4a0, 0x000000c0, 0xffffffff,
1055 	0x0000f4a4, 0x00680fff, 0xffffffff,
1056 	0x000004c8, 0x00000001, 0xffffffff,
1057 	0x000064ec, 0x00000000, 0xffffffff,
1058 	0x00000c7c, 0x00000000, 0xffffffff,
1059 	0x00006dfc, 0x00000000, 0xffffffff
1060 };
1061 #define CAICOS_SYSLS_DEFAULT_LENGTH sizeof(caicos_sysls_default) / (3 * sizeof(u32))
1062 
1063 static const u32 caicos_sysls_disable[] =
1064 {
1065 	0x000055e8, 0x00000000, 0xffffffff,
1066 	0x0000d0bc, 0x00000000, 0xffffffff,
1067 	0x000015c0, 0x00041401, 0xffffffff,
1068 	0x0000264c, 0x00040400, 0xffffffff,
1069 	0x00002648, 0x00040400, 0xffffffff,
1070 	0x00002650, 0x00040400, 0xffffffff,
1071 	0x000020b8, 0x00040400, 0xffffffff,
1072 	0x000020bc, 0x00040400, 0xffffffff,
1073 	0x0000f4a0, 0x000000c0, 0xffffffff,
1074 	0x0000f4a4, 0x00680000, 0xffffffff,
1075 	0x000004c8, 0x00000001, 0xffffffff,
1076 	0x000064ec, 0x00007ffd, 0xffffffff,
1077 	0x00000c7c, 0x0000ff00, 0xffffffff,
1078 	0x00006dfc, 0x0000007f, 0xffffffff
1079 };
1080 #define CAICOS_SYSLS_DISABLE_LENGTH sizeof(caicos_sysls_disable) / (3 * sizeof(u32))
1081 
1082 static const u32 caicos_sysls_enable[] =
1083 {
1084 	0x000055e8, 0x00000001, 0xffffffff,
1085 	0x0000d0bc, 0x00000100, 0xffffffff,
1086 	0x000015c0, 0x000c1401, 0xffffffff,
1087 	0x0000264c, 0x000c0400, 0xffffffff,
1088 	0x00002648, 0x000c0400, 0xffffffff,
1089 	0x00002650, 0x000c0400, 0xffffffff,
1090 	0x000020b8, 0x000c0400, 0xffffffff,
1091 	0x000020bc, 0x000c0400, 0xffffffff,
1092 	0x0000f4a0, 0x000000c0, 0xffffffff,
1093 	0x0000f4a4, 0x00680fff, 0xffffffff,
1094 	0x000064ec, 0x00000000, 0xffffffff,
1095 	0x00000c7c, 0x00000000, 0xffffffff,
1096 	0x00006dfc, 0x00000000, 0xffffffff,
1097 	0x000004c8, 0x00000000, 0xffffffff
1098 };
1099 #define CAICOS_SYSLS_ENABLE_LENGTH sizeof(caicos_sysls_enable) / (3 * sizeof(u32))
1100 
1101 //********* TURKS **************//
1102 static const u32 turks_sysls_default[] =
1103 {
1104 	0x000055e8, 0x00000000, 0xffffffff,
1105 	0x0000d0bc, 0x00000000, 0xffffffff,
1106 	0x000015c0, 0x000c1401, 0xffffffff,
1107 	0x0000264c, 0x000c0400, 0xffffffff,
1108 	0x00002648, 0x000c0400, 0xffffffff,
1109 	0x00002650, 0x000c0400, 0xffffffff,
1110 	0x000020b8, 0x000c0400, 0xffffffff,
1111 	0x000020bc, 0x000c0400, 0xffffffff,
1112 	0x000020c0, 0x000c0c80, 0xffffffff,
1113 	0x0000f4a0, 0x000000c0, 0xffffffff,
1114 	0x0000f4a4, 0x00680fff, 0xffffffff,
1115 	0x000004c8, 0x00000001, 0xffffffff,
1116 	0x000064ec, 0x00000000, 0xffffffff,
1117 	0x00000c7c, 0x00000000, 0xffffffff,
1118 	0x00006dfc, 0x00000000, 0xffffffff
1119 };
1120 #define TURKS_SYSLS_DEFAULT_LENGTH sizeof(turks_sysls_default) / (3 * sizeof(u32))
1121 
1122 static const u32 turks_sysls_disable[] =
1123 {
1124 	0x000055e8, 0x00000000, 0xffffffff,
1125 	0x0000d0bc, 0x00000000, 0xffffffff,
1126 	0x000015c0, 0x00041401, 0xffffffff,
1127 	0x0000264c, 0x00040400, 0xffffffff,
1128 	0x00002648, 0x00040400, 0xffffffff,
1129 	0x00002650, 0x00040400, 0xffffffff,
1130 	0x000020b8, 0x00040400, 0xffffffff,
1131 	0x000020bc, 0x00040400, 0xffffffff,
1132 	0x000020c0, 0x00040c80, 0xffffffff,
1133 	0x0000f4a0, 0x000000c0, 0xffffffff,
1134 	0x0000f4a4, 0x00680000, 0xffffffff,
1135 	0x000004c8, 0x00000001, 0xffffffff,
1136 	0x000064ec, 0x00007ffd, 0xffffffff,
1137 	0x00000c7c, 0x0000ff00, 0xffffffff,
1138 	0x00006dfc, 0x0000007f, 0xffffffff
1139 };
1140 #define TURKS_SYSLS_DISABLE_LENGTH sizeof(turks_sysls_disable) / (3 * sizeof(u32))
1141 
1142 static const u32 turks_sysls_enable[] =
1143 {
1144 	0x000055e8, 0x00000001, 0xffffffff,
1145 	0x0000d0bc, 0x00000100, 0xffffffff,
1146 	0x000015c0, 0x000c1401, 0xffffffff,
1147 	0x0000264c, 0x000c0400, 0xffffffff,
1148 	0x00002648, 0x000c0400, 0xffffffff,
1149 	0x00002650, 0x000c0400, 0xffffffff,
1150 	0x000020b8, 0x000c0400, 0xffffffff,
1151 	0x000020bc, 0x000c0400, 0xffffffff,
1152 	0x000020c0, 0x000c0c80, 0xffffffff,
1153 	0x0000f4a0, 0x000000c0, 0xffffffff,
1154 	0x0000f4a4, 0x00680fff, 0xffffffff,
1155 	0x000004c8, 0x00000000, 0xffffffff,
1156 	0x000064ec, 0x00000000, 0xffffffff,
1157 	0x00000c7c, 0x00000000, 0xffffffff,
1158 	0x00006dfc, 0x00000000, 0xffffffff
1159 };
1160 #define TURKS_SYSLS_ENABLE_LENGTH sizeof(turks_sysls_enable) / (3 * sizeof(u32))
1161 
1162 #endif
1163 
1164 u32 btc_valid_sclk[40] =
1165 {
1166 	5000,   10000,  15000,  20000,  25000,  30000,  35000,  40000,  45000,  50000,
1167 	55000,  60000,  65000,  70000,  75000,  80000,  85000,  90000,  95000,  100000,
1168 	105000, 110000, 11500,  120000, 125000, 130000, 135000, 140000, 145000, 150000,
1169 	155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000
1170 };
1171 
1172 static const struct radeon_blacklist_clocks btc_blacklist_clocks[] = {
1173 	{ 10000, 30000, RADEON_SCLK_UP },
1174 	{ 15000, 30000, RADEON_SCLK_UP },
1175 	{ 20000, 30000, RADEON_SCLK_UP },
1176 	{ 25000, 30000, RADEON_SCLK_UP }
1177 };
1178 
btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table * table,u32 * max_clock)1179 void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table,
1180 						     u32 *max_clock)
1181 {
1182 	u32 i, clock = 0;
1183 
1184 	if ((table == NULL) || (table->count == 0)) {
1185 		*max_clock = clock;
1186 		return;
1187 	}
1188 
1189 	for (i = 0; i < table->count; i++) {
1190 		if (clock < table->entries[i].clk)
1191 			clock = table->entries[i].clk;
1192 	}
1193 	*max_clock = clock;
1194 }
1195 
btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table * table,u32 clock,u16 max_voltage,u16 * voltage)1196 void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
1197 					u32 clock, u16 max_voltage, u16 *voltage)
1198 {
1199 	u32 i;
1200 
1201 	if ((table == NULL) || (table->count == 0))
1202 		return;
1203 
1204 	for (i= 0; i < table->count; i++) {
1205 		if (clock <= table->entries[i].clk) {
1206 			if (*voltage < table->entries[i].v)
1207 				*voltage = (u16)((table->entries[i].v < max_voltage) ?
1208 						  table->entries[i].v : max_voltage);
1209 			return;
1210 		}
1211 	}
1212 
1213 	*voltage = (*voltage > max_voltage) ? *voltage : max_voltage;
1214 }
1215 
btc_find_valid_clock(struct radeon_clock_array * clocks,u32 max_clock,u32 requested_clock)1216 static u32 btc_find_valid_clock(struct radeon_clock_array *clocks,
1217 				u32 max_clock, u32 requested_clock)
1218 {
1219 	unsigned int i;
1220 
1221 	if ((clocks == NULL) || (clocks->count == 0))
1222 		return (requested_clock < max_clock) ? requested_clock : max_clock;
1223 
1224 	for (i = 0; i < clocks->count; i++) {
1225 		if (clocks->values[i] >= requested_clock)
1226 			return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock;
1227 	}
1228 
1229 	return (clocks->values[clocks->count - 1] < max_clock) ?
1230 		clocks->values[clocks->count - 1] : max_clock;
1231 }
1232 
btc_get_valid_mclk(struct radeon_device * rdev,u32 max_mclk,u32 requested_mclk)1233 static u32 btc_get_valid_mclk(struct radeon_device *rdev,
1234 			      u32 max_mclk, u32 requested_mclk)
1235 {
1236 	return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_mclk_values,
1237 				    max_mclk, requested_mclk);
1238 }
1239 
btc_get_valid_sclk(struct radeon_device * rdev,u32 max_sclk,u32 requested_sclk)1240 static u32 btc_get_valid_sclk(struct radeon_device *rdev,
1241 			      u32 max_sclk, u32 requested_sclk)
1242 {
1243 	return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_sclk_values,
1244 				    max_sclk, requested_sclk);
1245 }
1246 
btc_skip_blacklist_clocks(struct radeon_device * rdev,const u32 max_sclk,const u32 max_mclk,u32 * sclk,u32 * mclk)1247 void btc_skip_blacklist_clocks(struct radeon_device *rdev,
1248 			       const u32 max_sclk, const u32 max_mclk,
1249 			       u32 *sclk, u32 *mclk)
1250 {
1251 	int i, num_blacklist_clocks;
1252 
1253 	if ((sclk == NULL) || (mclk == NULL))
1254 		return;
1255 
1256 	num_blacklist_clocks = ARRAY_SIZE(btc_blacklist_clocks);
1257 
1258 	for (i = 0; i < num_blacklist_clocks; i++) {
1259 		if ((btc_blacklist_clocks[i].sclk == *sclk) &&
1260 		    (btc_blacklist_clocks[i].mclk == *mclk))
1261 			break;
1262 	}
1263 
1264 	if (i < num_blacklist_clocks) {
1265 		if (btc_blacklist_clocks[i].action == RADEON_SCLK_UP) {
1266 			*sclk = btc_get_valid_sclk(rdev, max_sclk, *sclk + 1);
1267 
1268 			if (*sclk < max_sclk)
1269 				btc_skip_blacklist_clocks(rdev, max_sclk, max_mclk, sclk, mclk);
1270 		}
1271 	}
1272 }
1273 
btc_adjust_clock_combinations(struct radeon_device * rdev,const struct radeon_clock_and_voltage_limits * max_limits,struct rv7xx_pl * pl)1274 void btc_adjust_clock_combinations(struct radeon_device *rdev,
1275 				   const struct radeon_clock_and_voltage_limits *max_limits,
1276 				   struct rv7xx_pl *pl)
1277 {
1278 
1279 	if ((pl->mclk == 0) || (pl->sclk == 0))
1280 		return;
1281 
1282 	if (pl->mclk == pl->sclk)
1283 		return;
1284 
1285 	if (pl->mclk > pl->sclk) {
1286 		if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > rdev->pm.dpm.dyn_state.mclk_sclk_ratio)
1287 			pl->sclk = btc_get_valid_sclk(rdev,
1288 						      max_limits->sclk,
1289 						      (pl->mclk +
1290 						       (rdev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) /
1291 						      rdev->pm.dpm.dyn_state.mclk_sclk_ratio);
1292 	} else {
1293 		if ((pl->sclk - pl->mclk) > rdev->pm.dpm.dyn_state.sclk_mclk_delta)
1294 			pl->mclk = btc_get_valid_mclk(rdev,
1295 						      max_limits->mclk,
1296 						      pl->sclk -
1297 						      rdev->pm.dpm.dyn_state.sclk_mclk_delta);
1298 	}
1299 }
1300 
btc_find_voltage(struct atom_voltage_table * table,u16 voltage)1301 static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)
1302 {
1303 	unsigned int i;
1304 
1305 	for (i = 0; i < table->count; i++) {
1306 		if (voltage <= table->entries[i].value)
1307 			return table->entries[i].value;
1308 	}
1309 
1310 	return table->entries[table->count - 1].value;
1311 }
1312 
btc_apply_voltage_delta_rules(struct radeon_device * rdev,u16 max_vddc,u16 max_vddci,u16 * vddc,u16 * vddci)1313 void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
1314 				   u16 max_vddc, u16 max_vddci,
1315 				   u16 *vddc, u16 *vddci)
1316 {
1317 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1318 	u16 new_voltage;
1319 
1320 	if ((0 == *vddc) || (0 == *vddci))
1321 		return;
1322 
1323 	if (*vddc > *vddci) {
1324 		if ((*vddc - *vddci) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
1325 			new_voltage = btc_find_voltage(&eg_pi->vddci_voltage_table,
1326 						       (*vddc - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
1327 			*vddci = (new_voltage < max_vddci) ? new_voltage : max_vddci;
1328 		}
1329 	} else {
1330 		if ((*vddci - *vddc) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
1331 			new_voltage = btc_find_voltage(&eg_pi->vddc_voltage_table,
1332 						       (*vddci - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
1333 			*vddc = (new_voltage < max_vddc) ? new_voltage : max_vddc;
1334 		}
1335 	}
1336 }
1337 
btc_enable_bif_dynamic_pcie_gen2(struct radeon_device * rdev,bool enable)1338 static void btc_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
1339 					     bool enable)
1340 {
1341 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1342 	u32 tmp, bif;
1343 
1344 	tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
1345 	if (enable) {
1346 		if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
1347 		    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
1348 			if (!pi->boot_in_gen2) {
1349 				bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
1350 				bif |= CG_CLIENT_REQ(0xd);
1351 				WREG32(CG_BIF_REQ_AND_RSP, bif);
1352 
1353 				tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
1354 				tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
1355 				tmp |= LC_GEN2_EN_STRAP;
1356 
1357 				tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT;
1358 				WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1359 				udelay(10);
1360 				tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
1361 				WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1362 			}
1363 		}
1364 	} else {
1365 		if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
1366 		    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
1367 			if (!pi->boot_in_gen2) {
1368 				bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
1369 				bif |= CG_CLIENT_REQ(0xd);
1370 				WREG32(CG_BIF_REQ_AND_RSP, bif);
1371 
1372 				tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
1373 				tmp &= ~LC_GEN2_EN_STRAP;
1374 			}
1375 			WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1376 		}
1377 	}
1378 }
1379 
btc_enable_dynamic_pcie_gen2(struct radeon_device * rdev,bool enable)1380 static void btc_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
1381 					 bool enable)
1382 {
1383 	btc_enable_bif_dynamic_pcie_gen2(rdev, enable);
1384 
1385 	if (enable)
1386 		WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
1387 	else
1388 		WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
1389 }
1390 
btc_disable_ulv(struct radeon_device * rdev)1391 static int btc_disable_ulv(struct radeon_device *rdev)
1392 {
1393 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1394 
1395 	if (eg_pi->ulv.supported) {
1396 		if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_DisableULV) != PPSMC_Result_OK)
1397 			return -EINVAL;
1398 	}
1399 	return 0;
1400 }
1401 
btc_populate_ulv_state(struct radeon_device * rdev,RV770_SMC_STATETABLE * table)1402 static int btc_populate_ulv_state(struct radeon_device *rdev,
1403 				  RV770_SMC_STATETABLE *table)
1404 {
1405 	int ret = -EINVAL;
1406 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1407 	struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1408 
1409 	if (ulv_pl->vddc) {
1410 		ret = cypress_convert_power_level_to_smc(rdev,
1411 							 ulv_pl,
1412 							 &table->ULVState.levels[0],
1413 							 PPSMC_DISPLAY_WATERMARK_LOW);
1414 		if (ret == 0) {
1415 			table->ULVState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
1416 			table->ULVState.levels[0].ACIndex = 1;
1417 
1418 			table->ULVState.levels[1] = table->ULVState.levels[0];
1419 			table->ULVState.levels[2] = table->ULVState.levels[0];
1420 
1421 			table->ULVState.flags |= PPSMC_SWSTATE_FLAG_DC;
1422 
1423 			WREG32(CG_ULV_CONTROL, BTC_CGULVCONTROL_DFLT);
1424 			WREG32(CG_ULV_PARAMETER, BTC_CGULVPARAMETER_DFLT);
1425 		}
1426 	}
1427 
1428 	return ret;
1429 }
1430 
btc_populate_smc_acpi_state(struct radeon_device * rdev,RV770_SMC_STATETABLE * table)1431 static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
1432 				       RV770_SMC_STATETABLE *table)
1433 {
1434 	int ret = cypress_populate_smc_acpi_state(rdev, table);
1435 
1436 	if (ret == 0) {
1437 		table->ACPIState.levels[0].ACIndex = 0;
1438 		table->ACPIState.levels[1].ACIndex = 0;
1439 		table->ACPIState.levels[2].ACIndex = 0;
1440 	}
1441 
1442 	return ret;
1443 }
1444 
btc_program_mgcg_hw_sequence(struct radeon_device * rdev,const u32 * sequence,u32 count)1445 void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
1446 				  const u32 *sequence, u32 count)
1447 {
1448 	u32 i, length = count * 3;
1449 	u32 tmp;
1450 
1451 	for (i = 0; i < length; i+=3) {
1452 		tmp = RREG32(sequence[i]);
1453 		tmp &= ~sequence[i+2];
1454 		tmp |= sequence[i+1] & sequence[i+2];
1455 		WREG32(sequence[i], tmp);
1456 	}
1457 }
1458 
btc_cg_clock_gating_default(struct radeon_device * rdev)1459 static void btc_cg_clock_gating_default(struct radeon_device *rdev)
1460 {
1461 	u32 count;
1462 	const u32 *p = NULL;
1463 
1464 	if (rdev->family == CHIP_BARTS) {
1465 		p = (const u32 *)&barts_cgcg_cgls_default;
1466 		count = BARTS_CGCG_CGLS_DEFAULT_LENGTH;
1467 	} else if (rdev->family == CHIP_TURKS) {
1468 		p = (const u32 *)&turks_cgcg_cgls_default;
1469 		count = TURKS_CGCG_CGLS_DEFAULT_LENGTH;
1470 	} else if (rdev->family == CHIP_CAICOS) {
1471 		p = (const u32 *)&caicos_cgcg_cgls_default;
1472 		count = CAICOS_CGCG_CGLS_DEFAULT_LENGTH;
1473 	} else
1474 		return;
1475 
1476 	btc_program_mgcg_hw_sequence(rdev, p, count);
1477 }
1478 
btc_cg_clock_gating_enable(struct radeon_device * rdev,bool enable)1479 static void btc_cg_clock_gating_enable(struct radeon_device *rdev,
1480 				       bool enable)
1481 {
1482 	u32 count;
1483 	const u32 *p = NULL;
1484 
1485 	if (enable) {
1486 		if (rdev->family == CHIP_BARTS) {
1487 			p = (const u32 *)&barts_cgcg_cgls_enable;
1488 			count = BARTS_CGCG_CGLS_ENABLE_LENGTH;
1489 		} else if (rdev->family == CHIP_TURKS) {
1490 			p = (const u32 *)&turks_cgcg_cgls_enable;
1491 			count = TURKS_CGCG_CGLS_ENABLE_LENGTH;
1492 		} else if (rdev->family == CHIP_CAICOS) {
1493 			p = (const u32 *)&caicos_cgcg_cgls_enable;
1494 			count = CAICOS_CGCG_CGLS_ENABLE_LENGTH;
1495 		} else
1496 			return;
1497 	} else {
1498 		if (rdev->family == CHIP_BARTS) {
1499 			p = (const u32 *)&barts_cgcg_cgls_disable;
1500 			count = BARTS_CGCG_CGLS_DISABLE_LENGTH;
1501 		} else if (rdev->family == CHIP_TURKS) {
1502 			p = (const u32 *)&turks_cgcg_cgls_disable;
1503 			count = TURKS_CGCG_CGLS_DISABLE_LENGTH;
1504 		} else if (rdev->family == CHIP_CAICOS) {
1505 			p = (const u32 *)&caicos_cgcg_cgls_disable;
1506 			count = CAICOS_CGCG_CGLS_DISABLE_LENGTH;
1507 		} else
1508 			return;
1509 	}
1510 
1511 	btc_program_mgcg_hw_sequence(rdev, p, count);
1512 }
1513 
btc_mg_clock_gating_default(struct radeon_device * rdev)1514 static void btc_mg_clock_gating_default(struct radeon_device *rdev)
1515 {
1516 	u32 count;
1517 	const u32 *p = NULL;
1518 
1519 	if (rdev->family == CHIP_BARTS) {
1520 		p = (const u32 *)&barts_mgcg_default;
1521 		count = BARTS_MGCG_DEFAULT_LENGTH;
1522 	} else if (rdev->family == CHIP_TURKS) {
1523 		p = (const u32 *)&turks_mgcg_default;
1524 		count = TURKS_MGCG_DEFAULT_LENGTH;
1525 	} else if (rdev->family == CHIP_CAICOS) {
1526 		p = (const u32 *)&caicos_mgcg_default;
1527 		count = CAICOS_MGCG_DEFAULT_LENGTH;
1528 	} else
1529 		return;
1530 
1531 	btc_program_mgcg_hw_sequence(rdev, p, count);
1532 }
1533 
btc_mg_clock_gating_enable(struct radeon_device * rdev,bool enable)1534 static void btc_mg_clock_gating_enable(struct radeon_device *rdev,
1535 				       bool enable)
1536 {
1537 	u32 count;
1538 	const u32 *p = NULL;
1539 
1540 	if (enable) {
1541 		if (rdev->family == CHIP_BARTS) {
1542 			p = (const u32 *)&barts_mgcg_enable;
1543 			count = BARTS_MGCG_ENABLE_LENGTH;
1544 		} else if (rdev->family == CHIP_TURKS) {
1545 			p = (const u32 *)&turks_mgcg_enable;
1546 			count = TURKS_MGCG_ENABLE_LENGTH;
1547 		} else if (rdev->family == CHIP_CAICOS) {
1548 			p = (const u32 *)&caicos_mgcg_enable;
1549 			count = CAICOS_MGCG_ENABLE_LENGTH;
1550 		} else
1551 			return;
1552 	} else {
1553 		if (rdev->family == CHIP_BARTS) {
1554 			p = (const u32 *)&barts_mgcg_disable[0];
1555 			count = BARTS_MGCG_DISABLE_LENGTH;
1556 		} else if (rdev->family == CHIP_TURKS) {
1557 			p = (const u32 *)&turks_mgcg_disable[0];
1558 			count = TURKS_MGCG_DISABLE_LENGTH;
1559 		} else if (rdev->family == CHIP_CAICOS) {
1560 			p = (const u32 *)&caicos_mgcg_disable[0];
1561 			count = CAICOS_MGCG_DISABLE_LENGTH;
1562 		} else
1563 			return;
1564 	}
1565 
1566 	btc_program_mgcg_hw_sequence(rdev, p, count);
1567 }
1568 
btc_ls_clock_gating_default(struct radeon_device * rdev)1569 static void btc_ls_clock_gating_default(struct radeon_device *rdev)
1570 {
1571 	u32 count;
1572 	const u32 *p = NULL;
1573 
1574 	if (rdev->family == CHIP_BARTS) {
1575 		p = (const u32 *)&barts_sysls_default;
1576 		count = BARTS_SYSLS_DEFAULT_LENGTH;
1577 	} else if (rdev->family == CHIP_TURKS) {
1578 		p = (const u32 *)&turks_sysls_default;
1579 		count = TURKS_SYSLS_DEFAULT_LENGTH;
1580 	} else if (rdev->family == CHIP_CAICOS) {
1581 		p = (const u32 *)&caicos_sysls_default;
1582 		count = CAICOS_SYSLS_DEFAULT_LENGTH;
1583 	} else
1584 		return;
1585 
1586 	btc_program_mgcg_hw_sequence(rdev, p, count);
1587 }
1588 
btc_ls_clock_gating_enable(struct radeon_device * rdev,bool enable)1589 static void btc_ls_clock_gating_enable(struct radeon_device *rdev,
1590 				       bool enable)
1591 {
1592 	u32 count;
1593 	const u32 *p = NULL;
1594 
1595 	if (enable) {
1596 		if (rdev->family == CHIP_BARTS) {
1597 			p = (const u32 *)&barts_sysls_enable;
1598 			count = BARTS_SYSLS_ENABLE_LENGTH;
1599 		} else if (rdev->family == CHIP_TURKS) {
1600 			p = (const u32 *)&turks_sysls_enable;
1601 			count = TURKS_SYSLS_ENABLE_LENGTH;
1602 		} else if (rdev->family == CHIP_CAICOS) {
1603 			p = (const u32 *)&caicos_sysls_enable;
1604 			count = CAICOS_SYSLS_ENABLE_LENGTH;
1605 		} else
1606 			return;
1607 	} else {
1608 		if (rdev->family == CHIP_BARTS) {
1609 			p = (const u32 *)&barts_sysls_disable;
1610 			count = BARTS_SYSLS_DISABLE_LENGTH;
1611 		} else if (rdev->family == CHIP_TURKS) {
1612 			p = (const u32 *)&turks_sysls_disable;
1613 			count = TURKS_SYSLS_DISABLE_LENGTH;
1614 		} else if (rdev->family == CHIP_CAICOS) {
1615 			p = (const u32 *)&caicos_sysls_disable;
1616 			count = CAICOS_SYSLS_DISABLE_LENGTH;
1617 		} else
1618 			return;
1619 	}
1620 
1621 	btc_program_mgcg_hw_sequence(rdev, p, count);
1622 }
1623 
btc_dpm_enabled(struct radeon_device * rdev)1624 bool btc_dpm_enabled(struct radeon_device *rdev)
1625 {
1626 	if (rv770_is_smc_running(rdev))
1627 		return true;
1628 	else
1629 		return false;
1630 }
1631 
btc_init_smc_table(struct radeon_device * rdev,struct radeon_ps * radeon_boot_state)1632 static int btc_init_smc_table(struct radeon_device *rdev,
1633 			      struct radeon_ps *radeon_boot_state)
1634 {
1635 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1636 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1637 	RV770_SMC_STATETABLE *table = &pi->smc_statetable;
1638 	int ret;
1639 
1640 	memset(table, 0, sizeof(RV770_SMC_STATETABLE));
1641 
1642 	cypress_populate_smc_voltage_tables(rdev, table);
1643 
1644 	switch (rdev->pm.int_thermal_type) {
1645 	case THERMAL_TYPE_EVERGREEN:
1646 	case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
1647 		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
1648 		break;
1649 	case THERMAL_TYPE_NONE:
1650 		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
1651 		break;
1652 	default:
1653 		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
1654 		break;
1655 	}
1656 
1657 	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
1658 		table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
1659 
1660 	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT)
1661 		table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
1662 
1663 	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
1664 		table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
1665 
1666 	if (pi->mem_gddr5)
1667 		table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
1668 
1669 	ret = cypress_populate_smc_initial_state(rdev, radeon_boot_state, table);
1670 	if (ret)
1671 		return ret;
1672 
1673 	if (eg_pi->sclk_deep_sleep)
1674 		WREG32_P(SCLK_PSKIP_CNTL, PSKIP_ON_ALLOW_STOP_HI(32),
1675 			 ~PSKIP_ON_ALLOW_STOP_HI_MASK);
1676 
1677 	ret = btc_populate_smc_acpi_state(rdev, table);
1678 	if (ret)
1679 		return ret;
1680 
1681 	if (eg_pi->ulv.supported) {
1682 		ret = btc_populate_ulv_state(rdev, table);
1683 		if (ret)
1684 			eg_pi->ulv.supported = false;
1685 	}
1686 
1687 	table->driverState = table->initialState;
1688 
1689 	return rv770_copy_bytes_to_smc(rdev,
1690 				       pi->state_table_start,
1691 				       (u8 *)table,
1692 				       sizeof(RV770_SMC_STATETABLE),
1693 				       pi->sram_end);
1694 }
1695 
btc_set_at_for_uvd(struct radeon_device * rdev,struct radeon_ps * radeon_new_state)1696 static void btc_set_at_for_uvd(struct radeon_device *rdev,
1697 			       struct radeon_ps *radeon_new_state)
1698 {
1699 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1700 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1701 	int idx = 0;
1702 
1703 	if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2))
1704 		idx = 1;
1705 
1706 	if ((idx == 1) && !eg_pi->smu_uvd_hs) {
1707 		pi->rlp = 10;
1708 		pi->rmp = 100;
1709 		pi->lhp = 100;
1710 		pi->lmp = 10;
1711 	} else {
1712 		pi->rlp = eg_pi->ats[idx].rlp;
1713 		pi->rmp = eg_pi->ats[idx].rmp;
1714 		pi->lhp = eg_pi->ats[idx].lhp;
1715 		pi->lmp = eg_pi->ats[idx].lmp;
1716 	}
1717 
1718 }
1719 
btc_notify_uvd_to_smc(struct radeon_device * rdev,struct radeon_ps * radeon_new_state)1720 void btc_notify_uvd_to_smc(struct radeon_device *rdev,
1721 			   struct radeon_ps *radeon_new_state)
1722 {
1723 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1724 
1725 	if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
1726 		rv770_write_smc_soft_register(rdev,
1727 					      RV770_SMC_SOFT_REGISTER_uvd_enabled, 1);
1728 		eg_pi->uvd_enabled = true;
1729 	} else {
1730 		rv770_write_smc_soft_register(rdev,
1731 					      RV770_SMC_SOFT_REGISTER_uvd_enabled, 0);
1732 		eg_pi->uvd_enabled = false;
1733 	}
1734 }
1735 
btc_reset_to_default(struct radeon_device * rdev)1736 int btc_reset_to_default(struct radeon_device *rdev)
1737 {
1738 	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != PPSMC_Result_OK)
1739 		return -EINVAL;
1740 
1741 	return 0;
1742 }
1743 
btc_stop_smc(struct radeon_device * rdev)1744 static void btc_stop_smc(struct radeon_device *rdev)
1745 {
1746 	int i;
1747 
1748 	for (i = 0; i < rdev->usec_timeout; i++) {
1749 		if (((RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK) >> LB_SYNC_RESET_SEL_SHIFT) != 1)
1750 			break;
1751 		udelay(1);
1752 	}
1753 	udelay(100);
1754 
1755 	r7xx_stop_smc(rdev);
1756 }
1757 
btc_read_arb_registers(struct radeon_device * rdev)1758 void btc_read_arb_registers(struct radeon_device *rdev)
1759 {
1760 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1761 	struct evergreen_arb_registers *arb_registers =
1762 		&eg_pi->bootup_arb_registers;
1763 
1764 	arb_registers->mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING);
1765 	arb_registers->mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
1766 	arb_registers->mc_arb_rfsh_rate = RREG32(MC_ARB_RFSH_RATE);
1767 	arb_registers->mc_arb_burst_time = RREG32(MC_ARB_BURST_TIME);
1768 }
1769 
1770 
btc_set_arb0_registers(struct radeon_device * rdev,struct evergreen_arb_registers * arb_registers)1771 static void btc_set_arb0_registers(struct radeon_device *rdev,
1772 				   struct evergreen_arb_registers *arb_registers)
1773 {
1774 	u32 val;
1775 
1776 	WREG32(MC_ARB_DRAM_TIMING,  arb_registers->mc_arb_dram_timing);
1777 	WREG32(MC_ARB_DRAM_TIMING2, arb_registers->mc_arb_dram_timing2);
1778 
1779 	val = (arb_registers->mc_arb_rfsh_rate & POWERMODE0_MASK) >>
1780 		POWERMODE0_SHIFT;
1781 	WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
1782 
1783 	val = (arb_registers->mc_arb_burst_time & STATE0_MASK) >>
1784 		STATE0_SHIFT;
1785 	WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
1786 }
1787 
btc_set_boot_state_timing(struct radeon_device * rdev)1788 static void btc_set_boot_state_timing(struct radeon_device *rdev)
1789 {
1790 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1791 
1792 	if (eg_pi->ulv.supported)
1793 		btc_set_arb0_registers(rdev, &eg_pi->bootup_arb_registers);
1794 }
1795 
btc_is_state_ulv_compatible(struct radeon_device * rdev,struct radeon_ps * radeon_state)1796 static bool btc_is_state_ulv_compatible(struct radeon_device *rdev,
1797 					struct radeon_ps *radeon_state)
1798 {
1799 	struct rv7xx_ps *state = rv770_get_ps(radeon_state);
1800 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1801 	struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1802 
1803 	if (state->low.mclk != ulv_pl->mclk)
1804 		return false;
1805 
1806 	if (state->low.vddci != ulv_pl->vddci)
1807 		return false;
1808 
1809 	/* XXX check minclocks, etc. */
1810 
1811 	return true;
1812 }
1813 
1814 
btc_set_ulv_dram_timing(struct radeon_device * rdev)1815 static int btc_set_ulv_dram_timing(struct radeon_device *rdev)
1816 {
1817 	u32 val;
1818 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1819 	struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1820 
1821 	radeon_atom_set_engine_dram_timings(rdev,
1822 					    ulv_pl->sclk,
1823 					    ulv_pl->mclk);
1824 
1825 	val = rv770_calculate_memory_refresh_rate(rdev, ulv_pl->sclk);
1826 	WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
1827 
1828 	val = cypress_calculate_burst_time(rdev, ulv_pl->sclk, ulv_pl->mclk);
1829 	WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
1830 
1831 	return 0;
1832 }
1833 
btc_enable_ulv(struct radeon_device * rdev)1834 static int btc_enable_ulv(struct radeon_device *rdev)
1835 {
1836 	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableULV) != PPSMC_Result_OK)
1837 		return -EINVAL;
1838 
1839 	return 0;
1840 }
1841 
btc_set_power_state_conditionally_enable_ulv(struct radeon_device * rdev,struct radeon_ps * radeon_new_state)1842 static int btc_set_power_state_conditionally_enable_ulv(struct radeon_device *rdev,
1843 							struct radeon_ps *radeon_new_state)
1844 {
1845 	int ret = 0;
1846 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1847 
1848 	if (eg_pi->ulv.supported) {
1849 		if (btc_is_state_ulv_compatible(rdev, radeon_new_state)) {
1850 			// Set ARB[0] to reflect the DRAM timing needed for ULV.
1851 			ret = btc_set_ulv_dram_timing(rdev);
1852 			if (ret == 0)
1853 				ret = btc_enable_ulv(rdev);
1854 		}
1855 	}
1856 
1857 	return ret;
1858 }
1859 
btc_check_s0_mc_reg_index(u16 in_reg,u16 * out_reg)1860 static bool btc_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
1861 {
1862 	bool result = true;
1863 
1864 	switch (in_reg) {
1865 	case MC_SEQ_RAS_TIMING >> 2:
1866 		*out_reg = MC_SEQ_RAS_TIMING_LP >> 2;
1867 		break;
1868 	case MC_SEQ_CAS_TIMING >> 2:
1869 		*out_reg = MC_SEQ_CAS_TIMING_LP >> 2;
1870 		break;
1871 	case MC_SEQ_MISC_TIMING >> 2:
1872 		*out_reg = MC_SEQ_MISC_TIMING_LP >> 2;
1873 		break;
1874 	case MC_SEQ_MISC_TIMING2 >> 2:
1875 		*out_reg = MC_SEQ_MISC_TIMING2_LP >> 2;
1876 		break;
1877 	case MC_SEQ_RD_CTL_D0 >> 2:
1878 		*out_reg = MC_SEQ_RD_CTL_D0_LP >> 2;
1879 		break;
1880 	case MC_SEQ_RD_CTL_D1 >> 2:
1881 		*out_reg = MC_SEQ_RD_CTL_D1_LP >> 2;
1882 		break;
1883 	case MC_SEQ_WR_CTL_D0 >> 2:
1884 		*out_reg = MC_SEQ_WR_CTL_D0_LP >> 2;
1885 		break;
1886 	case MC_SEQ_WR_CTL_D1 >> 2:
1887 		*out_reg = MC_SEQ_WR_CTL_D1_LP >> 2;
1888 		break;
1889 	case MC_PMG_CMD_EMRS >> 2:
1890 		*out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
1891 		break;
1892 	case MC_PMG_CMD_MRS >> 2:
1893 		*out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2;
1894 		break;
1895 	case MC_PMG_CMD_MRS1 >> 2:
1896 		*out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
1897 		break;
1898 	default:
1899 		result = false;
1900 		break;
1901 	}
1902 
1903 	return result;
1904 }
1905 
btc_set_valid_flag(struct evergreen_mc_reg_table * table)1906 static void btc_set_valid_flag(struct evergreen_mc_reg_table *table)
1907 {
1908 	u8 i, j;
1909 
1910 	for (i = 0; i < table->last; i++) {
1911 		for (j = 1; j < table->num_entries; j++) {
1912 			if (table->mc_reg_table_entry[j-1].mc_data[i] !=
1913 			    table->mc_reg_table_entry[j].mc_data[i]) {
1914 				table->valid_flag |= (1 << i);
1915 				break;
1916 			}
1917 		}
1918 	}
1919 }
1920 
btc_set_mc_special_registers(struct radeon_device * rdev,struct evergreen_mc_reg_table * table)1921 static int btc_set_mc_special_registers(struct radeon_device *rdev,
1922 					struct evergreen_mc_reg_table *table)
1923 {
1924 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1925 	u8 i, j, k;
1926 	u32 tmp;
1927 
1928 	for (i = 0, j = table->last; i < table->last; i++) {
1929 		switch (table->mc_reg_address[i].s1) {
1930 		case MC_SEQ_MISC1 >> 2:
1931 			tmp = RREG32(MC_PMG_CMD_EMRS);
1932 			table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2;
1933 			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
1934 			for (k = 0; k < table->num_entries; k++) {
1935 				table->mc_reg_table_entry[k].mc_data[j] =
1936 					((tmp & 0xffff0000)) |
1937 					((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
1938 			}
1939 			j++;
1940 
1941 			if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1942 				return -EINVAL;
1943 
1944 			tmp = RREG32(MC_PMG_CMD_MRS);
1945 			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2;
1946 			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
1947 			for (k = 0; k < table->num_entries; k++) {
1948 				table->mc_reg_table_entry[k].mc_data[j] =
1949 					(tmp & 0xffff0000) |
1950 					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
1951 				if (!pi->mem_gddr5)
1952 					table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
1953 			}
1954 			j++;
1955 
1956 			if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1957 				return -EINVAL;
1958 			break;
1959 		case MC_SEQ_RESERVE_M >> 2:
1960 			tmp = RREG32(MC_PMG_CMD_MRS1);
1961 			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
1962 			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
1963 			for (k = 0; k < table->num_entries; k++) {
1964 				table->mc_reg_table_entry[k].mc_data[j] =
1965 					(tmp & 0xffff0000) |
1966 					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
1967 			}
1968 			j++;
1969 
1970 			if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1971 				return -EINVAL;
1972 			break;
1973 		default:
1974 			break;
1975 		}
1976 	}
1977 
1978 	table->last = j;
1979 
1980 	return 0;
1981 }
1982 
btc_set_s0_mc_reg_index(struct evergreen_mc_reg_table * table)1983 static void btc_set_s0_mc_reg_index(struct evergreen_mc_reg_table *table)
1984 {
1985 	u32 i;
1986 	u16 address;
1987 
1988 	for (i = 0; i < table->last; i++) {
1989 		table->mc_reg_address[i].s0 =
1990 			btc_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
1991 			address : table->mc_reg_address[i].s1;
1992 	}
1993 }
1994 
btc_copy_vbios_mc_reg_table(struct atom_mc_reg_table * table,struct evergreen_mc_reg_table * eg_table)1995 static int btc_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
1996 				       struct evergreen_mc_reg_table *eg_table)
1997 {
1998 	u8 i, j;
1999 
2000 	if (table->last > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
2001 		return -EINVAL;
2002 
2003 	if (table->num_entries > MAX_AC_TIMING_ENTRIES)
2004 		return -EINVAL;
2005 
2006 	for (i = 0; i < table->last; i++)
2007 		eg_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
2008 	eg_table->last = table->last;
2009 
2010 	for (i = 0; i < table->num_entries; i++) {
2011 		eg_table->mc_reg_table_entry[i].mclk_max =
2012 			table->mc_reg_table_entry[i].mclk_max;
2013 		for(j = 0; j < table->last; j++)
2014 			eg_table->mc_reg_table_entry[i].mc_data[j] =
2015 				table->mc_reg_table_entry[i].mc_data[j];
2016 	}
2017 	eg_table->num_entries = table->num_entries;
2018 
2019 	return 0;
2020 }
2021 
btc_initialize_mc_reg_table(struct radeon_device * rdev)2022 static int btc_initialize_mc_reg_table(struct radeon_device *rdev)
2023 {
2024 	int ret;
2025 	struct atom_mc_reg_table *table;
2026 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2027 	struct evergreen_mc_reg_table *eg_table = &eg_pi->mc_reg_table;
2028 	u8 module_index = rv770_get_memory_module_index(rdev);
2029 
2030 	table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
2031 	if (!table)
2032 		return -ENOMEM;
2033 
2034 	/* Program additional LP registers that are no longer programmed by VBIOS */
2035 	WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
2036 	WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
2037 	WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
2038 	WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
2039 	WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
2040 	WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
2041 	WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
2042 	WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
2043 	WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
2044 	WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
2045 	WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
2046 
2047 	ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
2048 
2049 	if (ret)
2050 		goto init_mc_done;
2051 
2052 	ret = btc_copy_vbios_mc_reg_table(table, eg_table);
2053 
2054 	if (ret)
2055 		goto init_mc_done;
2056 
2057 	btc_set_s0_mc_reg_index(eg_table);
2058 	ret = btc_set_mc_special_registers(rdev, eg_table);
2059 
2060 	if (ret)
2061 		goto init_mc_done;
2062 
2063 	btc_set_valid_flag(eg_table);
2064 
2065 init_mc_done:
2066 	kfree(table);
2067 
2068 	return ret;
2069 }
2070 
btc_init_stutter_mode(struct radeon_device * rdev)2071 static void btc_init_stutter_mode(struct radeon_device *rdev)
2072 {
2073 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2074 	u32 tmp;
2075 
2076 	if (pi->mclk_stutter_mode_threshold) {
2077 		if (pi->mem_gddr5) {
2078 			tmp = RREG32(MC_PMG_AUTO_CFG);
2079 			if ((0x200 & tmp) == 0) {
2080 				tmp = (tmp & 0xfffffc0b) | 0x204;
2081 				WREG32(MC_PMG_AUTO_CFG, tmp);
2082 			}
2083 		}
2084 	}
2085 }
2086 
btc_dpm_vblank_too_short(struct radeon_device * rdev)2087 bool btc_dpm_vblank_too_short(struct radeon_device *rdev)
2088 {
2089 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2090 	u32 vblank_time = r600_dpm_get_vblank_time(rdev);
2091 	u32 switch_limit = pi->mem_gddr5 ? 450 : 100;
2092 
2093 	if (vblank_time < switch_limit)
2094 		return true;
2095 	else
2096 		return false;
2097 
2098 }
2099 
btc_apply_state_adjust_rules(struct radeon_device * rdev,struct radeon_ps * rps)2100 static void btc_apply_state_adjust_rules(struct radeon_device *rdev,
2101 					 struct radeon_ps *rps)
2102 {
2103 	struct rv7xx_ps *ps = rv770_get_ps(rps);
2104 	struct radeon_clock_and_voltage_limits *max_limits;
2105 	bool disable_mclk_switching;
2106 	u32 mclk, sclk;
2107 	u16 vddc, vddci;
2108 
2109 	if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
2110 	    btc_dpm_vblank_too_short(rdev))
2111 		disable_mclk_switching = true;
2112 	else
2113 		disable_mclk_switching = false;
2114 
2115 	if (rdev->pm.dpm.ac_power)
2116 		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2117 	else
2118 		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
2119 
2120 	if (rdev->pm.dpm.ac_power == false) {
2121 		if (ps->high.mclk > max_limits->mclk)
2122 			ps->high.mclk = max_limits->mclk;
2123 		if (ps->high.sclk > max_limits->sclk)
2124 			ps->high.sclk = max_limits->sclk;
2125 		if (ps->high.vddc > max_limits->vddc)
2126 			ps->high.vddc = max_limits->vddc;
2127 		if (ps->high.vddci > max_limits->vddci)
2128 			ps->high.vddci = max_limits->vddci;
2129 
2130 		if (ps->medium.mclk > max_limits->mclk)
2131 			ps->medium.mclk = max_limits->mclk;
2132 		if (ps->medium.sclk > max_limits->sclk)
2133 			ps->medium.sclk = max_limits->sclk;
2134 		if (ps->medium.vddc > max_limits->vddc)
2135 			ps->medium.vddc = max_limits->vddc;
2136 		if (ps->medium.vddci > max_limits->vddci)
2137 			ps->medium.vddci = max_limits->vddci;
2138 
2139 		if (ps->low.mclk > max_limits->mclk)
2140 			ps->low.mclk = max_limits->mclk;
2141 		if (ps->low.sclk > max_limits->sclk)
2142 			ps->low.sclk = max_limits->sclk;
2143 		if (ps->low.vddc > max_limits->vddc)
2144 			ps->low.vddc = max_limits->vddc;
2145 		if (ps->low.vddci > max_limits->vddci)
2146 			ps->low.vddci = max_limits->vddci;
2147 	}
2148 
2149 	/* XXX validate the min clocks required for display */
2150 
2151 	if (disable_mclk_switching) {
2152 		sclk = ps->low.sclk;
2153 		mclk = ps->high.mclk;
2154 		vddc = ps->low.vddc;
2155 		vddci = ps->high.vddci;
2156 	} else {
2157 		sclk = ps->low.sclk;
2158 		mclk = ps->low.mclk;
2159 		vddc = ps->low.vddc;
2160 		vddci = ps->low.vddci;
2161 	}
2162 
2163 	/* adjusted low state */
2164 	ps->low.sclk = sclk;
2165 	ps->low.mclk = mclk;
2166 	ps->low.vddc = vddc;
2167 	ps->low.vddci = vddci;
2168 
2169 	btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2170 				  &ps->low.sclk, &ps->low.mclk);
2171 
2172 	/* adjusted medium, high states */
2173 	if (ps->medium.sclk < ps->low.sclk)
2174 		ps->medium.sclk = ps->low.sclk;
2175 	if (ps->medium.vddc < ps->low.vddc)
2176 		ps->medium.vddc = ps->low.vddc;
2177 	if (ps->high.sclk < ps->medium.sclk)
2178 		ps->high.sclk = ps->medium.sclk;
2179 	if (ps->high.vddc < ps->medium.vddc)
2180 		ps->high.vddc = ps->medium.vddc;
2181 
2182 	if (disable_mclk_switching) {
2183 		mclk = ps->low.mclk;
2184 		if (mclk < ps->medium.mclk)
2185 			mclk = ps->medium.mclk;
2186 		if (mclk < ps->high.mclk)
2187 			mclk = ps->high.mclk;
2188 		ps->low.mclk = mclk;
2189 		ps->low.vddci = vddci;
2190 		ps->medium.mclk = mclk;
2191 		ps->medium.vddci = vddci;
2192 		ps->high.mclk = mclk;
2193 		ps->high.vddci = vddci;
2194 	} else {
2195 		if (ps->medium.mclk < ps->low.mclk)
2196 			ps->medium.mclk = ps->low.mclk;
2197 		if (ps->medium.vddci < ps->low.vddci)
2198 			ps->medium.vddci = ps->low.vddci;
2199 		if (ps->high.mclk < ps->medium.mclk)
2200 			ps->high.mclk = ps->medium.mclk;
2201 		if (ps->high.vddci < ps->medium.vddci)
2202 			ps->high.vddci = ps->medium.vddci;
2203 	}
2204 
2205 	btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2206 				  &ps->medium.sclk, &ps->medium.mclk);
2207 	btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2208 				  &ps->high.sclk, &ps->high.mclk);
2209 
2210 	btc_adjust_clock_combinations(rdev, max_limits, &ps->low);
2211 	btc_adjust_clock_combinations(rdev, max_limits, &ps->medium);
2212 	btc_adjust_clock_combinations(rdev, max_limits, &ps->high);
2213 
2214 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2215 					   ps->low.sclk, max_limits->vddc, &ps->low.vddc);
2216 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2217 					   ps->low.mclk, max_limits->vddci, &ps->low.vddci);
2218 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2219 					   ps->low.mclk, max_limits->vddc, &ps->low.vddc);
2220 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2221 					   rdev->clock.current_dispclk, max_limits->vddc, &ps->low.vddc);
2222 
2223 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2224 					   ps->medium.sclk, max_limits->vddc, &ps->medium.vddc);
2225 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2226 					   ps->medium.mclk, max_limits->vddci, &ps->medium.vddci);
2227 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2228 					   ps->medium.mclk, max_limits->vddc, &ps->medium.vddc);
2229 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2230 					   rdev->clock.current_dispclk, max_limits->vddc, &ps->medium.vddc);
2231 
2232 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2233 					   ps->high.sclk, max_limits->vddc, &ps->high.vddc);
2234 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2235 					   ps->high.mclk, max_limits->vddci, &ps->high.vddci);
2236 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2237 					   ps->high.mclk, max_limits->vddc, &ps->high.vddc);
2238 	btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2239 					   rdev->clock.current_dispclk, max_limits->vddc, &ps->high.vddc);
2240 
2241 	btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2242 				      &ps->low.vddc, &ps->low.vddci);
2243 	btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2244 				      &ps->medium.vddc, &ps->medium.vddci);
2245 	btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2246 				      &ps->high.vddc, &ps->high.vddci);
2247 
2248 	if ((ps->high.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
2249 	    (ps->medium.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
2250 	    (ps->low.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc))
2251 		ps->dc_compatible = true;
2252 	else
2253 		ps->dc_compatible = false;
2254 
2255 	if (ps->low.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2256 		ps->low.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2257 	if (ps->medium.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2258 		ps->medium.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2259 	if (ps->high.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2260 		ps->high.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2261 }
2262 
btc_update_current_ps(struct radeon_device * rdev,struct radeon_ps * rps)2263 static void btc_update_current_ps(struct radeon_device *rdev,
2264 				  struct radeon_ps *rps)
2265 {
2266 	struct rv7xx_ps *new_ps = rv770_get_ps(rps);
2267 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2268 
2269 	eg_pi->current_rps = *rps;
2270 	eg_pi->current_ps = *new_ps;
2271 	eg_pi->current_rps.ps_priv = &eg_pi->current_ps;
2272 }
2273 
btc_update_requested_ps(struct radeon_device * rdev,struct radeon_ps * rps)2274 static void btc_update_requested_ps(struct radeon_device *rdev,
2275 				    struct radeon_ps *rps)
2276 {
2277 	struct rv7xx_ps *new_ps = rv770_get_ps(rps);
2278 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2279 
2280 	eg_pi->requested_rps = *rps;
2281 	eg_pi->requested_ps = *new_ps;
2282 	eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps;
2283 }
2284 
2285 #if 0
2286 void btc_dpm_reset_asic(struct radeon_device *rdev)
2287 {
2288 	rv770_restrict_performance_levels_before_switch(rdev);
2289 	btc_disable_ulv(rdev);
2290 	btc_set_boot_state_timing(rdev);
2291 	rv770_set_boot_state(rdev);
2292 }
2293 #endif
2294 
btc_dpm_pre_set_power_state(struct radeon_device * rdev)2295 int btc_dpm_pre_set_power_state(struct radeon_device *rdev)
2296 {
2297 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2298 	struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
2299 	struct radeon_ps *new_ps = &requested_ps;
2300 
2301 	btc_update_requested_ps(rdev, new_ps);
2302 
2303 	btc_apply_state_adjust_rules(rdev, &eg_pi->requested_rps);
2304 
2305 	return 0;
2306 }
2307 
btc_dpm_set_power_state(struct radeon_device * rdev)2308 int btc_dpm_set_power_state(struct radeon_device *rdev)
2309 {
2310 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2311 	struct radeon_ps *new_ps = &eg_pi->requested_rps;
2312 	struct radeon_ps *old_ps = &eg_pi->current_rps;
2313 	int ret;
2314 
2315 	ret = btc_disable_ulv(rdev);
2316 	btc_set_boot_state_timing(rdev);
2317 	ret = rv770_restrict_performance_levels_before_switch(rdev);
2318 	if (ret) {
2319 		DRM_ERROR("rv770_restrict_performance_levels_before_switch failed: %d\n", ret);
2320 		return ret;
2321 	}
2322 	if (eg_pi->pcie_performance_request)
2323 		cypress_notify_link_speed_change_before_state_change(rdev, new_ps, old_ps);
2324 
2325 	rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
2326 	ret = rv770_halt_smc(rdev);
2327 	if (ret) {
2328 		DRM_ERROR("rv770_halt_smc failed\n");
2329 		return ret;
2330 	}
2331 	btc_set_at_for_uvd(rdev, new_ps);
2332 	if (eg_pi->smu_uvd_hs)
2333 		btc_notify_uvd_to_smc(rdev, new_ps);
2334 	ret = cypress_upload_sw_state(rdev, new_ps);
2335 	if (ret) {
2336 		DRM_ERROR("cypress_upload_sw_state failed\n");
2337 		return ret;
2338 	}
2339 	if (eg_pi->dynamic_ac_timing) {
2340 		ret = cypress_upload_mc_reg_table(rdev, new_ps);
2341 		if (ret) {
2342 			DRM_ERROR("cypress_upload_mc_reg_table failed\n");
2343 			return ret;
2344 		}
2345 	}
2346 
2347 	cypress_program_memory_timing_parameters(rdev, new_ps);
2348 
2349 	ret = rv770_resume_smc(rdev);
2350 	if (ret) {
2351 		DRM_ERROR("rv770_resume_smc failed\n");
2352 		return ret;
2353 	}
2354 	ret = rv770_set_sw_state(rdev);
2355 	if (ret) {
2356 		DRM_ERROR("rv770_set_sw_state failed\n");
2357 		return ret;
2358 	}
2359 	rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
2360 
2361 	if (eg_pi->pcie_performance_request)
2362 		cypress_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
2363 
2364 	ret = btc_set_power_state_conditionally_enable_ulv(rdev, new_ps);
2365 	if (ret) {
2366 		DRM_ERROR("btc_set_power_state_conditionally_enable_ulv failed\n");
2367 		return ret;
2368 	}
2369 
2370 	return 0;
2371 }
2372 
btc_dpm_post_set_power_state(struct radeon_device * rdev)2373 void btc_dpm_post_set_power_state(struct radeon_device *rdev)
2374 {
2375 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2376 	struct radeon_ps *new_ps = &eg_pi->requested_rps;
2377 
2378 	btc_update_current_ps(rdev, new_ps);
2379 }
2380 
btc_dpm_enable(struct radeon_device * rdev)2381 int btc_dpm_enable(struct radeon_device *rdev)
2382 {
2383 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2384 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2385 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
2386 	int ret;
2387 
2388 	if (pi->gfx_clock_gating)
2389 		btc_cg_clock_gating_default(rdev);
2390 
2391 	if (btc_dpm_enabled(rdev))
2392 		return -EINVAL;
2393 
2394 	if (pi->mg_clock_gating)
2395 		btc_mg_clock_gating_default(rdev);
2396 
2397 	if (eg_pi->ls_clock_gating)
2398 		btc_ls_clock_gating_default(rdev);
2399 
2400 	if (pi->voltage_control) {
2401 		rv770_enable_voltage_control(rdev, true);
2402 		ret = cypress_construct_voltage_tables(rdev);
2403 		if (ret) {
2404 			DRM_ERROR("cypress_construct_voltage_tables failed\n");
2405 			return ret;
2406 		}
2407 	}
2408 
2409 	if (pi->mvdd_control) {
2410 		ret = cypress_get_mvdd_configuration(rdev);
2411 		if (ret) {
2412 			DRM_ERROR("cypress_get_mvdd_configuration failed\n");
2413 			return ret;
2414 		}
2415 	}
2416 
2417 	if (eg_pi->dynamic_ac_timing) {
2418 		ret = btc_initialize_mc_reg_table(rdev);
2419 		if (ret)
2420 			eg_pi->dynamic_ac_timing = false;
2421 	}
2422 
2423 	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
2424 		rv770_enable_backbias(rdev, true);
2425 
2426 	if (pi->dynamic_ss)
2427 		cypress_enable_spread_spectrum(rdev, true);
2428 
2429 	if (pi->thermal_protection)
2430 		rv770_enable_thermal_protection(rdev, true);
2431 
2432 	rv770_setup_bsp(rdev);
2433 	rv770_program_git(rdev);
2434 	rv770_program_tp(rdev);
2435 	rv770_program_tpp(rdev);
2436 	rv770_program_sstp(rdev);
2437 	rv770_program_engine_speed_parameters(rdev);
2438 	cypress_enable_display_gap(rdev);
2439 	rv770_program_vc(rdev);
2440 
2441 	if (pi->dynamic_pcie_gen2)
2442 		btc_enable_dynamic_pcie_gen2(rdev, true);
2443 
2444 	ret = rv770_upload_firmware(rdev);
2445 	if (ret) {
2446 		DRM_ERROR("rv770_upload_firmware failed\n");
2447 		return ret;
2448 	}
2449 	ret = cypress_get_table_locations(rdev);
2450 	if (ret) {
2451 		DRM_ERROR("cypress_get_table_locations failed\n");
2452 		return ret;
2453 	}
2454 	ret = btc_init_smc_table(rdev, boot_ps);
2455 	if (ret)
2456 		return ret;
2457 
2458 	if (eg_pi->dynamic_ac_timing) {
2459 		ret = cypress_populate_mc_reg_table(rdev, boot_ps);
2460 		if (ret) {
2461 			DRM_ERROR("cypress_populate_mc_reg_table failed\n");
2462 			return ret;
2463 		}
2464 	}
2465 
2466 	cypress_program_response_times(rdev);
2467 	r7xx_start_smc(rdev);
2468 	ret = cypress_notify_smc_display_change(rdev, false);
2469 	if (ret) {
2470 		DRM_ERROR("cypress_notify_smc_display_change failed\n");
2471 		return ret;
2472 	}
2473 	cypress_enable_sclk_control(rdev, true);
2474 
2475 	if (eg_pi->memory_transition)
2476 		cypress_enable_mclk_control(rdev, true);
2477 
2478 	cypress_start_dpm(rdev);
2479 
2480 	if (pi->gfx_clock_gating)
2481 		btc_cg_clock_gating_enable(rdev, true);
2482 
2483 	if (pi->mg_clock_gating)
2484 		btc_mg_clock_gating_enable(rdev, true);
2485 
2486 	if (eg_pi->ls_clock_gating)
2487 		btc_ls_clock_gating_enable(rdev, true);
2488 
2489 	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
2490 
2491 	btc_init_stutter_mode(rdev);
2492 
2493 	btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
2494 
2495 	return 0;
2496 };
2497 
btc_dpm_disable(struct radeon_device * rdev)2498 void btc_dpm_disable(struct radeon_device *rdev)
2499 {
2500 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2501 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2502 
2503 	if (!btc_dpm_enabled(rdev))
2504 		return;
2505 
2506 	rv770_clear_vc(rdev);
2507 
2508 	if (pi->thermal_protection)
2509 		rv770_enable_thermal_protection(rdev, false);
2510 
2511 	if (pi->dynamic_pcie_gen2)
2512 		btc_enable_dynamic_pcie_gen2(rdev, false);
2513 
2514 	if (rdev->irq.installed &&
2515 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
2516 		rdev->irq.dpm_thermal = false;
2517 		radeon_irq_set(rdev);
2518 	}
2519 
2520 	if (pi->gfx_clock_gating)
2521 		btc_cg_clock_gating_enable(rdev, false);
2522 
2523 	if (pi->mg_clock_gating)
2524 		btc_mg_clock_gating_enable(rdev, false);
2525 
2526 	if (eg_pi->ls_clock_gating)
2527 		btc_ls_clock_gating_enable(rdev, false);
2528 
2529 	rv770_stop_dpm(rdev);
2530 	btc_reset_to_default(rdev);
2531 	btc_stop_smc(rdev);
2532 	cypress_enable_spread_spectrum(rdev, false);
2533 
2534 	btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
2535 }
2536 
btc_dpm_setup_asic(struct radeon_device * rdev)2537 void btc_dpm_setup_asic(struct radeon_device *rdev)
2538 {
2539 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2540 	int r;
2541 
2542 	r = ni_mc_load_microcode(rdev);
2543 	if (r)
2544 		DRM_ERROR("Failed to load MC firmware!\n");
2545 	rv770_get_memory_type(rdev);
2546 	rv740_read_clock_registers(rdev);
2547 	btc_read_arb_registers(rdev);
2548 	rv770_read_voltage_smio_registers(rdev);
2549 
2550 	if (eg_pi->pcie_performance_request)
2551 		cypress_advertise_gen2_capability(rdev);
2552 
2553 	rv770_get_pcie_gen2_status(rdev);
2554 	rv770_enable_acpi_pm(rdev);
2555 }
2556 
btc_dpm_init(struct radeon_device * rdev)2557 int btc_dpm_init(struct radeon_device *rdev)
2558 {
2559 	struct rv7xx_power_info *pi;
2560 	struct evergreen_power_info *eg_pi;
2561 	struct atom_clock_dividers dividers;
2562 	int ret;
2563 
2564 	eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL);
2565 	if (eg_pi == NULL)
2566 		return -ENOMEM;
2567 	rdev->pm.dpm.priv = eg_pi;
2568 	pi = &eg_pi->rv7xx;
2569 
2570 	rv770_get_max_vddc(rdev);
2571 
2572 	eg_pi->ulv.supported = false;
2573 	pi->acpi_vddc = 0;
2574 	eg_pi->acpi_vddci = 0;
2575 	pi->min_vddc_in_table = 0;
2576 	pi->max_vddc_in_table = 0;
2577 
2578 	ret = r600_get_platform_caps(rdev);
2579 	if (ret)
2580 		return ret;
2581 
2582 	ret = rv7xx_parse_power_table(rdev);
2583 	if (ret)
2584 		return ret;
2585 	ret = r600_parse_extended_power_table(rdev);
2586 	if (ret)
2587 		return ret;
2588 
2589 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
2590 		kcalloc(4,
2591 			sizeof(struct radeon_clock_voltage_dependency_entry),
2592 			GFP_KERNEL);
2593 	if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
2594 		r600_free_extended_power_table(rdev);
2595 		return -ENOMEM;
2596 	}
2597 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
2598 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
2599 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
2600 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
2601 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 800;
2602 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
2603 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 800;
2604 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
2605 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 800;
2606 
2607 	if (rdev->pm.dpm.voltage_response_time == 0)
2608 		rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
2609 	if (rdev->pm.dpm.backbias_response_time == 0)
2610 		rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
2611 
2612 	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
2613 					     0, false, &dividers);
2614 	if (ret)
2615 		pi->ref_div = dividers.ref_div + 1;
2616 	else
2617 		pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
2618 
2619 	pi->mclk_strobe_mode_threshold = 40000;
2620 	pi->mclk_edc_enable_threshold = 40000;
2621 	eg_pi->mclk_edc_wr_enable_threshold = 40000;
2622 
2623 	pi->rlp = RV770_RLP_DFLT;
2624 	pi->rmp = RV770_RMP_DFLT;
2625 	pi->lhp = RV770_LHP_DFLT;
2626 	pi->lmp = RV770_LMP_DFLT;
2627 
2628 	eg_pi->ats[0].rlp = RV770_RLP_DFLT;
2629 	eg_pi->ats[0].rmp = RV770_RMP_DFLT;
2630 	eg_pi->ats[0].lhp = RV770_LHP_DFLT;
2631 	eg_pi->ats[0].lmp = RV770_LMP_DFLT;
2632 
2633 	eg_pi->ats[1].rlp = BTC_RLP_UVD_DFLT;
2634 	eg_pi->ats[1].rmp = BTC_RMP_UVD_DFLT;
2635 	eg_pi->ats[1].lhp = BTC_LHP_UVD_DFLT;
2636 	eg_pi->ats[1].lmp = BTC_LMP_UVD_DFLT;
2637 
2638 	eg_pi->smu_uvd_hs = true;
2639 
2640 	pi->voltage_control =
2641 		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
2642 
2643 	pi->mvdd_control =
2644 		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
2645 
2646 	eg_pi->vddci_control =
2647 		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
2648 
2649 	rv770_get_engine_memory_ss(rdev);
2650 
2651 	pi->asi = RV770_ASI_DFLT;
2652 	pi->pasi = CYPRESS_HASI_DFLT;
2653 	pi->vrc = CYPRESS_VRC_DFLT;
2654 
2655 	pi->power_gating = false;
2656 
2657 	pi->gfx_clock_gating = true;
2658 
2659 	pi->mg_clock_gating = true;
2660 	pi->mgcgtssm = true;
2661 	eg_pi->ls_clock_gating = false;
2662 	eg_pi->sclk_deep_sleep = false;
2663 
2664 	pi->dynamic_pcie_gen2 = true;
2665 
2666 	if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
2667 		pi->thermal_protection = true;
2668 	else
2669 		pi->thermal_protection = false;
2670 
2671 	pi->display_gap = true;
2672 
2673 	if (rdev->flags & RADEON_IS_MOBILITY)
2674 		pi->dcodt = true;
2675 	else
2676 		pi->dcodt = false;
2677 
2678 	pi->ulps = true;
2679 
2680 	eg_pi->dynamic_ac_timing = true;
2681 	eg_pi->abm = true;
2682 	eg_pi->mcls = true;
2683 	eg_pi->light_sleep = true;
2684 	eg_pi->memory_transition = true;
2685 #if defined(CONFIG_ACPI)
2686 	eg_pi->pcie_performance_request =
2687 		radeon_acpi_is_pcie_performance_request_supported(rdev);
2688 #else
2689 	eg_pi->pcie_performance_request = false;
2690 #endif
2691 
2692 	if (rdev->family == CHIP_BARTS)
2693 		eg_pi->dll_default_on = true;
2694 	else
2695 		eg_pi->dll_default_on = false;
2696 
2697 	eg_pi->sclk_deep_sleep = false;
2698 	if (ASIC_IS_LOMBOK(rdev))
2699 		pi->mclk_stutter_mode_threshold = 30000;
2700 	else
2701 		pi->mclk_stutter_mode_threshold = 0;
2702 
2703 	pi->sram_end = SMC_RAM_END;
2704 
2705 	rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;
2706 	rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
2707 	rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2 = 900;
2708 	rdev->pm.dpm.dyn_state.valid_sclk_values.count = ARRAY_SIZE(btc_valid_sclk);
2709 	rdev->pm.dpm.dyn_state.valid_sclk_values.values = btc_valid_sclk;
2710 	rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
2711 	rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
2712 
2713 	if (rdev->family == CHIP_TURKS)
2714 		rdev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;
2715 	else
2716 		rdev->pm.dpm.dyn_state.sclk_mclk_delta = 10000;
2717 
2718 	/* make sure dc limits are valid */
2719 	if ((rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk == 0) ||
2720 	    (rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk == 0))
2721 		rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
2722 			rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2723 
2724 	return 0;
2725 }
2726 
btc_dpm_fini(struct radeon_device * rdev)2727 void btc_dpm_fini(struct radeon_device *rdev)
2728 {
2729 	int i;
2730 
2731 	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
2732 		kfree(rdev->pm.dpm.ps[i].ps_priv);
2733 	}
2734 	kfree(rdev->pm.dpm.ps);
2735 	kfree(rdev->pm.dpm.priv);
2736 	kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
2737 	r600_free_extended_power_table(rdev);
2738 }
2739 
2740 #ifdef CONFIG_DEBUG_FS
btc_dpm_debugfs_print_current_performance_level(struct radeon_device * rdev,struct seq_file * m)2741 void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
2742 						     struct seq_file *m)
2743 {
2744 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2745 	struct radeon_ps *rps = &eg_pi->current_rps;
2746 	struct rv7xx_ps *ps = rv770_get_ps(rps);
2747 	struct rv7xx_pl *pl;
2748 	u32 current_index =
2749 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
2750 		CURRENT_PROFILE_INDEX_SHIFT;
2751 
2752 	if (current_index > 2) {
2753 		seq_printf(m, "invalid dpm profile %d\n", current_index);
2754 	} else {
2755 		if (current_index == 0)
2756 			pl = &ps->low;
2757 		else if (current_index == 1)
2758 			pl = &ps->medium;
2759 		else /* current_index == 2 */
2760 			pl = &ps->high;
2761 		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
2762 		seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
2763 			   current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
2764 	}
2765 }
2766 #endif	/* CONFIG_DEBUG_FS */
2767 
btc_dpm_get_current_sclk(struct radeon_device * rdev)2768 u32 btc_dpm_get_current_sclk(struct radeon_device *rdev)
2769 {
2770 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2771 	struct radeon_ps *rps = &eg_pi->current_rps;
2772 	struct rv7xx_ps *ps = rv770_get_ps(rps);
2773 	struct rv7xx_pl *pl;
2774 	u32 current_index =
2775 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
2776 		CURRENT_PROFILE_INDEX_SHIFT;
2777 
2778 	if (current_index > 2) {
2779 		return 0;
2780 	} else {
2781 		if (current_index == 0)
2782 			pl = &ps->low;
2783 		else if (current_index == 1)
2784 			pl = &ps->medium;
2785 		else /* current_index == 2 */
2786 			pl = &ps->high;
2787 		return pl->sclk;
2788 	}
2789 }
2790 
btc_dpm_get_current_mclk(struct radeon_device * rdev)2791 u32 btc_dpm_get_current_mclk(struct radeon_device *rdev)
2792 {
2793 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2794 	struct radeon_ps *rps = &eg_pi->current_rps;
2795 	struct rv7xx_ps *ps = rv770_get_ps(rps);
2796 	struct rv7xx_pl *pl;
2797 	u32 current_index =
2798 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
2799 		CURRENT_PROFILE_INDEX_SHIFT;
2800 
2801 	if (current_index > 2) {
2802 		return 0;
2803 	} else {
2804 		if (current_index == 0)
2805 			pl = &ps->low;
2806 		else if (current_index == 1)
2807 			pl = &ps->medium;
2808 		else /* current_index == 2 */
2809 			pl = &ps->high;
2810 		return pl->mclk;
2811 	}
2812 }
2813 
btc_dpm_get_sclk(struct radeon_device * rdev,bool low)2814 u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low)
2815 {
2816 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2817 	struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2818 
2819 	if (low)
2820 		return requested_state->low.sclk;
2821 	else
2822 		return requested_state->high.sclk;
2823 }
2824 
btc_dpm_get_mclk(struct radeon_device * rdev,bool low)2825 u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low)
2826 {
2827 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2828 	struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2829 
2830 	if (low)
2831 		return requested_state->low.mclk;
2832 	else
2833 		return requested_state->high.mclk;
2834 }
2835