aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/ipq806x/patches-4.9/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/ipq806x/patches-4.9/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch')
-rw-r--r--target/linux/ipq806x/patches-4.9/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch127
1 files changed, 127 insertions, 0 deletions
diff --git a/target/linux/ipq806x/patches-4.9/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch b/target/linux/ipq806x/patches-4.9/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch
new file mode 100644
index 0000000000..6c68edfe99
--- /dev/null
+++ b/target/linux/ipq806x/patches-4.9/0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch
@@ -0,0 +1,127 @@
+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>
+---
+ drivers/pci/host/pcie-qcom.c | 62 +++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 53 insertions(+), 9 deletions(-)
+
+--- a/drivers/pci/host/pcie-qcom.c
++++ b/drivers/pci/host/pcie-qcom.c
+@@ -37,7 +37,13 @@
+ #include "pcie-designware.h"
+
+ #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_AXI_MSTR_WR_ADDR_HALT 0x178
+@@ -48,6 +54,18 @@
+ #define PCIE20_CAP 0x70
+
+ #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)
+
+ struct qcom_pcie_resources_v0 {
+ struct clk *iface_clk;
+@@ -64,6 +82,7 @@ struct qcom_pcie_resources_v0 {
+ struct regulator *vdda;
+ struct regulator *vdda_phy;
+ struct regulator *vdda_refclk;
++ uint8_t phy_tx0_term_offset;
+ };
+
+ struct qcom_pcie_resources_v1 {
+@@ -100,6 +119,16 @@ struct qcom_pcie {
+
+ #define to_qcom_pcie(x) container_of(x, struct qcom_pcie, pp)
+
++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(pcie->reset, 1);
+@@ -195,6 +224,10 @@ static int qcom_pcie_get_resources_v0(st
+ 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;
++
+ return 0;
+ }
+
+@@ -254,7 +287,6 @@ static int qcom_pcie_init_v0(struct qcom
+ {
+ struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
+ struct device *dev = pcie->pp.dev;
+- u32 val;
+ int ret;
+
+ ret = reset_control_assert(res->ahb_reset);
+@@ -323,15 +355,27 @@ static int qcom_pcie_init_v0(struct qcom
+ 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) {