diff options
author | V Sowmya <v.sowmya@intel.com> | 2020-07-24 08:58:14 +0530 |
---|---|---|
committer | Subrata Banik <subrata.banik@intel.com> | 2020-08-17 05:14:05 +0000 |
commit | 7aee5c67a11bed7ae028aac6752ed2f31868b43e (patch) | |
tree | 259c7fa4de768fbaf1083ded3480ec1150c674ef /src/soc/intel/jasperlake/fsp_params.c | |
parent | 43f0dcbb7700da216039909992951f8b7b64b071 (diff) |
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>
Diffstat (limited to 'src/soc/intel/jasperlake/fsp_params.c')
-rw-r--r-- | src/soc/intel/jasperlake/fsp_params.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/soc/intel/jasperlake/fsp_params.c b/src/soc/intel/jasperlake/fsp_params.c index 92ac5b8994..c45af27ece 100644 --- a/src/soc/intel/jasperlake/fsp_params.c +++ b/src/soc/intel/jasperlake/fsp_params.c @@ -42,6 +42,38 @@ static const pci_devfn_t serial_io_dev[] = { 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 @@ static void parse_devicetree(FSP_S_CONFIG *params) 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 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) /* 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); } |