aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-5.4/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ipq806x/patches-5.4/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch')
-rw-r--r--target/linux/ipq806x/patches-5.4/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch124
1 files changed, 124 insertions, 0 deletions
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
new file mode 100644
index 0000000000..dde8fbaa7b
--- /dev/null
+++ b/target/linux/ipq806x/patches-5.4/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch
@@ -0,0 +1,124 @@
+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) {