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