Loading drivers/gpu/drm/drm_pci.c +49 −0 Original line number Diff line number Diff line Loading @@ -465,3 +465,52 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) DRM_INFO("Module unloaded\n"); } EXPORT_SYMBOL(drm_pci_exit); int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask) { struct pci_dev *root; int pos; u32 lnkcap, lnkcap2; *mask = 0; if (!dev->pdev) return -EINVAL; if (!pci_is_pcie(dev->pdev)) return -EINVAL; root = dev->pdev->bus->self; pos = pci_pcie_cap(root); if (!pos) return -EINVAL; /* we've been informed via and serverworks don't make the cut */ if (root->vendor == PCI_VENDOR_ID_VIA || root->vendor == PCI_VENDOR_ID_SERVERWORKS) return -EINVAL; pci_read_config_dword(root, pos + PCI_EXP_LNKCAP, &lnkcap); pci_read_config_dword(root, pos + PCI_EXP_LNKCAP2, &lnkcap2); lnkcap &= PCI_EXP_LNKCAP_SLS; lnkcap2 &= 0xfe; 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", root->vendor, root->device, lnkcap, lnkcap2); return 0; } EXPORT_SYMBOL(drm_pcie_get_speed_cap_mask); include/drm/drmP.h +5 −0 Original line number Diff line number Diff line Loading @@ -1761,6 +1761,11 @@ extern int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver); #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); /* platform section */ extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device); Loading Loading
drivers/gpu/drm/drm_pci.c +49 −0 Original line number Diff line number Diff line Loading @@ -465,3 +465,52 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) DRM_INFO("Module unloaded\n"); } EXPORT_SYMBOL(drm_pci_exit); int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask) { struct pci_dev *root; int pos; u32 lnkcap, lnkcap2; *mask = 0; if (!dev->pdev) return -EINVAL; if (!pci_is_pcie(dev->pdev)) return -EINVAL; root = dev->pdev->bus->self; pos = pci_pcie_cap(root); if (!pos) return -EINVAL; /* we've been informed via and serverworks don't make the cut */ if (root->vendor == PCI_VENDOR_ID_VIA || root->vendor == PCI_VENDOR_ID_SERVERWORKS) return -EINVAL; pci_read_config_dword(root, pos + PCI_EXP_LNKCAP, &lnkcap); pci_read_config_dword(root, pos + PCI_EXP_LNKCAP2, &lnkcap2); lnkcap &= PCI_EXP_LNKCAP_SLS; lnkcap2 &= 0xfe; 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", root->vendor, root->device, lnkcap, lnkcap2); return 0; } EXPORT_SYMBOL(drm_pcie_get_speed_cap_mask);
include/drm/drmP.h +5 −0 Original line number Diff line number Diff line Loading @@ -1761,6 +1761,11 @@ extern int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver); #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); /* platform section */ extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device); Loading