From 5c75f737b19d4a21756cc2001cce7ec164731f5a Mon Sep 17 00:00:00 2001 From: Jaxon Haws Date: Mon, 17 Oct 2022 16:09:55 -0500 Subject: lspci: Add support for CXL GPF Port DVSEC Add Global Persistent Flush DVSEC decoding for CXL port according to DVSEC Revision ID 0. Decode GPF Phase 1 Control and GPF Phase 2 Control. Signed-off-by: Jaxon Haws --- lib/header.h | 11 ++++++++++ ls-ecaps.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/lib/header.h b/lib/header.h index cc69a51..5dbd8ac 100644 --- a/lib/header.h +++ b/lib/header.h @@ -1141,6 +1141,17 @@ #define PCI_CXL_GPF_DEV_100MS 0x5 #define PCI_CXL_GPF_DEV_1S 0x6 #define PCI_CXL_GPF_DEV_10S 0x7 +#define PCI_CXL_GPF_PORT_LEN 0x10 +#define PCI_CXL_GPF_PORT_PHASE1_CTRL 0x0c /* GPF Phase 1 Control Register */ +#define PCI_CXL_GPF_PORT_PHASE2_CTRL 0x0e /* GPF Phase 2 Control Register */ +#define PCI_CXL_GPF_PORT_1US 0x0 +#define PCI_CXL_GPF_PORT_10US 0x1 +#define PCI_CXL_GPF_PORT_100US 0x2 +#define PCI_CXL_GPF_PORT_1MS 0x3 +#define PCI_CXL_GPF_PORT_10MS 0x4 +#define PCI_CXL_GPF_PORT_100MS 0x5 +#define PCI_CXL_GPF_PORT_1S 0x6 +#define PCI_CXL_GPF_PORT_10S 0x7 /* PCIe CXL Designated Vendor-Specific Capabilities for Flex Bus Port */ #define PCI_CXL_FB_LEN 0x20 diff --git a/ls-ecaps.c b/ls-ecaps.c index abfc30c..32108cd 100644 --- a/ls-ecaps.c +++ b/ls-ecaps.c @@ -880,6 +880,75 @@ dvsec_cxl_gpf_device(struct device *d, int where) printf("\t\tGPF Phase 2 Power: %umW\n", (unsigned int)l); } +static void +dvsec_cxl_gpf_port(struct device *d, int where) +{ + u16 w, timeout; + u8 time_base, time_scale; + + w = get_conf_word(d, where + PCI_CXL_GPF_PORT_PHASE1_CTRL); + time_base = BITS(w, 0, 4); + time_scale = BITS(w, 8, 4); + + switch (time_scale) + { + case PCI_CXL_GPF_PORT_100US: + case PCI_CXL_GPF_PORT_100MS: + timeout = time_base * 100; + break; + case PCI_CXL_GPF_PORT_10US: + case PCI_CXL_GPF_PORT_10MS: + case PCI_CXL_GPF_PORT_10S: + timeout = time_base * 10; + break; + case PCI_CXL_GPF_PORT_1US: + case PCI_CXL_GPF_PORT_1MS: + case PCI_CXL_GPF_PORT_1S: + timeout = time_base; + break; + default: + /* Reserved */ + printf("\t\tReserved time scale encoding %x\n", time_scale); + timeout = time_base; + } + + printf("\t\tGPF Phase 1 Timeout: %d%s\n", timeout, + (time_scale < PCI_CXL_GPF_PORT_1MS) ? "us": + (time_scale < PCI_CXL_GPF_PORT_1S) ? "ms" : + (time_scale == PCI_CXL_GPF_PORT_1S) ? "s" : ""); + + w = get_conf_word(d, where + PCI_CXL_GPF_PORT_PHASE2_CTRL); + time_base = BITS(w, 0, 4); + time_scale = BITS(w, 8, 4); + + switch (time_scale) + { + case PCI_CXL_GPF_PORT_100US: + case PCI_CXL_GPF_PORT_100MS: + timeout = time_base * 100; + break; + case PCI_CXL_GPF_PORT_10US: + case PCI_CXL_GPF_PORT_10MS: + case PCI_CXL_GPF_PORT_10S: + timeout = time_base * 10; + break; + case PCI_CXL_GPF_PORT_1US: + case PCI_CXL_GPF_PORT_1MS: + case PCI_CXL_GPF_PORT_1S: + timeout = time_base; + break; + default: + /* Reserved */ + printf("\t\tReserved time scale encoding %x\n", time_scale); + timeout = time_base; + } + + printf("\t\tGPF Phase 2 Timeout: %d%s\n", timeout, + (time_scale < PCI_CXL_GPF_PORT_1MS) ? "us": + (time_scale < PCI_CXL_GPF_PORT_1S) ? "ms" : + (time_scale == PCI_CXL_GPF_PORT_1S) ? "s" : ""); +} + static void dvsec_cxl_flex_bus(struct device *d, int where, int rev) { @@ -967,7 +1036,7 @@ cap_dvsec_cxl(struct device *d, int id, int rev, int where, int len) dvsec_cxl_port(d, where, len); break; case 4: - printf("\t\tGPF DVSEC for Port\n"); + dvsec_cxl_gpf_port(d, where); break; case 5: dvsec_cxl_gpf_device(d, where); -- cgit 1.2.3-korg