From 023a25b071a2d28f8eb8ba46da14f275c92d38d1 Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Mon, 12 Aug 2024 18:48:39 +0530 Subject: platform/x86/amd/pmf: Add support for notifying Smart PC Solution updates The APMF function 14 (Notify Smart PC Solution Updates) allows the BIOS (AMD/OEM) to be informed about the outputs of custom Smart PC policies. Enhance the PMF driver to invoke APMF function 14 when these custom policy outputs are triggered. Co-developed-by: Patil Rajesh Reddy Signed-off-by: Patil Rajesh Reddy Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20240812131839.308768-1-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/acpi.c | 31 +++++++++++++++++++++++++++ drivers/platform/x86/amd/pmf/pmf.h | 18 ++++++++++++++++ drivers/platform/x86/amd/pmf/tee-if.c | 40 +++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c index 1157ec148880..d5b496433d69 100644 --- a/drivers/platform/x86/amd/pmf/acpi.c +++ b/drivers/platform/x86/amd/pmf/acpi.c @@ -282,6 +282,29 @@ int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx) return 0; } +static int apmf_notify_smart_pc_update(struct amd_pmf_dev *pdev, u32 val, u32 preq, u32 index) +{ + struct amd_pmf_notify_smart_pc_update args; + struct acpi_buffer params; + union acpi_object *info; + + args.size = sizeof(args); + args.pending_req = preq; + args.custom_bios[index] = val; + + params.length = sizeof(args); + params.pointer = &args; + + info = apmf_if_call(pdev, APMF_FUNC_NOTIFY_SMART_PC_UPDATES, ¶ms); + if (!info) + return -EIO; + + kfree(info); + dev_dbg(pdev->dev, "Notify smart pc update, val: %u\n", val); + + return 0; +} + int apmf_get_auto_mode_def(struct amd_pmf_dev *pdev, struct apmf_auto_mode *data) { return apmf_if_call_store_buffer(pdev, APMF_FUNC_AUTO_MODE, data, sizeof(*data)); @@ -447,6 +470,14 @@ int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev) return 0; } +int amd_pmf_smartpc_apply_bios_output(struct amd_pmf_dev *dev, u32 val, u32 preq, u32 idx) +{ + if (!is_apmf_func_supported(dev, APMF_FUNC_NOTIFY_SMART_PC_UPDATES)) + return -EINVAL; + + return apmf_notify_smart_pc_update(dev, val, preq, idx); +} + void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev) { acpi_handle ahandle = ACPI_HANDLE(pmf_dev->dev); diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index 753d5662c080..9bf4326d06c3 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -35,6 +35,7 @@ struct cookie_header { #define APMF_FUNC_STATIC_SLIDER_GRANULAR 9 #define APMF_FUNC_DYN_SLIDER_AC 11 #define APMF_FUNC_DYN_SLIDER_DC 12 +#define APMF_FUNC_NOTIFY_SMART_PC_UPDATES 14 #define APMF_FUNC_SBIOS_HEARTBEAT_V2 16 /* Message Definitions */ @@ -82,7 +83,17 @@ struct cookie_header { #define PMF_POLICY_STT_SKINTEMP_APU 7 #define PMF_POLICY_STT_SKINTEMP_HS2 8 #define PMF_POLICY_SYSTEM_STATE 9 +#define PMF_POLICY_BIOS_OUTPUT_1 10 +#define PMF_POLICY_BIOS_OUTPUT_2 11 #define PMF_POLICY_P3T 38 +#define PMF_POLICY_BIOS_OUTPUT_3 57 +#define PMF_POLICY_BIOS_OUTPUT_4 58 +#define PMF_POLICY_BIOS_OUTPUT_5 59 +#define PMF_POLICY_BIOS_OUTPUT_6 60 +#define PMF_POLICY_BIOS_OUTPUT_7 61 +#define PMF_POLICY_BIOS_OUTPUT_8 62 +#define PMF_POLICY_BIOS_OUTPUT_9 63 +#define PMF_POLICY_BIOS_OUTPUT_10 64 /* TA macros */ #define PMF_TA_IF_VERSION_MAJOR 1 @@ -344,6 +355,12 @@ struct os_power_slider { u8 slider_event; } __packed; +struct amd_pmf_notify_smart_pc_update { + u16 size; + u32 pending_req; + u32 custom_bios[10]; +} __packed; + struct fan_table_control { bool manual; unsigned long fan_id; @@ -717,6 +734,7 @@ extern const struct attribute_group cnqf_feature_attribute_group; int amd_pmf_init_smart_pc(struct amd_pmf_dev *dev); void amd_pmf_deinit_smart_pc(struct amd_pmf_dev *dev); int apmf_check_smart_pc(struct amd_pmf_dev *pmf_dev); +int amd_pmf_smartpc_apply_bios_output(struct amd_pmf_dev *dev, u32 val, u32 preq, u32 idx); /* Smart PC - TA interfaces */ void amd_pmf_populate_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in); diff --git a/drivers/platform/x86/amd/pmf/tee-if.c b/drivers/platform/x86/amd/pmf/tee-if.c index e246367aacee..19c27b6e4666 100644 --- a/drivers/platform/x86/amd/pmf/tee-if.c +++ b/drivers/platform/x86/amd/pmf/tee-if.c @@ -160,6 +160,46 @@ static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct ta_pmf_enact_ dev_dbg(dev->dev, "update SYSTEM_STATE: %s\n", amd_pmf_uevent_as_str(val)); break; + + case PMF_POLICY_BIOS_OUTPUT_1: + amd_pmf_smartpc_apply_bios_output(dev, val, BIT(0), 0); + break; + + case PMF_POLICY_BIOS_OUTPUT_2: + amd_pmf_smartpc_apply_bios_output(dev, val, BIT(1), 1); + break; + + case PMF_POLICY_BIOS_OUTPUT_3: + amd_pmf_smartpc_apply_bios_output(dev, val, BIT(2), 2); + break; + + case PMF_POLICY_BIOS_OUTPUT_4: + amd_pmf_smartpc_apply_bios_output(dev, val, BIT(3), 3); + break; + + case PMF_POLICY_BIOS_OUTPUT_5: + amd_pmf_smartpc_apply_bios_output(dev, val, BIT(4), 4); + break; + + case PMF_POLICY_BIOS_OUTPUT_6: + amd_pmf_smartpc_apply_bios_output(dev, val, BIT(5), 5); + break; + + case PMF_POLICY_BIOS_OUTPUT_7: + amd_pmf_smartpc_apply_bios_output(dev, val, BIT(6), 6); + break; + + case PMF_POLICY_BIOS_OUTPUT_8: + amd_pmf_smartpc_apply_bios_output(dev, val, BIT(7), 7); + break; + + case PMF_POLICY_BIOS_OUTPUT_9: + amd_pmf_smartpc_apply_bios_output(dev, val, BIT(8), 8); + break; + + case PMF_POLICY_BIOS_OUTPUT_10: + amd_pmf_smartpc_apply_bios_output(dev, val, BIT(9), 9); + break; } } } -- cgit v1.2.3 From 37578054173919d898d2fe0b76d2f5d713937403 Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Mon, 19 Aug 2024 12:04:03 +0530 Subject: platform/x86/amd/pmf: Relocate CPU ID macros to the PMF header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CPU ID macros are needed by the Smart PC builder. Therefore, transfer the CPU ID macros from core.c to the common PMF header file. Reviewed-by: Ilpo Järvinen Co-developed-by: Patil Rajesh Reddy Signed-off-by: Patil Rajesh Reddy Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20240819063404.378061-1-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/core.c | 6 ------ drivers/platform/x86/amd/pmf/pmf.h | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index 8f1f719befa3..88314b0277a3 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -37,12 +37,6 @@ #define AMD_PMF_RESULT_CMD_UNKNOWN 0xFE #define AMD_PMF_RESULT_FAILED 0xFF -/* List of supported CPU ids */ -#define AMD_CPU_ID_RMB 0x14b5 -#define AMD_CPU_ID_PS 0x14e8 -#define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507 -#define PCI_DEVICE_ID_AMD_1AH_M60H_ROOT 0x1122 - #define PMF_MSG_DELAY_MIN_US 50 #define RESPONSE_REGISTER_LOOP_MAX 20000 diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index 9bf4326d06c3..9fc26f672f12 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -19,6 +19,12 @@ #define POLICY_SIGN_COOKIE 0x31535024 #define POLICY_COOKIE_OFFSET 0x10 +/* List of supported CPU ids */ +#define AMD_CPU_ID_RMB 0x14b5 +#define AMD_CPU_ID_PS 0x14e8 +#define PCI_DEVICE_ID_AMD_1AH_M20H_ROOT 0x1507 +#define PCI_DEVICE_ID_AMD_1AH_M60H_ROOT 0x1122 + struct cookie_header { u32 sign; u32 length; -- cgit v1.2.3 From 8f2407cb3f1e8586622e80269338efb7bed2f05b Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Mon, 19 Aug 2024 12:04:04 +0530 Subject: platform/x86/amd/pmf: Update SMU metrics table for 1AH family series MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SMU metrics table has been revised for the 1AH family series. Introduce a new metrics table structure to retrieve comprehensive metrics information from the PMFW. This information will be utilized by the PMF driver to adjust system thermals. Reviewed-by: Ilpo Järvinen Co-developed-by: Patil Rajesh Reddy Signed-off-by: Patil Rajesh Reddy Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20240819063404.378061-2-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/core.c | 14 +++++++++- drivers/platform/x86/amd/pmf/pmf.h | 49 +++++++++++++++++++++++++++++++++++ drivers/platform/x86/amd/pmf/spc.c | 51 +++++++++++++++++++++++++------------ 3 files changed, 97 insertions(+), 17 deletions(-) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index 88314b0277a3..d6af0ca036f1 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -255,7 +255,19 @@ int amd_pmf_set_dram_addr(struct amd_pmf_dev *dev, bool alloc_buffer) /* Get Metrics Table Address */ if (alloc_buffer) { - dev->buf = kzalloc(sizeof(dev->m_table), GFP_KERNEL); + switch (dev->cpu_id) { + case AMD_CPU_ID_PS: + case AMD_CPU_ID_RMB: + dev->mtable_size = sizeof(dev->m_table); + break; + case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT: + dev->mtable_size = sizeof(dev->m_table_v2); + break; + default: + dev_err(dev->dev, "Invalid CPU id: 0x%x", dev->cpu_id); + } + + dev->buf = kzalloc(dev->mtable_size, GFP_KERNEL); if (!dev->buf) return -ENOMEM; } diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index 9fc26f672f12..8ce8816da9c1 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -198,6 +198,53 @@ struct apmf_fan_idx { u32 fan_ctl_idx; } __packed; +struct smu_pmf_metrics_v2 { + u16 core_frequency[16]; /* MHz */ + u16 core_power[16]; /* mW */ + u16 core_temp[16]; /* centi-C */ + u16 gfx_temp; /* centi-C */ + u16 soc_temp; /* centi-C */ + u16 stapm_opn_limit; /* mW */ + u16 stapm_cur_limit; /* mW */ + u16 infra_cpu_maxfreq; /* MHz */ + u16 infra_gfx_maxfreq; /* MHz */ + u16 skin_temp; /* centi-C */ + u16 gfxclk_freq; /* MHz */ + u16 fclk_freq; /* MHz */ + u16 gfx_activity; /* GFX busy % [0-100] */ + u16 socclk_freq; /* MHz */ + u16 vclk_freq; /* MHz */ + u16 vcn_activity; /* VCN busy % [0-100] */ + u16 vpeclk_freq; /* MHz */ + u16 ipuclk_freq; /* MHz */ + u16 ipu_busy[8]; /* NPU busy % [0-100] */ + u16 dram_reads; /* MB/sec */ + u16 dram_writes; /* MB/sec */ + u16 core_c0residency[16]; /* C0 residency % [0-100] */ + u16 ipu_power; /* mW */ + u32 apu_power; /* mW */ + u32 gfx_power; /* mW */ + u32 dgpu_power; /* mW */ + u32 socket_power; /* mW */ + u32 all_core_power; /* mW */ + u32 filter_alpha_value; /* time constant [us] */ + u32 metrics_counter; + u16 memclk_freq; /* MHz */ + u16 mpipuclk_freq; /* MHz */ + u16 ipu_reads; /* MB/sec */ + u16 ipu_writes; /* MB/sec */ + u32 throttle_residency_prochot; + u32 throttle_residency_spl; + u32 throttle_residency_fppt; + u32 throttle_residency_sppt; + u32 throttle_residency_thm_core; + u32 throttle_residency_thm_gfx; + u32 throttle_residency_thm_soc; + u16 psys; + u16 spare1; + u32 spare[6]; +} __packed; + struct smu_pmf_metrics { u16 gfxclk_freq; /* in MHz */ u16 socclk_freq; /* in MHz */ @@ -295,6 +342,7 @@ struct amd_pmf_dev { int hb_interval; /* SBIOS heartbeat interval */ struct delayed_work heart_beat; struct smu_pmf_metrics m_table; + struct smu_pmf_metrics_v2 m_table_v2; struct delayed_work work_buffer; ktime_t start_time; int socket_power_history[AVG_SAMPLE_SIZE]; @@ -319,6 +367,7 @@ struct amd_pmf_dev { bool smart_pc_enabled; u16 pmf_if_version; struct input_dev *pmf_idev; + size_t mtable_size; }; struct apmf_sps_prop_granular_v2 { diff --git a/drivers/platform/x86/amd/pmf/spc.c b/drivers/platform/x86/amd/pmf/spc.c index 3c153fb1425e..b5183969f9bf 100644 --- a/drivers/platform/x86/amd/pmf/spc.c +++ b/drivers/platform/x86/amd/pmf/spc.c @@ -53,30 +53,49 @@ void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table * void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in) {} #endif -static void amd_pmf_get_smu_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in) +static void amd_pmf_get_c0_residency(u16 *core_res, size_t size, struct ta_pmf_enact_table *in) { u16 max, avg = 0; int i; - memset(dev->buf, 0, sizeof(dev->m_table)); - amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, 0, 7, NULL); - memcpy(&dev->m_table, dev->buf, sizeof(dev->m_table)); - - in->ev_info.socket_power = dev->m_table.apu_power + dev->m_table.dgpu_power; - in->ev_info.skin_temperature = dev->m_table.skin_temp; - /* Get the avg and max C0 residency of all the cores */ - max = dev->m_table.avg_core_c0residency[0]; - for (i = 0; i < ARRAY_SIZE(dev->m_table.avg_core_c0residency); i++) { - avg += dev->m_table.avg_core_c0residency[i]; - if (dev->m_table.avg_core_c0residency[i] > max) - max = dev->m_table.avg_core_c0residency[i]; + max = *core_res; + for (i = 0; i < size; i++) { + avg += core_res[i]; + if (core_res[i] > max) + max = core_res[i]; } - - avg = DIV_ROUND_CLOSEST(avg, ARRAY_SIZE(dev->m_table.avg_core_c0residency)); + avg = DIV_ROUND_CLOSEST(avg, size); in->ev_info.avg_c0residency = avg; in->ev_info.max_c0residency = max; - in->ev_info.gfx_busy = dev->m_table.avg_gfx_activity; +} + +static void amd_pmf_get_smu_info(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in) +{ + /* Get the updated metrics table data */ + memset(dev->buf, 0, dev->mtable_size); + amd_pmf_send_cmd(dev, SET_TRANSFER_TABLE, 0, 7, NULL); + + switch (dev->cpu_id) { + case AMD_CPU_ID_PS: + memcpy(&dev->m_table, dev->buf, dev->mtable_size); + in->ev_info.socket_power = dev->m_table.apu_power + dev->m_table.dgpu_power; + in->ev_info.skin_temperature = dev->m_table.skin_temp; + in->ev_info.gfx_busy = dev->m_table.avg_gfx_activity; + amd_pmf_get_c0_residency(dev->m_table.avg_core_c0residency, + ARRAY_SIZE(dev->m_table.avg_core_c0residency), in); + break; + case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT: + memcpy(&dev->m_table_v2, dev->buf, dev->mtable_size); + in->ev_info.socket_power = dev->m_table_v2.apu_power + dev->m_table_v2.dgpu_power; + in->ev_info.skin_temperature = dev->m_table_v2.skin_temp; + in->ev_info.gfx_busy = dev->m_table_v2.gfx_activity; + amd_pmf_get_c0_residency(dev->m_table_v2.core_c0residency, + ARRAY_SIZE(dev->m_table_v2.core_c0residency), in); + break; + default: + dev_err(dev->dev, "Unsupported CPU id: 0x%x", dev->cpu_id); + } } static const char * const pmf_battery_supply_name[] = { -- cgit v1.2.3 From 06369503d644068abd9e90918c6611274d94c126 Mon Sep 17 00:00:00 2001 From: aln8 Date: Thu, 12 Sep 2024 15:36:01 +0800 Subject: platform/x86/amd: pmf: Add quirk for TUF Gaming A14 The ASUS TUF Gaming A14 has the same issue as the ROG Zephyrus G14 where it advertises SPS support but doesn't use it. Signed-off-by: aln8 Acked-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20240912073601.65656-1-aln8un@gmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/pmf-quirks.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers/platform/x86/amd') diff --git a/drivers/platform/x86/amd/pmf/pmf-quirks.c b/drivers/platform/x86/amd/pmf/pmf-quirks.c index 460444cda1b2..6ee219a81537 100644 --- a/drivers/platform/x86/amd/pmf/pmf-quirks.c +++ b/drivers/platform/x86/amd/pmf/pmf-quirks.c @@ -37,6 +37,14 @@ static const struct dmi_system_id fwbug_list[] = { }, .driver_data = &quirk_no_sps_bug, }, + { + .ident = "ASUS TUF Gaming A14", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "FA401W"), + }, + .driver_data = &quirk_no_sps_bug, + }, {} }; -- cgit v1.2.3