summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/soc/intel/meteorlake/fsp_params.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/soc/intel/meteorlake/fsp_params.c b/src/soc/intel/meteorlake/fsp_params.c
index eff81762eb..790bf9ca11 100644
--- a/src/soc/intel/meteorlake/fsp_params.c
+++ b/src/soc/intel/meteorlake/fsp_params.c
@@ -42,6 +42,8 @@
#define DEF_DMVAL 15
#define DEF_DITOVAL 625
+#define MAX_ONBOARD_PCIE_DEVICES 256
+
static const struct slot_irq_constraints irq_constraints[] = {
{
.slot = PCI_DEV_SLOT_PCIE_3,
@@ -701,6 +703,70 @@ static void arch_silicon_init_params(FSPS_ARCH_UPD *s_arch_cfg)
fsp_debug_event_handler;
}
+static void evaluate_ssid(const struct device *dev, uint16_t *svid, uint16_t *ssid)
+{
+ if (!(dev && svid && ssid))
+ return;
+
+ *svid = CONFIG_SUBSYSTEM_VENDOR_ID ? : (dev->subsystem_vendor ? : 0x8086);
+ *ssid = CONFIG_SUBSYSTEM_DEVICE_ID ? : (dev->subsystem_device ? : 0xfffe);
+}
+
+/*
+ * Programming SSID before FSP-S is important because SSID registers of a few PCIE
+ * devices (e.g. IPU, Crashlog, XHCI, TCSS_XHCI etc.) are locked after FSP-S hence
+ * provide a custom SSID (same as DID by default) value via UPD.
+ */
+static void fill_fsps_pci_ssid_params(FSP_S_CONFIG *s_cfg,
+ const struct soc_intel_meteorlake_config *config)
+{
+ struct svid_ssid_init_entry {
+ union {
+ struct {
+ uint64_t reg:12;
+ uint64_t function:3;
+ uint64_t device:5;
+ uint64_t bus:8;
+ uint64_t ignore1:4;
+ uint64_t segment:16;
+ uint64_t ignore2:16;
+ };
+ uint64_t data;
+ };
+ struct {
+ uint16_t svid;
+ uint16_t ssid;
+ };
+ uint32_t ignore3;
+ };
+
+ static struct svid_ssid_init_entry ssid_table[MAX_ONBOARD_PCIE_DEVICES];
+ const struct device *dev;
+ int i = 0;
+
+ for (dev = all_devices; dev; dev = dev->next) {
+ if (!(is_dev_enabled(dev) && dev->path.type == DEVICE_PATH_PCI &&
+ dev->bus->secondary == 0))
+ continue;
+
+ if (dev->path.pci.devfn == PCI_DEVFN_ROOT) {
+ evaluate_ssid(dev, &s_cfg->SiCustomizedSvid, &s_cfg->SiCustomizedSsid);
+ } else {
+ ssid_table[i].reg = PCI_SUBSYSTEM_VENDOR_ID;
+ ssid_table[i].device = PCI_SLOT(dev->path.pci.devfn);
+ ssid_table[i].function = PCI_FUNC(dev->path.pci.devfn);
+ evaluate_ssid(dev, &ssid_table[i].svid, &ssid_table[i].ssid);
+ i++;
+ }
+ }
+
+ s_cfg->SiSsidTablePtr = (uintptr_t)ssid_table;
+ s_cfg->SiNumberOfSsidTableEntry = i;
+
+ /* Ensure FSP will program the registers */
+ s_cfg->SiSkipSsidProgramming = 0;
+}
+
static void soc_silicon_init_params(FSP_S_CONFIG *s_cfg,
struct soc_intel_meteorlake_config *config)
{
@@ -730,6 +796,7 @@ static void soc_silicon_init_params(FSP_S_CONFIG *s_cfg,
fill_fsps_ufs_params,
fill_fsps_ai_params,
fill_fsps_irq_params,
+ fill_fsps_pci_ssid_params,
};
for (size_t i = 0; i < ARRAY_SIZE(fill_fsps_params); i++)