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