2c4c57e2d29b0f7f7c953be36b8afc5a3d929274
[openwrt/staging/linusw.git] /
1 From e0c82f36ad5180d9582d353407ff1bf34a2734bb Mon Sep 17 00:00:00 2001
2 From: Weijie Gao <weijie.gao@mediatek.com>
3 Date: Fri, 20 May 2022 11:22:21 +0800
4 Subject: [PATCH 05/25] mips: mtmips: add support for MediaTek MT7621 SoC
5
6 This patch adds support for MediaTek MT7621 SoC.
7 All files are dedicated for u-boot.
8
9 The default build target is u-boot-mt7621.bin.
10
11 The specification of this chip:
12 https://www.mediatek.com/products/homenetworking/mt7621
13
14 Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
15 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
16 ---
17 arch/mips/dts/mt7621-u-boot.dtsi | 111 ++++++
18 arch/mips/dts/mt7621.dtsi | 349 +++++++++++++++++++
19 arch/mips/mach-mtmips/Kconfig | 49 ++-
20 arch/mips/mach-mtmips/Makefile | 4 +
21 arch/mips/mach-mtmips/cpu.c | 2 +-
22 arch/mips/mach-mtmips/mt7621/Kconfig | 95 +++++
23 arch/mips/mach-mtmips/mt7621/Makefile | 14 +
24 arch/mips/mach-mtmips/mt7621/init.c | 246 +++++++++++++
25 arch/mips/mach-mtmips/mt7621/mt7621.h | 229 ++++++++++++
26 arch/mips/mach-mtmips/mt7621/serial.c | 23 ++
27 arch/mips/mach-mtmips/mt7621/spl/Makefile | 9 +
28 arch/mips/mach-mtmips/mt7621/spl/cps.c | 153 ++++++++
29 arch/mips/mach-mtmips/mt7621/spl/dram.c | 153 ++++++++
30 arch/mips/mach-mtmips/mt7621/spl/dram.h | 39 +++
31 arch/mips/mach-mtmips/mt7621/spl/launch.c | 100 ++++++
32 arch/mips/mach-mtmips/mt7621/spl/launch.h | 52 +++
33 arch/mips/mach-mtmips/mt7621/spl/launch_ll.S | 339 ++++++++++++++++++
34 arch/mips/mach-mtmips/mt7621/spl/serial.c | 24 ++
35 arch/mips/mach-mtmips/mt7621/spl/spl.c | 95 +++++
36 arch/mips/mach-mtmips/mt7621/spl/start.S | 226 ++++++++++++
37 arch/mips/mach-mtmips/mt7621/sram_init.S | 22 ++
38 arch/mips/mach-mtmips/mt7621/tpl/Makefile | 4 +
39 arch/mips/mach-mtmips/mt7621/tpl/start.S | 161 +++++++++
40 arch/mips/mach-mtmips/mt7621/tpl/tpl.c | 144 ++++++++
41 include/configs/mt7621.h | 65 ++++
42 25 files changed, 2702 insertions(+), 6 deletions(-)
43 create mode 100644 arch/mips/dts/mt7621-u-boot.dtsi
44 create mode 100644 arch/mips/dts/mt7621.dtsi
45 create mode 100644 arch/mips/mach-mtmips/mt7621/Kconfig
46 create mode 100644 arch/mips/mach-mtmips/mt7621/Makefile
47 create mode 100644 arch/mips/mach-mtmips/mt7621/init.c
48 create mode 100644 arch/mips/mach-mtmips/mt7621/mt7621.h
49 create mode 100644 arch/mips/mach-mtmips/mt7621/serial.c
50 create mode 100644 arch/mips/mach-mtmips/mt7621/spl/Makefile
51 create mode 100644 arch/mips/mach-mtmips/mt7621/spl/cps.c
52 create mode 100644 arch/mips/mach-mtmips/mt7621/spl/dram.c
53 create mode 100644 arch/mips/mach-mtmips/mt7621/spl/dram.h
54 create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch.c
55 create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch.h
56 create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch_ll.S
57 create mode 100644 arch/mips/mach-mtmips/mt7621/spl/serial.c
58 create mode 100644 arch/mips/mach-mtmips/mt7621/spl/spl.c
59 create mode 100644 arch/mips/mach-mtmips/mt7621/spl/start.S
60 create mode 100644 arch/mips/mach-mtmips/mt7621/sram_init.S
61 create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/Makefile
62 create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/start.S
63 create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/tpl.c
64 create mode 100644 include/configs/mt7621.h
65
66 diff --git a/arch/mips/dts/mt7621-u-boot.dtsi b/arch/mips/dts/mt7621-u-boot.dtsi
67 new file mode 100644
68 index 0000000000..c5a8aa357f
69 --- /dev/null
70 +++ b/arch/mips/dts/mt7621-u-boot.dtsi
71 @@ -0,0 +1,111 @@
72 +// SPDX-License-Identifier: GPL-2.0
73 +/*
74 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
75 + *
76 + * Author: Weijie Gao <weijie.gao@mediatek.com>
77 + */
78 +
79 +#include <linux/stringify.h>
80 +
81 +/ {
82 + binman: binman {
83 + multiple-images;
84 + };
85 +};
86 +
87 +&sysc {
88 + u-boot,dm-pre-reloc;
89 +};
90 +
91 +&reboot {
92 + u-boot,dm-pre-reloc;
93 +};
94 +
95 +&clkctrl {
96 + u-boot,dm-pre-reloc;
97 +};
98 +
99 +&rstctrl {
100 + u-boot,dm-pre-reloc;
101 +};
102 +
103 +&pinctrl {
104 + u-boot,dm-pre-reloc;
105 +};
106 +
107 +&uart0 {
108 + u-boot,dm-pre-reloc;
109 +};
110 +
111 +&uart1 {
112 + u-boot,dm-pre-reloc;
113 +};
114 +
115 +&uart2 {
116 + u-boot,dm-pre-reloc;
117 +};
118 +
119 +&binman {
120 + u-boot-spl-ddr {
121 + align = <4>;
122 + align-size = <4>;
123 + filename = "u-boot-spl-ddr.bin";
124 + pad-byte = <0xff>;
125 +
126 + u-boot-spl {
127 + align-end = <4>;
128 + filename = "u-boot-spl.bin";
129 + };
130 +
131 + stage_bin {
132 + filename = "mt7621_stage_sram.bin";
133 + type = "blob-ext";
134 + };
135 + };
136 +
137 + spl-img {
138 + filename = "u-boot-spl-ddr.img";
139 +
140 + mkimage {
141 +#ifdef CONFIG_MT7621_BOOT_FROM_NAND
142 + args = "-T", "mtk_image", "-n", "mt7621=1",
143 + "-a", __stringify(CONFIG_SPL_TEXT_BASE),
144 + "-e", __stringify(CONFIG_SPL_TEXT_BASE);
145 +#else
146 + args = "-A", "mips", "-T", "standalone", "-O", "u-boot",
147 + "-C", "none", "-n", "MT7621 U-Boot SPL",
148 + "-a", __stringify(CONFIG_SPL_TEXT_BASE),
149 + "-e", __stringify(CONFIG_SPL_TEXT_BASE);
150 +#endif
151 +
152 + blob {
153 + filename = "u-boot-spl-ddr.bin";
154 + };
155 + };
156 + };
157 +
158 + mt7621-uboot {
159 + filename = "u-boot-mt7621.bin";
160 + pad-byte = <0xff>;
161 +
162 +#ifndef CONFIG_MT7621_BOOT_FROM_NAND
163 + u-boot-tpl {
164 + align-end = <4>;
165 + filename = "u-boot-tpl.bin";
166 + };
167 +#endif
168 +
169 + spl {
170 +#ifdef CONFIG_MT7621_BOOT_FROM_NAND
171 + align-end = <0x1000>;
172 +#endif
173 + filename = "u-boot-spl-ddr.img";
174 + type = "blob";
175 + };
176 +
177 + u-boot {
178 + filename = "u-boot-lzma.img";
179 + type = "blob";
180 + };
181 + };
182 +};
183 diff --git a/arch/mips/dts/mt7621.dtsi b/arch/mips/dts/mt7621.dtsi
184 new file mode 100644
185 index 0000000000..c32b6095e9
186 --- /dev/null
187 +++ b/arch/mips/dts/mt7621.dtsi
188 @@ -0,0 +1,349 @@
189 +// SPDX-License-Identifier: GPL-2.0
190 +/*
191 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
192 + *
193 + * Author: Weijie Gao <weijie.gao@mediatek.com>
194 + */
195 +
196 +#include <dt-bindings/clock/mt7621-clk.h>
197 +#include <dt-bindings/reset/mt7621-reset.h>
198 +#include <dt-bindings/phy/phy.h>
199 +
200 +/ {
201 + #address-cells = <1>;
202 + #size-cells = <1>;
203 + compatible = "mediatek,mt7621-soc";
204 +
205 + cpus {
206 + #address-cells = <1>;
207 + #size-cells = <0>;
208 +
209 + cpu@0 {
210 + device_type = "cpu";
211 + compatible = "mips,mips1004Kc";
212 + reg = <0>;
213 + };
214 +
215 + cpu@1 {
216 + device_type = "cpu";
217 + compatible = "mips,mips1004Kc";
218 + reg = <1>;
219 + };
220 + };
221 +
222 + clk48m: clk48m {
223 + compatible = "fixed-clock";
224 +
225 + clock-frequency = <48000000>;
226 +
227 + #clock-cells = <0>;
228 + };
229 +
230 + clk50m: clk50m {
231 + compatible = "fixed-clock";
232 +
233 + clock-frequency = <50000000>;
234 +
235 + #clock-cells = <0>;
236 + };
237 +
238 + sysc: sysctrl@1e000000 {
239 + compatible = "mediatek,mt7621-sysc", "syscon";
240 + reg = <0x1e000000 0x100>;
241 +
242 + clkctrl: clock-controller@1e000030 {
243 + compatible = "mediatek,mt7621-clk";
244 + mediatek,memc = <&memc>;
245 +
246 + #clock-cells = <1>;
247 + };
248 + };
249 +
250 + rstctrl: reset-controller@1e000034 {
251 + compatible = "mediatek,mtmips-reset";
252 + reg = <0x1e000034 0x4>;
253 + #reset-cells = <1>;
254 + };
255 +
256 + reboot: resetctl-reboot {
257 + compatible = "resetctl-reboot";
258 +
259 + resets = <&rstctrl RST_SYS>;
260 + reset-names = "sysreset";
261 + };
262 +
263 + memc: memctrl@1e005000 {
264 + compatible = "mediatek,mt7621-memc", "syscon";
265 + reg = <0x1e005000 0x1000>;
266 + };
267 +
268 + pinctrl: pinctrl@1e000060 {
269 + compatible = "mediatek,mt7621-pinctrl";
270 + reg = <0x1e000048 0x30>;
271 +
272 + pinctrl-names = "default";
273 + pinctrl-0 = <&state_default>;
274 +
275 + state_default: pin_state {
276 + };
277 +
278 + uart1_pins: uart1_pins {
279 + groups = "uart1";
280 + function = "uart";
281 + };
282 +
283 + uart2_pins: uart2_pins {
284 + groups = "uart2";
285 + function = "uart";
286 + };
287 +
288 + uart3_pins: uart3_pins {
289 + groups = "uart3";
290 + function = "uart";
291 + };
292 +
293 + sdxc_pins: sdxc_pins {
294 + groups = "sdxc";
295 + function = "sdxc";
296 + };
297 +
298 + spi_pins: spi_pins {
299 + groups = "spi";
300 + function = "spi";
301 + };
302 +
303 + eth_pins: eth_pins {
304 + mdio_pins {
305 + groups = "mdio";
306 + function = "mdio";
307 + };
308 +
309 + rgmii1_pins {
310 + groups = "rgmii1";
311 + function = "rgmii";
312 + };
313 +
314 + esw_pins {
315 + groups = "esw int";
316 + function = "esw int";
317 + };
318 +
319 + mdio_pconf {
320 + groups = "mdio";
321 + drive-strength = <2>;
322 + };
323 + };
324 + };
325 +
326 + watchdog: watchdog@1e000100 {
327 + compatible = "mediatek,mt7621-wdt";
328 + reg = <0x1e000100 0x40>;
329 +
330 + resets = <&rstctrl RST_TIMER>;
331 + reset-names = "wdt";
332 +
333 + status = "disabled";
334 + };
335 +
336 + gpio: gpio@1e000600 {
337 + #address-cells = <1>;
338 + #size-cells = <0>;
339 +
340 + compatible = "mtk,mt7621-gpio";
341 + reg = <0x1e000600 0x100>;
342 +
343 + resets = <&rstctrl RST_PIO>;
344 + reset-names = "pio";
345 +
346 + gpio0: bank@0 {
347 + reg = <0>;
348 + compatible = "mtk,mt7621-gpio-bank";
349 + gpio-controller;
350 + #gpio-cells = <2>;
351 + };
352 +
353 + gpio1: bank@1 {
354 + reg = <1>;
355 + compatible = "mtk,mt7621-gpio-bank";
356 + gpio-controller;
357 + #gpio-cells = <2>;
358 + };
359 +
360 + gpio2: bank@2 {
361 + reg = <2>;
362 + compatible = "mtk,mt7621-gpio-bank";
363 + gpio-controller;
364 + #gpio-cells = <2>;
365 + };
366 + };
367 +
368 + spi: spi@1e000b00 {
369 + compatible = "ralink,mt7621-spi";
370 + reg = <0x1e000b00 0x40>;
371 +
372 + status = "disabled";
373 +
374 + pinctrl-names = "default";
375 + pinctrl-0 = <&spi_pins>;
376 +
377 + resets = <&rstctrl RST_SPI>;
378 + reset-names = "spi";
379 +
380 + clocks = <&clkctrl MT7621_CLK_SPI>;
381 +
382 + #address-cells = <1>;
383 + #size-cells = <0>;
384 + };
385 +
386 + uart0: uart1@1e000c00 {
387 + compatible = "mediatek,hsuart", "ns16550a";
388 + reg = <0x1e000c00 0x100>;
389 +
390 + pinctrl-names = "default";
391 + pinctrl-0 = <&uart1_pins>;
392 +
393 + clocks = <&clkctrl MT7621_CLK_UART1>;
394 +
395 + resets = <&rstctrl RST_UART1>;
396 +
397 + reg-shift = <2>;
398 + };
399 +
400 + uart1: uart2@1e000d00 {
401 + compatible = "mediatek,hsuart", "ns16550a";
402 + reg = <0x1e000d00 0x100>;
403 +
404 + pinctrl-names = "default";
405 + pinctrl-0 = <&uart2_pins>;
406 +
407 + clocks = <&clkctrl MT7621_CLK_UART2>;
408 +
409 + resets = <&rstctrl RST_UART2>;
410 +
411 + reg-shift = <2>;
412 +
413 + status = "disabled";
414 + };
415 +
416 + uart2: uart3@1e000e00 {
417 + compatible = "mediatek,hsuart", "ns16550a";
418 + reg = <0x1e000e00 0x100>;
419 +
420 + pinctrl-names = "default";
421 + pinctrl-0 = <&uart3_pins>;
422 +
423 + clocks = <&clkctrl MT7621_CLK_UART3>;
424 +
425 + resets = <&rstctrl RST_UART3>;
426 +
427 + reg-shift = <2>;
428 +
429 + status = "disabled";
430 + };
431 +
432 + eth: eth@1e100000 {
433 + compatible = "mediatek,mt7621-eth";
434 + reg = <0x1e100000 0x20000>;
435 + mediatek,ethsys = <&sysc>;
436 +
437 + pinctrl-names = "default";
438 + pinctrl-0 = <&eth_pins>;
439 +
440 + resets = <&rstctrl RST_FE>, <&rstctrl RST_GMAC>, <&rstctrl RST_MCM>;
441 + reset-names = "fe", "gmac", "mcm";
442 +
443 + clocks = <&clkctrl MT7621_CLK_GDMA>,
444 + <&clkctrl MT7621_CLK_ETH>;
445 + clock-names = "gmac", "fe";
446 +
447 + #address-cells = <1>;
448 + #size-cells = <0>;
449 +
450 + mediatek,gmac-id = <0>;
451 + phy-mode = "rgmii";
452 + mediatek,switch = "mt7530";
453 + mediatek,mcm;
454 +
455 + fixed-link {
456 + speed = <1000>;
457 + full-duplex;
458 + };
459 + };
460 +
461 + mmc: mmc@1e130000 {
462 + compatible = "mediatek,mt7621-mmc";
463 + reg = <0x1e130000 0x4000>;
464 +
465 + status = "disabled";
466 +
467 + bus-width = <4>;
468 + builtin-cd = <1>;
469 + r_smpl = <1>;
470 +
471 + pinctrl-names = "default";
472 + pinctrl-0 = <&sdxc_pins>;
473 +
474 + clocks = <&clk50m>, <&clkctrl MT7621_CLK_SHXC>;
475 + clock-names = "source", "hclk";
476 +
477 + resets = <&rstctrl RST_SDXC>;
478 + };
479 +
480 + ssusb: usb@1e1c0000 {
481 + compatible = "mediatek,mt7621-xhci", "mediatek,mtk-xhci";
482 + reg = <0x1e1c0000 0x1000>, <0x1e1d0700 0x100>;
483 + reg-names = "mac", "ippc";
484 +
485 + clocks = <&clk48m>, <&clk48m>;
486 + clock-names = "sys_ck", "ref_ck";
487 +
488 + phys = <&u2port0 PHY_TYPE_USB2>,
489 + <&u3port0 PHY_TYPE_USB3>,
490 + <&u2port1 PHY_TYPE_USB2>;
491 +
492 + status = "disabled";
493 + };
494 +
495 + u3phy: usb-phy@1e1d0000 {
496 + compatible = "mediatek,mt7621-u3phy",
497 + "mediatek,generic-tphy-v1";
498 + reg = <0x1e1d0000 0x700>;
499 + #address-cells = <1>;
500 + #size-cells = <1>;
501 + ranges;
502 + status = "disabled";
503 +
504 + u2port0: usb-phy@1e1d0800 {
505 + reg = <0x1e1d0800 0x0100>;
506 + #phy-cells = <1>;
507 + clocks = <&clk48m>;
508 + clock-names = "ref";
509 + };
510 +
511 + u3port0: usb-phy@1e1d0900 {
512 + reg = <0x1e1d0900 0x0100>;
513 + #phy-cells = <1>;
514 + };
515 +
516 + u2port1: usb-phy@1e1d1000 {
517 + reg = <0x1e1d1000 0x0100>;
518 + #phy-cells = <1>;
519 + clocks = <&clk48m>;
520 + clock-names = "ref";
521 + };
522 + };
523 +
524 + i2c: i2c@1e000900 {
525 + compatible = "i2c-gpio";
526 +
527 + status = "disabled";
528 +
529 + i2c-gpio,delay-us = <3>;
530 +
531 + gpios = <&gpio0 3 1>, /* PIN3 as SDA */
532 + <&gpio0 4 1>; /* PIN4 as CLK */
533 +
534 + #address-cells = <1>;
535 + #size-cells = <0>;
536 + };
537 +};
538 diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig
539 index 151b004603..d46be503a2 100644
540 --- a/arch/mips/mach-mtmips/Kconfig
541 +++ b/arch/mips/mach-mtmips/Kconfig
542 @@ -9,6 +9,7 @@ config SYS_MALLOC_F_LEN
543
544 config SYS_SOC
545 default "mt7620" if SOC_MT7620
546 + default "mt7621" if SOC_MT7621
547 default "mt7628" if SOC_MT7628
548
549 config SYS_DCACHE_SIZE
550 @@ -18,25 +19,45 @@ config SYS_DCACHE_LINE_SIZE
551 default 32
552
553 config SYS_ICACHE_SIZE
554 - default 65536
555 + default 65536 if SOC_MT7620 || SOC_MT7628
556 + default 32768 if SOC_MT7621
557
558 config SYS_ICACHE_LINE_SIZE
559 default 32
560
561 +config SYS_SCACHE_LINE_SIZE
562 + default 32 if SOC_MT7621
563 +
564 config SYS_TEXT_BASE
565 - default 0x9c000000 if !SPL
566 - default 0x80200000 if SPL
567 + default 0x9c000000 if !SPL && !SOC_MT7621
568 + default 0x80200000 if SPL || SOC_MT7621
569
570 config SPL_TEXT_BASE
571 - default 0x9c000000
572 + default 0x9c000000 if !SOC_MT7621
573 + default 0x80100000 if SOC_MT7621
574 +
575 +config SPL_SIZE_LIMIT
576 + default 0x30000 if SOC_MT7621
577 +
578 +config TPL_TEXT_BASE
579 + default 0xbfc00000 if SOC_MT7621
580 +
581 +config TPL_MAX_SIZE
582 + default 4096 if SOC_MT7621
583
584 config SPL_PAYLOAD
585 default "u-boot-lzma.img" if SPL_LZMA
586
587 config BUILD_TARGET
588 - default "u-boot-with-spl.bin" if SPL
589 + default "u-boot-with-spl.bin" if SPL && !SOC_MT7621
590 + default "u-boot-lzma.img" if SOC_MT7621
591 default "u-boot.bin"
592
593 +config MAX_MEM_SIZE
594 + int
595 + default 256 if SOC_MT7620 || SOC_MT7628
596 + default 512 if SOC_MT7621
597 +
598 choice
599 prompt "MediaTek MIPS SoC select"
600
601 @@ -55,6 +76,23 @@ config SOC_MT7620
602 help
603 This supports MediaTek MT7620.
604
605 +config SOC_MT7621
606 + bool "MT7621"
607 + select MIPS_CM
608 + select MIPS_L2_CACHE
609 + select SYS_CACHE_SHIFT_5
610 + select SYS_MIPS_CACHE_INIT_RAM_LOAD
611 + select PINCTRL_MT7621
612 + select MTK_SERIAL
613 + select REGMAP
614 + select SYSCON
615 + select BINMAN
616 + select SUPPORT_TPL
617 + select SPL_LOADER_SUPPORT if SPL
618 + select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL
619 + help
620 + This supports MediaTek MT7621.
621 +
622 config SOC_MT7628
623 bool "MT7628"
624 select SYS_CACHE_SHIFT_5
625 @@ -80,6 +118,7 @@ config SOC_MT7628
626 endchoice
627
628 source "arch/mips/mach-mtmips/mt7620/Kconfig"
629 +source "arch/mips/mach-mtmips/mt7621/Kconfig"
630 source "arch/mips/mach-mtmips/mt7628/Kconfig"
631
632 endmenu
633 diff --git a/arch/mips/mach-mtmips/Makefile b/arch/mips/mach-mtmips/Makefile
634 index 4909b47ef2..19f1e07033 100644
635 --- a/arch/mips/mach-mtmips/Makefile
636 +++ b/arch/mips/mach-mtmips/Makefile
637 @@ -1,9 +1,13 @@
638 # SPDX-License-Identifier: GPL-2.0+
639
640 obj-y += cpu.o
641 +
642 +ifneq ($(CONFIG_SOC_MT7621),y)
643 obj-y += ddr_init.o
644 obj-y += ddr_cal.o
645 obj-$(CONFIG_SPL_BUILD) += spl.o
646 +endif
647
648 obj-$(CONFIG_SOC_MT7620) += mt7620/
649 +obj-$(CONFIG_SOC_MT7621) += mt7621/
650 obj-$(CONFIG_SOC_MT7628) += mt7628/
651 diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach-mtmips/cpu.c
652 index a4b5cff61d..f1e9022738 100644
653 --- a/arch/mips/mach-mtmips/cpu.c
654 +++ b/arch/mips/mach-mtmips/cpu.c
655 @@ -16,7 +16,7 @@ DECLARE_GLOBAL_DATA_PTR;
656
657 int dram_init(void)
658 {
659 - gd->ram_size = get_ram_size((void *)KSEG1, SZ_256M);
660 + gd->ram_size = get_ram_size((void *)KSEG1, CONFIG_MAX_MEM_SIZE << 20);
661
662 return 0;
663 }
664 diff --git a/arch/mips/mach-mtmips/mt7621/Kconfig b/arch/mips/mach-mtmips/mt7621/Kconfig
665 new file mode 100644
666 index 0000000000..37d512c68f
667 --- /dev/null
668 +++ b/arch/mips/mach-mtmips/mt7621/Kconfig
669 @@ -0,0 +1,95 @@
670 +
671 +if SOC_MT7621
672 +
673 +menu "CPU & DDR configuration"
674 +
675 +config MT7621_CPU_FREQ
676 + int "CPU Frequency (MHz)"
677 + range 400 1200
678 + default 880
679 +
680 +choice
681 + prompt "DRAM Frequency"
682 + default MT7621_DRAM_FREQ_1200
683 +
684 +config MT7621_DRAM_FREQ_400
685 + bool "400MHz"
686 +
687 +config MT7621_DRAM_FREQ_800
688 + bool "800MHz"
689 +
690 +config MT7621_DRAM_FREQ_1066
691 + bool "1066MHz"
692 +
693 +config MT7621_DRAM_FREQ_1200
694 + bool "1200MHz"
695 +
696 +endchoice
697 +
698 +choice
699 + prompt "DDR2 timing parameters"
700 + default MT7621_DRAM_DDR2_1024M
701 +
702 +config MT7621_DRAM_DDR2_512M
703 + bool "64MB"
704 +
705 +config MT7621_DRAM_DDR2_1024M
706 + bool "128MB"
707 +
708 +config MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ
709 + bool "W9751G6KB_A02 @ 1066MHz (64MB)"
710 +
711 +config MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ
712 + bool "W971GG6KB25 @ 800MHz (128MB)"
713 +
714 +config MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ
715 + bool "W971GG6KB18 @ 1066MHz (128MB)"
716 +
717 +endchoice
718 +
719 +choice
720 + prompt "DDR3 timing parameters"
721 + default MT7621_DRAM_DDR3_2048M
722 +
723 +config MT7621_DRAM_DDR3_1024M
724 + bool "128MB"
725 +
726 +config MT7621_DRAM_DDR3_1024M_KGD
727 + bool "128MB KGD (MT7621DA)"
728 +
729 +config MT7621_DRAM_DDR3_2048M
730 + bool "256MB"
731 +
732 +config MT7621_DRAM_DDR3_4096M
733 + bool "512MB"
734 +
735 +endchoice
736 +
737 +endmenu
738 +
739 +config DEBUG_UART_BOARD_INIT
740 + default y
741 +
742 +config MT7621_BOOT_FROM_NAND
743 + bool "Boot from NAND"
744 + help
745 + Select this if u-boot will boot from NAND flash. When booting from
746 + NAND, SPL will be loaded by bootrom directly and no TPL is needed.
747 +
748 +choice
749 + prompt "Board select"
750 +
751 +endchoice
752 +
753 +config SYS_CONFIG_NAME
754 + string "Board configuration name"
755 + default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB
756 +
757 +config SYS_BOARD
758 + string "Board name"
759 + default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB
760 +
761 +config SYS_VENDOR
762 + default "mediatek" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB
763 +
764 +endif
765 diff --git a/arch/mips/mach-mtmips/mt7621/Makefile b/arch/mips/mach-mtmips/mt7621/Makefile
766 new file mode 100644
767 index 0000000000..bf1b0bb688
768 --- /dev/null
769 +++ b/arch/mips/mach-mtmips/mt7621/Makefile
770 @@ -0,0 +1,14 @@
771 +# SPDX-License-Identifier: GPL-2.0
772 +
773 +obj-y += init.o
774 +obj-y += serial.o
775 +
776 +ifeq ($(CONFIG_SPL_BUILD),y)
777 +ifeq ($(CONFIG_TPL_BUILD),y)
778 +obj-y += tpl/
779 +else
780 +obj-y += spl/
781 +endif
782 +
783 +obj-y += sram_init.o
784 +endif
785 diff --git a/arch/mips/mach-mtmips/mt7621/init.c b/arch/mips/mach-mtmips/mt7621/init.c
786 new file mode 100644
787 index 0000000000..d21848ad23
788 --- /dev/null
789 +++ b/arch/mips/mach-mtmips/mt7621/init.c
790 @@ -0,0 +1,246 @@
791 +// SPDX-License-Identifier: GPL-2.0
792 +/*
793 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
794 + *
795 + * Author: Weijie Gao <weijie.gao@mediatek.com>
796 + */
797 +
798 +#include <clk.h>
799 +#include <dm.h>
800 +#include <dm/uclass.h>
801 +#include <dt-bindings/clock/mt7621-clk.h>
802 +#include <asm/global_data.h>
803 +#include <linux/io.h>
804 +#include <linux/bitfield.h>
805 +#include "mt7621.h"
806 +
807 +DECLARE_GLOBAL_DATA_PTR;
808 +
809 +static const char *const boot_mode[(CHIP_MODE_M >> CHIP_MODE_S) + 1] = {
810 + [1] = "NAND 2K+64",
811 + [2] = "SPI-NOR 3-Byte Addr",
812 + [3] = "SPI-NOR 4-Byte Addr",
813 + [10] = "NAND 2K+128",
814 + [11] = "NAND 4K+128",
815 + [12] = "NAND 4K+256",
816 +};
817 +
818 +int print_cpuinfo(void)
819 +{
820 + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
821 + u32 val, ver, eco, pkg, core, dram, chipmode;
822 + u32 cpu_clk, ddr_clk, bus_clk, xtal_clk;
823 + struct udevice *clkdev;
824 + const char *bootdev;
825 + struct clk clk;
826 + int ret;
827 +
828 + val = readl(sysc + SYSCTL_CHIP_REV_ID_REG);
829 + ver = FIELD_GET(VER_ID_M, val);
830 + eco = FIELD_GET(ECO_ID_M, val);
831 + pkg = FIELD_GET(PKG_ID, val);
832 + core = FIELD_GET(CPU_ID, val);
833 +
834 + val = readl(sysc + SYSCTL_SYSCFG0_REG);
835 + dram = FIELD_GET(DRAM_TYPE, val);
836 + chipmode = FIELD_GET(CHIP_MODE_M, val);
837 +
838 + bootdev = boot_mode[chipmode];
839 + if (!bootdev)
840 + bootdev = "Unsupported boot mode";
841 +
842 + printf("CPU: MediaTek MT7621%c ver %u, eco %u\n",
843 + core ? (pkg ? 'A' : 'N') : 'S', ver, eco);
844 +
845 + printf("Boot: DDR%u, %s\n", dram ? 2 : 3, bootdev);
846 +
847 + ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(mt7621_clk),
848 + &clkdev);
849 + if (ret)
850 + return ret;
851 +
852 + clk.dev = clkdev;
853 +
854 + clk.id = MT7621_CLK_CPU;
855 + cpu_clk = clk_get_rate(&clk);
856 +
857 + clk.id = MT7621_CLK_BUS;
858 + bus_clk = clk_get_rate(&clk);
859 +
860 + clk.id = MT7621_CLK_DDR;
861 + ddr_clk = clk_get_rate(&clk);
862 +
863 + clk.id = MT7621_CLK_XTAL;
864 + xtal_clk = clk_get_rate(&clk);
865 +
866 + /* Set final timer frequency */
867 + if (cpu_clk)
868 + gd->arch.timer_freq = cpu_clk / 2;
869 +
870 + printf("Clock: CPU: %uMHz, DDR: %uMT/s, Bus: %uMHz, XTAL: %uMHz\n",
871 + cpu_clk / 1000000, ddr_clk / 500000, bus_clk / 1000000,
872 + xtal_clk / 1000000);
873 +
874 + return 0;
875 +}
876 +
877 +unsigned long get_xtal_mhz(void)
878 +{
879 + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
880 + u32 bs, xtal_sel;
881 +
882 + bs = readl(sysc + SYSCTL_SYSCFG0_REG);
883 + xtal_sel = FIELD_GET(XTAL_MODE_SEL_M, bs);
884 +
885 + if (xtal_sel <= 2)
886 + return 20;
887 + else if (xtal_sel <= 5)
888 + return 40;
889 + else
890 + return 25;
891 +}
892 +
893 +static void xhci_config_40mhz(void __iomem *usbh)
894 +{
895 + writel(FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M, 0x20) |
896 + FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M, 0x20) |
897 + FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MODE_M, 2) |
898 + FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MODE_M, 2) | 0x10,
899 + usbh + SSUSB_MAC_CK_CTRL_REG);
900 +
901 + writel(FIELD_PREP(SSUSB_PLL_PREDIV_PE1D_M, 2) |
902 + FIELD_PREP(SSUSB_PLL_PREDIV_U3_M, 1) |
903 + FIELD_PREP(SSUSB_PLL_FBKDI_M, 4),
904 + usbh + DA_SSUSB_U3PHYA_10_REG);
905 +
906 + writel(FIELD_PREP(SSUSB_PLL_FBKDIV_PE2H_M, 0x18) |
907 + FIELD_PREP(SSUSB_PLL_FBKDIV_PE1D_M, 0x18) |
908 + FIELD_PREP(SSUSB_PLL_FBKDIV_PE1H_M, 0x18) |
909 + FIELD_PREP(SSUSB_PLL_FBKDIV_U3_M, 0x1e),
910 + usbh + DA_SSUSB_PLL_FBKDIV_REG);
911 +
912 + writel(FIELD_PREP(SSUSB_PLL_PCW_NCPO_U3_M, 0x1e400000),
913 + usbh + DA_SSUSB_PLL_PCW_NCPO_REG);
914 +
915 + writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE1H_M, 0x25) |
916 + FIELD_PREP(SSUSB_PLL_SSC_DELTA1_U3_M, 0x73),
917 + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG);
918 +
919 + writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA_U3_M, 0x71) |
920 + FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE2D_M, 0x4a),
921 + usbh + DA_SSUSB_U3PHYA_21_REG);
922 +
923 + writel(FIELD_PREP(SSUSB_PLL_SSC_PRD_M, 0x140),
924 + usbh + SSUSB_U3PHYA_9_REG);
925 +
926 + writel(FIELD_PREP(SSUSB_SYSPLL_PCW_NCPO_M, 0x11c00000),
927 + usbh + SSUSB_U3PHYA_3_REG);
928 +
929 + writel(FIELD_PREP(SSUSB_PCIE_CLKDRV_AMP_M, 4) |
930 + FIELD_PREP(SSUSB_SYSPLL_FBSEL_M, 1) |
931 + FIELD_PREP(SSUSB_SYSPLL_PREDIV_M, 1),
932 + usbh + SSUSB_U3PHYA_1_REG);
933 +
934 + writel(FIELD_PREP(SSUSB_SYSPLL_FBDIV_M, 0x12) |
935 + SSUSB_SYSPLL_VCO_DIV_SEL | SSUSB_SYSPLL_FPEN |
936 + SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN,
937 + usbh + SSUSB_U3PHYA_2_REG);
938 +
939 + writel(SSUSB_EQ_CURSEL | FIELD_PREP(SSUSB_RX_DAC_MUX_M, 8) |
940 + FIELD_PREP(SSUSB_PCIE_SIGDET_VTH_M, 1) |
941 + FIELD_PREP(SSUSB_PCIE_SIGDET_LPF_M, 1),
942 + usbh + SSUSB_U3PHYA_11_REG);
943 +
944 + writel(FIELD_PREP(SSUSB_RING_OSC_CNTEND_M, 0x1ff) |
945 + FIELD_PREP(SSUSB_XTAL_OSC_CNTEND_M, 0x7f) |
946 + SSUSB_RING_BYPASS_DET,
947 + usbh + SSUSB_B2_ROSC_0_REG);
948 +
949 + writel(FIELD_PREP(SSUSB_RING_OSC_FRC_RECAL_M, 3) |
950 + SSUSB_RING_OSC_FRC_SEL,
951 + usbh + SSUSB_B2_ROSC_1_REG);
952 +}
953 +
954 +static void xhci_config_25mhz(void __iomem *usbh)
955 +{
956 + writel(FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M, 0x20) |
957 + FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M, 0x20) |
958 + FIELD_PREP(SSUSB_MAC3_SYS_CK_GATE_MODE_M, 2) |
959 + FIELD_PREP(SSUSB_MAC2_SYS_CK_GATE_MODE_M, 2) | 0x10,
960 + usbh + SSUSB_MAC_CK_CTRL_REG);
961 +
962 + writel(FIELD_PREP(SSUSB_PLL_PREDIV_PE1D_M, 2) |
963 + FIELD_PREP(SSUSB_PLL_FBKDI_M, 4),
964 + usbh + DA_SSUSB_U3PHYA_10_REG);
965 +
966 + writel(FIELD_PREP(SSUSB_PLL_FBKDIV_PE2H_M, 0x18) |
967 + FIELD_PREP(SSUSB_PLL_FBKDIV_PE1D_M, 0x18) |
968 + FIELD_PREP(SSUSB_PLL_FBKDIV_PE1H_M, 0x18) |
969 + FIELD_PREP(SSUSB_PLL_FBKDIV_U3_M, 0x19),
970 + usbh + DA_SSUSB_PLL_FBKDIV_REG);
971 +
972 + writel(FIELD_PREP(SSUSB_PLL_PCW_NCPO_U3_M, 0x18000000),
973 + usbh + DA_SSUSB_PLL_PCW_NCPO_REG);
974 +
975 + writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE1H_M, 0x25) |
976 + FIELD_PREP(SSUSB_PLL_SSC_DELTA1_U3_M, 0x4a),
977 + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG);
978 +
979 + writel(FIELD_PREP(SSUSB_PLL_SSC_DELTA_U3_M, 0x48) |
980 + FIELD_PREP(SSUSB_PLL_SSC_DELTA1_PE2D_M, 0x4a),
981 + usbh + DA_SSUSB_U3PHYA_21_REG);
982 +
983 + writel(FIELD_PREP(SSUSB_PLL_SSC_PRD_M, 0x190),
984 + usbh + SSUSB_U3PHYA_9_REG);
985 +
986 + writel(FIELD_PREP(SSUSB_SYSPLL_PCW_NCPO_M, 0xe000000),
987 + usbh + SSUSB_U3PHYA_3_REG);
988 +
989 + writel(FIELD_PREP(SSUSB_PCIE_CLKDRV_AMP_M, 4) |
990 + FIELD_PREP(SSUSB_SYSPLL_FBSEL_M, 1),
991 + usbh + SSUSB_U3PHYA_1_REG);
992 +
993 + writel(FIELD_PREP(SSUSB_SYSPLL_FBDIV_M, 0xf) |
994 + SSUSB_SYSPLL_VCO_DIV_SEL | SSUSB_SYSPLL_FPEN |
995 + SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN,
996 + usbh + SSUSB_U3PHYA_2_REG);
997 +
998 + writel(SSUSB_EQ_CURSEL | FIELD_PREP(SSUSB_RX_DAC_MUX_M, 8) |
999 + FIELD_PREP(SSUSB_PCIE_SIGDET_VTH_M, 1) |
1000 + FIELD_PREP(SSUSB_PCIE_SIGDET_LPF_M, 1),
1001 + usbh + SSUSB_U3PHYA_11_REG);
1002 +
1003 + writel(FIELD_PREP(SSUSB_RING_OSC_CNTEND_M, 0x1ff) |
1004 + FIELD_PREP(SSUSB_XTAL_OSC_CNTEND_M, 0x7f) |
1005 + SSUSB_RING_BYPASS_DET,
1006 + usbh + SSUSB_B2_ROSC_0_REG);
1007 +
1008 + writel(FIELD_PREP(SSUSB_RING_OSC_FRC_RECAL_M, 3) |
1009 + SSUSB_RING_OSC_FRC_SEL,
1010 + usbh + SSUSB_B2_ROSC_1_REG);
1011 +}
1012 +
1013 +void lowlevel_init(void)
1014 +{
1015 + void __iomem *usbh = ioremap_nocache(SSUSB_BASE, SSUSB_SIZE);
1016 + u32 xtal = get_xtal_mhz();
1017 +
1018 + /* Setup USB xHCI */
1019 + if (xtal == 40)
1020 + xhci_config_40mhz(usbh);
1021 + else if (xtal == 25)
1022 + xhci_config_25mhz(usbh);
1023 +}
1024 +
1025 +ulong notrace get_tbclk(void)
1026 +{
1027 + return gd->arch.timer_freq;
1028 +}
1029 +
1030 +void _machine_restart(void)
1031 +{
1032 + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
1033 +
1034 + while (1)
1035 + writel(SYS_RST, sysc + SYSCTL_RSTCTL_REG);
1036 +}
1037 diff --git a/arch/mips/mach-mtmips/mt7621/mt7621.h b/arch/mips/mach-mtmips/mt7621/mt7621.h
1038 new file mode 100644
1039 index 0000000000..916cc993b4
1040 --- /dev/null
1041 +++ b/arch/mips/mach-mtmips/mt7621/mt7621.h
1042 @@ -0,0 +1,229 @@
1043 +/* SPDX-License-Identifier: GPL-2.0 */
1044 +/*
1045 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1046 + *
1047 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1048 + */
1049 +
1050 +#ifndef _MT7621_H_
1051 +#define _MT7621_H_
1052 +
1053 +#define SYSCTL_BASE 0x1e000000
1054 +#define SYSCTL_SIZE 0x100
1055 +#define TIMER_BASE 0x1e000100
1056 +#define TIMER_SIZE 0x100
1057 +#define RBUS_BASE 0x1e000400
1058 +#define RBUS_SIZE 0x100
1059 +#define GPIO_BASE 0x1e000600
1060 +#define GPIO_SIZE 0x100
1061 +#define DMA_CFG_ARB_BASE 0x1e000800
1062 +#define DMA_CFG_ARB_SIZE 0x100
1063 +#define SPI_BASE 0x1e000b00
1064 +#define SPI_SIZE 0x100
1065 +#define UART1_BASE 0x1e000c00
1066 +#define UART1_SIZE 0x100
1067 +#define UART2_BASE 0x1e000d00
1068 +#define UART2_SIZE 0x100
1069 +#define UART3_BASE 0x1e000e00
1070 +#define UART3_SIZE 0x100
1071 +#define NFI_BASE 0x1e003000
1072 +#define NFI_SIZE 0x800
1073 +#define NFI_ECC_BASE 0x1e003800
1074 +#define NFI_ECC_SIZE 0x800
1075 +#define DRAMC_BASE 0x1e005000
1076 +#define DRAMC_SIZE 0x1000
1077 +#define FE_BASE 0x1e100000
1078 +#define FE_SIZE 0xe000
1079 +#define GMAC_BASE 0x1e110000
1080 +#define GMAC_SIZE 0x8000
1081 +#define SSUSB_BASE 0x1e1c0000
1082 +#define SSUSB_SIZE 0x40000
1083 +
1084 + /* GIC Base Address */
1085 +#define MIPS_GIC_BASE 0x1fbc0000
1086 +
1087 + /* CPC Base Address */
1088 +#define MIPS_CPC_BASE 0x1fbf0000
1089 +
1090 + /* Flash Memory-mapped Base Address */
1091 +#define FLASH_MMAP_BASE 0x1fc00000
1092 +#define TPL_INFO_OFFSET 0x40
1093 +#define TPL_INFO_MAGIC 0x31323637 /* Magic "7621" */
1094 +
1095 +/* SRAM */
1096 +#define FE_SRAM_BASE1 0x8000
1097 +#define FE_SRAM_BASE2 0xa000
1098 +
1099 +/* SYSCTL_BASE */
1100 +#define SYSCTL_CHIP_REV_ID_REG 0x0c
1101 +#define CPU_ID 0x20000
1102 +#define PKG_ID 0x10000
1103 +#define VER_ID_S 8
1104 +#define VER_ID_M 0xf00
1105 +#define ECO_ID_S 0
1106 +#define ECO_ID_M 0x0f
1107 +
1108 +#define SYSCTL_SYSCFG0_REG 0x10
1109 +#define XTAL_MODE_SEL_S 6
1110 +#define XTAL_MODE_SEL_M 0x1c0
1111 +#define DRAM_TYPE 0x10
1112 +#define CHIP_MODE_S 0
1113 +#define CHIP_MODE_M 0x0f
1114 +
1115 +#define BOOT_SRAM_BASE_REG 0x20
1116 +
1117 +#define SYSCTL_CLKCFG0_REG 0x2c
1118 +#define CPU_CLK_SEL_S 30
1119 +#define CPU_CLK_SEL_M 0xc0000000
1120 +#define MPLL_CFG_SEL_S 23
1121 +#define MPLL_CFG_SEL_M 0x800000
1122 +
1123 +#define SYSCTL_RSTCTL_REG 0x34
1124 +#define MCM_RST 0x04
1125 +#define SYS_RST 0x01
1126 +
1127 +#define SYSCTL_CUR_CLK_STS_REG 0x44
1128 +#define CUR_CPU_FDIV_S 8
1129 +#define CUR_CPU_FDIV_M 0x1f00
1130 +#define CUR_CPU_FFRAC_S 0
1131 +#define CUR_CPU_FFRAC_M 0x1f
1132 +
1133 +#define SYSCTL_GPIOMODE_REG 0x60
1134 +#define UART2_MODE_S 5
1135 +#define UART2_MODE_M 0x60
1136 +#define UART3_MODE_S 3
1137 +#define UART3_MODE_M 0x18
1138 +#define UART1_MODE 0x02
1139 +
1140 +/* RBUS_BASE */
1141 +#define RBUS_DYN_CFG0_REG 0x0010
1142 +#define CPU_FDIV_S 8
1143 +#define CPU_FDIV_M 0x1f00
1144 +#define CPU_FFRAC_S 0
1145 +#define CPU_FFRAC_M 0x1f
1146 +
1147 +/* DMA_CFG_ARB_BASE */
1148 +#define DMA_ROUTE_REG 0x000c
1149 +
1150 +/* SPI_BASE */
1151 +#define SPI_SPACE_REG 0x003c
1152 +#define FS_SLAVE_SEL_S 12
1153 +#define FS_SLAVE_SEL_M 0x70000
1154 +#define FS_CLK_SEL_S 0
1155 +#define FS_CLK_SEL_M 0xfff
1156 +
1157 +/* FE_BASE */
1158 +#define FE_RST_GLO_REG 0x0004
1159 +#define FE_PSE_RAM 0x04
1160 +#define FE_PSE_MEM_EN 0x02
1161 +#define FE_PSE_RESET 0x01
1162 +
1163 +/* SSUSB_BASE */
1164 +#define SSUSB_MAC_CK_CTRL_REG 0x10784
1165 +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S 16
1166 +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M 0xff0000
1167 +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S 8
1168 +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M 0xff00
1169 +#define SSUSB_MAC3_SYS_CK_GATE_MODE_S 2
1170 +#define SSUSB_MAC3_SYS_CK_GATE_MODE_M 0x0c
1171 +#define SSUSB_MAC2_SYS_CK_GATE_MODE_S 0
1172 +#define SSUSB_MAC2_SYS_CK_GATE_MODE_M 0x03
1173 +
1174 +#define SSUSB_B2_ROSC_0_REG 0x10a40
1175 +#define SSUSB_RING_OSC_CNTEND_S 23
1176 +#define SSUSB_RING_OSC_CNTEND_M 0xff800000
1177 +#define SSUSB_XTAL_OSC_CNTEND_S 16
1178 +#define SSUSB_XTAL_OSC_CNTEND_M 0x7f0000
1179 +#define SSUSB_RING_BYPASS_DET 0x01
1180 +
1181 +#define SSUSB_B2_ROSC_1_REG 0x10a44
1182 +#define SSUSB_RING_OSC_FRC_RECAL_S 17
1183 +#define SSUSB_RING_OSC_FRC_RECAL_M 0x60000
1184 +#define SSUSB_RING_OSC_FRC_SEL 0x01
1185 +
1186 +#define SSUSB_U3PHYA_1_REG 0x10b04
1187 +#define SSUSB_PCIE_CLKDRV_AMP_S 27
1188 +#define SSUSB_PCIE_CLKDRV_AMP_M 0x38000000
1189 +#define SSUSB_SYSPLL_FBSEL_S 2
1190 +#define SSUSB_SYSPLL_FBSEL_M 0x0c
1191 +#define SSUSB_SYSPLL_PREDIV_S 0
1192 +#define SSUSB_SYSPLL_PREDIV_M 0x03
1193 +
1194 +#define SSUSB_U3PHYA_2_REG 0x10b08
1195 +#define SSUSB_SYSPLL_FBDIV_S 24
1196 +#define SSUSB_SYSPLL_FBDIV_M 0x7f000000
1197 +#define SSUSB_SYSPLL_VCO_DIV_SEL 0x200000
1198 +#define SSUSB_SYSPLL_FPEN 0x2000
1199 +#define SSUSB_SYSPLL_MONCK_EN 0x1000
1200 +#define SSUSB_SYSPLL_VOD_EN 0x200
1201 +
1202 +#define SSUSB_U3PHYA_3_REG 0x10b10
1203 +#define SSUSB_SYSPLL_PCW_NCPO_S 1
1204 +#define SSUSB_SYSPLL_PCW_NCPO_M 0xfffffffe
1205 +
1206 +#define SSUSB_U3PHYA_9_REG 0x10b24
1207 +#define SSUSB_PLL_SSC_PRD_S 0
1208 +#define SSUSB_PLL_SSC_PRD_M 0xffff
1209 +
1210 +#define SSUSB_U3PHYA_11_REG 0x10b2c
1211 +#define SSUSB_EQ_CURSEL 0x1000000
1212 +#define SSUSB_RX_DAC_MUX_S 19
1213 +#define SSUSB_RX_DAC_MUX_M 0xf80000
1214 +#define SSUSB_PCIE_SIGDET_VTH_S 5
1215 +#define SSUSB_PCIE_SIGDET_VTH_M 0x60
1216 +#define SSUSB_PCIE_SIGDET_LPF_S 3
1217 +#define SSUSB_PCIE_SIGDET_LPF_M 0x18
1218 +
1219 +#define DA_SSUSB_PLL_FBKDIV_REG 0x10c1c
1220 +#define SSUSB_PLL_FBKDIV_PE2H_S 24
1221 +#define SSUSB_PLL_FBKDIV_PE2H_M 0x7f000000
1222 +#define SSUSB_PLL_FBKDIV_PE1D_S 16
1223 +#define SSUSB_PLL_FBKDIV_PE1D_M 0x7f0000
1224 +#define SSUSB_PLL_FBKDIV_PE1H_S 8
1225 +#define SSUSB_PLL_FBKDIV_PE1H_M 0x7f00
1226 +#define SSUSB_PLL_FBKDIV_U3_S 0
1227 +#define SSUSB_PLL_FBKDIV_U3_M 0x7f
1228 +
1229 +#define DA_SSUSB_U3PHYA_10_REG 0x10c20
1230 +#define SSUSB_PLL_PREDIV_PE1D_S 18
1231 +#define SSUSB_PLL_PREDIV_PE1D_M 0xc0000
1232 +#define SSUSB_PLL_PREDIV_U3_S 8
1233 +#define SSUSB_PLL_PREDIV_U3_M 0x300
1234 +#define SSUSB_PLL_FBKDI_S 0
1235 +#define SSUSB_PLL_FBKDI_M 0x07
1236 +
1237 +#define DA_SSUSB_PLL_PCW_NCPO_REG 0x10c24
1238 +#define SSUSB_PLL_PCW_NCPO_U3_S 0
1239 +#define SSUSB_PLL_PCW_NCPO_U3_M 0x7fffffff
1240 +
1241 +#define DA_SSUSB_PLL_SSC_DELTA1_REG 0x10c38
1242 +#define SSUSB_PLL_SSC_DELTA1_PE1H_S 16
1243 +#define SSUSB_PLL_SSC_DELTA1_PE1H_M 0xffff0000
1244 +#define SSUSB_PLL_SSC_DELTA1_U3_S 0
1245 +#define SSUSB_PLL_SSC_DELTA1_U3_M 0xffff
1246 +
1247 +#define DA_SSUSB_U3PHYA_21_REG 0x10c40
1248 +#define SSUSB_PLL_SSC_DELTA_U3_S 16
1249 +#define SSUSB_PLL_SSC_DELTA_U3_M 0xffff0000
1250 +#define SSUSB_PLL_SSC_DELTA1_PE2D_S 0
1251 +#define SSUSB_PLL_SSC_DELTA1_PE2D_M 0xffff
1252 +
1253 +/* MT7621 specific CM values */
1254 +
1255 +/* GCR_REGx_BASE */
1256 +#define GCR_REG0_BASE_VALUE 0x1c000000
1257 +#define GCR_REG1_BASE_VALUE 0x60000000
1258 +#define GCR_REG2_BASE_VALUE 0x1c000000
1259 +#define GCR_REG3_BASE_VALUE 0x1c000000
1260 +
1261 +/* GCR_REGx_MASK */
1262 +#define GCR_REG0_MASK_VALUE 0x0000fc00 /* 64M Bus */
1263 +#define GCR_REG1_MASK_VALUE 0x0000f000 /* 256M PCI Mem */
1264 +#define GCR_REG2_MASK_VALUE 0x0000fc00 /* unused */
1265 +#define GCR_REG3_MASK_VALUE 0x0000fc00 /* unused */
1266 +
1267 +#ifndef __ASSEMBLY__
1268 +unsigned long get_xtal_mhz(void);
1269 +#endif
1270 +
1271 +#endif /* _MT7621_H_ */
1272 diff --git a/arch/mips/mach-mtmips/mt7621/serial.c b/arch/mips/mach-mtmips/mt7621/serial.c
1273 new file mode 100644
1274 index 0000000000..0ccc71dc75
1275 --- /dev/null
1276 +++ b/arch/mips/mach-mtmips/mt7621/serial.c
1277 @@ -0,0 +1,23 @@
1278 +// SPDX-License-Identifier: GPL-2.0
1279 +/*
1280 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1281 + *
1282 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1283 + */
1284 +
1285 +#include <asm/io.h>
1286 +#include <asm/addrspace.h>
1287 +#include "mt7621.h"
1288 +
1289 +void board_debug_uart_init(void)
1290 +{
1291 + void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
1292 +
1293 +#if CONFIG_DEBUG_UART_BASE == 0xbe000c00 /* KSEG1ADDR(UART1_BASE) */
1294 + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE);
1295 +#elif CONFIG_DEBUG_UART_BASE == 0xbe000d00 /* KSEG1ADDR(UART2_BASE) */
1296 + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M);
1297 +#elif CONFIG_DEBUG_UART_BASE == 0xbe000e00 /* KSEG1ADDR(UART3_BASE) */
1298 + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M);
1299 +#endif
1300 +}
1301 diff --git a/arch/mips/mach-mtmips/mt7621/spl/Makefile b/arch/mips/mach-mtmips/mt7621/spl/Makefile
1302 new file mode 100644
1303 index 0000000000..ebe54e79b9
1304 --- /dev/null
1305 +++ b/arch/mips/mach-mtmips/mt7621/spl/Makefile
1306 @@ -0,0 +1,9 @@
1307 +
1308 +extra-y += start.o
1309 +
1310 +obj-y += spl.o
1311 +obj-y += cps.o
1312 +obj-y += dram.o
1313 +obj-y += serial.o
1314 +obj-y += launch.o
1315 +obj-y += launch_ll.o
1316 diff --git a/arch/mips/mach-mtmips/mt7621/spl/cps.c b/arch/mips/mach-mtmips/mt7621/spl/cps.c
1317 new file mode 100644
1318 index 0000000000..779e646c12
1319 --- /dev/null
1320 +++ b/arch/mips/mach-mtmips/mt7621/spl/cps.c
1321 @@ -0,0 +1,153 @@
1322 +// SPDX-License-Identifier: GPL-2.0
1323 +/*
1324 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1325 + *
1326 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1327 + */
1328 +
1329 +#include <asm/io.h>
1330 +#include <asm/addrspace.h>
1331 +#include <asm/mipsregs.h>
1332 +#include <asm/cm.h>
1333 +#include <linux/bitfield.h>
1334 +#include "../mt7621.h"
1335 +
1336 +/* GIC Shared Register Bases */
1337 +#define GIC_SH_POL_BASE 0x100
1338 +#define GIC_SH_TRIG_BASE 0x180
1339 +#define GIC_SH_RMASK_BASE 0x300
1340 +#define GIC_SH_SMASK_BASE 0x380
1341 +#define GIC_SH_MASK_BASE 0x400
1342 +#define GIC_SH_PEND_BASE 0x480
1343 +#define GIC_SH_MAP_PIN_BASE 0x500
1344 +#define GIC_SH_MAP_VPE_BASE 0x2000
1345 +
1346 +/* GIC Registers */
1347 +#define GIC_SH_POL31_0 (GIC_SH_POL_BASE + 0x00)
1348 +#define GIC_SH_POL63_32 (GIC_SH_POL_BASE + 0x04)
1349 +
1350 +#define GIC_SH_TRIG31_0 (GIC_SH_TRIG_BASE + 0x00)
1351 +#define GIC_SH_TRIG63_32 (GIC_SH_TRIG_BASE + 0x04)
1352 +
1353 +#define GIC_SH_RMASK31_0 (GIC_SH_RMASK_BASE + 0x00)
1354 +#define GIC_SH_RMASK63_32 (GIC_SH_RMASK_BASE + 0x04)
1355 +
1356 +#define GIC_SH_SMASK31_0 (GIC_SH_SMASK_BASE + 0x00)
1357 +#define GIC_SH_SMASK63_32 (GIC_SH_SMASK_BASE + 0x04)
1358 +
1359 +#define GIC_SH_MAP_PIN(n) (GIC_SH_MAP_PIN_BASE + (n) * 4)
1360 +
1361 +#define GIC_SH_MAP_VPE(n, v) (GIC_SH_MAP_VPE_BASE + (n) * 0x20 + ((v) / 32) * 4)
1362 +#define GIC_SH_MAP_VPE31_0(n) GIC_SH_MAP_VPE(n, 0)
1363 +
1364 +/* GIC_SH_MAP_PIN fields */
1365 +#define GIC_MAP_TO_PIN BIT(31)
1366 +#define GIC_MAP_TO_NMI BIT(30)
1367 +#define GIC_MAP GENMASK(5, 0)
1368 +#define GIC_MAP_SHIFT 0
1369 +
1370 +static void cm_init(void __iomem *cm_base)
1371 +{
1372 + u32 gcrcfg, num_cores;
1373 +
1374 + gcrcfg = readl(cm_base + GCR_CONFIG);
1375 + num_cores = FIELD_GET(GCR_CONFIG_PCORES, gcrcfg) + 1;
1376 +
1377 + writel((1 << num_cores) - 1, cm_base + GCR_ACCESS);
1378 +
1379 + writel(GCR_REG0_BASE_VALUE, cm_base + GCR_REG0_BASE);
1380 + writel(GCR_REG1_BASE_VALUE, cm_base + GCR_REG1_BASE);
1381 + writel(GCR_REG2_BASE_VALUE, cm_base + GCR_REG2_BASE);
1382 + writel(GCR_REG3_BASE_VALUE, cm_base + GCR_REG3_BASE);
1383 +
1384 + clrsetbits_32(cm_base + GCR_REG0_MASK,
1385 + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
1386 + FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG0_MASK_VALUE) |
1387 + GCR_REGn_MASK_CMTGT_IOCU0);
1388 +
1389 + clrsetbits_32(cm_base + GCR_REG1_MASK,
1390 + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
1391 + FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG1_MASK_VALUE) |
1392 + GCR_REGn_MASK_CMTGT_IOCU0);
1393 +
1394 + clrsetbits_32(cm_base + GCR_REG2_MASK,
1395 + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
1396 + FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG2_MASK_VALUE) |
1397 + GCR_REGn_MASK_CMTGT_IOCU0);
1398 +
1399 + clrsetbits_32(cm_base + GCR_REG3_MASK,
1400 + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT,
1401 + FIELD_PREP(GCR_REGn_MASK_ADDRMASK, GCR_REG3_MASK_VALUE) |
1402 + GCR_REGn_MASK_CMTGT_IOCU0);
1403 +
1404 + clrbits_32(cm_base + GCR_BASE, CM_DEFAULT_TARGET_MASK);
1405 + setbits_32(cm_base + GCR_CONTROL, GCR_CONTROL_SYNCCTL);
1406 +}
1407 +
1408 +static void gic_init(void)
1409 +{
1410 + void __iomem *gic_base = (void *)KSEG1ADDR(MIPS_GIC_BASE);
1411 + int i;
1412 +
1413 + /* Interrupt 0..5: Level Trigger, Active High */
1414 + writel(0, gic_base + GIC_SH_TRIG31_0);
1415 + writel(0x3f, gic_base + GIC_SH_RMASK31_0);
1416 + writel(0x3f, gic_base + GIC_SH_POL31_0);
1417 + writel(0x3f, gic_base + GIC_SH_SMASK31_0);
1418 +
1419 + /* Interrupt 56..63: Edge Trigger, Rising Edge */
1420 + /* Hardcoded to set up the last 8 external interrupts for IPI. */
1421 + writel(0xff000000, gic_base + GIC_SH_TRIG63_32);
1422 + writel(0xff000000, gic_base + GIC_SH_RMASK63_32);
1423 + writel(0xff000000, gic_base + GIC_SH_POL63_32);
1424 + writel(0xff000000, gic_base + GIC_SH_SMASK63_32);
1425 +
1426 + /* Map interrupt source to particular hardware interrupt pin */
1427 + /* source {0,1,2,3,4,5} -> pin {0,0,4,3,0,5} */
1428 + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(0));
1429 + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(1));
1430 + writel(GIC_MAP_TO_PIN | 4, gic_base + GIC_SH_MAP_PIN(2));
1431 + writel(GIC_MAP_TO_PIN | 3, gic_base + GIC_SH_MAP_PIN(3));
1432 + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(4));
1433 + writel(GIC_MAP_TO_PIN | 5, gic_base + GIC_SH_MAP_PIN(5));
1434 +
1435 + /* source 56~59 -> pin 1, 60~63 -> pin 2 */
1436 + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(56));
1437 + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(57));
1438 + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(58));
1439 + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(59));
1440 + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(60));
1441 + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(61));
1442 + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(62));
1443 + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(63));
1444 +
1445 + /* Interrupt map to VPE (bit mask) */
1446 + for (i = 0; i < 32; i++)
1447 + writel(BIT(0), gic_base + GIC_SH_MAP_VPE31_0(i));
1448 +
1449 + /*
1450 + * Direct GIC_int 56..63 to vpe 0..3
1451 + * MIPS Linux convention that last 16 interrupts implemented be set
1452 + * aside for IPI signaling.
1453 + * The actual interrupts are tied low and software sends interrupts
1454 + * via GIC_SH_WEDGE writes.
1455 + */
1456 + for (i = 0; i < 4; i++) {
1457 + writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + 56));
1458 + writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + 60));
1459 + }
1460 +}
1461 +
1462 +void mt7621_cps_init(void)
1463 +{
1464 + void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE);
1465 +
1466 + /* Enable GIC */
1467 + writel(MIPS_GIC_BASE | GCR_GIC_EN, cm_base + GCR_GIC_BASE);
1468 +
1469 + /* Enable CPC */
1470 + writel(MIPS_CPC_BASE | GCR_CPC_EN, cm_base + GCR_CPC_BASE);
1471 +
1472 + gic_init();
1473 + cm_init(cm_base);
1474 +}
1475 diff --git a/arch/mips/mach-mtmips/mt7621/spl/dram.c b/arch/mips/mach-mtmips/mt7621/spl/dram.c
1476 new file mode 100644
1477 index 0000000000..100adfb93a
1478 --- /dev/null
1479 +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.c
1480 @@ -0,0 +1,153 @@
1481 +// SPDX-License-Identifier: GPL-2.0
1482 +/*
1483 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1484 + *
1485 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1486 + */
1487 +
1488 +#include <vsprintf.h>
1489 +#include <asm/io.h>
1490 +#include <asm/sections.h>
1491 +#include <asm/byteorder.h>
1492 +#include <asm/addrspace.h>
1493 +#include <linux/string.h>
1494 +#include "../mt7621.h"
1495 +#include "dram.h"
1496 +
1497 +static const u32 ddr2_act[DDR_PARAM_SIZE] = {
1498 +#if defined(CONFIG_MT7621_DRAM_DDR2_512M)
1499 + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174441,
1500 + 0x00000000, 0xF0748661, 0x40001273, 0x9F0A0481,
1501 + 0x0304692F, 0x15602842, 0x00008888, 0x88888888,
1502 + 0x00000000, 0x00000000, 0x00000000, 0x07100000,
1503 + 0x00001B63, 0x00002000, 0x00004000, 0x00006000,
1504 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1505 +#elif defined(CONFIG_MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ)
1506 + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x33484584,
1507 + 0x00000000, 0xF07486A1, 0x50001273, 0x9F010481,
1508 + 0x0304693F, 0x15602842, 0x00008888, 0x88888888,
1509 + 0x00000000, 0x00000000, 0x00000010, 0x07100000,
1510 + 0x00001F73, 0x00002000, 0x00004000, 0x00006000,
1511 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1512 +#elif defined(CONFIG_MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ)
1513 + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174430,
1514 + 0x01000000, 0xF0748661, 0x40001273, 0x9F0F0481,
1515 + 0x0304692F, 0x15602842, 0x00008888, 0x88888888,
1516 + 0x00000000, 0x00000000, 0x00000000, 0x07100000,
1517 + 0x00001B63, 0x00002000, 0x00004000, 0x00006000,
1518 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1519 +#elif defined(CONFIG_MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ)
1520 + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x33484584,
1521 + 0x01000000, 0xF07486A1, 0x50001273, 0x9F070481,
1522 + 0x0304693F, 0x15602842, 0x00008888, 0x88888888,
1523 + 0x00000000, 0x00000000, 0x00000010, 0x07100000,
1524 + 0x00001F73, 0x00002000, 0x00004000, 0x00006000,
1525 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1526 +#else /* CONFIG_MT7621_DRAM_DDR2_1024M */
1527 + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174441,
1528 + 0x01000000, 0xF0748661, 0x40001273, 0x9F0F0481,
1529 + 0x0304692F, 0x15602842, 0x00008888, 0x88888888,
1530 + 0x00000000, 0x00000000, 0x00000000, 0x07100000,
1531 + 0x00001B63, 0x00002000, 0x00004000, 0x00006000,
1532 + 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1533 +#endif
1534 +};
1535 +
1536 +static const u32 ddr3_act[DDR_PARAM_SIZE] = {
1537 +#if defined(CONFIG_MT7621_DRAM_DDR3_1024M)
1538 + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694683,
1539 + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F060481,
1540 + 0x03046948, 0x15602842, 0x00008888, 0x88888888,
1541 + 0x00000000, 0x00000000, 0x00000210, 0x07100000,
1542 + 0x00001B61, 0x00002040, 0x00004010, 0x00006000,
1543 + 0x0C000000, 0x07070000, 0x00000000, 0x00000000,
1544 +#elif defined(CONFIG_MT7621_DRAM_DDR3_4096M)
1545 + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694683,
1546 + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F0F0481,
1547 + 0x03046948, 0x15602842, 0x00008888, 0x88888888,
1548 + 0x00000000, 0x00000000, 0x00000240, 0x07100000,
1549 + 0x00001B61, 0x00002040, 0x00004010, 0x00006000,
1550 + 0x0C000000, 0x07070000, 0x00000000, 0x00000000,
1551 +#elif defined(CONFIG_MT7621_DRAM_DDR3_1024M_KGD)
1552 + 0xFF00FF00, 0xFF00FF00, 0x00000007, 0x44694683,
1553 + 0x01000000, 0xF07406A1, 0xC287221D, 0x9F060481,
1554 + 0x03046923, 0x152f2842, 0x00008888, 0x88888888,
1555 + 0x00000000, 0x00000000, 0x00000210, 0x07100000,
1556 + 0x00001B61, 0x00002040, 0x00004010, 0x00006000,
1557 + 0x0C000000, 0x07070000, 0x000C0000, 0x00000000,
1558 +#else /* CONFIG_MT7621_DRAM_DDR3_2048M */
1559 + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694673,
1560 + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F050481,
1561 + 0x03046948, 0x15602842, 0x00008888, 0x88888888,
1562 + 0x00000000, 0x00000000, 0x00000220, 0x07100000,
1563 + 0x00001B61, 0x00002040, 0x00004010, 0x00006000,
1564 + 0x0C000000, 0x07070000, 0x00000000, 0x00000000,
1565 +#endif
1566 +};
1567 +
1568 +#if defined(CONFIG_MT7621_DRAM_FREQ_400)
1569 +#define DDR_FREQ_PARAM 0x41000000
1570 +#elif defined(CONFIG_MT7621_DRAM_FREQ_1066)
1571 +#define DDR_FREQ_PARAM 0x21000000
1572 +#elif defined(CONFIG_MT7621_DRAM_FREQ_1200)
1573 +#define DDR_FREQ_PARAM 0x11000000
1574 +#else /* CONFIG_MT7621_DRAM_FREQ_800 */
1575 +#define DDR_FREQ_PARAM 0x31000000
1576 +#endif
1577 +
1578 +#define RG_MEPL_FBDIV_S 4
1579 +#define RG_MEPL_FBDIV_M 0x7f
1580 +
1581 +static inline void word_copy(u32 *dest, const u32 *src, u32 count)
1582 +{
1583 + u32 i;
1584 +
1585 + for (i = 0; i < count; i++)
1586 + dest[i] = src[i];
1587 +}
1588 +
1589 +static u32 calc_cpu_pll_val(void)
1590 +{
1591 + u32 div, baseval, fb;
1592 +
1593 + div = get_xtal_mhz();
1594 +
1595 + if (div == 40) {
1596 + div /= 2;
1597 + baseval = 0xc0005802;
1598 + } else {
1599 + baseval = 0xc0004802;
1600 + }
1601 +
1602 + fb = CONFIG_MT7621_CPU_FREQ / div - 1;
1603 + if (fb > RG_MEPL_FBDIV_M)
1604 + fb = RG_MEPL_FBDIV_M;
1605 +
1606 + return baseval | (fb << RG_MEPL_FBDIV_S);
1607 +}
1608 +
1609 +void prepare_stage_bin(void)
1610 +{
1611 + u32 stage_size;
1612 +
1613 + const struct stage_header *stock_stage_bin =
1614 + (const struct stage_header *)__image_copy_end;
1615 +
1616 + struct stage_header *new_stage_bin =
1617 + (struct stage_header *)STAGE_LOAD_ADDR;
1618 +
1619 + if (be32_to_cpu(stock_stage_bin->ep) != STAGE_LOAD_ADDR)
1620 + panic("Invalid DDR stage binary blob\n");
1621 +
1622 + stage_size = be32_to_cpu(stock_stage_bin->stage_size);
1623 +
1624 + word_copy((u32 *)new_stage_bin, (const u32 *)stock_stage_bin,
1625 + (stage_size + sizeof(u32) - 1) / sizeof(u32));
1626 +
1627 + word_copy(new_stage_bin->ddr2_act, ddr2_act, DDR_PARAM_SIZE);
1628 + word_copy(new_stage_bin->ddr3_act, ddr3_act, DDR_PARAM_SIZE);
1629 +
1630 + new_stage_bin->cpu_pll_cfg = calc_cpu_pll_val();
1631 + new_stage_bin->ddr_pll_cfg = DDR_FREQ_PARAM;
1632 + new_stage_bin->baudrate = CONFIG_BAUDRATE;
1633 +}
1634 diff --git a/arch/mips/mach-mtmips/mt7621/spl/dram.h b/arch/mips/mach-mtmips/mt7621/spl/dram.h
1635 new file mode 100644
1636 index 0000000000..7322c58276
1637 --- /dev/null
1638 +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.h
1639 @@ -0,0 +1,39 @@
1640 +/* SPDX-License-Identifier: GPL-2.0 */
1641 +/*
1642 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1643 + *
1644 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1645 + */
1646 +
1647 +#ifndef _MT7621_DRAM_H_
1648 +#define _MT7621_DRAM_H_
1649 +
1650 +#define STAGE_LOAD_ADDR 0xBE108800
1651 +
1652 +#ifndef __ASSEMBLY__
1653 +#include <linux/types.h>
1654 +
1655 +#define DDR_PARAM_SIZE 24
1656 +
1657 +struct stage_header {
1658 + u32 jump_insn[2];
1659 + u32 ep;
1660 + u32 stage_size;
1661 + u32 has_stage2;
1662 + u32 next_ep;
1663 + u32 next_size;
1664 + u32 next_offset;
1665 + u32 cpu_pll_cfg;
1666 + u32 ddr_pll_cfg;
1667 + u32 reserved2[6];
1668 + char build_tag[32];
1669 + u32 ddr3_act[DDR_PARAM_SIZE];
1670 + u32 padding1[2];
1671 + u32 ddr2_act[DDR_PARAM_SIZE];
1672 + u32 padding2[2];
1673 + u32 baudrate;
1674 + u32 padding3;
1675 +};
1676 +#endif
1677 +
1678 +#endif /* _MT7621_DRAM_H_ */
1679 diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch.c b/arch/mips/mach-mtmips/mt7621/spl/launch.c
1680 new file mode 100644
1681 index 0000000000..37c20a5f56
1682 --- /dev/null
1683 +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.c
1684 @@ -0,0 +1,100 @@
1685 +// SPDX-License-Identifier: GPL-2.0
1686 +/*
1687 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1688 + *
1689 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1690 + */
1691 +
1692 +#include <asm/io.h>
1693 +#include <asm/cm.h>
1694 +#include <asm/sections.h>
1695 +#include <asm/addrspace.h>
1696 +#include <asm/mipsmtregs.h>
1697 +#include <linux/sizes.h>
1698 +#include <time.h>
1699 +#include <cpu_func.h>
1700 +#include "launch.h"
1701 +#include "../mt7621.h"
1702 +
1703 +/* Cluster Power Controller (CPC) offsets */
1704 +#define CPC_CL_OTHER 0x2010
1705 +#define CPC_CO_CMD 0x4000
1706 +
1707 +/* CPC_CL_OTHER fields */
1708 +#define CPC_CL_OTHER_CORENUM_SHIFT 16
1709 +#define CPC_CL_OTHER_CORENUM GENMASK(23, 16)
1710 +
1711 +/* CPC_CO_CMD */
1712 +#define PWR_UP 3
1713 +
1714 +#define NUM_CORES 2
1715 +#define NUM_CPUS 4
1716 +#define WAIT_CPUS_TIMEOUT 4000
1717 +
1718 +static void copy_launch_wait_code(void)
1719 +{
1720 + memset((void *)KSEG1, 0, SZ_4K);
1721 +
1722 + memcpy((void *)KSEG1ADDR(LAUNCH_WAITCODE),
1723 + &launch_wait_code_start,
1724 + &launch_wait_code_end - &launch_wait_code_start);
1725 +
1726 + invalidate_dcache_range(KSEG0, SZ_4K);
1727 +}
1728 +
1729 +static void bootup_secondary_core(void)
1730 +{
1731 + void __iomem *cpcbase = (void __iomem *)KSEG1ADDR(MIPS_CPC_BASE);
1732 + int i;
1733 +
1734 + for (i = 1; i < NUM_CORES; i++) {
1735 + writel(i << CPC_CL_OTHER_CORENUM_SHIFT, cpcbase + CPC_CL_OTHER);
1736 + writel(PWR_UP, cpcbase + CPC_CO_CMD);
1737 + }
1738 +}
1739 +
1740 +void secondary_cpu_init(void)
1741 +{
1742 + void __iomem *sysc = (void __iomem *)KSEG1ADDR(SYSCTL_BASE);
1743 + u32 i, dual_core = 0, cpuready = 1, cpumask = 0x03;
1744 + ulong wait_tick;
1745 + struct cpulaunch_t *c;
1746 +
1747 + /* Copy LAUNCH wait code used by other VPEs */
1748 + copy_launch_wait_code();
1749 +
1750 + dual_core = readl(sysc + SYSCTL_CHIP_REV_ID_REG) & CPU_ID;
1751 +
1752 + if (dual_core) {
1753 + /* Bootup secondary core for MT7621A */
1754 + cpumask = 0x0f;
1755 +
1756 + /* Make BootROM/TPL redirect Core1's bootup flow to our entry point */
1757 + writel((uintptr_t)&_start, sysc + BOOT_SRAM_BASE_REG);
1758 +
1759 + bootup_secondary_core();
1760 + }
1761 +
1762 + /* Join the coherent domain */
1763 + join_coherent_domain(dual_core ? 2 : 1);
1764 +
1765 + /* Bootup Core0/VPE1 */
1766 + boot_vpe1();
1767 +
1768 + /* Wait for all CPU ready */
1769 + wait_tick = get_timer(0) + WAIT_CPUS_TIMEOUT;
1770 +
1771 + while (time_before(get_timer(0), wait_tick)) {
1772 + /* CPU0 is obviously ready */
1773 + for (i = 1; i < NUM_CPUS; i++) {
1774 + c = (struct cpulaunch_t *)(KSEG0ADDR(CPULAUNCH) +
1775 + (i << LOG2CPULAUNCH));
1776 +
1777 + if (c->flags & LAUNCH_FREADY)
1778 + cpuready |= BIT(i);
1779 + }
1780 +
1781 + if ((cpuready & cpumask) == cpumask)
1782 + break;
1783 + }
1784 +}
1785 diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch.h b/arch/mips/mach-mtmips/mt7621/spl/launch.h
1786 new file mode 100644
1787 index 0000000000..f34250d605
1788 --- /dev/null
1789 +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.h
1790 @@ -0,0 +1,52 @@
1791 +/* SPDX-License-Identifier: GPL-2.0 */
1792 +/*
1793 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1794 + *
1795 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1796 + */
1797 +
1798 +#ifndef _LAUNCH_H_
1799 +#define _LAUNCH_H_
1800 +
1801 +#ifndef __ASSEMBLY__
1802 +
1803 +struct cpulaunch_t {
1804 + unsigned long pc;
1805 + unsigned long gp;
1806 + unsigned long sp;
1807 + unsigned long a0;
1808 + unsigned long _pad[3]; /* pad to cache line size to avoid thrashing */
1809 + unsigned long flags;
1810 +};
1811 +
1812 +extern char launch_wait_code_start;
1813 +extern char launch_wait_code_end;
1814 +
1815 +void join_coherent_domain(int ncores);
1816 +void boot_vpe1(void);
1817 +
1818 +#else
1819 +
1820 +#define LAUNCH_PC 0
1821 +#define LAUNCH_GP 4
1822 +#define LAUNCH_SP 8
1823 +#define LAUNCH_A0 12
1824 +#define LAUNCH_FLAGS 28
1825 +
1826 +#endif
1827 +
1828 +#define LOG2CPULAUNCH 5
1829 +
1830 +#define LAUNCH_FREADY 1
1831 +#define LAUNCH_FGO 2
1832 +#define LAUNCH_FGONE 4
1833 +
1834 +#define LAUNCH_WAITCODE 0x00000d00
1835 +#define SCRLAUNCH 0x00000e00
1836 +#define CPULAUNCH 0x00000f00
1837 +#define NCPULAUNCH 8
1838 +
1839 +/* Polling period in count cycles for secondary CPU's */
1840 +#define LAUNCHPERIOD 10000
1841 +
1842 +#endif /* _LAUNCH_H_ */
1843 diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S
1844 new file mode 100644
1845 index 0000000000..32d28c7539
1846 --- /dev/null
1847 +++ b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S
1848 @@ -0,0 +1,339 @@
1849 +/* SPDX-License-Identifier: GPL-2.0 */
1850 +/*
1851 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1852 + *
1853 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1854 + */
1855 +
1856 +#include <asm/cm.h>
1857 +#include <asm/asm.h>
1858 +#include <asm/regdef.h>
1859 +#include <asm/cacheops.h>
1860 +#include <asm/mipsregs.h>
1861 +#include <asm/addrspace.h>
1862 +#include <asm/mipsmtregs.h>
1863 +#include "launch.h"
1864 +
1865 + .macro cache_loop curr, end, line_sz, op
1866 +10: cache \op, 0(\curr)
1867 + PTR_ADDU \curr, \curr, \line_sz
1868 + bne \curr, \end, 10b
1869 + .endm
1870 +
1871 + .set mt
1872 +
1873 +/*
1874 + * Join the coherent domain
1875 + * a0 = number of cores
1876 + */
1877 +LEAF(join_coherent_domain)
1878 + /*
1879 + * Enable coherence and allow interventions from all other cores.
1880 + * (Write access enabled via GCR_ACCESS by core 0.)
1881 + */
1882 + li t1, 1
1883 + sll t1, a0
1884 + addiu t1, -1
1885 +
1886 + li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE)
1887 + sw t1, GCR_Cx_COHERENCE(t0)
1888 + ehb
1889 +
1890 + move t2, zero
1891 +
1892 +_next_coherent_core:
1893 + sll t1, t2, GCR_Cx_OTHER_CORENUM_SHIFT
1894 + sw t1, GCR_Cx_OTHER(t0)
1895 +
1896 +_busy_wait_coherent_core:
1897 + lw t1, GCR_CO_COHERENCE(t0)
1898 + beqz t1, _busy_wait_coherent_core
1899 +
1900 + addiu t2, 1
1901 + bne t2, a0, _next_coherent_core
1902 +
1903 + jr ra
1904 + END(join_coherent_domain)
1905 +
1906 +/*
1907 + * All VPEs other than VPE0 will go here.
1908 + */
1909 +LEAF(launch_vpe_entry)
1910 + mfc0 t0, CP0_EBASE
1911 + and t0, t0, MIPS_EBASE_CPUNUM
1912 +
1913 + /* per-VPE cpulaunch_t */
1914 + li a0, KSEG0ADDR(CPULAUNCH)
1915 + sll t1, t0, LOG2CPULAUNCH
1916 + addu a0, t1
1917 +
1918 + /* Set CPU online flag */
1919 + li t0, LAUNCH_FREADY
1920 + sw t0, LAUNCH_FLAGS(a0)
1921 +
1922 + /* Enable count interrupt in mask, but do not enable interrupts */
1923 + mfc0 t0, CP0_STATUS
1924 + ori t0, STATUSF_IP7
1925 + mtc0 t0, CP0_STATUS
1926 +
1927 + /* VPEs executing in wait code do not need a stack */
1928 + li t9, KSEG0ADDR(LAUNCH_WAITCODE)
1929 + jr t9
1930 + END(launch_vpe_entry)
1931 +
1932 +/*
1933 + * This function will not be executed in place.
1934 + * It will be copied into memory, and VPEs other than VPE0 will be
1935 + * started to run into this in-memory function.
1936 + */
1937 +LEAF(launch_wait_code)
1938 + .globl launch_wait_code_start
1939 +launch_wait_code_start:
1940 +
1941 + move t0, a0
1942 +
1943 +start_poll:
1944 + /* Poll CPU go flag */
1945 + mtc0 zero, CP0_COUNT
1946 + li t1, LAUNCHPERIOD
1947 + mtc0 t1, CP0_COMPARE
1948 +
1949 +time_wait:
1950 + /* Software wait */
1951 + mfc0 t2, CP0_COUNT
1952 + subu t2, t1
1953 + bltz t2, time_wait
1954 +
1955 + /* Check the launch flag */
1956 + lw t3, LAUNCH_FLAGS(t0)
1957 + and t3, LAUNCH_FGO
1958 + beqz t3, start_poll
1959 +
1960 + /* Reset the counter and interrupts to give naive clients a chance */
1961 + mfc0 t1, CP0_STATUS
1962 + ins t1, zero, STATUSB_IP7, 1
1963 + mtc0 t1, CP0_STATUS
1964 +
1965 + mfc0 t1, CP0_COUNT
1966 + subu t1, 1
1967 + mtc0 t1, CP0_COMPARE
1968 +
1969 + /* Jump to kernel */
1970 + lw t9, LAUNCH_PC(t0)
1971 + lw gp, LAUNCH_GP(t0)
1972 + lw sp, LAUNCH_SP(t0)
1973 + lw a0, LAUNCH_A0(t0)
1974 + move a1, zero
1975 + move a2, zero
1976 + move a3, zero
1977 + ori t3, LAUNCH_FGONE
1978 + sw t3, LAUNCH_FLAGS(t0)
1979 +
1980 + jr t9
1981 +
1982 + .globl launch_wait_code_end
1983 +launch_wait_code_end:
1984 + END(launch_wait_code)
1985 +
1986 +/*
1987 + * Core1 will go here.
1988 + */
1989 +LEAF(launch_core_entry)
1990 + /* Disable caches */
1991 + bal mips_cache_disable
1992 +
1993 + /* Initialize L1 cache only */
1994 + li a0, CONFIG_SYS_ICACHE_SIZE
1995 + li a1, CONFIG_SYS_ICACHE_LINE_SIZE
1996 + li a2, CONFIG_SYS_DCACHE_SIZE
1997 + li a3, CONFIG_SYS_DCACHE_LINE_SIZE
1998 +
1999 + mtc0 zero, CP0_TAGLO
2000 + mtc0 zero, CP0_TAGLO, 2
2001 + ehb
2002 +
2003 + /*
2004 + * Initialize the I-cache first,
2005 + */
2006 + li t0, KSEG0
2007 + addu t1, t0, a0
2008 + /* clear tag to invalidate */
2009 + cache_loop t0, t1, a1, INDEX_STORE_TAG_I
2010 +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
2011 + /* fill once, so data field parity is correct */
2012 + PTR_LI t0, KSEG0
2013 + cache_loop t0, t1, a1, FILL
2014 + /* invalidate again - prudent but not strictly necessary */
2015 + PTR_LI t0, KSEG0
2016 + cache_loop t0, t1, a1, INDEX_STORE_TAG_I
2017 +#endif
2018 +
2019 + /*
2020 + * then initialize D-cache.
2021 + */
2022 + PTR_LI t0, KSEG0
2023 + PTR_ADDU t1, t0, a2
2024 + /* clear all tags */
2025 + cache_loop t0, t1, a3, INDEX_STORE_TAG_D
2026 +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
2027 + /* load from each line (in cached space) */
2028 + PTR_LI t0, KSEG0
2029 +2: LONG_L zero, 0(t0)
2030 + PTR_ADDU t0, a3
2031 + bne t0, t1, 2b
2032 + /* clear all tags */
2033 + PTR_LI t0, KSEG0
2034 + cache_loop t0, t1, a3, INDEX_STORE_TAG_D
2035 +#endif
2036 +
2037 + /* Set Cache Mode */
2038 + mfc0 t0, CP0_CONFIG
2039 + li t1, CONF_CM_CACHABLE_COW
2040 + ins t0, t1, 0, 3
2041 + mtc0 t0, CP0_CONFIG
2042 +
2043 + /* Join the coherent domain */
2044 + li a0, 2
2045 + bal join_coherent_domain
2046 +
2047 + /* Bootup Core0/VPE1 */
2048 + bal boot_vpe1
2049 +
2050 + b launch_vpe_entry
2051 + END(launch_core_entry)
2052 +
2053 +/*
2054 + * Bootup VPE1.
2055 + * This subroutine must be executed from VPE0 with VPECONF0[MVP] already set.
2056 + */
2057 +LEAF(boot_vpe1)
2058 + mfc0 t0, CP0_MVPCONF0
2059 +
2060 + /* a0 = number of TCs - 1 */
2061 + ext a0, t0, MVPCONF0_PTC_SHIFT, 8
2062 + beqz a0, _vpe1_init_done
2063 +
2064 + /* a1 = number of VPEs - 1 */
2065 + ext a1, t0, MVPCONF0_PVPE_SHIFT, 4
2066 + beqz a1, _vpe1_init_done
2067 +
2068 + /* a2 = current TC No. */
2069 + move a2, zero
2070 +
2071 + /* Enter VPE Configuration State */
2072 + mfc0 t0, CP0_MVPCONTROL
2073 + or t0, MVPCONTROL_VPC
2074 + mtc0 t0, CP0_MVPCONTROL
2075 + ehb
2076 +
2077 +_next_tc:
2078 + /* Set the TC number to be used on MTTR and MFTR instructions */
2079 + mfc0 t0, CP0_VPECONTROL
2080 + ins t0, a2, 0, 8
2081 + mtc0 t0, CP0_VPECONTROL
2082 + ehb
2083 +
2084 + /* TC0 is already bound */
2085 + beqz a2, _next_vpe
2086 +
2087 + /* Halt current TC */
2088 + li t0, TCHALT_H
2089 + mttc0 t0, CP0_TCHALT
2090 + ehb
2091 +
2092 + /* If there is spare TC, bind it to the last VPE (VPE[a1]) */
2093 + slt t1, a1, a2
2094 + bnez t1, _vpe_bind_tc
2095 + move t1, a1
2096 +
2097 + /* Set Exclusive TC for active TC */
2098 + mftc0 t0, CP0_VPECONF0
2099 + ins t0, a2, VPECONF0_XTC_SHIFT, 8
2100 + mttc0 t0, CP0_VPECONF0
2101 +
2102 + move t1, a2
2103 +_vpe_bind_tc:
2104 + /* Bind TC to a VPE */
2105 + mftc0 t0, CP0_TCBIND
2106 + ins t0, t1, TCBIND_CURVPE_SHIFT, 4
2107 + mttc0 t0, CP0_TCBIND
2108 +
2109 + /*
2110 + * Set up CP0_TCSTATUS register:
2111 + * Disable Coprocessor Usable bits
2112 + * Disable MDMX/DSP ASE
2113 + * Clear Dirty TC
2114 + * not dynamically allocatable
2115 + * not allocated
2116 + * Kernel mode
2117 + * interrupt exempt
2118 + * ASID 0
2119 + */
2120 + li t0, TCSTATUS_IXMT
2121 + mttc0 t0, CP0_TCSTATUS
2122 +
2123 +_next_vpe:
2124 + slt t1, a1, a2
2125 + bnez t1, _done_vpe # No more VPEs
2126 +
2127 + /* Disable TC multi-threading */
2128 + mftc0 t0, CP0_VPECONTROL
2129 + ins t0, zero, VPECONTROL_TE_SHIFT, 1
2130 + mttc0 t0, CP0_VPECONTROL
2131 +
2132 + /* Skip following configuration for TC0 */
2133 + beqz a2, _done_vpe
2134 +
2135 + /* Deactivate VPE, set Master VPE */
2136 + mftc0 t0, CP0_VPECONF0
2137 + ins t0, zero, VPECONF0_VPA_SHIFT, 1
2138 + or t0, VPECONF0_MVP
2139 + mttc0 t0, CP0_VPECONF0
2140 +
2141 + mfc0 t0, CP0_STATUS
2142 + mttc0 t0, CP0_STATUS
2143 +
2144 + mttc0 zero, CP0_EPC
2145 + mttc0 zero, CP0_CAUSE
2146 +
2147 + mfc0 t0, CP0_CONFIG
2148 + mttc0 t0, CP0_CONFIG
2149 +
2150 + /*
2151 + * VPE1 of each core can execute cached as its L1 I$ has already
2152 + * been initialized.
2153 + * and the L2$ has been initialized or "disabled" via CCA override.
2154 + */
2155 + PTR_LA t0, _start
2156 + mttc0 t0, CP0_TCRESTART
2157 +
2158 + /* Unset Interrupt Exempt, set Activate Thread */
2159 + mftc0 t0, CP0_TCSTATUS
2160 + ins t0, zero, TCSTATUS_IXMT_SHIFT, 1
2161 + ori t0, TCSTATUS_A
2162 + mttc0 t0, CP0_TCSTATUS
2163 +
2164 + /* Resume TC */
2165 + mttc0 zero, CP0_TCHALT
2166 +
2167 + /* Activate VPE */
2168 + mftc0 t0, CP0_VPECONF0
2169 + ori t0, VPECONF0_VPA
2170 + mttc0 t0, CP0_VPECONF0
2171 +
2172 +_done_vpe:
2173 + addu a2, 1
2174 + sltu t0, a0, a2
2175 + beqz t0, _next_tc
2176 +
2177 + mfc0 t0, CP0_MVPCONTROL
2178 + /* Enable all activated VPE to execute */
2179 + ori t0, MVPCONTROL_EVP
2180 + /* Exit VPE Configuration State */
2181 + ins t0, zero, MVPCONTROL_VPC_SHIFT, 1
2182 + mtc0 t0, CP0_MVPCONTROL
2183 + ehb
2184 +
2185 +_vpe1_init_done:
2186 + jr ra
2187 + END(boot_vpe1)
2188 diff --git a/arch/mips/mach-mtmips/mt7621/spl/serial.c b/arch/mips/mach-mtmips/mt7621/spl/serial.c
2189 new file mode 100644
2190 index 0000000000..5cf093a078
2191 --- /dev/null
2192 +++ b/arch/mips/mach-mtmips/mt7621/spl/serial.c
2193 @@ -0,0 +1,24 @@
2194 +// SPDX-License-Identifier: GPL-2.0
2195 +/*
2196 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2197 + *
2198 + * Author: Weijie Gao <weijie.gao@mediatek.com>
2199 + */
2200 +
2201 +#include <asm/io.h>
2202 +#include "../mt7621.h"
2203 +
2204 +void mtmips_spl_serial_init(void)
2205 +{
2206 +#ifdef CONFIG_SPL_SERIAL
2207 + void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
2208 +
2209 +#if CONFIG_CONS_INDEX == 1
2210 + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE);
2211 +#elif CONFIG_CONS_INDEX == 2
2212 + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M);
2213 +#elif CONFIG_CONS_INDEX == 3
2214 + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M);
2215 +#endif /* CONFIG_CONS_INDEX */
2216 +#endif /* CONFIG_SPL_SERIAL */
2217 +}
2218 diff --git a/arch/mips/mach-mtmips/mt7621/spl/spl.c b/arch/mips/mach-mtmips/mt7621/spl/spl.c
2219 new file mode 100644
2220 index 0000000000..71d01aa7f5
2221 --- /dev/null
2222 +++ b/arch/mips/mach-mtmips/mt7621/spl/spl.c
2223 @@ -0,0 +1,95 @@
2224 +// SPDX-License-Identifier: GPL-2.0
2225 +/*
2226 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2227 + *
2228 + * Author: Weijie Gao <weijie.gao@mediatek.com>
2229 + */
2230 +
2231 +#include <spl.h>
2232 +#include <init.h>
2233 +#include <image.h>
2234 +#include <vsprintf.h>
2235 +#include <malloc.h>
2236 +#include <asm/io.h>
2237 +#include <asm/sections.h>
2238 +#include <asm/addrspace.h>
2239 +#include <asm/byteorder.h>
2240 +#include <asm/global_data.h>
2241 +#include <linux/sizes.h>
2242 +#include <mach/serial.h>
2243 +#include "../mt7621.h"
2244 +#include "dram.h"
2245 +
2246 +DECLARE_GLOBAL_DATA_PTR;
2247 +
2248 +struct tpl_info {
2249 + u32 magic;
2250 + u32 size;
2251 +};
2252 +
2253 +void set_timer_freq_simple(void)
2254 +{
2255 + u32 div = get_xtal_mhz();
2256 +
2257 + /* Round down cpu freq */
2258 + gd->arch.timer_freq = rounddown(CONFIG_MT7621_CPU_FREQ, div) * 500000;
2259 +}
2260 +
2261 +void __noreturn board_init_f(ulong dummy)
2262 +{
2263 + spl_init();
2264 +
2265 +#ifdef CONFIG_SPL_SERIAL
2266 + /*
2267 + * mtmips_spl_serial_init() is useful if debug uart is enabled,
2268 + * or DM based serial is not enabled.
2269 + */
2270 + mtmips_spl_serial_init();
2271 + preloader_console_init();
2272 +#endif
2273 +
2274 + board_init_r(NULL, 0);
2275 +}
2276 +
2277 +void board_boot_order(u32 *spl_boot_list)
2278 +{
2279 +#ifdef CONFIG_MT7621_BOOT_FROM_NAND
2280 + spl_boot_list[0] = BOOT_DEVICE_NAND;
2281 +#else
2282 + spl_boot_list[0] = BOOT_DEVICE_NOR;
2283 +#endif
2284 +}
2285 +
2286 +unsigned long spl_nor_get_uboot_base(void)
2287 +{
2288 + const struct tpl_info *tpli;
2289 + const image_header_t *hdr;
2290 + u32 addr;
2291 +
2292 + addr = FLASH_MMAP_BASE + TPL_INFO_OFFSET;
2293 + tpli = (const struct tpl_info *)KSEG1ADDR(addr);
2294 +
2295 + if (tpli->magic == TPL_INFO_MAGIC) {
2296 + addr = FLASH_MMAP_BASE + tpli->size;
2297 + hdr = (const image_header_t *)KSEG1ADDR(addr);
2298 +
2299 + if (image_get_magic(hdr) == IH_MAGIC) {
2300 + addr += sizeof(*hdr) + image_get_size(hdr);
2301 + return KSEG1ADDR(addr);
2302 + }
2303 + }
2304 +
2305 + panic("Unable to locate SPL payload\n");
2306 + return 0;
2307 +}
2308 +
2309 +uint32_t spl_nand_get_uboot_raw_page(void)
2310 +{
2311 + const struct stage_header *sh = (const struct stage_header *)&_start;
2312 + u32 addr;
2313 +
2314 + addr = image_get_header_size() + be32_to_cpu(sh->stage_size);
2315 + addr = ALIGN(addr, SZ_4K);
2316 +
2317 + return addr;
2318 +}
2319 diff --git a/arch/mips/mach-mtmips/mt7621/spl/start.S b/arch/mips/mach-mtmips/mt7621/spl/start.S
2320 new file mode 100644
2321 index 0000000000..3cad3567e7
2322 --- /dev/null
2323 +++ b/arch/mips/mach-mtmips/mt7621/spl/start.S
2324 @@ -0,0 +1,226 @@
2325 +/* SPDX-License-Identifier: GPL-2.0 */
2326 +/*
2327 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2328 + *
2329 + * Author: Weijie Gao <weijie.gao@mediatek.com>
2330 + */
2331 +
2332 +#include <asm-offsets.h>
2333 +#include <config.h>
2334 +#include <asm/asm.h>
2335 +#include <asm/regdef.h>
2336 +#include <asm/mipsregs.h>
2337 +#include <asm/cacheops.h>
2338 +#include <asm/addrspace.h>
2339 +#include <asm/mipsmtregs.h>
2340 +#include <asm/cm.h>
2341 +#include "../mt7621.h"
2342 +#include "dram.h"
2343 +
2344 +#ifndef CONFIG_SYS_INIT_SP_ADDR
2345 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \
2346 + CONFIG_SYS_INIT_SP_OFFSET)
2347 +#endif
2348 +
2349 +#define SP_ADDR_TEMP 0xbe10dff0
2350 +
2351 + .macro init_wr sel
2352 + MTC0 zero, CP0_WATCHLO,\sel
2353 + mtc0 t1, CP0_WATCHHI,\sel
2354 + .endm
2355 +
2356 + .macro setup_stack_gd
2357 + li t0, -16
2358 + PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
2359 + and sp, t1, t0 # force 16 byte alignment
2360 + PTR_SUBU \
2361 + sp, sp, GD_SIZE # reserve space for gd
2362 + and sp, sp, t0 # force 16 byte alignment
2363 + move k0, sp # save gd pointer
2364 +#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
2365 + !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
2366 + li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
2367 + PTR_SUBU \
2368 + sp, sp, t2 # reserve space for early malloc
2369 + and sp, sp, t0 # force 16 byte alignment
2370 +#endif
2371 + move fp, sp
2372 +
2373 + /* Clear gd */
2374 + move t0, k0
2375 +1:
2376 + PTR_S zero, 0(t0)
2377 + PTR_ADDIU t0, PTRSIZE
2378 + blt t0, t1, 1b
2379 + nop
2380 +
2381 +#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
2382 + !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
2383 + PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
2384 +#endif
2385 + .endm
2386 +
2387 + .set noreorder
2388 +
2389 +ENTRY(_start)
2390 + b 1f
2391 + mtc0 zero, CP0_COUNT
2392 +
2393 + /* Stage header required by BootROM */
2394 + .org 0x8
2395 + .word 0 # ep, filled by mkimage
2396 + .word 0 # stage_size, filled by mkimage
2397 + .word 0 # has_stage2
2398 + .word 0 # next_ep
2399 + .word 0 # next_size
2400 + .word 0 # next_offset
2401 +
2402 +1:
2403 + /* Init CP0 Status */
2404 + mfc0 t0, CP0_STATUS
2405 + and t0, ST0_IMPL
2406 + or t0, ST0_BEV | ST0_ERL
2407 + mtc0 t0, CP0_STATUS
2408 + ehb
2409 +
2410 + /* Clear Watch Status bits and disable watch exceptions */
2411 + li t1, 0x7 # Clear I, R and W conditions
2412 + init_wr 0
2413 + init_wr 1
2414 + init_wr 2
2415 + init_wr 3
2416 +
2417 + /* Clear WP, IV and SW interrupts */
2418 + mtc0 zero, CP0_CAUSE
2419 +
2420 + /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
2421 + mtc0 zero, CP0_COMPARE
2422 +
2423 + /* VPE1 goes to wait code directly */
2424 + mfc0 t0, CP0_TCBIND
2425 + andi t0, TCBIND_CURVPE
2426 + bnez t0, launch_vpe_entry
2427 + nop
2428 +
2429 + /* Core1 goes to specific launch entry */
2430 + PTR_LI t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE)
2431 + lw t1, GCR_Cx_ID(t0)
2432 + bnez t1, launch_core_entry
2433 + nop
2434 +
2435 + /* MT7530 reset */
2436 + li t0, KSEG1ADDR(SYSCTL_BASE)
2437 + lw t1, SYSCTL_RSTCTL_REG(t0)
2438 + ori t1, MCM_RST
2439 + sw t1, SYSCTL_RSTCTL_REG(t0)
2440 +
2441 + /* Disable DMA route for PSE SRAM set by BootROM */
2442 + PTR_LI t0, KSEG1ADDR(DMA_CFG_ARB_BASE)
2443 + sw zero, DMA_ROUTE_REG(t0)
2444 +
2445 + /* Set CPU clock to 500MHz (Required if boot from NAND) */
2446 + li t0, KSEG1ADDR(SYSCTL_BASE)
2447 + lw t1, SYSCTL_CLKCFG0_REG(t0)
2448 + ins t1, zero, 30, 2 # CPU_CLK_SEL
2449 + sw t1, SYSCTL_CLKCFG0_REG(t0)
2450 +
2451 + /* Set CPU clock divider to 1/1 */
2452 + li t0, KSEG1ADDR(RBUS_BASE)
2453 + li t1, 0x101
2454 + sw t1, RBUS_DYN_CFG0_REG(t0)
2455 +
2456 + /* (Re-)initialize the SRAM */
2457 + bal mips_sram_init
2458 + nop
2459 +
2460 + /* Set up temporary stack */
2461 + li sp, SP_ADDR_TEMP
2462 +
2463 + /* Setup full CPS */
2464 + bal mips_cm_map
2465 + nop
2466 +
2467 + bal mt7621_cps_init
2468 + nop
2469 +
2470 + /* Prepare for CPU/DDR initialization binary blob */
2471 + bal prepare_stage_bin
2472 + nop
2473 +
2474 + /* Call CPU/DDR initialization binary blob */
2475 + li t9, STAGE_LOAD_ADDR
2476 + jalr t9
2477 + nop
2478 +
2479 + /* Switch CPU PLL source */
2480 + li t0, KSEG1ADDR(SYSCTL_BASE)
2481 + lw t1, SYSCTL_CLKCFG0_REG(t0)
2482 + li t2, 1
2483 + ins t1, t2, CPU_CLK_SEL_S, 2
2484 + sw t1, SYSCTL_CLKCFG0_REG(t0)
2485 +
2486 + /*
2487 + * Currently SPL is running on locked L2 cache (on KSEG0).
2488 + * To reset the entire cache, we have to writeback SPL to DRAM first.
2489 + * Cache flush won't work here. Use memcpy instead.
2490 + */
2491 +
2492 + la a0, __text_start
2493 + move a1, a0
2494 + la a2, __image_copy_end
2495 + sub a2, a2, a1
2496 + li a3, 5
2497 + ins a0, a3, 29, 3 # convert to KSEG1
2498 +
2499 + bal memcpy
2500 + nop
2501 +
2502 + /* Disable caches */
2503 + bal mips_cache_disable
2504 + nop
2505 +
2506 + /* Reset caches */
2507 + bal mips_cache_reset
2508 + nop
2509 +
2510 + /* Disable SRAM */
2511 + li t0, KSEG1ADDR(FE_BASE)
2512 + li t1, FE_PSE_RESET
2513 + sw t1, FE_RST_GLO_REG(t0)
2514 +
2515 + /* Clear the .bss section */
2516 + la a0, __bss_start
2517 + la a1, __bss_end
2518 +1: sw zero, 0(a0)
2519 + addiu a0, 4
2520 + ble a0, a1, 1b
2521 + nop
2522 +
2523 + /* Set up initial stack and global data */
2524 + setup_stack_gd
2525 +
2526 +#if CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
2527 + /* Set malloc base */
2528 + li t0, (CONFIG_SYS_INIT_SP_ADDR + 15) & (~15)
2529 + PTR_S t0, GD_MALLOC_BASE(k0) # gd->malloc_base offset
2530 +#endif
2531 +
2532 +#if defined(CONFIG_DEBUG_UART) && defined(CONFIG_SPL_SERIAL)
2533 + /* Earliest point to set up debug uart */
2534 + bal debug_uart_init
2535 + nop
2536 +#endif
2537 +
2538 + /* Setup timer */
2539 + bal set_timer_freq_simple
2540 + nop
2541 +
2542 + /* Bootup secondary CPUs */
2543 + bal secondary_cpu_init
2544 + nop
2545 +
2546 + move a0, zero # a0 <-- boot_flags = 0
2547 + bal board_init_f
2548 + move ra, zero
2549 +
2550 + END(_start)
2551 diff --git a/arch/mips/mach-mtmips/mt7621/sram_init.S b/arch/mips/mach-mtmips/mt7621/sram_init.S
2552 new file mode 100644
2553 index 0000000000..03b9eab10b
2554 --- /dev/null
2555 +++ b/arch/mips/mach-mtmips/mt7621/sram_init.S
2556 @@ -0,0 +1,22 @@
2557 +/* SPDX-License-Identifier: GPL-2.0 */
2558 +/*
2559 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2560 + *
2561 + * Author: Weijie Gao <weijie.gao@mediatek.com>
2562 + */
2563 +
2564 +#include <asm/addrspace.h>
2565 +#include <asm/asm.h>
2566 +#include <asm/regdef.h>
2567 +#include "mt7621.h"
2568 +
2569 +LEAF(mips_sram_init)
2570 + li t0, KSEG1ADDR(FE_BASE)
2571 + li t1, FE_PSE_RESET
2572 + sw t1, FE_RST_GLO_REG(t0)
2573 +
2574 + li t1, (FE_PSE_RAM | FE_PSE_MEM_EN)
2575 + sw t1, FE_RST_GLO_REG(t0)
2576 +
2577 + jr ra
2578 + END(mips_sram_init)
2579 diff --git a/arch/mips/mach-mtmips/mt7621/tpl/Makefile b/arch/mips/mach-mtmips/mt7621/tpl/Makefile
2580 new file mode 100644
2581 index 0000000000..471ad74249
2582 --- /dev/null
2583 +++ b/arch/mips/mach-mtmips/mt7621/tpl/Makefile
2584 @@ -0,0 +1,4 @@
2585 +
2586 +extra-y += start.o
2587 +
2588 +obj-y += tpl.o
2589 diff --git a/arch/mips/mach-mtmips/mt7621/tpl/start.S b/arch/mips/mach-mtmips/mt7621/tpl/start.S
2590 new file mode 100644
2591 index 0000000000..19b09f7251
2592 --- /dev/null
2593 +++ b/arch/mips/mach-mtmips/mt7621/tpl/start.S
2594 @@ -0,0 +1,161 @@
2595 +/* SPDX-License-Identifier: GPL-2.0 */
2596 +/*
2597 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2598 + *
2599 + * Author: Weijie Gao <weijie.gao@mediatek.com>
2600 + */
2601 +
2602 +#include <asm-offsets.h>
2603 +#include <config.h>
2604 +#include <asm/asm.h>
2605 +#include <asm/regdef.h>
2606 +#include <asm/addrspace.h>
2607 +#include <asm/mipsregs.h>
2608 +#include <asm/cm.h>
2609 +#include "../mt7621.h"
2610 +
2611 +#define SP_ADDR_TEMP 0xbe10dff0
2612 +
2613 + .set noreorder
2614 +
2615 + .macro init_wr sel
2616 + MTC0 zero, CP0_WATCHLO,\sel
2617 + mtc0 t1, CP0_WATCHHI,\sel
2618 + .endm
2619 +
2620 + .macro uhi_mips_exception
2621 + move k0, t9 # preserve t9 in k0
2622 + move k1, a0 # preserve a0 in k1
2623 + li t9, 15 # UHI exception operation
2624 + li a0, 0 # Use hard register context
2625 + sdbbp 1 # Invoke UHI operation
2626 + .endm
2627 +
2628 +ENTRY(_start)
2629 + b reset
2630 + mtc0 zero, CP0_COUNT
2631 +
2632 + /*
2633 + * Store TPL size here.
2634 + * This will be used by SPL to locate u-boot payload.
2635 + */
2636 + .org TPL_INFO_OFFSET
2637 + .word TPL_INFO_MAGIC
2638 + .word __image_copy_len
2639 +
2640 + /* Exception vector */
2641 + .org 0x200
2642 + /* TLB refill, 32 bit task */
2643 + uhi_mips_exception
2644 +
2645 + .org 0x280
2646 + /* XTLB refill, 64 bit task */
2647 + uhi_mips_exception
2648 +
2649 + .org 0x300
2650 + /* Cache error exception */
2651 + uhi_mips_exception
2652 +
2653 + .org 0x380
2654 + /* General exception */
2655 + uhi_mips_exception
2656 +
2657 + .org 0x400
2658 + /* Catch interrupt exceptions */
2659 + uhi_mips_exception
2660 +
2661 + .org 0x480
2662 + /* EJTAG debug exception */
2663 +1: b 1b
2664 + nop
2665 +
2666 + .org 0x500
2667 +
2668 +reset:
2669 + /* Set KSEG0 to Uncached */
2670 + mfc0 t0, CP0_CONFIG
2671 + ins t0, zero, 0, 3
2672 + ori t0, t0, CONF_CM_UNCACHED
2673 + mtc0 t0, CP0_CONFIG
2674 + ehb
2675 +
2676 + /* Check for CPU number */
2677 + mfc0 t0, CP0_EBASE
2678 + and t0, t0, MIPS_EBASE_CPUNUM
2679 + beqz t0, 1f
2680 + nop
2681 +
2682 + /* Secondary core goes to specified SPL entry address */
2683 + li t0, KSEG1ADDR(SYSCTL_BASE)
2684 + lw t0, BOOT_SRAM_BASE_REG(t0)
2685 + jr t0
2686 + nop
2687 +
2688 + /* Init CP0 Status */
2689 +1: mfc0 t0, CP0_STATUS
2690 + and t0, ST0_IMPL
2691 + or t0, ST0_BEV | ST0_ERL
2692 + mtc0 t0, CP0_STATUS
2693 + nop
2694 +
2695 + /* Clear Watch Status bits and disable watch exceptions */
2696 + li t1, 0x7 # Clear I, R and W conditions
2697 + init_wr 0
2698 + init_wr 1
2699 + init_wr 2
2700 + init_wr 3
2701 +
2702 + /* Clear WP, IV and SW interrupts */
2703 + mtc0 zero, CP0_CAUSE
2704 +
2705 + /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
2706 + mtc0 zero, CP0_COMPARE
2707 +
2708 + /* Setup basic CPS */
2709 + bal mips_cm_map
2710 + nop
2711 +
2712 + li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE)
2713 + li t1, GCR_REG0_BASE_VALUE
2714 + sw t1, GCR_REG0_BASE(t0)
2715 +
2716 + li t1, ((GCR_REG0_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | \
2717 + GCR_REGn_MASK_CMTGT_IOCU0)
2718 + sw t1, GCR_REG0_MASK(t0)
2719 +
2720 + lw t1, GCR_BASE(t0)
2721 + ins t1, zero, 0, 2 # CM_DEFAULT_TARGET
2722 + sw t1, GCR_BASE(t0)
2723 +
2724 + lw t1, GCR_CONTROL(t0)
2725 + li t2, GCR_CONTROL_SYNCCTL
2726 + or t1, t1, t2
2727 + sw t1, GCR_CONTROL(t0)
2728 +
2729 + /* Increase SPI frequency */
2730 + li t0, KSEG1ADDR(SPI_BASE)
2731 + li t1, 5
2732 + sw t1, SPI_SPACE_REG(t0)
2733 +
2734 + /* Set CPU clock to 500MHz */
2735 + li t0, KSEG1ADDR(SYSCTL_BASE)
2736 + lw t1, SYSCTL_CLKCFG0_REG(t0)
2737 + ins t1, zero, 30, 2 # CPU_CLK_SEL
2738 + sw t1, SYSCTL_CLKCFG0_REG(t0)
2739 +
2740 + /* Set CPU clock divider to 1/1 */
2741 + li t0, KSEG1ADDR(RBUS_BASE)
2742 + li t1, 0x101
2743 + sw t1, RBUS_DYN_CFG0_REG(t0)
2744 +
2745 + /* Initialize the SRAM */
2746 + bal mips_sram_init
2747 + nop
2748 +
2749 + /* Set up initial stack */
2750 + li sp, SP_ADDR_TEMP
2751 +
2752 + bal tpl_main
2753 + nop
2754 +
2755 + END(_start)
2756 diff --git a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c
2757 new file mode 100644
2758 index 0000000000..2a828907a3
2759 --- /dev/null
2760 +++ b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c
2761 @@ -0,0 +1,144 @@
2762 +// SPDX-License-Identifier: GPL-2.0
2763 +/*
2764 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2765 + *
2766 + * Author: Weijie Gao <weijie.gao@mediatek.com>
2767 + */
2768 +
2769 +#include <image.h>
2770 +#include <asm/system.h>
2771 +#include <asm/sections.h>
2772 +#include <asm/cacheops.h>
2773 +#include <asm/mipsregs.h>
2774 +#include <asm/cm.h>
2775 +
2776 +#define INDEX_STORE_DATA_SD 0x0f
2777 +
2778 +typedef void __noreturn (*image_entry_noargs_t)(void);
2779 +
2780 +/*
2781 + * Lock L2 cache and fill data
2782 + * Assume that data is 4-byte aligned and start_addr/size is 32-byte aligned
2783 + */
2784 +static void fill_lock_l2cache(uintptr_t dataptr, ulong start_addr, ulong size)
2785 +{
2786 + ulong slsize = CONFIG_SYS_DCACHE_LINE_SIZE;
2787 + ulong end_addr = start_addr + size;
2788 + const u32 *data = (u32 *)dataptr;
2789 + ulong i, addr;
2790 + u32 val;
2791 +
2792 + /* Clear WSC & SPR bit in ErrCtl */
2793 + val = read_c0_ecc();
2794 + val &= 0xcfffffff;
2795 + write_c0_ecc(val);
2796 + execution_hazard_barrier();
2797 +
2798 + for (addr = start_addr; addr < end_addr; addr += slsize) {
2799 + /* Set STagLo to lock cache line */
2800 + write_c0_staglo((addr & 0x1ffff800) | 0xa0);
2801 + mips_cache(INDEX_STORE_TAG_SD, (void *)addr);
2802 +
2803 + /* Fill data */
2804 + for (i = 0; i < slsize; i += 8) {
2805 + val = *data++;
2806 + __write_32bit_c0_register($28, 5, val); /* sdtaglo */
2807 + val = *data++;
2808 + __write_32bit_c0_register($29, 5, val); /* sdtaghi */
2809 + mips_cache(INDEX_STORE_DATA_SD, (void *)(addr + i));
2810 + }
2811 + }
2812 +
2813 + sync();
2814 +}
2815 +
2816 +/* A simple function to initialize MT7621's cache */
2817 +static void mt7621_cache_init(void)
2818 +{
2819 + void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE);
2820 + ulong lsize = CONFIG_SYS_DCACHE_LINE_SIZE;
2821 + ulong addr;
2822 + u32 val;
2823 +
2824 + /* Enable CCA override. Set to uncached */
2825 + val = readl(cm_base + GCR_BASE);
2826 + val &= ~CCA_DEFAULT_OVR_MASK;
2827 + val |= CCA_DEFAULT_OVREN | (2 << CCA_DEFAULT_OVR_SHIFT);
2828 + writel(val, cm_base + GCR_BASE);
2829 +
2830 + /* Initialize L1 I-Cache */
2831 + write_c0_taglo(0);
2832 + write_c0_taghi(0);
2833 +
2834 + for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += lsize)
2835 + mips_cache(INDEX_STORE_TAG_I, (void *)addr);
2836 +
2837 + /* Initialize L1 D-Cache */
2838 + write_c0_dtaglo(0);
2839 + __write_32bit_c0_register($29, 2, 0); /* dtaghi */
2840 +
2841 + for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += lsize)
2842 + mips_cache(INDEX_STORE_TAG_D, (void *)addr);
2843 +
2844 + /* Initialize L2 Cache */
2845 + write_c0_staglo(0);
2846 + __write_32bit_c0_register($29, 4, 0); /* staghi */
2847 +
2848 + for (addr = 0; addr < (256 << 10); addr += lsize)
2849 + mips_cache(INDEX_STORE_TAG_SD, (void *)addr);
2850 +
2851 + /* Dsiable CCA override */
2852 + val = readl(cm_base + GCR_BASE);
2853 + val &= ~(CCA_DEFAULT_OVR_MASK | CCA_DEFAULT_OVREN);
2854 + writel(val, cm_base + GCR_BASE);
2855 +
2856 + /* Set KSEG0 to non-coherent cached (important!) */
2857 + val = read_c0_config();
2858 + val &= ~CONF_CM_CMASK;
2859 + val |= CONF_CM_CACHABLE_NONCOHERENT;
2860 + write_c0_config(val);
2861 + execution_hazard_barrier();
2862 +
2863 + /* Again, invalidate L1 D-Cache */
2864 + for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += lsize)
2865 + mips_cache(INDEX_WRITEBACK_INV_D, (void *)addr);
2866 +
2867 + /* Invalidate L1 I-Cache */
2868 + for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += lsize)
2869 + mips_cache(INDEX_INVALIDATE_I, (void *)addr);
2870 +
2871 + /* Disable L2 cache bypass */
2872 + val = read_c0_config2();
2873 + val &= ~MIPS_CONF_IMPL;
2874 + write_c0_config2(val);
2875 + execution_hazard_barrier();
2876 +}
2877 +
2878 +void __noreturn tpl_main(void)
2879 +{
2880 + const image_header_t *hdr = (const image_header_t *)__image_copy_end;
2881 + image_entry_noargs_t image_entry;
2882 + u32 loadaddr, size;
2883 + uintptr_t data;
2884 +
2885 + /* Initialize the cache first */
2886 + mt7621_cache_init();
2887 +
2888 + if (image_get_magic(hdr) != IH_MAGIC)
2889 + goto failed;
2890 +
2891 + loadaddr = image_get_load(hdr);
2892 + size = image_get_size(hdr);
2893 + image_entry = (image_entry_noargs_t)image_get_ep(hdr);
2894 +
2895 + /* Load TPL image to L2 cache */
2896 + data = (uintptr_t)__image_copy_end + sizeof(struct image_header);
2897 + fill_lock_l2cache(data, loadaddr, size);
2898 +
2899 + /* Jump to SPL */
2900 + image_entry();
2901 +
2902 +failed:
2903 + for (;;)
2904 + ;
2905 +}
2906 diff --git a/include/configs/mt7621.h b/include/configs/mt7621.h
2907 new file mode 100644
2908 index 0000000000..dac6aa4afb
2909 --- /dev/null
2910 +++ b/include/configs/mt7621.h
2911 @@ -0,0 +1,65 @@
2912 +/* SPDX-License-Identifier: GPL-2.0 */
2913 +/*
2914 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2915 + *
2916 + * Author: Weijie Gao <weijie.gao@mediatek.com>
2917 + */
2918 +
2919 +#ifndef __CONFIG_MT7621_H
2920 +#define __CONFIG_MT7621_H
2921 +
2922 +#define CONFIG_SYS_MIPS_TIMER_FREQ 440000000
2923 +
2924 +#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000
2925 +
2926 +#define CONFIG_SYS_SDRAM_BASE 0x80000000
2927 +
2928 +#define CONFIG_VERY_BIG_RAM
2929 +#define CONFIG_MAX_MEM_MAPPED 0x1c000000
2930 +
2931 +#define CONFIG_SYS_INIT_SP_OFFSET 0x800000
2932 +
2933 +#define CONFIG_SYS_BOOTM_LEN 0x2000000
2934 +
2935 +#define CONFIG_SYS_MAXARGS 16
2936 +#define CONFIG_SYS_CBSIZE 1024
2937 +
2938 +#define CONFIG_SYS_NONCACHED_MEMORY 0x100000
2939 +
2940 +/* MMC */
2941 +#define MMC_SUPPORTS_TUNING
2942 +
2943 +/* NAND */
2944 +#define CONFIG_SYS_MAX_NAND_DEVICE 1
2945 +
2946 +/* Serial SPL */
2947 +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL)
2948 +#define CONFIG_SYS_NS16550_MEM32
2949 +#define CONFIG_SYS_NS16550_CLK 50000000
2950 +#define CONFIG_SYS_NS16550_REG_SIZE -4
2951 +#define CONFIG_SYS_NS16550_COM1 0xbe000c00
2952 +#endif
2953 +
2954 +/* Serial common */
2955 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
2956 + 230400, 460800, 921600 }
2957 +
2958 +/* SPL */
2959 +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
2960 +
2961 +#ifdef CONFIG_TPL_BUILD
2962 +#define CONFIG_SPL_START_S_PATH "arch/mips/mach-mtmips/mt7621/tpl"
2963 +/* .bss will not be used by TPL */
2964 +#define CONFIG_SPL_BSS_START_ADDR 0x80000000
2965 +#define CONFIG_SPL_BSS_MAX_SIZE 0
2966 +#else
2967 +#define CONFIG_SPL_START_S_PATH "arch/mips/mach-mtmips/mt7621/spl"
2968 +#define CONFIG_SPL_BSS_START_ADDR 0x80140000
2969 +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000
2970 +#define CONFIG_SPL_MAX_SIZE 0x30000
2971 +#endif
2972 +
2973 +/* Dummy value */
2974 +#define CONFIG_SYS_UBOOT_BASE 0
2975 +
2976 +#endif /* __CONFIG_MT7621_H */
2977 --
2978 2.36.1
2979