xref: /openbsd-src/sys/dev/pci/drm/amd/pm/legacy-dpm/amdgpu_si_dpm.c (revision e63417818b2b7cac6fb21f4ce19ac845a7d4c203)
11bb76ff1Sjsg /*
21bb76ff1Sjsg  * Copyright 2013 Advanced Micro Devices, Inc.
31bb76ff1Sjsg  *
41bb76ff1Sjsg  * Permission is hereby granted, free of charge, to any person obtaining a
51bb76ff1Sjsg  * copy of this software and associated documentation files (the "Software"),
61bb76ff1Sjsg  * to deal in the Software without restriction, including without limitation
71bb76ff1Sjsg  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
81bb76ff1Sjsg  * and/or sell copies of the Software, and to permit persons to whom the
91bb76ff1Sjsg  * Software is furnished to do so, subject to the following conditions:
101bb76ff1Sjsg  *
111bb76ff1Sjsg  * The above copyright notice and this permission notice shall be included in
121bb76ff1Sjsg  * all copies or substantial portions of the Software.
131bb76ff1Sjsg  *
141bb76ff1Sjsg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
151bb76ff1Sjsg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161bb76ff1Sjsg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
171bb76ff1Sjsg  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
181bb76ff1Sjsg  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
191bb76ff1Sjsg  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
201bb76ff1Sjsg  * OTHER DEALINGS IN THE SOFTWARE.
211bb76ff1Sjsg  *
221bb76ff1Sjsg  */
231bb76ff1Sjsg 
241bb76ff1Sjsg #include <linux/module.h>
251bb76ff1Sjsg #include <linux/pci.h>
261bb76ff1Sjsg 
271bb76ff1Sjsg #include "amdgpu.h"
281bb76ff1Sjsg #include "amdgpu_pm.h"
291bb76ff1Sjsg #include "amdgpu_dpm.h"
301bb76ff1Sjsg #include "amdgpu_atombios.h"
311bb76ff1Sjsg #include "amdgpu_dpm_internal.h"
321bb76ff1Sjsg #include "amd_pcie.h"
331bb76ff1Sjsg #include "sid.h"
341bb76ff1Sjsg #include "r600_dpm.h"
351bb76ff1Sjsg #include "si_dpm.h"
361bb76ff1Sjsg #include "atom.h"
371bb76ff1Sjsg #include "../include/pptable.h"
381bb76ff1Sjsg #include <linux/math64.h>
391bb76ff1Sjsg #include <linux/seq_file.h>
401bb76ff1Sjsg #include <linux/firmware.h>
411bb76ff1Sjsg #include <legacy_dpm.h>
421bb76ff1Sjsg 
431bb76ff1Sjsg #define MC_CG_ARB_FREQ_F0           0x0a
441bb76ff1Sjsg #define MC_CG_ARB_FREQ_F1           0x0b
451bb76ff1Sjsg #define MC_CG_ARB_FREQ_F2           0x0c
461bb76ff1Sjsg #define MC_CG_ARB_FREQ_F3           0x0d
471bb76ff1Sjsg 
481bb76ff1Sjsg #define SMC_RAM_END                 0x20000
491bb76ff1Sjsg 
501bb76ff1Sjsg #define SCLK_MIN_DEEPSLEEP_FREQ     1350
511bb76ff1Sjsg 
521bb76ff1Sjsg 
531bb76ff1Sjsg /* sizeof(ATOM_PPLIB_EXTENDEDHEADER) */
541bb76ff1Sjsg #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V2 12
551bb76ff1Sjsg #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V3 14
561bb76ff1Sjsg #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V4 16
571bb76ff1Sjsg #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V5 18
581bb76ff1Sjsg #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V6 20
591bb76ff1Sjsg #define SIZE_OF_ATOM_PPLIB_EXTENDEDHEADER_V7 22
601bb76ff1Sjsg 
611bb76ff1Sjsg #define BIOS_SCRATCH_4                                    0x5cd
621bb76ff1Sjsg 
631bb76ff1Sjsg MODULE_FIRMWARE("amdgpu/tahiti_smc.bin");
641bb76ff1Sjsg MODULE_FIRMWARE("amdgpu/pitcairn_smc.bin");
651bb76ff1Sjsg MODULE_FIRMWARE("amdgpu/pitcairn_k_smc.bin");
661bb76ff1Sjsg MODULE_FIRMWARE("amdgpu/verde_smc.bin");
671bb76ff1Sjsg MODULE_FIRMWARE("amdgpu/verde_k_smc.bin");
681bb76ff1Sjsg MODULE_FIRMWARE("amdgpu/oland_smc.bin");
691bb76ff1Sjsg MODULE_FIRMWARE("amdgpu/oland_k_smc.bin");
701bb76ff1Sjsg MODULE_FIRMWARE("amdgpu/hainan_smc.bin");
711bb76ff1Sjsg MODULE_FIRMWARE("amdgpu/hainan_k_smc.bin");
721bb76ff1Sjsg MODULE_FIRMWARE("amdgpu/banks_k_2_smc.bin");
731bb76ff1Sjsg 
741bb76ff1Sjsg static const struct amd_pm_funcs si_dpm_funcs;
751bb76ff1Sjsg 
761bb76ff1Sjsg union power_info {
771bb76ff1Sjsg 	struct _ATOM_POWERPLAY_INFO info;
781bb76ff1Sjsg 	struct _ATOM_POWERPLAY_INFO_V2 info_2;
791bb76ff1Sjsg 	struct _ATOM_POWERPLAY_INFO_V3 info_3;
801bb76ff1Sjsg 	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
811bb76ff1Sjsg 	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
821bb76ff1Sjsg 	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
831bb76ff1Sjsg 	struct _ATOM_PPLIB_POWERPLAYTABLE4 pplib4;
841bb76ff1Sjsg 	struct _ATOM_PPLIB_POWERPLAYTABLE5 pplib5;
851bb76ff1Sjsg };
861bb76ff1Sjsg 
871bb76ff1Sjsg union fan_info {
881bb76ff1Sjsg 	struct _ATOM_PPLIB_FANTABLE fan;
891bb76ff1Sjsg 	struct _ATOM_PPLIB_FANTABLE2 fan2;
901bb76ff1Sjsg 	struct _ATOM_PPLIB_FANTABLE3 fan3;
911bb76ff1Sjsg };
921bb76ff1Sjsg 
931bb76ff1Sjsg union pplib_clock_info {
941bb76ff1Sjsg 	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
951bb76ff1Sjsg 	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
961bb76ff1Sjsg 	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
971bb76ff1Sjsg 	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
981bb76ff1Sjsg 	struct _ATOM_PPLIB_SI_CLOCK_INFO si;
991bb76ff1Sjsg };
1001bb76ff1Sjsg 
1011bb76ff1Sjsg enum si_dpm_auto_throttle_src {
1021bb76ff1Sjsg 	SI_DPM_AUTO_THROTTLE_SRC_THERMAL,
1031bb76ff1Sjsg 	SI_DPM_AUTO_THROTTLE_SRC_EXTERNAL
1041bb76ff1Sjsg };
1051bb76ff1Sjsg 
1061bb76ff1Sjsg enum si_dpm_event_src {
1071bb76ff1Sjsg 	SI_DPM_EVENT_SRC_ANALOG = 0,
1081bb76ff1Sjsg 	SI_DPM_EVENT_SRC_EXTERNAL = 1,
1091bb76ff1Sjsg 	SI_DPM_EVENT_SRC_DIGITAL = 2,
1101bb76ff1Sjsg 	SI_DPM_EVENT_SRC_ANALOG_OR_EXTERNAL = 3,
1111bb76ff1Sjsg 	SI_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL = 4
1121bb76ff1Sjsg };
1131bb76ff1Sjsg 
1141bb76ff1Sjsg static const u32 r600_utc[R600_PM_NUMBER_OF_TC] =
1151bb76ff1Sjsg {
1161bb76ff1Sjsg 	R600_UTC_DFLT_00,
1171bb76ff1Sjsg 	R600_UTC_DFLT_01,
1181bb76ff1Sjsg 	R600_UTC_DFLT_02,
1191bb76ff1Sjsg 	R600_UTC_DFLT_03,
1201bb76ff1Sjsg 	R600_UTC_DFLT_04,
1211bb76ff1Sjsg 	R600_UTC_DFLT_05,
1221bb76ff1Sjsg 	R600_UTC_DFLT_06,
1231bb76ff1Sjsg 	R600_UTC_DFLT_07,
1241bb76ff1Sjsg 	R600_UTC_DFLT_08,
1251bb76ff1Sjsg 	R600_UTC_DFLT_09,
1261bb76ff1Sjsg 	R600_UTC_DFLT_10,
1271bb76ff1Sjsg 	R600_UTC_DFLT_11,
1281bb76ff1Sjsg 	R600_UTC_DFLT_12,
1291bb76ff1Sjsg 	R600_UTC_DFLT_13,
1301bb76ff1Sjsg 	R600_UTC_DFLT_14,
1311bb76ff1Sjsg };
1321bb76ff1Sjsg 
1331bb76ff1Sjsg static const u32 r600_dtc[R600_PM_NUMBER_OF_TC] =
1341bb76ff1Sjsg {
1351bb76ff1Sjsg 	R600_DTC_DFLT_00,
1361bb76ff1Sjsg 	R600_DTC_DFLT_01,
1371bb76ff1Sjsg 	R600_DTC_DFLT_02,
1381bb76ff1Sjsg 	R600_DTC_DFLT_03,
1391bb76ff1Sjsg 	R600_DTC_DFLT_04,
1401bb76ff1Sjsg 	R600_DTC_DFLT_05,
1411bb76ff1Sjsg 	R600_DTC_DFLT_06,
1421bb76ff1Sjsg 	R600_DTC_DFLT_07,
1431bb76ff1Sjsg 	R600_DTC_DFLT_08,
1441bb76ff1Sjsg 	R600_DTC_DFLT_09,
1451bb76ff1Sjsg 	R600_DTC_DFLT_10,
1461bb76ff1Sjsg 	R600_DTC_DFLT_11,
1471bb76ff1Sjsg 	R600_DTC_DFLT_12,
1481bb76ff1Sjsg 	R600_DTC_DFLT_13,
1491bb76ff1Sjsg 	R600_DTC_DFLT_14,
1501bb76ff1Sjsg };
1511bb76ff1Sjsg 
1521bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_tahiti[] =
1531bb76ff1Sjsg {
1541bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0xc, SISLANDS_CACCONFIG_CGIND },
1551bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1561bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0x101, SISLANDS_CACCONFIG_CGIND },
1571bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0xc, SISLANDS_CACCONFIG_CGIND },
1581bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1591bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1601bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1611bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1621bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1631bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x8fc, SISLANDS_CACCONFIG_CGIND },
1641bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1651bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x95, SISLANDS_CACCONFIG_CGIND },
1661bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x34e, SISLANDS_CACCONFIG_CGIND },
1671bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x1a1, SISLANDS_CACCONFIG_CGIND },
1681bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0xda, SISLANDS_CACCONFIG_CGIND },
1691bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1701bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1711bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x46, SISLANDS_CACCONFIG_CGIND },
1721bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1731bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x208, SISLANDS_CACCONFIG_CGIND },
1741bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0xe7, SISLANDS_CACCONFIG_CGIND },
1751bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x948, SISLANDS_CACCONFIG_CGIND },
1761bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1771bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1781bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1791bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1801bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1811bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1821bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1831bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1841bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x167, SISLANDS_CACCONFIG_CGIND },
1851bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1861bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1871bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1881bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
1891bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1901bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1911bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
1921bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1931bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x31, SISLANDS_CACCONFIG_CGIND },
1941bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1951bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1961bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1971bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1981bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1991bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
2001bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
2011bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
2021bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
2031bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
2041bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
2051bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
2061bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
2071bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
2081bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
2091bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
2101bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
2111bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
2121bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
2131bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0x18e, SISLANDS_CACCONFIG_CGIND },
2141bb76ff1Sjsg 	{ 0xFFFFFFFF }
2151bb76ff1Sjsg };
2161bb76ff1Sjsg 
2171bb76ff1Sjsg static const struct si_cac_config_reg lcac_tahiti[] =
2181bb76ff1Sjsg {
2191bb76ff1Sjsg 	{ 0x143, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
2201bb76ff1Sjsg 	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2211bb76ff1Sjsg 	{ 0x146, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
2221bb76ff1Sjsg 	{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2231bb76ff1Sjsg 	{ 0x149, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
2241bb76ff1Sjsg 	{ 0x149, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2251bb76ff1Sjsg 	{ 0x14c, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
2261bb76ff1Sjsg 	{ 0x14c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2271bb76ff1Sjsg 	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2281bb76ff1Sjsg 	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2291bb76ff1Sjsg 	{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2301bb76ff1Sjsg 	{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2311bb76ff1Sjsg 	{ 0x9e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2321bb76ff1Sjsg 	{ 0x9e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2331bb76ff1Sjsg 	{ 0x101, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2341bb76ff1Sjsg 	{ 0x101, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2351bb76ff1Sjsg 	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2361bb76ff1Sjsg 	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2371bb76ff1Sjsg 	{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2381bb76ff1Sjsg 	{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2391bb76ff1Sjsg 	{ 0x10a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2401bb76ff1Sjsg 	{ 0x10a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2411bb76ff1Sjsg 	{ 0x10d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2421bb76ff1Sjsg 	{ 0x10d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2431bb76ff1Sjsg 	{ 0x8c, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2441bb76ff1Sjsg 	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2451bb76ff1Sjsg 	{ 0x8f, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2461bb76ff1Sjsg 	{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2471bb76ff1Sjsg 	{ 0x92, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2481bb76ff1Sjsg 	{ 0x92, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2491bb76ff1Sjsg 	{ 0x95, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2501bb76ff1Sjsg 	{ 0x95, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2511bb76ff1Sjsg 	{ 0x14f, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2521bb76ff1Sjsg 	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2531bb76ff1Sjsg 	{ 0x152, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2541bb76ff1Sjsg 	{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2551bb76ff1Sjsg 	{ 0x155, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2561bb76ff1Sjsg 	{ 0x155, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2571bb76ff1Sjsg 	{ 0x158, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2581bb76ff1Sjsg 	{ 0x158, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2591bb76ff1Sjsg 	{ 0x110, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2601bb76ff1Sjsg 	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2611bb76ff1Sjsg 	{ 0x113, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2621bb76ff1Sjsg 	{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2631bb76ff1Sjsg 	{ 0x116, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2641bb76ff1Sjsg 	{ 0x116, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2651bb76ff1Sjsg 	{ 0x119, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
2661bb76ff1Sjsg 	{ 0x119, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2671bb76ff1Sjsg 	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2681bb76ff1Sjsg 	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2691bb76ff1Sjsg 	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2701bb76ff1Sjsg 	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2711bb76ff1Sjsg 	{ 0x122, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2721bb76ff1Sjsg 	{ 0x122, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2731bb76ff1Sjsg 	{ 0x125, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2741bb76ff1Sjsg 	{ 0x125, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2751bb76ff1Sjsg 	{ 0x128, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2761bb76ff1Sjsg 	{ 0x128, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2771bb76ff1Sjsg 	{ 0x12b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2781bb76ff1Sjsg 	{ 0x12b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2791bb76ff1Sjsg 	{ 0x15b, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
2801bb76ff1Sjsg 	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2811bb76ff1Sjsg 	{ 0x15e, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
2821bb76ff1Sjsg 	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2831bb76ff1Sjsg 	{ 0x161, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
2841bb76ff1Sjsg 	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2851bb76ff1Sjsg 	{ 0x164, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
2861bb76ff1Sjsg 	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2871bb76ff1Sjsg 	{ 0x167, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
2881bb76ff1Sjsg 	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2891bb76ff1Sjsg 	{ 0x16a, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
2901bb76ff1Sjsg 	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2911bb76ff1Sjsg 	{ 0x16d, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
2921bb76ff1Sjsg 	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2931bb76ff1Sjsg 	{ 0x170, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2941bb76ff1Sjsg 	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2951bb76ff1Sjsg 	{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2961bb76ff1Sjsg 	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2971bb76ff1Sjsg 	{ 0x176, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2981bb76ff1Sjsg 	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2991bb76ff1Sjsg 	{ 0x179, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
3001bb76ff1Sjsg 	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
3011bb76ff1Sjsg 	{ 0x17c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
3021bb76ff1Sjsg 	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
3031bb76ff1Sjsg 	{ 0x17f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
3041bb76ff1Sjsg 	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
3051bb76ff1Sjsg 	{ 0xFFFFFFFF }
3061bb76ff1Sjsg 
3071bb76ff1Sjsg };
3081bb76ff1Sjsg 
3091bb76ff1Sjsg static const struct si_cac_config_reg cac_override_tahiti[] =
3101bb76ff1Sjsg {
3111bb76ff1Sjsg 	{ 0xFFFFFFFF }
3121bb76ff1Sjsg };
3131bb76ff1Sjsg 
3141bb76ff1Sjsg static const struct si_powertune_data powertune_data_tahiti =
3151bb76ff1Sjsg {
3161bb76ff1Sjsg 	((1 << 16) | 27027),
3171bb76ff1Sjsg 	6,
3181bb76ff1Sjsg 	0,
3191bb76ff1Sjsg 	4,
3201bb76ff1Sjsg 	95,
3211bb76ff1Sjsg 	{
3221bb76ff1Sjsg 		0UL,
3231bb76ff1Sjsg 		0UL,
3241bb76ff1Sjsg 		4521550UL,
3251bb76ff1Sjsg 		309631529UL,
3261bb76ff1Sjsg 		-1270850L,
3271bb76ff1Sjsg 		4513710L,
3281bb76ff1Sjsg 		40
3291bb76ff1Sjsg 	},
3301bb76ff1Sjsg 	595000000UL,
3311bb76ff1Sjsg 	12,
3321bb76ff1Sjsg 	{
3331bb76ff1Sjsg 		0,
3341bb76ff1Sjsg 		0,
3351bb76ff1Sjsg 		0,
3361bb76ff1Sjsg 		0,
3371bb76ff1Sjsg 		0,
3381bb76ff1Sjsg 		0,
3391bb76ff1Sjsg 		0,
3401bb76ff1Sjsg 		0
3411bb76ff1Sjsg 	},
3421bb76ff1Sjsg 	true
3431bb76ff1Sjsg };
3441bb76ff1Sjsg 
3451bb76ff1Sjsg static const struct si_dte_data dte_data_tahiti =
3461bb76ff1Sjsg {
3471bb76ff1Sjsg 	{ 1159409, 0, 0, 0, 0 },
3481bb76ff1Sjsg 	{ 777, 0, 0, 0, 0 },
3491bb76ff1Sjsg 	2,
3501bb76ff1Sjsg 	54000,
3511bb76ff1Sjsg 	127000,
3521bb76ff1Sjsg 	25,
3531bb76ff1Sjsg 	2,
3541bb76ff1Sjsg 	10,
3551bb76ff1Sjsg 	13,
3561bb76ff1Sjsg 	{ 27, 31, 35, 39, 43, 47, 54, 61, 67, 74, 81, 88, 95, 0, 0, 0 },
3571bb76ff1Sjsg 	{ 240888759, 221057860, 235370597, 162287531, 158510299, 131423027, 116673180, 103067515, 87941937, 76209048, 68209175, 64090048, 58301890, 0, 0, 0 },
3581bb76ff1Sjsg 	{ 12024, 11189, 11451, 8411, 7939, 6666, 5681, 4905, 4241, 3720, 3354, 3122, 2890, 0, 0, 0 },
3591bb76ff1Sjsg 	85,
3601bb76ff1Sjsg 	false
3611bb76ff1Sjsg };
3621bb76ff1Sjsg 
3631bb76ff1Sjsg static const struct si_dte_data dte_data_tahiti_pro =
3641bb76ff1Sjsg {
3651bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
3661bb76ff1Sjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
3671bb76ff1Sjsg 	5,
3681bb76ff1Sjsg 	45000,
3691bb76ff1Sjsg 	100,
3701bb76ff1Sjsg 	0xA,
3711bb76ff1Sjsg 	1,
3721bb76ff1Sjsg 	0,
3731bb76ff1Sjsg 	0x10,
3741bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
3751bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
3761bb76ff1Sjsg 	{ 0x7D0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
3771bb76ff1Sjsg 	90,
3781bb76ff1Sjsg 	true
3791bb76ff1Sjsg };
3801bb76ff1Sjsg 
3811bb76ff1Sjsg static const struct si_dte_data dte_data_new_zealand =
3821bb76ff1Sjsg {
3831bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0 },
3841bb76ff1Sjsg 	{ 0x29B, 0x3E9, 0x537, 0x7D2, 0 },
3851bb76ff1Sjsg 	0x5,
3861bb76ff1Sjsg 	0xAFC8,
3871bb76ff1Sjsg 	0x69,
3881bb76ff1Sjsg 	0x32,
3891bb76ff1Sjsg 	1,
3901bb76ff1Sjsg 	0,
3911bb76ff1Sjsg 	0x10,
3921bb76ff1Sjsg 	{ 0x82, 0xA0, 0xB4, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
3931bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
3941bb76ff1Sjsg 	{ 0xDAC, 0x1388, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685 },
3951bb76ff1Sjsg 	85,
3961bb76ff1Sjsg 	true
3971bb76ff1Sjsg };
3981bb76ff1Sjsg 
3991bb76ff1Sjsg static const struct si_dte_data dte_data_aruba_pro =
4001bb76ff1Sjsg {
4011bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
4021bb76ff1Sjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
4031bb76ff1Sjsg 	5,
4041bb76ff1Sjsg 	45000,
4051bb76ff1Sjsg 	100,
4061bb76ff1Sjsg 	0xA,
4071bb76ff1Sjsg 	1,
4081bb76ff1Sjsg 	0,
4091bb76ff1Sjsg 	0x10,
4101bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
4111bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
4121bb76ff1Sjsg 	{ 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
4131bb76ff1Sjsg 	90,
4141bb76ff1Sjsg 	true
4151bb76ff1Sjsg };
4161bb76ff1Sjsg 
4171bb76ff1Sjsg static const struct si_dte_data dte_data_malta =
4181bb76ff1Sjsg {
4191bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
4201bb76ff1Sjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
4211bb76ff1Sjsg 	5,
4221bb76ff1Sjsg 	45000,
4231bb76ff1Sjsg 	100,
4241bb76ff1Sjsg 	0xA,
4251bb76ff1Sjsg 	1,
4261bb76ff1Sjsg 	0,
4271bb76ff1Sjsg 	0x10,
4281bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
4291bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
4301bb76ff1Sjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
4311bb76ff1Sjsg 	90,
4321bb76ff1Sjsg 	true
4331bb76ff1Sjsg };
4341bb76ff1Sjsg 
4351bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_pitcairn[] =
4361bb76ff1Sjsg {
4371bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x8a, SISLANDS_CACCONFIG_CGIND },
4381bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4391bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4401bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x24d, SISLANDS_CACCONFIG_CGIND },
4411bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x19, SISLANDS_CACCONFIG_CGIND },
4421bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
4431bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4441bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
4451bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4461bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0xc11, SISLANDS_CACCONFIG_CGIND },
4471bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0x7f3, SISLANDS_CACCONFIG_CGIND },
4481bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x403, SISLANDS_CACCONFIG_CGIND },
4491bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x367, SISLANDS_CACCONFIG_CGIND },
4501bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x4c9, SISLANDS_CACCONFIG_CGIND },
4511bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4521bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4531bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4541bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x45d, SISLANDS_CACCONFIG_CGIND },
4551bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0x36d, SISLANDS_CACCONFIG_CGIND },
4561bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x534, SISLANDS_CACCONFIG_CGIND },
4571bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x5da, SISLANDS_CACCONFIG_CGIND },
4581bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x880, SISLANDS_CACCONFIG_CGIND },
4591bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0x201, SISLANDS_CACCONFIG_CGIND },
4601bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4611bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4621bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0x9f, SISLANDS_CACCONFIG_CGIND },
4631bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x1f, SISLANDS_CACCONFIG_CGIND },
4641bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4651bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4661bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4671bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x5de, SISLANDS_CACCONFIG_CGIND },
4681bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4691bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x7b, SISLANDS_CACCONFIG_CGIND },
4701bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4711bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x13, SISLANDS_CACCONFIG_CGIND },
4721bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0xf9, SISLANDS_CACCONFIG_CGIND },
4731bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x66, SISLANDS_CACCONFIG_CGIND },
4741bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4751bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x13, SISLANDS_CACCONFIG_CGIND },
4761bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4771bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4781bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4791bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4801bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4811bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4821bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4831bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4841bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4851bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4861bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4871bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4881bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4891bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4901bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4911bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4921bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4931bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4941bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
4951bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
4961bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0x186, SISLANDS_CACCONFIG_CGIND },
4971bb76ff1Sjsg 	{ 0xFFFFFFFF }
4981bb76ff1Sjsg };
4991bb76ff1Sjsg 
5001bb76ff1Sjsg static const struct si_cac_config_reg lcac_pitcairn[] =
5011bb76ff1Sjsg {
5021bb76ff1Sjsg 	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5031bb76ff1Sjsg 	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5041bb76ff1Sjsg 	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5051bb76ff1Sjsg 	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5061bb76ff1Sjsg 	{ 0x110, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5071bb76ff1Sjsg 	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5081bb76ff1Sjsg 	{ 0x14f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5091bb76ff1Sjsg 	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5101bb76ff1Sjsg 	{ 0x8c, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5111bb76ff1Sjsg 	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5121bb76ff1Sjsg 	{ 0x143, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5131bb76ff1Sjsg 	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5141bb76ff1Sjsg 	{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5151bb76ff1Sjsg 	{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5161bb76ff1Sjsg 	{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5171bb76ff1Sjsg 	{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5181bb76ff1Sjsg 	{ 0x113, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5191bb76ff1Sjsg 	{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5201bb76ff1Sjsg 	{ 0x152, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5211bb76ff1Sjsg 	{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5221bb76ff1Sjsg 	{ 0x8f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5231bb76ff1Sjsg 	{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5241bb76ff1Sjsg 	{ 0x146, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5251bb76ff1Sjsg 	{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5261bb76ff1Sjsg 	{ 0x9e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5271bb76ff1Sjsg 	{ 0x9e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5281bb76ff1Sjsg 	{ 0x10a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5291bb76ff1Sjsg 	{ 0x10a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5301bb76ff1Sjsg 	{ 0x116, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5311bb76ff1Sjsg 	{ 0x116, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5321bb76ff1Sjsg 	{ 0x155, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5331bb76ff1Sjsg 	{ 0x155, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5341bb76ff1Sjsg 	{ 0x92, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5351bb76ff1Sjsg 	{ 0x92, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5361bb76ff1Sjsg 	{ 0x149, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5371bb76ff1Sjsg 	{ 0x149, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5381bb76ff1Sjsg 	{ 0x101, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5391bb76ff1Sjsg 	{ 0x101, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5401bb76ff1Sjsg 	{ 0x10d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5411bb76ff1Sjsg 	{ 0x10d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5421bb76ff1Sjsg 	{ 0x119, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5431bb76ff1Sjsg 	{ 0x119, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5441bb76ff1Sjsg 	{ 0x158, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5451bb76ff1Sjsg 	{ 0x158, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5461bb76ff1Sjsg 	{ 0x95, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
5471bb76ff1Sjsg 	{ 0x95, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5481bb76ff1Sjsg 	{ 0x14c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5491bb76ff1Sjsg 	{ 0x14c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5501bb76ff1Sjsg 	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5511bb76ff1Sjsg 	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5521bb76ff1Sjsg 	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5531bb76ff1Sjsg 	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5541bb76ff1Sjsg 	{ 0x122, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5551bb76ff1Sjsg 	{ 0x122, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5561bb76ff1Sjsg 	{ 0x125, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5571bb76ff1Sjsg 	{ 0x125, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5581bb76ff1Sjsg 	{ 0x128, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5591bb76ff1Sjsg 	{ 0x128, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5601bb76ff1Sjsg 	{ 0x12b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5611bb76ff1Sjsg 	{ 0x12b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5621bb76ff1Sjsg 	{ 0x164, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
5631bb76ff1Sjsg 	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5641bb76ff1Sjsg 	{ 0x167, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
5651bb76ff1Sjsg 	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5661bb76ff1Sjsg 	{ 0x16a, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
5671bb76ff1Sjsg 	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5681bb76ff1Sjsg 	{ 0x15e, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
5691bb76ff1Sjsg 	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5701bb76ff1Sjsg 	{ 0x161, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
5711bb76ff1Sjsg 	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5721bb76ff1Sjsg 	{ 0x15b, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
5731bb76ff1Sjsg 	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5741bb76ff1Sjsg 	{ 0x16d, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
5751bb76ff1Sjsg 	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5761bb76ff1Sjsg 	{ 0x170, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5771bb76ff1Sjsg 	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5781bb76ff1Sjsg 	{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5791bb76ff1Sjsg 	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5801bb76ff1Sjsg 	{ 0x176, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5811bb76ff1Sjsg 	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5821bb76ff1Sjsg 	{ 0x179, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5831bb76ff1Sjsg 	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5841bb76ff1Sjsg 	{ 0x17c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5851bb76ff1Sjsg 	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5861bb76ff1Sjsg 	{ 0x17f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
5871bb76ff1Sjsg 	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
5881bb76ff1Sjsg 	{ 0xFFFFFFFF }
5891bb76ff1Sjsg };
5901bb76ff1Sjsg 
5911bb76ff1Sjsg static const struct si_cac_config_reg cac_override_pitcairn[] =
5921bb76ff1Sjsg {
5931bb76ff1Sjsg     { 0xFFFFFFFF }
5941bb76ff1Sjsg };
5951bb76ff1Sjsg 
5961bb76ff1Sjsg static const struct si_powertune_data powertune_data_pitcairn =
5971bb76ff1Sjsg {
5981bb76ff1Sjsg 	((1 << 16) | 27027),
5991bb76ff1Sjsg 	5,
6001bb76ff1Sjsg 	0,
6011bb76ff1Sjsg 	6,
6021bb76ff1Sjsg 	100,
6031bb76ff1Sjsg 	{
6041bb76ff1Sjsg 		51600000UL,
6051bb76ff1Sjsg 		1800000UL,
6061bb76ff1Sjsg 		7194395UL,
6071bb76ff1Sjsg 		309631529UL,
6081bb76ff1Sjsg 		-1270850L,
6091bb76ff1Sjsg 		4513710L,
6101bb76ff1Sjsg 		100
6111bb76ff1Sjsg 	},
6121bb76ff1Sjsg 	117830498UL,
6131bb76ff1Sjsg 	12,
6141bb76ff1Sjsg 	{
6151bb76ff1Sjsg 		0,
6161bb76ff1Sjsg 		0,
6171bb76ff1Sjsg 		0,
6181bb76ff1Sjsg 		0,
6191bb76ff1Sjsg 		0,
6201bb76ff1Sjsg 		0,
6211bb76ff1Sjsg 		0,
6221bb76ff1Sjsg 		0
6231bb76ff1Sjsg 	},
6241bb76ff1Sjsg 	true
6251bb76ff1Sjsg };
6261bb76ff1Sjsg 
6271bb76ff1Sjsg static const struct si_dte_data dte_data_pitcairn =
6281bb76ff1Sjsg {
6291bb76ff1Sjsg 	{ 0, 0, 0, 0, 0 },
6301bb76ff1Sjsg 	{ 0, 0, 0, 0, 0 },
6311bb76ff1Sjsg 	0,
6321bb76ff1Sjsg 	0,
6331bb76ff1Sjsg 	0,
6341bb76ff1Sjsg 	0,
6351bb76ff1Sjsg 	0,
6361bb76ff1Sjsg 	0,
6371bb76ff1Sjsg 	0,
6381bb76ff1Sjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
6391bb76ff1Sjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
6401bb76ff1Sjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
6411bb76ff1Sjsg 	0,
6421bb76ff1Sjsg 	false
6431bb76ff1Sjsg };
6441bb76ff1Sjsg 
6451bb76ff1Sjsg static const struct si_dte_data dte_data_curacao_xt =
6461bb76ff1Sjsg {
6471bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
6481bb76ff1Sjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
6491bb76ff1Sjsg 	5,
6501bb76ff1Sjsg 	45000,
6511bb76ff1Sjsg 	100,
6521bb76ff1Sjsg 	0xA,
6531bb76ff1Sjsg 	1,
6541bb76ff1Sjsg 	0,
6551bb76ff1Sjsg 	0x10,
6561bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
6571bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
6581bb76ff1Sjsg 	{ 0x1D17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
6591bb76ff1Sjsg 	90,
6601bb76ff1Sjsg 	true
6611bb76ff1Sjsg };
6621bb76ff1Sjsg 
6631bb76ff1Sjsg static const struct si_dte_data dte_data_curacao_pro =
6641bb76ff1Sjsg {
6651bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
6661bb76ff1Sjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
6671bb76ff1Sjsg 	5,
6681bb76ff1Sjsg 	45000,
6691bb76ff1Sjsg 	100,
6701bb76ff1Sjsg 	0xA,
6711bb76ff1Sjsg 	1,
6721bb76ff1Sjsg 	0,
6731bb76ff1Sjsg 	0x10,
6741bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
6751bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
6761bb76ff1Sjsg 	{ 0x1D17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
6771bb76ff1Sjsg 	90,
6781bb76ff1Sjsg 	true
6791bb76ff1Sjsg };
6801bb76ff1Sjsg 
6811bb76ff1Sjsg static const struct si_dte_data dte_data_neptune_xt =
6821bb76ff1Sjsg {
6831bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
6841bb76ff1Sjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
6851bb76ff1Sjsg 	5,
6861bb76ff1Sjsg 	45000,
6871bb76ff1Sjsg 	100,
6881bb76ff1Sjsg 	0xA,
6891bb76ff1Sjsg 	1,
6901bb76ff1Sjsg 	0,
6911bb76ff1Sjsg 	0x10,
6921bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
6931bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
6941bb76ff1Sjsg 	{ 0x3A2F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
6951bb76ff1Sjsg 	90,
6961bb76ff1Sjsg 	true
6971bb76ff1Sjsg };
6981bb76ff1Sjsg 
6991bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_chelsea_pro[] =
7001bb76ff1Sjsg {
7011bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
7021bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
7031bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
7041bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
7051bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7061bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
7071bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
7081bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
7091bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
7101bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
7111bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
7121bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
7131bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
7141bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
7151bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
7161bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
7171bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
7181bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
7191bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
7201bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
7211bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
7221bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
7231bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
7241bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
7251bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
7261bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
7271bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
7281bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
7291bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
7301bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
7311bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
7321bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
7331bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
7341bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
7351bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
7361bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x2BD, SISLANDS_CACCONFIG_CGIND },
7371bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7381bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
7391bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7401bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
7411bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
7421bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7431bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7441bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
7451bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7461bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
7471bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7481bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7491bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7501bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7511bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7521bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7531bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7541bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7551bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7561bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7571bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7581bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7591bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7601bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
7611bb76ff1Sjsg 	{ 0xFFFFFFFF }
7621bb76ff1Sjsg };
7631bb76ff1Sjsg 
7641bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_chelsea_xt[] =
7651bb76ff1Sjsg {
7661bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
7671bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
7681bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
7691bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
7701bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7711bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
7721bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
7731bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
7741bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
7751bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
7761bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
7771bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
7781bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
7791bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
7801bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
7811bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
7821bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
7831bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
7841bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
7851bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
7861bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
7871bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
7881bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
7891bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
7901bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
7911bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
7921bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
7931bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
7941bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
7951bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
7961bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
7971bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
7981bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
7991bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
8001bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
8011bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x30A, SISLANDS_CACCONFIG_CGIND },
8021bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8031bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
8041bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8051bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
8061bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
8071bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8081bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8091bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
8101bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8111bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
8121bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8131bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8141bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8151bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8161bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8171bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8181bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8191bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8201bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8211bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8221bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8231bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8241bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8251bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
8261bb76ff1Sjsg 	{ 0xFFFFFFFF }
8271bb76ff1Sjsg };
8281bb76ff1Sjsg 
8291bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_heathrow[] =
8301bb76ff1Sjsg {
8311bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
8321bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
8331bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
8341bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
8351bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8361bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
8371bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
8381bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
8391bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
8401bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
8411bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
8421bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
8431bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
8441bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
8451bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
8461bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
8471bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
8481bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
8491bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
8501bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
8511bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
8521bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
8531bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
8541bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
8551bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
8561bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
8571bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
8581bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
8591bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
8601bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
8611bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
8621bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
8631bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
8641bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
8651bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
8661bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x362, SISLANDS_CACCONFIG_CGIND },
8671bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8681bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
8691bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8701bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
8711bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
8721bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8731bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8741bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
8751bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8761bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
8771bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8781bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8791bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8801bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8811bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8821bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8831bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8841bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8851bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8861bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8871bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8881bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8891bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8901bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
8911bb76ff1Sjsg 	{ 0xFFFFFFFF }
8921bb76ff1Sjsg };
8931bb76ff1Sjsg 
8941bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_cape_verde_pro[] =
8951bb76ff1Sjsg {
8961bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
8971bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
8981bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
8991bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
9001bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9011bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
9021bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
9031bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
9041bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
9051bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
9061bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
9071bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
9081bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
9091bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
9101bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
9111bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
9121bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
9131bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
9141bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
9151bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
9161bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
9171bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
9181bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
9191bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
9201bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
9211bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
9221bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
9231bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
9241bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9251bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
9261bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
9271bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
9281bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
9291bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
9301bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
9311bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x315, SISLANDS_CACCONFIG_CGIND },
9321bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9331bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
9341bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9351bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
9361bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
9371bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9381bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9391bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
9401bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9411bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
9421bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9431bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9441bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9451bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9461bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9471bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9481bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9491bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9501bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9511bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9521bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9531bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9541bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9551bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
9561bb76ff1Sjsg 	{ 0xFFFFFFFF }
9571bb76ff1Sjsg };
9581bb76ff1Sjsg 
9591bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_cape_verde[] =
9601bb76ff1Sjsg {
9611bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
9621bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
9631bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
9641bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
9651bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9661bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
9671bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
9681bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
9691bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
9701bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
9711bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
9721bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
9731bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
9741bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
9751bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
9761bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
9771bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
9781bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
9791bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
9801bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
9811bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
9821bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
9831bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
9841bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
9851bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
9861bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
9871bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
9881bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
9891bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9901bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
9911bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
9921bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
9931bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
9941bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
9951bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
9961bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x3BA, SISLANDS_CACCONFIG_CGIND },
9971bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9981bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
9991bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
10001bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
10011bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
10021bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
10031bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
10041bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
10051bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
10061bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
10071bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
10081bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
10091bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
10101bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
10111bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
10121bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
10131bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
10141bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
10151bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
10161bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
10171bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
10181bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
10191bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
10201bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
10211bb76ff1Sjsg 	{ 0xFFFFFFFF }
10221bb76ff1Sjsg };
10231bb76ff1Sjsg 
10241bb76ff1Sjsg static const struct si_cac_config_reg lcac_cape_verde[] =
10251bb76ff1Sjsg {
10261bb76ff1Sjsg 	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10271bb76ff1Sjsg 	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10281bb76ff1Sjsg 	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10291bb76ff1Sjsg 	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10301bb76ff1Sjsg 	{ 0x110, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
10311bb76ff1Sjsg 	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10321bb76ff1Sjsg 	{ 0x14f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
10331bb76ff1Sjsg 	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10341bb76ff1Sjsg 	{ 0x8c, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
10351bb76ff1Sjsg 	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10361bb76ff1Sjsg 	{ 0x143, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
10371bb76ff1Sjsg 	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10381bb76ff1Sjsg 	{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10391bb76ff1Sjsg 	{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10401bb76ff1Sjsg 	{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10411bb76ff1Sjsg 	{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10421bb76ff1Sjsg 	{ 0x113, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
10431bb76ff1Sjsg 	{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10441bb76ff1Sjsg 	{ 0x152, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
10451bb76ff1Sjsg 	{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10461bb76ff1Sjsg 	{ 0x8f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
10471bb76ff1Sjsg 	{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10481bb76ff1Sjsg 	{ 0x146, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
10491bb76ff1Sjsg 	{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10501bb76ff1Sjsg 	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10511bb76ff1Sjsg 	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10521bb76ff1Sjsg 	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10531bb76ff1Sjsg 	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10541bb76ff1Sjsg 	{ 0x164, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10551bb76ff1Sjsg 	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10561bb76ff1Sjsg 	{ 0x167, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10571bb76ff1Sjsg 	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10581bb76ff1Sjsg 	{ 0x16a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10591bb76ff1Sjsg 	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10601bb76ff1Sjsg 	{ 0x15e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10611bb76ff1Sjsg 	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10621bb76ff1Sjsg 	{ 0x161, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10631bb76ff1Sjsg 	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10641bb76ff1Sjsg 	{ 0x15b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10651bb76ff1Sjsg 	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10661bb76ff1Sjsg 	{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10671bb76ff1Sjsg 	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10681bb76ff1Sjsg 	{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
10691bb76ff1Sjsg 	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10701bb76ff1Sjsg 	{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
10711bb76ff1Sjsg 	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10721bb76ff1Sjsg 	{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
10731bb76ff1Sjsg 	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10741bb76ff1Sjsg 	{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
10751bb76ff1Sjsg 	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10761bb76ff1Sjsg 	{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
10771bb76ff1Sjsg 	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10781bb76ff1Sjsg 	{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
10791bb76ff1Sjsg 	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
10801bb76ff1Sjsg 	{ 0xFFFFFFFF }
10811bb76ff1Sjsg };
10821bb76ff1Sjsg 
10831bb76ff1Sjsg static const struct si_cac_config_reg cac_override_cape_verde[] =
10841bb76ff1Sjsg {
10851bb76ff1Sjsg     { 0xFFFFFFFF }
10861bb76ff1Sjsg };
10871bb76ff1Sjsg 
10881bb76ff1Sjsg static const struct si_powertune_data powertune_data_cape_verde =
10891bb76ff1Sjsg {
10901bb76ff1Sjsg 	((1 << 16) | 0x6993),
10911bb76ff1Sjsg 	5,
10921bb76ff1Sjsg 	0,
10931bb76ff1Sjsg 	7,
10941bb76ff1Sjsg 	105,
10951bb76ff1Sjsg 	{
10961bb76ff1Sjsg 		0UL,
10971bb76ff1Sjsg 		0UL,
10981bb76ff1Sjsg 		7194395UL,
10991bb76ff1Sjsg 		309631529UL,
11001bb76ff1Sjsg 		-1270850L,
11011bb76ff1Sjsg 		4513710L,
11021bb76ff1Sjsg 		100
11031bb76ff1Sjsg 	},
11041bb76ff1Sjsg 	117830498UL,
11051bb76ff1Sjsg 	12,
11061bb76ff1Sjsg 	{
11071bb76ff1Sjsg 		0,
11081bb76ff1Sjsg 		0,
11091bb76ff1Sjsg 		0,
11101bb76ff1Sjsg 		0,
11111bb76ff1Sjsg 		0,
11121bb76ff1Sjsg 		0,
11131bb76ff1Sjsg 		0,
11141bb76ff1Sjsg 		0
11151bb76ff1Sjsg 	},
11161bb76ff1Sjsg 	true
11171bb76ff1Sjsg };
11181bb76ff1Sjsg 
11191bb76ff1Sjsg static const struct si_dte_data dte_data_cape_verde =
11201bb76ff1Sjsg {
11211bb76ff1Sjsg 	{ 0, 0, 0, 0, 0 },
11221bb76ff1Sjsg 	{ 0, 0, 0, 0, 0 },
11231bb76ff1Sjsg 	0,
11241bb76ff1Sjsg 	0,
11251bb76ff1Sjsg 	0,
11261bb76ff1Sjsg 	0,
11271bb76ff1Sjsg 	0,
11281bb76ff1Sjsg 	0,
11291bb76ff1Sjsg 	0,
11301bb76ff1Sjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
11311bb76ff1Sjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
11321bb76ff1Sjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
11331bb76ff1Sjsg 	0,
11341bb76ff1Sjsg 	false
11351bb76ff1Sjsg };
11361bb76ff1Sjsg 
11371bb76ff1Sjsg static const struct si_dte_data dte_data_venus_xtx =
11381bb76ff1Sjsg {
11391bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
11401bb76ff1Sjsg 	{ 0x71C, 0xAAB, 0xE39, 0x11C7, 0x0 },
11411bb76ff1Sjsg 	5,
11421bb76ff1Sjsg 	55000,
11431bb76ff1Sjsg 	0x69,
11441bb76ff1Sjsg 	0xA,
11451bb76ff1Sjsg 	1,
11461bb76ff1Sjsg 	0,
11471bb76ff1Sjsg 	0x3,
11481bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
11491bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
11501bb76ff1Sjsg 	{ 0xD6D8, 0x88B8, 0x1555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
11511bb76ff1Sjsg 	90,
11521bb76ff1Sjsg 	true
11531bb76ff1Sjsg };
11541bb76ff1Sjsg 
11551bb76ff1Sjsg static const struct si_dte_data dte_data_venus_xt =
11561bb76ff1Sjsg {
11571bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
11581bb76ff1Sjsg 	{ 0xBDA, 0x11C7, 0x17B4, 0x1DA1, 0x0 },
11591bb76ff1Sjsg 	5,
11601bb76ff1Sjsg 	55000,
11611bb76ff1Sjsg 	0x69,
11621bb76ff1Sjsg 	0xA,
11631bb76ff1Sjsg 	1,
11641bb76ff1Sjsg 	0,
11651bb76ff1Sjsg 	0x3,
11661bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
11671bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
11681bb76ff1Sjsg 	{ 0xAFC8, 0x88B8, 0x238E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
11691bb76ff1Sjsg 	90,
11701bb76ff1Sjsg 	true
11711bb76ff1Sjsg };
11721bb76ff1Sjsg 
11731bb76ff1Sjsg static const struct si_dte_data dte_data_venus_pro =
11741bb76ff1Sjsg {
11751bb76ff1Sjsg 	{  0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
11761bb76ff1Sjsg 	{ 0x11C7, 0x1AAB, 0x238E, 0x2C72, 0x0 },
11771bb76ff1Sjsg 	5,
11781bb76ff1Sjsg 	55000,
11791bb76ff1Sjsg 	0x69,
11801bb76ff1Sjsg 	0xA,
11811bb76ff1Sjsg 	1,
11821bb76ff1Sjsg 	0,
11831bb76ff1Sjsg 	0x3,
11841bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
11851bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
11861bb76ff1Sjsg 	{ 0x88B8, 0x88B8, 0x3555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
11871bb76ff1Sjsg 	90,
11881bb76ff1Sjsg 	true
11891bb76ff1Sjsg };
11901bb76ff1Sjsg 
11911bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_oland[] =
11921bb76ff1Sjsg {
11931bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
11941bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
11951bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
11961bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
11971bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11981bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
11991bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
12001bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
12011bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
12021bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
12031bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
12041bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
12051bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
12061bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
12071bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
12081bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
12091bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
12101bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
12111bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
12121bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
12131bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
12141bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
12151bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
12161bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
12171bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
12181bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
12191bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
12201bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
12211bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
12221bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
12231bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
12241bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
12251bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
12261bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
12271bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
12281bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x3BA, SISLANDS_CACCONFIG_CGIND },
12291bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12301bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
12311bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12321bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
12331bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
12341bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12351bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12361bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
12371bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12381bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
12391bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12401bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
12411bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12421bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
12431bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12441bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
12451bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12461bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
12471bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12481bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
12491bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12501bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
12511bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12521bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
12531bb76ff1Sjsg 	{ 0xFFFFFFFF }
12541bb76ff1Sjsg };
12551bb76ff1Sjsg 
12561bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_mars_pro[] =
12571bb76ff1Sjsg {
12581bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
12591bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
12601bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
12611bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
12621bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12631bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
12641bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
12651bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
12661bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
12671bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
12681bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
12691bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
12701bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
12711bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
12721bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
12731bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
12741bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
12751bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
12761bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
12771bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
12781bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
12791bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
12801bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
12811bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
12821bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
12831bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
12841bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
12851bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
12861bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
12871bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
12881bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
12891bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
12901bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
12911bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
12921bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
12931bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x2, SISLANDS_CACCONFIG_CGIND },
12941bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12951bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
12961bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12971bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
12981bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
12991bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13001bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13011bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13021bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13031bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13041bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
13051bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
13061bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13071bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13081bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
13091bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
13101bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13111bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13121bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
13131bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
13141bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
13151bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
13161bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
13171bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
13181bb76ff1Sjsg 	{ 0xFFFFFFFF }
13191bb76ff1Sjsg };
13201bb76ff1Sjsg 
13211bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_mars_xt[] =
13221bb76ff1Sjsg {
13231bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
13241bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
13251bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
13261bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
13271bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13281bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
13291bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
13301bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
13311bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
13321bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
13331bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
13341bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
13351bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
13361bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
13371bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
13381bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
13391bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
13401bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
13411bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
13421bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
13431bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
13441bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
13451bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
13461bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
13471bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
13481bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
13491bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
13501bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
13511bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
13521bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
13531bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
13541bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
13551bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
13561bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
13571bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
13581bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x60, SISLANDS_CACCONFIG_CGIND },
13591bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13601bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
13611bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13621bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
13631bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
13641bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13651bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13661bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13671bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13681bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13691bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
13701bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
13711bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13721bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13731bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
13741bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
13751bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13761bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13771bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
13781bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
13791bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
13801bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
13811bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
13821bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
13831bb76ff1Sjsg 	{ 0xFFFFFFFF }
13841bb76ff1Sjsg };
13851bb76ff1Sjsg 
13861bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_oland_pro[] =
13871bb76ff1Sjsg {
13881bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
13891bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
13901bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
13911bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
13921bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13931bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
13941bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
13951bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
13961bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
13971bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
13981bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
13991bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
14001bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
14011bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
14021bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
14031bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
14041bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
14051bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
14061bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
14071bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
14081bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
14091bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
14101bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
14111bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
14121bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
14131bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
14141bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
14151bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
14161bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14171bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
14181bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
14191bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
14201bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
14211bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
14221bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
14231bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x90, SISLANDS_CACCONFIG_CGIND },
14241bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14251bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
14261bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14271bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
14281bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
14291bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14301bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14311bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
14321bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14331bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
14341bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
14351bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
14361bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14371bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
14381bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
14391bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
14401bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14411bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
14421bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
14431bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
14441bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
14451bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
14461bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
14471bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
14481bb76ff1Sjsg 	{ 0xFFFFFFFF }
14491bb76ff1Sjsg };
14501bb76ff1Sjsg 
14511bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_oland_xt[] =
14521bb76ff1Sjsg {
14531bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
14541bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
14551bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
14561bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
14571bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14581bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
14591bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
14601bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
14611bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
14621bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
14631bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
14641bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
14651bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
14661bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
14671bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
14681bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
14691bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
14701bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
14711bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
14721bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
14731bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
14741bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
14751bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
14761bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
14771bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
14781bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
14791bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
14801bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
14811bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14821bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
14831bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
14841bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
14851bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
14861bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
14871bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
14881bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x120, SISLANDS_CACCONFIG_CGIND },
14891bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14901bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
14911bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14921bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
14931bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
14941bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14951bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14961bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
14971bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14981bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
14991bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
15001bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
15011bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
15021bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
15031bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
15041bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
15051bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
15061bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
15071bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
15081bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
15091bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
15101bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
15111bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
15121bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
15131bb76ff1Sjsg 	{ 0xFFFFFFFF }
15141bb76ff1Sjsg };
15151bb76ff1Sjsg 
15161bb76ff1Sjsg static const struct si_cac_config_reg lcac_oland[] =
15171bb76ff1Sjsg {
15181bb76ff1Sjsg 	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15191bb76ff1Sjsg 	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15201bb76ff1Sjsg 	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15211bb76ff1Sjsg 	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15221bb76ff1Sjsg 	{ 0x110, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
15231bb76ff1Sjsg 	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15241bb76ff1Sjsg 	{ 0x14f, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
15251bb76ff1Sjsg 	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15261bb76ff1Sjsg 	{ 0x8c, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
15271bb76ff1Sjsg 	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15281bb76ff1Sjsg 	{ 0x143, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
15291bb76ff1Sjsg 	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15301bb76ff1Sjsg 	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15311bb76ff1Sjsg 	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15321bb76ff1Sjsg 	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15331bb76ff1Sjsg 	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15341bb76ff1Sjsg 	{ 0x164, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15351bb76ff1Sjsg 	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15361bb76ff1Sjsg 	{ 0x167, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15371bb76ff1Sjsg 	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15381bb76ff1Sjsg 	{ 0x16a, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15391bb76ff1Sjsg 	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15401bb76ff1Sjsg 	{ 0x15e, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15411bb76ff1Sjsg 	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15421bb76ff1Sjsg 	{ 0x161, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15431bb76ff1Sjsg 	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15441bb76ff1Sjsg 	{ 0x15b, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15451bb76ff1Sjsg 	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15461bb76ff1Sjsg 	{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15471bb76ff1Sjsg 	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15481bb76ff1Sjsg 	{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15491bb76ff1Sjsg 	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15501bb76ff1Sjsg 	{ 0x173, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15511bb76ff1Sjsg 	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15521bb76ff1Sjsg 	{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15531bb76ff1Sjsg 	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15541bb76ff1Sjsg 	{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15551bb76ff1Sjsg 	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15561bb76ff1Sjsg 	{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15571bb76ff1Sjsg 	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15581bb76ff1Sjsg 	{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15591bb76ff1Sjsg 	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15601bb76ff1Sjsg 	{ 0xFFFFFFFF }
15611bb76ff1Sjsg };
15621bb76ff1Sjsg 
15631bb76ff1Sjsg static const struct si_cac_config_reg lcac_mars_pro[] =
15641bb76ff1Sjsg {
15651bb76ff1Sjsg 	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15661bb76ff1Sjsg 	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15671bb76ff1Sjsg 	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15681bb76ff1Sjsg 	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15691bb76ff1Sjsg 	{ 0x110, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
15701bb76ff1Sjsg 	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15711bb76ff1Sjsg 	{ 0x14f, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
15721bb76ff1Sjsg 	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15731bb76ff1Sjsg 	{ 0x8c, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
15741bb76ff1Sjsg 	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15751bb76ff1Sjsg 	{ 0x143, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15761bb76ff1Sjsg 	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15771bb76ff1Sjsg 	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15781bb76ff1Sjsg 	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15791bb76ff1Sjsg 	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15801bb76ff1Sjsg 	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15811bb76ff1Sjsg 	{ 0x164, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15821bb76ff1Sjsg 	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15831bb76ff1Sjsg 	{ 0x167, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15841bb76ff1Sjsg 	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15851bb76ff1Sjsg 	{ 0x16a, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15861bb76ff1Sjsg 	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15871bb76ff1Sjsg 	{ 0x15e, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15881bb76ff1Sjsg 	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15891bb76ff1Sjsg 	{ 0x161, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15901bb76ff1Sjsg 	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15911bb76ff1Sjsg 	{ 0x15b, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15921bb76ff1Sjsg 	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15931bb76ff1Sjsg 	{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
15941bb76ff1Sjsg 	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15951bb76ff1Sjsg 	{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15961bb76ff1Sjsg 	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15971bb76ff1Sjsg 	{ 0x173, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15981bb76ff1Sjsg 	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15991bb76ff1Sjsg 	{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
16001bb76ff1Sjsg 	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
16011bb76ff1Sjsg 	{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
16021bb76ff1Sjsg 	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
16031bb76ff1Sjsg 	{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
16041bb76ff1Sjsg 	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
16051bb76ff1Sjsg 	{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
16061bb76ff1Sjsg 	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
16071bb76ff1Sjsg 	{ 0xFFFFFFFF }
16081bb76ff1Sjsg };
16091bb76ff1Sjsg 
16101bb76ff1Sjsg static const struct si_cac_config_reg cac_override_oland[] =
16111bb76ff1Sjsg {
16121bb76ff1Sjsg 	{ 0xFFFFFFFF }
16131bb76ff1Sjsg };
16141bb76ff1Sjsg 
16151bb76ff1Sjsg static const struct si_powertune_data powertune_data_oland =
16161bb76ff1Sjsg {
16171bb76ff1Sjsg 	((1 << 16) | 0x6993),
16181bb76ff1Sjsg 	5,
16191bb76ff1Sjsg 	0,
16201bb76ff1Sjsg 	7,
16211bb76ff1Sjsg 	105,
16221bb76ff1Sjsg 	{
16231bb76ff1Sjsg 		0UL,
16241bb76ff1Sjsg 		0UL,
16251bb76ff1Sjsg 		7194395UL,
16261bb76ff1Sjsg 		309631529UL,
16271bb76ff1Sjsg 		-1270850L,
16281bb76ff1Sjsg 		4513710L,
16291bb76ff1Sjsg 		100
16301bb76ff1Sjsg 	},
16311bb76ff1Sjsg 	117830498UL,
16321bb76ff1Sjsg 	12,
16331bb76ff1Sjsg 	{
16341bb76ff1Sjsg 		0,
16351bb76ff1Sjsg 		0,
16361bb76ff1Sjsg 		0,
16371bb76ff1Sjsg 		0,
16381bb76ff1Sjsg 		0,
16391bb76ff1Sjsg 		0,
16401bb76ff1Sjsg 		0,
16411bb76ff1Sjsg 		0
16421bb76ff1Sjsg 	},
16431bb76ff1Sjsg 	true
16441bb76ff1Sjsg };
16451bb76ff1Sjsg 
16461bb76ff1Sjsg static const struct si_powertune_data powertune_data_mars_pro =
16471bb76ff1Sjsg {
16481bb76ff1Sjsg 	((1 << 16) | 0x6993),
16491bb76ff1Sjsg 	5,
16501bb76ff1Sjsg 	0,
16511bb76ff1Sjsg 	7,
16521bb76ff1Sjsg 	105,
16531bb76ff1Sjsg 	{
16541bb76ff1Sjsg 		0UL,
16551bb76ff1Sjsg 		0UL,
16561bb76ff1Sjsg 		7194395UL,
16571bb76ff1Sjsg 		309631529UL,
16581bb76ff1Sjsg 		-1270850L,
16591bb76ff1Sjsg 		4513710L,
16601bb76ff1Sjsg 		100
16611bb76ff1Sjsg 	},
16621bb76ff1Sjsg 	117830498UL,
16631bb76ff1Sjsg 	12,
16641bb76ff1Sjsg 	{
16651bb76ff1Sjsg 		0,
16661bb76ff1Sjsg 		0,
16671bb76ff1Sjsg 		0,
16681bb76ff1Sjsg 		0,
16691bb76ff1Sjsg 		0,
16701bb76ff1Sjsg 		0,
16711bb76ff1Sjsg 		0,
16721bb76ff1Sjsg 		0
16731bb76ff1Sjsg 	},
16741bb76ff1Sjsg 	true
16751bb76ff1Sjsg };
16761bb76ff1Sjsg 
16771bb76ff1Sjsg static const struct si_dte_data dte_data_oland =
16781bb76ff1Sjsg {
16791bb76ff1Sjsg 	{ 0, 0, 0, 0, 0 },
16801bb76ff1Sjsg 	{ 0, 0, 0, 0, 0 },
16811bb76ff1Sjsg 	0,
16821bb76ff1Sjsg 	0,
16831bb76ff1Sjsg 	0,
16841bb76ff1Sjsg 	0,
16851bb76ff1Sjsg 	0,
16861bb76ff1Sjsg 	0,
16871bb76ff1Sjsg 	0,
16881bb76ff1Sjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
16891bb76ff1Sjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
16901bb76ff1Sjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
16911bb76ff1Sjsg 	0,
16921bb76ff1Sjsg 	false
16931bb76ff1Sjsg };
16941bb76ff1Sjsg 
16951bb76ff1Sjsg static const struct si_dte_data dte_data_mars_pro =
16961bb76ff1Sjsg {
16971bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
16981bb76ff1Sjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
16991bb76ff1Sjsg 	5,
17001bb76ff1Sjsg 	55000,
17011bb76ff1Sjsg 	105,
17021bb76ff1Sjsg 	0xA,
17031bb76ff1Sjsg 	1,
17041bb76ff1Sjsg 	0,
17051bb76ff1Sjsg 	0x10,
17061bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
17071bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
17081bb76ff1Sjsg 	{ 0xF627, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
17091bb76ff1Sjsg 	90,
17101bb76ff1Sjsg 	true
17111bb76ff1Sjsg };
17121bb76ff1Sjsg 
17131bb76ff1Sjsg static const struct si_dte_data dte_data_sun_xt =
17141bb76ff1Sjsg {
17151bb76ff1Sjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
17161bb76ff1Sjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
17171bb76ff1Sjsg 	5,
17181bb76ff1Sjsg 	55000,
17191bb76ff1Sjsg 	105,
17201bb76ff1Sjsg 	0xA,
17211bb76ff1Sjsg 	1,
17221bb76ff1Sjsg 	0,
17231bb76ff1Sjsg 	0x10,
17241bb76ff1Sjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
17251bb76ff1Sjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
17261bb76ff1Sjsg 	{ 0xD555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
17271bb76ff1Sjsg 	90,
17281bb76ff1Sjsg 	true
17291bb76ff1Sjsg };
17301bb76ff1Sjsg 
17311bb76ff1Sjsg 
17321bb76ff1Sjsg static const struct si_cac_config_reg cac_weights_hainan[] =
17331bb76ff1Sjsg {
17341bb76ff1Sjsg 	{ 0x0, 0x0000ffff, 0, 0x2d9, SISLANDS_CACCONFIG_CGIND },
17351bb76ff1Sjsg 	{ 0x0, 0xffff0000, 16, 0x22b, SISLANDS_CACCONFIG_CGIND },
17361bb76ff1Sjsg 	{ 0x1, 0x0000ffff, 0, 0x21c, SISLANDS_CACCONFIG_CGIND },
17371bb76ff1Sjsg 	{ 0x1, 0xffff0000, 16, 0x1dc, SISLANDS_CACCONFIG_CGIND },
17381bb76ff1Sjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
17391bb76ff1Sjsg 	{ 0x3, 0x0000ffff, 0, 0x24e, SISLANDS_CACCONFIG_CGIND },
17401bb76ff1Sjsg 	{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17411bb76ff1Sjsg 	{ 0x4, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
17421bb76ff1Sjsg 	{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17431bb76ff1Sjsg 	{ 0x5, 0x0000ffff, 0, 0x35e, SISLANDS_CACCONFIG_CGIND },
17441bb76ff1Sjsg 	{ 0x5, 0xffff0000, 16, 0x1143, SISLANDS_CACCONFIG_CGIND },
17451bb76ff1Sjsg 	{ 0x6, 0x0000ffff, 0, 0xe17, SISLANDS_CACCONFIG_CGIND },
17461bb76ff1Sjsg 	{ 0x6, 0xffff0000, 16, 0x441, SISLANDS_CACCONFIG_CGIND },
17471bb76ff1Sjsg 	{ 0x18f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
17481bb76ff1Sjsg 	{ 0x7, 0x0000ffff, 0, 0x28b, SISLANDS_CACCONFIG_CGIND },
17491bb76ff1Sjsg 	{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17501bb76ff1Sjsg 	{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
17511bb76ff1Sjsg 	{ 0x8, 0xffff0000, 16, 0xabe, SISLANDS_CACCONFIG_CGIND },
17521bb76ff1Sjsg 	{ 0x9, 0x0000ffff, 0, 0xf11, SISLANDS_CACCONFIG_CGIND },
17531bb76ff1Sjsg 	{ 0xa, 0x0000ffff, 0, 0x907, SISLANDS_CACCONFIG_CGIND },
17541bb76ff1Sjsg 	{ 0xb, 0x0000ffff, 0, 0xb45, SISLANDS_CACCONFIG_CGIND },
17551bb76ff1Sjsg 	{ 0xb, 0xffff0000, 16, 0xd1e, SISLANDS_CACCONFIG_CGIND },
17561bb76ff1Sjsg 	{ 0xc, 0x0000ffff, 0, 0xa2c, SISLANDS_CACCONFIG_CGIND },
17571bb76ff1Sjsg 	{ 0xd, 0x0000ffff, 0, 0x62, SISLANDS_CACCONFIG_CGIND },
17581bb76ff1Sjsg 	{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17591bb76ff1Sjsg 	{ 0xe, 0x0000ffff, 0, 0x1f3, SISLANDS_CACCONFIG_CGIND },
17601bb76ff1Sjsg 	{ 0xf, 0x0000ffff, 0, 0x42, SISLANDS_CACCONFIG_CGIND },
17611bb76ff1Sjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17621bb76ff1Sjsg 	{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
17631bb76ff1Sjsg 	{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17641bb76ff1Sjsg 	{ 0x11, 0x0000ffff, 0, 0x709, SISLANDS_CACCONFIG_CGIND },
17651bb76ff1Sjsg 	{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17661bb76ff1Sjsg 	{ 0x12, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
17671bb76ff1Sjsg 	{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
17681bb76ff1Sjsg 	{ 0x13, 0xffff0000, 16, 0x3a, SISLANDS_CACCONFIG_CGIND },
17691bb76ff1Sjsg 	{ 0x14, 0x0000ffff, 0, 0x357, SISLANDS_CACCONFIG_CGIND },
17701bb76ff1Sjsg 	{ 0x15, 0x0000ffff, 0, 0x9f, SISLANDS_CACCONFIG_CGIND },
17711bb76ff1Sjsg 	{ 0x15, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17721bb76ff1Sjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
17731bb76ff1Sjsg 	{ 0x16, 0x0000ffff, 0, 0x314, SISLANDS_CACCONFIG_CGIND },
17741bb76ff1Sjsg 	{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17751bb76ff1Sjsg 	{ 0x17, 0x0000ffff, 0, 0x6d, SISLANDS_CACCONFIG_CGIND },
17761bb76ff1Sjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
17771bb76ff1Sjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17781bb76ff1Sjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
17791bb76ff1Sjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
17801bb76ff1Sjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
17811bb76ff1Sjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
17821bb76ff1Sjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
17831bb76ff1Sjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
17841bb76ff1Sjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
17851bb76ff1Sjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
17861bb76ff1Sjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
17871bb76ff1Sjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
17881bb76ff1Sjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
17891bb76ff1Sjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
17901bb76ff1Sjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
17911bb76ff1Sjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
17921bb76ff1Sjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
17931bb76ff1Sjsg 	{ 0x6d, 0x0000ffff, 0, 0x1b9, SISLANDS_CACCONFIG_CGIND },
17941bb76ff1Sjsg 	{ 0xFFFFFFFF }
17951bb76ff1Sjsg };
17961bb76ff1Sjsg 
17971bb76ff1Sjsg static const struct si_powertune_data powertune_data_hainan =
17981bb76ff1Sjsg {
17991bb76ff1Sjsg 	((1 << 16) | 0x6993),
18001bb76ff1Sjsg 	5,
18011bb76ff1Sjsg 	0,
18021bb76ff1Sjsg 	9,
18031bb76ff1Sjsg 	105,
18041bb76ff1Sjsg 	{
18051bb76ff1Sjsg 		0UL,
18061bb76ff1Sjsg 		0UL,
18071bb76ff1Sjsg 		7194395UL,
18081bb76ff1Sjsg 		309631529UL,
18091bb76ff1Sjsg 		-1270850L,
18101bb76ff1Sjsg 		4513710L,
18111bb76ff1Sjsg 		100
18121bb76ff1Sjsg 	},
18131bb76ff1Sjsg 	117830498UL,
18141bb76ff1Sjsg 	12,
18151bb76ff1Sjsg 	{
18161bb76ff1Sjsg 		0,
18171bb76ff1Sjsg 		0,
18181bb76ff1Sjsg 		0,
18191bb76ff1Sjsg 		0,
18201bb76ff1Sjsg 		0,
18211bb76ff1Sjsg 		0,
18221bb76ff1Sjsg 		0,
18231bb76ff1Sjsg 		0
18241bb76ff1Sjsg 	},
18251bb76ff1Sjsg 	true
18261bb76ff1Sjsg };
18271bb76ff1Sjsg 
18281bb76ff1Sjsg static struct rv7xx_power_info *rv770_get_pi(struct amdgpu_device *adev);
18291bb76ff1Sjsg static struct evergreen_power_info *evergreen_get_pi(struct amdgpu_device *adev);
18301bb76ff1Sjsg static struct ni_power_info *ni_get_pi(struct amdgpu_device *adev);
18311bb76ff1Sjsg static struct  si_ps *si_get_ps(struct amdgpu_ps *rps);
18321bb76ff1Sjsg 
18331bb76ff1Sjsg static int si_populate_voltage_value(struct amdgpu_device *adev,
18341bb76ff1Sjsg 				     const struct atom_voltage_table *table,
18351bb76ff1Sjsg 				     u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage);
18361bb76ff1Sjsg static int si_get_std_voltage_value(struct amdgpu_device *adev,
18371bb76ff1Sjsg 				    SISLANDS_SMC_VOLTAGE_VALUE *voltage,
18381bb76ff1Sjsg 				    u16 *std_voltage);
18391bb76ff1Sjsg static int si_write_smc_soft_register(struct amdgpu_device *adev,
18401bb76ff1Sjsg 				      u16 reg_offset, u32 value);
18411bb76ff1Sjsg static int si_convert_power_level_to_smc(struct amdgpu_device *adev,
18421bb76ff1Sjsg 					 struct rv7xx_pl *pl,
18431bb76ff1Sjsg 					 SISLANDS_SMC_HW_PERFORMANCE_LEVEL *level);
18441bb76ff1Sjsg static int si_calculate_sclk_params(struct amdgpu_device *adev,
18451bb76ff1Sjsg 				    u32 engine_clock,
18461bb76ff1Sjsg 				    SISLANDS_SMC_SCLK_VALUE *sclk);
18471bb76ff1Sjsg 
18481bb76ff1Sjsg static void si_thermal_start_smc_fan_control(struct amdgpu_device *adev);
18491bb76ff1Sjsg static void si_fan_ctrl_set_default_mode(struct amdgpu_device *adev);
18501bb76ff1Sjsg static void si_dpm_set_irq_funcs(struct amdgpu_device *adev);
18511bb76ff1Sjsg 
si_get_pi(struct amdgpu_device * adev)18521bb76ff1Sjsg static struct si_power_info *si_get_pi(struct amdgpu_device *adev)
18531bb76ff1Sjsg {
18541bb76ff1Sjsg 	struct si_power_info *pi = adev->pm.dpm.priv;
18551bb76ff1Sjsg 	return pi;
18561bb76ff1Sjsg }
18571bb76ff1Sjsg 
si_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coeffients * coeff,u16 v,s32 t,u32 ileakage,u32 * leakage)18581bb76ff1Sjsg static void si_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coeffients *coeff,
18591bb76ff1Sjsg 						     u16 v, s32 t, u32 ileakage, u32 *leakage)
18601bb76ff1Sjsg {
18611bb76ff1Sjsg 	s64 kt, kv, leakage_w, i_leakage, vddc;
18621bb76ff1Sjsg 	s64 temperature, t_slope, t_intercept, av, bv, t_ref;
18631bb76ff1Sjsg 	s64 tmp;
18641bb76ff1Sjsg 
18651bb76ff1Sjsg 	i_leakage = div64_s64(drm_int2fixp(ileakage), 100);
18661bb76ff1Sjsg 	vddc = div64_s64(drm_int2fixp(v), 1000);
18671bb76ff1Sjsg 	temperature = div64_s64(drm_int2fixp(t), 1000);
18681bb76ff1Sjsg 
18691bb76ff1Sjsg 	t_slope = div64_s64(drm_int2fixp(coeff->t_slope), 100000000);
18701bb76ff1Sjsg 	t_intercept = div64_s64(drm_int2fixp(coeff->t_intercept), 100000000);
18711bb76ff1Sjsg 	av = div64_s64(drm_int2fixp(coeff->av), 100000000);
18721bb76ff1Sjsg 	bv = div64_s64(drm_int2fixp(coeff->bv), 100000000);
18731bb76ff1Sjsg 	t_ref = drm_int2fixp(coeff->t_ref);
18741bb76ff1Sjsg 
18751bb76ff1Sjsg 	tmp = drm_fixp_mul(t_slope, vddc) + t_intercept;
18761bb76ff1Sjsg 	kt = drm_fixp_exp(drm_fixp_mul(tmp, temperature));
18771bb76ff1Sjsg 	kt = drm_fixp_div(kt, drm_fixp_exp(drm_fixp_mul(tmp, t_ref)));
18781bb76ff1Sjsg 	kv = drm_fixp_mul(av, drm_fixp_exp(drm_fixp_mul(bv, vddc)));
18791bb76ff1Sjsg 
18801bb76ff1Sjsg 	leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc);
18811bb76ff1Sjsg 
18821bb76ff1Sjsg 	*leakage = drm_fixp2int(leakage_w * 1000);
18831bb76ff1Sjsg }
18841bb76ff1Sjsg 
si_calculate_leakage_for_v_and_t(struct amdgpu_device * adev,const struct ni_leakage_coeffients * coeff,u16 v,s32 t,u32 i_leakage,u32 * leakage)18851bb76ff1Sjsg static void si_calculate_leakage_for_v_and_t(struct amdgpu_device *adev,
18861bb76ff1Sjsg 					     const struct ni_leakage_coeffients *coeff,
18871bb76ff1Sjsg 					     u16 v,
18881bb76ff1Sjsg 					     s32 t,
18891bb76ff1Sjsg 					     u32 i_leakage,
18901bb76ff1Sjsg 					     u32 *leakage)
18911bb76ff1Sjsg {
18921bb76ff1Sjsg 	si_calculate_leakage_for_v_and_t_formula(coeff, v, t, i_leakage, leakage);
18931bb76ff1Sjsg }
18941bb76ff1Sjsg 
si_calculate_leakage_for_v_formula(const struct ni_leakage_coeffients * coeff,const u32 fixed_kt,u16 v,u32 ileakage,u32 * leakage)18951bb76ff1Sjsg static void si_calculate_leakage_for_v_formula(const struct ni_leakage_coeffients *coeff,
18961bb76ff1Sjsg 					       const u32 fixed_kt, u16 v,
18971bb76ff1Sjsg 					       u32 ileakage, u32 *leakage)
18981bb76ff1Sjsg {
18991bb76ff1Sjsg 	s64 kt, kv, leakage_w, i_leakage, vddc;
19001bb76ff1Sjsg 
19011bb76ff1Sjsg 	i_leakage = div64_s64(drm_int2fixp(ileakage), 100);
19021bb76ff1Sjsg 	vddc = div64_s64(drm_int2fixp(v), 1000);
19031bb76ff1Sjsg 
19041bb76ff1Sjsg 	kt = div64_s64(drm_int2fixp(fixed_kt), 100000000);
19051bb76ff1Sjsg 	kv = drm_fixp_mul(div64_s64(drm_int2fixp(coeff->av), 100000000),
19061bb76ff1Sjsg 			  drm_fixp_exp(drm_fixp_mul(div64_s64(drm_int2fixp(coeff->bv), 100000000), vddc)));
19071bb76ff1Sjsg 
19081bb76ff1Sjsg 	leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc);
19091bb76ff1Sjsg 
19101bb76ff1Sjsg 	*leakage = drm_fixp2int(leakage_w * 1000);
19111bb76ff1Sjsg }
19121bb76ff1Sjsg 
si_calculate_leakage_for_v(struct amdgpu_device * adev,const struct ni_leakage_coeffients * coeff,const u32 fixed_kt,u16 v,u32 i_leakage,u32 * leakage)19131bb76ff1Sjsg static void si_calculate_leakage_for_v(struct amdgpu_device *adev,
19141bb76ff1Sjsg 				       const struct ni_leakage_coeffients *coeff,
19151bb76ff1Sjsg 				       const u32 fixed_kt,
19161bb76ff1Sjsg 				       u16 v,
19171bb76ff1Sjsg 				       u32 i_leakage,
19181bb76ff1Sjsg 				       u32 *leakage)
19191bb76ff1Sjsg {
19201bb76ff1Sjsg 	si_calculate_leakage_for_v_formula(coeff, fixed_kt, v, i_leakage, leakage);
19211bb76ff1Sjsg }
19221bb76ff1Sjsg 
19231bb76ff1Sjsg 
si_update_dte_from_pl2(struct amdgpu_device * adev,struct si_dte_data * dte_data)19241bb76ff1Sjsg static void si_update_dte_from_pl2(struct amdgpu_device *adev,
19251bb76ff1Sjsg 				   struct si_dte_data *dte_data)
19261bb76ff1Sjsg {
19271bb76ff1Sjsg 	u32 p_limit1 = adev->pm.dpm.tdp_limit;
19281bb76ff1Sjsg 	u32 p_limit2 = adev->pm.dpm.near_tdp_limit;
19291bb76ff1Sjsg 	u32 k = dte_data->k;
19301bb76ff1Sjsg 	u32 t_max = dte_data->max_t;
19311bb76ff1Sjsg 	u32 t_split[5] = { 10, 15, 20, 25, 30 };
19321bb76ff1Sjsg 	u32 t_0 = dte_data->t0;
19331bb76ff1Sjsg 	u32 i;
19341bb76ff1Sjsg 
19351bb76ff1Sjsg 	if (p_limit2 != 0 && p_limit2 <= p_limit1) {
19361bb76ff1Sjsg 		dte_data->tdep_count = 3;
19371bb76ff1Sjsg 
19381bb76ff1Sjsg 		for (i = 0; i < k; i++) {
19391bb76ff1Sjsg 			dte_data->r[i] =
19401bb76ff1Sjsg 				(t_split[i] * (t_max - t_0/(u32)1000) * (1 << 14)) /
19411bb76ff1Sjsg 				(p_limit2  * (u32)100);
19421bb76ff1Sjsg 		}
19431bb76ff1Sjsg 
19441bb76ff1Sjsg 		dte_data->tdep_r[1] = dte_data->r[4] * 2;
19451bb76ff1Sjsg 
19461bb76ff1Sjsg 		for (i = 2; i < SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE; i++) {
19471bb76ff1Sjsg 			dte_data->tdep_r[i] = dte_data->r[4];
19481bb76ff1Sjsg 		}
19491bb76ff1Sjsg 	} else {
19501bb76ff1Sjsg 		DRM_ERROR("Invalid PL2! DTE will not be updated.\n");
19511bb76ff1Sjsg 	}
19521bb76ff1Sjsg }
19531bb76ff1Sjsg 
rv770_get_pi(struct amdgpu_device * adev)19541bb76ff1Sjsg static struct rv7xx_power_info *rv770_get_pi(struct amdgpu_device *adev)
19551bb76ff1Sjsg {
19561bb76ff1Sjsg 	struct rv7xx_power_info *pi = adev->pm.dpm.priv;
19571bb76ff1Sjsg 
19581bb76ff1Sjsg 	return pi;
19591bb76ff1Sjsg }
19601bb76ff1Sjsg 
ni_get_pi(struct amdgpu_device * adev)19611bb76ff1Sjsg static struct ni_power_info *ni_get_pi(struct amdgpu_device *adev)
19621bb76ff1Sjsg {
19631bb76ff1Sjsg 	struct ni_power_info *pi = adev->pm.dpm.priv;
19641bb76ff1Sjsg 
19651bb76ff1Sjsg 	return pi;
19661bb76ff1Sjsg }
19671bb76ff1Sjsg 
si_get_ps(struct amdgpu_ps * aps)19681bb76ff1Sjsg static struct si_ps *si_get_ps(struct amdgpu_ps *aps)
19691bb76ff1Sjsg {
19701bb76ff1Sjsg 	struct  si_ps *ps = aps->ps_priv;
19711bb76ff1Sjsg 
19721bb76ff1Sjsg 	return ps;
19731bb76ff1Sjsg }
19741bb76ff1Sjsg 
si_initialize_powertune_defaults(struct amdgpu_device * adev)19751bb76ff1Sjsg static void si_initialize_powertune_defaults(struct amdgpu_device *adev)
19761bb76ff1Sjsg {
19771bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
19781bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
19791bb76ff1Sjsg 	bool update_dte_from_pl2 = false;
19801bb76ff1Sjsg 
19811bb76ff1Sjsg 	if (adev->asic_type == CHIP_TAHITI) {
19821bb76ff1Sjsg 		si_pi->cac_weights = cac_weights_tahiti;
19831bb76ff1Sjsg 		si_pi->lcac_config = lcac_tahiti;
19841bb76ff1Sjsg 		si_pi->cac_override = cac_override_tahiti;
19851bb76ff1Sjsg 		si_pi->powertune_data = &powertune_data_tahiti;
19861bb76ff1Sjsg 		si_pi->dte_data = dte_data_tahiti;
19871bb76ff1Sjsg 
19881bb76ff1Sjsg 		switch (adev->pdev->device) {
19891bb76ff1Sjsg 		case 0x6798:
19901bb76ff1Sjsg 			si_pi->dte_data.enable_dte_by_default = true;
19911bb76ff1Sjsg 			break;
19921bb76ff1Sjsg 		case 0x6799:
19931bb76ff1Sjsg 			si_pi->dte_data = dte_data_new_zealand;
19941bb76ff1Sjsg 			break;
19951bb76ff1Sjsg 		case 0x6790:
19961bb76ff1Sjsg 		case 0x6791:
19971bb76ff1Sjsg 		case 0x6792:
19981bb76ff1Sjsg 		case 0x679E:
19991bb76ff1Sjsg 			si_pi->dte_data = dte_data_aruba_pro;
20001bb76ff1Sjsg 			update_dte_from_pl2 = true;
20011bb76ff1Sjsg 			break;
20021bb76ff1Sjsg 		case 0x679B:
20031bb76ff1Sjsg 			si_pi->dte_data = dte_data_malta;
20041bb76ff1Sjsg 			update_dte_from_pl2 = true;
20051bb76ff1Sjsg 			break;
20061bb76ff1Sjsg 		case 0x679A:
20071bb76ff1Sjsg 			si_pi->dte_data = dte_data_tahiti_pro;
20081bb76ff1Sjsg 			update_dte_from_pl2 = true;
20091bb76ff1Sjsg 			break;
20101bb76ff1Sjsg 		default:
20111bb76ff1Sjsg 			if (si_pi->dte_data.enable_dte_by_default == true)
20121bb76ff1Sjsg 				DRM_ERROR("DTE is not enabled!\n");
20131bb76ff1Sjsg 			break;
20141bb76ff1Sjsg 		}
20151bb76ff1Sjsg 	} else if (adev->asic_type == CHIP_PITCAIRN) {
20161bb76ff1Sjsg 		si_pi->cac_weights = cac_weights_pitcairn;
20171bb76ff1Sjsg 		si_pi->lcac_config = lcac_pitcairn;
20181bb76ff1Sjsg 		si_pi->cac_override = cac_override_pitcairn;
20191bb76ff1Sjsg 		si_pi->powertune_data = &powertune_data_pitcairn;
20201bb76ff1Sjsg 
20211bb76ff1Sjsg 		switch (adev->pdev->device) {
20221bb76ff1Sjsg 		case 0x6810:
20231bb76ff1Sjsg 		case 0x6818:
20241bb76ff1Sjsg 			si_pi->dte_data = dte_data_curacao_xt;
20251bb76ff1Sjsg 			update_dte_from_pl2 = true;
20261bb76ff1Sjsg 			break;
20271bb76ff1Sjsg 		case 0x6819:
20281bb76ff1Sjsg 		case 0x6811:
20291bb76ff1Sjsg 			si_pi->dte_data = dte_data_curacao_pro;
20301bb76ff1Sjsg 			update_dte_from_pl2 = true;
20311bb76ff1Sjsg 			break;
20321bb76ff1Sjsg 		case 0x6800:
20331bb76ff1Sjsg 		case 0x6806:
20341bb76ff1Sjsg 			si_pi->dte_data = dte_data_neptune_xt;
20351bb76ff1Sjsg 			update_dte_from_pl2 = true;
20361bb76ff1Sjsg 			break;
20371bb76ff1Sjsg 		default:
20381bb76ff1Sjsg 			si_pi->dte_data = dte_data_pitcairn;
20391bb76ff1Sjsg 			break;
20401bb76ff1Sjsg 		}
20411bb76ff1Sjsg 	} else if (adev->asic_type == CHIP_VERDE) {
20421bb76ff1Sjsg 		si_pi->lcac_config = lcac_cape_verde;
20431bb76ff1Sjsg 		si_pi->cac_override = cac_override_cape_verde;
20441bb76ff1Sjsg 		si_pi->powertune_data = &powertune_data_cape_verde;
20451bb76ff1Sjsg 
20461bb76ff1Sjsg 		switch (adev->pdev->device) {
20471bb76ff1Sjsg 		case 0x683B:
20481bb76ff1Sjsg 		case 0x683F:
20491bb76ff1Sjsg 		case 0x6829:
20501bb76ff1Sjsg 		case 0x6835:
20511bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_cape_verde_pro;
20521bb76ff1Sjsg 			si_pi->dte_data = dte_data_cape_verde;
20531bb76ff1Sjsg 			break;
20541bb76ff1Sjsg 		case 0x682C:
20551bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_cape_verde_pro;
20561bb76ff1Sjsg 			si_pi->dte_data = dte_data_sun_xt;
20571bb76ff1Sjsg 			update_dte_from_pl2 = true;
20581bb76ff1Sjsg 			break;
20591bb76ff1Sjsg 		case 0x6825:
20601bb76ff1Sjsg 		case 0x6827:
20611bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_heathrow;
20621bb76ff1Sjsg 			si_pi->dte_data = dte_data_cape_verde;
20631bb76ff1Sjsg 			break;
20641bb76ff1Sjsg 		case 0x6824:
20651bb76ff1Sjsg 		case 0x682D:
20661bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_chelsea_xt;
20671bb76ff1Sjsg 			si_pi->dte_data = dte_data_cape_verde;
20681bb76ff1Sjsg 			break;
20691bb76ff1Sjsg 		case 0x682F:
20701bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_chelsea_pro;
20711bb76ff1Sjsg 			si_pi->dte_data = dte_data_cape_verde;
20721bb76ff1Sjsg 			break;
20731bb76ff1Sjsg 		case 0x6820:
20741bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_heathrow;
20751bb76ff1Sjsg 			si_pi->dte_data = dte_data_venus_xtx;
20761bb76ff1Sjsg 			break;
20771bb76ff1Sjsg 		case 0x6821:
20781bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_heathrow;
20791bb76ff1Sjsg 			si_pi->dte_data = dte_data_venus_xt;
20801bb76ff1Sjsg 			break;
20811bb76ff1Sjsg 		case 0x6823:
20821bb76ff1Sjsg 		case 0x682B:
20831bb76ff1Sjsg 		case 0x6822:
20841bb76ff1Sjsg 		case 0x682A:
20851bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_chelsea_pro;
20861bb76ff1Sjsg 			si_pi->dte_data = dte_data_venus_pro;
20871bb76ff1Sjsg 			break;
20881bb76ff1Sjsg 		default:
20891bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_cape_verde;
20901bb76ff1Sjsg 			si_pi->dte_data = dte_data_cape_verde;
20911bb76ff1Sjsg 			break;
20921bb76ff1Sjsg 		}
20931bb76ff1Sjsg 	} else if (adev->asic_type == CHIP_OLAND) {
20941bb76ff1Sjsg 		si_pi->lcac_config = lcac_mars_pro;
20951bb76ff1Sjsg 		si_pi->cac_override = cac_override_oland;
20961bb76ff1Sjsg 		si_pi->powertune_data = &powertune_data_mars_pro;
20971bb76ff1Sjsg 		si_pi->dte_data = dte_data_mars_pro;
20981bb76ff1Sjsg 
20991bb76ff1Sjsg 		switch (adev->pdev->device) {
21001bb76ff1Sjsg 		case 0x6601:
21011bb76ff1Sjsg 		case 0x6621:
21021bb76ff1Sjsg 		case 0x6603:
21031bb76ff1Sjsg 		case 0x6605:
21041bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_mars_pro;
21051bb76ff1Sjsg 			update_dte_from_pl2 = true;
21061bb76ff1Sjsg 			break;
21071bb76ff1Sjsg 		case 0x6600:
21081bb76ff1Sjsg 		case 0x6606:
21091bb76ff1Sjsg 		case 0x6620:
21101bb76ff1Sjsg 		case 0x6604:
21111bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_mars_xt;
21121bb76ff1Sjsg 			update_dte_from_pl2 = true;
21131bb76ff1Sjsg 			break;
21141bb76ff1Sjsg 		case 0x6611:
21151bb76ff1Sjsg 		case 0x6613:
21161bb76ff1Sjsg 		case 0x6608:
21171bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_oland_pro;
21181bb76ff1Sjsg 			update_dte_from_pl2 = true;
21191bb76ff1Sjsg 			break;
21201bb76ff1Sjsg 		case 0x6610:
21211bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_oland_xt;
21221bb76ff1Sjsg 			update_dte_from_pl2 = true;
21231bb76ff1Sjsg 			break;
21241bb76ff1Sjsg 		default:
21251bb76ff1Sjsg 			si_pi->cac_weights = cac_weights_oland;
21261bb76ff1Sjsg 			si_pi->lcac_config = lcac_oland;
21271bb76ff1Sjsg 			si_pi->cac_override = cac_override_oland;
21281bb76ff1Sjsg 			si_pi->powertune_data = &powertune_data_oland;
21291bb76ff1Sjsg 			si_pi->dte_data = dte_data_oland;
21301bb76ff1Sjsg 			break;
21311bb76ff1Sjsg 		}
21321bb76ff1Sjsg 	} else if (adev->asic_type == CHIP_HAINAN) {
21331bb76ff1Sjsg 		si_pi->cac_weights = cac_weights_hainan;
21341bb76ff1Sjsg 		si_pi->lcac_config = lcac_oland;
21351bb76ff1Sjsg 		si_pi->cac_override = cac_override_oland;
21361bb76ff1Sjsg 		si_pi->powertune_data = &powertune_data_hainan;
21371bb76ff1Sjsg 		si_pi->dte_data = dte_data_sun_xt;
21381bb76ff1Sjsg 		update_dte_from_pl2 = true;
21391bb76ff1Sjsg 	} else {
21401bb76ff1Sjsg 		DRM_ERROR("Unknown SI asic revision, failed to initialize PowerTune!\n");
21411bb76ff1Sjsg 		return;
21421bb76ff1Sjsg 	}
21431bb76ff1Sjsg 
21441bb76ff1Sjsg 	ni_pi->enable_power_containment = false;
21451bb76ff1Sjsg 	ni_pi->enable_cac = false;
21461bb76ff1Sjsg 	ni_pi->enable_sq_ramping = false;
21471bb76ff1Sjsg 	si_pi->enable_dte = false;
21481bb76ff1Sjsg 
21491bb76ff1Sjsg 	if (si_pi->powertune_data->enable_powertune_by_default) {
21501bb76ff1Sjsg 		ni_pi->enable_power_containment = true;
21511bb76ff1Sjsg 		ni_pi->enable_cac = true;
21521bb76ff1Sjsg 		if (si_pi->dte_data.enable_dte_by_default) {
21531bb76ff1Sjsg 			si_pi->enable_dte = true;
21541bb76ff1Sjsg 			if (update_dte_from_pl2)
21551bb76ff1Sjsg 				si_update_dte_from_pl2(adev, &si_pi->dte_data);
21561bb76ff1Sjsg 
21571bb76ff1Sjsg 		}
21581bb76ff1Sjsg 		ni_pi->enable_sq_ramping = true;
21591bb76ff1Sjsg 	}
21601bb76ff1Sjsg 
21611bb76ff1Sjsg 	ni_pi->driver_calculate_cac_leakage = true;
21621bb76ff1Sjsg 	ni_pi->cac_configuration_required = true;
21631bb76ff1Sjsg 
21641bb76ff1Sjsg 	if (ni_pi->cac_configuration_required) {
21651bb76ff1Sjsg 		ni_pi->support_cac_long_term_average = true;
21661bb76ff1Sjsg 		si_pi->dyn_powertune_data.l2_lta_window_size =
21671bb76ff1Sjsg 			si_pi->powertune_data->l2_lta_window_size_default;
21681bb76ff1Sjsg 		si_pi->dyn_powertune_data.lts_truncate =
21691bb76ff1Sjsg 			si_pi->powertune_data->lts_truncate_default;
21701bb76ff1Sjsg 	} else {
21711bb76ff1Sjsg 		ni_pi->support_cac_long_term_average = false;
21721bb76ff1Sjsg 		si_pi->dyn_powertune_data.l2_lta_window_size = 0;
21731bb76ff1Sjsg 		si_pi->dyn_powertune_data.lts_truncate = 0;
21741bb76ff1Sjsg 	}
21751bb76ff1Sjsg 
21761bb76ff1Sjsg 	si_pi->dyn_powertune_data.disable_uvd_powertune = false;
21771bb76ff1Sjsg }
21781bb76ff1Sjsg 
si_get_smc_power_scaling_factor(struct amdgpu_device * adev)21791bb76ff1Sjsg static u32 si_get_smc_power_scaling_factor(struct amdgpu_device *adev)
21801bb76ff1Sjsg {
21811bb76ff1Sjsg 	return 1;
21821bb76ff1Sjsg }
21831bb76ff1Sjsg 
si_calculate_cac_wintime(struct amdgpu_device * adev)21841bb76ff1Sjsg static u32 si_calculate_cac_wintime(struct amdgpu_device *adev)
21851bb76ff1Sjsg {
21861bb76ff1Sjsg 	u32 xclk;
21871bb76ff1Sjsg 	u32 wintime;
21881bb76ff1Sjsg 	u32 cac_window;
21891bb76ff1Sjsg 	u32 cac_window_size;
21901bb76ff1Sjsg 
21911bb76ff1Sjsg 	xclk = amdgpu_asic_get_xclk(adev);
21921bb76ff1Sjsg 
21931bb76ff1Sjsg 	if (xclk == 0)
21941bb76ff1Sjsg 		return 0;
21951bb76ff1Sjsg 
21961bb76ff1Sjsg 	cac_window = RREG32(CG_CAC_CTRL) & CAC_WINDOW_MASK;
21971bb76ff1Sjsg 	cac_window_size = ((cac_window & 0xFFFF0000) >> 16) * (cac_window & 0x0000FFFF);
21981bb76ff1Sjsg 
21991bb76ff1Sjsg 	wintime = (cac_window_size * 100) / xclk;
22001bb76ff1Sjsg 
22011bb76ff1Sjsg 	return wintime;
22021bb76ff1Sjsg }
22031bb76ff1Sjsg 
si_scale_power_for_smc(u32 power_in_watts,u32 scaling_factor)22041bb76ff1Sjsg static u32 si_scale_power_for_smc(u32 power_in_watts, u32 scaling_factor)
22051bb76ff1Sjsg {
22061bb76ff1Sjsg 	return power_in_watts;
22071bb76ff1Sjsg }
22081bb76ff1Sjsg 
si_calculate_adjusted_tdp_limits(struct amdgpu_device * adev,bool adjust_polarity,u32 tdp_adjustment,u32 * tdp_limit,u32 * near_tdp_limit)22091bb76ff1Sjsg static int si_calculate_adjusted_tdp_limits(struct amdgpu_device *adev,
22101bb76ff1Sjsg 					    bool adjust_polarity,
22111bb76ff1Sjsg 					    u32 tdp_adjustment,
22121bb76ff1Sjsg 					    u32 *tdp_limit,
22131bb76ff1Sjsg 					    u32 *near_tdp_limit)
22141bb76ff1Sjsg {
22151bb76ff1Sjsg 	u32 adjustment_delta, max_tdp_limit;
22161bb76ff1Sjsg 
22171bb76ff1Sjsg 	if (tdp_adjustment > (u32)adev->pm.dpm.tdp_od_limit)
22181bb76ff1Sjsg 		return -EINVAL;
22191bb76ff1Sjsg 
22201bb76ff1Sjsg 	max_tdp_limit = ((100 + 100) * adev->pm.dpm.tdp_limit) / 100;
22211bb76ff1Sjsg 
22221bb76ff1Sjsg 	if (adjust_polarity) {
22231bb76ff1Sjsg 		*tdp_limit = ((100 + tdp_adjustment) * adev->pm.dpm.tdp_limit) / 100;
22241bb76ff1Sjsg 		*near_tdp_limit = adev->pm.dpm.near_tdp_limit_adjusted + (*tdp_limit - adev->pm.dpm.tdp_limit);
22251bb76ff1Sjsg 	} else {
22261bb76ff1Sjsg 		*tdp_limit = ((100 - tdp_adjustment) * adev->pm.dpm.tdp_limit) / 100;
22271bb76ff1Sjsg 		adjustment_delta  = adev->pm.dpm.tdp_limit - *tdp_limit;
22281bb76ff1Sjsg 		if (adjustment_delta < adev->pm.dpm.near_tdp_limit_adjusted)
22291bb76ff1Sjsg 			*near_tdp_limit = adev->pm.dpm.near_tdp_limit_adjusted - adjustment_delta;
22301bb76ff1Sjsg 		else
22311bb76ff1Sjsg 			*near_tdp_limit = 0;
22321bb76ff1Sjsg 	}
22331bb76ff1Sjsg 
22341bb76ff1Sjsg 	if ((*tdp_limit <= 0) || (*tdp_limit > max_tdp_limit))
22351bb76ff1Sjsg 		return -EINVAL;
22361bb76ff1Sjsg 	if ((*near_tdp_limit <= 0) || (*near_tdp_limit > *tdp_limit))
22371bb76ff1Sjsg 		return -EINVAL;
22381bb76ff1Sjsg 
22391bb76ff1Sjsg 	return 0;
22401bb76ff1Sjsg }
22411bb76ff1Sjsg 
si_populate_smc_tdp_limits(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state)22421bb76ff1Sjsg static int si_populate_smc_tdp_limits(struct amdgpu_device *adev,
22431bb76ff1Sjsg 				      struct amdgpu_ps *amdgpu_state)
22441bb76ff1Sjsg {
22451bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
22461bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
22471bb76ff1Sjsg 
22481bb76ff1Sjsg 	if (ni_pi->enable_power_containment) {
22491bb76ff1Sjsg 		SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable;
22501bb76ff1Sjsg 		PP_SIslands_PAPMParameters *papm_parm;
22511bb76ff1Sjsg 		struct amdgpu_ppm_table *ppm = adev->pm.dpm.dyn_state.ppm_table;
22521bb76ff1Sjsg 		u32 scaling_factor = si_get_smc_power_scaling_factor(adev);
22531bb76ff1Sjsg 		u32 tdp_limit;
22541bb76ff1Sjsg 		u32 near_tdp_limit;
22551bb76ff1Sjsg 		int ret;
22561bb76ff1Sjsg 
22571bb76ff1Sjsg 		if (scaling_factor == 0)
22581bb76ff1Sjsg 			return -EINVAL;
22591bb76ff1Sjsg 
22601bb76ff1Sjsg 		memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE));
22611bb76ff1Sjsg 
22621bb76ff1Sjsg 		ret = si_calculate_adjusted_tdp_limits(adev,
22631bb76ff1Sjsg 						       false, /* ??? */
22641bb76ff1Sjsg 						       adev->pm.dpm.tdp_adjustment,
22651bb76ff1Sjsg 						       &tdp_limit,
22661bb76ff1Sjsg 						       &near_tdp_limit);
22671bb76ff1Sjsg 		if (ret)
22681bb76ff1Sjsg 			return ret;
22691bb76ff1Sjsg 
22701bb76ff1Sjsg 		smc_table->dpm2Params.TDPLimit =
22711bb76ff1Sjsg 			cpu_to_be32(si_scale_power_for_smc(tdp_limit, scaling_factor) * 1000);
22721bb76ff1Sjsg 		smc_table->dpm2Params.NearTDPLimit =
22731bb76ff1Sjsg 			cpu_to_be32(si_scale_power_for_smc(near_tdp_limit, scaling_factor) * 1000);
22741bb76ff1Sjsg 		smc_table->dpm2Params.SafePowerLimit =
22751bb76ff1Sjsg 			cpu_to_be32(si_scale_power_for_smc((near_tdp_limit * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100, scaling_factor) * 1000);
22761bb76ff1Sjsg 
22771bb76ff1Sjsg 		ret = amdgpu_si_copy_bytes_to_smc(adev,
22781bb76ff1Sjsg 						  (si_pi->state_table_start + offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) +
22791bb76ff1Sjsg 						   offsetof(PP_SIslands_DPM2Parameters, TDPLimit)),
22801bb76ff1Sjsg 						  (u8 *)(&(smc_table->dpm2Params.TDPLimit)),
22811bb76ff1Sjsg 						  sizeof(u32) * 3,
22821bb76ff1Sjsg 						  si_pi->sram_end);
22831bb76ff1Sjsg 		if (ret)
22841bb76ff1Sjsg 			return ret;
22851bb76ff1Sjsg 
22861bb76ff1Sjsg 		if (si_pi->enable_ppm) {
22871bb76ff1Sjsg 			papm_parm = &si_pi->papm_parm;
22881bb76ff1Sjsg 			memset(papm_parm, 0, sizeof(PP_SIslands_PAPMParameters));
22891bb76ff1Sjsg 			papm_parm->NearTDPLimitTherm = cpu_to_be32(ppm->dgpu_tdp);
22901bb76ff1Sjsg 			papm_parm->dGPU_T_Limit = cpu_to_be32(ppm->tj_max);
22911bb76ff1Sjsg 			papm_parm->dGPU_T_Warning = cpu_to_be32(95);
22921bb76ff1Sjsg 			papm_parm->dGPU_T_Hysteresis = cpu_to_be32(5);
22931bb76ff1Sjsg 			papm_parm->PlatformPowerLimit = 0xffffffff;
22941bb76ff1Sjsg 			papm_parm->NearTDPLimitPAPM = 0xffffffff;
22951bb76ff1Sjsg 
22961bb76ff1Sjsg 			ret = amdgpu_si_copy_bytes_to_smc(adev, si_pi->papm_cfg_table_start,
22971bb76ff1Sjsg 							  (u8 *)papm_parm,
22981bb76ff1Sjsg 							  sizeof(PP_SIslands_PAPMParameters),
22991bb76ff1Sjsg 							  si_pi->sram_end);
23001bb76ff1Sjsg 			if (ret)
23011bb76ff1Sjsg 				return ret;
23021bb76ff1Sjsg 		}
23031bb76ff1Sjsg 	}
23041bb76ff1Sjsg 	return 0;
23051bb76ff1Sjsg }
23061bb76ff1Sjsg 
si_populate_smc_tdp_limits_2(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state)23071bb76ff1Sjsg static int si_populate_smc_tdp_limits_2(struct amdgpu_device *adev,
23081bb76ff1Sjsg 					struct amdgpu_ps *amdgpu_state)
23091bb76ff1Sjsg {
23101bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
23111bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
23121bb76ff1Sjsg 
23131bb76ff1Sjsg 	if (ni_pi->enable_power_containment) {
23141bb76ff1Sjsg 		SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable;
23151bb76ff1Sjsg 		u32 scaling_factor = si_get_smc_power_scaling_factor(adev);
23161bb76ff1Sjsg 		int ret;
23171bb76ff1Sjsg 
23181bb76ff1Sjsg 		memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE));
23191bb76ff1Sjsg 
23201bb76ff1Sjsg 		smc_table->dpm2Params.NearTDPLimit =
23211bb76ff1Sjsg 			cpu_to_be32(si_scale_power_for_smc(adev->pm.dpm.near_tdp_limit_adjusted, scaling_factor) * 1000);
23221bb76ff1Sjsg 		smc_table->dpm2Params.SafePowerLimit =
23231bb76ff1Sjsg 			cpu_to_be32(si_scale_power_for_smc((adev->pm.dpm.near_tdp_limit_adjusted * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100, scaling_factor) * 1000);
23241bb76ff1Sjsg 
23251bb76ff1Sjsg 		ret = amdgpu_si_copy_bytes_to_smc(adev,
23261bb76ff1Sjsg 						  (si_pi->state_table_start +
23271bb76ff1Sjsg 						   offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) +
23281bb76ff1Sjsg 						   offsetof(PP_SIslands_DPM2Parameters, NearTDPLimit)),
23291bb76ff1Sjsg 						  (u8 *)(&(smc_table->dpm2Params.NearTDPLimit)),
23301bb76ff1Sjsg 						  sizeof(u32) * 2,
23311bb76ff1Sjsg 						  si_pi->sram_end);
23321bb76ff1Sjsg 		if (ret)
23331bb76ff1Sjsg 			return ret;
23341bb76ff1Sjsg 	}
23351bb76ff1Sjsg 
23361bb76ff1Sjsg 	return 0;
23371bb76ff1Sjsg }
23381bb76ff1Sjsg 
si_calculate_power_efficiency_ratio(struct amdgpu_device * adev,const u16 prev_std_vddc,const u16 curr_std_vddc)23391bb76ff1Sjsg static u16 si_calculate_power_efficiency_ratio(struct amdgpu_device *adev,
23401bb76ff1Sjsg 					       const u16 prev_std_vddc,
23411bb76ff1Sjsg 					       const u16 curr_std_vddc)
23421bb76ff1Sjsg {
23431bb76ff1Sjsg 	u64 margin = (u64)SISLANDS_DPM2_PWREFFICIENCYRATIO_MARGIN;
23441bb76ff1Sjsg 	u64 prev_vddc = (u64)prev_std_vddc;
23451bb76ff1Sjsg 	u64 curr_vddc = (u64)curr_std_vddc;
23461bb76ff1Sjsg 	u64 pwr_efficiency_ratio, n, d;
23471bb76ff1Sjsg 
23481bb76ff1Sjsg 	if ((prev_vddc == 0) || (curr_vddc == 0))
23491bb76ff1Sjsg 		return 0;
23501bb76ff1Sjsg 
23511bb76ff1Sjsg 	n = div64_u64((u64)1024 * curr_vddc * curr_vddc * ((u64)1000 + margin), (u64)1000);
23521bb76ff1Sjsg 	d = prev_vddc * prev_vddc;
23531bb76ff1Sjsg 	pwr_efficiency_ratio = div64_u64(n, d);
23541bb76ff1Sjsg 
23551bb76ff1Sjsg 	if (pwr_efficiency_ratio > (u64)0xFFFF)
23561bb76ff1Sjsg 		return 0;
23571bb76ff1Sjsg 
23581bb76ff1Sjsg 	return (u16)pwr_efficiency_ratio;
23591bb76ff1Sjsg }
23601bb76ff1Sjsg 
si_should_disable_uvd_powertune(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state)23611bb76ff1Sjsg static bool si_should_disable_uvd_powertune(struct amdgpu_device *adev,
23621bb76ff1Sjsg 					    struct amdgpu_ps *amdgpu_state)
23631bb76ff1Sjsg {
23641bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
23651bb76ff1Sjsg 
23661bb76ff1Sjsg 	if (si_pi->dyn_powertune_data.disable_uvd_powertune &&
23671bb76ff1Sjsg 	    amdgpu_state->vclk && amdgpu_state->dclk)
23681bb76ff1Sjsg 		return true;
23691bb76ff1Sjsg 
23701bb76ff1Sjsg 	return false;
23711bb76ff1Sjsg }
23721bb76ff1Sjsg 
evergreen_get_pi(struct amdgpu_device * adev)23731bb76ff1Sjsg struct evergreen_power_info *evergreen_get_pi(struct amdgpu_device *adev)
23741bb76ff1Sjsg {
23751bb76ff1Sjsg 	struct evergreen_power_info *pi = adev->pm.dpm.priv;
23761bb76ff1Sjsg 
23771bb76ff1Sjsg 	return pi;
23781bb76ff1Sjsg }
23791bb76ff1Sjsg 
si_populate_power_containment_values(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state,SISLANDS_SMC_SWSTATE * smc_state)23801bb76ff1Sjsg static int si_populate_power_containment_values(struct amdgpu_device *adev,
23811bb76ff1Sjsg 						struct amdgpu_ps *amdgpu_state,
23821bb76ff1Sjsg 						SISLANDS_SMC_SWSTATE *smc_state)
23831bb76ff1Sjsg {
23841bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
23851bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
23861bb76ff1Sjsg 	struct  si_ps *state = si_get_ps(amdgpu_state);
23871bb76ff1Sjsg 	SISLANDS_SMC_VOLTAGE_VALUE vddc;
23881bb76ff1Sjsg 	u32 prev_sclk;
23891bb76ff1Sjsg 	u32 max_sclk;
23901bb76ff1Sjsg 	u32 min_sclk;
23911bb76ff1Sjsg 	u16 prev_std_vddc;
23921bb76ff1Sjsg 	u16 curr_std_vddc;
23931bb76ff1Sjsg 	int i;
23941bb76ff1Sjsg 	u16 pwr_efficiency_ratio;
23951bb76ff1Sjsg 	u8 max_ps_percent;
23961bb76ff1Sjsg 	bool disable_uvd_power_tune;
23971bb76ff1Sjsg 	int ret;
23981bb76ff1Sjsg 
23991bb76ff1Sjsg 	if (ni_pi->enable_power_containment == false)
24001bb76ff1Sjsg 		return 0;
24011bb76ff1Sjsg 
24021bb76ff1Sjsg 	if (state->performance_level_count == 0)
24031bb76ff1Sjsg 		return -EINVAL;
24041bb76ff1Sjsg 
24051bb76ff1Sjsg 	if (smc_state->levelCount != state->performance_level_count)
24061bb76ff1Sjsg 		return -EINVAL;
24071bb76ff1Sjsg 
24081bb76ff1Sjsg 	disable_uvd_power_tune = si_should_disable_uvd_powertune(adev, amdgpu_state);
24091bb76ff1Sjsg 
24101bb76ff1Sjsg 	smc_state->levels[0].dpm2.MaxPS = 0;
24111bb76ff1Sjsg 	smc_state->levels[0].dpm2.NearTDPDec = 0;
24121bb76ff1Sjsg 	smc_state->levels[0].dpm2.AboveSafeInc = 0;
24131bb76ff1Sjsg 	smc_state->levels[0].dpm2.BelowSafeInc = 0;
24141bb76ff1Sjsg 	smc_state->levels[0].dpm2.PwrEfficiencyRatio = 0;
24151bb76ff1Sjsg 
24161bb76ff1Sjsg 	for (i = 1; i < state->performance_level_count; i++) {
24171bb76ff1Sjsg 		prev_sclk = state->performance_levels[i-1].sclk;
24181bb76ff1Sjsg 		max_sclk  = state->performance_levels[i].sclk;
24191bb76ff1Sjsg 		if (i == 1)
24201bb76ff1Sjsg 			max_ps_percent = SISLANDS_DPM2_MAXPS_PERCENT_M;
24211bb76ff1Sjsg 		else
24221bb76ff1Sjsg 			max_ps_percent = SISLANDS_DPM2_MAXPS_PERCENT_H;
24231bb76ff1Sjsg 
24241bb76ff1Sjsg 		if (prev_sclk > max_sclk)
24251bb76ff1Sjsg 			return -EINVAL;
24261bb76ff1Sjsg 
24271bb76ff1Sjsg 		if ((max_ps_percent == 0) ||
24281bb76ff1Sjsg 		    (prev_sclk == max_sclk) ||
24291bb76ff1Sjsg 		    disable_uvd_power_tune)
24301bb76ff1Sjsg 			min_sclk = max_sclk;
24311bb76ff1Sjsg 		else if (i == 1)
24321bb76ff1Sjsg 			min_sclk = prev_sclk;
24331bb76ff1Sjsg 		else
24341bb76ff1Sjsg 			min_sclk = (prev_sclk * (u32)max_ps_percent) / 100;
24351bb76ff1Sjsg 
24361bb76ff1Sjsg 		if (min_sclk < state->performance_levels[0].sclk)
24371bb76ff1Sjsg 			min_sclk = state->performance_levels[0].sclk;
24381bb76ff1Sjsg 
24391bb76ff1Sjsg 		if (min_sclk == 0)
24401bb76ff1Sjsg 			return -EINVAL;
24411bb76ff1Sjsg 
24421bb76ff1Sjsg 		ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,
24431bb76ff1Sjsg 						state->performance_levels[i-1].vddc, &vddc);
24441bb76ff1Sjsg 		if (ret)
24451bb76ff1Sjsg 			return ret;
24461bb76ff1Sjsg 
24471bb76ff1Sjsg 		ret = si_get_std_voltage_value(adev, &vddc, &prev_std_vddc);
24481bb76ff1Sjsg 		if (ret)
24491bb76ff1Sjsg 			return ret;
24501bb76ff1Sjsg 
24511bb76ff1Sjsg 		ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,
24521bb76ff1Sjsg 						state->performance_levels[i].vddc, &vddc);
24531bb76ff1Sjsg 		if (ret)
24541bb76ff1Sjsg 			return ret;
24551bb76ff1Sjsg 
24561bb76ff1Sjsg 		ret = si_get_std_voltage_value(adev, &vddc, &curr_std_vddc);
24571bb76ff1Sjsg 		if (ret)
24581bb76ff1Sjsg 			return ret;
24591bb76ff1Sjsg 
24601bb76ff1Sjsg 		pwr_efficiency_ratio = si_calculate_power_efficiency_ratio(adev,
24611bb76ff1Sjsg 									   prev_std_vddc, curr_std_vddc);
24621bb76ff1Sjsg 
24631bb76ff1Sjsg 		smc_state->levels[i].dpm2.MaxPS = (u8)((SISLANDS_DPM2_MAX_PULSE_SKIP * (max_sclk - min_sclk)) / max_sclk);
24641bb76ff1Sjsg 		smc_state->levels[i].dpm2.NearTDPDec = SISLANDS_DPM2_NEAR_TDP_DEC;
24651bb76ff1Sjsg 		smc_state->levels[i].dpm2.AboveSafeInc = SISLANDS_DPM2_ABOVE_SAFE_INC;
24661bb76ff1Sjsg 		smc_state->levels[i].dpm2.BelowSafeInc = SISLANDS_DPM2_BELOW_SAFE_INC;
24671bb76ff1Sjsg 		smc_state->levels[i].dpm2.PwrEfficiencyRatio = cpu_to_be16(pwr_efficiency_ratio);
24681bb76ff1Sjsg 	}
24691bb76ff1Sjsg 
24701bb76ff1Sjsg 	return 0;
24711bb76ff1Sjsg }
24721bb76ff1Sjsg 
si_populate_sq_ramping_values(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state,SISLANDS_SMC_SWSTATE * smc_state)24731bb76ff1Sjsg static int si_populate_sq_ramping_values(struct amdgpu_device *adev,
24741bb76ff1Sjsg 					 struct amdgpu_ps *amdgpu_state,
24751bb76ff1Sjsg 					 SISLANDS_SMC_SWSTATE *smc_state)
24761bb76ff1Sjsg {
24771bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
24781bb76ff1Sjsg 	struct  si_ps *state = si_get_ps(amdgpu_state);
24791bb76ff1Sjsg 	u32 sq_power_throttle, sq_power_throttle2;
24801bb76ff1Sjsg 	bool enable_sq_ramping = ni_pi->enable_sq_ramping;
24811bb76ff1Sjsg 	int i;
24821bb76ff1Sjsg 
24831bb76ff1Sjsg 	if (state->performance_level_count == 0)
24841bb76ff1Sjsg 		return -EINVAL;
24851bb76ff1Sjsg 
24861bb76ff1Sjsg 	if (smc_state->levelCount != state->performance_level_count)
24871bb76ff1Sjsg 		return -EINVAL;
24881bb76ff1Sjsg 
24891bb76ff1Sjsg 	if (adev->pm.dpm.sq_ramping_threshold == 0)
24901bb76ff1Sjsg 		return -EINVAL;
24911bb76ff1Sjsg 
24921bb76ff1Sjsg 	if (SISLANDS_DPM2_SQ_RAMP_MAX_POWER > (MAX_POWER_MASK >> MAX_POWER_SHIFT))
24931bb76ff1Sjsg 		enable_sq_ramping = false;
24941bb76ff1Sjsg 
24951bb76ff1Sjsg 	if (SISLANDS_DPM2_SQ_RAMP_MIN_POWER > (MIN_POWER_MASK >> MIN_POWER_SHIFT))
24961bb76ff1Sjsg 		enable_sq_ramping = false;
24971bb76ff1Sjsg 
24981bb76ff1Sjsg 	if (SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA > (MAX_POWER_DELTA_MASK >> MAX_POWER_DELTA_SHIFT))
24991bb76ff1Sjsg 		enable_sq_ramping = false;
25001bb76ff1Sjsg 
25011bb76ff1Sjsg 	if (SISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT))
25021bb76ff1Sjsg 		enable_sq_ramping = false;
25031bb76ff1Sjsg 
25041bb76ff1Sjsg 	if (SISLANDS_DPM2_SQ_RAMP_LTI_RATIO > (LTI_RATIO_MASK >> LTI_RATIO_SHIFT))
25051bb76ff1Sjsg 		enable_sq_ramping = false;
25061bb76ff1Sjsg 
25071bb76ff1Sjsg 	for (i = 0; i < state->performance_level_count; i++) {
25081bb76ff1Sjsg 		sq_power_throttle = 0;
25091bb76ff1Sjsg 		sq_power_throttle2 = 0;
25101bb76ff1Sjsg 
25111bb76ff1Sjsg 		if ((state->performance_levels[i].sclk >= adev->pm.dpm.sq_ramping_threshold) &&
25121bb76ff1Sjsg 		    enable_sq_ramping) {
25131bb76ff1Sjsg 			sq_power_throttle |= MAX_POWER(SISLANDS_DPM2_SQ_RAMP_MAX_POWER);
25141bb76ff1Sjsg 			sq_power_throttle |= MIN_POWER(SISLANDS_DPM2_SQ_RAMP_MIN_POWER);
25151bb76ff1Sjsg 			sq_power_throttle2 |= MAX_POWER_DELTA(SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA);
25161bb76ff1Sjsg 			sq_power_throttle2 |= STI_SIZE(SISLANDS_DPM2_SQ_RAMP_STI_SIZE);
25171bb76ff1Sjsg 			sq_power_throttle2 |= LTI_RATIO(SISLANDS_DPM2_SQ_RAMP_LTI_RATIO);
25181bb76ff1Sjsg 		} else {
25191bb76ff1Sjsg 			sq_power_throttle |= MAX_POWER_MASK | MIN_POWER_MASK;
25201bb76ff1Sjsg 			sq_power_throttle2 |= MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
25211bb76ff1Sjsg 		}
25221bb76ff1Sjsg 
25231bb76ff1Sjsg 		smc_state->levels[i].SQPowerThrottle = cpu_to_be32(sq_power_throttle);
25241bb76ff1Sjsg 		smc_state->levels[i].SQPowerThrottle_2 = cpu_to_be32(sq_power_throttle2);
25251bb76ff1Sjsg 	}
25261bb76ff1Sjsg 
25271bb76ff1Sjsg 	return 0;
25281bb76ff1Sjsg }
25291bb76ff1Sjsg 
si_enable_power_containment(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_new_state,bool enable)25301bb76ff1Sjsg static int si_enable_power_containment(struct amdgpu_device *adev,
25311bb76ff1Sjsg 				       struct amdgpu_ps *amdgpu_new_state,
25321bb76ff1Sjsg 				       bool enable)
25331bb76ff1Sjsg {
25341bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
25351bb76ff1Sjsg 	PPSMC_Result smc_result;
25361bb76ff1Sjsg 	int ret = 0;
25371bb76ff1Sjsg 
25381bb76ff1Sjsg 	if (ni_pi->enable_power_containment) {
25391bb76ff1Sjsg 		if (enable) {
25401bb76ff1Sjsg 			if (!si_should_disable_uvd_powertune(adev, amdgpu_new_state)) {
25411bb76ff1Sjsg 				smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_TDPClampingActive);
25421bb76ff1Sjsg 				if (smc_result != PPSMC_Result_OK) {
25431bb76ff1Sjsg 					ret = -EINVAL;
25441bb76ff1Sjsg 					ni_pi->pc_enabled = false;
25451bb76ff1Sjsg 				} else {
25461bb76ff1Sjsg 					ni_pi->pc_enabled = true;
25471bb76ff1Sjsg 				}
25481bb76ff1Sjsg 			}
25491bb76ff1Sjsg 		} else {
25501bb76ff1Sjsg 			smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_TDPClampingInactive);
25511bb76ff1Sjsg 			if (smc_result != PPSMC_Result_OK)
25521bb76ff1Sjsg 				ret = -EINVAL;
25531bb76ff1Sjsg 			ni_pi->pc_enabled = false;
25541bb76ff1Sjsg 		}
25551bb76ff1Sjsg 	}
25561bb76ff1Sjsg 
25571bb76ff1Sjsg 	return ret;
25581bb76ff1Sjsg }
25591bb76ff1Sjsg 
si_initialize_smc_dte_tables(struct amdgpu_device * adev)25601bb76ff1Sjsg static int si_initialize_smc_dte_tables(struct amdgpu_device *adev)
25611bb76ff1Sjsg {
25621bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
25631bb76ff1Sjsg 	int ret = 0;
25641bb76ff1Sjsg 	struct si_dte_data *dte_data = &si_pi->dte_data;
25651bb76ff1Sjsg 	Smc_SIslands_DTE_Configuration *dte_tables = NULL;
25661bb76ff1Sjsg 	u32 table_size;
25671bb76ff1Sjsg 	u8 tdep_count;
25681bb76ff1Sjsg 	u32 i;
25691bb76ff1Sjsg 
25701bb76ff1Sjsg 	if (dte_data == NULL)
25711bb76ff1Sjsg 		si_pi->enable_dte = false;
25721bb76ff1Sjsg 
25731bb76ff1Sjsg 	if (si_pi->enable_dte == false)
25741bb76ff1Sjsg 		return 0;
25751bb76ff1Sjsg 
25761bb76ff1Sjsg 	if (dte_data->k <= 0)
25771bb76ff1Sjsg 		return -EINVAL;
25781bb76ff1Sjsg 
25791bb76ff1Sjsg 	dte_tables = kzalloc(sizeof(Smc_SIslands_DTE_Configuration), GFP_KERNEL);
25801bb76ff1Sjsg 	if (dte_tables == NULL) {
25811bb76ff1Sjsg 		si_pi->enable_dte = false;
25821bb76ff1Sjsg 		return -ENOMEM;
25831bb76ff1Sjsg 	}
25841bb76ff1Sjsg 
25851bb76ff1Sjsg 	table_size = dte_data->k;
25861bb76ff1Sjsg 
25871bb76ff1Sjsg 	if (table_size > SMC_SISLANDS_DTE_MAX_FILTER_STAGES)
25881bb76ff1Sjsg 		table_size = SMC_SISLANDS_DTE_MAX_FILTER_STAGES;
25891bb76ff1Sjsg 
25901bb76ff1Sjsg 	tdep_count = dte_data->tdep_count;
25911bb76ff1Sjsg 	if (tdep_count > SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE)
25921bb76ff1Sjsg 		tdep_count = SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE;
25931bb76ff1Sjsg 
25941bb76ff1Sjsg 	dte_tables->K = cpu_to_be32(table_size);
25951bb76ff1Sjsg 	dte_tables->T0 = cpu_to_be32(dte_data->t0);
25961bb76ff1Sjsg 	dte_tables->MaxT = cpu_to_be32(dte_data->max_t);
25971bb76ff1Sjsg 	dte_tables->WindowSize = dte_data->window_size;
25981bb76ff1Sjsg 	dte_tables->temp_select = dte_data->temp_select;
25991bb76ff1Sjsg 	dte_tables->DTE_mode = dte_data->dte_mode;
26001bb76ff1Sjsg 	dte_tables->Tthreshold = cpu_to_be32(dte_data->t_threshold);
26011bb76ff1Sjsg 
26021bb76ff1Sjsg 	if (tdep_count > 0)
26031bb76ff1Sjsg 		table_size--;
26041bb76ff1Sjsg 
26051bb76ff1Sjsg 	for (i = 0; i < table_size; i++) {
26061bb76ff1Sjsg 		dte_tables->tau[i] = cpu_to_be32(dte_data->tau[i]);
26071bb76ff1Sjsg 		dte_tables->R[i]   = cpu_to_be32(dte_data->r[i]);
26081bb76ff1Sjsg 	}
26091bb76ff1Sjsg 
26101bb76ff1Sjsg 	dte_tables->Tdep_count = tdep_count;
26111bb76ff1Sjsg 
26121bb76ff1Sjsg 	for (i = 0; i < (u32)tdep_count; i++) {
26131bb76ff1Sjsg 		dte_tables->T_limits[i] = dte_data->t_limits[i];
26141bb76ff1Sjsg 		dte_tables->Tdep_tau[i] = cpu_to_be32(dte_data->tdep_tau[i]);
26151bb76ff1Sjsg 		dte_tables->Tdep_R[i] = cpu_to_be32(dte_data->tdep_r[i]);
26161bb76ff1Sjsg 	}
26171bb76ff1Sjsg 
26181bb76ff1Sjsg 	ret = amdgpu_si_copy_bytes_to_smc(adev, si_pi->dte_table_start,
26191bb76ff1Sjsg 					  (u8 *)dte_tables,
26201bb76ff1Sjsg 					  sizeof(Smc_SIslands_DTE_Configuration),
26211bb76ff1Sjsg 					  si_pi->sram_end);
26221bb76ff1Sjsg 	kfree(dte_tables);
26231bb76ff1Sjsg 
26241bb76ff1Sjsg 	return ret;
26251bb76ff1Sjsg }
26261bb76ff1Sjsg 
si_get_cac_std_voltage_max_min(struct amdgpu_device * adev,u16 * max,u16 * min)26271bb76ff1Sjsg static int si_get_cac_std_voltage_max_min(struct amdgpu_device *adev,
26281bb76ff1Sjsg 					  u16 *max, u16 *min)
26291bb76ff1Sjsg {
26301bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
26311bb76ff1Sjsg 	struct amdgpu_cac_leakage_table *table =
26321bb76ff1Sjsg 		&adev->pm.dpm.dyn_state.cac_leakage_table;
26331bb76ff1Sjsg 	u32 i;
26341bb76ff1Sjsg 	u32 v0_loadline;
26351bb76ff1Sjsg 
26361bb76ff1Sjsg 	if (table == NULL)
26371bb76ff1Sjsg 		return -EINVAL;
26381bb76ff1Sjsg 
26391bb76ff1Sjsg 	*max = 0;
26401bb76ff1Sjsg 	*min = 0xFFFF;
26411bb76ff1Sjsg 
26421bb76ff1Sjsg 	for (i = 0; i < table->count; i++) {
26431bb76ff1Sjsg 		if (table->entries[i].vddc > *max)
26441bb76ff1Sjsg 			*max = table->entries[i].vddc;
26451bb76ff1Sjsg 		if (table->entries[i].vddc < *min)
26461bb76ff1Sjsg 			*min = table->entries[i].vddc;
26471bb76ff1Sjsg 	}
26481bb76ff1Sjsg 
26491bb76ff1Sjsg 	if (si_pi->powertune_data->lkge_lut_v0_percent > 100)
26501bb76ff1Sjsg 		return -EINVAL;
26511bb76ff1Sjsg 
26521bb76ff1Sjsg 	v0_loadline = (*min) * (100 - si_pi->powertune_data->lkge_lut_v0_percent) / 100;
26531bb76ff1Sjsg 
26541bb76ff1Sjsg 	if (v0_loadline > 0xFFFFUL)
26551bb76ff1Sjsg 		return -EINVAL;
26561bb76ff1Sjsg 
26571bb76ff1Sjsg 	*min = (u16)v0_loadline;
26581bb76ff1Sjsg 
26591bb76ff1Sjsg 	if ((*min > *max) || (*max == 0) || (*min == 0))
26601bb76ff1Sjsg 		return -EINVAL;
26611bb76ff1Sjsg 
26621bb76ff1Sjsg 	return 0;
26631bb76ff1Sjsg }
26641bb76ff1Sjsg 
si_get_cac_std_voltage_step(u16 max,u16 min)26651bb76ff1Sjsg static u16 si_get_cac_std_voltage_step(u16 max, u16 min)
26661bb76ff1Sjsg {
26671bb76ff1Sjsg 	return ((max - min) + (SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1)) /
26681bb76ff1Sjsg 		SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES;
26691bb76ff1Sjsg }
26701bb76ff1Sjsg 
si_init_dte_leakage_table(struct amdgpu_device * adev,PP_SIslands_CacConfig * cac_tables,u16 vddc_max,u16 vddc_min,u16 vddc_step,u16 t0,u16 t_step)26711bb76ff1Sjsg static int si_init_dte_leakage_table(struct amdgpu_device *adev,
26721bb76ff1Sjsg 				     PP_SIslands_CacConfig *cac_tables,
26731bb76ff1Sjsg 				     u16 vddc_max, u16 vddc_min, u16 vddc_step,
26741bb76ff1Sjsg 				     u16 t0, u16 t_step)
26751bb76ff1Sjsg {
26761bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
26771bb76ff1Sjsg 	u32 leakage;
26781bb76ff1Sjsg 	unsigned int i, j;
26791bb76ff1Sjsg 	s32 t;
26801bb76ff1Sjsg 	u32 smc_leakage;
26811bb76ff1Sjsg 	u32 scaling_factor;
26821bb76ff1Sjsg 	u16 voltage;
26831bb76ff1Sjsg 
26841bb76ff1Sjsg 	scaling_factor = si_get_smc_power_scaling_factor(adev);
26851bb76ff1Sjsg 
26861bb76ff1Sjsg 	for (i = 0; i < SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES ; i++) {
26871bb76ff1Sjsg 		t = (1000 * (i * t_step + t0));
26881bb76ff1Sjsg 
26891bb76ff1Sjsg 		for (j = 0; j < SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
26901bb76ff1Sjsg 			voltage = vddc_max - (vddc_step * j);
26911bb76ff1Sjsg 
26921bb76ff1Sjsg 			si_calculate_leakage_for_v_and_t(adev,
26931bb76ff1Sjsg 							 &si_pi->powertune_data->leakage_coefficients,
26941bb76ff1Sjsg 							 voltage,
26951bb76ff1Sjsg 							 t,
26961bb76ff1Sjsg 							 si_pi->dyn_powertune_data.cac_leakage,
26971bb76ff1Sjsg 							 &leakage);
26981bb76ff1Sjsg 
26991bb76ff1Sjsg 			smc_leakage = si_scale_power_for_smc(leakage, scaling_factor) / 4;
27001bb76ff1Sjsg 
27011bb76ff1Sjsg 			if (smc_leakage > 0xFFFF)
27021bb76ff1Sjsg 				smc_leakage = 0xFFFF;
27031bb76ff1Sjsg 
27041bb76ff1Sjsg 			cac_tables->cac_lkge_lut[i][SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES-1-j] =
27051bb76ff1Sjsg 				cpu_to_be16((u16)smc_leakage);
27061bb76ff1Sjsg 		}
27071bb76ff1Sjsg 	}
27081bb76ff1Sjsg 	return 0;
27091bb76ff1Sjsg }
27101bb76ff1Sjsg 
si_init_simplified_leakage_table(struct amdgpu_device * adev,PP_SIslands_CacConfig * cac_tables,u16 vddc_max,u16 vddc_min,u16 vddc_step)27111bb76ff1Sjsg static int si_init_simplified_leakage_table(struct amdgpu_device *adev,
27121bb76ff1Sjsg 					    PP_SIslands_CacConfig *cac_tables,
27131bb76ff1Sjsg 					    u16 vddc_max, u16 vddc_min, u16 vddc_step)
27141bb76ff1Sjsg {
27151bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
27161bb76ff1Sjsg 	u32 leakage;
27171bb76ff1Sjsg 	unsigned int i, j;
27181bb76ff1Sjsg 	u32 smc_leakage;
27191bb76ff1Sjsg 	u32 scaling_factor;
27201bb76ff1Sjsg 	u16 voltage;
27211bb76ff1Sjsg 
27221bb76ff1Sjsg 	scaling_factor = si_get_smc_power_scaling_factor(adev);
27231bb76ff1Sjsg 
27241bb76ff1Sjsg 	for (j = 0; j < SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
27251bb76ff1Sjsg 		voltage = vddc_max - (vddc_step * j);
27261bb76ff1Sjsg 
27271bb76ff1Sjsg 		si_calculate_leakage_for_v(adev,
27281bb76ff1Sjsg 					   &si_pi->powertune_data->leakage_coefficients,
27291bb76ff1Sjsg 					   si_pi->powertune_data->fixed_kt,
27301bb76ff1Sjsg 					   voltage,
27311bb76ff1Sjsg 					   si_pi->dyn_powertune_data.cac_leakage,
27321bb76ff1Sjsg 					   &leakage);
27331bb76ff1Sjsg 
27341bb76ff1Sjsg 		smc_leakage = si_scale_power_for_smc(leakage, scaling_factor) / 4;
27351bb76ff1Sjsg 
27361bb76ff1Sjsg 		if (smc_leakage > 0xFFFF)
27371bb76ff1Sjsg 			smc_leakage = 0xFFFF;
27381bb76ff1Sjsg 
27391bb76ff1Sjsg 		for (i = 0; i < SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES ; i++)
27401bb76ff1Sjsg 			cac_tables->cac_lkge_lut[i][SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES-1-j] =
27411bb76ff1Sjsg 				cpu_to_be16((u16)smc_leakage);
27421bb76ff1Sjsg 	}
27431bb76ff1Sjsg 	return 0;
27441bb76ff1Sjsg }
27451bb76ff1Sjsg 
si_initialize_smc_cac_tables(struct amdgpu_device * adev)27461bb76ff1Sjsg static int si_initialize_smc_cac_tables(struct amdgpu_device *adev)
27471bb76ff1Sjsg {
27481bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
27491bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
27501bb76ff1Sjsg 	PP_SIslands_CacConfig *cac_tables = NULL;
27511bb76ff1Sjsg 	u16 vddc_max, vddc_min, vddc_step;
27521bb76ff1Sjsg 	u16 t0, t_step;
27531bb76ff1Sjsg 	u32 load_line_slope, reg;
27541bb76ff1Sjsg 	int ret = 0;
27551bb76ff1Sjsg 	u32 ticks_per_us = amdgpu_asic_get_xclk(adev) / 100;
27561bb76ff1Sjsg 
27571bb76ff1Sjsg 	if (ni_pi->enable_cac == false)
27581bb76ff1Sjsg 		return 0;
27591bb76ff1Sjsg 
27601bb76ff1Sjsg 	cac_tables = kzalloc(sizeof(PP_SIslands_CacConfig), GFP_KERNEL);
27611bb76ff1Sjsg 	if (!cac_tables)
27621bb76ff1Sjsg 		return -ENOMEM;
27631bb76ff1Sjsg 
27641bb76ff1Sjsg 	reg = RREG32(CG_CAC_CTRL) & ~CAC_WINDOW_MASK;
27651bb76ff1Sjsg 	reg |= CAC_WINDOW(si_pi->powertune_data->cac_window);
27661bb76ff1Sjsg 	WREG32(CG_CAC_CTRL, reg);
27671bb76ff1Sjsg 
27681bb76ff1Sjsg 	si_pi->dyn_powertune_data.cac_leakage = adev->pm.dpm.cac_leakage;
27691bb76ff1Sjsg 	si_pi->dyn_powertune_data.dc_pwr_value =
27701bb76ff1Sjsg 		si_pi->powertune_data->dc_cac[NISLANDS_DCCAC_LEVEL_0];
27711bb76ff1Sjsg 	si_pi->dyn_powertune_data.wintime = si_calculate_cac_wintime(adev);
27721bb76ff1Sjsg 	si_pi->dyn_powertune_data.shift_n = si_pi->powertune_data->shift_n_default;
27731bb76ff1Sjsg 
27741bb76ff1Sjsg 	si_pi->dyn_powertune_data.leakage_minimum_temperature = 80 * 1000;
27751bb76ff1Sjsg 
27761bb76ff1Sjsg 	ret = si_get_cac_std_voltage_max_min(adev, &vddc_max, &vddc_min);
27771bb76ff1Sjsg 	if (ret)
27781bb76ff1Sjsg 		goto done_free;
27791bb76ff1Sjsg 
27801bb76ff1Sjsg 	vddc_step = si_get_cac_std_voltage_step(vddc_max, vddc_min);
27811bb76ff1Sjsg 	vddc_min = vddc_max - (vddc_step * (SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1));
27821bb76ff1Sjsg 	t_step = 4;
27831bb76ff1Sjsg 	t0 = 60;
27841bb76ff1Sjsg 
27851bb76ff1Sjsg 	if (si_pi->enable_dte || ni_pi->driver_calculate_cac_leakage)
27861bb76ff1Sjsg 		ret = si_init_dte_leakage_table(adev, cac_tables,
27871bb76ff1Sjsg 						vddc_max, vddc_min, vddc_step,
27881bb76ff1Sjsg 						t0, t_step);
27891bb76ff1Sjsg 	else
27901bb76ff1Sjsg 		ret = si_init_simplified_leakage_table(adev, cac_tables,
27911bb76ff1Sjsg 						       vddc_max, vddc_min, vddc_step);
27921bb76ff1Sjsg 	if (ret)
27931bb76ff1Sjsg 		goto done_free;
27941bb76ff1Sjsg 
27951bb76ff1Sjsg 	load_line_slope = ((u32)adev->pm.dpm.load_line_slope << SMC_SISLANDS_SCALE_R) / 100;
27961bb76ff1Sjsg 
27971bb76ff1Sjsg 	cac_tables->l2numWin_TDP = cpu_to_be32(si_pi->dyn_powertune_data.l2_lta_window_size);
27981bb76ff1Sjsg 	cac_tables->lts_truncate_n = si_pi->dyn_powertune_data.lts_truncate;
27991bb76ff1Sjsg 	cac_tables->SHIFT_N = si_pi->dyn_powertune_data.shift_n;
28001bb76ff1Sjsg 	cac_tables->lkge_lut_V0 = cpu_to_be32((u32)vddc_min);
28011bb76ff1Sjsg 	cac_tables->lkge_lut_Vstep = cpu_to_be32((u32)vddc_step);
28021bb76ff1Sjsg 	cac_tables->R_LL = cpu_to_be32(load_line_slope);
28031bb76ff1Sjsg 	cac_tables->WinTime = cpu_to_be32(si_pi->dyn_powertune_data.wintime);
28041bb76ff1Sjsg 	cac_tables->calculation_repeats = cpu_to_be32(2);
28051bb76ff1Sjsg 	cac_tables->dc_cac = cpu_to_be32(0);
28061bb76ff1Sjsg 	cac_tables->log2_PG_LKG_SCALE = 12;
28071bb76ff1Sjsg 	cac_tables->cac_temp = si_pi->powertune_data->operating_temp;
28081bb76ff1Sjsg 	cac_tables->lkge_lut_T0 = cpu_to_be32((u32)t0);
28091bb76ff1Sjsg 	cac_tables->lkge_lut_Tstep = cpu_to_be32((u32)t_step);
28101bb76ff1Sjsg 
28111bb76ff1Sjsg 	ret = amdgpu_si_copy_bytes_to_smc(adev, si_pi->cac_table_start,
28121bb76ff1Sjsg 					  (u8 *)cac_tables,
28131bb76ff1Sjsg 					  sizeof(PP_SIslands_CacConfig),
28141bb76ff1Sjsg 					  si_pi->sram_end);
28151bb76ff1Sjsg 
28161bb76ff1Sjsg 	if (ret)
28171bb76ff1Sjsg 		goto done_free;
28181bb76ff1Sjsg 
28191bb76ff1Sjsg 	ret = si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_ticks_per_us, ticks_per_us);
28201bb76ff1Sjsg 
28211bb76ff1Sjsg done_free:
28221bb76ff1Sjsg 	if (ret) {
28231bb76ff1Sjsg 		ni_pi->enable_cac = false;
28241bb76ff1Sjsg 		ni_pi->enable_power_containment = false;
28251bb76ff1Sjsg 	}
28261bb76ff1Sjsg 
28271bb76ff1Sjsg 	kfree(cac_tables);
28281bb76ff1Sjsg 
28291bb76ff1Sjsg 	return ret;
28301bb76ff1Sjsg }
28311bb76ff1Sjsg 
si_program_cac_config_registers(struct amdgpu_device * adev,const struct si_cac_config_reg * cac_config_regs)28321bb76ff1Sjsg static int si_program_cac_config_registers(struct amdgpu_device *adev,
28331bb76ff1Sjsg 					   const struct si_cac_config_reg *cac_config_regs)
28341bb76ff1Sjsg {
28351bb76ff1Sjsg 	const struct si_cac_config_reg *config_regs = cac_config_regs;
28361bb76ff1Sjsg 	u32 data = 0, offset;
28371bb76ff1Sjsg 
28381bb76ff1Sjsg 	if (!config_regs)
28391bb76ff1Sjsg 		return -EINVAL;
28401bb76ff1Sjsg 
28411bb76ff1Sjsg 	while (config_regs->offset != 0xFFFFFFFF) {
28421bb76ff1Sjsg 		switch (config_regs->type) {
28431bb76ff1Sjsg 		case SISLANDS_CACCONFIG_CGIND:
28441bb76ff1Sjsg 			offset = SMC_CG_IND_START + config_regs->offset;
28451bb76ff1Sjsg 			if (offset < SMC_CG_IND_END)
28461bb76ff1Sjsg 				data = RREG32_SMC(offset);
28471bb76ff1Sjsg 			break;
28481bb76ff1Sjsg 		default:
28491bb76ff1Sjsg 			data = RREG32(config_regs->offset);
28501bb76ff1Sjsg 			break;
28511bb76ff1Sjsg 		}
28521bb76ff1Sjsg 
28531bb76ff1Sjsg 		data &= ~config_regs->mask;
28541bb76ff1Sjsg 		data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
28551bb76ff1Sjsg 
28561bb76ff1Sjsg 		switch (config_regs->type) {
28571bb76ff1Sjsg 		case SISLANDS_CACCONFIG_CGIND:
28581bb76ff1Sjsg 			offset = SMC_CG_IND_START + config_regs->offset;
28591bb76ff1Sjsg 			if (offset < SMC_CG_IND_END)
28601bb76ff1Sjsg 				WREG32_SMC(offset, data);
28611bb76ff1Sjsg 			break;
28621bb76ff1Sjsg 		default:
28631bb76ff1Sjsg 			WREG32(config_regs->offset, data);
28641bb76ff1Sjsg 			break;
28651bb76ff1Sjsg 		}
28661bb76ff1Sjsg 		config_regs++;
28671bb76ff1Sjsg 	}
28681bb76ff1Sjsg 	return 0;
28691bb76ff1Sjsg }
28701bb76ff1Sjsg 
si_initialize_hardware_cac_manager(struct amdgpu_device * adev)28711bb76ff1Sjsg static int si_initialize_hardware_cac_manager(struct amdgpu_device *adev)
28721bb76ff1Sjsg {
28731bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
28741bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
28751bb76ff1Sjsg 	int ret;
28761bb76ff1Sjsg 
28771bb76ff1Sjsg 	if ((ni_pi->enable_cac == false) ||
28781bb76ff1Sjsg 	    (ni_pi->cac_configuration_required == false))
28791bb76ff1Sjsg 		return 0;
28801bb76ff1Sjsg 
28811bb76ff1Sjsg 	ret = si_program_cac_config_registers(adev, si_pi->lcac_config);
28821bb76ff1Sjsg 	if (ret)
28831bb76ff1Sjsg 		return ret;
28841bb76ff1Sjsg 	ret = si_program_cac_config_registers(adev, si_pi->cac_override);
28851bb76ff1Sjsg 	if (ret)
28861bb76ff1Sjsg 		return ret;
28871bb76ff1Sjsg 	ret = si_program_cac_config_registers(adev, si_pi->cac_weights);
28881bb76ff1Sjsg 	if (ret)
28891bb76ff1Sjsg 		return ret;
28901bb76ff1Sjsg 
28911bb76ff1Sjsg 	return 0;
28921bb76ff1Sjsg }
28931bb76ff1Sjsg 
si_enable_smc_cac(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_new_state,bool enable)28941bb76ff1Sjsg static int si_enable_smc_cac(struct amdgpu_device *adev,
28951bb76ff1Sjsg 			     struct amdgpu_ps *amdgpu_new_state,
28961bb76ff1Sjsg 			     bool enable)
28971bb76ff1Sjsg {
28981bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
28991bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
29001bb76ff1Sjsg 	PPSMC_Result smc_result;
29011bb76ff1Sjsg 	int ret = 0;
29021bb76ff1Sjsg 
29031bb76ff1Sjsg 	if (ni_pi->enable_cac) {
29041bb76ff1Sjsg 		if (enable) {
29051bb76ff1Sjsg 			if (!si_should_disable_uvd_powertune(adev, amdgpu_new_state)) {
29061bb76ff1Sjsg 				if (ni_pi->support_cac_long_term_average) {
29071bb76ff1Sjsg 					smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_CACLongTermAvgEnable);
29081bb76ff1Sjsg 					if (smc_result != PPSMC_Result_OK)
29091bb76ff1Sjsg 						ni_pi->support_cac_long_term_average = false;
29101bb76ff1Sjsg 				}
29111bb76ff1Sjsg 
29121bb76ff1Sjsg 				smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableCac);
29131bb76ff1Sjsg 				if (smc_result != PPSMC_Result_OK) {
29141bb76ff1Sjsg 					ret = -EINVAL;
29151bb76ff1Sjsg 					ni_pi->cac_enabled = false;
29161bb76ff1Sjsg 				} else {
29171bb76ff1Sjsg 					ni_pi->cac_enabled = true;
29181bb76ff1Sjsg 				}
29191bb76ff1Sjsg 
29201bb76ff1Sjsg 				if (si_pi->enable_dte) {
29211bb76ff1Sjsg 					smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableDTE);
29221bb76ff1Sjsg 					if (smc_result != PPSMC_Result_OK)
29231bb76ff1Sjsg 						ret = -EINVAL;
29241bb76ff1Sjsg 				}
29251bb76ff1Sjsg 			}
29261bb76ff1Sjsg 		} else if (ni_pi->cac_enabled) {
29271bb76ff1Sjsg 			if (si_pi->enable_dte)
29281bb76ff1Sjsg 				smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_DisableDTE);
29291bb76ff1Sjsg 
29301bb76ff1Sjsg 			smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_DisableCac);
29311bb76ff1Sjsg 
29321bb76ff1Sjsg 			ni_pi->cac_enabled = false;
29331bb76ff1Sjsg 
29341bb76ff1Sjsg 			if (ni_pi->support_cac_long_term_average)
29351bb76ff1Sjsg 				smc_result = amdgpu_si_send_msg_to_smc(adev, PPSMC_CACLongTermAvgDisable);
29361bb76ff1Sjsg 		}
29371bb76ff1Sjsg 	}
29381bb76ff1Sjsg 	return ret;
29391bb76ff1Sjsg }
29401bb76ff1Sjsg 
si_init_smc_spll_table(struct amdgpu_device * adev)29411bb76ff1Sjsg static int si_init_smc_spll_table(struct amdgpu_device *adev)
29421bb76ff1Sjsg {
29431bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
29441bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
29451bb76ff1Sjsg 	SMC_SISLANDS_SPLL_DIV_TABLE *spll_table;
29461bb76ff1Sjsg 	SISLANDS_SMC_SCLK_VALUE sclk_params;
29471bb76ff1Sjsg 	u32 fb_div, p_div;
29481bb76ff1Sjsg 	u32 clk_s, clk_v;
29491bb76ff1Sjsg 	u32 sclk = 0;
29501bb76ff1Sjsg 	int ret = 0;
29511bb76ff1Sjsg 	u32 tmp;
29521bb76ff1Sjsg 	int i;
29531bb76ff1Sjsg 
29541bb76ff1Sjsg 	if (si_pi->spll_table_start == 0)
29551bb76ff1Sjsg 		return -EINVAL;
29561bb76ff1Sjsg 
29571bb76ff1Sjsg 	spll_table = kzalloc(sizeof(SMC_SISLANDS_SPLL_DIV_TABLE), GFP_KERNEL);
29581bb76ff1Sjsg 	if (spll_table == NULL)
29591bb76ff1Sjsg 		return -ENOMEM;
29601bb76ff1Sjsg 
29611bb76ff1Sjsg 	for (i = 0; i < 256; i++) {
29621bb76ff1Sjsg 		ret = si_calculate_sclk_params(adev, sclk, &sclk_params);
29631bb76ff1Sjsg 		if (ret)
29641bb76ff1Sjsg 			break;
29651bb76ff1Sjsg 		p_div = (sclk_params.vCG_SPLL_FUNC_CNTL & SPLL_PDIV_A_MASK) >> SPLL_PDIV_A_SHIFT;
29661bb76ff1Sjsg 		fb_div = (sclk_params.vCG_SPLL_FUNC_CNTL_3 & SPLL_FB_DIV_MASK) >> SPLL_FB_DIV_SHIFT;
29671bb76ff1Sjsg 		clk_s = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM & CLK_S_MASK) >> CLK_S_SHIFT;
29681bb76ff1Sjsg 		clk_v = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM_2 & CLK_V_MASK) >> CLK_V_SHIFT;
29691bb76ff1Sjsg 
29701bb76ff1Sjsg 		fb_div &= ~0x00001FFF;
29711bb76ff1Sjsg 		fb_div >>= 1;
29721bb76ff1Sjsg 		clk_v >>= 6;
29731bb76ff1Sjsg 
29741bb76ff1Sjsg 		if (p_div & ~(SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT))
29751bb76ff1Sjsg 			ret = -EINVAL;
29761bb76ff1Sjsg 		if (fb_div & ~(SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT))
29771bb76ff1Sjsg 			ret = -EINVAL;
29781bb76ff1Sjsg 		if (clk_s & ~(SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT))
29791bb76ff1Sjsg 			ret = -EINVAL;
29801bb76ff1Sjsg 		if (clk_v & ~(SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT))
29811bb76ff1Sjsg 			ret = -EINVAL;
29821bb76ff1Sjsg 
29831bb76ff1Sjsg 		if (ret)
29841bb76ff1Sjsg 			break;
29851bb76ff1Sjsg 
29861bb76ff1Sjsg 		tmp = ((fb_div << SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK) |
29871bb76ff1Sjsg 			((p_div << SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK);
29881bb76ff1Sjsg 		spll_table->freq[i] = cpu_to_be32(tmp);
29891bb76ff1Sjsg 
29901bb76ff1Sjsg 		tmp = ((clk_v << SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK) |
29911bb76ff1Sjsg 			((clk_s << SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK);
29921bb76ff1Sjsg 		spll_table->ss[i] = cpu_to_be32(tmp);
29931bb76ff1Sjsg 
29941bb76ff1Sjsg 		sclk += 512;
29951bb76ff1Sjsg 	}
29961bb76ff1Sjsg 
29971bb76ff1Sjsg 
29981bb76ff1Sjsg 	if (!ret)
29991bb76ff1Sjsg 		ret = amdgpu_si_copy_bytes_to_smc(adev, si_pi->spll_table_start,
30001bb76ff1Sjsg 						  (u8 *)spll_table,
30011bb76ff1Sjsg 						  sizeof(SMC_SISLANDS_SPLL_DIV_TABLE),
30021bb76ff1Sjsg 						  si_pi->sram_end);
30031bb76ff1Sjsg 
30041bb76ff1Sjsg 	if (ret)
30051bb76ff1Sjsg 		ni_pi->enable_power_containment = false;
30061bb76ff1Sjsg 
30071bb76ff1Sjsg 	kfree(spll_table);
30081bb76ff1Sjsg 
30091bb76ff1Sjsg 	return ret;
30101bb76ff1Sjsg }
30111bb76ff1Sjsg 
si_get_lower_of_leakage_and_vce_voltage(struct amdgpu_device * adev,u16 vce_voltage)30121bb76ff1Sjsg static u16 si_get_lower_of_leakage_and_vce_voltage(struct amdgpu_device *adev,
30131bb76ff1Sjsg 						   u16 vce_voltage)
30141bb76ff1Sjsg {
30151bb76ff1Sjsg 	u16 highest_leakage = 0;
30161bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
30171bb76ff1Sjsg 	int i;
30181bb76ff1Sjsg 
30191bb76ff1Sjsg 	for (i = 0; i < si_pi->leakage_voltage.count; i++){
30201bb76ff1Sjsg 		if (highest_leakage < si_pi->leakage_voltage.entries[i].voltage)
30211bb76ff1Sjsg 			highest_leakage = si_pi->leakage_voltage.entries[i].voltage;
30221bb76ff1Sjsg 	}
30231bb76ff1Sjsg 
30241bb76ff1Sjsg 	if (si_pi->leakage_voltage.count && (highest_leakage < vce_voltage))
30251bb76ff1Sjsg 		return highest_leakage;
30261bb76ff1Sjsg 
30271bb76ff1Sjsg 	return vce_voltage;
30281bb76ff1Sjsg }
30291bb76ff1Sjsg 
si_get_vce_clock_voltage(struct amdgpu_device * adev,u32 evclk,u32 ecclk,u16 * voltage)30301bb76ff1Sjsg static int si_get_vce_clock_voltage(struct amdgpu_device *adev,
30311bb76ff1Sjsg 				    u32 evclk, u32 ecclk, u16 *voltage)
30321bb76ff1Sjsg {
30331bb76ff1Sjsg 	u32 i;
30341bb76ff1Sjsg 	int ret = -EINVAL;
30351bb76ff1Sjsg 	struct amdgpu_vce_clock_voltage_dependency_table *table =
30361bb76ff1Sjsg 		&adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
30371bb76ff1Sjsg 
30381bb76ff1Sjsg 	if (((evclk == 0) && (ecclk == 0)) ||
30391bb76ff1Sjsg 	    (table && (table->count == 0))) {
30401bb76ff1Sjsg 		*voltage = 0;
30411bb76ff1Sjsg 		return 0;
30421bb76ff1Sjsg 	}
30431bb76ff1Sjsg 
30441bb76ff1Sjsg 	for (i = 0; i < table->count; i++) {
30451bb76ff1Sjsg 		if ((evclk <= table->entries[i].evclk) &&
30461bb76ff1Sjsg 		    (ecclk <= table->entries[i].ecclk)) {
30471bb76ff1Sjsg 			*voltage = table->entries[i].v;
30481bb76ff1Sjsg 			ret = 0;
30491bb76ff1Sjsg 			break;
30501bb76ff1Sjsg 		}
30511bb76ff1Sjsg 	}
30521bb76ff1Sjsg 
30531bb76ff1Sjsg 	/* if no match return the highest voltage */
30541bb76ff1Sjsg 	if (ret)
30551bb76ff1Sjsg 		*voltage = table->entries[table->count - 1].v;
30561bb76ff1Sjsg 
30571bb76ff1Sjsg 	*voltage = si_get_lower_of_leakage_and_vce_voltage(adev, *voltage);
30581bb76ff1Sjsg 
30591bb76ff1Sjsg 	return ret;
30601bb76ff1Sjsg }
30611bb76ff1Sjsg 
si_dpm_vblank_too_short(void * handle)30621bb76ff1Sjsg static bool si_dpm_vblank_too_short(void *handle)
30631bb76ff1Sjsg {
30641bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
30651bb76ff1Sjsg 	u32 vblank_time = amdgpu_dpm_get_vblank_time(adev);
30661bb76ff1Sjsg 	/* we never hit the non-gddr5 limit so disable it */
30671bb76ff1Sjsg 	u32 switch_limit = adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5 ? 450 : 0;
30681bb76ff1Sjsg 
30691bb76ff1Sjsg 	if (vblank_time < switch_limit)
30701bb76ff1Sjsg 		return true;
30711bb76ff1Sjsg 	else
30721bb76ff1Sjsg 		return false;
30731bb76ff1Sjsg 
30741bb76ff1Sjsg }
30751bb76ff1Sjsg 
ni_copy_and_switch_arb_sets(struct amdgpu_device * adev,u32 arb_freq_src,u32 arb_freq_dest)30761bb76ff1Sjsg static int ni_copy_and_switch_arb_sets(struct amdgpu_device *adev,
30771bb76ff1Sjsg 				u32 arb_freq_src, u32 arb_freq_dest)
30781bb76ff1Sjsg {
30791bb76ff1Sjsg 	u32 mc_arb_dram_timing;
30801bb76ff1Sjsg 	u32 mc_arb_dram_timing2;
30811bb76ff1Sjsg 	u32 burst_time;
30821bb76ff1Sjsg 	u32 mc_cg_config;
30831bb76ff1Sjsg 
30841bb76ff1Sjsg 	switch (arb_freq_src) {
30851bb76ff1Sjsg 	case MC_CG_ARB_FREQ_F0:
30861bb76ff1Sjsg 		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING);
30871bb76ff1Sjsg 		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
30881bb76ff1Sjsg 		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE0_MASK) >> STATE0_SHIFT;
30891bb76ff1Sjsg 		break;
30901bb76ff1Sjsg 	case MC_CG_ARB_FREQ_F1:
30911bb76ff1Sjsg 		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING_1);
30921bb76ff1Sjsg 		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_1);
30931bb76ff1Sjsg 		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE1_MASK) >> STATE1_SHIFT;
30941bb76ff1Sjsg 		break;
30951bb76ff1Sjsg 	case MC_CG_ARB_FREQ_F2:
30961bb76ff1Sjsg 		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING_2);
30971bb76ff1Sjsg 		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_2);
30981bb76ff1Sjsg 		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE2_MASK) >> STATE2_SHIFT;
30991bb76ff1Sjsg 		break;
31001bb76ff1Sjsg 	case MC_CG_ARB_FREQ_F3:
31011bb76ff1Sjsg 		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING_3);
31021bb76ff1Sjsg 		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_3);
31031bb76ff1Sjsg 		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE3_MASK) >> STATE3_SHIFT;
31041bb76ff1Sjsg 		break;
31051bb76ff1Sjsg 	default:
31061bb76ff1Sjsg 		return -EINVAL;
31071bb76ff1Sjsg 	}
31081bb76ff1Sjsg 
31091bb76ff1Sjsg 	switch (arb_freq_dest) {
31101bb76ff1Sjsg 	case MC_CG_ARB_FREQ_F0:
31111bb76ff1Sjsg 		WREG32(MC_ARB_DRAM_TIMING, mc_arb_dram_timing);
31121bb76ff1Sjsg 		WREG32(MC_ARB_DRAM_TIMING2, mc_arb_dram_timing2);
31131bb76ff1Sjsg 		WREG32_P(MC_ARB_BURST_TIME, STATE0(burst_time), ~STATE0_MASK);
31141bb76ff1Sjsg 		break;
31151bb76ff1Sjsg 	case MC_CG_ARB_FREQ_F1:
31161bb76ff1Sjsg 		WREG32(MC_ARB_DRAM_TIMING_1, mc_arb_dram_timing);
31171bb76ff1Sjsg 		WREG32(MC_ARB_DRAM_TIMING2_1, mc_arb_dram_timing2);
31181bb76ff1Sjsg 		WREG32_P(MC_ARB_BURST_TIME, STATE1(burst_time), ~STATE1_MASK);
31191bb76ff1Sjsg 		break;
31201bb76ff1Sjsg 	case MC_CG_ARB_FREQ_F2:
31211bb76ff1Sjsg 		WREG32(MC_ARB_DRAM_TIMING_2, mc_arb_dram_timing);
31221bb76ff1Sjsg 		WREG32(MC_ARB_DRAM_TIMING2_2, mc_arb_dram_timing2);
31231bb76ff1Sjsg 		WREG32_P(MC_ARB_BURST_TIME, STATE2(burst_time), ~STATE2_MASK);
31241bb76ff1Sjsg 		break;
31251bb76ff1Sjsg 	case MC_CG_ARB_FREQ_F3:
31261bb76ff1Sjsg 		WREG32(MC_ARB_DRAM_TIMING_3, mc_arb_dram_timing);
31271bb76ff1Sjsg 		WREG32(MC_ARB_DRAM_TIMING2_3, mc_arb_dram_timing2);
31281bb76ff1Sjsg 		WREG32_P(MC_ARB_BURST_TIME, STATE3(burst_time), ~STATE3_MASK);
31291bb76ff1Sjsg 		break;
31301bb76ff1Sjsg 	default:
31311bb76ff1Sjsg 		return -EINVAL;
31321bb76ff1Sjsg 	}
31331bb76ff1Sjsg 
31341bb76ff1Sjsg 	mc_cg_config = RREG32(MC_CG_CONFIG) | 0x0000000F;
31351bb76ff1Sjsg 	WREG32(MC_CG_CONFIG, mc_cg_config);
31361bb76ff1Sjsg 	WREG32_P(MC_ARB_CG, CG_ARB_REQ(arb_freq_dest), ~CG_ARB_REQ_MASK);
31371bb76ff1Sjsg 
31381bb76ff1Sjsg 	return 0;
31391bb76ff1Sjsg }
31401bb76ff1Sjsg 
ni_update_current_ps(struct amdgpu_device * adev,struct amdgpu_ps * rps)31411bb76ff1Sjsg static void ni_update_current_ps(struct amdgpu_device *adev,
31421bb76ff1Sjsg 			  struct amdgpu_ps *rps)
31431bb76ff1Sjsg {
31441bb76ff1Sjsg 	struct si_ps *new_ps = si_get_ps(rps);
31451bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
31461bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
31471bb76ff1Sjsg 
31481bb76ff1Sjsg 	eg_pi->current_rps = *rps;
31491bb76ff1Sjsg 	ni_pi->current_ps = *new_ps;
31501bb76ff1Sjsg 	eg_pi->current_rps.ps_priv = &ni_pi->current_ps;
31511bb76ff1Sjsg 	adev->pm.dpm.current_ps = &eg_pi->current_rps;
31521bb76ff1Sjsg }
31531bb76ff1Sjsg 
ni_update_requested_ps(struct amdgpu_device * adev,struct amdgpu_ps * rps)31541bb76ff1Sjsg static void ni_update_requested_ps(struct amdgpu_device *adev,
31551bb76ff1Sjsg 			    struct amdgpu_ps *rps)
31561bb76ff1Sjsg {
31571bb76ff1Sjsg 	struct si_ps *new_ps = si_get_ps(rps);
31581bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
31591bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
31601bb76ff1Sjsg 
31611bb76ff1Sjsg 	eg_pi->requested_rps = *rps;
31621bb76ff1Sjsg 	ni_pi->requested_ps = *new_ps;
31631bb76ff1Sjsg 	eg_pi->requested_rps.ps_priv = &ni_pi->requested_ps;
31641bb76ff1Sjsg 	adev->pm.dpm.requested_ps = &eg_pi->requested_rps;
31651bb76ff1Sjsg }
31661bb76ff1Sjsg 
ni_set_uvd_clock_before_set_eng_clock(struct amdgpu_device * adev,struct amdgpu_ps * new_ps,struct amdgpu_ps * old_ps)31671bb76ff1Sjsg static void ni_set_uvd_clock_before_set_eng_clock(struct amdgpu_device *adev,
31681bb76ff1Sjsg 					   struct amdgpu_ps *new_ps,
31691bb76ff1Sjsg 					   struct amdgpu_ps *old_ps)
31701bb76ff1Sjsg {
31711bb76ff1Sjsg 	struct si_ps *new_state = si_get_ps(new_ps);
31721bb76ff1Sjsg 	struct si_ps *current_state = si_get_ps(old_ps);
31731bb76ff1Sjsg 
31741bb76ff1Sjsg 	if ((new_ps->vclk == old_ps->vclk) &&
31751bb76ff1Sjsg 	    (new_ps->dclk == old_ps->dclk))
31761bb76ff1Sjsg 		return;
31771bb76ff1Sjsg 
31781bb76ff1Sjsg 	if (new_state->performance_levels[new_state->performance_level_count - 1].sclk >=
31791bb76ff1Sjsg 	    current_state->performance_levels[current_state->performance_level_count - 1].sclk)
31801bb76ff1Sjsg 		return;
31811bb76ff1Sjsg 
31821bb76ff1Sjsg 	amdgpu_asic_set_uvd_clocks(adev, new_ps->vclk, new_ps->dclk);
31831bb76ff1Sjsg }
31841bb76ff1Sjsg 
ni_set_uvd_clock_after_set_eng_clock(struct amdgpu_device * adev,struct amdgpu_ps * new_ps,struct amdgpu_ps * old_ps)31851bb76ff1Sjsg static void ni_set_uvd_clock_after_set_eng_clock(struct amdgpu_device *adev,
31861bb76ff1Sjsg 					  struct amdgpu_ps *new_ps,
31871bb76ff1Sjsg 					  struct amdgpu_ps *old_ps)
31881bb76ff1Sjsg {
31891bb76ff1Sjsg 	struct si_ps *new_state = si_get_ps(new_ps);
31901bb76ff1Sjsg 	struct si_ps *current_state = si_get_ps(old_ps);
31911bb76ff1Sjsg 
31921bb76ff1Sjsg 	if ((new_ps->vclk == old_ps->vclk) &&
31931bb76ff1Sjsg 	    (new_ps->dclk == old_ps->dclk))
31941bb76ff1Sjsg 		return;
31951bb76ff1Sjsg 
31961bb76ff1Sjsg 	if (new_state->performance_levels[new_state->performance_level_count - 1].sclk <
31971bb76ff1Sjsg 	    current_state->performance_levels[current_state->performance_level_count - 1].sclk)
31981bb76ff1Sjsg 		return;
31991bb76ff1Sjsg 
32001bb76ff1Sjsg 	amdgpu_asic_set_uvd_clocks(adev, new_ps->vclk, new_ps->dclk);
32011bb76ff1Sjsg }
32021bb76ff1Sjsg 
btc_find_voltage(struct atom_voltage_table * table,u16 voltage)32031bb76ff1Sjsg static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)
32041bb76ff1Sjsg {
32051bb76ff1Sjsg 	unsigned int i;
32061bb76ff1Sjsg 
32071bb76ff1Sjsg 	for (i = 0; i < table->count; i++)
32081bb76ff1Sjsg 		if (voltage <= table->entries[i].value)
32091bb76ff1Sjsg 			return table->entries[i].value;
32101bb76ff1Sjsg 
32111bb76ff1Sjsg 	return table->entries[table->count - 1].value;
32121bb76ff1Sjsg }
32131bb76ff1Sjsg 
btc_find_valid_clock(struct amdgpu_clock_array * clocks,u32 max_clock,u32 requested_clock)32141bb76ff1Sjsg static u32 btc_find_valid_clock(struct amdgpu_clock_array *clocks,
32151bb76ff1Sjsg 		                u32 max_clock, u32 requested_clock)
32161bb76ff1Sjsg {
32171bb76ff1Sjsg 	unsigned int i;
32181bb76ff1Sjsg 
32191bb76ff1Sjsg 	if ((clocks == NULL) || (clocks->count == 0))
32201bb76ff1Sjsg 		return (requested_clock < max_clock) ? requested_clock : max_clock;
32211bb76ff1Sjsg 
32221bb76ff1Sjsg 	for (i = 0; i < clocks->count; i++) {
32231bb76ff1Sjsg 		if (clocks->values[i] >= requested_clock)
32241bb76ff1Sjsg 			return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock;
32251bb76ff1Sjsg 	}
32261bb76ff1Sjsg 
32271bb76ff1Sjsg 	return (clocks->values[clocks->count - 1] < max_clock) ?
32281bb76ff1Sjsg 		clocks->values[clocks->count - 1] : max_clock;
32291bb76ff1Sjsg }
32301bb76ff1Sjsg 
btc_get_valid_mclk(struct amdgpu_device * adev,u32 max_mclk,u32 requested_mclk)32311bb76ff1Sjsg static u32 btc_get_valid_mclk(struct amdgpu_device *adev,
32321bb76ff1Sjsg 			      u32 max_mclk, u32 requested_mclk)
32331bb76ff1Sjsg {
32341bb76ff1Sjsg 	return btc_find_valid_clock(&adev->pm.dpm.dyn_state.valid_mclk_values,
32351bb76ff1Sjsg 				    max_mclk, requested_mclk);
32361bb76ff1Sjsg }
32371bb76ff1Sjsg 
btc_get_valid_sclk(struct amdgpu_device * adev,u32 max_sclk,u32 requested_sclk)32381bb76ff1Sjsg static u32 btc_get_valid_sclk(struct amdgpu_device *adev,
32391bb76ff1Sjsg 		              u32 max_sclk, u32 requested_sclk)
32401bb76ff1Sjsg {
32411bb76ff1Sjsg 	return btc_find_valid_clock(&adev->pm.dpm.dyn_state.valid_sclk_values,
32421bb76ff1Sjsg 				    max_sclk, requested_sclk);
32431bb76ff1Sjsg }
32441bb76ff1Sjsg 
btc_get_max_clock_from_voltage_dependency_table(struct amdgpu_clock_voltage_dependency_table * table,u32 * max_clock)32451bb76ff1Sjsg static void btc_get_max_clock_from_voltage_dependency_table(struct amdgpu_clock_voltage_dependency_table *table,
32461bb76ff1Sjsg 							    u32 *max_clock)
32471bb76ff1Sjsg {
32481bb76ff1Sjsg 	u32 i, clock = 0;
32491bb76ff1Sjsg 
32501bb76ff1Sjsg 	if ((table == NULL) || (table->count == 0)) {
32511bb76ff1Sjsg 		*max_clock = clock;
32521bb76ff1Sjsg 		return;
32531bb76ff1Sjsg 	}
32541bb76ff1Sjsg 
32551bb76ff1Sjsg 	for (i = 0; i < table->count; i++) {
32561bb76ff1Sjsg 		if (clock < table->entries[i].clk)
32571bb76ff1Sjsg 			clock = table->entries[i].clk;
32581bb76ff1Sjsg 	}
32591bb76ff1Sjsg 	*max_clock = clock;
32601bb76ff1Sjsg }
32611bb76ff1Sjsg 
btc_apply_voltage_dependency_rules(struct amdgpu_clock_voltage_dependency_table * table,u32 clock,u16 max_voltage,u16 * voltage)32621bb76ff1Sjsg static void btc_apply_voltage_dependency_rules(struct amdgpu_clock_voltage_dependency_table *table,
32631bb76ff1Sjsg 					       u32 clock, u16 max_voltage, u16 *voltage)
32641bb76ff1Sjsg {
32651bb76ff1Sjsg 	u32 i;
32661bb76ff1Sjsg 
32671bb76ff1Sjsg 	if ((table == NULL) || (table->count == 0))
32681bb76ff1Sjsg 		return;
32691bb76ff1Sjsg 
32701bb76ff1Sjsg 	for (i= 0; i < table->count; i++) {
32711bb76ff1Sjsg 		if (clock <= table->entries[i].clk) {
32721bb76ff1Sjsg 			if (*voltage < table->entries[i].v)
32731bb76ff1Sjsg 				*voltage = (u16)((table->entries[i].v < max_voltage) ?
32741bb76ff1Sjsg 					   table->entries[i].v : max_voltage);
32751bb76ff1Sjsg 			return;
32761bb76ff1Sjsg 		}
32771bb76ff1Sjsg 	}
32781bb76ff1Sjsg 
32791bb76ff1Sjsg 	*voltage = (*voltage > max_voltage) ? *voltage : max_voltage;
32801bb76ff1Sjsg }
32811bb76ff1Sjsg 
btc_adjust_clock_combinations(struct amdgpu_device * adev,const struct amdgpu_clock_and_voltage_limits * max_limits,struct rv7xx_pl * pl)32821bb76ff1Sjsg static void btc_adjust_clock_combinations(struct amdgpu_device *adev,
32831bb76ff1Sjsg 					  const struct amdgpu_clock_and_voltage_limits *max_limits,
32841bb76ff1Sjsg 					  struct rv7xx_pl *pl)
32851bb76ff1Sjsg {
32861bb76ff1Sjsg 
32871bb76ff1Sjsg 	if ((pl->mclk == 0) || (pl->sclk == 0))
32881bb76ff1Sjsg 		return;
32891bb76ff1Sjsg 
32901bb76ff1Sjsg 	if (pl->mclk == pl->sclk)
32911bb76ff1Sjsg 		return;
32921bb76ff1Sjsg 
32931bb76ff1Sjsg 	if (pl->mclk > pl->sclk) {
32941bb76ff1Sjsg 		if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > adev->pm.dpm.dyn_state.mclk_sclk_ratio)
32951bb76ff1Sjsg 			pl->sclk = btc_get_valid_sclk(adev,
32961bb76ff1Sjsg 						      max_limits->sclk,
32971bb76ff1Sjsg 						      (pl->mclk +
32981bb76ff1Sjsg 						      (adev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) /
32991bb76ff1Sjsg 						      adev->pm.dpm.dyn_state.mclk_sclk_ratio);
33001bb76ff1Sjsg 	} else {
33011bb76ff1Sjsg 		if ((pl->sclk - pl->mclk) > adev->pm.dpm.dyn_state.sclk_mclk_delta)
33021bb76ff1Sjsg 			pl->mclk = btc_get_valid_mclk(adev,
33031bb76ff1Sjsg 						      max_limits->mclk,
33041bb76ff1Sjsg 						      pl->sclk -
33051bb76ff1Sjsg 						      adev->pm.dpm.dyn_state.sclk_mclk_delta);
33061bb76ff1Sjsg 	}
33071bb76ff1Sjsg }
33081bb76ff1Sjsg 
btc_apply_voltage_delta_rules(struct amdgpu_device * adev,u16 max_vddc,u16 max_vddci,u16 * vddc,u16 * vddci)33091bb76ff1Sjsg static void btc_apply_voltage_delta_rules(struct amdgpu_device *adev,
33101bb76ff1Sjsg 					  u16 max_vddc, u16 max_vddci,
33111bb76ff1Sjsg 					  u16 *vddc, u16 *vddci)
33121bb76ff1Sjsg {
33131bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
33141bb76ff1Sjsg 	u16 new_voltage;
33151bb76ff1Sjsg 
33161bb76ff1Sjsg 	if ((0 == *vddc) || (0 == *vddci))
33171bb76ff1Sjsg 		return;
33181bb76ff1Sjsg 
33191bb76ff1Sjsg 	if (*vddc > *vddci) {
33201bb76ff1Sjsg 		if ((*vddc - *vddci) > adev->pm.dpm.dyn_state.vddc_vddci_delta) {
33211bb76ff1Sjsg 			new_voltage = btc_find_voltage(&eg_pi->vddci_voltage_table,
33221bb76ff1Sjsg 						       (*vddc - adev->pm.dpm.dyn_state.vddc_vddci_delta));
33231bb76ff1Sjsg 			*vddci = (new_voltage < max_vddci) ? new_voltage : max_vddci;
33241bb76ff1Sjsg 		}
33251bb76ff1Sjsg 	} else {
33261bb76ff1Sjsg 		if ((*vddci - *vddc) > adev->pm.dpm.dyn_state.vddc_vddci_delta) {
33271bb76ff1Sjsg 			new_voltage = btc_find_voltage(&eg_pi->vddc_voltage_table,
33281bb76ff1Sjsg 						       (*vddci - adev->pm.dpm.dyn_state.vddc_vddci_delta));
33291bb76ff1Sjsg 			*vddc = (new_voltage < max_vddc) ? new_voltage : max_vddc;
33301bb76ff1Sjsg 		}
33311bb76ff1Sjsg 	}
33321bb76ff1Sjsg }
33331bb76ff1Sjsg 
r600_calculate_u_and_p(u32 i,u32 r_c,u32 p_b,u32 * p,u32 * u)33341bb76ff1Sjsg static void r600_calculate_u_and_p(u32 i, u32 r_c, u32 p_b,
33351bb76ff1Sjsg 			    u32 *p, u32 *u)
33361bb76ff1Sjsg {
33371bb76ff1Sjsg 	u32 b_c = 0;
33381bb76ff1Sjsg 	u32 i_c;
33391bb76ff1Sjsg 	u32 tmp;
33401bb76ff1Sjsg 
33411bb76ff1Sjsg 	i_c = (i * r_c) / 100;
33421bb76ff1Sjsg 	tmp = i_c >> p_b;
33431bb76ff1Sjsg 
33441bb76ff1Sjsg 	while (tmp) {
33451bb76ff1Sjsg 		b_c++;
33461bb76ff1Sjsg 		tmp >>= 1;
33471bb76ff1Sjsg 	}
33481bb76ff1Sjsg 
33491bb76ff1Sjsg 	*u = (b_c + 1) / 2;
33501bb76ff1Sjsg 	*p = i_c / (1 << (2 * (*u)));
33511bb76ff1Sjsg }
33521bb76ff1Sjsg 
r600_calculate_at(u32 t,u32 h,u32 fh,u32 fl,u32 * tl,u32 * th)33531bb76ff1Sjsg static int r600_calculate_at(u32 t, u32 h, u32 fh, u32 fl, u32 *tl, u32 *th)
33541bb76ff1Sjsg {
33551bb76ff1Sjsg 	u32 k, a, ah, al;
33561bb76ff1Sjsg 	u32 t1;
33571bb76ff1Sjsg 
33581bb76ff1Sjsg 	if ((fl == 0) || (fh == 0) || (fl > fh))
33591bb76ff1Sjsg 		return -EINVAL;
33601bb76ff1Sjsg 
33611bb76ff1Sjsg 	k = (100 * fh) / fl;
33621bb76ff1Sjsg 	t1 = (t * (k - 100));
33631bb76ff1Sjsg 	a = (1000 * (100 * h + t1)) / (10000 + (t1 / 100));
33641bb76ff1Sjsg 	a = (a + 5) / 10;
33651bb76ff1Sjsg 	ah = ((a * t) + 5000) / 10000;
33661bb76ff1Sjsg 	al = a - ah;
33671bb76ff1Sjsg 
33681bb76ff1Sjsg 	*th = t - ah;
33691bb76ff1Sjsg 	*tl = t + al;
33701bb76ff1Sjsg 
33711bb76ff1Sjsg 	return 0;
33721bb76ff1Sjsg }
33731bb76ff1Sjsg 
r600_is_uvd_state(u32 class,u32 class2)33741bb76ff1Sjsg static bool r600_is_uvd_state(u32 class, u32 class2)
33751bb76ff1Sjsg {
33761bb76ff1Sjsg 	if (class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
33771bb76ff1Sjsg 		return true;
33781bb76ff1Sjsg 	if (class & ATOM_PPLIB_CLASSIFICATION_HD2STATE)
33791bb76ff1Sjsg 		return true;
33801bb76ff1Sjsg 	if (class & ATOM_PPLIB_CLASSIFICATION_HDSTATE)
33811bb76ff1Sjsg 		return true;
33821bb76ff1Sjsg 	if (class & ATOM_PPLIB_CLASSIFICATION_SDSTATE)
33831bb76ff1Sjsg 		return true;
33841bb76ff1Sjsg 	if (class2 & ATOM_PPLIB_CLASSIFICATION2_MVC)
33851bb76ff1Sjsg 		return true;
33861bb76ff1Sjsg 	return false;
33871bb76ff1Sjsg }
33881bb76ff1Sjsg 
rv770_get_memory_module_index(struct amdgpu_device * adev)33891bb76ff1Sjsg static u8 rv770_get_memory_module_index(struct amdgpu_device *adev)
33901bb76ff1Sjsg {
33911bb76ff1Sjsg 	return (u8) ((RREG32(BIOS_SCRATCH_4) >> 16) & 0xff);
33921bb76ff1Sjsg }
33931bb76ff1Sjsg 
rv770_get_max_vddc(struct amdgpu_device * adev)33941bb76ff1Sjsg static void rv770_get_max_vddc(struct amdgpu_device *adev)
33951bb76ff1Sjsg {
33961bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
33971bb76ff1Sjsg 	u16 vddc;
33981bb76ff1Sjsg 
33991bb76ff1Sjsg 	if (amdgpu_atombios_get_max_vddc(adev, 0, 0, &vddc))
34001bb76ff1Sjsg 		pi->max_vddc = 0;
34011bb76ff1Sjsg 	else
34021bb76ff1Sjsg 		pi->max_vddc = vddc;
34031bb76ff1Sjsg }
34041bb76ff1Sjsg 
rv770_get_engine_memory_ss(struct amdgpu_device * adev)34051bb76ff1Sjsg static void rv770_get_engine_memory_ss(struct amdgpu_device *adev)
34061bb76ff1Sjsg {
34071bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
34081bb76ff1Sjsg 	struct amdgpu_atom_ss ss;
34091bb76ff1Sjsg 
34101bb76ff1Sjsg 	pi->sclk_ss = amdgpu_atombios_get_asic_ss_info(adev, &ss,
34111bb76ff1Sjsg 						       ASIC_INTERNAL_ENGINE_SS, 0);
34121bb76ff1Sjsg 	pi->mclk_ss = amdgpu_atombios_get_asic_ss_info(adev, &ss,
34131bb76ff1Sjsg 						       ASIC_INTERNAL_MEMORY_SS, 0);
34141bb76ff1Sjsg 
34151bb76ff1Sjsg 	if (pi->sclk_ss || pi->mclk_ss)
34161bb76ff1Sjsg 		pi->dynamic_ss = true;
34171bb76ff1Sjsg 	else
34181bb76ff1Sjsg 		pi->dynamic_ss = false;
34191bb76ff1Sjsg }
34201bb76ff1Sjsg 
34211bb76ff1Sjsg 
si_apply_state_adjust_rules(struct amdgpu_device * adev,struct amdgpu_ps * rps)34221bb76ff1Sjsg static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
34231bb76ff1Sjsg 					struct amdgpu_ps *rps)
34241bb76ff1Sjsg {
34251bb76ff1Sjsg 	struct  si_ps *ps = si_get_ps(rps);
34261bb76ff1Sjsg 	struct amdgpu_clock_and_voltage_limits *max_limits;
34271bb76ff1Sjsg 	bool disable_mclk_switching = false;
34281bb76ff1Sjsg 	bool disable_sclk_switching = false;
34291bb76ff1Sjsg 	u32 mclk, sclk;
34301bb76ff1Sjsg 	u16 vddc, vddci, min_vce_voltage = 0;
34311bb76ff1Sjsg 	u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;
34321bb76ff1Sjsg 	u32 max_sclk = 0, max_mclk = 0;
34331bb76ff1Sjsg 	int i;
34341bb76ff1Sjsg 
34351bb76ff1Sjsg 	if (adev->asic_type == CHIP_HAINAN) {
34361bb76ff1Sjsg 		if ((adev->pdev->revision == 0x81) ||
34371bb76ff1Sjsg 		    (adev->pdev->revision == 0xC3) ||
34381bb76ff1Sjsg 		    (adev->pdev->device == 0x6664) ||
34391bb76ff1Sjsg 		    (adev->pdev->device == 0x6665) ||
34401bb76ff1Sjsg 		    (adev->pdev->device == 0x6667)) {
34411bb76ff1Sjsg 			max_sclk = 75000;
34421bb76ff1Sjsg 		}
34431bb76ff1Sjsg 		if ((adev->pdev->revision == 0xC3) ||
34441bb76ff1Sjsg 		    (adev->pdev->device == 0x6665)) {
34451bb76ff1Sjsg 			max_sclk = 60000;
34461bb76ff1Sjsg 			max_mclk = 80000;
34471bb76ff1Sjsg 		}
34481bb76ff1Sjsg 	} else if (adev->asic_type == CHIP_OLAND) {
34491bb76ff1Sjsg 		if ((adev->pdev->revision == 0xC7) ||
34501bb76ff1Sjsg 		    (adev->pdev->revision == 0x80) ||
34511bb76ff1Sjsg 		    (adev->pdev->revision == 0x81) ||
34521bb76ff1Sjsg 		    (adev->pdev->revision == 0x83) ||
34531bb76ff1Sjsg 		    (adev->pdev->revision == 0x87) ||
34541bb76ff1Sjsg 		    (adev->pdev->device == 0x6604) ||
34551bb76ff1Sjsg 		    (adev->pdev->device == 0x6605)) {
34561bb76ff1Sjsg 			max_sclk = 75000;
34571bb76ff1Sjsg 		}
34581bb76ff1Sjsg 	}
34591bb76ff1Sjsg 
34601bb76ff1Sjsg 	if (rps->vce_active) {
34611bb76ff1Sjsg 		rps->evclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].evclk;
34621bb76ff1Sjsg 		rps->ecclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].ecclk;
34631bb76ff1Sjsg 		si_get_vce_clock_voltage(adev, rps->evclk, rps->ecclk,
34641bb76ff1Sjsg 					 &min_vce_voltage);
34651bb76ff1Sjsg 	} else {
34661bb76ff1Sjsg 		rps->evclk = 0;
34671bb76ff1Sjsg 		rps->ecclk = 0;
34681bb76ff1Sjsg 	}
34691bb76ff1Sjsg 
34701bb76ff1Sjsg 	if ((adev->pm.dpm.new_active_crtc_count > 1) ||
34711bb76ff1Sjsg 	    si_dpm_vblank_too_short(adev))
34721bb76ff1Sjsg 		disable_mclk_switching = true;
34731bb76ff1Sjsg 
34741bb76ff1Sjsg 	if (rps->vclk || rps->dclk) {
34751bb76ff1Sjsg 		disable_mclk_switching = true;
34761bb76ff1Sjsg 		disable_sclk_switching = true;
34771bb76ff1Sjsg 	}
34781bb76ff1Sjsg 
34791bb76ff1Sjsg 	if (adev->pm.ac_power)
34801bb76ff1Sjsg 		max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
34811bb76ff1Sjsg 	else
34821bb76ff1Sjsg 		max_limits = &adev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
34831bb76ff1Sjsg 
34841bb76ff1Sjsg 	for (i = ps->performance_level_count - 2; i >= 0; i--) {
34851bb76ff1Sjsg 		if (ps->performance_levels[i].vddc > ps->performance_levels[i+1].vddc)
34861bb76ff1Sjsg 			ps->performance_levels[i].vddc = ps->performance_levels[i+1].vddc;
34871bb76ff1Sjsg 	}
34881bb76ff1Sjsg 	if (adev->pm.ac_power == false) {
34891bb76ff1Sjsg 		for (i = 0; i < ps->performance_level_count; i++) {
34901bb76ff1Sjsg 			if (ps->performance_levels[i].mclk > max_limits->mclk)
34911bb76ff1Sjsg 				ps->performance_levels[i].mclk = max_limits->mclk;
34921bb76ff1Sjsg 			if (ps->performance_levels[i].sclk > max_limits->sclk)
34931bb76ff1Sjsg 				ps->performance_levels[i].sclk = max_limits->sclk;
34941bb76ff1Sjsg 			if (ps->performance_levels[i].vddc > max_limits->vddc)
34951bb76ff1Sjsg 				ps->performance_levels[i].vddc = max_limits->vddc;
34961bb76ff1Sjsg 			if (ps->performance_levels[i].vddci > max_limits->vddci)
34971bb76ff1Sjsg 				ps->performance_levels[i].vddci = max_limits->vddci;
34981bb76ff1Sjsg 		}
34991bb76ff1Sjsg 	}
35001bb76ff1Sjsg 
35011bb76ff1Sjsg 	/* limit clocks to max supported clocks based on voltage dependency tables */
35021bb76ff1Sjsg 	btc_get_max_clock_from_voltage_dependency_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
35031bb76ff1Sjsg 							&max_sclk_vddc);
35041bb76ff1Sjsg 	btc_get_max_clock_from_voltage_dependency_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
35051bb76ff1Sjsg 							&max_mclk_vddci);
35061bb76ff1Sjsg 	btc_get_max_clock_from_voltage_dependency_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
35071bb76ff1Sjsg 							&max_mclk_vddc);
35081bb76ff1Sjsg 
35091bb76ff1Sjsg 	for (i = 0; i < ps->performance_level_count; i++) {
35101bb76ff1Sjsg 		if (max_sclk_vddc) {
35111bb76ff1Sjsg 			if (ps->performance_levels[i].sclk > max_sclk_vddc)
35121bb76ff1Sjsg 				ps->performance_levels[i].sclk = max_sclk_vddc;
35131bb76ff1Sjsg 		}
35141bb76ff1Sjsg 		if (max_mclk_vddci) {
35151bb76ff1Sjsg 			if (ps->performance_levels[i].mclk > max_mclk_vddci)
35161bb76ff1Sjsg 				ps->performance_levels[i].mclk = max_mclk_vddci;
35171bb76ff1Sjsg 		}
35181bb76ff1Sjsg 		if (max_mclk_vddc) {
35191bb76ff1Sjsg 			if (ps->performance_levels[i].mclk > max_mclk_vddc)
35201bb76ff1Sjsg 				ps->performance_levels[i].mclk = max_mclk_vddc;
35211bb76ff1Sjsg 		}
35221bb76ff1Sjsg 		if (max_mclk) {
35231bb76ff1Sjsg 			if (ps->performance_levels[i].mclk > max_mclk)
35241bb76ff1Sjsg 				ps->performance_levels[i].mclk = max_mclk;
35251bb76ff1Sjsg 		}
35261bb76ff1Sjsg 		if (max_sclk) {
35271bb76ff1Sjsg 			if (ps->performance_levels[i].sclk > max_sclk)
35281bb76ff1Sjsg 				ps->performance_levels[i].sclk = max_sclk;
35291bb76ff1Sjsg 		}
35301bb76ff1Sjsg 	}
35311bb76ff1Sjsg 
35321bb76ff1Sjsg 	/* XXX validate the min clocks required for display */
35331bb76ff1Sjsg 
35341bb76ff1Sjsg 	if (disable_mclk_switching) {
35351bb76ff1Sjsg 		mclk  = ps->performance_levels[ps->performance_level_count - 1].mclk;
35361bb76ff1Sjsg 		vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
35371bb76ff1Sjsg 	} else {
35381bb76ff1Sjsg 		mclk = ps->performance_levels[0].mclk;
35391bb76ff1Sjsg 		vddci = ps->performance_levels[0].vddci;
35401bb76ff1Sjsg 	}
35411bb76ff1Sjsg 
35421bb76ff1Sjsg 	if (disable_sclk_switching) {
35431bb76ff1Sjsg 		sclk = ps->performance_levels[ps->performance_level_count - 1].sclk;
35441bb76ff1Sjsg 		vddc = ps->performance_levels[ps->performance_level_count - 1].vddc;
35451bb76ff1Sjsg 	} else {
35461bb76ff1Sjsg 		sclk = ps->performance_levels[0].sclk;
35471bb76ff1Sjsg 		vddc = ps->performance_levels[0].vddc;
35481bb76ff1Sjsg 	}
35491bb76ff1Sjsg 
35501bb76ff1Sjsg 	if (rps->vce_active) {
35511bb76ff1Sjsg 		if (sclk < adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].sclk)
35521bb76ff1Sjsg 			sclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].sclk;
35531bb76ff1Sjsg 		if (mclk < adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].mclk)
35541bb76ff1Sjsg 			mclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].mclk;
35551bb76ff1Sjsg 	}
35561bb76ff1Sjsg 
35571bb76ff1Sjsg 	/* adjusted low state */
35581bb76ff1Sjsg 	ps->performance_levels[0].sclk = sclk;
35591bb76ff1Sjsg 	ps->performance_levels[0].mclk = mclk;
35601bb76ff1Sjsg 	ps->performance_levels[0].vddc = vddc;
35611bb76ff1Sjsg 	ps->performance_levels[0].vddci = vddci;
35621bb76ff1Sjsg 
35631bb76ff1Sjsg 	if (disable_sclk_switching) {
35641bb76ff1Sjsg 		sclk = ps->performance_levels[0].sclk;
35651bb76ff1Sjsg 		for (i = 1; i < ps->performance_level_count; i++) {
35661bb76ff1Sjsg 			if (sclk < ps->performance_levels[i].sclk)
35671bb76ff1Sjsg 				sclk = ps->performance_levels[i].sclk;
35681bb76ff1Sjsg 		}
35691bb76ff1Sjsg 		for (i = 0; i < ps->performance_level_count; i++) {
35701bb76ff1Sjsg 			ps->performance_levels[i].sclk = sclk;
35711bb76ff1Sjsg 			ps->performance_levels[i].vddc = vddc;
35721bb76ff1Sjsg 		}
35731bb76ff1Sjsg 	} else {
35741bb76ff1Sjsg 		for (i = 1; i < ps->performance_level_count; i++) {
35751bb76ff1Sjsg 			if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
35761bb76ff1Sjsg 				ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
35771bb76ff1Sjsg 			if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
35781bb76ff1Sjsg 				ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
35791bb76ff1Sjsg 		}
35801bb76ff1Sjsg 	}
35811bb76ff1Sjsg 
35821bb76ff1Sjsg 	if (disable_mclk_switching) {
35831bb76ff1Sjsg 		mclk = ps->performance_levels[0].mclk;
35841bb76ff1Sjsg 		for (i = 1; i < ps->performance_level_count; i++) {
35851bb76ff1Sjsg 			if (mclk < ps->performance_levels[i].mclk)
35861bb76ff1Sjsg 				mclk = ps->performance_levels[i].mclk;
35871bb76ff1Sjsg 		}
35881bb76ff1Sjsg 		for (i = 0; i < ps->performance_level_count; i++) {
35891bb76ff1Sjsg 			ps->performance_levels[i].mclk = mclk;
35901bb76ff1Sjsg 			ps->performance_levels[i].vddci = vddci;
35911bb76ff1Sjsg 		}
35921bb76ff1Sjsg 	} else {
35931bb76ff1Sjsg 		for (i = 1; i < ps->performance_level_count; i++) {
35941bb76ff1Sjsg 			if (ps->performance_levels[i].mclk < ps->performance_levels[i - 1].mclk)
35951bb76ff1Sjsg 				ps->performance_levels[i].mclk = ps->performance_levels[i - 1].mclk;
35961bb76ff1Sjsg 			if (ps->performance_levels[i].vddci < ps->performance_levels[i - 1].vddci)
35971bb76ff1Sjsg 				ps->performance_levels[i].vddci = ps->performance_levels[i - 1].vddci;
35981bb76ff1Sjsg 		}
35991bb76ff1Sjsg 	}
36001bb76ff1Sjsg 
36011bb76ff1Sjsg 	for (i = 0; i < ps->performance_level_count; i++)
36021bb76ff1Sjsg 		btc_adjust_clock_combinations(adev, max_limits,
36031bb76ff1Sjsg 					      &ps->performance_levels[i]);
36041bb76ff1Sjsg 
36051bb76ff1Sjsg 	for (i = 0; i < ps->performance_level_count; i++) {
36061bb76ff1Sjsg 		if (ps->performance_levels[i].vddc < min_vce_voltage)
36071bb76ff1Sjsg 			ps->performance_levels[i].vddc = min_vce_voltage;
36081bb76ff1Sjsg 		btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
36091bb76ff1Sjsg 						   ps->performance_levels[i].sclk,
36101bb76ff1Sjsg 						   max_limits->vddc,  &ps->performance_levels[i].vddc);
36111bb76ff1Sjsg 		btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
36121bb76ff1Sjsg 						   ps->performance_levels[i].mclk,
36131bb76ff1Sjsg 						   max_limits->vddci, &ps->performance_levels[i].vddci);
36141bb76ff1Sjsg 		btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
36151bb76ff1Sjsg 						   ps->performance_levels[i].mclk,
36161bb76ff1Sjsg 						   max_limits->vddc,  &ps->performance_levels[i].vddc);
36171bb76ff1Sjsg 		btc_apply_voltage_dependency_rules(&adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
36181bb76ff1Sjsg 						   adev->clock.current_dispclk,
36191bb76ff1Sjsg 						   max_limits->vddc,  &ps->performance_levels[i].vddc);
36201bb76ff1Sjsg 	}
36211bb76ff1Sjsg 
36221bb76ff1Sjsg 	for (i = 0; i < ps->performance_level_count; i++) {
36231bb76ff1Sjsg 		btc_apply_voltage_delta_rules(adev,
36241bb76ff1Sjsg 					      max_limits->vddc, max_limits->vddci,
36251bb76ff1Sjsg 					      &ps->performance_levels[i].vddc,
36261bb76ff1Sjsg 					      &ps->performance_levels[i].vddci);
36271bb76ff1Sjsg 	}
36281bb76ff1Sjsg 
36291bb76ff1Sjsg 	ps->dc_compatible = true;
36301bb76ff1Sjsg 	for (i = 0; i < ps->performance_level_count; i++) {
36311bb76ff1Sjsg 		if (ps->performance_levels[i].vddc > adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc)
36321bb76ff1Sjsg 			ps->dc_compatible = false;
36331bb76ff1Sjsg 	}
36341bb76ff1Sjsg }
36351bb76ff1Sjsg 
36361bb76ff1Sjsg #if 0
36371bb76ff1Sjsg static int si_read_smc_soft_register(struct amdgpu_device *adev,
36381bb76ff1Sjsg 				     u16 reg_offset, u32 *value)
36391bb76ff1Sjsg {
36401bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
36411bb76ff1Sjsg 
36421bb76ff1Sjsg 	return amdgpu_si_read_smc_sram_dword(adev,
36431bb76ff1Sjsg 					     si_pi->soft_regs_start + reg_offset, value,
36441bb76ff1Sjsg 					     si_pi->sram_end);
36451bb76ff1Sjsg }
36461bb76ff1Sjsg #endif
36471bb76ff1Sjsg 
si_write_smc_soft_register(struct amdgpu_device * adev,u16 reg_offset,u32 value)36481bb76ff1Sjsg static int si_write_smc_soft_register(struct amdgpu_device *adev,
36491bb76ff1Sjsg 				      u16 reg_offset, u32 value)
36501bb76ff1Sjsg {
36511bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
36521bb76ff1Sjsg 
36531bb76ff1Sjsg 	return amdgpu_si_write_smc_sram_dword(adev,
36541bb76ff1Sjsg 					      si_pi->soft_regs_start + reg_offset,
36551bb76ff1Sjsg 					      value, si_pi->sram_end);
36561bb76ff1Sjsg }
36571bb76ff1Sjsg 
si_is_special_1gb_platform(struct amdgpu_device * adev)36581bb76ff1Sjsg static bool si_is_special_1gb_platform(struct amdgpu_device *adev)
36591bb76ff1Sjsg {
36601bb76ff1Sjsg 	bool ret = false;
36611bb76ff1Sjsg 	u32 tmp, width, row, column, bank, density;
36621bb76ff1Sjsg 	bool is_memory_gddr5, is_special;
36631bb76ff1Sjsg 
36641bb76ff1Sjsg 	tmp = RREG32(MC_SEQ_MISC0);
36651bb76ff1Sjsg 	is_memory_gddr5 = (MC_SEQ_MISC0_GDDR5_VALUE == ((tmp & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT));
36661bb76ff1Sjsg 	is_special = (MC_SEQ_MISC0_REV_ID_VALUE == ((tmp & MC_SEQ_MISC0_REV_ID_MASK) >> MC_SEQ_MISC0_REV_ID_SHIFT))
36671bb76ff1Sjsg 		& (MC_SEQ_MISC0_VEN_ID_VALUE == ((tmp & MC_SEQ_MISC0_VEN_ID_MASK) >> MC_SEQ_MISC0_VEN_ID_SHIFT));
36681bb76ff1Sjsg 
36691bb76ff1Sjsg 	WREG32(MC_SEQ_IO_DEBUG_INDEX, 0xb);
36701bb76ff1Sjsg 	width = ((RREG32(MC_SEQ_IO_DEBUG_DATA) >> 1) & 1) ? 16 : 32;
36711bb76ff1Sjsg 
36721bb76ff1Sjsg 	tmp = RREG32(MC_ARB_RAMCFG);
36731bb76ff1Sjsg 	row = ((tmp & NOOFROWS_MASK) >> NOOFROWS_SHIFT) + 10;
36741bb76ff1Sjsg 	column = ((tmp & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT) + 8;
36751bb76ff1Sjsg 	bank = ((tmp & NOOFBANK_MASK) >> NOOFBANK_SHIFT) + 2;
36761bb76ff1Sjsg 
36771bb76ff1Sjsg 	density = (1 << (row + column - 20 + bank)) * width;
36781bb76ff1Sjsg 
36791bb76ff1Sjsg 	if ((adev->pdev->device == 0x6819) &&
36801bb76ff1Sjsg 	    is_memory_gddr5 && is_special && (density == 0x400))
36811bb76ff1Sjsg 		ret = true;
36821bb76ff1Sjsg 
36831bb76ff1Sjsg 	return ret;
36841bb76ff1Sjsg }
36851bb76ff1Sjsg 
si_get_leakage_vddc(struct amdgpu_device * adev)36861bb76ff1Sjsg static void si_get_leakage_vddc(struct amdgpu_device *adev)
36871bb76ff1Sjsg {
36881bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
36891bb76ff1Sjsg 	u16 vddc, count = 0;
36901bb76ff1Sjsg 	int i, ret;
36911bb76ff1Sjsg 
36921bb76ff1Sjsg 	for (i = 0; i < SISLANDS_MAX_LEAKAGE_COUNT; i++) {
36931bb76ff1Sjsg 		ret = amdgpu_atombios_get_leakage_vddc_based_on_leakage_idx(adev, &vddc, SISLANDS_LEAKAGE_INDEX0 + i);
36941bb76ff1Sjsg 
36951bb76ff1Sjsg 		if (!ret && (vddc > 0) && (vddc != (SISLANDS_LEAKAGE_INDEX0 + i))) {
36961bb76ff1Sjsg 			si_pi->leakage_voltage.entries[count].voltage = vddc;
36971bb76ff1Sjsg 			si_pi->leakage_voltage.entries[count].leakage_index =
36981bb76ff1Sjsg 				SISLANDS_LEAKAGE_INDEX0 + i;
36991bb76ff1Sjsg 			count++;
37001bb76ff1Sjsg 		}
37011bb76ff1Sjsg 	}
37021bb76ff1Sjsg 	si_pi->leakage_voltage.count = count;
37031bb76ff1Sjsg }
37041bb76ff1Sjsg 
si_get_leakage_voltage_from_leakage_index(struct amdgpu_device * adev,u32 index,u16 * leakage_voltage)37051bb76ff1Sjsg static int si_get_leakage_voltage_from_leakage_index(struct amdgpu_device *adev,
37061bb76ff1Sjsg 						     u32 index, u16 *leakage_voltage)
37071bb76ff1Sjsg {
37081bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
37091bb76ff1Sjsg 	int i;
37101bb76ff1Sjsg 
37111bb76ff1Sjsg 	if (leakage_voltage == NULL)
37121bb76ff1Sjsg 		return -EINVAL;
37131bb76ff1Sjsg 
37141bb76ff1Sjsg 	if ((index & 0xff00) != 0xff00)
37151bb76ff1Sjsg 		return -EINVAL;
37161bb76ff1Sjsg 
37171bb76ff1Sjsg 	if ((index & 0xff) > SISLANDS_MAX_LEAKAGE_COUNT + 1)
37181bb76ff1Sjsg 		return -EINVAL;
37191bb76ff1Sjsg 
37201bb76ff1Sjsg 	if (index < SISLANDS_LEAKAGE_INDEX0)
37211bb76ff1Sjsg 		return -EINVAL;
37221bb76ff1Sjsg 
37231bb76ff1Sjsg 	for (i = 0; i < si_pi->leakage_voltage.count; i++) {
37241bb76ff1Sjsg 		if (si_pi->leakage_voltage.entries[i].leakage_index == index) {
37251bb76ff1Sjsg 			*leakage_voltage = si_pi->leakage_voltage.entries[i].voltage;
37261bb76ff1Sjsg 			return 0;
37271bb76ff1Sjsg 		}
37281bb76ff1Sjsg 	}
37291bb76ff1Sjsg 	return -EAGAIN;
37301bb76ff1Sjsg }
37311bb76ff1Sjsg 
si_set_dpm_event_sources(struct amdgpu_device * adev,u32 sources)37321bb76ff1Sjsg static void si_set_dpm_event_sources(struct amdgpu_device *adev, u32 sources)
37331bb76ff1Sjsg {
37341bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
37351bb76ff1Sjsg 	bool want_thermal_protection;
37361bb76ff1Sjsg 	enum si_dpm_event_src dpm_event_src;
37371bb76ff1Sjsg 
37381bb76ff1Sjsg 	switch (sources) {
37391bb76ff1Sjsg 	case 0:
37401bb76ff1Sjsg 	default:
37411bb76ff1Sjsg 		want_thermal_protection = false;
37421bb76ff1Sjsg 		break;
37431bb76ff1Sjsg 	case (1 << SI_DPM_AUTO_THROTTLE_SRC_THERMAL):
37441bb76ff1Sjsg 		want_thermal_protection = true;
37451bb76ff1Sjsg 		dpm_event_src = SI_DPM_EVENT_SRC_DIGITAL;
37461bb76ff1Sjsg 		break;
37471bb76ff1Sjsg 	case (1 << SI_DPM_AUTO_THROTTLE_SRC_EXTERNAL):
37481bb76ff1Sjsg 		want_thermal_protection = true;
37491bb76ff1Sjsg 		dpm_event_src = SI_DPM_EVENT_SRC_EXTERNAL;
37501bb76ff1Sjsg 		break;
37511bb76ff1Sjsg 	case ((1 << SI_DPM_AUTO_THROTTLE_SRC_EXTERNAL) |
37521bb76ff1Sjsg 	      (1 << SI_DPM_AUTO_THROTTLE_SRC_THERMAL)):
37531bb76ff1Sjsg 		want_thermal_protection = true;
37541bb76ff1Sjsg 		dpm_event_src = SI_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL;
37551bb76ff1Sjsg 		break;
37561bb76ff1Sjsg 	}
37571bb76ff1Sjsg 
37581bb76ff1Sjsg 	if (want_thermal_protection) {
37591bb76ff1Sjsg 		WREG32_P(CG_THERMAL_CTRL, DPM_EVENT_SRC(dpm_event_src), ~DPM_EVENT_SRC_MASK);
37601bb76ff1Sjsg 		if (pi->thermal_protection)
37611bb76ff1Sjsg 			WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
37621bb76ff1Sjsg 	} else {
37631bb76ff1Sjsg 		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
37641bb76ff1Sjsg 	}
37651bb76ff1Sjsg }
37661bb76ff1Sjsg 
si_enable_auto_throttle_source(struct amdgpu_device * adev,enum si_dpm_auto_throttle_src source,bool enable)37671bb76ff1Sjsg static void si_enable_auto_throttle_source(struct amdgpu_device *adev,
37681bb76ff1Sjsg 					   enum si_dpm_auto_throttle_src source,
37691bb76ff1Sjsg 					   bool enable)
37701bb76ff1Sjsg {
37711bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
37721bb76ff1Sjsg 
37731bb76ff1Sjsg 	if (enable) {
37741bb76ff1Sjsg 		if (!(pi->active_auto_throttle_sources & (1 << source))) {
37751bb76ff1Sjsg 			pi->active_auto_throttle_sources |= 1 << source;
37761bb76ff1Sjsg 			si_set_dpm_event_sources(adev, pi->active_auto_throttle_sources);
37771bb76ff1Sjsg 		}
37781bb76ff1Sjsg 	} else {
37791bb76ff1Sjsg 		if (pi->active_auto_throttle_sources & (1 << source)) {
37801bb76ff1Sjsg 			pi->active_auto_throttle_sources &= ~(1 << source);
37811bb76ff1Sjsg 			si_set_dpm_event_sources(adev, pi->active_auto_throttle_sources);
37821bb76ff1Sjsg 		}
37831bb76ff1Sjsg 	}
37841bb76ff1Sjsg }
37851bb76ff1Sjsg 
si_start_dpm(struct amdgpu_device * adev)37861bb76ff1Sjsg static void si_start_dpm(struct amdgpu_device *adev)
37871bb76ff1Sjsg {
37881bb76ff1Sjsg 	WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
37891bb76ff1Sjsg }
37901bb76ff1Sjsg 
si_stop_dpm(struct amdgpu_device * adev)37911bb76ff1Sjsg static void si_stop_dpm(struct amdgpu_device *adev)
37921bb76ff1Sjsg {
37931bb76ff1Sjsg 	WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
37941bb76ff1Sjsg }
37951bb76ff1Sjsg 
si_enable_sclk_control(struct amdgpu_device * adev,bool enable)37961bb76ff1Sjsg static void si_enable_sclk_control(struct amdgpu_device *adev, bool enable)
37971bb76ff1Sjsg {
37981bb76ff1Sjsg 	if (enable)
37991bb76ff1Sjsg 		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
38001bb76ff1Sjsg 	else
38011bb76ff1Sjsg 		WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
38021bb76ff1Sjsg 
38031bb76ff1Sjsg }
38041bb76ff1Sjsg 
38051bb76ff1Sjsg #if 0
38061bb76ff1Sjsg static int si_notify_hardware_of_thermal_state(struct amdgpu_device *adev,
38071bb76ff1Sjsg 					       u32 thermal_level)
38081bb76ff1Sjsg {
38091bb76ff1Sjsg 	PPSMC_Result ret;
38101bb76ff1Sjsg 
38111bb76ff1Sjsg 	if (thermal_level == 0) {
38121bb76ff1Sjsg 		ret = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableThermalInterrupt);
38131bb76ff1Sjsg 		if (ret == PPSMC_Result_OK)
38141bb76ff1Sjsg 			return 0;
38151bb76ff1Sjsg 		else
38161bb76ff1Sjsg 			return -EINVAL;
38171bb76ff1Sjsg 	}
38181bb76ff1Sjsg 	return 0;
38191bb76ff1Sjsg }
38201bb76ff1Sjsg 
38211bb76ff1Sjsg static void si_notify_hardware_vpu_recovery_event(struct amdgpu_device *adev)
38221bb76ff1Sjsg {
38231bb76ff1Sjsg 	si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_tdr_is_about_to_happen, true);
38241bb76ff1Sjsg }
38251bb76ff1Sjsg #endif
38261bb76ff1Sjsg 
38271bb76ff1Sjsg #if 0
38281bb76ff1Sjsg static int si_notify_hw_of_powersource(struct amdgpu_device *adev, bool ac_power)
38291bb76ff1Sjsg {
38301bb76ff1Sjsg 	if (ac_power)
38311bb76ff1Sjsg 		return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_RunningOnAC) == PPSMC_Result_OK) ?
38321bb76ff1Sjsg 			0 : -EINVAL;
38331bb76ff1Sjsg 
38341bb76ff1Sjsg 	return 0;
38351bb76ff1Sjsg }
38361bb76ff1Sjsg #endif
38371bb76ff1Sjsg 
si_send_msg_to_smc_with_parameter(struct amdgpu_device * adev,PPSMC_Msg msg,u32 parameter)38381bb76ff1Sjsg static PPSMC_Result si_send_msg_to_smc_with_parameter(struct amdgpu_device *adev,
38391bb76ff1Sjsg 						      PPSMC_Msg msg, u32 parameter)
38401bb76ff1Sjsg {
38411bb76ff1Sjsg 	WREG32(SMC_SCRATCH0, parameter);
38421bb76ff1Sjsg 	return amdgpu_si_send_msg_to_smc(adev, msg);
38431bb76ff1Sjsg }
38441bb76ff1Sjsg 
si_restrict_performance_levels_before_switch(struct amdgpu_device * adev)38451bb76ff1Sjsg static int si_restrict_performance_levels_before_switch(struct amdgpu_device *adev)
38461bb76ff1Sjsg {
38471bb76ff1Sjsg 	if (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
38481bb76ff1Sjsg 		return -EINVAL;
38491bb76ff1Sjsg 
38501bb76ff1Sjsg 	return (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, 1) == PPSMC_Result_OK) ?
38511bb76ff1Sjsg 		0 : -EINVAL;
38521bb76ff1Sjsg }
38531bb76ff1Sjsg 
si_dpm_force_performance_level(void * handle,enum amd_dpm_forced_level level)38541bb76ff1Sjsg static int si_dpm_force_performance_level(void *handle,
38551bb76ff1Sjsg 				   enum amd_dpm_forced_level level)
38561bb76ff1Sjsg {
38571bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
38581bb76ff1Sjsg 	struct amdgpu_ps *rps = adev->pm.dpm.current_ps;
38591bb76ff1Sjsg 	struct  si_ps *ps = si_get_ps(rps);
38601bb76ff1Sjsg 	u32 levels = ps->performance_level_count;
38611bb76ff1Sjsg 
38621bb76ff1Sjsg 	if (level == AMD_DPM_FORCED_LEVEL_HIGH) {
38631bb76ff1Sjsg 		if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK)
38641bb76ff1Sjsg 			return -EINVAL;
38651bb76ff1Sjsg 
38661bb76ff1Sjsg 		if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK)
38671bb76ff1Sjsg 			return -EINVAL;
38681bb76ff1Sjsg 	} else if (level == AMD_DPM_FORCED_LEVEL_LOW) {
38691bb76ff1Sjsg 		if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
38701bb76ff1Sjsg 			return -EINVAL;
38711bb76ff1Sjsg 
38721bb76ff1Sjsg 		if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK)
38731bb76ff1Sjsg 			return -EINVAL;
38741bb76ff1Sjsg 	} else if (level == AMD_DPM_FORCED_LEVEL_AUTO) {
38751bb76ff1Sjsg 		if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
38761bb76ff1Sjsg 			return -EINVAL;
38771bb76ff1Sjsg 
38781bb76ff1Sjsg 		if (si_send_msg_to_smc_with_parameter(adev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK)
38791bb76ff1Sjsg 			return -EINVAL;
38801bb76ff1Sjsg 	}
38811bb76ff1Sjsg 
38821bb76ff1Sjsg 	adev->pm.dpm.forced_level = level;
38831bb76ff1Sjsg 
38841bb76ff1Sjsg 	return 0;
38851bb76ff1Sjsg }
38861bb76ff1Sjsg 
38871bb76ff1Sjsg #if 0
38881bb76ff1Sjsg static int si_set_boot_state(struct amdgpu_device *adev)
38891bb76ff1Sjsg {
38901bb76ff1Sjsg 	return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_SwitchToInitialState) == PPSMC_Result_OK) ?
38911bb76ff1Sjsg 		0 : -EINVAL;
38921bb76ff1Sjsg }
38931bb76ff1Sjsg #endif
38941bb76ff1Sjsg 
si_set_sw_state(struct amdgpu_device * adev)38951bb76ff1Sjsg static int si_set_sw_state(struct amdgpu_device *adev)
38961bb76ff1Sjsg {
38971bb76ff1Sjsg 	return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_SwitchToSwState) == PPSMC_Result_OK) ?
38981bb76ff1Sjsg 		0 : -EINVAL;
38991bb76ff1Sjsg }
39001bb76ff1Sjsg 
si_halt_smc(struct amdgpu_device * adev)39011bb76ff1Sjsg static int si_halt_smc(struct amdgpu_device *adev)
39021bb76ff1Sjsg {
39031bb76ff1Sjsg 	if (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_Halt) != PPSMC_Result_OK)
39041bb76ff1Sjsg 		return -EINVAL;
39051bb76ff1Sjsg 
39061bb76ff1Sjsg 	return (amdgpu_si_wait_for_smc_inactive(adev) == PPSMC_Result_OK) ?
39071bb76ff1Sjsg 		0 : -EINVAL;
39081bb76ff1Sjsg }
39091bb76ff1Sjsg 
si_resume_smc(struct amdgpu_device * adev)39101bb76ff1Sjsg static int si_resume_smc(struct amdgpu_device *adev)
39111bb76ff1Sjsg {
39121bb76ff1Sjsg 	if (amdgpu_si_send_msg_to_smc(adev, PPSMC_FlushDataCache) != PPSMC_Result_OK)
39131bb76ff1Sjsg 		return -EINVAL;
39141bb76ff1Sjsg 
39151bb76ff1Sjsg 	return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_Resume) == PPSMC_Result_OK) ?
39161bb76ff1Sjsg 		0 : -EINVAL;
39171bb76ff1Sjsg }
39181bb76ff1Sjsg 
si_dpm_start_smc(struct amdgpu_device * adev)39191bb76ff1Sjsg static void si_dpm_start_smc(struct amdgpu_device *adev)
39201bb76ff1Sjsg {
39211bb76ff1Sjsg 	amdgpu_si_program_jump_on_start(adev);
39221bb76ff1Sjsg 	amdgpu_si_start_smc(adev);
39231bb76ff1Sjsg 	amdgpu_si_smc_clock(adev, true);
39241bb76ff1Sjsg }
39251bb76ff1Sjsg 
si_dpm_stop_smc(struct amdgpu_device * adev)39261bb76ff1Sjsg static void si_dpm_stop_smc(struct amdgpu_device *adev)
39271bb76ff1Sjsg {
39281bb76ff1Sjsg 	amdgpu_si_reset_smc(adev);
39291bb76ff1Sjsg 	amdgpu_si_smc_clock(adev, false);
39301bb76ff1Sjsg }
39311bb76ff1Sjsg 
si_process_firmware_header(struct amdgpu_device * adev)39321bb76ff1Sjsg static int si_process_firmware_header(struct amdgpu_device *adev)
39331bb76ff1Sjsg {
39341bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
39351bb76ff1Sjsg 	u32 tmp;
39361bb76ff1Sjsg 	int ret;
39371bb76ff1Sjsg 
39381bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev,
39391bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
39401bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_stateTable,
39411bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
39421bb76ff1Sjsg 	if (ret)
39431bb76ff1Sjsg 		return ret;
39441bb76ff1Sjsg 
39451bb76ff1Sjsg 	si_pi->state_table_start = tmp;
39461bb76ff1Sjsg 
39471bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev,
39481bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
39491bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_softRegisters,
39501bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
39511bb76ff1Sjsg 	if (ret)
39521bb76ff1Sjsg 		return ret;
39531bb76ff1Sjsg 
39541bb76ff1Sjsg 	si_pi->soft_regs_start = tmp;
39551bb76ff1Sjsg 
39561bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev,
39571bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
39581bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable,
39591bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
39601bb76ff1Sjsg 	if (ret)
39611bb76ff1Sjsg 		return ret;
39621bb76ff1Sjsg 
39631bb76ff1Sjsg 	si_pi->mc_reg_table_start = tmp;
39641bb76ff1Sjsg 
39651bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev,
39661bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
39671bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_fanTable,
39681bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
39691bb76ff1Sjsg 	if (ret)
39701bb76ff1Sjsg 		return ret;
39711bb76ff1Sjsg 
39721bb76ff1Sjsg 	si_pi->fan_table_start = tmp;
39731bb76ff1Sjsg 
39741bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev,
39751bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
39761bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable,
39771bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
39781bb76ff1Sjsg 	if (ret)
39791bb76ff1Sjsg 		return ret;
39801bb76ff1Sjsg 
39811bb76ff1Sjsg 	si_pi->arb_table_start = tmp;
39821bb76ff1Sjsg 
39831bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev,
39841bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
39851bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_CacConfigTable,
39861bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
39871bb76ff1Sjsg 	if (ret)
39881bb76ff1Sjsg 		return ret;
39891bb76ff1Sjsg 
39901bb76ff1Sjsg 	si_pi->cac_table_start = tmp;
39911bb76ff1Sjsg 
39921bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev,
39931bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
39941bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_DteConfiguration,
39951bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
39961bb76ff1Sjsg 	if (ret)
39971bb76ff1Sjsg 		return ret;
39981bb76ff1Sjsg 
39991bb76ff1Sjsg 	si_pi->dte_table_start = tmp;
40001bb76ff1Sjsg 
40011bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev,
40021bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
40031bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_spllTable,
40041bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
40051bb76ff1Sjsg 	if (ret)
40061bb76ff1Sjsg 		return ret;
40071bb76ff1Sjsg 
40081bb76ff1Sjsg 	si_pi->spll_table_start = tmp;
40091bb76ff1Sjsg 
40101bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev,
40111bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
40121bb76ff1Sjsg 					    SISLANDS_SMC_FIRMWARE_HEADER_PAPMParameters,
40131bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
40141bb76ff1Sjsg 	if (ret)
40151bb76ff1Sjsg 		return ret;
40161bb76ff1Sjsg 
40171bb76ff1Sjsg 	si_pi->papm_cfg_table_start = tmp;
40181bb76ff1Sjsg 
40191bb76ff1Sjsg 	return ret;
40201bb76ff1Sjsg }
40211bb76ff1Sjsg 
si_read_clock_registers(struct amdgpu_device * adev)40221bb76ff1Sjsg static void si_read_clock_registers(struct amdgpu_device *adev)
40231bb76ff1Sjsg {
40241bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
40251bb76ff1Sjsg 
40261bb76ff1Sjsg 	si_pi->clock_registers.cg_spll_func_cntl = RREG32(CG_SPLL_FUNC_CNTL);
40271bb76ff1Sjsg 	si_pi->clock_registers.cg_spll_func_cntl_2 = RREG32(CG_SPLL_FUNC_CNTL_2);
40281bb76ff1Sjsg 	si_pi->clock_registers.cg_spll_func_cntl_3 = RREG32(CG_SPLL_FUNC_CNTL_3);
40291bb76ff1Sjsg 	si_pi->clock_registers.cg_spll_func_cntl_4 = RREG32(CG_SPLL_FUNC_CNTL_4);
40301bb76ff1Sjsg 	si_pi->clock_registers.cg_spll_spread_spectrum = RREG32(CG_SPLL_SPREAD_SPECTRUM);
40311bb76ff1Sjsg 	si_pi->clock_registers.cg_spll_spread_spectrum_2 = RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
40321bb76ff1Sjsg 	si_pi->clock_registers.dll_cntl = RREG32(DLL_CNTL);
40331bb76ff1Sjsg 	si_pi->clock_registers.mclk_pwrmgt_cntl = RREG32(MCLK_PWRMGT_CNTL);
40341bb76ff1Sjsg 	si_pi->clock_registers.mpll_ad_func_cntl = RREG32(MPLL_AD_FUNC_CNTL);
40351bb76ff1Sjsg 	si_pi->clock_registers.mpll_dq_func_cntl = RREG32(MPLL_DQ_FUNC_CNTL);
40361bb76ff1Sjsg 	si_pi->clock_registers.mpll_func_cntl = RREG32(MPLL_FUNC_CNTL);
40371bb76ff1Sjsg 	si_pi->clock_registers.mpll_func_cntl_1 = RREG32(MPLL_FUNC_CNTL_1);
40381bb76ff1Sjsg 	si_pi->clock_registers.mpll_func_cntl_2 = RREG32(MPLL_FUNC_CNTL_2);
40391bb76ff1Sjsg 	si_pi->clock_registers.mpll_ss1 = RREG32(MPLL_SS1);
40401bb76ff1Sjsg 	si_pi->clock_registers.mpll_ss2 = RREG32(MPLL_SS2);
40411bb76ff1Sjsg }
40421bb76ff1Sjsg 
si_enable_thermal_protection(struct amdgpu_device * adev,bool enable)40431bb76ff1Sjsg static void si_enable_thermal_protection(struct amdgpu_device *adev,
40441bb76ff1Sjsg 					  bool enable)
40451bb76ff1Sjsg {
40461bb76ff1Sjsg 	if (enable)
40471bb76ff1Sjsg 		WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
40481bb76ff1Sjsg 	else
40491bb76ff1Sjsg 		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
40501bb76ff1Sjsg }
40511bb76ff1Sjsg 
si_enable_acpi_power_management(struct amdgpu_device * adev)40521bb76ff1Sjsg static void si_enable_acpi_power_management(struct amdgpu_device *adev)
40531bb76ff1Sjsg {
40541bb76ff1Sjsg 	WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
40551bb76ff1Sjsg }
40561bb76ff1Sjsg 
40571bb76ff1Sjsg #if 0
40581bb76ff1Sjsg static int si_enter_ulp_state(struct amdgpu_device *adev)
40591bb76ff1Sjsg {
40601bb76ff1Sjsg 	WREG32(SMC_MESSAGE_0, PPSMC_MSG_SwitchToMinimumPower);
40611bb76ff1Sjsg 
40621bb76ff1Sjsg 	udelay(25000);
40631bb76ff1Sjsg 
40641bb76ff1Sjsg 	return 0;
40651bb76ff1Sjsg }
40661bb76ff1Sjsg 
40671bb76ff1Sjsg static int si_exit_ulp_state(struct amdgpu_device *adev)
40681bb76ff1Sjsg {
40691bb76ff1Sjsg 	int i;
40701bb76ff1Sjsg 
40711bb76ff1Sjsg 	WREG32(SMC_MESSAGE_0, PPSMC_MSG_ResumeFromMinimumPower);
40721bb76ff1Sjsg 
40731bb76ff1Sjsg 	udelay(7000);
40741bb76ff1Sjsg 
40751bb76ff1Sjsg 	for (i = 0; i < adev->usec_timeout; i++) {
40761bb76ff1Sjsg 		if (RREG32(SMC_RESP_0) == 1)
40771bb76ff1Sjsg 			break;
40781bb76ff1Sjsg 		udelay(1000);
40791bb76ff1Sjsg 	}
40801bb76ff1Sjsg 
40811bb76ff1Sjsg 	return 0;
40821bb76ff1Sjsg }
40831bb76ff1Sjsg #endif
40841bb76ff1Sjsg 
si_notify_smc_display_change(struct amdgpu_device * adev,bool has_display)40851bb76ff1Sjsg static int si_notify_smc_display_change(struct amdgpu_device *adev,
40861bb76ff1Sjsg 				     bool has_display)
40871bb76ff1Sjsg {
40881bb76ff1Sjsg 	PPSMC_Msg msg = has_display ?
40891bb76ff1Sjsg 		PPSMC_MSG_HasDisplay : PPSMC_MSG_NoDisplay;
40901bb76ff1Sjsg 
40911bb76ff1Sjsg 	return (amdgpu_si_send_msg_to_smc(adev, msg) == PPSMC_Result_OK) ?
40921bb76ff1Sjsg 		0 : -EINVAL;
40931bb76ff1Sjsg }
40941bb76ff1Sjsg 
si_program_response_times(struct amdgpu_device * adev)40951bb76ff1Sjsg static void si_program_response_times(struct amdgpu_device *adev)
40961bb76ff1Sjsg {
40971bb76ff1Sjsg 	u32 voltage_response_time, acpi_delay_time, vbi_time_out;
40981bb76ff1Sjsg 	u32 vddc_dly, acpi_dly, vbi_dly;
40991bb76ff1Sjsg 	u32 reference_clock;
41001bb76ff1Sjsg 
41011bb76ff1Sjsg 	si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_mvdd_chg_time, 1);
41021bb76ff1Sjsg 
41031bb76ff1Sjsg 	voltage_response_time = (u32)adev->pm.dpm.voltage_response_time;
41041bb76ff1Sjsg 
41051bb76ff1Sjsg 	if (voltage_response_time == 0)
41061bb76ff1Sjsg 		voltage_response_time = 1000;
41071bb76ff1Sjsg 
41081bb76ff1Sjsg 	acpi_delay_time = 15000;
41091bb76ff1Sjsg 	vbi_time_out = 100000;
41101bb76ff1Sjsg 
41111bb76ff1Sjsg 	reference_clock = amdgpu_asic_get_xclk(adev);
41121bb76ff1Sjsg 
41131bb76ff1Sjsg 	vddc_dly = (voltage_response_time  * reference_clock) / 100;
41141bb76ff1Sjsg 	acpi_dly = (acpi_delay_time * reference_clock) / 100;
41151bb76ff1Sjsg 	vbi_dly  = (vbi_time_out * reference_clock) / 100;
41161bb76ff1Sjsg 
41171bb76ff1Sjsg 	si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_delay_vreg,  vddc_dly);
41181bb76ff1Sjsg 	si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_delay_acpi,  acpi_dly);
41191bb76ff1Sjsg 	si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);
41201bb76ff1Sjsg 	si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_mc_block_delay, 0xAA);
41211bb76ff1Sjsg }
41221bb76ff1Sjsg 
si_program_ds_registers(struct amdgpu_device * adev)41231bb76ff1Sjsg static void si_program_ds_registers(struct amdgpu_device *adev)
41241bb76ff1Sjsg {
41251bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
41261bb76ff1Sjsg 	u32 tmp;
41271bb76ff1Sjsg 
41281bb76ff1Sjsg 	/* DEEP_SLEEP_CLK_SEL field should be 0x10 on tahiti A0 */
41291bb76ff1Sjsg 	if (adev->asic_type == CHIP_TAHITI && adev->rev_id == 0x0)
41301bb76ff1Sjsg 		tmp = 0x10;
41311bb76ff1Sjsg 	else
41321bb76ff1Sjsg 		tmp = 0x1;
41331bb76ff1Sjsg 
41341bb76ff1Sjsg 	if (eg_pi->sclk_deep_sleep) {
41351bb76ff1Sjsg 		WREG32_P(MISC_CLK_CNTL, DEEP_SLEEP_CLK_SEL(tmp), ~DEEP_SLEEP_CLK_SEL_MASK);
41361bb76ff1Sjsg 		WREG32_P(CG_SPLL_AUTOSCALE_CNTL, AUTOSCALE_ON_SS_CLEAR,
41371bb76ff1Sjsg 			 ~AUTOSCALE_ON_SS_CLEAR);
41381bb76ff1Sjsg 	}
41391bb76ff1Sjsg }
41401bb76ff1Sjsg 
si_program_display_gap(struct amdgpu_device * adev)41411bb76ff1Sjsg static void si_program_display_gap(struct amdgpu_device *adev)
41421bb76ff1Sjsg {
41431bb76ff1Sjsg 	u32 tmp, pipe;
41441bb76ff1Sjsg 	int i;
41451bb76ff1Sjsg 
41461bb76ff1Sjsg 	tmp = RREG32(CG_DISPLAY_GAP_CNTL) & ~(DISP1_GAP_MASK | DISP2_GAP_MASK);
41471bb76ff1Sjsg 	if (adev->pm.dpm.new_active_crtc_count > 0)
41481bb76ff1Sjsg 		tmp |= DISP1_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM);
41491bb76ff1Sjsg 	else
41501bb76ff1Sjsg 		tmp |= DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE);
41511bb76ff1Sjsg 
41521bb76ff1Sjsg 	if (adev->pm.dpm.new_active_crtc_count > 1)
41531bb76ff1Sjsg 		tmp |= DISP2_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM);
41541bb76ff1Sjsg 	else
41551bb76ff1Sjsg 		tmp |= DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE);
41561bb76ff1Sjsg 
41571bb76ff1Sjsg 	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
41581bb76ff1Sjsg 
41591bb76ff1Sjsg 	tmp = RREG32(DCCG_DISP_SLOW_SELECT_REG);
41601bb76ff1Sjsg 	pipe = (tmp & DCCG_DISP1_SLOW_SELECT_MASK) >> DCCG_DISP1_SLOW_SELECT_SHIFT;
41611bb76ff1Sjsg 
41621bb76ff1Sjsg 	if ((adev->pm.dpm.new_active_crtc_count > 0) &&
41631bb76ff1Sjsg 	    (!(adev->pm.dpm.new_active_crtcs & (1 << pipe)))) {
41641bb76ff1Sjsg 		/* find the first active crtc */
41651bb76ff1Sjsg 		for (i = 0; i < adev->mode_info.num_crtc; i++) {
41661bb76ff1Sjsg 			if (adev->pm.dpm.new_active_crtcs & (1 << i))
41671bb76ff1Sjsg 				break;
41681bb76ff1Sjsg 		}
41691bb76ff1Sjsg 		if (i == adev->mode_info.num_crtc)
41701bb76ff1Sjsg 			pipe = 0;
41711bb76ff1Sjsg 		else
41721bb76ff1Sjsg 			pipe = i;
41731bb76ff1Sjsg 
41741bb76ff1Sjsg 		tmp &= ~DCCG_DISP1_SLOW_SELECT_MASK;
41751bb76ff1Sjsg 		tmp |= DCCG_DISP1_SLOW_SELECT(pipe);
41761bb76ff1Sjsg 		WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp);
41771bb76ff1Sjsg 	}
41781bb76ff1Sjsg 
41791bb76ff1Sjsg 	/* Setting this to false forces the performance state to low if the crtcs are disabled.
41801bb76ff1Sjsg 	 * This can be a problem on PowerXpress systems or if you want to use the card
41811bb76ff1Sjsg 	 * for offscreen rendering or compute if there are no crtcs enabled.
41821bb76ff1Sjsg 	 */
41831bb76ff1Sjsg 	si_notify_smc_display_change(adev, adev->pm.dpm.new_active_crtc_count > 0);
41841bb76ff1Sjsg }
41851bb76ff1Sjsg 
si_enable_spread_spectrum(struct amdgpu_device * adev,bool enable)41861bb76ff1Sjsg static void si_enable_spread_spectrum(struct amdgpu_device *adev, bool enable)
41871bb76ff1Sjsg {
41881bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
41891bb76ff1Sjsg 
41901bb76ff1Sjsg 	if (enable) {
41911bb76ff1Sjsg 		if (pi->sclk_ss)
41921bb76ff1Sjsg 			WREG32_P(GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, ~DYN_SPREAD_SPECTRUM_EN);
41931bb76ff1Sjsg 	} else {
41941bb76ff1Sjsg 		WREG32_P(CG_SPLL_SPREAD_SPECTRUM, 0, ~SSEN);
41951bb76ff1Sjsg 		WREG32_P(GENERAL_PWRMGT, 0, ~DYN_SPREAD_SPECTRUM_EN);
41961bb76ff1Sjsg 	}
41971bb76ff1Sjsg }
41981bb76ff1Sjsg 
si_setup_bsp(struct amdgpu_device * adev)41991bb76ff1Sjsg static void si_setup_bsp(struct amdgpu_device *adev)
42001bb76ff1Sjsg {
42011bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
42021bb76ff1Sjsg 	u32 xclk = amdgpu_asic_get_xclk(adev);
42031bb76ff1Sjsg 
42041bb76ff1Sjsg 	r600_calculate_u_and_p(pi->asi,
42051bb76ff1Sjsg 			       xclk,
42061bb76ff1Sjsg 			       16,
42071bb76ff1Sjsg 			       &pi->bsp,
42081bb76ff1Sjsg 			       &pi->bsu);
42091bb76ff1Sjsg 
42101bb76ff1Sjsg 	r600_calculate_u_and_p(pi->pasi,
42111bb76ff1Sjsg 			       xclk,
42121bb76ff1Sjsg 			       16,
42131bb76ff1Sjsg 			       &pi->pbsp,
42141bb76ff1Sjsg 			       &pi->pbsu);
42151bb76ff1Sjsg 
42161bb76ff1Sjsg 
42171bb76ff1Sjsg         pi->dsp = BSP(pi->bsp) | BSU(pi->bsu);
42181bb76ff1Sjsg 	pi->psp = BSP(pi->pbsp) | BSU(pi->pbsu);
42191bb76ff1Sjsg 
42201bb76ff1Sjsg 	WREG32(CG_BSP, pi->dsp);
42211bb76ff1Sjsg }
42221bb76ff1Sjsg 
si_program_git(struct amdgpu_device * adev)42231bb76ff1Sjsg static void si_program_git(struct amdgpu_device *adev)
42241bb76ff1Sjsg {
42251bb76ff1Sjsg 	WREG32_P(CG_GIT, CG_GICST(R600_GICST_DFLT), ~CG_GICST_MASK);
42261bb76ff1Sjsg }
42271bb76ff1Sjsg 
si_program_tp(struct amdgpu_device * adev)42281bb76ff1Sjsg static void si_program_tp(struct amdgpu_device *adev)
42291bb76ff1Sjsg {
42301bb76ff1Sjsg 	int i;
42311bb76ff1Sjsg 	enum r600_td td = R600_TD_DFLT;
42321bb76ff1Sjsg 
42331bb76ff1Sjsg 	for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)
42341bb76ff1Sjsg 		WREG32(CG_FFCT_0 + i, (UTC_0(r600_utc[i]) | DTC_0(r600_dtc[i])));
42351bb76ff1Sjsg 
42361bb76ff1Sjsg 	if (td == R600_TD_AUTO)
42371bb76ff1Sjsg 		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
42381bb76ff1Sjsg 	else
42391bb76ff1Sjsg 		WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
42401bb76ff1Sjsg 
42411bb76ff1Sjsg 	if (td == R600_TD_UP)
42421bb76ff1Sjsg 		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
42431bb76ff1Sjsg 
42441bb76ff1Sjsg 	if (td == R600_TD_DOWN)
42451bb76ff1Sjsg 		WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
42461bb76ff1Sjsg }
42471bb76ff1Sjsg 
si_program_tpp(struct amdgpu_device * adev)42481bb76ff1Sjsg static void si_program_tpp(struct amdgpu_device *adev)
42491bb76ff1Sjsg {
42501bb76ff1Sjsg 	WREG32(CG_TPC, R600_TPC_DFLT);
42511bb76ff1Sjsg }
42521bb76ff1Sjsg 
si_program_sstp(struct amdgpu_device * adev)42531bb76ff1Sjsg static void si_program_sstp(struct amdgpu_device *adev)
42541bb76ff1Sjsg {
42551bb76ff1Sjsg 	WREG32(CG_SSP, (SSTU(R600_SSTU_DFLT) | SST(R600_SST_DFLT)));
42561bb76ff1Sjsg }
42571bb76ff1Sjsg 
si_enable_display_gap(struct amdgpu_device * adev)42581bb76ff1Sjsg static void si_enable_display_gap(struct amdgpu_device *adev)
42591bb76ff1Sjsg {
42601bb76ff1Sjsg 	u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
42611bb76ff1Sjsg 
42621bb76ff1Sjsg 	tmp &= ~(DISP1_GAP_MASK | DISP2_GAP_MASK);
42631bb76ff1Sjsg 	tmp |= (DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE) |
42641bb76ff1Sjsg 		DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE));
42651bb76ff1Sjsg 
42661bb76ff1Sjsg 	tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
42671bb76ff1Sjsg 	tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK) |
42681bb76ff1Sjsg 		DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE));
42691bb76ff1Sjsg 	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
42701bb76ff1Sjsg }
42711bb76ff1Sjsg 
si_program_vc(struct amdgpu_device * adev)42721bb76ff1Sjsg static void si_program_vc(struct amdgpu_device *adev)
42731bb76ff1Sjsg {
42741bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
42751bb76ff1Sjsg 
42761bb76ff1Sjsg 	WREG32(CG_FTV, pi->vrc);
42771bb76ff1Sjsg }
42781bb76ff1Sjsg 
si_clear_vc(struct amdgpu_device * adev)42791bb76ff1Sjsg static void si_clear_vc(struct amdgpu_device *adev)
42801bb76ff1Sjsg {
42811bb76ff1Sjsg 	WREG32(CG_FTV, 0);
42821bb76ff1Sjsg }
42831bb76ff1Sjsg 
si_get_ddr3_mclk_frequency_ratio(u32 memory_clock)42841bb76ff1Sjsg static u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock)
42851bb76ff1Sjsg {
42861bb76ff1Sjsg 	u8 mc_para_index;
42871bb76ff1Sjsg 
42881bb76ff1Sjsg 	if (memory_clock < 10000)
42891bb76ff1Sjsg 		mc_para_index = 0;
42901bb76ff1Sjsg 	else if (memory_clock >= 80000)
42911bb76ff1Sjsg 		mc_para_index = 0x0f;
42921bb76ff1Sjsg 	else
42931bb76ff1Sjsg 		mc_para_index = (u8)((memory_clock - 10000) / 5000 + 1);
42941bb76ff1Sjsg 	return mc_para_index;
42951bb76ff1Sjsg }
42961bb76ff1Sjsg 
si_get_mclk_frequency_ratio(u32 memory_clock,bool strobe_mode)42971bb76ff1Sjsg static u8 si_get_mclk_frequency_ratio(u32 memory_clock, bool strobe_mode)
42981bb76ff1Sjsg {
42991bb76ff1Sjsg 	u8 mc_para_index;
43001bb76ff1Sjsg 
43011bb76ff1Sjsg 	if (strobe_mode) {
43021bb76ff1Sjsg 		if (memory_clock < 12500)
43031bb76ff1Sjsg 			mc_para_index = 0x00;
43041bb76ff1Sjsg 		else if (memory_clock > 47500)
43051bb76ff1Sjsg 			mc_para_index = 0x0f;
43061bb76ff1Sjsg 		else
43071bb76ff1Sjsg 			mc_para_index = (u8)((memory_clock - 10000) / 2500);
43081bb76ff1Sjsg 	} else {
43091bb76ff1Sjsg 		if (memory_clock < 65000)
43101bb76ff1Sjsg 			mc_para_index = 0x00;
43111bb76ff1Sjsg 		else if (memory_clock > 135000)
43121bb76ff1Sjsg 			mc_para_index = 0x0f;
43131bb76ff1Sjsg 		else
43141bb76ff1Sjsg 			mc_para_index = (u8)((memory_clock - 60000) / 5000);
43151bb76ff1Sjsg 	}
43161bb76ff1Sjsg 	return mc_para_index;
43171bb76ff1Sjsg }
43181bb76ff1Sjsg 
si_get_strobe_mode_settings(struct amdgpu_device * adev,u32 mclk)43191bb76ff1Sjsg static u8 si_get_strobe_mode_settings(struct amdgpu_device *adev, u32 mclk)
43201bb76ff1Sjsg {
43211bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
43221bb76ff1Sjsg 	bool strobe_mode = false;
43231bb76ff1Sjsg 	u8 result = 0;
43241bb76ff1Sjsg 
43251bb76ff1Sjsg 	if (mclk <= pi->mclk_strobe_mode_threshold)
43261bb76ff1Sjsg 		strobe_mode = true;
43271bb76ff1Sjsg 
43281bb76ff1Sjsg 	if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5)
43291bb76ff1Sjsg 		result = si_get_mclk_frequency_ratio(mclk, strobe_mode);
43301bb76ff1Sjsg 	else
43311bb76ff1Sjsg 		result = si_get_ddr3_mclk_frequency_ratio(mclk);
43321bb76ff1Sjsg 
43331bb76ff1Sjsg 	if (strobe_mode)
43341bb76ff1Sjsg 		result |= SISLANDS_SMC_STROBE_ENABLE;
43351bb76ff1Sjsg 
43361bb76ff1Sjsg 	return result;
43371bb76ff1Sjsg }
43381bb76ff1Sjsg 
si_upload_firmware(struct amdgpu_device * adev)43391bb76ff1Sjsg static int si_upload_firmware(struct amdgpu_device *adev)
43401bb76ff1Sjsg {
43411bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
43421bb76ff1Sjsg 
43431bb76ff1Sjsg 	amdgpu_si_reset_smc(adev);
43441bb76ff1Sjsg 	amdgpu_si_smc_clock(adev, false);
43451bb76ff1Sjsg 
43461bb76ff1Sjsg 	return amdgpu_si_load_smc_ucode(adev, si_pi->sram_end);
43471bb76ff1Sjsg }
43481bb76ff1Sjsg 
si_validate_phase_shedding_tables(struct amdgpu_device * adev,const struct atom_voltage_table * table,const struct amdgpu_phase_shedding_limits_table * limits)43491bb76ff1Sjsg static bool si_validate_phase_shedding_tables(struct amdgpu_device *adev,
43501bb76ff1Sjsg 					      const struct atom_voltage_table *table,
43511bb76ff1Sjsg 					      const struct amdgpu_phase_shedding_limits_table *limits)
43521bb76ff1Sjsg {
43531bb76ff1Sjsg 	u32 data, num_bits, num_levels;
43541bb76ff1Sjsg 
43551bb76ff1Sjsg 	if ((table == NULL) || (limits == NULL))
43561bb76ff1Sjsg 		return false;
43571bb76ff1Sjsg 
43581bb76ff1Sjsg 	data = table->mask_low;
43591bb76ff1Sjsg 
43601bb76ff1Sjsg 	num_bits = hweight32(data);
43611bb76ff1Sjsg 
43621bb76ff1Sjsg 	if (num_bits == 0)
43631bb76ff1Sjsg 		return false;
43641bb76ff1Sjsg 
43651bb76ff1Sjsg 	num_levels = (1 << num_bits);
43661bb76ff1Sjsg 
43671bb76ff1Sjsg 	if (table->count != num_levels)
43681bb76ff1Sjsg 		return false;
43691bb76ff1Sjsg 
43701bb76ff1Sjsg 	if (limits->count != (num_levels - 1))
43711bb76ff1Sjsg 		return false;
43721bb76ff1Sjsg 
43731bb76ff1Sjsg 	return true;
43741bb76ff1Sjsg }
43751bb76ff1Sjsg 
si_trim_voltage_table_to_fit_state_table(struct amdgpu_device * adev,u32 max_voltage_steps,struct atom_voltage_table * voltage_table)43761bb76ff1Sjsg static void si_trim_voltage_table_to_fit_state_table(struct amdgpu_device *adev,
43771bb76ff1Sjsg 					      u32 max_voltage_steps,
43781bb76ff1Sjsg 					      struct atom_voltage_table *voltage_table)
43791bb76ff1Sjsg {
43801bb76ff1Sjsg 	unsigned int i, diff;
43811bb76ff1Sjsg 
43821bb76ff1Sjsg 	if (voltage_table->count <= max_voltage_steps)
43831bb76ff1Sjsg 		return;
43841bb76ff1Sjsg 
43851bb76ff1Sjsg 	diff = voltage_table->count - max_voltage_steps;
43861bb76ff1Sjsg 
43871bb76ff1Sjsg 	for (i= 0; i < max_voltage_steps; i++)
43881bb76ff1Sjsg 		voltage_table->entries[i] = voltage_table->entries[i + diff];
43891bb76ff1Sjsg 
43901bb76ff1Sjsg 	voltage_table->count = max_voltage_steps;
43911bb76ff1Sjsg }
43921bb76ff1Sjsg 
si_get_svi2_voltage_table(struct amdgpu_device * adev,struct amdgpu_clock_voltage_dependency_table * voltage_dependency_table,struct atom_voltage_table * voltage_table)43931bb76ff1Sjsg static int si_get_svi2_voltage_table(struct amdgpu_device *adev,
43941bb76ff1Sjsg 				     struct amdgpu_clock_voltage_dependency_table *voltage_dependency_table,
43951bb76ff1Sjsg 				     struct atom_voltage_table *voltage_table)
43961bb76ff1Sjsg {
43971bb76ff1Sjsg 	u32 i;
43981bb76ff1Sjsg 
43991bb76ff1Sjsg 	if (voltage_dependency_table == NULL)
44001bb76ff1Sjsg 		return -EINVAL;
44011bb76ff1Sjsg 
44021bb76ff1Sjsg 	voltage_table->mask_low = 0;
44031bb76ff1Sjsg 	voltage_table->phase_delay = 0;
44041bb76ff1Sjsg 
44051bb76ff1Sjsg 	voltage_table->count = voltage_dependency_table->count;
44061bb76ff1Sjsg 	for (i = 0; i < voltage_table->count; i++) {
44071bb76ff1Sjsg 		voltage_table->entries[i].value = voltage_dependency_table->entries[i].v;
44081bb76ff1Sjsg 		voltage_table->entries[i].smio_low = 0;
44091bb76ff1Sjsg 	}
44101bb76ff1Sjsg 
44111bb76ff1Sjsg 	return 0;
44121bb76ff1Sjsg }
44131bb76ff1Sjsg 
si_construct_voltage_tables(struct amdgpu_device * adev)44141bb76ff1Sjsg static int si_construct_voltage_tables(struct amdgpu_device *adev)
44151bb76ff1Sjsg {
44161bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
44171bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
44181bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
44191bb76ff1Sjsg 	int ret;
44201bb76ff1Sjsg 
44211bb76ff1Sjsg 	if (pi->voltage_control) {
44221bb76ff1Sjsg 		ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_VDDC,
44231bb76ff1Sjsg 						    VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddc_voltage_table);
44241bb76ff1Sjsg 		if (ret)
44251bb76ff1Sjsg 			return ret;
44261bb76ff1Sjsg 
44271bb76ff1Sjsg 		if (eg_pi->vddc_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
44281bb76ff1Sjsg 			si_trim_voltage_table_to_fit_state_table(adev,
44291bb76ff1Sjsg 								 SISLANDS_MAX_NO_VREG_STEPS,
44301bb76ff1Sjsg 								 &eg_pi->vddc_voltage_table);
44311bb76ff1Sjsg 	} else if (si_pi->voltage_control_svi2) {
44321bb76ff1Sjsg 		ret = si_get_svi2_voltage_table(adev,
44331bb76ff1Sjsg 						&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
44341bb76ff1Sjsg 						&eg_pi->vddc_voltage_table);
44351bb76ff1Sjsg 		if (ret)
44361bb76ff1Sjsg 			return ret;
44371bb76ff1Sjsg 	} else {
44381bb76ff1Sjsg 		return -EINVAL;
44391bb76ff1Sjsg 	}
44401bb76ff1Sjsg 
44411bb76ff1Sjsg 	if (eg_pi->vddci_control) {
44421bb76ff1Sjsg 		ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_VDDCI,
44431bb76ff1Sjsg 						    VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddci_voltage_table);
44441bb76ff1Sjsg 		if (ret)
44451bb76ff1Sjsg 			return ret;
44461bb76ff1Sjsg 
44471bb76ff1Sjsg 		if (eg_pi->vddci_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
44481bb76ff1Sjsg 			si_trim_voltage_table_to_fit_state_table(adev,
44491bb76ff1Sjsg 								 SISLANDS_MAX_NO_VREG_STEPS,
44501bb76ff1Sjsg 								 &eg_pi->vddci_voltage_table);
44511bb76ff1Sjsg 	}
44521bb76ff1Sjsg 	if (si_pi->vddci_control_svi2) {
44531bb76ff1Sjsg 		ret = si_get_svi2_voltage_table(adev,
44541bb76ff1Sjsg 						&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
44551bb76ff1Sjsg 						&eg_pi->vddci_voltage_table);
44561bb76ff1Sjsg 		if (ret)
44571bb76ff1Sjsg 			return ret;
44581bb76ff1Sjsg 	}
44591bb76ff1Sjsg 
44601bb76ff1Sjsg 	if (pi->mvdd_control) {
44611bb76ff1Sjsg 		ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_MVDDC,
44621bb76ff1Sjsg 						    VOLTAGE_OBJ_GPIO_LUT, &si_pi->mvdd_voltage_table);
44631bb76ff1Sjsg 
44641bb76ff1Sjsg 		if (ret) {
44651bb76ff1Sjsg 			pi->mvdd_control = false;
44661bb76ff1Sjsg 			return ret;
44671bb76ff1Sjsg 		}
44681bb76ff1Sjsg 
44691bb76ff1Sjsg 		if (si_pi->mvdd_voltage_table.count == 0) {
44701bb76ff1Sjsg 			pi->mvdd_control = false;
44711bb76ff1Sjsg 			return -EINVAL;
44721bb76ff1Sjsg 		}
44731bb76ff1Sjsg 
44741bb76ff1Sjsg 		if (si_pi->mvdd_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
44751bb76ff1Sjsg 			si_trim_voltage_table_to_fit_state_table(adev,
44761bb76ff1Sjsg 								 SISLANDS_MAX_NO_VREG_STEPS,
44771bb76ff1Sjsg 								 &si_pi->mvdd_voltage_table);
44781bb76ff1Sjsg 	}
44791bb76ff1Sjsg 
44801bb76ff1Sjsg 	if (si_pi->vddc_phase_shed_control) {
44811bb76ff1Sjsg 		ret = amdgpu_atombios_get_voltage_table(adev, VOLTAGE_TYPE_VDDC,
44821bb76ff1Sjsg 						    VOLTAGE_OBJ_PHASE_LUT, &si_pi->vddc_phase_shed_table);
44831bb76ff1Sjsg 		if (ret)
44841bb76ff1Sjsg 			si_pi->vddc_phase_shed_control = false;
44851bb76ff1Sjsg 
44861bb76ff1Sjsg 		if ((si_pi->vddc_phase_shed_table.count == 0) ||
44871bb76ff1Sjsg 		    (si_pi->vddc_phase_shed_table.count > SISLANDS_MAX_NO_VREG_STEPS))
44881bb76ff1Sjsg 			si_pi->vddc_phase_shed_control = false;
44891bb76ff1Sjsg 	}
44901bb76ff1Sjsg 
44911bb76ff1Sjsg 	return 0;
44921bb76ff1Sjsg }
44931bb76ff1Sjsg 
si_populate_smc_voltage_table(struct amdgpu_device * adev,const struct atom_voltage_table * voltage_table,SISLANDS_SMC_STATETABLE * table)44941bb76ff1Sjsg static void si_populate_smc_voltage_table(struct amdgpu_device *adev,
44951bb76ff1Sjsg 					  const struct atom_voltage_table *voltage_table,
44961bb76ff1Sjsg 					  SISLANDS_SMC_STATETABLE *table)
44971bb76ff1Sjsg {
44981bb76ff1Sjsg 	unsigned int i;
44991bb76ff1Sjsg 
45001bb76ff1Sjsg 	for (i = 0; i < voltage_table->count; i++)
45011bb76ff1Sjsg 		table->lowSMIO[i] |= cpu_to_be32(voltage_table->entries[i].smio_low);
45021bb76ff1Sjsg }
45031bb76ff1Sjsg 
si_populate_smc_voltage_tables(struct amdgpu_device * adev,SISLANDS_SMC_STATETABLE * table)45041bb76ff1Sjsg static int si_populate_smc_voltage_tables(struct amdgpu_device *adev,
45051bb76ff1Sjsg 					  SISLANDS_SMC_STATETABLE *table)
45061bb76ff1Sjsg {
45071bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
45081bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
45091bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
45101bb76ff1Sjsg 	u8 i;
45111bb76ff1Sjsg 
45121bb76ff1Sjsg 	if (si_pi->voltage_control_svi2) {
45131bb76ff1Sjsg 		si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc,
45141bb76ff1Sjsg 			si_pi->svc_gpio_id);
45151bb76ff1Sjsg 		si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd,
45161bb76ff1Sjsg 			si_pi->svd_gpio_id);
45171bb76ff1Sjsg 		si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_svi_rework_plat_type,
45181bb76ff1Sjsg 					   2);
45191bb76ff1Sjsg 	} else {
45201bb76ff1Sjsg 		if (eg_pi->vddc_voltage_table.count) {
45211bb76ff1Sjsg 			si_populate_smc_voltage_table(adev, &eg_pi->vddc_voltage_table, table);
45221bb76ff1Sjsg 			table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
45231bb76ff1Sjsg 				cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
45241bb76ff1Sjsg 
45251bb76ff1Sjsg 			for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {
45261bb76ff1Sjsg 				if (pi->max_vddc_in_table <= eg_pi->vddc_voltage_table.entries[i].value) {
45271bb76ff1Sjsg 					table->maxVDDCIndexInPPTable = i;
45281bb76ff1Sjsg 					break;
45291bb76ff1Sjsg 				}
45301bb76ff1Sjsg 			}
45311bb76ff1Sjsg 		}
45321bb76ff1Sjsg 
45331bb76ff1Sjsg 		if (eg_pi->vddci_voltage_table.count) {
45341bb76ff1Sjsg 			si_populate_smc_voltage_table(adev, &eg_pi->vddci_voltage_table, table);
45351bb76ff1Sjsg 
45361bb76ff1Sjsg 			table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDCI] =
45371bb76ff1Sjsg 				cpu_to_be32(eg_pi->vddci_voltage_table.mask_low);
45381bb76ff1Sjsg 		}
45391bb76ff1Sjsg 
45401bb76ff1Sjsg 
45411bb76ff1Sjsg 		if (si_pi->mvdd_voltage_table.count) {
45421bb76ff1Sjsg 			si_populate_smc_voltage_table(adev, &si_pi->mvdd_voltage_table, table);
45431bb76ff1Sjsg 
45441bb76ff1Sjsg 			table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_MVDD] =
45451bb76ff1Sjsg 				cpu_to_be32(si_pi->mvdd_voltage_table.mask_low);
45461bb76ff1Sjsg 		}
45471bb76ff1Sjsg 
45481bb76ff1Sjsg 		if (si_pi->vddc_phase_shed_control) {
45491bb76ff1Sjsg 			if (si_validate_phase_shedding_tables(adev, &si_pi->vddc_phase_shed_table,
45501bb76ff1Sjsg 							      &adev->pm.dpm.dyn_state.phase_shedding_limits_table)) {
45511bb76ff1Sjsg 				si_populate_smc_voltage_table(adev, &si_pi->vddc_phase_shed_table, table);
45521bb76ff1Sjsg 
45531bb76ff1Sjsg 				table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] =
45541bb76ff1Sjsg 					cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low);
45551bb76ff1Sjsg 
45561bb76ff1Sjsg 				si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_phase_shedding_delay,
45571bb76ff1Sjsg 							   (u32)si_pi->vddc_phase_shed_table.phase_delay);
45581bb76ff1Sjsg 			} else {
45591bb76ff1Sjsg 				si_pi->vddc_phase_shed_control = false;
45601bb76ff1Sjsg 			}
45611bb76ff1Sjsg 		}
45621bb76ff1Sjsg 	}
45631bb76ff1Sjsg 
45641bb76ff1Sjsg 	return 0;
45651bb76ff1Sjsg }
45661bb76ff1Sjsg 
si_populate_voltage_value(struct amdgpu_device * adev,const struct atom_voltage_table * table,u16 value,SISLANDS_SMC_VOLTAGE_VALUE * voltage)45671bb76ff1Sjsg static int si_populate_voltage_value(struct amdgpu_device *adev,
45681bb76ff1Sjsg 				     const struct atom_voltage_table *table,
45691bb76ff1Sjsg 				     u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage)
45701bb76ff1Sjsg {
45711bb76ff1Sjsg 	unsigned int i;
45721bb76ff1Sjsg 
45731bb76ff1Sjsg 	for (i = 0; i < table->count; i++) {
45741bb76ff1Sjsg 		if (value <= table->entries[i].value) {
45751bb76ff1Sjsg 			voltage->index = (u8)i;
45761bb76ff1Sjsg 			voltage->value = cpu_to_be16(table->entries[i].value);
45771bb76ff1Sjsg 			break;
45781bb76ff1Sjsg 		}
45791bb76ff1Sjsg 	}
45801bb76ff1Sjsg 
45811bb76ff1Sjsg 	if (i >= table->count)
45821bb76ff1Sjsg 		return -EINVAL;
45831bb76ff1Sjsg 
45841bb76ff1Sjsg 	return 0;
45851bb76ff1Sjsg }
45861bb76ff1Sjsg 
si_populate_mvdd_value(struct amdgpu_device * adev,u32 mclk,SISLANDS_SMC_VOLTAGE_VALUE * voltage)45871bb76ff1Sjsg static int si_populate_mvdd_value(struct amdgpu_device *adev, u32 mclk,
45881bb76ff1Sjsg 				  SISLANDS_SMC_VOLTAGE_VALUE *voltage)
45891bb76ff1Sjsg {
45901bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
45911bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
45921bb76ff1Sjsg 
45931bb76ff1Sjsg 	if (pi->mvdd_control) {
45941bb76ff1Sjsg 		if (mclk <= pi->mvdd_split_frequency)
45951bb76ff1Sjsg 			voltage->index = 0;
45961bb76ff1Sjsg 		else
45971bb76ff1Sjsg 			voltage->index = (u8)(si_pi->mvdd_voltage_table.count) - 1;
45981bb76ff1Sjsg 
45991bb76ff1Sjsg 		voltage->value = cpu_to_be16(si_pi->mvdd_voltage_table.entries[voltage->index].value);
46001bb76ff1Sjsg 	}
46011bb76ff1Sjsg 	return 0;
46021bb76ff1Sjsg }
46031bb76ff1Sjsg 
si_get_std_voltage_value(struct amdgpu_device * adev,SISLANDS_SMC_VOLTAGE_VALUE * voltage,u16 * std_voltage)46041bb76ff1Sjsg static int si_get_std_voltage_value(struct amdgpu_device *adev,
46051bb76ff1Sjsg 				    SISLANDS_SMC_VOLTAGE_VALUE *voltage,
46061bb76ff1Sjsg 				    u16 *std_voltage)
46071bb76ff1Sjsg {
46081bb76ff1Sjsg 	u16 v_index;
46091bb76ff1Sjsg 	bool voltage_found = false;
46101bb76ff1Sjsg 	*std_voltage = be16_to_cpu(voltage->value);
46111bb76ff1Sjsg 
46121bb76ff1Sjsg 	if (adev->pm.dpm.dyn_state.cac_leakage_table.entries) {
46131bb76ff1Sjsg 		if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_NEW_CAC_VOLTAGE) {
46141bb76ff1Sjsg 			if (adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries == NULL)
46151bb76ff1Sjsg 				return -EINVAL;
46161bb76ff1Sjsg 
46171bb76ff1Sjsg 			for (v_index = 0; (u32)v_index < adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; v_index++) {
46181bb76ff1Sjsg 				if (be16_to_cpu(voltage->value) ==
46191bb76ff1Sjsg 				    (u16)adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[v_index].v) {
46201bb76ff1Sjsg 					voltage_found = true;
46211bb76ff1Sjsg 					if ((u32)v_index < adev->pm.dpm.dyn_state.cac_leakage_table.count)
46221bb76ff1Sjsg 						*std_voltage =
46231bb76ff1Sjsg 							adev->pm.dpm.dyn_state.cac_leakage_table.entries[v_index].vddc;
46241bb76ff1Sjsg 					else
46251bb76ff1Sjsg 						*std_voltage =
46261bb76ff1Sjsg 							adev->pm.dpm.dyn_state.cac_leakage_table.entries[adev->pm.dpm.dyn_state.cac_leakage_table.count-1].vddc;
46271bb76ff1Sjsg 					break;
46281bb76ff1Sjsg 				}
46291bb76ff1Sjsg 			}
46301bb76ff1Sjsg 
46311bb76ff1Sjsg 			if (!voltage_found) {
46321bb76ff1Sjsg 				for (v_index = 0; (u32)v_index < adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; v_index++) {
46331bb76ff1Sjsg 					if (be16_to_cpu(voltage->value) <=
46341bb76ff1Sjsg 					    (u16)adev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[v_index].v) {
46351bb76ff1Sjsg 						voltage_found = true;
46361bb76ff1Sjsg 						if ((u32)v_index < adev->pm.dpm.dyn_state.cac_leakage_table.count)
46371bb76ff1Sjsg 							*std_voltage =
46381bb76ff1Sjsg 								adev->pm.dpm.dyn_state.cac_leakage_table.entries[v_index].vddc;
46391bb76ff1Sjsg 						else
46401bb76ff1Sjsg 							*std_voltage =
46411bb76ff1Sjsg 								adev->pm.dpm.dyn_state.cac_leakage_table.entries[adev->pm.dpm.dyn_state.cac_leakage_table.count-1].vddc;
46421bb76ff1Sjsg 						break;
46431bb76ff1Sjsg 					}
46441bb76ff1Sjsg 				}
46451bb76ff1Sjsg 			}
46461bb76ff1Sjsg 		} else {
46471bb76ff1Sjsg 			if ((u32)voltage->index < adev->pm.dpm.dyn_state.cac_leakage_table.count)
46481bb76ff1Sjsg 				*std_voltage = adev->pm.dpm.dyn_state.cac_leakage_table.entries[voltage->index].vddc;
46491bb76ff1Sjsg 		}
46501bb76ff1Sjsg 	}
46511bb76ff1Sjsg 
46521bb76ff1Sjsg 	return 0;
46531bb76ff1Sjsg }
46541bb76ff1Sjsg 
si_populate_std_voltage_value(struct amdgpu_device * adev,u16 value,u8 index,SISLANDS_SMC_VOLTAGE_VALUE * voltage)46551bb76ff1Sjsg static int si_populate_std_voltage_value(struct amdgpu_device *adev,
46561bb76ff1Sjsg 					 u16 value, u8 index,
46571bb76ff1Sjsg 					 SISLANDS_SMC_VOLTAGE_VALUE *voltage)
46581bb76ff1Sjsg {
46591bb76ff1Sjsg 	voltage->index = index;
46601bb76ff1Sjsg 	voltage->value = cpu_to_be16(value);
46611bb76ff1Sjsg 
46621bb76ff1Sjsg 	return 0;
46631bb76ff1Sjsg }
46641bb76ff1Sjsg 
si_populate_phase_shedding_value(struct amdgpu_device * adev,const struct amdgpu_phase_shedding_limits_table * limits,u16 voltage,u32 sclk,u32 mclk,SISLANDS_SMC_VOLTAGE_VALUE * smc_voltage)46651bb76ff1Sjsg static int si_populate_phase_shedding_value(struct amdgpu_device *adev,
46661bb76ff1Sjsg 					    const struct amdgpu_phase_shedding_limits_table *limits,
46671bb76ff1Sjsg 					    u16 voltage, u32 sclk, u32 mclk,
46681bb76ff1Sjsg 					    SISLANDS_SMC_VOLTAGE_VALUE *smc_voltage)
46691bb76ff1Sjsg {
46701bb76ff1Sjsg 	unsigned int i;
46711bb76ff1Sjsg 
46721bb76ff1Sjsg 	for (i = 0; i < limits->count; i++) {
46731bb76ff1Sjsg 		if ((voltage <= limits->entries[i].voltage) &&
46741bb76ff1Sjsg 		    (sclk <= limits->entries[i].sclk) &&
46751bb76ff1Sjsg 		    (mclk <= limits->entries[i].mclk))
46761bb76ff1Sjsg 			break;
46771bb76ff1Sjsg 	}
46781bb76ff1Sjsg 
46791bb76ff1Sjsg 	smc_voltage->phase_settings = (u8)i;
46801bb76ff1Sjsg 
46811bb76ff1Sjsg 	return 0;
46821bb76ff1Sjsg }
46831bb76ff1Sjsg 
si_init_arb_table_index(struct amdgpu_device * adev)46841bb76ff1Sjsg static int si_init_arb_table_index(struct amdgpu_device *adev)
46851bb76ff1Sjsg {
46861bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
46871bb76ff1Sjsg 	u32 tmp;
46881bb76ff1Sjsg 	int ret;
46891bb76ff1Sjsg 
46901bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev, si_pi->arb_table_start,
46911bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
46921bb76ff1Sjsg 	if (ret)
46931bb76ff1Sjsg 		return ret;
46941bb76ff1Sjsg 
46951bb76ff1Sjsg 	tmp &= 0x00FFFFFF;
46961bb76ff1Sjsg 	tmp |= MC_CG_ARB_FREQ_F1 << 24;
46971bb76ff1Sjsg 
46981bb76ff1Sjsg 	return amdgpu_si_write_smc_sram_dword(adev, si_pi->arb_table_start,
46991bb76ff1Sjsg 					      tmp, si_pi->sram_end);
47001bb76ff1Sjsg }
47011bb76ff1Sjsg 
si_initial_switch_from_arb_f0_to_f1(struct amdgpu_device * adev)47021bb76ff1Sjsg static int si_initial_switch_from_arb_f0_to_f1(struct amdgpu_device *adev)
47031bb76ff1Sjsg {
47041bb76ff1Sjsg 	return ni_copy_and_switch_arb_sets(adev, MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);
47051bb76ff1Sjsg }
47061bb76ff1Sjsg 
si_reset_to_default(struct amdgpu_device * adev)47071bb76ff1Sjsg static int si_reset_to_default(struct amdgpu_device *adev)
47081bb76ff1Sjsg {
47091bb76ff1Sjsg 	return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_ResetToDefaults) == PPSMC_Result_OK) ?
47101bb76ff1Sjsg 		0 : -EINVAL;
47111bb76ff1Sjsg }
47121bb76ff1Sjsg 
si_force_switch_to_arb_f0(struct amdgpu_device * adev)47131bb76ff1Sjsg static int si_force_switch_to_arb_f0(struct amdgpu_device *adev)
47141bb76ff1Sjsg {
47151bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
47161bb76ff1Sjsg 	u32 tmp;
47171bb76ff1Sjsg 	int ret;
47181bb76ff1Sjsg 
47191bb76ff1Sjsg 	ret = amdgpu_si_read_smc_sram_dword(adev, si_pi->arb_table_start,
47201bb76ff1Sjsg 					    &tmp, si_pi->sram_end);
47211bb76ff1Sjsg 	if (ret)
47221bb76ff1Sjsg 		return ret;
47231bb76ff1Sjsg 
47241bb76ff1Sjsg 	tmp = (tmp >> 24) & 0xff;
47251bb76ff1Sjsg 
47261bb76ff1Sjsg 	if (tmp == MC_CG_ARB_FREQ_F0)
47271bb76ff1Sjsg 		return 0;
47281bb76ff1Sjsg 
47291bb76ff1Sjsg 	return ni_copy_and_switch_arb_sets(adev, tmp, MC_CG_ARB_FREQ_F0);
47301bb76ff1Sjsg }
47311bb76ff1Sjsg 
si_calculate_memory_refresh_rate(struct amdgpu_device * adev,u32 engine_clock)47321bb76ff1Sjsg static u32 si_calculate_memory_refresh_rate(struct amdgpu_device *adev,
47331bb76ff1Sjsg 					    u32 engine_clock)
47341bb76ff1Sjsg {
47351bb76ff1Sjsg 	u32 dram_rows;
47361bb76ff1Sjsg 	u32 dram_refresh_rate;
47371bb76ff1Sjsg 	u32 mc_arb_rfsh_rate;
47381bb76ff1Sjsg 	u32 tmp = (RREG32(MC_ARB_RAMCFG) & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
47391bb76ff1Sjsg 
47401bb76ff1Sjsg 	if (tmp >= 4)
47411bb76ff1Sjsg 		dram_rows = 16384;
47421bb76ff1Sjsg 	else
47431bb76ff1Sjsg 		dram_rows = 1 << (tmp + 10);
47441bb76ff1Sjsg 
47451bb76ff1Sjsg 	dram_refresh_rate = 1 << ((RREG32(MC_SEQ_MISC0) & 0x3) + 3);
47461bb76ff1Sjsg 	mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64;
47471bb76ff1Sjsg 
47481bb76ff1Sjsg 	return mc_arb_rfsh_rate;
47491bb76ff1Sjsg }
47501bb76ff1Sjsg 
si_populate_memory_timing_parameters(struct amdgpu_device * adev,struct rv7xx_pl * pl,SMC_SIslands_MCArbDramTimingRegisterSet * arb_regs)47511bb76ff1Sjsg static int si_populate_memory_timing_parameters(struct amdgpu_device *adev,
47521bb76ff1Sjsg 						struct rv7xx_pl *pl,
47531bb76ff1Sjsg 						SMC_SIslands_MCArbDramTimingRegisterSet *arb_regs)
47541bb76ff1Sjsg {
47551bb76ff1Sjsg 	u32 dram_timing;
47561bb76ff1Sjsg 	u32 dram_timing2;
47571bb76ff1Sjsg 	u32 burst_time;
47581bb76ff1Sjsg 
47591bb76ff1Sjsg 	arb_regs->mc_arb_rfsh_rate =
47601bb76ff1Sjsg 		(u8)si_calculate_memory_refresh_rate(adev, pl->sclk);
47611bb76ff1Sjsg 
47621bb76ff1Sjsg 	amdgpu_atombios_set_engine_dram_timings(adev,
47631bb76ff1Sjsg 					    pl->sclk,
47641bb76ff1Sjsg 		                            pl->mclk);
47651bb76ff1Sjsg 
47661bb76ff1Sjsg 	dram_timing  = RREG32(MC_ARB_DRAM_TIMING);
47671bb76ff1Sjsg 	dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
47681bb76ff1Sjsg 	burst_time = RREG32(MC_ARB_BURST_TIME) & STATE0_MASK;
47691bb76ff1Sjsg 
47701bb76ff1Sjsg 	arb_regs->mc_arb_dram_timing  = cpu_to_be32(dram_timing);
47711bb76ff1Sjsg 	arb_regs->mc_arb_dram_timing2 = cpu_to_be32(dram_timing2);
47721bb76ff1Sjsg 	arb_regs->mc_arb_burst_time = (u8)burst_time;
47731bb76ff1Sjsg 
47741bb76ff1Sjsg 	return 0;
47751bb76ff1Sjsg }
47761bb76ff1Sjsg 
si_do_program_memory_timing_parameters(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state,unsigned int first_arb_set)47771bb76ff1Sjsg static int si_do_program_memory_timing_parameters(struct amdgpu_device *adev,
47781bb76ff1Sjsg 						  struct amdgpu_ps *amdgpu_state,
47791bb76ff1Sjsg 						  unsigned int first_arb_set)
47801bb76ff1Sjsg {
47811bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
47821bb76ff1Sjsg 	struct  si_ps *state = si_get_ps(amdgpu_state);
47831bb76ff1Sjsg 	SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };
47841bb76ff1Sjsg 	int i, ret = 0;
47851bb76ff1Sjsg 
47861bb76ff1Sjsg 	for (i = 0; i < state->performance_level_count; i++) {
47871bb76ff1Sjsg 		ret = si_populate_memory_timing_parameters(adev, &state->performance_levels[i], &arb_regs);
47881bb76ff1Sjsg 		if (ret)
47891bb76ff1Sjsg 			break;
47901bb76ff1Sjsg 		ret = amdgpu_si_copy_bytes_to_smc(adev,
47911bb76ff1Sjsg 						  si_pi->arb_table_start +
47921bb76ff1Sjsg 						  offsetof(SMC_SIslands_MCArbDramTimingRegisters, data) +
47931bb76ff1Sjsg 						  sizeof(SMC_SIslands_MCArbDramTimingRegisterSet) * (first_arb_set + i),
47941bb76ff1Sjsg 						  (u8 *)&arb_regs,
47951bb76ff1Sjsg 						  sizeof(SMC_SIslands_MCArbDramTimingRegisterSet),
47961bb76ff1Sjsg 						  si_pi->sram_end);
47971bb76ff1Sjsg 		if (ret)
47981bb76ff1Sjsg 			break;
47991bb76ff1Sjsg 	}
48001bb76ff1Sjsg 
48011bb76ff1Sjsg 	return ret;
48021bb76ff1Sjsg }
48031bb76ff1Sjsg 
si_program_memory_timing_parameters(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_new_state)48041bb76ff1Sjsg static int si_program_memory_timing_parameters(struct amdgpu_device *adev,
48051bb76ff1Sjsg 					       struct amdgpu_ps *amdgpu_new_state)
48061bb76ff1Sjsg {
48071bb76ff1Sjsg 	return si_do_program_memory_timing_parameters(adev, amdgpu_new_state,
48081bb76ff1Sjsg 						      SISLANDS_DRIVER_STATE_ARB_INDEX);
48091bb76ff1Sjsg }
48101bb76ff1Sjsg 
si_populate_initial_mvdd_value(struct amdgpu_device * adev,struct SISLANDS_SMC_VOLTAGE_VALUE * voltage)48111bb76ff1Sjsg static int si_populate_initial_mvdd_value(struct amdgpu_device *adev,
48121bb76ff1Sjsg 					  struct SISLANDS_SMC_VOLTAGE_VALUE *voltage)
48131bb76ff1Sjsg {
48141bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
48151bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
48161bb76ff1Sjsg 
48171bb76ff1Sjsg 	if (pi->mvdd_control)
48181bb76ff1Sjsg 		return si_populate_voltage_value(adev, &si_pi->mvdd_voltage_table,
48191bb76ff1Sjsg 						 si_pi->mvdd_bootup_value, voltage);
48201bb76ff1Sjsg 
48211bb76ff1Sjsg 	return 0;
48221bb76ff1Sjsg }
48231bb76ff1Sjsg 
si_populate_smc_initial_state(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_initial_state,SISLANDS_SMC_STATETABLE * table)48241bb76ff1Sjsg static int si_populate_smc_initial_state(struct amdgpu_device *adev,
48251bb76ff1Sjsg 					 struct amdgpu_ps *amdgpu_initial_state,
48261bb76ff1Sjsg 					 SISLANDS_SMC_STATETABLE *table)
48271bb76ff1Sjsg {
48281bb76ff1Sjsg 	struct  si_ps *initial_state = si_get_ps(amdgpu_initial_state);
48291bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
48301bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
48311bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
48321bb76ff1Sjsg 	u32 reg;
48331bb76ff1Sjsg 	int ret;
48341bb76ff1Sjsg 
48351bb76ff1Sjsg 	table->initialState.level.mclk.vDLL_CNTL =
48361bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.dll_cntl);
48371bb76ff1Sjsg 	table->initialState.level.mclk.vMCLK_PWRMGT_CNTL =
48381bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.mclk_pwrmgt_cntl);
48391bb76ff1Sjsg 	table->initialState.level.mclk.vMPLL_AD_FUNC_CNTL =
48401bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.mpll_ad_func_cntl);
48411bb76ff1Sjsg 	table->initialState.level.mclk.vMPLL_DQ_FUNC_CNTL =
48421bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.mpll_dq_func_cntl);
48431bb76ff1Sjsg 	table->initialState.level.mclk.vMPLL_FUNC_CNTL =
48441bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.mpll_func_cntl);
48451bb76ff1Sjsg 	table->initialState.level.mclk.vMPLL_FUNC_CNTL_1 =
48461bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.mpll_func_cntl_1);
48471bb76ff1Sjsg 	table->initialState.level.mclk.vMPLL_FUNC_CNTL_2 =
48481bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.mpll_func_cntl_2);
48491bb76ff1Sjsg 	table->initialState.level.mclk.vMPLL_SS =
48501bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.mpll_ss1);
48511bb76ff1Sjsg 	table->initialState.level.mclk.vMPLL_SS2 =
48521bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.mpll_ss2);
48531bb76ff1Sjsg 
48541bb76ff1Sjsg 	table->initialState.level.mclk.mclk_value =
48551bb76ff1Sjsg 		cpu_to_be32(initial_state->performance_levels[0].mclk);
48561bb76ff1Sjsg 
48571bb76ff1Sjsg 	table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL =
48581bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl);
48591bb76ff1Sjsg 	table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_2 =
48601bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_2);
48611bb76ff1Sjsg 	table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_3 =
48621bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_3);
48631bb76ff1Sjsg 	table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_4 =
48641bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_4);
48651bb76ff1Sjsg 	table->initialState.level.sclk.vCG_SPLL_SPREAD_SPECTRUM =
48661bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_spread_spectrum);
48671bb76ff1Sjsg 	table->initialState.level.sclk.vCG_SPLL_SPREAD_SPECTRUM_2  =
48681bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_spread_spectrum_2);
48691bb76ff1Sjsg 
48701bb76ff1Sjsg 	table->initialState.level.sclk.sclk_value =
48711bb76ff1Sjsg 		cpu_to_be32(initial_state->performance_levels[0].sclk);
48721bb76ff1Sjsg 
48731bb76ff1Sjsg 	table->initialState.level.arbRefreshState =
48741bb76ff1Sjsg 		SISLANDS_INITIAL_STATE_ARB_INDEX;
48751bb76ff1Sjsg 
48761bb76ff1Sjsg 	table->initialState.level.ACIndex = 0;
48771bb76ff1Sjsg 
48781bb76ff1Sjsg 	ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,
48791bb76ff1Sjsg 					initial_state->performance_levels[0].vddc,
48801bb76ff1Sjsg 					&table->initialState.level.vddc);
48811bb76ff1Sjsg 
48821bb76ff1Sjsg 	if (!ret) {
48831bb76ff1Sjsg 		u16 std_vddc;
48841bb76ff1Sjsg 
48851bb76ff1Sjsg 		ret = si_get_std_voltage_value(adev,
48861bb76ff1Sjsg 					       &table->initialState.level.vddc,
48871bb76ff1Sjsg 					       &std_vddc);
48881bb76ff1Sjsg 		if (!ret)
48891bb76ff1Sjsg 			si_populate_std_voltage_value(adev, std_vddc,
48901bb76ff1Sjsg 						      table->initialState.level.vddc.index,
48911bb76ff1Sjsg 						      &table->initialState.level.std_vddc);
48921bb76ff1Sjsg 	}
48931bb76ff1Sjsg 
48941bb76ff1Sjsg 	if (eg_pi->vddci_control)
48951bb76ff1Sjsg 		si_populate_voltage_value(adev,
48961bb76ff1Sjsg 					  &eg_pi->vddci_voltage_table,
48971bb76ff1Sjsg 					  initial_state->performance_levels[0].vddci,
48981bb76ff1Sjsg 					  &table->initialState.level.vddci);
48991bb76ff1Sjsg 
49001bb76ff1Sjsg 	if (si_pi->vddc_phase_shed_control)
49011bb76ff1Sjsg 		si_populate_phase_shedding_value(adev,
49021bb76ff1Sjsg 						 &adev->pm.dpm.dyn_state.phase_shedding_limits_table,
49031bb76ff1Sjsg 						 initial_state->performance_levels[0].vddc,
49041bb76ff1Sjsg 						 initial_state->performance_levels[0].sclk,
49051bb76ff1Sjsg 						 initial_state->performance_levels[0].mclk,
49061bb76ff1Sjsg 						 &table->initialState.level.vddc);
49071bb76ff1Sjsg 
49081bb76ff1Sjsg 	si_populate_initial_mvdd_value(adev, &table->initialState.level.mvdd);
49091bb76ff1Sjsg 
49101bb76ff1Sjsg 	reg = CG_R(0xffff) | CG_L(0);
49111bb76ff1Sjsg 	table->initialState.level.aT = cpu_to_be32(reg);
49121bb76ff1Sjsg 	table->initialState.level.bSP = cpu_to_be32(pi->dsp);
49131bb76ff1Sjsg 	table->initialState.level.gen2PCIE = (u8)si_pi->boot_pcie_gen;
49141bb76ff1Sjsg 
49151bb76ff1Sjsg 	if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5) {
49161bb76ff1Sjsg 		table->initialState.level.strobeMode =
49171bb76ff1Sjsg 			si_get_strobe_mode_settings(adev,
49181bb76ff1Sjsg 						    initial_state->performance_levels[0].mclk);
49191bb76ff1Sjsg 
49201bb76ff1Sjsg 		if (initial_state->performance_levels[0].mclk > pi->mclk_edc_enable_threshold)
49211bb76ff1Sjsg 			table->initialState.level.mcFlags = SISLANDS_SMC_MC_EDC_RD_FLAG | SISLANDS_SMC_MC_EDC_WR_FLAG;
49221bb76ff1Sjsg 		else
49231bb76ff1Sjsg 			table->initialState.level.mcFlags =  0;
49241bb76ff1Sjsg 	}
49251bb76ff1Sjsg 
49261bb76ff1Sjsg 	table->initialState.levelCount = 1;
49271bb76ff1Sjsg 
49281bb76ff1Sjsg 	table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
49291bb76ff1Sjsg 
49301bb76ff1Sjsg 	table->initialState.level.dpm2.MaxPS = 0;
49311bb76ff1Sjsg 	table->initialState.level.dpm2.NearTDPDec = 0;
49321bb76ff1Sjsg 	table->initialState.level.dpm2.AboveSafeInc = 0;
49331bb76ff1Sjsg 	table->initialState.level.dpm2.BelowSafeInc = 0;
49341bb76ff1Sjsg 	table->initialState.level.dpm2.PwrEfficiencyRatio = 0;
49351bb76ff1Sjsg 
49361bb76ff1Sjsg 	reg = MIN_POWER_MASK | MAX_POWER_MASK;
49371bb76ff1Sjsg 	table->initialState.level.SQPowerThrottle = cpu_to_be32(reg);
49381bb76ff1Sjsg 
49391bb76ff1Sjsg 	reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
49401bb76ff1Sjsg 	table->initialState.level.SQPowerThrottle_2 = cpu_to_be32(reg);
49411bb76ff1Sjsg 
49421bb76ff1Sjsg 	return 0;
49431bb76ff1Sjsg }
49441bb76ff1Sjsg 
si_gen_pcie_gen_support(struct amdgpu_device * adev,u32 sys_mask,enum si_pcie_gen asic_gen,enum si_pcie_gen default_gen)49451bb76ff1Sjsg static enum si_pcie_gen si_gen_pcie_gen_support(struct amdgpu_device *adev,
49461bb76ff1Sjsg 						u32 sys_mask,
49471bb76ff1Sjsg 						enum si_pcie_gen asic_gen,
49481bb76ff1Sjsg 						enum si_pcie_gen default_gen)
49491bb76ff1Sjsg {
49501bb76ff1Sjsg 	switch (asic_gen) {
49511bb76ff1Sjsg 	case SI_PCIE_GEN1:
49521bb76ff1Sjsg 		return SI_PCIE_GEN1;
49531bb76ff1Sjsg 	case SI_PCIE_GEN2:
49541bb76ff1Sjsg 		return SI_PCIE_GEN2;
49551bb76ff1Sjsg 	case SI_PCIE_GEN3:
49561bb76ff1Sjsg 		return SI_PCIE_GEN3;
49571bb76ff1Sjsg 	default:
49581bb76ff1Sjsg 		if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3) &&
49591bb76ff1Sjsg 		    (default_gen == SI_PCIE_GEN3))
49601bb76ff1Sjsg 			return SI_PCIE_GEN3;
49611bb76ff1Sjsg 		else if ((sys_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2) &&
49621bb76ff1Sjsg 			 (default_gen == SI_PCIE_GEN2))
49631bb76ff1Sjsg 			return SI_PCIE_GEN2;
49641bb76ff1Sjsg 		else
49651bb76ff1Sjsg 			return SI_PCIE_GEN1;
49661bb76ff1Sjsg 	}
49671bb76ff1Sjsg 	return SI_PCIE_GEN1;
49681bb76ff1Sjsg }
49691bb76ff1Sjsg 
si_populate_smc_acpi_state(struct amdgpu_device * adev,SISLANDS_SMC_STATETABLE * table)49701bb76ff1Sjsg static int si_populate_smc_acpi_state(struct amdgpu_device *adev,
49711bb76ff1Sjsg 				      SISLANDS_SMC_STATETABLE *table)
49721bb76ff1Sjsg {
49731bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
49741bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
49751bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
49761bb76ff1Sjsg 	u32 spll_func_cntl = si_pi->clock_registers.cg_spll_func_cntl;
49771bb76ff1Sjsg 	u32 spll_func_cntl_2 = si_pi->clock_registers.cg_spll_func_cntl_2;
49781bb76ff1Sjsg 	u32 spll_func_cntl_3 = si_pi->clock_registers.cg_spll_func_cntl_3;
49791bb76ff1Sjsg 	u32 spll_func_cntl_4 = si_pi->clock_registers.cg_spll_func_cntl_4;
49801bb76ff1Sjsg 	u32 dll_cntl = si_pi->clock_registers.dll_cntl;
49811bb76ff1Sjsg 	u32 mclk_pwrmgt_cntl = si_pi->clock_registers.mclk_pwrmgt_cntl;
49821bb76ff1Sjsg 	u32 mpll_ad_func_cntl = si_pi->clock_registers.mpll_ad_func_cntl;
49831bb76ff1Sjsg 	u32 mpll_dq_func_cntl = si_pi->clock_registers.mpll_dq_func_cntl;
49841bb76ff1Sjsg 	u32 mpll_func_cntl = si_pi->clock_registers.mpll_func_cntl;
49851bb76ff1Sjsg 	u32 mpll_func_cntl_1 = si_pi->clock_registers.mpll_func_cntl_1;
49861bb76ff1Sjsg 	u32 mpll_func_cntl_2 = si_pi->clock_registers.mpll_func_cntl_2;
49871bb76ff1Sjsg 	u32 reg;
49881bb76ff1Sjsg 	int ret;
49891bb76ff1Sjsg 
49901bb76ff1Sjsg 	table->ACPIState = table->initialState;
49911bb76ff1Sjsg 
49921bb76ff1Sjsg 	table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
49931bb76ff1Sjsg 
49941bb76ff1Sjsg 	if (pi->acpi_vddc) {
49951bb76ff1Sjsg 		ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,
49961bb76ff1Sjsg 						pi->acpi_vddc, &table->ACPIState.level.vddc);
49971bb76ff1Sjsg 		if (!ret) {
49981bb76ff1Sjsg 			u16 std_vddc;
49991bb76ff1Sjsg 
50001bb76ff1Sjsg 			ret = si_get_std_voltage_value(adev,
50011bb76ff1Sjsg 						       &table->ACPIState.level.vddc, &std_vddc);
50021bb76ff1Sjsg 			if (!ret)
50031bb76ff1Sjsg 				si_populate_std_voltage_value(adev, std_vddc,
50041bb76ff1Sjsg 							      table->ACPIState.level.vddc.index,
50051bb76ff1Sjsg 							      &table->ACPIState.level.std_vddc);
50061bb76ff1Sjsg 		}
50071bb76ff1Sjsg 		table->ACPIState.level.gen2PCIE = si_pi->acpi_pcie_gen;
50081bb76ff1Sjsg 
50091bb76ff1Sjsg 		if (si_pi->vddc_phase_shed_control) {
50101bb76ff1Sjsg 			si_populate_phase_shedding_value(adev,
50111bb76ff1Sjsg 							 &adev->pm.dpm.dyn_state.phase_shedding_limits_table,
50121bb76ff1Sjsg 							 pi->acpi_vddc,
50131bb76ff1Sjsg 							 0,
50141bb76ff1Sjsg 							 0,
50151bb76ff1Sjsg 							 &table->ACPIState.level.vddc);
50161bb76ff1Sjsg 		}
50171bb76ff1Sjsg 	} else {
50181bb76ff1Sjsg 		ret = si_populate_voltage_value(adev, &eg_pi->vddc_voltage_table,
50191bb76ff1Sjsg 						pi->min_vddc_in_table, &table->ACPIState.level.vddc);
50201bb76ff1Sjsg 		if (!ret) {
50211bb76ff1Sjsg 			u16 std_vddc;
50221bb76ff1Sjsg 
50231bb76ff1Sjsg 			ret = si_get_std_voltage_value(adev,
50241bb76ff1Sjsg 						       &table->ACPIState.level.vddc, &std_vddc);
50251bb76ff1Sjsg 
50261bb76ff1Sjsg 			if (!ret)
50271bb76ff1Sjsg 				si_populate_std_voltage_value(adev, std_vddc,
50281bb76ff1Sjsg 							      table->ACPIState.level.vddc.index,
50291bb76ff1Sjsg 							      &table->ACPIState.level.std_vddc);
50301bb76ff1Sjsg 		}
50311bb76ff1Sjsg 		table->ACPIState.level.gen2PCIE =
50321bb76ff1Sjsg 			(u8)si_gen_pcie_gen_support(adev,
50331bb76ff1Sjsg 						    si_pi->sys_pcie_mask,
50341bb76ff1Sjsg 						    si_pi->boot_pcie_gen,
50351bb76ff1Sjsg 						    SI_PCIE_GEN1);
50361bb76ff1Sjsg 
50371bb76ff1Sjsg 		if (si_pi->vddc_phase_shed_control)
50381bb76ff1Sjsg 			si_populate_phase_shedding_value(adev,
50391bb76ff1Sjsg 							 &adev->pm.dpm.dyn_state.phase_shedding_limits_table,
50401bb76ff1Sjsg 							 pi->min_vddc_in_table,
50411bb76ff1Sjsg 							 0,
50421bb76ff1Sjsg 							 0,
50431bb76ff1Sjsg 							 &table->ACPIState.level.vddc);
50441bb76ff1Sjsg 	}
50451bb76ff1Sjsg 
50461bb76ff1Sjsg 	if (pi->acpi_vddc) {
50471bb76ff1Sjsg 		if (eg_pi->acpi_vddci)
50481bb76ff1Sjsg 			si_populate_voltage_value(adev, &eg_pi->vddci_voltage_table,
50491bb76ff1Sjsg 						  eg_pi->acpi_vddci,
50501bb76ff1Sjsg 						  &table->ACPIState.level.vddci);
50511bb76ff1Sjsg 	}
50521bb76ff1Sjsg 
50531bb76ff1Sjsg 	mclk_pwrmgt_cntl |= MRDCK0_RESET | MRDCK1_RESET;
50541bb76ff1Sjsg 	mclk_pwrmgt_cntl &= ~(MRDCK0_PDNB | MRDCK1_PDNB);
50551bb76ff1Sjsg 
50561bb76ff1Sjsg 	dll_cntl &= ~(MRDCK0_BYPASS | MRDCK1_BYPASS);
50571bb76ff1Sjsg 
50581bb76ff1Sjsg 	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
50591bb76ff1Sjsg 	spll_func_cntl_2 |= SCLK_MUX_SEL(4);
50601bb76ff1Sjsg 
50611bb76ff1Sjsg 	table->ACPIState.level.mclk.vDLL_CNTL =
50621bb76ff1Sjsg 		cpu_to_be32(dll_cntl);
50631bb76ff1Sjsg 	table->ACPIState.level.mclk.vMCLK_PWRMGT_CNTL =
50641bb76ff1Sjsg 		cpu_to_be32(mclk_pwrmgt_cntl);
50651bb76ff1Sjsg 	table->ACPIState.level.mclk.vMPLL_AD_FUNC_CNTL =
50661bb76ff1Sjsg 		cpu_to_be32(mpll_ad_func_cntl);
50671bb76ff1Sjsg 	table->ACPIState.level.mclk.vMPLL_DQ_FUNC_CNTL =
50681bb76ff1Sjsg 		cpu_to_be32(mpll_dq_func_cntl);
50691bb76ff1Sjsg 	table->ACPIState.level.mclk.vMPLL_FUNC_CNTL =
50701bb76ff1Sjsg 		cpu_to_be32(mpll_func_cntl);
50711bb76ff1Sjsg 	table->ACPIState.level.mclk.vMPLL_FUNC_CNTL_1 =
50721bb76ff1Sjsg 		cpu_to_be32(mpll_func_cntl_1);
50731bb76ff1Sjsg 	table->ACPIState.level.mclk.vMPLL_FUNC_CNTL_2 =
50741bb76ff1Sjsg 		cpu_to_be32(mpll_func_cntl_2);
50751bb76ff1Sjsg 	table->ACPIState.level.mclk.vMPLL_SS =
50761bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.mpll_ss1);
50771bb76ff1Sjsg 	table->ACPIState.level.mclk.vMPLL_SS2 =
50781bb76ff1Sjsg 		cpu_to_be32(si_pi->clock_registers.mpll_ss2);
50791bb76ff1Sjsg 
50801bb76ff1Sjsg 	table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL =
50811bb76ff1Sjsg 		cpu_to_be32(spll_func_cntl);
50821bb76ff1Sjsg 	table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_2 =
50831bb76ff1Sjsg 		cpu_to_be32(spll_func_cntl_2);
50841bb76ff1Sjsg 	table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_3 =
50851bb76ff1Sjsg 		cpu_to_be32(spll_func_cntl_3);
50861bb76ff1Sjsg 	table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_4 =
50871bb76ff1Sjsg 		cpu_to_be32(spll_func_cntl_4);
50881bb76ff1Sjsg 
50891bb76ff1Sjsg 	table->ACPIState.level.mclk.mclk_value = 0;
50901bb76ff1Sjsg 	table->ACPIState.level.sclk.sclk_value = 0;
50911bb76ff1Sjsg 
50921bb76ff1Sjsg 	si_populate_mvdd_value(adev, 0, &table->ACPIState.level.mvdd);
50931bb76ff1Sjsg 
50941bb76ff1Sjsg 	if (eg_pi->dynamic_ac_timing)
50951bb76ff1Sjsg 		table->ACPIState.level.ACIndex = 0;
50961bb76ff1Sjsg 
50971bb76ff1Sjsg 	table->ACPIState.level.dpm2.MaxPS = 0;
50981bb76ff1Sjsg 	table->ACPIState.level.dpm2.NearTDPDec = 0;
50991bb76ff1Sjsg 	table->ACPIState.level.dpm2.AboveSafeInc = 0;
51001bb76ff1Sjsg 	table->ACPIState.level.dpm2.BelowSafeInc = 0;
51011bb76ff1Sjsg 	table->ACPIState.level.dpm2.PwrEfficiencyRatio = 0;
51021bb76ff1Sjsg 
51031bb76ff1Sjsg 	reg = MIN_POWER_MASK | MAX_POWER_MASK;
51041bb76ff1Sjsg 	table->ACPIState.level.SQPowerThrottle = cpu_to_be32(reg);
51051bb76ff1Sjsg 
51061bb76ff1Sjsg 	reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
51071bb76ff1Sjsg 	table->ACPIState.level.SQPowerThrottle_2 = cpu_to_be32(reg);
51081bb76ff1Sjsg 
51091bb76ff1Sjsg 	return 0;
51101bb76ff1Sjsg }
51111bb76ff1Sjsg 
si_populate_ulv_state(struct amdgpu_device * adev,struct SISLANDS_SMC_SWSTATE_SINGLE * state)51121bb76ff1Sjsg static int si_populate_ulv_state(struct amdgpu_device *adev,
51131bb76ff1Sjsg 				 struct SISLANDS_SMC_SWSTATE_SINGLE *state)
51141bb76ff1Sjsg {
51151bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
51161bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
51171bb76ff1Sjsg 	struct si_ulv_param *ulv = &si_pi->ulv;
51181bb76ff1Sjsg 	u32 sclk_in_sr = 1350; /* ??? */
51191bb76ff1Sjsg 	int ret;
51201bb76ff1Sjsg 
51211bb76ff1Sjsg 	ret = si_convert_power_level_to_smc(adev, &ulv->pl,
51221bb76ff1Sjsg 					    &state->level);
51231bb76ff1Sjsg 	if (!ret) {
51241bb76ff1Sjsg 		if (eg_pi->sclk_deep_sleep) {
51251bb76ff1Sjsg 			if (sclk_in_sr <= SCLK_MIN_DEEPSLEEP_FREQ)
51261bb76ff1Sjsg 				state->level.stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_BYPASS;
51271bb76ff1Sjsg 			else
51281bb76ff1Sjsg 				state->level.stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE;
51291bb76ff1Sjsg 		}
51301bb76ff1Sjsg 		if (ulv->one_pcie_lane_in_ulv)
51311bb76ff1Sjsg 			state->flags |= PPSMC_SWSTATE_FLAG_PCIE_X1;
51321bb76ff1Sjsg 		state->level.arbRefreshState = (u8)(SISLANDS_ULV_STATE_ARB_INDEX);
51331bb76ff1Sjsg 		state->level.ACIndex = 1;
51341bb76ff1Sjsg 		state->level.std_vddc = state->level.vddc;
51351bb76ff1Sjsg 		state->levelCount = 1;
51361bb76ff1Sjsg 
51371bb76ff1Sjsg 		state->flags |= PPSMC_SWSTATE_FLAG_DC;
51381bb76ff1Sjsg 	}
51391bb76ff1Sjsg 
51401bb76ff1Sjsg 	return ret;
51411bb76ff1Sjsg }
51421bb76ff1Sjsg 
si_program_ulv_memory_timing_parameters(struct amdgpu_device * adev)51431bb76ff1Sjsg static int si_program_ulv_memory_timing_parameters(struct amdgpu_device *adev)
51441bb76ff1Sjsg {
51451bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
51461bb76ff1Sjsg 	struct si_ulv_param *ulv = &si_pi->ulv;
51471bb76ff1Sjsg 	SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };
51481bb76ff1Sjsg 	int ret;
51491bb76ff1Sjsg 
51501bb76ff1Sjsg 	ret = si_populate_memory_timing_parameters(adev, &ulv->pl,
51511bb76ff1Sjsg 						   &arb_regs);
51521bb76ff1Sjsg 	if (ret)
51531bb76ff1Sjsg 		return ret;
51541bb76ff1Sjsg 
51551bb76ff1Sjsg 	si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_ulv_volt_change_delay,
51561bb76ff1Sjsg 				   ulv->volt_change_delay);
51571bb76ff1Sjsg 
51581bb76ff1Sjsg 	ret = amdgpu_si_copy_bytes_to_smc(adev,
51591bb76ff1Sjsg 					  si_pi->arb_table_start +
51601bb76ff1Sjsg 					  offsetof(SMC_SIslands_MCArbDramTimingRegisters, data) +
51611bb76ff1Sjsg 					  sizeof(SMC_SIslands_MCArbDramTimingRegisterSet) * SISLANDS_ULV_STATE_ARB_INDEX,
51621bb76ff1Sjsg 					  (u8 *)&arb_regs,
51631bb76ff1Sjsg 					  sizeof(SMC_SIslands_MCArbDramTimingRegisterSet),
51641bb76ff1Sjsg 					  si_pi->sram_end);
51651bb76ff1Sjsg 
51661bb76ff1Sjsg 	return ret;
51671bb76ff1Sjsg }
51681bb76ff1Sjsg 
si_get_mvdd_configuration(struct amdgpu_device * adev)51691bb76ff1Sjsg static void si_get_mvdd_configuration(struct amdgpu_device *adev)
51701bb76ff1Sjsg {
51711bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
51721bb76ff1Sjsg 
51731bb76ff1Sjsg 	pi->mvdd_split_frequency = 30000;
51741bb76ff1Sjsg }
51751bb76ff1Sjsg 
si_init_smc_table(struct amdgpu_device * adev)51761bb76ff1Sjsg static int si_init_smc_table(struct amdgpu_device *adev)
51771bb76ff1Sjsg {
51781bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
51791bb76ff1Sjsg 	struct amdgpu_ps *amdgpu_boot_state = adev->pm.dpm.boot_ps;
51801bb76ff1Sjsg 	const struct si_ulv_param *ulv = &si_pi->ulv;
51811bb76ff1Sjsg 	SISLANDS_SMC_STATETABLE  *table = &si_pi->smc_statetable;
51821bb76ff1Sjsg 	int ret;
51831bb76ff1Sjsg 	u32 lane_width;
51841bb76ff1Sjsg 	u32 vr_hot_gpio;
51851bb76ff1Sjsg 
51861bb76ff1Sjsg 	si_populate_smc_voltage_tables(adev, table);
51871bb76ff1Sjsg 
51881bb76ff1Sjsg 	switch (adev->pm.int_thermal_type) {
51891bb76ff1Sjsg 	case THERMAL_TYPE_SI:
51901bb76ff1Sjsg 	case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
51911bb76ff1Sjsg 		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
51921bb76ff1Sjsg 		break;
51931bb76ff1Sjsg 	case THERMAL_TYPE_NONE:
51941bb76ff1Sjsg 		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
51951bb76ff1Sjsg 		break;
51961bb76ff1Sjsg 	default:
51971bb76ff1Sjsg 		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
51981bb76ff1Sjsg 		break;
51991bb76ff1Sjsg 	}
52001bb76ff1Sjsg 
52011bb76ff1Sjsg 	if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
52021bb76ff1Sjsg 		table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
52031bb76ff1Sjsg 
52041bb76ff1Sjsg 	if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT) {
52051bb76ff1Sjsg 		if ((adev->pdev->device != 0x6818) && (adev->pdev->device != 0x6819))
52061bb76ff1Sjsg 			table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
52071bb76ff1Sjsg 	}
52081bb76ff1Sjsg 
52091bb76ff1Sjsg 	if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
52101bb76ff1Sjsg 		table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
52111bb76ff1Sjsg 
52121bb76ff1Sjsg 	if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5)
52131bb76ff1Sjsg 		table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
52141bb76ff1Sjsg 
52151bb76ff1Sjsg 	if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY)
52161bb76ff1Sjsg 		table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH;
52171bb76ff1Sjsg 
52181bb76ff1Sjsg 	if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE) {
52191bb76ff1Sjsg 		table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO;
52201bb76ff1Sjsg 		vr_hot_gpio = adev->pm.dpm.backbias_response_time;
52211bb76ff1Sjsg 		si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_vr_hot_gpio,
52221bb76ff1Sjsg 					   vr_hot_gpio);
52231bb76ff1Sjsg 	}
52241bb76ff1Sjsg 
52251bb76ff1Sjsg 	ret = si_populate_smc_initial_state(adev, amdgpu_boot_state, table);
52261bb76ff1Sjsg 	if (ret)
52271bb76ff1Sjsg 		return ret;
52281bb76ff1Sjsg 
52291bb76ff1Sjsg 	ret = si_populate_smc_acpi_state(adev, table);
52301bb76ff1Sjsg 	if (ret)
52311bb76ff1Sjsg 		return ret;
52321bb76ff1Sjsg 
52331bb76ff1Sjsg 	table->driverState.flags = table->initialState.flags;
52341bb76ff1Sjsg 	table->driverState.levelCount = table->initialState.levelCount;
52351bb76ff1Sjsg 	table->driverState.levels[0] = table->initialState.level;
52361bb76ff1Sjsg 
52371bb76ff1Sjsg 	ret = si_do_program_memory_timing_parameters(adev, amdgpu_boot_state,
52381bb76ff1Sjsg 						     SISLANDS_INITIAL_STATE_ARB_INDEX);
52391bb76ff1Sjsg 	if (ret)
52401bb76ff1Sjsg 		return ret;
52411bb76ff1Sjsg 
52421bb76ff1Sjsg 	if (ulv->supported && ulv->pl.vddc) {
52431bb76ff1Sjsg 		ret = si_populate_ulv_state(adev, &table->ULVState);
52441bb76ff1Sjsg 		if (ret)
52451bb76ff1Sjsg 			return ret;
52461bb76ff1Sjsg 
52471bb76ff1Sjsg 		ret = si_program_ulv_memory_timing_parameters(adev);
52481bb76ff1Sjsg 		if (ret)
52491bb76ff1Sjsg 			return ret;
52501bb76ff1Sjsg 
52511bb76ff1Sjsg 		WREG32(CG_ULV_CONTROL, ulv->cg_ulv_control);
52521bb76ff1Sjsg 		WREG32(CG_ULV_PARAMETER, ulv->cg_ulv_parameter);
52531bb76ff1Sjsg 
52541bb76ff1Sjsg 		lane_width = amdgpu_get_pcie_lanes(adev);
52551bb76ff1Sjsg 		si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width, lane_width);
52561bb76ff1Sjsg 	} else {
52571bb76ff1Sjsg 		table->ULVState = table->initialState;
52581bb76ff1Sjsg 	}
52591bb76ff1Sjsg 
52601bb76ff1Sjsg 	return amdgpu_si_copy_bytes_to_smc(adev, si_pi->state_table_start,
52611bb76ff1Sjsg 					   (u8 *)table, sizeof(SISLANDS_SMC_STATETABLE),
52621bb76ff1Sjsg 					   si_pi->sram_end);
52631bb76ff1Sjsg }
52641bb76ff1Sjsg 
si_calculate_sclk_params(struct amdgpu_device * adev,u32 engine_clock,SISLANDS_SMC_SCLK_VALUE * sclk)52651bb76ff1Sjsg static int si_calculate_sclk_params(struct amdgpu_device *adev,
52661bb76ff1Sjsg 				    u32 engine_clock,
52671bb76ff1Sjsg 				    SISLANDS_SMC_SCLK_VALUE *sclk)
52681bb76ff1Sjsg {
52691bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
52701bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
52711bb76ff1Sjsg 	struct atom_clock_dividers dividers;
52721bb76ff1Sjsg 	u32 spll_func_cntl = si_pi->clock_registers.cg_spll_func_cntl;
52731bb76ff1Sjsg 	u32 spll_func_cntl_2 = si_pi->clock_registers.cg_spll_func_cntl_2;
52741bb76ff1Sjsg 	u32 spll_func_cntl_3 = si_pi->clock_registers.cg_spll_func_cntl_3;
52751bb76ff1Sjsg 	u32 spll_func_cntl_4 = si_pi->clock_registers.cg_spll_func_cntl_4;
52761bb76ff1Sjsg 	u32 cg_spll_spread_spectrum = si_pi->clock_registers.cg_spll_spread_spectrum;
52771bb76ff1Sjsg 	u32 cg_spll_spread_spectrum_2 = si_pi->clock_registers.cg_spll_spread_spectrum_2;
52781bb76ff1Sjsg 	u64 tmp;
52791bb76ff1Sjsg 	u32 reference_clock = adev->clock.spll.reference_freq;
52801bb76ff1Sjsg 	u32 reference_divider;
52811bb76ff1Sjsg 	u32 fbdiv;
52821bb76ff1Sjsg 	int ret;
52831bb76ff1Sjsg 
52841bb76ff1Sjsg 	ret = amdgpu_atombios_get_clock_dividers(adev, COMPUTE_ENGINE_PLL_PARAM,
52851bb76ff1Sjsg 					     engine_clock, false, &dividers);
52861bb76ff1Sjsg 	if (ret)
52871bb76ff1Sjsg 		return ret;
52881bb76ff1Sjsg 
52891bb76ff1Sjsg 	reference_divider = 1 + dividers.ref_div;
52901bb76ff1Sjsg 
52911bb76ff1Sjsg 	tmp = (u64) engine_clock * reference_divider * dividers.post_div * 16384;
52921bb76ff1Sjsg 	do_div(tmp, reference_clock);
52931bb76ff1Sjsg 	fbdiv = (u32) tmp;
52941bb76ff1Sjsg 
52951bb76ff1Sjsg 	spll_func_cntl &= ~(SPLL_PDIV_A_MASK | SPLL_REF_DIV_MASK);
52961bb76ff1Sjsg 	spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
52971bb76ff1Sjsg 	spll_func_cntl |= SPLL_PDIV_A(dividers.post_div);
52981bb76ff1Sjsg 
52991bb76ff1Sjsg 	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
53001bb76ff1Sjsg 	spll_func_cntl_2 |= SCLK_MUX_SEL(2);
53011bb76ff1Sjsg 
53021bb76ff1Sjsg 	spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
53031bb76ff1Sjsg 	spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
53041bb76ff1Sjsg 	spll_func_cntl_3 |= SPLL_DITHEN;
53051bb76ff1Sjsg 
53061bb76ff1Sjsg 	if (pi->sclk_ss) {
53071bb76ff1Sjsg 		struct amdgpu_atom_ss ss;
53081bb76ff1Sjsg 		u32 vco_freq = engine_clock * dividers.post_div;
53091bb76ff1Sjsg 
53101bb76ff1Sjsg 		if (amdgpu_atombios_get_asic_ss_info(adev, &ss,
53111bb76ff1Sjsg 						     ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
53121bb76ff1Sjsg 			u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
53131bb76ff1Sjsg 			u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000);
53141bb76ff1Sjsg 
53151bb76ff1Sjsg 			cg_spll_spread_spectrum &= ~CLK_S_MASK;
53161bb76ff1Sjsg 			cg_spll_spread_spectrum |= CLK_S(clk_s);
53171bb76ff1Sjsg 			cg_spll_spread_spectrum |= SSEN;
53181bb76ff1Sjsg 
53191bb76ff1Sjsg 			cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
53201bb76ff1Sjsg 			cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
53211bb76ff1Sjsg 		}
53221bb76ff1Sjsg 	}
53231bb76ff1Sjsg 
53241bb76ff1Sjsg 	sclk->sclk_value = engine_clock;
53251bb76ff1Sjsg 	sclk->vCG_SPLL_FUNC_CNTL = spll_func_cntl;
53261bb76ff1Sjsg 	sclk->vCG_SPLL_FUNC_CNTL_2 = spll_func_cntl_2;
53271bb76ff1Sjsg 	sclk->vCG_SPLL_FUNC_CNTL_3 = spll_func_cntl_3;
53281bb76ff1Sjsg 	sclk->vCG_SPLL_FUNC_CNTL_4 = spll_func_cntl_4;
53291bb76ff1Sjsg 	sclk->vCG_SPLL_SPREAD_SPECTRUM = cg_spll_spread_spectrum;
53301bb76ff1Sjsg 	sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cg_spll_spread_spectrum_2;
53311bb76ff1Sjsg 
53321bb76ff1Sjsg 	return 0;
53331bb76ff1Sjsg }
53341bb76ff1Sjsg 
si_populate_sclk_value(struct amdgpu_device * adev,u32 engine_clock,SISLANDS_SMC_SCLK_VALUE * sclk)53351bb76ff1Sjsg static int si_populate_sclk_value(struct amdgpu_device *adev,
53361bb76ff1Sjsg 				  u32 engine_clock,
53371bb76ff1Sjsg 				  SISLANDS_SMC_SCLK_VALUE *sclk)
53381bb76ff1Sjsg {
53391bb76ff1Sjsg 	SISLANDS_SMC_SCLK_VALUE sclk_tmp;
53401bb76ff1Sjsg 	int ret;
53411bb76ff1Sjsg 
53421bb76ff1Sjsg 	ret = si_calculate_sclk_params(adev, engine_clock, &sclk_tmp);
53431bb76ff1Sjsg 	if (!ret) {
53441bb76ff1Sjsg 		sclk->sclk_value = cpu_to_be32(sclk_tmp.sclk_value);
53451bb76ff1Sjsg 		sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL);
53461bb76ff1Sjsg 		sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_2);
53471bb76ff1Sjsg 		sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_3);
53481bb76ff1Sjsg 		sclk->vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_4);
53491bb76ff1Sjsg 		sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM);
53501bb76ff1Sjsg 		sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM_2);
53511bb76ff1Sjsg 	}
53521bb76ff1Sjsg 
53531bb76ff1Sjsg 	return ret;
53541bb76ff1Sjsg }
53551bb76ff1Sjsg 
si_populate_mclk_value(struct amdgpu_device * adev,u32 engine_clock,u32 memory_clock,SISLANDS_SMC_MCLK_VALUE * mclk,bool strobe_mode,bool dll_state_on)53561bb76ff1Sjsg static int si_populate_mclk_value(struct amdgpu_device *adev,
53571bb76ff1Sjsg 				  u32 engine_clock,
53581bb76ff1Sjsg 				  u32 memory_clock,
53591bb76ff1Sjsg 				  SISLANDS_SMC_MCLK_VALUE *mclk,
53601bb76ff1Sjsg 				  bool strobe_mode,
53611bb76ff1Sjsg 				  bool dll_state_on)
53621bb76ff1Sjsg {
53631bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
53641bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
53651bb76ff1Sjsg 	u32  dll_cntl = si_pi->clock_registers.dll_cntl;
53661bb76ff1Sjsg 	u32  mclk_pwrmgt_cntl = si_pi->clock_registers.mclk_pwrmgt_cntl;
53671bb76ff1Sjsg 	u32  mpll_ad_func_cntl = si_pi->clock_registers.mpll_ad_func_cntl;
53681bb76ff1Sjsg 	u32  mpll_dq_func_cntl = si_pi->clock_registers.mpll_dq_func_cntl;
53691bb76ff1Sjsg 	u32  mpll_func_cntl = si_pi->clock_registers.mpll_func_cntl;
53701bb76ff1Sjsg 	u32  mpll_func_cntl_1 = si_pi->clock_registers.mpll_func_cntl_1;
53711bb76ff1Sjsg 	u32  mpll_func_cntl_2 = si_pi->clock_registers.mpll_func_cntl_2;
53721bb76ff1Sjsg 	u32  mpll_ss1 = si_pi->clock_registers.mpll_ss1;
53731bb76ff1Sjsg 	u32  mpll_ss2 = si_pi->clock_registers.mpll_ss2;
53741bb76ff1Sjsg 	struct atom_mpll_param mpll_param;
53751bb76ff1Sjsg 	int ret;
53761bb76ff1Sjsg 
53771bb76ff1Sjsg 	ret = amdgpu_atombios_get_memory_pll_dividers(adev, memory_clock, strobe_mode, &mpll_param);
53781bb76ff1Sjsg 	if (ret)
53791bb76ff1Sjsg 		return ret;
53801bb76ff1Sjsg 
53811bb76ff1Sjsg 	mpll_func_cntl &= ~BWCTRL_MASK;
53821bb76ff1Sjsg 	mpll_func_cntl |= BWCTRL(mpll_param.bwcntl);
53831bb76ff1Sjsg 
53841bb76ff1Sjsg 	mpll_func_cntl_1 &= ~(CLKF_MASK | CLKFRAC_MASK | VCO_MODE_MASK);
53851bb76ff1Sjsg 	mpll_func_cntl_1 |= CLKF(mpll_param.clkf) |
53861bb76ff1Sjsg 		CLKFRAC(mpll_param.clkfrac) | VCO_MODE(mpll_param.vco_mode);
53871bb76ff1Sjsg 
53881bb76ff1Sjsg 	mpll_ad_func_cntl &= ~YCLK_POST_DIV_MASK;
53891bb76ff1Sjsg 	mpll_ad_func_cntl |= YCLK_POST_DIV(mpll_param.post_div);
53901bb76ff1Sjsg 
53911bb76ff1Sjsg 	if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5) {
53921bb76ff1Sjsg 		mpll_dq_func_cntl &= ~(YCLK_SEL_MASK | YCLK_POST_DIV_MASK);
53931bb76ff1Sjsg 		mpll_dq_func_cntl |= YCLK_SEL(mpll_param.yclk_sel) |
53941bb76ff1Sjsg 			YCLK_POST_DIV(mpll_param.post_div);
53951bb76ff1Sjsg 	}
53961bb76ff1Sjsg 
53971bb76ff1Sjsg 	if (pi->mclk_ss) {
53981bb76ff1Sjsg 		struct amdgpu_atom_ss ss;
53991bb76ff1Sjsg 		u32 freq_nom;
54001bb76ff1Sjsg 		u32 tmp;
54011bb76ff1Sjsg 		u32 reference_clock = adev->clock.mpll.reference_freq;
54021bb76ff1Sjsg 
54031bb76ff1Sjsg 		if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5)
54041bb76ff1Sjsg 			freq_nom = memory_clock * 4;
54051bb76ff1Sjsg 		else
54061bb76ff1Sjsg 			freq_nom = memory_clock * 2;
54071bb76ff1Sjsg 
54081bb76ff1Sjsg 		tmp = freq_nom / reference_clock;
54091bb76ff1Sjsg 		tmp = tmp * tmp;
54101bb76ff1Sjsg 		if (amdgpu_atombios_get_asic_ss_info(adev, &ss,
54111bb76ff1Sjsg 		                                     ASIC_INTERNAL_MEMORY_SS, freq_nom)) {
54121bb76ff1Sjsg 			u32 clks = reference_clock * 5 / ss.rate;
54131bb76ff1Sjsg 			u32 clkv = (u32)((((131 * ss.percentage * ss.rate) / 100) * tmp) / freq_nom);
54141bb76ff1Sjsg 
54151bb76ff1Sjsg 		        mpll_ss1 &= ~CLKV_MASK;
54161bb76ff1Sjsg 		        mpll_ss1 |= CLKV(clkv);
54171bb76ff1Sjsg 
54181bb76ff1Sjsg 		        mpll_ss2 &= ~CLKS_MASK;
54191bb76ff1Sjsg 		        mpll_ss2 |= CLKS(clks);
54201bb76ff1Sjsg 		}
54211bb76ff1Sjsg 	}
54221bb76ff1Sjsg 
54231bb76ff1Sjsg 	mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;
54241bb76ff1Sjsg 	mclk_pwrmgt_cntl |= DLL_SPEED(mpll_param.dll_speed);
54251bb76ff1Sjsg 
54261bb76ff1Sjsg 	if (dll_state_on)
54271bb76ff1Sjsg 		mclk_pwrmgt_cntl |= MRDCK0_PDNB | MRDCK1_PDNB;
54281bb76ff1Sjsg 	else
54291bb76ff1Sjsg 		mclk_pwrmgt_cntl &= ~(MRDCK0_PDNB | MRDCK1_PDNB);
54301bb76ff1Sjsg 
54311bb76ff1Sjsg 	mclk->mclk_value = cpu_to_be32(memory_clock);
54321bb76ff1Sjsg 	mclk->vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl);
54331bb76ff1Sjsg 	mclk->vMPLL_FUNC_CNTL_1 = cpu_to_be32(mpll_func_cntl_1);
54341bb76ff1Sjsg 	mclk->vMPLL_FUNC_CNTL_2 = cpu_to_be32(mpll_func_cntl_2);
54351bb76ff1Sjsg 	mclk->vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
54361bb76ff1Sjsg 	mclk->vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
54371bb76ff1Sjsg 	mclk->vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
54381bb76ff1Sjsg 	mclk->vDLL_CNTL = cpu_to_be32(dll_cntl);
54391bb76ff1Sjsg 	mclk->vMPLL_SS = cpu_to_be32(mpll_ss1);
54401bb76ff1Sjsg 	mclk->vMPLL_SS2 = cpu_to_be32(mpll_ss2);
54411bb76ff1Sjsg 
54421bb76ff1Sjsg 	return 0;
54431bb76ff1Sjsg }
54441bb76ff1Sjsg 
si_populate_smc_sp(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state,SISLANDS_SMC_SWSTATE * smc_state)54451bb76ff1Sjsg static void si_populate_smc_sp(struct amdgpu_device *adev,
54461bb76ff1Sjsg 			       struct amdgpu_ps *amdgpu_state,
54471bb76ff1Sjsg 			       SISLANDS_SMC_SWSTATE *smc_state)
54481bb76ff1Sjsg {
54491bb76ff1Sjsg 	struct  si_ps *ps = si_get_ps(amdgpu_state);
54501bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
54511bb76ff1Sjsg 	int i;
54521bb76ff1Sjsg 
54531bb76ff1Sjsg 	for (i = 0; i < ps->performance_level_count - 1; i++)
54541bb76ff1Sjsg 		smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);
54551bb76ff1Sjsg 
54561bb76ff1Sjsg 	smc_state->levels[ps->performance_level_count - 1].bSP =
54571bb76ff1Sjsg 		cpu_to_be32(pi->psp);
54581bb76ff1Sjsg }
54591bb76ff1Sjsg 
si_convert_power_level_to_smc(struct amdgpu_device * adev,struct rv7xx_pl * pl,SISLANDS_SMC_HW_PERFORMANCE_LEVEL * level)54601bb76ff1Sjsg static int si_convert_power_level_to_smc(struct amdgpu_device *adev,
54611bb76ff1Sjsg 					 struct rv7xx_pl *pl,
54621bb76ff1Sjsg 					 SISLANDS_SMC_HW_PERFORMANCE_LEVEL *level)
54631bb76ff1Sjsg {
54641bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
54651bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
54661bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
54671bb76ff1Sjsg 	int ret;
54681bb76ff1Sjsg 	bool dll_state_on;
54691bb76ff1Sjsg 	u16 std_vddc;
54701bb76ff1Sjsg 	bool gmc_pg = false;
54711bb76ff1Sjsg 
54721bb76ff1Sjsg 	if (eg_pi->pcie_performance_request &&
54731bb76ff1Sjsg 	    (si_pi->force_pcie_gen != SI_PCIE_GEN_INVALID))
54741bb76ff1Sjsg 		level->gen2PCIE = (u8)si_pi->force_pcie_gen;
54751bb76ff1Sjsg 	else
54761bb76ff1Sjsg 		level->gen2PCIE = (u8)pl->pcie_gen;
54771bb76ff1Sjsg 
54781bb76ff1Sjsg 	ret = si_populate_sclk_value(adev, pl->sclk, &level->sclk);
54791bb76ff1Sjsg 	if (ret)
54801bb76ff1Sjsg 		return ret;
54811bb76ff1Sjsg 
54821bb76ff1Sjsg 	level->mcFlags =  0;
54831bb76ff1Sjsg 
54841bb76ff1Sjsg 	if (pi->mclk_stutter_mode_threshold &&
54851bb76ff1Sjsg 	    (pl->mclk <= pi->mclk_stutter_mode_threshold) &&
54861bb76ff1Sjsg 	    !eg_pi->uvd_enabled &&
54871bb76ff1Sjsg 	    (RREG32(DPG_PIPE_STUTTER_CONTROL) & STUTTER_ENABLE) &&
54881bb76ff1Sjsg 	    (adev->pm.dpm.new_active_crtc_count <= 2)) {
54891bb76ff1Sjsg 		level->mcFlags |= SISLANDS_SMC_MC_STUTTER_EN;
54901bb76ff1Sjsg 
54911bb76ff1Sjsg 		if (gmc_pg)
54921bb76ff1Sjsg 			level->mcFlags |= SISLANDS_SMC_MC_PG_EN;
54931bb76ff1Sjsg 	}
54941bb76ff1Sjsg 
54951bb76ff1Sjsg 	if (adev->gmc.vram_type == AMDGPU_VRAM_TYPE_GDDR5) {
54961bb76ff1Sjsg 		if (pl->mclk > pi->mclk_edc_enable_threshold)
54971bb76ff1Sjsg 			level->mcFlags |= SISLANDS_SMC_MC_EDC_RD_FLAG;
54981bb76ff1Sjsg 
54991bb76ff1Sjsg 		if (pl->mclk > eg_pi->mclk_edc_wr_enable_threshold)
55001bb76ff1Sjsg 			level->mcFlags |= SISLANDS_SMC_MC_EDC_WR_FLAG;
55011bb76ff1Sjsg 
55021bb76ff1Sjsg 		level->strobeMode = si_get_strobe_mode_settings(adev, pl->mclk);
55031bb76ff1Sjsg 
55041bb76ff1Sjsg 		if (level->strobeMode & SISLANDS_SMC_STROBE_ENABLE) {
55051bb76ff1Sjsg 			if (si_get_mclk_frequency_ratio(pl->mclk, true) >=
55061bb76ff1Sjsg 			    ((RREG32(MC_SEQ_MISC7) >> 16) & 0xf))
55071bb76ff1Sjsg 				dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;
55081bb76ff1Sjsg 			else
55091bb76ff1Sjsg 				dll_state_on = ((RREG32(MC_SEQ_MISC6) >> 1) & 0x1) ? true : false;
55101bb76ff1Sjsg 		} else {
55111bb76ff1Sjsg 			dll_state_on = false;
55121bb76ff1Sjsg 		}
55131bb76ff1Sjsg 	} else {
55141bb76ff1Sjsg 		level->strobeMode = si_get_strobe_mode_settings(adev,
55151bb76ff1Sjsg 								pl->mclk);
55161bb76ff1Sjsg 
55171bb76ff1Sjsg 		dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;
55181bb76ff1Sjsg 	}
55191bb76ff1Sjsg 
55201bb76ff1Sjsg 	ret = si_populate_mclk_value(adev,
55211bb76ff1Sjsg 				     pl->sclk,
55221bb76ff1Sjsg 				     pl->mclk,
55231bb76ff1Sjsg 				     &level->mclk,
55241bb76ff1Sjsg 				     (level->strobeMode & SISLANDS_SMC_STROBE_ENABLE) != 0, dll_state_on);
55251bb76ff1Sjsg 	if (ret)
55261bb76ff1Sjsg 		return ret;
55271bb76ff1Sjsg 
55281bb76ff1Sjsg 	ret = si_populate_voltage_value(adev,
55291bb76ff1Sjsg 					&eg_pi->vddc_voltage_table,
55301bb76ff1Sjsg 					pl->vddc, &level->vddc);
55311bb76ff1Sjsg 	if (ret)
55321bb76ff1Sjsg 		return ret;
55331bb76ff1Sjsg 
55341bb76ff1Sjsg 
55351bb76ff1Sjsg 	ret = si_get_std_voltage_value(adev, &level->vddc, &std_vddc);
55361bb76ff1Sjsg 	if (ret)
55371bb76ff1Sjsg 		return ret;
55381bb76ff1Sjsg 
55391bb76ff1Sjsg 	ret = si_populate_std_voltage_value(adev, std_vddc,
55401bb76ff1Sjsg 					    level->vddc.index, &level->std_vddc);
55411bb76ff1Sjsg 	if (ret)
55421bb76ff1Sjsg 		return ret;
55431bb76ff1Sjsg 
55441bb76ff1Sjsg 	if (eg_pi->vddci_control) {
55451bb76ff1Sjsg 		ret = si_populate_voltage_value(adev, &eg_pi->vddci_voltage_table,
55461bb76ff1Sjsg 						pl->vddci, &level->vddci);
55471bb76ff1Sjsg 		if (ret)
55481bb76ff1Sjsg 			return ret;
55491bb76ff1Sjsg 	}
55501bb76ff1Sjsg 
55511bb76ff1Sjsg 	if (si_pi->vddc_phase_shed_control) {
55521bb76ff1Sjsg 		ret = si_populate_phase_shedding_value(adev,
55531bb76ff1Sjsg 						       &adev->pm.dpm.dyn_state.phase_shedding_limits_table,
55541bb76ff1Sjsg 						       pl->vddc,
55551bb76ff1Sjsg 						       pl->sclk,
55561bb76ff1Sjsg 						       pl->mclk,
55571bb76ff1Sjsg 						       &level->vddc);
55581bb76ff1Sjsg 		if (ret)
55591bb76ff1Sjsg 			return ret;
55601bb76ff1Sjsg 	}
55611bb76ff1Sjsg 
55621bb76ff1Sjsg 	level->MaxPoweredUpCU = si_pi->max_cu;
55631bb76ff1Sjsg 
55641bb76ff1Sjsg 	ret = si_populate_mvdd_value(adev, pl->mclk, &level->mvdd);
55651bb76ff1Sjsg 
55661bb76ff1Sjsg 	return ret;
55671bb76ff1Sjsg }
55681bb76ff1Sjsg 
si_populate_smc_t(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state,SISLANDS_SMC_SWSTATE * smc_state)55691bb76ff1Sjsg static int si_populate_smc_t(struct amdgpu_device *adev,
55701bb76ff1Sjsg 			     struct amdgpu_ps *amdgpu_state,
55711bb76ff1Sjsg 			     SISLANDS_SMC_SWSTATE *smc_state)
55721bb76ff1Sjsg {
55731bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
55741bb76ff1Sjsg 	struct  si_ps *state = si_get_ps(amdgpu_state);
55751bb76ff1Sjsg 	u32 a_t;
55761bb76ff1Sjsg 	u32 t_l, t_h;
55771bb76ff1Sjsg 	u32 high_bsp;
55781bb76ff1Sjsg 	int i, ret;
55791bb76ff1Sjsg 
55801bb76ff1Sjsg 	if (state->performance_level_count >= 9)
55811bb76ff1Sjsg 		return -EINVAL;
55821bb76ff1Sjsg 
55831bb76ff1Sjsg 	if (state->performance_level_count < 2) {
55841bb76ff1Sjsg 		a_t = CG_R(0xffff) | CG_L(0);
55851bb76ff1Sjsg 		smc_state->levels[0].aT = cpu_to_be32(a_t);
55861bb76ff1Sjsg 		return 0;
55871bb76ff1Sjsg 	}
55881bb76ff1Sjsg 
55891bb76ff1Sjsg 	smc_state->levels[0].aT = cpu_to_be32(0);
55901bb76ff1Sjsg 
55911bb76ff1Sjsg 	for (i = 0; i <= state->performance_level_count - 2; i++) {
55921bb76ff1Sjsg 		ret = r600_calculate_at(
55931bb76ff1Sjsg 			(50 / SISLANDS_MAX_HARDWARE_POWERLEVELS) * 100 * (i + 1),
55941bb76ff1Sjsg 			100 * R600_AH_DFLT,
55951bb76ff1Sjsg 			state->performance_levels[i + 1].sclk,
55961bb76ff1Sjsg 			state->performance_levels[i].sclk,
55971bb76ff1Sjsg 			&t_l,
55981bb76ff1Sjsg 			&t_h);
55991bb76ff1Sjsg 
56001bb76ff1Sjsg 		if (ret) {
56011bb76ff1Sjsg 			t_h = (i + 1) * 1000 - 50 * R600_AH_DFLT;
56021bb76ff1Sjsg 			t_l = (i + 1) * 1000 + 50 * R600_AH_DFLT;
56031bb76ff1Sjsg 		}
56041bb76ff1Sjsg 
56051bb76ff1Sjsg 		a_t = be32_to_cpu(smc_state->levels[i].aT) & ~CG_R_MASK;
56061bb76ff1Sjsg 		a_t |= CG_R(t_l * pi->bsp / 20000);
56071bb76ff1Sjsg 		smc_state->levels[i].aT = cpu_to_be32(a_t);
56081bb76ff1Sjsg 
56091bb76ff1Sjsg 		high_bsp = (i == state->performance_level_count - 2) ?
56101bb76ff1Sjsg 			pi->pbsp : pi->bsp;
56111bb76ff1Sjsg 		a_t = CG_R(0xffff) | CG_L(t_h * high_bsp / 20000);
56121bb76ff1Sjsg 		smc_state->levels[i + 1].aT = cpu_to_be32(a_t);
56131bb76ff1Sjsg 	}
56141bb76ff1Sjsg 
56151bb76ff1Sjsg 	return 0;
56161bb76ff1Sjsg }
56171bb76ff1Sjsg 
si_disable_ulv(struct amdgpu_device * adev)56181bb76ff1Sjsg static int si_disable_ulv(struct amdgpu_device *adev)
56191bb76ff1Sjsg {
56201bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
56211bb76ff1Sjsg 	struct si_ulv_param *ulv = &si_pi->ulv;
56221bb76ff1Sjsg 
56231bb76ff1Sjsg 	if (ulv->supported)
56241bb76ff1Sjsg 		return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_DisableULV) == PPSMC_Result_OK) ?
56251bb76ff1Sjsg 			0 : -EINVAL;
56261bb76ff1Sjsg 
56271bb76ff1Sjsg 	return 0;
56281bb76ff1Sjsg }
56291bb76ff1Sjsg 
si_is_state_ulv_compatible(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state)56301bb76ff1Sjsg static bool si_is_state_ulv_compatible(struct amdgpu_device *adev,
56311bb76ff1Sjsg 				       struct amdgpu_ps *amdgpu_state)
56321bb76ff1Sjsg {
56331bb76ff1Sjsg 	const struct si_power_info *si_pi = si_get_pi(adev);
56341bb76ff1Sjsg 	const struct si_ulv_param *ulv = &si_pi->ulv;
56351bb76ff1Sjsg 	const struct  si_ps *state = si_get_ps(amdgpu_state);
56361bb76ff1Sjsg 	int i;
56371bb76ff1Sjsg 
56381bb76ff1Sjsg 	if (state->performance_levels[0].mclk != ulv->pl.mclk)
56391bb76ff1Sjsg 		return false;
56401bb76ff1Sjsg 
56411bb76ff1Sjsg 	/* XXX validate against display requirements! */
56421bb76ff1Sjsg 
56431bb76ff1Sjsg 	for (i = 0; i < adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count; i++) {
56441bb76ff1Sjsg 		if (adev->clock.current_dispclk <=
56451bb76ff1Sjsg 		    adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[i].clk) {
56461bb76ff1Sjsg 			if (ulv->pl.vddc <
56471bb76ff1Sjsg 			    adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[i].v)
56481bb76ff1Sjsg 				return false;
56491bb76ff1Sjsg 		}
56501bb76ff1Sjsg 	}
56511bb76ff1Sjsg 
56521bb76ff1Sjsg 	if ((amdgpu_state->vclk != 0) || (amdgpu_state->dclk != 0))
56531bb76ff1Sjsg 		return false;
56541bb76ff1Sjsg 
56551bb76ff1Sjsg 	return true;
56561bb76ff1Sjsg }
56571bb76ff1Sjsg 
si_set_power_state_conditionally_enable_ulv(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_new_state)56581bb76ff1Sjsg static int si_set_power_state_conditionally_enable_ulv(struct amdgpu_device *adev,
56591bb76ff1Sjsg 						       struct amdgpu_ps *amdgpu_new_state)
56601bb76ff1Sjsg {
56611bb76ff1Sjsg 	const struct si_power_info *si_pi = si_get_pi(adev);
56621bb76ff1Sjsg 	const struct si_ulv_param *ulv = &si_pi->ulv;
56631bb76ff1Sjsg 
56641bb76ff1Sjsg 	if (ulv->supported) {
56651bb76ff1Sjsg 		if (si_is_state_ulv_compatible(adev, amdgpu_new_state))
56661bb76ff1Sjsg 			return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableULV) == PPSMC_Result_OK) ?
56671bb76ff1Sjsg 				0 : -EINVAL;
56681bb76ff1Sjsg 	}
56691bb76ff1Sjsg 	return 0;
56701bb76ff1Sjsg }
56711bb76ff1Sjsg 
si_convert_power_state_to_smc(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state,SISLANDS_SMC_SWSTATE * smc_state)56721bb76ff1Sjsg static int si_convert_power_state_to_smc(struct amdgpu_device *adev,
56731bb76ff1Sjsg 					 struct amdgpu_ps *amdgpu_state,
56741bb76ff1Sjsg 					 SISLANDS_SMC_SWSTATE *smc_state)
56751bb76ff1Sjsg {
56761bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
56771bb76ff1Sjsg 	struct ni_power_info *ni_pi = ni_get_pi(adev);
56781bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
56791bb76ff1Sjsg 	struct  si_ps *state = si_get_ps(amdgpu_state);
56801bb76ff1Sjsg 	int i, ret;
56811bb76ff1Sjsg 	u32 threshold;
56821bb76ff1Sjsg 	u32 sclk_in_sr = 1350; /* ??? */
56831bb76ff1Sjsg 
56841bb76ff1Sjsg 	if (state->performance_level_count > SISLANDS_MAX_HARDWARE_POWERLEVELS)
56851bb76ff1Sjsg 		return -EINVAL;
56861bb76ff1Sjsg 
56871bb76ff1Sjsg 	threshold = state->performance_levels[state->performance_level_count-1].sclk * 100 / 100;
56881bb76ff1Sjsg 
56891bb76ff1Sjsg 	if (amdgpu_state->vclk && amdgpu_state->dclk) {
56901bb76ff1Sjsg 		eg_pi->uvd_enabled = true;
56911bb76ff1Sjsg 		if (eg_pi->smu_uvd_hs)
56921bb76ff1Sjsg 			smc_state->flags |= PPSMC_SWSTATE_FLAG_UVD;
56931bb76ff1Sjsg 	} else {
56941bb76ff1Sjsg 		eg_pi->uvd_enabled = false;
56951bb76ff1Sjsg 	}
56961bb76ff1Sjsg 
56971bb76ff1Sjsg 	if (state->dc_compatible)
56981bb76ff1Sjsg 		smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;
56991bb76ff1Sjsg 
57001bb76ff1Sjsg 	smc_state->levelCount = 0;
57011bb76ff1Sjsg 	for (i = 0; i < state->performance_level_count; i++) {
57021bb76ff1Sjsg 		if (eg_pi->sclk_deep_sleep) {
57031bb76ff1Sjsg 			if ((i == 0) || si_pi->sclk_deep_sleep_above_low) {
57041bb76ff1Sjsg 				if (sclk_in_sr <= SCLK_MIN_DEEPSLEEP_FREQ)
57051bb76ff1Sjsg 					smc_state->levels[i].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_BYPASS;
57061bb76ff1Sjsg 				else
57071bb76ff1Sjsg 					smc_state->levels[i].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE;
57081bb76ff1Sjsg 			}
57091bb76ff1Sjsg 		}
57101bb76ff1Sjsg 
57111bb76ff1Sjsg 		ret = si_convert_power_level_to_smc(adev, &state->performance_levels[i],
57121bb76ff1Sjsg 						    &smc_state->levels[i]);
57131bb76ff1Sjsg 		smc_state->levels[i].arbRefreshState =
57141bb76ff1Sjsg 			(u8)(SISLANDS_DRIVER_STATE_ARB_INDEX + i);
57151bb76ff1Sjsg 
57161bb76ff1Sjsg 		if (ret)
57171bb76ff1Sjsg 			return ret;
57181bb76ff1Sjsg 
57191bb76ff1Sjsg 		if (ni_pi->enable_power_containment)
57201bb76ff1Sjsg 			smc_state->levels[i].displayWatermark =
57211bb76ff1Sjsg 				(state->performance_levels[i].sclk < threshold) ?
57221bb76ff1Sjsg 				PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
57231bb76ff1Sjsg 		else
57241bb76ff1Sjsg 			smc_state->levels[i].displayWatermark = (i < 2) ?
57251bb76ff1Sjsg 				PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
57261bb76ff1Sjsg 
57271bb76ff1Sjsg 		if (eg_pi->dynamic_ac_timing)
57281bb76ff1Sjsg 			smc_state->levels[i].ACIndex = SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i;
57291bb76ff1Sjsg 		else
57301bb76ff1Sjsg 			smc_state->levels[i].ACIndex = 0;
57311bb76ff1Sjsg 
57321bb76ff1Sjsg 		smc_state->levelCount++;
57331bb76ff1Sjsg 	}
57341bb76ff1Sjsg 
57351bb76ff1Sjsg 	si_write_smc_soft_register(adev,
57361bb76ff1Sjsg 				   SI_SMC_SOFT_REGISTER_watermark_threshold,
57371bb76ff1Sjsg 				   threshold / 512);
57381bb76ff1Sjsg 
57391bb76ff1Sjsg 	si_populate_smc_sp(adev, amdgpu_state, smc_state);
57401bb76ff1Sjsg 
57411bb76ff1Sjsg 	ret = si_populate_power_containment_values(adev, amdgpu_state, smc_state);
57421bb76ff1Sjsg 	if (ret)
57431bb76ff1Sjsg 		ni_pi->enable_power_containment = false;
57441bb76ff1Sjsg 
57451bb76ff1Sjsg 	ret = si_populate_sq_ramping_values(adev, amdgpu_state, smc_state);
57461bb76ff1Sjsg 	if (ret)
57471bb76ff1Sjsg 		ni_pi->enable_sq_ramping = false;
57481bb76ff1Sjsg 
57491bb76ff1Sjsg 	return si_populate_smc_t(adev, amdgpu_state, smc_state);
57501bb76ff1Sjsg }
57511bb76ff1Sjsg 
si_upload_sw_state(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_new_state)57521bb76ff1Sjsg static int si_upload_sw_state(struct amdgpu_device *adev,
57531bb76ff1Sjsg 			      struct amdgpu_ps *amdgpu_new_state)
57541bb76ff1Sjsg {
57551bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
57561bb76ff1Sjsg 	struct  si_ps *new_state = si_get_ps(amdgpu_new_state);
57571bb76ff1Sjsg 	int ret;
57581bb76ff1Sjsg 	u32 address = si_pi->state_table_start +
57591bb76ff1Sjsg 		offsetof(SISLANDS_SMC_STATETABLE, driverState);
57601bb76ff1Sjsg 	SISLANDS_SMC_SWSTATE *smc_state = &si_pi->smc_statetable.driverState;
57611bb76ff1Sjsg 	size_t state_size = struct_size(smc_state, levels,
57621bb76ff1Sjsg 					new_state->performance_level_count);
57631bb76ff1Sjsg 	memset(smc_state, 0, state_size);
57641bb76ff1Sjsg 
57651bb76ff1Sjsg 	ret = si_convert_power_state_to_smc(adev, amdgpu_new_state, smc_state);
57661bb76ff1Sjsg 	if (ret)
57671bb76ff1Sjsg 		return ret;
57681bb76ff1Sjsg 
57691bb76ff1Sjsg 	return amdgpu_si_copy_bytes_to_smc(adev, address, (u8 *)smc_state,
57701bb76ff1Sjsg 					   state_size, si_pi->sram_end);
57711bb76ff1Sjsg }
57721bb76ff1Sjsg 
si_upload_ulv_state(struct amdgpu_device * adev)57731bb76ff1Sjsg static int si_upload_ulv_state(struct amdgpu_device *adev)
57741bb76ff1Sjsg {
57751bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
57761bb76ff1Sjsg 	struct si_ulv_param *ulv = &si_pi->ulv;
57771bb76ff1Sjsg 	int ret = 0;
57781bb76ff1Sjsg 
57791bb76ff1Sjsg 	if (ulv->supported && ulv->pl.vddc) {
57801bb76ff1Sjsg 		u32 address = si_pi->state_table_start +
57811bb76ff1Sjsg 			offsetof(SISLANDS_SMC_STATETABLE, ULVState);
57821bb76ff1Sjsg 		struct SISLANDS_SMC_SWSTATE_SINGLE *smc_state = &si_pi->smc_statetable.ULVState;
57831bb76ff1Sjsg 		u32 state_size = sizeof(struct SISLANDS_SMC_SWSTATE_SINGLE);
57841bb76ff1Sjsg 
57851bb76ff1Sjsg 		memset(smc_state, 0, state_size);
57861bb76ff1Sjsg 
57871bb76ff1Sjsg 		ret = si_populate_ulv_state(adev, smc_state);
57881bb76ff1Sjsg 		if (!ret)
57891bb76ff1Sjsg 			ret = amdgpu_si_copy_bytes_to_smc(adev, address, (u8 *)smc_state,
57901bb76ff1Sjsg 							  state_size, si_pi->sram_end);
57911bb76ff1Sjsg 	}
57921bb76ff1Sjsg 
57931bb76ff1Sjsg 	return ret;
57941bb76ff1Sjsg }
57951bb76ff1Sjsg 
si_upload_smc_data(struct amdgpu_device * adev)57961bb76ff1Sjsg static int si_upload_smc_data(struct amdgpu_device *adev)
57971bb76ff1Sjsg {
57981bb76ff1Sjsg 	struct amdgpu_crtc *amdgpu_crtc = NULL;
57991bb76ff1Sjsg 	int i;
58001bb76ff1Sjsg 
58011bb76ff1Sjsg 	if (adev->pm.dpm.new_active_crtc_count == 0)
58021bb76ff1Sjsg 		return 0;
58031bb76ff1Sjsg 
58041bb76ff1Sjsg 	for (i = 0; i < adev->mode_info.num_crtc; i++) {
58051bb76ff1Sjsg 		if (adev->pm.dpm.new_active_crtcs & (1 << i)) {
58061bb76ff1Sjsg 			amdgpu_crtc = adev->mode_info.crtcs[i];
58071bb76ff1Sjsg 			break;
58081bb76ff1Sjsg 		}
58091bb76ff1Sjsg 	}
58101bb76ff1Sjsg 
58111bb76ff1Sjsg 	if (amdgpu_crtc == NULL)
58121bb76ff1Sjsg 		return 0;
58131bb76ff1Sjsg 
58141bb76ff1Sjsg 	if (amdgpu_crtc->line_time <= 0)
58151bb76ff1Sjsg 		return 0;
58161bb76ff1Sjsg 
58171bb76ff1Sjsg 	if (si_write_smc_soft_register(adev,
58181bb76ff1Sjsg 				       SI_SMC_SOFT_REGISTER_crtc_index,
58191bb76ff1Sjsg 				       amdgpu_crtc->crtc_id) != PPSMC_Result_OK)
58201bb76ff1Sjsg 		return 0;
58211bb76ff1Sjsg 
58221bb76ff1Sjsg 	if (si_write_smc_soft_register(adev,
58231bb76ff1Sjsg 				       SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min,
58241bb76ff1Sjsg 				       amdgpu_crtc->wm_high / amdgpu_crtc->line_time) != PPSMC_Result_OK)
58251bb76ff1Sjsg 		return 0;
58261bb76ff1Sjsg 
58271bb76ff1Sjsg 	if (si_write_smc_soft_register(adev,
58281bb76ff1Sjsg 				       SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max,
58291bb76ff1Sjsg 				       amdgpu_crtc->wm_low / amdgpu_crtc->line_time) != PPSMC_Result_OK)
58301bb76ff1Sjsg 		return 0;
58311bb76ff1Sjsg 
58321bb76ff1Sjsg 	return 0;
58331bb76ff1Sjsg }
58341bb76ff1Sjsg 
si_set_mc_special_registers(struct amdgpu_device * adev,struct si_mc_reg_table * table)58351bb76ff1Sjsg static int si_set_mc_special_registers(struct amdgpu_device *adev,
58361bb76ff1Sjsg 				       struct si_mc_reg_table *table)
58371bb76ff1Sjsg {
58381bb76ff1Sjsg 	u8 i, j, k;
58391bb76ff1Sjsg 	u32 temp_reg;
58401bb76ff1Sjsg 
58411bb76ff1Sjsg 	for (i = 0, j = table->last; i < table->last; i++) {
58421bb76ff1Sjsg 		if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
58431bb76ff1Sjsg 			return -EINVAL;
58441bb76ff1Sjsg 		switch (table->mc_reg_address[i].s1) {
58451bb76ff1Sjsg 		case MC_SEQ_MISC1:
58461bb76ff1Sjsg 			temp_reg = RREG32(MC_PMG_CMD_EMRS);
58471bb76ff1Sjsg 			table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS;
58481bb76ff1Sjsg 			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP;
58491bb76ff1Sjsg 			for (k = 0; k < table->num_entries; k++)
58501bb76ff1Sjsg 				table->mc_reg_table_entry[k].mc_data[j] =
58511bb76ff1Sjsg 					((temp_reg & 0xffff0000)) |
58521bb76ff1Sjsg 					((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
58531bb76ff1Sjsg 			j++;
58541bb76ff1Sjsg 
58551bb76ff1Sjsg 			if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
58561bb76ff1Sjsg 				return -EINVAL;
58571bb76ff1Sjsg 			temp_reg = RREG32(MC_PMG_CMD_MRS);
58581bb76ff1Sjsg 			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS;
58591bb76ff1Sjsg 			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP;
58601bb76ff1Sjsg 			for (k = 0; k < table->num_entries; k++) {
58611bb76ff1Sjsg 				table->mc_reg_table_entry[k].mc_data[j] =
58621bb76ff1Sjsg 					(temp_reg & 0xffff0000) |
58631bb76ff1Sjsg 					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
58641bb76ff1Sjsg 				if (adev->gmc.vram_type != AMDGPU_VRAM_TYPE_GDDR5)
58651bb76ff1Sjsg 					table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
58661bb76ff1Sjsg 			}
58671bb76ff1Sjsg 			j++;
58681bb76ff1Sjsg 
58691bb76ff1Sjsg 			if (adev->gmc.vram_type != AMDGPU_VRAM_TYPE_GDDR5) {
58701bb76ff1Sjsg 				if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
58711bb76ff1Sjsg 					return -EINVAL;
58721bb76ff1Sjsg 				table->mc_reg_address[j].s1 = MC_PMG_AUTO_CMD;
58731bb76ff1Sjsg 				table->mc_reg_address[j].s0 = MC_PMG_AUTO_CMD;
58741bb76ff1Sjsg 				for (k = 0; k < table->num_entries; k++)
58751bb76ff1Sjsg 					table->mc_reg_table_entry[k].mc_data[j] =
58761bb76ff1Sjsg 						(table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16;
58771bb76ff1Sjsg 				j++;
58781bb76ff1Sjsg 			}
58791bb76ff1Sjsg 			break;
58801bb76ff1Sjsg 		case MC_SEQ_RESERVE_M:
58811bb76ff1Sjsg 			temp_reg = RREG32(MC_PMG_CMD_MRS1);
58821bb76ff1Sjsg 			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1;
58831bb76ff1Sjsg 			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP;
58841bb76ff1Sjsg 			for(k = 0; k < table->num_entries; k++)
58851bb76ff1Sjsg 				table->mc_reg_table_entry[k].mc_data[j] =
58861bb76ff1Sjsg 					(temp_reg & 0xffff0000) |
58871bb76ff1Sjsg 					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
58881bb76ff1Sjsg 			j++;
58891bb76ff1Sjsg 			break;
58901bb76ff1Sjsg 		default:
58911bb76ff1Sjsg 			break;
58921bb76ff1Sjsg 		}
58931bb76ff1Sjsg 	}
58941bb76ff1Sjsg 
58951bb76ff1Sjsg 	table->last = j;
58961bb76ff1Sjsg 
58971bb76ff1Sjsg 	return 0;
58981bb76ff1Sjsg }
58991bb76ff1Sjsg 
si_check_s0_mc_reg_index(u16 in_reg,u16 * out_reg)59001bb76ff1Sjsg static bool si_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
59011bb76ff1Sjsg {
59021bb76ff1Sjsg 	bool result = true;
59031bb76ff1Sjsg 	switch (in_reg) {
59041bb76ff1Sjsg 	case  MC_SEQ_RAS_TIMING:
59051bb76ff1Sjsg 		*out_reg = MC_SEQ_RAS_TIMING_LP;
59061bb76ff1Sjsg 		break;
59071bb76ff1Sjsg 	case MC_SEQ_CAS_TIMING:
59081bb76ff1Sjsg 		*out_reg = MC_SEQ_CAS_TIMING_LP;
59091bb76ff1Sjsg 		break;
59101bb76ff1Sjsg 	case MC_SEQ_MISC_TIMING:
59111bb76ff1Sjsg 		*out_reg = MC_SEQ_MISC_TIMING_LP;
59121bb76ff1Sjsg 		break;
59131bb76ff1Sjsg 	case MC_SEQ_MISC_TIMING2:
59141bb76ff1Sjsg 		*out_reg = MC_SEQ_MISC_TIMING2_LP;
59151bb76ff1Sjsg 		break;
59161bb76ff1Sjsg 	case MC_SEQ_RD_CTL_D0:
59171bb76ff1Sjsg 		*out_reg = MC_SEQ_RD_CTL_D0_LP;
59181bb76ff1Sjsg 		break;
59191bb76ff1Sjsg 	case MC_SEQ_RD_CTL_D1:
59201bb76ff1Sjsg 		*out_reg = MC_SEQ_RD_CTL_D1_LP;
59211bb76ff1Sjsg 		break;
59221bb76ff1Sjsg 	case MC_SEQ_WR_CTL_D0:
59231bb76ff1Sjsg 		*out_reg = MC_SEQ_WR_CTL_D0_LP;
59241bb76ff1Sjsg 		break;
59251bb76ff1Sjsg 	case MC_SEQ_WR_CTL_D1:
59261bb76ff1Sjsg 		*out_reg = MC_SEQ_WR_CTL_D1_LP;
59271bb76ff1Sjsg 		break;
59281bb76ff1Sjsg 	case MC_PMG_CMD_EMRS:
59291bb76ff1Sjsg 		*out_reg = MC_SEQ_PMG_CMD_EMRS_LP;
59301bb76ff1Sjsg 		break;
59311bb76ff1Sjsg 	case MC_PMG_CMD_MRS:
59321bb76ff1Sjsg 		*out_reg = MC_SEQ_PMG_CMD_MRS_LP;
59331bb76ff1Sjsg 		break;
59341bb76ff1Sjsg 	case MC_PMG_CMD_MRS1:
59351bb76ff1Sjsg 		*out_reg = MC_SEQ_PMG_CMD_MRS1_LP;
59361bb76ff1Sjsg 		break;
59371bb76ff1Sjsg 	case MC_SEQ_PMG_TIMING:
59381bb76ff1Sjsg 		*out_reg = MC_SEQ_PMG_TIMING_LP;
59391bb76ff1Sjsg 		break;
59401bb76ff1Sjsg 	case MC_PMG_CMD_MRS2:
59411bb76ff1Sjsg 		*out_reg = MC_SEQ_PMG_CMD_MRS2_LP;
59421bb76ff1Sjsg 		break;
59431bb76ff1Sjsg 	case MC_SEQ_WR_CTL_2:
59441bb76ff1Sjsg 		*out_reg = MC_SEQ_WR_CTL_2_LP;
59451bb76ff1Sjsg 		break;
59461bb76ff1Sjsg 	default:
59471bb76ff1Sjsg 		result = false;
59481bb76ff1Sjsg 		break;
59491bb76ff1Sjsg 	}
59501bb76ff1Sjsg 
59511bb76ff1Sjsg 	return result;
59521bb76ff1Sjsg }
59531bb76ff1Sjsg 
si_set_valid_flag(struct si_mc_reg_table * table)59541bb76ff1Sjsg static void si_set_valid_flag(struct si_mc_reg_table *table)
59551bb76ff1Sjsg {
59561bb76ff1Sjsg 	u8 i, j;
59571bb76ff1Sjsg 
59581bb76ff1Sjsg 	for (i = 0; i < table->last; i++) {
59591bb76ff1Sjsg 		for (j = 1; j < table->num_entries; j++) {
59601bb76ff1Sjsg 			if (table->mc_reg_table_entry[j-1].mc_data[i] != table->mc_reg_table_entry[j].mc_data[i]) {
59611bb76ff1Sjsg 				table->valid_flag |= 1 << i;
59621bb76ff1Sjsg 				break;
59631bb76ff1Sjsg 			}
59641bb76ff1Sjsg 		}
59651bb76ff1Sjsg 	}
59661bb76ff1Sjsg }
59671bb76ff1Sjsg 
si_set_s0_mc_reg_index(struct si_mc_reg_table * table)59681bb76ff1Sjsg static void si_set_s0_mc_reg_index(struct si_mc_reg_table *table)
59691bb76ff1Sjsg {
59701bb76ff1Sjsg 	u32 i;
59711bb76ff1Sjsg 	u16 address;
59721bb76ff1Sjsg 
59731bb76ff1Sjsg 	for (i = 0; i < table->last; i++)
59741bb76ff1Sjsg 		table->mc_reg_address[i].s0 = si_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
59751bb76ff1Sjsg 			address : table->mc_reg_address[i].s1;
59761bb76ff1Sjsg 
59771bb76ff1Sjsg }
59781bb76ff1Sjsg 
si_copy_vbios_mc_reg_table(struct atom_mc_reg_table * table,struct si_mc_reg_table * si_table)59791bb76ff1Sjsg static int si_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
59801bb76ff1Sjsg 				      struct si_mc_reg_table *si_table)
59811bb76ff1Sjsg {
59821bb76ff1Sjsg 	u8 i, j;
59831bb76ff1Sjsg 
59841bb76ff1Sjsg 	if (table->last > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
59851bb76ff1Sjsg 		return -EINVAL;
59861bb76ff1Sjsg 	if (table->num_entries > MAX_AC_TIMING_ENTRIES)
59871bb76ff1Sjsg 		return -EINVAL;
59881bb76ff1Sjsg 
59891bb76ff1Sjsg 	for (i = 0; i < table->last; i++)
59901bb76ff1Sjsg 		si_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
59911bb76ff1Sjsg 	si_table->last = table->last;
59921bb76ff1Sjsg 
59931bb76ff1Sjsg 	for (i = 0; i < table->num_entries; i++) {
59941bb76ff1Sjsg 		si_table->mc_reg_table_entry[i].mclk_max =
59951bb76ff1Sjsg 			table->mc_reg_table_entry[i].mclk_max;
59961bb76ff1Sjsg 		for (j = 0; j < table->last; j++) {
59971bb76ff1Sjsg 			si_table->mc_reg_table_entry[i].mc_data[j] =
59981bb76ff1Sjsg 				table->mc_reg_table_entry[i].mc_data[j];
59991bb76ff1Sjsg 		}
60001bb76ff1Sjsg 	}
60011bb76ff1Sjsg 	si_table->num_entries = table->num_entries;
60021bb76ff1Sjsg 
60031bb76ff1Sjsg 	return 0;
60041bb76ff1Sjsg }
60051bb76ff1Sjsg 
si_initialize_mc_reg_table(struct amdgpu_device * adev)60061bb76ff1Sjsg static int si_initialize_mc_reg_table(struct amdgpu_device *adev)
60071bb76ff1Sjsg {
60081bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
60091bb76ff1Sjsg 	struct atom_mc_reg_table *table;
60101bb76ff1Sjsg 	struct si_mc_reg_table *si_table = &si_pi->mc_reg_table;
60111bb76ff1Sjsg 	u8 module_index = rv770_get_memory_module_index(adev);
60121bb76ff1Sjsg 	int ret;
60131bb76ff1Sjsg 
60141bb76ff1Sjsg 	table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
60151bb76ff1Sjsg 	if (!table)
60161bb76ff1Sjsg 		return -ENOMEM;
60171bb76ff1Sjsg 
60181bb76ff1Sjsg 	WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
60191bb76ff1Sjsg 	WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
60201bb76ff1Sjsg 	WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
60211bb76ff1Sjsg 	WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
60221bb76ff1Sjsg 	WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
60231bb76ff1Sjsg 	WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
60241bb76ff1Sjsg 	WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
60251bb76ff1Sjsg 	WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
60261bb76ff1Sjsg 	WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
60271bb76ff1Sjsg 	WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
60281bb76ff1Sjsg 	WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
60291bb76ff1Sjsg 	WREG32(MC_SEQ_PMG_TIMING_LP, RREG32(MC_SEQ_PMG_TIMING));
60301bb76ff1Sjsg 	WREG32(MC_SEQ_PMG_CMD_MRS2_LP, RREG32(MC_PMG_CMD_MRS2));
60311bb76ff1Sjsg 	WREG32(MC_SEQ_WR_CTL_2_LP, RREG32(MC_SEQ_WR_CTL_2));
60321bb76ff1Sjsg 
60331bb76ff1Sjsg 	ret = amdgpu_atombios_init_mc_reg_table(adev, module_index, table);
60341bb76ff1Sjsg 	if (ret)
60351bb76ff1Sjsg 		goto init_mc_done;
60361bb76ff1Sjsg 
60371bb76ff1Sjsg 	ret = si_copy_vbios_mc_reg_table(table, si_table);
60381bb76ff1Sjsg 	if (ret)
60391bb76ff1Sjsg 		goto init_mc_done;
60401bb76ff1Sjsg 
60411bb76ff1Sjsg 	si_set_s0_mc_reg_index(si_table);
60421bb76ff1Sjsg 
60431bb76ff1Sjsg 	ret = si_set_mc_special_registers(adev, si_table);
60441bb76ff1Sjsg 	if (ret)
60451bb76ff1Sjsg 		goto init_mc_done;
60461bb76ff1Sjsg 
60471bb76ff1Sjsg 	si_set_valid_flag(si_table);
60481bb76ff1Sjsg 
60491bb76ff1Sjsg init_mc_done:
60501bb76ff1Sjsg 	kfree(table);
60511bb76ff1Sjsg 
60521bb76ff1Sjsg 	return ret;
60531bb76ff1Sjsg 
60541bb76ff1Sjsg }
60551bb76ff1Sjsg 
si_populate_mc_reg_addresses(struct amdgpu_device * adev,SMC_SIslands_MCRegisters * mc_reg_table)60561bb76ff1Sjsg static void si_populate_mc_reg_addresses(struct amdgpu_device *adev,
60571bb76ff1Sjsg 					 SMC_SIslands_MCRegisters *mc_reg_table)
60581bb76ff1Sjsg {
60591bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
60601bb76ff1Sjsg 	u32 i, j;
60611bb76ff1Sjsg 
60621bb76ff1Sjsg 	for (i = 0, j = 0; j < si_pi->mc_reg_table.last; j++) {
60631bb76ff1Sjsg 		if (si_pi->mc_reg_table.valid_flag & (1 << j)) {
60641bb76ff1Sjsg 			if (i >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
60651bb76ff1Sjsg 				break;
60661bb76ff1Sjsg 			mc_reg_table->address[i].s0 =
60671bb76ff1Sjsg 				cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s0);
60681bb76ff1Sjsg 			mc_reg_table->address[i].s1 =
60691bb76ff1Sjsg 				cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s1);
60701bb76ff1Sjsg 			i++;
60711bb76ff1Sjsg 		}
60721bb76ff1Sjsg 	}
60731bb76ff1Sjsg 	mc_reg_table->last = (u8)i;
60741bb76ff1Sjsg }
60751bb76ff1Sjsg 
si_convert_mc_registers(const struct si_mc_reg_entry * entry,SMC_SIslands_MCRegisterSet * data,u32 num_entries,u32 valid_flag)60761bb76ff1Sjsg static void si_convert_mc_registers(const struct si_mc_reg_entry *entry,
60771bb76ff1Sjsg 				    SMC_SIslands_MCRegisterSet *data,
60781bb76ff1Sjsg 				    u32 num_entries, u32 valid_flag)
60791bb76ff1Sjsg {
60801bb76ff1Sjsg 	u32 i, j;
60811bb76ff1Sjsg 
60821bb76ff1Sjsg 	for(i = 0, j = 0; j < num_entries; j++) {
60831bb76ff1Sjsg 		if (valid_flag & (1 << j)) {
60841bb76ff1Sjsg 			data->value[i] = cpu_to_be32(entry->mc_data[j]);
60851bb76ff1Sjsg 			i++;
60861bb76ff1Sjsg 		}
60871bb76ff1Sjsg 	}
60881bb76ff1Sjsg }
60891bb76ff1Sjsg 
si_convert_mc_reg_table_entry_to_smc(struct amdgpu_device * adev,struct rv7xx_pl * pl,SMC_SIslands_MCRegisterSet * mc_reg_table_data)60901bb76ff1Sjsg static void si_convert_mc_reg_table_entry_to_smc(struct amdgpu_device *adev,
60911bb76ff1Sjsg 						 struct rv7xx_pl *pl,
60921bb76ff1Sjsg 						 SMC_SIslands_MCRegisterSet *mc_reg_table_data)
60931bb76ff1Sjsg {
60941bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
60951bb76ff1Sjsg 	u32 i = 0;
60961bb76ff1Sjsg 
60971bb76ff1Sjsg 	for (i = 0; i < si_pi->mc_reg_table.num_entries; i++) {
60981bb76ff1Sjsg 		if (pl->mclk <= si_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max)
60991bb76ff1Sjsg 			break;
61001bb76ff1Sjsg 	}
61011bb76ff1Sjsg 
61021bb76ff1Sjsg 	if ((i == si_pi->mc_reg_table.num_entries) && (i > 0))
61031bb76ff1Sjsg 		--i;
61041bb76ff1Sjsg 
61051bb76ff1Sjsg 	si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[i],
61061bb76ff1Sjsg 				mc_reg_table_data, si_pi->mc_reg_table.last,
61071bb76ff1Sjsg 				si_pi->mc_reg_table.valid_flag);
61081bb76ff1Sjsg }
61091bb76ff1Sjsg 
si_convert_mc_reg_table_to_smc(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state,SMC_SIslands_MCRegisters * mc_reg_table)61101bb76ff1Sjsg static void si_convert_mc_reg_table_to_smc(struct amdgpu_device *adev,
61111bb76ff1Sjsg 					   struct amdgpu_ps *amdgpu_state,
61121bb76ff1Sjsg 					   SMC_SIslands_MCRegisters *mc_reg_table)
61131bb76ff1Sjsg {
61141bb76ff1Sjsg 	struct si_ps *state = si_get_ps(amdgpu_state);
61151bb76ff1Sjsg 	int i;
61161bb76ff1Sjsg 
61171bb76ff1Sjsg 	for (i = 0; i < state->performance_level_count; i++) {
61181bb76ff1Sjsg 		si_convert_mc_reg_table_entry_to_smc(adev,
61191bb76ff1Sjsg 						     &state->performance_levels[i],
61201bb76ff1Sjsg 						     &mc_reg_table->data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i]);
61211bb76ff1Sjsg 	}
61221bb76ff1Sjsg }
61231bb76ff1Sjsg 
si_populate_mc_reg_table(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_boot_state)61241bb76ff1Sjsg static int si_populate_mc_reg_table(struct amdgpu_device *adev,
61251bb76ff1Sjsg 				    struct amdgpu_ps *amdgpu_boot_state)
61261bb76ff1Sjsg {
61271bb76ff1Sjsg 	struct  si_ps *boot_state = si_get_ps(amdgpu_boot_state);
61281bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
61291bb76ff1Sjsg 	struct si_ulv_param *ulv = &si_pi->ulv;
61301bb76ff1Sjsg 	SMC_SIslands_MCRegisters *smc_mc_reg_table = &si_pi->smc_mc_reg_table;
61311bb76ff1Sjsg 
61321bb76ff1Sjsg 	memset(smc_mc_reg_table, 0, sizeof(SMC_SIslands_MCRegisters));
61331bb76ff1Sjsg 
61341bb76ff1Sjsg 	si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_seq_index, 1);
61351bb76ff1Sjsg 
61361bb76ff1Sjsg 	si_populate_mc_reg_addresses(adev, smc_mc_reg_table);
61371bb76ff1Sjsg 
61381bb76ff1Sjsg 	si_convert_mc_reg_table_entry_to_smc(adev, &boot_state->performance_levels[0],
61391bb76ff1Sjsg 					     &smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_INITIAL_SLOT]);
61401bb76ff1Sjsg 
61411bb76ff1Sjsg 	si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[0],
61421bb76ff1Sjsg 				&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ACPI_SLOT],
61431bb76ff1Sjsg 				si_pi->mc_reg_table.last,
61441bb76ff1Sjsg 				si_pi->mc_reg_table.valid_flag);
61451bb76ff1Sjsg 
61461bb76ff1Sjsg 	if (ulv->supported && ulv->pl.vddc != 0)
61471bb76ff1Sjsg 		si_convert_mc_reg_table_entry_to_smc(adev, &ulv->pl,
61481bb76ff1Sjsg 						     &smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ULV_SLOT]);
61491bb76ff1Sjsg 	else
61501bb76ff1Sjsg 		si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[0],
61511bb76ff1Sjsg 					&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ULV_SLOT],
61521bb76ff1Sjsg 					si_pi->mc_reg_table.last,
61531bb76ff1Sjsg 					si_pi->mc_reg_table.valid_flag);
61541bb76ff1Sjsg 
61551bb76ff1Sjsg 	si_convert_mc_reg_table_to_smc(adev, amdgpu_boot_state, smc_mc_reg_table);
61561bb76ff1Sjsg 
61571bb76ff1Sjsg 	return amdgpu_si_copy_bytes_to_smc(adev, si_pi->mc_reg_table_start,
61581bb76ff1Sjsg 					   (u8 *)smc_mc_reg_table,
61591bb76ff1Sjsg 					   sizeof(SMC_SIslands_MCRegisters), si_pi->sram_end);
61601bb76ff1Sjsg }
61611bb76ff1Sjsg 
si_upload_mc_reg_table(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_new_state)61621bb76ff1Sjsg static int si_upload_mc_reg_table(struct amdgpu_device *adev,
61631bb76ff1Sjsg 				  struct amdgpu_ps *amdgpu_new_state)
61641bb76ff1Sjsg {
61651bb76ff1Sjsg 	struct si_ps *new_state = si_get_ps(amdgpu_new_state);
61661bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
61671bb76ff1Sjsg 	u32 address = si_pi->mc_reg_table_start +
61681bb76ff1Sjsg 		offsetof(SMC_SIslands_MCRegisters,
61691bb76ff1Sjsg 			 data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT]);
61701bb76ff1Sjsg 	SMC_SIslands_MCRegisters *smc_mc_reg_table = &si_pi->smc_mc_reg_table;
61711bb76ff1Sjsg 
61721bb76ff1Sjsg 	memset(smc_mc_reg_table, 0, sizeof(SMC_SIslands_MCRegisters));
61731bb76ff1Sjsg 
61741bb76ff1Sjsg 	si_convert_mc_reg_table_to_smc(adev, amdgpu_new_state, smc_mc_reg_table);
61751bb76ff1Sjsg 
61761bb76ff1Sjsg 	return amdgpu_si_copy_bytes_to_smc(adev, address,
61771bb76ff1Sjsg 					   (u8 *)&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT],
61781bb76ff1Sjsg 					   sizeof(SMC_SIslands_MCRegisterSet) * new_state->performance_level_count,
61791bb76ff1Sjsg 					   si_pi->sram_end);
61801bb76ff1Sjsg }
61811bb76ff1Sjsg 
si_enable_voltage_control(struct amdgpu_device * adev,bool enable)61821bb76ff1Sjsg static void si_enable_voltage_control(struct amdgpu_device *adev, bool enable)
61831bb76ff1Sjsg {
61841bb76ff1Sjsg 	if (enable)
61851bb76ff1Sjsg 		WREG32_P(GENERAL_PWRMGT, VOLT_PWRMGT_EN, ~VOLT_PWRMGT_EN);
61861bb76ff1Sjsg 	else
61871bb76ff1Sjsg 		WREG32_P(GENERAL_PWRMGT, 0, ~VOLT_PWRMGT_EN);
61881bb76ff1Sjsg }
61891bb76ff1Sjsg 
si_get_maximum_link_speed(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_state)61901bb76ff1Sjsg static enum si_pcie_gen si_get_maximum_link_speed(struct amdgpu_device *adev,
61911bb76ff1Sjsg 						  struct amdgpu_ps *amdgpu_state)
61921bb76ff1Sjsg {
61931bb76ff1Sjsg 	struct si_ps *state = si_get_ps(amdgpu_state);
61941bb76ff1Sjsg 	int i;
61951bb76ff1Sjsg 	u16 pcie_speed, max_speed = 0;
61961bb76ff1Sjsg 
61971bb76ff1Sjsg 	for (i = 0; i < state->performance_level_count; i++) {
61981bb76ff1Sjsg 		pcie_speed = state->performance_levels[i].pcie_gen;
61991bb76ff1Sjsg 		if (max_speed < pcie_speed)
62001bb76ff1Sjsg 			max_speed = pcie_speed;
62011bb76ff1Sjsg 	}
62021bb76ff1Sjsg 	return max_speed;
62031bb76ff1Sjsg }
62041bb76ff1Sjsg 
si_get_current_pcie_speed(struct amdgpu_device * adev)62051bb76ff1Sjsg static u16 si_get_current_pcie_speed(struct amdgpu_device *adev)
62061bb76ff1Sjsg {
62071bb76ff1Sjsg 	u32 speed_cntl;
62081bb76ff1Sjsg 
62091bb76ff1Sjsg 	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL) & LC_CURRENT_DATA_RATE_MASK;
62101bb76ff1Sjsg 	speed_cntl >>= LC_CURRENT_DATA_RATE_SHIFT;
62111bb76ff1Sjsg 
62121bb76ff1Sjsg 	return (u16)speed_cntl;
62131bb76ff1Sjsg }
62141bb76ff1Sjsg 
si_request_link_speed_change_before_state_change(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_new_state,struct amdgpu_ps * amdgpu_current_state)62151bb76ff1Sjsg static void si_request_link_speed_change_before_state_change(struct amdgpu_device *adev,
62161bb76ff1Sjsg 							     struct amdgpu_ps *amdgpu_new_state,
62171bb76ff1Sjsg 							     struct amdgpu_ps *amdgpu_current_state)
62181bb76ff1Sjsg {
62191bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
62201bb76ff1Sjsg 	enum si_pcie_gen target_link_speed = si_get_maximum_link_speed(adev, amdgpu_new_state);
62211bb76ff1Sjsg 	enum si_pcie_gen current_link_speed;
62221bb76ff1Sjsg 
62231bb76ff1Sjsg 	if (si_pi->force_pcie_gen == SI_PCIE_GEN_INVALID)
62241bb76ff1Sjsg 		current_link_speed = si_get_maximum_link_speed(adev, amdgpu_current_state);
62251bb76ff1Sjsg 	else
62261bb76ff1Sjsg 		current_link_speed = si_pi->force_pcie_gen;
62271bb76ff1Sjsg 
62281bb76ff1Sjsg 	si_pi->force_pcie_gen = SI_PCIE_GEN_INVALID;
62291bb76ff1Sjsg 	si_pi->pspp_notify_required = false;
62301bb76ff1Sjsg 	if (target_link_speed > current_link_speed) {
62311bb76ff1Sjsg 		switch (target_link_speed) {
62321bb76ff1Sjsg #if defined(CONFIG_ACPI)
62331bb76ff1Sjsg 		case SI_PCIE_GEN3:
62341bb76ff1Sjsg 			if (amdgpu_acpi_pcie_performance_request(adev, PCIE_PERF_REQ_PECI_GEN3, false) == 0)
62351bb76ff1Sjsg 				break;
62361bb76ff1Sjsg 			si_pi->force_pcie_gen = SI_PCIE_GEN2;
62371bb76ff1Sjsg 			if (current_link_speed == SI_PCIE_GEN2)
62381bb76ff1Sjsg 				break;
62391bb76ff1Sjsg 			fallthrough;
62401bb76ff1Sjsg 		case SI_PCIE_GEN2:
62411bb76ff1Sjsg 			if (amdgpu_acpi_pcie_performance_request(adev, PCIE_PERF_REQ_PECI_GEN2, false) == 0)
62421bb76ff1Sjsg 				break;
62431bb76ff1Sjsg 			fallthrough;
62441bb76ff1Sjsg #endif
62451bb76ff1Sjsg 		default:
62461bb76ff1Sjsg 			si_pi->force_pcie_gen = si_get_current_pcie_speed(adev);
62471bb76ff1Sjsg 			break;
62481bb76ff1Sjsg 		}
62491bb76ff1Sjsg 	} else {
62501bb76ff1Sjsg 		if (target_link_speed < current_link_speed)
62511bb76ff1Sjsg 			si_pi->pspp_notify_required = true;
62521bb76ff1Sjsg 	}
62531bb76ff1Sjsg }
62541bb76ff1Sjsg 
si_notify_link_speed_change_after_state_change(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_new_state,struct amdgpu_ps * amdgpu_current_state)62551bb76ff1Sjsg static void si_notify_link_speed_change_after_state_change(struct amdgpu_device *adev,
62561bb76ff1Sjsg 							   struct amdgpu_ps *amdgpu_new_state,
62571bb76ff1Sjsg 							   struct amdgpu_ps *amdgpu_current_state)
62581bb76ff1Sjsg {
62591bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
62601bb76ff1Sjsg 	enum si_pcie_gen target_link_speed = si_get_maximum_link_speed(adev, amdgpu_new_state);
62611bb76ff1Sjsg 	u8 request;
62621bb76ff1Sjsg 
62631bb76ff1Sjsg 	if (si_pi->pspp_notify_required) {
62641bb76ff1Sjsg 		if (target_link_speed == SI_PCIE_GEN3)
62651bb76ff1Sjsg 			request = PCIE_PERF_REQ_PECI_GEN3;
62661bb76ff1Sjsg 		else if (target_link_speed == SI_PCIE_GEN2)
62671bb76ff1Sjsg 			request = PCIE_PERF_REQ_PECI_GEN2;
62681bb76ff1Sjsg 		else
62691bb76ff1Sjsg 			request = PCIE_PERF_REQ_PECI_GEN1;
62701bb76ff1Sjsg 
62711bb76ff1Sjsg 		if ((request == PCIE_PERF_REQ_PECI_GEN1) &&
62721bb76ff1Sjsg 		    (si_get_current_pcie_speed(adev) > 0))
62731bb76ff1Sjsg 			return;
62741bb76ff1Sjsg 
62751bb76ff1Sjsg #if defined(CONFIG_ACPI)
62761bb76ff1Sjsg 		amdgpu_acpi_pcie_performance_request(adev, request, false);
62771bb76ff1Sjsg #endif
62781bb76ff1Sjsg 	}
62791bb76ff1Sjsg }
62801bb76ff1Sjsg 
62811bb76ff1Sjsg #if 0
62821bb76ff1Sjsg static int si_ds_request(struct amdgpu_device *adev,
62831bb76ff1Sjsg 			 bool ds_status_on, u32 count_write)
62841bb76ff1Sjsg {
62851bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
62861bb76ff1Sjsg 
62871bb76ff1Sjsg 	if (eg_pi->sclk_deep_sleep) {
62881bb76ff1Sjsg 		if (ds_status_on)
62891bb76ff1Sjsg 			return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_CancelThrottleOVRDSCLKDS) ==
62901bb76ff1Sjsg 				PPSMC_Result_OK) ?
62911bb76ff1Sjsg 				0 : -EINVAL;
62921bb76ff1Sjsg 		else
62931bb76ff1Sjsg 			return (amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_ThrottleOVRDSCLKDS) ==
62941bb76ff1Sjsg 				PPSMC_Result_OK) ? 0 : -EINVAL;
62951bb76ff1Sjsg 	}
62961bb76ff1Sjsg 	return 0;
62971bb76ff1Sjsg }
62981bb76ff1Sjsg #endif
62991bb76ff1Sjsg 
si_set_max_cu_value(struct amdgpu_device * adev)63001bb76ff1Sjsg static void si_set_max_cu_value(struct amdgpu_device *adev)
63011bb76ff1Sjsg {
63021bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
63031bb76ff1Sjsg 
63041bb76ff1Sjsg 	if (adev->asic_type == CHIP_VERDE) {
63051bb76ff1Sjsg 		switch (adev->pdev->device) {
63061bb76ff1Sjsg 		case 0x6820:
63071bb76ff1Sjsg 		case 0x6825:
63081bb76ff1Sjsg 		case 0x6821:
63091bb76ff1Sjsg 		case 0x6823:
63101bb76ff1Sjsg 		case 0x6827:
63111bb76ff1Sjsg 			si_pi->max_cu = 10;
63121bb76ff1Sjsg 			break;
63131bb76ff1Sjsg 		case 0x682D:
63141bb76ff1Sjsg 		case 0x6824:
63151bb76ff1Sjsg 		case 0x682F:
63161bb76ff1Sjsg 		case 0x6826:
63171bb76ff1Sjsg 			si_pi->max_cu = 8;
63181bb76ff1Sjsg 			break;
63191bb76ff1Sjsg 		case 0x6828:
63201bb76ff1Sjsg 		case 0x6830:
63211bb76ff1Sjsg 		case 0x6831:
63221bb76ff1Sjsg 		case 0x6838:
63231bb76ff1Sjsg 		case 0x6839:
63241bb76ff1Sjsg 		case 0x683D:
63251bb76ff1Sjsg 			si_pi->max_cu = 10;
63261bb76ff1Sjsg 			break;
63271bb76ff1Sjsg 		case 0x683B:
63281bb76ff1Sjsg 		case 0x683F:
63291bb76ff1Sjsg 		case 0x6829:
63301bb76ff1Sjsg 			si_pi->max_cu = 8;
63311bb76ff1Sjsg 			break;
63321bb76ff1Sjsg 		default:
63331bb76ff1Sjsg 			si_pi->max_cu = 0;
63341bb76ff1Sjsg 			break;
63351bb76ff1Sjsg 		}
63361bb76ff1Sjsg 	} else {
63371bb76ff1Sjsg 		si_pi->max_cu = 0;
63381bb76ff1Sjsg 	}
63391bb76ff1Sjsg }
63401bb76ff1Sjsg 
si_patch_single_dependency_table_based_on_leakage(struct amdgpu_device * adev,struct amdgpu_clock_voltage_dependency_table * table)63411bb76ff1Sjsg static int si_patch_single_dependency_table_based_on_leakage(struct amdgpu_device *adev,
63421bb76ff1Sjsg 							     struct amdgpu_clock_voltage_dependency_table *table)
63431bb76ff1Sjsg {
63441bb76ff1Sjsg 	u32 i;
63451bb76ff1Sjsg 	int j;
63461bb76ff1Sjsg 	u16 leakage_voltage;
63471bb76ff1Sjsg 
63481bb76ff1Sjsg 	if (table) {
63491bb76ff1Sjsg 		for (i = 0; i < table->count; i++) {
63501bb76ff1Sjsg 			switch (si_get_leakage_voltage_from_leakage_index(adev,
63511bb76ff1Sjsg 									  table->entries[i].v,
63521bb76ff1Sjsg 									  &leakage_voltage)) {
63531bb76ff1Sjsg 			case 0:
63541bb76ff1Sjsg 				table->entries[i].v = leakage_voltage;
63551bb76ff1Sjsg 				break;
63561bb76ff1Sjsg 			case -EAGAIN:
63571bb76ff1Sjsg 				return -EINVAL;
63581bb76ff1Sjsg 			case -EINVAL:
63591bb76ff1Sjsg 			default:
63601bb76ff1Sjsg 				break;
63611bb76ff1Sjsg 			}
63621bb76ff1Sjsg 		}
63631bb76ff1Sjsg 
63641bb76ff1Sjsg 		for (j = (table->count - 2); j >= 0; j--) {
63651bb76ff1Sjsg 			table->entries[j].v = (table->entries[j].v <= table->entries[j + 1].v) ?
63661bb76ff1Sjsg 				table->entries[j].v : table->entries[j + 1].v;
63671bb76ff1Sjsg 		}
63681bb76ff1Sjsg 	}
63691bb76ff1Sjsg 	return 0;
63701bb76ff1Sjsg }
63711bb76ff1Sjsg 
si_patch_dependency_tables_based_on_leakage(struct amdgpu_device * adev)63721bb76ff1Sjsg static int si_patch_dependency_tables_based_on_leakage(struct amdgpu_device *adev)
63731bb76ff1Sjsg {
63741bb76ff1Sjsg 	int ret = 0;
63751bb76ff1Sjsg 
63761bb76ff1Sjsg 	ret = si_patch_single_dependency_table_based_on_leakage(adev,
63771bb76ff1Sjsg 								&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk);
63781bb76ff1Sjsg 	if (ret)
63791bb76ff1Sjsg 		DRM_ERROR("Could not patch vddc_on_sclk leakage table\n");
63801bb76ff1Sjsg 	ret = si_patch_single_dependency_table_based_on_leakage(adev,
63811bb76ff1Sjsg 								&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk);
63821bb76ff1Sjsg 	if (ret)
63831bb76ff1Sjsg 		DRM_ERROR("Could not patch vddc_on_mclk leakage table\n");
63841bb76ff1Sjsg 	ret = si_patch_single_dependency_table_based_on_leakage(adev,
63851bb76ff1Sjsg 								&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk);
63861bb76ff1Sjsg 	if (ret)
63871bb76ff1Sjsg 		DRM_ERROR("Could not patch vddci_on_mclk leakage table\n");
63881bb76ff1Sjsg 	return ret;
63891bb76ff1Sjsg }
63901bb76ff1Sjsg 
si_set_pcie_lane_width_in_smc(struct amdgpu_device * adev,struct amdgpu_ps * amdgpu_new_state,struct amdgpu_ps * amdgpu_current_state)63911bb76ff1Sjsg static void si_set_pcie_lane_width_in_smc(struct amdgpu_device *adev,
63921bb76ff1Sjsg 					  struct amdgpu_ps *amdgpu_new_state,
63931bb76ff1Sjsg 					  struct amdgpu_ps *amdgpu_current_state)
63941bb76ff1Sjsg {
63951bb76ff1Sjsg 	u32 lane_width;
63961bb76ff1Sjsg 	u32 new_lane_width =
63971bb76ff1Sjsg 		((amdgpu_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
63981bb76ff1Sjsg 	u32 current_lane_width =
63991bb76ff1Sjsg 		((amdgpu_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
64001bb76ff1Sjsg 
64011bb76ff1Sjsg 	if (new_lane_width != current_lane_width) {
64021bb76ff1Sjsg 		amdgpu_set_pcie_lanes(adev, new_lane_width);
64031bb76ff1Sjsg 		lane_width = amdgpu_get_pcie_lanes(adev);
64041bb76ff1Sjsg 		si_write_smc_soft_register(adev, SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width, lane_width);
64051bb76ff1Sjsg 	}
64061bb76ff1Sjsg }
64071bb76ff1Sjsg 
si_dpm_setup_asic(struct amdgpu_device * adev)64081bb76ff1Sjsg static void si_dpm_setup_asic(struct amdgpu_device *adev)
64091bb76ff1Sjsg {
64101bb76ff1Sjsg 	si_read_clock_registers(adev);
64111bb76ff1Sjsg 	si_enable_acpi_power_management(adev);
64121bb76ff1Sjsg }
64131bb76ff1Sjsg 
si_thermal_enable_alert(struct amdgpu_device * adev,bool enable)64141bb76ff1Sjsg static int si_thermal_enable_alert(struct amdgpu_device *adev,
64151bb76ff1Sjsg 				   bool enable)
64161bb76ff1Sjsg {
64171bb76ff1Sjsg 	u32 thermal_int = RREG32(CG_THERMAL_INT);
64181bb76ff1Sjsg 
64191bb76ff1Sjsg 	if (enable) {
64201bb76ff1Sjsg 		PPSMC_Result result;
64211bb76ff1Sjsg 
64221bb76ff1Sjsg 		thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
64231bb76ff1Sjsg 		WREG32(CG_THERMAL_INT, thermal_int);
64241bb76ff1Sjsg 		result = amdgpu_si_send_msg_to_smc(adev, PPSMC_MSG_EnableThermalInterrupt);
64251bb76ff1Sjsg 		if (result != PPSMC_Result_OK) {
64261bb76ff1Sjsg 			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
64271bb76ff1Sjsg 			return -EINVAL;
64281bb76ff1Sjsg 		}
64291bb76ff1Sjsg 	} else {
64301bb76ff1Sjsg 		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
64311bb76ff1Sjsg 		WREG32(CG_THERMAL_INT, thermal_int);
64321bb76ff1Sjsg 	}
64331bb76ff1Sjsg 
64341bb76ff1Sjsg 	return 0;
64351bb76ff1Sjsg }
64361bb76ff1Sjsg 
si_thermal_set_temperature_range(struct amdgpu_device * adev,int min_temp,int max_temp)64371bb76ff1Sjsg static int si_thermal_set_temperature_range(struct amdgpu_device *adev,
64381bb76ff1Sjsg 					    int min_temp, int max_temp)
64391bb76ff1Sjsg {
64401bb76ff1Sjsg 	int low_temp = 0 * 1000;
64411bb76ff1Sjsg 	int high_temp = 255 * 1000;
64421bb76ff1Sjsg 
64431bb76ff1Sjsg 	if (low_temp < min_temp)
64441bb76ff1Sjsg 		low_temp = min_temp;
64451bb76ff1Sjsg 	if (high_temp > max_temp)
64461bb76ff1Sjsg 		high_temp = max_temp;
64471bb76ff1Sjsg 	if (high_temp < low_temp) {
64481bb76ff1Sjsg 		DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
64491bb76ff1Sjsg 		return -EINVAL;
64501bb76ff1Sjsg 	}
64511bb76ff1Sjsg 
64521bb76ff1Sjsg 	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTH(high_temp / 1000), ~DIG_THERM_INTH_MASK);
64531bb76ff1Sjsg 	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTL(low_temp / 1000), ~DIG_THERM_INTL_MASK);
64541bb76ff1Sjsg 	WREG32_P(CG_THERMAL_CTRL, DIG_THERM_DPM(high_temp / 1000), ~DIG_THERM_DPM_MASK);
64551bb76ff1Sjsg 
64561bb76ff1Sjsg 	adev->pm.dpm.thermal.min_temp = low_temp;
64571bb76ff1Sjsg 	adev->pm.dpm.thermal.max_temp = high_temp;
64581bb76ff1Sjsg 
64591bb76ff1Sjsg 	return 0;
64601bb76ff1Sjsg }
64611bb76ff1Sjsg 
si_fan_ctrl_set_static_mode(struct amdgpu_device * adev,u32 mode)64621bb76ff1Sjsg static void si_fan_ctrl_set_static_mode(struct amdgpu_device *adev, u32 mode)
64631bb76ff1Sjsg {
64641bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
64651bb76ff1Sjsg 	u32 tmp;
64661bb76ff1Sjsg 
64671bb76ff1Sjsg 	if (si_pi->fan_ctrl_is_in_default_mode) {
64681bb76ff1Sjsg 		tmp = (RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK) >> FDO_PWM_MODE_SHIFT;
64691bb76ff1Sjsg 		si_pi->fan_ctrl_default_mode = tmp;
64701bb76ff1Sjsg 		tmp = (RREG32(CG_FDO_CTRL2) & TMIN_MASK) >> TMIN_SHIFT;
64711bb76ff1Sjsg 		si_pi->t_min = tmp;
64721bb76ff1Sjsg 		si_pi->fan_ctrl_is_in_default_mode = false;
64731bb76ff1Sjsg 	}
64741bb76ff1Sjsg 
64751bb76ff1Sjsg 	tmp = RREG32(CG_FDO_CTRL2) & ~TMIN_MASK;
64761bb76ff1Sjsg 	tmp |= TMIN(0);
64771bb76ff1Sjsg 	WREG32(CG_FDO_CTRL2, tmp);
64781bb76ff1Sjsg 
64791bb76ff1Sjsg 	tmp = RREG32(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK;
64801bb76ff1Sjsg 	tmp |= FDO_PWM_MODE(mode);
64811bb76ff1Sjsg 	WREG32(CG_FDO_CTRL2, tmp);
64821bb76ff1Sjsg }
64831bb76ff1Sjsg 
si_thermal_setup_fan_table(struct amdgpu_device * adev)64841bb76ff1Sjsg static int si_thermal_setup_fan_table(struct amdgpu_device *adev)
64851bb76ff1Sjsg {
64861bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
64871bb76ff1Sjsg 	PP_SIslands_FanTable fan_table = { FDO_MODE_HARDWARE };
64881bb76ff1Sjsg 	u32 duty100;
64891bb76ff1Sjsg 	u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2;
64901bb76ff1Sjsg 	u16 fdo_min, slope1, slope2;
64911bb76ff1Sjsg 	u32 reference_clock, tmp;
64921bb76ff1Sjsg 	int ret;
64931bb76ff1Sjsg 	u64 tmp64;
64941bb76ff1Sjsg 
64951bb76ff1Sjsg 	if (!si_pi->fan_table_start) {
64961bb76ff1Sjsg 		adev->pm.dpm.fan.ucode_fan_control = false;
64971bb76ff1Sjsg 		return 0;
64981bb76ff1Sjsg 	}
64991bb76ff1Sjsg 
65001bb76ff1Sjsg 	duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
65011bb76ff1Sjsg 
65021bb76ff1Sjsg 	if (duty100 == 0) {
65031bb76ff1Sjsg 		adev->pm.dpm.fan.ucode_fan_control = false;
65041bb76ff1Sjsg 		return 0;
65051bb76ff1Sjsg 	}
65061bb76ff1Sjsg 
65071bb76ff1Sjsg 	tmp64 = (u64)adev->pm.dpm.fan.pwm_min * duty100;
65081bb76ff1Sjsg 	do_div(tmp64, 10000);
65091bb76ff1Sjsg 	fdo_min = (u16)tmp64;
65101bb76ff1Sjsg 
65111bb76ff1Sjsg 	t_diff1 = adev->pm.dpm.fan.t_med - adev->pm.dpm.fan.t_min;
65121bb76ff1Sjsg 	t_diff2 = adev->pm.dpm.fan.t_high - adev->pm.dpm.fan.t_med;
65131bb76ff1Sjsg 
65141bb76ff1Sjsg 	pwm_diff1 = adev->pm.dpm.fan.pwm_med - adev->pm.dpm.fan.pwm_min;
65151bb76ff1Sjsg 	pwm_diff2 = adev->pm.dpm.fan.pwm_high - adev->pm.dpm.fan.pwm_med;
65161bb76ff1Sjsg 
65171bb76ff1Sjsg 	slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
65181bb76ff1Sjsg 	slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);
65191bb76ff1Sjsg 
65201bb76ff1Sjsg 	fan_table.temp_min = cpu_to_be16((50 + adev->pm.dpm.fan.t_min) / 100);
65211bb76ff1Sjsg 	fan_table.temp_med = cpu_to_be16((50 + adev->pm.dpm.fan.t_med) / 100);
65221bb76ff1Sjsg 	fan_table.temp_max = cpu_to_be16((50 + adev->pm.dpm.fan.t_max) / 100);
65231bb76ff1Sjsg 	fan_table.slope1 = cpu_to_be16(slope1);
65241bb76ff1Sjsg 	fan_table.slope2 = cpu_to_be16(slope2);
65251bb76ff1Sjsg 	fan_table.fdo_min = cpu_to_be16(fdo_min);
65261bb76ff1Sjsg 	fan_table.hys_down = cpu_to_be16(adev->pm.dpm.fan.t_hyst);
65271bb76ff1Sjsg 	fan_table.hys_up = cpu_to_be16(1);
65281bb76ff1Sjsg 	fan_table.hys_slope = cpu_to_be16(1);
65291bb76ff1Sjsg 	fan_table.temp_resp_lim = cpu_to_be16(5);
65301bb76ff1Sjsg 	reference_clock = amdgpu_asic_get_xclk(adev);
65311bb76ff1Sjsg 
65321bb76ff1Sjsg 	fan_table.refresh_period = cpu_to_be32((adev->pm.dpm.fan.cycle_delay *
65331bb76ff1Sjsg 						reference_clock) / 1600);
65341bb76ff1Sjsg 	fan_table.fdo_max = cpu_to_be16((u16)duty100);
65351bb76ff1Sjsg 
65361bb76ff1Sjsg 	tmp = (RREG32(CG_MULT_THERMAL_CTRL) & TEMP_SEL_MASK) >> TEMP_SEL_SHIFT;
65371bb76ff1Sjsg 	fan_table.temp_src = (uint8_t)tmp;
65381bb76ff1Sjsg 
65391bb76ff1Sjsg 	ret = amdgpu_si_copy_bytes_to_smc(adev,
65401bb76ff1Sjsg 					  si_pi->fan_table_start,
65411bb76ff1Sjsg 					  (u8 *)(&fan_table),
65421bb76ff1Sjsg 					  sizeof(fan_table),
65431bb76ff1Sjsg 					  si_pi->sram_end);
65441bb76ff1Sjsg 
65451bb76ff1Sjsg 	if (ret) {
65461bb76ff1Sjsg 		DRM_ERROR("Failed to load fan table to the SMC.");
65471bb76ff1Sjsg 		adev->pm.dpm.fan.ucode_fan_control = false;
65481bb76ff1Sjsg 	}
65491bb76ff1Sjsg 
65501bb76ff1Sjsg 	return ret;
65511bb76ff1Sjsg }
65521bb76ff1Sjsg 
si_fan_ctrl_start_smc_fan_control(struct amdgpu_device * adev)65531bb76ff1Sjsg static int si_fan_ctrl_start_smc_fan_control(struct amdgpu_device *adev)
65541bb76ff1Sjsg {
65551bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
65561bb76ff1Sjsg 	PPSMC_Result ret;
65571bb76ff1Sjsg 
65581bb76ff1Sjsg 	ret = amdgpu_si_send_msg_to_smc(adev, PPSMC_StartFanControl);
65591bb76ff1Sjsg 	if (ret == PPSMC_Result_OK) {
65601bb76ff1Sjsg 		si_pi->fan_is_controlled_by_smc = true;
65611bb76ff1Sjsg 		return 0;
65621bb76ff1Sjsg 	} else {
65631bb76ff1Sjsg 		return -EINVAL;
65641bb76ff1Sjsg 	}
65651bb76ff1Sjsg }
65661bb76ff1Sjsg 
si_fan_ctrl_stop_smc_fan_control(struct amdgpu_device * adev)65671bb76ff1Sjsg static int si_fan_ctrl_stop_smc_fan_control(struct amdgpu_device *adev)
65681bb76ff1Sjsg {
65691bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
65701bb76ff1Sjsg 	PPSMC_Result ret;
65711bb76ff1Sjsg 
65721bb76ff1Sjsg 	ret = amdgpu_si_send_msg_to_smc(adev, PPSMC_StopFanControl);
65731bb76ff1Sjsg 
65741bb76ff1Sjsg 	if (ret == PPSMC_Result_OK) {
65751bb76ff1Sjsg 		si_pi->fan_is_controlled_by_smc = false;
65761bb76ff1Sjsg 		return 0;
65771bb76ff1Sjsg 	} else {
65781bb76ff1Sjsg 		return -EINVAL;
65791bb76ff1Sjsg 	}
65801bb76ff1Sjsg }
65811bb76ff1Sjsg 
si_dpm_get_fan_speed_pwm(void * handle,u32 * speed)65821bb76ff1Sjsg static int si_dpm_get_fan_speed_pwm(void *handle,
65831bb76ff1Sjsg 				      u32 *speed)
65841bb76ff1Sjsg {
65851bb76ff1Sjsg 	u32 duty, duty100;
65861bb76ff1Sjsg 	u64 tmp64;
65871bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
65881bb76ff1Sjsg 
65891bb76ff1Sjsg 	if (!speed)
65901bb76ff1Sjsg 		return -EINVAL;
65911bb76ff1Sjsg 
65921bb76ff1Sjsg 	if (adev->pm.no_fan)
65931bb76ff1Sjsg 		return -ENOENT;
65941bb76ff1Sjsg 
65951bb76ff1Sjsg 	duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
65961bb76ff1Sjsg 	duty = (RREG32(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT;
65971bb76ff1Sjsg 
65981bb76ff1Sjsg 	if (duty100 == 0)
65991bb76ff1Sjsg 		return -EINVAL;
66001bb76ff1Sjsg 
66011bb76ff1Sjsg 	tmp64 = (u64)duty * 255;
66021bb76ff1Sjsg 	do_div(tmp64, duty100);
66031bb76ff1Sjsg 	*speed = MIN((u32)tmp64, 255);
66041bb76ff1Sjsg 
66051bb76ff1Sjsg 	return 0;
66061bb76ff1Sjsg }
66071bb76ff1Sjsg 
si_dpm_set_fan_speed_pwm(void * handle,u32 speed)66081bb76ff1Sjsg static int si_dpm_set_fan_speed_pwm(void *handle,
66091bb76ff1Sjsg 				      u32 speed)
66101bb76ff1Sjsg {
66111bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
66121bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
66131bb76ff1Sjsg 	u32 tmp;
66141bb76ff1Sjsg 	u32 duty, duty100;
66151bb76ff1Sjsg 	u64 tmp64;
66161bb76ff1Sjsg 
66171bb76ff1Sjsg 	if (adev->pm.no_fan)
66181bb76ff1Sjsg 		return -ENOENT;
66191bb76ff1Sjsg 
66201bb76ff1Sjsg 	if (si_pi->fan_is_controlled_by_smc)
66211bb76ff1Sjsg 		return -EINVAL;
66221bb76ff1Sjsg 
66231bb76ff1Sjsg 	if (speed > 255)
66241bb76ff1Sjsg 		return -EINVAL;
66251bb76ff1Sjsg 
66261bb76ff1Sjsg 	duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
66271bb76ff1Sjsg 
66281bb76ff1Sjsg 	if (duty100 == 0)
66291bb76ff1Sjsg 		return -EINVAL;
66301bb76ff1Sjsg 
66311bb76ff1Sjsg 	tmp64 = (u64)speed * duty100;
66321bb76ff1Sjsg 	do_div(tmp64, 255);
66331bb76ff1Sjsg 	duty = (u32)tmp64;
66341bb76ff1Sjsg 
66351bb76ff1Sjsg 	tmp = RREG32(CG_FDO_CTRL0) & ~FDO_STATIC_DUTY_MASK;
66361bb76ff1Sjsg 	tmp |= FDO_STATIC_DUTY(duty);
66371bb76ff1Sjsg 	WREG32(CG_FDO_CTRL0, tmp);
66381bb76ff1Sjsg 
66391bb76ff1Sjsg 	return 0;
66401bb76ff1Sjsg }
66411bb76ff1Sjsg 
si_dpm_set_fan_control_mode(void * handle,u32 mode)66421bb76ff1Sjsg static int si_dpm_set_fan_control_mode(void *handle, u32 mode)
66431bb76ff1Sjsg {
66441bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
66451bb76ff1Sjsg 
66461bb76ff1Sjsg 	if (mode == U32_MAX)
66471bb76ff1Sjsg 		return -EINVAL;
66481bb76ff1Sjsg 
66491bb76ff1Sjsg 	if (mode) {
66501bb76ff1Sjsg 		/* stop auto-manage */
66511bb76ff1Sjsg 		if (adev->pm.dpm.fan.ucode_fan_control)
66521bb76ff1Sjsg 			si_fan_ctrl_stop_smc_fan_control(adev);
66531bb76ff1Sjsg 		si_fan_ctrl_set_static_mode(adev, mode);
66541bb76ff1Sjsg 	} else {
66551bb76ff1Sjsg 		/* restart auto-manage */
66561bb76ff1Sjsg 		if (adev->pm.dpm.fan.ucode_fan_control)
66571bb76ff1Sjsg 			si_thermal_start_smc_fan_control(adev);
66581bb76ff1Sjsg 		else
66591bb76ff1Sjsg 			si_fan_ctrl_set_default_mode(adev);
66601bb76ff1Sjsg 	}
66611bb76ff1Sjsg 
66621bb76ff1Sjsg 	return 0;
66631bb76ff1Sjsg }
66641bb76ff1Sjsg 
si_dpm_get_fan_control_mode(void * handle,u32 * fan_mode)66651bb76ff1Sjsg static int si_dpm_get_fan_control_mode(void *handle, u32 *fan_mode)
66661bb76ff1Sjsg {
66671bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
66681bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
66691bb76ff1Sjsg 	u32 tmp;
66701bb76ff1Sjsg 
66711bb76ff1Sjsg 	if (!fan_mode)
66721bb76ff1Sjsg 		return -EINVAL;
66731bb76ff1Sjsg 
66741bb76ff1Sjsg 	if (si_pi->fan_is_controlled_by_smc)
66751bb76ff1Sjsg 		return 0;
66761bb76ff1Sjsg 
66771bb76ff1Sjsg 	tmp = RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK;
66781bb76ff1Sjsg 	*fan_mode = (tmp >> FDO_PWM_MODE_SHIFT);
66791bb76ff1Sjsg 
66801bb76ff1Sjsg 	return 0;
66811bb76ff1Sjsg }
66821bb76ff1Sjsg 
66831bb76ff1Sjsg #if 0
66841bb76ff1Sjsg static int si_fan_ctrl_get_fan_speed_rpm(struct amdgpu_device *adev,
66851bb76ff1Sjsg 					 u32 *speed)
66861bb76ff1Sjsg {
66871bb76ff1Sjsg 	u32 tach_period;
66881bb76ff1Sjsg 	u32 xclk = amdgpu_asic_get_xclk(adev);
66891bb76ff1Sjsg 
66901bb76ff1Sjsg 	if (adev->pm.no_fan)
66911bb76ff1Sjsg 		return -ENOENT;
66921bb76ff1Sjsg 
66931bb76ff1Sjsg 	if (adev->pm.fan_pulses_per_revolution == 0)
66941bb76ff1Sjsg 		return -ENOENT;
66951bb76ff1Sjsg 
66961bb76ff1Sjsg 	tach_period = (RREG32(CG_TACH_STATUS) & TACH_PERIOD_MASK) >> TACH_PERIOD_SHIFT;
66971bb76ff1Sjsg 	if (tach_period == 0)
66981bb76ff1Sjsg 		return -ENOENT;
66991bb76ff1Sjsg 
67001bb76ff1Sjsg 	*speed = 60 * xclk * 10000 / tach_period;
67011bb76ff1Sjsg 
67021bb76ff1Sjsg 	return 0;
67031bb76ff1Sjsg }
67041bb76ff1Sjsg 
67051bb76ff1Sjsg static int si_fan_ctrl_set_fan_speed_rpm(struct amdgpu_device *adev,
67061bb76ff1Sjsg 					 u32 speed)
67071bb76ff1Sjsg {
67081bb76ff1Sjsg 	u32 tach_period, tmp;
67091bb76ff1Sjsg 	u32 xclk = amdgpu_asic_get_xclk(adev);
67101bb76ff1Sjsg 
67111bb76ff1Sjsg 	if (adev->pm.no_fan)
67121bb76ff1Sjsg 		return -ENOENT;
67131bb76ff1Sjsg 
67141bb76ff1Sjsg 	if (adev->pm.fan_pulses_per_revolution == 0)
67151bb76ff1Sjsg 		return -ENOENT;
67161bb76ff1Sjsg 
67171bb76ff1Sjsg 	if ((speed < adev->pm.fan_min_rpm) ||
67181bb76ff1Sjsg 	    (speed > adev->pm.fan_max_rpm))
67191bb76ff1Sjsg 		return -EINVAL;
67201bb76ff1Sjsg 
67211bb76ff1Sjsg 	if (adev->pm.dpm.fan.ucode_fan_control)
67221bb76ff1Sjsg 		si_fan_ctrl_stop_smc_fan_control(adev);
67231bb76ff1Sjsg 
67241bb76ff1Sjsg 	tach_period = 60 * xclk * 10000 / (8 * speed);
67251bb76ff1Sjsg 	tmp = RREG32(CG_TACH_CTRL) & ~TARGET_PERIOD_MASK;
67261bb76ff1Sjsg 	tmp |= TARGET_PERIOD(tach_period);
67271bb76ff1Sjsg 	WREG32(CG_TACH_CTRL, tmp);
67281bb76ff1Sjsg 
67291bb76ff1Sjsg 	si_fan_ctrl_set_static_mode(adev, FDO_PWM_MODE_STATIC_RPM);
67301bb76ff1Sjsg 
67311bb76ff1Sjsg 	return 0;
67321bb76ff1Sjsg }
67331bb76ff1Sjsg #endif
67341bb76ff1Sjsg 
si_fan_ctrl_set_default_mode(struct amdgpu_device * adev)67351bb76ff1Sjsg static void si_fan_ctrl_set_default_mode(struct amdgpu_device *adev)
67361bb76ff1Sjsg {
67371bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
67381bb76ff1Sjsg 	u32 tmp;
67391bb76ff1Sjsg 
67401bb76ff1Sjsg 	if (!si_pi->fan_ctrl_is_in_default_mode) {
67411bb76ff1Sjsg 		tmp = RREG32(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK;
67421bb76ff1Sjsg 		tmp |= FDO_PWM_MODE(si_pi->fan_ctrl_default_mode);
67431bb76ff1Sjsg 		WREG32(CG_FDO_CTRL2, tmp);
67441bb76ff1Sjsg 
67451bb76ff1Sjsg 		tmp = RREG32(CG_FDO_CTRL2) & ~TMIN_MASK;
67461bb76ff1Sjsg 		tmp |= TMIN(si_pi->t_min);
67471bb76ff1Sjsg 		WREG32(CG_FDO_CTRL2, tmp);
67481bb76ff1Sjsg 		si_pi->fan_ctrl_is_in_default_mode = true;
67491bb76ff1Sjsg 	}
67501bb76ff1Sjsg }
67511bb76ff1Sjsg 
si_thermal_start_smc_fan_control(struct amdgpu_device * adev)67521bb76ff1Sjsg static void si_thermal_start_smc_fan_control(struct amdgpu_device *adev)
67531bb76ff1Sjsg {
67541bb76ff1Sjsg 	if (adev->pm.dpm.fan.ucode_fan_control) {
67551bb76ff1Sjsg 		si_fan_ctrl_start_smc_fan_control(adev);
67561bb76ff1Sjsg 		si_fan_ctrl_set_static_mode(adev, FDO_PWM_MODE_STATIC);
67571bb76ff1Sjsg 	}
67581bb76ff1Sjsg }
67591bb76ff1Sjsg 
si_thermal_initialize(struct amdgpu_device * adev)67601bb76ff1Sjsg static void si_thermal_initialize(struct amdgpu_device *adev)
67611bb76ff1Sjsg {
67621bb76ff1Sjsg 	u32 tmp;
67631bb76ff1Sjsg 
67641bb76ff1Sjsg 	if (adev->pm.fan_pulses_per_revolution) {
67651bb76ff1Sjsg 		tmp = RREG32(CG_TACH_CTRL) & ~EDGE_PER_REV_MASK;
67661bb76ff1Sjsg 		tmp |= EDGE_PER_REV(adev->pm.fan_pulses_per_revolution -1);
67671bb76ff1Sjsg 		WREG32(CG_TACH_CTRL, tmp);
67681bb76ff1Sjsg 	}
67691bb76ff1Sjsg 
67701bb76ff1Sjsg 	tmp = RREG32(CG_FDO_CTRL2) & ~TACH_PWM_RESP_RATE_MASK;
67711bb76ff1Sjsg 	tmp |= TACH_PWM_RESP_RATE(0x28);
67721bb76ff1Sjsg 	WREG32(CG_FDO_CTRL2, tmp);
67731bb76ff1Sjsg }
67741bb76ff1Sjsg 
si_thermal_start_thermal_controller(struct amdgpu_device * adev)67751bb76ff1Sjsg static int si_thermal_start_thermal_controller(struct amdgpu_device *adev)
67761bb76ff1Sjsg {
67771bb76ff1Sjsg 	int ret;
67781bb76ff1Sjsg 
67791bb76ff1Sjsg 	si_thermal_initialize(adev);
67801bb76ff1Sjsg 	ret = si_thermal_set_temperature_range(adev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
67811bb76ff1Sjsg 	if (ret)
67821bb76ff1Sjsg 		return ret;
67831bb76ff1Sjsg 	ret = si_thermal_enable_alert(adev, true);
67841bb76ff1Sjsg 	if (ret)
67851bb76ff1Sjsg 		return ret;
67861bb76ff1Sjsg 	if (adev->pm.dpm.fan.ucode_fan_control) {
67871bb76ff1Sjsg 		ret = si_halt_smc(adev);
67881bb76ff1Sjsg 		if (ret)
67891bb76ff1Sjsg 			return ret;
67901bb76ff1Sjsg 		ret = si_thermal_setup_fan_table(adev);
67911bb76ff1Sjsg 		if (ret)
67921bb76ff1Sjsg 			return ret;
67931bb76ff1Sjsg 		ret = si_resume_smc(adev);
67941bb76ff1Sjsg 		if (ret)
67951bb76ff1Sjsg 			return ret;
67961bb76ff1Sjsg 		si_thermal_start_smc_fan_control(adev);
67971bb76ff1Sjsg 	}
67981bb76ff1Sjsg 
67991bb76ff1Sjsg 	return 0;
68001bb76ff1Sjsg }
68011bb76ff1Sjsg 
si_thermal_stop_thermal_controller(struct amdgpu_device * adev)68021bb76ff1Sjsg static void si_thermal_stop_thermal_controller(struct amdgpu_device *adev)
68031bb76ff1Sjsg {
68041bb76ff1Sjsg 	if (!adev->pm.no_fan) {
68051bb76ff1Sjsg 		si_fan_ctrl_set_default_mode(adev);
68061bb76ff1Sjsg 		si_fan_ctrl_stop_smc_fan_control(adev);
68071bb76ff1Sjsg 	}
68081bb76ff1Sjsg }
68091bb76ff1Sjsg 
si_dpm_enable(struct amdgpu_device * adev)68101bb76ff1Sjsg static int si_dpm_enable(struct amdgpu_device *adev)
68111bb76ff1Sjsg {
68121bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
68131bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
68141bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
68151bb76ff1Sjsg 	struct amdgpu_ps *boot_ps = adev->pm.dpm.boot_ps;
68161bb76ff1Sjsg 	int ret;
68171bb76ff1Sjsg 
68181bb76ff1Sjsg 	if (amdgpu_si_is_smc_running(adev))
68191bb76ff1Sjsg 		return -EINVAL;
68201bb76ff1Sjsg 	if (pi->voltage_control || si_pi->voltage_control_svi2)
68211bb76ff1Sjsg 		si_enable_voltage_control(adev, true);
68221bb76ff1Sjsg 	if (pi->mvdd_control)
68231bb76ff1Sjsg 		si_get_mvdd_configuration(adev);
68241bb76ff1Sjsg 	if (pi->voltage_control || si_pi->voltage_control_svi2) {
68251bb76ff1Sjsg 		ret = si_construct_voltage_tables(adev);
68261bb76ff1Sjsg 		if (ret) {
68271bb76ff1Sjsg 			DRM_ERROR("si_construct_voltage_tables failed\n");
68281bb76ff1Sjsg 			return ret;
68291bb76ff1Sjsg 		}
68301bb76ff1Sjsg 	}
68311bb76ff1Sjsg 	if (eg_pi->dynamic_ac_timing) {
68321bb76ff1Sjsg 		ret = si_initialize_mc_reg_table(adev);
68331bb76ff1Sjsg 		if (ret)
68341bb76ff1Sjsg 			eg_pi->dynamic_ac_timing = false;
68351bb76ff1Sjsg 	}
68361bb76ff1Sjsg 	if (pi->dynamic_ss)
68371bb76ff1Sjsg 		si_enable_spread_spectrum(adev, true);
68381bb76ff1Sjsg 	if (pi->thermal_protection)
68391bb76ff1Sjsg 		si_enable_thermal_protection(adev, true);
68401bb76ff1Sjsg 	si_setup_bsp(adev);
68411bb76ff1Sjsg 	si_program_git(adev);
68421bb76ff1Sjsg 	si_program_tp(adev);
68431bb76ff1Sjsg 	si_program_tpp(adev);
68441bb76ff1Sjsg 	si_program_sstp(adev);
68451bb76ff1Sjsg 	si_enable_display_gap(adev);
68461bb76ff1Sjsg 	si_program_vc(adev);
68471bb76ff1Sjsg 	ret = si_upload_firmware(adev);
68481bb76ff1Sjsg 	if (ret) {
68491bb76ff1Sjsg 		DRM_ERROR("si_upload_firmware failed\n");
68501bb76ff1Sjsg 		return ret;
68511bb76ff1Sjsg 	}
68521bb76ff1Sjsg 	ret = si_process_firmware_header(adev);
68531bb76ff1Sjsg 	if (ret) {
68541bb76ff1Sjsg 		DRM_ERROR("si_process_firmware_header failed\n");
68551bb76ff1Sjsg 		return ret;
68561bb76ff1Sjsg 	}
68571bb76ff1Sjsg 	ret = si_initial_switch_from_arb_f0_to_f1(adev);
68581bb76ff1Sjsg 	if (ret) {
68591bb76ff1Sjsg 		DRM_ERROR("si_initial_switch_from_arb_f0_to_f1 failed\n");
68601bb76ff1Sjsg 		return ret;
68611bb76ff1Sjsg 	}
68621bb76ff1Sjsg 	ret = si_init_smc_table(adev);
68631bb76ff1Sjsg 	if (ret) {
68641bb76ff1Sjsg 		DRM_ERROR("si_init_smc_table failed\n");
68651bb76ff1Sjsg 		return ret;
68661bb76ff1Sjsg 	}
68671bb76ff1Sjsg 	ret = si_init_smc_spll_table(adev);
68681bb76ff1Sjsg 	if (ret) {
68691bb76ff1Sjsg 		DRM_ERROR("si_init_smc_spll_table failed\n");
68701bb76ff1Sjsg 		return ret;
68711bb76ff1Sjsg 	}
68721bb76ff1Sjsg 	ret = si_init_arb_table_index(adev);
68731bb76ff1Sjsg 	if (ret) {
68741bb76ff1Sjsg 		DRM_ERROR("si_init_arb_table_index failed\n");
68751bb76ff1Sjsg 		return ret;
68761bb76ff1Sjsg 	}
68771bb76ff1Sjsg 	if (eg_pi->dynamic_ac_timing) {
68781bb76ff1Sjsg 		ret = si_populate_mc_reg_table(adev, boot_ps);
68791bb76ff1Sjsg 		if (ret) {
68801bb76ff1Sjsg 			DRM_ERROR("si_populate_mc_reg_table failed\n");
68811bb76ff1Sjsg 			return ret;
68821bb76ff1Sjsg 		}
68831bb76ff1Sjsg 	}
68841bb76ff1Sjsg 	ret = si_initialize_smc_cac_tables(adev);
68851bb76ff1Sjsg 	if (ret) {
68861bb76ff1Sjsg 		DRM_ERROR("si_initialize_smc_cac_tables failed\n");
68871bb76ff1Sjsg 		return ret;
68881bb76ff1Sjsg 	}
68891bb76ff1Sjsg 	ret = si_initialize_hardware_cac_manager(adev);
68901bb76ff1Sjsg 	if (ret) {
68911bb76ff1Sjsg 		DRM_ERROR("si_initialize_hardware_cac_manager failed\n");
68921bb76ff1Sjsg 		return ret;
68931bb76ff1Sjsg 	}
68941bb76ff1Sjsg 	ret = si_initialize_smc_dte_tables(adev);
68951bb76ff1Sjsg 	if (ret) {
68961bb76ff1Sjsg 		DRM_ERROR("si_initialize_smc_dte_tables failed\n");
68971bb76ff1Sjsg 		return ret;
68981bb76ff1Sjsg 	}
68991bb76ff1Sjsg 	ret = si_populate_smc_tdp_limits(adev, boot_ps);
69001bb76ff1Sjsg 	if (ret) {
69011bb76ff1Sjsg 		DRM_ERROR("si_populate_smc_tdp_limits failed\n");
69021bb76ff1Sjsg 		return ret;
69031bb76ff1Sjsg 	}
69041bb76ff1Sjsg 	ret = si_populate_smc_tdp_limits_2(adev, boot_ps);
69051bb76ff1Sjsg 	if (ret) {
69061bb76ff1Sjsg 		DRM_ERROR("si_populate_smc_tdp_limits_2 failed\n");
69071bb76ff1Sjsg 		return ret;
69081bb76ff1Sjsg 	}
69091bb76ff1Sjsg 	si_program_response_times(adev);
69101bb76ff1Sjsg 	si_program_ds_registers(adev);
69111bb76ff1Sjsg 	si_dpm_start_smc(adev);
69121bb76ff1Sjsg 	ret = si_notify_smc_display_change(adev, false);
69131bb76ff1Sjsg 	if (ret) {
69141bb76ff1Sjsg 		DRM_ERROR("si_notify_smc_display_change failed\n");
69151bb76ff1Sjsg 		return ret;
69161bb76ff1Sjsg 	}
69171bb76ff1Sjsg 	si_enable_sclk_control(adev, true);
69181bb76ff1Sjsg 	si_start_dpm(adev);
69191bb76ff1Sjsg 
69201bb76ff1Sjsg 	si_enable_auto_throttle_source(adev, SI_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
69211bb76ff1Sjsg 	si_thermal_start_thermal_controller(adev);
69221bb76ff1Sjsg 
69231bb76ff1Sjsg 	ni_update_current_ps(adev, boot_ps);
69241bb76ff1Sjsg 
69251bb76ff1Sjsg 	return 0;
69261bb76ff1Sjsg }
69271bb76ff1Sjsg 
si_set_temperature_range(struct amdgpu_device * adev)6928*e6341781Sjsg static int si_set_temperature_range(struct amdgpu_device *adev)
6929*e6341781Sjsg {
6930*e6341781Sjsg 	int ret;
6931*e6341781Sjsg 
6932*e6341781Sjsg 	ret = si_thermal_enable_alert(adev, false);
6933*e6341781Sjsg 	if (ret)
6934*e6341781Sjsg 		return ret;
6935*e6341781Sjsg 	ret = si_thermal_set_temperature_range(adev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
6936*e6341781Sjsg 	if (ret)
6937*e6341781Sjsg 		return ret;
6938*e6341781Sjsg 	ret = si_thermal_enable_alert(adev, true);
6939*e6341781Sjsg 	if (ret)
6940*e6341781Sjsg 		return ret;
6941*e6341781Sjsg 
6942*e6341781Sjsg 	return ret;
6943*e6341781Sjsg }
6944*e6341781Sjsg 
si_dpm_disable(struct amdgpu_device * adev)69451bb76ff1Sjsg static void si_dpm_disable(struct amdgpu_device *adev)
69461bb76ff1Sjsg {
69471bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
69481bb76ff1Sjsg 	struct amdgpu_ps *boot_ps = adev->pm.dpm.boot_ps;
69491bb76ff1Sjsg 
69501bb76ff1Sjsg 	if (!amdgpu_si_is_smc_running(adev))
69511bb76ff1Sjsg 		return;
69521bb76ff1Sjsg 	si_thermal_stop_thermal_controller(adev);
69531bb76ff1Sjsg 	si_disable_ulv(adev);
69541bb76ff1Sjsg 	si_clear_vc(adev);
69551bb76ff1Sjsg 	if (pi->thermal_protection)
69561bb76ff1Sjsg 		si_enable_thermal_protection(adev, false);
69571bb76ff1Sjsg 	si_enable_power_containment(adev, boot_ps, false);
69581bb76ff1Sjsg 	si_enable_smc_cac(adev, boot_ps, false);
69591bb76ff1Sjsg 	si_enable_spread_spectrum(adev, false);
69601bb76ff1Sjsg 	si_enable_auto_throttle_source(adev, SI_DPM_AUTO_THROTTLE_SRC_THERMAL, false);
69611bb76ff1Sjsg 	si_stop_dpm(adev);
69621bb76ff1Sjsg 	si_reset_to_default(adev);
69631bb76ff1Sjsg 	si_dpm_stop_smc(adev);
69641bb76ff1Sjsg 	si_force_switch_to_arb_f0(adev);
69651bb76ff1Sjsg 
69661bb76ff1Sjsg 	ni_update_current_ps(adev, boot_ps);
69671bb76ff1Sjsg }
69681bb76ff1Sjsg 
si_dpm_pre_set_power_state(void * handle)69691bb76ff1Sjsg static int si_dpm_pre_set_power_state(void *handle)
69701bb76ff1Sjsg {
69711bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
69721bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
69731bb76ff1Sjsg 	struct amdgpu_ps requested_ps = *adev->pm.dpm.requested_ps;
69741bb76ff1Sjsg 	struct amdgpu_ps *new_ps = &requested_ps;
69751bb76ff1Sjsg 
69761bb76ff1Sjsg 	ni_update_requested_ps(adev, new_ps);
69771bb76ff1Sjsg 	si_apply_state_adjust_rules(adev, &eg_pi->requested_rps);
69781bb76ff1Sjsg 
69791bb76ff1Sjsg 	return 0;
69801bb76ff1Sjsg }
69811bb76ff1Sjsg 
si_power_control_set_level(struct amdgpu_device * adev)69821bb76ff1Sjsg static int si_power_control_set_level(struct amdgpu_device *adev)
69831bb76ff1Sjsg {
69841bb76ff1Sjsg 	struct amdgpu_ps *new_ps = adev->pm.dpm.requested_ps;
69851bb76ff1Sjsg 	int ret;
69861bb76ff1Sjsg 
69871bb76ff1Sjsg 	ret = si_restrict_performance_levels_before_switch(adev);
69881bb76ff1Sjsg 	if (ret)
69891bb76ff1Sjsg 		return ret;
69901bb76ff1Sjsg 	ret = si_halt_smc(adev);
69911bb76ff1Sjsg 	if (ret)
69921bb76ff1Sjsg 		return ret;
69931bb76ff1Sjsg 	ret = si_populate_smc_tdp_limits(adev, new_ps);
69941bb76ff1Sjsg 	if (ret)
69951bb76ff1Sjsg 		return ret;
69961bb76ff1Sjsg 	ret = si_populate_smc_tdp_limits_2(adev, new_ps);
69971bb76ff1Sjsg 	if (ret)
69981bb76ff1Sjsg 		return ret;
69991bb76ff1Sjsg 	ret = si_resume_smc(adev);
70001bb76ff1Sjsg 	if (ret)
70011bb76ff1Sjsg 		return ret;
70021bb76ff1Sjsg 	return si_set_sw_state(adev);
70031bb76ff1Sjsg }
70041bb76ff1Sjsg 
si_set_vce_clock(struct amdgpu_device * adev,struct amdgpu_ps * new_rps,struct amdgpu_ps * old_rps)70051bb76ff1Sjsg static void si_set_vce_clock(struct amdgpu_device *adev,
70061bb76ff1Sjsg 			     struct amdgpu_ps *new_rps,
70071bb76ff1Sjsg 			     struct amdgpu_ps *old_rps)
70081bb76ff1Sjsg {
70091bb76ff1Sjsg 	if ((old_rps->evclk != new_rps->evclk) ||
70101bb76ff1Sjsg 	    (old_rps->ecclk != new_rps->ecclk)) {
70111bb76ff1Sjsg 		/* Turn the clocks on when encoding, off otherwise */
70121bb76ff1Sjsg 		if (new_rps->evclk || new_rps->ecclk) {
70131bb76ff1Sjsg 			/* Place holder for future VCE1.0 porting to amdgpu
70141bb76ff1Sjsg 			vce_v1_0_enable_mgcg(adev, false, false);*/
70151bb76ff1Sjsg 		} else {
70161bb76ff1Sjsg 			/* Place holder for future VCE1.0 porting to amdgpu
70171bb76ff1Sjsg 			vce_v1_0_enable_mgcg(adev, true, false);
70181bb76ff1Sjsg 			amdgpu_asic_set_vce_clocks(adev, new_rps->evclk, new_rps->ecclk);*/
70191bb76ff1Sjsg 		}
70201bb76ff1Sjsg 	}
70211bb76ff1Sjsg }
70221bb76ff1Sjsg 
si_dpm_set_power_state(void * handle)70231bb76ff1Sjsg static int si_dpm_set_power_state(void *handle)
70241bb76ff1Sjsg {
70251bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
70261bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
70271bb76ff1Sjsg 	struct amdgpu_ps *new_ps = &eg_pi->requested_rps;
70281bb76ff1Sjsg 	struct amdgpu_ps *old_ps = &eg_pi->current_rps;
70291bb76ff1Sjsg 	int ret;
70301bb76ff1Sjsg 
70311bb76ff1Sjsg 	ret = si_disable_ulv(adev);
70321bb76ff1Sjsg 	if (ret) {
70331bb76ff1Sjsg 		DRM_ERROR("si_disable_ulv failed\n");
70341bb76ff1Sjsg 		return ret;
70351bb76ff1Sjsg 	}
70361bb76ff1Sjsg 	ret = si_restrict_performance_levels_before_switch(adev);
70371bb76ff1Sjsg 	if (ret) {
70381bb76ff1Sjsg 		DRM_ERROR("si_restrict_performance_levels_before_switch failed\n");
70391bb76ff1Sjsg 		return ret;
70401bb76ff1Sjsg 	}
70411bb76ff1Sjsg 	if (eg_pi->pcie_performance_request)
70421bb76ff1Sjsg 		si_request_link_speed_change_before_state_change(adev, new_ps, old_ps);
70431bb76ff1Sjsg 	ni_set_uvd_clock_before_set_eng_clock(adev, new_ps, old_ps);
70441bb76ff1Sjsg 	ret = si_enable_power_containment(adev, new_ps, false);
70451bb76ff1Sjsg 	if (ret) {
70461bb76ff1Sjsg 		DRM_ERROR("si_enable_power_containment failed\n");
70471bb76ff1Sjsg 		return ret;
70481bb76ff1Sjsg 	}
70491bb76ff1Sjsg 	ret = si_enable_smc_cac(adev, new_ps, false);
70501bb76ff1Sjsg 	if (ret) {
70511bb76ff1Sjsg 		DRM_ERROR("si_enable_smc_cac failed\n");
70521bb76ff1Sjsg 		return ret;
70531bb76ff1Sjsg 	}
70541bb76ff1Sjsg 	ret = si_halt_smc(adev);
70551bb76ff1Sjsg 	if (ret) {
70561bb76ff1Sjsg 		DRM_ERROR("si_halt_smc failed\n");
70571bb76ff1Sjsg 		return ret;
70581bb76ff1Sjsg 	}
70591bb76ff1Sjsg 	ret = si_upload_sw_state(adev, new_ps);
70601bb76ff1Sjsg 	if (ret) {
70611bb76ff1Sjsg 		DRM_ERROR("si_upload_sw_state failed\n");
70621bb76ff1Sjsg 		return ret;
70631bb76ff1Sjsg 	}
70641bb76ff1Sjsg 	ret = si_upload_smc_data(adev);
70651bb76ff1Sjsg 	if (ret) {
70661bb76ff1Sjsg 		DRM_ERROR("si_upload_smc_data failed\n");
70671bb76ff1Sjsg 		return ret;
70681bb76ff1Sjsg 	}
70691bb76ff1Sjsg 	ret = si_upload_ulv_state(adev);
70701bb76ff1Sjsg 	if (ret) {
70711bb76ff1Sjsg 		DRM_ERROR("si_upload_ulv_state failed\n");
70721bb76ff1Sjsg 		return ret;
70731bb76ff1Sjsg 	}
70741bb76ff1Sjsg 	if (eg_pi->dynamic_ac_timing) {
70751bb76ff1Sjsg 		ret = si_upload_mc_reg_table(adev, new_ps);
70761bb76ff1Sjsg 		if (ret) {
70771bb76ff1Sjsg 			DRM_ERROR("si_upload_mc_reg_table failed\n");
70781bb76ff1Sjsg 			return ret;
70791bb76ff1Sjsg 		}
70801bb76ff1Sjsg 	}
70811bb76ff1Sjsg 	ret = si_program_memory_timing_parameters(adev, new_ps);
70821bb76ff1Sjsg 	if (ret) {
70831bb76ff1Sjsg 		DRM_ERROR("si_program_memory_timing_parameters failed\n");
70841bb76ff1Sjsg 		return ret;
70851bb76ff1Sjsg 	}
70861bb76ff1Sjsg 	si_set_pcie_lane_width_in_smc(adev, new_ps, old_ps);
70871bb76ff1Sjsg 
70881bb76ff1Sjsg 	ret = si_resume_smc(adev);
70891bb76ff1Sjsg 	if (ret) {
70901bb76ff1Sjsg 		DRM_ERROR("si_resume_smc failed\n");
70911bb76ff1Sjsg 		return ret;
70921bb76ff1Sjsg 	}
70931bb76ff1Sjsg 	ret = si_set_sw_state(adev);
70941bb76ff1Sjsg 	if (ret) {
70951bb76ff1Sjsg 		DRM_ERROR("si_set_sw_state failed\n");
70961bb76ff1Sjsg 		return ret;
70971bb76ff1Sjsg 	}
70981bb76ff1Sjsg 	ni_set_uvd_clock_after_set_eng_clock(adev, new_ps, old_ps);
70991bb76ff1Sjsg 	si_set_vce_clock(adev, new_ps, old_ps);
71001bb76ff1Sjsg 	if (eg_pi->pcie_performance_request)
71011bb76ff1Sjsg 		si_notify_link_speed_change_after_state_change(adev, new_ps, old_ps);
71021bb76ff1Sjsg 	ret = si_set_power_state_conditionally_enable_ulv(adev, new_ps);
71031bb76ff1Sjsg 	if (ret) {
71041bb76ff1Sjsg 		DRM_ERROR("si_set_power_state_conditionally_enable_ulv failed\n");
71051bb76ff1Sjsg 		return ret;
71061bb76ff1Sjsg 	}
71071bb76ff1Sjsg 	ret = si_enable_smc_cac(adev, new_ps, true);
71081bb76ff1Sjsg 	if (ret) {
71091bb76ff1Sjsg 		DRM_ERROR("si_enable_smc_cac failed\n");
71101bb76ff1Sjsg 		return ret;
71111bb76ff1Sjsg 	}
71121bb76ff1Sjsg 	ret = si_enable_power_containment(adev, new_ps, true);
71131bb76ff1Sjsg 	if (ret) {
71141bb76ff1Sjsg 		DRM_ERROR("si_enable_power_containment failed\n");
71151bb76ff1Sjsg 		return ret;
71161bb76ff1Sjsg 	}
71171bb76ff1Sjsg 
71181bb76ff1Sjsg 	ret = si_power_control_set_level(adev);
71191bb76ff1Sjsg 	if (ret) {
71201bb76ff1Sjsg 		DRM_ERROR("si_power_control_set_level failed\n");
71211bb76ff1Sjsg 		return ret;
71221bb76ff1Sjsg 	}
71231bb76ff1Sjsg 
71241bb76ff1Sjsg 	return 0;
71251bb76ff1Sjsg }
71261bb76ff1Sjsg 
si_dpm_post_set_power_state(void * handle)71271bb76ff1Sjsg static void si_dpm_post_set_power_state(void *handle)
71281bb76ff1Sjsg {
71291bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
71301bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
71311bb76ff1Sjsg 	struct amdgpu_ps *new_ps = &eg_pi->requested_rps;
71321bb76ff1Sjsg 
71331bb76ff1Sjsg 	ni_update_current_ps(adev, new_ps);
71341bb76ff1Sjsg }
71351bb76ff1Sjsg 
71361bb76ff1Sjsg #if 0
71371bb76ff1Sjsg void si_dpm_reset_asic(struct amdgpu_device *adev)
71381bb76ff1Sjsg {
71391bb76ff1Sjsg 	si_restrict_performance_levels_before_switch(adev);
71401bb76ff1Sjsg 	si_disable_ulv(adev);
71411bb76ff1Sjsg 	si_set_boot_state(adev);
71421bb76ff1Sjsg }
71431bb76ff1Sjsg #endif
71441bb76ff1Sjsg 
si_dpm_display_configuration_changed(void * handle)71451bb76ff1Sjsg static void si_dpm_display_configuration_changed(void *handle)
71461bb76ff1Sjsg {
71471bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
71481bb76ff1Sjsg 
71491bb76ff1Sjsg 	si_program_display_gap(adev);
71501bb76ff1Sjsg }
71511bb76ff1Sjsg 
71521bb76ff1Sjsg 
si_parse_pplib_non_clock_info(struct amdgpu_device * adev,struct amdgpu_ps * rps,struct _ATOM_PPLIB_NONCLOCK_INFO * non_clock_info,u8 table_rev)71531bb76ff1Sjsg static void si_parse_pplib_non_clock_info(struct amdgpu_device *adev,
71541bb76ff1Sjsg 					  struct amdgpu_ps *rps,
71551bb76ff1Sjsg 					  struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
71561bb76ff1Sjsg 					  u8 table_rev)
71571bb76ff1Sjsg {
71581bb76ff1Sjsg 	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
71591bb76ff1Sjsg 	rps->class = le16_to_cpu(non_clock_info->usClassification);
71601bb76ff1Sjsg 	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
71611bb76ff1Sjsg 
71621bb76ff1Sjsg 	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
71631bb76ff1Sjsg 		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
71641bb76ff1Sjsg 		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
71651bb76ff1Sjsg 	} else if (r600_is_uvd_state(rps->class, rps->class2)) {
71661bb76ff1Sjsg 		rps->vclk = RV770_DEFAULT_VCLK_FREQ;
71671bb76ff1Sjsg 		rps->dclk = RV770_DEFAULT_DCLK_FREQ;
71681bb76ff1Sjsg 	} else {
71691bb76ff1Sjsg 		rps->vclk = 0;
71701bb76ff1Sjsg 		rps->dclk = 0;
71711bb76ff1Sjsg 	}
71721bb76ff1Sjsg 
71731bb76ff1Sjsg 	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
71741bb76ff1Sjsg 		adev->pm.dpm.boot_ps = rps;
71751bb76ff1Sjsg 	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
71761bb76ff1Sjsg 		adev->pm.dpm.uvd_ps = rps;
71771bb76ff1Sjsg }
71781bb76ff1Sjsg 
si_parse_pplib_clock_info(struct amdgpu_device * adev,struct amdgpu_ps * rps,int index,union pplib_clock_info * clock_info)71791bb76ff1Sjsg static void si_parse_pplib_clock_info(struct amdgpu_device *adev,
71801bb76ff1Sjsg 				      struct amdgpu_ps *rps, int index,
71811bb76ff1Sjsg 				      union pplib_clock_info *clock_info)
71821bb76ff1Sjsg {
71831bb76ff1Sjsg 	struct rv7xx_power_info *pi = rv770_get_pi(adev);
71841bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
71851bb76ff1Sjsg 	struct si_power_info *si_pi = si_get_pi(adev);
71861bb76ff1Sjsg 	struct  si_ps *ps = si_get_ps(rps);
71871bb76ff1Sjsg 	u16 leakage_voltage;
71881bb76ff1Sjsg 	struct rv7xx_pl *pl = &ps->performance_levels[index];
71891bb76ff1Sjsg 	int ret;
71901bb76ff1Sjsg 
71911bb76ff1Sjsg 	ps->performance_level_count = index + 1;
71921bb76ff1Sjsg 
71931bb76ff1Sjsg 	pl->sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
71941bb76ff1Sjsg 	pl->sclk |= clock_info->si.ucEngineClockHigh << 16;
71951bb76ff1Sjsg 	pl->mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
71961bb76ff1Sjsg 	pl->mclk |= clock_info->si.ucMemoryClockHigh << 16;
71971bb76ff1Sjsg 
71981bb76ff1Sjsg 	pl->vddc = le16_to_cpu(clock_info->si.usVDDC);
71991bb76ff1Sjsg 	pl->vddci = le16_to_cpu(clock_info->si.usVDDCI);
72001bb76ff1Sjsg 	pl->flags = le32_to_cpu(clock_info->si.ulFlags);
72011bb76ff1Sjsg 	pl->pcie_gen = si_gen_pcie_gen_support(adev,
72021bb76ff1Sjsg 					       si_pi->sys_pcie_mask,
72031bb76ff1Sjsg 					       si_pi->boot_pcie_gen,
72041bb76ff1Sjsg 					       clock_info->si.ucPCIEGen);
72051bb76ff1Sjsg 
72061bb76ff1Sjsg 	/* patch up vddc if necessary */
72071bb76ff1Sjsg 	ret = si_get_leakage_voltage_from_leakage_index(adev, pl->vddc,
72081bb76ff1Sjsg 							&leakage_voltage);
72091bb76ff1Sjsg 	if (ret == 0)
72101bb76ff1Sjsg 		pl->vddc = leakage_voltage;
72111bb76ff1Sjsg 
72121bb76ff1Sjsg 	if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
72131bb76ff1Sjsg 		pi->acpi_vddc = pl->vddc;
72141bb76ff1Sjsg 		eg_pi->acpi_vddci = pl->vddci;
72151bb76ff1Sjsg 		si_pi->acpi_pcie_gen = pl->pcie_gen;
72161bb76ff1Sjsg 	}
72171bb76ff1Sjsg 
72181bb76ff1Sjsg 	if ((rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) &&
72191bb76ff1Sjsg 	    index == 0) {
72201bb76ff1Sjsg 		/* XXX disable for A0 tahiti */
72211bb76ff1Sjsg 		si_pi->ulv.supported = false;
72221bb76ff1Sjsg 		si_pi->ulv.pl = *pl;
72231bb76ff1Sjsg 		si_pi->ulv.one_pcie_lane_in_ulv = false;
72241bb76ff1Sjsg 		si_pi->ulv.volt_change_delay = SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT;
72251bb76ff1Sjsg 		si_pi->ulv.cg_ulv_parameter = SISLANDS_CGULVPARAMETER_DFLT;
72261bb76ff1Sjsg 		si_pi->ulv.cg_ulv_control = SISLANDS_CGULVCONTROL_DFLT;
72271bb76ff1Sjsg 	}
72281bb76ff1Sjsg 
72291bb76ff1Sjsg 	if (pi->min_vddc_in_table > pl->vddc)
72301bb76ff1Sjsg 		pi->min_vddc_in_table = pl->vddc;
72311bb76ff1Sjsg 
72321bb76ff1Sjsg 	if (pi->max_vddc_in_table < pl->vddc)
72331bb76ff1Sjsg 		pi->max_vddc_in_table = pl->vddc;
72341bb76ff1Sjsg 
72351bb76ff1Sjsg 	/* patch up boot state */
72361bb76ff1Sjsg 	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
72371bb76ff1Sjsg 		u16 vddc, vddci, mvdd;
72381bb76ff1Sjsg 		amdgpu_atombios_get_default_voltages(adev, &vddc, &vddci, &mvdd);
72391bb76ff1Sjsg 		pl->mclk = adev->clock.default_mclk;
72401bb76ff1Sjsg 		pl->sclk = adev->clock.default_sclk;
72411bb76ff1Sjsg 		pl->vddc = vddc;
72421bb76ff1Sjsg 		pl->vddci = vddci;
72431bb76ff1Sjsg 		si_pi->mvdd_bootup_value = mvdd;
72441bb76ff1Sjsg 	}
72451bb76ff1Sjsg 
72461bb76ff1Sjsg 	if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
72471bb76ff1Sjsg 	    ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
72481bb76ff1Sjsg 		adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk;
72491bb76ff1Sjsg 		adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk;
72501bb76ff1Sjsg 		adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc;
72511bb76ff1Sjsg 		adev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci;
72521bb76ff1Sjsg 	}
72531bb76ff1Sjsg }
72541bb76ff1Sjsg 
72551bb76ff1Sjsg union pplib_power_state {
72561bb76ff1Sjsg 	struct _ATOM_PPLIB_STATE v1;
72571bb76ff1Sjsg 	struct _ATOM_PPLIB_STATE_V2 v2;
72581bb76ff1Sjsg };
72591bb76ff1Sjsg 
si_parse_power_table(struct amdgpu_device * adev)72601bb76ff1Sjsg static int si_parse_power_table(struct amdgpu_device *adev)
72611bb76ff1Sjsg {
72621bb76ff1Sjsg 	struct amdgpu_mode_info *mode_info = &adev->mode_info;
72631bb76ff1Sjsg 	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
72641bb76ff1Sjsg 	union pplib_power_state *power_state;
72651bb76ff1Sjsg 	int i, j, k, non_clock_array_index, clock_array_index;
72661bb76ff1Sjsg 	union pplib_clock_info *clock_info;
72671bb76ff1Sjsg 	struct _StateArray *state_array;
72681bb76ff1Sjsg 	struct _ClockInfoArray *clock_info_array;
72691bb76ff1Sjsg 	struct _NonClockInfoArray *non_clock_info_array;
72701bb76ff1Sjsg 	union power_info *power_info;
72711bb76ff1Sjsg 	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
72721bb76ff1Sjsg 	u16 data_offset;
72731bb76ff1Sjsg 	u8 frev, crev;
72741bb76ff1Sjsg 	u8 *power_state_offset;
72751bb76ff1Sjsg 	struct  si_ps *ps;
72761bb76ff1Sjsg 
72771bb76ff1Sjsg 	if (!amdgpu_atom_parse_data_header(mode_info->atom_context, index, NULL,
72781bb76ff1Sjsg 				   &frev, &crev, &data_offset))
72791bb76ff1Sjsg 		return -EINVAL;
72801bb76ff1Sjsg 	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
72811bb76ff1Sjsg 
72821bb76ff1Sjsg 	amdgpu_add_thermal_controller(adev);
72831bb76ff1Sjsg 
72841bb76ff1Sjsg 	state_array = (struct _StateArray *)
72851bb76ff1Sjsg 		(mode_info->atom_context->bios + data_offset +
72861bb76ff1Sjsg 		 le16_to_cpu(power_info->pplib.usStateArrayOffset));
72871bb76ff1Sjsg 	clock_info_array = (struct _ClockInfoArray *)
72881bb76ff1Sjsg 		(mode_info->atom_context->bios + data_offset +
72891bb76ff1Sjsg 		 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
72901bb76ff1Sjsg 	non_clock_info_array = (struct _NonClockInfoArray *)
72911bb76ff1Sjsg 		(mode_info->atom_context->bios + data_offset +
72921bb76ff1Sjsg 		 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
72931bb76ff1Sjsg 
72941bb76ff1Sjsg 	adev->pm.dpm.ps = kcalloc(state_array->ucNumEntries,
72951bb76ff1Sjsg 				  sizeof(struct amdgpu_ps),
72961bb76ff1Sjsg 				  GFP_KERNEL);
72971bb76ff1Sjsg 	if (!adev->pm.dpm.ps)
72981bb76ff1Sjsg 		return -ENOMEM;
72991bb76ff1Sjsg 	power_state_offset = (u8 *)state_array->states;
73001bb76ff1Sjsg 	for (adev->pm.dpm.num_ps = 0, i = 0; i < state_array->ucNumEntries; i++) {
73011bb76ff1Sjsg 		u8 *idx;
73021bb76ff1Sjsg 		power_state = (union pplib_power_state *)power_state_offset;
73031bb76ff1Sjsg 		non_clock_array_index = power_state->v2.nonClockInfoIndex;
73041bb76ff1Sjsg 		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
73051bb76ff1Sjsg 			&non_clock_info_array->nonClockInfo[non_clock_array_index];
73061bb76ff1Sjsg 		ps = kzalloc(sizeof(struct  si_ps), GFP_KERNEL);
73071bb76ff1Sjsg 		if (ps == NULL)
73081bb76ff1Sjsg 			return -ENOMEM;
73091bb76ff1Sjsg 		adev->pm.dpm.ps[i].ps_priv = ps;
73101bb76ff1Sjsg 		si_parse_pplib_non_clock_info(adev, &adev->pm.dpm.ps[i],
73111bb76ff1Sjsg 					      non_clock_info,
73121bb76ff1Sjsg 					      non_clock_info_array->ucEntrySize);
73131bb76ff1Sjsg 		k = 0;
73141bb76ff1Sjsg 		idx = (u8 *)&power_state->v2.clockInfoIndex[0];
73151bb76ff1Sjsg 		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
73161bb76ff1Sjsg 			clock_array_index = idx[j];
73171bb76ff1Sjsg 			if (clock_array_index >= clock_info_array->ucNumEntries)
73181bb76ff1Sjsg 				continue;
73191bb76ff1Sjsg 			if (k >= SISLANDS_MAX_HARDWARE_POWERLEVELS)
73201bb76ff1Sjsg 				break;
73211bb76ff1Sjsg 			clock_info = (union pplib_clock_info *)
73221bb76ff1Sjsg 				((u8 *)&clock_info_array->clockInfo[0] +
73231bb76ff1Sjsg 				 (clock_array_index * clock_info_array->ucEntrySize));
73241bb76ff1Sjsg 			si_parse_pplib_clock_info(adev,
73251bb76ff1Sjsg 						  &adev->pm.dpm.ps[i], k,
73261bb76ff1Sjsg 						  clock_info);
73271bb76ff1Sjsg 			k++;
73281bb76ff1Sjsg 		}
73291bb76ff1Sjsg 		power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
73301bb76ff1Sjsg 		adev->pm.dpm.num_ps++;
73311bb76ff1Sjsg 	}
73321bb76ff1Sjsg 
73331bb76ff1Sjsg 	/* fill in the vce power states */
73341bb76ff1Sjsg 	for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) {
73351bb76ff1Sjsg 		u32 sclk, mclk;
73361bb76ff1Sjsg 		clock_array_index = adev->pm.dpm.vce_states[i].clk_idx;
73371bb76ff1Sjsg 		clock_info = (union pplib_clock_info *)
73381bb76ff1Sjsg 			&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
73391bb76ff1Sjsg 		sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
73401bb76ff1Sjsg 		sclk |= clock_info->si.ucEngineClockHigh << 16;
73411bb76ff1Sjsg 		mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
73421bb76ff1Sjsg 		mclk |= clock_info->si.ucMemoryClockHigh << 16;
73431bb76ff1Sjsg 		adev->pm.dpm.vce_states[i].sclk = sclk;
73441bb76ff1Sjsg 		adev->pm.dpm.vce_states[i].mclk = mclk;
73451bb76ff1Sjsg 	}
73461bb76ff1Sjsg 
73471bb76ff1Sjsg 	return 0;
73481bb76ff1Sjsg }
73491bb76ff1Sjsg 
si_dpm_init(struct amdgpu_device * adev)73501bb76ff1Sjsg static int si_dpm_init(struct amdgpu_device *adev)
73511bb76ff1Sjsg {
73521bb76ff1Sjsg 	struct rv7xx_power_info *pi;
73531bb76ff1Sjsg 	struct evergreen_power_info *eg_pi;
73541bb76ff1Sjsg 	struct ni_power_info *ni_pi;
73551bb76ff1Sjsg 	struct si_power_info *si_pi;
73561bb76ff1Sjsg 	struct atom_clock_dividers dividers;
73571bb76ff1Sjsg 	int ret;
73581bb76ff1Sjsg 
73591bb76ff1Sjsg 	si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL);
73601bb76ff1Sjsg 	if (si_pi == NULL)
73611bb76ff1Sjsg 		return -ENOMEM;
73621bb76ff1Sjsg 	adev->pm.dpm.priv = si_pi;
73631bb76ff1Sjsg 	ni_pi = &si_pi->ni;
73641bb76ff1Sjsg 	eg_pi = &ni_pi->eg;
73651bb76ff1Sjsg 	pi = &eg_pi->rv7xx;
73661bb76ff1Sjsg 
73671bb76ff1Sjsg 	si_pi->sys_pcie_mask =
73681bb76ff1Sjsg 		adev->pm.pcie_gen_mask & CAIL_PCIE_LINK_SPEED_SUPPORT_MASK;
73691bb76ff1Sjsg 	si_pi->force_pcie_gen = SI_PCIE_GEN_INVALID;
73701bb76ff1Sjsg 	si_pi->boot_pcie_gen = si_get_current_pcie_speed(adev);
73711bb76ff1Sjsg 
73721bb76ff1Sjsg 	si_set_max_cu_value(adev);
73731bb76ff1Sjsg 
73741bb76ff1Sjsg 	rv770_get_max_vddc(adev);
73751bb76ff1Sjsg 	si_get_leakage_vddc(adev);
73761bb76ff1Sjsg 	si_patch_dependency_tables_based_on_leakage(adev);
73771bb76ff1Sjsg 
73781bb76ff1Sjsg 	pi->acpi_vddc = 0;
73791bb76ff1Sjsg 	eg_pi->acpi_vddci = 0;
73801bb76ff1Sjsg 	pi->min_vddc_in_table = 0;
73811bb76ff1Sjsg 	pi->max_vddc_in_table = 0;
73821bb76ff1Sjsg 
73831bb76ff1Sjsg 	ret = amdgpu_get_platform_caps(adev);
73841bb76ff1Sjsg 	if (ret)
73851bb76ff1Sjsg 		return ret;
73861bb76ff1Sjsg 
73871bb76ff1Sjsg 	ret = amdgpu_parse_extended_power_table(adev);
73881bb76ff1Sjsg 	if (ret)
73891bb76ff1Sjsg 		return ret;
73901bb76ff1Sjsg 
73911bb76ff1Sjsg 	ret = si_parse_power_table(adev);
73921bb76ff1Sjsg 	if (ret)
73931bb76ff1Sjsg 		return ret;
73941bb76ff1Sjsg 
73951bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
73961bb76ff1Sjsg 		kcalloc(4,
73971bb76ff1Sjsg 			sizeof(struct amdgpu_clock_voltage_dependency_entry),
73981bb76ff1Sjsg 			GFP_KERNEL);
7399dac1dc01Sjsg 	if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries)
74001bb76ff1Sjsg 		return -ENOMEM;
7401dac1dc01Sjsg 
74021bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
74031bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
74041bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
74051bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
74061bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 720;
74071bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
74081bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 810;
74091bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
74101bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 900;
74111bb76ff1Sjsg 
74121bb76ff1Sjsg 	if (adev->pm.dpm.voltage_response_time == 0)
74131bb76ff1Sjsg 		adev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
74141bb76ff1Sjsg 	if (adev->pm.dpm.backbias_response_time == 0)
74151bb76ff1Sjsg 		adev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
74161bb76ff1Sjsg 
74171bb76ff1Sjsg 	ret = amdgpu_atombios_get_clock_dividers(adev, COMPUTE_ENGINE_PLL_PARAM,
74181bb76ff1Sjsg 					     0, false, &dividers);
74191bb76ff1Sjsg 	if (ret)
74201bb76ff1Sjsg 		pi->ref_div = dividers.ref_div + 1;
74211bb76ff1Sjsg 	else
74221bb76ff1Sjsg 		pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
74231bb76ff1Sjsg 
74241bb76ff1Sjsg 	eg_pi->smu_uvd_hs = false;
74251bb76ff1Sjsg 
74261bb76ff1Sjsg 	pi->mclk_strobe_mode_threshold = 40000;
74271bb76ff1Sjsg 	if (si_is_special_1gb_platform(adev))
74281bb76ff1Sjsg 		pi->mclk_stutter_mode_threshold = 0;
74291bb76ff1Sjsg 	else
74301bb76ff1Sjsg 		pi->mclk_stutter_mode_threshold = pi->mclk_strobe_mode_threshold;
74311bb76ff1Sjsg 	pi->mclk_edc_enable_threshold = 40000;
74321bb76ff1Sjsg 	eg_pi->mclk_edc_wr_enable_threshold = 40000;
74331bb76ff1Sjsg 
74341bb76ff1Sjsg 	ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold;
74351bb76ff1Sjsg 
74361bb76ff1Sjsg 	pi->voltage_control =
74371bb76ff1Sjsg 		amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,
74381bb76ff1Sjsg 					    VOLTAGE_OBJ_GPIO_LUT);
74391bb76ff1Sjsg 	if (!pi->voltage_control) {
74401bb76ff1Sjsg 		si_pi->voltage_control_svi2 =
74411bb76ff1Sjsg 			amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,
74421bb76ff1Sjsg 						    VOLTAGE_OBJ_SVID2);
74431bb76ff1Sjsg 		if (si_pi->voltage_control_svi2)
74441bb76ff1Sjsg 			amdgpu_atombios_get_svi2_info(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,
74451bb76ff1Sjsg 						  &si_pi->svd_gpio_id, &si_pi->svc_gpio_id);
74461bb76ff1Sjsg 	}
74471bb76ff1Sjsg 
74481bb76ff1Sjsg 	pi->mvdd_control =
74491bb76ff1Sjsg 		amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_MVDDC,
74501bb76ff1Sjsg 					    VOLTAGE_OBJ_GPIO_LUT);
74511bb76ff1Sjsg 
74521bb76ff1Sjsg 	eg_pi->vddci_control =
74531bb76ff1Sjsg 		amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDCI,
74541bb76ff1Sjsg 					    VOLTAGE_OBJ_GPIO_LUT);
74551bb76ff1Sjsg 	if (!eg_pi->vddci_control)
74561bb76ff1Sjsg 		si_pi->vddci_control_svi2 =
74571bb76ff1Sjsg 			amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDCI,
74581bb76ff1Sjsg 						    VOLTAGE_OBJ_SVID2);
74591bb76ff1Sjsg 
74601bb76ff1Sjsg 	si_pi->vddc_phase_shed_control =
74611bb76ff1Sjsg 		amdgpu_atombios_is_voltage_gpio(adev, SET_VOLTAGE_TYPE_ASIC_VDDC,
74621bb76ff1Sjsg 					    VOLTAGE_OBJ_PHASE_LUT);
74631bb76ff1Sjsg 
74641bb76ff1Sjsg 	rv770_get_engine_memory_ss(adev);
74651bb76ff1Sjsg 
74661bb76ff1Sjsg 	pi->asi = RV770_ASI_DFLT;
74671bb76ff1Sjsg 	pi->pasi = CYPRESS_HASI_DFLT;
74681bb76ff1Sjsg 	pi->vrc = SISLANDS_VRC_DFLT;
74691bb76ff1Sjsg 
74701bb76ff1Sjsg 	pi->gfx_clock_gating = true;
74711bb76ff1Sjsg 
74721bb76ff1Sjsg 	eg_pi->sclk_deep_sleep = true;
74731bb76ff1Sjsg 	si_pi->sclk_deep_sleep_above_low = false;
74741bb76ff1Sjsg 
74751bb76ff1Sjsg 	if (adev->pm.int_thermal_type != THERMAL_TYPE_NONE)
74761bb76ff1Sjsg 		pi->thermal_protection = true;
74771bb76ff1Sjsg 	else
74781bb76ff1Sjsg 		pi->thermal_protection = false;
74791bb76ff1Sjsg 
74801bb76ff1Sjsg 	eg_pi->dynamic_ac_timing = true;
74811bb76ff1Sjsg 
74821bb76ff1Sjsg 	eg_pi->light_sleep = true;
74831bb76ff1Sjsg #if defined(CONFIG_ACPI)
74841bb76ff1Sjsg 	eg_pi->pcie_performance_request =
74851bb76ff1Sjsg 		amdgpu_acpi_is_pcie_performance_request_supported(adev);
74861bb76ff1Sjsg #else
74871bb76ff1Sjsg 	eg_pi->pcie_performance_request = false;
74881bb76ff1Sjsg #endif
74891bb76ff1Sjsg 
74901bb76ff1Sjsg 	si_pi->sram_end = SMC_RAM_END;
74911bb76ff1Sjsg 
74921bb76ff1Sjsg 	adev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;
74931bb76ff1Sjsg 	adev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;
74941bb76ff1Sjsg 	adev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
74951bb76ff1Sjsg 	adev->pm.dpm.dyn_state.valid_sclk_values.count = 0;
74961bb76ff1Sjsg 	adev->pm.dpm.dyn_state.valid_sclk_values.values = NULL;
74971bb76ff1Sjsg 	adev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
74981bb76ff1Sjsg 	adev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
74991bb76ff1Sjsg 
75001bb76ff1Sjsg 	si_initialize_powertune_defaults(adev);
75011bb76ff1Sjsg 
75021bb76ff1Sjsg 	/* make sure dc limits are valid */
75031bb76ff1Sjsg 	if ((adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk == 0) ||
75041bb76ff1Sjsg 	    (adev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk == 0))
75051bb76ff1Sjsg 		adev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
75061bb76ff1Sjsg 			adev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
75071bb76ff1Sjsg 
75081bb76ff1Sjsg 	si_pi->fan_ctrl_is_in_default_mode = true;
75091bb76ff1Sjsg 
75101bb76ff1Sjsg 	return 0;
75111bb76ff1Sjsg }
75121bb76ff1Sjsg 
si_dpm_fini(struct amdgpu_device * adev)75131bb76ff1Sjsg static void si_dpm_fini(struct amdgpu_device *adev)
75141bb76ff1Sjsg {
75151bb76ff1Sjsg 	int i;
75161bb76ff1Sjsg 
75171bb76ff1Sjsg 	if (adev->pm.dpm.ps)
75181bb76ff1Sjsg 		for (i = 0; i < adev->pm.dpm.num_ps; i++)
75191bb76ff1Sjsg 			kfree(adev->pm.dpm.ps[i].ps_priv);
75201bb76ff1Sjsg 	kfree(adev->pm.dpm.ps);
75211bb76ff1Sjsg 	kfree(adev->pm.dpm.priv);
75221bb76ff1Sjsg 	kfree(adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
75231bb76ff1Sjsg 	amdgpu_free_extended_power_table(adev);
75241bb76ff1Sjsg }
75251bb76ff1Sjsg 
si_dpm_debugfs_print_current_performance_level(void * handle,struct seq_file * m)75261bb76ff1Sjsg static void si_dpm_debugfs_print_current_performance_level(void *handle,
75271bb76ff1Sjsg 						    struct seq_file *m)
75281bb76ff1Sjsg {
75291bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
75301bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
75311bb76ff1Sjsg 	struct amdgpu_ps *rps = &eg_pi->current_rps;
75321bb76ff1Sjsg 	struct  si_ps *ps = si_get_ps(rps);
75331bb76ff1Sjsg 	struct rv7xx_pl *pl;
75341bb76ff1Sjsg 	u32 current_index =
75351bb76ff1Sjsg 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
75361bb76ff1Sjsg 		CURRENT_STATE_INDEX_SHIFT;
75371bb76ff1Sjsg 
75381bb76ff1Sjsg 	if (current_index >= ps->performance_level_count) {
75391bb76ff1Sjsg 		seq_printf(m, "invalid dpm profile %d\n", current_index);
75401bb76ff1Sjsg 	} else {
75411bb76ff1Sjsg 		pl = &ps->performance_levels[current_index];
75421bb76ff1Sjsg 		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
75431bb76ff1Sjsg 		seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",
75441bb76ff1Sjsg 			   current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);
75451bb76ff1Sjsg 	}
75461bb76ff1Sjsg }
75471bb76ff1Sjsg 
si_dpm_set_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned type,enum amdgpu_interrupt_state state)75481bb76ff1Sjsg static int si_dpm_set_interrupt_state(struct amdgpu_device *adev,
75491bb76ff1Sjsg 				      struct amdgpu_irq_src *source,
75501bb76ff1Sjsg 				      unsigned type,
75511bb76ff1Sjsg 				      enum amdgpu_interrupt_state state)
75521bb76ff1Sjsg {
75531bb76ff1Sjsg 	u32 cg_thermal_int;
75541bb76ff1Sjsg 
75551bb76ff1Sjsg 	switch (type) {
75561bb76ff1Sjsg 	case AMDGPU_THERMAL_IRQ_LOW_TO_HIGH:
75571bb76ff1Sjsg 		switch (state) {
75581bb76ff1Sjsg 		case AMDGPU_IRQ_STATE_DISABLE:
75591bb76ff1Sjsg 			cg_thermal_int = RREG32_SMC(CG_THERMAL_INT);
75601bb76ff1Sjsg 			cg_thermal_int |= THERM_INT_MASK_HIGH;
75611bb76ff1Sjsg 			WREG32_SMC(CG_THERMAL_INT, cg_thermal_int);
75621bb76ff1Sjsg 			break;
75631bb76ff1Sjsg 		case AMDGPU_IRQ_STATE_ENABLE:
75641bb76ff1Sjsg 			cg_thermal_int = RREG32_SMC(CG_THERMAL_INT);
75651bb76ff1Sjsg 			cg_thermal_int &= ~THERM_INT_MASK_HIGH;
75661bb76ff1Sjsg 			WREG32_SMC(CG_THERMAL_INT, cg_thermal_int);
75671bb76ff1Sjsg 			break;
75681bb76ff1Sjsg 		default:
75691bb76ff1Sjsg 			break;
75701bb76ff1Sjsg 		}
75711bb76ff1Sjsg 		break;
75721bb76ff1Sjsg 
75731bb76ff1Sjsg 	case AMDGPU_THERMAL_IRQ_HIGH_TO_LOW:
75741bb76ff1Sjsg 		switch (state) {
75751bb76ff1Sjsg 		case AMDGPU_IRQ_STATE_DISABLE:
75761bb76ff1Sjsg 			cg_thermal_int = RREG32_SMC(CG_THERMAL_INT);
75771bb76ff1Sjsg 			cg_thermal_int |= THERM_INT_MASK_LOW;
75781bb76ff1Sjsg 			WREG32_SMC(CG_THERMAL_INT, cg_thermal_int);
75791bb76ff1Sjsg 			break;
75801bb76ff1Sjsg 		case AMDGPU_IRQ_STATE_ENABLE:
75811bb76ff1Sjsg 			cg_thermal_int = RREG32_SMC(CG_THERMAL_INT);
75821bb76ff1Sjsg 			cg_thermal_int &= ~THERM_INT_MASK_LOW;
75831bb76ff1Sjsg 			WREG32_SMC(CG_THERMAL_INT, cg_thermal_int);
75841bb76ff1Sjsg 			break;
75851bb76ff1Sjsg 		default:
75861bb76ff1Sjsg 			break;
75871bb76ff1Sjsg 		}
75881bb76ff1Sjsg 		break;
75891bb76ff1Sjsg 
75901bb76ff1Sjsg 	default:
75911bb76ff1Sjsg 		break;
75921bb76ff1Sjsg 	}
75931bb76ff1Sjsg 	return 0;
75941bb76ff1Sjsg }
75951bb76ff1Sjsg 
si_dpm_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)75961bb76ff1Sjsg static int si_dpm_process_interrupt(struct amdgpu_device *adev,
75971bb76ff1Sjsg 				    struct amdgpu_irq_src *source,
75981bb76ff1Sjsg 				    struct amdgpu_iv_entry *entry)
75991bb76ff1Sjsg {
76001bb76ff1Sjsg 	bool queue_thermal = false;
76011bb76ff1Sjsg 
76021bb76ff1Sjsg 	if (entry == NULL)
76031bb76ff1Sjsg 		return -EINVAL;
76041bb76ff1Sjsg 
76051bb76ff1Sjsg 	switch (entry->src_id) {
76061bb76ff1Sjsg 	case 230: /* thermal low to high */
76071bb76ff1Sjsg 		DRM_DEBUG("IH: thermal low to high\n");
76081bb76ff1Sjsg 		adev->pm.dpm.thermal.high_to_low = false;
76091bb76ff1Sjsg 		queue_thermal = true;
76101bb76ff1Sjsg 		break;
76111bb76ff1Sjsg 	case 231: /* thermal high to low */
76121bb76ff1Sjsg 		DRM_DEBUG("IH: thermal high to low\n");
76131bb76ff1Sjsg 		adev->pm.dpm.thermal.high_to_low = true;
76141bb76ff1Sjsg 		queue_thermal = true;
76151bb76ff1Sjsg 		break;
76161bb76ff1Sjsg 	default:
76171bb76ff1Sjsg 		break;
76181bb76ff1Sjsg 	}
76191bb76ff1Sjsg 
76201bb76ff1Sjsg 	if (queue_thermal)
76211bb76ff1Sjsg 		schedule_work(&adev->pm.dpm.thermal.work);
76221bb76ff1Sjsg 
76231bb76ff1Sjsg 	return 0;
76241bb76ff1Sjsg }
76251bb76ff1Sjsg 
si_dpm_late_init(void * handle)76261bb76ff1Sjsg static int si_dpm_late_init(void *handle)
76271bb76ff1Sjsg {
7628*e6341781Sjsg 	int ret;
7629*e6341781Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
7630*e6341781Sjsg 
7631*e6341781Sjsg 	if (!adev->pm.dpm_enabled)
7632*e6341781Sjsg 		return 0;
7633*e6341781Sjsg 
7634*e6341781Sjsg 	ret = si_set_temperature_range(adev);
7635*e6341781Sjsg 	if (ret)
7636*e6341781Sjsg 		return ret;
7637*e6341781Sjsg #if 0 //TODO ?
7638*e6341781Sjsg 	si_dpm_powergate_uvd(adev, true);
7639*e6341781Sjsg #endif
76401bb76ff1Sjsg 	return 0;
76411bb76ff1Sjsg }
76421bb76ff1Sjsg 
76431bb76ff1Sjsg /**
76441bb76ff1Sjsg  * si_dpm_init_microcode - load ucode images from disk
76451bb76ff1Sjsg  *
76461bb76ff1Sjsg  * @adev: amdgpu_device pointer
76471bb76ff1Sjsg  *
76481bb76ff1Sjsg  * Use the firmware interface to load the ucode images into
76491bb76ff1Sjsg  * the driver (not loaded into hw).
76501bb76ff1Sjsg  * Returns 0 on success, error on failure.
76511bb76ff1Sjsg  */
si_dpm_init_microcode(struct amdgpu_device * adev)76521bb76ff1Sjsg static int si_dpm_init_microcode(struct amdgpu_device *adev)
76531bb76ff1Sjsg {
76541bb76ff1Sjsg 	const char *chip_name;
76551bb76ff1Sjsg 	char fw_name[30];
76561bb76ff1Sjsg 	int err;
76571bb76ff1Sjsg 
76581bb76ff1Sjsg 	DRM_DEBUG("\n");
76591bb76ff1Sjsg 	switch (adev->asic_type) {
76601bb76ff1Sjsg 	case CHIP_TAHITI:
76611bb76ff1Sjsg 		chip_name = "tahiti";
76621bb76ff1Sjsg 		break;
76631bb76ff1Sjsg 	case CHIP_PITCAIRN:
76641bb76ff1Sjsg 		if ((adev->pdev->revision == 0x81) &&
76651bb76ff1Sjsg 		    ((adev->pdev->device == 0x6810) ||
76661bb76ff1Sjsg 		    (adev->pdev->device == 0x6811)))
76671bb76ff1Sjsg 			chip_name = "pitcairn_k";
76681bb76ff1Sjsg 		else
76691bb76ff1Sjsg 			chip_name = "pitcairn";
76701bb76ff1Sjsg 		break;
76711bb76ff1Sjsg 	case CHIP_VERDE:
76721bb76ff1Sjsg 		if (((adev->pdev->device == 0x6820) &&
76731bb76ff1Sjsg 			((adev->pdev->revision == 0x81) ||
76741bb76ff1Sjsg 			(adev->pdev->revision == 0x83))) ||
76751bb76ff1Sjsg 		    ((adev->pdev->device == 0x6821) &&
76761bb76ff1Sjsg 			((adev->pdev->revision == 0x83) ||
76771bb76ff1Sjsg 			(adev->pdev->revision == 0x87))) ||
76781bb76ff1Sjsg 		    ((adev->pdev->revision == 0x87) &&
76791bb76ff1Sjsg 			((adev->pdev->device == 0x6823) ||
76801bb76ff1Sjsg 			(adev->pdev->device == 0x682b))))
76811bb76ff1Sjsg 			chip_name = "verde_k";
76821bb76ff1Sjsg 		else
76831bb76ff1Sjsg 			chip_name = "verde";
76841bb76ff1Sjsg 		break;
76851bb76ff1Sjsg 	case CHIP_OLAND:
76861bb76ff1Sjsg 		if (((adev->pdev->revision == 0x81) &&
76871bb76ff1Sjsg 			((adev->pdev->device == 0x6600) ||
76881bb76ff1Sjsg 			(adev->pdev->device == 0x6604) ||
76891bb76ff1Sjsg 			(adev->pdev->device == 0x6605) ||
76901bb76ff1Sjsg 			(adev->pdev->device == 0x6610))) ||
76911bb76ff1Sjsg 		    ((adev->pdev->revision == 0x83) &&
76921bb76ff1Sjsg 			(adev->pdev->device == 0x6610)))
76931bb76ff1Sjsg 			chip_name = "oland_k";
76941bb76ff1Sjsg 		else
76951bb76ff1Sjsg 			chip_name = "oland";
76961bb76ff1Sjsg 		break;
76971bb76ff1Sjsg 	case CHIP_HAINAN:
76981bb76ff1Sjsg 		if (((adev->pdev->revision == 0x81) &&
76991bb76ff1Sjsg 			(adev->pdev->device == 0x6660)) ||
77001bb76ff1Sjsg 		    ((adev->pdev->revision == 0x83) &&
77011bb76ff1Sjsg 			((adev->pdev->device == 0x6660) ||
77021bb76ff1Sjsg 			(adev->pdev->device == 0x6663) ||
77031bb76ff1Sjsg 			(adev->pdev->device == 0x6665) ||
77041bb76ff1Sjsg 			 (adev->pdev->device == 0x6667))))
77051bb76ff1Sjsg 			chip_name = "hainan_k";
77061bb76ff1Sjsg 		else if ((adev->pdev->revision == 0xc3) &&
77071bb76ff1Sjsg 			 (adev->pdev->device == 0x6665))
77081bb76ff1Sjsg 			chip_name = "banks_k_2";
77091bb76ff1Sjsg 		else
77101bb76ff1Sjsg 			chip_name = "hainan";
77111bb76ff1Sjsg 		break;
77121bb76ff1Sjsg 	default: BUG();
77131bb76ff1Sjsg 	}
77141bb76ff1Sjsg 
77151bb76ff1Sjsg 	snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_smc.bin", chip_name);
7716f005ef32Sjsg 	err = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name);
77171bb76ff1Sjsg 	if (err) {
77181bb76ff1Sjsg 		DRM_ERROR("si_smc: Failed to load firmware. err = %d\"%s\"\n",
77191bb76ff1Sjsg 			  err, fw_name);
7720f005ef32Sjsg 		amdgpu_ucode_release(&adev->pm.fw);
77211bb76ff1Sjsg 	}
77221bb76ff1Sjsg 	return err;
77231bb76ff1Sjsg }
77241bb76ff1Sjsg 
si_dpm_sw_init(void * handle)77251bb76ff1Sjsg static int si_dpm_sw_init(void *handle)
77261bb76ff1Sjsg {
77271bb76ff1Sjsg 	int ret;
77281bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
77291bb76ff1Sjsg 
77301bb76ff1Sjsg 	ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 230, &adev->pm.dpm.thermal.irq);
77311bb76ff1Sjsg 	if (ret)
77321bb76ff1Sjsg 		return ret;
77331bb76ff1Sjsg 
77341bb76ff1Sjsg 	ret = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 231, &adev->pm.dpm.thermal.irq);
77351bb76ff1Sjsg 	if (ret)
77361bb76ff1Sjsg 		return ret;
77371bb76ff1Sjsg 
77381bb76ff1Sjsg 	/* default to balanced state */
77391bb76ff1Sjsg 	adev->pm.dpm.state = POWER_STATE_TYPE_BALANCED;
77401bb76ff1Sjsg 	adev->pm.dpm.user_state = POWER_STATE_TYPE_BALANCED;
77411bb76ff1Sjsg 	adev->pm.dpm.forced_level = AMD_DPM_FORCED_LEVEL_AUTO;
77421bb76ff1Sjsg 	adev->pm.default_sclk = adev->clock.default_sclk;
77431bb76ff1Sjsg 	adev->pm.default_mclk = adev->clock.default_mclk;
77441bb76ff1Sjsg 	adev->pm.current_sclk = adev->clock.default_sclk;
77451bb76ff1Sjsg 	adev->pm.current_mclk = adev->clock.default_mclk;
77461bb76ff1Sjsg 	adev->pm.int_thermal_type = THERMAL_TYPE_NONE;
77471bb76ff1Sjsg 
77481bb76ff1Sjsg 	if (amdgpu_dpm == 0)
77491bb76ff1Sjsg 		return 0;
77501bb76ff1Sjsg 
77511bb76ff1Sjsg 	ret = si_dpm_init_microcode(adev);
77521bb76ff1Sjsg 	if (ret)
77531bb76ff1Sjsg 		return ret;
77541bb76ff1Sjsg 
77551bb76ff1Sjsg 	INIT_WORK(&adev->pm.dpm.thermal.work, amdgpu_dpm_thermal_work_handler);
77561bb76ff1Sjsg 	ret = si_dpm_init(adev);
77571bb76ff1Sjsg 	if (ret)
77581bb76ff1Sjsg 		goto dpm_failed;
77591bb76ff1Sjsg 	adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
77601bb76ff1Sjsg 	if (amdgpu_dpm == 1)
77611bb76ff1Sjsg 		amdgpu_pm_print_power_states(adev);
77621bb76ff1Sjsg 	DRM_INFO("amdgpu: dpm initialized\n");
77631bb76ff1Sjsg 
77641bb76ff1Sjsg 	return 0;
77651bb76ff1Sjsg 
77661bb76ff1Sjsg dpm_failed:
77671bb76ff1Sjsg 	si_dpm_fini(adev);
77681bb76ff1Sjsg 	DRM_ERROR("amdgpu: dpm initialization failed\n");
77691bb76ff1Sjsg 	return ret;
77701bb76ff1Sjsg }
77711bb76ff1Sjsg 
si_dpm_sw_fini(void * handle)77721bb76ff1Sjsg static int si_dpm_sw_fini(void *handle)
77731bb76ff1Sjsg {
77741bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
77751bb76ff1Sjsg 
77761bb76ff1Sjsg 	flush_work(&adev->pm.dpm.thermal.work);
77771bb76ff1Sjsg 
77781bb76ff1Sjsg 	si_dpm_fini(adev);
77791bb76ff1Sjsg 
77801bb76ff1Sjsg 	return 0;
77811bb76ff1Sjsg }
77821bb76ff1Sjsg 
si_dpm_hw_init(void * handle)77831bb76ff1Sjsg static int si_dpm_hw_init(void *handle)
77841bb76ff1Sjsg {
77851bb76ff1Sjsg 	int ret;
77861bb76ff1Sjsg 
77871bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
77881bb76ff1Sjsg 
77891bb76ff1Sjsg 	if (!amdgpu_dpm)
77901bb76ff1Sjsg 		return 0;
77911bb76ff1Sjsg 
77921bb76ff1Sjsg 	si_dpm_setup_asic(adev);
77931bb76ff1Sjsg 	ret = si_dpm_enable(adev);
77941bb76ff1Sjsg 	if (ret)
77951bb76ff1Sjsg 		adev->pm.dpm_enabled = false;
77961bb76ff1Sjsg 	else
77971bb76ff1Sjsg 		adev->pm.dpm_enabled = true;
77981bb76ff1Sjsg 	amdgpu_legacy_dpm_compute_clocks(adev);
77991bb76ff1Sjsg 	return ret;
78001bb76ff1Sjsg }
78011bb76ff1Sjsg 
si_dpm_hw_fini(void * handle)78021bb76ff1Sjsg static int si_dpm_hw_fini(void *handle)
78031bb76ff1Sjsg {
78041bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
78051bb76ff1Sjsg 
78061bb76ff1Sjsg 	if (adev->pm.dpm_enabled)
78071bb76ff1Sjsg 		si_dpm_disable(adev);
78081bb76ff1Sjsg 
78091bb76ff1Sjsg 	return 0;
78101bb76ff1Sjsg }
78111bb76ff1Sjsg 
si_dpm_suspend(void * handle)78121bb76ff1Sjsg static int si_dpm_suspend(void *handle)
78131bb76ff1Sjsg {
78141bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
78151bb76ff1Sjsg 
78161bb76ff1Sjsg 	if (adev->pm.dpm_enabled) {
78171bb76ff1Sjsg 		/* disable dpm */
78181bb76ff1Sjsg 		si_dpm_disable(adev);
78191bb76ff1Sjsg 		/* reset the power state */
78201bb76ff1Sjsg 		adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
78211bb76ff1Sjsg 	}
78221bb76ff1Sjsg 	return 0;
78231bb76ff1Sjsg }
78241bb76ff1Sjsg 
si_dpm_resume(void * handle)78251bb76ff1Sjsg static int si_dpm_resume(void *handle)
78261bb76ff1Sjsg {
78271bb76ff1Sjsg 	int ret;
78281bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
78291bb76ff1Sjsg 
78301bb76ff1Sjsg 	if (adev->pm.dpm_enabled) {
78311bb76ff1Sjsg 		/* asic init will reset to the boot state */
78321bb76ff1Sjsg 		si_dpm_setup_asic(adev);
78331bb76ff1Sjsg 		ret = si_dpm_enable(adev);
78341bb76ff1Sjsg 		if (ret)
78351bb76ff1Sjsg 			adev->pm.dpm_enabled = false;
78361bb76ff1Sjsg 		else
78371bb76ff1Sjsg 			adev->pm.dpm_enabled = true;
78381bb76ff1Sjsg 		if (adev->pm.dpm_enabled)
78391bb76ff1Sjsg 			amdgpu_legacy_dpm_compute_clocks(adev);
78401bb76ff1Sjsg 	}
78411bb76ff1Sjsg 	return 0;
78421bb76ff1Sjsg }
78431bb76ff1Sjsg 
si_dpm_is_idle(void * handle)78441bb76ff1Sjsg static bool si_dpm_is_idle(void *handle)
78451bb76ff1Sjsg {
78461bb76ff1Sjsg 	/* XXX */
78471bb76ff1Sjsg 	return true;
78481bb76ff1Sjsg }
78491bb76ff1Sjsg 
si_dpm_wait_for_idle(void * handle)78501bb76ff1Sjsg static int si_dpm_wait_for_idle(void *handle)
78511bb76ff1Sjsg {
78521bb76ff1Sjsg 	/* XXX */
78531bb76ff1Sjsg 	return 0;
78541bb76ff1Sjsg }
78551bb76ff1Sjsg 
si_dpm_soft_reset(void * handle)78561bb76ff1Sjsg static int si_dpm_soft_reset(void *handle)
78571bb76ff1Sjsg {
78581bb76ff1Sjsg 	return 0;
78591bb76ff1Sjsg }
78601bb76ff1Sjsg 
si_dpm_set_clockgating_state(void * handle,enum amd_clockgating_state state)78611bb76ff1Sjsg static int si_dpm_set_clockgating_state(void *handle,
78621bb76ff1Sjsg 					enum amd_clockgating_state state)
78631bb76ff1Sjsg {
78641bb76ff1Sjsg 	return 0;
78651bb76ff1Sjsg }
78661bb76ff1Sjsg 
si_dpm_set_powergating_state(void * handle,enum amd_powergating_state state)78671bb76ff1Sjsg static int si_dpm_set_powergating_state(void *handle,
78681bb76ff1Sjsg 					enum amd_powergating_state state)
78691bb76ff1Sjsg {
78701bb76ff1Sjsg 	return 0;
78711bb76ff1Sjsg }
78721bb76ff1Sjsg 
78731bb76ff1Sjsg /* get temperature in millidegrees */
si_dpm_get_temp(void * handle)78741bb76ff1Sjsg static int si_dpm_get_temp(void *handle)
78751bb76ff1Sjsg {
78761bb76ff1Sjsg 	u32 temp;
78771bb76ff1Sjsg 	int actual_temp = 0;
78781bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
78791bb76ff1Sjsg 
78801bb76ff1Sjsg 	temp = (RREG32(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >>
78811bb76ff1Sjsg 		CTF_TEMP_SHIFT;
78821bb76ff1Sjsg 
78831bb76ff1Sjsg 	if (temp & 0x200)
78841bb76ff1Sjsg 		actual_temp = 255;
78851bb76ff1Sjsg 	else
78861bb76ff1Sjsg 		actual_temp = temp & 0x1ff;
78871bb76ff1Sjsg 
78881bb76ff1Sjsg 	actual_temp = (actual_temp * 1000);
78891bb76ff1Sjsg 
78901bb76ff1Sjsg 	return actual_temp;
78911bb76ff1Sjsg }
78921bb76ff1Sjsg 
si_dpm_get_sclk(void * handle,bool low)78931bb76ff1Sjsg static u32 si_dpm_get_sclk(void *handle, bool low)
78941bb76ff1Sjsg {
78951bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
78961bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
78971bb76ff1Sjsg 	struct  si_ps *requested_state = si_get_ps(&eg_pi->requested_rps);
78981bb76ff1Sjsg 
78991bb76ff1Sjsg 	if (low)
79001bb76ff1Sjsg 		return requested_state->performance_levels[0].sclk;
79011bb76ff1Sjsg 	else
79021bb76ff1Sjsg 		return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk;
79031bb76ff1Sjsg }
79041bb76ff1Sjsg 
si_dpm_get_mclk(void * handle,bool low)79051bb76ff1Sjsg static u32 si_dpm_get_mclk(void *handle, bool low)
79061bb76ff1Sjsg {
79071bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
79081bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
79091bb76ff1Sjsg 	struct  si_ps *requested_state = si_get_ps(&eg_pi->requested_rps);
79101bb76ff1Sjsg 
79111bb76ff1Sjsg 	if (low)
79121bb76ff1Sjsg 		return requested_state->performance_levels[0].mclk;
79131bb76ff1Sjsg 	else
79141bb76ff1Sjsg 		return requested_state->performance_levels[requested_state->performance_level_count - 1].mclk;
79151bb76ff1Sjsg }
79161bb76ff1Sjsg 
si_dpm_print_power_state(void * handle,void * current_ps)79171bb76ff1Sjsg static void si_dpm_print_power_state(void *handle,
79181bb76ff1Sjsg 				     void *current_ps)
79191bb76ff1Sjsg {
79201bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
79211bb76ff1Sjsg 	struct amdgpu_ps *rps = (struct amdgpu_ps *)current_ps;
79221bb76ff1Sjsg 	struct  si_ps *ps = si_get_ps(rps);
79231bb76ff1Sjsg 	struct rv7xx_pl *pl;
79241bb76ff1Sjsg 	int i;
79251bb76ff1Sjsg 
79261bb76ff1Sjsg 	amdgpu_dpm_print_class_info(rps->class, rps->class2);
79271bb76ff1Sjsg 	amdgpu_dpm_print_cap_info(rps->caps);
79281bb76ff1Sjsg 	DRM_INFO("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
79291bb76ff1Sjsg 	for (i = 0; i < ps->performance_level_count; i++) {
79301bb76ff1Sjsg 		pl = &ps->performance_levels[i];
79311bb76ff1Sjsg 		if (adev->asic_type >= CHIP_TAHITI)
79321bb76ff1Sjsg 			DRM_INFO("\t\tpower level %d    sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",
79331bb76ff1Sjsg 				 i, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);
79341bb76ff1Sjsg 		else
79351bb76ff1Sjsg 			DRM_INFO("\t\tpower level %d    sclk: %u mclk: %u vddc: %u vddci: %u\n",
79361bb76ff1Sjsg 				 i, pl->sclk, pl->mclk, pl->vddc, pl->vddci);
79371bb76ff1Sjsg 	}
79381bb76ff1Sjsg 	amdgpu_dpm_print_ps_status(adev, rps);
79391bb76ff1Sjsg }
79401bb76ff1Sjsg 
si_dpm_early_init(void * handle)79411bb76ff1Sjsg static int si_dpm_early_init(void *handle)
79421bb76ff1Sjsg {
79431bb76ff1Sjsg 
79441bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
79451bb76ff1Sjsg 
79461bb76ff1Sjsg 	adev->powerplay.pp_funcs = &si_dpm_funcs;
79471bb76ff1Sjsg 	adev->powerplay.pp_handle = adev;
79481bb76ff1Sjsg 	si_dpm_set_irq_funcs(adev);
79491bb76ff1Sjsg 	return 0;
79501bb76ff1Sjsg }
79511bb76ff1Sjsg 
si_are_power_levels_equal(const struct rv7xx_pl * si_cpl1,const struct rv7xx_pl * si_cpl2)79521bb76ff1Sjsg static inline bool si_are_power_levels_equal(const struct rv7xx_pl  *si_cpl1,
79531bb76ff1Sjsg 						const struct rv7xx_pl *si_cpl2)
79541bb76ff1Sjsg {
79551bb76ff1Sjsg 	return ((si_cpl1->mclk == si_cpl2->mclk) &&
79561bb76ff1Sjsg 		  (si_cpl1->sclk == si_cpl2->sclk) &&
79571bb76ff1Sjsg 		  (si_cpl1->pcie_gen == si_cpl2->pcie_gen) &&
79581bb76ff1Sjsg 		  (si_cpl1->vddc == si_cpl2->vddc) &&
79591bb76ff1Sjsg 		  (si_cpl1->vddci == si_cpl2->vddci));
79601bb76ff1Sjsg }
79611bb76ff1Sjsg 
si_check_state_equal(void * handle,void * current_ps,void * request_ps,bool * equal)79621bb76ff1Sjsg static int si_check_state_equal(void *handle,
79631bb76ff1Sjsg 				void *current_ps,
79641bb76ff1Sjsg 				void *request_ps,
79651bb76ff1Sjsg 				bool *equal)
79661bb76ff1Sjsg {
79671bb76ff1Sjsg 	struct si_ps *si_cps;
79681bb76ff1Sjsg 	struct si_ps *si_rps;
79691bb76ff1Sjsg 	int i;
79701bb76ff1Sjsg 	struct amdgpu_ps *cps = (struct amdgpu_ps *)current_ps;
79711bb76ff1Sjsg 	struct amdgpu_ps *rps = (struct amdgpu_ps *)request_ps;
79721bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
79731bb76ff1Sjsg 
79741bb76ff1Sjsg 	if (adev == NULL || cps == NULL || rps == NULL || equal == NULL)
79751bb76ff1Sjsg 		return -EINVAL;
79761bb76ff1Sjsg 
79771bb76ff1Sjsg 	si_cps = si_get_ps((struct amdgpu_ps *)cps);
79781bb76ff1Sjsg 	si_rps = si_get_ps((struct amdgpu_ps *)rps);
79791bb76ff1Sjsg 
79801bb76ff1Sjsg 	if (si_cps == NULL) {
79811bb76ff1Sjsg 		printk("si_cps is NULL\n");
79821bb76ff1Sjsg 		*equal = false;
79831bb76ff1Sjsg 		return 0;
79841bb76ff1Sjsg 	}
79851bb76ff1Sjsg 
79861bb76ff1Sjsg 	if (si_cps->performance_level_count != si_rps->performance_level_count) {
79871bb76ff1Sjsg 		*equal = false;
79881bb76ff1Sjsg 		return 0;
79891bb76ff1Sjsg 	}
79901bb76ff1Sjsg 
79911bb76ff1Sjsg 	for (i = 0; i < si_cps->performance_level_count; i++) {
79921bb76ff1Sjsg 		if (!si_are_power_levels_equal(&(si_cps->performance_levels[i]),
79931bb76ff1Sjsg 					&(si_rps->performance_levels[i]))) {
79941bb76ff1Sjsg 			*equal = false;
79951bb76ff1Sjsg 			return 0;
79961bb76ff1Sjsg 		}
79971bb76ff1Sjsg 	}
79981bb76ff1Sjsg 
79991bb76ff1Sjsg 	/* If all performance levels are the same try to use the UVD clocks to break the tie.*/
80001bb76ff1Sjsg 	*equal = ((cps->vclk == rps->vclk) && (cps->dclk == rps->dclk));
80011bb76ff1Sjsg 	*equal &= ((cps->evclk == rps->evclk) && (cps->ecclk == rps->ecclk));
80021bb76ff1Sjsg 
80031bb76ff1Sjsg 	return 0;
80041bb76ff1Sjsg }
80051bb76ff1Sjsg 
si_dpm_read_sensor(void * handle,int idx,void * value,int * size)80061bb76ff1Sjsg static int si_dpm_read_sensor(void *handle, int idx,
80071bb76ff1Sjsg 			      void *value, int *size)
80081bb76ff1Sjsg {
80091bb76ff1Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
80101bb76ff1Sjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(adev);
80111bb76ff1Sjsg 	struct amdgpu_ps *rps = &eg_pi->current_rps;
80121bb76ff1Sjsg 	struct  si_ps *ps = si_get_ps(rps);
80131bb76ff1Sjsg 	uint32_t sclk, mclk;
80141bb76ff1Sjsg 	u32 pl_index =
80151bb76ff1Sjsg 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
80161bb76ff1Sjsg 		CURRENT_STATE_INDEX_SHIFT;
80171bb76ff1Sjsg 
80181bb76ff1Sjsg 	/* size must be at least 4 bytes for all sensors */
80191bb76ff1Sjsg 	if (*size < 4)
80201bb76ff1Sjsg 		return -EINVAL;
80211bb76ff1Sjsg 
80221bb76ff1Sjsg 	switch (idx) {
80231bb76ff1Sjsg 	case AMDGPU_PP_SENSOR_GFX_SCLK:
80241bb76ff1Sjsg 		if (pl_index < ps->performance_level_count) {
80251bb76ff1Sjsg 			sclk = ps->performance_levels[pl_index].sclk;
80261bb76ff1Sjsg 			*((uint32_t *)value) = sclk;
80271bb76ff1Sjsg 			*size = 4;
80281bb76ff1Sjsg 			return 0;
80291bb76ff1Sjsg 		}
80301bb76ff1Sjsg 		return -EINVAL;
80311bb76ff1Sjsg 	case AMDGPU_PP_SENSOR_GFX_MCLK:
80321bb76ff1Sjsg 		if (pl_index < ps->performance_level_count) {
80331bb76ff1Sjsg 			mclk = ps->performance_levels[pl_index].mclk;
80341bb76ff1Sjsg 			*((uint32_t *)value) = mclk;
80351bb76ff1Sjsg 			*size = 4;
80361bb76ff1Sjsg 			return 0;
80371bb76ff1Sjsg 		}
80381bb76ff1Sjsg 		return -EINVAL;
80391bb76ff1Sjsg 	case AMDGPU_PP_SENSOR_GPU_TEMP:
80401bb76ff1Sjsg 		*((uint32_t *)value) = si_dpm_get_temp(adev);
80411bb76ff1Sjsg 		*size = 4;
80421bb76ff1Sjsg 		return 0;
80431bb76ff1Sjsg 	default:
80441bb76ff1Sjsg 		return -EOPNOTSUPP;
80451bb76ff1Sjsg 	}
80461bb76ff1Sjsg }
80471bb76ff1Sjsg 
80481bb76ff1Sjsg static const struct amd_ip_funcs si_dpm_ip_funcs = {
80491bb76ff1Sjsg 	.name = "si_dpm",
80501bb76ff1Sjsg 	.early_init = si_dpm_early_init,
80511bb76ff1Sjsg 	.late_init = si_dpm_late_init,
80521bb76ff1Sjsg 	.sw_init = si_dpm_sw_init,
80531bb76ff1Sjsg 	.sw_fini = si_dpm_sw_fini,
80541bb76ff1Sjsg 	.hw_init = si_dpm_hw_init,
80551bb76ff1Sjsg 	.hw_fini = si_dpm_hw_fini,
80561bb76ff1Sjsg 	.suspend = si_dpm_suspend,
80571bb76ff1Sjsg 	.resume = si_dpm_resume,
80581bb76ff1Sjsg 	.is_idle = si_dpm_is_idle,
80591bb76ff1Sjsg 	.wait_for_idle = si_dpm_wait_for_idle,
80601bb76ff1Sjsg 	.soft_reset = si_dpm_soft_reset,
80611bb76ff1Sjsg 	.set_clockgating_state = si_dpm_set_clockgating_state,
80621bb76ff1Sjsg 	.set_powergating_state = si_dpm_set_powergating_state,
80631bb76ff1Sjsg };
80641bb76ff1Sjsg 
80651bb76ff1Sjsg const struct amdgpu_ip_block_version si_smu_ip_block =
80661bb76ff1Sjsg {
80671bb76ff1Sjsg 	.type = AMD_IP_BLOCK_TYPE_SMC,
80681bb76ff1Sjsg 	.major = 6,
80691bb76ff1Sjsg 	.minor = 0,
80701bb76ff1Sjsg 	.rev = 0,
80711bb76ff1Sjsg 	.funcs = &si_dpm_ip_funcs,
80721bb76ff1Sjsg };
80731bb76ff1Sjsg 
80741bb76ff1Sjsg static const struct amd_pm_funcs si_dpm_funcs = {
80751bb76ff1Sjsg 	.pre_set_power_state = &si_dpm_pre_set_power_state,
80761bb76ff1Sjsg 	.set_power_state = &si_dpm_set_power_state,
80771bb76ff1Sjsg 	.post_set_power_state = &si_dpm_post_set_power_state,
80781bb76ff1Sjsg 	.display_configuration_changed = &si_dpm_display_configuration_changed,
80791bb76ff1Sjsg 	.get_sclk = &si_dpm_get_sclk,
80801bb76ff1Sjsg 	.get_mclk = &si_dpm_get_mclk,
80811bb76ff1Sjsg 	.print_power_state = &si_dpm_print_power_state,
80821bb76ff1Sjsg 	.debugfs_print_current_performance_level = &si_dpm_debugfs_print_current_performance_level,
80831bb76ff1Sjsg 	.force_performance_level = &si_dpm_force_performance_level,
80841bb76ff1Sjsg 	.vblank_too_short = &si_dpm_vblank_too_short,
80851bb76ff1Sjsg 	.set_fan_control_mode = &si_dpm_set_fan_control_mode,
80861bb76ff1Sjsg 	.get_fan_control_mode = &si_dpm_get_fan_control_mode,
80871bb76ff1Sjsg 	.set_fan_speed_pwm = &si_dpm_set_fan_speed_pwm,
80881bb76ff1Sjsg 	.get_fan_speed_pwm = &si_dpm_get_fan_speed_pwm,
80891bb76ff1Sjsg 	.check_state_equal = &si_check_state_equal,
80901bb76ff1Sjsg 	.get_vce_clock_state = amdgpu_get_vce_clock_state,
80911bb76ff1Sjsg 	.read_sensor = &si_dpm_read_sensor,
80921bb76ff1Sjsg 	.pm_compute_clocks = amdgpu_legacy_dpm_compute_clocks,
80931bb76ff1Sjsg };
80941bb76ff1Sjsg 
80951bb76ff1Sjsg static const struct amdgpu_irq_src_funcs si_dpm_irq_funcs = {
80961bb76ff1Sjsg 	.set = si_dpm_set_interrupt_state,
80971bb76ff1Sjsg 	.process = si_dpm_process_interrupt,
80981bb76ff1Sjsg };
80991bb76ff1Sjsg 
si_dpm_set_irq_funcs(struct amdgpu_device * adev)81001bb76ff1Sjsg static void si_dpm_set_irq_funcs(struct amdgpu_device *adev)
81011bb76ff1Sjsg {
81021bb76ff1Sjsg 	adev->pm.dpm.thermal.irq.num_types = AMDGPU_THERMAL_IRQ_LAST;
81031bb76ff1Sjsg 	adev->pm.dpm.thermal.irq.funcs = &si_dpm_irq_funcs;
81041bb76ff1Sjsg }
81051bb76ff1Sjsg 
8106