From: Nick Hainke Date: Tue, 23 May 2023 14:47:42 +0000 (+0200) Subject: ramips: mark patches accepted upstream X-Git-Tag: v23.05.0-rc1~25 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=dc2841045dec20209472938d50fdb27dc6682910;p=openwrt%2Fopenwrt.git ramips: mark patches accepted upstream Add kernel tags to the patches that got accepted upstream. Signed-off-by: Nick Hainke (cherry picked from commit 2388b119de9279d7adaa525c7ba502fcae1fe187) Signed-off-by: Daniel Golle --- diff --git a/target/linux/ramips/patches-5.15/100-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch b/target/linux/ramips/patches-5.15/100-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch deleted file mode 100644 index 1c8c7cd3d0..0000000000 --- a/target/linux/ramips/patches-5.15/100-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch +++ /dev/null @@ -1,1418 +0,0 @@ -From: Sergio Paracuellos -Date: Wed, 22 Sep 2021 07:00:34 +0200 -Subject: [PATCH] PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver - -Add driver for the PCIe controller of the MT7621 SoC. - -[bhelgaas: rename from pci-mt7621.c to pcie-mt7621.c; also rename Kconfig -symbol from PCI_MT7621 to PCIE_MT7621] -Link: https://lore.kernel.org/r/20210922050035.18162-3-sergio.paracuellos@gmail.com -Signed-off-by: Sergio Paracuellos -Signed-off-by: Lorenzo Pieralisi -Signed-off-by: Bjorn Helgaas -Acked-by: Greg Kroah-Hartman ---- - rename drivers/{staging/mt7621-pci/pci-mt7621.c => pci/controller/pcie-mt7621.c} (95%) - delete mode 100644 drivers/staging/mt7621-pci/Kconfig - delete mode 100644 drivers/staging/mt7621-pci/Makefile - delete mode 100644 drivers/staging/mt7621-pci/TODO - delete mode 100644 drivers/staging/mt7621-pci/mediatek,mt7621-pci.txt - ---- a/arch/mips/ralink/Kconfig -+++ b/arch/mips/ralink/Kconfig -@@ -51,7 +51,8 @@ choice - select SYS_SUPPORTS_HIGHMEM - select MIPS_GIC - select CLKSRC_MIPS_GIC -- select HAVE_PCI if PCI_MT7621 -+ select HAVE_PCI -+ select PCI_DRIVERS_GENERIC - select SOC_BUS - endchoice - ---- a/drivers/pci/controller/Kconfig -+++ b/drivers/pci/controller/Kconfig -@@ -312,6 +312,14 @@ config PCIE_HISI_ERR - Say Y here if you want error handling support - for the PCIe controller's errors on HiSilicon HIP SoCs - -+config PCIE_MT7621 -+ tristate "MediaTek MT7621 PCIe Controller" -+ depends on (RALINK && SOC_MT7621) || (MIPS && COMPILE_TEST) -+ select PHY_MT7621_PCI -+ default SOC_MT7621 -+ help -+ This selects a driver for the MediaTek MT7621 PCIe Controller. -+ - source "drivers/pci/controller/dwc/Kconfig" - source "drivers/pci/controller/mobiveil/Kconfig" - source "drivers/pci/controller/cadence/Kconfig" ---- a/drivers/pci/controller/Makefile -+++ b/drivers/pci/controller/Makefile -@@ -37,6 +37,8 @@ obj-$(CONFIG_VMD) += vmd.o - obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o - obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o - obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o -+obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621.o -+ - # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW - obj-y += dwc/ - obj-y += mobiveil/ ---- a/drivers/staging/Kconfig -+++ b/drivers/staging/Kconfig -@@ -86,8 +86,6 @@ source "drivers/staging/vc04_services/Kc - - source "drivers/staging/pi433/Kconfig" - --source "drivers/staging/mt7621-pci/Kconfig" -- - source "drivers/staging/mt7621-dma/Kconfig" - - source "drivers/staging/ralink-gdma/Kconfig" ---- a/drivers/staging/Makefile -+++ b/drivers/staging/Makefile -@@ -33,7 +33,6 @@ obj-$(CONFIG_KS7010) += ks7010/ - obj-$(CONFIG_GREYBUS) += greybus/ - obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ - obj-$(CONFIG_PI433) += pi433/ --obj-$(CONFIG_PCI_MT7621) += mt7621-pci/ - obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ - obj-$(CONFIG_DMA_RALINK) += ralink-gdma/ - obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ ---- a/drivers/staging/mt7621-pci/Kconfig -+++ /dev/null -@@ -1,8 +0,0 @@ --# SPDX-License-Identifier: GPL-2.0 --config PCI_MT7621 -- tristate "MediaTek MT7621 PCI Controller" -- depends on RALINK -- select PCI_DRIVERS_GENERIC -- help -- This selects a driver for the MediaTek MT7621 PCI Controller. -- ---- a/drivers/staging/mt7621-pci/Makefile -+++ /dev/null -@@ -1,2 +0,0 @@ --# SPDX-License-Identifier: GPL-2.0 --obj-$(CONFIG_PCI_MT7621) += pci-mt7621.o ---- a/drivers/staging/mt7621-pci/TODO -+++ /dev/null -@@ -1,4 +0,0 @@ -- --- general code review and cleanup -- --Cc: NeilBrown ---- a/drivers/staging/mt7621-pci/mediatek,mt7621-pci.txt -+++ /dev/null -@@ -1,104 +0,0 @@ --MediaTek MT7621 PCIe controller -- --Required properties: --- compatible: "mediatek,mt7621-pci" --- device_type: Must be "pci" --- reg: Base addresses and lengths of the PCIe subsys and root ports. --- bus-range: Range of bus numbers associated with this controller. --- #address-cells: Address representation for root ports (must be 3) --- pinctrl-names : The pin control state names. --- pinctrl-0: The "default" pinctrl state. --- #size-cells: Size representation for root ports (must be 2) --- ranges: Ranges for the PCI memory and I/O regions. --- #interrupt-cells: Must be 1 --- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties. -- Please refer to the standard PCI bus binding document for a more detailed -- explanation. --- status: either "disabled" or "okay". --- resets: Must contain an entry for each entry in reset-names. -- See ../reset/reset.txt for details. --- reset-names: Must be "pcie0", "pcie1", "pcieN"... based on the number of -- root ports. --- clocks: Must contain an entry for each entry in clock-names. -- See ../clocks/clock-bindings.txt for details. --- clock-names: Must be "pcie0", "pcie1", "pcieN"... based on the number of -- root ports. --- reset-gpios: GPIO specs for the reset pins. -- --In addition, the device tree node must have sub-nodes describing each PCIe port --interface, having the following mandatory properties: -- --Required properties: --- reg: Only the first four bytes are used to refer to the correct bus number -- and device number. --- #address-cells: Must be 3 --- #size-cells: Must be 2 --- ranges: Sub-ranges distributed from the PCIe controller node. An empty -- property is sufficient. --- bus-range: Range of bus numbers associated with this port. -- --Example for MT7621: -- -- pcie: pcie@1e140000 { -- compatible = "mediatek,mt7621-pci"; -- reg = <0x1e140000 0x100 /* host-pci bridge registers */ -- 0x1e142000 0x100 /* pcie port 0 RC control registers */ -- 0x1e143000 0x100 /* pcie port 1 RC control registers */ -- 0x1e144000 0x100>; /* pcie port 2 RC control registers */ -- -- #address-cells = <3>; -- #size-cells = <2>; -- -- pinctrl-names = "default"; -- pinctrl-0 = <&pcie_pins>; -- -- device_type = "pci"; -- -- bus-range = <0 255>; -- ranges = < -- 0x02000000 0 0x00000000 0x60000000 0 0x10000000 /* pci memory */ -- 0x01000000 0 0x00000000 0x1e160000 0 0x00010000 /* io space */ -- >; -- -- #interrupt-cells = <1>; -- interrupt-map-mask = <0xF0000 0 0 1>; -- interrupt-map = <0x10000 0 0 1 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>, -- <0x20000 0 0 1 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>, -- <0x30000 0 0 1 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>; -- -- status = "disabled"; -- -- resets = <&rstctrl 24 &rstctrl 25 &rstctrl 26>; -- reset-names = "pcie0", "pcie1", "pcie2"; -- clocks = <&clkctrl 24 &clkctrl 25 &clkctrl 26>; -- clock-names = "pcie0", "pcie1", "pcie2"; -- -- reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>, -- <&gpio 8 GPIO_ACTIVE_LOW>, -- <&gpio 7 GPIO_ACTIVE_LOW>; -- -- pcie@0,0 { -- reg = <0x0000 0 0 0 0>; -- #address-cells = <3>; -- #size-cells = <2>; -- ranges; -- bus-range = <0x00 0xff>; -- }; -- -- pcie@1,0 { -- reg = <0x0800 0 0 0 0>; -- #address-cells = <3>; -- #size-cells = <2>; -- ranges; -- bus-range = <0x00 0xff>; -- }; -- -- pcie@2,0 { -- reg = <0x1000 0 0 0 0>; -- #address-cells = <3>; -- #size-cells = <2>; -- ranges; -- bus-range = <0x00 0xff>; -- }; -- }; -- ---- a/drivers/staging/mt7621-pci/pci-mt7621.c -+++ /dev/null -@@ -1,601 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0+ --/* -- * BRIEF MODULE DESCRIPTION -- * PCI init for Ralink RT2880 solution -- * -- * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) -- * -- * May 2007 Bruce Chang -- * Initial Release -- * -- * May 2009 Bruce Chang -- * support RT2880/RT3883 PCIe -- * -- * May 2011 Bruce Chang -- * support RT6855/MT7620 PCIe -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --/* MediaTek specific configuration registers */ --#define PCIE_FTS_NUM 0x70c --#define PCIE_FTS_NUM_MASK GENMASK(15, 8) --#define PCIE_FTS_NUM_L0(x) (((x) & 0xff) << 8) -- --/* Host-PCI bridge registers */ --#define RALINK_PCI_PCICFG_ADDR 0x0000 --#define RALINK_PCI_PCIMSK_ADDR 0x000C --#define RALINK_PCI_CONFIG_ADDR 0x0020 --#define RALINK_PCI_CONFIG_DATA 0x0024 --#define RALINK_PCI_MEMBASE 0x0028 --#define RALINK_PCI_IOBASE 0x002C -- --/* PCIe RC control registers */ --#define RALINK_PCI_ID 0x0030 --#define RALINK_PCI_CLASS 0x0034 --#define RALINK_PCI_SUBID 0x0038 --#define RALINK_PCI_STATUS 0x0050 -- --/* Some definition values */ --#define PCIE_REVISION_ID BIT(0) --#define PCIE_CLASS_CODE (0x60400 << 8) --#define PCIE_BAR_MAP_MAX GENMASK(30, 16) --#define PCIE_BAR_ENABLE BIT(0) --#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) --#define PCIE_PORT_LINKUP BIT(0) --#define PCIE_PORT_CNT 3 -- --#define PERST_DELAY_MS 100 -- --/** -- * struct mt7621_pcie_port - PCIe port information -- * @base: I/O mapped register base -- * @list: port list -- * @pcie: pointer to PCIe host info -- * @clk: pointer to the port clock gate -- * @phy: pointer to PHY control block -- * @pcie_rst: pointer to port reset control -- * @gpio_rst: gpio reset -- * @slot: port slot -- * @enabled: indicates if port is enabled -- */ --struct mt7621_pcie_port { -- void __iomem *base; -- struct list_head list; -- struct mt7621_pcie *pcie; -- struct clk *clk; -- struct phy *phy; -- struct reset_control *pcie_rst; -- struct gpio_desc *gpio_rst; -- u32 slot; -- bool enabled; --}; -- --/** -- * struct mt7621_pcie - PCIe host information -- * @base: IO Mapped Register Base -- * @dev: Pointer to PCIe device -- * @ports: pointer to PCIe port information -- * @resets_inverted: depends on chip revision -- * reset lines are inverted. -- */ --struct mt7621_pcie { -- struct device *dev; -- void __iomem *base; -- struct list_head ports; -- bool resets_inverted; --}; -- --static inline u32 pcie_read(struct mt7621_pcie *pcie, u32 reg) --{ -- return readl_relaxed(pcie->base + reg); --} -- --static inline void pcie_write(struct mt7621_pcie *pcie, u32 val, u32 reg) --{ -- writel_relaxed(val, pcie->base + reg); --} -- --static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) --{ -- u32 val = readl_relaxed(pcie->base + reg); -- -- val &= ~clr; -- val |= set; -- writel_relaxed(val, pcie->base + reg); --} -- --static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) --{ -- return readl_relaxed(port->base + reg); --} -- --static inline void pcie_port_write(struct mt7621_pcie_port *port, -- u32 val, u32 reg) --{ -- writel_relaxed(val, port->base + reg); --} -- --static inline u32 mt7621_pcie_get_cfgaddr(unsigned int bus, unsigned int slot, -- unsigned int func, unsigned int where) --{ -- return (((where & 0xF00) >> 8) << 24) | (bus << 16) | (slot << 11) | -- (func << 8) | (where & 0xfc) | 0x80000000; --} -- --static void __iomem *mt7621_pcie_map_bus(struct pci_bus *bus, -- unsigned int devfn, int where) --{ -- struct mt7621_pcie *pcie = bus->sysdata; -- u32 address = mt7621_pcie_get_cfgaddr(bus->number, PCI_SLOT(devfn), -- PCI_FUNC(devfn), where); -- -- writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); -- -- return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); --} -- --struct pci_ops mt7621_pcie_ops = { -- .map_bus = mt7621_pcie_map_bus, -- .read = pci_generic_config_read, -- .write = pci_generic_config_write, --}; -- --static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) --{ -- u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); -- -- pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); -- return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); --} -- --static void write_config(struct mt7621_pcie *pcie, unsigned int dev, -- u32 reg, u32 val) --{ -- u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); -- -- pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); -- pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); --} -- --static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port) --{ -- if (port->gpio_rst) -- gpiod_set_value(port->gpio_rst, 1); --} -- --static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port) --{ -- if (port->gpio_rst) -- gpiod_set_value(port->gpio_rst, 0); --} -- --static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port) --{ -- return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0; --} -- --static inline void mt7621_control_assert(struct mt7621_pcie_port *port) --{ -- struct mt7621_pcie *pcie = port->pcie; -- -- if (pcie->resets_inverted) -- reset_control_assert(port->pcie_rst); -- else -- reset_control_deassert(port->pcie_rst); --} -- --static inline void mt7621_control_deassert(struct mt7621_pcie_port *port) --{ -- struct mt7621_pcie *pcie = port->pcie; -- -- if (pcie->resets_inverted) -- reset_control_deassert(port->pcie_rst); -- else -- reset_control_assert(port->pcie_rst); --} -- --static int setup_cm_memory_region(struct pci_host_bridge *host) --{ -- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); -- struct device *dev = pcie->dev; -- struct resource_entry *entry; -- resource_size_t mask; -- -- entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); -- if (!entry) { -- dev_err(dev, "Cannot get memory resource\n"); -- return -EINVAL; -- } -- -- if (mips_cps_numiocu(0)) { -- /* -- * FIXME: hardware doesn't accept mask values with 1s after -- * 0s (e.g. 0xffef), so it would be great to warn if that's -- * about to happen -- */ -- mask = ~(entry->res->end - entry->res->start); -- -- write_gcr_reg1_base(entry->res->start); -- write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); -- dev_info(dev, "PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", -- (unsigned long long)read_gcr_reg1_base(), -- (unsigned long long)read_gcr_reg1_mask()); -- } -- -- return 0; --} -- --static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, -- struct device_node *node, -- int slot) --{ -- struct mt7621_pcie_port *port; -- struct device *dev = pcie->dev; -- struct platform_device *pdev = to_platform_device(dev); -- char name[10]; -- int err; -- -- port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); -- if (!port) -- return -ENOMEM; -- -- port->base = devm_platform_ioremap_resource(pdev, slot + 1); -- if (IS_ERR(port->base)) -- return PTR_ERR(port->base); -- -- port->clk = devm_get_clk_from_child(dev, node, NULL); -- if (IS_ERR(port->clk)) { -- dev_err(dev, "failed to get pcie%d clock\n", slot); -- return PTR_ERR(port->clk); -- } -- -- port->pcie_rst = of_reset_control_get_exclusive(node, NULL); -- if (PTR_ERR(port->pcie_rst) == -EPROBE_DEFER) { -- dev_err(dev, "failed to get pcie%d reset control\n", slot); -- return PTR_ERR(port->pcie_rst); -- } -- -- snprintf(name, sizeof(name), "pcie-phy%d", slot); -- port->phy = devm_of_phy_get(dev, node, name); -- if (IS_ERR(port->phy)) { -- dev_err(dev, "failed to get pcie-phy%d\n", slot); -- err = PTR_ERR(port->phy); -- goto remove_reset; -- } -- -- port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, -- GPIOD_OUT_LOW); -- if (IS_ERR(port->gpio_rst)) { -- dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot); -- err = PTR_ERR(port->gpio_rst); -- goto remove_reset; -- } -- -- port->slot = slot; -- port->pcie = pcie; -- -- INIT_LIST_HEAD(&port->list); -- list_add_tail(&port->list, &pcie->ports); -- -- return 0; -- --remove_reset: -- reset_control_put(port->pcie_rst); -- return err; --} -- --static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) --{ -- struct device *dev = pcie->dev; -- struct platform_device *pdev = to_platform_device(dev); -- struct device_node *node = dev->of_node, *child; -- int err; -- -- pcie->base = devm_platform_ioremap_resource(pdev, 0); -- if (IS_ERR(pcie->base)) -- return PTR_ERR(pcie->base); -- -- for_each_available_child_of_node(node, child) { -- int slot; -- -- err = of_pci_get_devfn(child); -- if (err < 0) { -- of_node_put(child); -- dev_err(dev, "failed to parse devfn: %d\n", err); -- return err; -- } -- -- slot = PCI_SLOT(err); -- -- err = mt7621_pcie_parse_port(pcie, child, slot); -- if (err) { -- of_node_put(child); -- return err; -- } -- } -- -- return 0; --} -- --static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) --{ -- struct mt7621_pcie *pcie = port->pcie; -- struct device *dev = pcie->dev; -- u32 slot = port->slot; -- int err; -- -- err = phy_init(port->phy); -- if (err) { -- dev_err(dev, "failed to initialize port%d phy\n", slot); -- return err; -- } -- -- err = phy_power_on(port->phy); -- if (err) { -- dev_err(dev, "failed to power on port%d phy\n", slot); -- phy_exit(port->phy); -- return err; -- } -- -- port->enabled = true; -- -- return 0; --} -- --static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie) --{ -- struct mt7621_pcie_port *port; -- -- list_for_each_entry(port, &pcie->ports, list) { -- /* PCIe RC reset assert */ -- mt7621_control_assert(port); -- -- /* PCIe EP reset assert */ -- mt7621_rst_gpio_pcie_assert(port); -- } -- -- msleep(PERST_DELAY_MS); --} -- --static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie) --{ -- struct mt7621_pcie_port *port; -- -- list_for_each_entry(port, &pcie->ports, list) -- mt7621_control_deassert(port); --} -- --static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie) --{ -- struct mt7621_pcie_port *port; -- -- list_for_each_entry(port, &pcie->ports, list) -- mt7621_rst_gpio_pcie_deassert(port); -- -- msleep(PERST_DELAY_MS); --} -- --static int mt7621_pcie_init_ports(struct mt7621_pcie *pcie) --{ -- struct device *dev = pcie->dev; -- struct mt7621_pcie_port *port, *tmp; -- u8 num_disabled = 0; -- int err; -- -- mt7621_pcie_reset_assert(pcie); -- mt7621_pcie_reset_rc_deassert(pcie); -- -- list_for_each_entry_safe(port, tmp, &pcie->ports, list) { -- u32 slot = port->slot; -- -- if (slot == 1) { -- port->enabled = true; -- continue; -- } -- -- err = mt7621_pcie_init_port(port); -- if (err) { -- dev_err(dev, "Initiating port %d failed\n", slot); -- list_del(&port->list); -- } -- } -- -- mt7621_pcie_reset_ep_deassert(pcie); -- -- tmp = NULL; -- list_for_each_entry(port, &pcie->ports, list) { -- u32 slot = port->slot; -- -- if (!mt7621_pcie_port_is_linkup(port)) { -- dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", -- slot); -- mt7621_control_assert(port); -- port->enabled = false; -- num_disabled++; -- -- if (slot == 0) { -- tmp = port; -- continue; -- } -- -- if (slot == 1 && tmp && !tmp->enabled) -- phy_power_off(tmp->phy); -- } -- } -- -- return (num_disabled != PCIE_PORT_CNT) ? 0 : -ENODEV; --} -- --static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) --{ -- struct mt7621_pcie *pcie = port->pcie; -- u32 slot = port->slot; -- u32 val; -- -- /* enable pcie interrupt */ -- val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR); -- val |= PCIE_PORT_INT_EN(slot); -- pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR); -- -- /* map 2G DDR region */ -- pcie_port_write(port, PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, -- PCI_BASE_ADDRESS_0); -- -- /* configure class code and revision ID */ -- pcie_port_write(port, PCIE_CLASS_CODE | PCIE_REVISION_ID, -- RALINK_PCI_CLASS); -- -- /* configure RC FTS number to 250 when it leaves L0s */ -- val = read_config(pcie, slot, PCIE_FTS_NUM); -- val &= ~PCIE_FTS_NUM_MASK; -- val |= PCIE_FTS_NUM_L0(0x50); -- write_config(pcie, slot, PCIE_FTS_NUM, val); --} -- --static int mt7621_pcie_enable_ports(struct pci_host_bridge *host) --{ -- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); -- struct device *dev = pcie->dev; -- struct mt7621_pcie_port *port; -- struct resource_entry *entry; -- int err; -- -- entry = resource_list_first_type(&host->windows, IORESOURCE_IO); -- if (!entry) { -- dev_err(dev, "Cannot get io resource\n"); -- return -EINVAL; -- } -- -- /* Setup MEMWIN and IOWIN */ -- pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE); -- pcie_write(pcie, entry->res->start, RALINK_PCI_IOBASE); -- -- list_for_each_entry(port, &pcie->ports, list) { -- if (port->enabled) { -- err = clk_prepare_enable(port->clk); -- if (err) { -- dev_err(dev, "enabling clk pcie%d\n", -- port->slot); -- return err; -- } -- -- mt7621_pcie_enable_port(port); -- dev_info(dev, "PCIE%d enabled\n", port->slot); -- } -- } -- -- return 0; --} -- --static int mt7621_pcie_register_host(struct pci_host_bridge *host) --{ -- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); -- -- host->ops = &mt7621_pcie_ops; -- host->sysdata = pcie; -- return pci_host_probe(host); --} -- --static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { -- { .soc_id = "mt7621", .revision = "E2" }, -- { /* sentinel */ } --}; -- --static int mt7621_pcie_probe(struct platform_device *pdev) --{ -- struct device *dev = &pdev->dev; -- const struct soc_device_attribute *attr; -- struct mt7621_pcie_port *port; -- struct mt7621_pcie *pcie; -- struct pci_host_bridge *bridge; -- int err; -- -- if (!dev->of_node) -- return -ENODEV; -- -- bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); -- if (!bridge) -- return -ENOMEM; -- -- pcie = pci_host_bridge_priv(bridge); -- pcie->dev = dev; -- platform_set_drvdata(pdev, pcie); -- INIT_LIST_HEAD(&pcie->ports); -- -- attr = soc_device_match(mt7621_pcie_quirks_match); -- if (attr) -- pcie->resets_inverted = true; -- -- err = mt7621_pcie_parse_dt(pcie); -- if (err) { -- dev_err(dev, "Parsing DT failed\n"); -- return err; -- } -- -- err = mt7621_pcie_init_ports(pcie); -- if (err) { -- dev_err(dev, "Nothing connected in virtual bridges\n"); -- return 0; -- } -- -- err = mt7621_pcie_enable_ports(bridge); -- if (err) { -- dev_err(dev, "Error enabling pcie ports\n"); -- goto remove_resets; -- } -- -- err = setup_cm_memory_region(bridge); -- if (err) { -- dev_err(dev, "Error setting up iocu mem regions\n"); -- goto remove_resets; -- } -- -- return mt7621_pcie_register_host(bridge); -- --remove_resets: -- list_for_each_entry(port, &pcie->ports, list) -- reset_control_put(port->pcie_rst); -- -- return err; --} -- --static int mt7621_pcie_remove(struct platform_device *pdev) --{ -- struct mt7621_pcie *pcie = platform_get_drvdata(pdev); -- struct mt7621_pcie_port *port; -- -- list_for_each_entry(port, &pcie->ports, list) -- reset_control_put(port->pcie_rst); -- -- return 0; --} -- --static const struct of_device_id mt7621_pcie_ids[] = { -- { .compatible = "mediatek,mt7621-pci" }, -- {}, --}; --MODULE_DEVICE_TABLE(of, mt7621_pcie_ids); -- --static struct platform_driver mt7621_pcie_driver = { -- .probe = mt7621_pcie_probe, -- .remove = mt7621_pcie_remove, -- .driver = { -- .name = "mt7621-pci", -- .of_match_table = of_match_ptr(mt7621_pcie_ids), -- }, --}; --builtin_platform_driver(mt7621_pcie_driver); ---- /dev/null -+++ b/drivers/pci/controller/pcie-mt7621.c -@@ -0,0 +1,600 @@ -+// SPDX-License-Identifier: GPL-2.0+ -+/* -+ * BRIEF MODULE DESCRIPTION -+ * PCI init for Ralink RT2880 solution -+ * -+ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) -+ * -+ * May 2007 Bruce Chang -+ * Initial Release -+ * -+ * May 2009 Bruce Chang -+ * support RT2880/RT3883 PCIe -+ * -+ * May 2011 Bruce Chang -+ * support RT6855/MT7620 PCIe -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* MediaTek-specific configuration registers */ -+#define PCIE_FTS_NUM 0x70c -+#define PCIE_FTS_NUM_MASK GENMASK(15, 8) -+#define PCIE_FTS_NUM_L0(x) (((x) & 0xff) << 8) -+ -+/* Host-PCI bridge registers */ -+#define RALINK_PCI_PCICFG_ADDR 0x0000 -+#define RALINK_PCI_PCIMSK_ADDR 0x000c -+#define RALINK_PCI_CONFIG_ADDR 0x0020 -+#define RALINK_PCI_CONFIG_DATA 0x0024 -+#define RALINK_PCI_MEMBASE 0x0028 -+#define RALINK_PCI_IOBASE 0x002c -+ -+/* PCIe RC control registers */ -+#define RALINK_PCI_ID 0x0030 -+#define RALINK_PCI_CLASS 0x0034 -+#define RALINK_PCI_SUBID 0x0038 -+#define RALINK_PCI_STATUS 0x0050 -+ -+/* Some definition values */ -+#define PCIE_REVISION_ID BIT(0) -+#define PCIE_CLASS_CODE (0x60400 << 8) -+#define PCIE_BAR_MAP_MAX GENMASK(30, 16) -+#define PCIE_BAR_ENABLE BIT(0) -+#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) -+#define PCIE_PORT_LINKUP BIT(0) -+#define PCIE_PORT_CNT 3 -+ -+#define PERST_DELAY_MS 100 -+ -+/** -+ * struct mt7621_pcie_port - PCIe port information -+ * @base: I/O mapped register base -+ * @list: port list -+ * @pcie: pointer to PCIe host info -+ * @clk: pointer to the port clock gate -+ * @phy: pointer to PHY control block -+ * @pcie_rst: pointer to port reset control -+ * @gpio_rst: gpio reset -+ * @slot: port slot -+ * @enabled: indicates if port is enabled -+ */ -+struct mt7621_pcie_port { -+ void __iomem *base; -+ struct list_head list; -+ struct mt7621_pcie *pcie; -+ struct clk *clk; -+ struct phy *phy; -+ struct reset_control *pcie_rst; -+ struct gpio_desc *gpio_rst; -+ u32 slot; -+ bool enabled; -+}; -+ -+/** -+ * struct mt7621_pcie - PCIe host information -+ * @base: IO Mapped Register Base -+ * @dev: Pointer to PCIe device -+ * @ports: pointer to PCIe port information -+ * @resets_inverted: depends on chip revision -+ * reset lines are inverted. -+ */ -+struct mt7621_pcie { -+ void __iomem *base; -+ struct device *dev; -+ struct list_head ports; -+ bool resets_inverted; -+}; -+ -+static inline u32 pcie_read(struct mt7621_pcie *pcie, u32 reg) -+{ -+ return readl_relaxed(pcie->base + reg); -+} -+ -+static inline void pcie_write(struct mt7621_pcie *pcie, u32 val, u32 reg) -+{ -+ writel_relaxed(val, pcie->base + reg); -+} -+ -+static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) -+{ -+ u32 val = readl_relaxed(pcie->base + reg); -+ -+ val &= ~clr; -+ val |= set; -+ writel_relaxed(val, pcie->base + reg); -+} -+ -+static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) -+{ -+ return readl_relaxed(port->base + reg); -+} -+ -+static inline void pcie_port_write(struct mt7621_pcie_port *port, -+ u32 val, u32 reg) -+{ -+ writel_relaxed(val, port->base + reg); -+} -+ -+static inline u32 mt7621_pci_get_cfgaddr(unsigned int bus, unsigned int slot, -+ unsigned int func, unsigned int where) -+{ -+ return (((where & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) | -+ (func << 8) | (where & 0xfc) | 0x80000000; -+} -+ -+static void __iomem *mt7621_pcie_map_bus(struct pci_bus *bus, -+ unsigned int devfn, int where) -+{ -+ struct mt7621_pcie *pcie = bus->sysdata; -+ u32 address = mt7621_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), -+ PCI_FUNC(devfn), where); -+ -+ writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); -+ -+ return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); -+} -+ -+struct pci_ops mt7621_pci_ops = { -+ .map_bus = mt7621_pcie_map_bus, -+ .read = pci_generic_config_read, -+ .write = pci_generic_config_write, -+}; -+ -+static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) -+{ -+ u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); -+ -+ pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); -+ return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); -+} -+ -+static void write_config(struct mt7621_pcie *pcie, unsigned int dev, -+ u32 reg, u32 val) -+{ -+ u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); -+ -+ pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); -+ pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); -+} -+ -+static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port) -+{ -+ if (port->gpio_rst) -+ gpiod_set_value(port->gpio_rst, 1); -+} -+ -+static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port) -+{ -+ if (port->gpio_rst) -+ gpiod_set_value(port->gpio_rst, 0); -+} -+ -+static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port) -+{ -+ return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0; -+} -+ -+static inline void mt7621_control_assert(struct mt7621_pcie_port *port) -+{ -+ struct mt7621_pcie *pcie = port->pcie; -+ -+ if (pcie->resets_inverted) -+ reset_control_assert(port->pcie_rst); -+ else -+ reset_control_deassert(port->pcie_rst); -+} -+ -+static inline void mt7621_control_deassert(struct mt7621_pcie_port *port) -+{ -+ struct mt7621_pcie *pcie = port->pcie; -+ -+ if (pcie->resets_inverted) -+ reset_control_deassert(port->pcie_rst); -+ else -+ reset_control_assert(port->pcie_rst); -+} -+ -+static int setup_cm_memory_region(struct pci_host_bridge *host) -+{ -+ struct mt7621_pcie *pcie = pci_host_bridge_priv(host); -+ struct device *dev = pcie->dev; -+ struct resource_entry *entry; -+ resource_size_t mask; -+ -+ entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); -+ if (!entry) { -+ dev_err(dev, "cannot get memory resource\n"); -+ return -EINVAL; -+ } -+ -+ if (mips_cps_numiocu(0)) { -+ /* -+ * FIXME: hardware doesn't accept mask values with 1s after -+ * 0s (e.g. 0xffef), so it would be great to warn if that's -+ * about to happen -+ */ -+ mask = ~(entry->res->end - entry->res->start); -+ -+ write_gcr_reg1_base(entry->res->start); -+ write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); -+ dev_info(dev, "PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", -+ (unsigned long long)read_gcr_reg1_base(), -+ (unsigned long long)read_gcr_reg1_mask()); -+ } -+ -+ return 0; -+} -+ -+static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, -+ struct device_node *node, -+ int slot) -+{ -+ struct mt7621_pcie_port *port; -+ struct device *dev = pcie->dev; -+ struct platform_device *pdev = to_platform_device(dev); -+ char name[10]; -+ int err; -+ -+ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); -+ if (!port) -+ return -ENOMEM; -+ -+ port->base = devm_platform_ioremap_resource(pdev, slot + 1); -+ if (IS_ERR(port->base)) -+ return PTR_ERR(port->base); -+ -+ port->clk = devm_get_clk_from_child(dev, node, NULL); -+ if (IS_ERR(port->clk)) { -+ dev_err(dev, "failed to get pcie%d clock\n", slot); -+ return PTR_ERR(port->clk); -+ } -+ -+ port->pcie_rst = of_reset_control_get_exclusive(node, NULL); -+ if (PTR_ERR(port->pcie_rst) == -EPROBE_DEFER) { -+ dev_err(dev, "failed to get pcie%d reset control\n", slot); -+ return PTR_ERR(port->pcie_rst); -+ } -+ -+ snprintf(name, sizeof(name), "pcie-phy%d", slot); -+ port->phy = devm_of_phy_get(dev, node, name); -+ if (IS_ERR(port->phy)) { -+ dev_err(dev, "failed to get pcie-phy%d\n", slot); -+ err = PTR_ERR(port->phy); -+ goto remove_reset; -+ } -+ -+ port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, -+ GPIOD_OUT_LOW); -+ if (IS_ERR(port->gpio_rst)) { -+ dev_err(dev, "failed to get GPIO for PCIe%d\n", slot); -+ err = PTR_ERR(port->gpio_rst); -+ goto remove_reset; -+ } -+ -+ port->slot = slot; -+ port->pcie = pcie; -+ -+ INIT_LIST_HEAD(&port->list); -+ list_add_tail(&port->list, &pcie->ports); -+ -+ return 0; -+ -+remove_reset: -+ reset_control_put(port->pcie_rst); -+ return err; -+} -+ -+static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) -+{ -+ struct device *dev = pcie->dev; -+ struct platform_device *pdev = to_platform_device(dev); -+ struct device_node *node = dev->of_node, *child; -+ int err; -+ -+ pcie->base = devm_platform_ioremap_resource(pdev, 0); -+ if (IS_ERR(pcie->base)) -+ return PTR_ERR(pcie->base); -+ -+ for_each_available_child_of_node(node, child) { -+ int slot; -+ -+ err = of_pci_get_devfn(child); -+ if (err < 0) { -+ of_node_put(child); -+ dev_err(dev, "failed to parse devfn: %d\n", err); -+ return err; -+ } -+ -+ slot = PCI_SLOT(err); -+ -+ err = mt7621_pcie_parse_port(pcie, child, slot); -+ if (err) { -+ of_node_put(child); -+ return err; -+ } -+ } -+ -+ return 0; -+} -+ -+static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) -+{ -+ struct mt7621_pcie *pcie = port->pcie; -+ struct device *dev = pcie->dev; -+ u32 slot = port->slot; -+ int err; -+ -+ err = phy_init(port->phy); -+ if (err) { -+ dev_err(dev, "failed to initialize port%d phy\n", slot); -+ return err; -+ } -+ -+ err = phy_power_on(port->phy); -+ if (err) { -+ dev_err(dev, "failed to power on port%d phy\n", slot); -+ phy_exit(port->phy); -+ return err; -+ } -+ -+ port->enabled = true; -+ -+ return 0; -+} -+ -+static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie) -+{ -+ struct mt7621_pcie_port *port; -+ -+ list_for_each_entry(port, &pcie->ports, list) { -+ /* PCIe RC reset assert */ -+ mt7621_control_assert(port); -+ -+ /* PCIe EP reset assert */ -+ mt7621_rst_gpio_pcie_assert(port); -+ } -+ -+ msleep(PERST_DELAY_MS); -+} -+ -+static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie) -+{ -+ struct mt7621_pcie_port *port; -+ -+ list_for_each_entry(port, &pcie->ports, list) -+ mt7621_control_deassert(port); -+} -+ -+static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie) -+{ -+ struct mt7621_pcie_port *port; -+ -+ list_for_each_entry(port, &pcie->ports, list) -+ mt7621_rst_gpio_pcie_deassert(port); -+ -+ msleep(PERST_DELAY_MS); -+} -+ -+static int mt7621_pcie_init_ports(struct mt7621_pcie *pcie) -+{ -+ struct device *dev = pcie->dev; -+ struct mt7621_pcie_port *port, *tmp; -+ u8 num_disabled = 0; -+ int err; -+ -+ mt7621_pcie_reset_assert(pcie); -+ mt7621_pcie_reset_rc_deassert(pcie); -+ -+ list_for_each_entry_safe(port, tmp, &pcie->ports, list) { -+ u32 slot = port->slot; -+ -+ if (slot == 1) { -+ port->enabled = true; -+ continue; -+ } -+ -+ err = mt7621_pcie_init_port(port); -+ if (err) { -+ dev_err(dev, "initializing port %d failed\n", slot); -+ list_del(&port->list); -+ } -+ } -+ -+ mt7621_pcie_reset_ep_deassert(pcie); -+ -+ tmp = NULL; -+ list_for_each_entry(port, &pcie->ports, list) { -+ u32 slot = port->slot; -+ -+ if (!mt7621_pcie_port_is_linkup(port)) { -+ dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", -+ slot); -+ mt7621_control_assert(port); -+ port->enabled = false; -+ num_disabled++; -+ -+ if (slot == 0) { -+ tmp = port; -+ continue; -+ } -+ -+ if (slot == 1 && tmp && !tmp->enabled) -+ phy_power_off(tmp->phy); -+ } -+ } -+ -+ return (num_disabled != PCIE_PORT_CNT) ? 0 : -ENODEV; -+} -+ -+static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) -+{ -+ struct mt7621_pcie *pcie = port->pcie; -+ u32 slot = port->slot; -+ u32 val; -+ -+ /* enable pcie interrupt */ -+ val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR); -+ val |= PCIE_PORT_INT_EN(slot); -+ pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR); -+ -+ /* map 2G DDR region */ -+ pcie_port_write(port, PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, -+ PCI_BASE_ADDRESS_0); -+ -+ /* configure class code and revision ID */ -+ pcie_port_write(port, PCIE_CLASS_CODE | PCIE_REVISION_ID, -+ RALINK_PCI_CLASS); -+ -+ /* configure RC FTS number to 250 when it leaves L0s */ -+ val = read_config(pcie, slot, PCIE_FTS_NUM); -+ val &= ~PCIE_FTS_NUM_MASK; -+ val |= PCIE_FTS_NUM_L0(0x50); -+ write_config(pcie, slot, PCIE_FTS_NUM, val); -+} -+ -+static int mt7621_pcie_enable_ports(struct pci_host_bridge *host) -+{ -+ struct mt7621_pcie *pcie = pci_host_bridge_priv(host); -+ struct device *dev = pcie->dev; -+ struct mt7621_pcie_port *port; -+ struct resource_entry *entry; -+ int err; -+ -+ entry = resource_list_first_type(&host->windows, IORESOURCE_IO); -+ if (!entry) { -+ dev_err(dev, "cannot get io resource\n"); -+ return -EINVAL; -+ } -+ -+ /* Setup MEMWIN and IOWIN */ -+ pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE); -+ pcie_write(pcie, entry->res->start, RALINK_PCI_IOBASE); -+ -+ list_for_each_entry(port, &pcie->ports, list) { -+ if (port->enabled) { -+ err = clk_prepare_enable(port->clk); -+ if (err) { -+ dev_err(dev, "enabling clk pcie%d\n", -+ port->slot); -+ return err; -+ } -+ -+ mt7621_pcie_enable_port(port); -+ dev_info(dev, "PCIE%d enabled\n", port->slot); -+ } -+ } -+ -+ return 0; -+} -+ -+static int mt7621_pcie_register_host(struct pci_host_bridge *host) -+{ -+ struct mt7621_pcie *pcie = pci_host_bridge_priv(host); -+ -+ host->ops = &mt7621_pci_ops; -+ host->sysdata = pcie; -+ return pci_host_probe(host); -+} -+ -+static const struct soc_device_attribute mt7621_pci_quirks_match[] = { -+ { .soc_id = "mt7621", .revision = "E2" } -+}; -+ -+static int mt7621_pci_probe(struct platform_device *pdev) -+{ -+ struct device *dev = &pdev->dev; -+ const struct soc_device_attribute *attr; -+ struct mt7621_pcie_port *port; -+ struct mt7621_pcie *pcie; -+ struct pci_host_bridge *bridge; -+ int err; -+ -+ if (!dev->of_node) -+ return -ENODEV; -+ -+ bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); -+ if (!bridge) -+ return -ENOMEM; -+ -+ pcie = pci_host_bridge_priv(bridge); -+ pcie->dev = dev; -+ platform_set_drvdata(pdev, pcie); -+ INIT_LIST_HEAD(&pcie->ports); -+ -+ attr = soc_device_match(mt7621_pci_quirks_match); -+ if (attr) -+ pcie->resets_inverted = true; -+ -+ err = mt7621_pcie_parse_dt(pcie); -+ if (err) { -+ dev_err(dev, "parsing DT failed\n"); -+ return err; -+ } -+ -+ err = mt7621_pcie_init_ports(pcie); -+ if (err) { -+ dev_err(dev, "nothing connected in virtual bridges\n"); -+ return 0; -+ } -+ -+ err = mt7621_pcie_enable_ports(bridge); -+ if (err) { -+ dev_err(dev, "error enabling pcie ports\n"); -+ goto remove_resets; -+ } -+ -+ err = setup_cm_memory_region(bridge); -+ if (err) { -+ dev_err(dev, "error setting up iocu mem regions\n"); -+ goto remove_resets; -+ } -+ -+ return mt7621_pcie_register_host(bridge); -+ -+remove_resets: -+ list_for_each_entry(port, &pcie->ports, list) -+ reset_control_put(port->pcie_rst); -+ -+ return err; -+} -+ -+static int mt7621_pci_remove(struct platform_device *pdev) -+{ -+ struct mt7621_pcie *pcie = platform_get_drvdata(pdev); -+ struct mt7621_pcie_port *port; -+ -+ list_for_each_entry(port, &pcie->ports, list) -+ reset_control_put(port->pcie_rst); -+ -+ return 0; -+} -+ -+static const struct of_device_id mt7621_pci_ids[] = { -+ { .compatible = "mediatek,mt7621-pci" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mt7621_pci_ids); -+ -+static struct platform_driver mt7621_pci_driver = { -+ .probe = mt7621_pci_probe, -+ .remove = mt7621_pci_remove, -+ .driver = { -+ .name = "mt7621-pci", -+ .of_match_table = of_match_ptr(mt7621_pci_ids), -+ }, -+}; -+builtin_platform_driver(mt7621_pci_driver); diff --git a/target/linux/ramips/patches-5.15/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch b/target/linux/ramips/patches-5.15/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch new file mode 100644 index 0000000000..1c8c7cd3d0 --- /dev/null +++ b/target/linux/ramips/patches-5.15/100-v5.16-PCI-mt7621-Add-MediaTek-MT7621-PCIe-host-controller-.patch @@ -0,0 +1,1418 @@ +From: Sergio Paracuellos +Date: Wed, 22 Sep 2021 07:00:34 +0200 +Subject: [PATCH] PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver + +Add driver for the PCIe controller of the MT7621 SoC. + +[bhelgaas: rename from pci-mt7621.c to pcie-mt7621.c; also rename Kconfig +symbol from PCI_MT7621 to PCIE_MT7621] +Link: https://lore.kernel.org/r/20210922050035.18162-3-sergio.paracuellos@gmail.com +Signed-off-by: Sergio Paracuellos +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Bjorn Helgaas +Acked-by: Greg Kroah-Hartman +--- + rename drivers/{staging/mt7621-pci/pci-mt7621.c => pci/controller/pcie-mt7621.c} (95%) + delete mode 100644 drivers/staging/mt7621-pci/Kconfig + delete mode 100644 drivers/staging/mt7621-pci/Makefile + delete mode 100644 drivers/staging/mt7621-pci/TODO + delete mode 100644 drivers/staging/mt7621-pci/mediatek,mt7621-pci.txt + +--- a/arch/mips/ralink/Kconfig ++++ b/arch/mips/ralink/Kconfig +@@ -51,7 +51,8 @@ choice + select SYS_SUPPORTS_HIGHMEM + select MIPS_GIC + select CLKSRC_MIPS_GIC +- select HAVE_PCI if PCI_MT7621 ++ select HAVE_PCI ++ select PCI_DRIVERS_GENERIC + select SOC_BUS + endchoice + +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -312,6 +312,14 @@ config PCIE_HISI_ERR + Say Y here if you want error handling support + for the PCIe controller's errors on HiSilicon HIP SoCs + ++config PCIE_MT7621 ++ tristate "MediaTek MT7621 PCIe Controller" ++ depends on (RALINK && SOC_MT7621) || (MIPS && COMPILE_TEST) ++ select PHY_MT7621_PCI ++ default SOC_MT7621 ++ help ++ This selects a driver for the MediaTek MT7621 PCIe Controller. ++ + source "drivers/pci/controller/dwc/Kconfig" + source "drivers/pci/controller/mobiveil/Kconfig" + source "drivers/pci/controller/cadence/Kconfig" +--- a/drivers/pci/controller/Makefile ++++ b/drivers/pci/controller/Makefile +@@ -37,6 +37,8 @@ obj-$(CONFIG_VMD) += vmd.o + obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o + obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o + obj-$(CONFIG_PCIE_HISI_ERR) += pcie-hisi-error.o ++obj-$(CONFIG_PCIE_MT7621) += pcie-mt7621.o ++ + # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW + obj-y += dwc/ + obj-y += mobiveil/ +--- a/drivers/staging/Kconfig ++++ b/drivers/staging/Kconfig +@@ -86,8 +86,6 @@ source "drivers/staging/vc04_services/Kc + + source "drivers/staging/pi433/Kconfig" + +-source "drivers/staging/mt7621-pci/Kconfig" +- + source "drivers/staging/mt7621-dma/Kconfig" + + source "drivers/staging/ralink-gdma/Kconfig" +--- a/drivers/staging/Makefile ++++ b/drivers/staging/Makefile +@@ -33,7 +33,6 @@ obj-$(CONFIG_KS7010) += ks7010/ + obj-$(CONFIG_GREYBUS) += greybus/ + obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ + obj-$(CONFIG_PI433) += pi433/ +-obj-$(CONFIG_PCI_MT7621) += mt7621-pci/ + obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ + obj-$(CONFIG_DMA_RALINK) += ralink-gdma/ + obj-$(CONFIG_SOC_MT7621) += mt7621-dts/ +--- a/drivers/staging/mt7621-pci/Kconfig ++++ /dev/null +@@ -1,8 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0 +-config PCI_MT7621 +- tristate "MediaTek MT7621 PCI Controller" +- depends on RALINK +- select PCI_DRIVERS_GENERIC +- help +- This selects a driver for the MediaTek MT7621 PCI Controller. +- +--- a/drivers/staging/mt7621-pci/Makefile ++++ /dev/null +@@ -1,2 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0 +-obj-$(CONFIG_PCI_MT7621) += pci-mt7621.o +--- a/drivers/staging/mt7621-pci/TODO ++++ /dev/null +@@ -1,4 +0,0 @@ +- +-- general code review and cleanup +- +-Cc: NeilBrown +--- a/drivers/staging/mt7621-pci/mediatek,mt7621-pci.txt ++++ /dev/null +@@ -1,104 +0,0 @@ +-MediaTek MT7621 PCIe controller +- +-Required properties: +-- compatible: "mediatek,mt7621-pci" +-- device_type: Must be "pci" +-- reg: Base addresses and lengths of the PCIe subsys and root ports. +-- bus-range: Range of bus numbers associated with this controller. +-- #address-cells: Address representation for root ports (must be 3) +-- pinctrl-names : The pin control state names. +-- pinctrl-0: The "default" pinctrl state. +-- #size-cells: Size representation for root ports (must be 2) +-- ranges: Ranges for the PCI memory and I/O regions. +-- #interrupt-cells: Must be 1 +-- interrupt-map-mask and interrupt-map: Standard PCI IRQ mapping properties. +- Please refer to the standard PCI bus binding document for a more detailed +- explanation. +-- status: either "disabled" or "okay". +-- resets: Must contain an entry for each entry in reset-names. +- See ../reset/reset.txt for details. +-- reset-names: Must be "pcie0", "pcie1", "pcieN"... based on the number of +- root ports. +-- clocks: Must contain an entry for each entry in clock-names. +- See ../clocks/clock-bindings.txt for details. +-- clock-names: Must be "pcie0", "pcie1", "pcieN"... based on the number of +- root ports. +-- reset-gpios: GPIO specs for the reset pins. +- +-In addition, the device tree node must have sub-nodes describing each PCIe port +-interface, having the following mandatory properties: +- +-Required properties: +-- reg: Only the first four bytes are used to refer to the correct bus number +- and device number. +-- #address-cells: Must be 3 +-- #size-cells: Must be 2 +-- ranges: Sub-ranges distributed from the PCIe controller node. An empty +- property is sufficient. +-- bus-range: Range of bus numbers associated with this port. +- +-Example for MT7621: +- +- pcie: pcie@1e140000 { +- compatible = "mediatek,mt7621-pci"; +- reg = <0x1e140000 0x100 /* host-pci bridge registers */ +- 0x1e142000 0x100 /* pcie port 0 RC control registers */ +- 0x1e143000 0x100 /* pcie port 1 RC control registers */ +- 0x1e144000 0x100>; /* pcie port 2 RC control registers */ +- +- #address-cells = <3>; +- #size-cells = <2>; +- +- pinctrl-names = "default"; +- pinctrl-0 = <&pcie_pins>; +- +- device_type = "pci"; +- +- bus-range = <0 255>; +- ranges = < +- 0x02000000 0 0x00000000 0x60000000 0 0x10000000 /* pci memory */ +- 0x01000000 0 0x00000000 0x1e160000 0 0x00010000 /* io space */ +- >; +- +- #interrupt-cells = <1>; +- interrupt-map-mask = <0xF0000 0 0 1>; +- interrupt-map = <0x10000 0 0 1 &gic GIC_SHARED 4 IRQ_TYPE_LEVEL_HIGH>, +- <0x20000 0 0 1 &gic GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>, +- <0x30000 0 0 1 &gic GIC_SHARED 25 IRQ_TYPE_LEVEL_HIGH>; +- +- status = "disabled"; +- +- resets = <&rstctrl 24 &rstctrl 25 &rstctrl 26>; +- reset-names = "pcie0", "pcie1", "pcie2"; +- clocks = <&clkctrl 24 &clkctrl 25 &clkctrl 26>; +- clock-names = "pcie0", "pcie1", "pcie2"; +- +- reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>, +- <&gpio 8 GPIO_ACTIVE_LOW>, +- <&gpio 7 GPIO_ACTIVE_LOW>; +- +- pcie@0,0 { +- reg = <0x0000 0 0 0 0>; +- #address-cells = <3>; +- #size-cells = <2>; +- ranges; +- bus-range = <0x00 0xff>; +- }; +- +- pcie@1,0 { +- reg = <0x0800 0 0 0 0>; +- #address-cells = <3>; +- #size-cells = <2>; +- ranges; +- bus-range = <0x00 0xff>; +- }; +- +- pcie@2,0 { +- reg = <0x1000 0 0 0 0>; +- #address-cells = <3>; +- #size-cells = <2>; +- ranges; +- bus-range = <0x00 0xff>; +- }; +- }; +- +--- a/drivers/staging/mt7621-pci/pci-mt7621.c ++++ /dev/null +@@ -1,601 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ +-/* +- * BRIEF MODULE DESCRIPTION +- * PCI init for Ralink RT2880 solution +- * +- * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) +- * +- * May 2007 Bruce Chang +- * Initial Release +- * +- * May 2009 Bruce Chang +- * support RT2880/RT3883 PCIe +- * +- * May 2011 Bruce Chang +- * support RT6855/MT7620 PCIe +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-/* MediaTek specific configuration registers */ +-#define PCIE_FTS_NUM 0x70c +-#define PCIE_FTS_NUM_MASK GENMASK(15, 8) +-#define PCIE_FTS_NUM_L0(x) (((x) & 0xff) << 8) +- +-/* Host-PCI bridge registers */ +-#define RALINK_PCI_PCICFG_ADDR 0x0000 +-#define RALINK_PCI_PCIMSK_ADDR 0x000C +-#define RALINK_PCI_CONFIG_ADDR 0x0020 +-#define RALINK_PCI_CONFIG_DATA 0x0024 +-#define RALINK_PCI_MEMBASE 0x0028 +-#define RALINK_PCI_IOBASE 0x002C +- +-/* PCIe RC control registers */ +-#define RALINK_PCI_ID 0x0030 +-#define RALINK_PCI_CLASS 0x0034 +-#define RALINK_PCI_SUBID 0x0038 +-#define RALINK_PCI_STATUS 0x0050 +- +-/* Some definition values */ +-#define PCIE_REVISION_ID BIT(0) +-#define PCIE_CLASS_CODE (0x60400 << 8) +-#define PCIE_BAR_MAP_MAX GENMASK(30, 16) +-#define PCIE_BAR_ENABLE BIT(0) +-#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) +-#define PCIE_PORT_LINKUP BIT(0) +-#define PCIE_PORT_CNT 3 +- +-#define PERST_DELAY_MS 100 +- +-/** +- * struct mt7621_pcie_port - PCIe port information +- * @base: I/O mapped register base +- * @list: port list +- * @pcie: pointer to PCIe host info +- * @clk: pointer to the port clock gate +- * @phy: pointer to PHY control block +- * @pcie_rst: pointer to port reset control +- * @gpio_rst: gpio reset +- * @slot: port slot +- * @enabled: indicates if port is enabled +- */ +-struct mt7621_pcie_port { +- void __iomem *base; +- struct list_head list; +- struct mt7621_pcie *pcie; +- struct clk *clk; +- struct phy *phy; +- struct reset_control *pcie_rst; +- struct gpio_desc *gpio_rst; +- u32 slot; +- bool enabled; +-}; +- +-/** +- * struct mt7621_pcie - PCIe host information +- * @base: IO Mapped Register Base +- * @dev: Pointer to PCIe device +- * @ports: pointer to PCIe port information +- * @resets_inverted: depends on chip revision +- * reset lines are inverted. +- */ +-struct mt7621_pcie { +- struct device *dev; +- void __iomem *base; +- struct list_head ports; +- bool resets_inverted; +-}; +- +-static inline u32 pcie_read(struct mt7621_pcie *pcie, u32 reg) +-{ +- return readl_relaxed(pcie->base + reg); +-} +- +-static inline void pcie_write(struct mt7621_pcie *pcie, u32 val, u32 reg) +-{ +- writel_relaxed(val, pcie->base + reg); +-} +- +-static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) +-{ +- u32 val = readl_relaxed(pcie->base + reg); +- +- val &= ~clr; +- val |= set; +- writel_relaxed(val, pcie->base + reg); +-} +- +-static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) +-{ +- return readl_relaxed(port->base + reg); +-} +- +-static inline void pcie_port_write(struct mt7621_pcie_port *port, +- u32 val, u32 reg) +-{ +- writel_relaxed(val, port->base + reg); +-} +- +-static inline u32 mt7621_pcie_get_cfgaddr(unsigned int bus, unsigned int slot, +- unsigned int func, unsigned int where) +-{ +- return (((where & 0xF00) >> 8) << 24) | (bus << 16) | (slot << 11) | +- (func << 8) | (where & 0xfc) | 0x80000000; +-} +- +-static void __iomem *mt7621_pcie_map_bus(struct pci_bus *bus, +- unsigned int devfn, int where) +-{ +- struct mt7621_pcie *pcie = bus->sysdata; +- u32 address = mt7621_pcie_get_cfgaddr(bus->number, PCI_SLOT(devfn), +- PCI_FUNC(devfn), where); +- +- writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); +- +- return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); +-} +- +-struct pci_ops mt7621_pcie_ops = { +- .map_bus = mt7621_pcie_map_bus, +- .read = pci_generic_config_read, +- .write = pci_generic_config_write, +-}; +- +-static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) +-{ +- u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); +- +- pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); +- return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); +-} +- +-static void write_config(struct mt7621_pcie *pcie, unsigned int dev, +- u32 reg, u32 val) +-{ +- u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); +- +- pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); +- pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); +-} +- +-static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port) +-{ +- if (port->gpio_rst) +- gpiod_set_value(port->gpio_rst, 1); +-} +- +-static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port) +-{ +- if (port->gpio_rst) +- gpiod_set_value(port->gpio_rst, 0); +-} +- +-static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port) +-{ +- return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0; +-} +- +-static inline void mt7621_control_assert(struct mt7621_pcie_port *port) +-{ +- struct mt7621_pcie *pcie = port->pcie; +- +- if (pcie->resets_inverted) +- reset_control_assert(port->pcie_rst); +- else +- reset_control_deassert(port->pcie_rst); +-} +- +-static inline void mt7621_control_deassert(struct mt7621_pcie_port *port) +-{ +- struct mt7621_pcie *pcie = port->pcie; +- +- if (pcie->resets_inverted) +- reset_control_deassert(port->pcie_rst); +- else +- reset_control_assert(port->pcie_rst); +-} +- +-static int setup_cm_memory_region(struct pci_host_bridge *host) +-{ +- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); +- struct device *dev = pcie->dev; +- struct resource_entry *entry; +- resource_size_t mask; +- +- entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); +- if (!entry) { +- dev_err(dev, "Cannot get memory resource\n"); +- return -EINVAL; +- } +- +- if (mips_cps_numiocu(0)) { +- /* +- * FIXME: hardware doesn't accept mask values with 1s after +- * 0s (e.g. 0xffef), so it would be great to warn if that's +- * about to happen +- */ +- mask = ~(entry->res->end - entry->res->start); +- +- write_gcr_reg1_base(entry->res->start); +- write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); +- dev_info(dev, "PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", +- (unsigned long long)read_gcr_reg1_base(), +- (unsigned long long)read_gcr_reg1_mask()); +- } +- +- return 0; +-} +- +-static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, +- struct device_node *node, +- int slot) +-{ +- struct mt7621_pcie_port *port; +- struct device *dev = pcie->dev; +- struct platform_device *pdev = to_platform_device(dev); +- char name[10]; +- int err; +- +- port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); +- if (!port) +- return -ENOMEM; +- +- port->base = devm_platform_ioremap_resource(pdev, slot + 1); +- if (IS_ERR(port->base)) +- return PTR_ERR(port->base); +- +- port->clk = devm_get_clk_from_child(dev, node, NULL); +- if (IS_ERR(port->clk)) { +- dev_err(dev, "failed to get pcie%d clock\n", slot); +- return PTR_ERR(port->clk); +- } +- +- port->pcie_rst = of_reset_control_get_exclusive(node, NULL); +- if (PTR_ERR(port->pcie_rst) == -EPROBE_DEFER) { +- dev_err(dev, "failed to get pcie%d reset control\n", slot); +- return PTR_ERR(port->pcie_rst); +- } +- +- snprintf(name, sizeof(name), "pcie-phy%d", slot); +- port->phy = devm_of_phy_get(dev, node, name); +- if (IS_ERR(port->phy)) { +- dev_err(dev, "failed to get pcie-phy%d\n", slot); +- err = PTR_ERR(port->phy); +- goto remove_reset; +- } +- +- port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, +- GPIOD_OUT_LOW); +- if (IS_ERR(port->gpio_rst)) { +- dev_err(dev, "Failed to get GPIO for PCIe%d\n", slot); +- err = PTR_ERR(port->gpio_rst); +- goto remove_reset; +- } +- +- port->slot = slot; +- port->pcie = pcie; +- +- INIT_LIST_HEAD(&port->list); +- list_add_tail(&port->list, &pcie->ports); +- +- return 0; +- +-remove_reset: +- reset_control_put(port->pcie_rst); +- return err; +-} +- +-static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) +-{ +- struct device *dev = pcie->dev; +- struct platform_device *pdev = to_platform_device(dev); +- struct device_node *node = dev->of_node, *child; +- int err; +- +- pcie->base = devm_platform_ioremap_resource(pdev, 0); +- if (IS_ERR(pcie->base)) +- return PTR_ERR(pcie->base); +- +- for_each_available_child_of_node(node, child) { +- int slot; +- +- err = of_pci_get_devfn(child); +- if (err < 0) { +- of_node_put(child); +- dev_err(dev, "failed to parse devfn: %d\n", err); +- return err; +- } +- +- slot = PCI_SLOT(err); +- +- err = mt7621_pcie_parse_port(pcie, child, slot); +- if (err) { +- of_node_put(child); +- return err; +- } +- } +- +- return 0; +-} +- +-static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) +-{ +- struct mt7621_pcie *pcie = port->pcie; +- struct device *dev = pcie->dev; +- u32 slot = port->slot; +- int err; +- +- err = phy_init(port->phy); +- if (err) { +- dev_err(dev, "failed to initialize port%d phy\n", slot); +- return err; +- } +- +- err = phy_power_on(port->phy); +- if (err) { +- dev_err(dev, "failed to power on port%d phy\n", slot); +- phy_exit(port->phy); +- return err; +- } +- +- port->enabled = true; +- +- return 0; +-} +- +-static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie) +-{ +- struct mt7621_pcie_port *port; +- +- list_for_each_entry(port, &pcie->ports, list) { +- /* PCIe RC reset assert */ +- mt7621_control_assert(port); +- +- /* PCIe EP reset assert */ +- mt7621_rst_gpio_pcie_assert(port); +- } +- +- msleep(PERST_DELAY_MS); +-} +- +-static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie) +-{ +- struct mt7621_pcie_port *port; +- +- list_for_each_entry(port, &pcie->ports, list) +- mt7621_control_deassert(port); +-} +- +-static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie) +-{ +- struct mt7621_pcie_port *port; +- +- list_for_each_entry(port, &pcie->ports, list) +- mt7621_rst_gpio_pcie_deassert(port); +- +- msleep(PERST_DELAY_MS); +-} +- +-static int mt7621_pcie_init_ports(struct mt7621_pcie *pcie) +-{ +- struct device *dev = pcie->dev; +- struct mt7621_pcie_port *port, *tmp; +- u8 num_disabled = 0; +- int err; +- +- mt7621_pcie_reset_assert(pcie); +- mt7621_pcie_reset_rc_deassert(pcie); +- +- list_for_each_entry_safe(port, tmp, &pcie->ports, list) { +- u32 slot = port->slot; +- +- if (slot == 1) { +- port->enabled = true; +- continue; +- } +- +- err = mt7621_pcie_init_port(port); +- if (err) { +- dev_err(dev, "Initiating port %d failed\n", slot); +- list_del(&port->list); +- } +- } +- +- mt7621_pcie_reset_ep_deassert(pcie); +- +- tmp = NULL; +- list_for_each_entry(port, &pcie->ports, list) { +- u32 slot = port->slot; +- +- if (!mt7621_pcie_port_is_linkup(port)) { +- dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", +- slot); +- mt7621_control_assert(port); +- port->enabled = false; +- num_disabled++; +- +- if (slot == 0) { +- tmp = port; +- continue; +- } +- +- if (slot == 1 && tmp && !tmp->enabled) +- phy_power_off(tmp->phy); +- } +- } +- +- return (num_disabled != PCIE_PORT_CNT) ? 0 : -ENODEV; +-} +- +-static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) +-{ +- struct mt7621_pcie *pcie = port->pcie; +- u32 slot = port->slot; +- u32 val; +- +- /* enable pcie interrupt */ +- val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR); +- val |= PCIE_PORT_INT_EN(slot); +- pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR); +- +- /* map 2G DDR region */ +- pcie_port_write(port, PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, +- PCI_BASE_ADDRESS_0); +- +- /* configure class code and revision ID */ +- pcie_port_write(port, PCIE_CLASS_CODE | PCIE_REVISION_ID, +- RALINK_PCI_CLASS); +- +- /* configure RC FTS number to 250 when it leaves L0s */ +- val = read_config(pcie, slot, PCIE_FTS_NUM); +- val &= ~PCIE_FTS_NUM_MASK; +- val |= PCIE_FTS_NUM_L0(0x50); +- write_config(pcie, slot, PCIE_FTS_NUM, val); +-} +- +-static int mt7621_pcie_enable_ports(struct pci_host_bridge *host) +-{ +- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); +- struct device *dev = pcie->dev; +- struct mt7621_pcie_port *port; +- struct resource_entry *entry; +- int err; +- +- entry = resource_list_first_type(&host->windows, IORESOURCE_IO); +- if (!entry) { +- dev_err(dev, "Cannot get io resource\n"); +- return -EINVAL; +- } +- +- /* Setup MEMWIN and IOWIN */ +- pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE); +- pcie_write(pcie, entry->res->start, RALINK_PCI_IOBASE); +- +- list_for_each_entry(port, &pcie->ports, list) { +- if (port->enabled) { +- err = clk_prepare_enable(port->clk); +- if (err) { +- dev_err(dev, "enabling clk pcie%d\n", +- port->slot); +- return err; +- } +- +- mt7621_pcie_enable_port(port); +- dev_info(dev, "PCIE%d enabled\n", port->slot); +- } +- } +- +- return 0; +-} +- +-static int mt7621_pcie_register_host(struct pci_host_bridge *host) +-{ +- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); +- +- host->ops = &mt7621_pcie_ops; +- host->sysdata = pcie; +- return pci_host_probe(host); +-} +- +-static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { +- { .soc_id = "mt7621", .revision = "E2" }, +- { /* sentinel */ } +-}; +- +-static int mt7621_pcie_probe(struct platform_device *pdev) +-{ +- struct device *dev = &pdev->dev; +- const struct soc_device_attribute *attr; +- struct mt7621_pcie_port *port; +- struct mt7621_pcie *pcie; +- struct pci_host_bridge *bridge; +- int err; +- +- if (!dev->of_node) +- return -ENODEV; +- +- bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); +- if (!bridge) +- return -ENOMEM; +- +- pcie = pci_host_bridge_priv(bridge); +- pcie->dev = dev; +- platform_set_drvdata(pdev, pcie); +- INIT_LIST_HEAD(&pcie->ports); +- +- attr = soc_device_match(mt7621_pcie_quirks_match); +- if (attr) +- pcie->resets_inverted = true; +- +- err = mt7621_pcie_parse_dt(pcie); +- if (err) { +- dev_err(dev, "Parsing DT failed\n"); +- return err; +- } +- +- err = mt7621_pcie_init_ports(pcie); +- if (err) { +- dev_err(dev, "Nothing connected in virtual bridges\n"); +- return 0; +- } +- +- err = mt7621_pcie_enable_ports(bridge); +- if (err) { +- dev_err(dev, "Error enabling pcie ports\n"); +- goto remove_resets; +- } +- +- err = setup_cm_memory_region(bridge); +- if (err) { +- dev_err(dev, "Error setting up iocu mem regions\n"); +- goto remove_resets; +- } +- +- return mt7621_pcie_register_host(bridge); +- +-remove_resets: +- list_for_each_entry(port, &pcie->ports, list) +- reset_control_put(port->pcie_rst); +- +- return err; +-} +- +-static int mt7621_pcie_remove(struct platform_device *pdev) +-{ +- struct mt7621_pcie *pcie = platform_get_drvdata(pdev); +- struct mt7621_pcie_port *port; +- +- list_for_each_entry(port, &pcie->ports, list) +- reset_control_put(port->pcie_rst); +- +- return 0; +-} +- +-static const struct of_device_id mt7621_pcie_ids[] = { +- { .compatible = "mediatek,mt7621-pci" }, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, mt7621_pcie_ids); +- +-static struct platform_driver mt7621_pcie_driver = { +- .probe = mt7621_pcie_probe, +- .remove = mt7621_pcie_remove, +- .driver = { +- .name = "mt7621-pci", +- .of_match_table = of_match_ptr(mt7621_pcie_ids), +- }, +-}; +-builtin_platform_driver(mt7621_pcie_driver); +--- /dev/null ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -0,0 +1,600 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * PCI init for Ralink RT2880 solution ++ * ++ * Copyright 2007 Ralink Inc. (bruce_chang@ralinktech.com.tw) ++ * ++ * May 2007 Bruce Chang ++ * Initial Release ++ * ++ * May 2009 Bruce Chang ++ * support RT2880/RT3883 PCIe ++ * ++ * May 2011 Bruce Chang ++ * support RT6855/MT7620 PCIe ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* MediaTek-specific configuration registers */ ++#define PCIE_FTS_NUM 0x70c ++#define PCIE_FTS_NUM_MASK GENMASK(15, 8) ++#define PCIE_FTS_NUM_L0(x) (((x) & 0xff) << 8) ++ ++/* Host-PCI bridge registers */ ++#define RALINK_PCI_PCICFG_ADDR 0x0000 ++#define RALINK_PCI_PCIMSK_ADDR 0x000c ++#define RALINK_PCI_CONFIG_ADDR 0x0020 ++#define RALINK_PCI_CONFIG_DATA 0x0024 ++#define RALINK_PCI_MEMBASE 0x0028 ++#define RALINK_PCI_IOBASE 0x002c ++ ++/* PCIe RC control registers */ ++#define RALINK_PCI_ID 0x0030 ++#define RALINK_PCI_CLASS 0x0034 ++#define RALINK_PCI_SUBID 0x0038 ++#define RALINK_PCI_STATUS 0x0050 ++ ++/* Some definition values */ ++#define PCIE_REVISION_ID BIT(0) ++#define PCIE_CLASS_CODE (0x60400 << 8) ++#define PCIE_BAR_MAP_MAX GENMASK(30, 16) ++#define PCIE_BAR_ENABLE BIT(0) ++#define PCIE_PORT_INT_EN(x) BIT(20 + (x)) ++#define PCIE_PORT_LINKUP BIT(0) ++#define PCIE_PORT_CNT 3 ++ ++#define PERST_DELAY_MS 100 ++ ++/** ++ * struct mt7621_pcie_port - PCIe port information ++ * @base: I/O mapped register base ++ * @list: port list ++ * @pcie: pointer to PCIe host info ++ * @clk: pointer to the port clock gate ++ * @phy: pointer to PHY control block ++ * @pcie_rst: pointer to port reset control ++ * @gpio_rst: gpio reset ++ * @slot: port slot ++ * @enabled: indicates if port is enabled ++ */ ++struct mt7621_pcie_port { ++ void __iomem *base; ++ struct list_head list; ++ struct mt7621_pcie *pcie; ++ struct clk *clk; ++ struct phy *phy; ++ struct reset_control *pcie_rst; ++ struct gpio_desc *gpio_rst; ++ u32 slot; ++ bool enabled; ++}; ++ ++/** ++ * struct mt7621_pcie - PCIe host information ++ * @base: IO Mapped Register Base ++ * @dev: Pointer to PCIe device ++ * @ports: pointer to PCIe port information ++ * @resets_inverted: depends on chip revision ++ * reset lines are inverted. ++ */ ++struct mt7621_pcie { ++ void __iomem *base; ++ struct device *dev; ++ struct list_head ports; ++ bool resets_inverted; ++}; ++ ++static inline u32 pcie_read(struct mt7621_pcie *pcie, u32 reg) ++{ ++ return readl_relaxed(pcie->base + reg); ++} ++ ++static inline void pcie_write(struct mt7621_pcie *pcie, u32 val, u32 reg) ++{ ++ writel_relaxed(val, pcie->base + reg); ++} ++ ++static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) ++{ ++ u32 val = readl_relaxed(pcie->base + reg); ++ ++ val &= ~clr; ++ val |= set; ++ writel_relaxed(val, pcie->base + reg); ++} ++ ++static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) ++{ ++ return readl_relaxed(port->base + reg); ++} ++ ++static inline void pcie_port_write(struct mt7621_pcie_port *port, ++ u32 val, u32 reg) ++{ ++ writel_relaxed(val, port->base + reg); ++} ++ ++static inline u32 mt7621_pci_get_cfgaddr(unsigned int bus, unsigned int slot, ++ unsigned int func, unsigned int where) ++{ ++ return (((where & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) | ++ (func << 8) | (where & 0xfc) | 0x80000000; ++} ++ ++static void __iomem *mt7621_pcie_map_bus(struct pci_bus *bus, ++ unsigned int devfn, int where) ++{ ++ struct mt7621_pcie *pcie = bus->sysdata; ++ u32 address = mt7621_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), ++ PCI_FUNC(devfn), where); ++ ++ writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); ++ ++ return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); ++} ++ ++struct pci_ops mt7621_pci_ops = { ++ .map_bus = mt7621_pcie_map_bus, ++ .read = pci_generic_config_read, ++ .write = pci_generic_config_write, ++}; ++ ++static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) ++{ ++ u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); ++ ++ pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); ++ return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); ++} ++ ++static void write_config(struct mt7621_pcie *pcie, unsigned int dev, ++ u32 reg, u32 val) ++{ ++ u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); ++ ++ pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); ++ pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); ++} ++ ++static inline void mt7621_rst_gpio_pcie_assert(struct mt7621_pcie_port *port) ++{ ++ if (port->gpio_rst) ++ gpiod_set_value(port->gpio_rst, 1); ++} ++ ++static inline void mt7621_rst_gpio_pcie_deassert(struct mt7621_pcie_port *port) ++{ ++ if (port->gpio_rst) ++ gpiod_set_value(port->gpio_rst, 0); ++} ++ ++static inline bool mt7621_pcie_port_is_linkup(struct mt7621_pcie_port *port) ++{ ++ return (pcie_port_read(port, RALINK_PCI_STATUS) & PCIE_PORT_LINKUP) != 0; ++} ++ ++static inline void mt7621_control_assert(struct mt7621_pcie_port *port) ++{ ++ struct mt7621_pcie *pcie = port->pcie; ++ ++ if (pcie->resets_inverted) ++ reset_control_assert(port->pcie_rst); ++ else ++ reset_control_deassert(port->pcie_rst); ++} ++ ++static inline void mt7621_control_deassert(struct mt7621_pcie_port *port) ++{ ++ struct mt7621_pcie *pcie = port->pcie; ++ ++ if (pcie->resets_inverted) ++ reset_control_deassert(port->pcie_rst); ++ else ++ reset_control_assert(port->pcie_rst); ++} ++ ++static int setup_cm_memory_region(struct pci_host_bridge *host) ++{ ++ struct mt7621_pcie *pcie = pci_host_bridge_priv(host); ++ struct device *dev = pcie->dev; ++ struct resource_entry *entry; ++ resource_size_t mask; ++ ++ entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); ++ if (!entry) { ++ dev_err(dev, "cannot get memory resource\n"); ++ return -EINVAL; ++ } ++ ++ if (mips_cps_numiocu(0)) { ++ /* ++ * FIXME: hardware doesn't accept mask values with 1s after ++ * 0s (e.g. 0xffef), so it would be great to warn if that's ++ * about to happen ++ */ ++ mask = ~(entry->res->end - entry->res->start); ++ ++ write_gcr_reg1_base(entry->res->start); ++ write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); ++ dev_info(dev, "PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", ++ (unsigned long long)read_gcr_reg1_base(), ++ (unsigned long long)read_gcr_reg1_mask()); ++ } ++ ++ return 0; ++} ++ ++static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, ++ struct device_node *node, ++ int slot) ++{ ++ struct mt7621_pcie_port *port; ++ struct device *dev = pcie->dev; ++ struct platform_device *pdev = to_platform_device(dev); ++ char name[10]; ++ int err; ++ ++ port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); ++ if (!port) ++ return -ENOMEM; ++ ++ port->base = devm_platform_ioremap_resource(pdev, slot + 1); ++ if (IS_ERR(port->base)) ++ return PTR_ERR(port->base); ++ ++ port->clk = devm_get_clk_from_child(dev, node, NULL); ++ if (IS_ERR(port->clk)) { ++ dev_err(dev, "failed to get pcie%d clock\n", slot); ++ return PTR_ERR(port->clk); ++ } ++ ++ port->pcie_rst = of_reset_control_get_exclusive(node, NULL); ++ if (PTR_ERR(port->pcie_rst) == -EPROBE_DEFER) { ++ dev_err(dev, "failed to get pcie%d reset control\n", slot); ++ return PTR_ERR(port->pcie_rst); ++ } ++ ++ snprintf(name, sizeof(name), "pcie-phy%d", slot); ++ port->phy = devm_of_phy_get(dev, node, name); ++ if (IS_ERR(port->phy)) { ++ dev_err(dev, "failed to get pcie-phy%d\n", slot); ++ err = PTR_ERR(port->phy); ++ goto remove_reset; ++ } ++ ++ port->gpio_rst = devm_gpiod_get_index_optional(dev, "reset", slot, ++ GPIOD_OUT_LOW); ++ if (IS_ERR(port->gpio_rst)) { ++ dev_err(dev, "failed to get GPIO for PCIe%d\n", slot); ++ err = PTR_ERR(port->gpio_rst); ++ goto remove_reset; ++ } ++ ++ port->slot = slot; ++ port->pcie = pcie; ++ ++ INIT_LIST_HEAD(&port->list); ++ list_add_tail(&port->list, &pcie->ports); ++ ++ return 0; ++ ++remove_reset: ++ reset_control_put(port->pcie_rst); ++ return err; ++} ++ ++static int mt7621_pcie_parse_dt(struct mt7621_pcie *pcie) ++{ ++ struct device *dev = pcie->dev; ++ struct platform_device *pdev = to_platform_device(dev); ++ struct device_node *node = dev->of_node, *child; ++ int err; ++ ++ pcie->base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(pcie->base)) ++ return PTR_ERR(pcie->base); ++ ++ for_each_available_child_of_node(node, child) { ++ int slot; ++ ++ err = of_pci_get_devfn(child); ++ if (err < 0) { ++ of_node_put(child); ++ dev_err(dev, "failed to parse devfn: %d\n", err); ++ return err; ++ } ++ ++ slot = PCI_SLOT(err); ++ ++ err = mt7621_pcie_parse_port(pcie, child, slot); ++ if (err) { ++ of_node_put(child); ++ return err; ++ } ++ } ++ ++ return 0; ++} ++ ++static int mt7621_pcie_init_port(struct mt7621_pcie_port *port) ++{ ++ struct mt7621_pcie *pcie = port->pcie; ++ struct device *dev = pcie->dev; ++ u32 slot = port->slot; ++ int err; ++ ++ err = phy_init(port->phy); ++ if (err) { ++ dev_err(dev, "failed to initialize port%d phy\n", slot); ++ return err; ++ } ++ ++ err = phy_power_on(port->phy); ++ if (err) { ++ dev_err(dev, "failed to power on port%d phy\n", slot); ++ phy_exit(port->phy); ++ return err; ++ } ++ ++ port->enabled = true; ++ ++ return 0; ++} ++ ++static void mt7621_pcie_reset_assert(struct mt7621_pcie *pcie) ++{ ++ struct mt7621_pcie_port *port; ++ ++ list_for_each_entry(port, &pcie->ports, list) { ++ /* PCIe RC reset assert */ ++ mt7621_control_assert(port); ++ ++ /* PCIe EP reset assert */ ++ mt7621_rst_gpio_pcie_assert(port); ++ } ++ ++ msleep(PERST_DELAY_MS); ++} ++ ++static void mt7621_pcie_reset_rc_deassert(struct mt7621_pcie *pcie) ++{ ++ struct mt7621_pcie_port *port; ++ ++ list_for_each_entry(port, &pcie->ports, list) ++ mt7621_control_deassert(port); ++} ++ ++static void mt7621_pcie_reset_ep_deassert(struct mt7621_pcie *pcie) ++{ ++ struct mt7621_pcie_port *port; ++ ++ list_for_each_entry(port, &pcie->ports, list) ++ mt7621_rst_gpio_pcie_deassert(port); ++ ++ msleep(PERST_DELAY_MS); ++} ++ ++static int mt7621_pcie_init_ports(struct mt7621_pcie *pcie) ++{ ++ struct device *dev = pcie->dev; ++ struct mt7621_pcie_port *port, *tmp; ++ u8 num_disabled = 0; ++ int err; ++ ++ mt7621_pcie_reset_assert(pcie); ++ mt7621_pcie_reset_rc_deassert(pcie); ++ ++ list_for_each_entry_safe(port, tmp, &pcie->ports, list) { ++ u32 slot = port->slot; ++ ++ if (slot == 1) { ++ port->enabled = true; ++ continue; ++ } ++ ++ err = mt7621_pcie_init_port(port); ++ if (err) { ++ dev_err(dev, "initializing port %d failed\n", slot); ++ list_del(&port->list); ++ } ++ } ++ ++ mt7621_pcie_reset_ep_deassert(pcie); ++ ++ tmp = NULL; ++ list_for_each_entry(port, &pcie->ports, list) { ++ u32 slot = port->slot; ++ ++ if (!mt7621_pcie_port_is_linkup(port)) { ++ dev_err(dev, "pcie%d no card, disable it (RST & CLK)\n", ++ slot); ++ mt7621_control_assert(port); ++ port->enabled = false; ++ num_disabled++; ++ ++ if (slot == 0) { ++ tmp = port; ++ continue; ++ } ++ ++ if (slot == 1 && tmp && !tmp->enabled) ++ phy_power_off(tmp->phy); ++ } ++ } ++ ++ return (num_disabled != PCIE_PORT_CNT) ? 0 : -ENODEV; ++} ++ ++static void mt7621_pcie_enable_port(struct mt7621_pcie_port *port) ++{ ++ struct mt7621_pcie *pcie = port->pcie; ++ u32 slot = port->slot; ++ u32 val; ++ ++ /* enable pcie interrupt */ ++ val = pcie_read(pcie, RALINK_PCI_PCIMSK_ADDR); ++ val |= PCIE_PORT_INT_EN(slot); ++ pcie_write(pcie, val, RALINK_PCI_PCIMSK_ADDR); ++ ++ /* map 2G DDR region */ ++ pcie_port_write(port, PCIE_BAR_MAP_MAX | PCIE_BAR_ENABLE, ++ PCI_BASE_ADDRESS_0); ++ ++ /* configure class code and revision ID */ ++ pcie_port_write(port, PCIE_CLASS_CODE | PCIE_REVISION_ID, ++ RALINK_PCI_CLASS); ++ ++ /* configure RC FTS number to 250 when it leaves L0s */ ++ val = read_config(pcie, slot, PCIE_FTS_NUM); ++ val &= ~PCIE_FTS_NUM_MASK; ++ val |= PCIE_FTS_NUM_L0(0x50); ++ write_config(pcie, slot, PCIE_FTS_NUM, val); ++} ++ ++static int mt7621_pcie_enable_ports(struct pci_host_bridge *host) ++{ ++ struct mt7621_pcie *pcie = pci_host_bridge_priv(host); ++ struct device *dev = pcie->dev; ++ struct mt7621_pcie_port *port; ++ struct resource_entry *entry; ++ int err; ++ ++ entry = resource_list_first_type(&host->windows, IORESOURCE_IO); ++ if (!entry) { ++ dev_err(dev, "cannot get io resource\n"); ++ return -EINVAL; ++ } ++ ++ /* Setup MEMWIN and IOWIN */ ++ pcie_write(pcie, 0xffffffff, RALINK_PCI_MEMBASE); ++ pcie_write(pcie, entry->res->start, RALINK_PCI_IOBASE); ++ ++ list_for_each_entry(port, &pcie->ports, list) { ++ if (port->enabled) { ++ err = clk_prepare_enable(port->clk); ++ if (err) { ++ dev_err(dev, "enabling clk pcie%d\n", ++ port->slot); ++ return err; ++ } ++ ++ mt7621_pcie_enable_port(port); ++ dev_info(dev, "PCIE%d enabled\n", port->slot); ++ } ++ } ++ ++ return 0; ++} ++ ++static int mt7621_pcie_register_host(struct pci_host_bridge *host) ++{ ++ struct mt7621_pcie *pcie = pci_host_bridge_priv(host); ++ ++ host->ops = &mt7621_pci_ops; ++ host->sysdata = pcie; ++ return pci_host_probe(host); ++} ++ ++static const struct soc_device_attribute mt7621_pci_quirks_match[] = { ++ { .soc_id = "mt7621", .revision = "E2" } ++}; ++ ++static int mt7621_pci_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ const struct soc_device_attribute *attr; ++ struct mt7621_pcie_port *port; ++ struct mt7621_pcie *pcie; ++ struct pci_host_bridge *bridge; ++ int err; ++ ++ if (!dev->of_node) ++ return -ENODEV; ++ ++ bridge = devm_pci_alloc_host_bridge(dev, sizeof(*pcie)); ++ if (!bridge) ++ return -ENOMEM; ++ ++ pcie = pci_host_bridge_priv(bridge); ++ pcie->dev = dev; ++ platform_set_drvdata(pdev, pcie); ++ INIT_LIST_HEAD(&pcie->ports); ++ ++ attr = soc_device_match(mt7621_pci_quirks_match); ++ if (attr) ++ pcie->resets_inverted = true; ++ ++ err = mt7621_pcie_parse_dt(pcie); ++ if (err) { ++ dev_err(dev, "parsing DT failed\n"); ++ return err; ++ } ++ ++ err = mt7621_pcie_init_ports(pcie); ++ if (err) { ++ dev_err(dev, "nothing connected in virtual bridges\n"); ++ return 0; ++ } ++ ++ err = mt7621_pcie_enable_ports(bridge); ++ if (err) { ++ dev_err(dev, "error enabling pcie ports\n"); ++ goto remove_resets; ++ } ++ ++ err = setup_cm_memory_region(bridge); ++ if (err) { ++ dev_err(dev, "error setting up iocu mem regions\n"); ++ goto remove_resets; ++ } ++ ++ return mt7621_pcie_register_host(bridge); ++ ++remove_resets: ++ list_for_each_entry(port, &pcie->ports, list) ++ reset_control_put(port->pcie_rst); ++ ++ return err; ++} ++ ++static int mt7621_pci_remove(struct platform_device *pdev) ++{ ++ struct mt7621_pcie *pcie = platform_get_drvdata(pdev); ++ struct mt7621_pcie_port *port; ++ ++ list_for_each_entry(port, &pcie->ports, list) ++ reset_control_put(port->pcie_rst); ++ ++ return 0; ++} ++ ++static const struct of_device_id mt7621_pci_ids[] = { ++ { .compatible = "mediatek,mt7621-pci" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, mt7621_pci_ids); ++ ++static struct platform_driver mt7621_pci_driver = { ++ .probe = mt7621_pci_probe, ++ .remove = mt7621_pci_remove, ++ .driver = { ++ .name = "mt7621-pci", ++ .of_match_table = of_match_ptr(mt7621_pci_ids), ++ }, ++}; ++builtin_platform_driver(mt7621_pci_driver); diff --git a/target/linux/ramips/patches-5.15/101-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch b/target/linux/ramips/patches-5.15/101-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch deleted file mode 100644 index 916477511d..0000000000 --- a/target/linux/ramips/patches-5.15/101-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch +++ /dev/null @@ -1,134 +0,0 @@ -From: Bjorn Helgaas -Date: Wed, 22 Dec 2021 19:10:48 -0600 -Subject: [PATCH] PCI: mt7621: Rename mt7621_pci_ to mt7621_pcie_ - -Rename mt7621_pci_* structs and functions to mt7621_pcie_* for consistency -with the rest of the file. - -Link: https://lore.kernel.org/r/20211223011054.1227810-18-helgaas@kernel.org -Signed-off-by: Bjorn Helgaas -Reviewed-by: Sergio Paracuellos -Cc: Matthias Brugger ---- - ---- a/drivers/pci/controller/pcie-mt7621.c -+++ b/drivers/pci/controller/pcie-mt7621.c -@@ -93,8 +93,8 @@ struct mt7621_pcie_port { - * reset lines are inverted. - */ - struct mt7621_pcie { -- void __iomem *base; - struct device *dev; -+ void __iomem *base; - struct list_head ports; - bool resets_inverted; - }; -@@ -129,7 +129,7 @@ static inline void pcie_port_write(struc - writel_relaxed(val, port->base + reg); - } - --static inline u32 mt7621_pci_get_cfgaddr(unsigned int bus, unsigned int slot, -+static inline u32 mt7621_pcie_get_cfgaddr(unsigned int bus, unsigned int slot, - unsigned int func, unsigned int where) - { - return (((where & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) | -@@ -140,7 +140,7 @@ static void __iomem *mt7621_pcie_map_bus - unsigned int devfn, int where) - { - struct mt7621_pcie *pcie = bus->sysdata; -- u32 address = mt7621_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), -+ u32 address = mt7621_pcie_get_cfgaddr(bus->number, PCI_SLOT(devfn), - PCI_FUNC(devfn), where); - - writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); -@@ -148,7 +148,7 @@ static void __iomem *mt7621_pcie_map_bus - return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); - } - --struct pci_ops mt7621_pci_ops = { -+struct pci_ops mt7621_pcie_ops = { - .map_bus = mt7621_pcie_map_bus, - .read = pci_generic_config_read, - .write = pci_generic_config_write, -@@ -156,7 +156,7 @@ struct pci_ops mt7621_pci_ops = { - - static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) - { -- u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); -+ u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); - - pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); - return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); -@@ -165,7 +165,7 @@ static u32 read_config(struct mt7621_pci - static void write_config(struct mt7621_pcie *pcie, unsigned int dev, - u32 reg, u32 val) - { -- u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); -+ u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); - - pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); - pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); -@@ -505,16 +505,16 @@ static int mt7621_pcie_register_host(str - { - struct mt7621_pcie *pcie = pci_host_bridge_priv(host); - -- host->ops = &mt7621_pci_ops; -+ host->ops = &mt7621_pcie_ops; - host->sysdata = pcie; - return pci_host_probe(host); - } - --static const struct soc_device_attribute mt7621_pci_quirks_match[] = { -+static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { - { .soc_id = "mt7621", .revision = "E2" } - }; - --static int mt7621_pci_probe(struct platform_device *pdev) -+static int mt7621_pcie_probe(struct platform_device *pdev) - { - struct device *dev = &pdev->dev; - const struct soc_device_attribute *attr; -@@ -535,7 +535,7 @@ static int mt7621_pci_probe(struct platf - platform_set_drvdata(pdev, pcie); - INIT_LIST_HEAD(&pcie->ports); - -- attr = soc_device_match(mt7621_pci_quirks_match); -+ attr = soc_device_match(mt7621_pcie_quirks_match); - if (attr) - pcie->resets_inverted = true; - -@@ -572,7 +572,7 @@ remove_resets: - return err; - } - --static int mt7621_pci_remove(struct platform_device *pdev) -+static int mt7621_pcie_remove(struct platform_device *pdev) - { - struct mt7621_pcie *pcie = platform_get_drvdata(pdev); - struct mt7621_pcie_port *port; -@@ -583,18 +583,18 @@ static int mt7621_pci_remove(struct plat - return 0; - } - --static const struct of_device_id mt7621_pci_ids[] = { -+static const struct of_device_id mt7621_pcie_ids[] = { - { .compatible = "mediatek,mt7621-pci" }, - {}, - }; --MODULE_DEVICE_TABLE(of, mt7621_pci_ids); -+MODULE_DEVICE_TABLE(of, mt7621_pcie_ids); - --static struct platform_driver mt7621_pci_driver = { -- .probe = mt7621_pci_probe, -- .remove = mt7621_pci_remove, -+static struct platform_driver mt7621_pcie_driver = { -+ .probe = mt7621_pcie_probe, -+ .remove = mt7621_pcie_remove, - .driver = { - .name = "mt7621-pci", -- .of_match_table = of_match_ptr(mt7621_pci_ids), -+ .of_match_table = of_match_ptr(mt7621_pcie_ids), - }, - }; --builtin_platform_driver(mt7621_pci_driver); -+builtin_platform_driver(mt7621_pcie_driver); diff --git a/target/linux/ramips/patches-5.15/101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch b/target/linux/ramips/patches-5.15/101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch new file mode 100644 index 0000000000..916477511d --- /dev/null +++ b/target/linux/ramips/patches-5.15/101-v5.17-PCI-mt7621-Rename-mt7621_pci_-to-mt7621_pcie_.patch @@ -0,0 +1,134 @@ +From: Bjorn Helgaas +Date: Wed, 22 Dec 2021 19:10:48 -0600 +Subject: [PATCH] PCI: mt7621: Rename mt7621_pci_ to mt7621_pcie_ + +Rename mt7621_pci_* structs and functions to mt7621_pcie_* for consistency +with the rest of the file. + +Link: https://lore.kernel.org/r/20211223011054.1227810-18-helgaas@kernel.org +Signed-off-by: Bjorn Helgaas +Reviewed-by: Sergio Paracuellos +Cc: Matthias Brugger +--- + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -93,8 +93,8 @@ struct mt7621_pcie_port { + * reset lines are inverted. + */ + struct mt7621_pcie { +- void __iomem *base; + struct device *dev; ++ void __iomem *base; + struct list_head ports; + bool resets_inverted; + }; +@@ -129,7 +129,7 @@ static inline void pcie_port_write(struc + writel_relaxed(val, port->base + reg); + } + +-static inline u32 mt7621_pci_get_cfgaddr(unsigned int bus, unsigned int slot, ++static inline u32 mt7621_pcie_get_cfgaddr(unsigned int bus, unsigned int slot, + unsigned int func, unsigned int where) + { + return (((where & 0xf00) >> 8) << 24) | (bus << 16) | (slot << 11) | +@@ -140,7 +140,7 @@ static void __iomem *mt7621_pcie_map_bus + unsigned int devfn, int where) + { + struct mt7621_pcie *pcie = bus->sysdata; +- u32 address = mt7621_pci_get_cfgaddr(bus->number, PCI_SLOT(devfn), ++ u32 address = mt7621_pcie_get_cfgaddr(bus->number, PCI_SLOT(devfn), + PCI_FUNC(devfn), where); + + writel_relaxed(address, pcie->base + RALINK_PCI_CONFIG_ADDR); +@@ -148,7 +148,7 @@ static void __iomem *mt7621_pcie_map_bus + return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); + } + +-struct pci_ops mt7621_pci_ops = { ++struct pci_ops mt7621_pcie_ops = { + .map_bus = mt7621_pcie_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, +@@ -156,7 +156,7 @@ struct pci_ops mt7621_pci_ops = { + + static u32 read_config(struct mt7621_pcie *pcie, unsigned int dev, u32 reg) + { +- u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); ++ u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); + + pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); + return pcie_read(pcie, RALINK_PCI_CONFIG_DATA); +@@ -165,7 +165,7 @@ static u32 read_config(struct mt7621_pci + static void write_config(struct mt7621_pcie *pcie, unsigned int dev, + u32 reg, u32 val) + { +- u32 address = mt7621_pci_get_cfgaddr(0, dev, 0, reg); ++ u32 address = mt7621_pcie_get_cfgaddr(0, dev, 0, reg); + + pcie_write(pcie, address, RALINK_PCI_CONFIG_ADDR); + pcie_write(pcie, val, RALINK_PCI_CONFIG_DATA); +@@ -505,16 +505,16 @@ static int mt7621_pcie_register_host(str + { + struct mt7621_pcie *pcie = pci_host_bridge_priv(host); + +- host->ops = &mt7621_pci_ops; ++ host->ops = &mt7621_pcie_ops; + host->sysdata = pcie; + return pci_host_probe(host); + } + +-static const struct soc_device_attribute mt7621_pci_quirks_match[] = { ++static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { + { .soc_id = "mt7621", .revision = "E2" } + }; + +-static int mt7621_pci_probe(struct platform_device *pdev) ++static int mt7621_pcie_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; + const struct soc_device_attribute *attr; +@@ -535,7 +535,7 @@ static int mt7621_pci_probe(struct platf + platform_set_drvdata(pdev, pcie); + INIT_LIST_HEAD(&pcie->ports); + +- attr = soc_device_match(mt7621_pci_quirks_match); ++ attr = soc_device_match(mt7621_pcie_quirks_match); + if (attr) + pcie->resets_inverted = true; + +@@ -572,7 +572,7 @@ remove_resets: + return err; + } + +-static int mt7621_pci_remove(struct platform_device *pdev) ++static int mt7621_pcie_remove(struct platform_device *pdev) + { + struct mt7621_pcie *pcie = platform_get_drvdata(pdev); + struct mt7621_pcie_port *port; +@@ -583,18 +583,18 @@ static int mt7621_pci_remove(struct plat + return 0; + } + +-static const struct of_device_id mt7621_pci_ids[] = { ++static const struct of_device_id mt7621_pcie_ids[] = { + { .compatible = "mediatek,mt7621-pci" }, + {}, + }; +-MODULE_DEVICE_TABLE(of, mt7621_pci_ids); ++MODULE_DEVICE_TABLE(of, mt7621_pcie_ids); + +-static struct platform_driver mt7621_pci_driver = { +- .probe = mt7621_pci_probe, +- .remove = mt7621_pci_remove, ++static struct platform_driver mt7621_pcie_driver = { ++ .probe = mt7621_pcie_probe, ++ .remove = mt7621_pcie_remove, + .driver = { + .name = "mt7621-pci", +- .of_match_table = of_match_ptr(mt7621_pci_ids), ++ .of_match_table = of_match_ptr(mt7621_pcie_ids), + }, + }; +-builtin_platform_driver(mt7621_pci_driver); ++builtin_platform_driver(mt7621_pcie_driver); diff --git a/target/linux/ramips/patches-5.15/102-PCI-mt7621-Declare-mt7621_pci_ops-static.patch b/target/linux/ramips/patches-5.15/102-PCI-mt7621-Declare-mt7621_pci_ops-static.patch deleted file mode 100644 index 815ecc7d37..0000000000 --- a/target/linux/ramips/patches-5.15/102-PCI-mt7621-Declare-mt7621_pci_ops-static.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Sergio Paracuellos -Date: Wed, 17 Nov 2021 16:29:52 +0100 -Subject: [PATCH] PCI: mt7621: Declare mt7621_pci_ops static -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Sparse complains about mt7621_pci_ops symbol is not declared and asks if -it should be declared as static instead. Sparse is right. Hence declare -symbol as static. - -Link: https://lore.kernel.org/r/20211117152952.12271-1-sergio.paracuellos@gmail.com -Reported-by: kernel test robot -Signed-off-by: Sergio Paracuellos -Signed-off-by: Lorenzo Pieralisi -Signed-off-by: Bjorn Helgaas -Reviewed-by: Krzysztof Wilczyński ---- - ---- a/drivers/pci/controller/pcie-mt7621.c -+++ b/drivers/pci/controller/pcie-mt7621.c -@@ -148,7 +148,7 @@ static void __iomem *mt7621_pcie_map_bus - return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); - } - --struct pci_ops mt7621_pcie_ops = { -+static struct pci_ops mt7621_pcie_ops = { - .map_bus = mt7621_pcie_map_bus, - .read = pci_generic_config_read, - .write = pci_generic_config_write, diff --git a/target/linux/ramips/patches-5.15/102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch b/target/linux/ramips/patches-5.15/102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch new file mode 100644 index 0000000000..815ecc7d37 --- /dev/null +++ b/target/linux/ramips/patches-5.15/102-v5.17-PCI-mt7621-Declare-mt7621_pci_ops-static.patch @@ -0,0 +1,30 @@ +From: Sergio Paracuellos +Date: Wed, 17 Nov 2021 16:29:52 +0100 +Subject: [PATCH] PCI: mt7621: Declare mt7621_pci_ops static +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Sparse complains about mt7621_pci_ops symbol is not declared and asks if +it should be declared as static instead. Sparse is right. Hence declare +symbol as static. + +Link: https://lore.kernel.org/r/20211117152952.12271-1-sergio.paracuellos@gmail.com +Reported-by: kernel test robot +Signed-off-by: Sergio Paracuellos +Signed-off-by: Lorenzo Pieralisi +Signed-off-by: Bjorn Helgaas +Reviewed-by: Krzysztof Wilczyński +--- + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -148,7 +148,7 @@ static void __iomem *mt7621_pcie_map_bus + return pcie->base + RALINK_PCI_CONFIG_DATA + (where & 3); + } + +-struct pci_ops mt7621_pcie_ops = { ++static struct pci_ops mt7621_pcie_ops = { + .map_bus = mt7621_pcie_map_bus, + .read = pci_generic_config_read, + .write = pci_generic_config_write, diff --git a/target/linux/ramips/patches-5.15/103-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch b/target/linux/ramips/patches-5.15/103-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch deleted file mode 100644 index 4b46b3e3f6..0000000000 --- a/target/linux/ramips/patches-5.15/103-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch +++ /dev/null @@ -1,119 +0,0 @@ -From: Sergio Paracuellos -Date: Tue, 7 Dec 2021 11:49:21 +0100 -Subject: [PATCH] PCI: mt7621: Move MIPS setup to pcibios_root_bridge_prepare() - -On the MIPS ralink mt7621 platform, we need to set up I/O coherency units -based on the host bridge apertures. - -To remove this arch dependency from the driver itself, move the coherency -setup from the driver to pcibios_root_bridge_prepare(). - -[bhelgaas: squash add/remove into one patch, commit log] -Link: https://lore.kernel.org/r/20211207104924.21327-3-sergio.paracuellos@gmail.com -Link: https://lore.kernel.org/r/20211207104924.21327-4-sergio.paracuellos@gmail.com -Signed-off-by: Sergio Paracuellos -Signed-off-by: Bjorn Helgaas -Reviewed-by: Guenter Roeck # arch/mips -Acked-by: Thomas Bogendoerfer # arch/mips ---- - ---- a/arch/mips/ralink/mt7621.c -+++ b/arch/mips/ralink/mt7621.c -@@ -10,6 +10,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -25,6 +27,35 @@ - static u32 detect_magic __initdata; - static struct ralink_soc_info *soc_info_ptr; - -+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) -+{ -+ struct resource_entry *entry; -+ resource_size_t mask; -+ -+ entry = resource_list_first_type(&bridge->windows, IORESOURCE_MEM); -+ if (!entry) { -+ pr_err("Cannot get memory resource\n"); -+ return -EINVAL; -+ } -+ -+ if (mips_cps_numiocu(0)) { -+ /* -+ * Hardware doesn't accept mask values with 1s after -+ * 0s (e.g. 0xffef), so warn if that's happen -+ */ -+ mask = ~(entry->res->end - entry->res->start) & CM_GCR_REGn_MASK_ADDRMASK; -+ WARN_ON(mask && BIT(ffz(~mask)) - 1 != ~mask); -+ -+ write_gcr_reg1_base(entry->res->start); -+ write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); -+ pr_info("PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", -+ (unsigned long long)read_gcr_reg1_base(), -+ (unsigned long long)read_gcr_reg1_mask()); -+ } -+ -+ return 0; -+} -+ - phys_addr_t mips_cpc_default_phys_base(void) - { - panic("Cannot detect cpc address"); ---- a/drivers/pci/controller/pcie-mt7621.c -+++ b/drivers/pci/controller/pcie-mt7621.c -@@ -208,37 +208,6 @@ static inline void mt7621_control_deasse - reset_control_assert(port->pcie_rst); - } - --static int setup_cm_memory_region(struct pci_host_bridge *host) --{ -- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); -- struct device *dev = pcie->dev; -- struct resource_entry *entry; -- resource_size_t mask; -- -- entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); -- if (!entry) { -- dev_err(dev, "cannot get memory resource\n"); -- return -EINVAL; -- } -- -- if (mips_cps_numiocu(0)) { -- /* -- * FIXME: hardware doesn't accept mask values with 1s after -- * 0s (e.g. 0xffef), so it would be great to warn if that's -- * about to happen -- */ -- mask = ~(entry->res->end - entry->res->start); -- -- write_gcr_reg1_base(entry->res->start); -- write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); -- dev_info(dev, "PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", -- (unsigned long long)read_gcr_reg1_base(), -- (unsigned long long)read_gcr_reg1_mask()); -- } -- -- return 0; --} -- - static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, - struct device_node *node, - int slot) -@@ -557,12 +526,6 @@ static int mt7621_pcie_probe(struct plat - goto remove_resets; - } - -- err = setup_cm_memory_region(bridge); -- if (err) { -- dev_err(dev, "error setting up iocu mem regions\n"); -- goto remove_resets; -- } -- - return mt7621_pcie_register_host(bridge); - - remove_resets: diff --git a/target/linux/ramips/patches-5.15/103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch b/target/linux/ramips/patches-5.15/103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch new file mode 100644 index 0000000000..4b46b3e3f6 --- /dev/null +++ b/target/linux/ramips/patches-5.15/103-v5.17-PCI-mt7621-Move-MIPS-setup-to-pcibios_root_bridge_pr.patch @@ -0,0 +1,119 @@ +From: Sergio Paracuellos +Date: Tue, 7 Dec 2021 11:49:21 +0100 +Subject: [PATCH] PCI: mt7621: Move MIPS setup to pcibios_root_bridge_prepare() + +On the MIPS ralink mt7621 platform, we need to set up I/O coherency units +based on the host bridge apertures. + +To remove this arch dependency from the driver itself, move the coherency +setup from the driver to pcibios_root_bridge_prepare(). + +[bhelgaas: squash add/remove into one patch, commit log] +Link: https://lore.kernel.org/r/20211207104924.21327-3-sergio.paracuellos@gmail.com +Link: https://lore.kernel.org/r/20211207104924.21327-4-sergio.paracuellos@gmail.com +Signed-off-by: Sergio Paracuellos +Signed-off-by: Bjorn Helgaas +Reviewed-by: Guenter Roeck # arch/mips +Acked-by: Thomas Bogendoerfer # arch/mips +--- + +--- a/arch/mips/ralink/mt7621.c ++++ b/arch/mips/ralink/mt7621.c +@@ -10,6 +10,8 @@ + #include + #include + #include ++#include ++#include + + #include + #include +@@ -25,6 +27,35 @@ + static u32 detect_magic __initdata; + static struct ralink_soc_info *soc_info_ptr; + ++int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) ++{ ++ struct resource_entry *entry; ++ resource_size_t mask; ++ ++ entry = resource_list_first_type(&bridge->windows, IORESOURCE_MEM); ++ if (!entry) { ++ pr_err("Cannot get memory resource\n"); ++ return -EINVAL; ++ } ++ ++ if (mips_cps_numiocu(0)) { ++ /* ++ * Hardware doesn't accept mask values with 1s after ++ * 0s (e.g. 0xffef), so warn if that's happen ++ */ ++ mask = ~(entry->res->end - entry->res->start) & CM_GCR_REGn_MASK_ADDRMASK; ++ WARN_ON(mask && BIT(ffz(~mask)) - 1 != ~mask); ++ ++ write_gcr_reg1_base(entry->res->start); ++ write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); ++ pr_info("PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", ++ (unsigned long long)read_gcr_reg1_base(), ++ (unsigned long long)read_gcr_reg1_mask()); ++ } ++ ++ return 0; ++} ++ + phys_addr_t mips_cpc_default_phys_base(void) + { + panic("Cannot detect cpc address"); +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -208,37 +208,6 @@ static inline void mt7621_control_deasse + reset_control_assert(port->pcie_rst); + } + +-static int setup_cm_memory_region(struct pci_host_bridge *host) +-{ +- struct mt7621_pcie *pcie = pci_host_bridge_priv(host); +- struct device *dev = pcie->dev; +- struct resource_entry *entry; +- resource_size_t mask; +- +- entry = resource_list_first_type(&host->windows, IORESOURCE_MEM); +- if (!entry) { +- dev_err(dev, "cannot get memory resource\n"); +- return -EINVAL; +- } +- +- if (mips_cps_numiocu(0)) { +- /* +- * FIXME: hardware doesn't accept mask values with 1s after +- * 0s (e.g. 0xffef), so it would be great to warn if that's +- * about to happen +- */ +- mask = ~(entry->res->end - entry->res->start); +- +- write_gcr_reg1_base(entry->res->start); +- write_gcr_reg1_mask(mask | CM_GCR_REGn_MASK_CMTGT_IOCU0); +- dev_info(dev, "PCI coherence region base: 0x%08llx, mask/settings: 0x%08llx\n", +- (unsigned long long)read_gcr_reg1_base(), +- (unsigned long long)read_gcr_reg1_mask()); +- } +- +- return 0; +-} +- + static int mt7621_pcie_parse_port(struct mt7621_pcie *pcie, + struct device_node *node, + int slot) +@@ -557,12 +526,6 @@ static int mt7621_pcie_probe(struct plat + goto remove_resets; + } + +- err = setup_cm_memory_region(bridge); +- if (err) { +- dev_err(dev, "error setting up iocu mem regions\n"); +- goto remove_resets; +- } +- + return mt7621_pcie_register_host(bridge); + + remove_resets: diff --git a/target/linux/ramips/patches-5.15/104-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch b/target/linux/ramips/patches-5.15/104-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch deleted file mode 100644 index 0913a452c6..0000000000 --- a/target/linux/ramips/patches-5.15/104-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Sergio Paracuellos -Date: Mon, 24 Jan 2022 12:30:02 +0100 -Subject: [PATCH] PCI: mt7621: Drop of_match_ptr() to avoid unused variable - -We have stubs for most OF interfaces even when CONFIG_OF is not set, so we -allow building of pcie-mt7621.c in that case for compile testing. - -When CONFIG_OF is not set, "of_match_ptr(mt7621_pcie_ids)" compiles to -NULL, which leaves mt7621_pcie_ids unused: - - $ make W=1 - drivers/pci/controller/pcie-mt7621.c:549:34: warning: unused variable 'mt7621_pcie_ids' [-Wunused-const-variable] - -Drop of_match_ptr() to avoid the unused variable warning. - -[bhelgaas: commit log] -Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver") -Link: https://lore.kernel.org/r/20220124113003.406224-2-sergio.paracuellos@gmail.com -Link: https://lore.kernel.org/r/202201241754.igtHzgHv-lkp@intel.com -Reported-by: kernel test robot -Signed-off-by: Sergio Paracuellos -Signed-off-by: Bjorn Helgaas ---- - ---- a/drivers/pci/controller/pcie-mt7621.c -+++ b/drivers/pci/controller/pcie-mt7621.c -@@ -557,7 +557,7 @@ static struct platform_driver mt7621_pci - .remove = mt7621_pcie_remove, - .driver = { - .name = "mt7621-pci", -- .of_match_table = of_match_ptr(mt7621_pcie_ids), -+ .of_match_table = mt7621_pcie_ids, - }, - }; - builtin_platform_driver(mt7621_pcie_driver); diff --git a/target/linux/ramips/patches-5.15/104-v5.17-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch b/target/linux/ramips/patches-5.15/104-v5.17-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch new file mode 100644 index 0000000000..0913a452c6 --- /dev/null +++ b/target/linux/ramips/patches-5.15/104-v5.17-PCI-mt7621-Drop-of_match_ptr-to-avoid-unused-variabl.patch @@ -0,0 +1,35 @@ +From: Sergio Paracuellos +Date: Mon, 24 Jan 2022 12:30:02 +0100 +Subject: [PATCH] PCI: mt7621: Drop of_match_ptr() to avoid unused variable + +We have stubs for most OF interfaces even when CONFIG_OF is not set, so we +allow building of pcie-mt7621.c in that case for compile testing. + +When CONFIG_OF is not set, "of_match_ptr(mt7621_pcie_ids)" compiles to +NULL, which leaves mt7621_pcie_ids unused: + + $ make W=1 + drivers/pci/controller/pcie-mt7621.c:549:34: warning: unused variable 'mt7621_pcie_ids' [-Wunused-const-variable] + +Drop of_match_ptr() to avoid the unused variable warning. + +[bhelgaas: commit log] +Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver") +Link: https://lore.kernel.org/r/20220124113003.406224-2-sergio.paracuellos@gmail.com +Link: https://lore.kernel.org/r/202201241754.igtHzgHv-lkp@intel.com +Reported-by: kernel test robot +Signed-off-by: Sergio Paracuellos +Signed-off-by: Bjorn Helgaas +--- + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -557,7 +557,7 @@ static struct platform_driver mt7621_pci + .remove = mt7621_pcie_remove, + .driver = { + .name = "mt7621-pci", +- .of_match_table = of_match_ptr(mt7621_pcie_ids), ++ .of_match_table = mt7621_pcie_ids, + }, + }; + builtin_platform_driver(mt7621_pcie_driver); diff --git a/target/linux/ramips/patches-5.15/105-PCI-mt7621-Remove-unused-function-pcie_rmw.patch b/target/linux/ramips/patches-5.15/105-PCI-mt7621-Remove-unused-function-pcie_rmw.patch deleted file mode 100644 index 0323588e5a..0000000000 --- a/target/linux/ramips/patches-5.15/105-PCI-mt7621-Remove-unused-function-pcie_rmw.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Sergio Paracuellos -Date: Mon, 24 Jan 2022 12:30:03 +0100 -Subject: [PATCH] PCI: mt7621: Remove unused function pcie_rmw() - -Function pcie_rmw() is not being used at all and can be deleted. Hence get -rid of it, which fixes this warning: - - drivers/pci/controller/pcie-mt7621.c:112:20: warning: unused function 'pcie_rmw' [-Wunused-function] - -Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver") -Link: https://lore.kernel.org/r/20220124113003.406224-3-sergio.paracuellos@gmail.com -Link: https://lore.kernel.org/all/202201241754.igtHzgHv-lkp@intel.com/ -Reported-by: kernel test robot -Signed-off-by: Sergio Paracuellos -Signed-off-by: Bjorn Helgaas ---- - ---- a/drivers/pci/controller/pcie-mt7621.c -+++ b/drivers/pci/controller/pcie-mt7621.c -@@ -109,15 +109,6 @@ static inline void pcie_write(struct mt7 - writel_relaxed(val, pcie->base + reg); - } - --static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) --{ -- u32 val = readl_relaxed(pcie->base + reg); -- -- val &= ~clr; -- val |= set; -- writel_relaxed(val, pcie->base + reg); --} -- - static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) - { - return readl_relaxed(port->base + reg); diff --git a/target/linux/ramips/patches-5.15/105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch b/target/linux/ramips/patches-5.15/105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch new file mode 100644 index 0000000000..0323588e5a --- /dev/null +++ b/target/linux/ramips/patches-5.15/105-v5.17-PCI-mt7621-Remove-unused-function-pcie_rmw.patch @@ -0,0 +1,35 @@ +From: Sergio Paracuellos +Date: Mon, 24 Jan 2022 12:30:03 +0100 +Subject: [PATCH] PCI: mt7621: Remove unused function pcie_rmw() + +Function pcie_rmw() is not being used at all and can be deleted. Hence get +rid of it, which fixes this warning: + + drivers/pci/controller/pcie-mt7621.c:112:20: warning: unused function 'pcie_rmw' [-Wunused-function] + +Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver") +Link: https://lore.kernel.org/r/20220124113003.406224-3-sergio.paracuellos@gmail.com +Link: https://lore.kernel.org/all/202201241754.igtHzgHv-lkp@intel.com/ +Reported-by: kernel test robot +Signed-off-by: Sergio Paracuellos +Signed-off-by: Bjorn Helgaas +--- + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -109,15 +109,6 @@ static inline void pcie_write(struct mt7 + writel_relaxed(val, pcie->base + reg); + } + +-static inline void pcie_rmw(struct mt7621_pcie *pcie, u32 reg, u32 clr, u32 set) +-{ +- u32 val = readl_relaxed(pcie->base + reg); +- +- val &= ~clr; +- val |= set; +- writel_relaxed(val, pcie->base + reg); +-} +- + static inline u32 pcie_port_read(struct mt7621_pcie_port *port, u32 reg) + { + return readl_relaxed(port->base + reg); diff --git a/target/linux/ramips/patches-5.15/106-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch b/target/linux/ramips/patches-5.15/106-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch deleted file mode 100644 index 2fbbf9a7aa..0000000000 --- a/target/linux/ramips/patches-5.15/106-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Sergio Paracuellos -Date: Tue, 7 Dec 2021 11:49:20 +0100 -Subject: [PATCH] PCI: Let pcibios_root_bridge_prepare() access bridge->windows - -When pci_register_host_bridge() is called, bridge->windows are already -available. However these windows are being moved temporarily from there. - -To let pcibios_root_bridge_prepare() have access to these windows, move the -windows movement after calling this function. This is useful for the MIPS -ralink mt7621 platform so it can set up I/O coherence units and avoid -custom MIPS code in the mt7621 PCIe controller driver. - -Link: https://lore.kernel.org/r/20211207104924.21327-2-sergio.paracuellos@gmail.com -Signed-off-by: Sergio Paracuellos -Signed-off-by: Bjorn Helgaas -Acked-by: Arnd Bergmann ---- - ---- a/drivers/pci/probe.c -+++ b/drivers/pci/probe.c -@@ -898,8 +898,6 @@ static int pci_register_host_bridge(stru - - bridge->bus = bus; - -- /* Temporarily move resources off the list */ -- list_splice_init(&bridge->windows, &resources); - bus->sysdata = bridge->sysdata; - bus->ops = bridge->ops; - bus->number = bus->busn_res.start = bridge->busnr; -@@ -925,6 +923,8 @@ static int pci_register_host_bridge(stru - if (err) - goto free; - -+ /* Temporarily move resources off the list */ -+ list_splice_init(&bridge->windows, &resources); - err = device_add(&bridge->dev); - if (err) { - put_device(&bridge->dev); diff --git a/target/linux/ramips/patches-5.15/106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch b/target/linux/ramips/patches-5.15/106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch new file mode 100644 index 0000000000..2fbbf9a7aa --- /dev/null +++ b/target/linux/ramips/patches-5.15/106-v5.17-PCI-Let-pcibios_root_bridge_prepare-access-bridge-wi.patch @@ -0,0 +1,38 @@ +From: Sergio Paracuellos +Date: Tue, 7 Dec 2021 11:49:20 +0100 +Subject: [PATCH] PCI: Let pcibios_root_bridge_prepare() access bridge->windows + +When pci_register_host_bridge() is called, bridge->windows are already +available. However these windows are being moved temporarily from there. + +To let pcibios_root_bridge_prepare() have access to these windows, move the +windows movement after calling this function. This is useful for the MIPS +ralink mt7621 platform so it can set up I/O coherence units and avoid +custom MIPS code in the mt7621 PCIe controller driver. + +Link: https://lore.kernel.org/r/20211207104924.21327-2-sergio.paracuellos@gmail.com +Signed-off-by: Sergio Paracuellos +Signed-off-by: Bjorn Helgaas +Acked-by: Arnd Bergmann +--- + +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -898,8 +898,6 @@ static int pci_register_host_bridge(stru + + bridge->bus = bus; + +- /* Temporarily move resources off the list */ +- list_splice_init(&bridge->windows, &resources); + bus->sysdata = bridge->sysdata; + bus->ops = bridge->ops; + bus->number = bus->busn_res.start = bridge->busnr; +@@ -925,6 +923,8 @@ static int pci_register_host_bridge(stru + if (err) + goto free; + ++ /* Temporarily move resources off the list */ ++ list_splice_init(&bridge->windows, &resources); + err = device_add(&bridge->dev); + if (err) { + put_device(&bridge->dev); diff --git a/target/linux/ramips/patches-5.15/107-PCI-mt7621-Add-sentinel-to-quirks-table.patch b/target/linux/ramips/patches-5.15/107-PCI-mt7621-Add-sentinel-to-quirks-table.patch deleted file mode 100644 index c055f0096d..0000000000 --- a/target/linux/ramips/patches-5.15/107-PCI-mt7621-Add-sentinel-to-quirks-table.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 19098934f910b4d47cb30251dd39ffa57bef9523 Mon Sep 17 00:00:00 2001 -From: John Thomson -Date: Tue, 6 Dec 2022 06:46:45 +1000 -Subject: [PATCH] PCI: mt7621: Add sentinel to quirks table - -Current driver is missing a sentinel in the struct soc_device_attribute -array, which causes an oops when assessed by the -soc_device_match(mt7621_pcie_quirks_match) call. - -This was only exposed once the CONFIG_SOC_MT7621 mt7621 soc_dev_attr -was fixed to register the SOC as a device, in: - -commit 7c18b64bba3b ("mips: ralink: mt7621: do not use kzalloc too early") - -Fix it by adding the required sentinel. - -Link: https://lore.kernel.org/lkml/26ebbed1-0fe9-4af9-8466-65f841d0b382@app.fastmail.com -Link: https://lore.kernel.org/r/20221205204645.301301-1-git@johnthomson.fastmail.com.au -Fixes: b483b4e4d3f6 ("staging: mt7621-pci: add quirks for 'E2' revision using 'soc_device_attribute'") -Signed-off-by: John Thomson -Signed-off-by: Lorenzo Pieralisi -Acked-by: Sergio Paracuellos ---- - drivers/pci/controller/pcie-mt7621.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/pci/controller/pcie-mt7621.c -+++ b/drivers/pci/controller/pcie-mt7621.c -@@ -471,7 +471,8 @@ static int mt7621_pcie_register_host(str - } - - static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { -- { .soc_id = "mt7621", .revision = "E2" } -+ { .soc_id = "mt7621", .revision = "E2" }, -+ { /* sentinel */ } - }; - - static int mt7621_pcie_probe(struct platform_device *pdev) diff --git a/target/linux/ramips/patches-5.15/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch b/target/linux/ramips/patches-5.15/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch new file mode 100644 index 0000000000..c055f0096d --- /dev/null +++ b/target/linux/ramips/patches-5.15/107-v6.2-PCI-mt7621-Add-sentinel-to-quirks-table.patch @@ -0,0 +1,38 @@ +From 19098934f910b4d47cb30251dd39ffa57bef9523 Mon Sep 17 00:00:00 2001 +From: John Thomson +Date: Tue, 6 Dec 2022 06:46:45 +1000 +Subject: [PATCH] PCI: mt7621: Add sentinel to quirks table + +Current driver is missing a sentinel in the struct soc_device_attribute +array, which causes an oops when assessed by the +soc_device_match(mt7621_pcie_quirks_match) call. + +This was only exposed once the CONFIG_SOC_MT7621 mt7621 soc_dev_attr +was fixed to register the SOC as a device, in: + +commit 7c18b64bba3b ("mips: ralink: mt7621: do not use kzalloc too early") + +Fix it by adding the required sentinel. + +Link: https://lore.kernel.org/lkml/26ebbed1-0fe9-4af9-8466-65f841d0b382@app.fastmail.com +Link: https://lore.kernel.org/r/20221205204645.301301-1-git@johnthomson.fastmail.com.au +Fixes: b483b4e4d3f6 ("staging: mt7621-pci: add quirks for 'E2' revision using 'soc_device_attribute'") +Signed-off-by: John Thomson +Signed-off-by: Lorenzo Pieralisi +Acked-by: Sergio Paracuellos +--- + drivers/pci/controller/pcie-mt7621.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -471,7 +471,8 @@ static int mt7621_pcie_register_host(str + } + + static const struct soc_device_attribute mt7621_pcie_quirks_match[] = { +- { .soc_id = "mt7621", .revision = "E2" } ++ { .soc_id = "mt7621", .revision = "E2" }, ++ { /* sentinel */ } + }; + + static int mt7621_pcie_probe(struct platform_device *pdev) diff --git a/target/linux/ramips/patches-5.15/108-PCI-mt7621-Delay-phy-ports-initialization.patch b/target/linux/ramips/patches-5.15/108-PCI-mt7621-Delay-phy-ports-initialization.patch deleted file mode 100644 index de1d4cfc12..0000000000 --- a/target/linux/ramips/patches-5.15/108-PCI-mt7621-Delay-phy-ports-initialization.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0cb2a8f3456ff1cc51d571e287a48e8fddc98ec2 Mon Sep 17 00:00:00 2001 -From: Sergio Paracuellos -Date: Sat, 31 Dec 2022 08:40:41 +0100 -Subject: PCI: mt7621: Delay phy ports initialization - -Some devices like ZBT WE1326 and ZBT WF3526-P and some Netgear models need -to delay phy port initialization after calling the mt7621_pcie_init_port() -driver function to get into reliable boots for both warm and hard resets. - -The delay required to detect the ports seems to be in the range [75-100] -milliseconds. - -If the ports are not detected the controller is not functional. - -There is no datasheet or something similar to really understand why this -extra delay is needed only for these devices and it is not for most of -the boards that are built on mt7621 SoC. - -This issue has been reported by openWRT community and the complete -discussion is in [0]. The 100 milliseconds delay has been tested in all -devices to validate it. - -Add the extra 100 milliseconds delay to fix the issue. - -[0]: https://github.com/openwrt/openwrt/pull/11220 - -Link: https://lore.kernel.org/r/20221231074041.264738-1-sergio.paracuellos@gmail.com -Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver") -Signed-off-by: Sergio Paracuellos -Signed-off-by: Lorenzo Pieralisi ---- - drivers/pci/controller/pcie-mt7621.c | 2 ++ - 1 file changed, 2 insertions(+) - ---- a/drivers/pci/controller/pcie-mt7621.c -+++ b/drivers/pci/controller/pcie-mt7621.c -@@ -58,6 +58,7 @@ - #define PCIE_PORT_LINKUP BIT(0) - #define PCIE_PORT_CNT 3 - -+#define INIT_PORTS_DELAY_MS 100 - #define PERST_DELAY_MS 100 - - /** -@@ -374,6 +375,7 @@ static int mt7621_pcie_init_ports(struct - } - } - -+ msleep(INIT_PORTS_DELAY_MS); - mt7621_pcie_reset_ep_deassert(pcie); - - tmp = NULL; diff --git a/target/linux/ramips/patches-5.15/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch b/target/linux/ramips/patches-5.15/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch new file mode 100644 index 0000000000..de1d4cfc12 --- /dev/null +++ b/target/linux/ramips/patches-5.15/108-v6.3-PCI-mt7621-Delay-phy-ports-initialization.patch @@ -0,0 +1,52 @@ +From 0cb2a8f3456ff1cc51d571e287a48e8fddc98ec2 Mon Sep 17 00:00:00 2001 +From: Sergio Paracuellos +Date: Sat, 31 Dec 2022 08:40:41 +0100 +Subject: PCI: mt7621: Delay phy ports initialization + +Some devices like ZBT WE1326 and ZBT WF3526-P and some Netgear models need +to delay phy port initialization after calling the mt7621_pcie_init_port() +driver function to get into reliable boots for both warm and hard resets. + +The delay required to detect the ports seems to be in the range [75-100] +milliseconds. + +If the ports are not detected the controller is not functional. + +There is no datasheet or something similar to really understand why this +extra delay is needed only for these devices and it is not for most of +the boards that are built on mt7621 SoC. + +This issue has been reported by openWRT community and the complete +discussion is in [0]. The 100 milliseconds delay has been tested in all +devices to validate it. + +Add the extra 100 milliseconds delay to fix the issue. + +[0]: https://github.com/openwrt/openwrt/pull/11220 + +Link: https://lore.kernel.org/r/20221231074041.264738-1-sergio.paracuellos@gmail.com +Fixes: 2bdd5238e756 ("PCI: mt7621: Add MediaTek MT7621 PCIe host controller driver") +Signed-off-by: Sergio Paracuellos +Signed-off-by: Lorenzo Pieralisi +--- + drivers/pci/controller/pcie-mt7621.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/pci/controller/pcie-mt7621.c ++++ b/drivers/pci/controller/pcie-mt7621.c +@@ -58,6 +58,7 @@ + #define PCIE_PORT_LINKUP BIT(0) + #define PCIE_PORT_CNT 3 + ++#define INIT_PORTS_DELAY_MS 100 + #define PERST_DELAY_MS 100 + + /** +@@ -374,6 +375,7 @@ static int mt7621_pcie_init_ports(struct + } + } + ++ msleep(INIT_PORTS_DELAY_MS); + mt7621_pcie_reset_ep_deassert(pcie); + + tmp = NULL;