Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

platform/x86: asus-armoury: add ppt_* and nv_* tuning knobs

Adds the ppt_* and nv_* tuning knobs that are available via WMI methods
and adds proper min/max levels plus defaults.

The min/max are defined by ASUS and typically gained by looking at what
they allow in the ASUS Armoury Crate application - ASUS does not share
the values outside of this. It could also be possible to gain the AMD
values by use of ryzenadj and testing for the minimum stable value.

The general rule of thumb for adding to the match table is that if the
model range has a single CPU used throughout, then the DMI match can
omit the last letter of the model number as this is the GPU model.

If a min or max value is not provided it is assumed that the particular
setting is not supported. for example ppt_pl2_sppt_min/max is not set.
If a <ppt_setting>_def is not set then the default is assumed to be
<ppt_setting>_max

It is assumed that at least AC settings are available so that the
firmware attributes will be created - if no DC table is available
and power is on DC, then reading the attributes is -ENODEV.

Co-developed-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Denis Benato <denis.benato@linux.dev>
Signed-off-by: Luke D. Jones <luke@ljones.dev>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Tested-by: Mateusz Schyboll <dragonn@op.pl>
Tested-by: Porfet Lillian <porfet828@gmail.com>
Link: https://patch.msgid.link/20251102215319.3126879-10-denis.benato@linux.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Luke D. Jones and committed by
Ilpo Järvinen
39ae6c50 d849a9f2

+1593 -6
+296 -6
drivers/platform/x86/asus-armoury.c
··· 30 30 #include <linux/pci.h> 31 31 #include <linux/platform_data/x86/asus-wmi.h> 32 32 #include <linux/printk.h> 33 + #include <linux/power_supply.h> 33 34 #include <linux/sysfs.h> 34 35 35 36 #include "asus-armoury.h" ··· 49 48 #define ASUS_MINI_LED_2024_STRONG 0x01 50 49 #define ASUS_MINI_LED_2024_OFF 0x02 51 50 51 + /* Power tunable attribute name defines */ 52 + #define ATTR_PPT_PL1_SPL "ppt_pl1_spl" 53 + #define ATTR_PPT_PL2_SPPT "ppt_pl2_sppt" 54 + #define ATTR_PPT_PL3_FPPT "ppt_pl3_fppt" 55 + #define ATTR_PPT_APU_SPPT "ppt_apu_sppt" 56 + #define ATTR_PPT_PLATFORM_SPPT "ppt_platform_sppt" 57 + #define ATTR_NV_DYNAMIC_BOOST "nv_dynamic_boost" 58 + #define ATTR_NV_TEMP_TARGET "nv_temp_target" 59 + #define ATTR_NV_BASE_TGP "nv_base_tgp" 60 + #define ATTR_NV_TGP "nv_tgp" 61 + 62 + #define ASUS_ROG_TUNABLE_DC 0 63 + #define ASUS_ROG_TUNABLE_AC 1 64 + 65 + struct rog_tunables { 66 + const struct power_limits *power_limits; 67 + u32 ppt_pl1_spl; // cpu 68 + u32 ppt_pl2_sppt; // cpu 69 + u32 ppt_pl3_fppt; // cpu 70 + u32 ppt_apu_sppt; // plat 71 + u32 ppt_platform_sppt; // plat 72 + 73 + u32 nv_dynamic_boost; 74 + u32 nv_temp_target; 75 + u32 nv_tgp; 76 + }; 77 + 52 78 struct asus_armoury_priv { 53 79 struct device *fw_attr_dev; 54 80 struct kset *fw_attr_kset; ··· 87 59 * before a reboot if dGPU got disabled. 88 60 */ 89 61 struct mutex egpu_mutex; 62 + 63 + /* Index 0 for DC, 1 for AC */ 64 + struct rog_tunables *rog_tunables[2]; 90 65 91 66 u32 mini_led_dev_id; 92 67 u32 gpu_mux_dev_id; ··· 319 288 char *buf) 320 289 { 321 290 return sysfs_emit(buf, "enumeration\n"); 291 + } 292 + 293 + static ssize_t int_type_show(struct kobject *kobj, struct kobj_attribute *attr, 294 + char *buf) 295 + { 296 + return sysfs_emit(buf, "integer\n"); 322 297 } 323 298 324 299 /* Mini-LED mode **************************************************************/ ··· 733 696 } 734 697 ASUS_ATTR_GROUP_ENUM(apu_mem, "apu_mem", "Set available system RAM (in GB) for the APU to use"); 735 698 699 + /* Define helper to access the current power mode tunable values */ 700 + static inline struct rog_tunables *get_current_tunables(void) 701 + { 702 + if (power_supply_is_system_supplied()) 703 + return asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC]; 704 + 705 + return asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC]; 706 + } 707 + 736 708 /* Simple attribute creation */ 737 709 ASUS_ATTR_GROUP_ENUM_INT_RO(charge_mode, "charge_mode", ASUS_WMI_DEVID_CHARGE_MODE, "0;1;2\n", 738 710 "Show the current mode of charging"); ··· 758 712 "Set the panel brightness to Off<0> or On<1>"); 759 713 ASUS_ATTR_GROUP_BOOL_RO(egpu_connected, "egpu_connected", ASUS_WMI_DEVID_EGPU_CONNECTED, 760 714 "Show the eGPU connection status"); 715 + ASUS_ATTR_GROUP_ROG_TUNABLE(ppt_pl1_spl, ATTR_PPT_PL1_SPL, ASUS_WMI_DEVID_PPT_PL1_SPL, 716 + "Set the CPU slow package limit"); 717 + ASUS_ATTR_GROUP_ROG_TUNABLE(ppt_pl2_sppt, ATTR_PPT_PL2_SPPT, ASUS_WMI_DEVID_PPT_PL2_SPPT, 718 + "Set the CPU fast package limit"); 719 + ASUS_ATTR_GROUP_ROG_TUNABLE(ppt_pl3_fppt, ATTR_PPT_PL3_FPPT, ASUS_WMI_DEVID_PPT_PL3_FPPT, 720 + "Set the CPU fastest package limit"); 721 + ASUS_ATTR_GROUP_ROG_TUNABLE(ppt_apu_sppt, ATTR_PPT_APU_SPPT, ASUS_WMI_DEVID_PPT_APU_SPPT, 722 + "Set the APU package limit"); 723 + ASUS_ATTR_GROUP_ROG_TUNABLE(ppt_platform_sppt, ATTR_PPT_PLATFORM_SPPT, ASUS_WMI_DEVID_PPT_PLAT_SPPT, 724 + "Set the platform package limit"); 725 + ASUS_ATTR_GROUP_ROG_TUNABLE(nv_dynamic_boost, ATTR_NV_DYNAMIC_BOOST, ASUS_WMI_DEVID_NV_DYN_BOOST, 726 + "Set the Nvidia dynamic boost limit"); 727 + ASUS_ATTR_GROUP_ROG_TUNABLE(nv_temp_target, ATTR_NV_TEMP_TARGET, ASUS_WMI_DEVID_NV_THERM_TARGET, 728 + "Set the Nvidia max thermal limit"); 729 + ASUS_ATTR_GROUP_ROG_TUNABLE(nv_tgp, "nv_tgp", ASUS_WMI_DEVID_DGPU_SET_TGP, 730 + "Set the additional TGP on top of the base TGP"); 731 + ASUS_ATTR_GROUP_INT_VALUE_ONLY_RO(nv_base_tgp, ATTR_NV_BASE_TGP, ASUS_WMI_DEVID_DGPU_BASE_TGP, 732 + "Read the base TGP value"); 761 733 762 734 /* If an attribute does not require any special case handling add it here */ 763 735 static const struct asus_attr_group armoury_attr_groups[] = { ··· 783 719 { &egpu_enable_attr_group, ASUS_WMI_DEVID_EGPU }, 784 720 { &dgpu_disable_attr_group, ASUS_WMI_DEVID_DGPU }, 785 721 { &apu_mem_attr_group, ASUS_WMI_DEVID_APU_MEM }, 722 + 723 + { &ppt_pl1_spl_attr_group, ASUS_WMI_DEVID_PPT_PL1_SPL }, 724 + { &ppt_pl2_sppt_attr_group, ASUS_WMI_DEVID_PPT_PL2_SPPT }, 725 + { &ppt_pl3_fppt_attr_group, ASUS_WMI_DEVID_PPT_PL3_FPPT }, 726 + { &ppt_apu_sppt_attr_group, ASUS_WMI_DEVID_PPT_APU_SPPT }, 727 + { &ppt_platform_sppt_attr_group, ASUS_WMI_DEVID_PPT_PLAT_SPPT }, 728 + { &nv_dynamic_boost_attr_group, ASUS_WMI_DEVID_NV_DYN_BOOST }, 729 + { &nv_temp_target_attr_group, ASUS_WMI_DEVID_NV_THERM_TARGET }, 730 + { &nv_base_tgp_attr_group, ASUS_WMI_DEVID_DGPU_BASE_TGP }, 731 + { &nv_tgp_attr_group, ASUS_WMI_DEVID_DGPU_SET_TGP }, 786 732 787 733 { &charge_mode_attr_group, ASUS_WMI_DEVID_CHARGE_MODE }, 788 734 { &boot_sound_attr_group, ASUS_WMI_DEVID_BOOT_SOUND }, ··· 802 728 { &screen_auto_brightness_attr_group, ASUS_WMI_DEVID_SCREEN_AUTO_BRIGHTNESS }, 803 729 }; 804 730 731 + /** 732 + * is_power_tunable_attr - Determines if an attribute is a power-related tunable 733 + * @name: The name of the attribute to check 734 + * 735 + * This function checks if the given attribute name is related to power tuning. 736 + * 737 + * Return: true if the attribute is a power-related tunable, false otherwise 738 + */ 739 + static bool is_power_tunable_attr(const char *name) 740 + { 741 + static const char * const power_tunable_attrs[] = { 742 + ATTR_PPT_PL1_SPL, ATTR_PPT_PL2_SPPT, 743 + ATTR_PPT_PL3_FPPT, ATTR_PPT_APU_SPPT, 744 + ATTR_PPT_PLATFORM_SPPT, ATTR_NV_DYNAMIC_BOOST, 745 + ATTR_NV_TEMP_TARGET, ATTR_NV_BASE_TGP, 746 + ATTR_NV_TGP 747 + }; 748 + 749 + for (unsigned int i = 0; i < ARRAY_SIZE(power_tunable_attrs); i++) { 750 + if (!strcmp(name, power_tunable_attrs[i])) 751 + return true; 752 + } 753 + 754 + return false; 755 + } 756 + 757 + /** 758 + * has_valid_limit - Checks if a power-related attribute has a valid limit value 759 + * @name: The name of the attribute to check 760 + * @limits: Pointer to the power_limits structure containing limit values 761 + * 762 + * This function checks if a power-related attribute has a valid limit value. 763 + * It returns false if limits is NULL or if the corresponding limit value is zero. 764 + * 765 + * Return: true if the attribute has a valid limit value, false otherwise 766 + */ 767 + static bool has_valid_limit(const char *name, const struct power_limits *limits) 768 + { 769 + u32 limit_value = 0; 770 + 771 + if (!limits) 772 + return false; 773 + 774 + if (!strcmp(name, ATTR_PPT_PL1_SPL)) 775 + limit_value = limits->ppt_pl1_spl_max; 776 + else if (!strcmp(name, ATTR_PPT_PL2_SPPT)) 777 + limit_value = limits->ppt_pl2_sppt_max; 778 + else if (!strcmp(name, ATTR_PPT_PL3_FPPT)) 779 + limit_value = limits->ppt_pl3_fppt_max; 780 + else if (!strcmp(name, ATTR_PPT_APU_SPPT)) 781 + limit_value = limits->ppt_apu_sppt_max; 782 + else if (!strcmp(name, ATTR_PPT_PLATFORM_SPPT)) 783 + limit_value = limits->ppt_platform_sppt_max; 784 + else if (!strcmp(name, ATTR_NV_DYNAMIC_BOOST)) 785 + limit_value = limits->nv_dynamic_boost_max; 786 + else if (!strcmp(name, ATTR_NV_TEMP_TARGET)) 787 + limit_value = limits->nv_temp_target_max; 788 + else if (!strcmp(name, ATTR_NV_BASE_TGP) || 789 + !strcmp(name, ATTR_NV_TGP)) 790 + limit_value = limits->nv_tgp_max; 791 + 792 + return limit_value > 0; 793 + } 794 + 805 795 static int asus_fw_attr_add(void) 806 796 { 797 + const struct rog_tunables *const ac_rog_tunables = asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC]; 798 + const struct power_limits *limits; 799 + bool should_create; 800 + const char *name; 807 801 int err, i; 808 802 809 803 asus_armoury.fw_attr_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0), ··· 928 786 if (!armoury_has_devstate(armoury_attr_groups[i].wmi_devid)) 929 787 continue; 930 788 931 - err = sysfs_create_group(&asus_armoury.fw_attr_kset->kobj, 932 - armoury_attr_groups[i].attr_group); 933 - if (err) { 934 - pr_err("Failed to create sysfs-group for %s\n", 935 - armoury_attr_groups[i].attr_group->name); 936 - goto err_remove_groups; 789 + /* Always create by default, unless PPT is not present */ 790 + should_create = true; 791 + name = armoury_attr_groups[i].attr_group->name; 792 + 793 + /* Check if this is a power-related tunable requiring limits */ 794 + if (ac_rog_tunables && ac_rog_tunables->power_limits && 795 + is_power_tunable_attr(name)) { 796 + limits = ac_rog_tunables->power_limits; 797 + /* Check only AC: if not present then DC won't be either */ 798 + should_create = has_valid_limit(name, limits); 799 + if (!should_create) 800 + pr_debug("Missing max value for tunable %s\n", name); 801 + } 802 + 803 + if (should_create) { 804 + err = sysfs_create_group(&asus_armoury.fw_attr_kset->kobj, 805 + armoury_attr_groups[i].attr_group); 806 + if (err) { 807 + pr_err("Failed to create sysfs-group for %s\n", 808 + armoury_attr_groups[i].attr_group->name); 809 + goto err_remove_groups; 810 + } 937 811 } 938 812 } 939 813 ··· 978 820 979 821 /* Init / exit ****************************************************************/ 980 822 823 + /* Set up the min/max and defaults for ROG tunables */ 824 + static void init_rog_tunables(void) 825 + { 826 + const struct power_limits *ac_limits, *dc_limits; 827 + struct rog_tunables *ac_rog_tunables = NULL, *dc_rog_tunables = NULL; 828 + const struct power_data *power_data; 829 + const struct dmi_system_id *dmi_id; 830 + 831 + /* Match the system against the power_limits table */ 832 + dmi_id = dmi_first_match(power_limits); 833 + if (!dmi_id) { 834 + pr_warn("No matching power limits found for this system\n"); 835 + return; 836 + } 837 + 838 + /* Get the power data for this system */ 839 + power_data = dmi_id->driver_data; 840 + if (!power_data) { 841 + pr_info("No power data available for this system\n"); 842 + return; 843 + } 844 + 845 + /* Initialize AC power tunables */ 846 + ac_limits = power_data->ac_data; 847 + if (ac_limits) { 848 + ac_rog_tunables = kzalloc(sizeof(*asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC]), 849 + GFP_KERNEL); 850 + if (!ac_rog_tunables) 851 + goto err_nomem; 852 + 853 + asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC] = ac_rog_tunables; 854 + ac_rog_tunables->power_limits = ac_limits; 855 + 856 + /* Set initial AC values */ 857 + ac_rog_tunables->ppt_pl1_spl = 858 + ac_limits->ppt_pl1_spl_def ? 859 + ac_limits->ppt_pl1_spl_def : 860 + ac_limits->ppt_pl1_spl_max; 861 + 862 + ac_rog_tunables->ppt_pl2_sppt = 863 + ac_limits->ppt_pl2_sppt_def ? 864 + ac_limits->ppt_pl2_sppt_def : 865 + ac_limits->ppt_pl2_sppt_max; 866 + 867 + ac_rog_tunables->ppt_pl3_fppt = 868 + ac_limits->ppt_pl3_fppt_def ? 869 + ac_limits->ppt_pl3_fppt_def : 870 + ac_limits->ppt_pl3_fppt_max; 871 + 872 + ac_rog_tunables->ppt_apu_sppt = 873 + ac_limits->ppt_apu_sppt_def ? 874 + ac_limits->ppt_apu_sppt_def : 875 + ac_limits->ppt_apu_sppt_max; 876 + 877 + ac_rog_tunables->ppt_platform_sppt = 878 + ac_limits->ppt_platform_sppt_def ? 879 + ac_limits->ppt_platform_sppt_def : 880 + ac_limits->ppt_platform_sppt_max; 881 + 882 + ac_rog_tunables->nv_dynamic_boost = 883 + ac_limits->nv_dynamic_boost_max; 884 + ac_rog_tunables->nv_temp_target = 885 + ac_limits->nv_temp_target_max; 886 + ac_rog_tunables->nv_tgp = ac_limits->nv_tgp_max; 887 + 888 + pr_debug("AC power limits initialized for %s\n", dmi_id->matches[0].substr); 889 + } else { 890 + pr_debug("No AC PPT limits defined\n"); 891 + } 892 + 893 + /* Initialize DC power tunables */ 894 + dc_limits = power_data->dc_data; 895 + if (dc_limits) { 896 + dc_rog_tunables = kzalloc(sizeof(*asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC]), 897 + GFP_KERNEL); 898 + if (!dc_rog_tunables) { 899 + kfree(ac_rog_tunables); 900 + goto err_nomem; 901 + } 902 + 903 + asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC] = dc_rog_tunables; 904 + dc_rog_tunables->power_limits = dc_limits; 905 + 906 + /* Set initial DC values */ 907 + dc_rog_tunables->ppt_pl1_spl = 908 + dc_limits->ppt_pl1_spl_def ? 909 + dc_limits->ppt_pl1_spl_def : 910 + dc_limits->ppt_pl1_spl_max; 911 + 912 + dc_rog_tunables->ppt_pl2_sppt = 913 + dc_limits->ppt_pl2_sppt_def ? 914 + dc_limits->ppt_pl2_sppt_def : 915 + dc_limits->ppt_pl2_sppt_max; 916 + 917 + dc_rog_tunables->ppt_pl3_fppt = 918 + dc_limits->ppt_pl3_fppt_def ? 919 + dc_limits->ppt_pl3_fppt_def : 920 + dc_limits->ppt_pl3_fppt_max; 921 + 922 + dc_rog_tunables->ppt_apu_sppt = 923 + dc_limits->ppt_apu_sppt_def ? 924 + dc_limits->ppt_apu_sppt_def : 925 + dc_limits->ppt_apu_sppt_max; 926 + 927 + dc_rog_tunables->ppt_platform_sppt = 928 + dc_limits->ppt_platform_sppt_def ? 929 + dc_limits->ppt_platform_sppt_def : 930 + dc_limits->ppt_platform_sppt_max; 931 + 932 + dc_rog_tunables->nv_dynamic_boost = 933 + dc_limits->nv_dynamic_boost_max; 934 + dc_rog_tunables->nv_temp_target = 935 + dc_limits->nv_temp_target_max; 936 + dc_rog_tunables->nv_tgp = dc_limits->nv_tgp_max; 937 + 938 + pr_debug("DC power limits initialized for %s\n", dmi_id->matches[0].substr); 939 + } else { 940 + pr_debug("No DC PPT limits defined\n"); 941 + } 942 + 943 + return; 944 + 945 + err_nomem: 946 + pr_err("Failed to allocate memory for tunables\n"); 947 + } 948 + 981 949 static int __init asus_fw_init(void) 982 950 { 983 951 char *wmi_uid; ··· 1119 835 if (!strcmp(wmi_uid, ASUS_ACPI_UID_ASUSWMI)) 1120 836 return -ENODEV; 1121 837 838 + init_rog_tunables(); 839 + 840 + /* Must always be last step to ensure data is available */ 1122 841 return asus_fw_attr_add(); 1123 842 } 1124 843 ··· 1144 857 sysfs_remove_file(&asus_armoury.fw_attr_kset->kobj, &pending_reboot.attr); 1145 858 kset_unregister(asus_armoury.fw_attr_kset); 1146 859 device_destroy(&firmware_attributes_class, MKDEV(0, 0)); 860 + 861 + kfree(asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC]); 862 + kfree(asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC]); 1147 863 } 1148 864 1149 865 module_init(asus_fw_init);
+1294
drivers/platform/x86/asus-armoury.h
··· 8 8 #ifndef _ASUS_ARMOURY_H_ 9 9 #define _ASUS_ARMOURY_H_ 10 10 11 + #include <linux/dmi.h> 11 12 #include <linux/platform_device.h> 12 13 #include <linux/sysfs.h> 13 14 #include <linux/types.h> ··· 197 196 static const struct attribute_group _attrname##_attr_group = { \ 198 197 .name = _fsname, .attrs = _attrname##_attrs \ 199 198 } 199 + 200 + #define ASUS_ATTR_GROUP_INT_VALUE_ONLY_RO(_attrname, _fsname, _wmi, _dispname) \ 201 + ASUS_WMI_SHOW_INT(_attrname##_current_value, _wmi); \ 202 + static struct kobj_attribute attr_##_attrname##_current_value = \ 203 + __ASUS_ATTR_RO(_attrname, current_value); \ 204 + __ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \ 205 + static struct kobj_attribute attr_##_attrname##_type = \ 206 + __ASUS_ATTR_RO_AS(type, int_type_show); \ 207 + static struct attribute *_attrname##_attrs[] = { \ 208 + &attr_##_attrname##_current_value.attr, \ 209 + &attr_##_attrname##_display_name.attr, \ 210 + &attr_##_attrname##_type.attr, NULL \ 211 + }; \ 212 + static const struct attribute_group _attrname##_attr_group = { \ 213 + .name = _fsname, .attrs = _attrname##_attrs \ 214 + } 215 + 216 + /* 217 + * ROG PPT attributes need a little different in setup as they 218 + * require rog_tunables members. 219 + */ 220 + 221 + #define __ROG_TUNABLE_SHOW(_prop, _attrname, _val) \ 222 + static ssize_t _attrname##_##_prop##_show( \ 223 + struct kobject *kobj, struct kobj_attribute *attr, char *buf) \ 224 + { \ 225 + struct rog_tunables *tunables = get_current_tunables(); \ 226 + \ 227 + if (!tunables || !tunables->power_limits) \ 228 + return -ENODEV; \ 229 + \ 230 + return sysfs_emit(buf, "%d\n", tunables->power_limits->_val); \ 231 + } \ 232 + static struct kobj_attribute attr_##_attrname##_##_prop = \ 233 + __ASUS_ATTR_RO(_attrname, _prop) 234 + 235 + #define __ROG_TUNABLE_SHOW_DEFAULT(_attrname) \ 236 + static ssize_t _attrname##_default_value_show( \ 237 + struct kobject *kobj, struct kobj_attribute *attr, char *buf) \ 238 + { \ 239 + struct rog_tunables *tunables = get_current_tunables(); \ 240 + \ 241 + if (!tunables || !tunables->power_limits) \ 242 + return -ENODEV; \ 243 + \ 244 + return sysfs_emit( \ 245 + buf, "%d\n", \ 246 + tunables->power_limits->_attrname##_def ? \ 247 + tunables->power_limits->_attrname##_def : \ 248 + tunables->power_limits->_attrname##_max); \ 249 + } \ 250 + static struct kobj_attribute attr_##_attrname##_default_value = \ 251 + __ASUS_ATTR_RO(_attrname, default_value) 252 + 253 + #define __ROG_TUNABLE_RW(_attr, _wmi) \ 254 + static ssize_t _attr##_current_value_store( \ 255 + struct kobject *kobj, struct kobj_attribute *attr, \ 256 + const char *buf, size_t count) \ 257 + { \ 258 + struct rog_tunables *tunables = get_current_tunables(); \ 259 + \ 260 + if (!tunables || !tunables->power_limits) \ 261 + return -ENODEV; \ 262 + \ 263 + if (tunables->power_limits->_attr##_min == \ 264 + tunables->power_limits->_attr##_max) \ 265 + return -EINVAL; \ 266 + \ 267 + return armoury_attr_uint_store(kobj, attr, buf, count, \ 268 + tunables->power_limits->_attr##_min, \ 269 + tunables->power_limits->_attr##_max, \ 270 + &tunables->_attr, _wmi); \ 271 + } \ 272 + static ssize_t _attr##_current_value_show( \ 273 + struct kobject *kobj, struct kobj_attribute *attr, char *buf) \ 274 + { \ 275 + struct rog_tunables *tunables = get_current_tunables(); \ 276 + \ 277 + if (!tunables) \ 278 + return -ENODEV; \ 279 + \ 280 + return sysfs_emit(buf, "%u\n", tunables->_attr); \ 281 + } \ 282 + static struct kobj_attribute attr_##_attr##_current_value = \ 283 + __ASUS_ATTR_RW(_attr, current_value) 284 + 285 + #define ASUS_ATTR_GROUP_ROG_TUNABLE(_attrname, _fsname, _wmi, _dispname) \ 286 + __ROG_TUNABLE_RW(_attrname, _wmi); \ 287 + __ROG_TUNABLE_SHOW_DEFAULT(_attrname); \ 288 + __ROG_TUNABLE_SHOW(min_value, _attrname, _attrname##_min); \ 289 + __ROG_TUNABLE_SHOW(max_value, _attrname, _attrname##_max); \ 290 + __ATTR_SHOW_FMT(scalar_increment, _attrname, "%d\n", 1); \ 291 + __ATTR_SHOW_FMT(display_name, _attrname, "%s\n", _dispname); \ 292 + static struct kobj_attribute attr_##_attrname##_type = \ 293 + __ASUS_ATTR_RO_AS(type, int_type_show); \ 294 + static struct attribute *_attrname##_attrs[] = { \ 295 + &attr_##_attrname##_current_value.attr, \ 296 + &attr_##_attrname##_default_value.attr, \ 297 + &attr_##_attrname##_min_value.attr, \ 298 + &attr_##_attrname##_max_value.attr, \ 299 + &attr_##_attrname##_scalar_increment.attr, \ 300 + &attr_##_attrname##_display_name.attr, \ 301 + &attr_##_attrname##_type.attr, \ 302 + NULL \ 303 + }; \ 304 + static const struct attribute_group _attrname##_attr_group = { \ 305 + .name = _fsname, .attrs = _attrname##_attrs \ 306 + } 307 + 308 + /* Default is always the maximum value unless *_def is specified */ 309 + struct power_limits { 310 + u8 ppt_pl1_spl_min; 311 + u8 ppt_pl1_spl_def; 312 + u8 ppt_pl1_spl_max; 313 + u8 ppt_pl2_sppt_min; 314 + u8 ppt_pl2_sppt_def; 315 + u8 ppt_pl2_sppt_max; 316 + u8 ppt_pl3_fppt_min; 317 + u8 ppt_pl3_fppt_def; 318 + u8 ppt_pl3_fppt_max; 319 + u8 ppt_apu_sppt_min; 320 + u8 ppt_apu_sppt_def; 321 + u8 ppt_apu_sppt_max; 322 + u8 ppt_platform_sppt_min; 323 + u8 ppt_platform_sppt_def; 324 + u8 ppt_platform_sppt_max; 325 + /* Nvidia GPU specific, default is always max */ 326 + u8 nv_dynamic_boost_def; // unused. exists for macro 327 + u8 nv_dynamic_boost_min; 328 + u8 nv_dynamic_boost_max; 329 + u8 nv_temp_target_def; // unused. exists for macro 330 + u8 nv_temp_target_min; 331 + u8 nv_temp_target_max; 332 + u8 nv_tgp_def; // unused. exists for macro 333 + u8 nv_tgp_min; 334 + u8 nv_tgp_max; 335 + }; 336 + 337 + struct power_data { 338 + const struct power_limits *ac_data; 339 + const struct power_limits *dc_data; 340 + bool requires_fan_curve; 341 + }; 342 + 343 + /* 344 + * For each available attribute there must be a min and a max. 345 + * _def is not required and will be assumed to be default == max if missing. 346 + */ 347 + static const struct dmi_system_id power_limits[] = { 348 + { 349 + .matches = { 350 + DMI_MATCH(DMI_BOARD_NAME, "FA401W"), 351 + }, 352 + .driver_data = &(struct power_data) { 353 + .ac_data = &(struct power_limits) { 354 + .ppt_pl1_spl_min = 15, 355 + .ppt_pl1_spl_max = 80, 356 + .ppt_pl2_sppt_min = 35, 357 + .ppt_pl2_sppt_max = 80, 358 + .ppt_pl3_fppt_min = 35, 359 + .ppt_pl3_fppt_max = 80, 360 + .nv_dynamic_boost_min = 5, 361 + .nv_dynamic_boost_max = 25, 362 + .nv_temp_target_min = 75, 363 + .nv_temp_target_max = 87, 364 + .nv_tgp_min = 55, 365 + .nv_tgp_max = 75, 366 + }, 367 + .dc_data = &(struct power_limits) { 368 + .ppt_pl1_spl_min = 25, 369 + .ppt_pl1_spl_max = 30, 370 + .ppt_pl2_sppt_min = 31, 371 + .ppt_pl2_sppt_max = 44, 372 + .ppt_pl3_fppt_min = 45, 373 + .ppt_pl3_fppt_max = 65, 374 + .nv_temp_target_min = 75, 375 + .nv_temp_target_max = 87, 376 + }, 377 + }, 378 + }, 379 + { 380 + .matches = { 381 + DMI_MATCH(DMI_BOARD_NAME, "FA507N"), 382 + }, 383 + .driver_data = &(struct power_data) { 384 + .ac_data = &(struct power_limits) { 385 + .ppt_pl1_spl_min = 15, 386 + .ppt_pl1_spl_max = 80, 387 + .ppt_pl2_sppt_min = 35, 388 + .ppt_pl2_sppt_max = 80, 389 + .ppt_pl3_fppt_min = 35, 390 + .ppt_pl3_fppt_max = 80, 391 + .nv_dynamic_boost_min = 5, 392 + .nv_dynamic_boost_max = 25, 393 + .nv_temp_target_min = 75, 394 + .nv_temp_target_max = 87, 395 + }, 396 + .dc_data = &(struct power_limits) { 397 + .ppt_pl1_spl_min = 15, 398 + .ppt_pl1_spl_def = 45, 399 + .ppt_pl1_spl_max = 65, 400 + .ppt_pl2_sppt_min = 35, 401 + .ppt_pl2_sppt_def = 54, 402 + .ppt_pl2_sppt_max = 65, 403 + .ppt_pl3_fppt_min = 35, 404 + .ppt_pl3_fppt_max = 65, 405 + .nv_temp_target_min = 75, 406 + .nv_temp_target_max = 87, 407 + }, 408 + }, 409 + }, 410 + { 411 + .matches = { 412 + DMI_MATCH(DMI_BOARD_NAME, "FA507R"), 413 + }, 414 + .driver_data = &(struct power_data) { 415 + .ac_data = &(struct power_limits) { 416 + .ppt_pl1_spl_min = 15, 417 + .ppt_pl1_spl_max = 80, 418 + .ppt_pl2_sppt_min = 25, 419 + .ppt_pl2_sppt_max = 80, 420 + .ppt_pl3_fppt_min = 35, 421 + .ppt_pl3_fppt_max = 80 422 + }, 423 + .dc_data = NULL, 424 + }, 425 + }, 426 + { 427 + .matches = { 428 + DMI_MATCH(DMI_BOARD_NAME, "FA507X"), 429 + }, 430 + .driver_data = &(struct power_data) { 431 + .ac_data = &(struct power_limits) { 432 + .ppt_pl1_spl_min = 15, 433 + .ppt_pl1_spl_max = 80, 434 + .ppt_pl2_sppt_min = 35, 435 + .ppt_pl2_sppt_max = 80, 436 + .ppt_pl3_fppt_min = 35, 437 + .ppt_pl3_fppt_max = 80, 438 + .nv_dynamic_boost_min = 5, 439 + .nv_dynamic_boost_max = 20, 440 + .nv_temp_target_min = 75, 441 + .nv_temp_target_max = 87, 442 + .nv_tgp_min = 55, 443 + .nv_tgp_max = 85, 444 + }, 445 + .dc_data = &(struct power_limits) { 446 + .ppt_pl1_spl_min = 15, 447 + .ppt_pl1_spl_def = 45, 448 + .ppt_pl1_spl_max = 65, 449 + .ppt_pl2_sppt_min = 35, 450 + .ppt_pl2_sppt_def = 54, 451 + .ppt_pl2_sppt_max = 65, 452 + .ppt_pl3_fppt_min = 35, 453 + .ppt_pl3_fppt_max = 65, 454 + .nv_temp_target_min = 75, 455 + .nv_temp_target_max = 87, 456 + }, 457 + }, 458 + }, 459 + { 460 + .matches = { 461 + DMI_MATCH(DMI_BOARD_NAME, "FA507Z"), 462 + }, 463 + .driver_data = &(struct power_data) { 464 + .ac_data = &(struct power_limits) { 465 + .ppt_pl1_spl_min = 28, 466 + .ppt_pl1_spl_max = 65, 467 + .ppt_pl2_sppt_min = 28, 468 + .ppt_pl2_sppt_max = 105, 469 + .nv_dynamic_boost_min = 5, 470 + .nv_dynamic_boost_max = 15, 471 + .nv_temp_target_min = 75, 472 + .nv_temp_target_max = 87, 473 + .nv_tgp_min = 55, 474 + .nv_tgp_max = 85, 475 + }, 476 + .dc_data = &(struct power_limits) { 477 + .ppt_pl1_spl_min = 25, 478 + .ppt_pl1_spl_max = 45, 479 + .ppt_pl2_sppt_min = 35, 480 + .ppt_pl2_sppt_max = 60, 481 + .nv_temp_target_min = 75, 482 + .nv_temp_target_max = 87, 483 + }, 484 + }, 485 + }, 486 + { 487 + .matches = { 488 + DMI_MATCH(DMI_BOARD_NAME, "FA607P"), 489 + }, 490 + .driver_data = &(struct power_data) { 491 + .ac_data = &(struct power_limits) { 492 + .ppt_pl1_spl_min = 30, 493 + .ppt_pl1_spl_def = 100, 494 + .ppt_pl1_spl_max = 135, 495 + .ppt_pl2_sppt_min = 30, 496 + .ppt_pl2_sppt_def = 115, 497 + .ppt_pl2_sppt_max = 135, 498 + .ppt_pl3_fppt_min = 30, 499 + .ppt_pl3_fppt_max = 135, 500 + .nv_dynamic_boost_min = 5, 501 + .nv_dynamic_boost_max = 25, 502 + .nv_temp_target_min = 75, 503 + .nv_temp_target_max = 87, 504 + .nv_tgp_min = 55, 505 + .nv_tgp_max = 115, 506 + }, 507 + .dc_data = &(struct power_limits) { 508 + .ppt_pl1_spl_min = 25, 509 + .ppt_pl1_spl_def = 45, 510 + .ppt_pl1_spl_max = 80, 511 + .ppt_pl2_sppt_min = 25, 512 + .ppt_pl2_sppt_def = 60, 513 + .ppt_pl2_sppt_max = 80, 514 + .ppt_pl3_fppt_min = 25, 515 + .ppt_pl3_fppt_max = 80, 516 + .nv_temp_target_min = 75, 517 + .nv_temp_target_max = 87, 518 + }, 519 + }, 520 + }, 521 + { 522 + .matches = { 523 + DMI_MATCH(DMI_BOARD_NAME, "FA608WI"), 524 + }, 525 + .driver_data = &(struct power_data) { 526 + .ac_data = &(struct power_limits) { 527 + .ppt_pl1_spl_min = 15, 528 + .ppt_pl1_spl_def = 90, 529 + .ppt_pl1_spl_max = 90, 530 + .ppt_pl2_sppt_min = 35, 531 + .ppt_pl2_sppt_def = 90, 532 + .ppt_pl2_sppt_max = 90, 533 + .ppt_pl3_fppt_min = 35, 534 + .ppt_pl3_fppt_def = 90, 535 + .ppt_pl3_fppt_max = 90, 536 + .nv_dynamic_boost_min = 5, 537 + .nv_dynamic_boost_max = 25, 538 + .nv_temp_target_min = 75, 539 + .nv_temp_target_max = 87, 540 + .nv_tgp_min = 55, 541 + .nv_tgp_max = 115, 542 + }, 543 + .dc_data = &(struct power_limits) { 544 + .ppt_pl1_spl_min = 15, 545 + .ppt_pl1_spl_def = 45, 546 + .ppt_pl1_spl_max = 65, 547 + .ppt_pl2_sppt_min = 35, 548 + .ppt_pl2_sppt_def = 54, 549 + .ppt_pl2_sppt_max = 65, 550 + .ppt_pl3_fppt_min = 35, 551 + .ppt_pl3_fppt_def = 65, 552 + .ppt_pl3_fppt_max = 65, 553 + .nv_temp_target_min = 75, 554 + .nv_temp_target_max = 87, 555 + }, 556 + }, 557 + }, 558 + { 559 + .matches = { 560 + DMI_MATCH(DMI_BOARD_NAME, "FA617NS"), 561 + }, 562 + .driver_data = &(struct power_data) { 563 + .ac_data = &(struct power_limits) { 564 + .ppt_apu_sppt_min = 15, 565 + .ppt_apu_sppt_max = 80, 566 + .ppt_platform_sppt_min = 30, 567 + .ppt_platform_sppt_max = 120, 568 + }, 569 + .dc_data = &(struct power_limits) { 570 + .ppt_apu_sppt_min = 25, 571 + .ppt_apu_sppt_max = 35, 572 + .ppt_platform_sppt_min = 45, 573 + .ppt_platform_sppt_max = 100, 574 + }, 575 + }, 576 + }, 577 + { 578 + .matches = { 579 + DMI_MATCH(DMI_BOARD_NAME, "FA617NT"), 580 + }, 581 + .driver_data = &(struct power_data) { 582 + .ac_data = &(struct power_limits) { 583 + .ppt_apu_sppt_min = 15, 584 + .ppt_apu_sppt_max = 80, 585 + .ppt_platform_sppt_min = 30, 586 + .ppt_platform_sppt_max = 115, 587 + }, 588 + .dc_data = &(struct power_limits) { 589 + .ppt_apu_sppt_min = 15, 590 + .ppt_apu_sppt_max = 45, 591 + .ppt_platform_sppt_min = 30, 592 + .ppt_platform_sppt_max = 50, 593 + }, 594 + }, 595 + }, 596 + { 597 + .matches = { 598 + DMI_MATCH(DMI_BOARD_NAME, "FA617XS"), 599 + }, 600 + .driver_data = &(struct power_data) { 601 + .ac_data = &(struct power_limits) { 602 + .ppt_apu_sppt_min = 15, 603 + .ppt_apu_sppt_max = 80, 604 + .ppt_platform_sppt_min = 30, 605 + .ppt_platform_sppt_max = 120, 606 + .nv_temp_target_min = 75, 607 + .nv_temp_target_max = 87, 608 + }, 609 + .dc_data = &(struct power_limits) { 610 + .ppt_apu_sppt_min = 25, 611 + .ppt_apu_sppt_max = 35, 612 + .ppt_platform_sppt_min = 45, 613 + .ppt_platform_sppt_max = 100, 614 + .nv_temp_target_min = 75, 615 + .nv_temp_target_max = 87, 616 + }, 617 + }, 618 + }, 619 + { 620 + .matches = { 621 + DMI_MATCH(DMI_BOARD_NAME, "FX507VI"), 622 + }, 623 + .driver_data = &(struct power_data) { 624 + .ac_data = &(struct power_limits) { 625 + .ppt_pl1_spl_min = 28, 626 + .ppt_pl1_spl_max = 135, 627 + .ppt_pl2_sppt_min = 28, 628 + .ppt_pl2_sppt_max = 135, 629 + .nv_dynamic_boost_min = 5, 630 + .nv_dynamic_boost_max = 25, 631 + .nv_temp_target_min = 75, 632 + .nv_temp_target_max = 87, 633 + }, 634 + .dc_data = &(struct power_limits) { 635 + .ppt_pl1_spl_min = 25, 636 + .ppt_pl1_spl_max = 45, 637 + .ppt_pl2_sppt_min = 35, 638 + .ppt_pl2_sppt_max = 60, 639 + .nv_temp_target_min = 75, 640 + .nv_temp_target_max = 87, 641 + }, 642 + .requires_fan_curve = true, 643 + }, 644 + }, 645 + { 646 + .matches = { 647 + DMI_MATCH(DMI_BOARD_NAME, "FX507VV"), 648 + }, 649 + .driver_data = &(struct power_data) { 650 + .ac_data = &(struct power_limits) { 651 + .ppt_pl1_spl_min = 28, 652 + .ppt_pl1_spl_def = 115, 653 + .ppt_pl1_spl_max = 135, 654 + .ppt_pl2_sppt_min = 28, 655 + .ppt_pl2_sppt_max = 135, 656 + .nv_dynamic_boost_min = 5, 657 + .nv_dynamic_boost_max = 25, 658 + .nv_temp_target_min = 75, 659 + .nv_temp_target_max = 87, 660 + }, 661 + .dc_data = &(struct power_limits) { 662 + .ppt_pl1_spl_min = 25, 663 + .ppt_pl1_spl_max = 45, 664 + .ppt_pl2_sppt_min = 35, 665 + .ppt_pl2_sppt_max = 60, 666 + .nv_temp_target_min = 75, 667 + .nv_temp_target_max = 87, 668 + }, 669 + .requires_fan_curve = true, 670 + }, 671 + }, 672 + { 673 + .matches = { 674 + DMI_MATCH(DMI_BOARD_NAME, "FX507Z"), 675 + }, 676 + .driver_data = &(struct power_data) { 677 + .ac_data = &(struct power_limits) { 678 + .ppt_pl1_spl_min = 28, 679 + .ppt_pl1_spl_max = 90, 680 + .ppt_pl2_sppt_min = 28, 681 + .ppt_pl2_sppt_max = 135, 682 + .nv_dynamic_boost_min = 5, 683 + .nv_dynamic_boost_max = 15, 684 + }, 685 + .dc_data = &(struct power_limits) { 686 + .ppt_pl1_spl_min = 25, 687 + .ppt_pl1_spl_max = 45, 688 + .ppt_pl2_sppt_min = 35, 689 + .ppt_pl2_sppt_max = 60, 690 + }, 691 + .requires_fan_curve = true, 692 + }, 693 + }, 694 + { 695 + .matches = { 696 + DMI_MATCH(DMI_BOARD_NAME, "GA401Q"), 697 + }, 698 + .driver_data = &(struct power_data) { 699 + .ac_data = &(struct power_limits) { 700 + .ppt_pl1_spl_min = 15, 701 + .ppt_pl1_spl_max = 80, 702 + .ppt_pl2_sppt_min = 15, 703 + .ppt_pl2_sppt_max = 80, 704 + }, 705 + .dc_data = NULL, 706 + }, 707 + }, 708 + { 709 + .matches = { 710 + // This model is full AMD. No Nvidia dGPU. 711 + DMI_MATCH(DMI_BOARD_NAME, "GA402R"), 712 + }, 713 + .driver_data = &(struct power_data) { 714 + .ac_data = &(struct power_limits) { 715 + .ppt_apu_sppt_min = 15, 716 + .ppt_apu_sppt_max = 80, 717 + .ppt_platform_sppt_min = 30, 718 + .ppt_platform_sppt_max = 115, 719 + }, 720 + .dc_data = &(struct power_limits) { 721 + .ppt_apu_sppt_min = 25, 722 + .ppt_apu_sppt_def = 30, 723 + .ppt_apu_sppt_max = 45, 724 + .ppt_platform_sppt_min = 40, 725 + .ppt_platform_sppt_max = 60, 726 + }, 727 + }, 728 + }, 729 + { 730 + .matches = { 731 + DMI_MATCH(DMI_BOARD_NAME, "GA402X"), 732 + }, 733 + .driver_data = &(struct power_data) { 734 + .ac_data = &(struct power_limits) { 735 + .ppt_pl1_spl_min = 15, 736 + .ppt_pl1_spl_def = 35, 737 + .ppt_pl1_spl_max = 80, 738 + .ppt_pl2_sppt_min = 25, 739 + .ppt_pl2_sppt_def = 65, 740 + .ppt_pl2_sppt_max = 80, 741 + .ppt_pl3_fppt_min = 35, 742 + .ppt_pl3_fppt_max = 80, 743 + .nv_temp_target_min = 75, 744 + .nv_temp_target_max = 87, 745 + }, 746 + .dc_data = &(struct power_limits) { 747 + .ppt_pl1_spl_min = 15, 748 + .ppt_pl1_spl_max = 35, 749 + .ppt_pl2_sppt_min = 25, 750 + .ppt_pl2_sppt_max = 35, 751 + .ppt_pl3_fppt_min = 35, 752 + .ppt_pl3_fppt_max = 65, 753 + .nv_temp_target_min = 75, 754 + .nv_temp_target_max = 87, 755 + }, 756 + .requires_fan_curve = true, 757 + }, 758 + }, 759 + { 760 + .matches = { 761 + DMI_MATCH(DMI_BOARD_NAME, "GA403U"), 762 + }, 763 + .driver_data = &(struct power_data) { 764 + .ac_data = &(struct power_limits) { 765 + .ppt_pl1_spl_min = 15, 766 + .ppt_pl1_spl_max = 80, 767 + .ppt_pl2_sppt_min = 25, 768 + .ppt_pl2_sppt_max = 80, 769 + .ppt_pl3_fppt_min = 35, 770 + .ppt_pl3_fppt_max = 80, 771 + .nv_dynamic_boost_min = 5, 772 + .nv_dynamic_boost_max = 25, 773 + .nv_temp_target_min = 75, 774 + .nv_temp_target_max = 87, 775 + .nv_tgp_min = 55, 776 + .nv_tgp_max = 65, 777 + }, 778 + .dc_data = &(struct power_limits) { 779 + .ppt_pl1_spl_min = 15, 780 + .ppt_pl1_spl_max = 35, 781 + .ppt_pl2_sppt_min = 25, 782 + .ppt_pl2_sppt_max = 35, 783 + .ppt_pl3_fppt_min = 35, 784 + .ppt_pl3_fppt_max = 65, 785 + .nv_temp_target_min = 75, 786 + .nv_temp_target_max = 87, 787 + }, 788 + .requires_fan_curve = true, 789 + }, 790 + }, 791 + { 792 + .matches = { 793 + DMI_MATCH(DMI_BOARD_NAME, "GA503R"), 794 + }, 795 + .driver_data = &(struct power_data) { 796 + .ac_data = &(struct power_limits) { 797 + .ppt_pl1_spl_min = 15, 798 + .ppt_pl1_spl_def = 35, 799 + .ppt_pl1_spl_max = 80, 800 + .ppt_pl2_sppt_min = 35, 801 + .ppt_pl2_sppt_def = 65, 802 + .ppt_pl2_sppt_max = 80, 803 + .ppt_pl3_fppt_min = 35, 804 + .ppt_pl3_fppt_max = 80, 805 + .nv_dynamic_boost_min = 5, 806 + .nv_dynamic_boost_max = 20, 807 + .nv_temp_target_min = 75, 808 + .nv_temp_target_max = 87, 809 + }, 810 + .dc_data = &(struct power_limits) { 811 + .ppt_pl1_spl_min = 15, 812 + .ppt_pl1_spl_def = 25, 813 + .ppt_pl1_spl_max = 65, 814 + .ppt_pl2_sppt_min = 35, 815 + .ppt_pl2_sppt_def = 54, 816 + .ppt_pl2_sppt_max = 60, 817 + .ppt_pl3_fppt_min = 35, 818 + .ppt_pl3_fppt_max = 65, 819 + }, 820 + }, 821 + }, 822 + { 823 + .matches = { 824 + DMI_MATCH(DMI_BOARD_NAME, "GA605W"), 825 + }, 826 + .driver_data = &(struct power_data) { 827 + .ac_data = &(struct power_limits) { 828 + .ppt_pl1_spl_min = 15, 829 + .ppt_pl1_spl_max = 80, 830 + .ppt_pl2_sppt_min = 35, 831 + .ppt_pl2_sppt_max = 80, 832 + .ppt_pl3_fppt_min = 35, 833 + .ppt_pl3_fppt_max = 80, 834 + .nv_dynamic_boost_min = 5, 835 + .nv_dynamic_boost_max = 20, 836 + .nv_temp_target_min = 75, 837 + .nv_temp_target_max = 87, 838 + .nv_tgp_min = 55, 839 + .nv_tgp_max = 85, 840 + }, 841 + .dc_data = &(struct power_limits) { 842 + .ppt_pl1_spl_min = 25, 843 + .ppt_pl1_spl_max = 35, 844 + .ppt_pl2_sppt_min = 31, 845 + .ppt_pl2_sppt_max = 44, 846 + .ppt_pl3_fppt_min = 45, 847 + .ppt_pl3_fppt_max = 65, 848 + .nv_temp_target_min = 75, 849 + .nv_temp_target_max = 87, 850 + }, 851 + .requires_fan_curve = true, 852 + }, 853 + }, 854 + { 855 + .matches = { 856 + DMI_MATCH(DMI_BOARD_NAME, "GU603Z"), 857 + }, 858 + .driver_data = &(struct power_data) { 859 + .ac_data = &(struct power_limits) { 860 + .ppt_pl1_spl_min = 25, 861 + .ppt_pl1_spl_max = 60, 862 + .ppt_pl2_sppt_min = 25, 863 + .ppt_pl2_sppt_max = 135, 864 + .nv_dynamic_boost_min = 5, 865 + .nv_dynamic_boost_max = 20, 866 + .nv_temp_target_min = 75, 867 + .nv_temp_target_max = 87, 868 + }, 869 + .dc_data = &(struct power_limits) { 870 + .ppt_pl1_spl_min = 25, 871 + .ppt_pl1_spl_max = 40, 872 + .ppt_pl2_sppt_min = 25, 873 + .ppt_pl2_sppt_max = 40, 874 + .nv_temp_target_min = 75, 875 + .nv_temp_target_max = 87, 876 + } 877 + }, 878 + }, 879 + { 880 + .matches = { 881 + DMI_MATCH(DMI_BOARD_NAME, "GU604V"), 882 + }, 883 + .driver_data = &(struct power_data) { 884 + .ac_data = &(struct power_limits) { 885 + .ppt_pl1_spl_min = 65, 886 + .ppt_pl1_spl_max = 120, 887 + .ppt_pl2_sppt_min = 65, 888 + .ppt_pl2_sppt_max = 150, 889 + .nv_dynamic_boost_min = 5, 890 + .nv_dynamic_boost_max = 25, 891 + .nv_temp_target_min = 75, 892 + .nv_temp_target_max = 87, 893 + }, 894 + .dc_data = &(struct power_limits) { 895 + .ppt_pl1_spl_min = 25, 896 + .ppt_pl1_spl_max = 40, 897 + .ppt_pl2_sppt_min = 35, 898 + .ppt_pl2_sppt_def = 40, 899 + .ppt_pl2_sppt_max = 60, 900 + .nv_temp_target_min = 75, 901 + .nv_temp_target_max = 87, 902 + }, 903 + }, 904 + }, 905 + { 906 + .matches = { 907 + DMI_MATCH(DMI_BOARD_NAME, "GU605CW"), 908 + }, 909 + .driver_data = &(struct power_data) { 910 + .ac_data = &(struct power_limits) { 911 + .ppt_pl1_spl_min = 45, 912 + .ppt_pl1_spl_max = 85, 913 + .ppt_pl2_sppt_min = 56, 914 + .ppt_pl2_sppt_max = 110, 915 + .nv_dynamic_boost_min = 5, 916 + .nv_dynamic_boost_max = 20, 917 + .nv_temp_target_min = 75, 918 + .nv_temp_target_max = 87, 919 + .nv_tgp_min = 80, 920 + .nv_tgp_def = 90, 921 + .nv_tgp_max = 110, 922 + }, 923 + .dc_data = &(struct power_limits) { 924 + .ppt_pl1_spl_min = 25, 925 + .ppt_pl1_spl_max = 85, 926 + .ppt_pl2_sppt_min = 32, 927 + .ppt_pl2_sppt_max = 110, 928 + .nv_temp_target_min = 75, 929 + .nv_temp_target_max = 87, 930 + }, 931 + .requires_fan_curve = true, 932 + }, 933 + }, 934 + { 935 + .matches = { 936 + DMI_MATCH(DMI_BOARD_NAME, "GU605CX"), 937 + }, 938 + .driver_data = &(struct power_data) { 939 + .ac_data = &(struct power_limits) { 940 + .ppt_pl1_spl_min = 45, 941 + .ppt_pl1_spl_max = 85, 942 + .ppt_pl2_sppt_min = 56, 943 + .ppt_pl2_sppt_max = 110, 944 + .nv_dynamic_boost_min = 5, 945 + .nv_dynamic_boost_max = 20, 946 + .nv_temp_target_min = 7, 947 + .nv_temp_target_max = 87, 948 + .nv_tgp_min = 95, 949 + .nv_tgp_def = 100, 950 + .nv_tgp_max = 110, 951 + }, 952 + .dc_data = &(struct power_limits) { 953 + .ppt_pl1_spl_min = 25, 954 + .ppt_pl1_spl_max = 85, 955 + .ppt_pl2_sppt_min = 32, 956 + .ppt_pl2_sppt_max = 110, 957 + .nv_temp_target_min = 75, 958 + .nv_temp_target_max = 87, 959 + }, 960 + .requires_fan_curve = true, 961 + }, 962 + }, 963 + { 964 + .matches = { 965 + DMI_MATCH(DMI_BOARD_NAME, "GU605M"), 966 + }, 967 + .driver_data = &(struct power_data) { 968 + .ac_data = &(struct power_limits) { 969 + .ppt_pl1_spl_min = 28, 970 + .ppt_pl1_spl_max = 90, 971 + .ppt_pl2_sppt_min = 28, 972 + .ppt_pl2_sppt_max = 135, 973 + .nv_dynamic_boost_min = 5, 974 + .nv_dynamic_boost_max = 20, 975 + .nv_temp_target_min = 75, 976 + .nv_temp_target_max = 87, 977 + }, 978 + .dc_data = &(struct power_limits) { 979 + .ppt_pl1_spl_min = 25, 980 + .ppt_pl1_spl_max = 35, 981 + .ppt_pl2_sppt_min = 38, 982 + .ppt_pl2_sppt_max = 53, 983 + .nv_temp_target_min = 75, 984 + .nv_temp_target_max = 87, 985 + }, 986 + .requires_fan_curve = true, 987 + }, 988 + }, 989 + { 990 + .matches = { 991 + DMI_MATCH(DMI_BOARD_NAME, "GV301Q"), 992 + }, 993 + .driver_data = &(struct power_data) { 994 + .ac_data = &(struct power_limits) { 995 + .ppt_pl1_spl_min = 15, 996 + .ppt_pl1_spl_max = 45, 997 + .ppt_pl2_sppt_min = 65, 998 + .ppt_pl2_sppt_max = 80, 999 + }, 1000 + .dc_data = NULL, 1001 + }, 1002 + }, 1003 + { 1004 + .matches = { 1005 + DMI_MATCH(DMI_BOARD_NAME, "GV301R"), 1006 + }, 1007 + .driver_data = &(struct power_data) { 1008 + .ac_data = &(struct power_limits) { 1009 + .ppt_pl1_spl_min = 15, 1010 + .ppt_pl1_spl_max = 45, 1011 + .ppt_pl2_sppt_min = 25, 1012 + .ppt_pl2_sppt_max = 54, 1013 + .ppt_pl3_fppt_min = 35, 1014 + .ppt_pl3_fppt_max = 65, 1015 + .nv_temp_target_min = 75, 1016 + .nv_temp_target_max = 87, 1017 + }, 1018 + .dc_data = &(struct power_limits) { 1019 + .ppt_pl1_spl_min = 15, 1020 + .ppt_pl1_spl_max = 35, 1021 + .ppt_pl2_sppt_min = 25, 1022 + .ppt_pl2_sppt_max = 35, 1023 + .ppt_pl3_fppt_min = 35, 1024 + .ppt_pl3_fppt_max = 65, 1025 + .nv_temp_target_min = 75, 1026 + .nv_temp_target_max = 87, 1027 + }, 1028 + }, 1029 + }, 1030 + { 1031 + .matches = { 1032 + DMI_MATCH(DMI_BOARD_NAME, "GV601R"), 1033 + }, 1034 + .driver_data = &(struct power_data) { 1035 + .ac_data = &(struct power_limits) { 1036 + .ppt_pl1_spl_min = 15, 1037 + .ppt_pl1_spl_def = 35, 1038 + .ppt_pl1_spl_max = 90, 1039 + .ppt_pl2_sppt_min = 35, 1040 + .ppt_pl2_sppt_def = 54, 1041 + .ppt_pl2_sppt_max = 100, 1042 + .ppt_pl3_fppt_min = 35, 1043 + .ppt_pl3_fppt_def = 80, 1044 + .ppt_pl3_fppt_max = 125, 1045 + .nv_dynamic_boost_min = 5, 1046 + .nv_dynamic_boost_max = 25, 1047 + .nv_temp_target_min = 75, 1048 + .nv_temp_target_max = 87, 1049 + }, 1050 + .dc_data = &(struct power_limits) { 1051 + .ppt_pl1_spl_min = 15, 1052 + .ppt_pl1_spl_def = 28, 1053 + .ppt_pl1_spl_max = 65, 1054 + .ppt_pl2_sppt_min = 35, 1055 + .ppt_pl2_sppt_def = 54, 1056 + .ppt_pl2_sppt_max = 60, 1057 + .ppt_pl3_fppt_min = 35, 1058 + .ppt_pl3_fppt_def = 80, 1059 + .ppt_pl3_fppt_max = 65, 1060 + .nv_temp_target_min = 75, 1061 + .nv_temp_target_max = 87, 1062 + }, 1063 + }, 1064 + }, 1065 + { 1066 + .matches = { 1067 + DMI_MATCH(DMI_BOARD_NAME, "GV601V"), 1068 + }, 1069 + .driver_data = &(struct power_data) { 1070 + .ac_data = &(struct power_limits) { 1071 + .ppt_pl1_spl_min = 28, 1072 + .ppt_pl1_spl_def = 100, 1073 + .ppt_pl1_spl_max = 110, 1074 + .ppt_pl2_sppt_min = 28, 1075 + .ppt_pl2_sppt_max = 135, 1076 + .nv_dynamic_boost_min = 5, 1077 + .nv_dynamic_boost_max = 20, 1078 + .nv_temp_target_min = 75, 1079 + .nv_temp_target_max = 87, 1080 + }, 1081 + .dc_data = &(struct power_limits) { 1082 + .ppt_pl1_spl_min = 25, 1083 + .ppt_pl1_spl_max = 40, 1084 + .ppt_pl2_sppt_min = 35, 1085 + .ppt_pl2_sppt_def = 40, 1086 + .ppt_pl2_sppt_max = 60, 1087 + .nv_temp_target_min = 75, 1088 + .nv_temp_target_max = 87, 1089 + }, 1090 + }, 1091 + }, 1092 + { 1093 + .matches = { 1094 + DMI_MATCH(DMI_BOARD_NAME, "GX650P"), 1095 + }, 1096 + .driver_data = &(struct power_data) { 1097 + .ac_data = &(struct power_limits) { 1098 + .ppt_pl1_spl_min = 15, 1099 + .ppt_pl1_spl_def = 110, 1100 + .ppt_pl1_spl_max = 130, 1101 + .ppt_pl2_sppt_min = 35, 1102 + .ppt_pl2_sppt_def = 125, 1103 + .ppt_pl2_sppt_max = 130, 1104 + .ppt_pl3_fppt_min = 35, 1105 + .ppt_pl3_fppt_def = 125, 1106 + .ppt_pl3_fppt_max = 135, 1107 + .nv_dynamic_boost_min = 5, 1108 + .nv_dynamic_boost_max = 25, 1109 + .nv_temp_target_min = 75, 1110 + .nv_temp_target_max = 87, 1111 + }, 1112 + .dc_data = &(struct power_limits) { 1113 + .ppt_pl1_spl_min = 15, 1114 + .ppt_pl1_spl_def = 25, 1115 + .ppt_pl1_spl_max = 65, 1116 + .ppt_pl2_sppt_min = 35, 1117 + .ppt_pl2_sppt_def = 35, 1118 + .ppt_pl2_sppt_max = 65, 1119 + .ppt_pl3_fppt_min = 35, 1120 + .ppt_pl3_fppt_def = 42, 1121 + .ppt_pl3_fppt_max = 65, 1122 + .nv_temp_target_min = 75, 1123 + .nv_temp_target_max = 87, 1124 + }, 1125 + }, 1126 + }, 1127 + { 1128 + .matches = { 1129 + DMI_MATCH(DMI_BOARD_NAME, "G513I"), 1130 + }, 1131 + .driver_data = &(struct power_data) { 1132 + .ac_data = &(struct power_limits) { 1133 + /* Yes this laptop is very limited */ 1134 + .ppt_pl1_spl_min = 15, 1135 + .ppt_pl1_spl_max = 80, 1136 + .ppt_pl2_sppt_min = 15, 1137 + .ppt_pl2_sppt_max = 80, 1138 + }, 1139 + .dc_data = NULL, 1140 + .requires_fan_curve = true, 1141 + }, 1142 + }, 1143 + { 1144 + .matches = { 1145 + DMI_MATCH(DMI_BOARD_NAME, "G513QM"), 1146 + }, 1147 + .driver_data = &(struct power_data) { 1148 + .ac_data = &(struct power_limits) { 1149 + /* Yes this laptop is very limited */ 1150 + .ppt_pl1_spl_min = 15, 1151 + .ppt_pl1_spl_max = 100, 1152 + .ppt_pl2_sppt_min = 15, 1153 + .ppt_pl2_sppt_max = 190, 1154 + }, 1155 + .dc_data = NULL, 1156 + .requires_fan_curve = true, 1157 + }, 1158 + }, 1159 + { 1160 + .matches = { 1161 + DMI_MATCH(DMI_BOARD_NAME, "G513R"), 1162 + }, 1163 + .driver_data = &(struct power_data) { 1164 + .ac_data = &(struct power_limits) { 1165 + .ppt_pl1_spl_min = 35, 1166 + .ppt_pl1_spl_max = 90, 1167 + .ppt_pl2_sppt_min = 54, 1168 + .ppt_pl2_sppt_max = 100, 1169 + .ppt_pl3_fppt_min = 54, 1170 + .ppt_pl3_fppt_max = 125, 1171 + .nv_dynamic_boost_min = 5, 1172 + .nv_dynamic_boost_max = 25, 1173 + .nv_temp_target_min = 75, 1174 + .nv_temp_target_max = 87, 1175 + }, 1176 + .dc_data = &(struct power_limits) { 1177 + .ppt_pl1_spl_min = 28, 1178 + .ppt_pl1_spl_max = 50, 1179 + .ppt_pl2_sppt_min = 28, 1180 + .ppt_pl2_sppt_max = 50, 1181 + .ppt_pl3_fppt_min = 28, 1182 + .ppt_pl3_fppt_max = 65, 1183 + .nv_temp_target_min = 75, 1184 + .nv_temp_target_max = 87, 1185 + }, 1186 + .requires_fan_curve = true, 1187 + }, 1188 + }, 1189 + { 1190 + .matches = { 1191 + DMI_MATCH(DMI_BOARD_NAME, "G614J"), 1192 + }, 1193 + .driver_data = &(struct power_data) { 1194 + .ac_data = &(struct power_limits) { 1195 + .ppt_pl1_spl_min = 28, 1196 + .ppt_pl1_spl_max = 140, 1197 + .ppt_pl2_sppt_min = 28, 1198 + .ppt_pl2_sppt_max = 175, 1199 + .nv_temp_target_min = 75, 1200 + .nv_temp_target_max = 87, 1201 + .nv_dynamic_boost_min = 5, 1202 + .nv_dynamic_boost_max = 25, 1203 + }, 1204 + .dc_data = &(struct power_limits) { 1205 + .ppt_pl1_spl_min = 25, 1206 + .ppt_pl1_spl_max = 55, 1207 + .ppt_pl2_sppt_min = 25, 1208 + .ppt_pl2_sppt_max = 70, 1209 + .nv_temp_target_min = 75, 1210 + .nv_temp_target_max = 87, 1211 + }, 1212 + .requires_fan_curve = true, 1213 + }, 1214 + }, 1215 + { 1216 + .matches = { 1217 + DMI_MATCH(DMI_BOARD_NAME, "G634J"), 1218 + }, 1219 + .driver_data = &(struct power_data) { 1220 + .ac_data = &(struct power_limits) { 1221 + .ppt_pl1_spl_min = 28, 1222 + .ppt_pl1_spl_max = 140, 1223 + .ppt_pl2_sppt_min = 28, 1224 + .ppt_pl2_sppt_max = 175, 1225 + .nv_temp_target_min = 75, 1226 + .nv_temp_target_max = 87, 1227 + .nv_dynamic_boost_min = 5, 1228 + .nv_dynamic_boost_max = 25, 1229 + }, 1230 + .dc_data = &(struct power_limits) { 1231 + .ppt_pl1_spl_min = 25, 1232 + .ppt_pl1_spl_max = 55, 1233 + .ppt_pl2_sppt_min = 25, 1234 + .ppt_pl2_sppt_max = 70, 1235 + .nv_temp_target_min = 75, 1236 + .nv_temp_target_max = 87, 1237 + }, 1238 + .requires_fan_curve = true, 1239 + }, 1240 + }, 1241 + { 1242 + .matches = { 1243 + DMI_MATCH(DMI_BOARD_NAME, "G713PV"), 1244 + }, 1245 + .driver_data = &(struct power_data) { 1246 + .ac_data = &(struct power_limits) { 1247 + .ppt_pl1_spl_min = 30, 1248 + .ppt_pl1_spl_def = 120, 1249 + .ppt_pl1_spl_max = 130, 1250 + .ppt_pl2_sppt_min = 65, 1251 + .ppt_pl2_sppt_def = 125, 1252 + .ppt_pl2_sppt_max = 130, 1253 + .ppt_pl3_fppt_min = 65, 1254 + .ppt_pl3_fppt_def = 125, 1255 + .ppt_pl3_fppt_max = 130, 1256 + .nv_temp_target_min = 75, 1257 + .nv_temp_target_max = 87, 1258 + .nv_dynamic_boost_min = 5, 1259 + .nv_dynamic_boost_max = 25, 1260 + }, 1261 + .dc_data = &(struct power_limits) { 1262 + .ppt_pl1_spl_min = 25, 1263 + .ppt_pl1_spl_max = 65, 1264 + .ppt_pl2_sppt_min = 25, 1265 + .ppt_pl2_sppt_max = 65, 1266 + .ppt_pl3_fppt_min = 35, 1267 + .ppt_pl3_fppt_max = 75, 1268 + .nv_temp_target_min = 75, 1269 + .nv_temp_target_max = 87, 1270 + }, 1271 + .requires_fan_curve = true, 1272 + }, 1273 + }, 1274 + { 1275 + .matches = { 1276 + DMI_MATCH(DMI_BOARD_NAME, "G733C"), 1277 + }, 1278 + .driver_data = &(struct power_data) { 1279 + .ac_data = &(struct power_limits) { 1280 + .ppt_pl1_spl_min = 28, 1281 + .ppt_pl1_spl_max = 170, 1282 + .ppt_pl2_sppt_min = 28, 1283 + .ppt_pl2_sppt_max = 175, 1284 + .nv_temp_target_min = 75, 1285 + .nv_temp_target_max = 87, 1286 + .nv_dynamic_boost_min = 5, 1287 + .nv_dynamic_boost_max = 25, 1288 + }, 1289 + .dc_data = &(struct power_limits) { 1290 + .ppt_pl1_spl_min = 28, 1291 + .ppt_pl1_spl_max = 35, 1292 + .ppt_pl2_sppt_min = 28, 1293 + .ppt_pl2_sppt_max = 35, 1294 + .nv_temp_target_min = 75, 1295 + .nv_temp_target_max = 87, 1296 + }, 1297 + .requires_fan_curve = true, 1298 + }, 1299 + }, 1300 + { 1301 + .matches = { 1302 + DMI_MATCH(DMI_BOARD_NAME, "G733P"), 1303 + }, 1304 + .driver_data = &(struct power_data) { 1305 + .ac_data = &(struct power_limits) { 1306 + .ppt_pl1_spl_min = 30, 1307 + .ppt_pl1_spl_def = 100, 1308 + .ppt_pl1_spl_max = 130, 1309 + .ppt_pl2_sppt_min = 65, 1310 + .ppt_pl2_sppt_def = 125, 1311 + .ppt_pl2_sppt_max = 130, 1312 + .ppt_pl3_fppt_min = 65, 1313 + .ppt_pl3_fppt_def = 125, 1314 + .ppt_pl3_fppt_max = 130, 1315 + .nv_temp_target_min = 75, 1316 + .nv_temp_target_max = 87, 1317 + .nv_dynamic_boost_min = 5, 1318 + .nv_dynamic_boost_max = 25, 1319 + }, 1320 + .dc_data = &(struct power_limits) { 1321 + .ppt_pl1_spl_min = 25, 1322 + .ppt_pl1_spl_max = 65, 1323 + .ppt_pl2_sppt_min = 25, 1324 + .ppt_pl2_sppt_max = 65, 1325 + .ppt_pl3_fppt_min = 35, 1326 + .ppt_pl3_fppt_max = 75, 1327 + .nv_temp_target_min = 75, 1328 + .nv_temp_target_max = 87, 1329 + }, 1330 + .requires_fan_curve = true, 1331 + }, 1332 + }, 1333 + { 1334 + .matches = { 1335 + DMI_MATCH(DMI_BOARD_NAME, "G814J"), 1336 + }, 1337 + .driver_data = &(struct power_data) { 1338 + .ac_data = &(struct power_limits) { 1339 + .ppt_pl1_spl_min = 28, 1340 + .ppt_pl1_spl_max = 140, 1341 + .ppt_pl2_sppt_min = 28, 1342 + .ppt_pl2_sppt_max = 140, 1343 + .nv_dynamic_boost_min = 5, 1344 + .nv_dynamic_boost_max = 25, 1345 + }, 1346 + .dc_data = &(struct power_limits) { 1347 + .ppt_pl1_spl_min = 25, 1348 + .ppt_pl1_spl_max = 55, 1349 + .ppt_pl2_sppt_min = 25, 1350 + .ppt_pl2_sppt_max = 70, 1351 + }, 1352 + .requires_fan_curve = true, 1353 + }, 1354 + }, 1355 + { 1356 + .matches = { 1357 + DMI_MATCH(DMI_BOARD_NAME, "G834J"), 1358 + }, 1359 + .driver_data = &(struct power_data) { 1360 + .ac_data = &(struct power_limits) { 1361 + .ppt_pl1_spl_min = 28, 1362 + .ppt_pl1_spl_max = 140, 1363 + .ppt_pl2_sppt_min = 28, 1364 + .ppt_pl2_sppt_max = 175, 1365 + .nv_dynamic_boost_min = 5, 1366 + .nv_dynamic_boost_max = 25, 1367 + .nv_temp_target_min = 75, 1368 + .nv_temp_target_max = 87, 1369 + }, 1370 + .dc_data = &(struct power_limits) { 1371 + .ppt_pl1_spl_min = 25, 1372 + .ppt_pl1_spl_max = 55, 1373 + .ppt_pl2_sppt_min = 25, 1374 + .ppt_pl2_sppt_max = 70, 1375 + .nv_temp_target_min = 75, 1376 + .nv_temp_target_max = 87, 1377 + }, 1378 + .requires_fan_curve = true, 1379 + }, 1380 + }, 1381 + { 1382 + .matches = { 1383 + DMI_MATCH(DMI_BOARD_NAME, "H7606W"), 1384 + }, 1385 + .driver_data = &(struct power_data) { 1386 + .ac_data = &(struct power_limits) { 1387 + .ppt_pl1_spl_min = 15, 1388 + .ppt_pl1_spl_max = 80, 1389 + .ppt_pl2_sppt_min = 35, 1390 + .ppt_pl2_sppt_max = 80, 1391 + .ppt_pl3_fppt_min = 35, 1392 + .ppt_pl3_fppt_max = 80, 1393 + .nv_dynamic_boost_min = 5, 1394 + .nv_dynamic_boost_max = 20, 1395 + .nv_temp_target_min = 75, 1396 + .nv_temp_target_max = 87, 1397 + .nv_tgp_min = 55, 1398 + .nv_tgp_max = 85, 1399 + }, 1400 + .dc_data = &(struct power_limits) { 1401 + .ppt_pl1_spl_min = 25, 1402 + .ppt_pl1_spl_max = 35, 1403 + .ppt_pl2_sppt_min = 31, 1404 + .ppt_pl2_sppt_max = 44, 1405 + .ppt_pl3_fppt_min = 45, 1406 + .ppt_pl3_fppt_max = 65, 1407 + .nv_temp_target_min = 75, 1408 + .nv_temp_target_max = 87, 1409 + }, 1410 + }, 1411 + }, 1412 + { 1413 + .matches = { 1414 + DMI_MATCH(DMI_BOARD_NAME, "RC71"), 1415 + }, 1416 + .driver_data = &(struct power_data) { 1417 + .ac_data = &(struct power_limits) { 1418 + .ppt_pl1_spl_min = 7, 1419 + .ppt_pl1_spl_max = 30, 1420 + .ppt_pl2_sppt_min = 15, 1421 + .ppt_pl2_sppt_max = 43, 1422 + .ppt_pl3_fppt_min = 15, 1423 + .ppt_pl3_fppt_max = 53, 1424 + }, 1425 + .dc_data = &(struct power_limits) { 1426 + .ppt_pl1_spl_min = 7, 1427 + .ppt_pl1_spl_def = 15, 1428 + .ppt_pl1_spl_max = 25, 1429 + .ppt_pl2_sppt_min = 15, 1430 + .ppt_pl2_sppt_def = 20, 1431 + .ppt_pl2_sppt_max = 30, 1432 + .ppt_pl3_fppt_min = 15, 1433 + .ppt_pl3_fppt_def = 25, 1434 + .ppt_pl3_fppt_max = 35, 1435 + }, 1436 + }, 1437 + }, 1438 + { 1439 + .matches = { 1440 + DMI_MATCH(DMI_BOARD_NAME, "RC72"), 1441 + }, 1442 + .driver_data = &(struct power_data) { 1443 + .ac_data = &(struct power_limits) { 1444 + .ppt_pl1_spl_min = 7, 1445 + .ppt_pl1_spl_max = 30, 1446 + .ppt_pl2_sppt_min = 15, 1447 + .ppt_pl2_sppt_max = 43, 1448 + .ppt_pl3_fppt_min = 15, 1449 + .ppt_pl3_fppt_max = 53, 1450 + }, 1451 + .dc_data = &(struct power_limits) { 1452 + .ppt_pl1_spl_min = 7, 1453 + .ppt_pl1_spl_def = 17, 1454 + .ppt_pl1_spl_max = 25, 1455 + .ppt_pl2_sppt_min = 15, 1456 + .ppt_pl2_sppt_def = 24, 1457 + .ppt_pl2_sppt_max = 30, 1458 + .ppt_pl3_fppt_min = 15, 1459 + .ppt_pl3_fppt_def = 30, 1460 + .ppt_pl3_fppt_max = 35, 1461 + }, 1462 + }, 1463 + }, 1464 + { 1465 + .matches = { 1466 + DMI_MATCH(DMI_BOARD_NAME, "RC73XA"), 1467 + }, 1468 + .driver_data = &(struct power_data) { 1469 + .ac_data = &(struct power_limits) { 1470 + .ppt_pl1_spl_min = 7, 1471 + .ppt_pl1_spl_max = 35, 1472 + .ppt_pl2_sppt_min = 14, 1473 + .ppt_pl2_sppt_max = 45, 1474 + .ppt_pl3_fppt_min = 19, 1475 + .ppt_pl3_fppt_max = 55, 1476 + }, 1477 + .dc_data = &(struct power_limits) { 1478 + .ppt_pl1_spl_min = 7, 1479 + .ppt_pl1_spl_def = 17, 1480 + .ppt_pl1_spl_max = 35, 1481 + .ppt_pl2_sppt_min = 13, 1482 + .ppt_pl2_sppt_def = 21, 1483 + .ppt_pl2_sppt_max = 45, 1484 + .ppt_pl3_fppt_min = 19, 1485 + .ppt_pl3_fppt_def = 26, 1486 + .ppt_pl3_fppt_max = 55, 1487 + }, 1488 + }, 1489 + }, 1490 + {} 1491 + }; 200 1492 201 1493 #endif /* _ASUS_ARMOURY_H_ */
+3
include/linux/platform_data/x86/asus-wmi.h
··· 139 139 140 140 #define ASUS_WMI_DEVID_APU_MEM 0x000600C1 141 141 142 + #define ASUS_WMI_DEVID_DGPU_BASE_TGP 0x00120099 143 + #define ASUS_WMI_DEVID_DGPU_SET_TGP 0x00120098 144 + 142 145 /* gpu mux switch, 0 = dGPU, 1 = Optimus */ 143 146 #define ASUS_WMI_DEVID_GPU_MUX 0x00090016 144 147 #define ASUS_WMI_DEVID_GPU_MUX_VIVO 0x00090026