Re: [PATCH v2 8/8] platform/x86: asus-wmi: expose dGPU and CPU tunables for ROG

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 6/30/23 07:35, Luke D. Jones wrote:
> 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@xxxxxxxxxx>

Thanks, patch looks good to me:

Reviewed-by: Hans de Goede <hdegoede@xxxxxxxxxx>

(I'll fix the make htmldocs warning lkp spotted while merging this).

Regards,

Hans

> ---
>  .../ABI/testing/sysfs-platform-asus-wmi       |  58 ++++
>  drivers/platform/x86/asus-wmi.c               | 285 ++++++++++++++++++
>  include/linux/platform_data/x86/asus-wmi.h    |   9 +
>  3 files changed, 352 insertions(+)
> 
> diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
> index 5624bdef49cb..caaccd28fabf 100644
> --- a/Documentation/ABI/testing/sysfs-platform-asus-wmi
> +++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
> @@ -126,3 +126,61 @@ Description:
>  		Change the mini-LED mode:
>  			* 0 - Single-zone,
>  			* 1 - Multi-zone
> +
> +What:		/sys/devices/platform/<platform>/ppt_pl1_spl
> +Date:		Jun 2023
> +KernelVersion:	6.5
> +Contact:	"Luke Jones" <luke@xxxxxxxxxx>
> +Description:
> +		Set the Package Power Target total of CPU: PL1 on Intel, SPL on AMD.
> +		Shown on Intel+Nvidia or AMD+Nvidia based systems.
> +			* min=5, max=250
> +
> +What:		/sys/devices/platform/<platform>/ppt_pl2_sppt
> +Date:		Jun 2023
> +KernelVersion:	6.5
> +Contact:	"Luke Jones" <luke@xxxxxxxxxx>
> +Description:
> +		Set the Slow Package Power Tracking Limit of CPU: PL2 on Intel, SPPT,
> +		on AMD. Shown on Intel+Nvidia or AMD+Nvidia based systems.
> +			* min=5, max=250
> +
> +What:		/sys/devices/platform/<platform>/ppt_fppt
> +Date:		Jun 2023
> +KernelVersion:	6.5
> +Contact:	"Luke Jones" <luke@xxxxxxxxxx>
> +Description:
> +		Set the Fast Package Power Tracking Limit of CPU. AMD+Nvidia only.
> +			* min=5, max=250
> +
> +What:		/sys/devices/platform/<platform>/ppt_apu_sppt
> +Date:		Jun 2023
> +KernelVersion:	6.5
> +Contact:	"Luke Jones" <luke@xxxxxxxxxx>
> +Description:
> +		Set the APU SPPT limit. Shown on full AMD systems only.
> +			* min=5, max=130
> +
> +What:		/sys/devices/platform/<platform>/ppt_platform_sppt
> +Date:		Jun 2023
> +KernelVersion:	6.5
> +Contact:	"Luke Jones" <luke@xxxxxxxxxx>
> +Description:
> +		Set the platform SPPT limit. Shown on full AMD systems only.
> +			* min=5, max=130
> +
> +What:		/sys/devices/platform/<platform>/nv_dynamic_boost
> +Date:		Jun 2023
> +KernelVersion:	6.5
> +Contact:	"Luke Jones" <luke@xxxxxxxxxx>
> +Description:
> +		Set the dynamic boost limit of the Nvidia dGPU:
> +			* min=5, max=25
> +
> +What:		/sys/devices/platform/<platform>/nv_temp_target
> +Date:		Jun 2023
> +KernelVersion:	6.5
> +Contact:	"Luke Jones" <luke@xxxxxxxxxx>
> +Description:
> +		Set the target temperature limit of the Nvidia dGPU:
> +			* min=75, max=87
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index 1fc9e8afc2f3..d9a353081f91 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -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_BOOST_MIN	5
> +#define NVIDIA_BOOST_MAX	25
> +#define NVIDIA_TEMP_MIN		75
> +#define NVIDIA_TEMP_MAX		87
> +
>  static const char * const ashs_ids[] = { "ATK4001", "ATK4002", NULL };
>  
>  static int throttle_thermal_policy_write(struct asus_wmi *);
> @@ -247,6 +257,15 @@ struct asus_wmi {
>  	bool dgpu_disable_available;
>  	bool gpu_mux_mode_available;
>  
> +	/* Tunables provided by ASUS for gaming laptops */
> +	bool ppt_pl2_sppt_available;
> +	bool ppt_pl1_spl_available;
> +	bool ppt_apu_sppt_available;
> +	bool ppt_plat_sppt_available;
> +	bool ppt_fppt_available;
> +	bool nv_dyn_boost_available;
> +	bool nv_temp_tgt_available;
> +
>  	bool kbd_rgb_mode_available;
>  	bool kbd_rgb_state_available;
>  
> @@ -946,6 +965,244 @@ static const struct attribute_group *kbd_rgb_mode_groups[] = {
>  	NULL,
>  };
>  
> +/* Tunable: PPT: Intel=PL1, AMD=SPPT *****************************************/
> +static ssize_t ppt_pl2_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_PL2_SPPT, value, &result);
> +	if (err) {
> +		pr_warn("Failed to set ppt_pl2_sppt: %d\n", err);
> +		return err;
> +	}
> +
> +	if (result > 1) {
> +		pr_warn("Failed to set ppt_pl2_sppt (result): 0x%x\n", result);
> +		return -EIO;
> +	}
> +
> +	sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_pl2_sppt");
> +
> +	return count;
> +}
> +static DEVICE_ATTR_WO(ppt_pl2_sppt);
> +
> +/* Tunable: PPT, Intel=PL1, AMD=SPL ******************************************/
> +static ssize_t ppt_pl1_spl_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_PL1_SPL, value, &result);
> +	if (err) {
> +		pr_warn("Failed to set ppt_pl1_spl: %d\n", err);
> +		return err;
> +	}
> +
> +	if (result > 1) {
> +		pr_warn("Failed to set ppt_pl1_spl (result): 0x%x\n", result);
> +		return -EIO;
> +	}
> +
> +	sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_pl1_spl");
> +
> +	return count;
> +}
> +static DEVICE_ATTR_WO(ppt_pl1_spl);
> +
> +/* 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 SPPT *****************************************************/
> +static ssize_t ppt_apu_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_CPU_MIN || value > PPT_CPU_MAX)
> +		return -EINVAL;
> +
> +	err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_APU_SPPT, value, &result);
> +	if (err) {
> +		pr_warn("Failed to set ppt_apu_sppt: %d\n", err);
> +		return err;
> +	}
> +
> +	if (result > 1) {
> +		pr_warn("Failed to set ppt_apu_sppt (result): 0x%x\n", result);
> +		return -EIO;
> +	}
> +
> +	sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_apu_sppt");
> +
> +	return count;
> +}
> +static DEVICE_ATTR_WO(ppt_apu_sppt);
> +
> +/* Tunable: PPT platform SPPT ************************************************/
> +static ssize_t ppt_platform_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_CPU_MIN || value > PPT_CPU_MAX)
> +		return -EINVAL;
> +
> +	err = asus_wmi_set_devstate(ASUS_WMI_DEVID_PPT_PLAT_SPPT, value, &result);
> +	if (err) {
> +		pr_warn("Failed to set ppt_platform_sppt: %d\n", err);
> +		return err;
> +	}
> +
> +	if (result > 1) {
> +		pr_warn("Failed to set ppt_platform_sppt (result): 0x%x\n", result);
> +		return -EIO;
> +	}
> +
> +	sysfs_notify(&asus->platform_device->dev.kobj, NULL, "ppt_platform_sppt");
> +
> +	return count;
> +}
> +static DEVICE_ATTR_WO(ppt_platform_sppt);
> +
> +/* Tunable: NVIDIA dynamic boost *********************************************/
> +static ssize_t nv_dynamic_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_BOOST_MIN || value > NVIDIA_BOOST_MAX)
> +		return -EINVAL;
> +
> +	err = asus_wmi_set_devstate(ASUS_WMI_DEVID_NV_DYN_BOOST, value, &result);
> +	if (err) {
> +		pr_warn("Failed to set nv_dynamic_boost: %d\n", err);
> +		return err;
> +	}
> +
> +	if (result > 1) {
> +		pr_warn("Failed to set nv_dynamic_boost (result): 0x%x\n", result);
> +		return -EIO;
> +	}
> +
> +	sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_dynamic_boost");
> +
> +	return count;
> +}
> +static DEVICE_ATTR_WO(nv_dynamic_boost);
> +
> +/* Tunable: NVIDIA temperature target ****************************************/
> +static ssize_t nv_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_TEMP_MIN || value > NVIDIA_TEMP_MAX)
> +		return -EINVAL;
> +
> +	err = asus_wmi_set_devstate(ASUS_WMI_DEVID_NV_THERM_TARGET, value, &result);
> +	if (err) {
> +		pr_warn("Failed to set nv_temp_target: %d\n", err);
> +		return err;
> +	}
> +
> +	if (result > 1) {
> +		pr_warn("Failed to set nv_temp_target (result): 0x%x\n", result);
> +		return -EIO;
> +	}
> +
> +	sysfs_notify(&asus->platform_device->dev.kobj, NULL, "nv_temp_target");
> +
> +	return count;
> +}
> +static DEVICE_ATTR_WO(nv_temp_target);
> +
>  /* Battery ********************************************************************/
>  
>  /* The battery maximum charging percentage */
> @@ -3775,6 +4032,13 @@ 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_pl2_sppt.attr,
> +	&dev_attr_ppt_pl1_spl.attr,
> +	&dev_attr_ppt_fppt.attr,
> +	&dev_attr_ppt_apu_sppt.attr,
> +	&dev_attr_ppt_platform_sppt.attr,
> +	&dev_attr_nv_dynamic_boost.attr,
> +	&dev_attr_nv_temp_target.attr,
>  	&dev_attr_panel_od.attr,
>  	&dev_attr_mini_led_mode.attr,
>  	NULL
> @@ -3812,6 +4076,20 @@ 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_pl2_sppt.attr)
> +		ok = asus->ppt_pl2_sppt_available;
> +	else if (attr == &dev_attr_ppt_pl1_spl.attr)
> +		ok = asus->ppt_pl1_spl_available;
> +	else if (attr == &dev_attr_ppt_fppt.attr)
> +		ok = asus->ppt_fppt_available;
> +	else if (attr == &dev_attr_ppt_apu_sppt.attr)
> +		ok = asus->ppt_apu_sppt_available;
> +	else if (attr == &dev_attr_ppt_platform_sppt.attr)
> +		ok = asus->ppt_plat_sppt_available;
> +	else if (attr == &dev_attr_nv_dynamic_boost.attr)
> +		ok = asus->nv_dyn_boost_available;
> +	else if (attr == &dev_attr_nv_temp_target.attr)
> +		ok = asus->nv_temp_tgt_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 +4355,13 @@ 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_pl2_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL2_SPPT);
> +	asus->ppt_pl1_spl_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PL1_SPL);
> +	asus->ppt_fppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_FPPT);
> +	asus->ppt_apu_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_APU_SPPT);
> +	asus->ppt_plat_sppt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PPT_PLAT_SPPT);
> +	asus->nv_dyn_boost_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_DYN_BOOST);
> +	asus->nv_temp_tgt_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_NV_THERM_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);
>  
> diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
> index ea80361ac6c7..16e99a1c37fc 100644
> --- a/include/linux/platform_data/x86/asus-wmi.h
> +++ b/include/linux/platform_data/x86/asus-wmi.h
> @@ -86,6 +86,15 @@
>  #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_PL2_SPPT		0x001200A0
> +#define ASUS_WMI_DEVID_PPT_PL1_SPL		0x001200A3
> +#define ASUS_WMI_DEVID_PPT_APU_SPPT		0x001200B0
> +#define ASUS_WMI_DEVID_PPT_PLAT_SPPT	0x001200B1
> +#define ASUS_WMI_DEVID_PPT_FPPT			0x001200C1
> +#define ASUS_WMI_DEVID_NV_DYN_BOOST		0x001200C0
> +#define ASUS_WMI_DEVID_NV_THERM_TARGET	0x001200C2
> +
>  /* Power */
>  #define ASUS_WMI_DEVID_PROCESSOR_STATE	0x00120012
>  




[Index of Archives]     [Linux Kernel Development]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux