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 <felix-coreboot@felixheld.de> Change-Id: I3d1878ce4d9bc62ac597e6f71ef9630491628698 Reviewed-on: https://review.coreboot.org/c/coreboot/+/73924 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Fred Reitberger <reitbergerfred@gmail.com>
This commit is contained in:
@@ -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_freq_mul = pstate_reg.cpu_fid_0_11;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
Reference in New Issue
Block a user