From a25117d83f2929c4c51ec8afa0798f015cdaa3db Mon Sep 17 00:00:00 2001 From: Felix Held Date: Fri, 10 Mar 2023 00:04:46 +0100 Subject: soc/amd/glinda: introduce and use pstate_msr bitfield struct Add the pstate_msr union of a bitfield struct and a raw uint64_t to allow easier access of the bitfields of the P state MSRs which will be implemented in a following patch. PPR #57254 Rev 1.52 was used as a reference. This patch adds and uses the cpu_vid_8 bit which is the 9th bit of the voltage ID specified in the SVI3 spec. The way the CPU frequency is encoded in the PSTATE MSR has changed compared to Phoenix, so also update the comment in the SoC's Kconfig file that the selected SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H is likely incompatible which will be addressed in the future. Signed-off-by: Felix Held Change-Id: I3d1878ce4d9bc62ac597e6f71ef9630491628698 Reviewed-on: https://review.coreboot.org/c/coreboot/+/73924 Tested-by: build bot (Jenkins) Reviewed-by: Fred Reitberger --- src/soc/amd/glinda/Kconfig | 2 +- src/soc/amd/glinda/acpi.c | 50 ++++++++++-------------------------- src/soc/amd/glinda/include/soc/msr.h | 29 +++++++++++---------- 3 files changed, 29 insertions(+), 52 deletions(-) diff --git a/src/soc/amd/glinda/Kconfig b/src/soc/amd/glinda/Kconfig index 75ebace7f1..3ffee09d4f 100644 --- a/src/soc/amd/glinda/Kconfig +++ b/src/soc/amd/glinda/Kconfig @@ -69,7 +69,7 @@ config SOC_AMD_GLINDA select SOC_AMD_COMMON_BLOCK_SMU # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_SMU_SX_ENTRY # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_SPI # TODO: Check if this is still correct - select SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H # TODO: Check if this is still correct + select SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H # FIXME: This is likely incompatible select SOC_AMD_COMMON_BLOCK_UART # TODO: Check if this is still correct select SOC_AMD_COMMON_BLOCK_UCODE # TODO: Check if this is still correct select SOC_AMD_COMMON_FSP_CCX_CPPC_HOB # TODO: Check if this is still correct diff --git a/src/soc/amd/glinda/acpi.c b/src/soc/amd/glinda/acpi.c index 6e837283c8..b6830a48aa 100644 --- a/src/soc/amd/glinda/acpi.c +++ b/src/soc/amd/glinda/acpi.c @@ -100,57 +100,33 @@ void acpi_fill_fadt(acpi_fadt_t *fadt) uint32_t get_pstate_core_freq(msr_t pstate_def) { - uint32_t core_freq, core_freq_mul, core_freq_div; - bool valid_freq_divisor; + uint32_t core_freq_mul; + union pstate_msr pstate_reg; + + pstate_reg.raw = pstate_def.raw; /* Core frequency multiplier */ - core_freq_mul = pstate_def.lo & PSTATE_DEF_LO_FREQ_MUL_MASK; - - /* Core frequency divisor ID */ - core_freq_div = - (pstate_def.lo & PSTATE_DEF_LO_FREQ_DIV_MASK) >> PSTATE_DEF_LO_FREQ_DIV_SHIFT; - - if (core_freq_div == 0) { - return 0; - } else if ((core_freq_div >= PSTATE_DEF_LO_FREQ_DIV_MIN) - && (core_freq_div <= PSTATE_DEF_LO_EIGHTH_STEP_MAX)) { - /* Allow 1/8 integer steps for this range */ - valid_freq_divisor = true; - } else if ((core_freq_div > PSTATE_DEF_LO_EIGHTH_STEP_MAX) - && (core_freq_div <= PSTATE_DEF_LO_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; - } + core_freq_mul = pstate_reg.cpu_fid_0_11; - if (valid_freq_divisor) { - /* 25 * core_freq_mul / (core_freq_div / 8) */ - core_freq = - ((PSTATE_DEF_LO_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_LO_CORE_FREQ_BASE * core_freq_mul); - } - return core_freq; + /* CPU frequency is 5 * core_freq_mul */ + return PSTATE_DEF_LO_CORE_FREQ_BASE * core_freq_mul; } uint32_t get_pstate_core_power(msr_t pstate_def) { uint32_t voltage_in_uvolts, core_vid, current_value_amps, current_divisor, power_in_mw; + union pstate_msr pstate_reg; + + pstate_reg.raw = pstate_def.raw; /* Core voltage ID */ - core_vid = - (pstate_def.lo & PSTATE_DEF_LO_CORE_VID_MASK) >> PSTATE_DEF_LO_CORE_VID_SHIFT; + core_vid = pstate_reg.cpu_vid_0_7 | pstate_reg.cpu_vid_8 << 8; /* Current value in amps */ - current_value_amps = - (pstate_def.lo & PSTATE_DEF_LO_CUR_VAL_MASK) >> PSTATE_DEF_LO_CUR_VAL_SHIFT; + current_value_amps = pstate_reg.idd_value; /* Current divisor */ - current_divisor = - (pstate_def.lo & PSTATE_DEF_LO_CUR_DIV_MASK) >> PSTATE_DEF_LO_CUR_DIV_SHIFT; + current_divisor = pstate_reg.idd_div; /* Voltage */ if (core_vid == 0x00) { diff --git a/src/soc/amd/glinda/include/soc/msr.h b/src/soc/amd/glinda/include/soc/msr.h index 51ab5851b1..2c5b933b96 100644 --- a/src/soc/amd/glinda/include/soc/msr.h +++ b/src/soc/amd/glinda/include/soc/msr.h @@ -6,20 +6,21 @@ #define AMD_GLINDA_MSR_H /* MSRC001_00[6B:64] P-state [7:0] bit definitions */ -#define PSTATE_DEF_LO_CUR_DIV_SHIFT 30 -#define PSTATE_DEF_LO_CUR_DIV_MASK (0x3 << PSTATE_DEF_LO_CUR_DIV_SHIFT) -#define PSTATE_DEF_LO_CUR_VAL_SHIFT 22 -#define PSTATE_DEF_LO_CUR_VAL_MASK (0xFF << PSTATE_DEF_LO_CUR_VAL_SHIFT) -#define PSTATE_DEF_LO_CORE_VID_SHIFT 14 -#define PSTATE_DEF_LO_CORE_VID_MASK (0xFF << PSTATE_DEF_LO_CORE_VID_SHIFT) -#define PSTATE_DEF_LO_FREQ_DIV_SHIFT 8 -#define PSTATE_DEF_LO_FREQ_DIV_MASK (0x3F << PSTATE_DEF_LO_FREQ_DIV_SHIFT) -#define PSTATE_DEF_LO_FREQ_DIV_MIN 0x8 -#define PSTATE_DEF_LO_EIGHTH_STEP_MAX 0x1A -#define PSTATE_DEF_LO_FREQ_DIV_MAX 0x3E -#define PSTATE_DEF_LO_FREQ_MUL_SHIFT 0 -#define PSTATE_DEF_LO_FREQ_MUL_MASK (0xFF << PSTATE_DEF_LO_FREQ_MUL_SHIFT) -#define PSTATE_DEF_LO_CORE_FREQ_BASE 25 +union pstate_msr { + struct { + uint64_t cpu_fid_0_11 : 12; /* [ 0..11] */ + uint64_t : 2; /* [12..13] */ + uint64_t cpu_vid_0_7 : 8; /* [14..21] */ + uint64_t idd_value : 8; /* [22..29] */ + uint64_t idd_div : 2; /* [30..31] */ + uint64_t cpu_vid_8 : 1; /* [32..32] */ + uint64_t : 30; /* [33..62] */ + uint64_t pstate_en : 1; /* [63..63] */ + }; + uint64_t raw; +}; + +#define PSTATE_DEF_LO_CORE_FREQ_BASE 5 /* Value defined in Serial VID Interface 3.0 spec (#56413, NDA only) */ #define SERIAL_VID_DECODE_MICROVOLTS 5000 -- cgit v1.2.3