summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/elkhartlake/Kconfig38
-rw-r--r--src/soc/intel/elkhartlake/Makefile.inc13
-rw-r--r--src/soc/intel/elkhartlake/chip.h52
-rw-r--r--src/soc/intel/elkhartlake/fsp_params.c69
-rw-r--r--src/soc/intel/elkhartlake/romstage/fsp_params.c2
5 files changed, 173 insertions, 1 deletions
diff --git a/src/soc/intel/elkhartlake/Kconfig b/src/soc/intel/elkhartlake/Kconfig
index fce2f903d4..37807897aa 100644
--- a/src/soc/intel/elkhartlake/Kconfig
+++ b/src/soc/intel/elkhartlake/Kconfig
@@ -194,6 +194,44 @@ config FSP_FD_PATH
depends on FSP_USE_REPO
default "3rdparty/fsp/ElkhartLakeFspBinPkg/FspBin/FSPRel.bin"
+config PSE_ENABLE
+ bool "Enable PSE ARM controller"
+ help
+ Enable PSE IP. The PSE describes the integrated programmable
+ service engine that is designed together with x86 Atom cores
+ as an Asymmetric Multi-Processing (AMP) system.
+
+config ADD_PSE_IMAGE_TO_CBFS
+ bool "Add PSE Firmware to CBFS"
+ depends on PSE_ENABLE
+ default n
+ help
+ PSE FW binary is required to use PSE dedicated peripherals from
+ x86 subsystem. Once PSE is enabled, the FW will be loaded from
+ CBFS by FSP and executed.
+
+config PSE_IMAGE_FILE
+ string "PSE binary path and filename"
+ depends on ADD_PSE_IMAGE_TO_CBFS
+ help
+ The path and filename of the PSE binary.
+
+config PSE_FW_FILE_SIZE_KIB
+ hex "Memory buffer (KiB) for PSE FW image"
+ depends on ADD_PSE_IMAGE_TO_CBFS
+ default 0x200
+ help
+ It is recommended to allocate at least 512 KiB for PSE FW.
+
+config PSE_CONFIG_BUFFER_SIZE_KIB
+ hex "Memory buffer (KiB) for PSE config data"
+ depends on ADD_PSE_IMAGE_TO_CBFS
+ default 0x100
+ help
+ It is recommended to allocate at least 256 KiB for PSE config
+ data (FSP will append PSE config data to memory region right
+ after PSE FW memory region).
+
config SOC_INTEL_ELKHARTLAKE_DEBUG_CONSENT
int "Debug Consent for EHL"
# USB DBC is more common for developers so make this default to 3 if
diff --git a/src/soc/intel/elkhartlake/Makefile.inc b/src/soc/intel/elkhartlake/Makefile.inc
index 6a5d5c7b0e..ce93e46e79 100644
--- a/src/soc/intel/elkhartlake/Makefile.inc
+++ b/src/soc/intel/elkhartlake/Makefile.inc
@@ -51,5 +51,18 @@ CPPFLAGS_common += -I$(src)/soc/intel/elkhartlake/include
# B0 stepping
cpu_microcode_bins += 3rdparty/intel-microcode/intel-ucode/06-96-01
+cbfs-files-$(CONFIG_ADD_PSE_IMAGE_TO_CBFS) += pse.bin
+pse.bin-file := $(CONFIG_PSE_IMAGE_FILE)
+pse.bin-type := raw
+pse.bin-compression := lzma
+
+# Add a build time check if the PSE file size fits
+ifeq ($(CONFIG_ADD_PSE_IMAGE_TO_CBFS),y)
+ifeq ($(call int-gt,\
+ $(call file-size,$(CONFIG_PSE_IMAGE_FILE))\
+ $(shell printf "%d" $(call int-shift-left, $(CONFIG_PSE_FW_FILE_SIZE_KIB) 10))), 1)
+$(error PSE binary larger than CONFIG_PSE_FW_FILE_SIZE_KIB.)
+endif
+endif # CONFIG_ADD_PSE_IMAGE_TO_CBFS
endif
diff --git a/src/soc/intel/elkhartlake/chip.h b/src/soc/intel/elkhartlake/chip.h
index 210e92c4b6..a4e8cadb8d 100644
--- a/src/soc/intel/elkhartlake/chip.h
+++ b/src/soc/intel/elkhartlake/chip.h
@@ -49,6 +49,18 @@ enum tsn_gbe_link_speed {
};
/*
+ * PSE native pins and ownership assignment:-
+ * 0: Disable/pins are not owned by PSE/host
+ * 1: Pins are muxed to PSE IP, the IO is owned by PSE
+ * 2: Pins are muxed to PSE IP, the IO is owned by host
+ */
+enum pse_device_ownership {
+ Device_Disabled,
+ PSE_Owned,
+ Host_Owned,
+};
+
+/*
* Enable external V1P05 Rail in: BIT0:S0i1/S0i2,
* BIT1:S0i3, BIT2:S3, BIT3:S4, BIT4:S5
* However, EHL does not support S0i1 and S0i2,
@@ -453,6 +465,46 @@ struct soc_intel_elkhartlake_config {
bool PchTsnGbeSgmiiEnable;
/* PCH TSN GBE Multiple Virtual Channel: Disable (0) / Enable (1) */
bool PchTsnGbeMultiVcEnable;
+
+ /* PSE related */
+ /*
+ * PSE (Intel Programmable Services Engine) native pins and ownership
+ * assignment. If the device is configured as 'PSE owned', PSE will have
+ * full control of specific device and it will be hidden from coreboot
+ * and OS. If the device is configured as 'Host owned', the device will
+ * be visible to coreboot and OS as a PCI device, while PSE will still
+ * do some IP initialization and pin assignment works.
+ *
+ * PSE is still required during runtime to ensure any of PSE devices
+ * works properly.
+ */
+ enum pse_device_ownership PseDmaOwn[3];
+ enum pse_device_ownership PseUartOwn[6];
+ enum pse_device_ownership PseHsuartOwn[4];
+ enum pse_device_ownership PseQepOwn[4];
+ enum pse_device_ownership PseI2cOwn[8];
+ enum pse_device_ownership PseI2sOwn[2];
+ enum pse_device_ownership PseSpiOwn[4];
+ enum pse_device_ownership PseSpiCs0Own[4];
+ enum pse_device_ownership PseSpiCs1Own[4];
+ enum pse_device_ownership PseCanOwn[2];
+ enum pse_device_ownership PsePwmOwn;
+ enum pse_device_ownership PseAdcOwn;
+ /* PSE devices sideband interrupt: Disable (0) / Enable (1) */
+ bool PseDmaSbIntEn[3];
+ bool PseUartSbIntEn[6];
+ bool PseQepSbIntEn[4];
+ bool PseI2cSbIntEn[8];
+ bool PseI2sSbIntEn[2];
+ bool PseSpiSbIntEn[4];
+ bool PseCanSbIntEn[2];
+ bool PseLh2PseSbIntEn;
+ bool PsePwmSbIntEn;
+ bool PseAdcSbIntEn;
+ /* PSE PWM native function: Disable (0) / Enable (1) */
+ bool PsePwmPinEn[16];
+ /* PSE Console Shell */
+ bool PseShellEn;
};
typedef struct soc_intel_elkhartlake_config config_t;
diff --git a/src/soc/intel/elkhartlake/fsp_params.c b/src/soc/intel/elkhartlake/fsp_params.c
index ff7222db6d..fc5ea1c873 100644
--- a/src/soc/intel/elkhartlake/fsp_params.c
+++ b/src/soc/intel/elkhartlake/fsp_params.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <assert.h>
+#include <cbfs.h>
#include <console/console.h>
#include <device/device.h>
#include <fsp/api.h>
@@ -78,6 +79,70 @@ static void fill_fsps_fivr_params(FSP_S_CONFIG *s_cfg,
s_cfg->FivrSpreadSpectrum = config->fivr.spread_spectrum;
}
+static void fill_fsps_pse_params(FSP_S_CONFIG *params,
+ const struct soc_intel_elkhartlake_config *config)
+{
+ static char psefwbuf[(CONFIG_PSE_FW_FILE_SIZE_KIB +
+ CONFIG_PSE_CONFIG_BUFFER_SIZE_KIB) * KiB];
+ uint32_t pse_fw_base;
+ size_t psefwsize = cbfs_load("pse.bin", psefwbuf, sizeof(psefwbuf));
+ if (psefwsize > 0) {
+ pse_fw_base = (uintptr_t)&psefwbuf;
+ params->SiipRegionBase = pse_fw_base;
+ params->SiipRegionSize = psefwsize;
+ printk(BIOS_DEBUG, "PSE base: %08x size: %08zx\n", pse_fw_base, psefwsize);
+
+ /* Configure PSE peripherals */
+ FSP_ARRAY_LOAD(params->PchPseDmaEnable, config->PseDmaOwn);
+ FSP_ARRAY_LOAD(params->PchPseDmaSbInterruptEnable, config->PseDmaSbIntEn);
+ FSP_ARRAY_LOAD(params->PchPseUartEnable, config->PseUartOwn);
+ FSP_ARRAY_LOAD(params->PchPseUartSbInterruptEnable, config->PseUartSbIntEn);
+ FSP_ARRAY_LOAD(params->PchPseHsuartEnable, config->PseHsuartOwn);
+ FSP_ARRAY_LOAD(params->PchPseQepEnable, config->PseQepOwn);
+ FSP_ARRAY_LOAD(params->PchPseQepSbInterruptEnable, config->PseQepSbIntEn);
+ FSP_ARRAY_LOAD(params->PchPseI2cEnable, config->PseI2cOwn);
+ FSP_ARRAY_LOAD(params->PchPseI2cSbInterruptEnable, config->PseI2cSbIntEn);
+ FSP_ARRAY_LOAD(params->PchPseI2sEnable, config->PseI2sOwn);
+ FSP_ARRAY_LOAD(params->PchPseI2sSbInterruptEnable, config->PseI2sSbIntEn);
+ FSP_ARRAY_LOAD(params->PchPseSpiEnable, config->PseSpiOwn);
+ FSP_ARRAY_LOAD(params->PchPseSpiSbInterruptEnable, config->PseSpiSbIntEn);
+ FSP_ARRAY_LOAD(params->PchPseSpiCs0Enable, config->PseSpiCs0Own);
+ FSP_ARRAY_LOAD(params->PchPseSpiCs1Enable, config->PseSpiCs1Own);
+ FSP_ARRAY_LOAD(params->PchPseCanEnable, config->PseCanOwn);
+ FSP_ARRAY_LOAD(params->PchPseCanSbInterruptEnable, config->PseCanSbIntEn);
+ params->PchPsePwmEnable = config->PsePwmOwn;
+ params->PchPsePwmSbInterruptEnable = config->PsePwmSbIntEn;
+ FSP_ARRAY_LOAD(params->PchPsePwmPinEnable, config->PsePwmPinEn);
+ params->PchPseAdcEnable = config->PseAdcOwn;
+ params->PchPseAdcSbInterruptEnable = config->PseAdcSbIntEn;
+ params->PchPseLh2PseSbInterruptEnable = config->PseLh2PseSbIntEn;
+ params->PchPseShellEnabled = config->PseShellEn;
+
+ /*
+ * As a minimum requirement for PSE initialization, the configuration
+ * of devices below are required as shown.
+ * TODO: Help needed to find a better way to handle this part of code
+ * as the settings from devicetree are overwritten here.
+ *
+ * Set the ownership of these devices to PSE. These are hardcoded for now,
+ * if the PSE should be opened one day (hopefully), this can be handled
+ * much better.
+ */
+ params->PchPseDmaEnable[0] = PSE_Owned;
+ params->PchPseUartEnable[2] = PSE_Owned;
+ params->PchPseHsuartEnable[2] = PSE_Owned;
+ params->PchPseI2cEnable[2] = PSE_Owned;
+ params->PchPseTimedGpioEnable[0] = PSE_Owned;
+ params->PchPseTimedGpioEnable[1] = PSE_Owned;
+ /* Disable PSE DMA Sideband Interrupt for DMA 0 */
+ params->PchPseDmaSbInterruptEnable[0] = 0;
+ /* Set the log output to PSE UART 2 */
+ params->PchPseLogOutputChannel = 3;
+ } else {
+ die("PSE enabled but PSE FW not available!\n");
+ }
+}
+
static void parse_devicetree(FSP_S_CONFIG *params)
{
const struct soc_intel_elkhartlake_config *config = config_of_soc();
@@ -366,6 +431,10 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
}
}
+ /* PSE (Intel Programmable Services Engine) config */
+ if (CONFIG(PSE_ENABLE) && cbfs_file_exists("pse.bin"))
+ fill_fsps_pse_params(params, config);
+
/* Override/Fill FSP Silicon Param for mainboard */
mainboard_silicon_init_params(params);
}
diff --git a/src/soc/intel/elkhartlake/romstage/fsp_params.c b/src/soc/intel/elkhartlake/romstage/fsp_params.c
index 402b1342e6..b8aaca78db 100644
--- a/src/soc/intel/elkhartlake/romstage/fsp_params.c
+++ b/src/soc/intel/elkhartlake/romstage/fsp_params.c
@@ -123,7 +123,7 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg,
}
}
/* PSE (Intel Programmable Services Engine) switch */
- m_cfg->PchPseEnable = 0;
+ m_cfg->PchPseEnable = CONFIG(PSE_ENABLE) && cbfs_file_exists("pse.bin");
}
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)