Hi, On 8/9/22 04:50, Luke D. Jones wrote: > 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@xxxxxxxxxx> I see that you have replied to this that it needs more work. Besides it needing more work, ideally this should hook into the existing vga-switcheroo mechanism for this. Can you take a look at that please? I think this might be the first non GPU driver doing vga- switcheroo stuff. So this may be something to discuss on the dri-devel list. And if things don't work out we can always go back to just using an asus-wmi specific sysfs file for this as is done in this patch. Regards, Hans > --- > .../ABI/testing/sysfs-platform-asus-wmi | 9 ++ > drivers/platform/x86/asus-wmi.c | 91 +++++++++++++++++++ > include/linux/platform_data/x86/asus-wmi.h | 3 + > 3 files changed, 103 insertions(+) > > diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi > index 541dbfbbbb26..d483bc3cb2e6 100644 > --- a/Documentation/ABI/testing/sysfs-platform-asus-wmi > +++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi > @@ -67,6 +67,15 @@ Description: > * 0 - Disable, > * 1 - Enable, > > +What: /sys/devices/platform/<platform>/gpu_mux_mode > +Date: Aug 2022 > +KernelVersion: 6.0 > +Contact: "Luke Jones" <luke@xxxxxxxxxx> > +Description: > + Switch the GPU used by the hardware MUX: > + * 0 - Dedicated GPU, > + * 1 - Optimus mode, > + > What: /sys/devices/platform/<platform>/panel_od > Date: Aug 2022 > KernelVersion: 5.17 > diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c > index 78f1f3af1b12..c5fa21370481 100644 > --- a/drivers/platform/x86/asus-wmi.c > +++ b/drivers/platform/x86/asus-wmi.c > @@ -246,6 +246,9 @@ struct asus_wmi { > bool dgpu_disable_available; > bool dgpu_disable; > > + bool gpu_mux_mode_available; > + bool gpu_mux_mode; > + > bool keyboard_rgb_state_available; > bool keyboard_rgb_mode_available; > struct keyboard_rgb_led keyboard_rgb_led; > @@ -750,6 +753,86 @@ static ssize_t egpu_enable_store(struct device *dev, > > static DEVICE_ATTR_RW(egpu_enable); > > +/* gpu mux switch *************************************************************/ > +static int gpu_mux_mode_check_present(struct asus_wmi *asus) > +{ > + u32 result; > + int err; > + > + asus->gpu_mux_mode_available = false; > + > + err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_GPU_MUX, &result); > + if (err) { > + if (err == -ENODEV) > + return 0; > + return err; > + } > + > + if (result & ASUS_WMI_DSTS_PRESENCE_BIT) { > + asus->gpu_mux_mode_available = true; > + asus->gpu_mux_mode = result & ASUS_WMI_DSTS_STATUS_BIT; > + } > + > + return 0; > +} > + > +static int gpu_mux_mode_write(struct asus_wmi *asus) > +{ > + u32 retval; > + u8 value; > + int err; > + > + /* Don't rely on type conversion */ > + value = asus->gpu_mux_mode ? 1 : 0; > + > + err = asus_wmi_set_devstate(ASUS_WMI_DEVID_GPU_MUX, value, &retval); > + if (err) { > + pr_warn("Failed to set dGPU-only mode: %d\n", err); > + return err; > + } > + > + if (retval > 1) { > + pr_warn("Failed to set dGPU-only mode (retval): 0x%x\n", retval); > + return -EIO; > + } > + > + sysfs_notify(&asus->platform_device->dev.kobj, NULL, "gpu_mux_mode"); > + > + return 0; > +} > + > +static ssize_t gpu_mux_mode_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct asus_wmi *asus = dev_get_drvdata(dev); > + u8 mode = asus->gpu_mux_mode; > + > + return sysfs_emit(buf, "%d\n", mode); > +} > + > +static ssize_t gpu_mux_mode_store(struct device *dev, > + struct device_attribute *attr, > + const char *buf, size_t count) > +{ > + bool optimus; > + int result; > + > + struct asus_wmi *asus = dev_get_drvdata(dev); > + > + result = kstrtobool(buf, &optimus); > + if (result) > + return result; > + > + asus->gpu_mux_mode = optimus; > + > + result = gpu_mux_mode_write(asus); > + if (result) > + return result; > + > + return count; > +} > +static DEVICE_ATTR_RW(gpu_mux_mode); > + > /* TUF Laptop Keyboard RGB Modes **********************************************/ > static int keyboard_rgb_check_present(struct asus_wmi *asus) > { > @@ -3496,6 +3579,7 @@ static struct attribute *platform_attributes[] = { > &dev_attr_touchpad.attr, > &dev_attr_egpu_enable.attr, > &dev_attr_dgpu_disable.attr, > + &dev_attr_gpu_mux_mode.attr, > &dev_attr_keyboard_rgb_save.attr, > &dev_attr_keyboard_rgb_mode.attr, > &dev_attr_keyboard_rgb_speed.attr, > @@ -3531,6 +3615,8 @@ static umode_t asus_sysfs_is_visible(struct kobject *kobj, > ok = asus->egpu_enable_available; > else if (attr == &dev_attr_dgpu_disable.attr) > 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_keyboard_rgb_save.attr) > ok = asus->keyboard_rgb_mode_available; > else if (attr == &dev_attr_keyboard_rgb_mode.attr) > @@ -3810,6 +3896,10 @@ static int asus_wmi_add(struct platform_device *pdev) > if (err) > goto fail_dgpu_disable; > > + err = gpu_mux_mode_check_present(asus); > + if (err) > + goto fail_gpu_mux_mode; > + > err = keyboard_rgb_check_present(asus); > if (err) > goto fail_keyboard_rgb_mode; > @@ -3932,6 +4022,7 @@ static int asus_wmi_add(struct platform_device *pdev) > fail_fan_boost_mode: > fail_egpu_enable: > fail_dgpu_disable: > +fail_gpu_mux_mode: > fail_keyboard_rgb_mode: > fail_keyboard_rgb_state: > fail_platform: > diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h > index b5c966798ef8..3faeb98f6ea9 100644 > --- a/include/linux/platform_data/x86/asus-wmi.h > +++ b/include/linux/platform_data/x86/asus-wmi.h > @@ -98,6 +98,9 @@ > /* dgpu on/off */ > #define ASUS_WMI_DEVID_DGPU 0x00090020 > > +/* gpu mux switch, 0 = dGPU, 1 = Optimus */ > +#define ASUS_WMI_DEVID_GPU_MUX 0x00090016 > + > /* TUF laptop RGB control */ > #define ASUS_WMI_DEVID_TUF_RGB_MODE 0x00100056 > /* TUF laptop RGB state control */