xref: /openbsd-src/sys/dev/pci/drm/radeon/si_dpm.c (revision 1bb76ff151c0aba8e3312a604e4cd2e5195cf4b7)
17ccd5a2cSjsg /*
27ccd5a2cSjsg  * Copyright 2013 Advanced Micro Devices, Inc.
37ccd5a2cSjsg  *
47ccd5a2cSjsg  * Permission is hereby granted, free of charge, to any person obtaining a
57ccd5a2cSjsg  * copy of this software and associated documentation files (the "Software"),
67ccd5a2cSjsg  * to deal in the Software without restriction, including without limitation
77ccd5a2cSjsg  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ccd5a2cSjsg  * and/or sell copies of the Software, and to permit persons to whom the
97ccd5a2cSjsg  * Software is furnished to do so, subject to the following conditions:
107ccd5a2cSjsg  *
117ccd5a2cSjsg  * The above copyright notice and this permission notice shall be included in
127ccd5a2cSjsg  * all copies or substantial portions of the Software.
137ccd5a2cSjsg  *
147ccd5a2cSjsg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
157ccd5a2cSjsg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
167ccd5a2cSjsg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
177ccd5a2cSjsg  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
187ccd5a2cSjsg  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
197ccd5a2cSjsg  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
207ccd5a2cSjsg  * OTHER DEALINGS IN THE SOFTWARE.
217ccd5a2cSjsg  *
227ccd5a2cSjsg  */
237ccd5a2cSjsg 
24c349dbc7Sjsg #include <linux/math64.h>
25c349dbc7Sjsg #include <linux/pci.h>
26c349dbc7Sjsg #include <linux/seq_file.h>
27c349dbc7Sjsg 
28c349dbc7Sjsg #include "atom.h"
295ca02815Sjsg #include "evergreen.h"
30c349dbc7Sjsg #include "r600_dpm.h"
315ca02815Sjsg #include "rv770.h"
327ccd5a2cSjsg #include "radeon.h"
337ccd5a2cSjsg #include "radeon_asic.h"
345ca02815Sjsg #include "ni_dpm.h"
357ccd5a2cSjsg #include "si_dpm.h"
365ca02815Sjsg #include "si.h"
37c349dbc7Sjsg #include "sid.h"
385ca02815Sjsg #include "vce.h"
397ccd5a2cSjsg 
407ccd5a2cSjsg #define MC_CG_ARB_FREQ_F0           0x0a
417ccd5a2cSjsg #define MC_CG_ARB_FREQ_F1           0x0b
427ccd5a2cSjsg #define MC_CG_ARB_FREQ_F2           0x0c
437ccd5a2cSjsg #define MC_CG_ARB_FREQ_F3           0x0d
447ccd5a2cSjsg 
457ccd5a2cSjsg #define SMC_RAM_END                 0x20000
467ccd5a2cSjsg 
477ccd5a2cSjsg #define SCLK_MIN_DEEPSLEEP_FREQ     1350
487ccd5a2cSjsg 
497ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_tahiti[] =
507ccd5a2cSjsg {
517ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0xc, SISLANDS_CACCONFIG_CGIND },
527ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
537ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0x101, SISLANDS_CACCONFIG_CGIND },
547ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0xc, SISLANDS_CACCONFIG_CGIND },
557ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
567ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
577ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
587ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
597ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
607ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x8fc, SISLANDS_CACCONFIG_CGIND },
617ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
627ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x95, SISLANDS_CACCONFIG_CGIND },
637ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x34e, SISLANDS_CACCONFIG_CGIND },
647ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x1a1, SISLANDS_CACCONFIG_CGIND },
657ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0xda, SISLANDS_CACCONFIG_CGIND },
667ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
677ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
687ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x46, SISLANDS_CACCONFIG_CGIND },
697ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
707ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x208, SISLANDS_CACCONFIG_CGIND },
717ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0xe7, SISLANDS_CACCONFIG_CGIND },
727ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x948, SISLANDS_CACCONFIG_CGIND },
737ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
747ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
757ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
767ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
777ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
787ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
797ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
807ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
817ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x167, SISLANDS_CACCONFIG_CGIND },
827ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
837ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
847ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
857ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
867ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
877ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
887ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
897ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
907ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x31, SISLANDS_CACCONFIG_CGIND },
917ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
927ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
937ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
947ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
957ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
967ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
977ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
987ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
997ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1007ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1017ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1027ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1037ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1047ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1057ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1067ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1077ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1087ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
1097ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
1107ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0x18e, SISLANDS_CACCONFIG_CGIND },
1117ccd5a2cSjsg 	{ 0xFFFFFFFF }
1127ccd5a2cSjsg };
1137ccd5a2cSjsg 
1147ccd5a2cSjsg static const struct si_cac_config_reg lcac_tahiti[] =
1157ccd5a2cSjsg {
1167ccd5a2cSjsg 	{ 0x143, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
1177ccd5a2cSjsg 	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1187ccd5a2cSjsg 	{ 0x146, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
1197ccd5a2cSjsg 	{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1207ccd5a2cSjsg 	{ 0x149, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
1217ccd5a2cSjsg 	{ 0x149, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1227ccd5a2cSjsg 	{ 0x14c, 0x0001fffe, 1, 0x3, SISLANDS_CACCONFIG_CGIND },
1237ccd5a2cSjsg 	{ 0x14c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1247ccd5a2cSjsg 	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1257ccd5a2cSjsg 	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1267ccd5a2cSjsg 	{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1277ccd5a2cSjsg 	{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1287ccd5a2cSjsg 	{ 0x9e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1297ccd5a2cSjsg 	{ 0x9e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1307ccd5a2cSjsg 	{ 0x101, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1317ccd5a2cSjsg 	{ 0x101, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1327ccd5a2cSjsg 	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1337ccd5a2cSjsg 	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1347ccd5a2cSjsg 	{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1357ccd5a2cSjsg 	{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1367ccd5a2cSjsg 	{ 0x10a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1377ccd5a2cSjsg 	{ 0x10a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1387ccd5a2cSjsg 	{ 0x10d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1397ccd5a2cSjsg 	{ 0x10d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1407ccd5a2cSjsg 	{ 0x8c, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1417ccd5a2cSjsg 	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1427ccd5a2cSjsg 	{ 0x8f, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1437ccd5a2cSjsg 	{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1447ccd5a2cSjsg 	{ 0x92, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1457ccd5a2cSjsg 	{ 0x92, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1467ccd5a2cSjsg 	{ 0x95, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1477ccd5a2cSjsg 	{ 0x95, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1487ccd5a2cSjsg 	{ 0x14f, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1497ccd5a2cSjsg 	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1507ccd5a2cSjsg 	{ 0x152, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1517ccd5a2cSjsg 	{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1527ccd5a2cSjsg 	{ 0x155, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1537ccd5a2cSjsg 	{ 0x155, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1547ccd5a2cSjsg 	{ 0x158, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1557ccd5a2cSjsg 	{ 0x158, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1567ccd5a2cSjsg 	{ 0x110, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1577ccd5a2cSjsg 	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1587ccd5a2cSjsg 	{ 0x113, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1597ccd5a2cSjsg 	{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1607ccd5a2cSjsg 	{ 0x116, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1617ccd5a2cSjsg 	{ 0x116, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1627ccd5a2cSjsg 	{ 0x119, 0x0001fffe, 1, 0x8, SISLANDS_CACCONFIG_CGIND },
1637ccd5a2cSjsg 	{ 0x119, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1647ccd5a2cSjsg 	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1657ccd5a2cSjsg 	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1667ccd5a2cSjsg 	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1677ccd5a2cSjsg 	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1687ccd5a2cSjsg 	{ 0x122, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1697ccd5a2cSjsg 	{ 0x122, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1707ccd5a2cSjsg 	{ 0x125, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1717ccd5a2cSjsg 	{ 0x125, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1727ccd5a2cSjsg 	{ 0x128, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1737ccd5a2cSjsg 	{ 0x128, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1747ccd5a2cSjsg 	{ 0x12b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1757ccd5a2cSjsg 	{ 0x12b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1767ccd5a2cSjsg 	{ 0x15b, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
1777ccd5a2cSjsg 	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1787ccd5a2cSjsg 	{ 0x15e, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
1797ccd5a2cSjsg 	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1807ccd5a2cSjsg 	{ 0x161, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
1817ccd5a2cSjsg 	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1827ccd5a2cSjsg 	{ 0x164, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
1837ccd5a2cSjsg 	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1847ccd5a2cSjsg 	{ 0x167, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
1857ccd5a2cSjsg 	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1867ccd5a2cSjsg 	{ 0x16a, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
1877ccd5a2cSjsg 	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1887ccd5a2cSjsg 	{ 0x16d, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
1897ccd5a2cSjsg 	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1907ccd5a2cSjsg 	{ 0x170, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1917ccd5a2cSjsg 	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1927ccd5a2cSjsg 	{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1937ccd5a2cSjsg 	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1947ccd5a2cSjsg 	{ 0x176, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1957ccd5a2cSjsg 	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1967ccd5a2cSjsg 	{ 0x179, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1977ccd5a2cSjsg 	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
1987ccd5a2cSjsg 	{ 0x17c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
1997ccd5a2cSjsg 	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2007ccd5a2cSjsg 	{ 0x17f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
2017ccd5a2cSjsg 	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
2027ccd5a2cSjsg 	{ 0xFFFFFFFF }
2037ccd5a2cSjsg 
2047ccd5a2cSjsg };
2057ccd5a2cSjsg 
2067ccd5a2cSjsg static const struct si_cac_config_reg cac_override_tahiti[] =
2077ccd5a2cSjsg {
2087ccd5a2cSjsg 	{ 0xFFFFFFFF }
2097ccd5a2cSjsg };
2107ccd5a2cSjsg 
2117ccd5a2cSjsg static const struct si_powertune_data powertune_data_tahiti =
2127ccd5a2cSjsg {
2137ccd5a2cSjsg 	((1 << 16) | 27027),
2147ccd5a2cSjsg 	6,
2157ccd5a2cSjsg 	0,
2167ccd5a2cSjsg 	4,
2177ccd5a2cSjsg 	95,
2187ccd5a2cSjsg 	{
2197ccd5a2cSjsg 		0UL,
2207ccd5a2cSjsg 		0UL,
2217ccd5a2cSjsg 		4521550UL,
2227ccd5a2cSjsg 		309631529UL,
2237ccd5a2cSjsg 		-1270850L,
2247ccd5a2cSjsg 		4513710L,
2257ccd5a2cSjsg 		40
2267ccd5a2cSjsg 	},
2277ccd5a2cSjsg 	595000000UL,
2287ccd5a2cSjsg 	12,
2297ccd5a2cSjsg 	{
2307ccd5a2cSjsg 		0,
2317ccd5a2cSjsg 		0,
2327ccd5a2cSjsg 		0,
2337ccd5a2cSjsg 		0,
2347ccd5a2cSjsg 		0,
2357ccd5a2cSjsg 		0,
2367ccd5a2cSjsg 		0,
2377ccd5a2cSjsg 		0
2387ccd5a2cSjsg 	},
2397ccd5a2cSjsg 	true
2407ccd5a2cSjsg };
2417ccd5a2cSjsg 
2427ccd5a2cSjsg static const struct si_dte_data dte_data_tahiti =
2437ccd5a2cSjsg {
2447ccd5a2cSjsg 	{ 1159409, 0, 0, 0, 0 },
2457ccd5a2cSjsg 	{ 777, 0, 0, 0, 0 },
2467ccd5a2cSjsg 	2,
2477ccd5a2cSjsg 	54000,
2487ccd5a2cSjsg 	127000,
2497ccd5a2cSjsg 	25,
2507ccd5a2cSjsg 	2,
2517ccd5a2cSjsg 	10,
2527ccd5a2cSjsg 	13,
2537ccd5a2cSjsg 	{ 27, 31, 35, 39, 43, 47, 54, 61, 67, 74, 81, 88, 95, 0, 0, 0 },
2547ccd5a2cSjsg 	{ 240888759, 221057860, 235370597, 162287531, 158510299, 131423027, 116673180, 103067515, 87941937, 76209048, 68209175, 64090048, 58301890, 0, 0, 0 },
2557ccd5a2cSjsg 	{ 12024, 11189, 11451, 8411, 7939, 6666, 5681, 4905, 4241, 3720, 3354, 3122, 2890, 0, 0, 0 },
2567ccd5a2cSjsg 	85,
2577ccd5a2cSjsg 	false
2587ccd5a2cSjsg };
2597ccd5a2cSjsg 
2607ccd5a2cSjsg static const struct si_dte_data dte_data_tahiti_pro =
2617ccd5a2cSjsg {
2627ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
2637ccd5a2cSjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
2647ccd5a2cSjsg 	5,
2657ccd5a2cSjsg 	45000,
2667ccd5a2cSjsg 	100,
2677ccd5a2cSjsg 	0xA,
2687ccd5a2cSjsg 	1,
2697ccd5a2cSjsg 	0,
2707ccd5a2cSjsg 	0x10,
2717ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
2727ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
2737ccd5a2cSjsg 	{ 0x7D0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
2747ccd5a2cSjsg 	90,
2757ccd5a2cSjsg 	true
2767ccd5a2cSjsg };
2777ccd5a2cSjsg 
2787ccd5a2cSjsg static const struct si_dte_data dte_data_new_zealand =
2797ccd5a2cSjsg {
2807ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0 },
2817ccd5a2cSjsg 	{ 0x29B, 0x3E9, 0x537, 0x7D2, 0 },
2827ccd5a2cSjsg 	0x5,
2837ccd5a2cSjsg 	0xAFC8,
2847ccd5a2cSjsg 	0x69,
2857ccd5a2cSjsg 	0x32,
2867ccd5a2cSjsg 	1,
2877ccd5a2cSjsg 	0,
2887ccd5a2cSjsg 	0x10,
2897ccd5a2cSjsg 	{ 0x82, 0xA0, 0xB4, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
2907ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
2917ccd5a2cSjsg 	{ 0xDAC, 0x1388, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685, 0x685 },
2927ccd5a2cSjsg 	85,
2937ccd5a2cSjsg 	true
2947ccd5a2cSjsg };
2957ccd5a2cSjsg 
2967ccd5a2cSjsg static const struct si_dte_data dte_data_aruba_pro =
2977ccd5a2cSjsg {
2987ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
2997ccd5a2cSjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
3007ccd5a2cSjsg 	5,
3017ccd5a2cSjsg 	45000,
3027ccd5a2cSjsg 	100,
3037ccd5a2cSjsg 	0xA,
3047ccd5a2cSjsg 	1,
3057ccd5a2cSjsg 	0,
3067ccd5a2cSjsg 	0x10,
3077ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
3087ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
3097ccd5a2cSjsg 	{ 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
3107ccd5a2cSjsg 	90,
3117ccd5a2cSjsg 	true
3127ccd5a2cSjsg };
3137ccd5a2cSjsg 
3147ccd5a2cSjsg static const struct si_dte_data dte_data_malta =
3157ccd5a2cSjsg {
3167ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
3177ccd5a2cSjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
3187ccd5a2cSjsg 	5,
3197ccd5a2cSjsg 	45000,
3207ccd5a2cSjsg 	100,
3217ccd5a2cSjsg 	0xA,
3227ccd5a2cSjsg 	1,
3237ccd5a2cSjsg 	0,
3247ccd5a2cSjsg 	0x10,
3257ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
3267ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
3277ccd5a2cSjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
3287ccd5a2cSjsg 	90,
3297ccd5a2cSjsg 	true
3307ccd5a2cSjsg };
3317ccd5a2cSjsg 
332*1bb76ff1Sjsg static struct si_cac_config_reg cac_weights_pitcairn[] =
3337ccd5a2cSjsg {
3347ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x8a, SISLANDS_CACCONFIG_CGIND },
3357ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3367ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3377ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x24d, SISLANDS_CACCONFIG_CGIND },
3387ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x19, SISLANDS_CACCONFIG_CGIND },
3397ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
3407ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3417ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
3427ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3437ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0xc11, SISLANDS_CACCONFIG_CGIND },
3447ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0x7f3, SISLANDS_CACCONFIG_CGIND },
3457ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x403, SISLANDS_CACCONFIG_CGIND },
3467ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x367, SISLANDS_CACCONFIG_CGIND },
3477ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x4c9, SISLANDS_CACCONFIG_CGIND },
3487ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3497ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3507ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3517ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x45d, SISLANDS_CACCONFIG_CGIND },
3527ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0x36d, SISLANDS_CACCONFIG_CGIND },
3537ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x534, SISLANDS_CACCONFIG_CGIND },
3547ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x5da, SISLANDS_CACCONFIG_CGIND },
3557ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x880, SISLANDS_CACCONFIG_CGIND },
3567ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0x201, SISLANDS_CACCONFIG_CGIND },
3577ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3587ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3597ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0x9f, SISLANDS_CACCONFIG_CGIND },
3607ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x1f, SISLANDS_CACCONFIG_CGIND },
3617ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3627ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3637ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3647ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x5de, SISLANDS_CACCONFIG_CGIND },
3657ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3667ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x7b, SISLANDS_CACCONFIG_CGIND },
3677ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3687ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x13, SISLANDS_CACCONFIG_CGIND },
3697ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0xf9, SISLANDS_CACCONFIG_CGIND },
3707ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x66, SISLANDS_CACCONFIG_CGIND },
3717ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3727ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x13, SISLANDS_CACCONFIG_CGIND },
3737ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3747ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3757ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3767ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3777ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3787ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3797ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3807ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3817ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3827ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3837ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3847ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3857ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3867ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3877ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3887ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3897ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3907ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3917ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
3927ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
3937ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0x186, SISLANDS_CACCONFIG_CGIND },
3947ccd5a2cSjsg 	{ 0xFFFFFFFF }
3957ccd5a2cSjsg };
3967ccd5a2cSjsg 
3977ccd5a2cSjsg static const struct si_cac_config_reg lcac_pitcairn[] =
3987ccd5a2cSjsg {
3997ccd5a2cSjsg 	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4007ccd5a2cSjsg 	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4017ccd5a2cSjsg 	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4027ccd5a2cSjsg 	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4037ccd5a2cSjsg 	{ 0x110, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4047ccd5a2cSjsg 	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4057ccd5a2cSjsg 	{ 0x14f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4067ccd5a2cSjsg 	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4077ccd5a2cSjsg 	{ 0x8c, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4087ccd5a2cSjsg 	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4097ccd5a2cSjsg 	{ 0x143, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4107ccd5a2cSjsg 	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4117ccd5a2cSjsg 	{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4127ccd5a2cSjsg 	{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4137ccd5a2cSjsg 	{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4147ccd5a2cSjsg 	{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4157ccd5a2cSjsg 	{ 0x113, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4167ccd5a2cSjsg 	{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4177ccd5a2cSjsg 	{ 0x152, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4187ccd5a2cSjsg 	{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4197ccd5a2cSjsg 	{ 0x8f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4207ccd5a2cSjsg 	{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4217ccd5a2cSjsg 	{ 0x146, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4227ccd5a2cSjsg 	{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4237ccd5a2cSjsg 	{ 0x9e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4247ccd5a2cSjsg 	{ 0x9e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4257ccd5a2cSjsg 	{ 0x10a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4267ccd5a2cSjsg 	{ 0x10a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4277ccd5a2cSjsg 	{ 0x116, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4287ccd5a2cSjsg 	{ 0x116, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4297ccd5a2cSjsg 	{ 0x155, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4307ccd5a2cSjsg 	{ 0x155, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4317ccd5a2cSjsg 	{ 0x92, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4327ccd5a2cSjsg 	{ 0x92, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4337ccd5a2cSjsg 	{ 0x149, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4347ccd5a2cSjsg 	{ 0x149, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4357ccd5a2cSjsg 	{ 0x101, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4367ccd5a2cSjsg 	{ 0x101, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4377ccd5a2cSjsg 	{ 0x10d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4387ccd5a2cSjsg 	{ 0x10d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4397ccd5a2cSjsg 	{ 0x119, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4407ccd5a2cSjsg 	{ 0x119, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4417ccd5a2cSjsg 	{ 0x158, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4427ccd5a2cSjsg 	{ 0x158, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4437ccd5a2cSjsg 	{ 0x95, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
4447ccd5a2cSjsg 	{ 0x95, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4457ccd5a2cSjsg 	{ 0x14c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4467ccd5a2cSjsg 	{ 0x14c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4477ccd5a2cSjsg 	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4487ccd5a2cSjsg 	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4497ccd5a2cSjsg 	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4507ccd5a2cSjsg 	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4517ccd5a2cSjsg 	{ 0x122, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4527ccd5a2cSjsg 	{ 0x122, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4537ccd5a2cSjsg 	{ 0x125, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4547ccd5a2cSjsg 	{ 0x125, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4557ccd5a2cSjsg 	{ 0x128, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4567ccd5a2cSjsg 	{ 0x128, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4577ccd5a2cSjsg 	{ 0x12b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4587ccd5a2cSjsg 	{ 0x12b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4597ccd5a2cSjsg 	{ 0x164, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
4607ccd5a2cSjsg 	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4617ccd5a2cSjsg 	{ 0x167, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
4627ccd5a2cSjsg 	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4637ccd5a2cSjsg 	{ 0x16a, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
4647ccd5a2cSjsg 	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4657ccd5a2cSjsg 	{ 0x15e, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
4667ccd5a2cSjsg 	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4677ccd5a2cSjsg 	{ 0x161, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
4687ccd5a2cSjsg 	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4697ccd5a2cSjsg 	{ 0x15b, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
4707ccd5a2cSjsg 	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4717ccd5a2cSjsg 	{ 0x16d, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
4727ccd5a2cSjsg 	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4737ccd5a2cSjsg 	{ 0x170, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4747ccd5a2cSjsg 	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4757ccd5a2cSjsg 	{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4767ccd5a2cSjsg 	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4777ccd5a2cSjsg 	{ 0x176, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4787ccd5a2cSjsg 	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4797ccd5a2cSjsg 	{ 0x179, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4807ccd5a2cSjsg 	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4817ccd5a2cSjsg 	{ 0x17c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4827ccd5a2cSjsg 	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4837ccd5a2cSjsg 	{ 0x17f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
4847ccd5a2cSjsg 	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
4857ccd5a2cSjsg 	{ 0xFFFFFFFF }
4867ccd5a2cSjsg };
4877ccd5a2cSjsg 
4887ccd5a2cSjsg static const struct si_cac_config_reg cac_override_pitcairn[] =
4897ccd5a2cSjsg {
4907ccd5a2cSjsg 	{ 0xFFFFFFFF }
4917ccd5a2cSjsg };
4927ccd5a2cSjsg 
4937ccd5a2cSjsg static const struct si_powertune_data powertune_data_pitcairn =
4947ccd5a2cSjsg {
4957ccd5a2cSjsg 	((1 << 16) | 27027),
4967ccd5a2cSjsg 	5,
4977ccd5a2cSjsg 	0,
4987ccd5a2cSjsg 	6,
4997ccd5a2cSjsg 	100,
5007ccd5a2cSjsg 	{
5017ccd5a2cSjsg 		51600000UL,
5027ccd5a2cSjsg 		1800000UL,
5037ccd5a2cSjsg 		7194395UL,
5047ccd5a2cSjsg 		309631529UL,
5057ccd5a2cSjsg 		-1270850L,
5067ccd5a2cSjsg 		4513710L,
5077ccd5a2cSjsg 		100
5087ccd5a2cSjsg 	},
5097ccd5a2cSjsg 	117830498UL,
5107ccd5a2cSjsg 	12,
5117ccd5a2cSjsg 	{
5127ccd5a2cSjsg 		0,
5137ccd5a2cSjsg 		0,
5147ccd5a2cSjsg 		0,
5157ccd5a2cSjsg 		0,
5167ccd5a2cSjsg 		0,
5177ccd5a2cSjsg 		0,
5187ccd5a2cSjsg 		0,
5197ccd5a2cSjsg 		0
5207ccd5a2cSjsg 	},
5217ccd5a2cSjsg 	true
5227ccd5a2cSjsg };
5237ccd5a2cSjsg 
5247ccd5a2cSjsg static const struct si_dte_data dte_data_pitcairn =
5257ccd5a2cSjsg {
5267ccd5a2cSjsg 	{ 0, 0, 0, 0, 0 },
5277ccd5a2cSjsg 	{ 0, 0, 0, 0, 0 },
5287ccd5a2cSjsg 	0,
5297ccd5a2cSjsg 	0,
5307ccd5a2cSjsg 	0,
5317ccd5a2cSjsg 	0,
5327ccd5a2cSjsg 	0,
5337ccd5a2cSjsg 	0,
5347ccd5a2cSjsg 	0,
5357ccd5a2cSjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
5367ccd5a2cSjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
5377ccd5a2cSjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
5387ccd5a2cSjsg 	0,
5397ccd5a2cSjsg 	false
5407ccd5a2cSjsg };
5417ccd5a2cSjsg 
5427ccd5a2cSjsg static const struct si_dte_data dte_data_curacao_xt =
5437ccd5a2cSjsg {
5447ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
5457ccd5a2cSjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
5467ccd5a2cSjsg 	5,
5477ccd5a2cSjsg 	45000,
5487ccd5a2cSjsg 	100,
5497ccd5a2cSjsg 	0xA,
5507ccd5a2cSjsg 	1,
5517ccd5a2cSjsg 	0,
5527ccd5a2cSjsg 	0x10,
5537ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
5547ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
5557ccd5a2cSjsg 	{ 0x1D17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
5567ccd5a2cSjsg 	90,
5577ccd5a2cSjsg 	true
5587ccd5a2cSjsg };
5597ccd5a2cSjsg 
5607ccd5a2cSjsg static const struct si_dte_data dte_data_curacao_pro =
5617ccd5a2cSjsg {
5627ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
5637ccd5a2cSjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
5647ccd5a2cSjsg 	5,
5657ccd5a2cSjsg 	45000,
5667ccd5a2cSjsg 	100,
5677ccd5a2cSjsg 	0xA,
5687ccd5a2cSjsg 	1,
5697ccd5a2cSjsg 	0,
5707ccd5a2cSjsg 	0x10,
5717ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
5727ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
5737ccd5a2cSjsg 	{ 0x1D17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
5747ccd5a2cSjsg 	90,
5757ccd5a2cSjsg 	true
5767ccd5a2cSjsg };
5777ccd5a2cSjsg 
5787ccd5a2cSjsg static const struct si_dte_data dte_data_neptune_xt =
5797ccd5a2cSjsg {
5807ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
5817ccd5a2cSjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
5827ccd5a2cSjsg 	5,
5837ccd5a2cSjsg 	45000,
5847ccd5a2cSjsg 	100,
5857ccd5a2cSjsg 	0xA,
5867ccd5a2cSjsg 	1,
5877ccd5a2cSjsg 	0,
5887ccd5a2cSjsg 	0x10,
5897ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
5907ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
5917ccd5a2cSjsg 	{ 0x3A2F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
5927ccd5a2cSjsg 	90,
5937ccd5a2cSjsg 	true
5947ccd5a2cSjsg };
5957ccd5a2cSjsg 
5967ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_chelsea_pro[] =
5977ccd5a2cSjsg {
5987ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
5997ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
6007ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
6017ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
6027ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
6037ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
6047ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
6057ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
6067ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
6077ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
6087ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
6097ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
6107ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
6117ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
6127ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
6137ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
6147ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
6157ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
6167ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
6177ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
6187ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
6197ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
6207ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
6217ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
6227ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
6237ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
6247ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
6257ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
6267ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
6277ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
6287ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
6297ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
6307ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
6317ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
6327ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
6337ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x2BD, SISLANDS_CACCONFIG_CGIND },
6347ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
6357ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
6367ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
6377ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
6387ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
6397ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
6407ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
6417ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
6427ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
6437ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
6447ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
6457ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
6467ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
6477ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
6487ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
6497ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
6507ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
6517ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
6527ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
6537ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
6547ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
6557ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
6567ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
6577ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
6587ccd5a2cSjsg 	{ 0xFFFFFFFF }
6597ccd5a2cSjsg };
6607ccd5a2cSjsg 
6617ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_chelsea_xt[] =
6627ccd5a2cSjsg {
6637ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
6647ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
6657ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
6667ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
6677ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
6687ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
6697ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
6707ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
6717ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
6727ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
6737ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
6747ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
6757ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
6767ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
6777ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
6787ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
6797ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
6807ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
6817ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
6827ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
6837ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
6847ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
6857ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
6867ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
6877ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
6887ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
6897ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
6907ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
6917ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
6927ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
6937ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
6947ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
6957ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
6967ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
6977ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
6987ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x30A, SISLANDS_CACCONFIG_CGIND },
6997ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7007ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
7017ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7027ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
7037ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
7047ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7057ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7067ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
7077ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7087ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
7097ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7107ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7117ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7127ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7137ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7147ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7157ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7167ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7177ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7187ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7197ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7207ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7217ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7227ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
7237ccd5a2cSjsg 	{ 0xFFFFFFFF }
7247ccd5a2cSjsg };
7257ccd5a2cSjsg 
7267ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_heathrow[] =
7277ccd5a2cSjsg {
7287ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
7297ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
7307ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
7317ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
7327ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7337ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
7347ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
7357ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
7367ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
7377ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
7387ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
7397ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
7407ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
7417ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
7427ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
7437ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
7447ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
7457ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
7467ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
7477ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
7487ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
7497ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
7507ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
7517ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
7527ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
7537ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
7547ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
7557ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
7567ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
7577ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
7587ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
7597ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
7607ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
7617ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
7627ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
7637ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x362, SISLANDS_CACCONFIG_CGIND },
7647ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7657ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
7667ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7677ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
7687ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
7697ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7707ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7717ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
7727ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7737ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
7747ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7757ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7767ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7777ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7787ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7797ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7807ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7817ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7827ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7837ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7847ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7857ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
7867ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
7877ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
7887ccd5a2cSjsg 	{ 0xFFFFFFFF }
7897ccd5a2cSjsg };
7907ccd5a2cSjsg 
7917ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_cape_verde_pro[] =
7927ccd5a2cSjsg {
7937ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
7947ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
7957ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
7967ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
7977ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
7987ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
7997ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
8007ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
8017ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
8027ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
8037ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
8047ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
8057ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
8067ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
8077ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
8087ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
8097ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
8107ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
8117ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
8127ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
8137ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
8147ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
8157ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
8167ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
8177ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
8187ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
8197ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
8207ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
8217ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
8227ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
8237ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
8247ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
8257ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
8267ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
8277ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
8287ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x315, SISLANDS_CACCONFIG_CGIND },
8297ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8307ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
8317ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8327ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
8337ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
8347ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8357ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8367ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
8377ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8387ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
8397ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8407ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8417ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8427ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8437ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8447ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8457ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8467ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8477ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8487ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8497ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8507ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
8517ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
8527ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
8537ccd5a2cSjsg 	{ 0xFFFFFFFF }
8547ccd5a2cSjsg };
8557ccd5a2cSjsg 
8567ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_cape_verde[] =
8577ccd5a2cSjsg {
8587ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
8597ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
8607ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
8617ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
8627ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8637ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
8647ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
8657ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
8667ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
8677ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
8687ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
8697ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
8707ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
8717ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
8727ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
8737ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
8747ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
8757ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
8767ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
8777ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
8787ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
8797ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
8807ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
8817ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
8827ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
8837ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
8847ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
8857ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
8867ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
8877ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
8887ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
8897ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
8907ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
8917ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
8927ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
8937ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x3BA, SISLANDS_CACCONFIG_CGIND },
8947ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8957ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
8967ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
8977ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
8987ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
8997ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9007ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9017ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
9027ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
9037ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
9047ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9057ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9067ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9077ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9087ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9097ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9107ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9117ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9127ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9137ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9147ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9157ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
9167ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
9177ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
9187ccd5a2cSjsg 	{ 0xFFFFFFFF }
9197ccd5a2cSjsg };
9207ccd5a2cSjsg 
9217ccd5a2cSjsg static const struct si_cac_config_reg lcac_cape_verde[] =
9227ccd5a2cSjsg {
9237ccd5a2cSjsg 	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9247ccd5a2cSjsg 	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9257ccd5a2cSjsg 	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9267ccd5a2cSjsg 	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9277ccd5a2cSjsg 	{ 0x110, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
9287ccd5a2cSjsg 	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9297ccd5a2cSjsg 	{ 0x14f, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
9307ccd5a2cSjsg 	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9317ccd5a2cSjsg 	{ 0x8c, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
9327ccd5a2cSjsg 	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9337ccd5a2cSjsg 	{ 0x143, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
9347ccd5a2cSjsg 	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9357ccd5a2cSjsg 	{ 0x9b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9367ccd5a2cSjsg 	{ 0x9b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9377ccd5a2cSjsg 	{ 0x107, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9387ccd5a2cSjsg 	{ 0x107, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9397ccd5a2cSjsg 	{ 0x113, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
9407ccd5a2cSjsg 	{ 0x113, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9417ccd5a2cSjsg 	{ 0x152, 0x0001fffe, 1, 0x5, SISLANDS_CACCONFIG_CGIND },
9427ccd5a2cSjsg 	{ 0x152, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9437ccd5a2cSjsg 	{ 0x8f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
9447ccd5a2cSjsg 	{ 0x8f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9457ccd5a2cSjsg 	{ 0x146, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
9467ccd5a2cSjsg 	{ 0x146, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9477ccd5a2cSjsg 	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9487ccd5a2cSjsg 	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9497ccd5a2cSjsg 	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9507ccd5a2cSjsg 	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9517ccd5a2cSjsg 	{ 0x164, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9527ccd5a2cSjsg 	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9537ccd5a2cSjsg 	{ 0x167, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9547ccd5a2cSjsg 	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9557ccd5a2cSjsg 	{ 0x16a, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9567ccd5a2cSjsg 	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9577ccd5a2cSjsg 	{ 0x15e, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9587ccd5a2cSjsg 	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9597ccd5a2cSjsg 	{ 0x161, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9607ccd5a2cSjsg 	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9617ccd5a2cSjsg 	{ 0x15b, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9627ccd5a2cSjsg 	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9637ccd5a2cSjsg 	{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9647ccd5a2cSjsg 	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9657ccd5a2cSjsg 	{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
9667ccd5a2cSjsg 	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9677ccd5a2cSjsg 	{ 0x173, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
9687ccd5a2cSjsg 	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9697ccd5a2cSjsg 	{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
9707ccd5a2cSjsg 	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9717ccd5a2cSjsg 	{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
9727ccd5a2cSjsg 	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9737ccd5a2cSjsg 	{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
9747ccd5a2cSjsg 	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9757ccd5a2cSjsg 	{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
9767ccd5a2cSjsg 	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
9777ccd5a2cSjsg 	{ 0xFFFFFFFF }
9787ccd5a2cSjsg };
9797ccd5a2cSjsg 
9807ccd5a2cSjsg static const struct si_cac_config_reg cac_override_cape_verde[] =
9817ccd5a2cSjsg {
9827ccd5a2cSjsg 	{ 0xFFFFFFFF }
9837ccd5a2cSjsg };
9847ccd5a2cSjsg 
9857ccd5a2cSjsg static const struct si_powertune_data powertune_data_cape_verde =
9867ccd5a2cSjsg {
9877ccd5a2cSjsg 	((1 << 16) | 0x6993),
9887ccd5a2cSjsg 	5,
9897ccd5a2cSjsg 	0,
9907ccd5a2cSjsg 	7,
9917ccd5a2cSjsg 	105,
9927ccd5a2cSjsg 	{
9937ccd5a2cSjsg 		0UL,
9947ccd5a2cSjsg 		0UL,
9957ccd5a2cSjsg 		7194395UL,
9967ccd5a2cSjsg 		309631529UL,
9977ccd5a2cSjsg 		-1270850L,
9987ccd5a2cSjsg 		4513710L,
9997ccd5a2cSjsg 		100
10007ccd5a2cSjsg 	},
10017ccd5a2cSjsg 	117830498UL,
10027ccd5a2cSjsg 	12,
10037ccd5a2cSjsg 	{
10047ccd5a2cSjsg 		0,
10057ccd5a2cSjsg 		0,
10067ccd5a2cSjsg 		0,
10077ccd5a2cSjsg 		0,
10087ccd5a2cSjsg 		0,
10097ccd5a2cSjsg 		0,
10107ccd5a2cSjsg 		0,
10117ccd5a2cSjsg 		0
10127ccd5a2cSjsg 	},
10137ccd5a2cSjsg 	true
10147ccd5a2cSjsg };
10157ccd5a2cSjsg 
10167ccd5a2cSjsg static const struct si_dte_data dte_data_cape_verde =
10177ccd5a2cSjsg {
10187ccd5a2cSjsg 	{ 0, 0, 0, 0, 0 },
10197ccd5a2cSjsg 	{ 0, 0, 0, 0, 0 },
10207ccd5a2cSjsg 	0,
10217ccd5a2cSjsg 	0,
10227ccd5a2cSjsg 	0,
10237ccd5a2cSjsg 	0,
10247ccd5a2cSjsg 	0,
10257ccd5a2cSjsg 	0,
10267ccd5a2cSjsg 	0,
10277ccd5a2cSjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
10287ccd5a2cSjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
10297ccd5a2cSjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
10307ccd5a2cSjsg 	0,
10317ccd5a2cSjsg 	false
10327ccd5a2cSjsg };
10337ccd5a2cSjsg 
10347ccd5a2cSjsg static const struct si_dte_data dte_data_venus_xtx =
10357ccd5a2cSjsg {
10367ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
10377ccd5a2cSjsg 	{ 0x71C, 0xAAB, 0xE39, 0x11C7, 0x0 },
10387ccd5a2cSjsg 	5,
10397ccd5a2cSjsg 	55000,
10407ccd5a2cSjsg 	0x69,
10417ccd5a2cSjsg 	0xA,
10427ccd5a2cSjsg 	1,
10437ccd5a2cSjsg 	0,
10447ccd5a2cSjsg 	0x3,
10457ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
10467ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
10477ccd5a2cSjsg 	{ 0xD6D8, 0x88B8, 0x1555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
10487ccd5a2cSjsg 	90,
10497ccd5a2cSjsg 	true
10507ccd5a2cSjsg };
10517ccd5a2cSjsg 
10527ccd5a2cSjsg static const struct si_dte_data dte_data_venus_xt =
10537ccd5a2cSjsg {
10547ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
10557ccd5a2cSjsg 	{ 0xBDA, 0x11C7, 0x17B4, 0x1DA1, 0x0 },
10567ccd5a2cSjsg 	5,
10577ccd5a2cSjsg 	55000,
10587ccd5a2cSjsg 	0x69,
10597ccd5a2cSjsg 	0xA,
10607ccd5a2cSjsg 	1,
10617ccd5a2cSjsg 	0,
10627ccd5a2cSjsg 	0x3,
10637ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
10647ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
10657ccd5a2cSjsg 	{ 0xAFC8, 0x88B8, 0x238E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
10667ccd5a2cSjsg 	90,
10677ccd5a2cSjsg 	true
10687ccd5a2cSjsg };
10697ccd5a2cSjsg 
10707ccd5a2cSjsg static const struct si_dte_data dte_data_venus_pro =
10717ccd5a2cSjsg {
10727ccd5a2cSjsg 	{  0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
10737ccd5a2cSjsg 	{ 0x11C7, 0x1AAB, 0x238E, 0x2C72, 0x0 },
10747ccd5a2cSjsg 	5,
10757ccd5a2cSjsg 	55000,
10767ccd5a2cSjsg 	0x69,
10777ccd5a2cSjsg 	0xA,
10787ccd5a2cSjsg 	1,
10797ccd5a2cSjsg 	0,
10807ccd5a2cSjsg 	0x3,
10817ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
10827ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
10837ccd5a2cSjsg 	{ 0x88B8, 0x88B8, 0x3555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
10847ccd5a2cSjsg 	90,
10857ccd5a2cSjsg 	true
10867ccd5a2cSjsg };
10877ccd5a2cSjsg 
1088*1bb76ff1Sjsg static struct si_cac_config_reg cac_weights_oland[] =
10897ccd5a2cSjsg {
10907ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x82, SISLANDS_CACCONFIG_CGIND },
10917ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
10927ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0x153, SISLANDS_CACCONFIG_CGIND },
10937ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x52, SISLANDS_CACCONFIG_CGIND },
10947ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
10957ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
10967ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x4F, SISLANDS_CACCONFIG_CGIND },
10977ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0x135, SISLANDS_CACCONFIG_CGIND },
10987ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0xAC, SISLANDS_CACCONFIG_CGIND },
10997ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x118, SISLANDS_CACCONFIG_CGIND },
11007ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0xBE, SISLANDS_CACCONFIG_CGIND },
11017ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x110, SISLANDS_CACCONFIG_CGIND },
11027ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x4CD, SISLANDS_CACCONFIG_CGIND },
11037ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
11047ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x37, SISLANDS_CACCONFIG_CGIND },
11057ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0x27, SISLANDS_CACCONFIG_CGIND },
11067ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0xC3, SISLANDS_CACCONFIG_CGIND },
11077ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x35, SISLANDS_CACCONFIG_CGIND },
11087ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0x28, SISLANDS_CACCONFIG_CGIND },
11097ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x26C, SISLANDS_CACCONFIG_CGIND },
11107ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x3B2, SISLANDS_CACCONFIG_CGIND },
11117ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x99D, SISLANDS_CACCONFIG_CGIND },
11127ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xA3F, SISLANDS_CACCONFIG_CGIND },
11137ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0xA, SISLANDS_CACCONFIG_CGIND },
11147ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0xA, SISLANDS_CACCONFIG_CGIND },
11157ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
11167ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
11177ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
11187ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
11197ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x1, SISLANDS_CACCONFIG_CGIND },
11207ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
11217ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x15, SISLANDS_CACCONFIG_CGIND },
11227ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x34, SISLANDS_CACCONFIG_CGIND },
11237ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x4, SISLANDS_CACCONFIG_CGIND },
11247ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
11257ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x3BA, SISLANDS_CACCONFIG_CGIND },
11267ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11277ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
11287ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11297ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x30, SISLANDS_CACCONFIG_CGIND },
11307ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x7A, SISLANDS_CACCONFIG_CGIND },
11317ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11327ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11337ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
11347ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11357ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
11367ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
11377ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
11387ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
11397ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
11407ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
11417ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
11427ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
11437ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
11447ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
11457ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
11467ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
11477ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
11487ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
11497ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0x100, SISLANDS_CACCONFIG_CGIND },
11507ccd5a2cSjsg 	{ 0xFFFFFFFF }
11517ccd5a2cSjsg };
11527ccd5a2cSjsg 
11537ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_mars_pro[] =
11547ccd5a2cSjsg {
11557ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
11567ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
11577ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
11587ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
11597ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11607ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
11617ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
11627ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
11637ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
11647ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
11657ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
11667ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
11677ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
11687ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
11697ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
11707ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
11717ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
11727ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
11737ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
11747ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
11757ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
11767ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
11777ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
11787ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
11797ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
11807ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
11817ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
11827ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
11837ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
11847ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
11857ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
11867ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
11877ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
11887ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
11897ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
11907ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x2, SISLANDS_CACCONFIG_CGIND },
11917ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11927ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
11937ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11947ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
11957ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
11967ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11977ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
11987ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
11997ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12007ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
12017ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
12027ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
12037ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12047ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
12057ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
12067ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
12077ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12087ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
12097ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12107ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
12117ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12127ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
12137ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12147ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
12157ccd5a2cSjsg 	{ 0xFFFFFFFF }
12167ccd5a2cSjsg };
12177ccd5a2cSjsg 
12187ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_mars_xt[] =
12197ccd5a2cSjsg {
12207ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
12217ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
12227ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
12237ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
12247ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12257ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
12267ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
12277ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
12287ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
12297ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
12307ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
12317ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
12327ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
12337ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
12347ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
12357ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
12367ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
12377ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
12387ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
12397ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
12407ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
12417ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
12427ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
12437ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
12447ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
12457ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
12467ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
12477ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
12487ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
12497ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
12507ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
12517ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
12527ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
12537ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
12547ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
12557ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x60, SISLANDS_CACCONFIG_CGIND },
12567ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12577ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
12587ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12597ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
12607ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
12617ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12627ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12637ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
12647ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12657ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
12667ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
12677ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
12687ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12697ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
12707ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
12717ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
12727ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12737ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
12747ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12757ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
12767ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12777ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
12787ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
12797ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
12807ccd5a2cSjsg 	{ 0xFFFFFFFF }
12817ccd5a2cSjsg };
12827ccd5a2cSjsg 
12837ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_oland_pro[] =
12847ccd5a2cSjsg {
12857ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
12867ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
12877ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
12887ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
12897ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
12907ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
12917ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
12927ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
12937ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
12947ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
12957ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
12967ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
12977ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
12987ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
12997ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
13007ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
13017ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
13027ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
13037ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
13047ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
13057ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
13067ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
13077ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
13087ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
13097ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
13107ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
13117ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
13127ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
13137ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
13147ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
13157ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
13167ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
13177ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
13187ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
13197ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
13207ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x90, SISLANDS_CACCONFIG_CGIND },
13217ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13227ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
13237ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13247ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
13257ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
13267ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13277ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13287ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13297ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13307ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13317ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
13327ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
13337ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13347ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13357ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
13367ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
13377ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13387ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13397ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
13407ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
13417ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
13427ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
13437ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
13447ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
13457ccd5a2cSjsg 	{ 0xFFFFFFFF }
13467ccd5a2cSjsg };
13477ccd5a2cSjsg 
13487ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_oland_xt[] =
13497ccd5a2cSjsg {
13507ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x43, SISLANDS_CACCONFIG_CGIND },
13517ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
13527ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0xAF, SISLANDS_CACCONFIG_CGIND },
13537ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x2A, SISLANDS_CACCONFIG_CGIND },
13547ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13557ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
13567ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x29, SISLANDS_CACCONFIG_CGIND },
13577ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0xA0, SISLANDS_CACCONFIG_CGIND },
13587ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0x59, SISLANDS_CACCONFIG_CGIND },
13597ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x1A5, SISLANDS_CACCONFIG_CGIND },
13607ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0x1D6, SISLANDS_CACCONFIG_CGIND },
13617ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0x2A3, SISLANDS_CACCONFIG_CGIND },
13627ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x8FD, SISLANDS_CACCONFIG_CGIND },
13637ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x76, SISLANDS_CACCONFIG_CGIND },
13647ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x8A, SISLANDS_CACCONFIG_CGIND },
13657ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0xA3, SISLANDS_CACCONFIG_CGIND },
13667ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0x71, SISLANDS_CACCONFIG_CGIND },
13677ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0x36, SISLANDS_CACCONFIG_CGIND },
13687ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0xA6, SISLANDS_CACCONFIG_CGIND },
13697ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x81, SISLANDS_CACCONFIG_CGIND },
13707ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0x3D2, SISLANDS_CACCONFIG_CGIND },
13717ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0x27C, SISLANDS_CACCONFIG_CGIND },
13727ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xA96, SISLANDS_CACCONFIG_CGIND },
13737ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0x5, SISLANDS_CACCONFIG_CGIND },
13747ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0x5, SISLANDS_CACCONFIG_CGIND },
13757ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0xB, SISLANDS_CACCONFIG_CGIND },
13767ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x3, SISLANDS_CACCONFIG_CGIND },
13777ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x2, SISLANDS_CACCONFIG_CGIND },
13787ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
13797ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x4, SISLANDS_CACCONFIG_CGIND },
13807ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x15, SISLANDS_CACCONFIG_CGIND },
13817ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
13827ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x36, SISLANDS_CACCONFIG_CGIND },
13837ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x10, SISLANDS_CACCONFIG_CGIND },
13847ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x10, SISLANDS_CACCONFIG_CGIND },
13857ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x120, SISLANDS_CACCONFIG_CGIND },
13867ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13877ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x6, SISLANDS_CACCONFIG_CGIND },
13887ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13897ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x32, SISLANDS_CACCONFIG_CGIND },
13907ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x7E, SISLANDS_CACCONFIG_CGIND },
13917ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13927ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13937ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13947ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13957ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
13967ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0x280, SISLANDS_CACCONFIG_CGIND },
13977ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0x7, SISLANDS_CACCONFIG_CGIND },
13987ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
13997ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
14007ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0x3C, SISLANDS_CACCONFIG_CGIND },
14017ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0x203, SISLANDS_CACCONFIG_CGIND },
14027ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
14037ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
14047ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
14057ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
14067ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
14077ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
14087ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
14097ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0xB4, SISLANDS_CACCONFIG_CGIND },
14107ccd5a2cSjsg 	{ 0xFFFFFFFF }
14117ccd5a2cSjsg };
14127ccd5a2cSjsg 
14137ccd5a2cSjsg static const struct si_cac_config_reg lcac_oland[] =
14147ccd5a2cSjsg {
14157ccd5a2cSjsg 	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14167ccd5a2cSjsg 	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14177ccd5a2cSjsg 	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14187ccd5a2cSjsg 	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14197ccd5a2cSjsg 	{ 0x110, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
14207ccd5a2cSjsg 	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14217ccd5a2cSjsg 	{ 0x14f, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
14227ccd5a2cSjsg 	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14237ccd5a2cSjsg 	{ 0x8c, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
14247ccd5a2cSjsg 	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14257ccd5a2cSjsg 	{ 0x143, 0x0001fffe, 1, 0x4, SISLANDS_CACCONFIG_CGIND },
14267ccd5a2cSjsg 	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14277ccd5a2cSjsg 	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14287ccd5a2cSjsg 	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14297ccd5a2cSjsg 	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14307ccd5a2cSjsg 	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14317ccd5a2cSjsg 	{ 0x164, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14327ccd5a2cSjsg 	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14337ccd5a2cSjsg 	{ 0x167, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14347ccd5a2cSjsg 	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14357ccd5a2cSjsg 	{ 0x16a, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14367ccd5a2cSjsg 	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14377ccd5a2cSjsg 	{ 0x15e, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14387ccd5a2cSjsg 	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14397ccd5a2cSjsg 	{ 0x161, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14407ccd5a2cSjsg 	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14417ccd5a2cSjsg 	{ 0x15b, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14427ccd5a2cSjsg 	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14437ccd5a2cSjsg 	{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14447ccd5a2cSjsg 	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14457ccd5a2cSjsg 	{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14467ccd5a2cSjsg 	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14477ccd5a2cSjsg 	{ 0x173, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14487ccd5a2cSjsg 	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14497ccd5a2cSjsg 	{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14507ccd5a2cSjsg 	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14517ccd5a2cSjsg 	{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14527ccd5a2cSjsg 	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14537ccd5a2cSjsg 	{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14547ccd5a2cSjsg 	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14557ccd5a2cSjsg 	{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14567ccd5a2cSjsg 	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14577ccd5a2cSjsg 	{ 0xFFFFFFFF }
14587ccd5a2cSjsg };
14597ccd5a2cSjsg 
14607ccd5a2cSjsg static const struct si_cac_config_reg lcac_mars_pro[] =
14617ccd5a2cSjsg {
14627ccd5a2cSjsg 	{ 0x98, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14637ccd5a2cSjsg 	{ 0x98, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14647ccd5a2cSjsg 	{ 0x104, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14657ccd5a2cSjsg 	{ 0x104, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14667ccd5a2cSjsg 	{ 0x110, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
14677ccd5a2cSjsg 	{ 0x110, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14687ccd5a2cSjsg 	{ 0x14f, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
14697ccd5a2cSjsg 	{ 0x14f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14707ccd5a2cSjsg 	{ 0x8c, 0x0001fffe, 1, 0x6, SISLANDS_CACCONFIG_CGIND },
14717ccd5a2cSjsg 	{ 0x8c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14727ccd5a2cSjsg 	{ 0x143, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14737ccd5a2cSjsg 	{ 0x143, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14747ccd5a2cSjsg 	{ 0x11c, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14757ccd5a2cSjsg 	{ 0x11c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14767ccd5a2cSjsg 	{ 0x11f, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14777ccd5a2cSjsg 	{ 0x11f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14787ccd5a2cSjsg 	{ 0x164, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14797ccd5a2cSjsg 	{ 0x164, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14807ccd5a2cSjsg 	{ 0x167, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14817ccd5a2cSjsg 	{ 0x167, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14827ccd5a2cSjsg 	{ 0x16a, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14837ccd5a2cSjsg 	{ 0x16a, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14847ccd5a2cSjsg 	{ 0x15e, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14857ccd5a2cSjsg 	{ 0x15e, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14867ccd5a2cSjsg 	{ 0x161, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14877ccd5a2cSjsg 	{ 0x161, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14887ccd5a2cSjsg 	{ 0x15b, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14897ccd5a2cSjsg 	{ 0x15b, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14907ccd5a2cSjsg 	{ 0x16d, 0x0001fffe, 1, 0x2, SISLANDS_CACCONFIG_CGIND },
14917ccd5a2cSjsg 	{ 0x16d, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14927ccd5a2cSjsg 	{ 0x170, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14937ccd5a2cSjsg 	{ 0x170, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14947ccd5a2cSjsg 	{ 0x173, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14957ccd5a2cSjsg 	{ 0x173, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14967ccd5a2cSjsg 	{ 0x176, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14977ccd5a2cSjsg 	{ 0x176, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
14987ccd5a2cSjsg 	{ 0x179, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
14997ccd5a2cSjsg 	{ 0x179, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15007ccd5a2cSjsg 	{ 0x17c, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15017ccd5a2cSjsg 	{ 0x17c, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15027ccd5a2cSjsg 	{ 0x17f, 0x0001fffe, 1, 0x1, SISLANDS_CACCONFIG_CGIND },
15037ccd5a2cSjsg 	{ 0x17f, 0x00000001, 0, 0x1, SISLANDS_CACCONFIG_CGIND },
15047ccd5a2cSjsg 	{ 0xFFFFFFFF }
15057ccd5a2cSjsg };
15067ccd5a2cSjsg 
15077ccd5a2cSjsg static const struct si_cac_config_reg cac_override_oland[] =
15087ccd5a2cSjsg {
15097ccd5a2cSjsg 	{ 0xFFFFFFFF }
15107ccd5a2cSjsg };
15117ccd5a2cSjsg 
15127ccd5a2cSjsg static const struct si_powertune_data powertune_data_oland =
15137ccd5a2cSjsg {
15147ccd5a2cSjsg 	((1 << 16) | 0x6993),
15157ccd5a2cSjsg 	5,
15167ccd5a2cSjsg 	0,
15177ccd5a2cSjsg 	7,
15187ccd5a2cSjsg 	105,
15197ccd5a2cSjsg 	{
15207ccd5a2cSjsg 		0UL,
15217ccd5a2cSjsg 		0UL,
15227ccd5a2cSjsg 		7194395UL,
15237ccd5a2cSjsg 		309631529UL,
15247ccd5a2cSjsg 		-1270850L,
15257ccd5a2cSjsg 		4513710L,
15267ccd5a2cSjsg 		100
15277ccd5a2cSjsg 	},
15287ccd5a2cSjsg 	117830498UL,
15297ccd5a2cSjsg 	12,
15307ccd5a2cSjsg 	{
15317ccd5a2cSjsg 		0,
15327ccd5a2cSjsg 		0,
15337ccd5a2cSjsg 		0,
15347ccd5a2cSjsg 		0,
15357ccd5a2cSjsg 		0,
15367ccd5a2cSjsg 		0,
15377ccd5a2cSjsg 		0,
15387ccd5a2cSjsg 		0
15397ccd5a2cSjsg 	},
15407ccd5a2cSjsg 	true
15417ccd5a2cSjsg };
15427ccd5a2cSjsg 
15437ccd5a2cSjsg static const struct si_powertune_data powertune_data_mars_pro =
15447ccd5a2cSjsg {
15457ccd5a2cSjsg 	((1 << 16) | 0x6993),
15467ccd5a2cSjsg 	5,
15477ccd5a2cSjsg 	0,
15487ccd5a2cSjsg 	7,
15497ccd5a2cSjsg 	105,
15507ccd5a2cSjsg 	{
15517ccd5a2cSjsg 		0UL,
15527ccd5a2cSjsg 		0UL,
15537ccd5a2cSjsg 		7194395UL,
15547ccd5a2cSjsg 		309631529UL,
15557ccd5a2cSjsg 		-1270850L,
15567ccd5a2cSjsg 		4513710L,
15577ccd5a2cSjsg 		100
15587ccd5a2cSjsg 	},
15597ccd5a2cSjsg 	117830498UL,
15607ccd5a2cSjsg 	12,
15617ccd5a2cSjsg 	{
15627ccd5a2cSjsg 		0,
15637ccd5a2cSjsg 		0,
15647ccd5a2cSjsg 		0,
15657ccd5a2cSjsg 		0,
15667ccd5a2cSjsg 		0,
15677ccd5a2cSjsg 		0,
15687ccd5a2cSjsg 		0,
15697ccd5a2cSjsg 		0
15707ccd5a2cSjsg 	},
15717ccd5a2cSjsg 	true
15727ccd5a2cSjsg };
15737ccd5a2cSjsg 
15747ccd5a2cSjsg static const struct si_dte_data dte_data_oland =
15757ccd5a2cSjsg {
15767ccd5a2cSjsg 	{ 0, 0, 0, 0, 0 },
15777ccd5a2cSjsg 	{ 0, 0, 0, 0, 0 },
15787ccd5a2cSjsg 	0,
15797ccd5a2cSjsg 	0,
15807ccd5a2cSjsg 	0,
15817ccd5a2cSjsg 	0,
15827ccd5a2cSjsg 	0,
15837ccd5a2cSjsg 	0,
15847ccd5a2cSjsg 	0,
15857ccd5a2cSjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
15867ccd5a2cSjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
15877ccd5a2cSjsg 	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
15887ccd5a2cSjsg 	0,
15897ccd5a2cSjsg 	false
15907ccd5a2cSjsg };
15917ccd5a2cSjsg 
15927ccd5a2cSjsg static const struct si_dte_data dte_data_mars_pro =
15937ccd5a2cSjsg {
15947ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
15957ccd5a2cSjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
15967ccd5a2cSjsg 	5,
15977ccd5a2cSjsg 	55000,
15987ccd5a2cSjsg 	105,
15997ccd5a2cSjsg 	0xA,
16007ccd5a2cSjsg 	1,
16017ccd5a2cSjsg 	0,
16027ccd5a2cSjsg 	0x10,
16037ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
16047ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
16057ccd5a2cSjsg 	{ 0xF627, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
16067ccd5a2cSjsg 	90,
16077ccd5a2cSjsg 	true
16087ccd5a2cSjsg };
16097ccd5a2cSjsg 
16107ccd5a2cSjsg static const struct si_dte_data dte_data_sun_xt =
16117ccd5a2cSjsg {
16127ccd5a2cSjsg 	{ 0x1E8480, 0x3D0900, 0x989680, 0x2625A00, 0x0 },
16137ccd5a2cSjsg 	{ 0x0, 0x0, 0x0, 0x0, 0x0 },
16147ccd5a2cSjsg 	5,
16157ccd5a2cSjsg 	55000,
16167ccd5a2cSjsg 	105,
16177ccd5a2cSjsg 	0xA,
16187ccd5a2cSjsg 	1,
16197ccd5a2cSjsg 	0,
16207ccd5a2cSjsg 	0x10,
16217ccd5a2cSjsg 	{ 0x96, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
16227ccd5a2cSjsg 	{ 0x895440, 0x3D0900, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680, 0x989680 },
16237ccd5a2cSjsg 	{ 0xD555, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 },
16247ccd5a2cSjsg 	90,
16257ccd5a2cSjsg 	true
16267ccd5a2cSjsg };
16277ccd5a2cSjsg 
16287ccd5a2cSjsg 
16297ccd5a2cSjsg static const struct si_cac_config_reg cac_weights_hainan[] =
16307ccd5a2cSjsg {
16317ccd5a2cSjsg 	{ 0x0, 0x0000ffff, 0, 0x2d9, SISLANDS_CACCONFIG_CGIND },
16327ccd5a2cSjsg 	{ 0x0, 0xffff0000, 16, 0x22b, SISLANDS_CACCONFIG_CGIND },
16337ccd5a2cSjsg 	{ 0x1, 0x0000ffff, 0, 0x21c, SISLANDS_CACCONFIG_CGIND },
16347ccd5a2cSjsg 	{ 0x1, 0xffff0000, 16, 0x1dc, SISLANDS_CACCONFIG_CGIND },
16357ccd5a2cSjsg 	{ 0x2, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
16367ccd5a2cSjsg 	{ 0x3, 0x0000ffff, 0, 0x24e, SISLANDS_CACCONFIG_CGIND },
16377ccd5a2cSjsg 	{ 0x3, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16387ccd5a2cSjsg 	{ 0x4, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
16397ccd5a2cSjsg 	{ 0x4, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16407ccd5a2cSjsg 	{ 0x5, 0x0000ffff, 0, 0x35e, SISLANDS_CACCONFIG_CGIND },
16417ccd5a2cSjsg 	{ 0x5, 0xffff0000, 16, 0x1143, SISLANDS_CACCONFIG_CGIND },
16427ccd5a2cSjsg 	{ 0x6, 0x0000ffff, 0, 0xe17, SISLANDS_CACCONFIG_CGIND },
16437ccd5a2cSjsg 	{ 0x6, 0xffff0000, 16, 0x441, SISLANDS_CACCONFIG_CGIND },
16447ccd5a2cSjsg 	{ 0x18f, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
16457ccd5a2cSjsg 	{ 0x7, 0x0000ffff, 0, 0x28b, SISLANDS_CACCONFIG_CGIND },
16467ccd5a2cSjsg 	{ 0x7, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16477ccd5a2cSjsg 	{ 0x8, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
16487ccd5a2cSjsg 	{ 0x8, 0xffff0000, 16, 0xabe, SISLANDS_CACCONFIG_CGIND },
16497ccd5a2cSjsg 	{ 0x9, 0x0000ffff, 0, 0xf11, SISLANDS_CACCONFIG_CGIND },
16507ccd5a2cSjsg 	{ 0xa, 0x0000ffff, 0, 0x907, SISLANDS_CACCONFIG_CGIND },
16517ccd5a2cSjsg 	{ 0xb, 0x0000ffff, 0, 0xb45, SISLANDS_CACCONFIG_CGIND },
16527ccd5a2cSjsg 	{ 0xb, 0xffff0000, 16, 0xd1e, SISLANDS_CACCONFIG_CGIND },
16537ccd5a2cSjsg 	{ 0xc, 0x0000ffff, 0, 0xa2c, SISLANDS_CACCONFIG_CGIND },
16547ccd5a2cSjsg 	{ 0xd, 0x0000ffff, 0, 0x62, SISLANDS_CACCONFIG_CGIND },
16557ccd5a2cSjsg 	{ 0xd, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16567ccd5a2cSjsg 	{ 0xe, 0x0000ffff, 0, 0x1f3, SISLANDS_CACCONFIG_CGIND },
16577ccd5a2cSjsg 	{ 0xf, 0x0000ffff, 0, 0x42, SISLANDS_CACCONFIG_CGIND },
16587ccd5a2cSjsg 	{ 0xf, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16597ccd5a2cSjsg 	{ 0x10, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
16607ccd5a2cSjsg 	{ 0x10, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16617ccd5a2cSjsg 	{ 0x11, 0x0000ffff, 0, 0x709, SISLANDS_CACCONFIG_CGIND },
16627ccd5a2cSjsg 	{ 0x11, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16637ccd5a2cSjsg 	{ 0x12, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
16647ccd5a2cSjsg 	{ 0x13, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
16657ccd5a2cSjsg 	{ 0x13, 0xffff0000, 16, 0x3a, SISLANDS_CACCONFIG_CGIND },
16667ccd5a2cSjsg 	{ 0x14, 0x0000ffff, 0, 0x357, SISLANDS_CACCONFIG_CGIND },
16677ccd5a2cSjsg 	{ 0x15, 0x0000ffff, 0, 0x9f, SISLANDS_CACCONFIG_CGIND },
16687ccd5a2cSjsg 	{ 0x15, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16697ccd5a2cSjsg 	{ 0x4e, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
16707ccd5a2cSjsg 	{ 0x16, 0x0000ffff, 0, 0x314, SISLANDS_CACCONFIG_CGIND },
16717ccd5a2cSjsg 	{ 0x16, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16727ccd5a2cSjsg 	{ 0x17, 0x0000ffff, 0, 0x6d, SISLANDS_CACCONFIG_CGIND },
16737ccd5a2cSjsg 	{ 0x18, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
16747ccd5a2cSjsg 	{ 0x18, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16757ccd5a2cSjsg 	{ 0x19, 0x0000ffff, 0, 0x0, SISLANDS_CACCONFIG_CGIND },
16767ccd5a2cSjsg 	{ 0x19, 0xffff0000, 16, 0x0, SISLANDS_CACCONFIG_CGIND },
16777ccd5a2cSjsg 	{ 0x1a, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
16787ccd5a2cSjsg 	{ 0x1a, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
16797ccd5a2cSjsg 	{ 0x1b, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
16807ccd5a2cSjsg 	{ 0x1b, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
16817ccd5a2cSjsg 	{ 0x1c, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
16827ccd5a2cSjsg 	{ 0x1c, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
16837ccd5a2cSjsg 	{ 0x1d, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
16847ccd5a2cSjsg 	{ 0x1d, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
16857ccd5a2cSjsg 	{ 0x1e, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
16867ccd5a2cSjsg 	{ 0x1e, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
16877ccd5a2cSjsg 	{ 0x1f, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
16887ccd5a2cSjsg 	{ 0x1f, 0xffff0000, 16, 0, SISLANDS_CACCONFIG_CGIND },
16897ccd5a2cSjsg 	{ 0x20, 0x0000ffff, 0, 0, SISLANDS_CACCONFIG_CGIND },
16907ccd5a2cSjsg 	{ 0x6d, 0x0000ffff, 0, 0x1b9, SISLANDS_CACCONFIG_CGIND },
16917ccd5a2cSjsg 	{ 0xFFFFFFFF }
16927ccd5a2cSjsg };
16937ccd5a2cSjsg 
16947ccd5a2cSjsg static const struct si_powertune_data powertune_data_hainan =
16957ccd5a2cSjsg {
16967ccd5a2cSjsg 	((1 << 16) | 0x6993),
16977ccd5a2cSjsg 	5,
16987ccd5a2cSjsg 	0,
16997ccd5a2cSjsg 	9,
17007ccd5a2cSjsg 	105,
17017ccd5a2cSjsg 	{
17027ccd5a2cSjsg 		0UL,
17037ccd5a2cSjsg 		0UL,
17047ccd5a2cSjsg 		7194395UL,
17057ccd5a2cSjsg 		309631529UL,
17067ccd5a2cSjsg 		-1270850L,
17077ccd5a2cSjsg 		4513710L,
17087ccd5a2cSjsg 		100
17097ccd5a2cSjsg 	},
17107ccd5a2cSjsg 	117830498UL,
17117ccd5a2cSjsg 	12,
17127ccd5a2cSjsg 	{
17137ccd5a2cSjsg 		0,
17147ccd5a2cSjsg 		0,
17157ccd5a2cSjsg 		0,
17167ccd5a2cSjsg 		0,
17177ccd5a2cSjsg 		0,
17187ccd5a2cSjsg 		0,
17197ccd5a2cSjsg 		0,
17207ccd5a2cSjsg 		0
17217ccd5a2cSjsg 	},
17227ccd5a2cSjsg 	true
17237ccd5a2cSjsg };
17247ccd5a2cSjsg 
17257ccd5a2cSjsg static int si_populate_voltage_value(struct radeon_device *rdev,
17267ccd5a2cSjsg 				     const struct atom_voltage_table *table,
17277ccd5a2cSjsg 				     u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage);
17287ccd5a2cSjsg static int si_get_std_voltage_value(struct radeon_device *rdev,
17297ccd5a2cSjsg 				    SISLANDS_SMC_VOLTAGE_VALUE *voltage,
17307ccd5a2cSjsg 				    u16 *std_voltage);
17317ccd5a2cSjsg static int si_write_smc_soft_register(struct radeon_device *rdev,
17327ccd5a2cSjsg 				      u16 reg_offset, u32 value);
17337ccd5a2cSjsg static int si_convert_power_level_to_smc(struct radeon_device *rdev,
17347ccd5a2cSjsg 					 struct rv7xx_pl *pl,
17357ccd5a2cSjsg 					 SISLANDS_SMC_HW_PERFORMANCE_LEVEL *level);
17367ccd5a2cSjsg static int si_calculate_sclk_params(struct radeon_device *rdev,
17377ccd5a2cSjsg 				    u32 engine_clock,
17387ccd5a2cSjsg 				    SISLANDS_SMC_SCLK_VALUE *sclk);
17397ccd5a2cSjsg 
17407ccd5a2cSjsg static void si_thermal_start_smc_fan_control(struct radeon_device *rdev);
17417ccd5a2cSjsg static void si_fan_ctrl_set_default_mode(struct radeon_device *rdev);
17427ccd5a2cSjsg 
si_get_pi(struct radeon_device * rdev)17437ccd5a2cSjsg static struct si_power_info *si_get_pi(struct radeon_device *rdev)
17447ccd5a2cSjsg {
17457ccd5a2cSjsg 	struct si_power_info *pi = rdev->pm.dpm.priv;
17467ccd5a2cSjsg 
17477ccd5a2cSjsg 	return pi;
17487ccd5a2cSjsg }
17497ccd5a2cSjsg 
si_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coeffients * coeff,u16 v,s32 t,u32 ileakage,u32 * leakage)17507ccd5a2cSjsg static void si_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coeffients *coeff,
17517ccd5a2cSjsg 						     u16 v, s32 t, u32 ileakage, u32 *leakage)
17527ccd5a2cSjsg {
17537ccd5a2cSjsg 	s64 kt, kv, leakage_w, i_leakage, vddc;
17547ccd5a2cSjsg 	s64 temperature, t_slope, t_intercept, av, bv, t_ref;
17557ccd5a2cSjsg 	s64 tmp;
17567ccd5a2cSjsg 
17577ccd5a2cSjsg 	i_leakage = div64_s64(drm_int2fixp(ileakage), 100);
17587ccd5a2cSjsg 	vddc = div64_s64(drm_int2fixp(v), 1000);
17597ccd5a2cSjsg 	temperature = div64_s64(drm_int2fixp(t), 1000);
17607ccd5a2cSjsg 
17617ccd5a2cSjsg 	t_slope = div64_s64(drm_int2fixp(coeff->t_slope), 100000000);
17627ccd5a2cSjsg 	t_intercept = div64_s64(drm_int2fixp(coeff->t_intercept), 100000000);
17637ccd5a2cSjsg 	av = div64_s64(drm_int2fixp(coeff->av), 100000000);
17647ccd5a2cSjsg 	bv = div64_s64(drm_int2fixp(coeff->bv), 100000000);
17657ccd5a2cSjsg 	t_ref = drm_int2fixp(coeff->t_ref);
17667ccd5a2cSjsg 
17677ccd5a2cSjsg 	tmp = drm_fixp_mul(t_slope, vddc) + t_intercept;
17687ccd5a2cSjsg 	kt = drm_fixp_exp(drm_fixp_mul(tmp, temperature));
17697ccd5a2cSjsg 	kt = drm_fixp_div(kt, drm_fixp_exp(drm_fixp_mul(tmp, t_ref)));
17707ccd5a2cSjsg 	kv = drm_fixp_mul(av, drm_fixp_exp(drm_fixp_mul(bv, vddc)));
17717ccd5a2cSjsg 
17727ccd5a2cSjsg 	leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc);
17737ccd5a2cSjsg 
17747ccd5a2cSjsg 	*leakage = drm_fixp2int(leakage_w * 1000);
17757ccd5a2cSjsg }
17767ccd5a2cSjsg 
si_calculate_leakage_for_v_and_t(struct radeon_device * rdev,const struct ni_leakage_coeffients * coeff,u16 v,s32 t,u32 i_leakage,u32 * leakage)17777ccd5a2cSjsg static void si_calculate_leakage_for_v_and_t(struct radeon_device *rdev,
17787ccd5a2cSjsg 					     const struct ni_leakage_coeffients *coeff,
17797ccd5a2cSjsg 					     u16 v,
17807ccd5a2cSjsg 					     s32 t,
17817ccd5a2cSjsg 					     u32 i_leakage,
17827ccd5a2cSjsg 					     u32 *leakage)
17837ccd5a2cSjsg {
17847ccd5a2cSjsg 	si_calculate_leakage_for_v_and_t_formula(coeff, v, t, i_leakage, leakage);
17857ccd5a2cSjsg }
17867ccd5a2cSjsg 
si_calculate_leakage_for_v_formula(const struct ni_leakage_coeffients * coeff,const u32 fixed_kt,u16 v,u32 ileakage,u32 * leakage)17877ccd5a2cSjsg static void si_calculate_leakage_for_v_formula(const struct ni_leakage_coeffients *coeff,
17887ccd5a2cSjsg 					       const u32 fixed_kt, u16 v,
17897ccd5a2cSjsg 					       u32 ileakage, u32 *leakage)
17907ccd5a2cSjsg {
17917ccd5a2cSjsg 	s64 kt, kv, leakage_w, i_leakage, vddc;
17927ccd5a2cSjsg 
17937ccd5a2cSjsg 	i_leakage = div64_s64(drm_int2fixp(ileakage), 100);
17947ccd5a2cSjsg 	vddc = div64_s64(drm_int2fixp(v), 1000);
17957ccd5a2cSjsg 
17967ccd5a2cSjsg 	kt = div64_s64(drm_int2fixp(fixed_kt), 100000000);
17977ccd5a2cSjsg 	kv = drm_fixp_mul(div64_s64(drm_int2fixp(coeff->av), 100000000),
17987ccd5a2cSjsg 			  drm_fixp_exp(drm_fixp_mul(div64_s64(drm_int2fixp(coeff->bv), 100000000), vddc)));
17997ccd5a2cSjsg 
18007ccd5a2cSjsg 	leakage_w = drm_fixp_mul(drm_fixp_mul(drm_fixp_mul(i_leakage, kt), kv), vddc);
18017ccd5a2cSjsg 
18027ccd5a2cSjsg 	*leakage = drm_fixp2int(leakage_w * 1000);
18037ccd5a2cSjsg }
18047ccd5a2cSjsg 
si_calculate_leakage_for_v(struct radeon_device * rdev,const struct ni_leakage_coeffients * coeff,const u32 fixed_kt,u16 v,u32 i_leakage,u32 * leakage)18057ccd5a2cSjsg static void si_calculate_leakage_for_v(struct radeon_device *rdev,
18067ccd5a2cSjsg 				       const struct ni_leakage_coeffients *coeff,
18077ccd5a2cSjsg 				       const u32 fixed_kt,
18087ccd5a2cSjsg 				       u16 v,
18097ccd5a2cSjsg 				       u32 i_leakage,
18107ccd5a2cSjsg 				       u32 *leakage)
18117ccd5a2cSjsg {
18127ccd5a2cSjsg 	si_calculate_leakage_for_v_formula(coeff, fixed_kt, v, i_leakage, leakage);
18137ccd5a2cSjsg }
18147ccd5a2cSjsg 
18157ccd5a2cSjsg 
si_update_dte_from_pl2(struct radeon_device * rdev,struct si_dte_data * dte_data)18167ccd5a2cSjsg static void si_update_dte_from_pl2(struct radeon_device *rdev,
18177ccd5a2cSjsg 				   struct si_dte_data *dte_data)
18187ccd5a2cSjsg {
18197ccd5a2cSjsg 	u32 p_limit1 = rdev->pm.dpm.tdp_limit;
18207ccd5a2cSjsg 	u32 p_limit2 = rdev->pm.dpm.near_tdp_limit;
18217ccd5a2cSjsg 	u32 k = dte_data->k;
18227ccd5a2cSjsg 	u32 t_max = dte_data->max_t;
18237ccd5a2cSjsg 	u32 t_split[5] = { 10, 15, 20, 25, 30 };
18247ccd5a2cSjsg 	u32 t_0 = dte_data->t0;
18257ccd5a2cSjsg 	u32 i;
18267ccd5a2cSjsg 
18277ccd5a2cSjsg 	if (p_limit2 != 0 && p_limit2 <= p_limit1) {
18287ccd5a2cSjsg 		dte_data->tdep_count = 3;
18297ccd5a2cSjsg 
18307ccd5a2cSjsg 		for (i = 0; i < k; i++) {
18317ccd5a2cSjsg 			dte_data->r[i] =
18327ccd5a2cSjsg 				(t_split[i] * (t_max - t_0/(u32)1000) * (1 << 14)) /
18337ccd5a2cSjsg 				(p_limit2  * (u32)100);
18347ccd5a2cSjsg 		}
18357ccd5a2cSjsg 
18367ccd5a2cSjsg 		dte_data->tdep_r[1] = dte_data->r[4] * 2;
18377ccd5a2cSjsg 
18387ccd5a2cSjsg 		for (i = 2; i < SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE; i++) {
18397ccd5a2cSjsg 			dte_data->tdep_r[i] = dte_data->r[4];
18407ccd5a2cSjsg 		}
18417ccd5a2cSjsg 	} else {
18427ccd5a2cSjsg 		DRM_ERROR("Invalid PL2! DTE will not be updated.\n");
18437ccd5a2cSjsg 	}
18447ccd5a2cSjsg }
18457ccd5a2cSjsg 
si_initialize_powertune_defaults(struct radeon_device * rdev)18467ccd5a2cSjsg static void si_initialize_powertune_defaults(struct radeon_device *rdev)
18477ccd5a2cSjsg {
18487ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
18497ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
18507ccd5a2cSjsg 	bool update_dte_from_pl2 = false;
18517ccd5a2cSjsg 
18527ccd5a2cSjsg 	if (rdev->family == CHIP_TAHITI) {
18537ccd5a2cSjsg 		si_pi->cac_weights = cac_weights_tahiti;
18547ccd5a2cSjsg 		si_pi->lcac_config = lcac_tahiti;
18557ccd5a2cSjsg 		si_pi->cac_override = cac_override_tahiti;
18567ccd5a2cSjsg 		si_pi->powertune_data = &powertune_data_tahiti;
18577ccd5a2cSjsg 		si_pi->dte_data = dte_data_tahiti;
18587ccd5a2cSjsg 
18597ccd5a2cSjsg 		switch (rdev->pdev->device) {
18607ccd5a2cSjsg 		case 0x6798:
18617ccd5a2cSjsg 			si_pi->dte_data.enable_dte_by_default = true;
18627ccd5a2cSjsg 			break;
18637ccd5a2cSjsg 		case 0x6799:
18647ccd5a2cSjsg 			si_pi->dte_data = dte_data_new_zealand;
18657ccd5a2cSjsg 			break;
18667ccd5a2cSjsg 		case 0x6790:
18677ccd5a2cSjsg 		case 0x6791:
18687ccd5a2cSjsg 		case 0x6792:
18697ccd5a2cSjsg 		case 0x679E:
18707ccd5a2cSjsg 			si_pi->dte_data = dte_data_aruba_pro;
18717ccd5a2cSjsg 			update_dte_from_pl2 = true;
18727ccd5a2cSjsg 			break;
18737ccd5a2cSjsg 		case 0x679B:
18747ccd5a2cSjsg 			si_pi->dte_data = dte_data_malta;
18757ccd5a2cSjsg 			update_dte_from_pl2 = true;
18767ccd5a2cSjsg 			break;
18777ccd5a2cSjsg 		case 0x679A:
18787ccd5a2cSjsg 			si_pi->dte_data = dte_data_tahiti_pro;
18797ccd5a2cSjsg 			update_dte_from_pl2 = true;
18807ccd5a2cSjsg 			break;
18817ccd5a2cSjsg 		default:
18827ccd5a2cSjsg 			if (si_pi->dte_data.enable_dte_by_default == true)
18837ccd5a2cSjsg 				DRM_ERROR("DTE is not enabled!\n");
18847ccd5a2cSjsg 			break;
18857ccd5a2cSjsg 		}
18867ccd5a2cSjsg 	} else if (rdev->family == CHIP_PITCAIRN) {
18877ccd5a2cSjsg 		switch (rdev->pdev->device) {
18887ccd5a2cSjsg 		case 0x6810:
18897ccd5a2cSjsg 		case 0x6818:
18907ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_pitcairn;
18917ccd5a2cSjsg 			si_pi->lcac_config = lcac_pitcairn;
18927ccd5a2cSjsg 			si_pi->cac_override = cac_override_pitcairn;
18937ccd5a2cSjsg 			si_pi->powertune_data = &powertune_data_pitcairn;
18947ccd5a2cSjsg 			si_pi->dte_data = dte_data_curacao_xt;
18957ccd5a2cSjsg 			update_dte_from_pl2 = true;
18967ccd5a2cSjsg 			break;
18977ccd5a2cSjsg 		case 0x6819:
18987ccd5a2cSjsg 		case 0x6811:
18997ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_pitcairn;
19007ccd5a2cSjsg 			si_pi->lcac_config = lcac_pitcairn;
19017ccd5a2cSjsg 			si_pi->cac_override = cac_override_pitcairn;
19027ccd5a2cSjsg 			si_pi->powertune_data = &powertune_data_pitcairn;
19037ccd5a2cSjsg 			si_pi->dte_data = dte_data_curacao_pro;
19047ccd5a2cSjsg 			update_dte_from_pl2 = true;
19057ccd5a2cSjsg 			break;
19067ccd5a2cSjsg 		case 0x6800:
19077ccd5a2cSjsg 		case 0x6806:
19087ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_pitcairn;
19097ccd5a2cSjsg 			si_pi->lcac_config = lcac_pitcairn;
19107ccd5a2cSjsg 			si_pi->cac_override = cac_override_pitcairn;
19117ccd5a2cSjsg 			si_pi->powertune_data = &powertune_data_pitcairn;
19127ccd5a2cSjsg 			si_pi->dte_data = dte_data_neptune_xt;
19137ccd5a2cSjsg 			update_dte_from_pl2 = true;
19147ccd5a2cSjsg 			break;
19157ccd5a2cSjsg 		default:
19167ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_pitcairn;
19177ccd5a2cSjsg 			si_pi->lcac_config = lcac_pitcairn;
19187ccd5a2cSjsg 			si_pi->cac_override = cac_override_pitcairn;
19197ccd5a2cSjsg 			si_pi->powertune_data = &powertune_data_pitcairn;
19207ccd5a2cSjsg 			si_pi->dte_data = dte_data_pitcairn;
19217ccd5a2cSjsg 			break;
19227ccd5a2cSjsg 		}
19237ccd5a2cSjsg 	} else if (rdev->family == CHIP_VERDE) {
19247ccd5a2cSjsg 		si_pi->lcac_config = lcac_cape_verde;
19257ccd5a2cSjsg 		si_pi->cac_override = cac_override_cape_verde;
19267ccd5a2cSjsg 		si_pi->powertune_data = &powertune_data_cape_verde;
19277ccd5a2cSjsg 
19287ccd5a2cSjsg 		switch (rdev->pdev->device) {
19297ccd5a2cSjsg 		case 0x683B:
19307ccd5a2cSjsg 		case 0x683F:
19317ccd5a2cSjsg 		case 0x6829:
19327ccd5a2cSjsg 		case 0x6835:
19337ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_cape_verde_pro;
19347ccd5a2cSjsg 			si_pi->dte_data = dte_data_cape_verde;
19357ccd5a2cSjsg 			break;
19367ccd5a2cSjsg 		case 0x682C:
19377ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_cape_verde_pro;
19387ccd5a2cSjsg 			si_pi->dte_data = dte_data_sun_xt;
193939385a27Sjsg 			update_dte_from_pl2 = true;
19407ccd5a2cSjsg 			break;
19417ccd5a2cSjsg 		case 0x6825:
19427ccd5a2cSjsg 		case 0x6827:
19437ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_heathrow;
19447ccd5a2cSjsg 			si_pi->dte_data = dte_data_cape_verde;
19457ccd5a2cSjsg 			break;
19467ccd5a2cSjsg 		case 0x6824:
19477ccd5a2cSjsg 		case 0x682D:
19487ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_chelsea_xt;
19497ccd5a2cSjsg 			si_pi->dte_data = dte_data_cape_verde;
19507ccd5a2cSjsg 			break;
19517ccd5a2cSjsg 		case 0x682F:
19527ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_chelsea_pro;
19537ccd5a2cSjsg 			si_pi->dte_data = dte_data_cape_verde;
19547ccd5a2cSjsg 			break;
19557ccd5a2cSjsg 		case 0x6820:
19567ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_heathrow;
19577ccd5a2cSjsg 			si_pi->dte_data = dte_data_venus_xtx;
19587ccd5a2cSjsg 			break;
19597ccd5a2cSjsg 		case 0x6821:
19607ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_heathrow;
19617ccd5a2cSjsg 			si_pi->dte_data = dte_data_venus_xt;
19627ccd5a2cSjsg 			break;
19637ccd5a2cSjsg 		case 0x6823:
19647ccd5a2cSjsg 		case 0x682B:
19657ccd5a2cSjsg 		case 0x6822:
19667ccd5a2cSjsg 		case 0x682A:
19677ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_chelsea_pro;
19687ccd5a2cSjsg 			si_pi->dte_data = dte_data_venus_pro;
19697ccd5a2cSjsg 			break;
19707ccd5a2cSjsg 		default:
19717ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_cape_verde;
19727ccd5a2cSjsg 			si_pi->dte_data = dte_data_cape_verde;
19737ccd5a2cSjsg 			break;
19747ccd5a2cSjsg 		}
19757ccd5a2cSjsg 	} else if (rdev->family == CHIP_OLAND) {
19767ccd5a2cSjsg 		switch (rdev->pdev->device) {
19777ccd5a2cSjsg 		case 0x6601:
19787ccd5a2cSjsg 		case 0x6621:
19797ccd5a2cSjsg 		case 0x6603:
19807ccd5a2cSjsg 		case 0x6605:
19817ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_mars_pro;
19827ccd5a2cSjsg 			si_pi->lcac_config = lcac_mars_pro;
19837ccd5a2cSjsg 			si_pi->cac_override = cac_override_oland;
19847ccd5a2cSjsg 			si_pi->powertune_data = &powertune_data_mars_pro;
19857ccd5a2cSjsg 			si_pi->dte_data = dte_data_mars_pro;
19867ccd5a2cSjsg 			update_dte_from_pl2 = true;
19877ccd5a2cSjsg 			break;
19887ccd5a2cSjsg 		case 0x6600:
19897ccd5a2cSjsg 		case 0x6606:
19907ccd5a2cSjsg 		case 0x6620:
19917ccd5a2cSjsg 		case 0x6604:
19927ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_mars_xt;
19937ccd5a2cSjsg 			si_pi->lcac_config = lcac_mars_pro;
19947ccd5a2cSjsg 			si_pi->cac_override = cac_override_oland;
19957ccd5a2cSjsg 			si_pi->powertune_data = &powertune_data_mars_pro;
19967ccd5a2cSjsg 			si_pi->dte_data = dte_data_mars_pro;
19977ccd5a2cSjsg 			update_dte_from_pl2 = true;
19987ccd5a2cSjsg 			break;
19997ccd5a2cSjsg 		case 0x6611:
20007ccd5a2cSjsg 		case 0x6613:
20017ccd5a2cSjsg 		case 0x6608:
20027ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_oland_pro;
20037ccd5a2cSjsg 			si_pi->lcac_config = lcac_mars_pro;
20047ccd5a2cSjsg 			si_pi->cac_override = cac_override_oland;
20057ccd5a2cSjsg 			si_pi->powertune_data = &powertune_data_mars_pro;
20067ccd5a2cSjsg 			si_pi->dte_data = dte_data_mars_pro;
20077ccd5a2cSjsg 			update_dte_from_pl2 = true;
20087ccd5a2cSjsg 			break;
20097ccd5a2cSjsg 		case 0x6610:
20107ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_oland_xt;
20117ccd5a2cSjsg 			si_pi->lcac_config = lcac_mars_pro;
20127ccd5a2cSjsg 			si_pi->cac_override = cac_override_oland;
20137ccd5a2cSjsg 			si_pi->powertune_data = &powertune_data_mars_pro;
20147ccd5a2cSjsg 			si_pi->dte_data = dte_data_mars_pro;
20157ccd5a2cSjsg 			update_dte_from_pl2 = true;
20167ccd5a2cSjsg 			break;
20177ccd5a2cSjsg 		default:
20187ccd5a2cSjsg 			si_pi->cac_weights = cac_weights_oland;
20197ccd5a2cSjsg 			si_pi->lcac_config = lcac_oland;
20207ccd5a2cSjsg 			si_pi->cac_override = cac_override_oland;
20217ccd5a2cSjsg 			si_pi->powertune_data = &powertune_data_oland;
20227ccd5a2cSjsg 			si_pi->dte_data = dte_data_oland;
20237ccd5a2cSjsg 			break;
20247ccd5a2cSjsg 		}
20257ccd5a2cSjsg 	} else if (rdev->family == CHIP_HAINAN) {
20267ccd5a2cSjsg 		si_pi->cac_weights = cac_weights_hainan;
20277ccd5a2cSjsg 		si_pi->lcac_config = lcac_oland;
20287ccd5a2cSjsg 		si_pi->cac_override = cac_override_oland;
20297ccd5a2cSjsg 		si_pi->powertune_data = &powertune_data_hainan;
20307ccd5a2cSjsg 		si_pi->dte_data = dte_data_sun_xt;
20317ccd5a2cSjsg 		update_dte_from_pl2 = true;
20327ccd5a2cSjsg 	} else {
20337ccd5a2cSjsg 		DRM_ERROR("Unknown SI asic revision, failed to initialize PowerTune!\n");
20347ccd5a2cSjsg 		return;
20357ccd5a2cSjsg 	}
20367ccd5a2cSjsg 
20377ccd5a2cSjsg 	ni_pi->enable_power_containment = false;
20387ccd5a2cSjsg 	ni_pi->enable_cac = false;
20397ccd5a2cSjsg 	ni_pi->enable_sq_ramping = false;
20407ccd5a2cSjsg 	si_pi->enable_dte = false;
20417ccd5a2cSjsg 
20427ccd5a2cSjsg 	if (si_pi->powertune_data->enable_powertune_by_default) {
20437ccd5a2cSjsg 		ni_pi->enable_power_containment= true;
20447ccd5a2cSjsg 		ni_pi->enable_cac = true;
20457ccd5a2cSjsg 		if (si_pi->dte_data.enable_dte_by_default) {
20467ccd5a2cSjsg 			si_pi->enable_dte = true;
20477ccd5a2cSjsg 			if (update_dte_from_pl2)
20487ccd5a2cSjsg 				si_update_dte_from_pl2(rdev, &si_pi->dte_data);
20497ccd5a2cSjsg 
20507ccd5a2cSjsg 		}
20517ccd5a2cSjsg 		ni_pi->enable_sq_ramping = true;
20527ccd5a2cSjsg 	}
20537ccd5a2cSjsg 
20547ccd5a2cSjsg 	ni_pi->driver_calculate_cac_leakage = true;
20557ccd5a2cSjsg 	ni_pi->cac_configuration_required = true;
20567ccd5a2cSjsg 
20577ccd5a2cSjsg 	if (ni_pi->cac_configuration_required) {
20587ccd5a2cSjsg 		ni_pi->support_cac_long_term_average = true;
20597ccd5a2cSjsg 		si_pi->dyn_powertune_data.l2_lta_window_size =
20607ccd5a2cSjsg 			si_pi->powertune_data->l2_lta_window_size_default;
20617ccd5a2cSjsg 		si_pi->dyn_powertune_data.lts_truncate =
20627ccd5a2cSjsg 			si_pi->powertune_data->lts_truncate_default;
20637ccd5a2cSjsg 	} else {
20647ccd5a2cSjsg 		ni_pi->support_cac_long_term_average = false;
20657ccd5a2cSjsg 		si_pi->dyn_powertune_data.l2_lta_window_size = 0;
20667ccd5a2cSjsg 		si_pi->dyn_powertune_data.lts_truncate = 0;
20677ccd5a2cSjsg 	}
20687ccd5a2cSjsg 
20697ccd5a2cSjsg 	si_pi->dyn_powertune_data.disable_uvd_powertune = false;
20707ccd5a2cSjsg }
20717ccd5a2cSjsg 
si_get_smc_power_scaling_factor(struct radeon_device * rdev)20727ccd5a2cSjsg static u32 si_get_smc_power_scaling_factor(struct radeon_device *rdev)
20737ccd5a2cSjsg {
20747ccd5a2cSjsg 	return 1;
20757ccd5a2cSjsg }
20767ccd5a2cSjsg 
si_calculate_cac_wintime(struct radeon_device * rdev)20777ccd5a2cSjsg static u32 si_calculate_cac_wintime(struct radeon_device *rdev)
20787ccd5a2cSjsg {
20797ccd5a2cSjsg 	u32 xclk;
20807ccd5a2cSjsg 	u32 wintime;
20817ccd5a2cSjsg 	u32 cac_window;
20827ccd5a2cSjsg 	u32 cac_window_size;
20837ccd5a2cSjsg 
20847ccd5a2cSjsg 	xclk = radeon_get_xclk(rdev);
20857ccd5a2cSjsg 
20867ccd5a2cSjsg 	if (xclk == 0)
20877ccd5a2cSjsg 		return 0;
20887ccd5a2cSjsg 
20897ccd5a2cSjsg 	cac_window = RREG32(CG_CAC_CTRL) & CAC_WINDOW_MASK;
20907ccd5a2cSjsg 	cac_window_size = ((cac_window & 0xFFFF0000) >> 16) * (cac_window & 0x0000FFFF);
20917ccd5a2cSjsg 
20927ccd5a2cSjsg 	wintime = (cac_window_size * 100) / xclk;
20937ccd5a2cSjsg 
20947ccd5a2cSjsg 	return wintime;
20957ccd5a2cSjsg }
20967ccd5a2cSjsg 
si_scale_power_for_smc(u32 power_in_watts,u32 scaling_factor)20977ccd5a2cSjsg static u32 si_scale_power_for_smc(u32 power_in_watts, u32 scaling_factor)
20987ccd5a2cSjsg {
20997ccd5a2cSjsg 	return power_in_watts;
21007ccd5a2cSjsg }
21017ccd5a2cSjsg 
si_calculate_adjusted_tdp_limits(struct radeon_device * rdev,bool adjust_polarity,u32 tdp_adjustment,u32 * tdp_limit,u32 * near_tdp_limit)21027ccd5a2cSjsg static int si_calculate_adjusted_tdp_limits(struct radeon_device *rdev,
21037ccd5a2cSjsg 					    bool adjust_polarity,
21047ccd5a2cSjsg 					    u32 tdp_adjustment,
21057ccd5a2cSjsg 					    u32 *tdp_limit,
21067ccd5a2cSjsg 					    u32 *near_tdp_limit)
21077ccd5a2cSjsg {
21087ccd5a2cSjsg 	u32 adjustment_delta, max_tdp_limit;
21097ccd5a2cSjsg 
21107ccd5a2cSjsg 	if (tdp_adjustment > (u32)rdev->pm.dpm.tdp_od_limit)
21117ccd5a2cSjsg 		return -EINVAL;
21127ccd5a2cSjsg 
21137ccd5a2cSjsg 	max_tdp_limit = ((100 + 100) * rdev->pm.dpm.tdp_limit) / 100;
21147ccd5a2cSjsg 
21157ccd5a2cSjsg 	if (adjust_polarity) {
21167ccd5a2cSjsg 		*tdp_limit = ((100 + tdp_adjustment) * rdev->pm.dpm.tdp_limit) / 100;
21177ccd5a2cSjsg 		*near_tdp_limit = rdev->pm.dpm.near_tdp_limit_adjusted + (*tdp_limit - rdev->pm.dpm.tdp_limit);
21187ccd5a2cSjsg 	} else {
21197ccd5a2cSjsg 		*tdp_limit = ((100 - tdp_adjustment) * rdev->pm.dpm.tdp_limit) / 100;
21207ccd5a2cSjsg 		adjustment_delta  = rdev->pm.dpm.tdp_limit - *tdp_limit;
21217ccd5a2cSjsg 		if (adjustment_delta < rdev->pm.dpm.near_tdp_limit_adjusted)
21227ccd5a2cSjsg 			*near_tdp_limit = rdev->pm.dpm.near_tdp_limit_adjusted - adjustment_delta;
21237ccd5a2cSjsg 		else
21247ccd5a2cSjsg 			*near_tdp_limit = 0;
21257ccd5a2cSjsg 	}
21267ccd5a2cSjsg 
21277ccd5a2cSjsg 	if ((*tdp_limit <= 0) || (*tdp_limit > max_tdp_limit))
21287ccd5a2cSjsg 		return -EINVAL;
21297ccd5a2cSjsg 	if ((*near_tdp_limit <= 0) || (*near_tdp_limit > *tdp_limit))
21307ccd5a2cSjsg 		return -EINVAL;
21317ccd5a2cSjsg 
21327ccd5a2cSjsg 	return 0;
21337ccd5a2cSjsg }
21347ccd5a2cSjsg 
si_populate_smc_tdp_limits(struct radeon_device * rdev,struct radeon_ps * radeon_state)21357ccd5a2cSjsg static int si_populate_smc_tdp_limits(struct radeon_device *rdev,
21367ccd5a2cSjsg 				      struct radeon_ps *radeon_state)
21377ccd5a2cSjsg {
21387ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
21397ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
21407ccd5a2cSjsg 
21417ccd5a2cSjsg 	if (ni_pi->enable_power_containment) {
21427ccd5a2cSjsg 		SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable;
21437ccd5a2cSjsg 		PP_SIslands_PAPMParameters *papm_parm;
21447ccd5a2cSjsg 		struct radeon_ppm_table *ppm = rdev->pm.dpm.dyn_state.ppm_table;
21457ccd5a2cSjsg 		u32 scaling_factor = si_get_smc_power_scaling_factor(rdev);
21467ccd5a2cSjsg 		u32 tdp_limit;
21477ccd5a2cSjsg 		u32 near_tdp_limit;
21487ccd5a2cSjsg 		int ret;
21497ccd5a2cSjsg 
21507ccd5a2cSjsg 		if (scaling_factor == 0)
21517ccd5a2cSjsg 			return -EINVAL;
21527ccd5a2cSjsg 
21537ccd5a2cSjsg 		memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE));
21547ccd5a2cSjsg 
21557ccd5a2cSjsg 		ret = si_calculate_adjusted_tdp_limits(rdev,
21567ccd5a2cSjsg 						       false, /* ??? */
21577ccd5a2cSjsg 						       rdev->pm.dpm.tdp_adjustment,
21587ccd5a2cSjsg 						       &tdp_limit,
21597ccd5a2cSjsg 						       &near_tdp_limit);
21607ccd5a2cSjsg 		if (ret)
21617ccd5a2cSjsg 			return ret;
21627ccd5a2cSjsg 
21637ccd5a2cSjsg 		smc_table->dpm2Params.TDPLimit =
21647ccd5a2cSjsg 			cpu_to_be32(si_scale_power_for_smc(tdp_limit, scaling_factor) * 1000);
21657ccd5a2cSjsg 		smc_table->dpm2Params.NearTDPLimit =
21667ccd5a2cSjsg 			cpu_to_be32(si_scale_power_for_smc(near_tdp_limit, scaling_factor) * 1000);
21677ccd5a2cSjsg 		smc_table->dpm2Params.SafePowerLimit =
21687ccd5a2cSjsg 			cpu_to_be32(si_scale_power_for_smc((near_tdp_limit * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100, scaling_factor) * 1000);
21697ccd5a2cSjsg 
21707ccd5a2cSjsg 		ret = si_copy_bytes_to_smc(rdev,
21717ccd5a2cSjsg 					   (si_pi->state_table_start + offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) +
21727ccd5a2cSjsg 						 offsetof(PP_SIslands_DPM2Parameters, TDPLimit)),
21737ccd5a2cSjsg 					   (u8 *)(&(smc_table->dpm2Params.TDPLimit)),
21747ccd5a2cSjsg 					   sizeof(u32) * 3,
21757ccd5a2cSjsg 					   si_pi->sram_end);
21767ccd5a2cSjsg 		if (ret)
21777ccd5a2cSjsg 			return ret;
21787ccd5a2cSjsg 
21797ccd5a2cSjsg 		if (si_pi->enable_ppm) {
21807ccd5a2cSjsg 			papm_parm = &si_pi->papm_parm;
21817ccd5a2cSjsg 			memset(papm_parm, 0, sizeof(PP_SIslands_PAPMParameters));
21827ccd5a2cSjsg 			papm_parm->NearTDPLimitTherm = cpu_to_be32(ppm->dgpu_tdp);
21837ccd5a2cSjsg 			papm_parm->dGPU_T_Limit = cpu_to_be32(ppm->tj_max);
21847ccd5a2cSjsg 			papm_parm->dGPU_T_Warning = cpu_to_be32(95);
21857ccd5a2cSjsg 			papm_parm->dGPU_T_Hysteresis = cpu_to_be32(5);
21867ccd5a2cSjsg 			papm_parm->PlatformPowerLimit = 0xffffffff;
21877ccd5a2cSjsg 			papm_parm->NearTDPLimitPAPM = 0xffffffff;
21887ccd5a2cSjsg 
21897ccd5a2cSjsg 			ret = si_copy_bytes_to_smc(rdev, si_pi->papm_cfg_table_start,
21907ccd5a2cSjsg 						   (u8 *)papm_parm,
21917ccd5a2cSjsg 						   sizeof(PP_SIslands_PAPMParameters),
21927ccd5a2cSjsg 						   si_pi->sram_end);
21937ccd5a2cSjsg 			if (ret)
21947ccd5a2cSjsg 				return ret;
21957ccd5a2cSjsg 		}
21967ccd5a2cSjsg 	}
21977ccd5a2cSjsg 	return 0;
21987ccd5a2cSjsg }
21997ccd5a2cSjsg 
si_populate_smc_tdp_limits_2(struct radeon_device * rdev,struct radeon_ps * radeon_state)22007ccd5a2cSjsg static int si_populate_smc_tdp_limits_2(struct radeon_device *rdev,
22017ccd5a2cSjsg 					struct radeon_ps *radeon_state)
22027ccd5a2cSjsg {
22037ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
22047ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
22057ccd5a2cSjsg 
22067ccd5a2cSjsg 	if (ni_pi->enable_power_containment) {
22077ccd5a2cSjsg 		SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable;
22087ccd5a2cSjsg 		u32 scaling_factor = si_get_smc_power_scaling_factor(rdev);
22097ccd5a2cSjsg 		int ret;
22107ccd5a2cSjsg 
22117ccd5a2cSjsg 		memset(smc_table, 0, sizeof(SISLANDS_SMC_STATETABLE));
22127ccd5a2cSjsg 
22137ccd5a2cSjsg 		smc_table->dpm2Params.NearTDPLimit =
22147ccd5a2cSjsg 			cpu_to_be32(si_scale_power_for_smc(rdev->pm.dpm.near_tdp_limit_adjusted, scaling_factor) * 1000);
22157ccd5a2cSjsg 		smc_table->dpm2Params.SafePowerLimit =
22167ccd5a2cSjsg 			cpu_to_be32(si_scale_power_for_smc((rdev->pm.dpm.near_tdp_limit_adjusted * SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100, scaling_factor) * 1000);
22177ccd5a2cSjsg 
22187ccd5a2cSjsg 		ret = si_copy_bytes_to_smc(rdev,
22197ccd5a2cSjsg 					   (si_pi->state_table_start +
22207ccd5a2cSjsg 					    offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) +
22217ccd5a2cSjsg 					    offsetof(PP_SIslands_DPM2Parameters, NearTDPLimit)),
22227ccd5a2cSjsg 					   (u8 *)(&(smc_table->dpm2Params.NearTDPLimit)),
22237ccd5a2cSjsg 					   sizeof(u32) * 2,
22247ccd5a2cSjsg 					   si_pi->sram_end);
22257ccd5a2cSjsg 		if (ret)
22267ccd5a2cSjsg 			return ret;
22277ccd5a2cSjsg 	}
22287ccd5a2cSjsg 
22297ccd5a2cSjsg 	return 0;
22307ccd5a2cSjsg }
22317ccd5a2cSjsg 
si_calculate_power_efficiency_ratio(struct radeon_device * rdev,const u16 prev_std_vddc,const u16 curr_std_vddc)22327ccd5a2cSjsg static u16 si_calculate_power_efficiency_ratio(struct radeon_device *rdev,
22337ccd5a2cSjsg 					       const u16 prev_std_vddc,
22347ccd5a2cSjsg 					       const u16 curr_std_vddc)
22357ccd5a2cSjsg {
22367ccd5a2cSjsg 	u64 margin = (u64)SISLANDS_DPM2_PWREFFICIENCYRATIO_MARGIN;
22377ccd5a2cSjsg 	u64 prev_vddc = (u64)prev_std_vddc;
22387ccd5a2cSjsg 	u64 curr_vddc = (u64)curr_std_vddc;
22397ccd5a2cSjsg 	u64 pwr_efficiency_ratio, n, d;
22407ccd5a2cSjsg 
22417ccd5a2cSjsg 	if ((prev_vddc == 0) || (curr_vddc == 0))
22427ccd5a2cSjsg 		return 0;
22437ccd5a2cSjsg 
22447ccd5a2cSjsg 	n = div64_u64((u64)1024 * curr_vddc * curr_vddc * ((u64)1000 + margin), (u64)1000);
22457ccd5a2cSjsg 	d = prev_vddc * prev_vddc;
22467ccd5a2cSjsg 	pwr_efficiency_ratio = div64_u64(n, d);
22477ccd5a2cSjsg 
22487ccd5a2cSjsg 	if (pwr_efficiency_ratio > (u64)0xFFFF)
22497ccd5a2cSjsg 		return 0;
22507ccd5a2cSjsg 
22517ccd5a2cSjsg 	return (u16)pwr_efficiency_ratio;
22527ccd5a2cSjsg }
22537ccd5a2cSjsg 
si_should_disable_uvd_powertune(struct radeon_device * rdev,struct radeon_ps * radeon_state)22547ccd5a2cSjsg static bool si_should_disable_uvd_powertune(struct radeon_device *rdev,
22557ccd5a2cSjsg 					    struct radeon_ps *radeon_state)
22567ccd5a2cSjsg {
22577ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
22587ccd5a2cSjsg 
22597ccd5a2cSjsg 	if (si_pi->dyn_powertune_data.disable_uvd_powertune &&
22607ccd5a2cSjsg 	    radeon_state->vclk && radeon_state->dclk)
22617ccd5a2cSjsg 		return true;
22627ccd5a2cSjsg 
22637ccd5a2cSjsg 	return false;
22647ccd5a2cSjsg }
22657ccd5a2cSjsg 
si_populate_power_containment_values(struct radeon_device * rdev,struct radeon_ps * radeon_state,SISLANDS_SMC_SWSTATE * smc_state)22667ccd5a2cSjsg static int si_populate_power_containment_values(struct radeon_device *rdev,
22677ccd5a2cSjsg 						struct radeon_ps *radeon_state,
22687ccd5a2cSjsg 						SISLANDS_SMC_SWSTATE *smc_state)
22697ccd5a2cSjsg {
22707ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
22717ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
22727ccd5a2cSjsg 	struct ni_ps *state = ni_get_ps(radeon_state);
22737ccd5a2cSjsg 	SISLANDS_SMC_VOLTAGE_VALUE vddc;
22747ccd5a2cSjsg 	u32 prev_sclk;
22757ccd5a2cSjsg 	u32 max_sclk;
22767ccd5a2cSjsg 	u32 min_sclk;
22777ccd5a2cSjsg 	u16 prev_std_vddc;
22787ccd5a2cSjsg 	u16 curr_std_vddc;
22797ccd5a2cSjsg 	int i;
22807ccd5a2cSjsg 	u16 pwr_efficiency_ratio;
22817ccd5a2cSjsg 	u8 max_ps_percent;
22827ccd5a2cSjsg 	bool disable_uvd_power_tune;
22837ccd5a2cSjsg 	int ret;
22847ccd5a2cSjsg 
22857ccd5a2cSjsg 	if (ni_pi->enable_power_containment == false)
22867ccd5a2cSjsg 		return 0;
22877ccd5a2cSjsg 
22887ccd5a2cSjsg 	if (state->performance_level_count == 0)
22897ccd5a2cSjsg 		return -EINVAL;
22907ccd5a2cSjsg 
22917ccd5a2cSjsg 	if (smc_state->levelCount != state->performance_level_count)
22927ccd5a2cSjsg 		return -EINVAL;
22937ccd5a2cSjsg 
22947ccd5a2cSjsg 	disable_uvd_power_tune = si_should_disable_uvd_powertune(rdev, radeon_state);
22957ccd5a2cSjsg 
22967ccd5a2cSjsg 	smc_state->levels[0].dpm2.MaxPS = 0;
22977ccd5a2cSjsg 	smc_state->levels[0].dpm2.NearTDPDec = 0;
22987ccd5a2cSjsg 	smc_state->levels[0].dpm2.AboveSafeInc = 0;
22997ccd5a2cSjsg 	smc_state->levels[0].dpm2.BelowSafeInc = 0;
23007ccd5a2cSjsg 	smc_state->levels[0].dpm2.PwrEfficiencyRatio = 0;
23017ccd5a2cSjsg 
23027ccd5a2cSjsg 	for (i = 1; i < state->performance_level_count; i++) {
23037ccd5a2cSjsg 		prev_sclk = state->performance_levels[i-1].sclk;
23047ccd5a2cSjsg 		max_sclk  = state->performance_levels[i].sclk;
23057ccd5a2cSjsg 		if (i == 1)
23067ccd5a2cSjsg 			max_ps_percent = SISLANDS_DPM2_MAXPS_PERCENT_M;
23077ccd5a2cSjsg 		else
23087ccd5a2cSjsg 			max_ps_percent = SISLANDS_DPM2_MAXPS_PERCENT_H;
23097ccd5a2cSjsg 
23107ccd5a2cSjsg 		if (prev_sclk > max_sclk)
23117ccd5a2cSjsg 			return -EINVAL;
23127ccd5a2cSjsg 
23137ccd5a2cSjsg 		if ((max_ps_percent == 0) ||
23147ccd5a2cSjsg 		    (prev_sclk == max_sclk) ||
23157ccd5a2cSjsg 		    disable_uvd_power_tune) {
23167ccd5a2cSjsg 			min_sclk = max_sclk;
23177ccd5a2cSjsg 		} else if (i == 1) {
23187ccd5a2cSjsg 			min_sclk = prev_sclk;
23197ccd5a2cSjsg 		} else {
23207ccd5a2cSjsg 			min_sclk = (prev_sclk * (u32)max_ps_percent) / 100;
23217ccd5a2cSjsg 		}
23227ccd5a2cSjsg 
23237ccd5a2cSjsg 		if (min_sclk < state->performance_levels[0].sclk)
23247ccd5a2cSjsg 			min_sclk = state->performance_levels[0].sclk;
23257ccd5a2cSjsg 
23267ccd5a2cSjsg 		if (min_sclk == 0)
23277ccd5a2cSjsg 			return -EINVAL;
23287ccd5a2cSjsg 
23297ccd5a2cSjsg 		ret = si_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
23307ccd5a2cSjsg 						state->performance_levels[i-1].vddc, &vddc);
23317ccd5a2cSjsg 		if (ret)
23327ccd5a2cSjsg 			return ret;
23337ccd5a2cSjsg 
23347ccd5a2cSjsg 		ret = si_get_std_voltage_value(rdev, &vddc, &prev_std_vddc);
23357ccd5a2cSjsg 		if (ret)
23367ccd5a2cSjsg 			return ret;
23377ccd5a2cSjsg 
23387ccd5a2cSjsg 		ret = si_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
23397ccd5a2cSjsg 						state->performance_levels[i].vddc, &vddc);
23407ccd5a2cSjsg 		if (ret)
23417ccd5a2cSjsg 			return ret;
23427ccd5a2cSjsg 
23437ccd5a2cSjsg 		ret = si_get_std_voltage_value(rdev, &vddc, &curr_std_vddc);
23447ccd5a2cSjsg 		if (ret)
23457ccd5a2cSjsg 			return ret;
23467ccd5a2cSjsg 
23477ccd5a2cSjsg 		pwr_efficiency_ratio = si_calculate_power_efficiency_ratio(rdev,
23487ccd5a2cSjsg 									   prev_std_vddc, curr_std_vddc);
23497ccd5a2cSjsg 
23507ccd5a2cSjsg 		smc_state->levels[i].dpm2.MaxPS = (u8)((SISLANDS_DPM2_MAX_PULSE_SKIP * (max_sclk - min_sclk)) / max_sclk);
23517ccd5a2cSjsg 		smc_state->levels[i].dpm2.NearTDPDec = SISLANDS_DPM2_NEAR_TDP_DEC;
23527ccd5a2cSjsg 		smc_state->levels[i].dpm2.AboveSafeInc = SISLANDS_DPM2_ABOVE_SAFE_INC;
23537ccd5a2cSjsg 		smc_state->levels[i].dpm2.BelowSafeInc = SISLANDS_DPM2_BELOW_SAFE_INC;
23547ccd5a2cSjsg 		smc_state->levels[i].dpm2.PwrEfficiencyRatio = cpu_to_be16(pwr_efficiency_ratio);
23557ccd5a2cSjsg 	}
23567ccd5a2cSjsg 
23577ccd5a2cSjsg 	return 0;
23587ccd5a2cSjsg }
23597ccd5a2cSjsg 
si_populate_sq_ramping_values(struct radeon_device * rdev,struct radeon_ps * radeon_state,SISLANDS_SMC_SWSTATE * smc_state)23607ccd5a2cSjsg static int si_populate_sq_ramping_values(struct radeon_device *rdev,
23617ccd5a2cSjsg 					 struct radeon_ps *radeon_state,
23627ccd5a2cSjsg 					 SISLANDS_SMC_SWSTATE *smc_state)
23637ccd5a2cSjsg {
23647ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
23657ccd5a2cSjsg 	struct ni_ps *state = ni_get_ps(radeon_state);
23667ccd5a2cSjsg 	u32 sq_power_throttle, sq_power_throttle2;
23677ccd5a2cSjsg 	bool enable_sq_ramping = ni_pi->enable_sq_ramping;
23687ccd5a2cSjsg 	int i;
23697ccd5a2cSjsg 
23707ccd5a2cSjsg 	if (state->performance_level_count == 0)
23717ccd5a2cSjsg 		return -EINVAL;
23727ccd5a2cSjsg 
23737ccd5a2cSjsg 	if (smc_state->levelCount != state->performance_level_count)
23747ccd5a2cSjsg 		return -EINVAL;
23757ccd5a2cSjsg 
23767ccd5a2cSjsg 	if (rdev->pm.dpm.sq_ramping_threshold == 0)
23777ccd5a2cSjsg 		return -EINVAL;
23787ccd5a2cSjsg 
23797ccd5a2cSjsg 	if (SISLANDS_DPM2_SQ_RAMP_MAX_POWER > (MAX_POWER_MASK >> MAX_POWER_SHIFT))
23807ccd5a2cSjsg 		enable_sq_ramping = false;
23817ccd5a2cSjsg 
23827ccd5a2cSjsg 	if (SISLANDS_DPM2_SQ_RAMP_MIN_POWER > (MIN_POWER_MASK >> MIN_POWER_SHIFT))
23837ccd5a2cSjsg 		enable_sq_ramping = false;
23847ccd5a2cSjsg 
23857ccd5a2cSjsg 	if (SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA > (MAX_POWER_DELTA_MASK >> MAX_POWER_DELTA_SHIFT))
23867ccd5a2cSjsg 		enable_sq_ramping = false;
23877ccd5a2cSjsg 
23887ccd5a2cSjsg 	if (SISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT))
23897ccd5a2cSjsg 		enable_sq_ramping = false;
23907ccd5a2cSjsg 
23917ccd5a2cSjsg 	if (SISLANDS_DPM2_SQ_RAMP_LTI_RATIO > (LTI_RATIO_MASK >> LTI_RATIO_SHIFT))
23927ccd5a2cSjsg 		enable_sq_ramping = false;
23937ccd5a2cSjsg 
23947ccd5a2cSjsg 	for (i = 0; i < state->performance_level_count; i++) {
23957ccd5a2cSjsg 		sq_power_throttle = 0;
23967ccd5a2cSjsg 		sq_power_throttle2 = 0;
23977ccd5a2cSjsg 
23987ccd5a2cSjsg 		if ((state->performance_levels[i].sclk >= rdev->pm.dpm.sq_ramping_threshold) &&
23997ccd5a2cSjsg 		    enable_sq_ramping) {
24007ccd5a2cSjsg 			sq_power_throttle |= MAX_POWER(SISLANDS_DPM2_SQ_RAMP_MAX_POWER);
24017ccd5a2cSjsg 			sq_power_throttle |= MIN_POWER(SISLANDS_DPM2_SQ_RAMP_MIN_POWER);
24027ccd5a2cSjsg 			sq_power_throttle2 |= MAX_POWER_DELTA(SISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA);
24037ccd5a2cSjsg 			sq_power_throttle2 |= STI_SIZE(SISLANDS_DPM2_SQ_RAMP_STI_SIZE);
24047ccd5a2cSjsg 			sq_power_throttle2 |= LTI_RATIO(SISLANDS_DPM2_SQ_RAMP_LTI_RATIO);
24057ccd5a2cSjsg 		} else {
24067ccd5a2cSjsg 			sq_power_throttle |= MAX_POWER_MASK | MIN_POWER_MASK;
24077ccd5a2cSjsg 			sq_power_throttle2 |= MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
24087ccd5a2cSjsg 		}
24097ccd5a2cSjsg 
24107ccd5a2cSjsg 		smc_state->levels[i].SQPowerThrottle = cpu_to_be32(sq_power_throttle);
24117ccd5a2cSjsg 		smc_state->levels[i].SQPowerThrottle_2 = cpu_to_be32(sq_power_throttle2);
24127ccd5a2cSjsg 	}
24137ccd5a2cSjsg 
24147ccd5a2cSjsg 	return 0;
24157ccd5a2cSjsg }
24167ccd5a2cSjsg 
si_enable_power_containment(struct radeon_device * rdev,struct radeon_ps * radeon_new_state,bool enable)24177ccd5a2cSjsg static int si_enable_power_containment(struct radeon_device *rdev,
24187ccd5a2cSjsg 				       struct radeon_ps *radeon_new_state,
24197ccd5a2cSjsg 				       bool enable)
24207ccd5a2cSjsg {
24217ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
24227ccd5a2cSjsg 	PPSMC_Result smc_result;
24237ccd5a2cSjsg 	int ret = 0;
24247ccd5a2cSjsg 
24257ccd5a2cSjsg 	if (ni_pi->enable_power_containment) {
24267ccd5a2cSjsg 		if (enable) {
24277ccd5a2cSjsg 			if (!si_should_disable_uvd_powertune(rdev, radeon_new_state)) {
24287ccd5a2cSjsg 				smc_result = si_send_msg_to_smc(rdev, PPSMC_TDPClampingActive);
24297ccd5a2cSjsg 				if (smc_result != PPSMC_Result_OK) {
24307ccd5a2cSjsg 					ret = -EINVAL;
24317ccd5a2cSjsg 					ni_pi->pc_enabled = false;
24327ccd5a2cSjsg 				} else {
24337ccd5a2cSjsg 					ni_pi->pc_enabled = true;
24347ccd5a2cSjsg 				}
24357ccd5a2cSjsg 			}
24367ccd5a2cSjsg 		} else {
24377ccd5a2cSjsg 			smc_result = si_send_msg_to_smc(rdev, PPSMC_TDPClampingInactive);
24387ccd5a2cSjsg 			if (smc_result != PPSMC_Result_OK)
24397ccd5a2cSjsg 				ret = -EINVAL;
24407ccd5a2cSjsg 			ni_pi->pc_enabled = false;
24417ccd5a2cSjsg 		}
24427ccd5a2cSjsg 	}
24437ccd5a2cSjsg 
24447ccd5a2cSjsg 	return ret;
24457ccd5a2cSjsg }
24467ccd5a2cSjsg 
si_initialize_smc_dte_tables(struct radeon_device * rdev)24477ccd5a2cSjsg static int si_initialize_smc_dte_tables(struct radeon_device *rdev)
24487ccd5a2cSjsg {
24497ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
24507ccd5a2cSjsg 	int ret = 0;
24517ccd5a2cSjsg 	struct si_dte_data *dte_data = &si_pi->dte_data;
24527ccd5a2cSjsg 	Smc_SIslands_DTE_Configuration *dte_tables = NULL;
24537ccd5a2cSjsg 	u32 table_size;
24547ccd5a2cSjsg 	u8 tdep_count;
24557ccd5a2cSjsg 	u32 i;
24567ccd5a2cSjsg 
24577ccd5a2cSjsg 	if (dte_data == NULL)
24587ccd5a2cSjsg 		si_pi->enable_dte = false;
24597ccd5a2cSjsg 
24607ccd5a2cSjsg 	if (si_pi->enable_dte == false)
24617ccd5a2cSjsg 		return 0;
24627ccd5a2cSjsg 
24637ccd5a2cSjsg 	if (dte_data->k <= 0)
24647ccd5a2cSjsg 		return -EINVAL;
24657ccd5a2cSjsg 
24667ccd5a2cSjsg 	dte_tables = kzalloc(sizeof(Smc_SIslands_DTE_Configuration), GFP_KERNEL);
24677ccd5a2cSjsg 	if (dte_tables == NULL) {
24687ccd5a2cSjsg 		si_pi->enable_dte = false;
24697ccd5a2cSjsg 		return -ENOMEM;
24707ccd5a2cSjsg 	}
24717ccd5a2cSjsg 
24727ccd5a2cSjsg 	table_size = dte_data->k;
24737ccd5a2cSjsg 
24747ccd5a2cSjsg 	if (table_size > SMC_SISLANDS_DTE_MAX_FILTER_STAGES)
24757ccd5a2cSjsg 		table_size = SMC_SISLANDS_DTE_MAX_FILTER_STAGES;
24767ccd5a2cSjsg 
24777ccd5a2cSjsg 	tdep_count = dte_data->tdep_count;
24787ccd5a2cSjsg 	if (tdep_count > SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE)
24797ccd5a2cSjsg 		tdep_count = SMC_SISLANDS_DTE_MAX_TEMPERATURE_DEPENDENT_ARRAY_SIZE;
24807ccd5a2cSjsg 
24817ccd5a2cSjsg 	dte_tables->K = cpu_to_be32(table_size);
24827ccd5a2cSjsg 	dte_tables->T0 = cpu_to_be32(dte_data->t0);
24837ccd5a2cSjsg 	dte_tables->MaxT = cpu_to_be32(dte_data->max_t);
24847ccd5a2cSjsg 	dte_tables->WindowSize = dte_data->window_size;
24857ccd5a2cSjsg 	dte_tables->temp_select = dte_data->temp_select;
24867ccd5a2cSjsg 	dte_tables->DTE_mode = dte_data->dte_mode;
24877ccd5a2cSjsg 	dte_tables->Tthreshold = cpu_to_be32(dte_data->t_threshold);
24887ccd5a2cSjsg 
24897ccd5a2cSjsg 	if (tdep_count > 0)
24907ccd5a2cSjsg 		table_size--;
24917ccd5a2cSjsg 
24927ccd5a2cSjsg 	for (i = 0; i < table_size; i++) {
24937ccd5a2cSjsg 		dte_tables->tau[i] = cpu_to_be32(dte_data->tau[i]);
24947ccd5a2cSjsg 		dte_tables->R[i]   = cpu_to_be32(dte_data->r[i]);
24957ccd5a2cSjsg 	}
24967ccd5a2cSjsg 
24977ccd5a2cSjsg 	dte_tables->Tdep_count = tdep_count;
24987ccd5a2cSjsg 
24997ccd5a2cSjsg 	for (i = 0; i < (u32)tdep_count; i++) {
25007ccd5a2cSjsg 		dte_tables->T_limits[i] = dte_data->t_limits[i];
25017ccd5a2cSjsg 		dte_tables->Tdep_tau[i] = cpu_to_be32(dte_data->tdep_tau[i]);
25027ccd5a2cSjsg 		dte_tables->Tdep_R[i] = cpu_to_be32(dte_data->tdep_r[i]);
25037ccd5a2cSjsg 	}
25047ccd5a2cSjsg 
25057ccd5a2cSjsg 	ret = si_copy_bytes_to_smc(rdev, si_pi->dte_table_start, (u8 *)dte_tables,
25067ccd5a2cSjsg 				   sizeof(Smc_SIslands_DTE_Configuration), si_pi->sram_end);
25077ccd5a2cSjsg 	kfree(dte_tables);
25087ccd5a2cSjsg 
25097ccd5a2cSjsg 	return ret;
25107ccd5a2cSjsg }
25117ccd5a2cSjsg 
si_get_cac_std_voltage_max_min(struct radeon_device * rdev,u16 * max,u16 * min)25127ccd5a2cSjsg static int si_get_cac_std_voltage_max_min(struct radeon_device *rdev,
25137ccd5a2cSjsg 					  u16 *max, u16 *min)
25147ccd5a2cSjsg {
25157ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
25167ccd5a2cSjsg 	struct radeon_cac_leakage_table *table =
25177ccd5a2cSjsg 		&rdev->pm.dpm.dyn_state.cac_leakage_table;
25187ccd5a2cSjsg 	u32 i;
25197ccd5a2cSjsg 	u32 v0_loadline;
25207ccd5a2cSjsg 
25217ccd5a2cSjsg 
25227ccd5a2cSjsg 	if (table == NULL)
25237ccd5a2cSjsg 		return -EINVAL;
25247ccd5a2cSjsg 
25257ccd5a2cSjsg 	*max = 0;
25267ccd5a2cSjsg 	*min = 0xFFFF;
25277ccd5a2cSjsg 
25287ccd5a2cSjsg 	for (i = 0; i < table->count; i++) {
25297ccd5a2cSjsg 		if (table->entries[i].vddc > *max)
25307ccd5a2cSjsg 			*max = table->entries[i].vddc;
25317ccd5a2cSjsg 		if (table->entries[i].vddc < *min)
25327ccd5a2cSjsg 			*min = table->entries[i].vddc;
25337ccd5a2cSjsg 	}
25347ccd5a2cSjsg 
25357ccd5a2cSjsg 	if (si_pi->powertune_data->lkge_lut_v0_percent > 100)
25367ccd5a2cSjsg 		return -EINVAL;
25377ccd5a2cSjsg 
25387ccd5a2cSjsg 	v0_loadline = (*min) * (100 - si_pi->powertune_data->lkge_lut_v0_percent) / 100;
25397ccd5a2cSjsg 
25407ccd5a2cSjsg 	if (v0_loadline > 0xFFFFUL)
25417ccd5a2cSjsg 		return -EINVAL;
25427ccd5a2cSjsg 
25437ccd5a2cSjsg 	*min = (u16)v0_loadline;
25447ccd5a2cSjsg 
25457ccd5a2cSjsg 	if ((*min > *max) || (*max == 0) || (*min == 0))
25467ccd5a2cSjsg 		return -EINVAL;
25477ccd5a2cSjsg 
25487ccd5a2cSjsg 	return 0;
25497ccd5a2cSjsg }
25507ccd5a2cSjsg 
si_get_cac_std_voltage_step(u16 max,u16 min)25517ccd5a2cSjsg static u16 si_get_cac_std_voltage_step(u16 max, u16 min)
25527ccd5a2cSjsg {
25537ccd5a2cSjsg 	return ((max - min) + (SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1)) /
25547ccd5a2cSjsg 		SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES;
25557ccd5a2cSjsg }
25567ccd5a2cSjsg 
si_init_dte_leakage_table(struct radeon_device * rdev,PP_SIslands_CacConfig * cac_tables,u16 vddc_max,u16 vddc_min,u16 vddc_step,u16 t0,u16 t_step)25577ccd5a2cSjsg static int si_init_dte_leakage_table(struct radeon_device *rdev,
25587ccd5a2cSjsg 				     PP_SIslands_CacConfig *cac_tables,
25597ccd5a2cSjsg 				     u16 vddc_max, u16 vddc_min, u16 vddc_step,
25607ccd5a2cSjsg 				     u16 t0, u16 t_step)
25617ccd5a2cSjsg {
25627ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
25637ccd5a2cSjsg 	u32 leakage;
25647ccd5a2cSjsg 	unsigned int i, j;
25657ccd5a2cSjsg 	s32 t;
25667ccd5a2cSjsg 	u32 smc_leakage;
25677ccd5a2cSjsg 	u32 scaling_factor;
25687ccd5a2cSjsg 	u16 voltage;
25697ccd5a2cSjsg 
25707ccd5a2cSjsg 	scaling_factor = si_get_smc_power_scaling_factor(rdev);
25717ccd5a2cSjsg 
25727ccd5a2cSjsg 	for (i = 0; i < SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES ; i++) {
25737ccd5a2cSjsg 		t = (1000 * (i * t_step + t0));
25747ccd5a2cSjsg 
25757ccd5a2cSjsg 		for (j = 0; j < SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
25767ccd5a2cSjsg 			voltage = vddc_max - (vddc_step * j);
25777ccd5a2cSjsg 
25787ccd5a2cSjsg 			si_calculate_leakage_for_v_and_t(rdev,
25797ccd5a2cSjsg 							 &si_pi->powertune_data->leakage_coefficients,
25807ccd5a2cSjsg 							 voltage,
25817ccd5a2cSjsg 							 t,
25827ccd5a2cSjsg 							 si_pi->dyn_powertune_data.cac_leakage,
25837ccd5a2cSjsg 							 &leakage);
25847ccd5a2cSjsg 
25857ccd5a2cSjsg 			smc_leakage = si_scale_power_for_smc(leakage, scaling_factor) / 4;
25867ccd5a2cSjsg 
25877ccd5a2cSjsg 			if (smc_leakage > 0xFFFF)
25887ccd5a2cSjsg 				smc_leakage = 0xFFFF;
25897ccd5a2cSjsg 
25907ccd5a2cSjsg 			cac_tables->cac_lkge_lut[i][SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES-1-j] =
25917ccd5a2cSjsg 				cpu_to_be16((u16)smc_leakage);
25927ccd5a2cSjsg 		}
25937ccd5a2cSjsg 	}
25947ccd5a2cSjsg 	return 0;
25957ccd5a2cSjsg }
25967ccd5a2cSjsg 
si_init_simplified_leakage_table(struct radeon_device * rdev,PP_SIslands_CacConfig * cac_tables,u16 vddc_max,u16 vddc_min,u16 vddc_step)25977ccd5a2cSjsg static int si_init_simplified_leakage_table(struct radeon_device *rdev,
25987ccd5a2cSjsg 					    PP_SIslands_CacConfig *cac_tables,
25997ccd5a2cSjsg 					    u16 vddc_max, u16 vddc_min, u16 vddc_step)
26007ccd5a2cSjsg {
26017ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
26027ccd5a2cSjsg 	u32 leakage;
26037ccd5a2cSjsg 	unsigned int i, j;
26047ccd5a2cSjsg 	u32 smc_leakage;
26057ccd5a2cSjsg 	u32 scaling_factor;
26067ccd5a2cSjsg 	u16 voltage;
26077ccd5a2cSjsg 
26087ccd5a2cSjsg 	scaling_factor = si_get_smc_power_scaling_factor(rdev);
26097ccd5a2cSjsg 
26107ccd5a2cSjsg 	for (j = 0; j < SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
26117ccd5a2cSjsg 		voltage = vddc_max - (vddc_step * j);
26127ccd5a2cSjsg 
26137ccd5a2cSjsg 		si_calculate_leakage_for_v(rdev,
26147ccd5a2cSjsg 					   &si_pi->powertune_data->leakage_coefficients,
26157ccd5a2cSjsg 					   si_pi->powertune_data->fixed_kt,
26167ccd5a2cSjsg 					   voltage,
26177ccd5a2cSjsg 					   si_pi->dyn_powertune_data.cac_leakage,
26187ccd5a2cSjsg 					   &leakage);
26197ccd5a2cSjsg 
26207ccd5a2cSjsg 		smc_leakage = si_scale_power_for_smc(leakage, scaling_factor) / 4;
26217ccd5a2cSjsg 
26227ccd5a2cSjsg 		if (smc_leakage > 0xFFFF)
26237ccd5a2cSjsg 			smc_leakage = 0xFFFF;
26247ccd5a2cSjsg 
26257ccd5a2cSjsg 		for (i = 0; i < SMC_SISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES ; i++)
26267ccd5a2cSjsg 			cac_tables->cac_lkge_lut[i][SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES-1-j] =
26277ccd5a2cSjsg 				cpu_to_be16((u16)smc_leakage);
26287ccd5a2cSjsg 	}
26297ccd5a2cSjsg 	return 0;
26307ccd5a2cSjsg }
26317ccd5a2cSjsg 
si_initialize_smc_cac_tables(struct radeon_device * rdev)26327ccd5a2cSjsg static int si_initialize_smc_cac_tables(struct radeon_device *rdev)
26337ccd5a2cSjsg {
26347ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
26357ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
26367ccd5a2cSjsg 	PP_SIslands_CacConfig *cac_tables = NULL;
26377ccd5a2cSjsg 	u16 vddc_max, vddc_min, vddc_step;
26387ccd5a2cSjsg 	u16 t0, t_step;
26397ccd5a2cSjsg 	u32 load_line_slope, reg;
26407ccd5a2cSjsg 	int ret = 0;
26417ccd5a2cSjsg 	u32 ticks_per_us = radeon_get_xclk(rdev) / 100;
26427ccd5a2cSjsg 
26437ccd5a2cSjsg 	if (ni_pi->enable_cac == false)
26447ccd5a2cSjsg 		return 0;
26457ccd5a2cSjsg 
26467ccd5a2cSjsg 	cac_tables = kzalloc(sizeof(PP_SIslands_CacConfig), GFP_KERNEL);
26477ccd5a2cSjsg 	if (!cac_tables)
26487ccd5a2cSjsg 		return -ENOMEM;
26497ccd5a2cSjsg 
26507ccd5a2cSjsg 	reg = RREG32(CG_CAC_CTRL) & ~CAC_WINDOW_MASK;
26517ccd5a2cSjsg 	reg |= CAC_WINDOW(si_pi->powertune_data->cac_window);
26527ccd5a2cSjsg 	WREG32(CG_CAC_CTRL, reg);
26537ccd5a2cSjsg 
26547ccd5a2cSjsg 	si_pi->dyn_powertune_data.cac_leakage = rdev->pm.dpm.cac_leakage;
26557ccd5a2cSjsg 	si_pi->dyn_powertune_data.dc_pwr_value =
26567ccd5a2cSjsg 		si_pi->powertune_data->dc_cac[NISLANDS_DCCAC_LEVEL_0];
26577ccd5a2cSjsg 	si_pi->dyn_powertune_data.wintime = si_calculate_cac_wintime(rdev);
26587ccd5a2cSjsg 	si_pi->dyn_powertune_data.shift_n = si_pi->powertune_data->shift_n_default;
26597ccd5a2cSjsg 
26607ccd5a2cSjsg 	si_pi->dyn_powertune_data.leakage_minimum_temperature = 80 * 1000;
26617ccd5a2cSjsg 
26627ccd5a2cSjsg 	ret = si_get_cac_std_voltage_max_min(rdev, &vddc_max, &vddc_min);
26637ccd5a2cSjsg 	if (ret)
26647ccd5a2cSjsg 		goto done_free;
26657ccd5a2cSjsg 
26667ccd5a2cSjsg 	vddc_step = si_get_cac_std_voltage_step(vddc_max, vddc_min);
26677ccd5a2cSjsg 	vddc_min = vddc_max - (vddc_step * (SMC_SISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES - 1));
26687ccd5a2cSjsg 	t_step = 4;
26697ccd5a2cSjsg 	t0 = 60;
26707ccd5a2cSjsg 
26717ccd5a2cSjsg 	if (si_pi->enable_dte || ni_pi->driver_calculate_cac_leakage)
26727ccd5a2cSjsg 		ret = si_init_dte_leakage_table(rdev, cac_tables,
26737ccd5a2cSjsg 						vddc_max, vddc_min, vddc_step,
26747ccd5a2cSjsg 						t0, t_step);
26757ccd5a2cSjsg 	else
26767ccd5a2cSjsg 		ret = si_init_simplified_leakage_table(rdev, cac_tables,
26777ccd5a2cSjsg 						       vddc_max, vddc_min, vddc_step);
26787ccd5a2cSjsg 	if (ret)
26797ccd5a2cSjsg 		goto done_free;
26807ccd5a2cSjsg 
26817ccd5a2cSjsg 	load_line_slope = ((u32)rdev->pm.dpm.load_line_slope << SMC_SISLANDS_SCALE_R) / 100;
26827ccd5a2cSjsg 
26837ccd5a2cSjsg 	cac_tables->l2numWin_TDP = cpu_to_be32(si_pi->dyn_powertune_data.l2_lta_window_size);
26847ccd5a2cSjsg 	cac_tables->lts_truncate_n = si_pi->dyn_powertune_data.lts_truncate;
26857ccd5a2cSjsg 	cac_tables->SHIFT_N = si_pi->dyn_powertune_data.shift_n;
26867ccd5a2cSjsg 	cac_tables->lkge_lut_V0 = cpu_to_be32((u32)vddc_min);
26877ccd5a2cSjsg 	cac_tables->lkge_lut_Vstep = cpu_to_be32((u32)vddc_step);
26887ccd5a2cSjsg 	cac_tables->R_LL = cpu_to_be32(load_line_slope);
26897ccd5a2cSjsg 	cac_tables->WinTime = cpu_to_be32(si_pi->dyn_powertune_data.wintime);
26907ccd5a2cSjsg 	cac_tables->calculation_repeats = cpu_to_be32(2);
26917ccd5a2cSjsg 	cac_tables->dc_cac = cpu_to_be32(0);
26927ccd5a2cSjsg 	cac_tables->log2_PG_LKG_SCALE = 12;
26937ccd5a2cSjsg 	cac_tables->cac_temp = si_pi->powertune_data->operating_temp;
26947ccd5a2cSjsg 	cac_tables->lkge_lut_T0 = cpu_to_be32((u32)t0);
26957ccd5a2cSjsg 	cac_tables->lkge_lut_Tstep = cpu_to_be32((u32)t_step);
26967ccd5a2cSjsg 
26977ccd5a2cSjsg 	ret = si_copy_bytes_to_smc(rdev, si_pi->cac_table_start, (u8 *)cac_tables,
26987ccd5a2cSjsg 				   sizeof(PP_SIslands_CacConfig), si_pi->sram_end);
26997ccd5a2cSjsg 
27007ccd5a2cSjsg 	if (ret)
27017ccd5a2cSjsg 		goto done_free;
27027ccd5a2cSjsg 
27037ccd5a2cSjsg 	ret = si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_ticks_per_us, ticks_per_us);
27047ccd5a2cSjsg 
27057ccd5a2cSjsg done_free:
27067ccd5a2cSjsg 	if (ret) {
27077ccd5a2cSjsg 		ni_pi->enable_cac = false;
27087ccd5a2cSjsg 		ni_pi->enable_power_containment = false;
27097ccd5a2cSjsg 	}
27107ccd5a2cSjsg 
27117ccd5a2cSjsg 	kfree(cac_tables);
27127ccd5a2cSjsg 
27137ccd5a2cSjsg 	return 0;
27147ccd5a2cSjsg }
27157ccd5a2cSjsg 
si_program_cac_config_registers(struct radeon_device * rdev,const struct si_cac_config_reg * cac_config_regs)27167ccd5a2cSjsg static int si_program_cac_config_registers(struct radeon_device *rdev,
27177ccd5a2cSjsg 					   const struct si_cac_config_reg *cac_config_regs)
27187ccd5a2cSjsg {
27197ccd5a2cSjsg 	const struct si_cac_config_reg *config_regs = cac_config_regs;
27207ccd5a2cSjsg 	u32 data = 0, offset;
27217ccd5a2cSjsg 
27227ccd5a2cSjsg 	if (!config_regs)
27237ccd5a2cSjsg 		return -EINVAL;
27247ccd5a2cSjsg 
27257ccd5a2cSjsg 	while (config_regs->offset != 0xFFFFFFFF) {
27267ccd5a2cSjsg 		switch (config_regs->type) {
27277ccd5a2cSjsg 		case SISLANDS_CACCONFIG_CGIND:
27287ccd5a2cSjsg 			offset = SMC_CG_IND_START + config_regs->offset;
27297ccd5a2cSjsg 			if (offset < SMC_CG_IND_END)
27307ccd5a2cSjsg 				data = RREG32_SMC(offset);
27317ccd5a2cSjsg 			break;
27327ccd5a2cSjsg 		default:
27337ccd5a2cSjsg 			data = RREG32(config_regs->offset << 2);
27347ccd5a2cSjsg 			break;
27357ccd5a2cSjsg 		}
27367ccd5a2cSjsg 
27377ccd5a2cSjsg 		data &= ~config_regs->mask;
27387ccd5a2cSjsg 		data |= ((config_regs->value << config_regs->shift) & config_regs->mask);
27397ccd5a2cSjsg 
27407ccd5a2cSjsg 		switch (config_regs->type) {
27417ccd5a2cSjsg 		case SISLANDS_CACCONFIG_CGIND:
27427ccd5a2cSjsg 			offset = SMC_CG_IND_START + config_regs->offset;
27437ccd5a2cSjsg 			if (offset < SMC_CG_IND_END)
27447ccd5a2cSjsg 				WREG32_SMC(offset, data);
27457ccd5a2cSjsg 			break;
27467ccd5a2cSjsg 		default:
27477ccd5a2cSjsg 			WREG32(config_regs->offset << 2, data);
27487ccd5a2cSjsg 			break;
27497ccd5a2cSjsg 		}
27507ccd5a2cSjsg 		config_regs++;
27517ccd5a2cSjsg 	}
27527ccd5a2cSjsg 	return 0;
27537ccd5a2cSjsg }
27547ccd5a2cSjsg 
si_initialize_hardware_cac_manager(struct radeon_device * rdev)27557ccd5a2cSjsg static int si_initialize_hardware_cac_manager(struct radeon_device *rdev)
27567ccd5a2cSjsg {
27577ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
27587ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
27597ccd5a2cSjsg 	int ret;
27607ccd5a2cSjsg 
27617ccd5a2cSjsg 	if ((ni_pi->enable_cac == false) ||
27627ccd5a2cSjsg 	    (ni_pi->cac_configuration_required == false))
27637ccd5a2cSjsg 		return 0;
27647ccd5a2cSjsg 
27657ccd5a2cSjsg 	ret = si_program_cac_config_registers(rdev, si_pi->lcac_config);
27667ccd5a2cSjsg 	if (ret)
27677ccd5a2cSjsg 		return ret;
27687ccd5a2cSjsg 	ret = si_program_cac_config_registers(rdev, si_pi->cac_override);
27697ccd5a2cSjsg 	if (ret)
27707ccd5a2cSjsg 		return ret;
27717ccd5a2cSjsg 	ret = si_program_cac_config_registers(rdev, si_pi->cac_weights);
27727ccd5a2cSjsg 	if (ret)
27737ccd5a2cSjsg 		return ret;
27747ccd5a2cSjsg 
27757ccd5a2cSjsg 	return 0;
27767ccd5a2cSjsg }
27777ccd5a2cSjsg 
si_enable_smc_cac(struct radeon_device * rdev,struct radeon_ps * radeon_new_state,bool enable)27787ccd5a2cSjsg static int si_enable_smc_cac(struct radeon_device *rdev,
27797ccd5a2cSjsg 			     struct radeon_ps *radeon_new_state,
27807ccd5a2cSjsg 			     bool enable)
27817ccd5a2cSjsg {
27827ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
27837ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
27847ccd5a2cSjsg 	PPSMC_Result smc_result;
27857ccd5a2cSjsg 	int ret = 0;
27867ccd5a2cSjsg 
27877ccd5a2cSjsg 	if (ni_pi->enable_cac) {
27887ccd5a2cSjsg 		if (enable) {
27897ccd5a2cSjsg 			if (!si_should_disable_uvd_powertune(rdev, radeon_new_state)) {
27907ccd5a2cSjsg 				if (ni_pi->support_cac_long_term_average) {
27917ccd5a2cSjsg 					smc_result = si_send_msg_to_smc(rdev, PPSMC_CACLongTermAvgEnable);
27927ccd5a2cSjsg 					if (smc_result != PPSMC_Result_OK)
27937ccd5a2cSjsg 						ni_pi->support_cac_long_term_average = false;
27947ccd5a2cSjsg 				}
27957ccd5a2cSjsg 
27967ccd5a2cSjsg 				smc_result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableCac);
27977ccd5a2cSjsg 				if (smc_result != PPSMC_Result_OK) {
27987ccd5a2cSjsg 					ret = -EINVAL;
27997ccd5a2cSjsg 					ni_pi->cac_enabled = false;
28007ccd5a2cSjsg 				} else {
28017ccd5a2cSjsg 					ni_pi->cac_enabled = true;
28027ccd5a2cSjsg 				}
28037ccd5a2cSjsg 
28047ccd5a2cSjsg 				if (si_pi->enable_dte) {
28057ccd5a2cSjsg 					smc_result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableDTE);
28067ccd5a2cSjsg 					if (smc_result != PPSMC_Result_OK)
28077ccd5a2cSjsg 						ret = -EINVAL;
28087ccd5a2cSjsg 				}
28097ccd5a2cSjsg 			}
28107ccd5a2cSjsg 		} else if (ni_pi->cac_enabled) {
28117ccd5a2cSjsg 			if (si_pi->enable_dte)
28127ccd5a2cSjsg 				smc_result = si_send_msg_to_smc(rdev, PPSMC_MSG_DisableDTE);
28137ccd5a2cSjsg 
28147ccd5a2cSjsg 			smc_result = si_send_msg_to_smc(rdev, PPSMC_MSG_DisableCac);
28157ccd5a2cSjsg 
28167ccd5a2cSjsg 			ni_pi->cac_enabled = false;
28177ccd5a2cSjsg 
28187ccd5a2cSjsg 			if (ni_pi->support_cac_long_term_average)
28197ccd5a2cSjsg 				smc_result = si_send_msg_to_smc(rdev, PPSMC_CACLongTermAvgDisable);
28207ccd5a2cSjsg 		}
28217ccd5a2cSjsg 	}
28227ccd5a2cSjsg 	return ret;
28237ccd5a2cSjsg }
28247ccd5a2cSjsg 
si_init_smc_spll_table(struct radeon_device * rdev)28257ccd5a2cSjsg static int si_init_smc_spll_table(struct radeon_device *rdev)
28267ccd5a2cSjsg {
28277ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
28287ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
28297ccd5a2cSjsg 	SMC_SISLANDS_SPLL_DIV_TABLE *spll_table;
28307ccd5a2cSjsg 	SISLANDS_SMC_SCLK_VALUE sclk_params;
28317ccd5a2cSjsg 	u32 fb_div, p_div;
28327ccd5a2cSjsg 	u32 clk_s, clk_v;
28337ccd5a2cSjsg 	u32 sclk = 0;
28347ccd5a2cSjsg 	int ret = 0;
28357ccd5a2cSjsg 	u32 tmp;
28367ccd5a2cSjsg 	int i;
28377ccd5a2cSjsg 
28387ccd5a2cSjsg 	if (si_pi->spll_table_start == 0)
28397ccd5a2cSjsg 		return -EINVAL;
28407ccd5a2cSjsg 
28417ccd5a2cSjsg 	spll_table = kzalloc(sizeof(SMC_SISLANDS_SPLL_DIV_TABLE), GFP_KERNEL);
28427ccd5a2cSjsg 	if (spll_table == NULL)
28437ccd5a2cSjsg 		return -ENOMEM;
28447ccd5a2cSjsg 
28457ccd5a2cSjsg 	for (i = 0; i < 256; i++) {
28467ccd5a2cSjsg 		ret = si_calculate_sclk_params(rdev, sclk, &sclk_params);
28477ccd5a2cSjsg 		if (ret)
28487ccd5a2cSjsg 			break;
28497ccd5a2cSjsg 
28507ccd5a2cSjsg 		p_div = (sclk_params.vCG_SPLL_FUNC_CNTL & SPLL_PDIV_A_MASK) >> SPLL_PDIV_A_SHIFT;
28517ccd5a2cSjsg 		fb_div = (sclk_params.vCG_SPLL_FUNC_CNTL_3 & SPLL_FB_DIV_MASK) >> SPLL_FB_DIV_SHIFT;
28527ccd5a2cSjsg 		clk_s = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM & CLK_S_MASK) >> CLK_S_SHIFT;
28537ccd5a2cSjsg 		clk_v = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM_2 & CLK_V_MASK) >> CLK_V_SHIFT;
28547ccd5a2cSjsg 
28557ccd5a2cSjsg 		fb_div &= ~0x00001FFF;
28567ccd5a2cSjsg 		fb_div >>= 1;
28577ccd5a2cSjsg 		clk_v >>= 6;
28587ccd5a2cSjsg 
28597ccd5a2cSjsg 		if (p_div & ~(SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT))
28607ccd5a2cSjsg 			ret = -EINVAL;
28617ccd5a2cSjsg 		if (fb_div & ~(SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT))
28627ccd5a2cSjsg 			ret = -EINVAL;
28637ccd5a2cSjsg 		if (clk_s & ~(SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT))
28647ccd5a2cSjsg 			ret = -EINVAL;
28657ccd5a2cSjsg 		if (clk_v & ~(SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK >> SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT))
28667ccd5a2cSjsg 			ret = -EINVAL;
28677ccd5a2cSjsg 
28687ccd5a2cSjsg 		if (ret)
28697ccd5a2cSjsg 			break;
28707ccd5a2cSjsg 
28717ccd5a2cSjsg 		tmp = ((fb_div << SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_FBDIV_MASK) |
28727ccd5a2cSjsg 			((p_div << SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_PDIV_MASK);
28737ccd5a2cSjsg 		spll_table->freq[i] = cpu_to_be32(tmp);
28747ccd5a2cSjsg 
28757ccd5a2cSjsg 		tmp = ((clk_v << SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_CLKV_MASK) |
28767ccd5a2cSjsg 			((clk_s << SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT) & SMC_SISLANDS_SPLL_DIV_TABLE_CLKS_MASK);
28777ccd5a2cSjsg 		spll_table->ss[i] = cpu_to_be32(tmp);
28787ccd5a2cSjsg 
28797ccd5a2cSjsg 		sclk += 512;
28807ccd5a2cSjsg 	}
28817ccd5a2cSjsg 
28827ccd5a2cSjsg 
28837ccd5a2cSjsg 	if (!ret)
28847ccd5a2cSjsg 		ret = si_copy_bytes_to_smc(rdev, si_pi->spll_table_start,
28857ccd5a2cSjsg 					   (u8 *)spll_table, sizeof(SMC_SISLANDS_SPLL_DIV_TABLE),
28867ccd5a2cSjsg 					   si_pi->sram_end);
28877ccd5a2cSjsg 
28887ccd5a2cSjsg 	if (ret)
28897ccd5a2cSjsg 		ni_pi->enable_power_containment = false;
28907ccd5a2cSjsg 
28917ccd5a2cSjsg 	kfree(spll_table);
28927ccd5a2cSjsg 
28937ccd5a2cSjsg 	return ret;
28947ccd5a2cSjsg }
28957ccd5a2cSjsg 
si_get_lower_of_leakage_and_vce_voltage(struct radeon_device * rdev,u16 vce_voltage)28967ccd5a2cSjsg static u16 si_get_lower_of_leakage_and_vce_voltage(struct radeon_device *rdev,
28977ccd5a2cSjsg 						   u16 vce_voltage)
28987ccd5a2cSjsg {
28997ccd5a2cSjsg 	u16 highest_leakage = 0;
29007ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
29017ccd5a2cSjsg 	int i;
29027ccd5a2cSjsg 
29037ccd5a2cSjsg 	for (i = 0; i < si_pi->leakage_voltage.count; i++){
29047ccd5a2cSjsg 		if (highest_leakage < si_pi->leakage_voltage.entries[i].voltage)
29057ccd5a2cSjsg 			highest_leakage = si_pi->leakage_voltage.entries[i].voltage;
29067ccd5a2cSjsg 	}
29077ccd5a2cSjsg 
29087ccd5a2cSjsg 	if (si_pi->leakage_voltage.count && (highest_leakage < vce_voltage))
29097ccd5a2cSjsg 		return highest_leakage;
29107ccd5a2cSjsg 
29117ccd5a2cSjsg 	return vce_voltage;
29127ccd5a2cSjsg }
29137ccd5a2cSjsg 
si_get_vce_clock_voltage(struct radeon_device * rdev,u32 evclk,u32 ecclk,u16 * voltage)29147ccd5a2cSjsg static int si_get_vce_clock_voltage(struct radeon_device *rdev,
29157ccd5a2cSjsg 				    u32 evclk, u32 ecclk, u16 *voltage)
29167ccd5a2cSjsg {
29177ccd5a2cSjsg 	u32 i;
29187ccd5a2cSjsg 	int ret = -EINVAL;
29197ccd5a2cSjsg 	struct radeon_vce_clock_voltage_dependency_table *table =
29207ccd5a2cSjsg 		&rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table;
29217ccd5a2cSjsg 
29227ccd5a2cSjsg 	if (((evclk == 0) && (ecclk == 0)) ||
29237ccd5a2cSjsg 	    (table && (table->count == 0))) {
29247ccd5a2cSjsg 		*voltage = 0;
29257ccd5a2cSjsg 		return 0;
29267ccd5a2cSjsg 	}
29277ccd5a2cSjsg 
29287ccd5a2cSjsg 	for (i = 0; i < table->count; i++) {
29297ccd5a2cSjsg 		if ((evclk <= table->entries[i].evclk) &&
29307ccd5a2cSjsg 		    (ecclk <= table->entries[i].ecclk)) {
29317ccd5a2cSjsg 			*voltage = table->entries[i].v;
29327ccd5a2cSjsg 			ret = 0;
29337ccd5a2cSjsg 			break;
29347ccd5a2cSjsg 		}
29357ccd5a2cSjsg 	}
29367ccd5a2cSjsg 
29377ccd5a2cSjsg 	/* if no match return the highest voltage */
29387ccd5a2cSjsg 	if (ret)
29397ccd5a2cSjsg 		*voltage = table->entries[table->count - 1].v;
29407ccd5a2cSjsg 
29417ccd5a2cSjsg 	*voltage = si_get_lower_of_leakage_and_vce_voltage(rdev, *voltage);
29427ccd5a2cSjsg 
29437ccd5a2cSjsg 	return ret;
29447ccd5a2cSjsg }
29457ccd5a2cSjsg 
si_apply_state_adjust_rules(struct radeon_device * rdev,struct radeon_ps * rps)29467ccd5a2cSjsg static void si_apply_state_adjust_rules(struct radeon_device *rdev,
29477ccd5a2cSjsg 					struct radeon_ps *rps)
29487ccd5a2cSjsg {
29497ccd5a2cSjsg 	struct ni_ps *ps = ni_get_ps(rps);
29507ccd5a2cSjsg 	struct radeon_clock_and_voltage_limits *max_limits;
29517ccd5a2cSjsg 	bool disable_mclk_switching = false;
29527ccd5a2cSjsg 	bool disable_sclk_switching = false;
29537ccd5a2cSjsg 	u32 mclk, sclk;
29547ccd5a2cSjsg 	u16 vddc, vddci, min_vce_voltage = 0;
29557ccd5a2cSjsg 	u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;
29567ccd5a2cSjsg 	u32 max_sclk = 0, max_mclk = 0;
29577ccd5a2cSjsg 	int i;
29587ccd5a2cSjsg 
29597f4dd379Sjsg 	if (rdev->family == CHIP_HAINAN) {
29607ccd5a2cSjsg 		if ((rdev->pdev->revision == 0x81) ||
29617ccd5a2cSjsg 		    (rdev->pdev->revision == 0xC3) ||
29627ccd5a2cSjsg 		    (rdev->pdev->device == 0x6664) ||
29637ccd5a2cSjsg 		    (rdev->pdev->device == 0x6665) ||
29647ccd5a2cSjsg 		    (rdev->pdev->device == 0x6667)) {
29657ccd5a2cSjsg 			max_sclk = 75000;
29667f4dd379Sjsg 		}
29677f4dd379Sjsg 		if ((rdev->pdev->revision == 0xC3) ||
29687f4dd379Sjsg 		    (rdev->pdev->device == 0x6665)) {
29697f4dd379Sjsg 			max_sclk = 60000;
29707ccd5a2cSjsg 			max_mclk = 80000;
29717ccd5a2cSjsg 		}
29727ccd5a2cSjsg 	} else if (rdev->family == CHIP_OLAND) {
29737ccd5a2cSjsg 		if ((rdev->pdev->revision == 0xC7) ||
29747ccd5a2cSjsg 		    (rdev->pdev->revision == 0x80) ||
29757ccd5a2cSjsg 		    (rdev->pdev->revision == 0x81) ||
29767ccd5a2cSjsg 		    (rdev->pdev->revision == 0x83) ||
29777ccd5a2cSjsg 		    (rdev->pdev->revision == 0x87) ||
29787ccd5a2cSjsg 		    (rdev->pdev->device == 0x6604) ||
29797ccd5a2cSjsg 		    (rdev->pdev->device == 0x6605)) {
29807ccd5a2cSjsg 			max_sclk = 75000;
29817ccd5a2cSjsg 		}
2982ad8b1aafSjsg 
2983ad8b1aafSjsg 		if (rdev->pm.dpm.high_pixelclock_count > 1)
2984ad8b1aafSjsg 			disable_sclk_switching = true;
29857ccd5a2cSjsg 	}
29867ccd5a2cSjsg 
29877ccd5a2cSjsg 	if (rps->vce_active) {
29887ccd5a2cSjsg 		rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
29897ccd5a2cSjsg 		rps->ecclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].ecclk;
29907ccd5a2cSjsg 		si_get_vce_clock_voltage(rdev, rps->evclk, rps->ecclk,
29917ccd5a2cSjsg 					 &min_vce_voltage);
29927ccd5a2cSjsg 	} else {
29937ccd5a2cSjsg 		rps->evclk = 0;
29947ccd5a2cSjsg 		rps->ecclk = 0;
29957ccd5a2cSjsg 	}
29967ccd5a2cSjsg 
29977ccd5a2cSjsg 	if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
29987ccd5a2cSjsg 	    ni_dpm_vblank_too_short(rdev))
29997ccd5a2cSjsg 		disable_mclk_switching = true;
30007ccd5a2cSjsg 
30017ccd5a2cSjsg 	if (rps->vclk || rps->dclk) {
30027ccd5a2cSjsg 		disable_mclk_switching = true;
30037ccd5a2cSjsg 		disable_sclk_switching = true;
30047ccd5a2cSjsg 	}
30057ccd5a2cSjsg 
30067ccd5a2cSjsg 	if (rdev->pm.dpm.ac_power)
30077ccd5a2cSjsg 		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
30087ccd5a2cSjsg 	else
30097ccd5a2cSjsg 		max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
30107ccd5a2cSjsg 
30117ccd5a2cSjsg 	for (i = ps->performance_level_count - 2; i >= 0; i--) {
30127ccd5a2cSjsg 		if (ps->performance_levels[i].vddc > ps->performance_levels[i+1].vddc)
30137ccd5a2cSjsg 			ps->performance_levels[i].vddc = ps->performance_levels[i+1].vddc;
30147ccd5a2cSjsg 	}
30157ccd5a2cSjsg 	if (rdev->pm.dpm.ac_power == false) {
30167ccd5a2cSjsg 		for (i = 0; i < ps->performance_level_count; i++) {
30177ccd5a2cSjsg 			if (ps->performance_levels[i].mclk > max_limits->mclk)
30187ccd5a2cSjsg 				ps->performance_levels[i].mclk = max_limits->mclk;
30197ccd5a2cSjsg 			if (ps->performance_levels[i].sclk > max_limits->sclk)
30207ccd5a2cSjsg 				ps->performance_levels[i].sclk = max_limits->sclk;
30217ccd5a2cSjsg 			if (ps->performance_levels[i].vddc > max_limits->vddc)
30227ccd5a2cSjsg 				ps->performance_levels[i].vddc = max_limits->vddc;
30237ccd5a2cSjsg 			if (ps->performance_levels[i].vddci > max_limits->vddci)
30247ccd5a2cSjsg 				ps->performance_levels[i].vddci = max_limits->vddci;
30257ccd5a2cSjsg 		}
30267ccd5a2cSjsg 	}
30277ccd5a2cSjsg 
30287ccd5a2cSjsg 	/* limit clocks to max supported clocks based on voltage dependency tables */
30297ccd5a2cSjsg 	btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
30307ccd5a2cSjsg 							&max_sclk_vddc);
30317ccd5a2cSjsg 	btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
30327ccd5a2cSjsg 							&max_mclk_vddci);
30337ccd5a2cSjsg 	btc_get_max_clock_from_voltage_dependency_table(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
30347ccd5a2cSjsg 							&max_mclk_vddc);
30357ccd5a2cSjsg 
30367ccd5a2cSjsg 	for (i = 0; i < ps->performance_level_count; i++) {
30377ccd5a2cSjsg 		if (max_sclk_vddc) {
30387ccd5a2cSjsg 			if (ps->performance_levels[i].sclk > max_sclk_vddc)
30397ccd5a2cSjsg 				ps->performance_levels[i].sclk = max_sclk_vddc;
30407ccd5a2cSjsg 		}
30417ccd5a2cSjsg 		if (max_mclk_vddci) {
30427ccd5a2cSjsg 			if (ps->performance_levels[i].mclk > max_mclk_vddci)
30437ccd5a2cSjsg 				ps->performance_levels[i].mclk = max_mclk_vddci;
30447ccd5a2cSjsg 		}
30457ccd5a2cSjsg 		if (max_mclk_vddc) {
30467ccd5a2cSjsg 			if (ps->performance_levels[i].mclk > max_mclk_vddc)
30477ccd5a2cSjsg 				ps->performance_levels[i].mclk = max_mclk_vddc;
30487ccd5a2cSjsg 		}
30497ccd5a2cSjsg 		if (max_mclk) {
30507ccd5a2cSjsg 			if (ps->performance_levels[i].mclk > max_mclk)
30517ccd5a2cSjsg 				ps->performance_levels[i].mclk = max_mclk;
30527ccd5a2cSjsg 		}
30537ccd5a2cSjsg 		if (max_sclk) {
30547ccd5a2cSjsg 			if (ps->performance_levels[i].sclk > max_sclk)
30557ccd5a2cSjsg 				ps->performance_levels[i].sclk = max_sclk;
30567ccd5a2cSjsg 		}
30577ccd5a2cSjsg 	}
30587ccd5a2cSjsg 
30597ccd5a2cSjsg 	/* XXX validate the min clocks required for display */
30607ccd5a2cSjsg 
30617ccd5a2cSjsg 	if (disable_mclk_switching) {
30627ccd5a2cSjsg 		mclk  = ps->performance_levels[ps->performance_level_count - 1].mclk;
30637ccd5a2cSjsg 		vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
30647ccd5a2cSjsg 	} else {
30657ccd5a2cSjsg 		mclk = ps->performance_levels[0].mclk;
30667ccd5a2cSjsg 		vddci = ps->performance_levels[0].vddci;
30677ccd5a2cSjsg 	}
30687ccd5a2cSjsg 
30697ccd5a2cSjsg 	if (disable_sclk_switching) {
30707ccd5a2cSjsg 		sclk = ps->performance_levels[ps->performance_level_count - 1].sclk;
30717ccd5a2cSjsg 		vddc = ps->performance_levels[ps->performance_level_count - 1].vddc;
30727ccd5a2cSjsg 	} else {
30737ccd5a2cSjsg 		sclk = ps->performance_levels[0].sclk;
30747ccd5a2cSjsg 		vddc = ps->performance_levels[0].vddc;
30757ccd5a2cSjsg 	}
30767ccd5a2cSjsg 
30777ccd5a2cSjsg 	if (rps->vce_active) {
30787ccd5a2cSjsg 		if (sclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk)
30797ccd5a2cSjsg 			sclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].sclk;
30807ccd5a2cSjsg 		if (mclk < rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].mclk)
30817ccd5a2cSjsg 			mclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].mclk;
30827ccd5a2cSjsg 	}
30837ccd5a2cSjsg 
30847ccd5a2cSjsg 	/* adjusted low state */
30857ccd5a2cSjsg 	ps->performance_levels[0].sclk = sclk;
30867ccd5a2cSjsg 	ps->performance_levels[0].mclk = mclk;
30877ccd5a2cSjsg 	ps->performance_levels[0].vddc = vddc;
30887ccd5a2cSjsg 	ps->performance_levels[0].vddci = vddci;
30897ccd5a2cSjsg 
30907ccd5a2cSjsg 	if (disable_sclk_switching) {
30917ccd5a2cSjsg 		sclk = ps->performance_levels[0].sclk;
30927ccd5a2cSjsg 		for (i = 1; i < ps->performance_level_count; i++) {
30937ccd5a2cSjsg 			if (sclk < ps->performance_levels[i].sclk)
30947ccd5a2cSjsg 				sclk = ps->performance_levels[i].sclk;
30957ccd5a2cSjsg 		}
30967ccd5a2cSjsg 		for (i = 0; i < ps->performance_level_count; i++) {
30977ccd5a2cSjsg 			ps->performance_levels[i].sclk = sclk;
30987ccd5a2cSjsg 			ps->performance_levels[i].vddc = vddc;
30997ccd5a2cSjsg 		}
31007ccd5a2cSjsg 	} else {
31017ccd5a2cSjsg 		for (i = 1; i < ps->performance_level_count; i++) {
31027ccd5a2cSjsg 			if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
31037ccd5a2cSjsg 				ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
31047ccd5a2cSjsg 			if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
31057ccd5a2cSjsg 				ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
31067ccd5a2cSjsg 		}
31077ccd5a2cSjsg 	}
31087ccd5a2cSjsg 
31097ccd5a2cSjsg 	if (disable_mclk_switching) {
31107ccd5a2cSjsg 		mclk = ps->performance_levels[0].mclk;
31117ccd5a2cSjsg 		for (i = 1; i < ps->performance_level_count; i++) {
31127ccd5a2cSjsg 			if (mclk < ps->performance_levels[i].mclk)
31137ccd5a2cSjsg 				mclk = ps->performance_levels[i].mclk;
31147ccd5a2cSjsg 		}
31157ccd5a2cSjsg 		for (i = 0; i < ps->performance_level_count; i++) {
31167ccd5a2cSjsg 			ps->performance_levels[i].mclk = mclk;
31177ccd5a2cSjsg 			ps->performance_levels[i].vddci = vddci;
31187ccd5a2cSjsg 		}
31197ccd5a2cSjsg 	} else {
31207ccd5a2cSjsg 		for (i = 1; i < ps->performance_level_count; i++) {
31217ccd5a2cSjsg 			if (ps->performance_levels[i].mclk < ps->performance_levels[i - 1].mclk)
31227ccd5a2cSjsg 				ps->performance_levels[i].mclk = ps->performance_levels[i - 1].mclk;
31237ccd5a2cSjsg 			if (ps->performance_levels[i].vddci < ps->performance_levels[i - 1].vddci)
31247ccd5a2cSjsg 				ps->performance_levels[i].vddci = ps->performance_levels[i - 1].vddci;
31257ccd5a2cSjsg 		}
31267ccd5a2cSjsg 	}
31277ccd5a2cSjsg 
31287ccd5a2cSjsg 	for (i = 0; i < ps->performance_level_count; i++)
31297ccd5a2cSjsg 		btc_adjust_clock_combinations(rdev, max_limits,
31307ccd5a2cSjsg 					      &ps->performance_levels[i]);
31317ccd5a2cSjsg 
31327ccd5a2cSjsg 	for (i = 0; i < ps->performance_level_count; i++) {
31337ccd5a2cSjsg 		if (ps->performance_levels[i].vddc < min_vce_voltage)
31347ccd5a2cSjsg 			ps->performance_levels[i].vddc = min_vce_voltage;
31357ccd5a2cSjsg 		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
31367ccd5a2cSjsg 						   ps->performance_levels[i].sclk,
31377ccd5a2cSjsg 						   max_limits->vddc,  &ps->performance_levels[i].vddc);
31387ccd5a2cSjsg 		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
31397ccd5a2cSjsg 						   ps->performance_levels[i].mclk,
31407ccd5a2cSjsg 						   max_limits->vddci, &ps->performance_levels[i].vddci);
31417ccd5a2cSjsg 		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
31427ccd5a2cSjsg 						   ps->performance_levels[i].mclk,
31437ccd5a2cSjsg 						   max_limits->vddc,  &ps->performance_levels[i].vddc);
31447ccd5a2cSjsg 		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
31457ccd5a2cSjsg 						   rdev->clock.current_dispclk,
31467ccd5a2cSjsg 						   max_limits->vddc,  &ps->performance_levels[i].vddc);
31477ccd5a2cSjsg 	}
31487ccd5a2cSjsg 
31497ccd5a2cSjsg 	for (i = 0; i < ps->performance_level_count; i++) {
31507ccd5a2cSjsg 		btc_apply_voltage_delta_rules(rdev,
31517ccd5a2cSjsg 					      max_limits->vddc, max_limits->vddci,
31527ccd5a2cSjsg 					      &ps->performance_levels[i].vddc,
31537ccd5a2cSjsg 					      &ps->performance_levels[i].vddci);
31547ccd5a2cSjsg 	}
31557ccd5a2cSjsg 
31567ccd5a2cSjsg 	ps->dc_compatible = true;
31577ccd5a2cSjsg 	for (i = 0; i < ps->performance_level_count; i++) {
31587ccd5a2cSjsg 		if (ps->performance_levels[i].vddc > rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc)
31597ccd5a2cSjsg 			ps->dc_compatible = false;
31607ccd5a2cSjsg 	}
31617ccd5a2cSjsg }
31627ccd5a2cSjsg 
31637ccd5a2cSjsg #if 0
31647ccd5a2cSjsg static int si_read_smc_soft_register(struct radeon_device *rdev,
31657ccd5a2cSjsg 				     u16 reg_offset, u32 *value)
31667ccd5a2cSjsg {
31677ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
31687ccd5a2cSjsg 
31697ccd5a2cSjsg 	return si_read_smc_sram_dword(rdev,
31707ccd5a2cSjsg 				      si_pi->soft_regs_start + reg_offset, value,
31717ccd5a2cSjsg 				      si_pi->sram_end);
31727ccd5a2cSjsg }
31737ccd5a2cSjsg #endif
31747ccd5a2cSjsg 
si_write_smc_soft_register(struct radeon_device * rdev,u16 reg_offset,u32 value)31757ccd5a2cSjsg static int si_write_smc_soft_register(struct radeon_device *rdev,
31767ccd5a2cSjsg 				      u16 reg_offset, u32 value)
31777ccd5a2cSjsg {
31787ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
31797ccd5a2cSjsg 
31807ccd5a2cSjsg 	return si_write_smc_sram_dword(rdev,
31817ccd5a2cSjsg 				       si_pi->soft_regs_start + reg_offset,
31827ccd5a2cSjsg 				       value, si_pi->sram_end);
31837ccd5a2cSjsg }
31847ccd5a2cSjsg 
si_is_special_1gb_platform(struct radeon_device * rdev)31857ccd5a2cSjsg static bool si_is_special_1gb_platform(struct radeon_device *rdev)
31867ccd5a2cSjsg {
31877ccd5a2cSjsg 	bool ret = false;
31887ccd5a2cSjsg 	u32 tmp, width, row, column, bank, density;
31897ccd5a2cSjsg 	bool is_memory_gddr5, is_special;
31907ccd5a2cSjsg 
31917ccd5a2cSjsg 	tmp = RREG32(MC_SEQ_MISC0);
31927ccd5a2cSjsg 	is_memory_gddr5 = (MC_SEQ_MISC0_GDDR5_VALUE == ((tmp & MC_SEQ_MISC0_GDDR5_MASK) >> MC_SEQ_MISC0_GDDR5_SHIFT));
31937ccd5a2cSjsg 	is_special = (MC_SEQ_MISC0_REV_ID_VALUE == ((tmp & MC_SEQ_MISC0_REV_ID_MASK) >> MC_SEQ_MISC0_REV_ID_SHIFT))
31947ccd5a2cSjsg 		& (MC_SEQ_MISC0_VEN_ID_VALUE == ((tmp & MC_SEQ_MISC0_VEN_ID_MASK) >> MC_SEQ_MISC0_VEN_ID_SHIFT));
31957ccd5a2cSjsg 
31967ccd5a2cSjsg 	WREG32(MC_SEQ_IO_DEBUG_INDEX, 0xb);
31977ccd5a2cSjsg 	width = ((RREG32(MC_SEQ_IO_DEBUG_DATA) >> 1) & 1) ? 16 : 32;
31987ccd5a2cSjsg 
31997ccd5a2cSjsg 	tmp = RREG32(MC_ARB_RAMCFG);
32007ccd5a2cSjsg 	row = ((tmp & NOOFROWS_MASK) >> NOOFROWS_SHIFT) + 10;
32017ccd5a2cSjsg 	column = ((tmp & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT) + 8;
32027ccd5a2cSjsg 	bank = ((tmp & NOOFBANK_MASK) >> NOOFBANK_SHIFT) + 2;
32037ccd5a2cSjsg 
32047ccd5a2cSjsg 	density = (1 << (row + column - 20 + bank)) * width;
32057ccd5a2cSjsg 
32067ccd5a2cSjsg 	if ((rdev->pdev->device == 0x6819) &&
32077ccd5a2cSjsg 	    is_memory_gddr5 && is_special && (density == 0x400))
32087ccd5a2cSjsg 		ret = true;
32097ccd5a2cSjsg 
32107ccd5a2cSjsg 	return ret;
32117ccd5a2cSjsg }
32127ccd5a2cSjsg 
si_get_leakage_vddc(struct radeon_device * rdev)32137ccd5a2cSjsg static void si_get_leakage_vddc(struct radeon_device *rdev)
32147ccd5a2cSjsg {
32157ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
32167ccd5a2cSjsg 	u16 vddc, count = 0;
32177ccd5a2cSjsg 	int i, ret;
32187ccd5a2cSjsg 
32197ccd5a2cSjsg 	for (i = 0; i < SISLANDS_MAX_LEAKAGE_COUNT; i++) {
32207ccd5a2cSjsg 		ret = radeon_atom_get_leakage_vddc_based_on_leakage_idx(rdev, &vddc, SISLANDS_LEAKAGE_INDEX0 + i);
32217ccd5a2cSjsg 
32227ccd5a2cSjsg 		if (!ret && (vddc > 0) && (vddc != (SISLANDS_LEAKAGE_INDEX0 + i))) {
32237ccd5a2cSjsg 			si_pi->leakage_voltage.entries[count].voltage = vddc;
32247ccd5a2cSjsg 			si_pi->leakage_voltage.entries[count].leakage_index =
32257ccd5a2cSjsg 				SISLANDS_LEAKAGE_INDEX0 + i;
32267ccd5a2cSjsg 			count++;
32277ccd5a2cSjsg 		}
32287ccd5a2cSjsg 	}
32297ccd5a2cSjsg 	si_pi->leakage_voltage.count = count;
32307ccd5a2cSjsg }
32317ccd5a2cSjsg 
si_get_leakage_voltage_from_leakage_index(struct radeon_device * rdev,u32 index,u16 * leakage_voltage)32327ccd5a2cSjsg static int si_get_leakage_voltage_from_leakage_index(struct radeon_device *rdev,
32337ccd5a2cSjsg 						     u32 index, u16 *leakage_voltage)
32347ccd5a2cSjsg {
32357ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
32367ccd5a2cSjsg 	int i;
32377ccd5a2cSjsg 
32387ccd5a2cSjsg 	if (leakage_voltage == NULL)
32397ccd5a2cSjsg 		return -EINVAL;
32407ccd5a2cSjsg 
32417ccd5a2cSjsg 	if ((index & 0xff00) != 0xff00)
32427ccd5a2cSjsg 		return -EINVAL;
32437ccd5a2cSjsg 
32447ccd5a2cSjsg 	if ((index & 0xff) > SISLANDS_MAX_LEAKAGE_COUNT + 1)
32457ccd5a2cSjsg 		return -EINVAL;
32467ccd5a2cSjsg 
32477ccd5a2cSjsg 	if (index < SISLANDS_LEAKAGE_INDEX0)
32487ccd5a2cSjsg 		return -EINVAL;
32497ccd5a2cSjsg 
32507ccd5a2cSjsg 	for (i = 0; i < si_pi->leakage_voltage.count; i++) {
32517ccd5a2cSjsg 		if (si_pi->leakage_voltage.entries[i].leakage_index == index) {
32527ccd5a2cSjsg 			*leakage_voltage = si_pi->leakage_voltage.entries[i].voltage;
32537ccd5a2cSjsg 			return 0;
32547ccd5a2cSjsg 		}
32557ccd5a2cSjsg 	}
32567ccd5a2cSjsg 	return -EAGAIN;
32577ccd5a2cSjsg }
32587ccd5a2cSjsg 
si_set_dpm_event_sources(struct radeon_device * rdev,u32 sources)32597ccd5a2cSjsg static void si_set_dpm_event_sources(struct radeon_device *rdev, u32 sources)
32607ccd5a2cSjsg {
32617ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
32627ccd5a2cSjsg 	bool want_thermal_protection;
32637ccd5a2cSjsg 	enum radeon_dpm_event_src dpm_event_src;
32647ccd5a2cSjsg 
32657ccd5a2cSjsg 	switch (sources) {
32667ccd5a2cSjsg 	case 0:
32677ccd5a2cSjsg 	default:
32687ccd5a2cSjsg 		want_thermal_protection = false;
32697ccd5a2cSjsg 		break;
32707ccd5a2cSjsg 	case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL):
32717ccd5a2cSjsg 		want_thermal_protection = true;
32727ccd5a2cSjsg 		dpm_event_src = RADEON_DPM_EVENT_SRC_DIGITAL;
32737ccd5a2cSjsg 		break;
32747ccd5a2cSjsg 	case (1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL):
32757ccd5a2cSjsg 		want_thermal_protection = true;
32767ccd5a2cSjsg 		dpm_event_src = RADEON_DPM_EVENT_SRC_EXTERNAL;
32777ccd5a2cSjsg 		break;
32787ccd5a2cSjsg 	case ((1 << RADEON_DPM_AUTO_THROTTLE_SRC_EXTERNAL) |
32797ccd5a2cSjsg 	      (1 << RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL)):
32807ccd5a2cSjsg 		want_thermal_protection = true;
32817ccd5a2cSjsg 		dpm_event_src = RADEON_DPM_EVENT_SRC_DIGIAL_OR_EXTERNAL;
32827ccd5a2cSjsg 		break;
32837ccd5a2cSjsg 	}
32847ccd5a2cSjsg 
32857ccd5a2cSjsg 	if (want_thermal_protection) {
32867ccd5a2cSjsg 		WREG32_P(CG_THERMAL_CTRL, DPM_EVENT_SRC(dpm_event_src), ~DPM_EVENT_SRC_MASK);
32877ccd5a2cSjsg 		if (pi->thermal_protection)
32887ccd5a2cSjsg 			WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
32897ccd5a2cSjsg 	} else {
32907ccd5a2cSjsg 		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
32917ccd5a2cSjsg 	}
32927ccd5a2cSjsg }
32937ccd5a2cSjsg 
si_enable_auto_throttle_source(struct radeon_device * rdev,enum radeon_dpm_auto_throttle_src source,bool enable)32947ccd5a2cSjsg static void si_enable_auto_throttle_source(struct radeon_device *rdev,
32957ccd5a2cSjsg 					   enum radeon_dpm_auto_throttle_src source,
32967ccd5a2cSjsg 					   bool enable)
32977ccd5a2cSjsg {
32987ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
32997ccd5a2cSjsg 
33007ccd5a2cSjsg 	if (enable) {
33017ccd5a2cSjsg 		if (!(pi->active_auto_throttle_sources & (1 << source))) {
33027ccd5a2cSjsg 			pi->active_auto_throttle_sources |= 1 << source;
33037ccd5a2cSjsg 			si_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
33047ccd5a2cSjsg 		}
33057ccd5a2cSjsg 	} else {
33067ccd5a2cSjsg 		if (pi->active_auto_throttle_sources & (1 << source)) {
33077ccd5a2cSjsg 			pi->active_auto_throttle_sources &= ~(1 << source);
33087ccd5a2cSjsg 			si_set_dpm_event_sources(rdev, pi->active_auto_throttle_sources);
33097ccd5a2cSjsg 		}
33107ccd5a2cSjsg 	}
33117ccd5a2cSjsg }
33127ccd5a2cSjsg 
si_start_dpm(struct radeon_device * rdev)33137ccd5a2cSjsg static void si_start_dpm(struct radeon_device *rdev)
33147ccd5a2cSjsg {
33157ccd5a2cSjsg 	WREG32_P(GENERAL_PWRMGT, GLOBAL_PWRMGT_EN, ~GLOBAL_PWRMGT_EN);
33167ccd5a2cSjsg }
33177ccd5a2cSjsg 
si_stop_dpm(struct radeon_device * rdev)33187ccd5a2cSjsg static void si_stop_dpm(struct radeon_device *rdev)
33197ccd5a2cSjsg {
33207ccd5a2cSjsg 	WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
33217ccd5a2cSjsg }
33227ccd5a2cSjsg 
si_enable_sclk_control(struct radeon_device * rdev,bool enable)33237ccd5a2cSjsg static void si_enable_sclk_control(struct radeon_device *rdev, bool enable)
33247ccd5a2cSjsg {
33257ccd5a2cSjsg 	if (enable)
33267ccd5a2cSjsg 		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~SCLK_PWRMGT_OFF);
33277ccd5a2cSjsg 	else
33287ccd5a2cSjsg 		WREG32_P(SCLK_PWRMGT_CNTL, SCLK_PWRMGT_OFF, ~SCLK_PWRMGT_OFF);
33297ccd5a2cSjsg 
33307ccd5a2cSjsg }
33317ccd5a2cSjsg 
33327ccd5a2cSjsg #if 0
33337ccd5a2cSjsg static int si_notify_hardware_of_thermal_state(struct radeon_device *rdev,
33347ccd5a2cSjsg 					       u32 thermal_level)
33357ccd5a2cSjsg {
33367ccd5a2cSjsg 	PPSMC_Result ret;
33377ccd5a2cSjsg 
33387ccd5a2cSjsg 	if (thermal_level == 0) {
33397ccd5a2cSjsg 		ret = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
33407ccd5a2cSjsg 		if (ret == PPSMC_Result_OK)
33417ccd5a2cSjsg 			return 0;
33427ccd5a2cSjsg 		else
33437ccd5a2cSjsg 			return -EINVAL;
33447ccd5a2cSjsg 	}
33457ccd5a2cSjsg 	return 0;
33467ccd5a2cSjsg }
33477ccd5a2cSjsg 
33487ccd5a2cSjsg static void si_notify_hardware_vpu_recovery_event(struct radeon_device *rdev)
33497ccd5a2cSjsg {
33507ccd5a2cSjsg 	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_tdr_is_about_to_happen, true);
33517ccd5a2cSjsg }
33527ccd5a2cSjsg #endif
33537ccd5a2cSjsg 
33547ccd5a2cSjsg #if 0
33557ccd5a2cSjsg static int si_notify_hw_of_powersource(struct radeon_device *rdev, bool ac_power)
33567ccd5a2cSjsg {
33577ccd5a2cSjsg 	if (ac_power)
33587ccd5a2cSjsg 		return (si_send_msg_to_smc(rdev, PPSMC_MSG_RunningOnAC) == PPSMC_Result_OK) ?
33597ccd5a2cSjsg 			0 : -EINVAL;
33607ccd5a2cSjsg 
33617ccd5a2cSjsg 	return 0;
33627ccd5a2cSjsg }
33637ccd5a2cSjsg #endif
33647ccd5a2cSjsg 
si_send_msg_to_smc_with_parameter(struct radeon_device * rdev,PPSMC_Msg msg,u32 parameter)33657ccd5a2cSjsg static PPSMC_Result si_send_msg_to_smc_with_parameter(struct radeon_device *rdev,
33667ccd5a2cSjsg 						      PPSMC_Msg msg, u32 parameter)
33677ccd5a2cSjsg {
33687ccd5a2cSjsg 	WREG32(SMC_SCRATCH0, parameter);
33697ccd5a2cSjsg 	return si_send_msg_to_smc(rdev, msg);
33707ccd5a2cSjsg }
33717ccd5a2cSjsg 
si_restrict_performance_levels_before_switch(struct radeon_device * rdev)33727ccd5a2cSjsg static int si_restrict_performance_levels_before_switch(struct radeon_device *rdev)
33737ccd5a2cSjsg {
33747ccd5a2cSjsg 	if (si_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
33757ccd5a2cSjsg 		return -EINVAL;
33767ccd5a2cSjsg 
33777ccd5a2cSjsg 	return (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) == PPSMC_Result_OK) ?
33787ccd5a2cSjsg 		0 : -EINVAL;
33797ccd5a2cSjsg }
33807ccd5a2cSjsg 
si_dpm_force_performance_level(struct radeon_device * rdev,enum radeon_dpm_forced_level level)33817ccd5a2cSjsg int si_dpm_force_performance_level(struct radeon_device *rdev,
33827ccd5a2cSjsg 				   enum radeon_dpm_forced_level level)
33837ccd5a2cSjsg {
33847ccd5a2cSjsg 	struct radeon_ps *rps = rdev->pm.dpm.current_ps;
33857ccd5a2cSjsg 	struct ni_ps *ps = ni_get_ps(rps);
33867ccd5a2cSjsg 	u32 levels = ps->performance_level_count;
33877ccd5a2cSjsg 
33887ccd5a2cSjsg 	if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
33897ccd5a2cSjsg 		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK)
33907ccd5a2cSjsg 			return -EINVAL;
33917ccd5a2cSjsg 
33927ccd5a2cSjsg 		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 1) != PPSMC_Result_OK)
33937ccd5a2cSjsg 			return -EINVAL;
33947ccd5a2cSjsg 	} else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
33957ccd5a2cSjsg 		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
33967ccd5a2cSjsg 			return -EINVAL;
33977ccd5a2cSjsg 
33987ccd5a2cSjsg 		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) != PPSMC_Result_OK)
33997ccd5a2cSjsg 			return -EINVAL;
34007ccd5a2cSjsg 	} else if (level == RADEON_DPM_FORCED_LEVEL_AUTO) {
34017ccd5a2cSjsg 		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetForcedLevels, 0) != PPSMC_Result_OK)
34027ccd5a2cSjsg 			return -EINVAL;
34037ccd5a2cSjsg 
34047ccd5a2cSjsg 		if (si_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, levels) != PPSMC_Result_OK)
34057ccd5a2cSjsg 			return -EINVAL;
34067ccd5a2cSjsg 	}
34077ccd5a2cSjsg 
34087ccd5a2cSjsg 	rdev->pm.dpm.forced_level = level;
34097ccd5a2cSjsg 
34107ccd5a2cSjsg 	return 0;
34117ccd5a2cSjsg }
34127ccd5a2cSjsg 
34137ccd5a2cSjsg #if 0
34147ccd5a2cSjsg static int si_set_boot_state(struct radeon_device *rdev)
34157ccd5a2cSjsg {
34167ccd5a2cSjsg 	return (si_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToInitialState) == PPSMC_Result_OK) ?
34177ccd5a2cSjsg 		0 : -EINVAL;
34187ccd5a2cSjsg }
34197ccd5a2cSjsg #endif
34207ccd5a2cSjsg 
si_set_sw_state(struct radeon_device * rdev)34217ccd5a2cSjsg static int si_set_sw_state(struct radeon_device *rdev)
34227ccd5a2cSjsg {
34237ccd5a2cSjsg 	return (si_send_msg_to_smc(rdev, PPSMC_MSG_SwitchToSwState) == PPSMC_Result_OK) ?
34247ccd5a2cSjsg 		0 : -EINVAL;
34257ccd5a2cSjsg }
34267ccd5a2cSjsg 
si_halt_smc(struct radeon_device * rdev)34277ccd5a2cSjsg static int si_halt_smc(struct radeon_device *rdev)
34287ccd5a2cSjsg {
34297ccd5a2cSjsg 	if (si_send_msg_to_smc(rdev, PPSMC_MSG_Halt) != PPSMC_Result_OK)
34307ccd5a2cSjsg 		return -EINVAL;
34317ccd5a2cSjsg 
34327ccd5a2cSjsg 	return (si_wait_for_smc_inactive(rdev) == PPSMC_Result_OK) ?
34337ccd5a2cSjsg 		0 : -EINVAL;
34347ccd5a2cSjsg }
34357ccd5a2cSjsg 
si_resume_smc(struct radeon_device * rdev)34367ccd5a2cSjsg static int si_resume_smc(struct radeon_device *rdev)
34377ccd5a2cSjsg {
34387ccd5a2cSjsg 	if (si_send_msg_to_smc(rdev, PPSMC_FlushDataCache) != PPSMC_Result_OK)
34397ccd5a2cSjsg 		return -EINVAL;
34407ccd5a2cSjsg 
34417ccd5a2cSjsg 	return (si_send_msg_to_smc(rdev, PPSMC_MSG_Resume) == PPSMC_Result_OK) ?
34427ccd5a2cSjsg 		0 : -EINVAL;
34437ccd5a2cSjsg }
34447ccd5a2cSjsg 
si_dpm_start_smc(struct radeon_device * rdev)34457ccd5a2cSjsg static void si_dpm_start_smc(struct radeon_device *rdev)
34467ccd5a2cSjsg {
34477ccd5a2cSjsg 	si_program_jump_on_start(rdev);
34487ccd5a2cSjsg 	si_start_smc(rdev);
34497ccd5a2cSjsg 	si_start_smc_clock(rdev);
34507ccd5a2cSjsg }
34517ccd5a2cSjsg 
si_dpm_stop_smc(struct radeon_device * rdev)34527ccd5a2cSjsg static void si_dpm_stop_smc(struct radeon_device *rdev)
34537ccd5a2cSjsg {
34547ccd5a2cSjsg 	si_reset_smc(rdev);
34557ccd5a2cSjsg 	si_stop_smc_clock(rdev);
34567ccd5a2cSjsg }
34577ccd5a2cSjsg 
si_process_firmware_header(struct radeon_device * rdev)34587ccd5a2cSjsg static int si_process_firmware_header(struct radeon_device *rdev)
34597ccd5a2cSjsg {
34607ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
34617ccd5a2cSjsg 	u32 tmp;
34627ccd5a2cSjsg 	int ret;
34637ccd5a2cSjsg 
34647ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev,
34657ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
34667ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_stateTable,
34677ccd5a2cSjsg 				     &tmp, si_pi->sram_end);
34687ccd5a2cSjsg 	if (ret)
34697ccd5a2cSjsg 		return ret;
34707ccd5a2cSjsg 
34717ccd5a2cSjsg 	si_pi->state_table_start = tmp;
34727ccd5a2cSjsg 
34737ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev,
34747ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
34757ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_softRegisters,
34767ccd5a2cSjsg 				     &tmp, si_pi->sram_end);
34777ccd5a2cSjsg 	if (ret)
34787ccd5a2cSjsg 		return ret;
34797ccd5a2cSjsg 
34807ccd5a2cSjsg 	si_pi->soft_regs_start = tmp;
34817ccd5a2cSjsg 
34827ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev,
34837ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
34847ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable,
34857ccd5a2cSjsg 				     &tmp, si_pi->sram_end);
34867ccd5a2cSjsg 	if (ret)
34877ccd5a2cSjsg 		return ret;
34887ccd5a2cSjsg 
34897ccd5a2cSjsg 	si_pi->mc_reg_table_start = tmp;
34907ccd5a2cSjsg 
34917ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev,
34927ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
34937ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_fanTable,
34947ccd5a2cSjsg 				     &tmp, si_pi->sram_end);
34957ccd5a2cSjsg 	if (ret)
34967ccd5a2cSjsg 		return ret;
34977ccd5a2cSjsg 
34987ccd5a2cSjsg 	si_pi->fan_table_start = tmp;
34997ccd5a2cSjsg 
35007ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev,
35017ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
35027ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable,
35037ccd5a2cSjsg 				     &tmp, si_pi->sram_end);
35047ccd5a2cSjsg 	if (ret)
35057ccd5a2cSjsg 		return ret;
35067ccd5a2cSjsg 
35077ccd5a2cSjsg 	si_pi->arb_table_start = tmp;
35087ccd5a2cSjsg 
35097ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev,
35107ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
35117ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_CacConfigTable,
35127ccd5a2cSjsg 				     &tmp, si_pi->sram_end);
35137ccd5a2cSjsg 	if (ret)
35147ccd5a2cSjsg 		return ret;
35157ccd5a2cSjsg 
35167ccd5a2cSjsg 	si_pi->cac_table_start = tmp;
35177ccd5a2cSjsg 
35187ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev,
35197ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
35207ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_DteConfiguration,
35217ccd5a2cSjsg 				     &tmp, si_pi->sram_end);
35227ccd5a2cSjsg 	if (ret)
35237ccd5a2cSjsg 		return ret;
35247ccd5a2cSjsg 
35257ccd5a2cSjsg 	si_pi->dte_table_start = tmp;
35267ccd5a2cSjsg 
35277ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev,
35287ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
35297ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_spllTable,
35307ccd5a2cSjsg 				     &tmp, si_pi->sram_end);
35317ccd5a2cSjsg 	if (ret)
35327ccd5a2cSjsg 		return ret;
35337ccd5a2cSjsg 
35347ccd5a2cSjsg 	si_pi->spll_table_start = tmp;
35357ccd5a2cSjsg 
35367ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev,
35377ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
35387ccd5a2cSjsg 				     SISLANDS_SMC_FIRMWARE_HEADER_PAPMParameters,
35397ccd5a2cSjsg 				     &tmp, si_pi->sram_end);
35407ccd5a2cSjsg 	if (ret)
35417ccd5a2cSjsg 		return ret;
35427ccd5a2cSjsg 
35437ccd5a2cSjsg 	si_pi->papm_cfg_table_start = tmp;
35447ccd5a2cSjsg 
35457ccd5a2cSjsg 	return ret;
35467ccd5a2cSjsg }
35477ccd5a2cSjsg 
si_read_clock_registers(struct radeon_device * rdev)35487ccd5a2cSjsg static void si_read_clock_registers(struct radeon_device *rdev)
35497ccd5a2cSjsg {
35507ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
35517ccd5a2cSjsg 
35527ccd5a2cSjsg 	si_pi->clock_registers.cg_spll_func_cntl = RREG32(CG_SPLL_FUNC_CNTL);
35537ccd5a2cSjsg 	si_pi->clock_registers.cg_spll_func_cntl_2 = RREG32(CG_SPLL_FUNC_CNTL_2);
35547ccd5a2cSjsg 	si_pi->clock_registers.cg_spll_func_cntl_3 = RREG32(CG_SPLL_FUNC_CNTL_3);
35557ccd5a2cSjsg 	si_pi->clock_registers.cg_spll_func_cntl_4 = RREG32(CG_SPLL_FUNC_CNTL_4);
35567ccd5a2cSjsg 	si_pi->clock_registers.cg_spll_spread_spectrum = RREG32(CG_SPLL_SPREAD_SPECTRUM);
35577ccd5a2cSjsg 	si_pi->clock_registers.cg_spll_spread_spectrum_2 = RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
35587ccd5a2cSjsg 	si_pi->clock_registers.dll_cntl = RREG32(DLL_CNTL);
35597ccd5a2cSjsg 	si_pi->clock_registers.mclk_pwrmgt_cntl = RREG32(MCLK_PWRMGT_CNTL);
35607ccd5a2cSjsg 	si_pi->clock_registers.mpll_ad_func_cntl = RREG32(MPLL_AD_FUNC_CNTL);
35617ccd5a2cSjsg 	si_pi->clock_registers.mpll_dq_func_cntl = RREG32(MPLL_DQ_FUNC_CNTL);
35627ccd5a2cSjsg 	si_pi->clock_registers.mpll_func_cntl = RREG32(MPLL_FUNC_CNTL);
35637ccd5a2cSjsg 	si_pi->clock_registers.mpll_func_cntl_1 = RREG32(MPLL_FUNC_CNTL_1);
35647ccd5a2cSjsg 	si_pi->clock_registers.mpll_func_cntl_2 = RREG32(MPLL_FUNC_CNTL_2);
35657ccd5a2cSjsg 	si_pi->clock_registers.mpll_ss1 = RREG32(MPLL_SS1);
35667ccd5a2cSjsg 	si_pi->clock_registers.mpll_ss2 = RREG32(MPLL_SS2);
35677ccd5a2cSjsg }
35687ccd5a2cSjsg 
si_enable_thermal_protection(struct radeon_device * rdev,bool enable)35697ccd5a2cSjsg static void si_enable_thermal_protection(struct radeon_device *rdev,
35707ccd5a2cSjsg 					  bool enable)
35717ccd5a2cSjsg {
35727ccd5a2cSjsg 	if (enable)
35737ccd5a2cSjsg 		WREG32_P(GENERAL_PWRMGT, 0, ~THERMAL_PROTECTION_DIS);
35747ccd5a2cSjsg 	else
35757ccd5a2cSjsg 		WREG32_P(GENERAL_PWRMGT, THERMAL_PROTECTION_DIS, ~THERMAL_PROTECTION_DIS);
35767ccd5a2cSjsg }
35777ccd5a2cSjsg 
si_enable_acpi_power_management(struct radeon_device * rdev)35787ccd5a2cSjsg static void si_enable_acpi_power_management(struct radeon_device *rdev)
35797ccd5a2cSjsg {
35807ccd5a2cSjsg 	WREG32_P(GENERAL_PWRMGT, STATIC_PM_EN, ~STATIC_PM_EN);
35817ccd5a2cSjsg }
35827ccd5a2cSjsg 
35837ccd5a2cSjsg #if 0
35847ccd5a2cSjsg static int si_enter_ulp_state(struct radeon_device *rdev)
35857ccd5a2cSjsg {
35867ccd5a2cSjsg 	WREG32(SMC_MESSAGE_0, PPSMC_MSG_SwitchToMinimumPower);
35877ccd5a2cSjsg 
35887ccd5a2cSjsg 	udelay(25000);
35897ccd5a2cSjsg 
35907ccd5a2cSjsg 	return 0;
35917ccd5a2cSjsg }
35927ccd5a2cSjsg 
35937ccd5a2cSjsg static int si_exit_ulp_state(struct radeon_device *rdev)
35947ccd5a2cSjsg {
35957ccd5a2cSjsg 	int i;
35967ccd5a2cSjsg 
35977ccd5a2cSjsg 	WREG32(SMC_MESSAGE_0, PPSMC_MSG_ResumeFromMinimumPower);
35987ccd5a2cSjsg 
35997ccd5a2cSjsg 	udelay(7000);
36007ccd5a2cSjsg 
36017ccd5a2cSjsg 	for (i = 0; i < rdev->usec_timeout; i++) {
36027ccd5a2cSjsg 		if (RREG32(SMC_RESP_0) == 1)
36037ccd5a2cSjsg 			break;
36047ccd5a2cSjsg 		udelay(1000);
36057ccd5a2cSjsg 	}
36067ccd5a2cSjsg 
36077ccd5a2cSjsg 	return 0;
36087ccd5a2cSjsg }
36097ccd5a2cSjsg #endif
36107ccd5a2cSjsg 
si_notify_smc_display_change(struct radeon_device * rdev,bool has_display)36117ccd5a2cSjsg static int si_notify_smc_display_change(struct radeon_device *rdev,
36127ccd5a2cSjsg 				     bool has_display)
36137ccd5a2cSjsg {
36147ccd5a2cSjsg 	PPSMC_Msg msg = has_display ?
36157ccd5a2cSjsg 		PPSMC_MSG_HasDisplay : PPSMC_MSG_NoDisplay;
36167ccd5a2cSjsg 
36177ccd5a2cSjsg 	return (si_send_msg_to_smc(rdev, msg) == PPSMC_Result_OK) ?
36187ccd5a2cSjsg 		0 : -EINVAL;
36197ccd5a2cSjsg }
36207ccd5a2cSjsg 
si_program_response_times(struct radeon_device * rdev)36217ccd5a2cSjsg static void si_program_response_times(struct radeon_device *rdev)
36227ccd5a2cSjsg {
3623c349dbc7Sjsg 	u32 voltage_response_time, acpi_delay_time, vbi_time_out;
36247ccd5a2cSjsg 	u32 vddc_dly, acpi_dly, vbi_dly;
36257ccd5a2cSjsg 	u32 reference_clock;
36267ccd5a2cSjsg 
36277ccd5a2cSjsg 	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_mvdd_chg_time, 1);
36287ccd5a2cSjsg 
36297ccd5a2cSjsg 	voltage_response_time = (u32)rdev->pm.dpm.voltage_response_time;
36307ccd5a2cSjsg 
36317ccd5a2cSjsg 	if (voltage_response_time == 0)
36327ccd5a2cSjsg 		voltage_response_time = 1000;
36337ccd5a2cSjsg 
36347ccd5a2cSjsg 	acpi_delay_time = 15000;
36357ccd5a2cSjsg 	vbi_time_out = 100000;
36367ccd5a2cSjsg 
36377ccd5a2cSjsg 	reference_clock = radeon_get_xclk(rdev);
36387ccd5a2cSjsg 
36397ccd5a2cSjsg 	vddc_dly = (voltage_response_time  * reference_clock) / 100;
36407ccd5a2cSjsg 	acpi_dly = (acpi_delay_time * reference_clock) / 100;
36417ccd5a2cSjsg 	vbi_dly  = (vbi_time_out * reference_clock) / 100;
36427ccd5a2cSjsg 
36437ccd5a2cSjsg 	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_delay_vreg,  vddc_dly);
36447ccd5a2cSjsg 	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_delay_acpi,  acpi_dly);
36457ccd5a2cSjsg 	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);
36467ccd5a2cSjsg 	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_mc_block_delay, 0xAA);
36477ccd5a2cSjsg }
36487ccd5a2cSjsg 
si_program_ds_registers(struct radeon_device * rdev)36497ccd5a2cSjsg static void si_program_ds_registers(struct radeon_device *rdev)
36507ccd5a2cSjsg {
36517ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
36527ccd5a2cSjsg 	u32 tmp = 1; /* XXX: 0x10 on tahiti A0 */
36537ccd5a2cSjsg 
36547ccd5a2cSjsg 	if (eg_pi->sclk_deep_sleep) {
36557ccd5a2cSjsg 		WREG32_P(MISC_CLK_CNTL, DEEP_SLEEP_CLK_SEL(tmp), ~DEEP_SLEEP_CLK_SEL_MASK);
36567ccd5a2cSjsg 		WREG32_P(CG_SPLL_AUTOSCALE_CNTL, AUTOSCALE_ON_SS_CLEAR,
36577ccd5a2cSjsg 			 ~AUTOSCALE_ON_SS_CLEAR);
36587ccd5a2cSjsg 	}
36597ccd5a2cSjsg }
36607ccd5a2cSjsg 
si_program_display_gap(struct radeon_device * rdev)36617ccd5a2cSjsg static void si_program_display_gap(struct radeon_device *rdev)
36627ccd5a2cSjsg {
36637ccd5a2cSjsg 	u32 tmp, pipe;
36647ccd5a2cSjsg 	int i;
36657ccd5a2cSjsg 
36667ccd5a2cSjsg 	tmp = RREG32(CG_DISPLAY_GAP_CNTL) & ~(DISP1_GAP_MASK | DISP2_GAP_MASK);
36677ccd5a2cSjsg 	if (rdev->pm.dpm.new_active_crtc_count > 0)
36687ccd5a2cSjsg 		tmp |= DISP1_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM);
36697ccd5a2cSjsg 	else
36707ccd5a2cSjsg 		tmp |= DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE);
36717ccd5a2cSjsg 
36727ccd5a2cSjsg 	if (rdev->pm.dpm.new_active_crtc_count > 1)
36737ccd5a2cSjsg 		tmp |= DISP2_GAP(R600_PM_DISPLAY_GAP_VBLANK_OR_WM);
36747ccd5a2cSjsg 	else
36757ccd5a2cSjsg 		tmp |= DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE);
36767ccd5a2cSjsg 
36777ccd5a2cSjsg 	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
36787ccd5a2cSjsg 
36797ccd5a2cSjsg 	tmp = RREG32(DCCG_DISP_SLOW_SELECT_REG);
36807ccd5a2cSjsg 	pipe = (tmp & DCCG_DISP1_SLOW_SELECT_MASK) >> DCCG_DISP1_SLOW_SELECT_SHIFT;
36817ccd5a2cSjsg 
36827ccd5a2cSjsg 	if ((rdev->pm.dpm.new_active_crtc_count > 0) &&
36837ccd5a2cSjsg 	    (!(rdev->pm.dpm.new_active_crtcs & (1 << pipe)))) {
36847ccd5a2cSjsg 		/* find the first active crtc */
36857ccd5a2cSjsg 		for (i = 0; i < rdev->num_crtc; i++) {
36867ccd5a2cSjsg 			if (rdev->pm.dpm.new_active_crtcs & (1 << i))
36877ccd5a2cSjsg 				break;
36887ccd5a2cSjsg 		}
36897ccd5a2cSjsg 		if (i == rdev->num_crtc)
36907ccd5a2cSjsg 			pipe = 0;
36917ccd5a2cSjsg 		else
36927ccd5a2cSjsg 			pipe = i;
36937ccd5a2cSjsg 
36947ccd5a2cSjsg 		tmp &= ~DCCG_DISP1_SLOW_SELECT_MASK;
36957ccd5a2cSjsg 		tmp |= DCCG_DISP1_SLOW_SELECT(pipe);
36967ccd5a2cSjsg 		WREG32(DCCG_DISP_SLOW_SELECT_REG, tmp);
36977ccd5a2cSjsg 	}
36987ccd5a2cSjsg 
36997ccd5a2cSjsg 	/* Setting this to false forces the performance state to low if the crtcs are disabled.
37007ccd5a2cSjsg 	 * This can be a problem on PowerXpress systems or if you want to use the card
37017ccd5a2cSjsg 	 * for offscreen rendering or compute if there are no crtcs enabled.
37027ccd5a2cSjsg 	 */
37037ccd5a2cSjsg 	si_notify_smc_display_change(rdev, rdev->pm.dpm.new_active_crtc_count > 0);
37047ccd5a2cSjsg }
37057ccd5a2cSjsg 
si_enable_spread_spectrum(struct radeon_device * rdev,bool enable)37067ccd5a2cSjsg static void si_enable_spread_spectrum(struct radeon_device *rdev, bool enable)
37077ccd5a2cSjsg {
37087ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
37097ccd5a2cSjsg 
37107ccd5a2cSjsg 	if (enable) {
37117ccd5a2cSjsg 		if (pi->sclk_ss)
37127ccd5a2cSjsg 			WREG32_P(GENERAL_PWRMGT, DYN_SPREAD_SPECTRUM_EN, ~DYN_SPREAD_SPECTRUM_EN);
37137ccd5a2cSjsg 	} else {
37147ccd5a2cSjsg 		WREG32_P(CG_SPLL_SPREAD_SPECTRUM, 0, ~SSEN);
37157ccd5a2cSjsg 		WREG32_P(GENERAL_PWRMGT, 0, ~DYN_SPREAD_SPECTRUM_EN);
37167ccd5a2cSjsg 	}
37177ccd5a2cSjsg }
37187ccd5a2cSjsg 
si_setup_bsp(struct radeon_device * rdev)37197ccd5a2cSjsg static void si_setup_bsp(struct radeon_device *rdev)
37207ccd5a2cSjsg {
37217ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
37227ccd5a2cSjsg 	u32 xclk = radeon_get_xclk(rdev);
37237ccd5a2cSjsg 
37247ccd5a2cSjsg 	r600_calculate_u_and_p(pi->asi,
37257ccd5a2cSjsg 			       xclk,
37267ccd5a2cSjsg 			       16,
37277ccd5a2cSjsg 			       &pi->bsp,
37287ccd5a2cSjsg 			       &pi->bsu);
37297ccd5a2cSjsg 
37307ccd5a2cSjsg 	r600_calculate_u_and_p(pi->pasi,
37317ccd5a2cSjsg 			       xclk,
37327ccd5a2cSjsg 			       16,
37337ccd5a2cSjsg 			       &pi->pbsp,
37347ccd5a2cSjsg 			       &pi->pbsu);
37357ccd5a2cSjsg 
37367ccd5a2cSjsg 
37377ccd5a2cSjsg 	pi->dsp = BSP(pi->bsp) | BSU(pi->bsu);
37387ccd5a2cSjsg 	pi->psp = BSP(pi->pbsp) | BSU(pi->pbsu);
37397ccd5a2cSjsg 
37407ccd5a2cSjsg 	WREG32(CG_BSP, pi->dsp);
37417ccd5a2cSjsg }
37427ccd5a2cSjsg 
si_program_git(struct radeon_device * rdev)37437ccd5a2cSjsg static void si_program_git(struct radeon_device *rdev)
37447ccd5a2cSjsg {
37457ccd5a2cSjsg 	WREG32_P(CG_GIT, CG_GICST(R600_GICST_DFLT), ~CG_GICST_MASK);
37467ccd5a2cSjsg }
37477ccd5a2cSjsg 
si_program_tp(struct radeon_device * rdev)37487ccd5a2cSjsg static void si_program_tp(struct radeon_device *rdev)
37497ccd5a2cSjsg {
37507ccd5a2cSjsg 	int i;
37517ccd5a2cSjsg 	enum r600_td td = R600_TD_DFLT;
37527ccd5a2cSjsg 
37537ccd5a2cSjsg 	for (i = 0; i < R600_PM_NUMBER_OF_TC; i++)
37547ccd5a2cSjsg 		WREG32(CG_FFCT_0 + (i * 4), (UTC_0(r600_utc[i]) | DTC_0(r600_dtc[i])));
37557ccd5a2cSjsg 
37567ccd5a2cSjsg 	if (td == R600_TD_AUTO)
37577ccd5a2cSjsg 		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_FORCE_TREND_SEL);
37587ccd5a2cSjsg 	else
37597ccd5a2cSjsg 		WREG32_P(SCLK_PWRMGT_CNTL, FIR_FORCE_TREND_SEL, ~FIR_FORCE_TREND_SEL);
37607ccd5a2cSjsg 
37617ccd5a2cSjsg 	if (td == R600_TD_UP)
37627ccd5a2cSjsg 		WREG32_P(SCLK_PWRMGT_CNTL, 0, ~FIR_TREND_MODE);
37637ccd5a2cSjsg 
37647ccd5a2cSjsg 	if (td == R600_TD_DOWN)
37657ccd5a2cSjsg 		WREG32_P(SCLK_PWRMGT_CNTL, FIR_TREND_MODE, ~FIR_TREND_MODE);
37667ccd5a2cSjsg }
37677ccd5a2cSjsg 
si_program_tpp(struct radeon_device * rdev)37687ccd5a2cSjsg static void si_program_tpp(struct radeon_device *rdev)
37697ccd5a2cSjsg {
37707ccd5a2cSjsg 	WREG32(CG_TPC, R600_TPC_DFLT);
37717ccd5a2cSjsg }
37727ccd5a2cSjsg 
si_program_sstp(struct radeon_device * rdev)37737ccd5a2cSjsg static void si_program_sstp(struct radeon_device *rdev)
37747ccd5a2cSjsg {
37757ccd5a2cSjsg 	WREG32(CG_SSP, (SSTU(R600_SSTU_DFLT) | SST(R600_SST_DFLT)));
37767ccd5a2cSjsg }
37777ccd5a2cSjsg 
si_enable_display_gap(struct radeon_device * rdev)37787ccd5a2cSjsg static void si_enable_display_gap(struct radeon_device *rdev)
37797ccd5a2cSjsg {
37807ccd5a2cSjsg 	u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
37817ccd5a2cSjsg 
37827ccd5a2cSjsg 	tmp &= ~(DISP1_GAP_MASK | DISP2_GAP_MASK);
37837ccd5a2cSjsg 	tmp |= (DISP1_GAP(R600_PM_DISPLAY_GAP_IGNORE) |
37847ccd5a2cSjsg 		DISP2_GAP(R600_PM_DISPLAY_GAP_IGNORE));
37857ccd5a2cSjsg 
37867ccd5a2cSjsg 	tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
37877ccd5a2cSjsg 	tmp |= (DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK) |
37887ccd5a2cSjsg 		DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE));
37897ccd5a2cSjsg 	WREG32(CG_DISPLAY_GAP_CNTL, tmp);
37907ccd5a2cSjsg }
37917ccd5a2cSjsg 
si_program_vc(struct radeon_device * rdev)37927ccd5a2cSjsg static void si_program_vc(struct radeon_device *rdev)
37937ccd5a2cSjsg {
37947ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
37957ccd5a2cSjsg 
37967ccd5a2cSjsg 	WREG32(CG_FTV, pi->vrc);
37977ccd5a2cSjsg }
37987ccd5a2cSjsg 
si_clear_vc(struct radeon_device * rdev)37997ccd5a2cSjsg static void si_clear_vc(struct radeon_device *rdev)
38007ccd5a2cSjsg {
38017ccd5a2cSjsg 	WREG32(CG_FTV, 0);
38027ccd5a2cSjsg }
38037ccd5a2cSjsg 
si_get_ddr3_mclk_frequency_ratio(u32 memory_clock)38047ccd5a2cSjsg u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock)
38057ccd5a2cSjsg {
38067ccd5a2cSjsg 	u8 mc_para_index;
38077ccd5a2cSjsg 
38087ccd5a2cSjsg 	if (memory_clock < 10000)
38097ccd5a2cSjsg 		mc_para_index = 0;
38107ccd5a2cSjsg 	else if (memory_clock >= 80000)
38117ccd5a2cSjsg 		mc_para_index = 0x0f;
38127ccd5a2cSjsg 	else
38137ccd5a2cSjsg 		mc_para_index = (u8)((memory_clock - 10000) / 5000 + 1);
38147ccd5a2cSjsg 	return mc_para_index;
38157ccd5a2cSjsg }
38167ccd5a2cSjsg 
si_get_mclk_frequency_ratio(u32 memory_clock,bool strobe_mode)38177ccd5a2cSjsg u8 si_get_mclk_frequency_ratio(u32 memory_clock, bool strobe_mode)
38187ccd5a2cSjsg {
38197ccd5a2cSjsg 	u8 mc_para_index;
38207ccd5a2cSjsg 
38217ccd5a2cSjsg 	if (strobe_mode) {
38227ccd5a2cSjsg 		if (memory_clock < 12500)
38237ccd5a2cSjsg 			mc_para_index = 0x00;
38247ccd5a2cSjsg 		else if (memory_clock > 47500)
38257ccd5a2cSjsg 			mc_para_index = 0x0f;
38267ccd5a2cSjsg 		else
38277ccd5a2cSjsg 			mc_para_index = (u8)((memory_clock - 10000) / 2500);
38287ccd5a2cSjsg 	} else {
38297ccd5a2cSjsg 		if (memory_clock < 65000)
38307ccd5a2cSjsg 			mc_para_index = 0x00;
38317ccd5a2cSjsg 		else if (memory_clock > 135000)
38327ccd5a2cSjsg 			mc_para_index = 0x0f;
38337ccd5a2cSjsg 		else
38347ccd5a2cSjsg 			mc_para_index = (u8)((memory_clock - 60000) / 5000);
38357ccd5a2cSjsg 	}
38367ccd5a2cSjsg 	return mc_para_index;
38377ccd5a2cSjsg }
38387ccd5a2cSjsg 
si_get_strobe_mode_settings(struct radeon_device * rdev,u32 mclk)38397ccd5a2cSjsg static u8 si_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk)
38407ccd5a2cSjsg {
38417ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
38427ccd5a2cSjsg 	bool strobe_mode = false;
38437ccd5a2cSjsg 	u8 result = 0;
38447ccd5a2cSjsg 
38457ccd5a2cSjsg 	if (mclk <= pi->mclk_strobe_mode_threshold)
38467ccd5a2cSjsg 		strobe_mode = true;
38477ccd5a2cSjsg 
38487ccd5a2cSjsg 	if (pi->mem_gddr5)
38497ccd5a2cSjsg 		result = si_get_mclk_frequency_ratio(mclk, strobe_mode);
38507ccd5a2cSjsg 	else
38517ccd5a2cSjsg 		result = si_get_ddr3_mclk_frequency_ratio(mclk);
38527ccd5a2cSjsg 
38537ccd5a2cSjsg 	if (strobe_mode)
38547ccd5a2cSjsg 		result |= SISLANDS_SMC_STROBE_ENABLE;
38557ccd5a2cSjsg 
38567ccd5a2cSjsg 	return result;
38577ccd5a2cSjsg }
38587ccd5a2cSjsg 
si_upload_firmware(struct radeon_device * rdev)38597ccd5a2cSjsg static int si_upload_firmware(struct radeon_device *rdev)
38607ccd5a2cSjsg {
38617ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
38627ccd5a2cSjsg 	int ret;
38637ccd5a2cSjsg 
38647ccd5a2cSjsg 	si_reset_smc(rdev);
38657ccd5a2cSjsg 	si_stop_smc_clock(rdev);
38667ccd5a2cSjsg 
38677ccd5a2cSjsg 	ret = si_load_smc_ucode(rdev, si_pi->sram_end);
38687ccd5a2cSjsg 
38697ccd5a2cSjsg 	return ret;
38707ccd5a2cSjsg }
38717ccd5a2cSjsg 
si_validate_phase_shedding_tables(struct radeon_device * rdev,const struct atom_voltage_table * table,const struct radeon_phase_shedding_limits_table * limits)38727ccd5a2cSjsg static bool si_validate_phase_shedding_tables(struct radeon_device *rdev,
38737ccd5a2cSjsg 					      const struct atom_voltage_table *table,
38747ccd5a2cSjsg 					      const struct radeon_phase_shedding_limits_table *limits)
38757ccd5a2cSjsg {
38767ccd5a2cSjsg 	u32 data, num_bits, num_levels;
38777ccd5a2cSjsg 
38787ccd5a2cSjsg 	if ((table == NULL) || (limits == NULL))
38797ccd5a2cSjsg 		return false;
38807ccd5a2cSjsg 
38817ccd5a2cSjsg 	data = table->mask_low;
38827ccd5a2cSjsg 
38837ccd5a2cSjsg 	num_bits = hweight32(data);
38847ccd5a2cSjsg 
38857ccd5a2cSjsg 	if (num_bits == 0)
38867ccd5a2cSjsg 		return false;
38877ccd5a2cSjsg 
38887ccd5a2cSjsg 	num_levels = (1 << num_bits);
38897ccd5a2cSjsg 
38907ccd5a2cSjsg 	if (table->count != num_levels)
38917ccd5a2cSjsg 		return false;
38927ccd5a2cSjsg 
38937ccd5a2cSjsg 	if (limits->count != (num_levels - 1))
38947ccd5a2cSjsg 		return false;
38957ccd5a2cSjsg 
38967ccd5a2cSjsg 	return true;
38977ccd5a2cSjsg }
38987ccd5a2cSjsg 
si_trim_voltage_table_to_fit_state_table(struct radeon_device * rdev,u32 max_voltage_steps,struct atom_voltage_table * voltage_table)38997ccd5a2cSjsg void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev,
39007ccd5a2cSjsg 					      u32 max_voltage_steps,
39017ccd5a2cSjsg 					      struct atom_voltage_table *voltage_table)
39027ccd5a2cSjsg {
39037ccd5a2cSjsg 	unsigned int i, diff;
39047ccd5a2cSjsg 
39057ccd5a2cSjsg 	if (voltage_table->count <= max_voltage_steps)
39067ccd5a2cSjsg 		return;
39077ccd5a2cSjsg 
39087ccd5a2cSjsg 	diff = voltage_table->count - max_voltage_steps;
39097ccd5a2cSjsg 
39107ccd5a2cSjsg 	for (i= 0; i < max_voltage_steps; i++)
39117ccd5a2cSjsg 		voltage_table->entries[i] = voltage_table->entries[i + diff];
39127ccd5a2cSjsg 
39137ccd5a2cSjsg 	voltage_table->count = max_voltage_steps;
39147ccd5a2cSjsg }
39157ccd5a2cSjsg 
si_get_svi2_voltage_table(struct radeon_device * rdev,struct radeon_clock_voltage_dependency_table * voltage_dependency_table,struct atom_voltage_table * voltage_table)39167ccd5a2cSjsg static int si_get_svi2_voltage_table(struct radeon_device *rdev,
39177ccd5a2cSjsg 				     struct radeon_clock_voltage_dependency_table *voltage_dependency_table,
39187ccd5a2cSjsg 				     struct atom_voltage_table *voltage_table)
39197ccd5a2cSjsg {
39207ccd5a2cSjsg 	u32 i;
39217ccd5a2cSjsg 
39227ccd5a2cSjsg 	if (voltage_dependency_table == NULL)
39237ccd5a2cSjsg 		return -EINVAL;
39247ccd5a2cSjsg 
39257ccd5a2cSjsg 	voltage_table->mask_low = 0;
39267ccd5a2cSjsg 	voltage_table->phase_delay = 0;
39277ccd5a2cSjsg 
39287ccd5a2cSjsg 	voltage_table->count = voltage_dependency_table->count;
39297ccd5a2cSjsg 	for (i = 0; i < voltage_table->count; i++) {
39307ccd5a2cSjsg 		voltage_table->entries[i].value = voltage_dependency_table->entries[i].v;
39317ccd5a2cSjsg 		voltage_table->entries[i].smio_low = 0;
39327ccd5a2cSjsg 	}
39337ccd5a2cSjsg 
39347ccd5a2cSjsg 	return 0;
39357ccd5a2cSjsg }
39367ccd5a2cSjsg 
si_construct_voltage_tables(struct radeon_device * rdev)39377ccd5a2cSjsg static int si_construct_voltage_tables(struct radeon_device *rdev)
39387ccd5a2cSjsg {
39397ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
39407ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
39417ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
39427ccd5a2cSjsg 	int ret;
39437ccd5a2cSjsg 
39447ccd5a2cSjsg 	if (pi->voltage_control) {
39457ccd5a2cSjsg 		ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDC,
39467ccd5a2cSjsg 						    VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddc_voltage_table);
39477ccd5a2cSjsg 		if (ret)
39487ccd5a2cSjsg 			return ret;
39497ccd5a2cSjsg 
39507ccd5a2cSjsg 		if (eg_pi->vddc_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
39517ccd5a2cSjsg 			si_trim_voltage_table_to_fit_state_table(rdev,
39527ccd5a2cSjsg 								 SISLANDS_MAX_NO_VREG_STEPS,
39537ccd5a2cSjsg 								 &eg_pi->vddc_voltage_table);
39547ccd5a2cSjsg 	} else if (si_pi->voltage_control_svi2) {
39557ccd5a2cSjsg 		ret = si_get_svi2_voltage_table(rdev,
39567ccd5a2cSjsg 						&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
39577ccd5a2cSjsg 						&eg_pi->vddc_voltage_table);
39587ccd5a2cSjsg 		if (ret)
39597ccd5a2cSjsg 			return ret;
39607ccd5a2cSjsg 	} else {
39617ccd5a2cSjsg 		return -EINVAL;
39627ccd5a2cSjsg 	}
39637ccd5a2cSjsg 
39647ccd5a2cSjsg 	if (eg_pi->vddci_control) {
39657ccd5a2cSjsg 		ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDCI,
39667ccd5a2cSjsg 						    VOLTAGE_OBJ_GPIO_LUT, &eg_pi->vddci_voltage_table);
39677ccd5a2cSjsg 		if (ret)
39687ccd5a2cSjsg 			return ret;
39697ccd5a2cSjsg 
39707ccd5a2cSjsg 		if (eg_pi->vddci_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
39717ccd5a2cSjsg 			si_trim_voltage_table_to_fit_state_table(rdev,
39727ccd5a2cSjsg 								 SISLANDS_MAX_NO_VREG_STEPS,
39737ccd5a2cSjsg 								 &eg_pi->vddci_voltage_table);
39747ccd5a2cSjsg 	}
39757ccd5a2cSjsg 	if (si_pi->vddci_control_svi2) {
39767ccd5a2cSjsg 		ret = si_get_svi2_voltage_table(rdev,
39777ccd5a2cSjsg 						&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
39787ccd5a2cSjsg 						&eg_pi->vddci_voltage_table);
39797ccd5a2cSjsg 		if (ret)
39807ccd5a2cSjsg 			return ret;
39817ccd5a2cSjsg 	}
39827ccd5a2cSjsg 
39837ccd5a2cSjsg 	if (pi->mvdd_control) {
39847ccd5a2cSjsg 		ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_MVDDC,
39857ccd5a2cSjsg 						    VOLTAGE_OBJ_GPIO_LUT, &si_pi->mvdd_voltage_table);
39867ccd5a2cSjsg 
39877ccd5a2cSjsg 		if (ret) {
39887ccd5a2cSjsg 			pi->mvdd_control = false;
39897ccd5a2cSjsg 			return ret;
39907ccd5a2cSjsg 		}
39917ccd5a2cSjsg 
39927ccd5a2cSjsg 		if (si_pi->mvdd_voltage_table.count == 0) {
39937ccd5a2cSjsg 			pi->mvdd_control = false;
39947ccd5a2cSjsg 			return -EINVAL;
39957ccd5a2cSjsg 		}
39967ccd5a2cSjsg 
39977ccd5a2cSjsg 		if (si_pi->mvdd_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS)
39987ccd5a2cSjsg 			si_trim_voltage_table_to_fit_state_table(rdev,
39997ccd5a2cSjsg 								 SISLANDS_MAX_NO_VREG_STEPS,
40007ccd5a2cSjsg 								 &si_pi->mvdd_voltage_table);
40017ccd5a2cSjsg 	}
40027ccd5a2cSjsg 
40037ccd5a2cSjsg 	if (si_pi->vddc_phase_shed_control) {
40047ccd5a2cSjsg 		ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDC,
40057ccd5a2cSjsg 						    VOLTAGE_OBJ_PHASE_LUT, &si_pi->vddc_phase_shed_table);
40067ccd5a2cSjsg 		if (ret)
40077ccd5a2cSjsg 			si_pi->vddc_phase_shed_control = false;
40087ccd5a2cSjsg 
40097ccd5a2cSjsg 		if ((si_pi->vddc_phase_shed_table.count == 0) ||
40107ccd5a2cSjsg 		    (si_pi->vddc_phase_shed_table.count > SISLANDS_MAX_NO_VREG_STEPS))
40117ccd5a2cSjsg 			si_pi->vddc_phase_shed_control = false;
40127ccd5a2cSjsg 	}
40137ccd5a2cSjsg 
40147ccd5a2cSjsg 	return 0;
40157ccd5a2cSjsg }
40167ccd5a2cSjsg 
si_populate_smc_voltage_table(struct radeon_device * rdev,const struct atom_voltage_table * voltage_table,SISLANDS_SMC_STATETABLE * table)40177ccd5a2cSjsg static void si_populate_smc_voltage_table(struct radeon_device *rdev,
40187ccd5a2cSjsg 					  const struct atom_voltage_table *voltage_table,
40197ccd5a2cSjsg 					  SISLANDS_SMC_STATETABLE *table)
40207ccd5a2cSjsg {
40217ccd5a2cSjsg 	unsigned int i;
40227ccd5a2cSjsg 
40237ccd5a2cSjsg 	for (i = 0; i < voltage_table->count; i++)
40247ccd5a2cSjsg 		table->lowSMIO[i] |= cpu_to_be32(voltage_table->entries[i].smio_low);
40257ccd5a2cSjsg }
40267ccd5a2cSjsg 
si_populate_smc_voltage_tables(struct radeon_device * rdev,SISLANDS_SMC_STATETABLE * table)40277ccd5a2cSjsg static int si_populate_smc_voltage_tables(struct radeon_device *rdev,
40287ccd5a2cSjsg 					  SISLANDS_SMC_STATETABLE *table)
40297ccd5a2cSjsg {
40307ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
40317ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
40327ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
40337ccd5a2cSjsg 	u8 i;
40347ccd5a2cSjsg 
40357ccd5a2cSjsg 	if (si_pi->voltage_control_svi2) {
40367ccd5a2cSjsg 		si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svc,
40377ccd5a2cSjsg 			si_pi->svc_gpio_id);
40387ccd5a2cSjsg 		si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_gpio_id_svd,
40397ccd5a2cSjsg 			si_pi->svd_gpio_id);
40407ccd5a2cSjsg 		si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_svi_rework_plat_type,
40417ccd5a2cSjsg 					   2);
40427ccd5a2cSjsg 	} else {
40437ccd5a2cSjsg 		if (eg_pi->vddc_voltage_table.count) {
40447ccd5a2cSjsg 			si_populate_smc_voltage_table(rdev, &eg_pi->vddc_voltage_table, table);
40457ccd5a2cSjsg 			table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
40467ccd5a2cSjsg 				cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
40477ccd5a2cSjsg 
40487ccd5a2cSjsg 			for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {
40497ccd5a2cSjsg 				if (pi->max_vddc_in_table <= eg_pi->vddc_voltage_table.entries[i].value) {
40507ccd5a2cSjsg 					table->maxVDDCIndexInPPTable = i;
40517ccd5a2cSjsg 					break;
40527ccd5a2cSjsg 				}
40537ccd5a2cSjsg 			}
40547ccd5a2cSjsg 		}
40557ccd5a2cSjsg 
40567ccd5a2cSjsg 		if (eg_pi->vddci_voltage_table.count) {
40577ccd5a2cSjsg 			si_populate_smc_voltage_table(rdev, &eg_pi->vddci_voltage_table, table);
40587ccd5a2cSjsg 
40597ccd5a2cSjsg 			table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDCI] =
40607ccd5a2cSjsg 				cpu_to_be32(eg_pi->vddci_voltage_table.mask_low);
40617ccd5a2cSjsg 		}
40627ccd5a2cSjsg 
40637ccd5a2cSjsg 
40647ccd5a2cSjsg 		if (si_pi->mvdd_voltage_table.count) {
40657ccd5a2cSjsg 			si_populate_smc_voltage_table(rdev, &si_pi->mvdd_voltage_table, table);
40667ccd5a2cSjsg 
40677ccd5a2cSjsg 			table->voltageMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_MVDD] =
40687ccd5a2cSjsg 				cpu_to_be32(si_pi->mvdd_voltage_table.mask_low);
40697ccd5a2cSjsg 		}
40707ccd5a2cSjsg 
40717ccd5a2cSjsg 		if (si_pi->vddc_phase_shed_control) {
40727ccd5a2cSjsg 			if (si_validate_phase_shedding_tables(rdev, &si_pi->vddc_phase_shed_table,
40737ccd5a2cSjsg 							      &rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) {
40747ccd5a2cSjsg 				si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table);
40757ccd5a2cSjsg 
40767ccd5a2cSjsg 				table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] =
40777ccd5a2cSjsg 					cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low);
40787ccd5a2cSjsg 
40797ccd5a2cSjsg 				si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay,
40807ccd5a2cSjsg 							   (u32)si_pi->vddc_phase_shed_table.phase_delay);
40817ccd5a2cSjsg 			} else {
40827ccd5a2cSjsg 				si_pi->vddc_phase_shed_control = false;
40837ccd5a2cSjsg 			}
40847ccd5a2cSjsg 		}
40857ccd5a2cSjsg 	}
40867ccd5a2cSjsg 
40877ccd5a2cSjsg 	return 0;
40887ccd5a2cSjsg }
40897ccd5a2cSjsg 
si_populate_voltage_value(struct radeon_device * rdev,const struct atom_voltage_table * table,u16 value,SISLANDS_SMC_VOLTAGE_VALUE * voltage)40907ccd5a2cSjsg static int si_populate_voltage_value(struct radeon_device *rdev,
40917ccd5a2cSjsg 				     const struct atom_voltage_table *table,
40927ccd5a2cSjsg 				     u16 value, SISLANDS_SMC_VOLTAGE_VALUE *voltage)
40937ccd5a2cSjsg {
40947ccd5a2cSjsg 	unsigned int i;
40957ccd5a2cSjsg 
40967ccd5a2cSjsg 	for (i = 0; i < table->count; i++) {
40977ccd5a2cSjsg 		if (value <= table->entries[i].value) {
40987ccd5a2cSjsg 			voltage->index = (u8)i;
40997ccd5a2cSjsg 			voltage->value = cpu_to_be16(table->entries[i].value);
41007ccd5a2cSjsg 			break;
41017ccd5a2cSjsg 		}
41027ccd5a2cSjsg 	}
41037ccd5a2cSjsg 
41047ccd5a2cSjsg 	if (i >= table->count)
41057ccd5a2cSjsg 		return -EINVAL;
41067ccd5a2cSjsg 
41077ccd5a2cSjsg 	return 0;
41087ccd5a2cSjsg }
41097ccd5a2cSjsg 
si_populate_mvdd_value(struct radeon_device * rdev,u32 mclk,SISLANDS_SMC_VOLTAGE_VALUE * voltage)41107ccd5a2cSjsg static int si_populate_mvdd_value(struct radeon_device *rdev, u32 mclk,
41117ccd5a2cSjsg 				  SISLANDS_SMC_VOLTAGE_VALUE *voltage)
41127ccd5a2cSjsg {
41137ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
41147ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
41157ccd5a2cSjsg 
41167ccd5a2cSjsg 	if (pi->mvdd_control) {
41177ccd5a2cSjsg 		if (mclk <= pi->mvdd_split_frequency)
41187ccd5a2cSjsg 			voltage->index = 0;
41197ccd5a2cSjsg 		else
41207ccd5a2cSjsg 			voltage->index = (u8)(si_pi->mvdd_voltage_table.count) - 1;
41217ccd5a2cSjsg 
41227ccd5a2cSjsg 		voltage->value = cpu_to_be16(si_pi->mvdd_voltage_table.entries[voltage->index].value);
41237ccd5a2cSjsg 	}
41247ccd5a2cSjsg 	return 0;
41257ccd5a2cSjsg }
41267ccd5a2cSjsg 
si_get_std_voltage_value(struct radeon_device * rdev,SISLANDS_SMC_VOLTAGE_VALUE * voltage,u16 * std_voltage)41277ccd5a2cSjsg static int si_get_std_voltage_value(struct radeon_device *rdev,
41287ccd5a2cSjsg 				    SISLANDS_SMC_VOLTAGE_VALUE *voltage,
41297ccd5a2cSjsg 				    u16 *std_voltage)
41307ccd5a2cSjsg {
41317ccd5a2cSjsg 	u16 v_index;
41327ccd5a2cSjsg 	bool voltage_found = false;
41337ccd5a2cSjsg 	*std_voltage = be16_to_cpu(voltage->value);
41347ccd5a2cSjsg 
41357ccd5a2cSjsg 	if (rdev->pm.dpm.dyn_state.cac_leakage_table.entries) {
41367ccd5a2cSjsg 		if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_NEW_CAC_VOLTAGE) {
41377ccd5a2cSjsg 			if (rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries == NULL)
41387ccd5a2cSjsg 				return -EINVAL;
41397ccd5a2cSjsg 
41407ccd5a2cSjsg 			for (v_index = 0; (u32)v_index < rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; v_index++) {
41417ccd5a2cSjsg 				if (be16_to_cpu(voltage->value) ==
41427ccd5a2cSjsg 				    (u16)rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[v_index].v) {
41437ccd5a2cSjsg 					voltage_found = true;
41447ccd5a2cSjsg 					if ((u32)v_index < rdev->pm.dpm.dyn_state.cac_leakage_table.count)
41457ccd5a2cSjsg 						*std_voltage =
41467ccd5a2cSjsg 							rdev->pm.dpm.dyn_state.cac_leakage_table.entries[v_index].vddc;
41477ccd5a2cSjsg 					else
41487ccd5a2cSjsg 						*std_voltage =
41497ccd5a2cSjsg 							rdev->pm.dpm.dyn_state.cac_leakage_table.entries[rdev->pm.dpm.dyn_state.cac_leakage_table.count-1].vddc;
41507ccd5a2cSjsg 					break;
41517ccd5a2cSjsg 				}
41527ccd5a2cSjsg 			}
41537ccd5a2cSjsg 
41547ccd5a2cSjsg 			if (!voltage_found) {
41557ccd5a2cSjsg 				for (v_index = 0; (u32)v_index < rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.count; v_index++) {
41567ccd5a2cSjsg 					if (be16_to_cpu(voltage->value) <=
41577ccd5a2cSjsg 					    (u16)rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk.entries[v_index].v) {
41587ccd5a2cSjsg 						voltage_found = true;
41597ccd5a2cSjsg 						if ((u32)v_index < rdev->pm.dpm.dyn_state.cac_leakage_table.count)
41607ccd5a2cSjsg 							*std_voltage =
41617ccd5a2cSjsg 								rdev->pm.dpm.dyn_state.cac_leakage_table.entries[v_index].vddc;
41627ccd5a2cSjsg 						else
41637ccd5a2cSjsg 							*std_voltage =
41647ccd5a2cSjsg 								rdev->pm.dpm.dyn_state.cac_leakage_table.entries[rdev->pm.dpm.dyn_state.cac_leakage_table.count-1].vddc;
41657ccd5a2cSjsg 						break;
41667ccd5a2cSjsg 					}
41677ccd5a2cSjsg 				}
41687ccd5a2cSjsg 			}
41697ccd5a2cSjsg 		} else {
41707ccd5a2cSjsg 			if ((u32)voltage->index < rdev->pm.dpm.dyn_state.cac_leakage_table.count)
41717ccd5a2cSjsg 				*std_voltage = rdev->pm.dpm.dyn_state.cac_leakage_table.entries[voltage->index].vddc;
41727ccd5a2cSjsg 		}
41737ccd5a2cSjsg 	}
41747ccd5a2cSjsg 
41757ccd5a2cSjsg 	return 0;
41767ccd5a2cSjsg }
41777ccd5a2cSjsg 
si_populate_std_voltage_value(struct radeon_device * rdev,u16 value,u8 index,SISLANDS_SMC_VOLTAGE_VALUE * voltage)41787ccd5a2cSjsg static int si_populate_std_voltage_value(struct radeon_device *rdev,
41797ccd5a2cSjsg 					 u16 value, u8 index,
41807ccd5a2cSjsg 					 SISLANDS_SMC_VOLTAGE_VALUE *voltage)
41817ccd5a2cSjsg {
41827ccd5a2cSjsg 	voltage->index = index;
41837ccd5a2cSjsg 	voltage->value = cpu_to_be16(value);
41847ccd5a2cSjsg 
41857ccd5a2cSjsg 	return 0;
41867ccd5a2cSjsg }
41877ccd5a2cSjsg 
si_populate_phase_shedding_value(struct radeon_device * rdev,const struct radeon_phase_shedding_limits_table * limits,u16 voltage,u32 sclk,u32 mclk,SISLANDS_SMC_VOLTAGE_VALUE * smc_voltage)41887ccd5a2cSjsg static int si_populate_phase_shedding_value(struct radeon_device *rdev,
41897ccd5a2cSjsg 					    const struct radeon_phase_shedding_limits_table *limits,
41907ccd5a2cSjsg 					    u16 voltage, u32 sclk, u32 mclk,
41917ccd5a2cSjsg 					    SISLANDS_SMC_VOLTAGE_VALUE *smc_voltage)
41927ccd5a2cSjsg {
41937ccd5a2cSjsg 	unsigned int i;
41947ccd5a2cSjsg 
41957ccd5a2cSjsg 	for (i = 0; i < limits->count; i++) {
41967ccd5a2cSjsg 		if ((voltage <= limits->entries[i].voltage) &&
41977ccd5a2cSjsg 		    (sclk <= limits->entries[i].sclk) &&
41987ccd5a2cSjsg 		    (mclk <= limits->entries[i].mclk))
41997ccd5a2cSjsg 			break;
42007ccd5a2cSjsg 	}
42017ccd5a2cSjsg 
42027ccd5a2cSjsg 	smc_voltage->phase_settings = (u8)i;
42037ccd5a2cSjsg 
42047ccd5a2cSjsg 	return 0;
42057ccd5a2cSjsg }
42067ccd5a2cSjsg 
si_init_arb_table_index(struct radeon_device * rdev)42077ccd5a2cSjsg static int si_init_arb_table_index(struct radeon_device *rdev)
42087ccd5a2cSjsg {
42097ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
42107ccd5a2cSjsg 	u32 tmp;
42117ccd5a2cSjsg 	int ret;
42127ccd5a2cSjsg 
42137ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev, si_pi->arb_table_start, &tmp, si_pi->sram_end);
42147ccd5a2cSjsg 	if (ret)
42157ccd5a2cSjsg 		return ret;
42167ccd5a2cSjsg 
42177ccd5a2cSjsg 	tmp &= 0x00FFFFFF;
42187ccd5a2cSjsg 	tmp |= MC_CG_ARB_FREQ_F1 << 24;
42197ccd5a2cSjsg 
42207ccd5a2cSjsg 	return si_write_smc_sram_dword(rdev, si_pi->arb_table_start,  tmp, si_pi->sram_end);
42217ccd5a2cSjsg }
42227ccd5a2cSjsg 
si_initial_switch_from_arb_f0_to_f1(struct radeon_device * rdev)42237ccd5a2cSjsg static int si_initial_switch_from_arb_f0_to_f1(struct radeon_device *rdev)
42247ccd5a2cSjsg {
42257ccd5a2cSjsg 	return ni_copy_and_switch_arb_sets(rdev, MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);
42267ccd5a2cSjsg }
42277ccd5a2cSjsg 
si_reset_to_default(struct radeon_device * rdev)42287ccd5a2cSjsg static int si_reset_to_default(struct radeon_device *rdev)
42297ccd5a2cSjsg {
42307ccd5a2cSjsg 	return (si_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) == PPSMC_Result_OK) ?
42317ccd5a2cSjsg 		0 : -EINVAL;
42327ccd5a2cSjsg }
42337ccd5a2cSjsg 
si_force_switch_to_arb_f0(struct radeon_device * rdev)42347ccd5a2cSjsg static int si_force_switch_to_arb_f0(struct radeon_device *rdev)
42357ccd5a2cSjsg {
42367ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
42377ccd5a2cSjsg 	u32 tmp;
42387ccd5a2cSjsg 	int ret;
42397ccd5a2cSjsg 
42407ccd5a2cSjsg 	ret = si_read_smc_sram_dword(rdev, si_pi->arb_table_start,
42417ccd5a2cSjsg 				     &tmp, si_pi->sram_end);
42427ccd5a2cSjsg 	if (ret)
42437ccd5a2cSjsg 		return ret;
42447ccd5a2cSjsg 
42457ccd5a2cSjsg 	tmp = (tmp >> 24) & 0xff;
42467ccd5a2cSjsg 
42477ccd5a2cSjsg 	if (tmp == MC_CG_ARB_FREQ_F0)
42487ccd5a2cSjsg 		return 0;
42497ccd5a2cSjsg 
42507ccd5a2cSjsg 	return ni_copy_and_switch_arb_sets(rdev, tmp, MC_CG_ARB_FREQ_F0);
42517ccd5a2cSjsg }
42527ccd5a2cSjsg 
si_calculate_memory_refresh_rate(struct radeon_device * rdev,u32 engine_clock)42537ccd5a2cSjsg static u32 si_calculate_memory_refresh_rate(struct radeon_device *rdev,
42547ccd5a2cSjsg 					    u32 engine_clock)
42557ccd5a2cSjsg {
42567ccd5a2cSjsg 	u32 dram_rows;
42577ccd5a2cSjsg 	u32 dram_refresh_rate;
42587ccd5a2cSjsg 	u32 mc_arb_rfsh_rate;
42597ccd5a2cSjsg 	u32 tmp = (RREG32(MC_ARB_RAMCFG) & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
42607ccd5a2cSjsg 
42617ccd5a2cSjsg 	if (tmp >= 4)
42627ccd5a2cSjsg 		dram_rows = 16384;
42637ccd5a2cSjsg 	else
42647ccd5a2cSjsg 		dram_rows = 1 << (tmp + 10);
42657ccd5a2cSjsg 
42667ccd5a2cSjsg 	dram_refresh_rate = 1 << ((RREG32(MC_SEQ_MISC0) & 0x3) + 3);
42677ccd5a2cSjsg 	mc_arb_rfsh_rate = ((engine_clock * 10) * dram_refresh_rate / dram_rows - 32) / 64;
42687ccd5a2cSjsg 
42697ccd5a2cSjsg 	return mc_arb_rfsh_rate;
42707ccd5a2cSjsg }
42717ccd5a2cSjsg 
si_populate_memory_timing_parameters(struct radeon_device * rdev,struct rv7xx_pl * pl,SMC_SIslands_MCArbDramTimingRegisterSet * arb_regs)42727ccd5a2cSjsg static int si_populate_memory_timing_parameters(struct radeon_device *rdev,
42737ccd5a2cSjsg 						struct rv7xx_pl *pl,
42747ccd5a2cSjsg 						SMC_SIslands_MCArbDramTimingRegisterSet *arb_regs)
42757ccd5a2cSjsg {
42767ccd5a2cSjsg 	u32 dram_timing;
42777ccd5a2cSjsg 	u32 dram_timing2;
42787ccd5a2cSjsg 	u32 burst_time;
42797ccd5a2cSjsg 
42807ccd5a2cSjsg 	arb_regs->mc_arb_rfsh_rate =
42817ccd5a2cSjsg 		(u8)si_calculate_memory_refresh_rate(rdev, pl->sclk);
42827ccd5a2cSjsg 
42837ccd5a2cSjsg 	radeon_atom_set_engine_dram_timings(rdev,
42847ccd5a2cSjsg 					    pl->sclk,
42857ccd5a2cSjsg 					    pl->mclk);
42867ccd5a2cSjsg 
42877ccd5a2cSjsg 	dram_timing  = RREG32(MC_ARB_DRAM_TIMING);
42887ccd5a2cSjsg 	dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
42897ccd5a2cSjsg 	burst_time = RREG32(MC_ARB_BURST_TIME) & STATE0_MASK;
42907ccd5a2cSjsg 
42917ccd5a2cSjsg 	arb_regs->mc_arb_dram_timing  = cpu_to_be32(dram_timing);
42927ccd5a2cSjsg 	arb_regs->mc_arb_dram_timing2 = cpu_to_be32(dram_timing2);
42937ccd5a2cSjsg 	arb_regs->mc_arb_burst_time = (u8)burst_time;
42947ccd5a2cSjsg 
42957ccd5a2cSjsg 	return 0;
42967ccd5a2cSjsg }
42977ccd5a2cSjsg 
si_do_program_memory_timing_parameters(struct radeon_device * rdev,struct radeon_ps * radeon_state,unsigned int first_arb_set)42987ccd5a2cSjsg static int si_do_program_memory_timing_parameters(struct radeon_device *rdev,
42997ccd5a2cSjsg 						  struct radeon_ps *radeon_state,
43007ccd5a2cSjsg 						  unsigned int first_arb_set)
43017ccd5a2cSjsg {
43027ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
43037ccd5a2cSjsg 	struct ni_ps *state = ni_get_ps(radeon_state);
43047ccd5a2cSjsg 	SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };
43057ccd5a2cSjsg 	int i, ret = 0;
43067ccd5a2cSjsg 
43077ccd5a2cSjsg 	for (i = 0; i < state->performance_level_count; i++) {
43087ccd5a2cSjsg 		ret = si_populate_memory_timing_parameters(rdev, &state->performance_levels[i], &arb_regs);
43097ccd5a2cSjsg 		if (ret)
43107ccd5a2cSjsg 			break;
43117ccd5a2cSjsg 		ret = si_copy_bytes_to_smc(rdev,
43127ccd5a2cSjsg 					   si_pi->arb_table_start +
43137ccd5a2cSjsg 					   offsetof(SMC_SIslands_MCArbDramTimingRegisters, data) +
43147ccd5a2cSjsg 					   sizeof(SMC_SIslands_MCArbDramTimingRegisterSet) * (first_arb_set + i),
43157ccd5a2cSjsg 					   (u8 *)&arb_regs,
43167ccd5a2cSjsg 					   sizeof(SMC_SIslands_MCArbDramTimingRegisterSet),
43177ccd5a2cSjsg 					   si_pi->sram_end);
43187ccd5a2cSjsg 		if (ret)
43197ccd5a2cSjsg 			break;
43207ccd5a2cSjsg 	}
43217ccd5a2cSjsg 
43227ccd5a2cSjsg 	return ret;
43237ccd5a2cSjsg }
43247ccd5a2cSjsg 
si_program_memory_timing_parameters(struct radeon_device * rdev,struct radeon_ps * radeon_new_state)43257ccd5a2cSjsg static int si_program_memory_timing_parameters(struct radeon_device *rdev,
43267ccd5a2cSjsg 					       struct radeon_ps *radeon_new_state)
43277ccd5a2cSjsg {
43287ccd5a2cSjsg 	return si_do_program_memory_timing_parameters(rdev, radeon_new_state,
43297ccd5a2cSjsg 						      SISLANDS_DRIVER_STATE_ARB_INDEX);
43307ccd5a2cSjsg }
43317ccd5a2cSjsg 
si_populate_initial_mvdd_value(struct radeon_device * rdev,struct SISLANDS_SMC_VOLTAGE_VALUE * voltage)43327ccd5a2cSjsg static int si_populate_initial_mvdd_value(struct radeon_device *rdev,
43337ccd5a2cSjsg 					  struct SISLANDS_SMC_VOLTAGE_VALUE *voltage)
43347ccd5a2cSjsg {
43357ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
43367ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
43377ccd5a2cSjsg 
43387ccd5a2cSjsg 	if (pi->mvdd_control)
43397ccd5a2cSjsg 		return si_populate_voltage_value(rdev, &si_pi->mvdd_voltage_table,
43407ccd5a2cSjsg 						 si_pi->mvdd_bootup_value, voltage);
43417ccd5a2cSjsg 
43427ccd5a2cSjsg 	return 0;
43437ccd5a2cSjsg }
43447ccd5a2cSjsg 
si_populate_smc_initial_state(struct radeon_device * rdev,struct radeon_ps * radeon_initial_state,SISLANDS_SMC_STATETABLE * table)43457ccd5a2cSjsg static int si_populate_smc_initial_state(struct radeon_device *rdev,
43467ccd5a2cSjsg 					 struct radeon_ps *radeon_initial_state,
43477ccd5a2cSjsg 					 SISLANDS_SMC_STATETABLE *table)
43487ccd5a2cSjsg {
43497ccd5a2cSjsg 	struct ni_ps *initial_state = ni_get_ps(radeon_initial_state);
43507ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
43517ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
43527ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
43537ccd5a2cSjsg 	u32 reg;
43547ccd5a2cSjsg 	int ret;
43557ccd5a2cSjsg 
43565ca02815Sjsg 	table->initialState.level.mclk.vDLL_CNTL =
43577ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.dll_cntl);
43585ca02815Sjsg 	table->initialState.level.mclk.vMCLK_PWRMGT_CNTL =
43597ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.mclk_pwrmgt_cntl);
43605ca02815Sjsg 	table->initialState.level.mclk.vMPLL_AD_FUNC_CNTL =
43617ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.mpll_ad_func_cntl);
43625ca02815Sjsg 	table->initialState.level.mclk.vMPLL_DQ_FUNC_CNTL =
43637ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.mpll_dq_func_cntl);
43645ca02815Sjsg 	table->initialState.level.mclk.vMPLL_FUNC_CNTL =
43657ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.mpll_func_cntl);
43665ca02815Sjsg 	table->initialState.level.mclk.vMPLL_FUNC_CNTL_1 =
43677ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.mpll_func_cntl_1);
43685ca02815Sjsg 	table->initialState.level.mclk.vMPLL_FUNC_CNTL_2 =
43697ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.mpll_func_cntl_2);
43705ca02815Sjsg 	table->initialState.level.mclk.vMPLL_SS =
43717ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.mpll_ss1);
43725ca02815Sjsg 	table->initialState.level.mclk.vMPLL_SS2 =
43737ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.mpll_ss2);
43747ccd5a2cSjsg 
43755ca02815Sjsg 	table->initialState.level.mclk.mclk_value =
43767ccd5a2cSjsg 		cpu_to_be32(initial_state->performance_levels[0].mclk);
43777ccd5a2cSjsg 
43785ca02815Sjsg 	table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL =
43797ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl);
43805ca02815Sjsg 	table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_2 =
43817ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_2);
43825ca02815Sjsg 	table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_3 =
43837ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_3);
43845ca02815Sjsg 	table->initialState.level.sclk.vCG_SPLL_FUNC_CNTL_4 =
43857ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_func_cntl_4);
43865ca02815Sjsg 	table->initialState.level.sclk.vCG_SPLL_SPREAD_SPECTRUM =
43877ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_spread_spectrum);
43885ca02815Sjsg 	table->initialState.level.sclk.vCG_SPLL_SPREAD_SPECTRUM_2  =
43897ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.cg_spll_spread_spectrum_2);
43907ccd5a2cSjsg 
43915ca02815Sjsg 	table->initialState.level.sclk.sclk_value =
43927ccd5a2cSjsg 		cpu_to_be32(initial_state->performance_levels[0].sclk);
43937ccd5a2cSjsg 
43945ca02815Sjsg 	table->initialState.level.arbRefreshState =
43957ccd5a2cSjsg 		SISLANDS_INITIAL_STATE_ARB_INDEX;
43967ccd5a2cSjsg 
43975ca02815Sjsg 	table->initialState.level.ACIndex = 0;
43987ccd5a2cSjsg 
43997ccd5a2cSjsg 	ret = si_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
44007ccd5a2cSjsg 					initial_state->performance_levels[0].vddc,
44015ca02815Sjsg 					&table->initialState.level.vddc);
44027ccd5a2cSjsg 
44037ccd5a2cSjsg 	if (!ret) {
44047ccd5a2cSjsg 		u16 std_vddc;
44057ccd5a2cSjsg 
44067ccd5a2cSjsg 		ret = si_get_std_voltage_value(rdev,
44075ca02815Sjsg 					       &table->initialState.level.vddc,
44087ccd5a2cSjsg 					       &std_vddc);
44097ccd5a2cSjsg 		if (!ret)
44107ccd5a2cSjsg 			si_populate_std_voltage_value(rdev, std_vddc,
44115ca02815Sjsg 						      table->initialState.level.vddc.index,
44125ca02815Sjsg 						      &table->initialState.level.std_vddc);
44137ccd5a2cSjsg 	}
44147ccd5a2cSjsg 
44157ccd5a2cSjsg 	if (eg_pi->vddci_control)
44167ccd5a2cSjsg 		si_populate_voltage_value(rdev,
44177ccd5a2cSjsg 					  &eg_pi->vddci_voltage_table,
44187ccd5a2cSjsg 					  initial_state->performance_levels[0].vddci,
44195ca02815Sjsg 					  &table->initialState.level.vddci);
44207ccd5a2cSjsg 
44217ccd5a2cSjsg 	if (si_pi->vddc_phase_shed_control)
44227ccd5a2cSjsg 		si_populate_phase_shedding_value(rdev,
44237ccd5a2cSjsg 						 &rdev->pm.dpm.dyn_state.phase_shedding_limits_table,
44247ccd5a2cSjsg 						 initial_state->performance_levels[0].vddc,
44257ccd5a2cSjsg 						 initial_state->performance_levels[0].sclk,
44267ccd5a2cSjsg 						 initial_state->performance_levels[0].mclk,
44275ca02815Sjsg 						 &table->initialState.level.vddc);
44287ccd5a2cSjsg 
44295ca02815Sjsg 	si_populate_initial_mvdd_value(rdev, &table->initialState.level.mvdd);
44307ccd5a2cSjsg 
44317ccd5a2cSjsg 	reg = CG_R(0xffff) | CG_L(0);
44325ca02815Sjsg 	table->initialState.level.aT = cpu_to_be32(reg);
44337ccd5a2cSjsg 
44345ca02815Sjsg 	table->initialState.level.bSP = cpu_to_be32(pi->dsp);
44357ccd5a2cSjsg 
44365ca02815Sjsg 	table->initialState.level.gen2PCIE = (u8)si_pi->boot_pcie_gen;
44377ccd5a2cSjsg 
44387ccd5a2cSjsg 	if (pi->mem_gddr5) {
44395ca02815Sjsg 		table->initialState.level.strobeMode =
44407ccd5a2cSjsg 			si_get_strobe_mode_settings(rdev,
44417ccd5a2cSjsg 						    initial_state->performance_levels[0].mclk);
44427ccd5a2cSjsg 
44437ccd5a2cSjsg 		if (initial_state->performance_levels[0].mclk > pi->mclk_edc_enable_threshold)
44445ca02815Sjsg 			table->initialState.level.mcFlags = SISLANDS_SMC_MC_EDC_RD_FLAG | SISLANDS_SMC_MC_EDC_WR_FLAG;
44457ccd5a2cSjsg 		else
44465ca02815Sjsg 			table->initialState.level.mcFlags =  0;
44477ccd5a2cSjsg 	}
44487ccd5a2cSjsg 
44497ccd5a2cSjsg 	table->initialState.levelCount = 1;
44507ccd5a2cSjsg 
44517ccd5a2cSjsg 	table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
44527ccd5a2cSjsg 
44535ca02815Sjsg 	table->initialState.level.dpm2.MaxPS = 0;
44545ca02815Sjsg 	table->initialState.level.dpm2.NearTDPDec = 0;
44555ca02815Sjsg 	table->initialState.level.dpm2.AboveSafeInc = 0;
44565ca02815Sjsg 	table->initialState.level.dpm2.BelowSafeInc = 0;
44575ca02815Sjsg 	table->initialState.level.dpm2.PwrEfficiencyRatio = 0;
44587ccd5a2cSjsg 
44597ccd5a2cSjsg 	reg = MIN_POWER_MASK | MAX_POWER_MASK;
44605ca02815Sjsg 	table->initialState.level.SQPowerThrottle = cpu_to_be32(reg);
44617ccd5a2cSjsg 
44627ccd5a2cSjsg 	reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
44635ca02815Sjsg 	table->initialState.level.SQPowerThrottle_2 = cpu_to_be32(reg);
44647ccd5a2cSjsg 
44657ccd5a2cSjsg 	return 0;
44667ccd5a2cSjsg }
44677ccd5a2cSjsg 
si_populate_smc_acpi_state(struct radeon_device * rdev,SISLANDS_SMC_STATETABLE * table)44687ccd5a2cSjsg static int si_populate_smc_acpi_state(struct radeon_device *rdev,
44697ccd5a2cSjsg 				      SISLANDS_SMC_STATETABLE *table)
44707ccd5a2cSjsg {
44717ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
44727ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
44737ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
44747ccd5a2cSjsg 	u32 spll_func_cntl = si_pi->clock_registers.cg_spll_func_cntl;
44757ccd5a2cSjsg 	u32 spll_func_cntl_2 = si_pi->clock_registers.cg_spll_func_cntl_2;
44767ccd5a2cSjsg 	u32 spll_func_cntl_3 = si_pi->clock_registers.cg_spll_func_cntl_3;
44777ccd5a2cSjsg 	u32 spll_func_cntl_4 = si_pi->clock_registers.cg_spll_func_cntl_4;
44787ccd5a2cSjsg 	u32 dll_cntl = si_pi->clock_registers.dll_cntl;
44797ccd5a2cSjsg 	u32 mclk_pwrmgt_cntl = si_pi->clock_registers.mclk_pwrmgt_cntl;
44807ccd5a2cSjsg 	u32 mpll_ad_func_cntl = si_pi->clock_registers.mpll_ad_func_cntl;
44817ccd5a2cSjsg 	u32 mpll_dq_func_cntl = si_pi->clock_registers.mpll_dq_func_cntl;
44827ccd5a2cSjsg 	u32 mpll_func_cntl = si_pi->clock_registers.mpll_func_cntl;
44837ccd5a2cSjsg 	u32 mpll_func_cntl_1 = si_pi->clock_registers.mpll_func_cntl_1;
44847ccd5a2cSjsg 	u32 mpll_func_cntl_2 = si_pi->clock_registers.mpll_func_cntl_2;
44857ccd5a2cSjsg 	u32 reg;
44867ccd5a2cSjsg 	int ret;
44877ccd5a2cSjsg 
44887ccd5a2cSjsg 	table->ACPIState = table->initialState;
44897ccd5a2cSjsg 
44907ccd5a2cSjsg 	table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
44917ccd5a2cSjsg 
44927ccd5a2cSjsg 	if (pi->acpi_vddc) {
44937ccd5a2cSjsg 		ret = si_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
44945ca02815Sjsg 						pi->acpi_vddc, &table->ACPIState.level.vddc);
44957ccd5a2cSjsg 		if (!ret) {
44967ccd5a2cSjsg 			u16 std_vddc;
44977ccd5a2cSjsg 
44987ccd5a2cSjsg 			ret = si_get_std_voltage_value(rdev,
44995ca02815Sjsg 						       &table->ACPIState.level.vddc, &std_vddc);
45007ccd5a2cSjsg 			if (!ret)
45017ccd5a2cSjsg 				si_populate_std_voltage_value(rdev, std_vddc,
45025ca02815Sjsg 							      table->ACPIState.level.vddc.index,
45035ca02815Sjsg 							      &table->ACPIState.level.std_vddc);
45047ccd5a2cSjsg 		}
45055ca02815Sjsg 		table->ACPIState.level.gen2PCIE = si_pi->acpi_pcie_gen;
45067ccd5a2cSjsg 
45077ccd5a2cSjsg 		if (si_pi->vddc_phase_shed_control) {
45087ccd5a2cSjsg 			si_populate_phase_shedding_value(rdev,
45097ccd5a2cSjsg 							 &rdev->pm.dpm.dyn_state.phase_shedding_limits_table,
45107ccd5a2cSjsg 							 pi->acpi_vddc,
45117ccd5a2cSjsg 							 0,
45127ccd5a2cSjsg 							 0,
45135ca02815Sjsg 							 &table->ACPIState.level.vddc);
45147ccd5a2cSjsg 		}
45157ccd5a2cSjsg 	} else {
45167ccd5a2cSjsg 		ret = si_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
45175ca02815Sjsg 						pi->min_vddc_in_table, &table->ACPIState.level.vddc);
45187ccd5a2cSjsg 		if (!ret) {
45197ccd5a2cSjsg 			u16 std_vddc;
45207ccd5a2cSjsg 
45217ccd5a2cSjsg 			ret = si_get_std_voltage_value(rdev,
45225ca02815Sjsg 						       &table->ACPIState.level.vddc, &std_vddc);
45237ccd5a2cSjsg 
45247ccd5a2cSjsg 			if (!ret)
45257ccd5a2cSjsg 				si_populate_std_voltage_value(rdev, std_vddc,
45265ca02815Sjsg 							      table->ACPIState.level.vddc.index,
45275ca02815Sjsg 							      &table->ACPIState.level.std_vddc);
45287ccd5a2cSjsg 		}
45295ca02815Sjsg 		table->ACPIState.level.gen2PCIE = (u8)r600_get_pcie_gen_support(rdev,
45307ccd5a2cSjsg 										    si_pi->sys_pcie_mask,
45317ccd5a2cSjsg 										    si_pi->boot_pcie_gen,
45327ccd5a2cSjsg 										    RADEON_PCIE_GEN1);
45337ccd5a2cSjsg 
45347ccd5a2cSjsg 		if (si_pi->vddc_phase_shed_control)
45357ccd5a2cSjsg 			si_populate_phase_shedding_value(rdev,
45367ccd5a2cSjsg 							 &rdev->pm.dpm.dyn_state.phase_shedding_limits_table,
45377ccd5a2cSjsg 							 pi->min_vddc_in_table,
45387ccd5a2cSjsg 							 0,
45397ccd5a2cSjsg 							 0,
45405ca02815Sjsg 							 &table->ACPIState.level.vddc);
45417ccd5a2cSjsg 	}
45427ccd5a2cSjsg 
45437ccd5a2cSjsg 	if (pi->acpi_vddc) {
45447ccd5a2cSjsg 		if (eg_pi->acpi_vddci)
45457ccd5a2cSjsg 			si_populate_voltage_value(rdev, &eg_pi->vddci_voltage_table,
45467ccd5a2cSjsg 						  eg_pi->acpi_vddci,
45475ca02815Sjsg 						  &table->ACPIState.level.vddci);
45487ccd5a2cSjsg 	}
45497ccd5a2cSjsg 
45507ccd5a2cSjsg 	mclk_pwrmgt_cntl |= MRDCK0_RESET | MRDCK1_RESET;
45517ccd5a2cSjsg 	mclk_pwrmgt_cntl &= ~(MRDCK0_PDNB | MRDCK1_PDNB);
45527ccd5a2cSjsg 
45537ccd5a2cSjsg 	dll_cntl &= ~(MRDCK0_BYPASS | MRDCK1_BYPASS);
45547ccd5a2cSjsg 
45557ccd5a2cSjsg 	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
45567ccd5a2cSjsg 	spll_func_cntl_2 |= SCLK_MUX_SEL(4);
45577ccd5a2cSjsg 
45585ca02815Sjsg 	table->ACPIState.level.mclk.vDLL_CNTL =
45597ccd5a2cSjsg 		cpu_to_be32(dll_cntl);
45605ca02815Sjsg 	table->ACPIState.level.mclk.vMCLK_PWRMGT_CNTL =
45617ccd5a2cSjsg 		cpu_to_be32(mclk_pwrmgt_cntl);
45625ca02815Sjsg 	table->ACPIState.level.mclk.vMPLL_AD_FUNC_CNTL =
45637ccd5a2cSjsg 		cpu_to_be32(mpll_ad_func_cntl);
45645ca02815Sjsg 	table->ACPIState.level.mclk.vMPLL_DQ_FUNC_CNTL =
45657ccd5a2cSjsg 		cpu_to_be32(mpll_dq_func_cntl);
45665ca02815Sjsg 	table->ACPIState.level.mclk.vMPLL_FUNC_CNTL =
45677ccd5a2cSjsg 		cpu_to_be32(mpll_func_cntl);
45685ca02815Sjsg 	table->ACPIState.level.mclk.vMPLL_FUNC_CNTL_1 =
45697ccd5a2cSjsg 		cpu_to_be32(mpll_func_cntl_1);
45705ca02815Sjsg 	table->ACPIState.level.mclk.vMPLL_FUNC_CNTL_2 =
45717ccd5a2cSjsg 		cpu_to_be32(mpll_func_cntl_2);
45725ca02815Sjsg 	table->ACPIState.level.mclk.vMPLL_SS =
45737ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.mpll_ss1);
45745ca02815Sjsg 	table->ACPIState.level.mclk.vMPLL_SS2 =
45757ccd5a2cSjsg 		cpu_to_be32(si_pi->clock_registers.mpll_ss2);
45767ccd5a2cSjsg 
45775ca02815Sjsg 	table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL =
45787ccd5a2cSjsg 		cpu_to_be32(spll_func_cntl);
45795ca02815Sjsg 	table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_2 =
45807ccd5a2cSjsg 		cpu_to_be32(spll_func_cntl_2);
45815ca02815Sjsg 	table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_3 =
45827ccd5a2cSjsg 		cpu_to_be32(spll_func_cntl_3);
45835ca02815Sjsg 	table->ACPIState.level.sclk.vCG_SPLL_FUNC_CNTL_4 =
45847ccd5a2cSjsg 		cpu_to_be32(spll_func_cntl_4);
45857ccd5a2cSjsg 
45865ca02815Sjsg 	table->ACPIState.level.mclk.mclk_value = 0;
45875ca02815Sjsg 	table->ACPIState.level.sclk.sclk_value = 0;
45887ccd5a2cSjsg 
45895ca02815Sjsg 	si_populate_mvdd_value(rdev, 0, &table->ACPIState.level.mvdd);
45907ccd5a2cSjsg 
45917ccd5a2cSjsg 	if (eg_pi->dynamic_ac_timing)
45925ca02815Sjsg 		table->ACPIState.level.ACIndex = 0;
45937ccd5a2cSjsg 
45945ca02815Sjsg 	table->ACPIState.level.dpm2.MaxPS = 0;
45955ca02815Sjsg 	table->ACPIState.level.dpm2.NearTDPDec = 0;
45965ca02815Sjsg 	table->ACPIState.level.dpm2.AboveSafeInc = 0;
45975ca02815Sjsg 	table->ACPIState.level.dpm2.BelowSafeInc = 0;
45985ca02815Sjsg 	table->ACPIState.level.dpm2.PwrEfficiencyRatio = 0;
45997ccd5a2cSjsg 
46007ccd5a2cSjsg 	reg = MIN_POWER_MASK | MAX_POWER_MASK;
46015ca02815Sjsg 	table->ACPIState.level.SQPowerThrottle = cpu_to_be32(reg);
46027ccd5a2cSjsg 
46037ccd5a2cSjsg 	reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
46045ca02815Sjsg 	table->ACPIState.level.SQPowerThrottle_2 = cpu_to_be32(reg);
46057ccd5a2cSjsg 
46067ccd5a2cSjsg 	return 0;
46077ccd5a2cSjsg }
46087ccd5a2cSjsg 
si_populate_ulv_state(struct radeon_device * rdev,struct SISLANDS_SMC_SWSTATE_SINGLE * state)46097ccd5a2cSjsg static int si_populate_ulv_state(struct radeon_device *rdev,
46105ca02815Sjsg 				 struct SISLANDS_SMC_SWSTATE_SINGLE *state)
46117ccd5a2cSjsg {
46127ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
46137ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
46147ccd5a2cSjsg 	struct si_ulv_param *ulv = &si_pi->ulv;
46157ccd5a2cSjsg 	u32 sclk_in_sr = 1350; /* ??? */
46167ccd5a2cSjsg 	int ret;
46177ccd5a2cSjsg 
46187ccd5a2cSjsg 	ret = si_convert_power_level_to_smc(rdev, &ulv->pl,
46195ca02815Sjsg 					    &state->level);
46207ccd5a2cSjsg 	if (!ret) {
46217ccd5a2cSjsg 		if (eg_pi->sclk_deep_sleep) {
46227ccd5a2cSjsg 			if (sclk_in_sr <= SCLK_MIN_DEEPSLEEP_FREQ)
46235ca02815Sjsg 				state->level.stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_BYPASS;
46247ccd5a2cSjsg 			else
46255ca02815Sjsg 				state->level.stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE;
46267ccd5a2cSjsg 		}
46277ccd5a2cSjsg 		if (ulv->one_pcie_lane_in_ulv)
46287ccd5a2cSjsg 			state->flags |= PPSMC_SWSTATE_FLAG_PCIE_X1;
46295ca02815Sjsg 		state->level.arbRefreshState = (u8)(SISLANDS_ULV_STATE_ARB_INDEX);
46305ca02815Sjsg 		state->level.ACIndex = 1;
46315ca02815Sjsg 		state->level.std_vddc = state->level.vddc;
46327ccd5a2cSjsg 		state->levelCount = 1;
46337ccd5a2cSjsg 
46347ccd5a2cSjsg 		state->flags |= PPSMC_SWSTATE_FLAG_DC;
46357ccd5a2cSjsg 	}
46367ccd5a2cSjsg 
46377ccd5a2cSjsg 	return ret;
46387ccd5a2cSjsg }
46397ccd5a2cSjsg 
si_program_ulv_memory_timing_parameters(struct radeon_device * rdev)46407ccd5a2cSjsg static int si_program_ulv_memory_timing_parameters(struct radeon_device *rdev)
46417ccd5a2cSjsg {
46427ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
46437ccd5a2cSjsg 	struct si_ulv_param *ulv = &si_pi->ulv;
46447ccd5a2cSjsg 	SMC_SIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };
46457ccd5a2cSjsg 	int ret;
46467ccd5a2cSjsg 
46477ccd5a2cSjsg 	ret = si_populate_memory_timing_parameters(rdev, &ulv->pl,
46487ccd5a2cSjsg 						   &arb_regs);
46497ccd5a2cSjsg 	if (ret)
46507ccd5a2cSjsg 		return ret;
46517ccd5a2cSjsg 
46527ccd5a2cSjsg 	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_ulv_volt_change_delay,
46537ccd5a2cSjsg 				   ulv->volt_change_delay);
46547ccd5a2cSjsg 
46557ccd5a2cSjsg 	ret = si_copy_bytes_to_smc(rdev,
46567ccd5a2cSjsg 				   si_pi->arb_table_start +
46577ccd5a2cSjsg 				   offsetof(SMC_SIslands_MCArbDramTimingRegisters, data) +
46587ccd5a2cSjsg 				   sizeof(SMC_SIslands_MCArbDramTimingRegisterSet) * SISLANDS_ULV_STATE_ARB_INDEX,
46597ccd5a2cSjsg 				   (u8 *)&arb_regs,
46607ccd5a2cSjsg 				   sizeof(SMC_SIslands_MCArbDramTimingRegisterSet),
46617ccd5a2cSjsg 				   si_pi->sram_end);
46627ccd5a2cSjsg 
46637ccd5a2cSjsg 	return ret;
46647ccd5a2cSjsg }
46657ccd5a2cSjsg 
si_get_mvdd_configuration(struct radeon_device * rdev)46667ccd5a2cSjsg static void si_get_mvdd_configuration(struct radeon_device *rdev)
46677ccd5a2cSjsg {
46687ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
46697ccd5a2cSjsg 
46707ccd5a2cSjsg 	pi->mvdd_split_frequency = 30000;
46717ccd5a2cSjsg }
46727ccd5a2cSjsg 
si_init_smc_table(struct radeon_device * rdev)46737ccd5a2cSjsg static int si_init_smc_table(struct radeon_device *rdev)
46747ccd5a2cSjsg {
46757ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
46767ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
46777ccd5a2cSjsg 	struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps;
46787ccd5a2cSjsg 	const struct si_ulv_param *ulv = &si_pi->ulv;
46797ccd5a2cSjsg 	SISLANDS_SMC_STATETABLE  *table = &si_pi->smc_statetable;
46807ccd5a2cSjsg 	int ret;
46817ccd5a2cSjsg 	u32 lane_width;
46827ccd5a2cSjsg 	u32 vr_hot_gpio;
46837ccd5a2cSjsg 
46847ccd5a2cSjsg 	si_populate_smc_voltage_tables(rdev, table);
46857ccd5a2cSjsg 
46867ccd5a2cSjsg 	switch (rdev->pm.int_thermal_type) {
46877ccd5a2cSjsg 	case THERMAL_TYPE_SI:
46887ccd5a2cSjsg 	case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
46897ccd5a2cSjsg 		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
46907ccd5a2cSjsg 		break;
46917ccd5a2cSjsg 	case THERMAL_TYPE_NONE:
46927ccd5a2cSjsg 		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
46937ccd5a2cSjsg 		break;
46947ccd5a2cSjsg 	default:
46957ccd5a2cSjsg 		table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
46967ccd5a2cSjsg 		break;
46977ccd5a2cSjsg 	}
46987ccd5a2cSjsg 
46997ccd5a2cSjsg 	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
47007ccd5a2cSjsg 		table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
47017ccd5a2cSjsg 
47027ccd5a2cSjsg 	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT) {
47037ccd5a2cSjsg 		if ((rdev->pdev->device != 0x6818) && (rdev->pdev->device != 0x6819))
47047ccd5a2cSjsg 			table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
47057ccd5a2cSjsg 	}
47067ccd5a2cSjsg 
47077ccd5a2cSjsg 	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
47087ccd5a2cSjsg 		table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
47097ccd5a2cSjsg 
47107ccd5a2cSjsg 	if (pi->mem_gddr5)
47117ccd5a2cSjsg 		table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
47127ccd5a2cSjsg 
47137ccd5a2cSjsg 	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY)
47147ccd5a2cSjsg 		table->extraFlags |= PPSMC_EXTRAFLAGS_AC2DC_GPIO5_POLARITY_HIGH;
47157ccd5a2cSjsg 
47167ccd5a2cSjsg 	if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE) {
47177ccd5a2cSjsg 		table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT_PROG_GPIO;
47187ccd5a2cSjsg 		vr_hot_gpio = rdev->pm.dpm.backbias_response_time;
47197ccd5a2cSjsg 		si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_vr_hot_gpio,
47207ccd5a2cSjsg 					   vr_hot_gpio);
47217ccd5a2cSjsg 	}
47227ccd5a2cSjsg 
47237ccd5a2cSjsg 	ret = si_populate_smc_initial_state(rdev, radeon_boot_state, table);
47247ccd5a2cSjsg 	if (ret)
47257ccd5a2cSjsg 		return ret;
47267ccd5a2cSjsg 
47277ccd5a2cSjsg 	ret = si_populate_smc_acpi_state(rdev, table);
47287ccd5a2cSjsg 	if (ret)
47297ccd5a2cSjsg 		return ret;
47307ccd5a2cSjsg 
47315ca02815Sjsg 	table->driverState.flags = table->initialState.flags;
47325ca02815Sjsg 	table->driverState.levelCount = table->initialState.levelCount;
47335ca02815Sjsg 	table->driverState.levels[0] = table->initialState.level;
47347ccd5a2cSjsg 
47357ccd5a2cSjsg 	ret = si_do_program_memory_timing_parameters(rdev, radeon_boot_state,
47367ccd5a2cSjsg 						     SISLANDS_INITIAL_STATE_ARB_INDEX);
47377ccd5a2cSjsg 	if (ret)
47387ccd5a2cSjsg 		return ret;
47397ccd5a2cSjsg 
47407ccd5a2cSjsg 	if (ulv->supported && ulv->pl.vddc) {
47417ccd5a2cSjsg 		ret = si_populate_ulv_state(rdev, &table->ULVState);
47427ccd5a2cSjsg 		if (ret)
47437ccd5a2cSjsg 			return ret;
47447ccd5a2cSjsg 
47457ccd5a2cSjsg 		ret = si_program_ulv_memory_timing_parameters(rdev);
47467ccd5a2cSjsg 		if (ret)
47477ccd5a2cSjsg 			return ret;
47487ccd5a2cSjsg 
47497ccd5a2cSjsg 		WREG32(CG_ULV_CONTROL, ulv->cg_ulv_control);
47507ccd5a2cSjsg 		WREG32(CG_ULV_PARAMETER, ulv->cg_ulv_parameter);
47517ccd5a2cSjsg 
47527ccd5a2cSjsg 		lane_width = radeon_get_pcie_lanes(rdev);
47537ccd5a2cSjsg 		si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width, lane_width);
47547ccd5a2cSjsg 	} else {
47557ccd5a2cSjsg 		table->ULVState = table->initialState;
47567ccd5a2cSjsg 	}
47577ccd5a2cSjsg 
47587ccd5a2cSjsg 	return si_copy_bytes_to_smc(rdev, si_pi->state_table_start,
47597ccd5a2cSjsg 				    (u8 *)table, sizeof(SISLANDS_SMC_STATETABLE),
47607ccd5a2cSjsg 				    si_pi->sram_end);
47617ccd5a2cSjsg }
47627ccd5a2cSjsg 
si_calculate_sclk_params(struct radeon_device * rdev,u32 engine_clock,SISLANDS_SMC_SCLK_VALUE * sclk)47637ccd5a2cSjsg static int si_calculate_sclk_params(struct radeon_device *rdev,
47647ccd5a2cSjsg 				    u32 engine_clock,
47657ccd5a2cSjsg 				    SISLANDS_SMC_SCLK_VALUE *sclk)
47667ccd5a2cSjsg {
47677ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
47687ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
47697ccd5a2cSjsg 	struct atom_clock_dividers dividers;
47707ccd5a2cSjsg 	u32 spll_func_cntl = si_pi->clock_registers.cg_spll_func_cntl;
47717ccd5a2cSjsg 	u32 spll_func_cntl_2 = si_pi->clock_registers.cg_spll_func_cntl_2;
47727ccd5a2cSjsg 	u32 spll_func_cntl_3 = si_pi->clock_registers.cg_spll_func_cntl_3;
47737ccd5a2cSjsg 	u32 spll_func_cntl_4 = si_pi->clock_registers.cg_spll_func_cntl_4;
47747ccd5a2cSjsg 	u32 cg_spll_spread_spectrum = si_pi->clock_registers.cg_spll_spread_spectrum;
47757ccd5a2cSjsg 	u32 cg_spll_spread_spectrum_2 = si_pi->clock_registers.cg_spll_spread_spectrum_2;
47767ccd5a2cSjsg 	u64 tmp;
47777ccd5a2cSjsg 	u32 reference_clock = rdev->clock.spll.reference_freq;
47787ccd5a2cSjsg 	u32 reference_divider;
47797ccd5a2cSjsg 	u32 fbdiv;
47807ccd5a2cSjsg 	int ret;
47817ccd5a2cSjsg 
47827ccd5a2cSjsg 	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
47837ccd5a2cSjsg 					     engine_clock, false, &dividers);
47847ccd5a2cSjsg 	if (ret)
47857ccd5a2cSjsg 		return ret;
47867ccd5a2cSjsg 
47877ccd5a2cSjsg 	reference_divider = 1 + dividers.ref_div;
47887ccd5a2cSjsg 
47897ccd5a2cSjsg 	tmp = (u64) engine_clock * reference_divider * dividers.post_div * 16384;
47907ccd5a2cSjsg 	do_div(tmp, reference_clock);
47917ccd5a2cSjsg 	fbdiv = (u32) tmp;
47927ccd5a2cSjsg 
47937ccd5a2cSjsg 	spll_func_cntl &= ~(SPLL_PDIV_A_MASK | SPLL_REF_DIV_MASK);
47947ccd5a2cSjsg 	spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
47957ccd5a2cSjsg 	spll_func_cntl |= SPLL_PDIV_A(dividers.post_div);
47967ccd5a2cSjsg 
47977ccd5a2cSjsg 	spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
47987ccd5a2cSjsg 	spll_func_cntl_2 |= SCLK_MUX_SEL(2);
47997ccd5a2cSjsg 
48007ccd5a2cSjsg 	spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
48017ccd5a2cSjsg 	spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
48027ccd5a2cSjsg 	spll_func_cntl_3 |= SPLL_DITHEN;
48037ccd5a2cSjsg 
48047ccd5a2cSjsg 	if (pi->sclk_ss) {
48057ccd5a2cSjsg 		struct radeon_atom_ss ss;
48067ccd5a2cSjsg 		u32 vco_freq = engine_clock * dividers.post_div;
48077ccd5a2cSjsg 
48087ccd5a2cSjsg 		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
48097ccd5a2cSjsg 						     ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
48107ccd5a2cSjsg 			u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
48117ccd5a2cSjsg 			u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000);
48127ccd5a2cSjsg 
48137ccd5a2cSjsg 			cg_spll_spread_spectrum &= ~CLK_S_MASK;
48147ccd5a2cSjsg 			cg_spll_spread_spectrum |= CLK_S(clk_s);
48157ccd5a2cSjsg 			cg_spll_spread_spectrum |= SSEN;
48167ccd5a2cSjsg 
48177ccd5a2cSjsg 			cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
48187ccd5a2cSjsg 			cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
48197ccd5a2cSjsg 		}
48207ccd5a2cSjsg 	}
48217ccd5a2cSjsg 
48227ccd5a2cSjsg 	sclk->sclk_value = engine_clock;
48237ccd5a2cSjsg 	sclk->vCG_SPLL_FUNC_CNTL = spll_func_cntl;
48247ccd5a2cSjsg 	sclk->vCG_SPLL_FUNC_CNTL_2 = spll_func_cntl_2;
48257ccd5a2cSjsg 	sclk->vCG_SPLL_FUNC_CNTL_3 = spll_func_cntl_3;
48267ccd5a2cSjsg 	sclk->vCG_SPLL_FUNC_CNTL_4 = spll_func_cntl_4;
48277ccd5a2cSjsg 	sclk->vCG_SPLL_SPREAD_SPECTRUM = cg_spll_spread_spectrum;
48287ccd5a2cSjsg 	sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cg_spll_spread_spectrum_2;
48297ccd5a2cSjsg 
48307ccd5a2cSjsg 	return 0;
48317ccd5a2cSjsg }
48327ccd5a2cSjsg 
si_populate_sclk_value(struct radeon_device * rdev,u32 engine_clock,SISLANDS_SMC_SCLK_VALUE * sclk)48337ccd5a2cSjsg static int si_populate_sclk_value(struct radeon_device *rdev,
48347ccd5a2cSjsg 				  u32 engine_clock,
48357ccd5a2cSjsg 				  SISLANDS_SMC_SCLK_VALUE *sclk)
48367ccd5a2cSjsg {
48377ccd5a2cSjsg 	SISLANDS_SMC_SCLK_VALUE sclk_tmp;
48387ccd5a2cSjsg 	int ret;
48397ccd5a2cSjsg 
48407ccd5a2cSjsg 	ret = si_calculate_sclk_params(rdev, engine_clock, &sclk_tmp);
48417ccd5a2cSjsg 	if (!ret) {
48427ccd5a2cSjsg 		sclk->sclk_value = cpu_to_be32(sclk_tmp.sclk_value);
48437ccd5a2cSjsg 		sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL);
48447ccd5a2cSjsg 		sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_2);
48457ccd5a2cSjsg 		sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_3);
48467ccd5a2cSjsg 		sclk->vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_4);
48477ccd5a2cSjsg 		sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM);
48487ccd5a2cSjsg 		sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM_2);
48497ccd5a2cSjsg 	}
48507ccd5a2cSjsg 
48517ccd5a2cSjsg 	return ret;
48527ccd5a2cSjsg }
48537ccd5a2cSjsg 
si_populate_mclk_value(struct radeon_device * rdev,u32 engine_clock,u32 memory_clock,SISLANDS_SMC_MCLK_VALUE * mclk,bool strobe_mode,bool dll_state_on)48547ccd5a2cSjsg static int si_populate_mclk_value(struct radeon_device *rdev,
48557ccd5a2cSjsg 				  u32 engine_clock,
48567ccd5a2cSjsg 				  u32 memory_clock,
48577ccd5a2cSjsg 				  SISLANDS_SMC_MCLK_VALUE *mclk,
48587ccd5a2cSjsg 				  bool strobe_mode,
48597ccd5a2cSjsg 				  bool dll_state_on)
48607ccd5a2cSjsg {
48617ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
48627ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
48637ccd5a2cSjsg 	u32  dll_cntl = si_pi->clock_registers.dll_cntl;
48647ccd5a2cSjsg 	u32  mclk_pwrmgt_cntl = si_pi->clock_registers.mclk_pwrmgt_cntl;
48657ccd5a2cSjsg 	u32  mpll_ad_func_cntl = si_pi->clock_registers.mpll_ad_func_cntl;
48667ccd5a2cSjsg 	u32  mpll_dq_func_cntl = si_pi->clock_registers.mpll_dq_func_cntl;
48677ccd5a2cSjsg 	u32  mpll_func_cntl = si_pi->clock_registers.mpll_func_cntl;
48687ccd5a2cSjsg 	u32  mpll_func_cntl_1 = si_pi->clock_registers.mpll_func_cntl_1;
48697ccd5a2cSjsg 	u32  mpll_func_cntl_2 = si_pi->clock_registers.mpll_func_cntl_2;
48707ccd5a2cSjsg 	u32  mpll_ss1 = si_pi->clock_registers.mpll_ss1;
48717ccd5a2cSjsg 	u32  mpll_ss2 = si_pi->clock_registers.mpll_ss2;
48727ccd5a2cSjsg 	struct atom_mpll_param mpll_param;
48737ccd5a2cSjsg 	int ret;
48747ccd5a2cSjsg 
48757ccd5a2cSjsg 	ret = radeon_atom_get_memory_pll_dividers(rdev, memory_clock, strobe_mode, &mpll_param);
48767ccd5a2cSjsg 	if (ret)
48777ccd5a2cSjsg 		return ret;
48787ccd5a2cSjsg 
48797ccd5a2cSjsg 	mpll_func_cntl &= ~BWCTRL_MASK;
48807ccd5a2cSjsg 	mpll_func_cntl |= BWCTRL(mpll_param.bwcntl);
48817ccd5a2cSjsg 
48827ccd5a2cSjsg 	mpll_func_cntl_1 &= ~(CLKF_MASK | CLKFRAC_MASK | VCO_MODE_MASK);
48837ccd5a2cSjsg 	mpll_func_cntl_1 |= CLKF(mpll_param.clkf) |
48847ccd5a2cSjsg 		CLKFRAC(mpll_param.clkfrac) | VCO_MODE(mpll_param.vco_mode);
48857ccd5a2cSjsg 
48867ccd5a2cSjsg 	mpll_ad_func_cntl &= ~YCLK_POST_DIV_MASK;
48877ccd5a2cSjsg 	mpll_ad_func_cntl |= YCLK_POST_DIV(mpll_param.post_div);
48887ccd5a2cSjsg 
48897ccd5a2cSjsg 	if (pi->mem_gddr5) {
48907ccd5a2cSjsg 		mpll_dq_func_cntl &= ~(YCLK_SEL_MASK | YCLK_POST_DIV_MASK);
48917ccd5a2cSjsg 		mpll_dq_func_cntl |= YCLK_SEL(mpll_param.yclk_sel) |
48927ccd5a2cSjsg 			YCLK_POST_DIV(mpll_param.post_div);
48937ccd5a2cSjsg 	}
48947ccd5a2cSjsg 
48957ccd5a2cSjsg 	if (pi->mclk_ss) {
48967ccd5a2cSjsg 		struct radeon_atom_ss ss;
48977ccd5a2cSjsg 		u32 freq_nom;
48987ccd5a2cSjsg 		u32 tmp;
48997ccd5a2cSjsg 		u32 reference_clock = rdev->clock.mpll.reference_freq;
49007ccd5a2cSjsg 
49017ccd5a2cSjsg 		if (pi->mem_gddr5)
49027ccd5a2cSjsg 			freq_nom = memory_clock * 4;
49037ccd5a2cSjsg 		else
49047ccd5a2cSjsg 			freq_nom = memory_clock * 2;
49057ccd5a2cSjsg 
49067ccd5a2cSjsg 		tmp = freq_nom / reference_clock;
49077ccd5a2cSjsg 		tmp = tmp * tmp;
49087ccd5a2cSjsg 		if (radeon_atombios_get_asic_ss_info(rdev, &ss,
49097ccd5a2cSjsg 						     ASIC_INTERNAL_MEMORY_SS, freq_nom)) {
49107ccd5a2cSjsg 			u32 clks = reference_clock * 5 / ss.rate;
49117ccd5a2cSjsg 			u32 clkv = (u32)((((131 * ss.percentage * ss.rate) / 100) * tmp) / freq_nom);
49127ccd5a2cSjsg 
49137ccd5a2cSjsg 			mpll_ss1 &= ~CLKV_MASK;
49147ccd5a2cSjsg 			mpll_ss1 |= CLKV(clkv);
49157ccd5a2cSjsg 
49167ccd5a2cSjsg 			mpll_ss2 &= ~CLKS_MASK;
49177ccd5a2cSjsg 			mpll_ss2 |= CLKS(clks);
49187ccd5a2cSjsg 		}
49197ccd5a2cSjsg 	}
49207ccd5a2cSjsg 
49217ccd5a2cSjsg 	mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;
49227ccd5a2cSjsg 	mclk_pwrmgt_cntl |= DLL_SPEED(mpll_param.dll_speed);
49237ccd5a2cSjsg 
49247ccd5a2cSjsg 	if (dll_state_on)
49257ccd5a2cSjsg 		mclk_pwrmgt_cntl |= MRDCK0_PDNB | MRDCK1_PDNB;
49267ccd5a2cSjsg 	else
49277ccd5a2cSjsg 		mclk_pwrmgt_cntl &= ~(MRDCK0_PDNB | MRDCK1_PDNB);
49287ccd5a2cSjsg 
49297ccd5a2cSjsg 	mclk->mclk_value = cpu_to_be32(memory_clock);
49307ccd5a2cSjsg 	mclk->vMPLL_FUNC_CNTL = cpu_to_be32(mpll_func_cntl);
49317ccd5a2cSjsg 	mclk->vMPLL_FUNC_CNTL_1 = cpu_to_be32(mpll_func_cntl_1);
49327ccd5a2cSjsg 	mclk->vMPLL_FUNC_CNTL_2 = cpu_to_be32(mpll_func_cntl_2);
49337ccd5a2cSjsg 	mclk->vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
49347ccd5a2cSjsg 	mclk->vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
49357ccd5a2cSjsg 	mclk->vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
49367ccd5a2cSjsg 	mclk->vDLL_CNTL = cpu_to_be32(dll_cntl);
49377ccd5a2cSjsg 	mclk->vMPLL_SS = cpu_to_be32(mpll_ss1);
49387ccd5a2cSjsg 	mclk->vMPLL_SS2 = cpu_to_be32(mpll_ss2);
49397ccd5a2cSjsg 
49407ccd5a2cSjsg 	return 0;
49417ccd5a2cSjsg }
49427ccd5a2cSjsg 
si_populate_smc_sp(struct radeon_device * rdev,struct radeon_ps * radeon_state,SISLANDS_SMC_SWSTATE * smc_state)49437ccd5a2cSjsg static void si_populate_smc_sp(struct radeon_device *rdev,
49447ccd5a2cSjsg 			       struct radeon_ps *radeon_state,
49457ccd5a2cSjsg 			       SISLANDS_SMC_SWSTATE *smc_state)
49467ccd5a2cSjsg {
49477ccd5a2cSjsg 	struct ni_ps *ps = ni_get_ps(radeon_state);
49487ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
49497ccd5a2cSjsg 	int i;
49507ccd5a2cSjsg 
49517ccd5a2cSjsg 	for (i = 0; i < ps->performance_level_count - 1; i++)
49527ccd5a2cSjsg 		smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);
49537ccd5a2cSjsg 
49547ccd5a2cSjsg 	smc_state->levels[ps->performance_level_count - 1].bSP =
49557ccd5a2cSjsg 		cpu_to_be32(pi->psp);
49567ccd5a2cSjsg }
49577ccd5a2cSjsg 
si_convert_power_level_to_smc(struct radeon_device * rdev,struct rv7xx_pl * pl,SISLANDS_SMC_HW_PERFORMANCE_LEVEL * level)49587ccd5a2cSjsg static int si_convert_power_level_to_smc(struct radeon_device *rdev,
49597ccd5a2cSjsg 					 struct rv7xx_pl *pl,
49607ccd5a2cSjsg 					 SISLANDS_SMC_HW_PERFORMANCE_LEVEL *level)
49617ccd5a2cSjsg {
49627ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
49637ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
49647ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
49657ccd5a2cSjsg 	int ret;
49667ccd5a2cSjsg 	bool dll_state_on;
49677ccd5a2cSjsg 	u16 std_vddc;
49687ccd5a2cSjsg 	bool gmc_pg = false;
49697ccd5a2cSjsg 
49707ccd5a2cSjsg 	if (eg_pi->pcie_performance_request &&
49717ccd5a2cSjsg 	    (si_pi->force_pcie_gen != RADEON_PCIE_GEN_INVALID))
49727ccd5a2cSjsg 		level->gen2PCIE = (u8)si_pi->force_pcie_gen;
49737ccd5a2cSjsg 	else
49747ccd5a2cSjsg 		level->gen2PCIE = (u8)pl->pcie_gen;
49757ccd5a2cSjsg 
49767ccd5a2cSjsg 	ret = si_populate_sclk_value(rdev, pl->sclk, &level->sclk);
49777ccd5a2cSjsg 	if (ret)
49787ccd5a2cSjsg 		return ret;
49797ccd5a2cSjsg 
49807ccd5a2cSjsg 	level->mcFlags =  0;
49817ccd5a2cSjsg 
49827ccd5a2cSjsg 	if (pi->mclk_stutter_mode_threshold &&
49837ccd5a2cSjsg 	    (pl->mclk <= pi->mclk_stutter_mode_threshold) &&
49847ccd5a2cSjsg 	    !eg_pi->uvd_enabled &&
49857ccd5a2cSjsg 	    (RREG32(DPG_PIPE_STUTTER_CONTROL) & STUTTER_ENABLE) &&
49867ccd5a2cSjsg 	    (rdev->pm.dpm.new_active_crtc_count <= 2)) {
49877ccd5a2cSjsg 		level->mcFlags |= SISLANDS_SMC_MC_STUTTER_EN;
49887ccd5a2cSjsg 
49897ccd5a2cSjsg 		if (gmc_pg)
49907ccd5a2cSjsg 			level->mcFlags |= SISLANDS_SMC_MC_PG_EN;
49917ccd5a2cSjsg 	}
49927ccd5a2cSjsg 
49937ccd5a2cSjsg 	if (pi->mem_gddr5) {
49947ccd5a2cSjsg 		if (pl->mclk > pi->mclk_edc_enable_threshold)
49957ccd5a2cSjsg 			level->mcFlags |= SISLANDS_SMC_MC_EDC_RD_FLAG;
49967ccd5a2cSjsg 
49977ccd5a2cSjsg 		if (pl->mclk > eg_pi->mclk_edc_wr_enable_threshold)
49987ccd5a2cSjsg 			level->mcFlags |= SISLANDS_SMC_MC_EDC_WR_FLAG;
49997ccd5a2cSjsg 
50007ccd5a2cSjsg 		level->strobeMode = si_get_strobe_mode_settings(rdev, pl->mclk);
50017ccd5a2cSjsg 
50027ccd5a2cSjsg 		if (level->strobeMode & SISLANDS_SMC_STROBE_ENABLE) {
50037ccd5a2cSjsg 			if (si_get_mclk_frequency_ratio(pl->mclk, true) >=
50047ccd5a2cSjsg 			    ((RREG32(MC_SEQ_MISC7) >> 16) & 0xf))
50057ccd5a2cSjsg 				dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;
50067ccd5a2cSjsg 			else
50077ccd5a2cSjsg 				dll_state_on = ((RREG32(MC_SEQ_MISC6) >> 1) & 0x1) ? true : false;
50087ccd5a2cSjsg 		} else {
50097ccd5a2cSjsg 			dll_state_on = false;
50107ccd5a2cSjsg 		}
50117ccd5a2cSjsg 	} else {
50127ccd5a2cSjsg 		level->strobeMode = si_get_strobe_mode_settings(rdev,
50137ccd5a2cSjsg 								pl->mclk);
50147ccd5a2cSjsg 
50157ccd5a2cSjsg 		dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;
50167ccd5a2cSjsg 	}
50177ccd5a2cSjsg 
50187ccd5a2cSjsg 	ret = si_populate_mclk_value(rdev,
50197ccd5a2cSjsg 				     pl->sclk,
50207ccd5a2cSjsg 				     pl->mclk,
50217ccd5a2cSjsg 				     &level->mclk,
50227ccd5a2cSjsg 				     (level->strobeMode & SISLANDS_SMC_STROBE_ENABLE) != 0, dll_state_on);
50237ccd5a2cSjsg 	if (ret)
50247ccd5a2cSjsg 		return ret;
50257ccd5a2cSjsg 
50267ccd5a2cSjsg 	ret = si_populate_voltage_value(rdev,
50277ccd5a2cSjsg 					&eg_pi->vddc_voltage_table,
50287ccd5a2cSjsg 					pl->vddc, &level->vddc);
50297ccd5a2cSjsg 	if (ret)
50307ccd5a2cSjsg 		return ret;
50317ccd5a2cSjsg 
50327ccd5a2cSjsg 
50337ccd5a2cSjsg 	ret = si_get_std_voltage_value(rdev, &level->vddc, &std_vddc);
50347ccd5a2cSjsg 	if (ret)
50357ccd5a2cSjsg 		return ret;
50367ccd5a2cSjsg 
50377ccd5a2cSjsg 	ret = si_populate_std_voltage_value(rdev, std_vddc,
50387ccd5a2cSjsg 					    level->vddc.index, &level->std_vddc);
50397ccd5a2cSjsg 	if (ret)
50407ccd5a2cSjsg 		return ret;
50417ccd5a2cSjsg 
50427ccd5a2cSjsg 	if (eg_pi->vddci_control) {
50437ccd5a2cSjsg 		ret = si_populate_voltage_value(rdev, &eg_pi->vddci_voltage_table,
50447ccd5a2cSjsg 						pl->vddci, &level->vddci);
50457ccd5a2cSjsg 		if (ret)
50467ccd5a2cSjsg 			return ret;
50477ccd5a2cSjsg 	}
50487ccd5a2cSjsg 
50497ccd5a2cSjsg 	if (si_pi->vddc_phase_shed_control) {
50507ccd5a2cSjsg 		ret = si_populate_phase_shedding_value(rdev,
50517ccd5a2cSjsg 						       &rdev->pm.dpm.dyn_state.phase_shedding_limits_table,
50527ccd5a2cSjsg 						       pl->vddc,
50537ccd5a2cSjsg 						       pl->sclk,
50547ccd5a2cSjsg 						       pl->mclk,
50557ccd5a2cSjsg 						       &level->vddc);
50567ccd5a2cSjsg 		if (ret)
50577ccd5a2cSjsg 			return ret;
50587ccd5a2cSjsg 	}
50597ccd5a2cSjsg 
50607ccd5a2cSjsg 	level->MaxPoweredUpCU = si_pi->max_cu;
50617ccd5a2cSjsg 
50627ccd5a2cSjsg 	ret = si_populate_mvdd_value(rdev, pl->mclk, &level->mvdd);
50637ccd5a2cSjsg 
50647ccd5a2cSjsg 	return ret;
50657ccd5a2cSjsg }
50667ccd5a2cSjsg 
si_populate_smc_t(struct radeon_device * rdev,struct radeon_ps * radeon_state,SISLANDS_SMC_SWSTATE * smc_state)50677ccd5a2cSjsg static int si_populate_smc_t(struct radeon_device *rdev,
50687ccd5a2cSjsg 			     struct radeon_ps *radeon_state,
50697ccd5a2cSjsg 			     SISLANDS_SMC_SWSTATE *smc_state)
50707ccd5a2cSjsg {
50717ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
50727ccd5a2cSjsg 	struct ni_ps *state = ni_get_ps(radeon_state);
50737ccd5a2cSjsg 	u32 a_t;
50747ccd5a2cSjsg 	u32 t_l, t_h;
50757ccd5a2cSjsg 	u32 high_bsp;
50767ccd5a2cSjsg 	int i, ret;
50777ccd5a2cSjsg 
50787ccd5a2cSjsg 	if (state->performance_level_count >= 9)
50797ccd5a2cSjsg 		return -EINVAL;
50807ccd5a2cSjsg 
50817ccd5a2cSjsg 	if (state->performance_level_count < 2) {
50827ccd5a2cSjsg 		a_t = CG_R(0xffff) | CG_L(0);
50837ccd5a2cSjsg 		smc_state->levels[0].aT = cpu_to_be32(a_t);
50847ccd5a2cSjsg 		return 0;
50857ccd5a2cSjsg 	}
50867ccd5a2cSjsg 
50877ccd5a2cSjsg 	smc_state->levels[0].aT = cpu_to_be32(0);
50887ccd5a2cSjsg 
50897ccd5a2cSjsg 	for (i = 0; i <= state->performance_level_count - 2; i++) {
50907ccd5a2cSjsg 		ret = r600_calculate_at(
50917ccd5a2cSjsg 			(50 / SISLANDS_MAX_HARDWARE_POWERLEVELS) * 100 * (i + 1),
50927ccd5a2cSjsg 			100 * R600_AH_DFLT,
50937ccd5a2cSjsg 			state->performance_levels[i + 1].sclk,
50947ccd5a2cSjsg 			state->performance_levels[i].sclk,
50957ccd5a2cSjsg 			&t_l,
50967ccd5a2cSjsg 			&t_h);
50977ccd5a2cSjsg 
50987ccd5a2cSjsg 		if (ret) {
50997ccd5a2cSjsg 			t_h = (i + 1) * 1000 - 50 * R600_AH_DFLT;
51007ccd5a2cSjsg 			t_l = (i + 1) * 1000 + 50 * R600_AH_DFLT;
51017ccd5a2cSjsg 		}
51027ccd5a2cSjsg 
51037ccd5a2cSjsg 		a_t = be32_to_cpu(smc_state->levels[i].aT) & ~CG_R_MASK;
51047ccd5a2cSjsg 		a_t |= CG_R(t_l * pi->bsp / 20000);
51057ccd5a2cSjsg 		smc_state->levels[i].aT = cpu_to_be32(a_t);
51067ccd5a2cSjsg 
51077ccd5a2cSjsg 		high_bsp = (i == state->performance_level_count - 2) ?
51087ccd5a2cSjsg 			pi->pbsp : pi->bsp;
51097ccd5a2cSjsg 		a_t = CG_R(0xffff) | CG_L(t_h * high_bsp / 20000);
51107ccd5a2cSjsg 		smc_state->levels[i + 1].aT = cpu_to_be32(a_t);
51117ccd5a2cSjsg 	}
51127ccd5a2cSjsg 
51137ccd5a2cSjsg 	return 0;
51147ccd5a2cSjsg }
51157ccd5a2cSjsg 
si_disable_ulv(struct radeon_device * rdev)51167ccd5a2cSjsg static int si_disable_ulv(struct radeon_device *rdev)
51177ccd5a2cSjsg {
51187ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
51197ccd5a2cSjsg 	struct si_ulv_param *ulv = &si_pi->ulv;
51207ccd5a2cSjsg 
51217ccd5a2cSjsg 	if (ulv->supported)
51227ccd5a2cSjsg 		return (si_send_msg_to_smc(rdev, PPSMC_MSG_DisableULV) == PPSMC_Result_OK) ?
51237ccd5a2cSjsg 			0 : -EINVAL;
51247ccd5a2cSjsg 
51257ccd5a2cSjsg 	return 0;
51267ccd5a2cSjsg }
51277ccd5a2cSjsg 
si_is_state_ulv_compatible(struct radeon_device * rdev,struct radeon_ps * radeon_state)51287ccd5a2cSjsg static bool si_is_state_ulv_compatible(struct radeon_device *rdev,
51297ccd5a2cSjsg 				       struct radeon_ps *radeon_state)
51307ccd5a2cSjsg {
51317ccd5a2cSjsg 	const struct si_power_info *si_pi = si_get_pi(rdev);
51327ccd5a2cSjsg 	const struct si_ulv_param *ulv = &si_pi->ulv;
51337ccd5a2cSjsg 	const struct ni_ps *state = ni_get_ps(radeon_state);
51347ccd5a2cSjsg 	int i;
51357ccd5a2cSjsg 
51367ccd5a2cSjsg 	if (state->performance_levels[0].mclk != ulv->pl.mclk)
51377ccd5a2cSjsg 		return false;
51387ccd5a2cSjsg 
51397ccd5a2cSjsg 	/* XXX validate against display requirements! */
51407ccd5a2cSjsg 
51417ccd5a2cSjsg 	for (i = 0; i < rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count; i++) {
51427ccd5a2cSjsg 		if (rdev->clock.current_dispclk <=
51437ccd5a2cSjsg 		    rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[i].clk) {
51447ccd5a2cSjsg 			if (ulv->pl.vddc <
51457ccd5a2cSjsg 			    rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[i].v)
51467ccd5a2cSjsg 				return false;
51477ccd5a2cSjsg 		}
51487ccd5a2cSjsg 	}
51497ccd5a2cSjsg 
51507ccd5a2cSjsg 	if ((radeon_state->vclk != 0) || (radeon_state->dclk != 0))
51517ccd5a2cSjsg 		return false;
51527ccd5a2cSjsg 
51537ccd5a2cSjsg 	return true;
51547ccd5a2cSjsg }
51557ccd5a2cSjsg 
si_set_power_state_conditionally_enable_ulv(struct radeon_device * rdev,struct radeon_ps * radeon_new_state)51567ccd5a2cSjsg static int si_set_power_state_conditionally_enable_ulv(struct radeon_device *rdev,
51577ccd5a2cSjsg 						       struct radeon_ps *radeon_new_state)
51587ccd5a2cSjsg {
51597ccd5a2cSjsg 	const struct si_power_info *si_pi = si_get_pi(rdev);
51607ccd5a2cSjsg 	const struct si_ulv_param *ulv = &si_pi->ulv;
51617ccd5a2cSjsg 
51627ccd5a2cSjsg 	if (ulv->supported) {
51637ccd5a2cSjsg 		if (si_is_state_ulv_compatible(rdev, radeon_new_state))
51647ccd5a2cSjsg 			return (si_send_msg_to_smc(rdev, PPSMC_MSG_EnableULV) == PPSMC_Result_OK) ?
51657ccd5a2cSjsg 				0 : -EINVAL;
51667ccd5a2cSjsg 	}
51677ccd5a2cSjsg 	return 0;
51687ccd5a2cSjsg }
51697ccd5a2cSjsg 
si_convert_power_state_to_smc(struct radeon_device * rdev,struct radeon_ps * radeon_state,SISLANDS_SMC_SWSTATE * smc_state)51707ccd5a2cSjsg static int si_convert_power_state_to_smc(struct radeon_device *rdev,
51717ccd5a2cSjsg 					 struct radeon_ps *radeon_state,
51727ccd5a2cSjsg 					 SISLANDS_SMC_SWSTATE *smc_state)
51737ccd5a2cSjsg {
51747ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
51757ccd5a2cSjsg 	struct ni_power_info *ni_pi = ni_get_pi(rdev);
51767ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
51777ccd5a2cSjsg 	struct ni_ps *state = ni_get_ps(radeon_state);
51787ccd5a2cSjsg 	int i, ret;
51797ccd5a2cSjsg 	u32 threshold;
51807ccd5a2cSjsg 	u32 sclk_in_sr = 1350; /* ??? */
51817ccd5a2cSjsg 
51827ccd5a2cSjsg 	if (state->performance_level_count > SISLANDS_MAX_HARDWARE_POWERLEVELS)
51837ccd5a2cSjsg 		return -EINVAL;
51847ccd5a2cSjsg 
51857ccd5a2cSjsg 	threshold = state->performance_levels[state->performance_level_count-1].sclk * 100 / 100;
51867ccd5a2cSjsg 
51877ccd5a2cSjsg 	if (radeon_state->vclk && radeon_state->dclk) {
51887ccd5a2cSjsg 		eg_pi->uvd_enabled = true;
51897ccd5a2cSjsg 		if (eg_pi->smu_uvd_hs)
51907ccd5a2cSjsg 			smc_state->flags |= PPSMC_SWSTATE_FLAG_UVD;
51917ccd5a2cSjsg 	} else {
51927ccd5a2cSjsg 		eg_pi->uvd_enabled = false;
51937ccd5a2cSjsg 	}
51947ccd5a2cSjsg 
51957ccd5a2cSjsg 	if (state->dc_compatible)
51967ccd5a2cSjsg 		smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;
51977ccd5a2cSjsg 
51987ccd5a2cSjsg 	smc_state->levelCount = 0;
51997ccd5a2cSjsg 	for (i = 0; i < state->performance_level_count; i++) {
52007ccd5a2cSjsg 		if (eg_pi->sclk_deep_sleep) {
52017ccd5a2cSjsg 			if ((i == 0) || si_pi->sclk_deep_sleep_above_low) {
52027ccd5a2cSjsg 				if (sclk_in_sr <= SCLK_MIN_DEEPSLEEP_FREQ)
52037ccd5a2cSjsg 					smc_state->levels[i].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_BYPASS;
52047ccd5a2cSjsg 				else
52057ccd5a2cSjsg 					smc_state->levels[i].stateFlags |= PPSMC_STATEFLAG_DEEPSLEEP_THROTTLE;
52067ccd5a2cSjsg 			}
52077ccd5a2cSjsg 		}
52087ccd5a2cSjsg 
52097ccd5a2cSjsg 		ret = si_convert_power_level_to_smc(rdev, &state->performance_levels[i],
52107ccd5a2cSjsg 						    &smc_state->levels[i]);
52117ccd5a2cSjsg 		smc_state->levels[i].arbRefreshState =
52127ccd5a2cSjsg 			(u8)(SISLANDS_DRIVER_STATE_ARB_INDEX + i);
52137ccd5a2cSjsg 
52147ccd5a2cSjsg 		if (ret)
52157ccd5a2cSjsg 			return ret;
52167ccd5a2cSjsg 
52177ccd5a2cSjsg 		if (ni_pi->enable_power_containment)
52187ccd5a2cSjsg 			smc_state->levels[i].displayWatermark =
52197ccd5a2cSjsg 				(state->performance_levels[i].sclk < threshold) ?
52207ccd5a2cSjsg 				PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
52217ccd5a2cSjsg 		else
52227ccd5a2cSjsg 			smc_state->levels[i].displayWatermark = (i < 2) ?
52237ccd5a2cSjsg 				PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
52247ccd5a2cSjsg 
52257ccd5a2cSjsg 		if (eg_pi->dynamic_ac_timing)
52267ccd5a2cSjsg 			smc_state->levels[i].ACIndex = SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i;
52277ccd5a2cSjsg 		else
52287ccd5a2cSjsg 			smc_state->levels[i].ACIndex = 0;
52297ccd5a2cSjsg 
52307ccd5a2cSjsg 		smc_state->levelCount++;
52317ccd5a2cSjsg 	}
52327ccd5a2cSjsg 
52337ccd5a2cSjsg 	si_write_smc_soft_register(rdev,
52347ccd5a2cSjsg 				   SI_SMC_SOFT_REGISTER_watermark_threshold,
52357ccd5a2cSjsg 				   threshold / 512);
52367ccd5a2cSjsg 
52377ccd5a2cSjsg 	si_populate_smc_sp(rdev, radeon_state, smc_state);
52387ccd5a2cSjsg 
52397ccd5a2cSjsg 	ret = si_populate_power_containment_values(rdev, radeon_state, smc_state);
52407ccd5a2cSjsg 	if (ret)
52417ccd5a2cSjsg 		ni_pi->enable_power_containment = false;
52427ccd5a2cSjsg 
52437ccd5a2cSjsg 	ret = si_populate_sq_ramping_values(rdev, radeon_state, smc_state);
52447ccd5a2cSjsg 	if (ret)
52457ccd5a2cSjsg 		ni_pi->enable_sq_ramping = false;
52467ccd5a2cSjsg 
52477ccd5a2cSjsg 	return si_populate_smc_t(rdev, radeon_state, smc_state);
52487ccd5a2cSjsg }
52497ccd5a2cSjsg 
si_upload_sw_state(struct radeon_device * rdev,struct radeon_ps * radeon_new_state)52507ccd5a2cSjsg static int si_upload_sw_state(struct radeon_device *rdev,
52517ccd5a2cSjsg 			      struct radeon_ps *radeon_new_state)
52527ccd5a2cSjsg {
52537ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
52547ccd5a2cSjsg 	struct ni_ps *new_state = ni_get_ps(radeon_new_state);
52557ccd5a2cSjsg 	int ret;
52567ccd5a2cSjsg 	u32 address = si_pi->state_table_start +
52577ccd5a2cSjsg 		offsetof(SISLANDS_SMC_STATETABLE, driverState);
52587ccd5a2cSjsg 	SISLANDS_SMC_SWSTATE *smc_state = &si_pi->smc_statetable.driverState;
52595ca02815Sjsg 	size_t state_size = struct_size(smc_state, levels,
52605ca02815Sjsg 					new_state->performance_level_count);
52617ccd5a2cSjsg 
52627ccd5a2cSjsg 	memset(smc_state, 0, state_size);
52637ccd5a2cSjsg 
52647ccd5a2cSjsg 	ret = si_convert_power_state_to_smc(rdev, radeon_new_state, smc_state);
52657ccd5a2cSjsg 	if (ret)
52667ccd5a2cSjsg 		return ret;
52677ccd5a2cSjsg 
52687ccd5a2cSjsg 	ret = si_copy_bytes_to_smc(rdev, address, (u8 *)smc_state,
52697ccd5a2cSjsg 				   state_size, si_pi->sram_end);
52707ccd5a2cSjsg 
52717ccd5a2cSjsg 	return ret;
52727ccd5a2cSjsg }
52737ccd5a2cSjsg 
si_upload_ulv_state(struct radeon_device * rdev)52747ccd5a2cSjsg static int si_upload_ulv_state(struct radeon_device *rdev)
52757ccd5a2cSjsg {
52767ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
52777ccd5a2cSjsg 	struct si_ulv_param *ulv = &si_pi->ulv;
52787ccd5a2cSjsg 	int ret = 0;
52797ccd5a2cSjsg 
52807ccd5a2cSjsg 	if (ulv->supported && ulv->pl.vddc) {
52817ccd5a2cSjsg 		u32 address = si_pi->state_table_start +
52827ccd5a2cSjsg 			offsetof(SISLANDS_SMC_STATETABLE, ULVState);
52835ca02815Sjsg 		struct SISLANDS_SMC_SWSTATE_SINGLE *smc_state = &si_pi->smc_statetable.ULVState;
52845ca02815Sjsg 		u32 state_size = sizeof(struct SISLANDS_SMC_SWSTATE_SINGLE);
52857ccd5a2cSjsg 
52867ccd5a2cSjsg 		memset(smc_state, 0, state_size);
52877ccd5a2cSjsg 
52887ccd5a2cSjsg 		ret = si_populate_ulv_state(rdev, smc_state);
52897ccd5a2cSjsg 		if (!ret)
52907ccd5a2cSjsg 			ret = si_copy_bytes_to_smc(rdev, address, (u8 *)smc_state,
52917ccd5a2cSjsg 						   state_size, si_pi->sram_end);
52927ccd5a2cSjsg 	}
52937ccd5a2cSjsg 
52947ccd5a2cSjsg 	return ret;
52957ccd5a2cSjsg }
52967ccd5a2cSjsg 
si_upload_smc_data(struct radeon_device * rdev)52977ccd5a2cSjsg static int si_upload_smc_data(struct radeon_device *rdev)
52987ccd5a2cSjsg {
52997ccd5a2cSjsg 	struct radeon_crtc *radeon_crtc = NULL;
53007ccd5a2cSjsg 	int i;
53017ccd5a2cSjsg 
53027ccd5a2cSjsg 	if (rdev->pm.dpm.new_active_crtc_count == 0)
53037ccd5a2cSjsg 		return 0;
53047ccd5a2cSjsg 
53057ccd5a2cSjsg 	for (i = 0; i < rdev->num_crtc; i++) {
53067ccd5a2cSjsg 		if (rdev->pm.dpm.new_active_crtcs & (1 << i)) {
53077ccd5a2cSjsg 			radeon_crtc = rdev->mode_info.crtcs[i];
53087ccd5a2cSjsg 			break;
53097ccd5a2cSjsg 		}
53107ccd5a2cSjsg 	}
53117ccd5a2cSjsg 
53127ccd5a2cSjsg 	if (radeon_crtc == NULL)
53137ccd5a2cSjsg 		return 0;
53147ccd5a2cSjsg 
53157ccd5a2cSjsg 	if (radeon_crtc->line_time <= 0)
53167ccd5a2cSjsg 		return 0;
53177ccd5a2cSjsg 
53187ccd5a2cSjsg 	if (si_write_smc_soft_register(rdev,
53197ccd5a2cSjsg 				       SI_SMC_SOFT_REGISTER_crtc_index,
53207ccd5a2cSjsg 				       radeon_crtc->crtc_id) != PPSMC_Result_OK)
53217ccd5a2cSjsg 		return 0;
53227ccd5a2cSjsg 
53237ccd5a2cSjsg 	if (si_write_smc_soft_register(rdev,
53247ccd5a2cSjsg 				       SI_SMC_SOFT_REGISTER_mclk_change_block_cp_min,
53257ccd5a2cSjsg 				       radeon_crtc->wm_high / radeon_crtc->line_time) != PPSMC_Result_OK)
53267ccd5a2cSjsg 		return 0;
53277ccd5a2cSjsg 
53287ccd5a2cSjsg 	if (si_write_smc_soft_register(rdev,
53297ccd5a2cSjsg 				       SI_SMC_SOFT_REGISTER_mclk_change_block_cp_max,
53307ccd5a2cSjsg 				       radeon_crtc->wm_low / radeon_crtc->line_time) != PPSMC_Result_OK)
53317ccd5a2cSjsg 		return 0;
53327ccd5a2cSjsg 
53337ccd5a2cSjsg 	return 0;
53347ccd5a2cSjsg }
53357ccd5a2cSjsg 
si_set_mc_special_registers(struct radeon_device * rdev,struct si_mc_reg_table * table)53367ccd5a2cSjsg static int si_set_mc_special_registers(struct radeon_device *rdev,
53377ccd5a2cSjsg 				       struct si_mc_reg_table *table)
53387ccd5a2cSjsg {
53397ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
53407ccd5a2cSjsg 	u8 i, j, k;
53417ccd5a2cSjsg 	u32 temp_reg;
53427ccd5a2cSjsg 
53437ccd5a2cSjsg 	for (i = 0, j = table->last; i < table->last; i++) {
53447ccd5a2cSjsg 		if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
53457ccd5a2cSjsg 			return -EINVAL;
53467ccd5a2cSjsg 		switch (table->mc_reg_address[i].s1 << 2) {
53477ccd5a2cSjsg 		case MC_SEQ_MISC1:
53487ccd5a2cSjsg 			temp_reg = RREG32(MC_PMG_CMD_EMRS);
53497ccd5a2cSjsg 			table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2;
53507ccd5a2cSjsg 			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
53517ccd5a2cSjsg 			for (k = 0; k < table->num_entries; k++)
53527ccd5a2cSjsg 				table->mc_reg_table_entry[k].mc_data[j] =
53537ccd5a2cSjsg 					((temp_reg & 0xffff0000)) |
53547ccd5a2cSjsg 					((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
53557ccd5a2cSjsg 			j++;
53567ccd5a2cSjsg 			if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
53577ccd5a2cSjsg 				return -EINVAL;
53587ccd5a2cSjsg 
53597ccd5a2cSjsg 			temp_reg = RREG32(MC_PMG_CMD_MRS);
53607ccd5a2cSjsg 			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2;
53617ccd5a2cSjsg 			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
53627ccd5a2cSjsg 			for (k = 0; k < table->num_entries; k++) {
53637ccd5a2cSjsg 				table->mc_reg_table_entry[k].mc_data[j] =
53647ccd5a2cSjsg 					(temp_reg & 0xffff0000) |
53657ccd5a2cSjsg 					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
53667ccd5a2cSjsg 				if (!pi->mem_gddr5)
53677ccd5a2cSjsg 					table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
53687ccd5a2cSjsg 			}
53697ccd5a2cSjsg 			j++;
53707ccd5a2cSjsg 			if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
53717ccd5a2cSjsg 				return -EINVAL;
53727ccd5a2cSjsg 
53737ccd5a2cSjsg 			if (!pi->mem_gddr5) {
53747ccd5a2cSjsg 				table->mc_reg_address[j].s1 = MC_PMG_AUTO_CMD >> 2;
53757ccd5a2cSjsg 				table->mc_reg_address[j].s0 = MC_PMG_AUTO_CMD >> 2;
53767ccd5a2cSjsg 				for (k = 0; k < table->num_entries; k++)
53777ccd5a2cSjsg 					table->mc_reg_table_entry[k].mc_data[j] =
53787ccd5a2cSjsg 						(table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16;
53797ccd5a2cSjsg 				j++;
53807ccd5a2cSjsg 				if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
53817ccd5a2cSjsg 					return -EINVAL;
53827ccd5a2cSjsg 			}
53837ccd5a2cSjsg 			break;
53847ccd5a2cSjsg 		case MC_SEQ_RESERVE_M:
53857ccd5a2cSjsg 			temp_reg = RREG32(MC_PMG_CMD_MRS1);
53867ccd5a2cSjsg 			table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
53877ccd5a2cSjsg 			table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
53887ccd5a2cSjsg 			for(k = 0; k < table->num_entries; k++)
53897ccd5a2cSjsg 				table->mc_reg_table_entry[k].mc_data[j] =
53907ccd5a2cSjsg 					(temp_reg & 0xffff0000) |
53917ccd5a2cSjsg 					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
53927ccd5a2cSjsg 			j++;
53937ccd5a2cSjsg 			if (j >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
53947ccd5a2cSjsg 				return -EINVAL;
53957ccd5a2cSjsg 			break;
53967ccd5a2cSjsg 		default:
53977ccd5a2cSjsg 			break;
53987ccd5a2cSjsg 		}
53997ccd5a2cSjsg 	}
54007ccd5a2cSjsg 
54017ccd5a2cSjsg 	table->last = j;
54027ccd5a2cSjsg 
54037ccd5a2cSjsg 	return 0;
54047ccd5a2cSjsg }
54057ccd5a2cSjsg 
si_check_s0_mc_reg_index(u16 in_reg,u16 * out_reg)54067ccd5a2cSjsg static bool si_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
54077ccd5a2cSjsg {
54087ccd5a2cSjsg 	bool result = true;
54097ccd5a2cSjsg 
54107ccd5a2cSjsg 	switch (in_reg) {
54117ccd5a2cSjsg 	case  MC_SEQ_RAS_TIMING >> 2:
54127ccd5a2cSjsg 		*out_reg = MC_SEQ_RAS_TIMING_LP >> 2;
54137ccd5a2cSjsg 		break;
54147ccd5a2cSjsg 	case MC_SEQ_CAS_TIMING >> 2:
54157ccd5a2cSjsg 		*out_reg = MC_SEQ_CAS_TIMING_LP >> 2;
54167ccd5a2cSjsg 		break;
54177ccd5a2cSjsg 	case MC_SEQ_MISC_TIMING >> 2:
54187ccd5a2cSjsg 		*out_reg = MC_SEQ_MISC_TIMING_LP >> 2;
54197ccd5a2cSjsg 		break;
54207ccd5a2cSjsg 	case MC_SEQ_MISC_TIMING2 >> 2:
54217ccd5a2cSjsg 		*out_reg = MC_SEQ_MISC_TIMING2_LP >> 2;
54227ccd5a2cSjsg 		break;
54237ccd5a2cSjsg 	case MC_SEQ_RD_CTL_D0 >> 2:
54247ccd5a2cSjsg 		*out_reg = MC_SEQ_RD_CTL_D0_LP >> 2;
54257ccd5a2cSjsg 		break;
54267ccd5a2cSjsg 	case MC_SEQ_RD_CTL_D1 >> 2:
54277ccd5a2cSjsg 		*out_reg = MC_SEQ_RD_CTL_D1_LP >> 2;
54287ccd5a2cSjsg 		break;
54297ccd5a2cSjsg 	case MC_SEQ_WR_CTL_D0 >> 2:
54307ccd5a2cSjsg 		*out_reg = MC_SEQ_WR_CTL_D0_LP >> 2;
54317ccd5a2cSjsg 		break;
54327ccd5a2cSjsg 	case MC_SEQ_WR_CTL_D1 >> 2:
54337ccd5a2cSjsg 		*out_reg = MC_SEQ_WR_CTL_D1_LP >> 2;
54347ccd5a2cSjsg 		break;
54357ccd5a2cSjsg 	case MC_PMG_CMD_EMRS >> 2:
54367ccd5a2cSjsg 		*out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
54377ccd5a2cSjsg 		break;
54387ccd5a2cSjsg 	case MC_PMG_CMD_MRS >> 2:
54397ccd5a2cSjsg 		*out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2;
54407ccd5a2cSjsg 		break;
54417ccd5a2cSjsg 	case MC_PMG_CMD_MRS1 >> 2:
54427ccd5a2cSjsg 		*out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
54437ccd5a2cSjsg 		break;
54447ccd5a2cSjsg 	case MC_SEQ_PMG_TIMING >> 2:
54457ccd5a2cSjsg 		*out_reg = MC_SEQ_PMG_TIMING_LP >> 2;
54467ccd5a2cSjsg 		break;
54477ccd5a2cSjsg 	case MC_PMG_CMD_MRS2 >> 2:
54487ccd5a2cSjsg 		*out_reg = MC_SEQ_PMG_CMD_MRS2_LP >> 2;
54497ccd5a2cSjsg 		break;
54507ccd5a2cSjsg 	case MC_SEQ_WR_CTL_2 >> 2:
54517ccd5a2cSjsg 		*out_reg = MC_SEQ_WR_CTL_2_LP >> 2;
54527ccd5a2cSjsg 		break;
54537ccd5a2cSjsg 	default:
54547ccd5a2cSjsg 		result = false;
54557ccd5a2cSjsg 		break;
54567ccd5a2cSjsg 	}
54577ccd5a2cSjsg 
54587ccd5a2cSjsg 	return result;
54597ccd5a2cSjsg }
54607ccd5a2cSjsg 
si_set_valid_flag(struct si_mc_reg_table * table)54617ccd5a2cSjsg static void si_set_valid_flag(struct si_mc_reg_table *table)
54627ccd5a2cSjsg {
54637ccd5a2cSjsg 	u8 i, j;
54647ccd5a2cSjsg 
54657ccd5a2cSjsg 	for (i = 0; i < table->last; i++) {
54667ccd5a2cSjsg 		for (j = 1; j < table->num_entries; j++) {
54677ccd5a2cSjsg 			if (table->mc_reg_table_entry[j-1].mc_data[i] != table->mc_reg_table_entry[j].mc_data[i]) {
54687ccd5a2cSjsg 				table->valid_flag |= 1 << i;
54697ccd5a2cSjsg 				break;
54707ccd5a2cSjsg 			}
54717ccd5a2cSjsg 		}
54727ccd5a2cSjsg 	}
54737ccd5a2cSjsg }
54747ccd5a2cSjsg 
si_set_s0_mc_reg_index(struct si_mc_reg_table * table)54757ccd5a2cSjsg static void si_set_s0_mc_reg_index(struct si_mc_reg_table *table)
54767ccd5a2cSjsg {
54777ccd5a2cSjsg 	u32 i;
54787ccd5a2cSjsg 	u16 address;
54797ccd5a2cSjsg 
54807ccd5a2cSjsg 	for (i = 0; i < table->last; i++)
54817ccd5a2cSjsg 		table->mc_reg_address[i].s0 = si_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
54827ccd5a2cSjsg 			address : table->mc_reg_address[i].s1;
54837ccd5a2cSjsg 
54847ccd5a2cSjsg }
54857ccd5a2cSjsg 
si_copy_vbios_mc_reg_table(struct atom_mc_reg_table * table,struct si_mc_reg_table * si_table)54867ccd5a2cSjsg static int si_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
54877ccd5a2cSjsg 				      struct si_mc_reg_table *si_table)
54887ccd5a2cSjsg {
54897ccd5a2cSjsg 	u8 i, j;
54907ccd5a2cSjsg 
54917ccd5a2cSjsg 	if (table->last > SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
54927ccd5a2cSjsg 		return -EINVAL;
54937ccd5a2cSjsg 	if (table->num_entries > MAX_AC_TIMING_ENTRIES)
54947ccd5a2cSjsg 		return -EINVAL;
54957ccd5a2cSjsg 
54967ccd5a2cSjsg 	for (i = 0; i < table->last; i++)
54977ccd5a2cSjsg 		si_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
54987ccd5a2cSjsg 	si_table->last = table->last;
54997ccd5a2cSjsg 
55007ccd5a2cSjsg 	for (i = 0; i < table->num_entries; i++) {
55017ccd5a2cSjsg 		si_table->mc_reg_table_entry[i].mclk_max =
55027ccd5a2cSjsg 			table->mc_reg_table_entry[i].mclk_max;
55037ccd5a2cSjsg 		for (j = 0; j < table->last; j++) {
55047ccd5a2cSjsg 			si_table->mc_reg_table_entry[i].mc_data[j] =
55057ccd5a2cSjsg 				table->mc_reg_table_entry[i].mc_data[j];
55067ccd5a2cSjsg 		}
55077ccd5a2cSjsg 	}
55087ccd5a2cSjsg 	si_table->num_entries = table->num_entries;
55097ccd5a2cSjsg 
55107ccd5a2cSjsg 	return 0;
55117ccd5a2cSjsg }
55127ccd5a2cSjsg 
si_initialize_mc_reg_table(struct radeon_device * rdev)55137ccd5a2cSjsg static int si_initialize_mc_reg_table(struct radeon_device *rdev)
55147ccd5a2cSjsg {
55157ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
55167ccd5a2cSjsg 	struct atom_mc_reg_table *table;
55177ccd5a2cSjsg 	struct si_mc_reg_table *si_table = &si_pi->mc_reg_table;
55187ccd5a2cSjsg 	u8 module_index = rv770_get_memory_module_index(rdev);
55197ccd5a2cSjsg 	int ret;
55207ccd5a2cSjsg 
55217ccd5a2cSjsg 	table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
55227ccd5a2cSjsg 	if (!table)
55237ccd5a2cSjsg 		return -ENOMEM;
55247ccd5a2cSjsg 
55257ccd5a2cSjsg 	WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
55267ccd5a2cSjsg 	WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
55277ccd5a2cSjsg 	WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
55287ccd5a2cSjsg 	WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
55297ccd5a2cSjsg 	WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
55307ccd5a2cSjsg 	WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
55317ccd5a2cSjsg 	WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
55327ccd5a2cSjsg 	WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
55337ccd5a2cSjsg 	WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
55347ccd5a2cSjsg 	WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
55357ccd5a2cSjsg 	WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
55367ccd5a2cSjsg 	WREG32(MC_SEQ_PMG_TIMING_LP, RREG32(MC_SEQ_PMG_TIMING));
55377ccd5a2cSjsg 	WREG32(MC_SEQ_PMG_CMD_MRS2_LP, RREG32(MC_PMG_CMD_MRS2));
55387ccd5a2cSjsg 	WREG32(MC_SEQ_WR_CTL_2_LP, RREG32(MC_SEQ_WR_CTL_2));
55397ccd5a2cSjsg 
55407ccd5a2cSjsg 	ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
55417ccd5a2cSjsg 	if (ret)
55427ccd5a2cSjsg 		goto init_mc_done;
55437ccd5a2cSjsg 
55447ccd5a2cSjsg 	ret = si_copy_vbios_mc_reg_table(table, si_table);
55457ccd5a2cSjsg 	if (ret)
55467ccd5a2cSjsg 		goto init_mc_done;
55477ccd5a2cSjsg 
55487ccd5a2cSjsg 	si_set_s0_mc_reg_index(si_table);
55497ccd5a2cSjsg 
55507ccd5a2cSjsg 	ret = si_set_mc_special_registers(rdev, si_table);
55517ccd5a2cSjsg 	if (ret)
55527ccd5a2cSjsg 		goto init_mc_done;
55537ccd5a2cSjsg 
55547ccd5a2cSjsg 	si_set_valid_flag(si_table);
55557ccd5a2cSjsg 
55567ccd5a2cSjsg init_mc_done:
55577ccd5a2cSjsg 	kfree(table);
55587ccd5a2cSjsg 
55597ccd5a2cSjsg 	return ret;
55607ccd5a2cSjsg 
55617ccd5a2cSjsg }
55627ccd5a2cSjsg 
si_populate_mc_reg_addresses(struct radeon_device * rdev,SMC_SIslands_MCRegisters * mc_reg_table)55637ccd5a2cSjsg static void si_populate_mc_reg_addresses(struct radeon_device *rdev,
55647ccd5a2cSjsg 					 SMC_SIslands_MCRegisters *mc_reg_table)
55657ccd5a2cSjsg {
55667ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
55677ccd5a2cSjsg 	u32 i, j;
55687ccd5a2cSjsg 
55697ccd5a2cSjsg 	for (i = 0, j = 0; j < si_pi->mc_reg_table.last; j++) {
55707ccd5a2cSjsg 		if (si_pi->mc_reg_table.valid_flag & (1 << j)) {
55717ccd5a2cSjsg 			if (i >= SMC_SISLANDS_MC_REGISTER_ARRAY_SIZE)
55727ccd5a2cSjsg 				break;
55737ccd5a2cSjsg 			mc_reg_table->address[i].s0 =
55747ccd5a2cSjsg 				cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s0);
55757ccd5a2cSjsg 			mc_reg_table->address[i].s1 =
55767ccd5a2cSjsg 				cpu_to_be16(si_pi->mc_reg_table.mc_reg_address[j].s1);
55777ccd5a2cSjsg 			i++;
55787ccd5a2cSjsg 		}
55797ccd5a2cSjsg 	}
55807ccd5a2cSjsg 	mc_reg_table->last = (u8)i;
55817ccd5a2cSjsg }
55827ccd5a2cSjsg 
si_convert_mc_registers(const struct si_mc_reg_entry * entry,SMC_SIslands_MCRegisterSet * data,u32 num_entries,u32 valid_flag)55837ccd5a2cSjsg static void si_convert_mc_registers(const struct si_mc_reg_entry *entry,
55847ccd5a2cSjsg 				    SMC_SIslands_MCRegisterSet *data,
55857ccd5a2cSjsg 				    u32 num_entries, u32 valid_flag)
55867ccd5a2cSjsg {
55877ccd5a2cSjsg 	u32 i, j;
55887ccd5a2cSjsg 
55897ccd5a2cSjsg 	for(i = 0, j = 0; j < num_entries; j++) {
55907ccd5a2cSjsg 		if (valid_flag & (1 << j)) {
55917ccd5a2cSjsg 			data->value[i] = cpu_to_be32(entry->mc_data[j]);
55927ccd5a2cSjsg 			i++;
55937ccd5a2cSjsg 		}
55947ccd5a2cSjsg 	}
55957ccd5a2cSjsg }
55967ccd5a2cSjsg 
si_convert_mc_reg_table_entry_to_smc(struct radeon_device * rdev,struct rv7xx_pl * pl,SMC_SIslands_MCRegisterSet * mc_reg_table_data)55977ccd5a2cSjsg static void si_convert_mc_reg_table_entry_to_smc(struct radeon_device *rdev,
55987ccd5a2cSjsg 						 struct rv7xx_pl *pl,
55997ccd5a2cSjsg 						 SMC_SIslands_MCRegisterSet *mc_reg_table_data)
56007ccd5a2cSjsg {
56017ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
56027ccd5a2cSjsg 	u32 i = 0;
56037ccd5a2cSjsg 
56047ccd5a2cSjsg 	for (i = 0; i < si_pi->mc_reg_table.num_entries; i++) {
56057ccd5a2cSjsg 		if (pl->mclk <= si_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max)
56067ccd5a2cSjsg 			break;
56077ccd5a2cSjsg 	}
56087ccd5a2cSjsg 
56097ccd5a2cSjsg 	if ((i == si_pi->mc_reg_table.num_entries) && (i > 0))
56107ccd5a2cSjsg 		--i;
56117ccd5a2cSjsg 
56127ccd5a2cSjsg 	si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[i],
56137ccd5a2cSjsg 				mc_reg_table_data, si_pi->mc_reg_table.last,
56147ccd5a2cSjsg 				si_pi->mc_reg_table.valid_flag);
56157ccd5a2cSjsg }
56167ccd5a2cSjsg 
si_convert_mc_reg_table_to_smc(struct radeon_device * rdev,struct radeon_ps * radeon_state,SMC_SIslands_MCRegisters * mc_reg_table)56177ccd5a2cSjsg static void si_convert_mc_reg_table_to_smc(struct radeon_device *rdev,
56187ccd5a2cSjsg 					   struct radeon_ps *radeon_state,
56197ccd5a2cSjsg 					   SMC_SIslands_MCRegisters *mc_reg_table)
56207ccd5a2cSjsg {
56217ccd5a2cSjsg 	struct ni_ps *state = ni_get_ps(radeon_state);
56227ccd5a2cSjsg 	int i;
56237ccd5a2cSjsg 
56247ccd5a2cSjsg 	for (i = 0; i < state->performance_level_count; i++) {
56257ccd5a2cSjsg 		si_convert_mc_reg_table_entry_to_smc(rdev,
56267ccd5a2cSjsg 						     &state->performance_levels[i],
56277ccd5a2cSjsg 						     &mc_reg_table->data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i]);
56287ccd5a2cSjsg 	}
56297ccd5a2cSjsg }
56307ccd5a2cSjsg 
si_populate_mc_reg_table(struct radeon_device * rdev,struct radeon_ps * radeon_boot_state)56317ccd5a2cSjsg static int si_populate_mc_reg_table(struct radeon_device *rdev,
56327ccd5a2cSjsg 				    struct radeon_ps *radeon_boot_state)
56337ccd5a2cSjsg {
56347ccd5a2cSjsg 	struct ni_ps *boot_state = ni_get_ps(radeon_boot_state);
56357ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
56367ccd5a2cSjsg 	struct si_ulv_param *ulv = &si_pi->ulv;
56377ccd5a2cSjsg 	SMC_SIslands_MCRegisters *smc_mc_reg_table = &si_pi->smc_mc_reg_table;
56387ccd5a2cSjsg 
56397ccd5a2cSjsg 	memset(smc_mc_reg_table, 0, sizeof(SMC_SIslands_MCRegisters));
56407ccd5a2cSjsg 
56417ccd5a2cSjsg 	si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_seq_index, 1);
56427ccd5a2cSjsg 
56437ccd5a2cSjsg 	si_populate_mc_reg_addresses(rdev, smc_mc_reg_table);
56447ccd5a2cSjsg 
56457ccd5a2cSjsg 	si_convert_mc_reg_table_entry_to_smc(rdev, &boot_state->performance_levels[0],
56467ccd5a2cSjsg 					     &smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_INITIAL_SLOT]);
56477ccd5a2cSjsg 
56487ccd5a2cSjsg 	si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[0],
56497ccd5a2cSjsg 				&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ACPI_SLOT],
56507ccd5a2cSjsg 				si_pi->mc_reg_table.last,
56517ccd5a2cSjsg 				si_pi->mc_reg_table.valid_flag);
56527ccd5a2cSjsg 
56537ccd5a2cSjsg 	if (ulv->supported && ulv->pl.vddc != 0)
56547ccd5a2cSjsg 		si_convert_mc_reg_table_entry_to_smc(rdev, &ulv->pl,
56557ccd5a2cSjsg 						     &smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ULV_SLOT]);
56567ccd5a2cSjsg 	else
56577ccd5a2cSjsg 		si_convert_mc_registers(&si_pi->mc_reg_table.mc_reg_table_entry[0],
56587ccd5a2cSjsg 					&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_ULV_SLOT],
56597ccd5a2cSjsg 					si_pi->mc_reg_table.last,
56607ccd5a2cSjsg 					si_pi->mc_reg_table.valid_flag);
56617ccd5a2cSjsg 
56627ccd5a2cSjsg 	si_convert_mc_reg_table_to_smc(rdev, radeon_boot_state, smc_mc_reg_table);
56637ccd5a2cSjsg 
56647ccd5a2cSjsg 	return si_copy_bytes_to_smc(rdev, si_pi->mc_reg_table_start,
56657ccd5a2cSjsg 				    (u8 *)smc_mc_reg_table,
56667ccd5a2cSjsg 				    sizeof(SMC_SIslands_MCRegisters), si_pi->sram_end);
56677ccd5a2cSjsg }
56687ccd5a2cSjsg 
si_upload_mc_reg_table(struct radeon_device * rdev,struct radeon_ps * radeon_new_state)56697ccd5a2cSjsg static int si_upload_mc_reg_table(struct radeon_device *rdev,
56707ccd5a2cSjsg 				  struct radeon_ps *radeon_new_state)
56717ccd5a2cSjsg {
56727ccd5a2cSjsg 	struct ni_ps *new_state = ni_get_ps(radeon_new_state);
56737ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
56747ccd5a2cSjsg 	u32 address = si_pi->mc_reg_table_start +
56757ccd5a2cSjsg 		offsetof(SMC_SIslands_MCRegisters,
56767ccd5a2cSjsg 			 data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT]);
56777ccd5a2cSjsg 	SMC_SIslands_MCRegisters *smc_mc_reg_table = &si_pi->smc_mc_reg_table;
56787ccd5a2cSjsg 
56797ccd5a2cSjsg 	memset(smc_mc_reg_table, 0, sizeof(SMC_SIslands_MCRegisters));
56807ccd5a2cSjsg 
56817ccd5a2cSjsg 	si_convert_mc_reg_table_to_smc(rdev, radeon_new_state, smc_mc_reg_table);
56827ccd5a2cSjsg 
56837ccd5a2cSjsg 
56847ccd5a2cSjsg 	return si_copy_bytes_to_smc(rdev, address,
56857ccd5a2cSjsg 				    (u8 *)&smc_mc_reg_table->data[SISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT],
56867ccd5a2cSjsg 				    sizeof(SMC_SIslands_MCRegisterSet) * new_state->performance_level_count,
56877ccd5a2cSjsg 				    si_pi->sram_end);
56887ccd5a2cSjsg 
56897ccd5a2cSjsg }
56907ccd5a2cSjsg 
si_enable_voltage_control(struct radeon_device * rdev,bool enable)56917ccd5a2cSjsg static void si_enable_voltage_control(struct radeon_device *rdev, bool enable)
56927ccd5a2cSjsg {
56937ccd5a2cSjsg 	if (enable)
56947ccd5a2cSjsg 		WREG32_P(GENERAL_PWRMGT, VOLT_PWRMGT_EN, ~VOLT_PWRMGT_EN);
56957ccd5a2cSjsg 	else
56967ccd5a2cSjsg 		WREG32_P(GENERAL_PWRMGT, 0, ~VOLT_PWRMGT_EN);
56977ccd5a2cSjsg }
56987ccd5a2cSjsg 
si_get_maximum_link_speed(struct radeon_device * rdev,struct radeon_ps * radeon_state)56997ccd5a2cSjsg static enum radeon_pcie_gen si_get_maximum_link_speed(struct radeon_device *rdev,
57007ccd5a2cSjsg 						      struct radeon_ps *radeon_state)
57017ccd5a2cSjsg {
57027ccd5a2cSjsg 	struct ni_ps *state = ni_get_ps(radeon_state);
57037ccd5a2cSjsg 	int i;
57047ccd5a2cSjsg 	u16 pcie_speed, max_speed = 0;
57057ccd5a2cSjsg 
57067ccd5a2cSjsg 	for (i = 0; i < state->performance_level_count; i++) {
57077ccd5a2cSjsg 		pcie_speed = state->performance_levels[i].pcie_gen;
57087ccd5a2cSjsg 		if (max_speed < pcie_speed)
57097ccd5a2cSjsg 			max_speed = pcie_speed;
57107ccd5a2cSjsg 	}
57117ccd5a2cSjsg 	return max_speed;
57127ccd5a2cSjsg }
57137ccd5a2cSjsg 
si_get_current_pcie_speed(struct radeon_device * rdev)57147ccd5a2cSjsg static u16 si_get_current_pcie_speed(struct radeon_device *rdev)
57157ccd5a2cSjsg {
57167ccd5a2cSjsg 	u32 speed_cntl;
57177ccd5a2cSjsg 
57187ccd5a2cSjsg 	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL) & LC_CURRENT_DATA_RATE_MASK;
57197ccd5a2cSjsg 	speed_cntl >>= LC_CURRENT_DATA_RATE_SHIFT;
57207ccd5a2cSjsg 
57217ccd5a2cSjsg 	return (u16)speed_cntl;
57227ccd5a2cSjsg }
57237ccd5a2cSjsg 
si_request_link_speed_change_before_state_change(struct radeon_device * rdev,struct radeon_ps * radeon_new_state,struct radeon_ps * radeon_current_state)57247ccd5a2cSjsg static void si_request_link_speed_change_before_state_change(struct radeon_device *rdev,
57257ccd5a2cSjsg 							     struct radeon_ps *radeon_new_state,
57267ccd5a2cSjsg 							     struct radeon_ps *radeon_current_state)
57277ccd5a2cSjsg {
57287ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
57297ccd5a2cSjsg 	enum radeon_pcie_gen target_link_speed = si_get_maximum_link_speed(rdev, radeon_new_state);
57307ccd5a2cSjsg 	enum radeon_pcie_gen current_link_speed;
57317ccd5a2cSjsg 
57327ccd5a2cSjsg 	if (si_pi->force_pcie_gen == RADEON_PCIE_GEN_INVALID)
57337ccd5a2cSjsg 		current_link_speed = si_get_maximum_link_speed(rdev, radeon_current_state);
57347ccd5a2cSjsg 	else
57357ccd5a2cSjsg 		current_link_speed = si_pi->force_pcie_gen;
57367ccd5a2cSjsg 
57377ccd5a2cSjsg 	si_pi->force_pcie_gen = RADEON_PCIE_GEN_INVALID;
57387ccd5a2cSjsg 	si_pi->pspp_notify_required = false;
57397ccd5a2cSjsg 	if (target_link_speed > current_link_speed) {
57407ccd5a2cSjsg 		switch (target_link_speed) {
57417ccd5a2cSjsg #if defined(CONFIG_ACPI)
57427ccd5a2cSjsg 		case RADEON_PCIE_GEN3:
57437ccd5a2cSjsg 			if (radeon_acpi_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN3, false) == 0)
57447ccd5a2cSjsg 				break;
57457ccd5a2cSjsg 			si_pi->force_pcie_gen = RADEON_PCIE_GEN2;
57467ccd5a2cSjsg 			if (current_link_speed == RADEON_PCIE_GEN2)
57477ccd5a2cSjsg 				break;
5748ad8b1aafSjsg 			fallthrough;
57497ccd5a2cSjsg 		case RADEON_PCIE_GEN2:
57507ccd5a2cSjsg 			if (radeon_acpi_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, false) == 0)
57517ccd5a2cSjsg 				break;
57525ca02815Sjsg 			fallthrough;
57537ccd5a2cSjsg #endif
57547ccd5a2cSjsg 		default:
57557ccd5a2cSjsg 			si_pi->force_pcie_gen = si_get_current_pcie_speed(rdev);
57567ccd5a2cSjsg 			break;
57577ccd5a2cSjsg 		}
57587ccd5a2cSjsg 	} else {
57597ccd5a2cSjsg 		if (target_link_speed < current_link_speed)
57607ccd5a2cSjsg 			si_pi->pspp_notify_required = true;
57617ccd5a2cSjsg 	}
57627ccd5a2cSjsg }
57637ccd5a2cSjsg 
si_notify_link_speed_change_after_state_change(struct radeon_device * rdev,struct radeon_ps * radeon_new_state,struct radeon_ps * radeon_current_state)57647ccd5a2cSjsg static void si_notify_link_speed_change_after_state_change(struct radeon_device *rdev,
57657ccd5a2cSjsg 							   struct radeon_ps *radeon_new_state,
57667ccd5a2cSjsg 							   struct radeon_ps *radeon_current_state)
57677ccd5a2cSjsg {
57687ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
57697ccd5a2cSjsg 	enum radeon_pcie_gen target_link_speed = si_get_maximum_link_speed(rdev, radeon_new_state);
57707ccd5a2cSjsg 	u8 request;
57717ccd5a2cSjsg 
57727ccd5a2cSjsg 	if (si_pi->pspp_notify_required) {
57737ccd5a2cSjsg 		if (target_link_speed == RADEON_PCIE_GEN3)
57747ccd5a2cSjsg 			request = PCIE_PERF_REQ_PECI_GEN3;
57757ccd5a2cSjsg 		else if (target_link_speed == RADEON_PCIE_GEN2)
57767ccd5a2cSjsg 			request = PCIE_PERF_REQ_PECI_GEN2;
57777ccd5a2cSjsg 		else
57787ccd5a2cSjsg 			request = PCIE_PERF_REQ_PECI_GEN1;
57797ccd5a2cSjsg 
57807ccd5a2cSjsg 		if ((request == PCIE_PERF_REQ_PECI_GEN1) &&
57817ccd5a2cSjsg 		    (si_get_current_pcie_speed(rdev) > 0))
57827ccd5a2cSjsg 			return;
57837ccd5a2cSjsg 
57847ccd5a2cSjsg #if defined(CONFIG_ACPI)
57857ccd5a2cSjsg 		radeon_acpi_pcie_performance_request(rdev, request, false);
57867ccd5a2cSjsg #endif
57877ccd5a2cSjsg 	}
57887ccd5a2cSjsg }
57897ccd5a2cSjsg 
57907ccd5a2cSjsg #if 0
57917ccd5a2cSjsg static int si_ds_request(struct radeon_device *rdev,
57927ccd5a2cSjsg 			 bool ds_status_on, u32 count_write)
57937ccd5a2cSjsg {
57947ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
57957ccd5a2cSjsg 
57967ccd5a2cSjsg 	if (eg_pi->sclk_deep_sleep) {
57977ccd5a2cSjsg 		if (ds_status_on)
57987ccd5a2cSjsg 			return (si_send_msg_to_smc(rdev, PPSMC_MSG_CancelThrottleOVRDSCLKDS) ==
57997ccd5a2cSjsg 				PPSMC_Result_OK) ?
58007ccd5a2cSjsg 				0 : -EINVAL;
58017ccd5a2cSjsg 		else
58027ccd5a2cSjsg 			return (si_send_msg_to_smc(rdev, PPSMC_MSG_ThrottleOVRDSCLKDS) ==
58037ccd5a2cSjsg 				PPSMC_Result_OK) ? 0 : -EINVAL;
58047ccd5a2cSjsg 	}
58057ccd5a2cSjsg 	return 0;
58067ccd5a2cSjsg }
58077ccd5a2cSjsg #endif
58087ccd5a2cSjsg 
si_set_max_cu_value(struct radeon_device * rdev)58097ccd5a2cSjsg static void si_set_max_cu_value(struct radeon_device *rdev)
58107ccd5a2cSjsg {
58117ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
58127ccd5a2cSjsg 
58137ccd5a2cSjsg 	if (rdev->family == CHIP_VERDE) {
58147ccd5a2cSjsg 		switch (rdev->pdev->device) {
58157ccd5a2cSjsg 		case 0x6820:
58167ccd5a2cSjsg 		case 0x6825:
58177ccd5a2cSjsg 		case 0x6821:
58187ccd5a2cSjsg 		case 0x6823:
58197ccd5a2cSjsg 		case 0x6827:
58207ccd5a2cSjsg 			si_pi->max_cu = 10;
58217ccd5a2cSjsg 			break;
58227ccd5a2cSjsg 		case 0x682D:
58237ccd5a2cSjsg 		case 0x6824:
58247ccd5a2cSjsg 		case 0x682F:
58257ccd5a2cSjsg 		case 0x6826:
58267ccd5a2cSjsg 			si_pi->max_cu = 8;
58277ccd5a2cSjsg 			break;
58287ccd5a2cSjsg 		case 0x6828:
58297ccd5a2cSjsg 		case 0x6830:
58307ccd5a2cSjsg 		case 0x6831:
58317ccd5a2cSjsg 		case 0x6838:
58327ccd5a2cSjsg 		case 0x6839:
58337ccd5a2cSjsg 		case 0x683D:
58347ccd5a2cSjsg 			si_pi->max_cu = 10;
58357ccd5a2cSjsg 			break;
58367ccd5a2cSjsg 		case 0x683B:
58377ccd5a2cSjsg 		case 0x683F:
58387ccd5a2cSjsg 		case 0x6829:
58397ccd5a2cSjsg 			si_pi->max_cu = 8;
58407ccd5a2cSjsg 			break;
58417ccd5a2cSjsg 		default:
58427ccd5a2cSjsg 			si_pi->max_cu = 0;
58437ccd5a2cSjsg 			break;
58447ccd5a2cSjsg 		}
58457ccd5a2cSjsg 	} else {
58467ccd5a2cSjsg 		si_pi->max_cu = 0;
58477ccd5a2cSjsg 	}
58487ccd5a2cSjsg }
58497ccd5a2cSjsg 
si_patch_single_dependency_table_based_on_leakage(struct radeon_device * rdev,struct radeon_clock_voltage_dependency_table * table)58507ccd5a2cSjsg static int si_patch_single_dependency_table_based_on_leakage(struct radeon_device *rdev,
58517ccd5a2cSjsg 							     struct radeon_clock_voltage_dependency_table *table)
58527ccd5a2cSjsg {
58537ccd5a2cSjsg 	u32 i;
58547ccd5a2cSjsg 	int j;
58557ccd5a2cSjsg 	u16 leakage_voltage;
58567ccd5a2cSjsg 
58577ccd5a2cSjsg 	if (table) {
58587ccd5a2cSjsg 		for (i = 0; i < table->count; i++) {
58597ccd5a2cSjsg 			switch (si_get_leakage_voltage_from_leakage_index(rdev,
58607ccd5a2cSjsg 									  table->entries[i].v,
58617ccd5a2cSjsg 									  &leakage_voltage)) {
58627ccd5a2cSjsg 			case 0:
58637ccd5a2cSjsg 				table->entries[i].v = leakage_voltage;
58647ccd5a2cSjsg 				break;
58657ccd5a2cSjsg 			case -EAGAIN:
58667ccd5a2cSjsg 				return -EINVAL;
58677ccd5a2cSjsg 			case -EINVAL:
58687ccd5a2cSjsg 			default:
58697ccd5a2cSjsg 				break;
58707ccd5a2cSjsg 			}
58717ccd5a2cSjsg 		}
58727ccd5a2cSjsg 
58737ccd5a2cSjsg 		for (j = (table->count - 2); j >= 0; j--) {
58747ccd5a2cSjsg 			table->entries[j].v = (table->entries[j].v <= table->entries[j + 1].v) ?
58757ccd5a2cSjsg 				table->entries[j].v : table->entries[j + 1].v;
58767ccd5a2cSjsg 		}
58777ccd5a2cSjsg 	}
58787ccd5a2cSjsg 	return 0;
58797ccd5a2cSjsg }
58807ccd5a2cSjsg 
si_patch_dependency_tables_based_on_leakage(struct radeon_device * rdev)58817ccd5a2cSjsg static int si_patch_dependency_tables_based_on_leakage(struct radeon_device *rdev)
58827ccd5a2cSjsg {
5883c349dbc7Sjsg 	int ret;
58847ccd5a2cSjsg 
58857ccd5a2cSjsg 	ret = si_patch_single_dependency_table_based_on_leakage(rdev,
58867ccd5a2cSjsg 								&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk);
58877ccd5a2cSjsg 	ret = si_patch_single_dependency_table_based_on_leakage(rdev,
58887ccd5a2cSjsg 								&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk);
58897ccd5a2cSjsg 	ret = si_patch_single_dependency_table_based_on_leakage(rdev,
58907ccd5a2cSjsg 								&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk);
58917ccd5a2cSjsg 	return ret;
58927ccd5a2cSjsg }
58937ccd5a2cSjsg 
si_set_pcie_lane_width_in_smc(struct radeon_device * rdev,struct radeon_ps * radeon_new_state,struct radeon_ps * radeon_current_state)58947ccd5a2cSjsg static void si_set_pcie_lane_width_in_smc(struct radeon_device *rdev,
58957ccd5a2cSjsg 					  struct radeon_ps *radeon_new_state,
58967ccd5a2cSjsg 					  struct radeon_ps *radeon_current_state)
58977ccd5a2cSjsg {
58987ccd5a2cSjsg 	u32 lane_width;
58997ccd5a2cSjsg 	u32 new_lane_width =
59007ccd5a2cSjsg 		((radeon_new_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
59017ccd5a2cSjsg 	u32 current_lane_width =
59027ccd5a2cSjsg 		((radeon_current_state->caps & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1;
59037ccd5a2cSjsg 
59047ccd5a2cSjsg 	if (new_lane_width != current_lane_width) {
59057ccd5a2cSjsg 		radeon_set_pcie_lanes(rdev, new_lane_width);
59067ccd5a2cSjsg 		lane_width = radeon_get_pcie_lanes(rdev);
59077ccd5a2cSjsg 		si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_non_ulv_pcie_link_width, lane_width);
59087ccd5a2cSjsg 	}
59097ccd5a2cSjsg }
59107ccd5a2cSjsg 
si_set_vce_clock(struct radeon_device * rdev,struct radeon_ps * new_rps,struct radeon_ps * old_rps)59117ccd5a2cSjsg static void si_set_vce_clock(struct radeon_device *rdev,
59127ccd5a2cSjsg 			     struct radeon_ps *new_rps,
59137ccd5a2cSjsg 			     struct radeon_ps *old_rps)
59147ccd5a2cSjsg {
59157ccd5a2cSjsg 	if ((old_rps->evclk != new_rps->evclk) ||
59167ccd5a2cSjsg 	    (old_rps->ecclk != new_rps->ecclk)) {
59177ccd5a2cSjsg 		/* turn the clocks on when encoding, off otherwise */
59187ccd5a2cSjsg 		if (new_rps->evclk || new_rps->ecclk)
59197ccd5a2cSjsg 			vce_v1_0_enable_mgcg(rdev, false);
59207ccd5a2cSjsg 		else
59217ccd5a2cSjsg 			vce_v1_0_enable_mgcg(rdev, true);
59227ccd5a2cSjsg 		radeon_set_vce_clocks(rdev, new_rps->evclk, new_rps->ecclk);
59237ccd5a2cSjsg 	}
59247ccd5a2cSjsg }
59257ccd5a2cSjsg 
si_dpm_setup_asic(struct radeon_device * rdev)59267ccd5a2cSjsg void si_dpm_setup_asic(struct radeon_device *rdev)
59277ccd5a2cSjsg {
59287ccd5a2cSjsg 	int r;
59297ccd5a2cSjsg 
59307ccd5a2cSjsg 	r = si_mc_load_microcode(rdev);
59317ccd5a2cSjsg 	if (r)
59327ccd5a2cSjsg 		DRM_ERROR("Failed to load MC firmware!\n");
59337ccd5a2cSjsg 	rv770_get_memory_type(rdev);
59347ccd5a2cSjsg 	si_read_clock_registers(rdev);
59357ccd5a2cSjsg 	si_enable_acpi_power_management(rdev);
59367ccd5a2cSjsg }
59377ccd5a2cSjsg 
si_thermal_enable_alert(struct radeon_device * rdev,bool enable)59387ccd5a2cSjsg static int si_thermal_enable_alert(struct radeon_device *rdev,
59397ccd5a2cSjsg 				   bool enable)
59407ccd5a2cSjsg {
59417ccd5a2cSjsg 	u32 thermal_int = RREG32(CG_THERMAL_INT);
59427ccd5a2cSjsg 
59437ccd5a2cSjsg 	if (enable) {
59447ccd5a2cSjsg 		PPSMC_Result result;
59457ccd5a2cSjsg 
59467ccd5a2cSjsg 		thermal_int &= ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
59477ccd5a2cSjsg 		WREG32(CG_THERMAL_INT, thermal_int);
59487ccd5a2cSjsg 		rdev->irq.dpm_thermal = false;
59497ccd5a2cSjsg 		result = si_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
59507ccd5a2cSjsg 		if (result != PPSMC_Result_OK) {
59517ccd5a2cSjsg 			DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
59527ccd5a2cSjsg 			return -EINVAL;
59537ccd5a2cSjsg 		}
59547ccd5a2cSjsg 	} else {
59557ccd5a2cSjsg 		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
59567ccd5a2cSjsg 		WREG32(CG_THERMAL_INT, thermal_int);
59577ccd5a2cSjsg 		rdev->irq.dpm_thermal = true;
59587ccd5a2cSjsg 	}
59597ccd5a2cSjsg 
59607ccd5a2cSjsg 	return 0;
59617ccd5a2cSjsg }
59627ccd5a2cSjsg 
si_thermal_set_temperature_range(struct radeon_device * rdev,int min_temp,int max_temp)59637ccd5a2cSjsg static int si_thermal_set_temperature_range(struct radeon_device *rdev,
59647ccd5a2cSjsg 					    int min_temp, int max_temp)
59657ccd5a2cSjsg {
59667ccd5a2cSjsg 	int low_temp = 0 * 1000;
59677ccd5a2cSjsg 	int high_temp = 255 * 1000;
59687ccd5a2cSjsg 
59697ccd5a2cSjsg 	if (low_temp < min_temp)
59707ccd5a2cSjsg 		low_temp = min_temp;
59717ccd5a2cSjsg 	if (high_temp > max_temp)
59727ccd5a2cSjsg 		high_temp = max_temp;
59737ccd5a2cSjsg 	if (high_temp < low_temp) {
59747ccd5a2cSjsg 		DRM_ERROR("invalid thermal range: %d - %d\n", low_temp, high_temp);
59757ccd5a2cSjsg 		return -EINVAL;
59767ccd5a2cSjsg 	}
59777ccd5a2cSjsg 
59787ccd5a2cSjsg 	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTH(high_temp / 1000), ~DIG_THERM_INTH_MASK);
59797ccd5a2cSjsg 	WREG32_P(CG_THERMAL_INT, DIG_THERM_INTL(low_temp / 1000), ~DIG_THERM_INTL_MASK);
59807ccd5a2cSjsg 	WREG32_P(CG_THERMAL_CTRL, DIG_THERM_DPM(high_temp / 1000), ~DIG_THERM_DPM_MASK);
59817ccd5a2cSjsg 
59827ccd5a2cSjsg 	rdev->pm.dpm.thermal.min_temp = low_temp;
59837ccd5a2cSjsg 	rdev->pm.dpm.thermal.max_temp = high_temp;
59847ccd5a2cSjsg 
59857ccd5a2cSjsg 	return 0;
59867ccd5a2cSjsg }
59877ccd5a2cSjsg 
si_fan_ctrl_set_static_mode(struct radeon_device * rdev,u32 mode)59887ccd5a2cSjsg static void si_fan_ctrl_set_static_mode(struct radeon_device *rdev, u32 mode)
59897ccd5a2cSjsg {
59907ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
59917ccd5a2cSjsg 	u32 tmp;
59927ccd5a2cSjsg 
59937ccd5a2cSjsg 	if (si_pi->fan_ctrl_is_in_default_mode) {
59947ccd5a2cSjsg 		tmp = (RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK) >> FDO_PWM_MODE_SHIFT;
59957ccd5a2cSjsg 		si_pi->fan_ctrl_default_mode = tmp;
59967ccd5a2cSjsg 		tmp = (RREG32(CG_FDO_CTRL2) & TMIN_MASK) >> TMIN_SHIFT;
59977ccd5a2cSjsg 		si_pi->t_min = tmp;
59987ccd5a2cSjsg 		si_pi->fan_ctrl_is_in_default_mode = false;
59997ccd5a2cSjsg 	}
60007ccd5a2cSjsg 
60017ccd5a2cSjsg 	tmp = RREG32(CG_FDO_CTRL2) & ~TMIN_MASK;
60027ccd5a2cSjsg 	tmp |= TMIN(0);
60037ccd5a2cSjsg 	WREG32(CG_FDO_CTRL2, tmp);
60047ccd5a2cSjsg 
60057ccd5a2cSjsg 	tmp = RREG32(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK;
60067ccd5a2cSjsg 	tmp |= FDO_PWM_MODE(mode);
60077ccd5a2cSjsg 	WREG32(CG_FDO_CTRL2, tmp);
60087ccd5a2cSjsg }
60097ccd5a2cSjsg 
si_thermal_setup_fan_table(struct radeon_device * rdev)60107ccd5a2cSjsg static int si_thermal_setup_fan_table(struct radeon_device *rdev)
60117ccd5a2cSjsg {
60127ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
60137ccd5a2cSjsg 	PP_SIslands_FanTable fan_table = { FDO_MODE_HARDWARE };
60147ccd5a2cSjsg 	u32 duty100;
60157ccd5a2cSjsg 	u32 t_diff1, t_diff2, pwm_diff1, pwm_diff2;
60167ccd5a2cSjsg 	u16 fdo_min, slope1, slope2;
60177ccd5a2cSjsg 	u32 reference_clock, tmp;
60187ccd5a2cSjsg 	int ret;
60197ccd5a2cSjsg 	u64 tmp64;
60207ccd5a2cSjsg 
60217ccd5a2cSjsg 	if (!si_pi->fan_table_start) {
60227ccd5a2cSjsg 		rdev->pm.dpm.fan.ucode_fan_control = false;
60237ccd5a2cSjsg 		return 0;
60247ccd5a2cSjsg 	}
60257ccd5a2cSjsg 
60267ccd5a2cSjsg 	duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
60277ccd5a2cSjsg 
60287ccd5a2cSjsg 	if (duty100 == 0) {
60297ccd5a2cSjsg 		rdev->pm.dpm.fan.ucode_fan_control = false;
60307ccd5a2cSjsg 		return 0;
60317ccd5a2cSjsg 	}
60327ccd5a2cSjsg 
60337ccd5a2cSjsg 	tmp64 = (u64)rdev->pm.dpm.fan.pwm_min * duty100;
60347ccd5a2cSjsg 	do_div(tmp64, 10000);
60357ccd5a2cSjsg 	fdo_min = (u16)tmp64;
60367ccd5a2cSjsg 
60377ccd5a2cSjsg 	t_diff1 = rdev->pm.dpm.fan.t_med - rdev->pm.dpm.fan.t_min;
60387ccd5a2cSjsg 	t_diff2 = rdev->pm.dpm.fan.t_high - rdev->pm.dpm.fan.t_med;
60397ccd5a2cSjsg 
60407ccd5a2cSjsg 	pwm_diff1 = rdev->pm.dpm.fan.pwm_med - rdev->pm.dpm.fan.pwm_min;
60417ccd5a2cSjsg 	pwm_diff2 = rdev->pm.dpm.fan.pwm_high - rdev->pm.dpm.fan.pwm_med;
60427ccd5a2cSjsg 
60437ccd5a2cSjsg 	slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100);
60447ccd5a2cSjsg 	slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100);
60457ccd5a2cSjsg 
60467ccd5a2cSjsg 	fan_table.temp_min = cpu_to_be16((50 + rdev->pm.dpm.fan.t_min) / 100);
60477ccd5a2cSjsg 	fan_table.temp_med = cpu_to_be16((50 + rdev->pm.dpm.fan.t_med) / 100);
60487ccd5a2cSjsg 	fan_table.temp_max = cpu_to_be16((50 + rdev->pm.dpm.fan.t_max) / 100);
60497ccd5a2cSjsg 
60507ccd5a2cSjsg 	fan_table.slope1 = cpu_to_be16(slope1);
60517ccd5a2cSjsg 	fan_table.slope2 = cpu_to_be16(slope2);
60527ccd5a2cSjsg 
60537ccd5a2cSjsg 	fan_table.fdo_min = cpu_to_be16(fdo_min);
60547ccd5a2cSjsg 
60557ccd5a2cSjsg 	fan_table.hys_down = cpu_to_be16(rdev->pm.dpm.fan.t_hyst);
60567ccd5a2cSjsg 
60577ccd5a2cSjsg 	fan_table.hys_up = cpu_to_be16(1);
60587ccd5a2cSjsg 
60597ccd5a2cSjsg 	fan_table.hys_slope = cpu_to_be16(1);
60607ccd5a2cSjsg 
60617ccd5a2cSjsg 	fan_table.temp_resp_lim = cpu_to_be16(5);
60627ccd5a2cSjsg 
60637ccd5a2cSjsg 	reference_clock = radeon_get_xclk(rdev);
60647ccd5a2cSjsg 
60657ccd5a2cSjsg 	fan_table.refresh_period = cpu_to_be32((rdev->pm.dpm.fan.cycle_delay *
60667ccd5a2cSjsg 						reference_clock) / 1600);
60677ccd5a2cSjsg 
60687ccd5a2cSjsg 	fan_table.fdo_max = cpu_to_be16((u16)duty100);
60697ccd5a2cSjsg 
60707ccd5a2cSjsg 	tmp = (RREG32(CG_MULT_THERMAL_CTRL) & TEMP_SEL_MASK) >> TEMP_SEL_SHIFT;
60717ccd5a2cSjsg 	fan_table.temp_src = (uint8_t)tmp;
60727ccd5a2cSjsg 
60737ccd5a2cSjsg 	ret = si_copy_bytes_to_smc(rdev,
60747ccd5a2cSjsg 				   si_pi->fan_table_start,
60757ccd5a2cSjsg 				   (u8 *)(&fan_table),
60767ccd5a2cSjsg 				   sizeof(fan_table),
60777ccd5a2cSjsg 				   si_pi->sram_end);
60787ccd5a2cSjsg 
60797ccd5a2cSjsg 	if (ret) {
60807ccd5a2cSjsg 		DRM_ERROR("Failed to load fan table to the SMC.");
60817ccd5a2cSjsg 		rdev->pm.dpm.fan.ucode_fan_control = false;
60827ccd5a2cSjsg 	}
60837ccd5a2cSjsg 
60847ccd5a2cSjsg 	return 0;
60857ccd5a2cSjsg }
60867ccd5a2cSjsg 
si_fan_ctrl_start_smc_fan_control(struct radeon_device * rdev)60877ccd5a2cSjsg static int si_fan_ctrl_start_smc_fan_control(struct radeon_device *rdev)
60887ccd5a2cSjsg {
60897ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
60907ccd5a2cSjsg 	PPSMC_Result ret;
60917ccd5a2cSjsg 
60927ccd5a2cSjsg 	ret = si_send_msg_to_smc(rdev, PPSMC_StartFanControl);
60937ccd5a2cSjsg 	if (ret == PPSMC_Result_OK) {
60947ccd5a2cSjsg 		si_pi->fan_is_controlled_by_smc = true;
60957ccd5a2cSjsg 		return 0;
60967ccd5a2cSjsg 	} else {
60977ccd5a2cSjsg 		return -EINVAL;
60987ccd5a2cSjsg 	}
60997ccd5a2cSjsg }
61007ccd5a2cSjsg 
si_fan_ctrl_stop_smc_fan_control(struct radeon_device * rdev)61017ccd5a2cSjsg static int si_fan_ctrl_stop_smc_fan_control(struct radeon_device *rdev)
61027ccd5a2cSjsg {
61037ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
61047ccd5a2cSjsg 	PPSMC_Result ret;
61057ccd5a2cSjsg 
61067ccd5a2cSjsg 	ret = si_send_msg_to_smc(rdev, PPSMC_StopFanControl);
61077ccd5a2cSjsg 
61087ccd5a2cSjsg 	if (ret == PPSMC_Result_OK) {
61097ccd5a2cSjsg 		si_pi->fan_is_controlled_by_smc = false;
61107ccd5a2cSjsg 		return 0;
61117ccd5a2cSjsg 	} else {
61127ccd5a2cSjsg 		return -EINVAL;
61137ccd5a2cSjsg 	}
61147ccd5a2cSjsg }
61157ccd5a2cSjsg 
si_fan_ctrl_get_fan_speed_percent(struct radeon_device * rdev,u32 * speed)61167ccd5a2cSjsg int si_fan_ctrl_get_fan_speed_percent(struct radeon_device *rdev,
61177ccd5a2cSjsg 				      u32 *speed)
61187ccd5a2cSjsg {
61197ccd5a2cSjsg 	u32 duty, duty100;
61207ccd5a2cSjsg 	u64 tmp64;
61217ccd5a2cSjsg 
61227ccd5a2cSjsg 	if (rdev->pm.no_fan)
61237ccd5a2cSjsg 		return -ENOENT;
61247ccd5a2cSjsg 
61257ccd5a2cSjsg 	duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
61267ccd5a2cSjsg 	duty = (RREG32(CG_THERMAL_STATUS) & FDO_PWM_DUTY_MASK) >> FDO_PWM_DUTY_SHIFT;
61277ccd5a2cSjsg 
61287ccd5a2cSjsg 	if (duty100 == 0)
61297ccd5a2cSjsg 		return -EINVAL;
61307ccd5a2cSjsg 
61317ccd5a2cSjsg 	tmp64 = (u64)duty * 100;
61327ccd5a2cSjsg 	do_div(tmp64, duty100);
61337ccd5a2cSjsg 	*speed = (u32)tmp64;
61347ccd5a2cSjsg 
61357ccd5a2cSjsg 	if (*speed > 100)
61367ccd5a2cSjsg 		*speed = 100;
61377ccd5a2cSjsg 
61387ccd5a2cSjsg 	return 0;
61397ccd5a2cSjsg }
61407ccd5a2cSjsg 
si_fan_ctrl_set_fan_speed_percent(struct radeon_device * rdev,u32 speed)61417ccd5a2cSjsg int si_fan_ctrl_set_fan_speed_percent(struct radeon_device *rdev,
61427ccd5a2cSjsg 				      u32 speed)
61437ccd5a2cSjsg {
61447ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
61457ccd5a2cSjsg 	u32 tmp;
61467ccd5a2cSjsg 	u32 duty, duty100;
61477ccd5a2cSjsg 	u64 tmp64;
61487ccd5a2cSjsg 
61497ccd5a2cSjsg 	if (rdev->pm.no_fan)
61507ccd5a2cSjsg 		return -ENOENT;
61517ccd5a2cSjsg 
61527ccd5a2cSjsg 	if (si_pi->fan_is_controlled_by_smc)
61537ccd5a2cSjsg 		return -EINVAL;
61547ccd5a2cSjsg 
61557ccd5a2cSjsg 	if (speed > 100)
61567ccd5a2cSjsg 		return -EINVAL;
61577ccd5a2cSjsg 
61587ccd5a2cSjsg 	duty100 = (RREG32(CG_FDO_CTRL1) & FMAX_DUTY100_MASK) >> FMAX_DUTY100_SHIFT;
61597ccd5a2cSjsg 
61607ccd5a2cSjsg 	if (duty100 == 0)
61617ccd5a2cSjsg 		return -EINVAL;
61627ccd5a2cSjsg 
61637ccd5a2cSjsg 	tmp64 = (u64)speed * duty100;
61647ccd5a2cSjsg 	do_div(tmp64, 100);
61657ccd5a2cSjsg 	duty = (u32)tmp64;
61667ccd5a2cSjsg 
61677ccd5a2cSjsg 	tmp = RREG32(CG_FDO_CTRL0) & ~FDO_STATIC_DUTY_MASK;
61687ccd5a2cSjsg 	tmp |= FDO_STATIC_DUTY(duty);
61697ccd5a2cSjsg 	WREG32(CG_FDO_CTRL0, tmp);
61707ccd5a2cSjsg 
61717ccd5a2cSjsg 	return 0;
61727ccd5a2cSjsg }
61737ccd5a2cSjsg 
si_fan_ctrl_set_mode(struct radeon_device * rdev,u32 mode)61747ccd5a2cSjsg void si_fan_ctrl_set_mode(struct radeon_device *rdev, u32 mode)
61757ccd5a2cSjsg {
61767ccd5a2cSjsg 	if (mode) {
61777ccd5a2cSjsg 		/* stop auto-manage */
61787ccd5a2cSjsg 		if (rdev->pm.dpm.fan.ucode_fan_control)
61797ccd5a2cSjsg 			si_fan_ctrl_stop_smc_fan_control(rdev);
61807ccd5a2cSjsg 		si_fan_ctrl_set_static_mode(rdev, mode);
61817ccd5a2cSjsg 	} else {
61827ccd5a2cSjsg 		/* restart auto-manage */
61837ccd5a2cSjsg 		if (rdev->pm.dpm.fan.ucode_fan_control)
61847ccd5a2cSjsg 			si_thermal_start_smc_fan_control(rdev);
61857ccd5a2cSjsg 		else
61867ccd5a2cSjsg 			si_fan_ctrl_set_default_mode(rdev);
61877ccd5a2cSjsg 	}
61887ccd5a2cSjsg }
61897ccd5a2cSjsg 
si_fan_ctrl_get_mode(struct radeon_device * rdev)61907ccd5a2cSjsg u32 si_fan_ctrl_get_mode(struct radeon_device *rdev)
61917ccd5a2cSjsg {
61927ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
61937ccd5a2cSjsg 	u32 tmp;
61947ccd5a2cSjsg 
61957ccd5a2cSjsg 	if (si_pi->fan_is_controlled_by_smc)
61967ccd5a2cSjsg 		return 0;
61977ccd5a2cSjsg 
61987ccd5a2cSjsg 	tmp = RREG32(CG_FDO_CTRL2) & FDO_PWM_MODE_MASK;
61997ccd5a2cSjsg 	return (tmp >> FDO_PWM_MODE_SHIFT);
62007ccd5a2cSjsg }
62017ccd5a2cSjsg 
62027ccd5a2cSjsg #if 0
62037ccd5a2cSjsg static int si_fan_ctrl_get_fan_speed_rpm(struct radeon_device *rdev,
62047ccd5a2cSjsg 					 u32 *speed)
62057ccd5a2cSjsg {
62067ccd5a2cSjsg 	u32 tach_period;
62077ccd5a2cSjsg 	u32 xclk = radeon_get_xclk(rdev);
62087ccd5a2cSjsg 
62097ccd5a2cSjsg 	if (rdev->pm.no_fan)
62107ccd5a2cSjsg 		return -ENOENT;
62117ccd5a2cSjsg 
62127ccd5a2cSjsg 	if (rdev->pm.fan_pulses_per_revolution == 0)
62137ccd5a2cSjsg 		return -ENOENT;
62147ccd5a2cSjsg 
62157ccd5a2cSjsg 	tach_period = (RREG32(CG_TACH_STATUS) & TACH_PERIOD_MASK) >> TACH_PERIOD_SHIFT;
62167ccd5a2cSjsg 	if (tach_period == 0)
62177ccd5a2cSjsg 		return -ENOENT;
62187ccd5a2cSjsg 
62197ccd5a2cSjsg 	*speed = 60 * xclk * 10000 / tach_period;
62207ccd5a2cSjsg 
62217ccd5a2cSjsg 	return 0;
62227ccd5a2cSjsg }
62237ccd5a2cSjsg 
62247ccd5a2cSjsg static int si_fan_ctrl_set_fan_speed_rpm(struct radeon_device *rdev,
62257ccd5a2cSjsg 					 u32 speed)
62267ccd5a2cSjsg {
62277ccd5a2cSjsg 	u32 tach_period, tmp;
62287ccd5a2cSjsg 	u32 xclk = radeon_get_xclk(rdev);
62297ccd5a2cSjsg 
62307ccd5a2cSjsg 	if (rdev->pm.no_fan)
62317ccd5a2cSjsg 		return -ENOENT;
62327ccd5a2cSjsg 
62337ccd5a2cSjsg 	if (rdev->pm.fan_pulses_per_revolution == 0)
62347ccd5a2cSjsg 		return -ENOENT;
62357ccd5a2cSjsg 
62367ccd5a2cSjsg 	if ((speed < rdev->pm.fan_min_rpm) ||
62377ccd5a2cSjsg 	    (speed > rdev->pm.fan_max_rpm))
62387ccd5a2cSjsg 		return -EINVAL;
62397ccd5a2cSjsg 
62407ccd5a2cSjsg 	if (rdev->pm.dpm.fan.ucode_fan_control)
62417ccd5a2cSjsg 		si_fan_ctrl_stop_smc_fan_control(rdev);
62427ccd5a2cSjsg 
62437ccd5a2cSjsg 	tach_period = 60 * xclk * 10000 / (8 * speed);
62447ccd5a2cSjsg 	tmp = RREG32(CG_TACH_CTRL) & ~TARGET_PERIOD_MASK;
62457ccd5a2cSjsg 	tmp |= TARGET_PERIOD(tach_period);
62467ccd5a2cSjsg 	WREG32(CG_TACH_CTRL, tmp);
62477ccd5a2cSjsg 
62487ccd5a2cSjsg 	si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC_RPM);
62497ccd5a2cSjsg 
62507ccd5a2cSjsg 	return 0;
62517ccd5a2cSjsg }
62527ccd5a2cSjsg #endif
62537ccd5a2cSjsg 
si_fan_ctrl_set_default_mode(struct radeon_device * rdev)62547ccd5a2cSjsg static void si_fan_ctrl_set_default_mode(struct radeon_device *rdev)
62557ccd5a2cSjsg {
62567ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
62577ccd5a2cSjsg 	u32 tmp;
62587ccd5a2cSjsg 
62597ccd5a2cSjsg 	if (!si_pi->fan_ctrl_is_in_default_mode) {
62607ccd5a2cSjsg 		tmp = RREG32(CG_FDO_CTRL2) & ~FDO_PWM_MODE_MASK;
62617ccd5a2cSjsg 		tmp |= FDO_PWM_MODE(si_pi->fan_ctrl_default_mode);
62627ccd5a2cSjsg 		WREG32(CG_FDO_CTRL2, tmp);
62637ccd5a2cSjsg 
62647ccd5a2cSjsg 		tmp = RREG32(CG_FDO_CTRL2) & ~TMIN_MASK;
62657ccd5a2cSjsg 		tmp |= TMIN(si_pi->t_min);
62667ccd5a2cSjsg 		WREG32(CG_FDO_CTRL2, tmp);
62677ccd5a2cSjsg 		si_pi->fan_ctrl_is_in_default_mode = true;
62687ccd5a2cSjsg 	}
62697ccd5a2cSjsg }
62707ccd5a2cSjsg 
si_thermal_start_smc_fan_control(struct radeon_device * rdev)62717ccd5a2cSjsg static void si_thermal_start_smc_fan_control(struct radeon_device *rdev)
62727ccd5a2cSjsg {
62737ccd5a2cSjsg 	if (rdev->pm.dpm.fan.ucode_fan_control) {
62747ccd5a2cSjsg 		si_fan_ctrl_start_smc_fan_control(rdev);
62757ccd5a2cSjsg 		si_fan_ctrl_set_static_mode(rdev, FDO_PWM_MODE_STATIC);
62767ccd5a2cSjsg 	}
62777ccd5a2cSjsg }
62787ccd5a2cSjsg 
si_thermal_initialize(struct radeon_device * rdev)62797ccd5a2cSjsg static void si_thermal_initialize(struct radeon_device *rdev)
62807ccd5a2cSjsg {
62817ccd5a2cSjsg 	u32 tmp;
62827ccd5a2cSjsg 
62837ccd5a2cSjsg 	if (rdev->pm.fan_pulses_per_revolution) {
62847ccd5a2cSjsg 		tmp = RREG32(CG_TACH_CTRL) & ~EDGE_PER_REV_MASK;
62857ccd5a2cSjsg 		tmp |= EDGE_PER_REV(rdev->pm.fan_pulses_per_revolution -1);
62867ccd5a2cSjsg 		WREG32(CG_TACH_CTRL, tmp);
62877ccd5a2cSjsg 	}
62887ccd5a2cSjsg 
62897ccd5a2cSjsg 	tmp = RREG32(CG_FDO_CTRL2) & ~TACH_PWM_RESP_RATE_MASK;
62907ccd5a2cSjsg 	tmp |= TACH_PWM_RESP_RATE(0x28);
62917ccd5a2cSjsg 	WREG32(CG_FDO_CTRL2, tmp);
62927ccd5a2cSjsg }
62937ccd5a2cSjsg 
si_thermal_start_thermal_controller(struct radeon_device * rdev)62947ccd5a2cSjsg static int si_thermal_start_thermal_controller(struct radeon_device *rdev)
62957ccd5a2cSjsg {
62967ccd5a2cSjsg 	int ret;
62977ccd5a2cSjsg 
62987ccd5a2cSjsg 	si_thermal_initialize(rdev);
62997ccd5a2cSjsg 	ret = si_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
63007ccd5a2cSjsg 	if (ret)
63017ccd5a2cSjsg 		return ret;
63027ccd5a2cSjsg 	ret = si_thermal_enable_alert(rdev, true);
63037ccd5a2cSjsg 	if (ret)
63047ccd5a2cSjsg 		return ret;
63057ccd5a2cSjsg 	if (rdev->pm.dpm.fan.ucode_fan_control) {
63067ccd5a2cSjsg 		ret = si_halt_smc(rdev);
63077ccd5a2cSjsg 		if (ret)
63087ccd5a2cSjsg 			return ret;
63097ccd5a2cSjsg 		ret = si_thermal_setup_fan_table(rdev);
63107ccd5a2cSjsg 		if (ret)
63117ccd5a2cSjsg 			return ret;
63127ccd5a2cSjsg 		ret = si_resume_smc(rdev);
63137ccd5a2cSjsg 		if (ret)
63147ccd5a2cSjsg 			return ret;
63157ccd5a2cSjsg 		si_thermal_start_smc_fan_control(rdev);
63167ccd5a2cSjsg 	}
63177ccd5a2cSjsg 
63187ccd5a2cSjsg 	return 0;
63197ccd5a2cSjsg }
63207ccd5a2cSjsg 
si_thermal_stop_thermal_controller(struct radeon_device * rdev)63217ccd5a2cSjsg static void si_thermal_stop_thermal_controller(struct radeon_device *rdev)
63227ccd5a2cSjsg {
63237ccd5a2cSjsg 	if (!rdev->pm.no_fan) {
63247ccd5a2cSjsg 		si_fan_ctrl_set_default_mode(rdev);
63257ccd5a2cSjsg 		si_fan_ctrl_stop_smc_fan_control(rdev);
63267ccd5a2cSjsg 	}
63277ccd5a2cSjsg }
63287ccd5a2cSjsg 
si_dpm_enable(struct radeon_device * rdev)63297ccd5a2cSjsg int si_dpm_enable(struct radeon_device *rdev)
63307ccd5a2cSjsg {
63317ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
63327ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
63337ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
63347ccd5a2cSjsg 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
63357ccd5a2cSjsg 	int ret;
63367ccd5a2cSjsg 
63377ccd5a2cSjsg 	if (si_is_smc_running(rdev))
63387ccd5a2cSjsg 		return -EINVAL;
63397ccd5a2cSjsg 	if (pi->voltage_control || si_pi->voltage_control_svi2)
63407ccd5a2cSjsg 		si_enable_voltage_control(rdev, true);
63417ccd5a2cSjsg 	if (pi->mvdd_control)
63427ccd5a2cSjsg 		si_get_mvdd_configuration(rdev);
63437ccd5a2cSjsg 	if (pi->voltage_control || si_pi->voltage_control_svi2) {
63447ccd5a2cSjsg 		ret = si_construct_voltage_tables(rdev);
63457ccd5a2cSjsg 		if (ret) {
63467ccd5a2cSjsg 			DRM_ERROR("si_construct_voltage_tables failed\n");
63477ccd5a2cSjsg 			return ret;
63487ccd5a2cSjsg 		}
63497ccd5a2cSjsg 	}
63507ccd5a2cSjsg 	if (eg_pi->dynamic_ac_timing) {
63517ccd5a2cSjsg 		ret = si_initialize_mc_reg_table(rdev);
63527ccd5a2cSjsg 		if (ret)
63537ccd5a2cSjsg 			eg_pi->dynamic_ac_timing = false;
63547ccd5a2cSjsg 	}
63557ccd5a2cSjsg 	if (pi->dynamic_ss)
63567ccd5a2cSjsg 		si_enable_spread_spectrum(rdev, true);
63577ccd5a2cSjsg 	if (pi->thermal_protection)
63587ccd5a2cSjsg 		si_enable_thermal_protection(rdev, true);
63597ccd5a2cSjsg 	si_setup_bsp(rdev);
63607ccd5a2cSjsg 	si_program_git(rdev);
63617ccd5a2cSjsg 	si_program_tp(rdev);
63627ccd5a2cSjsg 	si_program_tpp(rdev);
63637ccd5a2cSjsg 	si_program_sstp(rdev);
63647ccd5a2cSjsg 	si_enable_display_gap(rdev);
63657ccd5a2cSjsg 	si_program_vc(rdev);
63667ccd5a2cSjsg 	ret = si_upload_firmware(rdev);
63677ccd5a2cSjsg 	if (ret) {
63687ccd5a2cSjsg 		DRM_ERROR("si_upload_firmware failed\n");
63697ccd5a2cSjsg 		return ret;
63707ccd5a2cSjsg 	}
63717ccd5a2cSjsg 	ret = si_process_firmware_header(rdev);
63727ccd5a2cSjsg 	if (ret) {
63737ccd5a2cSjsg 		DRM_ERROR("si_process_firmware_header failed\n");
63747ccd5a2cSjsg 		return ret;
63757ccd5a2cSjsg 	}
63767ccd5a2cSjsg 	ret = si_initial_switch_from_arb_f0_to_f1(rdev);
63777ccd5a2cSjsg 	if (ret) {
63787ccd5a2cSjsg 		DRM_ERROR("si_initial_switch_from_arb_f0_to_f1 failed\n");
63797ccd5a2cSjsg 		return ret;
63807ccd5a2cSjsg 	}
63817ccd5a2cSjsg 	ret = si_init_smc_table(rdev);
63827ccd5a2cSjsg 	if (ret) {
63837ccd5a2cSjsg 		DRM_ERROR("si_init_smc_table failed\n");
63847ccd5a2cSjsg 		return ret;
63857ccd5a2cSjsg 	}
63867ccd5a2cSjsg 	ret = si_init_smc_spll_table(rdev);
63877ccd5a2cSjsg 	if (ret) {
63887ccd5a2cSjsg 		DRM_ERROR("si_init_smc_spll_table failed\n");
63897ccd5a2cSjsg 		return ret;
63907ccd5a2cSjsg 	}
63917ccd5a2cSjsg 	ret = si_init_arb_table_index(rdev);
63927ccd5a2cSjsg 	if (ret) {
63937ccd5a2cSjsg 		DRM_ERROR("si_init_arb_table_index failed\n");
63947ccd5a2cSjsg 		return ret;
63957ccd5a2cSjsg 	}
63967ccd5a2cSjsg 	if (eg_pi->dynamic_ac_timing) {
63977ccd5a2cSjsg 		ret = si_populate_mc_reg_table(rdev, boot_ps);
63987ccd5a2cSjsg 		if (ret) {
63997ccd5a2cSjsg 			DRM_ERROR("si_populate_mc_reg_table failed\n");
64007ccd5a2cSjsg 			return ret;
64017ccd5a2cSjsg 		}
64027ccd5a2cSjsg 	}
64037ccd5a2cSjsg 	ret = si_initialize_smc_cac_tables(rdev);
64047ccd5a2cSjsg 	if (ret) {
64057ccd5a2cSjsg 		DRM_ERROR("si_initialize_smc_cac_tables failed\n");
64067ccd5a2cSjsg 		return ret;
64077ccd5a2cSjsg 	}
64087ccd5a2cSjsg 	ret = si_initialize_hardware_cac_manager(rdev);
64097ccd5a2cSjsg 	if (ret) {
64107ccd5a2cSjsg 		DRM_ERROR("si_initialize_hardware_cac_manager failed\n");
64117ccd5a2cSjsg 		return ret;
64127ccd5a2cSjsg 	}
64137ccd5a2cSjsg 	ret = si_initialize_smc_dte_tables(rdev);
64147ccd5a2cSjsg 	if (ret) {
64157ccd5a2cSjsg 		DRM_ERROR("si_initialize_smc_dte_tables failed\n");
64167ccd5a2cSjsg 		return ret;
64177ccd5a2cSjsg 	}
64187ccd5a2cSjsg 	ret = si_populate_smc_tdp_limits(rdev, boot_ps);
64197ccd5a2cSjsg 	if (ret) {
64207ccd5a2cSjsg 		DRM_ERROR("si_populate_smc_tdp_limits failed\n");
64217ccd5a2cSjsg 		return ret;
64227ccd5a2cSjsg 	}
64237ccd5a2cSjsg 	ret = si_populate_smc_tdp_limits_2(rdev, boot_ps);
64247ccd5a2cSjsg 	if (ret) {
64257ccd5a2cSjsg 		DRM_ERROR("si_populate_smc_tdp_limits_2 failed\n");
64267ccd5a2cSjsg 		return ret;
64277ccd5a2cSjsg 	}
64287ccd5a2cSjsg 	si_program_response_times(rdev);
64297ccd5a2cSjsg 	si_program_ds_registers(rdev);
64307ccd5a2cSjsg 	si_dpm_start_smc(rdev);
64317ccd5a2cSjsg 	ret = si_notify_smc_display_change(rdev, false);
64327ccd5a2cSjsg 	if (ret) {
64337ccd5a2cSjsg 		DRM_ERROR("si_notify_smc_display_change failed\n");
64347ccd5a2cSjsg 		return ret;
64357ccd5a2cSjsg 	}
64367ccd5a2cSjsg 	si_enable_sclk_control(rdev, true);
64377ccd5a2cSjsg 	si_start_dpm(rdev);
64387ccd5a2cSjsg 
64397ccd5a2cSjsg 	si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
64407ccd5a2cSjsg 
64417ccd5a2cSjsg 	si_thermal_start_thermal_controller(rdev);
64427ccd5a2cSjsg 
64437ccd5a2cSjsg 	ni_update_current_ps(rdev, boot_ps);
64447ccd5a2cSjsg 
64457ccd5a2cSjsg 	return 0;
64467ccd5a2cSjsg }
64477ccd5a2cSjsg 
si_set_temperature_range(struct radeon_device * rdev)64487ccd5a2cSjsg static int si_set_temperature_range(struct radeon_device *rdev)
64497ccd5a2cSjsg {
64507ccd5a2cSjsg 	int ret;
64517ccd5a2cSjsg 
64527ccd5a2cSjsg 	ret = si_thermal_enable_alert(rdev, false);
64537ccd5a2cSjsg 	if (ret)
64547ccd5a2cSjsg 		return ret;
64557ccd5a2cSjsg 	ret = si_thermal_set_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
64567ccd5a2cSjsg 	if (ret)
64577ccd5a2cSjsg 		return ret;
64587ccd5a2cSjsg 	ret = si_thermal_enable_alert(rdev, true);
64597ccd5a2cSjsg 	if (ret)
64607ccd5a2cSjsg 		return ret;
64617ccd5a2cSjsg 
64627ccd5a2cSjsg 	return ret;
64637ccd5a2cSjsg }
64647ccd5a2cSjsg 
si_dpm_late_enable(struct radeon_device * rdev)64657ccd5a2cSjsg int si_dpm_late_enable(struct radeon_device *rdev)
64667ccd5a2cSjsg {
64677ccd5a2cSjsg 	int ret;
64687ccd5a2cSjsg 
64697ccd5a2cSjsg 	ret = si_set_temperature_range(rdev);
64707ccd5a2cSjsg 	if (ret)
64717ccd5a2cSjsg 		return ret;
64727ccd5a2cSjsg 
64737ccd5a2cSjsg 	return ret;
64747ccd5a2cSjsg }
64757ccd5a2cSjsg 
si_dpm_disable(struct radeon_device * rdev)64767ccd5a2cSjsg void si_dpm_disable(struct radeon_device *rdev)
64777ccd5a2cSjsg {
64787ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
64797ccd5a2cSjsg 	struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
64807ccd5a2cSjsg 
64817ccd5a2cSjsg 	if (!si_is_smc_running(rdev))
64827ccd5a2cSjsg 		return;
64837ccd5a2cSjsg 	si_thermal_stop_thermal_controller(rdev);
64847ccd5a2cSjsg 	si_disable_ulv(rdev);
64857ccd5a2cSjsg 	si_clear_vc(rdev);
64867ccd5a2cSjsg 	if (pi->thermal_protection)
64877ccd5a2cSjsg 		si_enable_thermal_protection(rdev, false);
64887ccd5a2cSjsg 	si_enable_power_containment(rdev, boot_ps, false);
64897ccd5a2cSjsg 	si_enable_smc_cac(rdev, boot_ps, false);
64907ccd5a2cSjsg 	si_enable_spread_spectrum(rdev, false);
64917ccd5a2cSjsg 	si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, false);
64927ccd5a2cSjsg 	si_stop_dpm(rdev);
64937ccd5a2cSjsg 	si_reset_to_default(rdev);
64947ccd5a2cSjsg 	si_dpm_stop_smc(rdev);
64957ccd5a2cSjsg 	si_force_switch_to_arb_f0(rdev);
64967ccd5a2cSjsg 
64977ccd5a2cSjsg 	ni_update_current_ps(rdev, boot_ps);
64987ccd5a2cSjsg }
64997ccd5a2cSjsg 
si_dpm_pre_set_power_state(struct radeon_device * rdev)65007ccd5a2cSjsg int si_dpm_pre_set_power_state(struct radeon_device *rdev)
65017ccd5a2cSjsg {
65027ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
65037ccd5a2cSjsg 	struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
65047ccd5a2cSjsg 	struct radeon_ps *new_ps = &requested_ps;
65057ccd5a2cSjsg 
65067ccd5a2cSjsg 	ni_update_requested_ps(rdev, new_ps);
65077ccd5a2cSjsg 
65087ccd5a2cSjsg 	si_apply_state_adjust_rules(rdev, &eg_pi->requested_rps);
65097ccd5a2cSjsg 
65107ccd5a2cSjsg 	return 0;
65117ccd5a2cSjsg }
65127ccd5a2cSjsg 
si_power_control_set_level(struct radeon_device * rdev)65137ccd5a2cSjsg static int si_power_control_set_level(struct radeon_device *rdev)
65147ccd5a2cSjsg {
65157ccd5a2cSjsg 	struct radeon_ps *new_ps = rdev->pm.dpm.requested_ps;
65167ccd5a2cSjsg 	int ret;
65177ccd5a2cSjsg 
65187ccd5a2cSjsg 	ret = si_restrict_performance_levels_before_switch(rdev);
65197ccd5a2cSjsg 	if (ret)
65207ccd5a2cSjsg 		return ret;
65217ccd5a2cSjsg 	ret = si_halt_smc(rdev);
65227ccd5a2cSjsg 	if (ret)
65237ccd5a2cSjsg 		return ret;
65247ccd5a2cSjsg 	ret = si_populate_smc_tdp_limits(rdev, new_ps);
65257ccd5a2cSjsg 	if (ret)
65267ccd5a2cSjsg 		return ret;
65277ccd5a2cSjsg 	ret = si_populate_smc_tdp_limits_2(rdev, new_ps);
65287ccd5a2cSjsg 	if (ret)
65297ccd5a2cSjsg 		return ret;
65307ccd5a2cSjsg 	ret = si_resume_smc(rdev);
65317ccd5a2cSjsg 	if (ret)
65327ccd5a2cSjsg 		return ret;
65337ccd5a2cSjsg 	ret = si_set_sw_state(rdev);
65347ccd5a2cSjsg 	if (ret)
65357ccd5a2cSjsg 		return ret;
65367ccd5a2cSjsg 	return 0;
65377ccd5a2cSjsg }
65387ccd5a2cSjsg 
si_dpm_set_power_state(struct radeon_device * rdev)65397ccd5a2cSjsg int si_dpm_set_power_state(struct radeon_device *rdev)
65407ccd5a2cSjsg {
65417ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
65427ccd5a2cSjsg 	struct radeon_ps *new_ps = &eg_pi->requested_rps;
65437ccd5a2cSjsg 	struct radeon_ps *old_ps = &eg_pi->current_rps;
65447ccd5a2cSjsg 	int ret;
65457ccd5a2cSjsg 
65467ccd5a2cSjsg 	ret = si_disable_ulv(rdev);
65477ccd5a2cSjsg 	if (ret) {
65487ccd5a2cSjsg 		DRM_ERROR("si_disable_ulv failed\n");
65497ccd5a2cSjsg 		return ret;
65507ccd5a2cSjsg 	}
65517ccd5a2cSjsg 	ret = si_restrict_performance_levels_before_switch(rdev);
65527ccd5a2cSjsg 	if (ret) {
65537ccd5a2cSjsg 		DRM_ERROR("si_restrict_performance_levels_before_switch failed\n");
65547ccd5a2cSjsg 		return ret;
65557ccd5a2cSjsg 	}
65567ccd5a2cSjsg 	if (eg_pi->pcie_performance_request)
65577ccd5a2cSjsg 		si_request_link_speed_change_before_state_change(rdev, new_ps, old_ps);
65587ccd5a2cSjsg 	ni_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
65597ccd5a2cSjsg 	ret = si_enable_power_containment(rdev, new_ps, false);
65607ccd5a2cSjsg 	if (ret) {
65617ccd5a2cSjsg 		DRM_ERROR("si_enable_power_containment failed\n");
65627ccd5a2cSjsg 		return ret;
65637ccd5a2cSjsg 	}
65647ccd5a2cSjsg 	ret = si_enable_smc_cac(rdev, new_ps, false);
65657ccd5a2cSjsg 	if (ret) {
65667ccd5a2cSjsg 		DRM_ERROR("si_enable_smc_cac failed\n");
65677ccd5a2cSjsg 		return ret;
65687ccd5a2cSjsg 	}
65697ccd5a2cSjsg 	ret = si_halt_smc(rdev);
65707ccd5a2cSjsg 	if (ret) {
65717ccd5a2cSjsg 		DRM_ERROR("si_halt_smc failed\n");
65727ccd5a2cSjsg 		return ret;
65737ccd5a2cSjsg 	}
65747ccd5a2cSjsg 	ret = si_upload_sw_state(rdev, new_ps);
65757ccd5a2cSjsg 	if (ret) {
65767ccd5a2cSjsg 		DRM_ERROR("si_upload_sw_state failed\n");
65777ccd5a2cSjsg 		return ret;
65787ccd5a2cSjsg 	}
65797ccd5a2cSjsg 	ret = si_upload_smc_data(rdev);
65807ccd5a2cSjsg 	if (ret) {
65817ccd5a2cSjsg 		DRM_ERROR("si_upload_smc_data failed\n");
65827ccd5a2cSjsg 		return ret;
65837ccd5a2cSjsg 	}
65847ccd5a2cSjsg 	ret = si_upload_ulv_state(rdev);
65857ccd5a2cSjsg 	if (ret) {
65867ccd5a2cSjsg 		DRM_ERROR("si_upload_ulv_state failed\n");
65877ccd5a2cSjsg 		return ret;
65887ccd5a2cSjsg 	}
65897ccd5a2cSjsg 	if (eg_pi->dynamic_ac_timing) {
65907ccd5a2cSjsg 		ret = si_upload_mc_reg_table(rdev, new_ps);
65917ccd5a2cSjsg 		if (ret) {
65927ccd5a2cSjsg 			DRM_ERROR("si_upload_mc_reg_table failed\n");
65937ccd5a2cSjsg 			return ret;
65947ccd5a2cSjsg 		}
65957ccd5a2cSjsg 	}
65967ccd5a2cSjsg 	ret = si_program_memory_timing_parameters(rdev, new_ps);
65977ccd5a2cSjsg 	if (ret) {
65987ccd5a2cSjsg 		DRM_ERROR("si_program_memory_timing_parameters failed\n");
65997ccd5a2cSjsg 		return ret;
66007ccd5a2cSjsg 	}
66017ccd5a2cSjsg 	si_set_pcie_lane_width_in_smc(rdev, new_ps, old_ps);
66027ccd5a2cSjsg 
66037ccd5a2cSjsg 	ret = si_resume_smc(rdev);
66047ccd5a2cSjsg 	if (ret) {
66057ccd5a2cSjsg 		DRM_ERROR("si_resume_smc failed\n");
66067ccd5a2cSjsg 		return ret;
66077ccd5a2cSjsg 	}
66087ccd5a2cSjsg 	ret = si_set_sw_state(rdev);
66097ccd5a2cSjsg 	if (ret) {
66107ccd5a2cSjsg 		DRM_ERROR("si_set_sw_state failed\n");
66117ccd5a2cSjsg 		return ret;
66127ccd5a2cSjsg 	}
66137ccd5a2cSjsg 	ni_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
66147ccd5a2cSjsg 	si_set_vce_clock(rdev, new_ps, old_ps);
66157ccd5a2cSjsg 	if (eg_pi->pcie_performance_request)
66167ccd5a2cSjsg 		si_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
66177ccd5a2cSjsg 	ret = si_set_power_state_conditionally_enable_ulv(rdev, new_ps);
66187ccd5a2cSjsg 	if (ret) {
66197ccd5a2cSjsg 		DRM_ERROR("si_set_power_state_conditionally_enable_ulv failed\n");
66207ccd5a2cSjsg 		return ret;
66217ccd5a2cSjsg 	}
66227ccd5a2cSjsg 	ret = si_enable_smc_cac(rdev, new_ps, true);
66237ccd5a2cSjsg 	if (ret) {
66247ccd5a2cSjsg 		DRM_ERROR("si_enable_smc_cac failed\n");
66257ccd5a2cSjsg 		return ret;
66267ccd5a2cSjsg 	}
66277ccd5a2cSjsg 	ret = si_enable_power_containment(rdev, new_ps, true);
66287ccd5a2cSjsg 	if (ret) {
66297ccd5a2cSjsg 		DRM_ERROR("si_enable_power_containment failed\n");
66307ccd5a2cSjsg 		return ret;
66317ccd5a2cSjsg 	}
66327ccd5a2cSjsg 
66337ccd5a2cSjsg 	ret = si_power_control_set_level(rdev);
66347ccd5a2cSjsg 	if (ret) {
66357ccd5a2cSjsg 		DRM_ERROR("si_power_control_set_level failed\n");
66367ccd5a2cSjsg 		return ret;
66377ccd5a2cSjsg 	}
66387ccd5a2cSjsg 
66397ccd5a2cSjsg 	return 0;
66407ccd5a2cSjsg }
66417ccd5a2cSjsg 
si_dpm_post_set_power_state(struct radeon_device * rdev)66427ccd5a2cSjsg void si_dpm_post_set_power_state(struct radeon_device *rdev)
66437ccd5a2cSjsg {
66447ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
66457ccd5a2cSjsg 	struct radeon_ps *new_ps = &eg_pi->requested_rps;
66467ccd5a2cSjsg 
66477ccd5a2cSjsg 	ni_update_current_ps(rdev, new_ps);
66487ccd5a2cSjsg }
66497ccd5a2cSjsg 
66507ccd5a2cSjsg #if 0
66517ccd5a2cSjsg void si_dpm_reset_asic(struct radeon_device *rdev)
66527ccd5a2cSjsg {
66537ccd5a2cSjsg 	si_restrict_performance_levels_before_switch(rdev);
66547ccd5a2cSjsg 	si_disable_ulv(rdev);
66557ccd5a2cSjsg 	si_set_boot_state(rdev);
66567ccd5a2cSjsg }
66577ccd5a2cSjsg #endif
66587ccd5a2cSjsg 
si_dpm_display_configuration_changed(struct radeon_device * rdev)66597ccd5a2cSjsg void si_dpm_display_configuration_changed(struct radeon_device *rdev)
66607ccd5a2cSjsg {
66617ccd5a2cSjsg 	si_program_display_gap(rdev);
66627ccd5a2cSjsg }
66637ccd5a2cSjsg 
66647ccd5a2cSjsg union power_info {
66657ccd5a2cSjsg 	struct _ATOM_POWERPLAY_INFO info;
66667ccd5a2cSjsg 	struct _ATOM_POWERPLAY_INFO_V2 info_2;
66677ccd5a2cSjsg 	struct _ATOM_POWERPLAY_INFO_V3 info_3;
66687ccd5a2cSjsg 	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
66697ccd5a2cSjsg 	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
66707ccd5a2cSjsg 	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
66717ccd5a2cSjsg };
66727ccd5a2cSjsg 
66737ccd5a2cSjsg union pplib_clock_info {
66747ccd5a2cSjsg 	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
66757ccd5a2cSjsg 	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
66767ccd5a2cSjsg 	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
66777ccd5a2cSjsg 	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
66787ccd5a2cSjsg 	struct _ATOM_PPLIB_SI_CLOCK_INFO si;
66797ccd5a2cSjsg };
66807ccd5a2cSjsg 
66817ccd5a2cSjsg union pplib_power_state {
66827ccd5a2cSjsg 	struct _ATOM_PPLIB_STATE v1;
66837ccd5a2cSjsg 	struct _ATOM_PPLIB_STATE_V2 v2;
66847ccd5a2cSjsg };
66857ccd5a2cSjsg 
si_parse_pplib_non_clock_info(struct radeon_device * rdev,struct radeon_ps * rps,struct _ATOM_PPLIB_NONCLOCK_INFO * non_clock_info,u8 table_rev)66867ccd5a2cSjsg static void si_parse_pplib_non_clock_info(struct radeon_device *rdev,
66877ccd5a2cSjsg 					  struct radeon_ps *rps,
66887ccd5a2cSjsg 					  struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
66897ccd5a2cSjsg 					  u8 table_rev)
66907ccd5a2cSjsg {
66917ccd5a2cSjsg 	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
66927ccd5a2cSjsg 	rps->class = le16_to_cpu(non_clock_info->usClassification);
66937ccd5a2cSjsg 	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
66947ccd5a2cSjsg 
66957ccd5a2cSjsg 	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
66967ccd5a2cSjsg 		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
66977ccd5a2cSjsg 		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
66987ccd5a2cSjsg 	} else if (r600_is_uvd_state(rps->class, rps->class2)) {
66997ccd5a2cSjsg 		rps->vclk = RV770_DEFAULT_VCLK_FREQ;
67007ccd5a2cSjsg 		rps->dclk = RV770_DEFAULT_DCLK_FREQ;
67017ccd5a2cSjsg 	} else {
67027ccd5a2cSjsg 		rps->vclk = 0;
67037ccd5a2cSjsg 		rps->dclk = 0;
67047ccd5a2cSjsg 	}
67057ccd5a2cSjsg 
67067ccd5a2cSjsg 	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
67077ccd5a2cSjsg 		rdev->pm.dpm.boot_ps = rps;
67087ccd5a2cSjsg 	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
67097ccd5a2cSjsg 		rdev->pm.dpm.uvd_ps = rps;
67107ccd5a2cSjsg }
67117ccd5a2cSjsg 
si_parse_pplib_clock_info(struct radeon_device * rdev,struct radeon_ps * rps,int index,union pplib_clock_info * clock_info)67127ccd5a2cSjsg static void si_parse_pplib_clock_info(struct radeon_device *rdev,
67137ccd5a2cSjsg 				      struct radeon_ps *rps, int index,
67147ccd5a2cSjsg 				      union pplib_clock_info *clock_info)
67157ccd5a2cSjsg {
67167ccd5a2cSjsg 	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
67177ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
67187ccd5a2cSjsg 	struct si_power_info *si_pi = si_get_pi(rdev);
67197ccd5a2cSjsg 	struct ni_ps *ps = ni_get_ps(rps);
67207ccd5a2cSjsg 	u16 leakage_voltage;
67217ccd5a2cSjsg 	struct rv7xx_pl *pl = &ps->performance_levels[index];
67227ccd5a2cSjsg 	int ret;
67237ccd5a2cSjsg 
67247ccd5a2cSjsg 	ps->performance_level_count = index + 1;
67257ccd5a2cSjsg 
67267ccd5a2cSjsg 	pl->sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
67277ccd5a2cSjsg 	pl->sclk |= clock_info->si.ucEngineClockHigh << 16;
67287ccd5a2cSjsg 	pl->mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
67297ccd5a2cSjsg 	pl->mclk |= clock_info->si.ucMemoryClockHigh << 16;
67307ccd5a2cSjsg 
67317ccd5a2cSjsg 	pl->vddc = le16_to_cpu(clock_info->si.usVDDC);
67327ccd5a2cSjsg 	pl->vddci = le16_to_cpu(clock_info->si.usVDDCI);
67337ccd5a2cSjsg 	pl->flags = le32_to_cpu(clock_info->si.ulFlags);
67347ccd5a2cSjsg 	pl->pcie_gen = r600_get_pcie_gen_support(rdev,
67357ccd5a2cSjsg 						 si_pi->sys_pcie_mask,
67367ccd5a2cSjsg 						 si_pi->boot_pcie_gen,
67377ccd5a2cSjsg 						 clock_info->si.ucPCIEGen);
67387ccd5a2cSjsg 
67397ccd5a2cSjsg 	/* patch up vddc if necessary */
67407ccd5a2cSjsg 	ret = si_get_leakage_voltage_from_leakage_index(rdev, pl->vddc,
67417ccd5a2cSjsg 							&leakage_voltage);
67427ccd5a2cSjsg 	if (ret == 0)
67437ccd5a2cSjsg 		pl->vddc = leakage_voltage;
67447ccd5a2cSjsg 
67457ccd5a2cSjsg 	if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
67467ccd5a2cSjsg 		pi->acpi_vddc = pl->vddc;
67477ccd5a2cSjsg 		eg_pi->acpi_vddci = pl->vddci;
67487ccd5a2cSjsg 		si_pi->acpi_pcie_gen = pl->pcie_gen;
67497ccd5a2cSjsg 	}
67507ccd5a2cSjsg 
67517ccd5a2cSjsg 	if ((rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) &&
67527ccd5a2cSjsg 	    index == 0) {
67537ccd5a2cSjsg 		/* XXX disable for A0 tahiti */
67547ccd5a2cSjsg 		si_pi->ulv.supported = false;
67557ccd5a2cSjsg 		si_pi->ulv.pl = *pl;
67567ccd5a2cSjsg 		si_pi->ulv.one_pcie_lane_in_ulv = false;
67577ccd5a2cSjsg 		si_pi->ulv.volt_change_delay = SISLANDS_ULVVOLTAGECHANGEDELAY_DFLT;
67587ccd5a2cSjsg 		si_pi->ulv.cg_ulv_parameter = SISLANDS_CGULVPARAMETER_DFLT;
67597ccd5a2cSjsg 		si_pi->ulv.cg_ulv_control = SISLANDS_CGULVCONTROL_DFLT;
67607ccd5a2cSjsg 	}
67617ccd5a2cSjsg 
67627ccd5a2cSjsg 	if (pi->min_vddc_in_table > pl->vddc)
67637ccd5a2cSjsg 		pi->min_vddc_in_table = pl->vddc;
67647ccd5a2cSjsg 
67657ccd5a2cSjsg 	if (pi->max_vddc_in_table < pl->vddc)
67667ccd5a2cSjsg 		pi->max_vddc_in_table = pl->vddc;
67677ccd5a2cSjsg 
67687ccd5a2cSjsg 	/* patch up boot state */
67697ccd5a2cSjsg 	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
67707ccd5a2cSjsg 		u16 vddc, vddci, mvdd;
67717ccd5a2cSjsg 		radeon_atombios_get_default_voltages(rdev, &vddc, &vddci, &mvdd);
67727ccd5a2cSjsg 		pl->mclk = rdev->clock.default_mclk;
67737ccd5a2cSjsg 		pl->sclk = rdev->clock.default_sclk;
67747ccd5a2cSjsg 		pl->vddc = vddc;
67757ccd5a2cSjsg 		pl->vddci = vddci;
67767ccd5a2cSjsg 		si_pi->mvdd_bootup_value = mvdd;
67777ccd5a2cSjsg 	}
67787ccd5a2cSjsg 
67797ccd5a2cSjsg 	if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
67807ccd5a2cSjsg 	    ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
67817ccd5a2cSjsg 		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk;
67827ccd5a2cSjsg 		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk;
67837ccd5a2cSjsg 		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc;
67847ccd5a2cSjsg 		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci;
67857ccd5a2cSjsg 	}
67867ccd5a2cSjsg }
67877ccd5a2cSjsg 
si_parse_power_table(struct radeon_device * rdev)67887ccd5a2cSjsg static int si_parse_power_table(struct radeon_device *rdev)
67897ccd5a2cSjsg {
67907ccd5a2cSjsg 	struct radeon_mode_info *mode_info = &rdev->mode_info;
67917ccd5a2cSjsg 	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
67927ccd5a2cSjsg 	union pplib_power_state *power_state;
67937ccd5a2cSjsg 	int i, j, k, non_clock_array_index, clock_array_index;
67947ccd5a2cSjsg 	union pplib_clock_info *clock_info;
67957ccd5a2cSjsg 	struct _StateArray *state_array;
67967ccd5a2cSjsg 	struct _ClockInfoArray *clock_info_array;
67977ccd5a2cSjsg 	struct _NonClockInfoArray *non_clock_info_array;
67987ccd5a2cSjsg 	union power_info *power_info;
67997ccd5a2cSjsg 	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
68007ccd5a2cSjsg 	u16 data_offset;
68017ccd5a2cSjsg 	u8 frev, crev;
68027ccd5a2cSjsg 	u8 *power_state_offset;
68037ccd5a2cSjsg 	struct ni_ps *ps;
68047ccd5a2cSjsg 
68057ccd5a2cSjsg 	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
68067ccd5a2cSjsg 				   &frev, &crev, &data_offset))
68077ccd5a2cSjsg 		return -EINVAL;
68087ccd5a2cSjsg 	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
68097ccd5a2cSjsg 
68107ccd5a2cSjsg 	state_array = (struct _StateArray *)
68117ccd5a2cSjsg 		(mode_info->atom_context->bios + data_offset +
68127ccd5a2cSjsg 		 le16_to_cpu(power_info->pplib.usStateArrayOffset));
68137ccd5a2cSjsg 	clock_info_array = (struct _ClockInfoArray *)
68147ccd5a2cSjsg 		(mode_info->atom_context->bios + data_offset +
68157ccd5a2cSjsg 		 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset));
68167ccd5a2cSjsg 	non_clock_info_array = (struct _NonClockInfoArray *)
68177ccd5a2cSjsg 		(mode_info->atom_context->bios + data_offset +
68187ccd5a2cSjsg 		 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset));
68197ccd5a2cSjsg 
68207f4dd379Sjsg 	rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries,
68217f4dd379Sjsg 				  sizeof(struct radeon_ps),
68227f4dd379Sjsg 				  GFP_KERNEL);
68237ccd5a2cSjsg 	if (!rdev->pm.dpm.ps)
68247ccd5a2cSjsg 		return -ENOMEM;
68257ccd5a2cSjsg 	power_state_offset = (u8 *)state_array->states;
68267ccd5a2cSjsg 	for (i = 0; i < state_array->ucNumEntries; i++) {
68277ccd5a2cSjsg 		u8 *idx;
68287ccd5a2cSjsg 		power_state = (union pplib_power_state *)power_state_offset;
68297ccd5a2cSjsg 		non_clock_array_index = power_state->v2.nonClockInfoIndex;
68307ccd5a2cSjsg 		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
68317ccd5a2cSjsg 			&non_clock_info_array->nonClockInfo[non_clock_array_index];
68327ccd5a2cSjsg 		if (!rdev->pm.power_state[i].clock_info)
68337ccd5a2cSjsg 			return -EINVAL;
68347ccd5a2cSjsg 		ps = kzalloc(sizeof(struct ni_ps), GFP_KERNEL);
68357ccd5a2cSjsg 		if (ps == NULL) {
68367ccd5a2cSjsg 			kfree(rdev->pm.dpm.ps);
68377ccd5a2cSjsg 			return -ENOMEM;
68387ccd5a2cSjsg 		}
68397ccd5a2cSjsg 		rdev->pm.dpm.ps[i].ps_priv = ps;
68407ccd5a2cSjsg 		si_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
68417ccd5a2cSjsg 					      non_clock_info,
68427ccd5a2cSjsg 					      non_clock_info_array->ucEntrySize);
68437ccd5a2cSjsg 		k = 0;
68447ccd5a2cSjsg 		idx = (u8 *)&power_state->v2.clockInfoIndex[0];
68457ccd5a2cSjsg 		for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) {
68467ccd5a2cSjsg 			clock_array_index = idx[j];
68477ccd5a2cSjsg 			if (clock_array_index >= clock_info_array->ucNumEntries)
68487ccd5a2cSjsg 				continue;
68497ccd5a2cSjsg 			if (k >= SISLANDS_MAX_HARDWARE_POWERLEVELS)
68507ccd5a2cSjsg 				break;
68517ccd5a2cSjsg 			clock_info = (union pplib_clock_info *)
68527ccd5a2cSjsg 				((u8 *)&clock_info_array->clockInfo[0] +
68537ccd5a2cSjsg 				 (clock_array_index * clock_info_array->ucEntrySize));
68547ccd5a2cSjsg 			si_parse_pplib_clock_info(rdev,
68557ccd5a2cSjsg 						  &rdev->pm.dpm.ps[i], k,
68567ccd5a2cSjsg 						  clock_info);
68577ccd5a2cSjsg 			k++;
68587ccd5a2cSjsg 		}
68597ccd5a2cSjsg 		power_state_offset += 2 + power_state->v2.ucNumDPMLevels;
68607ccd5a2cSjsg 	}
68617ccd5a2cSjsg 	rdev->pm.dpm.num_ps = state_array->ucNumEntries;
68627ccd5a2cSjsg 
68637ccd5a2cSjsg 	/* fill in the vce power states */
68647ccd5a2cSjsg 	for (i = 0; i < RADEON_MAX_VCE_LEVELS; i++) {
68657ccd5a2cSjsg 		u32 sclk, mclk;
68667ccd5a2cSjsg 		clock_array_index = rdev->pm.dpm.vce_states[i].clk_idx;
68677ccd5a2cSjsg 		clock_info = (union pplib_clock_info *)
68687ccd5a2cSjsg 			&clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize];
68697ccd5a2cSjsg 		sclk = le16_to_cpu(clock_info->si.usEngineClockLow);
68707ccd5a2cSjsg 		sclk |= clock_info->si.ucEngineClockHigh << 16;
68717ccd5a2cSjsg 		mclk = le16_to_cpu(clock_info->si.usMemoryClockLow);
68727ccd5a2cSjsg 		mclk |= clock_info->si.ucMemoryClockHigh << 16;
68737ccd5a2cSjsg 		rdev->pm.dpm.vce_states[i].sclk = sclk;
68747ccd5a2cSjsg 		rdev->pm.dpm.vce_states[i].mclk = mclk;
68757ccd5a2cSjsg 	}
68767ccd5a2cSjsg 
68777ccd5a2cSjsg 	return 0;
68787ccd5a2cSjsg }
68797ccd5a2cSjsg 
si_dpm_init(struct radeon_device * rdev)68807ccd5a2cSjsg int si_dpm_init(struct radeon_device *rdev)
68817ccd5a2cSjsg {
68827ccd5a2cSjsg 	struct rv7xx_power_info *pi;
68837ccd5a2cSjsg 	struct evergreen_power_info *eg_pi;
68847ccd5a2cSjsg 	struct ni_power_info *ni_pi;
68857ccd5a2cSjsg 	struct si_power_info *si_pi;
68867ccd5a2cSjsg 	struct atom_clock_dividers dividers;
68877f4dd379Sjsg 	enum pci_bus_speed speed_cap = PCI_SPEED_UNKNOWN;
68887f4dd379Sjsg 	struct pci_dev *root = rdev->pdev->bus->self;
68897ccd5a2cSjsg 	int ret;
68907ccd5a2cSjsg 
68917ccd5a2cSjsg 	si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL);
68927ccd5a2cSjsg 	if (si_pi == NULL)
68937ccd5a2cSjsg 		return -ENOMEM;
68947ccd5a2cSjsg 	rdev->pm.dpm.priv = si_pi;
68957ccd5a2cSjsg 	ni_pi = &si_pi->ni;
68967ccd5a2cSjsg 	eg_pi = &ni_pi->eg;
68977ccd5a2cSjsg 	pi = &eg_pi->rv7xx;
68987ccd5a2cSjsg 
68997f4dd379Sjsg 	if (!pci_is_root_bus(rdev->pdev->bus))
69007f4dd379Sjsg 		speed_cap = pcie_get_speed_cap(root);
69017f4dd379Sjsg 	if (speed_cap == PCI_SPEED_UNKNOWN) {
69027ccd5a2cSjsg 		si_pi->sys_pcie_mask = 0;
69037f4dd379Sjsg 	} else {
69047f4dd379Sjsg 		if (speed_cap == PCIE_SPEED_8_0GT)
69057f4dd379Sjsg 			si_pi->sys_pcie_mask = RADEON_PCIE_SPEED_25 |
69067f4dd379Sjsg 				RADEON_PCIE_SPEED_50 |
69077f4dd379Sjsg 				RADEON_PCIE_SPEED_80;
69087f4dd379Sjsg 		else if (speed_cap == PCIE_SPEED_5_0GT)
69097f4dd379Sjsg 			si_pi->sys_pcie_mask = RADEON_PCIE_SPEED_25 |
69107f4dd379Sjsg 				RADEON_PCIE_SPEED_50;
69117ccd5a2cSjsg 		else
69127f4dd379Sjsg 			si_pi->sys_pcie_mask = RADEON_PCIE_SPEED_25;
69137f4dd379Sjsg 	}
69147ccd5a2cSjsg 	si_pi->force_pcie_gen = RADEON_PCIE_GEN_INVALID;
69157ccd5a2cSjsg 	si_pi->boot_pcie_gen = si_get_current_pcie_speed(rdev);
69167ccd5a2cSjsg 
69177ccd5a2cSjsg 	si_set_max_cu_value(rdev);
69187ccd5a2cSjsg 
69197ccd5a2cSjsg 	rv770_get_max_vddc(rdev);
69207ccd5a2cSjsg 	si_get_leakage_vddc(rdev);
69217ccd5a2cSjsg 	si_patch_dependency_tables_based_on_leakage(rdev);
69227ccd5a2cSjsg 
69237ccd5a2cSjsg 	pi->acpi_vddc = 0;
69247ccd5a2cSjsg 	eg_pi->acpi_vddci = 0;
69257ccd5a2cSjsg 	pi->min_vddc_in_table = 0;
69267ccd5a2cSjsg 	pi->max_vddc_in_table = 0;
69277ccd5a2cSjsg 
69287ccd5a2cSjsg 	ret = r600_get_platform_caps(rdev);
69297ccd5a2cSjsg 	if (ret)
69307ccd5a2cSjsg 		return ret;
69317ccd5a2cSjsg 
69327ccd5a2cSjsg 	ret = r600_parse_extended_power_table(rdev);
69337ccd5a2cSjsg 	if (ret)
69347ccd5a2cSjsg 		return ret;
69357ccd5a2cSjsg 
69367ccd5a2cSjsg 	ret = si_parse_power_table(rdev);
69377ccd5a2cSjsg 	if (ret)
69387ccd5a2cSjsg 		return ret;
69397ccd5a2cSjsg 
69407ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
69417f4dd379Sjsg 		kcalloc(4,
69427f4dd379Sjsg 			sizeof(struct radeon_clock_voltage_dependency_entry),
69437f4dd379Sjsg 			GFP_KERNEL);
69447ccd5a2cSjsg 	if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
69457ccd5a2cSjsg 		r600_free_extended_power_table(rdev);
69467ccd5a2cSjsg 		return -ENOMEM;
69477ccd5a2cSjsg 	}
69487ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
69497ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
69507ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
69517ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
69527ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 720;
69537ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
69547ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 810;
69557ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
69567ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 900;
69577ccd5a2cSjsg 
69587ccd5a2cSjsg 	if (rdev->pm.dpm.voltage_response_time == 0)
69597ccd5a2cSjsg 		rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
69607ccd5a2cSjsg 	if (rdev->pm.dpm.backbias_response_time == 0)
69617ccd5a2cSjsg 		rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
69627ccd5a2cSjsg 
69637ccd5a2cSjsg 	ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
69647ccd5a2cSjsg 					     0, false, &dividers);
69657ccd5a2cSjsg 	if (ret)
69667ccd5a2cSjsg 		pi->ref_div = dividers.ref_div + 1;
69677ccd5a2cSjsg 	else
69687ccd5a2cSjsg 		pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
69697ccd5a2cSjsg 
69707ccd5a2cSjsg 	eg_pi->smu_uvd_hs = false;
69717ccd5a2cSjsg 
69727ccd5a2cSjsg 	pi->mclk_strobe_mode_threshold = 40000;
69737ccd5a2cSjsg 	if (si_is_special_1gb_platform(rdev))
69747ccd5a2cSjsg 		pi->mclk_stutter_mode_threshold = 0;
69757ccd5a2cSjsg 	else
69767ccd5a2cSjsg 		pi->mclk_stutter_mode_threshold = pi->mclk_strobe_mode_threshold;
69777ccd5a2cSjsg 	pi->mclk_edc_enable_threshold = 40000;
69787ccd5a2cSjsg 	eg_pi->mclk_edc_wr_enable_threshold = 40000;
69797ccd5a2cSjsg 
69807ccd5a2cSjsg 	ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold;
69817ccd5a2cSjsg 
69827ccd5a2cSjsg 	pi->voltage_control =
69837ccd5a2cSjsg 		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
69847ccd5a2cSjsg 					    VOLTAGE_OBJ_GPIO_LUT);
69857ccd5a2cSjsg 	if (!pi->voltage_control) {
69867ccd5a2cSjsg 		si_pi->voltage_control_svi2 =
69877ccd5a2cSjsg 			radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
69887ccd5a2cSjsg 						    VOLTAGE_OBJ_SVID2);
69897ccd5a2cSjsg 		if (si_pi->voltage_control_svi2)
69907ccd5a2cSjsg 			radeon_atom_get_svi2_info(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
69917ccd5a2cSjsg 						  &si_pi->svd_gpio_id, &si_pi->svc_gpio_id);
69927ccd5a2cSjsg 	}
69937ccd5a2cSjsg 
69947ccd5a2cSjsg 	pi->mvdd_control =
69957ccd5a2cSjsg 		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC,
69967ccd5a2cSjsg 					    VOLTAGE_OBJ_GPIO_LUT);
69977ccd5a2cSjsg 
69987ccd5a2cSjsg 	eg_pi->vddci_control =
69997ccd5a2cSjsg 		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI,
70007ccd5a2cSjsg 					    VOLTAGE_OBJ_GPIO_LUT);
70017ccd5a2cSjsg 	if (!eg_pi->vddci_control)
70027ccd5a2cSjsg 		si_pi->vddci_control_svi2 =
70037ccd5a2cSjsg 			radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI,
70047ccd5a2cSjsg 						    VOLTAGE_OBJ_SVID2);
70057ccd5a2cSjsg 
70067ccd5a2cSjsg 	si_pi->vddc_phase_shed_control =
70077ccd5a2cSjsg 		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC,
70087ccd5a2cSjsg 					    VOLTAGE_OBJ_PHASE_LUT);
70097ccd5a2cSjsg 
70107ccd5a2cSjsg 	rv770_get_engine_memory_ss(rdev);
70117ccd5a2cSjsg 
70127ccd5a2cSjsg 	pi->asi = RV770_ASI_DFLT;
70137ccd5a2cSjsg 	pi->pasi = CYPRESS_HASI_DFLT;
70147ccd5a2cSjsg 	pi->vrc = SISLANDS_VRC_DFLT;
70157ccd5a2cSjsg 
70167ccd5a2cSjsg 	pi->gfx_clock_gating = true;
70177ccd5a2cSjsg 
70187ccd5a2cSjsg 	eg_pi->sclk_deep_sleep = true;
70197ccd5a2cSjsg 	si_pi->sclk_deep_sleep_above_low = false;
70207ccd5a2cSjsg 
70217ccd5a2cSjsg 	if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
70227ccd5a2cSjsg 		pi->thermal_protection = true;
70237ccd5a2cSjsg 	else
70247ccd5a2cSjsg 		pi->thermal_protection = false;
70257ccd5a2cSjsg 
70267ccd5a2cSjsg 	eg_pi->dynamic_ac_timing = true;
70277ccd5a2cSjsg 
70287ccd5a2cSjsg 	eg_pi->light_sleep = true;
70297ccd5a2cSjsg #if defined(CONFIG_ACPI)
70307ccd5a2cSjsg 	eg_pi->pcie_performance_request =
70317ccd5a2cSjsg 		radeon_acpi_is_pcie_performance_request_supported(rdev);
70327ccd5a2cSjsg #else
70337ccd5a2cSjsg 	eg_pi->pcie_performance_request = false;
70347ccd5a2cSjsg #endif
70357ccd5a2cSjsg 
70367ccd5a2cSjsg 	si_pi->sram_end = SMC_RAM_END;
70377ccd5a2cSjsg 
70387ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;
70397ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;
70407ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
70417ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.valid_sclk_values.count = 0;
70427ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.valid_sclk_values.values = NULL;
70437ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
70447ccd5a2cSjsg 	rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
70457ccd5a2cSjsg 
70467ccd5a2cSjsg 	si_initialize_powertune_defaults(rdev);
70477ccd5a2cSjsg 
70487ccd5a2cSjsg 	/* make sure dc limits are valid */
70497ccd5a2cSjsg 	if ((rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk == 0) ||
70507ccd5a2cSjsg 	    (rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk == 0))
70517ccd5a2cSjsg 		rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc =
70527ccd5a2cSjsg 			rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
70537ccd5a2cSjsg 
70547ccd5a2cSjsg 	si_pi->fan_ctrl_is_in_default_mode = true;
70557ccd5a2cSjsg 
70567ccd5a2cSjsg 	return 0;
70577ccd5a2cSjsg }
70587ccd5a2cSjsg 
si_dpm_fini(struct radeon_device * rdev)70597ccd5a2cSjsg void si_dpm_fini(struct radeon_device *rdev)
70607ccd5a2cSjsg {
70617ccd5a2cSjsg 	int i;
70627ccd5a2cSjsg 
70637ccd5a2cSjsg 	for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
70647ccd5a2cSjsg 		kfree(rdev->pm.dpm.ps[i].ps_priv);
70657ccd5a2cSjsg 	}
70667ccd5a2cSjsg 	kfree(rdev->pm.dpm.ps);
70677ccd5a2cSjsg 	kfree(rdev->pm.dpm.priv);
70687ccd5a2cSjsg 	kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
70697ccd5a2cSjsg 	r600_free_extended_power_table(rdev);
70707ccd5a2cSjsg }
70717ccd5a2cSjsg 
si_dpm_debugfs_print_current_performance_level(struct radeon_device * rdev,struct seq_file * m)70727ccd5a2cSjsg void si_dpm_debugfs_print_current_performance_level(struct radeon_device *rdev,
70737ccd5a2cSjsg 						    struct seq_file *m)
70747ccd5a2cSjsg {
70757ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
70767ccd5a2cSjsg 	struct radeon_ps *rps = &eg_pi->current_rps;
70777ccd5a2cSjsg 	struct ni_ps *ps = ni_get_ps(rps);
70787ccd5a2cSjsg 	struct rv7xx_pl *pl;
70797ccd5a2cSjsg 	u32 current_index =
70807ccd5a2cSjsg 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
70817ccd5a2cSjsg 		CURRENT_STATE_INDEX_SHIFT;
70827ccd5a2cSjsg 
70837ccd5a2cSjsg 	if (current_index >= ps->performance_level_count) {
70847ccd5a2cSjsg 		seq_printf(m, "invalid dpm profile %d\n", current_index);
70857ccd5a2cSjsg 	} else {
70867ccd5a2cSjsg 		pl = &ps->performance_levels[current_index];
70877ccd5a2cSjsg 		seq_printf(m, "uvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
70887ccd5a2cSjsg 		seq_printf(m, "power level %d    sclk: %u mclk: %u vddc: %u vddci: %u pcie gen: %u\n",
70897ccd5a2cSjsg 			   current_index, pl->sclk, pl->mclk, pl->vddc, pl->vddci, pl->pcie_gen + 1);
70907ccd5a2cSjsg 	}
70917ccd5a2cSjsg }
70927ccd5a2cSjsg 
si_dpm_get_current_sclk(struct radeon_device * rdev)70937ccd5a2cSjsg u32 si_dpm_get_current_sclk(struct radeon_device *rdev)
70947ccd5a2cSjsg {
70957ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
70967ccd5a2cSjsg 	struct radeon_ps *rps = &eg_pi->current_rps;
70977ccd5a2cSjsg 	struct ni_ps *ps = ni_get_ps(rps);
70987ccd5a2cSjsg 	struct rv7xx_pl *pl;
70997ccd5a2cSjsg 	u32 current_index =
71007ccd5a2cSjsg 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
71017ccd5a2cSjsg 		CURRENT_STATE_INDEX_SHIFT;
71027ccd5a2cSjsg 
71037ccd5a2cSjsg 	if (current_index >= ps->performance_level_count) {
71047ccd5a2cSjsg 		return 0;
71057ccd5a2cSjsg 	} else {
71067ccd5a2cSjsg 		pl = &ps->performance_levels[current_index];
71077ccd5a2cSjsg 		return pl->sclk;
71087ccd5a2cSjsg 	}
71097ccd5a2cSjsg }
71107ccd5a2cSjsg 
si_dpm_get_current_mclk(struct radeon_device * rdev)71117ccd5a2cSjsg u32 si_dpm_get_current_mclk(struct radeon_device *rdev)
71127ccd5a2cSjsg {
71137ccd5a2cSjsg 	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
71147ccd5a2cSjsg 	struct radeon_ps *rps = &eg_pi->current_rps;
71157ccd5a2cSjsg 	struct ni_ps *ps = ni_get_ps(rps);
71167ccd5a2cSjsg 	struct rv7xx_pl *pl;
71177ccd5a2cSjsg 	u32 current_index =
71187ccd5a2cSjsg 		(RREG32(TARGET_AND_CURRENT_PROFILE_INDEX) & CURRENT_STATE_INDEX_MASK) >>
71197ccd5a2cSjsg 		CURRENT_STATE_INDEX_SHIFT;
71207ccd5a2cSjsg 
71217ccd5a2cSjsg 	if (current_index >= ps->performance_level_count) {
71227ccd5a2cSjsg 		return 0;
71237ccd5a2cSjsg 	} else {
71247ccd5a2cSjsg 		pl = &ps->performance_levels[current_index];
71257ccd5a2cSjsg 		return pl->mclk;
71267ccd5a2cSjsg 	}
71277ccd5a2cSjsg }
7128