blob: 0ab3ab6383c8cb33b8f5eecb24d30e4fd2de9b77 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Wills Wang1d3d0f12016-03-16 16:59:52 +08002/*
3 * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
Rosy Song61290fb2019-03-16 09:24:44 +08004 * Copyright (C) 2018-2019 Rosy Song <rosysong@rosinson.com>
Wills Wang1d3d0f12016-03-16 16:59:52 +08005 */
6
7#include <common.h>
Masahiro Yamada1221ce42016-09-21 11:28:55 +09008#include <linux/errno.h>
Wills Wang1d3d0f12016-03-16 16:59:52 +08009#include <asm/io.h>
10#include <asm/addrspace.h>
11#include <asm/types.h>
12#include <mach/ath79.h>
13#include <mach/ar71xx_regs.h>
14
Rosy Song61290fb2019-03-16 09:24:44 +080015/* QCA956X ETH_SGMII_SERDES Registers */
16#define SGMII_SERDES_RES_CALIBRATION_LSB 23
17#define SGMII_SERDES_RES_CALIBRATION_MASK 0x07800000
18#define SGMII_SERDES_RES_CALIBRATION_SET(x) \
19 (((x) << SGMII_SERDES_RES_CALIBRATION_LSB) & SGMII_SERDES_RES_CALIBRATION_MASK)
20#define SGMII_SERDES_CDR_BW_LSB 1
21#define SGMII_SERDES_CDR_BW_MASK 0x00000006
22#define SGMII_SERDES_CDR_BW_SET(x) \
23 (((x) << SGMII_SERDES_CDR_BW_LSB) & SGMII_SERDES_CDR_BW_MASK)
24#define SGMII_SERDES_TX_DR_CTRL_LSB 4
25#define SGMII_SERDES_TX_DR_CTRL_MASK 0x00000070
26#define SGMII_SERDES_TX_DR_CTRL_SET(x) \
27 (((x) << SGMII_SERDES_TX_DR_CTRL_LSB) & SGMII_SERDES_TX_DR_CTRL_MASK)
28#define SGMII_SERDES_PLL_BW_LSB 8
29#define SGMII_SERDES_PLL_BW_MASK 0x00000100
30#define SGMII_SERDES_PLL_BW_SET(x) \
31 (((x) << SGMII_SERDES_PLL_BW_LSB) & SGMII_SERDES_PLL_BW_MASK)
32#define SGMII_SERDES_EN_SIGNAL_DETECT_LSB 16
33#define SGMII_SERDES_EN_SIGNAL_DETECT_MASK 0x00010000
34#define SGMII_SERDES_EN_SIGNAL_DETECT_SET(x) \
35 (((x) << SGMII_SERDES_EN_SIGNAL_DETECT_LSB) & SGMII_SERDES_EN_SIGNAL_DETECT_MASK)
36#define SGMII_SERDES_FIBER_SDO_LSB 17
37#define SGMII_SERDES_FIBER_SDO_MASK 0x00020000
38#define SGMII_SERDES_FIBER_SDO_SET(x) \
39 (((x) << SGMII_SERDES_FIBER_SDO_LSB) & SGMII_SERDES_FIBER_SDO_MASK)
40#define SGMII_SERDES_VCO_REG_LSB 27
41#define SGMII_SERDES_VCO_REG_MASK 0x78000000
42#define SGMII_SERDES_VCO_REG_SET(x) \
43 (((x) << SGMII_SERDES_VCO_REG_LSB) & SGMII_SERDES_VCO_REG_MASK)
44#define SGMII_SERDES_VCO_FAST_LSB 9
45#define SGMII_SERDES_VCO_FAST_MASK 0x00000200
46#define SGMII_SERDES_VCO_FAST_GET(x) \
47 (((x) & SGMII_SERDES_VCO_FAST_MASK) >> SGMII_SERDES_VCO_FAST_LSB)
48#define SGMII_SERDES_VCO_SLOW_LSB 10
49#define SGMII_SERDES_VCO_SLOW_MASK 0x00000400
50#define SGMII_SERDES_VCO_SLOW_GET(x) \
51 (((x) & SGMII_SERDES_VCO_SLOW_MASK) >> SGMII_SERDES_VCO_SLOW_LSB)
52
Wills Wang1d3d0f12016-03-16 16:59:52 +080053void _machine_restart(void)
54{
55 void __iomem *base;
56 u32 reg = 0;
57
58 base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
59 MAP_NOCACHE);
60 if (soc_is_ar71xx())
61 reg = AR71XX_RESET_REG_RESET_MODULE;
62 else if (soc_is_ar724x())
63 reg = AR724X_RESET_REG_RESET_MODULE;
64 else if (soc_is_ar913x())
65 reg = AR913X_RESET_REG_RESET_MODULE;
66 else if (soc_is_ar933x())
67 reg = AR933X_RESET_REG_RESET_MODULE;
68 else if (soc_is_ar934x())
69 reg = AR934X_RESET_REG_RESET_MODULE;
70 else if (soc_is_qca953x())
71 reg = QCA953X_RESET_REG_RESET_MODULE;
72 else if (soc_is_qca955x())
73 reg = QCA955X_RESET_REG_RESET_MODULE;
74 else if (soc_is_qca956x())
75 reg = QCA956X_RESET_REG_RESET_MODULE;
76 else
77 puts("Reset register not defined for this SOC\n");
78
79 if (reg)
80 setbits_be32(base + reg, AR71XX_RESET_FULL_CHIP);
81
82 while (1)
83 /* NOP */;
84}
85
Wills Wang37523912016-05-30 22:54:50 +080086u32 ath79_get_bootstrap(void)
Wills Wang1d3d0f12016-03-16 16:59:52 +080087{
Marek Vasut43a092f2016-05-06 20:10:35 +020088 void __iomem *base;
Wills Wang1d3d0f12016-03-16 16:59:52 +080089 u32 reg = 0;
90
91 base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
92 MAP_NOCACHE);
93 if (soc_is_ar933x())
94 reg = AR933X_RESET_REG_BOOTSTRAP;
95 else if (soc_is_ar934x())
96 reg = AR934X_RESET_REG_BOOTSTRAP;
97 else if (soc_is_qca953x())
98 reg = QCA953X_RESET_REG_BOOTSTRAP;
99 else if (soc_is_qca955x())
100 reg = QCA955X_RESET_REG_BOOTSTRAP;
101 else if (soc_is_qca956x())
102 reg = QCA956X_RESET_REG_BOOTSTRAP;
103 else
104 puts("Bootstrap register not defined for this SOC\n");
105
106 if (reg)
107 return readl(base + reg);
108
109 return 0;
110}
Marek Vasut6b699742016-05-06 20:10:37 +0200111
Marek Vasut4771bbe2016-05-06 20:10:39 +0200112static int eth_init_ar933x(void)
113{
114 void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
115 MAP_NOCACHE);
116 void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
117 MAP_NOCACHE);
118 void __iomem *gregs = map_physmem(AR933X_GMAC_BASE, AR933X_GMAC_SIZE,
119 MAP_NOCACHE);
120 const u32 mask = AR933X_RESET_GE0_MAC | AR933X_RESET_GE0_MDIO |
121 AR933X_RESET_GE1_MAC | AR933X_RESET_GE1_MDIO |
Wills Wang42a3f3e2016-05-22 11:59:50 +0800122 AR933X_RESET_ETH_SWITCH |
123 AR933X_RESET_ETH_SWITCH_ANALOG;
Marek Vasut4771bbe2016-05-06 20:10:39 +0200124
125 /* Clear MDIO slave EN bit. */
126 clrbits_be32(rregs + AR933X_RESET_REG_BOOTSTRAP, BIT(17));
127 mdelay(10);
128
129 /* Get Atheros S26 PHY out of reset. */
Wills Wangca09e662016-05-30 22:54:54 +0800130 clrsetbits_be32(pregs + AR933X_PLL_SWITCH_CLOCK_CONTROL_REG,
Marek Vasut4771bbe2016-05-06 20:10:39 +0200131 0x1f, 0x10);
132 mdelay(10);
133
134 setbits_be32(rregs + AR933X_RESET_REG_RESET_MODULE, mask);
135 mdelay(10);
136 clrbits_be32(rregs + AR933X_RESET_REG_RESET_MODULE, mask);
137 mdelay(10);
138
139 /* Configure AR93xx GMAC register. */
140 clrsetbits_be32(gregs + AR933X_GMAC_REG_ETH_CFG,
141 AR933X_ETH_CFG_MII_GE0_MASTER |
142 AR933X_ETH_CFG_MII_GE0_SLAVE,
143 AR933X_ETH_CFG_MII_GE0_SLAVE);
144 return 0;
145}
146
147static int eth_init_ar934x(void)
148{
149 void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
150 MAP_NOCACHE);
151 void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
152 MAP_NOCACHE);
153 void __iomem *gregs = map_physmem(AR934X_GMAC_BASE, AR934X_GMAC_SIZE,
154 MAP_NOCACHE);
155 const u32 mask = AR934X_RESET_GE0_MAC | AR934X_RESET_GE0_MDIO |
156 AR934X_RESET_GE1_MAC | AR934X_RESET_GE1_MDIO |
157 AR934X_RESET_ETH_SWITCH_ANALOG;
158 u32 reg;
159
160 reg = readl(rregs + AR934X_RESET_REG_BOOTSTRAP);
161 if (reg & AR934X_BOOTSTRAP_REF_CLK_40)
162 writel(0x570, pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
163 else
164 writel(0x271, pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
165 writel(BIT(26) | BIT(25), pregs + AR934X_PLL_ETH_XMII_CONTROL_REG);
166
167 setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
168 mdelay(1);
169 clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
170 mdelay(1);
171
172 /* Configure AR934x GMAC register. */
173 writel(AR934X_ETH_CFG_RGMII_GMAC0, gregs + AR934X_GMAC_REG_ETH_CFG);
174 return 0;
175}
176
Wills Wangcdeb68e2016-05-30 22:54:53 +0800177static int eth_init_qca953x(void)
178{
179 void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
180 MAP_NOCACHE);
181 const u32 mask = QCA953X_RESET_GE0_MAC | QCA953X_RESET_GE0_MDIO |
182 QCA953X_RESET_GE1_MAC | QCA953X_RESET_GE1_MDIO |
183 QCA953X_RESET_ETH_SWITCH_ANALOG |
184 QCA953X_RESET_ETH_SWITCH;
185
186 setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
187 mdelay(1);
188 clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
189 mdelay(1);
190
191 return 0;
192}
193
Rosy Song61290fb2019-03-16 09:24:44 +0800194static int qca956x_sgmii_cal(void)
195{
196 int i;
197 u32 reg, rev_sgmii_val;
198 u32 vco_fast, vco_slow;
199 u32 start_val = 0, end_val = 0;
200 void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
201 MAP_NOCACHE);
202 void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
203 MAP_NOCACHE);
204 void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
205 MAP_NOCACHE);
206 const u32 mask = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII;
207
208 writel(BIT(2) | BIT(0), pregs + QCA956X_PLL_ETH_SGMII_SERDES_REG);
209
210 reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
211 vco_fast = SGMII_SERDES_VCO_FAST_GET(reg);
212 vco_slow = SGMII_SERDES_VCO_SLOW_GET(reg);
213
214 /* Set resistor calibration from 0000 to 1111 */
215 for (i = 0; i < 0x10; i++) {
216 reg = (readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) &
217 ~SGMII_SERDES_RES_CALIBRATION_MASK) |
218 SGMII_SERDES_RES_CALIBRATION_SET(i);
219 writel(reg, gregs + QCA956X_GMAC_REG_SGMII_SERDES);
220
221 udelay(50);
222
223 reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
224 if (vco_fast != SGMII_SERDES_VCO_FAST_GET(reg) ||
225 vco_slow != SGMII_SERDES_VCO_SLOW_GET(reg)) {
226 if (start_val == 0) {
227 start_val = i;
228 end_val = i;
229 } else {
230 end_val = i;
231 }
232 }
233 vco_fast = SGMII_SERDES_VCO_FAST_GET(reg);
234 vco_slow = SGMII_SERDES_VCO_SLOW_GET(reg);
235 }
236
237 if (start_val == 0)
238 rev_sgmii_val = 0x7;
239 else
240 rev_sgmii_val = (start_val + end_val) >> 1;
241
242 writel((readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) &
243 ~SGMII_SERDES_RES_CALIBRATION_MASK) |
244 SGMII_SERDES_RES_CALIBRATION_SET(rev_sgmii_val),
245 gregs + QCA956X_GMAC_REG_SGMII_SERDES);
246
247 writel(BIT(2) | BIT(0), pregs + QCA956X_PLL_ETH_SGMII_SERDES_REG);
248
249 reg = readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES);
250 writel(SGMII_SERDES_CDR_BW_SET(3) | SGMII_SERDES_TX_DR_CTRL_SET(1) |
251 SGMII_SERDES_PLL_BW_SET(1) | SGMII_SERDES_EN_SIGNAL_DETECT_SET(1) |
252 SGMII_SERDES_FIBER_SDO_SET(1) | SGMII_SERDES_VCO_REG_SET(3) | reg,
253 gregs + QCA956X_GMAC_REG_SGMII_SERDES);
254
255 setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
256 mdelay(1);
257 clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
258 mdelay(1);
259
260 while (!(readl(gregs + QCA956X_GMAC_REG_SGMII_SERDES) & BIT(15)))
261 /* NOP */;
262
263 return 0;
264}
265
266static int qca956x_sgmii_setup(void)
267{
268 int i;
269 u32 s = 0, reg = 0;
270 u32 _regs[] = {
271 BIT(4), /* HW_RX_125M_N */
272 BIT(2), /* RX_125M_N */
273 BIT(3), /* TX_125M_N */
274 BIT(0), /* RX_CLK_N */
275 BIT(1), /* TX_CLK_N */
276 };
277 void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
278 MAP_NOCACHE);
279
280 /* Force sgmii mode */
281 writel(BIT(6) | BIT(15) | BIT(8), gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
282 udelay(10);
283 writel(0x2 | BIT(5) | (0x2 << 6), gregs + QCA956X_GMAC_REG_SGMII_CONFIG);
284
285 /* SGMII reset sequence sugguest by qca systems team. */
286 writel(0, gregs + QCA956X_GMAC_REG_SGMII_RESET);
287 for (i = 0; i < ARRAY_SIZE(_regs); i++) {
288 reg |= _regs[i];
289 writel(reg, gregs + QCA956X_GMAC_REG_SGMII_RESET);
290 }
291
292 writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) & ~BIT(15),
293 gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
294
295 /*
296 * WARNING: Across resets SGMII link status goes to weird state.
297 * if 0xb8070058 (SGMII_DEBUG Register) reads other than 0xf or 0x10
298 * for sure we are in bad state.
299 * Issue a PHY RESET in MR_AN_CONTROL_ADDRESS to keep going.
300 */
301 i = 0;
302 s = (readl(gregs + QCA956X_GMAC_REG_SGMII_DEBUG) & 0xff);
303 while (!(s == 0xf || s == 0x10)) {
304 writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) | BIT(15),
305 gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
306 udelay(100);
307 writel(readl(gregs + QCA956X_GMAC_REG_MR_AN_CTRL) & ~BIT(15),
308 gregs + QCA956X_GMAC_REG_MR_AN_CTRL);
309 if (i++ == 10)
310 break;
311 s = (readl(gregs + QCA956X_GMAC_REG_SGMII_DEBUG) & 0xff);
312 }
313
314 return 0;
315}
316
317static int qca956x_s17_reset(void)
318{
319 void __iomem *regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
320 MAP_NOCACHE);
321 void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
322 MAP_NOCACHE);
323 const u32 mask = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII |
324 QCA956X_RESET_EXTERNAL | QCA956X_RESET_SGMII_ANALOG |
325 QCA956X_RESET_SWITCH;
326 /* Bits(Reserved in datasheet) should be set to 1 */
327 const u32 mask_r = QCA956X_RESET_SGMII_ASSERT | QCA956X_RESET_SGMII |
328 QCA956X_RESET_EXTERNAL;
329
330 setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
331 mdelay(1);
332 clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask_r);
333 mdelay(1);
334
335 /* Reset s17 switch(GPIO11) SYS_RST_L */
336 writel(readl(regs + AR71XX_GPIO_REG_OE) & ~BIT(11),
337 regs + AR71XX_GPIO_REG_OE);
338 udelay(100);
339
340 writel(readl(regs + AR71XX_GPIO_REG_OUT) & ~BIT(11),
341 regs + AR71XX_GPIO_REG_OUT);
342 udelay(100);
343 writel(readl(regs + AR71XX_GPIO_REG_OUT) | BIT(11),
344 regs + AR71XX_GPIO_REG_OUT);
345
346 return 0;
347}
348
349static int qca956x_init_mdio(void)
350{
351 u32 reg;
352 void __iomem *regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
353 MAP_NOCACHE);
354 void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
355 MAP_NOCACHE);
356 const u32 mask = QCA956X_RESET_GE0_MDIO | QCA956X_RESET_GE0_MAC |
357 QCA956X_RESET_GE1_MDIO | QCA956X_RESET_GE1_MAC;
358
359 setbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
360 mdelay(1);
361 clrbits_be32(rregs + QCA956X_RESET_REG_RESET_MODULE, mask);
362 mdelay(1);
363
364 /* GPIO4 as MDI */
365 reg = readl(regs + QCA956X_GPIO_REG_IN_ENABLE3);
366 reg &= ~(0xff << 16);
367 reg |= (0x4 << 16);
368 writel(reg, regs + QCA956X_GPIO_REG_IN_ENABLE3);
369
370 /* GPIO4 as MDO */
371 reg = readl(regs + QCA956X_GPIO_REG_OUT_FUNC1);
372 reg &= ~0xff;
373 reg |= 0x20;
374 writel(reg, regs + QCA956X_GPIO_REG_OUT_FUNC1);
375
376 /* Init MDC(GPIO3) / MDIO(GPIO4) */
377 reg = readl(regs + AR71XX_GPIO_REG_OE);
378 reg &= ~BIT(4);
379 writel(reg, regs + AR71XX_GPIO_REG_OE);
380 udelay(100);
381
382 reg = readl(regs + AR71XX_GPIO_REG_OE);
383 reg &= ~BIT(3);
384 writel(reg, regs + AR71XX_GPIO_REG_OE);
385 udelay(100);
386
387 /* GPIO3 as MDI */
388 reg = readl(regs + QCA956X_GPIO_REG_OUT_FUNC0);
389 reg &= ~(0xff << 24);
390 reg |= (0x21 << 24);
391 writel(reg, regs + QCA956X_GPIO_REG_OUT_FUNC0);
392
393 return 0;
394}
395
396static int eth_init_qca956x(void)
397{
398 void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
399 MAP_NOCACHE);
400 void __iomem *gregs = map_physmem(AR71XX_MII_BASE, AR71XX_MII_SIZE,
401 MAP_NOCACHE);
402
403 qca956x_sgmii_cal();
404 qca956x_s17_reset();
405 qca956x_init_mdio();
406
407 if (ath79_get_bootstrap() & QCA956X_BOOTSTRAP_REF_CLK_40)
408 writel(0x45500, pregs + QCA956X_PLL_SWITCH_CLK_CTRL_REG);
409 else
410 writel(0xc5200, pregs + QCA956X_PLL_SWITCH_CLK_CTRL_REG);
411
412 qca956x_sgmii_setup();
413
414 writel((3 << 16) | (3 << 14) | (1 << 0) | (1 << 6),
415 gregs + QCA956X_GMAC_REG_ETH_CFG);
416
417 writel((1 << 31) | (2 << 28) | (2 << 26) | (1 << 25),
418 pregs + QCA956X_PLL_ETH_XMII_CTRL_REG);
419 mdelay(1);
420
421 return 0;
422}
423
Marek Vasut4771bbe2016-05-06 20:10:39 +0200424int ath79_eth_reset(void)
425{
426 /*
427 * Un-reset ethernet. DM still doesn't have any notion of reset
428 * framework, so we do it by hand here.
429 */
430 if (soc_is_ar933x())
431 return eth_init_ar933x();
432 if (soc_is_ar934x())
433 return eth_init_ar934x();
Wills Wangcdeb68e2016-05-30 22:54:53 +0800434 if (soc_is_qca953x())
435 return eth_init_qca953x();
Rosy Song61290fb2019-03-16 09:24:44 +0800436 if (soc_is_qca956x())
437 return eth_init_qca956x();
Marek Vasut4771bbe2016-05-06 20:10:39 +0200438
439 return -EINVAL;
440}
441
Marek Vasut6b699742016-05-06 20:10:37 +0200442static int usb_reset_ar933x(void __iomem *reset_regs)
443{
444 /* Ungate the USB block */
445 setbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
446 AR933X_RESET_USBSUS_OVERRIDE);
447 mdelay(1);
448 clrbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
449 AR933X_RESET_USB_HOST);
450 mdelay(1);
451 clrbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
452 AR933X_RESET_USB_PHY);
453 mdelay(1);
454
455 return 0;
456}
457
458static int usb_reset_ar934x(void __iomem *reset_regs)
459{
460 /* Ungate the USB block */
461 setbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
462 AR934X_RESET_USBSUS_OVERRIDE);
463 mdelay(1);
464 clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
465 AR934X_RESET_USB_PHY);
466 mdelay(1);
467 clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
468 AR934X_RESET_USB_PHY_ANALOG);
469 mdelay(1);
470 clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
471 AR934X_RESET_USB_HOST);
472 mdelay(1);
473
474 return 0;
475}
476
Wills Wangcdeb68e2016-05-30 22:54:53 +0800477static int usb_reset_qca953x(void __iomem *reset_regs)
478{
479 void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
480 MAP_NOCACHE);
481
482 clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG,
483 0xf00, 0x200);
484 mdelay(10);
485
486 /* Ungate the USB block */
487 setbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
488 QCA953X_RESET_USBSUS_OVERRIDE);
489 mdelay(1);
490 clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
491 QCA953X_RESET_USB_PHY);
492 mdelay(1);
493 clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
494 QCA953X_RESET_USB_PHY_ANALOG);
495 mdelay(1);
496 clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
497 QCA953X_RESET_USB_HOST);
498 mdelay(1);
499 clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
500 QCA953X_RESET_USB_PHY_PLL_PWD_EXT);
501 mdelay(1);
502
503 return 0;
504}
505
Marek Vasut6b699742016-05-06 20:10:37 +0200506int ath79_usb_reset(void)
507{
508 void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE,
509 AR71XX_USB_CTRL_SIZE,
510 MAP_NOCACHE);
511 void __iomem *reset_regs = map_physmem(AR71XX_RESET_BASE,
512 AR71XX_RESET_SIZE,
513 MAP_NOCACHE);
514 /*
515 * Turn on the Buff and Desc swap bits.
516 * NOTE: This write into an undocumented register in mandatory to
517 * get the USB controller operational in BigEndian mode.
518 */
519 writel(0xf0000, usbc_regs + AR71XX_USB_CTRL_REG_CONFIG);
520
521 if (soc_is_ar933x())
522 return usb_reset_ar933x(reset_regs);
523 if (soc_is_ar934x())
524 return usb_reset_ar934x(reset_regs);
Wills Wangcdeb68e2016-05-30 22:54:53 +0800525 if (soc_is_qca953x())
526 return usb_reset_qca953x(reset_regs);
Marek Vasut6b699742016-05-06 20:10:37 +0200527
528 return -EINVAL;
529}