Paul Fagerburg has submitted this change. ( https://review.coreboot.org/c/coreboot/+/62933 )
Change subject: soc/mediatek: Ensure PERST# deassertion time follows the spec ......................................................................
soc/mediatek: Ensure PERST# deassertion time follows the spec
According to the PCIe CEM specification, the deassertion of PERST# should occur at least 100ms after the assertion. To ensure the 100ms delay requirement is met, calculate the elapsed time since assertion. If it is smaller than 100ms, do an extra delay.
TEST=Build pass and boot up to kernel successfully via SSD on Dojo board, here is the measured PERST# time: [DEBUG] mtk_pcie_domain_enable: 432517 us elapsed since assert PERST# [INFO ] mtk_pcie_domain_enable: PCIe link up success (17 tries)
And the SSD information in boot log is as follows: == NVME IDENTIFY CONTROLLER DATA == PCI VID : 0x15b7 PCI SSVID : 0x15b7 SN : 21517J440114 MN : WDC PC SN530 SDBPTPZ-256G-1006 RAB : 0x4 AERL : 0x7 SQES : 0x66 CQES : 0x44 NN : 0x1 Identified NVMe model WDC PC SN530 SDBPTPZ-256G-1006
BUG=b:178565024 BRANCH=cherry
Signed-off-by: Jianjun Wang jianjun.wang@mediatek.com Change-Id: Ie2b7b6174abdf951af5796ab5ed141c45f32fc71 Reviewed-on: https://review.coreboot.org/c/coreboot/+/62933 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Yu-Ping Wu yupingso@google.com --- M src/soc/mediatek/common/pcie.c M src/soc/mediatek/mt8195/pcie.c 2 files changed, 31 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Yu-Ping Wu: Looks good to me, approved
diff --git a/src/soc/mediatek/common/pcie.c b/src/soc/mediatek/common/pcie.c index c46b53f..3a75f6b 100644 --- a/src/soc/mediatek/common/pcie.c +++ b/src/soc/mediatek/common/pcie.c @@ -11,6 +11,7 @@ #include <delay.h> #include <lib.h> #include <soc/addressmap.h> +#include <soc/early_init.h> #include <soc/pcie.h> #include <soc/pcie_common.h> #include <soc/soc_chip.h> @@ -214,6 +215,7 @@ const mtk_soc_config_t *config = config_of(dev); const struct mtk_pcie_config *conf = &config->pcie_config; const char *ltssm_state; + uint64_t perst_time_us; size_t tries = 0; uint32_t val;
@@ -233,6 +235,32 @@ val &= ~PCIE_INTX_ENABLE; write32p(conf->base + PCIE_INT_ENABLE_REG, val);
+ perst_time_us = early_init_get_elapsed_time_us(EARLY_INIT_PCIE); + printk(BIOS_DEBUG, "%s: %lld us elapsed since assert PERST#\n", + __func__, perst_time_us); + + /* + * Described in PCIe CEM specification sections 2.2 + * (PERST# Signal) and 2.2.1 (Initial Power-Up (G3 to S0)). + * The deassertion of PERST# should be delayed 100ms (TPVPERL) + * for the power and clock to become stable. + */ + const uint64_t min_perst_time_us = 100000; /* 100 ms */ + if (perst_time_us < min_perst_time_us) { + if (!perst_time_us) { + printk(BIOS_WARNING, + "%s: PCIe early init data not found, sleeping 100ms\n", + __func__); + mtk_pcie_reset(conf->base + PCIE_RST_CTRL_REG, true); + } else { + printk(BIOS_WARNING, + "%s: Need an extra %lld us delay to meet PERST# deassertion requirement\n", + __func__, min_perst_time_us - perst_time_us); + } + + udelay(min_perst_time_us - perst_time_us); + } + /* De-assert reset signals */ mtk_pcie_reset(conf->base + PCIE_RST_CTRL_REG, false);
diff --git a/src/soc/mediatek/mt8195/pcie.c b/src/soc/mediatek/mt8195/pcie.c index 1a17c6c..df347c0 100644 --- a/src/soc/mediatek/mt8195/pcie.c +++ b/src/soc/mediatek/mt8195/pcie.c @@ -6,6 +6,7 @@ #include <device/resource.h> #include <delay.h> #include <soc/addressmap.h> +#include <soc/early_init.h> #include <soc/gpio.h> #include <soc/pcie.h> #include <soc/pcie_common.h> @@ -72,4 +73,6 @@
/* Assert all reset signals at early stage */ mtk_pcie_reset(PCIE_RST_CTRL_REG, true); + + early_init_save_time(EARLY_INIT_PCIE); }