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