Linux Audio

Check our new training course

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