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