treewide: use new procd sysupgrade $UPGRADE_BACKUP variable
[oweals/openwrt.git] / target / linux / ipq806x / patches-4.14 / 0071-3-PCI-qcom-Fixed-IPQ806x-PCIE-init-changes.patch
1 From eddd13215d0f2b549ebc5f0e8796d5b1231f90a0 Mon Sep 17 00:00:00 2001
2 From: Sham Muthayyan <smuthayy@codeaurora.org>
3 Date: Tue, 19 Jul 2016 19:58:22 +0530
4 Subject: PCI: qcom: Fixed IPQ806x PCIE init changes
5
6 Change-Id: Ic319b1aec27a47809284759f8fcb6a8815b7cf7e
7 Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org>
8 ---
9  drivers/pci/host/pcie-qcom.c | 62 +++++++++++++++++++++++++++++++++++++-------
10  1 file changed, 53 insertions(+), 9 deletions(-)
11
12 --- a/drivers/pci/dwc/pcie-qcom.c
13 +++ b/drivers/pci/dwc/pcie-qcom.c
14 @@ -52,7 +52,13 @@
15  #define PCIE_CAP_CPL_TIMEOUT_DISABLE           0x10
16  
17  #define PCIE20_PARF_PHY_CTRL                   0x40
18 +#define PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK      (0x1f << 16)
19 +#define PHY_CTRL_PHY_TX0_TERM_OFFSET(x)                (x << 16)
20 +
21  #define PCIE20_PARF_PHY_REFCLK                 0x4C
22 +#define REF_SSP_EN                             BIT(16)
23 +#define REF_USE_PAD                            BIT(12)
24 +
25  #define PCIE20_PARF_DBI_BASE_ADDR              0x168
26  #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE                0x16C
27  #define PCIE20_PARF_MHI_CLOCK_RESET_CTRL       0x174
28 @@ -83,6 +89,18 @@
29  #define DBI_RO_WR_EN                           1
30  
31  #define PERST_DELAY_US                         1000
32 +/* PARF registers */
33 +#define PCIE20_PARF_PCS_DEEMPH                 0x34
34 +#define PCS_DEEMPH_TX_DEEMPH_GEN1(x)           (x << 16)
35 +#define PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(x)     (x << 8)
36 +#define PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(x)       (x << 0)
37 +
38 +#define PCIE20_PARF_PCS_SWING                  0x38
39 +#define PCS_SWING_TX_SWING_FULL(x)             (x << 8)
40 +#define PCS_SWING_TX_SWING_LOW(x)              (x << 0)
41 +
42 +#define PCIE20_PARF_CONFIG_BITS                        0x50
43 +#define PHY_RX0_EQ(x)                          (x << 24)
44  
45  #define PCIE20_v3_PARF_SLV_ADDR_SPACE_SIZE     0x358
46  #define SLV_ADDR_SPACE_SZ                      0x10000000
47 @@ -102,6 +120,7 @@ struct qcom_pcie_resources_2_1_0 {
48         struct regulator *vdda;
49         struct regulator *vdda_phy;
50         struct regulator *vdda_refclk;
51 +       uint8_t phy_tx0_term_offset;
52  };
53  
54  struct qcom_pcie_resources_1_0_0 {
55 @@ -179,6 +198,16 @@ struct qcom_pcie {
56  
57  #define to_qcom_pcie(x)                dev_get_drvdata((x)->dev)
58  
59 +static inline void
60 +writel_masked(void __iomem *addr, u32 clear_mask, u32 set_mask)
61 +{
62 +       u32 val = readl(addr);
63 +
64 +       val &= ~clear_mask;
65 +       val |= set_mask;
66 +       writel(val, addr);
67 +}
68 +
69  static void qcom_ep_reset_assert(struct qcom_pcie *pcie)
70  {
71         gpiod_set_value_cansleep(pcie->reset, 1);
72 @@ -280,6 +309,10 @@ static int qcom_pcie_get_resources_2_1_0
73         if (IS_ERR(res->ext_reset))
74                 return PTR_ERR(res->ext_reset);
75  
76 +       if (of_property_read_u8(dev->of_node, "phy-tx0-term-offset",
77 +                               &res->phy_tx0_term_offset))
78 +               res->phy_tx0_term_offset = 0;
79 +
80         res->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
81         return PTR_ERR_OR_ZERO(res->phy_reset);
82  }
83 @@ -309,7 +342,6 @@ static int qcom_pcie_init_2_1_0(struct q
84         struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
85         struct dw_pcie *pci = pcie->pci;
86         struct device *dev = pci->dev;
87 -       u32 val;
88         int ret;
89  
90         ret = reset_control_assert(res->ahb_reset);
91 @@ -378,15 +410,26 @@ static int qcom_pcie_init_2_1_0(struct q
92                 goto err_deassert_ahb;
93         }
94  
95 -       /* enable PCIe clocks and resets */
96 -       val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
97 -       val &= ~BIT(0);
98 -       writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
99 -
100 -       /* enable external reference clock */
101 -       val = readl(pcie->parf + PCIE20_PARF_PHY_REFCLK);
102 -       val |= BIT(16);
103 -       writel(val, pcie->parf + PCIE20_PARF_PHY_REFCLK);
104 +       writel_masked(pcie->parf + PCIE20_PARF_PHY_CTRL, BIT(0), 0);
105 +
106 +       /* Set Tx termination offset */
107 +       writel_masked(pcie->parf + PCIE20_PARF_PHY_CTRL,
108 +                     PHY_CTRL_PHY_TX0_TERM_OFFSET_MASK,
109 +                     PHY_CTRL_PHY_TX0_TERM_OFFSET(res->phy_tx0_term_offset));
110 +
111 +       /* PARF programming */
112 +       writel(PCS_DEEMPH_TX_DEEMPH_GEN1(0x18) |
113 +              PCS_DEEMPH_TX_DEEMPH_GEN2_3_5DB(0x18) |
114 +              PCS_DEEMPH_TX_DEEMPH_GEN2_6DB(0x22),
115 +              pcie->parf + PCIE20_PARF_PCS_DEEMPH);
116 +       writel(PCS_SWING_TX_SWING_FULL(0x78) |
117 +              PCS_SWING_TX_SWING_LOW(0x78),
118 +              pcie->parf + PCIE20_PARF_PCS_SWING);
119 +       writel(PHY_RX0_EQ(0x4), pcie->parf + PCIE20_PARF_CONFIG_BITS);
120 +
121 +       /* Enable reference clock */
122 +       writel_masked(pcie->parf + PCIE20_PARF_PHY_REFCLK,
123 +                     REF_USE_PAD, REF_SSP_EN);
124  
125         ret = reset_control_deassert(res->phy_reset);
126         if (ret) {