kernel: bump 5.4 to 5.4.73
[openwrt/openwrt.git] / target / linux / mvebu / patches-5.4 / 405-PCI-aardvark-Improve-link-training.patch
1 From 43fc679ced18006b12d918d7a8a4af392b7fbfe7 Mon Sep 17 00:00:00 2001
2 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.behun@nic.cz>
3 Date: Thu, 30 Apr 2020 10:06:17 +0200
4 Subject: [PATCH] PCI: aardvark: Improve link training
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 Currently the aardvark driver trains link in PCIe gen2 mode. This may
10 cause some buggy gen1 cards (such as Compex WLE900VX) to be unstable or
11 even not detected. Moreover when ASPM code tries to retrain link second
12 time, these cards may stop responding and link goes down. If gen1 is
13 used this does not happen.
14
15 Unconditionally forcing gen1 is not a good solution since it may have
16 performance impact on gen2 cards.
17
18 To overcome this, read 'max-link-speed' property (as defined in PCI
19 device tree bindings) and use this as max gen mode. Then iteratively try
20 link training at this mode or lower until successful. After successful
21 link training choose final controller gen based on Negotiated Link Speed
22 from Link Status register, which should match card speed.
23
24 Link: https://lore.kernel.org/r/20200430080625.26070-5-pali@kernel.org
25 Tested-by: Tomasz Maciej Nowak <tmn505@gmail.com>
26 Signed-off-by: Pali Rohár <pali@kernel.org>
27 Signed-off-by: Marek Behún <marek.behun@nic.cz>
28 Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
29 Reviewed-by: Rob Herring <robh@kernel.org>
30 Acked-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
31 ---
32 drivers/pci/controller/pci-aardvark.c | 114 ++++++++++++++++++++------
33 1 file changed, 89 insertions(+), 25 deletions(-)
34
35 --- a/drivers/pci/controller/pci-aardvark.c
36 +++ b/drivers/pci/controller/pci-aardvark.c
37 @@ -39,6 +39,7 @@
38 #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0
39 #define PCIE_CORE_LINK_L0S_ENTRY BIT(0)
40 #define PCIE_CORE_LINK_TRAINING BIT(5)
41 +#define PCIE_CORE_LINK_SPEED_SHIFT 16
42 #define PCIE_CORE_LINK_WIDTH_SHIFT 20
43 #define PCIE_CORE_ERR_CAPCTL_REG 0x118
44 #define PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX BIT(5)
45 @@ -201,6 +202,7 @@ struct advk_pcie {
46 struct mutex msi_used_lock;
47 u16 msi_msg;
48 int root_bus_nr;
49 + int link_gen;
50 struct pci_bridge_emul bridge;
51 };
52
53 @@ -225,20 +227,16 @@ static int advk_pcie_link_up(struct advk
54
55 static int advk_pcie_wait_for_link(struct advk_pcie *pcie)
56 {
57 - struct device *dev = &pcie->pdev->dev;
58 int retries;
59
60 /* check if the link is up or not */
61 for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
62 - if (advk_pcie_link_up(pcie)) {
63 - dev_info(dev, "link up\n");
64 + if (advk_pcie_link_up(pcie))
65 return 0;
66 - }
67
68 usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
69 }
70
71 - dev_err(dev, "link never came up\n");
72 return -ETIMEDOUT;
73 }
74
75 @@ -253,6 +251,85 @@ static void advk_pcie_wait_for_retrain(s
76 }
77 }
78
79 +static int advk_pcie_train_at_gen(struct advk_pcie *pcie, int gen)
80 +{
81 + int ret, neg_gen;
82 + u32 reg;
83 +
84 + /* Setup link speed */
85 + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
86 + reg &= ~PCIE_GEN_SEL_MSK;
87 + if (gen == 3)
88 + reg |= SPEED_GEN_3;
89 + else if (gen == 2)
90 + reg |= SPEED_GEN_2;
91 + else
92 + reg |= SPEED_GEN_1;
93 + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
94 +
95 + /*
96 + * Enable link training. This is not needed in every call to this
97 + * function, just once suffices, but it does not break anything either.
98 + */
99 + reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
100 + reg |= LINK_TRAINING_EN;
101 + advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
102 +
103 + /*
104 + * Start link training immediately after enabling it.
105 + * This solves problems for some buggy cards.
106 + */
107 + reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG);
108 + reg |= PCIE_CORE_LINK_TRAINING;
109 + advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
110 +
111 + ret = advk_pcie_wait_for_link(pcie);
112 + if (ret)
113 + return ret;
114 +
115 + reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG);
116 + neg_gen = (reg >> PCIE_CORE_LINK_SPEED_SHIFT) & 0xf;
117 +
118 + return neg_gen;
119 +}
120 +
121 +static void advk_pcie_train_link(struct advk_pcie *pcie)
122 +{
123 + struct device *dev = &pcie->pdev->dev;
124 + int neg_gen = -1, gen;
125 +
126 + /*
127 + * Try link training at link gen specified by device tree property
128 + * 'max-link-speed'. If this fails, iteratively train at lower gen.
129 + */
130 + for (gen = pcie->link_gen; gen > 0; --gen) {
131 + neg_gen = advk_pcie_train_at_gen(pcie, gen);
132 + if (neg_gen > 0)
133 + break;
134 + }
135 +
136 + if (neg_gen < 0)
137 + goto err;
138 +
139 + /*
140 + * After successful training if negotiated gen is lower than requested,
141 + * train again on negotiated gen. This solves some stability issues for
142 + * some buggy gen1 cards.
143 + */
144 + if (neg_gen < gen) {
145 + gen = neg_gen;
146 + neg_gen = advk_pcie_train_at_gen(pcie, gen);
147 + }
148 +
149 + if (neg_gen == gen) {
150 + dev_info(dev, "link up at gen %i\n", gen);
151 + return;
152 + }
153 +
154 +err:
155 + dev_err(dev, "link never came up\n");
156 +}
157 +
158 static void advk_pcie_setup_hw(struct advk_pcie *pcie)
159 {
160 u32 reg;
161 @@ -288,12 +365,6 @@ static void advk_pcie_setup_hw(struct ad
162 PCIE_CORE_CTRL2_TD_ENABLE;
163 advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);
164
165 - /* Set GEN2 */
166 - reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
167 - reg &= ~PCIE_GEN_SEL_MSK;
168 - reg |= SPEED_GEN_2;
169 - advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
170 -
171 /* Set lane X1 */
172 reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
173 reg &= ~LANE_CNT_MSK;
174 @@ -341,20 +412,7 @@ static void advk_pcie_setup_hw(struct ad
175 */
176 msleep(PCI_PM_D3COLD_WAIT);
177
178 - /* Enable link training */
179 - reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
180 - reg |= LINK_TRAINING_EN;
181 - advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);
182 -
183 - /*
184 - * Start link training immediately after enabling it.
185 - * This solves problems for some buggy cards.
186 - */
187 - reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG);
188 - reg |= PCIE_CORE_LINK_TRAINING;
189 - advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG);
190 -
191 - advk_pcie_wait_for_link(pcie);
192 + advk_pcie_train_link(pcie);
193
194 reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
195 reg |= PCIE_CORE_CMD_MEM_ACCESS_EN |
196 @@ -1035,6 +1093,12 @@ static int advk_pcie_probe(struct platfo
197 return ret;
198 }
199
200 + ret = of_pci_get_max_link_speed(dev->of_node);
201 + if (ret <= 0 || ret > 3)
202 + pcie->link_gen = 3;
203 + else
204 + pcie->link_gen = ret;
205 +
206 advk_pcie_setup_hw(pcie);
207
208 ret = advk_sw_pci_bridge_init(pcie);