diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/intel/skylake/chip.c | 12 | ||||
-rw-r--r-- | src/soc/intel/skylake/chip.h | 5 | ||||
-rw-r--r-- | src/soc/intel/skylake/finalize.c | 55 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/pci_devs.h | 2 | ||||
-rw-r--r-- | src/soc/intel/skylake/include/soc/pcr.h | 6 |
5 files changed, 80 insertions, 0 deletions
diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c index e6eb537fc5..f4dc4a729f 100644 --- a/src/soc/intel/skylake/chip.c +++ b/src/soc/intel/skylake/chip.c @@ -347,6 +347,18 @@ void soc_silicon_init_params(SILICON_INIT_UPD *params) params->SkipMpInit = config->SkipMpInit; + /* + * To disable Heci, the Psf needs to be left unlocked + * by FSP after end of post sequence. Based on the devicetree + * setting, we set the appropriate PsfUnlock policy in Fsp, + * do the changes and then lock it back in Coreboot + * + */ + if (config->HeciEnabled == 0) + params->PsfUnlock = 1; + else + params->PsfUnlock = 0; + for (i = 0; i < ARRAY_SIZE(config->domain_vr_config); i++) { params->VrConfigEnable[i] = config->domain_vr_config[i].vr_config_enable; diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h index 1ff1fcfc1c..1c45470b9f 100644 --- a/src/soc/intel/skylake/chip.h +++ b/src/soc/intel/skylake/chip.h @@ -331,6 +331,11 @@ struct soc_intel_skylake_config { * 3 = GT unsliced, 4 = GT sliced */ struct vr_config domain_vr_config[NUM_VR_DOMAINS]; + /* + * HeciEnabled decides the state of Heci1 at end of boot + * Setting to 0 (default) disables Heci1 and hides the device from OS + */ + u8 HeciEnabled; }; typedef struct soc_intel_skylake_config config_t; diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c index e2577aadeb..8069b405e8 100644 --- a/src/soc/intel/skylake/finalize.c +++ b/src/soc/intel/skylake/finalize.c @@ -31,6 +31,55 @@ #include <soc/spi.h> #include <soc/systemagent.h> #include <device/pci.h> +#include <chip.h> + +#define PCH_P2SB_EPMASK0 0xB0 +#define PCH_P2SB_EPMASK(mask_number) PCH_P2SB_EPMASK0 + (mask_number * 4) + +#define PCH_P2SB_E0 0xE0 + +static void pch_configure_endpoints(device_t dev, int epmask_id, uint32_t mask) +{ + uint32_t reg32; + + reg32 = pci_read_config32(dev, PCH_P2SB_EPMASK(epmask_id)); + pci_write_config32(dev, PCH_P2SB_EPMASK(epmask_id), reg32 | mask); +} + +static void pch_disable_heci(void) +{ + device_t dev; + u8 reg8; + uint32_t mask; + + dev = PCH_DEV_P2SB; + + /* + * if p2sb device 1f.1 is not present or hidden in devicetree + * p2sb device becomes NULL + */ + if (!dev) + return; + + /* unhide p2sb device */ + pci_write_config8(dev, PCH_P2SB_E0 + 1, 0); + + /* disable heci */ + pcr_andthenor32(PID_PSF1, PSF_BASE_ADDRESS + PCH_PCR_PSFX_T0_SHDW_PCIEN, + ~0, PCH_PCR_PSFX_T0_SHDW_PCIEN_FUNDIS); + + /* Remove the host accessing right to PSF register range. */ + /* Set p2sb PCI offset EPMASK5 C4h [29, 28, 27, 26] to [1, 1, 1, 1] */ + mask = (1 << 29) | (1 << 28) | (1 << 27) | (1 << 26); + pch_configure_endpoints(dev, 5, mask); + + /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */ + reg8 = pci_read_config8(dev, PCH_P2SB_E0 + 2); + pci_write_config8(dev, PCH_P2SB_E0 + 2, reg8 | (1 << 1)); + + /* hide p2sb device */ + pci_write_config8(dev, PCH_P2SB_E0 + 1, 1); +} static void pch_finalize_script(void) { @@ -40,6 +89,7 @@ static void pch_finalize_script(void) u16 tcobase; u16 tcocnt; uint8_t *pmcbase; + config_t *config; u32 pmsyncreg; /* Set SPI opcode menu */ @@ -69,6 +119,11 @@ static void pch_finalize_script(void) pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG); pmsyncreg |= PMSYNC_LOCK; write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg); + + /* we should disable Heci1 based on the devicetree policy */ + config = dev->chip_info; + if (config->HeciEnabled == 0) + pch_disable_heci(); } static void soc_lockdown(void) diff --git a/src/soc/intel/skylake/include/soc/pci_devs.h b/src/soc/intel/skylake/include/soc/pci_devs.h index 5ce2136a8c..2dba3dec20 100644 --- a/src/soc/intel/skylake/include/soc/pci_devs.h +++ b/src/soc/intel/skylake/include/soc/pci_devs.h @@ -127,6 +127,7 @@ #define PCH_DEV_SLOT_LPC 0x1f #define PCH_DEVFN_LPC _PCH_DEVFN(LPC, 0) +#define PCH_DEVFN_P2SB _PCH_DEVFN(LPC, 1) #define PCH_DEVFN_PMC _PCH_DEVFN(LPC, 2) #define PCH_DEVFN_HDA _PCH_DEVFN(LPC, 3) #define PCH_DEVFN_SMBUS _PCH_DEVFN(LPC, 4) @@ -134,6 +135,7 @@ #define PCH_DEVFN_GBE _PCH_DEVFN(LPC, 6) #define PCH_DEVFN_TRACEHUB _PCH_DEVFN(LPC, 7) #define PCH_DEV_LPC _PCH_DEV(LPC, 0) +#define PCH_DEV_P2SB _PCH_DEV(LPC, 1) #define PCH_DEV_PMC _PCH_DEV(LPC, 2) #define PCH_DEV_HDA _PCH_DEV(LPC, 3) #define PCH_DEV_SMBUS _PCH_DEV(LPC, 4) diff --git a/src/soc/intel/skylake/include/soc/pcr.h b/src/soc/intel/skylake/include/soc/pcr.h index cb64af6578..8a46cd1e5e 100644 --- a/src/soc/intel/skylake/include/soc/pcr.h +++ b/src/soc/intel/skylake/include/soc/pcr.h @@ -83,6 +83,7 @@ #define PID_GPIOCOM2 0xAD #define PID_GPIOCOM1 0xAE #define PID_GPIOCOM0 0xAF +#define PID_PSF1 0xBA #define PID_SCS 0xC0 #define PID_RTC 0xC3 #define PID_ITSS 0xC4 @@ -90,6 +91,11 @@ #define PID_SERIALIO 0xCB #define PID_DMI 0xEF +#define PCH_PCR_PSFX_T0_SHDW_PCIEN 0x1C + +#define PCH_PCR_PSFX_T0_SHDW_PCIEN_FUNDIS (1 << 8) +#define PSF_BASE_ADDRESS 0xA00 + #if !defined(__ASSEMBLER__) && !defined(__ACPI__) #include <stdint.h> |