diff options
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.patch | 124 |
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) { |