summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/x86/hp/hp-wmi.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c
index b5955b6eb50b..630519c08617 100644
--- a/drivers/platform/x86/hp/hp-wmi.c
+++ b/drivers/platform/x86/hp/hp-wmi.c
@@ -38,6 +38,8 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45E9-BE91-3D44E2C707E4");
#define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
#define HPWMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4"
+#define HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET 0x62
+#define HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET 0x63
#define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95
#define zero_if_sup(tmp) (zero_insize_support?0:sizeof(tmp)) // use when zero insize is required
@@ -57,7 +59,7 @@ static const char * const omen_thermal_profile_boards[] = {
"874A", "8603", "8604", "8748", "886B", "886C", "878A", "878B", "878C",
"88C8", "88CB", "8786", "8787", "8788", "88D1", "88D2", "88F4", "88FD",
"88F5", "88F6", "88F7", "88FE", "88FF", "8900", "8901", "8902", "8912",
- "8917", "8918", "8949", "894A", "89EB"
+ "8917", "8918", "8949", "894A", "89EB", "8BAD", "8A42"
};
/* DMI Board names of Omen laptops that are specifically set to be thermal
@@ -68,6 +70,14 @@ static const char * const omen_thermal_profile_force_v0_boards[] = {
"8607", "8746", "8747", "8749", "874A", "8748"
};
+/* DMI board names of Omen laptops that have a thermal profile timer which will
+ * cause the embedded controller to set the thermal profile back to
+ * "balanced" when reaching zero.
+ */
+static const char * const omen_timed_thermal_profile_boards[] = {
+ "8BAD", "8A42"
+};
+
/* DMI Board names of Victus laptops */
static const char * const victus_thermal_profile_boards[] = {
"8A25"
@@ -184,6 +194,12 @@ enum hp_thermal_profile_omen_v1 {
HP_OMEN_V1_THERMAL_PROFILE_COOL = 0x50,
};
+enum hp_thermal_profile_omen_flags {
+ HP_OMEN_EC_FLAGS_TURBO = 0x04,
+ HP_OMEN_EC_FLAGS_NOTIMER = 0x02,
+ HP_OMEN_EC_FLAGS_JUSTSET = 0x01,
+};
+
enum hp_thermal_profile_victus {
HP_VICTUS_THERMAL_PROFILE_DEFAULT = 0x00,
HP_VICTUS_THERMAL_PROFILE_PERFORMANCE = 0x01,
@@ -451,7 +467,11 @@ static int hp_wmi_get_tablet_mode(void)
static int omen_thermal_profile_set(int mode)
{
- char buffer[2] = {0, mode};
+ /* The Omen Control Center actively sets the first byte of the buffer to
+ * 255, so let's mimic this behaviour to be as close as possible to
+ * the original software.
+ */
+ char buffer[2] = {-1, mode};
int ret;
ret = hp_wmi_perform_query(HPWMI_SET_PERFORMANCE_MODE, HPWMI_GM,
@@ -1203,10 +1223,33 @@ static int platform_profile_omen_get(struct platform_profile_handler *pprof,
return 0;
}
+static bool has_omen_thermal_profile_ec_timer(void)
+{
+ const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
+
+ if (!board_name)
+ return false;
+
+ return match_string(omen_timed_thermal_profile_boards,
+ ARRAY_SIZE(omen_timed_thermal_profile_boards),
+ board_name) >= 0;
+}
+
+inline int omen_thermal_profile_ec_flags_set(enum hp_thermal_profile_omen_flags flags)
+{
+ return ec_write(HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET, flags);
+}
+
+inline int omen_thermal_profile_ec_timer_set(u8 value)
+{
+ return ec_write(HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET, value);
+}
+
static int platform_profile_omen_set(struct platform_profile_handler *pprof,
enum platform_profile_option profile)
{
int err, tp, tp_version;
+ enum hp_thermal_profile_omen_flags flags = 0;
tp_version = omen_get_thermal_policy_version();
@@ -1240,6 +1283,20 @@ static int platform_profile_omen_set(struct platform_profile_handler *pprof,
if (err < 0)
return err;
+ if (has_omen_thermal_profile_ec_timer()) {
+ err = omen_thermal_profile_ec_timer_set(0);
+ if (err < 0)
+ return err;
+
+ if (profile == PLATFORM_PROFILE_PERFORMANCE)
+ flags = HP_OMEN_EC_FLAGS_NOTIMER |
+ HP_OMEN_EC_FLAGS_TURBO;
+
+ err = omen_thermal_profile_ec_flags_set(flags);
+ if (err < 0)
+ return err;
+ }
+
return 0;
}