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