Skip to content

Commit

Permalink
platform/x86: thinkpad_acpi: Fix profile mode display in AMT mode
Browse files Browse the repository at this point in the history
Recently AMT mode was enabled (somewhat unexpectedly) on the Lenovo
Z13 platform. The FW is advertising it is available and the driver tries
to use it - unfortunately it reports the profile mode incorrectly.

Note, there is also some extra work needed to enable the dynamic aspect
of AMT support that I will be following up with; but more testing is
needed first. This patch just fixes things so the profiles are reported
correctly.

Link: https://gitlab.freedesktop.org/hadess/power-profiles-daemon/-/issues/115
Fixes: 46dcbc6 ("platform/x86: thinkpad-acpi: Add support for automatic mode transitions")

Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Link: https://lore.kernel.org/r/20230112221228.490946-1-mpearson-lenovo@squebb.ca
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
  • Loading branch information
mrhpearson authored and jwrdegoede committed Jan 13, 2023
1 parent cf5ac2d commit fde5f74
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions drivers/platform/x86/thinkpad_acpi.c
Expand Up @@ -10311,9 +10311,11 @@ static DEFINE_MUTEX(dytc_mutex);
static int dytc_capabilities;
static bool dytc_mmc_get_available;

static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *profile)
static int convert_dytc_to_profile(int funcmode, int dytcmode,
enum platform_profile_option *profile)
{
if (dytc_capabilities & BIT(DYTC_FC_MMC)) {
switch (funcmode) {
case DYTC_FUNCTION_MMC:
switch (dytcmode) {
case DYTC_MODE_MMC_LOWPOWER:
*profile = PLATFORM_PROFILE_LOW_POWER;
Expand All @@ -10329,8 +10331,7 @@ static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *p
return -EINVAL;
}
return 0;
}
if (dytc_capabilities & BIT(DYTC_FC_PSC)) {
case DYTC_FUNCTION_PSC:
switch (dytcmode) {
case DYTC_MODE_PSC_LOWPOWER:
*profile = PLATFORM_PROFILE_LOW_POWER;
Expand All @@ -10344,6 +10345,14 @@ static int convert_dytc_to_profile(int dytcmode, enum platform_profile_option *p
default: /* Unknown mode */
return -EINVAL;
}
return 0;
case DYTC_FUNCTION_AMT:
/* For now return balanced. It's the closest we have to 'auto' */
*profile = PLATFORM_PROFILE_BALANCED;
return 0;
default:
/* Unknown function */
return -EOPNOTSUPP;
}
return 0;
}
Expand Down Expand Up @@ -10492,6 +10501,7 @@ static int dytc_profile_set(struct platform_profile_handler *pprof,
err = dytc_command(DYTC_SET_COMMAND(DYTC_FUNCTION_PSC, perfmode, 1), &output);
if (err)
goto unlock;

/* system supports AMT, activate it when on balanced */
if (dytc_capabilities & BIT(DYTC_FC_AMT))
dytc_control_amt(profile == PLATFORM_PROFILE_BALANCED);
Expand All @@ -10507,7 +10517,7 @@ static void dytc_profile_refresh(void)
{
enum platform_profile_option profile;
int output, err = 0;
int perfmode;
int perfmode, funcmode;

mutex_lock(&dytc_mutex);
if (dytc_capabilities & BIT(DYTC_FC_MMC)) {
Expand All @@ -10522,8 +10532,9 @@ static void dytc_profile_refresh(void)
if (err)
return;

funcmode = (output >> DYTC_GET_FUNCTION_BIT) & 0xF;
perfmode = (output >> DYTC_GET_MODE_BIT) & 0xF;
convert_dytc_to_profile(perfmode, &profile);
convert_dytc_to_profile(funcmode, perfmode, &profile);
if (profile != dytc_current_profile) {
dytc_current_profile = profile;
platform_profile_notify();
Expand Down

0 comments on commit fde5f74

Please sign in to comment.