Path: blob/master/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
26535 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 = amdgpu_dpm_get_vblank_time(adev);3084/* we never hit the non-gddr5 limit so disable it */3085u32 switch_limit = adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5 ? 450 : 0;30863087if (vblank_time < switch_limit)3088return true;3089else3090return false;30913092}30933094static int ni_copy_and_switch_arb_sets(struct amdgpu_device *adev,3095u32 arb_freq_src, u32 arb_freq_dest)3096{3097u32 mc_arb_dram_timing;3098u32 mc_arb_dram_timing2;3099u32 burst_time;3100u32 mc_cg_config;31013102switch (arb_freq_src) {3103case MC_CG_ARB_FREQ_F0:3104mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING);3105mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);3106burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE0_MASK) >> STATE0_SHIFT;3107break;3108case MC_CG_ARB_FREQ_F1:3109mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING_1);3110mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_1);3111burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE1_MASK) >> STATE1_SHIFT;3112break;3113case MC_CG_ARB_FREQ_F2:3114mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING_2);3115mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_2);3116burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE2_MASK) >> STATE2_SHIFT;3117break;3118case MC_CG_ARB_FREQ_F3:3119mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING_3);3120mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_3);3121burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE3_MASK) >> STATE3_SHIFT;3122break;3123default:3124return -EINVAL;3125}31263127switch (arb_freq_dest) {3128case MC_CG_ARB_FREQ_F0:3129WREG32(MC_ARB_DRAM_TIMING, mc_arb_dram_timing);3130WREG32(MC_ARB_DRAM_TIMING2, mc_arb_dram_timing2);3131WREG32_P(MC_ARB_BURST_TIME, STATE0(burst_time), ~STATE0_MASK);3132break;3133case MC_CG_ARB_FREQ_F1:3134WREG32(MC_ARB_DRAM_TIMING_1, mc_arb_dram_timing);3135WREG32(MC_ARB_DRAM_TIMING2_1, mc_arb_dram_timing2);3136WREG32_P(MC_ARB_BURST_TIME, STATE1(burst_time), ~STATE1_MASK);3137break;3138case MC_CG_ARB_FREQ_F2:3139WREG32(MC_ARB_DRAM_TIMING_2, mc_arb_dram_timing);3140WREG32(MC_ARB_DRAM_TIMING2_2, mc_arb_dram_timing2);3141WREG32_P(MC_ARB_BURST_TIME, STATE2(burst_time), ~STATE2_MASK);3142break;3143case MC_CG_ARB_FREQ_F3:3144WREG32(MC_ARB_DRAM_TIMING_3, mc_arb_dram_timing);3145WREG32(MC_ARB_DRAM_TIMING2_3, mc_arb_dram_timing2);3146WREG32_P(MC_ARB_BURST_TIME, STATE3(burst_time), ~STATE3_MASK);3147break;3148default:3149return -EINVAL;3150}31513152mc_cg_config = RREG32(MC_CG_CONFIG) | 0x0000000F;3153WREG32(MC_CG_CONFIG, mc_cg_config);3154WREG32_P(MC_ARB_CG, CG_ARB_REQ(arb_freq_dest), ~CG_ARB_REQ_MASK);31553156return 0;3157}31583159static void ni_update_current_ps(struct amdgpu_device *adev,3160struct amdgpu_ps *rps)3161{3162struct si_ps *new_ps = si_get_ps(rps);3163struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);3164struct ni_power_info *ni_pi = ni_get_pi(adev);31653166eg_pi->current_rps = *rps;3167ni_pi->current_ps = *new_ps;3168eg_pi->current_rps.ps_priv = &ni_pi->current_ps;3169adev->pm.dpm.current_ps = &eg_pi->current_rps;3170}31713172static void ni_update_requested_ps(struct amdgpu_device *adev,3173struct amdgpu_ps *rps)3174{3175struct si_ps *new_ps = si_get_ps(rps);3176struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);3177struct ni_power_info *ni_pi = ni_get_pi(adev);31783179eg_pi->requested_rps = *rps;3180ni_pi->requested_ps = *new_ps;3181eg_pi->requested_rps.ps_priv = &ni_pi->requested_ps;3182adev->pm.dpm.requested_ps = &eg_pi->requested_rps;3183}31843185static void ni_set_uvd_clock_before_set_eng_clock(struct amdgpu_device *adev,3186struct amdgpu_ps *new_ps,3187struct amdgpu_ps *old_ps)3188{3189struct si_ps *new_state = si_get_ps(new_ps);3190struct si_ps *current_state = si_get_ps(old_ps);31913192if ((new_ps->vclk == old_ps->vclk) &&3193(new_ps->dclk == old_ps->dclk))3194return;31953196if (new_state->performance_levels[new_state->performance_level_count - 1].sclk >=3197current_state->performance_levels[current_state->performance_level_count - 1].sclk)3198return;31993200amdgpu_asic_set_uvd_clocks(adev, new_ps->vclk, new_ps->dclk);3201}32023203static void ni_set_uvd_clock_after_set_eng_clock(struct amdgpu_device *adev,3204struct amdgpu_ps *new_ps,3205struct amdgpu_ps *old_ps)3206{3207struct si_ps *new_state = si_get_ps(new_ps);3208struct si_ps *current_state = si_get_ps(old_ps);32093210if ((new_ps->vclk == old_ps->vclk) &&3211(new_ps->dclk == old_ps->dclk))3212return;32133214if (new_state->performance_levels[new_state->performance_level_count - 1].sclk <3215current_state->performance_levels[current_state->performance_level_count - 1].sclk)3216return;32173218amdgpu_asic_set_uvd_clocks(adev, new_ps->vclk, new_ps->dclk);3219}32203221static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)3222{3223unsigned int i;32243225for (i = 0; i < table->count; i++)3226if (voltage <= table->entries[i].value)3227return table->entries[i].value;32283229return table->entries[table->count - 1].value;3230}32313232static u32 btc_find_valid_clock(struct amdgpu_clock_array *clocks,3233u32 max_clock, u32 requested_clock)3234{3235unsigned int i;32363237if ((clocks == NULL) || (clocks->count == 0))3238return (requested_clock < max_clock) ? requested_clock : max_clock;32393240for (i = 0; i < clocks->count; i++) {3241if (clocks->values[i] >= requested_clock)3242return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock;3243}32443245return (clocks->values[clocks->count - 1] < max_clock) ?3246clocks->values[clocks->count - 1] : max_clock;3247}32483249static u32 btc_get_valid_mclk(struct amdgpu_device *adev,3250u32 max_mclk, u32 requested_mclk)3251{3252return btc_find_valid_clock(&adev->pm.dpm.dyn_state.valid_mclk_values,3253max_mclk, requested_mclk);3254}32553256static u32 btc_get_valid_sclk(struct amdgpu_device *adev,3257u32 max_sclk, u32 requested_sclk)3258{3259return btc_find_valid_clock(&adev->pm.dpm.dyn_state.valid_sclk_values,3260max_sclk, requested_sclk);3261}32623263static void btc_get_max_clock_from_voltage_dependency_table(struct amdgpu_clock_voltage_dependency_table *table,3264u32 *max_clock)3265{3266u32 i, clock = 0;32673268if ((table == NULL) || (table->count == 0)) {3269*max_clock = clock;3270return;3271}32723273for (i = 0; i < table->count; i++) {3274if (clock < table->entries[i].clk)3275clock = table->entries[i].clk;3276}3277*max_clock = clock;3278}32793280static void btc_apply_voltage_dependency_rules(struct amdgpu_clock_voltage_dependency_table *table,3281u32 clock, u16 max_voltage, u16 *voltage)3282{3283u32 i;32843285if ((table == NULL) || (table->count == 0))3286return;32873288for (i= 0; i < table->count; i++) {3289if (clock <= table->entries[i].clk) {3290if (*voltage < table->entries[i].v)3291*voltage = (u16)((table->entries[i].v < max_voltage) ?3292table->entries[i].v : max_voltage);3293return;3294}3295}32963297*voltage = (*voltage > max_voltage) ? *voltage : max_voltage;3298}32993300static void btc_adjust_clock_combinations(struct amdgpu_device *adev,3301const struct amdgpu_clock_and_voltage_limits *max_limits,3302struct rv7xx_pl *pl)3303{33043305if ((pl->mclk == 0) || (pl->sclk == 0))3306return;33073308if (pl->mclk == pl->sclk)3309return;33103311if (pl->mclk > pl->sclk) {3312if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > adev->pm.dpm.dyn_state.mclk_sclk_ratio)3313pl->sclk = btc_get_valid_sclk(adev,3314max_limits->sclk,3315(pl->mclk +3316(adev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) /3317adev->pm.dpm.dyn_state.mclk_sclk_ratio);3318} else {3319if ((pl->sclk - pl->mclk) > adev->pm.dpm.dyn_state.sclk_mclk_delta)3320pl->mclk = btc_get_valid_mclk(adev,3321max_limits->mclk,3322pl->sclk -3323adev->pm.dpm.dyn_state.sclk_mclk_delta);3324}3325}33263327static void btc_apply_voltage_delta_rules(struct amdgpu_device *adev,3328u16 max_vddc, u16 max_vddci,3329u16 *vddc, u16 *vddci)3330{3331struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);3332u16 new_voltage;33333334if ((0 == *vddc) || (0 == *vddci))3335return;33363337if (*vddc > *vddci) {3338if ((*vddc - *vddci) > adev->pm.dpm.dyn_state.vddc_vddci_delta) {3339new_voltage = btc_find_voltage(&eg_pi->vddci_voltage_table,3340(*vddc - adev->pm.dpm.dyn_state.vddc_vddci_delta));3341*vddci = (new_voltage < max_vddci) ? new_voltage : max_vddci;3342}3343} else {3344if ((*vddci - *vddc) > adev->pm.dpm.dyn_state.vddc_vddci_delta) {3345new_voltage = btc_find_voltage(&eg_pi->vddc_voltage_table,3346(*vddci - adev->pm.dpm.dyn_state.vddc_vddci_delta));3347*vddc = (new_voltage < max_vddc) ? new_voltage : max_vddc;3348}3349}3350}33513352static void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,3353u32 *p, u32 *u)3354{3355u32 b_c = 0;3356u32 i_c;3357u32 tmp;33583359i_c = (i * r_c) / 100;3360tmp = i_c >> p_b;33613362while (tmp) {3363b_c++;3364tmp >>= 1;3365}33663367*u = (b_c + 1) / 2;3368*p = i_c / (1 << (2 * (*u)));3369}33703371static int r600_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th)3372{3373u32 k, a, ah, al;3374u32 t1;33753376if ((fl == 0) || (fh == 0) || (fl > fh))3377return -EINVAL;33783379k = (100 * fh) / fl;3380t1 = (t * (k - 100));3381a = (1000 * (100 * h + t1)) / (10000 + (t1 / 100));3382a = (a + 5) / 10;3383ah = ((a * t) + 5000) / 10000;3384al = a - ah;33853386*th = t - ah;3387*tl = t + al;33883389return 0;3390}33913392static bool r600_is_uvd_state(u32 class, u32 class2)3393{3394if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)3395return true;3396if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)3397return true;3398if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)3399return true;3400if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)3401return true;3402if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)3403return true;3404return false;3405}34063407static u8 rv770_get_memory_module_index(struct amdgpu_device *adev)3408{3409return (u8) ((RREG32(BIOS_SCRATCH_4) >> 16) & 0xff);3410}34113412static void rv770_get_max_vddc(struct amdgpu_device *adev)3413{3414struct rv7xx_power_info *pi = rv770_get_pi(adev);3415u16 vddc;34163417if (amdgpu_atombios_get_max_vddc(adev, 0, 0, &vddc))3418pi->max_vddc = 0;3419else3420pi->max_vddc = vddc;3421}34223423static void rv770_get_engine_memory_ss(struct amdgpu_device *adev)3424{3425struct rv7xx_power_info *pi = rv770_get_pi(adev);3426struct amdgpu_atom_ss ss;34273428pi->sclk_ss = amdgpu_atombios_get_asic_ss_info(adev, &ss,3429ASIC_INTERNAL_ENGINE_SS, 0);3430pi->mclk_ss = amdgpu_atombios_get_asic_ss_info(adev, &ss,3431ASIC_INTERNAL_MEMORY_SS, 0);34323433if (pi->sclk_ss || pi->mclk_ss)3434pi->dynamic_ss = true;3435else3436pi->dynamic_ss = false;3437}343834393440static void si_apply_state_adjust_rules(struct amdgpu_device *adev,3441struct amdgpu_ps *rps)3442{3443struct si_ps *ps = si_get_ps(rps);3444struct amdgpu_clock_and_voltage_limits *max_limits;3445bool disable_mclk_switching = false;3446bool disable_sclk_switching = false;3447u32 mclk, sclk;3448u16 vddc, vddci, min_vce_voltage = 0;3449u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;3450u32 max_sclk = 0, max_mclk = 0;3451int i;34523453if (adev->asic_type == CHIP_HAINAN) {3454if ((adev->pdev->revision == 0x81) ||3455(adev->pdev->revision == 0xC3) ||3456(adev->pdev->device == 0x6664) ||3457(adev->pdev->device == 0x6665) ||3458(adev->pdev->device == 0x6667)) {3459max_sclk = 75000;3460}3461if ((adev->pdev->revision == 0xC3) ||3462(adev->pdev->device == 0x6665)) {3463max_sclk = 60000;3464max_mclk = 80000;3465}3466} else if (adev->asic_type == CHIP_OLAND) {3467if ((adev->pdev->revision == 0xC7) ||3468(adev->pdev->revision == 0x80) ||3469(adev->pdev->revision == 0x81) ||3470(adev->pdev->revision == 0x83) ||3471(adev->pdev->revision == 0x87) ||3472(adev->pdev->device == 0x6604) ||3473(adev->pdev->device == 0x6605)) {3474max_sclk = 75000;3475}3476}34773478if (rps->vce_active) {3479rps->evclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].evclk;3480rps->ecclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].ecclk;3481si_get_vce_clock_voltage(adev, rps->evclk, rps->ecclk,3482&min_vce_voltage);3483} else {3484rps->evclk = 0;3485rps->ecclk = 0;3486}34873488if ((adev->pm.dpm.new_active_crtc_count > 1) ||3489si_dpm_vblank_too_short(adev))3490disable_mclk_switching = true;34913492if (rps->vclk || rps->dclk) {3493disable_mclk_switching = true;3494disable_sclk_switching = true;3495}34963497if (adev->pm.ac_power)3498max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac;3499else3500max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc;35013502for (i = ps->performance_level_count - 2; i >= 0; i--) {3503if (ps->performance_levels[i].vddc > ps->performance_levels[i+1].vddc)3504ps->performance_levels[i].vddc = ps->performance_levels[i+1].vddc;3505}3506if (adev->pm.ac_power == false) {3507for (i = 0; i < ps->performance_level_count; i++) {3508if (ps->performance_levels[i].mclk > max_limits->mclk)3509ps->performance_levels[i].mclk = max_limits->mclk;3510if (ps->performance_levels[i].sclk > max_limits->sclk)3511ps->performance_levels[i].sclk = max_limits->sclk;3512if (ps->performance_levels[i].vddc > max_limits->vddc)3513ps->performance_levels[i].vddc = max_limits->vddc;3514if (ps->performance_levels[i].vddci > max_limits->vddci)3515ps->performance_levels[i].vddci = max_limits->vddci;3516}3517}35183519/* limit clocks to max supported clocks based on voltage dependency tables */3520btc_get_max_clock_from_voltage_dependency_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,3521&max_sclk_vddc);3522btc_get_max_clock_from_voltage_dependency_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,3523&max_mclk_vddci);3524btc_get_max_clock_from_voltage_dependency_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,3525&max_mclk_vddc);35263527for (i = 0; i < ps->performance_level_count; i++) {3528if (max_sclk_vddc) {3529if (ps->performance_levels[i].sclk > max_sclk_vddc)3530ps->performance_levels[i].sclk = max_sclk_vddc;3531}3532if (max_mclk_vddci) {3533if (ps->performance_levels[i].mclk > max_mclk_vddci)3534ps->performance_levels[i].mclk = max_mclk_vddci;3535}3536if (max_mclk_vddc) {3537if (ps->performance_levels[i].mclk > max_mclk_vddc)3538ps->performance_levels[i].mclk = max_mclk_vddc;3539}3540if (max_mclk) {3541if (ps->performance_levels[i].mclk > max_mclk)3542ps->performance_levels[i].mclk = max_mclk;3543}3544if (max_sclk) {3545if (ps->performance_levels[i].sclk > max_sclk)3546ps->performance_levels[i].sclk = max_sclk;3547}3548}35493550/* XXX validate the min clocks required for display */35513552if (disable_mclk_switching) {3553mclk = ps->performance_levels[ps->performance_level_count - 1].mclk;3554vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;3555} else {3556mclk = ps->performance_levels[0].mclk;3557vddci = ps->performance_levels[0].vddci;3558}35593560if (disable_sclk_switching) {3561sclk = ps->performance_levels[ps->performance_level_count - 1].sclk;3562vddc = ps->performance_levels[ps->performance_level_count - 1].vddc;3563} else {3564sclk = ps->performance_levels[0].sclk;3565vddc = ps->performance_levels[0].vddc;3566}35673568if (rps->vce_active) {3569if (sclk < adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].sclk)3570sclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].sclk;3571if (mclk < adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].mclk)3572mclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].mclk;3573}35743575/* adjusted low state */3576ps->performance_levels[0].sclk = sclk;3577ps->performance_levels[0].mclk = mclk;3578ps->performance_levels[0].vddc = vddc;3579ps->performance_levels[0].vddci = vddci;35803581if (disable_sclk_switching) {3582sclk = ps->performance_levels[0].sclk;3583for (i = 1; i < ps->performance_level_count; i++) {3584if (sclk < ps->performance_levels[i].sclk)3585sclk = ps->performance_levels[i].sclk;3586}3587for (i = 0; i < ps->performance_level_count; i++) {3588ps->performance_levels[i].sclk = sclk;3589ps->performance_levels[i].vddc = vddc;3590}3591} else {3592for (i = 1; i < ps->performance_level_count; i++) {3593if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)3594ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;3595if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)3596ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;3597}3598}35993600if (disable_mclk_switching) {3601mclk = ps->performance_levels[0].mclk;3602for (i = 1; i < ps->performance_level_count; i++) {3603if (mclk < ps->performance_levels[i].mclk)3604mclk = ps->performance_levels[i].mclk;3605}3606for (i = 0; i < ps->performance_level_count; i++) {3607ps->performance_levels[i].mclk = mclk;3608ps->performance_levels[i].vddci = vddci;3609}3610} else {3611for (i = 1; i < ps->performance_level_count; i++) {3612if (ps->performance_levels[i].mclk < ps->performance_levels[i - 1].mclk)3613ps->performance_levels[i].mclk = ps->performance_levels[i - 1].mclk;3614if (ps->performance_levels[i].vddci < ps->performance_levels[i - 1].vddci)3615ps->performance_levels[i].vddci = ps->performance_levels[i - 1].vddci;3616}3617}36183619for (i = 0; i < ps->performance_level_count; i++)3620btc_adjust_clock_combinations(adev, max_limits,3621&ps->performance_levels[i]);36223623for (i = 0; i < ps->performance_level_count; i++) {3624if (ps->performance_levels[i].vddc < min_vce_voltage)3625ps->performance_levels[i].vddc = min_vce_voltage;3626btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,3627ps->performance_levels[i].sclk,3628max_limits->vddc, &ps->performance_levels[i].vddc);3629btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,3630ps->performance_levels[i].mclk,3631max_limits->vddci, &ps->performance_levels[i].vddci);3632btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,3633ps->performance_levels[i].mclk,3634max_limits->vddc, &ps->performance_levels[i].vddc);3635btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,3636adev->clock.current_dispclk,3637max_limits->vddc, &ps->performance_levels[i].vddc);3638}36393640for (i = 0; i < ps->performance_level_count; i++) {3641btc_apply_voltage_delta_rules(adev,3642max_limits->vddc, max_limits->vddci,3643&ps->performance_levels[i].vddc,3644&ps->performance_levels[i].vddci);3645}36463647ps->dc_compatible = true;3648for (i = 0; i < ps->performance_level_count; i++) {3649if (ps->performance_levels[i].vddc > adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc)3650ps->dc_compatible = false;3651}3652}36533654#if 03655static int si_read_smc_soft_register(struct amdgpu_device *adev,3656u16 reg_offset, u32 *value)3657{3658struct si_power_info *si_pi = si_get_pi(adev);36593660return amdgpu_si_read_smc_sram_dword(adev,3661si_pi->soft_regs_start + reg_offset, value,3662si_pi->sram_end);3663}3664#endif36653666static int si_write_smc_soft_register(struct amdgpu_device *adev,3667u16 reg_offset, u32 value)3668{3669struct si_power_info *si_pi = si_get_pi(adev);36703671return amdgpu_si_write_smc_sram_dword(adev,3672si_pi->soft_regs_start + reg_offset,3673value, si_pi->sram_end);3674}36753676static bool si_is_special_1gb_platform(struct amdgpu_device *adev)3677{3678bool ret = false;3679u32 tmp, width, row, column, bank, density;3680bool is_memory_gddr5, is_special;36813682tmp = RREG32(MC_SEQ_MISC0);3683is_memory_gddr5 = (MC_SEQ_MISC0_GDDR5_VALUE == ((tmp & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT));3684is_special = (MC_SEQ_MISC0_REV_ID_VALUE == ((tmp & MC_SEQ_MISC0_REV_ID_MASK) >> MC_SEQ_MISC0_REV_ID_SHIFT))3685& (MC_SEQ_MISC0_VEN_ID_VALUE == ((tmp & MC_SEQ_MISC0_VEN_ID_MASK) >> MC_SEQ_MISC0_VEN_ID_SHIFT));36863687WREG32(MC_SEQ_IO_DEBUG_INDEX, 0xb);3688width = ((RREG32(MC_SEQ_IO_DEBUG_DATA) >> 1) & 1) ? 16 : 32;36893690tmp = RREG32(mmMC_ARB_RAMCFG);3691row = ((tmp & MC_ARB_RAMCFG__NOOFROWS_MASK) >> MC_ARB_RAMCFG__NOOFROWS__SHIFT) + 10;3692column = ((tmp & MC_ARB_RAMCFG__NOOFCOLS_MASK) >> MC_ARB_RAMCFG__NOOFCOLS__SHIFT) + 8;3693bank = ((tmp & MC_ARB_RAMCFG__NOOFBANK_MASK) >> MC_ARB_RAMCFG__NOOFBANK__SHIFT) + 2;36943695density = (1 << (row + column - 20 + bank)) * width;36963697if ((adev->pdev->device == 0x6819) &&3698is_memory_gddr5 && is_special && (density == 0x400))3699ret = true;37003701return ret;3702}37033704static void si_get_leakage_vddc(struct amdgpu_device *adev)3705{3706struct si_power_info *si_pi = si_get_pi(adev);3707u16 vddc, count = 0;3708int i, ret;37093710for (i = 0; i < SISLANDS_MAX_LEAKAGE_COUNT; i++) {3711ret = amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(adev, &vddc, SISLANDS_LEAKAGE_INDEX0 + i);37123713if (!ret && (vddc > 0) && (vddc != (SISLANDS_LEAKAGE_INDEX0 + i))) {3714si_pi->leakage_voltage.entries[count].voltage = vddc;3715si_pi->leakage_voltage.entries[count].leakage_index =3716SISLANDS_LEAKAGE_INDEX0 + i;3717count++;3718}3719}3720si_pi->leakage_voltage.count = count;3721}37223723static int si_get_leakage_voltage_from_leakage_index(struct amdgpu_device *adev,3724u32 index, u16 *leakage_voltage)3725{3726struct si_power_info *si_pi = si_get_pi(adev);3727int i;37283729if (leakage_voltage == NULL)3730return -EINVAL;37313732if ((index & 0xff00) != 0xff00)3733return -EINVAL;37343735if ((index & 0xff) > SISLANDS_MAX_LEAKAGE_COUNT + 1)3736return -EINVAL;37373738if (index < SISLANDS_LEAKAGE_INDEX0)3739return -EINVAL;37403741for (i = 0; i < si_pi->leakage_voltage.count; i++) {3742if (si_pi->leakage_voltage.entries[i].leakage_index == index) {3743*leakage_voltage = si_pi->leakage_voltage.entries[i].voltage;3744return 0;3745}3746}3747return -EAGAIN;3748}37493750static void si_set_dpm_event_sources(struct amdgpu_device *adev, u32 sources)3751{3752struct rv7xx_power_info *pi = rv770_get_pi(adev);3753bool want_thermal_protection;3754enum si_dpm_event_src dpm_event_src;37553756switch (sources) {3757case 0:3758default:3759want_thermal_protection = false;3760break;3761case (1 << SI_DPM_AUTO_THROTTLE_SRC_THERMAL):3762want_thermal_protection = true;3763dpm_event_src = SI_DPM_EVENT_SRC_DIGITAL;3764break;3765case (1 << SI_DPM_AUTO_THROTTLE_SRC_EXTERNAL):3766want_thermal_protection = true;3767dpm_event_src = SI_DPM_EVENT_SRC_EXTERNAL;3768break;3769case ((1 << SI_DPM_AUTO_THROTTLE_SRC_EXTERNAL) |3770(1 << SI_DPM_AUTO_THROTTLE_SRC_THERMAL)):3771want_thermal_protection = true;3772dpm_event_src = SI_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL;3773break;3774}37753776if (want_thermal_protection) {3777WREG32_P(mmCG_THERMAL_CTRL, dpm_event_src << CG_THERMAL_CTRL__DPM_EVENT_SRC__SHIFT, ~CG_THERMAL_CTRL__DPM_EVENT_SRC_MASK);3778if (pi->thermal_protection)3779WREG32_P(mmGENERAL_PWRMGT, 0, ~GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK);3780} else {3781WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK, ~GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK);3782}3783}37843785static void si_enable_auto_throttle_source(struct amdgpu_device *adev,3786enum si_dpm_auto_throttle_src source,3787bool enable)3788{3789struct rv7xx_power_info *pi = rv770_get_pi(adev);37903791if (enable) {3792if (!(pi->active_auto_throttle_sources & (1 << source))) {3793pi->active_auto_throttle_sources |= 1 << source;3794si_set_dpm_event_sources(adev, pi->active_auto_throttle_sources);3795}3796} else {3797if (pi->active_auto_throttle_sources & (1 << source)) {3798pi->active_auto_throttle_sources &= ~(1 << source);3799si_set_dpm_event_sources(adev, pi->active_auto_throttle_sources);3800}3801}3802}38033804static void si_start_dpm(struct amdgpu_device *adev)3805{3806WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__GLOBAL_PWRMGT_EN_MASK, ~GENERAL_PWRMGT__GLOBAL_PWRMGT_EN_MASK);3807}38083809static void si_stop_dpm(struct amdgpu_device *adev)3810{3811WREG32_P(mmGENERAL_PWRMGT, 0, ~GENERAL_PWRMGT__GLOBAL_PWRMGT_EN_MASK);3812}38133814static void si_enable_sclk_control(struct amdgpu_device *adev, bool enable)3815{3816if (enable)3817WREG32_P(mmSCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_CNTL__SCLK_PWRMGT_OFF_MASK);3818else3819WREG32_P(mmSCLK_PWRMGT_CNTL, SCLK_PWRMGT_CNTL__SCLK_PWRMGT_OFF_MASK, ~SCLK_PWRMGT_CNTL__SCLK_PWRMGT_OFF_MASK);38203821}38223823#if 03824static int si_notify_hardware_of_thermal_state(struct amdgpu_device *adev,3825u32 thermal_level)3826{3827PPSMC_Result ret;38283829if (thermal_level == 0) {3830ret = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableThermalInterrupt);3831if (ret == PPSMC_Result_OK)3832return 0;3833else3834return -EINVAL;3835}3836return 0;3837}38383839static void si_notify_hardware_vpu_recovery_event(struct amdgpu_device *adev)3840{3841si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_tdr_is_about_to_happen, true);3842}3843#endif38443845#if 03846static int si_notify_hw_of_powersource(struct amdgpu_device *adev, bool ac_power)3847{3848if (ac_power)3849return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_RunningOnAC) == PPSMC_Result_OK) ?38500 : -EINVAL;38513852return 0;3853}3854#endif38553856static PPSMC_Result si_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,3857PPSMC_Msg msg, u32 parameter)3858{3859WREG32(mmSMC_SCRATCH0, parameter);3860return amdgpu_si_send_msg_to_smc(adev, msg);3861}38623863static int si_restrict_performance_levels_before_switch(struct amdgpu_device *adev)3864{3865if (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)3866return -EINVAL;38673868return (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, 1) == PPSMC_Result_OK) ?38690 : -EINVAL;3870}38713872static int si_dpm_force_performance_level(void *handle,3873enum amd_dpm_forced_level level)3874{3875struct amdgpu_device *adev = (struct amdgpu_device *)handle;3876struct amdgpu_ps *rps = adev->pm.dpm.current_ps;3877struct si_ps *ps = si_get_ps(rps);3878u32 levels = ps->performance_level_count;38793880if (level == AMD_DPM_FORCED_LEVEL_HIGH) {3881if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK)3882return -EINVAL;38833884if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK)3885return -EINVAL;3886} else if (level == AMD_DPM_FORCED_LEVEL_LOW) {3887if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)3888return -EINVAL;38893890if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK)3891return -EINVAL;3892} else if (level == AMD_DPM_FORCED_LEVEL_AUTO) {3893if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)3894return -EINVAL;38953896if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK)3897return -EINVAL;3898}38993900adev->pm.dpm.forced_level = level;39013902return 0;3903}39043905#if 03906static int si_set_boot_state(struct amdgpu_device *adev)3907{3908return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_SwitchToInitialState) == PPSMC_Result_OK) ?39090 : -EINVAL;3910}3911#endif39123913static int si_set_sw_state(struct amdgpu_device *adev)3914{3915return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_SwitchToSwState) == PPSMC_Result_OK) ?39160 : -EINVAL;3917}39183919static int si_halt_smc(struct amdgpu_device *adev)3920{3921if (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_Halt) != PPSMC_Result_OK)3922return -EINVAL;39233924return (amdgpu_si_wait_for_smc_inactive(adev) == PPSMC_Result_OK) ?39250 : -EINVAL;3926}39273928static int si_resume_smc(struct amdgpu_device *adev)3929{3930if (amdgpu_si_send_msg_to_smc(adev, PPSMC_FlushDataCache) != PPSMC_Result_OK)3931return -EINVAL;39323933return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_Resume) == PPSMC_Result_OK) ?39340 : -EINVAL;3935}39363937static void si_dpm_start_smc(struct amdgpu_device *adev)3938{3939amdgpu_si_program_jump_on_start(adev);3940amdgpu_si_start_smc(adev);3941amdgpu_si_smc_clock(adev, true);3942}39433944static void si_dpm_stop_smc(struct amdgpu_device *adev)3945{3946amdgpu_si_reset_smc(adev);3947amdgpu_si_smc_clock(adev, false);3948}39493950static int si_process_firmware_header(struct amdgpu_device *adev)3951{3952struct si_power_info *si_pi = si_get_pi(adev);3953u32 tmp;3954int ret;39553956ret = amdgpu_si_read_smc_sram_dword(adev,3957SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +3958SISLANDS_SMC_FIRMWARE_HEADER_stateTable,3959&tmp, si_pi->sram_end);3960if (ret)3961return ret;39623963si_pi->state_table_start = tmp;39643965ret = amdgpu_si_read_smc_sram_dword(adev,3966SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +3967SISLANDS_SMC_FIRMWARE_HEADER_softRegisters,3968&tmp, si_pi->sram_end);3969if (ret)3970return ret;39713972si_pi->soft_regs_start = tmp;39733974ret = amdgpu_si_read_smc_sram_dword(adev,3975SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +3976SISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable,3977&tmp, si_pi->sram_end);3978if (ret)3979return ret;39803981si_pi->mc_reg_table_start = tmp;39823983ret = amdgpu_si_read_smc_sram_dword(adev,3984SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +3985SISLANDS_SMC_FIRMWARE_HEADER_fanTable,3986&tmp, si_pi->sram_end);3987if (ret)3988return ret;39893990si_pi->fan_table_start = tmp;39913992ret = amdgpu_si_read_smc_sram_dword(adev,3993SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +3994SISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable,3995&tmp, si_pi->sram_end);3996if (ret)3997return ret;39983999si_pi->arb_table_start = tmp;40004001ret = amdgpu_si_read_smc_sram_dword(adev,4002SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4003SISLANDS_SMC_FIRMWARE_HEADER_CacConfigTable,4004&tmp, si_pi->sram_end);4005if (ret)4006return ret;40074008si_pi->cac_table_start = tmp;40094010ret = amdgpu_si_read_smc_sram_dword(adev,4011SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4012SISLANDS_SMC_FIRMWARE_HEADER_DteConfiguration,4013&tmp, si_pi->sram_end);4014if (ret)4015return ret;40164017si_pi->dte_table_start = tmp;40184019ret = amdgpu_si_read_smc_sram_dword(adev,4020SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4021SISLANDS_SMC_FIRMWARE_HEADER_spllTable,4022&tmp, si_pi->sram_end);4023if (ret)4024return ret;40254026si_pi->spll_table_start = tmp;40274028ret = amdgpu_si_read_smc_sram_dword(adev,4029SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +4030SISLANDS_SMC_FIRMWARE_HEADER_PAPMParameters,4031&tmp, si_pi->sram_end);4032if (ret)4033return ret;40344035si_pi->papm_cfg_table_start = tmp;40364037return ret;4038}40394040static void si_read_clock_registers(struct amdgpu_device *adev)4041{4042struct si_power_info *si_pi = si_get_pi(adev);40434044si_pi->clock_registers.cg_spll_func_cntl = RREG32(mmCG_SPLL_FUNC_CNTL);4045si_pi->clock_registers.cg_spll_func_cntl_2 = RREG32(mmCG_SPLL_FUNC_CNTL_2);4046si_pi->clock_registers.cg_spll_func_cntl_3 = RREG32(mmCG_SPLL_FUNC_CNTL_3);4047si_pi->clock_registers.cg_spll_func_cntl_4 = RREG32(mmCG_SPLL_FUNC_CNTL_4);4048si_pi->clock_registers.cg_spll_spread_spectrum = RREG32(mmCG_SPLL_SPREAD_SPECTRUM);4049si_pi->clock_registers.cg_spll_spread_spectrum_2 = RREG32(mmCG_SPLL_SPREAD_SPECTRUM_2);4050si_pi->clock_registers.dll_cntl = RREG32(DLL_CNTL);4051si_pi->clock_registers.mclk_pwrmgt_cntl = RREG32(MCLK_PWRMGT_CNTL);4052si_pi->clock_registers.mpll_ad_func_cntl = RREG32(MPLL_AD_FUNC_CNTL);4053si_pi->clock_registers.mpll_dq_func_cntl = RREG32(MPLL_DQ_FUNC_CNTL);4054si_pi->clock_registers.mpll_func_cntl = RREG32(MPLL_FUNC_CNTL);4055si_pi->clock_registers.mpll_func_cntl_1 = RREG32(MPLL_FUNC_CNTL_1);4056si_pi->clock_registers.mpll_func_cntl_2 = RREG32(MPLL_FUNC_CNTL_2);4057si_pi->clock_registers.mpll_ss1 = RREG32(MPLL_SS1);4058si_pi->clock_registers.mpll_ss2 = RREG32(MPLL_SS2);4059}40604061static void si_enable_thermal_protection(struct amdgpu_device *adev,4062bool enable)4063{4064if (enable)4065WREG32_P(mmGENERAL_PWRMGT, 0, ~GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK);4066else4067WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK, ~GENERAL_PWRMGT__THERMAL_PROTECTION_DIS_MASK);4068}40694070static void si_enable_acpi_power_management(struct amdgpu_device *adev)4071{4072WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__STATIC_PM_EN_MASK, ~GENERAL_PWRMGT__STATIC_PM_EN_MASK);4073}40744075#if 04076static int si_enter_ulp_state(struct amdgpu_device *adev)4077{4078WREG32(SMC_MESSAGE_0, PPSMC_MSG_SwitchToMinimumPower);40794080udelay(25000);40814082return 0;4083}40844085static int si_exit_ulp_state(struct amdgpu_device *adev)4086{4087int i;40884089WREG32(SMC_MESSAGE_0, PPSMC_MSG_ResumeFromMinimumPower);40904091udelay(7000);40924093for (i = 0; i < adev->usec_timeout; i++) {4094if (RREG32(SMC_RESP_0) == 1)4095break;4096udelay(1000);4097}40984099return 0;4100}4101#endif41024103static int si_notify_smc_display_change(struct amdgpu_device *adev,4104bool has_display)4105{4106PPSMC_Msg msg = has_display ?4107PPSMC_MSG_HasDisplay : PPSMC_MSG_NoDisplay;41084109return (amdgpu_si_send_msg_to_smc(adev, msg) == PPSMC_Result_OK) ?41100 : -EINVAL;4111}41124113static void si_program_response_times(struct amdgpu_device *adev)4114{4115u32 voltage_response_time, acpi_delay_time, vbi_time_out;4116u32 vddc_dly, acpi_dly, vbi_dly;4117u32 reference_clock;41184119si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_mvdd_chg_time, 1);41204121voltage_response_time = (u32)adev->pm.dpm.voltage_response_time;41224123if (voltage_response_time == 0)4124voltage_response_time = 1000;41254126acpi_delay_time = 15000;4127vbi_time_out = 100000;41284129reference_clock = amdgpu_asic_get_xclk(adev);41304131vddc_dly = (voltage_response_time * reference_clock) / 100;4132acpi_dly = (acpi_delay_time * reference_clock) / 100;4133vbi_dly = (vbi_time_out * reference_clock) / 100;41344135si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_delay_vreg, vddc_dly);4136si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_delay_acpi, acpi_dly);4137si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);4138si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_mc_block_delay, 0xAA);4139}41404141static void si_program_ds_registers(struct amdgpu_device *adev)4142{4143struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);4144u32 tmp;41454146/* DEEP_SLEEP_CLK_SEL field should be 0x10 on tahiti A0 */4147if (adev->asic_type == CHIP_TAHITI && adev->rev_id == 0x0)4148tmp = 0x10;4149else4150tmp = 0x1;41514152if (eg_pi->sclk_deep_sleep) {4153WREG32_P(mmMISC_CLK_CNTL, (tmp << MISC_CLK_CNTL__DEEP_SLEEP_CLK_SEL__SHIFT), ~MISC_CLK_CNTL__DEEP_SLEEP_CLK_SEL_MASK);4154WREG32_P(mmCG_SPLL_AUTOSCALE_CNTL, CG_SPLL_AUTOSCALE_CNTL__AUTOSCALE_ON_SS_CLEAR_MASK,4155~CG_SPLL_AUTOSCALE_CNTL__AUTOSCALE_ON_SS_CLEAR_MASK);4156}4157}41584159static void si_program_display_gap(struct amdgpu_device *adev)4160{4161u32 tmp, pipe;4162int i;41634164tmp = RREG32(mmCG_DISPLAY_GAP_CNTL) & ~(CG_DISPLAY_GAP_CNTL__DISP1_GAP_MASK | CG_DISPLAY_GAP_CNTL__DISP2_GAP_MASK);4165if (adev->pm.dpm.new_active_crtc_count > 0)4166tmp |= R600_PM_DISPLAY_GAP_VBLANK_OR_WM << CG_DISPLAY_GAP_CNTL__DISP1_GAP__SHIFT;4167else4168tmp |= R600_PM_DISPLAY_GAP_IGNORE << CG_DISPLAY_GAP_CNTL__DISP1_GAP__SHIFT;41694170if (adev->pm.dpm.new_active_crtc_count > 1)4171tmp |= R600_PM_DISPLAY_GAP_VBLANK_OR_WM << CG_DISPLAY_GAP_CNTL__DISP2_GAP__SHIFT;4172else4173tmp |= R600_PM_DISPLAY_GAP_IGNORE << CG_DISPLAY_GAP_CNTL__DISP2_GAP__SHIFT;41744175WREG32(mmCG_DISPLAY_GAP_CNTL, tmp);41764177tmp = RREG32(DCCG_DISP_SLOW_SELECT_REG);4178pipe = (tmp & DCCG_DISP1_SLOW_SELECT_MASK) >> DCCG_DISP1_SLOW_SELECT_SHIFT;41794180if ((adev->pm.dpm.new_active_crtc_count > 0) &&4181(!(adev->pm.dpm.new_active_crtcs & (1 << pipe)))) {4182/* find the first active crtc */4183for (i = 0; i < adev->mode_info.num_crtc; i++) {4184if (adev->pm.dpm.new_active_crtcs & (1 << i))4185break;4186}4187if (i == adev->mode_info.num_crtc)4188pipe = 0;4189else4190pipe = i;41914192tmp &= ~DCCG_DISP1_SLOW_SELECT_MASK;4193tmp |= DCCG_DISP1_SLOW_SELECT(pipe);4194WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp);4195}41964197/* Setting this to false forces the performance state to low if the crtcs are disabled.4198* This can be a problem on PowerXpress systems or if you want to use the card4199* for offscreen rendering or compute if there are no crtcs enabled.4200*/4201si_notify_smc_display_change(adev, adev->pm.dpm.new_active_crtc_count > 0);4202}42034204static void si_enable_spread_spectrum(struct amdgpu_device *adev, bool enable)4205{4206struct rv7xx_power_info *pi = rv770_get_pi(adev);42074208if (enable) {4209if (pi->sclk_ss)4210WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__DYN_SPREAD_SPECTRUM_EN_MASK, ~GENERAL_PWRMGT__DYN_SPREAD_SPECTRUM_EN_MASK);4211} else {4212WREG32_P(mmCG_SPLL_SPREAD_SPECTRUM, 0, ~CG_SPLL_SPREAD_SPECTRUM__SSEN_MASK);4213WREG32_P(mmGENERAL_PWRMGT, 0, ~GENERAL_PWRMGT__DYN_SPREAD_SPECTRUM_EN_MASK);4214}4215}42164217static void si_setup_bsp(struct amdgpu_device *adev)4218{4219struct rv7xx_power_info *pi = rv770_get_pi(adev);4220u32 xclk = amdgpu_asic_get_xclk(adev);42214222r600_calculate_u_and_p(pi->asi,4223xclk,422416,4225&pi->bsp,4226&pi->bsu);42274228r600_calculate_u_and_p(pi->pasi,4229xclk,423016,4231&pi->pbsp,4232&pi->pbsu);423342344235pi->dsp = (pi->bsp << CG_BSP__BSP__SHIFT) | (pi->bsu << CG_BSP__BSU__SHIFT);4236pi->psp = (pi->pbsp << CG_BSP__BSP__SHIFT) | (pi->pbsu << CG_BSP__BSU__SHIFT);42374238WREG32(mmCG_BSP, pi->dsp);4239}42404241static void si_program_git(struct amdgpu_device *adev)4242{4243WREG32_P(mmCG_GIT, R600_GICST_DFLT << CG_GIT__CG_GICST__SHIFT, ~CG_GIT__CG_GICST_MASK);4244}42454246static void si_program_tp(struct amdgpu_device *adev)4247{4248int i;4249enum r600_td td = R600_TD_DFLT;42504251for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)4252WREG32(mmCG_FFCT_0 + i, (r600_utc[i] << CG_FFCT_0__UTC_0__SHIFT | r600_dtc[i] << CG_FFCT_0__DTC_0__SHIFT));42534254if (td == R600_TD_AUTO)4255WREG32_P(mmSCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_CNTL__FIR_FORCE_TREND_SEL_MASK);4256else4257WREG32_P(mmSCLK_PWRMGT_CNTL, SCLK_PWRMGT_CNTL__FIR_FORCE_TREND_SEL_MASK, ~SCLK_PWRMGT_CNTL__FIR_FORCE_TREND_SEL_MASK);42584259if (td == R600_TD_UP)4260WREG32_P(mmSCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_CNTL__FIR_TREND_MODE_MASK);42614262if (td == R600_TD_DOWN)4263WREG32_P(mmSCLK_PWRMGT_CNTL, SCLK_PWRMGT_CNTL__FIR_TREND_MODE_MASK, ~SCLK_PWRMGT_CNTL__FIR_TREND_MODE_MASK);4264}42654266static void si_program_tpp(struct amdgpu_device *adev)4267{4268WREG32(mmCG_TPC, R600_TPC_DFLT);4269}42704271static void si_program_sstp(struct amdgpu_device *adev)4272{4273WREG32(mmCG_SSP, (R600_SSTU_DFLT << CG_SSP__SSTU__SHIFT| R600_SST_DFLT << CG_SSP__SST__SHIFT));4274}42754276static void si_enable_display_gap(struct amdgpu_device *adev)4277{4278u32 tmp = RREG32(mmCG_DISPLAY_GAP_CNTL);42794280tmp &= ~(CG_DISPLAY_GAP_CNTL__DISP1_GAP_MASK | CG_DISPLAY_GAP_CNTL__DISP2_GAP_MASK);4281tmp |= (R600_PM_DISPLAY_GAP_IGNORE << CG_DISPLAY_GAP_CNTL__DISP1_GAP__SHIFT |4282R600_PM_DISPLAY_GAP_IGNORE << CG_DISPLAY_GAP_CNTL__DISP2_GAP__SHIFT);42834284tmp &= ~(CG_DISPLAY_GAP_CNTL__DISP1_GAP_MCHG_MASK | CG_DISPLAY_GAP_CNTL__DISP2_GAP_MCHG_MASK);4285tmp |= (R600_PM_DISPLAY_GAP_VBLANK << CG_DISPLAY_GAP_CNTL__DISP1_GAP_MCHG__SHIFT |4286R600_PM_DISPLAY_GAP_IGNORE << CG_DISPLAY_GAP_CNTL__DISP2_GAP_MCHG__SHIFT);4287WREG32(mmCG_DISPLAY_GAP_CNTL, tmp);4288}42894290static void si_program_vc(struct amdgpu_device *adev)4291{4292struct rv7xx_power_info *pi = rv770_get_pi(adev);42934294WREG32(mmCG_FTV, pi->vrc);4295}42964297static void si_clear_vc(struct amdgpu_device *adev)4298{4299WREG32(mmCG_FTV, 0);4300}43014302static u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock)4303{4304u8 mc_para_index;43054306if (memory_clock < 10000)4307mc_para_index = 0;4308else if (memory_clock >= 80000)4309mc_para_index = 0x0f;4310else4311mc_para_index = (u8)((memory_clock - 10000) / 5000 + 1);4312return mc_para_index;4313}43144315static u8 si_get_mclk_frequency_ratio(u32 memory_clock, bool strobe_mode)4316{4317u8 mc_para_index;43184319if (strobe_mode) {4320if (memory_clock < 12500)4321mc_para_index = 0x00;4322else if (memory_clock > 47500)4323mc_para_index = 0x0f;4324else4325mc_para_index = (u8)((memory_clock - 10000) / 2500);4326} else {4327if (memory_clock < 65000)4328mc_para_index = 0x00;4329else if (memory_clock > 135000)4330mc_para_index = 0x0f;4331else4332mc_para_index = (u8)((memory_clock - 60000) / 5000);4333}4334return mc_para_index;4335}43364337static u8 si_get_strobe_mode_settings(struct amdgpu_device *adev, u32 mclk)4338{4339struct rv7xx_power_info *pi = rv770_get_pi(adev);4340bool strobe_mode = false;4341u8 result = 0;43424343if (mclk <= pi->mclk_strobe_mode_threshold)4344strobe_mode = true;43454346if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5)4347result = si_get_mclk_frequency_ratio(mclk, strobe_mode);4348else4349result = si_get_ddr3_mclk_frequency_ratio(mclk);43504351if (strobe_mode)4352result |= SISLANDS_SMC_STROBE_ENABLE;43534354return result;4355}43564357static int si_upload_firmware(struct amdgpu_device *adev)4358{4359struct si_power_info *si_pi = si_get_pi(adev);43604361amdgpu_si_reset_smc(adev);4362amdgpu_si_smc_clock(adev, false);43634364return amdgpu_si_load_smc_ucode(adev, si_pi->sram_end);4365}43664367static bool si_validate_phase_shedding_tables(struct amdgpu_device *adev,4368const struct atom_voltage_table *table,4369const struct amdgpu_phase_shedding_limits_table *limits)4370{4371u32 data, num_bits, num_levels;43724373if ((table == NULL) || (limits == NULL))4374return false;43754376data = table->mask_low;43774378num_bits = hweight32(data);43794380if (num_bits == 0)4381return false;43824383num_levels = (1 << num_bits);43844385if (table->count != num_levels)4386return false;43874388if (limits->count != (num_levels - 1))4389return false;43904391return true;4392}43934394static void si_trim_voltage_table_to_fit_state_table(struct amdgpu_device *adev,4395u32 max_voltage_steps,4396struct atom_voltage_table *voltage_table)4397{4398unsigned int i, diff;43994400if (voltage_table->count <= max_voltage_steps)4401return;44024403diff = voltage_table->count - max_voltage_steps;44044405for (i= 0; i < max_voltage_steps; i++)4406voltage_table->entries[i] = voltage_table->entries[i + diff];44074408voltage_table->count = max_voltage_steps;4409}44104411static int si_get_svi2_voltage_table(struct amdgpu_device *adev,4412struct amdgpu_clock_voltage_dependency_table *voltage_dependency_table,4413struct atom_voltage_table *voltage_table)4414{4415u32 i;44164417if (voltage_dependency_table == NULL)4418return -EINVAL;44194420voltage_table->mask_low = 0;4421voltage_table->phase_delay = 0;44224423voltage_table->count = voltage_dependency_table->count;4424for (i = 0; i < voltage_table->count; i++) {4425voltage_table->entries[i].value = voltage_dependency_table->entries[i].v;4426voltage_table->entries[i].smio_low = 0;4427}44284429return 0;4430}44314432static int si_construct_voltage_tables(struct amdgpu_device *adev)4433{4434struct rv7xx_power_info *pi = rv770_get_pi(adev);4435struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);4436struct si_power_info *si_pi = si_get_pi(adev);4437int ret;44384439if (pi->voltage_control) {4440ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_VDDC,4441VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddc_voltage_table);4442if (ret)4443return ret;44444445if (eg_pi->vddc_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)4446si_trim_voltage_table_to_fit_state_table(adev,4447SISLANDS_MAX_NO_VREG_STEPS,4448&eg_pi->vddc_voltage_table);4449} else if (si_pi->voltage_control_svi2) {4450ret = si_get_svi2_voltage_table(adev,4451&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,4452&eg_pi->vddc_voltage_table);4453if (ret)4454return ret;4455} else {4456return -EINVAL;4457}44584459if (eg_pi->vddci_control) {4460ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_VDDCI,4461VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddci_voltage_table);4462if (ret)4463return ret;44644465if (eg_pi->vddci_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)4466si_trim_voltage_table_to_fit_state_table(adev,4467SISLANDS_MAX_NO_VREG_STEPS,4468&eg_pi->vddci_voltage_table);4469}4470if (si_pi->vddci_control_svi2) {4471ret = si_get_svi2_voltage_table(adev,4472&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,4473&eg_pi->vddci_voltage_table);4474if (ret)4475return ret;4476}44774478if (pi->mvdd_control) {4479ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_MVDDC,4480VOLTAGE_OBJ_GPIO_LUT, &si_pi->mvdd_voltage_table);44814482if (ret) {4483pi->mvdd_control = false;4484return ret;4485}44864487if (si_pi->mvdd_voltage_table.count == 0) {4488pi->mvdd_control = false;4489return -EINVAL;4490}44914492if (si_pi->mvdd_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)4493si_trim_voltage_table_to_fit_state_table(adev,4494SISLANDS_MAX_NO_VREG_STEPS,4495&si_pi->mvdd_voltage_table);4496}44974498if (si_pi->vddc_phase_shed_control) {4499ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_VDDC,4500VOLTAGE_OBJ_PHASE_LUT, &si_pi->vddc_phase_shed_table);4501if (ret)4502si_pi->vddc_phase_shed_control = false;45034504if ((si_pi->vddc_phase_shed_table.count == 0) ||4505(si_pi->vddc_phase_shed_table.count > SISLANDS_MAX_NO_VREG_STEPS))4506si_pi->vddc_phase_shed_control = false;4507}45084509return 0;4510}45114512static void si_populate_smc_voltage_table(struct amdgpu_device *adev,4513const struct atom_voltage_table *voltage_table,4514SISLANDS_SMC_STATETABLE *table)4515{4516unsigned int i;45174518for (i = 0; i < voltage_table->count; i++)4519table->lowSMIO[i] |= cpu_to_be32(voltage_table->entries[i].smio_low);4520}45214522static int si_populate_smc_voltage_tables(struct amdgpu_device *adev,4523SISLANDS_SMC_STATETABLE *table)4524{4525struct rv7xx_power_info *pi = rv770_get_pi(adev);4526struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);4527struct si_power_info *si_pi = si_get_pi(adev);4528u8 i;45294530if (si_pi->voltage_control_svi2) {4531si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc,4532si_pi->svc_gpio_id);4533si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd,4534si_pi->svd_gpio_id);4535si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_svi_rework_plat_type,45362);4537} else {4538if (eg_pi->vddc_voltage_table.count) {4539si_populate_smc_voltage_table(adev, &eg_pi->vddc_voltage_table, table);4540table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =4541cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);45424543for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {4544if (pi->max_vddc_in_table <= eg_pi->vddc_voltage_table.entries[i].value) {4545table->maxVDDCIndexInPPTable = i;4546break;4547}4548}4549}45504551if (eg_pi->vddci_voltage_table.count) {4552si_populate_smc_voltage_table(adev, &eg_pi->vddci_voltage_table, table);45534554table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDCI] =4555cpu_to_be32(eg_pi->vddci_voltage_table.mask_low);4556}455745584559if (si_pi->mvdd_voltage_table.count) {4560si_populate_smc_voltage_table(adev, &si_pi->mvdd_voltage_table, table);45614562table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_MVDD] =4563cpu_to_be32(si_pi->mvdd_voltage_table.mask_low);4564}45654566if (si_pi->vddc_phase_shed_control) {4567if (si_validate_phase_shedding_tables(adev, &si_pi->vddc_phase_shed_table,4568&adev->pm.dpm.dyn_state.phase_shedding_limits_table)) {4569si_populate_smc_voltage_table(adev, &si_pi->vddc_phase_shed_table, table);45704571table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] =4572cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low);45734574si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_phase_shedding_delay,4575(u32)si_pi->vddc_phase_shed_table.phase_delay);4576} else {4577si_pi->vddc_phase_shed_control = false;4578}4579}4580}45814582return 0;4583}45844585static int si_populate_voltage_value(struct amdgpu_device *adev,4586const struct atom_voltage_table *table,4587u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage)4588{4589unsigned int i;45904591for (i = 0; i < table->count; i++) {4592if (value <= table->entries[i].value) {4593voltage->index = (u8)i;4594voltage->value = cpu_to_be16(table->entries[i].value);4595break;4596}4597}45984599if (i >= table->count)4600return -EINVAL;46014602return 0;4603}46044605static int si_populate_mvdd_value(struct amdgpu_device *adev, u32 mclk,4606SISLANDS_SMC_VOLTAGE_VALUE *voltage)4607{4608struct rv7xx_power_info *pi = rv770_get_pi(adev);4609struct si_power_info *si_pi = si_get_pi(adev);46104611if (pi->mvdd_control) {4612if (mclk <= pi->mvdd_split_frequency)4613voltage->index = 0;4614else4615voltage->index = (u8)(si_pi->mvdd_voltage_table.count) - 1;46164617voltage->value = cpu_to_be16(si_pi->mvdd_voltage_table.entries[voltage->index].value);4618}4619return 0;4620}46214622static int si_get_std_voltage_value(struct amdgpu_device *adev,4623SISLANDS_SMC_VOLTAGE_VALUE *voltage,4624u16 *std_voltage)4625{4626u16 v_index;4627bool voltage_found = false;4628*std_voltage = be16_to_cpu(voltage->value);46294630if (adev->pm.dpm.dyn_state.cac_leakage_table.entries) {4631if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_NEW_CAC_VOLTAGE) {4632if (adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries == NULL)4633return -EINVAL;46344635for (v_index = 0; (u32)v_index < adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; v_index++) {4636if (be16_to_cpu(voltage->value) ==4637(u16)adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[v_index].v) {4638voltage_found = true;4639if ((u32)v_index < adev->pm.dpm.dyn_state.cac_leakage_table.count)4640*std_voltage =4641adev->pm.dpm.dyn_state.cac_leakage_table.entries[v_index].vddc;4642else4643*std_voltage =4644adev->pm.dpm.dyn_state.cac_leakage_table.entries[adev->pm.dpm.dyn_state.cac_leakage_table.count-1].vddc;4645break;4646}4647}46484649if (!voltage_found) {4650for (v_index = 0; (u32)v_index < adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; v_index++) {4651if (be16_to_cpu(voltage->value) <=4652(u16)adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[v_index].v) {4653voltage_found = true;4654if ((u32)v_index < adev->pm.dpm.dyn_state.cac_leakage_table.count)4655*std_voltage =4656adev->pm.dpm.dyn_state.cac_leakage_table.entries[v_index].vddc;4657else4658*std_voltage =4659adev->pm.dpm.dyn_state.cac_leakage_table.entries[adev->pm.dpm.dyn_state.cac_leakage_table.count-1].vddc;4660break;4661}4662}4663}4664} else {4665if ((u32)voltage->index < adev->pm.dpm.dyn_state.cac_leakage_table.count)4666*std_voltage = adev->pm.dpm.dyn_state.cac_leakage_table.entries[voltage->index].vddc;4667}4668}46694670return 0;4671}46724673static int si_populate_std_voltage_value(struct amdgpu_device *adev,4674u16 value, u8 index,4675SISLANDS_SMC_VOLTAGE_VALUE *voltage)4676{4677voltage->index = index;4678voltage->value = cpu_to_be16(value);46794680return 0;4681}46824683static int si_populate_phase_shedding_value(struct amdgpu_device *adev,4684const struct amdgpu_phase_shedding_limits_table *limits,4685u16 voltage, u32 sclk, u32 mclk,4686SISLANDS_SMC_VOLTAGE_VALUE *smc_voltage)4687{4688unsigned int i;46894690for (i = 0; i < limits->count; i++) {4691if ((voltage <= limits->entries[i].voltage) &&4692(sclk <= limits->entries[i].sclk) &&4693(mclk <= limits->entries[i].mclk))4694break;4695}46964697smc_voltage->phase_settings = (u8)i;46984699return 0;4700}47014702static int si_init_arb_table_index(struct amdgpu_device *adev)4703{4704struct si_power_info *si_pi = si_get_pi(adev);4705u32 tmp;4706int ret;47074708ret = amdgpu_si_read_smc_sram_dword(adev, si_pi->arb_table_start,4709&tmp, si_pi->sram_end);4710if (ret)4711return ret;47124713tmp &= 0x00FFFFFF;4714tmp |= MC_CG_ARB_FREQ_F1 << 24;47154716return amdgpu_si_write_smc_sram_dword(adev, si_pi->arb_table_start,4717tmp, si_pi->sram_end);4718}47194720static int si_initial_switch_from_arb_f0_to_f1(struct amdgpu_device *adev)4721{4722return ni_copy_and_switch_arb_sets(adev, MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);4723}47244725static int si_reset_to_default(struct amdgpu_device *adev)4726{4727return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_ResetToDefaults) == PPSMC_Result_OK) ?47280 : -EINVAL;4729}47304731static int si_force_switch_to_arb_f0(struct amdgpu_device *adev)4732{4733struct si_power_info *si_pi = si_get_pi(adev);4734u32 tmp;4735int ret;47364737ret = amdgpu_si_read_smc_sram_dword(adev, si_pi->arb_table_start,4738&tmp, si_pi->sram_end);4739if (ret)4740return ret;47414742tmp = (tmp >> 24) & 0xff;47434744if (tmp == MC_CG_ARB_FREQ_F0)4745return 0;47464747return ni_copy_and_switch_arb_sets(adev, tmp, MC_CG_ARB_FREQ_F0);4748}47494750static u32 si_calculate_memory_refresh_rate(struct amdgpu_device *adev,4751u32 engine_clock)4752{4753u32 dram_rows;4754u32 dram_refresh_rate;4755u32 mc_arb_rfsh_rate;4756u32 tmp = (RREG32(mmMC_ARB_RAMCFG) & MC_ARB_RAMCFG__NOOFROWS_MASK) >> MC_ARB_RAMCFG__NOOFROWS__SHIFT;47574758if (tmp >= 4)4759dram_rows = 16384;4760else4761dram_rows = 1 << (tmp + 10);47624763dram_refresh_rate = 1 << ((RREG32(MC_SEQ_MISC0) & 0x3) + 3);4764mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64;47654766return mc_arb_rfsh_rate;4767}47684769static int si_populate_memory_timing_parameters(struct amdgpu_device *adev,4770struct rv7xx_pl *pl,4771SMC_SIslands_MCArbDramTimingRegisterSet *arb_regs)4772{4773u32 dram_timing;4774u32 dram_timing2;4775u32 burst_time;4776int ret;47774778arb_regs->mc_arb_rfsh_rate =4779(u8)si_calculate_memory_refresh_rate(adev, pl->sclk);47804781ret = amdgpu_atombios_set_engine_dram_timings(adev, pl->sclk,4782pl->mclk);4783if (ret)4784return ret;47854786dram_timing = RREG32(MC_ARB_DRAM_TIMING);4787dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);4788burst_time = RREG32(MC_ARB_BURST_TIME) & STATE0_MASK;47894790arb_regs->mc_arb_dram_timing = cpu_to_be32(dram_timing);4791arb_regs->mc_arb_dram_timing2 = cpu_to_be32(dram_timing2);4792arb_regs->mc_arb_burst_time = (u8)burst_time;47934794return 0;4795}47964797static int si_do_program_memory_timing_parameters(struct amdgpu_device *adev,4798struct amdgpu_ps *amdgpu_state,4799unsigned int first_arb_set)4800{4801struct si_power_info *si_pi = si_get_pi(adev);4802struct si_ps *state = si_get_ps(amdgpu_state);4803SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };4804int i, ret = 0;48054806for (i = 0; i < state->performance_level_count; i++) {4807ret = si_populate_memory_timing_parameters(adev, &state->performance_levels[i], &arb_regs);4808if (ret)4809break;4810ret = amdgpu_si_copy_bytes_to_smc(adev,4811si_pi->arb_table_start +4812offsetof(SMC_SIslands_MCArbDramTimingRegisters, data) +4813sizeof(SMC_SIslands_MCArbDramTimingRegisterSet) * (first_arb_set + i),4814(u8 *)&arb_regs,4815sizeof(SMC_SIslands_MCArbDramTimingRegisterSet),4816si_pi->sram_end);4817if (ret)4818break;4819}48204821return ret;4822}48234824static int si_program_memory_timing_parameters(struct amdgpu_device *adev,4825struct amdgpu_ps *amdgpu_new_state)4826{4827return si_do_program_memory_timing_parameters(adev, amdgpu_new_state,4828SISLANDS_DRIVER_STATE_ARB_INDEX);4829}48304831static int si_populate_initial_mvdd_value(struct amdgpu_device *adev,4832struct SISLANDS_SMC_VOLTAGE_VALUE *voltage)4833{4834struct rv7xx_power_info *pi = rv770_get_pi(adev);4835struct si_power_info *si_pi = si_get_pi(adev);48364837if (pi->mvdd_control)4838return si_populate_voltage_value(adev, &si_pi->mvdd_voltage_table,4839si_pi->mvdd_bootup_value, voltage);48404841return 0;4842}48434844static int si_populate_smc_initial_state(struct amdgpu_device *adev,4845struct amdgpu_ps *amdgpu_initial_state,4846SISLANDS_SMC_STATETABLE *table)4847{4848struct si_ps *initial_state = si_get_ps(amdgpu_initial_state);4849struct rv7xx_power_info *pi = rv770_get_pi(adev);4850struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);4851struct si_power_info *si_pi = si_get_pi(adev);4852u32 reg;4853int ret;48544855table->initialState.level.mclk.vDLL_CNTL =4856cpu_to_be32(si_pi->clock_registers.dll_cntl);4857table->initialState.level.mclk.vMCLK_PWRMGT_CNTL =4858cpu_to_be32(si_pi->clock_registers.mclk_pwrmgt_cntl);4859table->initialState.level.mclk.vMPLL_AD_FUNC_CNTL =4860cpu_to_be32(si_pi->clock_registers.mpll_ad_func_cntl);4861table->initialState.level.mclk.vMPLL_DQ_FUNC_CNTL =4862cpu_to_be32(si_pi->clock_registers.mpll_dq_func_cntl);4863table->initialState.level.mclk.vMPLL_FUNC_CNTL =4864cpu_to_be32(si_pi->clock_registers.mpll_func_cntl);4865table->initialState.level.mclk.vMPLL_FUNC_CNTL_1 =4866cpu_to_be32(si_pi->clock_registers.mpll_func_cntl_1);4867table->initialState.level.mclk.vMPLL_FUNC_CNTL_2 =4868cpu_to_be32(si_pi->clock_registers.mpll_func_cntl_2);4869table->initialState.level.mclk.vMPLL_SS =4870cpu_to_be32(si_pi->clock_registers.mpll_ss1);4871table->initialState.level.mclk.vMPLL_SS2 =4872cpu_to_be32(si_pi->clock_registers.mpll_ss2);48734874table->initialState.level.mclk.mclk_value =4875cpu_to_be32(initial_state->performance_levels[0].mclk);48764877table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL =4878cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl);4879table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_2 =4880cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_2);4881table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_3 =4882cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_3);4883table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_4 =4884cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_4);4885table->initialState.level.sclk.vCG_SPLL_SPREAD_SPECTRUM =4886cpu_to_be32(si_pi->clock_registers.cg_spll_spread_spectrum);4887table->initialState.level.sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =4888cpu_to_be32(si_pi->clock_registers.cg_spll_spread_spectrum_2);48894890table->initialState.level.sclk.sclk_value =4891cpu_to_be32(initial_state->performance_levels[0].sclk);48924893table->initialState.level.arbRefreshState =4894SISLANDS_INITIAL_STATE_ARB_INDEX;48954896table->initialState.level.ACIndex = 0;48974898ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,4899initial_state->performance_levels[0].vddc,4900&table->initialState.level.vddc);49014902if (!ret) {4903u16 std_vddc;49044905ret = si_get_std_voltage_value(adev,4906&table->initialState.level.vddc,4907&std_vddc);4908if (!ret)4909si_populate_std_voltage_value(adev, std_vddc,4910table->initialState.level.vddc.index,4911&table->initialState.level.std_vddc);4912}49134914if (eg_pi->vddci_control)4915si_populate_voltage_value(adev,4916&eg_pi->vddci_voltage_table,4917initial_state->performance_levels[0].vddci,4918&table->initialState.level.vddci);49194920if (si_pi->vddc_phase_shed_control)4921si_populate_phase_shedding_value(adev,4922&adev->pm.dpm.dyn_state.phase_shedding_limits_table,4923initial_state->performance_levels[0].vddc,4924initial_state->performance_levels[0].sclk,4925initial_state->performance_levels[0].mclk,4926&table->initialState.level.vddc);49274928si_populate_initial_mvdd_value(adev, &table->initialState.level.mvdd);49294930reg = 0xffff << CG_AT__CG_R__SHIFT | 0 << CG_AT__CG_L__SHIFT;4931table->initialState.level.aT = cpu_to_be32(reg);4932table->initialState.level.bSP = cpu_to_be32(pi->dsp);4933table->initialState.level.gen2PCIE = (u8)si_pi->boot_pcie_gen;49344935if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5) {4936table->initialState.level.strobeMode =4937si_get_strobe_mode_settings(adev,4938initial_state->performance_levels[0].mclk);49394940if (initial_state->performance_levels[0].mclk > pi->mclk_edc_enable_threshold)4941table->initialState.level.mcFlags = SISLANDS_SMC_MC_EDC_RD_FLAG | SISLANDS_SMC_MC_EDC_WR_FLAG;4942else4943table->initialState.level.mcFlags = 0;4944}49454946table->initialState.levelCount = 1;49474948table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;49494950table->initialState.level.dpm2.MaxPS = 0;4951table->initialState.level.dpm2.NearTDPDec = 0;4952table->initialState.level.dpm2.AboveSafeInc = 0;4953table->initialState.level.dpm2.BelowSafeInc = 0;4954table->initialState.level.dpm2.PwrEfficiencyRatio = 0;49554956reg = SQ_POWER_THROTTLE__MIN_POWER_MASK |4957SQ_POWER_THROTTLE__MAX_POWER_MASK;4958table->initialState.level.SQPowerThrottle = cpu_to_be32(reg);49594960reg = SQ_POWER_THROTTLE2__MAX_POWER_DELTA_MASK |4961SQ_POWER_THROTTLE2__SHORT_TERM_INTERVAL_SIZE_MASK |4962SQ_POWER_THROTTLE2__LONG_TERM_INTERVAL_RATIO_MASK;4963table->initialState.level.SQPowerThrottle_2 = cpu_to_be32(reg);49644965return 0;4966}49674968static enum si_pcie_gen si_gen_pcie_gen_support(struct amdgpu_device *adev,4969u32 sys_mask,4970enum si_pcie_gen asic_gen,4971enum si_pcie_gen default_gen)4972{4973switch (asic_gen) {4974case SI_PCIE_GEN1:4975return SI_PCIE_GEN1;4976case SI_PCIE_GEN2:4977return SI_PCIE_GEN2;4978case SI_PCIE_GEN3:4979return SI_PCIE_GEN3;4980default:4981if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) &&4982(default_gen == SI_PCIE_GEN3))4983return SI_PCIE_GEN3;4984else if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) &&4985(default_gen == SI_PCIE_GEN2))4986return SI_PCIE_GEN2;4987else4988return SI_PCIE_GEN1;4989}4990return SI_PCIE_GEN1;4991}49924993static int si_populate_smc_acpi_state(struct amdgpu_device *adev,4994SISLANDS_SMC_STATETABLE *table)4995{4996struct rv7xx_power_info *pi = rv770_get_pi(adev);4997struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);4998struct si_power_info *si_pi = si_get_pi(adev);4999u32 spll_func_cntl = si_pi->clock_registers.cg_spll_func_cntl;5000u32 spll_func_cntl_2 = si_pi->clock_registers.cg_spll_func_cntl_2;5001u32 spll_func_cntl_3 = si_pi->clock_registers.cg_spll_func_cntl_3;5002u32 spll_func_cntl_4 = si_pi->clock_registers.cg_spll_func_cntl_4;5003u32 dll_cntl = si_pi->clock_registers.dll_cntl;5004u32 mclk_pwrmgt_cntl = si_pi->clock_registers.mclk_pwrmgt_cntl;5005u32 mpll_ad_func_cntl = si_pi->clock_registers.mpll_ad_func_cntl;5006u32 mpll_dq_func_cntl = si_pi->clock_registers.mpll_dq_func_cntl;5007u32 mpll_func_cntl = si_pi->clock_registers.mpll_func_cntl;5008u32 mpll_func_cntl_1 = si_pi->clock_registers.mpll_func_cntl_1;5009u32 mpll_func_cntl_2 = si_pi->clock_registers.mpll_func_cntl_2;5010u32 reg;5011int ret;50125013table->ACPIState = table->initialState;50145015table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;50165017if (pi->acpi_vddc) {5018ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,5019pi->acpi_vddc, &table->ACPIState.level.vddc);5020if (!ret) {5021u16 std_vddc;50225023ret = si_get_std_voltage_value(adev,5024&table->ACPIState.level.vddc, &std_vddc);5025if (!ret)5026si_populate_std_voltage_value(adev, std_vddc,5027table->ACPIState.level.vddc.index,5028&table->ACPIState.level.std_vddc);5029}5030table->ACPIState.level.gen2PCIE = si_pi->acpi_pcie_gen;50315032if (si_pi->vddc_phase_shed_control) {5033si_populate_phase_shedding_value(adev,5034&adev->pm.dpm.dyn_state.phase_shedding_limits_table,5035pi->acpi_vddc,50360,50370,5038&table->ACPIState.level.vddc);5039}5040} else {5041ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,5042pi->min_vddc_in_table, &table->ACPIState.level.vddc);5043if (!ret) {5044u16 std_vddc;50455046ret = si_get_std_voltage_value(adev,5047&table->ACPIState.level.vddc, &std_vddc);50485049if (!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 =5055(u8)si_gen_pcie_gen_support(adev,5056si_pi->sys_pcie_mask,5057si_pi->boot_pcie_gen,5058SI_PCIE_GEN1);50595060if (si_pi->vddc_phase_shed_control)5061si_populate_phase_shedding_value(adev,5062&adev->pm.dpm.dyn_state.phase_shedding_limits_table,5063pi->min_vddc_in_table,50640,50650,5066&table->ACPIState.level.vddc);5067}50685069if (pi->acpi_vddc) {5070if (eg_pi->acpi_vddci)5071si_populate_voltage_value(adev, &eg_pi->vddci_voltage_table,5072eg_pi->acpi_vddci,5073&table->ACPIState.level.vddci);5074}50755076mclk_pwrmgt_cntl |= MRDCK0_RESET | MRDCK1_RESET;5077mclk_pwrmgt_cntl &= ~(MRDCK0_PDNB | MRDCK1_PDNB);50785079dll_cntl &= ~(MRDCK0_BYPASS | MRDCK1_BYPASS);50805081spll_func_cntl_2 &= ~CG_SPLL_FUNC_CNTL_2__SCLK_MUX_SEL_MASK;5082spll_func_cntl_2 |= 4 << CG_SPLL_FUNC_CNTL_2__SCLK_MUX_SEL__SHIFT;50835084table->ACPIState.level.mclk.vDLL_CNTL =5085cpu_to_be32(dll_cntl);5086table->ACPIState.level.mclk.vMCLK_PWRMGT_CNTL =5087cpu_to_be32(mclk_pwrmgt_cntl);5088table->ACPIState.level.mclk.vMPLL_AD_FUNC_CNTL =5089cpu_to_be32(mpll_ad_func_cntl);5090table->ACPIState.level.mclk.vMPLL_DQ_FUNC_CNTL =5091cpu_to_be32(mpll_dq_func_cntl);5092table->ACPIState.level.mclk.vMPLL_FUNC_CNTL =5093cpu_to_be32(mpll_func_cntl);5094table->ACPIState.level.mclk.vMPLL_FUNC_CNTL_1 =5095cpu_to_be32(mpll_func_cntl_1);5096table->ACPIState.level.mclk.vMPLL_FUNC_CNTL_2 =5097cpu_to_be32(mpll_func_cntl_2);5098table->ACPIState.level.mclk.vMPLL_SS =5099cpu_to_be32(si_pi->clock_registers.mpll_ss1);5100table->ACPIState.level.mclk.vMPLL_SS2 =5101cpu_to_be32(si_pi->clock_registers.mpll_ss2);51025103table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL =5104cpu_to_be32(spll_func_cntl);5105table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_2 =5106cpu_to_be32(spll_func_cntl_2);5107table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_3 =5108cpu_to_be32(spll_func_cntl_3);5109table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_4 =5110cpu_to_be32(spll_func_cntl_4);51115112table->ACPIState.level.mclk.mclk_value = 0;5113table->ACPIState.level.sclk.sclk_value = 0;51145115si_populate_mvdd_value(adev, 0, &table->ACPIState.level.mvdd);51165117if (eg_pi->dynamic_ac_timing)5118table->ACPIState.level.ACIndex = 0;51195120table->ACPIState.level.dpm2.MaxPS = 0;5121table->ACPIState.level.dpm2.NearTDPDec = 0;5122table->ACPIState.level.dpm2.AboveSafeInc = 0;5123table->ACPIState.level.dpm2.BelowSafeInc = 0;5124table->ACPIState.level.dpm2.PwrEfficiencyRatio = 0;51255126reg = SQ_POWER_THROTTLE__MIN_POWER_MASK | SQ_POWER_THROTTLE__MAX_POWER_MASK;5127table->ACPIState.level.SQPowerThrottle = cpu_to_be32(reg);51285129reg = SQ_POWER_THROTTLE2__MAX_POWER_DELTA_MASK | SQ_POWER_THROTTLE2__SHORT_TERM_INTERVAL_SIZE_MASK | SQ_POWER_THROTTLE2__LONG_TERM_INTERVAL_RATIO_MASK;5130table->ACPIState.level.SQPowerThrottle_2 = cpu_to_be32(reg);51315132return 0;5133}51345135static int si_populate_ulv_state(struct amdgpu_device *adev,5136struct SISLANDS_SMC_SWSTATE_SINGLE *state)5137{5138struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);5139struct si_power_info *si_pi = si_get_pi(adev);5140struct si_ulv_param *ulv = &si_pi->ulv;5141u32 sclk_in_sr = 1350; /* ??? */5142int ret;51435144ret = si_convert_power_level_to_smc(adev, &ulv->pl,5145&state->level);5146if (!ret) {5147if (eg_pi->sclk_deep_sleep) {5148if (sclk_in_sr <= SCLK_MIN_DEEPSLEEP_FREQ)5149state->level.stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_BYPASS;5150else5151state->level.stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE;5152}5153if (ulv->one_pcie_lane_in_ulv)5154state->flags |= PPSMC_SWSTATE_FLAG_PCIE_X1;5155state->level.arbRefreshState = (u8)(SISLANDS_ULV_STATE_ARB_INDEX);5156state->level.ACIndex = 1;5157state->level.std_vddc = state->level.vddc;5158state->levelCount = 1;51595160state->flags |= PPSMC_SWSTATE_FLAG_DC;5161}51625163return ret;5164}51655166static int si_program_ulv_memory_timing_parameters(struct amdgpu_device *adev)5167{5168struct si_power_info *si_pi = si_get_pi(adev);5169struct si_ulv_param *ulv = &si_pi->ulv;5170SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };5171int ret;51725173ret = si_populate_memory_timing_parameters(adev, &ulv->pl,5174&arb_regs);5175if (ret)5176return ret;51775178si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_ulv_volt_change_delay,5179ulv->volt_change_delay);51805181ret = amdgpu_si_copy_bytes_to_smc(adev,5182si_pi->arb_table_start +5183offsetof(SMC_SIslands_MCArbDramTimingRegisters, data) +5184sizeof(SMC_SIslands_MCArbDramTimingRegisterSet) * SISLANDS_ULV_STATE_ARB_INDEX,5185(u8 *)&arb_regs,5186sizeof(SMC_SIslands_MCArbDramTimingRegisterSet),5187si_pi->sram_end);51885189return ret;5190}51915192static void si_get_mvdd_configuration(struct amdgpu_device *adev)5193{5194struct rv7xx_power_info *pi = rv770_get_pi(adev);51955196pi->mvdd_split_frequency = 30000;5197}51985199static int si_init_smc_table(struct amdgpu_device *adev)5200{5201struct si_power_info *si_pi = si_get_pi(adev);5202struct amdgpu_ps *amdgpu_boot_state = adev->pm.dpm.boot_ps;5203const struct si_ulv_param *ulv = &si_pi->ulv;5204SISLANDS_SMC_STATETABLE *table = &si_pi->smc_statetable;5205int ret;5206u32 lane_width;5207u32 vr_hot_gpio;52085209si_populate_smc_voltage_tables(adev, table);52105211switch (adev->pm.int_thermal_type) {5212case THERMAL_TYPE_SI:5213case THERMAL_TYPE_EMC2103_WITH_INTERNAL:5214table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;5215break;5216case THERMAL_TYPE_NONE:5217table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;5218break;5219default:5220table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;5221break;5222}52235224if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)5225table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;52265227if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT) {5228if ((adev->pdev->device != 0x6818) && (adev->pdev->device != 0x6819))5229table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;5230}52315232if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)5233table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;52345235if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5)5236table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;52375238if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY)5239table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH;52405241if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE) {5242table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO;5243vr_hot_gpio = adev->pm.dpm.backbias_response_time;5244si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_vr_hot_gpio,5245vr_hot_gpio);5246}52475248ret = si_populate_smc_initial_state(adev, amdgpu_boot_state, table);5249if (ret)5250return ret;52515252ret = si_populate_smc_acpi_state(adev, table);5253if (ret)5254return ret;52555256table->driverState.flags = table->initialState.flags;5257table->driverState.levelCount = table->initialState.levelCount;5258table->driverState.levels[0] = table->initialState.level;52595260ret = si_do_program_memory_timing_parameters(adev, amdgpu_boot_state,5261SISLANDS_INITIAL_STATE_ARB_INDEX);5262if (ret)5263return ret;52645265if (ulv->supported && ulv->pl.vddc) {5266ret = si_populate_ulv_state(adev, &table->ULVState);5267if (ret)5268return ret;52695270ret = si_program_ulv_memory_timing_parameters(adev);5271if (ret)5272return ret;52735274WREG32(mmCG_ULV_CONTROL, ulv->cg_ulv_control);5275WREG32(mmCG_ULV_PARAMETER, ulv->cg_ulv_parameter);52765277lane_width = amdgpu_get_pcie_lanes(adev);5278si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width, lane_width);5279} else {5280table->ULVState = table->initialState;5281}52825283return amdgpu_si_copy_bytes_to_smc(adev, si_pi->state_table_start,5284(u8 *)table, sizeof(SISLANDS_SMC_STATETABLE),5285si_pi->sram_end);5286}52875288static int si_calculate_sclk_params(struct amdgpu_device *adev,5289u32 engine_clock,5290SISLANDS_SMC_SCLK_VALUE *sclk)5291{5292struct rv7xx_power_info *pi = rv770_get_pi(adev);5293struct si_power_info *si_pi = si_get_pi(adev);5294struct atom_clock_dividers dividers;5295u32 spll_func_cntl = si_pi->clock_registers.cg_spll_func_cntl;5296u32 spll_func_cntl_2 = si_pi->clock_registers.cg_spll_func_cntl_2;5297u32 spll_func_cntl_3 = si_pi->clock_registers.cg_spll_func_cntl_3;5298u32 spll_func_cntl_4 = si_pi->clock_registers.cg_spll_func_cntl_4;5299u32 cg_spll_spread_spectrum = si_pi->clock_registers.cg_spll_spread_spectrum;5300u32 cg_spll_spread_spectrum_2 = si_pi->clock_registers.cg_spll_spread_spectrum_2;5301u64 tmp;5302u32 reference_clock = adev->clock.spll.reference_freq;5303u32 reference_divider;5304u32 fbdiv;5305int ret;53065307ret = amdgpu_atombios_get_clock_dividers(adev, COMPUTE_ENGINE_PLL_PARAM,5308engine_clock, false, ÷rs);5309if (ret)5310return ret;53115312reference_divider = 1 + dividers.ref_div;53135314tmp = (u64) engine_clock * reference_divider * dividers.post_div * 16384;5315do_div(tmp, reference_clock);5316fbdiv = (u32) tmp;53175318spll_func_cntl &= ~(CG_SPLL_FUNC_CNTL__SPLL_PDIV_A_MASK | CG_SPLL_FUNC_CNTL__SPLL_REF_DIV_MASK);5319spll_func_cntl |= dividers.ref_div << CG_SPLL_FUNC_CNTL__SPLL_REF_DIV__SHIFT;5320spll_func_cntl |= dividers.post_div << CG_SPLL_FUNC_CNTL__SPLL_PDIV_A__SHIFT;53215322spll_func_cntl_2 &= ~CG_SPLL_FUNC_CNTL_2__SCLK_MUX_SEL_MASK;5323spll_func_cntl_2 |= 2 << CG_SPLL_FUNC_CNTL_2__SCLK_MUX_SEL__SHIFT;53245325spll_func_cntl_3 &= ~CG_SPLL_FUNC_CNTL_3__SPLL_FB_DIV_MASK;5326spll_func_cntl_3 |= fbdiv << CG_SPLL_FUNC_CNTL_3__SPLL_FB_DIV__SHIFT;5327spll_func_cntl_3 |= CG_SPLL_FUNC_CNTL_3__SPLL_DITHEN_MASK;53285329if (pi->sclk_ss) {5330struct amdgpu_atom_ss ss;5331u32 vco_freq = engine_clock * dividers.post_div;53325333if (amdgpu_atombios_get_asic_ss_info(adev, &ss,5334ASIC_INTERNAL_ENGINE_SS, vco_freq)) {5335u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);5336u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000);53375338cg_spll_spread_spectrum &= ~CG_SPLL_SPREAD_SPECTRUM__CLK_S_MASK;5339cg_spll_spread_spectrum |= clk_s << CG_SPLL_SPREAD_SPECTRUM__CLK_S__SHIFT;5340cg_spll_spread_spectrum |= CG_SPLL_SPREAD_SPECTRUM__SSEN_MASK;53415342cg_spll_spread_spectrum_2 &= ~CG_SPLL_SPREAD_SPECTRUM_2__CLK_V_MASK;5343cg_spll_spread_spectrum_2 |= clk_v << CG_SPLL_SPREAD_SPECTRUM_2__CLK_V__SHIFT;5344}5345}53465347sclk->sclk_value = engine_clock;5348sclk->vCG_SPLL_FUNC_CNTL = spll_func_cntl;5349sclk->vCG_SPLL_FUNC_CNTL_2 = spll_func_cntl_2;5350sclk->vCG_SPLL_FUNC_CNTL_3 = spll_func_cntl_3;5351sclk->vCG_SPLL_FUNC_CNTL_4 = spll_func_cntl_4;5352sclk->vCG_SPLL_SPREAD_SPECTRUM = cg_spll_spread_spectrum;5353sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cg_spll_spread_spectrum_2;53545355return 0;5356}53575358static int si_populate_sclk_value(struct amdgpu_device *adev,5359u32 engine_clock,5360SISLANDS_SMC_SCLK_VALUE *sclk)5361{5362SISLANDS_SMC_SCLK_VALUE sclk_tmp;5363int ret;53645365ret = si_calculate_sclk_params(adev, engine_clock, &sclk_tmp);5366if (!ret) {5367sclk->sclk_value = cpu_to_be32(sclk_tmp.sclk_value);5368sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL);5369sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_2);5370sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_3);5371sclk->vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_4);5372sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM);5373sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM_2);5374}53755376return ret;5377}53785379static int si_populate_mclk_value(struct amdgpu_device *adev,5380u32 engine_clock,5381u32 memory_clock,5382SISLANDS_SMC_MCLK_VALUE *mclk,5383bool strobe_mode,5384bool dll_state_on)5385{5386struct rv7xx_power_info *pi = rv770_get_pi(adev);5387struct si_power_info *si_pi = si_get_pi(adev);5388u32 dll_cntl = si_pi->clock_registers.dll_cntl;5389u32 mclk_pwrmgt_cntl = si_pi->clock_registers.mclk_pwrmgt_cntl;5390u32 mpll_ad_func_cntl = si_pi->clock_registers.mpll_ad_func_cntl;5391u32 mpll_dq_func_cntl = si_pi->clock_registers.mpll_dq_func_cntl;5392u32 mpll_func_cntl = si_pi->clock_registers.mpll_func_cntl;5393u32 mpll_func_cntl_1 = si_pi->clock_registers.mpll_func_cntl_1;5394u32 mpll_func_cntl_2 = si_pi->clock_registers.mpll_func_cntl_2;5395u32 mpll_ss1 = si_pi->clock_registers.mpll_ss1;5396u32 mpll_ss2 = si_pi->clock_registers.mpll_ss2;5397struct atom_mpll_param mpll_param;5398int ret;53995400ret = amdgpu_atombios_get_memory_pll_dividers(adev, memory_clock, strobe_mode, &mpll_param);5401if (ret)5402return ret;54035404mpll_func_cntl &= ~BWCTRL_MASK;5405mpll_func_cntl |= BWCTRL(mpll_param.bwcntl);54065407mpll_func_cntl_1 &= ~(CLKF_MASK | CLKFRAC_MASK | VCO_MODE_MASK);5408mpll_func_cntl_1 |= CLKF(mpll_param.clkf) |5409CLKFRAC(mpll_param.clkfrac) | VCO_MODE(mpll_param.vco_mode);54105411mpll_ad_func_cntl &= ~YCLK_POST_DIV_MASK;5412mpll_ad_func_cntl |= YCLK_POST_DIV(mpll_param.post_div);54135414if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5) {5415mpll_dq_func_cntl &= ~(YCLK_SEL_MASK | YCLK_POST_DIV_MASK);5416mpll_dq_func_cntl |= YCLK_SEL(mpll_param.yclk_sel) |5417YCLK_POST_DIV(mpll_param.post_div);5418}54195420if (pi->mclk_ss) {5421struct amdgpu_atom_ss ss;5422u32 freq_nom;5423u32 tmp;5424u32 reference_clock = adev->clock.mpll.reference_freq;54255426if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5)5427freq_nom = memory_clock * 4;5428else5429freq_nom = memory_clock * 2;54305431tmp = freq_nom / reference_clock;5432tmp = tmp * tmp;5433if (amdgpu_atombios_get_asic_ss_info(adev, &ss,5434ASIC_INTERNAL_MEMORY_SS, freq_nom)) {5435u32 clks = reference_clock * 5 / ss.rate;5436u32 clkv = (u32)((((131 * ss.percentage * ss.rate) / 100) * tmp) / freq_nom);54375438mpll_ss1 &= ~CLKV_MASK;5439mpll_ss1 |= CLKV(clkv);54405441mpll_ss2 &= ~CLKS_MASK;5442mpll_ss2 |= CLKS(clks);5443}5444}54455446mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;5447mclk_pwrmgt_cntl |= DLL_SPEED(mpll_param.dll_speed);54485449if (dll_state_on)5450mclk_pwrmgt_cntl |= MRDCK0_PDNB | MRDCK1_PDNB;5451else5452mclk_pwrmgt_cntl &= ~(MRDCK0_PDNB | MRDCK1_PDNB);54535454mclk->mclk_value = cpu_to_be32(memory_clock);5455mclk->vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl);5456mclk->vMPLL_FUNC_CNTL_1 = cpu_to_be32(mpll_func_cntl_1);5457mclk->vMPLL_FUNC_CNTL_2 = cpu_to_be32(mpll_func_cntl_2);5458mclk->vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);5459mclk->vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);5460mclk->vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);5461mclk->vDLL_CNTL = cpu_to_be32(dll_cntl);5462mclk->vMPLL_SS = cpu_to_be32(mpll_ss1);5463mclk->vMPLL_SS2 = cpu_to_be32(mpll_ss2);54645465return 0;5466}54675468static void si_populate_smc_sp(struct amdgpu_device *adev,5469struct amdgpu_ps *amdgpu_state,5470SISLANDS_SMC_SWSTATE *smc_state)5471{5472struct si_ps *ps = si_get_ps(amdgpu_state);5473struct rv7xx_power_info *pi = rv770_get_pi(adev);5474int i;54755476for (i = 0; i < ps->performance_level_count - 1; i++)5477smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);54785479smc_state->levels[ps->performance_level_count - 1].bSP =5480cpu_to_be32(pi->psp);5481}54825483static int si_convert_power_level_to_smc(struct amdgpu_device *adev,5484struct rv7xx_pl *pl,5485SISLANDS_SMC_HW_PERFORMANCE_LEVEL *level)5486{5487struct rv7xx_power_info *pi = rv770_get_pi(adev);5488struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);5489struct si_power_info *si_pi = si_get_pi(adev);5490int ret;5491bool dll_state_on;5492u16 std_vddc;54935494if (eg_pi->pcie_performance_request &&5495(si_pi->force_pcie_gen != SI_PCIE_GEN_INVALID))5496level->gen2PCIE = (u8)si_pi->force_pcie_gen;5497else5498level->gen2PCIE = (u8)pl->pcie_gen;54995500ret = si_populate_sclk_value(adev, pl->sclk, &level->sclk);5501if (ret)5502return ret;55035504level->mcFlags = 0;55055506if (pi->mclk_stutter_mode_threshold &&5507(pl->mclk <= pi->mclk_stutter_mode_threshold) &&5508!eg_pi->uvd_enabled &&5509(RREG32(mmDPG_PIPE_STUTTER_CONTROL) & DPG_PIPE_STUTTER_CONTROL__STUTTER_ENABLE_MASK) &&5510(adev->pm.dpm.new_active_crtc_count <= 2)) {5511level->mcFlags |= SISLANDS_SMC_MC_STUTTER_EN;5512}55135514if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5) {5515if (pl->mclk > pi->mclk_edc_enable_threshold)5516level->mcFlags |= SISLANDS_SMC_MC_EDC_RD_FLAG;55175518if (pl->mclk > eg_pi->mclk_edc_wr_enable_threshold)5519level->mcFlags |= SISLANDS_SMC_MC_EDC_WR_FLAG;55205521level->strobeMode = si_get_strobe_mode_settings(adev, pl->mclk);55225523if (level->strobeMode & SISLANDS_SMC_STROBE_ENABLE) {5524if (si_get_mclk_frequency_ratio(pl->mclk, true) >=5525((RREG32(MC_SEQ_MISC7) >> 16) & 0xf))5526dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;5527else5528dll_state_on = ((RREG32(MC_SEQ_MISC6) >> 1) & 0x1) ? true : false;5529} else {5530dll_state_on = false;5531}5532} else {5533level->strobeMode = si_get_strobe_mode_settings(adev,5534pl->mclk);55355536dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;5537}55385539ret = si_populate_mclk_value(adev,5540pl->sclk,5541pl->mclk,5542&level->mclk,5543(level->strobeMode & SISLANDS_SMC_STROBE_ENABLE) != 0, dll_state_on);5544if (ret)5545return ret;55465547ret = si_populate_voltage_value(adev,5548&eg_pi->vddc_voltage_table,5549pl->vddc, &level->vddc);5550if (ret)5551return ret;555255535554ret = si_get_std_voltage_value(adev, &level->vddc, &std_vddc);5555if (ret)5556return ret;55575558ret = si_populate_std_voltage_value(adev, std_vddc,5559level->vddc.index, &level->std_vddc);5560if (ret)5561return ret;55625563if (eg_pi->vddci_control) {5564ret = si_populate_voltage_value(adev, &eg_pi->vddci_voltage_table,5565pl->vddci, &level->vddci);5566if (ret)5567return ret;5568}55695570if (si_pi->vddc_phase_shed_control) {5571ret = si_populate_phase_shedding_value(adev,5572&adev->pm.dpm.dyn_state.phase_shedding_limits_table,5573pl->vddc,5574pl->sclk,5575pl->mclk,5576&level->vddc);5577if (ret)5578return ret;5579}55805581level->MaxPoweredUpCU = si_pi->max_cu;55825583ret = si_populate_mvdd_value(adev, pl->mclk, &level->mvdd);55845585return ret;5586}55875588static int si_populate_smc_t(struct amdgpu_device *adev,5589struct amdgpu_ps *amdgpu_state,5590SISLANDS_SMC_SWSTATE *smc_state)5591{5592struct rv7xx_power_info *pi = rv770_get_pi(adev);5593struct si_ps *state = si_get_ps(amdgpu_state);5594u32 a_t;5595u32 t_l, t_h;5596u32 high_bsp;5597int i, ret;55985599if (state->performance_level_count >= 9)5600return -EINVAL;56015602if (state->performance_level_count < 2) {5603a_t = 0xffff << CG_AT__CG_R__SHIFT | 0 << CG_AT__CG_L__SHIFT;5604smc_state->levels[0].aT = cpu_to_be32(a_t);5605return 0;5606}56075608smc_state->levels[0].aT = cpu_to_be32(0);56095610for (i = 0; i <= state->performance_level_count - 2; i++) {5611ret = r600_calculate_at(5612(50 / SISLANDS_MAX_HARDWARE_POWERLEVELS) * 100 * (i + 1),5613100 * R600_AH_DFLT,5614state->performance_levels[i + 1].sclk,5615state->performance_levels[i].sclk,5616&t_l,5617&t_h);56185619if (ret) {5620t_h = (i + 1) * 1000 - 50 * R600_AH_DFLT;5621t_l = (i + 1) * 1000 + 50 * R600_AH_DFLT;5622}56235624a_t = be32_to_cpu(smc_state->levels[i].aT) & ~CG_AT__CG_R_MASK;5625a_t |= (t_l * pi->bsp / 20000) << CG_AT__CG_R__SHIFT;5626smc_state->levels[i].aT = cpu_to_be32(a_t);56275628high_bsp = (i == state->performance_level_count - 2) ?5629pi->pbsp : pi->bsp;5630a_t = (0xffff) << CG_AT__CG_R__SHIFT | (t_h * high_bsp / 20000) << CG_AT__CG_L__SHIFT;5631smc_state->levels[i + 1].aT = cpu_to_be32(a_t);5632}56335634return 0;5635}56365637static int si_disable_ulv(struct amdgpu_device *adev)5638{5639struct si_power_info *si_pi = si_get_pi(adev);5640struct si_ulv_param *ulv = &si_pi->ulv;56415642if (ulv->supported)5643return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_DisableULV) == PPSMC_Result_OK) ?56440 : -EINVAL;56455646return 0;5647}56485649static bool si_is_state_ulv_compatible(struct amdgpu_device *adev,5650struct amdgpu_ps *amdgpu_state)5651{5652const struct si_power_info *si_pi = si_get_pi(adev);5653const struct si_ulv_param *ulv = &si_pi->ulv;5654const struct si_ps *state = si_get_ps(amdgpu_state);5655int i;56565657if (state->performance_levels[0].mclk != ulv->pl.mclk)5658return false;56595660/* XXX validate against display requirements! */56615662for (i = 0; i < adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count; i++) {5663if (adev->clock.current_dispclk <=5664adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[i].clk) {5665if (ulv->pl.vddc <5666adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[i].v)5667return false;5668}5669}56705671if ((amdgpu_state->vclk != 0) || (amdgpu_state->dclk != 0))5672return false;56735674return true;5675}56765677static int si_set_power_state_conditionally_enable_ulv(struct amdgpu_device *adev,5678struct amdgpu_ps *amdgpu_new_state)5679{5680const struct si_power_info *si_pi = si_get_pi(adev);5681const struct si_ulv_param *ulv = &si_pi->ulv;56825683if (ulv->supported) {5684if (si_is_state_ulv_compatible(adev, amdgpu_new_state))5685return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableULV) == PPSMC_Result_OK) ?56860 : -EINVAL;5687}5688return 0;5689}56905691static int si_convert_power_state_to_smc(struct amdgpu_device *adev,5692struct amdgpu_ps *amdgpu_state,5693SISLANDS_SMC_SWSTATE *smc_state)5694{5695struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);5696struct ni_power_info *ni_pi = ni_get_pi(adev);5697struct si_power_info *si_pi = si_get_pi(adev);5698struct si_ps *state = si_get_ps(amdgpu_state);5699int i, ret;5700u32 threshold;5701u32 sclk_in_sr = 1350; /* ??? */57025703if (state->performance_level_count > SISLANDS_MAX_HARDWARE_POWERLEVELS)5704return -EINVAL;57055706threshold = state->performance_levels[state->performance_level_count-1].sclk * 100 / 100;57075708if (amdgpu_state->vclk && amdgpu_state->dclk) {5709eg_pi->uvd_enabled = true;5710if (eg_pi->smu_uvd_hs)5711smc_state->flags |= PPSMC_SWSTATE_FLAG_UVD;5712} else {5713eg_pi->uvd_enabled = false;5714}57155716if (state->dc_compatible)5717smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;57185719smc_state->levelCount = 0;5720for (i = 0; i < state->performance_level_count; i++) {5721if (eg_pi->sclk_deep_sleep) {5722if ((i == 0) || si_pi->sclk_deep_sleep_above_low) {5723if (sclk_in_sr <= SCLK_MIN_DEEPSLEEP_FREQ)5724smc_state->levels[i].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_BYPASS;5725else5726smc_state->levels[i].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE;5727}5728}57295730ret = si_convert_power_level_to_smc(adev, &state->performance_levels[i],5731&smc_state->levels[i]);5732smc_state->levels[i].arbRefreshState =5733(u8)(SISLANDS_DRIVER_STATE_ARB_INDEX + i);57345735if (ret)5736return ret;57375738if (ni_pi->enable_power_containment)5739smc_state->levels[i].displayWatermark =5740(state->performance_levels[i].sclk < threshold) ?5741PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;5742else5743smc_state->levels[i].displayWatermark = (i < 2) ?5744PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;57455746if (eg_pi->dynamic_ac_timing)5747smc_state->levels[i].ACIndex = SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i;5748else5749smc_state->levels[i].ACIndex = 0;57505751smc_state->levelCount++;5752}57535754si_write_smc_soft_register(adev,5755SI_SMC_SOFT_REGISTER_watermark_threshold,5756threshold / 512);57575758si_populate_smc_sp(adev, amdgpu_state, smc_state);57595760ret = si_populate_power_containment_values(adev, amdgpu_state, smc_state);5761if (ret)5762ni_pi->enable_power_containment = false;57635764ret = si_populate_sq_ramping_values(adev, amdgpu_state, smc_state);5765if (ret)5766ni_pi->enable_sq_ramping = false;57675768return si_populate_smc_t(adev, amdgpu_state, smc_state);5769}57705771static int si_upload_sw_state(struct amdgpu_device *adev,5772struct amdgpu_ps *amdgpu_new_state)5773{5774struct si_power_info *si_pi = si_get_pi(adev);5775struct si_ps *new_state = si_get_ps(amdgpu_new_state);5776int ret;5777u32 address = si_pi->state_table_start +5778offsetof(SISLANDS_SMC_STATETABLE, driverState);5779SISLANDS_SMC_SWSTATE *smc_state = &si_pi->smc_statetable.driverState;5780size_t state_size = struct_size(smc_state, levels,5781new_state->performance_level_count);5782memset(smc_state, 0, state_size);57835784ret = si_convert_power_state_to_smc(adev, amdgpu_new_state, smc_state);5785if (ret)5786return ret;57875788return amdgpu_si_copy_bytes_to_smc(adev, address, (u8 *)smc_state,5789state_size, si_pi->sram_end);5790}57915792static int si_upload_ulv_state(struct amdgpu_device *adev)5793{5794struct si_power_info *si_pi = si_get_pi(adev);5795struct si_ulv_param *ulv = &si_pi->ulv;5796int ret = 0;57975798if (ulv->supported && ulv->pl.vddc) {5799u32 address = si_pi->state_table_start +5800offsetof(SISLANDS_SMC_STATETABLE, ULVState);5801struct SISLANDS_SMC_SWSTATE_SINGLE *smc_state = &si_pi->smc_statetable.ULVState;5802u32 state_size = sizeof(struct SISLANDS_SMC_SWSTATE_SINGLE);58035804memset(smc_state, 0, state_size);58055806ret = si_populate_ulv_state(adev, smc_state);5807if (!ret)5808ret = amdgpu_si_copy_bytes_to_smc(adev, address, (u8 *)smc_state,5809state_size, si_pi->sram_end);5810}58115812return ret;5813}58145815static int si_upload_smc_data(struct amdgpu_device *adev)5816{5817struct amdgpu_crtc *amdgpu_crtc = NULL;5818int i;58195820if (adev->pm.dpm.new_active_crtc_count == 0)5821return 0;58225823for (i = 0; i < adev->mode_info.num_crtc; i++) {5824if (adev->pm.dpm.new_active_crtcs & (1 << i)) {5825amdgpu_crtc = adev->mode_info.crtcs[i];5826break;5827}5828}58295830if (amdgpu_crtc == NULL)5831return 0;58325833if (amdgpu_crtc->line_time <= 0)5834return 0;58355836if (si_write_smc_soft_register(adev,5837SI_SMC_SOFT_REGISTER_crtc_index,5838amdgpu_crtc->crtc_id) != PPSMC_Result_OK)5839return 0;58405841if (si_write_smc_soft_register(adev,5842SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min,5843amdgpu_crtc->wm_high / amdgpu_crtc->line_time) != PPSMC_Result_OK)5844return 0;58455846if (si_write_smc_soft_register(adev,5847SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max,5848amdgpu_crtc->wm_low / amdgpu_crtc->line_time) != PPSMC_Result_OK)5849return 0;58505851return 0;5852}58535854static int si_set_mc_special_registers(struct amdgpu_device *adev,5855struct si_mc_reg_table *table)5856{5857u8 i, j, k;5858u32 temp_reg;58595860for (i = 0, j = table->last; i < table->last; i++) {5861if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)5862return -EINVAL;5863switch (table->mc_reg_address[i].s1) {5864case MC_SEQ_MISC1:5865temp_reg = RREG32(MC_PMG_CMD_EMRS);5866table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS;5867table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP;5868for (k = 0; k < table->num_entries; k++)5869table->mc_reg_table_entry[k].mc_data[j] =5870((temp_reg & 0xffff0000)) |5871((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);5872j++;58735874if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)5875return -EINVAL;5876temp_reg = RREG32(MC_PMG_CMD_MRS);5877table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS;5878table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP;5879for (k = 0; k < table->num_entries; k++) {5880table->mc_reg_table_entry[k].mc_data[j] =5881(temp_reg & 0xffff0000) |5882(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);5883if (adev->gmc.vram_type != AMDGPU_VRAM_TYPE_GDDR5)5884table->mc_reg_table_entry[k].mc_data[j] |= 0x100;5885}5886j++;58875888if (adev->gmc.vram_type != AMDGPU_VRAM_TYPE_GDDR5) {5889if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)5890return -EINVAL;5891table->mc_reg_address[j].s1 = MC_PMG_AUTO_CMD;5892table->mc_reg_address[j].s0 = MC_PMG_AUTO_CMD;5893for (k = 0; k < table->num_entries; k++)5894table->mc_reg_table_entry[k].mc_data[j] =5895(table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16;5896j++;5897}5898break;5899case MC_SEQ_RESERVE_M:5900temp_reg = RREG32(MC_PMG_CMD_MRS1);5901table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1;5902table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP;5903for(k = 0; k < table->num_entries; k++)5904table->mc_reg_table_entry[k].mc_data[j] =5905(temp_reg & 0xffff0000) |5906(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);5907j++;5908break;5909default:5910break;5911}5912}59135914table->last = j;59155916return 0;5917}59185919static bool si_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)5920{5921bool result = true;5922switch (in_reg) {5923case MC_SEQ_RAS_TIMING:5924*out_reg = MC_SEQ_RAS_TIMING_LP;5925break;5926case MC_SEQ_CAS_TIMING:5927*out_reg = MC_SEQ_CAS_TIMING_LP;5928break;5929case MC_SEQ_MISC_TIMING:5930*out_reg = MC_SEQ_MISC_TIMING_LP;5931break;5932case MC_SEQ_MISC_TIMING2:5933*out_reg = MC_SEQ_MISC_TIMING2_LP;5934break;5935case MC_SEQ_RD_CTL_D0:5936*out_reg = MC_SEQ_RD_CTL_D0_LP;5937break;5938case MC_SEQ_RD_CTL_D1:5939*out_reg = MC_SEQ_RD_CTL_D1_LP;5940break;5941case MC_SEQ_WR_CTL_D0:5942*out_reg = MC_SEQ_WR_CTL_D0_LP;5943break;5944case MC_SEQ_WR_CTL_D1:5945*out_reg = MC_SEQ_WR_CTL_D1_LP;5946break;5947case MC_PMG_CMD_EMRS:5948*out_reg = MC_SEQ_PMG_CMD_EMRS_LP;5949break;5950case MC_PMG_CMD_MRS:5951*out_reg = MC_SEQ_PMG_CMD_MRS_LP;5952break;5953case MC_PMG_CMD_MRS1:5954*out_reg = MC_SEQ_PMG_CMD_MRS1_LP;5955break;5956case MC_SEQ_PMG_TIMING:5957*out_reg = MC_SEQ_PMG_TIMING_LP;5958break;5959case MC_PMG_CMD_MRS2:5960*out_reg = MC_SEQ_PMG_CMD_MRS2_LP;5961break;5962case MC_SEQ_WR_CTL_2:5963*out_reg = MC_SEQ_WR_CTL_2_LP;5964break;5965default:5966result = false;5967break;5968}59695970return result;5971}59725973static void si_set_valid_flag(struct si_mc_reg_table *table)5974{5975u8 i, j;59765977for (i = 0; i < table->last; i++) {5978for (j = 1; j < table->num_entries; j++) {5979if (table->mc_reg_table_entry[j-1].mc_data[i] != table->mc_reg_table_entry[j].mc_data[i]) {5980table->valid_flag |= 1 << i;5981break;5982}5983}5984}5985}59865987static void si_set_s0_mc_reg_index(struct si_mc_reg_table *table)5988{5989u32 i;5990u16 address;59915992for (i = 0; i < table->last; i++)5993table->mc_reg_address[i].s0 = si_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?5994address : table->mc_reg_address[i].s1;59955996}59975998static int si_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,5999struct si_mc_reg_table *si_table)6000{6001u8 i, j;60026003if (table->last > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)6004return -EINVAL;6005if (table->num_entries > MAX_AC_TIMING_ENTRIES)6006return -EINVAL;60076008for (i = 0; i < table->last; i++)6009si_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;6010si_table->last = table->last;60116012for (i = 0; i < table->num_entries; i++) {6013si_table->mc_reg_table_entry[i].mclk_max =6014table->mc_reg_table_entry[i].mclk_max;6015for (j = 0; j < table->last; j++) {6016si_table->mc_reg_table_entry[i].mc_data[j] =6017table->mc_reg_table_entry[i].mc_data[j];6018}6019}6020si_table->num_entries = table->num_entries;60216022return 0;6023}60246025static int si_initialize_mc_reg_table(struct amdgpu_device *adev)6026{6027struct si_power_info *si_pi = si_get_pi(adev);6028struct atom_mc_reg_table *table;6029struct si_mc_reg_table *si_table = &si_pi->mc_reg_table;6030u8 module_index = rv770_get_memory_module_index(adev);6031int ret;60326033table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);6034if (!table)6035return -ENOMEM;60366037WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));6038WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));6039WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));6040WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));6041WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));6042WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));6043WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));6044WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));6045WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));6046WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));6047WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));6048WREG32(MC_SEQ_PMG_TIMING_LP, RREG32(MC_SEQ_PMG_TIMING));6049WREG32(MC_SEQ_PMG_CMD_MRS2_LP, RREG32(MC_PMG_CMD_MRS2));6050WREG32(MC_SEQ_WR_CTL_2_LP, RREG32(MC_SEQ_WR_CTL_2));60516052ret = amdgpu_atombios_init_mc_reg_table(adev, module_index, table);6053if (ret)6054goto init_mc_done;60556056ret = si_copy_vbios_mc_reg_table(table, si_table);6057if (ret)6058goto init_mc_done;60596060si_set_s0_mc_reg_index(si_table);60616062ret = si_set_mc_special_registers(adev, si_table);6063if (ret)6064goto init_mc_done;60656066si_set_valid_flag(si_table);60676068init_mc_done:6069kfree(table);60706071return ret;60726073}60746075static void si_populate_mc_reg_addresses(struct amdgpu_device *adev,6076SMC_SIslands_MCRegisters *mc_reg_table)6077{6078struct si_power_info *si_pi = si_get_pi(adev);6079u32 i, j;60806081for (i = 0, j = 0; j < si_pi->mc_reg_table.last; j++) {6082if (si_pi->mc_reg_table.valid_flag & (1 << j)) {6083if (i >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)6084break;6085mc_reg_table->address[i].s0 =6086cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s0);6087mc_reg_table->address[i].s1 =6088cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s1);6089i++;6090}6091}6092mc_reg_table->last = (u8)i;6093}60946095static void si_convert_mc_registers(const struct si_mc_reg_entry *entry,6096SMC_SIslands_MCRegisterSet *data,6097u32 num_entries, u32 valid_flag)6098{6099u32 i, j;61006101for(i = 0, j = 0; j < num_entries; j++) {6102if (valid_flag & (1 << j)) {6103data->value[i] = cpu_to_be32(entry->mc_data[j]);6104i++;6105}6106}6107}61086109static void si_convert_mc_reg_table_entry_to_smc(struct amdgpu_device *adev,6110struct rv7xx_pl *pl,6111SMC_SIslands_MCRegisterSet *mc_reg_table_data)6112{6113struct si_power_info *si_pi = si_get_pi(adev);6114u32 i = 0;61156116for (i = 0; i < si_pi->mc_reg_table.num_entries; i++) {6117if (pl->mclk <= si_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max)6118break;6119}61206121if ((i == si_pi->mc_reg_table.num_entries) && (i > 0))6122--i;61236124si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[i],6125mc_reg_table_data, si_pi->mc_reg_table.last,6126si_pi->mc_reg_table.valid_flag);6127}61286129static void si_convert_mc_reg_table_to_smc(struct amdgpu_device *adev,6130struct amdgpu_ps *amdgpu_state,6131SMC_SIslands_MCRegisters *mc_reg_table)6132{6133struct si_ps *state = si_get_ps(amdgpu_state);6134int i;61356136for (i = 0; i < state->performance_level_count; i++) {6137si_convert_mc_reg_table_entry_to_smc(adev,6138&state->performance_levels[i],6139&mc_reg_table->data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i]);6140}6141}61426143static int si_populate_mc_reg_table(struct amdgpu_device *adev,6144struct amdgpu_ps *amdgpu_boot_state)6145{6146struct si_ps *boot_state = si_get_ps(amdgpu_boot_state);6147struct si_power_info *si_pi = si_get_pi(adev);6148struct si_ulv_param *ulv = &si_pi->ulv;6149SMC_SIslands_MCRegisters *smc_mc_reg_table = &si_pi->smc_mc_reg_table;61506151memset(smc_mc_reg_table, 0, sizeof(SMC_SIslands_MCRegisters));61526153si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_seq_index, 1);61546155si_populate_mc_reg_addresses(adev, smc_mc_reg_table);61566157si_convert_mc_reg_table_entry_to_smc(adev, &boot_state->performance_levels[0],6158&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_INITIAL_SLOT]);61596160si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[0],6161&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ACPI_SLOT],6162si_pi->mc_reg_table.last,6163si_pi->mc_reg_table.valid_flag);61646165if (ulv->supported && ulv->pl.vddc != 0)6166si_convert_mc_reg_table_entry_to_smc(adev, &ulv->pl,6167&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ULV_SLOT]);6168else6169si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[0],6170&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ULV_SLOT],6171si_pi->mc_reg_table.last,6172si_pi->mc_reg_table.valid_flag);61736174si_convert_mc_reg_table_to_smc(adev, amdgpu_boot_state, smc_mc_reg_table);61756176return amdgpu_si_copy_bytes_to_smc(adev, si_pi->mc_reg_table_start,6177(u8 *)smc_mc_reg_table,6178sizeof(SMC_SIslands_MCRegisters), si_pi->sram_end);6179}61806181static int si_upload_mc_reg_table(struct amdgpu_device *adev,6182struct amdgpu_ps *amdgpu_new_state)6183{6184struct si_ps *new_state = si_get_ps(amdgpu_new_state);6185struct si_power_info *si_pi = si_get_pi(adev);6186u32 address = si_pi->mc_reg_table_start +6187offsetof(SMC_SIslands_MCRegisters,6188data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT]);6189SMC_SIslands_MCRegisters *smc_mc_reg_table = &si_pi->smc_mc_reg_table;61906191memset(smc_mc_reg_table, 0, sizeof(SMC_SIslands_MCRegisters));61926193si_convert_mc_reg_table_to_smc(adev, amdgpu_new_state, smc_mc_reg_table);61946195return amdgpu_si_copy_bytes_to_smc(adev, address,6196(u8 *)&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT],6197sizeof(SMC_SIslands_MCRegisterSet) * new_state->performance_level_count,6198si_pi->sram_end);6199}62006201static void si_enable_voltage_control(struct amdgpu_device *adev, bool enable)6202{6203if (enable)6204WREG32_P(mmGENERAL_PWRMGT, GENERAL_PWRMGT__VOLT_PWRMGT_EN_MASK, ~GENERAL_PWRMGT__VOLT_PWRMGT_EN_MASK);6205else6206WREG32_P(mmGENERAL_PWRMGT, 0, ~GENERAL_PWRMGT__VOLT_PWRMGT_EN_MASK);6207}62086209static enum si_pcie_gen si_get_maximum_link_speed(struct amdgpu_device *adev,6210struct amdgpu_ps *amdgpu_state)6211{6212struct si_ps *state = si_get_ps(amdgpu_state);6213int i;6214u16 pcie_speed, max_speed = 0;62156216for (i = 0; i < state->performance_level_count; i++) {6217pcie_speed = state->performance_levels[i].pcie_gen;6218if (max_speed < pcie_speed)6219max_speed = pcie_speed;6220}6221return max_speed;6222}62236224static u16 si_get_current_pcie_speed(struct amdgpu_device *adev)6225{6226u32 speed_cntl;62276228speed_cntl = RREG32_PCIE_PORT(ixPCIE_LC_SPEED_CNTL) & PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK;6229speed_cntl >>= PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT;62306231return (u16)speed_cntl;6232}62336234static void si_request_link_speed_change_before_state_change(struct amdgpu_device *adev,6235struct amdgpu_ps *amdgpu_new_state,6236struct amdgpu_ps *amdgpu_current_state)6237{6238struct si_power_info *si_pi = si_get_pi(adev);6239enum si_pcie_gen target_link_speed = si_get_maximum_link_speed(adev, amdgpu_new_state);6240enum si_pcie_gen current_link_speed;62416242if (si_pi->force_pcie_gen == SI_PCIE_GEN_INVALID)6243current_link_speed = si_get_maximum_link_speed(adev, amdgpu_current_state);6244else6245current_link_speed = si_pi->force_pcie_gen;62466247si_pi->force_pcie_gen = SI_PCIE_GEN_INVALID;6248si_pi->pspp_notify_required = false;6249if (target_link_speed > current_link_speed) {6250switch (target_link_speed) {6251#if defined(CONFIG_ACPI)6252case SI_PCIE_GEN3:6253if (amdgpu_acpi_pcie_performance_request(adev, PCIE_PERF_REQ_PECI_GEN3, false) == 0)6254break;6255si_pi->force_pcie_gen = SI_PCIE_GEN2;6256if (current_link_speed == SI_PCIE_GEN2)6257break;6258fallthrough;6259case SI_PCIE_GEN2:6260if (amdgpu_acpi_pcie_performance_request(adev, PCIE_PERF_REQ_PECI_GEN2, false) == 0)6261break;6262fallthrough;6263#endif6264default:6265si_pi->force_pcie_gen = si_get_current_pcie_speed(adev);6266break;6267}6268} else {6269if (target_link_speed < current_link_speed)6270si_pi->pspp_notify_required = true;6271}6272}62736274static void si_notify_link_speed_change_after_state_change(struct amdgpu_device *adev,6275struct amdgpu_ps *amdgpu_new_state,6276struct amdgpu_ps *amdgpu_current_state)6277{6278struct si_power_info *si_pi = si_get_pi(adev);6279enum si_pcie_gen target_link_speed = si_get_maximum_link_speed(adev, amdgpu_new_state);6280u8 request;62816282if (si_pi->pspp_notify_required) {6283if (target_link_speed == SI_PCIE_GEN3)6284request = PCIE_PERF_REQ_PECI_GEN3;6285else if (target_link_speed == SI_PCIE_GEN2)6286request = PCIE_PERF_REQ_PECI_GEN2;6287else6288request = PCIE_PERF_REQ_PECI_GEN1;62896290if ((request == PCIE_PERF_REQ_PECI_GEN1) &&6291(si_get_current_pcie_speed(adev) > 0))6292return;62936294#if defined(CONFIG_ACPI)6295amdgpu_acpi_pcie_performance_request(adev, request, false);6296#endif6297}6298}62996300#if 06301static int si_ds_request(struct amdgpu_device *adev,6302bool ds_status_on, u32 count_write)6303{6304struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);63056306if (eg_pi->sclk_deep_sleep) {6307if (ds_status_on)6308return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_CancelThrottleOVRDSCLKDS) ==6309PPSMC_Result_OK) ?63100 : -EINVAL;6311else6312return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_ThrottleOVRDSCLKDS) ==6313PPSMC_Result_OK) ? 0 : -EINVAL;6314}6315return 0;6316}6317#endif63186319static void si_set_max_cu_value(struct amdgpu_device *adev)6320{6321struct si_power_info *si_pi = si_get_pi(adev);63226323if (adev->asic_type == CHIP_VERDE) {6324switch (adev->pdev->device) {6325case 0x6820:6326case 0x6825:6327case 0x6821:6328case 0x6823:6329case 0x6827:6330si_pi->max_cu = 10;6331break;6332case 0x682D:6333case 0x6824:6334case 0x682F:6335case 0x6826:6336si_pi->max_cu = 8;6337break;6338case 0x6828:6339case 0x6830:6340case 0x6831:6341case 0x6838:6342case 0x6839:6343case 0x683D:6344si_pi->max_cu = 10;6345break;6346case 0x683B:6347case 0x683F:6348case 0x6829:6349si_pi->max_cu = 8;6350break;6351default:6352si_pi->max_cu = 0;6353break;6354}6355} else {6356si_pi->max_cu = 0;6357}6358}63596360static int si_patch_single_dependency_table_based_on_leakage(struct amdgpu_device *adev,6361struct amdgpu_clock_voltage_dependency_table *table)6362{6363u32 i;6364int j;6365u16 leakage_voltage;63666367if (table) {6368for (i = 0; i < table->count; i++) {6369switch (si_get_leakage_voltage_from_leakage_index(adev,6370table->entries[i].v,6371&leakage_voltage)) {6372case 0:6373table->entries[i].v = leakage_voltage;6374break;6375case -EAGAIN:6376return -EINVAL;6377case -EINVAL:6378default:6379break;6380}6381}63826383for (j = (table->count - 2); j >= 0; j--) {6384table->entries[j].v = (table->entries[j].v <= table->entries[j + 1].v) ?6385table->entries[j].v : table->entries[j + 1].v;6386}6387}6388return 0;6389}63906391static int si_patch_dependency_tables_based_on_leakage(struct amdgpu_device *adev)6392{6393int ret = 0;63946395ret = si_patch_single_dependency_table_based_on_leakage(adev,6396&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk);6397if (ret)6398DRM_ERROR("Could not patch vddc_on_sclk leakage table\n");6399ret = si_patch_single_dependency_table_based_on_leakage(adev,6400&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk);6401if (ret)6402DRM_ERROR("Could not patch vddc_on_mclk leakage table\n");6403ret = si_patch_single_dependency_table_based_on_leakage(adev,6404&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk);6405if (ret)6406DRM_ERROR("Could not patch vddci_on_mclk leakage table\n");6407return ret;6408}64096410static void si_set_pcie_lane_width_in_smc(struct amdgpu_device *adev,6411struct amdgpu_ps *amdgpu_new_state,6412struct amdgpu_ps *amdgpu_current_state)6413{6414u32 lane_width;6415u32 new_lane_width =6416((amdgpu_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;6417u32 current_lane_width =6418((amdgpu_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;64196420if (new_lane_width != current_lane_width) {6421amdgpu_set_pcie_lanes(adev, new_lane_width);6422lane_width = amdgpu_get_pcie_lanes(adev);6423si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width, lane_width);6424}6425}64266427static void si_dpm_setup_asic(struct amdgpu_device *adev)6428{6429si_read_clock_registers(adev);6430si_enable_acpi_power_management(adev);6431}64326433static int si_thermal_enable_alert(struct amdgpu_device *adev,6434bool enable)6435{6436u32 thermal_int = RREG32(mmCG_THERMAL_INT);64376438if (enable) {6439PPSMC_Result result;64406441thermal_int &= ~(CG_THERMAL_INT__THERM_INT_MASK_HIGH_MASK | CG_THERMAL_INT__THERM_INT_MASK_LOW_MASK);6442WREG32(mmCG_THERMAL_INT, thermal_int);6443result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableThermalInterrupt);6444if (result != PPSMC_Result_OK) {6445DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");6446return -EINVAL;6447}6448} else {6449thermal_int |= CG_THERMAL_INT__THERM_INT_MASK_HIGH_MASK | CG_THERMAL_INT__THERM_INT_MASK_LOW_MASK;6450WREG32(mmCG_THERMAL_INT, thermal_int);6451}64526453return 0;6454}64556456static int si_thermal_set_temperature_range(struct amdgpu_device *adev,6457int min_temp, int max_temp)6458{6459int low_temp = 0 * 1000;6460int high_temp = 255 * 1000;64616462if (low_temp < min_temp)6463low_temp = min_temp;6464if (high_temp > max_temp)6465high_temp = max_temp;6466if (high_temp < low_temp) {6467DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);6468return -EINVAL;6469}64706471WREG32_P(mmCG_THERMAL_INT, (high_temp / 1000) << CG_THERMAL_INT__DIG_THERM_INTH__SHIFT, ~CG_THERMAL_INT__DIG_THERM_INTH_MASK);6472WREG32_P(mmCG_THERMAL_INT, (low_temp / 1000) << CG_THERMAL_INT__DIG_THERM_INTL__SHIFT, ~CG_THERMAL_INT__DIG_THERM_INTL_MASK);6473WREG32_P(mmCG_THERMAL_CTRL, (high_temp / 1000) << CG_THERMAL_CTRL__DIG_THERM_DPM__SHIFT, ~CG_THERMAL_CTRL__DIG_THERM_DPM_MASK);64746475adev->pm.dpm.thermal.min_temp = low_temp;6476adev->pm.dpm.thermal.max_temp = high_temp;64776478return 0;6479}64806481static void si_fan_ctrl_set_static_mode(struct amdgpu_device *adev, u32 mode)6482{6483struct si_power_info *si_pi = si_get_pi(adev);6484u32 tmp;64856486if (si_pi->fan_ctrl_is_in_default_mode) {6487tmp = (RREG32(mmCG_FDO_CTRL2) & CG_FDO_CTRL2__FDO_PWM_MODE_MASK) >> CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT;6488si_pi->fan_ctrl_default_mode = tmp;6489tmp = (RREG32(mmCG_FDO_CTRL2) & CG_FDO_CTRL2__TMIN_MASK) >> CG_FDO_CTRL2__TMIN__SHIFT;6490si_pi->t_min = tmp;6491si_pi->fan_ctrl_is_in_default_mode = false;6492}64936494tmp = RREG32(mmCG_FDO_CTRL2) & ~CG_FDO_CTRL2__TMIN_MASK;6495tmp |= 0 << CG_FDO_CTRL2__TMIN__SHIFT;6496WREG32(mmCG_FDO_CTRL2, tmp);64976498tmp = RREG32(mmCG_FDO_CTRL2) & ~CG_FDO_CTRL2__FDO_PWM_MODE_MASK;6499tmp |= mode << CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT;6500WREG32(mmCG_FDO_CTRL2, tmp);6501}65026503static int si_thermal_setup_fan_table(struct amdgpu_device *adev)6504{6505struct si_power_info *si_pi = si_get_pi(adev);6506PP_SIslands_FanTable fan_table = { FDO_MODE_HARDWARE };6507u32 duty100;6508u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2;6509u16 fdo_min, slope1, slope2;6510u32 reference_clock, tmp;6511int ret;6512u64 tmp64;65136514if (!si_pi->fan_table_start) {6515adev->pm.dpm.fan.ucode_fan_control = false;6516return 0;6517}65186519duty100 = (RREG32(mmCG_FDO_CTRL1) & CG_FDO_CTRL1__FMAX_DUTY100_MASK) >> CG_FDO_CTRL1__FMAX_DUTY100__SHIFT;65206521if (duty100 == 0) {6522adev->pm.dpm.fan.ucode_fan_control = false;6523return 0;6524}65256526tmp64 = (u64)adev->pm.dpm.fan.pwm_min * duty100;6527do_div(tmp64, 10000);6528fdo_min = (u16)tmp64;65296530t_diff1 = adev->pm.dpm.fan.t_med - adev->pm.dpm.fan.t_min;6531t_diff2 = adev->pm.dpm.fan.t_high - adev->pm.dpm.fan.t_med;65326533pwm_diff1 = adev->pm.dpm.fan.pwm_med - adev->pm.dpm.fan.pwm_min;6534pwm_diff2 = adev->pm.dpm.fan.pwm_high - adev->pm.dpm.fan.pwm_med;65356536slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);6537slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);65386539fan_table.temp_min = cpu_to_be16((50 + adev->pm.dpm.fan.t_min) / 100);6540fan_table.temp_med = cpu_to_be16((50 + adev->pm.dpm.fan.t_med) / 100);6541fan_table.temp_max = cpu_to_be16((50 + adev->pm.dpm.fan.t_max) / 100);6542fan_table.slope1 = cpu_to_be16(slope1);6543fan_table.slope2 = cpu_to_be16(slope2);6544fan_table.fdo_min = cpu_to_be16(fdo_min);6545fan_table.hys_down = cpu_to_be16(adev->pm.dpm.fan.t_hyst);6546fan_table.hys_up = cpu_to_be16(1);6547fan_table.hys_slope = cpu_to_be16(1);6548fan_table.temp_resp_lim = cpu_to_be16(5);6549reference_clock = amdgpu_asic_get_xclk(adev);65506551fan_table.refresh_period = cpu_to_be32((adev->pm.dpm.fan.cycle_delay *6552reference_clock) / 1600);6553fan_table.fdo_max = cpu_to_be16((u16)duty100);65546555tmp = (RREG32(mmCG_MULT_THERMAL_CTRL) & CG_MULT_THERMAL_CTRL__TEMP_SEL_MASK) >> CG_MULT_THERMAL_CTRL__TEMP_SEL__SHIFT;6556fan_table.temp_src = (uint8_t)tmp;65576558ret = amdgpu_si_copy_bytes_to_smc(adev,6559si_pi->fan_table_start,6560(u8 *)(&fan_table),6561sizeof(fan_table),6562si_pi->sram_end);65636564if (ret) {6565DRM_ERROR("Failed to load fan table to the SMC.");6566adev->pm.dpm.fan.ucode_fan_control = false;6567}65686569return ret;6570}65716572static int si_fan_ctrl_start_smc_fan_control(struct amdgpu_device *adev)6573{6574struct si_power_info *si_pi = si_get_pi(adev);6575PPSMC_Result ret;65766577ret = amdgpu_si_send_msg_to_smc(adev, PPSMC_StartFanControl);6578if (ret == PPSMC_Result_OK) {6579si_pi->fan_is_controlled_by_smc = true;6580return 0;6581} else {6582return -EINVAL;6583}6584}65856586static int si_fan_ctrl_stop_smc_fan_control(struct amdgpu_device *adev)6587{6588struct si_power_info *si_pi = si_get_pi(adev);6589PPSMC_Result ret;65906591ret = amdgpu_si_send_msg_to_smc(adev, PPSMC_StopFanControl);65926593if (ret == PPSMC_Result_OK) {6594si_pi->fan_is_controlled_by_smc = false;6595return 0;6596} else {6597return -EINVAL;6598}6599}66006601static int si_dpm_get_fan_speed_pwm(void *handle,6602u32 *speed)6603{6604u32 duty, duty100;6605u64 tmp64;6606struct amdgpu_device *adev = (struct amdgpu_device *)handle;66076608if (!speed)6609return -EINVAL;66106611if (adev->pm.no_fan)6612return -ENOENT;66136614duty100 = (RREG32(mmCG_FDO_CTRL1) & CG_FDO_CTRL1__FMAX_DUTY100_MASK) >> CG_FDO_CTRL1__FMAX_DUTY100__SHIFT;6615duty = (RREG32(mmCG_THERMAL_STATUS) & CG_THERMAL_STATUS__FDO_PWM_DUTY_MASK) >> CG_THERMAL_STATUS__FDO_PWM_DUTY__SHIFT;66166617if (duty100 == 0)6618return -EINVAL;66196620tmp64 = (u64)duty * 255;6621do_div(tmp64, duty100);6622*speed = min_t(u32, tmp64, 255);66236624return 0;6625}66266627static int si_dpm_set_fan_speed_pwm(void *handle,6628u32 speed)6629{6630struct amdgpu_device *adev = (struct amdgpu_device *)handle;6631struct si_power_info *si_pi = si_get_pi(adev);6632u32 tmp;6633u32 duty, duty100;6634u64 tmp64;66356636if (adev->pm.no_fan)6637return -ENOENT;66386639if (si_pi->fan_is_controlled_by_smc)6640return -EINVAL;66416642if (speed > 255)6643return -EINVAL;66446645duty100 = (RREG32(mmCG_FDO_CTRL1) & CG_FDO_CTRL1__FMAX_DUTY100_MASK) >> CG_FDO_CTRL1__FMAX_DUTY100__SHIFT;66466647if (duty100 == 0)6648return -EINVAL;66496650tmp64 = (u64)speed * duty100;6651do_div(tmp64, 255);6652duty = (u32)tmp64;66536654tmp = RREG32(mmCG_FDO_CTRL0) & ~CG_FDO_CTRL0__FDO_STATIC_DUTY_MASK;6655tmp |= duty << CG_FDO_CTRL0__FDO_STATIC_DUTY__SHIFT;6656WREG32(mmCG_FDO_CTRL0, tmp);66576658return 0;6659}66606661static int si_dpm_set_fan_control_mode(void *handle, u32 mode)6662{6663struct amdgpu_device *adev = (struct amdgpu_device *)handle;66646665if (mode == U32_MAX)6666return -EINVAL;66676668if (mode) {6669/* stop auto-manage */6670if (adev->pm.dpm.fan.ucode_fan_control)6671si_fan_ctrl_stop_smc_fan_control(adev);6672si_fan_ctrl_set_static_mode(adev, mode);6673} else {6674/* restart auto-manage */6675if (adev->pm.dpm.fan.ucode_fan_control)6676si_thermal_start_smc_fan_control(adev);6677else6678si_fan_ctrl_set_default_mode(adev);6679}66806681return 0;6682}66836684static int si_dpm_get_fan_control_mode(void *handle, u32 *fan_mode)6685{6686struct amdgpu_device *adev = (struct amdgpu_device *)handle;6687struct si_power_info *si_pi = si_get_pi(adev);6688u32 tmp;66896690if (!fan_mode)6691return -EINVAL;66926693if (si_pi->fan_is_controlled_by_smc)6694return 0;66956696tmp = RREG32(mmCG_FDO_CTRL2) & CG_FDO_CTRL2__FDO_PWM_MODE_MASK;6697*fan_mode = (tmp >> CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT);66986699return 0;6700}67016702#if 06703static int si_fan_ctrl_get_fan_speed_rpm(struct amdgpu_device *adev,6704u32 *speed)6705{6706u32 tach_period;6707u32 xclk = amdgpu_asic_get_xclk(adev);67086709if (adev->pm.no_fan)6710return -ENOENT;67116712if (adev->pm.fan_pulses_per_revolution == 0)6713return -ENOENT;67146715tach_period = (RREG32(mmCG_TACH_STATUS) & CG_TACH_STATUS__TACH_PERIOD_MASK) >> CG_TACH_STATUS__TACH_PERIOD__SHIFT;6716if (tach_period == 0)6717return -ENOENT;67186719*speed = 60 * xclk * 10000 / tach_period;67206721return 0;6722}67236724static int si_fan_ctrl_set_fan_speed_rpm(struct amdgpu_device *adev,6725u32 speed)6726{6727u32 tach_period, tmp;6728u32 xclk = amdgpu_asic_get_xclk(adev);67296730if (adev->pm.no_fan)6731return -ENOENT;67326733if (adev->pm.fan_pulses_per_revolution == 0)6734return -ENOENT;67356736if ((speed < adev->pm.fan_min_rpm) ||6737(speed > adev->pm.fan_max_rpm))6738return -EINVAL;67396740if (adev->pm.dpm.fan.ucode_fan_control)6741si_fan_ctrl_stop_smc_fan_control(adev);67426743tach_period = 60 * xclk * 10000 / (8 * speed);6744tmp = RREG32(mmCG_TACH_CTRL) & ~CG_TACH_CTRL__TARGET_PERIOD_MASK;6745tmp |= tach_period << CG_TACH_CTRL__TARGET_PERIOD__SHIFT;6746WREG32(mmCG_TACH_CTRL, tmp);67476748si_fan_ctrl_set_static_mode(adev, FDO_PWM_MODE_STATIC_RPM);67496750return 0;6751}6752#endif67536754static void si_fan_ctrl_set_default_mode(struct amdgpu_device *adev)6755{6756struct si_power_info *si_pi = si_get_pi(adev);6757u32 tmp;67586759if (!si_pi->fan_ctrl_is_in_default_mode) {6760tmp = RREG32(mmCG_FDO_CTRL2) & ~CG_FDO_CTRL2__FDO_PWM_MODE_MASK;6761tmp |= si_pi->fan_ctrl_default_mode << CG_FDO_CTRL2__FDO_PWM_MODE__SHIFT;6762WREG32(mmCG_FDO_CTRL2, tmp);67636764tmp = RREG32(mmCG_FDO_CTRL2) & ~CG_FDO_CTRL2__TMIN_MASK;6765tmp |= si_pi->t_min << CG_FDO_CTRL2__TMIN__SHIFT;6766WREG32(mmCG_FDO_CTRL2, tmp);6767si_pi->fan_ctrl_is_in_default_mode = true;6768}6769}67706771static void si_thermal_start_smc_fan_control(struct amdgpu_device *adev)6772{6773if (adev->pm.dpm.fan.ucode_fan_control) {6774si_fan_ctrl_start_smc_fan_control(adev);6775si_fan_ctrl_set_static_mode(adev, FDO_PWM_MODE_STATIC);6776}6777}67786779static void si_thermal_initialize(struct amdgpu_device *adev)6780{6781u32 tmp;67826783if (adev->pm.fan_pulses_per_revolution) {6784tmp = RREG32(mmCG_TACH_CTRL) & ~CG_TACH_CTRL__EDGE_PER_REV_MASK;6785tmp |= (adev->pm.fan_pulses_per_revolution -1) << CG_TACH_CTRL__EDGE_PER_REV__SHIFT;6786WREG32(mmCG_TACH_CTRL, tmp);6787}67886789tmp = RREG32(mmCG_FDO_CTRL2) & ~CG_FDO_CTRL2__TACH_PWM_RESP_RATE_MASK;6790tmp |= 0x28 << CG_FDO_CTRL2__TACH_PWM_RESP_RATE__SHIFT;6791WREG32(mmCG_FDO_CTRL2, tmp);6792}67936794static int si_thermal_start_thermal_controller(struct amdgpu_device *adev)6795{6796int ret;67976798si_thermal_initialize(adev);6799ret = si_thermal_set_temperature_range(adev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);6800if (ret)6801return ret;6802ret = si_thermal_enable_alert(adev, true);6803if (ret)6804return ret;6805if (adev->pm.dpm.fan.ucode_fan_control) {6806ret = si_halt_smc(adev);6807if (ret)6808return ret;6809ret = si_thermal_setup_fan_table(adev);6810if (ret)6811return ret;6812ret = si_resume_smc(adev);6813if (ret)6814return ret;6815si_thermal_start_smc_fan_control(adev);6816}68176818return 0;6819}68206821static void si_thermal_stop_thermal_controller(struct amdgpu_device *adev)6822{6823if (!adev->pm.no_fan) {6824si_fan_ctrl_set_default_mode(adev);6825si_fan_ctrl_stop_smc_fan_control(adev);6826}6827}68286829static int si_dpm_enable(struct amdgpu_device *adev)6830{6831struct rv7xx_power_info *pi = rv770_get_pi(adev);6832struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);6833struct si_power_info *si_pi = si_get_pi(adev);6834struct amdgpu_ps *boot_ps = adev->pm.dpm.boot_ps;6835int ret;68366837if (amdgpu_si_is_smc_running(adev))6838return -EINVAL;6839if (pi->voltage_control || si_pi->voltage_control_svi2)6840si_enable_voltage_control(adev, true);6841if (pi->mvdd_control)6842si_get_mvdd_configuration(adev);6843if (pi->voltage_control || si_pi->voltage_control_svi2) {6844ret = si_construct_voltage_tables(adev);6845if (ret) {6846DRM_ERROR("si_construct_voltage_tables failed\n");6847return ret;6848}6849}6850if (eg_pi->dynamic_ac_timing) {6851ret = si_initialize_mc_reg_table(adev);6852if (ret)6853eg_pi->dynamic_ac_timing = false;6854}6855if (pi->dynamic_ss)6856si_enable_spread_spectrum(adev, true);6857if (pi->thermal_protection)6858si_enable_thermal_protection(adev, true);6859si_setup_bsp(adev);6860si_program_git(adev);6861si_program_tp(adev);6862si_program_tpp(adev);6863si_program_sstp(adev);6864si_enable_display_gap(adev);6865si_program_vc(adev);6866ret = si_upload_firmware(adev);6867if (ret) {6868DRM_ERROR("si_upload_firmware failed\n");6869return ret;6870}6871ret = si_process_firmware_header(adev);6872if (ret) {6873DRM_ERROR("si_process_firmware_header failed\n");6874return ret;6875}6876ret = si_initial_switch_from_arb_f0_to_f1(adev);6877if (ret) {6878DRM_ERROR("si_initial_switch_from_arb_f0_to_f1 failed\n");6879return ret;6880}6881ret = si_init_smc_table(adev);6882if (ret) {6883DRM_ERROR("si_init_smc_table failed\n");6884return ret;6885}6886ret = si_init_smc_spll_table(adev);6887if (ret) {6888DRM_ERROR("si_init_smc_spll_table failed\n");6889return ret;6890}6891ret = si_init_arb_table_index(adev);6892if (ret) {6893DRM_ERROR("si_init_arb_table_index failed\n");6894return ret;6895}6896if (eg_pi->dynamic_ac_timing) {6897ret = si_populate_mc_reg_table(adev, boot_ps);6898if (ret) {6899DRM_ERROR("si_populate_mc_reg_table failed\n");6900return ret;6901}6902}6903ret = si_initialize_smc_cac_tables(adev);6904if (ret) {6905DRM_ERROR("si_initialize_smc_cac_tables failed\n");6906return ret;6907}6908ret = si_initialize_hardware_cac_manager(adev);6909if (ret) {6910DRM_ERROR("si_initialize_hardware_cac_manager failed\n");6911return ret;6912}6913ret = si_initialize_smc_dte_tables(adev);6914if (ret) {6915DRM_ERROR("si_initialize_smc_dte_tables failed\n");6916return ret;6917}6918ret = si_populate_smc_tdp_limits(adev, boot_ps);6919if (ret) {6920DRM_ERROR("si_populate_smc_tdp_limits failed\n");6921return ret;6922}6923ret = si_populate_smc_tdp_limits_2(adev, boot_ps);6924if (ret) {6925DRM_ERROR("si_populate_smc_tdp_limits_2 failed\n");6926return ret;6927}6928si_program_response_times(adev);6929si_program_ds_registers(adev);6930si_dpm_start_smc(adev);6931ret = si_notify_smc_display_change(adev, false);6932if (ret) {6933DRM_ERROR("si_notify_smc_display_change failed\n");6934return ret;6935}6936si_enable_sclk_control(adev, true);6937si_start_dpm(adev);69386939si_enable_auto_throttle_source(adev, SI_DPM_AUTO_THROTTLE_SRC_THERMAL, true);6940si_thermal_start_thermal_controller(adev);69416942ni_update_current_ps(adev, boot_ps);69436944return 0;6945}69466947static int si_set_temperature_range(struct amdgpu_device *adev)6948{6949int ret;69506951ret = si_thermal_enable_alert(adev, false);6952if (ret)6953return ret;6954ret = si_thermal_set_temperature_range(adev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);6955if (ret)6956return ret;6957ret = si_thermal_enable_alert(adev, true);6958if (ret)6959return ret;69606961return ret;6962}69636964static void si_dpm_disable(struct amdgpu_device *adev)6965{6966struct rv7xx_power_info *pi = rv770_get_pi(adev);6967struct amdgpu_ps *boot_ps = adev->pm.dpm.boot_ps;69686969if (!amdgpu_si_is_smc_running(adev))6970return;6971si_thermal_stop_thermal_controller(adev);6972si_disable_ulv(adev);6973si_clear_vc(adev);6974if (pi->thermal_protection)6975si_enable_thermal_protection(adev, false);6976si_enable_power_containment(adev, boot_ps, false);6977si_enable_smc_cac(adev, boot_ps, false);6978si_enable_spread_spectrum(adev, false);6979si_enable_auto_throttle_source(adev, SI_DPM_AUTO_THROTTLE_SRC_THERMAL, false);6980si_stop_dpm(adev);6981si_reset_to_default(adev);6982si_dpm_stop_smc(adev);6983si_force_switch_to_arb_f0(adev);69846985ni_update_current_ps(adev, boot_ps);6986}69876988static int si_dpm_pre_set_power_state(void *handle)6989{6990struct amdgpu_device *adev = (struct amdgpu_device *)handle;6991struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);6992struct amdgpu_ps requested_ps = *adev->pm.dpm.requested_ps;6993struct amdgpu_ps *new_ps = &requested_ps;69946995ni_update_requested_ps(adev, new_ps);6996si_apply_state_adjust_rules(adev, &eg_pi->requested_rps);69976998return 0;6999}70007001static int si_power_control_set_level(struct amdgpu_device *adev)7002{7003struct amdgpu_ps *new_ps = adev->pm.dpm.requested_ps;7004int ret;70057006ret = si_restrict_performance_levels_before_switch(adev);7007if (ret)7008return ret;7009ret = si_halt_smc(adev);7010if (ret)7011return ret;7012ret = si_populate_smc_tdp_limits(adev, new_ps);7013if (ret)7014return ret;7015ret = si_populate_smc_tdp_limits_2(adev, new_ps);7016if (ret)7017return ret;7018ret = si_resume_smc(adev);7019if (ret)7020return ret;7021return si_set_sw_state(adev);7022}70237024static void si_set_vce_clock(struct amdgpu_device *adev,7025struct amdgpu_ps *new_rps,7026struct amdgpu_ps *old_rps)7027{7028if ((old_rps->evclk != new_rps->evclk) ||7029(old_rps->ecclk != new_rps->ecclk)) {7030/* Turn the clocks on when encoding, off otherwise */7031if (new_rps->evclk || new_rps->ecclk) {7032/* Place holder for future VCE1.0 porting to amdgpu7033vce_v1_0_enable_mgcg(adev, false, false);*/7034} else {7035/* Place holder for future VCE1.0 porting to amdgpu7036vce_v1_0_enable_mgcg(adev, true, false);7037amdgpu_asic_set_vce_clocks(adev, new_rps->evclk, new_rps->ecclk);*/7038}7039}7040}70417042static int si_dpm_set_power_state(void *handle)7043{7044struct amdgpu_device *adev = (struct amdgpu_device *)handle;7045struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7046struct amdgpu_ps *new_ps = &eg_pi->requested_rps;7047struct amdgpu_ps *old_ps = &eg_pi->current_rps;7048int ret;70497050ret = si_disable_ulv(adev);7051if (ret) {7052DRM_ERROR("si_disable_ulv failed\n");7053return ret;7054}7055ret = si_restrict_performance_levels_before_switch(adev);7056if (ret) {7057DRM_ERROR("si_restrict_performance_levels_before_switch failed\n");7058return ret;7059}7060if (eg_pi->pcie_performance_request)7061si_request_link_speed_change_before_state_change(adev, new_ps, old_ps);7062ni_set_uvd_clock_before_set_eng_clock(adev, new_ps, old_ps);7063ret = si_enable_power_containment(adev, new_ps, false);7064if (ret) {7065DRM_ERROR("si_enable_power_containment failed\n");7066return ret;7067}7068ret = si_enable_smc_cac(adev, new_ps, false);7069if (ret) {7070DRM_ERROR("si_enable_smc_cac failed\n");7071return ret;7072}7073ret = si_halt_smc(adev);7074if (ret) {7075DRM_ERROR("si_halt_smc failed\n");7076return ret;7077}7078ret = si_upload_sw_state(adev, new_ps);7079if (ret) {7080DRM_ERROR("si_upload_sw_state failed\n");7081return ret;7082}7083ret = si_upload_smc_data(adev);7084if (ret) {7085DRM_ERROR("si_upload_smc_data failed\n");7086return ret;7087}7088ret = si_upload_ulv_state(adev);7089if (ret) {7090DRM_ERROR("si_upload_ulv_state failed\n");7091return ret;7092}7093if (eg_pi->dynamic_ac_timing) {7094ret = si_upload_mc_reg_table(adev, new_ps);7095if (ret) {7096DRM_ERROR("si_upload_mc_reg_table failed\n");7097return ret;7098}7099}7100ret = si_program_memory_timing_parameters(adev, new_ps);7101if (ret) {7102DRM_ERROR("si_program_memory_timing_parameters failed\n");7103return ret;7104}7105si_set_pcie_lane_width_in_smc(adev, new_ps, old_ps);71067107ret = si_resume_smc(adev);7108if (ret) {7109DRM_ERROR("si_resume_smc failed\n");7110return ret;7111}7112ret = si_set_sw_state(adev);7113if (ret) {7114DRM_ERROR("si_set_sw_state failed\n");7115return ret;7116}7117ni_set_uvd_clock_after_set_eng_clock(adev, new_ps, old_ps);7118si_set_vce_clock(adev, new_ps, old_ps);7119if (eg_pi->pcie_performance_request)7120si_notify_link_speed_change_after_state_change(adev, new_ps, old_ps);7121ret = si_set_power_state_conditionally_enable_ulv(adev, new_ps);7122if (ret) {7123DRM_ERROR("si_set_power_state_conditionally_enable_ulv failed\n");7124return ret;7125}7126ret = si_enable_smc_cac(adev, new_ps, true);7127if (ret) {7128DRM_ERROR("si_enable_smc_cac failed\n");7129return ret;7130}7131ret = si_enable_power_containment(adev, new_ps, true);7132if (ret) {7133DRM_ERROR("si_enable_power_containment failed\n");7134return ret;7135}71367137ret = si_power_control_set_level(adev);7138if (ret) {7139DRM_ERROR("si_power_control_set_level failed\n");7140return ret;7141}71427143return 0;7144}71457146static void si_dpm_post_set_power_state(void *handle)7147{7148struct amdgpu_device *adev = (struct amdgpu_device *)handle;7149struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7150struct amdgpu_ps *new_ps = &eg_pi->requested_rps;71517152ni_update_current_ps(adev, new_ps);7153}71547155#if 07156void si_dpm_reset_asic(struct amdgpu_device *adev)7157{7158si_restrict_performance_levels_before_switch(adev);7159si_disable_ulv(adev);7160si_set_boot_state(adev);7161}7162#endif71637164static void si_dpm_display_configuration_changed(void *handle)7165{7166struct amdgpu_device *adev = (struct amdgpu_device *)handle;71677168si_program_display_gap(adev);7169}717071717172static void si_parse_pplib_non_clock_info(struct amdgpu_device *adev,7173struct amdgpu_ps *rps,7174struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,7175u8 table_rev)7176{7177rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);7178rps->class = le16_to_cpu(non_clock_info->usClassification);7179rps->class2 = le16_to_cpu(non_clock_info->usClassification2);71807181if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {7182rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);7183rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);7184} else if (r600_is_uvd_state(rps->class, rps->class2)) {7185rps->vclk = RV770_DEFAULT_VCLK_FREQ;7186rps->dclk = RV770_DEFAULT_DCLK_FREQ;7187} else {7188rps->vclk = 0;7189rps->dclk = 0;7190}71917192if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)7193adev->pm.dpm.boot_ps = rps;7194if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)7195adev->pm.dpm.uvd_ps = rps;7196}71977198static void si_parse_pplib_clock_info(struct amdgpu_device *adev,7199struct amdgpu_ps *rps, int index,7200union pplib_clock_info *clock_info)7201{7202struct rv7xx_power_info *pi = rv770_get_pi(adev);7203struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7204struct si_power_info *si_pi = si_get_pi(adev);7205struct si_ps *ps = si_get_ps(rps);7206u16 leakage_voltage;7207struct rv7xx_pl *pl = &ps->performance_levels[index];7208int ret;72097210ps->performance_level_count = index + 1;72117212pl->sclk = le16_to_cpu(clock_info->si.usEngineClockLow);7213pl->sclk |= clock_info->si.ucEngineClockHigh << 16;7214pl->mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);7215pl->mclk |= clock_info->si.ucMemoryClockHigh << 16;72167217pl->vddc = le16_to_cpu(clock_info->si.usVDDC);7218pl->vddci = le16_to_cpu(clock_info->si.usVDDCI);7219pl->flags = le32_to_cpu(clock_info->si.ulFlags);7220pl->pcie_gen = si_gen_pcie_gen_support(adev,7221si_pi->sys_pcie_mask,7222si_pi->boot_pcie_gen,7223clock_info->si.ucPCIEGen);72247225/* patch up vddc if necessary */7226ret = si_get_leakage_voltage_from_leakage_index(adev, pl->vddc,7227&leakage_voltage);7228if (ret == 0)7229pl->vddc = leakage_voltage;72307231if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {7232pi->acpi_vddc = pl->vddc;7233eg_pi->acpi_vddci = pl->vddci;7234si_pi->acpi_pcie_gen = pl->pcie_gen;7235}72367237if ((rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) &&7238index == 0) {7239/* XXX disable for A0 tahiti */7240si_pi->ulv.supported = false;7241si_pi->ulv.pl = *pl;7242si_pi->ulv.one_pcie_lane_in_ulv = false;7243si_pi->ulv.volt_change_delay = SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT;7244si_pi->ulv.cg_ulv_parameter = SISLANDS_CGULVPARAMETER_DFLT;7245si_pi->ulv.cg_ulv_control = SISLANDS_CGULVCONTROL_DFLT;7246}72477248if (pi->min_vddc_in_table > pl->vddc)7249pi->min_vddc_in_table = pl->vddc;72507251if (pi->max_vddc_in_table < pl->vddc)7252pi->max_vddc_in_table = pl->vddc;72537254/* patch up boot state */7255if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {7256u16 vddc, vddci, mvdd;7257amdgpu_atombios_get_default_voltages(adev, &vddc, &vddci, &mvdd);7258pl->mclk = adev->clock.default_mclk;7259pl->sclk = adev->clock.default_sclk;7260pl->vddc = vddc;7261pl->vddci = vddci;7262si_pi->mvdd_bootup_value = mvdd;7263}72647265if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==7266ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {7267adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk;7268adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk;7269adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc;7270adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci;7271}7272}72737274union pplib_power_state {7275struct _ATOM_PPLIB_STATE v1;7276struct _ATOM_PPLIB_STATE_V2 v2;7277};72787279static int si_parse_power_table(struct amdgpu_device *adev)7280{7281struct amdgpu_mode_info *mode_info = &adev->mode_info;7282struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;7283union pplib_power_state *power_state;7284int i, j, k, non_clock_array_index, clock_array_index;7285union pplib_clock_info *clock_info;7286struct _StateArray *state_array;7287struct _ClockInfoArray *clock_info_array;7288struct _NonClockInfoArray *non_clock_info_array;7289union power_info *power_info;7290int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);7291u16 data_offset;7292u8 frev, crev;7293u8 *power_state_offset;7294struct si_ps *ps;72957296if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,7297&frev, &crev, &data_offset))7298return -EINVAL;7299power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);73007301amdgpu_add_thermal_controller(adev);73027303state_array = (struct _StateArray *)7304(mode_info->atom_context->bios + data_offset +7305le16_to_cpu(power_info->pplib.usStateArrayOffset));7306clock_info_array = (struct _ClockInfoArray *)7307(mode_info->atom_context->bios + data_offset +7308le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));7309non_clock_info_array = (struct _NonClockInfoArray *)7310(mode_info->atom_context->bios + data_offset +7311le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));73127313adev->pm.dpm.ps = kcalloc(state_array->ucNumEntries,7314sizeof(struct amdgpu_ps),7315GFP_KERNEL);7316if (!adev->pm.dpm.ps)7317return -ENOMEM;7318power_state_offset = (u8 *)state_array->states;7319for (adev->pm.dpm.num_ps = 0, i = 0; i < state_array->ucNumEntries; i++) {7320u8 *idx;7321power_state = (union pplib_power_state *)power_state_offset;7322non_clock_array_index = power_state->v2.nonClockInfoIndex;7323non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)7324&non_clock_info_array->nonClockInfo[non_clock_array_index];7325ps = kzalloc(sizeof(struct si_ps), GFP_KERNEL);7326if (ps == NULL)7327return -ENOMEM;7328adev->pm.dpm.ps[i].ps_priv = ps;7329si_parse_pplib_non_clock_info(adev, &adev->pm.dpm.ps[i],7330non_clock_info,7331non_clock_info_array->ucEntrySize);7332k = 0;7333idx = (u8 *)&power_state->v2.clockInfoIndex[0];7334for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {7335clock_array_index = idx[j];7336if (clock_array_index >= clock_info_array->ucNumEntries)7337continue;7338if (k >= SISLANDS_MAX_HARDWARE_POWERLEVELS)7339break;7340clock_info = (union pplib_clock_info *)7341((u8 *)&clock_info_array->clockInfo[0] +7342(clock_array_index * clock_info_array->ucEntrySize));7343si_parse_pplib_clock_info(adev,7344&adev->pm.dpm.ps[i], k,7345clock_info);7346k++;7347}7348power_state_offset += 2 + power_state->v2.ucNumDPMLevels;7349adev->pm.dpm.num_ps++;7350}73517352/* fill in the vce power states */7353for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) {7354u32 sclk, mclk;7355clock_array_index = adev->pm.dpm.vce_states[i].clk_idx;7356clock_info = (union pplib_clock_info *)7357&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];7358sclk = le16_to_cpu(clock_info->si.usEngineClockLow);7359sclk |= clock_info->si.ucEngineClockHigh << 16;7360mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);7361mclk |= clock_info->si.ucMemoryClockHigh << 16;7362adev->pm.dpm.vce_states[i].sclk = sclk;7363adev->pm.dpm.vce_states[i].mclk = mclk;7364}73657366return 0;7367}73687369static int si_dpm_init(struct amdgpu_device *adev)7370{7371struct rv7xx_power_info *pi;7372struct evergreen_power_info *eg_pi;7373struct ni_power_info *ni_pi;7374struct si_power_info *si_pi;7375struct atom_clock_dividers dividers;7376int ret;73777378si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL);7379if (si_pi == NULL)7380return -ENOMEM;7381adev->pm.dpm.priv = si_pi;7382ni_pi = &si_pi->ni;7383eg_pi = &ni_pi->eg;7384pi = &eg_pi->rv7xx;73857386si_pi->sys_pcie_mask =7387adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK;7388si_pi->force_pcie_gen = SI_PCIE_GEN_INVALID;7389si_pi->boot_pcie_gen = si_get_current_pcie_speed(adev);73907391si_set_max_cu_value(adev);73927393rv770_get_max_vddc(adev);7394si_get_leakage_vddc(adev);7395si_patch_dependency_tables_based_on_leakage(adev);73967397pi->acpi_vddc = 0;7398eg_pi->acpi_vddci = 0;7399pi->min_vddc_in_table = 0;7400pi->max_vddc_in_table = 0;74017402ret = amdgpu_get_platform_caps(adev);7403if (ret)7404return ret;74057406ret = amdgpu_parse_extended_power_table(adev);7407if (ret)7408return ret;74097410ret = si_parse_power_table(adev);7411if (ret)7412return ret;74137414adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =7415kcalloc(4,7416sizeof(struct amdgpu_clock_voltage_dependency_entry),7417GFP_KERNEL);7418if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries)7419return -ENOMEM;74207421adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;7422adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;7423adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;7424adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;7425adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 720;7426adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;7427adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 810;7428adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;7429adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 900;74307431if (adev->pm.dpm.voltage_response_time == 0)7432adev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;7433if (adev->pm.dpm.backbias_response_time == 0)7434adev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;74357436ret = amdgpu_atombios_get_clock_dividers(adev, COMPUTE_ENGINE_PLL_PARAM,74370, false, ÷rs);7438if (ret)7439pi->ref_div = dividers.ref_div + 1;7440else7441pi->ref_div = R600_REFERENCEDIVIDER_DFLT;74427443eg_pi->smu_uvd_hs = false;74447445pi->mclk_strobe_mode_threshold = 40000;7446if (si_is_special_1gb_platform(adev))7447pi->mclk_stutter_mode_threshold = 0;7448else7449pi->mclk_stutter_mode_threshold = pi->mclk_strobe_mode_threshold;7450pi->mclk_edc_enable_threshold = 40000;7451eg_pi->mclk_edc_wr_enable_threshold = 40000;74527453ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold;74547455pi->voltage_control =7456amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,7457VOLTAGE_OBJ_GPIO_LUT);7458if (!pi->voltage_control) {7459si_pi->voltage_control_svi2 =7460amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,7461VOLTAGE_OBJ_SVID2);7462if (si_pi->voltage_control_svi2)7463amdgpu_atombios_get_svi2_info(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,7464&si_pi->svd_gpio_id, &si_pi->svc_gpio_id);7465}74667467pi->mvdd_control =7468amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_MVDDC,7469VOLTAGE_OBJ_GPIO_LUT);74707471eg_pi->vddci_control =7472amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDCI,7473VOLTAGE_OBJ_GPIO_LUT);7474if (!eg_pi->vddci_control)7475si_pi->vddci_control_svi2 =7476amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDCI,7477VOLTAGE_OBJ_SVID2);74787479si_pi->vddc_phase_shed_control =7480amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,7481VOLTAGE_OBJ_PHASE_LUT);74827483rv770_get_engine_memory_ss(adev);74847485pi->asi = RV770_ASI_DFLT;7486pi->pasi = CYPRESS_HASI_DFLT;7487pi->vrc = SISLANDS_VRC_DFLT;74887489pi->gfx_clock_gating = true;74907491eg_pi->sclk_deep_sleep = true;7492si_pi->sclk_deep_sleep_above_low = false;74937494if (adev->pm.int_thermal_type != THERMAL_TYPE_NONE)7495pi->thermal_protection = true;7496else7497pi->thermal_protection = false;74987499eg_pi->dynamic_ac_timing = true;75007501eg_pi->light_sleep = true;7502#if defined(CONFIG_ACPI)7503eg_pi->pcie_performance_request =7504amdgpu_acpi_is_pcie_performance_request_supported(adev);7505#else7506eg_pi->pcie_performance_request = false;7507#endif75087509si_pi->sram_end = SMC_RAM_END;75107511adev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;7512adev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;7513adev->pm.dpm.dyn_state.vddc_vddci_delta = 200;7514adev->pm.dpm.dyn_state.valid_sclk_values.count = 0;7515adev->pm.dpm.dyn_state.valid_sclk_values.values = NULL;7516adev->pm.dpm.dyn_state.valid_mclk_values.count = 0;7517adev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;75187519si_initialize_powertune_defaults(adev);75207521/* make sure dc limits are valid */7522if ((adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk == 0) ||7523(adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk == 0))7524adev->pm.dpm.dyn_state.max_clock_voltage_on_dc =7525adev->pm.dpm.dyn_state.max_clock_voltage_on_ac;75267527si_pi->fan_ctrl_is_in_default_mode = true;75287529return 0;7530}75317532static void si_dpm_fini(struct amdgpu_device *adev)7533{7534int i;75357536if (adev->pm.dpm.ps)7537for (i = 0; i < adev->pm.dpm.num_ps; i++)7538kfree(adev->pm.dpm.ps[i].ps_priv);7539kfree(adev->pm.dpm.ps);7540kfree(adev->pm.dpm.priv);7541kfree(adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);7542amdgpu_free_extended_power_table(adev);7543}75447545static void si_dpm_debugfs_print_current_performance_level(void *handle,7546struct seq_file *m)7547{7548struct amdgpu_device *adev = (struct amdgpu_device *)handle;7549struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7550struct amdgpu_ps *rps = &eg_pi->current_rps;7551struct si_ps *ps = si_get_ps(rps);7552struct rv7xx_pl *pl;7553u32 current_index =7554(RREG32(mmTARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_AND_CURRENT_PROFILE_INDEX__CURRENT_STATE_INDEX_MASK) >>7555TARGET_AND_CURRENT_PROFILE_INDEX__CURRENT_STATE_INDEX__SHIFT;75567557if (current_index >= ps->performance_level_count) {7558seq_printf(m, "invalid dpm profile %d\n", current_index);7559} else {7560pl = &ps->performance_levels[current_index];7561seq_printf(m, "uvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);7562seq_printf(m, "power level %d sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",7563current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);7564}7565}75667567static int si_dpm_set_interrupt_state(struct amdgpu_device *adev,7568struct amdgpu_irq_src *source,7569unsigned type,7570enum amdgpu_interrupt_state state)7571{7572u32 cg_thermal_int;75737574switch (type) {7575case AMDGPU_THERMAL_IRQ_LOW_TO_HIGH:7576switch (state) {7577case AMDGPU_IRQ_STATE_DISABLE:7578cg_thermal_int = RREG32_SMC(mmCG_THERMAL_INT);7579cg_thermal_int |= CG_THERMAL_INT__THERM_INT_MASK_HIGH_MASK;7580WREG32_SMC(mmCG_THERMAL_INT, cg_thermal_int);7581break;7582case AMDGPU_IRQ_STATE_ENABLE:7583cg_thermal_int = RREG32_SMC(mmCG_THERMAL_INT);7584cg_thermal_int &= ~CG_THERMAL_INT__THERM_INT_MASK_HIGH_MASK;7585WREG32_SMC(mmCG_THERMAL_INT, cg_thermal_int);7586break;7587default:7588break;7589}7590break;75917592case AMDGPU_THERMAL_IRQ_HIGH_TO_LOW:7593switch (state) {7594case AMDGPU_IRQ_STATE_DISABLE:7595cg_thermal_int = RREG32_SMC(mmCG_THERMAL_INT);7596cg_thermal_int |= CG_THERMAL_INT__THERM_INT_MASK_LOW_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_LOW_MASK;7602WREG32_SMC(mmCG_THERMAL_INT, cg_thermal_int);7603break;7604default:7605break;7606}7607break;76087609default:7610break;7611}7612return 0;7613}76147615static int si_dpm_process_interrupt(struct amdgpu_device *adev,7616struct amdgpu_irq_src *source,7617struct amdgpu_iv_entry *entry)7618{7619bool queue_thermal = false;76207621if (entry == NULL)7622return -EINVAL;76237624switch (entry->src_id) {7625case 230: /* thermal low to high */7626DRM_DEBUG("IH: thermal low to high\n");7627adev->pm.dpm.thermal.high_to_low = false;7628queue_thermal = true;7629break;7630case 231: /* thermal high to low */7631DRM_DEBUG("IH: thermal high to low\n");7632adev->pm.dpm.thermal.high_to_low = true;7633queue_thermal = true;7634break;7635default:7636break;7637}76387639if (queue_thermal)7640schedule_work(&adev->pm.dpm.thermal.work);76417642return 0;7643}76447645static int si_dpm_late_init(struct amdgpu_ip_block *ip_block)7646{7647int ret;7648struct amdgpu_device *adev = ip_block->adev;76497650if (!adev->pm.dpm_enabled)7651return 0;76527653ret = si_set_temperature_range(adev);7654if (ret)7655return ret;7656#if 0 //TODO ?7657si_dpm_powergate_uvd(adev, true);7658#endif7659return 0;7660}76617662/**7663* si_dpm_init_microcode - load ucode images from disk7664*7665* @adev: amdgpu_device pointer7666*7667* Use the firmware interface to load the ucode images into7668* the driver (not loaded into hw).7669* Returns 0 on success, error on failure.7670*/7671static int si_dpm_init_microcode(struct amdgpu_device *adev)7672{7673const char *chip_name;7674int err;76757676DRM_DEBUG("\n");7677switch (adev->asic_type) {7678case CHIP_TAHITI:7679chip_name = "tahiti";7680break;7681case CHIP_PITCAIRN:7682if ((adev->pdev->revision == 0x81) &&7683((adev->pdev->device == 0x6810) ||7684(adev->pdev->device == 0x6811)))7685chip_name = "pitcairn_k";7686else7687chip_name = "pitcairn";7688break;7689case CHIP_VERDE:7690if (((adev->pdev->device == 0x6820) &&7691((adev->pdev->revision == 0x81) ||7692(adev->pdev->revision == 0x83))) ||7693((adev->pdev->device == 0x6821) &&7694((adev->pdev->revision == 0x83) ||7695(adev->pdev->revision == 0x87))) ||7696((adev->pdev->revision == 0x87) &&7697((adev->pdev->device == 0x6823) ||7698(adev->pdev->device == 0x682b))))7699chip_name = "verde_k";7700else7701chip_name = "verde";7702break;7703case CHIP_OLAND:7704if (((adev->pdev->revision == 0x81) &&7705((adev->pdev->device == 0x6600) ||7706(adev->pdev->device == 0x6604) ||7707(adev->pdev->device == 0x6605) ||7708(adev->pdev->device == 0x6610))) ||7709((adev->pdev->revision == 0x83) &&7710(adev->pdev->device == 0x6610)))7711chip_name = "oland_k";7712else7713chip_name = "oland";7714break;7715case CHIP_HAINAN:7716if (((adev->pdev->revision == 0x81) &&7717(adev->pdev->device == 0x6660)) ||7718((adev->pdev->revision == 0x83) &&7719((adev->pdev->device == 0x6660) ||7720(adev->pdev->device == 0x6663) ||7721(adev->pdev->device == 0x6665) ||7722(adev->pdev->device == 0x6667))))7723chip_name = "hainan_k";7724else if ((adev->pdev->revision == 0xc3) &&7725(adev->pdev->device == 0x6665))7726chip_name = "banks_k_2";7727else7728chip_name = "hainan";7729break;7730default: BUG();7731}77327733err = amdgpu_ucode_request(adev, &adev->pm.fw, AMDGPU_UCODE_REQUIRED,7734"amdgpu/%s_smc.bin", chip_name);7735if (err) {7736DRM_ERROR("si_smc: Failed to load firmware. err = %d\"%s_smc.bin\"\n",7737err, chip_name);7738amdgpu_ucode_release(&adev->pm.fw);7739}7740return err;7741}77427743static int si_dpm_sw_init(struct amdgpu_ip_block *ip_block)7744{7745int ret;7746struct amdgpu_device *adev = ip_block->adev;77477748ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 230, &adev->pm.dpm.thermal.irq);7749if (ret)7750return ret;77517752ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 231, &adev->pm.dpm.thermal.irq);7753if (ret)7754return ret;77557756/* default to balanced state */7757adev->pm.dpm.state = POWER_STATE_TYPE_BALANCED;7758adev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED;7759adev->pm.dpm.forced_level = AMD_DPM_FORCED_LEVEL_AUTO;7760adev->pm.default_sclk = adev->clock.default_sclk;7761adev->pm.default_mclk = adev->clock.default_mclk;7762adev->pm.current_sclk = adev->clock.default_sclk;7763adev->pm.current_mclk = adev->clock.default_mclk;7764adev->pm.int_thermal_type = THERMAL_TYPE_NONE;77657766if (amdgpu_dpm == 0)7767return 0;77687769ret = si_dpm_init_microcode(adev);7770if (ret)7771return ret;77727773INIT_WORK(&adev->pm.dpm.thermal.work, amdgpu_dpm_thermal_work_handler);7774ret = si_dpm_init(adev);7775if (ret)7776goto dpm_failed;7777adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;7778if (amdgpu_dpm == 1)7779amdgpu_pm_print_power_states(adev);7780DRM_INFO("amdgpu: dpm initialized\n");77817782return 0;77837784dpm_failed:7785si_dpm_fini(adev);7786DRM_ERROR("amdgpu: dpm initialization failed\n");7787return ret;7788}77897790static int si_dpm_sw_fini(struct amdgpu_ip_block *ip_block)7791{7792struct amdgpu_device *adev = ip_block->adev;77937794flush_work(&adev->pm.dpm.thermal.work);77957796si_dpm_fini(adev);77977798return 0;7799}78007801static int si_dpm_hw_init(struct amdgpu_ip_block *ip_block)7802{7803int ret;78047805struct amdgpu_device *adev = ip_block->adev;78067807if (!amdgpu_dpm)7808return 0;78097810mutex_lock(&adev->pm.mutex);7811si_dpm_setup_asic(adev);7812ret = si_dpm_enable(adev);7813if (ret)7814adev->pm.dpm_enabled = false;7815else7816adev->pm.dpm_enabled = true;7817amdgpu_legacy_dpm_compute_clocks(adev);7818mutex_unlock(&adev->pm.mutex);7819return ret;7820}78217822static int si_dpm_hw_fini(struct amdgpu_ip_block *ip_block)7823{7824struct amdgpu_device *adev = ip_block->adev;78257826if (adev->pm.dpm_enabled)7827si_dpm_disable(adev);78287829return 0;7830}78317832static int si_dpm_suspend(struct amdgpu_ip_block *ip_block)7833{7834struct amdgpu_device *adev = ip_block->adev;78357836cancel_work_sync(&adev->pm.dpm.thermal.work);78377838if (adev->pm.dpm_enabled) {7839mutex_lock(&adev->pm.mutex);7840adev->pm.dpm_enabled = false;7841/* disable dpm */7842si_dpm_disable(adev);7843/* reset the power state */7844adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;7845mutex_unlock(&adev->pm.mutex);7846}78477848return 0;7849}78507851static int si_dpm_resume(struct amdgpu_ip_block *ip_block)7852{7853int ret = 0;7854struct amdgpu_device *adev = ip_block->adev;78557856if (!amdgpu_dpm)7857return 0;78587859if (!adev->pm.dpm_enabled) {7860/* asic init will reset to the boot state */7861mutex_lock(&adev->pm.mutex);7862si_dpm_setup_asic(adev);7863ret = si_dpm_enable(adev);7864if (ret) {7865adev->pm.dpm_enabled = false;7866} else {7867adev->pm.dpm_enabled = true;7868amdgpu_legacy_dpm_compute_clocks(adev);7869}7870mutex_unlock(&adev->pm.mutex);7871}78727873return ret;7874}78757876static bool si_dpm_is_idle(struct amdgpu_ip_block *ip_block)7877{7878/* XXX */7879return true;7880}78817882static int si_dpm_wait_for_idle(struct amdgpu_ip_block *ip_block)7883{7884/* XXX */7885return 0;7886}78877888static int si_dpm_set_clockgating_state(struct amdgpu_ip_block *ip_block,7889enum amd_clockgating_state state)7890{7891return 0;7892}78937894static int si_dpm_set_powergating_state(struct amdgpu_ip_block *ip_block,7895enum amd_powergating_state state)7896{7897return 0;7898}78997900/* get temperature in millidegrees */7901static int si_dpm_get_temp(void *handle)7902{7903u32 temp;7904int actual_temp = 0;7905struct amdgpu_device *adev = (struct amdgpu_device *)handle;79067907temp = (RREG32(mmCG_MULT_THERMAL_STATUS) & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >>7908CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT;79097910if (temp & 0x200)7911actual_temp = 255;7912else7913actual_temp = temp & 0x1ff;79147915actual_temp = (actual_temp * 1000);79167917return actual_temp;7918}79197920static u32 si_dpm_get_sclk(void *handle, bool low)7921{7922struct amdgpu_device *adev = (struct amdgpu_device *)handle;7923struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7924struct si_ps *requested_state = si_get_ps(&eg_pi->requested_rps);79257926if (low)7927return requested_state->performance_levels[0].sclk;7928else7929return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk;7930}79317932static u32 si_dpm_get_mclk(void *handle, bool low)7933{7934struct amdgpu_device *adev = (struct amdgpu_device *)handle;7935struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);7936struct si_ps *requested_state = si_get_ps(&eg_pi->requested_rps);79377938if (low)7939return requested_state->performance_levels[0].mclk;7940else7941return requested_state->performance_levels[requested_state->performance_level_count - 1].mclk;7942}79437944static void si_dpm_print_power_state(void *handle,7945void *current_ps)7946{7947struct amdgpu_device *adev = (struct amdgpu_device *)handle;7948struct amdgpu_ps *rps = (struct amdgpu_ps *)current_ps;7949struct si_ps *ps = si_get_ps(rps);7950struct rv7xx_pl *pl;7951int i;79527953amdgpu_dpm_dbg_print_class_info(adev, rps->class, rps->class2);7954amdgpu_dpm_dbg_print_cap_info(adev, rps->caps);7955drm_dbg(adev_to_drm(adev), "\tuvd vclk: %d dclk: %d\n", rps->vclk, rps->dclk);7956for (i = 0; i < ps->performance_level_count; i++) {7957pl = &ps->performance_levels[i];7958drm_dbg(adev_to_drm(adev), "\t\tpower level %d sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",7959i, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);7960}7961amdgpu_dpm_dbg_print_ps_status(adev, rps);7962}79637964static int si_dpm_early_init(struct amdgpu_ip_block *ip_block)7965{79667967struct amdgpu_device *adev = ip_block->adev;79687969adev->powerplay.pp_funcs = &si_dpm_funcs;7970adev->powerplay.pp_handle = adev;7971si_dpm_set_irq_funcs(adev);7972return 0;7973}79747975static inline bool si_are_power_levels_equal(const struct rv7xx_pl *si_cpl1,7976const struct rv7xx_pl *si_cpl2)7977{7978return ((si_cpl1->mclk == si_cpl2->mclk) &&7979(si_cpl1->sclk == si_cpl2->sclk) &&7980(si_cpl1->pcie_gen == si_cpl2->pcie_gen) &&7981(si_cpl1->vddc == si_cpl2->vddc) &&7982(si_cpl1->vddci == si_cpl2->vddci));7983}79847985static int si_check_state_equal(void *handle,7986void *current_ps,7987void *request_ps,7988bool *equal)7989{7990struct si_ps *si_cps;7991struct si_ps *si_rps;7992int i;7993struct amdgpu_ps *cps = (struct amdgpu_ps *)current_ps;7994struct amdgpu_ps *rps = (struct amdgpu_ps *)request_ps;7995struct amdgpu_device *adev = (struct amdgpu_device *)handle;79967997if (adev == NULL || cps == NULL || rps == NULL || equal == NULL)7998return -EINVAL;79998000si_cps = si_get_ps((struct amdgpu_ps *)cps);8001si_rps = si_get_ps((struct amdgpu_ps *)rps);80028003if (si_cps == NULL) {8004printk("si_cps is NULL\n");8005*equal = false;8006return 0;8007}80088009if (si_cps->performance_level_count != si_rps->performance_level_count) {8010*equal = false;8011return 0;8012}80138014for (i = 0; i < si_cps->performance_level_count; i++) {8015if (!si_are_power_levels_equal(&(si_cps->performance_levels[i]),8016&(si_rps->performance_levels[i]))) {8017*equal = false;8018return 0;8019}8020}80218022/* If all performance levels are the same try to use the UVD clocks to break the tie.*/8023*equal = ((cps->vclk == rps->vclk) && (cps->dclk == rps->dclk));8024*equal &= ((cps->evclk == rps->evclk) && (cps->ecclk == rps->ecclk));80258026return 0;8027}80288029static int si_dpm_read_sensor(void *handle, int idx,8030void *value, int *size)8031{8032struct amdgpu_device *adev = (struct amdgpu_device *)handle;8033struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);8034struct amdgpu_ps *rps = &eg_pi->current_rps;8035struct si_ps *ps = si_get_ps(rps);8036uint32_t sclk, mclk;8037u32 pl_index =8038(RREG32(mmTARGET_AND_CURRENT_PROFILE_INDEX) & TARGET_AND_CURRENT_PROFILE_INDEX__CURRENT_STATE_INDEX_MASK) >>8039TARGET_AND_CURRENT_PROFILE_INDEX__CURRENT_STATE_INDEX__SHIFT;80408041/* size must be at least 4 bytes for all sensors */8042if (*size < 4)8043return -EINVAL;80448045switch (idx) {8046case AMDGPU_PP_SENSOR_GFX_SCLK:8047if (pl_index < ps->performance_level_count) {8048sclk = ps->performance_levels[pl_index].sclk;8049*((uint32_t *)value) = sclk;8050*size = 4;8051return 0;8052}8053return -EINVAL;8054case AMDGPU_PP_SENSOR_GFX_MCLK:8055if (pl_index < ps->performance_level_count) {8056mclk = ps->performance_levels[pl_index].mclk;8057*((uint32_t *)value) = mclk;8058*size = 4;8059return 0;8060}8061return -EINVAL;8062case AMDGPU_PP_SENSOR_GPU_TEMP:8063*((uint32_t *)value) = si_dpm_get_temp(adev);8064*size = 4;8065return 0;8066default:8067return -EOPNOTSUPP;8068}8069}80708071static const struct amd_ip_funcs si_dpm_ip_funcs = {8072.name = "si_dpm",8073.early_init = si_dpm_early_init,8074.late_init = si_dpm_late_init,8075.sw_init = si_dpm_sw_init,8076.sw_fini = si_dpm_sw_fini,8077.hw_init = si_dpm_hw_init,8078.hw_fini = si_dpm_hw_fini,8079.suspend = si_dpm_suspend,8080.resume = si_dpm_resume,8081.is_idle = si_dpm_is_idle,8082.wait_for_idle = si_dpm_wait_for_idle,8083.set_clockgating_state = si_dpm_set_clockgating_state,8084.set_powergating_state = si_dpm_set_powergating_state,8085};80868087const struct amdgpu_ip_block_version si_smu_ip_block =8088{8089.type = AMD_IP_BLOCK_TYPE_SMC,8090.major = 6,8091.minor = 0,8092.rev = 0,8093.funcs = &si_dpm_ip_funcs,8094};80958096static const struct amd_pm_funcs si_dpm_funcs = {8097.pre_set_power_state = &si_dpm_pre_set_power_state,8098.set_power_state = &si_dpm_set_power_state,8099.post_set_power_state = &si_dpm_post_set_power_state,8100.display_configuration_changed = &si_dpm_display_configuration_changed,8101.get_sclk = &si_dpm_get_sclk,8102.get_mclk = &si_dpm_get_mclk,8103.print_power_state = &si_dpm_print_power_state,8104.debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level,8105.force_performance_level = &si_dpm_force_performance_level,8106.vblank_too_short = &si_dpm_vblank_too_short,8107.set_fan_control_mode = &si_dpm_set_fan_control_mode,8108.get_fan_control_mode = &si_dpm_get_fan_control_mode,8109.set_fan_speed_pwm = &si_dpm_set_fan_speed_pwm,8110.get_fan_speed_pwm = &si_dpm_get_fan_speed_pwm,8111.check_state_equal = &si_check_state_equal,8112.get_vce_clock_state = amdgpu_get_vce_clock_state,8113.read_sensor = &si_dpm_read_sensor,8114.pm_compute_clocks = amdgpu_legacy_dpm_compute_clocks,8115};81168117static const struct amdgpu_irq_src_funcs si_dpm_irq_funcs = {8118.set = si_dpm_set_interrupt_state,8119.process = si_dpm_process_interrupt,8120};81218122static void si_dpm_set_irq_funcs(struct amdgpu_device *adev)8123{8124adev->pm.dpm.thermal.irq.num_types = AMDGPU_THERMAL_IRQ_LAST;8125adev->pm.dpm.thermal.irq.funcs = &si_dpm_irq_funcs;8126}8127812881298130