Message ID | 20240817-pci-qcom-ep-cleanup-v1-2-d6b958226559@linaro.org (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Krzysztof Wilczyński |
Headers | show |
Series | PCI: {qcom-ep/tegra194}: Move endpoint cleanups to PERST# deassert handler | expand |
Hello, > Currently, the endpoint cleanup function dw_pcie_ep_cleanup() and EPF > deinit notify function pci_epc_deinit_notify() are called during the > execution of pex_ep_event_pex_rst_assert() i.e., when the host has asserted > PERST#. But quickly after this step, refclk will also be disabled by the > host. > > All of the tegra194 endpoint SoCs supported as of now depend on the refclk > from the host for keeping the controller operational. Due to this > limitation, any access to the hardware registers in the absence of refclk > will result in a whole endpoint crash. Unfortunately, most of the > controller cleanups require accessing the hardware registers (like eDMA > cleanup performed in dw_pcie_ep_cleanup(), etc...). So these cleanup > functions can cause the crash in the endpoint SoC once host asserts PERST#. > > One way to address this issue is by generating the refclk in the endpoint > itself and not depending on the host. But that is not always possible as > some of the endpoint designs do require the endpoint to consume refclk from > the host. > > So let's fix this crash by moving the controller cleanups to the start of > the pex_ep_event_pex_rst_deassert() function. This function is called > whenever the host has deasserted PERST# and it is guaranteed that the > refclk would be active at this point. So at the start of this function > (after enabling resources) the controller cleanup can be performed. Once > finished, rest of the code execution for PERST# deassert can continue as > usual. Applied to controller/tegra194, thank you! [01/01] PCI: tegra194: Move controller cleanups to pex_ep_event_pex_rst_deassert() https://git.kernel.org/pci/pci/c/40e2125381dc Krzysztof
diff --git a/drivers/pci/controller/dwc/pcie-tegra194.c b/drivers/pci/controller/dwc/pcie-tegra194.c index 4bf7b433417a..d68dd18ed43c 100644 --- a/drivers/pci/controller/dwc/pcie-tegra194.c +++ b/drivers/pci/controller/dwc/pcie-tegra194.c @@ -1709,9 +1709,6 @@ static void pex_ep_event_pex_rst_assert(struct tegra_pcie_dw *pcie) if (ret) dev_err(pcie->dev, "Failed to go Detect state: %d\n", ret); - pci_epc_deinit_notify(pcie->pci.ep.epc); - dw_pcie_ep_cleanup(&pcie->pci.ep); - reset_control_assert(pcie->core_rst); tegra_pcie_disable_phy(pcie); @@ -1790,6 +1787,10 @@ static void pex_ep_event_pex_rst_deassert(struct tegra_pcie_dw *pcie) goto fail_phy; } + /* Perform cleanup that requires refclk */ + pci_epc_deinit_notify(pcie->pci.ep.epc); + dw_pcie_ep_cleanup(&pcie->pci.ep); + /* Clear any stale interrupt statuses */ appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L0); appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L1_0_0);