]> git.ipfire.org Git - thirdparty/pciutils.git/commitdiff
lspci: Add support for CXL GPF Device DVSEC
authorJaxon Haws <jaxon.haws@amd.com>
Mon, 17 Oct 2022 20:29:41 +0000 (15:29 -0500)
committerJaxon Haws <jaxon.haws@amd.com>
Wed, 2 Nov 2022 17:30:29 +0000 (12:30 -0500)
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 <jaxon.haws@amd.com>
lib/header.h
ls-ecaps.c

index e74f6d80e8c00c22b1636e50f7fd76aceb6bb8dd..36b7040affdce70f1b08085e41d8cfaee2c06858 100644 (file)
 /* 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 */
index b9a451283dba34a2431b9b48b9d77ffda8f16294..af71c63689bf19e41af7d9a8a4e2780b1e778330 100644 (file)
@@ -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");