Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/85316?usp=email )
Change subject: soc/intel/xeon_sp: Add PCU PCI drivers ......................................................................
soc/intel/xeon_sp: Add PCU PCI drivers
Move PCU specific code into separate files: - PCUs registers are now locked by the PCI driver final call - set_bios_init_completion() is not part of PCU1 driver - Integrate config_reset_cpl3_csrs() into PCU driver
TEST: Still boots on ocp/tiogapass.
Change-Id: Ib4a58b80a1c9fd766946b17c11c629a9df79c573 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/soc/intel/xeon_sp/Kconfig M src/soc/intel/xeon_sp/Makefile.mk M src/soc/intel/xeon_sp/cpx/chip.c M src/soc/intel/xeon_sp/gnr/Kconfig M src/soc/intel/xeon_sp/include/soc/util.h A src/soc/intel/xeon_sp/pcu0.c A src/soc/intel/xeon_sp/pcu1.c A src/soc/intel/xeon_sp/pcu2.c A src/soc/intel/xeon_sp/pcu3.c A src/soc/intel/xeon_sp/pcu6.c M src/soc/intel/xeon_sp/skx/chip.c M src/soc/intel/xeon_sp/skx/cpu.c M src/soc/intel/xeon_sp/skx/include/soc/soc_util.h M src/soc/intel/xeon_sp/skx/soc_util.c M src/soc/intel/xeon_sp/spr/Kconfig M src/soc/intel/xeon_sp/spr/chip.c M src/soc/intel/xeon_sp/util.c 17 files changed, 335 insertions(+), 257 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/16/85316/1
diff --git a/src/soc/intel/xeon_sp/Kconfig b/src/soc/intel/xeon_sp/Kconfig index e1a4ac5..583a892 100644 --- a/src/soc/intel/xeon_sp/Kconfig +++ b/src/soc/intel/xeon_sp/Kconfig @@ -115,4 +115,7 @@ default y select SHADOW_ROM_TABLE_TO_EBDA
+config XEON_SP_HAVE_PCU6 + bool + endif ## SOC_INTEL_XEON_SP diff --git a/src/soc/intel/xeon_sp/Makefile.mk b/src/soc/intel/xeon_sp/Makefile.mk index 0fc32d8..e44f809 100644 --- a/src/soc/intel/xeon_sp/Makefile.mk +++ b/src/soc/intel/xeon_sp/Makefile.mk @@ -22,6 +22,11 @@ ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smmrelocate.c ramstage-$(CONFIG_XEON_SP_HAVE_IIO_IOAPIC) += iio_ioapic.c ramstage-y += sad.c +ramstage-y += pcu0.c +ramstage-y += pcu1.c +ramstage-y += pcu2.c +ramstage-y += pcu3.c +ramstage-$(CONFIG_XEON_SP_HAVE_PCU6) += pcu6.c
smm-y += smihandler.c pmutil.c postcar-y += spi.c diff --git a/src/soc/intel/xeon_sp/cpx/chip.c b/src/soc/intel/xeon_sp/cpx/chip.c index afa5357..80cd029 100644 --- a/src/soc/intel/xeon_sp/cpx/chip.c +++ b/src/soc/intel/xeon_sp/cpx/chip.c @@ -94,42 +94,6 @@ iio_dmi_en_masks(); }
-static void set_pcu_locks(void) -{ - struct device *dev = NULL; - - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR0_DEVID, dev))) { - printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev)); - pci_or_config32(dev, PCU_CR0_P_STATE_LIMITS, P_STATE_LIMITS_LOCK); - pci_or_config32(dev, PCU_CR0_PACKAGE_RAPL_LIMIT_UPR, - PKG_PWR_LIM_LOCK_UPR); - pci_or_config32(dev, PCU_CR0_TURBO_ACTIVATION_RATIO, - TURBO_ACTIVATION_RATIO_LOCK); - } - - dev = NULL; - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR1_DEVID, dev))) { - printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev)); - pci_or_config32(dev, PCU_CR1_SAPMCTL, SAPMCTL_LOCK_MASK); - } - - dev = NULL; - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR2_DEVID, dev))) { - printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev)); - pci_or_config32(dev, PCU_CR2_DRAM_PLANE_POWER_LIMIT, - PP_PWR_LIM_LOCK); - pci_or_config32(dev, PCU_CR2_DRAM_POWER_INFO_UPR, - DRAM_POWER_INFO_LOCK_UPR); - } - - dev = NULL; - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR3_DEVID, dev))) { - printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev)); - pci_or_config32(dev, PCU_CR3_CONFIG_TDP_CONTROL, TDP_LOCK); - pci_or_config32(dev, PCU_CR3_FLEX_RATIO, OC_LOCK); - } -} - static void set_imc_locks(void) { struct device *dev = 0; @@ -152,13 +116,11 @@ /* LOCK PAM */ pci_or_config32(pcidev_path_on_root(PCI_DEVFN(0, 0)), 0x80, 1 << 0);
- set_pcu_locks(); set_imc_locks(); set_upi_locks();
p2sb_hide(); iio_enable_masks(); - set_bios_init_completion(); }
static void chip_init(void *data) diff --git a/src/soc/intel/xeon_sp/gnr/Kconfig b/src/soc/intel/xeon_sp/gnr/Kconfig index 4dee961..4a6ddb2 100644 --- a/src/soc/intel/xeon_sp/gnr/Kconfig +++ b/src/soc/intel/xeon_sp/gnr/Kconfig @@ -15,6 +15,7 @@ select PLATFORM_USES_FSP2_X86_32 select HAVE_IOAT_DOMAINS select FSP_SPEC_VIOLATION_XEON_SP_HEAP_WORKAROUND + select XEON_SP_HAVE_PCU6 help Intel Granite Rapids support
diff --git a/src/soc/intel/xeon_sp/include/soc/util.h b/src/soc/intel/xeon_sp/include/soc/util.h index 8e5833a..c4ea591 100644 --- a/src/soc/intel/xeon_sp/include/soc/util.h +++ b/src/soc/intel/xeon_sp/include/soc/util.h @@ -14,7 +14,6 @@ const IIO_UDS *get_iio_uds(void); unsigned int soc_get_num_cpus(void); bool soc_cpu_is_enabled(const size_t idx); -void set_bios_init_completion(void);
bool is_memtype_non_volatile(uint16_t mem_type); bool is_memtype_reserved(uint16_t mem_type); diff --git a/src/soc/intel/xeon_sp/pcu0.c b/src/soc/intel/xeon_sp/pcu0.c new file mode 100644 index 0000000..b8cd07e --- /dev/null +++ b/src/soc/intel/xeon_sp/pcu0.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <device/pci.h> +#include <device/pci_ids.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/util.h> + +static void pcu0_init(struct device *dev) +{ +} + +static void pcu0_final(struct device *dev) +{ + printk(BIOS_INFO, "%s: locking registers\n", dev_path(dev)); + pci_or_config32(dev, PCU_CR0_P_STATE_LIMITS, P_STATE_LIMITS_LOCK); + pci_or_config32(dev, PCU_CR0_PACKAGE_RAPL_LIMIT_UPR, + PKG_PWR_LIM_LOCK_UPR); + pci_or_config32(dev, PCU_CR0_TURBO_ACTIVATION_RATIO, + TURBO_ACTIVATION_RATIO_LOCK); + + /* Set PMAX_LOCK - must be set before RESET CPL4 */ + pci_or_config32(dev, PCU_CR0_PMAX, PMAX_LOCK); +} + +static struct device_operations pcu0_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = pcu0_init, + .final = pcu0_final, +}; + +static const struct pci_driver pcu0_driver __pci_driver = { + .ops = &pcu0_ops, + .vendor = PCI_VID_INTEL, + .device = PCU_CR0_DEVID, +}; diff --git a/src/soc/intel/xeon_sp/pcu1.c b/src/soc/intel/xeon_sp/pcu1.c new file mode 100644 index 0000000..e82673a --- /dev/null +++ b/src/soc/intel/xeon_sp/pcu1.c @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <bootstate.h> +#include <delay.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <soc/acpi.h> +#include <soc/chip_common.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/util.h> +#include <timer.h> + +/* return true if command timed out else false */ +static bool wait_for_bios_cmd_cpl(struct device *pcu1, uint32_t reg, uint32_t mask, + uint32_t target) +{ + const uint32_t max_delay = 5000; /* 5 seconds max */ + const uint32_t step_delay = 50; /* 50 us */ + struct stopwatch sw; + + stopwatch_init_msecs_expire(&sw, max_delay); + while ((pci_read_config32(pcu1, reg) & mask) != target) { + udelay(step_delay); + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "%s timed out for dev: %s, reg: 0x%x, " + "mask: 0x%x, target: 0x%x\n", + __func__, dev_path(pcu1), reg, mask, target); + return true; /* timedout */ + } + } + return false; /* successful */ +} + +/* return true if command timed out else false */ +static bool write_bios_mailbox_cmd(struct device *pcu1, uint32_t command, uint32_t data) +{ + /* verify bios is not in busy state */ + if (wait_for_bios_cmd_cpl(pcu1, PCU_CR1_BIOS_MB_INTERFACE_REG, BIOS_MB_RUN_BUSY_MASK, 0)) + return true; /* timed out */ + + /* write data to data register */ + printk(BIOS_SPEW, "%s - pci_write_config32 reg: 0x%x, data: 0x%x\n", __func__, + PCU_CR1_BIOS_MB_DATA_REG, data); + + pci_write_config32(pcu1, PCU_CR1_BIOS_MB_DATA_REG, data); + + /* write the command */ + printk(BIOS_SPEW, "%s - pci_write_config32 reg: 0x%x, data: 0x%lx\n", __func__, + PCU_CR1_BIOS_MB_INTERFACE_REG, command | BIOS_MB_RUN_BUSY_MASK); + + pci_write_config32(pcu1, PCU_CR1_BIOS_MB_INTERFACE_REG, + command | BIOS_MB_RUN_BUSY_MASK); + + /* wait for completion or time out*/ + return wait_for_bios_cmd_cpl(pcu1, PCU_CR1_BIOS_MB_INTERFACE_REG, + BIOS_MB_RUN_BUSY_MASK, 0); +} + +/* return true if command timed out else false */ +static bool set_bios_reset_cpl_for_package(struct device *pcu1, + uint32_t rst_cpl_mask, + uint32_t pcode_init_mask, + uint32_t val) +{ + /* update BIOS RESET completion bit */ + pci_update_config32(pcu1, PCU_CR1_BIOS_RESET_CPL_REG, ~rst_cpl_mask, val); + + /* wait for PCU ack */ + return wait_for_bios_cmd_cpl(pcu1, PCU_CR1_BIOS_RESET_CPL_REG, + pcode_init_mask, pcode_init_mask); +} + +static void set_bios_init_completion_for_package(uint32_t socket) +{ + struct device *pcu1 = dev_find_device_on_socket(socket, PCI_VID_INTEL, PCU_CR1_DEVID); + bool timedout; + + if (!pcu1) + die("Failed to locate PCU PCI device\n"); + + /* update RST_CPL3, PCODE_INIT_DONE3 */ + timedout = set_bios_reset_cpl_for_package(pcu1, RST_CPL3_MASK, + PCODE_INIT_DONE3_MASK, RST_CPL3_MASK); + if (timedout) + die("BIOS RESET CPL3 timed out.\n"); + + /* update RST_CPL4, PCODE_INIT_DONE4 */ + timedout = set_bios_reset_cpl_for_package(pcu1, RST_CPL4_MASK, + PCODE_INIT_DONE4_MASK, RST_CPL4_MASK); + if (timedout) + die("BIOS RESET CPL4 timed out.\n"); +} + +static void set_bios_init_completion(void *unused) +{ + uint32_t sbsp_socket_id = 0; + + if (CONFIG(SOC_INTEL_GRANITERAPIDS)) + return; + + /* + * According to the BIOS Writer's Guide, the SBSP must be the last socket + * to receive the BIOS init completion message. So, we send it to all non-SBSP + * sockets first. + */ + for (uint32_t socket = 0; socket < CONFIG_MAX_SOCKET; ++socket) { + if (!soc_cpu_is_enabled(socket)) + continue; + if (socket == sbsp_socket_id) + continue; + set_bios_init_completion_for_package(socket); + } + + /* And finally, take care of the SBSP */ + set_bios_init_completion_for_package(sbsp_socket_id); +} + +/* Set BIOS INIT completion after locking registers */ +BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY, set_bios_init_completion, NULL); +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, set_bios_init_completion, NULL); + +static void pcu1_init(struct device *dev) +{ + u32 data; + bool timedout; + + printk(BIOS_INFO, "%s: init registers\n", dev_path(dev)); + + /* Make sure to issue BIOS_CMD_WRITE_PCU_MISC_CFG at least once */ + timedout = write_bios_mailbox_cmd(dev, BIOS_CMD_READ_PCU_MISC_CFG, 0); + if (timedout) { + /* 2nd try */ + timedout = write_bios_mailbox_cmd(dev, BIOS_CMD_READ_PCU_MISC_CFG, 0); + if (timedout) + die("BIOS PCU Misc Config Read timed out.\n"); + } + + data = pci_read_config32(dev, PCU_CR1_BIOS_MB_DATA_REG); + printk(BIOS_SPEW, "%s - pci_read_config32 reg: 0x%x, data: 0x%x\n", + __func__, PCU_CR1_BIOS_MB_DATA_REG, data); + + timedout = write_bios_mailbox_cmd(dev, BIOS_CMD_WRITE_PCU_MISC_CFG, data); + if (timedout) + die("BIOS PCU Misc Config Write timed out.\n"); + + if (CONFIG(SOC_INTEL_SKYLAKE_SP)) { + /* clear bits 27:31 - FSP sets this with 0x7 which needs to be cleared */ + pci_and_config32(dev, PCU_CR1_SAPMCTL, 0xfffffff); + } +} + +static void pcu1_final(struct device *dev) +{ + printk(BIOS_INFO, "%s: locking registers\n", dev_path(dev)); + pci_or_config32(dev, PCU_CR1_SAPMCTL, SAPMCTL_LOCK_MASK); + pci_or_config32(dev, PCU_CR1_DESIRED_CORES_CFG2_REG, + PCU_CR1_DESIRED_CORES_CFG2_REG_LOCK_MASK); +} + +static struct device_operations pcu1_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = pcu1_init, + .final = pcu1_final, +}; + +static const struct pci_driver pcu1_driver __pci_driver = { + .ops = &pcu1_ops, + .vendor = PCI_VID_INTEL, + .device = PCU_CR1_DEVID, +}; diff --git a/src/soc/intel/xeon_sp/pcu2.c b/src/soc/intel/xeon_sp/pcu2.c new file mode 100644 index 0000000..4a48e91 --- /dev/null +++ b/src/soc/intel/xeon_sp/pcu2.c @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <device/pci.h> +#include <device/pci_ids.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/util.h> + +static void pcu2_init(struct device *dev) +{ + printk(BIOS_INFO, "%s: init registers\n", dev_path(dev)); + + if (CONFIG(SOC_INTEL_SKYLAKE_SP)) { + pci_or_config32(dev, PCU_CR2_PKG_CST_ENTRY_CRITERIA_MASK, 0xFFFFFF); + pci_or_config32(dev, PCU_CR2_PKG_CST_ENTRY_CRITERIA_MASK2, 7); + + pci_write_config32(dev, PCU_CR2_PROCHOT_RESPONSE_RATIO_REG, + PROCHOT_RATIO); + dump_csr(dev, PCU_CR2_PROCHOT_RESPONSE_RATIO_REG); + + pci_or_config32(dev, PCU_CR2_DYNAMIC_PERF_POWER_CTL, + UNOCRE_PLIMIT_OVERRIDE_SHIFT); + } +} + +static void pcu2_final(struct device *dev) +{ + printk(BIOS_INFO, "%s: locking registers\n", dev_path(dev)); + pci_or_config32(dev, PCU_CR2_DRAM_PLANE_POWER_LIMIT, + PP_PWR_LIM_LOCK); + pci_or_config32(dev, PCU_CR2_DRAM_POWER_INFO_UPR, + DRAM_POWER_INFO_LOCK_UPR); +} + +static struct device_operations pcu2_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = pcu2_init, + .final = pcu2_final, +}; + +static const struct pci_driver pcu2_driver __pci_driver = { + .ops = &pcu2_ops, + .vendor = PCI_VID_INTEL, + .device = PCU_CR2_DEVID, +}; diff --git a/src/soc/intel/xeon_sp/pcu3.c b/src/soc/intel/xeon_sp/pcu3.c new file mode 100644 index 0000000..6834ec5 --- /dev/null +++ b/src/soc/intel/xeon_sp/pcu3.c @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <device/pci.h> +#include <device/pci_ids.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/util.h> + +static void pcu3_init(struct device *dev) +{ +} + +static void pcu3_final(struct device *dev) +{ + printk(BIOS_INFO, "%s: locking registers\n", dev_path(dev)); + pci_or_config32(dev, PCU_CR3_CONFIG_TDP_CONTROL, TDP_LOCK); + pci_or_config32(dev, PCU_CR3_FLEX_RATIO, OC_LOCK); +} + +static struct device_operations pcu3_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = pcu3_init, + .final = pcu3_final, +}; + +static const struct pci_driver pcu3_driver __pci_driver = { + .ops = &pcu3_ops, + .vendor = PCI_VID_INTEL, + .device = PCU_CR3_DEVID, +}; diff --git a/src/soc/intel/xeon_sp/pcu6.c b/src/soc/intel/xeon_sp/pcu6.c new file mode 100644 index 0000000..e227c40 --- /dev/null +++ b/src/soc/intel/xeon_sp/pcu6.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include <device/pci.h> +#include <device/pci_ids.h> +#include <soc/pci_devs.h> +#include <soc/ramstage.h> +#include <soc/util.h> + +static void pcu6_init(struct device *dev) +{ +} + +static void pcu6_final(struct device *dev) +{ + printk(BIOS_INFO, "%s: locking registers\n", dev_path(dev)); + pci_or_config32(dev, PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_UPR, + PLT_PWR_LIM_LOCK_UPR); + pci_or_config32(dev, PCU_CR6_PLATFORM_POWER_INFO_CFG_UPR, + PLT_PWR_INFO_LOCK_UPR); +} + +static struct device_operations pcu6_ops = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = pcu6_init, + .final = pcu6_final, +}; + +static const struct pci_driver pcu6_driver __pci_driver = { + .ops = &pcu6_ops, + .vendor = PCI_VID_INTEL, + .device = PCU_CR6_DEVID, +}; diff --git a/src/soc/intel/xeon_sp/skx/chip.c b/src/soc/intel/xeon_sp/skx/chip.c index 50a3ee3..2f05cfb 100644 --- a/src/soc/intel/xeon_sp/skx/chip.c +++ b/src/soc/intel/xeon_sp/skx/chip.c @@ -38,42 +38,6 @@ } }
-static void set_pcu_locks(void) -{ - struct device *dev = NULL; - - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR0_DEVID, dev))) { - printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev)); - pci_or_config32(dev, PCU_CR0_P_STATE_LIMITS, P_STATE_LIMITS_LOCK); - pci_or_config32(dev, PCU_CR0_PACKAGE_RAPL_LIMIT_UPR, - PKG_PWR_LIM_LOCK_UPR); - pci_or_config32(dev, PCU_CR0_TURBO_ACTIVATION_RATIO, - TURBO_ACTIVATION_RATIO_LOCK); - } - - dev = NULL; - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR1_DEVID, dev))) { - printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev)); - pci_or_config32(dev, PCU_CR1_SAPMCTL, SAPMCTL_LOCK_MASK); - } - - dev = NULL; - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR2_DEVID, dev))) { - printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev)); - pci_or_config32(dev, PCU_CR2_DRAM_PLANE_POWER_LIMIT, - PP_PWR_LIM_LOCK); - pci_or_config32(dev, PCU_CR2_DRAM_POWER_INFO_UPR, - DRAM_POWER_INFO_LOCK_UPR); - } - - dev = NULL; - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR3_DEVID, dev))) { - printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev)); - pci_or_config32(dev, PCU_CR3_CONFIG_TDP_CONTROL, TDP_LOCK); - pci_or_config32(dev, PCU_CR3_FLEX_RATIO, OC_LOCK); - } -} - static void set_imc_locks(void) { struct device *dev = 0; @@ -92,11 +56,8 @@ { // Temp Fix - should be done by FSP, in 2S bios completion // is not carried out on socket 2 - set_pcu_locks(); set_imc_locks(); set_upi_locks(); - - set_bios_init_completion(); }
static void soc_init(void *data) diff --git a/src/soc/intel/xeon_sp/skx/cpu.c b/src/soc/intel/xeon_sp/skx/cpu.c index 36dc63b..1becda8 100644 --- a/src/soc/intel/xeon_sp/skx/cpu.c +++ b/src/soc/intel/xeon_sp/skx/cpu.c @@ -293,8 +293,6 @@ */ chip_config = bus->dev->chip_info;
- config_reset_cpl3_csrs(); - /* calls src/cpu/x86/mp_init.c */ /* TODO: Handle mp_init_with_smm failure? */ mp_init_with_smm(bus, &mp_ops); diff --git a/src/soc/intel/xeon_sp/skx/include/soc/soc_util.h b/src/soc/intel/xeon_sp/skx/include/soc/soc_util.h index ce7c645..f0e1761 100644 --- a/src/soc/intel/xeon_sp/skx/include/soc/soc_util.h +++ b/src/soc/intel/xeon_sp/skx/include/soc/soc_util.h @@ -9,8 +9,6 @@ #define xSTACK_RES STACK_RES #define xIIO_RESOURCE_INSTANCE IIO_RESOURCE_INSTANCE
-void config_reset_cpl3_csrs(void); - const struct SystemMemoryMapHob *get_system_memory_map(void);
uint8_t get_cxl_node_count(void); diff --git a/src/soc/intel/xeon_sp/skx/soc_util.c b/src/soc/intel/xeon_sp/skx/soc_util.c index 387b566..5a035f5 100644 --- a/src/soc/intel/xeon_sp/skx/soc_util.c +++ b/src/soc/intel/xeon_sp/skx/soc_util.c @@ -83,42 +83,6 @@ return false; }
-#if ENV_RAMSTAGE -void config_reset_cpl3_csrs(void) -{ - uint32_t data; - struct device *dev; - - // FIXME: Looks like this needs to run after FSP-S since it modifies FSP defaults! - - dev = NULL; - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR1_DEVID, dev))) { - data = pci_read_config32(dev, PCU_CR1_SAPMCTL); - /* clear bits 27:31 - FSP sets this with 0x7 which needs to be cleared */ - data &= 0x0fffffff; - pci_write_config32(dev, PCU_CR1_SAPMCTL, data); - } - - dev = NULL; - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR2_DEVID, dev))) { - data = PCIE_IN_PKGCSTATE_L1_MASK; - pci_write_config32(dev, PCU_CR2_PKG_CST_ENTRY_CRITERIA_MASK, data); - - data = KTI_IN_PKGCSTATE_L1_MASK; - pci_write_config32(dev, PCU_CR2_PKG_CST_ENTRY_CRITERIA_MASK2, data); - - data = PROCHOT_RATIO; - printk(BIOS_SPEW, "PCU_CR2_PROCHOT_RESPONSE_RATIO_REG data: 0x%x\n", data); - pci_write_config32(dev, PCU_CR2_PROCHOT_RESPONSE_RATIO_REG, data); - dump_csr(dev, PCU_CR2_PROCHOT_RESPONSE_RATIO_REG); - - data = pci_read_config32(dev, PCU_CR2_DYNAMIC_PERF_POWER_CTL); - data |= UNOCRE_PLIMIT_OVERRIDE_SHIFT; - pci_write_config32(dev, PCU_CR2_DYNAMIC_PERF_POWER_CTL, data); - } -} -#endif - bool is_memtype_reserved(uint16_t mem_type) { return !!(mem_type & MEM_TYPE_RESERVED); diff --git a/src/soc/intel/xeon_sp/spr/Kconfig b/src/soc/intel/xeon_sp/spr/Kconfig index d6c9832..e8e1b29 100644 --- a/src/soc/intel/xeon_sp/spr/Kconfig +++ b/src/soc/intel/xeon_sp/spr/Kconfig @@ -16,6 +16,7 @@ select UDK_202005_BINDING select SOC_INTEL_HAS_CXL select HAVE_X86_64_SUPPORT + select XEON_SP_HAVE_PCU6 help Intel Sapphire Rapids-SP support
diff --git a/src/soc/intel/xeon_sp/spr/chip.c b/src/soc/intel/xeon_sp/spr/chip.c index e179df0..0766e8c 100644 --- a/src/soc/intel/xeon_sp/spr/chip.c +++ b/src/soc/intel/xeon_sp/spr/chip.c @@ -116,8 +116,6 @@ lock_oc_cfg(true); /* Disable CPU Crashlog to avoid conflict between CPU Crashlog and BMC ACD. */ disable_cpu_crashlog(); - - set_bios_init_completion(); }
static void chip_init(void *data) diff --git a/src/soc/intel/xeon_sp/util.c b/src/soc/intel/xeon_sp/util.c index 69f3c15..d04782c 100644 --- a/src/soc/intel/xeon_sp/util.c +++ b/src/soc/intel/xeon_sp/util.c @@ -119,140 +119,4 @@ return bdf; } return p2sb_get_ioapic_bdf(); -} - -#if ENV_RAMSTAGE /* Setting devtree variables is only allowed in ramstage. */ - -/* return true if command timed out else false */ -static bool wait_for_bios_cmd_cpl(struct device *pcu1, uint32_t reg, uint32_t mask, - uint32_t target) -{ - const uint32_t max_delay = 5000; /* 5 seconds max */ - const uint32_t step_delay = 50; /* 50 us */ - struct stopwatch sw; - - stopwatch_init_msecs_expire(&sw, max_delay); - while ((pci_read_config32(pcu1, reg) & mask) != target) { - udelay(step_delay); - if (stopwatch_expired(&sw)) { - printk(BIOS_ERR, "%s timed out for dev: %s, reg: 0x%x, " - "mask: 0x%x, target: 0x%x\n", - __func__, dev_path(pcu1), reg, mask, target); - return true; /* timedout */ - } - } - return false; /* successful */ -} - -/* return true if command timed out else false */ -static bool write_bios_mailbox_cmd(struct device *pcu1, uint32_t command, uint32_t data) -{ - /* verify bios is not in busy state */ - if (wait_for_bios_cmd_cpl(pcu1, PCU_CR1_BIOS_MB_INTERFACE_REG, BIOS_MB_RUN_BUSY_MASK, 0)) - return true; /* timed out */ - - /* write data to data register */ - printk(BIOS_SPEW, "%s - pci_write_config32 reg: 0x%x, data: 0x%x\n", __func__, - PCU_CR1_BIOS_MB_DATA_REG, data); - - pci_write_config32(pcu1, PCU_CR1_BIOS_MB_DATA_REG, data); - - /* write the command */ - printk(BIOS_SPEW, "%s - pci_write_config32 reg: 0x%x, data: 0x%lx\n", __func__, - PCU_CR1_BIOS_MB_INTERFACE_REG, command | BIOS_MB_RUN_BUSY_MASK); - - pci_write_config32(pcu1, PCU_CR1_BIOS_MB_INTERFACE_REG, - command | BIOS_MB_RUN_BUSY_MASK); - - /* wait for completion or time out*/ - return wait_for_bios_cmd_cpl(pcu1, PCU_CR1_BIOS_MB_INTERFACE_REG, - BIOS_MB_RUN_BUSY_MASK, 0); -} - -/* return true if command timed out else false */ -static bool set_bios_reset_cpl_for_package(struct device *pcu1, - uint32_t rst_cpl_mask, - uint32_t pcode_init_mask, - uint32_t val) -{ - /* update BIOS RESET completion bit */ - pci_update_config32(pcu1, PCU_CR1_BIOS_RESET_CPL_REG, ~rst_cpl_mask, val); - - /* wait for PCU ack */ - return wait_for_bios_cmd_cpl(pcu1, PCU_CR1_BIOS_RESET_CPL_REG, - pcode_init_mask, pcode_init_mask); -} - -static void set_bios_init_completion_for_package(uint32_t socket) -{ - struct device *pcu0 = dev_find_device_on_socket(socket, PCI_VID_INTEL, PCU_CR0_DEVID); - struct device *pcu1 = dev_find_device_on_socket(socket, PCI_VID_INTEL, PCU_CR1_DEVID); - uint32_t data; - bool timedout; - - if (!pcu0 || !pcu1) - die("Failed to locate PCU PCI device\n"); - - /* read PCU config */ - timedout = write_bios_mailbox_cmd(pcu1, BIOS_CMD_READ_PCU_MISC_CFG, 0); - if (timedout) { - /* 2nd try */ - timedout = write_bios_mailbox_cmd(pcu1, BIOS_CMD_READ_PCU_MISC_CFG, 0); - if (timedout) - die("BIOS PCU Misc Config Read timed out.\n"); - - /* Since the 1st try failed, we need to make sure PCU is in stable state */ - data = pci_read_config32(pcu1, PCU_CR1_BIOS_MB_DATA_REG); - printk(BIOS_SPEW, "%s - pci_read_config32 reg: 0x%x, data: 0x%x\n", - __func__, PCU_CR1_BIOS_MB_DATA_REG, data); - timedout = write_bios_mailbox_cmd(pcu1, BIOS_CMD_WRITE_PCU_MISC_CFG, data); - if (timedout) - die("BIOS PCU Misc Config Write timed out.\n"); - } - - /* update RST_CPL3, PCODE_INIT_DONE3 */ - timedout = set_bios_reset_cpl_for_package(pcu1, RST_CPL3_MASK, - PCODE_INIT_DONE3_MASK, RST_CPL3_MASK); - if (timedout) - die("BIOS RESET CPL3 timed out.\n"); - - /* Set PMAX_LOCK - must be set before RESET CPL4 */ - data = pci_read_config32(pcu0, PCU_CR0_PMAX); - data |= PMAX_LOCK; - pci_write_config32(pcu0, PCU_CR0_PMAX, data); - - /* update RST_CPL4, PCODE_INIT_DONE4 */ - timedout = set_bios_reset_cpl_for_package(pcu1, RST_CPL4_MASK, - PCODE_INIT_DONE4_MASK, RST_CPL4_MASK); - if (timedout) - die("BIOS RESET CPL4 timed out.\n"); - - /* set CSR_DESIRED_CORES_CFG2 lock bit */ - data = pci_read_config32(pcu1, PCU_CR1_DESIRED_CORES_CFG2_REG); - data |= PCU_CR1_DESIRED_CORES_CFG2_REG_LOCK_MASK; - printk(BIOS_SPEW, "%s - pci_write_config32 PCU_CR1_DESIRED_CORES_CFG2_REG 0x%x, data: 0x%x\n", - __func__, PCU_CR1_DESIRED_CORES_CFG2_REG, data); - pci_write_config32(pcu1, PCU_CR1_DESIRED_CORES_CFG2_REG, data); -} - -void set_bios_init_completion(void) -{ - uint32_t sbsp_socket_id = 0; - - /* - * According to the BIOS Writer's Guide, the SBSP must be the last socket - * to receive the BIOS init completion message. So, we send it to all non-SBSP - * sockets first. - */ - for (uint32_t socket = 0; socket < CONFIG_MAX_SOCKET; ++socket) { - if (!soc_cpu_is_enabled(socket)) - continue; - if (socket == sbsp_socket_id) - continue; - set_bios_init_completion_for_package(socket); - } - - /* And finally, take care of the SBSP */ - set_bios_init_completion_for_package(sbsp_socket_id); -} -#endif +} \ No newline at end of file