From: Rafał Miłecki Date: Thu, 21 Jan 2016 05:59:16 +0000 (+0000) Subject: bcm53xx: fix iProc regression with sent patch instead of a revert X-Git-Tag: reboot~709 X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=commitdiff_plain;h=a6ec12bb098ecb634871f3401ed77f365f04c47c bcm53xx: fix iProc regression with sent patch instead of a revert This properly fixes #21393. Signed-off-by: Rafał Miłecki SVN-Revision: 48423 --- diff --git a/target/linux/bcm53xx/patches-4.1/175-PCI-iproc-Fix-BCMA-PCIe-bus-scanning-regression.patch b/target/linux/bcm53xx/patches-4.1/175-PCI-iproc-Fix-BCMA-PCIe-bus-scanning-regression.patch new file mode 100644 index 0000000000..21c7716846 --- /dev/null +++ b/target/linux/bcm53xx/patches-4.1/175-PCI-iproc-Fix-BCMA-PCIe-bus-scanning-regression.patch @@ -0,0 +1,51 @@ +From patchwork Wed Jan 20 22:55:10 2016 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: PCI: iproc: Fix BCMA PCIe bus scanning regression +From: Ray Jui +X-Patchwork-Id: 570953 +Message-Id: <1453330510-21926-1-git-send-email-rjui@broadcom.com> +To: Bjorn Helgaas +Cc: Rafal Milecki , Hante Meuleman , + Hauke Mehrtens , , + , + , Ray Jui +Date: Wed, 20 Jan 2016 14:55:10 -0800 + +Commit 943ebae781f5 ("PCI: iproc: Add PAXC interface support") causes +regression on EP device detection on BCMA based platforms. This patch +fixes the issue by allowing multiple devices to be configured on the +same bus, for all PAXB based child buses + +Reported-by: Rafal Milecki +Fixes: 943ebae781f5 ("PCI: iproc: Add PAXC interface support") +Signed-off-by: Ray Jui +--- + drivers/pci/host/pcie-iproc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/pci/host/pcie-iproc.c ++++ b/drivers/pci/host/pcie-iproc.c +@@ -171,10 +171,11 @@ static inline void iproc_pcie_ob_write(s + } + + static inline bool iproc_pcie_device_is_valid(struct iproc_pcie *pcie, ++ unsigned int busnum, + unsigned int slot, + unsigned int fn) + { +- if (slot > 0) ++ if ((pcie->type == IPROC_PCIE_PAXC || busnum == 0) && slot > 0) + return false; + + /* PAXC can only support limited number of functions */ +@@ -199,7 +200,7 @@ static void __iomem *iproc_pcie_map_cfg_ + u32 val; + u16 offset; + +- if (!iproc_pcie_device_is_valid(pcie, slot, fn)) ++ if (!iproc_pcie_device_is_valid(pcie, busno, slot, fn)) + return NULL; + + /* root complex access */ diff --git a/target/linux/bcm53xx/patches-4.1/800-Revert-PCI-iproc-Add-PAXC-interface-support.patch b/target/linux/bcm53xx/patches-4.1/800-Revert-PCI-iproc-Add-PAXC-interface-support.patch deleted file mode 100644 index 4aad6868f3..0000000000 --- a/target/linux/bcm53xx/patches-4.1/800-Revert-PCI-iproc-Add-PAXC-interface-support.patch +++ /dev/null @@ -1,425 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH] Revert "PCI: iproc: Add PAXC interface support" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adding PAXC support fixed all "invalid BAR" firmware bug messages but -also broke finding extra buses and attached devices. This affected -e.g. Netgear R8000 which has 2 (out of 3) BCM43602 cards connected to -the 2nd "PCIe Gen 2" controller. None of them is detected with PAXC -code. - -This reverts commit 943ebae781f519ecfecbfa1b997f15f59116e41d. - -Signed-off-by: Rafał Miłecki ---- - drivers/pci/host/pcie-iproc-platform.c | 24 +--- - drivers/pci/host/pcie-iproc.c | 202 ++++++--------------------------- - drivers/pci/host/pcie-iproc.h | 19 ---- - 3 files changed, 40 insertions(+), 205 deletions(-) - ---- a/drivers/pci/host/pcie-iproc-platform.c -+++ b/drivers/pci/host/pcie-iproc-platform.c -@@ -26,21 +26,8 @@ - - #include "pcie-iproc.h" - --static const struct of_device_id iproc_pcie_of_match_table[] = { -- { -- .compatible = "brcm,iproc-pcie", -- .data = (int *)IPROC_PCIE_PAXB, -- }, { -- .compatible = "brcm,iproc-pcie-paxc", -- .data = (int *)IPROC_PCIE_PAXC, -- }, -- { /* sentinel */ } --}; --MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table); -- - static int iproc_pcie_pltfm_probe(struct platform_device *pdev) - { -- const struct of_device_id *of_id; - struct iproc_pcie *pcie; - struct device_node *np = pdev->dev.of_node; - struct resource reg; -@@ -48,16 +35,11 @@ static int iproc_pcie_pltfm_probe(struct - LIST_HEAD(res); - int ret; - -- of_id = of_match_device(iproc_pcie_of_match_table, &pdev->dev); -- if (!of_id) -- return -EINVAL; -- - pcie = devm_kzalloc(&pdev->dev, sizeof(struct iproc_pcie), GFP_KERNEL); - if (!pcie) - return -ENOMEM; - - pcie->dev = &pdev->dev; -- pcie->type = (enum iproc_pcie_type)of_id->data; - platform_set_drvdata(pdev, pcie); - - ret = of_address_to_resource(np, 0, ®); -@@ -133,6 +115,12 @@ static int iproc_pcie_pltfm_remove(struc - return iproc_pcie_remove(pcie); - } - -+static const struct of_device_id iproc_pcie_of_match_table[] = { -+ { .compatible = "brcm,iproc-pcie", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table); -+ - static struct platform_driver iproc_pcie_pltfm_driver = { - .driver = { - .name = "iproc-pcie", ---- a/drivers/pci/host/pcie-iproc.c -+++ b/drivers/pci/host/pcie-iproc.c -@@ -30,16 +30,20 @@ - - #include "pcie-iproc.h" - -+#define CLK_CONTROL_OFFSET 0x000 - #define EP_PERST_SOURCE_SELECT_SHIFT 2 - #define EP_PERST_SOURCE_SELECT BIT(EP_PERST_SOURCE_SELECT_SHIFT) - #define EP_MODE_SURVIVE_PERST_SHIFT 1 - #define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT) - #define RC_PCIE_RST_OUTPUT_SHIFT 0 - #define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT) --#define PAXC_RESET_MASK 0x7f - -+#define CFG_IND_ADDR_OFFSET 0x120 - #define CFG_IND_ADDR_MASK 0x00001ffc - -+#define CFG_IND_DATA_OFFSET 0x124 -+ -+#define CFG_ADDR_OFFSET 0x1f8 - #define CFG_ADDR_BUS_NUM_SHIFT 20 - #define CFG_ADDR_BUS_NUM_MASK 0x0ff00000 - #define CFG_ADDR_DEV_NUM_SHIFT 15 -@@ -51,8 +55,12 @@ - #define CFG_ADDR_CFG_TYPE_SHIFT 0 - #define CFG_ADDR_CFG_TYPE_MASK 0x00000003 - -+#define CFG_DATA_OFFSET 0x1fc -+ -+#define SYS_RC_INTX_EN 0x330 - #define SYS_RC_INTX_MASK 0xf - -+#define PCIE_LINK_STATUS_OFFSET 0xf0c - #define PCIE_PHYLINKUP_SHIFT 3 - #define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT) - #define PCIE_DL_ACTIVE_SHIFT 2 -@@ -63,54 +71,12 @@ - #define OARR_SIZE_CFG_SHIFT 1 - #define OARR_SIZE_CFG BIT(OARR_SIZE_CFG_SHIFT) - --#define MAX_NUM_OB_WINDOWS 2 --#define MAX_NUM_PAXC_PF 4 -- --#define IPROC_PCIE_REG_INVALID 0xffff -+#define OARR_LO(window) (0xd20 + (window) * 8) -+#define OARR_HI(window) (0xd24 + (window) * 8) -+#define OMAP_LO(window) (0xd40 + (window) * 8) -+#define OMAP_HI(window) (0xd44 + (window) * 8) - --enum iproc_pcie_reg { -- IPROC_PCIE_CLK_CTRL = 0, -- IPROC_PCIE_CFG_IND_ADDR, -- IPROC_PCIE_CFG_IND_DATA, -- IPROC_PCIE_CFG_ADDR, -- IPROC_PCIE_CFG_DATA, -- IPROC_PCIE_INTX_EN, -- IPROC_PCIE_OARR_LO, -- IPROC_PCIE_OARR_HI, -- IPROC_PCIE_OMAP_LO, -- IPROC_PCIE_OMAP_HI, -- IPROC_PCIE_LINK_STATUS, --}; -- --/* iProc PCIe PAXB registers */ --static const u16 iproc_pcie_reg_paxb[] = { -- [IPROC_PCIE_CLK_CTRL] = 0x000, -- [IPROC_PCIE_CFG_IND_ADDR] = 0x120, -- [IPROC_PCIE_CFG_IND_DATA] = 0x124, -- [IPROC_PCIE_CFG_ADDR] = 0x1f8, -- [IPROC_PCIE_CFG_DATA] = 0x1fc, -- [IPROC_PCIE_INTX_EN] = 0x330, -- [IPROC_PCIE_OARR_LO] = 0xd20, -- [IPROC_PCIE_OARR_HI] = 0xd24, -- [IPROC_PCIE_OMAP_LO] = 0xd40, -- [IPROC_PCIE_OMAP_HI] = 0xd44, -- [IPROC_PCIE_LINK_STATUS] = 0xf0c, --}; -- --/* iProc PCIe PAXC v1 registers */ --static const u16 iproc_pcie_reg_paxc[] = { -- [IPROC_PCIE_CLK_CTRL] = 0x000, -- [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0, -- [IPROC_PCIE_CFG_IND_DATA] = 0x1f4, -- [IPROC_PCIE_CFG_ADDR] = 0x1f8, -- [IPROC_PCIE_CFG_DATA] = 0x1fc, -- [IPROC_PCIE_INTX_EN] = IPROC_PCIE_REG_INVALID, -- [IPROC_PCIE_OARR_LO] = IPROC_PCIE_REG_INVALID, -- [IPROC_PCIE_OARR_HI] = IPROC_PCIE_REG_INVALID, -- [IPROC_PCIE_OMAP_LO] = IPROC_PCIE_REG_INVALID, -- [IPROC_PCIE_OMAP_HI] = IPROC_PCIE_REG_INVALID, -- [IPROC_PCIE_LINK_STATUS] = IPROC_PCIE_REG_INVALID, --}; -+#define MAX_NUM_OB_WINDOWS 2 - - static inline struct iproc_pcie *iproc_data(struct pci_bus *bus) - { -@@ -125,65 +91,6 @@ static inline struct iproc_pcie *iproc_d - return pcie; - } - --static inline bool iproc_pcie_reg_is_invalid(u16 reg_offset) --{ -- return !!(reg_offset == IPROC_PCIE_REG_INVALID); --} -- --static inline u16 iproc_pcie_reg_offset(struct iproc_pcie *pcie, -- enum iproc_pcie_reg reg) --{ -- return pcie->reg_offsets[reg]; --} -- --static inline u32 iproc_pcie_read_reg(struct iproc_pcie *pcie, -- enum iproc_pcie_reg reg) --{ -- u16 offset = iproc_pcie_reg_offset(pcie, reg); -- -- if (iproc_pcie_reg_is_invalid(offset)) -- return 0; -- -- return readl(pcie->base + offset); --} -- --static inline void iproc_pcie_write_reg(struct iproc_pcie *pcie, -- enum iproc_pcie_reg reg, u32 val) --{ -- u16 offset = iproc_pcie_reg_offset(pcie, reg); -- -- if (iproc_pcie_reg_is_invalid(offset)) -- return; -- -- writel(val, pcie->base + offset); --} -- --static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie, -- enum iproc_pcie_reg reg, -- unsigned window, u32 val) --{ -- u16 offset = iproc_pcie_reg_offset(pcie, reg); -- -- if (iproc_pcie_reg_is_invalid(offset)) -- return; -- -- writel(val, pcie->base + offset + (window * 8)); --} -- --static inline bool iproc_pcie_device_is_valid(struct iproc_pcie *pcie, -- unsigned int slot, -- unsigned int fn) --{ -- if (slot > 0) -- return false; -- -- /* PAXC can only support limited number of functions */ -- if (pcie->type == IPROC_PCIE_PAXC && fn >= MAX_NUM_PAXC_PF) -- return false; -- -- return true; --} -- - /** - * Note access to the configuration registers are protected at the higher layer - * by 'pci_lock' in drivers/pci/access.c -@@ -197,34 +104,28 @@ static void __iomem *iproc_pcie_map_cfg_ - unsigned fn = PCI_FUNC(devfn); - unsigned busno = bus->number; - u32 val; -- u16 offset; -- -- if (!iproc_pcie_device_is_valid(pcie, slot, fn)) -- return NULL; - - /* root complex access */ - if (busno == 0) { -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR, -- where & CFG_IND_ADDR_MASK); -- offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA); -- if (iproc_pcie_reg_is_invalid(offset)) -+ if (slot >= 1) - return NULL; -- else -- return (pcie->base + offset); -+ writel(where & CFG_IND_ADDR_MASK, -+ pcie->base + CFG_IND_ADDR_OFFSET); -+ return (pcie->base + CFG_IND_DATA_OFFSET); - } - -+ if (fn > 1) -+ return NULL; -+ - /* EP device access */ - val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | - (slot << CFG_ADDR_DEV_NUM_SHIFT) | - (fn << CFG_ADDR_FUNC_NUM_SHIFT) | - (where & CFG_ADDR_REG_NUM_MASK) | - (1 & CFG_ADDR_CFG_TYPE_MASK); -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val); -- offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA); -- if (iproc_pcie_reg_is_invalid(offset)) -- return NULL; -- else -- return (pcie->base + offset); -+ writel(val, pcie->base + CFG_ADDR_OFFSET); -+ -+ return (pcie->base + CFG_DATA_OFFSET); - } - - static struct pci_ops iproc_pcie_ops = { -@@ -237,29 +138,18 @@ static void iproc_pcie_reset(struct ipro - { - u32 val; - -- if (pcie->type == IPROC_PCIE_PAXC) { -- val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); -- val &= ~PAXC_RESET_MASK; -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); -- udelay(100); -- val |= PAXC_RESET_MASK; -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); -- udelay(100); -- return; -- } -- - /* - * Select perst_b signal as reset source. Put the device into reset, - * and then bring it out of reset - */ -- val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); -+ val = readl(pcie->base + CLK_CONTROL_OFFSET); - val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST & - ~RC_PCIE_RST_OUTPUT; -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); -+ writel(val, pcie->base + CLK_CONTROL_OFFSET); - udelay(250); - - val |= RC_PCIE_RST_OUTPUT; -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); -+ writel(val, pcie->base + CLK_CONTROL_OFFSET); - msleep(100); - } - -@@ -270,14 +160,7 @@ static int iproc_pcie_check_link(struct - u16 pos, link_status; - bool link_is_active = false; - -- /* -- * PAXC connects to emulated endpoint devices directly and does not -- * have a Serdes. Therefore skip the link detection logic here. -- */ -- if (pcie->type == IPROC_PCIE_PAXC) -- return 0; -- -- val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS); -+ val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET); - if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) { - dev_err(pcie->dev, "PHY or data link is INACTIVE!\n"); - return -ENODEV; -@@ -338,7 +221,7 @@ static int iproc_pcie_check_link(struct - - static void iproc_pcie_enable(struct iproc_pcie *pcie) - { -- iproc_pcie_write_reg(pcie, IPROC_PCIE_INTX_EN, SYS_RC_INTX_MASK); -+ writel(SYS_RC_INTX_MASK, pcie->base + SYS_RC_INTX_EN); - } - - /** -@@ -389,15 +272,11 @@ static int iproc_pcie_setup_ob(struct ip - axi_addr -= ob->axi_offset; - - for (i = 0; i < MAX_NUM_OB_WINDOWS; i++) { -- iproc_pcie_ob_write(pcie, IPROC_PCIE_OARR_LO, i, -- lower_32_bits(axi_addr) | OARR_VALID | -- (ob->set_oarr_size ? 1 : 0)); -- iproc_pcie_ob_write(pcie, IPROC_PCIE_OARR_HI, i, -- upper_32_bits(axi_addr)); -- iproc_pcie_ob_write(pcie, IPROC_PCIE_OMAP_LO, i, -- lower_32_bits(pci_addr)); -- iproc_pcie_ob_write(pcie, IPROC_PCIE_OMAP_HI, i, -- upper_32_bits(pci_addr)); -+ writel(lower_32_bits(axi_addr) | OARR_VALID | -+ (ob->set_oarr_size ? 1 : 0), pcie->base + OARR_LO(i)); -+ writel(upper_32_bits(axi_addr), pcie->base + OARR_HI(i)); -+ writel(lower_32_bits(pci_addr), pcie->base + OMAP_LO(i)); -+ writel(upper_32_bits(pci_addr), pcie->base + OMAP_HI(i)); - - size -= ob->window_size; - if (size == 0) -@@ -481,19 +360,6 @@ int iproc_pcie_setup(struct iproc_pcie * - goto err_exit_phy; - } - -- switch (pcie->type) { -- case IPROC_PCIE_PAXB: -- pcie->reg_offsets = iproc_pcie_reg_paxb; -- break; -- case IPROC_PCIE_PAXC: -- pcie->reg_offsets = iproc_pcie_reg_paxc; -- break; -- default: -- dev_err(pcie->dev, "incompatible iProc PCIe interface\n"); -- ret = -EINVAL; -- goto err_power_off_phy; -- } -- - iproc_pcie_reset(pcie); - - if (pcie->need_ob_cfg) { ---- a/drivers/pci/host/pcie-iproc.h -+++ b/drivers/pci/host/pcie-iproc.h -@@ -15,20 +15,6 @@ - #define _PCIE_IPROC_H - - /** -- * iProc PCIe interface type -- * -- * PAXB is the wrapper used in root complex that can be connected to an -- * external endpoint device. -- * -- * PAXC is the wrapper used in root complex dedicated for internal emulated -- * endpoint devices. -- */ --enum iproc_pcie_type { -- IPROC_PCIE_PAXB = 0, -- IPROC_PCIE_PAXC, --}; -- --/** - * iProc PCIe outbound mapping - * @set_oarr_size: indicates the OARR size bit needs to be set - * @axi_offset: offset from the AXI address to the internal address used by -@@ -45,10 +31,7 @@ struct iproc_msi; - - /** - * iProc PCIe device -- * - * @dev: pointer to device data structure -- * @type: iProc PCIe interface type -- * @reg_offsets: register offsets - * @base: PCIe host controller I/O register base - * @base_addr: PCIe host controller register base physical address - * @sysdata: Per PCI controller data (ARM-specific) -@@ -61,8 +44,6 @@ struct iproc_msi; - */ - struct iproc_pcie { - struct device *dev; -- enum iproc_pcie_type type; -- const u16 *reg_offsets; - void __iomem *base; - phys_addr_t base_addr; - #ifdef CONFIG_ARM diff --git a/target/linux/bcm53xx/patches-4.4/180-PCI-iproc-Fix-BCMA-PCIe-bus-scanning-regression.patch b/target/linux/bcm53xx/patches-4.4/180-PCI-iproc-Fix-BCMA-PCIe-bus-scanning-regression.patch new file mode 100644 index 0000000000..21c7716846 --- /dev/null +++ b/target/linux/bcm53xx/patches-4.4/180-PCI-iproc-Fix-BCMA-PCIe-bus-scanning-regression.patch @@ -0,0 +1,51 @@ +From patchwork Wed Jan 20 22:55:10 2016 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: PCI: iproc: Fix BCMA PCIe bus scanning regression +From: Ray Jui +X-Patchwork-Id: 570953 +Message-Id: <1453330510-21926-1-git-send-email-rjui@broadcom.com> +To: Bjorn Helgaas +Cc: Rafal Milecki , Hante Meuleman , + Hauke Mehrtens , , + , + , Ray Jui +Date: Wed, 20 Jan 2016 14:55:10 -0800 + +Commit 943ebae781f5 ("PCI: iproc: Add PAXC interface support") causes +regression on EP device detection on BCMA based platforms. This patch +fixes the issue by allowing multiple devices to be configured on the +same bus, for all PAXB based child buses + +Reported-by: Rafal Milecki +Fixes: 943ebae781f5 ("PCI: iproc: Add PAXC interface support") +Signed-off-by: Ray Jui +--- + drivers/pci/host/pcie-iproc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/pci/host/pcie-iproc.c ++++ b/drivers/pci/host/pcie-iproc.c +@@ -171,10 +171,11 @@ static inline void iproc_pcie_ob_write(s + } + + static inline bool iproc_pcie_device_is_valid(struct iproc_pcie *pcie, ++ unsigned int busnum, + unsigned int slot, + unsigned int fn) + { +- if (slot > 0) ++ if ((pcie->type == IPROC_PCIE_PAXC || busnum == 0) && slot > 0) + return false; + + /* PAXC can only support limited number of functions */ +@@ -199,7 +200,7 @@ static void __iomem *iproc_pcie_map_cfg_ + u32 val; + u16 offset; + +- if (!iproc_pcie_device_is_valid(pcie, slot, fn)) ++ if (!iproc_pcie_device_is_valid(pcie, busno, slot, fn)) + return NULL; + + /* root complex access */ diff --git a/target/linux/bcm53xx/patches-4.4/800-Revert-PCI-iproc-Add-PAXC-interface-support.patch b/target/linux/bcm53xx/patches-4.4/800-Revert-PCI-iproc-Add-PAXC-interface-support.patch deleted file mode 100644 index 4aad6868f3..0000000000 --- a/target/linux/bcm53xx/patches-4.4/800-Revert-PCI-iproc-Add-PAXC-interface-support.patch +++ /dev/null @@ -1,425 +0,0 @@ -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Subject: [PATCH] Revert "PCI: iproc: Add PAXC interface support" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adding PAXC support fixed all "invalid BAR" firmware bug messages but -also broke finding extra buses and attached devices. This affected -e.g. Netgear R8000 which has 2 (out of 3) BCM43602 cards connected to -the 2nd "PCIe Gen 2" controller. None of them is detected with PAXC -code. - -This reverts commit 943ebae781f519ecfecbfa1b997f15f59116e41d. - -Signed-off-by: Rafał Miłecki ---- - drivers/pci/host/pcie-iproc-platform.c | 24 +--- - drivers/pci/host/pcie-iproc.c | 202 ++++++--------------------------- - drivers/pci/host/pcie-iproc.h | 19 ---- - 3 files changed, 40 insertions(+), 205 deletions(-) - ---- a/drivers/pci/host/pcie-iproc-platform.c -+++ b/drivers/pci/host/pcie-iproc-platform.c -@@ -26,21 +26,8 @@ - - #include "pcie-iproc.h" - --static const struct of_device_id iproc_pcie_of_match_table[] = { -- { -- .compatible = "brcm,iproc-pcie", -- .data = (int *)IPROC_PCIE_PAXB, -- }, { -- .compatible = "brcm,iproc-pcie-paxc", -- .data = (int *)IPROC_PCIE_PAXC, -- }, -- { /* sentinel */ } --}; --MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table); -- - static int iproc_pcie_pltfm_probe(struct platform_device *pdev) - { -- const struct of_device_id *of_id; - struct iproc_pcie *pcie; - struct device_node *np = pdev->dev.of_node; - struct resource reg; -@@ -48,16 +35,11 @@ static int iproc_pcie_pltfm_probe(struct - LIST_HEAD(res); - int ret; - -- of_id = of_match_device(iproc_pcie_of_match_table, &pdev->dev); -- if (!of_id) -- return -EINVAL; -- - pcie = devm_kzalloc(&pdev->dev, sizeof(struct iproc_pcie), GFP_KERNEL); - if (!pcie) - return -ENOMEM; - - pcie->dev = &pdev->dev; -- pcie->type = (enum iproc_pcie_type)of_id->data; - platform_set_drvdata(pdev, pcie); - - ret = of_address_to_resource(np, 0, ®); -@@ -133,6 +115,12 @@ static int iproc_pcie_pltfm_remove(struc - return iproc_pcie_remove(pcie); - } - -+static const struct of_device_id iproc_pcie_of_match_table[] = { -+ { .compatible = "brcm,iproc-pcie", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table); -+ - static struct platform_driver iproc_pcie_pltfm_driver = { - .driver = { - .name = "iproc-pcie", ---- a/drivers/pci/host/pcie-iproc.c -+++ b/drivers/pci/host/pcie-iproc.c -@@ -30,16 +30,20 @@ - - #include "pcie-iproc.h" - -+#define CLK_CONTROL_OFFSET 0x000 - #define EP_PERST_SOURCE_SELECT_SHIFT 2 - #define EP_PERST_SOURCE_SELECT BIT(EP_PERST_SOURCE_SELECT_SHIFT) - #define EP_MODE_SURVIVE_PERST_SHIFT 1 - #define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT) - #define RC_PCIE_RST_OUTPUT_SHIFT 0 - #define RC_PCIE_RST_OUTPUT BIT(RC_PCIE_RST_OUTPUT_SHIFT) --#define PAXC_RESET_MASK 0x7f - -+#define CFG_IND_ADDR_OFFSET 0x120 - #define CFG_IND_ADDR_MASK 0x00001ffc - -+#define CFG_IND_DATA_OFFSET 0x124 -+ -+#define CFG_ADDR_OFFSET 0x1f8 - #define CFG_ADDR_BUS_NUM_SHIFT 20 - #define CFG_ADDR_BUS_NUM_MASK 0x0ff00000 - #define CFG_ADDR_DEV_NUM_SHIFT 15 -@@ -51,8 +55,12 @@ - #define CFG_ADDR_CFG_TYPE_SHIFT 0 - #define CFG_ADDR_CFG_TYPE_MASK 0x00000003 - -+#define CFG_DATA_OFFSET 0x1fc -+ -+#define SYS_RC_INTX_EN 0x330 - #define SYS_RC_INTX_MASK 0xf - -+#define PCIE_LINK_STATUS_OFFSET 0xf0c - #define PCIE_PHYLINKUP_SHIFT 3 - #define PCIE_PHYLINKUP BIT(PCIE_PHYLINKUP_SHIFT) - #define PCIE_DL_ACTIVE_SHIFT 2 -@@ -63,54 +71,12 @@ - #define OARR_SIZE_CFG_SHIFT 1 - #define OARR_SIZE_CFG BIT(OARR_SIZE_CFG_SHIFT) - --#define MAX_NUM_OB_WINDOWS 2 --#define MAX_NUM_PAXC_PF 4 -- --#define IPROC_PCIE_REG_INVALID 0xffff -+#define OARR_LO(window) (0xd20 + (window) * 8) -+#define OARR_HI(window) (0xd24 + (window) * 8) -+#define OMAP_LO(window) (0xd40 + (window) * 8) -+#define OMAP_HI(window) (0xd44 + (window) * 8) - --enum iproc_pcie_reg { -- IPROC_PCIE_CLK_CTRL = 0, -- IPROC_PCIE_CFG_IND_ADDR, -- IPROC_PCIE_CFG_IND_DATA, -- IPROC_PCIE_CFG_ADDR, -- IPROC_PCIE_CFG_DATA, -- IPROC_PCIE_INTX_EN, -- IPROC_PCIE_OARR_LO, -- IPROC_PCIE_OARR_HI, -- IPROC_PCIE_OMAP_LO, -- IPROC_PCIE_OMAP_HI, -- IPROC_PCIE_LINK_STATUS, --}; -- --/* iProc PCIe PAXB registers */ --static const u16 iproc_pcie_reg_paxb[] = { -- [IPROC_PCIE_CLK_CTRL] = 0x000, -- [IPROC_PCIE_CFG_IND_ADDR] = 0x120, -- [IPROC_PCIE_CFG_IND_DATA] = 0x124, -- [IPROC_PCIE_CFG_ADDR] = 0x1f8, -- [IPROC_PCIE_CFG_DATA] = 0x1fc, -- [IPROC_PCIE_INTX_EN] = 0x330, -- [IPROC_PCIE_OARR_LO] = 0xd20, -- [IPROC_PCIE_OARR_HI] = 0xd24, -- [IPROC_PCIE_OMAP_LO] = 0xd40, -- [IPROC_PCIE_OMAP_HI] = 0xd44, -- [IPROC_PCIE_LINK_STATUS] = 0xf0c, --}; -- --/* iProc PCIe PAXC v1 registers */ --static const u16 iproc_pcie_reg_paxc[] = { -- [IPROC_PCIE_CLK_CTRL] = 0x000, -- [IPROC_PCIE_CFG_IND_ADDR] = 0x1f0, -- [IPROC_PCIE_CFG_IND_DATA] = 0x1f4, -- [IPROC_PCIE_CFG_ADDR] = 0x1f8, -- [IPROC_PCIE_CFG_DATA] = 0x1fc, -- [IPROC_PCIE_INTX_EN] = IPROC_PCIE_REG_INVALID, -- [IPROC_PCIE_OARR_LO] = IPROC_PCIE_REG_INVALID, -- [IPROC_PCIE_OARR_HI] = IPROC_PCIE_REG_INVALID, -- [IPROC_PCIE_OMAP_LO] = IPROC_PCIE_REG_INVALID, -- [IPROC_PCIE_OMAP_HI] = IPROC_PCIE_REG_INVALID, -- [IPROC_PCIE_LINK_STATUS] = IPROC_PCIE_REG_INVALID, --}; -+#define MAX_NUM_OB_WINDOWS 2 - - static inline struct iproc_pcie *iproc_data(struct pci_bus *bus) - { -@@ -125,65 +91,6 @@ static inline struct iproc_pcie *iproc_d - return pcie; - } - --static inline bool iproc_pcie_reg_is_invalid(u16 reg_offset) --{ -- return !!(reg_offset == IPROC_PCIE_REG_INVALID); --} -- --static inline u16 iproc_pcie_reg_offset(struct iproc_pcie *pcie, -- enum iproc_pcie_reg reg) --{ -- return pcie->reg_offsets[reg]; --} -- --static inline u32 iproc_pcie_read_reg(struct iproc_pcie *pcie, -- enum iproc_pcie_reg reg) --{ -- u16 offset = iproc_pcie_reg_offset(pcie, reg); -- -- if (iproc_pcie_reg_is_invalid(offset)) -- return 0; -- -- return readl(pcie->base + offset); --} -- --static inline void iproc_pcie_write_reg(struct iproc_pcie *pcie, -- enum iproc_pcie_reg reg, u32 val) --{ -- u16 offset = iproc_pcie_reg_offset(pcie, reg); -- -- if (iproc_pcie_reg_is_invalid(offset)) -- return; -- -- writel(val, pcie->base + offset); --} -- --static inline void iproc_pcie_ob_write(struct iproc_pcie *pcie, -- enum iproc_pcie_reg reg, -- unsigned window, u32 val) --{ -- u16 offset = iproc_pcie_reg_offset(pcie, reg); -- -- if (iproc_pcie_reg_is_invalid(offset)) -- return; -- -- writel(val, pcie->base + offset + (window * 8)); --} -- --static inline bool iproc_pcie_device_is_valid(struct iproc_pcie *pcie, -- unsigned int slot, -- unsigned int fn) --{ -- if (slot > 0) -- return false; -- -- /* PAXC can only support limited number of functions */ -- if (pcie->type == IPROC_PCIE_PAXC && fn >= MAX_NUM_PAXC_PF) -- return false; -- -- return true; --} -- - /** - * Note access to the configuration registers are protected at the higher layer - * by 'pci_lock' in drivers/pci/access.c -@@ -197,34 +104,28 @@ static void __iomem *iproc_pcie_map_cfg_ - unsigned fn = PCI_FUNC(devfn); - unsigned busno = bus->number; - u32 val; -- u16 offset; -- -- if (!iproc_pcie_device_is_valid(pcie, slot, fn)) -- return NULL; - - /* root complex access */ - if (busno == 0) { -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_IND_ADDR, -- where & CFG_IND_ADDR_MASK); -- offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_IND_DATA); -- if (iproc_pcie_reg_is_invalid(offset)) -+ if (slot >= 1) - return NULL; -- else -- return (pcie->base + offset); -+ writel(where & CFG_IND_ADDR_MASK, -+ pcie->base + CFG_IND_ADDR_OFFSET); -+ return (pcie->base + CFG_IND_DATA_OFFSET); - } - -+ if (fn > 1) -+ return NULL; -+ - /* EP device access */ - val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | - (slot << CFG_ADDR_DEV_NUM_SHIFT) | - (fn << CFG_ADDR_FUNC_NUM_SHIFT) | - (where & CFG_ADDR_REG_NUM_MASK) | - (1 & CFG_ADDR_CFG_TYPE_MASK); -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CFG_ADDR, val); -- offset = iproc_pcie_reg_offset(pcie, IPROC_PCIE_CFG_DATA); -- if (iproc_pcie_reg_is_invalid(offset)) -- return NULL; -- else -- return (pcie->base + offset); -+ writel(val, pcie->base + CFG_ADDR_OFFSET); -+ -+ return (pcie->base + CFG_DATA_OFFSET); - } - - static struct pci_ops iproc_pcie_ops = { -@@ -237,29 +138,18 @@ static void iproc_pcie_reset(struct ipro - { - u32 val; - -- if (pcie->type == IPROC_PCIE_PAXC) { -- val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); -- val &= ~PAXC_RESET_MASK; -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); -- udelay(100); -- val |= PAXC_RESET_MASK; -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); -- udelay(100); -- return; -- } -- - /* - * Select perst_b signal as reset source. Put the device into reset, - * and then bring it out of reset - */ -- val = iproc_pcie_read_reg(pcie, IPROC_PCIE_CLK_CTRL); -+ val = readl(pcie->base + CLK_CONTROL_OFFSET); - val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST & - ~RC_PCIE_RST_OUTPUT; -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); -+ writel(val, pcie->base + CLK_CONTROL_OFFSET); - udelay(250); - - val |= RC_PCIE_RST_OUTPUT; -- iproc_pcie_write_reg(pcie, IPROC_PCIE_CLK_CTRL, val); -+ writel(val, pcie->base + CLK_CONTROL_OFFSET); - msleep(100); - } - -@@ -270,14 +160,7 @@ static int iproc_pcie_check_link(struct - u16 pos, link_status; - bool link_is_active = false; - -- /* -- * PAXC connects to emulated endpoint devices directly and does not -- * have a Serdes. Therefore skip the link detection logic here. -- */ -- if (pcie->type == IPROC_PCIE_PAXC) -- return 0; -- -- val = iproc_pcie_read_reg(pcie, IPROC_PCIE_LINK_STATUS); -+ val = readl(pcie->base + PCIE_LINK_STATUS_OFFSET); - if (!(val & PCIE_PHYLINKUP) || !(val & PCIE_DL_ACTIVE)) { - dev_err(pcie->dev, "PHY or data link is INACTIVE!\n"); - return -ENODEV; -@@ -338,7 +221,7 @@ static int iproc_pcie_check_link(struct - - static void iproc_pcie_enable(struct iproc_pcie *pcie) - { -- iproc_pcie_write_reg(pcie, IPROC_PCIE_INTX_EN, SYS_RC_INTX_MASK); -+ writel(SYS_RC_INTX_MASK, pcie->base + SYS_RC_INTX_EN); - } - - /** -@@ -389,15 +272,11 @@ static int iproc_pcie_setup_ob(struct ip - axi_addr -= ob->axi_offset; - - for (i = 0; i < MAX_NUM_OB_WINDOWS; i++) { -- iproc_pcie_ob_write(pcie, IPROC_PCIE_OARR_LO, i, -- lower_32_bits(axi_addr) | OARR_VALID | -- (ob->set_oarr_size ? 1 : 0)); -- iproc_pcie_ob_write(pcie, IPROC_PCIE_OARR_HI, i, -- upper_32_bits(axi_addr)); -- iproc_pcie_ob_write(pcie, IPROC_PCIE_OMAP_LO, i, -- lower_32_bits(pci_addr)); -- iproc_pcie_ob_write(pcie, IPROC_PCIE_OMAP_HI, i, -- upper_32_bits(pci_addr)); -+ writel(lower_32_bits(axi_addr) | OARR_VALID | -+ (ob->set_oarr_size ? 1 : 0), pcie->base + OARR_LO(i)); -+ writel(upper_32_bits(axi_addr), pcie->base + OARR_HI(i)); -+ writel(lower_32_bits(pci_addr), pcie->base + OMAP_LO(i)); -+ writel(upper_32_bits(pci_addr), pcie->base + OMAP_HI(i)); - - size -= ob->window_size; - if (size == 0) -@@ -481,19 +360,6 @@ int iproc_pcie_setup(struct iproc_pcie * - goto err_exit_phy; - } - -- switch (pcie->type) { -- case IPROC_PCIE_PAXB: -- pcie->reg_offsets = iproc_pcie_reg_paxb; -- break; -- case IPROC_PCIE_PAXC: -- pcie->reg_offsets = iproc_pcie_reg_paxc; -- break; -- default: -- dev_err(pcie->dev, "incompatible iProc PCIe interface\n"); -- ret = -EINVAL; -- goto err_power_off_phy; -- } -- - iproc_pcie_reset(pcie); - - if (pcie->need_ob_cfg) { ---- a/drivers/pci/host/pcie-iproc.h -+++ b/drivers/pci/host/pcie-iproc.h -@@ -15,20 +15,6 @@ - #define _PCIE_IPROC_H - - /** -- * iProc PCIe interface type -- * -- * PAXB is the wrapper used in root complex that can be connected to an -- * external endpoint device. -- * -- * PAXC is the wrapper used in root complex dedicated for internal emulated -- * endpoint devices. -- */ --enum iproc_pcie_type { -- IPROC_PCIE_PAXB = 0, -- IPROC_PCIE_PAXC, --}; -- --/** - * iProc PCIe outbound mapping - * @set_oarr_size: indicates the OARR size bit needs to be set - * @axi_offset: offset from the AXI address to the internal address used by -@@ -45,10 +31,7 @@ struct iproc_msi; - - /** - * iProc PCIe device -- * - * @dev: pointer to device data structure -- * @type: iProc PCIe interface type -- * @reg_offsets: register offsets - * @base: PCIe host controller I/O register base - * @base_addr: PCIe host controller register base physical address - * @sysdata: Per PCI controller data (ARM-specific) -@@ -61,8 +44,6 @@ struct iproc_msi; - */ - struct iproc_pcie { - struct device *dev; -- enum iproc_pcie_type type; -- const u16 *reg_offsets; - void __iomem *base; - phys_addr_t base_addr; - #ifdef CONFIG_ARM