diff options
-rw-r--r-- | src/soc/intel/elkhartlake/Kconfig | 38 | ||||
-rw-r--r-- | src/soc/intel/elkhartlake/Makefile.inc | 13 | ||||
-rw-r--r-- | src/soc/intel/elkhartlake/chip.h | 52 | ||||
-rw-r--r-- | src/soc/intel/elkhartlake/fsp_params.c | 69 | ||||
-rw-r--r-- | src/soc/intel/elkhartlake/romstage/fsp_params.c | 2 |
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) |