aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/ath79
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
committerWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
commita07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch)
tree84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/ath79
downloadohosKernel-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/Kconfig48
-rw-r--r--arch/mips/ath79/Makefile11
-rw-r--r--arch/mips/ath79/Platform6
-rw-r--r--arch/mips/ath79/clock.c673
-rw-r--r--arch/mips/ath79/common.c149
-rw-r--r--arch/mips/ath79/common.h21
-rw-r--r--arch/mips/ath79/early_printk.c146
-rw-r--r--arch/mips/ath79/prom.c39
-rw-r--r--arch/mips/ath79/setup.c279
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
2if ATH79
3
4config SOC_AR71XX
5 select HAVE_PCI
6 def_bool n
7
8config SOC_AR724X
9 select HAVE_PCI
10 select PCI_AR724X if PCI
11 def_bool n
12
13config SOC_AR913X
14 def_bool n
15
16config SOC_AR933X
17 def_bool n
18
19config SOC_AR934X
20 select HAVE_PCI
21 select PCI_AR724X if PCI
22 def_bool n
23
24config SOC_QCA955X
25 select HAVE_PCI
26 select PCI_AR724X if PCI
27 def_bool n
28
29config PCI_AR724X
30 def_bool n
31
32config ATH79_DEV_GPIO_BUTTONS
33 def_bool n
34
35config ATH79_DEV_LEDS_GPIO
36 def_bool n
37
38config ATH79_DEV_SPI
39 def_bool n
40
41config ATH79_DEV_USB
42 def_bool n
43
44config ATH79_DEV_WMAC
45 depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X)
46 def_bool n
47
48endif
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
9obj-y := prom.o setup.o common.o clock.o
10
11obj-$(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
5cflags-$(CONFIG_ATH79) += -I$(srctree)/arch/mips/include/asm/mach-ath79
6load-$(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
31static struct clk *clks[ATH79_CLK_END];
32static struct clk_onecell_data clk_data = {
33 .clks = clks,
34 .clk_num = ARRAY_SIZE(clks),
35};
36
37static 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
45static 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
51static 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
60static 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
70static 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
81static 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
93static 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
124static 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
144static 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
212static 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
232static 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
350static 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
433static 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
516static 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
618static 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
659err_iounmap:
660 iounmap(pll_base);
661
662err_clk:
663 clk_put(ref_clk);
664}
665
666CLK_OF_DECLARE(ar7100_clk, "qca,ar7100-pll", ath79_clocks_init_dt);
667CLK_OF_DECLARE(ar7240_clk, "qca,ar7240-pll", ath79_clocks_init_dt);
668CLK_OF_DECLARE(ar9130_clk, "qca,ar9130-pll", ath79_clocks_init_dt);
669CLK_OF_DECLARE(ar9330_clk, "qca,ar9330-pll", ath79_clocks_init_dt);
670CLK_OF_DECLARE(ar9340_clk, "qca,ar9340-pll", ath79_clocks_init_dt);
671CLK_OF_DECLARE(ar9530_clk, "qca,qca9530-pll", ath79_clocks_init_dt);
672CLK_OF_DECLARE(ar9550_clk, "qca,qca9550-pll", ath79_clocks_init_dt);
673CLK_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
21static DEFINE_SPINLOCK(ath79_device_reset_lock);
22
23u32 ath79_cpu_freq;
24EXPORT_SYMBOL_GPL(ath79_cpu_freq);
25
26u32 ath79_ahb_freq;
27EXPORT_SYMBOL_GPL(ath79_ahb_freq);
28
29u32 ath79_ddr_freq;
30EXPORT_SYMBOL_GPL(ath79_ddr_freq);
31
32enum ath79_soc_type ath79_soc;
33unsigned int ath79_soc_rev;
34
35void __iomem *ath79_pll_base;
36void __iomem *ath79_reset_base;
37EXPORT_SYMBOL_GPL(ath79_reset_base);
38static void __iomem *ath79_ddr_base;
39static void __iomem *ath79_ddr_wb_flush_base;
40static void __iomem *ath79_ddr_pci_win_base;
41
42void 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}
54EXPORT_SYMBOL_GPL(ath79_ddr_ctrl_init);
55
56void 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}
70EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush);
71
72void 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}
85EXPORT_SYMBOL_GPL(ath79_ddr_set_pci_windows);
86
87void 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}
117EXPORT_SYMBOL_GPL(ath79_device_reset_set);
118
119void 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}
149EXPORT_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
19void 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
19static void (*_prom_putchar)(char);
20
21static 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
34static 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
43static 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
55static void prom_putchar_dummy(char ch)
56{
57 /* nothing to do */
58}
59
60static 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
100static 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
140void 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
22void __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
36void __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
35static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
36
37static 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
46static void ath79_halt(void)
47{
48 while (1)
49 cpu_wait();
50}
51
52static 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
204const char *get_system_type(void)
205{
206 return ath79_sys_type;
207}
208
209unsigned int get_c0_compare_int(void)
210{
211 return CP0_LEGACY_COMPARE_IRQ;
212}
213
214void __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
241void __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
271void __init arch_init_irq(void)
272{
273 irqchip_init();
274}
275
276void __init device_tree_init(void)
277{
278 unflatten_and_copy_device_tree();
279}