diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h index a9b8641626..57d51e76b2 100644 --- a/src/soc/intel/skylake/chip.h +++ b/src/soc/intel/skylake/chip.h @@ -35,6 +35,8 @@ #include #include +#define MAX_PEG_PORTS 3 + enum skylake_i2c_voltage { I2C_VOLTAGE_3V3, I2C_VOLTAGE_1V8 @@ -213,6 +215,28 @@ struct soc_intel_skylake_config { * respective PCIe root port. */ + /* PEG Max Link Width */ + enum { + Peg0_x16, + Peg0_x1, + Peg0_x2, + Peg0_x4, + Peg0_x8, + } Peg0MaxLinkWidth; + + enum { + Peg1_x8, + Peg1_x1, + Peg1_x2, + Peg1_x4, + } Peg1MaxLinkWidth; + + enum { + Peg2_x4, + Peg2_x1, + Peg2_x2, + } Peg2MaxLinkWidth; + /* * Enable/Disable Root Port * 0: Disable Root Port diff --git a/src/soc/intel/skylake/include/soc/pci_devs.h b/src/soc/intel/skylake/include/soc/pci_devs.h index f6957940e5..d59c80008b 100644 --- a/src/soc/intel/skylake/include/soc/pci_devs.h +++ b/src/soc/intel/skylake/include/soc/pci_devs.h @@ -37,6 +37,13 @@ #define SA_DEVFN_ROOT _SA_DEVFN(ROOT) #define SA_DEV_ROOT _SA_DEV(ROOT) +#define SA_DEV_SLOT_PEG 0x01 +#define SA_DEVFN_PEG(func) PCI_DEVFN(SA_DEV_SLOT_PEG, func) +#define SA_DEV_PEG(func) dev_find_slot(0, SA_DEVFN_PEG(func)) +#define SA_DEV_PEG0 SA_DEV_PEG(0) +#define SA_DEV_PEG1 SA_DEV_PEG(1) +#define SA_DEV_PEG2 SA_DEV_PEG(2) + #define SA_DEV_SLOT_IGD 0x02 #define SA_DEVFN_IGD _SA_DEVFN(IGD) #define SA_DEV_IGD _SA_DEV(IGD) diff --git a/src/soc/intel/skylake/romstage/romstage_fsp20.c b/src/soc/intel/skylake/romstage/romstage_fsp20.c index b65c9ff935..d9b2706a8b 100644 --- a/src/soc/intel/skylake/romstage/romstage_fsp20.c +++ b/src/soc/intel/skylake/romstage/romstage_fsp20.c @@ -202,6 +202,61 @@ static void cpu_flex_override(FSP_M_CONFIG *m_cfg) m_cfg->CpuRatio = (flex_ratio.lo >> 8) & 0xff; } +static void soc_peg_init_params(FSP_M_CONFIG *m_cfg, + FSP_M_TEST_CONFIG *m_t_cfg, + const struct soc_intel_skylake_config *config) +{ + const struct device *dev; + /* + * To enable or disable the corresponding PEG root port you need to + * add to the devicetree.cb: + * + * device pci 01.0 on end # enable PEG0 root port + * device pci 01.1 off end # do not configure PEG1 + * + * If PEG port is not defined in the device tree, it will be disabled + * in FSP + */ + dev = SA_DEV_PEG0; /* PEG 0:1:0 */ + if (!dev || !dev->enabled) + m_cfg->Peg0Enable = 0; + else if (dev->enabled) { + m_cfg->Peg0Enable = dev->enabled; + m_cfg->Peg0MaxLinkWidth = config->Peg0MaxLinkWidth; + /* Use maximum possible link speed */ + m_cfg->Peg0MaxLinkSpeed = 0; + /* Power down unused lanes based on the max possible width */ + m_cfg->Peg0PowerDownUnusedLanes = 1; + /* Set [Auto] for options to enable equalization methods */ + m_t_cfg->Peg0Gen3EqPh2Enable = 2; + m_t_cfg->Peg0Gen3EqPh3Method = 0; + } + + dev = SA_DEV_PEG1; /* PEG 0:1:1 */ + if (!dev || !dev->enabled) + m_cfg->Peg1Enable = 0; + else if (dev->enabled) { + m_cfg->Peg1Enable = dev->enabled; + m_cfg->Peg1MaxLinkWidth = config->Peg1MaxLinkWidth; + m_cfg->Peg1MaxLinkSpeed = 0; + m_cfg->Peg1PowerDownUnusedLanes = 1; + m_t_cfg->Peg1Gen3EqPh2Enable = 2; + m_t_cfg->Peg1Gen3EqPh3Method = 0; + } + + dev = SA_DEV_PEG2; /* PEG 0:1:2 */ + if (!dev || !dev->enabled) + m_cfg->Peg2Enable = 0; + else if (dev->enabled) { + m_cfg->Peg2Enable = dev->enabled; + m_cfg->Peg2MaxLinkWidth = config->Peg2MaxLinkWidth; + m_cfg->Peg2MaxLinkSpeed = 0; + m_cfg->Peg2PowerDownUnusedLanes = 1; + m_t_cfg->Peg2Gen3EqPh2Enable = 2; + m_t_cfg->Peg2Gen3EqPh3Method = 0; + } +} + static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, const struct soc_intel_skylake_config *config) { @@ -276,6 +331,7 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) config = dev->chip_info; soc_memory_init_params(m_cfg, config); + soc_peg_init_params(m_cfg, m_t_cfg, config); /* Skip creating Management Engine MBP HOB */ m_t_cfg->SkipMbpHob = 0x01;