intel/apollolake: Enable turbo
This patch adds punit initialization code after FspMemoryInit so that turbo can be initialized after that. BUG=chrome-os-partner:58158 BRANCH=None Change-Id: I4939da47da82b9a728cf1b5cf6d5ec54b4f5b31d Signed-off-by: Shaunak Saha <shaunak.saha@intel.com> Reviewed-on: https://review.coreboot.org/17203 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
a09b338362
commit
a012254d01
|
@ -23,6 +23,7 @@
|
|||
#include <device/device.h>
|
||||
|
||||
void apollolake_init_cpus(struct device *dev);
|
||||
void set_max_freq(void);
|
||||
#endif
|
||||
|
||||
#define CPUID_APOLLOLAKE_A0 0x506c8
|
||||
|
@ -88,4 +89,7 @@ void apollolake_init_cpus(struct device *dev);
|
|||
/* Common Timer Copy (CTC) frequency - 19.2MHz. */
|
||||
#define CTC_FREQ 19200000
|
||||
|
||||
/* This is burst mode BIT 38 in MSR_IA32_MISC_ENABLES MSR at offset 1A0h */
|
||||
#define APL_BURST_MODE_DISABLE 0x40
|
||||
|
||||
#endif /* _SOC_APOLLOLAKE_CPU_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_VEC_NUMBER 0x18
|
||||
#define PUINT_THERMAL_DEVICE_IRQ_LOCK 0x80000000
|
||||
|
||||
#define ACPI_PMIO_BASE 0x400
|
||||
#define ACPI_PMIO_SIZE 0x100
|
||||
#define R_ACPI_PM1_TMR 0x8
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
#define NB_DEVFN _PCI_DEVFN(0, 0)
|
||||
#define NB_DEV_ROOT _PCI_DEV(0x0, 0)
|
||||
|
||||
#define PUNIT_DEV _PCI_DEV(0, 1)
|
||||
#define PUNIT_DEVFN _PCI_DEVFN(0x0, 1)
|
||||
|
||||
#define IGD_DEV _PCI_DEV(0x2, 0)
|
||||
#define IGD_DEVFN _PCI_DEVFN(0x2, 0)
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <fsp/api.h>
|
||||
#include <fsp/memmap.h>
|
||||
#include <fsp/util.h>
|
||||
#include <soc/cpu.h>
|
||||
#include <soc/iomap.h>
|
||||
#include <soc/northbridge.h>
|
||||
#include <soc/pci_devs.h>
|
||||
|
@ -40,6 +41,9 @@
|
|||
#include <soc/uart.h>
|
||||
#include <string.h>
|
||||
#include <timestamp.h>
|
||||
#include <timer.h>
|
||||
#include <delay.h>
|
||||
#include "chip.h"
|
||||
|
||||
static struct chipset_power_state power_state CAR_GLOBAL;
|
||||
|
||||
|
@ -100,6 +104,65 @@ static void migrate_power_state(int is_recovery)
|
|||
}
|
||||
ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state);
|
||||
|
||||
/*
|
||||
* Punit Initialization code. This all isn't documented, but
|
||||
* this is the recipe.
|
||||
*/
|
||||
static bool punit_init(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t data;
|
||||
struct stopwatch sw;
|
||||
|
||||
/*
|
||||
* Software Core Disable Mask (P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR).
|
||||
* Enable all cores here.
|
||||
*/
|
||||
write32((void *)(MCH_BASE_ADDR + P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR),
|
||||
0x0);
|
||||
|
||||
void *bios_rest_cpl = (void *)(MCH_BASE_ADDR +
|
||||
P_CR_BIOS_RESET_CPL_0_0_0_MCHBAR);
|
||||
/* P-Unit bring up */
|
||||
reg = read32(bios_rest_cpl);
|
||||
if (reg == 0xffffffff) {
|
||||
/* P-unit not found */
|
||||
printk(BIOS_DEBUG, "Punit MMIO not available \n");
|
||||
return false;
|
||||
} else {
|
||||
/* Set Punit interrupt pin IPIN offset 3D */
|
||||
pci_write_config8(PUNIT_DEVFN, PCI_INTERRUPT_PIN, 0x2);
|
||||
|
||||
/* Set PUINT IRQ to 24 and INTPIN LOCK */
|
||||
write32((void *)(MCH_BASE_ADDR + PUNIT_THERMAL_DEVICE_IRQ),
|
||||
PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER |
|
||||
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) */
|
||||
write32(bios_rest_cpl, 0x1);
|
||||
|
||||
/*
|
||||
* Poll for bit 8 in same reg (RST_CPL).
|
||||
* We wait here till 1 ms for the bit to get set.
|
||||
*/
|
||||
stopwatch_init_msecs_expire(&sw, 1);
|
||||
while (!(read32(bios_rest_cpl) & 0x100)) {
|
||||
if (stopwatch_expired(&sw)) {
|
||||
printk(BIOS_DEBUG,
|
||||
"Failed to set RST_CPL bit\n");
|
||||
return false;
|
||||
}
|
||||
udelay(100);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
asmlinkage void car_stage_entry(void)
|
||||
{
|
||||
struct postcar_frame pcf;
|
||||
|
@ -119,6 +182,12 @@ asmlinkage void car_stage_entry(void)
|
|||
|
||||
s3wake = fill_power_state(ps) == ACPI_S3;
|
||||
fsp_memory_init(s3wake);
|
||||
|
||||
if (punit_init())
|
||||
set_max_freq();
|
||||
else
|
||||
printk(BIOS_DEBUG, "Punit failed to initialize properly\n");
|
||||
|
||||
if (postcar_frame_init(&pcf, 1*KiB))
|
||||
die("Unable to initialize postcar frame.\n");
|
||||
|
||||
|
|
|
@ -14,12 +14,54 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <cpu/intel/speedstep.h>
|
||||
#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, msr_rd;
|
||||
unsigned int eax;
|
||||
|
||||
eax = cpuid_eax(CPUID_LEAF_PM);
|
||||
|
||||
msr = rdmsr(MSR_IA32_MISC_ENABLES);
|
||||
if (!(eax &= 0x2) && ((msr.hi & APL_BURST_MODE_DISABLE) == 0)) {
|
||||
/* Burst Mode has been factory configured as disabled
|
||||
* and is not available in this physical processor
|
||||
* package.
|
||||
*/
|
||||
printk(BIOS_DEBUG, "Burst Mode is factory disabled\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Enable burst mode */
|
||||
msr.hi &= ~APL_BURST_MODE_DISABLE;
|
||||
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(IA32_PERF_CTL);
|
||||
msr.lo &= ~0xff00;
|
||||
|
||||
/* Read the frequency limit ratio and set it properly in PERF_CTL */
|
||||
msr_rd = rdmsr(FREQ_LIMIT_RATIO);
|
||||
msr.lo |= (msr_rd.lo & 0xff) << 8;
|
||||
|
||||
wrmsr(IA32_PERF_CTL, msr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue