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