drm: Import drm_pcie_get_speed_cap_mask() in drm_pci.c

This comes with several PCI_VENDOR_ID_* defines which should go in a
more central place.
This commit is contained in:
Jean-Sébastien Pédron 2013-08-25 11:34:37 +00:00
parent 85e8977a2c
commit e27c6c9fa2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=254848
2 changed files with 67 additions and 0 deletions

View File

@ -1421,5 +1421,22 @@ do { \
#define EREMOTEIO ENXIO
#define ERESTARTSYS ERESTART
#define PCI_VENDOR_ID_APPLE 0x106b
#define PCI_VENDOR_ID_ASUSTEK 0x1043
#define PCI_VENDOR_ID_ATI 0x1002
#define PCI_VENDOR_ID_DELL 0x1028
#define PCI_VENDOR_ID_HP 0x103c
#define PCI_VENDOR_ID_IBM 0x1014
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_VENDOR_ID_SERVERWORKS 0x1166
#define PCI_VENDOR_ID_SONY 0x104d
#define PCI_VENDOR_ID_VIA 0x1106
#define DRM_PCIE_SPEED_25 1
#define DRM_PCIE_SPEED_50 2
#define DRM_PCIE_SPEED_80 4
extern int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *speed_mask);
#endif /* __KERNEL__ */
#endif /* _DRM_P_H_ */

View File

@ -123,3 +123,53 @@ drm_pci_free(struct drm_device *dev, drm_dma_handle_t *dmah)
}
/*@}*/
int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask)
{
device_t root;
int pos;
u32 lnkcap = 0, lnkcap2 = 0;
*mask = 0;
if (!drm_device_is_pcie(dev))
return -EINVAL;
root = device_get_parent(dev->device);
pos = 0;
pci_find_cap(root, PCIY_EXPRESS, &pos);
if (!pos)
return -EINVAL;
/* we've been informed via and serverworks don't make the cut */
if (pci_get_vendor(root) == PCI_VENDOR_ID_VIA ||
pci_get_vendor(root) == PCI_VENDOR_ID_SERVERWORKS)
return -EINVAL;
lnkcap = pci_read_config(root, pos + PCIER_LINK_CAP, 4);
lnkcap2 = pci_read_config(root, pos + PCIER_LINK_CAP2, 4);
lnkcap &= PCIEM_LINK_CAP_MAX_SPEED;
lnkcap2 &= 0xfe;
#define PCI_EXP_LNKCAP2_SLS_2_5GB 0x02 /* Supported Link Speed 2.5GT/s */
#define PCI_EXP_LNKCAP2_SLS_5_0GB 0x04 /* Supported Link Speed 5.0GT/s */
#define PCI_EXP_LNKCAP2_SLS_8_0GB 0x08 /* Supported Link Speed 8.0GT/s */
if (lnkcap2) { /* PCIE GEN 3.0 */
if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB)
*mask |= DRM_PCIE_SPEED_25;
if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB)
*mask |= DRM_PCIE_SPEED_50;
if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB)
*mask |= DRM_PCIE_SPEED_80;
} else {
if (lnkcap & 1)
*mask |= DRM_PCIE_SPEED_25;
if (lnkcap & 2)
*mask |= DRM_PCIE_SPEED_50;
}
DRM_INFO("probing gen 2 caps for device %x:%x = %x/%x\n", pci_get_vendor(root), pci_get_device(root), lnkcap, lnkcap2);
return 0;
}