Path: blob/master/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
29294 views
/*1* Copyright 2013 Advanced Micro Devices, Inc.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR17* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19* OTHER DEALINGS IN THE SOFTWARE.20*21*/2223#include <linux/module.h>24#include <linux/pci.h>2526#include "amdgpu.h"27#include "amdgpu_pm.h"28#include "amdgpu_dpm.h"29#include "amdgpu_atombios.h"30#include "amdgpu_dpm_internal.h"31#include "amd_pcie.h"32#include "atom.h"33#include "gfx_v6_0.h"34#include "r600_dpm.h"35#include "sid.h"36#include "si_dpm.h"37#include "../include/pptable.h"38#include <linux/math64.h>39#include <linux/seq_file.h>40#include <linux/firmware.h>41#include <legacy_dpm.h>4243#include "bif/bif_3_0_d.h"44#include "bif/bif_3_0_sh_mask.h"4546#include "dce/dce_6_0_d.h"47#include "dce/dce_6_0_sh_mask.h"4849#include "gca/gfx_6_0_d.h"50#include "gca/gfx_6_0_sh_mask.h"5152#include"gmc/gmc_6_0_d.h"53#include"gmc/gmc_6_0_sh_mask.h"5455#include "smu/smu_6_0_d.h"56#include "smu/smu_6_0_sh_mask.h"5758#define MC_CG_ARB_FREQ_F0 0x0a59#define MC_CG_ARB_FREQ_F1 0x0b60#define MC_CG_ARB_FREQ_F2 0x0c61#define MC_CG_ARB_FREQ_F3 0x0d6263#define SMC_RAM_END 0x200006465#define SCLK_MIN_DEEPSLEEP_FREQ 1350666768/* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */69#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 1270#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 1471#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4 1672#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 1873#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6 2074#define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7 227576#define BIOS_SCRATCH_4 0x5cd7778MODULE_FIRMWARE("amdgpu/tahiti_smc.bin");79MODULE_FIRMWARE("amdgpu/pitcairn_smc.bin");80MODULE_FIRMWARE("amdgpu/pitcairn_k_smc.bin");81MODULE_FIRMWARE("amdgpu/verde_smc.bin");82MODULE_FIRMWARE("amdgpu/verde_k_smc.bin");83MODULE_FIRMWARE("amdgpu/oland_smc.bin");84MODULE_FIRMWARE("amdgpu/oland_k_smc.bin");85MODULE_FIRMWARE("amdgpu/hainan_smc.bin");86MODULE_FIRMWARE("amdgpu/hainan_k_smc.bin");87MODULE_FIRMWARE("amdgpu/banks_k_2_smc.bin");8889static const struct amd_pm_funcs si_dpm_funcs;9091union power_info {92struct _ATOM_POWERPLAY_INFO info;93struct _ATOM_POWERPLAY_INFO_V2 info_2;94struct _ATOM_POWERPLAY_INFO_V3 info_3;95struct _ATOM_PPLIB_POWERPLAYTABLE pplib;96struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;97struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;98struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4;99struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5;100};101102union fan_info {103struct _ATOM_PPLIB_FANTABLE fan;104struct _ATOM_PPLIB_FANTABLE2 fan2;105struct _ATOM_PPLIB_FANTABLE3 fan3;106};107108union pplib_clock_info {109struct _ATOM_PPLIB_R600_CLOCK_INFO r600;110struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;111struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;112struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;113struct _ATOM_PPLIB_SI_CLOCK_INFO si;114};115116enum si_dpm_auto_throttle_src {117SI_DPM_AUTO_THROTTLE_SRC_THERMAL,118SI_DPM_AUTO_THROTTLE_SRC_EXTERNAL119};120121enum si_dpm_event_src {122SI_DPM_EVENT_SRC_ANALOG = 0,123SI_DPM_EVENT_SRC_EXTERNAL = 1,124SI_DPM_EVENT_SRC_DIGITAL = 2,125SI_DPM_EVENT_SRC_ANALOG_OR_EXTERNAL = 3,126SI_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4127};128129static const u32 r600_utc[R600_PM_NUMBER_OF_TC] =130{131R600_UTC_DFLT_00,132R600_UTC_DFLT_01,133R600_UTC_DFLT_02,134R600_UTC_DFLT_03,135R600_UTC_DFLT_04,136R600_UTC_DFLT_05,137R600_UTC_DFLT_06,138R600_UTC_DFLT_07,139R600_UTC_DFLT_08,140R600_UTC_DFLT_09,141R600_UTC_DFLT_10,142R600_UTC_DFLT_11,143R600_UTC_DFLT_12,144R600_UTC_DFLT_13,145R600_UTC_DFLT_14,146};147148static const u32 r600_dtc[R600_PM_NUMBER_OF_TC] =149{150R600_DTC_DFLT_00,151R600_DTC_DFLT_01,152R600_DTC_DFLT_02,153R600_DTC_DFLT_03,154R600_DTC_DFLT_04,155R600_DTC_DFLT_05,156R600_DTC_DFLT_06,157R600_DTC_DFLT_07,158R600_DTC_DFLT_08,159R600_DTC_DFLT_09,160R600_DTC_DFLT_10,161R600_DTC_DFLT_11,162R600_DTC_DFLT_12,163R600_DTC_DFLT_13,164R600_DTC_DFLT_14,165};166167static const struct si_cac_config_reg cac_weights_tahiti[] =168{169{ 0x0, 0x0000ffff, 0, 0xc, SISLANDS_CACCONFIG_CGIND },170{ 0x0, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },171{ 0x1, 0x0000ffff, 0, 0x101, SISLANDS_CACCONFIG_CGIND },172{ 0x1, 0xffff0000, 16, 0xc, SISLANDS_CACCONFIG_CGIND },173{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },174{ 0x3, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },175{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },176{ 0x4, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },177{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },178{ 0x5, 0x0000ffff, 0, 0x8fc, SISLANDS_CACCONFIG_CGIND },179{ 0x5, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },180{ 0x6, 0x0000ffff, 0, 0x95, SISLANDS_CACCONFIG_CGIND },181{ 0x6, 0xffff0000, 16, 0x34e, SISLANDS_CACCONFIG_CGIND },182{ 0x18f, 0x0000ffff, 0, 0x1a1, SISLANDS_CACCONFIG_CGIND },183{ 0x7, 0x0000ffff, 0, 0xda, SISLANDS_CACCONFIG_CGIND },184{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },185{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },186{ 0x8, 0xffff0000, 16, 0x46, SISLANDS_CACCONFIG_CGIND },187{ 0x9, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },188{ 0xa, 0x0000ffff, 0, 0x208, SISLANDS_CACCONFIG_CGIND },189{ 0xb, 0x0000ffff, 0, 0xe7, SISLANDS_CACCONFIG_CGIND },190{ 0xb, 0xffff0000, 16, 0x948, SISLANDS_CACCONFIG_CGIND },191{ 0xc, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },192{ 0xd, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },193{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },194{ 0xe, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },195{ 0xf, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },196{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },197{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },198{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },199{ 0x11, 0x0000ffff, 0, 0x167, SISLANDS_CACCONFIG_CGIND },200{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },201{ 0x12, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },202{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },203{ 0x13, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },204{ 0x14, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },205{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },206{ 0x15, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },207{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },208{ 0x16, 0x0000ffff, 0, 0x31, SISLANDS_CACCONFIG_CGIND },209{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },210{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },211{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },212{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },213{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },214{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },215{ 0x1a, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },216{ 0x1a, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },217{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },218{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },219{ 0x1c, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },220{ 0x1c, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },221{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },222{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },223{ 0x1e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },224{ 0x1e, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },225{ 0x1f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },226{ 0x1f, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },227{ 0x20, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },228{ 0x6d, 0x0000ffff, 0, 0x18e, SISLANDS_CACCONFIG_CGIND },229{ 0xFFFFFFFF }230};231232static const struct si_cac_config_reg lcac_tahiti[] =233{234{ 0x143, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },235{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },236{ 0x146, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },237{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },238{ 0x149, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },239{ 0x149, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },240{ 0x14c, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },241{ 0x14c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },242{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },243{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },244{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },245{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },246{ 0x9e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },247{ 0x9e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },248{ 0x101, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },249{ 0x101, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },250{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },251{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },252{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },253{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },254{ 0x10a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },255{ 0x10a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },256{ 0x10d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },257{ 0x10d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },258{ 0x8c, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },259{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },260{ 0x8f, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },261{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },262{ 0x92, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },263{ 0x92, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },264{ 0x95, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },265{ 0x95, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },266{ 0x14f, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },267{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },268{ 0x152, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },269{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },270{ 0x155, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },271{ 0x155, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },272{ 0x158, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },273{ 0x158, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },274{ 0x110, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },275{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },276{ 0x113, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },277{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },278{ 0x116, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },279{ 0x116, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },280{ 0x119, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },281{ 0x119, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },282{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },283{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },284{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },285{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },286{ 0x122, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },287{ 0x122, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },288{ 0x125, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },289{ 0x125, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },290{ 0x128, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },291{ 0x128, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },292{ 0x12b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },293{ 0x12b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },294{ 0x15b, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },295{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },296{ 0x15e, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },297{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },298{ 0x161, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },299{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },300{ 0x164, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },301{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },302{ 0x167, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },303{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },304{ 0x16a, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },305{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },306{ 0x16d, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },307{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },308{ 0x170, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },309{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },310{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },311{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },312{ 0x176, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },313{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },314{ 0x179, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },315{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },316{ 0x17c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },317{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },318{ 0x17f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },319{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },320{ 0xFFFFFFFF }321322};323324static const struct si_cac_config_reg cac_override_tahiti[] =325{326{ 0xFFFFFFFF }327};328329static const struct si_powertune_data powertune_data_tahiti =330{331((1 << 16) | 27027),3326,3330,3344,33595,336{3370UL,3380UL,3394521550UL,340309631529UL,341-1270850L,3424513710L,34340344},345595000000UL,34612,347{3480,3490,3500,3510,3520,3530,3540,3550356},357true358};359360static const struct si_dte_data dte_data_tahiti =361{362{ 1159409, 0, 0, 0, 0 },363{ 777, 0, 0, 0, 0 },3642,36554000,366127000,36725,3682,36910,37013,371{ 27, 31, 35, 39, 43, 47, 54, 61, 67, 74, 81, 88, 95, 0, 0, 0 },372{ 240888759, 221057860, 235370597, 162287531, 158510299, 131423027, 116673180, 103067515, 87941937, 76209048, 68209175, 64090048, 58301890, 0, 0, 0 },373{ 12024, 11189, 11451, 8411, 7939, 6666, 5681, 4905, 4241, 3720, 3354, 3122, 2890, 0, 0, 0 },37485,375false376};377378static const struct si_dte_data dte_data_tahiti_pro =379{380{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },381{ 0x0, 0x0, 0x0, 0x0, 0x0 },3825,38345000,384100,3850xA,3861,3870,3880x10,389{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },390{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },391{ 0x7D0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },39290,393true394};395396static const struct si_dte_data dte_data_new_zealand =397{398{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0 },399{ 0x29B, 0x3E9, 0x537, 0x7D2, 0 },4000x5,4010xAFC8,4020x69,4030x32,4041,4050,4060x10,407{ 0x82, 0xA0, 0xB4, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },408{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },409{ 0xDAC, 0x1388, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685 },41085,411true412};413414static const struct si_dte_data dte_data_aruba_pro =415{416{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },417{ 0x0, 0x0, 0x0, 0x0, 0x0 },4185,41945000,420100,4210xA,4221,4230,4240x10,425{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },426{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },427{ 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },42890,429true430};431432static const struct si_dte_data dte_data_malta =433{434{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },435{ 0x0, 0x0, 0x0, 0x0, 0x0 },4365,43745000,438100,4390xA,4401,4410,4420x10,443{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },444{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },445{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },44690,447true448};449450static const struct si_cac_config_reg cac_weights_pitcairn[] =451{452{ 0x0, 0x0000ffff, 0, 0x8a, SISLANDS_CACCONFIG_CGIND },453{ 0x0, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },454{ 0x1, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },455{ 0x1, 0xffff0000, 16, 0x24d, SISLANDS_CACCONFIG_CGIND },456{ 0x2, 0x0000ffff, 0, 0x19, SISLANDS_CACCONFIG_CGIND },457{ 0x3, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },458{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },459{ 0x4, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },460{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },461{ 0x5, 0x0000ffff, 0, 0xc11, SISLANDS_CACCONFIG_CGIND },462{ 0x5, 0xffff0000, 16, 0x7f3, SISLANDS_CACCONFIG_CGIND },463{ 0x6, 0x0000ffff, 0, 0x403, SISLANDS_CACCONFIG_CGIND },464{ 0x6, 0xffff0000, 16, 0x367, SISLANDS_CACCONFIG_CGIND },465{ 0x18f, 0x0000ffff, 0, 0x4c9, SISLANDS_CACCONFIG_CGIND },466{ 0x7, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },467{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },468{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },469{ 0x8, 0xffff0000, 16, 0x45d, SISLANDS_CACCONFIG_CGIND },470{ 0x9, 0x0000ffff, 0, 0x36d, SISLANDS_CACCONFIG_CGIND },471{ 0xa, 0x0000ffff, 0, 0x534, SISLANDS_CACCONFIG_CGIND },472{ 0xb, 0x0000ffff, 0, 0x5da, SISLANDS_CACCONFIG_CGIND },473{ 0xb, 0xffff0000, 16, 0x880, SISLANDS_CACCONFIG_CGIND },474{ 0xc, 0x0000ffff, 0, 0x201, SISLANDS_CACCONFIG_CGIND },475{ 0xd, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },476{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },477{ 0xe, 0x0000ffff, 0, 0x9f, SISLANDS_CACCONFIG_CGIND },478{ 0xf, 0x0000ffff, 0, 0x1f, SISLANDS_CACCONFIG_CGIND },479{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },480{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },481{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },482{ 0x11, 0x0000ffff, 0, 0x5de, SISLANDS_CACCONFIG_CGIND },483{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },484{ 0x12, 0x0000ffff, 0, 0x7b, SISLANDS_CACCONFIG_CGIND },485{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },486{ 0x13, 0xffff0000, 16, 0x13, SISLANDS_CACCONFIG_CGIND },487{ 0x14, 0x0000ffff, 0, 0xf9, SISLANDS_CACCONFIG_CGIND },488{ 0x15, 0x0000ffff, 0, 0x66, SISLANDS_CACCONFIG_CGIND },489{ 0x15, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },490{ 0x4e, 0x0000ffff, 0, 0x13, SISLANDS_CACCONFIG_CGIND },491{ 0x16, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },492{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },493{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },494{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },495{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },496{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },497{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },498{ 0x1a, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },499{ 0x1a, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },500{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },501{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },502{ 0x1c, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },503{ 0x1c, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },504{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },505{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },506{ 0x1e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },507{ 0x1e, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },508{ 0x1f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },509{ 0x1f, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },510{ 0x20, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },511{ 0x6d, 0x0000ffff, 0, 0x186, SISLANDS_CACCONFIG_CGIND },512{ 0xFFFFFFFF }513};514515static const struct si_cac_config_reg lcac_pitcairn[] =516{517{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },518{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },519{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },520{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },521{ 0x110, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },522{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },523{ 0x14f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },524{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },525{ 0x8c, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },526{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },527{ 0x143, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },528{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },529{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },530{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },531{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },532{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },533{ 0x113, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },534{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },535{ 0x152, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },536{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },537{ 0x8f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },538{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },539{ 0x146, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },540{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },541{ 0x9e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },542{ 0x9e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },543{ 0x10a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },544{ 0x10a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },545{ 0x116, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },546{ 0x116, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },547{ 0x155, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },548{ 0x155, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },549{ 0x92, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },550{ 0x92, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },551{ 0x149, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },552{ 0x149, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },553{ 0x101, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },554{ 0x101, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },555{ 0x10d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },556{ 0x10d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },557{ 0x119, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },558{ 0x119, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },559{ 0x158, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },560{ 0x158, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },561{ 0x95, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },562{ 0x95, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },563{ 0x14c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },564{ 0x14c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },565{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },566{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },567{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },568{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },569{ 0x122, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },570{ 0x122, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },571{ 0x125, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },572{ 0x125, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },573{ 0x128, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },574{ 0x128, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },575{ 0x12b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },576{ 0x12b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },577{ 0x164, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },578{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },579{ 0x167, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },580{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },581{ 0x16a, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },582{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },583{ 0x15e, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },584{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },585{ 0x161, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },586{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },587{ 0x15b, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },588{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },589{ 0x16d, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },590{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },591{ 0x170, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },592{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },593{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },594{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },595{ 0x176, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },596{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },597{ 0x179, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },598{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },599{ 0x17c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },600{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },601{ 0x17f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },602{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },603{ 0xFFFFFFFF }604};605606static const struct si_cac_config_reg cac_override_pitcairn[] =607{608{ 0xFFFFFFFF }609};610611static const struct si_powertune_data powertune_data_pitcairn =612{613((1 << 16) | 27027),6145,6150,6166,617100,618{61951600000UL,6201800000UL,6217194395UL,622309631529UL,623-1270850L,6244513710L,625100626},627117830498UL,62812,629{6300,6310,6320,6330,6340,6350,6360,6370638},639true640};641642static const struct si_dte_data dte_data_pitcairn =643{644{ 0, 0, 0, 0, 0 },645{ 0, 0, 0, 0, 0 },6460,6470,6480,6490,6500,6510,6520,653{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },654{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },655{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },6560,657false658};659660static const struct si_dte_data dte_data_curacao_xt =661{662{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },663{ 0x0, 0x0, 0x0, 0x0, 0x0 },6645,66545000,666100,6670xA,6681,6690,6700x10,671{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },672{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },673{ 0x1D17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },67490,675true676};677678static const struct si_dte_data dte_data_curacao_pro =679{680{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },681{ 0x0, 0x0, 0x0, 0x0, 0x0 },6825,68345000,684100,6850xA,6861,6870,6880x10,689{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },690{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },691{ 0x1D17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },69290,693true694};695696static const struct si_dte_data dte_data_neptune_xt =697{698{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },699{ 0x0, 0x0, 0x0, 0x0, 0x0 },7005,70145000,702100,7030xA,7041,7050,7060x10,707{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },708{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },709{ 0x3A2F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },71090,711true712};713714static const struct si_cac_config_reg cac_weights_chelsea_pro[] =715{716{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },717{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },718{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },719{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },720{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },721{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },722{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },723{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },724{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },725{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },726{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },727{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },728{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },729{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },730{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },731{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },732{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },733{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },734{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },735{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },736{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },737{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },738{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },739{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },740{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },741{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },742{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },743{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },744{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },745{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },746{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },747{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },748{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },749{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },750{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },751{ 0x14, 0x0000ffff, 0, 0x2BD, SISLANDS_CACCONFIG_CGIND },752{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },753{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },754{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },755{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },756{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },757{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },758{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },759{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },760{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },761{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },762{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },763{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },764{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },765{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },766{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },767{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },768{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },769{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },770{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },771{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },772{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },773{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },774{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },775{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },776{ 0xFFFFFFFF }777};778779static const struct si_cac_config_reg cac_weights_chelsea_xt[] =780{781{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },782{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },783{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },784{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },785{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },786{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },787{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },788{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },789{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },790{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },791{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },792{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },793{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },794{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },795{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },796{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },797{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },798{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },799{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },800{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },801{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },802{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },803{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },804{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },805{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },806{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },807{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },808{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },809{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },810{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },811{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },812{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },813{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },814{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },815{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },816{ 0x14, 0x0000ffff, 0, 0x30A, SISLANDS_CACCONFIG_CGIND },817{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },818{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },819{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },820{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },821{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },822{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },823{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },824{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },825{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },826{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },827{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },828{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },829{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },830{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },831{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },832{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },833{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },834{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },835{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },836{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },837{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },838{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },839{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },840{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },841{ 0xFFFFFFFF }842};843844static const struct si_cac_config_reg cac_weights_heathrow[] =845{846{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },847{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },848{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },849{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },850{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },851{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },852{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },853{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },854{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },855{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },856{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },857{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },858{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },859{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },860{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },861{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },862{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },863{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },864{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },865{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },866{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },867{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },868{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },869{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },870{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },871{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },872{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },873{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },874{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },875{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },876{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },877{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },878{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },879{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },880{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },881{ 0x14, 0x0000ffff, 0, 0x362, SISLANDS_CACCONFIG_CGIND },882{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },883{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },884{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },885{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },886{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },887{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },888{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },889{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },890{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },891{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },892{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },893{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },894{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },895{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },896{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },897{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },898{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },899{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },900{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },901{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },902{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },903{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },904{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },905{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },906{ 0xFFFFFFFF }907};908909static const struct si_cac_config_reg cac_weights_cape_verde_pro[] =910{911{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },912{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },913{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },914{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },915{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },916{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },917{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },918{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },919{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },920{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },921{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },922{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },923{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },924{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },925{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },926{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },927{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },928{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },929{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },930{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },931{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },932{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },933{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },934{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },935{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },936{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },937{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },938{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },939{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },940{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },941{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },942{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },943{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },944{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },945{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },946{ 0x14, 0x0000ffff, 0, 0x315, SISLANDS_CACCONFIG_CGIND },947{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },948{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },949{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },950{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },951{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },952{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },953{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },954{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },955{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },956{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },957{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },958{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },959{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },960{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },961{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },962{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },963{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },964{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },965{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },966{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },967{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },968{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },969{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },970{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },971{ 0xFFFFFFFF }972};973974static const struct si_cac_config_reg cac_weights_cape_verde[] =975{976{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },977{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },978{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },979{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },980{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },981{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },982{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },983{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },984{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },985{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },986{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },987{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },988{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },989{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },990{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },991{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },992{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },993{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },994{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },995{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },996{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },997{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },998{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },999{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },1000{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },1001{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },1002{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },1003{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1004{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1005{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },1006{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },1007{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },1008{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },1009{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },1010{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },1011{ 0x14, 0x0000ffff, 0, 0x3BA, SISLANDS_CACCONFIG_CGIND },1012{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1013{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },1014{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1015{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },1016{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },1017{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1018{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1019{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1020{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1021{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1022{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1023{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1024{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1025{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1026{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1027{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1028{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1029{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1030{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1031{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1032{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1033{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1034{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1035{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },1036{ 0xFFFFFFFF }1037};10381039static const struct si_cac_config_reg lcac_cape_verde[] =1040{1041{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1042{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1043{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1044{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1045{ 0x110, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },1046{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1047{ 0x14f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },1048{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1049{ 0x8c, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },1050{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1051{ 0x143, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1052{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1053{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1054{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1055{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1056{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1057{ 0x113, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },1058{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1059{ 0x152, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },1060{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1061{ 0x8f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1062{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1063{ 0x146, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1064{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1065{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1066{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1067{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1068{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1069{ 0x164, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1070{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1071{ 0x167, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1072{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1073{ 0x16a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1074{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1075{ 0x15e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1076{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1077{ 0x161, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1078{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1079{ 0x15b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1080{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1081{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1082{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1083{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1084{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1085{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1086{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1087{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1088{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1089{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1090{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1091{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1092{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1093{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1094{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1095{ 0xFFFFFFFF }1096};10971098static const struct si_cac_config_reg cac_override_cape_verde[] =1099{1100{ 0xFFFFFFFF }1101};11021103static const struct si_powertune_data powertune_data_cape_verde =1104{1105((1 << 16) | 0x6993),11065,11070,11087,1109105,1110{11110UL,11120UL,11137194395UL,1114309631529UL,1115-1270850L,11164513710L,11171001118},1119117830498UL,112012,1121{11220,11230,11240,11250,11260,11270,11280,112901130},1131true1132};11331134static const struct si_dte_data dte_data_cape_verde =1135{1136{ 0, 0, 0, 0, 0 },1137{ 0, 0, 0, 0, 0 },11380,11390,11400,11410,11420,11430,11440,1145{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },1146{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },1147{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },11480,1149false1150};11511152static const struct si_dte_data dte_data_venus_xtx =1153{1154{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },1155{ 0x71C, 0xAAB, 0xE39, 0x11C7, 0x0 },11565,115755000,11580x69,11590xA,11601,11610,11620x3,1163{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },1164{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },1165{ 0xD6D8, 0x88B8, 0x1555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },116690,1167true1168};11691170static const struct si_dte_data dte_data_venus_xt =1171{1172{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },1173{ 0xBDA, 0x11C7, 0x17B4, 0x1DA1, 0x0 },11745,117555000,11760x69,11770xA,11781,11790,11800x3,1181{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },1182{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },1183{ 0xAFC8, 0x88B8, 0x238E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },118490,1185true1186};11871188static const struct si_dte_data dte_data_venus_pro =1189{1190{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },1191{ 0x11C7, 0x1AAB, 0x238E, 0x2C72, 0x0 },11925,119355000,11940x69,11950xA,11961,11970,11980x3,1199{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },1200{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },1201{ 0x88B8, 0x88B8, 0x3555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },120290,1203true1204};12051206static const struct si_cac_config_reg cac_weights_oland[] =1207{1208{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },1209{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },1210{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },1211{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },1212{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1213{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },1214{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },1215{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },1216{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },1217{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },1218{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },1219{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },1220{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },1221{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },1222{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },1223{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },1224{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },1225{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },1226{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },1227{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },1228{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },1229{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },1230{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },1231{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },1232{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },1233{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },1234{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },1235{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1236{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1237{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },1238{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },1239{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },1240{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },1241{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },1242{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },1243{ 0x14, 0x0000ffff, 0, 0x3BA, SISLANDS_CACCONFIG_CGIND },1244{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1245{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },1246{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1247{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },1248{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },1249{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1250{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1251{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1252{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1253{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1254{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1255{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1256{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1257{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1258{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1259{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1260{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1261{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1262{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1263{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1264{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1265{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1266{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1267{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },1268{ 0xFFFFFFFF }1269};12701271static const struct si_cac_config_reg cac_weights_mars_pro[] =1272{1273{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },1274{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },1275{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },1276{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },1277{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1278{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },1279{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },1280{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },1281{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },1282{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },1283{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },1284{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },1285{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },1286{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },1287{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },1288{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },1289{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },1290{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },1291{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },1292{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },1293{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },1294{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },1295{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },1296{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },1297{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },1298{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },1299{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },1300{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },1301{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1302{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },1303{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },1304{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },1305{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },1306{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },1307{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },1308{ 0x14, 0x0000ffff, 0, 0x2, SISLANDS_CACCONFIG_CGIND },1309{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1310{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },1311{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1312{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },1313{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },1314{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1315{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1316{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1317{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1318{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1319{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },1320{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },1321{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1322{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1323{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },1324{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },1325{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1326{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1327{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1328{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1329{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1330{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1331{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1332{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },1333{ 0xFFFFFFFF }1334};13351336static const struct si_cac_config_reg cac_weights_mars_xt[] =1337{1338{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },1339{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },1340{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },1341{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },1342{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1343{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },1344{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },1345{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },1346{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },1347{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },1348{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },1349{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },1350{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },1351{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },1352{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },1353{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },1354{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },1355{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },1356{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },1357{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },1358{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },1359{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },1360{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },1361{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },1362{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },1363{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },1364{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },1365{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },1366{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1367{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },1368{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },1369{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },1370{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },1371{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },1372{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },1373{ 0x14, 0x0000ffff, 0, 0x60, SISLANDS_CACCONFIG_CGIND },1374{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1375{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },1376{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1377{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },1378{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },1379{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1380{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1381{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1382{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1383{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1384{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },1385{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },1386{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1387{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1388{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },1389{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },1390{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1391{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1392{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1393{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1394{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1395{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1396{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1397{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },1398{ 0xFFFFFFFF }1399};14001401static const struct si_cac_config_reg cac_weights_oland_pro[] =1402{1403{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },1404{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },1405{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },1406{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },1407{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1408{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },1409{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },1410{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },1411{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },1412{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },1413{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },1414{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },1415{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },1416{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },1417{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },1418{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },1419{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },1420{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },1421{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },1422{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },1423{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },1424{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },1425{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },1426{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },1427{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },1428{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },1429{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },1430{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },1431{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1432{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },1433{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },1434{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },1435{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },1436{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },1437{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },1438{ 0x14, 0x0000ffff, 0, 0x90, SISLANDS_CACCONFIG_CGIND },1439{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1440{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },1441{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1442{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },1443{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },1444{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1445{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1446{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1447{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1448{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1449{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },1450{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },1451{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1452{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1453{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },1454{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },1455{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1456{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1457{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1458{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1459{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1460{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1461{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1462{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },1463{ 0xFFFFFFFF }1464};14651466static const struct si_cac_config_reg cac_weights_oland_xt[] =1467{1468{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },1469{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },1470{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },1471{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },1472{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1473{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },1474{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },1475{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },1476{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },1477{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },1478{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },1479{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },1480{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },1481{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },1482{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },1483{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },1484{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },1485{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },1486{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },1487{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },1488{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },1489{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },1490{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },1491{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },1492{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },1493{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },1494{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },1495{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },1496{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1497{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },1498{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },1499{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },1500{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },1501{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },1502{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },1503{ 0x14, 0x0000ffff, 0, 0x120, SISLANDS_CACCONFIG_CGIND },1504{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1505{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },1506{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1507{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },1508{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },1509{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1510{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1511{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1512{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1513{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1514{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },1515{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },1516{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1517{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1518{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },1519{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },1520{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1521{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1522{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1523{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1524{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1525{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1526{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1527{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },1528{ 0xFFFFFFFF }1529};15301531static const struct si_cac_config_reg lcac_oland[] =1532{1533{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1534{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1535{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1536{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1537{ 0x110, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },1538{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1539{ 0x14f, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },1540{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1541{ 0x8c, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },1542{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1543{ 0x143, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },1544{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1545{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1546{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1547{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1548{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1549{ 0x164, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1550{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1551{ 0x167, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1552{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1553{ 0x16a, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1554{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1555{ 0x15e, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1556{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1557{ 0x161, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1558{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1559{ 0x15b, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1560{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1561{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1562{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1563{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1564{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1565{ 0x173, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1566{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1567{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1568{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1569{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1570{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1571{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1572{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1573{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1574{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1575{ 0xFFFFFFFF }1576};15771578static const struct si_cac_config_reg lcac_mars_pro[] =1579{1580{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1581{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1582{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1583{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1584{ 0x110, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },1585{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1586{ 0x14f, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },1587{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1588{ 0x8c, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },1589{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1590{ 0x143, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1591{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1592{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1593{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1594{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1595{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1596{ 0x164, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1597{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1598{ 0x167, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1599{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1600{ 0x16a, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1601{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1602{ 0x15e, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1603{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1604{ 0x161, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1605{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1606{ 0x15b, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1607{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1608{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },1609{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1610{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1611{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1612{ 0x173, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1613{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1614{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1615{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1616{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1617{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1618{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1619{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1620{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },1621{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },1622{ 0xFFFFFFFF }1623};16241625static const struct si_cac_config_reg cac_override_oland[] =1626{1627{ 0xFFFFFFFF }1628};16291630static const struct si_powertune_data powertune_data_oland =1631{1632((1 << 16) | 0x6993),16335,16340,16357,1636105,1637{16380UL,16390UL,16407194395UL,1641309631529UL,1642-1270850L,16434513710L,16441001645},1646117830498UL,164712,1648{16490,16500,16510,16520,16530,16540,16550,165601657},1658true1659};16601661static const struct si_powertune_data powertune_data_mars_pro =1662{1663((1 << 16) | 0x6993),16645,16650,16667,1667105,1668{16690UL,16700UL,16717194395UL,1672309631529UL,1673-1270850L,16744513710L,16751001676},1677117830498UL,167812,1679{16800,16810,16820,16830,16840,16850,16860,168701688},1689true1690};16911692static const struct si_dte_data dte_data_oland =1693{1694{ 0, 0, 0, 0, 0 },1695{ 0, 0, 0, 0, 0 },16960,16970,16980,16990,17000,17010,17020,1703{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },1704{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },1705{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },17060,1707false1708};17091710static const struct si_dte_data dte_data_mars_pro =1711{1712{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },1713{ 0x0, 0x0, 0x0, 0x0, 0x0 },17145,171555000,1716105,17170xA,17181,17190,17200x10,1721{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },1722{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },1723{ 0xF627, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },172490,1725true1726};17271728static const struct si_dte_data dte_data_sun_xt =1729{1730{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },1731{ 0x0, 0x0, 0x0, 0x0, 0x0 },17325,173355000,1734105,17350xA,17361,17370,17380x10,1739{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },1740{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },1741{ 0xD555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },174290,1743true1744};174517461747static const struct si_cac_config_reg cac_weights_hainan[] =1748{1749{ 0x0, 0x0000ffff, 0, 0x2d9, SISLANDS_CACCONFIG_CGIND },1750{ 0x0, 0xffff0000, 16, 0x22b, SISLANDS_CACCONFIG_CGIND },1751{ 0x1, 0x0000ffff, 0, 0x21c, SISLANDS_CACCONFIG_CGIND },1752{ 0x1, 0xffff0000, 16, 0x1dc, SISLANDS_CACCONFIG_CGIND },1753{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1754{ 0x3, 0x0000ffff, 0, 0x24e, SISLANDS_CACCONFIG_CGIND },1755{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1756{ 0x4, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1757{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1758{ 0x5, 0x0000ffff, 0, 0x35e, SISLANDS_CACCONFIG_CGIND },1759{ 0x5, 0xffff0000, 16, 0x1143, SISLANDS_CACCONFIG_CGIND },1760{ 0x6, 0x0000ffff, 0, 0xe17, SISLANDS_CACCONFIG_CGIND },1761{ 0x6, 0xffff0000, 16, 0x441, SISLANDS_CACCONFIG_CGIND },1762{ 0x18f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1763{ 0x7, 0x0000ffff, 0, 0x28b, SISLANDS_CACCONFIG_CGIND },1764{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1765{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1766{ 0x8, 0xffff0000, 16, 0xabe, SISLANDS_CACCONFIG_CGIND },1767{ 0x9, 0x0000ffff, 0, 0xf11, SISLANDS_CACCONFIG_CGIND },1768{ 0xa, 0x0000ffff, 0, 0x907, SISLANDS_CACCONFIG_CGIND },1769{ 0xb, 0x0000ffff, 0, 0xb45, SISLANDS_CACCONFIG_CGIND },1770{ 0xb, 0xffff0000, 16, 0xd1e, SISLANDS_CACCONFIG_CGIND },1771{ 0xc, 0x0000ffff, 0, 0xa2c, SISLANDS_CACCONFIG_CGIND },1772{ 0xd, 0x0000ffff, 0, 0x62, SISLANDS_CACCONFIG_CGIND },1773{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1774{ 0xe, 0x0000ffff, 0, 0x1f3, SISLANDS_CACCONFIG_CGIND },1775{ 0xf, 0x0000ffff, 0, 0x42, SISLANDS_CACCONFIG_CGIND },1776{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1777{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1778{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1779{ 0x11, 0x0000ffff, 0, 0x709, SISLANDS_CACCONFIG_CGIND },1780{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1781{ 0x12, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1782{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1783{ 0x13, 0xffff0000, 16, 0x3a, SISLANDS_CACCONFIG_CGIND },1784{ 0x14, 0x0000ffff, 0, 0x357, SISLANDS_CACCONFIG_CGIND },1785{ 0x15, 0x0000ffff, 0, 0x9f, SISLANDS_CACCONFIG_CGIND },1786{ 0x15, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1787{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1788{ 0x16, 0x0000ffff, 0, 0x314, SISLANDS_CACCONFIG_CGIND },1789{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1790{ 0x17, 0x0000ffff, 0, 0x6d, SISLANDS_CACCONFIG_CGIND },1791{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1792{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1793{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },1794{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },1795{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1796{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1797{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1798{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1799{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1800{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1801{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1802{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1803{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1804{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1805{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1806{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },1807{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },1808{ 0x6d, 0x0000ffff, 0, 0x1b9, SISLANDS_CACCONFIG_CGIND },1809{ 0xFFFFFFFF }1810};18111812static const struct si_powertune_data powertune_data_hainan =1813{1814((1 << 16) | 0x6993),18155,18160,18179,1818105,1819{18200UL,18210UL,18227194395UL,1823309631529UL,1824-1270850L,18254513710L,18261001827},1828117830498UL,182912,1830{18310,18320,18330,18340,18350,18360,18370,183801839},1840true1841};18421843static struct rv7xx_power_info *rv770_get_pi(struct amdgpu_device *adev);1844static struct evergreen_power_info *evergreen_get_pi(struct amdgpu_device *adev);1845static struct ni_power_info *ni_get_pi(struct amdgpu_device *adev);1846static struct si_ps *si_get_ps(struct amdgpu_ps *rps);18471848static int si_populate_voltage_value(struct amdgpu_device *adev,1849const struct atom_voltage_table *table,1850u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage);1851static int si_get_std_voltage_value(struct amdgpu_device *adev,1852SISLANDS_SMC_VOLTAGE_VALUE *voltage,1853u16 *std_voltage);1854static int si_write_smc_soft_register(struct amdgpu_device *adev,1855u16 reg_offset, u32 value);1856static int si_convert_power_level_to_smc(struct amdgpu_device *adev,1857struct rv7xx_pl *pl,1858SISLANDS_SMC_HW_PERFORMANCE_LEVEL *level);1859static int si_calculate_sclk_params(struct amdgpu_device *adev,1860u32 engine_clock,1861SISLANDS_SMC_SCLK_VALUE *sclk);18621863static void si_thermal_start_smc_fan_control(struct amdgpu_device *adev);1864static void si_fan_ctrl_set_default_mode(struct amdgpu_device *adev);1865static void si_dpm_set_irq_funcs(struct amdgpu_device *adev);18661867static struct si_power_info *si_get_pi(struct amdgpu_device *adev)1868{1869struct si_power_info *pi = adev->pm.dpm.priv;1870return pi;1871}18721873static void si_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coeffients *coeff,1874u16 v, s32 t, u32 ileakage, u32 *leakage)1875{1876s64 kt, kv, leakage_w, i_leakage, vddc;1877s64 temperature, t_slope, t_intercept, av, bv, t_ref;1878s64 tmp;18791880i_leakage = div64_s64(drm_int2fixp(ileakage), 100);1881vddc = div64_s64(drm_int2fixp(v), 1000);1882temperature = div64_s64(drm_int2fixp(t), 1000);18831884t_slope = div64_s64(drm_int2fixp(coeff->t_slope), 100000000);1885t_intercept = div64_s64(drm_int2fixp(coeff->t_intercept), 100000000);1886av = div64_s64(drm_int2fixp(coeff->av), 100000000);1887bv = div64_s64(drm_int2fixp(coeff->bv), 100000000);1888t_ref = drm_int2fixp(coeff->t_ref);18891890tmp = drm_fixp_mul(t_slope, vddc) + t_intercept;1891kt = drm_fixp_exp(drm_fixp_mul(tmp, temperature));1892kt = drm_fixp_div(kt, drm_fixp_exp(drm_fixp_mul(tmp, t_ref)));1893kv = drm_fixp_mul(av, drm_fixp_exp(drm_fixp_mul(bv, vddc)));18941895leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc);18961897*leakage = drm_fixp2int(leakage_w * 1000);1898}18991900static void si_calculate_leakage_for_v_and_t(struct amdgpu_device *adev,1901const struct ni_leakage_coeffients *coeff,1902u16 v,1903s32 t,1904u32 i_leakage,1905u32 *leakage)1906{1907si_calculate_leakage_for_v_and_t_formula(coeff, v, t, i_leakage, leakage);1908}19091910static void si_calculate_leakage_for_v_formula(const struct ni_leakage_coeffients *coeff,1911const u32 fixed_kt, u16 v,1912u32 ileakage, u32 *leakage)1913{1914s64 kt, kv, leakage_w, i_leakage, vddc;19151916i_leakage = div64_s64(drm_int2fixp(ileakage), 100);1917vddc = div64_s64(drm_int2fixp(v), 1000);19181919kt = div64_s64(drm_int2fixp(fixed_kt), 100000000);1920kv = drm_fixp_mul(div64_s64(drm_int2fixp(coeff->av), 100000000),1921drm_fixp_exp(drm_fixp_mul(div64_s64(drm_int2fixp(coeff->bv), 100000000), vddc)));19221923leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc);19241925*leakage = drm_fixp2int(leakage_w * 1000);1926}19271928static void si_calculate_leakage_for_v(struct amdgpu_device *adev,1929const struct ni_leakage_coeffients *coeff,1930const u32 fixed_kt,1931u16 v,1932u32 i_leakage,1933u32 *leakage)1934{1935si_calculate_leakage_for_v_formula(coeff, fixed_kt, v, i_leakage, leakage);1936}193719381939static void si_update_dte_from_pl2(struct amdgpu_device *adev,1940struct si_dte_data *dte_data)1941{1942u32 p_limit1 = adev->pm.dpm.tdp_limit;1943u32 p_limit2 = adev->pm.dpm.near_tdp_limit;1944u32 k = dte_data->k;1945u32 t_max = dte_data->max_t;1946u32 t_split[5] = { 10, 15, 20, 25, 30 };1947u32 t_0 = dte_data->t0;1948u32 i;19491950if (p_limit2 != 0 && p_limit2 <= p_limit1) {1951dte_data->tdep_count = 3;19521953for (i = 0; i < k; i++) {1954dte_data->r[i] =1955(t_split[i] * (t_max - t_0/(u32)1000) * (1 << 14)) /1956(p_limit2 * (u32)100);1957}19581959dte_data->tdep_r[1] = dte_data->r[4] * 2;19601961for (i = 2; i < SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE; i++) {1962dte_data->tdep_r[i] = dte_data->r[4];1963}1964} else {1965DRM_ERROR("Invalid PL2! DTE will not be updated.\n");1966}1967}19681969static struct rv7xx_power_info *rv770_get_pi(struct amdgpu_device *adev)1970{1971struct rv7xx_power_info *pi = adev->pm.dpm.priv;19721973return pi;1974}19751976static struct ni_power_info *ni_get_pi(struct amdgpu_device *adev)1977{1978struct ni_power_info *pi = adev->pm.dpm.priv;19791980return pi;1981}19821983static struct si_ps *si_get_ps(struct amdgpu_ps *aps)1984{1985struct si_ps *ps = aps->ps_priv;19861987return ps;1988}19891990static void si_initialize_powertune_defaults(struct amdgpu_device *adev)1991{1992struct ni_power_info *ni_pi = ni_get_pi(adev);1993struct si_power_info *si_pi = si_get_pi(adev);1994bool update_dte_from_pl2 = false;19951996if (adev->asic_type == CHIP_TAHITI) {1997si_pi->cac_weights = cac_weights_tahiti;1998si_pi->lcac_config = lcac_tahiti;1999si_pi->cac_override = cac_override_tahiti;2000si_pi->powertune_data = &powertune_data_tahiti;2001si_pi->dte_data = dte_data_tahiti;20022003switch (adev->pdev->device) {2004case 0x6798:2005si_pi->dte_data.enable_dte_by_default = true;2006break;2007case 0x6799:2008si_pi->dte_data = dte_data_new_zealand;2009break;2010case 0x6790:2011case 0x6791:2012case 0x6792:2013case 0x679E:2014si_pi->dte_data = dte_data_aruba_pro;2015update_dte_from_pl2 = true;2016break;2017case 0x679B:2018si_pi->dte_data = dte_data_malta;2019update_dte_from_pl2 = true;2020break;2021case 0x679A:2022si_pi->dte_data = dte_data_tahiti_pro;2023update_dte_from_pl2 = true;2024break;2025default:2026if (si_pi->dte_data.enable_dte_by_default == true)2027DRM_ERROR("DTE is not enabled!\n");2028break;2029}2030} else if (adev->asic_type == CHIP_PITCAIRN) {2031si_pi->cac_weights = cac_weights_pitcairn;2032si_pi->lcac_config = lcac_pitcairn;2033si_pi->cac_override = cac_override_pitcairn;2034si_pi->powertune_data = &powertune_data_pitcairn;20352036switch (adev->pdev->device) {2037case 0x6810:2038case 0x6818:2039si_pi->dte_data = dte_data_curacao_xt;2040update_dte_from_pl2 = true;2041break;2042case 0x6819:2043case 0x6811:2044si_pi->dte_data = dte_data_curacao_pro;2045update_dte_from_pl2 = true;2046break;2047case 0x6800:2048case 0x6806:2049si_pi->dte_data = dte_data_neptune_xt;2050update_dte_from_pl2 = true;2051break;2052default:2053si_pi->dte_data = dte_data_pitcairn;2054break;2055}2056} else if (adev->asic_type == CHIP_VERDE) {2057si_pi->lcac_config = lcac_cape_verde;2058si_pi->cac_override = cac_override_cape_verde;2059si_pi->powertune_data = &powertune_data_cape_verde;20602061switch (adev->pdev->device) {2062case 0x683B:2063case 0x683F:2064case 0x6829:2065case 0x6835:2066si_pi->cac_weights = cac_weights_cape_verde_pro;2067si_pi->dte_data = dte_data_cape_verde;2068break;2069case 0x682C:2070si_pi->cac_weights = cac_weights_cape_verde_pro;2071si_pi->dte_data = dte_data_sun_xt;2072update_dte_from_pl2 = true;2073break;2074case 0x6825:2075case 0x6827:2076si_pi->cac_weights = cac_weights_heathrow;2077si_pi->dte_data = dte_data_cape_verde;2078break;2079case 0x6824:2080case 0x682D:2081si_pi->cac_weights = cac_weights_chelsea_xt;2082si_pi->dte_data = dte_data_cape_verde;2083break;2084case 0x682F:2085si_pi->cac_weights = cac_weights_chelsea_pro;2086si_pi->dte_data = dte_data_cape_verde;2087break;2088case 0x6820:2089si_pi->cac_weights = cac_weights_heathrow;2090si_pi->dte_data = dte_data_venus_xtx;2091break;2092case 0x6821:2093si_pi->cac_weights = cac_weights_heathrow;2094si_pi->dte_data = dte_data_venus_xt;2095break;2096case 0x6823:2097case 0x682B:2098case 0x6822:2099case 0x682A:2100si_pi->cac_weights = cac_weights_chelsea_pro;2101si_pi->dte_data = dte_data_venus_pro;2102break;2103default:2104si_pi->cac_weights = cac_weights_cape_verde;2105si_pi->dte_data = dte_data_cape_verde;2106break;2107}2108} else if (adev->asic_type == CHIP_OLAND) {2109si_pi->lcac_config = lcac_mars_pro;2110si_pi->cac_override = cac_override_oland;2111si_pi->powertune_data = &powertune_data_mars_pro;2112si_pi->dte_data = dte_data_mars_pro;21132114switch (adev->pdev->device) {2115case 0x6601:2116case 0x6621:2117case 0x6603:2118case 0x6605:2119si_pi->cac_weights = cac_weights_mars_pro;2120update_dte_from_pl2 = true;2121break;2122case 0x6600:2123case 0x6606:2124case 0x6620:2125case 0x6604:2126si_pi->cac_weights = cac_weights_mars_xt;2127update_dte_from_pl2 = true;2128break;2129case 0x6611:2130case 0x6613:2131case 0x6608:2132si_pi->cac_weights = cac_weights_oland_pro;2133update_dte_from_pl2 = true;2134break;2135case 0x6610:2136si_pi->cac_weights = cac_weights_oland_xt;2137update_dte_from_pl2 = true;2138break;2139default:2140si_pi->cac_weights = cac_weights_oland;2141si_pi->lcac_config = lcac_oland;2142si_pi->cac_override = cac_override_oland;2143si_pi->powertune_data = &powertune_data_oland;2144si_pi->dte_data = dte_data_oland;2145break;2146}2147} else if (adev->asic_type == CHIP_HAINAN) {2148si_pi->cac_weights = cac_weights_hainan;2149si_pi->lcac_config = lcac_oland;2150si_pi->cac_override = cac_override_oland;2151si_pi->powertune_data = &powertune_data_hainan;2152si_pi->dte_data = dte_data_sun_xt;2153update_dte_from_pl2 = true;2154} else {2155DRM_ERROR("Unknown SI asic revision, failed to initialize PowerTune!\n");2156return;2157}21582159ni_pi->enable_power_containment = false;2160ni_pi->enable_cac = false;2161ni_pi->enable_sq_ramping = false;2162si_pi->enable_dte = false;21632164if (si_pi->powertune_data->enable_powertune_by_default) {2165ni_pi->enable_power_containment = true;2166ni_pi->enable_cac = true;2167if (si_pi->dte_data.enable_dte_by_default) {2168si_pi->enable_dte = true;2169if (update_dte_from_pl2)2170si_update_dte_from_pl2(adev, &si_pi->dte_data);21712172}2173ni_pi->enable_sq_ramping = true;2174}21752176ni_pi->driver_calculate_cac_leakage = true;2177ni_pi->cac_configuration_required = true;21782179if (ni_pi->cac_configuration_required) {2180ni_pi->support_cac_long_term_average = true;2181si_pi->dyn_powertune_data.l2_lta_window_size =2182si_pi->powertune_data->l2_lta_window_size_default;2183si_pi->dyn_powertune_data.lts_truncate =2184si_pi->powertune_data->lts_truncate_default;2185} else {2186ni_pi->support_cac_long_term_average = false;2187si_pi->dyn_powertune_data.l2_lta_window_size = 0;2188si_pi->dyn_powertune_data.lts_truncate = 0;2189}21902191si_pi->dyn_powertune_data.disable_uvd_powertune = false;2192}21932194static u32 si_get_smc_power_scaling_factor(struct amdgpu_device *adev)2195{2196return 1;2197}21982199static u32 si_calculate_cac_wintime(struct amdgpu_device *adev)2200{2201u32 xclk;2202u32 wintime;2203u32 cac_window;2204u32 cac_window_size;22052206xclk = amdgpu_asic_get_xclk(adev);22072208if (xclk == 0)2209return 0;22102211cac_window = RREG32(mmCG_CAC_CTRL) & CG_CAC_CTRL__CAC_WINDOW_MASK;2212cac_window_size = ((cac_window & 0xFFFF0000) >> 16) * (cac_window & 0x0000FFFF);22132214wintime = (cac_window_size * 100) / xclk;22152216return wintime;2217}22182219static u32 si_scale_power_for_smc(u32 power_in_watts, u32 scaling_factor)2220{2221return power_in_watts;2222}22232224static int si_calculate_adjusted_tdp_limits(struct amdgpu_device *adev,2225bool adjust_polarity,2226u32 tdp_adjustment,2227u32 *tdp_limit,2228u32 *near_tdp_limit)2229{2230u32 adjustment_delta, max_tdp_limit;22312232if (tdp_adjustment > (u32)adev->pm.dpm.tdp_od_limit)2233return -EINVAL;22342235max_tdp_limit = ((100 + 100) * adev->pm.dpm.tdp_limit) / 100;22362237if (adjust_polarity) {2238*tdp_limit = ((100 + tdp_adjustment) * adev->pm.dpm.tdp_limit) / 100;2239*near_tdp_limit = adev->pm.dpm.near_tdp_limit_adjusted + (*tdp_limit - adev->pm.dpm.tdp_limit);2240} else {2241*tdp_limit = ((100 - tdp_adjustment) * adev->pm.dpm.tdp_limit) / 100;2242adjustment_delta = adev->pm.dpm.tdp_limit - *tdp_limit;2243if (adjustment_delta < adev->pm.dpm.near_tdp_limit_adjusted)2244*near_tdp_limit = adev->pm.dpm.near_tdp_limit_adjusted - adjustment_delta;2245else2246*near_tdp_limit = 0;2247}22482249if ((*tdp_limit <= 0) || (*tdp_limit > max_tdp_limit))2250return -EINVAL;2251if ((*near_tdp_limit <= 0) || (*near_tdp_limit > *tdp_limit))2252return -EINVAL;22532254return 0;2255}22562257static int si_populate_smc_tdp_limits(struct amdgpu_device *adev,2258struct amdgpu_ps *amdgpu_state)2259{2260struct ni_power_info *ni_pi = ni_get_pi(adev);2261struct si_power_info *si_pi = si_get_pi(adev);22622263if (ni_pi->enable_power_containment) {2264SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable;2265PP_SIslands_PAPMParameters *papm_parm;2266struct amdgpu_ppm_table *ppm = adev->pm.dpm.dyn_state.ppm_table;2267u32 scaling_factor = si_get_smc_power_scaling_factor(adev);2268u32 tdp_limit;2269u32 near_tdp_limit;2270int ret;22712272if (scaling_factor == 0)2273return -EINVAL;22742275memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE));22762277ret = si_calculate_adjusted_tdp_limits(adev,2278false, /* ??? */2279adev->pm.dpm.tdp_adjustment,2280&tdp_limit,2281&near_tdp_limit);2282if (ret)2283return ret;22842285smc_table->dpm2Params.TDPLimit =2286cpu_to_be32(si_scale_power_for_smc(tdp_limit, scaling_factor) * 1000);2287smc_table->dpm2Params.NearTDPLimit =2288cpu_to_be32(si_scale_power_for_smc(near_tdp_limit, scaling_factor) * 1000);2289smc_table->dpm2Params.SafePowerLimit =2290cpu_to_be32(si_scale_power_for_smc((near_tdp_limit * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100, scaling_factor) * 1000);22912292ret = amdgpu_si_copy_bytes_to_smc(adev,2293(si_pi->state_table_start + offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) +2294offsetof(PP_SIslands_DPM2Parameters, TDPLimit)),2295(u8 *)(&(smc_table->dpm2Params.TDPLimit)),2296sizeof(u32) * 3,2297si_pi->sram_end);2298if (ret)2299return ret;23002301if (si_pi->enable_ppm) {2302papm_parm = &si_pi->papm_parm;2303memset(papm_parm, 0, sizeof(PP_SIslands_PAPMParameters));2304papm_parm->NearTDPLimitTherm = cpu_to_be32(ppm->dgpu_tdp);2305papm_parm->dGPU_T_Limit = cpu_to_be32(ppm->tj_max);2306papm_parm->dGPU_T_Warning = cpu_to_be32(95);2307papm_parm->dGPU_T_Hysteresis = cpu_to_be32(5);2308papm_parm->PlatformPowerLimit = 0xffffffff;2309papm_parm->NearTDPLimitPAPM = 0xffffffff;23102311ret = amdgpu_si_copy_bytes_to_smc(adev, si_pi->papm_cfg_table_start,2312(u8 *)papm_parm,2313sizeof(PP_SIslands_PAPMParameters),2314si_pi->sram_end);2315if (ret)2316return ret;2317}2318}2319return 0;2320}23212322static int si_populate_smc_tdp_limits_2(struct amdgpu_device *adev,2323struct amdgpu_ps *amdgpu_state)2324{2325struct ni_power_info *ni_pi = ni_get_pi(adev);2326struct si_power_info *si_pi = si_get_pi(adev);23272328if (ni_pi->enable_power_containment) {2329SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable;2330u32 scaling_factor = si_get_smc_power_scaling_factor(adev);2331int ret;23322333memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE));23342335smc_table->dpm2Params.NearTDPLimit =2336cpu_to_be32(si_scale_power_for_smc(adev->pm.dpm.near_tdp_limit_adjusted, scaling_factor) * 1000);2337smc_table->dpm2Params.SafePowerLimit =2338cpu_to_be32(si_scale_power_for_smc((adev->pm.dpm.near_tdp_limit_adjusted * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100, scaling_factor) * 1000);23392340ret = amdgpu_si_copy_bytes_to_smc(adev,2341(si_pi->state_table_start +2342offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) +2343offsetof(PP_SIslands_DPM2Parameters, NearTDPLimit)),2344(u8 *)(&(smc_table->dpm2Params.NearTDPLimit)),2345sizeof(u32) * 2,2346si_pi->sram_end);2347if (ret)2348return ret;2349}23502351return 0;2352}23532354static u16 si_calculate_power_efficiency_ratio(struct amdgpu_device *adev,2355const u16 prev_std_vddc,2356const u16 curr_std_vddc)2357{2358u64 margin = (u64)SISLANDS_DPM2_PWREFFICIENCYRATIO_MARGIN;2359u64 prev_vddc = (u64)prev_std_vddc;2360u64 curr_vddc = (u64)curr_std_vddc;2361u64 pwr_efficiency_ratio, n, d;23622363if ((prev_vddc == 0) || (curr_vddc == 0))2364return 0;23652366n = div64_u64((u64)1024 * curr_vddc * curr_vddc * ((u64)1000 + margin), (u64)1000);2367d = prev_vddc * prev_vddc;2368pwr_efficiency_ratio = div64_u64(n, d);23692370if (pwr_efficiency_ratio > (u64)0xFFFF)2371return 0;23722373return (u16)pwr_efficiency_ratio;2374}23752376static bool si_should_disable_uvd_powertune(struct amdgpu_device *adev,2377struct amdgpu_ps *amdgpu_state)2378{2379struct si_power_info *si_pi = si_get_pi(adev);23802381if (si_pi->dyn_powertune_data.disable_uvd_powertune &&2382amdgpu_state->vclk && amdgpu_state->dclk)2383return true;23842385return false;2386}23872388struct evergreen_power_info *evergreen_get_pi(struct amdgpu_device *adev)2389{2390struct evergreen_power_info *pi = adev->pm.dpm.priv;23912392return pi;2393}23942395static int si_populate_power_containment_values(struct amdgpu_device *adev,2396struct amdgpu_ps *amdgpu_state,2397SISLANDS_SMC_SWSTATE *smc_state)2398{2399struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);2400struct ni_power_info *ni_pi = ni_get_pi(adev);2401struct si_ps *state = si_get_ps(amdgpu_state);2402SISLANDS_SMC_VOLTAGE_VALUE vddc;2403u32 prev_sclk;2404u32 max_sclk;2405u32 min_sclk;2406u16 prev_std_vddc;2407u16 curr_std_vddc;2408int i;2409u16 pwr_efficiency_ratio;2410u8 max_ps_percent;2411bool disable_uvd_power_tune;2412int ret;24132414if (ni_pi->enable_power_containment == false)2415return 0;24162417if (state->performance_level_count == 0)2418return -EINVAL;24192420if (smc_state->levelCount != state->performance_level_count)2421return -EINVAL;24222423disable_uvd_power_tune = si_should_disable_uvd_powertune(adev, amdgpu_state);24242425smc_state->levels[0].dpm2.MaxPS = 0;2426smc_state->levels[0].dpm2.NearTDPDec = 0;2427smc_state->levels[0].dpm2.AboveSafeInc = 0;2428smc_state->levels[0].dpm2.BelowSafeInc = 0;2429smc_state->levels[0].dpm2.PwrEfficiencyRatio = 0;24302431for (i = 1; i < state->performance_level_count; i++) {2432prev_sclk = state->performance_levels[i-1].sclk;2433max_sclk = state->performance_levels[i].sclk;2434if (i == 1)2435max_ps_percent = SISLANDS_DPM2_MAXPS_PERCENT_M;2436else2437max_ps_percent = SISLANDS_DPM2_MAXPS_PERCENT_H;24382439if (prev_sclk > max_sclk)2440return -EINVAL;24412442if ((max_ps_percent == 0) ||2443(prev_sclk == max_sclk) ||2444disable_uvd_power_tune)2445min_sclk = max_sclk;2446else if (i == 1)2447min_sclk = prev_sclk;2448else2449min_sclk = (prev_sclk * (u32)max_ps_percent) / 100;24502451if (min_sclk < state->performance_levels[0].sclk)2452min_sclk = state->performance_levels[0].sclk;24532454if (min_sclk == 0)2455return -EINVAL;24562457ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,2458state->performance_levels[i-1].vddc, &vddc);2459if (ret)2460return ret;24612462ret = si_get_std_voltage_value(adev, &vddc, &prev_std_vddc);2463if (ret)2464return ret;24652466ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,2467state->performance_levels[i].vddc, &vddc);2468if (ret)2469return ret;24702471ret = si_get_std_voltage_value(adev, &vddc, &curr_std_vddc);2472if (ret)2473return ret;24742475pwr_efficiency_ratio = si_calculate_power_efficiency_ratio(adev,2476prev_std_vddc, curr_std_vddc);24772478smc_state->levels[i].dpm2.MaxPS = (u8)((SISLANDS_DPM2_MAX_PULSE_SKIP * (max_sclk - min_sclk)) / max_sclk);2479smc_state->levels[i].dpm2.NearTDPDec = SISLANDS_DPM2_NEAR_TDP_DEC;2480smc_state->levels[i].dpm2.AboveSafeInc = SISLANDS_DPM2_ABOVE_SAFE_INC;2481smc_state->levels[i].dpm2.BelowSafeInc = SISLANDS_DPM2_BELOW_SAFE_INC;2482smc_state->levels[i].dpm2.PwrEfficiencyRatio = cpu_to_be16(pwr_efficiency_ratio);2483}24842485return 0;2486}24872488static int si_populate_sq_ramping_values(struct amdgpu_device *adev,2489struct amdgpu_ps *amdgpu_state,2490SISLANDS_SMC_SWSTATE *smc_state)2491{2492struct ni_power_info *ni_pi = ni_get_pi(adev);2493struct si_ps *state = si_get_ps(amdgpu_state);2494u32 sq_power_throttle, sq_power_throttle2;2495bool enable_sq_ramping = ni_pi->enable_sq_ramping;2496int i;24972498if (state->performance_level_count == 0)2499return -EINVAL;25002501if (smc_state->levelCount != state->performance_level_count)2502return -EINVAL;25032504if (adev->pm.dpm.sq_ramping_threshold == 0)2505return -EINVAL;25062507if (SISLANDS_DPM2_SQ_RAMP_MAX_POWER > (SQ_POWER_THROTTLE__MAX_POWER_MASK >> SQ_POWER_THROTTLE__MAX_POWER__SHIFT))2508enable_sq_ramping = false;25092510if (SISLANDS_DPM2_SQ_RAMP_MIN_POWER > (SQ_POWER_THROTTLE__MIN_POWER_MASK >> SQ_POWER_THROTTLE__MIN_POWER__SHIFT))2511enable_sq_ramping = false;25122513if (SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA > (SQ_POWER_THROTTLE2__MAX_POWER_DELTA_MASK >> SQ_POWER_THROTTLE2__MAX_POWER_DELTA__SHIFT))2514enable_sq_ramping = false;25152516if (SISLANDS_DPM2_SQ_RAMP_STI_SIZE > (SQ_POWER_THROTTLE2__SHORT_TERM_INTERVAL_SIZE_MASK >> SQ_POWER_THROTTLE2__SHORT_TERM_INTERVAL_SIZE__SHIFT))2517enable_sq_ramping = false;25182519if (SISLANDS_DPM2_SQ_RAMP_LTI_RATIO > (SQ_POWER_THROTTLE2__LONG_TERM_INTERVAL_RATIO_MASK >> SQ_POWER_THROTTLE2__LONG_TERM_INTERVAL_RATIO__SHIFT))2520enable_sq_ramping = false;25212522for (i = 0; i < state->performance_level_count; i++) {2523sq_power_throttle = 0;2524sq_power_throttle2 = 0;25252526if ((state->performance_levels[i].sclk >= adev->pm.dpm.sq_ramping_threshold) &&2527enable_sq_ramping) {2528sq_power_throttle |= SISLANDS_DPM2_SQ_RAMP_MAX_POWER << SQ_POWER_THROTTLE__MAX_POWER__SHIFT;2529sq_power_throttle |= SISLANDS_DPM2_SQ_RAMP_MIN_POWER << SQ_POWER_THROTTLE__MIN_POWER__SHIFT;2530sq_power_throttle2 |= SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA << SQ_POWER_THROTTLE2__MAX_POWER_DELTA__SHIFT;2531sq_power_throttle2 |= SISLANDS_DPM2_SQ_RAMP_STI_SIZE << SQ_POWER_THROTTLE2__SHORT_TERM_INTERVAL_SIZE__SHIFT;2532sq_power_throttle2 |= SISLANDS_DPM2_SQ_RAMP_LTI_RATIO << SQ_POWER_THROTTLE2__LONG_TERM_INTERVAL_RATIO__SHIFT;2533} else {2534sq_power_throttle |= SQ_POWER_THROTTLE__MAX_POWER_MASK |2535SQ_POWER_THROTTLE__MIN_POWER_MASK;2536sq_power_throttle2 |= SQ_POWER_THROTTLE2__MAX_POWER_DELTA_MASK |2537SQ_POWER_THROTTLE2__SHORT_TERM_INTERVAL_SIZE_MASK |2538SQ_POWER_THROTTLE2__LONG_TERM_INTERVAL_RATIO_MASK;2539}25402541smc_state->levels[i].SQPowerThrottle = cpu_to_be32(sq_power_throttle);2542smc_state->levels[i].SQPowerThrottle_2 = cpu_to_be32(sq_power_throttle2);2543}25442545return 0;2546}25472548static int si_enable_power_containment(struct amdgpu_device *adev,2549struct amdgpu_ps *amdgpu_new_state,2550bool enable)2551{2552struct ni_power_info *ni_pi = ni_get_pi(adev);2553PPSMC_Result smc_result;2554int ret = 0;25552556if (ni_pi->enable_power_containment) {2557if (enable) {2558if (!si_should_disable_uvd_powertune(adev, amdgpu_new_state)) {2559smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_TDPClampingActive);2560if (smc_result != PPSMC_Result_OK) {2561ret = -EINVAL;2562ni_pi->pc_enabled = false;2563} else {2564ni_pi->pc_enabled = true;2565}2566}2567} else {2568smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_TDPClampingInactive);2569if (smc_result != PPSMC_Result_OK)2570ret = -EINVAL;2571ni_pi->pc_enabled = false;2572}2573}25742575return ret;2576}25772578static int si_initialize_smc_dte_tables(struct amdgpu_device *adev)2579{2580struct si_power_info *si_pi = si_get_pi(adev);2581int ret = 0;2582struct si_dte_data *dte_data = &si_pi->dte_data;2583Smc_SIslands_DTE_Configuration *dte_tables = NULL;2584u32 table_size;2585u8 tdep_count;2586u32 i;25872588if (dte_data == NULL)2589si_pi->enable_dte = false;25902591if (si_pi->enable_dte == false)2592return 0;25932594if (dte_data->k <= 0)2595return -EINVAL;25962597dte_tables = kzalloc(sizeof(Smc_SIslands_DTE_Configuration), GFP_KERNEL);2598if (dte_tables == NULL) {2599si_pi->enable_dte = false;2600return -ENOMEM;2601}26022603table_size = dte_data->k;26042605if (table_size > SMC_SISLANDS_DTE_MAX_FILTER_STAGES)2606table_size = SMC_SISLANDS_DTE_MAX_FILTER_STAGES;26072608tdep_count = dte_data->tdep_count;2609if (tdep_count > SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE)2610tdep_count = SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE;26112612dte_tables->K = cpu_to_be32(table_size);2613dte_tables->T0 = cpu_to_be32(dte_data->t0);2614dte_tables->MaxT = cpu_to_be32(dte_data->max_t);2615dte_tables->WindowSize = dte_data->window_size;2616dte_tables->temp_select = dte_data->temp_select;2617dte_tables->DTE_mode = dte_data->dte_mode;2618dte_tables->Tthreshold = cpu_to_be32(dte_data->t_threshold);26192620if (tdep_count > 0)2621table_size--;26222623for (i = 0; i < table_size; i++) {2624dte_tables->tau[i] = cpu_to_be32(dte_data->tau[i]);2625dte_tables->R[i] = cpu_to_be32(dte_data->r[i]);2626}26272628dte_tables->Tdep_count = tdep_count;26292630for (i = 0; i < (u32)tdep_count; i++) {2631dte_tables->T_limits[i] = dte_data->t_limits[i];2632dte_tables->Tdep_tau[i] = cpu_to_be32(dte_data->tdep_tau[i]);2633dte_tables->Tdep_R[i] = cpu_to_be32(dte_data->tdep_r[i]);2634}26352636ret = amdgpu_si_copy_bytes_to_smc(adev, si_pi->dte_table_start,2637(u8 *)dte_tables,2638sizeof(Smc_SIslands_DTE_Configuration),2639si_pi->sram_end);2640kfree(dte_tables);26412642return ret;2643}26442645static int si_get_cac_std_voltage_max_min(struct amdgpu_device *adev,2646u16 *max, u16 *min)2647{2648struct si_power_info *si_pi = si_get_pi(adev);2649struct amdgpu_cac_leakage_table *table =2650&adev->pm.dpm.dyn_state.cac_leakage_table;2651u32 i;2652u32 v0_loadline;26532654if (table == NULL)2655return -EINVAL;26562657*max = 0;2658*min = 0xFFFF;26592660for (i = 0; i < table->count; i++) {2661if (table->entries[i].vddc > *max)2662*max = table->entries[i].vddc;2663if (table->entries[i].vddc < *min)2664*min = table->entries[i].vddc;2665}26662667if (si_pi->powertune_data->lkge_lut_v0_percent > 100)2668return -EINVAL;26692670v0_loadline = (*min) * (100 - si_pi->powertune_data->lkge_lut_v0_percent) / 100;26712672if (v0_loadline > 0xFFFFUL)2673return -EINVAL;26742675*min = (u16)v0_loadline;26762677if ((*min > *max) || (*max == 0) || (*min == 0))2678return -EINVAL;26792680return 0;2681}26822683static u16 si_get_cac_std_voltage_step(u16 max, u16 min)2684{2685return ((max - min) + (SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1)) /2686SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES;2687}26882689static int si_init_dte_leakage_table(struct amdgpu_device *adev,2690PP_SIslands_CacConfig *cac_tables,2691u16 vddc_max, u16 vddc_min, u16 vddc_step,2692u16 t0, u16 t_step)2693{2694struct si_power_info *si_pi = si_get_pi(adev);2695u32 leakage;2696unsigned int i, j;2697s32 t;2698u32 smc_leakage;2699u32 scaling_factor;2700u16 voltage;27012702scaling_factor = si_get_smc_power_scaling_factor(adev);27032704for (i = 0; i < SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES ; i++) {2705t = (1000 * (i * t_step + t0));27062707for (j = 0; j < SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {2708voltage = vddc_max - (vddc_step * j);27092710si_calculate_leakage_for_v_and_t(adev,2711&si_pi->powertune_data->leakage_coefficients,2712voltage,2713t,2714si_pi->dyn_powertune_data.cac_leakage,2715&leakage);27162717smc_leakage = si_scale_power_for_smc(leakage, scaling_factor) / 4;27182719if (smc_leakage > 0xFFFF)2720smc_leakage = 0xFFFF;27212722cac_tables->cac_lkge_lut[i][SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES-1-j] =2723cpu_to_be16((u16)smc_leakage);2724}2725}2726return 0;2727}27282729static int si_init_simplified_leakage_table(struct amdgpu_device *adev,2730PP_SIslands_CacConfig *cac_tables,2731u16 vddc_max, u16 vddc_min, u16 vddc_step)2732{2733struct si_power_info *si_pi = si_get_pi(adev);2734u32 leakage;2735unsigned int i, j;2736u32 smc_leakage;2737u32 scaling_factor;2738u16 voltage;27392740scaling_factor = si_get_smc_power_scaling_factor(adev);27412742for (j = 0; j < SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {2743voltage = vddc_max - (vddc_step * j);27442745si_calculate_leakage_for_v(adev,2746&si_pi->powertune_data->leakage_coefficients,2747si_pi->powertune_data->fixed_kt,2748voltage,2749si_pi->dyn_powertune_data.cac_leakage,2750&leakage);27512752smc_leakage = si_scale_power_for_smc(leakage, scaling_factor) / 4;27532754if (smc_leakage > 0xFFFF)2755smc_leakage = 0xFFFF;27562757for (i = 0; i < SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES ; i++)2758cac_tables->cac_lkge_lut[i][SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES-1-j] =2759cpu_to_be16((u16)smc_leakage);2760}2761return 0;2762}27632764static int si_initialize_smc_cac_tables(struct amdgpu_device *adev)2765{2766struct ni_power_info *ni_pi = ni_get_pi(adev);2767struct si_power_info *si_pi = si_get_pi(adev);2768PP_SIslands_CacConfig *cac_tables = NULL;2769u16 vddc_max, vddc_min, vddc_step;2770u16 t0, t_step;2771u32 load_line_slope, reg;2772int ret = 0;2773u32 ticks_per_us = amdgpu_asic_get_xclk(adev) / 100;27742775if (ni_pi->enable_cac == false)2776return 0;27772778cac_tables = kzalloc(sizeof(PP_SIslands_CacConfig), GFP_KERNEL);2779if (!cac_tables)2780return -ENOMEM;27812782reg = RREG32(mmCG_CAC_CTRL) & ~CG_CAC_CTRL__CAC_WINDOW_MASK;2783reg |= (si_pi->powertune_data->cac_window << CG_CAC_CTRL__CAC_WINDOW__SHIFT);2784WREG32(mmCG_CAC_CTRL, reg);27852786si_pi->dyn_powertune_data.cac_leakage = adev->pm.dpm.cac_leakage;2787si_pi->dyn_powertune_data.dc_pwr_value =2788si_pi->powertune_data->dc_cac[NISLANDS_DCCAC_LEVEL_0];2789si_pi->dyn_powertune_data.wintime = si_calculate_cac_wintime(adev);2790si_pi->dyn_powertune_data.shift_n = si_pi->powertune_data->shift_n_default;27912792si_pi->dyn_powertune_data.leakage_minimum_temperature = 80 * 1000;27932794ret = si_get_cac_std_voltage_max_min(adev, &vddc_max, &vddc_min);2795if (ret)2796goto done_free;27972798vddc_step = si_get_cac_std_voltage_step(vddc_max, vddc_min);2799vddc_min = vddc_max - (vddc_step * (SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1));2800t_step = 4;2801t0 = 60;28022803if (si_pi->enable_dte || ni_pi->driver_calculate_cac_leakage)2804ret = si_init_dte_leakage_table(adev, cac_tables,2805vddc_max, vddc_min, vddc_step,2806t0, t_step);2807else2808ret = si_init_simplified_leakage_table(adev, cac_tables,2809vddc_max, vddc_min, vddc_step);2810if (ret)2811goto done_free;28122813load_line_slope = ((u32)adev->pm.dpm.load_line_slope << SMC_SISLANDS_SCALE_R) / 100;28142815cac_tables->l2numWin_TDP = cpu_to_be32(si_pi->dyn_powertune_data.l2_lta_window_size);2816cac_tables->lts_truncate_n = si_pi->dyn_powertune_data.lts_truncate;2817cac_tables->SHIFT_N = si_pi->dyn_powertune_data.shift_n;2818cac_tables->lkge_lut_V0 = cpu_to_be32((u32)vddc_min);2819cac_tables->lkge_lut_Vstep = cpu_to_be32((u32)vddc_step);2820cac_tables->R_LL = cpu_to_be32(load_line_slope);2821cac_tables->WinTime = cpu_to_be32(si_pi->dyn_powertune_data.wintime);2822cac_tables->calculation_repeats = cpu_to_be32(2);2823cac_tables->dc_cac = cpu_to_be32(0);2824cac_tables->log2_PG_LKG_SCALE = 12;2825cac_tables->cac_temp = si_pi->powertune_data->operating_temp;2826cac_tables->lkge_lut_T0 = cpu_to_be32((u32)t0);2827cac_tables->lkge_lut_Tstep = cpu_to_be32((u32)t_step);28282829ret = amdgpu_si_copy_bytes_to_smc(adev, si_pi->cac_table_start,2830(u8 *)cac_tables,2831sizeof(PP_SIslands_CacConfig),2832si_pi->sram_end);28332834if (ret)2835goto done_free;28362837ret = si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_ticks_per_us, ticks_per_us);28382839done_free:2840if (ret) {2841ni_pi->enable_cac = false;2842ni_pi->enable_power_containment = false;2843}28442845kfree(cac_tables);28462847return ret;2848}28492850static int si_program_cac_config_registers(struct amdgpu_device *adev,2851const struct si_cac_config_reg *cac_config_regs)2852{2853const struct si_cac_config_reg *config_regs = cac_config_regs;2854u32 data = 0, offset;28552856if (!config_regs)2857return -EINVAL;28582859while (config_regs->offset != 0xFFFFFFFF) {2860switch (config_regs->type) {2861case SISLANDS_CACCONFIG_CGIND:2862offset = SMC_CG_IND_START + config_regs->offset;2863if (offset < SMC_CG_IND_END)2864data = RREG32_SMC(offset);2865break;2866default:2867data = RREG32(config_regs->offset);2868break;2869}28702871data &= ~config_regs->mask;2872data |= ((config_regs->value << config_regs->shift) & config_regs->mask);28732874switch (config_regs->type) {2875case SISLANDS_CACCONFIG_CGIND:2876offset = SMC_CG_IND_START + config_regs->offset;2877if (offset < SMC_CG_IND_END)2878WREG32_SMC(offset, data);2879break;2880default:2881WREG32(config_regs->offset, data);2882break;2883}2884config_regs++;2885}2886return 0;2887}28882889static int si_initialize_hardware_cac_manager(struct amdgpu_device *adev)2890{2891struct ni_power_info *ni_pi = ni_get_pi(adev);2892struct si_power_info *si_pi = si_get_pi(adev);2893int ret;28942895if ((ni_pi->enable_cac == false) ||2896(ni_pi->cac_configuration_required == false))2897return 0;28982899ret = si_program_cac_config_registers(adev, si_pi->lcac_config);2900if (ret)2901return ret;2902ret = si_program_cac_config_registers(adev, si_pi->cac_override);2903if (ret)2904return ret;2905ret = si_program_cac_config_registers(adev, si_pi->cac_weights);2906if (ret)2907return ret;29082909return 0;2910}29112912static int si_enable_smc_cac(struct amdgpu_device *adev,2913struct amdgpu_ps *amdgpu_new_state,2914bool enable)2915{2916struct ni_power_info *ni_pi = ni_get_pi(adev);2917struct si_power_info *si_pi = si_get_pi(adev);2918PPSMC_Result smc_result;2919int ret = 0;29202921if (ni_pi->enable_cac) {2922if (enable) {2923if (!si_should_disable_uvd_powertune(adev, amdgpu_new_state)) {2924if (ni_pi->support_cac_long_term_average) {2925smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_CACLongTermAvgEnable);2926if (smc_result != PPSMC_Result_OK)2927ni_pi->support_cac_long_term_average = false;2928}29292930smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableCac);2931if (smc_result != PPSMC_Result_OK) {2932ret = -EINVAL;2933ni_pi->cac_enabled = false;2934} else {2935ni_pi->cac_enabled = true;2936}29372938if (si_pi->enable_dte) {2939smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableDTE);2940if (smc_result != PPSMC_Result_OK)2941ret = -EINVAL;2942}2943}2944} else if (ni_pi->cac_enabled) {2945if (si_pi->enable_dte)2946smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_DisableDTE);29472948smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_DisableCac);29492950ni_pi->cac_enabled = false;29512952if (ni_pi->support_cac_long_term_average)2953smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_CACLongTermAvgDisable);2954}2955}2956return ret;2957}29582959static int si_init_smc_spll_table(struct amdgpu_device *adev)2960{2961struct ni_power_info *ni_pi = ni_get_pi(adev);2962struct si_power_info *si_pi = si_get_pi(adev);2963SMC_SISLANDS_SPLL_DIV_TABLE *spll_table;2964SISLANDS_SMC_SCLK_VALUE sclk_params;2965u32 fb_div, p_div;2966u32 clk_s, clk_v;2967u32 sclk = 0;2968int ret = 0;2969u32 tmp;2970int i;29712972if (si_pi->spll_table_start == 0)2973return -EINVAL;29742975spll_table = kzalloc(sizeof(SMC_SISLANDS_SPLL_DIV_TABLE), GFP_KERNEL);2976if (spll_table == NULL)2977return -ENOMEM;29782979for (i = 0; i < 256; i++) {2980ret = si_calculate_sclk_params(adev, sclk, &sclk_params);2981if (ret)2982break;2983p_div = (sclk_params.vCG_SPLL_FUNC_CNTL & CG_SPLL_FUNC_CNTL__SPLL_PDIV_A_MASK) >> CG_SPLL_FUNC_CNTL__SPLL_PDIV_A__SHIFT;2984fb_div = (sclk_params.vCG_SPLL_FUNC_CNTL_3 & CG_SPLL_FUNC_CNTL_3__SPLL_FB_DIV_MASK) >> CG_SPLL_FUNC_CNTL_3__SPLL_FB_DIV__SHIFT;2985clk_s = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM & CG_SPLL_SPREAD_SPECTRUM__CLK_S_MASK) >> CG_SPLL_SPREAD_SPECTRUM__CLK_S__SHIFT;2986clk_v = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM_2 & CG_SPLL_SPREAD_SPECTRUM_2__CLK_V_MASK) >> CG_SPLL_SPREAD_SPECTRUM_2__CLK_V__SHIFT;29872988fb_div &= ~0x00001FFF;2989fb_div >>= 1;2990clk_v >>= 6;29912992if (p_div & ~(SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT))2993ret = -EINVAL;2994if (fb_div & ~(SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT))2995ret = -EINVAL;2996if (clk_s & ~(SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT))2997ret = -EINVAL;2998if (clk_v & ~(SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT))2999ret = -EINVAL;30003001if (ret)3002break;30033004tmp = ((fb_div << SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK) |3005((p_div << SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK);3006spll_table->freq[i] = cpu_to_be32(tmp);30073008tmp = ((clk_v << SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK) |3009((clk_s << SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK);3010spll_table->ss[i] = cpu_to_be32(tmp);30113012sclk += 512;3013}301430153016if (!ret)3017ret = amdgpu_si_copy_bytes_to_smc(adev, si_pi->spll_table_start,3018(u8 *)spll_table,3019sizeof(SMC_SISLANDS_SPLL_DIV_TABLE),3020si_pi->sram_end);30213022if (ret)3023ni_pi->enable_power_containment = false;30243025kfree(spll_table);30263027return ret;3028}30293030static u16 si_get_lower_of_leakage_and_vce_voltage(struct amdgpu_device *adev,3031u16 vce_voltage)3032{3033u16 highest_leakage = 0;3034struct si_power_info *si_pi = si_get_pi(adev);3035int i;30363037for (i = 0; i < si_pi->leakage_voltage.count; i++){3038if (highest_leakage < si_pi->leakage_voltage.entries[i].voltage)3039highest_leakage = si_pi->leakage_voltage.entries[i].voltage;3040}30413042if (si_pi->leakage_voltage.count && (highest_leakage < vce_voltage))3043return highest_leakage;30443045return vce_voltage;3046}30473048static int si_get_vce_clock_voltage(struct amdgpu_device *adev,3049u32 evclk, u32 ecclk, u16 *voltage)3050{3051u32 i;3052int ret = -EINVAL;3053struct amdgpu_vce_clock_voltage_dependency_table *table =3054&adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;30553056if (((evclk == 0) && (ecclk == 0)) ||3057(table && (table->count == 0))) {3058*voltage = 0;3059return 0;3060}30613062for (i = 0; i < table->count; i++) {3063if ((evclk <= table->entries[i].evclk) &&3064(ecclk <= table->entries[i].ecclk)) {3065*voltage = table->entries[i].v;3066ret = 0;3067break;3068}3069}30703071/* if no match return the highest voltage */3072if (ret)3073*voltage = table->entries[table->count - 1].v;30743075*voltage = si_get_lower_of_leakage_and_vce_voltage(adev, *voltage);30763077return ret;3078}30793080static bool si_dpm_vblank_too_short(void *handle)3081{3082struct amdgpu_device *adev = (struct amdgpu_device *)handle;3083u32 vblank_time = adev->pm.pm_display_cfg.min_vblank_time;3084/* we never hit the non-gddr5 limit so disable it */3085u32 switch_limit = adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5 ? 450 : 0;30863087/* Consider zero vblank time too short and disable MCLK switching.3088* Note that the vblank time is set to maximum when no displays are attached,3089* so we'll still enable MCLK switching in that case.3090*/3091if (vblank_time == 0)3092return true;3093else if (vblank_time < switch_limit)3094return true;3095else3096return false;30973098}30993100static int ni_copy_and_switch_arb_sets(struct amdgpu_device *adev,3101u32 arb_freq_src, u32 arb_freq_dest)3102{3103u32 mc_arb_dram_timing;3104u32 mc_arb_dram_timing2;3105u32 burst_time;3106u32 mc_cg_config;31073108switch (arb_freq_src) {3109case MC_CG_ARB_FREQ_F0:3110mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING);3111mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);3112burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE0_MASK) >> STATE0_SHIFT;3113break;3114case MC_CG_ARB_FREQ_F1:3115mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING_1);3116mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_1);3117burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE1_MASK) >> STATE1_SHIFT;3118break;3119case MC_CG_ARB_FREQ_F2:3120mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING_2);3121mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_2);3122burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE2_MASK) >> STATE2_SHIFT;3123break;3124case MC_CG_ARB_FREQ_F3:3125mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING_3);3126mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_3);3127burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE3_MASK) >> STATE3_SHIFT;3128break;3129default:3130return -EINVAL;3131}31323133switch (arb_freq_dest) {3134case MC_CG_ARB_FREQ_F0:3135WREG32(MC_ARB_DRAM_TIMING, mc_arb_dram_timing);3136WREG32(MC_ARB_DRAM_TIMING2, mc_arb_dram_timing2);3137WREG32_P(MC_ARB_BURST_TIME, STATE0(burst_time), ~STATE0_MASK);3138break;3139case MC_CG_ARB_FREQ_F1:3140WREG32(MC_ARB_DRAM_TIMING_1, mc_arb_dram_timing);3141WREG32(MC_ARB_DRAM_TIMING2_1, mc_arb_dram_timing2);3142WREG32_P(MC_ARB_BURST_TIME, STATE1(burst_time), ~STATE1_MASK);3143break;3144case MC_CG_ARB_FREQ_F2:3145WREG32(MC_ARB_DRAM_TIMING_2, mc_arb_dram_timing);3146WREG32(MC_ARB_DRAM_TIMING2_2, mc_arb_dram_timing2);3147WREG32_P(MC_ARB_BURST_TIME, STATE2(burst_time), ~STATE2_MASK);3148break;3149case MC_CG_ARB_FREQ_F3:3150WREG32(MC_ARB_DRAM_TIMING_3, mc_arb_dram_timing);3151WREG32(MC_ARB_DRAM_TIMING2_3, mc_arb_dram_timing2);3152WREG32_P(MC_ARB_BURST_TIME, STATE3(burst_time), ~STATE3_MASK);3153break;3154default:3155return -EINVAL;3156}31573158mc_cg_config = RREG32(MC_CG_CONFIG) | 0x0000000F;3159WREG32(MC_CG_CONFIG, mc_cg_config);3160WREG32_P(MC_ARB_CG, CG_ARB_REQ(arb_freq_dest), ~CG_ARB_REQ_MASK);31613162return 0;3163}31643165static void ni_update_current_ps(struct amdgpu_device *adev,3166struct amdgpu_ps *rps)3167{3168struct si_ps *new_ps = si_get_ps(rps);3169struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);3170struct ni_power_info *ni_pi = ni_get_pi(adev);31713172eg_pi->current_rps = *rps;3173ni_pi->current_ps = *new_ps;3174eg_pi->current_rps.ps_priv = &ni_pi->current_ps;3175adev->pm.dpm.current_ps = &eg_pi->current_rps;3176}31773178static void ni_update_requested_ps(struct amdgpu_device *adev,3179struct amdgpu_ps *rps)3180{3181struct si_ps *new_ps = si_get_ps(rps);3182struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);3183struct ni_power_info *ni_pi = ni_get_pi(adev);31843185eg_pi->requested_rps = *rps;3186ni_pi->requested_ps = *new_ps;3187eg_pi->requested_rps.ps_priv = &ni_pi->requested_ps;3188adev->pm.dpm.requested_ps = &eg_pi->requested_rps;3189}31903191static void ni_set_uvd_clock_before_set_eng_clock(struct amdgpu_device *adev,3192struct amdgpu_ps *new_ps,3193struct amdgpu_ps *old_ps)3194{3195struct si_ps *new_state = si_get_ps(new_ps);3196struct si_ps *current_state = si_get_ps(old_ps);31973198if ((new_ps->vclk == old_ps->vclk) &&3199(new_ps->dclk == old_ps->dclk))3200return;32013202if (new_state->performance_levels[new_state->performance_level_count - 1].sclk >=3203current_state->performance_levels[current_state->performance_level_count - 1].sclk)3204return;32053206amdgpu_asic_set_uvd_clocks(adev, new_ps->vclk, new_ps->dclk);3207}32083209static void ni_set_uvd_clock_after_set_eng_clock(struct amdgpu_device *adev,3210struct amdgpu_ps *new_ps,3211struct amdgpu_ps *old_ps)3212{3213struct si_ps *new_state = si_get_ps(new_ps);3214struct si_ps *current_state = si_get_ps(old_ps);32153216if ((new_ps->vclk == old_ps->vclk) &&3217(new_ps->dclk == old_ps->dclk))3218return;32193220if (new_state->performance_levels[new_state->performance_level_count - 1].sclk <3221current_state->performance_levels[current_state->performance_level_count - 1].sclk)3222return;32233224amdgpu_asic_set_uvd_clocks(adev, new_ps->vclk, new_ps->dclk);3225}32263227static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)3228{3229unsigned int i;32303231for (i = 0; i < table->count; i++)3232if (voltage <= table->entries[i].value)3233return table->entries[i].value;32343235return table->entries[table->count - 1].value;3236}32373238static u32 btc_find_valid_clock(struct amdgpu_clock_array *clocks,3239u32 max_clock, u32 requested_clock)3240{3241unsigned int i;32423243if ((clocks == NULL) || (clocks->count == 0))3244return (requested_clock < max_clock) ? requested_clock : max_clock;32453246for (i = 0; i < clocks->count; i++) {3247if (clocks->values[i] >= requested_clock)3248return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock;3249}32503251return (clocks->values[clocks->count - 1] < max_clock) ?3252clocks->values[clocks->count - 1] : max_clock;3253}32543255static u32 btc_get_valid_mclk(struct amdgpu_device *adev,3256u32 max_mclk, u32 requested_mclk)3257{3258return btc_find_valid_clock(&adev->pm.dpm.dyn_state.valid_mclk_values,3259max_mclk, requested_mclk);3260}32613262static u32 btc_get_valid_sclk(struct amdgpu_device *adev,3263u32 max_sclk, u32 requested_sclk)3264{3265return btc_find_valid_clock(&adev->pm.dpm.dyn_state.valid_sclk_values,3266max_sclk, requested_sclk);3267}32683269static void btc_get_max_clock_from_voltage_dependency_table(struct amdgpu_clock_voltage_dependency_table *table,3270u32 *max_clock)3271{3272u32 i, clock = 0;32733274if ((table == NULL) || (table->count == 0)) {3275*max_clock = clock;3276return;3277}32783279for (i = 0; i < table->count; i++) {3280if (clock < table->entries[i].clk)3281clock = table->entries[i].clk;3282}3283*max_clock = clock;3284}32853286static void btc_apply_voltage_dependency_rules(struct amdgpu_clock_voltage_dependency_table *table,3287u32 clock, u16 max_voltage, u16 *voltage)3288{3289u32 i;32903291if ((table == NULL) || (table->count == 0))3292return;32933294for (i= 0; i < table->count; i++) {3295if (clock <= table->entries[i].clk) {3296if (*voltage < table->entries[i].v)3297*voltage = (u16)((table->entries[i].v < max_voltage) ?3298table->entries[i].v : max_voltage);3299return;3300}3301}33023303*voltage = (*voltage > max_voltage) ? *voltage : max_voltage;3304}33053306static void btc_adjust_clock_combinations(struct amdgpu_device *adev,3307const struct amdgpu_clock_and_voltage_limits *max_limits,3308struct rv7xx_pl *pl)3309{33103311if ((pl->mclk == 0) || (pl->sclk == 0))3312return;33133314if (pl->mclk == pl->sclk)3315return;33163317if (pl->mclk > pl->sclk) {3318if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > adev->pm.dpm.dyn_state.mclk_sclk_ratio)3319pl->sclk = btc_get_valid_sclk(adev,3320max_limits->sclk,3321(pl->mclk +3322(adev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) /3323adev->pm.dpm.dyn_state.mclk_sclk_ratio);3324} else {3325if ((pl->sclk - pl->mclk) > adev->pm.dpm.dyn_state.sclk_mclk_delta)3326pl->mclk = btc_get_valid_mclk(adev,3327max_limits->mclk,3328pl->sclk -3329adev->pm.dpm.dyn_state.sclk_mclk_delta);3330}3331}33323333static void btc_apply_voltage_delta_rules(struct amdgpu_device *adev,3334u16 max_vddc, u16 max_vddci,3335u16 *vddc, u16 *vddci)3336{3337struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);3338u16 new_voltage;33393340if ((0 == *vddc) || (0 == *vddci))3341return;33423343if (*vddc > *vddci) {3344if ((*vddc - *vddci) > adev->pm.dpm.dyn_state.vddc_vddci_delta) {3345new_voltage = btc_find_voltage(&eg_pi->vddci_voltage_table,3346(*vddc - adev->pm.dpm.dyn_state.vddc_vddci_delta));3347*vddci = (new_voltage < max_vddci) ? new_voltage : max_vddci;3348}3349} else {3350if ((*vddci - *vddc) > adev->pm.dpm.dyn_state.vddc_vddci_delta) {3351new_voltage = btc_find_voltage(&eg_pi->vddc_voltage_table,3352(*vddci - adev->pm.dpm.dyn_state.vddc_vddci_delta));3353*vddc = (new_voltage < max_vddc) ? new_voltage : max_vddc;3354}3355}3356}33573358static void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,3359u32 *p, u32 *u)3360{3361u32 b_c = 0;3362u32 i_c;3363u32 tmp;33643365i_c = (i * r_c) / 100;3366tmp = i_c >> p_b;33673368while (tmp) {3369b_c++;3370tmp >>= 1;3371}33723373*u = (b_c + 1) / 2;3374*p = i_c / (1 << (2 * (*u)));3375}33763377static int r600_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th)3378{3379u32 k, a, ah, al;3380u32 t1;33813382if ((fl == 0) || (fh == 0) || (fl > fh))3383return -EINVAL;33843385k = (100 * fh) / fl;3386t1 = (t * (k - 100));3387a = (1000 * (100 * h + t1)) / (10000 + (t1 / 100));3388a = (a + 5) / 10;3389ah = ((a * t) + 5000) / 10000;3390al = a - ah;33913392*th = t - ah;3393*tl = t + al;33943395return 0;3396}33973398static bool r600_is_uvd_state(u32 class, u32 class2)3399{3400if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)3401return true;3402if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)3403return true;3404if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)3405return true;3406if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)3407return true;3408if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)3409return true;3410return false;3411}34123413static u8 rv770_get_memory_module_index(struct amdgpu_device *adev)3414{3415return (u8) ((RREG32(BIOS_SCRATCH_4) >> 16) & 0xff);3416}34173418static void rv770_get_max_vddc(struct amdgpu_device *adev)3419{3420struct rv7xx_power_info *pi = rv770_get_pi(adev);3421u16 vddc;34223423if (amdgpu_atombios_get_max_vddc(adev, 0, 0, &vddc))3424pi->max_vddc = 0;3425else3426pi->max_vddc = vddc;3427}34283429static void rv770_get_engine_memory_ss(struct amdgpu_device *adev)3430{3431struct rv7xx_power_info *pi = rv770_get_pi(adev);3432struct amdgpu_atom_ss ss;34333434pi->sclk_ss = amdgpu_atombios_get_asic_ss_info(adev, &ss,3435ASIC_INTERNAL_ENGINE_SS, 0);3436pi->mclk_ss = amdgpu_atombios_get_asic_ss_info(adev, &ss,3437ASIC_INTERNAL_MEMORY_SS, 0);34383439if (pi->sclk_ss || pi->mclk_ss)3440pi->dynamic_ss = true;3441else3442pi->dynamic_ss = false;3443}344434453446static void si_apply_state_adjust_rules(struct amdgpu_device *adev,3447struct amdgpu_ps *rps)3448{3449const struct amd_pp_display_configuration *display_cfg =3450&adev->pm.pm_display_cfg;3451struct si_ps *ps = si_get_ps(rps);3452struct amdgpu_clock_and_voltage_limits *max_limits;3453bool disable_mclk_switching = false;3454bool disable_sclk_switching = false;3455u32 mclk, sclk;3456u16 vddc, vddci, min_vce_voltage = 0;3457u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;3458u32 max_sclk = 0, max_mclk = 0;3459u32 high_pixelclock_count = 0;3460int i;34613462if (adev->asic_type == CHIP_HAINAN) {3463if ((adev->pdev->revision == 0x81) ||3464(adev->pdev->revision == 0xC3) ||3465(adev->pdev->device == 0x6664) ||3466(adev->pdev->device == 0x6665) ||3467(adev->pdev->device == 0x6667)) {3468max_sclk = 75000;3469}3470if ((adev->pdev->revision == 0xC3) ||3471(adev->pdev->device == 0x6665)) {3472max_sclk = 60000;3473max_mclk = 80000;3474}3475} else if (adev->asic_type == CHIP_OLAND) {3476if ((adev->pdev->revision == 0xC7) ||3477(adev->pdev->revision == 0x80) ||3478(adev->pdev->revision == 0x81) ||3479(adev->pdev->revision == 0x83) ||3480(adev->pdev->revision == 0x87) ||3481(adev->pdev->device == 0x6604) ||3482(adev->pdev->device == 0x6605)) {3483max_sclk = 75000;3484}3485}34863487/* We define "high pixelclock" for SI as higher than necessary for 4K 30Hz.3488* For example, 4K 60Hz and 1080p 144Hz fall into this category.3489* Find number of such displays connected.3490*/3491for (i = 0; i < display_cfg->num_display; i++) {3492/* The array only contains active displays. */3493if (display_cfg->displays[i].pixel_clock > 297000)3494high_pixelclock_count++;3495}34963497/* These are some ad-hoc fixes to some issues observed with SI GPUs.3498* They are necessary because we don't have something like dce_calcs3499* for these GPUs to calculate bandwidth requirements.3500*/3501if (high_pixelclock_count) {3502/* On Oland, we observe some flickering when two 4K 60Hz3503* displays are connected, possibly because voltage is too low.3504* Raise the voltage by requiring a higher SCLK.3505* (Voltage cannot be adjusted independently without also SCLK.)3506*/3507if (high_pixelclock_count > 1 && adev->asic_type == CHIP_OLAND)3508disable_sclk_switching = true;3509}35103511if (rps->vce_active) {3512rps->evclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].evclk;3513rps->ecclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].ecclk;3514si_get_vce_clock_voltage(adev, rps->evclk, rps->ecclk,3515&min_vce_voltage);3516} else {3517rps->evclk = 0;3518rps->ecclk = 0;3519}35203521if ((adev->pm.pm_display_cfg.num_display > 1) ||3522si_dpm_vblank_too_short(adev))3523disable_mclk_switching = true;35243525if (rps->vclk || rps->dclk) {3526disable_mclk_switching = true;3527disable_sclk_switching = true;3528}35293530if (adev->pm.ac_power)3531max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac;3532else3533max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc;35343535for (i = ps->performance_level_count - 2; i >= 0; i--) {3536if (ps->performance_levels[i].vddc > ps->performance_levels[i+1].vddc)3537ps->performance_levels[i].vddc = ps->performance_levels[i+1].vddc;3538}3539if (adev->pm.ac_power == false) {3540for (i = 0; i < ps->performance_level_count; i++) {3541if (ps->performance_levels[i].mclk > max_limits->mclk)3542ps->performance_levels[i].mclk = max_limits->mclk;3543if (ps->performance_levels[i].sclk > max_limits->sclk)3544ps->performance_levels[i].sclk = max_limits->sclk;3545if (ps->performance_levels[i].vddc > max_limits->vddc)3546ps->performance_levels[i].vddc = max_limits->vddc;3547if (ps->performance_levels[i].vddci > max_limits->vddci)3548ps->performance_levels[i].vddci = max_limits->vddci;3549}3550}35513552/* limit clocks to max supported clocks based on voltage dependency tables */3553btc_get_max_clock_from_voltage_dependency_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,3554&max_sclk_vddc);3555btc_get_max_clock_from_voltage_dependency_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,3556&max_mclk_vddci);3557btc_get_max_clock_from_voltage_dependency_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,3558&max_mclk_vddc);35593560for (i = 0; i < ps->performance_level_count; i++) {3561if (max_sclk_vddc) {3562if (ps->performance_levels[i].sclk > max_sclk_vddc)3563ps->performance_levels[i].sclk = max_sclk_vddc;3564}3565if (max_mclk_vddci) {3566if (ps->performance_levels[i].mclk > max_mclk_vddci)3567ps->performance_levels[i].mclk = max_mclk_vddci;3568}3569if (max_mclk_vddc) {3570if (ps->performance_levels[i].mclk > max_mclk_vddc)3571ps->performance_levels[i].mclk = max_mclk_vddc;3572}3573if (max_mclk) {3574if (ps->performance_levels[i].mclk > max_mclk)3575ps->performance_levels[i].mclk = max_mclk;3576}3577if (max_sclk) {3578if (ps->performance_levels[i].sclk > max_sclk)3579ps->performance_levels[i].sclk = max_sclk;3580}3581}35823583/* XXX validate the min clocks required for display */35843585if (disable_mclk_switching) {3586mclk = ps->performance_levels[ps->performance_level_count - 1].mclk;3587vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;3588} else {3589mclk = ps->performance_levels[0].mclk;3590vddci = ps->performance_levels[0].vddci;3591}35923593if (disable_sclk_switching) {3594sclk = ps->performance_levels[ps->performance_level_count - 1].sclk;3595vddc = ps->performance_levels[ps->performance_level_count - 1].vddc;3596} else {3597sclk = ps->performance_levels[0].sclk;3598vddc = ps->performance_levels[0].vddc;3599}36003601if (rps->vce_active) {3602if (sclk < adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].sclk)3603sclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].sclk;3604if (mclk < adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].mclk)3605mclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].mclk;3606}36073608/* adjusted low state */3609ps->performance_levels[0].sclk = sclk;3610ps->performance_levels[0].mclk = mclk;3611ps->performance_levels[0].vddc = vddc;3612ps->performance_levels[0].vddci = vddci;36133614if (disable_sclk_switching) {3615sclk = ps->performance_levels[0].sclk;3616for (i = 1; i < ps->performance_level_count; i++) {3617if (sclk < ps->performance_levels[i].sclk)3618sclk = ps->performance_levels[i].sclk;3619}3620for (i = 0; i < ps->performance_level_count; i++) {3621ps->performance_levels[i].sclk = sclk;3622ps->performance_levels[i].vddc = vddc;3623}3624} else {3625for (i = 1; i < ps->performance_level_count; i++) {3626if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)3627ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;3628if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)3629ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;3630}3631}36323633if (disable_mclk_switching) {3634mclk = ps->performance_levels[0].mclk;3635for (i = 1; i < ps->performance_level_count; i++) {3636if (mclk < ps->performance_levels[i].mclk)3637mclk = ps->performance_levels[i].mclk;3638}3639for (i = 0; i < ps->performance_level_count; i++) {3640ps->performance_levels[i].mclk = mclk;3641ps->performance_levels[i].vddci = vddci;3642}3643} else {3644for (i = 1; i < ps->performance_level_count; i++) {3645if (ps->performance_levels[i].mclk < ps->performance_levels[i - 1].mclk)3646ps->performance_levels[i].mclk = ps->performance_levels[i - 1].mclk;3647if (ps->performance_levels[i].vddci < ps->performance_levels[i - 1].vddci)3648ps->performance_levels[i].vddci = ps->performance_levels[i - 1].vddci;3649}3650}36513652for (i = 0; i < ps->performance_level_count; i++)3653btc_adjust_clock_combinations(adev, max_limits,3654&ps->performance_levels[i]);36553656for (i = 0; i < ps->performance_level_count; i++) {3657if (ps->performance_levels[i].vddc < min_vce_voltage)3658ps->performance_levels[i].vddc = min_vce_voltage;3659btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,3660ps->performance_levels[i].sclk,3661max_limits->vddc, &ps->performance_levels[i].vddc);3662btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,3663ps->performance_levels[i].mclk,3664max_limits->vddci, &ps->performance_levels[i].vddci);3665btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,3666ps->performance_levels[i].mclk,3667max_limits->vddc, &ps->performance_levels[i].vddc);3668btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,3669display_cfg->display_clk,3670max_limits->vddc, &ps->performance_levels[i].vddc);3671}36723673for (i = 0; i < ps->performance_level_count; i++) {3674btc_apply_voltage_delta_rules(adev,3675max_limits->vddc, max_limits->vddci,3676&ps->performance_levels[i].vddc,3677&ps->performance_levels[i].vddci);3678}36793680ps->dc_compatible = true;3681for (i = 0; i < ps->performance_level_count; i++) {3682if (ps->performance_levels[i].vddc > adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc)3683ps->dc_compatible = false;3684}3685}36863687#if 03688static int si_read_smc_soft_register(struct amdgpu_device *adev,3689u16 reg_offset, u32 *value)3690{3691struct si_power_info *si_pi = si_get_pi(adev);36923693return amdgpu_si_read_smc_sram_dword(adev,3694si_pi->soft_regs_start + reg_offset, value,3695si_pi->sram_end);3696}3697#endif36983699static int si_write_smc_soft_register(struct amdgpu_device *adev,3700u16 reg_offset, u32 value)3701{3702struct si_power_info *si_pi = si_get_pi(adev);37033704return amdgpu_si_write_smc_sram_dword(adev,3705si_pi->soft_regs_start + reg_offset,3706value, si_pi->sram_end);3707}37083709static bool si_is_special_1gb_platform(struct amdgpu_device *adev)3710{3711bool ret = false;3712u32 tmp, width, row, column, bank, density;3713bool is_memory_gddr5, is_special;37143715tmp = RREG32(MC_SEQ_MISC0);3716is_memory_gddr5 = (MC_SEQ_MISC0_GDDR5_VALUE == ((tmp & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT));3717is_special = (MC_SEQ_MISC0_REV_ID_VALUE == ((tmp & MC_SEQ_MISC0_REV_ID_MASK) >> MC_SEQ_MISC0_REV_ID_SHIFT))3718& (MC_SEQ_MISC0_VEN_ID_VALUE == ((tmp & MC_SEQ_MISC0_VEN_ID_MASK) >> MC_SEQ_MISC0_VEN_ID_SHIFT));37193720WREG32(MC_SEQ_IO_DEBUG_INDEX, 0xb);3721width = ((RREG32(MC_SEQ_IO_DEBUG_DATA) >> 1) & 1) ? 16 : 32;37223723tmp = RREG32(mmMC_ARB_RAMCFG);3724row = ((tmp & MC_ARB_RAMCFG__NOOFROWS_MASK) >> MC_ARB_RAMCFG__NOOFROWS__SHIFT) + 10;3725column = ((tmp & MC_ARB_RAMCFG__NOOFCOLS_MASK) >> MC_ARB_RAMCFG__NOOFCOLS__SHIFT) + 8;3726bank = ((tmp & MC_ARB_RAMCFG__NOOFBANK_MASK) >> MC_ARB_RAMCFG__NOOFBANK__SHIFT) + 2;37273728density = (1 << (row + column - 20 + bank)) * width;37293730if ((adev->pdev->device == 0x6819) &&3731is_memory_gddr5 && is_special && (density == 0x400))3732ret = true;37333734return ret;3735}37363737static void si_get_leakage_vddc(struct amdgpu_device *adev)3738{3739struct si_power_info *si_pi = si_get_pi(adev);3740u16 vddc, count = 0;3741int i, ret;37423743for (i = 0; i < SISLANDS_MAX_LEAKAGE_COUNT; i++) {3744ret = amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(adev, &vddc, SISLANDS_LEAKAGE_INDEX0 + i);37453746if (!ret && (vddc > 0) && (vddc != (SISLANDS_LEAKAGE_INDEX0 + i))) {3747si_pi->leakage_voltage.entries[count].voltage = vddc;3748si_pi->leakage_voltage.entries[count].leakage_index =3749SISLANDS_LEAKAGE_INDEX0 + i;3750count++;3751}3752}3753si_pi->leakage_voltage.count = count;3754}37553756static int si_get_leakage_voltage_from_leakage_index(struct amdgpu_device *adev,3757u32 index, u16 *leakage_voltage)3758{3759struct si_power_info *si_pi = si_get_pi(adev);3760int i;37613762if (leakage_voltage == NULL)3763return -EINVAL;37643765if ((index & 0xff00) != 0xff00)3766return -EINVAL;37673768if ((index & 0xff) > SISLANDS_MAX_LEAKAGE_COUNT + 1)3769return -EINVAL;37703771if (index < SISLANDS_LEAKAGE_INDEX0)3772return -EINVAL;37733774for (i = 0; i < si_pi->leakage_voltage.count; i++) {3775if (si_pi->leakage_voltage.entries[i].leakage_index == index) {3776*leakage_voltage = si_pi->leakage_voltage.entries[i].voltage;3777return 0;3778}3779}3780return -EAGAIN;3781}37823783static void si_set_dpm_event_sources(struct amdgpu_device *adev, u32 sources)3784{3785struct rv7xx_power_info *pi = rv770_get_pi(adev);3786bool want_thermal_protection;3787enum si_dpm_event_src dpm_event_src;37883789switch (sources) {3790case 0:3791default:3792want_thermal_protection = false;3793break;3794case (1 << SI_DPM_AUTO_THROTTLE_SRC_THERMAL):3795want_thermal_protection = true;3796dpm_event_src = SI_DPM_EVENT_SRC_DIGITAL;3797break;3798case (1 << SI_DPM_AUTO_THROTTLE_SRC_EXTERNAL):3799want_thermal_protection = true;3800dpm_event_src = SI_DPM_EVENT_SRC_EXTERNAL;3801break;3802case ((1 << SI_DPM_AUTO_THROTTLE_SRC_EXTERNAL) |3803(1 << SI_DPM_AUTO_THROTTLE_SRC_THERMAL)):3804want_thermal_protection = true;3805dpm_event_src = SI_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL;3806break;3807}38083809if (want_thermal_protection) {3810WREG32_P(mmCG_THERMAL_CTRL, dpm_event_src << CG_THERMAL_CTRL__DPM_EVENT_SRC__SHIFT, ~CG_THERMAL_CTRL__DPM_EVENT_SRC_MASK);3811if (pi->thermal_protection)3812WREG32_P(mmGENERAL_PWRMGT, 0, ~GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK);3813} else {3814WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK, ~GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK);3815}3816}38173818static void si_enable_auto_throttle_source(struct amdgpu_device *adev,3819enum si_dpm_auto_throttle_src source,3820bool enable)3821{3822struct rv7xx_power_info *pi = rv770_get_pi(adev);38233824if (enable) {3825if (!(pi->active_auto_throttle_sources & (1 << source))) {3826pi->active_auto_throttle_sources |= 1 << source;3827si_set_dpm_event_sources(adev, pi->active_auto_throttle_sources);3828}3829} else {3830if (pi->active_auto_throttle_sources & (1 << source)) {3831pi->active_auto_throttle_sources &= ~(1 << source);3832si_set_dpm_event_sources(adev, pi->active_auto_throttle_sources);3833}3834}3835}38363837static void si_start_dpm(struct amdgpu_device *adev)3838{3839WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__GLOBAL_PWRMGT_EN_MASK, ~GENERAL_PWRMGT__GLOBAL_PWRMGT_EN_MASK);3840}38413842static void si_stop_dpm(struct amdgpu_device *adev)3843{3844WREG32_P(mmGENERAL_PWRMGT, 0, ~GENERAL_PWRMGT__GLOBAL_PWRMGT_EN_MASK);3845}38463847static void si_enable_sclk_control(struct amdgpu_device *adev, bool enable)3848{3849if (enable)3850WREG32_P(mmSCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_CNTL__SCLK_PWRMGT_OFF_MASK);3851else3852WREG32_P(mmSCLK_PWRMGT_CNTL, SCLK_PWRMGT_CNTL__SCLK_PWRMGT_OFF_MASK, ~SCLK_PWRMGT_CNTL__SCLK_PWRMGT_OFF_MASK);38533854}38553856#if 03857static int si_notify_hardware_of_thermal_state(struct amdgpu_device *adev,3858u32 thermal_level)3859{3860PPSMC_Result ret;38613862if (thermal_level == 0) {3863ret = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableThermalInterrupt);3864if (ret == PPSMC_Result_OK)3865return 0;3866else3867return -EINVAL;3868}3869return 0;3870}38713872static void si_notify_hardware_vpu_recovery_event(struct amdgpu_device *adev)3873{3874si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_tdr_is_about_to_happen, true);3875}3876#endif38773878#if 03879static int si_notify_hw_of_powersource(struct amdgpu_device *adev, bool ac_power)3880{3881if (ac_power)3882return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_RunningOnAC) == PPSMC_Result_OK) ?38830 : -EINVAL;38843885return 0;3886}3887#endif38883889static PPSMC_Result si_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,3890PPSMC_Msg msg, u32 parameter)3891{3892WREG32(mmSMC_SCRATCH0, parameter);3893return amdgpu_si_send_msg_to_smc(adev, msg);3894}38953896static int si_restrict_performance_levels_before_switch(struct amdgpu_device *adev)3897{3898if (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)3899return -EINVAL;39003901return (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, 1) == PPSMC_Result_OK) ?39020 : -EINVAL;3903}39043905static int si_dpm_force_performance_level(void *handle,3906enum amd_dpm_forced_level level)3907{3908struct amdgpu_device *adev = (struct amdgpu_device *)handle;3909struct amdgpu_ps *rps = adev->pm.dpm.current_ps;3910struct si_ps *ps = si_get_ps(rps);3911u32 levels = ps->performance_level_count;39123913if (level == AMD_DPM_FORCED_LEVEL_HIGH) {3914if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK)3915return -EINVAL;39163917if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK)3918return -EINVAL;3919} else if (level == AMD_DPM_FORCED_LEVEL_LOW) {3920if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)3921return -EINVAL;39223923if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK)3924return -EINVAL;3925} else if (level == AMD_DPM_FORCED_LEVEL_AUTO) {3926if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)3927return -EINVAL;39283929if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK)3930return -EINVAL;3931}39323933adev->pm.dpm.forced_level = level;39343935return 0;3936}39373938#if 03939static int si_set_boot_state(struct amdgpu_device *adev)3940{3941return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_SwitchToInitialState) == PPSMC_Result_OK) ?39420 : -EINVAL;3943}3944#endif39453946static int si_set_sw_state(struct amdgpu_device *adev)3947{3948return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_SwitchToSwState) == PPSMC_Result_OK) ?39490 : -EINVAL;3950}39513952static int si_halt_smc(struct amdgpu_device *adev)3953{3954if (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_Halt) != PPSMC_Result_OK)3955return -EINVAL;39563957return (amdgpu_si_wait_for_smc_inactive(adev) == PPSMC_Result_OK) ?39580 : -EINVAL;3959}39603961static int si_resume_smc(struct amdgpu_device *adev)3962{3963if (amdgpu_si_send_msg_to_smc(adev, PPSMC_FlushDataCache) != PPSMC_Result_OK)3964return -EINVAL;39653966return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_Resume) == PPSMC_Result_OK) ?39670 : -EINVAL;3968}39693970static void si_dpm_start_smc(struct amdgpu_device *adev)3971{3972amdgpu_si_program_jump_on_start(adev);3973amdgpu_si_start_smc(adev);3974amdgpu_si_smc_clock(adev, true);3975}39763977static void si_dpm_stop_smc(struct amdgpu_device *adev)3978{3979amdgpu_si_reset_smc(adev);3980amdgpu_si_smc_clock(adev, false);3981}39823983static int si_process_firmware_header(struct amdgpu_device *adev)3984{3985struct si_power_info *si_pi = si_get_pi(adev);3986u32 tmp;3987int ret;39883989ret = amdgpu_si_read_smc_sram_dword(adev,3990SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +3991SISLANDS_SMC_FIRMWARE_HEADER_stateTable,3992&tmp, si_pi->sram_end);3993if (ret)3994return ret;39953996si_pi->state_table_start = tmp;39973998ret = amdgpu_si_read_smc_sram_dword(adev,3999SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4000SISLANDS_SMC_FIRMWARE_HEADER_softRegisters,4001&tmp, si_pi->sram_end);4002if (ret)4003return ret;40044005si_pi->soft_regs_start = tmp;40064007ret = amdgpu_si_read_smc_sram_dword(adev,4008SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4009SISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable,4010&tmp, si_pi->sram_end);4011if (ret)4012return ret;40134014si_pi->mc_reg_table_start = tmp;40154016ret = amdgpu_si_read_smc_sram_dword(adev,4017SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4018SISLANDS_SMC_FIRMWARE_HEADER_fanTable,4019&tmp, si_pi->sram_end);4020if (ret)4021return ret;40224023si_pi->fan_table_start = tmp;40244025ret = amdgpu_si_read_smc_sram_dword(adev,4026SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4027SISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable,4028&tmp, si_pi->sram_end);4029if (ret)4030return ret;40314032si_pi->arb_table_start = tmp;40334034ret = amdgpu_si_read_smc_sram_dword(adev,4035SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4036SISLANDS_SMC_FIRMWARE_HEADER_CacConfigTable,4037&tmp, si_pi->sram_end);4038if (ret)4039return ret;40404041si_pi->cac_table_start = tmp;40424043ret = amdgpu_si_read_smc_sram_dword(adev,4044SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4045SISLANDS_SMC_FIRMWARE_HEADER_DteConfiguration,4046&tmp, si_pi->sram_end);4047if (ret)4048return ret;40494050si_pi->dte_table_start = tmp;40514052ret = amdgpu_si_read_smc_sram_dword(adev,4053SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4054SISLANDS_SMC_FIRMWARE_HEADER_spllTable,4055&tmp, si_pi->sram_end);4056if (ret)4057return ret;40584059si_pi->spll_table_start = tmp;40604061ret = amdgpu_si_read_smc_sram_dword(adev,4062SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4063SISLANDS_SMC_FIRMWARE_HEADER_PAPMParameters,4064&tmp, si_pi->sram_end);4065if (ret)4066return ret;40674068si_pi->papm_cfg_table_start = tmp;40694070return ret;4071}40724073static void si_read_clock_registers(struct amdgpu_device *adev)4074{4075struct si_power_info *si_pi = si_get_pi(adev);40764077si_pi->clock_registers.cg_spll_func_cntl = RREG32(mmCG_SPLL_FUNC_CNTL);4078si_pi->clock_registers.cg_spll_func_cntl_2 = RREG32(mmCG_SPLL_FUNC_CNTL_2);4079si_pi->clock_registers.cg_spll_func_cntl_3 = RREG32(mmCG_SPLL_FUNC_CNTL_3);4080si_pi->clock_registers.cg_spll_func_cntl_4 = RREG32(mmCG_SPLL_FUNC_CNTL_4);4081si_pi->clock_registers.cg_spll_spread_spectrum = RREG32(mmCG_SPLL_SPREAD_SPECTRUM);4082si_pi->clock_registers.cg_spll_spread_spectrum_2 = RREG32(mmCG_SPLL_SPREAD_SPECTRUM_2);4083si_pi->clock_registers.dll_cntl = RREG32(DLL_CNTL);4084si_pi->clock_registers.mclk_pwrmgt_cntl = RREG32(MCLK_PWRMGT_CNTL);4085si_pi->clock_registers.mpll_ad_func_cntl = RREG32(MPLL_AD_FUNC_CNTL);4086si_pi->clock_registers.mpll_dq_func_cntl = RREG32(MPLL_DQ_FUNC_CNTL);4087si_pi->clock_registers.mpll_func_cntl = RREG32(MPLL_FUNC_CNTL);4088si_pi->clock_registers.mpll_func_cntl_1 = RREG32(MPLL_FUNC_CNTL_1);4089si_pi->clock_registers.mpll_func_cntl_2 = RREG32(MPLL_FUNC_CNTL_2);4090si_pi->clock_registers.mpll_ss1 = RREG32(MPLL_SS1);4091si_pi->clock_registers.mpll_ss2 = RREG32(MPLL_SS2);4092}40934094static void si_enable_thermal_protection(struct amdgpu_device *adev,4095bool enable)4096{4097if (enable)4098WREG32_P(mmGENERAL_PWRMGT, 0, ~GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK);4099else4100WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK, ~GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK);4101}41024103static void si_enable_acpi_power_management(struct amdgpu_device *adev)4104{4105WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__STATIC_PM_EN_MASK, ~GENERAL_PWRMGT__STATIC_PM_EN_MASK);4106}41074108#if 04109static int si_enter_ulp_state(struct amdgpu_device *adev)4110{4111WREG32(SMC_MESSAGE_0, PPSMC_MSG_SwitchToMinimumPower);41124113udelay(25000);41144115return 0;4116}41174118static int si_exit_ulp_state(struct amdgpu_device *adev)4119{4120int i;41214122WREG32(SMC_MESSAGE_0, PPSMC_MSG_ResumeFromMinimumPower);41234124udelay(7000);41254126for (i = 0; i < adev->usec_timeout; i++) {4127if (RREG32(SMC_RESP_0) == 1)4128break;4129udelay(1000);4130}41314132return 0;4133}4134#endif41354136static int si_notify_smc_display_change(struct amdgpu_device *adev,4137bool has_display)4138{4139PPSMC_Msg msg = has_display ?4140PPSMC_MSG_HasDisplay : PPSMC_MSG_NoDisplay;41414142return (amdgpu_si_send_msg_to_smc(adev, msg) == PPSMC_Result_OK) ?41430 : -EINVAL;4144}41454146static void si_program_response_times(struct amdgpu_device *adev)4147{4148u32 voltage_response_time, acpi_delay_time, vbi_time_out;4149u32 vddc_dly, acpi_dly, vbi_dly;4150u32 reference_clock;41514152si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_mvdd_chg_time, 1);41534154voltage_response_time = (u32)adev->pm.dpm.voltage_response_time;41554156if (voltage_response_time == 0)4157voltage_response_time = 1000;41584159acpi_delay_time = 15000;4160vbi_time_out = 100000;41614162reference_clock = amdgpu_asic_get_xclk(adev);41634164vddc_dly = (voltage_response_time * reference_clock) / 100;4165acpi_dly = (acpi_delay_time * reference_clock) / 100;4166vbi_dly = (vbi_time_out * reference_clock) / 100;41674168si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_delay_vreg, vddc_dly);4169si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_delay_acpi, acpi_dly);4170si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);4171si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_mc_block_delay, 0xAA);4172}41734174static void si_program_ds_registers(struct amdgpu_device *adev)4175{4176struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);4177u32 tmp;41784179/* DEEP_SLEEP_CLK_SEL field should be 0x10 on tahiti A0 */4180if (adev->asic_type == CHIP_TAHITI && adev->rev_id == 0x0)4181tmp = 0x10;4182else4183tmp = 0x1;41844185if (eg_pi->sclk_deep_sleep) {4186WREG32_P(mmMISC_CLK_CNTL, (tmp << MISC_CLK_CNTL__DEEP_SLEEP_CLK_SEL__SHIFT), ~MISC_CLK_CNTL__DEEP_SLEEP_CLK_SEL_MASK);4187WREG32_P(mmCG_SPLL_AUTOSCALE_CNTL, CG_SPLL_AUTOSCALE_CNTL__AUTOSCALE_ON_SS_CLEAR_MASK,4188~CG_SPLL_AUTOSCALE_CNTL__AUTOSCALE_ON_SS_CLEAR_MASK);4189}4190}41914192static void si_program_display_gap(struct amdgpu_device *adev)4193{4194const struct amd_pp_display_configuration *cfg = &adev->pm.pm_display_cfg;4195u32 tmp, pipe;41964197tmp = RREG32(mmCG_DISPLAY_GAP_CNTL) & ~(CG_DISPLAY_GAP_CNTL__DISP1_GAP_MASK | CG_DISPLAY_GAP_CNTL__DISP2_GAP_MASK);4198if (cfg->num_display > 0)4199tmp |= R600_PM_DISPLAY_GAP_VBLANK_OR_WM << CG_DISPLAY_GAP_CNTL__DISP1_GAP__SHIFT;4200else4201tmp |= R600_PM_DISPLAY_GAP_IGNORE << CG_DISPLAY_GAP_CNTL__DISP1_GAP__SHIFT;42024203if (cfg->num_display > 1)4204tmp |= R600_PM_DISPLAY_GAP_VBLANK_OR_WM << CG_DISPLAY_GAP_CNTL__DISP2_GAP__SHIFT;4205else4206tmp |= R600_PM_DISPLAY_GAP_IGNORE << CG_DISPLAY_GAP_CNTL__DISP2_GAP__SHIFT;42074208WREG32(mmCG_DISPLAY_GAP_CNTL, tmp);42094210tmp = RREG32(DCCG_DISP_SLOW_SELECT_REG);4211pipe = (tmp & DCCG_DISP1_SLOW_SELECT_MASK) >> DCCG_DISP1_SLOW_SELECT_SHIFT;42124213if (cfg->num_display > 0 && pipe != cfg->crtc_index) {4214pipe = cfg->crtc_index;42154216tmp &= ~DCCG_DISP1_SLOW_SELECT_MASK;4217tmp |= DCCG_DISP1_SLOW_SELECT(pipe);4218WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp);4219}42204221/* Setting this to false forces the performance state to low if the crtcs are disabled.4222* This can be a problem on PowerXpress systems or if you want to use the card4223* for offscreen rendering or compute if there are no crtcs enabled.4224*/4225si_notify_smc_display_change(adev, cfg->num_display > 0);4226}42274228static void si_enable_spread_spectrum(struct amdgpu_device *adev, bool enable)4229{4230struct rv7xx_power_info *pi = rv770_get_pi(adev);42314232if (enable) {4233if (pi->sclk_ss)4234WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__DYN_SPREAD_SPECTRUM_EN_MASK, ~GENERAL_PWRMGT__DYN_SPREAD_SPECTRUM_EN_MASK);4235} else {4236WREG32_P(mmCG_SPLL_SPREAD_SPECTRUM, 0, ~CG_SPLL_SPREAD_SPECTRUM__SSEN_MASK);4237WREG32_P(mmGENERAL_PWRMGT, 0, ~GENERAL_PWRMGT__DYN_SPREAD_SPECTRUM_EN_MASK);4238}4239}42404241static void si_setup_bsp(struct amdgpu_device *adev)4242{4243struct rv7xx_power_info *pi = rv770_get_pi(adev);4244u32 xclk = amdgpu_asic_get_xclk(adev);42454246r600_calculate_u_and_p(pi->asi,4247xclk,424816,4249&pi->bsp,4250&pi->bsu);42514252r600_calculate_u_and_p(pi->pasi,4253xclk,425416,4255&pi->pbsp,4256&pi->pbsu);425742584259pi->dsp = (pi->bsp << CG_BSP__BSP__SHIFT) | (pi->bsu << CG_BSP__BSU__SHIFT);4260pi->psp = (pi->pbsp << CG_BSP__BSP__SHIFT) | (pi->pbsu << CG_BSP__BSU__SHIFT);42614262WREG32(mmCG_BSP, pi->dsp);4263}42644265static void si_program_git(struct amdgpu_device *adev)4266{4267WREG32_P(mmCG_GIT, R600_GICST_DFLT << CG_GIT__CG_GICST__SHIFT, ~CG_GIT__CG_GICST_MASK);4268}42694270static void si_program_tp(struct amdgpu_device *adev)4271{4272int i;4273enum r600_td td = R600_TD_DFLT;42744275for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)4276WREG32(mmCG_FFCT_0 + i, (r600_utc[i] << CG_FFCT_0__UTC_0__SHIFT | r600_dtc[i] << CG_FFCT_0__DTC_0__SHIFT));42774278if (td == R600_TD_AUTO)4279WREG32_P(mmSCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_CNTL__FIR_FORCE_TREND_SEL_MASK);4280else4281WREG32_P(mmSCLK_PWRMGT_CNTL, SCLK_PWRMGT_CNTL__FIR_FORCE_TREND_SEL_MASK, ~SCLK_PWRMGT_CNTL__FIR_FORCE_TREND_SEL_MASK);42824283if (td == R600_TD_UP)4284WREG32_P(mmSCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_CNTL__FIR_TREND_MODE_MASK);42854286if (td == R600_TD_DOWN)4287WREG32_P(mmSCLK_PWRMGT_CNTL, SCLK_PWRMGT_CNTL__FIR_TREND_MODE_MASK, ~SCLK_PWRMGT_CNTL__FIR_TREND_MODE_MASK);4288}42894290static void si_program_tpp(struct amdgpu_device *adev)4291{4292WREG32(mmCG_TPC, R600_TPC_DFLT);4293}42944295static void si_program_sstp(struct amdgpu_device *adev)4296{4297WREG32(mmCG_SSP, (R600_SSTU_DFLT << CG_SSP__SSTU__SHIFT| R600_SST_DFLT << CG_SSP__SST__SHIFT));4298}42994300static void si_enable_display_gap(struct amdgpu_device *adev)4301{4302u32 tmp = RREG32(mmCG_DISPLAY_GAP_CNTL);43034304tmp &= ~(CG_DISPLAY_GAP_CNTL__DISP1_GAP_MASK | CG_DISPLAY_GAP_CNTL__DISP2_GAP_MASK);4305tmp |= (R600_PM_DISPLAY_GAP_IGNORE << CG_DISPLAY_GAP_CNTL__DISP1_GAP__SHIFT |4306R600_PM_DISPLAY_GAP_IGNORE << CG_DISPLAY_GAP_CNTL__DISP2_GAP__SHIFT);43074308tmp &= ~(CG_DISPLAY_GAP_CNTL__DISP1_GAP_MCHG_MASK | CG_DISPLAY_GAP_CNTL__DISP2_GAP_MCHG_MASK);4309tmp |= (R600_PM_DISPLAY_GAP_VBLANK << CG_DISPLAY_GAP_CNTL__DISP1_GAP_MCHG__SHIFT |4310R600_PM_DISPLAY_GAP_IGNORE << CG_DISPLAY_GAP_CNTL__DISP2_GAP_MCHG__SHIFT);4311WREG32(mmCG_DISPLAY_GAP_CNTL, tmp);4312}43134314static void si_program_vc(struct amdgpu_device *adev)4315{4316struct rv7xx_power_info *pi = rv770_get_pi(adev);43174318WREG32(mmCG_FTV, pi->vrc);4319}43204321static void si_clear_vc(struct amdgpu_device *adev)4322{4323WREG32(mmCG_FTV, 0);4324}43254326static u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock)4327{4328u8 mc_para_index;43294330if (memory_clock < 10000)4331mc_para_index = 0;4332else if (memory_clock >= 80000)4333mc_para_index = 0x0f;4334else4335mc_para_index = (u8)((memory_clock - 10000) / 5000 + 1);4336return mc_para_index;4337}43384339static u8 si_get_mclk_frequency_ratio(u32 memory_clock, bool strobe_mode)4340{4341u8 mc_para_index;43424343if (strobe_mode) {4344if (memory_clock < 12500)4345mc_para_index = 0x00;4346else if (memory_clock > 47500)4347mc_para_index = 0x0f;4348else4349mc_para_index = (u8)((memory_clock - 10000) / 2500);4350} else {4351if (memory_clock < 65000)4352mc_para_index = 0x00;4353else if (memory_clock > 135000)4354mc_para_index = 0x0f;4355else4356mc_para_index = (u8)((memory_clock - 60000) / 5000);4357}4358return mc_para_index;4359}43604361static u8 si_get_strobe_mode_settings(struct amdgpu_device *adev, u32 mclk)4362{4363struct rv7xx_power_info *pi = rv770_get_pi(adev);4364bool strobe_mode = false;4365u8 result = 0;43664367if (mclk <= pi->mclk_strobe_mode_threshold)4368strobe_mode = true;43694370if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5)4371result = si_get_mclk_frequency_ratio(mclk, strobe_mode);4372else4373result = si_get_ddr3_mclk_frequency_ratio(mclk);43744375if (strobe_mode)4376result |= SISLANDS_SMC_STROBE_ENABLE;43774378return result;4379}43804381static int si_upload_firmware(struct amdgpu_device *adev)4382{4383struct si_power_info *si_pi = si_get_pi(adev);43844385amdgpu_si_reset_smc(adev);4386amdgpu_si_smc_clock(adev, false);43874388return amdgpu_si_load_smc_ucode(adev, si_pi->sram_end);4389}43904391static bool si_validate_phase_shedding_tables(struct amdgpu_device *adev,4392const struct atom_voltage_table *table,4393const struct amdgpu_phase_shedding_limits_table *limits)4394{4395u32 data, num_bits, num_levels;43964397if ((table == NULL) || (limits == NULL))4398return false;43994400data = table->mask_low;44014402num_bits = hweight32(data);44034404if (num_bits == 0)4405return false;44064407num_levels = (1 << num_bits);44084409if (table->count != num_levels)4410return false;44114412if (limits->count != (num_levels - 1))4413return false;44144415return true;4416}44174418static void si_trim_voltage_table_to_fit_state_table(struct amdgpu_device *adev,4419u32 max_voltage_steps,4420struct atom_voltage_table *voltage_table)4421{4422unsigned int i, diff;44234424if (voltage_table->count <= max_voltage_steps)4425return;44264427diff = voltage_table->count - max_voltage_steps;44284429for (i= 0; i < max_voltage_steps; i++)4430voltage_table->entries[i] = voltage_table->entries[i + diff];44314432voltage_table->count = max_voltage_steps;4433}44344435static int si_get_svi2_voltage_table(struct amdgpu_device *adev,4436struct amdgpu_clock_voltage_dependency_table *voltage_dependency_table,4437struct atom_voltage_table *voltage_table)4438{4439u32 i;44404441if (voltage_dependency_table == NULL)4442return -EINVAL;44434444voltage_table->mask_low = 0;4445voltage_table->phase_delay = 0;44464447voltage_table->count = voltage_dependency_table->count;4448for (i = 0; i < voltage_table->count; i++) {4449voltage_table->entries[i].value = voltage_dependency_table->entries[i].v;4450voltage_table->entries[i].smio_low = 0;4451}44524453return 0;4454}44554456static int si_construct_voltage_tables(struct amdgpu_device *adev)4457{4458struct rv7xx_power_info *pi = rv770_get_pi(adev);4459struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);4460struct si_power_info *si_pi = si_get_pi(adev);4461int ret;44624463if (pi->voltage_control) {4464ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_VDDC,4465VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddc_voltage_table);4466if (ret)4467return ret;44684469if (eg_pi->vddc_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)4470si_trim_voltage_table_to_fit_state_table(adev,4471SISLANDS_MAX_NO_VREG_STEPS,4472&eg_pi->vddc_voltage_table);4473} else if (si_pi->voltage_control_svi2) {4474ret = si_get_svi2_voltage_table(adev,4475&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,4476&eg_pi->vddc_voltage_table);4477if (ret)4478return ret;4479} else {4480return -EINVAL;4481}44824483if (eg_pi->vddci_control) {4484ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_VDDCI,4485VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddci_voltage_table);4486if (ret)4487return ret;44884489if (eg_pi->vddci_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)4490si_trim_voltage_table_to_fit_state_table(adev,4491SISLANDS_MAX_NO_VREG_STEPS,4492&eg_pi->vddci_voltage_table);4493}4494if (si_pi->vddci_control_svi2) {4495ret = si_get_svi2_voltage_table(adev,4496&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,4497&eg_pi->vddci_voltage_table);4498if (ret)4499return ret;4500}45014502if (pi->mvdd_control) {4503ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_MVDDC,4504VOLTAGE_OBJ_GPIO_LUT, &si_pi->mvdd_voltage_table);45054506if (ret) {4507pi->mvdd_control = false;4508return ret;4509}45104511if (si_pi->mvdd_voltage_table.count == 0) {4512pi->mvdd_control = false;4513return -EINVAL;4514}45154516if (si_pi->mvdd_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)4517si_trim_voltage_table_to_fit_state_table(adev,4518SISLANDS_MAX_NO_VREG_STEPS,4519&si_pi->mvdd_voltage_table);4520}45214522if (si_pi->vddc_phase_shed_control) {4523ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_VDDC,4524VOLTAGE_OBJ_PHASE_LUT, &si_pi->vddc_phase_shed_table);4525if (ret)4526si_pi->vddc_phase_shed_control = false;45274528if ((si_pi->vddc_phase_shed_table.count == 0) ||4529(si_pi->vddc_phase_shed_table.count > SISLANDS_MAX_NO_VREG_STEPS))4530si_pi->vddc_phase_shed_control = false;4531}45324533return 0;4534}45354536static void si_populate_smc_voltage_table(struct amdgpu_device *adev,4537const struct atom_voltage_table *voltage_table,4538SISLANDS_SMC_STATETABLE *table)4539{4540unsigned int i;45414542for (i = 0; i < voltage_table->count; i++)4543table->lowSMIO[i] |= cpu_to_be32(voltage_table->entries[i].smio_low);4544}45454546static int si_populate_smc_voltage_tables(struct amdgpu_device *adev,4547SISLANDS_SMC_STATETABLE *table)4548{4549struct rv7xx_power_info *pi = rv770_get_pi(adev);4550struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);4551struct si_power_info *si_pi = si_get_pi(adev);4552u8 i;45534554if (si_pi->voltage_control_svi2) {4555si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc,4556si_pi->svc_gpio_id);4557si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd,4558si_pi->svd_gpio_id);4559si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_svi_rework_plat_type,45602);4561} else {4562if (eg_pi->vddc_voltage_table.count) {4563si_populate_smc_voltage_table(adev, &eg_pi->vddc_voltage_table, table);4564table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =4565cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);45664567for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {4568if (pi->max_vddc_in_table <= eg_pi->vddc_voltage_table.entries[i].value) {4569table->maxVDDCIndexInPPTable = i;4570break;4571}4572}4573}45744575if (eg_pi->vddci_voltage_table.count) {4576si_populate_smc_voltage_table(adev, &eg_pi->vddci_voltage_table, table);45774578table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDCI] =4579cpu_to_be32(eg_pi->vddci_voltage_table.mask_low);4580}458145824583if (si_pi->mvdd_voltage_table.count) {4584si_populate_smc_voltage_table(adev, &si_pi->mvdd_voltage_table, table);45854586table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_MVDD] =4587cpu_to_be32(si_pi->mvdd_voltage_table.mask_low);4588}45894590if (si_pi->vddc_phase_shed_control) {4591if (si_validate_phase_shedding_tables(adev, &si_pi->vddc_phase_shed_table,4592&adev->pm.dpm.dyn_state.phase_shedding_limits_table)) {4593si_populate_smc_voltage_table(adev, &si_pi->vddc_phase_shed_table, table);45944595table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] =4596cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low);45974598si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_phase_shedding_delay,4599(u32)si_pi->vddc_phase_shed_table.phase_delay);4600} else {4601si_pi->vddc_phase_shed_control = false;4602}4603}4604}46054606return 0;4607}46084609static int si_populate_voltage_value(struct amdgpu_device *adev,4610const struct atom_voltage_table *table,4611u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage)4612{4613unsigned int i;46144615for (i = 0; i < table->count; i++) {4616if (value <= table->entries[i].value) {4617voltage->index = (u8)i;4618voltage->value = cpu_to_be16(table->entries[i].value);4619break;4620}4621}46224623if (i >= table->count)4624return -EINVAL;46254626return 0;4627}46284629static int si_populate_mvdd_value(struct amdgpu_device *adev, u32 mclk,4630SISLANDS_SMC_VOLTAGE_VALUE *voltage)4631{4632struct rv7xx_power_info *pi = rv770_get_pi(adev);4633struct si_power_info *si_pi = si_get_pi(adev);46344635if (pi->mvdd_control) {4636if (mclk <= pi->mvdd_split_frequency)4637voltage->index = 0;4638else4639voltage->index = (u8)(si_pi->mvdd_voltage_table.count) - 1;46404641voltage->value = cpu_to_be16(si_pi->mvdd_voltage_table.entries[voltage->index].value);4642}4643return 0;4644}46454646static int si_get_std_voltage_value(struct amdgpu_device *adev,4647SISLANDS_SMC_VOLTAGE_VALUE *voltage,4648u16 *std_voltage)4649{4650u16 v_index;4651bool voltage_found = false;4652*std_voltage = be16_to_cpu(voltage->value);46534654if (adev->pm.dpm.dyn_state.cac_leakage_table.entries) {4655if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_NEW_CAC_VOLTAGE) {4656if (adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries == NULL)4657return -EINVAL;46584659for (v_index = 0; (u32)v_index < adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; v_index++) {4660if (be16_to_cpu(voltage->value) ==4661(u16)adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[v_index].v) {4662voltage_found = true;4663if ((u32)v_index < adev->pm.dpm.dyn_state.cac_leakage_table.count)4664*std_voltage =4665adev->pm.dpm.dyn_state.cac_leakage_table.entries[v_index].vddc;4666else4667*std_voltage =4668adev->pm.dpm.dyn_state.cac_leakage_table.entries[adev->pm.dpm.dyn_state.cac_leakage_table.count-1].vddc;4669break;4670}4671}46724673if (!voltage_found) {4674for (v_index = 0; (u32)v_index < adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; v_index++) {4675if (be16_to_cpu(voltage->value) <=4676(u16)adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[v_index].v) {4677voltage_found = true;4678if ((u32)v_index < adev->pm.dpm.dyn_state.cac_leakage_table.count)4679*std_voltage =4680adev->pm.dpm.dyn_state.cac_leakage_table.entries[v_index].vddc;4681else4682*std_voltage =4683adev->pm.dpm.dyn_state.cac_leakage_table.entries[adev->pm.dpm.dyn_state.cac_leakage_table.count-1].vddc;4684break;4685}4686}4687}4688} else {4689if ((u32)voltage->index < adev->pm.dpm.dyn_state.cac_leakage_table.count)4690*std_voltage = adev->pm.dpm.dyn_state.cac_leakage_table.entries[voltage->index].vddc;4691}4692}46934694return 0;4695}46964697static int si_populate_std_voltage_value(struct amdgpu_device *adev,4698u16 value, u8 index,4699SISLANDS_SMC_VOLTAGE_VALUE *voltage)4700{4701voltage->index = index;4702voltage->value = cpu_to_be16(value);47034704return 0;4705}47064707static int si_populate_phase_shedding_value(struct amdgpu_device *adev,4708const struct amdgpu_phase_shedding_limits_table *limits,4709u16 voltage, u32 sclk, u32 mclk,4710SISLANDS_SMC_VOLTAGE_VALUE *smc_voltage)4711{4712unsigned int i;47134714for (i = 0; i < limits->count; i++) {4715if ((voltage <= limits->entries[i].voltage) &&4716(sclk <= limits->entries[i].sclk) &&4717(mclk <= limits->entries[i].mclk))4718break;4719}47204721smc_voltage->phase_settings = (u8)i;47224723return 0;4724}47254726static int si_init_arb_table_index(struct amdgpu_device *adev)4727{4728struct si_power_info *si_pi = si_get_pi(adev);4729u32 tmp;4730int ret;47314732ret = amdgpu_si_read_smc_sram_dword(adev, si_pi->arb_table_start,4733&tmp, si_pi->sram_end);4734if (ret)4735return ret;47364737tmp &= 0x00FFFFFF;4738tmp |= MC_CG_ARB_FREQ_F1 << 24;47394740return amdgpu_si_write_smc_sram_dword(adev, si_pi->arb_table_start,4741tmp, si_pi->sram_end);4742}47434744static int si_initial_switch_from_arb_f0_to_f1(struct amdgpu_device *adev)4745{4746return ni_copy_and_switch_arb_sets(adev, MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);4747}47484749static int si_reset_to_default(struct amdgpu_device *adev)4750{4751return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_ResetToDefaults) == PPSMC_Result_OK) ?47520 : -EINVAL;4753}47544755static int si_force_switch_to_arb_f0(struct amdgpu_device *adev)4756{4757struct si_power_info *si_pi = si_get_pi(adev);4758u32 tmp;4759int ret;47604761ret = amdgpu_si_read_smc_sram_dword(adev, si_pi->arb_table_start,4762&tmp, si_pi->sram_end);4763if (ret)4764return ret;47654766tmp = (tmp >> 24) & 0xff;47674768if (tmp == MC_CG_ARB_FREQ_F0)4769return 0;47704771return ni_copy_and_switch_arb_sets(adev, tmp, MC_CG_ARB_FREQ_F0);4772}47734774static u32 si_calculate_memory_refresh_rate(struct amdgpu_device *adev,4775u32 engine_clock)4776{4777u32 dram_rows;4778u32 dram_refresh_rate;4779u32 mc_arb_rfsh_rate;4780u32 tmp = (RREG32(mmMC_ARB_RAMCFG) & MC_ARB_RAMCFG__NOOFROWS_MASK) >> MC_ARB_RAMCFG__NOOFROWS__SHIFT;47814782if (tmp >= 4)4783dram_rows = 16384;4784else4785dram_rows = 1 << (tmp + 10);47864787dram_refresh_rate = 1 << ((RREG32(MC_SEQ_MISC0) & 0x3) + 3);4788mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64;47894790return mc_arb_rfsh_rate;4791}47924793static int si_populate_memory_timing_parameters(struct amdgpu_device *adev,4794struct rv7xx_pl *pl,4795SMC_SIslands_MCArbDramTimingRegisterSet *arb_regs)4796{4797u32 dram_timing;4798u32 dram_timing2;4799u32 burst_time;4800int ret;48014802arb_regs->mc_arb_rfsh_rate =4803(u8)si_calculate_memory_refresh_rate(adev, pl->sclk);48044805ret = amdgpu_atombios_set_engine_dram_timings(adev, pl->sclk,4806pl->mclk);4807if (ret)4808return ret;48094810dram_timing = RREG32(MC_ARB_DRAM_TIMING);4811dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);4812burst_time = RREG32(MC_ARB_BURST_TIME) & STATE0_MASK;48134814arb_regs->mc_arb_dram_timing = cpu_to_be32(dram_timing);4815arb_regs->mc_arb_dram_timing2 = cpu_to_be32(dram_timing2);4816arb_regs->mc_arb_burst_time = (u8)burst_time;48174818return 0;4819}48204821static int si_do_program_memory_timing_parameters(struct amdgpu_device *adev,4822struct amdgpu_ps *amdgpu_state,4823unsigned int first_arb_set)4824{4825struct si_power_info *si_pi = si_get_pi(adev);4826struct si_ps *state = si_get_ps(amdgpu_state);4827SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };4828int i, ret = 0;48294830for (i = 0; i < state->performance_level_count; i++) {4831ret = si_populate_memory_timing_parameters(adev, &state->performance_levels[i], &arb_regs);4832if (ret)4833break;4834ret = amdgpu_si_copy_bytes_to_smc(adev,4835si_pi->arb_table_start +4836offsetof(SMC_SIslands_MCArbDramTimingRegisters, data) +4837sizeof(SMC_SIslands_MCArbDramTimingRegisterSet) * (first_arb_set + i),4838(u8 *)&arb_regs,4839sizeof(SMC_SIslands_MCArbDramTimingRegisterSet),4840si_pi->sram_end);4841if (ret)4842break;4843}48444845return ret;4846}48474848static int si_program_memory_timing_parameters(struct amdgpu_device *adev,4849struct amdgpu_ps *amdgpu_new_state)4850{4851return si_do_program_memory_timing_parameters(adev, amdgpu_new_state,4852SISLANDS_DRIVER_STATE_ARB_INDEX);4853}48544855static int si_populate_initial_mvdd_value(struct amdgpu_device *adev,4856struct SISLANDS_SMC_VOLTAGE_VALUE *voltage)4857{4858struct rv7xx_power_info *pi = rv770_get_pi(adev);4859struct si_power_info *si_pi = si_get_pi(adev);48604861if (pi->mvdd_control)4862return si_populate_voltage_value(adev, &si_pi->mvdd_voltage_table,4863si_pi->mvdd_bootup_value, voltage);48644865return 0;4866}48674868static int si_populate_smc_initial_state(struct amdgpu_device *adev,4869struct amdgpu_ps *amdgpu_initial_state,4870SISLANDS_SMC_STATETABLE *table)4871{4872struct si_ps *initial_state = si_get_ps(amdgpu_initial_state);4873struct rv7xx_power_info *pi = rv770_get_pi(adev);4874struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);4875struct si_power_info *si_pi = si_get_pi(adev);4876u32 reg;4877int ret;48784879table->initialState.level.mclk.vDLL_CNTL =4880cpu_to_be32(si_pi->clock_registers.dll_cntl);4881table->initialState.level.mclk.vMCLK_PWRMGT_CNTL =4882cpu_to_be32(si_pi->clock_registers.mclk_pwrmgt_cntl);4883table->initialState.level.mclk.vMPLL_AD_FUNC_CNTL =4884cpu_to_be32(si_pi->clock_registers.mpll_ad_func_cntl);4885table->initialState.level.mclk.vMPLL_DQ_FUNC_CNTL =4886cpu_to_be32(si_pi->clock_registers.mpll_dq_func_cntl);4887table->initialState.level.mclk.vMPLL_FUNC_CNTL =4888cpu_to_be32(si_pi->clock_registers.mpll_func_cntl);4889table->initialState.level.mclk.vMPLL_FUNC_CNTL_1 =4890cpu_to_be32(si_pi->clock_registers.mpll_func_cntl_1);4891table->initialState.level.mclk.vMPLL_FUNC_CNTL_2 =4892cpu_to_be32(si_pi->clock_registers.mpll_func_cntl_2);4893table->initialState.level.mclk.vMPLL_SS =4894cpu_to_be32(si_pi->clock_registers.mpll_ss1);4895table->initialState.level.mclk.vMPLL_SS2 =4896cpu_to_be32(si_pi->clock_registers.mpll_ss2);48974898table->initialState.level.mclk.mclk_value =4899cpu_to_be32(initial_state->performance_levels[0].mclk);49004901table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL =4902cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl);4903table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_2 =4904cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_2);4905table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_3 =4906cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_3);4907table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_4 =4908cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_4);4909table->initialState.level.sclk.vCG_SPLL_SPREAD_SPECTRUM =4910cpu_to_be32(si_pi->clock_registers.cg_spll_spread_spectrum);4911table->initialState.level.sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =4912cpu_to_be32(si_pi->clock_registers.cg_spll_spread_spectrum_2);49134914table->initialState.level.sclk.sclk_value =4915cpu_to_be32(initial_state->performance_levels[0].sclk);49164917table->initialState.level.arbRefreshState =4918SISLANDS_INITIAL_STATE_ARB_INDEX;49194920table->initialState.level.ACIndex = 0;49214922ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,4923initial_state->performance_levels[0].vddc,4924&table->initialState.level.vddc);49254926if (!ret) {4927u16 std_vddc;49284929ret = si_get_std_voltage_value(adev,4930&table->initialState.level.vddc,4931&std_vddc);4932if (!ret)4933si_populate_std_voltage_value(adev, std_vddc,4934table->initialState.level.vddc.index,4935&table->initialState.level.std_vddc);4936}49374938if (eg_pi->vddci_control)4939si_populate_voltage_value(adev,4940&eg_pi->vddci_voltage_table,4941initial_state->performance_levels[0].vddci,4942&table->initialState.level.vddci);49434944if (si_pi->vddc_phase_shed_control)4945si_populate_phase_shedding_value(adev,4946&adev->pm.dpm.dyn_state.phase_shedding_limits_table,4947initial_state->performance_levels[0].vddc,4948initial_state->performance_levels[0].sclk,4949initial_state->performance_levels[0].mclk,4950&table->initialState.level.vddc);49514952si_populate_initial_mvdd_value(adev, &table->initialState.level.mvdd);49534954reg = 0xffff << CG_AT__CG_R__SHIFT | 0 << CG_AT__CG_L__SHIFT;4955table->initialState.level.aT = cpu_to_be32(reg);4956table->initialState.level.bSP = cpu_to_be32(pi->dsp);4957table->initialState.level.gen2PCIE = (u8)si_pi->boot_pcie_gen;49584959if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5) {4960table->initialState.level.strobeMode =4961si_get_strobe_mode_settings(adev,4962initial_state->performance_levels[0].mclk);49634964if (initial_state->performance_levels[0].mclk > pi->mclk_edc_enable_threshold)4965table->initialState.level.mcFlags = SISLANDS_SMC_MC_EDC_RD_FLAG | SISLANDS_SMC_MC_EDC_WR_FLAG;4966else4967table->initialState.level.mcFlags = 0;4968}49694970table->initialState.levelCount = 1;49714972table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;49734974table->initialState.level.dpm2.MaxPS = 0;4975table->initialState.level.dpm2.NearTDPDec = 0;4976table->initialState.level.dpm2.AboveSafeInc = 0;4977table->initialState.level.dpm2.BelowSafeInc = 0;4978table->initialState.level.dpm2.PwrEfficiencyRatio = 0;49794980reg = SQ_POWER_THROTTLE__MIN_POWER_MASK |4981SQ_POWER_THROTTLE__MAX_POWER_MASK;4982table->initialState.level.SQPowerThrottle = cpu_to_be32(reg);49834984reg = SQ_POWER_THROTTLE2__MAX_POWER_DELTA_MASK |4985SQ_POWER_THROTTLE2__SHORT_TERM_INTERVAL_SIZE_MASK |4986SQ_POWER_THROTTLE2__LONG_TERM_INTERVAL_RATIO_MASK;4987table->initialState.level.SQPowerThrottle_2 = cpu_to_be32(reg);49884989return 0;4990}49914992static enum si_pcie_gen si_gen_pcie_gen_support(struct amdgpu_device *adev,4993u32 sys_mask,4994enum si_pcie_gen asic_gen,4995enum si_pcie_gen default_gen)4996{4997switch (asic_gen) {4998case SI_PCIE_GEN1:4999return SI_PCIE_GEN1;5000case SI_PCIE_GEN2:5001return SI_PCIE_GEN2;5002case SI_PCIE_GEN3:5003return SI_PCIE_GEN3;5004default:5005if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) &&5006(default_gen == SI_PCIE_GEN3))5007return SI_PCIE_GEN3;5008else if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) &&5009(default_gen == SI_PCIE_GEN2))5010return SI_PCIE_GEN2;5011else5012return SI_PCIE_GEN1;5013}5014return SI_PCIE_GEN1;5015}50165017static int si_populate_smc_acpi_state(struct amdgpu_device *adev,5018SISLANDS_SMC_STATETABLE *table)5019{5020struct rv7xx_power_info *pi = rv770_get_pi(adev);5021struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);5022struct si_power_info *si_pi = si_get_pi(adev);5023u32 spll_func_cntl = si_pi->clock_registers.cg_spll_func_cntl;5024u32 spll_func_cntl_2 = si_pi->clock_registers.cg_spll_func_cntl_2;5025u32 spll_func_cntl_3 = si_pi->clock_registers.cg_spll_func_cntl_3;5026u32 spll_func_cntl_4 = si_pi->clock_registers.cg_spll_func_cntl_4;5027u32 dll_cntl = si_pi->clock_registers.dll_cntl;5028u32 mclk_pwrmgt_cntl = si_pi->clock_registers.mclk_pwrmgt_cntl;5029u32 mpll_ad_func_cntl = si_pi->clock_registers.mpll_ad_func_cntl;5030u32 mpll_dq_func_cntl = si_pi->clock_registers.mpll_dq_func_cntl;5031u32 mpll_func_cntl = si_pi->clock_registers.mpll_func_cntl;5032u32 mpll_func_cntl_1 = si_pi->clock_registers.mpll_func_cntl_1;5033u32 mpll_func_cntl_2 = si_pi->clock_registers.mpll_func_cntl_2;5034u32 reg;5035int ret;50365037table->ACPIState = table->initialState;50385039table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;50405041if (pi->acpi_vddc) {5042ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,5043pi->acpi_vddc, &table->ACPIState.level.vddc);5044if (!ret) {5045u16 std_vddc;50465047ret = si_get_std_voltage_value(adev,5048&table->ACPIState.level.vddc, &std_vddc);5049if (!ret)5050si_populate_std_voltage_value(adev, std_vddc,5051table->ACPIState.level.vddc.index,5052&table->ACPIState.level.std_vddc);5053}5054table->ACPIState.level.gen2PCIE = si_pi->acpi_pcie_gen;50555056if (si_pi->vddc_phase_shed_control) {5057si_populate_phase_shedding_value(adev,5058&adev->pm.dpm.dyn_state.phase_shedding_limits_table,5059pi->acpi_vddc,50600,50610,5062&table->ACPIState.level.vddc);5063}5064} else {5065ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,5066pi->min_vddc_in_table, &table->ACPIState.level.vddc);5067if (!ret) {5068u16 std_vddc;50695070ret = si_get_std_voltage_value(adev,5071&table->ACPIState.level.vddc, &std_vddc);50725073if (!ret)5074si_populate_std_voltage_value(adev, std_vddc,5075table->ACPIState.level.vddc.index,5076&table->ACPIState.level.std_vddc);5077}5078table->ACPIState.level.gen2PCIE =5079(u8)si_gen_pcie_gen_support(adev,5080si_pi->sys_pcie_mask,5081si_pi->boot_pcie_gen,5082SI_PCIE_GEN1);50835084if (si_pi->vddc_phase_shed_control)5085si_populate_phase_shedding_value(adev,5086&adev->pm.dpm.dyn_state.phase_shedding_limits_table,5087pi->min_vddc_in_table,50880,50890,5090&table->ACPIState.level.vddc);5091}50925093if (pi->acpi_vddc) {5094if (eg_pi->acpi_vddci)5095si_populate_voltage_value(adev, &eg_pi->vddci_voltage_table,5096eg_pi->acpi_vddci,5097&table->ACPIState.level.vddci);5098}50995100mclk_pwrmgt_cntl |= MRDCK0_RESET | MRDCK1_RESET;5101mclk_pwrmgt_cntl &= ~(MRDCK0_PDNB | MRDCK1_PDNB);51025103dll_cntl &= ~(MRDCK0_BYPASS | MRDCK1_BYPASS);51045105spll_func_cntl_2 &= ~CG_SPLL_FUNC_CNTL_2__SCLK_MUX_SEL_MASK;5106spll_func_cntl_2 |= 4 << CG_SPLL_FUNC_CNTL_2__SCLK_MUX_SEL__SHIFT;51075108table->ACPIState.level.mclk.vDLL_CNTL =5109cpu_to_be32(dll_cntl);5110table->ACPIState.level.mclk.vMCLK_PWRMGT_CNTL =5111cpu_to_be32(mclk_pwrmgt_cntl);5112table->ACPIState.level.mclk.vMPLL_AD_FUNC_CNTL =5113cpu_to_be32(mpll_ad_func_cntl);5114table->ACPIState.level.mclk.vMPLL_DQ_FUNC_CNTL =5115cpu_to_be32(mpll_dq_func_cntl);5116table->ACPIState.level.mclk.vMPLL_FUNC_CNTL =5117cpu_to_be32(mpll_func_cntl);5118table->ACPIState.level.mclk.vMPLL_FUNC_CNTL_1 =5119cpu_to_be32(mpll_func_cntl_1);5120table->ACPIState.level.mclk.vMPLL_FUNC_CNTL_2 =5121cpu_to_be32(mpll_func_cntl_2);5122table->ACPIState.level.mclk.vMPLL_SS =5123cpu_to_be32(si_pi->clock_registers.mpll_ss1);5124table->ACPIState.level.mclk.vMPLL_SS2 =5125cpu_to_be32(si_pi->clock_registers.mpll_ss2);51265127table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL =5128cpu_to_be32(spll_func_cntl);5129table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_2 =5130cpu_to_be32(spll_func_cntl_2);5131table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_3 =5132cpu_to_be32(spll_func_cntl_3);5133table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_4 =5134cpu_to_be32(spll_func_cntl_4);51355136table->ACPIState.level.mclk.mclk_value = 0;5137table->ACPIState.level.sclk.sclk_value = 0;51385139si_populate_mvdd_value(adev, 0, &table->ACPIState.level.mvdd);51405141if (eg_pi->dynamic_ac_timing)5142table->ACPIState.level.ACIndex = 0;51435144table->ACPIState.level.dpm2.MaxPS = 0;5145table->ACPIState.level.dpm2.NearTDPDec = 0;5146table->ACPIState.level.dpm2.AboveSafeInc = 0;5147table->ACPIState.level.dpm2.BelowSafeInc = 0;5148table->ACPIState.level.dpm2.PwrEfficiencyRatio = 0;51495150reg = SQ_POWER_THROTTLE__MIN_POWER_MASK | SQ_POWER_THROTTLE__MAX_POWER_MASK;5151table->ACPIState.level.SQPowerThrottle = cpu_to_be32(reg);51525153reg = SQ_POWER_THROTTLE2__MAX_POWER_DELTA_MASK | SQ_POWER_THROTTLE2__SHORT_TERM_INTERVAL_SIZE_MASK | SQ_POWER_THROTTLE2__LONG_TERM_INTERVAL_RATIO_MASK;5154table->ACPIState.level.SQPowerThrottle_2 = cpu_to_be32(reg);51555156return 0;5157}51585159static int si_populate_ulv_state(struct amdgpu_device *adev,5160struct SISLANDS_SMC_SWSTATE_SINGLE *state)5161{5162struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);5163struct si_power_info *si_pi = si_get_pi(adev);5164struct si_ulv_param *ulv = &si_pi->ulv;5165u32 sclk_in_sr = 1350; /* ??? */5166int ret;51675168ret = si_convert_power_level_to_smc(adev, &ulv->pl,5169&state->level);5170if (!ret) {5171if (eg_pi->sclk_deep_sleep) {5172if (sclk_in_sr <= SCLK_MIN_DEEPSLEEP_FREQ)5173state->level.stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_BYPASS;5174else5175state->level.stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE;5176}5177if (ulv->one_pcie_lane_in_ulv)5178state->flags |= PPSMC_SWSTATE_FLAG_PCIE_X1;5179state->level.arbRefreshState = (u8)(SISLANDS_ULV_STATE_ARB_INDEX);5180state->level.ACIndex = 1;5181state->level.std_vddc = state->level.vddc;5182state->levelCount = 1;51835184state->flags |= PPSMC_SWSTATE_FLAG_DC;5185}51865187return ret;5188}51895190static int si_program_ulv_memory_timing_parameters(struct amdgpu_device *adev)5191{5192struct si_power_info *si_pi = si_get_pi(adev);5193struct si_ulv_param *ulv = &si_pi->ulv;5194SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };5195int ret;51965197ret = si_populate_memory_timing_parameters(adev, &ulv->pl,5198&arb_regs);5199if (ret)5200return ret;52015202si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_ulv_volt_change_delay,5203ulv->volt_change_delay);52045205ret = amdgpu_si_copy_bytes_to_smc(adev,5206si_pi->arb_table_start +5207offsetof(SMC_SIslands_MCArbDramTimingRegisters, data) +5208sizeof(SMC_SIslands_MCArbDramTimingRegisterSet) * SISLANDS_ULV_STATE_ARB_INDEX,5209(u8 *)&arb_regs,5210sizeof(SMC_SIslands_MCArbDramTimingRegisterSet),5211si_pi->sram_end);52125213return ret;5214}52155216static void si_get_mvdd_configuration(struct amdgpu_device *adev)5217{5218struct rv7xx_power_info *pi = rv770_get_pi(adev);52195220pi->mvdd_split_frequency = 30000;5221}52225223static int si_init_smc_table(struct amdgpu_device *adev)5224{5225struct si_power_info *si_pi = si_get_pi(adev);5226struct amdgpu_ps *amdgpu_boot_state = adev->pm.dpm.boot_ps;5227const struct si_ulv_param *ulv = &si_pi->ulv;5228SISLANDS_SMC_STATETABLE *table = &si_pi->smc_statetable;5229int ret;5230u32 lane_width;5231u32 vr_hot_gpio;52325233si_populate_smc_voltage_tables(adev, table);52345235switch (adev->pm.int_thermal_type) {5236case THERMAL_TYPE_SI:5237case THERMAL_TYPE_EMC2103_WITH_INTERNAL:5238table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;5239break;5240case THERMAL_TYPE_NONE:5241table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;5242break;5243default:5244table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;5245break;5246}52475248if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)5249table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;52505251if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT) {5252if ((adev->pdev->device != 0x6818) && (adev->pdev->device != 0x6819))5253table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;5254}52555256if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)5257table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;52585259if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5)5260table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;52615262if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY)5263table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH;52645265if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE) {5266table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO;5267vr_hot_gpio = adev->pm.dpm.backbias_response_time;5268si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_vr_hot_gpio,5269vr_hot_gpio);5270}52715272ret = si_populate_smc_initial_state(adev, amdgpu_boot_state, table);5273if (ret)5274return ret;52755276ret = si_populate_smc_acpi_state(adev, table);5277if (ret)5278return ret;52795280table->driverState.flags = table->initialState.flags;5281table->driverState.levelCount = table->initialState.levelCount;5282table->driverState.levels[0] = table->initialState.level;52835284ret = si_do_program_memory_timing_parameters(adev, amdgpu_boot_state,5285SISLANDS_INITIAL_STATE_ARB_INDEX);5286if (ret)5287return ret;52885289if (ulv->supported && ulv->pl.vddc) {5290ret = si_populate_ulv_state(adev, &table->ULVState);5291if (ret)5292return ret;52935294ret = si_program_ulv_memory_timing_parameters(adev);5295if (ret)5296return ret;52975298WREG32(mmCG_ULV_CONTROL, ulv->cg_ulv_control);5299WREG32(mmCG_ULV_PARAMETER, ulv->cg_ulv_parameter);53005301lane_width = amdgpu_get_pcie_lanes(adev);5302si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width, lane_width);5303} else {5304table->ULVState = table->initialState;5305}53065307return amdgpu_si_copy_bytes_to_smc(adev, si_pi->state_table_start,5308(u8 *)table, sizeof(SISLANDS_SMC_STATETABLE),5309si_pi->sram_end);5310}53115312static int si_calculate_sclk_params(struct amdgpu_device *adev,5313u32 engine_clock,5314SISLANDS_SMC_SCLK_VALUE *sclk)5315{5316struct rv7xx_power_info *pi = rv770_get_pi(adev);5317struct si_power_info *si_pi = si_get_pi(adev);5318struct atom_clock_dividers dividers;5319u32 spll_func_cntl = si_pi->clock_registers.cg_spll_func_cntl;5320u32 spll_func_cntl_2 = si_pi->clock_registers.cg_spll_func_cntl_2;5321u32 spll_func_cntl_3 = si_pi->clock_registers.cg_spll_func_cntl_3;5322u32 spll_func_cntl_4 = si_pi->clock_registers.cg_spll_func_cntl_4;5323u32 cg_spll_spread_spectrum = si_pi->clock_registers.cg_spll_spread_spectrum;5324u32 cg_spll_spread_spectrum_2 = si_pi->clock_registers.cg_spll_spread_spectrum_2;5325u64 tmp;5326u32 reference_clock = adev->clock.spll.reference_freq;5327u32 reference_divider;5328u32 fbdiv;5329int ret;53305331ret = amdgpu_atombios_get_clock_dividers(adev, COMPUTE_ENGINE_PLL_PARAM,5332engine_clock, false, ÷rs);5333if (ret)5334return ret;53355336reference_divider = 1 + dividers.ref_div;53375338tmp = (u64) engine_clock * reference_divider * dividers.post_div * 16384;5339do_div(tmp, reference_clock);5340fbdiv = (u32) tmp;53415342spll_func_cntl &= ~(CG_SPLL_FUNC_CNTL__SPLL_PDIV_A_MASK | CG_SPLL_FUNC_CNTL__SPLL_REF_DIV_MASK);5343spll_func_cntl |= dividers.ref_div << CG_SPLL_FUNC_CNTL__SPLL_REF_DIV__SHIFT;5344spll_func_cntl |= dividers.post_div << CG_SPLL_FUNC_CNTL__SPLL_PDIV_A__SHIFT;53455346spll_func_cntl_2 &= ~CG_SPLL_FUNC_CNTL_2__SCLK_MUX_SEL_MASK;5347spll_func_cntl_2 |= 2 << CG_SPLL_FUNC_CNTL_2__SCLK_MUX_SEL__SHIFT;53485349spll_func_cntl_3 &= ~CG_SPLL_FUNC_CNTL_3__SPLL_FB_DIV_MASK;5350spll_func_cntl_3 |= fbdiv << CG_SPLL_FUNC_CNTL_3__SPLL_FB_DIV__SHIFT;5351spll_func_cntl_3 |= CG_SPLL_FUNC_CNTL_3__SPLL_DITHEN_MASK;53525353if (pi->sclk_ss) {5354struct amdgpu_atom_ss ss;5355u32 vco_freq = engine_clock * dividers.post_div;53565357if (amdgpu_atombios_get_asic_ss_info(adev, &ss,5358ASIC_INTERNAL_ENGINE_SS, vco_freq)) {5359u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);5360u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000);53615362cg_spll_spread_spectrum &= ~CG_SPLL_SPREAD_SPECTRUM__CLK_S_MASK;5363cg_spll_spread_spectrum |= clk_s << CG_SPLL_SPREAD_SPECTRUM__CLK_S__SHIFT;5364cg_spll_spread_spectrum |= CG_SPLL_SPREAD_SPECTRUM__SSEN_MASK;53655366cg_spll_spread_spectrum_2 &= ~CG_SPLL_SPREAD_SPECTRUM_2__CLK_V_MASK;5367cg_spll_spread_spectrum_2 |= clk_v << CG_SPLL_SPREAD_SPECTRUM_2__CLK_V__SHIFT;5368}5369}53705371sclk->sclk_value = engine_clock;5372sclk->vCG_SPLL_FUNC_CNTL = spll_func_cntl;5373sclk->vCG_SPLL_FUNC_CNTL_2 = spll_func_cntl_2;5374sclk->vCG_SPLL_FUNC_CNTL_3 = spll_func_cntl_3;5375sclk->vCG_SPLL_FUNC_CNTL_4 = spll_func_cntl_4;5376sclk->vCG_SPLL_SPREAD_SPECTRUM = cg_spll_spread_spectrum;5377sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cg_spll_spread_spectrum_2;53785379return 0;5380}53815382static int si_populate_sclk_value(struct amdgpu_device *adev,5383u32 engine_clock,5384SISLANDS_SMC_SCLK_VALUE *sclk)5385{5386SISLANDS_SMC_SCLK_VALUE sclk_tmp;5387int ret;53885389ret = si_calculate_sclk_params(adev, engine_clock, &sclk_tmp);5390if (!ret) {5391sclk->sclk_value = cpu_to_be32(sclk_tmp.sclk_value);5392sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL);5393sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_2);5394sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_3);5395sclk->vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_4);5396sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM);5397sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM_2);5398}53995400return ret;5401}54025403static int si_populate_mclk_value(struct amdgpu_device *adev,5404u32 engine_clock,5405u32 memory_clock,5406SISLANDS_SMC_MCLK_VALUE *mclk,5407bool strobe_mode,5408bool dll_state_on)5409{5410struct rv7xx_power_info *pi = rv770_get_pi(adev);5411struct si_power_info *si_pi = si_get_pi(adev);5412u32 dll_cntl = si_pi->clock_registers.dll_cntl;5413u32 mclk_pwrmgt_cntl = si_pi->clock_registers.mclk_pwrmgt_cntl;5414u32 mpll_ad_func_cntl = si_pi->clock_registers.mpll_ad_func_cntl;5415u32 mpll_dq_func_cntl = si_pi->clock_registers.mpll_dq_func_cntl;5416u32 mpll_func_cntl = si_pi->clock_registers.mpll_func_cntl;5417u32 mpll_func_cntl_1 = si_pi->clock_registers.mpll_func_cntl_1;5418u32 mpll_func_cntl_2 = si_pi->clock_registers.mpll_func_cntl_2;5419u32 mpll_ss1 = si_pi->clock_registers.mpll_ss1;5420u32 mpll_ss2 = si_pi->clock_registers.mpll_ss2;5421struct atom_mpll_param mpll_param;5422int ret;54235424ret = amdgpu_atombios_get_memory_pll_dividers(adev, memory_clock, strobe_mode, &mpll_param);5425if (ret)5426return ret;54275428mpll_func_cntl &= ~BWCTRL_MASK;5429mpll_func_cntl |= BWCTRL(mpll_param.bwcntl);54305431mpll_func_cntl_1 &= ~(CLKF_MASK | CLKFRAC_MASK | VCO_MODE_MASK);5432mpll_func_cntl_1 |= CLKF(mpll_param.clkf) |5433CLKFRAC(mpll_param.clkfrac) | VCO_MODE(mpll_param.vco_mode);54345435mpll_ad_func_cntl &= ~YCLK_POST_DIV_MASK;5436mpll_ad_func_cntl |= YCLK_POST_DIV(mpll_param.post_div);54375438if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5) {5439mpll_dq_func_cntl &= ~(YCLK_SEL_MASK | YCLK_POST_DIV_MASK);5440mpll_dq_func_cntl |= YCLK_SEL(mpll_param.yclk_sel) |5441YCLK_POST_DIV(mpll_param.post_div);5442}54435444if (pi->mclk_ss) {5445struct amdgpu_atom_ss ss;5446u32 freq_nom;5447u32 tmp;5448u32 reference_clock = adev->clock.mpll.reference_freq;54495450if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5)5451freq_nom = memory_clock * 4;5452else5453freq_nom = memory_clock * 2;54545455tmp = freq_nom / reference_clock;5456tmp = tmp * tmp;5457if (amdgpu_atombios_get_asic_ss_info(adev, &ss,5458ASIC_INTERNAL_MEMORY_SS, freq_nom)) {5459u32 clks = reference_clock * 5 / ss.rate;5460u32 clkv = (u32)((((131 * ss.percentage * ss.rate) / 100) * tmp) / freq_nom);54615462mpll_ss1 &= ~CLKV_MASK;5463mpll_ss1 |= CLKV(clkv);54645465mpll_ss2 &= ~CLKS_MASK;5466mpll_ss2 |= CLKS(clks);5467}5468}54695470mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;5471mclk_pwrmgt_cntl |= DLL_SPEED(mpll_param.dll_speed);54725473if (dll_state_on)5474mclk_pwrmgt_cntl |= MRDCK0_PDNB | MRDCK1_PDNB;5475else5476mclk_pwrmgt_cntl &= ~(MRDCK0_PDNB | MRDCK1_PDNB);54775478mclk->mclk_value = cpu_to_be32(memory_clock);5479mclk->vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl);5480mclk->vMPLL_FUNC_CNTL_1 = cpu_to_be32(mpll_func_cntl_1);5481mclk->vMPLL_FUNC_CNTL_2 = cpu_to_be32(mpll_func_cntl_2);5482mclk->vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);5483mclk->vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);5484mclk->vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);5485mclk->vDLL_CNTL = cpu_to_be32(dll_cntl);5486mclk->vMPLL_SS = cpu_to_be32(mpll_ss1);5487mclk->vMPLL_SS2 = cpu_to_be32(mpll_ss2);54885489return 0;5490}54915492static void si_populate_smc_sp(struct amdgpu_device *adev,5493struct amdgpu_ps *amdgpu_state,5494SISLANDS_SMC_SWSTATE *smc_state)5495{5496struct si_ps *ps = si_get_ps(amdgpu_state);5497struct rv7xx_power_info *pi = rv770_get_pi(adev);5498int i;54995500for (i = 0; i < ps->performance_level_count - 1; i++)5501smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);55025503smc_state->levels[ps->performance_level_count - 1].bSP =5504cpu_to_be32(pi->psp);5505}55065507static int si_convert_power_level_to_smc(struct amdgpu_device *adev,5508struct rv7xx_pl *pl,5509SISLANDS_SMC_HW_PERFORMANCE_LEVEL *level)5510{5511struct rv7xx_power_info *pi = rv770_get_pi(adev);5512struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);5513struct si_power_info *si_pi = si_get_pi(adev);5514int ret;5515bool dll_state_on;5516u16 std_vddc;55175518if (eg_pi->pcie_performance_request &&5519(si_pi->force_pcie_gen != SI_PCIE_GEN_INVALID))5520level->gen2PCIE = (u8)si_pi->force_pcie_gen;5521else5522level->gen2PCIE = (u8)pl->pcie_gen;55235524ret = si_populate_sclk_value(adev, pl->sclk, &level->sclk);5525if (ret)5526return ret;55275528level->mcFlags = 0;55295530if (pi->mclk_stutter_mode_threshold &&5531(pl->mclk <= pi->mclk_stutter_mode_threshold) &&5532!eg_pi->uvd_enabled &&5533(RREG32(mmDPG_PIPE_STUTTER_CONTROL) & DPG_PIPE_STUTTER_CONTROL__STUTTER_ENABLE_MASK) &&5534(adev->pm.pm_display_cfg.num_display <= 2)) {5535level->mcFlags |= SISLANDS_SMC_MC_STUTTER_EN;5536}55375538if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5) {5539if (pl->mclk > pi->mclk_edc_enable_threshold)5540level->mcFlags |= SISLANDS_SMC_MC_EDC_RD_FLAG;55415542if (pl->mclk > eg_pi->mclk_edc_wr_enable_threshold)5543level->mcFlags |= SISLANDS_SMC_MC_EDC_WR_FLAG;55445545level->strobeMode = si_get_strobe_mode_settings(adev, pl->mclk);55465547if (level->strobeMode & SISLANDS_SMC_STROBE_ENABLE) {5548if (si_get_mclk_frequency_ratio(pl->mclk, true) >=5549((RREG32(MC_SEQ_MISC7) >> 16) & 0xf))5550dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;5551else5552dll_state_on = ((RREG32(MC_SEQ_MISC6) >> 1) & 0x1) ? true : false;5553} else {5554dll_state_on = false;5555}5556} else {5557level->strobeMode = si_get_strobe_mode_settings(adev,5558pl->mclk);55595560dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;5561}55625563ret = si_populate_mclk_value(adev,5564pl->sclk,5565pl->mclk,5566&level->mclk,5567(level->strobeMode & SISLANDS_SMC_STROBE_ENABLE) != 0, dll_state_on);5568if (ret)5569return ret;55705571ret = si_populate_voltage_value(adev,5572&eg_pi->vddc_voltage_table,5573pl->vddc, &level->vddc);5574if (ret)5575return ret;557655775578ret = si_get_std_voltage_value(adev, &level->vddc, &std_vddc);5579if (ret)5580return ret;55815582ret = si_populate_std_voltage_value(adev, std_vddc,5583level->vddc.index, &level->std_vddc);5584if (ret)5585return ret;55865587if (eg_pi->vddci_control) {5588ret = si_populate_voltage_value(adev, &eg_pi->vddci_voltage_table,5589pl->vddci, &level->vddci);5590if (ret)5591return ret;5592}55935594if (si_pi->vddc_phase_shed_control) {5595ret = si_populate_phase_shedding_value(adev,5596&adev->pm.dpm.dyn_state.phase_shedding_limits_table,5597pl->vddc,5598pl->sclk,5599pl->mclk,5600&level->vddc);5601if (ret)5602return ret;5603}56045605level->MaxPoweredUpCU = si_pi->max_cu;56065607ret = si_populate_mvdd_value(adev, pl->mclk, &level->mvdd);56085609return ret;5610}56115612static int si_populate_smc_t(struct amdgpu_device *adev,5613struct amdgpu_ps *amdgpu_state,5614SISLANDS_SMC_SWSTATE *smc_state)5615{5616struct rv7xx_power_info *pi = rv770_get_pi(adev);5617struct si_ps *state = si_get_ps(amdgpu_state);5618u32 a_t;5619u32 t_l, t_h;5620u32 high_bsp;5621int i, ret;56225623if (state->performance_level_count >= 9)5624return -EINVAL;56255626if (state->performance_level_count < 2) {5627a_t = 0xffff << CG_AT__CG_R__SHIFT | 0 << CG_AT__CG_L__SHIFT;5628smc_state->levels[0].aT = cpu_to_be32(a_t);5629return 0;5630}56315632smc_state->levels[0].aT = cpu_to_be32(0);56335634for (i = 0; i <= state->performance_level_count - 2; i++) {5635ret = r600_calculate_at(5636(50 / SISLANDS_MAX_HARDWARE_POWERLEVELS) * 100 * (i + 1),5637100 * R600_AH_DFLT,5638state->performance_levels[i + 1].sclk,5639state->performance_levels[i].sclk,5640&t_l,5641&t_h);56425643if (ret) {5644t_h = (i + 1) * 1000 - 50 * R600_AH_DFLT;5645t_l = (i + 1) * 1000 + 50 * R600_AH_DFLT;5646}56475648a_t = be32_to_cpu(smc_state->levels[i].aT) & ~CG_AT__CG_R_MASK;5649a_t |= (t_l * pi->bsp / 20000) << CG_AT__CG_R__SHIFT;5650smc_state->levels[i].aT = cpu_to_be32(a_t);56515652high_bsp = (i == state->performance_level_count - 2) ?5653pi->pbsp : pi->bsp;5654a_t = (0xffff) << CG_AT__CG_R__SHIFT | (t_h * high_bsp / 20000) << CG_AT__CG_L__SHIFT;5655smc_state->levels[i + 1].aT = cpu_to_be32(a_t);5656}56575658return 0;5659}56605661static int si_disable_ulv(struct amdgpu_device *adev)5662{5663PPSMC_Result r;56645665r = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_DisableULV);5666return (r == PPSMC_Result_OK) ? 0 : -EINVAL;5667}56685669static bool si_is_state_ulv_compatible(struct amdgpu_device *adev,5670struct amdgpu_ps *amdgpu_state)5671{5672const struct si_power_info *si_pi = si_get_pi(adev);5673const struct si_ulv_param *ulv = &si_pi->ulv;5674const struct si_ps *state = si_get_ps(amdgpu_state);5675int i;56765677if (state->performance_levels[0].mclk != ulv->pl.mclk)5678return false;56795680/* XXX validate against display requirements! */56815682for (i = 0; i < adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count; i++) {5683if (adev->pm.pm_display_cfg.display_clk <=5684adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[i].clk) {5685if (ulv->pl.vddc <5686adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[i].v)5687return false;5688}5689}56905691if ((amdgpu_state->vclk != 0) || (amdgpu_state->dclk != 0))5692return false;56935694return true;5695}56965697static int si_set_power_state_conditionally_enable_ulv(struct amdgpu_device *adev,5698struct amdgpu_ps *amdgpu_new_state)5699{5700const struct si_power_info *si_pi = si_get_pi(adev);5701const struct si_ulv_param *ulv = &si_pi->ulv;57025703if (ulv->supported) {5704if (si_is_state_ulv_compatible(adev, amdgpu_new_state))5705return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableULV) == PPSMC_Result_OK) ?57060 : -EINVAL;5707}5708return 0;5709}57105711static int si_convert_power_state_to_smc(struct amdgpu_device *adev,5712struct amdgpu_ps *amdgpu_state,5713SISLANDS_SMC_SWSTATE *smc_state)5714{5715struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);5716struct ni_power_info *ni_pi = ni_get_pi(adev);5717struct si_power_info *si_pi = si_get_pi(adev);5718struct si_ps *state = si_get_ps(amdgpu_state);5719int i, ret;5720u32 threshold;5721u32 sclk_in_sr = 1350; /* ??? */57225723if (state->performance_level_count > SISLANDS_MAX_HARDWARE_POWERLEVELS)5724return -EINVAL;57255726threshold = state->performance_levels[state->performance_level_count-1].sclk * 100 / 100;57275728if (amdgpu_state->vclk && amdgpu_state->dclk) {5729eg_pi->uvd_enabled = true;5730if (eg_pi->smu_uvd_hs)5731smc_state->flags |= PPSMC_SWSTATE_FLAG_UVD;5732} else {5733eg_pi->uvd_enabled = false;5734}57355736if (state->dc_compatible)5737smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;57385739smc_state->levelCount = 0;5740for (i = 0; i < state->performance_level_count; i++) {5741if (eg_pi->sclk_deep_sleep) {5742if ((i == 0) || si_pi->sclk_deep_sleep_above_low) {5743if (sclk_in_sr <= SCLK_MIN_DEEPSLEEP_FREQ)5744smc_state->levels[i].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_BYPASS;5745else5746smc_state->levels[i].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE;5747}5748}57495750ret = si_convert_power_level_to_smc(adev, &state->performance_levels[i],5751&smc_state->levels[i]);5752smc_state->levels[i].arbRefreshState =5753(u8)(SISLANDS_DRIVER_STATE_ARB_INDEX + i);57545755if (ret)5756return ret;57575758if (ni_pi->enable_power_containment)5759smc_state->levels[i].displayWatermark =5760(state->performance_levels[i].sclk < threshold) ?5761PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;5762else5763smc_state->levels[i].displayWatermark = (i < 2) ?5764PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;57655766if (eg_pi->dynamic_ac_timing)5767smc_state->levels[i].ACIndex = SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i;5768else5769smc_state->levels[i].ACIndex = 0;57705771smc_state->levelCount++;5772}57735774si_write_smc_soft_register(adev,5775SI_SMC_SOFT_REGISTER_watermark_threshold,5776threshold / 512);57775778si_populate_smc_sp(adev, amdgpu_state, smc_state);57795780ret = si_populate_power_containment_values(adev, amdgpu_state, smc_state);5781if (ret)5782ni_pi->enable_power_containment = false;57835784ret = si_populate_sq_ramping_values(adev, amdgpu_state, smc_state);5785if (ret)5786ni_pi->enable_sq_ramping = false;57875788return si_populate_smc_t(adev, amdgpu_state, smc_state);5789}57905791static int si_upload_sw_state(struct amdgpu_device *adev,5792struct amdgpu_ps *amdgpu_new_state)5793{5794struct si_power_info *si_pi = si_get_pi(adev);5795struct si_ps *new_state = si_get_ps(amdgpu_new_state);5796int ret;5797u32 address = si_pi->state_table_start +5798offsetof(SISLANDS_SMC_STATETABLE, driverState);5799SISLANDS_SMC_SWSTATE *smc_state = &si_pi->smc_statetable.driverState;5800size_t state_size = struct_size(smc_state, levels,5801new_state->performance_level_count);5802memset(smc_state, 0, state_size);58035804ret = si_convert_power_state_to_smc(adev, amdgpu_new_state, smc_state);5805if (ret)5806return ret;58075808return amdgpu_si_copy_bytes_to_smc(adev, address, (u8 *)smc_state,5809state_size, si_pi->sram_end);5810}58115812static int si_upload_ulv_state(struct amdgpu_device *adev)5813{5814struct si_power_info *si_pi = si_get_pi(adev);5815struct si_ulv_param *ulv = &si_pi->ulv;5816int ret = 0;58175818if (ulv->supported && ulv->pl.vddc) {5819u32 address = si_pi->state_table_start +5820offsetof(SISLANDS_SMC_STATETABLE, ULVState);5821struct SISLANDS_SMC_SWSTATE_SINGLE *smc_state = &si_pi->smc_statetable.ULVState;5822u32 state_size = sizeof(struct SISLANDS_SMC_SWSTATE_SINGLE);58235824memset(smc_state, 0, state_size);58255826ret = si_populate_ulv_state(adev, smc_state);5827if (!ret)5828ret = amdgpu_si_copy_bytes_to_smc(adev, address, (u8 *)smc_state,5829state_size, si_pi->sram_end);5830}58315832return ret;5833}58345835static int si_upload_smc_data(struct amdgpu_device *adev)5836{5837const struct amd_pp_display_configuration *cfg = &adev->pm.pm_display_cfg;5838u32 crtc_index = 0;5839u32 mclk_change_block_cp_min = 0;5840u32 mclk_change_block_cp_max = 0;58415842/* When a display is plugged in, program these so that the SMC5843* performs MCLK switching when it doesn't cause flickering.5844* When no display is plugged in, there is no need to restrict5845* MCLK switching, so program them to zero.5846*/5847if (cfg->num_display) {5848crtc_index = cfg->crtc_index;58495850if (cfg->line_time_in_us) {5851mclk_change_block_cp_min = 200 / cfg->line_time_in_us;5852mclk_change_block_cp_max = 100 / cfg->line_time_in_us;5853}5854}58555856si_write_smc_soft_register(adev,5857SI_SMC_SOFT_REGISTER_crtc_index,5858crtc_index);58595860si_write_smc_soft_register(adev,5861SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min,5862mclk_change_block_cp_min);58635864si_write_smc_soft_register(adev,5865SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max,5866mclk_change_block_cp_max);58675868return 0;5869}58705871static int si_set_mc_special_registers(struct amdgpu_device *adev,5872struct si_mc_reg_table *table)5873{5874u8 i, j, k;5875u32 temp_reg;58765877for (i = 0, j = table->last; i < table->last; i++) {5878if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)5879return -EINVAL;5880switch (table->mc_reg_address[i].s1) {5881case MC_SEQ_MISC1:5882temp_reg = RREG32(MC_PMG_CMD_EMRS);5883table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS;5884table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP;5885for (k = 0; k < table->num_entries; k++)5886table->mc_reg_table_entry[k].mc_data[j] =5887((temp_reg & 0xffff0000)) |5888((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);5889j++;58905891if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)5892return -EINVAL;5893temp_reg = RREG32(MC_PMG_CMD_MRS);5894table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS;5895table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP;5896for (k = 0; k < table->num_entries; k++) {5897table->mc_reg_table_entry[k].mc_data[j] =5898(temp_reg & 0xffff0000) |5899(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);5900if (adev->gmc.vram_type != AMDGPU_VRAM_TYPE_GDDR5)5901table->mc_reg_table_entry[k].mc_data[j] |= 0x100;5902}5903j++;59045905if (adev->gmc.vram_type != AMDGPU_VRAM_TYPE_GDDR5) {5906if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)5907return -EINVAL;5908table->mc_reg_address[j].s1 = MC_PMG_AUTO_CMD;5909table->mc_reg_address[j].s0 = MC_PMG_AUTO_CMD;5910for (k = 0; k < table->num_entries; k++)5911table->mc_reg_table_entry[k].mc_data[j] =5912(table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16;5913j++;5914}5915break;5916case MC_SEQ_RESERVE_M:5917temp_reg = RREG32(MC_PMG_CMD_MRS1);5918table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1;5919table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP;5920for(k = 0; k < table->num_entries; k++)5921table->mc_reg_table_entry[k].mc_data[j] =5922(temp_reg & 0xffff0000) |5923(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);5924j++;5925break;5926default:5927break;5928}5929}59305931table->last = j;59325933return 0;5934}59355936static bool si_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)5937{5938bool result = true;5939switch (in_reg) {5940case MC_SEQ_RAS_TIMING:5941*out_reg = MC_SEQ_RAS_TIMING_LP;5942break;5943case MC_SEQ_CAS_TIMING:5944*out_reg = MC_SEQ_CAS_TIMING_LP;5945break;5946case MC_SEQ_MISC_TIMING:5947*out_reg = MC_SEQ_MISC_TIMING_LP;5948break;5949case MC_SEQ_MISC_TIMING2:5950*out_reg = MC_SEQ_MISC_TIMING2_LP;5951break;5952case MC_SEQ_RD_CTL_D0:5953*out_reg = MC_SEQ_RD_CTL_D0_LP;5954break;5955case MC_SEQ_RD_CTL_D1:5956*out_reg = MC_SEQ_RD_CTL_D1_LP;5957break;5958case MC_SEQ_WR_CTL_D0:5959*out_reg = MC_SEQ_WR_CTL_D0_LP;5960break;5961case MC_SEQ_WR_CTL_D1:5962*out_reg = MC_SEQ_WR_CTL_D1_LP;5963break;5964case MC_PMG_CMD_EMRS:5965*out_reg = MC_SEQ_PMG_CMD_EMRS_LP;5966break;5967case MC_PMG_CMD_MRS:5968*out_reg = MC_SEQ_PMG_CMD_MRS_LP;5969break;5970case MC_PMG_CMD_MRS1:5971*out_reg = MC_SEQ_PMG_CMD_MRS1_LP;5972break;5973case MC_SEQ_PMG_TIMING:5974*out_reg = MC_SEQ_PMG_TIMING_LP;5975break;5976case MC_PMG_CMD_MRS2:5977*out_reg = MC_SEQ_PMG_CMD_MRS2_LP;5978break;5979case MC_SEQ_WR_CTL_2:5980*out_reg = MC_SEQ_WR_CTL_2_LP;5981break;5982default:5983result = false;5984break;5985}59865987return result;5988}59895990static void si_set_valid_flag(struct si_mc_reg_table *table)5991{5992u8 i, j;59935994for (i = 0; i < table->last; i++) {5995for (j = 1; j < table->num_entries; j++) {5996if (table->mc_reg_table_entry[j-1].mc_data[i] != table->mc_reg_table_entry[j].mc_data[i]) {5997table->valid_flag |= 1 << i;5998break;5999}6000}6001}6002}60036004static void si_set_s0_mc_reg_index(struct si_mc_reg_table *table)6005{6006u32 i;6007u16 address;60086009for (i = 0; i < table->last; i++)6010table->mc_reg_address[i].s0 = si_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?6011address : table->mc_reg_address[i].s1;60126013}60146015static int si_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,6016struct si_mc_reg_table *si_table)6017{6018u8 i, j;60196020if (table->last > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)6021return -EINVAL;6022if (table->num_entries > MAX_AC_TIMING_ENTRIES)6023return -EINVAL;60246025for (i = 0; i < table->last; i++)6026si_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;6027si_table->last = table->last;60286029for (i = 0; i < table->num_entries; i++) {6030si_table->mc_reg_table_entry[i].mclk_max =6031table->mc_reg_table_entry[i].mclk_max;6032for (j = 0; j < table->last; j++) {6033si_table->mc_reg_table_entry[i].mc_data[j] =6034table->mc_reg_table_entry[i].mc_data[j];6035}6036}6037si_table->num_entries = table->num_entries;60386039return 0;6040}60416042static int si_initialize_mc_reg_table(struct amdgpu_device *adev)6043{6044struct si_power_info *si_pi = si_get_pi(adev);6045struct atom_mc_reg_table *table;6046struct si_mc_reg_table *si_table = &si_pi->mc_reg_table;6047u8 module_index = rv770_get_memory_module_index(adev);6048int ret;60496050table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);6051if (!table)6052return -ENOMEM;60536054WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));6055WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));6056WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));6057WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));6058WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));6059WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));6060WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));6061WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));6062WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));6063WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));6064WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));6065WREG32(MC_SEQ_PMG_TIMING_LP, RREG32(MC_SEQ_PMG_TIMING));6066WREG32(MC_SEQ_PMG_CMD_MRS2_LP, RREG32(MC_PMG_CMD_MRS2));6067WREG32(MC_SEQ_WR_CTL_2_LP, RREG32(MC_SEQ_WR_CTL_2));60686069ret = amdgpu_atombios_init_mc_reg_table(adev, module_index, table);6070if (ret)6071goto init_mc_done;60726073ret = si_copy_vbios_mc_reg_table(table, si_table);6074if (ret)6075goto init_mc_done;60766077si_set_s0_mc_reg_index(si_table);60786079ret = si_set_mc_special_registers(adev, si_table);6080if (ret)6081goto init_mc_done;60826083si_set_valid_flag(si_table);60846085init_mc_done:6086kfree(table);60876088return ret;60896090}60916092static void si_populate_mc_reg_addresses(struct amdgpu_device *adev,6093SMC_SIslands_MCRegisters *mc_reg_table)6094{6095struct si_power_info *si_pi = si_get_pi(adev);6096u32 i, j;60976098for (i = 0, j = 0; j < si_pi->mc_reg_table.last; j++) {6099if (si_pi->mc_reg_table.valid_flag & (1 << j)) {6100if (i >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)6101break;6102mc_reg_table->address[i].s0 =6103cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s0);6104mc_reg_table->address[i].s1 =6105cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s1);6106i++;6107}6108}6109mc_reg_table->last = (u8)i;6110}61116112static void si_convert_mc_registers(const struct si_mc_reg_entry *entry,6113SMC_SIslands_MCRegisterSet *data,6114u32 num_entries, u32 valid_flag)6115{6116u32 i, j;61176118for(i = 0, j = 0; j < num_entries; j++) {6119if (valid_flag & (1 << j)) {6120data->value[i] = cpu_to_be32(entry->mc_data[j]);6121i++;6122}6123}6124}61256126static void si_convert_mc_reg_table_entry_to_smc(struct amdgpu_device *adev,6127struct rv7xx_pl *pl,6128SMC_SIslands_MCRegisterSet *mc_reg_table_data)6129{6130struct si_power_info *si_pi = si_get_pi(adev);6131u32 i = 0;61326133for (i = 0; i < si_pi->mc_reg_table.num_entries; i++) {6134if (pl->mclk <= si_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max)6135break;6136}61376138if ((i == si_pi->mc_reg_table.num_entries) && (i > 0))6139--i;61406141si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[i],6142mc_reg_table_data, si_pi->mc_reg_table.last,6143si_pi->mc_reg_table.valid_flag);6144}61456146static void si_convert_mc_reg_table_to_smc(struct amdgpu_device *adev,6147struct amdgpu_ps *amdgpu_state,6148SMC_SIslands_MCRegisters *mc_reg_table)6149{6150struct si_ps *state = si_get_ps(amdgpu_state);6151int i;61526153for (i = 0; i < state->performance_level_count; i++) {6154si_convert_mc_reg_table_entry_to_smc(adev,6155&state->performance_levels[i],6156&mc_reg_table->data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i]);6157}6158}61596160static int si_populate_mc_reg_table(struct amdgpu_device *adev,6161struct amdgpu_ps *amdgpu_boot_state)6162{6163struct si_ps *boot_state = si_get_ps(amdgpu_boot_state);6164struct si_power_info *si_pi = si_get_pi(adev);6165struct si_ulv_param *ulv = &si_pi->ulv;6166SMC_SIslands_MCRegisters *smc_mc_reg_table = &si_pi->smc_mc_reg_table;61676168memset(smc_mc_reg_table, 0, sizeof(SMC_SIslands_MCRegisters));61696170si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_seq_index, 1);61716172si_populate_mc_reg_addresses(adev, smc_mc_reg_table);61736174si_convert_mc_reg_table_entry_to_smc(adev, &boot_state->performance_levels[0],6175&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_INITIAL_SLOT]);61766177si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[0],6178&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ACPI_SLOT],6179si_pi->mc_reg_table.last,6180si_pi->mc_reg_table.valid_flag);61816182if (ulv->supported && ulv->pl.vddc != 0)6183si_convert_mc_reg_table_entry_to_smc(adev, &ulv->pl,6184&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ULV_SLOT]);6185else6186si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[0],6187&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ULV_SLOT],6188si_pi->mc_reg_table.last,6189si_pi->mc_reg_table.valid_flag);61906191si_convert_mc_reg_table_to_smc(adev, amdgpu_boot_state, smc_mc_reg_table);61926193return amdgpu_si_copy_bytes_to_smc(adev, si_pi->mc_reg_table_start,6194(u8 *)smc_mc_reg_table,6195sizeof(SMC_SIslands_MCRegisters), si_pi->sram_end);6196}61976198static int si_upload_mc_reg_table(struct amdgpu_device *adev,6199struct amdgpu_ps *amdgpu_new_state)6200{6201struct si_ps *new_state = si_get_ps(amdgpu_new_state);6202struct si_power_info *si_pi = si_get_pi(adev);6203u32 address = si_pi->mc_reg_table_start +6204offsetof(SMC_SIslands_MCRegisters,6205data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT]);6206SMC_SIslands_MCRegisters *smc_mc_reg_table = &si_pi->smc_mc_reg_table;62076208memset(smc_mc_reg_table, 0, sizeof(SMC_SIslands_MCRegisters));62096210si_convert_mc_reg_table_to_smc(adev, amdgpu_new_state, smc_mc_reg_table);62116212return amdgpu_si_copy_bytes_to_smc(adev, address,6213(u8 *)&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT],6214sizeof(SMC_SIslands_MCRegisterSet) * new_state->performance_level_count,6215si_pi->sram_end);6216}62176218static void si_enable_voltage_control(struct amdgpu_device *adev, bool enable)6219{6220if (enable)6221WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__VOLT_PWRMGT_EN_MASK, ~GENERAL_PWRMGT__VOLT_PWRMGT_EN_MASK);6222else6223WREG32_P(mmGENERAL_PWRMGT, 0, ~GENERAL_PWRMGT__VOLT_PWRMGT_EN_MASK);6224}62256226static enum si_pcie_gen si_get_maximum_link_speed(struct amdgpu_device *adev,6227struct amdgpu_ps *amdgpu_state)6228{6229struct si_ps *state = si_get_ps(amdgpu_state);6230int i;6231u16 pcie_speed, max_speed = 0;62326233for (i = 0; i < state->performance_level_count; i++) {6234pcie_speed = state->performance_levels[i].pcie_gen;6235if (max_speed < pcie_speed)6236max_speed = pcie_speed;6237}6238return max_speed;6239}62406241static u16 si_get_current_pcie_speed(struct amdgpu_device *adev)6242{6243u32 speed_cntl;62446245speed_cntl = RREG32_PCIE_PORT(ixPCIE_LC_SPEED_CNTL) & PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK;6246speed_cntl >>= PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT;62476248return (u16)speed_cntl;6249}62506251static void si_request_link_speed_change_before_state_change(struct amdgpu_device *adev,6252struct amdgpu_ps *amdgpu_new_state,6253struct amdgpu_ps *amdgpu_current_state)6254{6255struct si_power_info *si_pi = si_get_pi(adev);6256enum si_pcie_gen target_link_speed = si_get_maximum_link_speed(adev, amdgpu_new_state);6257enum si_pcie_gen current_link_speed;62586259if (si_pi->force_pcie_gen == SI_PCIE_GEN_INVALID)6260current_link_speed = si_get_maximum_link_speed(adev, amdgpu_current_state);6261else6262current_link_speed = si_pi->force_pcie_gen;62636264si_pi->force_pcie_gen = SI_PCIE_GEN_INVALID;6265si_pi->pspp_notify_required = false;6266if (target_link_speed > current_link_speed) {6267switch (target_link_speed) {6268#if defined(CONFIG_ACPI)6269case SI_PCIE_GEN3:6270if (amdgpu_acpi_pcie_performance_request(adev, PCIE_PERF_REQ_PECI_GEN3, false) == 0)6271break;6272si_pi->force_pcie_gen = SI_PCIE_GEN2;6273if (current_link_speed == SI_PCIE_GEN2)6274break;6275fallthrough;6276case SI_PCIE_GEN2:6277if (amdgpu_acpi_pcie_performance_request(adev, PCIE_PERF_REQ_PECI_GEN2, false) == 0)6278break;6279fallthrough;6280#endif6281default:6282si_pi->force_pcie_gen = si_get_current_pcie_speed(adev);6283break;6284}6285} else {6286if (target_link_speed < current_link_speed)6287si_pi->pspp_notify_required = true;6288}6289}62906291static void si_notify_link_speed_change_after_state_change(struct amdgpu_device *adev,6292struct amdgpu_ps *amdgpu_new_state,6293struct amdgpu_ps *amdgpu_current_state)6294{6295struct si_power_info *si_pi = si_get_pi(adev);6296enum si_pcie_gen target_link_speed = si_get_maximum_link_speed(adev, amdgpu_new_state);6297u8 request;62986299if (si_pi->pspp_notify_required) {6300if (target_link_speed == SI_PCIE_GEN3)6301request = PCIE_PERF_REQ_PECI_GEN3;6302else if (target_link_speed == SI_PCIE_GEN2)6303request = PCIE_PERF_REQ_PECI_GEN2;6304else6305request = PCIE_PERF_REQ_PECI_GEN1;63066307if ((request == PCIE_PERF_REQ_PECI_GEN1) &&6308(si_get_current_pcie_speed(adev) > 0))6309return;63106311#if defined(CONFIG_ACPI)6312amdgpu_acpi_pcie_performance_request(adev, request, false);6313#endif6314}6315}63166317#if 06318static int si_ds_request(struct amdgpu_device *adev,6319bool ds_status_on, u32 count_write)6320{6321struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);63226323if (eg_pi->sclk_deep_sleep) {6324if (ds_status_on)6325return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_CancelThrottleOVRDSCLKDS) ==6326PPSMC_Result_OK) ?63270 : -EINVAL;6328else6329return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_ThrottleOVRDSCLKDS) ==6330PPSMC_Result_OK) ? 0 : -EINVAL;6331}6332return 0;6333}6334#endif63356336static void si_set_max_cu_value(struct amdgpu_device *adev)6337{6338struct si_power_info *si_pi = si_get_pi(adev);63396340if (adev->asic_type == CHIP_VERDE) {6341switch (adev->pdev->device) {6342case 0x6820:6343case 0x6825:6344case 0x6821:6345case 0x6823:6346case 0x6827:6347si_pi->max_cu = 10;6348break;6349case 0x682D:6350case 0x6824:6351case 0x682F:6352case 0x6826:6353si_pi->max_cu = 8;6354break;6355case 0x6828:6356case 0x6830:6357case 0x6831:6358case 0x6838:6359case 0x6839:6360case 0x683D:6361si_pi->max_cu = 10;6362break;6363case 0x683B:6364case 0x683F:6365case 0x6829:6366si_pi->max_cu = 8;6367break;6368default:6369si_pi->max_cu = 0;6370break;6371}6372} else {6373si_pi->max_cu = 0;6374}6375}63766377static int si_patch_single_dependency_table_based_on_leakage(struct amdgpu_device *adev,6378struct amdgpu_clock_voltage_dependency_table *table)6379{6380u32 i;6381int j;6382u16 leakage_voltage;63836384if (table) {6385for (i = 0; i < table->count; i++) {6386switch (si_get_leakage_voltage_from_leakage_index(adev,6387table->entries[i].v,6388&leakage_voltage)) {6389case 0:6390table->entries[i].v = leakage_voltage;6391break;6392case -EAGAIN:6393return -EINVAL;6394case -EINVAL:6395default:6396break;6397}6398}63996400for (j = (table->count - 2); j >= 0; j--) {6401table->entries[j].v = (table->entries[j].v <= table->entries[j + 1].v) ?6402table->entries[j].v : table->entries[j + 1].v;6403}6404}6405return 0;6406}64076408static int si_patch_dependency_tables_based_on_leakage(struct amdgpu_device *adev)6409{6410int ret = 0;64116412ret = si_patch_single_dependency_table_based_on_leakage(adev,6413&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk);6414if (ret)6415DRM_ERROR("Could not patch vddc_on_sclk leakage table\n");6416ret = si_patch_single_dependency_table_based_on_leakage(adev,6417&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk);6418if (ret)6419DRM_ERROR("Could not patch vddc_on_mclk leakage table\n");6420ret = si_patch_single_dependency_table_based_on_leakage(adev,6421&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk);6422if (ret)6423DRM_ERROR("Could not patch vddci_on_mclk leakage table\n");6424return ret;6425}64266427static void si_set_pcie_lane_width_in_smc(struct amdgpu_device *adev,6428struct amdgpu_ps *amdgpu_new_state,6429struct amdgpu_ps *amdgpu_current_state)6430{6431u32 lane_width;6432u32 new_lane_width =6433((amdgpu_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;6434u32 current_lane_width =6435((amdgpu_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;64366437if (new_lane_width != current_lane_width) {6438amdgpu_set_pcie_lanes(adev, new_lane_width);6439lane_width = amdgpu_get_pcie_lanes(adev);6440si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width, lane_width);6441}6442}64436444static void si_dpm_setup_asic(struct amdgpu_device *adev)6445{6446si_read_clock_registers(adev);6447si_enable_acpi_power_management(adev);6448}64496450static int si_thermal_enable_alert(struct amdgpu_device *adev,6451bool enable)6452{6453u32 thermal_int = RREG32(mmCG_THERMAL_INT);64546455if (enable) {6456PPSMC_Result result;64576458thermal_int &= ~(CG_THERMAL_INT__THERM_INT_MASK_HIGH_MASK | CG_THERMAL_INT__THERM_INT_MASK_LOW_MASK);6459WREG32(mmCG_THERMAL_INT, thermal_int);6460result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableThermalInterrupt);6461if (result != PPSMC_Result_OK) {6462DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");6463return -EINVAL;6464}6465} else {6466thermal_int |= CG_THERMAL_INT__THERM_INT_MASK_HIGH_MASK | CG_THERMAL_INT__THERM_INT_MASK_LOW_MASK;6467WREG32(mmCG_THERMAL_INT, thermal_int);6468}64696470return 0;6471}64726473static int si_thermal_set_temperature_range(struct amdgpu_device *adev,6474int min_temp, int max_temp)6475{6476int low_temp = 0 * 1000;6477int high_temp = 255 * 1000;64786479if (low_temp < min_temp)6480low_temp = min_temp;6481if (high_temp > max_temp)6482high_temp = max_temp;6483if (high_temp < low_temp) {6484DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);6485return -EINVAL;6486}64876488WREG32_P(mmCG_THERMAL_INT, (high_temp / 1000) << CG_THERMAL_INT__DIG_THERM_INTH__SHIFT, ~CG_THERMAL_INT__DIG_THERM_INTH_MASK);6489WREG32_P(mmCG_THERMAL_INT, (low_temp / 1000) << CG_THERMAL_INT__DIG_THERM_INTL__SHIFT, ~CG_THERMAL_INT__DIG_THERM_INTL_MASK);6490WREG32_P(mmCG_THERMAL_CTRL, (high_temp / 1000) << CG_THERMAL_CTRL__DIG_THERM_DPM__SHIFT, ~CG_THERMAL_CTRL__DIG_THERM_DPM_MASK);64916492adev->pm.dpm.thermal.min_temp = low_temp;6493adev->pm.dpm.thermal.max_temp = high_temp;64946495return 0;6496}64976498static void si_fan_ctrl_set_static_mode(struct amdgpu_device *adev, u32 mode)6499{6500struct si_power_info *si_pi = si_get_pi(adev);6501u32 tmp;65026503if (si_pi->fan_ctrl_is_in_default_mode) {6504tmp = (RREG32(mmCG_FDO_CTRL2) & CG_FDO_CTRL2__FDO_PWM_MODE_MASK) >> CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT;6505si_pi->fan_ctrl_default_mode = tmp;6506tmp = (RREG32(mmCG_FDO_CTRL2) & CG_FDO_CTRL2__TMIN_MASK) >> CG_FDO_CTRL2__TMIN__SHIFT;6507si_pi->t_min = tmp;6508si_pi->fan_ctrl_is_in_default_mode = false;6509}65106511tmp = RREG32(mmCG_FDO_CTRL2) & ~CG_FDO_CTRL2__TMIN_MASK;6512tmp |= 0 << CG_FDO_CTRL2__TMIN__SHIFT;6513WREG32(mmCG_FDO_CTRL2, tmp);65146515tmp = RREG32(mmCG_FDO_CTRL2) & ~CG_FDO_CTRL2__FDO_PWM_MODE_MASK;6516tmp |= mode << CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT;6517WREG32(mmCG_FDO_CTRL2, tmp);6518}65196520static int si_thermal_setup_fan_table(struct amdgpu_device *adev)6521{6522struct si_power_info *si_pi = si_get_pi(adev);6523PP_SIslands_FanTable fan_table = { FDO_MODE_HARDWARE };6524u32 duty100;6525u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2;6526u16 fdo_min, slope1, slope2;6527u32 reference_clock, tmp;6528int ret;6529u64 tmp64;65306531if (!si_pi->fan_table_start) {6532adev->pm.dpm.fan.ucode_fan_control = false;6533return 0;6534}65356536duty100 = (RREG32(mmCG_FDO_CTRL1) & CG_FDO_CTRL1__FMAX_DUTY100_MASK) >> CG_FDO_CTRL1__FMAX_DUTY100__SHIFT;65376538if (duty100 == 0) {6539adev->pm.dpm.fan.ucode_fan_control = false;6540return 0;6541}65426543tmp64 = (u64)adev->pm.dpm.fan.pwm_min * duty100;6544do_div(tmp64, 10000);6545fdo_min = (u16)tmp64;65466547t_diff1 = adev->pm.dpm.fan.t_med - adev->pm.dpm.fan.t_min;6548t_diff2 = adev->pm.dpm.fan.t_high - adev->pm.dpm.fan.t_med;65496550pwm_diff1 = adev->pm.dpm.fan.pwm_med - adev->pm.dpm.fan.pwm_min;6551pwm_diff2 = adev->pm.dpm.fan.pwm_high - adev->pm.dpm.fan.pwm_med;65526553slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);6554slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);65556556fan_table.temp_min = cpu_to_be16((50 + adev->pm.dpm.fan.t_min) / 100);6557fan_table.temp_med = cpu_to_be16((50 + adev->pm.dpm.fan.t_med) / 100);6558fan_table.temp_max = cpu_to_be16((50 + adev->pm.dpm.fan.t_max) / 100);6559fan_table.slope1 = cpu_to_be16(slope1);6560fan_table.slope2 = cpu_to_be16(slope2);6561fan_table.fdo_min = cpu_to_be16(fdo_min);6562fan_table.hys_down = cpu_to_be16(adev->pm.dpm.fan.t_hyst);6563fan_table.hys_up = cpu_to_be16(1);6564fan_table.hys_slope = cpu_to_be16(1);6565fan_table.temp_resp_lim = cpu_to_be16(5);6566reference_clock = amdgpu_asic_get_xclk(adev);65676568fan_table.refresh_period = cpu_to_be32((adev->pm.dpm.fan.cycle_delay *6569reference_clock) / 1600);6570fan_table.fdo_max = cpu_to_be16((u16)duty100);65716572tmp = (RREG32(mmCG_MULT_THERMAL_CTRL) & CG_MULT_THERMAL_CTRL__TEMP_SEL_MASK) >> CG_MULT_THERMAL_CTRL__TEMP_SEL__SHIFT;6573fan_table.temp_src = (uint8_t)tmp;65746575ret = amdgpu_si_copy_bytes_to_smc(adev,6576si_pi->fan_table_start,6577(u8 *)(&fan_table),6578sizeof(fan_table),6579si_pi->sram_end);65806581if (ret) {6582DRM_ERROR("Failed to load fan table to the SMC.");6583adev->pm.dpm.fan.ucode_fan_control = false;6584}65856586return ret;6587}65886589static int si_fan_ctrl_start_smc_fan_control(struct amdgpu_device *adev)6590{6591struct si_power_info *si_pi = si_get_pi(adev);6592PPSMC_Result ret;65936594ret = amdgpu_si_send_msg_to_smc(adev, PPSMC_StartFanControl);6595if (ret == PPSMC_Result_OK) {6596si_pi->fan_is_controlled_by_smc = true;6597return 0;6598} else {6599return -EINVAL;6600}6601}66026603static int si_fan_ctrl_stop_smc_fan_control(struct amdgpu_device *adev)6604{6605struct si_power_info *si_pi = si_get_pi(adev);6606PPSMC_Result ret;66076608ret = amdgpu_si_send_msg_to_smc(adev, PPSMC_StopFanControl);66096610if (ret == PPSMC_Result_OK) {6611si_pi->fan_is_controlled_by_smc = false;6612return 0;6613} else {6614return -EINVAL;6615}6616}66176618static int si_dpm_get_fan_speed_pwm(void *handle,6619u32 *speed)6620{6621u32 duty, duty100;6622u64 tmp64;6623struct amdgpu_device *adev = (struct amdgpu_device *)handle;66246625if (!speed)6626return -EINVAL;66276628if (adev->pm.no_fan)6629return -ENOENT;66306631duty100 = (RREG32(mmCG_FDO_CTRL1) & CG_FDO_CTRL1__FMAX_DUTY100_MASK) >> CG_FDO_CTRL1__FMAX_DUTY100__SHIFT;6632duty = (RREG32(mmCG_THERMAL_STATUS) & CG_THERMAL_STATUS__FDO_PWM_DUTY_MASK) >> CG_THERMAL_STATUS__FDO_PWM_DUTY__SHIFT;66336634if (duty100 == 0)6635return -EINVAL;66366637tmp64 = (u64)duty * 255;6638do_div(tmp64, duty100);6639*speed = min_t(u32, tmp64, 255);66406641return 0;6642}66436644static int si_dpm_set_fan_speed_pwm(void *handle,6645u32 speed)6646{6647struct amdgpu_device *adev = (struct amdgpu_device *)handle;6648struct si_power_info *si_pi = si_get_pi(adev);6649u32 tmp;6650u32 duty, duty100;6651u64 tmp64;66526653if (adev->pm.no_fan)6654return -ENOENT;66556656if (si_pi->fan_is_controlled_by_smc)6657return -EINVAL;66586659if (speed > 255)6660return -EINVAL;66616662duty100 = (RREG32(mmCG_FDO_CTRL1) & CG_FDO_CTRL1__FMAX_DUTY100_MASK) >> CG_FDO_CTRL1__FMAX_DUTY100__SHIFT;66636664if (duty100 == 0)6665return -EINVAL;66666667tmp64 = (u64)speed * duty100;6668do_div(tmp64, 255);6669duty = (u32)tmp64;66706671tmp = RREG32(mmCG_FDO_CTRL0) & ~CG_FDO_CTRL0__FDO_STATIC_DUTY_MASK;6672tmp |= duty << CG_FDO_CTRL0__FDO_STATIC_DUTY__SHIFT;6673WREG32(mmCG_FDO_CTRL0, tmp);66746675return 0;6676}66776678static int si_dpm_set_fan_control_mode(void *handle, u32 mode)6679{6680struct amdgpu_device *adev = (struct amdgpu_device *)handle;66816682if (mode == U32_MAX)6683return -EINVAL;66846685if (mode) {6686/* stop auto-manage */6687if (adev->pm.dpm.fan.ucode_fan_control)6688si_fan_ctrl_stop_smc_fan_control(adev);6689si_fan_ctrl_set_static_mode(adev, mode);6690} else {6691/* restart auto-manage */6692if (adev->pm.dpm.fan.ucode_fan_control)6693si_thermal_start_smc_fan_control(adev);6694else6695si_fan_ctrl_set_default_mode(adev);6696}66976698return 0;6699}67006701static int si_dpm_get_fan_control_mode(void *handle, u32 *fan_mode)6702{6703struct amdgpu_device *adev = (struct amdgpu_device *)handle;6704struct si_power_info *si_pi = si_get_pi(adev);6705u32 tmp;67066707if (!fan_mode)6708return -EINVAL;67096710if (si_pi->fan_is_controlled_by_smc)6711return 0;67126713tmp = RREG32(mmCG_FDO_CTRL2) & CG_FDO_CTRL2__FDO_PWM_MODE_MASK;6714*fan_mode = (tmp >> CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT);67156716return 0;6717}67186719#if 06720static int si_fan_ctrl_get_fan_speed_rpm(struct amdgpu_device *adev,6721u32 *speed)6722{6723u32 tach_period;6724u32 xclk = amdgpu_asic_get_xclk(adev);67256726if (adev->pm.no_fan)6727return -ENOENT;67286729if (adev->pm.fan_pulses_per_revolution == 0)6730return -ENOENT;67316732tach_period = (RREG32(mmCG_TACH_STATUS) & CG_TACH_STATUS__TACH_PERIOD_MASK) >> CG_TACH_STATUS__TACH_PERIOD__SHIFT;6733if (tach_period == 0)6734return -ENOENT;67356736*speed = 60 * xclk * 10000 / tach_period;67376738return 0;6739}67406741static int si_fan_ctrl_set_fan_speed_rpm(struct amdgpu_device *adev,6742u32 speed)6743{6744u32 tach_period, tmp;6745u32 xclk = amdgpu_asic_get_xclk(adev);67466747if (adev->pm.no_fan)6748return -ENOENT;67496750if (adev->pm.fan_pulses_per_revolution == 0)6751return -ENOENT;67526753if ((speed < adev->pm.fan_min_rpm) ||6754(speed > adev->pm.fan_max_rpm))6755return -EINVAL;67566757if (adev->pm.dpm.fan.ucode_fan_control)6758si_fan_ctrl_stop_smc_fan_control(adev);67596760tach_period = 60 * xclk * 10000 / (8 * speed);6761tmp = RREG32(mmCG_TACH_CTRL) & ~CG_TACH_CTRL__TARGET_PERIOD_MASK;6762tmp |= tach_period << CG_TACH_CTRL__TARGET_PERIOD__SHIFT;6763WREG32(mmCG_TACH_CTRL, tmp);67646765si_fan_ctrl_set_static_mode(adev, FDO_PWM_MODE_STATIC_RPM);67666767return 0;6768}6769#endif67706771static void si_fan_ctrl_set_default_mode(struct amdgpu_device *adev)6772{6773struct si_power_info *si_pi = si_get_pi(adev);6774u32 tmp;67756776if (!si_pi->fan_ctrl_is_in_default_mode) {6777tmp = RREG32(mmCG_FDO_CTRL2) & ~CG_FDO_CTRL2__FDO_PWM_MODE_MASK;6778tmp |= si_pi->fan_ctrl_default_mode << CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT;6779WREG32(mmCG_FDO_CTRL2, tmp);67806781tmp = RREG32(mmCG_FDO_CTRL2) & ~CG_FDO_CTRL2__TMIN_MASK;6782tmp |= si_pi->t_min << CG_FDO_CTRL2__TMIN__SHIFT;6783WREG32(mmCG_FDO_CTRL2, tmp);6784si_pi->fan_ctrl_is_in_default_mode = true;6785}6786}67876788static void si_thermal_start_smc_fan_control(struct amdgpu_device *adev)6789{6790if (adev->pm.dpm.fan.ucode_fan_control) {6791si_fan_ctrl_start_smc_fan_control(adev);6792si_fan_ctrl_set_static_mode(adev, FDO_PWM_MODE_STATIC);6793}6794}67956796static void si_thermal_initialize(struct amdgpu_device *adev)6797{6798u32 tmp;67996800if (adev->pm.fan_pulses_per_revolution) {6801tmp = RREG32(mmCG_TACH_CTRL) & ~CG_TACH_CTRL__EDGE_PER_REV_MASK;6802tmp |= (adev->pm.fan_pulses_per_revolution -1) << CG_TACH_CTRL__EDGE_PER_REV__SHIFT;6803WREG32(mmCG_TACH_CTRL, tmp);6804}68056806tmp = RREG32(mmCG_FDO_CTRL2) & ~CG_FDO_CTRL2__TACH_PWM_RESP_RATE_MASK;6807tmp |= 0x28 << CG_FDO_CTRL2__TACH_PWM_RESP_RATE__SHIFT;6808WREG32(mmCG_FDO_CTRL2, tmp);6809}68106811static int si_thermal_start_thermal_controller(struct amdgpu_device *adev)6812{6813int ret;68146815si_thermal_initialize(adev);6816ret = si_thermal_set_temperature_range(adev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);6817if (ret)6818return ret;6819ret = si_thermal_enable_alert(adev, true);6820if (ret)6821return ret;6822if (adev->pm.dpm.fan.ucode_fan_control) {6823ret = si_halt_smc(adev);6824if (ret)6825return ret;6826ret = si_thermal_setup_fan_table(adev);6827if (ret)6828return ret;6829ret = si_resume_smc(adev);6830if (ret)6831return ret;6832si_thermal_start_smc_fan_control(adev);6833}68346835return 0;6836}68376838static void si_thermal_stop_thermal_controller(struct amdgpu_device *adev)6839{6840if (!adev->pm.no_fan) {6841si_fan_ctrl_set_default_mode(adev);6842si_fan_ctrl_stop_smc_fan_control(adev);6843}6844}68456846static int si_dpm_enable(struct amdgpu_device *adev)6847{6848struct rv7xx_power_info *pi = rv770_get_pi(adev);6849struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);6850struct si_power_info *si_pi = si_get_pi(adev);6851struct amdgpu_ps *boot_ps = adev->pm.dpm.boot_ps;6852int ret;68536854if (amdgpu_si_is_smc_running(adev))6855return -EINVAL;6856if (pi->voltage_control || si_pi->voltage_control_svi2)6857si_enable_voltage_control(adev, true);6858if (pi->mvdd_control)6859si_get_mvdd_configuration(adev);6860if (pi->voltage_control || si_pi->voltage_control_svi2) {6861ret = si_construct_voltage_tables(adev);6862if (ret) {6863DRM_ERROR("si_construct_voltage_tables failed\n");6864return ret;6865}6866}6867if (eg_pi->dynamic_ac_timing) {6868ret = si_initialize_mc_reg_table(adev);6869if (ret)6870eg_pi->dynamic_ac_timing = false;6871}6872if (pi->dynamic_ss)6873si_enable_spread_spectrum(adev, true);6874if (pi->thermal_protection)6875si_enable_thermal_protection(adev, true);6876si_setup_bsp(adev);6877si_program_git(adev);6878si_program_tp(adev);6879si_program_tpp(adev);6880si_program_sstp(adev);6881si_enable_display_gap(adev);6882si_program_vc(adev);6883ret = si_upload_firmware(adev);6884if (ret) {6885DRM_ERROR("si_upload_firmware failed\n");6886return ret;6887}6888ret = si_process_firmware_header(adev);6889if (ret) {6890DRM_ERROR("si_process_firmware_header failed\n");6891return ret;6892}6893ret = si_initial_switch_from_arb_f0_to_f1(adev);6894if (ret) {6895DRM_ERROR("si_initial_switch_from_arb_f0_to_f1 failed\n");6896return ret;6897}6898ret = si_init_smc_table(adev);6899if (ret) {6900DRM_ERROR("si_init_smc_table failed\n");6901return ret;6902}6903ret = si_init_smc_spll_table(adev);6904if (ret) {6905DRM_ERROR("si_init_smc_spll_table failed\n");6906return ret;6907}6908ret = si_init_arb_table_index(adev);6909if (ret) {6910DRM_ERROR("si_init_arb_table_index failed\n");6911return ret;6912}6913if (eg_pi->dynamic_ac_timing) {6914ret = si_populate_mc_reg_table(adev, boot_ps);6915if (ret) {6916DRM_ERROR("si_populate_mc_reg_table failed\n");6917return ret;6918}6919}6920ret = si_initialize_smc_cac_tables(adev);6921if (ret) {6922DRM_ERROR("si_initialize_smc_cac_tables failed\n");6923return ret;6924}6925ret = si_initialize_hardware_cac_manager(adev);6926if (ret) {6927DRM_ERROR("si_initialize_hardware_cac_manager failed\n");6928return ret;6929}6930ret = si_initialize_smc_dte_tables(adev);6931if (ret) {6932DRM_ERROR("si_initialize_smc_dte_tables failed\n");6933return ret;6934}6935ret = si_populate_smc_tdp_limits(adev, boot_ps);6936if (ret) {6937DRM_ERROR("si_populate_smc_tdp_limits failed\n");6938return ret;6939}6940ret = si_populate_smc_tdp_limits_2(adev, boot_ps);6941if (ret) {6942DRM_ERROR("si_populate_smc_tdp_limits_2 failed\n");6943return ret;6944}6945si_program_response_times(adev);6946si_program_ds_registers(adev);6947si_dpm_start_smc(adev);6948ret = si_notify_smc_display_change(adev, false);6949if (ret) {6950DRM_ERROR("si_notify_smc_display_change failed\n");6951return ret;6952}6953si_enable_sclk_control(adev, true);6954si_start_dpm(adev);69556956si_enable_auto_throttle_source(adev, SI_DPM_AUTO_THROTTLE_SRC_THERMAL, true);6957si_thermal_start_thermal_controller(adev);69586959ni_update_current_ps(adev, boot_ps);69606961return 0;6962}69636964static int si_set_temperature_range(struct amdgpu_device *adev)6965{6966int ret;69676968ret = si_thermal_enable_alert(adev, false);6969if (ret)6970return ret;6971ret = si_thermal_set_temperature_range(adev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);6972if (ret)6973return ret;6974ret = si_thermal_enable_alert(adev, true);6975if (ret)6976return ret;69776978return ret;6979}69806981static void si_dpm_disable(struct amdgpu_device *adev)6982{6983struct rv7xx_power_info *pi = rv770_get_pi(adev);6984struct amdgpu_ps *boot_ps = adev->pm.dpm.boot_ps;69856986if (!amdgpu_si_is_smc_running(adev))6987return;6988si_thermal_stop_thermal_controller(adev);6989si_disable_ulv(adev);6990si_clear_vc(adev);6991if (pi->thermal_protection)6992si_enable_thermal_protection(adev, false);6993si_enable_power_containment(adev, boot_ps, false);6994si_enable_smc_cac(adev, boot_ps, false);6995si_enable_spread_spectrum(adev, false);6996si_enable_auto_throttle_source(adev, SI_DPM_AUTO_THROTTLE_SRC_THERMAL, false);6997si_stop_dpm(adev);6998si_reset_to_default(adev);6999si_dpm_stop_smc(adev);7000si_force_switch_to_arb_f0(adev);70017002ni_update_current_ps(adev, boot_ps);7003}70047005static int si_dpm_pre_set_power_state(void *handle)7006{7007struct amdgpu_device *adev = (struct amdgpu_device *)handle;7008struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7009struct amdgpu_ps requested_ps = *adev->pm.dpm.requested_ps;7010struct amdgpu_ps *new_ps = &requested_ps;70117012ni_update_requested_ps(adev, new_ps);7013si_apply_state_adjust_rules(adev, &eg_pi->requested_rps);70147015return 0;7016}70177018static int si_power_control_set_level(struct amdgpu_device *adev)7019{7020struct amdgpu_ps *new_ps = adev->pm.dpm.requested_ps;7021int ret;70227023ret = si_restrict_performance_levels_before_switch(adev);7024if (ret)7025return ret;7026ret = si_halt_smc(adev);7027if (ret)7028return ret;7029ret = si_populate_smc_tdp_limits(adev, new_ps);7030if (ret)7031return ret;7032ret = si_populate_smc_tdp_limits_2(adev, new_ps);7033if (ret)7034return ret;7035ret = si_resume_smc(adev);7036if (ret)7037return ret;7038return si_set_sw_state(adev);7039}70407041static void si_set_vce_clock(struct amdgpu_device *adev,7042struct amdgpu_ps *new_rps,7043struct amdgpu_ps *old_rps)7044{7045if ((old_rps->evclk != new_rps->evclk) ||7046(old_rps->ecclk != new_rps->ecclk)) {7047/* Turn the clocks on when encoding, off otherwise */7048if (new_rps->evclk || new_rps->ecclk) {7049/* Place holder for future VCE1.0 porting to amdgpu7050vce_v1_0_enable_mgcg(adev, false, false);*/7051} else {7052/* Place holder for future VCE1.0 porting to amdgpu7053vce_v1_0_enable_mgcg(adev, true, false);7054amdgpu_asic_set_vce_clocks(adev, new_rps->evclk, new_rps->ecclk);*/7055}7056}7057}70587059static int si_dpm_set_power_state(void *handle)7060{7061struct amdgpu_device *adev = (struct amdgpu_device *)handle;7062struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7063struct amdgpu_ps *new_ps = &eg_pi->requested_rps;7064struct amdgpu_ps *old_ps = &eg_pi->current_rps;7065int ret;70667067ret = si_disable_ulv(adev);7068if (ret) {7069DRM_ERROR("si_disable_ulv failed\n");7070return ret;7071}7072ret = si_restrict_performance_levels_before_switch(adev);7073if (ret) {7074DRM_ERROR("si_restrict_performance_levels_before_switch failed\n");7075return ret;7076}7077if (eg_pi->pcie_performance_request)7078si_request_link_speed_change_before_state_change(adev, new_ps, old_ps);7079ni_set_uvd_clock_before_set_eng_clock(adev, new_ps, old_ps);7080ret = si_enable_power_containment(adev, new_ps, false);7081if (ret) {7082DRM_ERROR("si_enable_power_containment failed\n");7083return ret;7084}7085ret = si_enable_smc_cac(adev, new_ps, false);7086if (ret) {7087DRM_ERROR("si_enable_smc_cac failed\n");7088return ret;7089}7090ret = si_halt_smc(adev);7091if (ret) {7092DRM_ERROR("si_halt_smc failed\n");7093return ret;7094}7095ret = si_upload_sw_state(adev, new_ps);7096if (ret) {7097DRM_ERROR("si_upload_sw_state failed\n");7098return ret;7099}7100ret = si_upload_smc_data(adev);7101if (ret) {7102DRM_ERROR("si_upload_smc_data failed\n");7103return ret;7104}7105ret = si_upload_ulv_state(adev);7106if (ret) {7107DRM_ERROR("si_upload_ulv_state failed\n");7108return ret;7109}7110if (eg_pi->dynamic_ac_timing) {7111ret = si_upload_mc_reg_table(adev, new_ps);7112if (ret) {7113DRM_ERROR("si_upload_mc_reg_table failed\n");7114return ret;7115}7116}7117ret = si_program_memory_timing_parameters(adev, new_ps);7118if (ret) {7119DRM_ERROR("si_program_memory_timing_parameters failed\n");7120return ret;7121}7122si_set_pcie_lane_width_in_smc(adev, new_ps, old_ps);71237124ret = si_resume_smc(adev);7125if (ret) {7126DRM_ERROR("si_resume_smc failed\n");7127return ret;7128}7129ret = si_set_sw_state(adev);7130if (ret) {7131DRM_ERROR("si_set_sw_state failed\n");7132return ret;7133}7134ni_set_uvd_clock_after_set_eng_clock(adev, new_ps, old_ps);7135si_set_vce_clock(adev, new_ps, old_ps);7136if (eg_pi->pcie_performance_request)7137si_notify_link_speed_change_after_state_change(adev, new_ps, old_ps);7138ret = si_set_power_state_conditionally_enable_ulv(adev, new_ps);7139if (ret) {7140DRM_ERROR("si_set_power_state_conditionally_enable_ulv failed\n");7141return ret;7142}7143ret = si_enable_smc_cac(adev, new_ps, true);7144if (ret) {7145DRM_ERROR("si_enable_smc_cac failed\n");7146return ret;7147}7148ret = si_enable_power_containment(adev, new_ps, true);7149if (ret) {7150DRM_ERROR("si_enable_power_containment failed\n");7151return ret;7152}71537154ret = si_power_control_set_level(adev);7155if (ret) {7156DRM_ERROR("si_power_control_set_level failed\n");7157return ret;7158}71597160return 0;7161}71627163static void si_dpm_post_set_power_state(void *handle)7164{7165struct amdgpu_device *adev = (struct amdgpu_device *)handle;7166struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7167struct amdgpu_ps *new_ps = &eg_pi->requested_rps;71687169ni_update_current_ps(adev, new_ps);7170}71717172#if 07173void si_dpm_reset_asic(struct amdgpu_device *adev)7174{7175si_restrict_performance_levels_before_switch(adev);7176si_disable_ulv(adev);7177si_set_boot_state(adev);7178}7179#endif71807181static void si_dpm_display_configuration_changed(void *handle)7182{7183struct amdgpu_device *adev = (struct amdgpu_device *)handle;71847185si_program_display_gap(adev);7186}718771887189static void si_parse_pplib_non_clock_info(struct amdgpu_device *adev,7190struct amdgpu_ps *rps,7191struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,7192u8 table_rev)7193{7194rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);7195rps->class = le16_to_cpu(non_clock_info->usClassification);7196rps->class2 = le16_to_cpu(non_clock_info->usClassification2);71977198if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {7199rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);7200rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);7201} else if (r600_is_uvd_state(rps->class, rps->class2)) {7202rps->vclk = RV770_DEFAULT_VCLK_FREQ;7203rps->dclk = RV770_DEFAULT_DCLK_FREQ;7204} else {7205rps->vclk = 0;7206rps->dclk = 0;7207}72087209if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)7210adev->pm.dpm.boot_ps = rps;7211if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)7212adev->pm.dpm.uvd_ps = rps;7213}72147215static void si_parse_pplib_clock_info(struct amdgpu_device *adev,7216struct amdgpu_ps *rps, int index,7217union pplib_clock_info *clock_info)7218{7219struct rv7xx_power_info *pi = rv770_get_pi(adev);7220struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7221struct si_power_info *si_pi = si_get_pi(adev);7222struct si_ps *ps = si_get_ps(rps);7223u16 leakage_voltage;7224struct rv7xx_pl *pl = &ps->performance_levels[index];7225int ret;72267227ps->performance_level_count = index + 1;72287229pl->sclk = le16_to_cpu(clock_info->si.usEngineClockLow);7230pl->sclk |= clock_info->si.ucEngineClockHigh << 16;7231pl->mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);7232pl->mclk |= clock_info->si.ucMemoryClockHigh << 16;72337234pl->vddc = le16_to_cpu(clock_info->si.usVDDC);7235pl->vddci = le16_to_cpu(clock_info->si.usVDDCI);7236pl->flags = le32_to_cpu(clock_info->si.ulFlags);7237pl->pcie_gen = si_gen_pcie_gen_support(adev,7238si_pi->sys_pcie_mask,7239si_pi->boot_pcie_gen,7240clock_info->si.ucPCIEGen);72417242/* patch up vddc if necessary */7243ret = si_get_leakage_voltage_from_leakage_index(adev, pl->vddc,7244&leakage_voltage);7245if (ret == 0)7246pl->vddc = leakage_voltage;72477248if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {7249pi->acpi_vddc = pl->vddc;7250eg_pi->acpi_vddci = pl->vddci;7251si_pi->acpi_pcie_gen = pl->pcie_gen;7252}72537254if ((rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) &&7255index == 0) {7256/* XXX disable for A0 tahiti */7257si_pi->ulv.supported = false;7258si_pi->ulv.pl = *pl;7259si_pi->ulv.one_pcie_lane_in_ulv = false;7260si_pi->ulv.volt_change_delay = SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT;7261si_pi->ulv.cg_ulv_parameter = SISLANDS_CGULVPARAMETER_DFLT;7262si_pi->ulv.cg_ulv_control = SISLANDS_CGULVCONTROL_DFLT;7263}72647265if (pi->min_vddc_in_table > pl->vddc)7266pi->min_vddc_in_table = pl->vddc;72677268if (pi->max_vddc_in_table < pl->vddc)7269pi->max_vddc_in_table = pl->vddc;72707271/* patch up boot state */7272if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {7273u16 vddc, vddci, mvdd;7274amdgpu_atombios_get_default_voltages(adev, &vddc, &vddci, &mvdd);7275pl->mclk = adev->clock.default_mclk;7276pl->sclk = adev->clock.default_sclk;7277pl->vddc = vddc;7278pl->vddci = vddci;7279si_pi->mvdd_bootup_value = mvdd;7280}72817282if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==7283ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {7284adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk;7285adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk;7286adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc;7287adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci;7288}7289}72907291union pplib_power_state {7292struct _ATOM_PPLIB_STATE v1;7293struct _ATOM_PPLIB_STATE_V2 v2;7294};72957296static int si_parse_power_table(struct amdgpu_device *adev)7297{7298struct amdgpu_mode_info *mode_info = &adev->mode_info;7299struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;7300union pplib_power_state *power_state;7301int i, j, k, non_clock_array_index, clock_array_index;7302union pplib_clock_info *clock_info;7303struct _StateArray *state_array;7304struct _ClockInfoArray *clock_info_array;7305struct _NonClockInfoArray *non_clock_info_array;7306union power_info *power_info;7307int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);7308u16 data_offset;7309u8 frev, crev;7310u8 *power_state_offset;7311struct si_ps *ps;73127313if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,7314&frev, &crev, &data_offset))7315return -EINVAL;7316power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);73177318amdgpu_add_thermal_controller(adev);73197320state_array = (struct _StateArray *)7321(mode_info->atom_context->bios + data_offset +7322le16_to_cpu(power_info->pplib.usStateArrayOffset));7323clock_info_array = (struct _ClockInfoArray *)7324(mode_info->atom_context->bios + data_offset +7325le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));7326non_clock_info_array = (struct _NonClockInfoArray *)7327(mode_info->atom_context->bios + data_offset +7328le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));73297330adev->pm.dpm.ps = kcalloc(state_array->ucNumEntries,7331sizeof(struct amdgpu_ps),7332GFP_KERNEL);7333if (!adev->pm.dpm.ps)7334return -ENOMEM;7335power_state_offset = (u8 *)state_array->states;7336for (adev->pm.dpm.num_ps = 0, i = 0; i < state_array->ucNumEntries; i++) {7337u8 *idx;7338power_state = (union pplib_power_state *)power_state_offset;7339non_clock_array_index = power_state->v2.nonClockInfoIndex;7340non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)7341&non_clock_info_array->nonClockInfo[non_clock_array_index];7342ps = kzalloc(sizeof(struct si_ps), GFP_KERNEL);7343if (ps == NULL)7344return -ENOMEM;7345adev->pm.dpm.ps[i].ps_priv = ps;7346si_parse_pplib_non_clock_info(adev, &adev->pm.dpm.ps[i],7347non_clock_info,7348non_clock_info_array->ucEntrySize);7349k = 0;7350idx = (u8 *)&power_state->v2.clockInfoIndex[0];7351for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {7352clock_array_index = idx[j];7353if (clock_array_index >= clock_info_array->ucNumEntries)7354continue;7355if (k >= SISLANDS_MAX_HARDWARE_POWERLEVELS)7356break;7357clock_info = (union pplib_clock_info *)7358((u8 *)&clock_info_array->clockInfo[0] +7359(clock_array_index * clock_info_array->ucEntrySize));7360si_parse_pplib_clock_info(adev,7361&adev->pm.dpm.ps[i], k,7362clock_info);7363k++;7364}7365power_state_offset += 2 + power_state->v2.ucNumDPMLevels;7366adev->pm.dpm.num_ps++;7367}73687369/* fill in the vce power states */7370for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) {7371u32 sclk, mclk;7372clock_array_index = adev->pm.dpm.vce_states[i].clk_idx;7373clock_info = (union pplib_clock_info *)7374&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];7375sclk = le16_to_cpu(clock_info->si.usEngineClockLow);7376sclk |= clock_info->si.ucEngineClockHigh << 16;7377mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);7378mclk |= clock_info->si.ucMemoryClockHigh << 16;7379adev->pm.dpm.vce_states[i].sclk = sclk;7380adev->pm.dpm.vce_states[i].mclk = mclk;7381}73827383return 0;7384}73857386static int si_dpm_init(struct amdgpu_device *adev)7387{7388struct rv7xx_power_info *pi;7389struct evergreen_power_info *eg_pi;7390struct ni_power_info *ni_pi;7391struct si_power_info *si_pi;7392struct atom_clock_dividers dividers;7393int ret;73947395si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL);7396if (si_pi == NULL)7397return -ENOMEM;7398adev->pm.dpm.priv = si_pi;7399ni_pi = &si_pi->ni;7400eg_pi = &ni_pi->eg;7401pi = &eg_pi->rv7xx;74027403si_pi->sys_pcie_mask =7404adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK;7405si_pi->force_pcie_gen = SI_PCIE_GEN_INVALID;7406si_pi->boot_pcie_gen = si_get_current_pcie_speed(adev);74077408si_set_max_cu_value(adev);74097410rv770_get_max_vddc(adev);7411si_get_leakage_vddc(adev);7412si_patch_dependency_tables_based_on_leakage(adev);74137414pi->acpi_vddc = 0;7415eg_pi->acpi_vddci = 0;7416pi->min_vddc_in_table = 0;7417pi->max_vddc_in_table = 0;74187419ret = amdgpu_get_platform_caps(adev);7420if (ret)7421return ret;74227423ret = amdgpu_parse_extended_power_table(adev);7424if (ret)7425return ret;74267427ret = si_parse_power_table(adev);7428if (ret)7429return ret;74307431adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =7432kcalloc(4,7433sizeof(struct amdgpu_clock_voltage_dependency_entry),7434GFP_KERNEL);7435if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries)7436return -ENOMEM;74377438adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;7439adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;7440adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;7441adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;7442adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 720;7443adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;7444adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 810;7445adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;7446adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 900;74477448if (adev->pm.dpm.voltage_response_time == 0)7449adev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;7450if (adev->pm.dpm.backbias_response_time == 0)7451adev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;74527453ret = amdgpu_atombios_get_clock_dividers(adev, COMPUTE_ENGINE_PLL_PARAM,74540, false, ÷rs);7455if (ret)7456pi->ref_div = dividers.ref_div + 1;7457else7458pi->ref_div = R600_REFERENCEDIVIDER_DFLT;74597460eg_pi->smu_uvd_hs = false;74617462pi->mclk_strobe_mode_threshold = 40000;7463if (si_is_special_1gb_platform(adev))7464pi->mclk_stutter_mode_threshold = 0;7465else7466pi->mclk_stutter_mode_threshold = pi->mclk_strobe_mode_threshold;7467pi->mclk_edc_enable_threshold = 40000;7468eg_pi->mclk_edc_wr_enable_threshold = 40000;74697470ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold;74717472pi->voltage_control =7473amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,7474VOLTAGE_OBJ_GPIO_LUT);7475if (!pi->voltage_control) {7476si_pi->voltage_control_svi2 =7477amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,7478VOLTAGE_OBJ_SVID2);7479if (si_pi->voltage_control_svi2)7480amdgpu_atombios_get_svi2_info(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,7481&si_pi->svd_gpio_id, &si_pi->svc_gpio_id);7482}74837484pi->mvdd_control =7485amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_MVDDC,7486VOLTAGE_OBJ_GPIO_LUT);74877488eg_pi->vddci_control =7489amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDCI,7490VOLTAGE_OBJ_GPIO_LUT);7491if (!eg_pi->vddci_control)7492si_pi->vddci_control_svi2 =7493amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDCI,7494VOLTAGE_OBJ_SVID2);74957496si_pi->vddc_phase_shed_control =7497amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,7498VOLTAGE_OBJ_PHASE_LUT);74997500rv770_get_engine_memory_ss(adev);75017502pi->asi = RV770_ASI_DFLT;7503pi->pasi = CYPRESS_HASI_DFLT;7504pi->vrc = SISLANDS_VRC_DFLT;75057506pi->gfx_clock_gating = true;75077508eg_pi->sclk_deep_sleep = true;7509si_pi->sclk_deep_sleep_above_low = false;75107511if (adev->pm.int_thermal_type != THERMAL_TYPE_NONE)7512pi->thermal_protection = true;7513else7514pi->thermal_protection = false;75157516eg_pi->dynamic_ac_timing = true;75177518eg_pi->light_sleep = true;7519#if defined(CONFIG_ACPI)7520eg_pi->pcie_performance_request =7521amdgpu_acpi_is_pcie_performance_request_supported(adev);7522#else7523eg_pi->pcie_performance_request = false;7524#endif75257526si_pi->sram_end = SMC_RAM_END;75277528adev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;7529adev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;7530adev->pm.dpm.dyn_state.vddc_vddci_delta = 200;7531adev->pm.dpm.dyn_state.valid_sclk_values.count = 0;7532adev->pm.dpm.dyn_state.valid_sclk_values.values = NULL;7533adev->pm.dpm.dyn_state.valid_mclk_values.count = 0;7534adev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;75357536si_initialize_powertune_defaults(adev);75377538/* make sure dc limits are valid */7539if ((adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk == 0) ||7540(adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk == 0))7541adev->pm.dpm.dyn_state.max_clock_voltage_on_dc =7542adev->pm.dpm.dyn_state.max_clock_voltage_on_ac;75437544si_pi->fan_ctrl_is_in_default_mode = true;75457546return 0;7547}75487549static void si_dpm_fini(struct amdgpu_device *adev)7550{7551int i;75527553if (adev->pm.dpm.ps)7554for (i = 0; i < adev->pm.dpm.num_ps; i++)7555kfree(adev->pm.dpm.ps[i].ps_priv);7556kfree(adev->pm.dpm.ps);7557kfree(adev->pm.dpm.priv);7558kfree(adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);7559amdgpu_free_extended_power_table(adev);7560}75617562static void si_dpm_debugfs_print_current_performance_level(void *handle,7563struct seq_file *m)7564{7565struct amdgpu_device *adev = (struct amdgpu_device *)handle;7566struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7567struct amdgpu_ps *rps = &eg_pi->current_rps;7568struct si_ps *ps = si_get_ps(rps);7569struct rv7xx_pl *pl;7570u32 current_index =7571(RREG32(mmTARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_AND_CURRENT_PROFILE_INDEX__CURRENT_STATE_INDEX_MASK) >>7572TARGET_AND_CURRENT_PROFILE_INDEX__CURRENT_STATE_INDEX__SHIFT;75737574if (current_index >= ps->performance_level_count) {7575seq_printf(m, "invalid dpm profile %d\n", current_index);7576} else {7577pl = &ps->performance_levels[current_index];7578seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);7579seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",7580current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);7581}7582}75837584static int si_dpm_set_interrupt_state(struct amdgpu_device *adev,7585struct amdgpu_irq_src *source,7586unsigned type,7587enum amdgpu_interrupt_state state)7588{7589u32 cg_thermal_int;75907591switch (type) {7592case AMDGPU_THERMAL_IRQ_LOW_TO_HIGH:7593switch (state) {7594case AMDGPU_IRQ_STATE_DISABLE:7595cg_thermal_int = RREG32_SMC(mmCG_THERMAL_INT);7596cg_thermal_int |= CG_THERMAL_INT__THERM_INT_MASK_HIGH_MASK;7597WREG32_SMC(mmCG_THERMAL_INT, cg_thermal_int);7598break;7599case AMDGPU_IRQ_STATE_ENABLE:7600cg_thermal_int = RREG32_SMC(mmCG_THERMAL_INT);7601cg_thermal_int &= ~CG_THERMAL_INT__THERM_INT_MASK_HIGH_MASK;7602WREG32_SMC(mmCG_THERMAL_INT, cg_thermal_int);7603break;7604default:7605break;7606}7607break;76087609case AMDGPU_THERMAL_IRQ_HIGH_TO_LOW:7610switch (state) {7611case AMDGPU_IRQ_STATE_DISABLE:7612cg_thermal_int = RREG32_SMC(mmCG_THERMAL_INT);7613cg_thermal_int |= CG_THERMAL_INT__THERM_INT_MASK_LOW_MASK;7614WREG32_SMC(mmCG_THERMAL_INT, cg_thermal_int);7615break;7616case AMDGPU_IRQ_STATE_ENABLE:7617cg_thermal_int = RREG32_SMC(mmCG_THERMAL_INT);7618cg_thermal_int &= ~CG_THERMAL_INT__THERM_INT_MASK_LOW_MASK;7619WREG32_SMC(mmCG_THERMAL_INT, cg_thermal_int);7620break;7621default:7622break;7623}7624break;76257626default:7627break;7628}7629return 0;7630}76317632static int si_dpm_process_interrupt(struct amdgpu_device *adev,7633struct amdgpu_irq_src *source,7634struct amdgpu_iv_entry *entry)7635{7636bool queue_thermal = false;76377638if (entry == NULL)7639return -EINVAL;76407641switch (entry->src_id) {7642case 230: /* thermal low to high */7643DRM_DEBUG("IH: thermal low to high\n");7644adev->pm.dpm.thermal.high_to_low = false;7645queue_thermal = true;7646break;7647case 231: /* thermal high to low */7648DRM_DEBUG("IH: thermal high to low\n");7649adev->pm.dpm.thermal.high_to_low = true;7650queue_thermal = true;7651break;7652default:7653break;7654}76557656if (queue_thermal)7657schedule_work(&adev->pm.dpm.thermal.work);76587659return 0;7660}76617662static int si_dpm_late_init(struct amdgpu_ip_block *ip_block)7663{7664int ret;7665struct amdgpu_device *adev = ip_block->adev;76667667if (!adev->pm.dpm_enabled)7668return 0;76697670ret = si_set_temperature_range(adev);7671if (ret)7672return ret;7673#if 0 //TODO ?7674si_dpm_powergate_uvd(adev, true);7675#endif7676return 0;7677}76787679/**7680* si_dpm_init_microcode - load ucode images from disk7681*7682* @adev: amdgpu_device pointer7683*7684* Use the firmware interface to load the ucode images into7685* the driver (not loaded into hw).7686* Returns 0 on success, error on failure.7687*/7688static int si_dpm_init_microcode(struct amdgpu_device *adev)7689{7690const char *chip_name;7691int err;76927693DRM_DEBUG("\n");7694switch (adev->asic_type) {7695case CHIP_TAHITI:7696chip_name = "tahiti";7697break;7698case CHIP_PITCAIRN:7699if ((adev->pdev->revision == 0x81) &&7700((adev->pdev->device == 0x6810) ||7701(adev->pdev->device == 0x6811)))7702chip_name = "pitcairn_k";7703else7704chip_name = "pitcairn";7705break;7706case CHIP_VERDE:7707if (((adev->pdev->device == 0x6820) &&7708((adev->pdev->revision == 0x81) ||7709(adev->pdev->revision == 0x83))) ||7710((adev->pdev->device == 0x6821) &&7711((adev->pdev->revision == 0x83) ||7712(adev->pdev->revision == 0x87))) ||7713((adev->pdev->revision == 0x87) &&7714((adev->pdev->device == 0x6823) ||7715(adev->pdev->device == 0x682b))))7716chip_name = "verde_k";7717else7718chip_name = "verde";7719break;7720case CHIP_OLAND:7721if (((adev->pdev->revision == 0x81) &&7722((adev->pdev->device == 0x6600) ||7723(adev->pdev->device == 0x6604) ||7724(adev->pdev->device == 0x6605) ||7725(adev->pdev->device == 0x6610))) ||7726((adev->pdev->revision == 0x83) &&7727(adev->pdev->device == 0x6610)))7728chip_name = "oland_k";7729else7730chip_name = "oland";7731break;7732case CHIP_HAINAN:7733if (((adev->pdev->revision == 0x81) &&7734(adev->pdev->device == 0x6660)) ||7735((adev->pdev->revision == 0x83) &&7736((adev->pdev->device == 0x6660) ||7737(adev->pdev->device == 0x6663) ||7738(adev->pdev->device == 0x6665) ||7739(adev->pdev->device == 0x6667))))7740chip_name = "hainan_k";7741else if ((adev->pdev->revision == 0xc3) &&7742(adev->pdev->device == 0x6665))7743chip_name = "banks_k_2";7744else7745chip_name = "hainan";7746break;7747default: BUG();7748}77497750err = amdgpu_ucode_request(adev, &adev->pm.fw, AMDGPU_UCODE_REQUIRED,7751"amdgpu/%s_smc.bin", chip_name);7752if (err) {7753DRM_ERROR("si_smc: Failed to load firmware. err = %d\"%s_smc.bin\"\n",7754err, chip_name);7755amdgpu_ucode_release(&adev->pm.fw);7756}7757return err;7758}77597760static int si_dpm_sw_init(struct amdgpu_ip_block *ip_block)7761{7762int ret;7763struct amdgpu_device *adev = ip_block->adev;77647765ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 230, &adev->pm.dpm.thermal.irq);7766if (ret)7767return ret;77687769ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 231, &adev->pm.dpm.thermal.irq);7770if (ret)7771return ret;77727773/* default to balanced state */7774adev->pm.dpm.state = POWER_STATE_TYPE_BALANCED;7775adev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED;7776adev->pm.dpm.forced_level = AMD_DPM_FORCED_LEVEL_AUTO;7777adev->pm.default_sclk = adev->clock.default_sclk;7778adev->pm.default_mclk = adev->clock.default_mclk;7779adev->pm.current_sclk = adev->clock.default_sclk;7780adev->pm.current_mclk = adev->clock.default_mclk;7781adev->pm.int_thermal_type = THERMAL_TYPE_NONE;77827783if (amdgpu_dpm == 0)7784return 0;77857786ret = si_dpm_init_microcode(adev);7787if (ret)7788return ret;77897790INIT_WORK(&adev->pm.dpm.thermal.work, amdgpu_dpm_thermal_work_handler);7791ret = si_dpm_init(adev);7792if (ret)7793goto dpm_failed;7794adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;7795if (amdgpu_dpm == 1)7796amdgpu_pm_print_power_states(adev);7797DRM_INFO("amdgpu: dpm initialized\n");77987799return 0;78007801dpm_failed:7802si_dpm_fini(adev);7803DRM_ERROR("amdgpu: dpm initialization failed\n");7804return ret;7805}78067807static int si_dpm_sw_fini(struct amdgpu_ip_block *ip_block)7808{7809struct amdgpu_device *adev = ip_block->adev;78107811flush_work(&adev->pm.dpm.thermal.work);78127813si_dpm_fini(adev);78147815return 0;7816}78177818static int si_dpm_hw_init(struct amdgpu_ip_block *ip_block)7819{7820int ret;78217822struct amdgpu_device *adev = ip_block->adev;78237824if (!amdgpu_dpm)7825return 0;78267827mutex_lock(&adev->pm.mutex);7828si_dpm_setup_asic(adev);7829ret = si_dpm_enable(adev);7830if (ret)7831adev->pm.dpm_enabled = false;7832else7833adev->pm.dpm_enabled = true;7834amdgpu_legacy_dpm_compute_clocks(adev);7835mutex_unlock(&adev->pm.mutex);7836return ret;7837}78387839static int si_dpm_hw_fini(struct amdgpu_ip_block *ip_block)7840{7841struct amdgpu_device *adev = ip_block->adev;78427843if (adev->pm.dpm_enabled)7844si_dpm_disable(adev);78457846return 0;7847}78487849static int si_dpm_suspend(struct amdgpu_ip_block *ip_block)7850{7851struct amdgpu_device *adev = ip_block->adev;78527853cancel_work_sync(&adev->pm.dpm.thermal.work);78547855if (adev->pm.dpm_enabled) {7856mutex_lock(&adev->pm.mutex);7857adev->pm.dpm_enabled = false;7858/* disable dpm */7859si_dpm_disable(adev);7860/* reset the power state */7861adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;7862mutex_unlock(&adev->pm.mutex);7863}78647865return 0;7866}78677868static int si_dpm_resume(struct amdgpu_ip_block *ip_block)7869{7870int ret = 0;7871struct amdgpu_device *adev = ip_block->adev;78727873if (!amdgpu_dpm)7874return 0;78757876if (!adev->pm.dpm_enabled) {7877/* asic init will reset to the boot state */7878mutex_lock(&adev->pm.mutex);7879si_dpm_setup_asic(adev);7880ret = si_dpm_enable(adev);7881if (ret) {7882adev->pm.dpm_enabled = false;7883} else {7884adev->pm.dpm_enabled = true;7885amdgpu_legacy_dpm_compute_clocks(adev);7886}7887mutex_unlock(&adev->pm.mutex);7888}78897890return ret;7891}78927893static bool si_dpm_is_idle(struct amdgpu_ip_block *ip_block)7894{7895/* XXX */7896return true;7897}78987899static int si_dpm_wait_for_idle(struct amdgpu_ip_block *ip_block)7900{7901/* XXX */7902return 0;7903}79047905static int si_dpm_set_clockgating_state(struct amdgpu_ip_block *ip_block,7906enum amd_clockgating_state state)7907{7908return 0;7909}79107911static int si_dpm_set_powergating_state(struct amdgpu_ip_block *ip_block,7912enum amd_powergating_state state)7913{7914return 0;7915}79167917/* get temperature in millidegrees */7918static int si_dpm_get_temp(void *handle)7919{7920u32 temp;7921int actual_temp = 0;7922struct amdgpu_device *adev = (struct amdgpu_device *)handle;79237924temp = (RREG32(mmCG_MULT_THERMAL_STATUS) & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >>7925CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT;79267927if (temp & 0x200)7928actual_temp = 255;7929else7930actual_temp = temp & 0x1ff;79317932actual_temp = (actual_temp * 1000);79337934return actual_temp;7935}79367937static u32 si_dpm_get_sclk(void *handle, bool low)7938{7939struct amdgpu_device *adev = (struct amdgpu_device *)handle;7940struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7941struct si_ps *requested_state = si_get_ps(&eg_pi->requested_rps);79427943if (low)7944return requested_state->performance_levels[0].sclk;7945else7946return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk;7947}79487949static u32 si_dpm_get_mclk(void *handle, bool low)7950{7951struct amdgpu_device *adev = (struct amdgpu_device *)handle;7952struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7953struct si_ps *requested_state = si_get_ps(&eg_pi->requested_rps);79547955if (low)7956return requested_state->performance_levels[0].mclk;7957else7958return requested_state->performance_levels[requested_state->performance_level_count - 1].mclk;7959}79607961static void si_dpm_print_power_state(void *handle,7962void *current_ps)7963{7964struct amdgpu_device *adev = (struct amdgpu_device *)handle;7965struct amdgpu_ps *rps = (struct amdgpu_ps *)current_ps;7966struct si_ps *ps = si_get_ps(rps);7967struct rv7xx_pl *pl;7968int i;79697970amdgpu_dpm_dbg_print_class_info(adev, rps->class, rps->class2);7971amdgpu_dpm_dbg_print_cap_info(adev, rps->caps);7972drm_dbg(adev_to_drm(adev), "\tuvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);7973drm_dbg(adev_to_drm(adev), "\tvce evclk: %d ecclk: %d\n", rps->evclk, rps->ecclk);7974for (i = 0; i < ps->performance_level_count; i++) {7975pl = &ps->performance_levels[i];7976drm_dbg(adev_to_drm(adev), "\t\tpower level %d sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",7977i, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);7978}7979amdgpu_dpm_dbg_print_ps_status(adev, rps);7980}79817982static int si_dpm_early_init(struct amdgpu_ip_block *ip_block)7983{79847985struct amdgpu_device *adev = ip_block->adev;79867987adev->powerplay.pp_funcs = &si_dpm_funcs;7988adev->powerplay.pp_handle = adev;7989si_dpm_set_irq_funcs(adev);7990return 0;7991}79927993static inline bool si_are_power_levels_equal(const struct rv7xx_pl *si_cpl1,7994const struct rv7xx_pl *si_cpl2)7995{7996return ((si_cpl1->mclk == si_cpl2->mclk) &&7997(si_cpl1->sclk == si_cpl2->sclk) &&7998(si_cpl1->pcie_gen == si_cpl2->pcie_gen) &&7999(si_cpl1->vddc == si_cpl2->vddc) &&8000(si_cpl1->vddci == si_cpl2->vddci));8001}80028003static int si_check_state_equal(void *handle,8004void *current_ps,8005void *request_ps,8006bool *equal)8007{8008struct si_ps *si_cps;8009struct si_ps *si_rps;8010int i;8011struct amdgpu_ps *cps = (struct amdgpu_ps *)current_ps;8012struct amdgpu_ps *rps = (struct amdgpu_ps *)request_ps;8013struct amdgpu_device *adev = (struct amdgpu_device *)handle;80148015if (adev == NULL || cps == NULL || rps == NULL || equal == NULL)8016return -EINVAL;80178018si_cps = si_get_ps((struct amdgpu_ps *)cps);8019si_rps = si_get_ps((struct amdgpu_ps *)rps);80208021if (si_cps == NULL) {8022printk("si_cps is NULL\n");8023*equal = false;8024return 0;8025}80268027if (si_cps->performance_level_count != si_rps->performance_level_count) {8028*equal = false;8029return 0;8030}80318032for (i = 0; i < si_cps->performance_level_count; i++) {8033if (!si_are_power_levels_equal(&(si_cps->performance_levels[i]),8034&(si_rps->performance_levels[i]))) {8035*equal = false;8036return 0;8037}8038}80398040/* If all performance levels are the same try to use the UVD clocks to break the tie.*/8041*equal = ((cps->vclk == rps->vclk) && (cps->dclk == rps->dclk));8042*equal &= ((cps->evclk == rps->evclk) && (cps->ecclk == rps->ecclk));80438044return 0;8045}80468047static int si_dpm_read_sensor(void *handle, int idx,8048void *value, int *size)8049{8050struct amdgpu_device *adev = (struct amdgpu_device *)handle;8051struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);8052struct amdgpu_ps *rps = &eg_pi->current_rps;8053struct si_ps *ps = si_get_ps(rps);8054uint32_t sclk, mclk;8055u32 pl_index =8056(RREG32(mmTARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_AND_CURRENT_PROFILE_INDEX__CURRENT_STATE_INDEX_MASK) >>8057TARGET_AND_CURRENT_PROFILE_INDEX__CURRENT_STATE_INDEX__SHIFT;80588059/* size must be at least 4 bytes for all sensors */8060if (*size < 4)8061return -EINVAL;80628063switch (idx) {8064case AMDGPU_PP_SENSOR_GFX_SCLK:8065if (pl_index < ps->performance_level_count) {8066sclk = ps->performance_levels[pl_index].sclk;8067*((uint32_t *)value) = sclk;8068*size = 4;8069return 0;8070}8071return -EINVAL;8072case AMDGPU_PP_SENSOR_GFX_MCLK:8073if (pl_index < ps->performance_level_count) {8074mclk = ps->performance_levels[pl_index].mclk;8075*((uint32_t *)value) = mclk;8076*size = 4;8077return 0;8078}8079return -EINVAL;8080case AMDGPU_PP_SENSOR_GPU_TEMP:8081*((uint32_t *)value) = si_dpm_get_temp(adev);8082*size = 4;8083return 0;8084default:8085return -EOPNOTSUPP;8086}8087}80888089static const struct amd_ip_funcs si_dpm_ip_funcs = {8090.name = "si_dpm",8091.early_init = si_dpm_early_init,8092.late_init = si_dpm_late_init,8093.sw_init = si_dpm_sw_init,8094.sw_fini = si_dpm_sw_fini,8095.hw_init = si_dpm_hw_init,8096.hw_fini = si_dpm_hw_fini,8097.suspend = si_dpm_suspend,8098.resume = si_dpm_resume,8099.is_idle = si_dpm_is_idle,8100.wait_for_idle = si_dpm_wait_for_idle,8101.set_clockgating_state = si_dpm_set_clockgating_state,8102.set_powergating_state = si_dpm_set_powergating_state,8103};81048105const struct amdgpu_ip_block_version si_smu_ip_block =8106{8107.type = AMD_IP_BLOCK_TYPE_SMC,8108.major = 6,8109.minor = 0,8110.rev = 0,8111.funcs = &si_dpm_ip_funcs,8112};81138114static const struct amd_pm_funcs si_dpm_funcs = {8115.pre_set_power_state = &si_dpm_pre_set_power_state,8116.set_power_state = &si_dpm_set_power_state,8117.post_set_power_state = &si_dpm_post_set_power_state,8118.display_configuration_changed = &si_dpm_display_configuration_changed,8119.get_sclk = &si_dpm_get_sclk,8120.get_mclk = &si_dpm_get_mclk,8121.print_power_state = &si_dpm_print_power_state,8122.debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level,8123.force_performance_level = &si_dpm_force_performance_level,8124.vblank_too_short = &si_dpm_vblank_too_short,8125.set_fan_control_mode = &si_dpm_set_fan_control_mode,8126.get_fan_control_mode = &si_dpm_get_fan_control_mode,8127.set_fan_speed_pwm = &si_dpm_set_fan_speed_pwm,8128.get_fan_speed_pwm = &si_dpm_get_fan_speed_pwm,8129.check_state_equal = &si_check_state_equal,8130.get_vce_clock_state = amdgpu_get_vce_clock_state,8131.read_sensor = &si_dpm_read_sensor,8132.pm_compute_clocks = amdgpu_legacy_dpm_compute_clocks,8133};81348135static const struct amdgpu_irq_src_funcs si_dpm_irq_funcs = {8136.set = si_dpm_set_interrupt_state,8137.process = si_dpm_process_interrupt,8138};81398140static void si_dpm_set_irq_funcs(struct amdgpu_device *adev)8141{8142adev->pm.dpm.thermal.irq.num_types = AMDGPU_THERMAL_IRQ_LAST;8143adev->pm.dpm.thermal.irq.funcs = &si_dpm_irq_funcs;8144}8145814681478148