@@ -126,3 +126,75 @@ Description:
Change the mini-LED mode:
* 0 - Single-zone,
* 1 - Multi-zone
+
+What: /sys/devices/platform/<platform>/ppt_total
+Date: Jun 2023
+KernelVersion: 6.5
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ Set the Package Power Target total of CPU, corresponds to PL1 on Intel:
+ * min=5, max=250
+
+What: /sys/devices/platform/<platform>/ppt_sppt
+Date: Jun 2023
+KernelVersion: 6.5
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ Set the Slow Package Power Tracking Limit of CPU, corresponds to PL2 on Intel:
+ * min=5, max=250
+
+What: /sys/devices/platform/<platform>/ppt_fppt
+Date: Jun 2023
+KernelVersion: 6.5
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ Set the Fast Package Power Tracking Limit of CPU:
+ * min=5, max=250
+
+What: /sys/devices/platform/<platform>/ppt_edc
+Date: Jun 2023
+KernelVersion: 6.5
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ Set the Electrical Design Current for the CPU, peak current:
+ * min=5, max=250
+
+What: /sys/devices/platform/<platform>/ppt_tdc
+Date: Jun 2023
+KernelVersion: 6.5
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ Set the Thermal Design Current for the CPU, sustained current:
+ * min=5, max=250
+
+What: /sys/devices/platform/<platform>/ppt_limit
+Date: Jun 2023
+KernelVersion: 6.5
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ Set the CPU PPT limit:
+ * min=5, max=130
+
+What: /sys/devices/platform/<platform>/ppt_limit_slow
+Date: Jun 2023
+KernelVersion: 6.5
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ Set the CPU PPT slow limit:
+ * min=5, max=130
+
+What: /sys/devices/platform/<platform>/nv_gpu_boost
+Date: Jun 2023
+KernelVersion: 6.5
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ Set the extra current boost of the Nvidia dGPU:
+ * min=5, max=25
+
+What: /sys/devices/platform/<platform>/nv_gpu_temp_target
+Date: Jun 2023
+KernelVersion: 6.5
+Contact: "Luke Jones" <luke@ljones.dev>
+Description:
+ Set the temperature limit of the Nvidia dGPU:
+ * min=75, max=87
@@ -117,6 +117,16 @@ module_param(fnlock_default, bool, 0444);
/* Mask to determine if setting temperature or percentage */
#define FAN_CURVE_PWM_MASK 0x04
+/* Limits for tunables available on ASUS ROG laptops */
+#define PPT_TOTAL_MIN 5
+#define PPT_TOTAL_MAX 250
+#define PPT_CPU_MIN 5
+#define PPT_CPU_MAX 130
+#define NVIDIA_GPU_BOOST_MIN 5
+#define NVIDIA_GPU_BOOST_MAX 25
+#define NVIDIA_GPU_TEMP_MIN 75
+#define NVIDIA_GPU_TEMP_MAX 87
+
static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
static int throttle_thermal_policy_write(struct asus_wmi *);
@@ -247,6 +257,17 @@ struct asus_wmi {
bool dgpu_disable_available;
bool gpu_mux_mode_available;
+ /* Tunables provided by ASUS for gaming laptops */
+ bool ppt_total_available;
+ bool ppt_edc_available;
+ bool ppt_tdc_available;
+ bool ppt_sppt_available;
+ bool ppt_limit_available;
+ bool ppt_limit_slow_available;
+ bool ppt_fppt_available;
+ bool nv_gpu_boost_available;
+ bool nv_gpu_temp_target_available;
+
bool kbd_rgb_mode_available;
bool kbd_rgb_state_available;
@@ -946,6 +967,312 @@ static const struct attribute_group *kbd_rgb_mode_groups[] = {
NULL,
};
+/* Tunable: PPT Total **********************************************************/
+static ssize_t ppt_total_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int result, err;
+ u32 value;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = kstrtou32(buf, 10, &value);
+ if (result)
+ return result;
+
+ if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX)
+ return -EINVAL;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_TOTAL, value, &result);
+ if (err) {
+ pr_warn("Failed to set ppt_total: %d\n", err);
+ return err;
+ }
+
+ if (result > 1) {
+ pr_warn("Failed to set ppt_total (result): 0x%x\n", result);
+ return -EIO;
+ }
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_total");
+
+ return count;
+}
+static DEVICE_ATTR_WO(ppt_total);
+
+/* Tunable: PPT EDC **********************************************************/
+static ssize_t ppt_edc_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int result, err;
+ u32 value;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = kstrtou32(buf, 10, &value);
+ if (result)
+ return result;
+
+ if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX)
+ return -EINVAL;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_EDC, value, &result);
+ if (err) {
+ pr_warn("Failed to set ppt_edc: %d\n", err);
+ return err;
+ }
+
+ if (result > 1) {
+ pr_warn("Failed to set ppt_edc (result): 0x%x\n", result);
+ return -EIO;
+ }
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_edc");
+
+ return count;
+}
+static DEVICE_ATTR_WO(ppt_edc);
+
+/* Tunable: PPT TDC ***********************************************************/
+static ssize_t ppt_tdc_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int result, err;
+ u32 value;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = kstrtou32(buf, 10, &value);
+ if (result)
+ return result;
+
+ if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX)
+ return -EINVAL;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_TDC, value, &result);
+ if (err) {
+ pr_warn("Failed to set ppt_tdc: %d\n", err);
+ return err;
+ }
+
+ if (result > 1) {
+ pr_warn("Failed to set ppt_tdc (result): 0x%x\n", result);
+ return -EIO;
+ }
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_tdc");
+
+ return count;
+}
+static DEVICE_ATTR_WO(ppt_tdc);
+
+/* Tunable: PPT APU sPPT ******************************************************/
+static ssize_t ppt_sppt_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int result, err;
+ u32 value;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = kstrtou32(buf, 10, &value);
+ if (result)
+ return result;
+
+ if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX)
+ return -EINVAL;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_SPPT, value, &result);
+ if (err) {
+ pr_warn("Failed to set ppt_sppt: %d\n", err);
+ return err;
+ }
+
+ if (result > 1) {
+ pr_warn("Failed to set ppt_sppt (result): 0x%x\n", result);
+ return -EIO;
+ }
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_sppt");
+
+ return count;
+}
+static DEVICE_ATTR_WO(ppt_sppt);
+
+/* Tunable: PPT APU fPPT ******************************************************/
+static ssize_t ppt_fppt_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int result, err;
+ u32 value;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = kstrtou32(buf, 10, &value);
+ if (result)
+ return result;
+
+ if (value < PPT_TOTAL_MIN || value > PPT_TOTAL_MAX)
+ return -EINVAL;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_FPPT, value, &result);
+ if (err) {
+ pr_warn("Failed to set ppt_fppt: %d\n", err);
+ return err;
+ }
+
+ if (result > 1) {
+ pr_warn("Failed to set ppt_fppt (result): 0x%x\n", result);
+ return -EIO;
+ }
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_fpu_sppt");
+
+ return count;
+}
+static DEVICE_ATTR_WO(ppt_fppt);
+
+/* Tunable: PPT APU limit *****************************************************/
+static ssize_t ppt_limit_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int result, err;
+ u32 value;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = kstrtou32(buf, 10, &value);
+ if (result)
+ return result;
+
+ if (value < PPT_CPU_MIN || value > PPT_CPU_MAX)
+ return -EINVAL;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_LIMIT, value, &result);
+ if (err) {
+ pr_warn("Failed to set ppt_limit: %d\n", err);
+ return err;
+ }
+
+ if (result > 1) {
+ pr_warn("Failed to set ppt_limit (result): 0x%x\n", result);
+ return -EIO;
+ }
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_limit");
+
+ return count;
+}
+static DEVICE_ATTR_WO(ppt_limit);
+
+/* Tunable: PPT limit slow ****************************************************/
+static ssize_t ppt_limit_slow_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int result, err;
+ u32 value;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = kstrtou32(buf, 10, &value);
+ if (result)
+ return result;
+
+ if (value < PPT_CPU_MIN || value > PPT_CPU_MAX)
+ return -EINVAL;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_LIMIT_SLOW, value, &result);
+ if (err) {
+ pr_warn("Failed to set ppt_limit_slow: %d\n", err);
+ return err;
+ }
+
+ if (result > 1) {
+ pr_warn("Failed to set ppt_limit_slow (result): 0x%x\n", result);
+ return -EIO;
+ }
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_limit_slow");
+
+ return count;
+}
+static DEVICE_ATTR_WO(ppt_limit_slow);
+
+/* Tunable: NVIDIA GPU boost **************************************************/
+static ssize_t nv_gpu_boost_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int result, err;
+ u32 value;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = kstrtou32(buf, 10, &value);
+ if (result)
+ return result;
+
+ if (value < NVIDIA_GPU_BOOST_MIN || value > NVIDIA_GPU_BOOST_MAX)
+ return -EINVAL;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_NV_GPU_BOOST, value, &result);
+ if (err) {
+ pr_warn("Failed to set nv_gpu_boost: %d\n", err);
+ return err;
+ }
+
+ if (result > 1) {
+ pr_warn("Failed to set nv_gpu_boost (result): 0x%x\n", result);
+ return -EIO;
+ }
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_gpu_boost");
+
+ return count;
+}
+static DEVICE_ATTR_WO(nv_gpu_boost);
+
+/* Tunable: NVIDIA GPU temperature target *************************************/
+static ssize_t nv_gpu_temp_target_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int result, err;
+ u32 value;
+
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+
+ result = kstrtou32(buf, 10, &value);
+ if (result)
+ return result;
+
+ if (value < NVIDIA_GPU_TEMP_MIN || value > NVIDIA_GPU_TEMP_MAX)
+ return -EINVAL;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_NV_GPU_TEMP_TARGET, value, &result);
+ if (err) {
+ pr_warn("Failed to set nv_gpu_temp_target: %d\n", err);
+ return err;
+ }
+
+ if (result > 1) {
+ pr_warn("Failed to set nv_gpu_temp_target (result): 0x%x\n", result);
+ return -EIO;
+ }
+
+ sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_gpu_temp_target");
+
+ return count;
+}
+static DEVICE_ATTR_WO(nv_gpu_temp_target);
+
/* Battery ********************************************************************/
/* The battery maximum charging percentage */
@@ -3775,6 +4102,15 @@ static struct attribute *platform_attributes[] = {
&dev_attr_als_enable.attr,
&dev_attr_fan_boost_mode.attr,
&dev_attr_throttle_thermal_policy.attr,
+ &dev_attr_ppt_total.attr,
+ &dev_attr_ppt_edc.attr,
+ &dev_attr_ppt_tdc.attr,
+ &dev_attr_ppt_sppt.attr,
+ &dev_attr_ppt_fppt.attr,
+ &dev_attr_ppt_limit.attr,
+ &dev_attr_ppt_limit_slow.attr,
+ &dev_attr_nv_gpu_boost.attr,
+ &dev_attr_nv_gpu_temp_target.attr,
&dev_attr_panel_od.attr,
&dev_attr_mini_led_mode.attr,
NULL
@@ -3812,6 +4148,24 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
ok = asus->fan_boost_mode_available;
else if (attr == &dev_attr_throttle_thermal_policy.attr)
ok = asus->throttle_thermal_policy_available;
+ else if (attr == &dev_attr_ppt_total.attr)
+ ok = asus->ppt_total_available;
+ else if (attr == &dev_attr_ppt_edc.attr)
+ ok = asus->ppt_edc_available;
+ else if (attr == &dev_attr_ppt_tdc.attr)
+ ok = asus->ppt_tdc_available;
+ else if (attr == &dev_attr_ppt_sppt.attr)
+ ok = asus->ppt_sppt_available;
+ else if (attr == &dev_attr_ppt_fppt.attr)
+ ok = asus->ppt_fppt_available;
+ else if (attr == &dev_attr_ppt_limit.attr)
+ ok = asus->ppt_limit_available;
+ else if (attr == &dev_attr_ppt_limit_slow.attr)
+ ok = asus->ppt_limit_slow_available;
+ else if (attr == &dev_attr_nv_gpu_boost.attr)
+ ok = asus->nv_gpu_boost_available;
+ else if (attr == &dev_attr_nv_gpu_temp_target.attr)
+ ok = asus->nv_gpu_temp_target_available;
else if (attr == &dev_attr_panel_od.attr)
ok = asus->panel_overdrive_available;
else if (attr == &dev_attr_mini_led_mode.attr)
@@ -4077,6 +4431,17 @@ static int asus_wmi_add(struct platform_device *pdev)
asus->gpu_mux_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX);
asus->kbd_rgb_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_MODE);
asus->kbd_rgb_state_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_TUF_RGB_STATE);
+ asus->ppt_total_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_TOTAL);
+ asus->ppt_edc_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_EDC);
+ asus->ppt_tdc_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_TDC);
+ asus->ppt_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_SPPT);
+ asus->ppt_fppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_FPPT);
+ asus->ppt_limit_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_LIMIT);
+ asus->ppt_limit_slow_available = asus_wmi_dev_is_present(asus,
+ ASUS_WMI_DEVID_PPT_LIMIT_SLOW);
+ asus->nv_gpu_boost_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_GPU_BOOST);
+ asus->nv_gpu_temp_target_available = asus_wmi_dev_is_present(asus,
+ ASUS_WMI_DEVID_NV_GPU_TEMP_TARGET);
asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
asus->mini_led_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_MINI_LED_MODE);
@@ -86,6 +86,17 @@
#define ASUS_WMI_DEVID_GPU_FAN_CURVE 0x00110025
#define ASUS_WMI_DEVID_MID_FAN_CURVE 0x00110032
+/* Tunables for AUS ROG laptops */
+#define ASUS_WMI_DEVID_PPT_TOTAL 0x001200A0
+#define ASUS_WMI_DEVID_PPT_EDC 0x001200A1
+#define ASUS_WMI_DEVID_PPT_TDC 0x001200A2
+#define ASUS_WMI_DEVID_PPT_SPPT 0x001200A3
+#define ASUS_WMI_DEVID_PPT_LIMIT 0x001200B0
+#define ASUS_WMI_DEVID_PPT_LIMIT_SLOW 0x001200B1
+#define ASUS_WMI_DEVID_PPT_FPPT 0x001200C1
+#define ASUS_WMI_DEVID_NV_GPU_BOOST 0x001200C0
+#define ASUS_WMI_DEVID_NV_GPU_TEMP_TARGET 0x001200C2
+
/* Power */
#define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012