aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/skylake/chip.c12
-rw-r--r--src/soc/intel/skylake/chip.h5
-rw-r--r--src/soc/intel/skylake/finalize.c55
-rw-r--r--src/soc/intel/skylake/include/soc/pci_devs.h2
-rw-r--r--src/soc/intel/skylake/include/soc/pcr.h6
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>