Linux Audio

Check our new training course

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