platform-driver-x86.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53
@ 2021-08-12 12:53 JafarAkhondali
  2021-08-12 16:43 ` kernel test robot
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: JafarAkhondali @ 2021-08-12 12:53 UTC (permalink / raw)
  To: Hans de Goede, jlee, linux-kernel, platform-driver-x86, mgross
  Cc: JafarAkhondali

Hi,

The Acer Predator Helios series (usually denoted by PHxxx-yy) features
a particular key above the keyboard named "TURBO".
The turbo key does 3 things:
1. Set all fan's speeds to TURBO mode
2. Overclocks the CPU and GPU in the safe range
3. Turn on an LED just below the turbo button

All the above actions are operating using WMI function calls,
and there is no custom OC level for turbo. It acts as a flag
for enabling turbo mode instead of telling processors to use
a specific multiply of power (e.g. 1.3x of power).

I've run some benchmark tests and it worked fine:

GpuTest 0.7.0
http://www.geeks3d.com

Module: FurMark
Normal mode Score: 7289 points (FPS: 121)
Turbo mode Score: 7675 points (FPS: 127)
Settings:
- 1920x1080 fullscreen
- antialiasing: Off
- duration: 60000 ms

Renderer:
- GeForce RTX 2060/PCIe/SSE2
- OpenGL: 4.6.0 NVIDIA 460.32.03

This feature is presented by Acer officially and should not harm
hardware in any case.

A challenging part of implementing this feature is that calling
overclock function requires knowing the exact count of fans
for CPU and GPU of each model, which to the best of my
knowledge is not available in the kernel.

So after checking the official PredatorSense application methods, it
turned out they have provided the software the list of fans in each model.
I have access to the mentioned list, and all similar PH-iii-jj can be
added easily by matching "DMI_PRODUCT_NAME".

Creating a specific file for the Acer gaming features is not possible
because the current in use WMI event GUID is required for the turbo button
and it's not possible to register multiple listeners on a single WMI event.


Signed-off-by: JafarAkhondali <jafar.akhoondali@gmail.com>
---
 Changes in v5:
 - Use helper for Turbo fan mode
 - Initialize OC GPU config variables

 Changes in v4:
 - Fix Indents
 - Make functions return early

 Changes in v3:
 - Remove usages of gaming_interface
 - Add ACPI output for u32 buffer length
 - Remove set_u64 and get_u64 functions
 - Remove unrelated whitespace changes for to this patch

 Changes in v2:
 - Fix formatting problems


 drivers/platform/x86/acer-wmi.c | 179 ++++++++++++++++++++++++++++++++
 1 file changed, 179 insertions(+)

diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 85db9403cc14..c8f118fe04ac 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -60,6 +60,11 @@ MODULE_LICENSE("GPL");
 #define ACER_WMID_GET_THREEG_METHODID		10
 #define ACER_WMID_SET_THREEG_METHODID		11
 
+#define ACER_WMID_SET_GAMING_LED_METHODID 2
+#define ACER_WMID_GET_GAMING_LED_METHODID 4
+#define ACER_WMID_SET_GAMING_FAN_BEHAVIOR 14
+#define ACER_WMID_SET_GAMING_MISC_SETTING_METHODID 22
+
 /*
  * Acer ACPI method GUIDs
  */
@@ -68,6 +73,7 @@ MODULE_LICENSE("GPL");
 #define WMID_GUID1		"6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
 #define WMID_GUID2		"95764E09-FB56-4E83-B31A-37761F60994A"
 #define WMID_GUID3		"61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
+#define WMID_GUID4		"7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56"
 
 /*
  * Acer ACPI event GUIDs
@@ -81,6 +87,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
 enum acer_wmi_event_ids {
 	WMID_HOTKEY_EVENT = 0x1,
 	WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5,
+	WMID_GAMING_TURBO_KEY_EVENT = 0x7,
 };
 
 static const struct key_entry acer_wmi_keymap[] __initconst = {
@@ -215,6 +222,9 @@ struct hotkey_function_type_aa {
 #define ACER_CAP_THREEG			BIT(4)
 #define ACER_CAP_SET_FUNCTION_MODE	BIT(5)
 #define ACER_CAP_KBD_DOCK		BIT(6)
+#define ACER_CAP_TURBO_OC     BIT(7)
+#define ACER_CAP_TURBO_LED     BIT(8)
+#define ACER_CAP_TURBO_FAN     BIT(9)
 
 /*
  * Interface type flags
@@ -301,6 +311,9 @@ struct quirk_entry {
 	u8 mailled;
 	s8 brightness;
 	u8 bluetooth;
+	u8 turbo;
+	u8 cpu_fans;
+	u8 gpu_fans;
 };
 
 static struct quirk_entry *quirks;
@@ -312,6 +325,10 @@ static void __init set_quirks(void)
 
 	if (quirks->brightness)
 		interface->capability |= ACER_CAP_BRIGHTNESS;
+
+	if (quirks->turbo)
+		interface->capability |= ACER_CAP_TURBO_OC | ACER_CAP_TURBO_LED
+					 | ACER_CAP_TURBO_FAN;
 }
 
 static int __init dmi_matched(const struct dmi_system_id *dmi)
@@ -340,6 +357,12 @@ static struct quirk_entry quirk_acer_travelmate_2490 = {
 	.mailled = 1,
 };
 
+static struct quirk_entry quirk_acer_predator_ph315_53 = {
+	.turbo = 1,
+	.cpu_fans = 1,
+	.gpu_fans = 1,
+};
+
 /* This AMW0 laptop has no bluetooth */
 static struct quirk_entry quirk_medion_md_98300 = {
 	.wireless = 1,
@@ -507,6 +530,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
 		},
 		.driver_data = &quirk_acer_travelmate_2490,
 	},
+	{
+		.callback = dmi_matched,
+		.ident = "Acer Predator PH315-53",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH315-53"),
+		},
+		.driver_data = &quirk_acer_predator_ph315_53,
+	},
 	{
 		.callback = set_force_caps,
 		.ident = "Acer Aspire Switch 10E SW3-016",
@@ -1344,6 +1376,114 @@ static struct wmi_interface wmid_v2_interface = {
 	.type = ACER_WMID_v2,
 };
 
+/*
+ * WMID Gaming interface
+ */
+
+static acpi_status
+WMI_gaming_execute_u64(u32 method_id, u64 in, u64 *out)
+{
+	struct acpi_buffer input = { (acpi_size) sizeof(u64), (void *)(&in) };
+	struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *obj;
+	u32 tmp = 0;
+	acpi_status status;
+
+	status = wmi_evaluate_method(WMID_GUID4, 0, method_id, &input, &result);
+
+	if (ACPI_FAILURE(status))
+		return status;
+	obj = (union acpi_object *) result.pointer;
+
+	if (obj) {
+		if (obj->type == ACPI_TYPE_BUFFER) {
+			if (obj->buffer.length == sizeof(u32))
+				tmp = *((u32 *) obj->buffer.pointer);
+			else if (obj->buffer.length == sizeof(u64))
+				tmp = *((u64 *) obj->buffer.pointer);
+		} else if (obj->type == ACPI_TYPE_INTEGER) {
+			tmp = (u64) obj->integer.value;
+		}
+	}
+
+	if (out)
+		*out = tmp;
+
+	kfree(result.pointer);
+
+	return status;
+}
+
+static acpi_status WMID_gaming_set_u64(u64 value, u32 cap)
+{
+	u32 method_id = 0;
+
+	if (!(interface->capability & cap))
+		return AE_BAD_PARAMETER;
+
+	switch (cap) {
+	case ACER_CAP_TURBO_LED:
+		method_id = ACER_WMID_SET_GAMING_LED_METHODID;
+		break;
+	case ACER_CAP_TURBO_FAN:
+		method_id = ACER_WMID_SET_GAMING_FAN_BEHAVIOR;
+		break;
+	case ACER_CAP_TURBO_OC:
+		method_id = ACER_WMID_SET_GAMING_MISC_SETTING_METHODID;
+		break;
+	default:
+		return AE_BAD_PARAMETER;
+	}
+
+	return WMI_gaming_execute_u64(method_id, value, NULL);
+}
+
+static acpi_status WMID_gaming_get_u64(u64 *value, u32 cap)
+{
+	acpi_status status;
+	u64 result;
+	u64 input;
+	u32 method_id;
+
+	if (!(interface->capability & cap))
+		return AE_BAD_PARAMETER;
+
+	switch (cap) {
+	case ACER_CAP_TURBO_LED:
+		method_id = ACER_WMID_GET_GAMING_LED_METHODID;
+		input = 0x1;
+		break;
+	default:
+		return AE_BAD_PARAMETER;
+	}
+	status = WMI_gaming_execute_u64(method_id, input, &result);
+	if (ACPI_SUCCESS(status))
+		*value = (u64) result;
+
+	return status;
+}
+
+void WMID_gaming_set_fan_mode(u8 fan_mode)
+{
+	/* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
+	u64 gpu_fan_config1 = 0, gpu_fan_config2 = 0;
+	int i;
+
+	if (quirks->cpu_fans > 0)
+		gpu_fan_config2 |= 1;
+	for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
+		gpu_fan_config2 |= 1 << (i + 1);
+	for (i = 0; i < quirks->gpu_fans; ++i)
+		gpu_fan_config2 |= 1 << (i + 3);
+	if (quirks->cpu_fans > 0)
+		gpu_fan_config1 |= fan_mode;
+	for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
+		gpu_fan_config1 |= fan_mode << (2 * i + 2);
+	for (i = 0; i < quirks->gpu_fans; ++i)
+		gpu_fan_config1 |= fan_mode << (2 * i + 6);
+	WMID_gaming_set_u64(gpu_fan_config2 | gpu_fan_config1 << 16, ACER_CAP_TURBO_FAN);
+}
+
 /*
  * Generic Device (interface-independent)
  */
@@ -1575,6 +1715,41 @@ static int acer_gsensor_event(void)
 	return 0;
 }
 
+/*
+ *  Predator series turbo button
+ */
+static int acer_toggle_turbo(void)
+{
+	u64 turbo_led_state;
+
+	/* Get current state from turbo button */
+	if (ACPI_FAILURE(WMID_gaming_get_u64(&turbo_led_state, ACER_CAP_TURBO_LED)))
+		return -1;
+
+	if (turbo_led_state) {
+		/* Turn off turbo led */
+		WMID_gaming_set_u64(0x1, ACER_CAP_TURBO_LED);
+
+		/* Set FAN mode to auto */
+		WMID_gaming_set_fan_mode(0x1);
+
+		/* Set OC to normal */
+		WMID_gaming_set_u64(0x5, ACER_CAP_TURBO_OC);
+		WMID_gaming_set_u64(0x7, ACER_CAP_TURBO_OC);
+	} else {
+		/* Turn on turbo led */
+		WMID_gaming_set_u64(0x10001, ACER_CAP_TURBO_LED);
+
+		/* Set FAN mode to turbo */
+		WMID_gaming_set_fan_mode(0x2);
+
+		/* Set OC to turbo mode */
+		WMID_gaming_set_u64(0x205, ACER_CAP_TURBO_OC);
+		WMID_gaming_set_u64(0x207, ACER_CAP_TURBO_OC);
+	}
+	return turbo_led_state;
+}
+
 /*
  * Switch series keyboard dock status
  */
@@ -1872,6 +2047,10 @@ static void acer_wmi_notify(u32 value, void *context)
 		acer_gsensor_event();
 		acer_kbd_dock_event(&return_value);
 		break;
+	case WMID_GAMING_TURBO_KEY_EVENT:
+		if (return_value.key_num == 0x4)
+			acer_toggle_turbo();
+		break;
 	default:
 		pr_warn("Unknown function number - %d - %d\n",
 			return_value.function, return_value.key_num);
-- 
2.30.2


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53
  2021-08-12 12:53 [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53 JafarAkhondali
@ 2021-08-12 16:43 ` kernel test robot
  2021-08-12 17:57 ` kernel test robot
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2021-08-12 16:43 UTC (permalink / raw)
  To: JafarAkhondali, Hans de Goede, jlee, linux-kernel,
	platform-driver-x86, mgross
  Cc: kbuild-all, JafarAkhondali

[-- Attachment #1: Type: text/plain, Size: 2632 bytes --]

Hi JafarAkhondali,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.14-rc5 next-20210812]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/JafarAkhondali/platform-x86-acer-wmi-Add-Turbo-Mode-support-for-Acer-PH315-53/20210812-212347
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 1746f4db513563bb22e0ba0c419d0c90912dfae1
config: i386-randconfig-a015-20210812 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
        # https://github.com/0day-ci/linux/commit/292cfa3c9af2eb61b782c6d94d08d35300318ca3
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review JafarAkhondali/platform-x86-acer-wmi-Add-Turbo-Mode-support-for-Acer-PH315-53/20210812-212347
        git checkout 292cfa3c9af2eb61b782c6d94d08d35300318ca3
        # save the attached .config to linux build tree
        make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/platform/x86/acer-wmi.c:1466:6: warning: no previous prototype for 'WMID_gaming_set_fan_mode' [-Wmissing-prototypes]
    1466 | void WMID_gaming_set_fan_mode(u8 fan_mode)
         |      ^~~~~~~~~~~~~~~~~~~~~~~~


vim +/WMID_gaming_set_fan_mode +1466 drivers/platform/x86/acer-wmi.c

  1465	
> 1466	void WMID_gaming_set_fan_mode(u8 fan_mode)
  1467	{
  1468		/* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
  1469		u64 gpu_fan_config1 = 0, gpu_fan_config2 = 0;
  1470		int i;
  1471	
  1472		if (quirks->cpu_fans > 0)
  1473			gpu_fan_config2 |= 1;
  1474		for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
  1475			gpu_fan_config2 |= 1 << (i + 1);
  1476		for (i = 0; i < quirks->gpu_fans; ++i)
  1477			gpu_fan_config2 |= 1 << (i + 3);
  1478		if (quirks->cpu_fans > 0)
  1479			gpu_fan_config1 |= fan_mode;
  1480		for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
  1481			gpu_fan_config1 |= fan_mode << (2 * i + 2);
  1482		for (i = 0; i < quirks->gpu_fans; ++i)
  1483			gpu_fan_config1 |= fan_mode << (2 * i + 6);
  1484		WMID_gaming_set_u64(gpu_fan_config2 | gpu_fan_config1 << 16, ACER_CAP_TURBO_FAN);
  1485	}
  1486	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 42845 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53
  2021-08-12 12:53 [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53 JafarAkhondali
  2021-08-12 16:43 ` kernel test robot
@ 2021-08-12 17:57 ` kernel test robot
  2021-08-12 20:15 ` Hans de Goede
  2021-08-13 11:22 ` Hans de Goede
  3 siblings, 0 replies; 7+ messages in thread
From: kernel test robot @ 2021-08-12 17:57 UTC (permalink / raw)
  To: JafarAkhondali, Hans de Goede, jlee, linux-kernel,
	platform-driver-x86, mgross
  Cc: clang-built-linux, kbuild-all, JafarAkhondali

[-- Attachment #1: Type: text/plain, Size: 3095 bytes --]

Hi JafarAkhondali,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.14-rc5 next-20210812]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/JafarAkhondali/platform-x86-acer-wmi-Add-Turbo-Mode-support-for-Acer-PH315-53/20210812-212347
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 1746f4db513563bb22e0ba0c419d0c90912dfae1
config: x86_64-randconfig-a011-20210812 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 767496d19cb9a1fbba57ff08095faa161998ee36)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/292cfa3c9af2eb61b782c6d94d08d35300318ca3
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review JafarAkhondali/platform-x86-acer-wmi-Add-Turbo-Mode-support-for-Acer-PH315-53/20210812-212347
        git checkout 292cfa3c9af2eb61b782c6d94d08d35300318ca3
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/platform/x86/acer-wmi.c:1466:6: warning: no previous prototype for function 'WMID_gaming_set_fan_mode' [-Wmissing-prototypes]
   void WMID_gaming_set_fan_mode(u8 fan_mode)
        ^
   drivers/platform/x86/acer-wmi.c:1466:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
   void WMID_gaming_set_fan_mode(u8 fan_mode)
   ^
   static 
   1 warning generated.


vim +/WMID_gaming_set_fan_mode +1466 drivers/platform/x86/acer-wmi.c

  1465	
> 1466	void WMID_gaming_set_fan_mode(u8 fan_mode)
  1467	{
  1468		/* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
  1469		u64 gpu_fan_config1 = 0, gpu_fan_config2 = 0;
  1470		int i;
  1471	
  1472		if (quirks->cpu_fans > 0)
  1473			gpu_fan_config2 |= 1;
  1474		for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
  1475			gpu_fan_config2 |= 1 << (i + 1);
  1476		for (i = 0; i < quirks->gpu_fans; ++i)
  1477			gpu_fan_config2 |= 1 << (i + 3);
  1478		if (quirks->cpu_fans > 0)
  1479			gpu_fan_config1 |= fan_mode;
  1480		for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
  1481			gpu_fan_config1 |= fan_mode << (2 * i + 2);
  1482		for (i = 0; i < quirks->gpu_fans; ++i)
  1483			gpu_fan_config1 |= fan_mode << (2 * i + 6);
  1484		WMID_gaming_set_u64(gpu_fan_config2 | gpu_fan_config1 << 16, ACER_CAP_TURBO_FAN);
  1485	}
  1486	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 41114 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53
  2021-08-12 12:53 [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53 JafarAkhondali
  2021-08-12 16:43 ` kernel test robot
  2021-08-12 17:57 ` kernel test robot
@ 2021-08-12 20:15 ` Hans de Goede
  2021-08-13 11:22 ` Hans de Goede
  3 siblings, 0 replies; 7+ messages in thread
From: Hans de Goede @ 2021-08-12 20:15 UTC (permalink / raw)
  To: JafarAkhondali, jlee, linux-kernel, platform-driver-x86, mgross

Hi,

On 8/12/21 2:53 PM, JafarAkhondali wrote:
> Hi,
> 
> The Acer Predator Helios series (usually denoted by PHxxx-yy) features
> a particular key above the keyboard named "TURBO".
> The turbo key does 3 things:
> 1. Set all fan's speeds to TURBO mode
> 2. Overclocks the CPU and GPU in the safe range
> 3. Turn on an LED just below the turbo button
> 
> All the above actions are operating using WMI function calls,
> and there is no custom OC level for turbo. It acts as a flag
> for enabling turbo mode instead of telling processors to use
> a specific multiply of power (e.g. 1.3x of power).
> 
> I've run some benchmark tests and it worked fine:
> 
> GpuTest 0.7.0
> http://www.geeks3d.com
> 
> Module: FurMark
> Normal mode Score: 7289 points (FPS: 121)
> Turbo mode Score: 7675 points (FPS: 127)
> Settings:
> - 1920x1080 fullscreen
> - antialiasing: Off
> - duration: 60000 ms
> 
> Renderer:
> - GeForce RTX 2060/PCIe/SSE2
> - OpenGL: 4.6.0 NVIDIA 460.32.03
> 
> This feature is presented by Acer officially and should not harm
> hardware in any case.
> 
> A challenging part of implementing this feature is that calling
> overclock function requires knowing the exact count of fans
> for CPU and GPU of each model, which to the best of my
> knowledge is not available in the kernel.
> 
> So after checking the official PredatorSense application methods, it
> turned out they have provided the software the list of fans in each model.
> I have access to the mentioned list, and all similar PH-iii-jj can be
> added easily by matching "DMI_PRODUCT_NAME".
> 
> Creating a specific file for the Acer gaming features is not possible
> because the current in use WMI event GUID is required for the turbo button
> and it's not possible to register multiple listeners on a single WMI event.
> 
> 
> Signed-off-by: JafarAkhondali <jafar.akhoondali@gmail.com>
> ---
>  Changes in v5:
>  - Use helper for Turbo fan mode
>  - Initialize OC GPU config variables

Thanks this looks good now. I'll apply this tomorrow, I'll
add "static" to the new helper when merging this (as pointed
out by the buildbot), there is no need to send a new version for that.

Regards,

Hans



> 
>  Changes in v4:
>  - Fix Indents
>  - Make functions return early
> 
>  Changes in v3:
>  - Remove usages of gaming_interface
>  - Add ACPI output for u32 buffer length
>  - Remove set_u64 and get_u64 functions
>  - Remove unrelated whitespace changes for to this patch
> 
>  Changes in v2:
>  - Fix formatting problems
> 
> 
>  drivers/platform/x86/acer-wmi.c | 179 ++++++++++++++++++++++++++++++++
>  1 file changed, 179 insertions(+)
> 
> diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
> index 85db9403cc14..c8f118fe04ac 100644
> --- a/drivers/platform/x86/acer-wmi.c
> +++ b/drivers/platform/x86/acer-wmi.c
> @@ -60,6 +60,11 @@ MODULE_LICENSE("GPL");
>  #define ACER_WMID_GET_THREEG_METHODID		10
>  #define ACER_WMID_SET_THREEG_METHODID		11
>  
> +#define ACER_WMID_SET_GAMING_LED_METHODID 2
> +#define ACER_WMID_GET_GAMING_LED_METHODID 4
> +#define ACER_WMID_SET_GAMING_FAN_BEHAVIOR 14
> +#define ACER_WMID_SET_GAMING_MISC_SETTING_METHODID 22
> +
>  /*
>   * Acer ACPI method GUIDs
>   */
> @@ -68,6 +73,7 @@ MODULE_LICENSE("GPL");
>  #define WMID_GUID1		"6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
>  #define WMID_GUID2		"95764E09-FB56-4E83-B31A-37761F60994A"
>  #define WMID_GUID3		"61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
> +#define WMID_GUID4		"7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56"
>  
>  /*
>   * Acer ACPI event GUIDs
> @@ -81,6 +87,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
>  enum acer_wmi_event_ids {
>  	WMID_HOTKEY_EVENT = 0x1,
>  	WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5,
> +	WMID_GAMING_TURBO_KEY_EVENT = 0x7,
>  };
>  
>  static const struct key_entry acer_wmi_keymap[] __initconst = {
> @@ -215,6 +222,9 @@ struct hotkey_function_type_aa {
>  #define ACER_CAP_THREEG			BIT(4)
>  #define ACER_CAP_SET_FUNCTION_MODE	BIT(5)
>  #define ACER_CAP_KBD_DOCK		BIT(6)
> +#define ACER_CAP_TURBO_OC     BIT(7)
> +#define ACER_CAP_TURBO_LED     BIT(8)
> +#define ACER_CAP_TURBO_FAN     BIT(9)
>  
>  /*
>   * Interface type flags
> @@ -301,6 +311,9 @@ struct quirk_entry {
>  	u8 mailled;
>  	s8 brightness;
>  	u8 bluetooth;
> +	u8 turbo;
> +	u8 cpu_fans;
> +	u8 gpu_fans;
>  };
>  
>  static struct quirk_entry *quirks;
> @@ -312,6 +325,10 @@ static void __init set_quirks(void)
>  
>  	if (quirks->brightness)
>  		interface->capability |= ACER_CAP_BRIGHTNESS;
> +
> +	if (quirks->turbo)
> +		interface->capability |= ACER_CAP_TURBO_OC | ACER_CAP_TURBO_LED
> +					 | ACER_CAP_TURBO_FAN;
>  }
>  
>  static int __init dmi_matched(const struct dmi_system_id *dmi)
> @@ -340,6 +357,12 @@ static struct quirk_entry quirk_acer_travelmate_2490 = {
>  	.mailled = 1,
>  };
>  
> +static struct quirk_entry quirk_acer_predator_ph315_53 = {
> +	.turbo = 1,
> +	.cpu_fans = 1,
> +	.gpu_fans = 1,
> +};
> +
>  /* This AMW0 laptop has no bluetooth */
>  static struct quirk_entry quirk_medion_md_98300 = {
>  	.wireless = 1,
> @@ -507,6 +530,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
>  		},
>  		.driver_data = &quirk_acer_travelmate_2490,
>  	},
> +	{
> +		.callback = dmi_matched,
> +		.ident = "Acer Predator PH315-53",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH315-53"),
> +		},
> +		.driver_data = &quirk_acer_predator_ph315_53,
> +	},
>  	{
>  		.callback = set_force_caps,
>  		.ident = "Acer Aspire Switch 10E SW3-016",
> @@ -1344,6 +1376,114 @@ static struct wmi_interface wmid_v2_interface = {
>  	.type = ACER_WMID_v2,
>  };
>  
> +/*
> + * WMID Gaming interface
> + */
> +
> +static acpi_status
> +WMI_gaming_execute_u64(u32 method_id, u64 in, u64 *out)
> +{
> +	struct acpi_buffer input = { (acpi_size) sizeof(u64), (void *)(&in) };
> +	struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
> +	union acpi_object *obj;
> +	u32 tmp = 0;
> +	acpi_status status;
> +
> +	status = wmi_evaluate_method(WMID_GUID4, 0, method_id, &input, &result);
> +
> +	if (ACPI_FAILURE(status))
> +		return status;
> +	obj = (union acpi_object *) result.pointer;
> +
> +	if (obj) {
> +		if (obj->type == ACPI_TYPE_BUFFER) {
> +			if (obj->buffer.length == sizeof(u32))
> +				tmp = *((u32 *) obj->buffer.pointer);
> +			else if (obj->buffer.length == sizeof(u64))
> +				tmp = *((u64 *) obj->buffer.pointer);
> +		} else if (obj->type == ACPI_TYPE_INTEGER) {
> +			tmp = (u64) obj->integer.value;
> +		}
> +	}
> +
> +	if (out)
> +		*out = tmp;
> +
> +	kfree(result.pointer);
> +
> +	return status;
> +}
> +
> +static acpi_status WMID_gaming_set_u64(u64 value, u32 cap)
> +{
> +	u32 method_id = 0;
> +
> +	if (!(interface->capability & cap))
> +		return AE_BAD_PARAMETER;
> +
> +	switch (cap) {
> +	case ACER_CAP_TURBO_LED:
> +		method_id = ACER_WMID_SET_GAMING_LED_METHODID;
> +		break;
> +	case ACER_CAP_TURBO_FAN:
> +		method_id = ACER_WMID_SET_GAMING_FAN_BEHAVIOR;
> +		break;
> +	case ACER_CAP_TURBO_OC:
> +		method_id = ACER_WMID_SET_GAMING_MISC_SETTING_METHODID;
> +		break;
> +	default:
> +		return AE_BAD_PARAMETER;
> +	}
> +
> +	return WMI_gaming_execute_u64(method_id, value, NULL);
> +}
> +
> +static acpi_status WMID_gaming_get_u64(u64 *value, u32 cap)
> +{
> +	acpi_status status;
> +	u64 result;
> +	u64 input;
> +	u32 method_id;
> +
> +	if (!(interface->capability & cap))
> +		return AE_BAD_PARAMETER;
> +
> +	switch (cap) {
> +	case ACER_CAP_TURBO_LED:
> +		method_id = ACER_WMID_GET_GAMING_LED_METHODID;
> +		input = 0x1;
> +		break;
> +	default:
> +		return AE_BAD_PARAMETER;
> +	}
> +	status = WMI_gaming_execute_u64(method_id, input, &result);
> +	if (ACPI_SUCCESS(status))
> +		*value = (u64) result;
> +
> +	return status;
> +}
> +
> +void WMID_gaming_set_fan_mode(u8 fan_mode)
> +{
> +	/* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
> +	u64 gpu_fan_config1 = 0, gpu_fan_config2 = 0;
> +	int i;
> +
> +	if (quirks->cpu_fans > 0)
> +		gpu_fan_config2 |= 1;
> +	for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
> +		gpu_fan_config2 |= 1 << (i + 1);
> +	for (i = 0; i < quirks->gpu_fans; ++i)
> +		gpu_fan_config2 |= 1 << (i + 3);
> +	if (quirks->cpu_fans > 0)
> +		gpu_fan_config1 |= fan_mode;
> +	for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
> +		gpu_fan_config1 |= fan_mode << (2 * i + 2);
> +	for (i = 0; i < quirks->gpu_fans; ++i)
> +		gpu_fan_config1 |= fan_mode << (2 * i + 6);
> +	WMID_gaming_set_u64(gpu_fan_config2 | gpu_fan_config1 << 16, ACER_CAP_TURBO_FAN);
> +}
> +
>  /*
>   * Generic Device (interface-independent)
>   */
> @@ -1575,6 +1715,41 @@ static int acer_gsensor_event(void)
>  	return 0;
>  }
>  
> +/*
> + *  Predator series turbo button
> + */
> +static int acer_toggle_turbo(void)
> +{
> +	u64 turbo_led_state;
> +
> +	/* Get current state from turbo button */
> +	if (ACPI_FAILURE(WMID_gaming_get_u64(&turbo_led_state, ACER_CAP_TURBO_LED)))
> +		return -1;
> +
> +	if (turbo_led_state) {
> +		/* Turn off turbo led */
> +		WMID_gaming_set_u64(0x1, ACER_CAP_TURBO_LED);
> +
> +		/* Set FAN mode to auto */
> +		WMID_gaming_set_fan_mode(0x1);
> +
> +		/* Set OC to normal */
> +		WMID_gaming_set_u64(0x5, ACER_CAP_TURBO_OC);
> +		WMID_gaming_set_u64(0x7, ACER_CAP_TURBO_OC);
> +	} else {
> +		/* Turn on turbo led */
> +		WMID_gaming_set_u64(0x10001, ACER_CAP_TURBO_LED);
> +
> +		/* Set FAN mode to turbo */
> +		WMID_gaming_set_fan_mode(0x2);
> +
> +		/* Set OC to turbo mode */
> +		WMID_gaming_set_u64(0x205, ACER_CAP_TURBO_OC);
> +		WMID_gaming_set_u64(0x207, ACER_CAP_TURBO_OC);
> +	}
> +	return turbo_led_state;
> +}
> +
>  /*
>   * Switch series keyboard dock status
>   */
> @@ -1872,6 +2047,10 @@ static void acer_wmi_notify(u32 value, void *context)
>  		acer_gsensor_event();
>  		acer_kbd_dock_event(&return_value);
>  		break;
> +	case WMID_GAMING_TURBO_KEY_EVENT:
> +		if (return_value.key_num == 0x4)
> +			acer_toggle_turbo();
> +		break;
>  	default:
>  		pr_warn("Unknown function number - %d - %d\n",
>  			return_value.function, return_value.key_num);
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53
  2021-08-12 12:53 [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53 JafarAkhondali
                   ` (2 preceding siblings ...)
  2021-08-12 20:15 ` Hans de Goede
@ 2021-08-13 11:22 ` Hans de Goede
  2021-08-14 11:40   ` Jafar Akhondali
  3 siblings, 1 reply; 7+ messages in thread
From: Hans de Goede @ 2021-08-13 11:22 UTC (permalink / raw)
  To: JafarAkhondali, jlee, linux-kernel, platform-driver-x86, mgross

Hi,

On 8/12/21 2:53 PM, JafarAkhondali wrote:
> Hi,
> 
> The Acer Predator Helios series (usually denoted by PHxxx-yy) features
> a particular key above the keyboard named "TURBO".
> The turbo key does 3 things:
> 1. Set all fan's speeds to TURBO mode
> 2. Overclocks the CPU and GPU in the safe range
> 3. Turn on an LED just below the turbo button
> 
> All the above actions are operating using WMI function calls,
> and there is no custom OC level for turbo. It acts as a flag
> for enabling turbo mode instead of telling processors to use
> a specific multiply of power (e.g. 1.3x of power).
> 
> I've run some benchmark tests and it worked fine:
> 
> GpuTest 0.7.0
> http://www.geeks3d.com
> 
> Module: FurMark
> Normal mode Score: 7289 points (FPS: 121)
> Turbo mode Score: 7675 points (FPS: 127)
> Settings:
> - 1920x1080 fullscreen
> - antialiasing: Off
> - duration: 60000 ms
> 
> Renderer:
> - GeForce RTX 2060/PCIe/SSE2
> - OpenGL: 4.6.0 NVIDIA 460.32.03
> 
> This feature is presented by Acer officially and should not harm
> hardware in any case.
> 
> A challenging part of implementing this feature is that calling
> overclock function requires knowing the exact count of fans
> for CPU and GPU of each model, which to the best of my
> knowledge is not available in the kernel.
> 
> So after checking the official PredatorSense application methods, it
> turned out they have provided the software the list of fans in each model.
> I have access to the mentioned list, and all similar PH-iii-jj can be
> added easily by matching "DMI_PRODUCT_NAME".
> 
> Creating a specific file for the Acer gaming features is not possible
> because the current in use WMI event GUID is required for the turbo button
> and it's not possible to register multiple listeners on a single WMI event.
> 
> 
> Signed-off-by: JafarAkhondali <jafar.akhoondali@gmail.com>

Thank you for your patch, I've applied this patch to my review-hans 
branch:
https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/log/?h=review-hans

Note it will show up in my review-hans branch once I've pushed my
local branch there, which might take a while.

Once I've run some tests on this branch the patches there will be
added to the platform-drivers-x86/for-next branch and eventually
will be included in the pdx86 pull-request to Linus for the next
merge-window.

Regards,

Hans




> ---
>  Changes in v5:
>  - Use helper for Turbo fan mode
>  - Initialize OC GPU config variables
> 
>  Changes in v4:
>  - Fix Indents
>  - Make functions return early
> 
>  Changes in v3:
>  - Remove usages of gaming_interface
>  - Add ACPI output for u32 buffer length
>  - Remove set_u64 and get_u64 functions
>  - Remove unrelated whitespace changes for to this patch
> 
>  Changes in v2:
>  - Fix formatting problems
> 
> 
>  drivers/platform/x86/acer-wmi.c | 179 ++++++++++++++++++++++++++++++++
>  1 file changed, 179 insertions(+)
> 
> diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
> index 85db9403cc14..c8f118fe04ac 100644
> --- a/drivers/platform/x86/acer-wmi.c
> +++ b/drivers/platform/x86/acer-wmi.c
> @@ -60,6 +60,11 @@ MODULE_LICENSE("GPL");
>  #define ACER_WMID_GET_THREEG_METHODID		10
>  #define ACER_WMID_SET_THREEG_METHODID		11
>  
> +#define ACER_WMID_SET_GAMING_LED_METHODID 2
> +#define ACER_WMID_GET_GAMING_LED_METHODID 4
> +#define ACER_WMID_SET_GAMING_FAN_BEHAVIOR 14
> +#define ACER_WMID_SET_GAMING_MISC_SETTING_METHODID 22
> +
>  /*
>   * Acer ACPI method GUIDs
>   */
> @@ -68,6 +73,7 @@ MODULE_LICENSE("GPL");
>  #define WMID_GUID1		"6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
>  #define WMID_GUID2		"95764E09-FB56-4E83-B31A-37761F60994A"
>  #define WMID_GUID3		"61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
> +#define WMID_GUID4		"7A4DDFE7-5B5D-40B4-8595-4408E0CC7F56"
>  
>  /*
>   * Acer ACPI event GUIDs
> @@ -81,6 +87,7 @@ MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
>  enum acer_wmi_event_ids {
>  	WMID_HOTKEY_EVENT = 0x1,
>  	WMID_ACCEL_OR_KBD_DOCK_EVENT = 0x5,
> +	WMID_GAMING_TURBO_KEY_EVENT = 0x7,
>  };
>  
>  static const struct key_entry acer_wmi_keymap[] __initconst = {
> @@ -215,6 +222,9 @@ struct hotkey_function_type_aa {
>  #define ACER_CAP_THREEG			BIT(4)
>  #define ACER_CAP_SET_FUNCTION_MODE	BIT(5)
>  #define ACER_CAP_KBD_DOCK		BIT(6)
> +#define ACER_CAP_TURBO_OC     BIT(7)
> +#define ACER_CAP_TURBO_LED     BIT(8)
> +#define ACER_CAP_TURBO_FAN     BIT(9)
>  
>  /*
>   * Interface type flags
> @@ -301,6 +311,9 @@ struct quirk_entry {
>  	u8 mailled;
>  	s8 brightness;
>  	u8 bluetooth;
> +	u8 turbo;
> +	u8 cpu_fans;
> +	u8 gpu_fans;
>  };
>  
>  static struct quirk_entry *quirks;
> @@ -312,6 +325,10 @@ static void __init set_quirks(void)
>  
>  	if (quirks->brightness)
>  		interface->capability |= ACER_CAP_BRIGHTNESS;
> +
> +	if (quirks->turbo)
> +		interface->capability |= ACER_CAP_TURBO_OC | ACER_CAP_TURBO_LED
> +					 | ACER_CAP_TURBO_FAN;
>  }
>  
>  static int __init dmi_matched(const struct dmi_system_id *dmi)
> @@ -340,6 +357,12 @@ static struct quirk_entry quirk_acer_travelmate_2490 = {
>  	.mailled = 1,
>  };
>  
> +static struct quirk_entry quirk_acer_predator_ph315_53 = {
> +	.turbo = 1,
> +	.cpu_fans = 1,
> +	.gpu_fans = 1,
> +};
> +
>  /* This AMW0 laptop has no bluetooth */
>  static struct quirk_entry quirk_medion_md_98300 = {
>  	.wireless = 1,
> @@ -507,6 +530,15 @@ static const struct dmi_system_id acer_quirks[] __initconst = {
>  		},
>  		.driver_data = &quirk_acer_travelmate_2490,
>  	},
> +	{
> +		.callback = dmi_matched,
> +		.ident = "Acer Predator PH315-53",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Predator PH315-53"),
> +		},
> +		.driver_data = &quirk_acer_predator_ph315_53,
> +	},
>  	{
>  		.callback = set_force_caps,
>  		.ident = "Acer Aspire Switch 10E SW3-016",
> @@ -1344,6 +1376,114 @@ static struct wmi_interface wmid_v2_interface = {
>  	.type = ACER_WMID_v2,
>  };
>  
> +/*
> + * WMID Gaming interface
> + */
> +
> +static acpi_status
> +WMI_gaming_execute_u64(u32 method_id, u64 in, u64 *out)
> +{
> +	struct acpi_buffer input = { (acpi_size) sizeof(u64), (void *)(&in) };
> +	struct acpi_buffer result = { ACPI_ALLOCATE_BUFFER, NULL };
> +	union acpi_object *obj;
> +	u32 tmp = 0;
> +	acpi_status status;
> +
> +	status = wmi_evaluate_method(WMID_GUID4, 0, method_id, &input, &result);
> +
> +	if (ACPI_FAILURE(status))
> +		return status;
> +	obj = (union acpi_object *) result.pointer;
> +
> +	if (obj) {
> +		if (obj->type == ACPI_TYPE_BUFFER) {
> +			if (obj->buffer.length == sizeof(u32))
> +				tmp = *((u32 *) obj->buffer.pointer);
> +			else if (obj->buffer.length == sizeof(u64))
> +				tmp = *((u64 *) obj->buffer.pointer);
> +		} else if (obj->type == ACPI_TYPE_INTEGER) {
> +			tmp = (u64) obj->integer.value;
> +		}
> +	}
> +
> +	if (out)
> +		*out = tmp;
> +
> +	kfree(result.pointer);
> +
> +	return status;
> +}
> +
> +static acpi_status WMID_gaming_set_u64(u64 value, u32 cap)
> +{
> +	u32 method_id = 0;
> +
> +	if (!(interface->capability & cap))
> +		return AE_BAD_PARAMETER;
> +
> +	switch (cap) {
> +	case ACER_CAP_TURBO_LED:
> +		method_id = ACER_WMID_SET_GAMING_LED_METHODID;
> +		break;
> +	case ACER_CAP_TURBO_FAN:
> +		method_id = ACER_WMID_SET_GAMING_FAN_BEHAVIOR;
> +		break;
> +	case ACER_CAP_TURBO_OC:
> +		method_id = ACER_WMID_SET_GAMING_MISC_SETTING_METHODID;
> +		break;
> +	default:
> +		return AE_BAD_PARAMETER;
> +	}
> +
> +	return WMI_gaming_execute_u64(method_id, value, NULL);
> +}
> +
> +static acpi_status WMID_gaming_get_u64(u64 *value, u32 cap)
> +{
> +	acpi_status status;
> +	u64 result;
> +	u64 input;
> +	u32 method_id;
> +
> +	if (!(interface->capability & cap))
> +		return AE_BAD_PARAMETER;
> +
> +	switch (cap) {
> +	case ACER_CAP_TURBO_LED:
> +		method_id = ACER_WMID_GET_GAMING_LED_METHODID;
> +		input = 0x1;
> +		break;
> +	default:
> +		return AE_BAD_PARAMETER;
> +	}
> +	status = WMI_gaming_execute_u64(method_id, input, &result);
> +	if (ACPI_SUCCESS(status))
> +		*value = (u64) result;
> +
> +	return status;
> +}
> +
> +void WMID_gaming_set_fan_mode(u8 fan_mode)
> +{
> +	/* fan_mode = 1 is used for auto, fan_mode = 2 used for turbo*/
> +	u64 gpu_fan_config1 = 0, gpu_fan_config2 = 0;
> +	int i;
> +
> +	if (quirks->cpu_fans > 0)
> +		gpu_fan_config2 |= 1;
> +	for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
> +		gpu_fan_config2 |= 1 << (i + 1);
> +	for (i = 0; i < quirks->gpu_fans; ++i)
> +		gpu_fan_config2 |= 1 << (i + 3);
> +	if (quirks->cpu_fans > 0)
> +		gpu_fan_config1 |= fan_mode;
> +	for (i = 0; i < (quirks->cpu_fans + quirks->gpu_fans); ++i)
> +		gpu_fan_config1 |= fan_mode << (2 * i + 2);
> +	for (i = 0; i < quirks->gpu_fans; ++i)
> +		gpu_fan_config1 |= fan_mode << (2 * i + 6);
> +	WMID_gaming_set_u64(gpu_fan_config2 | gpu_fan_config1 << 16, ACER_CAP_TURBO_FAN);
> +}
> +
>  /*
>   * Generic Device (interface-independent)
>   */
> @@ -1575,6 +1715,41 @@ static int acer_gsensor_event(void)
>  	return 0;
>  }
>  
> +/*
> + *  Predator series turbo button
> + */
> +static int acer_toggle_turbo(void)
> +{
> +	u64 turbo_led_state;
> +
> +	/* Get current state from turbo button */
> +	if (ACPI_FAILURE(WMID_gaming_get_u64(&turbo_led_state, ACER_CAP_TURBO_LED)))
> +		return -1;
> +
> +	if (turbo_led_state) {
> +		/* Turn off turbo led */
> +		WMID_gaming_set_u64(0x1, ACER_CAP_TURBO_LED);
> +
> +		/* Set FAN mode to auto */
> +		WMID_gaming_set_fan_mode(0x1);
> +
> +		/* Set OC to normal */
> +		WMID_gaming_set_u64(0x5, ACER_CAP_TURBO_OC);
> +		WMID_gaming_set_u64(0x7, ACER_CAP_TURBO_OC);
> +	} else {
> +		/* Turn on turbo led */
> +		WMID_gaming_set_u64(0x10001, ACER_CAP_TURBO_LED);
> +
> +		/* Set FAN mode to turbo */
> +		WMID_gaming_set_fan_mode(0x2);
> +
> +		/* Set OC to turbo mode */
> +		WMID_gaming_set_u64(0x205, ACER_CAP_TURBO_OC);
> +		WMID_gaming_set_u64(0x207, ACER_CAP_TURBO_OC);
> +	}
> +	return turbo_led_state;
> +}
> +
>  /*
>   * Switch series keyboard dock status
>   */
> @@ -1872,6 +2047,10 @@ static void acer_wmi_notify(u32 value, void *context)
>  		acer_gsensor_event();
>  		acer_kbd_dock_event(&return_value);
>  		break;
> +	case WMID_GAMING_TURBO_KEY_EVENT:
> +		if (return_value.key_num == 0x4)
> +			acer_toggle_turbo();
> +		break;
>  	default:
>  		pr_warn("Unknown function number - %d - %d\n",
>  			return_value.function, return_value.key_num);
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53
  2021-08-13 11:22 ` Hans de Goede
@ 2021-08-14 11:40   ` Jafar Akhondali
  2021-08-15 13:50     ` Hans de Goede
  0 siblings, 1 reply; 7+ messages in thread
From: Jafar Akhondali @ 2021-08-14 11:40 UTC (permalink / raw)
  To: Hans de Goede; +Cc: jlee, linux-kernel, platform-driver-x86, mgross

 Hi Hans,
Thank you for your efforts on the patch, I've sure learned a lot from
your comments as this
was my first contribution to Linux kernel.

Just an extra question, for the next patch I'm gonna send turbo mode support for
14 other Acer Predator laptops. The only required change is that I should add
"quirk_entry" for GPU and CPU fan count, and match product names to their quirk.

12 of these Predator laptops have exactly 1 fan for CPU and 1 fan for GPU,
but two of them have 2 fans for GPU and 1 for CPU. So my question is should
I add the quirks per product (which will end up to have 14 quirks,
same as current patch) like:

static struct quirk_entry quirk_acer_predator_ph315_53 = {
      .turbo = 1,
      .cpu_fans = 1,
      .gpu_fans = 1,
};

or should I specify the quirk per fan count like this one:

static struct quirk_entry quirk_acer_predator_gpu_fan_one_cpu_fan_one = {
      .turbo = 1,
      .cpu_fans = 1,
      .gpu_fans = 1,
};

and then set different matched DMI product names to the above quirk?

The first approach is more verbose, the second uses less code.
If possible, I would like to know your thoughts on this.

Thanks in advance,

Best,

Jafar

On Fri, Aug 13, 2021 at 3:52 PM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi,
>
> On 8/12/21 2:53 PM, JafarAkhondali wrote:
> > Hi,
> >
> > The Acer Predator Helios series (usually denoted by PHxxx-yy) features
> > a particular key above the keyboard named "TURBO".
> > The turbo key does 3 things:
> > 1. Set all fan's speeds to TURBO mode
> > 2. Overclocks the CPU and GPU in the safe range
> > 3. Turn on an LED just below the turbo button
> >
> > All the above actions are operating using WMI function calls,
> > and there is no custom OC level for turbo. It acts as a flag
> > for enabling turbo mode instead of telling processors to use
> > a specific multiply of power (e.g. 1.3x of power).
> >
> > I've run some benchmark tests and it worked fine:
> >
> > GpuTest 0.7.0
> > http://www.geeks3d.com
> >
> > Module: FurMark
> > Normal mode Score: 7289 points (FPS: 121)
> > Turbo mode Score: 7675 points (FPS: 127)
> > Settings:
> > - 1920x1080 fullscreen
> > - antialiasing: Off
> > - duration: 60000 ms
> >
> > Renderer:
> > - GeForce RTX 2060/PCIe/SSE2
> > - OpenGL: 4.6.0 NVIDIA 460.32.03
> >
> > This feature is presented by Acer officially and should not harm
> > hardware in any case.
> >
> > A challenging part of implementing this feature is that calling
> > overclock function requires knowing the exact count of fans
> > for CPU and GPU of each model, which to the best of my
> > knowledge is not available in the kernel.
> >
> > So after checking the official PredatorSense application methods, it
> > turned out they have provided the software the list of fans in each model.
> > I have access to the mentioned list, and all similar PH-iii-jj can be
> > added easily by matching "DMI_PRODUCT_NAME".
> >
> > Creating a specific file for the Acer gaming features is not possible
> > because the current in use WMI event GUID is required for the turbo button
> > and it's not possible to register multiple listeners on a single WMI event.
> >
> >
> > Signed-off-by: JafarAkhondali <jafar.akhoondali@gmail.com>
>
> Thank you for your patch, I've applied this patch to my review-hans
> branch:
> https://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git/log/?h=review-hans
>
> Note it will show up in my review-hans branch once I've pushed my
> local branch there, which might take a while.
>
> Once I've run some tests on this branch the patches there will be
> added to the platform-drivers-x86/for-next branch and eventually
> will be included in the pdx86 pull-request to Linus for the next
> merge-window.
>
> Regards,
>
> Hans
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53
  2021-08-14 11:40   ` Jafar Akhondali
@ 2021-08-15 13:50     ` Hans de Goede
  0 siblings, 0 replies; 7+ messages in thread
From: Hans de Goede @ 2021-08-15 13:50 UTC (permalink / raw)
  To: Jafar Akhondali; +Cc: jlee, linux-kernel, platform-driver-x86, mgross

Hi,

On 8/14/21 1:40 PM, Jafar Akhondali wrote:
>  Hi Hans,
> Thank you for your efforts on the patch, I've sure learned a lot from
> your comments as this
> was my first contribution to Linux kernel.
> 
> Just an extra question, for the next patch I'm gonna send turbo mode support for
> 14 other Acer Predator laptops. The only required change is that I should add
> "quirk_entry" for GPU and CPU fan count, and match product names to their quirk.
> 
> 12 of these Predator laptops have exactly 1 fan for CPU and 1 fan for GPU,
> but two of them have 2 fans for GPU and 1 for CPU. So my question is should
> I add the quirks per product (which will end up to have 14 quirks,
> same as current patch) like:
> 
> static struct quirk_entry quirk_acer_predator_ph315_53 = {
>       .turbo = 1,
>       .cpu_fans = 1,
>       .gpu_fans = 1,
> };
> 
> or should I specify the quirk per fan count like this one:
> 
> static struct quirk_entry quirk_acer_predator_gpu_fan_one_cpu_fan_one = {
>       .turbo = 1,
>       .cpu_fans = 1,
>       .gpu_fans = 1,
> };
> 
> and then set different matched DMI product names to the above quirk?
> 
> The first approach is more verbose, the second uses less code.
> If possible, I would like to know your thoughts on this.

Please use the second approach of having a single:

static struct quirk_entry quirk_acer_predator_gpu_fan_one_cpu_fan_one = {
      .turbo = 1,
      .cpu_fans = 1,
      .gpu_fans = 1,
};

With the DMI entries with all laptops with this setup pointing to that
one quirk_entry.

Regards,

Hans


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-08-15 13:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-12 12:53 [PATCH v5] platform/x86: acer-wmi: Add Turbo Mode support for Acer PH315-53 JafarAkhondali
2021-08-12 16:43 ` kernel test robot
2021-08-12 17:57 ` kernel test robot
2021-08-12 20:15 ` Hans de Goede
2021-08-13 11:22 ` Hans de Goede
2021-08-14 11:40   ` Jafar Akhondali
2021-08-15 13:50     ` Hans de Goede

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).