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

platform/x86: asus-wmi: expose dGPU and CPU tunables for ROG

Expose various CPU and dGPU tunables that are available on many ASUS
ROG laptops. The tunables shown in sysfs will vary depending on the CPU
and dGPU vendor.

All of these variables are write only and there is no easy way to find
what the defaults are. In general they seem to default to the max value
the vendor sets for the CPU and dGPU package - this is not the same as
the min/max writable value. Values written to these variables that are
beyond the capabilities of the CPU are ignored by the laptop.

Signed-off-by: Luke D. Jones <luke@ljones.dev>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Link: https://lore.kernel.org/r/20230630053552.976579-9-luke@ljones.dev
Signed-off-by: Hans de Goede <hdegoede@redhat.com>

authored by

Luke D. Jones and committed by
Hans de Goede
e0b278e7 abac4259

+354
+60
Documentation/ABI/testing/sysfs-platform-asus-wmi
··· 126 126 Change the mini-LED mode: 127 127 * 0 - Single-zone, 128 128 * 1 - Multi-zone 129 + 130 + What: /sys/devices/platform/<platform>/ppt_pl1_spl 131 + Date: Jun 2023 132 + KernelVersion: 6.5 133 + Contact: "Luke Jones" <luke@ljones.dev> 134 + Description: 135 + Set the Package Power Target total of CPU: PL1 on Intel, SPL on AMD. 136 + Shown on Intel+Nvidia or AMD+Nvidia based systems: 137 + 138 + * min=5, max=250 139 + 140 + What: /sys/devices/platform/<platform>/ppt_pl2_sppt 141 + Date: Jun 2023 142 + KernelVersion: 6.5 143 + Contact: "Luke Jones" <luke@ljones.dev> 144 + Description: 145 + Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT, 146 + on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems: 147 + 148 + * min=5, max=250 149 + 150 + What: /sys/devices/platform/<platform>/ppt_fppt 151 + Date: Jun 2023 152 + KernelVersion: 6.5 153 + Contact: "Luke Jones" <luke@ljones.dev> 154 + Description: 155 + Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only: 156 + * min=5, max=250 157 + 158 + What: /sys/devices/platform/<platform>/ppt_apu_sppt 159 + Date: Jun 2023 160 + KernelVersion: 6.5 161 + Contact: "Luke Jones" <luke@ljones.dev> 162 + Description: 163 + Set the APU SPPT limit. Shown on full AMD systems only: 164 + * min=5, max=130 165 + 166 + What: /sys/devices/platform/<platform>/ppt_platform_sppt 167 + Date: Jun 2023 168 + KernelVersion: 6.5 169 + Contact: "Luke Jones" <luke@ljones.dev> 170 + Description: 171 + Set the platform SPPT limit. Shown on full AMD systems only: 172 + * min=5, max=130 173 + 174 + What: /sys/devices/platform/<platform>/nv_dynamic_boost 175 + Date: Jun 2023 176 + KernelVersion: 6.5 177 + Contact: "Luke Jones" <luke@ljones.dev> 178 + Description: 179 + Set the dynamic boost limit of the Nvidia dGPU: 180 + * min=5, max=25 181 + 182 + What: /sys/devices/platform/<platform>/nv_temp_target 183 + Date: Jun 2023 184 + KernelVersion: 6.5 185 + Contact: "Luke Jones" <luke@ljones.dev> 186 + Description: 187 + Set the target temperature limit of the Nvidia dGPU: 188 + * min=75, max=87
+285
drivers/platform/x86/asus-wmi.c
··· 117 117 /* Mask to determine if setting temperature or percentage */ 118 118 #define FAN_CURVE_PWM_MASK 0x04 119 119 120 + /* Limits for tunables available on ASUS ROG laptops */ 121 + #define PPT_TOTAL_MIN 5 122 + #define PPT_TOTAL_MAX 250 123 + #define PPT_CPU_MIN 5 124 + #define PPT_CPU_MAX 130 125 + #define NVIDIA_BOOST_MIN 5 126 + #define NVIDIA_BOOST_MAX 25 127 + #define NVIDIA_TEMP_MIN 75 128 + #define NVIDIA_TEMP_MAX 87 129 + 120 130 static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL }; 121 131 122 132 static int throttle_thermal_policy_write(struct asus_wmi *); ··· 256 246 bool egpu_connect_available; 257 247 bool dgpu_disable_available; 258 248 bool gpu_mux_mode_available; 249 + 250 + /* Tunables provided by ASUS for gaming laptops */ 251 + bool ppt_pl2_sppt_available; 252 + bool ppt_pl1_spl_available; 253 + bool ppt_apu_sppt_available; 254 + bool ppt_plat_sppt_available; 255 + bool ppt_fppt_available; 256 + bool nv_dyn_boost_available; 257 + bool nv_temp_tgt_available; 259 258 260 259 bool kbd_rgb_mode_available; 261 260 bool kbd_rgb_state_available; ··· 964 945 NULL, 965 946 NULL, 966 947 }; 948 + 949 + /* Tunable: PPT: Intel=PL1, AMD=SPPT *****************************************/ 950 + static ssize_t ppt_pl2_sppt_store(struct device *dev, 951 + struct device_attribute *attr, 952 + const char *buf, size_t count) 953 + { 954 + int result, err; 955 + u32 value; 956 + 957 + struct asus_wmi *asus = dev_get_drvdata(dev); 958 + 959 + result = kstrtou32(buf, 10, &value); 960 + if (result) 961 + return result; 962 + 963 + if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX) 964 + return -EINVAL; 965 + 966 + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_PL2_SPPT, value, &result); 967 + if (err) { 968 + pr_warn("Failed to set ppt_pl2_sppt: %d\n", err); 969 + return err; 970 + } 971 + 972 + if (result > 1) { 973 + pr_warn("Failed to set ppt_pl2_sppt (result): 0x%x\n", result); 974 + return -EIO; 975 + } 976 + 977 + sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_pl2_sppt"); 978 + 979 + return count; 980 + } 981 + static DEVICE_ATTR_WO(ppt_pl2_sppt); 982 + 983 + /* Tunable: PPT, Intel=PL1, AMD=SPL ******************************************/ 984 + static ssize_t ppt_pl1_spl_store(struct device *dev, 985 + struct device_attribute *attr, 986 + const char *buf, size_t count) 987 + { 988 + int result, err; 989 + u32 value; 990 + 991 + struct asus_wmi *asus = dev_get_drvdata(dev); 992 + 993 + result = kstrtou32(buf, 10, &value); 994 + if (result) 995 + return result; 996 + 997 + if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX) 998 + return -EINVAL; 999 + 1000 + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_PL1_SPL, value, &result); 1001 + if (err) { 1002 + pr_warn("Failed to set ppt_pl1_spl: %d\n", err); 1003 + return err; 1004 + } 1005 + 1006 + if (result > 1) { 1007 + pr_warn("Failed to set ppt_pl1_spl (result): 0x%x\n", result); 1008 + return -EIO; 1009 + } 1010 + 1011 + sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_pl1_spl"); 1012 + 1013 + return count; 1014 + } 1015 + static DEVICE_ATTR_WO(ppt_pl1_spl); 1016 + 1017 + /* Tunable: PPT APU FPPT ******************************************************/ 1018 + static ssize_t ppt_fppt_store(struct device *dev, 1019 + struct device_attribute *attr, 1020 + const char *buf, size_t count) 1021 + { 1022 + int result, err; 1023 + u32 value; 1024 + 1025 + struct asus_wmi *asus = dev_get_drvdata(dev); 1026 + 1027 + result = kstrtou32(buf, 10, &value); 1028 + if (result) 1029 + return result; 1030 + 1031 + if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX) 1032 + return -EINVAL; 1033 + 1034 + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_FPPT, value, &result); 1035 + if (err) { 1036 + pr_warn("Failed to set ppt_fppt: %d\n", err); 1037 + return err; 1038 + } 1039 + 1040 + if (result > 1) { 1041 + pr_warn("Failed to set ppt_fppt (result): 0x%x\n", result); 1042 + return -EIO; 1043 + } 1044 + 1045 + sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_fpu_sppt"); 1046 + 1047 + return count; 1048 + } 1049 + static DEVICE_ATTR_WO(ppt_fppt); 1050 + 1051 + /* Tunable: PPT APU SPPT *****************************************************/ 1052 + static ssize_t ppt_apu_sppt_store(struct device *dev, 1053 + struct device_attribute *attr, 1054 + const char *buf, size_t count) 1055 + { 1056 + int result, err; 1057 + u32 value; 1058 + 1059 + struct asus_wmi *asus = dev_get_drvdata(dev); 1060 + 1061 + result = kstrtou32(buf, 10, &value); 1062 + if (result) 1063 + return result; 1064 + 1065 + if (value < PPT_CPU_MIN || value > PPT_CPU_MAX) 1066 + return -EINVAL; 1067 + 1068 + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_APU_SPPT, value, &result); 1069 + if (err) { 1070 + pr_warn("Failed to set ppt_apu_sppt: %d\n", err); 1071 + return err; 1072 + } 1073 + 1074 + if (result > 1) { 1075 + pr_warn("Failed to set ppt_apu_sppt (result): 0x%x\n", result); 1076 + return -EIO; 1077 + } 1078 + 1079 + sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_apu_sppt"); 1080 + 1081 + return count; 1082 + } 1083 + static DEVICE_ATTR_WO(ppt_apu_sppt); 1084 + 1085 + /* Tunable: PPT platform SPPT ************************************************/ 1086 + static ssize_t ppt_platform_sppt_store(struct device *dev, 1087 + struct device_attribute *attr, 1088 + const char *buf, size_t count) 1089 + { 1090 + int result, err; 1091 + u32 value; 1092 + 1093 + struct asus_wmi *asus = dev_get_drvdata(dev); 1094 + 1095 + result = kstrtou32(buf, 10, &value); 1096 + if (result) 1097 + return result; 1098 + 1099 + if (value < PPT_CPU_MIN || value > PPT_CPU_MAX) 1100 + return -EINVAL; 1101 + 1102 + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_PLAT_SPPT, value, &result); 1103 + if (err) { 1104 + pr_warn("Failed to set ppt_platform_sppt: %d\n", err); 1105 + return err; 1106 + } 1107 + 1108 + if (result > 1) { 1109 + pr_warn("Failed to set ppt_platform_sppt (result): 0x%x\n", result); 1110 + return -EIO; 1111 + } 1112 + 1113 + sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_platform_sppt"); 1114 + 1115 + return count; 1116 + } 1117 + static DEVICE_ATTR_WO(ppt_platform_sppt); 1118 + 1119 + /* Tunable: NVIDIA dynamic boost *********************************************/ 1120 + static ssize_t nv_dynamic_boost_store(struct device *dev, 1121 + struct device_attribute *attr, 1122 + const char *buf, size_t count) 1123 + { 1124 + int result, err; 1125 + u32 value; 1126 + 1127 + struct asus_wmi *asus = dev_get_drvdata(dev); 1128 + 1129 + result = kstrtou32(buf, 10, &value); 1130 + if (result) 1131 + return result; 1132 + 1133 + if (value < NVIDIA_BOOST_MIN || value > NVIDIA_BOOST_MAX) 1134 + return -EINVAL; 1135 + 1136 + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_NV_DYN_BOOST, value, &result); 1137 + if (err) { 1138 + pr_warn("Failed to set nv_dynamic_boost: %d\n", err); 1139 + return err; 1140 + } 1141 + 1142 + if (result > 1) { 1143 + pr_warn("Failed to set nv_dynamic_boost (result): 0x%x\n", result); 1144 + return -EIO; 1145 + } 1146 + 1147 + sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_dynamic_boost"); 1148 + 1149 + return count; 1150 + } 1151 + static DEVICE_ATTR_WO(nv_dynamic_boost); 1152 + 1153 + /* Tunable: NVIDIA temperature target ****************************************/ 1154 + static ssize_t nv_temp_target_store(struct device *dev, 1155 + struct device_attribute *attr, 1156 + const char *buf, size_t count) 1157 + { 1158 + int result, err; 1159 + u32 value; 1160 + 1161 + struct asus_wmi *asus = dev_get_drvdata(dev); 1162 + 1163 + result = kstrtou32(buf, 10, &value); 1164 + if (result) 1165 + return result; 1166 + 1167 + if (value < NVIDIA_TEMP_MIN || value > NVIDIA_TEMP_MAX) 1168 + return -EINVAL; 1169 + 1170 + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_NV_THERM_TARGET, value, &result); 1171 + if (err) { 1172 + pr_warn("Failed to set nv_temp_target: %d\n", err); 1173 + return err; 1174 + } 1175 + 1176 + if (result > 1) { 1177 + pr_warn("Failed to set nv_temp_target (result): 0x%x\n", result); 1178 + return -EIO; 1179 + } 1180 + 1181 + sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_temp_target"); 1182 + 1183 + return count; 1184 + } 1185 + static DEVICE_ATTR_WO(nv_temp_target); 967 1186 968 1187 /* Battery ********************************************************************/ 969 1188 ··· 4032 3775 &dev_attr_als_enable.attr, 4033 3776 &dev_attr_fan_boost_mode.attr, 4034 3777 &dev_attr_throttle_thermal_policy.attr, 3778 + &dev_attr_ppt_pl2_sppt.attr, 3779 + &dev_attr_ppt_pl1_spl.attr, 3780 + &dev_attr_ppt_fppt.attr, 3781 + &dev_attr_ppt_apu_sppt.attr, 3782 + &dev_attr_ppt_platform_sppt.attr, 3783 + &dev_attr_nv_dynamic_boost.attr, 3784 + &dev_attr_nv_temp_target.attr, 4035 3785 &dev_attr_panel_od.attr, 4036 3786 &dev_attr_mini_led_mode.attr, 4037 3787 NULL ··· 4076 3812 ok = asus->fan_boost_mode_available; 4077 3813 else if (attr == &dev_attr_throttle_thermal_policy.attr) 4078 3814 ok = asus->throttle_thermal_policy_available; 3815 + else if (attr == &dev_attr_ppt_pl2_sppt.attr) 3816 + ok = asus->ppt_pl2_sppt_available; 3817 + else if (attr == &dev_attr_ppt_pl1_spl.attr) 3818 + ok = asus->ppt_pl1_spl_available; 3819 + else if (attr == &dev_attr_ppt_fppt.attr) 3820 + ok = asus->ppt_fppt_available; 3821 + else if (attr == &dev_attr_ppt_apu_sppt.attr) 3822 + ok = asus->ppt_apu_sppt_available; 3823 + else if (attr == &dev_attr_ppt_platform_sppt.attr) 3824 + ok = asus->ppt_plat_sppt_available; 3825 + else if (attr == &dev_attr_nv_dynamic_boost.attr) 3826 + ok = asus->nv_dyn_boost_available; 3827 + else if (attr == &dev_attr_nv_temp_target.attr) 3828 + ok = asus->nv_temp_tgt_available; 4079 3829 else if (attr == &dev_attr_panel_od.attr) 4080 3830 ok = asus->panel_overdrive_available; 4081 3831 else if (attr == &dev_attr_mini_led_mode.attr) ··· 4355 4077 asus->gpu_mux_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX); 4356 4078 asus->kbd_rgb_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE); 4357 4079 asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE); 4080 + asus->ppt_pl2_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL2_SPPT); 4081 + asus->ppt_pl1_spl_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL1_SPL); 4082 + asus->ppt_fppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_FPPT); 4083 + asus->ppt_apu_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_APU_SPPT); 4084 + asus->ppt_plat_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PLAT_SPPT); 4085 + asus->nv_dyn_boost_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_DYN_BOOST); 4086 + asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_TARGET); 4358 4087 asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD); 4359 4088 asus->mini_led_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE); 4360 4089
+9
include/linux/platform_data/x86/asus-wmi.h
··· 86 86 #define ASUS_WMI_DEVID_GPU_FAN_CURVE 0x00110025 87 87 #define ASUS_WMI_DEVID_MID_FAN_CURVE 0x00110032 88 88 89 + /* Tunables for AUS ROG laptops */ 90 + #define ASUS_WMI_DEVID_PPT_PL2_SPPT 0x001200A0 91 + #define ASUS_WMI_DEVID_PPT_PL1_SPL 0x001200A3 92 + #define ASUS_WMI_DEVID_PPT_APU_SPPT 0x001200B0 93 + #define ASUS_WMI_DEVID_PPT_PLAT_SPPT 0x001200B1 94 + #define ASUS_WMI_DEVID_PPT_FPPT 0x001200C1 95 + #define ASUS_WMI_DEVID_NV_DYN_BOOST 0x001200C0 96 + #define ASUS_WMI_DEVID_NV_THERM_TARGET 0x001200C2 97 + 89 98 /* Power */ 90 99 #define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012 91 100