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