platform/x86: amd: pmf: Fix STT limits

JIRA: https://issues.redhat.com/browse/RHEL-105420

commit fcf27a6a926fd9eeba39e9c3fde43c9298fe284e
Author: Mario Limonciello <mario.limonciello@amd.com>
Date:   Mon Apr 7 13:18:21 2025 -0500

    platform/x86: amd: pmf: Fix STT limits

    On some platforms it has been observed that STT limits are not being
    applied properly causing poor performance as power limits are set too low.

    STT limits that are sent to the platform are supposed to be in Q8.8
    format.  Convert them before sending.

    Reported-by: Yijun Shen <Yijun.Shen@dell.com>
    Fixes: 7c45534afa443 ("platform/x86/amd/pmf: Add support for PMF Policy Binary")
    Cc: stable@vger.kernel.org
    Tested-by: Yijun Shen <Yijun_Shen@Dell.com>
    Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
    Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
    Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
    Link: https://lore.kernel.org/r/20250407181915.1482450-1-superm1@kernel.org
    Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

Signed-off-by: David Arcari <darcari@redhat.com>
This commit is contained in:
David Arcari 2025-09-18 15:18:02 -04:00
parent f5e52a6076
commit 93d900a094
6 changed files with 33 additions and 12 deletions

View File

@ -120,9 +120,9 @@ static void amd_pmf_set_automode(struct amd_pmf_dev *dev, int idx,
amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, pwr_ctrl->sppt_apu_only, NULL);
amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, pwr_ctrl->stt_min, NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
pwr_ctrl->stt_skin_temp[STT_TEMP_APU], NULL);
fixp_q88_fromint(pwr_ctrl->stt_skin_temp[STT_TEMP_APU]), NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
pwr_ctrl->stt_skin_temp[STT_TEMP_HS2], NULL);
fixp_q88_fromint(pwr_ctrl->stt_skin_temp[STT_TEMP_HS2]), NULL);
if (is_apmf_func_supported(dev, APMF_FUNC_SET_FAN_IDX))
apmf_update_fan_idx(dev, config_store.mode_set[idx].fan_control.manual,

View File

@ -81,10 +81,10 @@ static int amd_pmf_set_cnqf(struct amd_pmf_dev *dev, int src, int idx,
amd_pmf_send_cmd(dev, SET_SPPT, false, pc->sppt, NULL);
amd_pmf_send_cmd(dev, SET_SPPT_APU_ONLY, false, pc->sppt_apu_only, NULL);
amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false, pc->stt_min, NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false, pc->stt_skin_temp[STT_TEMP_APU],
NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false, pc->stt_skin_temp[STT_TEMP_HS2],
NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
fixp_q88_fromint(pc->stt_skin_temp[STT_TEMP_APU]), NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
fixp_q88_fromint(pc->stt_skin_temp[STT_TEMP_HS2]), NULL);
if (is_apmf_func_supported(dev, APMF_FUNC_SET_FAN_IDX))
apmf_update_fan_idx(dev,

View File

@ -176,6 +176,20 @@ static void __maybe_unused amd_pmf_dump_registers(struct amd_pmf_dev *dev)
dev_dbg(dev->dev, "AMD_PMF_REGISTER_MESSAGE:%x\n", value);
}
/**
* fixp_q88_fromint: Convert integer to Q8.8
* @val: input value
*
* Converts an integer into binary fixed point format where 8 bits
* are used for integer and 8 bits are used for the decimal.
*
* Return: unsigned integer converted to Q8.8 format
*/
u32 fixp_q88_fromint(u32 val)
{
return val << 8;
}
int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 *data)
{
int rc;

View File

@ -777,6 +777,7 @@ int apmf_install_handler(struct amd_pmf_dev *pmf_dev);
int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag);
int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer);
int amd_pmf_notify_sbios_heartbeat_event_v2(struct amd_pmf_dev *dev, u8 flag);
u32 fixp_q88_fromint(u32 val);
/* SPS Layer */
int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf);

View File

@ -198,9 +198,11 @@ static void amd_pmf_update_slider_v2(struct amd_pmf_dev *dev, int idx)
amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false,
apts_config_store.val[idx].stt_min_limit, NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
apts_config_store.val[idx].stt_skin_temp_limit_apu, NULL);
fixp_q88_fromint(apts_config_store.val[idx].stt_skin_temp_limit_apu),
NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
apts_config_store.val[idx].stt_skin_temp_limit_hs2, NULL);
fixp_q88_fromint(apts_config_store.val[idx].stt_skin_temp_limit_hs2),
NULL);
}
void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx,
@ -217,9 +219,11 @@ void amd_pmf_update_slider(struct amd_pmf_dev *dev, bool op, int idx,
amd_pmf_send_cmd(dev, SET_STT_MIN_LIMIT, false,
config_store.prop[src][idx].stt_min, NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
config_store.prop[src][idx].stt_skin_temp[STT_TEMP_APU], NULL);
fixp_q88_fromint(config_store.prop[src][idx].stt_skin_temp[STT_TEMP_APU]),
NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
config_store.prop[src][idx].stt_skin_temp[STT_TEMP_HS2], NULL);
fixp_q88_fromint(config_store.prop[src][idx].stt_skin_temp[STT_TEMP_HS2]),
NULL);
} else if (op == SLIDER_OP_GET) {
amd_pmf_send_cmd(dev, GET_SPL, true, ARG_NONE, &table->prop[src][idx].spl);
amd_pmf_send_cmd(dev, GET_FPPT, true, ARG_NONE, &table->prop[src][idx].fppt);

View File

@ -123,7 +123,8 @@ static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct ta_pmf_enact_
case PMF_POLICY_STT_SKINTEMP_APU:
if (dev->prev_data->stt_skintemp_apu != val) {
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false, val, NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_APU, false,
fixp_q88_fromint(val), NULL);
dev_dbg(dev->dev, "update STT_SKINTEMP_APU: %u\n", val);
dev->prev_data->stt_skintemp_apu = val;
}
@ -131,7 +132,8 @@ static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct ta_pmf_enact_
case PMF_POLICY_STT_SKINTEMP_HS2:
if (dev->prev_data->stt_skintemp_hs2 != val) {
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false, val, NULL);
amd_pmf_send_cmd(dev, SET_STT_LIMIT_HS2, false,
fixp_q88_fromint(val), NULL);
dev_dbg(dev->dev, "update STT_SKINTEMP_HS2: %u\n", val);
dev->prev_data->stt_skintemp_hs2 = val;
}