Home | History | Annotate | Line # | Download | only in hwmgr
      1 /*	$NetBSD: amdgpu_vega20_processpptables.c,v 1.2 2021/12/18 23:45:26 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2018 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  */
     25 #include <sys/cdefs.h>
     26 __KERNEL_RCSID(0, "$NetBSD: amdgpu_vega20_processpptables.c,v 1.2 2021/12/18 23:45:26 riastradh Exp $");
     27 
     28 #include <linux/module.h>
     29 #include <linux/slab.h>
     30 #include <linux/fb.h>
     31 
     32 #include "smu11_driver_if.h"
     33 #include "vega20_processpptables.h"
     34 #include "ppatomfwctrl.h"
     35 #include "atomfirmware.h"
     36 #include "pp_debug.h"
     37 #include "cgs_common.h"
     38 #include "vega20_pptable.h"
     39 
     40 #define VEGA20_FAN_TARGET_TEMPERATURE_OVERRIDE 105
     41 
     42 static void set_hw_cap(struct pp_hwmgr *hwmgr, bool enable,
     43 		enum phm_platform_caps cap)
     44 {
     45 	if (enable)
     46 		phm_cap_set(hwmgr->platform_descriptor.platformCaps, cap);
     47 	else
     48 		phm_cap_unset(hwmgr->platform_descriptor.platformCaps, cap);
     49 }
     50 
     51 static const void *get_powerplay_table(struct pp_hwmgr *hwmgr)
     52 {
     53 	int index = GetIndexIntoMasterDataTable(powerplayinfo);
     54 
     55 	u16 size;
     56 	u8 frev, crev;
     57 	const void *table_address = hwmgr->soft_pp_table;
     58 
     59 	if (!table_address) {
     60 		table_address = (ATOM_Vega20_POWERPLAYTABLE *)
     61 				smu_atom_get_data_table(hwmgr->adev, index,
     62 						&size, &frev, &crev);
     63 
     64 		hwmgr->soft_pp_table = table_address;
     65 		hwmgr->soft_pp_table_size = size;
     66 	}
     67 
     68 	return table_address;
     69 }
     70 
     71 #if 0
     72 static void dump_pptable(PPTable_t *pptable)
     73 {
     74 	int i;
     75 
     76 	pr_info("Version = 0x%08x\n", pptable->Version);
     77 
     78 	pr_info("FeaturesToRun[0] = 0x%08x\n", pptable->FeaturesToRun[0]);
     79 	pr_info("FeaturesToRun[1] = 0x%08x\n", pptable->FeaturesToRun[1]);
     80 
     81 	pr_info("SocketPowerLimitAc0 = %d\n", pptable->SocketPowerLimitAc0);
     82 	pr_info("SocketPowerLimitAc0Tau = %d\n", pptable->SocketPowerLimitAc0Tau);
     83 	pr_info("SocketPowerLimitAc1 = %d\n", pptable->SocketPowerLimitAc1);
     84 	pr_info("SocketPowerLimitAc1Tau = %d\n", pptable->SocketPowerLimitAc1Tau);
     85 	pr_info("SocketPowerLimitAc2 = %d\n", pptable->SocketPowerLimitAc2);
     86 	pr_info("SocketPowerLimitAc2Tau = %d\n", pptable->SocketPowerLimitAc2Tau);
     87 	pr_info("SocketPowerLimitAc3 = %d\n", pptable->SocketPowerLimitAc3);
     88 	pr_info("SocketPowerLimitAc3Tau = %d\n", pptable->SocketPowerLimitAc3Tau);
     89 	pr_info("SocketPowerLimitDc = %d\n", pptable->SocketPowerLimitDc);
     90 	pr_info("SocketPowerLimitDcTau = %d\n", pptable->SocketPowerLimitDcTau);
     91 	pr_info("TdcLimitSoc = %d\n", pptable->TdcLimitSoc);
     92 	pr_info("TdcLimitSocTau = %d\n", pptable->TdcLimitSocTau);
     93 	pr_info("TdcLimitGfx = %d\n", pptable->TdcLimitGfx);
     94 	pr_info("TdcLimitGfxTau = %d\n", pptable->TdcLimitGfxTau);
     95 
     96 	pr_info("TedgeLimit = %d\n", pptable->TedgeLimit);
     97 	pr_info("ThotspotLimit = %d\n", pptable->ThotspotLimit);
     98 	pr_info("ThbmLimit = %d\n", pptable->ThbmLimit);
     99 	pr_info("Tvr_gfxLimit = %d\n", pptable->Tvr_gfxLimit);
    100 	pr_info("Tvr_memLimit = %d\n", pptable->Tvr_memLimit);
    101 	pr_info("Tliquid1Limit = %d\n", pptable->Tliquid1Limit);
    102 	pr_info("Tliquid2Limit = %d\n", pptable->Tliquid2Limit);
    103 	pr_info("TplxLimit = %d\n", pptable->TplxLimit);
    104 	pr_info("FitLimit = %d\n", pptable->FitLimit);
    105 
    106 	pr_info("PpmPowerLimit = %d\n", pptable->PpmPowerLimit);
    107 	pr_info("PpmTemperatureThreshold = %d\n", pptable->PpmTemperatureThreshold);
    108 
    109 	pr_info("MemoryOnPackage = 0x%02x\n", pptable->MemoryOnPackage);
    110 	pr_info("padding8_limits = 0x%02x\n", pptable->padding8_limits);
    111 	pr_info("Tvr_SocLimit = %d\n", pptable->Tvr_SocLimit);
    112 
    113 	pr_info("UlvVoltageOffsetSoc = %d\n", pptable->UlvVoltageOffsetSoc);
    114 	pr_info("UlvVoltageOffsetGfx = %d\n", pptable->UlvVoltageOffsetGfx);
    115 
    116 	pr_info("UlvSmnclkDid = %d\n", pptable->UlvSmnclkDid);
    117 	pr_info("UlvMp1clkDid = %d\n", pptable->UlvMp1clkDid);
    118 	pr_info("UlvGfxclkBypass = %d\n", pptable->UlvGfxclkBypass);
    119 	pr_info("Padding234 = 0x%02x\n", pptable->Padding234);
    120 
    121 	pr_info("MinVoltageGfx = %d\n", pptable->MinVoltageGfx);
    122 	pr_info("MinVoltageSoc = %d\n", pptable->MinVoltageSoc);
    123 	pr_info("MaxVoltageGfx = %d\n", pptable->MaxVoltageGfx);
    124 	pr_info("MaxVoltageSoc = %d\n", pptable->MaxVoltageSoc);
    125 
    126 	pr_info("LoadLineResistanceGfx = %d\n", pptable->LoadLineResistanceGfx);
    127 	pr_info("LoadLineResistanceSoc = %d\n", pptable->LoadLineResistanceSoc);
    128 
    129 	pr_info("[PPCLK_GFXCLK]\n"
    130 			"  .VoltageMode          = 0x%02x\n"
    131 			"  .SnapToDiscrete       = 0x%02x\n"
    132 			"  .NumDiscreteLevels    = 0x%02x\n"
    133 			"  .padding              = 0x%02x\n"
    134 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    135 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    136 			pptable->DpmDescriptor[PPCLK_GFXCLK].VoltageMode,
    137 			pptable->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete,
    138 			pptable->DpmDescriptor[PPCLK_GFXCLK].NumDiscreteLevels,
    139 			pptable->DpmDescriptor[PPCLK_GFXCLK].padding,
    140 			pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.m,
    141 			pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.b,
    142 			pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.a,
    143 			pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.b,
    144 			pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.c);
    145 
    146 	pr_info("[PPCLK_VCLK]\n"
    147 			"  .VoltageMode          = 0x%02x\n"
    148 			"  .SnapToDiscrete       = 0x%02x\n"
    149 			"  .NumDiscreteLevels    = 0x%02x\n"
    150 			"  .padding              = 0x%02x\n"
    151 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    152 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    153 			pptable->DpmDescriptor[PPCLK_VCLK].VoltageMode,
    154 			pptable->DpmDescriptor[PPCLK_VCLK].SnapToDiscrete,
    155 			pptable->DpmDescriptor[PPCLK_VCLK].NumDiscreteLevels,
    156 			pptable->DpmDescriptor[PPCLK_VCLK].padding,
    157 			pptable->DpmDescriptor[PPCLK_VCLK].ConversionToAvfsClk.m,
    158 			pptable->DpmDescriptor[PPCLK_VCLK].ConversionToAvfsClk.b,
    159 			pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.a,
    160 			pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.b,
    161 			pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.c);
    162 
    163 	pr_info("[PPCLK_DCLK]\n"
    164 			"  .VoltageMode          = 0x%02x\n"
    165 			"  .SnapToDiscrete       = 0x%02x\n"
    166 			"  .NumDiscreteLevels    = 0x%02x\n"
    167 			"  .padding              = 0x%02x\n"
    168 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    169 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    170 			pptable->DpmDescriptor[PPCLK_DCLK].VoltageMode,
    171 			pptable->DpmDescriptor[PPCLK_DCLK].SnapToDiscrete,
    172 			pptable->DpmDescriptor[PPCLK_DCLK].NumDiscreteLevels,
    173 			pptable->DpmDescriptor[PPCLK_DCLK].padding,
    174 			pptable->DpmDescriptor[PPCLK_DCLK].ConversionToAvfsClk.m,
    175 			pptable->DpmDescriptor[PPCLK_DCLK].ConversionToAvfsClk.b,
    176 			pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.a,
    177 			pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.b,
    178 			pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.c);
    179 
    180 	pr_info("[PPCLK_ECLK]\n"
    181 			"  .VoltageMode          = 0x%02x\n"
    182 			"  .SnapToDiscrete       = 0x%02x\n"
    183 			"  .NumDiscreteLevels    = 0x%02x\n"
    184 			"  .padding              = 0x%02x\n"
    185 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    186 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    187 			pptable->DpmDescriptor[PPCLK_ECLK].VoltageMode,
    188 			pptable->DpmDescriptor[PPCLK_ECLK].SnapToDiscrete,
    189 			pptable->DpmDescriptor[PPCLK_ECLK].NumDiscreteLevels,
    190 			pptable->DpmDescriptor[PPCLK_ECLK].padding,
    191 			pptable->DpmDescriptor[PPCLK_ECLK].ConversionToAvfsClk.m,
    192 			pptable->DpmDescriptor[PPCLK_ECLK].ConversionToAvfsClk.b,
    193 			pptable->DpmDescriptor[PPCLK_ECLK].SsCurve.a,
    194 			pptable->DpmDescriptor[PPCLK_ECLK].SsCurve.b,
    195 			pptable->DpmDescriptor[PPCLK_ECLK].SsCurve.c);
    196 
    197 	pr_info("[PPCLK_SOCCLK]\n"
    198 			"  .VoltageMode          = 0x%02x\n"
    199 			"  .SnapToDiscrete       = 0x%02x\n"
    200 			"  .NumDiscreteLevels    = 0x%02x\n"
    201 			"  .padding              = 0x%02x\n"
    202 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    203 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    204 			pptable->DpmDescriptor[PPCLK_SOCCLK].VoltageMode,
    205 			pptable->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete,
    206 			pptable->DpmDescriptor[PPCLK_SOCCLK].NumDiscreteLevels,
    207 			pptable->DpmDescriptor[PPCLK_SOCCLK].padding,
    208 			pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.m,
    209 			pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.b,
    210 			pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.a,
    211 			pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.b,
    212 			pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.c);
    213 
    214 	pr_info("[PPCLK_UCLK]\n"
    215 			"  .VoltageMode          = 0x%02x\n"
    216 			"  .SnapToDiscrete       = 0x%02x\n"
    217 			"  .NumDiscreteLevels    = 0x%02x\n"
    218 			"  .padding              = 0x%02x\n"
    219 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    220 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    221 			pptable->DpmDescriptor[PPCLK_UCLK].VoltageMode,
    222 			pptable->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete,
    223 			pptable->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels,
    224 			pptable->DpmDescriptor[PPCLK_UCLK].padding,
    225 			pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.m,
    226 			pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.b,
    227 			pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.a,
    228 			pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.b,
    229 			pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.c);
    230 
    231 	pr_info("[PPCLK_DCEFCLK]\n"
    232 			"  .VoltageMode          = 0x%02x\n"
    233 			"  .SnapToDiscrete       = 0x%02x\n"
    234 			"  .NumDiscreteLevels    = 0x%02x\n"
    235 			"  .padding              = 0x%02x\n"
    236 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    237 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    238 			pptable->DpmDescriptor[PPCLK_DCEFCLK].VoltageMode,
    239 			pptable->DpmDescriptor[PPCLK_DCEFCLK].SnapToDiscrete,
    240 			pptable->DpmDescriptor[PPCLK_DCEFCLK].NumDiscreteLevels,
    241 			pptable->DpmDescriptor[PPCLK_DCEFCLK].padding,
    242 			pptable->DpmDescriptor[PPCLK_DCEFCLK].ConversionToAvfsClk.m,
    243 			pptable->DpmDescriptor[PPCLK_DCEFCLK].ConversionToAvfsClk.b,
    244 			pptable->DpmDescriptor[PPCLK_DCEFCLK].SsCurve.a,
    245 			pptable->DpmDescriptor[PPCLK_DCEFCLK].SsCurve.b,
    246 			pptable->DpmDescriptor[PPCLK_DCEFCLK].SsCurve.c);
    247 
    248 	pr_info("[PPCLK_DISPCLK]\n"
    249 			"  .VoltageMode          = 0x%02x\n"
    250 			"  .SnapToDiscrete       = 0x%02x\n"
    251 			"  .NumDiscreteLevels    = 0x%02x\n"
    252 			"  .padding              = 0x%02x\n"
    253 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    254 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    255 			pptable->DpmDescriptor[PPCLK_DISPCLK].VoltageMode,
    256 			pptable->DpmDescriptor[PPCLK_DISPCLK].SnapToDiscrete,
    257 			pptable->DpmDescriptor[PPCLK_DISPCLK].NumDiscreteLevels,
    258 			pptable->DpmDescriptor[PPCLK_DISPCLK].padding,
    259 			pptable->DpmDescriptor[PPCLK_DISPCLK].ConversionToAvfsClk.m,
    260 			pptable->DpmDescriptor[PPCLK_DISPCLK].ConversionToAvfsClk.b,
    261 			pptable->DpmDescriptor[PPCLK_DISPCLK].SsCurve.a,
    262 			pptable->DpmDescriptor[PPCLK_DISPCLK].SsCurve.b,
    263 			pptable->DpmDescriptor[PPCLK_DISPCLK].SsCurve.c);
    264 
    265 	pr_info("[PPCLK_PIXCLK]\n"
    266 			"  .VoltageMode          = 0x%02x\n"
    267 			"  .SnapToDiscrete       = 0x%02x\n"
    268 			"  .NumDiscreteLevels    = 0x%02x\n"
    269 			"  .padding              = 0x%02x\n"
    270 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    271 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    272 			pptable->DpmDescriptor[PPCLK_PIXCLK].VoltageMode,
    273 			pptable->DpmDescriptor[PPCLK_PIXCLK].SnapToDiscrete,
    274 			pptable->DpmDescriptor[PPCLK_PIXCLK].NumDiscreteLevels,
    275 			pptable->DpmDescriptor[PPCLK_PIXCLK].padding,
    276 			pptable->DpmDescriptor[PPCLK_PIXCLK].ConversionToAvfsClk.m,
    277 			pptable->DpmDescriptor[PPCLK_PIXCLK].ConversionToAvfsClk.b,
    278 			pptable->DpmDescriptor[PPCLK_PIXCLK].SsCurve.a,
    279 			pptable->DpmDescriptor[PPCLK_PIXCLK].SsCurve.b,
    280 			pptable->DpmDescriptor[PPCLK_PIXCLK].SsCurve.c);
    281 
    282 	pr_info("[PPCLK_PHYCLK]\n"
    283 			"  .VoltageMode          = 0x%02x\n"
    284 			"  .SnapToDiscrete       = 0x%02x\n"
    285 			"  .NumDiscreteLevels    = 0x%02x\n"
    286 			"  .padding              = 0x%02x\n"
    287 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    288 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    289 			pptable->DpmDescriptor[PPCLK_PHYCLK].VoltageMode,
    290 			pptable->DpmDescriptor[PPCLK_PHYCLK].SnapToDiscrete,
    291 			pptable->DpmDescriptor[PPCLK_PHYCLK].NumDiscreteLevels,
    292 			pptable->DpmDescriptor[PPCLK_PHYCLK].padding,
    293 			pptable->DpmDescriptor[PPCLK_PHYCLK].ConversionToAvfsClk.m,
    294 			pptable->DpmDescriptor[PPCLK_PHYCLK].ConversionToAvfsClk.b,
    295 			pptable->DpmDescriptor[PPCLK_PHYCLK].SsCurve.a,
    296 			pptable->DpmDescriptor[PPCLK_PHYCLK].SsCurve.b,
    297 			pptable->DpmDescriptor[PPCLK_PHYCLK].SsCurve.c);
    298 
    299 	pr_info("[PPCLK_FCLK]\n"
    300 			"  .VoltageMode          = 0x%02x\n"
    301 			"  .SnapToDiscrete       = 0x%02x\n"
    302 			"  .NumDiscreteLevels    = 0x%02x\n"
    303 			"  .padding              = 0x%02x\n"
    304 			"  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
    305 			"  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n",
    306 			pptable->DpmDescriptor[PPCLK_FCLK].VoltageMode,
    307 			pptable->DpmDescriptor[PPCLK_FCLK].SnapToDiscrete,
    308 			pptable->DpmDescriptor[PPCLK_FCLK].NumDiscreteLevels,
    309 			pptable->DpmDescriptor[PPCLK_FCLK].padding,
    310 			pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.m,
    311 			pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.b,
    312 			pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.a,
    313 			pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.b,
    314 			pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.c);
    315 
    316 
    317 	pr_info("FreqTableGfx\n");
    318 	for (i = 0; i < NUM_GFXCLK_DPM_LEVELS; i++)
    319 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTableGfx[i]);
    320 
    321 	pr_info("FreqTableVclk\n");
    322 	for (i = 0; i < NUM_VCLK_DPM_LEVELS; i++)
    323 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTableVclk[i]);
    324 
    325 	pr_info("FreqTableDclk\n");
    326 	for (i = 0; i < NUM_DCLK_DPM_LEVELS; i++)
    327 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTableDclk[i]);
    328 
    329 	pr_info("FreqTableEclk\n");
    330 	for (i = 0; i < NUM_ECLK_DPM_LEVELS; i++)
    331 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTableEclk[i]);
    332 
    333 	pr_info("FreqTableSocclk\n");
    334 	for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++)
    335 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTableSocclk[i]);
    336 
    337 	pr_info("FreqTableUclk\n");
    338 	for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
    339 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTableUclk[i]);
    340 
    341 	pr_info("FreqTableFclk\n");
    342 	for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++)
    343 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTableFclk[i]);
    344 
    345 	pr_info("FreqTableDcefclk\n");
    346 	for (i = 0; i < NUM_DCEFCLK_DPM_LEVELS; i++)
    347 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTableDcefclk[i]);
    348 
    349 	pr_info("FreqTableDispclk\n");
    350 	for (i = 0; i < NUM_DISPCLK_DPM_LEVELS; i++)
    351 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTableDispclk[i]);
    352 
    353 	pr_info("FreqTablePixclk\n");
    354 	for (i = 0; i < NUM_PIXCLK_DPM_LEVELS; i++)
    355 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTablePixclk[i]);
    356 
    357 	pr_info("FreqTablePhyclk\n");
    358 	for (i = 0; i < NUM_PHYCLK_DPM_LEVELS; i++)
    359 		pr_info("  .[%02d] = %d\n", i, pptable->FreqTablePhyclk[i]);
    360 
    361 	pr_info("DcModeMaxFreq[PPCLK_GFXCLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_GFXCLK]);
    362 	pr_info("DcModeMaxFreq[PPCLK_VCLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_VCLK]);
    363 	pr_info("DcModeMaxFreq[PPCLK_DCLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_DCLK]);
    364 	pr_info("DcModeMaxFreq[PPCLK_ECLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_ECLK]);
    365 	pr_info("DcModeMaxFreq[PPCLK_SOCCLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_SOCCLK]);
    366 	pr_info("DcModeMaxFreq[PPCLK_UCLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_UCLK]);
    367 	pr_info("DcModeMaxFreq[PPCLK_DCEFCLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_DCEFCLK]);
    368 	pr_info("DcModeMaxFreq[PPCLK_DISPCLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_DISPCLK]);
    369 	pr_info("DcModeMaxFreq[PPCLK_PIXCLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_PIXCLK]);
    370 	pr_info("DcModeMaxFreq[PPCLK_PHYCLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_PHYCLK]);
    371 	pr_info("DcModeMaxFreq[PPCLK_FCLK] = %d\n", pptable->DcModeMaxFreq[PPCLK_FCLK]);
    372 	pr_info("Padding8_Clks = %d\n", pptable->Padding8_Clks);
    373 
    374 	pr_info("Mp0clkFreq\n");
    375 	for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
    376 		pr_info("  .[%d] = %d\n", i, pptable->Mp0clkFreq[i]);
    377 
    378 	pr_info("Mp0DpmVoltage\n");
    379 	for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
    380 		pr_info("  .[%d] = %d\n", i, pptable->Mp0DpmVoltage[i]);
    381 
    382 	pr_info("GfxclkFidle = 0x%x\n", pptable->GfxclkFidle);
    383 	pr_info("GfxclkSlewRate = 0x%x\n", pptable->GfxclkSlewRate);
    384 	pr_info("CksEnableFreq = 0x%x\n", pptable->CksEnableFreq);
    385 	pr_info("Padding789 = 0x%x\n", pptable->Padding789);
    386 	pr_info("CksVoltageOffset[a = 0x%08x b = 0x%08x c = 0x%08x]\n",
    387 			pptable->CksVoltageOffset.a,
    388 			pptable->CksVoltageOffset.b,
    389 			pptable->CksVoltageOffset.c);
    390 	pr_info("Padding567[0] = 0x%x\n", pptable->Padding567[0]);
    391 	pr_info("Padding567[1] = 0x%x\n", pptable->Padding567[1]);
    392 	pr_info("Padding567[2] = 0x%x\n", pptable->Padding567[2]);
    393 	pr_info("Padding567[3] = 0x%x\n", pptable->Padding567[3]);
    394 	pr_info("GfxclkDsMaxFreq = %d\n", pptable->GfxclkDsMaxFreq);
    395 	pr_info("GfxclkSource = 0x%x\n", pptable->GfxclkSource);
    396 	pr_info("Padding456 = 0x%x\n", pptable->Padding456);
    397 
    398 	pr_info("LowestUclkReservedForUlv = %d\n", pptable->LowestUclkReservedForUlv);
    399 	pr_info("Padding8_Uclk[0] = 0x%x\n", pptable->Padding8_Uclk[0]);
    400 	pr_info("Padding8_Uclk[1] = 0x%x\n", pptable->Padding8_Uclk[1]);
    401 	pr_info("Padding8_Uclk[2] = 0x%x\n", pptable->Padding8_Uclk[2]);
    402 
    403 	pr_info("PcieGenSpeed\n");
    404 	for (i = 0; i < NUM_LINK_LEVELS; i++)
    405 		pr_info("  .[%d] = %d\n", i, pptable->PcieGenSpeed[i]);
    406 
    407 	pr_info("PcieLaneCount\n");
    408 	for (i = 0; i < NUM_LINK_LEVELS; i++)
    409 		pr_info("  .[%d] = %d\n", i, pptable->PcieLaneCount[i]);
    410 
    411 	pr_info("LclkFreq\n");
    412 	for (i = 0; i < NUM_LINK_LEVELS; i++)
    413 		pr_info("  .[%d] = %d\n", i, pptable->LclkFreq[i]);
    414 
    415 	pr_info("EnableTdpm = %d\n", pptable->EnableTdpm);
    416 	pr_info("TdpmHighHystTemperature = %d\n", pptable->TdpmHighHystTemperature);
    417 	pr_info("TdpmLowHystTemperature = %d\n", pptable->TdpmLowHystTemperature);
    418 	pr_info("GfxclkFreqHighTempLimit = %d\n", pptable->GfxclkFreqHighTempLimit);
    419 
    420 	pr_info("FanStopTemp = %d\n", pptable->FanStopTemp);
    421 	pr_info("FanStartTemp = %d\n", pptable->FanStartTemp);
    422 
    423 	pr_info("FanGainEdge = %d\n", pptable->FanGainEdge);
    424 	pr_info("FanGainHotspot = %d\n", pptable->FanGainHotspot);
    425 	pr_info("FanGainLiquid = %d\n", pptable->FanGainLiquid);
    426 	pr_info("FanGainVrGfx = %d\n", pptable->FanGainVrGfx);
    427 	pr_info("FanGainVrSoc = %d\n", pptable->FanGainVrSoc);
    428 	pr_info("FanGainPlx = %d\n", pptable->FanGainPlx);
    429 	pr_info("FanGainHbm = %d\n", pptable->FanGainHbm);
    430 	pr_info("FanPwmMin = %d\n", pptable->FanPwmMin);
    431 	pr_info("FanAcousticLimitRpm = %d\n", pptable->FanAcousticLimitRpm);
    432 	pr_info("FanThrottlingRpm = %d\n", pptable->FanThrottlingRpm);
    433 	pr_info("FanMaximumRpm = %d\n", pptable->FanMaximumRpm);
    434 	pr_info("FanTargetTemperature = %d\n", pptable->FanTargetTemperature);
    435 	pr_info("FanTargetGfxclk = %d\n", pptable->FanTargetGfxclk);
    436 	pr_info("FanZeroRpmEnable = %d\n", pptable->FanZeroRpmEnable);
    437 	pr_info("FanTachEdgePerRev = %d\n", pptable->FanTachEdgePerRev);
    438 
    439 	pr_info("FuzzyFan_ErrorSetDelta = %d\n", pptable->FuzzyFan_ErrorSetDelta);
    440 	pr_info("FuzzyFan_ErrorRateSetDelta = %d\n", pptable->FuzzyFan_ErrorRateSetDelta);
    441 	pr_info("FuzzyFan_PwmSetDelta = %d\n", pptable->FuzzyFan_PwmSetDelta);
    442 	pr_info("FuzzyFan_Reserved = %d\n", pptable->FuzzyFan_Reserved);
    443 
    444 	pr_info("OverrideAvfsGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_GFX]);
    445 	pr_info("OverrideAvfsGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_SOC]);
    446 	pr_info("Padding8_Avfs[0] = %d\n", pptable->Padding8_Avfs[0]);
    447 	pr_info("Padding8_Avfs[1] = %d\n", pptable->Padding8_Avfs[1]);
    448 
    449 	pr_info("qAvfsGb[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
    450 			pptable->qAvfsGb[AVFS_VOLTAGE_GFX].a,
    451 			pptable->qAvfsGb[AVFS_VOLTAGE_GFX].b,
    452 			pptable->qAvfsGb[AVFS_VOLTAGE_GFX].c);
    453 	pr_info("qAvfsGb[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
    454 			pptable->qAvfsGb[AVFS_VOLTAGE_SOC].a,
    455 			pptable->qAvfsGb[AVFS_VOLTAGE_SOC].b,
    456 			pptable->qAvfsGb[AVFS_VOLTAGE_SOC].c);
    457 	pr_info("dBtcGbGfxCksOn{a = 0x%x b = 0x%x c = 0x%x}\n",
    458 			pptable->dBtcGbGfxCksOn.a,
    459 			pptable->dBtcGbGfxCksOn.b,
    460 			pptable->dBtcGbGfxCksOn.c);
    461 	pr_info("dBtcGbGfxCksOff{a = 0x%x b = 0x%x c = 0x%x}\n",
    462 			pptable->dBtcGbGfxCksOff.a,
    463 			pptable->dBtcGbGfxCksOff.b,
    464 			pptable->dBtcGbGfxCksOff.c);
    465 	pr_info("dBtcGbGfxAfll{a = 0x%x b = 0x%x c = 0x%x}\n",
    466 			pptable->dBtcGbGfxAfll.a,
    467 			pptable->dBtcGbGfxAfll.b,
    468 			pptable->dBtcGbGfxAfll.c);
    469 	pr_info("dBtcGbSoc{a = 0x%x b = 0x%x c = 0x%x}\n",
    470 			pptable->dBtcGbSoc.a,
    471 			pptable->dBtcGbSoc.b,
    472 			pptable->dBtcGbSoc.c);
    473 	pr_info("qAgingGb[AVFS_VOLTAGE_GFX]{m = 0x%x b = 0x%x}\n",
    474 			pptable->qAgingGb[AVFS_VOLTAGE_GFX].m,
    475 			pptable->qAgingGb[AVFS_VOLTAGE_GFX].b);
    476 	pr_info("qAgingGb[AVFS_VOLTAGE_SOC]{m = 0x%x b = 0x%x}\n",
    477 			pptable->qAgingGb[AVFS_VOLTAGE_SOC].m,
    478 			pptable->qAgingGb[AVFS_VOLTAGE_SOC].b);
    479 
    480 	pr_info("qStaticVoltageOffset[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
    481 			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].a,
    482 			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].b,
    483 			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].c);
    484 	pr_info("qStaticVoltageOffset[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
    485 			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].a,
    486 			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].b,
    487 			pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].c);
    488 
    489 	pr_info("DcTol[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_GFX]);
    490 	pr_info("DcTol[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_SOC]);
    491 
    492 	pr_info("DcBtcEnabled[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_GFX]);
    493 	pr_info("DcBtcEnabled[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_SOC]);
    494 	pr_info("Padding8_GfxBtc[0] = 0x%x\n", pptable->Padding8_GfxBtc[0]);
    495 	pr_info("Padding8_GfxBtc[1] = 0x%x\n", pptable->Padding8_GfxBtc[1]);
    496 
    497 	pr_info("DcBtcMin[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_GFX]);
    498 	pr_info("DcBtcMin[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_SOC]);
    499 	pr_info("DcBtcMax[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_GFX]);
    500 	pr_info("DcBtcMax[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_SOC]);
    501 
    502 	pr_info("XgmiLinkSpeed\n");
    503 	for (i = 0; i < NUM_XGMI_LEVELS; i++)
    504 		pr_info("  .[%d] = %d\n", i, pptable->XgmiLinkSpeed[i]);
    505 	pr_info("XgmiLinkWidth\n");
    506 	for (i = 0; i < NUM_XGMI_LEVELS; i++)
    507 		pr_info("  .[%d] = %d\n", i, pptable->XgmiLinkWidth[i]);
    508 	pr_info("XgmiFclkFreq\n");
    509 	for (i = 0; i < NUM_XGMI_LEVELS; i++)
    510 		pr_info("  .[%d] = %d\n", i, pptable->XgmiFclkFreq[i]);
    511 	pr_info("XgmiUclkFreq\n");
    512 	for (i = 0; i < NUM_XGMI_LEVELS; i++)
    513 		pr_info("  .[%d] = %d\n", i, pptable->XgmiUclkFreq[i]);
    514 	pr_info("XgmiSocclkFreq\n");
    515 	for (i = 0; i < NUM_XGMI_LEVELS; i++)
    516 		pr_info("  .[%d] = %d\n", i, pptable->XgmiSocclkFreq[i]);
    517 	pr_info("XgmiSocVoltage\n");
    518 	for (i = 0; i < NUM_XGMI_LEVELS; i++)
    519 		pr_info("  .[%d] = %d\n", i, pptable->XgmiSocVoltage[i]);
    520 
    521 	pr_info("DebugOverrides = 0x%x\n", pptable->DebugOverrides);
    522 	pr_info("ReservedEquation0{a = 0x%x b = 0x%x c = 0x%x}\n",
    523 			pptable->ReservedEquation0.a,
    524 			pptable->ReservedEquation0.b,
    525 			pptable->ReservedEquation0.c);
    526 	pr_info("ReservedEquation1{a = 0x%x b = 0x%x c = 0x%x}\n",
    527 			pptable->ReservedEquation1.a,
    528 			pptable->ReservedEquation1.b,
    529 			pptable->ReservedEquation1.c);
    530 	pr_info("ReservedEquation2{a = 0x%x b = 0x%x c = 0x%x}\n",
    531 			pptable->ReservedEquation2.a,
    532 			pptable->ReservedEquation2.b,
    533 			pptable->ReservedEquation2.c);
    534 	pr_info("ReservedEquation3{a = 0x%x b = 0x%x c = 0x%x}\n",
    535 			pptable->ReservedEquation3.a,
    536 			pptable->ReservedEquation3.b,
    537 			pptable->ReservedEquation3.c);
    538 
    539 	pr_info("MinVoltageUlvGfx = %d\n", pptable->MinVoltageUlvGfx);
    540 	pr_info("MinVoltageUlvSoc = %d\n", pptable->MinVoltageUlvSoc);
    541 
    542 	pr_info("MGpuFanBoostLimitRpm = %d\n", pptable->MGpuFanBoostLimitRpm);
    543 	pr_info("padding16_Fan = %d\n", pptable->padding16_Fan);
    544 
    545 	pr_info("FanGainVrMem0 = %d\n", pptable->FanGainVrMem0);
    546 	pr_info("FanGainVrMem0 = %d\n", pptable->FanGainVrMem0);
    547 
    548 	pr_info("DcBtcGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_GFX]);
    549 	pr_info("DcBtcGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_SOC]);
    550 
    551 	for (i = 0; i < 11; i++)
    552 		pr_info("Reserved[%d] = 0x%x\n", i, pptable->Reserved[i]);
    553 
    554 	for (i = 0; i < 3; i++)
    555 		pr_info("Padding32[%d] = 0x%x\n", i, pptable->Padding32[i]);
    556 
    557 	pr_info("MaxVoltageStepGfx = 0x%x\n", pptable->MaxVoltageStepGfx);
    558 	pr_info("MaxVoltageStepSoc = 0x%x\n", pptable->MaxVoltageStepSoc);
    559 
    560 	pr_info("VddGfxVrMapping = 0x%x\n", pptable->VddGfxVrMapping);
    561 	pr_info("VddSocVrMapping = 0x%x\n", pptable->VddSocVrMapping);
    562 	pr_info("VddMem0VrMapping = 0x%x\n", pptable->VddMem0VrMapping);
    563 	pr_info("VddMem1VrMapping = 0x%x\n", pptable->VddMem1VrMapping);
    564 
    565 	pr_info("GfxUlvPhaseSheddingMask = 0x%x\n", pptable->GfxUlvPhaseSheddingMask);
    566 	pr_info("SocUlvPhaseSheddingMask = 0x%x\n", pptable->SocUlvPhaseSheddingMask);
    567 	pr_info("ExternalSensorPresent = 0x%x\n", pptable->ExternalSensorPresent);
    568 	pr_info("Padding8_V = 0x%x\n", pptable->Padding8_V);
    569 
    570 	pr_info("GfxMaxCurrent = 0x%x\n", pptable->GfxMaxCurrent);
    571 	pr_info("GfxOffset = 0x%x\n", pptable->GfxOffset);
    572 	pr_info("Padding_TelemetryGfx = 0x%x\n", pptable->Padding_TelemetryGfx);
    573 
    574 	pr_info("SocMaxCurrent = 0x%x\n", pptable->SocMaxCurrent);
    575 	pr_info("SocOffset = 0x%x\n", pptable->SocOffset);
    576 	pr_info("Padding_TelemetrySoc = 0x%x\n", pptable->Padding_TelemetrySoc);
    577 
    578 	pr_info("Mem0MaxCurrent = 0x%x\n", pptable->Mem0MaxCurrent);
    579 	pr_info("Mem0Offset = 0x%x\n", pptable->Mem0Offset);
    580 	pr_info("Padding_TelemetryMem0 = 0x%x\n", pptable->Padding_TelemetryMem0);
    581 
    582 	pr_info("Mem1MaxCurrent = 0x%x\n", pptable->Mem1MaxCurrent);
    583 	pr_info("Mem1Offset = 0x%x\n", pptable->Mem1Offset);
    584 	pr_info("Padding_TelemetryMem1 = 0x%x\n", pptable->Padding_TelemetryMem1);
    585 
    586 	pr_info("AcDcGpio = %d\n", pptable->AcDcGpio);
    587 	pr_info("AcDcPolarity = %d\n", pptable->AcDcPolarity);
    588 	pr_info("VR0HotGpio = %d\n", pptable->VR0HotGpio);
    589 	pr_info("VR0HotPolarity = %d\n", pptable->VR0HotPolarity);
    590 
    591 	pr_info("VR1HotGpio = %d\n", pptable->VR1HotGpio);
    592 	pr_info("VR1HotPolarity = %d\n", pptable->VR1HotPolarity);
    593 	pr_info("Padding1 = 0x%x\n", pptable->Padding1);
    594 	pr_info("Padding2 = 0x%x\n", pptable->Padding2);
    595 
    596 	pr_info("LedPin0 = %d\n", pptable->LedPin0);
    597 	pr_info("LedPin1 = %d\n", pptable->LedPin1);
    598 	pr_info("LedPin2 = %d\n", pptable->LedPin2);
    599 	pr_info("padding8_4 = 0x%x\n", pptable->padding8_4);
    600 
    601 	pr_info("PllGfxclkSpreadEnabled = %d\n", pptable->PllGfxclkSpreadEnabled);
    602 	pr_info("PllGfxclkSpreadPercent = %d\n", pptable->PllGfxclkSpreadPercent);
    603 	pr_info("PllGfxclkSpreadFreq = %d\n", pptable->PllGfxclkSpreadFreq);
    604 
    605 	pr_info("UclkSpreadEnabled = %d\n", pptable->UclkSpreadEnabled);
    606 	pr_info("UclkSpreadPercent = %d\n", pptable->UclkSpreadPercent);
    607 	pr_info("UclkSpreadFreq = %d\n", pptable->UclkSpreadFreq);
    608 
    609 	pr_info("FclkSpreadEnabled = %d\n", pptable->FclkSpreadEnabled);
    610 	pr_info("FclkSpreadPercent = %d\n", pptable->FclkSpreadPercent);
    611 	pr_info("FclkSpreadFreq = %d\n", pptable->FclkSpreadFreq);
    612 
    613 	pr_info("FllGfxclkSpreadEnabled = %d\n", pptable->FllGfxclkSpreadEnabled);
    614 	pr_info("FllGfxclkSpreadPercent = %d\n", pptable->FllGfxclkSpreadPercent);
    615 	pr_info("FllGfxclkSpreadFreq = %d\n", pptable->FllGfxclkSpreadFreq);
    616 
    617 	for (i = 0; i < I2C_CONTROLLER_NAME_COUNT; i++) {
    618 		pr_info("I2cControllers[%d]:\n", i);
    619 		pr_info("                   .Enabled = %d\n",
    620 				pptable->I2cControllers[i].Enabled);
    621 		pr_info("                   .SlaveAddress = 0x%x\n",
    622 				pptable->I2cControllers[i].SlaveAddress);
    623 		pr_info("                   .ControllerPort = %d\n",
    624 				pptable->I2cControllers[i].ControllerPort);
    625 		pr_info("                   .ControllerName = %d\n",
    626 				pptable->I2cControllers[i].ControllerName);
    627 		pr_info("                   .ThermalThrottler = %d\n",
    628 				pptable->I2cControllers[i].ThermalThrottler);
    629 		pr_info("                   .I2cProtocol = %d\n",
    630 				pptable->I2cControllers[i].I2cProtocol);
    631 		pr_info("                   .I2cSpeed = %d\n",
    632 				pptable->I2cControllers[i].I2cSpeed);
    633 	}
    634 
    635 	for (i = 0; i < 10; i++)
    636 		pr_info("BoardReserved[%d] = 0x%x\n", i, pptable->BoardReserved[i]);
    637 
    638 	for (i = 0; i < 8; i++)
    639 		pr_info("MmHubPadding[%d] = 0x%x\n", i, pptable->MmHubPadding[i]);
    640 }
    641 #endif
    642 
    643 static int check_powerplay_tables(
    644 		struct pp_hwmgr *hwmgr,
    645 		const ATOM_Vega20_POWERPLAYTABLE *powerplay_table)
    646 {
    647 	PP_ASSERT_WITH_CODE((powerplay_table->sHeader.format_revision >=
    648 		ATOM_VEGA20_TABLE_REVISION_VEGA20),
    649 		"Unsupported PPTable format!", return -1);
    650 	PP_ASSERT_WITH_CODE(powerplay_table->sHeader.structuresize > 0,
    651 		"Invalid PowerPlay Table!", return -1);
    652 
    653 	if (powerplay_table->smcPPTable.Version != PPTABLE_V20_SMU_VERSION) {
    654 		pr_info("Unmatch PPTable version: "
    655 			"pptable from VBIOS is V%d while driver supported is V%d!",
    656 			powerplay_table->smcPPTable.Version,
    657 			PPTABLE_V20_SMU_VERSION);
    658 		return -EINVAL;
    659 	}
    660 
    661 	//dump_pptable(&powerplay_table->smcPPTable);
    662 
    663 	return 0;
    664 }
    665 
    666 static int set_platform_caps(struct pp_hwmgr *hwmgr, uint32_t powerplay_caps)
    667 {
    668 	set_hw_cap(
    669 		hwmgr,
    670 		0 != (powerplay_caps & ATOM_VEGA20_PP_PLATFORM_CAP_POWERPLAY),
    671 		PHM_PlatformCaps_PowerPlaySupport);
    672 
    673 	set_hw_cap(
    674 		hwmgr,
    675 		0 != (powerplay_caps & ATOM_VEGA20_PP_PLATFORM_CAP_SBIOSPOWERSOURCE),
    676 		PHM_PlatformCaps_BiosPowerSourceControl);
    677 
    678 	set_hw_cap(
    679 		hwmgr,
    680 		0 != (powerplay_caps & ATOM_VEGA20_PP_PLATFORM_CAP_BACO),
    681 		PHM_PlatformCaps_BACO);
    682 
    683 	set_hw_cap(
    684 		hwmgr,
    685 		0 != (powerplay_caps & ATOM_VEGA20_PP_PLATFORM_CAP_BAMACO),
    686 		 PHM_PlatformCaps_BAMACO);
    687 
    688 	return 0;
    689 }
    690 
    691 static int copy_overdrive_feature_capabilities_array(
    692 		struct pp_hwmgr *hwmgr,
    693 		uint8_t **pptable_info_array,
    694 		const uint8_t *pptable_array,
    695 		uint8_t od_feature_count)
    696 {
    697 	uint32_t array_size, i;
    698 	uint8_t *table;
    699 	bool od_supported = false;
    700 
    701 	array_size = sizeof(uint8_t) * od_feature_count;
    702 	table = kzalloc(array_size, GFP_KERNEL);
    703 	if (NULL == table)
    704 		return -ENOMEM;
    705 
    706 	for (i = 0; i < od_feature_count; i++) {
    707 		table[i] = le32_to_cpu(pptable_array[i]);
    708 		if (table[i])
    709 			od_supported = true;
    710 	}
    711 
    712 	*pptable_info_array = table;
    713 
    714 	if (od_supported)
    715 		phm_cap_set(hwmgr->platform_descriptor.platformCaps,
    716 				PHM_PlatformCaps_ACOverdriveSupport);
    717 
    718 	return 0;
    719 }
    720 
    721 static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable)
    722 {
    723 	struct atom_smc_dpm_info_v4_4 *smc_dpm_table;
    724 	int index = GetIndexIntoMasterDataTable(smc_dpm_info);
    725 	int i;
    726 
    727 	PP_ASSERT_WITH_CODE(
    728 		smc_dpm_table = smu_atom_get_data_table(hwmgr->adev, index, NULL, NULL, NULL),
    729 		"[appendVbiosPPTable] Failed to retrieve Smc Dpm Table from VBIOS!",
    730 		return -1);
    731 
    732 	ppsmc_pptable->MaxVoltageStepGfx = smc_dpm_table->maxvoltagestepgfx;
    733 	ppsmc_pptable->MaxVoltageStepSoc = smc_dpm_table->maxvoltagestepsoc;
    734 
    735 	ppsmc_pptable->VddGfxVrMapping = smc_dpm_table->vddgfxvrmapping;
    736 	ppsmc_pptable->VddSocVrMapping = smc_dpm_table->vddsocvrmapping;
    737 	ppsmc_pptable->VddMem0VrMapping = smc_dpm_table->vddmem0vrmapping;
    738 	ppsmc_pptable->VddMem1VrMapping = smc_dpm_table->vddmem1vrmapping;
    739 
    740 	ppsmc_pptable->GfxUlvPhaseSheddingMask = smc_dpm_table->gfxulvphasesheddingmask;
    741 	ppsmc_pptable->SocUlvPhaseSheddingMask = smc_dpm_table->soculvphasesheddingmask;
    742 	ppsmc_pptable->ExternalSensorPresent = smc_dpm_table->externalsensorpresent;
    743 
    744 	ppsmc_pptable->GfxMaxCurrent = smc_dpm_table->gfxmaxcurrent;
    745 	ppsmc_pptable->GfxOffset = smc_dpm_table->gfxoffset;
    746 	ppsmc_pptable->Padding_TelemetryGfx = smc_dpm_table->padding_telemetrygfx;
    747 
    748 	ppsmc_pptable->SocMaxCurrent = smc_dpm_table->socmaxcurrent;
    749 	ppsmc_pptable->SocOffset = smc_dpm_table->socoffset;
    750 	ppsmc_pptable->Padding_TelemetrySoc = smc_dpm_table->padding_telemetrysoc;
    751 
    752 	ppsmc_pptable->Mem0MaxCurrent = smc_dpm_table->mem0maxcurrent;
    753 	ppsmc_pptable->Mem0Offset = smc_dpm_table->mem0offset;
    754 	ppsmc_pptable->Padding_TelemetryMem0 = smc_dpm_table->padding_telemetrymem0;
    755 
    756 	ppsmc_pptable->Mem1MaxCurrent = smc_dpm_table->mem1maxcurrent;
    757 	ppsmc_pptable->Mem1Offset = smc_dpm_table->mem1offset;
    758 	ppsmc_pptable->Padding_TelemetryMem1 = smc_dpm_table->padding_telemetrymem1;
    759 
    760 	ppsmc_pptable->AcDcGpio = smc_dpm_table->acdcgpio;
    761 	ppsmc_pptable->AcDcPolarity = smc_dpm_table->acdcpolarity;
    762 	ppsmc_pptable->VR0HotGpio = smc_dpm_table->vr0hotgpio;
    763 	ppsmc_pptable->VR0HotPolarity = smc_dpm_table->vr0hotpolarity;
    764 
    765 	ppsmc_pptable->VR1HotGpio = smc_dpm_table->vr1hotgpio;
    766 	ppsmc_pptable->VR1HotPolarity = smc_dpm_table->vr1hotpolarity;
    767 	ppsmc_pptable->Padding1 = smc_dpm_table->padding1;
    768 	ppsmc_pptable->Padding2 = smc_dpm_table->padding2;
    769 
    770 	ppsmc_pptable->LedPin0 = smc_dpm_table->ledpin0;
    771 	ppsmc_pptable->LedPin1 = smc_dpm_table->ledpin1;
    772 	ppsmc_pptable->LedPin2 = smc_dpm_table->ledpin2;
    773 
    774 	ppsmc_pptable->PllGfxclkSpreadEnabled = smc_dpm_table->pllgfxclkspreadenabled;
    775 	ppsmc_pptable->PllGfxclkSpreadPercent = smc_dpm_table->pllgfxclkspreadpercent;
    776 	ppsmc_pptable->PllGfxclkSpreadFreq = smc_dpm_table->pllgfxclkspreadfreq;
    777 
    778 	ppsmc_pptable->UclkSpreadEnabled = 0;
    779 	ppsmc_pptable->UclkSpreadPercent = smc_dpm_table->uclkspreadpercent;
    780 	ppsmc_pptable->UclkSpreadFreq = smc_dpm_table->uclkspreadfreq;
    781 
    782 	ppsmc_pptable->FclkSpreadEnabled = smc_dpm_table->fclkspreadenabled;
    783 	ppsmc_pptable->FclkSpreadPercent = smc_dpm_table->fclkspreadpercent;
    784 	ppsmc_pptable->FclkSpreadFreq = smc_dpm_table->fclkspreadfreq;
    785 
    786 	ppsmc_pptable->FllGfxclkSpreadEnabled = smc_dpm_table->fllgfxclkspreadenabled;
    787 	ppsmc_pptable->FllGfxclkSpreadPercent = smc_dpm_table->fllgfxclkspreadpercent;
    788 	ppsmc_pptable->FllGfxclkSpreadFreq = smc_dpm_table->fllgfxclkspreadfreq;
    789 
    790 	for (i = 0; i < I2C_CONTROLLER_NAME_COUNT; i++) {
    791 		ppsmc_pptable->I2cControllers[i].Enabled =
    792 			smc_dpm_table->i2ccontrollers[i].enabled;
    793 		ppsmc_pptable->I2cControllers[i].SlaveAddress =
    794 			smc_dpm_table->i2ccontrollers[i].slaveaddress;
    795 		ppsmc_pptable->I2cControllers[i].ControllerPort =
    796 			smc_dpm_table->i2ccontrollers[i].controllerport;
    797 		ppsmc_pptable->I2cControllers[i].ThermalThrottler =
    798 			smc_dpm_table->i2ccontrollers[i].thermalthrottler;
    799 		ppsmc_pptable->I2cControllers[i].I2cProtocol =
    800 			smc_dpm_table->i2ccontrollers[i].i2cprotocol;
    801 		ppsmc_pptable->I2cControllers[i].I2cSpeed =
    802 			smc_dpm_table->i2ccontrollers[i].i2cspeed;
    803 	}
    804 
    805 	return 0;
    806 }
    807 
    808 static int override_powerplay_table_fantargettemperature(struct pp_hwmgr *hwmgr)
    809 {
    810 	struct phm_ppt_v3_information *pptable_information =
    811 		(struct phm_ppt_v3_information *)hwmgr->pptable;
    812 	PPTable_t *ppsmc_pptable = (PPTable_t *)(pptable_information->smc_pptable);
    813 
    814 	ppsmc_pptable->FanTargetTemperature = VEGA20_FAN_TARGET_TEMPERATURE_OVERRIDE;
    815 
    816 	return 0;
    817 }
    818 
    819 #define VEGA20_ENGINECLOCK_HARDMAX 198000
    820 static int init_powerplay_table_information(
    821 		struct pp_hwmgr *hwmgr,
    822 		const ATOM_Vega20_POWERPLAYTABLE *powerplay_table)
    823 {
    824 	struct phm_ppt_v3_information *pptable_information =
    825 		(struct phm_ppt_v3_information *)hwmgr->pptable;
    826 	uint32_t disable_power_control = 0;
    827 	uint32_t od_feature_count, od_setting_count, power_saving_clock_count;
    828 	int result;
    829 
    830 	hwmgr->thermal_controller.ucType = powerplay_table->ucThermalControllerType;
    831 	pptable_information->uc_thermal_controller_type = powerplay_table->ucThermalControllerType;
    832 	hwmgr->thermal_controller.fanInfo.ulMinRPM = 0;
    833 	hwmgr->thermal_controller.fanInfo.ulMaxRPM = powerplay_table->smcPPTable.FanMaximumRpm;
    834 
    835 	set_hw_cap(hwmgr,
    836 		ATOM_VEGA20_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType,
    837 		PHM_PlatformCaps_ThermalController);
    838 
    839 	phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_MicrocodeFanControl);
    840 
    841 	if (powerplay_table->OverDrive8Table.ucODTableRevision == 1) {
    842 		od_feature_count =
    843 			(le32_to_cpu(powerplay_table->OverDrive8Table.ODFeatureCount) >
    844 			 ATOM_VEGA20_ODFEATURE_COUNT) ?
    845 			ATOM_VEGA20_ODFEATURE_COUNT :
    846 			le32_to_cpu(powerplay_table->OverDrive8Table.ODFeatureCount);
    847 		od_setting_count =
    848 			(le32_to_cpu(powerplay_table->OverDrive8Table.ODSettingCount) >
    849 			 ATOM_VEGA20_ODSETTING_COUNT) ?
    850 			ATOM_VEGA20_ODSETTING_COUNT :
    851 			le32_to_cpu(powerplay_table->OverDrive8Table.ODSettingCount);
    852 
    853 		copy_overdrive_feature_capabilities_array(hwmgr,
    854 				&pptable_information->od_feature_capabilities,
    855 				powerplay_table->OverDrive8Table.ODFeatureCapabilities,
    856 				od_feature_count);
    857 		phm_copy_overdrive_settings_limits_array(hwmgr,
    858 				&pptable_information->od_settings_max,
    859 				powerplay_table->OverDrive8Table.ODSettingsMax,
    860 				od_setting_count);
    861 		phm_copy_overdrive_settings_limits_array(hwmgr,
    862 				&pptable_information->od_settings_min,
    863 				powerplay_table->OverDrive8Table.ODSettingsMin,
    864 				od_setting_count);
    865 	}
    866 
    867 	pptable_information->us_small_power_limit1 = le16_to_cpu(powerplay_table->usSmallPowerLimit1);
    868 	pptable_information->us_small_power_limit2 = le16_to_cpu(powerplay_table->usSmallPowerLimit2);
    869 	pptable_information->us_boost_power_limit = le16_to_cpu(powerplay_table->usBoostPowerLimit);
    870 	pptable_information->us_od_turbo_power_limit = le16_to_cpu(powerplay_table->usODTurboPowerLimit);
    871 	pptable_information->us_od_powersave_power_limit = le16_to_cpu(powerplay_table->usODPowerSavePowerLimit);
    872 
    873 	pptable_information->us_software_shutdown_temp = le16_to_cpu(powerplay_table->usSoftwareShutdownTemp);
    874 
    875 	hwmgr->platform_descriptor.TDPODLimit = le32_to_cpu(powerplay_table->OverDrive8Table.ODSettingsMax[ATOM_VEGA20_ODSETTING_POWERPERCENTAGE]);
    876 
    877 	disable_power_control = 0;
    878 	if (!disable_power_control && hwmgr->platform_descriptor.TDPODLimit)
    879 		/* enable TDP overdrive (PowerControl) feature as well if supported */
    880 		phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PowerControl);
    881 
    882 	if (powerplay_table->PowerSavingClockTable.ucTableRevision == 1) {
    883 		power_saving_clock_count =
    884 			(le32_to_cpu(powerplay_table->PowerSavingClockTable.PowerSavingClockCount) >=
    885 			 ATOM_VEGA20_PPCLOCK_COUNT) ?
    886 			ATOM_VEGA20_PPCLOCK_COUNT :
    887 			le32_to_cpu(powerplay_table->PowerSavingClockTable.PowerSavingClockCount);
    888 		phm_copy_clock_limits_array(hwmgr,
    889 				&pptable_information->power_saving_clock_max,
    890 				powerplay_table->PowerSavingClockTable.PowerSavingClockMax,
    891 				power_saving_clock_count);
    892 		phm_copy_clock_limits_array(hwmgr,
    893 				&pptable_information->power_saving_clock_min,
    894 				powerplay_table->PowerSavingClockTable.PowerSavingClockMin,
    895 				power_saving_clock_count);
    896 	}
    897 
    898 	pptable_information->smc_pptable = (PPTable_t *)kmalloc(sizeof(PPTable_t), GFP_KERNEL);
    899 	if (pptable_information->smc_pptable == NULL)
    900 		return -ENOMEM;
    901 
    902 	memcpy(pptable_information->smc_pptable,
    903 			&(powerplay_table->smcPPTable),
    904 			sizeof(PPTable_t));
    905 
    906 
    907 	result = append_vbios_pptable(hwmgr, (pptable_information->smc_pptable));
    908 	if (result)
    909 		return result;
    910 
    911 	result = override_powerplay_table_fantargettemperature(hwmgr);
    912 
    913 	return result;
    914 }
    915 
    916 static int vega20_pp_tables_initialize(struct pp_hwmgr *hwmgr)
    917 {
    918 	int result = 0;
    919 	const ATOM_Vega20_POWERPLAYTABLE *powerplay_table;
    920 
    921 	hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v3_information), GFP_KERNEL);
    922 	PP_ASSERT_WITH_CODE((hwmgr->pptable != NULL),
    923 		"Failed to allocate hwmgr->pptable!", return -ENOMEM);
    924 
    925 	powerplay_table = get_powerplay_table(hwmgr);
    926 	PP_ASSERT_WITH_CODE((powerplay_table != NULL),
    927 		"Missing PowerPlay Table!", return -1);
    928 
    929 	result = check_powerplay_tables(hwmgr, powerplay_table);
    930 	PP_ASSERT_WITH_CODE((result == 0),
    931 		"check_powerplay_tables failed", return result);
    932 
    933 	result = set_platform_caps(hwmgr,
    934 			le32_to_cpu(powerplay_table->ulPlatformCaps));
    935 	PP_ASSERT_WITH_CODE((result == 0),
    936 		"set_platform_caps failed", return result);
    937 
    938 	result = init_powerplay_table_information(hwmgr, powerplay_table);
    939 	PP_ASSERT_WITH_CODE((result == 0),
    940 		"init_powerplay_table_information failed", return result);
    941 
    942 	return result;
    943 }
    944 
    945 static int vega20_pp_tables_uninitialize(struct pp_hwmgr *hwmgr)
    946 {
    947 	struct phm_ppt_v3_information *pp_table_info =
    948 			(struct phm_ppt_v3_information *)(hwmgr->pptable);
    949 
    950 	kfree(pp_table_info->power_saving_clock_max);
    951 	pp_table_info->power_saving_clock_max = NULL;
    952 
    953 	kfree(pp_table_info->power_saving_clock_min);
    954 	pp_table_info->power_saving_clock_min = NULL;
    955 
    956 	kfree(pp_table_info->od_feature_capabilities);
    957 	pp_table_info->od_feature_capabilities = NULL;
    958 
    959 	kfree(pp_table_info->od_settings_max);
    960 	pp_table_info->od_settings_max = NULL;
    961 
    962 	kfree(pp_table_info->od_settings_min);
    963 	pp_table_info->od_settings_min = NULL;
    964 
    965 	kfree(pp_table_info->smc_pptable);
    966 	pp_table_info->smc_pptable = NULL;
    967 
    968 	kfree(hwmgr->pptable);
    969 	hwmgr->pptable = NULL;
    970 
    971 	return 0;
    972 }
    973 
    974 const struct pp_table_func vega20_pptable_funcs = {
    975 	.pptable_init = vega20_pp_tables_initialize,
    976 	.pptable_fini = vega20_pp_tables_uninitialize,
    977 };
    978