pci.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // SPDX-License-Identifier: BSD-3-Clause-Clear
  2. /*
  3. * Copyright (C) 2019 Lorenzo Bianconi <lorenzo@kernel.org>
  4. */
  5. #include "mt76.h"
  6. #include <linux/pci.h>
  7. void mt76_pci_disable_aspm(struct pci_dev *pdev)
  8. {
  9. struct pci_dev *parent = pdev->bus->self;
  10. u16 aspm_conf, parent_aspm_conf = 0;
  11. pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &aspm_conf);
  12. aspm_conf &= PCI_EXP_LNKCTL_ASPMC;
  13. if (parent) {
  14. pcie_capability_read_word(parent, PCI_EXP_LNKCTL,
  15. &parent_aspm_conf);
  16. parent_aspm_conf &= PCI_EXP_LNKCTL_ASPMC;
  17. }
  18. if (!aspm_conf && (!parent || !parent_aspm_conf)) {
  19. /* aspm already disabled */
  20. return;
  21. }
  22. dev_info(&pdev->dev, "disabling ASPM %s %s\n",
  23. (aspm_conf & PCI_EXP_LNKCTL_ASPM_L0S) ? "L0s" : "",
  24. (aspm_conf & PCI_EXP_LNKCTL_ASPM_L1) ? "L1" : "");
  25. if (IS_ENABLED(CONFIG_PCIEASPM)) {
  26. int err;
  27. err = pci_disable_link_state(pdev, aspm_conf);
  28. if (!err)
  29. return;
  30. }
  31. /* both device and parent should have the same ASPM setting.
  32. * disable ASPM in downstream component first and then upstream.
  33. */
  34. pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, aspm_conf);
  35. if (parent)
  36. pcie_capability_clear_word(parent, PCI_EXP_LNKCTL,
  37. aspm_conf);
  38. }
  39. EXPORT_SYMBOL_GPL(mt76_pci_disable_aspm);
  40. bool mt76_pci_aspm_supported(struct pci_dev *pdev)
  41. {
  42. struct pci_dev *parent = pdev->bus->self;
  43. u16 aspm_conf, parent_aspm_conf = 0;
  44. bool result = true;
  45. pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &aspm_conf);
  46. aspm_conf &= PCI_EXP_LNKCTL_ASPMC;
  47. if (parent) {
  48. pcie_capability_read_word(parent, PCI_EXP_LNKCTL,
  49. &parent_aspm_conf);
  50. parent_aspm_conf &= PCI_EXP_LNKCTL_ASPMC;
  51. }
  52. if (!aspm_conf && (!parent || !parent_aspm_conf)) {
  53. /* aspm already disabled */
  54. result = false;
  55. }
  56. return result;
  57. }
  58. EXPORT_SYMBOL_GPL(mt76_pci_aspm_supported);