Hello! On 26.09.2020 19:09, marek.vasut@xxxxxxxxx wrote:
From: Marek Vasut <marek.vasut+renesas@xxxxxxxxx> The R-Car PCIe controller is capable of handling L0s/L1 link states. While the controller can enter and exit L0s link state, and exit L1 link state, without any additional action from the driver, to enter L1 link state, the driver must complete the link state transition by issuing additional commands to the controller. The problem is, this transition is not atomic. The controller sets PMEL1RX bit in PMSR register upon reception of PM_ENTER_L1 DLLP from the PCIe card, but then the controller enters some sort of inbetween state. The driver must detect this condition and complete the link state transition, by setting L1IATN bit in PMCTLR and waiting for the link state transition to complete. If a PCIe access happens inside of this window, where the controller
s/of//.
is inbetween L0 and L1 link states, the access generates a fault and
My spellchecker trips on "inbetween"...
the ARM 'imprecise external abort' handler is invoked. Just like other PCI controller drivers, here we hook the fault handler, perform the fixup to help the controller enter L1 link state, and then restart the instruction which triggered the fault. Since the controller
If this is imprecise or async external abort, how we can re-execute the instruction that triggered the fault? It's been probably executed already, no?
is in L1 link state now, the link can exit from L1 link state to L0 and successfully complete the access. Note that this fixup is applicable only to Aarch32 R-Car controllers, the Aarch64 R-Car perform the same fixup in TFA, see TFA commit [1] 0969397f2 ("rcar_gen3: plat: Prevent PCIe hang during L1X config access") [1] https://github.com/ARM-software/arm-trusted-firmware/commit/0969397f295621aa26b3d14b76dd397d22be58bf Signed-off-by: Marek Vasut <marek.vasut+renesas@xxxxxxxxx> Cc: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> Cc: Geert Uytterhoeven <geert+renesas@xxxxxxxxx> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@xxxxxxx> Cc: Wolfram Sang <wsa@xxxxxxxxxxxxx> Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@xxxxxxxxxxx> Cc: linux-renesas-soc@xxxxxxxxxxxxxxx
[...]
+static int __init rcar_pcie_init(void) +{ +#ifdef CONFIG_ARM_LPAE + hook_fault_code(17, rcar_pcie_aarch32_abort_handler, SIGBUS, 0, + "asynchronous external abort"); +#else + hook_fault_code(22, rcar_pcie_aarch32_abort_handler, SIGBUS, 0, + "imprecise external abort"); +#endif + return platform_driver_register(&rcar_pcie_driver); +} +device_initcall(rcar_pcie_init); +#else builtin_platform_driver(rcar_pcie_driver); +#endif
[...] MBR, Sergei