aboutsummaryrefslogtreecommitdiff
path: root/nixos/modules/kernel-patches/0021-PCI-aardvark-Add-support-for-DLLSC-and-hotplug-inter.patch
diff options
context:
space:
mode:
authorKarel Kočí <cynerd@email.cz>2022-11-01 09:44:59 +0100
committerKarel Kočí <cynerd@email.cz>2022-11-01 09:44:59 +0100
commit955268e13f8f9422e7e89ee6350ec793dddd1e94 (patch)
tree1714aa5f8383ddf5aaaf7826c8502f686bcd8a7a /nixos/modules/kernel-patches/0021-PCI-aardvark-Add-support-for-DLLSC-and-hotplug-inter.patch
parent06293bfbb5082dc636358d49f3e6fea88c4f2a67 (diff)
downloadnixturris-955268e13f8f9422e7e89ee6350ec793dddd1e94.tar.gz
nixturris-955268e13f8f9422e7e89ee6350ec793dddd1e94.tar.bz2
nixturris-955268e13f8f9422e7e89ee6350ec793dddd1e94.zip
nixos: try to fix Turris Omnia PCIe on Linux 6.0
Unfortunatelly this seems to not work.
Diffstat (limited to 'nixos/modules/kernel-patches/0021-PCI-aardvark-Add-support-for-DLLSC-and-hotplug-inter.patch')
-rw-r--r--nixos/modules/kernel-patches/0021-PCI-aardvark-Add-support-for-DLLSC-and-hotplug-inter.patch268
1 files changed, 0 insertions, 268 deletions
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?= <pali@kernel.org>
-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 <pali@kernel.org>
-Signed-off-by: Marek Behún <kabel@kernel.org>
----
- 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 <linux/of_address.h>
- #include <linux/of_gpio.h>
- #include <linux/of_pci.h>
-+#include <linux/timer.h>
-
- #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
-