-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
linux: pci: Fix PCI probing race condition
The Keystone PCI controller had a race condition hidden that made its probing fail. Add a patch provided by TI (currently mainlined) that fixes this race condition and returns PCI back to a funcional state. Tested with a Hailo-8 NPU card. While at it add a second patch suggested by TI that fixes "a 45 second delay when no Endpoint Device is connected to the PCIe connector". Signed-off-by: Diogo Ivo <[email protected]>
- Loading branch information
1 parent
33d74ea
commit 91c99e8
Showing
2 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
54 changes: 54 additions & 0 deletions
54
...l/linux/files/patches-6.1/0095-PCI-keystone-Fix-race-condition-when-initializing-PH.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Siddharth Vadapalli <[email protected]> | ||
Date: Wed, 27 Sep 2023 09:48:45 +0530 | ||
Subject: [PATCH] PCI: keystone: Fix race condition when initializing PHYs | ||
|
||
The PCI driver invokes the PHY APIs using the ks_pcie_enable_phy() | ||
function. The PHY in this case is the Serdes. It is possible that the | ||
PCI instance is configured for two lane operation across two different | ||
Serdes instances, using one lane of each Serdes. | ||
|
||
In such a configuration, if the reference clock for one Serdes is | ||
provided by the other Serdes, it results in a race condition. After the | ||
Serdes providing the reference clock is initialized by the PCI driver by | ||
invoking its PHY APIs, it is not guaranteed that this Serdes remains | ||
powered on long enough for the PHY APIs based initialization of the | ||
dependent Serdes. In such cases, the PLL of the dependent Serdes fails | ||
to lock due to the absence of the reference clock from the former Serdes | ||
which has been powered off by the PM Core. | ||
|
||
Fix this by obtaining reference to the PHYs before invoking the PHY | ||
initialization APIs and releasing reference after the initialization is | ||
complete. | ||
|
||
Link: https://lore.kernel.org/linux-pci/[email protected] | ||
Fixes: 49229238ab47 ("PCI: keystone: Cleanup PHY handling") | ||
Signed-off-by: Siddharth Vadapalli <[email protected]> | ||
Signed-off-by: Krzysztof Wilczyński <[email protected]> | ||
Acked-by: Ravi Gunasekaran <[email protected]> | ||
[Commit c12ca110c613 upstream] | ||
--- | ||
drivers/pci/controller/dwc/pci-keystone.c | 9 +++++++++ | ||
1 file changed, 9 insertions(+) | ||
|
||
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c | ||
index fefb375a777a..a5dbe8c9b077 100644 | ||
--- a/drivers/pci/controller/dwc/pci-keystone.c | ||
+++ b/drivers/pci/controller/dwc/pci-keystone.c | ||
@@ -1367,7 +1367,16 @@ static int __init ks_pcie_probe(struct platform_device *pdev) | ||
goto err_link; | ||
} | ||
|
||
+ /* Obtain references to the PHYs */ | ||
+ for (i = 0; i < num_lanes; i++) | ||
+ phy_pm_runtime_get_sync(ks_pcie->phy[i]); | ||
+ | ||
ret = ks_pcie_enable_phy(ks_pcie); | ||
+ | ||
+ /* Release references to the PHYs */ | ||
+ for (i = 0; i < num_lanes; i++) | ||
+ phy_pm_runtime_put_sync(ks_pcie->phy[i]); | ||
+ | ||
if (ret) { | ||
dev_err(dev, "failed to enable phy\n"); | ||
goto err_link; |
68 changes: 68 additions & 0 deletions
68
recipes-kernel/linux/files/patches-6.1/0096-PCI-keystone-Fix-pci_ops-for-AM654x-SoC.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Siddharth Vadapalli <[email protected]> | ||
Date: Mon, 22 Jan 2024 11:19:32 +0000 | ||
Subject: [PATCH] PCI: keystone: Fix pci_ops for AM654x SoC | ||
|
||
In the process of converting .scan_bus() callbacks to .add_bus(), the | ||
ks_pcie_v3_65_scan_bus() function was changed to ks_pcie_v3_65_add_bus(). | ||
The .scan_bus() method belonged to ks_pcie_host_ops which was specific | ||
to controller version 3.65a, while the .add_bus() method had been added | ||
to ks_pcie_ops which is shared between the controller versions 3.65a and | ||
4.90a. Neither the older ks_pcie_v3_65_scan_bus() method, nor the newer | ||
ks_pcie_v3_65_add_bus() method are applicable to the controller version | ||
4.90a which is present in AM654x SoCs. | ||
|
||
Thus, fix this by creating ks_pcie_am6_ops for the AM654x SoC which uses DW | ||
PCIe IP-core version 4.90a controller and omitting the .add_bus() method | ||
which is not applicable to the 4.90a controller. Update ks_pcie_host_init() | ||
accordingly in order to set the pci_ops to ks_pcie_am6_ops if the platform | ||
is AM654x SoC and to ks_pcie_ops otherwise, by making use of the "is_am6" | ||
flag. | ||
|
||
Fixes: 6ab15b5e7057 ("PCI: dwc: keystone: Convert .scan_bus() callback to use add_bus") | ||
Signed-off-by: Siddharth Vadapalli <[email protected]> | ||
Reviewed-by: Serge Semin <[email protected]> | ||
[Taken from https://lore.kernel.org/all/[email protected]/, manually edited] | ||
--- | ||
drivers/pci/controller/dwc/pci-keystone.c | 18 ++++++++++++------ | ||
1 file changed, 12 insertions(+), 6 deletions(-) | ||
|
||
diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c | ||
index a5dbe8c9b077..356bfdec00eb 100644 | ||
--- a/drivers/pci/controller/dwc/pci-keystone.c | ||
+++ b/drivers/pci/controller/dwc/pci-keystone.c | ||
@@ -581,6 +581,12 @@ static struct pci_ops ks_pcie_ops = { | ||
.add_bus = ks_pcie_v3_65_add_bus, | ||
}; | ||
|
||
+static struct pci_ops ks_pcie_am6_ops = { | ||
+ .map_bus = dw_pcie_own_conf_map_bus, | ||
+ .read = pci_generic_config_read, | ||
+ .write = pci_generic_config_write, | ||
+}; | ||
+ | ||
/** | ||
* ks_pcie_link_up() - Check if link up | ||
* @pci: A pointer to the dw_pcie structure which holds the DesignWare PCIe host | ||
@@ -948,15 +954,15 @@ static int __init ks_pcie_host_init(struct dw_pcie_rp *pp) | ||
struct keystone_pcie *ks_pcie = to_keystone_pcie(pci); | ||
int ret; | ||
|
||
- pp->bridge->ops = &ks_pcie_ops; | ||
- | ||
- if (!ks_pcie->is_am6) { | ||
- pp->bridge->child_ops = &ks_child_pcie_ops; | ||
- ret = ks_pcie_config_legacy_irq(ks_pcie); | ||
+ if (ks_pcie->is_am6) { | ||
+ pp->bridge->ops = &ks_pcie_am6_ops; | ||
+ ret = ks_pcie_am654_config_legacy_irq(ks_pcie); | ||
if (ret) | ||
return ret; | ||
} else { | ||
- ret = ks_pcie_am654_config_legacy_irq(ks_pcie); | ||
+ pp->bridge->ops = &ks_pcie_ops; | ||
+ pp->bridge->child_ops = &ks_child_pcie_ops; | ||
+ ret = ks_pcie_config_legacy_irq(ks_pcie); | ||
if (ret) | ||
return ret; | ||
} |