diff options
author | Felix Held <felix-coreboot@felixheld.de> | 2023-03-24 16:30:55 +0100 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2023-03-29 16:15:10 +0000 |
commit | a63f859553a29842fd8d65ae8a6523cd429a5f85 (patch) | |
tree | ccf769584dc8e02611be5123f2721f41a21023f3 /src/soc/amd/common/block | |
parent | c08d804f01d88ac028c7271f0efed07373c3bc97 (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/Kconfig | 12 | ||||
-rw-r--r-- | src/soc/amd/common/block/cpu/tsc/Makefile.inc | 16 | ||||
-rw-r--r-- | src/soc/amd/common/block/cpu/tsc/cpufreq_17_19.c | 48 | ||||
-rw-r--r-- | src/soc/amd/common/block/cpu/tsc/cpufreq_1a.c | 18 |
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; +} |