diff --git a/src/soc/intel/xeon_sp/cpx/Makefile.mk b/src/soc/intel/xeon_sp/cpx/Makefile.mk index b54b0ef3ba..c6639a2044 100644 --- a/src/soc/intel/xeon_sp/cpx/Makefile.mk +++ b/src/soc/intel/xeon_sp/cpx/Makefile.mk @@ -13,7 +13,10 @@ ramstage-y += chip.c cpu.c soc_util.c soc_acpi.c ramstage-y += ../chip_gen1.c ../lpc_gen1.c ramstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c - +ramstage-y += ../pcu0.c +ramstage-y += ../pcu1.c +ramstage-y += ../pcu2.c +ramstage-y += ../pcu3.c CPPFLAGS_common += -I$(src)/soc/intel/xeon_sp/cpx/include -I$(src)/soc/intel/xeon_sp/cpx CPPFLAGS_common += -I$(src)/vendorcode/intel/fsp/fsp2_0/cooperlake_sp diff --git a/src/soc/intel/xeon_sp/cpx/chip.c b/src/soc/intel/xeon_sp/cpx/chip.c index afa5357abb..80cd029d97 100644 --- a/src/soc/intel/xeon_sp/cpx/chip.c +++ b/src/soc/intel/xeon_sp/cpx/chip.c @@ -94,42 +94,6 @@ static void iio_enable_masks(void) 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 @@ static void chip_final(void *data) /* 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/cpx/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h index 0fc473eb71..808a0db266 100644 --- a/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h +++ b/src/soc/intel/xeon_sp/cpx/include/soc/pci_devs.h @@ -15,73 +15,11 @@ #define SAD_ALL_PAM456_CSR 0x44 #define SAD_ALL_DEVID 0x344f -#if !defined(__SIMPLE_DEVICE__) -#define _PCU_DEV(bus, func) pcidev_path_on_bus(bus, PCI_DEVFN(PCU_DEV, func)) -#else -#define _PCU_DEV(bus, func) PCI_DEV(bus, PCU_DEV, func) -#endif - #define PCU_IIO_STACK 1 -#define PCU_DEV 30 - -#define PCU_CR0_FUN 0 #define PCU_CR0_DEVID 0x2080 -#define PCU_DEV_CR0(bus) _PCU_DEV(bus, PCU_CR0_FUN) -#define PCU_CR0_PLATFORM_INFO 0xa8 -#define PCU_CR0_TURBO_ACTIVATION_RATIO 0xb0 -#define TURBO_ACTIVATION_RATIO_LOCK BIT(31) -#define PCU_CR0_P_STATE_LIMITS 0xd8 -#define P_STATE_LIMITS_LOCK BIT(31) -#define PCU_CR0_PACKAGE_RAPL_LIMIT_LWR 0xe8 -#define PCU_CR0_PACKAGE_RAPL_LIMIT_UPR (PCU_CR0_PACKAGE_RAPL_LIMIT_LWR + 4) -#define PKG_PWR_LIM_LOCK_UPR BIT(31) -#define PCU_CR0_PMAX 0xf0 -#define PMAX_LOCK BIT(31) - -#define PCU_CR1_FUN 1 #define PCU_CR1_DEVID 0x2081 -#define PCU_DEV_CR1(bus) _PCU_DEV(bus, PCU_CR1_FUN) -#define PCU_CR1_BIOS_MB_DATA_REG 0x8c - -#define PCU_CR1_BIOS_MB_INTERFACE_REG 0x90 -#define BIOS_MB_RUN_BUSY_MASK BIT(31) -#define BIOS_MB_CMD_MASK 0xff -#define BIOS_CMD_READ_PCU_MISC_CFG 0x5 -#define BIOS_CMD_WRITE_PCU_MISC_CFG 0x6 -#define BIOS_ERR_INVALID_CMD 0x01 - -#define PCU_CR1_BIOS_RESET_CPL_REG 0x94 -#define RST_CPL1_MASK BIT(1) -#define RST_CPL2_MASK BIT(2) -#define RST_CPL3_MASK BIT(3) -#define RST_CPL4_MASK BIT(4) -#define PCODE_INIT_DONE1_MASK BIT(9) -#define PCODE_INIT_DONE2_MASK BIT(10) -#define PCODE_INIT_DONE3_MASK BIT(11) -#define PCODE_INIT_DONE4_MASK BIT(12) - -#define PCU_CR1_DESIRED_CORES_CFG2_REG 0xa0 -#define PCU_CR1_DESIRED_CORES_CFG2_REG_LOCK_MASK BIT(31) - -#define PCU_CR1_SAPMCTL 0xb0 -#define SAPMCTL_LOCK_MASK BIT(31) - -#define PCU_CR2_FUN 2 #define PCU_CR2_DEVID 0x2082 -#define PCU_DEV_CR2(bus) _PCU_DEV(bus, PCU_CR2_FUN) -#define PCU_CR2_DRAM_POWER_INFO_LWR 0xa8 -#define PCU_CR2_DRAM_POWER_INFO_UPR (PCU_CR2_DRAM_POWER_INFO_LWR + 4) -#define DRAM_POWER_INFO_LOCK_UPR BIT(31) -#define PCU_CR2_DRAM_PLANE_POWER_LIMIT 0xf0 -#define PP_PWR_LIM_LOCK BIT(31) - -#define PCU_CR3_FUN 3 #define PCU_CR3_DEVID 0x2083 -#define PCU_DEV_CR3(bus) _PCU_DEV(bus, PCU_CR3_FUN) -#define PCU_CR3_CONFIG_TDP_CONTROL 0x60 -#define TDP_LOCK BIT(31) -#define PCU_CR3_FLEX_RATIO 0xa0 -#define OC_LOCK BIT(20) #if !defined(__SIMPLE_DEVICE__) #define _UBOX_DEV(func) pcidev_path_on_root_debug(PCI_DEVFN(UBOX_DEV, func), __func__) diff --git a/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h index fab090a3a7..bddca8a111 100644 --- a/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h +++ b/src/soc/intel/xeon_sp/gnr/include/soc/pci_devs.h @@ -41,95 +41,17 @@ #define SAD_ALL_PAM456_CSR 0x84 #define SAD_ALL_DEVID 0x344f -#if !defined(__SIMPLE_DEVICE__) -#define _PCU_DEV(bus, func) pcidev_path_on_bus(bus, PCI_DEVFN(PCU_DEV, func)) -#else -#define _PCU_DEV(bus, func) PCI_DEV(bus, PCU_DEV, func) -#endif - -/* PCU [B:31, D:30, F:0->F:6] */ -#define PCU_IIO_STACK UNCORE_BUS_1 -#define PCU_DEV 30 - -#define PCU_CR0_FUN 0 +/* PCU [B:31, D:30, F:0] */ +#define PCU_IIO_STACK 1 #define PCU_CR0_DEVID 0x3258 -#define PCU_DEV_CR0(bus) _PCU_DEV(bus, PCU_CR0_FUN) -#define PCU_CR0_PLATFORM_INFO 0xa8 -#define PCU_CR0_TURBO_ACTIVATION_RATIO 0xb0 -#define TURBO_ACTIVATION_RATIO_LOCK BIT(31) -#define PCU_CR0_P_STATE_LIMITS 0xd8 -#define P_STATE_LIMITS_LOCK BIT(31) -#define PCU_CR0_PACKAGE_RAPL_LIMIT_LWR 0xe8 -#define PCU_CR0_PACKAGE_RAPL_LIMIT_UPR (PCU_CR0_PACKAGE_RAPL_LIMIT_LWR + 4) -#define PKG_PWR_LIM_LOCK_UPR BIT(31) -#define PCU_CR0_PMAX 0xf0 -#define PMAX_LOCK BIT(31) -#define PCU_CR0_VR_CURRENT_CONFIG_CFG 0xf8 -#define VR_CURRENT_CONFIG_LOCK BIT(31) - -#define PCU_CR1_FUN 1 +/* PCU [B:31, D:30, F:1] */ #define PCU_CR1_DEVID 0x3259 -#define PCU_DEV_CR1(bus) _PCU_DEV(bus, PCU_CR1_FUN) -#define PCU_CR1_BIOS_MB_DATA_REG 0x8c - -#define PCU_CR1_BIOS_MB_INTERFACE_REG 0x90 -#define BIOS_MB_RUN_BUSY_MASK BIT(31) -#define BIOS_MB_CMD_MASK 0xff -#define BIOS_CMD_READ_PCU_MISC_CFG 0x5 -#define BIOS_CMD_WRITE_PCU_MISC_CFG 0x6 -#define BIOS_ERR_INVALID_CMD 0x01 - -#define PCU_CR1_BIOS_RESET_CPL_REG 0x94 -#define RST_CPL1_MASK BIT(1) -#define RST_CPL2_MASK BIT(2) -#define RST_CPL3_MASK BIT(3) -#define RST_CPL4_MASK BIT(4) -#define PCODE_INIT_DONE1_MASK BIT(9) -#define PCODE_INIT_DONE2_MASK BIT(10) -#define PCODE_INIT_DONE3_MASK BIT(11) -#define PCODE_INIT_DONE4_MASK BIT(12) - -#define PCU_CR1_DESIRED_CORES_CFG2_REG 0xbc -#define PCU_CR1_DESIRED_CORES_CFG2_REG_LOCK_MASK BIT(31) - -#define PCU_CR2_FUN 2 +/* PCU [B:31, D:30, F:2] */ #define PCU_CR2_DEVID 0x325a -#define PCU_DEV_CR2(bus) _PCU_DEV(bus, PCU_CR2_FUN) -#define PCU_CR2_DRAM_POWER_INFO_LWR 0xa8 -#define PCU_CR2_DRAM_POWER_INFO_UPR (PCU_CR2_DRAM_POWER_INFO_LWR + 4) -#define DRAM_POWER_INFO_LOCK_UPR BIT(31) - -#define PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR 0xf0 -#define PCU_CR2_DRAM_PLANE_POWER_LIMIT_UPR (PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR + 4) -#define PP_PWR_LIM_LOCK_UPR BIT(31) - -#define PCU_CR3_FUN 3 +/* PCU [B:31, D:30, F:3] */ #define PCU_CR3_DEVID 0x325b -#define PCU_CR3_CAPID4 0x94 -#define ERR_SPOOFING_DIS 1 -#define PCU_DEV_CR3(bus) _PCU_DEV(bus, PCU_CR3_FUN) -#define PCU_CR3_CONFIG_TDP_CONTROL 0xd8 -#define TDP_LOCK BIT(31) -#define PCU_CR3_FLEX_RATIO 0xa0 -#define OC_LOCK BIT(20) - -#define PCU_CR4_FUN 4 -#define PCU_CR4_DEVID 0x325c -#define PCU_VIRAL_CONTROL 0x84 -#define PCU_FW_ERR_EN (1 << 10) -#define PCU_UC_ERR_EN (1 << 9) -#define PCU_HW_ERR_EN (1 << 8) -#define PCU_EMCA_MODE (1 << 2) - -#define PCU_CR6_FUN 6 +/* PCU [B:31, D:30, F:6] */ #define PCU_CR6_DEVID 0x325e -#define PCU_DEV_CR6(bus) _PCU_DEV(bus, PCU_CR6_FUN) -#define PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_LWR 0xa8 -#define PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_UPR (PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_LWR + 4) -#define PLT_PWR_LIM_LOCK_UPR BIT(31) -#define PCU_CR6_PLATFORM_POWER_INFO_CFG_LWR 0xb0 -#define PCU_CR6_PLATFORM_POWER_INFO_CFG_UPR (PCU_CR6_PLATFORM_POWER_INFO_CFG_LWR + 4) -#define PLT_PWR_INFO_LOCK_UPR BIT(31) /* Memory Map/VTD Device Functions * These are available in each IIO stack diff --git a/src/soc/intel/xeon_sp/include/soc/pcu.h b/src/soc/intel/xeon_sp/include/soc/pcu.h new file mode 100644 index 0000000000..f6e024bf38 --- /dev/null +++ b/src/soc/intel/xeon_sp/include/soc/pcu.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _SOC_PCU_H_ +#define _SOC_PCU_H_ + +#if !defined(__SIMPLE_DEVICE__) +#define _PCU_DEV(bus, func) pcidev_path_on_bus(bus, PCI_DEVFN(PCU_DEV, func)) +#else +#define _PCU_DEV(bus, func) PCI_DEV(bus, PCU_DEV, func) +#endif + +#define PCU_DEV 30 + +#define PCU_CR0_FUN 0 +#define PCU_DEV_CR0(bus) _PCU_DEV(bus, PCU_CR0_FUN) +#define PCU_CR0_PLATFORM_INFO 0xa8 +#define PCU_CR0_TURBO_ACTIVATION_RATIO 0xb0 +#define TURBO_ACTIVATION_RATIO_LOCK BIT(31) +#define PCU_CR0_P_STATE_LIMITS 0xd8 +#define P_STATE_LIMITS_LOCK_SHIFT 31 +#define P_STATE_LIMITS_LOCK (1 << P_STATE_LIMITS_LOCK_SHIFT) +#define PCU_CR0_TEMPERATURE_TARGET 0xe4 +#define PCU_CR0_PACKAGE_RAPL_LIMIT_LWR 0xe8 +#define PCU_CR0_PACKAGE_RAPL_LIMIT_UPR (PCU_CR0_PACKAGE_RAPL_LIMIT_LWR + 4) +#define PKG_PWR_LIM_LOCK_UPR BIT(31) +#define PCU_CR0_CURRENT_CONFIG 0xf8 +#define MAX_NON_TURBO_LIM_RATIO_SHIFT 8 /* 8:15 */ +#define MAX_NON_TURBO_LIM_RATIO_MASK (0xff << MAX_NON_TURBO_LIM_RATIO_SHIFT) +#define PCU_CR0_PMAX 0xf0 +#define PMAX_LOCK BIT(31) +#define PCU_CR0_VR_CURRENT_CONFIG_CFG 0xf8 +#define VR_CURRENT_CONFIG_LOCK BIT(31) + +#define PCU_CR1_FUN 1 + +#define PCU_CR1_C2C3TT_REG 0xdc +#define PCU_CR1_PCIE_ILTR_OVRD 0xfc +#define PCU_CR1_SAPMCTL 0xb0 + +#define PCU_CR1_BIOS_MB_DATA_REG 0x8c + +#define PCU_CR1_BIOS_MB_INTERFACE_REG 0x90 +#define BIOS_MB_RUN_BUSY_MASK BIT(31) +#define BIOS_MB_CMD_MASK 0xff +#define BIOS_CMD_READ_PCU_MISC_CFG 0x5 +#define BIOS_CMD_WRITE_PCU_MISC_CFG 0x6 +#define BIOS_ERR_INVALID_CMD 0x01 + +#define PCU_CR1_BIOS_RESET_CPL_REG 0x94 +#define RST_CPL1_MASK BIT(1) +#define RST_CPL2_MASK BIT(2) +#define RST_CPL3_MASK BIT(3) +#define RST_CPL4_MASK BIT(4) +#define PCODE_INIT_DONE1_MASK BIT(9) +#define PCODE_INIT_DONE2_MASK BIT(10) +#define PCODE_INIT_DONE3_MASK BIT(11) +#define PCODE_INIT_DONE4_MASK BIT(12) + +#define PCU_CR1_MC_BIOS_REQ 0x98 + +#if (CONFIG(SOC_INTEL_SKYLAKE_SP) || CONFIG(SOC_INTEL_COOPERLAKE_SP)) +#define PCU_CR1_DESIRED_CORES_CFG2_REG 0xa0 +#else +#define PCU_CR1_DESIRED_CORES_CFG2_REG 0xbc +#endif +#define PCU_CR1_DESIRED_CORES_CFG2_REG_LOCK_MASK BIT(31) + +#define PCU_CR1_SAPMCTL 0xb0 +#define SAPMCTL_LOCK_MASK BIT(31) + +#define PCU_CR2_FUN 2 +#define PCU_DEV_CR2(bus) _PCU_DEV(bus, PCU_CR2_FUN) +#define PCU_CR2_PKG_CST_ENTRY_CRITERIA_MASK 0x8c +#define PCIE_IN_PKGCSTATE_L1_MASK 0xFFFFFF /* 23:0 bits */ +#define PCU_CR2_PKG_CST_ENTRY_CRITERIA_MASK2 0x90 +#define KTI_IN_PKGCSTATE_L1_MASK 0x7 /* 2:0 bits */ +#define PCU_CR2_DRAM_POWER_INFO_LWR 0xa8 +#define PCU_CR2_DRAM_POWER_INFO_UPR (PCU_CR2_DRAM_POWER_INFO_LWR + 4) +#define DRAM_POWER_INFO_LOCK_UPR BIT(31) +#define PCU_CR2_DYNAMIC_PERF_POWER_CTL 0xdc +#define UNCORE_PLIMIT_OVERRIDE_BIT 20 +#define UNOCRE_PLIMIT_OVERRIDE_SHIFT (1 << UNCORE_PLIMIT_OVERRIDE_BIT) +#define PCU_CR2_PROCHOT_RESPONSE_RATIO_REG 0xb0 +#define PROCHOT_RATIO 0xa /* bits 0:7 */ +#define PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR 0xf0 +#define PP_PWR_LIM_LOCK BIT(31) +#define PCU_CR2_DRAM_PLANE_POWER_LIMIT_UPR (PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR + 4) +#define PP_PWR_LIM_LOCK_UPR BIT(31) + +#define PCU_CR3_FUN 3 +#define PCU_DEV_CR3(bus) _PCU_DEV(bus, PCU_CR3_FUN) +#define PCU_CR3_CAPID4 0x94 +#define ERR_SPOOFING_DIS 1 +#if (CONFIG(SOC_INTEL_SKYLAKE_SP) || CONFIG(SOC_INTEL_COOPERLAKE_SP)) +#define PCU_CR3_CONFIG_TDP_CONTROL 0x60 +#else +#define PCU_CR3_CONFIG_TDP_CONTROL 0xd8 +#endif +#define TDP_LOCK BIT(31) +#define PCU_CR3_FLEX_RATIO 0xa0 +#define OC_LOCK BIT(20) + +#define PCU_CR4_FUN 4 +#define PCU_VIRAL_CONTROL 0x84 +#define PCU_FW_ERR_EN (1 << 10) +#define PCU_UC_ERR_EN (1 << 9) +#define PCU_HW_ERR_EN (1 << 8) +#define PCU_EMCA_MODE (1 << 2) + +#define PCU_CR6_FUN 6 +#define PCU_DEV_CR6(bus) _PCU_DEV(bus, PCU_CR6_FUN) +#define PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_LWR 0xa8 +#define PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_UPR (PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_LWR + 4) +#define PLT_PWR_LIM_LOCK_UPR BIT(31) +#define PCU_CR6_PLATFORM_POWER_INFO_CFG_LWR 0xb0 +#define PCU_CR6_PLATFORM_POWER_INFO_CFG_UPR (PCU_CR6_PLATFORM_POWER_INFO_CFG_LWR + 4) +#define PLT_PWR_INFO_LOCK_UPR BIT(31) + +#endif /* _SOC_PCU_H_ */ diff --git a/src/soc/intel/xeon_sp/include/soc/util.h b/src/soc/intel/xeon_sp/include/soc/util.h index 8e5833a245..c4ea5912f8 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 @@ int get_platform_thread_count(void); 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 0000000000..1bc3c2a850 --- /dev/null +++ b/src/soc/intel/xeon_sp/pcu0.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include + +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, + .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 0000000000..a19bfa836b --- /dev/null +++ b/src/soc/intel/xeon_sp/pcu1.c @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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; + + /* + * 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)); + if (CONFIG(SOC_INTEL_SKYLAKE_SP) || CONFIG(SOC_INTEL_COOPERLAKE_SP)) { + 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 0000000000..278bdb87ce --- /dev/null +++ b/src/soc/intel/xeon_sp/pcu2.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include + +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); + 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)); + if (CONFIG(SOC_INTEL_SKYLAKE_SP) || CONFIG(SOC_INTEL_COOPERLAKE_SP)) { + pci_or_config32(dev, PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR, + PP_PWR_LIM_LOCK); + } else { + pci_or_config32(dev, PCU_CR2_DRAM_PLANE_POWER_LIMIT_UPR, + PP_PWR_LIM_LOCK_UPR); + } + 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 0000000000..cd859e320e --- /dev/null +++ b/src/soc/intel/xeon_sp/pcu3.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include + +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); + if (CONFIG(SOC_INTEL_SKYLAKE_SP) || CONFIG(SOC_INTEL_COOPERLAKE_SP)) { + 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, + .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 0000000000..60a609e00d --- /dev/null +++ b/src/soc/intel/xeon_sp/pcu6.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include + +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, + .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/Makefile.mk b/src/soc/intel/xeon_sp/skx/Makefile.mk index 624d60a142..2955cbf03c 100644 --- a/src/soc/intel/xeon_sp/skx/Makefile.mk +++ b/src/soc/intel/xeon_sp/skx/Makefile.mk @@ -23,7 +23,10 @@ ramstage-y += ioapic.c ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c ramstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c ramstage-y += hob_display.c - +ramstage-y += ../pcu0.c +ramstage-y += ../pcu1.c +ramstage-y += ../pcu2.c +ramstage-y += ../pcu3.c CPPFLAGS_common += -I$(src)/soc/intel/xeon_sp/skx/include -I$(src)/soc/intel/xeon_sp/skx cpu_microcode_bins += 3rdparty/intel-microcode/intel-ucode/06-55-04 diff --git a/src/soc/intel/xeon_sp/skx/chip.c b/src/soc/intel/xeon_sp/skx/chip.c index 50a3ee3f2c..2f05cfb093 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 soc_enable_dev(struct device *dev) } } -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 @@ static void soc_final(void *data) { // 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 36dc63b154..1becda8f0a 100644 --- a/src/soc/intel/xeon_sp/skx/cpu.c +++ b/src/soc/intel/xeon_sp/skx/cpu.c @@ -293,8 +293,6 @@ void mp_init_cpus(struct bus *bus) */ 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/pci_devs.h b/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h index 78393c1330..b6414ad62f 100644 --- a/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h +++ b/src/soc/intel/xeon_sp/skx/include/soc/pci_devs.h @@ -9,16 +9,6 @@ #include #include -#define dump_csr(dev, reg) \ - printk(BIOS_SPEW, "%s reg: %s (0x%x), data: 0x%x\n", \ - dev_path(dev), \ - #reg, reg, pci_read_config32(dev, reg)) - -#define dump_csr64(dev, reg) \ - printk(BIOS_SPEW, "%s reg: %s (0x%x), data: 0x%x%x\n", \ - dev_path(dev), #reg, reg, \ - pci_read_config32(dev, reg+4), pci_read_config32(dev, reg)) - #define SAD_ALL_DEV 29 #define SAD_ALL_FUNC 0 #define SAD_ALL_PAM0123_CSR 0x40 @@ -26,93 +16,11 @@ #define SAD_ALL_PAM456_CSR 0x44 #define SAD_ALL_DEVID 0x2054 -#if !defined(__SIMPLE_DEVICE__) -#define _PCU_DEV(bus, func) pcidev_path_on_bus(bus, PCI_DEVFN(PCU_DEV, func)) -#else -#define _PCU_DEV(bus, func) PCI_DEV(bus, PCU_DEV, func) -#endif - #define PCU_IIO_STACK 1 -#define PCU_DEV 30 - -#define PCU_CR0_FUN 0 #define PCU_CR0_DEVID 0x2080 -#define PCU_DEV_CR0(bus) _PCU_DEV(bus, PCU_CR0_FUN) -#define PCU_CR0_PLATFORM_INFO 0xa8 -#define PCU_CR0_TURBO_ACTIVATION_RATIO 0xb0 -#define TURBO_ACTIVATION_RATIO_LOCK BIT(31) -#define PCU_CR0_P_STATE_LIMITS 0xd8 -#define P_STATE_LIMITS_LOCK_SHIFT 31 -#define P_STATE_LIMITS_LOCK (1 << P_STATE_LIMITS_LOCK_SHIFT) -#define PCU_CR0_TEMPERATURE_TARGET 0xe4 -#define PCU_CR0_PACKAGE_RAPL_LIMIT 0xe8 -#define PCU_CR0_PACKAGE_RAPL_LIMIT_UPR (PCU_CR0_PACKAGE_RAPL_LIMIT + 4) -#define PKG_PWR_LIM_LOCK_UPR BIT(31) -#define PCU_CR0_CURRENT_CONFIG 0xf8 -#define MAX_NON_TURBO_LIM_RATIO_SHIFT 8 /* 8:15 */ -#define MAX_NON_TURBO_LIM_RATIO_MASK (0xff << MAX_NON_TURBO_LIM_RATIO_SHIFT) -#define PCU_CR0_PMAX 0xf0 -#define PMAX_LOCK BIT(31) - -#define PCU_CR1_FUN 1 #define PCU_CR1_DEVID 0x2081 - -#define PCU_CR1_C2C3TT_REG 0xdc -#define PCU_CR1_PCIE_ILTR_OVRD 0xfc -#define PCU_CR1_SAPMCTL 0xb0 - -#define PCU_CR1_BIOS_MB_DATA_REG 0x8c - -#define PCU_CR1_BIOS_MB_INTERFACE_REG 0x90 -#define BIOS_MB_RUN_BUSY_MASK BIT(31) -#define BIOS_MB_CMD_MASK 0xff -#define BIOS_CMD_READ_PCU_MISC_CFG 0x5 -#define BIOS_CMD_WRITE_PCU_MISC_CFG 0x6 -#define BIOS_ERR_INVALID_CMD 0x01 - -#define PCU_CR1_BIOS_RESET_CPL_REG 0x94 -#define RST_CPL1_MASK BIT(1) -#define RST_CPL2_MASK BIT(2) -#define RST_CPL3_MASK BIT(3) -#define RST_CPL4_MASK BIT(4) -#define PCODE_INIT_DONE1_MASK BIT(9) -#define PCODE_INIT_DONE2_MASK BIT(10) -#define PCODE_INIT_DONE3_MASK BIT(11) -#define PCODE_INIT_DONE4_MASK BIT(12) - -#define PCU_CR1_MC_BIOS_REQ 0x98 - -#define PCU_CR1_DESIRED_CORES_CFG2_REG 0xa0 -#define PCU_CR1_DESIRED_CORES_CFG2_REG_LOCK_MASK BIT(31) - -#define PCU_CR1_SAPMCTL 0xb0 -#define SAPMCTL_LOCK_MASK BIT(31) - -#define PCU_CR2_FUN 2 #define PCU_CR2_DEVID 0x2082 -#define PCU_DEV_CR2(bus) _PCU_DEV(bus, PCU_CR2_FUN) -#define PCU_CR2_PKG_CST_ENTRY_CRITERIA_MASK 0x8c -#define PCIE_IN_PKGCSTATE_L1_MASK 0xFFFFFF /* 23:0 bits */ -#define PCU_CR2_PKG_CST_ENTRY_CRITERIA_MASK2 0x90 -#define KTI_IN_PKGCSTATE_L1_MASK 0x7 /* 2:0 bits */ -#define PCU_CR2_DRAM_POWER_INFO_LWR 0xa8 -#define PCU_CR2_DRAM_POWER_INFO_UPR (PCU_CR2_DRAM_POWER_INFO_LWR + 4) -#define DRAM_POWER_INFO_LOCK_UPR BIT(31) -#define PCU_CR2_DYNAMIC_PERF_POWER_CTL 0xdc -#define UNCORE_PLIMIT_OVERRIDE_BIT 20 -#define UNOCRE_PLIMIT_OVERRIDE_SHIFT (1 << UNCORE_PLIMIT_OVERRIDE_BIT) -#define PCU_CR2_PROCHOT_RESPONSE_RATIO_REG 0xb0 -#define PROCHOT_RATIO 0xa /* bits 0:7 */ -#define PCU_CR2_DRAM_PLANE_POWER_LIMIT 0xf0 -#define PP_PWR_LIM_LOCK BIT(31) - -#define PCU_CR3_FUN 3 #define PCU_CR3_DEVID 0x2083 -#define PCU_DEV_CR3(bus) _PCU_DEV(bus, PCU_CR3_FUN) -#define PCU_CR3_CONFIG_TDP_CONTROL 0x60 -#define TDP_LOCK BIT(31) -#define PCU_CR3_FLEX_RATIO 0xa0 -#define OC_LOCK BIT(20) #if !defined(__SIMPLE_DEVICE__) #define _UBOX_DEV(func) pcidev_path_on_root_debug(PCI_DEVFN(UBOX_DEV, func), __func__) 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 ce7c645037..f0e1761263 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 387b5668f5..5a035f5a15 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 @@ bool is_ubox_stack_res(const STACK_RES *res) 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/Makefile.mk b/src/soc/intel/xeon_sp/spr/Makefile.mk index f1755e4828..39d6a99d28 100644 --- a/src/soc/intel/xeon_sp/spr/Makefile.mk +++ b/src/soc/intel/xeon_sp/spr/Makefile.mk @@ -17,6 +17,12 @@ ramstage-y += crashlog.c ioat.c ramstage-y += ../chip_gen1.c ../lpc_gen1.c ramstage-$(CONFIG_DISPLAY_HOBS) += hob_display.c ramstage-$(CONFIG_DISPLAY_UPD_DATA) += upd_display.c +ramstage-y += ../pcu0.c +ramstage-y += ../pcu1.c +ramstage-y += ../pcu2.c +ramstage-y += ../pcu3.c +ramstage-y += ../pcu6.c + CPPFLAGS_common += -I$(src)/soc/intel/xeon_sp/spr/include -I$(src)/soc/intel/xeon_sp/spr cpu_microcode_bins += 3rdparty/intel-microcode/intel-ucode/06-8f-08 diff --git a/src/soc/intel/xeon_sp/spr/chip.c b/src/soc/intel/xeon_sp/spr/chip.c index e179df0e15..9fd747d2d5 100644 --- a/src/soc/intel/xeon_sp/spr/chip.c +++ b/src/soc/intel/xeon_sp/spr/chip.c @@ -59,44 +59,6 @@ static void chip_enable_dev(struct device *dev) } } -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_CR2_DEVID, dev))) { - printk(BIOS_SPEW, "%s: locking registers\n", dev_path(dev)); - pci_or_config32(dev, PCU_CR2_DRAM_POWER_INFO_UPR, - DRAM_POWER_INFO_LOCK_UPR); - pci_or_config32(dev, PCU_CR2_DRAM_PLANE_POWER_LIMIT_UPR, - PP_PWR_LIM_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); - } - - dev = NULL; - while ((dev = dev_find_device(PCI_VID_INTEL, PCU_CR6_DEVID, dev))) { - printk(BIOS_SPEW, "%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 void chip_final(void *data) { /* Lock SBI */ @@ -105,7 +67,6 @@ static void chip_final(void *data) /* LOCK PAM */ pci_or_config32(pcidev_path_on_root(PCI_DEVFN(0, 0)), 0x80, 1 << 0); - set_pcu_locks(); tco_lockdown(); p2sb_hide(); @@ -116,8 +77,6 @@ static void chip_final(void *data) 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/spr/include/soc/pci_devs.h b/src/soc/intel/xeon_sp/spr/include/soc/pci_devs.h index ae1a020d1a..0825260ac5 100644 --- a/src/soc/intel/xeon_sp/spr/include/soc/pci_devs.h +++ b/src/soc/intel/xeon_sp/spr/include/soc/pci_devs.h @@ -29,60 +29,14 @@ /* PCU [B:31, D:30, F:0] */ #define PCU_IIO_STACK 1 #define PCU_CR0_DEVID 0x3258 -#define PCU_CR0_PLATFORM_INFO 0xa8 -#define PCU_CR0_TURBO_ACTIVATION_RATIO 0xb0 -#define TURBO_ACTIVATION_RATIO_LOCK BIT(31) -#define PCU_CR0_P_STATE_LIMITS 0xd8 -#define P_STATE_LIMITS_LOCK BIT(31) -#define PCU_CR0_PACKAGE_RAPL_LIMIT_LWR 0xe8 -#define PCU_CR0_PACKAGE_RAPL_LIMIT_UPR (PCU_CR0_PACKAGE_RAPL_LIMIT_LWR + 4) -#define PKG_PWR_LIM_LOCK_UPR BIT(31) -#define PCU_CR0_PMAX 0xf0 -#define PMAX_LOCK BIT(31) - /* PCU [B:31, D:30, F:1] */ #define PCU_CR1_DEVID 0x3259 -#define PCU_CR1_BIOS_MB_DATA_REG 0x8c - -#define PCU_CR1_BIOS_MB_INTERFACE_REG 0x90 -#define BIOS_MB_RUN_BUSY_MASK BIT(31) -#define BIOS_CMD_READ_PCU_MISC_CFG 0x5 -#define BIOS_CMD_WRITE_PCU_MISC_CFG 0x6 - -#define PCU_CR1_BIOS_RESET_CPL_REG 0x94 -#define RST_CPL3_MASK BIT(3) -#define RST_CPL4_MASK BIT(4) -#define PCODE_INIT_DONE3_MASK BIT(11) -#define PCODE_INIT_DONE4_MASK BIT(12) - -#define PCU_CR1_DESIRED_CORES_CFG2_REG 0xbc -#define PCU_CR1_DESIRED_CORES_CFG2_REG_LOCK_MASK BIT(31) - /* PCU [B:31, D:30, F:2] */ #define PCU_CR2_DEVID 0x325a -#define PCU_CR2_DRAM_POWER_INFO_LWR 0xa8 -#define PCU_CR2_DRAM_POWER_INFO_UPR (PCU_CR2_DRAM_POWER_INFO_LWR + 4) -#define DRAM_POWER_INFO_LOCK_UPR BIT(31) - -#define PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR 0xf0 -#define PCU_CR2_DRAM_PLANE_POWER_LIMIT_UPR (PCU_CR2_DRAM_PLANE_POWER_LIMIT_LWR + 4) -#define PP_PWR_LIM_LOCK_UPR BIT(31) - /* PCU [B:31, D:30, F:3] */ #define PCU_CR3_DEVID 0x325b -#define PCU_CR3_CONFIG_TDP_CONTROL 0xd8 -#define TDP_LOCK BIT(31) -#define PCU_CR3_FLEX_RATIO 0xa0 -#define OC_LOCK BIT(20) - /* PCU [B:31, D:30, F:6] */ #define PCU_CR6_DEVID 0x325e -#define PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_LWR 0xa8 -#define PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_UPR (PCU_CR6_PLATFORM_RAPL_LIMIT_CFG_LWR + 4) -#define PLT_PWR_LIM_LOCK_UPR BIT(31) -#define PCU_CR6_PLATFORM_POWER_INFO_CFG_LWR 0xb0 -#define PCU_CR6_PLATFORM_POWER_INFO_CFG_UPR (PCU_CR6_PLATFORM_POWER_INFO_CFG_LWR + 4) -#define PLT_PWR_INFO_LOCK_UPR BIT(31) /* Memory Map/VTD Device Functions * These are available in each IIO stack at B:D.F = B:0.0 diff --git a/src/soc/intel/xeon_sp/util.c b/src/soc/intel/xeon_sp/util.c index 69f3c15452..3dd0155a40 100644 --- a/src/soc/intel/xeon_sp/util.c +++ b/src/soc/intel/xeon_sp/util.c @@ -120,139 +120,3 @@ union p2sb_bdf soc_get_ioapic_bdf(void) } 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