Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2011 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  * Authors: Alex Deucher
0023  */
0024 
0025 #include <linux/pci.h>
0026 #include <linux/seq_file.h>
0027 
0028 #include "atom.h"
0029 #include "btc_dpm.h"
0030 #include "btcd.h"
0031 #include "cypress_dpm.h"
0032 #include "evergreen.h"
0033 #include "r600_dpm.h"
0034 #include "rv770.h"
0035 #include "radeon.h"
0036 #include "radeon_asic.h"
0037 
0038 #define MC_CG_ARB_FREQ_F0           0x0a
0039 #define MC_CG_ARB_FREQ_F1           0x0b
0040 #define MC_CG_ARB_FREQ_F2           0x0c
0041 #define MC_CG_ARB_FREQ_F3           0x0d
0042 
0043 #define MC_CG_SEQ_DRAMCONF_S0       0x05
0044 #define MC_CG_SEQ_DRAMCONF_S1       0x06
0045 #define MC_CG_SEQ_YCLK_SUSPEND      0x04
0046 #define MC_CG_SEQ_YCLK_RESUME       0x0a
0047 
0048 #define SMC_RAM_END 0x8000
0049 
0050 #ifndef BTC_MGCG_SEQUENCE
0051 #define BTC_MGCG_SEQUENCE  300
0052 
0053 extern int ni_mc_load_microcode(struct radeon_device *rdev);
0054 
0055 //********* BARTS **************//
0056 static const u32 barts_cgcg_cgls_default[] =
0057 {
0058     /* Register,   Value,     Mask bits */
0059     0x000008f8, 0x00000010, 0xffffffff,
0060     0x000008fc, 0x00000000, 0xffffffff,
0061     0x000008f8, 0x00000011, 0xffffffff,
0062     0x000008fc, 0x00000000, 0xffffffff,
0063     0x000008f8, 0x00000012, 0xffffffff,
0064     0x000008fc, 0x00000000, 0xffffffff,
0065     0x000008f8, 0x00000013, 0xffffffff,
0066     0x000008fc, 0x00000000, 0xffffffff,
0067     0x000008f8, 0x00000014, 0xffffffff,
0068     0x000008fc, 0x00000000, 0xffffffff,
0069     0x000008f8, 0x00000015, 0xffffffff,
0070     0x000008fc, 0x00000000, 0xffffffff,
0071     0x000008f8, 0x00000016, 0xffffffff,
0072     0x000008fc, 0x00000000, 0xffffffff,
0073     0x000008f8, 0x00000017, 0xffffffff,
0074     0x000008fc, 0x00000000, 0xffffffff,
0075     0x000008f8, 0x00000018, 0xffffffff,
0076     0x000008fc, 0x00000000, 0xffffffff,
0077     0x000008f8, 0x00000019, 0xffffffff,
0078     0x000008fc, 0x00000000, 0xffffffff,
0079     0x000008f8, 0x0000001a, 0xffffffff,
0080     0x000008fc, 0x00000000, 0xffffffff,
0081     0x000008f8, 0x0000001b, 0xffffffff,
0082     0x000008fc, 0x00000000, 0xffffffff,
0083     0x000008f8, 0x00000020, 0xffffffff,
0084     0x000008fc, 0x00000000, 0xffffffff,
0085     0x000008f8, 0x00000021, 0xffffffff,
0086     0x000008fc, 0x00000000, 0xffffffff,
0087     0x000008f8, 0x00000022, 0xffffffff,
0088     0x000008fc, 0x00000000, 0xffffffff,
0089     0x000008f8, 0x00000023, 0xffffffff,
0090     0x000008fc, 0x00000000, 0xffffffff,
0091     0x000008f8, 0x00000024, 0xffffffff,
0092     0x000008fc, 0x00000000, 0xffffffff,
0093     0x000008f8, 0x00000025, 0xffffffff,
0094     0x000008fc, 0x00000000, 0xffffffff,
0095     0x000008f8, 0x00000026, 0xffffffff,
0096     0x000008fc, 0x00000000, 0xffffffff,
0097     0x000008f8, 0x00000027, 0xffffffff,
0098     0x000008fc, 0x00000000, 0xffffffff,
0099     0x000008f8, 0x00000028, 0xffffffff,
0100     0x000008fc, 0x00000000, 0xffffffff,
0101     0x000008f8, 0x00000029, 0xffffffff,
0102     0x000008fc, 0x00000000, 0xffffffff,
0103     0x000008f8, 0x0000002a, 0xffffffff,
0104     0x000008fc, 0x00000000, 0xffffffff,
0105     0x000008f8, 0x0000002b, 0xffffffff,
0106     0x000008fc, 0x00000000, 0xffffffff
0107 };
0108 #define BARTS_CGCG_CGLS_DEFAULT_LENGTH sizeof(barts_cgcg_cgls_default) / (3 * sizeof(u32))
0109 
0110 static const u32 barts_cgcg_cgls_disable[] =
0111 {
0112     0x000008f8, 0x00000010, 0xffffffff,
0113     0x000008fc, 0xffffffff, 0xffffffff,
0114     0x000008f8, 0x00000011, 0xffffffff,
0115     0x000008fc, 0xffffffff, 0xffffffff,
0116     0x000008f8, 0x00000012, 0xffffffff,
0117     0x000008fc, 0xffffffff, 0xffffffff,
0118     0x000008f8, 0x00000013, 0xffffffff,
0119     0x000008fc, 0xffffffff, 0xffffffff,
0120     0x000008f8, 0x00000014, 0xffffffff,
0121     0x000008fc, 0xffffffff, 0xffffffff,
0122     0x000008f8, 0x00000015, 0xffffffff,
0123     0x000008fc, 0xffffffff, 0xffffffff,
0124     0x000008f8, 0x00000016, 0xffffffff,
0125     0x000008fc, 0xffffffff, 0xffffffff,
0126     0x000008f8, 0x00000017, 0xffffffff,
0127     0x000008fc, 0xffffffff, 0xffffffff,
0128     0x000008f8, 0x00000018, 0xffffffff,
0129     0x000008fc, 0xffffffff, 0xffffffff,
0130     0x000008f8, 0x00000019, 0xffffffff,
0131     0x000008fc, 0xffffffff, 0xffffffff,
0132     0x000008f8, 0x0000001a, 0xffffffff,
0133     0x000008fc, 0xffffffff, 0xffffffff,
0134     0x000008f8, 0x0000001b, 0xffffffff,
0135     0x000008fc, 0xffffffff, 0xffffffff,
0136     0x000008f8, 0x00000020, 0xffffffff,
0137     0x000008fc, 0x00000000, 0xffffffff,
0138     0x000008f8, 0x00000021, 0xffffffff,
0139     0x000008fc, 0x00000000, 0xffffffff,
0140     0x000008f8, 0x00000022, 0xffffffff,
0141     0x000008fc, 0x00000000, 0xffffffff,
0142     0x000008f8, 0x00000023, 0xffffffff,
0143     0x000008fc, 0x00000000, 0xffffffff,
0144     0x000008f8, 0x00000024, 0xffffffff,
0145     0x000008fc, 0x00000000, 0xffffffff,
0146     0x000008f8, 0x00000025, 0xffffffff,
0147     0x000008fc, 0x00000000, 0xffffffff,
0148     0x000008f8, 0x00000026, 0xffffffff,
0149     0x000008fc, 0x00000000, 0xffffffff,
0150     0x000008f8, 0x00000027, 0xffffffff,
0151     0x000008fc, 0x00000000, 0xffffffff,
0152     0x000008f8, 0x00000028, 0xffffffff,
0153     0x000008fc, 0x00000000, 0xffffffff,
0154     0x000008f8, 0x00000029, 0xffffffff,
0155     0x000008fc, 0x00000000, 0xffffffff,
0156     0x000008f8, 0x0000002a, 0xffffffff,
0157     0x000008fc, 0x00000000, 0xffffffff,
0158     0x000008f8, 0x0000002b, 0xffffffff,
0159     0x000008fc, 0x00000000, 0xffffffff,
0160     0x00000644, 0x000f7912, 0x001f4180,
0161     0x00000644, 0x000f3812, 0x001f4180
0162 };
0163 #define BARTS_CGCG_CGLS_DISABLE_LENGTH sizeof(barts_cgcg_cgls_disable) / (3 * sizeof(u32))
0164 
0165 static const u32 barts_cgcg_cgls_enable[] =
0166 {
0167     /* 0x0000c124, 0x84180000, 0x00180000, */
0168     0x00000644, 0x000f7892, 0x001f4080,
0169     0x000008f8, 0x00000010, 0xffffffff,
0170     0x000008fc, 0x00000000, 0xffffffff,
0171     0x000008f8, 0x00000011, 0xffffffff,
0172     0x000008fc, 0x00000000, 0xffffffff,
0173     0x000008f8, 0x00000012, 0xffffffff,
0174     0x000008fc, 0x00000000, 0xffffffff,
0175     0x000008f8, 0x00000013, 0xffffffff,
0176     0x000008fc, 0x00000000, 0xffffffff,
0177     0x000008f8, 0x00000014, 0xffffffff,
0178     0x000008fc, 0x00000000, 0xffffffff,
0179     0x000008f8, 0x00000015, 0xffffffff,
0180     0x000008fc, 0x00000000, 0xffffffff,
0181     0x000008f8, 0x00000016, 0xffffffff,
0182     0x000008fc, 0x00000000, 0xffffffff,
0183     0x000008f8, 0x00000017, 0xffffffff,
0184     0x000008fc, 0x00000000, 0xffffffff,
0185     0x000008f8, 0x00000018, 0xffffffff,
0186     0x000008fc, 0x00000000, 0xffffffff,
0187     0x000008f8, 0x00000019, 0xffffffff,
0188     0x000008fc, 0x00000000, 0xffffffff,
0189     0x000008f8, 0x0000001a, 0xffffffff,
0190     0x000008fc, 0x00000000, 0xffffffff,
0191     0x000008f8, 0x0000001b, 0xffffffff,
0192     0x000008fc, 0x00000000, 0xffffffff,
0193     0x000008f8, 0x00000020, 0xffffffff,
0194     0x000008fc, 0xffffffff, 0xffffffff,
0195     0x000008f8, 0x00000021, 0xffffffff,
0196     0x000008fc, 0xffffffff, 0xffffffff,
0197     0x000008f8, 0x00000022, 0xffffffff,
0198     0x000008fc, 0xffffffff, 0xffffffff,
0199     0x000008f8, 0x00000023, 0xffffffff,
0200     0x000008fc, 0xffffffff, 0xffffffff,
0201     0x000008f8, 0x00000024, 0xffffffff,
0202     0x000008fc, 0xffffffff, 0xffffffff,
0203     0x000008f8, 0x00000025, 0xffffffff,
0204     0x000008fc, 0xffffffff, 0xffffffff,
0205     0x000008f8, 0x00000026, 0xffffffff,
0206     0x000008fc, 0xffffffff, 0xffffffff,
0207     0x000008f8, 0x00000027, 0xffffffff,
0208     0x000008fc, 0xffffffff, 0xffffffff,
0209     0x000008f8, 0x00000028, 0xffffffff,
0210     0x000008fc, 0xffffffff, 0xffffffff,
0211     0x000008f8, 0x00000029, 0xffffffff,
0212     0x000008fc, 0xffffffff, 0xffffffff,
0213     0x000008f8, 0x0000002a, 0xffffffff,
0214     0x000008fc, 0xffffffff, 0xffffffff,
0215     0x000008f8, 0x0000002b, 0xffffffff,
0216     0x000008fc, 0xffffffff, 0xffffffff
0217 };
0218 #define BARTS_CGCG_CGLS_ENABLE_LENGTH sizeof(barts_cgcg_cgls_enable) / (3 * sizeof(u32))
0219 
0220 static const u32 barts_mgcg_default[] =
0221 {
0222     0x0000802c, 0xc0000000, 0xffffffff,
0223     0x00005448, 0x00000100, 0xffffffff,
0224     0x000055e4, 0x00600100, 0xffffffff,
0225     0x0000160c, 0x00000100, 0xffffffff,
0226     0x0000c164, 0x00000100, 0xffffffff,
0227     0x00008a18, 0x00000100, 0xffffffff,
0228     0x0000897c, 0x06000100, 0xffffffff,
0229     0x00008b28, 0x00000100, 0xffffffff,
0230     0x00009144, 0x00000100, 0xffffffff,
0231     0x00009a60, 0x00000100, 0xffffffff,
0232     0x00009868, 0x00000100, 0xffffffff,
0233     0x00008d58, 0x00000100, 0xffffffff,
0234     0x00009510, 0x00000100, 0xffffffff,
0235     0x0000949c, 0x00000100, 0xffffffff,
0236     0x00009654, 0x00000100, 0xffffffff,
0237     0x00009030, 0x00000100, 0xffffffff,
0238     0x00009034, 0x00000100, 0xffffffff,
0239     0x00009038, 0x00000100, 0xffffffff,
0240     0x0000903c, 0x00000100, 0xffffffff,
0241     0x00009040, 0x00000100, 0xffffffff,
0242     0x0000a200, 0x00000100, 0xffffffff,
0243     0x0000a204, 0x00000100, 0xffffffff,
0244     0x0000a208, 0x00000100, 0xffffffff,
0245     0x0000a20c, 0x00000100, 0xffffffff,
0246     0x0000977c, 0x00000100, 0xffffffff,
0247     0x00003f80, 0x00000100, 0xffffffff,
0248     0x0000a210, 0x00000100, 0xffffffff,
0249     0x0000a214, 0x00000100, 0xffffffff,
0250     0x000004d8, 0x00000100, 0xffffffff,
0251     0x00009784, 0x00000100, 0xffffffff,
0252     0x00009698, 0x00000100, 0xffffffff,
0253     0x000004d4, 0x00000200, 0xffffffff,
0254     0x000004d0, 0x00000000, 0xffffffff,
0255     0x000030cc, 0x00000100, 0xffffffff,
0256     0x0000d0c0, 0xff000100, 0xffffffff,
0257     0x0000802c, 0x40000000, 0xffffffff,
0258     0x0000915c, 0x00010000, 0xffffffff,
0259     0x00009160, 0x00030002, 0xffffffff,
0260     0x00009164, 0x00050004, 0xffffffff,
0261     0x00009168, 0x00070006, 0xffffffff,
0262     0x00009178, 0x00070000, 0xffffffff,
0263     0x0000917c, 0x00030002, 0xffffffff,
0264     0x00009180, 0x00050004, 0xffffffff,
0265     0x0000918c, 0x00010006, 0xffffffff,
0266     0x00009190, 0x00090008, 0xffffffff,
0267     0x00009194, 0x00070000, 0xffffffff,
0268     0x00009198, 0x00030002, 0xffffffff,
0269     0x0000919c, 0x00050004, 0xffffffff,
0270     0x000091a8, 0x00010006, 0xffffffff,
0271     0x000091ac, 0x00090008, 0xffffffff,
0272     0x000091b0, 0x00070000, 0xffffffff,
0273     0x000091b4, 0x00030002, 0xffffffff,
0274     0x000091b8, 0x00050004, 0xffffffff,
0275     0x000091c4, 0x00010006, 0xffffffff,
0276     0x000091c8, 0x00090008, 0xffffffff,
0277     0x000091cc, 0x00070000, 0xffffffff,
0278     0x000091d0, 0x00030002, 0xffffffff,
0279     0x000091d4, 0x00050004, 0xffffffff,
0280     0x000091e0, 0x00010006, 0xffffffff,
0281     0x000091e4, 0x00090008, 0xffffffff,
0282     0x000091e8, 0x00000000, 0xffffffff,
0283     0x000091ec, 0x00070000, 0xffffffff,
0284     0x000091f0, 0x00030002, 0xffffffff,
0285     0x000091f4, 0x00050004, 0xffffffff,
0286     0x00009200, 0x00010006, 0xffffffff,
0287     0x00009204, 0x00090008, 0xffffffff,
0288     0x00009208, 0x00070000, 0xffffffff,
0289     0x0000920c, 0x00030002, 0xffffffff,
0290     0x00009210, 0x00050004, 0xffffffff,
0291     0x0000921c, 0x00010006, 0xffffffff,
0292     0x00009220, 0x00090008, 0xffffffff,
0293     0x00009224, 0x00070000, 0xffffffff,
0294     0x00009228, 0x00030002, 0xffffffff,
0295     0x0000922c, 0x00050004, 0xffffffff,
0296     0x00009238, 0x00010006, 0xffffffff,
0297     0x0000923c, 0x00090008, 0xffffffff,
0298     0x00009294, 0x00000000, 0xffffffff,
0299     0x0000802c, 0x40010000, 0xffffffff,
0300     0x0000915c, 0x00010000, 0xffffffff,
0301     0x00009160, 0x00030002, 0xffffffff,
0302     0x00009164, 0x00050004, 0xffffffff,
0303     0x00009168, 0x00070006, 0xffffffff,
0304     0x00009178, 0x00070000, 0xffffffff,
0305     0x0000917c, 0x00030002, 0xffffffff,
0306     0x00009180, 0x00050004, 0xffffffff,
0307     0x0000918c, 0x00010006, 0xffffffff,
0308     0x00009190, 0x00090008, 0xffffffff,
0309     0x00009194, 0x00070000, 0xffffffff,
0310     0x00009198, 0x00030002, 0xffffffff,
0311     0x0000919c, 0x00050004, 0xffffffff,
0312     0x000091a8, 0x00010006, 0xffffffff,
0313     0x000091ac, 0x00090008, 0xffffffff,
0314     0x000091b0, 0x00070000, 0xffffffff,
0315     0x000091b4, 0x00030002, 0xffffffff,
0316     0x000091b8, 0x00050004, 0xffffffff,
0317     0x000091c4, 0x00010006, 0xffffffff,
0318     0x000091c8, 0x00090008, 0xffffffff,
0319     0x000091cc, 0x00070000, 0xffffffff,
0320     0x000091d0, 0x00030002, 0xffffffff,
0321     0x000091d4, 0x00050004, 0xffffffff,
0322     0x000091e0, 0x00010006, 0xffffffff,
0323     0x000091e4, 0x00090008, 0xffffffff,
0324     0x000091e8, 0x00000000, 0xffffffff,
0325     0x000091ec, 0x00070000, 0xffffffff,
0326     0x000091f0, 0x00030002, 0xffffffff,
0327     0x000091f4, 0x00050004, 0xffffffff,
0328     0x00009200, 0x00010006, 0xffffffff,
0329     0x00009204, 0x00090008, 0xffffffff,
0330     0x00009208, 0x00070000, 0xffffffff,
0331     0x0000920c, 0x00030002, 0xffffffff,
0332     0x00009210, 0x00050004, 0xffffffff,
0333     0x0000921c, 0x00010006, 0xffffffff,
0334     0x00009220, 0x00090008, 0xffffffff,
0335     0x00009224, 0x00070000, 0xffffffff,
0336     0x00009228, 0x00030002, 0xffffffff,
0337     0x0000922c, 0x00050004, 0xffffffff,
0338     0x00009238, 0x00010006, 0xffffffff,
0339     0x0000923c, 0x00090008, 0xffffffff,
0340     0x00009294, 0x00000000, 0xffffffff,
0341     0x0000802c, 0xc0000000, 0xffffffff,
0342     0x000008f8, 0x00000010, 0xffffffff,
0343     0x000008fc, 0x00000000, 0xffffffff,
0344     0x000008f8, 0x00000011, 0xffffffff,
0345     0x000008fc, 0x00000000, 0xffffffff,
0346     0x000008f8, 0x00000012, 0xffffffff,
0347     0x000008fc, 0x00000000, 0xffffffff,
0348     0x000008f8, 0x00000013, 0xffffffff,
0349     0x000008fc, 0x00000000, 0xffffffff,
0350     0x000008f8, 0x00000014, 0xffffffff,
0351     0x000008fc, 0x00000000, 0xffffffff,
0352     0x000008f8, 0x00000015, 0xffffffff,
0353     0x000008fc, 0x00000000, 0xffffffff,
0354     0x000008f8, 0x00000016, 0xffffffff,
0355     0x000008fc, 0x00000000, 0xffffffff,
0356     0x000008f8, 0x00000017, 0xffffffff,
0357     0x000008fc, 0x00000000, 0xffffffff,
0358     0x000008f8, 0x00000018, 0xffffffff,
0359     0x000008fc, 0x00000000, 0xffffffff,
0360     0x000008f8, 0x00000019, 0xffffffff,
0361     0x000008fc, 0x00000000, 0xffffffff,
0362     0x000008f8, 0x0000001a, 0xffffffff,
0363     0x000008fc, 0x00000000, 0xffffffff,
0364     0x000008f8, 0x0000001b, 0xffffffff,
0365     0x000008fc, 0x00000000, 0xffffffff
0366 };
0367 #define BARTS_MGCG_DEFAULT_LENGTH sizeof(barts_mgcg_default) / (3 * sizeof(u32))
0368 
0369 static const u32 barts_mgcg_disable[] =
0370 {
0371     0x0000802c, 0xc0000000, 0xffffffff,
0372     0x000008f8, 0x00000000, 0xffffffff,
0373     0x000008fc, 0xffffffff, 0xffffffff,
0374     0x000008f8, 0x00000001, 0xffffffff,
0375     0x000008fc, 0xffffffff, 0xffffffff,
0376     0x000008f8, 0x00000002, 0xffffffff,
0377     0x000008fc, 0xffffffff, 0xffffffff,
0378     0x000008f8, 0x00000003, 0xffffffff,
0379     0x000008fc, 0xffffffff, 0xffffffff,
0380     0x00009150, 0x00600000, 0xffffffff
0381 };
0382 #define BARTS_MGCG_DISABLE_LENGTH sizeof(barts_mgcg_disable) / (3 * sizeof(u32))
0383 
0384 static const u32 barts_mgcg_enable[] =
0385 {
0386     0x0000802c, 0xc0000000, 0xffffffff,
0387     0x000008f8, 0x00000000, 0xffffffff,
0388     0x000008fc, 0x00000000, 0xffffffff,
0389     0x000008f8, 0x00000001, 0xffffffff,
0390     0x000008fc, 0x00000000, 0xffffffff,
0391     0x000008f8, 0x00000002, 0xffffffff,
0392     0x000008fc, 0x00000000, 0xffffffff,
0393     0x000008f8, 0x00000003, 0xffffffff,
0394     0x000008fc, 0x00000000, 0xffffffff,
0395     0x00009150, 0x81944000, 0xffffffff
0396 };
0397 #define BARTS_MGCG_ENABLE_LENGTH sizeof(barts_mgcg_enable) / (3 * sizeof(u32))
0398 
0399 //********* CAICOS **************//
0400 static const u32 caicos_cgcg_cgls_default[] =
0401 {
0402     0x000008f8, 0x00000010, 0xffffffff,
0403     0x000008fc, 0x00000000, 0xffffffff,
0404     0x000008f8, 0x00000011, 0xffffffff,
0405     0x000008fc, 0x00000000, 0xffffffff,
0406     0x000008f8, 0x00000012, 0xffffffff,
0407     0x000008fc, 0x00000000, 0xffffffff,
0408     0x000008f8, 0x00000013, 0xffffffff,
0409     0x000008fc, 0x00000000, 0xffffffff,
0410     0x000008f8, 0x00000014, 0xffffffff,
0411     0x000008fc, 0x00000000, 0xffffffff,
0412     0x000008f8, 0x00000015, 0xffffffff,
0413     0x000008fc, 0x00000000, 0xffffffff,
0414     0x000008f8, 0x00000016, 0xffffffff,
0415     0x000008fc, 0x00000000, 0xffffffff,
0416     0x000008f8, 0x00000017, 0xffffffff,
0417     0x000008fc, 0x00000000, 0xffffffff,
0418     0x000008f8, 0x00000018, 0xffffffff,
0419     0x000008fc, 0x00000000, 0xffffffff,
0420     0x000008f8, 0x00000019, 0xffffffff,
0421     0x000008fc, 0x00000000, 0xffffffff,
0422     0x000008f8, 0x0000001a, 0xffffffff,
0423     0x000008fc, 0x00000000, 0xffffffff,
0424     0x000008f8, 0x0000001b, 0xffffffff,
0425     0x000008fc, 0x00000000, 0xffffffff,
0426     0x000008f8, 0x00000020, 0xffffffff,
0427     0x000008fc, 0x00000000, 0xffffffff,
0428     0x000008f8, 0x00000021, 0xffffffff,
0429     0x000008fc, 0x00000000, 0xffffffff,
0430     0x000008f8, 0x00000022, 0xffffffff,
0431     0x000008fc, 0x00000000, 0xffffffff,
0432     0x000008f8, 0x00000023, 0xffffffff,
0433     0x000008fc, 0x00000000, 0xffffffff,
0434     0x000008f8, 0x00000024, 0xffffffff,
0435     0x000008fc, 0x00000000, 0xffffffff,
0436     0x000008f8, 0x00000025, 0xffffffff,
0437     0x000008fc, 0x00000000, 0xffffffff,
0438     0x000008f8, 0x00000026, 0xffffffff,
0439     0x000008fc, 0x00000000, 0xffffffff,
0440     0x000008f8, 0x00000027, 0xffffffff,
0441     0x000008fc, 0x00000000, 0xffffffff,
0442     0x000008f8, 0x00000028, 0xffffffff,
0443     0x000008fc, 0x00000000, 0xffffffff,
0444     0x000008f8, 0x00000029, 0xffffffff,
0445     0x000008fc, 0x00000000, 0xffffffff,
0446     0x000008f8, 0x0000002a, 0xffffffff,
0447     0x000008fc, 0x00000000, 0xffffffff,
0448     0x000008f8, 0x0000002b, 0xffffffff,
0449     0x000008fc, 0x00000000, 0xffffffff
0450 };
0451 #define CAICOS_CGCG_CGLS_DEFAULT_LENGTH sizeof(caicos_cgcg_cgls_default) / (3 * sizeof(u32))
0452 
0453 static const u32 caicos_cgcg_cgls_disable[] =
0454 {
0455     0x000008f8, 0x00000010, 0xffffffff,
0456     0x000008fc, 0xffffffff, 0xffffffff,
0457     0x000008f8, 0x00000011, 0xffffffff,
0458     0x000008fc, 0xffffffff, 0xffffffff,
0459     0x000008f8, 0x00000012, 0xffffffff,
0460     0x000008fc, 0xffffffff, 0xffffffff,
0461     0x000008f8, 0x00000013, 0xffffffff,
0462     0x000008fc, 0xffffffff, 0xffffffff,
0463     0x000008f8, 0x00000014, 0xffffffff,
0464     0x000008fc, 0xffffffff, 0xffffffff,
0465     0x000008f8, 0x00000015, 0xffffffff,
0466     0x000008fc, 0xffffffff, 0xffffffff,
0467     0x000008f8, 0x00000016, 0xffffffff,
0468     0x000008fc, 0xffffffff, 0xffffffff,
0469     0x000008f8, 0x00000017, 0xffffffff,
0470     0x000008fc, 0xffffffff, 0xffffffff,
0471     0x000008f8, 0x00000018, 0xffffffff,
0472     0x000008fc, 0xffffffff, 0xffffffff,
0473     0x000008f8, 0x00000019, 0xffffffff,
0474     0x000008fc, 0xffffffff, 0xffffffff,
0475     0x000008f8, 0x0000001a, 0xffffffff,
0476     0x000008fc, 0xffffffff, 0xffffffff,
0477     0x000008f8, 0x0000001b, 0xffffffff,
0478     0x000008fc, 0xffffffff, 0xffffffff,
0479     0x000008f8, 0x00000020, 0xffffffff,
0480     0x000008fc, 0x00000000, 0xffffffff,
0481     0x000008f8, 0x00000021, 0xffffffff,
0482     0x000008fc, 0x00000000, 0xffffffff,
0483     0x000008f8, 0x00000022, 0xffffffff,
0484     0x000008fc, 0x00000000, 0xffffffff,
0485     0x000008f8, 0x00000023, 0xffffffff,
0486     0x000008fc, 0x00000000, 0xffffffff,
0487     0x000008f8, 0x00000024, 0xffffffff,
0488     0x000008fc, 0x00000000, 0xffffffff,
0489     0x000008f8, 0x00000025, 0xffffffff,
0490     0x000008fc, 0x00000000, 0xffffffff,
0491     0x000008f8, 0x00000026, 0xffffffff,
0492     0x000008fc, 0x00000000, 0xffffffff,
0493     0x000008f8, 0x00000027, 0xffffffff,
0494     0x000008fc, 0x00000000, 0xffffffff,
0495     0x000008f8, 0x00000028, 0xffffffff,
0496     0x000008fc, 0x00000000, 0xffffffff,
0497     0x000008f8, 0x00000029, 0xffffffff,
0498     0x000008fc, 0x00000000, 0xffffffff,
0499     0x000008f8, 0x0000002a, 0xffffffff,
0500     0x000008fc, 0x00000000, 0xffffffff,
0501     0x000008f8, 0x0000002b, 0xffffffff,
0502     0x000008fc, 0x00000000, 0xffffffff,
0503     0x00000644, 0x000f7912, 0x001f4180,
0504     0x00000644, 0x000f3812, 0x001f4180
0505 };
0506 #define CAICOS_CGCG_CGLS_DISABLE_LENGTH sizeof(caicos_cgcg_cgls_disable) / (3 * sizeof(u32))
0507 
0508 static const u32 caicos_cgcg_cgls_enable[] =
0509 {
0510     /* 0x0000c124, 0x84180000, 0x00180000, */
0511     0x00000644, 0x000f7892, 0x001f4080,
0512     0x000008f8, 0x00000010, 0xffffffff,
0513     0x000008fc, 0x00000000, 0xffffffff,
0514     0x000008f8, 0x00000011, 0xffffffff,
0515     0x000008fc, 0x00000000, 0xffffffff,
0516     0x000008f8, 0x00000012, 0xffffffff,
0517     0x000008fc, 0x00000000, 0xffffffff,
0518     0x000008f8, 0x00000013, 0xffffffff,
0519     0x000008fc, 0x00000000, 0xffffffff,
0520     0x000008f8, 0x00000014, 0xffffffff,
0521     0x000008fc, 0x00000000, 0xffffffff,
0522     0x000008f8, 0x00000015, 0xffffffff,
0523     0x000008fc, 0x00000000, 0xffffffff,
0524     0x000008f8, 0x00000016, 0xffffffff,
0525     0x000008fc, 0x00000000, 0xffffffff,
0526     0x000008f8, 0x00000017, 0xffffffff,
0527     0x000008fc, 0x00000000, 0xffffffff,
0528     0x000008f8, 0x00000018, 0xffffffff,
0529     0x000008fc, 0x00000000, 0xffffffff,
0530     0x000008f8, 0x00000019, 0xffffffff,
0531     0x000008fc, 0x00000000, 0xffffffff,
0532     0x000008f8, 0x0000001a, 0xffffffff,
0533     0x000008fc, 0x00000000, 0xffffffff,
0534     0x000008f8, 0x0000001b, 0xffffffff,
0535     0x000008fc, 0x00000000, 0xffffffff,
0536     0x000008f8, 0x00000020, 0xffffffff,
0537     0x000008fc, 0xffffffff, 0xffffffff,
0538     0x000008f8, 0x00000021, 0xffffffff,
0539     0x000008fc, 0xffffffff, 0xffffffff,
0540     0x000008f8, 0x00000022, 0xffffffff,
0541     0x000008fc, 0xffffffff, 0xffffffff,
0542     0x000008f8, 0x00000023, 0xffffffff,
0543     0x000008fc, 0xffffffff, 0xffffffff,
0544     0x000008f8, 0x00000024, 0xffffffff,
0545     0x000008fc, 0xffffffff, 0xffffffff,
0546     0x000008f8, 0x00000025, 0xffffffff,
0547     0x000008fc, 0xffffffff, 0xffffffff,
0548     0x000008f8, 0x00000026, 0xffffffff,
0549     0x000008fc, 0xffffffff, 0xffffffff,
0550     0x000008f8, 0x00000027, 0xffffffff,
0551     0x000008fc, 0xffffffff, 0xffffffff,
0552     0x000008f8, 0x00000028, 0xffffffff,
0553     0x000008fc, 0xffffffff, 0xffffffff,
0554     0x000008f8, 0x00000029, 0xffffffff,
0555     0x000008fc, 0xffffffff, 0xffffffff,
0556     0x000008f8, 0x0000002a, 0xffffffff,
0557     0x000008fc, 0xffffffff, 0xffffffff,
0558     0x000008f8, 0x0000002b, 0xffffffff,
0559     0x000008fc, 0xffffffff, 0xffffffff
0560 };
0561 #define CAICOS_CGCG_CGLS_ENABLE_LENGTH sizeof(caicos_cgcg_cgls_enable) / (3 * sizeof(u32))
0562 
0563 static const u32 caicos_mgcg_default[] =
0564 {
0565     0x0000802c, 0xc0000000, 0xffffffff,
0566     0x00005448, 0x00000100, 0xffffffff,
0567     0x000055e4, 0x00600100, 0xffffffff,
0568     0x0000160c, 0x00000100, 0xffffffff,
0569     0x0000c164, 0x00000100, 0xffffffff,
0570     0x00008a18, 0x00000100, 0xffffffff,
0571     0x0000897c, 0x06000100, 0xffffffff,
0572     0x00008b28, 0x00000100, 0xffffffff,
0573     0x00009144, 0x00000100, 0xffffffff,
0574     0x00009a60, 0x00000100, 0xffffffff,
0575     0x00009868, 0x00000100, 0xffffffff,
0576     0x00008d58, 0x00000100, 0xffffffff,
0577     0x00009510, 0x00000100, 0xffffffff,
0578     0x0000949c, 0x00000100, 0xffffffff,
0579     0x00009654, 0x00000100, 0xffffffff,
0580     0x00009030, 0x00000100, 0xffffffff,
0581     0x00009034, 0x00000100, 0xffffffff,
0582     0x00009038, 0x00000100, 0xffffffff,
0583     0x0000903c, 0x00000100, 0xffffffff,
0584     0x00009040, 0x00000100, 0xffffffff,
0585     0x0000a200, 0x00000100, 0xffffffff,
0586     0x0000a204, 0x00000100, 0xffffffff,
0587     0x0000a208, 0x00000100, 0xffffffff,
0588     0x0000a20c, 0x00000100, 0xffffffff,
0589     0x0000977c, 0x00000100, 0xffffffff,
0590     0x00003f80, 0x00000100, 0xffffffff,
0591     0x0000a210, 0x00000100, 0xffffffff,
0592     0x0000a214, 0x00000100, 0xffffffff,
0593     0x000004d8, 0x00000100, 0xffffffff,
0594     0x00009784, 0x00000100, 0xffffffff,
0595     0x00009698, 0x00000100, 0xffffffff,
0596     0x000004d4, 0x00000200, 0xffffffff,
0597     0x000004d0, 0x00000000, 0xffffffff,
0598     0x000030cc, 0x00000100, 0xffffffff,
0599     0x0000d0c0, 0xff000100, 0xffffffff,
0600     0x0000915c, 0x00010000, 0xffffffff,
0601     0x00009160, 0x00030002, 0xffffffff,
0602     0x00009164, 0x00050004, 0xffffffff,
0603     0x00009168, 0x00070006, 0xffffffff,
0604     0x00009178, 0x00070000, 0xffffffff,
0605     0x0000917c, 0x00030002, 0xffffffff,
0606     0x00009180, 0x00050004, 0xffffffff,
0607     0x0000918c, 0x00010006, 0xffffffff,
0608     0x00009190, 0x00090008, 0xffffffff,
0609     0x00009194, 0x00070000, 0xffffffff,
0610     0x00009198, 0x00030002, 0xffffffff,
0611     0x0000919c, 0x00050004, 0xffffffff,
0612     0x000091a8, 0x00010006, 0xffffffff,
0613     0x000091ac, 0x00090008, 0xffffffff,
0614     0x000091e8, 0x00000000, 0xffffffff,
0615     0x00009294, 0x00000000, 0xffffffff,
0616     0x000008f8, 0x00000010, 0xffffffff,
0617     0x000008fc, 0x00000000, 0xffffffff,
0618     0x000008f8, 0x00000011, 0xffffffff,
0619     0x000008fc, 0x00000000, 0xffffffff,
0620     0x000008f8, 0x00000012, 0xffffffff,
0621     0x000008fc, 0x00000000, 0xffffffff,
0622     0x000008f8, 0x00000013, 0xffffffff,
0623     0x000008fc, 0x00000000, 0xffffffff,
0624     0x000008f8, 0x00000014, 0xffffffff,
0625     0x000008fc, 0x00000000, 0xffffffff,
0626     0x000008f8, 0x00000015, 0xffffffff,
0627     0x000008fc, 0x00000000, 0xffffffff,
0628     0x000008f8, 0x00000016, 0xffffffff,
0629     0x000008fc, 0x00000000, 0xffffffff,
0630     0x000008f8, 0x00000017, 0xffffffff,
0631     0x000008fc, 0x00000000, 0xffffffff,
0632     0x000008f8, 0x00000018, 0xffffffff,
0633     0x000008fc, 0x00000000, 0xffffffff,
0634     0x000008f8, 0x00000019, 0xffffffff,
0635     0x000008fc, 0x00000000, 0xffffffff,
0636     0x000008f8, 0x0000001a, 0xffffffff,
0637     0x000008fc, 0x00000000, 0xffffffff,
0638     0x000008f8, 0x0000001b, 0xffffffff,
0639     0x000008fc, 0x00000000, 0xffffffff
0640 };
0641 #define CAICOS_MGCG_DEFAULT_LENGTH sizeof(caicos_mgcg_default) / (3 * sizeof(u32))
0642 
0643 static const u32 caicos_mgcg_disable[] =
0644 {
0645     0x0000802c, 0xc0000000, 0xffffffff,
0646     0x000008f8, 0x00000000, 0xffffffff,
0647     0x000008fc, 0xffffffff, 0xffffffff,
0648     0x000008f8, 0x00000001, 0xffffffff,
0649     0x000008fc, 0xffffffff, 0xffffffff,
0650     0x000008f8, 0x00000002, 0xffffffff,
0651     0x000008fc, 0xffffffff, 0xffffffff,
0652     0x000008f8, 0x00000003, 0xffffffff,
0653     0x000008fc, 0xffffffff, 0xffffffff,
0654     0x00009150, 0x00600000, 0xffffffff
0655 };
0656 #define CAICOS_MGCG_DISABLE_LENGTH sizeof(caicos_mgcg_disable) / (3 * sizeof(u32))
0657 
0658 static const u32 caicos_mgcg_enable[] =
0659 {
0660     0x0000802c, 0xc0000000, 0xffffffff,
0661     0x000008f8, 0x00000000, 0xffffffff,
0662     0x000008fc, 0x00000000, 0xffffffff,
0663     0x000008f8, 0x00000001, 0xffffffff,
0664     0x000008fc, 0x00000000, 0xffffffff,
0665     0x000008f8, 0x00000002, 0xffffffff,
0666     0x000008fc, 0x00000000, 0xffffffff,
0667     0x000008f8, 0x00000003, 0xffffffff,
0668     0x000008fc, 0x00000000, 0xffffffff,
0669     0x00009150, 0x46944040, 0xffffffff
0670 };
0671 #define CAICOS_MGCG_ENABLE_LENGTH sizeof(caicos_mgcg_enable) / (3 * sizeof(u32))
0672 
0673 //********* TURKS **************//
0674 static const u32 turks_cgcg_cgls_default[] =
0675 {
0676     0x000008f8, 0x00000010, 0xffffffff,
0677     0x000008fc, 0x00000000, 0xffffffff,
0678     0x000008f8, 0x00000011, 0xffffffff,
0679     0x000008fc, 0x00000000, 0xffffffff,
0680     0x000008f8, 0x00000012, 0xffffffff,
0681     0x000008fc, 0x00000000, 0xffffffff,
0682     0x000008f8, 0x00000013, 0xffffffff,
0683     0x000008fc, 0x00000000, 0xffffffff,
0684     0x000008f8, 0x00000014, 0xffffffff,
0685     0x000008fc, 0x00000000, 0xffffffff,
0686     0x000008f8, 0x00000015, 0xffffffff,
0687     0x000008fc, 0x00000000, 0xffffffff,
0688     0x000008f8, 0x00000016, 0xffffffff,
0689     0x000008fc, 0x00000000, 0xffffffff,
0690     0x000008f8, 0x00000017, 0xffffffff,
0691     0x000008fc, 0x00000000, 0xffffffff,
0692     0x000008f8, 0x00000018, 0xffffffff,
0693     0x000008fc, 0x00000000, 0xffffffff,
0694     0x000008f8, 0x00000019, 0xffffffff,
0695     0x000008fc, 0x00000000, 0xffffffff,
0696     0x000008f8, 0x0000001a, 0xffffffff,
0697     0x000008fc, 0x00000000, 0xffffffff,
0698     0x000008f8, 0x0000001b, 0xffffffff,
0699     0x000008fc, 0x00000000, 0xffffffff,
0700     0x000008f8, 0x00000020, 0xffffffff,
0701     0x000008fc, 0x00000000, 0xffffffff,
0702     0x000008f8, 0x00000021, 0xffffffff,
0703     0x000008fc, 0x00000000, 0xffffffff,
0704     0x000008f8, 0x00000022, 0xffffffff,
0705     0x000008fc, 0x00000000, 0xffffffff,
0706     0x000008f8, 0x00000023, 0xffffffff,
0707     0x000008fc, 0x00000000, 0xffffffff,
0708     0x000008f8, 0x00000024, 0xffffffff,
0709     0x000008fc, 0x00000000, 0xffffffff,
0710     0x000008f8, 0x00000025, 0xffffffff,
0711     0x000008fc, 0x00000000, 0xffffffff,
0712     0x000008f8, 0x00000026, 0xffffffff,
0713     0x000008fc, 0x00000000, 0xffffffff,
0714     0x000008f8, 0x00000027, 0xffffffff,
0715     0x000008fc, 0x00000000, 0xffffffff,
0716     0x000008f8, 0x00000028, 0xffffffff,
0717     0x000008fc, 0x00000000, 0xffffffff,
0718     0x000008f8, 0x00000029, 0xffffffff,
0719     0x000008fc, 0x00000000, 0xffffffff,
0720     0x000008f8, 0x0000002a, 0xffffffff,
0721     0x000008fc, 0x00000000, 0xffffffff,
0722     0x000008f8, 0x0000002b, 0xffffffff,
0723     0x000008fc, 0x00000000, 0xffffffff
0724 };
0725 #define TURKS_CGCG_CGLS_DEFAULT_LENGTH  sizeof(turks_cgcg_cgls_default) / (3 * sizeof(u32))
0726 
0727 static const u32 turks_cgcg_cgls_disable[] =
0728 {
0729     0x000008f8, 0x00000010, 0xffffffff,
0730     0x000008fc, 0xffffffff, 0xffffffff,
0731     0x000008f8, 0x00000011, 0xffffffff,
0732     0x000008fc, 0xffffffff, 0xffffffff,
0733     0x000008f8, 0x00000012, 0xffffffff,
0734     0x000008fc, 0xffffffff, 0xffffffff,
0735     0x000008f8, 0x00000013, 0xffffffff,
0736     0x000008fc, 0xffffffff, 0xffffffff,
0737     0x000008f8, 0x00000014, 0xffffffff,
0738     0x000008fc, 0xffffffff, 0xffffffff,
0739     0x000008f8, 0x00000015, 0xffffffff,
0740     0x000008fc, 0xffffffff, 0xffffffff,
0741     0x000008f8, 0x00000016, 0xffffffff,
0742     0x000008fc, 0xffffffff, 0xffffffff,
0743     0x000008f8, 0x00000017, 0xffffffff,
0744     0x000008fc, 0xffffffff, 0xffffffff,
0745     0x000008f8, 0x00000018, 0xffffffff,
0746     0x000008fc, 0xffffffff, 0xffffffff,
0747     0x000008f8, 0x00000019, 0xffffffff,
0748     0x000008fc, 0xffffffff, 0xffffffff,
0749     0x000008f8, 0x0000001a, 0xffffffff,
0750     0x000008fc, 0xffffffff, 0xffffffff,
0751     0x000008f8, 0x0000001b, 0xffffffff,
0752     0x000008fc, 0xffffffff, 0xffffffff,
0753     0x000008f8, 0x00000020, 0xffffffff,
0754     0x000008fc, 0x00000000, 0xffffffff,
0755     0x000008f8, 0x00000021, 0xffffffff,
0756     0x000008fc, 0x00000000, 0xffffffff,
0757     0x000008f8, 0x00000022, 0xffffffff,
0758     0x000008fc, 0x00000000, 0xffffffff,
0759     0x000008f8, 0x00000023, 0xffffffff,
0760     0x000008fc, 0x00000000, 0xffffffff,
0761     0x000008f8, 0x00000024, 0xffffffff,
0762     0x000008fc, 0x00000000, 0xffffffff,
0763     0x000008f8, 0x00000025, 0xffffffff,
0764     0x000008fc, 0x00000000, 0xffffffff,
0765     0x000008f8, 0x00000026, 0xffffffff,
0766     0x000008fc, 0x00000000, 0xffffffff,
0767     0x000008f8, 0x00000027, 0xffffffff,
0768     0x000008fc, 0x00000000, 0xffffffff,
0769     0x000008f8, 0x00000028, 0xffffffff,
0770     0x000008fc, 0x00000000, 0xffffffff,
0771     0x000008f8, 0x00000029, 0xffffffff,
0772     0x000008fc, 0x00000000, 0xffffffff,
0773     0x000008f8, 0x0000002a, 0xffffffff,
0774     0x000008fc, 0x00000000, 0xffffffff,
0775     0x000008f8, 0x0000002b, 0xffffffff,
0776     0x000008fc, 0x00000000, 0xffffffff,
0777     0x00000644, 0x000f7912, 0x001f4180,
0778     0x00000644, 0x000f3812, 0x001f4180
0779 };
0780 #define TURKS_CGCG_CGLS_DISABLE_LENGTH sizeof(turks_cgcg_cgls_disable) / (3 * sizeof(u32))
0781 
0782 static const u32 turks_cgcg_cgls_enable[] =
0783 {
0784     /* 0x0000c124, 0x84180000, 0x00180000, */
0785     0x00000644, 0x000f7892, 0x001f4080,
0786     0x000008f8, 0x00000010, 0xffffffff,
0787     0x000008fc, 0x00000000, 0xffffffff,
0788     0x000008f8, 0x00000011, 0xffffffff,
0789     0x000008fc, 0x00000000, 0xffffffff,
0790     0x000008f8, 0x00000012, 0xffffffff,
0791     0x000008fc, 0x00000000, 0xffffffff,
0792     0x000008f8, 0x00000013, 0xffffffff,
0793     0x000008fc, 0x00000000, 0xffffffff,
0794     0x000008f8, 0x00000014, 0xffffffff,
0795     0x000008fc, 0x00000000, 0xffffffff,
0796     0x000008f8, 0x00000015, 0xffffffff,
0797     0x000008fc, 0x00000000, 0xffffffff,
0798     0x000008f8, 0x00000016, 0xffffffff,
0799     0x000008fc, 0x00000000, 0xffffffff,
0800     0x000008f8, 0x00000017, 0xffffffff,
0801     0x000008fc, 0x00000000, 0xffffffff,
0802     0x000008f8, 0x00000018, 0xffffffff,
0803     0x000008fc, 0x00000000, 0xffffffff,
0804     0x000008f8, 0x00000019, 0xffffffff,
0805     0x000008fc, 0x00000000, 0xffffffff,
0806     0x000008f8, 0x0000001a, 0xffffffff,
0807     0x000008fc, 0x00000000, 0xffffffff,
0808     0x000008f8, 0x0000001b, 0xffffffff,
0809     0x000008fc, 0x00000000, 0xffffffff,
0810     0x000008f8, 0x00000020, 0xffffffff,
0811     0x000008fc, 0xffffffff, 0xffffffff,
0812     0x000008f8, 0x00000021, 0xffffffff,
0813     0x000008fc, 0xffffffff, 0xffffffff,
0814     0x000008f8, 0x00000022, 0xffffffff,
0815     0x000008fc, 0xffffffff, 0xffffffff,
0816     0x000008f8, 0x00000023, 0xffffffff,
0817     0x000008fc, 0xffffffff, 0xffffffff,
0818     0x000008f8, 0x00000024, 0xffffffff,
0819     0x000008fc, 0xffffffff, 0xffffffff,
0820     0x000008f8, 0x00000025, 0xffffffff,
0821     0x000008fc, 0xffffffff, 0xffffffff,
0822     0x000008f8, 0x00000026, 0xffffffff,
0823     0x000008fc, 0xffffffff, 0xffffffff,
0824     0x000008f8, 0x00000027, 0xffffffff,
0825     0x000008fc, 0xffffffff, 0xffffffff,
0826     0x000008f8, 0x00000028, 0xffffffff,
0827     0x000008fc, 0xffffffff, 0xffffffff,
0828     0x000008f8, 0x00000029, 0xffffffff,
0829     0x000008fc, 0xffffffff, 0xffffffff,
0830     0x000008f8, 0x0000002a, 0xffffffff,
0831     0x000008fc, 0xffffffff, 0xffffffff,
0832     0x000008f8, 0x0000002b, 0xffffffff,
0833     0x000008fc, 0xffffffff, 0xffffffff
0834 };
0835 #define TURKS_CGCG_CGLS_ENABLE_LENGTH sizeof(turks_cgcg_cgls_enable) / (3 * sizeof(u32))
0836 
0837 // These are the sequences for turks_mgcg_shls
0838 static const u32 turks_mgcg_default[] =
0839 {
0840     0x0000802c, 0xc0000000, 0xffffffff,
0841     0x00005448, 0x00000100, 0xffffffff,
0842     0x000055e4, 0x00600100, 0xffffffff,
0843     0x0000160c, 0x00000100, 0xffffffff,
0844     0x0000c164, 0x00000100, 0xffffffff,
0845     0x00008a18, 0x00000100, 0xffffffff,
0846     0x0000897c, 0x06000100, 0xffffffff,
0847     0x00008b28, 0x00000100, 0xffffffff,
0848     0x00009144, 0x00000100, 0xffffffff,
0849     0x00009a60, 0x00000100, 0xffffffff,
0850     0x00009868, 0x00000100, 0xffffffff,
0851     0x00008d58, 0x00000100, 0xffffffff,
0852     0x00009510, 0x00000100, 0xffffffff,
0853     0x0000949c, 0x00000100, 0xffffffff,
0854     0x00009654, 0x00000100, 0xffffffff,
0855     0x00009030, 0x00000100, 0xffffffff,
0856     0x00009034, 0x00000100, 0xffffffff,
0857     0x00009038, 0x00000100, 0xffffffff,
0858     0x0000903c, 0x00000100, 0xffffffff,
0859     0x00009040, 0x00000100, 0xffffffff,
0860     0x0000a200, 0x00000100, 0xffffffff,
0861     0x0000a204, 0x00000100, 0xffffffff,
0862     0x0000a208, 0x00000100, 0xffffffff,
0863     0x0000a20c, 0x00000100, 0xffffffff,
0864     0x0000977c, 0x00000100, 0xffffffff,
0865     0x00003f80, 0x00000100, 0xffffffff,
0866     0x0000a210, 0x00000100, 0xffffffff,
0867     0x0000a214, 0x00000100, 0xffffffff,
0868     0x000004d8, 0x00000100, 0xffffffff,
0869     0x00009784, 0x00000100, 0xffffffff,
0870     0x00009698, 0x00000100, 0xffffffff,
0871     0x000004d4, 0x00000200, 0xffffffff,
0872     0x000004d0, 0x00000000, 0xffffffff,
0873     0x000030cc, 0x00000100, 0xffffffff,
0874     0x0000d0c0, 0x00000100, 0xffffffff,
0875     0x0000915c, 0x00010000, 0xffffffff,
0876     0x00009160, 0x00030002, 0xffffffff,
0877     0x00009164, 0x00050004, 0xffffffff,
0878     0x00009168, 0x00070006, 0xffffffff,
0879     0x00009178, 0x00070000, 0xffffffff,
0880     0x0000917c, 0x00030002, 0xffffffff,
0881     0x00009180, 0x00050004, 0xffffffff,
0882     0x0000918c, 0x00010006, 0xffffffff,
0883     0x00009190, 0x00090008, 0xffffffff,
0884     0x00009194, 0x00070000, 0xffffffff,
0885     0x00009198, 0x00030002, 0xffffffff,
0886     0x0000919c, 0x00050004, 0xffffffff,
0887     0x000091a8, 0x00010006, 0xffffffff,
0888     0x000091ac, 0x00090008, 0xffffffff,
0889     0x000091b0, 0x00070000, 0xffffffff,
0890     0x000091b4, 0x00030002, 0xffffffff,
0891     0x000091b8, 0x00050004, 0xffffffff,
0892     0x000091c4, 0x00010006, 0xffffffff,
0893     0x000091c8, 0x00090008, 0xffffffff,
0894     0x000091cc, 0x00070000, 0xffffffff,
0895     0x000091d0, 0x00030002, 0xffffffff,
0896     0x000091d4, 0x00050004, 0xffffffff,
0897     0x000091e0, 0x00010006, 0xffffffff,
0898     0x000091e4, 0x00090008, 0xffffffff,
0899     0x000091e8, 0x00000000, 0xffffffff,
0900     0x000091ec, 0x00070000, 0xffffffff,
0901     0x000091f0, 0x00030002, 0xffffffff,
0902     0x000091f4, 0x00050004, 0xffffffff,
0903     0x00009200, 0x00010006, 0xffffffff,
0904     0x00009204, 0x00090008, 0xffffffff,
0905     0x00009208, 0x00070000, 0xffffffff,
0906     0x0000920c, 0x00030002, 0xffffffff,
0907     0x00009210, 0x00050004, 0xffffffff,
0908     0x0000921c, 0x00010006, 0xffffffff,
0909     0x00009220, 0x00090008, 0xffffffff,
0910     0x00009294, 0x00000000, 0xffffffff,
0911     0x000008f8, 0x00000010, 0xffffffff,
0912     0x000008fc, 0x00000000, 0xffffffff,
0913     0x000008f8, 0x00000011, 0xffffffff,
0914     0x000008fc, 0x00000000, 0xffffffff,
0915     0x000008f8, 0x00000012, 0xffffffff,
0916     0x000008fc, 0x00000000, 0xffffffff,
0917     0x000008f8, 0x00000013, 0xffffffff,
0918     0x000008fc, 0x00000000, 0xffffffff,
0919     0x000008f8, 0x00000014, 0xffffffff,
0920     0x000008fc, 0x00000000, 0xffffffff,
0921     0x000008f8, 0x00000015, 0xffffffff,
0922     0x000008fc, 0x00000000, 0xffffffff,
0923     0x000008f8, 0x00000016, 0xffffffff,
0924     0x000008fc, 0x00000000, 0xffffffff,
0925     0x000008f8, 0x00000017, 0xffffffff,
0926     0x000008fc, 0x00000000, 0xffffffff,
0927     0x000008f8, 0x00000018, 0xffffffff,
0928     0x000008fc, 0x00000000, 0xffffffff,
0929     0x000008f8, 0x00000019, 0xffffffff,
0930     0x000008fc, 0x00000000, 0xffffffff,
0931     0x000008f8, 0x0000001a, 0xffffffff,
0932     0x000008fc, 0x00000000, 0xffffffff,
0933     0x000008f8, 0x0000001b, 0xffffffff,
0934     0x000008fc, 0x00000000, 0xffffffff
0935 };
0936 #define TURKS_MGCG_DEFAULT_LENGTH sizeof(turks_mgcg_default) / (3 * sizeof(u32))
0937 
0938 static const u32 turks_mgcg_disable[] =
0939 {
0940     0x0000802c, 0xc0000000, 0xffffffff,
0941     0x000008f8, 0x00000000, 0xffffffff,
0942     0x000008fc, 0xffffffff, 0xffffffff,
0943     0x000008f8, 0x00000001, 0xffffffff,
0944     0x000008fc, 0xffffffff, 0xffffffff,
0945     0x000008f8, 0x00000002, 0xffffffff,
0946     0x000008fc, 0xffffffff, 0xffffffff,
0947     0x000008f8, 0x00000003, 0xffffffff,
0948     0x000008fc, 0xffffffff, 0xffffffff,
0949     0x00009150, 0x00600000, 0xffffffff
0950 };
0951 #define TURKS_MGCG_DISABLE_LENGTH sizeof(turks_mgcg_disable) / (3 * sizeof(u32))
0952 
0953 static const u32 turks_mgcg_enable[] =
0954 {
0955     0x0000802c, 0xc0000000, 0xffffffff,
0956     0x000008f8, 0x00000000, 0xffffffff,
0957     0x000008fc, 0x00000000, 0xffffffff,
0958     0x000008f8, 0x00000001, 0xffffffff,
0959     0x000008fc, 0x00000000, 0xffffffff,
0960     0x000008f8, 0x00000002, 0xffffffff,
0961     0x000008fc, 0x00000000, 0xffffffff,
0962     0x000008f8, 0x00000003, 0xffffffff,
0963     0x000008fc, 0x00000000, 0xffffffff,
0964     0x00009150, 0x6e944000, 0xffffffff
0965 };
0966 #define TURKS_MGCG_ENABLE_LENGTH sizeof(turks_mgcg_enable) / (3 * sizeof(u32))
0967 
0968 #endif
0969 
0970 #ifndef BTC_SYSLS_SEQUENCE
0971 #define BTC_SYSLS_SEQUENCE  100
0972 
0973 
0974 //********* BARTS **************//
0975 static const u32 barts_sysls_default[] =
0976 {
0977     /* Register,   Value,     Mask bits */
0978     0x000055e8, 0x00000000, 0xffffffff,
0979     0x0000d0bc, 0x00000000, 0xffffffff,
0980     0x000015c0, 0x000c1401, 0xffffffff,
0981     0x0000264c, 0x000c0400, 0xffffffff,
0982     0x00002648, 0x000c0400, 0xffffffff,
0983     0x00002650, 0x000c0400, 0xffffffff,
0984     0x000020b8, 0x000c0400, 0xffffffff,
0985     0x000020bc, 0x000c0400, 0xffffffff,
0986     0x000020c0, 0x000c0c80, 0xffffffff,
0987     0x0000f4a0, 0x000000c0, 0xffffffff,
0988     0x0000f4a4, 0x00680fff, 0xffffffff,
0989     0x000004c8, 0x00000001, 0xffffffff,
0990     0x000064ec, 0x00000000, 0xffffffff,
0991     0x00000c7c, 0x00000000, 0xffffffff,
0992     0x00006dfc, 0x00000000, 0xffffffff
0993 };
0994 #define BARTS_SYSLS_DEFAULT_LENGTH sizeof(barts_sysls_default) / (3 * sizeof(u32))
0995 
0996 static const u32 barts_sysls_disable[] =
0997 {
0998     0x000055e8, 0x00000000, 0xffffffff,
0999     0x0000d0bc, 0x00000000, 0xffffffff,
1000     0x000015c0, 0x00041401, 0xffffffff,
1001     0x0000264c, 0x00040400, 0xffffffff,
1002     0x00002648, 0x00040400, 0xffffffff,
1003     0x00002650, 0x00040400, 0xffffffff,
1004     0x000020b8, 0x00040400, 0xffffffff,
1005     0x000020bc, 0x00040400, 0xffffffff,
1006     0x000020c0, 0x00040c80, 0xffffffff,
1007     0x0000f4a0, 0x000000c0, 0xffffffff,
1008     0x0000f4a4, 0x00680000, 0xffffffff,
1009     0x000004c8, 0x00000001, 0xffffffff,
1010     0x000064ec, 0x00007ffd, 0xffffffff,
1011     0x00000c7c, 0x0000ff00, 0xffffffff,
1012     0x00006dfc, 0x0000007f, 0xffffffff
1013 };
1014 #define BARTS_SYSLS_DISABLE_LENGTH sizeof(barts_sysls_disable) / (3 * sizeof(u32))
1015 
1016 static const u32 barts_sysls_enable[] =
1017 {
1018     0x000055e8, 0x00000001, 0xffffffff,
1019     0x0000d0bc, 0x00000100, 0xffffffff,
1020     0x000015c0, 0x000c1401, 0xffffffff,
1021     0x0000264c, 0x000c0400, 0xffffffff,
1022     0x00002648, 0x000c0400, 0xffffffff,
1023     0x00002650, 0x000c0400, 0xffffffff,
1024     0x000020b8, 0x000c0400, 0xffffffff,
1025     0x000020bc, 0x000c0400, 0xffffffff,
1026     0x000020c0, 0x000c0c80, 0xffffffff,
1027     0x0000f4a0, 0x000000c0, 0xffffffff,
1028     0x0000f4a4, 0x00680fff, 0xffffffff,
1029     0x000004c8, 0x00000000, 0xffffffff,
1030     0x000064ec, 0x00000000, 0xffffffff,
1031     0x00000c7c, 0x00000000, 0xffffffff,
1032     0x00006dfc, 0x00000000, 0xffffffff
1033 };
1034 #define BARTS_SYSLS_ENABLE_LENGTH sizeof(barts_sysls_enable) / (3 * sizeof(u32))
1035 
1036 //********* CAICOS **************//
1037 static const u32 caicos_sysls_default[] =
1038 {
1039     0x000055e8, 0x00000000, 0xffffffff,
1040     0x0000d0bc, 0x00000000, 0xffffffff,
1041     0x000015c0, 0x000c1401, 0xffffffff,
1042     0x0000264c, 0x000c0400, 0xffffffff,
1043     0x00002648, 0x000c0400, 0xffffffff,
1044     0x00002650, 0x000c0400, 0xffffffff,
1045     0x000020b8, 0x000c0400, 0xffffffff,
1046     0x000020bc, 0x000c0400, 0xffffffff,
1047     0x0000f4a0, 0x000000c0, 0xffffffff,
1048     0x0000f4a4, 0x00680fff, 0xffffffff,
1049     0x000004c8, 0x00000001, 0xffffffff,
1050     0x000064ec, 0x00000000, 0xffffffff,
1051     0x00000c7c, 0x00000000, 0xffffffff,
1052     0x00006dfc, 0x00000000, 0xffffffff
1053 };
1054 #define CAICOS_SYSLS_DEFAULT_LENGTH sizeof(caicos_sysls_default) / (3 * sizeof(u32))
1055 
1056 static const u32 caicos_sysls_disable[] =
1057 {
1058     0x000055e8, 0x00000000, 0xffffffff,
1059     0x0000d0bc, 0x00000000, 0xffffffff,
1060     0x000015c0, 0x00041401, 0xffffffff,
1061     0x0000264c, 0x00040400, 0xffffffff,
1062     0x00002648, 0x00040400, 0xffffffff,
1063     0x00002650, 0x00040400, 0xffffffff,
1064     0x000020b8, 0x00040400, 0xffffffff,
1065     0x000020bc, 0x00040400, 0xffffffff,
1066     0x0000f4a0, 0x000000c0, 0xffffffff,
1067     0x0000f4a4, 0x00680000, 0xffffffff,
1068     0x000004c8, 0x00000001, 0xffffffff,
1069     0x000064ec, 0x00007ffd, 0xffffffff,
1070     0x00000c7c, 0x0000ff00, 0xffffffff,
1071     0x00006dfc, 0x0000007f, 0xffffffff
1072 };
1073 #define CAICOS_SYSLS_DISABLE_LENGTH sizeof(caicos_sysls_disable) / (3 * sizeof(u32))
1074 
1075 static const u32 caicos_sysls_enable[] =
1076 {
1077     0x000055e8, 0x00000001, 0xffffffff,
1078     0x0000d0bc, 0x00000100, 0xffffffff,
1079     0x000015c0, 0x000c1401, 0xffffffff,
1080     0x0000264c, 0x000c0400, 0xffffffff,
1081     0x00002648, 0x000c0400, 0xffffffff,
1082     0x00002650, 0x000c0400, 0xffffffff,
1083     0x000020b8, 0x000c0400, 0xffffffff,
1084     0x000020bc, 0x000c0400, 0xffffffff,
1085     0x0000f4a0, 0x000000c0, 0xffffffff,
1086     0x0000f4a4, 0x00680fff, 0xffffffff,
1087     0x000064ec, 0x00000000, 0xffffffff,
1088     0x00000c7c, 0x00000000, 0xffffffff,
1089     0x00006dfc, 0x00000000, 0xffffffff,
1090     0x000004c8, 0x00000000, 0xffffffff
1091 };
1092 #define CAICOS_SYSLS_ENABLE_LENGTH sizeof(caicos_sysls_enable) / (3 * sizeof(u32))
1093 
1094 //********* TURKS **************//
1095 static const u32 turks_sysls_default[] =
1096 {
1097     0x000055e8, 0x00000000, 0xffffffff,
1098     0x0000d0bc, 0x00000000, 0xffffffff,
1099     0x000015c0, 0x000c1401, 0xffffffff,
1100     0x0000264c, 0x000c0400, 0xffffffff,
1101     0x00002648, 0x000c0400, 0xffffffff,
1102     0x00002650, 0x000c0400, 0xffffffff,
1103     0x000020b8, 0x000c0400, 0xffffffff,
1104     0x000020bc, 0x000c0400, 0xffffffff,
1105     0x000020c0, 0x000c0c80, 0xffffffff,
1106     0x0000f4a0, 0x000000c0, 0xffffffff,
1107     0x0000f4a4, 0x00680fff, 0xffffffff,
1108     0x000004c8, 0x00000001, 0xffffffff,
1109     0x000064ec, 0x00000000, 0xffffffff,
1110     0x00000c7c, 0x00000000, 0xffffffff,
1111     0x00006dfc, 0x00000000, 0xffffffff
1112 };
1113 #define TURKS_SYSLS_DEFAULT_LENGTH sizeof(turks_sysls_default) / (3 * sizeof(u32))
1114 
1115 static const u32 turks_sysls_disable[] =
1116 {
1117     0x000055e8, 0x00000000, 0xffffffff,
1118     0x0000d0bc, 0x00000000, 0xffffffff,
1119     0x000015c0, 0x00041401, 0xffffffff,
1120     0x0000264c, 0x00040400, 0xffffffff,
1121     0x00002648, 0x00040400, 0xffffffff,
1122     0x00002650, 0x00040400, 0xffffffff,
1123     0x000020b8, 0x00040400, 0xffffffff,
1124     0x000020bc, 0x00040400, 0xffffffff,
1125     0x000020c0, 0x00040c80, 0xffffffff,
1126     0x0000f4a0, 0x000000c0, 0xffffffff,
1127     0x0000f4a4, 0x00680000, 0xffffffff,
1128     0x000004c8, 0x00000001, 0xffffffff,
1129     0x000064ec, 0x00007ffd, 0xffffffff,
1130     0x00000c7c, 0x0000ff00, 0xffffffff,
1131     0x00006dfc, 0x0000007f, 0xffffffff
1132 };
1133 #define TURKS_SYSLS_DISABLE_LENGTH sizeof(turks_sysls_disable) / (3 * sizeof(u32))
1134 
1135 static const u32 turks_sysls_enable[] =
1136 {
1137     0x000055e8, 0x00000001, 0xffffffff,
1138     0x0000d0bc, 0x00000100, 0xffffffff,
1139     0x000015c0, 0x000c1401, 0xffffffff,
1140     0x0000264c, 0x000c0400, 0xffffffff,
1141     0x00002648, 0x000c0400, 0xffffffff,
1142     0x00002650, 0x000c0400, 0xffffffff,
1143     0x000020b8, 0x000c0400, 0xffffffff,
1144     0x000020bc, 0x000c0400, 0xffffffff,
1145     0x000020c0, 0x000c0c80, 0xffffffff,
1146     0x0000f4a0, 0x000000c0, 0xffffffff,
1147     0x0000f4a4, 0x00680fff, 0xffffffff,
1148     0x000004c8, 0x00000000, 0xffffffff,
1149     0x000064ec, 0x00000000, 0xffffffff,
1150     0x00000c7c, 0x00000000, 0xffffffff,
1151     0x00006dfc, 0x00000000, 0xffffffff
1152 };
1153 #define TURKS_SYSLS_ENABLE_LENGTH sizeof(turks_sysls_enable) / (3 * sizeof(u32))
1154 
1155 #endif
1156 
1157 u32 btc_valid_sclk[40] =
1158 {
1159     5000,   10000,  15000,  20000,  25000,  30000,  35000,  40000,  45000,  50000,
1160     55000,  60000,  65000,  70000,  75000,  80000,  85000,  90000,  95000,  100000,
1161     105000, 110000, 11500,  120000, 125000, 130000, 135000, 140000, 145000, 150000,
1162     155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000
1163 };
1164 
1165 static const struct radeon_blacklist_clocks btc_blacklist_clocks[] = {
1166     { 10000, 30000, RADEON_SCLK_UP },
1167     { 15000, 30000, RADEON_SCLK_UP },
1168     { 20000, 30000, RADEON_SCLK_UP },
1169     { 25000, 30000, RADEON_SCLK_UP }
1170 };
1171 
1172 void btc_get_max_clock_from_voltage_dependency_table(struct radeon_clock_voltage_dependency_table *table,
1173                              u32 *max_clock)
1174 {
1175     u32 i, clock = 0;
1176 
1177     if ((table == NULL) || (table->count == 0)) {
1178         *max_clock = clock;
1179         return;
1180     }
1181 
1182     for (i = 0; i < table->count; i++) {
1183         if (clock < table->entries[i].clk)
1184             clock = table->entries[i].clk;
1185     }
1186     *max_clock = clock;
1187 }
1188 
1189 void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
1190                     u32 clock, u16 max_voltage, u16 *voltage)
1191 {
1192     u32 i;
1193 
1194     if ((table == NULL) || (table->count == 0))
1195         return;
1196 
1197     for (i= 0; i < table->count; i++) {
1198         if (clock <= table->entries[i].clk) {
1199             if (*voltage < table->entries[i].v)
1200                 *voltage = (u16)((table->entries[i].v < max_voltage) ?
1201                           table->entries[i].v : max_voltage);
1202             return;
1203         }
1204     }
1205 
1206     *voltage = (*voltage > max_voltage) ? *voltage : max_voltage;
1207 }
1208 
1209 static u32 btc_find_valid_clock(struct radeon_clock_array *clocks,
1210                 u32 max_clock, u32 requested_clock)
1211 {
1212     unsigned int i;
1213 
1214     if ((clocks == NULL) || (clocks->count == 0))
1215         return (requested_clock < max_clock) ? requested_clock : max_clock;
1216 
1217     for (i = 0; i < clocks->count; i++) {
1218         if (clocks->values[i] >= requested_clock)
1219             return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock;
1220     }
1221 
1222     return (clocks->values[clocks->count - 1] < max_clock) ?
1223         clocks->values[clocks->count - 1] : max_clock;
1224 }
1225 
1226 static u32 btc_get_valid_mclk(struct radeon_device *rdev,
1227                   u32 max_mclk, u32 requested_mclk)
1228 {
1229     return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_mclk_values,
1230                     max_mclk, requested_mclk);
1231 }
1232 
1233 static u32 btc_get_valid_sclk(struct radeon_device *rdev,
1234                   u32 max_sclk, u32 requested_sclk)
1235 {
1236     return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_sclk_values,
1237                     max_sclk, requested_sclk);
1238 }
1239 
1240 void btc_skip_blacklist_clocks(struct radeon_device *rdev,
1241                    const u32 max_sclk, const u32 max_mclk,
1242                    u32 *sclk, u32 *mclk)
1243 {
1244     int i, num_blacklist_clocks;
1245 
1246     if ((sclk == NULL) || (mclk == NULL))
1247         return;
1248 
1249     num_blacklist_clocks = ARRAY_SIZE(btc_blacklist_clocks);
1250 
1251     for (i = 0; i < num_blacklist_clocks; i++) {
1252         if ((btc_blacklist_clocks[i].sclk == *sclk) &&
1253             (btc_blacklist_clocks[i].mclk == *mclk))
1254             break;
1255     }
1256 
1257     if (i < num_blacklist_clocks) {
1258         if (btc_blacklist_clocks[i].action == RADEON_SCLK_UP) {
1259             *sclk = btc_get_valid_sclk(rdev, max_sclk, *sclk + 1);
1260 
1261             if (*sclk < max_sclk)
1262                 btc_skip_blacklist_clocks(rdev, max_sclk, max_mclk, sclk, mclk);
1263         }
1264     }
1265 }
1266 
1267 void btc_adjust_clock_combinations(struct radeon_device *rdev,
1268                    const struct radeon_clock_and_voltage_limits *max_limits,
1269                    struct rv7xx_pl *pl)
1270 {
1271 
1272     if ((pl->mclk == 0) || (pl->sclk == 0))
1273         return;
1274 
1275     if (pl->mclk == pl->sclk)
1276         return;
1277 
1278     if (pl->mclk > pl->sclk) {
1279         if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > rdev->pm.dpm.dyn_state.mclk_sclk_ratio)
1280             pl->sclk = btc_get_valid_sclk(rdev,
1281                               max_limits->sclk,
1282                               (pl->mclk +
1283                                (rdev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) /
1284                               rdev->pm.dpm.dyn_state.mclk_sclk_ratio);
1285     } else {
1286         if ((pl->sclk - pl->mclk) > rdev->pm.dpm.dyn_state.sclk_mclk_delta)
1287             pl->mclk = btc_get_valid_mclk(rdev,
1288                               max_limits->mclk,
1289                               pl->sclk -
1290                               rdev->pm.dpm.dyn_state.sclk_mclk_delta);
1291     }
1292 }
1293 
1294 static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)
1295 {
1296     unsigned int i;
1297 
1298     for (i = 0; i < table->count; i++) {
1299         if (voltage <= table->entries[i].value)
1300             return table->entries[i].value;
1301     }
1302 
1303     return table->entries[table->count - 1].value;
1304 }
1305 
1306 void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
1307                    u16 max_vddc, u16 max_vddci,
1308                    u16 *vddc, u16 *vddci)
1309 {
1310     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1311     u16 new_voltage;
1312 
1313     if ((0 == *vddc) || (0 == *vddci))
1314         return;
1315 
1316     if (*vddc > *vddci) {
1317         if ((*vddc - *vddci) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
1318             new_voltage = btc_find_voltage(&eg_pi->vddci_voltage_table,
1319                                (*vddc - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
1320             *vddci = (new_voltage < max_vddci) ? new_voltage : max_vddci;
1321         }
1322     } else {
1323         if ((*vddci - *vddc) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
1324             new_voltage = btc_find_voltage(&eg_pi->vddc_voltage_table,
1325                                (*vddci - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
1326             *vddc = (new_voltage < max_vddc) ? new_voltage : max_vddc;
1327         }
1328     }
1329 }
1330 
1331 static void btc_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
1332                          bool enable)
1333 {
1334     struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1335     u32 tmp, bif;
1336 
1337     tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
1338     if (enable) {
1339         if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
1340             (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
1341             if (!pi->boot_in_gen2) {
1342                 bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
1343                 bif |= CG_CLIENT_REQ(0xd);
1344                 WREG32(CG_BIF_REQ_AND_RSP, bif);
1345 
1346                 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
1347                 tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
1348                 tmp |= LC_GEN2_EN_STRAP;
1349 
1350                 tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT;
1351                 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1352                 udelay(10);
1353                 tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
1354                 WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1355             }
1356         }
1357     } else {
1358         if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
1359             (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
1360             if (!pi->boot_in_gen2) {
1361                 bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
1362                 bif |= CG_CLIENT_REQ(0xd);
1363                 WREG32(CG_BIF_REQ_AND_RSP, bif);
1364 
1365                 tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
1366                 tmp &= ~LC_GEN2_EN_STRAP;
1367             }
1368             WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
1369         }
1370     }
1371 }
1372 
1373 static void btc_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
1374                      bool enable)
1375 {
1376     btc_enable_bif_dynamic_pcie_gen2(rdev, enable);
1377 
1378     if (enable)
1379         WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
1380     else
1381         WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
1382 }
1383 
1384 static int btc_disable_ulv(struct radeon_device *rdev)
1385 {
1386     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1387 
1388     if (eg_pi->ulv.supported) {
1389         if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_DisableULV) != PPSMC_Result_OK)
1390             return -EINVAL;
1391     }
1392     return 0;
1393 }
1394 
1395 static int btc_populate_ulv_state(struct radeon_device *rdev,
1396                   RV770_SMC_STATETABLE *table)
1397 {
1398     int ret = -EINVAL;
1399     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1400     struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1401 
1402     if (ulv_pl->vddc) {
1403         ret = cypress_convert_power_level_to_smc(rdev,
1404                              ulv_pl,
1405                              &table->ULVState.levels[0],
1406                              PPSMC_DISPLAY_WATERMARK_LOW);
1407         if (ret == 0) {
1408             table->ULVState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
1409             table->ULVState.levels[0].ACIndex = 1;
1410 
1411             table->ULVState.levels[1] = table->ULVState.levels[0];
1412             table->ULVState.levels[2] = table->ULVState.levels[0];
1413 
1414             table->ULVState.flags |= PPSMC_SWSTATE_FLAG_DC;
1415 
1416             WREG32(CG_ULV_CONTROL, BTC_CGULVCONTROL_DFLT);
1417             WREG32(CG_ULV_PARAMETER, BTC_CGULVPARAMETER_DFLT);
1418         }
1419     }
1420 
1421     return ret;
1422 }
1423 
1424 static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
1425                        RV770_SMC_STATETABLE *table)
1426 {
1427     int ret = cypress_populate_smc_acpi_state(rdev, table);
1428 
1429     if (ret == 0) {
1430         table->ACPIState.levels[0].ACIndex = 0;
1431         table->ACPIState.levels[1].ACIndex = 0;
1432         table->ACPIState.levels[2].ACIndex = 0;
1433     }
1434 
1435     return ret;
1436 }
1437 
1438 void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
1439                   const u32 *sequence, u32 count)
1440 {
1441     u32 i, length = count * 3;
1442     u32 tmp;
1443 
1444     for (i = 0; i < length; i+=3) {
1445         tmp = RREG32(sequence[i]);
1446         tmp &= ~sequence[i+2];
1447         tmp |= sequence[i+1] & sequence[i+2];
1448         WREG32(sequence[i], tmp);
1449     }
1450 }
1451 
1452 static void btc_cg_clock_gating_default(struct radeon_device *rdev)
1453 {
1454     u32 count;
1455     const u32 *p = NULL;
1456 
1457     if (rdev->family == CHIP_BARTS) {
1458         p = (const u32 *)&barts_cgcg_cgls_default;
1459         count = BARTS_CGCG_CGLS_DEFAULT_LENGTH;
1460     } else if (rdev->family == CHIP_TURKS) {
1461         p = (const u32 *)&turks_cgcg_cgls_default;
1462         count = TURKS_CGCG_CGLS_DEFAULT_LENGTH;
1463     } else if (rdev->family == CHIP_CAICOS) {
1464         p = (const u32 *)&caicos_cgcg_cgls_default;
1465         count = CAICOS_CGCG_CGLS_DEFAULT_LENGTH;
1466     } else
1467         return;
1468 
1469     btc_program_mgcg_hw_sequence(rdev, p, count);
1470 }
1471 
1472 static void btc_cg_clock_gating_enable(struct radeon_device *rdev,
1473                        bool enable)
1474 {
1475     u32 count;
1476     const u32 *p = NULL;
1477 
1478     if (enable) {
1479         if (rdev->family == CHIP_BARTS) {
1480             p = (const u32 *)&barts_cgcg_cgls_enable;
1481             count = BARTS_CGCG_CGLS_ENABLE_LENGTH;
1482         } else if (rdev->family == CHIP_TURKS) {
1483             p = (const u32 *)&turks_cgcg_cgls_enable;
1484             count = TURKS_CGCG_CGLS_ENABLE_LENGTH;
1485         } else if (rdev->family == CHIP_CAICOS) {
1486             p = (const u32 *)&caicos_cgcg_cgls_enable;
1487             count = CAICOS_CGCG_CGLS_ENABLE_LENGTH;
1488         } else
1489             return;
1490     } else {
1491         if (rdev->family == CHIP_BARTS) {
1492             p = (const u32 *)&barts_cgcg_cgls_disable;
1493             count = BARTS_CGCG_CGLS_DISABLE_LENGTH;
1494         } else if (rdev->family == CHIP_TURKS) {
1495             p = (const u32 *)&turks_cgcg_cgls_disable;
1496             count = TURKS_CGCG_CGLS_DISABLE_LENGTH;
1497         } else if (rdev->family == CHIP_CAICOS) {
1498             p = (const u32 *)&caicos_cgcg_cgls_disable;
1499             count = CAICOS_CGCG_CGLS_DISABLE_LENGTH;
1500         } else
1501             return;
1502     }
1503 
1504     btc_program_mgcg_hw_sequence(rdev, p, count);
1505 }
1506 
1507 static void btc_mg_clock_gating_default(struct radeon_device *rdev)
1508 {
1509     u32 count;
1510     const u32 *p = NULL;
1511 
1512     if (rdev->family == CHIP_BARTS) {
1513         p = (const u32 *)&barts_mgcg_default;
1514         count = BARTS_MGCG_DEFAULT_LENGTH;
1515     } else if (rdev->family == CHIP_TURKS) {
1516         p = (const u32 *)&turks_mgcg_default;
1517         count = TURKS_MGCG_DEFAULT_LENGTH;
1518     } else if (rdev->family == CHIP_CAICOS) {
1519         p = (const u32 *)&caicos_mgcg_default;
1520         count = CAICOS_MGCG_DEFAULT_LENGTH;
1521     } else
1522         return;
1523 
1524     btc_program_mgcg_hw_sequence(rdev, p, count);
1525 }
1526 
1527 static void btc_mg_clock_gating_enable(struct radeon_device *rdev,
1528                        bool enable)
1529 {
1530     u32 count;
1531     const u32 *p = NULL;
1532 
1533     if (enable) {
1534         if (rdev->family == CHIP_BARTS) {
1535             p = (const u32 *)&barts_mgcg_enable;
1536             count = BARTS_MGCG_ENABLE_LENGTH;
1537         } else if (rdev->family == CHIP_TURKS) {
1538             p = (const u32 *)&turks_mgcg_enable;
1539             count = TURKS_MGCG_ENABLE_LENGTH;
1540         } else if (rdev->family == CHIP_CAICOS) {
1541             p = (const u32 *)&caicos_mgcg_enable;
1542             count = CAICOS_MGCG_ENABLE_LENGTH;
1543         } else
1544             return;
1545     } else {
1546         if (rdev->family == CHIP_BARTS) {
1547             p = (const u32 *)&barts_mgcg_disable[0];
1548             count = BARTS_MGCG_DISABLE_LENGTH;
1549         } else if (rdev->family == CHIP_TURKS) {
1550             p = (const u32 *)&turks_mgcg_disable[0];
1551             count = TURKS_MGCG_DISABLE_LENGTH;
1552         } else if (rdev->family == CHIP_CAICOS) {
1553             p = (const u32 *)&caicos_mgcg_disable[0];
1554             count = CAICOS_MGCG_DISABLE_LENGTH;
1555         } else
1556             return;
1557     }
1558 
1559     btc_program_mgcg_hw_sequence(rdev, p, count);
1560 }
1561 
1562 static void btc_ls_clock_gating_default(struct radeon_device *rdev)
1563 {
1564     u32 count;
1565     const u32 *p = NULL;
1566 
1567     if (rdev->family == CHIP_BARTS) {
1568         p = (const u32 *)&barts_sysls_default;
1569         count = BARTS_SYSLS_DEFAULT_LENGTH;
1570     } else if (rdev->family == CHIP_TURKS) {
1571         p = (const u32 *)&turks_sysls_default;
1572         count = TURKS_SYSLS_DEFAULT_LENGTH;
1573     } else if (rdev->family == CHIP_CAICOS) {
1574         p = (const u32 *)&caicos_sysls_default;
1575         count = CAICOS_SYSLS_DEFAULT_LENGTH;
1576     } else
1577         return;
1578 
1579     btc_program_mgcg_hw_sequence(rdev, p, count);
1580 }
1581 
1582 static void btc_ls_clock_gating_enable(struct radeon_device *rdev,
1583                        bool enable)
1584 {
1585     u32 count;
1586     const u32 *p = NULL;
1587 
1588     if (enable) {
1589         if (rdev->family == CHIP_BARTS) {
1590             p = (const u32 *)&barts_sysls_enable;
1591             count = BARTS_SYSLS_ENABLE_LENGTH;
1592         } else if (rdev->family == CHIP_TURKS) {
1593             p = (const u32 *)&turks_sysls_enable;
1594             count = TURKS_SYSLS_ENABLE_LENGTH;
1595         } else if (rdev->family == CHIP_CAICOS) {
1596             p = (const u32 *)&caicos_sysls_enable;
1597             count = CAICOS_SYSLS_ENABLE_LENGTH;
1598         } else
1599             return;
1600     } else {
1601         if (rdev->family == CHIP_BARTS) {
1602             p = (const u32 *)&barts_sysls_disable;
1603             count = BARTS_SYSLS_DISABLE_LENGTH;
1604         } else if (rdev->family == CHIP_TURKS) {
1605             p = (const u32 *)&turks_sysls_disable;
1606             count = TURKS_SYSLS_DISABLE_LENGTH;
1607         } else if (rdev->family == CHIP_CAICOS) {
1608             p = (const u32 *)&caicos_sysls_disable;
1609             count = CAICOS_SYSLS_DISABLE_LENGTH;
1610         } else
1611             return;
1612     }
1613 
1614     btc_program_mgcg_hw_sequence(rdev, p, count);
1615 }
1616 
1617 bool btc_dpm_enabled(struct radeon_device *rdev)
1618 {
1619     if (rv770_is_smc_running(rdev))
1620         return true;
1621     else
1622         return false;
1623 }
1624 
1625 static int btc_init_smc_table(struct radeon_device *rdev,
1626                   struct radeon_ps *radeon_boot_state)
1627 {
1628     struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1629     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1630     RV770_SMC_STATETABLE *table = &pi->smc_statetable;
1631     int ret;
1632 
1633     memset(table, 0, sizeof(RV770_SMC_STATETABLE));
1634 
1635     cypress_populate_smc_voltage_tables(rdev, table);
1636 
1637     switch (rdev->pm.int_thermal_type) {
1638     case THERMAL_TYPE_EVERGREEN:
1639     case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
1640         table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
1641         break;
1642     case THERMAL_TYPE_NONE:
1643         table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
1644         break;
1645     default:
1646         table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
1647         break;
1648     }
1649 
1650     if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
1651         table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
1652 
1653     if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT)
1654         table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
1655 
1656     if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
1657         table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
1658 
1659     if (pi->mem_gddr5)
1660         table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
1661 
1662     ret = cypress_populate_smc_initial_state(rdev, radeon_boot_state, table);
1663     if (ret)
1664         return ret;
1665 
1666     if (eg_pi->sclk_deep_sleep)
1667         WREG32_P(SCLK_PSKIP_CNTL, PSKIP_ON_ALLOW_STOP_HI(32),
1668              ~PSKIP_ON_ALLOW_STOP_HI_MASK);
1669 
1670     ret = btc_populate_smc_acpi_state(rdev, table);
1671     if (ret)
1672         return ret;
1673 
1674     if (eg_pi->ulv.supported) {
1675         ret = btc_populate_ulv_state(rdev, table);
1676         if (ret)
1677             eg_pi->ulv.supported = false;
1678     }
1679 
1680     table->driverState = table->initialState;
1681 
1682     return rv770_copy_bytes_to_smc(rdev,
1683                        pi->state_table_start,
1684                        (u8 *)table,
1685                        sizeof(RV770_SMC_STATETABLE),
1686                        pi->sram_end);
1687 }
1688 
1689 static void btc_set_at_for_uvd(struct radeon_device *rdev,
1690                    struct radeon_ps *radeon_new_state)
1691 {
1692     struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1693     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1694     int idx = 0;
1695 
1696     if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2))
1697         idx = 1;
1698 
1699     if ((idx == 1) && !eg_pi->smu_uvd_hs) {
1700         pi->rlp = 10;
1701         pi->rmp = 100;
1702         pi->lhp = 100;
1703         pi->lmp = 10;
1704     } else {
1705         pi->rlp = eg_pi->ats[idx].rlp;
1706         pi->rmp = eg_pi->ats[idx].rmp;
1707         pi->lhp = eg_pi->ats[idx].lhp;
1708         pi->lmp = eg_pi->ats[idx].lmp;
1709     }
1710 
1711 }
1712 
1713 void btc_notify_uvd_to_smc(struct radeon_device *rdev,
1714                struct radeon_ps *radeon_new_state)
1715 {
1716     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1717 
1718     if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
1719         rv770_write_smc_soft_register(rdev,
1720                           RV770_SMC_SOFT_REGISTER_uvd_enabled, 1);
1721         eg_pi->uvd_enabled = true;
1722     } else {
1723         rv770_write_smc_soft_register(rdev,
1724                           RV770_SMC_SOFT_REGISTER_uvd_enabled, 0);
1725         eg_pi->uvd_enabled = false;
1726     }
1727 }
1728 
1729 int btc_reset_to_default(struct radeon_device *rdev)
1730 {
1731     if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != PPSMC_Result_OK)
1732         return -EINVAL;
1733 
1734     return 0;
1735 }
1736 
1737 static void btc_stop_smc(struct radeon_device *rdev)
1738 {
1739     int i;
1740 
1741     for (i = 0; i < rdev->usec_timeout; i++) {
1742         if (((RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK) >> LB_SYNC_RESET_SEL_SHIFT) != 1)
1743             break;
1744         udelay(1);
1745     }
1746     udelay(100);
1747 
1748     r7xx_stop_smc(rdev);
1749 }
1750 
1751 void btc_read_arb_registers(struct radeon_device *rdev)
1752 {
1753     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1754     struct evergreen_arb_registers *arb_registers =
1755         &eg_pi->bootup_arb_registers;
1756 
1757     arb_registers->mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING);
1758     arb_registers->mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
1759     arb_registers->mc_arb_rfsh_rate = RREG32(MC_ARB_RFSH_RATE);
1760     arb_registers->mc_arb_burst_time = RREG32(MC_ARB_BURST_TIME);
1761 }
1762 
1763 
1764 static void btc_set_arb0_registers(struct radeon_device *rdev,
1765                    struct evergreen_arb_registers *arb_registers)
1766 {
1767     u32 val;
1768 
1769     WREG32(MC_ARB_DRAM_TIMING,  arb_registers->mc_arb_dram_timing);
1770     WREG32(MC_ARB_DRAM_TIMING2, arb_registers->mc_arb_dram_timing2);
1771 
1772     val = (arb_registers->mc_arb_rfsh_rate & POWERMODE0_MASK) >>
1773         POWERMODE0_SHIFT;
1774     WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
1775 
1776     val = (arb_registers->mc_arb_burst_time & STATE0_MASK) >>
1777         STATE0_SHIFT;
1778     WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
1779 }
1780 
1781 static void btc_set_boot_state_timing(struct radeon_device *rdev)
1782 {
1783     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1784 
1785     if (eg_pi->ulv.supported)
1786         btc_set_arb0_registers(rdev, &eg_pi->bootup_arb_registers);
1787 }
1788 
1789 static bool btc_is_state_ulv_compatible(struct radeon_device *rdev,
1790                     struct radeon_ps *radeon_state)
1791 {
1792     struct rv7xx_ps *state = rv770_get_ps(radeon_state);
1793     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1794     struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1795 
1796     if (state->low.mclk != ulv_pl->mclk)
1797         return false;
1798 
1799     if (state->low.vddci != ulv_pl->vddci)
1800         return false;
1801 
1802     /* XXX check minclocks, etc. */
1803 
1804     return true;
1805 }
1806 
1807 
1808 static int btc_set_ulv_dram_timing(struct radeon_device *rdev)
1809 {
1810     u32 val;
1811     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1812     struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
1813 
1814     radeon_atom_set_engine_dram_timings(rdev,
1815                         ulv_pl->sclk,
1816                         ulv_pl->mclk);
1817 
1818     val = rv770_calculate_memory_refresh_rate(rdev, ulv_pl->sclk);
1819     WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
1820 
1821     val = cypress_calculate_burst_time(rdev, ulv_pl->sclk, ulv_pl->mclk);
1822     WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
1823 
1824     return 0;
1825 }
1826 
1827 static int btc_enable_ulv(struct radeon_device *rdev)
1828 {
1829     if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableULV) != PPSMC_Result_OK)
1830         return -EINVAL;
1831 
1832     return 0;
1833 }
1834 
1835 static int btc_set_power_state_conditionally_enable_ulv(struct radeon_device *rdev,
1836                             struct radeon_ps *radeon_new_state)
1837 {
1838     int ret = 0;
1839     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
1840 
1841     if (eg_pi->ulv.supported) {
1842         if (btc_is_state_ulv_compatible(rdev, radeon_new_state)) {
1843             // Set ARB[0] to reflect the DRAM timing needed for ULV.
1844             ret = btc_set_ulv_dram_timing(rdev);
1845             if (ret == 0)
1846                 ret = btc_enable_ulv(rdev);
1847         }
1848     }
1849 
1850     return ret;
1851 }
1852 
1853 static bool btc_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
1854 {
1855     bool result = true;
1856 
1857     switch (in_reg) {
1858     case MC_SEQ_RAS_TIMING >> 2:
1859         *out_reg = MC_SEQ_RAS_TIMING_LP >> 2;
1860         break;
1861     case MC_SEQ_CAS_TIMING >> 2:
1862         *out_reg = MC_SEQ_CAS_TIMING_LP >> 2;
1863         break;
1864     case MC_SEQ_MISC_TIMING >> 2:
1865         *out_reg = MC_SEQ_MISC_TIMING_LP >> 2;
1866         break;
1867     case MC_SEQ_MISC_TIMING2 >> 2:
1868         *out_reg = MC_SEQ_MISC_TIMING2_LP >> 2;
1869         break;
1870     case MC_SEQ_RD_CTL_D0 >> 2:
1871         *out_reg = MC_SEQ_RD_CTL_D0_LP >> 2;
1872         break;
1873     case MC_SEQ_RD_CTL_D1 >> 2:
1874         *out_reg = MC_SEQ_RD_CTL_D1_LP >> 2;
1875         break;
1876     case MC_SEQ_WR_CTL_D0 >> 2:
1877         *out_reg = MC_SEQ_WR_CTL_D0_LP >> 2;
1878         break;
1879     case MC_SEQ_WR_CTL_D1 >> 2:
1880         *out_reg = MC_SEQ_WR_CTL_D1_LP >> 2;
1881         break;
1882     case MC_PMG_CMD_EMRS >> 2:
1883         *out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
1884         break;
1885     case MC_PMG_CMD_MRS >> 2:
1886         *out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2;
1887         break;
1888     case MC_PMG_CMD_MRS1 >> 2:
1889         *out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
1890         break;
1891     default:
1892         result = false;
1893         break;
1894     }
1895 
1896     return result;
1897 }
1898 
1899 static void btc_set_valid_flag(struct evergreen_mc_reg_table *table)
1900 {
1901     u8 i, j;
1902 
1903     for (i = 0; i < table->last; i++) {
1904         for (j = 1; j < table->num_entries; j++) {
1905             if (table->mc_reg_table_entry[j-1].mc_data[i] !=
1906                 table->mc_reg_table_entry[j].mc_data[i]) {
1907                 table->valid_flag |= (1 << i);
1908                 break;
1909             }
1910         }
1911     }
1912 }
1913 
1914 static int btc_set_mc_special_registers(struct radeon_device *rdev,
1915                     struct evergreen_mc_reg_table *table)
1916 {
1917     struct rv7xx_power_info *pi = rv770_get_pi(rdev);
1918     u8 i, j, k;
1919     u32 tmp;
1920 
1921     for (i = 0, j = table->last; i < table->last; i++) {
1922         switch (table->mc_reg_address[i].s1) {
1923         case MC_SEQ_MISC1 >> 2:
1924             tmp = RREG32(MC_PMG_CMD_EMRS);
1925             table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2;
1926             table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
1927             for (k = 0; k < table->num_entries; k++) {
1928                 table->mc_reg_table_entry[k].mc_data[j] =
1929                     ((tmp & 0xffff0000)) |
1930                     ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
1931             }
1932             j++;
1933 
1934             if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1935                 return -EINVAL;
1936 
1937             tmp = RREG32(MC_PMG_CMD_MRS);
1938             table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2;
1939             table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
1940             for (k = 0; k < table->num_entries; k++) {
1941                 table->mc_reg_table_entry[k].mc_data[j] =
1942                     (tmp & 0xffff0000) |
1943                     (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
1944                 if (!pi->mem_gddr5)
1945                     table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
1946             }
1947             j++;
1948 
1949             if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1950                 return -EINVAL;
1951             break;
1952         case MC_SEQ_RESERVE_M >> 2:
1953             tmp = RREG32(MC_PMG_CMD_MRS1);
1954             table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
1955             table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
1956             for (k = 0; k < table->num_entries; k++) {
1957                 table->mc_reg_table_entry[k].mc_data[j] =
1958                     (tmp & 0xffff0000) |
1959                     (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
1960             }
1961             j++;
1962 
1963             if (j >= SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1964                 return -EINVAL;
1965             break;
1966         default:
1967             break;
1968         }
1969     }
1970 
1971     table->last = j;
1972 
1973     return 0;
1974 }
1975 
1976 static void btc_set_s0_mc_reg_index(struct evergreen_mc_reg_table *table)
1977 {
1978     u32 i;
1979     u16 address;
1980 
1981     for (i = 0; i < table->last; i++) {
1982         table->mc_reg_address[i].s0 =
1983             btc_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
1984             address : table->mc_reg_address[i].s1;
1985     }
1986 }
1987 
1988 static int btc_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
1989                        struct evergreen_mc_reg_table *eg_table)
1990 {
1991     u8 i, j;
1992 
1993     if (table->last > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
1994         return -EINVAL;
1995 
1996     if (table->num_entries > MAX_AC_TIMING_ENTRIES)
1997         return -EINVAL;
1998 
1999     for (i = 0; i < table->last; i++)
2000         eg_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
2001     eg_table->last = table->last;
2002 
2003     for (i = 0; i < table->num_entries; i++) {
2004         eg_table->mc_reg_table_entry[i].mclk_max =
2005             table->mc_reg_table_entry[i].mclk_max;
2006         for(j = 0; j < table->last; j++)
2007             eg_table->mc_reg_table_entry[i].mc_data[j] =
2008                 table->mc_reg_table_entry[i].mc_data[j];
2009     }
2010     eg_table->num_entries = table->num_entries;
2011 
2012     return 0;
2013 }
2014 
2015 static int btc_initialize_mc_reg_table(struct radeon_device *rdev)
2016 {
2017     int ret;
2018     struct atom_mc_reg_table *table;
2019     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2020     struct evergreen_mc_reg_table *eg_table = &eg_pi->mc_reg_table;
2021     u8 module_index = rv770_get_memory_module_index(rdev);
2022 
2023     table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
2024     if (!table)
2025         return -ENOMEM;
2026 
2027     /* Program additional LP registers that are no longer programmed by VBIOS */
2028     WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
2029     WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
2030     WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
2031     WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
2032     WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
2033     WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
2034     WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
2035     WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
2036     WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
2037     WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
2038     WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
2039 
2040     ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
2041 
2042     if (ret)
2043         goto init_mc_done;
2044 
2045     ret = btc_copy_vbios_mc_reg_table(table, eg_table);
2046 
2047     if (ret)
2048         goto init_mc_done;
2049 
2050     btc_set_s0_mc_reg_index(eg_table);
2051     ret = btc_set_mc_special_registers(rdev, eg_table);
2052 
2053     if (ret)
2054         goto init_mc_done;
2055 
2056     btc_set_valid_flag(eg_table);
2057 
2058 init_mc_done:
2059     kfree(table);
2060 
2061     return ret;
2062 }
2063 
2064 static void btc_init_stutter_mode(struct radeon_device *rdev)
2065 {
2066     struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2067     u32 tmp;
2068 
2069     if (pi->mclk_stutter_mode_threshold) {
2070         if (pi->mem_gddr5) {
2071             tmp = RREG32(MC_PMG_AUTO_CFG);
2072             if ((0x200 & tmp) == 0) {
2073                 tmp = (tmp & 0xfffffc0b) | 0x204;
2074                 WREG32(MC_PMG_AUTO_CFG, tmp);
2075             }
2076         }
2077     }
2078 }
2079 
2080 bool btc_dpm_vblank_too_short(struct radeon_device *rdev)
2081 {
2082     struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2083     u32 vblank_time = r600_dpm_get_vblank_time(rdev);
2084     u32 switch_limit = pi->mem_gddr5 ? 450 : 100;
2085 
2086     if (vblank_time < switch_limit)
2087         return true;
2088     else
2089         return false;
2090 
2091 }
2092 
2093 static void btc_apply_state_adjust_rules(struct radeon_device *rdev,
2094                      struct radeon_ps *rps)
2095 {
2096     struct rv7xx_ps *ps = rv770_get_ps(rps);
2097     struct radeon_clock_and_voltage_limits *max_limits;
2098     bool disable_mclk_switching;
2099     u32 mclk, sclk;
2100     u16 vddc, vddci;
2101 
2102     if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
2103         btc_dpm_vblank_too_short(rdev))
2104         disable_mclk_switching = true;
2105     else
2106         disable_mclk_switching = false;
2107 
2108     if (rdev->pm.dpm.ac_power)
2109         max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2110     else
2111         max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
2112 
2113     if (rdev->pm.dpm.ac_power == false) {
2114         if (ps->high.mclk > max_limits->mclk)
2115             ps->high.mclk = max_limits->mclk;
2116         if (ps->high.sclk > max_limits->sclk)
2117             ps->high.sclk = max_limits->sclk;
2118         if (ps->high.vddc > max_limits->vddc)
2119             ps->high.vddc = max_limits->vddc;
2120         if (ps->high.vddci > max_limits->vddci)
2121             ps->high.vddci = max_limits->vddci;
2122 
2123         if (ps->medium.mclk > max_limits->mclk)
2124             ps->medium.mclk = max_limits->mclk;
2125         if (ps->medium.sclk > max_limits->sclk)
2126             ps->medium.sclk = max_limits->sclk;
2127         if (ps->medium.vddc > max_limits->vddc)
2128             ps->medium.vddc = max_limits->vddc;
2129         if (ps->medium.vddci > max_limits->vddci)
2130             ps->medium.vddci = max_limits->vddci;
2131 
2132         if (ps->low.mclk > max_limits->mclk)
2133             ps->low.mclk = max_limits->mclk;
2134         if (ps->low.sclk > max_limits->sclk)
2135             ps->low.sclk = max_limits->sclk;
2136         if (ps->low.vddc > max_limits->vddc)
2137             ps->low.vddc = max_limits->vddc;
2138         if (ps->low.vddci > max_limits->vddci)
2139             ps->low.vddci = max_limits->vddci;
2140     }
2141 
2142     /* XXX validate the min clocks required for display */
2143 
2144     if (disable_mclk_switching) {
2145         sclk = ps->low.sclk;
2146         mclk = ps->high.mclk;
2147         vddc = ps->low.vddc;
2148         vddci = ps->high.vddci;
2149     } else {
2150         sclk = ps->low.sclk;
2151         mclk = ps->low.mclk;
2152         vddc = ps->low.vddc;
2153         vddci = ps->low.vddci;
2154     }
2155 
2156     /* adjusted low state */
2157     ps->low.sclk = sclk;
2158     ps->low.mclk = mclk;
2159     ps->low.vddc = vddc;
2160     ps->low.vddci = vddci;
2161 
2162     btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2163                   &ps->low.sclk, &ps->low.mclk);
2164 
2165     /* adjusted medium, high states */
2166     if (ps->medium.sclk < ps->low.sclk)
2167         ps->medium.sclk = ps->low.sclk;
2168     if (ps->medium.vddc < ps->low.vddc)
2169         ps->medium.vddc = ps->low.vddc;
2170     if (ps->high.sclk < ps->medium.sclk)
2171         ps->high.sclk = ps->medium.sclk;
2172     if (ps->high.vddc < ps->medium.vddc)
2173         ps->high.vddc = ps->medium.vddc;
2174 
2175     if (disable_mclk_switching) {
2176         mclk = ps->low.mclk;
2177         if (mclk < ps->medium.mclk)
2178             mclk = ps->medium.mclk;
2179         if (mclk < ps->high.mclk)
2180             mclk = ps->high.mclk;
2181         ps->low.mclk = mclk;
2182         ps->low.vddci = vddci;
2183         ps->medium.mclk = mclk;
2184         ps->medium.vddci = vddci;
2185         ps->high.mclk = mclk;
2186         ps->high.vddci = vddci;
2187     } else {
2188         if (ps->medium.mclk < ps->low.mclk)
2189             ps->medium.mclk = ps->low.mclk;
2190         if (ps->medium.vddci < ps->low.vddci)
2191             ps->medium.vddci = ps->low.vddci;
2192         if (ps->high.mclk < ps->medium.mclk)
2193             ps->high.mclk = ps->medium.mclk;
2194         if (ps->high.vddci < ps->medium.vddci)
2195             ps->high.vddci = ps->medium.vddci;
2196     }
2197 
2198     btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2199                   &ps->medium.sclk, &ps->medium.mclk);
2200     btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
2201                   &ps->high.sclk, &ps->high.mclk);
2202 
2203     btc_adjust_clock_combinations(rdev, max_limits, &ps->low);
2204     btc_adjust_clock_combinations(rdev, max_limits, &ps->medium);
2205     btc_adjust_clock_combinations(rdev, max_limits, &ps->high);
2206 
2207     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2208                        ps->low.sclk, max_limits->vddc, &ps->low.vddc);
2209     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2210                        ps->low.mclk, max_limits->vddci, &ps->low.vddci);
2211     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2212                        ps->low.mclk, max_limits->vddc, &ps->low.vddc);
2213     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2214                        rdev->clock.current_dispclk, max_limits->vddc, &ps->low.vddc);
2215 
2216     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2217                        ps->medium.sclk, max_limits->vddc, &ps->medium.vddc);
2218     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2219                        ps->medium.mclk, max_limits->vddci, &ps->medium.vddci);
2220     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2221                        ps->medium.mclk, max_limits->vddc, &ps->medium.vddc);
2222     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2223                        rdev->clock.current_dispclk, max_limits->vddc, &ps->medium.vddc);
2224 
2225     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
2226                        ps->high.sclk, max_limits->vddc, &ps->high.vddc);
2227     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
2228                        ps->high.mclk, max_limits->vddci, &ps->high.vddci);
2229     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
2230                        ps->high.mclk, max_limits->vddc, &ps->high.vddc);
2231     btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
2232                        rdev->clock.current_dispclk, max_limits->vddc, &ps->high.vddc);
2233 
2234     btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2235                       &ps->low.vddc, &ps->low.vddci);
2236     btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2237                       &ps->medium.vddc, &ps->medium.vddci);
2238     btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
2239                       &ps->high.vddc, &ps->high.vddci);
2240 
2241     if ((ps->high.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
2242         (ps->medium.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
2243         (ps->low.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc))
2244         ps->dc_compatible = true;
2245     else
2246         ps->dc_compatible = false;
2247 
2248     if (ps->low.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2249         ps->low.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2250     if (ps->medium.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2251         ps->medium.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2252     if (ps->high.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
2253         ps->high.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
2254 }
2255 
2256 static void btc_update_current_ps(struct radeon_device *rdev,
2257                   struct radeon_ps *rps)
2258 {
2259     struct rv7xx_ps *new_ps = rv770_get_ps(rps);
2260     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2261 
2262     eg_pi->current_rps = *rps;
2263     eg_pi->current_ps = *new_ps;
2264     eg_pi->current_rps.ps_priv = &eg_pi->current_ps;
2265 }
2266 
2267 static void btc_update_requested_ps(struct radeon_device *rdev,
2268                     struct radeon_ps *rps)
2269 {
2270     struct rv7xx_ps *new_ps = rv770_get_ps(rps);
2271     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2272 
2273     eg_pi->requested_rps = *rps;
2274     eg_pi->requested_ps = *new_ps;
2275     eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps;
2276 }
2277 
2278 #if 0
2279 void btc_dpm_reset_asic(struct radeon_device *rdev)
2280 {
2281     rv770_restrict_performance_levels_before_switch(rdev);
2282     btc_disable_ulv(rdev);
2283     btc_set_boot_state_timing(rdev);
2284     rv770_set_boot_state(rdev);
2285 }
2286 #endif
2287 
2288 int btc_dpm_pre_set_power_state(struct radeon_device *rdev)
2289 {
2290     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2291     struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
2292     struct radeon_ps *new_ps = &requested_ps;
2293 
2294     btc_update_requested_ps(rdev, new_ps);
2295 
2296     btc_apply_state_adjust_rules(rdev, &eg_pi->requested_rps);
2297 
2298     return 0;
2299 }
2300 
2301 int btc_dpm_set_power_state(struct radeon_device *rdev)
2302 {
2303     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2304     struct radeon_ps *new_ps = &eg_pi->requested_rps;
2305     struct radeon_ps *old_ps = &eg_pi->current_rps;
2306     int ret;
2307 
2308     ret = btc_disable_ulv(rdev);
2309     btc_set_boot_state_timing(rdev);
2310     ret = rv770_restrict_performance_levels_before_switch(rdev);
2311     if (ret) {
2312         DRM_ERROR("rv770_restrict_performance_levels_before_switch failed\n");
2313         return ret;
2314     }
2315     if (eg_pi->pcie_performance_request)
2316         cypress_notify_link_speed_change_before_state_change(rdev, new_ps, old_ps);
2317 
2318     rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
2319     ret = rv770_halt_smc(rdev);
2320     if (ret) {
2321         DRM_ERROR("rv770_halt_smc failed\n");
2322         return ret;
2323     }
2324     btc_set_at_for_uvd(rdev, new_ps);
2325     if (eg_pi->smu_uvd_hs)
2326         btc_notify_uvd_to_smc(rdev, new_ps);
2327     ret = cypress_upload_sw_state(rdev, new_ps);
2328     if (ret) {
2329         DRM_ERROR("cypress_upload_sw_state failed\n");
2330         return ret;
2331     }
2332     if (eg_pi->dynamic_ac_timing) {
2333         ret = cypress_upload_mc_reg_table(rdev, new_ps);
2334         if (ret) {
2335             DRM_ERROR("cypress_upload_mc_reg_table failed\n");
2336             return ret;
2337         }
2338     }
2339 
2340     cypress_program_memory_timing_parameters(rdev, new_ps);
2341 
2342     ret = rv770_resume_smc(rdev);
2343     if (ret) {
2344         DRM_ERROR("rv770_resume_smc failed\n");
2345         return ret;
2346     }
2347     ret = rv770_set_sw_state(rdev);
2348     if (ret) {
2349         DRM_ERROR("rv770_set_sw_state failed\n");
2350         return ret;
2351     }
2352     rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
2353 
2354     if (eg_pi->pcie_performance_request)
2355         cypress_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
2356 
2357     ret = btc_set_power_state_conditionally_enable_ulv(rdev, new_ps);
2358     if (ret) {
2359         DRM_ERROR("btc_set_power_state_conditionally_enable_ulv failed\n");
2360         return ret;
2361     }
2362 
2363     return 0;
2364 }
2365 
2366 void btc_dpm_post_set_power_state(struct radeon_device *rdev)
2367 {
2368     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2369     struct radeon_ps *new_ps = &eg_pi->requested_rps;
2370 
2371     btc_update_current_ps(rdev, new_ps);
2372 }
2373 
2374 int btc_dpm_enable(struct radeon_device *rdev)
2375 {
2376     struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2377     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2378     struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
2379     int ret;
2380 
2381     if (pi->gfx_clock_gating)
2382         btc_cg_clock_gating_default(rdev);
2383 
2384     if (btc_dpm_enabled(rdev))
2385         return -EINVAL;
2386 
2387     if (pi->mg_clock_gating)
2388         btc_mg_clock_gating_default(rdev);
2389 
2390     if (eg_pi->ls_clock_gating)
2391         btc_ls_clock_gating_default(rdev);
2392 
2393     if (pi->voltage_control) {
2394         rv770_enable_voltage_control(rdev, true);
2395         ret = cypress_construct_voltage_tables(rdev);
2396         if (ret) {
2397             DRM_ERROR("cypress_construct_voltage_tables failed\n");
2398             return ret;
2399         }
2400     }
2401 
2402     if (pi->mvdd_control) {
2403         ret = cypress_get_mvdd_configuration(rdev);
2404         if (ret) {
2405             DRM_ERROR("cypress_get_mvdd_configuration failed\n");
2406             return ret;
2407         }
2408     }
2409 
2410     if (eg_pi->dynamic_ac_timing) {
2411         ret = btc_initialize_mc_reg_table(rdev);
2412         if (ret)
2413             eg_pi->dynamic_ac_timing = false;
2414     }
2415 
2416     if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
2417         rv770_enable_backbias(rdev, true);
2418 
2419     if (pi->dynamic_ss)
2420         cypress_enable_spread_spectrum(rdev, true);
2421 
2422     if (pi->thermal_protection)
2423         rv770_enable_thermal_protection(rdev, true);
2424 
2425     rv770_setup_bsp(rdev);
2426     rv770_program_git(rdev);
2427     rv770_program_tp(rdev);
2428     rv770_program_tpp(rdev);
2429     rv770_program_sstp(rdev);
2430     rv770_program_engine_speed_parameters(rdev);
2431     cypress_enable_display_gap(rdev);
2432     rv770_program_vc(rdev);
2433 
2434     if (pi->dynamic_pcie_gen2)
2435         btc_enable_dynamic_pcie_gen2(rdev, true);
2436 
2437     ret = rv770_upload_firmware(rdev);
2438     if (ret) {
2439         DRM_ERROR("rv770_upload_firmware failed\n");
2440         return ret;
2441     }
2442     ret = cypress_get_table_locations(rdev);
2443     if (ret) {
2444         DRM_ERROR("cypress_get_table_locations failed\n");
2445         return ret;
2446     }
2447     ret = btc_init_smc_table(rdev, boot_ps);
2448     if (ret)
2449         return ret;
2450 
2451     if (eg_pi->dynamic_ac_timing) {
2452         ret = cypress_populate_mc_reg_table(rdev, boot_ps);
2453         if (ret) {
2454             DRM_ERROR("cypress_populate_mc_reg_table failed\n");
2455             return ret;
2456         }
2457     }
2458 
2459     cypress_program_response_times(rdev);
2460     r7xx_start_smc(rdev);
2461     ret = cypress_notify_smc_display_change(rdev, false);
2462     if (ret) {
2463         DRM_ERROR("cypress_notify_smc_display_change failed\n");
2464         return ret;
2465     }
2466     cypress_enable_sclk_control(rdev, true);
2467 
2468     if (eg_pi->memory_transition)
2469         cypress_enable_mclk_control(rdev, true);
2470 
2471     cypress_start_dpm(rdev);
2472 
2473     if (pi->gfx_clock_gating)
2474         btc_cg_clock_gating_enable(rdev, true);
2475 
2476     if (pi->mg_clock_gating)
2477         btc_mg_clock_gating_enable(rdev, true);
2478 
2479     if (eg_pi->ls_clock_gating)
2480         btc_ls_clock_gating_enable(rdev, true);
2481 
2482     rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
2483 
2484     btc_init_stutter_mode(rdev);
2485 
2486     btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
2487 
2488     return 0;
2489 };
2490 
2491 void btc_dpm_disable(struct radeon_device *rdev)
2492 {
2493     struct rv7xx_power_info *pi = rv770_get_pi(rdev);
2494     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2495 
2496     if (!btc_dpm_enabled(rdev))
2497         return;
2498 
2499     rv770_clear_vc(rdev);
2500 
2501     if (pi->thermal_protection)
2502         rv770_enable_thermal_protection(rdev, false);
2503 
2504     if (pi->dynamic_pcie_gen2)
2505         btc_enable_dynamic_pcie_gen2(rdev, false);
2506 
2507     if (rdev->irq.installed &&
2508         r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
2509         rdev->irq.dpm_thermal = false;
2510         radeon_irq_set(rdev);
2511     }
2512 
2513     if (pi->gfx_clock_gating)
2514         btc_cg_clock_gating_enable(rdev, false);
2515 
2516     if (pi->mg_clock_gating)
2517         btc_mg_clock_gating_enable(rdev, false);
2518 
2519     if (eg_pi->ls_clock_gating)
2520         btc_ls_clock_gating_enable(rdev, false);
2521 
2522     rv770_stop_dpm(rdev);
2523     btc_reset_to_default(rdev);
2524     btc_stop_smc(rdev);
2525     cypress_enable_spread_spectrum(rdev, false);
2526 
2527     btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
2528 }
2529 
2530 void btc_dpm_setup_asic(struct radeon_device *rdev)
2531 {
2532     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2533     int r;
2534 
2535     r = ni_mc_load_microcode(rdev);
2536     if (r)
2537         DRM_ERROR("Failed to load MC firmware!\n");
2538     rv770_get_memory_type(rdev);
2539     rv740_read_clock_registers(rdev);
2540     btc_read_arb_registers(rdev);
2541     rv770_read_voltage_smio_registers(rdev);
2542 
2543     if (eg_pi->pcie_performance_request)
2544         cypress_advertise_gen2_capability(rdev);
2545 
2546     rv770_get_pcie_gen2_status(rdev);
2547     rv770_enable_acpi_pm(rdev);
2548 }
2549 
2550 int btc_dpm_init(struct radeon_device *rdev)
2551 {
2552     struct rv7xx_power_info *pi;
2553     struct evergreen_power_info *eg_pi;
2554     struct atom_clock_dividers dividers;
2555     int ret;
2556 
2557     eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL);
2558     if (eg_pi == NULL)
2559         return -ENOMEM;
2560     rdev->pm.dpm.priv = eg_pi;
2561     pi = &eg_pi->rv7xx;
2562 
2563     rv770_get_max_vddc(rdev);
2564 
2565     eg_pi->ulv.supported = false;
2566     pi->acpi_vddc = 0;
2567     eg_pi->acpi_vddci = 0;
2568     pi->min_vddc_in_table = 0;
2569     pi->max_vddc_in_table = 0;
2570 
2571     ret = r600_get_platform_caps(rdev);
2572     if (ret)
2573         return ret;
2574 
2575     ret = rv7xx_parse_power_table(rdev);
2576     if (ret)
2577         return ret;
2578     ret = r600_parse_extended_power_table(rdev);
2579     if (ret)
2580         return ret;
2581 
2582     rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
2583         kcalloc(4,
2584             sizeof(struct radeon_clock_voltage_dependency_entry),
2585             GFP_KERNEL);
2586     if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
2587         r600_free_extended_power_table(rdev);
2588         return -ENOMEM;
2589     }
2590     rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
2591     rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
2592     rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
2593     rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
2594     rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 800;
2595     rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
2596     rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 800;
2597     rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
2598     rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 800;
2599 
2600     if (rdev->pm.dpm.voltage_response_time == 0)
2601         rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
2602     if (rdev->pm.dpm.backbias_response_time == 0)
2603         rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
2604 
2605     ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
2606                          0, false, &dividers);
2607     if (ret)
2608         pi->ref_div = dividers.ref_div + 1;
2609     else
2610         pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
2611 
2612     pi->mclk_strobe_mode_threshold = 40000;
2613     pi->mclk_edc_enable_threshold = 40000;
2614     eg_pi->mclk_edc_wr_enable_threshold = 40000;
2615 
2616     pi->rlp = RV770_RLP_DFLT;
2617     pi->rmp = RV770_RMP_DFLT;
2618     pi->lhp = RV770_LHP_DFLT;
2619     pi->lmp = RV770_LMP_DFLT;
2620 
2621     eg_pi->ats[0].rlp = RV770_RLP_DFLT;
2622     eg_pi->ats[0].rmp = RV770_RMP_DFLT;
2623     eg_pi->ats[0].lhp = RV770_LHP_DFLT;
2624     eg_pi->ats[0].lmp = RV770_LMP_DFLT;
2625 
2626     eg_pi->ats[1].rlp = BTC_RLP_UVD_DFLT;
2627     eg_pi->ats[1].rmp = BTC_RMP_UVD_DFLT;
2628     eg_pi->ats[1].lhp = BTC_LHP_UVD_DFLT;
2629     eg_pi->ats[1].lmp = BTC_LMP_UVD_DFLT;
2630 
2631     eg_pi->smu_uvd_hs = true;
2632 
2633     pi->voltage_control =
2634         radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
2635 
2636     pi->mvdd_control =
2637         radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
2638 
2639     eg_pi->vddci_control =
2640         radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
2641 
2642     rv770_get_engine_memory_ss(rdev);
2643 
2644     pi->asi = RV770_ASI_DFLT;
2645     pi->pasi = CYPRESS_HASI_DFLT;
2646     pi->vrc = CYPRESS_VRC_DFLT;
2647 
2648     pi->power_gating = false;
2649 
2650     pi->gfx_clock_gating = true;
2651 
2652     pi->mg_clock_gating = true;
2653     pi->mgcgtssm = true;
2654     eg_pi->ls_clock_gating = false;
2655     eg_pi->sclk_deep_sleep = false;
2656 
2657     pi->dynamic_pcie_gen2 = true;
2658 
2659     if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
2660         pi->thermal_protection = true;
2661     else
2662         pi->thermal_protection = false;
2663 
2664     pi->display_gap = true;
2665 
2666     if (rdev->flags & RADEON_IS_MOBILITY)
2667         pi->dcodt = true;
2668     else
2669         pi->dcodt = false;
2670 
2671     pi->ulps = true;
2672 
2673     eg_pi->dynamic_ac_timing = true;
2674     eg_pi->abm = true;
2675     eg_pi->mcls = true;
2676     eg_pi->light_sleep = true;
2677     eg_pi->memory_transition = true;
2678 #if defined(CONFIG_ACPI)
2679     eg_pi->pcie_performance_request =
2680         radeon_acpi_is_pcie_performance_request_supported(rdev);
2681 #else
2682     eg_pi->pcie_performance_request = false;
2683 #endif
2684 
2685     if (rdev->family == CHIP_BARTS)
2686         eg_pi->dll_default_on = true;
2687     else
2688         eg_pi->dll_default_on = false;
2689 
2690     eg_pi->sclk_deep_sleep = false;
2691     if (ASIC_IS_LOMBOK(rdev))
2692         pi->mclk_stutter_mode_threshold = 30000;
2693     else
2694         pi->mclk_stutter_mode_threshold = 0;
2695 
2696     pi->sram_end = SMC_RAM_END;
2697 
2698     rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;
2699     rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
2700     rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2 = 900;
2701     rdev->pm.dpm.dyn_state.valid_sclk_values.count = ARRAY_SIZE(btc_valid_sclk);
2702     rdev->pm.dpm.dyn_state.valid_sclk_values.values = btc_valid_sclk;
2703     rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
2704     rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
2705 
2706     if (rdev->family == CHIP_TURKS)
2707         rdev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;
2708     else
2709         rdev->pm.dpm.dyn_state.sclk_mclk_delta = 10000;
2710 
2711     /* make sure dc limits are valid */
2712     if ((rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk == 0) ||
2713         (rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk == 0))
2714         rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
2715             rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
2716 
2717     return 0;
2718 }
2719 
2720 void btc_dpm_fini(struct radeon_device *rdev)
2721 {
2722     int i;
2723 
2724     for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
2725         kfree(rdev->pm.dpm.ps[i].ps_priv);
2726     }
2727     kfree(rdev->pm.dpm.ps);
2728     kfree(rdev->pm.dpm.priv);
2729     kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
2730     r600_free_extended_power_table(rdev);
2731 }
2732 
2733 void btc_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
2734                              struct seq_file *m)
2735 {
2736     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2737     struct radeon_ps *rps = &eg_pi->current_rps;
2738     struct rv7xx_ps *ps = rv770_get_ps(rps);
2739     struct rv7xx_pl *pl;
2740     u32 current_index =
2741         (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
2742         CURRENT_PROFILE_INDEX_SHIFT;
2743 
2744     if (current_index > 2) {
2745         seq_printf(m, "invalid dpm profile %d\n", current_index);
2746     } else {
2747         if (current_index == 0)
2748             pl = &ps->low;
2749         else if (current_index == 1)
2750             pl = &ps->medium;
2751         else /* current_index == 2 */
2752             pl = &ps->high;
2753         seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
2754         seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
2755                current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
2756     }
2757 }
2758 
2759 u32 btc_dpm_get_current_sclk(struct radeon_device *rdev)
2760 {
2761     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2762     struct radeon_ps *rps = &eg_pi->current_rps;
2763     struct rv7xx_ps *ps = rv770_get_ps(rps);
2764     struct rv7xx_pl *pl;
2765     u32 current_index =
2766         (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
2767         CURRENT_PROFILE_INDEX_SHIFT;
2768 
2769     if (current_index > 2) {
2770         return 0;
2771     } else {
2772         if (current_index == 0)
2773             pl = &ps->low;
2774         else if (current_index == 1)
2775             pl = &ps->medium;
2776         else /* current_index == 2 */
2777             pl = &ps->high;
2778         return pl->sclk;
2779     }
2780 }
2781 
2782 u32 btc_dpm_get_current_mclk(struct radeon_device *rdev)
2783 {
2784     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2785     struct radeon_ps *rps = &eg_pi->current_rps;
2786     struct rv7xx_ps *ps = rv770_get_ps(rps);
2787     struct rv7xx_pl *pl;
2788     u32 current_index =
2789         (RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_PROFILE_INDEX_MASK) >>
2790         CURRENT_PROFILE_INDEX_SHIFT;
2791 
2792     if (current_index > 2) {
2793         return 0;
2794     } else {
2795         if (current_index == 0)
2796             pl = &ps->low;
2797         else if (current_index == 1)
2798             pl = &ps->medium;
2799         else /* current_index == 2 */
2800             pl = &ps->high;
2801         return pl->mclk;
2802     }
2803 }
2804 
2805 u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low)
2806 {
2807     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2808     struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2809 
2810     if (low)
2811         return requested_state->low.sclk;
2812     else
2813         return requested_state->high.sclk;
2814 }
2815 
2816 u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low)
2817 {
2818     struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
2819     struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
2820 
2821     if (low)
2822         return requested_state->low.mclk;
2823     else
2824         return requested_state->high.mclk;
2825 }