From a82ebb3d800d7baf72122e82ab7c9b240d0a8a56 Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Wed, 10 May 2023 20:17:50 +0530 Subject: platform/x86/amd/pmf: Add PMF acpi debug support PMF driver maintains an internal config store for each PMF feature after the feature init happens. Having a debug mechanism to triage in-field issues w.r.t to mode switch not happening based on the OEM fed values via the ACPI method to PMF driver is becoming the need of the hour. Add support to get more ACPI debug spew guarded by a CONFIG. Co-developed-by: Patil Rajesh Reddy Signed-off-by: Patil Rajesh Reddy Signed-off-by: Shyam Sundar S K Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20230510144751.66601-1-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/auto-mode.c | 120 +++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) (limited to 'drivers/platform/x86/amd/pmf/auto-mode.c') diff --git a/drivers/platform/x86/amd/pmf/auto-mode.c b/drivers/platform/x86/amd/pmf/auto-mode.c index 96a8e1832c05..64425201d353 100644 --- a/drivers/platform/x86/amd/pmf/auto-mode.c +++ b/drivers/platform/x86/amd/pmf/auto-mode.c @@ -15,6 +15,100 @@ static struct auto_mode_mode_config config_store; static const char *state_as_str(unsigned int state); +#ifdef CONFIG_AMD_PMF_DEBUG +static void amd_pmf_dump_auto_mode_defaults(struct auto_mode_mode_config *data) +{ + struct auto_mode_mode_settings *its_mode; + + pr_debug("Auto Mode Data - BEGIN\n"); + + /* time constant */ + pr_debug("balanced_to_perf: %u ms\n", + data->transition[AUTO_TRANSITION_TO_PERFORMANCE].time_constant); + pr_debug("perf_to_balanced: %u ms\n", + data->transition[AUTO_TRANSITION_FROM_PERFORMANCE_TO_BALANCE].time_constant); + pr_debug("quiet_to_balanced: %u ms\n", + data->transition[AUTO_TRANSITION_FROM_QUIET_TO_BALANCE].time_constant); + pr_debug("balanced_to_quiet: %u ms\n", + data->transition[AUTO_TRANSITION_TO_QUIET].time_constant); + + /* power floor */ + pr_debug("pfloor_perf: %u mW\n", data->mode_set[AUTO_PERFORMANCE].power_floor); + pr_debug("pfloor_balanced: %u mW\n", data->mode_set[AUTO_BALANCE].power_floor); + pr_debug("pfloor_quiet: %u mW\n", data->mode_set[AUTO_QUIET].power_floor); + + /* Power delta for mode change */ + pr_debug("pd_balanced_to_perf: %u mW\n", + data->transition[AUTO_TRANSITION_TO_PERFORMANCE].power_delta); + pr_debug("pd_perf_to_balanced: %u mW\n", + data->transition[AUTO_TRANSITION_FROM_PERFORMANCE_TO_BALANCE].power_delta); + pr_debug("pd_quiet_to_balanced: %u mW\n", + data->transition[AUTO_TRANSITION_FROM_QUIET_TO_BALANCE].power_delta); + pr_debug("pd_balanced_to_quiet: %u mW\n", + data->transition[AUTO_TRANSITION_TO_QUIET].power_delta); + + /* skin temperature limits */ + its_mode = &data->mode_set[AUTO_PERFORMANCE_ON_LAP]; + pr_debug("stt_apu_perf_on_lap: %u C\n", + its_mode->power_control.stt_skin_temp[STT_TEMP_APU]); + pr_debug("stt_hs2_perf_on_lap: %u C\n", + its_mode->power_control.stt_skin_temp[STT_TEMP_HS2]); + pr_debug("stt_min_limit_perf_on_lap: %u mW\n", its_mode->power_control.stt_min); + + its_mode = &data->mode_set[AUTO_PERFORMANCE]; + pr_debug("stt_apu_perf: %u C\n", its_mode->power_control.stt_skin_temp[STT_TEMP_APU]); + pr_debug("stt_hs2_perf: %u C\n", its_mode->power_control.stt_skin_temp[STT_TEMP_HS2]); + pr_debug("stt_min_limit_perf: %u mW\n", its_mode->power_control.stt_min); + + its_mode = &data->mode_set[AUTO_BALANCE]; + pr_debug("stt_apu_balanced: %u C\n", its_mode->power_control.stt_skin_temp[STT_TEMP_APU]); + pr_debug("stt_hs2_balanced: %u C\n", its_mode->power_control.stt_skin_temp[STT_TEMP_HS2]); + pr_debug("stt_min_limit_balanced: %u mW\n", its_mode->power_control.stt_min); + + its_mode = &data->mode_set[AUTO_QUIET]; + pr_debug("stt_apu_quiet: %u C\n", its_mode->power_control.stt_skin_temp[STT_TEMP_APU]); + pr_debug("stt_hs2_quiet: %u C\n", its_mode->power_control.stt_skin_temp[STT_TEMP_HS2]); + pr_debug("stt_min_limit_quiet: %u mW\n", its_mode->power_control.stt_min); + + /* SPL based power limits */ + its_mode = &data->mode_set[AUTO_PERFORMANCE_ON_LAP]; + pr_debug("fppt_perf_on_lap: %u mW\n", its_mode->power_control.fppt); + pr_debug("sppt_perf_on_lap: %u mW\n", its_mode->power_control.sppt); + pr_debug("spl_perf_on_lap: %u mW\n", its_mode->power_control.spl); + pr_debug("sppt_apu_only_perf_on_lap: %u mW\n", its_mode->power_control.sppt_apu_only); + + its_mode = &data->mode_set[AUTO_PERFORMANCE]; + pr_debug("fppt_perf: %u mW\n", its_mode->power_control.fppt); + pr_debug("sppt_perf: %u mW\n", its_mode->power_control.sppt); + pr_debug("spl_perf: %u mW\n", its_mode->power_control.spl); + pr_debug("sppt_apu_only_perf: %u mW\n", its_mode->power_control.sppt_apu_only); + + its_mode = &data->mode_set[AUTO_BALANCE]; + pr_debug("fppt_balanced: %u mW\n", its_mode->power_control.fppt); + pr_debug("sppt_balanced: %u mW\n", its_mode->power_control.sppt); + pr_debug("spl_balanced: %u mW\n", its_mode->power_control.spl); + pr_debug("sppt_apu_only_balanced: %u mW\n", its_mode->power_control.sppt_apu_only); + + its_mode = &data->mode_set[AUTO_QUIET]; + pr_debug("fppt_quiet: %u mW\n", its_mode->power_control.fppt); + pr_debug("sppt_quiet: %u mW\n", its_mode->power_control.sppt); + pr_debug("spl_quiet: %u mW\n", its_mode->power_control.spl); + pr_debug("sppt_apu_only_quiet: %u mW\n", its_mode->power_control.sppt_apu_only); + + /* Fan ID */ + pr_debug("fan_id_perf: %lu\n", + data->mode_set[AUTO_PERFORMANCE].fan_control.fan_id); + pr_debug("fan_id_balanced: %lu\n", + data->mode_set[AUTO_BALANCE].fan_control.fan_id); + pr_debug("fan_id_quiet: %lu\n", + data->mode_set[AUTO_QUIET].fan_control.fan_id); + + pr_debug("Auto Mode Data - END\n"); +} +#else +static void amd_pmf_dump_auto_mode_defaults(struct auto_mode_mode_config *data) {} +#endif + static void amd_pmf_set_automode(struct amd_pmf_dev *dev, int idx, struct auto_mode_mode_config *table) { @@ -140,6 +234,30 @@ static void amd_pmf_get_power_threshold(void) config_store.transition[AUTO_TRANSITION_FROM_PERFORMANCE_TO_BALANCE].power_threshold = config_store.mode_set[AUTO_PERFORMANCE].power_floor - config_store.transition[AUTO_TRANSITION_FROM_PERFORMANCE_TO_BALANCE].power_delta; + +#ifdef CONFIG_AMD_PMF_DEBUG + pr_debug("[AUTO MODE TO_QUIET] pt: %u mW pf: %u mW pd: %u mW\n", + config_store.transition[AUTO_TRANSITION_TO_QUIET].power_threshold, + config_store.mode_set[AUTO_BALANCE].power_floor, + config_store.transition[AUTO_TRANSITION_TO_QUIET].power_delta); + + pr_debug("[AUTO MODE TO_PERFORMANCE] pt: %u mW pf: %u mW pd: %u mW\n", + config_store.transition[AUTO_TRANSITION_TO_PERFORMANCE].power_threshold, + config_store.mode_set[AUTO_BALANCE].power_floor, + config_store.transition[AUTO_TRANSITION_TO_PERFORMANCE].power_delta); + + pr_debug("[AUTO MODE QUIET_TO_BALANCE] pt: %u mW pf: %u mW pd: %u mW\n", + config_store.transition[AUTO_TRANSITION_FROM_QUIET_TO_BALANCE] + .power_threshold, + config_store.mode_set[AUTO_QUIET].power_floor, + config_store.transition[AUTO_TRANSITION_FROM_QUIET_TO_BALANCE].power_delta); + + pr_debug("[AUTO MODE PERFORMANCE_TO_BALANCE] pt: %u mW pf: %u mW pd: %u mW\n", + config_store.transition[AUTO_TRANSITION_FROM_PERFORMANCE_TO_BALANCE] + .power_threshold, + config_store.mode_set[AUTO_PERFORMANCE].power_floor, + config_store.transition[AUTO_TRANSITION_FROM_PERFORMANCE_TO_BALANCE].power_delta); +#endif } static const char *state_as_str(unsigned int state) @@ -262,6 +380,8 @@ static void amd_pmf_load_defaults_auto_mode(struct amd_pmf_dev *dev) /* set to initial default values */ config_store.current_mode = AUTO_BALANCE; dev->socket_power_history_idx = -1; + + amd_pmf_dump_auto_mode_defaults(&config_store); } int amd_pmf_reset_amt(struct amd_pmf_dev *dev) -- cgit From 63b5dbfdb770254c4fdb58d22b62458308685592 Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Wed, 10 May 2023 20:17:51 +0530 Subject: platform/x86/amd/pmf: Add PMF debug facilities At times, when the mode transitions fail to happen, the current driver does not give enough debug information on why the transition failed or the default preset values did not load. Having an on-demand logs guarded by CONFIG would be helpful in such cases. Co-developed-by: Patil Rajesh Reddy Signed-off-by: Patil Rajesh Reddy Signed-off-by: Shyam Sundar S K Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20230510144751.66601-2-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/auto-mode.c | 23 +++++++++++++++++++++++ drivers/platform/x86/amd/pmf/cnqf.c | 19 +++++++++++++++++++ 2 files changed, 42 insertions(+) (limited to 'drivers/platform/x86/amd/pmf/auto-mode.c') diff --git a/drivers/platform/x86/amd/pmf/auto-mode.c b/drivers/platform/x86/amd/pmf/auto-mode.c index 64425201d353..02ff68be10d0 100644 --- a/drivers/platform/x86/amd/pmf/auto-mode.c +++ b/drivers/platform/x86/amd/pmf/auto-mode.c @@ -179,11 +179,34 @@ void amd_pmf_trans_automode(struct amd_pmf_dev *dev, int socket_power, ktime_t t config_store.transition[i].applied = false; update = true; } + +#ifdef CONFIG_AMD_PMF_DEBUG + dev_dbg(dev->dev, "[AUTO MODE] average_power : %d mW mode: %s\n", avg_power, + state_as_str(config_store.current_mode)); + + dev_dbg(dev->dev, "[AUTO MODE] time: %lld ms timer: %u ms tc: %u ms\n", + time_elapsed_ms, config_store.transition[i].timer, + config_store.transition[i].time_constant); + + dev_dbg(dev->dev, "[AUTO MODE] shiftup: %u pt: %u mW pf: %u mW pd: %u mW\n", + config_store.transition[i].shifting_up, + config_store.transition[i].power_threshold, + config_store.mode_set[i].power_floor, + config_store.transition[i].power_delta); +#endif } dev_dbg(dev->dev, "[AUTO_MODE] avg power: %u mW mode: %s\n", avg_power, state_as_str(config_store.current_mode)); +#ifdef CONFIG_AMD_PMF_DEBUG + dev_dbg(dev->dev, "[AUTO MODE] priority1: %u priority2: %u priority3: %u priority4: %u\n", + config_store.transition[0].applied, + config_store.transition[1].applied, + config_store.transition[2].applied, + config_store.transition[3].applied); +#endif + if (update) { for (j = 0; j < AUTO_TRANSITION_MAX; j++) { /* Apply the mode with highest priority indentified */ diff --git a/drivers/platform/x86/amd/pmf/cnqf.c b/drivers/platform/x86/amd/pmf/cnqf.c index 35af7c18f600..539b186e9027 100644 --- a/drivers/platform/x86/amd/pmf/cnqf.c +++ b/drivers/platform/x86/amd/pmf/cnqf.c @@ -175,6 +175,13 @@ int amd_pmf_trans_cnqf(struct amd_pmf_dev *dev, int socket_power, ktime_t time_l config_store.trans_param[src][i].count++; tp = &config_store.trans_param[src][i]; + +#ifdef CONFIG_AMD_PMF_DEBUG + dev_dbg(dev->dev, "avg_power: %u mW total_power: %u mW count: %u timer: %u ms\n", + avg_power, config_store.trans_param[src][i].total_power, + config_store.trans_param[src][i].count, + config_store.trans_param[src][i].timer); +#endif if (tp->timer >= tp->time_constant && tp->count) { avg_power = tp->total_power / tp->count; @@ -195,6 +202,18 @@ int amd_pmf_trans_cnqf(struct amd_pmf_dev *dev, int socket_power, ktime_t time_l dev_dbg(dev->dev, "[CNQF] Avg power: %u mW socket power: %u mW mode:%s\n", avg_power, socket_power, state_as_str(config_store.current_mode)); +#ifdef CONFIG_AMD_PMF_DEBUG + dev_dbg(dev->dev, "[CNQF] priority1: %u priority2: %u priority3: %u\n", + config_store.trans_param[src][0].priority, + config_store.trans_param[src][1].priority, + config_store.trans_param[src][2].priority); + + dev_dbg(dev->dev, "[CNQF] priority4: %u priority5: %u priority6: %u\n", + config_store.trans_param[src][3].priority, + config_store.trans_param[src][4].priority, + config_store.trans_param[src][5].priority); +#endif + for (j = 0; j < CNQF_TRANSITION_MAX; j++) { /* apply the highest priority */ if (config_store.trans_param[src][j].priority) { -- cgit