aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaxon Haws <jaxon.haws@amd.com>2022-10-17 16:09:55 -0500
committerJaxon Haws <jaxon.haws@amd.com>2022-11-16 12:25:58 -0600
commit5c75f737b19d4a21756cc2001cce7ec164731f5a (patch)
tree00813dc7e5824b484401b702b6219d0a08363350
parent9e567a4e5a8ca4bdd097ff6707fc6a517ca8d177 (diff)
downloadpciutils-5c75f737b19d4a21756cc2001cce7ec164731f5a.tar.gz
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 <jaxon.haws@amd.com>
-rw-r--r--lib/header.h11
-rw-r--r--ls-ecaps.c71
2 files changed, 81 insertions, 1 deletions
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
@@ -881,6 +881,75 @@ dvsec_cxl_gpf_device(struct device *d, int where)
}
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)
{
u16 w;
@@ -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);