xref: /linux/drivers/gpu/drm/radeon/btc_dpm.c (revision 2ba9268dd603d23e17643437b2246acb6844953b)
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 "drmP.h"
26 #include "radeon.h"
27 #include "radeon_asic.h"
28 #include "btcd.h"
29 #include "r600_dpm.h"
30 #include "cypress_dpm.h"
31 #include "btc_dpm.h"
32 #include "atom.h"
33 #include <linux/seq_file.h>
34 
35 #define MC_CG_ARB_FREQ_F0           0x0a
36 #define MC_CG_ARB_FREQ_F1           0x0b
37 #define MC_CG_ARB_FREQ_F2           0x0c
38 #define MC_CG_ARB_FREQ_F3           0x0d
39 
40 #define MC_CG_SEQ_DRAMCONF_S0       0x05
41 #define MC_CG_SEQ_DRAMCONF_S1       0x06
42 #define MC_CG_SEQ_YCLK_SUSPEND      0x04
43 #define MC_CG_SEQ_YCLK_RESUME       0x0a
44 
45 #define SMC_RAM_END 0x8000
46 
47 #ifndef BTC_MGCG_SEQUENCE
48 #define BTC_MGCG_SEQUENCE  300
49 
50 struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
51 struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
52 struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
53 
54 extern int ni_mc_load_microcode(struct radeon_device *rdev);
55 
56 //********* BARTS **************//
57 static const u32 barts_cgcg_cgls_default[] =
58 {
59 	/* Register,   Value,     Mask bits */
60 	0x000008f8, 0x00000010, 0xffffffff,
61 	0x000008fc, 0x00000000, 0xffffffff,
62 	0x000008f8, 0x00000011, 0xffffffff,
63 	0x000008fc, 0x00000000, 0xffffffff,
64 	0x000008f8, 0x00000012, 0xffffffff,
65 	0x000008fc, 0x00000000, 0xffffffff,
66 	0x000008f8, 0x00000013, 0xffffffff,
67 	0x000008fc, 0x00000000, 0xffffffff,
68 	0x000008f8, 0x00000014, 0xffffffff,
69 	0x000008fc, 0x00000000, 0xffffffff,
70 	0x000008f8, 0x00000015, 0xffffffff,
71 	0x000008fc, 0x00000000, 0xffffffff,
72 	0x000008f8, 0x00000016, 0xffffffff,
73 	0x000008fc, 0x00000000, 0xffffffff,
74 	0x000008f8, 0x00000017, 0xffffffff,
75 	0x000008fc, 0x00000000, 0xffffffff,
76 	0x000008f8, 0x00000018, 0xffffffff,
77 	0x000008fc, 0x00000000, 0xffffffff,
78 	0x000008f8, 0x00000019, 0xffffffff,
79 	0x000008fc, 0x00000000, 0xffffffff,
80 	0x000008f8, 0x0000001a, 0xffffffff,
81 	0x000008fc, 0x00000000, 0xffffffff,
82 	0x000008f8, 0x0000001b, 0xffffffff,
83 	0x000008fc, 0x00000000, 0xffffffff,
84 	0x000008f8, 0x00000020, 0xffffffff,
85 	0x000008fc, 0x00000000, 0xffffffff,
86 	0x000008f8, 0x00000021, 0xffffffff,
87 	0x000008fc, 0x00000000, 0xffffffff,
88 	0x000008f8, 0x00000022, 0xffffffff,
89 	0x000008fc, 0x00000000, 0xffffffff,
90 	0x000008f8, 0x00000023, 0xffffffff,
91 	0x000008fc, 0x00000000, 0xffffffff,
92 	0x000008f8, 0x00000024, 0xffffffff,
93 	0x000008fc, 0x00000000, 0xffffffff,
94 	0x000008f8, 0x00000025, 0xffffffff,
95 	0x000008fc, 0x00000000, 0xffffffff,
96 	0x000008f8, 0x00000026, 0xffffffff,
97 	0x000008fc, 0x00000000, 0xffffffff,
98 	0x000008f8, 0x00000027, 0xffffffff,
99 	0x000008fc, 0x00000000, 0xffffffff,
100 	0x000008f8, 0x00000028, 0xffffffff,
101 	0x000008fc, 0x00000000, 0xffffffff,
102 	0x000008f8, 0x00000029, 0xffffffff,
103 	0x000008fc, 0x00000000, 0xffffffff,
104 	0x000008f8, 0x0000002a, 0xffffffff,
105 	0x000008fc, 0x00000000, 0xffffffff,
106 	0x000008f8, 0x0000002b, 0xffffffff,
107 	0x000008fc, 0x00000000, 0xffffffff
108 };
109 #define BARTS_CGCG_CGLS_DEFAULT_LENGTH sizeof(barts_cgcg_cgls_default) / (3 * sizeof(u32))
110 
111 static const u32 barts_cgcg_cgls_disable[] =
112 {
113 	0x000008f8, 0x00000010, 0xffffffff,
114 	0x000008fc, 0xffffffff, 0xffffffff,
115 	0x000008f8, 0x00000011, 0xffffffff,
116 	0x000008fc, 0xffffffff, 0xffffffff,
117 	0x000008f8, 0x00000012, 0xffffffff,
118 	0x000008fc, 0xffffffff, 0xffffffff,
119 	0x000008f8, 0x00000013, 0xffffffff,
120 	0x000008fc, 0xffffffff, 0xffffffff,
121 	0x000008f8, 0x00000014, 0xffffffff,
122 	0x000008fc, 0xffffffff, 0xffffffff,
123 	0x000008f8, 0x00000015, 0xffffffff,
124 	0x000008fc, 0xffffffff, 0xffffffff,
125 	0x000008f8, 0x00000016, 0xffffffff,
126 	0x000008fc, 0xffffffff, 0xffffffff,
127 	0x000008f8, 0x00000017, 0xffffffff,
128 	0x000008fc, 0xffffffff, 0xffffffff,
129 	0x000008f8, 0x00000018, 0xffffffff,
130 	0x000008fc, 0xffffffff, 0xffffffff,
131 	0x000008f8, 0x00000019, 0xffffffff,
132 	0x000008fc, 0xffffffff, 0xffffffff,
133 	0x000008f8, 0x0000001a, 0xffffffff,
134 	0x000008fc, 0xffffffff, 0xffffffff,
135 	0x000008f8, 0x0000001b, 0xffffffff,
136 	0x000008fc, 0xffffffff, 0xffffffff,
137 	0x000008f8, 0x00000020, 0xffffffff,
138 	0x000008fc, 0x00000000, 0xffffffff,
139 	0x000008f8, 0x00000021, 0xffffffff,
140 	0x000008fc, 0x00000000, 0xffffffff,
141 	0x000008f8, 0x00000022, 0xffffffff,
142 	0x000008fc, 0x00000000, 0xffffffff,
143 	0x000008f8, 0x00000023, 0xffffffff,
144 	0x000008fc, 0x00000000, 0xffffffff,
145 	0x000008f8, 0x00000024, 0xffffffff,
146 	0x000008fc, 0x00000000, 0xffffffff,
147 	0x000008f8, 0x00000025, 0xffffffff,
148 	0x000008fc, 0x00000000, 0xffffffff,
149 	0x000008f8, 0x00000026, 0xffffffff,
150 	0x000008fc, 0x00000000, 0xffffffff,
151 	0x000008f8, 0x00000027, 0xffffffff,
152 	0x000008fc, 0x00000000, 0xffffffff,
153 	0x000008f8, 0x00000028, 0xffffffff,
154 	0x000008fc, 0x00000000, 0xffffffff,
155 	0x000008f8, 0x00000029, 0xffffffff,
156 	0x000008fc, 0x00000000, 0xffffffff,
157 	0x000008f8, 0x0000002a, 0xffffffff,
158 	0x000008fc, 0x00000000, 0xffffffff,
159 	0x000008f8, 0x0000002b, 0xffffffff,
160 	0x000008fc, 0x00000000, 0xffffffff,
161 	0x00000644, 0x000f7912, 0x001f4180,
162 	0x00000644, 0x000f3812, 0x001f4180
163 };
164 #define BARTS_CGCG_CGLS_DISABLE_LENGTH sizeof(barts_cgcg_cgls_disable) / (3 * sizeof(u32))
165 
166 static const u32 barts_cgcg_cgls_enable[] =
167 {
168 	/* 0x0000c124, 0x84180000, 0x00180000, */
169 	0x00000644, 0x000f7892, 0x001f4080,
170 	0x000008f8, 0x00000010, 0xffffffff,
171 	0x000008fc, 0x00000000, 0xffffffff,
172 	0x000008f8, 0x00000011, 0xffffffff,
173 	0x000008fc, 0x00000000, 0xffffffff,
174 	0x000008f8, 0x00000012, 0xffffffff,
175 	0x000008fc, 0x00000000, 0xffffffff,
176 	0x000008f8, 0x00000013, 0xffffffff,
177 	0x000008fc, 0x00000000, 0xffffffff,
178 	0x000008f8, 0x00000014, 0xffffffff,
179 	0x000008fc, 0x00000000, 0xffffffff,
180 	0x000008f8, 0x00000015, 0xffffffff,
181 	0x000008fc, 0x00000000, 0xffffffff,
182 	0x000008f8, 0x00000016, 0xffffffff,
183 	0x000008fc, 0x00000000, 0xffffffff,
184 	0x000008f8, 0x00000017, 0xffffffff,
185 	0x000008fc, 0x00000000, 0xffffffff,
186 	0x000008f8, 0x00000018, 0xffffffff,
187 	0x000008fc, 0x00000000, 0xffffffff,
188 	0x000008f8, 0x00000019, 0xffffffff,
189 	0x000008fc, 0x00000000, 0xffffffff,
190 	0x000008f8, 0x0000001a, 0xffffffff,
191 	0x000008fc, 0x00000000, 0xffffffff,
192 	0x000008f8, 0x0000001b, 0xffffffff,
193 	0x000008fc, 0x00000000, 0xffffffff,
194 	0x000008f8, 0x00000020, 0xffffffff,
195 	0x000008fc, 0xffffffff, 0xffffffff,
196 	0x000008f8, 0x00000021, 0xffffffff,
197 	0x000008fc, 0xffffffff, 0xffffffff,
198 	0x000008f8, 0x00000022, 0xffffffff,
199 	0x000008fc, 0xffffffff, 0xffffffff,
200 	0x000008f8, 0x00000023, 0xffffffff,
201 	0x000008fc, 0xffffffff, 0xffffffff,
202 	0x000008f8, 0x00000024, 0xffffffff,
203 	0x000008fc, 0xffffffff, 0xffffffff,
204 	0x000008f8, 0x00000025, 0xffffffff,
205 	0x000008fc, 0xffffffff, 0xffffffff,
206 	0x000008f8, 0x00000026, 0xffffffff,
207 	0x000008fc, 0xffffffff, 0xffffffff,
208 	0x000008f8, 0x00000027, 0xffffffff,
209 	0x000008fc, 0xffffffff, 0xffffffff,
210 	0x000008f8, 0x00000028, 0xffffffff,
211 	0x000008fc, 0xffffffff, 0xffffffff,
212 	0x000008f8, 0x00000029, 0xffffffff,
213 	0x000008fc, 0xffffffff, 0xffffffff,
214 	0x000008f8, 0x0000002a, 0xffffffff,
215 	0x000008fc, 0xffffffff, 0xffffffff,
216 	0x000008f8, 0x0000002b, 0xffffffff,
217 	0x000008fc, 0xffffffff, 0xffffffff
218 };
219 #define BARTS_CGCG_CGLS_ENABLE_LENGTH sizeof(barts_cgcg_cgls_enable) / (3 * sizeof(u32))
220 
221 static const u32 barts_mgcg_default[] =
222 {
223 	0x0000802c, 0xc0000000, 0xffffffff,
224 	0x00005448, 0x00000100, 0xffffffff,
225 	0x000055e4, 0x00600100, 0xffffffff,
226 	0x0000160c, 0x00000100, 0xffffffff,
227 	0x0000c164, 0x00000100, 0xffffffff,
228 	0x00008a18, 0x00000100, 0xffffffff,
229 	0x0000897c, 0x06000100, 0xffffffff,
230 	0x00008b28, 0x00000100, 0xffffffff,
231 	0x00009144, 0x00000100, 0xffffffff,
232 	0x00009a60, 0x00000100, 0xffffffff,
233 	0x00009868, 0x00000100, 0xffffffff,
234 	0x00008d58, 0x00000100, 0xffffffff,
235 	0x00009510, 0x00000100, 0xffffffff,
236 	0x0000949c, 0x00000100, 0xffffffff,
237 	0x00009654, 0x00000100, 0xffffffff,
238 	0x00009030, 0x00000100, 0xffffffff,
239 	0x00009034, 0x00000100, 0xffffffff,
240 	0x00009038, 0x00000100, 0xffffffff,
241 	0x0000903c, 0x00000100, 0xffffffff,
242 	0x00009040, 0x00000100, 0xffffffff,
243 	0x0000a200, 0x00000100, 0xffffffff,
244 	0x0000a204, 0x00000100, 0xffffffff,
245 	0x0000a208, 0x00000100, 0xffffffff,
246 	0x0000a20c, 0x00000100, 0xffffffff,
247 	0x0000977c, 0x00000100, 0xffffffff,
248 	0x00003f80, 0x00000100, 0xffffffff,
249 	0x0000a210, 0x00000100, 0xffffffff,
250 	0x0000a214, 0x00000100, 0xffffffff,
251 	0x000004d8, 0x00000100, 0xffffffff,
252 	0x00009784, 0x00000100, 0xffffffff,
253 	0x00009698, 0x00000100, 0xffffffff,
254 	0x000004d4, 0x00000200, 0xffffffff,
255 	0x000004d0, 0x00000000, 0xffffffff,
256 	0x000030cc, 0x00000100, 0xffffffff,
257 	0x0000d0c0, 0xff000100, 0xffffffff,
258 	0x0000802c, 0x40000000, 0xffffffff,
259 	0x0000915c, 0x00010000, 0xffffffff,
260 	0x00009160, 0x00030002, 0xffffffff,
261 	0x00009164, 0x00050004, 0xffffffff,
262 	0x00009168, 0x00070006, 0xffffffff,
263 	0x00009178, 0x00070000, 0xffffffff,
264 	0x0000917c, 0x00030002, 0xffffffff,
265 	0x00009180, 0x00050004, 0xffffffff,
266 	0x0000918c, 0x00010006, 0xffffffff,
267 	0x00009190, 0x00090008, 0xffffffff,
268 	0x00009194, 0x00070000, 0xffffffff,
269 	0x00009198, 0x00030002, 0xffffffff,
270 	0x0000919c, 0x00050004, 0xffffffff,
271 	0x000091a8, 0x00010006, 0xffffffff,
272 	0x000091ac, 0x00090008, 0xffffffff,
273 	0x000091b0, 0x00070000, 0xffffffff,
274 	0x000091b4, 0x00030002, 0xffffffff,
275 	0x000091b8, 0x00050004, 0xffffffff,
276 	0x000091c4, 0x00010006, 0xffffffff,
277 	0x000091c8, 0x00090008, 0xffffffff,
278 	0x000091cc, 0x00070000, 0xffffffff,
279 	0x000091d0, 0x00030002, 0xffffffff,
280 	0x000091d4, 0x00050004, 0xffffffff,
281 	0x000091e0, 0x00010006, 0xffffffff,
282 	0x000091e4, 0x00090008, 0xffffffff,
283 	0x000091e8, 0x00000000, 0xffffffff,
284 	0x000091ec, 0x00070000, 0xffffffff,
285 	0x000091f0, 0x00030002, 0xffffffff,
286 	0x000091f4, 0x00050004, 0xffffffff,
287 	0x00009200, 0x00010006, 0xffffffff,
288 	0x00009204, 0x00090008, 0xffffffff,
289 	0x00009208, 0x00070000, 0xffffffff,
290 	0x0000920c, 0x00030002, 0xffffffff,
291 	0x00009210, 0x00050004, 0xffffffff,
292 	0x0000921c, 0x00010006, 0xffffffff,
293 	0x00009220, 0x00090008, 0xffffffff,
294 	0x00009224, 0x00070000, 0xffffffff,
295 	0x00009228, 0x00030002, 0xffffffff,
296 	0x0000922c, 0x00050004, 0xffffffff,
297 	0x00009238, 0x00010006, 0xffffffff,
298 	0x0000923c, 0x00090008, 0xffffffff,
299 	0x00009294, 0x00000000, 0xffffffff,
300 	0x0000802c, 0x40010000, 0xffffffff,
301 	0x0000915c, 0x00010000, 0xffffffff,
302 	0x00009160, 0x00030002, 0xffffffff,
303 	0x00009164, 0x00050004, 0xffffffff,
304 	0x00009168, 0x00070006, 0xffffffff,
305 	0x00009178, 0x00070000, 0xffffffff,
306 	0x0000917c, 0x00030002, 0xffffffff,
307 	0x00009180, 0x00050004, 0xffffffff,
308 	0x0000918c, 0x00010006, 0xffffffff,
309 	0x00009190, 0x00090008, 0xffffffff,
310 	0x00009194, 0x00070000, 0xffffffff,
311 	0x00009198, 0x00030002, 0xffffffff,
312 	0x0000919c, 0x00050004, 0xffffffff,
313 	0x000091a8, 0x00010006, 0xffffffff,
314 	0x000091ac, 0x00090008, 0xffffffff,
315 	0x000091b0, 0x00070000, 0xffffffff,
316 	0x000091b4, 0x00030002, 0xffffffff,
317 	0x000091b8, 0x00050004, 0xffffffff,
318 	0x000091c4, 0x00010006, 0xffffffff,
319 	0x000091c8, 0x00090008, 0xffffffff,
320 	0x000091cc, 0x00070000, 0xffffffff,
321 	0x000091d0, 0x00030002, 0xffffffff,
322 	0x000091d4, 0x00050004, 0xffffffff,
323 	0x000091e0, 0x00010006, 0xffffffff,
324 	0x000091e4, 0x00090008, 0xffffffff,
325 	0x000091e8, 0x00000000, 0xffffffff,
326 	0x000091ec, 0x00070000, 0xffffffff,
327 	0x000091f0, 0x00030002, 0xffffffff,
328 	0x000091f4, 0x00050004, 0xffffffff,
329 	0x00009200, 0x00010006, 0xffffffff,
330 	0x00009204, 0x00090008, 0xffffffff,
331 	0x00009208, 0x00070000, 0xffffffff,
332 	0x0000920c, 0x00030002, 0xffffffff,
333 	0x00009210, 0x00050004, 0xffffffff,
334 	0x0000921c, 0x00010006, 0xffffffff,
335 	0x00009220, 0x00090008, 0xffffffff,
336 	0x00009224, 0x00070000, 0xffffffff,
337 	0x00009228, 0x00030002, 0xffffffff,
338 	0x0000922c, 0x00050004, 0xffffffff,
339 	0x00009238, 0x00010006, 0xffffffff,
340 	0x0000923c, 0x00090008, 0xffffffff,
341 	0x00009294, 0x00000000, 0xffffffff,
342 	0x0000802c, 0xc0000000, 0xffffffff,
343 	0x000008f8, 0x00000010, 0xffffffff,
344 	0x000008fc, 0x00000000, 0xffffffff,
345 	0x000008f8, 0x00000011, 0xffffffff,
346 	0x000008fc, 0x00000000, 0xffffffff,
347 	0x000008f8, 0x00000012, 0xffffffff,
348 	0x000008fc, 0x00000000, 0xffffffff,
349 	0x000008f8, 0x00000013, 0xffffffff,
350 	0x000008fc, 0x00000000, 0xffffffff,
351 	0x000008f8, 0x00000014, 0xffffffff,
352 	0x000008fc, 0x00000000, 0xffffffff,
353 	0x000008f8, 0x00000015, 0xffffffff,
354 	0x000008fc, 0x00000000, 0xffffffff,
355 	0x000008f8, 0x00000016, 0xffffffff,
356 	0x000008fc, 0x00000000, 0xffffffff,
357 	0x000008f8, 0x00000017, 0xffffffff,
358 	0x000008fc, 0x00000000, 0xffffffff,
359 	0x000008f8, 0x00000018, 0xffffffff,
360 	0x000008fc, 0x00000000, 0xffffffff,
361 	0x000008f8, 0x00000019, 0xffffffff,
362 	0x000008fc, 0x00000000, 0xffffffff,
363 	0x000008f8, 0x0000001a, 0xffffffff,
364 	0x000008fc, 0x00000000, 0xffffffff,
365 	0x000008f8, 0x0000001b, 0xffffffff,
366 	0x000008fc, 0x00000000, 0xffffffff
367 };
368 #define BARTS_MGCG_DEFAULT_LENGTH sizeof(barts_mgcg_default) / (3 * sizeof(u32))
369 
370 static const u32 barts_mgcg_disable[] =
371 {
372 	0x0000802c, 0xc0000000, 0xffffffff,
373 	0x000008f8, 0x00000000, 0xffffffff,
374 	0x000008fc, 0xffffffff, 0xffffffff,
375 	0x000008f8, 0x00000001, 0xffffffff,
376 	0x000008fc, 0xffffffff, 0xffffffff,
377 	0x000008f8, 0x00000002, 0xffffffff,
378 	0x000008fc, 0xffffffff, 0xffffffff,
379 	0x000008f8, 0x00000003, 0xffffffff,
380 	0x000008fc, 0xffffffff, 0xffffffff,
381 	0x00009150, 0x00600000, 0xffffffff
382 };
383 #define BARTS_MGCG_DISABLE_LENGTH sizeof(barts_mgcg_disable) / (3 * sizeof(u32))
384 
385 static const u32 barts_mgcg_enable[] =
386 {
387 	0x0000802c, 0xc0000000, 0xffffffff,
388 	0x000008f8, 0x00000000, 0xffffffff,
389 	0x000008fc, 0x00000000, 0xffffffff,
390 	0x000008f8, 0x00000001, 0xffffffff,
391 	0x000008fc, 0x00000000, 0xffffffff,
392 	0x000008f8, 0x00000002, 0xffffffff,
393 	0x000008fc, 0x00000000, 0xffffffff,
394 	0x000008f8, 0x00000003, 0xffffffff,
395 	0x000008fc, 0x00000000, 0xffffffff,
396 	0x00009150, 0x81944000, 0xffffffff
397 };
398 #define BARTS_MGCG_ENABLE_LENGTH sizeof(barts_mgcg_enable) / (3 * sizeof(u32))
399 
400 //********* CAICOS **************//
401 static const u32 caicos_cgcg_cgls_default[] =
402 {
403 	0x000008f8, 0x00000010, 0xffffffff,
404 	0x000008fc, 0x00000000, 0xffffffff,
405 	0x000008f8, 0x00000011, 0xffffffff,
406 	0x000008fc, 0x00000000, 0xffffffff,
407 	0x000008f8, 0x00000012, 0xffffffff,
408 	0x000008fc, 0x00000000, 0xffffffff,
409 	0x000008f8, 0x00000013, 0xffffffff,
410 	0x000008fc, 0x00000000, 0xffffffff,
411 	0x000008f8, 0x00000014, 0xffffffff,
412 	0x000008fc, 0x00000000, 0xffffffff,
413 	0x000008f8, 0x00000015, 0xffffffff,
414 	0x000008fc, 0x00000000, 0xffffffff,
415 	0x000008f8, 0x00000016, 0xffffffff,
416 	0x000008fc, 0x00000000, 0xffffffff,
417 	0x000008f8, 0x00000017, 0xffffffff,
418 	0x000008fc, 0x00000000, 0xffffffff,
419 	0x000008f8, 0x00000018, 0xffffffff,
420 	0x000008fc, 0x00000000, 0xffffffff,
421 	0x000008f8, 0x00000019, 0xffffffff,
422 	0x000008fc, 0x00000000, 0xffffffff,
423 	0x000008f8, 0x0000001a, 0xffffffff,
424 	0x000008fc, 0x00000000, 0xffffffff,
425 	0x000008f8, 0x0000001b, 0xffffffff,
426 	0x000008fc, 0x00000000, 0xffffffff,
427 	0x000008f8, 0x00000020, 0xffffffff,
428 	0x000008fc, 0x00000000, 0xffffffff,
429 	0x000008f8, 0x00000021, 0xffffffff,
430 	0x000008fc, 0x00000000, 0xffffffff,
431 	0x000008f8, 0x00000022, 0xffffffff,
432 	0x000008fc, 0x00000000, 0xffffffff,
433 	0x000008f8, 0x00000023, 0xffffffff,
434 	0x000008fc, 0x00000000, 0xffffffff,
435 	0x000008f8, 0x00000024, 0xffffffff,
436 	0x000008fc, 0x00000000, 0xffffffff,
437 	0x000008f8, 0x00000025, 0xffffffff,
438 	0x000008fc, 0x00000000, 0xffffffff,
439 	0x000008f8, 0x00000026, 0xffffffff,
440 	0x000008fc, 0x00000000, 0xffffffff,
441 	0x000008f8, 0x00000027, 0xffffffff,
442 	0x000008fc, 0x00000000, 0xffffffff,
443 	0x000008f8, 0x00000028, 0xffffffff,
444 	0x000008fc, 0x00000000, 0xffffffff,
445 	0x000008f8, 0x00000029, 0xffffffff,
446 	0x000008fc, 0x00000000, 0xffffffff,
447 	0x000008f8, 0x0000002a, 0xffffffff,
448 	0x000008fc, 0x00000000, 0xffffffff,
449 	0x000008f8, 0x0000002b, 0xffffffff,
450 	0x000008fc, 0x00000000, 0xffffffff
451 };
452 #define CAICOS_CGCG_CGLS_DEFAULT_LENGTH sizeof(caicos_cgcg_cgls_default) / (3 * sizeof(u32))
453 
454 static const u32 caicos_cgcg_cgls_disable[] =
455 {
456 	0x000008f8, 0x00000010, 0xffffffff,
457 	0x000008fc, 0xffffffff, 0xffffffff,
458 	0x000008f8, 0x00000011, 0xffffffff,
459 	0x000008fc, 0xffffffff, 0xffffffff,
460 	0x000008f8, 0x00000012, 0xffffffff,
461 	0x000008fc, 0xffffffff, 0xffffffff,
462 	0x000008f8, 0x00000013, 0xffffffff,
463 	0x000008fc, 0xffffffff, 0xffffffff,
464 	0x000008f8, 0x00000014, 0xffffffff,
465 	0x000008fc, 0xffffffff, 0xffffffff,
466 	0x000008f8, 0x00000015, 0xffffffff,
467 	0x000008fc, 0xffffffff, 0xffffffff,
468 	0x000008f8, 0x00000016, 0xffffffff,
469 	0x000008fc, 0xffffffff, 0xffffffff,
470 	0x000008f8, 0x00000017, 0xffffffff,
471 	0x000008fc, 0xffffffff, 0xffffffff,
472 	0x000008f8, 0x00000018, 0xffffffff,
473 	0x000008fc, 0xffffffff, 0xffffffff,
474 	0x000008f8, 0x00000019, 0xffffffff,
475 	0x000008fc, 0xffffffff, 0xffffffff,
476 	0x000008f8, 0x0000001a, 0xffffffff,
477 	0x000008fc, 0xffffffff, 0xffffffff,
478 	0x000008f8, 0x0000001b, 0xffffffff,
479 	0x000008fc, 0xffffffff, 0xffffffff,
480 	0x000008f8, 0x00000020, 0xffffffff,
481 	0x000008fc, 0x00000000, 0xffffffff,
482 	0x000008f8, 0x00000021, 0xffffffff,
483 	0x000008fc, 0x00000000, 0xffffffff,
484 	0x000008f8, 0x00000022, 0xffffffff,
485 	0x000008fc, 0x00000000, 0xffffffff,
486 	0x000008f8, 0x00000023, 0xffffffff,
487 	0x000008fc, 0x00000000, 0xffffffff,
488 	0x000008f8, 0x00000024, 0xffffffff,
489 	0x000008fc, 0x00000000, 0xffffffff,
490 	0x000008f8, 0x00000025, 0xffffffff,
491 	0x000008fc, 0x00000000, 0xffffffff,
492 	0x000008f8, 0x00000026, 0xffffffff,
493 	0x000008fc, 0x00000000, 0xffffffff,
494 	0x000008f8, 0x00000027, 0xffffffff,
495 	0x000008fc, 0x00000000, 0xffffffff,
496 	0x000008f8, 0x00000028, 0xffffffff,
497 	0x000008fc, 0x00000000, 0xffffffff,
498 	0x000008f8, 0x00000029, 0xffffffff,
499 	0x000008fc, 0x00000000, 0xffffffff,
500 	0x000008f8, 0x0000002a, 0xffffffff,
501 	0x000008fc, 0x00000000, 0xffffffff,
502 	0x000008f8, 0x0000002b, 0xffffffff,
503 	0x000008fc, 0x00000000, 0xffffffff,
504 	0x00000644, 0x000f7912, 0x001f4180,
505 	0x00000644, 0x000f3812, 0x001f4180
506 };
507 #define CAICOS_CGCG_CGLS_DISABLE_LENGTH sizeof(caicos_cgcg_cgls_disable) / (3 * sizeof(u32))
508 
509 static const u32 caicos_cgcg_cgls_enable[] =
510 {
511 	/* 0x0000c124, 0x84180000, 0x00180000, */
512 	0x00000644, 0x000f7892, 0x001f4080,
513 	0x000008f8, 0x00000010, 0xffffffff,
514 	0x000008fc, 0x00000000, 0xffffffff,
515 	0x000008f8, 0x00000011, 0xffffffff,
516 	0x000008fc, 0x00000000, 0xffffffff,
517 	0x000008f8, 0x00000012, 0xffffffff,
518 	0x000008fc, 0x00000000, 0xffffffff,
519 	0x000008f8, 0x00000013, 0xffffffff,
520 	0x000008fc, 0x00000000, 0xffffffff,
521 	0x000008f8, 0x00000014, 0xffffffff,
522 	0x000008fc, 0x00000000, 0xffffffff,
523 	0x000008f8, 0x00000015, 0xffffffff,
524 	0x000008fc, 0x00000000, 0xffffffff,
525 	0x000008f8, 0x00000016, 0xffffffff,
526 	0x000008fc, 0x00000000, 0xffffffff,
527 	0x000008f8, 0x00000017, 0xffffffff,
528 	0x000008fc, 0x00000000, 0xffffffff,
529 	0x000008f8, 0x00000018, 0xffffffff,
530 	0x000008fc, 0x00000000, 0xffffffff,
531 	0x000008f8, 0x00000019, 0xffffffff,
532 	0x000008fc, 0x00000000, 0xffffffff,
533 	0x000008f8, 0x0000001a, 0xffffffff,
534 	0x000008fc, 0x00000000, 0xffffffff,
535 	0x000008f8, 0x0000001b, 0xffffffff,
536 	0x000008fc, 0x00000000, 0xffffffff,
537 	0x000008f8, 0x00000020, 0xffffffff,
538 	0x000008fc, 0xffffffff, 0xffffffff,
539 	0x000008f8, 0x00000021, 0xffffffff,
540 	0x000008fc, 0xffffffff, 0xffffffff,
541 	0x000008f8, 0x00000022, 0xffffffff,
542 	0x000008fc, 0xffffffff, 0xffffffff,
543 	0x000008f8, 0x00000023, 0xffffffff,
544 	0x000008fc, 0xffffffff, 0xffffffff,
545 	0x000008f8, 0x00000024, 0xffffffff,
546 	0x000008fc, 0xffffffff, 0xffffffff,
547 	0x000008f8, 0x00000025, 0xffffffff,
548 	0x000008fc, 0xffffffff, 0xffffffff,
549 	0x000008f8, 0x00000026, 0xffffffff,
550 	0x000008fc, 0xffffffff, 0xffffffff,
551 	0x000008f8, 0x00000027, 0xffffffff,
552 	0x000008fc, 0xffffffff, 0xffffffff,
553 	0x000008f8, 0x00000028, 0xffffffff,
554 	0x000008fc, 0xffffffff, 0xffffffff,
555 	0x000008f8, 0x00000029, 0xffffffff,
556 	0x000008fc, 0xffffffff, 0xffffffff,
557 	0x000008f8, 0x0000002a, 0xffffffff,
558 	0x000008fc, 0xffffffff, 0xffffffff,
559 	0x000008f8, 0x0000002b, 0xffffffff,
560 	0x000008fc, 0xffffffff, 0xffffffff
561 };
562 #define CAICOS_CGCG_CGLS_ENABLE_LENGTH sizeof(caicos_cgcg_cgls_enable) / (3 * sizeof(u32))
563 
564 static const u32 caicos_mgcg_default[] =
565 {
566 	0x0000802c, 0xc0000000, 0xffffffff,
567 	0x00005448, 0x00000100, 0xffffffff,
568 	0x000055e4, 0x00600100, 0xffffffff,
569 	0x0000160c, 0x00000100, 0xffffffff,
570 	0x0000c164, 0x00000100, 0xffffffff,
571 	0x00008a18, 0x00000100, 0xffffffff,
572 	0x0000897c, 0x06000100, 0xffffffff,
573 	0x00008b28, 0x00000100, 0xffffffff,
574 	0x00009144, 0x00000100, 0xffffffff,
575 	0x00009a60, 0x00000100, 0xffffffff,
576 	0x00009868, 0x00000100, 0xffffffff,
577 	0x00008d58, 0x00000100, 0xffffffff,
578 	0x00009510, 0x00000100, 0xffffffff,
579 	0x0000949c, 0x00000100, 0xffffffff,
580 	0x00009654, 0x00000100, 0xffffffff,
581 	0x00009030, 0x00000100, 0xffffffff,
582 	0x00009034, 0x00000100, 0xffffffff,
583 	0x00009038, 0x00000100, 0xffffffff,
584 	0x0000903c, 0x00000100, 0xffffffff,
585 	0x00009040, 0x00000100, 0xffffffff,
586 	0x0000a200, 0x00000100, 0xffffffff,
587 	0x0000a204, 0x00000100, 0xffffffff,
588 	0x0000a208, 0x00000100, 0xffffffff,
589 	0x0000a20c, 0x00000100, 0xffffffff,
590 	0x0000977c, 0x00000100, 0xffffffff,
591 	0x00003f80, 0x00000100, 0xffffffff,
592 	0x0000a210, 0x00000100, 0xffffffff,
593 	0x0000a214, 0x00000100, 0xffffffff,
594 	0x000004d8, 0x00000100, 0xffffffff,
595 	0x00009784, 0x00000100, 0xffffffff,
596 	0x00009698, 0x00000100, 0xffffffff,
597 	0x000004d4, 0x00000200, 0xffffffff,
598 	0x000004d0, 0x00000000, 0xffffffff,
599 	0x000030cc, 0x00000100, 0xffffffff,
600 	0x0000d0c0, 0xff000100, 0xffffffff,
601 	0x0000915c, 0x00010000, 0xffffffff,
602 	0x00009160, 0x00030002, 0xffffffff,
603 	0x00009164, 0x00050004, 0xffffffff,
604 	0x00009168, 0x00070006, 0xffffffff,
605 	0x00009178, 0x00070000, 0xffffffff,
606 	0x0000917c, 0x00030002, 0xffffffff,
607 	0x00009180, 0x00050004, 0xffffffff,
608 	0x0000918c, 0x00010006, 0xffffffff,
609 	0x00009190, 0x00090008, 0xffffffff,
610 	0x00009194, 0x00070000, 0xffffffff,
611 	0x00009198, 0x00030002, 0xffffffff,
612 	0x0000919c, 0x00050004, 0xffffffff,
613 	0x000091a8, 0x00010006, 0xffffffff,
614 	0x000091ac, 0x00090008, 0xffffffff,
615 	0x000091e8, 0x00000000, 0xffffffff,
616 	0x00009294, 0x00000000, 0xffffffff,
617 	0x000008f8, 0x00000010, 0xffffffff,
618 	0x000008fc, 0x00000000, 0xffffffff,
619 	0x000008f8, 0x00000011, 0xffffffff,
620 	0x000008fc, 0x00000000, 0xffffffff,
621 	0x000008f8, 0x00000012, 0xffffffff,
622 	0x000008fc, 0x00000000, 0xffffffff,
623 	0x000008f8, 0x00000013, 0xffffffff,
624 	0x000008fc, 0x00000000, 0xffffffff,
625 	0x000008f8, 0x00000014, 0xffffffff,
626 	0x000008fc, 0x00000000, 0xffffffff,
627 	0x000008f8, 0x00000015, 0xffffffff,
628 	0x000008fc, 0x00000000, 0xffffffff,
629 	0x000008f8, 0x00000016, 0xffffffff,
630 	0x000008fc, 0x00000000, 0xffffffff,
631 	0x000008f8, 0x00000017, 0xffffffff,
632 	0x000008fc, 0x00000000, 0xffffffff,
633 	0x000008f8, 0x00000018, 0xffffffff,
634 	0x000008fc, 0x00000000, 0xffffffff,
635 	0x000008f8, 0x00000019, 0xffffffff,
636 	0x000008fc, 0x00000000, 0xffffffff,
637 	0x000008f8, 0x0000001a, 0xffffffff,
638 	0x000008fc, 0x00000000, 0xffffffff,
639 	0x000008f8, 0x0000001b, 0xffffffff,
640 	0x000008fc, 0x00000000, 0xffffffff
641 };
642 #define CAICOS_MGCG_DEFAULT_LENGTH sizeof(caicos_mgcg_default) / (3 * sizeof(u32))
643 
644 static const u32 caicos_mgcg_disable[] =
645 {
646 	0x0000802c, 0xc0000000, 0xffffffff,
647 	0x000008f8, 0x00000000, 0xffffffff,
648 	0x000008fc, 0xffffffff, 0xffffffff,
649 	0x000008f8, 0x00000001, 0xffffffff,
650 	0x000008fc, 0xffffffff, 0xffffffff,
651 	0x000008f8, 0x00000002, 0xffffffff,
652 	0x000008fc, 0xffffffff, 0xffffffff,
653 	0x000008f8, 0x00000003, 0xffffffff,
654 	0x000008fc, 0xffffffff, 0xffffffff,
655 	0x00009150, 0x00600000, 0xffffffff
656 };
657 #define CAICOS_MGCG_DISABLE_LENGTH sizeof(caicos_mgcg_disable) / (3 * sizeof(u32))
658 
659 static const u32 caicos_mgcg_enable[] =
660 {
661 	0x0000802c, 0xc0000000, 0xffffffff,
662 	0x000008f8, 0x00000000, 0xffffffff,
663 	0x000008fc, 0x00000000, 0xffffffff,
664 	0x000008f8, 0x00000001, 0xffffffff,
665 	0x000008fc, 0x00000000, 0xffffffff,
666 	0x000008f8, 0x00000002, 0xffffffff,
667 	0x000008fc, 0x00000000, 0xffffffff,
668 	0x000008f8, 0x00000003, 0xffffffff,
669 	0x000008fc, 0x00000000, 0xffffffff,
670 	0x00009150, 0x46944040, 0xffffffff
671 };
672 #define CAICOS_MGCG_ENABLE_LENGTH sizeof(caicos_mgcg_enable) / (3 * sizeof(u32))
673 
674 //********* TURKS **************//
675 static const u32 turks_cgcg_cgls_default[] =
676 {
677 	0x000008f8, 0x00000010, 0xffffffff,
678 	0x000008fc, 0x00000000, 0xffffffff,
679 	0x000008f8, 0x00000011, 0xffffffff,
680 	0x000008fc, 0x00000000, 0xffffffff,
681 	0x000008f8, 0x00000012, 0xffffffff,
682 	0x000008fc, 0x00000000, 0xffffffff,
683 	0x000008f8, 0x00000013, 0xffffffff,
684 	0x000008fc, 0x00000000, 0xffffffff,
685 	0x000008f8, 0x00000014, 0xffffffff,
686 	0x000008fc, 0x00000000, 0xffffffff,
687 	0x000008f8, 0x00000015, 0xffffffff,
688 	0x000008fc, 0x00000000, 0xffffffff,
689 	0x000008f8, 0x00000016, 0xffffffff,
690 	0x000008fc, 0x00000000, 0xffffffff,
691 	0x000008f8, 0x00000017, 0xffffffff,
692 	0x000008fc, 0x00000000, 0xffffffff,
693 	0x000008f8, 0x00000018, 0xffffffff,
694 	0x000008fc, 0x00000000, 0xffffffff,
695 	0x000008f8, 0x00000019, 0xffffffff,
696 	0x000008fc, 0x00000000, 0xffffffff,
697 	0x000008f8, 0x0000001a, 0xffffffff,
698 	0x000008fc, 0x00000000, 0xffffffff,
699 	0x000008f8, 0x0000001b, 0xffffffff,
700 	0x000008fc, 0x00000000, 0xffffffff,
701 	0x000008f8, 0x00000020, 0xffffffff,
702 	0x000008fc, 0x00000000, 0xffffffff,
703 	0x000008f8, 0x00000021, 0xffffffff,
704 	0x000008fc, 0x00000000, 0xffffffff,
705 	0x000008f8, 0x00000022, 0xffffffff,
706 	0x000008fc, 0x00000000, 0xffffffff,
707 	0x000008f8, 0x00000023, 0xffffffff,
708 	0x000008fc, 0x00000000, 0xffffffff,
709 	0x000008f8, 0x00000024, 0xffffffff,
710 	0x000008fc, 0x00000000, 0xffffffff,
711 	0x000008f8, 0x00000025, 0xffffffff,
712 	0x000008fc, 0x00000000, 0xffffffff,
713 	0x000008f8, 0x00000026, 0xffffffff,
714 	0x000008fc, 0x00000000, 0xffffffff,
715 	0x000008f8, 0x00000027, 0xffffffff,
716 	0x000008fc, 0x00000000, 0xffffffff,
717 	0x000008f8, 0x00000028, 0xffffffff,
718 	0x000008fc, 0x00000000, 0xffffffff,
719 	0x000008f8, 0x00000029, 0xffffffff,
720 	0x000008fc, 0x00000000, 0xffffffff,
721 	0x000008f8, 0x0000002a, 0xffffffff,
722 	0x000008fc, 0x00000000, 0xffffffff,
723 	0x000008f8, 0x0000002b, 0xffffffff,
724 	0x000008fc, 0x00000000, 0xffffffff
725 };
726 #define TURKS_CGCG_CGLS_DEFAULT_LENGTH  sizeof(turks_cgcg_cgls_default) / (3 * sizeof(u32))
727 
728 static const u32 turks_cgcg_cgls_disable[] =
729 {
730 	0x000008f8, 0x00000010, 0xffffffff,
731 	0x000008fc, 0xffffffff, 0xffffffff,
732 	0x000008f8, 0x00000011, 0xffffffff,
733 	0x000008fc, 0xffffffff, 0xffffffff,
734 	0x000008f8, 0x00000012, 0xffffffff,
735 	0x000008fc, 0xffffffff, 0xffffffff,
736 	0x000008f8, 0x00000013, 0xffffffff,
737 	0x000008fc, 0xffffffff, 0xffffffff,
738 	0x000008f8, 0x00000014, 0xffffffff,
739 	0x000008fc, 0xffffffff, 0xffffffff,
740 	0x000008f8, 0x00000015, 0xffffffff,
741 	0x000008fc, 0xffffffff, 0xffffffff,
742 	0x000008f8, 0x00000016, 0xffffffff,
743 	0x000008fc, 0xffffffff, 0xffffffff,
744 	0x000008f8, 0x00000017, 0xffffffff,
745 	0x000008fc, 0xffffffff, 0xffffffff,
746 	0x000008f8, 0x00000018, 0xffffffff,
747 	0x000008fc, 0xffffffff, 0xffffffff,
748 	0x000008f8, 0x00000019, 0xffffffff,
749 	0x000008fc, 0xffffffff, 0xffffffff,
750 	0x000008f8, 0x0000001a, 0xffffffff,
751 	0x000008fc, 0xffffffff, 0xffffffff,
752 	0x000008f8, 0x0000001b, 0xffffffff,
753 	0x000008fc, 0xffffffff, 0xffffffff,
754 	0x000008f8, 0x00000020, 0xffffffff,
755 	0x000008fc, 0x00000000, 0xffffffff,
756 	0x000008f8, 0x00000021, 0xffffffff,
757 	0x000008fc, 0x00000000, 0xffffffff,
758 	0x000008f8, 0x00000022, 0xffffffff,
759 	0x000008fc, 0x00000000, 0xffffffff,
760 	0x000008f8, 0x00000023, 0xffffffff,
761 	0x000008fc, 0x00000000, 0xffffffff,
762 	0x000008f8, 0x00000024, 0xffffffff,
763 	0x000008fc, 0x00000000, 0xffffffff,
764 	0x000008f8, 0x00000025, 0xffffffff,
765 	0x000008fc, 0x00000000, 0xffffffff,
766 	0x000008f8, 0x00000026, 0xffffffff,
767 	0x000008fc, 0x00000000, 0xffffffff,
768 	0x000008f8, 0x00000027, 0xffffffff,
769 	0x000008fc, 0x00000000, 0xffffffff,
770 	0x000008f8, 0x00000028, 0xffffffff,
771 	0x000008fc, 0x00000000, 0xffffffff,
772 	0x000008f8, 0x00000029, 0xffffffff,
773 	0x000008fc, 0x00000000, 0xffffffff,
774 	0x000008f8, 0x0000002a, 0xffffffff,
775 	0x000008fc, 0x00000000, 0xffffffff,
776 	0x000008f8, 0x0000002b, 0xffffffff,
777 	0x000008fc, 0x00000000, 0xffffffff,
778 	0x00000644, 0x000f7912, 0x001f4180,
779 	0x00000644, 0x000f3812, 0x001f4180
780 };
781 #define TURKS_CGCG_CGLS_DISABLE_LENGTH sizeof(turks_cgcg_cgls_disable) / (3 * sizeof(u32))
782 
783 static const u32 turks_cgcg_cgls_enable[] =
784 {
785 	/* 0x0000c124, 0x84180000, 0x00180000, */
786 	0x00000644, 0x000f7892, 0x001f4080,
787 	0x000008f8, 0x00000010, 0xffffffff,
788 	0x000008fc, 0x00000000, 0xffffffff,
789 	0x000008f8, 0x00000011, 0xffffffff,
790 	0x000008fc, 0x00000000, 0xffffffff,
791 	0x000008f8, 0x00000012, 0xffffffff,
792 	0x000008fc, 0x00000000, 0xffffffff,
793 	0x000008f8, 0x00000013, 0xffffffff,
794 	0x000008fc, 0x00000000, 0xffffffff,
795 	0x000008f8, 0x00000014, 0xffffffff,
796 	0x000008fc, 0x00000000, 0xffffffff,
797 	0x000008f8, 0x00000015, 0xffffffff,
798 	0x000008fc, 0x00000000, 0xffffffff,
799 	0x000008f8, 0x00000016, 0xffffffff,
800 	0x000008fc, 0x00000000, 0xffffffff,
801 	0x000008f8, 0x00000017, 0xffffffff,
802 	0x000008fc, 0x00000000, 0xffffffff,
803 	0x000008f8, 0x00000018, 0xffffffff,
804 	0x000008fc, 0x00000000, 0xffffffff,
805 	0x000008f8, 0x00000019, 0xffffffff,
806 	0x000008fc, 0x00000000, 0xffffffff,
807 	0x000008f8, 0x0000001a, 0xffffffff,
808 	0x000008fc, 0x00000000, 0xffffffff,
809 	0x000008f8, 0x0000001b, 0xffffffff,
810 	0x000008fc, 0x00000000, 0xffffffff,
811 	0x000008f8, 0x00000020, 0xffffffff,
812 	0x000008fc, 0xffffffff, 0xffffffff,
813 	0x000008f8, 0x00000021, 0xffffffff,
814 	0x000008fc, 0xffffffff, 0xffffffff,
815 	0x000008f8, 0x00000022, 0xffffffff,
816 	0x000008fc, 0xffffffff, 0xffffffff,
817 	0x000008f8, 0x00000023, 0xffffffff,
818 	0x000008fc, 0xffffffff, 0xffffffff,
819 	0x000008f8, 0x00000024, 0xffffffff,
820 	0x000008fc, 0xffffffff, 0xffffffff,
821 	0x000008f8, 0x00000025, 0xffffffff,
822 	0x000008fc, 0xffffffff, 0xffffffff,
823 	0x000008f8, 0x00000026, 0xffffffff,
824 	0x000008fc, 0xffffffff, 0xffffffff,
825 	0x000008f8, 0x00000027, 0xffffffff,
826 	0x000008fc, 0xffffffff, 0xffffffff,
827 	0x000008f8, 0x00000028, 0xffffffff,
828 	0x000008fc, 0xffffffff, 0xffffffff,
829 	0x000008f8, 0x00000029, 0xffffffff,
830 	0x000008fc, 0xffffffff, 0xffffffff,
831 	0x000008f8, 0x0000002a, 0xffffffff,
832 	0x000008fc, 0xffffffff, 0xffffffff,
833 	0x000008f8, 0x0000002b, 0xffffffff,
834 	0x000008fc, 0xffffffff, 0xffffffff
835 };
836 #define TURKS_CGCG_CGLS_ENABLE_LENGTH sizeof(turks_cgcg_cgls_enable) / (3 * sizeof(u32))
837 
838 // These are the sequences for turks_mgcg_shls
839 static const u32 turks_mgcg_default[] =
840 {
841 	0x0000802c, 0xc0000000, 0xffffffff,
842 	0x00005448, 0x00000100, 0xffffffff,
843 	0x000055e4, 0x00600100, 0xffffffff,
844 	0x0000160c, 0x00000100, 0xffffffff,
845 	0x0000c164, 0x00000100, 0xffffffff,
846 	0x00008a18, 0x00000100, 0xffffffff,
847 	0x0000897c, 0x06000100, 0xffffffff,
848 	0x00008b28, 0x00000100, 0xffffffff,
849 	0x00009144, 0x00000100, 0xffffffff,
850 	0x00009a60, 0x00000100, 0xffffffff,
851 	0x00009868, 0x00000100, 0xffffffff,
852 	0x00008d58, 0x00000100, 0xffffffff,
853 	0x00009510, 0x00000100, 0xffffffff,
854 	0x0000949c, 0x00000100, 0xffffffff,
855 	0x00009654, 0x00000100, 0xffffffff,
856 	0x00009030, 0x00000100, 0xffffffff,
857 	0x00009034, 0x00000100, 0xffffffff,
858 	0x00009038, 0x00000100, 0xffffffff,
859 	0x0000903c, 0x00000100, 0xffffffff,
860 	0x00009040, 0x00000100, 0xffffffff,
861 	0x0000a200, 0x00000100, 0xffffffff,
862 	0x0000a204, 0x00000100, 0xffffffff,
863 	0x0000a208, 0x00000100, 0xffffffff,
864 	0x0000a20c, 0x00000100, 0xffffffff,
865 	0x0000977c, 0x00000100, 0xffffffff,
866 	0x00003f80, 0x00000100, 0xffffffff,
867 	0x0000a210, 0x00000100, 0xffffffff,
868 	0x0000a214, 0x00000100, 0xffffffff,
869 	0x000004d8, 0x00000100, 0xffffffff,
870 	0x00009784, 0x00000100, 0xffffffff,
871 	0x00009698, 0x00000100, 0xffffffff,
872 	0x000004d4, 0x00000200, 0xffffffff,
873 	0x000004d0, 0x00000000, 0xffffffff,
874 	0x000030cc, 0x00000100, 0xffffffff,
875 	0x0000d0c0, 0x00000100, 0xffffffff,
876 	0x0000915c, 0x00010000, 0xffffffff,
877 	0x00009160, 0x00030002, 0xffffffff,
878 	0x00009164, 0x00050004, 0xffffffff,
879 	0x00009168, 0x00070006, 0xffffffff,
880 	0x00009178, 0x00070000, 0xffffffff,
881 	0x0000917c, 0x00030002, 0xffffffff,
882 	0x00009180, 0x00050004, 0xffffffff,
883 	0x0000918c, 0x00010006, 0xffffffff,
884 	0x00009190, 0x00090008, 0xffffffff,
885 	0x00009194, 0x00070000, 0xffffffff,
886 	0x00009198, 0x00030002, 0xffffffff,
887 	0x0000919c, 0x00050004, 0xffffffff,
888 	0x000091a8, 0x00010006, 0xffffffff,
889 	0x000091ac, 0x00090008, 0xffffffff,
890 	0x000091b0, 0x00070000, 0xffffffff,
891 	0x000091b4, 0x00030002, 0xffffffff,
892 	0x000091b8, 0x00050004, 0xffffffff,
893 	0x000091c4, 0x00010006, 0xffffffff,
894 	0x000091c8, 0x00090008, 0xffffffff,
895 	0x000091cc, 0x00070000, 0xffffffff,
896 	0x000091d0, 0x00030002, 0xffffffff,
897 	0x000091d4, 0x00050004, 0xffffffff,
898 	0x000091e0, 0x00010006, 0xffffffff,
899 	0x000091e4, 0x00090008, 0xffffffff,
900 	0x000091e8, 0x00000000, 0xffffffff,
901 	0x000091ec, 0x00070000, 0xffffffff,
902 	0x000091f0, 0x00030002, 0xffffffff,
903 	0x000091f4, 0x00050004, 0xffffffff,
904 	0x00009200, 0x00010006, 0xffffffff,
905 	0x00009204, 0x00090008, 0xffffffff,
906 	0x00009208, 0x00070000, 0xffffffff,
907 	0x0000920c, 0x00030002, 0xffffffff,
908 	0x00009210, 0x00050004, 0xffffffff,
909 	0x0000921c, 0x00010006, 0xffffffff,
910 	0x00009220, 0x00090008, 0xffffffff,
911 	0x00009294, 0x00000000, 0xffffffff,
912 	0x000008f8, 0x00000010, 0xffffffff,
913 	0x000008fc, 0x00000000, 0xffffffff,
914 	0x000008f8, 0x00000011, 0xffffffff,
915 	0x000008fc, 0x00000000, 0xffffffff,
916 	0x000008f8, 0x00000012, 0xffffffff,
917 	0x000008fc, 0x00000000, 0xffffffff,
918 	0x000008f8, 0x00000013, 0xffffffff,
919 	0x000008fc, 0x00000000, 0xffffffff,
920 	0x000008f8, 0x00000014, 0xffffffff,
921 	0x000008fc, 0x00000000, 0xffffffff,
922 	0x000008f8, 0x00000015, 0xffffffff,
923 	0x000008fc, 0x00000000, 0xffffffff,
924 	0x000008f8, 0x00000016, 0xffffffff,
925 	0x000008fc, 0x00000000, 0xffffffff,
926 	0x000008f8, 0x00000017, 0xffffffff,
927 	0x000008fc, 0x00000000, 0xffffffff,
928 	0x000008f8, 0x00000018, 0xffffffff,
929 	0x000008fc, 0x00000000, 0xffffffff,
930 	0x000008f8, 0x00000019, 0xffffffff,
931 	0x000008fc, 0x00000000, 0xffffffff,
932 	0x000008f8, 0x0000001a, 0xffffffff,
933 	0x000008fc, 0x00000000, 0xffffffff,
934 	0x000008f8, 0x0000001b, 0xffffffff,
935 	0x000008fc, 0x00000000, 0xffffffff
936 };
937 #define TURKS_MGCG_DEFAULT_LENGTH sizeof(turks_mgcg_default) / (3 * sizeof(u32))
938 
939 static const u32 turks_mgcg_disable[] =
940 {
941 	0x0000802c, 0xc0000000, 0xffffffff,
942 	0x000008f8, 0x00000000, 0xffffffff,
943 	0x000008fc, 0xffffffff, 0xffffffff,
944 	0x000008f8, 0x00000001, 0xffffffff,
945 	0x000008fc, 0xffffffff, 0xffffffff,
946 	0x000008f8, 0x00000002, 0xffffffff,
947 	0x000008fc, 0xffffffff, 0xffffffff,
948 	0x000008f8, 0x00000003, 0xffffffff,
949 	0x000008fc, 0xffffffff, 0xffffffff,
950 	0x00009150, 0x00600000, 0xffffffff
951 };
952 #define TURKS_MGCG_DISABLE_LENGTH sizeof(turks_mgcg_disable) / (3 * sizeof(u32))
953 
954 static const u32 turks_mgcg_enable[] =
955 {
956 	0x0000802c, 0xc0000000, 0xffffffff,
957 	0x000008f8, 0x00000000, 0xffffffff,
958 	0x000008fc, 0x00000000, 0xffffffff,
959 	0x000008f8, 0x00000001, 0xffffffff,
960 	0x000008fc, 0x00000000, 0xffffffff,
961 	0x000008f8, 0x00000002, 0xffffffff,
962 	0x000008fc, 0x00000000, 0xffffffff,
963 	0x000008f8, 0x00000003, 0xffffffff,
964 	0x000008fc, 0x00000000, 0xffffffff,
965 	0x00009150, 0x6e944000, 0xffffffff
966 };
967 #define TURKS_MGCG_ENABLE_LENGTH sizeof(turks_mgcg_enable) / (3 * sizeof(u32))
968 
969 #endif
970 
971 #ifndef BTC_SYSLS_SEQUENCE
972 #define BTC_SYSLS_SEQUENCE  100
973 
974 
975 //********* BARTS **************//
976 static const u32 barts_sysls_default[] =
977 {
978 	/* Register,   Value,     Mask bits */
979 	0x000055e8, 0x00000000, 0xffffffff,
980 	0x0000d0bc, 0x00000000, 0xffffffff,
981 	0x000015c0, 0x000c1401, 0xffffffff,
982 	0x0000264c, 0x000c0400, 0xffffffff,
983 	0x00002648, 0x000c0400, 0xffffffff,
984 	0x00002650, 0x000c0400, 0xffffffff,
985 	0x000020b8, 0x000c0400, 0xffffffff,
986 	0x000020bc, 0x000c0400, 0xffffffff,
987 	0x000020c0, 0x000c0c80, 0xffffffff,
988 	0x0000f4a0, 0x000000c0, 0xffffffff,
989 	0x0000f4a4, 0x00680fff, 0xffffffff,
990 	0x000004c8, 0x00000001, 0xffffffff,
991 	0x000064ec, 0x00000000, 0xffffffff,
992 	0x00000c7c, 0x00000000, 0xffffffff,
993 	0x00006dfc, 0x00000000, 0xffffffff
994 };
995 #define BARTS_SYSLS_DEFAULT_LENGTH sizeof(barts_sysls_default) / (3 * sizeof(u32))
996 
997 static const u32 barts_sysls_disable[] =
998 {
999 	0x000055e8, 0x00000000, 0xffffffff,
1000 	0x0000d0bc, 0x00000000, 0xffffffff,
1001 	0x000015c0, 0x00041401, 0xffffffff,
1002 	0x0000264c, 0x00040400, 0xffffffff,
1003 	0x00002648, 0x00040400, 0xffffffff,
1004 	0x00002650, 0x00040400, 0xffffffff,
1005 	0x000020b8, 0x00040400, 0xffffffff,
1006 	0x000020bc, 0x00040400, 0xffffffff,
1007 	0x000020c0, 0x00040c80, 0xffffffff,
1008 	0x0000f4a0, 0x000000c0, 0xffffffff,
1009 	0x0000f4a4, 0x00680000, 0xffffffff,
1010 	0x000004c8, 0x00000001, 0xffffffff,
1011 	0x000064ec, 0x00007ffd, 0xffffffff,
1012 	0x00000c7c, 0x0000ff00, 0xffffffff,
1013 	0x00006dfc, 0x0000007f, 0xffffffff
1014 };
1015 #define BARTS_SYSLS_DISABLE_LENGTH sizeof(barts_sysls_disable) / (3 * sizeof(u32))
1016 
1017 static const u32 barts_sysls_enable[] =
1018 {
1019 	0x000055e8, 0x00000001, 0xffffffff,
1020 	0x0000d0bc, 0x00000100, 0xffffffff,
1021 	0x000015c0, 0x000c1401, 0xffffffff,
1022 	0x0000264c, 0x000c0400, 0xffffffff,
1023 	0x00002648, 0x000c0400, 0xffffffff,
1024 	0x00002650, 0x000c0400, 0xffffffff,
1025 	0x000020b8, 0x000c0400, 0xffffffff,
1026 	0x000020bc, 0x000c0400, 0xffffffff,
1027 	0x000020c0, 0x000c0c80, 0xffffffff,
1028 	0x0000f4a0, 0x000000c0, 0xffffffff,
1029 	0x0000f4a4, 0x00680fff, 0xffffffff,
1030 	0x000004c8, 0x00000000, 0xffffffff,
1031 	0x000064ec, 0x00000000, 0xffffffff,
1032 	0x00000c7c, 0x00000000, 0xffffffff,
1033 	0x00006dfc, 0x00000000, 0xffffffff
1034 };
1035 #define BARTS_SYSLS_ENABLE_LENGTH sizeof(barts_sysls_enable) / (3 * sizeof(u32))
1036 
1037 //********* CAICOS **************//
1038 static const u32 caicos_sysls_default[] =
1039 {
1040 	0x000055e8, 0x00000000, 0xffffffff,
1041 	0x0000d0bc, 0x00000000, 0xffffffff,
1042 	0x000015c0, 0x000c1401, 0xffffffff,
1043 	0x0000264c, 0x000c0400, 0xffffffff,
1044 	0x00002648, 0x000c0400, 0xffffffff,
1045 	0x00002650, 0x000c0400, 0xffffffff,
1046 	0x000020b8, 0x000c0400, 0xffffffff,
1047 	0x000020bc, 0x000c0400, 0xffffffff,
1048 	0x0000f4a0, 0x000000c0, 0xffffffff,
1049 	0x0000f4a4, 0x00680fff, 0xffffffff,
1050 	0x000004c8, 0x00000001, 0xffffffff,
1051 	0x000064ec, 0x00000000, 0xffffffff,
1052 	0x00000c7c, 0x00000000, 0xffffffff,
1053 	0x00006dfc, 0x00000000, 0xffffffff
1054 };
1055 #define CAICOS_SYSLS_DEFAULT_LENGTH sizeof(caicos_sysls_default) / (3 * sizeof(u32))
1056 
1057 static const u32 caicos_sysls_disable[] =
1058 {
1059 	0x000055e8, 0x00000000, 0xffffffff,
1060 	0x0000d0bc, 0x00000000, 0xffffffff,
1061 	0x000015c0, 0x00041401, 0xffffffff,
1062 	0x0000264c, 0x00040400, 0xffffffff,
1063 	0x00002648, 0x00040400, 0xffffffff,
1064 	0x00002650, 0x00040400, 0xffffffff,
1065 	0x000020b8, 0x00040400, 0xffffffff,
1066 	0x000020bc, 0x00040400, 0xffffffff,
1067 	0x0000f4a0, 0x000000c0, 0xffffffff,
1068 	0x0000f4a4, 0x00680000, 0xffffffff,
1069 	0x000004c8, 0x00000001, 0xffffffff,
1070 	0x000064ec, 0x00007ffd, 0xffffffff,
1071 	0x00000c7c, 0x0000ff00, 0xffffffff,
1072 	0x00006dfc, 0x0000007f, 0xffffffff
1073 };
1074 #define CAICOS_SYSLS_DISABLE_LENGTH sizeof(caicos_sysls_disable) / (3 * sizeof(u32))
1075 
1076 static const u32 caicos_sysls_enable[] =
1077 {
1078 	0x000055e8, 0x00000001, 0xffffffff,
1079 	0x0000d0bc, 0x00000100, 0xffffffff,
1080 	0x000015c0, 0x000c1401, 0xffffffff,
1081 	0x0000264c, 0x000c0400, 0xffffffff,
1082 	0x00002648, 0x000c0400, 0xffffffff,
1083 	0x00002650, 0x000c0400, 0xffffffff,
1084 	0x000020b8, 0x000c0400, 0xffffffff,
1085 	0x000020bc, 0x000c0400, 0xffffffff,
1086 	0x0000f4a0, 0x000000c0, 0xffffffff,
1087 	0x0000f4a4, 0x00680fff, 0xffffffff,
1088 	0x000064ec, 0x00000000, 0xffffffff,
1089 	0x00000c7c, 0x00000000, 0xffffffff,
1090 	0x00006dfc, 0x00000000, 0xffffffff,
1091 	0x000004c8, 0x00000000, 0xffffffff
1092 };
1093 #define CAICOS_SYSLS_ENABLE_LENGTH sizeof(caicos_sysls_enable) / (3 * sizeof(u32))
1094 
1095 //********* TURKS **************//
1096 static const u32 turks_sysls_default[] =
1097 {
1098 	0x000055e8, 0x00000000, 0xffffffff,
1099 	0x0000d0bc, 0x00000000, 0xffffffff,
1100 	0x000015c0, 0x000c1401, 0xffffffff,
1101 	0x0000264c, 0x000c0400, 0xffffffff,
1102 	0x00002648, 0x000c0400, 0xffffffff,
1103 	0x00002650, 0x000c0400, 0xffffffff,
1104 	0x000020b8, 0x000c0400, 0xffffffff,
1105 	0x000020bc, 0x000c0400, 0xffffffff,
1106 	0x000020c0, 0x000c0c80, 0xffffffff,
1107 	0x0000f4a0, 0x000000c0, 0xffffffff,
1108 	0x0000f4a4, 0x00680fff, 0xffffffff,
1109 	0x000004c8, 0x00000001, 0xffffffff,
1110 	0x000064ec, 0x00000000, 0xffffffff,
1111 	0x00000c7c, 0x00000000, 0xffffffff,
1112 	0x00006dfc, 0x00000000, 0xffffffff
1113 };
1114 #define TURKS_SYSLS_DEFAULT_LENGTH sizeof(turks_sysls_default) / (3 * sizeof(u32))
1115 
1116 static const u32 turks_sysls_disable[] =
1117 {
1118 	0x000055e8, 0x00000000, 0xffffffff,
1119 	0x0000d0bc, 0x00000000, 0xffffffff,
1120 	0x000015c0, 0x00041401, 0xffffffff,
1121 	0x0000264c, 0x00040400, 0xffffffff,
1122 	0x00002648, 0x00040400, 0xffffffff,
1123 	0x00002650, 0x00040400, 0xffffffff,
1124 	0x000020b8, 0x00040400, 0xffffffff,
1125 	0x000020bc, 0x00040400, 0xffffffff,
1126 	0x000020c0, 0x00040c80, 0xffffffff,
1127 	0x0000f4a0, 0x000000c0, 0xffffffff,
1128 	0x0000f4a4, 0x00680000, 0xffffffff,
1129 	0x000004c8, 0x00000001, 0xffffffff,
1130 	0x000064ec, 0x00007ffd, 0xffffffff,
1131 	0x00000c7c, 0x0000ff00, 0xffffffff,
1132 	0x00006dfc, 0x0000007f, 0xffffffff
1133 };
1134 #define TURKS_SYSLS_DISABLE_LENGTH sizeof(turks_sysls_disable) / (3 * sizeof(u32))
1135 
1136 static const u32 turks_sysls_enable[] =
1137 {
1138 	0x000055e8, 0x00000001, 0xffffffff,
1139 	0x0000d0bc, 0x00000100, 0xffffffff,
1140 	0x000015c0, 0x000c1401, 0xffffffff,
1141 	0x0000264c, 0x000c0400, 0xffffffff,
1142 	0x00002648, 0x000c0400, 0xffffffff,
1143 	0x00002650, 0x000c0400, 0xffffffff,
1144 	0x000020b8, 0x000c0400, 0xffffffff,
1145 	0x000020bc, 0x000c0400, 0xffffffff,
1146 	0x000020c0, 0x000c0c80, 0xffffffff,
1147 	0x0000f4a0, 0x000000c0, 0xffffffff,
1148 	0x0000f4a4, 0x00680fff, 0xffffffff,
1149 	0x000004c8, 0x00000000, 0xffffffff,
1150 	0x000064ec, 0x00000000, 0xffffffff,
1151 	0x00000c7c, 0x00000000, 0xffffffff,
1152 	0x00006dfc, 0x00000000, 0xffffffff
1153 };
1154 #define TURKS_SYSLS_ENABLE_LENGTH sizeof(turks_sysls_enable) / (3 * sizeof(u32))
1155 
1156 #endif
1157 
1158 u32 btc_valid_sclk[40] =
1159 {
1160 	5000,   10000,  15000,  20000,  25000,  30000,  35000,  40000,  45000,  50000,
1161 	55000,  60000,  65000,  70000,  75000,  80000,  85000,  90000,  95000,  100000,
1162 	105000, 110000, 11500,  120000, 125000, 130000, 135000, 140000, 145000, 150000,
1163 	155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000
1164 };
1165 
1166 static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
1167 {
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 		kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL);
2586 	if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
2587 		r600_free_extended_power_table(rdev);
2588 		return -ENOMEM;
2589 	}
2590 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
2591 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
2592 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
2593 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
2594 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 800;
2595 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
2596 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 800;
2597 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
2598 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 800;
2599 
2600 	if (rdev->pm.dpm.voltage_response_time == 0)
2601 		rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
2602 	if (rdev->pm.dpm.backbias_response_time == 0)
2603 		rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
2604 
2605 	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
2606 					     0, false, &dividers);
2607 	if (ret)
2608 		pi->ref_div = dividers.ref_div + 1;
2609 	else
2610 		pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
2611 
2612 	pi->mclk_strobe_mode_threshold = 40000;
2613 	pi->mclk_edc_enable_threshold = 40000;
2614 	eg_pi->mclk_edc_wr_enable_threshold = 40000;
2615 
2616 	pi->rlp = RV770_RLP_DFLT;
2617 	pi->rmp = RV770_RMP_DFLT;
2618 	pi->lhp = RV770_LHP_DFLT;
2619 	pi->lmp = RV770_LMP_DFLT;
2620 
2621 	eg_pi->ats[0].rlp = RV770_RLP_DFLT;
2622 	eg_pi->ats[0].rmp = RV770_RMP_DFLT;
2623 	eg_pi->ats[0].lhp = RV770_LHP_DFLT;
2624 	eg_pi->ats[0].lmp = RV770_LMP_DFLT;
2625 
2626 	eg_pi->ats[1].rlp = BTC_RLP_UVD_DFLT;
2627 	eg_pi->ats[1].rmp = BTC_RMP_UVD_DFLT;
2628 	eg_pi->ats[1].lhp = BTC_LHP_UVD_DFLT;
2629 	eg_pi->ats[1].lmp = BTC_LMP_UVD_DFLT;
2630 
2631 	eg_pi->smu_uvd_hs = true;
2632 
2633 	pi->voltage_control =
2634 		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
2635 
2636 	pi->mvdd_control =
2637 		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
2638 
2639 	eg_pi->vddci_control =
2640 		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
2641 
2642 	rv770_get_engine_memory_ss(rdev);
2643 
2644 	pi->asi = RV770_ASI_DFLT;
2645 	pi->pasi = CYPRESS_HASI_DFLT;
2646 	pi->vrc = CYPRESS_VRC_DFLT;
2647 
2648 	pi->power_gating = false;
2649 
2650 	pi->gfx_clock_gating = true;
2651 
2652 	pi->mg_clock_gating = true;
2653 	pi->mgcgtssm = true;
2654 	eg_pi->ls_clock_gating = false;
2655 	eg_pi->sclk_deep_sleep = false;
2656 
2657 	pi->dynamic_pcie_gen2 = true;
2658 
2659 	if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
2660 		pi->thermal_protection = true;
2661 	else
2662 		pi->thermal_protection = false;
2663 
2664 	pi->display_gap = true;
2665 
2666 	if (rdev->flags & RADEON_IS_MOBILITY)
2667 		pi->dcodt = true;
2668 	else
2669 		pi->dcodt = false;
2670 
2671 	pi->ulps = true;
2672 
2673 	eg_pi->dynamic_ac_timing = true;
2674 	eg_pi->abm = true;
2675 	eg_pi->mcls = true;
2676 	eg_pi->light_sleep = true;
2677 	eg_pi->memory_transition = true;
2678 #if defined(CONFIG_ACPI)
2679 	eg_pi->pcie_performance_request =
2680 		radeon_acpi_is_pcie_performance_request_supported(rdev);
2681 #else
2682 	eg_pi->pcie_performance_request = false;
2683 #endif
2684 
2685 	if (rdev->family == CHIP_BARTS)
2686 		eg_pi->dll_default_on = true;
2687 	else
2688 		eg_pi->dll_default_on = false;
2689 
2690 	eg_pi->sclk_deep_sleep = false;
2691 	if (ASIC_IS_LOMBOK(rdev))
2692 		pi->mclk_stutter_mode_threshold = 30000;
2693 	else
2694 		pi->mclk_stutter_mode_threshold = 0;
2695 
2696 	pi->sram_end = SMC_RAM_END;
2697 
2698 	rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;
2699 	rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
2700 	rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2 = 900;
2701 	rdev->pm.dpm.dyn_state.valid_sclk_values.count = ARRAY_SIZE(btc_valid_sclk);
2702 	rdev->pm.dpm.dyn_state.valid_sclk_values.values = btc_valid_sclk;
2703 	rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
2704 	rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
2705 
2706 	if (rdev->family == CHIP_TURKS)
2707 		rdev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;
2708 	else
2709 		rdev->pm.dpm.dyn_state.sclk_mclk_delta = 10000;
2710 
2711 	/* make sure dc limits are valid */
2712 	if ((rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk == 0) ||
2713 	    (rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk == 0))
2714 		rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
2715 			rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2716 
2717 	return 0;
2718 }
2719 
2720 void btc_dpm_fini(struct radeon_device *rdev)
2721 {
2722 	int i;
2723 
2724 	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
2725 		kfree(rdev->pm.dpm.ps[i].ps_priv);
2726 	}
2727 	kfree(rdev->pm.dpm.ps);
2728 	kfree(rdev->pm.dpm.priv);
2729 	kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
2730 	r600_free_extended_power_table(rdev);
2731 }
2732 
2733 void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
2734 						     struct seq_file *m)
2735 {
2736 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2737 	struct radeon_ps *rps = &eg_pi->current_rps;
2738 	struct rv7xx_ps *ps = rv770_get_ps(rps);
2739 	struct rv7xx_pl *pl;
2740 	u32 current_index =
2741 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
2742 		CURRENT_PROFILE_INDEX_SHIFT;
2743 
2744 	if (current_index > 2) {
2745 		seq_printf(m, "invalid dpm profile %d\n", current_index);
2746 	} else {
2747 		if (current_index == 0)
2748 			pl = &ps->low;
2749 		else if (current_index == 1)
2750 			pl = &ps->medium;
2751 		else /* current_index == 2 */
2752 			pl = &ps->high;
2753 		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
2754 		if (rdev->family >= CHIP_CEDAR) {
2755 			seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
2756 				   current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
2757 		} else {
2758 			seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u\n",
2759 				   current_index, pl->sclk, pl->mclk, pl->vddc);
2760 		}
2761 	}
2762 }
2763 
2764 u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low)
2765 {
2766 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2767 	struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2768 
2769 	if (low)
2770 		return requested_state->low.sclk;
2771 	else
2772 		return requested_state->high.sclk;
2773 }
2774 
2775 u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low)
2776 {
2777 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2778 	struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2779 
2780 	if (low)
2781 		return requested_state->low.mclk;
2782 	else
2783 		return requested_state->high.mclk;
2784 }
2785