blob: 6a94d886f94ff7832fc8ef3a2fd1598391c8d57a [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>
Wills Wang833a1a82016-03-16 16:59:52 +08004 */
5
6#include <common.h>
Masahiro Yamada56a931c2016-09-21 11:28:55 +09007#include <linux/errno.h>
Wills Wang833a1a82016-03-16 16:59:52 +08008#include <asm/io.h>
9#include <asm/addrspace.h>
10#include <asm/types.h>
11#include <mach/ath79.h>
12#include <mach/ar71xx_regs.h>
13
14void _machine_restart(void)
15{
16 void __iomem *base;
17 u32 reg = 0;
18
19 base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
20 MAP_NOCACHE);
21 if (soc_is_ar71xx())
22 reg = AR71XX_RESET_REG_RESET_MODULE;
23 else if (soc_is_ar724x())
24 reg = AR724X_RESET_REG_RESET_MODULE;
25 else if (soc_is_ar913x())
26 reg = AR913X_RESET_REG_RESET_MODULE;
27 else if (soc_is_ar933x())
28 reg = AR933X_RESET_REG_RESET_MODULE;
29 else if (soc_is_ar934x())
30 reg = AR934X_RESET_REG_RESET_MODULE;
31 else if (soc_is_qca953x())
32 reg = QCA953X_RESET_REG_RESET_MODULE;
33 else if (soc_is_qca955x())
34 reg = QCA955X_RESET_REG_RESET_MODULE;
35 else if (soc_is_qca956x())
36 reg = QCA956X_RESET_REG_RESET_MODULE;
37 else
38 puts("Reset register not defined for this SOC\n");
39
40 if (reg)
41 setbits_be32(base + reg, AR71XX_RESET_FULL_CHIP);
42
43 while (1)
44 /* NOP */;
45}
46
Wills Wangddc05522016-05-30 22:54:50 +080047u32 ath79_get_bootstrap(void)
Wills Wang833a1a82016-03-16 16:59:52 +080048{
Marek Vasutfef59082016-05-06 20:10:35 +020049 void __iomem *base;
Wills Wang833a1a82016-03-16 16:59:52 +080050 u32 reg = 0;
51
52 base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
53 MAP_NOCACHE);
54 if (soc_is_ar933x())
55 reg = AR933X_RESET_REG_BOOTSTRAP;
56 else if (soc_is_ar934x())
57 reg = AR934X_RESET_REG_BOOTSTRAP;
58 else if (soc_is_qca953x())
59 reg = QCA953X_RESET_REG_BOOTSTRAP;
60 else if (soc_is_qca955x())
61 reg = QCA955X_RESET_REG_BOOTSTRAP;
62 else if (soc_is_qca956x())
63 reg = QCA956X_RESET_REG_BOOTSTRAP;
64 else
65 puts("Bootstrap register not defined for this SOC\n");
66
67 if (reg)
68 return readl(base + reg);
69
70 return 0;
71}
Marek Vasutdff26d82016-05-06 20:10:37 +020072
Marek Vasutc06cdad2016-05-06 20:10:39 +020073static int eth_init_ar933x(void)
74{
75 void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
76 MAP_NOCACHE);
77 void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
78 MAP_NOCACHE);
79 void __iomem *gregs = map_physmem(AR933X_GMAC_BASE, AR933X_GMAC_SIZE,
80 MAP_NOCACHE);
81 const u32 mask = AR933X_RESET_GE0_MAC | AR933X_RESET_GE0_MDIO |
82 AR933X_RESET_GE1_MAC | AR933X_RESET_GE1_MDIO |
Wills Wang52872452016-05-22 11:59:50 +080083 AR933X_RESET_ETH_SWITCH |
84 AR933X_RESET_ETH_SWITCH_ANALOG;
Marek Vasutc06cdad2016-05-06 20:10:39 +020085
86 /* Clear MDIO slave EN bit. */
87 clrbits_be32(rregs + AR933X_RESET_REG_BOOTSTRAP, BIT(17));
88 mdelay(10);
89
90 /* Get Atheros S26 PHY out of reset. */
Wills Wang8958f562016-05-30 22:54:54 +080091 clrsetbits_be32(pregs + AR933X_PLL_SWITCH_CLOCK_CONTROL_REG,
Marek Vasutc06cdad2016-05-06 20:10:39 +020092 0x1f, 0x10);
93 mdelay(10);
94
95 setbits_be32(rregs + AR933X_RESET_REG_RESET_MODULE, mask);
96 mdelay(10);
97 clrbits_be32(rregs + AR933X_RESET_REG_RESET_MODULE, mask);
98 mdelay(10);
99
100 /* Configure AR93xx GMAC register. */
101 clrsetbits_be32(gregs + AR933X_GMAC_REG_ETH_CFG,
102 AR933X_ETH_CFG_MII_GE0_MASTER |
103 AR933X_ETH_CFG_MII_GE0_SLAVE,
104 AR933X_ETH_CFG_MII_GE0_SLAVE);
105 return 0;
106}
107
108static int eth_init_ar934x(void)
109{
110 void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
111 MAP_NOCACHE);
112 void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
113 MAP_NOCACHE);
114 void __iomem *gregs = map_physmem(AR934X_GMAC_BASE, AR934X_GMAC_SIZE,
115 MAP_NOCACHE);
116 const u32 mask = AR934X_RESET_GE0_MAC | AR934X_RESET_GE0_MDIO |
117 AR934X_RESET_GE1_MAC | AR934X_RESET_GE1_MDIO |
118 AR934X_RESET_ETH_SWITCH_ANALOG;
119 u32 reg;
120
121 reg = readl(rregs + AR934X_RESET_REG_BOOTSTRAP);
122 if (reg & AR934X_BOOTSTRAP_REF_CLK_40)
123 writel(0x570, pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
124 else
125 writel(0x271, pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
126 writel(BIT(26) | BIT(25), pregs + AR934X_PLL_ETH_XMII_CONTROL_REG);
127
128 setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
129 mdelay(1);
130 clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
131 mdelay(1);
132
133 /* Configure AR934x GMAC register. */
134 writel(AR934X_ETH_CFG_RGMII_GMAC0, gregs + AR934X_GMAC_REG_ETH_CFG);
135 return 0;
136}
137
Wills Wang4b973932016-05-30 22:54:53 +0800138static int eth_init_qca953x(void)
139{
140 void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
141 MAP_NOCACHE);
142 const u32 mask = QCA953X_RESET_GE0_MAC | QCA953X_RESET_GE0_MDIO |
143 QCA953X_RESET_GE1_MAC | QCA953X_RESET_GE1_MDIO |
144 QCA953X_RESET_ETH_SWITCH_ANALOG |
145 QCA953X_RESET_ETH_SWITCH;
146
147 setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
148 mdelay(1);
149 clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
150 mdelay(1);
151
152 return 0;
153}
154
Marek Vasutc06cdad2016-05-06 20:10:39 +0200155int ath79_eth_reset(void)
156{
157 /*
158 * Un-reset ethernet. DM still doesn't have any notion of reset
159 * framework, so we do it by hand here.
160 */
161 if (soc_is_ar933x())
162 return eth_init_ar933x();
163 if (soc_is_ar934x())
164 return eth_init_ar934x();
Wills Wang4b973932016-05-30 22:54:53 +0800165 if (soc_is_qca953x())
166 return eth_init_qca953x();
Marek Vasutc06cdad2016-05-06 20:10:39 +0200167
168 return -EINVAL;
169}
170
Marek Vasutdff26d82016-05-06 20:10:37 +0200171static int usb_reset_ar933x(void __iomem *reset_regs)
172{
173 /* Ungate the USB block */
174 setbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
175 AR933X_RESET_USBSUS_OVERRIDE);
176 mdelay(1);
177 clrbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
178 AR933X_RESET_USB_HOST);
179 mdelay(1);
180 clrbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
181 AR933X_RESET_USB_PHY);
182 mdelay(1);
183
184 return 0;
185}
186
187static int usb_reset_ar934x(void __iomem *reset_regs)
188{
189 /* Ungate the USB block */
190 setbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
191 AR934X_RESET_USBSUS_OVERRIDE);
192 mdelay(1);
193 clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
194 AR934X_RESET_USB_PHY);
195 mdelay(1);
196 clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
197 AR934X_RESET_USB_PHY_ANALOG);
198 mdelay(1);
199 clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
200 AR934X_RESET_USB_HOST);
201 mdelay(1);
202
203 return 0;
204}
205
Wills Wang4b973932016-05-30 22:54:53 +0800206static int usb_reset_qca953x(void __iomem *reset_regs)
207{
208 void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
209 MAP_NOCACHE);
210
211 clrsetbits_be32(pregs + QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG,
212 0xf00, 0x200);
213 mdelay(10);
214
215 /* Ungate the USB block */
216 setbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
217 QCA953X_RESET_USBSUS_OVERRIDE);
218 mdelay(1);
219 clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
220 QCA953X_RESET_USB_PHY);
221 mdelay(1);
222 clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
223 QCA953X_RESET_USB_PHY_ANALOG);
224 mdelay(1);
225 clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
226 QCA953X_RESET_USB_HOST);
227 mdelay(1);
228 clrbits_be32(reset_regs + QCA953X_RESET_REG_RESET_MODULE,
229 QCA953X_RESET_USB_PHY_PLL_PWD_EXT);
230 mdelay(1);
231
232 return 0;
233}
234
Marek Vasutdff26d82016-05-06 20:10:37 +0200235int ath79_usb_reset(void)
236{
237 void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE,
238 AR71XX_USB_CTRL_SIZE,
239 MAP_NOCACHE);
240 void __iomem *reset_regs = map_physmem(AR71XX_RESET_BASE,
241 AR71XX_RESET_SIZE,
242 MAP_NOCACHE);
243 /*
244 * Turn on the Buff and Desc swap bits.
245 * NOTE: This write into an undocumented register in mandatory to
246 * get the USB controller operational in BigEndian mode.
247 */
248 writel(0xf0000, usbc_regs + AR71XX_USB_CTRL_REG_CONFIG);
249
250 if (soc_is_ar933x())
251 return usb_reset_ar933x(reset_regs);
252 if (soc_is_ar934x())
253 return usb_reset_ar934x(reset_regs);
Wills Wang4b973932016-05-30 22:54:53 +0800254 if (soc_is_qca953x())
255 return usb_reset_qca953x(reset_regs);
Marek Vasutdff26d82016-05-06 20:10:37 +0200256
257 return -EINVAL;
258}