summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLean Sheng Tan <lean.sheng.tan@intel.com>2021-06-09 13:58:12 -0700
committerFelix Held <felix-coreboot@felixheld.de>2022-01-25 16:09:18 +0000
commit5cd7579ee54dbd9d424c6adc4b0228bcede95ffb (patch)
treec23c481f7980325c6653db2f3b4aeff88e321cd4 /src
parent36425312ee8a04efa7582abfe143cb887e8ece30 (diff)
soc/intel/elkhartlake: Introduce Intel PSE
The IntelĀ® Programmable Services Engine (IntelĀ® PSE) is a dedicated offload engine for IoT functions powered by an ARM Cortex-M7 microcontroller. It provides independent, low-DMIPS computing and low-speed I/Os for IoT applications, plus dedicated services for real-time computing and time-sensitive synchronization. The PSE hosts new functions, including remote out-of-band device management, network proxy, embedded controller lite and sensor hub. This CL enables the user to provide the base address of the PSE FW blob which will then be loaded by the FSP-S onto the ARM controller. PSE FW will do the initialization work of PSE controller and its peripherals. The loading of PSE FW should have negligible impact on boot time unless PSE controller could not locate the PSE FW and FSP will attempt to redo PSE FW loading and wait for PSE handshake until it times out. Once PSE controller locate the PSE FW, it will do initialization concurrently by itself with coreboot booting. It also adds PSE related FSP-S UPD settings which enable the setup of peripheral ownership (assigned to the PSE or x86 subsystem) and interrupts. These assignments need to take place at a given point in the boot process and cannot be changed later. To verify if PSE FW is loaded properly, the user could enable PchPseShellEnabled flag and the log will be printed at PSE UART 2. For further info please refer to doc #611825 (for HW overview) and #614110 (for PSE EDS). Signed-off-by: Lean Sheng Tan <lean.sheng.tan@intel.com> Change-Id: Ifea08fb82fea18ef66bab04b3ce378e79a0afbf7 Reviewed-on: https://review.coreboot.org/c/coreboot/+/55367 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Werner Zeh <werner.zeh@siemens.com>
Diffstat (limited to 'src')
-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)