diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2013-08-27 03:18:46 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2013-08-27 03:18:46 +0000 |
commit | dff1b3b14e353b48eb49f0cb0cebea2c565dc587 (patch) | |
tree | 48c45eec940f885df170c94d48f30f4738fc0529 | |
parent | 2d5f4a32de6c16a05825dbbac9af884942af82b7 (diff) |
implement drm_pcie_get_speed_cap_mask()
non integrated radeon >= r600 parts will now try to enable PCIe 2.0/3.0
speeds when the PCIe root port advertises the relevant speeds.
-rw-r--r-- | sys/dev/pci/drm/drm_drv.c | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/sys/dev/pci/drm/drm_drv.c b/sys/dev/pci/drm/drm_drv.c index 92d95dd2f57..ba9f30cddc5 100644 --- a/sys/dev/pci/drm/drm_drv.c +++ b/sys/dev/pci/drm/drm_drv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: drm_drv.c,v 1.112 2013/08/27 03:06:03 jsg Exp $ */ +/* $OpenBSD: drm_drv.c,v 1.113 2013/08/27 03:18:45 jsg Exp $ */ /*- * Copyright 2007-2009 Owain G. Ainsworth <oga@openbsd.org> * Copyright © 2008 Intel Corporation @@ -1830,43 +1830,43 @@ again: int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask) { - printf("%s stub\n", __func__); - return -EINVAL; -#ifdef notyet - struct pci_dev *root; - int pos; - u32 lnkcap = 0, lnkcap2 = 0; + pci_chipset_tag_t pc = dev->pc; + pcitag_t tag; + int pos ; + pcireg_t xcap, lnkcap = 0, lnkcap2 = 0; + pcireg_t id; *mask = 0; - if (!dev->pdev) - return -EINVAL; - if (!pci_is_pcie(dev->pdev)) + if (dev->bridgetag == NULL) return -EINVAL; + tag = *dev->bridgetag; - root = dev->pdev->bus->self; - - pos = pci_pcie_cap(root); - if (!pos) + if (!pci_get_capability(pc, tag, PCI_CAP_PCIEXPRESS, + &pos, NULL)) return -EINVAL; + id = pci_conf_read(pc, tag, PCI_ID_REG); + /* 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) + if (PCI_VENDOR(id) == PCI_VENDOR_VIATECH || + PCI_VENDOR(id) == PCI_VENDOR_RCC) return -EINVAL; - pci_read_config_dword(root, pos + PCI_EXP_LNKCAP, &lnkcap); - pci_read_config_dword(root, pos + PCI_EXP_LNKCAP2, &lnkcap2); + lnkcap = pci_conf_read(pc, tag, pos + PCI_PCIE_LCAP); + xcap = pci_conf_read(pc, tag, pos + PCI_PCIE_XCAP); + if (PCI_PCIE_XCAP_VER(xcap) >= 2) + lnkcap2 = pci_conf_read(pc, tag, pos + PCI_PCIE_LCAP2); - lnkcap &= PCI_EXP_LNKCAP_SLS; + lnkcap &= 0x0f; lnkcap2 &= 0xfe; if (lnkcap2) { /* PCIE GEN 3.0 */ - if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_2_5GB) + if (lnkcap2 & 2) *mask |= DRM_PCIE_SPEED_25; - if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_5_0GB) + if (lnkcap2 & 4) *mask |= DRM_PCIE_SPEED_50; - if (lnkcap2 & PCI_EXP_LNKCAP2_SLS_8_0GB) + if (lnkcap2 & 8) *mask |= DRM_PCIE_SPEED_80; } else { if (lnkcap & 1) @@ -1875,9 +1875,9 @@ int drm_pcie_get_speed_cap_mask(struct drm_device *dev, u32 *mask) *mask |= DRM_PCIE_SPEED_50; } - DRM_INFO("probing gen 2 caps for device %x:%x = %x/%x\n", root->vendor, root->device, lnkcap, lnkcap2); + DRM_INFO("probing gen 2 caps for device 0x%04x:0x%04x = %x/%x\n", + PCI_VENDOR(id), PCI_PRODUCT(id), lnkcap, lnkcap2); return 0; -#endif } int |