diff --git a/src/soc/intel/meteorlake/fsp_params.c b/src/soc/intel/meteorlake/fsp_params.c index 5bd28aad2c..3b4fe466d1 100644 --- a/src/soc/intel/meteorlake/fsp_params.c +++ b/src/soc/intel/meteorlake/fsp_params.c @@ -263,6 +263,76 @@ static const SI_PCH_DEVICE_INTERRUPT_CONFIG *pci_irq_to_fsp(size_t *out_count) return config; } +/* + * The PCIe RP ASPM and PCIe L1 Substate UPDs follow the PCI Express Base + * Specification 1.1. The UPDs and their default values are consistent + * from Skylake through Meteor Lake. However, the default for CPU ports + * differs from PCH ports. Use auto and maximum unless overwritten + * to make the behaviour consistent. + * + * +-------------------+--------------------------+-----------+-----------+ + * | Setting | Option | PCH Ports | CPU Ports | + * |-------------------|--------------------------|-----------|-----------| + * | PcieRpEnableCpm | Disabled | [Default] | [Default] | + * | | Enabled | | | + * |-------------------|--------------------------|-----------|-----------| + * | PcieRpAspm | PchPcieAspmDisabled | | | + * | | PchPcieAspmL0s | | | + * | | PchPcieAspmL1 | | | + * | | PchPcieAspmL0sL1 | | [Default] | + * | | PchPcieAspmAutoConfig | [Default] | | + * | | PchPcieAspmMax | | | + * |-------------------|--------------------------|-----------|-----------| + * | PcieRpL1Substates | Disabled | | | + * | | PchPcieL1SubstatesL1_1 | | | + * | | PchPcieL1SubstatesL1_1_2 | | [Default] | + * | | PchPcieL1SubstatesMax | [Default] | | + * +-------------------+--------------------------+-----------+-----------+ + */ + +static unsigned int mtl_aspm_control_to_upd(enum ASPM_control aspm_control) +{ + /* Disable without Kconfig selected */ + if (!CONFIG(PCIEXP_ASPM)) + return UPD_INDEX(ASPM_DISABLE); + + /* Use auto unless overwritten */ + if (!aspm_control) + return UPD_INDEX(ASPM_AUTO); + + return UPD_INDEX(aspm_control); +} + +static unsigned int mtl_l1ss_control_to_upd(enum L1_substates_control l1_substates_control) +{ + /* Disable without Kconfig selected */ + if (!CONFIG(PCIEXP_ASPM)) + return UPD_INDEX(L1_SS_DISABLED); + + /* Don't enable UPD if Kconfig not set */ + if (!CONFIG(PCIEXP_L1_SUB_STATE)) + return UPD_INDEX(L1_SS_DISABLED); + + /* L1 Substate should be disabled in compliance mode */ + if (CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE)) + return UPD_INDEX(L1_SS_DISABLED); + + /* Use maximum unless overwritten */ + if (!l1_substates_control) + return UPD_INDEX(L1_SS_L1_2); + + return UPD_INDEX(l1_substates_control); +} + +static void configure_pch_rp_power_management(FSP_S_CONFIG *s_cfg, + const struct pcie_rp_config *rp_cfg, + unsigned int index) +{ + s_cfg->PcieRpEnableCpm[index] = CONFIG(PCIEXP_CLK_PM); + s_cfg->PcieRpAspm[index] = mtl_aspm_control_to_upd(rp_cfg->pcie_rp_aspm); + s_cfg->PcieRpL1Substates[index] = mtl_l1ss_control_to_upd(rp_cfg->PcieRpL1Substates); +} + /* * ME End of Post configuration * 0 - Disable EOP. @@ -296,47 +366,6 @@ static const pci_devfn_t uart_dev[] = { PCI_DEVFN_UART2 }; -/* - * Chip config parameter PcieRpL1Substates uses (UPD value + 1) - * because UPD value of 0 for PcieRpL1Substates means disabled for FSP. - * In order to ensure that mainboard setting does not disable L1 substates - * incorrectly, chip config parameter values are offset by 1 with 0 meaning - * use FSP UPD default. get_l1_substate_control() ensures that the right UPD - * value is set in fsp_params. - * 0: Use FSP UPD default - * 1: Disable L1 substates - * 2: Use L1.1 - * 3: Use L1.2 (FSP UPD default) - */ -static int get_l1_substate_control(enum L1_substates_control ctl) -{ - if (CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE)) - ctl = L1_SS_DISABLED; - else if ((ctl > L1_SS_L1_2) || (ctl == L1_SS_FSP_DEFAULT)) - ctl = L1_SS_L1_2; - return ctl - 1; -} - -/* - * Chip config parameter pcie_rp_aspm uses (UPD value + 1) because - * a UPD value of 0 for pcie_rp_aspm means disabled. In order to ensure - * that the mainboard setting does not disable ASPM incorrectly, chip - * config parameter values are offset by 1 with 0 meaning use FSP UPD default. - * get_aspm_control() ensures that the right UPD value is set in fsp_params. - * 0: Use FSP UPD default - * 1: Disable ASPM - * 2: L0s only - * 3: L1 only - * 4: L0s and L1 - * 5: Auto configuration - */ -static unsigned int get_aspm_control(enum ASPM_control ctl) -{ - if ((ctl > ASPM_AUTO) || (ctl == ASPM_DEFAULT)) - ctl = ASPM_AUTO; - return ctl - 1; -} - __weak void mainboard_update_soc_chip_config(struct soc_intel_meteorlake_config *config) { /* Override settings per board. */ @@ -667,15 +696,12 @@ static void fill_fsps_pcie_params(FSP_S_CONFIG *s_cfg, if (!(enable_mask & BIT(i))) continue; const struct pcie_rp_config *rp_cfg = &config->pcie_rp[i]; - s_cfg->PcieRpL1Substates[i] = - get_l1_substate_control(rp_cfg->PcieRpL1Substates); s_cfg->PcieRpLtrEnable[i] = !!(rp_cfg->flags & PCIE_RP_LTR); s_cfg->PcieRpAdvancedErrorReporting[i] = !!(rp_cfg->flags & PCIE_RP_AER); s_cfg->PcieRpHotPlug[i] = !!(rp_cfg->flags & PCIE_RP_HOTPLUG) || CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); s_cfg->PcieRpClkReqDetect[i] = !!(rp_cfg->flags & PCIE_RP_CLK_REQ_DETECT); - if (rp_cfg->pcie_rp_aspm) - s_cfg->PcieRpAspm[i] = get_aspm_control(rp_cfg->pcie_rp_aspm); + configure_pch_rp_power_management(s_cfg, rp_cfg, i); } s_cfg->PcieComplianceTestMode = CONFIG(SOC_INTEL_COMPLIANCE_TEST_MODE); }