diff options
author | Ansuel Smith <ansuelsmth@gmail.com> | 2020-08-08 16:50:04 +0200 |
---|---|---|
committer | Adrian Schmutzler <freifunk@adrianschmutzler.de> | 2020-08-24 14:09:11 +0200 |
commit | 58d2bd88aefef1f3a37b401223fccae374af6c63 (patch) | |
tree | c748931222229e2cffd3e1721f11728a0ce524ad /target/linux/ipq806x/patches-5.4 | |
parent | ba2ddba56b7824008fb3b544b1e1ae5d52ee39e5 (diff) | |
download | upstream-58d2bd88aefef1f3a37b401223fccae374af6c63.tar.gz upstream-58d2bd88aefef1f3a37b401223fccae374af6c63.tar.bz2 upstream-58d2bd88aefef1f3a37b401223fccae374af6c63.zip |
ipq806x: replace pci patchset with upstream version
Changes:
- Update patches
- Update dts with new binding
Tx term offset dropped and replaced with a new compatible
Removed:
- 0071-5-PCI-qcom-Programming-the-PCIE-iATU-for-IPQ806x
Pci init does the same exact thing (was needed in older kernel version)
- 0071-7-pcie-Set-PCIE-MRRS-and-MPS-to-256B
Rejected upstream, can't find any reason to have this. No regression with
testing it on R7800.
Tested on R7800 (ipq8065), R7500 v2 ("ipq8064-v2")
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
Tested-by: Paul Blazejowski <paulb@blazebox.homeip.net> [R7800]
[rebase and refresh]
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
Diffstat (limited to 'target/linux/ipq806x/patches-5.4')
16 files changed, 610 insertions, 562 deletions
diff --git a/target/linux/ipq806x/patches-5.4/0071-2-PCI-qcom-Fixed-IPQ806x-PCIE-reset-changes.patch b/target/linux/ipq806x/patches-5.4/0071-2-PCI-qcom-Fixed-IPQ806x-PCIE-reset-changes.patch deleted file mode 100644 index 5bd865a42e..0000000000 --- a/target/linux/ipq806x/patches-5.4/0071-2-PCI-qcom-Fixed-IPQ806x-PCIE-reset-changes.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 490d103232287eb51c92c49a4ef8865fd0a9d59e Mon Sep 17 00:00:00 2001 -From: Sham Muthayyan <smuthayy@codeaurora.org> -Date: Tue, 19 Jul 2016 18:58:18 +0530 -Subject: PCI: qcom: Fixed IPQ806x PCIE reset changes - -Change-Id: Ia6590e960b9754b1e8b7a51f318788cd63e9e321 -Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org> ---- - ---- a/drivers/pci/controller/dwc/pcie-qcom.c -+++ b/drivers/pci/controller/dwc/pcie-qcom.c -@@ -92,6 +92,7 @@ struct qcom_pcie_resources_2_1_0 { - struct reset_control *ahb_reset; - struct reset_control *por_reset; - struct reset_control *phy_reset; -+ struct reset_control *ext_reset; - struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY]; - }; - -@@ -261,6 +262,10 @@ static int qcom_pcie_get_resources_2_1_0 - if (IS_ERR(res->por_reset)) - return PTR_ERR(res->por_reset); - -+ res->ext_reset = devm_reset_control_get(dev, "ext"); -+ if (IS_ERR(res->ext_reset)) -+ return PTR_ERR(res->ext_reset); -+ - res->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); - return PTR_ERR_OR_ZERO(res->phy_reset); - } -@@ -274,6 +279,7 @@ static void qcom_pcie_deinit_2_1_0(struc - reset_control_assert(res->ahb_reset); - reset_control_assert(res->por_reset); - reset_control_assert(res->pci_reset); -+ reset_control_assert(res->ext_reset); - clk_disable_unprepare(res->iface_clk); - clk_disable_unprepare(res->core_clk); - clk_disable_unprepare(res->phy_clk); -@@ -290,15 +296,21 @@ static int qcom_pcie_init_2_1_0(struct q - u32 val; - int ret; - -+ ret = reset_control_assert(res->ahb_reset); -+ if (ret) { -+ dev_err(dev, "cannot assert ahb reset\n"); -+ return ret; -+ } -+ - ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies); - if (ret < 0) { - dev_err(dev, "cannot enable regulators\n"); - return ret; - } - -- ret = reset_control_assert(res->ahb_reset); -+ ret = reset_control_deassert(res->ext_reset); - if (ret) { -- dev_err(dev, "cannot assert ahb reset\n"); -+ dev_err(dev, "cannot assert ext reset\n"); - goto err_assert_ahb; - } - diff --git a/target/linux/ipq806x/patches-5.4/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch b/target/linux/ipq806x/patches-5.4/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch deleted file mode 100644 index dde8fbaa7b..0000000000 --- a/target/linux/ipq806x/patches-5.4/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch +++ /dev/null @@ -1,124 +0,0 @@ -From eddd13215d0f2b549ebc5f0e8796d5b1231f90a0 Mon Sep 17 00:00:00 2001 -From: Sham Muthayyan <smuthayy@codeaurora.org> -Date: Tue, 19 Jul 2016 19:58:22 +0530 -Subject: PCI: qcom: Fixed IPQ806x PCIE init changes - -Change-Id: Ic319b1aec27a47809284759f8fcb6a8815b7cf7e -Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org> ---- - ---- a/drivers/pci/controller/dwc/pcie-qcom.c -+++ b/drivers/pci/controller/dwc/pcie-qcom.c -@@ -45,7 +45,13 @@ - #define PCIE_CAP_CPL_TIMEOUT_DISABLE 0x10 - - #define PCIE20_PARF_PHY_CTRL 0x40 -+#define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK (0x1f << 16) -+#define PHY_CTRL_PHY_TX0_TERM_OFFSET(x) (x << 16) -+ - #define PCIE20_PARF_PHY_REFCLK 0x4C -+#define REF_SSP_EN BIT(16) -+#define REF_USE_PAD BIT(12) -+ - #define PCIE20_PARF_DBI_BASE_ADDR 0x168 - #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16C - #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL 0x174 -@@ -76,6 +82,18 @@ - #define DBI_RO_WR_EN 1 - - #define PERST_DELAY_US 1000 -+/* PARF registers */ -+#define PCIE20_PARF_PCS_DEEMPH 0x34 -+#define PCS_DEEMPH_TX_DEEMPH_GEN1(x) (x << 16) -+#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) (x << 8) -+#define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) (x << 0) -+ -+#define PCIE20_PARF_PCS_SWING 0x38 -+#define PCS_SWING_TX_SWING_FULL(x) (x << 8) -+#define PCS_SWING_TX_SWING_LOW(x) (x << 0) -+ -+#define PCIE20_PARF_CONFIG_BITS 0x50 -+#define PHY_RX0_EQ(x) (x << 24) - - #define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE 0x358 - #define SLV_ADDR_SPACE_SZ 0x10000000 -@@ -94,6 +112,7 @@ struct qcom_pcie_resources_2_1_0 { - struct reset_control *phy_reset; - struct reset_control *ext_reset; - struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY]; -+ uint8_t phy_tx0_term_offset; - }; - - struct qcom_pcie_resources_1_0_0 { -@@ -173,6 +192,16 @@ struct qcom_pcie { - - #define to_qcom_pcie(x) dev_get_drvdata((x)->dev) - -+static inline void -+writel_masked(void __iomem *addr, u32 clear_mask, u32 set_mask) -+{ -+ u32 val = readl(addr); -+ -+ val &= ~clear_mask; -+ val |= set_mask; -+ writel(val, addr); -+} -+ - static void qcom_ep_reset_assert(struct qcom_pcie *pcie) - { - gpiod_set_value_cansleep(pcie->reset, 1); -@@ -266,6 +295,10 @@ static int qcom_pcie_get_resources_2_1_0 - if (IS_ERR(res->ext_reset)) - return PTR_ERR(res->ext_reset); - -+ if (of_property_read_u8(dev->of_node, "phy-tx0-term-offset", -+ &res->phy_tx0_term_offset)) -+ res->phy_tx0_term_offset = 0; -+ - res->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); - return PTR_ERR_OR_ZERO(res->phy_reset); - } -@@ -293,7 +326,6 @@ static int qcom_pcie_init_2_1_0(struct q - struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; - struct dw_pcie *pci = pcie->pci; - struct device *dev = pci->dev; -- u32 val; - int ret; - - ret = reset_control_assert(res->ahb_reset); -@@ -350,15 +382,26 @@ static int qcom_pcie_init_2_1_0(struct q - goto err_deassert_ahb; - } - -- /* enable PCIe clocks and resets */ -- val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); -- val &= ~BIT(0); -- writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); -- -- /* enable external reference clock */ -- val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK); -- val |= BIT(16); -- writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK); -+ writel_masked(pcie->parf + PCIE20_PARF_PHY_CTRL, BIT(0), 0); -+ -+ /* Set Tx termination offset */ -+ writel_masked(pcie->parf + PCIE20_PARF_PHY_CTRL, -+ PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK, -+ PHY_CTRL_PHY_TX0_TERM_OFFSET(res->phy_tx0_term_offset)); -+ -+ /* PARF programming */ -+ writel(PCS_DEEMPH_TX_DEEMPH_GEN1(0x18) | -+ PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(0x18) | -+ PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(0x22), -+ pcie->parf + PCIE20_PARF_PCS_DEEMPH); -+ writel(PCS_SWING_TX_SWING_FULL(0x78) | -+ PCS_SWING_TX_SWING_LOW(0x78), -+ pcie->parf + PCIE20_PARF_PCS_SWING); -+ writel(PHY_RX0_EQ(0x4), pcie->parf + PCIE20_PARF_CONFIG_BITS); -+ -+ /* Enable reference clock */ -+ writel_masked(pcie->parf + PCIE20_PARF_PHY_REFCLK, -+ REF_USE_PAD, REF_SSP_EN); - - ret = reset_control_deassert(res->phy_reset); - if (ret) { diff --git a/target/linux/ipq806x/patches-5.4/0071-5-PCI-qcom-Programming-the-PCIE-iATU-for-IPQ806x.patch b/target/linux/ipq806x/patches-5.4/0071-5-PCI-qcom-Programming-the-PCIE-iATU-for-IPQ806x.patch deleted file mode 100644 index f6ebe0c0af..0000000000 --- a/target/linux/ipq806x/patches-5.4/0071-5-PCI-qcom-Programming-the-PCIE-iATU-for-IPQ806x.patch +++ /dev/null @@ -1,112 +0,0 @@ -From d27c303e828d7e42f339a459d2abfe30c51698e9 Mon Sep 17 00:00:00 2001 -From: Sham Muthayyan <smuthayy@codeaurora.org> -Date: Tue, 26 Jul 2016 12:28:31 +0530 -Subject: PCI: qcom: Programming the PCIE iATU for IPQ806x - -Resolved PCIE EP detection errors caused due to missing iATU programming. - -Change-Id: Ie95c0f8cb940abc0192a8a3c4e825ddba54b72fe -Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org> ---- - ---- a/drivers/pci/controller/dwc/pcie-qcom.c -+++ b/drivers/pci/controller/dwc/pcie-qcom.c -@@ -76,6 +76,30 @@ - #define PCIE20_CAP_LINK_1 (PCIE20_CAP + 0x14) - #define PCIE_CAP_LINK1_VAL 0x2FD7F - -+#define PCIE20_CAP_LINKCTRLSTATUS (PCIE20_CAP + 0x10) -+ -+#define PCIE20_AXI_MSTR_RESP_COMP_CTRL0 0x818 -+#define PCIE20_AXI_MSTR_RESP_COMP_CTRL1 0x81c -+ -+#define PCIE20_PLR_IATU_VIEWPORT 0x900 -+#define PCIE20_PLR_IATU_REGION_OUTBOUND (0x0 << 31) -+#define PCIE20_PLR_IATU_REGION_INDEX(x) (x << 0) -+ -+#define PCIE20_PLR_IATU_CTRL1 0x904 -+#define PCIE20_PLR_IATU_TYPE_CFG0 (0x4 << 0) -+#define PCIE20_PLR_IATU_TYPE_MEM (0x0 << 0) -+ -+#define PCIE20_PLR_IATU_CTRL2 0x908 -+#define PCIE20_PLR_IATU_ENABLE BIT(31) -+ -+#define PCIE20_PLR_IATU_LBAR 0x90C -+#define PCIE20_PLR_IATU_UBAR 0x910 -+#define PCIE20_PLR_IATU_LAR 0x914 -+#define PCIE20_PLR_IATU_LTAR 0x918 -+#define PCIE20_PLR_IATU_UTAR 0x91c -+ -+#define MSM_PCIE_DEV_CFG_ADDR 0x01000000 -+ - #define PCIE20_PARF_Q2A_FLUSH 0x1AC - - #define PCIE20_MISC_CONTROL_1_REG 0x8BC -@@ -240,6 +264,57 @@ static void qcom_pcie_2_1_0_ltssm_enable - writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL); - } - -+static void qcom_pcie_prog_viewport_cfg0(struct qcom_pcie *pcie, u32 busdev) -+{ -+ struct pcie_port *pp = &pcie->pci->pp; -+ -+ /* -+ * program and enable address translation region 0 (device config -+ * address space); region type config; -+ * axi config address range to device config address range -+ */ -+ writel(PCIE20_PLR_IATU_REGION_OUTBOUND | -+ PCIE20_PLR_IATU_REGION_INDEX(0), -+ pcie->pci->dbi_base + PCIE20_PLR_IATU_VIEWPORT); -+ -+ writel(PCIE20_PLR_IATU_TYPE_CFG0, pcie->pci->dbi_base + PCIE20_PLR_IATU_CTRL1); -+ writel(PCIE20_PLR_IATU_ENABLE, pcie->pci->dbi_base + PCIE20_PLR_IATU_CTRL2); -+ writel(pp->cfg0_base, pcie->pci->dbi_base + PCIE20_PLR_IATU_LBAR); -+ writel((pp->cfg0_base >> 32), pcie->pci->dbi_base + PCIE20_PLR_IATU_UBAR); -+ writel((pp->cfg0_base + pp->cfg0_size - 1), -+ pcie->pci->dbi_base + PCIE20_PLR_IATU_LAR); -+ writel(busdev, pcie->pci->dbi_base + PCIE20_PLR_IATU_LTAR); -+ writel(0, pcie->pci->dbi_base + PCIE20_PLR_IATU_UTAR); -+} -+ -+static void qcom_pcie_prog_viewport_mem2_outbound(struct qcom_pcie *pcie) -+{ -+ struct pcie_port *pp = &pcie->pci->pp; -+ -+ /* -+ * program and enable address translation region 2 (device resource -+ * address space); region type memory; -+ * axi device bar address range to device bar address range -+ */ -+ writel(PCIE20_PLR_IATU_REGION_OUTBOUND | -+ PCIE20_PLR_IATU_REGION_INDEX(2), -+ pcie->pci->dbi_base + PCIE20_PLR_IATU_VIEWPORT); -+ -+ writel(PCIE20_PLR_IATU_TYPE_MEM, pcie->pci->dbi_base + PCIE20_PLR_IATU_CTRL1); -+ writel(PCIE20_PLR_IATU_ENABLE, pcie->pci->dbi_base + PCIE20_PLR_IATU_CTRL2); -+ writel(pp->mem_base, pcie->pci->dbi_base + PCIE20_PLR_IATU_LBAR); -+ writel((pp->mem_base >> 32), pcie->pci->dbi_base + PCIE20_PLR_IATU_UBAR); -+ writel(pp->mem_base + pp->mem_size - 1, -+ pcie->pci->dbi_base + PCIE20_PLR_IATU_LAR); -+ writel(pp->mem_bus_addr, pcie->pci->dbi_base + PCIE20_PLR_IATU_LTAR); -+ writel(upper_32_bits(pp->mem_bus_addr), -+ pcie->pci->dbi_base + PCIE20_PLR_IATU_UTAR); -+ -+ /* 256B PCIE buffer setting */ -+ writel(0x1, pcie->pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL0); -+ writel(0x1, pcie->pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1); -+} -+ - static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie) - { - struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; -@@ -437,6 +512,9 @@ static int qcom_pcie_init_2_1_0(struct q - writel(CFG_BRIDGE_SB_INIT, - pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1); - -+ qcom_pcie_prog_viewport_cfg0(pcie, MSM_PCIE_DEV_CFG_ADDR); -+ qcom_pcie_prog_viewport_mem2_outbound(pcie); -+ - return 0; - - err_deassert_ahb: diff --git a/target/linux/ipq806x/patches-5.4/0071-6-PCI-qcom-Force-GEN1-support.patch b/target/linux/ipq806x/patches-5.4/0071-6-PCI-qcom-Force-GEN1-support.patch deleted file mode 100644 index 275b7c0915..0000000000 --- a/target/linux/ipq806x/patches-5.4/0071-6-PCI-qcom-Force-GEN1-support.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 4910cfd150342ec7b038892262923c725a9c4001 Mon Sep 17 00:00:00 2001 -From: Sham Muthayyan <smuthayy@codeaurora.org> -Date: Wed, 7 Sep 2016 16:44:28 +0530 -Subject: PCI: qcom: Force GEN1 support - -Change-Id: Ica54ddb737d7b851469deab1745f54bf431bd3f0 -Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org> ---- - ---- a/drivers/pci/controller/dwc/pcie-qcom.c -+++ b/drivers/pci/controller/dwc/pcie-qcom.c -@@ -122,6 +122,8 @@ - #define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE 0x358 - #define SLV_ADDR_SPACE_SZ 0x10000000 - -+#define PCIE20_LNK_CONTROL2_LINK_STATUS2 0xA0 -+ - #define QCOM_PCIE_2_1_0_MAX_SUPPLY 3 - struct qcom_pcie_resources_2_1_0 { - struct clk *iface_clk; -@@ -212,6 +214,7 @@ struct qcom_pcie { - struct phy *phy; - struct gpio_desc *reset; - const struct qcom_pcie_ops *ops; -+ uint32_t force_gen1; - }; - - #define to_qcom_pcie(x) dev_get_drvdata((x)->dev) -@@ -504,6 +507,11 @@ static int qcom_pcie_init_2_1_0(struct q - - /* wait for clock acquisition */ - usleep_range(1000, 1500); -+ if (pcie->force_gen1) { -+ writel_relaxed((readl_relaxed( -+ pcie->pci->dbi_base + PCIE20_LNK_CONTROL2_LINK_STATUS2) | 1), -+ pcie->pci->dbi_base + PCIE20_LNK_CONTROL2_LINK_STATUS2); -+ } - - - /* Set the Max TLP size to 2K, instead of using default of 4K */ -@@ -1340,6 +1348,8 @@ static int qcom_pcie_probe(struct platfo - struct dw_pcie *pci; - struct qcom_pcie *pcie; - int ret; -+ uint32_t force_gen1 = 0; -+ struct device_node *np = pdev->dev.of_node; - - pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); - if (!pcie) -@@ -1370,6 +1380,9 @@ static int qcom_pcie_probe(struct platfo - goto err_pm_runtime_put; - } - -+ of_property_read_u32(np, "force_gen1", &force_gen1); -+ pcie->force_gen1 = force_gen1; -+ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf"); - pcie->parf = devm_ioremap_resource(dev, res); - if (IS_ERR(pcie->parf)) { diff --git a/target/linux/ipq806x/patches-5.4/0071-7-pcie-Set-PCIE-MRRS-and-MPS-to-256B.patch b/target/linux/ipq806x/patches-5.4/0071-7-pcie-Set-PCIE-MRRS-and-MPS-to-256B.patch deleted file mode 100644 index 51df248c04..0000000000 --- a/target/linux/ipq806x/patches-5.4/0071-7-pcie-Set-PCIE-MRRS-and-MPS-to-256B.patch +++ /dev/null @@ -1,69 +0,0 @@ -From edff8f777c6321ca89bb950a382f409c4a126e28 Mon Sep 17 00:00:00 2001 -From: Gokul Sriram Palanisamy <gpalan@codeaurora.org> -Date: Thu, 15 Dec 2016 17:38:18 +0530 -Subject: pcie: Set PCIE MRRS and MPS to 256B - -Set Max Read Request Size and Max Payload Size to 256 bytes, -per chip team recommendation. - -Change-Id: I097004be2ced1b3096ffc10c318aae0b2bb155e8 -Signed-off-by: Gokul Sriram Palanisamy <gpalan@codeaurora.org> ---- - drivers/pci/host/pcie-qcom.c | 37 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 37 insertions(+) - -(limited to 'drivers/pci/host/pcie-qcom.c') - ---- a/drivers/pci/controller/dwc/pcie-qcom.c -+++ b/drivers/pci/controller/dwc/pcie-qcom.c -@@ -124,6 +124,14 @@ - - #define PCIE20_LNK_CONTROL2_LINK_STATUS2 0xA0 - -+#define __set(v, a, b) (((v) << (b)) & GENMASK(a, b)) -+#define __mask(a, b) (((1 << ((a) + 1)) - 1) & ~((1 << (b)) - 1)) -+#define PCIE20_DEV_CAS 0x78 -+#define PCIE20_MRRS_MASK __mask(14, 12) -+#define PCIE20_MRRS(x) __set(x, 14, 12) -+#define PCIE20_MPS_MASK __mask(7, 5) -+#define PCIE20_MPS(x) __set(x, 7, 5) -+ - #define QCOM_PCIE_2_1_0_MAX_SUPPLY 3 - struct qcom_pcie_resources_2_1_0 { - struct clk *iface_clk; -@@ -1448,6 +1456,35 @@ err_pm_runtime_put: - return ret; - } - -+static void qcom_pcie_fixup_final(struct pci_dev *dev) -+{ -+ int cap, err; -+ u16 ctl, reg_val; -+ -+ cap = pci_pcie_cap(dev); -+ if (!cap) -+ return; -+ -+ err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); -+ -+ if (err) -+ return; -+ -+ reg_val = ctl; -+ -+ if (((reg_val & PCIE20_MRRS_MASK) >> 12) > 1) -+ reg_val = (reg_val & ~(PCIE20_MRRS_MASK)) | PCIE20_MRRS(0x1); -+ -+ if (((ctl & PCIE20_MPS_MASK) >> 5) > 1) -+ reg_val = (reg_val & ~(PCIE20_MPS_MASK)) | PCIE20_MPS(0x1); -+ -+ err = pci_write_config_word(dev, cap + PCI_EXP_DEVCTL, reg_val); -+ -+ if (err) -+ pr_err("pcie config write failed %d\n", err); -+} -+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, qcom_pcie_fixup_final); -+ - static const struct of_device_id qcom_pcie_match[] = { - { .compatible = "qcom,pcie-apq8084", .data = &ops_1_0_0 }, - { .compatible = "qcom,pcie-ipq8064", .data = &ops_2_1_0 }, diff --git a/target/linux/ipq806x/patches-5.4/0071-8-pcie-qcom-Fixed-pcie_phy_clk-branch-issue.patch b/target/linux/ipq806x/patches-5.4/0071-8-pcie-qcom-Fixed-pcie_phy_clk-branch-issue.patch deleted file mode 100644 index 7cbeb3bed7..0000000000 --- a/target/linux/ipq806x/patches-5.4/0071-8-pcie-qcom-Fixed-pcie_phy_clk-branch-issue.patch +++ /dev/null @@ -1,91 +0,0 @@ -From b74bab6186131eea09459eedf5d737645a3559c9 Mon Sep 17 00:00:00 2001 -From: Abhishek Sahu <absahu@codeaurora.org> -Date: Thu, 22 Dec 2016 11:18:45 +0530 -Subject: pcie: qcom: Fixed pcie_phy_clk branch issue - -Following backtraces are observed in PCIe deinit operation. - - Hardware name: Qualcomm (Flattened Device Tree) - (unwind_backtrace) from [] (show_stack+0x10/0x14) - (show_stack) from [] (dump_stack+0x84/0x98) - (dump_stack) from [] (warn_slowpath_common+0x9c/0xb8) - (warn_slowpath_common) from [] (warn_slowpath_fmt+0x30/0x40) - (warn_slowpath_fmt) from [] (clk_branch_wait+0x114/0x120) - (clk_branch_wait) from [] (clk_core_disable+0xd0/0x1f4) - (clk_core_disable) from [] (clk_disable+0x24/0x30) - (clk_disable) from [] (qcom_pcie_deinit_v0+0x6c/0xb8) - (qcom_pcie_deinit_v0) from [] (qcom_pcie_host_init+0xe0/0xe8) - (qcom_pcie_host_init) from [] (dw_pcie_host_init+0x3b0/0x538) - (dw_pcie_host_init) from [] (qcom_pcie_probe+0x20c/0x2e4) - -pcie_phy_clk is generated for PCIe controller itself and the -GCC controls its branch operation. This error is coming since -the assert operations turn off the parent clock before branch -clock. Now this patch moves clk_disable_unprepare before assert -operations. - -Similarly, during probe function, the clock branch operation -should be done after dessert operation. Currently, it does not -generate any error since bootloader enables the pcie_phy_clk -but the same error is coming during probe, if bootloader -disables pcie_phy_clk. - -Change-Id: Ib29c154d10eb64363d9cc982ce5fd8107af5627d -Signed-off-by: Abhishek Sahu <absahu@codeaurora.org> ---- - drivers/pci/host/pcie-qcom.c | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - ---- a/drivers/pci/controller/dwc/pcie-qcom.c -+++ b/drivers/pci/controller/dwc/pcie-qcom.c -@@ -393,6 +393,7 @@ static void qcom_pcie_deinit_2_1_0(struc - { - struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; - -+ clk_disable_unprepare(res->phy_clk); - reset_control_assert(res->pci_reset); - reset_control_assert(res->axi_reset); - reset_control_assert(res->ahb_reset); -@@ -401,7 +402,6 @@ static void qcom_pcie_deinit_2_1_0(struc - reset_control_assert(res->ext_reset); - clk_disable_unprepare(res->iface_clk); - clk_disable_unprepare(res->core_clk); -- clk_disable_unprepare(res->phy_clk); - clk_disable_unprepare(res->aux_clk); - clk_disable_unprepare(res->ref_clk); - regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies); -@@ -444,12 +444,6 @@ static int qcom_pcie_init_2_1_0(struct q - goto err_clk_core; - } - -- ret = clk_prepare_enable(res->phy_clk); -- if (ret) { -- dev_err(dev, "cannot prepare/enable phy clock\n"); -- goto err_clk_phy; -- } -- - ret = clk_prepare_enable(res->aux_clk); - if (ret) { - dev_err(dev, "cannot prepare/enable aux clock\n"); -@@ -513,6 +507,12 @@ static int qcom_pcie_init_2_1_0(struct q - return ret; - } - -+ ret = clk_prepare_enable(res->phy_clk); -+ if (ret) { -+ dev_err(dev, "cannot prepare/enable phy clock\n"); -+ goto err_deassert_ahb; -+ } -+ - /* wait for clock acquisition */ - usleep_range(1000, 1500); - if (pcie->force_gen1) { -@@ -538,8 +538,6 @@ err_deassert_ahb: - err_clk_ref: - clk_disable_unprepare(res->aux_clk); - err_clk_aux: -- clk_disable_unprepare(res->phy_clk); --err_clk_phy: - clk_disable_unprepare(res->core_clk); - err_clk_core: - clk_disable_unprepare(res->iface_clk); diff --git a/target/linux/ipq806x/patches-5.4/0071-9-pcie-qcom-change-duplicate-pci-reset-to-phy-reset.patch b/target/linux/ipq806x/patches-5.4/0071-9-pcie-qcom-change-duplicate-pci-reset-to-phy-reset.patch deleted file mode 100644 index 3fff78bfd4..0000000000 --- a/target/linux/ipq806x/patches-5.4/0071-9-pcie-qcom-change-duplicate-pci-reset-to-phy-reset.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 1a9c48123bd09f75562b6a2ee0f0a7b2d533cd45 Mon Sep 17 00:00:00 2001 -From: Abhishek Sahu <absahu@codeaurora.org> -Date: Thu, 22 Dec 2016 11:50:49 +0530 -Subject: pcie: qcom: change duplicate pci reset to phy reset - -The deinit issues reset_control_assert for pci twice and -does not contain phy reset. - -Change-Id: Iba849963c7e5f9a2a1063f0e2e89635df70b8a99 -Signed-off-by: Abhishek Sahu <absahu@codeaurora.org> ---- - drivers/pci/host/pcie-qcom.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/pci/controller/dwc/pcie-qcom.c -+++ b/drivers/pci/controller/dwc/pcie-qcom.c -@@ -394,7 +394,7 @@ static void qcom_pcie_deinit_2_1_0(struc - struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; - - clk_disable_unprepare(res->phy_clk); -- reset_control_assert(res->pci_reset); -+ reset_control_assert(res->phy_reset); - reset_control_assert(res->axi_reset); - reset_control_assert(res->ahb_reset); - reset_control_assert(res->por_reset); diff --git a/target/linux/ipq806x/patches-5.4/085-ipq8064-v1.0-dtsi-additions.patch b/target/linux/ipq806x/patches-5.4/085-ipq8064-v1.0-dtsi-additions.patch index 9837fb156d..58f6a46e4f 100644 --- a/target/linux/ipq806x/patches-5.4/085-ipq8064-v1.0-dtsi-additions.patch +++ b/target/linux/ipq806x/patches-5.4/085-ipq8064-v1.0-dtsi-additions.patch @@ -4,7 +4,7 @@ for the (local) additional contents of qcom-ipq8064.dtsi --- a/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi +++ b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi -@@ -56,3 +56,19 @@ +@@ -56,3 +56,7 @@ }; }; }; @@ -12,15 +12,3 @@ for the (local) additional contents of qcom-ipq8064.dtsi +&CPU_SPC { + status = "okay"; +}; -+ -+&pcie0 { -+ phy-tx0-term-offset = <7>; -+}; -+ -+&pcie1 { -+ phy-tx0-term-offset = <7>; -+}; -+ -+&pcie2 { -+ phy-tx0-term-offset = <7>; -+}; diff --git a/target/linux/ipq806x/patches-5.4/0071-1-PCI-qcom-Fixed-IPQ806x-specific-clocks.patch b/target/linux/ipq806x/patches-5.4/093-1-v5.8-ipq806x-PCI-qcom-Add-missing-ipq806x-clocks-in-PCIe-driver.patch index 3a3e0a0000..7eb79cae4d 100644 --- a/target/linux/ipq806x/patches-5.4/0071-1-PCI-qcom-Fixed-IPQ806x-specific-clocks.patch +++ b/target/linux/ipq806x/patches-5.4/093-1-v5.8-ipq806x-PCI-qcom-Add-missing-ipq806x-clocks-in-PCIe-driver.patch @@ -1,11 +1,21 @@ -From 86655aa14304ca88a8ce8847276147dbc1a83238 Mon Sep 17 00:00:00 2001 -From: Sham Muthayyan <smuthayy@codeaurora.org> -Date: Tue, 19 Jul 2016 18:44:49 +0530 -Subject: PCI: qcom: Fixed IPQ806x specific clocks +From 8b6f0330b5f9a7543356bfa9e76d580f03aa2c1e Mon Sep 17 00:00:00 2001 +From: Ansuel Smith <ansuelsmth@gmail.com> +Date: Mon, 15 Jun 2020 23:05:57 +0200 +Subject: PCI: qcom: Add missing ipq806x clocks in PCIe driver -Change-Id: I488e1bc707d6a22b37a338f41935e3922009ba5e +Aux and Ref clk are missing in PCIe qcom driver. Add support for this +optional clks for ipq8064/apq8064 SoC. + +Link: https://lore.kernel.org/r/20200615210608.21469-2-ansuelsmth@gmail.com +Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver") Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org> +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> +Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Reviewed-by: Rob Herring <robh@kernel.org> +Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com> --- + drivers/pci/controller/dwc/pcie-qcom.c | 38 +++++++++++++++++++++++++++++----- + 1 file changed, 33 insertions(+), 5 deletions(-) --- a/drivers/pci/controller/dwc/pcie-qcom.c +++ b/drivers/pci/controller/dwc/pcie-qcom.c @@ -22,11 +32,11 @@ Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org> if (IS_ERR(res->phy_clk)) return PTR_ERR(res->phy_clk); -+ res->aux_clk = devm_clk_get(dev, "aux"); ++ res->aux_clk = devm_clk_get_optional(dev, "aux"); + if (IS_ERR(res->aux_clk)) + return PTR_ERR(res->aux_clk); + -+ res->ref_clk = devm_clk_get(dev, "ref"); ++ res->ref_clk = devm_clk_get_optional(dev, "ref"); + if (IS_ERR(res->ref_clk)) + return PTR_ERR(res->ref_clk); + diff --git a/target/linux/ipq806x/patches-5.4/093-2-v5.8-ipq806x-PCI-qcom-Change-duplicate-PCI-reset-to-phy-reset.patch b/target/linux/ipq806x/patches-5.4/093-2-v5.8-ipq806x-PCI-qcom-Change-duplicate-PCI-reset-to-phy-reset.patch new file mode 100644 index 0000000000..a2d44a4fb0 --- /dev/null +++ b/target/linux/ipq806x/patches-5.4/093-2-v5.8-ipq806x-PCI-qcom-Change-duplicate-PCI-reset-to-phy-reset.patch @@ -0,0 +1,72 @@ +From dd58318c019f10bc94db36df66af6c55d4c0cbba Mon Sep 17 00:00:00 2001 +From: Abhishek Sahu <absahu@codeaurora.org> +Date: Mon, 15 Jun 2020 23:05:59 +0200 +Subject: PCI: qcom: Change duplicate PCI reset to phy reset + +The deinit issues reset_control_assert for PCI twice and does not contain +phy reset. + +Link: https://lore.kernel.org/r/20200615210608.21469-4-ansuelsmth@gmail.com +Signed-off-by: Abhishek Sahu <absahu@codeaurora.org> +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> +Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Reviewed-by: Rob Herring <robh@kernel.org> +Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com> +--- + drivers/pci/controller/dwc/pcie-qcom.c | 18 ++++++++---------- + 1 file changed, 8 insertions(+), 10 deletions(-) + +--- a/drivers/pci/controller/dwc/pcie-qcom.c ++++ b/drivers/pci/controller/dwc/pcie-qcom.c +@@ -269,14 +269,14 @@ static void qcom_pcie_deinit_2_1_0(struc + { + struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; + ++ clk_disable_unprepare(res->phy_clk); + reset_control_assert(res->pci_reset); + reset_control_assert(res->axi_reset); + reset_control_assert(res->ahb_reset); + reset_control_assert(res->por_reset); +- reset_control_assert(res->pci_reset); ++ reset_control_assert(res->phy_reset); + clk_disable_unprepare(res->iface_clk); + clk_disable_unprepare(res->core_clk); +- clk_disable_unprepare(res->phy_clk); + clk_disable_unprepare(res->aux_clk); + clk_disable_unprepare(res->ref_clk); + regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies); +@@ -314,12 +314,6 @@ static int qcom_pcie_init_2_1_0(struct q + goto err_clk_core; + } + +- ret = clk_prepare_enable(res->phy_clk); +- if (ret) { +- dev_err(dev, "cannot prepare/enable phy clock\n"); +- goto err_clk_phy; +- } +- + ret = clk_prepare_enable(res->aux_clk); + if (ret) { + dev_err(dev, "cannot prepare/enable aux clock\n"); +@@ -372,6 +366,12 @@ static int qcom_pcie_init_2_1_0(struct q + return ret; + } + ++ ret = clk_prepare_enable(res->phy_clk); ++ if (ret) { ++ dev_err(dev, "cannot prepare/enable phy clock\n"); ++ goto err_deassert_ahb; ++ } ++ + /* wait for clock acquisition */ + usleep_range(1000, 1500); + +@@ -389,8 +389,6 @@ err_deassert_ahb: + err_clk_ref: + clk_disable_unprepare(res->aux_clk); + err_clk_aux: +- clk_disable_unprepare(res->phy_clk); +-err_clk_phy: + clk_disable_unprepare(res->core_clk); + err_clk_core: + clk_disable_unprepare(res->iface_clk); diff --git a/target/linux/ipq806x/patches-5.4/093-3-v5.8-ipq806x-PCI-qcom-Add-missing-reset-for-ipq806x.patch b/target/linux/ipq806x/patches-5.4/093-3-v5.8-ipq806x-PCI-qcom-Add-missing-reset-for-ipq806x.patch new file mode 100644 index 0000000000..e9595dc2a9 --- /dev/null +++ b/target/linux/ipq806x/patches-5.4/093-3-v5.8-ipq806x-PCI-qcom-Add-missing-reset-for-ipq806x.patch @@ -0,0 +1,62 @@ +From ee367e2cdd2202b5714982739e684543cd2cee0e Mon Sep 17 00:00:00 2001 +From: Ansuel Smith <ansuelsmth@gmail.com> +Date: Mon, 15 Jun 2020 23:06:00 +0200 +Subject: PCI: qcom: Add missing reset for ipq806x + +Add missing ext reset used by ipq8064 SoC in PCIe qcom driver. + +Link: https://lore.kernel.org/r/20200615210608.21469-5-ansuelsmth@gmail.com +Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver") +Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org> +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> +Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Reviewed-by: Rob Herring <robh@kernel.org> +Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> +Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com> +Cc: stable@vger.kernel.org # v4.5+ +--- + drivers/pci/controller/dwc/pcie-qcom.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/pci/controller/dwc/pcie-qcom.c ++++ b/drivers/pci/controller/dwc/pcie-qcom.c +@@ -92,6 +92,7 @@ struct qcom_pcie_resources_2_1_0 { + struct reset_control *ahb_reset; + struct reset_control *por_reset; + struct reset_control *phy_reset; ++ struct reset_control *ext_reset; + struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY]; + }; + +@@ -261,6 +262,10 @@ static int qcom_pcie_get_resources_2_1_0 + if (IS_ERR(res->por_reset)) + return PTR_ERR(res->por_reset); + ++ res->ext_reset = devm_reset_control_get_optional_exclusive(dev, "ext"); ++ if (IS_ERR(res->ext_reset)) ++ return PTR_ERR(res->ext_reset); ++ + res->phy_reset = devm_reset_control_get_exclusive(dev, "phy"); + return PTR_ERR_OR_ZERO(res->phy_reset); + } +@@ -274,6 +279,7 @@ static void qcom_pcie_deinit_2_1_0(struc + reset_control_assert(res->axi_reset); + reset_control_assert(res->ahb_reset); + reset_control_assert(res->por_reset); ++ reset_control_assert(res->ext_reset); + reset_control_assert(res->phy_reset); + clk_disable_unprepare(res->iface_clk); + clk_disable_unprepare(res->core_clk); +@@ -332,6 +338,12 @@ static int qcom_pcie_init_2_1_0(struct q + goto err_deassert_ahb; + } + ++ ret = reset_control_deassert(res->ext_reset); ++ if (ret) { ++ dev_err(dev, "cannot deassert ext reset\n"); ++ goto err_deassert_ahb; ++ } ++ + /* enable PCIe clocks and resets */ + val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); + val &= ~BIT(0); diff --git a/target/linux/ipq806x/patches-5.4/093-4-v5.8-ipq806x-PCI-qcom-Use-bulk-clk-api-and-assert-on-error.patch b/target/linux/ipq806x/patches-5.4/093-4-v5.8-ipq806x-PCI-qcom-Use-bulk-clk-api-and-assert-on-error.patch new file mode 100644 index 0000000000..4d2da5f768 --- /dev/null +++ b/target/linux/ipq806x/patches-5.4/093-4-v5.8-ipq806x-PCI-qcom-Use-bulk-clk-api-and-assert-on-error.patch @@ -0,0 +1,226 @@ +From 6a114526af4689938863bf34976c83bfd279f517 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith <ansuelsmth@gmail.com> +Date: Mon, 15 Jun 2020 23:06:02 +0200 +Subject: PCI: qcom: Use bulk clk api and assert on error + +Rework 2.1.0 revision to use bulk clk api and fix missing assert on +reset_control_deassert error. + +Link: https://lore.kernel.org/r/20200615210608.21469-7-ansuelsmth@gmail.com +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> +Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Reviewed-by: Rob Herring <robh@kernel.org> +Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com> +--- + drivers/pci/controller/dwc/pcie-qcom.c | 131 ++++++++++++--------------------- + 1 file changed, 46 insertions(+), 85 deletions(-) + +--- a/drivers/pci/controller/dwc/pcie-qcom.c ++++ b/drivers/pci/controller/dwc/pcie-qcom.c +@@ -81,12 +81,9 @@ + #define SLV_ADDR_SPACE_SZ 0x10000000 + + #define QCOM_PCIE_2_1_0_MAX_SUPPLY 3 ++#define QCOM_PCIE_2_1_0_MAX_CLOCKS 5 + struct qcom_pcie_resources_2_1_0 { +- struct clk *iface_clk; +- struct clk *core_clk; +- struct clk *phy_clk; +- struct clk *aux_clk; +- struct clk *ref_clk; ++ struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS]; + struct reset_control *pci_reset; + struct reset_control *axi_reset; + struct reset_control *ahb_reset; +@@ -226,25 +223,21 @@ static int qcom_pcie_get_resources_2_1_0 + if (ret) + return ret; + +- res->iface_clk = devm_clk_get(dev, "iface"); +- if (IS_ERR(res->iface_clk)) +- return PTR_ERR(res->iface_clk); +- +- res->core_clk = devm_clk_get(dev, "core"); +- if (IS_ERR(res->core_clk)) +- return PTR_ERR(res->core_clk); +- +- res->phy_clk = devm_clk_get(dev, "phy"); +- if (IS_ERR(res->phy_clk)) +- return PTR_ERR(res->phy_clk); +- +- res->aux_clk = devm_clk_get_optional(dev, "aux"); +- if (IS_ERR(res->aux_clk)) +- return PTR_ERR(res->aux_clk); +- +- res->ref_clk = devm_clk_get_optional(dev, "ref"); +- if (IS_ERR(res->ref_clk)) +- return PTR_ERR(res->ref_clk); ++ res->clks[0].id = "iface"; ++ res->clks[1].id = "core"; ++ res->clks[2].id = "phy"; ++ res->clks[3].id = "aux"; ++ res->clks[4].id = "ref"; ++ ++ /* iface, core, phy are required */ ++ ret = devm_clk_bulk_get(dev, 3, res->clks); ++ if (ret < 0) ++ return ret; ++ ++ /* aux, ref are optional */ ++ ret = devm_clk_bulk_get_optional(dev, 2, res->clks + 3); ++ if (ret < 0) ++ return ret; + + res->pci_reset = devm_reset_control_get_exclusive(dev, "pci"); + if (IS_ERR(res->pci_reset)) +@@ -274,17 +267,13 @@ static void qcom_pcie_deinit_2_1_0(struc + { + struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; + +- clk_disable_unprepare(res->phy_clk); ++ clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks); + reset_control_assert(res->pci_reset); + reset_control_assert(res->axi_reset); + reset_control_assert(res->ahb_reset); + reset_control_assert(res->por_reset); + reset_control_assert(res->ext_reset); + reset_control_assert(res->phy_reset); +- clk_disable_unprepare(res->iface_clk); +- clk_disable_unprepare(res->core_clk); +- clk_disable_unprepare(res->aux_clk); +- clk_disable_unprepare(res->ref_clk); + regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies); + } + +@@ -302,36 +291,6 @@ static int qcom_pcie_init_2_1_0(struct q + return ret; + } + +- ret = reset_control_assert(res->ahb_reset); +- if (ret) { +- dev_err(dev, "cannot assert ahb reset\n"); +- goto err_assert_ahb; +- } +- +- ret = clk_prepare_enable(res->iface_clk); +- if (ret) { +- dev_err(dev, "cannot prepare/enable iface clock\n"); +- goto err_assert_ahb; +- } +- +- ret = clk_prepare_enable(res->core_clk); +- if (ret) { +- dev_err(dev, "cannot prepare/enable core clock\n"); +- goto err_clk_core; +- } +- +- ret = clk_prepare_enable(res->aux_clk); +- if (ret) { +- dev_err(dev, "cannot prepare/enable aux clock\n"); +- goto err_clk_aux; +- } +- +- ret = clk_prepare_enable(res->ref_clk); +- if (ret) { +- dev_err(dev, "cannot prepare/enable ref clock\n"); +- goto err_clk_ref; +- } +- + ret = reset_control_deassert(res->ahb_reset); + if (ret) { + dev_err(dev, "cannot deassert ahb reset\n"); +@@ -341,48 +300,46 @@ static int qcom_pcie_init_2_1_0(struct q + ret = reset_control_deassert(res->ext_reset); + if (ret) { + dev_err(dev, "cannot deassert ext reset\n"); +- goto err_deassert_ahb; ++ goto err_deassert_ext; + } + +- /* enable PCIe clocks and resets */ +- val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); +- val &= ~BIT(0); +- writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); +- +- /* enable external reference clock */ +- val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK); +- val |= BIT(16); +- writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK); +- + ret = reset_control_deassert(res->phy_reset); + if (ret) { + dev_err(dev, "cannot deassert phy reset\n"); +- return ret; ++ goto err_deassert_phy; + } + + ret = reset_control_deassert(res->pci_reset); + if (ret) { + dev_err(dev, "cannot deassert pci reset\n"); +- return ret; ++ goto err_deassert_pci; + } + + ret = reset_control_deassert(res->por_reset); + if (ret) { + dev_err(dev, "cannot deassert por reset\n"); +- return ret; ++ goto err_deassert_por; + } + + ret = reset_control_deassert(res->axi_reset); + if (ret) { + dev_err(dev, "cannot deassert axi reset\n"); +- return ret; ++ goto err_deassert_axi; + } + +- ret = clk_prepare_enable(res->phy_clk); +- if (ret) { +- dev_err(dev, "cannot prepare/enable phy clock\n"); +- goto err_deassert_ahb; +- } ++ ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks); ++ if (ret) ++ goto err_clks; ++ ++ /* enable PCIe clocks and resets */ ++ val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); ++ val &= ~BIT(0); ++ writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); ++ ++ /* enable external reference clock */ ++ val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK); ++ val |= BIT(16); ++ writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK); + + /* wait for clock acquisition */ + usleep_range(1000, 1500); +@@ -396,15 +353,19 @@ static int qcom_pcie_init_2_1_0(struct q + + return 0; + ++err_clks: ++ reset_control_assert(res->axi_reset); ++err_deassert_axi: ++ reset_control_assert(res->por_reset); ++err_deassert_por: ++ reset_control_assert(res->pci_reset); ++err_deassert_pci: ++ reset_control_assert(res->phy_reset); ++err_deassert_phy: ++ reset_control_assert(res->ext_reset); ++err_deassert_ext: ++ reset_control_assert(res->ahb_reset); + err_deassert_ahb: +- clk_disable_unprepare(res->ref_clk); +-err_clk_ref: +- clk_disable_unprepare(res->aux_clk); +-err_clk_aux: +- clk_disable_unprepare(res->core_clk); +-err_clk_core: +- clk_disable_unprepare(res->iface_clk); +-err_assert_ahb: + regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies); + + return ret; diff --git a/target/linux/ipq806x/patches-5.4/093-5-v5.8-ipq806x-PCI-qcom-Define-some-PARF-params-needed-for-ipq8064-SoC.patch b/target/linux/ipq806x/patches-5.4/093-5-v5.8-ipq806x-PCI-qcom-Define-some-PARF-params-needed-for-ipq8064-SoC.patch new file mode 100644 index 0000000000..ff3f34cbf8 --- /dev/null +++ b/target/linux/ipq806x/patches-5.4/093-5-v5.8-ipq806x-PCI-qcom-Define-some-PARF-params-needed-for-ipq8064-SoC.patch @@ -0,0 +1,67 @@ +From 5149901e9e6deca487c01cc434a3ac4125c7b00b Mon Sep 17 00:00:00 2001 +From: Ansuel Smith <ansuelsmth@gmail.com> +Date: Mon, 15 Jun 2020 23:06:03 +0200 +Subject: PCI: qcom: Define some PARF params needed for ipq8064 SoC + +Set some specific value for Tx De-Emphasis, Tx Swing and Rx equalization +needed on some ipq8064 based device (Netgear R7800 for example). Without +this the system locks on kernel load. + +Link: https://lore.kernel.org/r/20200615210608.21469-8-ansuelsmth@gmail.com +Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver") +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> +Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Reviewed-by: Rob Herring <robh@kernel.org> +Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com> +Cc: stable@vger.kernel.org # v4.5+ +--- + drivers/pci/controller/dwc/pcie-qcom.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/drivers/pci/controller/dwc/pcie-qcom.c ++++ b/drivers/pci/controller/dwc/pcie-qcom.c +@@ -76,6 +76,18 @@ + #define DBI_RO_WR_EN 1 + + #define PERST_DELAY_US 1000 ++/* PARF registers */ ++#define PCIE20_PARF_PCS_DEEMPH 0x34 ++#define PCS_DEEMPH_TX_DEEMPH_GEN1(x) ((x) << 16) ++#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x) ((x) << 8) ++#define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x) ((x) << 0) ++ ++#define PCIE20_PARF_PCS_SWING 0x38 ++#define PCS_SWING_TX_SWING_FULL(x) ((x) << 8) ++#define PCS_SWING_TX_SWING_LOW(x) ((x) << 0) ++ ++#define PCIE20_PARF_CONFIG_BITS 0x50 ++#define PHY_RX0_EQ(x) ((x) << 24) + + #define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE 0x358 + #define SLV_ADDR_SPACE_SZ 0x10000000 +@@ -282,6 +294,7 @@ static int qcom_pcie_init_2_1_0(struct q + struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0; + struct dw_pcie *pci = pcie->pci; + struct device *dev = pci->dev; ++ struct device_node *node = dev->of_node; + u32 val; + int ret; + +@@ -336,6 +349,17 @@ static int qcom_pcie_init_2_1_0(struct q + val &= ~BIT(0); + writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); + ++ if (of_device_is_compatible(node, "qcom,pcie-ipq8064")) { ++ writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) | ++ PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(24) | ++ PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(34), ++ pcie->parf + PCIE20_PARF_PCS_DEEMPH); ++ writel(PCS_SWING_TX_SWING_FULL(120) | ++ PCS_SWING_TX_SWING_LOW(120), ++ pcie->parf + PCIE20_PARF_PCS_SWING); ++ writel(PHY_RX0_EQ(4), pcie->parf + PCIE20_PARF_CONFIG_BITS); ++ } ++ + /* enable external reference clock */ + val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK); + val |= BIT(16); diff --git a/target/linux/ipq806x/patches-5.4/093-6-v5.8-ipq806x-PCI-qcom-Add-support-for-tx-term-offset-for-rev-2_1_0.patch b/target/linux/ipq806x/patches-5.4/093-6-v5.8-ipq806x-PCI-qcom-Add-support-for-tx-term-offset-for-rev-2_1_0.patch new file mode 100644 index 0000000000..911c18e69d --- /dev/null +++ b/target/linux/ipq806x/patches-5.4/093-6-v5.8-ipq806x-PCI-qcom-Add-support-for-tx-term-offset-for-rev-2_1_0.patch @@ -0,0 +1,55 @@ +From de3c4bf648975ea0b1d344d811e9b0748907b47c Mon Sep 17 00:00:00 2001 +From: Ansuel Smith <ansuelsmth@gmail.com> +Date: Mon, 15 Jun 2020 23:06:04 +0200 +Subject: PCI: qcom: Add support for tx term offset for rev 2.1.0 + +Add tx term offset support to pcie qcom driver need in some revision of +the ipq806x SoC. Ipq8064 needs tx term offset set to 7. + +Link: https://lore.kernel.org/r/20200615210608.21469-9-ansuelsmth@gmail.com +Fixes: 82a823833f4e ("PCI: qcom: Add Qualcomm PCIe controller driver") +Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org> +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> +Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com> +Cc: stable@vger.kernel.org # v4.5+ +--- + drivers/pci/controller/dwc/pcie-qcom.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/dwc/pcie-qcom.c ++++ b/drivers/pci/controller/dwc/pcie-qcom.c +@@ -45,7 +45,13 @@ + #define PCIE_CAP_CPL_TIMEOUT_DISABLE 0x10 + + #define PCIE20_PARF_PHY_CTRL 0x40 ++#define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK GENMASK(20, 16) ++#define PHY_CTRL_PHY_TX0_TERM_OFFSET(x) ((x) << 16) ++ + #define PCIE20_PARF_PHY_REFCLK 0x4C ++#define PHY_REFCLK_SSP_EN BIT(16) ++#define PHY_REFCLK_USE_PAD BIT(12) ++ + #define PCIE20_PARF_DBI_BASE_ADDR 0x168 + #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16C + #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL 0x174 +@@ -360,9 +366,18 @@ static int qcom_pcie_init_2_1_0(struct q + writel(PHY_RX0_EQ(4), pcie->parf + PCIE20_PARF_CONFIG_BITS); + } + ++ if (of_device_is_compatible(node, "qcom,pcie-ipq8064")) { ++ /* set TX termination offset */ ++ val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL); ++ val &= ~PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK; ++ val |= PHY_CTRL_PHY_TX0_TERM_OFFSET(7); ++ writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); ++ } ++ + /* enable external reference clock */ + val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK); +- val |= BIT(16); ++ val &= ~PHY_REFCLK_USE_PAD; ++ val |= PHY_REFCLK_SSP_EN; + writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK); + + /* wait for clock acquisition */ diff --git a/target/linux/ipq806x/patches-5.4/093-7-v5.8-ipq806x-PCI-qcom-Add-ipq8064-rev2-variant.patch b/target/linux/ipq806x/patches-5.4/093-7-v5.8-ipq806x-PCI-qcom-Add-ipq8064-rev2-variant.patch new file mode 100644 index 0000000000..4e8fa41f35 --- /dev/null +++ b/target/linux/ipq806x/patches-5.4/093-7-v5.8-ipq806x-PCI-qcom-Add-ipq8064-rev2-variant.patch @@ -0,0 +1,36 @@ +From 8df093fe2ae1717389df0dcdc620c02cc35abb21 Mon Sep 17 00:00:00 2001 +From: Ansuel Smith <ansuelsmth@gmail.com> +Date: Mon, 15 Jun 2020 23:06:05 +0200 +Subject: PCI: qcom: Add ipq8064 rev2 variant + +Ipq8064-v2 have tx term offset set to 0. Introduce this variant to permit +different offset based on the revision. + +Link: https://lore.kernel.org/r/20200615210608.21469-10-ansuelsmth@gmail.com +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> +Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com> +--- + drivers/pci/controller/dwc/pcie-qcom.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/pci/controller/dwc/pcie-qcom.c ++++ b/drivers/pci/controller/dwc/pcie-qcom.c +@@ -355,7 +355,8 @@ static int qcom_pcie_init_2_1_0(struct q + val &= ~BIT(0); + writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL); + +- if (of_device_is_compatible(node, "qcom,pcie-ipq8064")) { ++ if (of_device_is_compatible(node, "qcom,pcie-ipq8064") || ++ of_device_is_compatible(node, "qcom,pcie-ipq8064-v2")) { + writel(PCS_DEEMPH_TX_DEEMPH_GEN1(24) | + PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(24) | + PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(34), +@@ -1315,6 +1316,7 @@ err_pm_runtime_put: + static const struct of_device_id qcom_pcie_match[] = { + { .compatible = "qcom,pcie-apq8084", .data = &ops_1_0_0 }, + { .compatible = "qcom,pcie-ipq8064", .data = &ops_2_1_0 }, ++ { .compatible = "qcom,pcie-ipq8064-v2", .data = &ops_2_1_0 }, + { .compatible = "qcom,pcie-apq8064", .data = &ops_2_1_0 }, + { .compatible = "qcom,pcie-msm8996", .data = &ops_2_3_2 }, + { .compatible = "qcom,pcie-ipq8074", .data = &ops_2_3_3 }, diff --git a/target/linux/ipq806x/patches-5.4/093-8-v5.8-ipq806x-PCI-qcom-Support-pci-speed-set-for-ipq806x.patch b/target/linux/ipq806x/patches-5.4/093-8-v5.8-ipq806x-PCI-qcom-Support-pci-speed-set-for-ipq806x.patch new file mode 100644 index 0000000000..9f60f14619 --- /dev/null +++ b/target/linux/ipq806x/patches-5.4/093-8-v5.8-ipq806x-PCI-qcom-Support-pci-speed-set-for-ipq806x.patch @@ -0,0 +1,74 @@ +From 51ed2c2b60265006bde7531d10993cf24def0aee Mon Sep 17 00:00:00 2001 +From: Sham Muthayyan <smuthayy@codeaurora.org> +Date: Mon, 15 Jun 2020 23:06:07 +0200 +Subject: PCI: qcom: Support pci speed set for ipq806x + +Some SoC based on ipq8064/5 needs to be limited to pci GEN1 speed due to +some hardware limitations. Add support for speed setting defined by the +max-link-speed binding. If not defined the max speed is set to GEN2 by +default. + +Link: https://lore.kernel.org/r/20200615210608.21469-12-ansuelsmth@gmail.com +Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org> +Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> +Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Reviewed-by: Rob Herring <robh@kernel.org> +Acked-by: Stanimir Varbanov <svarbanov@mm-sol.com> +--- + +Backported with light changes: +* One include is missing in kernel 5.4 + + drivers/pci/controller/dwc/pcie-qcom.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/pci/controller/dwc/pcie-qcom.c ++++ b/drivers/pci/controller/dwc/pcie-qcom.c +@@ -27,6 +27,7 @@ + #include <linux/slab.h> + #include <linux/types.h> + ++#include "../../pci.h" + #include "pcie-designware.h" + + #define PCIE20_PARF_SYS_CTRL 0x00 +@@ -98,6 +99,8 @@ + #define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE 0x358 + #define SLV_ADDR_SPACE_SZ 0x10000000 + ++#define PCIE20_LNK_CONTROL2_LINK_STATUS2 0xa0 ++ + #define QCOM_PCIE_2_1_0_MAX_SUPPLY 3 + #define QCOM_PCIE_2_1_0_MAX_CLOCKS 5 + struct qcom_pcie_resources_2_1_0 { +@@ -184,6 +187,7 @@ struct qcom_pcie { + struct phy *phy; + struct gpio_desc *reset; + const struct qcom_pcie_ops *ops; ++ int gen; + }; + + #define to_qcom_pcie(x) dev_get_drvdata((x)->dev) +@@ -384,6 +388,11 @@ static int qcom_pcie_init_2_1_0(struct q + /* wait for clock acquisition */ + usleep_range(1000, 1500); + ++ if (pcie->gen == 1) { ++ val = readl(pci->dbi_base + PCIE20_LNK_CONTROL2_LINK_STATUS2); ++ val |= PCI_EXP_LNKSTA_CLS_2_5GB; ++ writel(val, pci->dbi_base + PCIE20_LNK_CONTROL2_LINK_STATUS2); ++ } + + /* Set the Max TLP size to 2K, instead of using default of 4K */ + writel(CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K, +@@ -1248,6 +1257,10 @@ static int qcom_pcie_probe(struct platfo + goto err_pm_runtime_put; + } + ++ pcie->gen = of_pci_get_max_link_speed(pdev->dev.of_node); ++ if (pcie->gen < 0) ++ pcie->gen = 2; ++ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "parf"); + pcie->parf = devm_ioremap_resource(dev, res); + if (IS_ERR(pcie->parf)) { |