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