From 0965cec53c9e421f900bb050b1c83196a0a5687b Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 8 Aug 2022 16:39:40 +0100 Subject: [pci] Generalise function-level reset mechanism Signed-off-by: Michael Brown --- src/drivers/bus/pciextra.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/drivers/bus') diff --git a/src/drivers/bus/pciextra.c b/src/drivers/bus/pciextra.c index 3082d8a3d..23617bc9a 100644 --- a/src/drivers/bus/pciextra.c +++ b/src/drivers/bus/pciextra.c @@ -1,6 +1,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include +#include #include static int pci_find_capability_common ( struct pci_device *pci, @@ -112,3 +113,24 @@ unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg ) { size = size & ~( size - 1 ); return size; } + +/** + * Perform PCI Express function-level reset (FLR) + * + * @v pci PCI device + * @v exp PCI Express Capability address + */ +void pci_reset ( struct pci_device *pci, unsigned int exp ) { + uint16_t control; + + /* Perform a PCIe function-level reset */ + pci_read_config_word ( pci, ( exp + PCI_EXP_DEVCTL ), &control ); + control |= PCI_EXP_DEVCTL_FLR; + pci_write_config_word ( pci, ( exp + PCI_EXP_DEVCTL ), control ); + + /* Allow time for reset to complete */ + mdelay ( PCI_EXP_FLR_DELAY_MS ); + + /* Re-enable device */ + adjust_pci_device ( pci ); +} -- cgit v1.2.3-55-g7522