baytrail: Add BCLK and IACORE to pattrs

The bus clock speed is needed when building ACPI P-state tables
so extract that function and have the value be saved in pattrs.

The various IACORE values are also needed, but rather than have
the ACPI code to the bit manipulation have the pattrs store an
array of the possible values for it to use directly.

BUG=chrome-os-partner:23505
BRANCH=none
TEST=build and boot on rambi

Change-Id: I5ac06ccf66e9109186dd01342dbb6ccdd334ca69
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/176140
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Commit-Queue: Aaron Durbin <adurbin@chromium.org>
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/4953
Tested-by: build bot (Jenkins)
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
This commit is contained in:
Duncan Laurie 2013-11-07 12:47:35 -08:00 committed by Aaron Durbin
parent 05a3393a2c
commit 6aa9f1f0eb
4 changed files with 57 additions and 22 deletions

View File

@ -31,9 +31,14 @@
#define MSR_PKG_POWER_SKU_UNIT 0x606 #define MSR_PKG_POWER_SKU_UNIT 0x606
#define MSR_PKG_POWER_LIMIT 0x610 #define MSR_PKG_POWER_LIMIT 0x610
#define MSR_IACORE_RATIOS 0x66a #define MSR_IACORE_RATIOS 0x66a
#define MSR_IACORE_TURBO_RATIOS 0x66c
#define MSR_IACORE_VIDS 0x66b #define MSR_IACORE_VIDS 0x66b
#define MSR_IACORE_TURBO_VIDS 0x66d
#define MSR_PKG_TURBO_CFG1 0x670 #define MSR_PKG_TURBO_CFG1 0x670
#define MSR_CPU_TURBO_WKLD_CFG1 0x671 #define MSR_CPU_TURBO_WKLD_CFG1 0x671
#define MSR_CPU_TURBO_WKLD_CFG2 0x672 #define MSR_CPU_TURBO_WKLD_CFG2 0x672
#endif /* _BAYTRAIL_IOSF_H_ */ /* Read BCLK from MSR */
unsigned bus_freq_khz(void);
#endif /* _BAYTRAIL_MSR_H_ */

View File

@ -23,6 +23,14 @@
#include <stdint.h> #include <stdint.h>
#include <cpu/x86/msr.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 /* The pattrs structure is a common place to stash pertinent information
* about the processor or platform. Instead of going to the source (msrs, cpuid) * about the processor or platform. Instead of going to the source (msrs, cpuid)
* every time an attribute is needed use the pattrs structure. * every time an attribute is needed use the pattrs structure.
@ -30,14 +38,15 @@
struct pattrs { struct pattrs {
msr_t platform_id; msr_t platform_id;
msr_t platform_info; msr_t platform_info;
msr_t iacore_ratios; int iacore_ratios[IACORE_END];
msr_t iacore_vids; int iacore_vids[IACORE_END];
uint32_t cpuid; uint32_t cpuid;
int revid; int revid;
int stepping; int stepping;
const void *microcode_patch; const void *microcode_patch;
int address_bits; int address_bits;
int num_cpus; int num_cpus;
unsigned bclk_khz;
}; };
/* This is just to hide the abstraction w/o relying on how the underlying /* This is just to hide the abstraction w/o relying on how the underlying

View File

@ -76,6 +76,7 @@ static const char *stepping_str[] = { "A0", "A1", "B0", "B1", "B2", "B3" };
static void fill_in_pattrs(void) static void fill_in_pattrs(void)
{ {
device_t dev; device_t dev;
msr_t msr;
struct pattrs *attrs = (struct pattrs *)pattrs_get(); struct pattrs *attrs = (struct pattrs *)pattrs_get();
attrs->cpuid = cpuid_eax(1); 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_id, MSR_IA32_PLATFORM_ID);
fill_in_msr(&attrs->platform_info, MSR_PLATFORM_INFO); 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) static inline void set_acpi_sleep_type(int val)

View File

@ -22,28 +22,32 @@
#include <cpu/x86/tsc.h> #include <cpu/x86/tsc.h>
#include <baytrail/msr.h> #include <baytrail/msr.h>
unsigned bus_freq_khz(void)
{
msr_t clk_info = rdmsr(MSR_BSEL_CR_OVERCLOCK_CONTROL);
switch (clk_info.lo & 0x3) {
case 0:
return 83333;
case 1:
return 100000;
case 2:
return 133333;
case 3:
return 116666;
default:
return 0;
}
}
unsigned long tsc_freq_mhz(void) unsigned long tsc_freq_mhz(void)
{ {
msr_t platform_info; msr_t platform_info;
msr_t clk_info; unsigned bclk_khz = bus_freq_khz();
unsigned long bclk_khz;
if (!bclk_khz)
return 0;
platform_info = rdmsr(MSR_PLATFORM_INFO); platform_info = rdmsr(MSR_PLATFORM_INFO);
clk_info = rdmsr(MSR_BSEL_CR_OVERCLOCK_CONTROL);
switch (clk_info.lo & 0x3) {
case 0:
bclk_khz = 83333;
break;
case 1:
bclk_khz = 100000;
break;
case 2:
bclk_khz = 133333;
break;
case 3:
bclk_khz = 116666;
break;
}
return (bclk_khz * ((platform_info.lo >> 8) & 0xff)) / 1000; return (bclk_khz * ((platform_info.lo >> 8) & 0xff)) / 1000;
} }