diff options
-rw-r--r-- | src/soc/intel/baytrail/baytrail/msr.h | 7 | ||||
-rw-r--r-- | src/soc/intel/baytrail/baytrail/pattrs.h | 13 | ||||
-rw-r--r-- | src/soc/intel/baytrail/ramstage.c | 21 | ||||
-rw-r--r-- | src/soc/intel/baytrail/tsc_freq.c | 34 |
4 files changed, 55 insertions, 20 deletions
diff --git a/src/soc/intel/baytrail/baytrail/msr.h b/src/soc/intel/baytrail/baytrail/msr.h index 462f24990c..dd03af0d17 100644 --- a/src/soc/intel/baytrail/baytrail/msr.h +++ b/src/soc/intel/baytrail/baytrail/msr.h @@ -31,9 +31,14 @@ #define MSR_PKG_POWER_SKU_UNIT 0x606 #define MSR_PKG_POWER_LIMIT 0x610 #define MSR_IACORE_RATIOS 0x66a +#define MSR_IACORE_TURBO_RATIOS 0x66c #define MSR_IACORE_VIDS 0x66b +#define MSR_IACORE_TURBO_VIDS 0x66d #define MSR_PKG_TURBO_CFG1 0x670 #define MSR_CPU_TURBO_WKLD_CFG1 0x671 #define MSR_CPU_TURBO_WKLD_CFG2 0x672 -#endif /* _BAYTRAIL_IOSF_H_ */ +/* Read BCLK from MSR */ +unsigned bus_freq_khz(void); + +#endif /* _BAYTRAIL_MSR_H_ */ diff --git a/src/soc/intel/baytrail/baytrail/pattrs.h b/src/soc/intel/baytrail/baytrail/pattrs.h index 7c210b95af..d4eb721593 100644 --- a/src/soc/intel/baytrail/baytrail/pattrs.h +++ b/src/soc/intel/baytrail/baytrail/pattrs.h @@ -23,6 +23,14 @@ #include <stdint.h> #include <cpu/x86/msr.h> +enum { + IACORE_MIN, + IACORE_LFM, + IACORE_MAX, + IACORE_TURBO, + IACORE_END +}; + /* The pattrs structure is a common place to stash pertinent information * about the processor or platform. Instead of going to the source (msrs, cpuid) * every time an attribute is needed use the pattrs structure. @@ -30,14 +38,15 @@ struct pattrs { msr_t platform_id; msr_t platform_info; - msr_t iacore_ratios; - msr_t iacore_vids; + int iacore_ratios[IACORE_END]; + int iacore_vids[IACORE_END]; uint32_t cpuid; int revid; int stepping; const void *microcode_patch; int address_bits; int num_cpus; + unsigned bclk_khz; }; /* This is just to hide the abstraction w/o relying on how the underlying diff --git a/src/soc/intel/baytrail/ramstage.c b/src/soc/intel/baytrail/ramstage.c index ab29190936..0c2bed86b7 100644 --- a/src/soc/intel/baytrail/ramstage.c +++ b/src/soc/intel/baytrail/ramstage.c @@ -76,6 +76,7 @@ static const char *stepping_str[] = { "A0", "A1", "B0", "B1", "B2", "B3" }; static void fill_in_pattrs(void) { device_t dev; + msr_t msr; struct pattrs *attrs = (struct pattrs *)pattrs_get(); attrs->cpuid = cpuid_eax(1); @@ -103,8 +104,24 @@ static void fill_in_pattrs(void) fill_in_msr(&attrs->platform_id, MSR_IA32_PLATFORM_ID); fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO); - fill_in_msr(&attrs->iacore_ratios, MSR_IACORE_RATIOS); - fill_in_msr(&attrs->iacore_vids, MSR_IACORE_VIDS); + + /* Set IA core speed ratio and voltages */ + msr = rdmsr(MSR_IACORE_RATIOS); + attrs->iacore_ratios[IACORE_MIN] = msr.lo & 0x7f; + attrs->iacore_ratios[IACORE_LFM] = (msr.lo >> 8) & 0x7f; + attrs->iacore_ratios[IACORE_MAX] = (msr.lo >> 16) & 0x7f; + msr = rdmsr(MSR_IACORE_TURBO_RATIOS); + attrs->iacore_ratios[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */ + + msr = rdmsr(MSR_IACORE_VIDS); + attrs->iacore_vids[IACORE_MIN] = msr.lo & 0x7f; + attrs->iacore_vids[IACORE_LFM] = (msr.lo >> 8) & 0x7f; + attrs->iacore_vids[IACORE_MAX] = (msr.lo >> 16) & 0x7f; + msr = rdmsr(MSR_IACORE_TURBO_VIDS); + attrs->iacore_vids[IACORE_TURBO] = (msr.lo & 0xff); /* 1 core max */ + + /* Set bus clock speed */ + attrs->bclk_khz = bus_freq_khz(); } static inline void set_acpi_sleep_type(int val) diff --git a/src/soc/intel/baytrail/tsc_freq.c b/src/soc/intel/baytrail/tsc_freq.c index 7795ab45b0..90f154c896 100644 --- a/src/soc/intel/baytrail/tsc_freq.c +++ b/src/soc/intel/baytrail/tsc_freq.c @@ -22,28 +22,32 @@ #include <cpu/x86/tsc.h> #include <baytrail/msr.h> -unsigned long tsc_freq_mhz(void) +unsigned bus_freq_khz(void) { - msr_t platform_info; - msr_t clk_info; - unsigned long bclk_khz; - - platform_info = rdmsr(MSR_PLATFORM_INFO); - clk_info = rdmsr(MSR_BSEL_CR_OVERCLOCK_CONTROL); + msr_t clk_info = rdmsr(MSR_BSEL_CR_OVERCLOCK_CONTROL); switch (clk_info.lo & 0x3) { case 0: - bclk_khz = 83333; - break; + return 83333; case 1: - bclk_khz = 100000; - break; + return 100000; case 2: - bclk_khz = 133333; - break; + return 133333; case 3: - bclk_khz = 116666; - break; + return 116666; + default: + return 0; } +} + +unsigned long tsc_freq_mhz(void) +{ + msr_t platform_info; + unsigned bclk_khz = bus_freq_khz(); + + if (!bclk_khz) + return 0; + + platform_info = rdmsr(MSR_PLATFORM_INFO); return (bclk_khz * ((platform_info.lo >> 8) & 0xff)) / 1000; } |