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