V Sowmya has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/43791 )
Change subject: soc/intel/jasperlake: Add FSP UPD for minimum assertion widths ......................................................................
soc/intel/jasperlake: Add FSP UPD for minimum assertion widths
Add the FSP UPD for the chipset minimum assertion width and Power cycle duration setting to chip options which can be configured per maiboard. * 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 --- M src/soc/intel/jasperlake/chip.h M src/soc/intel/jasperlake/fsp_params.c 2 files changed, 187 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/91/43791/1
diff --git a/src/soc/intel/jasperlake/chip.h b/src/soc/intel/jasperlake/chip.h index e5e10e3..77421f0 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 6493fd5..921ff5d 100644 --- a/src/soc/intel/jasperlake/fsp_params.c +++ b/src/soc/intel/jasperlake/fsp_params.c @@ -41,6 +41,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(); @@ -76,6 +108,92 @@ sizeof(config->SerialIoUartMode)); }
+static enum min_assrt_dur get_high_asst_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; +} + +static void get_min_assrt_dur(uint8_t slp_s4_min_asst, uint8_t slp_s3_min_asst, + uint8_t slp_a_min_asst, 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_asst_dur_list : 1s, 1s(default), 2s, 3s, 4s */ + const enum min_assrt_dur slp_s4_asst_dur_list[] = { + MinAssrtDur1s, MinAssrtDur1s, MinAssrtDur2s, MinAssrtDur3s, MinAssrtDur4s + }; + + /* slp_s3_asst_dur_list: 50ms, 60us, 1ms, 50ms (Default), 2s */ + const enum min_assrt_dur slp_s3_asst_dur_list[] = { + MinAssrtDur50ms, MinAssrtDur60us, MinAssrtDur1ms, MinAssrtDur50ms, MinAssrtDur2s + }; + + /* slp_a_asst_dur_list: 2s, 0s, 4s, 98ms, 2s(Default) */ + const enum min_assrt_dur slp_a_asst_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_asst < ARRAY_SIZE(slp_s4_asst_dur_list)) + cfg_assrt_dur->slp_s4 = slp_s4_asst_dur_list[slp_s4_min_asst]; + + if (slp_s3_min_asst < ARRAY_SIZE(slp_s3_asst_dur_list)) + cfg_assrt_dur->slp_s3 = slp_s3_asst_dur_list[slp_s3_min_asst]; + + if (slp_a_min_asst < ARRAY_SIZE(slp_a_asst_dur_list)) + cfg_assrt_dur->slp_a = slp_a_asst_dur_list[slp_a_min_asst]; + + 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]; +} + +static uint8_t get_pm_pwr_cyc_dur(uint8_t slp_s4_min_asst, uint8_t slp_s3_min_asst, + uint8_t slp_a_min_asst, uint8_t pm_pwr_cyc_dur) +{ + /* Set default values for the minimum asserton 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_asst_width; + + /* Convert assertion durations from register-encoded to microseconds */ + get_min_assrt_dur(slp_s4_min_asst, slp_s3_min_asst, slp_a_min_asst, pm_pwr_cyc_dur, + &cfg_assrt_dur); + + /* Get the higher assertion duration among PCH EDS specified signals for pwr_cyc_dur */ + high_asst_width = get_high_asst_width(&cfg_assrt_dur); + + if (cfg_assrt_dur.pm_pwr_cyc_dur >= high_asst_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) { @@ -219,6 +337,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); }