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