1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <amdblocks/cpu.h> 4 #include <console/console.h> 5 #include <soc/msr.h> 6 #include <types.h> 7 8 #define PSTATE_DEF_FREQ_DIV_MIN 0x8 9 #define PSTATE_DEF_EIGHTH_STEP_MAX 0x1A 10 #define PSTATE_DEF_FREQ_DIV_MAX 0x3E 11 #define PSTATE_DEF_CORE_FREQ_BASE 25 12 get_pstate_core_freq(union pstate_msr pstate_reg)13uint32_t get_pstate_core_freq(union pstate_msr pstate_reg) 14 { 15 uint32_t core_freq, core_freq_mul, core_freq_div; 16 bool valid_freq_divisor; 17 18 /* Core frequency multiplier */ 19 core_freq_mul = pstate_reg.cpu_fid_0_7; 20 21 /* Core frequency divisor ID */ 22 core_freq_div = pstate_reg.cpu_dfs_id; 23 24 if (core_freq_div == 0) { 25 return 0; 26 } else if ((core_freq_div >= PSTATE_DEF_FREQ_DIV_MIN) 27 && (core_freq_div <= PSTATE_DEF_EIGHTH_STEP_MAX)) { 28 /* Allow 1/8 integer steps for this range */ 29 valid_freq_divisor = true; 30 } else if ((core_freq_div > PSTATE_DEF_EIGHTH_STEP_MAX) 31 && (core_freq_div <= PSTATE_DEF_FREQ_DIV_MAX) && !(core_freq_div & 0x1)) { 32 /* Only allow 1/4 integer steps for this range */ 33 valid_freq_divisor = true; 34 } else { 35 valid_freq_divisor = false; 36 } 37 38 if (valid_freq_divisor) { 39 /* 25 * core_freq_mul / (core_freq_div / 8) */ 40 core_freq = 41 ((PSTATE_DEF_CORE_FREQ_BASE * core_freq_mul * 8) / (core_freq_div)); 42 } else { 43 printk(BIOS_WARNING, "Undefined core_freq_div %x used. Force to 1.\n", 44 core_freq_div); 45 core_freq = (PSTATE_DEF_CORE_FREQ_BASE * core_freq_mul); 46 } 47 return core_freq; 48 } 49