mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
platform/x86: asus-wmi: Support the hardware GPU MUX on some laptops
Support the hardware GPU MUX switch available on some models. This switch can toggle the MUX between: - 0, Dedicated mode - 1, Optimus mode Optimus mode is the regular iGPU + dGPU available, while dedicated mode switches the system to have only the dGPU available. Signed-off-by: Luke D. Jones <luke@ljones.dev> Link: https://lore.kernel.org/r/20220813092624.6228-1-luke@ljones.dev Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
committed by
Hans de Goede
parent
3c3b55564a
commit
01ef026ab3
@@ -58,6 +58,18 @@ Description:
|
|||||||
* 1 - overboost,
|
* 1 - overboost,
|
||||||
* 2 - silent
|
* 2 - silent
|
||||||
|
|
||||||
|
What: /sys/devices/platform/<platform>/gpu_mux_mode
|
||||||
|
Date: Aug 2022
|
||||||
|
KernelVersion: 6.1
|
||||||
|
Contact: "Luke Jones" <luke@ljones.dev>
|
||||||
|
Description:
|
||||||
|
Switch the GPU hardware MUX mode. Laptops with this feature can
|
||||||
|
can be toggled to boot with only the dGPU (discrete mode) or in
|
||||||
|
standard Optimus/Hybrid mode. On switch a reboot is required:
|
||||||
|
|
||||||
|
* 0 - Discrete GPU,
|
||||||
|
* 1 - Optimus/Hybrid,
|
||||||
|
|
||||||
What: /sys/devices/platform/<platform>/dgpu_disable
|
What: /sys/devices/platform/<platform>/dgpu_disable
|
||||||
Date: Aug 2022
|
Date: Aug 2022
|
||||||
KernelVersion: 5.17
|
KernelVersion: 5.17
|
||||||
|
@@ -231,6 +231,7 @@ struct asus_wmi {
|
|||||||
|
|
||||||
bool egpu_enable_available;
|
bool egpu_enable_available;
|
||||||
bool dgpu_disable_available;
|
bool dgpu_disable_available;
|
||||||
|
bool gpu_mux_mode_available;
|
||||||
|
|
||||||
bool throttle_thermal_policy_available;
|
bool throttle_thermal_policy_available;
|
||||||
u8 throttle_thermal_policy_mode;
|
u8 throttle_thermal_policy_mode;
|
||||||
@@ -657,6 +658,52 @@ static ssize_t egpu_enable_store(struct device *dev,
|
|||||||
}
|
}
|
||||||
static DEVICE_ATTR_RW(egpu_enable);
|
static DEVICE_ATTR_RW(egpu_enable);
|
||||||
|
|
||||||
|
/* gpu mux switch *************************************************************/
|
||||||
|
static ssize_t gpu_mux_mode_show(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPU_MUX);
|
||||||
|
if (result < 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
return sysfs_emit(buf, "%d\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t gpu_mux_mode_store(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct asus_wmi *asus = dev_get_drvdata(dev);
|
||||||
|
int result, err;
|
||||||
|
u32 optimus;
|
||||||
|
|
||||||
|
err = kstrtou32(buf, 10, &optimus);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (optimus > 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
err = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_MUX, optimus, &result);
|
||||||
|
if (err) {
|
||||||
|
dev_err(dev, "Failed to set GPU MUX mode: %d\n", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
/* !1 is considered a fail by ASUS */
|
||||||
|
if (result != 1) {
|
||||||
|
dev_warn(dev, "Failed to set GPU MUX mode (result): 0x%x\n", result);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
sysfs_notify(&asus->platform_device->dev.kobj, NULL, "gpu_mux_mode");
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
static DEVICE_ATTR_RW(gpu_mux_mode);
|
||||||
|
|
||||||
/* Battery ********************************************************************/
|
/* Battery ********************************************************************/
|
||||||
|
|
||||||
/* The battery maximum charging percentage */
|
/* The battery maximum charging percentage */
|
||||||
@@ -3172,6 +3219,7 @@ static struct attribute *platform_attributes[] = {
|
|||||||
&dev_attr_touchpad.attr,
|
&dev_attr_touchpad.attr,
|
||||||
&dev_attr_egpu_enable.attr,
|
&dev_attr_egpu_enable.attr,
|
||||||
&dev_attr_dgpu_disable.attr,
|
&dev_attr_dgpu_disable.attr,
|
||||||
|
&dev_attr_gpu_mux_mode.attr,
|
||||||
&dev_attr_lid_resume.attr,
|
&dev_attr_lid_resume.attr,
|
||||||
&dev_attr_als_enable.attr,
|
&dev_attr_als_enable.attr,
|
||||||
&dev_attr_fan_boost_mode.attr,
|
&dev_attr_fan_boost_mode.attr,
|
||||||
@@ -3202,6 +3250,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj,
|
|||||||
ok = asus->egpu_enable_available;
|
ok = asus->egpu_enable_available;
|
||||||
else if (attr == &dev_attr_dgpu_disable.attr)
|
else if (attr == &dev_attr_dgpu_disable.attr)
|
||||||
ok = asus->dgpu_disable_available;
|
ok = asus->dgpu_disable_available;
|
||||||
|
else if (attr == &dev_attr_gpu_mux_mode.attr)
|
||||||
|
ok = asus->gpu_mux_mode_available;
|
||||||
else if (attr == &dev_attr_fan_boost_mode.attr)
|
else if (attr == &dev_attr_fan_boost_mode.attr)
|
||||||
ok = asus->fan_boost_mode_available;
|
ok = asus->fan_boost_mode_available;
|
||||||
else if (attr == &dev_attr_throttle_thermal_policy.attr)
|
else if (attr == &dev_attr_throttle_thermal_policy.attr)
|
||||||
@@ -3465,6 +3515,7 @@ static int asus_wmi_add(struct platform_device *pdev)
|
|||||||
|
|
||||||
asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
|
asus->egpu_enable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_EGPU);
|
||||||
asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
|
asus->dgpu_disable_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_DGPU);
|
||||||
|
asus->gpu_mux_mode_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_GPU_MUX);
|
||||||
asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
|
asus->panel_overdrive_available = asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_PANEL_OD);
|
||||||
|
|
||||||
err = fan_boost_mode_check_present(asus);
|
err = fan_boost_mode_check_present(asus);
|
||||||
|
@@ -99,6 +99,9 @@
|
|||||||
/* dgpu on/off */
|
/* dgpu on/off */
|
||||||
#define ASUS_WMI_DEVID_DGPU 0x00090020
|
#define ASUS_WMI_DEVID_DGPU 0x00090020
|
||||||
|
|
||||||
|
/* gpu mux switch, 0 = dGPU, 1 = Optimus */
|
||||||
|
#define ASUS_WMI_DEVID_GPU_MUX 0x00090016
|
||||||
|
|
||||||
/* DSTS masks */
|
/* DSTS masks */
|
||||||
#define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
|
#define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
|
||||||
#define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
|
#define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
|
||||||
|
Reference in New Issue
Block a user