Linux Audio

Check our new training course

Yocto / OpenEmbedded training

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