From: Greg Kroah-Hartman Date: Sun, 28 Nov 2021 12:51:29 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v5.15.6~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9f1123d691a0f9be9cc2cf11407fa485c173b82c;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: arm64-dts-marvell-armada-37xx-set-pcie_reset_pin-to-gpio-function.patch pci-aardvark-configure-pcie-resources-from-ranges-dt-property.patch pci-aardvark-deduplicate-code-in-advk_pcie_rd_conf.patch pci-aardvark-don-t-touch-pcie-registers-if-no-card-connected.patch pci-aardvark-fix-big-endian-support.patch pci-aardvark-fix-compilation-on-s390.patch pci-aardvark-fix-link-training.patch pci-aardvark-fix-pcie-max-payload-size-setting.patch pci-aardvark-fix-support-for-bus-mastering-and-pci_command-on-emulated-bridge.patch pci-aardvark-fix-support-for-pci_bridge_ctl_bus_reset-on-emulated-bridge.patch pci-aardvark-implement-re-issuing-config-requests-on-crs-response.patch pci-aardvark-improve-link-training.patch pci-aardvark-issue-perst-via-gpio.patch pci-aardvark-move-pcie-reset-card-code-to-advk_pcie_train_link.patch pci-aardvark-replace-custom-macros-by-standard-linux-pci_regs.h-macros.patch pci-aardvark-set-pci-bridge-class-code-to-pci-bridge.patch pci-aardvark-simplify-initialization-of-rootcap-on-virtual-bridge.patch pci-aardvark-train-link-immediately-after-enabling-training.patch pci-aardvark-update-comment-about-disabling-link-training.patch pci-aardvark-wait-for-endpoint-to-be-ready-before-training-link.patch pci-pci-bridge-emul-fix-array-overruns-improve-safety.patch pinctrl-armada-37xx-correct-pwm-pins-definitions.patch --- diff --git a/queue-5.4/arm64-dts-marvell-armada-37xx-set-pcie_reset_pin-to-gpio-function.patch b/queue-5.4/arm64-dts-marvell-armada-37xx-set-pcie_reset_pin-to-gpio-function.patch new file mode 100644 index 00000000000..af1e8696fde --- /dev/null +++ b/queue-5.4/arm64-dts-marvell-armada-37xx-set-pcie_reset_pin-to-gpio-function.patch @@ -0,0 +1,98 @@ +From foo@baz Sun Nov 28 01:44:18 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:16 +0100 +Subject: arm64: dts: marvell: armada-37xx: Set pcie_reset_pin to gpio function +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Remi Pommarel" , "Tomasz Maciej Nowak" , "Thomas Petazzoni" , "Gregory CLEMENT" , "Marek Behún" +Message-ID: <20211125002616.31363-23-kabel@kernel.org> + +From: "Marek Behún" + +commit 715878016984b2617f6c1f177c50039e12e7bd5b upstream. + +We found out that we are unable to control the PERST# signal via the +default pin dedicated to be PERST# pin (GPIO2[3] pin) on A3700 SOC when +this pin is in EP_PCIE1_Resetn mode. There is a register in the PCIe +register space called PERSTN_GPIO_EN (D0088004[3]), but changing the +value of this register does not change the pin output when measuring +with voltmeter. + +We do not know if this is a bug in the SOC, or if it works only when +PCIe controller is in a certain state. + +Commit f4c7d053d7f7 ("PCI: aardvark: Wait for endpoint to be ready +before training link") says that when this pin changes pinctrl mode +from EP_PCIE1_Resetn to GPIO, the PERST# signal is asserted for a brief +moment. + +So currently the situation is that on A3700 boards the PERST# signal is +asserted in U-Boot (because the code in U-Boot issues reset via this pin +via GPIO mode), and then in Linux by the obscure and undocumented +mechanism described by the above mentioned commit. + +We want to issue PERST# signal in a known way, therefore this patch +changes the pcie_reset_pin function from "pcie" to "gpio" and adds the +reset-gpios property to the PCIe node in device tree files of +EspressoBin and Armada 3720 Dev Board (Turris Mox device tree already +has this property and uDPU does not have a PCIe port). + +Signed-off-by: Marek Behún +Cc: Remi Pommarel +Tested-by: Tomasz Maciej Nowak +Acked-by: Thomas Petazzoni +Signed-off-by: Gregory CLEMENT +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/marvell/armada-3720-db.dts | 3 +++ + arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts | 1 + + arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts | 4 ---- + arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 2 +- + 4 files changed, 5 insertions(+), 5 deletions(-) + +--- a/arch/arm64/boot/dts/marvell/armada-3720-db.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-db.dts +@@ -128,6 +128,9 @@ + + /* CON15(V2.0)/CON17(V1.4) : PCIe / CON15(V2.0)/CON12(V1.4) :mini-PCIe */ + &pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>; ++ reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + +--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dts +@@ -59,6 +59,7 @@ + phys = <&comphy1 0>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>; ++ reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>; + }; + + /* J6 */ +--- a/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts ++++ b/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +@@ -127,10 +127,6 @@ + }; + }; + +-&pcie_reset_pins { +- function = "gpio"; +-}; +- + &pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_reset_pins &pcie_clkreq_pins>; +--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi ++++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi +@@ -318,7 +318,7 @@ + + pcie_reset_pins: pcie-reset-pins { + groups = "pcie1"; +- function = "pcie"; ++ function = "gpio"; + }; + + pcie_clkreq_pins: pcie-clkreq-pins { diff --git a/queue-5.4/pci-aardvark-configure-pcie-resources-from-ranges-dt-property.patch b/queue-5.4/pci-aardvark-configure-pcie-resources-from-ranges-dt-property.patch new file mode 100644 index 00000000000..e44549ea3cf --- /dev/null +++ b/queue-5.4/pci-aardvark-configure-pcie-resources-from-ranges-dt-property.patch @@ -0,0 +1,297 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:06 +0100 +Subject: PCI: aardvark: Configure PCIe resources from 'ranges' DT property +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Lorenzo Pieralisi" , "Marek Behún" +Message-ID: <20211125002616.31363-13-kabel@kernel.org> + +From: Pali Rohár + +commit 64f160e19e9264a7f6d89c516baae1473b6f8359 upstream. + +In commit 6df6ba974a55 ("PCI: aardvark: Remove PCIe outbound window +configuration") was removed aardvark PCIe outbound window configuration and +commit description said that was recommended solution by HW designers. + +But that commit completely removed support for configuring PCIe IO +resources without removing PCIe IO 'ranges' from DTS files. After that +commit PCIe IO space started to be treated as PCIe MEM space and accessing +it just caused kernel crash. + +Moreover implementation of PCIe outbound windows prior that commit was +incorrect. It completely ignored offset between CPU address and PCIe bus +address and expected that in DTS is CPU address always same as PCIe bus +address without doing any checks. Also it completely ignored size of every +PCIe resource specified in 'ranges' DTS property and expected that every +PCIe resource has size 128 MB (also for PCIe IO range). Again without any +check. Apparently none of PCIe resource has in DTS specified size of 128 +MB. So it was completely broken and thanks to how aardvark mask works, +configuration was completely ignored. + +This patch reverts back support for PCIe outbound window configuration but +implementation is a new without issues mentioned above. PCIe outbound +window is required when DTS specify in 'ranges' property non-zero offset +between CPU and PCIe address space. To address recommendation by HW +designers as specified in commit description of 6df6ba974a55, set default +outbound parameters as PCIe MEM access without translation and therefore +for this PCIe 'ranges' it is not needed to configure PCIe outbound window. +For PCIe IO space is needed to configure aardvark PCIe outbound window. + +This patch fixes kernel crash when trying to access PCIe IO space. + +Link: https://lore.kernel.org/r/20210624215546.4015-2-pali@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Cc: stable@vger.kernel.org # 6df6ba974a55 ("PCI: aardvark: Remove PCIe outbound window configuration") +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 190 +++++++++++++++++++++++++++++++++- + 1 file changed, 189 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -114,6 +114,46 @@ + #define PCIE_MSI_PAYLOAD_REG (CONTROL_BASE_ADDR + 0x9C) + #define PCIE_MSI_DATA_MASK GENMASK(15, 0) + ++/* PCIe window configuration */ ++#define OB_WIN_BASE_ADDR 0x4c00 ++#define OB_WIN_BLOCK_SIZE 0x20 ++#define OB_WIN_COUNT 8 ++#define OB_WIN_REG_ADDR(win, offset) (OB_WIN_BASE_ADDR + \ ++ OB_WIN_BLOCK_SIZE * (win) + \ ++ (offset)) ++#define OB_WIN_MATCH_LS(win) OB_WIN_REG_ADDR(win, 0x00) ++#define OB_WIN_ENABLE BIT(0) ++#define OB_WIN_MATCH_MS(win) OB_WIN_REG_ADDR(win, 0x04) ++#define OB_WIN_REMAP_LS(win) OB_WIN_REG_ADDR(win, 0x08) ++#define OB_WIN_REMAP_MS(win) OB_WIN_REG_ADDR(win, 0x0c) ++#define OB_WIN_MASK_LS(win) OB_WIN_REG_ADDR(win, 0x10) ++#define OB_WIN_MASK_MS(win) OB_WIN_REG_ADDR(win, 0x14) ++#define OB_WIN_ACTIONS(win) OB_WIN_REG_ADDR(win, 0x18) ++#define OB_WIN_DEFAULT_ACTIONS (OB_WIN_ACTIONS(OB_WIN_COUNT-1) + 0x4) ++#define OB_WIN_FUNC_NUM_MASK GENMASK(31, 24) ++#define OB_WIN_FUNC_NUM_SHIFT 24 ++#define OB_WIN_FUNC_NUM_ENABLE BIT(23) ++#define OB_WIN_BUS_NUM_BITS_MASK GENMASK(22, 20) ++#define OB_WIN_BUS_NUM_BITS_SHIFT 20 ++#define OB_WIN_MSG_CODE_ENABLE BIT(22) ++#define OB_WIN_MSG_CODE_MASK GENMASK(21, 14) ++#define OB_WIN_MSG_CODE_SHIFT 14 ++#define OB_WIN_MSG_PAYLOAD_LEN BIT(12) ++#define OB_WIN_ATTR_ENABLE BIT(11) ++#define OB_WIN_ATTR_TC_MASK GENMASK(10, 8) ++#define OB_WIN_ATTR_TC_SHIFT 8 ++#define OB_WIN_ATTR_RELAXED BIT(7) ++#define OB_WIN_ATTR_NOSNOOP BIT(6) ++#define OB_WIN_ATTR_POISON BIT(5) ++#define OB_WIN_ATTR_IDO BIT(4) ++#define OB_WIN_TYPE_MASK GENMASK(3, 0) ++#define OB_WIN_TYPE_SHIFT 0 ++#define OB_WIN_TYPE_MEM 0x0 ++#define OB_WIN_TYPE_IO 0x4 ++#define OB_WIN_TYPE_CONFIG_TYPE0 0x8 ++#define OB_WIN_TYPE_CONFIG_TYPE1 0x9 ++#define OB_WIN_TYPE_MSG 0xc ++ + /* LMI registers base address and register offsets */ + #define LMI_BASE_ADDR 0x6000 + #define CFG_REG (LMI_BASE_ADDR + 0x0) +@@ -229,6 +269,13 @@ struct advk_pcie { + struct platform_device *pdev; + void __iomem *base; + struct list_head resources; ++ struct { ++ phys_addr_t match; ++ phys_addr_t remap; ++ phys_addr_t mask; ++ u32 actions; ++ } wins[OB_WIN_COUNT]; ++ u8 wins_count; + struct irq_domain *irq_domain; + struct irq_chip irq_chip; + raw_spinlock_t irq_lock; +@@ -452,9 +499,39 @@ err: + dev_err(dev, "link never came up\n"); + } + ++/* ++ * Set PCIe address window register which could be used for memory ++ * mapping. ++ */ ++static void advk_pcie_set_ob_win(struct advk_pcie *pcie, u8 win_num, ++ phys_addr_t match, phys_addr_t remap, ++ phys_addr_t mask, u32 actions) ++{ ++ advk_writel(pcie, OB_WIN_ENABLE | ++ lower_32_bits(match), OB_WIN_MATCH_LS(win_num)); ++ advk_writel(pcie, upper_32_bits(match), OB_WIN_MATCH_MS(win_num)); ++ advk_writel(pcie, lower_32_bits(remap), OB_WIN_REMAP_LS(win_num)); ++ advk_writel(pcie, upper_32_bits(remap), OB_WIN_REMAP_MS(win_num)); ++ advk_writel(pcie, lower_32_bits(mask), OB_WIN_MASK_LS(win_num)); ++ advk_writel(pcie, upper_32_bits(mask), OB_WIN_MASK_MS(win_num)); ++ advk_writel(pcie, actions, OB_WIN_ACTIONS(win_num)); ++} ++ ++static void advk_pcie_disable_ob_win(struct advk_pcie *pcie, u8 win_num) ++{ ++ advk_writel(pcie, 0, OB_WIN_MATCH_LS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_MATCH_MS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_REMAP_LS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_REMAP_MS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_MASK_LS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_MASK_MS(win_num)); ++ advk_writel(pcie, 0, OB_WIN_ACTIONS(win_num)); ++} ++ + static void advk_pcie_setup_hw(struct advk_pcie *pcie) + { + u32 reg; ++ int i; + + /* Set to Direct mode */ + reg = advk_readl(pcie, CTRL_CONFIG_REG); +@@ -528,15 +605,51 @@ static void advk_pcie_setup_hw(struct ad + reg = PCIE_IRQ_ALL_MASK & (~PCIE_IRQ_ENABLE_INTS_MASK); + advk_writel(pcie, reg, HOST_CTRL_INT_MASK_REG); + ++ /* ++ * Enable AXI address window location generation: ++ * When it is enabled, the default outbound window ++ * configurations (Default User Field: 0xD0074CFC) ++ * are used to transparent address translation for ++ * the outbound transactions. Thus, PCIe address ++ * windows are not required for transparent memory ++ * access when default outbound window configuration ++ * is set for memory access. ++ */ + reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); + reg |= PCIE_CORE_CTRL2_OB_WIN_ENABLE; + advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); + +- /* Bypass the address window mapping for PIO */ ++ /* ++ * Set memory access in Default User Field so it ++ * is not required to configure PCIe address for ++ * transparent memory access. ++ */ ++ advk_writel(pcie, OB_WIN_TYPE_MEM, OB_WIN_DEFAULT_ACTIONS); ++ ++ /* ++ * Bypass the address window mapping for PIO: ++ * Since PIO access already contains all required ++ * info over AXI interface by PIO registers, the ++ * address window is not required. ++ */ + reg = advk_readl(pcie, PIO_CTRL); + reg |= PIO_CTRL_ADDR_WIN_DISABLE; + advk_writel(pcie, reg, PIO_CTRL); + ++ /* ++ * Configure PCIe address windows for non-memory or ++ * non-transparent access as by default PCIe uses ++ * transparent memory access. ++ */ ++ for (i = 0; i < pcie->wins_count; i++) ++ advk_pcie_set_ob_win(pcie, i, ++ pcie->wins[i].match, pcie->wins[i].remap, ++ pcie->wins[i].mask, pcie->wins[i].actions); ++ ++ /* Disable remaining PCIe outbound windows */ ++ for (i = pcie->wins_count; i < OB_WIN_COUNT; i++) ++ advk_pcie_disable_ob_win(pcie, i); ++ + advk_pcie_train_link(pcie); + + reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); +@@ -1345,6 +1458,7 @@ static int advk_pcie_probe(struct platfo + struct advk_pcie *pcie; + struct resource *res; + struct pci_host_bridge *bridge; ++ struct resource_entry *entry; + int ret, irq; + + bridge = devm_pci_alloc_host_bridge(dev, sizeof(struct advk_pcie)); +@@ -1374,6 +1488,80 @@ static int advk_pcie_probe(struct platfo + return ret; + } + ++ resource_list_for_each_entry(entry, &pcie->resources) { ++ resource_size_t start = entry->res->start; ++ resource_size_t size = resource_size(entry->res); ++ unsigned long type = resource_type(entry->res); ++ u64 win_size; ++ ++ /* ++ * Aardvark hardware allows to configure also PCIe window ++ * for config type 0 and type 1 mapping, but driver uses ++ * only PIO for issuing configuration transfers which does ++ * not use PCIe window configuration. ++ */ ++ if (type != IORESOURCE_MEM && type != IORESOURCE_MEM_64 && ++ type != IORESOURCE_IO) ++ continue; ++ ++ /* ++ * Skip transparent memory resources. Default outbound access ++ * configuration is set to transparent memory access so it ++ * does not need window configuration. ++ */ ++ if ((type == IORESOURCE_MEM || type == IORESOURCE_MEM_64) && ++ entry->offset == 0) ++ continue; ++ ++ /* ++ * The n-th PCIe window is configured by tuple (match, remap, mask) ++ * and an access to address A uses this window if A matches the ++ * match with given mask. ++ * So every PCIe window size must be a power of two and every start ++ * address must be aligned to window size. Minimal size is 64 KiB ++ * because lower 16 bits of mask must be zero. Remapped address ++ * may have set only bits from the mask. ++ */ ++ while (pcie->wins_count < OB_WIN_COUNT && size > 0) { ++ /* Calculate the largest aligned window size */ ++ win_size = (1ULL << (fls64(size)-1)) | ++ (start ? (1ULL << __ffs64(start)) : 0); ++ win_size = 1ULL << __ffs64(win_size); ++ if (win_size < 0x10000) ++ break; ++ ++ dev_dbg(dev, ++ "Configuring PCIe window %d: [0x%llx-0x%llx] as %lu\n", ++ pcie->wins_count, (unsigned long long)start, ++ (unsigned long long)start + win_size, type); ++ ++ if (type == IORESOURCE_IO) { ++ pcie->wins[pcie->wins_count].actions = OB_WIN_TYPE_IO; ++ pcie->wins[pcie->wins_count].match = pci_pio_to_address(start); ++ } else { ++ pcie->wins[pcie->wins_count].actions = OB_WIN_TYPE_MEM; ++ pcie->wins[pcie->wins_count].match = start; ++ } ++ pcie->wins[pcie->wins_count].remap = start - entry->offset; ++ pcie->wins[pcie->wins_count].mask = ~(win_size - 1); ++ ++ if (pcie->wins[pcie->wins_count].remap & (win_size - 1)) ++ break; ++ ++ start += win_size; ++ size -= win_size; ++ pcie->wins_count++; ++ } ++ ++ if (size > 0) { ++ dev_err(&pcie->pdev->dev, ++ "Invalid PCIe region [0x%llx-0x%llx]\n", ++ (unsigned long long)entry->res->start, ++ (unsigned long long)entry->res->end + 1); ++ return -EINVAL; ++ } ++ } ++ + pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node, + "reset-gpios", 0, + GPIOD_OUT_LOW, diff --git a/queue-5.4/pci-aardvark-deduplicate-code-in-advk_pcie_rd_conf.patch b/queue-5.4/pci-aardvark-deduplicate-code-in-advk_pcie_rd_conf.patch new file mode 100644 index 00000000000..3a26e9da9b6 --- /dev/null +++ b/queue-5.4/pci-aardvark-deduplicate-code-in-advk_pcie_rd_conf.patch @@ -0,0 +1,98 @@ +From 67cb2a4c93499c2c22704998fd1fd2bc35194d8e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Beh=C3=BAn?= +Date: Tue, 5 Oct 2021 20:09:47 +0200 +Subject: PCI: aardvark: Deduplicate code in advk_pcie_rd_conf() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marek Behún + +commit 67cb2a4c93499c2c22704998fd1fd2bc35194d8e upstream. + +Avoid code repetition in advk_pcie_rd_conf() by handling errors with +goto jump, as is customary in kernel. + +Link: https://lore.kernel.org/r/20211005180952.6812-9-kabel@kernel.org +Fixes: 43f5c77bcbd2 ("PCI: aardvark: Fix reporting CRS value") +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 48 ++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 28 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -773,18 +773,8 @@ static int advk_pcie_rd_conf(struct pci_ + (le16_to_cpu(pcie->bridge.pcie_conf.rootctl) & + PCI_EXP_RTCTL_CRSSVE); + +- if (advk_pcie_pio_is_running(pcie)) { +- /* +- * If it is possible return Completion Retry Status so caller +- * tries to issue the request again instead of failing. +- */ +- if (allow_crs) { +- *val = CFG_RD_CRS_VAL; +- return PCIBIOS_SUCCESSFUL; +- } +- *val = 0xffffffff; +- return PCIBIOS_SET_FAILED; +- } ++ if (advk_pcie_pio_is_running(pcie)) ++ goto try_crs; + + /* Program the control register */ + reg = advk_readl(pcie, PIO_CTRL); +@@ -808,25 +798,13 @@ static int advk_pcie_rd_conf(struct pci_ + advk_writel(pcie, 1, PIO_START); + + ret = advk_pcie_wait_pio(pcie); +- if (ret < 0) { +- /* +- * If it is possible return Completion Retry Status so caller +- * tries to issue the request again instead of failing. +- */ +- if (allow_crs) { +- *val = CFG_RD_CRS_VAL; +- return PCIBIOS_SUCCESSFUL; +- } +- *val = 0xffffffff; +- return PCIBIOS_SET_FAILED; +- } ++ if (ret < 0) ++ goto try_crs; + + /* Check PIO status and get the read result */ + ret = advk_pcie_check_pio_status(pcie, allow_crs, val); +- if (ret < 0) { +- *val = 0xffffffff; +- return PCIBIOS_SET_FAILED; +- } ++ if (ret < 0) ++ goto fail; + + if (size == 1) + *val = (*val >> (8 * (where & 3))) & 0xff; +@@ -834,6 +812,20 @@ static int advk_pcie_rd_conf(struct pci_ + *val = (*val >> (8 * (where & 3))) & 0xffff; + + return PCIBIOS_SUCCESSFUL; ++ ++try_crs: ++ /* ++ * If it is possible, return Completion Retry Status so that caller ++ * tries to issue the request again instead of failing. ++ */ ++ if (allow_crs) { ++ *val = CFG_RD_CRS_VAL; ++ return PCIBIOS_SUCCESSFUL; ++ } ++ ++fail: ++ *val = 0xffffffff; ++ return PCIBIOS_SET_FAILED; + } + + static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn, diff --git a/queue-5.4/pci-aardvark-don-t-touch-pcie-registers-if-no-card-connected.patch b/queue-5.4/pci-aardvark-don-t-touch-pcie-registers-if-no-card-connected.patch new file mode 100644 index 00000000000..d7f19e9545a --- /dev/null +++ b/queue-5.4/pci-aardvark-don-t-touch-pcie-registers-if-no-card-connected.patch @@ -0,0 +1,55 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:01 +0100 +Subject: PCI: aardvark: Don't touch PCIe registers if no card connected +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Lorenzo Pieralisi" , "Marek Behún" +Message-ID: <20211125002616.31363-8-kabel@kernel.org> + +From: Pali Rohár + +commit 70e380250c3621c55ff218cbaf2272830d9dbb1d upstream. + +When there is no PCIe card connected and advk_pcie_rd_conf() or +advk_pcie_wr_conf() is called for PCI bus which doesn't belong to emulated +root bridge, the aardvark driver throws the following error message: + + advk-pcie d0070000.pcie: config read/write timed out + +Obviously accessing PCIe registers of disconnected card is not possible. + +Extend check in advk_pcie_valid_device() function for validating +availability of PCIe bus. If PCIe link is down, then the device is marked +as Not Found and the driver does not try to access these registers. + +This is just an optimization to prevent accessing PCIe registers when card +is disconnected. Trying to access PCIe registers of disconnected card does +not cause any crash, kernel just needs to wait for a timeout. So if card +disappear immediately after checking for PCIe link (before accessing PCIe +registers), it does not cause any problems. + +Link: https://lore.kernel.org/r/20200702083036.12230-1-pali@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -806,6 +806,13 @@ static bool advk_pcie_valid_device(struc + if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0) + return false; + ++ /* ++ * If the link goes down after we check for link-up, nothing bad ++ * happens but the config access times out. ++ */ ++ if (bus->number != pcie->root_bus_nr && !advk_pcie_link_up(pcie)) ++ return false; ++ + return true; + } + diff --git a/queue-5.4/pci-aardvark-fix-big-endian-support.patch b/queue-5.4/pci-aardvark-fix-big-endian-support.patch new file mode 100644 index 00000000000..5ecb3f0af9b --- /dev/null +++ b/queue-5.4/pci-aardvark-fix-big-endian-support.patch @@ -0,0 +1,53 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:25:56 +0100 +Subject: PCI: aardvark: Fix big endian support +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Grzegorz Jaszczyk" , "Lorenzo Pieralisi" , "Marek Behún" +Message-ID: <20211125002616.31363-3-kabel@kernel.org> + +From: Grzegorz Jaszczyk + +commit e078723f9cccd509482fd7f30a4afb1125ca7a2a upstream. + +Initialise every multiple-byte field of emulated PCI bridge config +space with proper cpu_to_le* macro. This is required since the structure +describing config space of emulated bridge assumes little-endian +convention. + +Signed-off-by: Grzegorz Jaszczyk +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -686,18 +686,20 @@ static int advk_sw_pci_bridge_init(struc + struct pci_bridge_emul *bridge = &pcie->bridge; + int ret; + +- bridge->conf.vendor = advk_readl(pcie, PCIE_CORE_DEV_ID_REG) & 0xffff; +- bridge->conf.device = advk_readl(pcie, PCIE_CORE_DEV_ID_REG) >> 16; ++ bridge->conf.vendor = ++ cpu_to_le16(advk_readl(pcie, PCIE_CORE_DEV_ID_REG) & 0xffff); ++ bridge->conf.device = ++ cpu_to_le16(advk_readl(pcie, PCIE_CORE_DEV_ID_REG) >> 16); + bridge->conf.class_revision = +- advk_readl(pcie, PCIE_CORE_DEV_REV_REG) & 0xff; ++ cpu_to_le32(advk_readl(pcie, PCIE_CORE_DEV_REV_REG) & 0xff); + + /* Support 32 bits I/O addressing */ + bridge->conf.iobase = PCI_IO_RANGE_TYPE_32; + bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32; + + /* Support 64 bits memory pref */ +- bridge->conf.pref_mem_base = PCI_PREF_RANGE_TYPE_64; +- bridge->conf.pref_mem_limit = PCI_PREF_RANGE_TYPE_64; ++ bridge->conf.pref_mem_base = cpu_to_le16(PCI_PREF_RANGE_TYPE_64); ++ bridge->conf.pref_mem_limit = cpu_to_le16(PCI_PREF_RANGE_TYPE_64); + + /* Support interrupt A for MSI feature */ + bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE; diff --git a/queue-5.4/pci-aardvark-fix-compilation-on-s390.patch b/queue-5.4/pci-aardvark-fix-compilation-on-s390.patch new file mode 100644 index 00000000000..c7e384256c0 --- /dev/null +++ b/queue-5.4/pci-aardvark-fix-compilation-on-s390.patch @@ -0,0 +1,45 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:02 +0100 +Subject: PCI: aardvark: Fix compilation on s390 +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "kernel test robot" , "Lorenzo Pieralisi" , "Marek Behún" , "Marek Behún" +Message-ID: <20211125002616.31363-9-kabel@kernel.org> + +From: Pali Rohár + +commit b32c012e4b98f0126aa327be2d1f409963057643 upstream. + +Include linux/gpio/consumer.h instead of linux/gpio.h, as is said in the +latter file. + +This was reported by kernel test bot when compiling for s390. + + drivers/pci/controller/pci-aardvark.c:350:2: error: implicit declaration of function 'gpiod_set_value_cansleep' [-Werror,-Wimplicit-function-declaration] + drivers/pci/controller/pci-aardvark.c:1074:21: error: implicit declaration of function 'devm_gpiod_get_from_of_node' [-Werror,-Wimplicit-function-declaration] + drivers/pci/controller/pci-aardvark.c:1076:14: error: use of undeclared identifier 'GPIOD_OUT_LOW' + +Link: https://lore.kernel.org/r/202006211118.LxtENQfl%25lkp@intel.com +Link: https://lore.kernel.org/r/20200907111038.5811-2-pali@kernel.org +Fixes: 5169a9851daa ("PCI: aardvark: Issue PERST via GPIO") +Reported-by: kernel test robot +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -9,7 +9,7 @@ + */ + + #include +-#include ++#include + #include + #include + #include diff --git a/queue-5.4/pci-aardvark-fix-link-training.patch b/queue-5.4/pci-aardvark-fix-link-training.patch new file mode 100644 index 00000000000..09cc0c21db5 --- /dev/null +++ b/queue-5.4/pci-aardvark-fix-link-training.patch @@ -0,0 +1,320 @@ +From foo@baz Sun Nov 28 01:44:18 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:11 +0100 +Subject: PCI: aardvark: Fix link training +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" +Message-ID: <20211125002616.31363-18-kabel@kernel.org> + +From: Pali Rohár + +commit f76b36d40beee0a13aa8f6aa011df0d7cbbb8a7f upstream. + +Fix multiple link training issues in aardvark driver. The main reason of +these issues was misunderstanding of what certain registers do, since their +names and comments were misleading: before commit 96be36dbffac ("PCI: +aardvark: Replace custom macros by standard linux/pci_regs.h macros"), the +pci-aardvark.c driver used custom macros for accessing standard PCIe Root +Bridge registers, and misleading comments did not help to understand what +the code was really doing. + +After doing more tests and experiments I've come to the conclusion that the +SPEED_GEN register in aardvark sets the PCIe revision / generation +compliance and forces maximal link speed. Both GEN3 and GEN2 values set the +read-only PCI_EXP_FLAGS_VERS bits (PCIe capabilities version of Root +Bridge) to value 2, while GEN1 value sets PCI_EXP_FLAGS_VERS to 1, which +matches with PCI Express specifications revisions 3, 2 and 1 respectively. +Changing SPEED_GEN also sets the read-only bits PCI_EXP_LNKCAP_SLS and +PCI_EXP_LNKCAP2_SLS to corresponding speed. + +(Note that PCI Express rev 1 specification does not define PCI_EXP_LNKCAP2 + and PCI_EXP_LNKCTL2 registers and when SPEED_GEN is set to GEN1 (which + also sets PCI_EXP_FLAGS_VERS set to 1), lspci cannot access + PCI_EXP_LNKCAP2 and PCI_EXP_LNKCTL2 registers.) + +Changing PCIe link speed can be done via PCI_EXP_LNKCTL2_TLS bits of +PCI_EXP_LNKCTL2 register. Armada 3700 Functional Specifications says that +the default value of PCI_EXP_LNKCTL2_TLS is based on SPEED_GEN value, but +tests showed that the default value is always 8.0 GT/s, independently of +speed set by SPEED_GEN. So after setting SPEED_GEN, we must also set value +in PCI_EXP_LNKCTL2 register via PCI_EXP_LNKCTL2_TLS bits. + +Triggering PCI_EXP_LNKCTL_RL bit immediately after setting LINK_TRAINING_EN +bit actually doesn't do anything. Tests have shown that a delay is needed +after enabling LINK_TRAINING_EN bit. As triggering PCI_EXP_LNKCTL_RL +currently does nothing, remove it. + +Commit 43fc679ced18 ("PCI: aardvark: Improve link training") introduced +code which sets SPEED_GEN register based on negotiated link speed from +PCI_EXP_LNKSTA_CLS bits of PCI_EXP_LNKSTA register. This code was added to +fix detection of Compex WLE900VX (Atheros QCA9880) WiFi GEN1 PCIe cards, as +otherwise these cards were "invisible" on PCIe bus (probably because they +crashed). But apparently more people reported the same issues with these +cards also with other PCIe controllers [1] and I was able to reproduce this +issue also with other "noname" WiFi cards based on Atheros QCA9890 chip +(with the same PCI vendor/device ids as Atheros QCA9880). So this is not an +issue in aardvark but rather an issue in Atheros QCA98xx chips. Also, this +issue only exists if the kernel is compiled with PCIe ASPM support, and a +generic workaround for this is to change PCIe Bridge to 2.5 GT/s link speed +via PCI_EXP_LNKCTL2_TLS_2_5GT bits in PCI_EXP_LNKCTL2 register [2], before +triggering PCI_EXP_LNKCTL_RL bit. This workaround also works when SPEED_GEN +is set to value GEN2 (5 GT/s). So remove this hack completely in the +aardvark driver and always set SPEED_GEN to value from 'max-link-speed' DT +property. Fix for Atheros QCA98xx chips is handled separately by patch [2]. + +These two things (code for triggering PCI_EXP_LNKCTL_RL bit and changing +SPEED_GEN value) also explain why commit 6964494582f5 ("PCI: aardvark: +Train link immediately after enabling training") somehow fixed detection of +those problematic Compex cards with Atheros chips: if triggering link +retraining (via PCI_EXP_LNKCTL_RL bit) was done immediately after enabling +link training (via LINK_TRAINING_EN), it did nothing. If there was a +specific delay, aardvark HW already initialized PCIe link and therefore +triggering link retraining caused the above issue. Compex cards triggered +link down event and disappeared from the PCIe bus. + +Commit f4c7d053d7f7 ("PCI: aardvark: Wait for endpoint to be ready before +training link") added 100ms sleep before calling 'Start link training' +command and explained that it is a requirement of PCI Express +specification. But the code after this 100ms sleep was not doing 'Start +link training', rather it triggered PCI_EXP_LNKCTL_RL bit via PCIe Root +Bridge to put link into Recovery state. + +The required delay after fundamental reset is already done in function +advk_pcie_wait_for_link() which also checks whether PCIe link is up. +So after removing the code which triggers PCI_EXP_LNKCTL_RL bit on PCIe +Root Bridge, there is no need to wait 100ms again. Remove the extra +msleep() call and update comment about the delay required by the PCI +Express specification. + +According to Marvell Armada 3700 Functional Specifications, Link training +should be enabled via aardvark register LINK_TRAINING_EN after selecting +PCIe generation and x1 lane. There is no need to disable it prior resetting +card via PERST# signal. This disabling code was introduced in commit +5169a9851daa ("PCI: aardvark: Issue PERST via GPIO") as a workaround for +some Atheros cards. It turns out that this also is Atheros specific issue +and affects any PCIe controller, not only aardvark. Moreover this Atheros +issue was triggered by juggling with PCI_EXP_LNKCTL_RL, LINK_TRAINING_EN +and SPEED_GEN bits interleaved with sleeps. Now, after removing triggering +PCI_EXP_LNKCTL_RL, there is no need to explicitly disable LINK_TRAINING_EN +bit. So remove this code too. The problematic Compex cards described in +previous git commits are correctly detected in advk_pcie_train_link() +function even after applying all these changes. + +Note that with this patch, and also prior this patch, some NVMe disks which +support PCIe GEN3 with 8 GT/s speed are negotiated only at the lowest link +speed 2.5 GT/s, independently of SPEED_GEN value. After manually triggering +PCI_EXP_LNKCTL_RL bit (e.g. from userspace via setpci), these NVMe disks +change link speed to 5 GT/s when SPEED_GEN was configured to GEN2. This +issue first needs to be properly investigated. I will send a fix in the +future. + +On the other hand, some other GEN2 PCIe cards with 5 GT/s speed are +autonomously by HW autonegotiated at full 5 GT/s speed without need of any +software interaction. + +Armada 3700 Functional Specifications describes the following steps for +link training: set SPEED_GEN to GEN2, enable LINK_TRAINING_EN, poll until +link training is complete, trigger PCI_EXP_LNKCTL_RL, poll until signal +rate is 5 GT/s, poll until link training is complete, enable ASPM L0s. + +The requirement for triggering PCI_EXP_LNKCTL_RL can be explained by the +need to achieve 5 GT/s speed (as changing link speed is done by throw to +recovery state entered by PCI_EXP_LNKCTL_RL) or maybe as a part of enabling +ASPM L0s (but in this case ASPM L0s should have been enabled prior +PCI_EXP_LNKCTL_RL). + +It is unknown why the original pci-aardvark.c driver was triggering +PCI_EXP_LNKCTL_RL bit before waiting for the link to be up. This does not +align with neither PCIe base specifications nor with Armada 3700 Functional +Specification. (Note that in older versions of aardvark, this bit was +called incorrectly PCIE_CORE_LINK_TRAINING, so this may be the reason.) + +It is also unknown why Armada 3700 Functional Specification says that it is +needed to trigger PCI_EXP_LNKCTL_RL for GEN2 mode, as according to PCIe +base specification 5 GT/s speed negotiation is supposed to be entirely +autonomous, even if initial speed is 2.5 GT/s. + +[1] - https://lore.kernel.org/linux-pci/87h7l8axqp.fsf@toke.dk/ +[2] - https://lore.kernel.org/linux-pci/20210326124326.21163-1-pali@kernel.org/ + +Link: https://lore.kernel.org/r/20211005180952.6812-12-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 119 ++++++++++------------------------ + 1 file changed, 35 insertions(+), 84 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -303,11 +303,6 @@ static inline u32 advk_readl(struct advk + return readl(pcie->base + reg); + } + +-static inline u16 advk_read16(struct advk_pcie *pcie, u64 reg) +-{ +- return advk_readl(pcie, (reg & ~0x3)) >> ((reg & 0x3) * 8); +-} +- + static u8 advk_pcie_ltssm_state(struct advk_pcie *pcie) + { + u32 val; +@@ -381,23 +376,9 @@ static void advk_pcie_wait_for_retrain(s + + static void advk_pcie_issue_perst(struct advk_pcie *pcie) + { +- u32 reg; +- + if (!pcie->reset_gpio) + return; + +- /* +- * As required by PCI Express spec (PCI Express Base Specification, REV. +- * 4.0 PCI Express, February 19 2014, 6.6.1 Conventional Reset) a delay +- * for at least 100ms after de-asserting PERST# signal is needed before +- * link training is enabled. So ensure that link training is disabled +- * prior de-asserting PERST# signal to fulfill that PCI Express spec +- * requirement. +- */ +- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); +- reg &= ~LINK_TRAINING_EN; +- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); +- + /* 10ms delay is needed for some cards */ + dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); + gpiod_set_value_cansleep(pcie->reset_gpio, 1); +@@ -405,54 +386,47 @@ static void advk_pcie_issue_perst(struct + gpiod_set_value_cansleep(pcie->reset_gpio, 0); + } + +-static int advk_pcie_train_at_gen(struct advk_pcie *pcie, int gen) ++static void advk_pcie_train_link(struct advk_pcie *pcie) + { +- int ret, neg_gen; ++ struct device *dev = &pcie->pdev->dev; + u32 reg; ++ int ret; + +- /* Setup link speed */ ++ /* ++ * Setup PCIe rev / gen compliance based on device tree property ++ * 'max-link-speed' which also forces maximal link speed. ++ */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg &= ~PCIE_GEN_SEL_MSK; +- if (gen == 3) ++ if (pcie->link_gen == 3) + reg |= SPEED_GEN_3; +- else if (gen == 2) ++ else if (pcie->link_gen == 2) + reg |= SPEED_GEN_2; + else + reg |= SPEED_GEN_1; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + + /* +- * Enable link training. This is not needed in every call to this +- * function, just once suffices, but it does not break anything either. +- */ ++ * Set maximal link speed value also into PCIe Link Control 2 register. ++ * Armada 3700 Functional Specification says that default value is based ++ * on SPEED_GEN but tests showed that default value is always 8.0 GT/s. ++ */ ++ reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL2); ++ reg &= ~PCI_EXP_LNKCTL2_TLS; ++ if (pcie->link_gen == 3) ++ reg |= PCI_EXP_LNKCTL2_TLS_8_0GT; ++ else if (pcie->link_gen == 2) ++ reg |= PCI_EXP_LNKCTL2_TLS_5_0GT; ++ else ++ reg |= PCI_EXP_LNKCTL2_TLS_2_5GT; ++ advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL2); ++ ++ /* Enable link training after selecting PCIe generation */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg |= LINK_TRAINING_EN; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + + /* +- * Start link training immediately after enabling it. +- * This solves problems for some buggy cards. +- */ +- reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL); +- reg |= PCI_EXP_LNKCTL_RL; +- advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL); +- +- ret = advk_pcie_wait_for_link(pcie); +- if (ret) +- return ret; +- +- reg = advk_read16(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKSTA); +- neg_gen = reg & PCI_EXP_LNKSTA_CLS; +- +- return neg_gen; +-} +- +-static void advk_pcie_train_link(struct advk_pcie *pcie) +-{ +- struct device *dev = &pcie->pdev->dev; +- int neg_gen = -1, gen; +- +- /* + * Reset PCIe card via PERST# signal. Some cards are not detected + * during link training when they are in some non-initial state. + */ +@@ -462,41 +436,18 @@ static void advk_pcie_train_link(struct + * PERST# signal could have been asserted by pinctrl subsystem before + * probe() callback has been called or issued explicitly by reset gpio + * function advk_pcie_issue_perst(), making the endpoint going into +- * fundamental reset. As required by PCI Express spec a delay for at +- * least 100ms after such a reset before link training is needed. +- */ +- msleep(PCI_PM_D3COLD_WAIT); +- +- /* +- * Try link training at link gen specified by device tree property +- * 'max-link-speed'. If this fails, iteratively train at lower gen. +- */ +- for (gen = pcie->link_gen; gen > 0; --gen) { +- neg_gen = advk_pcie_train_at_gen(pcie, gen); +- if (neg_gen > 0) +- break; +- } +- +- if (neg_gen < 0) +- goto err; +- +- /* +- * After successful training if negotiated gen is lower than requested, +- * train again on negotiated gen. This solves some stability issues for +- * some buggy gen1 cards. ++ * fundamental reset. As required by PCI Express spec (PCI Express ++ * Base Specification, REV. 4.0 PCI Express, February 19 2014, 6.6.1 ++ * Conventional Reset) a delay for at least 100ms after such a reset ++ * before sending a Configuration Request to the device is needed. ++ * So wait until PCIe link is up. Function advk_pcie_wait_for_link() ++ * waits for link at least 900ms. + */ +- if (neg_gen < gen) { +- gen = neg_gen; +- neg_gen = advk_pcie_train_at_gen(pcie, gen); +- } +- +- if (neg_gen == gen) { +- dev_info(dev, "link up at gen %i\n", gen); +- return; +- } +- +-err: +- dev_err(dev, "link never came up\n"); ++ 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"); + } + + /* diff --git a/queue-5.4/pci-aardvark-fix-pcie-max-payload-size-setting.patch b/queue-5.4/pci-aardvark-fix-pcie-max-payload-size-setting.patch new file mode 100644 index 00000000000..a23057f904b --- /dev/null +++ b/queue-5.4/pci-aardvark-fix-pcie-max-payload-size-setting.patch @@ -0,0 +1,51 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:07 +0100 +Subject: PCI: aardvark: Fix PCIe Max Payload Size setting +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" +Message-ID: <20211125002616.31363-14-kabel@kernel.org> + +From: Pali Rohár + +commit a4e17d65dafdd3513042d8f00404c9b6068a825c upstream. + +Change PCIe Max Payload Size setting in PCIe Device Control register to 512 +bytes to align with PCIe Link Initialization sequence as defined in Marvell +Armada 3700 Functional Specification. According to the specification, +maximal Max Payload Size supported by this device is 512 bytes. + +Without this kernel prints suspicious line: + + pci 0000:01:00.0: Upstream bridge's Max Payload Size set to 256 (was 16384, max 512) + +With this change it changes to: + + pci 0000:01:00.0: Upstream bridge's Max Payload Size set to 256 (was 512, max 512) + +Link: https://lore.kernel.org/r/20211005180952.6812-3-kabel@kernel.org +Fixes: 8c39d710363c ("PCI: aardvark: Add Aardvark PCI host controller driver") +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Cc: stable@vger.kernel.org +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -565,8 +565,9 @@ static void advk_pcie_setup_hw(struct ad + reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); + reg &= ~PCI_EXP_DEVCTL_RELAX_EN; + reg &= ~PCI_EXP_DEVCTL_NOSNOOP_EN; ++ reg &= ~PCI_EXP_DEVCTL_PAYLOAD; + reg &= ~PCI_EXP_DEVCTL_READRQ; +- reg |= PCI_EXP_DEVCTL_PAYLOAD; /* Set max payload size */ ++ reg |= PCI_EXP_DEVCTL_PAYLOAD_512B; + reg |= PCI_EXP_DEVCTL_READRQ_512B; + advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); + diff --git a/queue-5.4/pci-aardvark-fix-support-for-bus-mastering-and-pci_command-on-emulated-bridge.patch b/queue-5.4/pci-aardvark-fix-support-for-bus-mastering-and-pci_command-on-emulated-bridge.patch new file mode 100644 index 00000000000..7802898480c --- /dev/null +++ b/queue-5.4/pci-aardvark-fix-support-for-bus-mastering-and-pci_command-on-emulated-bridge.patch @@ -0,0 +1,125 @@ +From foo@baz Sun Nov 28 01:44:18 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:12 +0100 +Subject: PCI: aardvark: Fix support for bus mastering and PCI_COMMAND on emulated bridge +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" +Message-ID: <20211125002616.31363-19-kabel@kernel.org> + +From: Pali Rohár + +commit 771153fc884f566a89af2d30033b7f3bc6e24e84 upstream. + +>From very vague, ambiguous and incomplete information from Marvell we +deduced that the 32-bit Aardvark register at address 0x4 +(PCIE_CORE_CMD_STATUS_REG), which is not documented for Root Complex mode +in the Functional Specification (only for Endpoint mode), controls two +16-bit PCIe registers: Command Register and Status Registers of PCIe Root +Port. + +This means that bit 2 controls bus mastering and forwarding of memory and +I/O requests in the upstream direction. According to PCI specifications +bits [0:2] of Command Register, this should be by default disabled on +reset. So explicitly disable these bits at early setup of the Aardvark +driver. + +Remove code which unconditionally enables all 3 bits and let kernel code +(via pci_set_master() function) to handle bus mastering of Root PCIe +Bridge via emulated PCI_COMMAND on emulated bridge. + +Link: https://lore.kernel.org/r/20211028185659.20329-5-kabel@kernel.org +Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space") +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Cc: stable@vger.kernel.org # b2a56469d550 ("PCI: aardvark: Add FIXME comment for PCIE_CORE_CMD_STATUS_REG access") +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 47 +++++++++++++++++++++++++++------- + 1 file changed, 38 insertions(+), 9 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -27,9 +27,6 @@ + /* PCIe core registers */ + #define PCIE_CORE_DEV_ID_REG 0x0 + #define PCIE_CORE_CMD_STATUS_REG 0x4 +-#define PCIE_CORE_CMD_IO_ACCESS_EN BIT(0) +-#define PCIE_CORE_CMD_MEM_ACCESS_EN BIT(1) +-#define PCIE_CORE_CMD_MEM_IO_REQ_EN BIT(2) + #define PCIE_CORE_DEV_REV_REG 0x8 + #define PCIE_CORE_PCIEXP_CAP 0xc0 + #define PCIE_CORE_ERR_CAPCTL_REG 0x118 +@@ -505,6 +502,11 @@ static void advk_pcie_setup_hw(struct ad + reg = (PCI_VENDOR_ID_MARVELL << 16) | PCI_VENDOR_ID_MARVELL; + advk_writel(pcie, reg, VENDOR_ID_REG); + ++ /* Disable Root Bridge I/O space, memory space and bus mastering */ ++ reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); ++ reg &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); ++ advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); ++ + /* Set Advanced Error Capabilities and Control PF0 register */ + reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX | + PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN | +@@ -603,12 +605,6 @@ static void advk_pcie_setup_hw(struct ad + advk_pcie_disable_ob_win(pcie, i); + + advk_pcie_train_link(pcie); +- +- reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); +- reg |= PCIE_CORE_CMD_MEM_ACCESS_EN | +- PCIE_CORE_CMD_IO_ACCESS_EN | +- PCIE_CORE_CMD_MEM_IO_REQ_EN; +- advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); + } + + static int advk_pcie_check_pio_status(struct advk_pcie *pcie, bool allow_crs, u32 *val) +@@ -737,6 +733,37 @@ static int advk_pcie_wait_pio(struct adv + return -ETIMEDOUT; + } + ++static pci_bridge_emul_read_status_t ++advk_pci_bridge_emul_base_conf_read(struct pci_bridge_emul *bridge, ++ int reg, u32 *value) ++{ ++ struct advk_pcie *pcie = bridge->data; ++ ++ switch (reg) { ++ case PCI_COMMAND: ++ *value = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); ++ return PCI_BRIDGE_EMUL_HANDLED; ++ ++ default: ++ return PCI_BRIDGE_EMUL_NOT_HANDLED; ++ } ++} ++ ++static void ++advk_pci_bridge_emul_base_conf_write(struct pci_bridge_emul *bridge, ++ int reg, u32 old, u32 new, u32 mask) ++{ ++ struct advk_pcie *pcie = bridge->data; ++ ++ switch (reg) { ++ case PCI_COMMAND: ++ advk_writel(pcie, new, PCIE_CORE_CMD_STATUS_REG); ++ break; ++ ++ default: ++ break; ++ } ++} + + static pci_bridge_emul_read_status_t + advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge, +@@ -838,6 +865,8 @@ advk_pci_bridge_emul_pcie_conf_write(str + } + + static struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = { ++ .read_base = advk_pci_bridge_emul_base_conf_read, ++ .write_base = advk_pci_bridge_emul_base_conf_write, + .read_pcie = advk_pci_bridge_emul_pcie_conf_read, + .write_pcie = advk_pci_bridge_emul_pcie_conf_write, + }; diff --git a/queue-5.4/pci-aardvark-fix-support-for-pci_bridge_ctl_bus_reset-on-emulated-bridge.patch b/queue-5.4/pci-aardvark-fix-support-for-pci_bridge_ctl_bus_reset-on-emulated-bridge.patch new file mode 100644 index 00000000000..a87b6bca3cb --- /dev/null +++ b/queue-5.4/pci-aardvark-fix-support-for-pci_bridge_ctl_bus_reset-on-emulated-bridge.patch @@ -0,0 +1,78 @@ +From foo@baz Sun Nov 28 01:44:18 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:14 +0100 +Subject: PCI: aardvark: Fix support for PCI_BRIDGE_CTL_BUS_RESET on emulated bridge +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" +Message-ID: <20211125002616.31363-21-kabel@kernel.org> + +From: Pali Rohár + +commit bc4fac42e5f8460af09c0a7f2f1915be09e20c71 upstream. + +Aardvark supports PCIe Hot Reset via PCIE_CORE_CTRL1_REG. + +Use it for implementing PCI_BRIDGE_CTL_BUS_RESET bit of PCI_BRIDGE_CONTROL +register on emulated bridge. + +With this, the function pci_reset_secondary_bus() starts working and can +reset connected PCIe card. Custom userspace script [1] which uses setpci +can trigger PCIe Hot Reset and reset the card manually. + +[1] https://alexforencich.com/wiki/en/pcie/hot-reset-linux + +Link: https://lore.kernel.org/r/20211028185659.20329-7-kabel@kernel.org +Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space") +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Cc: stable@vger.kernel.org +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -764,6 +764,22 @@ advk_pci_bridge_emul_base_conf_read(stru + *value = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); + return PCI_BRIDGE_EMUL_HANDLED; + ++ case PCI_INTERRUPT_LINE: { ++ /* ++ * From the whole 32bit register we support reading from HW only ++ * one bit: PCI_BRIDGE_CTL_BUS_RESET. ++ * Other bits are retrieved only from emulated config buffer. ++ */ ++ __le32 *cfgspace = (__le32 *)&bridge->conf; ++ u32 val = le32_to_cpu(cfgspace[PCI_INTERRUPT_LINE / 4]); ++ if (advk_readl(pcie, PCIE_CORE_CTRL1_REG) & HOT_RESET_GEN) ++ val |= PCI_BRIDGE_CTL_BUS_RESET << 16; ++ else ++ val &= ~(PCI_BRIDGE_CTL_BUS_RESET << 16); ++ *value = val; ++ return PCI_BRIDGE_EMUL_HANDLED; ++ } ++ + default: + return PCI_BRIDGE_EMUL_NOT_HANDLED; + } +@@ -780,6 +796,17 @@ advk_pci_bridge_emul_base_conf_write(str + advk_writel(pcie, new, PCIE_CORE_CMD_STATUS_REG); + break; + ++ case PCI_INTERRUPT_LINE: ++ if (mask & (PCI_BRIDGE_CTL_BUS_RESET << 16)) { ++ u32 val = advk_readl(pcie, PCIE_CORE_CTRL1_REG); ++ if (new & (PCI_BRIDGE_CTL_BUS_RESET << 16)) ++ val |= HOT_RESET_GEN; ++ else ++ val &= ~HOT_RESET_GEN; ++ advk_writel(pcie, val, PCIE_CORE_CTRL1_REG); ++ } ++ break; ++ + default: + break; + } diff --git a/queue-5.4/pci-aardvark-implement-re-issuing-config-requests-on-crs-response.patch b/queue-5.4/pci-aardvark-implement-re-issuing-config-requests-on-crs-response.patch new file mode 100644 index 00000000000..ddef196b6dd --- /dev/null +++ b/queue-5.4/pci-aardvark-implement-re-issuing-config-requests-on-crs-response.patch @@ -0,0 +1,212 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:09 +0100 +Subject: PCI: aardvark: Implement re-issuing config requests on CRS response +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" +Message-ID: <20211125002616.31363-16-kabel@kernel.org> + +From: Pali Rohár + +commit 223dec14a05337a4155f1deed46d2becce4d00fd upstream. + +Commit 43f5c77bcbd2 ("PCI: aardvark: Fix reporting CRS value") fixed +handling of CRS response and when CRSSVE flag was not enabled it marked CRS +response as failed transaction (due to simplicity). + +But pci-aardvark.c driver is already waiting up to the PIO_RETRY_CNT count +for PIO config response and so we can with a small change implement +re-issuing of config requests as described in PCIe base specification. + +This change implements re-issuing of config requests when response is CRS. +Set upper bound of wait cycles to around PIO_RETRY_CNT, afterwards the +transaction is marked as failed and an all-ones value is returned as +before. + +We do this by returning appropriate error codes from function +advk_pcie_check_pio_status(). On CRS we return -EAGAIN and caller then +reissues transaction. + +Link: https://lore.kernel.org/r/20211005180952.6812-10-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 69 +++++++++++++++++++++------------- + 1 file changed, 44 insertions(+), 25 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -666,6 +666,7 @@ static int advk_pcie_check_pio_status(st + u32 reg; + unsigned int status; + char *strcomp_status, *str_posted; ++ int ret; + + reg = advk_readl(pcie, PIO_STAT); + status = (reg & PIO_COMPLETION_STATUS_MASK) >> +@@ -690,6 +691,7 @@ static int advk_pcie_check_pio_status(st + case PIO_COMPLETION_STATUS_OK: + if (reg & PIO_ERR_STATUS) { + strcomp_status = "COMP_ERR"; ++ ret = -EFAULT; + break; + } + /* Get the read result */ +@@ -697,9 +699,11 @@ static int advk_pcie_check_pio_status(st + *val = advk_readl(pcie, PIO_RD_DATA); + /* No error */ + strcomp_status = NULL; ++ ret = 0; + break; + case PIO_COMPLETION_STATUS_UR: + strcomp_status = "UR"; ++ ret = -EOPNOTSUPP; + break; + case PIO_COMPLETION_STATUS_CRS: + if (allow_crs && val) { +@@ -717,6 +721,7 @@ static int advk_pcie_check_pio_status(st + */ + *val = CFG_RD_CRS_VAL; + strcomp_status = NULL; ++ ret = 0; + break; + } + /* PCIe r4.0, sec 2.3.2, says: +@@ -732,21 +737,24 @@ static int advk_pcie_check_pio_status(st + * Request and taking appropriate action, e.g., complete the + * Request to the host as a failed transaction. + * +- * To simplify implementation do not re-issue the Configuration +- * Request and complete the Request as a failed transaction. ++ * So return -EAGAIN and caller (pci-aardvark.c driver) will ++ * re-issue request again up to the PIO_RETRY_CNT retries. + */ + strcomp_status = "CRS"; ++ ret = -EAGAIN; + break; + case PIO_COMPLETION_STATUS_CA: + strcomp_status = "CA"; ++ ret = -ECANCELED; + break; + default: + strcomp_status = "Unknown"; ++ ret = -EINVAL; + break; + } + + if (!strcomp_status) +- return 0; ++ return ret; + + if (reg & PIO_NON_POSTED_REQ) + str_posted = "Non-posted"; +@@ -756,7 +764,7 @@ static int advk_pcie_check_pio_status(st + dev_dbg(dev, "%s PIO Response Status: %s, %#x @ %#x\n", + str_posted, strcomp_status, reg, advk_readl(pcie, PIO_ADDR_LS)); + +- return -EFAULT; ++ return ret; + } + + static int advk_pcie_wait_pio(struct advk_pcie *pcie) +@@ -764,13 +772,13 @@ static int advk_pcie_wait_pio(struct adv + struct device *dev = &pcie->pdev->dev; + int i; + +- for (i = 0; i < PIO_RETRY_CNT; i++) { ++ for (i = 1; i <= PIO_RETRY_CNT; i++) { + u32 start, isr; + + start = advk_readl(pcie, PIO_START); + isr = advk_readl(pcie, PIO_ISR); + if (!start && isr) +- return 0; ++ return i; + udelay(PIO_RETRY_DELAY); + } + +@@ -974,6 +982,7 @@ static int advk_pcie_rd_conf(struct pci_ + int where, int size, u32 *val) + { + struct advk_pcie *pcie = bus->sysdata; ++ int retry_count; + bool allow_crs; + u32 reg; + int ret; +@@ -1016,16 +1025,22 @@ static int advk_pcie_rd_conf(struct pci_ + /* Program the data strobe */ + advk_writel(pcie, 0xf, PIO_WR_DATA_STRB); + +- /* Clear PIO DONE ISR and start the transfer */ +- advk_writel(pcie, 1, PIO_ISR); +- advk_writel(pcie, 1, PIO_START); +- +- ret = advk_pcie_wait_pio(pcie); +- if (ret < 0) +- goto try_crs; ++ retry_count = 0; ++ do { ++ /* Clear PIO DONE ISR and start the transfer */ ++ advk_writel(pcie, 1, PIO_ISR); ++ advk_writel(pcie, 1, PIO_START); ++ ++ ret = advk_pcie_wait_pio(pcie); ++ if (ret < 0) ++ goto try_crs; ++ ++ retry_count += ret; ++ ++ /* Check PIO status and get the read result */ ++ ret = advk_pcie_check_pio_status(pcie, allow_crs, val); ++ } while (ret == -EAGAIN && retry_count < PIO_RETRY_CNT); + +- /* Check PIO status and get the read result */ +- ret = advk_pcie_check_pio_status(pcie, allow_crs, val); + if (ret < 0) + goto fail; + +@@ -1057,6 +1072,7 @@ static int advk_pcie_wr_conf(struct pci_ + struct advk_pcie *pcie = bus->sysdata; + u32 reg; + u32 data_strobe = 0x0; ++ int retry_count; + int offset; + int ret; + +@@ -1098,19 +1114,22 @@ static int advk_pcie_wr_conf(struct pci_ + /* Program the data strobe */ + advk_writel(pcie, data_strobe, PIO_WR_DATA_STRB); + +- /* Clear PIO DONE ISR and start the transfer */ +- advk_writel(pcie, 1, PIO_ISR); +- advk_writel(pcie, 1, PIO_START); ++ retry_count = 0; ++ do { ++ /* Clear PIO DONE ISR and start the transfer */ ++ advk_writel(pcie, 1, PIO_ISR); ++ advk_writel(pcie, 1, PIO_START); ++ ++ ret = advk_pcie_wait_pio(pcie); ++ if (ret < 0) ++ return PCIBIOS_SET_FAILED; + +- ret = advk_pcie_wait_pio(pcie); +- if (ret < 0) +- return PCIBIOS_SET_FAILED; ++ retry_count += ret; + +- ret = advk_pcie_check_pio_status(pcie, false, NULL); +- if (ret < 0) +- return PCIBIOS_SET_FAILED; ++ ret = advk_pcie_check_pio_status(pcie, false, NULL); ++ } while (ret == -EAGAIN && retry_count < PIO_RETRY_CNT); + +- return PCIBIOS_SUCCESSFUL; ++ return ret < 0 ? PCIBIOS_SET_FAILED : PCIBIOS_SUCCESSFUL; + } + + static struct pci_ops advk_pcie_ops = { diff --git a/queue-5.4/pci-aardvark-improve-link-training.patch b/queue-5.4/pci-aardvark-improve-link-training.patch new file mode 100644 index 00000000000..73a1f1b19d2 --- /dev/null +++ b/queue-5.4/pci-aardvark-improve-link-training.patch @@ -0,0 +1,214 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:25:58 +0100 +Subject: PCI: aardvark: Improve link training +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Tomasz Maciej Nowak" , "Lorenzo Pieralisi" , "Rob Herring" , "Thomas Petazzoni" , "Marek Behún" +Message-ID: <20211125002616.31363-5-kabel@kernel.org> + +From: Marek Behún + +commit 43fc679ced18006b12d918d7a8a4af392b7fbfe7 upstream. + +Currently the aardvark driver trains link in PCIe gen2 mode. This may +cause some buggy gen1 cards (such as Compex WLE900VX) to be unstable or +even not detected. Moreover when ASPM code tries to retrain link second +time, these cards may stop responding and link goes down. If gen1 is +used this does not happen. + +Unconditionally forcing gen1 is not a good solution since it may have +performance impact on gen2 cards. + +To overcome this, read 'max-link-speed' property (as defined in PCI +device tree bindings) and use this as max gen mode. Then iteratively try +link training at this mode or lower until successful. After successful +link training choose final controller gen based on Negotiated Link Speed +from Link Status register, which should match card speed. + +Link: https://lore.kernel.org/r/20200430080625.26070-5-pali@kernel.org +Tested-by: Tomasz Maciej Nowak +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Rob Herring +Acked-by: Thomas Petazzoni +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 114 ++++++++++++++++++++++++++-------- + 1 file changed, 89 insertions(+), 25 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -39,6 +39,7 @@ + #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 + #define PCIE_CORE_LINK_L0S_ENTRY BIT(0) + #define PCIE_CORE_LINK_TRAINING BIT(5) ++#define PCIE_CORE_LINK_SPEED_SHIFT 16 + #define PCIE_CORE_LINK_WIDTH_SHIFT 20 + #define PCIE_CORE_ERR_CAPCTL_REG 0x118 + #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5) +@@ -249,6 +250,7 @@ struct advk_pcie { + struct mutex msi_used_lock; + u16 msi_msg; + int root_bus_nr; ++ int link_gen; + struct pci_bridge_emul bridge; + }; + +@@ -309,20 +311,16 @@ static inline bool advk_pcie_link_traini + + static int advk_pcie_wait_for_link(struct advk_pcie *pcie) + { +- struct device *dev = &pcie->pdev->dev; + int retries; + + /* check if the link is up or not */ + for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { +- if (advk_pcie_link_up(pcie)) { +- dev_info(dev, "link up\n"); ++ if (advk_pcie_link_up(pcie)) + return 0; +- } + + usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); + } + +- dev_err(dev, "link never came up\n"); + return -ETIMEDOUT; + } + +@@ -337,6 +335,85 @@ static void advk_pcie_wait_for_retrain(s + } + } + ++static int advk_pcie_train_at_gen(struct advk_pcie *pcie, int gen) ++{ ++ int ret, neg_gen; ++ u32 reg; ++ ++ /* Setup link speed */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg &= ~PCIE_GEN_SEL_MSK; ++ if (gen == 3) ++ reg |= SPEED_GEN_3; ++ else if (gen == 2) ++ reg |= SPEED_GEN_2; ++ else ++ reg |= SPEED_GEN_1; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* ++ * Enable link training. This is not needed in every call to this ++ * function, just once suffices, but it does not break anything either. ++ */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg |= LINK_TRAINING_EN; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* ++ * Start link training immediately after enabling it. ++ * This solves problems for some buggy cards. ++ */ ++ reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); ++ reg |= PCIE_CORE_LINK_TRAINING; ++ advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); ++ ++ ret = advk_pcie_wait_for_link(pcie); ++ if (ret) ++ return ret; ++ ++ reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); ++ neg_gen = (reg >> PCIE_CORE_LINK_SPEED_SHIFT) & 0xf; ++ ++ return neg_gen; ++} ++ ++static void advk_pcie_train_link(struct advk_pcie *pcie) ++{ ++ struct device *dev = &pcie->pdev->dev; ++ int neg_gen = -1, gen; ++ ++ /* ++ * Try link training at link gen specified by device tree property ++ * 'max-link-speed'. If this fails, iteratively train at lower gen. ++ */ ++ for (gen = pcie->link_gen; gen > 0; --gen) { ++ neg_gen = advk_pcie_train_at_gen(pcie, gen); ++ if (neg_gen > 0) ++ break; ++ } ++ ++ if (neg_gen < 0) ++ goto err; ++ ++ /* ++ * After successful training if negotiated gen is lower than requested, ++ * train again on negotiated gen. This solves some stability issues for ++ * some buggy gen1 cards. ++ */ ++ if (neg_gen < gen) { ++ gen = neg_gen; ++ neg_gen = advk_pcie_train_at_gen(pcie, gen); ++ } ++ ++ if (neg_gen == gen) { ++ dev_info(dev, "link up at gen %i\n", gen); ++ return; ++ } ++ ++err: ++ dev_err(dev, "link never came up\n"); ++} ++ + static void advk_pcie_setup_hw(struct advk_pcie *pcie) + { + u32 reg; +@@ -382,12 +459,6 @@ static void advk_pcie_setup_hw(struct ad + PCIE_CORE_CTRL2_TD_ENABLE; + advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG); + +- /* Set GEN2 */ +- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); +- reg &= ~PCIE_GEN_SEL_MSK; +- reg |= SPEED_GEN_2; +- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); +- + /* Set lane X1 */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg &= ~LANE_CNT_MSK; +@@ -435,20 +506,7 @@ static void advk_pcie_setup_hw(struct ad + */ + msleep(PCI_PM_D3COLD_WAIT); + +- /* Enable link training */ +- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); +- reg |= LINK_TRAINING_EN; +- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); +- +- /* +- * Start link training immediately after enabling it. +- * This solves problems for some buggy cards. +- */ +- reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); +- reg |= PCIE_CORE_LINK_TRAINING; +- advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); +- +- advk_pcie_wait_for_link(pcie); ++ advk_pcie_train_link(pcie); + + reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); + reg |= PCIE_CORE_CMD_MEM_ACCESS_EN | +@@ -1278,6 +1336,12 @@ static int advk_pcie_probe(struct platfo + return ret; + } + ++ ret = of_pci_get_max_link_speed(dev->of_node); ++ if (ret <= 0 || ret > 3) ++ pcie->link_gen = 3; ++ else ++ pcie->link_gen = ret; ++ + advk_pcie_setup_hw(pcie); + + ret = advk_sw_pci_bridge_init(pcie); diff --git a/queue-5.4/pci-aardvark-issue-perst-via-gpio.patch b/queue-5.4/pci-aardvark-issue-perst-via-gpio.patch new file mode 100644 index 00000000000..782968f7125 --- /dev/null +++ b/queue-5.4/pci-aardvark-issue-perst-via-gpio.patch @@ -0,0 +1,129 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:25:59 +0100 +Subject: PCI: aardvark: Issue PERST via GPIO +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Tomasz Maciej Nowak" , "Lorenzo Pieralisi" , "Thomas Petazzoni" , "Marek Behún" +Message-ID: <20211125002616.31363-6-kabel@kernel.org> + +From: Pali Rohár + +commit 5169a9851daaa2782a7bd2bb83d5b1bd224b2879 upstream. + +Add support for issuing PERST via GPIO specified in 'reset-gpios' +property (as described in PCI device tree bindings). + +Some buggy cards (e.g. Compex WLE900VX or WLE1216) are not detected +after reboot when PERST is not issued during driver initialization. + +If bootloader already enabled link training then issuing PERST has no +effect for some buggy cards (e.g. Compex WLE900VX) and these cards are +not detected. We therefore clear the LINK_TRAINING_EN register before. + +It was observed that Compex WLE900VX card needs to be in PERST reset +for at least 10ms if bootloader enabled link training. + +Tested on Turris MOX. + +Link: https://lore.kernel.org/r/20200430080625.26070-6-pali@kernel.org +Tested-by: Tomasz Maciej Nowak +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Acked-by: Thomas Petazzoni +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 43 +++++++++++++++++++++++++++++++++- + 1 file changed, 42 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -9,6 +9,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -17,6 +18,7 @@ + #include + #include + #include ++#include + #include + + #include "../pci.h" +@@ -252,6 +254,7 @@ struct advk_pcie { + int root_bus_nr; + int link_gen; + struct pci_bridge_emul bridge; ++ struct gpio_desc *reset_gpio; + }; + + static inline void advk_writel(struct advk_pcie *pcie, u32 val, u64 reg) +@@ -414,10 +417,31 @@ err: + dev_err(dev, "link never came up\n"); + } + ++static void advk_pcie_issue_perst(struct advk_pcie *pcie) ++{ ++ u32 reg; ++ ++ if (!pcie->reset_gpio) ++ return; ++ ++ /* PERST does not work for some cards when link training is enabled */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg &= ~LINK_TRAINING_EN; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* 10ms delay is needed for some cards */ ++ dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); ++ gpiod_set_value_cansleep(pcie->reset_gpio, 1); ++ usleep_range(10000, 11000); ++ gpiod_set_value_cansleep(pcie->reset_gpio, 0); ++} ++ + static void advk_pcie_setup_hw(struct advk_pcie *pcie) + { + u32 reg; + ++ advk_pcie_issue_perst(pcie); ++ + /* Set to Direct mode */ + reg = advk_readl(pcie, CTRL_CONFIG_REG); + reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT); +@@ -500,7 +524,8 @@ static void advk_pcie_setup_hw(struct ad + + /* + * PERST# signal could have been asserted by pinctrl subsystem before +- * probe() callback has been called, making the endpoint going into ++ * probe() callback has been called or issued explicitly by reset gpio ++ * function advk_pcie_issue_perst(), making the endpoint going into + * fundamental reset. As required by PCI Express spec a delay for at + * least 100ms after such a reset before link training is needed. + */ +@@ -1336,6 +1361,22 @@ static int advk_pcie_probe(struct platfo + return ret; + } + ++ pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node, ++ "reset-gpios", 0, ++ GPIOD_OUT_LOW, ++ "pcie1-reset"); ++ ret = PTR_ERR_OR_ZERO(pcie->reset_gpio); ++ if (ret) { ++ if (ret == -ENOENT) { ++ pcie->reset_gpio = NULL; ++ } else { ++ if (ret != -EPROBE_DEFER) ++ dev_err(dev, "Failed to get reset-gpio: %i\n", ++ ret); ++ return ret; ++ } ++ } ++ + ret = of_pci_get_max_link_speed(dev->of_node); + if (ret <= 0 || ret > 3) + pcie->link_gen = 3; diff --git a/queue-5.4/pci-aardvark-move-pcie-reset-card-code-to-advk_pcie_train_link.patch b/queue-5.4/pci-aardvark-move-pcie-reset-card-code-to-advk_pcie_train_link.patch new file mode 100644 index 00000000000..abc6d44ec88 --- /dev/null +++ b/queue-5.4/pci-aardvark-move-pcie-reset-card-code-to-advk_pcie_train_link.patch @@ -0,0 +1,130 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:03 +0100 +Subject: PCI: aardvark: Move PCIe reset card code to advk_pcie_train_link() +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" , "Marek Behún" +Message-ID: <20211125002616.31363-10-kabel@kernel.org> + +From: Pali Rohár + +commit d0c6a3475b033960e85ae2bf176b14cab0a627d2 upstream. + +Move code which belongs to link training (delays and resets) into +advk_pcie_train_link() function, so everything related to link training, +including timings is at one place. + +After experiments it can be observed that link training in aardvark +hardware is very sensitive to timings and delays, so it is a good idea to +have this code at the same place as link training calls. + +This patch does not change behavior of aardvark initialization. + +Link: https://lore.kernel.org/r/20200907111038.5811-6-pali@kernel.org +Tested-by: Marek Behún +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 64 ++++++++++++++++++---------------- + 1 file changed, 34 insertions(+), 30 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -332,6 +332,25 @@ static void advk_pcie_wait_for_retrain(s + } + } + ++static void advk_pcie_issue_perst(struct advk_pcie *pcie) ++{ ++ u32 reg; ++ ++ if (!pcie->reset_gpio) ++ return; ++ ++ /* PERST does not work for some cards when link training is enabled */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg &= ~LINK_TRAINING_EN; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* 10ms delay is needed for some cards */ ++ dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); ++ gpiod_set_value_cansleep(pcie->reset_gpio, 1); ++ usleep_range(10000, 11000); ++ gpiod_set_value_cansleep(pcie->reset_gpio, 0); ++} ++ + static int advk_pcie_train_at_gen(struct advk_pcie *pcie, int gen) + { + int ret, neg_gen; +@@ -380,6 +399,21 @@ static void advk_pcie_train_link(struct + int neg_gen = -1, gen; + + /* ++ * Reset PCIe card via PERST# signal. Some cards are not detected ++ * during link training when they are in some non-initial state. ++ */ ++ advk_pcie_issue_perst(pcie); ++ ++ /* ++ * PERST# signal could have been asserted by pinctrl subsystem before ++ * probe() callback has been called or issued explicitly by reset gpio ++ * function advk_pcie_issue_perst(), making the endpoint going into ++ * fundamental reset. As required by PCI Express spec a delay for at ++ * least 100ms after such a reset before link training is needed. ++ */ ++ msleep(PCI_PM_D3COLD_WAIT); ++ ++ /* + * Try link training at link gen specified by device tree property + * 'max-link-speed'. If this fails, iteratively train at lower gen. + */ +@@ -411,31 +445,10 @@ err: + dev_err(dev, "link never came up\n"); + } + +-static void advk_pcie_issue_perst(struct advk_pcie *pcie) +-{ +- u32 reg; +- +- if (!pcie->reset_gpio) +- return; +- +- /* PERST does not work for some cards when link training is enabled */ +- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); +- reg &= ~LINK_TRAINING_EN; +- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); +- +- /* 10ms delay is needed for some cards */ +- dev_info(&pcie->pdev->dev, "issuing PERST via reset GPIO for 10ms\n"); +- gpiod_set_value_cansleep(pcie->reset_gpio, 1); +- usleep_range(10000, 11000); +- gpiod_set_value_cansleep(pcie->reset_gpio, 0); +-} +- + static void advk_pcie_setup_hw(struct advk_pcie *pcie) + { + u32 reg; + +- advk_pcie_issue_perst(pcie); +- + /* Set to Direct mode */ + reg = advk_readl(pcie, CTRL_CONFIG_REG); + reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT); +@@ -517,15 +530,6 @@ static void advk_pcie_setup_hw(struct ad + reg |= PIO_CTRL_ADDR_WIN_DISABLE; + advk_writel(pcie, reg, PIO_CTRL); + +- /* +- * PERST# signal could have been asserted by pinctrl subsystem before +- * probe() callback has been called or issued explicitly by reset gpio +- * function advk_pcie_issue_perst(), making the endpoint going into +- * fundamental reset. As required by PCI Express spec a delay for at +- * least 100ms after such a reset before link training is needed. +- */ +- msleep(PCI_PM_D3COLD_WAIT); +- + advk_pcie_train_link(pcie); + + reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); diff --git a/queue-5.4/pci-aardvark-replace-custom-macros-by-standard-linux-pci_regs.h-macros.patch b/queue-5.4/pci-aardvark-replace-custom-macros-by-standard-linux-pci_regs.h-macros.patch new file mode 100644 index 00000000000..f2f58405e70 --- /dev/null +++ b/queue-5.4/pci-aardvark-replace-custom-macros-by-standard-linux-pci_regs.h-macros.patch @@ -0,0 +1,103 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:00 +0100 +Subject: PCI: aardvark: Replace custom macros by standard linux/pci_regs.h macros +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Tomasz Maciej Nowak" , "Lorenzo Pieralisi" , "Rob Herring" , "Thomas Petazzoni" , "Marek Behún" +Message-ID: <20211125002616.31363-7-kabel@kernel.org> + +From: Pali Rohár + +commit 96be36dbffacea0aa9e6ec4839583e79faa141a1 upstream. + +PCI-E capability macros are already defined in linux/pci_regs.h. +Remove their reimplementation in pcie-aardvark. + +Link: https://lore.kernel.org/r/20200430080625.26070-9-pali@kernel.org +Tested-by: Tomasz Maciej Nowak +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Rob Herring +Acked-by: Thomas Petazzoni +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 41 ++++++++++++++-------------------- + 1 file changed, 18 insertions(+), 23 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -32,17 +32,6 @@ + #define PCIE_CORE_CMD_MEM_IO_REQ_EN BIT(2) + #define PCIE_CORE_DEV_REV_REG 0x8 + #define PCIE_CORE_PCIEXP_CAP 0xc0 +-#define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8 +-#define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4) +-#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5 +-#define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11) +-#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12 +-#define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2 +-#define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0 +-#define PCIE_CORE_LINK_L0S_ENTRY BIT(0) +-#define PCIE_CORE_LINK_TRAINING BIT(5) +-#define PCIE_CORE_LINK_SPEED_SHIFT 16 +-#define PCIE_CORE_LINK_WIDTH_SHIFT 20 + #define PCIE_CORE_ERR_CAPCTL_REG 0x118 + #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5) + #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN BIT(6) +@@ -267,6 +256,11 @@ static inline u32 advk_readl(struct advk + return readl(pcie->base + reg); + } + ++static inline u16 advk_read16(struct advk_pcie *pcie, u64 reg) ++{ ++ return advk_readl(pcie, (reg & ~0x3)) >> ((reg & 0x3) * 8); ++} ++ + static u8 advk_pcie_ltssm_state(struct advk_pcie *pcie) + { + u32 val; +@@ -366,16 +360,16 @@ static int advk_pcie_train_at_gen(struct + * Start link training immediately after enabling it. + * This solves problems for some buggy cards. + */ +- reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); +- reg |= PCIE_CORE_LINK_TRAINING; +- advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); ++ reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL); ++ reg |= PCI_EXP_LNKCTL_RL; ++ advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKCTL); + + ret = advk_pcie_wait_for_link(pcie); + if (ret) + return ret; + +- reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); +- neg_gen = (reg >> PCIE_CORE_LINK_SPEED_SHIFT) & 0xf; ++ reg = advk_read16(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_LNKSTA); ++ neg_gen = reg & PCI_EXP_LNKSTA_CLS; + + return neg_gen; + } +@@ -470,13 +464,14 @@ static void advk_pcie_setup_hw(struct ad + PCIE_CORE_ERR_CAPCTL_ECRC_CHCK_RCV; + advk_writel(pcie, reg, PCIE_CORE_ERR_CAPCTL_REG); + +- /* Set PCIe Device Control and Status 1 PF0 register */ +- reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE | +- (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) | +- PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE | +- (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ << +- PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT); +- advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG); ++ /* Set PCIe Device Control register */ ++ reg = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); ++ reg &= ~PCI_EXP_DEVCTL_RELAX_EN; ++ reg &= ~PCI_EXP_DEVCTL_NOSNOOP_EN; ++ reg &= ~PCI_EXP_DEVCTL_READRQ; ++ reg |= PCI_EXP_DEVCTL_PAYLOAD; /* Set max payload size */ ++ reg |= PCI_EXP_DEVCTL_READRQ_512B; ++ advk_writel(pcie, reg, PCIE_CORE_PCIEXP_CAP + PCI_EXP_DEVCTL); + + /* Program PCIe Control 2 to disable strict ordering */ + reg = PCIE_CORE_CTRL2_RESERVED | diff --git a/queue-5.4/pci-aardvark-set-pci-bridge-class-code-to-pci-bridge.patch b/queue-5.4/pci-aardvark-set-pci-bridge-class-code-to-pci-bridge.patch new file mode 100644 index 00000000000..a0104a169c4 --- /dev/null +++ b/queue-5.4/pci-aardvark-set-pci-bridge-class-code-to-pci-bridge.patch @@ -0,0 +1,65 @@ +From foo@baz Sun Nov 28 01:44:18 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:13 +0100 +Subject: PCI: aardvark: Set PCI Bridge Class Code to PCI Bridge +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" +Message-ID: <20211125002616.31363-20-kabel@kernel.org> + +From: Pali Rohár + +commit 84e1b4045dc887b78bdc87d92927093dc3a465aa upstream. + +Aardvark controller has something like config space of a Root Port +available at offset 0x0 of internal registers - these registers are used +for implementation of the emulated bridge. + +The default value of Class Code of this bridge corresponds to a RAID Mass +storage controller, though. (This is probably intended for when the +controller is used as Endpoint.) + +Change the Class Code to correspond to a PCI Bridge. + +Add comment explaining this change. + +Link: https://lore.kernel.org/r/20211028185659.20329-6-kabel@kernel.org +Fixes: 8a3ebd8de328 ("PCI: aardvark: Implement emulated root PCI bridge config space") +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Cc: stable@vger.kernel.org +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -502,6 +502,26 @@ static void advk_pcie_setup_hw(struct ad + reg = (PCI_VENDOR_ID_MARVELL << 16) | PCI_VENDOR_ID_MARVELL; + advk_writel(pcie, reg, VENDOR_ID_REG); + ++ /* ++ * Change Class Code of PCI Bridge device to PCI Bridge (0x600400), ++ * because the default value is Mass storage controller (0x010400). ++ * ++ * Note that this Aardvark PCI Bridge does not have compliant Type 1 ++ * Configuration Space and it even cannot be accessed via Aardvark's ++ * PCI config space access method. Something like config space is ++ * available in internal Aardvark registers starting at offset 0x0 ++ * and is reported as Type 0. In range 0x10 - 0x34 it has totally ++ * different registers. ++ * ++ * Therefore driver uses emulation of PCI Bridge which emulates ++ * access to configuration space via internal Aardvark registers or ++ * emulated configuration buffer. ++ */ ++ reg = advk_readl(pcie, PCIE_CORE_DEV_REV_REG); ++ reg &= ~0xffffff00; ++ reg |= (PCI_CLASS_BRIDGE_PCI << 8) << 8; ++ advk_writel(pcie, reg, PCIE_CORE_DEV_REV_REG); ++ + /* Disable Root Bridge I/O space, memory space and bus mastering */ + reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); + reg &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); diff --git a/queue-5.4/pci-aardvark-simplify-initialization-of-rootcap-on-virtual-bridge.patch b/queue-5.4/pci-aardvark-simplify-initialization-of-rootcap-on-virtual-bridge.patch new file mode 100644 index 00000000000..219dd6e015d --- /dev/null +++ b/queue-5.4/pci-aardvark-simplify-initialization-of-rootcap-on-virtual-bridge.patch @@ -0,0 +1,63 @@ +From foo@baz Sun Nov 28 01:44:18 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:10 +0100 +Subject: PCI: aardvark: Simplify initialization of rootcap on virtual bridge +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Lorenzo Pieralisi" +Message-ID: <20211125002616.31363-17-kabel@kernel.org> + +From: Pali Rohár + +commit 454c53271fc11f3aa5e44e41fd99ca181bd32c62 upstream. + +PCIe config space can be initialized also before pci_bridge_emul_init() +call, so move rootcap initialization after PCI config space initialization. + +This simplifies the function a little since it removes one if (ret < 0) +check. + +Link: https://lore.kernel.org/r/20211005180952.6812-11-kabel@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Marek Behún +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 14 ++++---------- + 1 file changed, 4 insertions(+), 10 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -898,7 +898,6 @@ static struct pci_bridge_emul_ops advk_p + static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) + { + struct pci_bridge_emul *bridge = &pcie->bridge; +- int ret; + + bridge->conf.vendor = + cpu_to_le16(advk_readl(pcie, PCIE_CORE_DEV_ID_REG) & 0xffff); +@@ -918,19 +917,14 @@ static int advk_sw_pci_bridge_init(struc + /* Support interrupt A for MSI feature */ + bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE; + ++ /* Indicates supports for Completion Retry Status */ ++ bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS); ++ + bridge->has_pcie = true; + bridge->data = pcie; + bridge->ops = &advk_pci_bridge_emul_ops; + +- /* PCIe config space can be initialized after pci_bridge_emul_init() */ +- ret = pci_bridge_emul_init(bridge, 0); +- if (ret < 0) +- return ret; +- +- /* Indicates supports for Completion Retry Status */ +- bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS); +- +- return 0; ++ return pci_bridge_emul_init(bridge, 0); + } + + static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus, diff --git a/queue-5.4/pci-aardvark-train-link-immediately-after-enabling-training.patch b/queue-5.4/pci-aardvark-train-link-immediately-after-enabling-training.patch new file mode 100644 index 00000000000..32d9c74dccd --- /dev/null +++ b/queue-5.4/pci-aardvark-train-link-immediately-after-enabling-training.patch @@ -0,0 +1,66 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:25:57 +0100 +Subject: PCI: aardvark: Train link immediately after enabling training +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Tomasz Maciej Nowak" , "Lorenzo Pieralisi" , "Rob Herring" , "Thomas Petazzoni" , "Marek Behún" +Message-ID: <20211125002616.31363-4-kabel@kernel.org> + +From: Pali Rohár + +commit 6964494582f56a3882c2c53b0edbfe99eb32b2e1 upstream. + +Adding even 100ms (PCI_PM_D3COLD_WAIT) delay between enabling link +training and starting link training causes detection issues with some +buggy cards (such as Compex WLE900VX). + +Move the code which enables link training immediately before the one +which starts link traning. + +This fixes detection issues of Compex WLE900VX card on Turris MOX after +cold boot. + +Link: https://lore.kernel.org/r/20200430080625.26070-2-pali@kernel.org +Fixes: f4c7d053d7f7 ("PCI: aardvark: Wait for endpoint to be ready...") +Tested-by: Tomasz Maciej Nowak +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Acked-by: Rob Herring +Acked-by: Thomas Petazzoni +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -394,11 +394,6 @@ static void advk_pcie_setup_hw(struct ad + reg |= LANE_COUNT_1; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); + +- /* Enable link training */ +- reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); +- reg |= LINK_TRAINING_EN; +- advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); +- + /* Enable MSI */ + reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); + reg |= PCIE_CORE_CTRL2_MSI_ENABLE; +@@ -440,7 +435,15 @@ static void advk_pcie_setup_hw(struct ad + */ + msleep(PCI_PM_D3COLD_WAIT); + +- /* Start link training */ ++ /* Enable link training */ ++ reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); ++ reg |= LINK_TRAINING_EN; ++ advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); ++ ++ /* ++ * Start link training immediately after enabling it. ++ * This solves problems for some buggy cards. ++ */ + reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); + reg |= PCIE_CORE_LINK_TRAINING; + advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); diff --git a/queue-5.4/pci-aardvark-update-comment-about-disabling-link-training.patch b/queue-5.4/pci-aardvark-update-comment-about-disabling-link-training.patch new file mode 100644 index 00000000000..504a41c914c --- /dev/null +++ b/queue-5.4/pci-aardvark-update-comment-about-disabling-link-training.patch @@ -0,0 +1,45 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:04 +0100 +Subject: PCI: aardvark: Update comment about disabling link training +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Lorenzo Pieralisi" , "Marek Behún" +Message-ID: <20211125002616.31363-11-kabel@kernel.org> + +From: Pali Rohár + +commit 1d1cd163d0de22a4041a6f1aeabcf78f80076539 upstream. + +According to PCI Express Base Specifications (rev 4.0, 6.6.1 +"Conventional reset"), after fundamental reset a 100ms delay is needed +prior to enabling link training. + +Update comment in code to reflect this requirement. + +Link: https://lore.kernel.org/r/20201202184659.3795-1-pali@kernel.org +Signed-off-by: Pali Rohár +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -339,7 +339,14 @@ static void advk_pcie_issue_perst(struct + if (!pcie->reset_gpio) + return; + +- /* PERST does not work for some cards when link training is enabled */ ++ /* ++ * As required by PCI Express spec (PCI Express Base Specification, REV. ++ * 4.0 PCI Express, February 19 2014, 6.6.1 Conventional Reset) a delay ++ * for at least 100ms after de-asserting PERST# signal is needed before ++ * link training is enabled. So ensure that link training is disabled ++ * prior de-asserting PERST# signal to fulfill that PCI Express spec ++ * requirement. ++ */ + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); + reg &= ~LINK_TRAINING_EN; + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG); diff --git a/queue-5.4/pci-aardvark-wait-for-endpoint-to-be-ready-before-training-link.patch b/queue-5.4/pci-aardvark-wait-for-endpoint-to-be-ready-before-training-link.patch new file mode 100644 index 00000000000..0f6a7eaf6dd --- /dev/null +++ b/queue-5.4/pci-aardvark-wait-for-endpoint-to-be-ready-before-training-link.patch @@ -0,0 +1,58 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:25:55 +0100 +Subject: PCI: aardvark: Wait for endpoint to be ready before training link +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Remi Pommarel" , "Lorenzo Pieralisi" , "Thomas Petazzoni" , "Marek Behún" +Message-ID: <20211125002616.31363-2-kabel@kernel.org> + +From: Remi Pommarel + +commit f4c7d053d7f77cd5c1a1ba7c7ce085ddba13d1d7 upstream. + +When configuring pcie reset pin from gpio (e.g. initially set by +u-boot) to pcie function this pin goes low for a brief moment +asserting the PERST# signal. Thus connected device enters fundamental +reset process and link configuration can only begin after a minimal +100ms delay (see [1]). + +Because the pin configuration comes from the "default" pinctrl it is +implicitly configured before the probe callback is called: + +driver_probe_device() + really_probe() + ... + pinctrl_bind_pins() /* Here pin goes from gpio to PCIE reset + function and PERST# is asserted */ + ... + drv->probe() + +[1] "PCI Express Base Specification", REV. 4.0 + PCI Express, February 19 2014, 6.6.1 Conventional Reset + +Signed-off-by: Remi Pommarel +Signed-off-by: Lorenzo Pieralisi +Acked-by: Thomas Petazzoni +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pci-aardvark.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/pci/controller/pci-aardvark.c ++++ b/drivers/pci/controller/pci-aardvark.c +@@ -432,6 +432,14 @@ static void advk_pcie_setup_hw(struct ad + reg |= PIO_CTRL_ADDR_WIN_DISABLE; + advk_writel(pcie, reg, PIO_CTRL); + ++ /* ++ * PERST# signal could have been asserted by pinctrl subsystem before ++ * probe() callback has been called, making the endpoint going into ++ * fundamental reset. As required by PCI Express spec a delay for at ++ * least 100ms after such a reset before link training is needed. ++ */ ++ msleep(PCI_PM_D3COLD_WAIT); ++ + /* Start link training */ + reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); + reg |= PCIE_CORE_LINK_TRAINING; diff --git a/queue-5.4/pci-pci-bridge-emul-fix-array-overruns-improve-safety.patch b/queue-5.4/pci-pci-bridge-emul-fix-array-overruns-improve-safety.patch new file mode 100644 index 00000000000..8439db3c5a0 --- /dev/null +++ b/queue-5.4/pci-pci-bridge-emul-fix-array-overruns-improve-safety.patch @@ -0,0 +1,72 @@ +From foo@baz Sun Nov 28 01:44:17 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:05 +0100 +Subject: PCI: pci-bridge-emul: Fix array overruns, improve safety +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Russell King" , "Bjorn Helgaas" , "Marek Behún" +Message-ID: <20211125002616.31363-12-kabel@kernel.org> + +From: Russell King + +commit f8ee579d53aca887d93f5f411462f25c085a5106 upstream. + +We allow up to PCI_EXP_SLTSTA2 registers to be accessed, but the +pcie_cap_regs_behavior[] array only covers up to PCI_EXP_RTSTA. Expand +this array to avoid walking off the end of it. + +Do the same for pci_regs_behavior for consistency[], and add a +BUILD_BUG_ON() to also check the bridge->conf structure size. + +Fixes: 23a5fba4d941 ("PCI: Introduce PCI bridge emulated config space common logic") +Link: https://lore.kernel.org/r/E1l6z9W-0006Re-MQ@rmk-PC.armlinux.org.uk +Signed-off-by: Russell King +Signed-off-by: Bjorn Helgaas +Reviewed-by: Pali Rohár +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/pci-bridge-emul.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/drivers/pci/pci-bridge-emul.c ++++ b/drivers/pci/pci-bridge-emul.c +@@ -21,8 +21,9 @@ + #include "pci-bridge-emul.h" + + #define PCI_BRIDGE_CONF_END PCI_STD_HEADER_SIZEOF ++#define PCI_CAP_PCIE_SIZEOF (PCI_EXP_SLTSTA2 + 2) + #define PCI_CAP_PCIE_START PCI_BRIDGE_CONF_END +-#define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_EXP_SLTSTA2 + 2) ++#define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_CAP_PCIE_SIZEOF) + + struct pci_bridge_reg_behavior { + /* Read-only bits */ +@@ -38,7 +39,8 @@ struct pci_bridge_reg_behavior { + u32 rsvd; + }; + +-static const struct pci_bridge_reg_behavior pci_regs_behavior[] = { ++static const ++struct pci_bridge_reg_behavior pci_regs_behavior[PCI_STD_HEADER_SIZEOF / 4] = { + [PCI_VENDOR_ID / 4] = { .ro = ~0 }, + [PCI_COMMAND / 4] = { + .rw = (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | +@@ -173,7 +175,8 @@ static const struct pci_bridge_reg_behav + }, + }; + +-static const struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = { ++static const ++struct pci_bridge_reg_behavior pcie_cap_regs_behavior[PCI_CAP_PCIE_SIZEOF / 4] = { + [PCI_CAP_LIST_ID / 4] = { + /* + * Capability ID, Next Capability Pointer and +@@ -270,6 +273,8 @@ static const struct pci_bridge_reg_behav + int pci_bridge_emul_init(struct pci_bridge_emul *bridge, + unsigned int flags) + { ++ BUILD_BUG_ON(sizeof(bridge->conf) != PCI_BRIDGE_CONF_END); ++ + bridge->conf.class_revision |= cpu_to_le32(PCI_CLASS_BRIDGE_PCI << 16); + bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE; + bridge->conf.cache_line_size = 0x10; diff --git a/queue-5.4/pinctrl-armada-37xx-correct-pwm-pins-definitions.patch b/queue-5.4/pinctrl-armada-37xx-correct-pwm-pins-definitions.patch new file mode 100644 index 00000000000..36b9827a348 --- /dev/null +++ b/queue-5.4/pinctrl-armada-37xx-correct-pwm-pins-definitions.patch @@ -0,0 +1,101 @@ +From foo@baz Sun Nov 28 01:44:18 PM CET 2021 +From: "Marek Behún" +Date: Thu, 25 Nov 2021 01:26:15 +0100 +Subject: pinctrl: armada-37xx: Correct PWM pins definitions +To: Greg Kroah-Hartman , Sasha Levin +Cc: pali@kernel.org, stable@vger.kernel.org, "Marek Behún" , "Rob Herring" , "Linus Walleij" +Message-ID: <20211125002616.31363-22-kabel@kernel.org> + +From: "Marek Behún" + +commit baf8d6899b1e8906dc076ef26cc633e96a8bb0c3 upstream. + +The PWM pins on North Bridge on Armada 37xx can be configured into PWM +or GPIO functions. When in PWM function, each pin can also be configured +to drive low on 0 and tri-state on 1 (LED mode). + +The current definitions handle this by declaring two pin groups for each +pin: +- group "pwmN" with functions "pwm" and "gpio" +- group "ledN_od" ("od" for open drain) with functions "led" and "gpio" + +This is semantically incorrect. The correct definition for each pin +should be one group with three functions: "pwm", "led" and "gpio". + +Change the "pwmN" groups to support "led" function. + +Remove "ledN_od" groups. This cannot break backwards compatibility with +older device trees: no device tree uses it since there is no PWM driver +for this SOC yet. Also "ledN_od" groups are not even documented. + +Fixes: b835d6953009 ("pinctrl: armada-37xx: swap polarity on LED group") +Signed-off-by: Marek Behún +Acked-by: Rob Herring +Link: https://lore.kernel.org/r/20210719112938.27594-1-kabel@kernel.org +Signed-off-by: Linus Walleij +Signed-off-by: Marek Behún +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt | 8 ++-- + drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 17 ++++------ + 2 files changed, 12 insertions(+), 13 deletions(-) + +--- a/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt ++++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada-37xx-pinctrl.txt +@@ -43,19 +43,19 @@ group emmc_nb + + group pwm0 + - pin 11 (GPIO1-11) +- - functions pwm, gpio ++ - functions pwm, led, gpio + + group pwm1 + - pin 12 +- - functions pwm, gpio ++ - functions pwm, led, gpio + + group pwm2 + - pin 13 +- - functions pwm, gpio ++ - functions pwm, led, gpio + + group pwm3 + - pin 14 +- - functions pwm, gpio ++ - functions pwm, led, gpio + + group pmic1 + - pin 7 +--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c ++++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +@@ -166,10 +166,14 @@ static struct armada_37xx_pin_group arma + PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"), + PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"), + PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"), +- PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"), +- PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"), +- PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"), +- PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"), ++ PIN_GRP_GPIO_3("pwm0", 11, 1, BIT(3) | BIT(20), 0, BIT(20), BIT(3), ++ "pwm", "led"), ++ PIN_GRP_GPIO_3("pwm1", 12, 1, BIT(4) | BIT(21), 0, BIT(21), BIT(4), ++ "pwm", "led"), ++ PIN_GRP_GPIO_3("pwm2", 13, 1, BIT(5) | BIT(22), 0, BIT(22), BIT(5), ++ "pwm", "led"), ++ PIN_GRP_GPIO_3("pwm3", 14, 1, BIT(6) | BIT(23), 0, BIT(23), BIT(6), ++ "pwm", "led"), + PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"), + PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"), + PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"), +@@ -183,11 +187,6 @@ static struct armada_37xx_pin_group arma + PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19), + BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19), + 18, 2, "gpio", "uart"), +- PIN_GRP_GPIO_2("led0_od", 11, 1, BIT(20), BIT(20), 0, "led"), +- PIN_GRP_GPIO_2("led1_od", 12, 1, BIT(21), BIT(21), 0, "led"), +- PIN_GRP_GPIO_2("led2_od", 13, 1, BIT(22), BIT(22), 0, "led"), +- PIN_GRP_GPIO_2("led3_od", 14, 1, BIT(23), BIT(23), 0, "led"), +- + }; + + static struct armada_37xx_pin_group armada_37xx_sb_groups[] = { diff --git a/queue-5.4/series b/queue-5.4/series index 1bdb07398c7..feb0292a13b 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -20,3 +20,25 @@ tracing-uprobe-fix-uprobe_perf_open-probes-iteration.patch tracing-fix-pid-filtering-when-triggers-are-attached.patch mmc-sdhci-fix-adma-for-page_size-64kib.patch mdio-aspeed-fix-link-is-down-issue.patch +pci-aardvark-deduplicate-code-in-advk_pcie_rd_conf.patch +pci-aardvark-wait-for-endpoint-to-be-ready-before-training-link.patch +pci-aardvark-fix-big-endian-support.patch +pci-aardvark-train-link-immediately-after-enabling-training.patch +pci-aardvark-improve-link-training.patch +pci-aardvark-issue-perst-via-gpio.patch +pci-aardvark-replace-custom-macros-by-standard-linux-pci_regs.h-macros.patch +pci-aardvark-don-t-touch-pcie-registers-if-no-card-connected.patch +pci-aardvark-fix-compilation-on-s390.patch +pci-aardvark-move-pcie-reset-card-code-to-advk_pcie_train_link.patch +pci-aardvark-update-comment-about-disabling-link-training.patch +pci-pci-bridge-emul-fix-array-overruns-improve-safety.patch +pci-aardvark-configure-pcie-resources-from-ranges-dt-property.patch +pci-aardvark-fix-pcie-max-payload-size-setting.patch +pci-aardvark-implement-re-issuing-config-requests-on-crs-response.patch +pci-aardvark-simplify-initialization-of-rootcap-on-virtual-bridge.patch +pci-aardvark-fix-link-training.patch +pci-aardvark-fix-support-for-bus-mastering-and-pci_command-on-emulated-bridge.patch +pci-aardvark-set-pci-bridge-class-code-to-pci-bridge.patch +pci-aardvark-fix-support-for-pci_bridge_ctl_bus_reset-on-emulated-bridge.patch +pinctrl-armada-37xx-correct-pwm-pins-definitions.patch +arm64-dts-marvell-armada-37xx-set-pcie_reset_pin-to-gpio-function.patch