Skip to content

Commit eeeb4c9

Browse files
VulnXij-intel
authored andcommitted
platform/x86: hp-wmi: Add EC offsets to read Victus S thermal profile
The current implementation for Victus S thermal profiles only supports setting the profile. The driver was missing the logic to read the hardware state, meaning it would default to "Balanced" on driver load, overriding the currently active profile. Furthermore, the driver could not detect if the firmware reset the profile on a power source change. Statically store the known EC offsets for reading thermal profile in the new .ec_tp_offset field of struct thermal_profile_params. Implement platform_profile_victus_s_get_ec() to use this offset to read the real hardware state. Additionally, update the power source event notifier to use the actual hardware state when re-triggering CPU power limits actualization. Testing on HP Omen 16-wf1xxx (board ID 8C78) confirmed that the thermal profile is now persistent across driver loads and power source change events. Signed-off-by: Krishna Chomal <krishna.chomal108@gmail.com> Link: https://patch.msgid.link/20260121182858.66363-1-krishna.chomal108@gmail.com Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
1 parent 059417e commit eeeb4c9

1 file changed

Lines changed: 96 additions & 7 deletions

File tree

drivers/platform/x86/hp/hp-wmi.c

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,13 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45E9-BE91-3D44E2C707E4");
4646
#define HPWMI_EVENT_GUID "95F24279-4D7B-4334-9387-ACCDC67EF61C"
4747
#define HPWMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4"
4848

49-
#define HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET 0x62
50-
#define HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET 0x63
51-
#define HP_OMEN_EC_THERMAL_PROFILE_OFFSET 0x95
49+
enum hp_ec_offsets {
50+
HP_EC_OFFSET_UNKNOWN = 0x00,
51+
HP_VICTUS_S_EC_THERMAL_PROFILE_OFFSET = 0x59,
52+
HP_OMEN_EC_THERMAL_PROFILE_FLAGS_OFFSET = 0x62,
53+
HP_OMEN_EC_THERMAL_PROFILE_TIMER_OFFSET = 0x63,
54+
HP_OMEN_EC_THERMAL_PROFILE_OFFSET = 0x95,
55+
};
5256

5357
#define HP_FAN_SPEED_AUTOMATIC 0x00
5458
#define HP_POWER_LIMIT_DEFAULT 0x00
@@ -94,22 +98,26 @@ enum hp_thermal_profile {
9498
HP_THERMAL_PROFILE_QUIET = 0x03,
9599
};
96100

101+
97102
struct thermal_profile_params {
98103
u8 performance;
99104
u8 balanced;
100105
u8 low_power;
106+
u8 ec_tp_offset;
101107
};
102108

103109
static const struct thermal_profile_params victus_s_thermal_params = {
104110
.performance = HP_VICTUS_S_THERMAL_PROFILE_PERFORMANCE,
105111
.balanced = HP_VICTUS_S_THERMAL_PROFILE_DEFAULT,
106112
.low_power = HP_VICTUS_S_THERMAL_PROFILE_DEFAULT,
113+
.ec_tp_offset = HP_EC_OFFSET_UNKNOWN,
107114
};
108115

109116
static const struct thermal_profile_params omen_v1_thermal_params = {
110117
.performance = HP_OMEN_V1_THERMAL_PROFILE_PERFORMANCE,
111118
.balanced = HP_OMEN_V1_THERMAL_PROFILE_DEFAULT,
112119
.low_power = HP_OMEN_V1_THERMAL_PROFILE_DEFAULT,
120+
.ec_tp_offset = HP_VICTUS_S_EC_THERMAL_PROFILE_OFFSET,
113121
};
114122

115123
/*
@@ -1785,6 +1793,60 @@ static int victus_s_set_cpu_pl1_pl2(u8 pl1, u8 pl2)
17851793
return ret;
17861794
}
17871795

1796+
static int platform_profile_victus_s_get_ec(enum platform_profile_option *profile)
1797+
{
1798+
int ret = 0;
1799+
bool current_ctgp_state, current_ppab_state;
1800+
u8 current_dstate, current_gpu_slowdown_temp, tp;
1801+
const struct thermal_profile_params *params;
1802+
1803+
params = active_thermal_profile_params;
1804+
if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
1805+
*profile = active_platform_profile;
1806+
return 0;
1807+
}
1808+
1809+
ret = ec_read(params->ec_tp_offset, &tp);
1810+
if (ret)
1811+
return ret;
1812+
1813+
/*
1814+
* We cannot use active_thermal_profile_params here, because boards
1815+
* like 8C78 have tp == 0x0 || tp == 0x1 after cold boot, but logically
1816+
* it should have tp == 0x30 || tp == 0x31, as corrected by the Omen
1817+
* Gaming Hub on windows. Hence accept both of these values.
1818+
*/
1819+
if (tp == victus_s_thermal_params.performance ||
1820+
tp == omen_v1_thermal_params.performance) {
1821+
*profile = PLATFORM_PROFILE_PERFORMANCE;
1822+
} else if (tp == victus_s_thermal_params.balanced ||
1823+
tp == omen_v1_thermal_params.balanced) {
1824+
/*
1825+
* Since both PLATFORM_PROFILE_LOW_POWER and
1826+
* PLATFORM_PROFILE_BALANCED share the same thermal profile
1827+
* parameter value, hence to differentiate between them, we
1828+
* query the GPU CTGP and PPAB states and compare based off of
1829+
* that.
1830+
*/
1831+
ret = victus_s_gpu_thermal_profile_get(&current_ctgp_state,
1832+
&current_ppab_state,
1833+
&current_dstate,
1834+
&current_gpu_slowdown_temp);
1835+
if (ret < 0)
1836+
return ret;
1837+
if (current_ctgp_state == 0 && current_ppab_state == 0)
1838+
*profile = PLATFORM_PROFILE_LOW_POWER;
1839+
else if (current_ctgp_state == 0 && current_ppab_state == 1)
1840+
*profile = PLATFORM_PROFILE_BALANCED;
1841+
else
1842+
return -EINVAL;
1843+
} else {
1844+
return -EINVAL;
1845+
}
1846+
1847+
return 0;
1848+
}
1849+
17881850
static int platform_profile_victus_s_set_ec(enum platform_profile_option profile)
17891851
{
17901852
struct thermal_profile_params *params;
@@ -1952,13 +2014,25 @@ static int victus_s_powersource_event(struct notifier_block *nb,
19522014
void *data)
19532015
{
19542016
struct acpi_bus_event *event_entry = data;
2017+
enum platform_profile_option actual_profile;
19552018
int err;
19562019

19572020
if (strcmp(event_entry->device_class, ACPI_AC_CLASS) != 0)
19582021
return NOTIFY_DONE;
19592022

19602023
pr_debug("Received power source device event\n");
19612024

2025+
guard(mutex)(&active_platform_profile_lock);
2026+
err = platform_profile_victus_s_get_ec(&actual_profile);
2027+
if (err < 0) {
2028+
/*
2029+
* Although we failed to get the current platform profile, we
2030+
* still want the other event consumers to process it.
2031+
*/
2032+
pr_warn("Failed to read current platform profile (%d)\n", err);
2033+
return NOTIFY_DONE;
2034+
}
2035+
19622036
/*
19632037
* Switching to battery power source while Performance mode is active
19642038
* needs manual triggering of CPU power limits. Same goes when switching
@@ -1967,7 +2041,7 @@ static int victus_s_powersource_event(struct notifier_block *nb,
19672041
* Seen on HP 16-s1034nf (board 8C9C) with F.11 and F.13 BIOS versions.
19682042
*/
19692043

1970-
if (active_platform_profile == PLATFORM_PROFILE_PERFORMANCE) {
2044+
if (actual_profile == PLATFORM_PROFILE_PERFORMANCE) {
19712045
pr_debug("Triggering CPU PL1/PL2 actualization\n");
19722046
err = victus_s_set_cpu_pl1_pl2(HP_POWER_LIMIT_DEFAULT,
19732047
HP_POWER_LIMIT_DEFAULT);
@@ -2078,11 +2152,22 @@ static int thermal_profile_setup(struct platform_device *device)
20782152
ops = &platform_profile_victus_ops;
20792153
} else if (is_victus_s_thermal_profile()) {
20802154
/*
2081-
* Being unable to retrieve laptop's current thermal profile,
2082-
* during this setup, we set it to Balanced by default.
2155+
* For an unknown EC layout board, platform_profile_victus_s_get_ec(),
2156+
* behaves like a wrapper around active_platform_profile, to avoid using
2157+
* uninitialized data, we default to PLATFORM_PROFILE_BALANCED.
20832158
*/
2084-
active_platform_profile = PLATFORM_PROFILE_BALANCED;
2159+
if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
2160+
active_platform_profile = PLATFORM_PROFILE_BALANCED;
2161+
} else {
2162+
err = platform_profile_victus_s_get_ec(&active_platform_profile);
2163+
if (err < 0)
2164+
return err;
2165+
}
20852166

2167+
/*
2168+
* call thermal profile write command to ensure that the
2169+
* firmware correctly sets the OEM variables
2170+
*/
20862171
err = platform_profile_victus_s_set_ec(active_platform_profile);
20872172
if (err < 0)
20882173
return err;
@@ -2505,6 +2590,10 @@ static void __init setup_active_thermal_profile_params(void)
25052590
*/
25062591
is_victus_s_board = true;
25072592
active_thermal_profile_params = id->driver_data;
2593+
if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
2594+
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",
2595+
dmi_get_system_info(DMI_BOARD_NAME));
2596+
}
25082597
}
25092598
}
25102599

0 commit comments

Comments
 (0)