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