From 955268e13f8f9422e7e89ee6350ec793dddd1e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Tue, 1 Nov 2022 09:44:59 +0100 Subject: nixos: try to fix Turris Omnia PCIe on Linux 6.0 Unfortunatelly this seems to not work. --- ...k-Add-support-for-DLLSC-and-hotplug-inter.patch | 268 --------------------- 1 file changed, 268 deletions(-) delete mode 100644 nixos/modules/kernel-patches/0021-PCI-aardvark-Add-support-for-DLLSC-and-hotplug-inter.patch (limited to 'nixos/modules/kernel-patches/0021-PCI-aardvark-Add-support-for-DLLSC-and-hotplug-inter.patch') diff --git a/nixos/modules/kernel-patches/0021-PCI-aardvark-Add-support-for-DLLSC-and-hotplug-inter.patch b/nixos/modules/kernel-patches/0021-PCI-aardvark-Add-support-for-DLLSC-and-hotplug-inter.patch deleted file mode 100644 index 5debe96..0000000 --- a/nixos/modules/kernel-patches/0021-PCI-aardvark-Add-support-for-DLLSC-and-hotplug-inter.patch +++ /dev/null @@ -1,268 +0,0 @@ -From e9d12baaf2ca8f10303816dd3114f6fb54d9481f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pali=20Roh=C3=A1r?= -Date: Wed, 31 Aug 2022 15:55:46 +0200 -Subject: [PATCH 21/96] PCI: aardvark: Add support for DLLSC and hotplug - interrupt -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add support for Data Link Layer State Change in the emulated slot -registers and hotplug interrupt via the emulated root bridge. - -This is mainly useful for when an error causes link down event. With -this change, drivers can try recovery. - -Link down state change can be implemented because Aardvark supports Link -Down event interrupt. Use it for signaling that Data Link Layer Link is -not active anymore via Hot-Plug Interrupt on emulated root bridge. - -Link up interrupt is not available on Aardvark, but we check for whether -link is up in the advk_pcie_link_up() function. By triggering Hot-Plug -Interrupt from this function we achieve Link up event, so long as the -function is called (which it is after probe and when rescanning). -Although it is not ideal, it is better than nothing. - -Since advk_pcie_link_up() is not called from interrupt handler, we -cannot call generic_handle_domain_irq() from it directly. Instead create -a TIMER_IRQSAFE timer and trigger it from advk_pcie_link_up(). - -(We haven't been able to find any documentation for a Link Up interrupt - on Aardvark, but it is possible there is one, in some undocumented - register. If we manage to find this information, this can be - rewritten.) - -Signed-off-by: Pali Rohár -Signed-off-by: Marek Behún ---- - drivers/pci/controller/Kconfig | 3 + - drivers/pci/controller/pci-aardvark.c | 101 ++++++++++++++++++++++++-- - 2 files changed, 99 insertions(+), 5 deletions(-) - -diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig -index e4635712dbce..d4baecbcf574 100644 ---- a/drivers/pci/controller/Kconfig -+++ b/drivers/pci/controller/Kconfig -@@ -24,6 +24,9 @@ config PCI_AARDVARK - depends on OF - depends on PCI_MSI_IRQ_DOMAIN - select PCI_BRIDGE_EMUL -+ select PCIEPORTBUS -+ select HOTPLUG_PCI -+ select HOTPLUG_PCI_PCIE - help - Add support for Aardvark 64bit PCIe Host Controller. This - controller is part of the South Bridge of the Marvel Armada -diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c -index 668b052e3e2a..b2f143191313 100644 ---- a/drivers/pci/controller/pci-aardvark.c -+++ b/drivers/pci/controller/pci-aardvark.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #include "../pci.h" - #include "../pci-bridge-emul.h" -@@ -101,6 +102,7 @@ - #define PCIE_MSG_PM_PME_MASK BIT(7) - #define PCIE_ISR0_MASK_REG (CONTROL_BASE_ADDR + 0x44) - #define PCIE_ISR0_MSI_INT_PENDING BIT(24) -+#define PCIE_ISR0_LINK_DOWN BIT(1) - #define PCIE_ISR0_CORR_ERR BIT(11) - #define PCIE_ISR0_NFAT_ERR BIT(12) - #define PCIE_ISR0_FAT_ERR BIT(13) -@@ -285,6 +287,8 @@ struct advk_pcie { - DECLARE_BITMAP(msi_used, MSI_IRQ_NUM); - struct mutex msi_used_lock; - int link_gen; -+ bool link_was_up; -+ struct timer_list link_irq_timer; - struct pci_bridge_emul bridge; - struct gpio_desc *reset_gpio; - struct phy *phy; -@@ -314,7 +318,24 @@ static inline bool advk_pcie_link_up(struct advk_pcie *pcie) - { - /* check if LTSSM is in normal operation - some L* state */ - u8 ltssm_state = advk_pcie_ltssm_state(pcie); -- return ltssm_state >= LTSSM_L0 && ltssm_state < LTSSM_DISABLED; -+ bool link_is_up; -+ u16 slotsta; -+ -+ link_is_up = ltssm_state >= LTSSM_L0 && ltssm_state < LTSSM_DISABLED; -+ -+ if (link_is_up && !pcie->link_was_up) { -+ dev_info(&pcie->pdev->dev, "link up\n"); -+ -+ pcie->link_was_up = true; -+ -+ slotsta = le16_to_cpu(pcie->bridge.pcie_conf.slotsta); -+ slotsta |= PCI_EXP_SLTSTA_DLLSC; -+ pcie->bridge.pcie_conf.slotsta = cpu_to_le16(slotsta); -+ -+ mod_timer(&pcie->link_irq_timer, jiffies + 1); -+ } -+ -+ return link_is_up; - } - - static inline bool advk_pcie_link_active(struct advk_pcie *pcie) -@@ -443,8 +464,6 @@ static void advk_pcie_train_link(struct advk_pcie *pcie) - ret = advk_pcie_wait_for_link(pcie); - if (ret < 0) - dev_err(dev, "link never came up\n"); -- else -- dev_info(dev, "link up\n"); - } - - /* -@@ -593,6 +612,11 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) - reg &= ~PCIE_ISR0_MSI_INT_PENDING; - advk_writel(pcie, reg, PCIE_ISR0_MASK_REG); - -+ /* Unmask Link Down interrupt */ -+ reg = advk_readl(pcie, PCIE_ISR0_MASK_REG); -+ reg &= ~PCIE_ISR0_LINK_DOWN; -+ advk_writel(pcie, reg, PCIE_ISR0_MASK_REG); -+ - /* Unmask PME interrupt for processing of PME requester */ - reg = advk_readl(pcie, PCIE_ISR0_MASK_REG); - reg &= ~PCIE_MSG_PM_PME_MASK; -@@ -919,6 +943,14 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge, - advk_pcie_wait_for_retrain(pcie); - break; - -+ case PCI_EXP_SLTCTL: { -+ u16 slotctl = le16_to_cpu(bridge->pcie_conf.slotctl); -+ /* Only emulation of HPIE and DLLSCE bits is provided */ -+ slotctl &= PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_DLLSCE; -+ bridge->pcie_conf.slotctl = cpu_to_le16(slotctl); -+ break; -+ } -+ - case PCI_EXP_RTCTL: { - u16 rootctl = le16_to_cpu(bridge->pcie_conf.rootctl); - /* Only emulation of PMEIE and CRSSVE bits is provided */ -@@ -1036,6 +1068,7 @@ static const struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = { - static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) - { - struct pci_bridge_emul *bridge = &pcie->bridge; -+ u32 slotcap; - - bridge->conf.vendor = - cpu_to_le16(advk_readl(pcie, PCIE_CORE_DEV_ID_REG) & 0xffff); -@@ -1062,6 +1095,13 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) - bridge->pcie_conf.cap = cpu_to_le16(2 | PCI_EXP_FLAGS_SLOT); - - /* -+ * Mark bridge as Hot Plug Capable since this is the way how to enable -+ * delivering of Data Link Layer State Change interrupts. -+ * -+ * Set No Command Completed Support because bridge does not support -+ * Command Completed Interrupt. Every command is executed immediately -+ * without any delay. -+ * - * Set Presence Detect State bit permanently since there is no support - * for unplugging the card nor detecting whether it is plugged. (If a - * platform exists in the future that supports it, via a GPIO for -@@ -1071,8 +1111,9 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) - * value is reserved for ports within the same silicon as Root Port - * which is not our case. - */ -- bridge->pcie_conf.slotcap = cpu_to_le32(FIELD_PREP(PCI_EXP_SLTCAP_PSN, -- 1)); -+ slotcap = PCI_EXP_SLTCAP_NCCS | PCI_EXP_SLTCAP_HPC | -+ FIELD_PREP(PCI_EXP_SLTCAP_PSN, 1); -+ bridge->pcie_conf.slotcap = cpu_to_le32(slotcap); - bridge->pcie_conf.slotsta = cpu_to_le16(PCI_EXP_SLTSTA_PDS); - - /* Indicates supports for Completion Retry Status */ -@@ -1585,6 +1626,24 @@ static void advk_pcie_remove_rp_irq_domain(struct advk_pcie *pcie) - irq_domain_remove(pcie->rp_irq_domain); - } - -+static void advk_pcie_link_irq_handler(struct timer_list *timer) -+{ -+ struct advk_pcie *pcie = from_timer(pcie, timer, link_irq_timer); -+ u16 slotctl; -+ -+ slotctl = le16_to_cpu(pcie->bridge.pcie_conf.slotctl); -+ if (!(slotctl & PCI_EXP_SLTCTL_DLLSCE) || -+ !(slotctl & PCI_EXP_SLTCTL_HPIE)) -+ return; -+ -+ /* -+ * Aardvark HW returns zero for PCI_EXP_FLAGS_IRQ, so use PCIe -+ * interrupt 0 -+ */ -+ if (generic_handle_domain_irq(pcie->rp_irq_domain, 0) == -EINVAL) -+ dev_err_ratelimited(&pcie->pdev->dev, "unhandled HP IRQ\n"); -+} -+ - static void advk_pcie_handle_pme(struct advk_pcie *pcie) - { - u32 requester = advk_readl(pcie, PCIE_MSG_LOG_REG) >> 16; -@@ -1636,6 +1695,7 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie) - { - u32 isr0_val, isr0_mask, isr0_status; - u32 isr1_val, isr1_mask, isr1_status; -+ u16 slotsta; - int i; - - isr0_val = advk_readl(pcie, PCIE_ISR0_REG); -@@ -1662,6 +1722,26 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie) - dev_err_ratelimited(&pcie->pdev->dev, "unhandled ERR IRQ\n"); - } - -+ /* Process Link Down interrupt as HP IRQ */ -+ if (isr0_status & PCIE_ISR0_LINK_DOWN) { -+ advk_writel(pcie, PCIE_ISR0_LINK_DOWN, PCIE_ISR0_REG); -+ -+ dev_info(&pcie->pdev->dev, "link down\n"); -+ -+ pcie->link_was_up = false; -+ -+ slotsta = le16_to_cpu(pcie->bridge.pcie_conf.slotsta); -+ slotsta |= PCI_EXP_SLTSTA_DLLSC; -+ pcie->bridge.pcie_conf.slotsta = cpu_to_le16(slotsta); -+ -+ /* -+ * Deactivate timer and call advk_pcie_link_irq_handler() -+ * function directly as we are in the interrupt context. -+ */ -+ del_timer_sync(&pcie->link_irq_timer); -+ advk_pcie_link_irq_handler(&pcie->link_irq_timer); -+ } -+ - /* Process MSI interrupts */ - if (isr0_status & PCIE_ISR0_MSI_INT_PENDING) - advk_pcie_handle_msi(pcie); -@@ -1898,6 +1978,14 @@ static int advk_pcie_probe(struct platform_device *pdev) - if (ret) - return ret; - -+ /* -+ * generic_handle_domain_irq() expects local IRQs to be disabled since -+ * normally it is called from interrupt context, so use TIMER_IRQSAFE -+ * flag for this link_irq_timer. -+ */ -+ timer_setup(&pcie->link_irq_timer, advk_pcie_link_irq_handler, -+ TIMER_IRQSAFE); -+ - advk_pcie_setup_hw(pcie); - - ret = advk_sw_pci_bridge_init(pcie); -@@ -1986,6 +2074,9 @@ static int advk_pcie_remove(struct platform_device *pdev) - advk_pcie_remove_msi_irq_domain(pcie); - advk_pcie_remove_irq_domain(pcie); - -+ /* Deactivate link event timer */ -+ del_timer_sync(&pcie->link_irq_timer); -+ - /* Free config space for emulated root bridge */ - pci_bridge_emul_cleanup(&pcie->bridge); - --- -2.37.2 - -- cgit v1.2.3