From d462e89c81b9bb0986087abf30a8ea62dcc123a3 Mon Sep 17 00:00:00 2001 From: Jaxon Haws Date: Mon, 17 Oct 2022 15:29:41 -0500 Subject: [PATCH] lspci: Add support for CXL GPF Device DVSEC Add Global Persistent Flush DVSEC decoding for CXL device according to DVSEC Revision ID 0. Decode GPF Phase 2 Duration and GPF Phase 2 Power. Signed-off-by: Jaxon Haws --- lib/header.h | 13 +++++++++++++ ls-ecaps.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/lib/header.h b/lib/header.h index e74f6d8..36b7040 100644 --- a/lib/header.h +++ b/lib/header.h @@ -1129,6 +1129,19 @@ /* PCIe CXL 2.0 Designated Vendor-Specific Capabilities for Register Locator */ #define PCI_CXL_RL_BLOCK1_LO 0x0c +/* PCIe CXL Designated Vendor-Specific Capabilities for Global Persistent Flush */ +#define PCI_CXL_GPF_DEV_LEN 0x10 +#define PCI_CXL_GPF_DEV_PHASE2_DUR 0x0a /* GPF Phase 2 Duration Register */ +#define PCI_CXL_GPF_DEV_PHASE2_POW 0x0c /* GPF Phase 2 Power Register */ +#define PCI_CXL_GPF_DEV_1US 0x0 +#define PCI_CXL_GPF_DEV_10US 0x1 +#define PCI_CXL_GPF_DEV_100US 0x2 +#define PCI_CXL_GPF_DEV_1MS 0x3 +#define PCI_CXL_GPF_DEV_10MS 0x4 +#define PCI_CXL_GPF_DEV_100MS 0x5 +#define PCI_CXL_GPF_DEV_1S 0x6 +#define PCI_CXL_GPF_DEV_10S 0x7 + /* Access Control Services */ #define PCI_ACS_CAP 0x04 /* ACS Capability Register */ #define PCI_ACS_CAP_VALID 0x0001 /* ACS Source Validation */ diff --git a/ls-ecaps.c b/ls-ecaps.c index b9a4512..af71c63 100644 --- a/ls-ecaps.c +++ b/ls-ecaps.c @@ -838,6 +838,48 @@ dvsec_cxl_register_locator(struct device *d, int where, int len) } } +static void +dvsec_cxl_gpf_device(struct device *d, int where) +{ + u32 l; + u16 w, duration; + u8 time_base, time_scale; + + w = get_conf_word(d, where + PCI_CXL_GPF_DEV_PHASE2_DUR); + time_base = BITS(w, 0, 4); + time_scale = BITS(w, 8, 4); + + switch (time_scale) + { + case PCI_CXL_GPF_DEV_100US: + case PCI_CXL_GPF_DEV_100MS: + duration = time_base * 100; + break; + case PCI_CXL_GPF_DEV_10US: + case PCI_CXL_GPF_DEV_10MS: + case PCI_CXL_GPF_DEV_10S: + duration = time_base * 10; + break; + case PCI_CXL_GPF_DEV_1US: + case PCI_CXL_GPF_DEV_1MS: + case PCI_CXL_GPF_DEV_1S: + duration = time_base; + break; + default: + /* Reserved */ + printf("\t\tReserved time scale encoding %x\n", time_scale); + duration = time_base; + } + + printf("\t\tGPF Phase 2 Duration: %u%s\n", duration, + (time_scale < PCI_CXL_GPF_DEV_1MS) ? "us": + (time_scale < PCI_CXL_GPF_DEV_1S) ? "ms" : + (time_scale == PCI_CXL_GPF_DEV_1S) ? "s" : ""); + + l = get_conf_long(d, where + PCI_CXL_GPF_DEV_PHASE2_POW); + printf("\t\tGPF Phase 2 Power: %umW\n", (unsigned int)l); +} + static void cap_dvsec_cxl(struct device *d, int id, int rev, int where, int len) { @@ -863,7 +905,7 @@ cap_dvsec_cxl(struct device *d, int id, int rev, int where, int len) printf("\t\tGPF DVSEC for Port\n"); break; case 5: - printf("\t\tGPF DVSEC for Device\n"); + dvsec_cxl_gpf_device(d, where); break; case 7: printf("\t\tPCIe DVSEC Flex Bus Port\n"); -- 2.39.2