diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/ath79 | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/ath79')
-rw-r--r-- | arch/mips/ath79/Kconfig | 48 | ||||
-rw-r--r-- | arch/mips/ath79/Makefile | 11 | ||||
-rw-r--r-- | arch/mips/ath79/Platform | 6 | ||||
-rw-r--r-- | arch/mips/ath79/clock.c | 673 | ||||
-rw-r--r-- | arch/mips/ath79/common.c | 149 | ||||
-rw-r--r-- | arch/mips/ath79/common.h | 21 | ||||
-rw-r--r-- | arch/mips/ath79/early_printk.c | 146 | ||||
-rw-r--r-- | arch/mips/ath79/prom.c | 39 | ||||
-rw-r--r-- | arch/mips/ath79/setup.c | 279 |
9 files changed, 1372 insertions, 0 deletions
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig new file mode 100644 index 000000000..736741664 --- /dev/null +++ b/arch/mips/ath79/Kconfig | |||
@@ -0,0 +1,48 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | if ATH79 | ||
3 | |||
4 | config SOC_AR71XX | ||
5 | select HAVE_PCI | ||
6 | def_bool n | ||
7 | |||
8 | config SOC_AR724X | ||
9 | select HAVE_PCI | ||
10 | select PCI_AR724X if PCI | ||
11 | def_bool n | ||
12 | |||
13 | config SOC_AR913X | ||
14 | def_bool n | ||
15 | |||
16 | config SOC_AR933X | ||
17 | def_bool n | ||
18 | |||
19 | config SOC_AR934X | ||
20 | select HAVE_PCI | ||
21 | select PCI_AR724X if PCI | ||
22 | def_bool n | ||
23 | |||
24 | config SOC_QCA955X | ||
25 | select HAVE_PCI | ||
26 | select PCI_AR724X if PCI | ||
27 | def_bool n | ||
28 | |||
29 | config PCI_AR724X | ||
30 | def_bool n | ||
31 | |||
32 | config ATH79_DEV_GPIO_BUTTONS | ||
33 | def_bool n | ||
34 | |||
35 | config ATH79_DEV_LEDS_GPIO | ||
36 | def_bool n | ||
37 | |||
38 | config ATH79_DEV_SPI | ||
39 | def_bool n | ||
40 | |||
41 | config ATH79_DEV_USB | ||
42 | def_bool n | ||
43 | |||
44 | config ATH79_DEV_WMAC | ||
45 | depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X) | ||
46 | def_bool n | ||
47 | |||
48 | endif | ||
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile new file mode 100644 index 000000000..0fb3aaf42 --- /dev/null +++ b/arch/mips/ath79/Makefile | |||
@@ -0,0 +1,11 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0-only | ||
2 | # | ||
3 | # Makefile for the Atheros AR71XX/AR724X/AR913X specific parts of the kernel | ||
4 | # | ||
5 | # Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
6 | # Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
7 | # | ||
8 | |||
9 | obj-y := prom.o setup.o common.o clock.o | ||
10 | |||
11 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | ||
diff --git a/arch/mips/ath79/Platform b/arch/mips/ath79/Platform new file mode 100644 index 000000000..57744472e --- /dev/null +++ b/arch/mips/ath79/Platform | |||
@@ -0,0 +1,6 @@ | |||
1 | # | ||
2 | # Atheros AR71xx/AR724x/AR913x | ||
3 | # | ||
4 | |||
5 | cflags-$(CONFIG_ATH79) += -I$(srctree)/arch/mips/include/asm/mach-ath79 | ||
6 | load-$(CONFIG_ATH79) = 0xffffffff80060000 | ||
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c new file mode 100644 index 000000000..050f6553f --- /dev/null +++ b/arch/mips/ath79/clock.c | |||
@@ -0,0 +1,673 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /* | ||
3 | * Atheros AR71XX/AR724X/AR913X common routines | ||
4 | * | ||
5 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||
6 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||
7 | * | ||
8 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/clkdev.h> | ||
17 | #include <linux/clk-provider.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <dt-bindings/clock/ath79-clk.h> | ||
21 | |||
22 | #include <asm/div64.h> | ||
23 | |||
24 | #include <asm/mach-ath79/ath79.h> | ||
25 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
26 | #include "common.h" | ||
27 | |||
28 | #define AR71XX_BASE_FREQ 40000000 | ||
29 | #define AR724X_BASE_FREQ 40000000 | ||
30 | |||
31 | static struct clk *clks[ATH79_CLK_END]; | ||
32 | static struct clk_onecell_data clk_data = { | ||
33 | .clks = clks, | ||
34 | .clk_num = ARRAY_SIZE(clks), | ||
35 | }; | ||
36 | |||
37 | static const char * const clk_names[ATH79_CLK_END] = { | ||
38 | [ATH79_CLK_CPU] = "cpu", | ||
39 | [ATH79_CLK_DDR] = "ddr", | ||
40 | [ATH79_CLK_AHB] = "ahb", | ||
41 | [ATH79_CLK_REF] = "ref", | ||
42 | [ATH79_CLK_MDIO] = "mdio", | ||
43 | }; | ||
44 | |||
45 | static const char * __init ath79_clk_name(int type) | ||
46 | { | ||
47 | BUG_ON(type >= ARRAY_SIZE(clk_names) || !clk_names[type]); | ||
48 | return clk_names[type]; | ||
49 | } | ||
50 | |||
51 | static void __init __ath79_set_clk(int type, const char *name, struct clk *clk) | ||
52 | { | ||
53 | if (IS_ERR(clk)) | ||
54 | panic("failed to allocate %s clock structure", clk_names[type]); | ||
55 | |||
56 | clks[type] = clk; | ||
57 | clk_register_clkdev(clk, name, NULL); | ||
58 | } | ||
59 | |||
60 | static struct clk * __init ath79_set_clk(int type, unsigned long rate) | ||
61 | { | ||
62 | const char *name = ath79_clk_name(type); | ||
63 | struct clk *clk; | ||
64 | |||
65 | clk = clk_register_fixed_rate(NULL, name, NULL, 0, rate); | ||
66 | __ath79_set_clk(type, name, clk); | ||
67 | return clk; | ||
68 | } | ||
69 | |||
70 | static struct clk * __init ath79_set_ff_clk(int type, const char *parent, | ||
71 | unsigned int mult, unsigned int div) | ||
72 | { | ||
73 | const char *name = ath79_clk_name(type); | ||
74 | struct clk *clk; | ||
75 | |||
76 | clk = clk_register_fixed_factor(NULL, name, parent, 0, mult, div); | ||
77 | __ath79_set_clk(type, name, clk); | ||
78 | return clk; | ||
79 | } | ||
80 | |||
81 | static unsigned long __init ath79_setup_ref_clk(unsigned long rate) | ||
82 | { | ||
83 | struct clk *clk = clks[ATH79_CLK_REF]; | ||
84 | |||
85 | if (clk) | ||
86 | rate = clk_get_rate(clk); | ||
87 | else | ||
88 | clk = ath79_set_clk(ATH79_CLK_REF, rate); | ||
89 | |||
90 | return rate; | ||
91 | } | ||
92 | |||
93 | static void __init ar71xx_clocks_init(void __iomem *pll_base) | ||
94 | { | ||
95 | unsigned long ref_rate; | ||
96 | unsigned long cpu_rate; | ||
97 | unsigned long ddr_rate; | ||
98 | unsigned long ahb_rate; | ||
99 | u32 pll; | ||
100 | u32 freq; | ||
101 | u32 div; | ||
102 | |||
103 | ref_rate = ath79_setup_ref_clk(AR71XX_BASE_FREQ); | ||
104 | |||
105 | pll = __raw_readl(pll_base + AR71XX_PLL_REG_CPU_CONFIG); | ||
106 | |||
107 | div = ((pll >> AR71XX_PLL_FB_SHIFT) & AR71XX_PLL_FB_MASK) + 1; | ||
108 | freq = div * ref_rate; | ||
109 | |||
110 | div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; | ||
111 | cpu_rate = freq / div; | ||
112 | |||
113 | div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; | ||
114 | ddr_rate = freq / div; | ||
115 | |||
116 | div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; | ||
117 | ahb_rate = cpu_rate / div; | ||
118 | |||
119 | ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||
120 | ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||
121 | ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||
122 | } | ||
123 | |||
124 | static void __init ar724x_clocks_init(void __iomem *pll_base) | ||
125 | { | ||
126 | u32 mult, div, ddr_div, ahb_div; | ||
127 | u32 pll; | ||
128 | |||
129 | ath79_setup_ref_clk(AR71XX_BASE_FREQ); | ||
130 | |||
131 | pll = __raw_readl(pll_base + AR724X_PLL_REG_CPU_CONFIG); | ||
132 | |||
133 | mult = ((pll >> AR724X_PLL_FB_SHIFT) & AR724X_PLL_FB_MASK); | ||
134 | div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK) * 2; | ||
135 | |||
136 | ddr_div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; | ||
137 | ahb_div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; | ||
138 | |||
139 | ath79_set_ff_clk(ATH79_CLK_CPU, "ref", mult, div); | ||
140 | ath79_set_ff_clk(ATH79_CLK_DDR, "ref", mult, div * ddr_div); | ||
141 | ath79_set_ff_clk(ATH79_CLK_AHB, "ref", mult, div * ahb_div); | ||
142 | } | ||
143 | |||
144 | static void __init ar933x_clocks_init(void __iomem *pll_base) | ||
145 | { | ||
146 | unsigned long ref_rate; | ||
147 | u32 clock_ctrl; | ||
148 | u32 ref_div; | ||
149 | u32 ninit_mul; | ||
150 | u32 out_div; | ||
151 | |||
152 | u32 cpu_div; | ||
153 | u32 ddr_div; | ||
154 | u32 ahb_div; | ||
155 | u32 t; | ||
156 | |||
157 | t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | ||
158 | if (t & AR933X_BOOTSTRAP_REF_CLK_40) | ||
159 | ref_rate = (40 * 1000 * 1000); | ||
160 | else | ||
161 | ref_rate = (25 * 1000 * 1000); | ||
162 | |||
163 | ath79_setup_ref_clk(ref_rate); | ||
164 | |||
165 | clock_ctrl = __raw_readl(pll_base + AR933X_PLL_CLOCK_CTRL_REG); | ||
166 | if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) { | ||
167 | ref_div = 1; | ||
168 | ninit_mul = 1; | ||
169 | out_div = 1; | ||
170 | |||
171 | cpu_div = 1; | ||
172 | ddr_div = 1; | ||
173 | ahb_div = 1; | ||
174 | } else { | ||
175 | u32 cpu_config; | ||
176 | u32 t; | ||
177 | |||
178 | cpu_config = __raw_readl(pll_base + AR933X_PLL_CPU_CONFIG_REG); | ||
179 | |||
180 | t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||
181 | AR933X_PLL_CPU_CONFIG_REFDIV_MASK; | ||
182 | ref_div = t; | ||
183 | |||
184 | ninit_mul = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) & | ||
185 | AR933X_PLL_CPU_CONFIG_NINT_MASK; | ||
186 | |||
187 | t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||
188 | AR933X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||
189 | if (t == 0) | ||
190 | t = 1; | ||
191 | |||
192 | out_div = (1 << t); | ||
193 | |||
194 | cpu_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) & | ||
195 | AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1; | ||
196 | |||
197 | ddr_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) & | ||
198 | AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1; | ||
199 | |||
200 | ahb_div = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) & | ||
201 | AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1; | ||
202 | } | ||
203 | |||
204 | ath79_set_ff_clk(ATH79_CLK_CPU, "ref", ninit_mul, | ||
205 | ref_div * out_div * cpu_div); | ||
206 | ath79_set_ff_clk(ATH79_CLK_DDR, "ref", ninit_mul, | ||
207 | ref_div * out_div * ddr_div); | ||
208 | ath79_set_ff_clk(ATH79_CLK_AHB, "ref", ninit_mul, | ||
209 | ref_div * out_div * ahb_div); | ||
210 | } | ||
211 | |||
212 | static u32 __init ar934x_get_pll_freq(u32 ref, u32 ref_div, u32 nint, u32 nfrac, | ||
213 | u32 frac, u32 out_div) | ||
214 | { | ||
215 | u64 t; | ||
216 | u32 ret; | ||
217 | |||
218 | t = ref; | ||
219 | t *= nint; | ||
220 | do_div(t, ref_div); | ||
221 | ret = t; | ||
222 | |||
223 | t = ref; | ||
224 | t *= nfrac; | ||
225 | do_div(t, ref_div * frac); | ||
226 | ret += t; | ||
227 | |||
228 | ret /= (1 << out_div); | ||
229 | return ret; | ||
230 | } | ||
231 | |||
232 | static void __init ar934x_clocks_init(void __iomem *pll_base) | ||
233 | { | ||
234 | unsigned long ref_rate; | ||
235 | unsigned long cpu_rate; | ||
236 | unsigned long ddr_rate; | ||
237 | unsigned long ahb_rate; | ||
238 | u32 pll, out_div, ref_div, nint, nfrac, frac, clk_ctrl, postdiv; | ||
239 | u32 cpu_pll, ddr_pll; | ||
240 | u32 bootstrap; | ||
241 | void __iomem *dpll_base; | ||
242 | |||
243 | dpll_base = ioremap(AR934X_SRIF_BASE, AR934X_SRIF_SIZE); | ||
244 | |||
245 | bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | ||
246 | if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) | ||
247 | ref_rate = 40 * 1000 * 1000; | ||
248 | else | ||
249 | ref_rate = 25 * 1000 * 1000; | ||
250 | |||
251 | ref_rate = ath79_setup_ref_clk(ref_rate); | ||
252 | |||
253 | pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL2_REG); | ||
254 | if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { | ||
255 | out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & | ||
256 | AR934X_SRIF_DPLL2_OUTDIV_MASK; | ||
257 | pll = __raw_readl(dpll_base + AR934X_SRIF_CPU_DPLL1_REG); | ||
258 | nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & | ||
259 | AR934X_SRIF_DPLL1_NINT_MASK; | ||
260 | nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; | ||
261 | ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & | ||
262 | AR934X_SRIF_DPLL1_REFDIV_MASK; | ||
263 | frac = 1 << 18; | ||
264 | } else { | ||
265 | pll = __raw_readl(pll_base + AR934X_PLL_CPU_CONFIG_REG); | ||
266 | out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||
267 | AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||
268 | ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||
269 | AR934X_PLL_CPU_CONFIG_REFDIV_MASK; | ||
270 | nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & | ||
271 | AR934X_PLL_CPU_CONFIG_NINT_MASK; | ||
272 | nfrac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & | ||
273 | AR934X_PLL_CPU_CONFIG_NFRAC_MASK; | ||
274 | frac = 1 << 6; | ||
275 | } | ||
276 | |||
277 | cpu_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, | ||
278 | nfrac, frac, out_div); | ||
279 | |||
280 | pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL2_REG); | ||
281 | if (pll & AR934X_SRIF_DPLL2_LOCAL_PLL) { | ||
282 | out_div = (pll >> AR934X_SRIF_DPLL2_OUTDIV_SHIFT) & | ||
283 | AR934X_SRIF_DPLL2_OUTDIV_MASK; | ||
284 | pll = __raw_readl(dpll_base + AR934X_SRIF_DDR_DPLL1_REG); | ||
285 | nint = (pll >> AR934X_SRIF_DPLL1_NINT_SHIFT) & | ||
286 | AR934X_SRIF_DPLL1_NINT_MASK; | ||
287 | nfrac = pll & AR934X_SRIF_DPLL1_NFRAC_MASK; | ||
288 | ref_div = (pll >> AR934X_SRIF_DPLL1_REFDIV_SHIFT) & | ||
289 | AR934X_SRIF_DPLL1_REFDIV_MASK; | ||
290 | frac = 1 << 18; | ||
291 | } else { | ||
292 | pll = __raw_readl(pll_base + AR934X_PLL_DDR_CONFIG_REG); | ||
293 | out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | ||
294 | AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; | ||
295 | ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | ||
296 | AR934X_PLL_DDR_CONFIG_REFDIV_MASK; | ||
297 | nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & | ||
298 | AR934X_PLL_DDR_CONFIG_NINT_MASK; | ||
299 | nfrac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & | ||
300 | AR934X_PLL_DDR_CONFIG_NFRAC_MASK; | ||
301 | frac = 1 << 10; | ||
302 | } | ||
303 | |||
304 | ddr_pll = ar934x_get_pll_freq(ref_rate, ref_div, nint, | ||
305 | nfrac, frac, out_div); | ||
306 | |||
307 | clk_ctrl = __raw_readl(pll_base + AR934X_PLL_CPU_DDR_CLK_CTRL_REG); | ||
308 | |||
309 | postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & | ||
310 | AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; | ||
311 | |||
312 | if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) | ||
313 | cpu_rate = ref_rate; | ||
314 | else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) | ||
315 | cpu_rate = cpu_pll / (postdiv + 1); | ||
316 | else | ||
317 | cpu_rate = ddr_pll / (postdiv + 1); | ||
318 | |||
319 | postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) & | ||
320 | AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; | ||
321 | |||
322 | if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) | ||
323 | ddr_rate = ref_rate; | ||
324 | else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) | ||
325 | ddr_rate = ddr_pll / (postdiv + 1); | ||
326 | else | ||
327 | ddr_rate = cpu_pll / (postdiv + 1); | ||
328 | |||
329 | postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) & | ||
330 | AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; | ||
331 | |||
332 | if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) | ||
333 | ahb_rate = ref_rate; | ||
334 | else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) | ||
335 | ahb_rate = ddr_pll / (postdiv + 1); | ||
336 | else | ||
337 | ahb_rate = cpu_pll / (postdiv + 1); | ||
338 | |||
339 | ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||
340 | ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||
341 | ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||
342 | |||
343 | clk_ctrl = __raw_readl(pll_base + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG); | ||
344 | if (clk_ctrl & AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL) | ||
345 | ath79_set_clk(ATH79_CLK_MDIO, 100 * 1000 * 1000); | ||
346 | |||
347 | iounmap(dpll_base); | ||
348 | } | ||
349 | |||
350 | static void __init qca953x_clocks_init(void __iomem *pll_base) | ||
351 | { | ||
352 | unsigned long ref_rate; | ||
353 | unsigned long cpu_rate; | ||
354 | unsigned long ddr_rate; | ||
355 | unsigned long ahb_rate; | ||
356 | u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; | ||
357 | u32 cpu_pll, ddr_pll; | ||
358 | u32 bootstrap; | ||
359 | |||
360 | bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP); | ||
361 | if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40) | ||
362 | ref_rate = 40 * 1000 * 1000; | ||
363 | else | ||
364 | ref_rate = 25 * 1000 * 1000; | ||
365 | |||
366 | ref_rate = ath79_setup_ref_clk(ref_rate); | ||
367 | |||
368 | pll = __raw_readl(pll_base + QCA953X_PLL_CPU_CONFIG_REG); | ||
369 | out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||
370 | QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||
371 | ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||
372 | QCA953X_PLL_CPU_CONFIG_REFDIV_MASK; | ||
373 | nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) & | ||
374 | QCA953X_PLL_CPU_CONFIG_NINT_MASK; | ||
375 | frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) & | ||
376 | QCA953X_PLL_CPU_CONFIG_NFRAC_MASK; | ||
377 | |||
378 | cpu_pll = nint * ref_rate / ref_div; | ||
379 | cpu_pll += frac * (ref_rate >> 6) / ref_div; | ||
380 | cpu_pll /= (1 << out_div); | ||
381 | |||
382 | pll = __raw_readl(pll_base + QCA953X_PLL_DDR_CONFIG_REG); | ||
383 | out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | ||
384 | QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK; | ||
385 | ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | ||
386 | QCA953X_PLL_DDR_CONFIG_REFDIV_MASK; | ||
387 | nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) & | ||
388 | QCA953X_PLL_DDR_CONFIG_NINT_MASK; | ||
389 | frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) & | ||
390 | QCA953X_PLL_DDR_CONFIG_NFRAC_MASK; | ||
391 | |||
392 | ddr_pll = nint * ref_rate / ref_div; | ||
393 | ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4); | ||
394 | ddr_pll /= (1 << out_div); | ||
395 | |||
396 | clk_ctrl = __raw_readl(pll_base + QCA953X_PLL_CLK_CTRL_REG); | ||
397 | |||
398 | postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & | ||
399 | QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; | ||
400 | |||
401 | if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS) | ||
402 | cpu_rate = ref_rate; | ||
403 | else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) | ||
404 | cpu_rate = cpu_pll / (postdiv + 1); | ||
405 | else | ||
406 | cpu_rate = ddr_pll / (postdiv + 1); | ||
407 | |||
408 | postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & | ||
409 | QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; | ||
410 | |||
411 | if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS) | ||
412 | ddr_rate = ref_rate; | ||
413 | else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) | ||
414 | ddr_rate = ddr_pll / (postdiv + 1); | ||
415 | else | ||
416 | ddr_rate = cpu_pll / (postdiv + 1); | ||
417 | |||
418 | postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & | ||
419 | QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; | ||
420 | |||
421 | if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS) | ||
422 | ahb_rate = ref_rate; | ||
423 | else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) | ||
424 | ahb_rate = ddr_pll / (postdiv + 1); | ||
425 | else | ||
426 | ahb_rate = cpu_pll / (postdiv + 1); | ||
427 | |||
428 | ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||
429 | ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||
430 | ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||
431 | } | ||
432 | |||
433 | static void __init qca955x_clocks_init(void __iomem *pll_base) | ||
434 | { | ||
435 | unsigned long ref_rate; | ||
436 | unsigned long cpu_rate; | ||
437 | unsigned long ddr_rate; | ||
438 | unsigned long ahb_rate; | ||
439 | u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; | ||
440 | u32 cpu_pll, ddr_pll; | ||
441 | u32 bootstrap; | ||
442 | |||
443 | bootstrap = ath79_reset_rr(QCA955X_RESET_REG_BOOTSTRAP); | ||
444 | if (bootstrap & QCA955X_BOOTSTRAP_REF_CLK_40) | ||
445 | ref_rate = 40 * 1000 * 1000; | ||
446 | else | ||
447 | ref_rate = 25 * 1000 * 1000; | ||
448 | |||
449 | ref_rate = ath79_setup_ref_clk(ref_rate); | ||
450 | |||
451 | pll = __raw_readl(pll_base + QCA955X_PLL_CPU_CONFIG_REG); | ||
452 | out_div = (pll >> QCA955X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||
453 | QCA955X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||
454 | ref_div = (pll >> QCA955X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||
455 | QCA955X_PLL_CPU_CONFIG_REFDIV_MASK; | ||
456 | nint = (pll >> QCA955X_PLL_CPU_CONFIG_NINT_SHIFT) & | ||
457 | QCA955X_PLL_CPU_CONFIG_NINT_MASK; | ||
458 | frac = (pll >> QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT) & | ||
459 | QCA955X_PLL_CPU_CONFIG_NFRAC_MASK; | ||
460 | |||
461 | cpu_pll = nint * ref_rate / ref_div; | ||
462 | cpu_pll += frac * ref_rate / (ref_div * (1 << 6)); | ||
463 | cpu_pll /= (1 << out_div); | ||
464 | |||
465 | pll = __raw_readl(pll_base + QCA955X_PLL_DDR_CONFIG_REG); | ||
466 | out_div = (pll >> QCA955X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | ||
467 | QCA955X_PLL_DDR_CONFIG_OUTDIV_MASK; | ||
468 | ref_div = (pll >> QCA955X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | ||
469 | QCA955X_PLL_DDR_CONFIG_REFDIV_MASK; | ||
470 | nint = (pll >> QCA955X_PLL_DDR_CONFIG_NINT_SHIFT) & | ||
471 | QCA955X_PLL_DDR_CONFIG_NINT_MASK; | ||
472 | frac = (pll >> QCA955X_PLL_DDR_CONFIG_NFRAC_SHIFT) & | ||
473 | QCA955X_PLL_DDR_CONFIG_NFRAC_MASK; | ||
474 | |||
475 | ddr_pll = nint * ref_rate / ref_div; | ||
476 | ddr_pll += frac * ref_rate / (ref_div * (1 << 10)); | ||
477 | ddr_pll /= (1 << out_div); | ||
478 | |||
479 | clk_ctrl = __raw_readl(pll_base + QCA955X_PLL_CLK_CTRL_REG); | ||
480 | |||
481 | postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & | ||
482 | QCA955X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; | ||
483 | |||
484 | if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPU_PLL_BYPASS) | ||
485 | cpu_rate = ref_rate; | ||
486 | else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL) | ||
487 | cpu_rate = ddr_pll / (postdiv + 1); | ||
488 | else | ||
489 | cpu_rate = cpu_pll / (postdiv + 1); | ||
490 | |||
491 | postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & | ||
492 | QCA955X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; | ||
493 | |||
494 | if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDR_PLL_BYPASS) | ||
495 | ddr_rate = ref_rate; | ||
496 | else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL) | ||
497 | ddr_rate = cpu_pll / (postdiv + 1); | ||
498 | else | ||
499 | ddr_rate = ddr_pll / (postdiv + 1); | ||
500 | |||
501 | postdiv = (clk_ctrl >> QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & | ||
502 | QCA955X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; | ||
503 | |||
504 | if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHB_PLL_BYPASS) | ||
505 | ahb_rate = ref_rate; | ||
506 | else if (clk_ctrl & QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) | ||
507 | ahb_rate = ddr_pll / (postdiv + 1); | ||
508 | else | ||
509 | ahb_rate = cpu_pll / (postdiv + 1); | ||
510 | |||
511 | ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||
512 | ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||
513 | ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||
514 | } | ||
515 | |||
516 | static void __init qca956x_clocks_init(void __iomem *pll_base) | ||
517 | { | ||
518 | unsigned long ref_rate; | ||
519 | unsigned long cpu_rate; | ||
520 | unsigned long ddr_rate; | ||
521 | unsigned long ahb_rate; | ||
522 | u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv; | ||
523 | u32 cpu_pll, ddr_pll; | ||
524 | u32 bootstrap; | ||
525 | |||
526 | /* | ||
527 | * QCA956x timer init workaround has to be applied right before setting | ||
528 | * up the clock. Else, there will be no jiffies | ||
529 | */ | ||
530 | u32 misc; | ||
531 | |||
532 | misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
533 | misc |= MISC_INT_MIPS_SI_TIMERINT_MASK; | ||
534 | ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc); | ||
535 | |||
536 | bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP); | ||
537 | if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40) | ||
538 | ref_rate = 40 * 1000 * 1000; | ||
539 | else | ||
540 | ref_rate = 25 * 1000 * 1000; | ||
541 | |||
542 | ref_rate = ath79_setup_ref_clk(ref_rate); | ||
543 | |||
544 | pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG_REG); | ||
545 | out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||
546 | QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||
547 | ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||
548 | QCA956X_PLL_CPU_CONFIG_REFDIV_MASK; | ||
549 | |||
550 | pll = __raw_readl(pll_base + QCA956X_PLL_CPU_CONFIG1_REG); | ||
551 | nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) & | ||
552 | QCA956X_PLL_CPU_CONFIG1_NINT_MASK; | ||
553 | hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) & | ||
554 | QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK; | ||
555 | lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) & | ||
556 | QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK; | ||
557 | |||
558 | cpu_pll = nint * ref_rate / ref_div; | ||
559 | cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); | ||
560 | cpu_pll += (hfrac >> 13) * ref_rate / ref_div; | ||
561 | cpu_pll /= (1 << out_div); | ||
562 | |||
563 | pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG_REG); | ||
564 | out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | ||
565 | QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK; | ||
566 | ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | ||
567 | QCA956X_PLL_DDR_CONFIG_REFDIV_MASK; | ||
568 | pll = __raw_readl(pll_base + QCA956X_PLL_DDR_CONFIG1_REG); | ||
569 | nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) & | ||
570 | QCA956X_PLL_DDR_CONFIG1_NINT_MASK; | ||
571 | hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) & | ||
572 | QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK; | ||
573 | lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) & | ||
574 | QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK; | ||
575 | |||
576 | ddr_pll = nint * ref_rate / ref_div; | ||
577 | ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13); | ||
578 | ddr_pll += (hfrac >> 13) * ref_rate / ref_div; | ||
579 | ddr_pll /= (1 << out_div); | ||
580 | |||
581 | clk_ctrl = __raw_readl(pll_base + QCA956X_PLL_CLK_CTRL_REG); | ||
582 | |||
583 | postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) & | ||
584 | QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK; | ||
585 | |||
586 | if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS) | ||
587 | cpu_rate = ref_rate; | ||
588 | else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL) | ||
589 | cpu_rate = ddr_pll / (postdiv + 1); | ||
590 | else | ||
591 | cpu_rate = cpu_pll / (postdiv + 1); | ||
592 | |||
593 | postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) & | ||
594 | QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK; | ||
595 | |||
596 | if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS) | ||
597 | ddr_rate = ref_rate; | ||
598 | else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL) | ||
599 | ddr_rate = cpu_pll / (postdiv + 1); | ||
600 | else | ||
601 | ddr_rate = ddr_pll / (postdiv + 1); | ||
602 | |||
603 | postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) & | ||
604 | QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK; | ||
605 | |||
606 | if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS) | ||
607 | ahb_rate = ref_rate; | ||
608 | else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) | ||
609 | ahb_rate = ddr_pll / (postdiv + 1); | ||
610 | else | ||
611 | ahb_rate = cpu_pll / (postdiv + 1); | ||
612 | |||
613 | ath79_set_clk(ATH79_CLK_CPU, cpu_rate); | ||
614 | ath79_set_clk(ATH79_CLK_DDR, ddr_rate); | ||
615 | ath79_set_clk(ATH79_CLK_AHB, ahb_rate); | ||
616 | } | ||
617 | |||
618 | static void __init ath79_clocks_init_dt(struct device_node *np) | ||
619 | { | ||
620 | struct clk *ref_clk; | ||
621 | void __iomem *pll_base; | ||
622 | |||
623 | ref_clk = of_clk_get(np, 0); | ||
624 | if (!IS_ERR(ref_clk)) | ||
625 | clks[ATH79_CLK_REF] = ref_clk; | ||
626 | |||
627 | pll_base = of_iomap(np, 0); | ||
628 | if (!pll_base) { | ||
629 | pr_err("%pOF: can't map pll registers\n", np); | ||
630 | goto err_clk; | ||
631 | } | ||
632 | |||
633 | if (of_device_is_compatible(np, "qca,ar7100-pll")) | ||
634 | ar71xx_clocks_init(pll_base); | ||
635 | else if (of_device_is_compatible(np, "qca,ar7240-pll") || | ||
636 | of_device_is_compatible(np, "qca,ar9130-pll")) | ||
637 | ar724x_clocks_init(pll_base); | ||
638 | else if (of_device_is_compatible(np, "qca,ar9330-pll")) | ||
639 | ar933x_clocks_init(pll_base); | ||
640 | else if (of_device_is_compatible(np, "qca,ar9340-pll")) | ||
641 | ar934x_clocks_init(pll_base); | ||
642 | else if (of_device_is_compatible(np, "qca,qca9530-pll")) | ||
643 | qca953x_clocks_init(pll_base); | ||
644 | else if (of_device_is_compatible(np, "qca,qca9550-pll")) | ||
645 | qca955x_clocks_init(pll_base); | ||
646 | else if (of_device_is_compatible(np, "qca,qca9560-pll")) | ||
647 | qca956x_clocks_init(pll_base); | ||
648 | |||
649 | if (!clks[ATH79_CLK_MDIO]) | ||
650 | clks[ATH79_CLK_MDIO] = clks[ATH79_CLK_REF]; | ||
651 | |||
652 | if (of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data)) { | ||
653 | pr_err("%pOF: could not register clk provider\n", np); | ||
654 | goto err_iounmap; | ||
655 | } | ||
656 | |||
657 | return; | ||
658 | |||
659 | err_iounmap: | ||
660 | iounmap(pll_base); | ||
661 | |||
662 | err_clk: | ||
663 | clk_put(ref_clk); | ||
664 | } | ||
665 | |||
666 | CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt); | ||
667 | CLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ath79_clocks_init_dt); | ||
668 | CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt); | ||
669 | CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt); | ||
670 | CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ath79_clocks_init_dt); | ||
671 | CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt); | ||
672 | CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt); | ||
673 | CLK_OF_DECLARE(ar9560_clk, "qca,qca9560-pll", ath79_clocks_init_dt); | ||
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c new file mode 100644 index 000000000..137abbc65 --- /dev/null +++ b/arch/mips/ath79/common.c | |||
@@ -0,0 +1,149 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /* | ||
3 | * Atheros AR71XX/AR724X/AR913X common routines | ||
4 | * | ||
5 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||
6 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
7 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
8 | * | ||
9 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/export.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | |||
17 | #include <asm/mach-ath79/ath79.h> | ||
18 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
19 | #include "common.h" | ||
20 | |||
21 | static DEFINE_SPINLOCK(ath79_device_reset_lock); | ||
22 | |||
23 | u32 ath79_cpu_freq; | ||
24 | EXPORT_SYMBOL_GPL(ath79_cpu_freq); | ||
25 | |||
26 | u32 ath79_ahb_freq; | ||
27 | EXPORT_SYMBOL_GPL(ath79_ahb_freq); | ||
28 | |||
29 | u32 ath79_ddr_freq; | ||
30 | EXPORT_SYMBOL_GPL(ath79_ddr_freq); | ||
31 | |||
32 | enum ath79_soc_type ath79_soc; | ||
33 | unsigned int ath79_soc_rev; | ||
34 | |||
35 | void __iomem *ath79_pll_base; | ||
36 | void __iomem *ath79_reset_base; | ||
37 | EXPORT_SYMBOL_GPL(ath79_reset_base); | ||
38 | static void __iomem *ath79_ddr_base; | ||
39 | static void __iomem *ath79_ddr_wb_flush_base; | ||
40 | static void __iomem *ath79_ddr_pci_win_base; | ||
41 | |||
42 | void ath79_ddr_ctrl_init(void) | ||
43 | { | ||
44 | ath79_ddr_base = ioremap(AR71XX_DDR_CTRL_BASE, | ||
45 | AR71XX_DDR_CTRL_SIZE); | ||
46 | if (soc_is_ar913x() || soc_is_ar724x() || soc_is_ar933x()) { | ||
47 | ath79_ddr_wb_flush_base = ath79_ddr_base + 0x7c; | ||
48 | ath79_ddr_pci_win_base = 0; | ||
49 | } else { | ||
50 | ath79_ddr_wb_flush_base = ath79_ddr_base + 0x9c; | ||
51 | ath79_ddr_pci_win_base = ath79_ddr_base + 0x7c; | ||
52 | } | ||
53 | } | ||
54 | EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init); | ||
55 | |||
56 | void ath79_ddr_wb_flush(u32 reg) | ||
57 | { | ||
58 | void __iomem *flush_reg = ath79_ddr_wb_flush_base + (reg * 4); | ||
59 | |||
60 | /* Flush the DDR write buffer. */ | ||
61 | __raw_writel(0x1, flush_reg); | ||
62 | while (__raw_readl(flush_reg) & 0x1) | ||
63 | ; | ||
64 | |||
65 | /* It must be run twice. */ | ||
66 | __raw_writel(0x1, flush_reg); | ||
67 | while (__raw_readl(flush_reg) & 0x1) | ||
68 | ; | ||
69 | } | ||
70 | EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush); | ||
71 | |||
72 | void ath79_ddr_set_pci_windows(void) | ||
73 | { | ||
74 | BUG_ON(!ath79_ddr_pci_win_base); | ||
75 | |||
76 | __raw_writel(AR71XX_PCI_WIN0_OFFS, ath79_ddr_pci_win_base + 0x0); | ||
77 | __raw_writel(AR71XX_PCI_WIN1_OFFS, ath79_ddr_pci_win_base + 0x4); | ||
78 | __raw_writel(AR71XX_PCI_WIN2_OFFS, ath79_ddr_pci_win_base + 0x8); | ||
79 | __raw_writel(AR71XX_PCI_WIN3_OFFS, ath79_ddr_pci_win_base + 0xc); | ||
80 | __raw_writel(AR71XX_PCI_WIN4_OFFS, ath79_ddr_pci_win_base + 0x10); | ||
81 | __raw_writel(AR71XX_PCI_WIN5_OFFS, ath79_ddr_pci_win_base + 0x14); | ||
82 | __raw_writel(AR71XX_PCI_WIN6_OFFS, ath79_ddr_pci_win_base + 0x18); | ||
83 | __raw_writel(AR71XX_PCI_WIN7_OFFS, ath79_ddr_pci_win_base + 0x1c); | ||
84 | } | ||
85 | EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows); | ||
86 | |||
87 | void ath79_device_reset_set(u32 mask) | ||
88 | { | ||
89 | unsigned long flags; | ||
90 | u32 reg; | ||
91 | u32 t; | ||
92 | |||
93 | if (soc_is_ar71xx()) | ||
94 | reg = AR71XX_RESET_REG_RESET_MODULE; | ||
95 | else if (soc_is_ar724x()) | ||
96 | reg = AR724X_RESET_REG_RESET_MODULE; | ||
97 | else if (soc_is_ar913x()) | ||
98 | reg = AR913X_RESET_REG_RESET_MODULE; | ||
99 | else if (soc_is_ar933x()) | ||
100 | reg = AR933X_RESET_REG_RESET_MODULE; | ||
101 | else if (soc_is_ar934x()) | ||
102 | reg = AR934X_RESET_REG_RESET_MODULE; | ||
103 | else if (soc_is_qca953x()) | ||
104 | reg = QCA953X_RESET_REG_RESET_MODULE; | ||
105 | else if (soc_is_qca955x()) | ||
106 | reg = QCA955X_RESET_REG_RESET_MODULE; | ||
107 | else if (soc_is_qca956x() || soc_is_tp9343()) | ||
108 | reg = QCA956X_RESET_REG_RESET_MODULE; | ||
109 | else | ||
110 | BUG(); | ||
111 | |||
112 | spin_lock_irqsave(&ath79_device_reset_lock, flags); | ||
113 | t = ath79_reset_rr(reg); | ||
114 | ath79_reset_wr(reg, t | mask); | ||
115 | spin_unlock_irqrestore(&ath79_device_reset_lock, flags); | ||
116 | } | ||
117 | EXPORT_SYMBOL_GPL(ath79_device_reset_set); | ||
118 | |||
119 | void ath79_device_reset_clear(u32 mask) | ||
120 | { | ||
121 | unsigned long flags; | ||
122 | u32 reg; | ||
123 | u32 t; | ||
124 | |||
125 | if (soc_is_ar71xx()) | ||
126 | reg = AR71XX_RESET_REG_RESET_MODULE; | ||
127 | else if (soc_is_ar724x()) | ||
128 | reg = AR724X_RESET_REG_RESET_MODULE; | ||
129 | else if (soc_is_ar913x()) | ||
130 | reg = AR913X_RESET_REG_RESET_MODULE; | ||
131 | else if (soc_is_ar933x()) | ||
132 | reg = AR933X_RESET_REG_RESET_MODULE; | ||
133 | else if (soc_is_ar934x()) | ||
134 | reg = AR934X_RESET_REG_RESET_MODULE; | ||
135 | else if (soc_is_qca953x()) | ||
136 | reg = QCA953X_RESET_REG_RESET_MODULE; | ||
137 | else if (soc_is_qca955x()) | ||
138 | reg = QCA955X_RESET_REG_RESET_MODULE; | ||
139 | else if (soc_is_qca956x() || soc_is_tp9343()) | ||
140 | reg = QCA956X_RESET_REG_RESET_MODULE; | ||
141 | else | ||
142 | BUG(); | ||
143 | |||
144 | spin_lock_irqsave(&ath79_device_reset_lock, flags); | ||
145 | t = ath79_reset_rr(reg); | ||
146 | ath79_reset_wr(reg, t & ~mask); | ||
147 | spin_unlock_irqrestore(&ath79_device_reset_lock, flags); | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(ath79_device_reset_clear); | ||
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h new file mode 100644 index 000000000..47fb66d7b --- /dev/null +++ b/arch/mips/ath79/common.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
2 | /* | ||
3 | * Atheros AR71XX/AR724X/AR913X common definitions | ||
4 | * | ||
5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
7 | * | ||
8 | * Parts of this file are based on Atheros' 2.6.15 BSP | ||
9 | */ | ||
10 | |||
11 | #ifndef __ATH79_COMMON_H | ||
12 | #define __ATH79_COMMON_H | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | |||
16 | #define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024) | ||
17 | #define ATH79_MEM_SIZE_MAX (256 * 1024 * 1024) | ||
18 | |||
19 | void ath79_ddr_ctrl_init(void); | ||
20 | |||
21 | #endif /* __ATH79_COMMON_H */ | ||
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c new file mode 100644 index 000000000..782732cd1 --- /dev/null +++ b/arch/mips/ath79/early_printk.c | |||
@@ -0,0 +1,146 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /* | ||
3 | * Atheros AR7XXX/AR9XXX SoC early printk support | ||
4 | * | ||
5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/io.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/serial_reg.h> | ||
12 | #include <asm/addrspace.h> | ||
13 | #include <asm/setup.h> | ||
14 | |||
15 | #include <asm/mach-ath79/ath79.h> | ||
16 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
17 | #include <asm/mach-ath79/ar933x_uart.h> | ||
18 | |||
19 | static void (*_prom_putchar)(char); | ||
20 | |||
21 | static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val) | ||
22 | { | ||
23 | u32 t; | ||
24 | |||
25 | do { | ||
26 | t = __raw_readl(reg); | ||
27 | if ((t & mask) == val) | ||
28 | break; | ||
29 | } while (1); | ||
30 | } | ||
31 | |||
32 | #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) | ||
33 | |||
34 | static void prom_putchar_ar71xx(char ch) | ||
35 | { | ||
36 | void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); | ||
37 | |||
38 | prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY); | ||
39 | __raw_writel((unsigned char)ch, base + UART_TX * 4); | ||
40 | prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY); | ||
41 | } | ||
42 | |||
43 | static void prom_putchar_ar933x(char ch) | ||
44 | { | ||
45 | void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE)); | ||
46 | |||
47 | prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, | ||
48 | AR933X_UART_DATA_TX_CSR); | ||
49 | __raw_writel(AR933X_UART_DATA_TX_CSR | (unsigned char)ch, | ||
50 | base + AR933X_UART_DATA_REG); | ||
51 | prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR, | ||
52 | AR933X_UART_DATA_TX_CSR); | ||
53 | } | ||
54 | |||
55 | static void prom_putchar_dummy(char ch) | ||
56 | { | ||
57 | /* nothing to do */ | ||
58 | } | ||
59 | |||
60 | static void prom_enable_uart(u32 id) | ||
61 | { | ||
62 | void __iomem *gpio_base; | ||
63 | u32 uart_en; | ||
64 | u32 t; | ||
65 | |||
66 | switch (id) { | ||
67 | case REV_ID_MAJOR_AR71XX: | ||
68 | uart_en = AR71XX_GPIO_FUNC_UART_EN; | ||
69 | break; | ||
70 | |||
71 | case REV_ID_MAJOR_AR7240: | ||
72 | case REV_ID_MAJOR_AR7241: | ||
73 | case REV_ID_MAJOR_AR7242: | ||
74 | uart_en = AR724X_GPIO_FUNC_UART_EN; | ||
75 | break; | ||
76 | |||
77 | case REV_ID_MAJOR_AR913X: | ||
78 | uart_en = AR913X_GPIO_FUNC_UART_EN; | ||
79 | break; | ||
80 | |||
81 | case REV_ID_MAJOR_AR9330: | ||
82 | case REV_ID_MAJOR_AR9331: | ||
83 | uart_en = AR933X_GPIO_FUNC_UART_EN; | ||
84 | break; | ||
85 | |||
86 | case REV_ID_MAJOR_AR9341: | ||
87 | case REV_ID_MAJOR_AR9342: | ||
88 | case REV_ID_MAJOR_AR9344: | ||
89 | /* TODO */ | ||
90 | default: | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | gpio_base = (void __iomem *)KSEG1ADDR(AR71XX_GPIO_BASE); | ||
95 | t = __raw_readl(gpio_base + AR71XX_GPIO_REG_FUNC); | ||
96 | t |= uart_en; | ||
97 | __raw_writel(t, gpio_base + AR71XX_GPIO_REG_FUNC); | ||
98 | } | ||
99 | |||
100 | static void prom_putchar_init(void) | ||
101 | { | ||
102 | void __iomem *base; | ||
103 | u32 id; | ||
104 | |||
105 | base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE)); | ||
106 | id = __raw_readl(base + AR71XX_RESET_REG_REV_ID); | ||
107 | id &= REV_ID_MAJOR_MASK; | ||
108 | |||
109 | switch (id) { | ||
110 | case REV_ID_MAJOR_AR71XX: | ||
111 | case REV_ID_MAJOR_AR7240: | ||
112 | case REV_ID_MAJOR_AR7241: | ||
113 | case REV_ID_MAJOR_AR7242: | ||
114 | case REV_ID_MAJOR_AR913X: | ||
115 | case REV_ID_MAJOR_AR9341: | ||
116 | case REV_ID_MAJOR_AR9342: | ||
117 | case REV_ID_MAJOR_AR9344: | ||
118 | case REV_ID_MAJOR_QCA9533: | ||
119 | case REV_ID_MAJOR_QCA9533_V2: | ||
120 | case REV_ID_MAJOR_QCA9556: | ||
121 | case REV_ID_MAJOR_QCA9558: | ||
122 | case REV_ID_MAJOR_TP9343: | ||
123 | case REV_ID_MAJOR_QCA956X: | ||
124 | _prom_putchar = prom_putchar_ar71xx; | ||
125 | break; | ||
126 | |||
127 | case REV_ID_MAJOR_AR9330: | ||
128 | case REV_ID_MAJOR_AR9331: | ||
129 | _prom_putchar = prom_putchar_ar933x; | ||
130 | break; | ||
131 | |||
132 | default: | ||
133 | _prom_putchar = prom_putchar_dummy; | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | prom_enable_uart(id); | ||
138 | } | ||
139 | |||
140 | void prom_putchar(char ch) | ||
141 | { | ||
142 | if (!_prom_putchar) | ||
143 | prom_putchar_init(); | ||
144 | |||
145 | _prom_putchar(ch); | ||
146 | } | ||
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c new file mode 100644 index 000000000..25724b4e9 --- /dev/null +++ b/arch/mips/ath79/prom.c | |||
@@ -0,0 +1,39 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /* | ||
3 | * Atheros AR71XX/AR724X/AR913X specific prom routines | ||
4 | * | ||
5 | * Copyright (C) 2015 Laurent Fasnacht <l@libres.ch> | ||
6 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
7 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <linux/initrd.h> | ||
15 | |||
16 | #include <asm/bootinfo.h> | ||
17 | #include <asm/addrspace.h> | ||
18 | #include <asm/fw/fw.h> | ||
19 | |||
20 | #include "common.h" | ||
21 | |||
22 | void __init prom_init(void) | ||
23 | { | ||
24 | fw_init_cmdline(); | ||
25 | |||
26 | #ifdef CONFIG_BLK_DEV_INITRD | ||
27 | /* Read the initrd address from the firmware environment */ | ||
28 | initrd_start = fw_getenvl("initrd_start"); | ||
29 | if (initrd_start) { | ||
30 | initrd_start = KSEG0ADDR(initrd_start); | ||
31 | initrd_end = initrd_start + fw_getenvl("initrd_size"); | ||
32 | } | ||
33 | #endif | ||
34 | } | ||
35 | |||
36 | void __init prom_free_prom_memory(void) | ||
37 | { | ||
38 | /* We do not have to prom memory to free */ | ||
39 | } | ||
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c new file mode 100644 index 000000000..7e7bf9c2a --- /dev/null +++ b/arch/mips/ath79/setup.c | |||
@@ -0,0 +1,279 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0-only | ||
2 | /* | ||
3 | * Atheros AR71XX/AR724X/AR913X specific setup | ||
4 | * | ||
5 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||
6 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
7 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
8 | * | ||
9 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/memblock.h> | ||
16 | #include <linux/err.h> | ||
17 | #include <linux/clk.h> | ||
18 | #include <linux/of_clk.h> | ||
19 | #include <linux/of_fdt.h> | ||
20 | #include <linux/irqchip.h> | ||
21 | |||
22 | #include <asm/bootinfo.h> | ||
23 | #include <asm/idle.h> | ||
24 | #include <asm/time.h> /* for mips_hpt_frequency */ | ||
25 | #include <asm/reboot.h> /* for _machine_{restart,halt} */ | ||
26 | #include <asm/prom.h> | ||
27 | #include <asm/fw/fw.h> | ||
28 | |||
29 | #include <asm/mach-ath79/ath79.h> | ||
30 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
31 | #include "common.h" | ||
32 | |||
33 | #define ATH79_SYS_TYPE_LEN 64 | ||
34 | |||
35 | static char ath79_sys_type[ATH79_SYS_TYPE_LEN]; | ||
36 | |||
37 | static void ath79_restart(char *command) | ||
38 | { | ||
39 | local_irq_disable(); | ||
40 | ath79_device_reset_set(AR71XX_RESET_FULL_CHIP); | ||
41 | for (;;) | ||
42 | if (cpu_wait) | ||
43 | cpu_wait(); | ||
44 | } | ||
45 | |||
46 | static void ath79_halt(void) | ||
47 | { | ||
48 | while (1) | ||
49 | cpu_wait(); | ||
50 | } | ||
51 | |||
52 | static void __init ath79_detect_sys_type(void) | ||
53 | { | ||
54 | char *chip = "????"; | ||
55 | u32 id; | ||
56 | u32 major; | ||
57 | u32 minor; | ||
58 | u32 rev = 0; | ||
59 | u32 ver = 1; | ||
60 | |||
61 | id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID); | ||
62 | major = id & REV_ID_MAJOR_MASK; | ||
63 | |||
64 | switch (major) { | ||
65 | case REV_ID_MAJOR_AR71XX: | ||
66 | minor = id & AR71XX_REV_ID_MINOR_MASK; | ||
67 | rev = id >> AR71XX_REV_ID_REVISION_SHIFT; | ||
68 | rev &= AR71XX_REV_ID_REVISION_MASK; | ||
69 | switch (minor) { | ||
70 | case AR71XX_REV_ID_MINOR_AR7130: | ||
71 | ath79_soc = ATH79_SOC_AR7130; | ||
72 | chip = "7130"; | ||
73 | break; | ||
74 | |||
75 | case AR71XX_REV_ID_MINOR_AR7141: | ||
76 | ath79_soc = ATH79_SOC_AR7141; | ||
77 | chip = "7141"; | ||
78 | break; | ||
79 | |||
80 | case AR71XX_REV_ID_MINOR_AR7161: | ||
81 | ath79_soc = ATH79_SOC_AR7161; | ||
82 | chip = "7161"; | ||
83 | break; | ||
84 | } | ||
85 | break; | ||
86 | |||
87 | case REV_ID_MAJOR_AR7240: | ||
88 | ath79_soc = ATH79_SOC_AR7240; | ||
89 | chip = "7240"; | ||
90 | rev = id & AR724X_REV_ID_REVISION_MASK; | ||
91 | break; | ||
92 | |||
93 | case REV_ID_MAJOR_AR7241: | ||
94 | ath79_soc = ATH79_SOC_AR7241; | ||
95 | chip = "7241"; | ||
96 | rev = id & AR724X_REV_ID_REVISION_MASK; | ||
97 | break; | ||
98 | |||
99 | case REV_ID_MAJOR_AR7242: | ||
100 | ath79_soc = ATH79_SOC_AR7242; | ||
101 | chip = "7242"; | ||
102 | rev = id & AR724X_REV_ID_REVISION_MASK; | ||
103 | break; | ||
104 | |||
105 | case REV_ID_MAJOR_AR913X: | ||
106 | minor = id & AR913X_REV_ID_MINOR_MASK; | ||
107 | rev = id >> AR913X_REV_ID_REVISION_SHIFT; | ||
108 | rev &= AR913X_REV_ID_REVISION_MASK; | ||
109 | switch (minor) { | ||
110 | case AR913X_REV_ID_MINOR_AR9130: | ||
111 | ath79_soc = ATH79_SOC_AR9130; | ||
112 | chip = "9130"; | ||
113 | break; | ||
114 | |||
115 | case AR913X_REV_ID_MINOR_AR9132: | ||
116 | ath79_soc = ATH79_SOC_AR9132; | ||
117 | chip = "9132"; | ||
118 | break; | ||
119 | } | ||
120 | break; | ||
121 | |||
122 | case REV_ID_MAJOR_AR9330: | ||
123 | ath79_soc = ATH79_SOC_AR9330; | ||
124 | chip = "9330"; | ||
125 | rev = id & AR933X_REV_ID_REVISION_MASK; | ||
126 | break; | ||
127 | |||
128 | case REV_ID_MAJOR_AR9331: | ||
129 | ath79_soc = ATH79_SOC_AR9331; | ||
130 | chip = "9331"; | ||
131 | rev = id & AR933X_REV_ID_REVISION_MASK; | ||
132 | break; | ||
133 | |||
134 | case REV_ID_MAJOR_AR9341: | ||
135 | ath79_soc = ATH79_SOC_AR9341; | ||
136 | chip = "9341"; | ||
137 | rev = id & AR934X_REV_ID_REVISION_MASK; | ||
138 | break; | ||
139 | |||
140 | case REV_ID_MAJOR_AR9342: | ||
141 | ath79_soc = ATH79_SOC_AR9342; | ||
142 | chip = "9342"; | ||
143 | rev = id & AR934X_REV_ID_REVISION_MASK; | ||
144 | break; | ||
145 | |||
146 | case REV_ID_MAJOR_AR9344: | ||
147 | ath79_soc = ATH79_SOC_AR9344; | ||
148 | chip = "9344"; | ||
149 | rev = id & AR934X_REV_ID_REVISION_MASK; | ||
150 | break; | ||
151 | |||
152 | case REV_ID_MAJOR_QCA9533_V2: | ||
153 | ver = 2; | ||
154 | ath79_soc_rev = 2; | ||
155 | fallthrough; | ||
156 | case REV_ID_MAJOR_QCA9533: | ||
157 | ath79_soc = ATH79_SOC_QCA9533; | ||
158 | chip = "9533"; | ||
159 | rev = id & QCA953X_REV_ID_REVISION_MASK; | ||
160 | break; | ||
161 | |||
162 | case REV_ID_MAJOR_QCA9556: | ||
163 | ath79_soc = ATH79_SOC_QCA9556; | ||
164 | chip = "9556"; | ||
165 | rev = id & QCA955X_REV_ID_REVISION_MASK; | ||
166 | break; | ||
167 | |||
168 | case REV_ID_MAJOR_QCA9558: | ||
169 | ath79_soc = ATH79_SOC_QCA9558; | ||
170 | chip = "9558"; | ||
171 | rev = id & QCA955X_REV_ID_REVISION_MASK; | ||
172 | break; | ||
173 | |||
174 | case REV_ID_MAJOR_QCA956X: | ||
175 | ath79_soc = ATH79_SOC_QCA956X; | ||
176 | chip = "956X"; | ||
177 | rev = id & QCA956X_REV_ID_REVISION_MASK; | ||
178 | break; | ||
179 | |||
180 | case REV_ID_MAJOR_TP9343: | ||
181 | ath79_soc = ATH79_SOC_TP9343; | ||
182 | chip = "9343"; | ||
183 | rev = id & QCA956X_REV_ID_REVISION_MASK; | ||
184 | break; | ||
185 | |||
186 | default: | ||
187 | panic("ath79: unknown SoC, id:0x%08x", id); | ||
188 | } | ||
189 | |||
190 | if (ver == 1) | ||
191 | ath79_soc_rev = rev; | ||
192 | |||
193 | if (soc_is_qca953x() || soc_is_qca955x() || soc_is_qca956x()) | ||
194 | sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s ver %u rev %u", | ||
195 | chip, ver, rev); | ||
196 | else if (soc_is_tp9343()) | ||
197 | sprintf(ath79_sys_type, "Qualcomm Atheros TP%s rev %u", | ||
198 | chip, rev); | ||
199 | else | ||
200 | sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev); | ||
201 | pr_info("SoC: %s\n", ath79_sys_type); | ||
202 | } | ||
203 | |||
204 | const char *get_system_type(void) | ||
205 | { | ||
206 | return ath79_sys_type; | ||
207 | } | ||
208 | |||
209 | unsigned int get_c0_compare_int(void) | ||
210 | { | ||
211 | return CP0_LEGACY_COMPARE_IRQ; | ||
212 | } | ||
213 | |||
214 | void __init plat_mem_setup(void) | ||
215 | { | ||
216 | unsigned long fdt_start; | ||
217 | |||
218 | set_io_port_base(KSEG1); | ||
219 | |||
220 | /* Get the position of the FDT passed by the bootloader */ | ||
221 | fdt_start = fw_getenvl("fdt_start"); | ||
222 | if (fdt_start) | ||
223 | __dt_setup_arch((void *)KSEG0ADDR(fdt_start)); | ||
224 | else if (fw_passed_dtb) | ||
225 | __dt_setup_arch((void *)KSEG0ADDR(fw_passed_dtb)); | ||
226 | |||
227 | ath79_reset_base = ioremap(AR71XX_RESET_BASE, | ||
228 | AR71XX_RESET_SIZE); | ||
229 | ath79_pll_base = ioremap(AR71XX_PLL_BASE, | ||
230 | AR71XX_PLL_SIZE); | ||
231 | ath79_detect_sys_type(); | ||
232 | ath79_ddr_ctrl_init(); | ||
233 | |||
234 | detect_memory_region(0, ATH79_MEM_SIZE_MIN, ATH79_MEM_SIZE_MAX); | ||
235 | |||
236 | _machine_restart = ath79_restart; | ||
237 | _machine_halt = ath79_halt; | ||
238 | pm_power_off = ath79_halt; | ||
239 | } | ||
240 | |||
241 | void __init plat_time_init(void) | ||
242 | { | ||
243 | struct device_node *np; | ||
244 | struct clk *clk; | ||
245 | unsigned long cpu_clk_rate; | ||
246 | |||
247 | of_clk_init(NULL); | ||
248 | |||
249 | np = of_get_cpu_node(0, NULL); | ||
250 | if (!np) { | ||
251 | pr_err("Failed to get CPU node\n"); | ||
252 | return; | ||
253 | } | ||
254 | |||
255 | clk = of_clk_get(np, 0); | ||
256 | if (IS_ERR(clk)) { | ||
257 | pr_err("Failed to get CPU clock: %ld\n", PTR_ERR(clk)); | ||
258 | return; | ||
259 | } | ||
260 | |||
261 | cpu_clk_rate = clk_get_rate(clk); | ||
262 | |||
263 | pr_info("CPU clock: %lu.%03lu MHz\n", | ||
264 | cpu_clk_rate / 1000000, (cpu_clk_rate / 1000) % 1000); | ||
265 | |||
266 | mips_hpt_frequency = cpu_clk_rate / 2; | ||
267 | |||
268 | clk_put(clk); | ||
269 | } | ||
270 | |||
271 | void __init arch_init_irq(void) | ||
272 | { | ||
273 | irqchip_init(); | ||
274 | } | ||
275 | |||
276 | void __init device_tree_init(void) | ||
277 | { | ||
278 | unflatten_and_copy_device_tree(); | ||
279 | } | ||