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>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/85316
Reviewed-by: Shuo Liu <shuo.liu@intel.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Lean Sheng Tan <sheng.tan@9elements.com>
This commit is contained in:
Patrick Rudolph 2024-11-25 17:02:35 +01:00 committed by Lean Sheng Tan
commit 41c2e1685e
21 changed files with 457 additions and 581 deletions

View file

@ -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

View file

@ -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)

View file

@ -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__)

View file

@ -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

View file

@ -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_ */

View file

@ -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);

View file

@ -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/pcu.h>
#include <soc/ramstage.h>
#include <soc/util.h>
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,
};

View file

@ -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/pcu.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;
/*
* 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,
};

View file

@ -0,0 +1,51 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <device/pci.h>
#include <device/pci_ids.h>
#include <soc/pci_devs.h>
#include <soc/pcu.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);
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,
};

View file

@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <device/pci.h>
#include <device/pci_ids.h>
#include <soc/pci_devs.h>
#include <soc/pcu.h>
#include <soc/ramstage.h>
#include <soc/util.h>
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,
};

View file

@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <device/pci.h>
#include <device/pci_ids.h>
#include <soc/pci_devs.h>
#include <soc/pcu.h>
#include <soc/ramstage.h>
#include <soc/util.h>
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,
};

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -9,16 +9,6 @@
#include <hob_iiouds.h>
#include <soc/pch_pci_devs.h>
#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__)

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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