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
6 This patch adds support for MediaTek MT7621 SoC.
7 All files are dedicated for u-boot.
9 The default build target is u-boot-mt7621.bin.
11 The specification of this chip:
12 https://www.mediatek.com/products/homenetworking/mt7621
14 Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
15 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
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
66 diff --git a/arch/mips/dts/mt7621-u-boot.dtsi b/arch/mips/dts/mt7621-u-boot.dtsi
68 index 0000000000..c5a8aa357f
70 +++ b/arch/mips/dts/mt7621-u-boot.dtsi
72 +// SPDX-License-Identifier: GPL-2.0
74 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
76 + * Author: Weijie Gao <weijie.gao@mediatek.com>
79 +#include <linux/stringify.h>
88 + u-boot,dm-pre-reloc;
92 + u-boot,dm-pre-reloc;
96 + u-boot,dm-pre-reloc;
100 + u-boot,dm-pre-reloc;
104 + u-boot,dm-pre-reloc;
108 + u-boot,dm-pre-reloc;
112 + u-boot,dm-pre-reloc;
116 + u-boot,dm-pre-reloc;
123 + filename = "u-boot-spl-ddr.bin";
128 + filename = "u-boot-spl.bin";
132 + filename = "mt7621_stage_sram.bin";
138 + filename = "u-boot-spl-ddr.img";
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);
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);
153 + filename = "u-boot-spl-ddr.bin";
159 + filename = "u-boot-mt7621.bin";
162 +#ifndef CONFIG_MT7621_BOOT_FROM_NAND
165 + filename = "u-boot-tpl.bin";
170 +#ifdef CONFIG_MT7621_BOOT_FROM_NAND
171 + align-end = <0x1000>;
173 + filename = "u-boot-spl-ddr.img";
178 + filename = "u-boot-lzma.img";
183 diff --git a/arch/mips/dts/mt7621.dtsi b/arch/mips/dts/mt7621.dtsi
185 index 0000000000..c32b6095e9
187 +++ b/arch/mips/dts/mt7621.dtsi
189 +// SPDX-License-Identifier: GPL-2.0
191 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
193 + * Author: Weijie Gao <weijie.gao@mediatek.com>
196 +#include <dt-bindings/clock/mt7621-clk.h>
197 +#include <dt-bindings/reset/mt7621-reset.h>
198 +#include <dt-bindings/phy/phy.h>
201 + #address-cells = <1>;
203 + compatible = "mediatek,mt7621-soc";
206 + #address-cells = <1>;
210 + device_type = "cpu";
211 + compatible = "mips,mips1004Kc";
216 + device_type = "cpu";
217 + compatible = "mips,mips1004Kc";
223 + compatible = "fixed-clock";
225 + clock-frequency = <48000000>;
227 + #clock-cells = <0>;
231 + compatible = "fixed-clock";
233 + clock-frequency = <50000000>;
235 + #clock-cells = <0>;
238 + sysc: sysctrl@1e000000 {
239 + compatible = "mediatek,mt7621-sysc", "syscon";
240 + reg = <0x1e000000 0x100>;
242 + clkctrl: clock-controller@1e000030 {
243 + compatible = "mediatek,mt7621-clk";
244 + mediatek,memc = <&memc>;
246 + #clock-cells = <1>;
250 + rstctrl: reset-controller@1e000034 {
251 + compatible = "mediatek,mtmips-reset";
252 + reg = <0x1e000034 0x4>;
253 + #reset-cells = <1>;
256 + reboot: resetctl-reboot {
257 + compatible = "resetctl-reboot";
259 + resets = <&rstctrl RST_SYS>;
260 + reset-names = "sysreset";
263 + memc: memctrl@1e005000 {
264 + compatible = "mediatek,mt7621-memc", "syscon";
265 + reg = <0x1e005000 0x1000>;
268 + pinctrl: pinctrl@1e000060 {
269 + compatible = "mediatek,mt7621-pinctrl";
270 + reg = <0x1e000048 0x30>;
272 + pinctrl-names = "default";
273 + pinctrl-0 = <&state_default>;
275 + state_default: pin_state {
278 + uart1_pins: uart1_pins {
283 + uart2_pins: uart2_pins {
288 + uart3_pins: uart3_pins {
293 + sdxc_pins: sdxc_pins {
298 + spi_pins: spi_pins {
303 + eth_pins: eth_pins {
311 + function = "rgmii";
315 + groups = "esw int";
316 + function = "esw int";
321 + drive-strength = <2>;
326 + watchdog: watchdog@1e000100 {
327 + compatible = "mediatek,mt7621-wdt";
328 + reg = <0x1e000100 0x40>;
330 + resets = <&rstctrl RST_TIMER>;
331 + reset-names = "wdt";
333 + status = "disabled";
336 + gpio: gpio@1e000600 {
337 + #address-cells = <1>;
340 + compatible = "mtk,mt7621-gpio";
341 + reg = <0x1e000600 0x100>;
343 + resets = <&rstctrl RST_PIO>;
344 + reset-names = "pio";
348 + compatible = "mtk,mt7621-gpio-bank";
355 + compatible = "mtk,mt7621-gpio-bank";
362 + compatible = "mtk,mt7621-gpio-bank";
368 + spi: spi@1e000b00 {
369 + compatible = "ralink,mt7621-spi";
370 + reg = <0x1e000b00 0x40>;
372 + status = "disabled";
374 + pinctrl-names = "default";
375 + pinctrl-0 = <&spi_pins>;
377 + resets = <&rstctrl RST_SPI>;
378 + reset-names = "spi";
380 + clocks = <&clkctrl MT7621_CLK_SPI>;
382 + #address-cells = <1>;
386 + uart0: uart1@1e000c00 {
387 + compatible = "mediatek,hsuart", "ns16550a";
388 + reg = <0x1e000c00 0x100>;
390 + pinctrl-names = "default";
391 + pinctrl-0 = <&uart1_pins>;
393 + clocks = <&clkctrl MT7621_CLK_UART1>;
395 + resets = <&rstctrl RST_UART1>;
400 + uart1: uart2@1e000d00 {
401 + compatible = "mediatek,hsuart", "ns16550a";
402 + reg = <0x1e000d00 0x100>;
404 + pinctrl-names = "default";
405 + pinctrl-0 = <&uart2_pins>;
407 + clocks = <&clkctrl MT7621_CLK_UART2>;
409 + resets = <&rstctrl RST_UART2>;
413 + status = "disabled";
416 + uart2: uart3@1e000e00 {
417 + compatible = "mediatek,hsuart", "ns16550a";
418 + reg = <0x1e000e00 0x100>;
420 + pinctrl-names = "default";
421 + pinctrl-0 = <&uart3_pins>;
423 + clocks = <&clkctrl MT7621_CLK_UART3>;
425 + resets = <&rstctrl RST_UART3>;
429 + status = "disabled";
432 + eth: eth@1e100000 {
433 + compatible = "mediatek,mt7621-eth";
434 + reg = <0x1e100000 0x20000>;
435 + mediatek,ethsys = <&sysc>;
437 + pinctrl-names = "default";
438 + pinctrl-0 = <ð_pins>;
440 + resets = <&rstctrl RST_FE>, <&rstctrl RST_GMAC>, <&rstctrl RST_MCM>;
441 + reset-names = "fe", "gmac", "mcm";
443 + clocks = <&clkctrl MT7621_CLK_GDMA>,
444 + <&clkctrl MT7621_CLK_ETH>;
445 + clock-names = "gmac", "fe";
447 + #address-cells = <1>;
450 + mediatek,gmac-id = <0>;
451 + phy-mode = "rgmii";
452 + mediatek,switch = "mt7530";
461 + mmc: mmc@1e130000 {
462 + compatible = "mediatek,mt7621-mmc";
463 + reg = <0x1e130000 0x4000>;
465 + status = "disabled";
471 + pinctrl-names = "default";
472 + pinctrl-0 = <&sdxc_pins>;
474 + clocks = <&clk50m>, <&clkctrl MT7621_CLK_SHXC>;
475 + clock-names = "source", "hclk";
477 + resets = <&rstctrl RST_SDXC>;
480 + ssusb: usb@1e1c0000 {
481 + compatible = "mediatek,mt7621-xhci", "mediatek,mtk-xhci";
482 + reg = <0x1e1c0000 0x1000>, <0x1e1d0700 0x100>;
483 + reg-names = "mac", "ippc";
485 + clocks = <&clk48m>, <&clk48m>;
486 + clock-names = "sys_ck", "ref_ck";
488 + phys = <&u2port0 PHY_TYPE_USB2>,
489 + <&u3port0 PHY_TYPE_USB3>,
490 + <&u2port1 PHY_TYPE_USB2>;
492 + status = "disabled";
495 + u3phy: usb-phy@1e1d0000 {
496 + compatible = "mediatek,mt7621-u3phy",
497 + "mediatek,generic-tphy-v1";
498 + reg = <0x1e1d0000 0x700>;
499 + #address-cells = <1>;
502 + status = "disabled";
504 + u2port0: usb-phy@1e1d0800 {
505 + reg = <0x1e1d0800 0x0100>;
507 + clocks = <&clk48m>;
508 + clock-names = "ref";
511 + u3port0: usb-phy@1e1d0900 {
512 + reg = <0x1e1d0900 0x0100>;
516 + u2port1: usb-phy@1e1d1000 {
517 + reg = <0x1e1d1000 0x0100>;
519 + clocks = <&clk48m>;
520 + clock-names = "ref";
524 + i2c: i2c@1e000900 {
525 + compatible = "i2c-gpio";
527 + status = "disabled";
529 + i2c-gpio,delay-us = <3>;
531 + gpios = <&gpio0 3 1>, /* PIN3 as SDA */
532 + <&gpio0 4 1>; /* PIN4 as CLK */
534 + #address-cells = <1>;
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
545 default "mt7620" if SOC_MT7620
546 + default "mt7621" if SOC_MT7621
547 default "mt7628" if SOC_MT7628
549 config SYS_DCACHE_SIZE
550 @@ -18,25 +19,45 @@ config SYS_DCACHE_LINE_SIZE
553 config SYS_ICACHE_SIZE
555 + default 65536 if SOC_MT7620 || SOC_MT7628
556 + default 32768 if SOC_MT7621
558 config SYS_ICACHE_LINE_SIZE
561 +config SYS_SCACHE_LINE_SIZE
562 + default 32 if SOC_MT7621
565 - default 0x9c000000 if !SPL
566 - default 0x80200000 if SPL
567 + default 0x9c000000 if !SPL && !SOC_MT7621
568 + default 0x80200000 if SPL || SOC_MT7621
572 + default 0x9c000000 if !SOC_MT7621
573 + default 0x80100000 if SOC_MT7621
575 +config SPL_SIZE_LIMIT
576 + default 0x30000 if SOC_MT7621
578 +config TPL_TEXT_BASE
579 + default 0xbfc00000 if SOC_MT7621
582 + default 4096 if SOC_MT7621
585 default "u-boot-lzma.img" if SPL_LZMA
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
595 + default 256 if SOC_MT7620 || SOC_MT7628
596 + default 512 if SOC_MT7621
599 prompt "MediaTek MIPS SoC select"
601 @@ -55,6 +76,23 @@ config SOC_MT7620
603 This supports MediaTek MT7620.
608 + select MIPS_L2_CACHE
609 + select SYS_CACHE_SHIFT_5
610 + select SYS_MIPS_CACHE_INIT_RAM_LOAD
611 + select PINCTRL_MT7621
617 + select SPL_LOADER_SUPPORT if SPL
618 + select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL
620 + This supports MediaTek MT7621.
624 select SYS_CACHE_SHIFT_5
625 @@ -80,6 +118,7 @@ config SOC_MT7628
628 source "arch/mips/mach-mtmips/mt7620/Kconfig"
629 +source "arch/mips/mach-mtmips/mt7621/Kconfig"
630 source "arch/mips/mach-mtmips/mt7628/Kconfig"
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
638 # SPDX-License-Identifier: GPL-2.0+
642 +ifneq ($(CONFIG_SOC_MT7621),y)
645 obj-$(CONFIG_SPL_BUILD) += spl.o
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;
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);
664 diff --git a/arch/mips/mach-mtmips/mt7621/Kconfig b/arch/mips/mach-mtmips/mt7621/Kconfig
666 index 0000000000..37d512c68f
668 +++ b/arch/mips/mach-mtmips/mt7621/Kconfig
673 +menu "CPU & DDR configuration"
675 +config MT7621_CPU_FREQ
676 + int "CPU Frequency (MHz)"
681 + prompt "DRAM Frequency"
682 + default MT7621_DRAM_FREQ_1200
684 +config MT7621_DRAM_FREQ_400
687 +config MT7621_DRAM_FREQ_800
690 +config MT7621_DRAM_FREQ_1066
693 +config MT7621_DRAM_FREQ_1200
699 + prompt "DDR2 timing parameters"
700 + default MT7621_DRAM_DDR2_1024M
702 +config MT7621_DRAM_DDR2_512M
705 +config MT7621_DRAM_DDR2_1024M
708 +config MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ
709 + bool "W9751G6KB_A02 @ 1066MHz (64MB)"
711 +config MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ
712 + bool "W971GG6KB25 @ 800MHz (128MB)"
714 +config MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ
715 + bool "W971GG6KB18 @ 1066MHz (128MB)"
720 + prompt "DDR3 timing parameters"
721 + default MT7621_DRAM_DDR3_2048M
723 +config MT7621_DRAM_DDR3_1024M
726 +config MT7621_DRAM_DDR3_1024M_KGD
727 + bool "128MB KGD (MT7621DA)"
729 +config MT7621_DRAM_DDR3_2048M
732 +config MT7621_DRAM_DDR3_4096M
739 +config DEBUG_UART_BOARD_INIT
742 +config MT7621_BOOT_FROM_NAND
743 + bool "Boot from NAND"
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.
749 + prompt "Board select"
753 +config SYS_CONFIG_NAME
754 + string "Board configuration name"
755 + default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB
758 + string "Board name"
759 + default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB
762 + default "mediatek" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB
765 diff --git a/arch/mips/mach-mtmips/mt7621/Makefile b/arch/mips/mach-mtmips/mt7621/Makefile
767 index 0000000000..bf1b0bb688
769 +++ b/arch/mips/mach-mtmips/mt7621/Makefile
771 +# SPDX-License-Identifier: GPL-2.0
776 +ifeq ($(CONFIG_SPL_BUILD),y)
777 +ifeq ($(CONFIG_TPL_BUILD),y)
783 +obj-y += sram_init.o
785 diff --git a/arch/mips/mach-mtmips/mt7621/init.c b/arch/mips/mach-mtmips/mt7621/init.c
787 index 0000000000..d21848ad23
789 +++ b/arch/mips/mach-mtmips/mt7621/init.c
791 +// SPDX-License-Identifier: GPL-2.0
793 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
795 + * Author: Weijie Gao <weijie.gao@mediatek.com>
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>
807 +DECLARE_GLOBAL_DATA_PTR;
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",
818 +int print_cpuinfo(void)
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;
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);
834 + val = readl(sysc + SYSCTL_SYSCFG0_REG);
835 + dram = FIELD_GET(DRAM_TYPE, val);
836 + chipmode = FIELD_GET(CHIP_MODE_M, val);
838 + bootdev = boot_mode[chipmode];
840 + bootdev = "Unsupported boot mode";
842 + printf("CPU: MediaTek MT7621%c ver %u, eco %u\n",
843 + core ? (pkg ? 'A' : 'N') : 'S', ver, eco);
845 + printf("Boot: DDR%u, %s\n", dram ? 2 : 3, bootdev);
847 + ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(mt7621_clk),
854 + clk.id = MT7621_CLK_CPU;
855 + cpu_clk = clk_get_rate(&clk);
857 + clk.id = MT7621_CLK_BUS;
858 + bus_clk = clk_get_rate(&clk);
860 + clk.id = MT7621_CLK_DDR;
861 + ddr_clk = clk_get_rate(&clk);
863 + clk.id = MT7621_CLK_XTAL;
864 + xtal_clk = clk_get_rate(&clk);
866 + /* Set final timer frequency */
868 + gd->arch.timer_freq = cpu_clk / 2;
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);
877 +unsigned long get_xtal_mhz(void)
879 + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
882 + bs = readl(sysc + SYSCTL_SYSCFG0_REG);
883 + xtal_sel = FIELD_GET(XTAL_MODE_SEL_M, bs);
887 + else if (xtal_sel <= 5)
893 +static void xhci_config_40mhz(void __iomem *usbh)
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);
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);
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);
912 + writel(FIELD_PREP(SSUSB_PLL_PCW_NCPO_U3_M, 0x1e400000),
913 + usbh + DA_SSUSB_PLL_PCW_NCPO_REG);
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);
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);
923 + writel(FIELD_PREP(SSUSB_PLL_SSC_PRD_M, 0x140),
924 + usbh + SSUSB_U3PHYA_9_REG);
926 + writel(FIELD_PREP(SSUSB_SYSPLL_PCW_NCPO_M, 0x11c00000),
927 + usbh + SSUSB_U3PHYA_3_REG);
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);
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);
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);
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);
949 + writel(FIELD_PREP(SSUSB_RING_OSC_FRC_RECAL_M, 3) |
950 + SSUSB_RING_OSC_FRC_SEL,
951 + usbh + SSUSB_B2_ROSC_1_REG);
954 +static void xhci_config_25mhz(void __iomem *usbh)
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);
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);
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);
972 + writel(FIELD_PREP(SSUSB_PLL_PCW_NCPO_U3_M, 0x18000000),
973 + usbh + DA_SSUSB_PLL_PCW_NCPO_REG);
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);
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);
983 + writel(FIELD_PREP(SSUSB_PLL_SSC_PRD_M, 0x190),
984 + usbh + SSUSB_U3PHYA_9_REG);
986 + writel(FIELD_PREP(SSUSB_SYSPLL_PCW_NCPO_M, 0xe000000),
987 + usbh + SSUSB_U3PHYA_3_REG);
989 + writel(FIELD_PREP(SSUSB_PCIE_CLKDRV_AMP_M, 4) |
990 + FIELD_PREP(SSUSB_SYSPLL_FBSEL_M, 1),
991 + usbh + SSUSB_U3PHYA_1_REG);
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);
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);
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);
1008 + writel(FIELD_PREP(SSUSB_RING_OSC_FRC_RECAL_M, 3) |
1009 + SSUSB_RING_OSC_FRC_SEL,
1010 + usbh + SSUSB_B2_ROSC_1_REG);
1013 +void lowlevel_init(void)
1015 + void __iomem *usbh = ioremap_nocache(SSUSB_BASE, SSUSB_SIZE);
1016 + u32 xtal = get_xtal_mhz();
1018 + /* Setup USB xHCI */
1020 + xhci_config_40mhz(usbh);
1021 + else if (xtal == 25)
1022 + xhci_config_25mhz(usbh);
1025 +ulong notrace get_tbclk(void)
1027 + return gd->arch.timer_freq;
1030 +void _machine_restart(void)
1032 + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
1035 + writel(SYS_RST, sysc + SYSCTL_RSTCTL_REG);
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
1041 +++ b/arch/mips/mach-mtmips/mt7621/mt7621.h
1043 +/* SPDX-License-Identifier: GPL-2.0 */
1045 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1047 + * Author: Weijie Gao <weijie.gao@mediatek.com>
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
1084 + /* GIC Base Address */
1085 +#define MIPS_GIC_BASE 0x1fbc0000
1087 + /* CPC Base Address */
1088 +#define MIPS_CPC_BASE 0x1fbf0000
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" */
1096 +#define FE_SRAM_BASE1 0x8000
1097 +#define FE_SRAM_BASE2 0xa000
1100 +#define SYSCTL_CHIP_REV_ID_REG 0x0c
1101 +#define CPU_ID 0x20000
1102 +#define PKG_ID 0x10000
1104 +#define VER_ID_M 0xf00
1106 +#define ECO_ID_M 0x0f
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
1115 +#define BOOT_SRAM_BASE_REG 0x20
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
1123 +#define SYSCTL_RSTCTL_REG 0x34
1124 +#define MCM_RST 0x04
1125 +#define SYS_RST 0x01
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
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
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
1147 +/* DMA_CFG_ARB_BASE */
1148 +#define DMA_ROUTE_REG 0x000c
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
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
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
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
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
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
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
1202 +#define SSUSB_U3PHYA_3_REG 0x10b10
1203 +#define SSUSB_SYSPLL_PCW_NCPO_S 1
1204 +#define SSUSB_SYSPLL_PCW_NCPO_M 0xfffffffe
1206 +#define SSUSB_U3PHYA_9_REG 0x10b24
1207 +#define SSUSB_PLL_SSC_PRD_S 0
1208 +#define SSUSB_PLL_SSC_PRD_M 0xffff
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
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
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
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
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
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
1253 +/* MT7621 specific CM values */
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
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 */
1267 +#ifndef __ASSEMBLY__
1268 +unsigned long get_xtal_mhz(void);
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
1276 +++ b/arch/mips/mach-mtmips/mt7621/serial.c
1278 +// SPDX-License-Identifier: GPL-2.0
1280 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1282 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1285 +#include <asm/io.h>
1286 +#include <asm/addrspace.h>
1287 +#include "mt7621.h"
1289 +void board_debug_uart_init(void)
1291 + void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
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);
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
1305 +++ b/arch/mips/mach-mtmips/mt7621/spl/Makefile
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
1320 +++ b/arch/mips/mach-mtmips/mt7621/spl/cps.c
1322 +// SPDX-License-Identifier: GPL-2.0
1324 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1326 + * Author: Weijie Gao <weijie.gao@mediatek.com>
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"
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
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)
1350 +#define GIC_SH_TRIG31_0 (GIC_SH_TRIG_BASE + 0x00)
1351 +#define GIC_SH_TRIG63_32 (GIC_SH_TRIG_BASE + 0x04)
1353 +#define GIC_SH_RMASK31_0 (GIC_SH_RMASK_BASE + 0x00)
1354 +#define GIC_SH_RMASK63_32 (GIC_SH_RMASK_BASE + 0x04)
1356 +#define GIC_SH_SMASK31_0 (GIC_SH_SMASK_BASE + 0x00)
1357 +#define GIC_SH_SMASK63_32 (GIC_SH_SMASK_BASE + 0x04)
1359 +#define GIC_SH_MAP_PIN(n) (GIC_SH_MAP_PIN_BASE + (n) * 4)
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)
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
1370 +static void cm_init(void __iomem *cm_base)
1372 + u32 gcrcfg, num_cores;
1374 + gcrcfg = readl(cm_base + GCR_CONFIG);
1375 + num_cores = FIELD_GET(GCR_CONFIG_PCORES, gcrcfg) + 1;
1377 + writel((1 << num_cores) - 1, cm_base + GCR_ACCESS);
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);
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);
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);
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);
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);
1404 + clrbits_32(cm_base + GCR_BASE, CM_DEFAULT_TARGET_MASK);
1405 + setbits_32(cm_base + GCR_CONTROL, GCR_CONTROL_SYNCCTL);
1408 +static void gic_init(void)
1410 + void __iomem *gic_base = (void *)KSEG1ADDR(MIPS_GIC_BASE);
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);
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);
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));
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));
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));
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.
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));
1462 +void mt7621_cps_init(void)
1464 + void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE);
1467 + writel(MIPS_GIC_BASE | GCR_GIC_EN, cm_base + GCR_GIC_BASE);
1470 + writel(MIPS_CPC_BASE | GCR_CPC_EN, cm_base + GCR_CPC_BASE);
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
1479 +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.c
1481 +// SPDX-License-Identifier: GPL-2.0
1483 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1485 + * Author: Weijie Gao <weijie.gao@mediatek.com>
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"
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,
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,
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
1578 +#define RG_MEPL_FBDIV_S 4
1579 +#define RG_MEPL_FBDIV_M 0x7f
1581 +static inline void word_copy(u32 *dest, const u32 *src, u32 count)
1585 + for (i = 0; i < count; i++)
1589 +static u32 calc_cpu_pll_val(void)
1591 + u32 div, baseval, fb;
1593 + div = get_xtal_mhz();
1597 + baseval = 0xc0005802;
1599 + baseval = 0xc0004802;
1602 + fb = CONFIG_MT7621_CPU_FREQ / div - 1;
1603 + if (fb > RG_MEPL_FBDIV_M)
1604 + fb = RG_MEPL_FBDIV_M;
1606 + return baseval | (fb << RG_MEPL_FBDIV_S);
1609 +void prepare_stage_bin(void)
1613 + const struct stage_header *stock_stage_bin =
1614 + (const struct stage_header *)__image_copy_end;
1616 + struct stage_header *new_stage_bin =
1617 + (struct stage_header *)STAGE_LOAD_ADDR;
1619 + if (be32_to_cpu(stock_stage_bin->ep) != STAGE_LOAD_ADDR)
1620 + panic("Invalid DDR stage binary blob\n");
1622 + stage_size = be32_to_cpu(stock_stage_bin->stage_size);
1624 + word_copy((u32 *)new_stage_bin, (const u32 *)stock_stage_bin,
1625 + (stage_size + sizeof(u32) - 1) / sizeof(u32));
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);
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;
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
1638 +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.h
1640 +/* SPDX-License-Identifier: GPL-2.0 */
1642 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1644 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1647 +#ifndef _MT7621_DRAM_H_
1648 +#define _MT7621_DRAM_H_
1650 +#define STAGE_LOAD_ADDR 0xBE108800
1652 +#ifndef __ASSEMBLY__
1653 +#include <linux/types.h>
1655 +#define DDR_PARAM_SIZE 24
1657 +struct stage_header {
1668 + char build_tag[32];
1669 + u32 ddr3_act[DDR_PARAM_SIZE];
1671 + u32 ddr2_act[DDR_PARAM_SIZE];
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
1683 +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.c
1685 +// SPDX-License-Identifier: GPL-2.0
1687 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1689 + * Author: Weijie Gao <weijie.gao@mediatek.com>
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>
1699 +#include <cpu_func.h>
1700 +#include "launch.h"
1701 +#include "../mt7621.h"
1703 +/* Cluster Power Controller (CPC) offsets */
1704 +#define CPC_CL_OTHER 0x2010
1705 +#define CPC_CO_CMD 0x4000
1707 +/* CPC_CL_OTHER fields */
1708 +#define CPC_CL_OTHER_CORENUM_SHIFT 16
1709 +#define CPC_CL_OTHER_CORENUM GENMASK(23, 16)
1714 +#define NUM_CORES 2
1716 +#define WAIT_CPUS_TIMEOUT 4000
1718 +static void copy_launch_wait_code(void)
1720 + memset((void *)KSEG1, 0, SZ_4K);
1722 + memcpy((void *)KSEG1ADDR(LAUNCH_WAITCODE),
1723 + &launch_wait_code_start,
1724 + &launch_wait_code_end - &launch_wait_code_start);
1726 + invalidate_dcache_range(KSEG0, SZ_4K);
1729 +static void bootup_secondary_core(void)
1731 + void __iomem *cpcbase = (void __iomem *)KSEG1ADDR(MIPS_CPC_BASE);
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);
1740 +void secondary_cpu_init(void)
1742 + void __iomem *sysc = (void __iomem *)KSEG1ADDR(SYSCTL_BASE);
1743 + u32 i, dual_core = 0, cpuready = 1, cpumask = 0x03;
1745 + struct cpulaunch_t *c;
1747 + /* Copy LAUNCH wait code used by other VPEs */
1748 + copy_launch_wait_code();
1750 + dual_core = readl(sysc + SYSCTL_CHIP_REV_ID_REG) & CPU_ID;
1753 + /* Bootup secondary core for MT7621A */
1756 + /* Make BootROM/TPL redirect Core1's bootup flow to our entry point */
1757 + writel((uintptr_t)&_start, sysc + BOOT_SRAM_BASE_REG);
1759 + bootup_secondary_core();
1762 + /* Join the coherent domain */
1763 + join_coherent_domain(dual_core ? 2 : 1);
1765 + /* Bootup Core0/VPE1 */
1768 + /* Wait for all CPU ready */
1769 + wait_tick = get_timer(0) + WAIT_CPUS_TIMEOUT;
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));
1777 + if (c->flags & LAUNCH_FREADY)
1778 + cpuready |= BIT(i);
1781 + if ((cpuready & cpumask) == cpumask)
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
1789 +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.h
1791 +/* SPDX-License-Identifier: GPL-2.0 */
1793 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1795 + * Author: Weijie Gao <weijie.gao@mediatek.com>
1801 +#ifndef __ASSEMBLY__
1803 +struct cpulaunch_t {
1808 + unsigned long _pad[3]; /* pad to cache line size to avoid thrashing */
1809 + unsigned long flags;
1812 +extern char launch_wait_code_start;
1813 +extern char launch_wait_code_end;
1815 +void join_coherent_domain(int ncores);
1816 +void boot_vpe1(void);
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
1828 +#define LOG2CPULAUNCH 5
1830 +#define LAUNCH_FREADY 1
1831 +#define LAUNCH_FGO 2
1832 +#define LAUNCH_FGONE 4
1834 +#define LAUNCH_WAITCODE 0x00000d00
1835 +#define SCRLAUNCH 0x00000e00
1836 +#define CPULAUNCH 0x00000f00
1837 +#define NCPULAUNCH 8
1839 +/* Polling period in count cycles for secondary CPU's */
1840 +#define LAUNCHPERIOD 10000
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
1847 +++ b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S
1849 +/* SPDX-License-Identifier: GPL-2.0 */
1851 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
1853 + * Author: Weijie Gao <weijie.gao@mediatek.com>
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"
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
1874 + * Join the coherent domain
1875 + * a0 = number of cores
1877 +LEAF(join_coherent_domain)
1879 + * Enable coherence and allow interventions from all other cores.
1880 + * (Write access enabled via GCR_ACCESS by core 0.)
1886 + li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE)
1887 + sw t1, GCR_Cx_COHERENCE(t0)
1892 +_next_coherent_core:
1893 + sll t1, t2, GCR_Cx_OTHER_CORENUM_SHIFT
1894 + sw t1, GCR_Cx_OTHER(t0)
1896 +_busy_wait_coherent_core:
1897 + lw t1, GCR_CO_COHERENCE(t0)
1898 + beqz t1, _busy_wait_coherent_core
1901 + bne t2, a0, _next_coherent_core
1904 + END(join_coherent_domain)
1907 + * All VPEs other than VPE0 will go here.
1909 +LEAF(launch_vpe_entry)
1910 + mfc0 t0, CP0_EBASE
1911 + and t0, t0, MIPS_EBASE_CPUNUM
1913 + /* per-VPE cpulaunch_t */
1914 + li a0, KSEG0ADDR(CPULAUNCH)
1915 + sll t1, t0, LOG2CPULAUNCH
1918 + /* Set CPU online flag */
1919 + li t0, LAUNCH_FREADY
1920 + sw t0, LAUNCH_FLAGS(a0)
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
1927 + /* VPEs executing in wait code do not need a stack */
1928 + li t9, KSEG0ADDR(LAUNCH_WAITCODE)
1930 + END(launch_vpe_entry)
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.
1937 +LEAF(launch_wait_code)
1938 + .globl launch_wait_code_start
1939 +launch_wait_code_start:
1944 + /* Poll CPU go flag */
1945 + mtc0 zero, CP0_COUNT
1946 + li t1, LAUNCHPERIOD
1947 + mtc0 t1, CP0_COMPARE
1950 + /* Software wait */
1951 + mfc0 t2, CP0_COUNT
1953 + bltz t2, time_wait
1955 + /* Check the launch flag */
1956 + lw t3, LAUNCH_FLAGS(t0)
1957 + and t3, LAUNCH_FGO
1958 + beqz t3, start_poll
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
1965 + mfc0 t1, CP0_COUNT
1967 + mtc0 t1, CP0_COMPARE
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)
1977 + ori t3, LAUNCH_FGONE
1978 + sw t3, LAUNCH_FLAGS(t0)
1982 + .globl launch_wait_code_end
1983 +launch_wait_code_end:
1984 + END(launch_wait_code)
1987 + * Core1 will go here.
1989 +LEAF(launch_core_entry)
1990 + /* Disable caches */
1991 + bal mips_cache_disable
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
1999 + mtc0 zero, CP0_TAGLO
2000 + mtc0 zero, CP0_TAGLO, 2
2004 + * Initialize the I-cache first,
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 */
2013 + cache_loop t0, t1, a1, FILL
2014 + /* invalidate again - prudent but not strictly necessary */
2016 + cache_loop t0, t1, a1, INDEX_STORE_TAG_I
2020 + * then initialize D-cache.
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) */
2029 +2: LONG_L zero, 0(t0)
2032 + /* clear all tags */
2034 + cache_loop t0, t1, a3, INDEX_STORE_TAG_D
2037 + /* Set Cache Mode */
2038 + mfc0 t0, CP0_CONFIG
2039 + li t1, CONF_CM_CACHABLE_COW
2041 + mtc0 t0, CP0_CONFIG
2043 + /* Join the coherent domain */
2045 + bal join_coherent_domain
2047 + /* Bootup Core0/VPE1 */
2050 + b launch_vpe_entry
2051 + END(launch_core_entry)
2055 + * This subroutine must be executed from VPE0 with VPECONF0[MVP] already set.
2058 + mfc0 t0, CP0_MVPCONF0
2060 + /* a0 = number of TCs - 1 */
2061 + ext a0, t0, MVPCONF0_PTC_SHIFT, 8
2062 + beqz a0, _vpe1_init_done
2064 + /* a1 = number of VPEs - 1 */
2065 + ext a1, t0, MVPCONF0_PVPE_SHIFT, 4
2066 + beqz a1, _vpe1_init_done
2068 + /* a2 = current TC No. */
2071 + /* Enter VPE Configuration State */
2072 + mfc0 t0, CP0_MVPCONTROL
2073 + or t0, MVPCONTROL_VPC
2074 + mtc0 t0, CP0_MVPCONTROL
2078 + /* Set the TC number to be used on MTTR and MFTR instructions */
2079 + mfc0 t0, CP0_VPECONTROL
2081 + mtc0 t0, CP0_VPECONTROL
2084 + /* TC0 is already bound */
2085 + beqz a2, _next_vpe
2087 + /* Halt current TC */
2089 + mttc0 t0, CP0_TCHALT
2092 + /* If there is spare TC, bind it to the last VPE (VPE[a1]) */
2094 + bnez t1, _vpe_bind_tc
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
2104 + /* Bind TC to a VPE */
2105 + mftc0 t0, CP0_TCBIND
2106 + ins t0, t1, TCBIND_CURVPE_SHIFT, 4
2107 + mttc0 t0, CP0_TCBIND
2110 + * Set up CP0_TCSTATUS register:
2111 + * Disable Coprocessor Usable bits
2112 + * Disable MDMX/DSP ASE
2114 + * not dynamically allocatable
2117 + * interrupt exempt
2120 + li t0, TCSTATUS_IXMT
2121 + mttc0 t0, CP0_TCSTATUS
2125 + bnez t1, _done_vpe # No more VPEs
2127 + /* Disable TC multi-threading */
2128 + mftc0 t0, CP0_VPECONTROL
2129 + ins t0, zero, VPECONTROL_TE_SHIFT, 1
2130 + mttc0 t0, CP0_VPECONTROL
2132 + /* Skip following configuration for TC0 */
2133 + beqz a2, _done_vpe
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
2141 + mfc0 t0, CP0_STATUS
2142 + mttc0 t0, CP0_STATUS
2144 + mttc0 zero, CP0_EPC
2145 + mttc0 zero, CP0_CAUSE
2147 + mfc0 t0, CP0_CONFIG
2148 + mttc0 t0, CP0_CONFIG
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.
2156 + mttc0 t0, CP0_TCRESTART
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
2165 + mttc0 zero, CP0_TCHALT
2167 + /* Activate VPE */
2168 + mftc0 t0, CP0_VPECONF0
2169 + ori t0, VPECONF0_VPA
2170 + mttc0 t0, CP0_VPECONF0
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
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
2192 +++ b/arch/mips/mach-mtmips/mt7621/spl/serial.c
2194 +// SPDX-License-Identifier: GPL-2.0
2196 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2198 + * Author: Weijie Gao <weijie.gao@mediatek.com>
2201 +#include <asm/io.h>
2202 +#include "../mt7621.h"
2204 +void mtmips_spl_serial_init(void)
2206 +#ifdef CONFIG_SPL_SERIAL
2207 + void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
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 */
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
2222 +++ b/arch/mips/mach-mtmips/mt7621/spl/spl.c
2224 +// SPDX-License-Identifier: GPL-2.0
2226 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2228 + * Author: Weijie Gao <weijie.gao@mediatek.com>
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"
2246 +DECLARE_GLOBAL_DATA_PTR;
2253 +void set_timer_freq_simple(void)
2255 + u32 div = get_xtal_mhz();
2257 + /* Round down cpu freq */
2258 + gd->arch.timer_freq = rounddown(CONFIG_MT7621_CPU_FREQ, div) * 500000;
2261 +void __noreturn board_init_f(ulong dummy)
2265 +#ifdef CONFIG_SPL_SERIAL
2267 + * mtmips_spl_serial_init() is useful if debug uart is enabled,
2268 + * or DM based serial is not enabled.
2270 + mtmips_spl_serial_init();
2271 + preloader_console_init();
2274 + board_init_r(NULL, 0);
2277 +void board_boot_order(u32 *spl_boot_list)
2279 +#ifdef CONFIG_MT7621_BOOT_FROM_NAND
2280 + spl_boot_list[0] = BOOT_DEVICE_NAND;
2282 + spl_boot_list[0] = BOOT_DEVICE_NOR;
2286 +unsigned long spl_nor_get_uboot_base(void)
2288 + const struct tpl_info *tpli;
2289 + const image_header_t *hdr;
2292 + addr = FLASH_MMAP_BASE + TPL_INFO_OFFSET;
2293 + tpli = (const struct tpl_info *)KSEG1ADDR(addr);
2295 + if (tpli->magic == TPL_INFO_MAGIC) {
2296 + addr = FLASH_MMAP_BASE + tpli->size;
2297 + hdr = (const image_header_t *)KSEG1ADDR(addr);
2299 + if (image_get_magic(hdr) == IH_MAGIC) {
2300 + addr += sizeof(*hdr) + image_get_size(hdr);
2301 + return KSEG1ADDR(addr);
2305 + panic("Unable to locate SPL payload\n");
2309 +uint32_t spl_nand_get_uboot_raw_page(void)
2311 + const struct stage_header *sh = (const struct stage_header *)&_start;
2314 + addr = image_get_header_size() + be32_to_cpu(sh->stage_size);
2315 + addr = ALIGN(addr, SZ_4K);
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
2323 +++ b/arch/mips/mach-mtmips/mt7621/spl/start.S
2325 +/* SPDX-License-Identifier: GPL-2.0 */
2327 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2329 + * Author: Weijie Gao <weijie.gao@mediatek.com>
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"
2344 +#ifndef CONFIG_SYS_INIT_SP_ADDR
2345 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \
2346 + CONFIG_SYS_INIT_SP_OFFSET)
2349 +#define SP_ADDR_TEMP 0xbe10dff0
2351 + .macro init_wr sel
2352 + MTC0 zero, CP0_WATCHLO,\sel
2353 + mtc0 t1, CP0_WATCHHI,\sel
2356 + .macro setup_stack_gd
2358 + PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
2359 + and sp, t1, t0 # force 16 byte alignment
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)
2368 + sp, sp, t2 # reserve space for early malloc
2369 + and sp, sp, t0 # force 16 byte alignment
2377 + PTR_ADDIU t0, PTRSIZE
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
2391 + mtc0 zero, CP0_COUNT
2393 + /* Stage header required by BootROM */
2395 + .word 0 # ep, filled by mkimage
2396 + .word 0 # stage_size, filled by mkimage
2397 + .word 0 # has_stage2
2399 + .word 0 # next_size
2400 + .word 0 # next_offset
2403 + /* Init CP0 Status */
2404 + mfc0 t0, CP0_STATUS
2406 + or t0, ST0_BEV | ST0_ERL
2407 + mtc0 t0, CP0_STATUS
2410 + /* Clear Watch Status bits and disable watch exceptions */
2411 + li t1, 0x7 # Clear I, R and W conditions
2417 + /* Clear WP, IV and SW interrupts */
2418 + mtc0 zero, CP0_CAUSE
2420 + /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
2421 + mtc0 zero, CP0_COMPARE
2423 + /* VPE1 goes to wait code directly */
2424 + mfc0 t0, CP0_TCBIND
2425 + andi t0, TCBIND_CURVPE
2426 + bnez t0, launch_vpe_entry
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
2435 + /* MT7530 reset */
2436 + li t0, KSEG1ADDR(SYSCTL_BASE)
2437 + lw t1, SYSCTL_RSTCTL_REG(t0)
2439 + sw t1, SYSCTL_RSTCTL_REG(t0)
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)
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)
2451 + /* Set CPU clock divider to 1/1 */
2452 + li t0, KSEG1ADDR(RBUS_BASE)
2454 + sw t1, RBUS_DYN_CFG0_REG(t0)
2456 + /* (Re-)initialize the SRAM */
2457 + bal mips_sram_init
2460 + /* Set up temporary stack */
2461 + li sp, SP_ADDR_TEMP
2463 + /* Setup full CPS */
2467 + bal mt7621_cps_init
2470 + /* Prepare for CPU/DDR initialization binary blob */
2471 + bal prepare_stage_bin
2474 + /* Call CPU/DDR initialization binary blob */
2475 + li t9, STAGE_LOAD_ADDR
2479 + /* Switch CPU PLL source */
2480 + li t0, KSEG1ADDR(SYSCTL_BASE)
2481 + lw t1, SYSCTL_CLKCFG0_REG(t0)
2483 + ins t1, t2, CPU_CLK_SEL_S, 2
2484 + sw t1, SYSCTL_CLKCFG0_REG(t0)
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.
2492 + la a0, __text_start
2494 + la a2, __image_copy_end
2497 + ins a0, a3, 29, 3 # convert to KSEG1
2502 + /* Disable caches */
2503 + bal mips_cache_disable
2506 + /* Reset caches */
2507 + bal mips_cache_reset
2510 + /* Disable SRAM */
2511 + li t0, KSEG1ADDR(FE_BASE)
2512 + li t1, FE_PSE_RESET
2513 + sw t1, FE_RST_GLO_REG(t0)
2515 + /* Clear the .bss section */
2516 + la a0, __bss_start
2523 + /* Set up initial stack and global data */
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
2532 +#if defined(CONFIG_DEBUG_UART) && defined(CONFIG_SPL_SERIAL)
2533 + /* Earliest point to set up debug uart */
2534 + bal debug_uart_init
2539 + bal set_timer_freq_simple
2542 + /* Bootup secondary CPUs */
2543 + bal secondary_cpu_init
2546 + move a0, zero # a0 <-- boot_flags = 0
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
2555 +++ b/arch/mips/mach-mtmips/mt7621/sram_init.S
2557 +/* SPDX-License-Identifier: GPL-2.0 */
2559 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2561 + * Author: Weijie Gao <weijie.gao@mediatek.com>
2564 +#include <asm/addrspace.h>
2565 +#include <asm/asm.h>
2566 +#include <asm/regdef.h>
2567 +#include "mt7621.h"
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)
2574 + li t1, (FE_PSE_RAM | FE_PSE_MEM_EN)
2575 + sw t1, FE_RST_GLO_REG(t0)
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
2583 +++ b/arch/mips/mach-mtmips/mt7621/tpl/Makefile
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
2593 +++ b/arch/mips/mach-mtmips/mt7621/tpl/start.S
2595 +/* SPDX-License-Identifier: GPL-2.0 */
2597 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2599 + * Author: Weijie Gao <weijie.gao@mediatek.com>
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"
2611 +#define SP_ADDR_TEMP 0xbe10dff0
2615 + .macro init_wr sel
2616 + MTC0 zero, CP0_WATCHLO,\sel
2617 + mtc0 t1, CP0_WATCHHI,\sel
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
2630 + mtc0 zero, CP0_COUNT
2633 + * Store TPL size here.
2634 + * This will be used by SPL to locate u-boot payload.
2636 + .org TPL_INFO_OFFSET
2637 + .word TPL_INFO_MAGIC
2638 + .word __image_copy_len
2640 + /* Exception vector */
2642 + /* TLB refill, 32 bit task */
2643 + uhi_mips_exception
2646 + /* XTLB refill, 64 bit task */
2647 + uhi_mips_exception
2650 + /* Cache error exception */
2651 + uhi_mips_exception
2654 + /* General exception */
2655 + uhi_mips_exception
2658 + /* Catch interrupt exceptions */
2659 + uhi_mips_exception
2662 + /* EJTAG debug exception */
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
2676 + /* Check for CPU number */
2677 + mfc0 t0, CP0_EBASE
2678 + and t0, t0, MIPS_EBASE_CPUNUM
2682 + /* Secondary core goes to specified SPL entry address */
2683 + li t0, KSEG1ADDR(SYSCTL_BASE)
2684 + lw t0, BOOT_SRAM_BASE_REG(t0)
2688 + /* Init CP0 Status */
2689 +1: mfc0 t0, CP0_STATUS
2691 + or t0, ST0_BEV | ST0_ERL
2692 + mtc0 t0, CP0_STATUS
2695 + /* Clear Watch Status bits and disable watch exceptions */
2696 + li t1, 0x7 # Clear I, R and W conditions
2702 + /* Clear WP, IV and SW interrupts */
2703 + mtc0 zero, CP0_CAUSE
2705 + /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
2706 + mtc0 zero, CP0_COMPARE
2708 + /* Setup basic CPS */
2712 + li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE)
2713 + li t1, GCR_REG0_BASE_VALUE
2714 + sw t1, GCR_REG0_BASE(t0)
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)
2720 + lw t1, GCR_BASE(t0)
2721 + ins t1, zero, 0, 2 # CM_DEFAULT_TARGET
2722 + sw t1, GCR_BASE(t0)
2724 + lw t1, GCR_CONTROL(t0)
2725 + li t2, GCR_CONTROL_SYNCCTL
2727 + sw t1, GCR_CONTROL(t0)
2729 + /* Increase SPI frequency */
2730 + li t0, KSEG1ADDR(SPI_BASE)
2732 + sw t1, SPI_SPACE_REG(t0)
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)
2740 + /* Set CPU clock divider to 1/1 */
2741 + li t0, KSEG1ADDR(RBUS_BASE)
2743 + sw t1, RBUS_DYN_CFG0_REG(t0)
2745 + /* Initialize the SRAM */
2746 + bal mips_sram_init
2749 + /* Set up initial stack */
2750 + li sp, SP_ADDR_TEMP
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
2760 +++ b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c
2762 +// SPDX-License-Identifier: GPL-2.0
2764 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2766 + * Author: Weijie Gao <weijie.gao@mediatek.com>
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>
2776 +#define INDEX_STORE_DATA_SD 0x0f
2778 +typedef void __noreturn (*image_entry_noargs_t)(void);
2781 + * Lock L2 cache and fill data
2782 + * Assume that data is 4-byte aligned and start_addr/size is 32-byte aligned
2784 +static void fill_lock_l2cache(uintptr_t dataptr, ulong start_addr, ulong size)
2786 + ulong slsize = CONFIG_SYS_DCACHE_LINE_SIZE;
2787 + ulong end_addr = start_addr + size;
2788 + const u32 *data = (u32 *)dataptr;
2792 + /* Clear WSC & SPR bit in ErrCtl */
2793 + val = read_c0_ecc();
2794 + val &= 0xcfffffff;
2795 + write_c0_ecc(val);
2796 + execution_hazard_barrier();
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);
2804 + for (i = 0; i < slsize; i += 8) {
2806 + __write_32bit_c0_register($28, 5, val); /* sdtaglo */
2808 + __write_32bit_c0_register($29, 5, val); /* sdtaghi */
2809 + mips_cache(INDEX_STORE_DATA_SD, (void *)(addr + i));
2816 +/* A simple function to initialize MT7621's cache */
2817 +static void mt7621_cache_init(void)
2819 + void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE);
2820 + ulong lsize = CONFIG_SYS_DCACHE_LINE_SIZE;
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);
2830 + /* Initialize L1 I-Cache */
2831 + write_c0_taglo(0);
2832 + write_c0_taghi(0);
2834 + for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += lsize)
2835 + mips_cache(INDEX_STORE_TAG_I, (void *)addr);
2837 + /* Initialize L1 D-Cache */
2838 + write_c0_dtaglo(0);
2839 + __write_32bit_c0_register($29, 2, 0); /* dtaghi */
2841 + for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += lsize)
2842 + mips_cache(INDEX_STORE_TAG_D, (void *)addr);
2844 + /* Initialize L2 Cache */
2845 + write_c0_staglo(0);
2846 + __write_32bit_c0_register($29, 4, 0); /* staghi */
2848 + for (addr = 0; addr < (256 << 10); addr += lsize)
2849 + mips_cache(INDEX_STORE_TAG_SD, (void *)addr);
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);
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();
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);
2867 + /* Invalidate L1 I-Cache */
2868 + for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += lsize)
2869 + mips_cache(INDEX_INVALIDATE_I, (void *)addr);
2871 + /* Disable L2 cache bypass */
2872 + val = read_c0_config2();
2873 + val &= ~MIPS_CONF_IMPL;
2874 + write_c0_config2(val);
2875 + execution_hazard_barrier();
2878 +void __noreturn tpl_main(void)
2880 + const image_header_t *hdr = (const image_header_t *)__image_copy_end;
2881 + image_entry_noargs_t image_entry;
2882 + u32 loadaddr, size;
2885 + /* Initialize the cache first */
2886 + mt7621_cache_init();
2888 + if (image_get_magic(hdr) != IH_MAGIC)
2891 + loadaddr = image_get_load(hdr);
2892 + size = image_get_size(hdr);
2893 + image_entry = (image_entry_noargs_t)image_get_ep(hdr);
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);
2906 diff --git a/include/configs/mt7621.h b/include/configs/mt7621.h
2907 new file mode 100644
2908 index 0000000000..dac6aa4afb
2910 +++ b/include/configs/mt7621.h
2912 +/* SPDX-License-Identifier: GPL-2.0 */
2914 + * Copyright (C) 2022 MediaTek Inc. All rights reserved.
2916 + * Author: Weijie Gao <weijie.gao@mediatek.com>
2919 +#ifndef __CONFIG_MT7621_H
2920 +#define __CONFIG_MT7621_H
2922 +#define CONFIG_SYS_MIPS_TIMER_FREQ 440000000
2924 +#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000
2926 +#define CONFIG_SYS_SDRAM_BASE 0x80000000
2928 +#define CONFIG_VERY_BIG_RAM
2929 +#define CONFIG_MAX_MEM_MAPPED 0x1c000000
2931 +#define CONFIG_SYS_INIT_SP_OFFSET 0x800000
2933 +#define CONFIG_SYS_BOOTM_LEN 0x2000000
2935 +#define CONFIG_SYS_MAXARGS 16
2936 +#define CONFIG_SYS_CBSIZE 1024
2938 +#define CONFIG_SYS_NONCACHED_MEMORY 0x100000
2941 +#define MMC_SUPPORTS_TUNING
2944 +#define CONFIG_SYS_MAX_NAND_DEVICE 1
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
2954 +/* Serial common */
2955 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
2956 + 230400, 460800, 921600 }
2959 +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
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
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
2974 +#define CONFIG_SYS_UBOOT_BASE 0
2976 +#endif /* __CONFIG_MT7621_H */