CXL rev3.0 8.1.3.8.2 Memory_Info_valid field The Memory_Info_Valid bit indicates that the CXL Range Size High and Size Low registers are valid. The bit must be set within 1 second of reset deassertion to the device. Check valid bit before we check the Memory_Active bit when waiting for cxl_await_media_ready() to ensure that the memory info is valid for consumption. Signed-off-by: Dave Jiang <dave.jiang@xxxxxxxxx> --- drivers/cxl/core/pci.c | 25 +++++++++++++++++++++++-- drivers/cxl/port.c | 20 ++++++++++---------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c index 54ac6f8825ff..79a1348e7b98 100644 --- a/drivers/cxl/core/pci.c +++ b/drivers/cxl/core/pci.c @@ -111,11 +111,32 @@ int cxl_await_media_ready(struct cxl_dev_state *cxlds) int d = cxlds->cxl_dvsec; bool active = false; u64 md_status; + u32 temp; int rc, i; - for (i = media_ready_timeout; i; i--) { - u32 temp; + /* Check MEM INFO VALID bit first, give up after 1s */ + i = 1; + do { + rc = pci_read_config_dword(pdev, + d + CXL_DVSEC_RANGE_SIZE_LOW(0), + &temp); + if (rc) + return rc; + active = FIELD_GET(CXL_DVSEC_MEM_INFO_VALID, temp); + if (active) + break; + msleep(1000); + } while (i--); + + if (!active) { + dev_err(&pdev->dev, + "timeout awaiting memory valid after 1 second.\n"); + return -ETIMEDOUT; + } + + /* Check MEM ACTIVE bit, up to 60s timeout by default */ + for (i = media_ready_timeout; i; i--) { rc = pci_read_config_dword( pdev, d + CXL_DVSEC_RANGE_SIZE_LOW(0), &temp); if (rc) diff --git a/drivers/cxl/port.c b/drivers/cxl/port.c index d72e38f9ae44..03380c18fc52 100644 --- a/drivers/cxl/port.c +++ b/drivers/cxl/port.c @@ -99,6 +99,16 @@ static int cxl_port_probe(struct device *dev) if (rc) return rc; + rc = cxl_hdm_decode_init(cxlds, cxlhdm); + if (rc) + return rc; + + rc = cxl_await_media_ready(cxlds); + if (rc) { + dev_err(dev, "Media not active (%d)\n", rc); + return rc; + } + if (port->cdat.table) { rc = cdat_table_parse_dsmas(port->cdat.table, cxl_dsmas_parse_entry, @@ -117,16 +127,6 @@ static int cxl_port_probe(struct device *dev) if (rc) dev_dbg(dev, "Failed to do QoS calculations\n"); } - - rc = cxl_hdm_decode_init(cxlds, cxlhdm); - if (rc) - return rc; - - rc = cxl_await_media_ready(cxlds); - if (rc) { - dev_err(dev, "Media not active (%d)\n", rc); - return rc; - } } rc = devm_cxl_enumerate_decoders(cxlhdm);