Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys fill out more of the linux pci API compat



details:   https://anonhg.NetBSD.org/src/rev/14a120b74e75
branches:  trunk
changeset: 370173:14a120b74e75
user:      mrg <mrg%NetBSD.org@localhost>
date:      Tue Sep 20 23:01:42 2022 +0000

description:
fill out more of the linux pci API compat

- implement pcie_get_speed_cap(), pcie_bandwidth_available(), and
  pci_is_root_bus().
- expand "enum pci_bus_speed" to add PCIe 5.x and 6.x speeds.
- add "enum pcie_link_width".
- add defines for PCIE_LCSR_LINKSPEED (PCIe generation) and PCIE_LCSR_NLW
  (negotiated lane width) to pcireg.h
- enable amdgpu_device_get_pcie_info() code now it works.

ok riastradh@

diffstat:

 sys/dev/pci/pcireg.h                                      |   15 +-
 sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_device.c |    6 +-
 sys/external/bsd/drm2/include/linux/pci.h                 |   28 ++-
 sys/external/bsd/drm2/linux/linux_pci.c                   |  145 +++++++++++++-
 4 files changed, 184 insertions(+), 10 deletions(-)

diffs (290 lines):

diff -r 05a1191aaf2f -r 14a120b74e75 sys/dev/pci/pcireg.h
--- a/sys/dev/pci/pcireg.h      Tue Sep 20 12:25:01 2022 +0000
+++ b/sys/dev/pci/pcireg.h      Tue Sep 20 23:01:42 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pcireg.h,v 1.165 2022/01/31 10:14:55 msaitoh Exp $     */
+/*     $NetBSD: pcireg.h,v 1.166 2022/09/20 23:01:42 mrg Exp $ */
 
 /*
  * Copyright (c) 1995, 1996, 1999, 2000
@@ -1063,7 +1063,20 @@
 #define PCIE_LCSR_LABIE                __BIT(11)      /* Link Autonomous BW Intr En */
 #define        PCIE_LCSR_DRSSGNL       __BITS(15, 14) /* DRS Signaling */
 #define        PCIE_LCSR_LINKSPEED     __BITS(19, 16) /* Link Speed */
+#define  PCIE_LCSR_LINKSPEED_2 1              /* 2.5GT/s */
+#define  PCIE_LCSR_LINKSPEED_5 2              /* 5GT/s */
+#define  PCIE_LCSR_LINKSPEED_8 3              /* 8GT/s */
+#define  PCIE_LCSR_LINKSPEED_16        4              /* 16GT/s */
+#define  PCIE_LCSR_LINKSPEED_32        5              /* 32GT/s */
+#define  PCIE_LCSR_LINKSPEED_64        6              /* 64GT/s */
 #define        PCIE_LCSR_NLW           __BITS(25, 20) /* Negotiated Link Width */
+#define  PCIE_LCSR_NLW_X1      __BIT(20)       /* Negotiated x1 */
+#define  PCIE_LCSR_NLW_X2      __BIT(21)       /* Negotiated x2 */
+#define  PCIE_LCSR_NLW_X4      __BIT(22)       /* Negotiated x4 */
+#define  PCIE_LCSR_NLW_X8      __BIT(23)       /* Negotiated x8 */
+#define  PCIE_LCSR_NLW_X12     __BITS(22, 23)  /* Negotiated x12 */
+#define  PCIE_LCSR_NLW_X16     __BIT(24)       /* Negotiated x16 */
+#define  PCIE_LCSR_NLW_X32     __BIT(25)       /* Negotiated x32 */
 #define        PCIE_LCSR_LINKTRAIN_ERR __BIT(10 + 16) /* Link Training Error */
 #define        PCIE_LCSR_LINKTRAIN     __BIT(11 + 16) /* Link Training */
 #define        PCIE_LCSR_SLOTCLKCFG    __BIT(12 + 16) /* Slot Clock Configuration */
diff -r 05a1191aaf2f -r 14a120b74e75 sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_device.c
--- a/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_device.c Tue Sep 20 12:25:01 2022 +0000
+++ b/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_device.c Tue Sep 20 23:01:42 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: amdgpu_device.c,v 1.16 2021/12/19 12:41:33 riastradh Exp $     */
+/*     $NetBSD: amdgpu_device.c,v 1.17 2022/09/20 23:01:42 mrg Exp $   */
 
 /*
  * Copyright 2008 Advanced Micro Devices, Inc.
@@ -28,7 +28,7 @@
  *          Jerome Glisse
  */
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: amdgpu_device.c,v 1.16 2021/12/19 12:41:33 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: amdgpu_device.c,v 1.17 2022/09/20 23:01:42 mrg Exp $");
 
 #include <linux/power_supply.h>
 #include <linux/kthread.h>
@@ -4447,7 +4447,6 @@
  */
 static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev)
 {
-#ifndef __NetBSD__             /* XXX amdgpu pcie */
        struct pci_dev *pdev;
        enum pci_bus_speed speed_cap, platform_speed_cap;
        enum pcie_link_width platform_link_width;
@@ -4571,7 +4570,6 @@
                        }
                }
        }
-#endif
 }
 
 int amdgpu_device_baco_enter(struct drm_device *dev)
diff -r 05a1191aaf2f -r 14a120b74e75 sys/external/bsd/drm2/include/linux/pci.h
--- a/sys/external/bsd/drm2/include/linux/pci.h Tue Sep 20 12:25:01 2022 +0000
+++ b/sys/external/bsd/drm2/include/linux/pci.h Tue Sep 20 23:01:42 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pci.h,v 1.53 2022/02/27 14:23:08 riastradh Exp $       */
+/*     $NetBSD: pci.h,v 1.54 2022/09/20 23:01:42 mrg Exp $     */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -190,6 +190,24 @@
        PCIE_SPEED_5_0GT,
        PCIE_SPEED_8_0GT,
        PCIE_SPEED_16_0GT,
+       PCIE_SPEED_32_0GT,
+       PCIE_SPEED_64_0GT,
+};
+
+/*
+ * Actually values from the Link Status register, bits 16-19.  Don't use
+ * these as a bit-mask -- these are the only known, valid values.
+ */
+enum pcie_link_width {
+       PCIE_LNK_WIDTH_RESRV   = 0,
+       PCIE_LNK_X1            = __BIT(0),
+       PCIE_LNK_X2            = __BIT(1),
+       PCIE_LNK_X4            = __BIT(2),
+       PCIE_LNK_X8            = __BIT(3),
+       PCIE_LNK_X12           = __BITS(2,3),
+       PCIE_LNK_X16           = __BIT(4),
+       PCIE_LNK_X32           = __BIT(5),
+       PCIE_LNK_WIDTH_UNKNOWN = __BITS(0, 7),
 };
 
 #define        PCIBIOS_MIN_MEM 0x100000        /* XXX bogus x86 kludge bollocks */
@@ -242,6 +260,8 @@
 #define        pci_write_config_dword          linux_pci_write_config_dword
 #define        pci_write_config_word           linux_pci_write_config_word
 #define        pcibios_align_resource          linux_pcibios_align_resource
+#define        pcie_get_speed_cap              linux_pcie_get_speed_cap
+#define        pcie_bandwidth_available        linux_pcie_bandwidth_available
 
 /* NetBSD local additions.  */
 void           linux_pci_dev_init(struct pci_dev *, device_t, device_t,
@@ -323,6 +343,12 @@
 void           pci_save_state(struct pci_dev *);
 void           pci_restore_state(struct pci_dev *);
 
+enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev);
+unsigned       pcie_bandwidth_available(struct pci_dev *dev,
+                                        struct pci_dev **limiting_dev,
+                                        enum pci_bus_speed *speed,
+                                        enum pcie_link_width *width);
+
 static inline bool
 dev_is_pci(struct device *dev)
 {
diff -r 05a1191aaf2f -r 14a120b74e75 sys/external/bsd/drm2/linux/linux_pci.c
--- a/sys/external/bsd/drm2/linux/linux_pci.c   Tue Sep 20 12:25:01 2022 +0000
+++ b/sys/external/bsd/drm2/linux/linux_pci.c   Tue Sep 20 23:01:42 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: linux_pci.c,v 1.23 2022/07/20 01:20:20 riastradh Exp $ */
+/*     $NetBSD: linux_pci.c,v 1.24 2022/09/20 23:01:42 mrg Exp $       */
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_pci.c,v 1.23 2022/07/20 01:20:20 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_pci.c,v 1.24 2022/09/20 23:01:42 mrg Exp $");
 
 #if NACPICA > 0
 #include <dev/acpi/acpivar.h>
@@ -716,8 +716,7 @@
 pci_is_root_bus(struct pci_bus *bus)
 {
 
-       /* XXX Cop-out. */
-       return false;
+       return bus->number == 0;
 }
 
 int
@@ -800,3 +799,141 @@
        KASSERT(pdev->pd_saved_state == NULL);
        KASSERT(pdev->pd_intr_handles == NULL);
 }
+
+enum pci_bus_speed
+pcie_get_speed_cap(struct pci_dev *dev)
+{
+       pci_chipset_tag_t pc = dev->pd_pa.pa_pc;
+       pcitag_t tag = dev->pd_pa.pa_tag;
+       pcireg_t lcap, lcap2, xcap;
+       int off;
+
+       /* Must have capabilities. */
+       if (pci_get_capability(pc, tag, PCI_CAP_PCIEXPRESS, &off, NULL) == 0)
+               return PCI_SPEED_UNKNOWN;
+
+       /* Only PCIe 3.x has LCAP2. */
+       xcap = pci_conf_read(pc, tag, off + PCIE_XCAP);
+       if (__SHIFTOUT(xcap, PCIE_XCAP_VER_MASK) >= 2) {
+               lcap2 = pci_conf_read(pc, tag, off + PCIE_LCAP2);
+               if (lcap2) {
+                       if ((lcap2 & PCIE_LCAP2_SUP_LNKS64) != 0) {
+                               return PCIE_SPEED_64_0GT;
+                       }
+                       if ((lcap2 & PCIE_LCAP2_SUP_LNKS32) != 0) {
+                               return PCIE_SPEED_32_0GT;
+                       }
+                       if ((lcap2 & PCIE_LCAP2_SUP_LNKS16) != 0) {
+                               return PCIE_SPEED_16_0GT;
+                       }
+                       if ((lcap2 & PCIE_LCAP2_SUP_LNKS8) != 0) {
+                               return PCIE_SPEED_8_0GT;
+                       }
+                       if ((lcap2 & PCIE_LCAP2_SUP_LNKS5) != 0) {
+                               return PCIE_SPEED_5_0GT;
+                       }
+                       if ((lcap2 & PCIE_LCAP2_SUP_LNKS2) != 0) {
+                               return PCIE_SPEED_2_5GT;
+                       }
+               }
+       }
+
+       lcap = pci_conf_read(pc, tag, off + PCIE_LCAP);
+       if ((lcap & PCIE_LCAP_MAX_SPEED) == PCIE_LCAP_MAX_SPEED_64) {
+               return PCIE_SPEED_64_0GT;
+       }
+       if ((lcap & PCIE_LCAP_MAX_SPEED) == PCIE_LCAP_MAX_SPEED_32) {
+               return PCIE_SPEED_32_0GT;
+       }
+       if ((lcap & PCIE_LCAP_MAX_SPEED) == PCIE_LCAP_MAX_SPEED_16) {
+               return PCIE_SPEED_16_0GT;
+       }
+       if ((lcap & PCIE_LCAP_MAX_SPEED) == PCIE_LCAP_MAX_SPEED_8) {
+               return PCIE_SPEED_8_0GT;
+       }
+       if ((lcap & PCIE_LCAP_MAX_SPEED) == PCIE_LCAP_MAX_SPEED_5) {
+               return PCIE_SPEED_5_0GT;
+       }
+       if ((lcap & PCIE_LCAP_MAX_SPEED) == PCIE_LCAP_MAX_SPEED_2) {
+               return PCIE_SPEED_2_5GT;
+       }
+
+       return PCI_SPEED_UNKNOWN;
+}
+
+/*
+ * This should walk the tree, it only checks this device currently.
+ * It also does not write to limiting_dev (the only caller in drm2
+ * currently does not use it.)
+ */
+unsigned
+pcie_bandwidth_available(struct pci_dev *dev,
+    struct pci_dev **limiting_dev,
+    enum pci_bus_speed *speed,
+    enum pcie_link_width *width)
+{
+       pci_chipset_tag_t pc = dev->pd_pa.pa_pc;
+       pcitag_t tag = dev->pd_pa.pa_tag;
+       pcireg_t lcsr;
+       unsigned per_line_speed, num_lanes;
+       int off;
+
+       /* Must have capabilities. */
+       if (pci_get_capability(pc, tag, PCI_CAP_PCIEXPRESS, &off, NULL) == 0)
+               return 0;
+
+       if (speed)
+               *speed = PCI_SPEED_UNKNOWN;
+       if (width)
+               *width = 0;
+
+       lcsr = pci_conf_read(pc, tag, off + PCIE_LCSR);
+
+       switch (lcsr & PCIE_LCSR_NLW) {
+       case PCIE_LCSR_NLW_X1:
+       case PCIE_LCSR_NLW_X2:
+       case PCIE_LCSR_NLW_X4:
+       case PCIE_LCSR_NLW_X8:
+       case PCIE_LCSR_NLW_X12:
+       case PCIE_LCSR_NLW_X16:
+       case PCIE_LCSR_NLW_X32:
+               num_lanes = __SHIFTOUT(lcsr, PCIE_LCSR_NLW);
+               if (width)
+                       *width = num_lanes;
+               break;
+       default:
+               num_lanes = 0;
+               break;
+       }
+
+       switch (__SHIFTOUT(lcsr, PCIE_LCSR_LINKSPEED)) {
+       case PCIE_LCSR_LINKSPEED_2:
+               *speed = PCIE_SPEED_2_5GT;
+               per_line_speed = 2500 * 8 / 10;
+               break;
+       case PCIE_LCSR_LINKSPEED_5:
+               *speed = PCIE_SPEED_5_0GT;
+               per_line_speed = 5000 * 8 / 10;
+               break;
+       case PCIE_LCSR_LINKSPEED_8:
+               *speed = PCIE_SPEED_8_0GT;
+               per_line_speed = 8000 * 128 / 130;
+               break;
+       case PCIE_LCSR_LINKSPEED_16:
+               *speed = PCIE_SPEED_16_0GT;
+               per_line_speed = 16000 * 128 / 130;
+               break;
+       case PCIE_LCSR_LINKSPEED_32:
+               *speed = PCIE_SPEED_32_0GT;
+               per_line_speed = 32000 * 128 / 130;
+               break;
+       case PCIE_LCSR_LINKSPEED_64:
+               *speed = PCIE_SPEED_64_0GT;
+               per_line_speed = 64000 * 128 / 130;
+               break;
+       default:
+               per_line_speed = 0;
+       }
+
+       return num_lanes * per_line_speed;
+}



Home | Main Index | Thread Index | Old Index