amdgpu: implement enough to make amdgpu_device_get_pcie_info() mostly work define PCIe link cap and link cap2 speed definitions from PCIe 3.0 7.8.8, and 7.8.18. add some missing values for linux pci_bus_speed, add pcie_link_width, also from 7.8.8. add linux compatible pcie_capability_read_dword() and pcie_get_speed_cap(). with this in place, enable most of the ode in amdgpu_device_get_pcie_info(). still missing: support for pci_is_root_bus() and pcie_bandwidth_available(). diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h index 80d0aff5f82c..02590817f51b 100644 --- a/sys/dev/pci/pcireg.h +++ b/sys/dev/pci/pcireg.h @@ -1002,6 +1002,12 @@ typedef u_int8_t pci_revision_t; #define PCIE_DCSR_EMGPWRREDD __BIT(6 + 16) /* Emg. Pwr. Reduct. Detected */ #define PCIE_LCAP 0x0c /* Link Capabilities Register */ #define PCIE_LCAP_MAX_SPEED __BITS(3, 0) /* Max Link Speed */ +#define PCIE_LCAP_MAX_SPEED_2 __BIT(0) /* 2.5GT/s */ +#define PCIE_LCAP_MAX_SPEED_5 __BIT(1) /* 5GT/s */ +#define PCIE_LCAP_MAX_SPEED_8 __BIT(3) /* 8GT/s */ +#define PCIE_LCAP_MAX_SPEED_16 __BIT(4) /* 16GT/s */ +#define PCIE_LCAP_MAX_SPEED_32 __BIT(5) /* 32GT/s */ +#define PCIE_LCAP_MAX_SPEED_64 __BIT(6) /* 64GT/s */ #define PCIE_LCAP_MAX_WIDTH __BITS(9, 4) /* Maximum Link Width */ #define PCIE_LCAP_ASPM __BITS(11, 10) /* Active State Link PM Supp. */ #define PCIE_LCAP_L0S_EXIT __BITS(14, 12) /* L0s Exit Latency */ @@ -1121,6 +1127,12 @@ typedef u_int8_t pci_revision_t; #define PCIE_DCSR2_EETLP __BIT(15) /* End-End TLP Prefix Blcking */ #define PCIE_LCAP2 0x2c /* Link Capabilities 2 Register */ #define PCIE_LCAP2_SUP_LNKSV __BITS(7, 1) /* Supported Link Speeds Vect */ +#define PCIE_LCAP2_SUP_LNKS2 __BIT(1) /* Supported Speed 2.5GT/ */ +#define PCIE_LCAP2_SUP_LNKS5 __BIT(2) /* Supported Speed 5GT/ */ +#define PCIE_LCAP2_SUP_LNKS8 __BIT(3) /* Supported Speed 8GT/ */ +#define PCIE_LCAP2_SUP_LNKS16 __BIT(4) /* Supported Speed 16GT/ */ +#define PCIE_LCAP2_SUP_LNKS32 __BIT(5) /* Supported Speed 32GT/ */ +#define PCIE_LCAP2_SUP_LNKS64 __BIT(6) /* Supported Speed 64GT/ */ #define PCIE_LCAP2_CROSSLNK __BIT(8) /* Crosslink Supported */ #define PCIE_LCAP2_LOWSKPOS_GENSUPPSV __BITS(15, 9) /* Lower SKP OS Generation Supp. Spd. Vect */ diff --git a/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_device.c b/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_device.c index 91233a3f040f..604db74d68ab 100644 --- a/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_device.c +++ b/sys/external/bsd/drm2/dist/drm/amd/amdgpu/amdgpu_device.c @@ -4446,7 +4446,6 @@ skip_sched_resume: */ 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; @@ -4457,6 +4456,7 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) if (amdgpu_pcie_lane_cap) adev->pm.pcie_mlw_mask = amdgpu_pcie_lane_cap; +#ifndef __NetBSD__ /* XXX amdgpu pcie */ /* covers APUs as well */ if (pci_is_root_bus(adev->pdev->bus)) { if (adev->pm.pcie_gen_mask == 0) @@ -4465,12 +4465,18 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) adev->pm.pcie_mlw_mask = AMDGPU_DEFAULT_PCIE_MLW_MASK; return; } +#endif if (adev->pm.pcie_gen_mask && adev->pm.pcie_mlw_mask) return; +#ifndef __NetBSD__ /* XXX amdgpu pcie */ pcie_bandwidth_available(adev->pdev, NULL, &platform_speed_cap, &platform_link_width); +#else + platform_speed_cap = PCI_SPEED_UNKNOWN; + platform_link_width = PCIE_LNK_WIDTH_UNKNOWN; +#endif if (adev->pm.pcie_gen_mask == 0) { /* asic caps */ @@ -4570,7 +4576,6 @@ static void amdgpu_device_get_pcie_info(struct amdgpu_device *adev) } } } -#endif } int amdgpu_device_baco_enter(struct drm_device *dev) diff --git a/sys/external/bsd/drm2/include/linux/pci.h b/sys/external/bsd/drm2/include/linux/pci.h index 666b7f3741ea..2486fd7d021a 100644 --- a/sys/external/bsd/drm2/include/linux/pci.h +++ b/sys/external/bsd/drm2/include/linux/pci.h @@ -188,8 +188,24 @@ enum pci_bus_speed { PCIE_SPEED_5_0GT, PCIE_SPEED_8_0GT, PCIE_SPEED_16_0GT, + PCIE_SPEED_32_0GT, + PCIE_SPEED_64_0GT, }; +enum pcie_link_width { + PCIE_LNK_X1 = 0x01, + PCIE_LNK_X2 = 0x02, + PCIE_LNK_X4 = 0x04, + PCIE_LNK_X8 = 0x08, + PCIE_LNK_X12 = 0x0c, + PCIE_LNK_X16 = 0x10, + PCIE_LNK_X32 = 0x20, + PCIE_LNK_WIDTH_UNKNOWN = 0xff, +}; + +#define PCI_EXP_LNKCAP PCIE_LCAP +#define PCI_EXP_LNKCAP_CLKPM PCIE_LCAP_CLOCK_PM + #define PCIBIOS_MIN_MEM 0x100000 /* XXX bogus x86 kludge bollocks */ #define __pci_rom_iomem @@ -240,6 +256,8 @@ enum pci_bus_speed { #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_capability_read_dword linux_pcie_capability_read_dword +#define pcie_get_speed_cap linux_pcie_get_speed_cap /* NetBSD local additions. */ void linux_pci_dev_init(struct pci_dev *, device_t, device_t, @@ -329,4 +347,7 @@ dev_is_pci(struct device *dev) return parent && device_is_a(parent, "pci"); } +int pcie_capability_read_dword(struct pci_dev *, int, u32 *); +enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *); + #endif /* _LINUX_PCI_H_ */ diff --git a/sys/external/bsd/drm2/linux/linux_pci.c b/sys/external/bsd/drm2/linux/linux_pci.c index f51ce9636300..e9b1c97f5fda 100644 --- a/sys/external/bsd/drm2/linux/linux_pci.c +++ b/sys/external/bsd/drm2/linux/linux_pci.c @@ -805,3 +805,53 @@ linux_pci_dev_destroy(struct pci_dev *pdev) KASSERT(pdev->pd_saved_state == NULL); KASSERT(pdev->pd_intr_handles == NULL); } + +int +pcie_capability_read_dword(struct pci_dev *pdev, int pos, u32 *val) +{ + + *val = 0; + if (pci_find_capability(pdev, PCI_CAP_PCIEXPRESS) && + pci_read_config_dword(pdev, pos, val)) + return 1; + + return 0; +} + +enum pci_bus_speed +pcie_get_speed_cap(struct pci_dev *pdev) +{ + pcireg_t reg; + + if (pcie_capability_read_dword(pdev, PCIE_LCAP2, ®)) { + switch (reg & PCIE_LCAP2_SUP_LNKSV) { + case PCIE_LCAP2_SUP_LNKS2: + return PCIE_SPEED_2_5GT; + case PCIE_LCAP2_SUP_LNKS5: + return PCIE_SPEED_5_0GT; + case PCIE_LCAP2_SUP_LNKS8: + return PCIE_SPEED_8_0GT; + case PCIE_LCAP2_SUP_LNKS16: + return PCIE_SPEED_16_0GT; + case PCIE_LCAP2_SUP_LNKS32: + return PCIE_SPEED_32_0GT; + case PCIE_LCAP2_SUP_LNKS64: + return PCIE_SPEED_64_0GT; + default: + return PCI_SPEED_UNKNOWN; + } + } + + if (pcie_capability_read_dword(pdev, PCIE_LCAP2, ®)) { + switch (reg & PCIE_LCAP_MAX_SPEED) { + case PCIE_LCAP_MAX_SPEED_2: + return PCIE_SPEED_2_5GT; + case PCIE_LCAP_MAX_SPEED_5: + return PCIE_SPEED_5_0GT; + default: + break; + } + } + + return PCI_SPEED_UNKNOWN; +}