#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
+enum hp_ec_offsets {
+ HP_EC_OFFSET_UNKNOWN = 0x00,
+ HP_VICTUS_S_EC_THERMAL_PROFILE_OFFSET = 0x59,
+ HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET = 0x62,
+ HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET = 0x63,
+ HP_OMEN_EC_THERMAL_PROFILE_OFFSET = 0x95,
+};
#define HP_FAN_SPEED_AUTOMATIC 0x00
#define HP_POWER_LIMIT_DEFAULT 0x00
HP_THERMAL_PROFILE_QUIET = 0x03,
};
+
struct thermal_profile_params {
u8 performance;
u8 balanced;
u8 low_power;
+ u8 ec_tp_offset;
};
static const struct thermal_profile_params victus_s_thermal_params = {
.performance = HP_VICTUS_S_THERMAL_PROFILE_PERFORMANCE,
.balanced = HP_VICTUS_S_THERMAL_PROFILE_DEFAULT,
.low_power = HP_VICTUS_S_THERMAL_PROFILE_DEFAULT,
+ .ec_tp_offset = HP_EC_OFFSET_UNKNOWN,
};
static const struct thermal_profile_params omen_v1_thermal_params = {
.performance = HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE,
.balanced = HP_OMEN_V1_THERMAL_PROFILE_DEFAULT,
.low_power = HP_OMEN_V1_THERMAL_PROFILE_DEFAULT,
+ .ec_tp_offset = HP_VICTUS_S_EC_THERMAL_PROFILE_OFFSET,
};
/*
return ret;
}
+static int platform_profile_victus_s_get_ec(enum platform_profile_option *profile)
+{
+ int ret = 0;
+ bool current_ctgp_state, current_ppab_state;
+ u8 current_dstate, current_gpu_slowdown_temp, tp;
+ const struct thermal_profile_params *params;
+
+ params = active_thermal_profile_params;
+ if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
+ *profile = active_platform_profile;
+ return 0;
+ }
+
+ ret = ec_read(params->ec_tp_offset, &tp);
+ if (ret)
+ return ret;
+
+ /*
+ * We cannot use active_thermal_profile_params here, because boards
+ * like 8C78 have tp == 0x0 || tp == 0x1 after cold boot, but logically
+ * it should have tp == 0x30 || tp == 0x31, as corrected by the Omen
+ * Gaming Hub on windows. Hence accept both of these values.
+ */
+ if (tp == victus_s_thermal_params.performance ||
+ tp == omen_v1_thermal_params.performance) {
+ *profile = PLATFORM_PROFILE_PERFORMANCE;
+ } else if (tp == victus_s_thermal_params.balanced ||
+ tp == omen_v1_thermal_params.balanced) {
+ /*
+ * Since both PLATFORM_PROFILE_LOW_POWER and
+ * PLATFORM_PROFILE_BALANCED share the same thermal profile
+ * parameter value, hence to differentiate between them, we
+ * query the GPU CTGP and PPAB states and compare based off of
+ * that.
+ */
+ ret = victus_s_gpu_thermal_profile_get(¤t_ctgp_state,
+ ¤t_ppab_state,
+ ¤t_dstate,
+ ¤t_gpu_slowdown_temp);
+ if (ret < 0)
+ return ret;
+ if (current_ctgp_state == 0 && current_ppab_state == 0)
+ *profile = PLATFORM_PROFILE_LOW_POWER;
+ else if (current_ctgp_state == 0 && current_ppab_state == 1)
+ *profile = PLATFORM_PROFILE_BALANCED;
+ else
+ return -EINVAL;
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static int platform_profile_victus_s_set_ec(enum platform_profile_option profile)
{
struct thermal_profile_params *params;
void *data)
{
struct acpi_bus_event *event_entry = data;
+ enum platform_profile_option actual_profile;
int err;
if (strcmp(event_entry->device_class, ACPI_AC_CLASS) != 0)
pr_debug("Received power source device event\n");
+ guard(mutex)(&active_platform_profile_lock);
+ err = platform_profile_victus_s_get_ec(&actual_profile);
+ if (err < 0) {
+ /*
+ * Although we failed to get the current platform profile, we
+ * still want the other event consumers to process it.
+ */
+ pr_warn("Failed to read current platform profile (%d)\n", err);
+ return NOTIFY_DONE;
+ }
+
/*
* Switching to battery power source while Performance mode is active
* needs manual triggering of CPU power limits. Same goes when switching
* Seen on HP 16-s1034nf (board 8C9C) with F.11 and F.13 BIOS versions.
*/
- if (active_platform_profile == PLATFORM_PROFILE_PERFORMANCE) {
+ if (actual_profile == PLATFORM_PROFILE_PERFORMANCE) {
pr_debug("Triggering CPU PL1/PL2 actualization\n");
err = victus_s_set_cpu_pl1_pl2(HP_POWER_LIMIT_DEFAULT,
HP_POWER_LIMIT_DEFAULT);
ops = &platform_profile_victus_ops;
} else if (is_victus_s_thermal_profile()) {
/*
- * Being unable to retrieve laptop's current thermal profile,
- * during this setup, we set it to Balanced by default.
+ * For an unknown EC layout board, platform_profile_victus_s_get_ec(),
+ * behaves like a wrapper around active_platform_profile, to avoid using
+ * uninitialized data, we default to PLATFORM_PROFILE_BALANCED.
*/
- active_platform_profile = PLATFORM_PROFILE_BALANCED;
+ if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
+ active_platform_profile = PLATFORM_PROFILE_BALANCED;
+ } else {
+ err = platform_profile_victus_s_get_ec(&active_platform_profile);
+ if (err < 0)
+ return err;
+ }
+ /*
+ * call thermal profile write command to ensure that the
+ * firmware correctly sets the OEM variables
+ */
err = platform_profile_victus_s_set_ec(active_platform_profile);
if (err < 0)
return err;
*/
is_victus_s_board = true;
active_thermal_profile_params = id->driver_data;
+ if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
+ pr_warn("Unknown EC layout for board %s. Thermal profile readback will be disabled. Please report this to platform-driver-x86@vger.kernel.org\n",
+ dmi_get_system_info(DMI_BOARD_NAME));
+ }
}
}