Message ID | 20200928042611.1696178-2-sjg@chromium.org |
---|---|
State | Superseded |
Delegated to: | Bin Meng |
Headers | show |
Series | x86: Allow Coral to boot into Chrome OS | expand |
Hi Simon, On Mon, Sep 28, 2020 at 12:26 PM Simon Glass <sjg@chromium.org> wrote: > > Set up MSRs required for Apollo Lake. This enables Linux to use the > timers correctly. Also write the fixed MSRs for this platform. > > Signed-off-by: Simon Glass <sjg@chromium.org> > --- > > arch/x86/cpu/apollolake/cpu.c | 84 ++++++++++++++++++++++ > arch/x86/cpu/apollolake/cpu_common.c | 25 +++++++ > arch/x86/cpu/apollolake/cpu_spl.c | 20 ------ > arch/x86/cpu/intel_common/cpu.c | 19 +++++ > arch/x86/include/asm/arch-apollolake/cpu.h | 7 ++ > arch/x86/include/asm/cpu_common.h | 2 + > arch/x86/include/asm/msr-index.h | 20 +++++- > 7 files changed, 156 insertions(+), 21 deletions(-) > > diff --git a/arch/x86/cpu/apollolake/cpu.c b/arch/x86/cpu/apollolake/cpu.c > index 8da2e64e226..e39b4cfba3c 100644 > --- a/arch/x86/cpu/apollolake/cpu.c > +++ b/arch/x86/cpu/apollolake/cpu.c > @@ -13,6 +13,9 @@ > #include <asm/cpu_x86.h> > #include <asm/intel_acpi.h> > #include <asm/msr.h> > +#include <asm/mtrr.h> > +#include <asm/arch/cpu.h> > +#include <asm/arch/iomap.h> > #include <dm/acpi.h> > > #define CSTATE_RES(address_space, width, offset, address) \ > @@ -86,6 +89,86 @@ static int acpi_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx) > return 0; > } > > +static void update_fixed_mtrss(void) I think the name should be _mtrrs, not mtrss > +{ > + native_write_msr(MTRR_FIX_64K_00000_MSR, > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); > + native_write_msr(MTRR_FIX_16K_80000_MSR, > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); > + native_write_msr(MTRR_FIX_4K_E0000_MSR, > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); > + native_write_msr(MTRR_FIX_4K_E8000_MSR, > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); > + native_write_msr(MTRR_FIX_4K_F0000_MSR, > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); > + native_write_msr(MTRR_FIX_4K_F8000_MSR, > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), > + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); > +} > + > +static void setup_core_msrs(void) > +{ > + wrmsrl(MSR_PMG_CST_CONFIG_CONTROL, > + PKG_C_STATE_LIMIT_C2_MASK | CORE_C_STATE_LIMIT_C10_MASK | > + IO_MWAIT_REDIRECT_MASK | CST_CFG_LOCK_MASK); > + /* Power Management I/O base address for I/O trapping to C-states */ > + wrmsrl(MSR_PMG_IO_CAPTURE_ADR, ACPI_PMIO_CST_REG | > + (PMG_IO_BASE_CST_RNG_BLK_SIZE << 16)); > + /* Disable C1E */ > + msr_clrsetbits_64(MSR_POWER_CTL, 0x2, 0); > + /* Disable support for MONITOR and MWAIT instructions */ > + msr_clrsetbits_64(MSR_IA32_MISC_ENABLE, MISC_ENABLE_MWAIT, 0); > + /* > + * Enable and Lock the Advanced Encryption Standard (AES-NI) > + * feature register > + */ > + msr_clrsetbits_64(MSR_FEATURE_CONFIG, FEATURE_CONFIG_RESERVED_MASK, > + FEATURE_CONFIG_LOCK); > + > + update_fixed_mtrss(); > +} > + > +static int soc_core_init(void) > +{ > + struct udevice *pmc; > + int ret; > + > + /* Clear out pending MCEs */ > + cpu_mca_configure(); > + > + /* Set core MSRs */ > + setup_core_msrs(); > + /* > + * Enable ACPI PM timer emulation, which also lets microcode know > + * location of ACPI_BASE_ADDRESS. This also enables other features > + * implemented in microcode. > + */ > + ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc); > + if (ret) > + return log_msg_ret("PMC", ret); > + enable_pm_timer_emulation(pmc); > + > + return 0; > +} > + > +static int cpu_apl_probe(struct udevice *dev) > +{ > + if (gd->flags & GD_FLG_RELOC) { > + int ret; > + > + ret = soc_core_init(); > + if (ret) > + return log_ret(ret); > + } > + > + return 0; > +} > + > struct acpi_ops apl_cpu_acpi_ops = { > .fill_ssdt = acpi_cpu_fill_ssdt, > }; > @@ -107,6 +190,7 @@ U_BOOT_DRIVER(cpu_x86_apl_drv) = { > .id = UCLASS_CPU, > .of_match = cpu_x86_apl_ids, > .bind = cpu_x86_bind, > + .probe = cpu_apl_probe, > .ops = &cpu_x86_apl_ops, > ACPI_OPS_PTR(&apl_cpu_acpi_ops) > .flags = DM_FLAG_PRE_RELOC, > diff --git a/arch/x86/cpu/apollolake/cpu_common.c b/arch/x86/cpu/apollolake/cpu_common.c > index ba6bda37bc5..63f6999b024 100644 > --- a/arch/x86/cpu/apollolake/cpu_common.c > +++ b/arch/x86/cpu/apollolake/cpu_common.c > @@ -4,8 +4,13 @@ > */ > > #include <common.h> > +#include <dm.h> > +#include <log.h> > #include <asm/cpu_common.h> > #include <asm/msr.h> > +#include <asm/arch/cpu.h> > +#include <asm/arch/iomap.h> > +#include <power/acpi_pmc.h> > > void cpu_flush_l1d_to_l2(void) > { > @@ -15,3 +20,23 @@ void cpu_flush_l1d_to_l2(void) > msr.lo |= FLUSH_DL1_L2; > msr_write(MSR_POWER_MISC, msr); > } > + > +void enable_pm_timer_emulation(const struct udevice *pmc) > +{ > + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc); > + msr_t msr; > + > + /* > + * The derived frequency is calculated as follows: > + * (CTC_FREQ * msr[63:32]) >> 32 = target frequency. > + * > + * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is > + * used. > + */ > + msr.hi = (3579545ULL << 32) / CTC_FREQ; > + > + /* Set PM1 timer IO port and enable */ > + msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR); > + debug("PM timer %x %x\n", msr.hi, msr.lo); > + msr_write(MSR_EMULATE_PM_TIMER, msr); > +} > diff --git a/arch/x86/cpu/apollolake/cpu_spl.c b/arch/x86/cpu/apollolake/cpu_spl.c > index 9f32f2e27e1..fafe4dbc0a0 100644 > --- a/arch/x86/cpu/apollolake/cpu_spl.c > +++ b/arch/x86/cpu/apollolake/cpu_spl.c > @@ -114,26 +114,6 @@ static int fast_spi_cache_bios_region(void) > return 0; > } > > -static void enable_pm_timer_emulation(struct udevice *pmc) > -{ > - struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc); > - msr_t msr; > - > - /* > - * The derived frequency is calculated as follows: > - * (CTC_FREQ * msr[63:32]) >> 32 = target frequency. > - * > - * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is > - * used. > - */ > - msr.hi = (3579545ULL << 32) / CTC_FREQ; > - > - /* Set PM1 timer IO port and enable */ > - msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR); > - debug("PM timer %x %x\n", msr.hi, msr.lo); > - msr_write(MSR_EMULATE_PM_TIMER, msr); > -} > - > static void google_chromeec_ioport_range(uint *out_basep, uint *out_sizep) > { > uint base; > diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c > index 39aa0f63c65..c756fe08906 100644 > --- a/arch/x86/cpu/intel_common/cpu.c > +++ b/arch/x86/cpu/intel_common/cpu.c > @@ -306,3 +306,22 @@ int cpu_get_cores_per_package(void) > > return cores; > } > + > +void cpu_mca_configure(void) > +{ > + msr_t msr; > + int i; > + int num_banks; > + > + msr = msr_read(MSR_IA32_MCG_CAP); > + num_banks = msr.lo & 0xff; > + msr.lo = 0; > + msr.hi = 0; > + for (i = 0; i < num_banks; i++) { > + /* Clear the machine check status */ > + msr_write(MSR_IA32_MC0_STATUS + (i * 4), msr); > + /* Initialize machine checks */ > + msr_write(MSR_IA32_MC0_CTL + i * 4, > + (msr_t) {.lo = 0xffffffff, .hi = 0xffffffff}); > + } > +} > diff --git a/arch/x86/include/asm/arch-apollolake/cpu.h b/arch/x86/include/asm/arch-apollolake/cpu.h > index 5e906c5e7d7..a692104cd1f 100644 > --- a/arch/x86/include/asm/arch-apollolake/cpu.h > +++ b/arch/x86/include/asm/arch-apollolake/cpu.h > @@ -15,6 +15,13 @@ > #ifndef __ASSEMBLY__ > /* Flush L1D to L2 */ > void cpu_flush_l1d_to_l2(void); > + > +/** > + * Enable emulation of the PM timer Could we put more details on what this function does? > + * > + * @pmc: PMC device > + */ > +void enable_pm_timer_emulation(const struct udevice *pmc); > #endif > > #endif /* _ASM_ARCH_CPU_H */ > diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h > index 48f56c2aad9..66311de7fdc 100644 > --- a/arch/x86/include/asm/cpu_common.h > +++ b/arch/x86/include/asm/cpu_common.h > @@ -184,4 +184,6 @@ int cpu_get_max_turbo_ratio(void); > */ > int cpu_get_cores_per_package(void); > > +void cpu_mca_configure(void); Please add some comments on what this function does > + > #endif > diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h > index 94e6b18e21c..c49b4225ac2 100644 > --- a/arch/x86/include/asm/msr-index.h > +++ b/arch/x86/include/asm/msr-index.h > @@ -68,7 +68,18 @@ > #define MSR_BSEL_CR_OVERCLOCK_CONTROL 0x000000cd > #define MSR_PLATFORM_INFO 0x000000ce > #define MSR_PMG_CST_CONFIG_CONTROL 0x000000e2 > -#define SINGLE_PCTL (1 << 11) > +/* Set MSR_PMG_CST_CONFIG_CONTROL[3:0] for Package C-State limit */ > +#define PKG_C_STATE_LIMIT_C2_MASK BIT(1) > +/* Set MSR_PMG_CST_CONFIG_CONTROL[7:4] for Core C-State limit*/ > +#define CORE_C_STATE_LIMIT_C10_MASK 0x70 > +/* Set MSR_PMG_CST_CONFIG_CONTROL[10] to IO redirect to MWAIT */ > +#define IO_MWAIT_REDIRECT_MASK BIT(10) > +/* Set MSR_PMG_CST_CONFIG_CONTROL[15] to lock CST_CFG [0-15] bits */ > +#define CST_CFG_LOCK_MASK BIT(15) > +#define SINGLE_PCTL BIT(11) > + > +/* ACPI PMIO Offset to C-state register */ > +#define ACPI_PMIO_CST_REG (ACPI_BASE_ADDRESS + 0x14) > > #define MSR_MTRRcap 0x000000fe > #define MSR_IA32_BBL_CR_CTL 0x00000119 > @@ -83,6 +94,10 @@ > #define EMULATE_PM_TMR_EN (1 << 16) > #define EMULATE_DELAY_VALUE 0x13 > > +#define MSR_FEATURE_CONFIG 0x13c > +#define FEATURE_CONFIG_RESERVED_MASK 0x3ULL > +#define FEATURE_CONFIG_LOCK (1 << 0) > + > #define MSR_IA32_SYSENTER_CS 0x00000174 > #define MSR_IA32_SYSENTER_ESP 0x00000175 > #define MSR_IA32_SYSENTER_EIP 0x00000176 > @@ -453,6 +468,9 @@ > #define MSR_AMD_PERF_CTL 0xc0010062 > > #define MSR_PMG_CST_CONFIG_CTL 0x000000e2 > +/* CST Range (R/W) IO port block size */ > +#define PMG_IO_BASE_CST_RNG_BLK_SIZE 0x5 > + > #define MSR_PMG_IO_CAPTURE_ADR 0x000000e4 > #define MSR_IA32_MPERF 0x000000e7 > #define MSR_IA32_APERF 0x000000e8 > -- Regards, Bin
diff --git a/arch/x86/cpu/apollolake/cpu.c b/arch/x86/cpu/apollolake/cpu.c index 8da2e64e226..e39b4cfba3c 100644 --- a/arch/x86/cpu/apollolake/cpu.c +++ b/arch/x86/cpu/apollolake/cpu.c @@ -13,6 +13,9 @@ #include <asm/cpu_x86.h> #include <asm/intel_acpi.h> #include <asm/msr.h> +#include <asm/mtrr.h> +#include <asm/arch/cpu.h> +#include <asm/arch/iomap.h> #include <dm/acpi.h> #define CSTATE_RES(address_space, width, offset, address) \ @@ -86,6 +89,86 @@ static int acpi_cpu_fill_ssdt(const struct udevice *dev, struct acpi_ctx *ctx) return 0; } +static void update_fixed_mtrss(void) +{ + native_write_msr(MTRR_FIX_64K_00000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); + native_write_msr(MTRR_FIX_16K_80000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); + native_write_msr(MTRR_FIX_4K_E0000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); + native_write_msr(MTRR_FIX_4K_E8000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); + native_write_msr(MTRR_FIX_4K_F0000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); + native_write_msr(MTRR_FIX_4K_F8000_MSR, + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK), + MTRR_FIX_TYPE(MTRR_TYPE_WRBACK)); +} + +static void setup_core_msrs(void) +{ + wrmsrl(MSR_PMG_CST_CONFIG_CONTROL, + PKG_C_STATE_LIMIT_C2_MASK | CORE_C_STATE_LIMIT_C10_MASK | + IO_MWAIT_REDIRECT_MASK | CST_CFG_LOCK_MASK); + /* Power Management I/O base address for I/O trapping to C-states */ + wrmsrl(MSR_PMG_IO_CAPTURE_ADR, ACPI_PMIO_CST_REG | + (PMG_IO_BASE_CST_RNG_BLK_SIZE << 16)); + /* Disable C1E */ + msr_clrsetbits_64(MSR_POWER_CTL, 0x2, 0); + /* Disable support for MONITOR and MWAIT instructions */ + msr_clrsetbits_64(MSR_IA32_MISC_ENABLE, MISC_ENABLE_MWAIT, 0); + /* + * Enable and Lock the Advanced Encryption Standard (AES-NI) + * feature register + */ + msr_clrsetbits_64(MSR_FEATURE_CONFIG, FEATURE_CONFIG_RESERVED_MASK, + FEATURE_CONFIG_LOCK); + + update_fixed_mtrss(); +} + +static int soc_core_init(void) +{ + struct udevice *pmc; + int ret; + + /* Clear out pending MCEs */ + cpu_mca_configure(); + + /* Set core MSRs */ + setup_core_msrs(); + /* + * Enable ACPI PM timer emulation, which also lets microcode know + * location of ACPI_BASE_ADDRESS. This also enables other features + * implemented in microcode. + */ + ret = uclass_first_device_err(UCLASS_ACPI_PMC, &pmc); + if (ret) + return log_msg_ret("PMC", ret); + enable_pm_timer_emulation(pmc); + + return 0; +} + +static int cpu_apl_probe(struct udevice *dev) +{ + if (gd->flags & GD_FLG_RELOC) { + int ret; + + ret = soc_core_init(); + if (ret) + return log_ret(ret); + } + + return 0; +} + struct acpi_ops apl_cpu_acpi_ops = { .fill_ssdt = acpi_cpu_fill_ssdt, }; @@ -107,6 +190,7 @@ U_BOOT_DRIVER(cpu_x86_apl_drv) = { .id = UCLASS_CPU, .of_match = cpu_x86_apl_ids, .bind = cpu_x86_bind, + .probe = cpu_apl_probe, .ops = &cpu_x86_apl_ops, ACPI_OPS_PTR(&apl_cpu_acpi_ops) .flags = DM_FLAG_PRE_RELOC, diff --git a/arch/x86/cpu/apollolake/cpu_common.c b/arch/x86/cpu/apollolake/cpu_common.c index ba6bda37bc5..63f6999b024 100644 --- a/arch/x86/cpu/apollolake/cpu_common.c +++ b/arch/x86/cpu/apollolake/cpu_common.c @@ -4,8 +4,13 @@ */ #include <common.h> +#include <dm.h> +#include <log.h> #include <asm/cpu_common.h> #include <asm/msr.h> +#include <asm/arch/cpu.h> +#include <asm/arch/iomap.h> +#include <power/acpi_pmc.h> void cpu_flush_l1d_to_l2(void) { @@ -15,3 +20,23 @@ void cpu_flush_l1d_to_l2(void) msr.lo |= FLUSH_DL1_L2; msr_write(MSR_POWER_MISC, msr); } + +void enable_pm_timer_emulation(const struct udevice *pmc) +{ + struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc); + msr_t msr; + + /* + * The derived frequency is calculated as follows: + * (CTC_FREQ * msr[63:32]) >> 32 = target frequency. + * + * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is + * used. + */ + msr.hi = (3579545ULL << 32) / CTC_FREQ; + + /* Set PM1 timer IO port and enable */ + msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR); + debug("PM timer %x %x\n", msr.hi, msr.lo); + msr_write(MSR_EMULATE_PM_TIMER, msr); +} diff --git a/arch/x86/cpu/apollolake/cpu_spl.c b/arch/x86/cpu/apollolake/cpu_spl.c index 9f32f2e27e1..fafe4dbc0a0 100644 --- a/arch/x86/cpu/apollolake/cpu_spl.c +++ b/arch/x86/cpu/apollolake/cpu_spl.c @@ -114,26 +114,6 @@ static int fast_spi_cache_bios_region(void) return 0; } -static void enable_pm_timer_emulation(struct udevice *pmc) -{ - struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc); - msr_t msr; - - /* - * The derived frequency is calculated as follows: - * (CTC_FREQ * msr[63:32]) >> 32 = target frequency. - * - * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is - * used. - */ - msr.hi = (3579545ULL << 32) / CTC_FREQ; - - /* Set PM1 timer IO port and enable */ - msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR); - debug("PM timer %x %x\n", msr.hi, msr.lo); - msr_write(MSR_EMULATE_PM_TIMER, msr); -} - static void google_chromeec_ioport_range(uint *out_basep, uint *out_sizep) { uint base; diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c index 39aa0f63c65..c756fe08906 100644 --- a/arch/x86/cpu/intel_common/cpu.c +++ b/arch/x86/cpu/intel_common/cpu.c @@ -306,3 +306,22 @@ int cpu_get_cores_per_package(void) return cores; } + +void cpu_mca_configure(void) +{ + msr_t msr; + int i; + int num_banks; + + msr = msr_read(MSR_IA32_MCG_CAP); + num_banks = msr.lo & 0xff; + msr.lo = 0; + msr.hi = 0; + for (i = 0; i < num_banks; i++) { + /* Clear the machine check status */ + msr_write(MSR_IA32_MC0_STATUS + (i * 4), msr); + /* Initialize machine checks */ + msr_write(MSR_IA32_MC0_CTL + i * 4, + (msr_t) {.lo = 0xffffffff, .hi = 0xffffffff}); + } +} diff --git a/arch/x86/include/asm/arch-apollolake/cpu.h b/arch/x86/include/asm/arch-apollolake/cpu.h index 5e906c5e7d7..a692104cd1f 100644 --- a/arch/x86/include/asm/arch-apollolake/cpu.h +++ b/arch/x86/include/asm/arch-apollolake/cpu.h @@ -15,6 +15,13 @@ #ifndef __ASSEMBLY__ /* Flush L1D to L2 */ void cpu_flush_l1d_to_l2(void); + +/** + * Enable emulation of the PM timer + * + * @pmc: PMC device + */ +void enable_pm_timer_emulation(const struct udevice *pmc); #endif #endif /* _ASM_ARCH_CPU_H */ diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h index 48f56c2aad9..66311de7fdc 100644 --- a/arch/x86/include/asm/cpu_common.h +++ b/arch/x86/include/asm/cpu_common.h @@ -184,4 +184,6 @@ int cpu_get_max_turbo_ratio(void); */ int cpu_get_cores_per_package(void); +void cpu_mca_configure(void); + #endif diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 94e6b18e21c..c49b4225ac2 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -68,7 +68,18 @@ #define MSR_BSEL_CR_OVERCLOCK_CONTROL 0x000000cd #define MSR_PLATFORM_INFO 0x000000ce #define MSR_PMG_CST_CONFIG_CONTROL 0x000000e2 -#define SINGLE_PCTL (1 << 11) +/* Set MSR_PMG_CST_CONFIG_CONTROL[3:0] for Package C-State limit */ +#define PKG_C_STATE_LIMIT_C2_MASK BIT(1) +/* Set MSR_PMG_CST_CONFIG_CONTROL[7:4] for Core C-State limit*/ +#define CORE_C_STATE_LIMIT_C10_MASK 0x70 +/* Set MSR_PMG_CST_CONFIG_CONTROL[10] to IO redirect to MWAIT */ +#define IO_MWAIT_REDIRECT_MASK BIT(10) +/* Set MSR_PMG_CST_CONFIG_CONTROL[15] to lock CST_CFG [0-15] bits */ +#define CST_CFG_LOCK_MASK BIT(15) +#define SINGLE_PCTL BIT(11) + +/* ACPI PMIO Offset to C-state register */ +#define ACPI_PMIO_CST_REG (ACPI_BASE_ADDRESS + 0x14) #define MSR_MTRRcap 0x000000fe #define MSR_IA32_BBL_CR_CTL 0x00000119 @@ -83,6 +94,10 @@ #define EMULATE_PM_TMR_EN (1 << 16) #define EMULATE_DELAY_VALUE 0x13 +#define MSR_FEATURE_CONFIG 0x13c +#define FEATURE_CONFIG_RESERVED_MASK 0x3ULL +#define FEATURE_CONFIG_LOCK (1 << 0) + #define MSR_IA32_SYSENTER_CS 0x00000174 #define MSR_IA32_SYSENTER_ESP 0x00000175 #define MSR_IA32_SYSENTER_EIP 0x00000176 @@ -453,6 +468,9 @@ #define MSR_AMD_PERF_CTL 0xc0010062 #define MSR_PMG_CST_CONFIG_CTL 0x000000e2 +/* CST Range (R/W) IO port block size */ +#define PMG_IO_BASE_CST_RNG_BLK_SIZE 0x5 + #define MSR_PMG_IO_CAPTURE_ADR 0x000000e4 #define MSR_IA32_MPERF 0x000000e7 #define MSR_IA32_APERF 0x000000e8
Set up MSRs required for Apollo Lake. This enables Linux to use the timers correctly. Also write the fixed MSRs for this platform. Signed-off-by: Simon Glass <sjg@chromium.org> --- arch/x86/cpu/apollolake/cpu.c | 84 ++++++++++++++++++++++ arch/x86/cpu/apollolake/cpu_common.c | 25 +++++++ arch/x86/cpu/apollolake/cpu_spl.c | 20 ------ arch/x86/cpu/intel_common/cpu.c | 19 +++++ arch/x86/include/asm/arch-apollolake/cpu.h | 7 ++ arch/x86/include/asm/cpu_common.h | 2 + arch/x86/include/asm/msr-index.h | 20 +++++- 7 files changed, 156 insertions(+), 21 deletions(-)