summaryrefslogtreecommitdiff
path: root/src/soc/amd/common/block
diff options
context:
space:
mode:
authorFelix Held <felix-coreboot@felixheld.de>2023-03-24 16:30:55 +0100
committerFelix Held <felix-coreboot@felixheld.de>2023-03-29 16:15:10 +0000
commita63f859553a29842fd8d65ae8a6523cd429a5f85 (patch)
treeccf769584dc8e02611be5123f2721f41a21023f3 /src/soc/amd/common/block
parentc08d804f01d88ac028c7271f0efed07373c3bc97 (diff)
soc/amd/common/cpu/tsc: factor out family-specific get_pstate_core_freq
Factor out the get_pstate_core_freq function from the SoC's acpi.c files to both avoid duplication and to also be able to use the same function in the TSC frequency calculation in a follow-up patch. The family 17h and 19h SoCs use the same frequency encoding in the P state MSRs while the family 1Ah SoCs use a different encoding. The family 15h and 16h SoCs use another encoding, but since this isn't implemented in Stoneyridge's acpi.c, this will be added in a follow-up patch. Signed-off-by: Felix Held <felix-coreboot@felixheld.de> Change-Id: I8619822c2c61e06ae5db86896d5323c9b105b25b Reviewed-on: https://review.coreboot.org/c/coreboot/+/74010 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com> Reviewed-by: Martin Roth <martin.roth@amd.corp-partner.google.com>
Diffstat (limited to 'src/soc/amd/common/block')
-rw-r--r--src/soc/amd/common/block/cpu/Kconfig12
-rw-r--r--src/soc/amd/common/block/cpu/tsc/Makefile.inc16
-rw-r--r--src/soc/amd/common/block/cpu/tsc/cpufreq_17_19.c48
-rw-r--r--src/soc/amd/common/block/cpu/tsc/cpufreq_1a.c18
4 files changed, 94 insertions, 0 deletions
diff --git a/src/soc/amd/common/block/cpu/Kconfig b/src/soc/amd/common/block/cpu/Kconfig
index 5dc846bb00..391e1e5b35 100644
--- a/src/soc/amd/common/block/cpu/Kconfig
+++ b/src/soc/amd/common/block/cpu/Kconfig
@@ -39,6 +39,18 @@ config ACPI_CPU_STRING
endif # SOC_AMD_COMMON_BLOCK_NONCAR
+config SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM17H_19H
+ bool
+ help
+ Select this option to include code to calculate the CPU frequency
+ from the P state MSR values on AMD CPU families 17h and 19h.
+
+config SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM1AH
+ bool
+ help
+ Select this option to include code to calculate the CPU frequency
+ from the P state MSR values on AMD CPU family 1Ah.
+
config SOC_AMD_COMMON_BLOCK_MCA_COMMON
bool
help
diff --git a/src/soc/amd/common/block/cpu/tsc/Makefile.inc b/src/soc/amd/common/block/cpu/tsc/Makefile.inc
index ba7f942c0b..6176023223 100644
--- a/src/soc/amd/common/block/cpu/tsc/Makefile.inc
+++ b/src/soc/amd/common/block/cpu/tsc/Makefile.inc
@@ -1,4 +1,20 @@
## SPDX-License-Identifier: GPL-2.0-only
+
+bootblock-$(CONFIG_SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM17H_19H) += cpufreq_17_19.c
+bootblock-$(CONFIG_SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM1AH) += cpufreq_1a.c
+
+verstage_x86-$(CONFIG_SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM17H_19H) += cpufreq_17_19.c
+verstage_x86-$(CONFIG_SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM1AH) += cpufreq_1a.c
+
+romstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM17H_19H) += cpufreq_17_19.c
+romstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM1AH) += cpufreq_1a.c
+
+ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM17H_19H) += cpufreq_17_19.c
+ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM1AH) += cpufreq_1a.c
+
+smm-$(CONFIG_SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM17H_19H) += cpufreq_17_19.c
+smm-$(CONFIG_SOC_AMD_COMMON_BLOCK_CPUFREQ_FAM1AH) += cpufreq_1a.c
+
ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H),y)
bootblock-y += tsc_freq.c
diff --git a/src/soc/amd/common/block/cpu/tsc/cpufreq_17_19.c b/src/soc/amd/common/block/cpu/tsc/cpufreq_17_19.c
new file mode 100644
index 0000000000..8f5e3012d1
--- /dev/null
+++ b/src/soc/amd/common/block/cpu/tsc/cpufreq_17_19.c
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <amdblocks/cpu.h>
+#include <console/console.h>
+#include <soc/msr.h>
+#include <types.h>
+
+#define PSTATE_DEF_FREQ_DIV_MIN 0x8
+#define PSTATE_DEF_EIGHTH_STEP_MAX 0x1A
+#define PSTATE_DEF_FREQ_DIV_MAX 0x3E
+#define PSTATE_DEF_CORE_FREQ_BASE 25
+
+uint32_t get_pstate_core_freq(union pstate_msr pstate_reg)
+{
+ uint32_t core_freq, core_freq_mul, core_freq_div;
+ bool valid_freq_divisor;
+
+ /* Core frequency multiplier */
+ core_freq_mul = pstate_reg.cpu_fid_0_7;
+
+ /* Core frequency divisor ID */
+ core_freq_div = pstate_reg.cpu_dfs_id;
+
+ if (core_freq_div == 0) {
+ return 0;
+ } else if ((core_freq_div >= PSTATE_DEF_FREQ_DIV_MIN)
+ && (core_freq_div <= PSTATE_DEF_EIGHTH_STEP_MAX)) {
+ /* Allow 1/8 integer steps for this range */
+ valid_freq_divisor = true;
+ } else if ((core_freq_div > PSTATE_DEF_EIGHTH_STEP_MAX)
+ && (core_freq_div <= PSTATE_DEF_FREQ_DIV_MAX) && !(core_freq_div & 0x1)) {
+ /* Only allow 1/4 integer steps for this range */
+ valid_freq_divisor = true;
+ } else {
+ valid_freq_divisor = false;
+ }
+
+ if (valid_freq_divisor) {
+ /* 25 * core_freq_mul / (core_freq_div / 8) */
+ core_freq =
+ ((PSTATE_DEF_CORE_FREQ_BASE * core_freq_mul * 8) / (core_freq_div));
+ } else {
+ printk(BIOS_WARNING, "Undefined core_freq_div %x used. Force to 1.\n",
+ core_freq_div);
+ core_freq = (PSTATE_DEF_CORE_FREQ_BASE * core_freq_mul);
+ }
+ return core_freq;
+}
diff --git a/src/soc/amd/common/block/cpu/tsc/cpufreq_1a.c b/src/soc/amd/common/block/cpu/tsc/cpufreq_1a.c
new file mode 100644
index 0000000000..c8cb59a37e
--- /dev/null
+++ b/src/soc/amd/common/block/cpu/tsc/cpufreq_1a.c
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <amdblocks/cpu.h>
+#include <soc/msr.h>
+#include <types.h>
+
+#define PSTATE_DEF_CORE_FREQ_BASE 5
+
+uint32_t get_pstate_core_freq(union pstate_msr pstate_reg)
+{
+ uint32_t core_freq_mul;
+
+ /* Core frequency multiplier */
+ core_freq_mul = pstate_reg.cpu_fid_0_11;
+
+ /* CPU frequency is 5 * core_freq_mul */
+ return PSTATE_DEF_CORE_FREQ_BASE * core_freq_mul;
+}