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