Home | History | Annotate | Line # | Download | only in radeon
      1  1.3  riastrad /*	$NetBSD: radeon_trinity_dpm.c,v 1.3 2021/12/18 23:45:43 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * Copyright 2012 Advanced Micro Devices, Inc.
      5  1.1  riastrad  *
      6  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      7  1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
      8  1.1  riastrad  * to deal in the Software without restriction, including without limitation
      9  1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     11  1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     12  1.1  riastrad  *
     13  1.1  riastrad  * The above copyright notice and this permission notice shall be included in
     14  1.1  riastrad  * all copies or substantial portions of the Software.
     15  1.1  riastrad  *
     16  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  1.1  riastrad  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  1.1  riastrad  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  1.1  riastrad  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  1.1  riastrad  * OTHER DEALINGS IN THE SOFTWARE.
     23  1.1  riastrad  *
     24  1.1  riastrad  */
     25  1.1  riastrad 
     26  1.1  riastrad #include <sys/cdefs.h>
     27  1.3  riastrad __KERNEL_RCSID(0, "$NetBSD: radeon_trinity_dpm.c,v 1.3 2021/12/18 23:45:43 riastradh Exp $");
     28  1.1  riastrad 
     29  1.3  riastrad #include <linux/pci.h>
     30  1.3  riastrad #include <linux/seq_file.h>
     31  1.3  riastrad 
     32  1.3  riastrad #include "r600_dpm.h"
     33  1.1  riastrad #include "radeon.h"
     34  1.1  riastrad #include "radeon_asic.h"
     35  1.3  riastrad #include "trinity_dpm.h"
     36  1.1  riastrad #include "trinityd.h"
     37  1.1  riastrad 
     38  1.1  riastrad #define TRINITY_MAX_DEEPSLEEP_DIVIDER_ID 5
     39  1.1  riastrad #define TRINITY_MINIMUM_ENGINE_CLOCK 800
     40  1.1  riastrad #define SCLK_MIN_DIV_INTV_SHIFT     12
     41  1.1  riastrad #define TRINITY_DISPCLK_BYPASS_THRESHOLD 10000
     42  1.1  riastrad 
     43  1.1  riastrad #ifndef TRINITY_MGCG_SEQUENCE
     44  1.1  riastrad #define TRINITY_MGCG_SEQUENCE  100
     45  1.1  riastrad 
     46  1.1  riastrad static const u32 trinity_mgcg_shls_default[] =
     47  1.1  riastrad {
     48  1.1  riastrad 	/* Register, Value, Mask */
     49  1.1  riastrad 	0x0000802c, 0xc0000000, 0xffffffff,
     50  1.1  riastrad 	0x00003fc4, 0xc0000000, 0xffffffff,
     51  1.1  riastrad 	0x00005448, 0x00000100, 0xffffffff,
     52  1.1  riastrad 	0x000055e4, 0x00000100, 0xffffffff,
     53  1.1  riastrad 	0x0000160c, 0x00000100, 0xffffffff,
     54  1.1  riastrad 	0x00008984, 0x06000100, 0xffffffff,
     55  1.1  riastrad 	0x0000c164, 0x00000100, 0xffffffff,
     56  1.1  riastrad 	0x00008a18, 0x00000100, 0xffffffff,
     57  1.1  riastrad 	0x0000897c, 0x06000100, 0xffffffff,
     58  1.1  riastrad 	0x00008b28, 0x00000100, 0xffffffff,
     59  1.1  riastrad 	0x00009144, 0x00800200, 0xffffffff,
     60  1.1  riastrad 	0x00009a60, 0x00000100, 0xffffffff,
     61  1.1  riastrad 	0x00009868, 0x00000100, 0xffffffff,
     62  1.1  riastrad 	0x00008d58, 0x00000100, 0xffffffff,
     63  1.1  riastrad 	0x00009510, 0x00000100, 0xffffffff,
     64  1.1  riastrad 	0x0000949c, 0x00000100, 0xffffffff,
     65  1.1  riastrad 	0x00009654, 0x00000100, 0xffffffff,
     66  1.1  riastrad 	0x00009030, 0x00000100, 0xffffffff,
     67  1.1  riastrad 	0x00009034, 0x00000100, 0xffffffff,
     68  1.1  riastrad 	0x00009038, 0x00000100, 0xffffffff,
     69  1.1  riastrad 	0x0000903c, 0x00000100, 0xffffffff,
     70  1.1  riastrad 	0x00009040, 0x00000100, 0xffffffff,
     71  1.1  riastrad 	0x0000a200, 0x00000100, 0xffffffff,
     72  1.1  riastrad 	0x0000a204, 0x00000100, 0xffffffff,
     73  1.1  riastrad 	0x0000a208, 0x00000100, 0xffffffff,
     74  1.1  riastrad 	0x0000a20c, 0x00000100, 0xffffffff,
     75  1.1  riastrad 	0x00009744, 0x00000100, 0xffffffff,
     76  1.1  riastrad 	0x00003f80, 0x00000100, 0xffffffff,
     77  1.1  riastrad 	0x0000a210, 0x00000100, 0xffffffff,
     78  1.1  riastrad 	0x0000a214, 0x00000100, 0xffffffff,
     79  1.1  riastrad 	0x000004d8, 0x00000100, 0xffffffff,
     80  1.1  riastrad 	0x00009664, 0x00000100, 0xffffffff,
     81  1.1  riastrad 	0x00009698, 0x00000100, 0xffffffff,
     82  1.1  riastrad 	0x000004d4, 0x00000200, 0xffffffff,
     83  1.1  riastrad 	0x000004d0, 0x00000000, 0xffffffff,
     84  1.1  riastrad 	0x000030cc, 0x00000104, 0xffffffff,
     85  1.1  riastrad 	0x0000d0c0, 0x00000100, 0xffffffff,
     86  1.1  riastrad 	0x0000d8c0, 0x00000100, 0xffffffff,
     87  1.1  riastrad 	0x0000951c, 0x00010000, 0xffffffff,
     88  1.1  riastrad 	0x00009160, 0x00030002, 0xffffffff,
     89  1.1  riastrad 	0x00009164, 0x00050004, 0xffffffff,
     90  1.1  riastrad 	0x00009168, 0x00070006, 0xffffffff,
     91  1.1  riastrad 	0x00009178, 0x00070000, 0xffffffff,
     92  1.1  riastrad 	0x0000917c, 0x00030002, 0xffffffff,
     93  1.1  riastrad 	0x00009180, 0x00050004, 0xffffffff,
     94  1.1  riastrad 	0x0000918c, 0x00010006, 0xffffffff,
     95  1.1  riastrad 	0x00009190, 0x00090008, 0xffffffff,
     96  1.1  riastrad 	0x00009194, 0x00070000, 0xffffffff,
     97  1.1  riastrad 	0x00009198, 0x00030002, 0xffffffff,
     98  1.1  riastrad 	0x0000919c, 0x00050004, 0xffffffff,
     99  1.1  riastrad 	0x000091a8, 0x00010006, 0xffffffff,
    100  1.1  riastrad 	0x000091ac, 0x00090008, 0xffffffff,
    101  1.1  riastrad 	0x000091b0, 0x00070000, 0xffffffff,
    102  1.1  riastrad 	0x000091b4, 0x00030002, 0xffffffff,
    103  1.1  riastrad 	0x000091b8, 0x00050004, 0xffffffff,
    104  1.1  riastrad 	0x000091c4, 0x00010006, 0xffffffff,
    105  1.1  riastrad 	0x000091c8, 0x00090008, 0xffffffff,
    106  1.1  riastrad 	0x000091cc, 0x00070000, 0xffffffff,
    107  1.1  riastrad 	0x000091d0, 0x00030002, 0xffffffff,
    108  1.1  riastrad 	0x000091d4, 0x00050004, 0xffffffff,
    109  1.1  riastrad 	0x000091e0, 0x00010006, 0xffffffff,
    110  1.1  riastrad 	0x000091e4, 0x00090008, 0xffffffff,
    111  1.1  riastrad 	0x000091e8, 0x00000000, 0xffffffff,
    112  1.1  riastrad 	0x000091ec, 0x00070000, 0xffffffff,
    113  1.1  riastrad 	0x000091f0, 0x00030002, 0xffffffff,
    114  1.1  riastrad 	0x000091f4, 0x00050004, 0xffffffff,
    115  1.1  riastrad 	0x00009200, 0x00010006, 0xffffffff,
    116  1.1  riastrad 	0x00009204, 0x00090008, 0xffffffff,
    117  1.1  riastrad 	0x00009208, 0x00070000, 0xffffffff,
    118  1.1  riastrad 	0x0000920c, 0x00030002, 0xffffffff,
    119  1.1  riastrad 	0x00009210, 0x00050004, 0xffffffff,
    120  1.1  riastrad 	0x0000921c, 0x00010006, 0xffffffff,
    121  1.1  riastrad 	0x00009220, 0x00090008, 0xffffffff,
    122  1.1  riastrad 	0x00009294, 0x00000000, 0xffffffff
    123  1.1  riastrad };
    124  1.1  riastrad 
    125  1.1  riastrad static const u32 trinity_mgcg_shls_enable[] =
    126  1.1  riastrad {
    127  1.1  riastrad 	/* Register, Value, Mask */
    128  1.1  riastrad 	0x0000802c, 0xc0000000, 0xffffffff,
    129  1.1  riastrad 	0x000008f8, 0x00000000, 0xffffffff,
    130  1.1  riastrad 	0x000008fc, 0x00000000, 0x000133FF,
    131  1.1  riastrad 	0x000008f8, 0x00000001, 0xffffffff,
    132  1.1  riastrad 	0x000008fc, 0x00000000, 0xE00B03FC,
    133  1.1  riastrad 	0x00009150, 0x96944200, 0xffffffff
    134  1.1  riastrad };
    135  1.1  riastrad 
    136  1.1  riastrad static const u32 trinity_mgcg_shls_disable[] =
    137  1.1  riastrad {
    138  1.1  riastrad 	/* Register, Value, Mask */
    139  1.1  riastrad 	0x0000802c, 0xc0000000, 0xffffffff,
    140  1.1  riastrad 	0x00009150, 0x00600000, 0xffffffff,
    141  1.1  riastrad 	0x000008f8, 0x00000000, 0xffffffff,
    142  1.1  riastrad 	0x000008fc, 0xffffffff, 0x000133FF,
    143  1.1  riastrad 	0x000008f8, 0x00000001, 0xffffffff,
    144  1.1  riastrad 	0x000008fc, 0xffffffff, 0xE00B03FC
    145  1.1  riastrad };
    146  1.1  riastrad #endif
    147  1.1  riastrad 
    148  1.1  riastrad #ifndef TRINITY_SYSLS_SEQUENCE
    149  1.1  riastrad #define TRINITY_SYSLS_SEQUENCE  100
    150  1.1  riastrad 
    151  1.1  riastrad static const u32 trinity_sysls_default[] =
    152  1.1  riastrad {
    153  1.1  riastrad 	/* Register, Value, Mask */
    154  1.1  riastrad 	0x000055e8, 0x00000000, 0xffffffff,
    155  1.1  riastrad 	0x0000d0bc, 0x00000000, 0xffffffff,
    156  1.1  riastrad 	0x0000d8bc, 0x00000000, 0xffffffff,
    157  1.1  riastrad 	0x000015c0, 0x000c1401, 0xffffffff,
    158  1.1  riastrad 	0x0000264c, 0x000c0400, 0xffffffff,
    159  1.1  riastrad 	0x00002648, 0x000c0400, 0xffffffff,
    160  1.1  riastrad 	0x00002650, 0x000c0400, 0xffffffff,
    161  1.1  riastrad 	0x000020b8, 0x000c0400, 0xffffffff,
    162  1.1  riastrad 	0x000020bc, 0x000c0400, 0xffffffff,
    163  1.1  riastrad 	0x000020c0, 0x000c0c80, 0xffffffff,
    164  1.1  riastrad 	0x0000f4a0, 0x000000c0, 0xffffffff,
    165  1.1  riastrad 	0x0000f4a4, 0x00680fff, 0xffffffff,
    166  1.1  riastrad 	0x00002f50, 0x00000404, 0xffffffff,
    167  1.1  riastrad 	0x000004c8, 0x00000001, 0xffffffff,
    168  1.1  riastrad 	0x0000641c, 0x00000000, 0xffffffff,
    169  1.1  riastrad 	0x00000c7c, 0x00000000, 0xffffffff,
    170  1.1  riastrad 	0x00006dfc, 0x00000000, 0xffffffff
    171  1.1  riastrad };
    172  1.1  riastrad 
    173  1.1  riastrad static const u32 trinity_sysls_disable[] =
    174  1.1  riastrad {
    175  1.1  riastrad 	/* Register, Value, Mask */
    176  1.1  riastrad 	0x0000d0c0, 0x00000000, 0xffffffff,
    177  1.1  riastrad 	0x0000d8c0, 0x00000000, 0xffffffff,
    178  1.1  riastrad 	0x000055e8, 0x00000000, 0xffffffff,
    179  1.1  riastrad 	0x0000d0bc, 0x00000000, 0xffffffff,
    180  1.1  riastrad 	0x0000d8bc, 0x00000000, 0xffffffff,
    181  1.1  riastrad 	0x000015c0, 0x00041401, 0xffffffff,
    182  1.1  riastrad 	0x0000264c, 0x00040400, 0xffffffff,
    183  1.1  riastrad 	0x00002648, 0x00040400, 0xffffffff,
    184  1.1  riastrad 	0x00002650, 0x00040400, 0xffffffff,
    185  1.1  riastrad 	0x000020b8, 0x00040400, 0xffffffff,
    186  1.1  riastrad 	0x000020bc, 0x00040400, 0xffffffff,
    187  1.1  riastrad 	0x000020c0, 0x00040c80, 0xffffffff,
    188  1.1  riastrad 	0x0000f4a0, 0x000000c0, 0xffffffff,
    189  1.1  riastrad 	0x0000f4a4, 0x00680000, 0xffffffff,
    190  1.1  riastrad 	0x00002f50, 0x00000404, 0xffffffff,
    191  1.1  riastrad 	0x000004c8, 0x00000001, 0xffffffff,
    192  1.1  riastrad 	0x0000641c, 0x00007ffd, 0xffffffff,
    193  1.1  riastrad 	0x00000c7c, 0x0000ff00, 0xffffffff,
    194  1.1  riastrad 	0x00006dfc, 0x0000007f, 0xffffffff
    195  1.1  riastrad };
    196  1.1  riastrad 
    197  1.1  riastrad static const u32 trinity_sysls_enable[] =
    198  1.1  riastrad {
    199  1.1  riastrad 	/* Register, Value, Mask */
    200  1.1  riastrad 	0x000055e8, 0x00000001, 0xffffffff,
    201  1.1  riastrad 	0x0000d0bc, 0x00000100, 0xffffffff,
    202  1.1  riastrad 	0x0000d8bc, 0x00000100, 0xffffffff,
    203  1.1  riastrad 	0x000015c0, 0x000c1401, 0xffffffff,
    204  1.1  riastrad 	0x0000264c, 0x000c0400, 0xffffffff,
    205  1.1  riastrad 	0x00002648, 0x000c0400, 0xffffffff,
    206  1.1  riastrad 	0x00002650, 0x000c0400, 0xffffffff,
    207  1.1  riastrad 	0x000020b8, 0x000c0400, 0xffffffff,
    208  1.1  riastrad 	0x000020bc, 0x000c0400, 0xffffffff,
    209  1.1  riastrad 	0x000020c0, 0x000c0c80, 0xffffffff,
    210  1.1  riastrad 	0x0000f4a0, 0x000000c0, 0xffffffff,
    211  1.1  riastrad 	0x0000f4a4, 0x00680fff, 0xffffffff,
    212  1.1  riastrad 	0x00002f50, 0x00000903, 0xffffffff,
    213  1.1  riastrad 	0x000004c8, 0x00000000, 0xffffffff,
    214  1.1  riastrad 	0x0000641c, 0x00000000, 0xffffffff,
    215  1.1  riastrad 	0x00000c7c, 0x00000000, 0xffffffff,
    216  1.1  riastrad 	0x00006dfc, 0x00000000, 0xffffffff
    217  1.1  riastrad };
    218  1.1  riastrad #endif
    219  1.1  riastrad 
    220  1.1  riastrad static const u32 trinity_override_mgpg_sequences[] =
    221  1.1  riastrad {
    222  1.1  riastrad 	/* Register, Value */
    223  1.1  riastrad 	0x00000200, 0xE030032C,
    224  1.1  riastrad 	0x00000204, 0x00000FFF,
    225  1.1  riastrad 	0x00000200, 0xE0300058,
    226  1.1  riastrad 	0x00000204, 0x00030301,
    227  1.1  riastrad 	0x00000200, 0xE0300054,
    228  1.1  riastrad 	0x00000204, 0x500010FF,
    229  1.1  riastrad 	0x00000200, 0xE0300074,
    230  1.1  riastrad 	0x00000204, 0x00030301,
    231  1.1  riastrad 	0x00000200, 0xE0300070,
    232  1.1  riastrad 	0x00000204, 0x500010FF,
    233  1.1  riastrad 	0x00000200, 0xE0300090,
    234  1.1  riastrad 	0x00000204, 0x00030301,
    235  1.1  riastrad 	0x00000200, 0xE030008C,
    236  1.1  riastrad 	0x00000204, 0x500010FF,
    237  1.1  riastrad 	0x00000200, 0xE03000AC,
    238  1.1  riastrad 	0x00000204, 0x00030301,
    239  1.1  riastrad 	0x00000200, 0xE03000A8,
    240  1.1  riastrad 	0x00000204, 0x500010FF,
    241  1.1  riastrad 	0x00000200, 0xE03000C8,
    242  1.1  riastrad 	0x00000204, 0x00030301,
    243  1.1  riastrad 	0x00000200, 0xE03000C4,
    244  1.1  riastrad 	0x00000204, 0x500010FF,
    245  1.1  riastrad 	0x00000200, 0xE03000E4,
    246  1.1  riastrad 	0x00000204, 0x00030301,
    247  1.1  riastrad 	0x00000200, 0xE03000E0,
    248  1.1  riastrad 	0x00000204, 0x500010FF,
    249  1.1  riastrad 	0x00000200, 0xE0300100,
    250  1.1  riastrad 	0x00000204, 0x00030301,
    251  1.1  riastrad 	0x00000200, 0xE03000FC,
    252  1.1  riastrad 	0x00000204, 0x500010FF,
    253  1.1  riastrad 	0x00000200, 0xE0300058,
    254  1.1  riastrad 	0x00000204, 0x00030303,
    255  1.1  riastrad 	0x00000200, 0xE0300054,
    256  1.1  riastrad 	0x00000204, 0x600010FF,
    257  1.1  riastrad 	0x00000200, 0xE0300074,
    258  1.1  riastrad 	0x00000204, 0x00030303,
    259  1.1  riastrad 	0x00000200, 0xE0300070,
    260  1.1  riastrad 	0x00000204, 0x600010FF,
    261  1.1  riastrad 	0x00000200, 0xE0300090,
    262  1.1  riastrad 	0x00000204, 0x00030303,
    263  1.1  riastrad 	0x00000200, 0xE030008C,
    264  1.1  riastrad 	0x00000204, 0x600010FF,
    265  1.1  riastrad 	0x00000200, 0xE03000AC,
    266  1.1  riastrad 	0x00000204, 0x00030303,
    267  1.1  riastrad 	0x00000200, 0xE03000A8,
    268  1.1  riastrad 	0x00000204, 0x600010FF,
    269  1.1  riastrad 	0x00000200, 0xE03000C8,
    270  1.1  riastrad 	0x00000204, 0x00030303,
    271  1.1  riastrad 	0x00000200, 0xE03000C4,
    272  1.1  riastrad 	0x00000204, 0x600010FF,
    273  1.1  riastrad 	0x00000200, 0xE03000E4,
    274  1.1  riastrad 	0x00000204, 0x00030303,
    275  1.1  riastrad 	0x00000200, 0xE03000E0,
    276  1.1  riastrad 	0x00000204, 0x600010FF,
    277  1.1  riastrad 	0x00000200, 0xE0300100,
    278  1.1  riastrad 	0x00000204, 0x00030303,
    279  1.1  riastrad 	0x00000200, 0xE03000FC,
    280  1.1  riastrad 	0x00000204, 0x600010FF,
    281  1.1  riastrad 	0x00000200, 0xE0300058,
    282  1.1  riastrad 	0x00000204, 0x00030303,
    283  1.1  riastrad 	0x00000200, 0xE0300054,
    284  1.1  riastrad 	0x00000204, 0x700010FF,
    285  1.1  riastrad 	0x00000200, 0xE0300074,
    286  1.1  riastrad 	0x00000204, 0x00030303,
    287  1.1  riastrad 	0x00000200, 0xE0300070,
    288  1.1  riastrad 	0x00000204, 0x700010FF,
    289  1.1  riastrad 	0x00000200, 0xE0300090,
    290  1.1  riastrad 	0x00000204, 0x00030303,
    291  1.1  riastrad 	0x00000200, 0xE030008C,
    292  1.1  riastrad 	0x00000204, 0x700010FF,
    293  1.1  riastrad 	0x00000200, 0xE03000AC,
    294  1.1  riastrad 	0x00000204, 0x00030303,
    295  1.1  riastrad 	0x00000200, 0xE03000A8,
    296  1.1  riastrad 	0x00000204, 0x700010FF,
    297  1.1  riastrad 	0x00000200, 0xE03000C8,
    298  1.1  riastrad 	0x00000204, 0x00030303,
    299  1.1  riastrad 	0x00000200, 0xE03000C4,
    300  1.1  riastrad 	0x00000204, 0x700010FF,
    301  1.1  riastrad 	0x00000200, 0xE03000E4,
    302  1.1  riastrad 	0x00000204, 0x00030303,
    303  1.1  riastrad 	0x00000200, 0xE03000E0,
    304  1.1  riastrad 	0x00000204, 0x700010FF,
    305  1.1  riastrad 	0x00000200, 0xE0300100,
    306  1.1  riastrad 	0x00000204, 0x00030303,
    307  1.1  riastrad 	0x00000200, 0xE03000FC,
    308  1.1  riastrad 	0x00000204, 0x700010FF,
    309  1.1  riastrad 	0x00000200, 0xE0300058,
    310  1.1  riastrad 	0x00000204, 0x00010303,
    311  1.1  riastrad 	0x00000200, 0xE0300054,
    312  1.1  riastrad 	0x00000204, 0x800010FF,
    313  1.1  riastrad 	0x00000200, 0xE0300074,
    314  1.1  riastrad 	0x00000204, 0x00010303,
    315  1.1  riastrad 	0x00000200, 0xE0300070,
    316  1.1  riastrad 	0x00000204, 0x800010FF,
    317  1.1  riastrad 	0x00000200, 0xE0300090,
    318  1.1  riastrad 	0x00000204, 0x00010303,
    319  1.1  riastrad 	0x00000200, 0xE030008C,
    320  1.1  riastrad 	0x00000204, 0x800010FF,
    321  1.1  riastrad 	0x00000200, 0xE03000AC,
    322  1.1  riastrad 	0x00000204, 0x00010303,
    323  1.1  riastrad 	0x00000200, 0xE03000A8,
    324  1.1  riastrad 	0x00000204, 0x800010FF,
    325  1.1  riastrad 	0x00000200, 0xE03000C4,
    326  1.1  riastrad 	0x00000204, 0x800010FF,
    327  1.1  riastrad 	0x00000200, 0xE03000C8,
    328  1.1  riastrad 	0x00000204, 0x00010303,
    329  1.1  riastrad 	0x00000200, 0xE03000E4,
    330  1.1  riastrad 	0x00000204, 0x00010303,
    331  1.1  riastrad 	0x00000200, 0xE03000E0,
    332  1.1  riastrad 	0x00000204, 0x800010FF,
    333  1.1  riastrad 	0x00000200, 0xE0300100,
    334  1.1  riastrad 	0x00000204, 0x00010303,
    335  1.1  riastrad 	0x00000200, 0xE03000FC,
    336  1.1  riastrad 	0x00000204, 0x800010FF,
    337  1.1  riastrad 	0x00000200, 0x0001f198,
    338  1.1  riastrad 	0x00000204, 0x0003ffff,
    339  1.1  riastrad 	0x00000200, 0x0001f19C,
    340  1.1  riastrad 	0x00000204, 0x3fffffff,
    341  1.1  riastrad 	0x00000200, 0xE030032C,
    342  1.1  riastrad 	0x00000204, 0x00000000,
    343  1.1  riastrad };
    344  1.1  riastrad 
    345  1.1  riastrad extern void vce_v1_0_enable_mgcg(struct radeon_device *rdev, bool enable);
    346  1.1  riastrad static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
    347  1.1  riastrad 						   const u32 *seq, u32 count);
    348  1.1  riastrad static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev);
    349  1.1  riastrad static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
    350  1.1  riastrad 					     struct radeon_ps *new_rps,
    351  1.1  riastrad 					     struct radeon_ps *old_rps);
    352  1.1  riastrad 
    353  1.1  riastrad static struct trinity_ps *trinity_get_ps(struct radeon_ps *rps)
    354  1.1  riastrad {
    355  1.1  riastrad 	struct trinity_ps *ps = rps->ps_priv;
    356  1.1  riastrad 
    357  1.1  riastrad 	return ps;
    358  1.1  riastrad }
    359  1.1  riastrad 
    360  1.1  riastrad static struct trinity_power_info *trinity_get_pi(struct radeon_device *rdev)
    361  1.1  riastrad {
    362  1.1  riastrad 	struct trinity_power_info *pi = rdev->pm.dpm.priv;
    363  1.1  riastrad 
    364  1.1  riastrad 	return pi;
    365  1.1  riastrad }
    366  1.1  riastrad 
    367  1.1  riastrad static void trinity_gfx_powergating_initialize(struct radeon_device *rdev)
    368  1.1  riastrad {
    369  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
    370  1.1  riastrad 	u32 p, u;
    371  1.1  riastrad 	u32 value;
    372  1.1  riastrad 	struct atom_clock_dividers dividers;
    373  1.1  riastrad 	u32 xclk = radeon_get_xclk(rdev);
    374  1.1  riastrad 	u32 sssd = 1;
    375  1.1  riastrad 	int ret;
    376  1.1  riastrad 	u32 hw_rev = (RREG32(HW_REV) & ATI_REV_ID_MASK) >> ATI_REV_ID_SHIFT;
    377  1.1  riastrad 
    378  1.3  riastrad 	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
    379  1.3  riastrad 					     25000, false, &dividers);
    380  1.1  riastrad 	if (ret)
    381  1.1  riastrad 		return;
    382  1.1  riastrad 
    383  1.1  riastrad 	value = RREG32_SMC(GFX_POWER_GATING_CNTL);
    384  1.1  riastrad 	value &= ~(SSSD_MASK | PDS_DIV_MASK);
    385  1.1  riastrad 	if (sssd)
    386  1.1  riastrad 		value |= SSSD(1);
    387  1.1  riastrad 	value |= PDS_DIV(dividers.post_div);
    388  1.1  riastrad 	WREG32_SMC(GFX_POWER_GATING_CNTL, value);
    389  1.1  riastrad 
    390  1.1  riastrad 	r600_calculate_u_and_p(500, xclk, 16, &p, &u);
    391  1.1  riastrad 
    392  1.1  riastrad 	WREG32(CG_PG_CTRL, SP(p) | SU(u));
    393  1.1  riastrad 
    394  1.1  riastrad 	WREG32_P(CG_GIPOTS, CG_GIPOT(p), ~CG_GIPOT_MASK);
    395  1.1  riastrad 
    396  1.1  riastrad 	/* XXX double check hw_rev */
    397  1.1  riastrad 	if (pi->override_dynamic_mgpg && (hw_rev == 0))
    398  1.1  riastrad 		trinity_override_dynamic_mg_powergating(rdev);
    399  1.1  riastrad 
    400  1.1  riastrad }
    401  1.1  riastrad 
    402  1.1  riastrad #define CGCG_CGTT_LOCAL0_MASK       0xFFFF33FF
    403  1.1  riastrad #define CGCG_CGTT_LOCAL1_MASK       0xFFFB0FFE
    404  1.1  riastrad #define CGTS_SM_CTRL_REG_DISABLE    0x00600000
    405  1.1  riastrad #define CGTS_SM_CTRL_REG_ENABLE     0x96944200
    406  1.1  riastrad 
    407  1.1  riastrad static void trinity_mg_clockgating_enable(struct radeon_device *rdev,
    408  1.1  riastrad 					  bool enable)
    409  1.1  riastrad {
    410  1.1  riastrad 	u32 local0;
    411  1.1  riastrad 	u32 local1;
    412  1.1  riastrad 
    413  1.1  riastrad 	if (enable) {
    414  1.1  riastrad 		local0 = RREG32_CG(CG_CGTT_LOCAL_0);
    415  1.1  riastrad 		local1 = RREG32_CG(CG_CGTT_LOCAL_1);
    416  1.1  riastrad 
    417  1.1  riastrad 		WREG32_CG(CG_CGTT_LOCAL_0,
    418  1.1  riastrad 			  (0x00380000 & CGCG_CGTT_LOCAL0_MASK) | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
    419  1.1  riastrad 		WREG32_CG(CG_CGTT_LOCAL_1,
    420  1.1  riastrad 			  (0x0E000000 & CGCG_CGTT_LOCAL1_MASK) | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
    421  1.1  riastrad 
    422  1.1  riastrad 		WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_ENABLE);
    423  1.1  riastrad 	} else {
    424  1.1  riastrad 		WREG32(CGTS_SM_CTRL_REG, CGTS_SM_CTRL_REG_DISABLE);
    425  1.1  riastrad 
    426  1.1  riastrad 		local0 = RREG32_CG(CG_CGTT_LOCAL_0);
    427  1.1  riastrad 		local1 = RREG32_CG(CG_CGTT_LOCAL_1);
    428  1.1  riastrad 
    429  1.1  riastrad 		WREG32_CG(CG_CGTT_LOCAL_0,
    430  1.1  riastrad 			  CGCG_CGTT_LOCAL0_MASK | (local0 & ~CGCG_CGTT_LOCAL0_MASK) );
    431  1.1  riastrad 		WREG32_CG(CG_CGTT_LOCAL_1,
    432  1.1  riastrad 			  CGCG_CGTT_LOCAL1_MASK | (local1 & ~CGCG_CGTT_LOCAL1_MASK) );
    433  1.1  riastrad 	}
    434  1.1  riastrad }
    435  1.1  riastrad 
    436  1.1  riastrad static void trinity_mg_clockgating_initialize(struct radeon_device *rdev)
    437  1.1  riastrad {
    438  1.1  riastrad 	u32 count;
    439  1.1  riastrad 	const u32 *seq = NULL;
    440  1.1  riastrad 
    441  1.1  riastrad 	seq = &trinity_mgcg_shls_default[0];
    442  1.1  riastrad 	count = sizeof(trinity_mgcg_shls_default) / (3 * sizeof(u32));
    443  1.1  riastrad 
    444  1.1  riastrad 	trinity_program_clk_gating_hw_sequence(rdev, seq, count);
    445  1.1  riastrad }
    446  1.1  riastrad 
    447  1.1  riastrad static void trinity_gfx_clockgating_enable(struct radeon_device *rdev,
    448  1.1  riastrad 					   bool enable)
    449  1.1  riastrad {
    450  1.1  riastrad 	if (enable) {
    451  1.1  riastrad 		WREG32_P(SCLK_PWRMGT_CNTL, DYN_GFX_CLK_OFF_EN, ~DYN_GFX_CLK_OFF_EN);
    452  1.1  riastrad 	} else {
    453  1.1  riastrad 		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
    454  1.1  riastrad 		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
    455  1.1  riastrad 		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
    456  1.1  riastrad 		RREG32(GB_ADDR_CONFIG);
    457  1.1  riastrad 	}
    458  1.1  riastrad }
    459  1.1  riastrad 
    460  1.1  riastrad static void trinity_program_clk_gating_hw_sequence(struct radeon_device *rdev,
    461  1.1  riastrad 						   const u32 *seq, u32 count)
    462  1.1  riastrad {
    463  1.1  riastrad 	u32 i, length = count * 3;
    464  1.1  riastrad 
    465  1.1  riastrad 	for (i = 0; i < length; i += 3)
    466  1.1  riastrad 		WREG32_P(seq[i], seq[i+1], ~seq[i+2]);
    467  1.1  riastrad }
    468  1.1  riastrad 
    469  1.1  riastrad static void trinity_program_override_mgpg_sequences(struct radeon_device *rdev,
    470  1.1  riastrad 						    const u32 *seq, u32 count)
    471  1.1  riastrad {
    472  1.1  riastrad 	u32  i, length = count * 2;
    473  1.1  riastrad 
    474  1.1  riastrad 	for (i = 0; i < length; i += 2)
    475  1.1  riastrad 		WREG32(seq[i], seq[i+1]);
    476  1.1  riastrad 
    477  1.1  riastrad }
    478  1.1  riastrad 
    479  1.1  riastrad static void trinity_override_dynamic_mg_powergating(struct radeon_device *rdev)
    480  1.1  riastrad {
    481  1.1  riastrad 	u32 count;
    482  1.1  riastrad 	const u32 *seq = NULL;
    483  1.1  riastrad 
    484  1.1  riastrad 	seq = &trinity_override_mgpg_sequences[0];
    485  1.1  riastrad 	count = sizeof(trinity_override_mgpg_sequences) / (2 * sizeof(u32));
    486  1.1  riastrad 
    487  1.1  riastrad 	trinity_program_override_mgpg_sequences(rdev, seq, count);
    488  1.1  riastrad }
    489  1.1  riastrad 
    490  1.1  riastrad static void trinity_ls_clockgating_enable(struct radeon_device *rdev,
    491  1.1  riastrad 					  bool enable)
    492  1.1  riastrad {
    493  1.1  riastrad 	u32 count;
    494  1.1  riastrad 	const u32 *seq = NULL;
    495  1.1  riastrad 
    496  1.1  riastrad 	if (enable) {
    497  1.1  riastrad 		seq = &trinity_sysls_enable[0];
    498  1.1  riastrad 		count = sizeof(trinity_sysls_enable) / (3 * sizeof(u32));
    499  1.1  riastrad 	} else {
    500  1.1  riastrad 		seq = &trinity_sysls_disable[0];
    501  1.1  riastrad 		count = sizeof(trinity_sysls_disable) / (3 * sizeof(u32));
    502  1.1  riastrad 	}
    503  1.1  riastrad 
    504  1.1  riastrad 	trinity_program_clk_gating_hw_sequence(rdev, seq, count);
    505  1.1  riastrad }
    506  1.1  riastrad 
    507  1.1  riastrad static void trinity_gfx_powergating_enable(struct radeon_device *rdev,
    508  1.1  riastrad 					   bool enable)
    509  1.1  riastrad {
    510  1.1  riastrad 	if (enable) {
    511  1.1  riastrad 		if (RREG32_SMC(CC_SMU_TST_EFUSE1_MISC) & RB_BACKEND_DISABLE_MASK)
    512  1.1  riastrad 			WREG32_SMC(SMU_SCRATCH_A, (RREG32_SMC(SMU_SCRATCH_A) | 0x01));
    513  1.1  riastrad 
    514  1.1  riastrad 		WREG32_P(SCLK_PWRMGT_CNTL, DYN_PWR_DOWN_EN, ~DYN_PWR_DOWN_EN);
    515  1.1  riastrad 	} else {
    516  1.1  riastrad 		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_PWR_DOWN_EN);
    517  1.1  riastrad 		RREG32(GB_ADDR_CONFIG);
    518  1.1  riastrad 	}
    519  1.1  riastrad }
    520  1.1  riastrad 
    521  1.1  riastrad static void trinity_gfx_dynamic_mgpg_enable(struct radeon_device *rdev,
    522  1.1  riastrad 					    bool enable)
    523  1.1  riastrad {
    524  1.1  riastrad 	u32 value;
    525  1.1  riastrad 
    526  1.1  riastrad 	if (enable) {
    527  1.1  riastrad 		value = RREG32_SMC(PM_I_CNTL_1);
    528  1.1  riastrad 		value &= ~DS_PG_CNTL_MASK;
    529  1.1  riastrad 		value |= DS_PG_CNTL(1);
    530  1.1  riastrad 		WREG32_SMC(PM_I_CNTL_1, value);
    531  1.1  riastrad 
    532  1.1  riastrad 		value = RREG32_SMC(SMU_S_PG_CNTL);
    533  1.1  riastrad 		value &= ~DS_PG_EN_MASK;
    534  1.1  riastrad 		value |= DS_PG_EN(1);
    535  1.1  riastrad 		WREG32_SMC(SMU_S_PG_CNTL, value);
    536  1.1  riastrad 	} else {
    537  1.1  riastrad 		value = RREG32_SMC(SMU_S_PG_CNTL);
    538  1.1  riastrad 		value &= ~DS_PG_EN_MASK;
    539  1.1  riastrad 		WREG32_SMC(SMU_S_PG_CNTL, value);
    540  1.1  riastrad 
    541  1.1  riastrad 		value = RREG32_SMC(PM_I_CNTL_1);
    542  1.1  riastrad 		value &= ~DS_PG_CNTL_MASK;
    543  1.1  riastrad 		WREG32_SMC(PM_I_CNTL_1, value);
    544  1.1  riastrad 	}
    545  1.1  riastrad 
    546  1.1  riastrad 	trinity_gfx_dynamic_mgpg_config(rdev);
    547  1.1  riastrad 
    548  1.1  riastrad }
    549  1.1  riastrad 
    550  1.1  riastrad static void trinity_enable_clock_power_gating(struct radeon_device *rdev)
    551  1.1  riastrad {
    552  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
    553  1.1  riastrad 
    554  1.1  riastrad 	if (pi->enable_gfx_clock_gating)
    555  1.1  riastrad 		sumo_gfx_clockgating_initialize(rdev);
    556  1.1  riastrad 	if (pi->enable_mg_clock_gating)
    557  1.1  riastrad 		trinity_mg_clockgating_initialize(rdev);
    558  1.1  riastrad 	if (pi->enable_gfx_power_gating)
    559  1.1  riastrad 		trinity_gfx_powergating_initialize(rdev);
    560  1.1  riastrad 	if (pi->enable_mg_clock_gating) {
    561  1.1  riastrad 		trinity_ls_clockgating_enable(rdev, true);
    562  1.1  riastrad 		trinity_mg_clockgating_enable(rdev, true);
    563  1.1  riastrad 	}
    564  1.1  riastrad 	if (pi->enable_gfx_clock_gating)
    565  1.1  riastrad 		trinity_gfx_clockgating_enable(rdev, true);
    566  1.1  riastrad 	if (pi->enable_gfx_dynamic_mgpg)
    567  1.1  riastrad 		trinity_gfx_dynamic_mgpg_enable(rdev, true);
    568  1.1  riastrad 	if (pi->enable_gfx_power_gating)
    569  1.1  riastrad 		trinity_gfx_powergating_enable(rdev, true);
    570  1.1  riastrad }
    571  1.1  riastrad 
    572  1.1  riastrad static void trinity_disable_clock_power_gating(struct radeon_device *rdev)
    573  1.1  riastrad {
    574  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
    575  1.1  riastrad 
    576  1.1  riastrad 	if (pi->enable_gfx_power_gating)
    577  1.1  riastrad 		trinity_gfx_powergating_enable(rdev, false);
    578  1.1  riastrad 	if (pi->enable_gfx_dynamic_mgpg)
    579  1.1  riastrad 		trinity_gfx_dynamic_mgpg_enable(rdev, false);
    580  1.1  riastrad 	if (pi->enable_gfx_clock_gating)
    581  1.1  riastrad 		trinity_gfx_clockgating_enable(rdev, false);
    582  1.1  riastrad 	if (pi->enable_mg_clock_gating) {
    583  1.1  riastrad 		trinity_mg_clockgating_enable(rdev, false);
    584  1.1  riastrad 		trinity_ls_clockgating_enable(rdev, false);
    585  1.1  riastrad 	}
    586  1.1  riastrad }
    587  1.1  riastrad 
    588  1.1  riastrad static void trinity_set_divider_value(struct radeon_device *rdev,
    589  1.1  riastrad 				      u32 index, u32 sclk)
    590  1.1  riastrad {
    591  1.1  riastrad 	struct atom_clock_dividers  dividers;
    592  1.1  riastrad 	int ret;
    593  1.1  riastrad 	u32 value;
    594  1.1  riastrad 	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
    595  1.1  riastrad 
    596  1.3  riastrad 	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
    597  1.3  riastrad 					     sclk, false, &dividers);
    598  1.1  riastrad 	if (ret)
    599  1.1  riastrad 		return;
    600  1.1  riastrad 
    601  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
    602  1.1  riastrad 	value &= ~CLK_DIVIDER_MASK;
    603  1.1  riastrad 	value |= CLK_DIVIDER(dividers.post_div);
    604  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
    605  1.1  riastrad 
    606  1.3  riastrad 	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
    607  1.3  riastrad 					     sclk/2, false, &dividers);
    608  1.1  riastrad 	if (ret)
    609  1.1  riastrad 		return;
    610  1.1  riastrad 
    611  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix);
    612  1.1  riastrad 	value &= ~PD_SCLK_DIVIDER_MASK;
    613  1.1  riastrad 	value |= PD_SCLK_DIVIDER(dividers.post_div);
    614  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_PG_CNTL + ix, value);
    615  1.1  riastrad }
    616  1.1  riastrad 
    617  1.1  riastrad static void trinity_set_ds_dividers(struct radeon_device *rdev,
    618  1.1  riastrad 				    u32 index, u32 divider)
    619  1.1  riastrad {
    620  1.1  riastrad 	u32 value;
    621  1.1  riastrad 	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
    622  1.1  riastrad 
    623  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
    624  1.1  riastrad 	value &= ~DS_DIV_MASK;
    625  1.1  riastrad 	value |= DS_DIV(divider);
    626  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
    627  1.1  riastrad }
    628  1.1  riastrad 
    629  1.1  riastrad static void trinity_set_ss_dividers(struct radeon_device *rdev,
    630  1.1  riastrad 				    u32 index, u32 divider)
    631  1.1  riastrad {
    632  1.1  riastrad 	u32 value;
    633  1.1  riastrad 	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
    634  1.1  riastrad 
    635  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
    636  1.1  riastrad 	value &= ~DS_SH_DIV_MASK;
    637  1.1  riastrad 	value |= DS_SH_DIV(divider);
    638  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
    639  1.1  riastrad }
    640  1.1  riastrad 
    641  1.1  riastrad static void trinity_set_vid(struct radeon_device *rdev, u32 index, u32 vid)
    642  1.1  riastrad {
    643  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
    644  1.1  riastrad 	u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid);
    645  1.1  riastrad 	u32 value;
    646  1.1  riastrad 	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
    647  1.1  riastrad 
    648  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
    649  1.1  riastrad 	value &= ~VID_MASK;
    650  1.1  riastrad 	value |= VID(vid_7bit);
    651  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
    652  1.1  riastrad 
    653  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
    654  1.1  riastrad 	value &= ~LVRT_MASK;
    655  1.1  riastrad 	value |= LVRT(0);
    656  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
    657  1.1  riastrad }
    658  1.1  riastrad 
    659  1.1  riastrad static void trinity_set_allos_gnb_slow(struct radeon_device *rdev,
    660  1.1  riastrad 				       u32 index, u32 gnb_slow)
    661  1.1  riastrad {
    662  1.1  riastrad 	u32 value;
    663  1.1  riastrad 	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
    664  1.1  riastrad 
    665  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix);
    666  1.1  riastrad 	value &= ~GNB_SLOW_MASK;
    667  1.1  riastrad 	value |= GNB_SLOW(gnb_slow);
    668  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value);
    669  1.1  riastrad }
    670  1.1  riastrad 
    671  1.1  riastrad static void trinity_set_force_nbp_state(struct radeon_device *rdev,
    672  1.1  riastrad 					u32 index, u32 force_nbp_state)
    673  1.1  riastrad {
    674  1.1  riastrad 	u32 value;
    675  1.1  riastrad 	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
    676  1.1  riastrad 
    677  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix);
    678  1.1  riastrad 	value &= ~FORCE_NBPS1_MASK;
    679  1.1  riastrad 	value |= FORCE_NBPS1(force_nbp_state);
    680  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_3 + ix, value);
    681  1.1  riastrad }
    682  1.1  riastrad 
    683  1.1  riastrad static void trinity_set_display_wm(struct radeon_device *rdev,
    684  1.1  riastrad 				   u32 index, u32 wm)
    685  1.1  riastrad {
    686  1.1  riastrad 	u32 value;
    687  1.1  riastrad 	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
    688  1.1  riastrad 
    689  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
    690  1.1  riastrad 	value &= ~DISPLAY_WM_MASK;
    691  1.1  riastrad 	value |= DISPLAY_WM(wm);
    692  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
    693  1.1  riastrad }
    694  1.1  riastrad 
    695  1.1  riastrad static void trinity_set_vce_wm(struct radeon_device *rdev,
    696  1.1  riastrad 			       u32 index, u32 wm)
    697  1.1  riastrad {
    698  1.1  riastrad 	u32 value;
    699  1.1  riastrad 	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
    700  1.1  riastrad 
    701  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix);
    702  1.1  riastrad 	value &= ~VCE_WM_MASK;
    703  1.1  riastrad 	value |= VCE_WM(wm);
    704  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_1 + ix, value);
    705  1.1  riastrad }
    706  1.1  riastrad 
    707  1.1  riastrad static void trinity_set_at(struct radeon_device *rdev,
    708  1.1  riastrad 			   u32 index, u32 at)
    709  1.1  riastrad {
    710  1.1  riastrad 	u32 value;
    711  1.1  riastrad 	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
    712  1.1  riastrad 
    713  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix);
    714  1.1  riastrad 	value &= ~AT_MASK;
    715  1.1  riastrad 	value |= AT(at);
    716  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_AT + ix, value);
    717  1.1  riastrad }
    718  1.1  riastrad 
    719  1.1  riastrad static void trinity_program_power_level(struct radeon_device *rdev,
    720  1.1  riastrad 					struct trinity_pl *pl, u32 index)
    721  1.1  riastrad {
    722  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
    723  1.1  riastrad 
    724  1.1  riastrad 	if (index >= SUMO_MAX_HARDWARE_POWERLEVELS)
    725  1.1  riastrad 		return;
    726  1.1  riastrad 
    727  1.1  riastrad 	trinity_set_divider_value(rdev, index, pl->sclk);
    728  1.1  riastrad 	trinity_set_vid(rdev, index, pl->vddc_index);
    729  1.1  riastrad 	trinity_set_ss_dividers(rdev, index, pl->ss_divider_index);
    730  1.1  riastrad 	trinity_set_ds_dividers(rdev, index, pl->ds_divider_index);
    731  1.1  riastrad 	trinity_set_allos_gnb_slow(rdev, index, pl->allow_gnb_slow);
    732  1.1  riastrad 	trinity_set_force_nbp_state(rdev, index, pl->force_nbp_state);
    733  1.1  riastrad 	trinity_set_display_wm(rdev, index, pl->display_wm);
    734  1.1  riastrad 	trinity_set_vce_wm(rdev, index, pl->vce_wm);
    735  1.1  riastrad 	trinity_set_at(rdev, index, pi->at[index]);
    736  1.1  riastrad }
    737  1.1  riastrad 
    738  1.1  riastrad static void trinity_power_level_enable_disable(struct radeon_device *rdev,
    739  1.1  riastrad 					       u32 index, bool enable)
    740  1.1  riastrad {
    741  1.1  riastrad 	u32 value;
    742  1.1  riastrad 	u32 ix = index * TRINITY_SIZEOF_DPM_STATE_TABLE;
    743  1.1  riastrad 
    744  1.1  riastrad 	value = RREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix);
    745  1.1  riastrad 	value &= ~STATE_VALID_MASK;
    746  1.1  riastrad 	if (enable)
    747  1.1  riastrad 		value |= STATE_VALID(1);
    748  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_STATE_0_CNTL_0 + ix, value);
    749  1.1  riastrad }
    750  1.1  riastrad 
    751  1.1  riastrad static bool trinity_dpm_enabled(struct radeon_device *rdev)
    752  1.1  riastrad {
    753  1.1  riastrad 	if (RREG32_SMC(SMU_SCLK_DPM_CNTL) & SCLK_DPM_EN(1))
    754  1.1  riastrad 		return true;
    755  1.1  riastrad 	else
    756  1.1  riastrad 		return false;
    757  1.1  riastrad }
    758  1.1  riastrad 
    759  1.1  riastrad static void trinity_start_dpm(struct radeon_device *rdev)
    760  1.1  riastrad {
    761  1.1  riastrad 	u32 value = RREG32_SMC(SMU_SCLK_DPM_CNTL);
    762  1.1  riastrad 
    763  1.1  riastrad 	value &= ~(SCLK_DPM_EN_MASK | SCLK_DPM_BOOT_STATE_MASK | VOLTAGE_CHG_EN_MASK);
    764  1.1  riastrad 	value |= SCLK_DPM_EN(1) | SCLK_DPM_BOOT_STATE(0) | VOLTAGE_CHG_EN(1);
    765  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_CNTL, value);
    766  1.1  riastrad 
    767  1.1  riastrad 	WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
    768  1.1  riastrad 	WREG32_P(CG_CG_VOLTAGE_CNTL, 0, ~EN);
    769  1.1  riastrad 
    770  1.1  riastrad 	trinity_dpm_config(rdev, true);
    771  1.1  riastrad }
    772  1.1  riastrad 
    773  1.1  riastrad static void trinity_wait_for_dpm_enabled(struct radeon_device *rdev)
    774  1.1  riastrad {
    775  1.1  riastrad 	int i;
    776  1.1  riastrad 
    777  1.1  riastrad 	for (i = 0; i < rdev->usec_timeout; i++) {
    778  1.1  riastrad 		if (RREG32(SCLK_PWRMGT_CNTL) & DYNAMIC_PM_EN)
    779  1.1  riastrad 			break;
    780  1.1  riastrad 		udelay(1);
    781  1.1  riastrad 	}
    782  1.1  riastrad 	for (i = 0; i < rdev->usec_timeout; i++) {
    783  1.1  riastrad 		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_STATE_MASK) == 0)
    784  1.1  riastrad 			break;
    785  1.1  riastrad 		udelay(1);
    786  1.1  riastrad 	}
    787  1.1  riastrad 	for (i = 0; i < rdev->usec_timeout; i++) {
    788  1.1  riastrad 		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0)
    789  1.1  riastrad 			break;
    790  1.1  riastrad 		udelay(1);
    791  1.1  riastrad 	}
    792  1.1  riastrad }
    793  1.1  riastrad 
    794  1.1  riastrad static void trinity_stop_dpm(struct radeon_device *rdev)
    795  1.1  riastrad {
    796  1.1  riastrad 	u32 sclk_dpm_cntl;
    797  1.1  riastrad 
    798  1.1  riastrad 	WREG32_P(CG_CG_VOLTAGE_CNTL, EN, ~EN);
    799  1.1  riastrad 
    800  1.1  riastrad 	sclk_dpm_cntl = RREG32_SMC(SMU_SCLK_DPM_CNTL);
    801  1.1  riastrad 	sclk_dpm_cntl &= ~(SCLK_DPM_EN_MASK | VOLTAGE_CHG_EN_MASK);
    802  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_CNTL, sclk_dpm_cntl);
    803  1.1  riastrad 
    804  1.1  riastrad 	trinity_dpm_config(rdev, false);
    805  1.1  riastrad }
    806  1.1  riastrad 
    807  1.1  riastrad static void trinity_start_am(struct radeon_device *rdev)
    808  1.1  riastrad {
    809  1.1  riastrad 	WREG32_P(SCLK_PWRMGT_CNTL, 0, ~(RESET_SCLK_CNT | RESET_BUSY_CNT));
    810  1.1  riastrad }
    811  1.1  riastrad 
    812  1.1  riastrad static void trinity_reset_am(struct radeon_device *rdev)
    813  1.1  riastrad {
    814  1.1  riastrad 	WREG32_P(SCLK_PWRMGT_CNTL, RESET_SCLK_CNT | RESET_BUSY_CNT,
    815  1.1  riastrad 		 ~(RESET_SCLK_CNT | RESET_BUSY_CNT));
    816  1.1  riastrad }
    817  1.1  riastrad 
    818  1.1  riastrad static void trinity_wait_for_level_0(struct radeon_device *rdev)
    819  1.1  riastrad {
    820  1.1  riastrad 	int i;
    821  1.1  riastrad 
    822  1.1  riastrad 	for (i = 0; i < rdev->usec_timeout; i++) {
    823  1.1  riastrad 		if ((RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) == 0)
    824  1.1  riastrad 			break;
    825  1.1  riastrad 		udelay(1);
    826  1.1  riastrad 	}
    827  1.1  riastrad }
    828  1.1  riastrad 
    829  1.1  riastrad static void trinity_enable_power_level_0(struct radeon_device *rdev)
    830  1.1  riastrad {
    831  1.1  riastrad 	trinity_power_level_enable_disable(rdev, 0, true);
    832  1.1  riastrad }
    833  1.1  riastrad 
    834  1.1  riastrad static void trinity_force_level_0(struct radeon_device *rdev)
    835  1.1  riastrad {
    836  1.1  riastrad 	trinity_dpm_force_state(rdev, 0);
    837  1.1  riastrad }
    838  1.1  riastrad 
    839  1.1  riastrad static void trinity_unforce_levels(struct radeon_device *rdev)
    840  1.1  riastrad {
    841  1.1  riastrad 	trinity_dpm_no_forced_level(rdev);
    842  1.1  riastrad }
    843  1.1  riastrad 
    844  1.1  riastrad static void trinity_program_power_levels_0_to_n(struct radeon_device *rdev,
    845  1.1  riastrad 						struct radeon_ps *new_rps,
    846  1.1  riastrad 						struct radeon_ps *old_rps)
    847  1.1  riastrad {
    848  1.1  riastrad 	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
    849  1.1  riastrad 	struct trinity_ps *old_ps = trinity_get_ps(old_rps);
    850  1.1  riastrad 	u32 i;
    851  1.1  riastrad 	u32 n_current_state_levels = (old_ps == NULL) ? 1 : old_ps->num_levels;
    852  1.1  riastrad 
    853  1.1  riastrad 	for (i = 0; i < new_ps->num_levels; i++) {
    854  1.1  riastrad 		trinity_program_power_level(rdev, &new_ps->levels[i], i);
    855  1.1  riastrad 		trinity_power_level_enable_disable(rdev, i, true);
    856  1.1  riastrad 	}
    857  1.1  riastrad 
    858  1.1  riastrad 	for (i = new_ps->num_levels; i < n_current_state_levels; i++)
    859  1.1  riastrad 		trinity_power_level_enable_disable(rdev, i, false);
    860  1.1  riastrad }
    861  1.1  riastrad 
    862  1.1  riastrad static void trinity_program_bootup_state(struct radeon_device *rdev)
    863  1.1  riastrad {
    864  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
    865  1.1  riastrad 	u32 i;
    866  1.1  riastrad 
    867  1.1  riastrad 	trinity_program_power_level(rdev, &pi->boot_pl, 0);
    868  1.1  riastrad 	trinity_power_level_enable_disable(rdev, 0, true);
    869  1.1  riastrad 
    870  1.1  riastrad 	for (i = 1; i < 8; i++)
    871  1.1  riastrad 		trinity_power_level_enable_disable(rdev, i, false);
    872  1.1  riastrad }
    873  1.1  riastrad 
    874  1.1  riastrad static void trinity_setup_uvd_clock_table(struct radeon_device *rdev,
    875  1.1  riastrad 					  struct radeon_ps *rps)
    876  1.1  riastrad {
    877  1.1  riastrad 	struct trinity_ps *ps = trinity_get_ps(rps);
    878  1.1  riastrad 	u32 uvdstates = (ps->vclk_low_divider |
    879  1.1  riastrad 			 ps->vclk_high_divider << 8 |
    880  1.1  riastrad 			 ps->dclk_low_divider << 16 |
    881  1.1  riastrad 			 ps->dclk_high_divider << 24);
    882  1.1  riastrad 
    883  1.1  riastrad 	WREG32_SMC(SMU_UVD_DPM_STATES, uvdstates);
    884  1.1  riastrad }
    885  1.1  riastrad 
    886  1.1  riastrad static void trinity_setup_uvd_dpm_interval(struct radeon_device *rdev,
    887  1.1  riastrad 					   u32 interval)
    888  1.1  riastrad {
    889  1.1  riastrad 	u32 p, u;
    890  1.1  riastrad 	u32 tp = RREG32_SMC(PM_TP);
    891  1.1  riastrad 	u32 val;
    892  1.1  riastrad 	u32 xclk = radeon_get_xclk(rdev);
    893  1.1  riastrad 
    894  1.1  riastrad 	r600_calculate_u_and_p(interval, xclk, 16, &p, &u);
    895  1.1  riastrad 
    896  1.1  riastrad 	val = (p + tp - 1) / tp;
    897  1.1  riastrad 
    898  1.1  riastrad 	WREG32_SMC(SMU_UVD_DPM_CNTL, val);
    899  1.1  riastrad }
    900  1.1  riastrad 
    901  1.1  riastrad static bool trinity_uvd_clocks_zero(struct radeon_ps *rps)
    902  1.1  riastrad {
    903  1.1  riastrad 	if ((rps->vclk == 0) && (rps->dclk == 0))
    904  1.1  riastrad 		return true;
    905  1.1  riastrad 	else
    906  1.1  riastrad 		return false;
    907  1.1  riastrad }
    908  1.1  riastrad 
    909  1.1  riastrad static bool trinity_uvd_clocks_equal(struct radeon_ps *rps1,
    910  1.1  riastrad 				     struct radeon_ps *rps2)
    911  1.1  riastrad {
    912  1.1  riastrad 	struct trinity_ps *ps1 = trinity_get_ps(rps1);
    913  1.1  riastrad 	struct trinity_ps *ps2 = trinity_get_ps(rps2);
    914  1.1  riastrad 
    915  1.1  riastrad 	if ((rps1->vclk == rps2->vclk) &&
    916  1.1  riastrad 	    (rps1->dclk == rps2->dclk) &&
    917  1.1  riastrad 	    (ps1->vclk_low_divider == ps2->vclk_low_divider) &&
    918  1.1  riastrad 	    (ps1->vclk_high_divider == ps2->vclk_high_divider) &&
    919  1.1  riastrad 	    (ps1->dclk_low_divider == ps2->dclk_low_divider) &&
    920  1.1  riastrad 	    (ps1->dclk_high_divider == ps2->dclk_high_divider))
    921  1.1  riastrad 		return true;
    922  1.1  riastrad 	else
    923  1.1  riastrad 		return false;
    924  1.1  riastrad }
    925  1.1  riastrad 
    926  1.1  riastrad static void trinity_setup_uvd_clocks(struct radeon_device *rdev,
    927  1.1  riastrad 				     struct radeon_ps *new_rps,
    928  1.1  riastrad 				     struct radeon_ps *old_rps)
    929  1.1  riastrad {
    930  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
    931  1.1  riastrad 
    932  1.1  riastrad 	if (pi->enable_gfx_power_gating) {
    933  1.1  riastrad 		trinity_gfx_powergating_enable(rdev, false);
    934  1.1  riastrad 	}
    935  1.1  riastrad 
    936  1.1  riastrad 	if (pi->uvd_dpm) {
    937  1.1  riastrad 		if (trinity_uvd_clocks_zero(new_rps) &&
    938  1.1  riastrad 		    !trinity_uvd_clocks_zero(old_rps)) {
    939  1.1  riastrad 			trinity_setup_uvd_dpm_interval(rdev, 0);
    940  1.1  riastrad 		} else if (!trinity_uvd_clocks_zero(new_rps)) {
    941  1.1  riastrad 			trinity_setup_uvd_clock_table(rdev, new_rps);
    942  1.1  riastrad 
    943  1.1  riastrad 			if (trinity_uvd_clocks_zero(old_rps)) {
    944  1.1  riastrad 				u32 tmp = RREG32(CG_MISC_REG);
    945  1.1  riastrad 				tmp &= 0xfffffffd;
    946  1.1  riastrad 				WREG32(CG_MISC_REG, tmp);
    947  1.1  riastrad 
    948  1.1  riastrad 				radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
    949  1.1  riastrad 
    950  1.1  riastrad 				trinity_setup_uvd_dpm_interval(rdev, 3000);
    951  1.1  riastrad 			}
    952  1.1  riastrad 		}
    953  1.1  riastrad 		trinity_uvd_dpm_config(rdev);
    954  1.1  riastrad 	} else {
    955  1.1  riastrad 		if (trinity_uvd_clocks_zero(new_rps) ||
    956  1.1  riastrad 		    trinity_uvd_clocks_equal(new_rps, old_rps))
    957  1.1  riastrad 			return;
    958  1.1  riastrad 
    959  1.1  riastrad 		radeon_set_uvd_clocks(rdev, new_rps->vclk, new_rps->dclk);
    960  1.1  riastrad 	}
    961  1.1  riastrad 
    962  1.1  riastrad 	if (pi->enable_gfx_power_gating) {
    963  1.1  riastrad 		trinity_gfx_powergating_enable(rdev, true);
    964  1.1  riastrad 	}
    965  1.1  riastrad }
    966  1.1  riastrad 
    967  1.1  riastrad static void trinity_set_uvd_clock_before_set_eng_clock(struct radeon_device *rdev,
    968  1.1  riastrad 						       struct radeon_ps *new_rps,
    969  1.1  riastrad 						       struct radeon_ps *old_rps)
    970  1.1  riastrad {
    971  1.1  riastrad 	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
    972  1.1  riastrad 	struct trinity_ps *current_ps = trinity_get_ps(new_rps);
    973  1.1  riastrad 
    974  1.1  riastrad 	if (new_ps->levels[new_ps->num_levels - 1].sclk >=
    975  1.1  riastrad 	    current_ps->levels[current_ps->num_levels - 1].sclk)
    976  1.1  riastrad 		return;
    977  1.1  riastrad 
    978  1.1  riastrad 	trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
    979  1.1  riastrad }
    980  1.1  riastrad 
    981  1.1  riastrad static void trinity_set_uvd_clock_after_set_eng_clock(struct radeon_device *rdev,
    982  1.1  riastrad 						      struct radeon_ps *new_rps,
    983  1.1  riastrad 						      struct radeon_ps *old_rps)
    984  1.1  riastrad {
    985  1.1  riastrad 	struct trinity_ps *new_ps = trinity_get_ps(new_rps);
    986  1.1  riastrad 	struct trinity_ps *current_ps = trinity_get_ps(old_rps);
    987  1.1  riastrad 
    988  1.1  riastrad 	if (new_ps->levels[new_ps->num_levels - 1].sclk <
    989  1.1  riastrad 	    current_ps->levels[current_ps->num_levels - 1].sclk)
    990  1.1  riastrad 		return;
    991  1.1  riastrad 
    992  1.1  riastrad 	trinity_setup_uvd_clocks(rdev, new_rps, old_rps);
    993  1.1  riastrad }
    994  1.1  riastrad 
    995  1.1  riastrad static void trinity_set_vce_clock(struct radeon_device *rdev,
    996  1.1  riastrad 				  struct radeon_ps *new_rps,
    997  1.1  riastrad 				  struct radeon_ps *old_rps)
    998  1.1  riastrad {
    999  1.1  riastrad 	if ((old_rps->evclk != new_rps->evclk) ||
   1000  1.1  riastrad 	    (old_rps->ecclk != new_rps->ecclk)) {
   1001  1.1  riastrad 		/* turn the clocks on when encoding, off otherwise */
   1002  1.1  riastrad 		if (new_rps->evclk || new_rps->ecclk)
   1003  1.1  riastrad 			vce_v1_0_enable_mgcg(rdev, false);
   1004  1.1  riastrad 		else
   1005  1.1  riastrad 			vce_v1_0_enable_mgcg(rdev, true);
   1006  1.1  riastrad 		radeon_set_vce_clocks(rdev, new_rps->evclk, new_rps->ecclk);
   1007  1.1  riastrad 	}
   1008  1.1  riastrad }
   1009  1.1  riastrad 
   1010  1.1  riastrad static void trinity_program_ttt(struct radeon_device *rdev)
   1011  1.1  riastrad {
   1012  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1013  1.1  riastrad 	u32 value = RREG32_SMC(SMU_SCLK_DPM_TTT);
   1014  1.1  riastrad 
   1015  1.1  riastrad 	value &= ~(HT_MASK | LT_MASK);
   1016  1.1  riastrad 	value |= HT((pi->thermal_auto_throttling + 49) * 8);
   1017  1.1  riastrad 	value |= LT((pi->thermal_auto_throttling + 49 - pi->sys_info.htc_hyst_lmt) * 8);
   1018  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_TTT, value);
   1019  1.1  riastrad }
   1020  1.1  riastrad 
   1021  1.1  riastrad static void trinity_enable_att(struct radeon_device *rdev)
   1022  1.1  riastrad {
   1023  1.1  riastrad 	u32 value = RREG32_SMC(SMU_SCLK_DPM_TT_CNTL);
   1024  1.1  riastrad 
   1025  1.1  riastrad 	value &= ~SCLK_TT_EN_MASK;
   1026  1.1  riastrad 	value |= SCLK_TT_EN(1);
   1027  1.1  riastrad 	WREG32_SMC(SMU_SCLK_DPM_TT_CNTL, value);
   1028  1.1  riastrad }
   1029  1.1  riastrad 
   1030  1.1  riastrad static void trinity_program_sclk_dpm(struct radeon_device *rdev)
   1031  1.1  riastrad {
   1032  1.1  riastrad 	u32 p, u;
   1033  1.1  riastrad 	u32 tp = RREG32_SMC(PM_TP);
   1034  1.1  riastrad 	u32 ni;
   1035  1.1  riastrad 	u32 xclk = radeon_get_xclk(rdev);
   1036  1.1  riastrad 	u32 value;
   1037  1.1  riastrad 
   1038  1.1  riastrad 	r600_calculate_u_and_p(400, xclk, 16, &p, &u);
   1039  1.1  riastrad 
   1040  1.1  riastrad 	ni = (p + tp - 1) / tp;
   1041  1.1  riastrad 
   1042  1.1  riastrad 	value = RREG32_SMC(PM_I_CNTL_1);
   1043  1.1  riastrad 	value &= ~SCLK_DPM_MASK;
   1044  1.1  riastrad 	value |= SCLK_DPM(ni);
   1045  1.1  riastrad 	WREG32_SMC(PM_I_CNTL_1, value);
   1046  1.1  riastrad }
   1047  1.1  riastrad 
   1048  1.1  riastrad static int trinity_set_thermal_temperature_range(struct radeon_device *rdev,
   1049  1.1  riastrad 						 int min_temp, int max_temp)
   1050  1.1  riastrad {
   1051  1.1  riastrad 	int low_temp = 0 * 1000;
   1052  1.1  riastrad 	int high_temp = 255 * 1000;
   1053  1.1  riastrad 
   1054  1.3  riastrad 	if (low_temp < min_temp)
   1055  1.1  riastrad 		low_temp = min_temp;
   1056  1.3  riastrad 	if (high_temp > max_temp)
   1057  1.1  riastrad 		high_temp = max_temp;
   1058  1.3  riastrad 	if (high_temp < low_temp) {
   1059  1.1  riastrad 		DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
   1060  1.3  riastrad 		return -EINVAL;
   1061  1.3  riastrad 	}
   1062  1.1  riastrad 
   1063  1.1  riastrad 	WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTH(49 + (high_temp / 1000)), ~DIG_THERM_INTH_MASK);
   1064  1.1  riastrad 	WREG32_P(CG_THERMAL_INT_CTRL, DIG_THERM_INTL(49 + (low_temp / 1000)), ~DIG_THERM_INTL_MASK);
   1065  1.1  riastrad 
   1066  1.1  riastrad 	rdev->pm.dpm.thermal.min_temp = low_temp;
   1067  1.1  riastrad 	rdev->pm.dpm.thermal.max_temp = high_temp;
   1068  1.1  riastrad 
   1069  1.1  riastrad 	return 0;
   1070  1.1  riastrad }
   1071  1.1  riastrad 
   1072  1.1  riastrad static void trinity_update_current_ps(struct radeon_device *rdev,
   1073  1.1  riastrad 				      struct radeon_ps *rps)
   1074  1.1  riastrad {
   1075  1.1  riastrad 	struct trinity_ps *new_ps = trinity_get_ps(rps);
   1076  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1077  1.1  riastrad 
   1078  1.1  riastrad 	pi->current_rps = *rps;
   1079  1.1  riastrad 	pi->current_ps = *new_ps;
   1080  1.1  riastrad 	pi->current_rps.ps_priv = &pi->current_ps;
   1081  1.1  riastrad }
   1082  1.1  riastrad 
   1083  1.1  riastrad static void trinity_update_requested_ps(struct radeon_device *rdev,
   1084  1.1  riastrad 					struct radeon_ps *rps)
   1085  1.1  riastrad {
   1086  1.1  riastrad 	struct trinity_ps *new_ps = trinity_get_ps(rps);
   1087  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1088  1.1  riastrad 
   1089  1.1  riastrad 	pi->requested_rps = *rps;
   1090  1.1  riastrad 	pi->requested_ps = *new_ps;
   1091  1.1  riastrad 	pi->requested_rps.ps_priv = &pi->requested_ps;
   1092  1.1  riastrad }
   1093  1.1  riastrad 
   1094  1.1  riastrad void trinity_dpm_enable_bapm(struct radeon_device *rdev, bool enable)
   1095  1.1  riastrad {
   1096  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1097  1.1  riastrad 
   1098  1.1  riastrad 	if (pi->enable_bapm) {
   1099  1.1  riastrad 		trinity_acquire_mutex(rdev);
   1100  1.1  riastrad 		trinity_dpm_bapm_enable(rdev, enable);
   1101  1.1  riastrad 		trinity_release_mutex(rdev);
   1102  1.1  riastrad 	}
   1103  1.1  riastrad }
   1104  1.1  riastrad 
   1105  1.1  riastrad int trinity_dpm_enable(struct radeon_device *rdev)
   1106  1.1  riastrad {
   1107  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1108  1.1  riastrad 
   1109  1.1  riastrad 	trinity_acquire_mutex(rdev);
   1110  1.1  riastrad 
   1111  1.1  riastrad 	if (trinity_dpm_enabled(rdev)) {
   1112  1.1  riastrad 		trinity_release_mutex(rdev);
   1113  1.1  riastrad 		return -EINVAL;
   1114  1.1  riastrad 	}
   1115  1.1  riastrad 
   1116  1.1  riastrad 	trinity_program_bootup_state(rdev);
   1117  1.1  riastrad 	sumo_program_vc(rdev, 0x00C00033);
   1118  1.1  riastrad 	trinity_start_am(rdev);
   1119  1.1  riastrad 	if (pi->enable_auto_thermal_throttling) {
   1120  1.1  riastrad 		trinity_program_ttt(rdev);
   1121  1.1  riastrad 		trinity_enable_att(rdev);
   1122  1.1  riastrad 	}
   1123  1.1  riastrad 	trinity_program_sclk_dpm(rdev);
   1124  1.1  riastrad 	trinity_start_dpm(rdev);
   1125  1.1  riastrad 	trinity_wait_for_dpm_enabled(rdev);
   1126  1.1  riastrad 	trinity_dpm_bapm_enable(rdev, false);
   1127  1.1  riastrad 	trinity_release_mutex(rdev);
   1128  1.1  riastrad 
   1129  1.1  riastrad 	trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
   1130  1.1  riastrad 
   1131  1.1  riastrad 	return 0;
   1132  1.1  riastrad }
   1133  1.1  riastrad 
   1134  1.1  riastrad int trinity_dpm_late_enable(struct radeon_device *rdev)
   1135  1.1  riastrad {
   1136  1.1  riastrad 	int ret;
   1137  1.1  riastrad 
   1138  1.1  riastrad 	trinity_acquire_mutex(rdev);
   1139  1.1  riastrad 	trinity_enable_clock_power_gating(rdev);
   1140  1.1  riastrad 
   1141  1.1  riastrad 	if (rdev->irq.installed &&
   1142  1.1  riastrad 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
   1143  1.1  riastrad 		ret = trinity_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
   1144  1.1  riastrad 		if (ret) {
   1145  1.1  riastrad 			trinity_release_mutex(rdev);
   1146  1.1  riastrad 			return ret;
   1147  1.1  riastrad 		}
   1148  1.1  riastrad 		rdev->irq.dpm_thermal = true;
   1149  1.1  riastrad 		radeon_irq_set(rdev);
   1150  1.1  riastrad 	}
   1151  1.1  riastrad 	trinity_release_mutex(rdev);
   1152  1.1  riastrad 
   1153  1.1  riastrad 	return 0;
   1154  1.1  riastrad }
   1155  1.1  riastrad 
   1156  1.1  riastrad void trinity_dpm_disable(struct radeon_device *rdev)
   1157  1.1  riastrad {
   1158  1.1  riastrad 	trinity_acquire_mutex(rdev);
   1159  1.1  riastrad 	if (!trinity_dpm_enabled(rdev)) {
   1160  1.1  riastrad 		trinity_release_mutex(rdev);
   1161  1.1  riastrad 		return;
   1162  1.1  riastrad 	}
   1163  1.1  riastrad 	trinity_dpm_bapm_enable(rdev, false);
   1164  1.1  riastrad 	trinity_disable_clock_power_gating(rdev);
   1165  1.1  riastrad 	sumo_clear_vc(rdev);
   1166  1.1  riastrad 	trinity_wait_for_level_0(rdev);
   1167  1.1  riastrad 	trinity_stop_dpm(rdev);
   1168  1.1  riastrad 	trinity_reset_am(rdev);
   1169  1.1  riastrad 	trinity_release_mutex(rdev);
   1170  1.1  riastrad 
   1171  1.1  riastrad 	if (rdev->irq.installed &&
   1172  1.1  riastrad 	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
   1173  1.1  riastrad 		rdev->irq.dpm_thermal = false;
   1174  1.1  riastrad 		radeon_irq_set(rdev);
   1175  1.1  riastrad 	}
   1176  1.1  riastrad 
   1177  1.1  riastrad 	trinity_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
   1178  1.1  riastrad }
   1179  1.1  riastrad 
   1180  1.1  riastrad static void trinity_get_min_sclk_divider(struct radeon_device *rdev)
   1181  1.1  riastrad {
   1182  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1183  1.1  riastrad 
   1184  1.1  riastrad 	pi->min_sclk_did =
   1185  1.1  riastrad 		(RREG32_SMC(CC_SMU_MISC_FUSES) & MinSClkDid_MASK) >> MinSClkDid_SHIFT;
   1186  1.1  riastrad }
   1187  1.1  riastrad 
   1188  1.1  riastrad static void trinity_setup_nbp_sim(struct radeon_device *rdev,
   1189  1.1  riastrad 				  struct radeon_ps *rps)
   1190  1.1  riastrad {
   1191  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1192  1.1  riastrad 	struct trinity_ps *new_ps = trinity_get_ps(rps);
   1193  1.1  riastrad 	u32 nbpsconfig;
   1194  1.1  riastrad 
   1195  1.1  riastrad 	if (pi->sys_info.nb_dpm_enable) {
   1196  1.1  riastrad 		nbpsconfig = RREG32_SMC(NB_PSTATE_CONFIG);
   1197  1.1  riastrad 		nbpsconfig &= ~(Dpm0PgNbPsLo_MASK | Dpm0PgNbPsHi_MASK | DpmXNbPsLo_MASK | DpmXNbPsHi_MASK);
   1198  1.1  riastrad 		nbpsconfig |= (Dpm0PgNbPsLo(new_ps->Dpm0PgNbPsLo) |
   1199  1.1  riastrad 			       Dpm0PgNbPsHi(new_ps->Dpm0PgNbPsHi) |
   1200  1.1  riastrad 			       DpmXNbPsLo(new_ps->DpmXNbPsLo) |
   1201  1.1  riastrad 			       DpmXNbPsHi(new_ps->DpmXNbPsHi));
   1202  1.1  riastrad 		WREG32_SMC(NB_PSTATE_CONFIG, nbpsconfig);
   1203  1.1  riastrad 	}
   1204  1.1  riastrad }
   1205  1.1  riastrad 
   1206  1.1  riastrad int trinity_dpm_force_performance_level(struct radeon_device *rdev,
   1207  1.1  riastrad 					enum radeon_dpm_forced_level level)
   1208  1.1  riastrad {
   1209  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1210  1.1  riastrad 	struct radeon_ps *rps = &pi->current_rps;
   1211  1.1  riastrad 	struct trinity_ps *ps = trinity_get_ps(rps);
   1212  1.1  riastrad 	int i, ret;
   1213  1.1  riastrad 
   1214  1.1  riastrad 	if (ps->num_levels <= 1)
   1215  1.1  riastrad 		return 0;
   1216  1.1  riastrad 
   1217  1.1  riastrad 	if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
   1218  1.1  riastrad 		/* not supported by the hw */
   1219  1.1  riastrad 		return -EINVAL;
   1220  1.1  riastrad 	} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
   1221  1.1  riastrad 		ret = trinity_dpm_n_levels_disabled(rdev, ps->num_levels - 1);
   1222  1.1  riastrad 		if (ret)
   1223  1.1  riastrad 			return ret;
   1224  1.1  riastrad 	} else {
   1225  1.1  riastrad 		for (i = 0; i < ps->num_levels; i++) {
   1226  1.1  riastrad 			ret = trinity_dpm_n_levels_disabled(rdev, 0);
   1227  1.1  riastrad 			if (ret)
   1228  1.1  riastrad 				return ret;
   1229  1.1  riastrad 		}
   1230  1.1  riastrad 	}
   1231  1.1  riastrad 
   1232  1.1  riastrad 	rdev->pm.dpm.forced_level = level;
   1233  1.1  riastrad 
   1234  1.1  riastrad 	return 0;
   1235  1.1  riastrad }
   1236  1.1  riastrad 
   1237  1.1  riastrad int trinity_dpm_pre_set_power_state(struct radeon_device *rdev)
   1238  1.1  riastrad {
   1239  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1240  1.1  riastrad 	struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
   1241  1.1  riastrad 	struct radeon_ps *new_ps = &requested_ps;
   1242  1.1  riastrad 
   1243  1.1  riastrad 	trinity_update_requested_ps(rdev, new_ps);
   1244  1.1  riastrad 
   1245  1.1  riastrad 	trinity_apply_state_adjust_rules(rdev,
   1246  1.1  riastrad 					 &pi->requested_rps,
   1247  1.1  riastrad 					 &pi->current_rps);
   1248  1.1  riastrad 
   1249  1.1  riastrad 	return 0;
   1250  1.1  riastrad }
   1251  1.1  riastrad 
   1252  1.1  riastrad int trinity_dpm_set_power_state(struct radeon_device *rdev)
   1253  1.1  riastrad {
   1254  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1255  1.1  riastrad 	struct radeon_ps *new_ps = &pi->requested_rps;
   1256  1.1  riastrad 	struct radeon_ps *old_ps = &pi->current_rps;
   1257  1.1  riastrad 
   1258  1.1  riastrad 	trinity_acquire_mutex(rdev);
   1259  1.1  riastrad 	if (pi->enable_dpm) {
   1260  1.1  riastrad 		if (pi->enable_bapm)
   1261  1.1  riastrad 			trinity_dpm_bapm_enable(rdev, rdev->pm.dpm.ac_power);
   1262  1.1  riastrad 		trinity_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
   1263  1.1  riastrad 		trinity_enable_power_level_0(rdev);
   1264  1.1  riastrad 		trinity_force_level_0(rdev);
   1265  1.1  riastrad 		trinity_wait_for_level_0(rdev);
   1266  1.1  riastrad 		trinity_setup_nbp_sim(rdev, new_ps);
   1267  1.1  riastrad 		trinity_program_power_levels_0_to_n(rdev, new_ps, old_ps);
   1268  1.1  riastrad 		trinity_force_level_0(rdev);
   1269  1.1  riastrad 		trinity_unforce_levels(rdev);
   1270  1.1  riastrad 		trinity_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
   1271  1.1  riastrad 		trinity_set_vce_clock(rdev, new_ps, old_ps);
   1272  1.1  riastrad 	}
   1273  1.1  riastrad 	trinity_release_mutex(rdev);
   1274  1.1  riastrad 
   1275  1.1  riastrad 	return 0;
   1276  1.1  riastrad }
   1277  1.1  riastrad 
   1278  1.1  riastrad void trinity_dpm_post_set_power_state(struct radeon_device *rdev)
   1279  1.1  riastrad {
   1280  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1281  1.1  riastrad 	struct radeon_ps *new_ps = &pi->requested_rps;
   1282  1.1  riastrad 
   1283  1.1  riastrad 	trinity_update_current_ps(rdev, new_ps);
   1284  1.1  riastrad }
   1285  1.1  riastrad 
   1286  1.1  riastrad void trinity_dpm_setup_asic(struct radeon_device *rdev)
   1287  1.1  riastrad {
   1288  1.1  riastrad 	trinity_acquire_mutex(rdev);
   1289  1.1  riastrad 	sumo_program_sstp(rdev);
   1290  1.1  riastrad 	sumo_take_smu_control(rdev, true);
   1291  1.1  riastrad 	trinity_get_min_sclk_divider(rdev);
   1292  1.1  riastrad 	trinity_release_mutex(rdev);
   1293  1.1  riastrad }
   1294  1.1  riastrad 
   1295  1.1  riastrad #if 0
   1296  1.1  riastrad void trinity_dpm_reset_asic(struct radeon_device *rdev)
   1297  1.1  riastrad {
   1298  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1299  1.1  riastrad 
   1300  1.1  riastrad 	trinity_acquire_mutex(rdev);
   1301  1.1  riastrad 	if (pi->enable_dpm) {
   1302  1.1  riastrad 		trinity_enable_power_level_0(rdev);
   1303  1.1  riastrad 		trinity_force_level_0(rdev);
   1304  1.1  riastrad 		trinity_wait_for_level_0(rdev);
   1305  1.1  riastrad 		trinity_program_bootup_state(rdev);
   1306  1.1  riastrad 		trinity_force_level_0(rdev);
   1307  1.1  riastrad 		trinity_unforce_levels(rdev);
   1308  1.1  riastrad 	}
   1309  1.1  riastrad 	trinity_release_mutex(rdev);
   1310  1.1  riastrad }
   1311  1.1  riastrad #endif
   1312  1.1  riastrad 
   1313  1.1  riastrad static u16 trinity_convert_voltage_index_to_value(struct radeon_device *rdev,
   1314  1.1  riastrad 						  u32 vid_2bit)
   1315  1.1  riastrad {
   1316  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1317  1.1  riastrad 	u32 vid_7bit = sumo_convert_vid2_to_vid7(rdev, &pi->sys_info.vid_mapping_table, vid_2bit);
   1318  1.1  riastrad 	u32 svi_mode = (RREG32_SMC(PM_CONFIG) & SVI_Mode) ? 1 : 0;
   1319  1.1  riastrad 	u32 step = (svi_mode == 0) ? 1250 : 625;
   1320  1.1  riastrad 	u32 delta = vid_7bit * step + 50;
   1321  1.1  riastrad 
   1322  1.1  riastrad 	if (delta > 155000)
   1323  1.1  riastrad 		return 0;
   1324  1.1  riastrad 
   1325  1.1  riastrad 	return (155000 - delta) / 100;
   1326  1.1  riastrad }
   1327  1.1  riastrad 
   1328  1.1  riastrad static void trinity_patch_boot_state(struct radeon_device *rdev,
   1329  1.1  riastrad 				     struct trinity_ps *ps)
   1330  1.1  riastrad {
   1331  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1332  1.1  riastrad 
   1333  1.1  riastrad 	ps->num_levels = 1;
   1334  1.1  riastrad 	ps->nbps_flags = 0;
   1335  1.1  riastrad 	ps->bapm_flags = 0;
   1336  1.1  riastrad 	ps->levels[0] = pi->boot_pl;
   1337  1.1  riastrad }
   1338  1.1  riastrad 
   1339  1.1  riastrad static u8 trinity_calculate_vce_wm(struct radeon_device *rdev, u32 sclk)
   1340  1.1  riastrad {
   1341  1.1  riastrad 	if (sclk < 20000)
   1342  1.1  riastrad 		return 1;
   1343  1.1  riastrad 	return 0;
   1344  1.1  riastrad }
   1345  1.1  riastrad 
   1346  1.1  riastrad static void trinity_construct_boot_state(struct radeon_device *rdev)
   1347  1.1  riastrad {
   1348  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1349  1.1  riastrad 
   1350  1.1  riastrad 	pi->boot_pl.sclk = pi->sys_info.bootup_sclk;
   1351  1.1  riastrad 	pi->boot_pl.vddc_index = pi->sys_info.bootup_nb_voltage_index;
   1352  1.1  riastrad 	pi->boot_pl.ds_divider_index = 0;
   1353  1.1  riastrad 	pi->boot_pl.ss_divider_index = 0;
   1354  1.1  riastrad 	pi->boot_pl.allow_gnb_slow = 1;
   1355  1.1  riastrad 	pi->boot_pl.force_nbp_state = 0;
   1356  1.1  riastrad 	pi->boot_pl.display_wm = 0;
   1357  1.1  riastrad 	pi->boot_pl.vce_wm = 0;
   1358  1.1  riastrad 	pi->current_ps.num_levels = 1;
   1359  1.1  riastrad 	pi->current_ps.levels[0] = pi->boot_pl;
   1360  1.1  riastrad }
   1361  1.1  riastrad 
   1362  1.1  riastrad static u8 trinity_get_sleep_divider_id_from_clock(struct radeon_device *rdev,
   1363  1.1  riastrad 						  u32 sclk, u32 min_sclk_in_sr)
   1364  1.1  riastrad {
   1365  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1366  1.1  riastrad 	u32 i;
   1367  1.1  riastrad 	u32 temp;
   1368  1.2  riastrad 	u32 min = (min_sclk_in_sr > TRINITY_MINIMUM_ENGINE_CLOCK) ?
   1369  1.1  riastrad 		min_sclk_in_sr : TRINITY_MINIMUM_ENGINE_CLOCK;
   1370  1.1  riastrad 
   1371  1.2  riastrad 	if (sclk < min)
   1372  1.1  riastrad 		return 0;
   1373  1.1  riastrad 
   1374  1.1  riastrad 	if (!pi->enable_sclk_ds)
   1375  1.1  riastrad 		return 0;
   1376  1.1  riastrad 
   1377  1.1  riastrad 	for (i = TRINITY_MAX_DEEPSLEEP_DIVIDER_ID;  ; i--) {
   1378  1.1  riastrad 		temp = sclk / sumo_get_sleep_divider_from_id(i);
   1379  1.2  riastrad 		if (temp >= min || i == 0)
   1380  1.1  riastrad 			break;
   1381  1.1  riastrad 	}
   1382  1.1  riastrad 
   1383  1.1  riastrad 	return (u8)i;
   1384  1.1  riastrad }
   1385  1.1  riastrad 
   1386  1.1  riastrad static u32 trinity_get_valid_engine_clock(struct radeon_device *rdev,
   1387  1.1  riastrad 					  u32 lower_limit)
   1388  1.1  riastrad {
   1389  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1390  1.1  riastrad 	u32 i;
   1391  1.1  riastrad 
   1392  1.1  riastrad 	for (i = 0; i < pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries; i++) {
   1393  1.1  riastrad 		if (pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency >= lower_limit)
   1394  1.1  riastrad 			return pi->sys_info.sclk_voltage_mapping_table.entries[i].sclk_frequency;
   1395  1.1  riastrad 	}
   1396  1.1  riastrad 
   1397  1.1  riastrad 	if (i == pi->sys_info.sclk_voltage_mapping_table.num_max_dpm_entries)
   1398  1.1  riastrad 		DRM_ERROR("engine clock out of range!");
   1399  1.1  riastrad 
   1400  1.1  riastrad 	return 0;
   1401  1.1  riastrad }
   1402  1.1  riastrad 
   1403  1.1  riastrad static void trinity_patch_thermal_state(struct radeon_device *rdev,
   1404  1.1  riastrad 					struct trinity_ps *ps,
   1405  1.1  riastrad 					struct trinity_ps *current_ps)
   1406  1.1  riastrad {
   1407  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1408  1.1  riastrad 	u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
   1409  1.1  riastrad 	u32 current_vddc;
   1410  1.1  riastrad 	u32 current_sclk;
   1411  1.1  riastrad 	u32 current_index = 0;
   1412  1.1  riastrad 
   1413  1.1  riastrad 	if (current_ps) {
   1414  1.1  riastrad 		current_vddc = current_ps->levels[current_index].vddc_index;
   1415  1.1  riastrad 		current_sclk = current_ps->levels[current_index].sclk;
   1416  1.1  riastrad 	} else {
   1417  1.1  riastrad 		current_vddc = pi->boot_pl.vddc_index;
   1418  1.1  riastrad 		current_sclk = pi->boot_pl.sclk;
   1419  1.1  riastrad 	}
   1420  1.1  riastrad 
   1421  1.1  riastrad 	ps->levels[0].vddc_index = current_vddc;
   1422  1.1  riastrad 
   1423  1.1  riastrad 	if (ps->levels[0].sclk > current_sclk)
   1424  1.1  riastrad 		ps->levels[0].sclk = current_sclk;
   1425  1.1  riastrad 
   1426  1.1  riastrad 	ps->levels[0].ds_divider_index =
   1427  1.1  riastrad 		trinity_get_sleep_divider_id_from_clock(rdev, ps->levels[0].sclk, sclk_in_sr);
   1428  1.1  riastrad 	ps->levels[0].ss_divider_index = ps->levels[0].ds_divider_index;
   1429  1.1  riastrad 	ps->levels[0].allow_gnb_slow = 1;
   1430  1.1  riastrad 	ps->levels[0].force_nbp_state = 0;
   1431  1.1  riastrad 	ps->levels[0].display_wm = 0;
   1432  1.1  riastrad 	ps->levels[0].vce_wm =
   1433  1.1  riastrad 		trinity_calculate_vce_wm(rdev, ps->levels[0].sclk);
   1434  1.1  riastrad }
   1435  1.1  riastrad 
   1436  1.1  riastrad static u8 trinity_calculate_display_wm(struct radeon_device *rdev,
   1437  1.1  riastrad 				       struct trinity_ps *ps, u32 index)
   1438  1.1  riastrad {
   1439  1.1  riastrad 	if (ps == NULL || ps->num_levels <= 1)
   1440  1.1  riastrad 		return 0;
   1441  1.1  riastrad 	else if (ps->num_levels == 2) {
   1442  1.1  riastrad 		if (index == 0)
   1443  1.1  riastrad 			return 0;
   1444  1.1  riastrad 		else
   1445  1.1  riastrad 			return 1;
   1446  1.1  riastrad 	} else {
   1447  1.1  riastrad 		if (index == 0)
   1448  1.1  riastrad 			return 0;
   1449  1.1  riastrad 		else if (ps->levels[index].sclk < 30000)
   1450  1.1  riastrad 			return 0;
   1451  1.1  riastrad 		else
   1452  1.1  riastrad 			return 1;
   1453  1.1  riastrad 	}
   1454  1.1  riastrad }
   1455  1.1  riastrad 
   1456  1.1  riastrad static u32 trinity_get_uvd_clock_index(struct radeon_device *rdev,
   1457  1.1  riastrad 				       struct radeon_ps *rps)
   1458  1.1  riastrad {
   1459  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1460  1.1  riastrad 	u32 i = 0;
   1461  1.1  riastrad 
   1462  1.1  riastrad 	for (i = 0; i < 4; i++) {
   1463  1.1  riastrad 		if ((rps->vclk == pi->sys_info.uvd_clock_table_entries[i].vclk) &&
   1464  1.1  riastrad 		    (rps->dclk == pi->sys_info.uvd_clock_table_entries[i].dclk))
   1465  1.1  riastrad 		    break;
   1466  1.1  riastrad 	}
   1467  1.1  riastrad 
   1468  1.1  riastrad 	if (i >= 4) {
   1469  1.1  riastrad 		DRM_ERROR("UVD clock index not found!\n");
   1470  1.1  riastrad 		i = 3;
   1471  1.1  riastrad 	}
   1472  1.1  riastrad 	return i;
   1473  1.1  riastrad }
   1474  1.1  riastrad 
   1475  1.1  riastrad static void trinity_adjust_uvd_state(struct radeon_device *rdev,
   1476  1.1  riastrad 				     struct radeon_ps *rps)
   1477  1.1  riastrad {
   1478  1.1  riastrad 	struct trinity_ps *ps = trinity_get_ps(rps);
   1479  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1480  1.1  riastrad 	u32 high_index = 0;
   1481  1.1  riastrad 	u32 low_index = 0;
   1482  1.1  riastrad 
   1483  1.1  riastrad 	if (pi->uvd_dpm && r600_is_uvd_state(rps->class, rps->class2)) {
   1484  1.1  riastrad 		high_index = trinity_get_uvd_clock_index(rdev, rps);
   1485  1.1  riastrad 
   1486  1.1  riastrad 		switch(high_index) {
   1487  1.1  riastrad 		case 3:
   1488  1.1  riastrad 		case 2:
   1489  1.1  riastrad 			low_index = 1;
   1490  1.1  riastrad 			break;
   1491  1.1  riastrad 		case 1:
   1492  1.1  riastrad 		case 0:
   1493  1.1  riastrad 		default:
   1494  1.1  riastrad 			low_index = 0;
   1495  1.1  riastrad 			break;
   1496  1.1  riastrad 		}
   1497  1.1  riastrad 
   1498  1.1  riastrad 		ps->vclk_low_divider =
   1499  1.1  riastrad 			pi->sys_info.uvd_clock_table_entries[high_index].vclk_did;
   1500  1.1  riastrad 		ps->dclk_low_divider =
   1501  1.1  riastrad 			pi->sys_info.uvd_clock_table_entries[high_index].dclk_did;
   1502  1.1  riastrad 		ps->vclk_high_divider =
   1503  1.1  riastrad 			pi->sys_info.uvd_clock_table_entries[low_index].vclk_did;
   1504  1.1  riastrad 		ps->dclk_high_divider =
   1505  1.1  riastrad 			pi->sys_info.uvd_clock_table_entries[low_index].dclk_did;
   1506  1.1  riastrad 	}
   1507  1.1  riastrad }
   1508  1.1  riastrad 
   1509  1.1  riastrad static int trinity_get_vce_clock_voltage(struct radeon_device *rdev,
   1510  1.1  riastrad 					 u32 evclk, u32 ecclk, u16 *voltage)
   1511  1.1  riastrad {
   1512  1.1  riastrad 	u32 i;
   1513  1.1  riastrad 	int ret = -EINVAL;
   1514  1.1  riastrad 	struct radeon_vce_clock_voltage_dependency_table *table =
   1515  1.1  riastrad 		&rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
   1516  1.1  riastrad 
   1517  1.1  riastrad 	if (((evclk == 0) && (ecclk == 0)) ||
   1518  1.1  riastrad 	    (table && (table->count == 0))) {
   1519  1.1  riastrad 		*voltage = 0;
   1520  1.1  riastrad 		return 0;
   1521  1.1  riastrad 	}
   1522  1.1  riastrad 
   1523  1.1  riastrad 	for (i = 0; i < table->count; i++) {
   1524  1.1  riastrad 		if ((evclk <= table->entries[i].evclk) &&
   1525  1.1  riastrad 		    (ecclk <= table->entries[i].ecclk)) {
   1526  1.1  riastrad 			*voltage = table->entries[i].v;
   1527  1.1  riastrad 			ret = 0;
   1528  1.1  riastrad 			break;
   1529  1.1  riastrad 		}
   1530  1.1  riastrad 	}
   1531  1.1  riastrad 
   1532  1.1  riastrad 	/* if no match return the highest voltage */
   1533  1.1  riastrad 	if (ret)
   1534  1.1  riastrad 		*voltage = table->entries[table->count - 1].v;
   1535  1.1  riastrad 
   1536  1.1  riastrad 	return ret;
   1537  1.1  riastrad }
   1538  1.1  riastrad 
   1539  1.1  riastrad static void trinity_apply_state_adjust_rules(struct radeon_device *rdev,
   1540  1.1  riastrad 					     struct radeon_ps *new_rps,
   1541  1.1  riastrad 					     struct radeon_ps *old_rps)
   1542  1.1  riastrad {
   1543  1.1  riastrad 	struct trinity_ps *ps = trinity_get_ps(new_rps);
   1544  1.1  riastrad 	struct trinity_ps *current_ps = trinity_get_ps(old_rps);
   1545  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1546  1.1  riastrad 	u32 min_voltage = 0; /* ??? */
   1547  1.1  riastrad 	u32 min_sclk = pi->sys_info.min_sclk; /* XXX check against disp reqs */
   1548  1.1  riastrad 	u32 sclk_in_sr = pi->sys_info.min_sclk; /* ??? */
   1549  1.1  riastrad 	u32 i;
   1550  1.1  riastrad 	u16 min_vce_voltage;
   1551  1.1  riastrad 	bool force_high;
   1552  1.1  riastrad 	u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;
   1553  1.1  riastrad 
   1554  1.1  riastrad 	if (new_rps->class & ATOM_PPLIB_CLASSIFICATION_THERMAL)
   1555  1.1  riastrad 		return trinity_patch_thermal_state(rdev, ps, current_ps);
   1556  1.1  riastrad 
   1557  1.1  riastrad 	trinity_adjust_uvd_state(rdev, new_rps);
   1558  1.1  riastrad 
   1559  1.1  riastrad 	if (new_rps->vce_active) {
   1560  1.1  riastrad 		new_rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
   1561  1.1  riastrad 		new_rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk;
   1562  1.1  riastrad 	} else {
   1563  1.1  riastrad 		new_rps->evclk = 0;
   1564  1.1  riastrad 		new_rps->ecclk = 0;
   1565  1.1  riastrad 	}
   1566  1.1  riastrad 
   1567  1.1  riastrad 	for (i = 0; i < ps->num_levels; i++) {
   1568  1.1  riastrad 		if (ps->levels[i].vddc_index < min_voltage)
   1569  1.1  riastrad 			ps->levels[i].vddc_index = min_voltage;
   1570  1.1  riastrad 
   1571  1.1  riastrad 		if (ps->levels[i].sclk < min_sclk)
   1572  1.1  riastrad 			ps->levels[i].sclk =
   1573  1.1  riastrad 				trinity_get_valid_engine_clock(rdev, min_sclk);
   1574  1.1  riastrad 
   1575  1.1  riastrad 		/* patch in vce limits */
   1576  1.1  riastrad 		if (new_rps->vce_active) {
   1577  1.1  riastrad 			/* sclk */
   1578  1.1  riastrad 			if (ps->levels[i].sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk)
   1579  1.1  riastrad 				ps->levels[i].sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk;
   1580  1.1  riastrad 			/* vddc */
   1581  1.1  riastrad 			trinity_get_vce_clock_voltage(rdev, new_rps->evclk, new_rps->ecclk, &min_vce_voltage);
   1582  1.1  riastrad 			if (ps->levels[i].vddc_index < min_vce_voltage)
   1583  1.1  riastrad 				ps->levels[i].vddc_index = min_vce_voltage;
   1584  1.1  riastrad 		}
   1585  1.1  riastrad 
   1586  1.1  riastrad 		ps->levels[i].ds_divider_index =
   1587  1.1  riastrad 			sumo_get_sleep_divider_id_from_clock(rdev, ps->levels[i].sclk, sclk_in_sr);
   1588  1.1  riastrad 
   1589  1.1  riastrad 		ps->levels[i].ss_divider_index = ps->levels[i].ds_divider_index;
   1590  1.1  riastrad 
   1591  1.1  riastrad 		ps->levels[i].allow_gnb_slow = 1;
   1592  1.1  riastrad 		ps->levels[i].force_nbp_state = 0;
   1593  1.1  riastrad 		ps->levels[i].display_wm =
   1594  1.1  riastrad 			trinity_calculate_display_wm(rdev, ps, i);
   1595  1.1  riastrad 		ps->levels[i].vce_wm =
   1596  1.1  riastrad 			trinity_calculate_vce_wm(rdev, ps->levels[0].sclk);
   1597  1.1  riastrad 	}
   1598  1.1  riastrad 
   1599  1.1  riastrad 	if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) ||
   1600  1.1  riastrad 	    ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY))
   1601  1.1  riastrad 		ps->bapm_flags |= TRINITY_POWERSTATE_FLAGS_BAPM_DISABLE;
   1602  1.1  riastrad 
   1603  1.1  riastrad 	if (pi->sys_info.nb_dpm_enable) {
   1604  1.1  riastrad 		ps->Dpm0PgNbPsLo = 0x1;
   1605  1.1  riastrad 		ps->Dpm0PgNbPsHi = 0x0;
   1606  1.1  riastrad 		ps->DpmXNbPsLo = 0x2;
   1607  1.1  riastrad 		ps->DpmXNbPsHi = 0x1;
   1608  1.1  riastrad 
   1609  1.1  riastrad 		if ((new_rps->class & (ATOM_PPLIB_CLASSIFICATION_HDSTATE | ATOM_PPLIB_CLASSIFICATION_SDSTATE)) ||
   1610  1.1  riastrad 		    ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY)) {
   1611  1.1  riastrad 			force_high = ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_HDSTATE) ||
   1612  1.1  riastrad 				      ((new_rps->class & ATOM_PPLIB_CLASSIFICATION_SDSTATE) &&
   1613  1.1  riastrad 				       (pi->sys_info.uma_channel_number == 1)));
   1614  1.1  riastrad 			force_high = (num_active_displays >= 3) || force_high;
   1615  1.1  riastrad 			ps->Dpm0PgNbPsLo = force_high ? 0x2 : 0x3;
   1616  1.1  riastrad 			ps->Dpm0PgNbPsHi = 0x1;
   1617  1.1  riastrad 			ps->DpmXNbPsLo = force_high ? 0x2 : 0x3;
   1618  1.1  riastrad 			ps->DpmXNbPsHi = 0x2;
   1619  1.1  riastrad 			ps->levels[ps->num_levels - 1].allow_gnb_slow = 0;
   1620  1.1  riastrad 		}
   1621  1.1  riastrad 	}
   1622  1.1  riastrad }
   1623  1.1  riastrad 
   1624  1.1  riastrad static void trinity_cleanup_asic(struct radeon_device *rdev)
   1625  1.1  riastrad {
   1626  1.1  riastrad 	sumo_take_smu_control(rdev, false);
   1627  1.1  riastrad }
   1628  1.1  riastrad 
   1629  1.1  riastrad #if 0
   1630  1.1  riastrad static void trinity_pre_display_configuration_change(struct radeon_device *rdev)
   1631  1.1  riastrad {
   1632  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1633  1.1  riastrad 
   1634  1.1  riastrad 	if (pi->voltage_drop_in_dce)
   1635  1.1  riastrad 		trinity_dce_enable_voltage_adjustment(rdev, false);
   1636  1.1  riastrad }
   1637  1.1  riastrad #endif
   1638  1.1  riastrad 
   1639  1.1  riastrad static void trinity_add_dccac_value(struct radeon_device *rdev)
   1640  1.1  riastrad {
   1641  1.1  riastrad 	u32 gpu_cac_avrg_cntl_window_size;
   1642  1.1  riastrad 	u32 num_active_displays = rdev->pm.dpm.new_active_crtc_count;
   1643  1.1  riastrad 	u64 disp_clk = rdev->clock.default_dispclk / 100;
   1644  1.1  riastrad 	u32 dc_cac_value;
   1645  1.1  riastrad 
   1646  1.1  riastrad 	gpu_cac_avrg_cntl_window_size =
   1647  1.1  riastrad 		(RREG32_SMC(GPU_CAC_AVRG_CNTL) & WINDOW_SIZE_MASK) >> WINDOW_SIZE_SHIFT;
   1648  1.1  riastrad 
   1649  1.1  riastrad 	dc_cac_value = (u32)((14213 * disp_clk * disp_clk * (u64)num_active_displays) >>
   1650  1.1  riastrad 			     (32 - gpu_cac_avrg_cntl_window_size));
   1651  1.1  riastrad 
   1652  1.1  riastrad 	WREG32_SMC(DC_CAC_VALUE, dc_cac_value);
   1653  1.1  riastrad }
   1654  1.1  riastrad 
   1655  1.1  riastrad void trinity_dpm_display_configuration_changed(struct radeon_device *rdev)
   1656  1.1  riastrad {
   1657  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1658  1.1  riastrad 
   1659  1.1  riastrad 	if (pi->voltage_drop_in_dce)
   1660  1.1  riastrad 		trinity_dce_enable_voltage_adjustment(rdev, true);
   1661  1.1  riastrad 	trinity_add_dccac_value(rdev);
   1662  1.1  riastrad }
   1663  1.1  riastrad 
   1664  1.1  riastrad union power_info {
   1665  1.1  riastrad 	struct _ATOM_POWERPLAY_INFO info;
   1666  1.1  riastrad 	struct _ATOM_POWERPLAY_INFO_V2 info_2;
   1667  1.1  riastrad 	struct _ATOM_POWERPLAY_INFO_V3 info_3;
   1668  1.1  riastrad 	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
   1669  1.1  riastrad 	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
   1670  1.1  riastrad 	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
   1671  1.1  riastrad };
   1672  1.1  riastrad 
   1673  1.1  riastrad union pplib_clock_info {
   1674  1.1  riastrad 	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
   1675  1.1  riastrad 	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
   1676  1.1  riastrad 	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
   1677  1.1  riastrad 	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
   1678  1.1  riastrad };
   1679  1.1  riastrad 
   1680  1.1  riastrad union pplib_power_state {
   1681  1.1  riastrad 	struct _ATOM_PPLIB_STATE v1;
   1682  1.1  riastrad 	struct _ATOM_PPLIB_STATE_V2 v2;
   1683  1.1  riastrad };
   1684  1.1  riastrad 
   1685  1.1  riastrad static void trinity_parse_pplib_non_clock_info(struct radeon_device *rdev,
   1686  1.1  riastrad 					       struct radeon_ps *rps,
   1687  1.1  riastrad 					       struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
   1688  1.1  riastrad 					       u8 table_rev)
   1689  1.1  riastrad {
   1690  1.1  riastrad 	struct trinity_ps *ps = trinity_get_ps(rps);
   1691  1.1  riastrad 
   1692  1.1  riastrad 	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
   1693  1.1  riastrad 	rps->class = le16_to_cpu(non_clock_info->usClassification);
   1694  1.1  riastrad 	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
   1695  1.1  riastrad 
   1696  1.1  riastrad 	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
   1697  1.1  riastrad 		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
   1698  1.1  riastrad 		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
   1699  1.1  riastrad 	} else {
   1700  1.1  riastrad 		rps->vclk = 0;
   1701  1.1  riastrad 		rps->dclk = 0;
   1702  1.1  riastrad 	}
   1703  1.1  riastrad 
   1704  1.1  riastrad 	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
   1705  1.1  riastrad 		rdev->pm.dpm.boot_ps = rps;
   1706  1.1  riastrad 		trinity_patch_boot_state(rdev, ps);
   1707  1.1  riastrad 	}
   1708  1.1  riastrad 	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
   1709  1.1  riastrad 		rdev->pm.dpm.uvd_ps = rps;
   1710  1.1  riastrad }
   1711  1.1  riastrad 
   1712  1.1  riastrad static void trinity_parse_pplib_clock_info(struct radeon_device *rdev,
   1713  1.1  riastrad 					   struct radeon_ps *rps, int index,
   1714  1.1  riastrad 					   union pplib_clock_info *clock_info)
   1715  1.1  riastrad {
   1716  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1717  1.1  riastrad 	struct trinity_ps *ps = trinity_get_ps(rps);
   1718  1.1  riastrad 	struct trinity_pl *pl = &ps->levels[index];
   1719  1.1  riastrad 	u32 sclk;
   1720  1.1  riastrad 
   1721  1.1  riastrad 	sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
   1722  1.1  riastrad 	sclk |= clock_info->sumo.ucEngineClockHigh << 16;
   1723  1.1  riastrad 	pl->sclk = sclk;
   1724  1.1  riastrad 	pl->vddc_index = clock_info->sumo.vddcIndex;
   1725  1.1  riastrad 
   1726  1.1  riastrad 	ps->num_levels = index + 1;
   1727  1.1  riastrad 
   1728  1.1  riastrad 	if (pi->enable_sclk_ds) {
   1729  1.1  riastrad 		pl->ds_divider_index = 5;
   1730  1.1  riastrad 		pl->ss_divider_index = 5;
   1731  1.1  riastrad 	}
   1732  1.1  riastrad }
   1733  1.1  riastrad 
   1734  1.1  riastrad static int trinity_parse_power_table(struct radeon_device *rdev)
   1735  1.1  riastrad {
   1736  1.1  riastrad 	struct radeon_mode_info *mode_info = &rdev->mode_info;
   1737  1.1  riastrad 	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
   1738  1.1  riastrad 	union pplib_power_state *power_state;
   1739  1.1  riastrad 	int i, j, k, non_clock_array_index, clock_array_index;
   1740  1.1  riastrad 	union pplib_clock_info *clock_info;
   1741  1.1  riastrad 	struct _StateArray *state_array;
   1742  1.1  riastrad 	struct _ClockInfoArray *clock_info_array;
   1743  1.1  riastrad 	struct _NonClockInfoArray *non_clock_info_array;
   1744  1.1  riastrad 	union power_info *power_info;
   1745  1.1  riastrad 	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
   1746  1.3  riastrad 	u16 data_offset;
   1747  1.1  riastrad 	u8 frev, crev;
   1748  1.1  riastrad 	u8 *power_state_offset;
   1749  1.1  riastrad 	struct sumo_ps *ps;
   1750  1.1  riastrad 
   1751  1.1  riastrad 	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
   1752  1.1  riastrad 				   &frev, &crev, &data_offset))
   1753  1.1  riastrad 		return -EINVAL;
   1754  1.1  riastrad 	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
   1755  1.1  riastrad 
   1756  1.1  riastrad 	state_array = (struct _StateArray *)
   1757  1.1  riastrad 		(mode_info->atom_context->bios + data_offset +
   1758  1.1  riastrad 		 le16_to_cpu(power_info->pplib.usStateArrayOffset));
   1759  1.1  riastrad 	clock_info_array = (struct _ClockInfoArray *)
   1760  1.1  riastrad 		(mode_info->atom_context->bios + data_offset +
   1761  1.1  riastrad 		 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
   1762  1.1  riastrad 	non_clock_info_array = (struct _NonClockInfoArray *)
   1763  1.1  riastrad 		(mode_info->atom_context->bios + data_offset +
   1764  1.1  riastrad 		 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
   1765  1.1  riastrad 
   1766  1.3  riastrad 	rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries,
   1767  1.3  riastrad 				  sizeof(struct radeon_ps),
   1768  1.3  riastrad 				  GFP_KERNEL);
   1769  1.1  riastrad 	if (!rdev->pm.dpm.ps)
   1770  1.1  riastrad 		return -ENOMEM;
   1771  1.1  riastrad 	power_state_offset = (u8 *)state_array->states;
   1772  1.1  riastrad 	for (i = 0; i < state_array->ucNumEntries; i++) {
   1773  1.1  riastrad 		u8 *idx;
   1774  1.1  riastrad 		power_state = (union pplib_power_state *)power_state_offset;
   1775  1.1  riastrad 		non_clock_array_index = power_state->v2.nonClockInfoIndex;
   1776  1.1  riastrad 		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
   1777  1.1  riastrad 			&non_clock_info_array->nonClockInfo[non_clock_array_index];
   1778  1.1  riastrad 		if (!rdev->pm.power_state[i].clock_info)
   1779  1.1  riastrad 			return -EINVAL;
   1780  1.1  riastrad 		ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL);
   1781  1.1  riastrad 		if (ps == NULL) {
   1782  1.1  riastrad 			kfree(rdev->pm.dpm.ps);
   1783  1.1  riastrad 			return -ENOMEM;
   1784  1.1  riastrad 		}
   1785  1.1  riastrad 		rdev->pm.dpm.ps[i].ps_priv = ps;
   1786  1.1  riastrad 		k = 0;
   1787  1.1  riastrad 		idx = (u8 *)&power_state->v2.clockInfoIndex[0];
   1788  1.1  riastrad 		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
   1789  1.1  riastrad 			clock_array_index = idx[j];
   1790  1.1  riastrad 			if (clock_array_index >= clock_info_array->ucNumEntries)
   1791  1.1  riastrad 				continue;
   1792  1.1  riastrad 			if (k >= SUMO_MAX_HARDWARE_POWERLEVELS)
   1793  1.1  riastrad 				break;
   1794  1.1  riastrad 			clock_info = (union pplib_clock_info *)
   1795  1.1  riastrad 				((u8 *)&clock_info_array->clockInfo[0] +
   1796  1.1  riastrad 				 (clock_array_index * clock_info_array->ucEntrySize));
   1797  1.1  riastrad 			trinity_parse_pplib_clock_info(rdev,
   1798  1.1  riastrad 						       &rdev->pm.dpm.ps[i], k,
   1799  1.1  riastrad 						       clock_info);
   1800  1.1  riastrad 			k++;
   1801  1.1  riastrad 		}
   1802  1.1  riastrad 		trinity_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
   1803  1.1  riastrad 						   non_clock_info,
   1804  1.1  riastrad 						   non_clock_info_array->ucEntrySize);
   1805  1.1  riastrad 		power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
   1806  1.1  riastrad 	}
   1807  1.1  riastrad 	rdev->pm.dpm.num_ps = state_array->ucNumEntries;
   1808  1.1  riastrad 
   1809  1.1  riastrad 	/* fill in the vce power states */
   1810  1.1  riastrad 	for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) {
   1811  1.1  riastrad 		u32 sclk;
   1812  1.1  riastrad 		clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx;
   1813  1.1  riastrad 		clock_info = (union pplib_clock_info *)
   1814  1.1  riastrad 			&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
   1815  1.1  riastrad 		sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow);
   1816  1.1  riastrad 		sclk |= clock_info->sumo.ucEngineClockHigh << 16;
   1817  1.1  riastrad 		rdev->pm.dpm.vce_states[i].sclk = sclk;
   1818  1.1  riastrad 		rdev->pm.dpm.vce_states[i].mclk = 0;
   1819  1.1  riastrad 	}
   1820  1.1  riastrad 
   1821  1.1  riastrad 	return 0;
   1822  1.1  riastrad }
   1823  1.1  riastrad 
   1824  1.1  riastrad union igp_info {
   1825  1.1  riastrad 	struct _ATOM_INTEGRATED_SYSTEM_INFO info;
   1826  1.1  riastrad 	struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2;
   1827  1.1  riastrad 	struct _ATOM_INTEGRATED_SYSTEM_INFO_V5 info_5;
   1828  1.1  riastrad 	struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6;
   1829  1.1  riastrad 	struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7;
   1830  1.1  riastrad };
   1831  1.1  riastrad 
   1832  1.1  riastrad static u32 trinity_convert_did_to_freq(struct radeon_device *rdev, u8 did)
   1833  1.1  riastrad {
   1834  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1835  1.1  riastrad 	u32 divider;
   1836  1.1  riastrad 
   1837  1.1  riastrad 	if (did >= 8 && did <= 0x3f)
   1838  1.1  riastrad 		divider = did * 25;
   1839  1.1  riastrad 	else if (did > 0x3f && did <= 0x5f)
   1840  1.1  riastrad 		divider = (did - 64) * 50 + 1600;
   1841  1.1  riastrad 	else if (did > 0x5f && did <= 0x7e)
   1842  1.1  riastrad 		divider = (did - 96) * 100 + 3200;
   1843  1.1  riastrad 	else if (did == 0x7f)
   1844  1.1  riastrad 		divider = 128 * 100;
   1845  1.1  riastrad 	else
   1846  1.1  riastrad 		return 10000;
   1847  1.1  riastrad 
   1848  1.1  riastrad 	return ((pi->sys_info.dentist_vco_freq * 100) + (divider - 1)) / divider;
   1849  1.1  riastrad }
   1850  1.1  riastrad 
   1851  1.1  riastrad static int trinity_parse_sys_info_table(struct radeon_device *rdev)
   1852  1.1  riastrad {
   1853  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   1854  1.1  riastrad 	struct radeon_mode_info *mode_info = &rdev->mode_info;
   1855  1.1  riastrad 	int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
   1856  1.1  riastrad 	union igp_info *igp_info;
   1857  1.1  riastrad 	u8 frev, crev;
   1858  1.1  riastrad 	u16 data_offset;
   1859  1.1  riastrad 	int i;
   1860  1.1  riastrad 
   1861  1.1  riastrad 	if (atom_parse_data_header(mode_info->atom_context, index, NULL,
   1862  1.1  riastrad 				   &frev, &crev, &data_offset)) {
   1863  1.1  riastrad 		igp_info = (union igp_info *)(mode_info->atom_context->bios +
   1864  1.1  riastrad 					      data_offset);
   1865  1.1  riastrad 
   1866  1.1  riastrad 		if (crev != 7) {
   1867  1.1  riastrad 			DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev);
   1868  1.1  riastrad 			return -EINVAL;
   1869  1.1  riastrad 		}
   1870  1.1  riastrad 		pi->sys_info.bootup_sclk = le32_to_cpu(igp_info->info_7.ulBootUpEngineClock);
   1871  1.1  riastrad 		pi->sys_info.min_sclk = le32_to_cpu(igp_info->info_7.ulMinEngineClock);
   1872  1.1  riastrad 		pi->sys_info.bootup_uma_clk = le32_to_cpu(igp_info->info_7.ulBootUpUMAClock);
   1873  1.1  riastrad 		pi->sys_info.dentist_vco_freq = le32_to_cpu(igp_info->info_7.ulDentistVCOFreq);
   1874  1.1  riastrad 		pi->sys_info.bootup_nb_voltage_index =
   1875  1.1  riastrad 			le16_to_cpu(igp_info->info_7.usBootUpNBVoltage);
   1876  1.1  riastrad 		if (igp_info->info_7.ucHtcTmpLmt == 0)
   1877  1.1  riastrad 			pi->sys_info.htc_tmp_lmt = 203;
   1878  1.1  riastrad 		else
   1879  1.1  riastrad 			pi->sys_info.htc_tmp_lmt = igp_info->info_7.ucHtcTmpLmt;
   1880  1.1  riastrad 		if (igp_info->info_7.ucHtcHystLmt == 0)
   1881  1.1  riastrad 			pi->sys_info.htc_hyst_lmt = 5;
   1882  1.1  riastrad 		else
   1883  1.1  riastrad 			pi->sys_info.htc_hyst_lmt = igp_info->info_7.ucHtcHystLmt;
   1884  1.1  riastrad 		if (pi->sys_info.htc_tmp_lmt <= pi->sys_info.htc_hyst_lmt) {
   1885  1.1  riastrad 			DRM_ERROR("The htcTmpLmt should be larger than htcHystLmt.\n");
   1886  1.1  riastrad 		}
   1887  1.1  riastrad 
   1888  1.1  riastrad 		if (pi->enable_nbps_policy)
   1889  1.1  riastrad 			pi->sys_info.nb_dpm_enable = igp_info->info_7.ucNBDPMEnable;
   1890  1.1  riastrad 		else
   1891  1.1  riastrad 			pi->sys_info.nb_dpm_enable = 0;
   1892  1.1  riastrad 
   1893  1.1  riastrad 		for (i = 0; i < TRINITY_NUM_NBPSTATES; i++) {
   1894  1.1  riastrad 			pi->sys_info.nbp_mclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateMemclkFreq[i]);
   1895  1.1  riastrad 			pi->sys_info.nbp_nclk[i] = le32_to_cpu(igp_info->info_7.ulNbpStateNClkFreq[i]);
   1896  1.1  riastrad 		}
   1897  1.1  riastrad 
   1898  1.1  riastrad 		pi->sys_info.nbp_voltage_index[0] = le16_to_cpu(igp_info->info_7.usNBP0Voltage);
   1899  1.1  riastrad 		pi->sys_info.nbp_voltage_index[1] = le16_to_cpu(igp_info->info_7.usNBP1Voltage);
   1900  1.1  riastrad 		pi->sys_info.nbp_voltage_index[2] = le16_to_cpu(igp_info->info_7.usNBP2Voltage);
   1901  1.1  riastrad 		pi->sys_info.nbp_voltage_index[3] = le16_to_cpu(igp_info->info_7.usNBP3Voltage);
   1902  1.1  riastrad 
   1903  1.1  riastrad 		if (!pi->sys_info.nb_dpm_enable) {
   1904  1.1  riastrad 			for (i = 1; i < TRINITY_NUM_NBPSTATES; i++) {
   1905  1.1  riastrad 				pi->sys_info.nbp_mclk[i] = pi->sys_info.nbp_mclk[0];
   1906  1.1  riastrad 				pi->sys_info.nbp_nclk[i] = pi->sys_info.nbp_nclk[0];
   1907  1.1  riastrad 				pi->sys_info.nbp_voltage_index[i] = pi->sys_info.nbp_voltage_index[0];
   1908  1.1  riastrad 			}
   1909  1.1  riastrad 		}
   1910  1.1  riastrad 
   1911  1.1  riastrad 		pi->sys_info.uma_channel_number = igp_info->info_7.ucUMAChannelNumber;
   1912  1.1  riastrad 
   1913  1.1  riastrad 		sumo_construct_sclk_voltage_mapping_table(rdev,
   1914  1.1  riastrad 							  &pi->sys_info.sclk_voltage_mapping_table,
   1915  1.1  riastrad 							  igp_info->info_7.sAvail_SCLK);
   1916  1.1  riastrad 		sumo_construct_vid_mapping_table(rdev, &pi->sys_info.vid_mapping_table,
   1917  1.1  riastrad 						 igp_info->info_7.sAvail_SCLK);
   1918  1.1  riastrad 
   1919  1.1  riastrad 		pi->sys_info.uvd_clock_table_entries[0].vclk_did =
   1920  1.1  riastrad 			igp_info->info_7.ucDPMState0VclkFid;
   1921  1.1  riastrad 		pi->sys_info.uvd_clock_table_entries[1].vclk_did =
   1922  1.1  riastrad 			igp_info->info_7.ucDPMState1VclkFid;
   1923  1.1  riastrad 		pi->sys_info.uvd_clock_table_entries[2].vclk_did =
   1924  1.1  riastrad 			igp_info->info_7.ucDPMState2VclkFid;
   1925  1.1  riastrad 		pi->sys_info.uvd_clock_table_entries[3].vclk_did =
   1926  1.1  riastrad 			igp_info->info_7.ucDPMState3VclkFid;
   1927  1.1  riastrad 
   1928  1.1  riastrad 		pi->sys_info.uvd_clock_table_entries[0].dclk_did =
   1929  1.1  riastrad 			igp_info->info_7.ucDPMState0DclkFid;
   1930  1.1  riastrad 		pi->sys_info.uvd_clock_table_entries[1].dclk_did =
   1931  1.1  riastrad 			igp_info->info_7.ucDPMState1DclkFid;
   1932  1.1  riastrad 		pi->sys_info.uvd_clock_table_entries[2].dclk_did =
   1933  1.1  riastrad 			igp_info->info_7.ucDPMState2DclkFid;
   1934  1.1  riastrad 		pi->sys_info.uvd_clock_table_entries[3].dclk_did =
   1935  1.1  riastrad 			igp_info->info_7.ucDPMState3DclkFid;
   1936  1.1  riastrad 
   1937  1.1  riastrad 		for (i = 0; i < 4; i++) {
   1938  1.1  riastrad 			pi->sys_info.uvd_clock_table_entries[i].vclk =
   1939  1.1  riastrad 				trinity_convert_did_to_freq(rdev,
   1940  1.1  riastrad 							    pi->sys_info.uvd_clock_table_entries[i].vclk_did);
   1941  1.1  riastrad 			pi->sys_info.uvd_clock_table_entries[i].dclk =
   1942  1.1  riastrad 				trinity_convert_did_to_freq(rdev,
   1943  1.1  riastrad 							    pi->sys_info.uvd_clock_table_entries[i].dclk_did);
   1944  1.1  riastrad 		}
   1945  1.1  riastrad 
   1946  1.1  riastrad 
   1947  1.1  riastrad 
   1948  1.1  riastrad 	}
   1949  1.1  riastrad 	return 0;
   1950  1.1  riastrad }
   1951  1.1  riastrad 
   1952  1.1  riastrad int trinity_dpm_init(struct radeon_device *rdev)
   1953  1.1  riastrad {
   1954  1.1  riastrad 	struct trinity_power_info *pi;
   1955  1.1  riastrad 	int ret, i;
   1956  1.1  riastrad 
   1957  1.1  riastrad 	pi = kzalloc(sizeof(struct trinity_power_info), GFP_KERNEL);
   1958  1.1  riastrad 	if (pi == NULL)
   1959  1.1  riastrad 		return -ENOMEM;
   1960  1.1  riastrad 	rdev->pm.dpm.priv = pi;
   1961  1.1  riastrad 
   1962  1.1  riastrad 	for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++)
   1963  1.1  riastrad 		pi->at[i] = TRINITY_AT_DFLT;
   1964  1.1  riastrad 
   1965  1.1  riastrad 	if (radeon_bapm == -1) {
   1966  1.1  riastrad 		/* There are stability issues reported on with
   1967  1.1  riastrad 		 * bapm enabled when switching between AC and battery
   1968  1.1  riastrad 		 * power.  At the same time, some MSI boards hang
   1969  1.1  riastrad 		 * if it's not enabled and dpm is enabled.  Just enable
   1970  1.1  riastrad 		 * it for MSI boards right now.
   1971  1.1  riastrad 		 */
   1972  1.1  riastrad 		if (rdev->pdev->subsystem_vendor == 0x1462)
   1973  1.1  riastrad 			pi->enable_bapm = true;
   1974  1.1  riastrad 		else
   1975  1.1  riastrad 			pi->enable_bapm = false;
   1976  1.1  riastrad 	} else if (radeon_bapm == 0) {
   1977  1.1  riastrad 		pi->enable_bapm = false;
   1978  1.1  riastrad 	} else {
   1979  1.1  riastrad 		pi->enable_bapm = true;
   1980  1.1  riastrad 	}
   1981  1.1  riastrad 	pi->enable_nbps_policy = true;
   1982  1.1  riastrad 	pi->enable_sclk_ds = true;
   1983  1.1  riastrad 	pi->enable_gfx_power_gating = true;
   1984  1.1  riastrad 	pi->enable_gfx_clock_gating = true;
   1985  1.1  riastrad 	pi->enable_mg_clock_gating = false;
   1986  1.1  riastrad 	pi->enable_gfx_dynamic_mgpg = false;
   1987  1.1  riastrad 	pi->override_dynamic_mgpg = false;
   1988  1.1  riastrad 	pi->enable_auto_thermal_throttling = true;
   1989  1.1  riastrad 	pi->voltage_drop_in_dce = false; /* need to restructure dpm/modeset interaction */
   1990  1.1  riastrad 	pi->uvd_dpm = true; /* ??? */
   1991  1.1  riastrad 
   1992  1.1  riastrad 	ret = trinity_parse_sys_info_table(rdev);
   1993  1.1  riastrad 	if (ret)
   1994  1.1  riastrad 		return ret;
   1995  1.1  riastrad 
   1996  1.1  riastrad 	trinity_construct_boot_state(rdev);
   1997  1.1  riastrad 
   1998  1.1  riastrad 	ret = r600_get_platform_caps(rdev);
   1999  1.1  riastrad 	if (ret)
   2000  1.1  riastrad 		return ret;
   2001  1.1  riastrad 
   2002  1.1  riastrad 	ret = r600_parse_extended_power_table(rdev);
   2003  1.1  riastrad 	if (ret)
   2004  1.1  riastrad 		return ret;
   2005  1.1  riastrad 
   2006  1.1  riastrad 	ret = trinity_parse_power_table(rdev);
   2007  1.1  riastrad 	if (ret)
   2008  1.1  riastrad 		return ret;
   2009  1.1  riastrad 
   2010  1.1  riastrad 	pi->thermal_auto_throttling = pi->sys_info.htc_tmp_lmt;
   2011  1.1  riastrad 	pi->enable_dpm = true;
   2012  1.1  riastrad 
   2013  1.1  riastrad 	return 0;
   2014  1.1  riastrad }
   2015  1.1  riastrad 
   2016  1.1  riastrad void trinity_dpm_print_power_state(struct radeon_device *rdev,
   2017  1.1  riastrad 				   struct radeon_ps *rps)
   2018  1.1  riastrad {
   2019  1.1  riastrad 	int i;
   2020  1.1  riastrad 	struct trinity_ps *ps = trinity_get_ps(rps);
   2021  1.1  riastrad 
   2022  1.1  riastrad 	r600_dpm_print_class_info(rps->class, rps->class2);
   2023  1.1  riastrad 	r600_dpm_print_cap_info(rps->caps);
   2024  1.1  riastrad 	printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
   2025  1.1  riastrad 	for (i = 0; i < ps->num_levels; i++) {
   2026  1.1  riastrad 		struct trinity_pl *pl = &ps->levels[i];
   2027  1.1  riastrad 		printk("\t\tpower level %d    sclk: %u vddc: %u\n",
   2028  1.1  riastrad 		       i, pl->sclk,
   2029  1.1  riastrad 		       trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
   2030  1.1  riastrad 	}
   2031  1.1  riastrad 	r600_dpm_print_ps_status(rdev, rps);
   2032  1.1  riastrad }
   2033  1.1  riastrad 
   2034  1.1  riastrad #ifdef CONFIG_DEBUG_FS
   2035  1.1  riastrad void trinity_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
   2036  1.1  riastrad 							 struct seq_file *m)
   2037  1.1  riastrad {
   2038  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   2039  1.1  riastrad 	struct radeon_ps *rps = &pi->current_rps;
   2040  1.1  riastrad 	struct trinity_ps *ps = trinity_get_ps(rps);
   2041  1.1  riastrad 	struct trinity_pl *pl;
   2042  1.1  riastrad 	u32 current_index =
   2043  1.1  riastrad 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >>
   2044  1.1  riastrad 		CURRENT_STATE_SHIFT;
   2045  1.1  riastrad 
   2046  1.1  riastrad 	if (current_index >= ps->num_levels) {
   2047  1.1  riastrad 		seq_printf(m, "invalid dpm profile %d\n", current_index);
   2048  1.1  riastrad 	} else {
   2049  1.1  riastrad 		pl = &ps->levels[current_index];
   2050  1.1  riastrad 		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
   2051  1.1  riastrad 		seq_printf(m, "power level %d    sclk: %u vddc: %u\n",
   2052  1.1  riastrad 			   current_index, pl->sclk,
   2053  1.1  riastrad 			   trinity_convert_voltage_index_to_value(rdev, pl->vddc_index));
   2054  1.1  riastrad 	}
   2055  1.1  riastrad }
   2056  1.1  riastrad #endif
   2057  1.1  riastrad 
   2058  1.1  riastrad u32 trinity_dpm_get_current_sclk(struct radeon_device *rdev)
   2059  1.1  riastrad {
   2060  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   2061  1.1  riastrad 	struct radeon_ps *rps = &pi->current_rps;
   2062  1.1  riastrad 	struct trinity_ps *ps = trinity_get_ps(rps);
   2063  1.1  riastrad 	struct trinity_pl *pl;
   2064  1.1  riastrad 	u32 current_index =
   2065  1.1  riastrad 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_MASK) >>
   2066  1.1  riastrad 		CURRENT_STATE_SHIFT;
   2067  1.1  riastrad 
   2068  1.1  riastrad 	if (current_index >= ps->num_levels) {
   2069  1.1  riastrad 		return 0;
   2070  1.1  riastrad 	} else {
   2071  1.1  riastrad 		pl = &ps->levels[current_index];
   2072  1.1  riastrad 		return pl->sclk;
   2073  1.1  riastrad 	}
   2074  1.1  riastrad }
   2075  1.1  riastrad 
   2076  1.1  riastrad u32 trinity_dpm_get_current_mclk(struct radeon_device *rdev)
   2077  1.1  riastrad {
   2078  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   2079  1.1  riastrad 
   2080  1.1  riastrad 	return pi->sys_info.bootup_uma_clk;
   2081  1.1  riastrad }
   2082  1.1  riastrad 
   2083  1.1  riastrad void trinity_dpm_fini(struct radeon_device *rdev)
   2084  1.1  riastrad {
   2085  1.1  riastrad 	int i;
   2086  1.1  riastrad 
   2087  1.1  riastrad 	trinity_cleanup_asic(rdev); /* ??? */
   2088  1.1  riastrad 
   2089  1.1  riastrad 	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
   2090  1.1  riastrad 		kfree(rdev->pm.dpm.ps[i].ps_priv);
   2091  1.1  riastrad 	}
   2092  1.1  riastrad 	kfree(rdev->pm.dpm.ps);
   2093  1.1  riastrad 	kfree(rdev->pm.dpm.priv);
   2094  1.1  riastrad 	r600_free_extended_power_table(rdev);
   2095  1.1  riastrad }
   2096  1.1  riastrad 
   2097  1.1  riastrad u32 trinity_dpm_get_sclk(struct radeon_device *rdev, bool low)
   2098  1.1  riastrad {
   2099  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   2100  1.1  riastrad 	struct trinity_ps *requested_state = trinity_get_ps(&pi->requested_rps);
   2101  1.1  riastrad 
   2102  1.1  riastrad 	if (low)
   2103  1.1  riastrad 		return requested_state->levels[0].sclk;
   2104  1.1  riastrad 	else
   2105  1.1  riastrad 		return requested_state->levels[requested_state->num_levels - 1].sclk;
   2106  1.1  riastrad }
   2107  1.1  riastrad 
   2108  1.1  riastrad u32 trinity_dpm_get_mclk(struct radeon_device *rdev, bool low)
   2109  1.1  riastrad {
   2110  1.1  riastrad 	struct trinity_power_info *pi = trinity_get_pi(rdev);
   2111  1.1  riastrad 
   2112  1.1  riastrad 	return pi->sys_info.bootup_uma_clk;
   2113  1.1  riastrad }
   2114