Shaunak Saha (shaunak.saha@intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17203
-gerrit
commit 0f3898de8337876354523f1fdf1fc718c87591c0 Author: Shaunak Saha shaunak.saha@intel.com Date: Mon Oct 10 12:34:28 2016 -0700
src/apollolake: Enable turbo
This patch adds punit initilazation code after FspMemoryInit so that turbo can be initialized after that.
Change-Id: I4939da47da82b9a728cf1b5cf6d5ec54b4f5b31d Signed-off-by: Shaunak Saha shaunak.saha@intel.com --- src/soc/intel/apollolake/chip.h | 2 + src/soc/intel/apollolake/include/soc/iomap.h | 6 +++ src/soc/intel/apollolake/romstage.c | 55 ++++++++++++++++++++++++++++ src/soc/intel/apollolake/tsc_freq.c | 38 +++++++++++++++++++ 4 files changed, 101 insertions(+)
diff --git a/src/soc/intel/apollolake/chip.h b/src/soc/intel/apollolake/chip.h index 6c3bcd8..706f810 100644 --- a/src/soc/intel/apollolake/chip.h +++ b/src/soc/intel/apollolake/chip.h @@ -124,4 +124,6 @@ struct soc_intel_apollolake_config { uint16_t prt0_gpio; };
+void get_max_freq(void); +void set_max_freq(void); #endif /* _SOC_APOLLOLAKE_CHIP_H_ */ diff --git a/src/soc/intel/apollolake/include/soc/iomap.h b/src/soc/intel/apollolake/include/soc/iomap.h index 621b0a6..c15ba95 100644 --- a/src/soc/intel/apollolake/include/soc/iomap.h +++ b/src/soc/intel/apollolake/include/soc/iomap.h @@ -25,6 +25,12 @@ #define MCH_BASE_ADDR 0xfed10000 #define MCH_BASE_SIZE (32 * KiB)
+#define P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR 0x7168 +#define P_CR_BIOS_RESET_CPL_0_0_0_MCHBAR 0x7078 +#define PUNIT_THERMAL_DEVICE_IRQ 0x700C +#define PUINT_THERMAL_DEVICE_IRQ 0x18 +#define PUINT_THERMAL_DEVICE_IRQ_LOCK 0x80000000 + #define ACPI_PMIO_BASE 0x400 #define ACPI_PMIO_SIZE 0x100 #define R_ACPI_PM1_TMR 0x8 diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c index 1f6a38f..f8bffdc 100644 --- a/src/soc/intel/apollolake/romstage.c +++ b/src/soc/intel/apollolake/romstage.c @@ -40,6 +40,8 @@ #include <soc/uart.h> #include <string.h> #include <timestamp.h> +#include <delay.h> +#include "chip.h"
static struct chipset_power_state power_state CAR_GLOBAL;
@@ -100,6 +102,55 @@ static void migrate_power_state(int is_recovery) } ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state);
+/* Punit Initialization code */ +/*this is all voodoo that isn't documented, but this is the recipe */ +static void punit_init(void) +{ + uint32_t reg; + uint32_t data, temp; + + /* + * Software Core Disable Mask (P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR)-7168h. + * Enable all cores here. + */ + temp = read32((void *)(MCH_BASE_ADDR + 0x00007168)); + write32((void *)(MCH_BASE_ADDR + P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR), 0x0); + + /* P-Unit bring up */ + reg = read32((void *)(MCH_BASE_ADDR + P_CR_BIOS_RESET_CPL_0_0_0_MCHBAR)); + if(reg == 0xffffffff) { + /* P-unit not found */ + printk(BIOS_DEBUG,"Punit MMIO not available \n"); + } + else { + printk(BIOS_DEBUG,"Punit MMIO available \n"); + + /* Set Punit interrupt pin IPIN offset 3D */ + write32((void *)(0xE000103D),0x002); + + /* Set PUINT IRQ to 24 and INTPIN LOCK */ + write32((void *)(MCH_BASE_ADDR + PUNIT_THERMAL_DEVICE_IRQ), + PUINT_THERMAL_DEVICE_IRQ | PUINT_THERMAL_DEVICE_IRQ_LOCK); + + data = read32((void *)(MCH_BASE_ADDR + 0x7818)); + data &= 0xFFFFE01F; + data |= (0x20 | 0x200); + write32((void *)(MCH_BASE_ADDR + 0x7818), data); + + /* Stage0 BIOS Reset Complete (RST_CPL): Set by BIOS to + * indicate that all power management configurations as part of reset + * are complete + */ + write32((void *)(MCH_BASE_ADDR + P_CR_BIOS_RESET_CPL_0_0_0_MCHBAR), 0x1); + + /* Poll for bit 8 in same reg (RST_CPL). It will be set once Pcode observes bit 0 being set */ + data = read32((void *)(MCH_BASE_ADDR + P_CR_BIOS_RESET_CPL_0_0_0_MCHBAR)); + while ( !(read32 ((void *)(MCH_BASE_ADDR + P_CR_BIOS_RESET_CPL_0_0_0_MCHBAR)) & 0x100) ) { + udelay(100); + } + } +} + asmlinkage void car_stage_entry(void) { struct postcar_frame pcf; @@ -119,6 +170,10 @@ asmlinkage void car_stage_entry(void)
s3wake = fill_power_state(ps) == ACPI_S3; fsp_memory_init(s3wake); + + punit_init(); + set_max_freq(); + if (postcar_frame_init(&pcf, 1*KiB)) die("Unable to initialize postcar frame.\n");
diff --git a/src/soc/intel/apollolake/tsc_freq.c b/src/soc/intel/apollolake/tsc_freq.c index 9dd1dea..c3168dc 100644 --- a/src/soc/intel/apollolake/tsc_freq.c +++ b/src/soc/intel/apollolake/tsc_freq.c @@ -14,12 +14,50 @@ * GNU General Public License for more details. */
+#include <cpu/intel/turbo.h> #include <cpu/x86/msr.h> #include <cpu/x86/tsc.h> #include <soc/cpu.h> +#include <console/console.h> +#include <delay.h> +#include "chip.h"
unsigned long tsc_freq_mhz(void) { msr_t msr = rdmsr(MSR_PLATFORM_INFO); return (BASE_CLOCK_MHZ * ((msr.lo >> 8) & 0xff)); } + +void set_max_freq(void) +{ + msr_t msr; + unsigned int eax; + + eax = cpuid_eax(6); + + msr = rdmsr(MSR_IA32_MISC_ENABLES); + if((eax == 0 ) && ((msr.hi & 0x4000000000)==0)) { + /* Burst Mode has been factory configured as disabled + * and is not available in this physical processor + * package. + */ + printk(BIOS_DEBUG, "Burst Mode is disabled\n"); + return; + } + else { + /* Enable burst mode */ + msr.hi = 0; + wrmsr(MSR_IA32_MISC_ENABLES, msr); + } + + /* Enable speed step. */ + msr = rdmsr(MSR_IA32_MISC_ENABLES); + msr.lo |= (1 << 16); + wrmsr(MSR_IA32_MISC_ENABLES, msr); + + /* Set P-State ratio */ + msr = rdmsr(0x199); + msr.lo &= ~(0xff00); + msr.lo |= 0x1700; + wrmsr(0x199,msr); +}