summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2024-08-10 20:20:51 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2024-08-10 20:20:51 +0000
commitcde60ccdd163ade80e42aa1c16aa93f1f09e1e40 (patch)
tree1f1dae2bf1f173d383755024eb29eafb404997f0
parent19e8cdbd12164b01ee8150a2963f2f5fa95517af (diff)
Some AMD Ryzen xHCI controllers need a bit more time to transition from D3
into D0. Fixes xhci(4) issues after resume. ok deraadt@
-rw-r--r--sys/dev/pci/pci.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index cd35953deae..463a3df1cad 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pci.c,v 1.128 2024/03/18 21:20:46 kettenis Exp $ */
+/* $OpenBSD: pci.c,v 1.129 2024/08/10 20:20:50 kettenis Exp $ */
/* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */
/*
@@ -752,8 +752,22 @@ pci_get_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
int
pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int state)
{
- pcireg_t reg;
+ pcireg_t id, reg;
int offset, ostate = state;
+ int d3_delay = 10 * 1000;
+
+ /* Some AMD Ryzen xHCI controllers need a bit more time to wake up. */
+ id = pci_conf_read(pc, tag, PCI_ID_REG);
+ if (PCI_VENDOR(id) == PCI_VENDOR_AMD) {
+ switch (PCI_PRODUCT(id)) {
+ case PCI_PRODUCT_AMD_17_1X_XHCI_1:
+ case PCI_PRODUCT_AMD_17_1X_XHCI_2:
+ case PCI_PRODUCT_AMD_17_6X_XHCI:
+ d3_delay = 20 * 1000;
+ default:
+ break;
+ }
+ }
/*
* Warn the firmware that we are going to put the device
@@ -783,7 +797,7 @@ pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int state)
(reg & ~PCI_PMCSR_STATE_MASK) | state);
if (state == PCI_PMCSR_STATE_D3 ||
ostate == PCI_PMCSR_STATE_D3)
- delay(10 * 1000);
+ delay(d3_delay);
}
}