Subrata Banik has submitted this change. ( https://review.coreboot.org/c/coreboot/+/43791 )
Change subject: soc/intel/jasperlake: Add FSP UPDs for minimum assertion widths ......................................................................
soc/intel/jasperlake: Add FSP UPDs for minimum assertion widths
Add the FSP UPDs for the chipset minimum assertion widths and Power cycle duration to the chip options which can be configured per mainboard.
* PchPmSlpS3MinAssert: SLP_S3 Minimum Assertion Width Policy * PchPmSlpS4MinAssert: SLP_S4 Minimum Assertion Width Policy * PchPmSlpSusMinAssert: SLP_SUS Minimum Assertion Width Policy * PchPmSlpAMinAssert: SLP_A Minimum Assertion Width Policy * PchPmPwrCycDur: PCH PM Reset Power Cycle Duration * Check to avoid violating the PCH EDS recommendation for the PchPmPwrCycDur setting.
BUG=b:159104150
Change-Id: I042e8e34b7dfda3bc21e5f2e6727cb7692ffc7f7 Signed-off-by: V Sowmya v.sowmya@intel.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/43791 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Aamir Bohra aamir.bohra@intel.com Reviewed-by: Sridhar Siricilla sridhar.siricilla@intel.com Reviewed-by: Maulik V Vaghela maulik.v.vaghela@intel.com Reviewed-by: Ronak Kanabar ronak.kanabar@intel.com Reviewed-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/jasperlake/chip.h M src/soc/intel/jasperlake/fsp_params.c 2 files changed, 194 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Subrata Banik: Looks good to me, approved Aamir Bohra: Looks good to me, approved Maulik V Vaghela: Looks good to me, approved Ronak Kanabar: Looks good to me, but someone else must approve Sridhar Siricilla: Looks good to me, but someone else must approve
diff --git a/src/soc/intel/jasperlake/chip.h b/src/soc/intel/jasperlake/chip.h index e5e10e3..70fbbc3 100644 --- a/src/soc/intel/jasperlake/chip.h +++ b/src/soc/intel/jasperlake/chip.h @@ -291,6 +291,59 @@ * for the platforms with soldered down SOC. */ uint8_t SkipCpuReplacementCheck; + + /* + * SLP_S3 Minimum Assertion Width Policy + * 1 = 60us + * 2 = 1ms + * 3 = 50ms (default) + * 4 = 2s + */ + uint8_t PchPmSlpS3MinAssert; + + /* + * SLP_S4 Minimum Assertion Width Policy + * 1 = 1s (default) + * 2 = 2s + * 3 = 3s + * 4 = 4s + */ + uint8_t PchPmSlpS4MinAssert; + + /* + * SLP_SUS Minimum Assertion Width Policy + * 1 = 0ms + * 2 = 500ms + * 3 = 1s + * 4 = 4s (default) + */ + uint8_t PchPmSlpSusMinAssert; + + /* + * SLP_A Minimum Assertion Width Policy + * 1 = 0ms + * 2 = 4s + * 3 = 98ms + * 4 = 2s (default) + */ + uint8_t PchPmSlpAMinAssert; + + /* + * PCH PM Reset Power Cycle Duration + * 0 = 4s (default) + * 1 = 1s + * 2 = 2s + * 3 = 3s + * 4 = 4s + * + * NOTE: Duration programmed in the PchPmPwrCycDur should never be smaller than the + * stretch duration programmed in the following registers: + * - GEN_PMCON_A.SLP_S3_MIN_ASST_WDTH (PchPmSlpS3MinAssert) + * - GEN_PMCON_A.S4MAW (PchPmSlpS4MinAssert) + * - PM_CFG.SLP_A_MIN_ASST_WDTH (PchPmSlpAMinAssert) + * - PM_CFG.SLP_LAN_MIN_ASST_WDTH + */ + uint8_t PchPmPwrCycDur; };
typedef struct soc_intel_jasperlake_config config_t; diff --git a/src/soc/intel/jasperlake/fsp_params.c b/src/soc/intel/jasperlake/fsp_params.c index 92ac5b8..c45af27 100644 --- a/src/soc/intel/jasperlake/fsp_params.c +++ b/src/soc/intel/jasperlake/fsp_params.c @@ -42,6 +42,38 @@ PCH_DEVFN_UART2 };
+/* List of Minimum Assertion durations in microseconds */ +enum min_assrt_dur { + MinAssrtDur0s = 0, + MinAssrtDur60us = 60, + MinAssrtDur1ms = 1000, + MinAssrtDur50ms = 50000, + MinAssrtDur98ms = 98000, + MinAssrtDur500ms = 500000, + MinAssrtDur1s = 1000000, + MinAssrtDur2s = 2000000, + MinAssrtDur3s = 3000000, + MinAssrtDur4s = 4000000, +}; + +/* Signal Assertion duration values */ +struct cfg_assrt_dur { + /* Minimum assertion duration of SLP_A signal */ + enum min_assrt_dur slp_a; + + /* Minimum assertion duration of SLP_4 signal */ + enum min_assrt_dur slp_s4; + + /* Minimum assertion duration of SLP_3 signal */ + enum min_assrt_dur slp_s3; + + /* PCH PM Power Cycle duration */ + enum min_assrt_dur pm_pwr_cyc_dur; +}; + +/* Default value of PchPmPwrCycDur */ +#define PCH_PM_PWR_CYC_DUR 0 + static void parse_devicetree(FSP_S_CONFIG *params) { const struct soc_intel_jasperlake_config *config = config_of_soc(); @@ -77,6 +109,99 @@ sizeof(config->SerialIoUartMode)); }
+/* This function returns the highest assertion duration of the SLP_Sx assertion widths */ +static enum min_assrt_dur get_high_assrt_width(const struct cfg_assrt_dur *cfg_assrt_dur) +{ + enum min_assrt_dur max_assert_dur = cfg_assrt_dur->slp_s4; + + if (max_assert_dur < cfg_assrt_dur->slp_s3) + max_assert_dur = cfg_assrt_dur->slp_s3; + + if (max_assert_dur < cfg_assrt_dur->slp_a) + max_assert_dur = cfg_assrt_dur->slp_a; + + return max_assert_dur; +} + +/* This function converts assertion durations from register-encoded to microseconds */ +static void get_min_assrt_dur(uint8_t slp_s4_min_assrt, uint8_t slp_s3_min_assrt, + uint8_t slp_a_min_assrt, uint8_t pm_pwr_cyc_dur, + struct cfg_assrt_dur *cfg_assrt_dur) +{ + /* + * Ensure slp_x_dur_list[] elements in the devicetree config are in sync with + * FSP encoded values. + */ + + /* slp_s4_assrt_dur_list : 1s, 1s(default), 2s, 3s, 4s */ + const enum min_assrt_dur slp_s4_assrt_dur_list[] = { + MinAssrtDur1s, MinAssrtDur1s, MinAssrtDur2s, MinAssrtDur3s, MinAssrtDur4s + }; + + /* slp_s3_assrt_dur_list: 50ms, 60us, 1ms, 50ms (Default), 2s */ + const enum min_assrt_dur slp_s3_assrt_dur_list[] = { + MinAssrtDur50ms, MinAssrtDur60us, MinAssrtDur1ms, MinAssrtDur50ms, MinAssrtDur2s + }; + + /* slp_a_assrt_dur_list: 2s, 0s, 4s, 98ms, 2s(Default) */ + const enum min_assrt_dur slp_a_assrt_dur_list[] = { + MinAssrtDur2s, MinAssrtDur0s, MinAssrtDur4s, MinAssrtDur98ms, MinAssrtDur2s + }; + + /* pm_pwr_cyc_dur_list: 4s(Default), 1s, 2s, 3s, 4s */ + const enum min_assrt_dur pm_pwr_cyc_dur_list[] = { + MinAssrtDur4s, MinAssrtDur1s, MinAssrtDur2s, MinAssrtDur3s, MinAssrtDur4s + }; + + /* Get signal assertion width */ + if (slp_s4_min_assrt < ARRAY_SIZE(slp_s4_assrt_dur_list)) + cfg_assrt_dur->slp_s4 = slp_s4_assrt_dur_list[slp_s4_min_assrt]; + + if (slp_s3_min_assrt < ARRAY_SIZE(slp_s3_assrt_dur_list)) + cfg_assrt_dur->slp_s3 = slp_s3_assrt_dur_list[slp_s3_min_assrt]; + + if (slp_a_min_assrt < ARRAY_SIZE(slp_a_assrt_dur_list)) + cfg_assrt_dur->slp_a = slp_a_assrt_dur_list[slp_a_min_assrt]; + + if (pm_pwr_cyc_dur < ARRAY_SIZE(pm_pwr_cyc_dur_list)) + cfg_assrt_dur->pm_pwr_cyc_dur = pm_pwr_cyc_dur_list[pm_pwr_cyc_dur]; +} + +/* This function ensures that the duration programmed in the PchPmPwrCycDur will never be + * smaller than the SLP_Sx assertion widths. + * If the pm_pwr_cyc_dur is less than any of the SLP_Sx assertion widths then it returns the + * default value PCH_PM_PWR_CYC_DUR. + */ +static uint8_t get_pm_pwr_cyc_dur(uint8_t slp_s4_min_assrt, uint8_t slp_s3_min_assrt, + uint8_t slp_a_min_assrt, uint8_t pm_pwr_cyc_dur) +{ + /* Set default values for the minimum assertion duration */ + struct cfg_assrt_dur cfg_assrt_dur = { + .slp_a = MinAssrtDur2s, + .slp_s4 = MinAssrtDur1s, + .slp_s3 = MinAssrtDur50ms, + .pm_pwr_cyc_dur = MinAssrtDur4s + }; + + enum min_assrt_dur high_assrt_width; + + /* Convert assertion durations from register-encoded to microseconds */ + get_min_assrt_dur(slp_s4_min_assrt, slp_s3_min_assrt, slp_a_min_assrt, pm_pwr_cyc_dur, + &cfg_assrt_dur); + + /* Get the highest assertion duration among PCH EDS specified signals for pwr_cyc_dur */ + high_assrt_width = get_high_assrt_width(&cfg_assrt_dur); + + if (cfg_assrt_dur.pm_pwr_cyc_dur >= high_assrt_width) + return pm_pwr_cyc_dur; + + printk(BIOS_DEBUG, + "Set PmPwrCycDur to 4s as configured PmPwrCycDur (%d) violates PCH EDS " + "spec\n", pm_pwr_cyc_dur); + + return PCH_PM_PWR_CYC_DUR; +} + /* UPD parameters to be initialized before SiliconInit */ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) { @@ -204,6 +329,22 @@ /* Provide correct UART number for FSP debug logs */ params->SerialIoDebugUartNumber = CONFIG_UART_FOR_CONSOLE;
+ /* Apply minimum assertion width settings if non-zero */ + if (config->PchPmSlpS3MinAssert) + params->PchPmSlpS3MinAssert = config->PchPmSlpS3MinAssert; + if (config->PchPmSlpS4MinAssert) + params->PchPmSlpS4MinAssert = config->PchPmSlpS4MinAssert; + if (config->PchPmSlpSusMinAssert) + params->PchPmSlpSusMinAssert = config->PchPmSlpSusMinAssert; + if (config->PchPmSlpAMinAssert) + params->PchPmSlpAMinAssert = config->PchPmSlpAMinAssert; + + /* Set Power Cycle Duration */ + if (config->PchPmPwrCycDur) + params->PchPmPwrCycDur = get_pm_pwr_cyc_dur(config->PchPmSlpS4MinAssert, + config->PchPmSlpS3MinAssert, config->PchPmSlpAMinAssert, + config->PchPmPwrCycDur); + /* Override/Fill FSP Silicon Param for mainboard */ mainboard_silicon_init_params(params); }