aboutsummaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/intel/baytrail/baytrail/msr.h7
-rw-r--r--src/soc/intel/baytrail/baytrail/pattrs.h13
-rw-r--r--src/soc/intel/baytrail/ramstage.c21
-rw-r--r--src/soc/intel/baytrail/tsc_freq.c34
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;
}