Message ID | d5509bdb31f518f1a14b86c03b64504fbbf81e07.1652183768.git.weijie.gao@mediatek.com |
---|---|
State | Superseded |
Delegated to: | Daniel Schwierzeck |
Headers | show |
Series | Add support for MediaTek MT7621 SoC | expand |
Hi Weijie, I just commented on the device tree stuff. On 5/10/22 8:18 AM, Weijie Gao wrote: > This patch adds support for MediaTek MT7621 SoC. > All files are dedicated for u-boot. > > The default build target is u-boot-mt7621.bin. > > The specification of this chip: > https://www.mediatek.com/products/homenetworking/mt7621 > > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com> > --- > v4 changes: > Add full support for booting from flash (SPL/TPL support) > Boot all cores/VPEs > Use binman to generate final binary > Use binman to embed external binary blob > v3 changes: > Update clock name for mt7621.dtsi due to clk driver changed > v2 changes: > Add a kconfig for max supported ram size > Remove network configs from default config file > --- > arch/mips/dts/mt7621-u-boot.dtsi | 79 ++++ > arch/mips/dts/mt7621.dtsi | 370 +++++++++++++++++++ > arch/mips/mach-mtmips/Kconfig | 49 ++- > arch/mips/mach-mtmips/Makefile | 4 + > arch/mips/mach-mtmips/cpu.c | 2 +- > arch/mips/mach-mtmips/mt7621/Kconfig | 95 +++++ > arch/mips/mach-mtmips/mt7621/Makefile | 14 + > arch/mips/mach-mtmips/mt7621/init.c | 229 ++++++++++++ > arch/mips/mach-mtmips/mt7621/mt7621.h | 229 ++++++++++++ > arch/mips/mach-mtmips/mt7621/serial.c | 23 ++ > arch/mips/mach-mtmips/mt7621/spl/Makefile | 9 + > arch/mips/mach-mtmips/mt7621/spl/cps.c | 152 ++++++++ > arch/mips/mach-mtmips/mt7621/spl/dram.c | 143 +++++++ > arch/mips/mach-mtmips/mt7621/spl/dram.h | 37 ++ > arch/mips/mach-mtmips/mt7621/spl/launch.c | 100 +++++ > arch/mips/mach-mtmips/mt7621/spl/launch.h | 52 +++ > arch/mips/mach-mtmips/mt7621/spl/launch_ll.S | 357 ++++++++++++++++++ > arch/mips/mach-mtmips/mt7621/spl/serial.c | 24 ++ > arch/mips/mach-mtmips/mt7621/spl/spl.c | 95 +++++ > arch/mips/mach-mtmips/mt7621/spl/start.S | 226 +++++++++++ > arch/mips/mach-mtmips/mt7621/sram_init.S | 22 ++ > arch/mips/mach-mtmips/mt7621/tpl/Makefile | 4 + > arch/mips/mach-mtmips/mt7621/tpl/start.S | 161 ++++++++ > arch/mips/mach-mtmips/mt7621/tpl/tpl.c | 146 ++++++++ > include/configs/mt7621.h | 67 ++++ > 25 files changed, 2683 insertions(+), 6 deletions(-) > create mode 100644 arch/mips/dts/mt7621-u-boot.dtsi > create mode 100644 arch/mips/dts/mt7621.dtsi > create mode 100644 arch/mips/mach-mtmips/mt7621/Kconfig > create mode 100644 arch/mips/mach-mtmips/mt7621/Makefile > create mode 100644 arch/mips/mach-mtmips/mt7621/init.c > create mode 100644 arch/mips/mach-mtmips/mt7621/mt7621.h > create mode 100644 arch/mips/mach-mtmips/mt7621/serial.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/Makefile > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/cps.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/dram.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/dram.h > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch.h > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch_ll.S > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/serial.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/spl.c > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/start.S > create mode 100644 arch/mips/mach-mtmips/mt7621/sram_init.S > create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/Makefile > create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/start.S > create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/tpl.c > create mode 100644 include/configs/mt7621.h > > diff --git a/arch/mips/dts/mt7621-u-boot.dtsi b/arch/mips/dts/mt7621-u-boot.dtsi > new file mode 100644 > index 0000000000..b9b02003a5 > --- /dev/null > +++ b/arch/mips/dts/mt7621-u-boot.dtsi > @@ -0,0 +1,79 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <linux/stringify.h> > + > +/ { > + binman: binman { > + multiple-images; > + }; > +}; > + > +&binman { > + u-boot-spl-ddr { > + align = <4>; > + align-size = <4>; > + filename = "u-boot-spl-ddr.bin"; > + pad-byte = <0xff>; > + > + u-boot-spl { > + align-end = <4>; > + filename = "u-boot-spl.bin"; > + }; > + > + stage_bin { > + filename = "mt7621_stage_sram.bin"; > + type = "blob-ext"; > + }; > + }; > + > + spl-img { > + filename = "u-boot-spl-ddr.img"; > + > + mkimage { > +#ifdef CONFIG_MT7621_BOOT_FROM_NAND > + args = "-T", "mtk_image", "-n", "mt7621=1", > + "-a", __stringify(CONFIG_SPL_TEXT_BASE), > + "-e", __stringify(CONFIG_SPL_TEXT_BASE); > +#else > + args = "-A", "mips", "-T", "standalone", "-O", "u-boot", > + "-C", "none", "-n", "MT7621 U-Boot SPL", > + "-a", __stringify(CONFIG_SPL_TEXT_BASE), > + "-e", __stringify(CONFIG_SPL_TEXT_BASE); > +#endif > + > + blob { > + filename = "u-boot-spl-ddr.bin"; > + }; > + }; > + }; > + > + mt7621-uboot { > + filename = "u-boot-mt7621.bin"; > + pad-byte = <0xff>; > + > +#ifndef CONFIG_MT7621_BOOT_FROM_NAND > + u-boot-tpl { > + align-end = <4>; > + filename = "u-boot-tpl.bin"; > + }; > +#endif > + > + spl { > +#ifdef CONFIG_MT7621_BOOT_FROM_NAND > + align-end = <0x1000>; > +#endif > + filename = "u-boot-spl-ddr.img"; > + type = "blob"; > + }; > + > + u-boot { > + filename = "u-boot-lzma.img"; > + type = "blob"; > + }; > + }; > +}; > diff --git a/arch/mips/dts/mt7621.dtsi b/arch/mips/dts/mt7621.dtsi > new file mode 100644 > index 0000000000..285179e896 > --- /dev/null > +++ b/arch/mips/dts/mt7621.dtsi > @@ -0,0 +1,370 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <dt-bindings/clock/mt7621-clk.h> > +#include <dt-bindings/reset/mt7621-reset.h> > +#include <dt-bindings/phy/phy.h> > + > +/ { > + #address-cells = <1>; > + #size-cells = <1>; > + compatible = "mediatek,mt7621-soc"; > + > + cpus { > + #address-cells = <1>; > + #size-cells = <0>; > + > + cpu@0 { > + device_type = "cpu"; > + compatible = "mips,mips1004Kc"; > + reg = <0>; > + }; > + > + cpu@1 { > + device_type = "cpu"; > + compatible = "mips,mips1004Kc"; > + reg = <0>; reg = <1>; > + }; > + }; > + > + clk48m: clk48m@0 { > + compatible = "fixed-clock"; > + > + clock-frequency = <48000000>; > + > + #clock-cells = <0>; > + }; > + > + clk50m: clk50m@0 { > + compatible = "fixed-clock"; > + > + clock-frequency = <50000000>; > + > + #clock-cells = <0>; > + }; > + > + sysc: sysc@1e000000 { sysc: syscon@1e000000 > + compatible = "mediatek,mt7621-sysc", "syscon"; > + reg = <0x1e000000 0x100>; > + }; As commented under the clock patch, I think it would be better to include the clock controller and reset controller bindings as children of this one. > + clkctrl: clkctrl@1e000030 { clock-controller@1e000030 (or just clock-controller with the above suggestion) > + compatible = "mediatek,mt7621-clk"; > + mediatek,sysc = <&sysc>; > + mediatek,memc = <&memc>; > + > + #clock-cells = <1>; > + u-boot,dm-pre-reloc; > + }; > + > + rstctrl: rstctrl@1e000034 { reset-controller@1e000034 > + compatible = "mediatek,mtmips-reset"; > + reg = <0x1e000034 0x4>; > + #reset-cells = <1>; > + }; > + > + reboot: resetctl-reboot { > + compatible = "resetctl-reboot"; > + > + resets = <&rstctrl RST_SYS>; > + reset-names = "sysreset"; > + }; > + > + memc: memc@1e005000 { > + compatible = "mediatek,mt7621-memc", "syscon"; > + reg = <0x1e005000 0x1000>; > + }; > + > + pinctrl: pinctrl@1e000060 { > + compatible = "mediatek,mt7621-pinctrl"; > + reg = <0x1e000048 0x30>; > + > + pinctrl-names = "default"; > + pinctrl-0 = <&state_default>; > + > + state_default: pin_state { > + uart1 { > + groups = "uart1"; > + function = "uart"; > + }; > + > + gpios { > + groups = "i2c", "uart3", "pcie reset"; > + function = "gpio"; > + }; > + > + jtag { > + groups = "jtag"; > + function = "jtag"; > + }; I think the JTAG is perhaps the only thing which should be in here. Everything else can be changed by boards. > + > + wdt { > + groups = "wdt"; > + function = "wdt rst"; > + }; > + }; > + > + uart1_pins: uart1_pins { > + groups = "uart1"; > + function = "uart"; > + }; > + > + uart2_pins: uart2_pins { > + groups = "uart2"; > + function = "uart"; > + }; > + > + uart3_pins: uart3_pins { > + groups = "uart3"; > + function = "uart"; > + }; > + > + sdxc_pins: sdxc_pins { > + groups = "sdxc"; > + function = "sdxc"; > + }; > + > + spi_pins: spi_pins { > + groups = "spi"; > + function = "spi"; > + }; > + > + eth_pins: eth_pins { > + mdio_pins { > + groups = "mdio"; > + function = "mdio"; > + }; > + > + rgmii1_pins { > + groups = "rgmii1"; > + function = "rgmii"; > + }; > + > + esw_pins { > + groups = "esw int"; > + function = "esw int"; > + }; > + > + mdio_pconf { > + groups = "mdio"; > + drive-strength = <2>; > + }; > + }; > + }; > + > + watchdog: watchdog@1e000100 { > + compatible = "mediatek,mt7621-wdt"; > + reg = <0x1e000100 0x40>; > + > + resets = <&rstctrl RST_TIMER>; > + reset-names = "wdt"; > + > + status = "disabled"; > + }; > + > + gpio: gpio@1e000600 { > + #address-cells = <1>; > + #size-cells = <0>; > + > + compatible = "mtk,mt7621-gpio"; > + reg = <0x1e000600 0x100>; > + > + resets = <&rstctrl RST_PIO>; > + reset-names = "pio"; > + > + gpio0: bank@0 { > + reg = <0>; > + compatible = "mtk,mt7621-gpio-bank"; > + gpio-controller; > + #gpio-cells = <2>; > + }; > + > + gpio1: bank@1 { > + reg = <1>; > + compatible = "mtk,mt7621-gpio-bank"; > + gpio-controller; > + #gpio-cells = <2>; > + }; > + > + gpio2: bank@2 { > + reg = <2>; > + compatible = "mtk,mt7621-gpio-bank"; > + gpio-controller; > + #gpio-cells = <2>; > + }; > + }; > + > + spi: spi@1e000b00 { > + compatible = "ralink,mt7621-spi"; > + reg = <0x1e000b00 0x40>; > + > + status = "disabled"; > + > + pinctrl-names = "default"; > + pinctrl-0 = <&spi_pins>; > + > + resets = <&rstctrl RST_SPI>; > + reset-names = "spi"; > + > + clocks = <&clkctrl MT7621_CLK_SPI>; > + > + #address-cells = <1>; > + #size-cells = <0>; > + }; > + > + uart0: uart1@1e000c00 { > + compatible = "mediatek,hsuart", "ns16550a"; > + reg = <0x1e000c00 0x100>; > + > + pinctrl-names = "default"; > + pinctrl-0 = <&uart1_pins>; > + > + clocks = <&clkctrl MT7621_CLK_UART1>; > + > + resets = <&rstctrl RST_UART1>; > + > + reg-shift = <2>; > + }; > + > + uart1: uart2@1e000d00 { > + compatible = "mediatek,hsuart", "ns16550a"; > + reg = <0x1e000d00 0x100>; > + > + pinctrl-names = "default"; > + pinctrl-0 = <&uart2_pins>; > + > + clocks = <&clkctrl MT7621_CLK_UART2>; > + > + resets = <&rstctrl RST_UART2>; > + > + reg-shift = <2>; > + > + status = "disabled"; > + }; > + > + uart2: uart3@1e000e00 { > + compatible = "mediatek,hsuart", "ns16550a"; > + reg = <0x1e000e00 0x100>; > + > + pinctrl-names = "default"; > + pinctrl-0 = <&uart3_pins>; > + > + clocks = <&clkctrl MT7621_CLK_UART3>; > + > + resets = <&rstctrl RST_UART3>; > + > + reg-shift = <2>; > + > + status = "disabled"; > + }; > + > + eth: eth@1e100000 { > + compatible = "mediatek,mt7621-eth"; > + reg = <0x1e100000 0x20000>; > + mediatek,ethsys = <&sysc>; > + > + pinctrl-names = "default"; > + pinctrl-0 = <ð_pins>; > + > + resets = <&rstctrl RST_FE>, <&rstctrl RST_GMAC>, <&rstctrl RST_MCM>; > + reset-names = "fe", "gmac", "mcm"; > + > + clocks = <&clkctrl MT7621_CLK_GDMA>, > + <&clkctrl MT7621_CLK_ETH>; > + clock-names = "gmac", "fe"; > + > + #address-cells = <1>; > + #size-cells = <0>; > + > + mediatek,gmac-id = <0>; > + phy-mode = "rgmii"; > + mediatek,switch = "mt7530"; > + mediatek,mcm; > + > + fixed-link { > + speed = <1000>; > + full-duplex; > + }; Should this be under the board? The only time this should be in the SoC dts s if there is an internal connection to another MAC on the SoC itself. > + }; > + > + mmc: mmc@1e130000 { > + compatible = "mediatek,mt7621-mmc"; > + reg = <0x1e130000 0x4000>; > + > + status = "disabled"; > + > + bus-width = <4>; > + builtin-cd = <1>; > + r_smpl = <1>; > + > + pinctrl-names = "default"; > + pinctrl-0 = <&sdxc_pins>; This should be in the board dts. > + > + clocks = <&clk50m>, <&clkctrl MT7621_CLK_SHXC>; > + clock-names = "source", "hclk"; > + > + resets = <&rstctrl RST_SDXC>; > + }; > + > + ssusb: usb@1e1c0000 { > + compatible = "mediatek,mt7621-xhci", "mediatek,mtk-xhci"; > + reg = <0x1e1c0000 0x1000>, <0x1e1d0700 0x100>; > + reg-names = "mac", "ippc"; > + > + clocks = <&clk48m>, <&clk48m>; > + clock-names = "sys_ck", "ref_ck"; > + > + phys = <&u2port0 PHY_TYPE_USB2>, > + <&u3port0 PHY_TYPE_USB3>, > + <&u2port1 PHY_TYPE_USB2>; > + > + status = "disabled"; > + }; > + > + u3phy: usb-phy@1e1d0000 { > + compatible = "mediatek,mt7621-u3phy", > + "mediatek,generic-tphy-v1"; > + reg = <0x1e1d0000 0x700>; > + #address-cells = <1>; > + #size-cells = <1>; > + ranges; > + status = "disabled"; > + > + u2port0: usb-phy@1e1d0800 { > + reg = <0x1e1d0800 0x0100>; > + #phy-cells = <1>; > + clocks = <&clk48m>; > + clock-names = "ref"; > + }; > + > + u3port0: usb-phy@1e1d0900 { > + reg = <0x1e1d0900 0x0100>; > + #phy-cells = <1>; > + }; > + > + u2port1: usb-phy@1e1d1000 { > + reg = <0x1e1d1000 0x0100>; > + #phy-cells = <1>; > + clocks = <&clk48m>; > + clock-names = "ref"; > + }; > + }; > + > + i2c: i2c@1e000900 { > + compatible = "i2c-gpio"; > + > + status = "disabled"; > + > + i2c-gpio,delay-us = <3>; > + > + gpios = <&gpio0 3 1>, /* PIN3 as SDA */ > + <&gpio0 4 1>; /* PIN4 as CLK */ > + > + #address-cells = <1>; > + #size-cells = <0>; > + }; This should be on the board dts. > +}; > diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig > index 151b004603..d46be503a2 100644 > --- a/arch/mips/mach-mtmips/Kconfig > +++ b/arch/mips/mach-mtmips/Kconfig > @@ -9,6 +9,7 @@ config SYS_MALLOC_F_LEN > > config SYS_SOC > default "mt7620" if SOC_MT7620 > + default "mt7621" if SOC_MT7621 > default "mt7628" if SOC_MT7628 > > config SYS_DCACHE_SIZE > @@ -18,25 +19,45 @@ config SYS_DCACHE_LINE_SIZE > default 32 > > config SYS_ICACHE_SIZE > - default 65536 > + default 65536 if SOC_MT7620 || SOC_MT7628 > + default 32768 if SOC_MT7621 > > config SYS_ICACHE_LINE_SIZE > default 32 > > +config SYS_SCACHE_LINE_SIZE > + default 32 if SOC_MT7621 > + > config SYS_TEXT_BASE > - default 0x9c000000 if !SPL > - default 0x80200000 if SPL > + default 0x9c000000 if !SPL && !SOC_MT7621 > + default 0x80200000 if SPL || SOC_MT7621 > > config SPL_TEXT_BASE > - default 0x9c000000 > + default 0x9c000000 if !SOC_MT7621 > + default 0x80100000 if SOC_MT7621 > + > +config SPL_SIZE_LIMIT > + default 0x30000 if SOC_MT7621 > + > +config TPL_TEXT_BASE > + default 0xbfc00000 if SOC_MT7621 > + > +config TPL_MAX_SIZE > + default 4096 if SOC_MT7621 > > config SPL_PAYLOAD > default "u-boot-lzma.img" if SPL_LZMA > > config BUILD_TARGET > - default "u-boot-with-spl.bin" if SPL > + default "u-boot-with-spl.bin" if SPL && !SOC_MT7621 > + default "u-boot-lzma.img" if SOC_MT7621 > default "u-boot.bin" > > +config MAX_MEM_SIZE > + int > + default 256 if SOC_MT7620 || SOC_MT7628 > + default 512 if SOC_MT7621 > + > choice > prompt "MediaTek MIPS SoC select" > > @@ -55,6 +76,23 @@ config SOC_MT7620 > help > This supports MediaTek MT7620. > > +config SOC_MT7621 > + bool "MT7621" > + select MIPS_CM > + select MIPS_L2_CACHE > + select SYS_CACHE_SHIFT_5 > + select SYS_MIPS_CACHE_INIT_RAM_LOAD > + select PINCTRL_MT7621 > + select MTK_SERIAL > + select REGMAP > + select SYSCON > + select BINMAN > + select SUPPORT_TPL > + select SPL_LOADER_SUPPORT if SPL > + select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL > + help > + This supports MediaTek MT7621. > + > config SOC_MT7628 > bool "MT7628" > select SYS_CACHE_SHIFT_5 > @@ -80,6 +118,7 @@ config SOC_MT7628 > endchoice > > source "arch/mips/mach-mtmips/mt7620/Kconfig" > +source "arch/mips/mach-mtmips/mt7621/Kconfig" > source "arch/mips/mach-mtmips/mt7628/Kconfig" > > endmenu > diff --git a/arch/mips/mach-mtmips/Makefile b/arch/mips/mach-mtmips/Makefile > index 4909b47ef2..19f1e07033 100644 > --- a/arch/mips/mach-mtmips/Makefile > +++ b/arch/mips/mach-mtmips/Makefile > @@ -1,9 +1,13 @@ > # SPDX-License-Identifier: GPL-2.0+ > > obj-y += cpu.o > + > +ifneq ($(CONFIG_SOC_MT7621),y) > obj-y += ddr_init.o > obj-y += ddr_cal.o > obj-$(CONFIG_SPL_BUILD) += spl.o > +endif > > obj-$(CONFIG_SOC_MT7620) += mt7620/ > +obj-$(CONFIG_SOC_MT7621) += mt7621/ > obj-$(CONFIG_SOC_MT7628) += mt7628/ > diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach-mtmips/cpu.c > index a4b5cff61d..f1e9022738 100644 > --- a/arch/mips/mach-mtmips/cpu.c > +++ b/arch/mips/mach-mtmips/cpu.c > @@ -16,7 +16,7 @@ DECLARE_GLOBAL_DATA_PTR; > > int dram_init(void) > { > - gd->ram_size = get_ram_size((void *)KSEG1, SZ_256M); > + gd->ram_size = get_ram_size((void *)KSEG1, CONFIG_MAX_MEM_SIZE << 20); > > return 0; > } > diff --git a/arch/mips/mach-mtmips/mt7621/Kconfig b/arch/mips/mach-mtmips/mt7621/Kconfig > new file mode 100644 > index 0000000000..37d512c68f > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/Kconfig > @@ -0,0 +1,95 @@ > + > +if SOC_MT7621 > + > +menu "CPU & DDR configuration" > + > +config MT7621_CPU_FREQ > + int "CPU Frequency (MHz)" > + range 400 1200 > + default 880 > + > +choice > + prompt "DRAM Frequency" > + default MT7621_DRAM_FREQ_1200 > + > +config MT7621_DRAM_FREQ_400 > + bool "400MHz" > + > +config MT7621_DRAM_FREQ_800 > + bool "800MHz" > + > +config MT7621_DRAM_FREQ_1066 > + bool "1066MHz" > + > +config MT7621_DRAM_FREQ_1200 > + bool "1200MHz" > + > +endchoice > + > +choice > + prompt "DDR2 timing parameters" > + default MT7621_DRAM_DDR2_1024M > + > +config MT7621_DRAM_DDR2_512M > + bool "64MB" > + > +config MT7621_DRAM_DDR2_1024M > + bool "128MB" > + > +config MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ > + bool "W9751G6KB_A02 @ 1066MHz (64MB)" > + > +config MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ > + bool "W971GG6KB25 @ 800MHz (128MB)" > + > +config MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ > + bool "W971GG6KB18 @ 1066MHz (128MB)" > + > +endchoice > + > +choice > + prompt "DDR3 timing parameters" > + default MT7621_DRAM_DDR3_2048M > + > +config MT7621_DRAM_DDR3_1024M > + bool "128MB" > + > +config MT7621_DRAM_DDR3_1024M_KGD > + bool "128MB KGD (MT7621DA)" > + > +config MT7621_DRAM_DDR3_2048M > + bool "256MB" > + > +config MT7621_DRAM_DDR3_4096M > + bool "512MB" > + > +endchoice > + > +endmenu > + > +config DEBUG_UART_BOARD_INIT > + default y > + > +config MT7621_BOOT_FROM_NAND > + bool "Boot from NAND" > + help > + Select this if u-boot will boot from NAND flash. When booting from > + NAND, SPL will be loaded by bootrom directly and no TPL is needed. > + > +choice > + prompt "Board select" > + > +endchoice > + > +config SYS_CONFIG_NAME > + string "Board configuration name" > + default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB > + > +config SYS_BOARD > + string "Board name" > + default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB > + > +config SYS_VENDOR > + default "mediatek" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB > + > +endif > diff --git a/arch/mips/mach-mtmips/mt7621/Makefile b/arch/mips/mach-mtmips/mt7621/Makefile > new file mode 100644 > index 0000000000..bf1b0bb688 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/Makefile > @@ -0,0 +1,14 @@ > +# SPDX-License-Identifier: GPL-2.0 > + > +obj-y += init.o > +obj-y += serial.o > + > +ifeq ($(CONFIG_SPL_BUILD),y) > +ifeq ($(CONFIG_TPL_BUILD),y) > +obj-y += tpl/ > +else > +obj-y += spl/ > +endif > + > +obj-y += sram_init.o > +endif > diff --git a/arch/mips/mach-mtmips/mt7621/init.c b/arch/mips/mach-mtmips/mt7621/init.c > new file mode 100644 > index 0000000000..ec63712bc1 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/init.c > @@ -0,0 +1,229 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <clk.h> > +#include <dm.h> > +#include <dm/uclass.h> > +#include <dt-bindings/clock/mt7621-clk.h> > +#include <asm/global_data.h> > +#include <linux/io.h> > +#include "mt7621.h" > + > +DECLARE_GLOBAL_DATA_PTR; > + > +static const char *const boot_mode[(CHIP_MODE_M >> CHIP_MODE_S) + 1] = { > + [1] = "NAND 2K+64", > + [2] = "SPI-NOR 3-Byte Addr", > + [3] = "SPI-NOR 4-Byte Addr", > + [10] = "NAND 2K+128", > + [11] = "NAND 4K+128", > + [12] = "NAND 4K+256", > +}; > + > +int print_cpuinfo(void) > +{ > + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); > + u32 val, ver, eco, pkg, core, dram, chipmode; > + u32 cpu_clk, ddr_clk, bus_clk, xtal_clk; > + struct udevice *clkdev; > + const char *bootdev; > + struct clk clk; > + int ret; > + > + val = readl(sysc + SYSCTL_CHIP_REV_ID_REG); > + ver = (val & VER_ID_M) >> VER_ID_S; > + eco = (val & ECO_ID_M) >> ECO_ID_S; > + pkg = !!(val & PKG_ID); > + core = !!(val & CPU_ID); > + > + val = readl(sysc + SYSCTL_SYSCFG0_REG); > + dram = val & DRAM_TYPE; > + chipmode = (val & CHIP_MODE_M) >> CHIP_MODE_S; > + > + bootdev = boot_mode[chipmode]; > + if (!bootdev) > + bootdev = "Unsupported boot mode"; > + > + printf("CPU: MediaTek MT7621%c ver %u, eco %u\n", > + core ? (pkg ? 'A' : 'N') : 'S', ver, eco); > + > + printf("Boot: DDR%u, %s\n", dram ? 2 : 3, bootdev); > + > + ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(mt7621_clk), > + &clkdev); > + if (ret) > + return ret; > + > + clk.dev = clkdev; > + > + clk.id = MT7621_CLK_CPU; > + cpu_clk = clk_get_rate(&clk); > + > + clk.id = MT7621_CLK_BUS; > + bus_clk = clk_get_rate(&clk); > + > + clk.id = MT7621_CLK_DDR; > + ddr_clk = clk_get_rate(&clk); > + > + clk.id = MT7621_CLK_XTAL; > + xtal_clk = clk_get_rate(&clk); > + > + /* Set final timer frequency */ > + if (cpu_clk) > + gd->arch.timer_freq = cpu_clk / 2; > + > + printf("Clock: CPU: %uMHz, DDR: %uMT/s, Bus: %uMHz, XTAL: %uMHz\n", > + cpu_clk / 1000000, ddr_clk / 500000, bus_clk / 1000000, > + xtal_clk / 1000000); > + > + return 0; > +} > + > +unsigned long get_xtal_mhz(void) > +{ > + void __iomem *sysc = (void *)KSEG1ADDR(SYSCTL_BASE); > + u32 bs, xtal_sel; > + > + bs = readl(sysc + SYSCTL_SYSCFG0_REG); > + xtal_sel = (bs & XTAL_MODE_SEL_M) >> XTAL_MODE_SEL_S; > + > + if (xtal_sel <= 2) > + return 20; > + else if (xtal_sel <= 5) > + return 40; > + else > + return 25; > +} > + > +static void xhci_config_40mhz(void __iomem *usbh) > +{ > + writel((0x20 << SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S) | > + (0x20 << SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S) | > + (2 << SSUSB_MAC3_SYS_CK_GATE_MODE_S) | > + (2 << SSUSB_MAC2_SYS_CK_GATE_MODE_S) | 0x10, > + usbh + SSUSB_MAC_CK_CTRL_REG); > + > + writel((2 << SSUSB_PLL_PREDIV_PE1D_S) | (1 << SSUSB_PLL_PREDIV_U3_S) | > + (4 << SSUSB_PLL_FBKDI_S), usbh + DA_SSUSB_U3PHYA_10_REG); > + > + writel((0x18 << SSUSB_PLL_FBKDIV_PE2H_S) | > + (0x18 << SSUSB_PLL_FBKDIV_PE1D_S) | > + (0x18 << SSUSB_PLL_FBKDIV_PE1H_S) | > + (0x1e << SSUSB_PLL_FBKDIV_U3_S), > + usbh + DA_SSUSB_PLL_FBKDIV_REG); > + > + writel((0x1e400000 << SSUSB_PLL_PCW_NCPO_U3_S), > + usbh + DA_SSUSB_PLL_PCW_NCPO_REG); > + > + writel((0x25 << SSUSB_PLL_SSC_DELTA1_PE1H_S) | > + (0x73 << SSUSB_PLL_SSC_DELTA1_U3_S), > + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG); > + > + writel((0x71 << SSUSB_PLL_SSC_DELTA_U3_S) | > + (0x4a << SSUSB_PLL_SSC_DELTA1_PE2D_S), > + usbh + DA_SSUSB_U3PHYA_21_REG); > + > + writel((0x140 << SSUSB_PLL_SSC_PRD_S), usbh + SSUSB_U3PHYA_9_REG); > + > + writel((0x11c00000 << SSUSB_SYSPLL_PCW_NCPO_S), > + usbh + SSUSB_U3PHYA_3_REG); > + > + writel((4 << SSUSB_PCIE_CLKDRV_AMP_S) | (1 << SSUSB_SYSPLL_FBSEL_S) | > + (1 << SSUSB_SYSPLL_PREDIV_S), usbh + SSUSB_U3PHYA_1_REG); > + > + writel((0x12 << SSUSB_SYSPLL_FBDIV_S) | SSUSB_SYSPLL_VCO_DIV_SEL | > + SSUSB_SYSPLL_FPEN | SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN, > + usbh + SSUSB_U3PHYA_2_REG); > + > + writel(SSUSB_EQ_CURSEL | (8 << SSUSB_RX_DAC_MUX_S) | > + (1 << SSUSB_PCIE_SIGDET_VTH_S) | (1 << SSUSB_PCIE_SIGDET_LPF_S), > + usbh + SSUSB_U3PHYA_11_REG); > + > + writel((0x1ff << SSUSB_RING_OSC_CNTEND_S) | > + (0x7f << SSUSB_XTAL_OSC_CNTEND_S) | SSUSB_RING_BYPASS_DET, > + usbh + SSUSB_B2_ROSC_0_REG); > + > + writel((3 << SSUSB_RING_OSC_FRC_RECAL_S) | SSUSB_RING_OSC_FRC_SEL, > + usbh + SSUSB_B2_ROSC_1_REG); > +} > + > +static void xhci_config_25mhz(void __iomem *usbh) > +{ > + writel((0x20 << SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S) | > + (0x20 << SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S) | > + (2 << SSUSB_MAC3_SYS_CK_GATE_MODE_S) | > + (2 << SSUSB_MAC2_SYS_CK_GATE_MODE_S) | 0x10, > + usbh + SSUSB_MAC_CK_CTRL_REG); > + > + writel((2 << SSUSB_PLL_PREDIV_PE1D_S) | (4 << SSUSB_PLL_FBKDI_S), > + usbh + DA_SSUSB_U3PHYA_10_REG); > + > + writel((0x18 << SSUSB_PLL_FBKDIV_PE2H_S) | > + (0x18 << SSUSB_PLL_FBKDIV_PE1D_S) | > + (0x18 << SSUSB_PLL_FBKDIV_PE1H_S) | > + (0x19 << SSUSB_PLL_FBKDIV_U3_S), > + usbh + DA_SSUSB_PLL_FBKDIV_REG); > + > + writel((0x18000000 << SSUSB_PLL_PCW_NCPO_U3_S), > + usbh + DA_SSUSB_PLL_PCW_NCPO_REG); > + > + writel((0x25 << SSUSB_PLL_SSC_DELTA1_PE1H_S) | > + (0x4a << SSUSB_PLL_SSC_DELTA1_U3_S), > + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG); > + > + writel((0x48 << SSUSB_PLL_SSC_DELTA_U3_S) | > + (0x4a << SSUSB_PLL_SSC_DELTA1_PE2D_S), > + usbh + DA_SSUSB_U3PHYA_21_REG); > + > + writel((0x190 << SSUSB_PLL_SSC_PRD_S), usbh + SSUSB_U3PHYA_9_REG); > + > + writel((0xe000000 << SSUSB_SYSPLL_PCW_NCPO_S), > + usbh + SSUSB_U3PHYA_3_REG); > + > + writel((4 << SSUSB_PCIE_CLKDRV_AMP_S) | (1 << SSUSB_SYSPLL_FBSEL_S), > + usbh + SSUSB_U3PHYA_1_REG); > + > + writel((0xf << SSUSB_SYSPLL_FBDIV_S) | SSUSB_SYSPLL_VCO_DIV_SEL | > + SSUSB_SYSPLL_FPEN | SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN, > + usbh + SSUSB_U3PHYA_2_REG); > + > + writel(SSUSB_EQ_CURSEL | (8 << SSUSB_RX_DAC_MUX_S) | > + (1 << SSUSB_PCIE_SIGDET_VTH_S) | (1 << SSUSB_PCIE_SIGDET_LPF_S), > + usbh + SSUSB_U3PHYA_11_REG); > + > + writel((0x1ff << SSUSB_RING_OSC_CNTEND_S) | > + (0x7f << SSUSB_XTAL_OSC_CNTEND_S) | SSUSB_RING_BYPASS_DET, > + usbh + SSUSB_B2_ROSC_0_REG); > + > + writel((3 << SSUSB_RING_OSC_FRC_RECAL_S) | SSUSB_RING_OSC_FRC_SEL, > + usbh + SSUSB_B2_ROSC_1_REG); > +} > + > +void lowlevel_init(void) > +{ > + void __iomem *usbh = ioremap_nocache(SSUSB_BASE, SSUSB_SIZE); > + u32 xtal = get_xtal_mhz(); > + > + /* Setup USB xHCI */ > + if (xtal == 40) > + xhci_config_40mhz(usbh); > + else if (xtal == 25) > + xhci_config_25mhz(usbh); > +} > + > +ulong notrace get_tbclk(void) > +{ > + return gd->arch.timer_freq; > +} > + > +void _machine_restart(void) > +{ > + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); > + > + while (1) > + writel(SYS_RST, sysc + SYSCTL_RSTCTL_REG); > +} > diff --git a/arch/mips/mach-mtmips/mt7621/mt7621.h b/arch/mips/mach-mtmips/mt7621/mt7621.h > new file mode 100644 > index 0000000000..916cc993b4 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/mt7621.h > @@ -0,0 +1,229 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#ifndef _MT7621_H_ > +#define _MT7621_H_ > + > +#define SYSCTL_BASE 0x1e000000 > +#define SYSCTL_SIZE 0x100 > +#define TIMER_BASE 0x1e000100 > +#define TIMER_SIZE 0x100 > +#define RBUS_BASE 0x1e000400 > +#define RBUS_SIZE 0x100 > +#define GPIO_BASE 0x1e000600 > +#define GPIO_SIZE 0x100 > +#define DMA_CFG_ARB_BASE 0x1e000800 > +#define DMA_CFG_ARB_SIZE 0x100 > +#define SPI_BASE 0x1e000b00 > +#define SPI_SIZE 0x100 > +#define UART1_BASE 0x1e000c00 > +#define UART1_SIZE 0x100 > +#define UART2_BASE 0x1e000d00 > +#define UART2_SIZE 0x100 > +#define UART3_BASE 0x1e000e00 > +#define UART3_SIZE 0x100 > +#define NFI_BASE 0x1e003000 > +#define NFI_SIZE 0x800 > +#define NFI_ECC_BASE 0x1e003800 > +#define NFI_ECC_SIZE 0x800 > +#define DRAMC_BASE 0x1e005000 > +#define DRAMC_SIZE 0x1000 > +#define FE_BASE 0x1e100000 > +#define FE_SIZE 0xe000 > +#define GMAC_BASE 0x1e110000 > +#define GMAC_SIZE 0x8000 > +#define SSUSB_BASE 0x1e1c0000 > +#define SSUSB_SIZE 0x40000 > + > + /* GIC Base Address */ > +#define MIPS_GIC_BASE 0x1fbc0000 > + > + /* CPC Base Address */ > +#define MIPS_CPC_BASE 0x1fbf0000 > + > + /* Flash Memory-mapped Base Address */ > +#define FLASH_MMAP_BASE 0x1fc00000 > +#define TPL_INFO_OFFSET 0x40 > +#define TPL_INFO_MAGIC 0x31323637 /* Magic "7621" */ > + > +/* SRAM */ > +#define FE_SRAM_BASE1 0x8000 > +#define FE_SRAM_BASE2 0xa000 > + > +/* SYSCTL_BASE */ > +#define SYSCTL_CHIP_REV_ID_REG 0x0c > +#define CPU_ID 0x20000 > +#define PKG_ID 0x10000 > +#define VER_ID_S 8 > +#define VER_ID_M 0xf00 > +#define ECO_ID_S 0 > +#define ECO_ID_M 0x0f > + > +#define SYSCTL_SYSCFG0_REG 0x10 > +#define XTAL_MODE_SEL_S 6 > +#define XTAL_MODE_SEL_M 0x1c0 > +#define DRAM_TYPE 0x10 > +#define CHIP_MODE_S 0 > +#define CHIP_MODE_M 0x0f > + > +#define BOOT_SRAM_BASE_REG 0x20 > + > +#define SYSCTL_CLKCFG0_REG 0x2c > +#define CPU_CLK_SEL_S 30 > +#define CPU_CLK_SEL_M 0xc0000000 > +#define MPLL_CFG_SEL_S 23 > +#define MPLL_CFG_SEL_M 0x800000 > + > +#define SYSCTL_RSTCTL_REG 0x34 > +#define MCM_RST 0x04 > +#define SYS_RST 0x01 > + > +#define SYSCTL_CUR_CLK_STS_REG 0x44 > +#define CUR_CPU_FDIV_S 8 > +#define CUR_CPU_FDIV_M 0x1f00 > +#define CUR_CPU_FFRAC_S 0 > +#define CUR_CPU_FFRAC_M 0x1f > + > +#define SYSCTL_GPIOMODE_REG 0x60 > +#define UART2_MODE_S 5 > +#define UART2_MODE_M 0x60 > +#define UART3_MODE_S 3 > +#define UART3_MODE_M 0x18 > +#define UART1_MODE 0x02 > + > +/* RBUS_BASE */ > +#define RBUS_DYN_CFG0_REG 0x0010 > +#define CPU_FDIV_S 8 > +#define CPU_FDIV_M 0x1f00 > +#define CPU_FFRAC_S 0 > +#define CPU_FFRAC_M 0x1f > + > +/* DMA_CFG_ARB_BASE */ > +#define DMA_ROUTE_REG 0x000c > + > +/* SPI_BASE */ > +#define SPI_SPACE_REG 0x003c > +#define FS_SLAVE_SEL_S 12 > +#define FS_SLAVE_SEL_M 0x70000 > +#define FS_CLK_SEL_S 0 > +#define FS_CLK_SEL_M 0xfff > + > +/* FE_BASE */ > +#define FE_RST_GLO_REG 0x0004 > +#define FE_PSE_RAM 0x04 > +#define FE_PSE_MEM_EN 0x02 > +#define FE_PSE_RESET 0x01 > + > +/* SSUSB_BASE */ > +#define SSUSB_MAC_CK_CTRL_REG 0x10784 > +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S 16 > +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M 0xff0000 > +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S 8 > +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M 0xff00 > +#define SSUSB_MAC3_SYS_CK_GATE_MODE_S 2 > +#define SSUSB_MAC3_SYS_CK_GATE_MODE_M 0x0c > +#define SSUSB_MAC2_SYS_CK_GATE_MODE_S 0 > +#define SSUSB_MAC2_SYS_CK_GATE_MODE_M 0x03 > + > +#define SSUSB_B2_ROSC_0_REG 0x10a40 > +#define SSUSB_RING_OSC_CNTEND_S 23 > +#define SSUSB_RING_OSC_CNTEND_M 0xff800000 > +#define SSUSB_XTAL_OSC_CNTEND_S 16 > +#define SSUSB_XTAL_OSC_CNTEND_M 0x7f0000 > +#define SSUSB_RING_BYPASS_DET 0x01 > + > +#define SSUSB_B2_ROSC_1_REG 0x10a44 > +#define SSUSB_RING_OSC_FRC_RECAL_S 17 > +#define SSUSB_RING_OSC_FRC_RECAL_M 0x60000 > +#define SSUSB_RING_OSC_FRC_SEL 0x01 > + > +#define SSUSB_U3PHYA_1_REG 0x10b04 > +#define SSUSB_PCIE_CLKDRV_AMP_S 27 > +#define SSUSB_PCIE_CLKDRV_AMP_M 0x38000000 > +#define SSUSB_SYSPLL_FBSEL_S 2 > +#define SSUSB_SYSPLL_FBSEL_M 0x0c > +#define SSUSB_SYSPLL_PREDIV_S 0 > +#define SSUSB_SYSPLL_PREDIV_M 0x03 > + > +#define SSUSB_U3PHYA_2_REG 0x10b08 > +#define SSUSB_SYSPLL_FBDIV_S 24 > +#define SSUSB_SYSPLL_FBDIV_M 0x7f000000 > +#define SSUSB_SYSPLL_VCO_DIV_SEL 0x200000 > +#define SSUSB_SYSPLL_FPEN 0x2000 > +#define SSUSB_SYSPLL_MONCK_EN 0x1000 > +#define SSUSB_SYSPLL_VOD_EN 0x200 > + > +#define SSUSB_U3PHYA_3_REG 0x10b10 > +#define SSUSB_SYSPLL_PCW_NCPO_S 1 > +#define SSUSB_SYSPLL_PCW_NCPO_M 0xfffffffe > + > +#define SSUSB_U3PHYA_9_REG 0x10b24 > +#define SSUSB_PLL_SSC_PRD_S 0 > +#define SSUSB_PLL_SSC_PRD_M 0xffff > + > +#define SSUSB_U3PHYA_11_REG 0x10b2c > +#define SSUSB_EQ_CURSEL 0x1000000 > +#define SSUSB_RX_DAC_MUX_S 19 > +#define SSUSB_RX_DAC_MUX_M 0xf80000 > +#define SSUSB_PCIE_SIGDET_VTH_S 5 > +#define SSUSB_PCIE_SIGDET_VTH_M 0x60 > +#define SSUSB_PCIE_SIGDET_LPF_S 3 > +#define SSUSB_PCIE_SIGDET_LPF_M 0x18 > + > +#define DA_SSUSB_PLL_FBKDIV_REG 0x10c1c > +#define SSUSB_PLL_FBKDIV_PE2H_S 24 > +#define SSUSB_PLL_FBKDIV_PE2H_M 0x7f000000 > +#define SSUSB_PLL_FBKDIV_PE1D_S 16 > +#define SSUSB_PLL_FBKDIV_PE1D_M 0x7f0000 > +#define SSUSB_PLL_FBKDIV_PE1H_S 8 > +#define SSUSB_PLL_FBKDIV_PE1H_M 0x7f00 > +#define SSUSB_PLL_FBKDIV_U3_S 0 > +#define SSUSB_PLL_FBKDIV_U3_M 0x7f > + > +#define DA_SSUSB_U3PHYA_10_REG 0x10c20 > +#define SSUSB_PLL_PREDIV_PE1D_S 18 > +#define SSUSB_PLL_PREDIV_PE1D_M 0xc0000 > +#define SSUSB_PLL_PREDIV_U3_S 8 > +#define SSUSB_PLL_PREDIV_U3_M 0x300 > +#define SSUSB_PLL_FBKDI_S 0 > +#define SSUSB_PLL_FBKDI_M 0x07 > + > +#define DA_SSUSB_PLL_PCW_NCPO_REG 0x10c24 > +#define SSUSB_PLL_PCW_NCPO_U3_S 0 > +#define SSUSB_PLL_PCW_NCPO_U3_M 0x7fffffff > + > +#define DA_SSUSB_PLL_SSC_DELTA1_REG 0x10c38 > +#define SSUSB_PLL_SSC_DELTA1_PE1H_S 16 > +#define SSUSB_PLL_SSC_DELTA1_PE1H_M 0xffff0000 > +#define SSUSB_PLL_SSC_DELTA1_U3_S 0 > +#define SSUSB_PLL_SSC_DELTA1_U3_M 0xffff > + > +#define DA_SSUSB_U3PHYA_21_REG 0x10c40 > +#define SSUSB_PLL_SSC_DELTA_U3_S 16 > +#define SSUSB_PLL_SSC_DELTA_U3_M 0xffff0000 > +#define SSUSB_PLL_SSC_DELTA1_PE2D_S 0 > +#define SSUSB_PLL_SSC_DELTA1_PE2D_M 0xffff > + > +/* MT7621 specific CM values */ > + > +/* GCR_REGx_BASE */ > +#define GCR_REG0_BASE_VALUE 0x1c000000 > +#define GCR_REG1_BASE_VALUE 0x60000000 > +#define GCR_REG2_BASE_VALUE 0x1c000000 > +#define GCR_REG3_BASE_VALUE 0x1c000000 > + > +/* GCR_REGx_MASK */ > +#define GCR_REG0_MASK_VALUE 0x0000fc00 /* 64M Bus */ > +#define GCR_REG1_MASK_VALUE 0x0000f000 /* 256M PCI Mem */ > +#define GCR_REG2_MASK_VALUE 0x0000fc00 /* unused */ > +#define GCR_REG3_MASK_VALUE 0x0000fc00 /* unused */ > + > +#ifndef __ASSEMBLY__ > +unsigned long get_xtal_mhz(void); > +#endif > + > +#endif /* _MT7621_H_ */ > diff --git a/arch/mips/mach-mtmips/mt7621/serial.c b/arch/mips/mach-mtmips/mt7621/serial.c > new file mode 100644 > index 0000000000..0ccc71dc75 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/serial.c > @@ -0,0 +1,23 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <asm/io.h> > +#include <asm/addrspace.h> > +#include "mt7621.h" > + > +void board_debug_uart_init(void) > +{ > + void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); > + > +#if CONFIG_DEBUG_UART_BASE == 0xbe000c00 /* KSEG1ADDR(UART1_BASE) */ > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE); > +#elif CONFIG_DEBUG_UART_BASE == 0xbe000d00 /* KSEG1ADDR(UART2_BASE) */ > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M); > +#elif CONFIG_DEBUG_UART_BASE == 0xbe000e00 /* KSEG1ADDR(UART3_BASE) */ > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M); > +#endif > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/Makefile b/arch/mips/mach-mtmips/mt7621/spl/Makefile > new file mode 100644 > index 0000000000..ebe54e79b9 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/Makefile > @@ -0,0 +1,9 @@ > + > +extra-y += start.o > + > +obj-y += spl.o > +obj-y += cps.o > +obj-y += dram.o > +obj-y += serial.o > +obj-y += launch.o > +obj-y += launch_ll.o > diff --git a/arch/mips/mach-mtmips/mt7621/spl/cps.c b/arch/mips/mach-mtmips/mt7621/spl/cps.c > new file mode 100644 > index 0000000000..61f319f45f > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/cps.c > @@ -0,0 +1,152 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <asm/io.h> > +#include <asm/addrspace.h> > +#include <asm/mipsregs.h> > +#include <asm/cm.h> > +#include "../mt7621.h" > + > +/* GIC Shared Register Bases */ > +#define GIC_SH_POL_BASE 0x100 > +#define GIC_SH_TRIG_BASE 0x180 > +#define GIC_SH_RMASK_BASE 0x300 > +#define GIC_SH_SMASK_BASE 0x380 > +#define GIC_SH_MASK_BASE 0x400 > +#define GIC_SH_PEND_BASE 0x480 > +#define GIC_SH_MAP_PIN_BASE 0x500 > +#define GIC_SH_MAP_VPE_BASE 0x2000 > + > +/* GIC Registers */ > +#define GIC_SH_POL31_0 (GIC_SH_POL_BASE + 0x00) > +#define GIC_SH_POL63_32 (GIC_SH_POL_BASE + 0x04) > + > +#define GIC_SH_TRIG31_0 (GIC_SH_TRIG_BASE + 0x00) > +#define GIC_SH_TRIG63_32 (GIC_SH_TRIG_BASE + 0x04) > + > +#define GIC_SH_RMASK31_0 (GIC_SH_RMASK_BASE + 0x00) > +#define GIC_SH_RMASK63_32 (GIC_SH_RMASK_BASE + 0x04) > + > +#define GIC_SH_SMASK31_0 (GIC_SH_SMASK_BASE + 0x00) > +#define GIC_SH_SMASK63_32 (GIC_SH_SMASK_BASE + 0x04) > + > +#define GIC_SH_MAP_PIN(n) (GIC_SH_MAP_PIN_BASE + (n) * 4) > + > +#define GIC_SH_MAP_VPE(n, v) (GIC_SH_MAP_VPE_BASE + (n) * 0x20 + ((v) / 32) * 4) > +#define GIC_SH_MAP_VPE31_0(n) GIC_SH_MAP_VPE(n, 0) > + > +/* GIC_SH_MAP_PIN fields */ > +#define GIC_MAP_TO_PIN BIT(31) > +#define GIC_MAP_TO_NMI BIT(30) > +#define GIC_MAP GENMASK(5, 0) > +#define GIC_MAP_SHIFT 0 > + > +static void cm_init(void __iomem *cm_base) > +{ > + u32 num_cores; > + > + num_cores = ((readl(cm_base + GCR_CONFIG) & GCR_CONFIG_PCORES) >> > + GCR_CONFIG_PCORES_SHIFT) + 1; > + > + writel((1 << num_cores) - 1, cm_base + GCR_ACCESS); > + > + writel(GCR_REG0_BASE_VALUE, cm_base + GCR_REG0_BASE); > + writel(GCR_REG1_BASE_VALUE, cm_base + GCR_REG1_BASE); > + writel(GCR_REG2_BASE_VALUE, cm_base + GCR_REG2_BASE); > + writel(GCR_REG3_BASE_VALUE, cm_base + GCR_REG3_BASE); > + > + clrsetbits_32(cm_base + GCR_REG0_MASK, > + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, > + (GCR_REG0_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | > + GCR_REGn_MASK_CMTGT_IOCU0); > + > + clrsetbits_32(cm_base + GCR_REG1_MASK, > + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, > + (GCR_REG1_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | > + GCR_REGn_MASK_CMTGT_IOCU0); > + > + clrsetbits_32(cm_base + GCR_REG2_MASK, > + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, > + (GCR_REG2_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | > + GCR_REGn_MASK_CMTGT_IOCU0); > + > + clrsetbits_32(cm_base + GCR_REG3_MASK, > + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, > + (GCR_REG3_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | > + GCR_REGn_MASK_CMTGT_IOCU0); > + > + clrbits_32(cm_base + GCR_BASE, CM_DEFAULT_TARGET_MASK); > + setbits_32(cm_base + GCR_CONTROL, GCR_CONTROL_SYNCCTL); > +} > + > +static void gic_init(void) > +{ > + void __iomem *gic_base = (void *)KSEG1ADDR(MIPS_GIC_BASE); > + int i; > + > + /* Interrupt 0..5: Level Trigger, Active High */ > + writel(0, gic_base + GIC_SH_TRIG31_0); > + writel(0x3f, gic_base + GIC_SH_RMASK31_0); > + writel(0x3f, gic_base + GIC_SH_POL31_0); > + writel(0x3f, gic_base + GIC_SH_SMASK31_0); > + > + /* Interrupt 56..63: Edge Trigger, Rising Edge */ > + /* Hardcoded to set up the last 8 external interrupts for IPI. */ > + writel(0xff000000, gic_base + GIC_SH_TRIG63_32); > + writel(0xff000000, gic_base + GIC_SH_RMASK63_32); > + writel(0xff000000, gic_base + GIC_SH_POL63_32); > + writel(0xff000000, gic_base + GIC_SH_SMASK63_32); > + > + /* Map interrupt source to particular hardware interrupt pin */ > + /* source {0,1,2,3,4,5} -> pin {0,0,4,3,0,5} */ > + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(0)); > + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(1)); > + writel(GIC_MAP_TO_PIN | 4, gic_base + GIC_SH_MAP_PIN(2)); > + writel(GIC_MAP_TO_PIN | 3, gic_base + GIC_SH_MAP_PIN(3)); > + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(4)); > + writel(GIC_MAP_TO_PIN | 5, gic_base + GIC_SH_MAP_PIN(5)); > + > + /* source 56~59 -> pin 1, 60~63 -> pin 2 */ > + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(56)); > + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(57)); > + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(58)); > + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(59)); > + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(60)); > + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(61)); > + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(62)); > + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(63)); > + > + /* Interrupt map to VPE (bit mask) */ > + for (i = 0; i < 32; i++) > + writel(BIT(0), gic_base + GIC_SH_MAP_VPE31_0(i)); > + > + /* > + * Direct GIC_int 56..63 to vpe 0..3 > + * MIPS Linux convention that last 16 interrupts implemented be set > + * aside for IPI signaling. > + * The actual interrupts are tied low and software sends interrupts > + * via GIC_SH_WEDGE writes. > + */ > + for (i = 0; i < 4; i++) { > + writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + 56)); > + writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + 60)); > + } > +} > + > +void mt7621_cps_init(void) > +{ > + void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE); > + > + /* Enable GIC */ > + writel(MIPS_GIC_BASE | GCR_GIC_EN, cm_base + GCR_GIC_BASE); > + > + /* Enable CPC */ > + writel(MIPS_CPC_BASE | GCR_CPC_EN, cm_base + GCR_CPC_BASE); > + > + gic_init(); > + cm_init(cm_base); > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/dram.c b/arch/mips/mach-mtmips/mt7621/spl/dram.c > new file mode 100644 > index 0000000000..6c3b501ae5 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.c > @@ -0,0 +1,143 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <asm/io.h> > +#include <asm/sections.h> > +#include <asm/byteorder.h> > +#include <asm/addrspace.h> > +#include <linux/string.h> > +#include "../mt7621.h" > +#include "dram.h" > + > +static const u32 ddr2_act[24] = { > +#if defined(CONFIG_MT7621_DRAM_DDR2_512M) > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174441, > + 0x00000000, 0xF0748661, 0x40001273, 0x9F0A0481, > + 0x0304692F, 0x15602842, 0x00008888, 0x88888888, > + 0x00000000, 0x00000000, 0x00000000, 0x07100000, > + 0x00001B63, 0x00002000, 0x00004000, 0x00006000, > + 0x00000000, 0x00000000, 0x00000000, 0x00000000, > +#elif defined(CONFIG_MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ) > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x33484584, > + 0x00000000, 0xF07486A1, 0x50001273, 0x9F010481, > + 0x0304693F, 0x15602842, 0x00008888, 0x88888888, > + 0x00000000, 0x00000000, 0x00000010, 0x07100000, > + 0x00001F73, 0x00002000, 0x00004000, 0x00006000, > + 0x00000000, 0x00000000, 0x00000000, 0x00000000, > +#elif defined(CONFIG_MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ) > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174430, > + 0x01000000, 0xF0748661, 0x40001273, 0x9F0F0481, > + 0x0304692F, 0x15602842, 0x00008888, 0x88888888, > + 0x00000000, 0x00000000, 0x00000000, 0x07100000, > + 0x00001B63, 0x00002000, 0x00004000, 0x00006000, > + 0x00000000, 0x00000000, 0x00000000, 0x00000000, > +#elif defined(CONFIG_MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ) > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x33484584, > + 0x01000000, 0xF07486A1, 0x50001273, 0x9F070481, > + 0x0304693F, 0x15602842, 0x00008888, 0x88888888, > + 0x00000000, 0x00000000, 0x00000010, 0x07100000, > + 0x00001F73, 0x00002000, 0x00004000, 0x00006000, > + 0x00000000, 0x00000000, 0x00000000, 0x00000000, > +#else /* CONFIG_MT7621_DRAM_DDR2_1024M */ > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174441, > + 0x01000000, 0xF0748661, 0x40001273, 0x9F0F0481, > + 0x0304692F, 0x15602842, 0x00008888, 0x88888888, > + 0x00000000, 0x00000000, 0x00000000, 0x07100000, > + 0x00001B63, 0x00002000, 0x00004000, 0x00006000, > + 0x00000000, 0x00000000, 0x00000000, 0x00000000, > +#endif > +}; > + > +static const u32 ddr3_act[24] = { > +#if defined(CONFIG_MT7621_DRAM_DDR3_1024M) > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694683, > + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F060481, > + 0x03046948, 0x15602842, 0x00008888, 0x88888888, > + 0x00000000, 0x00000000, 0x00000210, 0x07100000, > + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, > + 0x0C000000, 0x07070000, 0x00000000, 0x00000000, > +#elif defined(CONFIG_MT7621_DRAM_DDR3_4096M) > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694683, > + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F0F0481, > + 0x03046948, 0x15602842, 0x00008888, 0x88888888, > + 0x00000000, 0x00000000, 0x00000240, 0x07100000, > + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, > + 0x0C000000, 0x07070000, 0x00000000, 0x00000000, > +#elif defined(CONFIG_MT7621_DRAM_DDR3_1024M_KGD) > + 0xFF00FF00, 0xFF00FF00, 0x00000007, 0x44694683, > + 0x01000000, 0xF07406A1, 0xC287221D, 0x9F060481, > + 0x03046923, 0x152f2842, 0x00008888, 0x88888888, > + 0x00000000, 0x00000000, 0x00000210, 0x07100000, > + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, > + 0x0C000000, 0x07070000, 0x000C0000, 0x00000000, > +#else /* CONFIG_MT7621_DRAM_DDR3_2048M */ > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694673, > + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F050481, > + 0x03046948, 0x15602842, 0x00008888, 0x88888888, > + 0x00000000, 0x00000000, 0x00000220, 0x07100000, > + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, > + 0x0C000000, 0x07070000, 0x00000000, 0x00000000, > +#endif > +}; > + > +#if defined(CONFIG_MT7621_DRAM_FREQ_400) > +#define DDR_FREQ_PARAM 0x41000000 > +#elif defined(CONFIG_MT7621_DRAM_FREQ_1066) > +#define DDR_FREQ_PARAM 0x21000000 > +#elif defined(CONFIG_MT7621_DRAM_FREQ_1200) > +#define DDR_FREQ_PARAM 0x11000000 > +#else /* CONFIG_MT7621_DRAM_FREQ_800 */ > +#define DDR_FREQ_PARAM 0x31000000 > +#endif > + > +#define RG_MEPL_FBDIV_S 4 > +#define RG_MEPL_FBDIV_M 0x7f > + > +static u32 calc_cpu_pll_val(void) > +{ > + u32 div, baseval, fb; > + > + div = get_xtal_mhz(); > + > + if (div == 40) { > + div /= 2; > + baseval = 0xc0005802; > + } else { > + baseval = 0xc0004802; > + } > + > + fb = CONFIG_MT7621_CPU_FREQ / div - 1; > + if (fb > RG_MEPL_FBDIV_M) > + fb = RG_MEPL_FBDIV_M; > + > + return baseval | (fb << RG_MEPL_FBDIV_S); > +} > + > +void prepare_stage_bin(void) > +{ > + const struct stage_header *stock_stage_bin = > + (const struct stage_header *)__image_copy_end; > + > + struct stage_header *new_stage_bin = > + (struct stage_header *)STAGE_LOAD_ADDR; > + > + if (be32_to_cpu(stock_stage_bin->ep) != STAGE_LOAD_ADDR) { > + /* Possible wrong binary blob. Hang here */ > + for (;;) > + ; > + } > + > + memcpy(new_stage_bin, stock_stage_bin, > + be32_to_cpu(stock_stage_bin->stage_size)); > + > + memcpy(new_stage_bin->ddr2_act, ddr2_act, sizeof(ddr2_act)); > + memcpy(new_stage_bin->ddr3_act, ddr3_act, sizeof(ddr3_act)); > + > + new_stage_bin->cpu_pll_cfg = calc_cpu_pll_val(); > + new_stage_bin->ddr_pll_cfg = DDR_FREQ_PARAM; > + new_stage_bin->baudrate = CONFIG_BAUDRATE; > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/dram.h b/arch/mips/mach-mtmips/mt7621/spl/dram.h > new file mode 100644 > index 0000000000..4ca66644ef > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.h > @@ -0,0 +1,37 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#ifndef _MT7621_DRAM_H_ > +#define _MT7621_DRAM_H_ > + > +#define STAGE_LOAD_ADDR 0xBE108800 > + > +#ifndef __ASSEMBLY__ > +#include <linux/types.h> > + > +struct stage_header { > + u32 jump_insn[2]; > + u32 ep; > + u32 stage_size; > + u32 has_stage2; > + u32 next_ep; > + u32 next_size; > + u32 next_offset; > + u32 cpu_pll_cfg; > + u32 ddr_pll_cfg; > + u32 reserved2[6]; > + char build_tag[32]; > + u32 ddr3_act[24]; > + u32 padding1[2]; > + u32 ddr2_act[24]; > + u32 padding2[2]; > + u32 baudrate; > + u32 padding3; > +}; > +#endif > + > +#endif /* _MT7621_DRAM_H_ */ > diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch.c b/arch/mips/mach-mtmips/mt7621/spl/launch.c > new file mode 100644 > index 0000000000..37c20a5f56 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.c > @@ -0,0 +1,100 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <asm/io.h> > +#include <asm/cm.h> > +#include <asm/sections.h> > +#include <asm/addrspace.h> > +#include <asm/mipsmtregs.h> > +#include <linux/sizes.h> > +#include <time.h> > +#include <cpu_func.h> > +#include "launch.h" > +#include "../mt7621.h" > + > +/* Cluster Power Controller (CPC) offsets */ > +#define CPC_CL_OTHER 0x2010 > +#define CPC_CO_CMD 0x4000 > + > +/* CPC_CL_OTHER fields */ > +#define CPC_CL_OTHER_CORENUM_SHIFT 16 > +#define CPC_CL_OTHER_CORENUM GENMASK(23, 16) > + > +/* CPC_CO_CMD */ > +#define PWR_UP 3 > + > +#define NUM_CORES 2 > +#define NUM_CPUS 4 > +#define WAIT_CPUS_TIMEOUT 4000 > + > +static void copy_launch_wait_code(void) > +{ > + memset((void *)KSEG1, 0, SZ_4K); > + > + memcpy((void *)KSEG1ADDR(LAUNCH_WAITCODE), > + &launch_wait_code_start, > + &launch_wait_code_end - &launch_wait_code_start); > + > + invalidate_dcache_range(KSEG0, SZ_4K); > +} > + > +static void bootup_secondary_core(void) > +{ > + void __iomem *cpcbase = (void __iomem *)KSEG1ADDR(MIPS_CPC_BASE); > + int i; > + > + for (i = 1; i < NUM_CORES; i++) { > + writel(i << CPC_CL_OTHER_CORENUM_SHIFT, cpcbase + CPC_CL_OTHER); > + writel(PWR_UP, cpcbase + CPC_CO_CMD); > + } > +} > + > +void secondary_cpu_init(void) > +{ > + void __iomem *sysc = (void __iomem *)KSEG1ADDR(SYSCTL_BASE); > + u32 i, dual_core = 0, cpuready = 1, cpumask = 0x03; > + ulong wait_tick; > + struct cpulaunch_t *c; > + > + /* Copy LAUNCH wait code used by other VPEs */ > + copy_launch_wait_code(); > + > + dual_core = readl(sysc + SYSCTL_CHIP_REV_ID_REG) & CPU_ID; > + > + if (dual_core) { > + /* Bootup secondary core for MT7621A */ > + cpumask = 0x0f; > + > + /* Make BootROM/TPL redirect Core1's bootup flow to our entry point */ > + writel((uintptr_t)&_start, sysc + BOOT_SRAM_BASE_REG); > + > + bootup_secondary_core(); > + } > + > + /* Join the coherent domain */ > + join_coherent_domain(dual_core ? 2 : 1); > + > + /* Bootup Core0/VPE1 */ > + boot_vpe1(); > + > + /* Wait for all CPU ready */ > + wait_tick = get_timer(0) + WAIT_CPUS_TIMEOUT; > + > + while (time_before(get_timer(0), wait_tick)) { > + /* CPU0 is obviously ready */ > + for (i = 1; i < NUM_CPUS; i++) { > + c = (struct cpulaunch_t *)(KSEG0ADDR(CPULAUNCH) + > + (i << LOG2CPULAUNCH)); > + > + if (c->flags & LAUNCH_FREADY) > + cpuready |= BIT(i); > + } > + > + if ((cpuready & cpumask) == cpumask) > + break; > + } > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch.h b/arch/mips/mach-mtmips/mt7621/spl/launch.h > new file mode 100644 > index 0000000000..f34250d605 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.h > @@ -0,0 +1,52 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#ifndef _LAUNCH_H_ > +#define _LAUNCH_H_ > + > +#ifndef __ASSEMBLY__ > + > +struct cpulaunch_t { > + unsigned long pc; > + unsigned long gp; > + unsigned long sp; > + unsigned long a0; > + unsigned long _pad[3]; /* pad to cache line size to avoid thrashing */ > + unsigned long flags; > +}; > + > +extern char launch_wait_code_start; > +extern char launch_wait_code_end; > + > +void join_coherent_domain(int ncores); > +void boot_vpe1(void); > + > +#else > + > +#define LAUNCH_PC 0 > +#define LAUNCH_GP 4 > +#define LAUNCH_SP 8 > +#define LAUNCH_A0 12 > +#define LAUNCH_FLAGS 28 > + > +#endif > + > +#define LOG2CPULAUNCH 5 > + > +#define LAUNCH_FREADY 1 > +#define LAUNCH_FGO 2 > +#define LAUNCH_FGONE 4 > + > +#define LAUNCH_WAITCODE 0x00000d00 > +#define SCRLAUNCH 0x00000e00 > +#define CPULAUNCH 0x00000f00 > +#define NCPULAUNCH 8 > + > +/* Polling period in count cycles for secondary CPU's */ > +#define LAUNCHPERIOD 10000 > + > +#endif /* _LAUNCH_H_ */ > diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S > new file mode 100644 > index 0000000000..55a8fff9af > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S > @@ -0,0 +1,357 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <asm/cm.h> > +#include <asm/asm.h> > +#include <asm/regdef.h> > +#include <asm/cacheops.h> > +#include <asm/mipsregs.h> > +#include <asm/addrspace.h> > +#include <asm/mipsmtregs.h> > +#include "launch.h" > + > + .macro cache_loop curr, end, line_sz, op > +10: cache \op, 0(\curr) > + PTR_ADDU \curr, \curr, \line_sz > + bne \curr, \end, 10b > + .endm > + > + .set mt > + > +/* > + * Join the coherent domain > + * a0 = number of cores > + */ > +LEAF(join_coherent_domain) > + /* > + * Enable coherence and allow interventions from all other cores. > + * (Write access enabled via GCR_ACCESS by core 0.) > + */ > + li t1, 1 > + sll t1, a0 > + addiu t1, -1 > + > + li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE) > + sw t1, GCR_Cx_COHERENCE(t0) > + ehb > + > + move t2, zero > + > +_next_coherent_core: > + sll t1, t2, GCR_Cx_OTHER_CORENUM_SHIFT > + sw t1, GCR_Cx_OTHER(t0) > + > +_busy_wait_coherent_core: > + lw t1, GCR_CO_COHERENCE(t0) > + beqz t1, _busy_wait_coherent_core > + nop > + > + addiu t2, 1 > + bne t2, a0, _next_coherent_core > + nop > + > + jr ra > + nop > + END(join_coherent_domain) > + > +/* > + * All VPEs other than VPE0 will go here. > + */ > +LEAF(launch_vpe_entry) > + mfc0 t0, CP0_EBASE > + and t0, t0, MIPS_EBASE_CPUNUM > + > + /* per-VPE cpulaunch_t */ > + li a0, KSEG0ADDR(CPULAUNCH) > + sll t1, t0, LOG2CPULAUNCH > + addu a0, t1 > + > + /* Set CPU online flag */ > + li t0, LAUNCH_FREADY > + sw t0, LAUNCH_FLAGS(a0) > + > + /* Enable count interrupt in mask, but do not enable interrupts */ > + mfc0 t0, CP0_STATUS > + ori t0, STATUSF_IP7 > + mtc0 t0, CP0_STATUS > + > + /* VPEs executing in wait code do not need a stack */ > + li t9, KSEG0ADDR(LAUNCH_WAITCODE) > + jr t9 > + nop > + END(launch_vpe_entry) > + > +/* > + * This function will not be executed in place. > + * It will be copied into memory, and VPEs other than VPE0 will be > + * started to run into this in-memory function. > + */ > +LEAF(launch_wait_code) > + .globl launch_wait_code_start > +launch_wait_code_start: > + > + move t0, a0 > + > +start_poll: > + /* Poll CPU go flag */ > + mtc0 zero, CP0_COUNT > + li t1, LAUNCHPERIOD > + mtc0 t1, CP0_COMPARE > + > +time_wait: > + /* Software wait */ > + mfc0 t2, CP0_COUNT > + subu t2, t1 > + bltz t2, time_wait > + nop > + > + /* Check the launch flag */ > + lw t3, LAUNCH_FLAGS(t0) > + and t3, LAUNCH_FGO > + beqz t3, start_poll > + nop > + > + /* Reset the counter and interrupts to give naive clients a chance */ > + mfc0 t1, CP0_STATUS > + ins t1, zero, STATUSB_IP7, 1 > + mtc0 t1, CP0_STATUS > + > + mfc0 t1, CP0_COUNT > + subu t1, 1 > + mtc0 t1, CP0_COMPARE > + > + /* Jump to kernel */ > + lw t9, LAUNCH_PC(t0) > + lw gp, LAUNCH_GP(t0) > + lw sp, LAUNCH_SP(t0) > + lw a0, LAUNCH_A0(t0) > + move a1, zero > + move a2, zero > + move a3, zero > + ori t3, LAUNCH_FGONE > + sw t3, LAUNCH_FLAGS(t0) > + > + jr t9 > + nop > + > + .globl launch_wait_code_end > +launch_wait_code_end: > + END(launch_wait_code) > + > +/* > + * Core1 will go here. > + */ > +LEAF(launch_core_entry) > + /* Disable caches */ > + bal mips_cache_disable > + nop > + > + /* Initialize L1 cache only */ > + li a0, CONFIG_SYS_ICACHE_SIZE > + li a1, CONFIG_SYS_ICACHE_LINE_SIZE > + li a2, CONFIG_SYS_DCACHE_SIZE > + li a3, CONFIG_SYS_DCACHE_LINE_SIZE > + > + mtc0 zero, CP0_TAGLO > + mtc0 zero, CP0_TAGLO, 2 > + ehb > + > + /* > + * Initialize the I-cache first, > + */ > + li t0, KSEG0 > + addu t1, t0, a0 > + /* clear tag to invalidate */ > + cache_loop t0, t1, a1, INDEX_STORE_TAG_I > +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD > + /* fill once, so data field parity is correct */ > + PTR_LI t0, KSEG0 > + cache_loop t0, t1, a1, FILL > + /* invalidate again - prudent but not strictly necessary */ > + PTR_LI t0, KSEG0 > + cache_loop t0, t1, a1, INDEX_STORE_TAG_I > +#endif > + > + /* > + * then initialize D-cache. > + */ > + PTR_LI t0, KSEG0 > + PTR_ADDU t1, t0, a2 > + /* clear all tags */ > + cache_loop t0, t1, a3, INDEX_STORE_TAG_D > +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD > + /* load from each line (in cached space) */ > + PTR_LI t0, KSEG0 > +2: LONG_L zero, 0(t0) > + PTR_ADDU t0, a3 > + bne t0, t1, 2b > + /* clear all tags */ > + PTR_LI t0, KSEG0 > + cache_loop t0, t1, a3, INDEX_STORE_TAG_D > +#endif > + > + /* Set Cache Mode */ > + mfc0 t0, CP0_CONFIG > + li t1, CONF_CM_CACHABLE_COW > + ins t0, t1, 0, 3 > + mtc0 t0, CP0_CONFIG > + > + /* Join the coherent domain */ > + li a0, 2 > + bal join_coherent_domain > + nop > + > + /* Bootup Core0/VPE1 */ > + bal boot_vpe1 > + nop > + > + b launch_vpe_entry > + nop > + END(launch_core_entry) > + > +/* > + * Bootup VPE1. > + * This subroutine must be executed from VPE0 with VPECONF0[MVP] already set. > + */ > +LEAF(boot_vpe1) > + mfc0 t0, CP0_MVPCONF0 > + > + /* a0 = number of TCs - 1 */ > + ext a0, t0, MVPCONF0_PTC_SHIFT, 8 > + beqz a0, _vpe1_init_done > + nop > + > + /* a1 = number of VPEs - 1 */ > + ext a1, t0, MVPCONF0_PVPE_SHIFT, 4 > + beqz a1, _vpe1_init_done > + nop > + > + /* a2 = current TC No. */ > + move a2, zero > + > + /* Enter VPE Configuration State */ > + mfc0 t0, CP0_MVPCONTROL > + or t0, MVPCONTROL_VPC > + mtc0 t0, CP0_MVPCONTROL > + ehb > + > +_next_tc: > + /* Set the TC number to be used on MTTR and MFTR instructions */ > + mfc0 t0, CP0_VPECONTROL > + ins t0, a2, 0, 8 > + mtc0 t0, CP0_VPECONTROL > + ehb > + > + /* TC0 is already bound */ > + beqz a2, _next_vpe > + nop > + > + /* Halt current TC */ > + li t0, TCHALT_H > + mttc0 t0, CP0_TCHALT > + ehb > + > + /* If there is spare TC, bind it to the last VPE (VPE[a1]) */ > + slt t1, a1, a2 > + bnez t1, _vpe_bind_tc > + move t1, a1 > + > + /* Set Exclusive TC for active TC */ > + mftc0 t0, CP0_VPECONF0 > + ins t0, a2, VPECONF0_XTC_SHIFT, 8 > + mttc0 t0, CP0_VPECONF0 > + > + move t1, a2 > +_vpe_bind_tc: > + /* Bind TC to a VPE */ > + mftc0 t0, CP0_TCBIND > + ins t0, t1, TCBIND_CURVPE_SHIFT, 4 > + mttc0 t0, CP0_TCBIND > + > + /* > + * Set up CP0_TCSTATUS register: > + * Disable Coprocessor Usable bits > + * Disable MDMX/DSP ASE > + * Clear Dirty TC > + * not dynamically allocatable > + * not allocated > + * Kernel mode > + * interrupt exempt > + * ASID 0 > + */ > + li t0, TCSTATUS_IXMT > + mttc0 t0, CP0_TCSTATUS > + > +_next_vpe: > + slt t1, a1, a2 > + bnez t1, _done_vpe # No more VPEs > + nop > + > + /* Disable TC multi-threading */ > + mftc0 t0, CP0_VPECONTROL > + ins t0, zero, VPECONTROL_TE_SHIFT, 1 > + mttc0 t0, CP0_VPECONTROL > + > + /* Skip following configuration for TC0 */ > + beqz a2, _done_vpe > + nop > + > + /* Deactivate VPE, set Master VPE */ > + mftc0 t0, CP0_VPECONF0 > + ins t0, zero, VPECONF0_VPA_SHIFT, 1 > + or t0, VPECONF0_MVP > + mttc0 t0, CP0_VPECONF0 > + > + mfc0 t0, CP0_STATUS > + mttc0 t0, CP0_STATUS > + > + mttc0 zero, CP0_EPC > + mttc0 zero, CP0_CAUSE > + > + mfc0 t0, CP0_CONFIG > + mttc0 t0, CP0_CONFIG > + > + /* > + * VPE1 of each core can execute cached as its L1 I$ has already > + * been initialized. > + * and the L2$ has been initialized or "disabled" via CCA override. > + */ > + PTR_LA t0, _start > + mttc0 t0, CP0_TCRESTART > + > + /* Unset Interrupt Exempt, set Activate Thread */ > + mftc0 t0, CP0_TCSTATUS > + ins t0, zero, TCSTATUS_IXMT_SHIFT, 1 > + ori t0, TCSTATUS_A > + mttc0 t0, CP0_TCSTATUS > + > + /* Resume TC */ > + mttc0 zero, CP0_TCHALT > + > + /* Activate VPE */ > + mftc0 t0, CP0_VPECONF0 > + ori t0, VPECONF0_VPA > + mttc0 t0, CP0_VPECONF0 > + > +_done_vpe: > + addu a2, 1 > + sltu t0, a0, a2 > + beqz t0, _next_tc > + nop > + > + mfc0 t0, CP0_MVPCONTROL > + /* Enable all activated VPE to execute */ > + ori t0, MVPCONTROL_EVP > + /* Exit VPE Configuration State */ > + ins t0, zero, MVPCONTROL_VPC_SHIFT, 1 > + mtc0 t0, CP0_MVPCONTROL > + ehb > + > +_vpe1_init_done: > + jr ra > + nop > + END(boot_vpe1) > diff --git a/arch/mips/mach-mtmips/mt7621/spl/serial.c b/arch/mips/mach-mtmips/mt7621/spl/serial.c > new file mode 100644 > index 0000000000..5cf093a078 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/serial.c > @@ -0,0 +1,24 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <asm/io.h> > +#include "../mt7621.h" > + > +void mtmips_spl_serial_init(void) > +{ > +#ifdef CONFIG_SPL_SERIAL > + void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); > + > +#if CONFIG_CONS_INDEX == 1 > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE); > +#elif CONFIG_CONS_INDEX == 2 > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M); > +#elif CONFIG_CONS_INDEX == 3 > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M); > +#endif /* CONFIG_CONS_INDEX */ > +#endif /* CONFIG_SPL_SERIAL */ > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/spl.c b/arch/mips/mach-mtmips/mt7621/spl/spl.c > new file mode 100644 > index 0000000000..71d01aa7f5 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/spl.c > @@ -0,0 +1,95 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <spl.h> > +#include <init.h> > +#include <image.h> > +#include <vsprintf.h> > +#include <malloc.h> > +#include <asm/io.h> > +#include <asm/sections.h> > +#include <asm/addrspace.h> > +#include <asm/byteorder.h> > +#include <asm/global_data.h> > +#include <linux/sizes.h> > +#include <mach/serial.h> > +#include "../mt7621.h" > +#include "dram.h" > + > +DECLARE_GLOBAL_DATA_PTR; > + > +struct tpl_info { > + u32 magic; > + u32 size; > +}; > + > +void set_timer_freq_simple(void) > +{ > + u32 div = get_xtal_mhz(); > + > + /* Round down cpu freq */ > + gd->arch.timer_freq = rounddown(CONFIG_MT7621_CPU_FREQ, div) * 500000; > +} > + > +void __noreturn board_init_f(ulong dummy) > +{ > + spl_init(); > + > +#ifdef CONFIG_SPL_SERIAL > + /* > + * mtmips_spl_serial_init() is useful if debug uart is enabled, > + * or DM based serial is not enabled. > + */ > + mtmips_spl_serial_init(); > + preloader_console_init(); > +#endif > + > + board_init_r(NULL, 0); > +} > + > +void board_boot_order(u32 *spl_boot_list) > +{ > +#ifdef CONFIG_MT7621_BOOT_FROM_NAND > + spl_boot_list[0] = BOOT_DEVICE_NAND; > +#else > + spl_boot_list[0] = BOOT_DEVICE_NOR; > +#endif > +} > + > +unsigned long spl_nor_get_uboot_base(void) > +{ > + const struct tpl_info *tpli; > + const image_header_t *hdr; > + u32 addr; > + > + addr = FLASH_MMAP_BASE + TPL_INFO_OFFSET; > + tpli = (const struct tpl_info *)KSEG1ADDR(addr); > + > + if (tpli->magic == TPL_INFO_MAGIC) { > + addr = FLASH_MMAP_BASE + tpli->size; > + hdr = (const image_header_t *)KSEG1ADDR(addr); > + > + if (image_get_magic(hdr) == IH_MAGIC) { > + addr += sizeof(*hdr) + image_get_size(hdr); > + return KSEG1ADDR(addr); > + } > + } > + > + panic("Unable to locate SPL payload\n"); > + return 0; > +} > + > +uint32_t spl_nand_get_uboot_raw_page(void) > +{ > + const struct stage_header *sh = (const struct stage_header *)&_start; > + u32 addr; > + > + addr = image_get_header_size() + be32_to_cpu(sh->stage_size); > + addr = ALIGN(addr, SZ_4K); > + > + return addr; > +} > diff --git a/arch/mips/mach-mtmips/mt7621/spl/start.S b/arch/mips/mach-mtmips/mt7621/spl/start.S > new file mode 100644 > index 0000000000..3cad3567e7 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/spl/start.S > @@ -0,0 +1,226 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <asm-offsets.h> > +#include <config.h> > +#include <asm/asm.h> > +#include <asm/regdef.h> > +#include <asm/mipsregs.h> > +#include <asm/cacheops.h> > +#include <asm/addrspace.h> > +#include <asm/mipsmtregs.h> > +#include <asm/cm.h> > +#include "../mt7621.h" > +#include "dram.h" > + > +#ifndef CONFIG_SYS_INIT_SP_ADDR > +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ > + CONFIG_SYS_INIT_SP_OFFSET) > +#endif > + > +#define SP_ADDR_TEMP 0xbe10dff0 > + > + .macro init_wr sel > + MTC0 zero, CP0_WATCHLO,\sel > + mtc0 t1, CP0_WATCHHI,\sel > + .endm > + > + .macro setup_stack_gd > + li t0, -16 > + PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR > + and sp, t1, t0 # force 16 byte alignment > + PTR_SUBU \ > + sp, sp, GD_SIZE # reserve space for gd > + and sp, sp, t0 # force 16 byte alignment > + move k0, sp # save gd pointer > +#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \ > + !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) > + li t2, CONFIG_VAL(SYS_MALLOC_F_LEN) > + PTR_SUBU \ > + sp, sp, t2 # reserve space for early malloc > + and sp, sp, t0 # force 16 byte alignment > +#endif > + move fp, sp > + > + /* Clear gd */ > + move t0, k0 > +1: > + PTR_S zero, 0(t0) > + PTR_ADDIU t0, PTRSIZE > + blt t0, t1, 1b > + nop > + > +#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \ > + !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) > + PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset > +#endif > + .endm > + > + .set noreorder > + > +ENTRY(_start) > + b 1f > + mtc0 zero, CP0_COUNT > + > + /* Stage header required by BootROM */ > + .org 0x8 > + .word 0 # ep, filled by mkimage > + .word 0 # stage_size, filled by mkimage > + .word 0 # has_stage2 > + .word 0 # next_ep > + .word 0 # next_size > + .word 0 # next_offset > + > +1: > + /* Init CP0 Status */ > + mfc0 t0, CP0_STATUS > + and t0, ST0_IMPL > + or t0, ST0_BEV | ST0_ERL > + mtc0 t0, CP0_STATUS > + ehb > + > + /* Clear Watch Status bits and disable watch exceptions */ > + li t1, 0x7 # Clear I, R and W conditions > + init_wr 0 > + init_wr 1 > + init_wr 2 > + init_wr 3 > + > + /* Clear WP, IV and SW interrupts */ > + mtc0 zero, CP0_CAUSE > + > + /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */ > + mtc0 zero, CP0_COMPARE > + > + /* VPE1 goes to wait code directly */ > + mfc0 t0, CP0_TCBIND > + andi t0, TCBIND_CURVPE > + bnez t0, launch_vpe_entry > + nop > + > + /* Core1 goes to specific launch entry */ > + PTR_LI t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE) > + lw t1, GCR_Cx_ID(t0) > + bnez t1, launch_core_entry > + nop > + > + /* MT7530 reset */ > + li t0, KSEG1ADDR(SYSCTL_BASE) > + lw t1, SYSCTL_RSTCTL_REG(t0) > + ori t1, MCM_RST > + sw t1, SYSCTL_RSTCTL_REG(t0) > + > + /* Disable DMA route for PSE SRAM set by BootROM */ > + PTR_LI t0, KSEG1ADDR(DMA_CFG_ARB_BASE) > + sw zero, DMA_ROUTE_REG(t0) > + > + /* Set CPU clock to 500MHz (Required if boot from NAND) */ > + li t0, KSEG1ADDR(SYSCTL_BASE) > + lw t1, SYSCTL_CLKCFG0_REG(t0) > + ins t1, zero, 30, 2 # CPU_CLK_SEL > + sw t1, SYSCTL_CLKCFG0_REG(t0) > + > + /* Set CPU clock divider to 1/1 */ > + li t0, KSEG1ADDR(RBUS_BASE) > + li t1, 0x101 > + sw t1, RBUS_DYN_CFG0_REG(t0) > + > + /* (Re-)initialize the SRAM */ > + bal mips_sram_init > + nop > + > + /* Set up temporary stack */ > + li sp, SP_ADDR_TEMP > + > + /* Setup full CPS */ > + bal mips_cm_map > + nop > + > + bal mt7621_cps_init > + nop > + > + /* Prepare for CPU/DDR initialization binary blob */ > + bal prepare_stage_bin > + nop > + > + /* Call CPU/DDR initialization binary blob */ > + li t9, STAGE_LOAD_ADDR > + jalr t9 > + nop > + > + /* Switch CPU PLL source */ > + li t0, KSEG1ADDR(SYSCTL_BASE) > + lw t1, SYSCTL_CLKCFG0_REG(t0) > + li t2, 1 > + ins t1, t2, CPU_CLK_SEL_S, 2 > + sw t1, SYSCTL_CLKCFG0_REG(t0) > + > + /* > + * Currently SPL is running on locked L2 cache (on KSEG0). > + * To reset the entire cache, we have to writeback SPL to DRAM first. > + * Cache flush won't work here. Use memcpy instead. > + */ > + > + la a0, __text_start > + move a1, a0 > + la a2, __image_copy_end > + sub a2, a2, a1 > + li a3, 5 > + ins a0, a3, 29, 3 # convert to KSEG1 > + > + bal memcpy > + nop > + > + /* Disable caches */ > + bal mips_cache_disable > + nop > + > + /* Reset caches */ > + bal mips_cache_reset > + nop > + > + /* Disable SRAM */ > + li t0, KSEG1ADDR(FE_BASE) > + li t1, FE_PSE_RESET > + sw t1, FE_RST_GLO_REG(t0) > + > + /* Clear the .bss section */ > + la a0, __bss_start > + la a1, __bss_end > +1: sw zero, 0(a0) > + addiu a0, 4 > + ble a0, a1, 1b > + nop > + > + /* Set up initial stack and global data */ > + setup_stack_gd > + > +#if CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) > + /* Set malloc base */ > + li t0, (CONFIG_SYS_INIT_SP_ADDR + 15) & (~15) > + PTR_S t0, GD_MALLOC_BASE(k0) # gd->malloc_base offset > +#endif > + > +#if defined(CONFIG_DEBUG_UART) && defined(CONFIG_SPL_SERIAL) > + /* Earliest point to set up debug uart */ > + bal debug_uart_init > + nop > +#endif > + > + /* Setup timer */ > + bal set_timer_freq_simple > + nop > + > + /* Bootup secondary CPUs */ > + bal secondary_cpu_init > + nop > + > + move a0, zero # a0 <-- boot_flags = 0 > + bal board_init_f > + move ra, zero > + > + END(_start) > diff --git a/arch/mips/mach-mtmips/mt7621/sram_init.S b/arch/mips/mach-mtmips/mt7621/sram_init.S > new file mode 100644 > index 0000000000..74ddd6bcd7 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/sram_init.S > @@ -0,0 +1,22 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <asm/addrspace.h> > +#include <asm/asm.h> > +#include <asm/regdef.h> > +#include "mt7621.h" > + > +LEAF(mips_sram_init) > + li t0, KSEG1ADDR(FE_BASE) > + li t1, FE_PSE_RESET > + sw t1, FE_RST_GLO_REG(t0) > + > + li t1, (FE_PSE_RAM | FE_PSE_MEM_EN) > + sw t1, FE_RST_GLO_REG(t0) > + > + jr ra > + END(mips_sram_init) > diff --git a/arch/mips/mach-mtmips/mt7621/tpl/Makefile b/arch/mips/mach-mtmips/mt7621/tpl/Makefile > new file mode 100644 > index 0000000000..471ad74249 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/tpl/Makefile > @@ -0,0 +1,4 @@ > + > +extra-y += start.o > + > +obj-y += tpl.o > diff --git a/arch/mips/mach-mtmips/mt7621/tpl/start.S b/arch/mips/mach-mtmips/mt7621/tpl/start.S > new file mode 100644 > index 0000000000..19b09f7251 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/tpl/start.S > @@ -0,0 +1,161 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <asm-offsets.h> > +#include <config.h> > +#include <asm/asm.h> > +#include <asm/regdef.h> > +#include <asm/addrspace.h> > +#include <asm/mipsregs.h> > +#include <asm/cm.h> > +#include "../mt7621.h" > + > +#define SP_ADDR_TEMP 0xbe10dff0 > + > + .set noreorder > + > + .macro init_wr sel > + MTC0 zero, CP0_WATCHLO,\sel > + mtc0 t1, CP0_WATCHHI,\sel > + .endm > + > + .macro uhi_mips_exception > + move k0, t9 # preserve t9 in k0 > + move k1, a0 # preserve a0 in k1 > + li t9, 15 # UHI exception operation > + li a0, 0 # Use hard register context > + sdbbp 1 # Invoke UHI operation > + .endm > + > +ENTRY(_start) > + b reset > + mtc0 zero, CP0_COUNT > + > + /* > + * Store TPL size here. > + * This will be used by SPL to locate u-boot payload. > + */ > + .org TPL_INFO_OFFSET > + .word TPL_INFO_MAGIC > + .word __image_copy_len > + > + /* Exception vector */ > + .org 0x200 > + /* TLB refill, 32 bit task */ > + uhi_mips_exception > + > + .org 0x280 > + /* XTLB refill, 64 bit task */ > + uhi_mips_exception > + > + .org 0x300 > + /* Cache error exception */ > + uhi_mips_exception > + > + .org 0x380 > + /* General exception */ > + uhi_mips_exception > + > + .org 0x400 > + /* Catch interrupt exceptions */ > + uhi_mips_exception > + > + .org 0x480 > + /* EJTAG debug exception */ > +1: b 1b > + nop > + > + .org 0x500 > + > +reset: > + /* Set KSEG0 to Uncached */ > + mfc0 t0, CP0_CONFIG > + ins t0, zero, 0, 3 > + ori t0, t0, CONF_CM_UNCACHED > + mtc0 t0, CP0_CONFIG > + ehb > + > + /* Check for CPU number */ > + mfc0 t0, CP0_EBASE > + and t0, t0, MIPS_EBASE_CPUNUM > + beqz t0, 1f > + nop > + > + /* Secondary core goes to specified SPL entry address */ > + li t0, KSEG1ADDR(SYSCTL_BASE) > + lw t0, BOOT_SRAM_BASE_REG(t0) > + jr t0 > + nop > + > + /* Init CP0 Status */ > +1: mfc0 t0, CP0_STATUS > + and t0, ST0_IMPL > + or t0, ST0_BEV | ST0_ERL > + mtc0 t0, CP0_STATUS > + nop > + > + /* Clear Watch Status bits and disable watch exceptions */ > + li t1, 0x7 # Clear I, R and W conditions > + init_wr 0 > + init_wr 1 > + init_wr 2 > + init_wr 3 > + > + /* Clear WP, IV and SW interrupts */ > + mtc0 zero, CP0_CAUSE > + > + /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */ > + mtc0 zero, CP0_COMPARE > + > + /* Setup basic CPS */ > + bal mips_cm_map > + nop > + > + li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE) > + li t1, GCR_REG0_BASE_VALUE > + sw t1, GCR_REG0_BASE(t0) > + > + li t1, ((GCR_REG0_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | \ > + GCR_REGn_MASK_CMTGT_IOCU0) > + sw t1, GCR_REG0_MASK(t0) > + > + lw t1, GCR_BASE(t0) > + ins t1, zero, 0, 2 # CM_DEFAULT_TARGET > + sw t1, GCR_BASE(t0) > + > + lw t1, GCR_CONTROL(t0) > + li t2, GCR_CONTROL_SYNCCTL > + or t1, t1, t2 > + sw t1, GCR_CONTROL(t0) > + > + /* Increase SPI frequency */ > + li t0, KSEG1ADDR(SPI_BASE) > + li t1, 5 > + sw t1, SPI_SPACE_REG(t0) > + > + /* Set CPU clock to 500MHz */ > + li t0, KSEG1ADDR(SYSCTL_BASE) > + lw t1, SYSCTL_CLKCFG0_REG(t0) > + ins t1, zero, 30, 2 # CPU_CLK_SEL > + sw t1, SYSCTL_CLKCFG0_REG(t0) > + > + /* Set CPU clock divider to 1/1 */ > + li t0, KSEG1ADDR(RBUS_BASE) > + li t1, 0x101 > + sw t1, RBUS_DYN_CFG0_REG(t0) > + > + /* Initialize the SRAM */ > + bal mips_sram_init > + nop > + > + /* Set up initial stack */ > + li sp, SP_ADDR_TEMP > + > + bal tpl_main > + nop > + > + END(_start) > diff --git a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c > new file mode 100644 > index 0000000000..77bcf0ddf0 > --- /dev/null > +++ b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c > @@ -0,0 +1,146 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#include <image.h> > +#include <asm/sections.h> > +#include <asm/cacheops.h> > +#include <asm/mipsregs.h> > +#include <asm/cm.h> > + > +#define INDEX_STORE_DATA_SD 0x0f > + > +typedef void __noreturn (*image_entry_noargs_t)(void); > + > +static inline void ehb(void) > +{ > + __asm__ __volatile__ ("ehb"); > +} > + > +/* > + * Lock L2 cache and fill data > + * Assume that data is 4-byte aligned and start_addr/size is 32-byte aligned > + */ > +static void fill_lock_l2cache(uintptr_t dataptr, ulong start_addr, ulong size) > +{ > + ulong slsize = CONFIG_SYS_DCACHE_LINE_SIZE; > + ulong end_addr = start_addr + size; > + const u32 *data = (u32 *)dataptr; > + ulong i, addr; > + u32 val; > + > + /* Clear WSC & SPR bit in ErrCtl */ > + val = read_c0_ecc(); > + val &= 0xcfffffff; > + write_c0_ecc(val); > + ehb(); > + > + for (addr = start_addr; addr < end_addr; addr += slsize) { > + /* Set STagLo to lock cache line */ > + write_c0_staglo((addr & 0x1ffff800) | 0xa0); > + mips_cache(INDEX_STORE_TAG_SD, (void *)addr); > + > + /* Fill data */ > + for (i = 0; i < slsize; i += 8) { > + val = *data++; > + __write_32bit_c0_register($28, 5, val); /* sdtaglo */ > + val = *data++; > + __write_32bit_c0_register($29, 5, val); /* sdtaghi */ > + mips_cache(INDEX_STORE_DATA_SD, (void *)(addr + i)); > + } > + } > +} > + > +/* A simple function to initialize MT7621's cache */ > +static void mt7621_cache_init(void) > +{ > + void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE); > + ulong lsize = CONFIG_SYS_DCACHE_LINE_SIZE; > + ulong addr; > + u32 val; > + > + /* Enable CCA override. Set to uncached */ > + val = readl(cm_base + GCR_BASE); > + val &= ~CCA_DEFAULT_OVR_MASK; > + val |= CCA_DEFAULT_OVREN | (2 << CCA_DEFAULT_OVR_SHIFT); > + writel(val, cm_base + GCR_BASE); > + > + /* Initialize L1 I-Cache */ > + write_c0_taglo(0); > + write_c0_taghi(0); > + > + for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += lsize) > + mips_cache(INDEX_STORE_TAG_I, (void *)addr); > + > + /* Initialize L1 D-Cache */ > + write_c0_dtaglo(0); > + __write_32bit_c0_register($29, 2, 0); /* dtaghi */ > + > + for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += lsize) > + mips_cache(INDEX_STORE_TAG_D, (void *)addr); > + > + /* Initialize L2 Cache */ > + write_c0_staglo(0); > + __write_32bit_c0_register($29, 4, 0); /* staghi */ > + > + for (addr = 0; addr < (256 << 10); addr += lsize) > + mips_cache(INDEX_STORE_TAG_SD, (void *)addr); > + > + /* Dsiable CCA override */ > + val = readl(cm_base + GCR_BASE); > + val &= ~(CCA_DEFAULT_OVR_MASK | CCA_DEFAULT_OVREN); > + writel(val, cm_base + GCR_BASE); > + > + /* Set KSEG0 to non-coherent cached (important!) */ > + val = read_c0_config(); > + val &= ~CONF_CM_CMASK; > + val |= CONF_CM_CACHABLE_NONCOHERENT; > + write_c0_config(val); > + ehb(); > + > + /* Again, invalidate L1 D-Cache */ > + for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += lsize) > + mips_cache(INDEX_WRITEBACK_INV_D, (void *)addr); > + > + /* Invalidate L1 I-Cache */ > + for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += lsize) > + mips_cache(INDEX_INVALIDATE_I, (void *)addr); > + > + /* Disable L2 cache bypass */ > + val = read_c0_config2(); > + val &= ~MIPS_CONF_IMPL; > + write_c0_config2(val); > + ehb(); > +} > + > +void __noreturn tpl_main(void) > +{ > + const image_header_t *hdr = (const image_header_t *)__image_copy_end; > + image_entry_noargs_t image_entry; > + u32 loadaddr, size; > + uintptr_t data; > + > + /* Initialize the cache first */ > + mt7621_cache_init(); > + > + if (image_get_magic(hdr) != IH_MAGIC) > + goto failed; > + > + loadaddr = image_get_load(hdr); > + size = image_get_size(hdr); > + image_entry = (image_entry_noargs_t)image_get_ep(hdr); > + > + /* Load TPL image to L2 cache */ > + data = (uintptr_t)__image_copy_end + sizeof(struct image_header); > + fill_lock_l2cache(data, loadaddr, size); > + > + /* Jump to SPL */ > + image_entry(); > + > +failed: > + for (;;) > + ; > +} > diff --git a/include/configs/mt7621.h b/include/configs/mt7621.h > new file mode 100644 > index 0000000000..580d5fde0c > --- /dev/null > +++ b/include/configs/mt7621.h > @@ -0,0 +1,67 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > + * > + * Author: Weijie Gao <weijie.gao@mediatek.com> > + */ > + > +#ifndef __CONFIG_MT7621_H > +#define __CONFIG_MT7621_H > + > +#define CONFIG_SYS_HZ 1000 > +#define CONFIG_SYS_MIPS_TIMER_FREQ 440000000 > + > +#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000 > + > +#define CONFIG_SYS_SDRAM_BASE 0x80000000 > + > +#define CONFIG_VERY_BIG_RAM > +#define CONFIG_MAX_MEM_MAPPED 0x1c000000 > + > +#define CONFIG_SYS_INIT_SP_OFFSET 0x800000 > + > +#define CONFIG_SYS_BOOTM_LEN 0x2000000 > + > +#define CONFIG_SYS_MAXARGS 16 > +#define CONFIG_SYS_CBSIZE 1024 > + > +#define CONFIG_SYS_NONCACHED_MEMORY 0x100000 > + > +/* MMC */ > +#define MMC_SUPPORTS_TUNING > + > +/* NAND */ > +#define CONFIG_SYS_MAX_NAND_DEVICE 1 > + > +/* Serial SPL */ > +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL) > +#define CONFIG_SYS_NS16550_MEM32 > +#define CONFIG_SYS_NS16550_CLK 50000000 > +#define CONFIG_SYS_NS16550_REG_SIZE -4 > +#define CONFIG_SYS_NS16550_COM1 0xbe000c00 > +#endif > + > +/* Serial common */ > +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ > + 230400, 460800, 921600 } > + > +/* SPL */ > +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE > + > +#ifdef CONFIG_TPL_BUILD > +#define CONFIG_SPL_START_S_PATH "arch/mips/mach-mtmips/mt7621/tpl" > +/* .bss will not be used by TPL */ > +#define CONFIG_SPL_BSS_START_ADDR 0x80000000 > +#define CONFIG_SPL_BSS_MAX_SIZE 0 > +#else > +#define CONFIG_SPL_START_S_PATH "arch/mips/mach-mtmips/mt7621/spl" > +#define CONFIG_SPL_BSS_START_ADDR 0x80140000 > +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 > +#define CONFIG_SPL_MAX_SIZE 0x30000 > +#endif > + > +/* Dummy value */ > +#define CONFIG_SYS_UBOOT_BASE 0 > +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0 > + > +#endif /* __CONFIG_MT7621_H */ >
On Wed, 2022-05-11 at 12:36 -0400, Sean Anderson wrote: > Hi Weijie, > > I just commented on the device tree stuff. > > On 5/10/22 8:18 AM, Weijie Gao wrote: > > This patch adds support for MediaTek MT7621 SoC. > > All files are dedicated for u-boot. > > > > The default build target is u-boot-mt7621.bin. > > > > The specification of this chip: > > https://www.mediatek.com/products/homenetworking/mt7621 > > > > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com> > > --- > > v4 changes: > > Add full support for booting from flash (SPL/TPL support) > > Boot all cores/VPEs > > Use binman to generate final binary > > Use binman to embed external binary blob > > v3 changes: > > Update clock name for mt7621.dtsi due to clk driver changed > > v2 changes: > > Add a kconfig for max supported ram size > > Remove network configs from default config file > > --- > > arch/mips/dts/mt7621-u-boot.dtsi | 79 ++++ > > arch/mips/dts/mt7621.dtsi | 370 > > +++++++++++++++++++ > > arch/mips/mach-mtmips/Kconfig | 49 ++- > > arch/mips/mach-mtmips/Makefile | 4 + > > arch/mips/mach-mtmips/cpu.c | 2 +- > > arch/mips/mach-mtmips/mt7621/Kconfig | 95 +++++ > > arch/mips/mach-mtmips/mt7621/Makefile | 14 + > > arch/mips/mach-mtmips/mt7621/init.c | 229 ++++++++++++ > > arch/mips/mach-mtmips/mt7621/mt7621.h | 229 ++++++++++++ > > arch/mips/mach-mtmips/mt7621/serial.c | 23 ++ > > arch/mips/mach-mtmips/mt7621/spl/Makefile | 9 + > > arch/mips/mach-mtmips/mt7621/spl/cps.c | 152 ++++++++ > > arch/mips/mach-mtmips/mt7621/spl/dram.c | 143 +++++++ > > arch/mips/mach-mtmips/mt7621/spl/dram.h | 37 ++ > > arch/mips/mach-mtmips/mt7621/spl/launch.c | 100 +++++ > > arch/mips/mach-mtmips/mt7621/spl/launch.h | 52 +++ > > arch/mips/mach-mtmips/mt7621/spl/launch_ll.S | 357 > > ++++++++++++++++++ > > arch/mips/mach-mtmips/mt7621/spl/serial.c | 24 ++ > > arch/mips/mach-mtmips/mt7621/spl/spl.c | 95 +++++ > > arch/mips/mach-mtmips/mt7621/spl/start.S | 226 +++++++++++ > > arch/mips/mach-mtmips/mt7621/sram_init.S | 22 ++ > > arch/mips/mach-mtmips/mt7621/tpl/Makefile | 4 + > > arch/mips/mach-mtmips/mt7621/tpl/start.S | 161 ++++++++ > > arch/mips/mach-mtmips/mt7621/tpl/tpl.c | 146 ++++++++ > > include/configs/mt7621.h | 67 ++++ > > 25 files changed, 2683 insertions(+), 6 deletions(-) > > create mode 100644 arch/mips/dts/mt7621-u-boot.dtsi > > create mode 100644 arch/mips/dts/mt7621.dtsi > > create mode 100644 arch/mips/mach-mtmips/mt7621/Kconfig > > create mode 100644 arch/mips/mach-mtmips/mt7621/Makefile > > create mode 100644 arch/mips/mach-mtmips/mt7621/init.c > > create mode 100644 arch/mips/mach-mtmips/mt7621/mt7621.h > > create mode 100644 arch/mips/mach-mtmips/mt7621/serial.c > > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/Makefile > > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/cps.c > > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/dram.c > > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/dram.h > > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch.c > > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch.h > > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch_ll.S > > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/serial.c > > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/spl.c > > create mode 100644 arch/mips/mach-mtmips/mt7621/spl/start.S > > create mode 100644 arch/mips/mach-mtmips/mt7621/sram_init.S > > create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/Makefile > > create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/start.S > > create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/tpl.c > > create mode 100644 include/configs/mt7621.h > > > > diff --git a/arch/mips/dts/mt7621-u-boot.dtsi > > b/arch/mips/dts/mt7621-u-boot.dtsi > > new file mode 100644 > > index 0000000000..b9b02003a5 > > --- /dev/null > > +++ b/arch/mips/dts/mt7621-u-boot.dtsi > > @@ -0,0 +1,79 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <linux/stringify.h> > > + > > +/ { > > + binman: binman { > > + multiple-images; > > + }; > > +}; > > + > > +&binman { > > + u-boot-spl-ddr { > > + align = <4>; > > + align-size = <4>; > > + filename = "u-boot-spl-ddr.bin"; > > + pad-byte = <0xff>; > > + > > + u-boot-spl { > > + align-end = <4>; > > + filename = "u-boot-spl.bin"; > > + }; > > + > > + stage_bin { > > + filename = "mt7621_stage_sram.bin"; > > + type = "blob-ext"; > > + }; > > + }; > > + > > + spl-img { > > + filename = "u-boot-spl-ddr.img"; > > + > > + mkimage { > > +#ifdef CONFIG_MT7621_BOOT_FROM_NAND > > + args = "-T", "mtk_image", "-n", > > "mt7621=1", > > + "-a", > > __stringify(CONFIG_SPL_TEXT_BASE), > > + "-e", > > __stringify(CONFIG_SPL_TEXT_BASE); > > +#else > > + args = "-A", "mips", "-T", "standalone", > > "-O", "u-boot", > > + "-C", "none", "-n", "MT7621 U-Boot > > SPL", > > + "-a", > > __stringify(CONFIG_SPL_TEXT_BASE), > > + "-e", > > __stringify(CONFIG_SPL_TEXT_BASE); > > +#endif > > + > > + blob { > > + filename = "u-boot-spl-ddr.bin"; > > + }; > > + }; > > + }; > > + > > + mt7621-uboot { > > + filename = "u-boot-mt7621.bin"; > > + pad-byte = <0xff>; > > + > > +#ifndef CONFIG_MT7621_BOOT_FROM_NAND > > + u-boot-tpl { > > + align-end = <4>; > > + filename = "u-boot-tpl.bin"; > > + }; > > +#endif > > + > > + spl { > > +#ifdef CONFIG_MT7621_BOOT_FROM_NAND > > + align-end = <0x1000>; > > +#endif > > + filename = "u-boot-spl-ddr.img"; > > + type = "blob"; > > + }; > > + > > + u-boot { > > + filename = "u-boot-lzma.img"; > > + type = "blob"; > > + }; > > + }; > > +}; > > diff --git a/arch/mips/dts/mt7621.dtsi b/arch/mips/dts/mt7621.dtsi > > new file mode 100644 > > index 0000000000..285179e896 > > --- /dev/null > > +++ b/arch/mips/dts/mt7621.dtsi > > @@ -0,0 +1,370 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <dt-bindings/clock/mt7621-clk.h> > > +#include <dt-bindings/reset/mt7621-reset.h> > > +#include <dt-bindings/phy/phy.h> > > + > > +/ { > > + #address-cells = <1>; > > + #size-cells = <1>; > > + compatible = "mediatek,mt7621-soc"; > > + > > + cpus { > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + cpu@0 { > > + device_type = "cpu"; > > + compatible = "mips,mips1004Kc"; > > + reg = <0>; > > + }; > > + > > + cpu@1 { > > + device_type = "cpu"; > > + compatible = "mips,mips1004Kc"; > > + reg = <0>; > > reg = <1>; > > > + }; > > + }; > > + > > + clk48m: clk48m@0 { > > + compatible = "fixed-clock"; > > + > > + clock-frequency = <48000000>; > > + > > + #clock-cells = <0>; > > + }; > > + > > + clk50m: clk50m@0 { > > + compatible = "fixed-clock"; > > + > > + clock-frequency = <50000000>; > > + > > + #clock-cells = <0>; > > + }; > > + > > + sysc: sysc@1e000000 { > > sysc: syscon@1e000000 > > > + compatible = "mediatek,mt7621-sysc", "syscon"; > > + reg = <0x1e000000 0x100>; > > + }; > > As commented under the clock patch, I think it would be better to > include the clock controller and reset controller bindings as > children > of this one. > > > + clkctrl: clkctrl@1e000030 { > > clock-controller@1e000030 (or just clock-controller with the above > suggestion) > > > + compatible = "mediatek,mt7621-clk"; > > + mediatek,sysc = <&sysc>; > > + mediatek,memc = <&memc>; > > + > > + #clock-cells = <1>; > > + u-boot,dm-pre-reloc; > > + }; > > + > > + rstctrl: rstctrl@1e000034 { > > reset-controller@1e000034 > > > + compatible = "mediatek,mtmips-reset"; > > + reg = <0x1e000034 0x4>; > > + #reset-cells = <1>; > > + }; > > + > > + reboot: resetctl-reboot { > > + compatible = "resetctl-reboot"; > > + > > + resets = <&rstctrl RST_SYS>; > > + reset-names = "sysreset"; > > + }; > > + > > + memc: memc@1e005000 { > > + compatible = "mediatek,mt7621-memc", "syscon"; > > + reg = <0x1e005000 0x1000>; > > + }; > > + > > + pinctrl: pinctrl@1e000060 { > > + compatible = "mediatek,mt7621-pinctrl"; > > + reg = <0x1e000048 0x30>; > > + > > + pinctrl-names = "default"; > > + pinctrl-0 = <&state_default>; > > + > > + state_default: pin_state { > > + uart1 { > > + groups = "uart1"; > > + function = "uart"; > > + }; > > + > > + gpios { > > + groups = "i2c", "uart3", "pcie > > reset"; > > + function = "gpio"; > > + }; > > + > > + jtag { > > + groups = "jtag"; > > + function = "jtag"; > > + }; > > I think the JTAG is perhaps the only thing which should be in here. > Everything > else can be changed by boards. uart1 is always used as a debug console. i2c/uart3/pcie reset are used as pcie reset pins for total three pcie RCs for most devices. But it's OK to move them to dts files of two reference boards. > > > + > > + wdt { > > + groups = "wdt"; > > + function = "wdt rst"; > > + }; > > + }; > > + > > + uart1_pins: uart1_pins { > > + groups = "uart1"; > > + function = "uart"; > > + }; > > + > > + uart2_pins: uart2_pins { > > + groups = "uart2"; > > + function = "uart"; > > + }; > > + > > + uart3_pins: uart3_pins { > > + groups = "uart3"; > > + function = "uart"; > > + }; > > + > > + sdxc_pins: sdxc_pins { > > + groups = "sdxc"; > > + function = "sdxc"; > > + }; > > + > > + spi_pins: spi_pins { > > + groups = "spi"; > > + function = "spi"; > > + }; > > + > > + eth_pins: eth_pins { > > + mdio_pins { > > + groups = "mdio"; > > + function = "mdio"; > > + }; > > + > > + rgmii1_pins { > > + groups = "rgmii1"; > > + function = "rgmii"; > > + }; > > + > > + esw_pins { > > + groups = "esw int"; > > + function = "esw int"; > > + }; > > + > > + mdio_pconf { > > + groups = "mdio"; > > + drive-strength = <2>; > > + }; > > + }; > > + }; > > + > > + watchdog: watchdog@1e000100 { > > + compatible = "mediatek,mt7621-wdt"; > > + reg = <0x1e000100 0x40>; > > + > > + resets = <&rstctrl RST_TIMER>; > > + reset-names = "wdt"; > > + > > + status = "disabled"; > > + }; > > + > > + gpio: gpio@1e000600 { > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + compatible = "mtk,mt7621-gpio"; > > + reg = <0x1e000600 0x100>; > > + > > + resets = <&rstctrl RST_PIO>; > > + reset-names = "pio"; > > + > > + gpio0: bank@0 { > > + reg = <0>; > > + compatible = "mtk,mt7621-gpio-bank"; > > + gpio-controller; > > + #gpio-cells = <2>; > > + }; > > + > > + gpio1: bank@1 { > > + reg = <1>; > > + compatible = "mtk,mt7621-gpio-bank"; > > + gpio-controller; > > + #gpio-cells = <2>; > > + }; > > + > > + gpio2: bank@2 { > > + reg = <2>; > > + compatible = "mtk,mt7621-gpio-bank"; > > + gpio-controller; > > + #gpio-cells = <2>; > > + }; > > + }; > > + > > + spi: spi@1e000b00 { > > + compatible = "ralink,mt7621-spi"; > > + reg = <0x1e000b00 0x40>; > > + > > + status = "disabled"; > > + > > + pinctrl-names = "default"; > > + pinctrl-0 = <&spi_pins>; > > + > > + resets = <&rstctrl RST_SPI>; > > + reset-names = "spi"; > > + > > + clocks = <&clkctrl MT7621_CLK_SPI>; > > + > > + #address-cells = <1>; > > + #size-cells = <0>; > > + }; > > + > > + uart0: uart1@1e000c00 { > > + compatible = "mediatek,hsuart", "ns16550a"; > > + reg = <0x1e000c00 0x100>; > > + > > + pinctrl-names = "default"; > > + pinctrl-0 = <&uart1_pins>; > > + > > + clocks = <&clkctrl MT7621_CLK_UART1>; > > + > > + resets = <&rstctrl RST_UART1>; > > + > > + reg-shift = <2>; > > + }; > > + > > + uart1: uart2@1e000d00 { > > + compatible = "mediatek,hsuart", "ns16550a"; > > + reg = <0x1e000d00 0x100>; > > + > > + pinctrl-names = "default"; > > + pinctrl-0 = <&uart2_pins>; > > + > > + clocks = <&clkctrl MT7621_CLK_UART2>; > > + > > + resets = <&rstctrl RST_UART2>; > > + > > + reg-shift = <2>; > > + > > + status = "disabled"; > > + }; > > + > > + uart2: uart3@1e000e00 { > > + compatible = "mediatek,hsuart", "ns16550a"; > > + reg = <0x1e000e00 0x100>; > > + > > + pinctrl-names = "default"; > > + pinctrl-0 = <&uart3_pins>; > > + > > + clocks = <&clkctrl MT7621_CLK_UART3>; > > + > > + resets = <&rstctrl RST_UART3>; > > + > > + reg-shift = <2>; > > + > > + status = "disabled"; > > + }; > > + > > + eth: eth@1e100000 { > > + compatible = "mediatek,mt7621-eth"; > > + reg = <0x1e100000 0x20000>; > > + mediatek,ethsys = <&sysc>; > > + > > + pinctrl-names = "default"; > > + pinctrl-0 = <ð_pins>; > > + > > + resets = <&rstctrl RST_FE>, <&rstctrl RST_GMAC>, > > <&rstctrl RST_MCM>; > > + reset-names = "fe", "gmac", "mcm"; > > + > > + clocks = <&clkctrl MT7621_CLK_GDMA>, > > + <&clkctrl MT7621_CLK_ETH>; > > + clock-names = "gmac", "fe"; > > + > > + #address-cells = <1>; > > + #size-cells = <0>; > > + > > + mediatek,gmac-id = <0>; > > + phy-mode = "rgmii"; > > + mediatek,switch = "mt7530"; > > + mediatek,mcm; > > + > > + fixed-link { > > + speed = <1000>; > > + full-duplex; > > + }; > > Should this be under the board? The only time this should be in the > SoC dts > s if there is an internal connection to another MAC on the SoC > itself. MT7621A is a multi-chip module (MCM), and a MT7530 giga switch is always connected to the RGMII1 of MT7621 it self. > > > + }; > > + > > + mmc: mmc@1e130000 { > > + compatible = "mediatek,mt7621-mmc"; > > + reg = <0x1e130000 0x4000>; > > + > > + status = "disabled"; > > + > > + bus-width = <4>; > > + builtin-cd = <1>; > > + r_smpl = <1>; > > + > > + pinctrl-names = "default"; > > + pinctrl-0 = <&sdxc_pins>; > > This should be in the board dts. This is the reference design for all mt7621 devices and should not be changed. > > > + > > + clocks = <&clk50m>, <&clkctrl MT7621_CLK_SHXC>; > > + clock-names = "source", "hclk"; > > + > > + resets = <&rstctrl RST_SDXC>; > > + }; > > + > > + ssusb: usb@1e1c0000 { > > + compatible = "mediatek,mt7621-xhci", > > "mediatek,mtk-xhci"; > > + reg = <0x1e1c0000 0x1000>, <0x1e1d0700 0x100>; > > + reg-names = "mac", "ippc"; > > + > > + clocks = <&clk48m>, <&clk48m>; > > + clock-names = "sys_ck", "ref_ck"; > > + > > + phys = <&u2port0 PHY_TYPE_USB2>, > > + <&u3port0 PHY_TYPE_USB3>, > > + <&u2port1 PHY_TYPE_USB2>; > > + > > + status = "disabled"; > > + }; > > + > > + u3phy: usb-phy@1e1d0000 { > > + compatible = "mediatek,mt7621-u3phy", > > + "mediatek,generic-tphy-v1"; > > + reg = <0x1e1d0000 0x700>; > > + #address-cells = <1>; > > + #size-cells = <1>; > > + ranges; > > + status = "disabled"; > > + > > + u2port0: usb-phy@1e1d0800 { > > + reg = <0x1e1d0800 0x0100>; > > + #phy-cells = <1>; > > + clocks = <&clk48m>; > > + clock-names = "ref"; > > + }; > > + > > + u3port0: usb-phy@1e1d0900 { > > + reg = <0x1e1d0900 0x0100>; > > + #phy-cells = <1>; > > + }; > > + > > + u2port1: usb-phy@1e1d1000 { > > + reg = <0x1e1d1000 0x0100>; > > + #phy-cells = <1>; > > + clocks = <&clk48m>; > > + clock-names = "ref"; > > + }; > > + }; > > + > > + i2c: i2c@1e000900 { > > + compatible = "i2c-gpio"; > > + > > + status = "disabled"; > > + > > + i2c-gpio,delay-us = <3>; > > + > > + gpios = <&gpio0 3 1>, /* PIN3 as SDA */ > > + <&gpio0 4 1>; /* PIN4 as CLK */ > > + > > + #address-cells = <1>; > > + #size-cells = <0>; > > + }; > > This should be on the board dts. Pin3/4 are the actual pins of the built-in i2c module. Since there's no i2c driver for mt7621, and u-boot is single-threaded, it's ok to use gpio bitbang mode for i2c. > > > +}; > > diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach- > > mtmips/Kconfig > > index 151b004603..d46be503a2 100644 > > --- a/arch/mips/mach-mtmips/Kconfig > > +++ b/arch/mips/mach-mtmips/Kconfig > > @@ -9,6 +9,7 @@ config SYS_MALLOC_F_LEN > > > > config SYS_SOC > > default "mt7620" if SOC_MT7620 > > + default "mt7621" if SOC_MT7621 > > default "mt7628" if SOC_MT7628 > > > > config SYS_DCACHE_SIZE > > @@ -18,25 +19,45 @@ config SYS_DCACHE_LINE_SIZE > > default 32 > > > > config SYS_ICACHE_SIZE > > - default 65536 > > + default 65536 if SOC_MT7620 || SOC_MT7628 > > + default 32768 if SOC_MT7621 > > > > config SYS_ICACHE_LINE_SIZE > > default 32 > > > > +config SYS_SCACHE_LINE_SIZE > > + default 32 if SOC_MT7621 > > + > > config SYS_TEXT_BASE > > - default 0x9c000000 if !SPL > > - default 0x80200000 if SPL > > + default 0x9c000000 if !SPL && !SOC_MT7621 > > + default 0x80200000 if SPL || SOC_MT7621 > > > > config SPL_TEXT_BASE > > - default 0x9c000000 > > + default 0x9c000000 if !SOC_MT7621 > > + default 0x80100000 if SOC_MT7621 > > + > > +config SPL_SIZE_LIMIT > > + default 0x30000 if SOC_MT7621 > > + > > +config TPL_TEXT_BASE > > + default 0xbfc00000 if SOC_MT7621 > > + > > +config TPL_MAX_SIZE > > + default 4096 if SOC_MT7621 > > > > config SPL_PAYLOAD > > default "u-boot-lzma.img" if SPL_LZMA > > > > config BUILD_TARGET > > - default "u-boot-with-spl.bin" if SPL > > + default "u-boot-with-spl.bin" if SPL && !SOC_MT7621 > > + default "u-boot-lzma.img" if SOC_MT7621 > > default "u-boot.bin" > > > > +config MAX_MEM_SIZE > > + int > > + default 256 if SOC_MT7620 || SOC_MT7628 > > + default 512 if SOC_MT7621 > > + > > choice > > prompt "MediaTek MIPS SoC select" > > > > @@ -55,6 +76,23 @@ config SOC_MT7620 > > help > > This supports MediaTek MT7620. > > > > +config SOC_MT7621 > > + bool "MT7621" > > + select MIPS_CM > > + select MIPS_L2_CACHE > > + select SYS_CACHE_SHIFT_5 > > + select SYS_MIPS_CACHE_INIT_RAM_LOAD > > + select PINCTRL_MT7621 > > + select MTK_SERIAL > > + select REGMAP > > + select SYSCON > > + select BINMAN > > + select SUPPORT_TPL > > + select SPL_LOADER_SUPPORT if SPL > > + select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL > > + help > > + This supports MediaTek MT7621. > > + > > config SOC_MT7628 > > bool "MT7628" > > select SYS_CACHE_SHIFT_5 > > @@ -80,6 +118,7 @@ config SOC_MT7628 > > endchoice > > > > source "arch/mips/mach-mtmips/mt7620/Kconfig" > > +source "arch/mips/mach-mtmips/mt7621/Kconfig" > > source "arch/mips/mach-mtmips/mt7628/Kconfig" > > > > endmenu > > diff --git a/arch/mips/mach-mtmips/Makefile b/arch/mips/mach- > > mtmips/Makefile > > index 4909b47ef2..19f1e07033 100644 > > --- a/arch/mips/mach-mtmips/Makefile > > +++ b/arch/mips/mach-mtmips/Makefile > > @@ -1,9 +1,13 @@ > > # SPDX-License-Identifier: GPL-2.0+ > > > > obj-y += cpu.o > > + > > +ifneq ($(CONFIG_SOC_MT7621),y) > > obj-y += ddr_init.o > > obj-y += ddr_cal.o > > obj-$(CONFIG_SPL_BUILD) += spl.o > > +endif > > > > obj-$(CONFIG_SOC_MT7620) += mt7620/ > > +obj-$(CONFIG_SOC_MT7621) += mt7621/ > > obj-$(CONFIG_SOC_MT7628) += mt7628/ > > diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach- > > mtmips/cpu.c > > index a4b5cff61d..f1e9022738 100644 > > --- a/arch/mips/mach-mtmips/cpu.c > > +++ b/arch/mips/mach-mtmips/cpu.c > > @@ -16,7 +16,7 @@ DECLARE_GLOBAL_DATA_PTR; > > > > int dram_init(void) > > { > > - gd->ram_size = get_ram_size((void *)KSEG1, SZ_256M); > > + gd->ram_size = get_ram_size((void *)KSEG1, > > CONFIG_MAX_MEM_SIZE << 20); > > > > return 0; > > } > > diff --git a/arch/mips/mach-mtmips/mt7621/Kconfig b/arch/mips/mach- > > mtmips/mt7621/Kconfig > > new file mode 100644 > > index 0000000000..37d512c68f > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/Kconfig > > @@ -0,0 +1,95 @@ > > + > > +if SOC_MT7621 > > + > > +menu "CPU & DDR configuration" > > + > > +config MT7621_CPU_FREQ > > + int "CPU Frequency (MHz)" > > + range 400 1200 > > + default 880 > > + > > +choice > > + prompt "DRAM Frequency" > > + default MT7621_DRAM_FREQ_1200 > > + > > +config MT7621_DRAM_FREQ_400 > > + bool "400MHz" > > + > > +config MT7621_DRAM_FREQ_800 > > + bool "800MHz" > > + > > +config MT7621_DRAM_FREQ_1066 > > + bool "1066MHz" > > + > > +config MT7621_DRAM_FREQ_1200 > > + bool "1200MHz" > > + > > +endchoice > > + > > +choice > > + prompt "DDR2 timing parameters" > > + default MT7621_DRAM_DDR2_1024M > > + > > +config MT7621_DRAM_DDR2_512M > > + bool "64MB" > > + > > +config MT7621_DRAM_DDR2_1024M > > + bool "128MB" > > + > > +config MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ > > + bool "W9751G6KB_A02 @ 1066MHz (64MB)" > > + > > +config MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ > > + bool "W971GG6KB25 @ 800MHz (128MB)" > > + > > +config MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ > > + bool "W971GG6KB18 @ 1066MHz (128MB)" > > + > > +endchoice > > + > > +choice > > + prompt "DDR3 timing parameters" > > + default MT7621_DRAM_DDR3_2048M > > + > > +config MT7621_DRAM_DDR3_1024M > > + bool "128MB" > > + > > +config MT7621_DRAM_DDR3_1024M_KGD > > + bool "128MB KGD (MT7621DA)" > > + > > +config MT7621_DRAM_DDR3_2048M > > + bool "256MB" > > + > > +config MT7621_DRAM_DDR3_4096M > > + bool "512MB" > > + > > +endchoice > > + > > +endmenu > > + > > +config DEBUG_UART_BOARD_INIT > > + default y > > + > > +config MT7621_BOOT_FROM_NAND > > + bool "Boot from NAND" > > + help > > + Select this if u-boot will boot from NAND flash. When > > booting from > > + NAND, SPL will be loaded by bootrom directly and no TPL > > is needed. > > + > > +choice > > + prompt "Board select" > > + > > +endchoice > > + > > +config SYS_CONFIG_NAME > > + string "Board configuration name" > > + default "mt7621" if BOARD_MT7621_RFB || > > BOARD_MT7621_NAND_RFB > > + > > +config SYS_BOARD > > + string "Board name" > > + default "mt7621" if BOARD_MT7621_RFB || > > BOARD_MT7621_NAND_RFB > > + > > +config SYS_VENDOR > > + default "mediatek" if BOARD_MT7621_RFB || > > BOARD_MT7621_NAND_RFB > > + > > +endif > > diff --git a/arch/mips/mach-mtmips/mt7621/Makefile > > b/arch/mips/mach-mtmips/mt7621/Makefile > > new file mode 100644 > > index 0000000000..bf1b0bb688 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/Makefile > > @@ -0,0 +1,14 @@ > > +# SPDX-License-Identifier: GPL-2.0 > > + > > +obj-y += init.o > > +obj-y += serial.o > > + > > +ifeq ($(CONFIG_SPL_BUILD),y) > > +ifeq ($(CONFIG_TPL_BUILD),y) > > +obj-y += tpl/ > > +else > > +obj-y += spl/ > > +endif > > + > > +obj-y += sram_init.o > > +endif > > diff --git a/arch/mips/mach-mtmips/mt7621/init.c b/arch/mips/mach- > > mtmips/mt7621/init.c > > new file mode 100644 > > index 0000000000..ec63712bc1 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/init.c > > @@ -0,0 +1,229 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <clk.h> > > +#include <dm.h> > > +#include <dm/uclass.h> > > +#include <dt-bindings/clock/mt7621-clk.h> > > +#include <asm/global_data.h> > > +#include <linux/io.h> > > +#include "mt7621.h" > > + > > +DECLARE_GLOBAL_DATA_PTR; > > + > > +static const char *const boot_mode[(CHIP_MODE_M >> CHIP_MODE_S) + > > 1] = { > > + [1] = "NAND 2K+64", > > + [2] = "SPI-NOR 3-Byte Addr", > > + [3] = "SPI-NOR 4-Byte Addr", > > + [10] = "NAND 2K+128", > > + [11] = "NAND 4K+128", > > + [12] = "NAND 4K+256", > > +}; > > + > > +int print_cpuinfo(void) > > +{ > > + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, > > SYSCTL_SIZE); > > + u32 val, ver, eco, pkg, core, dram, chipmode; > > + u32 cpu_clk, ddr_clk, bus_clk, xtal_clk; > > + struct udevice *clkdev; > > + const char *bootdev; > > + struct clk clk; > > + int ret; > > + > > + val = readl(sysc + SYSCTL_CHIP_REV_ID_REG); > > + ver = (val & VER_ID_M) >> VER_ID_S; > > + eco = (val & ECO_ID_M) >> ECO_ID_S; > > + pkg = !!(val & PKG_ID); > > + core = !!(val & CPU_ID); > > + > > + val = readl(sysc + SYSCTL_SYSCFG0_REG); > > + dram = val & DRAM_TYPE; > > + chipmode = (val & CHIP_MODE_M) >> CHIP_MODE_S; > > + > > + bootdev = boot_mode[chipmode]; > > + if (!bootdev) > > + bootdev = "Unsupported boot mode"; > > + > > + printf("CPU: MediaTek MT7621%c ver %u, eco %u\n", > > + core ? (pkg ? 'A' : 'N') : 'S', ver, eco); > > + > > + printf("Boot: DDR%u, %s\n", dram ? 2 : 3, bootdev); > > + > > + ret = uclass_get_device_by_driver(UCLASS_CLK, > > DM_DRIVER_GET(mt7621_clk), > > + &clkdev); > > + if (ret) > > + return ret; > > + > > + clk.dev = clkdev; > > + > > + clk.id = MT7621_CLK_CPU; > > + cpu_clk = clk_get_rate(&clk); > > + > > + clk.id = MT7621_CLK_BUS; > > + bus_clk = clk_get_rate(&clk); > > + > > + clk.id = MT7621_CLK_DDR; > > + ddr_clk = clk_get_rate(&clk); > > + > > + clk.id = MT7621_CLK_XTAL; > > + xtal_clk = clk_get_rate(&clk); > > + > > + /* Set final timer frequency */ > > + if (cpu_clk) > > + gd->arch.timer_freq = cpu_clk / 2; > > + > > + printf("Clock: CPU: %uMHz, DDR: %uMT/s, Bus: %uMHz, XTAL: > > %uMHz\n", > > + cpu_clk / 1000000, ddr_clk / 500000, bus_clk / > > 1000000, > > + xtal_clk / 1000000); > > + > > + return 0; > > +} > > + > > +unsigned long get_xtal_mhz(void) > > +{ > > + void __iomem *sysc = (void *)KSEG1ADDR(SYSCTL_BASE); > > + u32 bs, xtal_sel; > > + > > + bs = readl(sysc + SYSCTL_SYSCFG0_REG); > > + xtal_sel = (bs & XTAL_MODE_SEL_M) >> XTAL_MODE_SEL_S; > > + > > + if (xtal_sel <= 2) > > + return 20; > > + else if (xtal_sel <= 5) > > + return 40; > > + else > > + return 25; > > +} > > + > > +static void xhci_config_40mhz(void __iomem *usbh) > > +{ > > + writel((0x20 << SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S) | > > + (0x20 << SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S) | > > + (2 << SSUSB_MAC3_SYS_CK_GATE_MODE_S) | > > + (2 << SSUSB_MAC2_SYS_CK_GATE_MODE_S) | 0x10, > > + usbh + SSUSB_MAC_CK_CTRL_REG); > > + > > + writel((2 << SSUSB_PLL_PREDIV_PE1D_S) | (1 << > > SSUSB_PLL_PREDIV_U3_S) | > > + (4 << SSUSB_PLL_FBKDI_S), usbh + > > DA_SSUSB_U3PHYA_10_REG); > > + > > + writel((0x18 << SSUSB_PLL_FBKDIV_PE2H_S) | > > + (0x18 << SSUSB_PLL_FBKDIV_PE1D_S) | > > + (0x18 << SSUSB_PLL_FBKDIV_PE1H_S) | > > + (0x1e << SSUSB_PLL_FBKDIV_U3_S), > > + usbh + DA_SSUSB_PLL_FBKDIV_REG); > > + > > + writel((0x1e400000 << SSUSB_PLL_PCW_NCPO_U3_S), > > + usbh + DA_SSUSB_PLL_PCW_NCPO_REG); > > + > > + writel((0x25 << SSUSB_PLL_SSC_DELTA1_PE1H_S) | > > + (0x73 << SSUSB_PLL_SSC_DELTA1_U3_S), > > + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG); > > + > > + writel((0x71 << SSUSB_PLL_SSC_DELTA_U3_S) | > > + (0x4a << SSUSB_PLL_SSC_DELTA1_PE2D_S), > > + usbh + DA_SSUSB_U3PHYA_21_REG); > > + > > + writel((0x140 << SSUSB_PLL_SSC_PRD_S), usbh + > > SSUSB_U3PHYA_9_REG); > > + > > + writel((0x11c00000 << SSUSB_SYSPLL_PCW_NCPO_S), > > + usbh + SSUSB_U3PHYA_3_REG); > > + > > + writel((4 << SSUSB_PCIE_CLKDRV_AMP_S) | (1 << > > SSUSB_SYSPLL_FBSEL_S) | > > + (1 << SSUSB_SYSPLL_PREDIV_S), usbh + > > SSUSB_U3PHYA_1_REG); > > + > > + writel((0x12 << SSUSB_SYSPLL_FBDIV_S) | > > SSUSB_SYSPLL_VCO_DIV_SEL | > > + SSUSB_SYSPLL_FPEN | SSUSB_SYSPLL_MONCK_EN | > > SSUSB_SYSPLL_VOD_EN, > > + usbh + SSUSB_U3PHYA_2_REG); > > + > > + writel(SSUSB_EQ_CURSEL | (8 << SSUSB_RX_DAC_MUX_S) | > > + (1 << SSUSB_PCIE_SIGDET_VTH_S) | (1 << > > SSUSB_PCIE_SIGDET_LPF_S), > > + usbh + SSUSB_U3PHYA_11_REG); > > + > > + writel((0x1ff << SSUSB_RING_OSC_CNTEND_S) | > > + (0x7f << SSUSB_XTAL_OSC_CNTEND_S) | > > SSUSB_RING_BYPASS_DET, > > + usbh + SSUSB_B2_ROSC_0_REG); > > + > > + writel((3 << SSUSB_RING_OSC_FRC_RECAL_S) | > > SSUSB_RING_OSC_FRC_SEL, > > + usbh + SSUSB_B2_ROSC_1_REG); > > +} > > + > > +static void xhci_config_25mhz(void __iomem *usbh) > > +{ > > + writel((0x20 << SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S) | > > + (0x20 << SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S) | > > + (2 << SSUSB_MAC3_SYS_CK_GATE_MODE_S) | > > + (2 << SSUSB_MAC2_SYS_CK_GATE_MODE_S) | 0x10, > > + usbh + SSUSB_MAC_CK_CTRL_REG); > > + > > + writel((2 << SSUSB_PLL_PREDIV_PE1D_S) | (4 << > > SSUSB_PLL_FBKDI_S), > > + usbh + DA_SSUSB_U3PHYA_10_REG); > > + > > + writel((0x18 << SSUSB_PLL_FBKDIV_PE2H_S) | > > + (0x18 << SSUSB_PLL_FBKDIV_PE1D_S) | > > + (0x18 << SSUSB_PLL_FBKDIV_PE1H_S) | > > + (0x19 << SSUSB_PLL_FBKDIV_U3_S), > > + usbh + DA_SSUSB_PLL_FBKDIV_REG); > > + > > + writel((0x18000000 << SSUSB_PLL_PCW_NCPO_U3_S), > > + usbh + DA_SSUSB_PLL_PCW_NCPO_REG); > > + > > + writel((0x25 << SSUSB_PLL_SSC_DELTA1_PE1H_S) | > > + (0x4a << SSUSB_PLL_SSC_DELTA1_U3_S), > > + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG); > > + > > + writel((0x48 << SSUSB_PLL_SSC_DELTA_U3_S) | > > + (0x4a << SSUSB_PLL_SSC_DELTA1_PE2D_S), > > + usbh + DA_SSUSB_U3PHYA_21_REG); > > + > > + writel((0x190 << SSUSB_PLL_SSC_PRD_S), usbh + > > SSUSB_U3PHYA_9_REG); > > + > > + writel((0xe000000 << SSUSB_SYSPLL_PCW_NCPO_S), > > + usbh + SSUSB_U3PHYA_3_REG); > > + > > + writel((4 << SSUSB_PCIE_CLKDRV_AMP_S) | (1 << > > SSUSB_SYSPLL_FBSEL_S), > > + usbh + SSUSB_U3PHYA_1_REG); > > + > > + writel((0xf << SSUSB_SYSPLL_FBDIV_S) | > > SSUSB_SYSPLL_VCO_DIV_SEL | > > + SSUSB_SYSPLL_FPEN | SSUSB_SYSPLL_MONCK_EN | > > SSUSB_SYSPLL_VOD_EN, > > + usbh + SSUSB_U3PHYA_2_REG); > > + > > + writel(SSUSB_EQ_CURSEL | (8 << SSUSB_RX_DAC_MUX_S) | > > + (1 << SSUSB_PCIE_SIGDET_VTH_S) | (1 << > > SSUSB_PCIE_SIGDET_LPF_S), > > + usbh + SSUSB_U3PHYA_11_REG); > > + > > + writel((0x1ff << SSUSB_RING_OSC_CNTEND_S) | > > + (0x7f << SSUSB_XTAL_OSC_CNTEND_S) | > > SSUSB_RING_BYPASS_DET, > > + usbh + SSUSB_B2_ROSC_0_REG); > > + > > + writel((3 << SSUSB_RING_OSC_FRC_RECAL_S) | > > SSUSB_RING_OSC_FRC_SEL, > > + usbh + SSUSB_B2_ROSC_1_REG); > > +} > > + > > +void lowlevel_init(void) > > +{ > > + void __iomem *usbh = ioremap_nocache(SSUSB_BASE, > > SSUSB_SIZE); > > + u32 xtal = get_xtal_mhz(); > > + > > + /* Setup USB xHCI */ > > + if (xtal == 40) > > + xhci_config_40mhz(usbh); > > + else if (xtal == 25) > > + xhci_config_25mhz(usbh); > > +} > > + > > +ulong notrace get_tbclk(void) > > +{ > > + return gd->arch.timer_freq; > > +} > > + > > +void _machine_restart(void) > > +{ > > + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, > > SYSCTL_SIZE); > > + > > + while (1) > > + writel(SYS_RST, sysc + SYSCTL_RSTCTL_REG); > > +} > > diff --git a/arch/mips/mach-mtmips/mt7621/mt7621.h > > b/arch/mips/mach-mtmips/mt7621/mt7621.h > > new file mode 100644 > > index 0000000000..916cc993b4 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/mt7621.h > > @@ -0,0 +1,229 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#ifndef _MT7621_H_ > > +#define _MT7621_H_ > > + > > +#define SYSCTL_BASE 0x1e000000 > > +#define SYSCTL_SIZE 0x100 > > +#define TIMER_BASE 0x1e000100 > > +#define TIMER_SIZE 0x100 > > +#define RBUS_BASE 0x1e000400 > > +#define RBUS_SIZE 0x100 > > +#define GPIO_BASE 0x1e000600 > > +#define GPIO_SIZE 0x100 > > +#define DMA_CFG_ARB_BASE 0x1e000800 > > +#define DMA_CFG_ARB_SIZE 0x100 > > +#define SPI_BASE 0x1e000b00 > > +#define SPI_SIZE 0x100 > > +#define UART1_BASE 0x1e000c00 > > +#define UART1_SIZE 0x100 > > +#define UART2_BASE 0x1e000d00 > > +#define UART2_SIZE 0x100 > > +#define UART3_BASE 0x1e000e00 > > +#define UART3_SIZE 0x100 > > +#define NFI_BASE 0x1e003000 > > +#define NFI_SIZE 0x800 > > +#define NFI_ECC_BASE 0x1e003800 > > +#define NFI_ECC_SIZE 0x800 > > +#define DRAMC_BASE 0x1e005000 > > +#define DRAMC_SIZE 0x1000 > > +#define FE_BASE 0x1e100000 > > +#define FE_SIZE 0xe000 > > +#define GMAC_BASE 0x1e110000 > > +#define GMAC_SIZE 0x8000 > > +#define SSUSB_BASE 0x1e1c0000 > > +#define SSUSB_SIZE 0x40000 > > + > > + /* GIC Base Address */ > > +#define MIPS_GIC_BASE 0x1fbc0000 > > + > > + /* CPC Base Address */ > > +#define MIPS_CPC_BASE 0x1fbf0000 > > + > > + /* Flash Memory-mapped Base Address */ > > +#define FLASH_MMAP_BASE 0x1fc00000 > > +#define TPL_INFO_OFFSET 0x40 > > +#define TPL_INFO_MAGIC 0x31323637 > > /* Magic "7621" */ > > + > > +/* SRAM */ > > +#define FE_SRAM_BASE1 0x8000 > > +#define FE_SRAM_BASE2 0xa000 > > + > > +/* SYSCTL_BASE */ > > +#define SYSCTL_CHIP_REV_ID_REG 0x0c > > +#define CPU_ID 0x20000 > > +#define PKG_ID 0x10000 > > +#define VER_ID_S 8 > > +#define VER_ID_M 0xf00 > > +#define ECO_ID_S 0 > > +#define ECO_ID_M 0x0f > > + > > +#define SYSCTL_SYSCFG0_REG 0x10 > > +#define XTAL_MODE_SEL_S 6 > > +#define XTAL_MODE_SEL_M 0x1c0 > > +#define DRAM_TYPE 0x10 > > +#define CHIP_MODE_S 0 > > +#define CHIP_MODE_M 0x0f > > + > > +#define BOOT_SRAM_BASE_REG 0x20 > > + > > +#define SYSCTL_CLKCFG0_REG 0x2c > > +#define CPU_CLK_SEL_S 30 > > +#define CPU_CLK_SEL_M 0xc0000000 > > +#define MPLL_CFG_SEL_S 23 > > +#define MPLL_CFG_SEL_M 0x800000 > > + > > +#define SYSCTL_RSTCTL_REG 0x34 > > +#define MCM_RST 0x04 > > +#define SYS_RST 0x01 > > + > > +#define SYSCTL_CUR_CLK_STS_REG 0x44 > > +#define CUR_CPU_FDIV_S 8 > > +#define CUR_CPU_FDIV_M 0x1f00 > > +#define CUR_CPU_FFRAC_S 0 > > +#define CUR_CPU_FFRAC_M 0x1f > > + > > +#define SYSCTL_GPIOMODE_REG 0x60 > > +#define UART2_MODE_S 5 > > +#define UART2_MODE_M 0x60 > > +#define UART3_MODE_S 3 > > +#define UART3_MODE_M 0x18 > > +#define UART1_MODE 0x02 > > + > > +/* RBUS_BASE */ > > +#define RBUS_DYN_CFG0_REG 0x0010 > > +#define CPU_FDIV_S 8 > > +#define CPU_FDIV_M 0x1f00 > > +#define CPU_FFRAC_S 0 > > +#define CPU_FFRAC_M 0x1f > > + > > +/* DMA_CFG_ARB_BASE */ > > +#define DMA_ROUTE_REG 0x000c > > + > > +/* SPI_BASE */ > > +#define SPI_SPACE_REG 0x003c > > +#define FS_SLAVE_SEL_S 12 > > +#define FS_SLAVE_SEL_M 0x70000 > > +#define FS_CLK_SEL_S 0 > > +#define FS_CLK_SEL_M 0xfff > > + > > +/* FE_BASE */ > > +#define FE_RST_GLO_REG 0x0004 > > +#define FE_PSE_RAM 0x04 > > +#define FE_PSE_MEM_EN 0x02 > > +#define FE_PSE_RESET 0x01 > > + > > +/* SSUSB_BASE */ > > +#define SSUSB_MAC_CK_CTRL_REG 0x10784 > > +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S 16 > > +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M 0xff0000 > > +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S 8 > > +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M 0xff00 > > +#define SSUSB_MAC3_SYS_CK_GATE_MODE_S 2 > > +#define SSUSB_MAC3_SYS_CK_GATE_MODE_M 0x0c > > +#define SSUSB_MAC2_SYS_CK_GATE_MODE_S 0 > > +#define SSUSB_MAC2_SYS_CK_GATE_MODE_M 0x03 > > + > > +#define SSUSB_B2_ROSC_0_REG 0x10a40 > > +#define SSUSB_RING_OSC_CNTEND_S 23 > > +#define SSUSB_RING_OSC_CNTEND_M 0xff800000 > > +#define SSUSB_XTAL_OSC_CNTEND_S 16 > > +#define SSUSB_XTAL_OSC_CNTEND_M 0x7f0000 > > +#define SSUSB_RING_BYPASS_DET 0x01 > > + > > +#define SSUSB_B2_ROSC_1_REG 0x10a44 > > +#define SSUSB_RING_OSC_FRC_RECAL_S 17 > > +#define SSUSB_RING_OSC_FRC_RECAL_M 0x60000 > > +#define SSUSB_RING_OSC_FRC_SEL 0x01 > > + > > +#define SSUSB_U3PHYA_1_REG 0x10b04 > > +#define SSUSB_PCIE_CLKDRV_AMP_S 27 > > +#define SSUSB_PCIE_CLKDRV_AMP_M 0x38000000 > > +#define SSUSB_SYSPLL_FBSEL_S 2 > > +#define SSUSB_SYSPLL_FBSEL_M 0x0c > > +#define SSUSB_SYSPLL_PREDIV_S 0 > > +#define SSUSB_SYSPLL_PREDIV_M 0x03 > > + > > +#define SSUSB_U3PHYA_2_REG 0x10b08 > > +#define SSUSB_SYSPLL_FBDIV_S 24 > > +#define SSUSB_SYSPLL_FBDIV_M 0x7f000000 > > +#define SSUSB_SYSPLL_VCO_DIV_SEL 0x200000 > > +#define SSUSB_SYSPLL_FPEN 0x2000 > > +#define SSUSB_SYSPLL_MONCK_EN 0x1000 > > +#define SSUSB_SYSPLL_VOD_EN 0x200 > > + > > +#define SSUSB_U3PHYA_3_REG 0x10b10 > > +#define SSUSB_SYSPLL_PCW_NCPO_S 1 > > +#define SSUSB_SYSPLL_PCW_NCPO_M 0xfffffffe > > + > > +#define SSUSB_U3PHYA_9_REG 0x10b24 > > +#define SSUSB_PLL_SSC_PRD_S 0 > > +#define SSUSB_PLL_SSC_PRD_M 0xffff > > + > > +#define SSUSB_U3PHYA_11_REG 0x10b2c > > +#define SSUSB_EQ_CURSEL 0x1000000 > > +#define SSUSB_RX_DAC_MUX_S 19 > > +#define SSUSB_RX_DAC_MUX_M 0xf80000 > > +#define SSUSB_PCIE_SIGDET_VTH_S 5 > > +#define SSUSB_PCIE_SIGDET_VTH_M 0x60 > > +#define SSUSB_PCIE_SIGDET_LPF_S 3 > > +#define SSUSB_PCIE_SIGDET_LPF_M 0x18 > > + > > +#define DA_SSUSB_PLL_FBKDIV_REG 0x10c1c > > +#define SSUSB_PLL_FBKDIV_PE2H_S 24 > > +#define SSUSB_PLL_FBKDIV_PE2H_M 0x7f000000 > > +#define SSUSB_PLL_FBKDIV_PE1D_S 16 > > +#define SSUSB_PLL_FBKDIV_PE1D_M 0x7f0000 > > +#define SSUSB_PLL_FBKDIV_PE1H_S 8 > > +#define SSUSB_PLL_FBKDIV_PE1H_M 0x7f00 > > +#define SSUSB_PLL_FBKDIV_U3_S 0 > > +#define SSUSB_PLL_FBKDIV_U3_M 0x7f > > + > > +#define DA_SSUSB_U3PHYA_10_REG 0x10c20 > > +#define SSUSB_PLL_PREDIV_PE1D_S 18 > > +#define SSUSB_PLL_PREDIV_PE1D_M 0xc0000 > > +#define SSUSB_PLL_PREDIV_U3_S 8 > > +#define SSUSB_PLL_PREDIV_U3_M 0x300 > > +#define SSUSB_PLL_FBKDI_S 0 > > +#define SSUSB_PLL_FBKDI_M 0x07 > > + > > +#define DA_SSUSB_PLL_PCW_NCPO_REG 0x10c24 > > +#define SSUSB_PLL_PCW_NCPO_U3_S 0 > > +#define SSUSB_PLL_PCW_NCPO_U3_M 0x7fffffff > > + > > +#define DA_SSUSB_PLL_SSC_DELTA1_REG 0x10c38 > > +#define SSUSB_PLL_SSC_DELTA1_PE1H_S 16 > > +#define SSUSB_PLL_SSC_DELTA1_PE1H_M 0xffff0000 > > +#define SSUSB_PLL_SSC_DELTA1_U3_S 0 > > +#define SSUSB_PLL_SSC_DELTA1_U3_M 0xffff > > + > > +#define DA_SSUSB_U3PHYA_21_REG 0x10c40 > > +#define SSUSB_PLL_SSC_DELTA_U3_S 16 > > +#define SSUSB_PLL_SSC_DELTA_U3_M 0xffff0000 > > +#define SSUSB_PLL_SSC_DELTA1_PE2D_S 0 > > +#define SSUSB_PLL_SSC_DELTA1_PE2D_M 0xffff > > + > > +/* MT7621 specific CM values */ > > + > > +/* GCR_REGx_BASE */ > > +#define GCR_REG0_BASE_VALUE 0x1c000000 > > +#define GCR_REG1_BASE_VALUE 0x60000000 > > +#define GCR_REG2_BASE_VALUE 0x1c000000 > > +#define GCR_REG3_BASE_VALUE 0x1c000000 > > + > > +/* GCR_REGx_MASK */ > > +#define GCR_REG0_MASK_VALUE 0x0000fc00 /* > > 64M Bus */ > > +#define GCR_REG1_MASK_VALUE 0x0000f000 /* > > 256M PCI Mem */ > > +#define GCR_REG2_MASK_VALUE 0x0000fc00 /* > > unused */ > > +#define GCR_REG3_MASK_VALUE 0x0000fc00 /* > > unused */ > > + > > +#ifndef __ASSEMBLY__ > > +unsigned long get_xtal_mhz(void); > > +#endif > > + > > +#endif /* _MT7621_H_ */ > > diff --git a/arch/mips/mach-mtmips/mt7621/serial.c > > b/arch/mips/mach-mtmips/mt7621/serial.c > > new file mode 100644 > > index 0000000000..0ccc71dc75 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/serial.c > > @@ -0,0 +1,23 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <asm/io.h> > > +#include <asm/addrspace.h> > > +#include "mt7621.h" > > + > > +void board_debug_uart_init(void) > > +{ > > + void __iomem *base = ioremap_nocache(SYSCTL_BASE, > > SYSCTL_SIZE); > > + > > +#if CONFIG_DEBUG_UART_BASE == 0xbe000c00 /* KSEG1ADDR(UART1_BASE) > > */ > > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE); > > +#elif CONFIG_DEBUG_UART_BASE == 0xbe000d00 /* > > KSEG1ADDR(UART2_BASE) */ > > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M); > > +#elif CONFIG_DEBUG_UART_BASE == 0xbe000e00 /* > > KSEG1ADDR(UART3_BASE) */ > > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M); > > +#endif > > +} > > diff --git a/arch/mips/mach-mtmips/mt7621/spl/Makefile > > b/arch/mips/mach-mtmips/mt7621/spl/Makefile > > new file mode 100644 > > index 0000000000..ebe54e79b9 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/spl/Makefile > > @@ -0,0 +1,9 @@ > > + > > +extra-y += start.o > > + > > +obj-y += spl.o > > +obj-y += cps.o > > +obj-y += dram.o > > +obj-y += serial.o > > +obj-y += launch.o > > +obj-y += launch_ll.o > > diff --git a/arch/mips/mach-mtmips/mt7621/spl/cps.c > > b/arch/mips/mach-mtmips/mt7621/spl/cps.c > > new file mode 100644 > > index 0000000000..61f319f45f > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/spl/cps.c > > @@ -0,0 +1,152 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <asm/io.h> > > +#include <asm/addrspace.h> > > +#include <asm/mipsregs.h> > > +#include <asm/cm.h> > > +#include "../mt7621.h" > > + > > +/* GIC Shared Register Bases */ > > +#define GIC_SH_POL_BASE 0x100 > > +#define GIC_SH_TRIG_BASE 0x180 > > +#define GIC_SH_RMASK_BASE 0x300 > > +#define GIC_SH_SMASK_BASE 0x380 > > +#define GIC_SH_MASK_BASE 0x400 > > +#define GIC_SH_PEND_BASE 0x480 > > +#define GIC_SH_MAP_PIN_BASE 0x500 > > +#define GIC_SH_MAP_VPE_BASE 0x2000 > > + > > +/* GIC Registers */ > > +#define GIC_SH_POL31_0 (GIC_SH_POL_BASE + 0x00) > > +#define GIC_SH_POL63_32 (GIC_SH_POL_BASE + 0x04) > > + > > +#define GIC_SH_TRIG31_0 (GIC_SH_TRIG_BASE + 0x00) > > +#define GIC_SH_TRIG63_32 (GIC_SH_TRIG_BASE + 0x04) > > + > > +#define GIC_SH_RMASK31_0 (GIC_SH_RMASK_BASE + 0x00) > > +#define GIC_SH_RMASK63_32 (GIC_SH_RMASK_BASE + 0x04) > > + > > +#define GIC_SH_SMASK31_0 (GIC_SH_SMASK_BASE + 0x00) > > +#define GIC_SH_SMASK63_32 (GIC_SH_SMASK_BASE + 0x04) > > + > > +#define GIC_SH_MAP_PIN(n) (GIC_SH_MAP_PIN_BASE + (n) * 4) > > + > > +#define GIC_SH_MAP_VPE(n, v) (GIC_SH_MAP_VPE_BASE + (n) * > > 0x20 + ((v) / 32) * 4) > > +#define GIC_SH_MAP_VPE31_0(n) GIC_SH_MAP_VPE(n, 0) > > + > > +/* GIC_SH_MAP_PIN fields */ > > +#define GIC_MAP_TO_PIN BIT(31) > > +#define GIC_MAP_TO_NMI BIT(30) > > +#define GIC_MAP GENMASK(5, 0) > > +#define GIC_MAP_SHIFT 0 > > + > > +static void cm_init(void __iomem *cm_base) > > +{ > > + u32 num_cores; > > + > > + num_cores = ((readl(cm_base + GCR_CONFIG) & > > GCR_CONFIG_PCORES) >> > > + GCR_CONFIG_PCORES_SHIFT) + 1; > > + > > + writel((1 << num_cores) - 1, cm_base + GCR_ACCESS); > > + > > + writel(GCR_REG0_BASE_VALUE, cm_base + GCR_REG0_BASE); > > + writel(GCR_REG1_BASE_VALUE, cm_base + GCR_REG1_BASE); > > + writel(GCR_REG2_BASE_VALUE, cm_base + GCR_REG2_BASE); > > + writel(GCR_REG3_BASE_VALUE, cm_base + GCR_REG3_BASE); > > + > > + clrsetbits_32(cm_base + GCR_REG0_MASK, > > + GCR_REGn_MASK_ADDRMASK | > > GCR_REGn_MASK_CMTGT, > > + (GCR_REG0_MASK_VALUE << > > GCR_REGn_MASK_ADDRMASK_SHIFT) | > > + GCR_REGn_MASK_CMTGT_IOCU0); > > + > > + clrsetbits_32(cm_base + GCR_REG1_MASK, > > + GCR_REGn_MASK_ADDRMASK | > > GCR_REGn_MASK_CMTGT, > > + (GCR_REG1_MASK_VALUE << > > GCR_REGn_MASK_ADDRMASK_SHIFT) | > > + GCR_REGn_MASK_CMTGT_IOCU0); > > + > > + clrsetbits_32(cm_base + GCR_REG2_MASK, > > + GCR_REGn_MASK_ADDRMASK | > > GCR_REGn_MASK_CMTGT, > > + (GCR_REG2_MASK_VALUE << > > GCR_REGn_MASK_ADDRMASK_SHIFT) | > > + GCR_REGn_MASK_CMTGT_IOCU0); > > + > > + clrsetbits_32(cm_base + GCR_REG3_MASK, > > + GCR_REGn_MASK_ADDRMASK | > > GCR_REGn_MASK_CMTGT, > > + (GCR_REG3_MASK_VALUE << > > GCR_REGn_MASK_ADDRMASK_SHIFT) | > > + GCR_REGn_MASK_CMTGT_IOCU0); > > + > > + clrbits_32(cm_base + GCR_BASE, CM_DEFAULT_TARGET_MASK); > > + setbits_32(cm_base + GCR_CONTROL, GCR_CONTROL_SYNCCTL); > > +} > > + > > +static void gic_init(void) > > +{ > > + void __iomem *gic_base = (void *)KSEG1ADDR(MIPS_GIC_BASE); > > + int i; > > + > > + /* Interrupt 0..5: Level Trigger, Active High */ > > + writel(0, gic_base + GIC_SH_TRIG31_0); > > + writel(0x3f, gic_base + GIC_SH_RMASK31_0); > > + writel(0x3f, gic_base + GIC_SH_POL31_0); > > + writel(0x3f, gic_base + GIC_SH_SMASK31_0); > > + > > + /* Interrupt 56..63: Edge Trigger, Rising Edge */ > > + /* Hardcoded to set up the last 8 external interrupts for > > IPI. */ > > + writel(0xff000000, gic_base + GIC_SH_TRIG63_32); > > + writel(0xff000000, gic_base + GIC_SH_RMASK63_32); > > + writel(0xff000000, gic_base + GIC_SH_POL63_32); > > + writel(0xff000000, gic_base + GIC_SH_SMASK63_32); > > + > > + /* Map interrupt source to particular hardware interrupt > > pin */ > > + /* source {0,1,2,3,4,5} -> pin {0,0,4,3,0,5} */ > > + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(0)); > > + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(1)); > > + writel(GIC_MAP_TO_PIN | 4, gic_base + GIC_SH_MAP_PIN(2)); > > + writel(GIC_MAP_TO_PIN | 3, gic_base + GIC_SH_MAP_PIN(3)); > > + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(4)); > > + writel(GIC_MAP_TO_PIN | 5, gic_base + GIC_SH_MAP_PIN(5)); > > + > > + /* source 56~59 -> pin 1, 60~63 -> pin 2 */ > > + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(56)); > > + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(57)); > > + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(58)); > > + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(59)); > > + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(60)); > > + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(61)); > > + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(62)); > > + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(63)); > > + > > + /* Interrupt map to VPE (bit mask) */ > > + for (i = 0; i < 32; i++) > > + writel(BIT(0), gic_base + GIC_SH_MAP_VPE31_0(i)); > > + > > + /* > > + * Direct GIC_int 56..63 to vpe 0..3 > > + * MIPS Linux convention that last 16 interrupts > > implemented be set > > + * aside for IPI signaling. > > + * The actual interrupts are tied low and software sends > > interrupts > > + * via GIC_SH_WEDGE writes. > > + */ > > + for (i = 0; i < 4; i++) { > > + writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + > > 56)); > > + writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + > > 60)); > > + } > > +} > > + > > +void mt7621_cps_init(void) > > +{ > > + void __iomem *cm_base = (void > > *)KSEG1ADDR(CONFIG_MIPS_CM_BASE); > > + > > + /* Enable GIC */ > > + writel(MIPS_GIC_BASE | GCR_GIC_EN, cm_base + > > GCR_GIC_BASE); > > + > > + /* Enable CPC */ > > + writel(MIPS_CPC_BASE | GCR_CPC_EN, cm_base + > > GCR_CPC_BASE); > > + > > + gic_init(); > > + cm_init(cm_base); > > +} > > diff --git a/arch/mips/mach-mtmips/mt7621/spl/dram.c > > b/arch/mips/mach-mtmips/mt7621/spl/dram.c > > new file mode 100644 > > index 0000000000..6c3b501ae5 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.c > > @@ -0,0 +1,143 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <asm/io.h> > > +#include <asm/sections.h> > > +#include <asm/byteorder.h> > > +#include <asm/addrspace.h> > > +#include <linux/string.h> > > +#include "../mt7621.h" > > +#include "dram.h" > > + > > +static const u32 ddr2_act[24] = { > > +#if defined(CONFIG_MT7621_DRAM_DDR2_512M) > > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174441, > > + 0x00000000, 0xF0748661, 0x40001273, 0x9F0A0481, > > + 0x0304692F, 0x15602842, 0x00008888, 0x88888888, > > + 0x00000000, 0x00000000, 0x00000000, 0x07100000, > > + 0x00001B63, 0x00002000, 0x00004000, 0x00006000, > > + 0x00000000, 0x00000000, 0x00000000, 0x00000000, > > +#elif defined(CONFIG_MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ) > > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x33484584, > > + 0x00000000, 0xF07486A1, 0x50001273, 0x9F010481, > > + 0x0304693F, 0x15602842, 0x00008888, 0x88888888, > > + 0x00000000, 0x00000000, 0x00000010, 0x07100000, > > + 0x00001F73, 0x00002000, 0x00004000, 0x00006000, > > + 0x00000000, 0x00000000, 0x00000000, 0x00000000, > > +#elif defined(CONFIG_MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ) > > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174430, > > + 0x01000000, 0xF0748661, 0x40001273, 0x9F0F0481, > > + 0x0304692F, 0x15602842, 0x00008888, 0x88888888, > > + 0x00000000, 0x00000000, 0x00000000, 0x07100000, > > + 0x00001B63, 0x00002000, 0x00004000, 0x00006000, > > + 0x00000000, 0x00000000, 0x00000000, 0x00000000, > > +#elif defined(CONFIG_MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ) > > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x33484584, > > + 0x01000000, 0xF07486A1, 0x50001273, 0x9F070481, > > + 0x0304693F, 0x15602842, 0x00008888, 0x88888888, > > + 0x00000000, 0x00000000, 0x00000010, 0x07100000, > > + 0x00001F73, 0x00002000, 0x00004000, 0x00006000, > > + 0x00000000, 0x00000000, 0x00000000, 0x00000000, > > +#else /* CONFIG_MT7621_DRAM_DDR2_1024M */ > > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174441, > > + 0x01000000, 0xF0748661, 0x40001273, 0x9F0F0481, > > + 0x0304692F, 0x15602842, 0x00008888, 0x88888888, > > + 0x00000000, 0x00000000, 0x00000000, 0x07100000, > > + 0x00001B63, 0x00002000, 0x00004000, 0x00006000, > > + 0x00000000, 0x00000000, 0x00000000, 0x00000000, > > +#endif > > +}; > > + > > +static const u32 ddr3_act[24] = { > > +#if defined(CONFIG_MT7621_DRAM_DDR3_1024M) > > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694683, > > + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F060481, > > + 0x03046948, 0x15602842, 0x00008888, 0x88888888, > > + 0x00000000, 0x00000000, 0x00000210, 0x07100000, > > + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, > > + 0x0C000000, 0x07070000, 0x00000000, 0x00000000, > > +#elif defined(CONFIG_MT7621_DRAM_DDR3_4096M) > > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694683, > > + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F0F0481, > > + 0x03046948, 0x15602842, 0x00008888, 0x88888888, > > + 0x00000000, 0x00000000, 0x00000240, 0x07100000, > > + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, > > + 0x0C000000, 0x07070000, 0x00000000, 0x00000000, > > +#elif defined(CONFIG_MT7621_DRAM_DDR3_1024M_KGD) > > + 0xFF00FF00, 0xFF00FF00, 0x00000007, 0x44694683, > > + 0x01000000, 0xF07406A1, 0xC287221D, 0x9F060481, > > + 0x03046923, 0x152f2842, 0x00008888, 0x88888888, > > + 0x00000000, 0x00000000, 0x00000210, 0x07100000, > > + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, > > + 0x0C000000, 0x07070000, 0x000C0000, 0x00000000, > > +#else /* CONFIG_MT7621_DRAM_DDR3_2048M */ > > + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694673, > > + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F050481, > > + 0x03046948, 0x15602842, 0x00008888, 0x88888888, > > + 0x00000000, 0x00000000, 0x00000220, 0x07100000, > > + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, > > + 0x0C000000, 0x07070000, 0x00000000, 0x00000000, > > +#endif > > +}; > > + > > +#if defined(CONFIG_MT7621_DRAM_FREQ_400) > > +#define DDR_FREQ_PARAM 0x41000000 > > +#elif defined(CONFIG_MT7621_DRAM_FREQ_1066) > > +#define DDR_FREQ_PARAM 0x21000000 > > +#elif defined(CONFIG_MT7621_DRAM_FREQ_1200) > > +#define DDR_FREQ_PARAM 0x11000000 > > +#else /* CONFIG_MT7621_DRAM_FREQ_800 */ > > +#define DDR_FREQ_PARAM 0x31000000 > > +#endif > > + > > +#define RG_MEPL_FBDIV_S 4 > > +#define RG_MEPL_FBDIV_M 0x7f > > + > > +static u32 calc_cpu_pll_val(void) > > +{ > > + u32 div, baseval, fb; > > + > > + div = get_xtal_mhz(); > > + > > + if (div == 40) { > > + div /= 2; > > + baseval = 0xc0005802; > > + } else { > > + baseval = 0xc0004802; > > + } > > + > > + fb = CONFIG_MT7621_CPU_FREQ / div - 1; > > + if (fb > RG_MEPL_FBDIV_M) > > + fb = RG_MEPL_FBDIV_M; > > + > > + return baseval | (fb << RG_MEPL_FBDIV_S); > > +} > > + > > +void prepare_stage_bin(void) > > +{ > > + const struct stage_header *stock_stage_bin = > > + (const struct stage_header *)__image_copy_end; > > + > > + struct stage_header *new_stage_bin = > > + (struct stage_header *)STAGE_LOAD_ADDR; > > + > > + if (be32_to_cpu(stock_stage_bin->ep) != STAGE_LOAD_ADDR) { > > + /* Possible wrong binary blob. Hang here */ > > + for (;;) > > + ; > > + } > > + > > + memcpy(new_stage_bin, stock_stage_bin, > > + be32_to_cpu(stock_stage_bin->stage_size)); > > + > > + memcpy(new_stage_bin->ddr2_act, ddr2_act, > > sizeof(ddr2_act)); > > + memcpy(new_stage_bin->ddr3_act, ddr3_act, > > sizeof(ddr3_act)); > > + > > + new_stage_bin->cpu_pll_cfg = calc_cpu_pll_val(); > > + new_stage_bin->ddr_pll_cfg = DDR_FREQ_PARAM; > > + new_stage_bin->baudrate = CONFIG_BAUDRATE; > > +} > > diff --git a/arch/mips/mach-mtmips/mt7621/spl/dram.h > > b/arch/mips/mach-mtmips/mt7621/spl/dram.h > > new file mode 100644 > > index 0000000000..4ca66644ef > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.h > > @@ -0,0 +1,37 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#ifndef _MT7621_DRAM_H_ > > +#define _MT7621_DRAM_H_ > > + > > +#define STAGE_LOAD_ADDR 0xBE108800 > > + > > +#ifndef __ASSEMBLY__ > > +#include <linux/types.h> > > + > > +struct stage_header { > > + u32 jump_insn[2]; > > + u32 ep; > > + u32 stage_size; > > + u32 has_stage2; > > + u32 next_ep; > > + u32 next_size; > > + u32 next_offset; > > + u32 cpu_pll_cfg; > > + u32 ddr_pll_cfg; > > + u32 reserved2[6]; > > + char build_tag[32]; > > + u32 ddr3_act[24]; > > + u32 padding1[2]; > > + u32 ddr2_act[24]; > > + u32 padding2[2]; > > + u32 baudrate; > > + u32 padding3; > > +}; > > +#endif > > + > > +#endif /* _MT7621_DRAM_H_ */ > > diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch.c > > b/arch/mips/mach-mtmips/mt7621/spl/launch.c > > new file mode 100644 > > index 0000000000..37c20a5f56 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.c > > @@ -0,0 +1,100 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <asm/io.h> > > +#include <asm/cm.h> > > +#include <asm/sections.h> > > +#include <asm/addrspace.h> > > +#include <asm/mipsmtregs.h> > > +#include <linux/sizes.h> > > +#include <time.h> > > +#include <cpu_func.h> > > +#include "launch.h" > > +#include "../mt7621.h" > > + > > +/* Cluster Power Controller (CPC) offsets */ > > +#define CPC_CL_OTHER 0x2010 > > +#define CPC_CO_CMD 0x4000 > > + > > +/* CPC_CL_OTHER fields */ > > +#define CPC_CL_OTHER_CORENUM_SHIFT 16 > > +#define CPC_CL_OTHER_CORENUM GENMASK(23, 16) > > + > > +/* CPC_CO_CMD */ > > +#define PWR_UP 3 > > + > > +#define NUM_CORES 2 > > +#define NUM_CPUS 4 > > +#define WAIT_CPUS_TIMEOUT 4000 > > + > > +static void copy_launch_wait_code(void) > > +{ > > + memset((void *)KSEG1, 0, SZ_4K); > > + > > + memcpy((void *)KSEG1ADDR(LAUNCH_WAITCODE), > > + &launch_wait_code_start, > > + &launch_wait_code_end - &launch_wait_code_start); > > + > > + invalidate_dcache_range(KSEG0, SZ_4K); > > +} > > + > > +static void bootup_secondary_core(void) > > +{ > > + void __iomem *cpcbase = (void __iomem > > *)KSEG1ADDR(MIPS_CPC_BASE); > > + int i; > > + > > + for (i = 1; i < NUM_CORES; i++) { > > + writel(i << CPC_CL_OTHER_CORENUM_SHIFT, cpcbase + > > CPC_CL_OTHER); > > + writel(PWR_UP, cpcbase + CPC_CO_CMD); > > + } > > +} > > + > > +void secondary_cpu_init(void) > > +{ > > + void __iomem *sysc = (void __iomem > > *)KSEG1ADDR(SYSCTL_BASE); > > + u32 i, dual_core = 0, cpuready = 1, cpumask = 0x03; > > + ulong wait_tick; > > + struct cpulaunch_t *c; > > + > > + /* Copy LAUNCH wait code used by other VPEs */ > > + copy_launch_wait_code(); > > + > > + dual_core = readl(sysc + SYSCTL_CHIP_REV_ID_REG) & CPU_ID; > > + > > + if (dual_core) { > > + /* Bootup secondary core for MT7621A */ > > + cpumask = 0x0f; > > + > > + /* Make BootROM/TPL redirect Core1's bootup flow > > to our entry point */ > > + writel((uintptr_t)&_start, sysc + > > BOOT_SRAM_BASE_REG); > > + > > + bootup_secondary_core(); > > + } > > + > > + /* Join the coherent domain */ > > + join_coherent_domain(dual_core ? 2 : 1); > > + > > + /* Bootup Core0/VPE1 */ > > + boot_vpe1(); > > + > > + /* Wait for all CPU ready */ > > + wait_tick = get_timer(0) + WAIT_CPUS_TIMEOUT; > > + > > + while (time_before(get_timer(0), wait_tick)) { > > + /* CPU0 is obviously ready */ > > + for (i = 1; i < NUM_CPUS; i++) { > > + c = (struct cpulaunch_t > > *)(KSEG0ADDR(CPULAUNCH) + > > + (i << > > LOG2CPULAUNCH)); > > + > > + if (c->flags & LAUNCH_FREADY) > > + cpuready |= BIT(i); > > + } > > + > > + if ((cpuready & cpumask) == cpumask) > > + break; > > + } > > +} > > diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch.h > > b/arch/mips/mach-mtmips/mt7621/spl/launch.h > > new file mode 100644 > > index 0000000000..f34250d605 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.h > > @@ -0,0 +1,52 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#ifndef _LAUNCH_H_ > > +#define _LAUNCH_H_ > > + > > +#ifndef __ASSEMBLY__ > > + > > +struct cpulaunch_t { > > + unsigned long pc; > > + unsigned long gp; > > + unsigned long sp; > > + unsigned long a0; > > + unsigned long _pad[3]; /* pad to cache line size to avoid > > thrashing */ > > + unsigned long flags; > > +}; > > + > > +extern char launch_wait_code_start; > > +extern char launch_wait_code_end; > > + > > +void join_coherent_domain(int ncores); > > +void boot_vpe1(void); > > + > > +#else > > + > > +#define LAUNCH_PC 0 > > +#define LAUNCH_GP 4 > > +#define LAUNCH_SP 8 > > +#define LAUNCH_A0 12 > > +#define LAUNCH_FLAGS 28 > > + > > +#endif > > + > > +#define LOG2CPULAUNCH 5 > > + > > +#define LAUNCH_FREADY 1 > > +#define LAUNCH_FGO 2 > > +#define LAUNCH_FGONE 4 > > + > > +#define LAUNCH_WAITCODE 0x00000d00 > > +#define SCRLAUNCH 0x00000e00 > > +#define CPULAUNCH 0x00000f00 > > +#define NCPULAUNCH 8 > > + > > +/* Polling period in count cycles for secondary CPU's */ > > +#define LAUNCHPERIOD 10000 > > + > > +#endif /* _LAUNCH_H_ */ > > diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S > > b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S > > new file mode 100644 > > index 0000000000..55a8fff9af > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S > > @@ -0,0 +1,357 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <asm/cm.h> > > +#include <asm/asm.h> > > +#include <asm/regdef.h> > > +#include <asm/cacheops.h> > > +#include <asm/mipsregs.h> > > +#include <asm/addrspace.h> > > +#include <asm/mipsmtregs.h> > > +#include "launch.h" > > + > > + .macro cache_loop curr, end, line_sz, op > > +10: cache \op, 0(\curr) > > + PTR_ADDU \curr, \curr, \line_sz > > + bne \curr, \end, 10b > > + .endm > > + > > + .set mt > > + > > +/* > > + * Join the coherent domain > > + * a0 = number of cores > > + */ > > +LEAF(join_coherent_domain) > > + /* > > + * Enable coherence and allow interventions from all other > > cores. > > + * (Write access enabled via GCR_ACCESS by core 0.) > > + */ > > + li t1, 1 > > + sll t1, a0 > > + addiu t1, -1 > > + > > + li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE) > > + sw t1, GCR_Cx_COHERENCE(t0) > > + ehb > > + > > + move t2, zero > > + > > +_next_coherent_core: > > + sll t1, t2, GCR_Cx_OTHER_CORENUM_SHIFT > > + sw t1, GCR_Cx_OTHER(t0) > > + > > +_busy_wait_coherent_core: > > + lw t1, GCR_CO_COHERENCE(t0) > > + beqz t1, _busy_wait_coherent_core > > + nop > > + > > + addiu t2, 1 > > + bne t2, a0, _next_coherent_core > > + nop > > + > > + jr ra > > + nop > > + END(join_coherent_domain) > > + > > +/* > > + * All VPEs other than VPE0 will go here. > > + */ > > +LEAF(launch_vpe_entry) > > + mfc0 t0, CP0_EBASE > > + and t0, t0, MIPS_EBASE_CPUNUM > > + > > + /* per-VPE cpulaunch_t */ > > + li a0, KSEG0ADDR(CPULAUNCH) > > + sll t1, t0, LOG2CPULAUNCH > > + addu a0, t1 > > + > > + /* Set CPU online flag */ > > + li t0, LAUNCH_FREADY > > + sw t0, LAUNCH_FLAGS(a0) > > + > > + /* Enable count interrupt in mask, but do not enable > > interrupts */ > > + mfc0 t0, CP0_STATUS > > + ori t0, STATUSF_IP7 > > + mtc0 t0, CP0_STATUS > > + > > + /* VPEs executing in wait code do not need a stack */ > > + li t9, KSEG0ADDR(LAUNCH_WAITCODE) > > + jr t9 > > + nop > > + END(launch_vpe_entry) > > + > > +/* > > + * This function will not be executed in place. > > + * It will be copied into memory, and VPEs other than VPE0 will be > > + * started to run into this in-memory function. > > + */ > > +LEAF(launch_wait_code) > > + .globl launch_wait_code_start > > +launch_wait_code_start: > > + > > + move t0, a0 > > + > > +start_poll: > > + /* Poll CPU go flag */ > > + mtc0 zero, CP0_COUNT > > + li t1, LAUNCHPERIOD > > + mtc0 t1, CP0_COMPARE > > + > > +time_wait: > > + /* Software wait */ > > + mfc0 t2, CP0_COUNT > > + subu t2, t1 > > + bltz t2, time_wait > > + nop > > + > > + /* Check the launch flag */ > > + lw t3, LAUNCH_FLAGS(t0) > > + and t3, LAUNCH_FGO > > + beqz t3, start_poll > > + nop > > + > > + /* Reset the counter and interrupts to give naive clients > > a chance */ > > + mfc0 t1, CP0_STATUS > > + ins t1, zero, STATUSB_IP7, 1 > > + mtc0 t1, CP0_STATUS > > + > > + mfc0 t1, CP0_COUNT > > + subu t1, 1 > > + mtc0 t1, CP0_COMPARE > > + > > + /* Jump to kernel */ > > + lw t9, LAUNCH_PC(t0) > > + lw gp, LAUNCH_GP(t0) > > + lw sp, LAUNCH_SP(t0) > > + lw a0, LAUNCH_A0(t0) > > + move a1, zero > > + move a2, zero > > + move a3, zero > > + ori t3, LAUNCH_FGONE > > + sw t3, LAUNCH_FLAGS(t0) > > + > > + jr t9 > > + nop > > + > > + .globl launch_wait_code_end > > +launch_wait_code_end: > > + END(launch_wait_code) > > + > > +/* > > + * Core1 will go here. > > + */ > > +LEAF(launch_core_entry) > > + /* Disable caches */ > > + bal mips_cache_disable > > + nop > > + > > + /* Initialize L1 cache only */ > > + li a0, CONFIG_SYS_ICACHE_SIZE > > + li a1, CONFIG_SYS_ICACHE_LINE_SIZE > > + li a2, CONFIG_SYS_DCACHE_SIZE > > + li a3, CONFIG_SYS_DCACHE_LINE_SIZE > > + > > + mtc0 zero, CP0_TAGLO > > + mtc0 zero, CP0_TAGLO, 2 > > + ehb > > + > > + /* > > + * Initialize the I-cache first, > > + */ > > + li t0, KSEG0 > > + addu t1, t0, a0 > > + /* clear tag to invalidate */ > > + cache_loop t0, t1, a1, INDEX_STORE_TAG_I > > +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD > > + /* fill once, so data field parity is correct */ > > + PTR_LI t0, KSEG0 > > + cache_loop t0, t1, a1, FILL > > + /* invalidate again - prudent but not strictly necessary > > */ > > + PTR_LI t0, KSEG0 > > + cache_loop t0, t1, a1, INDEX_STORE_TAG_I > > +#endif > > + > > + /* > > + * then initialize D-cache. > > + */ > > + PTR_LI t0, KSEG0 > > + PTR_ADDU t1, t0, a2 > > + /* clear all tags */ > > + cache_loop t0, t1, a3, INDEX_STORE_TAG_D > > +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD > > + /* load from each line (in cached space) */ > > + PTR_LI t0, KSEG0 > > +2: LONG_L zero, 0(t0) > > + PTR_ADDU t0, a3 > > + bne t0, t1, 2b > > + /* clear all tags */ > > + PTR_LI t0, KSEG0 > > + cache_loop t0, t1, a3, INDEX_STORE_TAG_D > > +#endif > > + > > + /* Set Cache Mode */ > > + mfc0 t0, CP0_CONFIG > > + li t1, CONF_CM_CACHABLE_COW > > + ins t0, t1, 0, 3 > > + mtc0 t0, CP0_CONFIG > > + > > + /* Join the coherent domain */ > > + li a0, 2 > > + bal join_coherent_domain > > + nop > > + > > + /* Bootup Core0/VPE1 */ > > + bal boot_vpe1 > > + nop > > + > > + b launch_vpe_entry > > + nop > > + END(launch_core_entry) > > + > > +/* > > + * Bootup VPE1. > > + * This subroutine must be executed from VPE0 with VPECONF0[MVP] > > already set. > > + */ > > +LEAF(boot_vpe1) > > + mfc0 t0, CP0_MVPCONF0 > > + > > + /* a0 = number of TCs - 1 */ > > + ext a0, t0, MVPCONF0_PTC_SHIFT, 8 > > + beqz a0, _vpe1_init_done > > + nop > > + > > + /* a1 = number of VPEs - 1 */ > > + ext a1, t0, MVPCONF0_PVPE_SHIFT, 4 > > + beqz a1, _vpe1_init_done > > + nop > > + > > + /* a2 = current TC No. */ > > + move a2, zero > > + > > + /* Enter VPE Configuration State */ > > + mfc0 t0, CP0_MVPCONTROL > > + or t0, MVPCONTROL_VPC > > + mtc0 t0, CP0_MVPCONTROL > > + ehb > > + > > +_next_tc: > > + /* Set the TC number to be used on MTTR and MFTR > > instructions */ > > + mfc0 t0, CP0_VPECONTROL > > + ins t0, a2, 0, 8 > > + mtc0 t0, CP0_VPECONTROL > > + ehb > > + > > + /* TC0 is already bound */ > > + beqz a2, _next_vpe > > + nop > > + > > + /* Halt current TC */ > > + li t0, TCHALT_H > > + mttc0 t0, CP0_TCHALT > > + ehb > > + > > + /* If there is spare TC, bind it to the last VPE (VPE[a1]) > > */ > > + slt t1, a1, a2 > > + bnez t1, _vpe_bind_tc > > + move t1, a1 > > + > > + /* Set Exclusive TC for active TC */ > > + mftc0 t0, CP0_VPECONF0 > > + ins t0, a2, VPECONF0_XTC_SHIFT, 8 > > + mttc0 t0, CP0_VPECONF0 > > + > > + move t1, a2 > > +_vpe_bind_tc: > > + /* Bind TC to a VPE */ > > + mftc0 t0, CP0_TCBIND > > + ins t0, t1, TCBIND_CURVPE_SHIFT, 4 > > + mttc0 t0, CP0_TCBIND > > + > > + /* > > + * Set up CP0_TCSTATUS register: > > + * Disable Coprocessor Usable bits > > + * Disable MDMX/DSP ASE > > + * Clear Dirty TC > > + * not dynamically allocatable > > + * not allocated > > + * Kernel mode > > + * interrupt exempt > > + * ASID 0 > > + */ > > + li t0, TCSTATUS_IXMT > > + mttc0 t0, CP0_TCSTATUS > > + > > +_next_vpe: > > + slt t1, a1, a2 > > + bnez t1, _done_vpe # No more VPEs > > + nop > > + > > + /* Disable TC multi-threading */ > > + mftc0 t0, CP0_VPECONTROL > > + ins t0, zero, VPECONTROL_TE_SHIFT, 1 > > + mttc0 t0, CP0_VPECONTROL > > + > > + /* Skip following configuration for TC0 */ > > + beqz a2, _done_vpe > > + nop > > + > > + /* Deactivate VPE, set Master VPE */ > > + mftc0 t0, CP0_VPECONF0 > > + ins t0, zero, VPECONF0_VPA_SHIFT, 1 > > + or t0, VPECONF0_MVP > > + mttc0 t0, CP0_VPECONF0 > > + > > + mfc0 t0, CP0_STATUS > > + mttc0 t0, CP0_STATUS > > + > > + mttc0 zero, CP0_EPC > > + mttc0 zero, CP0_CAUSE > > + > > + mfc0 t0, CP0_CONFIG > > + mttc0 t0, CP0_CONFIG > > + > > + /* > > + * VPE1 of each core can execute cached as its L1 I$ has > > already > > + * been initialized. > > + * and the L2$ has been initialized or "disabled" via CCA > > override. > > + */ > > + PTR_LA t0, _start > > + mttc0 t0, CP0_TCRESTART > > + > > + /* Unset Interrupt Exempt, set Activate Thread */ > > + mftc0 t0, CP0_TCSTATUS > > + ins t0, zero, TCSTATUS_IXMT_SHIFT, 1 > > + ori t0, TCSTATUS_A > > + mttc0 t0, CP0_TCSTATUS > > + > > + /* Resume TC */ > > + mttc0 zero, CP0_TCHALT > > + > > + /* Activate VPE */ > > + mftc0 t0, CP0_VPECONF0 > > + ori t0, VPECONF0_VPA > > + mttc0 t0, CP0_VPECONF0 > > + > > +_done_vpe: > > + addu a2, 1 > > + sltu t0, a0, a2 > > + beqz t0, _next_tc > > + nop > > + > > + mfc0 t0, CP0_MVPCONTROL > > + /* Enable all activated VPE to execute */ > > + ori t0, MVPCONTROL_EVP > > + /* Exit VPE Configuration State */ > > + ins t0, zero, MVPCONTROL_VPC_SHIFT, 1 > > + mtc0 t0, CP0_MVPCONTROL > > + ehb > > + > > +_vpe1_init_done: > > + jr ra > > + nop > > + END(boot_vpe1) > > diff --git a/arch/mips/mach-mtmips/mt7621/spl/serial.c > > b/arch/mips/mach-mtmips/mt7621/spl/serial.c > > new file mode 100644 > > index 0000000000..5cf093a078 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/spl/serial.c > > @@ -0,0 +1,24 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <asm/io.h> > > +#include "../mt7621.h" > > + > > +void mtmips_spl_serial_init(void) > > +{ > > +#ifdef CONFIG_SPL_SERIAL > > + void __iomem *base = ioremap_nocache(SYSCTL_BASE, > > SYSCTL_SIZE); > > + > > +#if CONFIG_CONS_INDEX == 1 > > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE); > > +#elif CONFIG_CONS_INDEX == 2 > > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M); > > +#elif CONFIG_CONS_INDEX == 3 > > + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M); > > +#endif /* CONFIG_CONS_INDEX */ > > +#endif /* CONFIG_SPL_SERIAL */ > > +} > > diff --git a/arch/mips/mach-mtmips/mt7621/spl/spl.c > > b/arch/mips/mach-mtmips/mt7621/spl/spl.c > > new file mode 100644 > > index 0000000000..71d01aa7f5 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/spl/spl.c > > @@ -0,0 +1,95 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <spl.h> > > +#include <init.h> > > +#include <image.h> > > +#include <vsprintf.h> > > +#include <malloc.h> > > +#include <asm/io.h> > > +#include <asm/sections.h> > > +#include <asm/addrspace.h> > > +#include <asm/byteorder.h> > > +#include <asm/global_data.h> > > +#include <linux/sizes.h> > > +#include <mach/serial.h> > > +#include "../mt7621.h" > > +#include "dram.h" > > + > > +DECLARE_GLOBAL_DATA_PTR; > > + > > +struct tpl_info { > > + u32 magic; > > + u32 size; > > +}; > > + > > +void set_timer_freq_simple(void) > > +{ > > + u32 div = get_xtal_mhz(); > > + > > + /* Round down cpu freq */ > > + gd->arch.timer_freq = rounddown(CONFIG_MT7621_CPU_FREQ, > > div) * 500000; > > +} > > + > > +void __noreturn board_init_f(ulong dummy) > > +{ > > + spl_init(); > > + > > +#ifdef CONFIG_SPL_SERIAL > > + /* > > + * mtmips_spl_serial_init() is useful if debug uart is > > enabled, > > + * or DM based serial is not enabled. > > + */ > > + mtmips_spl_serial_init(); > > + preloader_console_init(); > > +#endif > > + > > + board_init_r(NULL, 0); > > +} > > + > > +void board_boot_order(u32 *spl_boot_list) > > +{ > > +#ifdef CONFIG_MT7621_BOOT_FROM_NAND > > + spl_boot_list[0] = BOOT_DEVICE_NAND; > > +#else > > + spl_boot_list[0] = BOOT_DEVICE_NOR; > > +#endif > > +} > > + > > +unsigned long spl_nor_get_uboot_base(void) > > +{ > > + const struct tpl_info *tpli; > > + const image_header_t *hdr; > > + u32 addr; > > + > > + addr = FLASH_MMAP_BASE + TPL_INFO_OFFSET; > > + tpli = (const struct tpl_info *)KSEG1ADDR(addr); > > + > > + if (tpli->magic == TPL_INFO_MAGIC) { > > + addr = FLASH_MMAP_BASE + tpli->size; > > + hdr = (const image_header_t *)KSEG1ADDR(addr); > > + > > + if (image_get_magic(hdr) == IH_MAGIC) { > > + addr += sizeof(*hdr) + > > image_get_size(hdr); > > + return KSEG1ADDR(addr); > > + } > > + } > > + > > + panic("Unable to locate SPL payload\n"); > > + return 0; > > +} > > + > > +uint32_t spl_nand_get_uboot_raw_page(void) > > +{ > > + const struct stage_header *sh = (const struct stage_header > > *)&_start; > > + u32 addr; > > + > > + addr = image_get_header_size() + be32_to_cpu(sh- > > >stage_size); > > + addr = ALIGN(addr, SZ_4K); > > + > > + return addr; > > +} > > diff --git a/arch/mips/mach-mtmips/mt7621/spl/start.S > > b/arch/mips/mach-mtmips/mt7621/spl/start.S > > new file mode 100644 > > index 0000000000..3cad3567e7 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/spl/start.S > > @@ -0,0 +1,226 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <asm-offsets.h> > > +#include <config.h> > > +#include <asm/asm.h> > > +#include <asm/regdef.h> > > +#include <asm/mipsregs.h> > > +#include <asm/cacheops.h> > > +#include <asm/addrspace.h> > > +#include <asm/mipsmtregs.h> > > +#include <asm/cm.h> > > +#include "../mt7621.h" > > +#include "dram.h" > > + > > +#ifndef CONFIG_SYS_INIT_SP_ADDR > > +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ > > + CONFIG_SYS_INIT_SP_OFFSET) > > +#endif > > + > > +#define SP_ADDR_TEMP 0xbe10dff0 > > + > > + .macro init_wr sel > > + MTC0 zero, CP0_WATCHLO,\sel > > + mtc0 t1, CP0_WATCHHI,\sel > > + .endm > > + > > + .macro setup_stack_gd > > + li t0, -16 > > + PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR > > + and sp, t1, t0 # force 16 byte > > alignment > > + PTR_SUBU \ > > + sp, sp, GD_SIZE # reserve space for > > gd > > + and sp, sp, t0 # force 16 byte > > alignment > > + move k0, sp # save gd > > pointer > > +#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \ > > + !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) > > + li t2, CONFIG_VAL(SYS_MALLOC_F_LEN) > > + PTR_SUBU \ > > + sp, sp, t2 # reserve space for > > early malloc > > + and sp, sp, t0 # force 16 byte > > alignment > > +#endif > > + move fp, sp > > + > > + /* Clear gd */ > > + move t0, k0 > > +1: > > + PTR_S zero, 0(t0) > > + PTR_ADDIU t0, PTRSIZE > > + blt t0, t1, 1b > > + nop > > + > > +#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \ > > + !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) > > + PTR_S sp, GD_MALLOC_BASE(k0) # gd- > > >malloc_base offset > > +#endif > > + .endm > > + > > + .set noreorder > > + > > +ENTRY(_start) > > + b 1f > > + mtc0 zero, CP0_COUNT > > + > > + /* Stage header required by BootROM */ > > + .org 0x8 > > + .word 0 # ep, filled by mkimage > > + .word 0 # stage_size, filled by > > mkimage > > + .word 0 # has_stage2 > > + .word 0 # next_ep > > + .word 0 # next_size > > + .word 0 # next_offset > > + > > +1: > > + /* Init CP0 Status */ > > + mfc0 t0, CP0_STATUS > > + and t0, ST0_IMPL > > + or t0, ST0_BEV | ST0_ERL > > + mtc0 t0, CP0_STATUS > > + ehb > > + > > + /* Clear Watch Status bits and disable watch exceptions */ > > + li t1, 0x7 # Clear I, R and W > > conditions > > + init_wr 0 > > + init_wr 1 > > + init_wr 2 > > + init_wr 3 > > + > > + /* Clear WP, IV and SW interrupts */ > > + mtc0 zero, CP0_CAUSE > > + > > + /* Clear timer interrupt (CP0_COUNT cleared on branch to > > 'reset') */ > > + mtc0 zero, CP0_COMPARE > > + > > + /* VPE1 goes to wait code directly */ > > + mfc0 t0, CP0_TCBIND > > + andi t0, TCBIND_CURVPE > > + bnez t0, launch_vpe_entry > > + nop > > + > > + /* Core1 goes to specific launch entry */ > > + PTR_LI t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE) > > + lw t1, GCR_Cx_ID(t0) > > + bnez t1, launch_core_entry > > + nop > > + > > + /* MT7530 reset */ > > + li t0, KSEG1ADDR(SYSCTL_BASE) > > + lw t1, SYSCTL_RSTCTL_REG(t0) > > + ori t1, MCM_RST > > + sw t1, SYSCTL_RSTCTL_REG(t0) > > + > > + /* Disable DMA route for PSE SRAM set by BootROM */ > > + PTR_LI t0, KSEG1ADDR(DMA_CFG_ARB_BASE) > > + sw zero, DMA_ROUTE_REG(t0) > > + > > + /* Set CPU clock to 500MHz (Required if boot from NAND) */ > > + li t0, KSEG1ADDR(SYSCTL_BASE) > > + lw t1, SYSCTL_CLKCFG0_REG(t0) > > + ins t1, zero, 30, 2 # CPU_CLK_SEL > > + sw t1, SYSCTL_CLKCFG0_REG(t0) > > + > > + /* Set CPU clock divider to 1/1 */ > > + li t0, KSEG1ADDR(RBUS_BASE) > > + li t1, 0x101 > > + sw t1, RBUS_DYN_CFG0_REG(t0) > > + > > + /* (Re-)initialize the SRAM */ > > + bal mips_sram_init > > + nop > > + > > + /* Set up temporary stack */ > > + li sp, SP_ADDR_TEMP > > + > > + /* Setup full CPS */ > > + bal mips_cm_map > > + nop > > + > > + bal mt7621_cps_init > > + nop > > + > > + /* Prepare for CPU/DDR initialization binary blob */ > > + bal prepare_stage_bin > > + nop > > + > > + /* Call CPU/DDR initialization binary blob */ > > + li t9, STAGE_LOAD_ADDR > > + jalr t9 > > + nop > > + > > + /* Switch CPU PLL source */ > > + li t0, KSEG1ADDR(SYSCTL_BASE) > > + lw t1, SYSCTL_CLKCFG0_REG(t0) > > + li t2, 1 > > + ins t1, t2, CPU_CLK_SEL_S, 2 > > + sw t1, SYSCTL_CLKCFG0_REG(t0) > > + > > + /* > > + * Currently SPL is running on locked L2 cache (on KSEG0). > > + * To reset the entire cache, we have to writeback SPL to > > DRAM first. > > + * Cache flush won't work here. Use memcpy instead. > > + */ > > + > > + la a0, __text_start > > + move a1, a0 > > + la a2, __image_copy_end > > + sub a2, a2, a1 > > + li a3, 5 > > + ins a0, a3, 29, 3 # convert to KSEG1 > > + > > + bal memcpy > > + nop > > + > > + /* Disable caches */ > > + bal mips_cache_disable > > + nop > > + > > + /* Reset caches */ > > + bal mips_cache_reset > > + nop > > + > > + /* Disable SRAM */ > > + li t0, KSEG1ADDR(FE_BASE) > > + li t1, FE_PSE_RESET > > + sw t1, FE_RST_GLO_REG(t0) > > + > > + /* Clear the .bss section */ > > + la a0, __bss_start > > + la a1, __bss_end > > +1: sw zero, 0(a0) > > + addiu a0, 4 > > + ble a0, a1, 1b > > + nop > > + > > + /* Set up initial stack and global data */ > > + setup_stack_gd > > + > > +#if CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) > > + /* Set malloc base */ > > + li t0, (CONFIG_SYS_INIT_SP_ADDR + 15) & (~15) > > + PTR_S t0, GD_MALLOC_BASE(k0) # gd- > > >malloc_base offset > > +#endif > > + > > +#if defined(CONFIG_DEBUG_UART) && defined(CONFIG_SPL_SERIAL) > > + /* Earliest point to set up debug uart */ > > + bal debug_uart_init > > + nop > > +#endif > > + > > + /* Setup timer */ > > + bal set_timer_freq_simple > > + nop > > + > > + /* Bootup secondary CPUs */ > > + bal secondary_cpu_init > > + nop > > + > > + move a0, zero # a0 <-- boot_flags = > > 0 > > + bal board_init_f > > + move ra, zero > > + > > + END(_start) > > diff --git a/arch/mips/mach-mtmips/mt7621/sram_init.S > > b/arch/mips/mach-mtmips/mt7621/sram_init.S > > new file mode 100644 > > index 0000000000..74ddd6bcd7 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/sram_init.S > > @@ -0,0 +1,22 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <asm/addrspace.h> > > +#include <asm/asm.h> > > +#include <asm/regdef.h> > > +#include "mt7621.h" > > + > > +LEAF(mips_sram_init) > > + li t0, KSEG1ADDR(FE_BASE) > > + li t1, FE_PSE_RESET > > + sw t1, FE_RST_GLO_REG(t0) > > + > > + li t1, (FE_PSE_RAM | FE_PSE_MEM_EN) > > + sw t1, FE_RST_GLO_REG(t0) > > + > > + jr ra > > + END(mips_sram_init) > > diff --git a/arch/mips/mach-mtmips/mt7621/tpl/Makefile > > b/arch/mips/mach-mtmips/mt7621/tpl/Makefile > > new file mode 100644 > > index 0000000000..471ad74249 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/tpl/Makefile > > @@ -0,0 +1,4 @@ > > + > > +extra-y += start.o > > + > > +obj-y += tpl.o > > diff --git a/arch/mips/mach-mtmips/mt7621/tpl/start.S > > b/arch/mips/mach-mtmips/mt7621/tpl/start.S > > new file mode 100644 > > index 0000000000..19b09f7251 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/tpl/start.S > > @@ -0,0 +1,161 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <asm-offsets.h> > > +#include <config.h> > > +#include <asm/asm.h> > > +#include <asm/regdef.h> > > +#include <asm/addrspace.h> > > +#include <asm/mipsregs.h> > > +#include <asm/cm.h> > > +#include "../mt7621.h" > > + > > +#define SP_ADDR_TEMP 0xbe10dff0 > > + > > + .set noreorder > > + > > + .macro init_wr sel > > + MTC0 zero, CP0_WATCHLO,\sel > > + mtc0 t1, CP0_WATCHHI,\sel > > + .endm > > + > > + .macro uhi_mips_exception > > + move k0, t9 # preserve t9 in k0 > > + move k1, a0 # preserve a0 in k1 > > + li t9, 15 # UHI exception operation > > + li a0, 0 # Use hard register context > > + sdbbp 1 # Invoke UHI operation > > + .endm > > + > > +ENTRY(_start) > > + b reset > > + mtc0 zero, CP0_COUNT > > + > > + /* > > + * Store TPL size here. > > + * This will be used by SPL to locate u-boot payload. > > + */ > > + .org TPL_INFO_OFFSET > > + .word TPL_INFO_MAGIC > > + .word __image_copy_len > > + > > + /* Exception vector */ > > + .org 0x200 > > + /* TLB refill, 32 bit task */ > > + uhi_mips_exception > > + > > + .org 0x280 > > + /* XTLB refill, 64 bit task */ > > + uhi_mips_exception > > + > > + .org 0x300 > > + /* Cache error exception */ > > + uhi_mips_exception > > + > > + .org 0x380 > > + /* General exception */ > > + uhi_mips_exception > > + > > + .org 0x400 > > + /* Catch interrupt exceptions */ > > + uhi_mips_exception > > + > > + .org 0x480 > > + /* EJTAG debug exception */ > > +1: b 1b > > + nop > > + > > + .org 0x500 > > + > > +reset: > > + /* Set KSEG0 to Uncached */ > > + mfc0 t0, CP0_CONFIG > > + ins t0, zero, 0, 3 > > + ori t0, t0, CONF_CM_UNCACHED > > + mtc0 t0, CP0_CONFIG > > + ehb > > + > > + /* Check for CPU number */ > > + mfc0 t0, CP0_EBASE > > + and t0, t0, MIPS_EBASE_CPUNUM > > + beqz t0, 1f > > + nop > > + > > + /* Secondary core goes to specified SPL entry address */ > > + li t0, KSEG1ADDR(SYSCTL_BASE) > > + lw t0, BOOT_SRAM_BASE_REG(t0) > > + jr t0 > > + nop > > + > > + /* Init CP0 Status */ > > +1: mfc0 t0, CP0_STATUS > > + and t0, ST0_IMPL > > + or t0, ST0_BEV | ST0_ERL > > + mtc0 t0, CP0_STATUS > > + nop > > + > > + /* Clear Watch Status bits and disable watch exceptions */ > > + li t1, 0x7 # Clear I, R and W > > conditions > > + init_wr 0 > > + init_wr 1 > > + init_wr 2 > > + init_wr 3 > > + > > + /* Clear WP, IV and SW interrupts */ > > + mtc0 zero, CP0_CAUSE > > + > > + /* Clear timer interrupt (CP0_COUNT cleared on branch to > > 'reset') */ > > + mtc0 zero, CP0_COMPARE > > + > > + /* Setup basic CPS */ > > + bal mips_cm_map > > + nop > > + > > + li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE) > > + li t1, GCR_REG0_BASE_VALUE > > + sw t1, GCR_REG0_BASE(t0) > > + > > + li t1, ((GCR_REG0_MASK_VALUE << > > GCR_REGn_MASK_ADDRMASK_SHIFT) | \ > > + GCR_REGn_MASK_CMTGT_IOCU0) > > + sw t1, GCR_REG0_MASK(t0) > > + > > + lw t1, GCR_BASE(t0) > > + ins t1, zero, 0, 2 # > > CM_DEFAULT_TARGET > > + sw t1, GCR_BASE(t0) > > + > > + lw t1, GCR_CONTROL(t0) > > + li t2, GCR_CONTROL_SYNCCTL > > + or t1, t1, t2 > > + sw t1, GCR_CONTROL(t0) > > + > > + /* Increase SPI frequency */ > > + li t0, KSEG1ADDR(SPI_BASE) > > + li t1, 5 > > + sw t1, SPI_SPACE_REG(t0) > > + > > + /* Set CPU clock to 500MHz */ > > + li t0, KSEG1ADDR(SYSCTL_BASE) > > + lw t1, SYSCTL_CLKCFG0_REG(t0) > > + ins t1, zero, 30, 2 # CPU_CLK_SEL > > + sw t1, SYSCTL_CLKCFG0_REG(t0) > > + > > + /* Set CPU clock divider to 1/1 */ > > + li t0, KSEG1ADDR(RBUS_BASE) > > + li t1, 0x101 > > + sw t1, RBUS_DYN_CFG0_REG(t0) > > + > > + /* Initialize the SRAM */ > > + bal mips_sram_init > > + nop > > + > > + /* Set up initial stack */ > > + li sp, SP_ADDR_TEMP > > + > > + bal tpl_main > > + nop > > + > > + END(_start) > > diff --git a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c > > b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c > > new file mode 100644 > > index 0000000000..77bcf0ddf0 > > --- /dev/null > > +++ b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c > > @@ -0,0 +1,146 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#include <image.h> > > +#include <asm/sections.h> > > +#include <asm/cacheops.h> > > +#include <asm/mipsregs.h> > > +#include <asm/cm.h> > > + > > +#define INDEX_STORE_DATA_SD 0x0f > > + > > +typedef void __noreturn (*image_entry_noargs_t)(void); > > + > > +static inline void ehb(void) > > +{ > > + __asm__ __volatile__ ("ehb"); > > +} > > + > > +/* > > + * Lock L2 cache and fill data > > + * Assume that data is 4-byte aligned and start_addr/size is 32- > > byte aligned > > + */ > > +static void fill_lock_l2cache(uintptr_t dataptr, ulong start_addr, > > ulong size) > > +{ > > + ulong slsize = CONFIG_SYS_DCACHE_LINE_SIZE; > > + ulong end_addr = start_addr + size; > > + const u32 *data = (u32 *)dataptr; > > + ulong i, addr; > > + u32 val; > > + > > + /* Clear WSC & SPR bit in ErrCtl */ > > + val = read_c0_ecc(); > > + val &= 0xcfffffff; > > + write_c0_ecc(val); > > + ehb(); > > + > > + for (addr = start_addr; addr < end_addr; addr += slsize) { > > + /* Set STagLo to lock cache line */ > > + write_c0_staglo((addr & 0x1ffff800) | 0xa0); > > + mips_cache(INDEX_STORE_TAG_SD, (void *)addr); > > + > > + /* Fill data */ > > + for (i = 0; i < slsize; i += 8) { > > + val = *data++; > > + __write_32bit_c0_register($28, 5, val); /* > > sdtaglo */ > > + val = *data++; > > + __write_32bit_c0_register($29, 5, val); /* > > sdtaghi */ > > + mips_cache(INDEX_STORE_DATA_SD, (void > > *)(addr + i)); > > + } > > + } > > +} > > + > > +/* A simple function to initialize MT7621's cache */ > > +static void mt7621_cache_init(void) > > +{ > > + void __iomem *cm_base = (void > > *)KSEG1ADDR(CONFIG_MIPS_CM_BASE); > > + ulong lsize = CONFIG_SYS_DCACHE_LINE_SIZE; > > + ulong addr; > > + u32 val; > > + > > + /* Enable CCA override. Set to uncached */ > > + val = readl(cm_base + GCR_BASE); > > + val &= ~CCA_DEFAULT_OVR_MASK; > > + val |= CCA_DEFAULT_OVREN | (2 << CCA_DEFAULT_OVR_SHIFT); > > + writel(val, cm_base + GCR_BASE); > > + > > + /* Initialize L1 I-Cache */ > > + write_c0_taglo(0); > > + write_c0_taghi(0); > > + > > + for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += > > lsize) > > + mips_cache(INDEX_STORE_TAG_I, (void *)addr); > > + > > + /* Initialize L1 D-Cache */ > > + write_c0_dtaglo(0); > > + __write_32bit_c0_register($29, 2, 0); /* dtaghi */ > > + > > + for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += > > lsize) > > + mips_cache(INDEX_STORE_TAG_D, (void *)addr); > > + > > + /* Initialize L2 Cache */ > > + write_c0_staglo(0); > > + __write_32bit_c0_register($29, 4, 0); /* staghi */ > > + > > + for (addr = 0; addr < (256 << 10); addr += lsize) > > + mips_cache(INDEX_STORE_TAG_SD, (void *)addr); > > + > > + /* Dsiable CCA override */ > > + val = readl(cm_base + GCR_BASE); > > + val &= ~(CCA_DEFAULT_OVR_MASK | CCA_DEFAULT_OVREN); > > + writel(val, cm_base + GCR_BASE); > > + > > + /* Set KSEG0 to non-coherent cached (important!) */ > > + val = read_c0_config(); > > + val &= ~CONF_CM_CMASK; > > + val |= CONF_CM_CACHABLE_NONCOHERENT; > > + write_c0_config(val); > > + ehb(); > > + > > + /* Again, invalidate L1 D-Cache */ > > + for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += > > lsize) > > + mips_cache(INDEX_WRITEBACK_INV_D, (void *)addr); > > + > > + /* Invalidate L1 I-Cache */ > > + for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += > > lsize) > > + mips_cache(INDEX_INVALIDATE_I, (void *)addr); > > + > > + /* Disable L2 cache bypass */ > > + val = read_c0_config2(); > > + val &= ~MIPS_CONF_IMPL; > > + write_c0_config2(val); > > + ehb(); > > +} > > + > > +void __noreturn tpl_main(void) > > +{ > > + const image_header_t *hdr = (const image_header_t > > *)__image_copy_end; > > + image_entry_noargs_t image_entry; > > + u32 loadaddr, size; > > + uintptr_t data; > > + > > + /* Initialize the cache first */ > > + mt7621_cache_init(); > > + > > + if (image_get_magic(hdr) != IH_MAGIC) > > + goto failed; > > + > > + loadaddr = image_get_load(hdr); > > + size = image_get_size(hdr); > > + image_entry = (image_entry_noargs_t)image_get_ep(hdr); > > + > > + /* Load TPL image to L2 cache */ > > + data = (uintptr_t)__image_copy_end + sizeof(struct > > image_header); > > + fill_lock_l2cache(data, loadaddr, size); > > + > > + /* Jump to SPL */ > > + image_entry(); > > + > > +failed: > > + for (;;) > > + ; > > +} > > diff --git a/include/configs/mt7621.h b/include/configs/mt7621.h > > new file mode 100644 > > index 0000000000..580d5fde0c > > --- /dev/null > > +++ b/include/configs/mt7621.h > > @@ -0,0 +1,67 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +/* > > + * Copyright (C) 2022 MediaTek Inc. All rights reserved. > > + * > > + * Author: Weijie Gao <weijie.gao@mediatek.com> > > + */ > > + > > +#ifndef __CONFIG_MT7621_H > > +#define __CONFIG_MT7621_H > > + > > +#define CONFIG_SYS_HZ 1000 > > +#define CONFIG_SYS_MIPS_TIMER_FREQ 440000000 > > + > > +#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000 > > + > > +#define CONFIG_SYS_SDRAM_BASE 0x80000000 > > + > > +#define CONFIG_VERY_BIG_RAM > > +#define CONFIG_MAX_MEM_MAPPED 0x1c000000 > > + > > +#define CONFIG_SYS_INIT_SP_OFFSET 0x800000 > > + > > +#define CONFIG_SYS_BOOTM_LEN 0x2000000 > > + > > +#define CONFIG_SYS_MAXARGS 16 > > +#define CONFIG_SYS_CBSIZE 1024 > > + > > +#define CONFIG_SYS_NONCACHED_MEMORY 0x100000 > > + > > +/* MMC */ > > +#define MMC_SUPPORTS_TUNING > > + > > +/* NAND */ > > +#define CONFIG_SYS_MAX_NAND_DEVICE 1 > > + > > +/* Serial SPL */ > > +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL) > > +#define CONFIG_SYS_NS16550_MEM32 > > +#define CONFIG_SYS_NS16550_CLK 50000000 > > +#define CONFIG_SYS_NS16550_REG_SIZE -4 > > +#define CONFIG_SYS_NS16550_COM1 0xbe000c00 > > +#endif > > + > > +/* Serial common */ > > +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, > > 57600, 115200, \ > > + 230400, 460800, 921600 } > > + > > +/* SPL */ > > +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE > > + > > +#ifdef CONFIG_TPL_BUILD > > +#define CONFIG_SPL_START_S_PATH "arch/mips/mach- > > mtmips/mt7621/tpl" > > +/* .bss will not be used by TPL */ > > +#define CONFIG_SPL_BSS_START_ADDR 0x80000000 > > +#define CONFIG_SPL_BSS_MAX_SIZE 0 > > +#else > > +#define CONFIG_SPL_START_S_PATH "arch/mips/mach- > > mtmips/mt7621/spl" > > +#define CONFIG_SPL_BSS_START_ADDR 0x80140000 > > +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 > > +#define CONFIG_SPL_MAX_SIZE 0x30000 > > +#endif > > + > > +/* Dummy value */ > > +#define CONFIG_SYS_UBOOT_BASE 0 > > +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0 > > + > > +#endif /* __CONFIG_MT7621_H */ > > > >
diff --git a/arch/mips/dts/mt7621-u-boot.dtsi b/arch/mips/dts/mt7621-u-boot.dtsi new file mode 100644 index 0000000000..b9b02003a5 --- /dev/null +++ b/arch/mips/dts/mt7621-u-boot.dtsi @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <linux/stringify.h> + +/ { + binman: binman { + multiple-images; + }; +}; + +&binman { + u-boot-spl-ddr { + align = <4>; + align-size = <4>; + filename = "u-boot-spl-ddr.bin"; + pad-byte = <0xff>; + + u-boot-spl { + align-end = <4>; + filename = "u-boot-spl.bin"; + }; + + stage_bin { + filename = "mt7621_stage_sram.bin"; + type = "blob-ext"; + }; + }; + + spl-img { + filename = "u-boot-spl-ddr.img"; + + mkimage { +#ifdef CONFIG_MT7621_BOOT_FROM_NAND + args = "-T", "mtk_image", "-n", "mt7621=1", + "-a", __stringify(CONFIG_SPL_TEXT_BASE), + "-e", __stringify(CONFIG_SPL_TEXT_BASE); +#else + args = "-A", "mips", "-T", "standalone", "-O", "u-boot", + "-C", "none", "-n", "MT7621 U-Boot SPL", + "-a", __stringify(CONFIG_SPL_TEXT_BASE), + "-e", __stringify(CONFIG_SPL_TEXT_BASE); +#endif + + blob { + filename = "u-boot-spl-ddr.bin"; + }; + }; + }; + + mt7621-uboot { + filename = "u-boot-mt7621.bin"; + pad-byte = <0xff>; + +#ifndef CONFIG_MT7621_BOOT_FROM_NAND + u-boot-tpl { + align-end = <4>; + filename = "u-boot-tpl.bin"; + }; +#endif + + spl { +#ifdef CONFIG_MT7621_BOOT_FROM_NAND + align-end = <0x1000>; +#endif + filename = "u-boot-spl-ddr.img"; + type = "blob"; + }; + + u-boot { + filename = "u-boot-lzma.img"; + type = "blob"; + }; + }; +}; diff --git a/arch/mips/dts/mt7621.dtsi b/arch/mips/dts/mt7621.dtsi new file mode 100644 index 0000000000..285179e896 --- /dev/null +++ b/arch/mips/dts/mt7621.dtsi @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <dt-bindings/clock/mt7621-clk.h> +#include <dt-bindings/reset/mt7621-reset.h> +#include <dt-bindings/phy/phy.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mediatek,mt7621-soc"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "mips,mips1004Kc"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "mips,mips1004Kc"; + reg = <0>; + }; + }; + + clk48m: clk48m@0 { + compatible = "fixed-clock"; + + clock-frequency = <48000000>; + + #clock-cells = <0>; + }; + + clk50m: clk50m@0 { + compatible = "fixed-clock"; + + clock-frequency = <50000000>; + + #clock-cells = <0>; + }; + + sysc: sysc@1e000000 { + compatible = "mediatek,mt7621-sysc", "syscon"; + reg = <0x1e000000 0x100>; + }; + + clkctrl: clkctrl@1e000030 { + compatible = "mediatek,mt7621-clk"; + mediatek,sysc = <&sysc>; + mediatek,memc = <&memc>; + + #clock-cells = <1>; + u-boot,dm-pre-reloc; + }; + + rstctrl: rstctrl@1e000034 { + compatible = "mediatek,mtmips-reset"; + reg = <0x1e000034 0x4>; + #reset-cells = <1>; + }; + + reboot: resetctl-reboot { + compatible = "resetctl-reboot"; + + resets = <&rstctrl RST_SYS>; + reset-names = "sysreset"; + }; + + memc: memc@1e005000 { + compatible = "mediatek,mt7621-memc", "syscon"; + reg = <0x1e005000 0x1000>; + }; + + pinctrl: pinctrl@1e000060 { + compatible = "mediatek,mt7621-pinctrl"; + reg = <0x1e000048 0x30>; + + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pin_state { + uart1 { + groups = "uart1"; + function = "uart"; + }; + + gpios { + groups = "i2c", "uart3", "pcie reset"; + function = "gpio"; + }; + + jtag { + groups = "jtag"; + function = "jtag"; + }; + + wdt { + groups = "wdt"; + function = "wdt rst"; + }; + }; + + uart1_pins: uart1_pins { + groups = "uart1"; + function = "uart"; + }; + + uart2_pins: uart2_pins { + groups = "uart2"; + function = "uart"; + }; + + uart3_pins: uart3_pins { + groups = "uart3"; + function = "uart"; + }; + + sdxc_pins: sdxc_pins { + groups = "sdxc"; + function = "sdxc"; + }; + + spi_pins: spi_pins { + groups = "spi"; + function = "spi"; + }; + + eth_pins: eth_pins { + mdio_pins { + groups = "mdio"; + function = "mdio"; + }; + + rgmii1_pins { + groups = "rgmii1"; + function = "rgmii"; + }; + + esw_pins { + groups = "esw int"; + function = "esw int"; + }; + + mdio_pconf { + groups = "mdio"; + drive-strength = <2>; + }; + }; + }; + + watchdog: watchdog@1e000100 { + compatible = "mediatek,mt7621-wdt"; + reg = <0x1e000100 0x40>; + + resets = <&rstctrl RST_TIMER>; + reset-names = "wdt"; + + status = "disabled"; + }; + + gpio: gpio@1e000600 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "mtk,mt7621-gpio"; + reg = <0x1e000600 0x100>; + + resets = <&rstctrl RST_PIO>; + reset-names = "pio"; + + gpio0: bank@0 { + reg = <0>; + compatible = "mtk,mt7621-gpio-bank"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio1: bank@1 { + reg = <1>; + compatible = "mtk,mt7621-gpio-bank"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio2: bank@2 { + reg = <2>; + compatible = "mtk,mt7621-gpio-bank"; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + spi: spi@1e000b00 { + compatible = "ralink,mt7621-spi"; + reg = <0x1e000b00 0x40>; + + status = "disabled"; + + pinctrl-names = "default"; + pinctrl-0 = <&spi_pins>; + + resets = <&rstctrl RST_SPI>; + reset-names = "spi"; + + clocks = <&clkctrl MT7621_CLK_SPI>; + + #address-cells = <1>; + #size-cells = <0>; + }; + + uart0: uart1@1e000c00 { + compatible = "mediatek,hsuart", "ns16550a"; + reg = <0x1e000c00 0x100>; + + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + + clocks = <&clkctrl MT7621_CLK_UART1>; + + resets = <&rstctrl RST_UART1>; + + reg-shift = <2>; + }; + + uart1: uart2@1e000d00 { + compatible = "mediatek,hsuart", "ns16550a"; + reg = <0x1e000d00 0x100>; + + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + + clocks = <&clkctrl MT7621_CLK_UART2>; + + resets = <&rstctrl RST_UART2>; + + reg-shift = <2>; + + status = "disabled"; + }; + + uart2: uart3@1e000e00 { + compatible = "mediatek,hsuart", "ns16550a"; + reg = <0x1e000e00 0x100>; + + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; + + clocks = <&clkctrl MT7621_CLK_UART3>; + + resets = <&rstctrl RST_UART3>; + + reg-shift = <2>; + + status = "disabled"; + }; + + eth: eth@1e100000 { + compatible = "mediatek,mt7621-eth"; + reg = <0x1e100000 0x20000>; + mediatek,ethsys = <&sysc>; + + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + + resets = <&rstctrl RST_FE>, <&rstctrl RST_GMAC>, <&rstctrl RST_MCM>; + reset-names = "fe", "gmac", "mcm"; + + clocks = <&clkctrl MT7621_CLK_GDMA>, + <&clkctrl MT7621_CLK_ETH>; + clock-names = "gmac", "fe"; + + #address-cells = <1>; + #size-cells = <0>; + + mediatek,gmac-id = <0>; + phy-mode = "rgmii"; + mediatek,switch = "mt7530"; + mediatek,mcm; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + mmc: mmc@1e130000 { + compatible = "mediatek,mt7621-mmc"; + reg = <0x1e130000 0x4000>; + + status = "disabled"; + + bus-width = <4>; + builtin-cd = <1>; + r_smpl = <1>; + + pinctrl-names = "default"; + pinctrl-0 = <&sdxc_pins>; + + clocks = <&clk50m>, <&clkctrl MT7621_CLK_SHXC>; + clock-names = "source", "hclk"; + + resets = <&rstctrl RST_SDXC>; + }; + + ssusb: usb@1e1c0000 { + compatible = "mediatek,mt7621-xhci", "mediatek,mtk-xhci"; + reg = <0x1e1c0000 0x1000>, <0x1e1d0700 0x100>; + reg-names = "mac", "ippc"; + + clocks = <&clk48m>, <&clk48m>; + clock-names = "sys_ck", "ref_ck"; + + phys = <&u2port0 PHY_TYPE_USB2>, + <&u3port0 PHY_TYPE_USB3>, + <&u2port1 PHY_TYPE_USB2>; + + status = "disabled"; + }; + + u3phy: usb-phy@1e1d0000 { + compatible = "mediatek,mt7621-u3phy", + "mediatek,generic-tphy-v1"; + reg = <0x1e1d0000 0x700>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + status = "disabled"; + + u2port0: usb-phy@1e1d0800 { + reg = <0x1e1d0800 0x0100>; + #phy-cells = <1>; + clocks = <&clk48m>; + clock-names = "ref"; + }; + + u3port0: usb-phy@1e1d0900 { + reg = <0x1e1d0900 0x0100>; + #phy-cells = <1>; + }; + + u2port1: usb-phy@1e1d1000 { + reg = <0x1e1d1000 0x0100>; + #phy-cells = <1>; + clocks = <&clk48m>; + clock-names = "ref"; + }; + }; + + i2c: i2c@1e000900 { + compatible = "i2c-gpio"; + + status = "disabled"; + + i2c-gpio,delay-us = <3>; + + gpios = <&gpio0 3 1>, /* PIN3 as SDA */ + <&gpio0 4 1>; /* PIN4 as CLK */ + + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig index 151b004603..d46be503a2 100644 --- a/arch/mips/mach-mtmips/Kconfig +++ b/arch/mips/mach-mtmips/Kconfig @@ -9,6 +9,7 @@ config SYS_MALLOC_F_LEN config SYS_SOC default "mt7620" if SOC_MT7620 + default "mt7621" if SOC_MT7621 default "mt7628" if SOC_MT7628 config SYS_DCACHE_SIZE @@ -18,25 +19,45 @@ config SYS_DCACHE_LINE_SIZE default 32 config SYS_ICACHE_SIZE - default 65536 + default 65536 if SOC_MT7620 || SOC_MT7628 + default 32768 if SOC_MT7621 config SYS_ICACHE_LINE_SIZE default 32 +config SYS_SCACHE_LINE_SIZE + default 32 if SOC_MT7621 + config SYS_TEXT_BASE - default 0x9c000000 if !SPL - default 0x80200000 if SPL + default 0x9c000000 if !SPL && !SOC_MT7621 + default 0x80200000 if SPL || SOC_MT7621 config SPL_TEXT_BASE - default 0x9c000000 + default 0x9c000000 if !SOC_MT7621 + default 0x80100000 if SOC_MT7621 + +config SPL_SIZE_LIMIT + default 0x30000 if SOC_MT7621 + +config TPL_TEXT_BASE + default 0xbfc00000 if SOC_MT7621 + +config TPL_MAX_SIZE + default 4096 if SOC_MT7621 config SPL_PAYLOAD default "u-boot-lzma.img" if SPL_LZMA config BUILD_TARGET - default "u-boot-with-spl.bin" if SPL + default "u-boot-with-spl.bin" if SPL && !SOC_MT7621 + default "u-boot-lzma.img" if SOC_MT7621 default "u-boot.bin" +config MAX_MEM_SIZE + int + default 256 if SOC_MT7620 || SOC_MT7628 + default 512 if SOC_MT7621 + choice prompt "MediaTek MIPS SoC select" @@ -55,6 +76,23 @@ config SOC_MT7620 help This supports MediaTek MT7620. +config SOC_MT7621 + bool "MT7621" + select MIPS_CM + select MIPS_L2_CACHE + select SYS_CACHE_SHIFT_5 + select SYS_MIPS_CACHE_INIT_RAM_LOAD + select PINCTRL_MT7621 + select MTK_SERIAL + select REGMAP + select SYSCON + select BINMAN + select SUPPORT_TPL + select SPL_LOADER_SUPPORT if SPL + select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL + help + This supports MediaTek MT7621. + config SOC_MT7628 bool "MT7628" select SYS_CACHE_SHIFT_5 @@ -80,6 +118,7 @@ config SOC_MT7628 endchoice source "arch/mips/mach-mtmips/mt7620/Kconfig" +source "arch/mips/mach-mtmips/mt7621/Kconfig" source "arch/mips/mach-mtmips/mt7628/Kconfig" endmenu diff --git a/arch/mips/mach-mtmips/Makefile b/arch/mips/mach-mtmips/Makefile index 4909b47ef2..19f1e07033 100644 --- a/arch/mips/mach-mtmips/Makefile +++ b/arch/mips/mach-mtmips/Makefile @@ -1,9 +1,13 @@ # SPDX-License-Identifier: GPL-2.0+ obj-y += cpu.o + +ifneq ($(CONFIG_SOC_MT7621),y) obj-y += ddr_init.o obj-y += ddr_cal.o obj-$(CONFIG_SPL_BUILD) += spl.o +endif obj-$(CONFIG_SOC_MT7620) += mt7620/ +obj-$(CONFIG_SOC_MT7621) += mt7621/ obj-$(CONFIG_SOC_MT7628) += mt7628/ diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach-mtmips/cpu.c index a4b5cff61d..f1e9022738 100644 --- a/arch/mips/mach-mtmips/cpu.c +++ b/arch/mips/mach-mtmips/cpu.c @@ -16,7 +16,7 @@ DECLARE_GLOBAL_DATA_PTR; int dram_init(void) { - gd->ram_size = get_ram_size((void *)KSEG1, SZ_256M); + gd->ram_size = get_ram_size((void *)KSEG1, CONFIG_MAX_MEM_SIZE << 20); return 0; } diff --git a/arch/mips/mach-mtmips/mt7621/Kconfig b/arch/mips/mach-mtmips/mt7621/Kconfig new file mode 100644 index 0000000000..37d512c68f --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/Kconfig @@ -0,0 +1,95 @@ + +if SOC_MT7621 + +menu "CPU & DDR configuration" + +config MT7621_CPU_FREQ + int "CPU Frequency (MHz)" + range 400 1200 + default 880 + +choice + prompt "DRAM Frequency" + default MT7621_DRAM_FREQ_1200 + +config MT7621_DRAM_FREQ_400 + bool "400MHz" + +config MT7621_DRAM_FREQ_800 + bool "800MHz" + +config MT7621_DRAM_FREQ_1066 + bool "1066MHz" + +config MT7621_DRAM_FREQ_1200 + bool "1200MHz" + +endchoice + +choice + prompt "DDR2 timing parameters" + default MT7621_DRAM_DDR2_1024M + +config MT7621_DRAM_DDR2_512M + bool "64MB" + +config MT7621_DRAM_DDR2_1024M + bool "128MB" + +config MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ + bool "W9751G6KB_A02 @ 1066MHz (64MB)" + +config MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ + bool "W971GG6KB25 @ 800MHz (128MB)" + +config MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ + bool "W971GG6KB18 @ 1066MHz (128MB)" + +endchoice + +choice + prompt "DDR3 timing parameters" + default MT7621_DRAM_DDR3_2048M + +config MT7621_DRAM_DDR3_1024M + bool "128MB" + +config MT7621_DRAM_DDR3_1024M_KGD + bool "128MB KGD (MT7621DA)" + +config MT7621_DRAM_DDR3_2048M + bool "256MB" + +config MT7621_DRAM_DDR3_4096M + bool "512MB" + +endchoice + +endmenu + +config DEBUG_UART_BOARD_INIT + default y + +config MT7621_BOOT_FROM_NAND + bool "Boot from NAND" + help + Select this if u-boot will boot from NAND flash. When booting from + NAND, SPL will be loaded by bootrom directly and no TPL is needed. + +choice + prompt "Board select" + +endchoice + +config SYS_CONFIG_NAME + string "Board configuration name" + default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB + +config SYS_BOARD + string "Board name" + default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB + +config SYS_VENDOR + default "mediatek" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB + +endif diff --git a/arch/mips/mach-mtmips/mt7621/Makefile b/arch/mips/mach-mtmips/mt7621/Makefile new file mode 100644 index 0000000000..bf1b0bb688 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += init.o +obj-y += serial.o + +ifeq ($(CONFIG_SPL_BUILD),y) +ifeq ($(CONFIG_TPL_BUILD),y) +obj-y += tpl/ +else +obj-y += spl/ +endif + +obj-y += sram_init.o +endif diff --git a/arch/mips/mach-mtmips/mt7621/init.c b/arch/mips/mach-mtmips/mt7621/init.c new file mode 100644 index 0000000000..ec63712bc1 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/init.c @@ -0,0 +1,229 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <clk.h> +#include <dm.h> +#include <dm/uclass.h> +#include <dt-bindings/clock/mt7621-clk.h> +#include <asm/global_data.h> +#include <linux/io.h> +#include "mt7621.h" + +DECLARE_GLOBAL_DATA_PTR; + +static const char *const boot_mode[(CHIP_MODE_M >> CHIP_MODE_S) + 1] = { + [1] = "NAND 2K+64", + [2] = "SPI-NOR 3-Byte Addr", + [3] = "SPI-NOR 4-Byte Addr", + [10] = "NAND 2K+128", + [11] = "NAND 4K+128", + [12] = "NAND 4K+256", +}; + +int print_cpuinfo(void) +{ + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); + u32 val, ver, eco, pkg, core, dram, chipmode; + u32 cpu_clk, ddr_clk, bus_clk, xtal_clk; + struct udevice *clkdev; + const char *bootdev; + struct clk clk; + int ret; + + val = readl(sysc + SYSCTL_CHIP_REV_ID_REG); + ver = (val & VER_ID_M) >> VER_ID_S; + eco = (val & ECO_ID_M) >> ECO_ID_S; + pkg = !!(val & PKG_ID); + core = !!(val & CPU_ID); + + val = readl(sysc + SYSCTL_SYSCFG0_REG); + dram = val & DRAM_TYPE; + chipmode = (val & CHIP_MODE_M) >> CHIP_MODE_S; + + bootdev = boot_mode[chipmode]; + if (!bootdev) + bootdev = "Unsupported boot mode"; + + printf("CPU: MediaTek MT7621%c ver %u, eco %u\n", + core ? (pkg ? 'A' : 'N') : 'S', ver, eco); + + printf("Boot: DDR%u, %s\n", dram ? 2 : 3, bootdev); + + ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(mt7621_clk), + &clkdev); + if (ret) + return ret; + + clk.dev = clkdev; + + clk.id = MT7621_CLK_CPU; + cpu_clk = clk_get_rate(&clk); + + clk.id = MT7621_CLK_BUS; + bus_clk = clk_get_rate(&clk); + + clk.id = MT7621_CLK_DDR; + ddr_clk = clk_get_rate(&clk); + + clk.id = MT7621_CLK_XTAL; + xtal_clk = clk_get_rate(&clk); + + /* Set final timer frequency */ + if (cpu_clk) + gd->arch.timer_freq = cpu_clk / 2; + + printf("Clock: CPU: %uMHz, DDR: %uMT/s, Bus: %uMHz, XTAL: %uMHz\n", + cpu_clk / 1000000, ddr_clk / 500000, bus_clk / 1000000, + xtal_clk / 1000000); + + return 0; +} + +unsigned long get_xtal_mhz(void) +{ + void __iomem *sysc = (void *)KSEG1ADDR(SYSCTL_BASE); + u32 bs, xtal_sel; + + bs = readl(sysc + SYSCTL_SYSCFG0_REG); + xtal_sel = (bs & XTAL_MODE_SEL_M) >> XTAL_MODE_SEL_S; + + if (xtal_sel <= 2) + return 20; + else if (xtal_sel <= 5) + return 40; + else + return 25; +} + +static void xhci_config_40mhz(void __iomem *usbh) +{ + writel((0x20 << SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S) | + (0x20 << SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S) | + (2 << SSUSB_MAC3_SYS_CK_GATE_MODE_S) | + (2 << SSUSB_MAC2_SYS_CK_GATE_MODE_S) | 0x10, + usbh + SSUSB_MAC_CK_CTRL_REG); + + writel((2 << SSUSB_PLL_PREDIV_PE1D_S) | (1 << SSUSB_PLL_PREDIV_U3_S) | + (4 << SSUSB_PLL_FBKDI_S), usbh + DA_SSUSB_U3PHYA_10_REG); + + writel((0x18 << SSUSB_PLL_FBKDIV_PE2H_S) | + (0x18 << SSUSB_PLL_FBKDIV_PE1D_S) | + (0x18 << SSUSB_PLL_FBKDIV_PE1H_S) | + (0x1e << SSUSB_PLL_FBKDIV_U3_S), + usbh + DA_SSUSB_PLL_FBKDIV_REG); + + writel((0x1e400000 << SSUSB_PLL_PCW_NCPO_U3_S), + usbh + DA_SSUSB_PLL_PCW_NCPO_REG); + + writel((0x25 << SSUSB_PLL_SSC_DELTA1_PE1H_S) | + (0x73 << SSUSB_PLL_SSC_DELTA1_U3_S), + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG); + + writel((0x71 << SSUSB_PLL_SSC_DELTA_U3_S) | + (0x4a << SSUSB_PLL_SSC_DELTA1_PE2D_S), + usbh + DA_SSUSB_U3PHYA_21_REG); + + writel((0x140 << SSUSB_PLL_SSC_PRD_S), usbh + SSUSB_U3PHYA_9_REG); + + writel((0x11c00000 << SSUSB_SYSPLL_PCW_NCPO_S), + usbh + SSUSB_U3PHYA_3_REG); + + writel((4 << SSUSB_PCIE_CLKDRV_AMP_S) | (1 << SSUSB_SYSPLL_FBSEL_S) | + (1 << SSUSB_SYSPLL_PREDIV_S), usbh + SSUSB_U3PHYA_1_REG); + + writel((0x12 << SSUSB_SYSPLL_FBDIV_S) | SSUSB_SYSPLL_VCO_DIV_SEL | + SSUSB_SYSPLL_FPEN | SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN, + usbh + SSUSB_U3PHYA_2_REG); + + writel(SSUSB_EQ_CURSEL | (8 << SSUSB_RX_DAC_MUX_S) | + (1 << SSUSB_PCIE_SIGDET_VTH_S) | (1 << SSUSB_PCIE_SIGDET_LPF_S), + usbh + SSUSB_U3PHYA_11_REG); + + writel((0x1ff << SSUSB_RING_OSC_CNTEND_S) | + (0x7f << SSUSB_XTAL_OSC_CNTEND_S) | SSUSB_RING_BYPASS_DET, + usbh + SSUSB_B2_ROSC_0_REG); + + writel((3 << SSUSB_RING_OSC_FRC_RECAL_S) | SSUSB_RING_OSC_FRC_SEL, + usbh + SSUSB_B2_ROSC_1_REG); +} + +static void xhci_config_25mhz(void __iomem *usbh) +{ + writel((0x20 << SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S) | + (0x20 << SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S) | + (2 << SSUSB_MAC3_SYS_CK_GATE_MODE_S) | + (2 << SSUSB_MAC2_SYS_CK_GATE_MODE_S) | 0x10, + usbh + SSUSB_MAC_CK_CTRL_REG); + + writel((2 << SSUSB_PLL_PREDIV_PE1D_S) | (4 << SSUSB_PLL_FBKDI_S), + usbh + DA_SSUSB_U3PHYA_10_REG); + + writel((0x18 << SSUSB_PLL_FBKDIV_PE2H_S) | + (0x18 << SSUSB_PLL_FBKDIV_PE1D_S) | + (0x18 << SSUSB_PLL_FBKDIV_PE1H_S) | + (0x19 << SSUSB_PLL_FBKDIV_U3_S), + usbh + DA_SSUSB_PLL_FBKDIV_REG); + + writel((0x18000000 << SSUSB_PLL_PCW_NCPO_U3_S), + usbh + DA_SSUSB_PLL_PCW_NCPO_REG); + + writel((0x25 << SSUSB_PLL_SSC_DELTA1_PE1H_S) | + (0x4a << SSUSB_PLL_SSC_DELTA1_U3_S), + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG); + + writel((0x48 << SSUSB_PLL_SSC_DELTA_U3_S) | + (0x4a << SSUSB_PLL_SSC_DELTA1_PE2D_S), + usbh + DA_SSUSB_U3PHYA_21_REG); + + writel((0x190 << SSUSB_PLL_SSC_PRD_S), usbh + SSUSB_U3PHYA_9_REG); + + writel((0xe000000 << SSUSB_SYSPLL_PCW_NCPO_S), + usbh + SSUSB_U3PHYA_3_REG); + + writel((4 << SSUSB_PCIE_CLKDRV_AMP_S) | (1 << SSUSB_SYSPLL_FBSEL_S), + usbh + SSUSB_U3PHYA_1_REG); + + writel((0xf << SSUSB_SYSPLL_FBDIV_S) | SSUSB_SYSPLL_VCO_DIV_SEL | + SSUSB_SYSPLL_FPEN | SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN, + usbh + SSUSB_U3PHYA_2_REG); + + writel(SSUSB_EQ_CURSEL | (8 << SSUSB_RX_DAC_MUX_S) | + (1 << SSUSB_PCIE_SIGDET_VTH_S) | (1 << SSUSB_PCIE_SIGDET_LPF_S), + usbh + SSUSB_U3PHYA_11_REG); + + writel((0x1ff << SSUSB_RING_OSC_CNTEND_S) | + (0x7f << SSUSB_XTAL_OSC_CNTEND_S) | SSUSB_RING_BYPASS_DET, + usbh + SSUSB_B2_ROSC_0_REG); + + writel((3 << SSUSB_RING_OSC_FRC_RECAL_S) | SSUSB_RING_OSC_FRC_SEL, + usbh + SSUSB_B2_ROSC_1_REG); +} + +void lowlevel_init(void) +{ + void __iomem *usbh = ioremap_nocache(SSUSB_BASE, SSUSB_SIZE); + u32 xtal = get_xtal_mhz(); + + /* Setup USB xHCI */ + if (xtal == 40) + xhci_config_40mhz(usbh); + else if (xtal == 25) + xhci_config_25mhz(usbh); +} + +ulong notrace get_tbclk(void) +{ + return gd->arch.timer_freq; +} + +void _machine_restart(void) +{ + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); + + while (1) + writel(SYS_RST, sysc + SYSCTL_RSTCTL_REG); +} diff --git a/arch/mips/mach-mtmips/mt7621/mt7621.h b/arch/mips/mach-mtmips/mt7621/mt7621.h new file mode 100644 index 0000000000..916cc993b4 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/mt7621.h @@ -0,0 +1,229 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#ifndef _MT7621_H_ +#define _MT7621_H_ + +#define SYSCTL_BASE 0x1e000000 +#define SYSCTL_SIZE 0x100 +#define TIMER_BASE 0x1e000100 +#define TIMER_SIZE 0x100 +#define RBUS_BASE 0x1e000400 +#define RBUS_SIZE 0x100 +#define GPIO_BASE 0x1e000600 +#define GPIO_SIZE 0x100 +#define DMA_CFG_ARB_BASE 0x1e000800 +#define DMA_CFG_ARB_SIZE 0x100 +#define SPI_BASE 0x1e000b00 +#define SPI_SIZE 0x100 +#define UART1_BASE 0x1e000c00 +#define UART1_SIZE 0x100 +#define UART2_BASE 0x1e000d00 +#define UART2_SIZE 0x100 +#define UART3_BASE 0x1e000e00 +#define UART3_SIZE 0x100 +#define NFI_BASE 0x1e003000 +#define NFI_SIZE 0x800 +#define NFI_ECC_BASE 0x1e003800 +#define NFI_ECC_SIZE 0x800 +#define DRAMC_BASE 0x1e005000 +#define DRAMC_SIZE 0x1000 +#define FE_BASE 0x1e100000 +#define FE_SIZE 0xe000 +#define GMAC_BASE 0x1e110000 +#define GMAC_SIZE 0x8000 +#define SSUSB_BASE 0x1e1c0000 +#define SSUSB_SIZE 0x40000 + + /* GIC Base Address */ +#define MIPS_GIC_BASE 0x1fbc0000 + + /* CPC Base Address */ +#define MIPS_CPC_BASE 0x1fbf0000 + + /* Flash Memory-mapped Base Address */ +#define FLASH_MMAP_BASE 0x1fc00000 +#define TPL_INFO_OFFSET 0x40 +#define TPL_INFO_MAGIC 0x31323637 /* Magic "7621" */ + +/* SRAM */ +#define FE_SRAM_BASE1 0x8000 +#define FE_SRAM_BASE2 0xa000 + +/* SYSCTL_BASE */ +#define SYSCTL_CHIP_REV_ID_REG 0x0c +#define CPU_ID 0x20000 +#define PKG_ID 0x10000 +#define VER_ID_S 8 +#define VER_ID_M 0xf00 +#define ECO_ID_S 0 +#define ECO_ID_M 0x0f + +#define SYSCTL_SYSCFG0_REG 0x10 +#define XTAL_MODE_SEL_S 6 +#define XTAL_MODE_SEL_M 0x1c0 +#define DRAM_TYPE 0x10 +#define CHIP_MODE_S 0 +#define CHIP_MODE_M 0x0f + +#define BOOT_SRAM_BASE_REG 0x20 + +#define SYSCTL_CLKCFG0_REG 0x2c +#define CPU_CLK_SEL_S 30 +#define CPU_CLK_SEL_M 0xc0000000 +#define MPLL_CFG_SEL_S 23 +#define MPLL_CFG_SEL_M 0x800000 + +#define SYSCTL_RSTCTL_REG 0x34 +#define MCM_RST 0x04 +#define SYS_RST 0x01 + +#define SYSCTL_CUR_CLK_STS_REG 0x44 +#define CUR_CPU_FDIV_S 8 +#define CUR_CPU_FDIV_M 0x1f00 +#define CUR_CPU_FFRAC_S 0 +#define CUR_CPU_FFRAC_M 0x1f + +#define SYSCTL_GPIOMODE_REG 0x60 +#define UART2_MODE_S 5 +#define UART2_MODE_M 0x60 +#define UART3_MODE_S 3 +#define UART3_MODE_M 0x18 +#define UART1_MODE 0x02 + +/* RBUS_BASE */ +#define RBUS_DYN_CFG0_REG 0x0010 +#define CPU_FDIV_S 8 +#define CPU_FDIV_M 0x1f00 +#define CPU_FFRAC_S 0 +#define CPU_FFRAC_M 0x1f + +/* DMA_CFG_ARB_BASE */ +#define DMA_ROUTE_REG 0x000c + +/* SPI_BASE */ +#define SPI_SPACE_REG 0x003c +#define FS_SLAVE_SEL_S 12 +#define FS_SLAVE_SEL_M 0x70000 +#define FS_CLK_SEL_S 0 +#define FS_CLK_SEL_M 0xfff + +/* FE_BASE */ +#define FE_RST_GLO_REG 0x0004 +#define FE_PSE_RAM 0x04 +#define FE_PSE_MEM_EN 0x02 +#define FE_PSE_RESET 0x01 + +/* SSUSB_BASE */ +#define SSUSB_MAC_CK_CTRL_REG 0x10784 +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S 16 +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M 0xff0000 +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S 8 +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M 0xff00 +#define SSUSB_MAC3_SYS_CK_GATE_MODE_S 2 +#define SSUSB_MAC3_SYS_CK_GATE_MODE_M 0x0c +#define SSUSB_MAC2_SYS_CK_GATE_MODE_S 0 +#define SSUSB_MAC2_SYS_CK_GATE_MODE_M 0x03 + +#define SSUSB_B2_ROSC_0_REG 0x10a40 +#define SSUSB_RING_OSC_CNTEND_S 23 +#define SSUSB_RING_OSC_CNTEND_M 0xff800000 +#define SSUSB_XTAL_OSC_CNTEND_S 16 +#define SSUSB_XTAL_OSC_CNTEND_M 0x7f0000 +#define SSUSB_RING_BYPASS_DET 0x01 + +#define SSUSB_B2_ROSC_1_REG 0x10a44 +#define SSUSB_RING_OSC_FRC_RECAL_S 17 +#define SSUSB_RING_OSC_FRC_RECAL_M 0x60000 +#define SSUSB_RING_OSC_FRC_SEL 0x01 + +#define SSUSB_U3PHYA_1_REG 0x10b04 +#define SSUSB_PCIE_CLKDRV_AMP_S 27 +#define SSUSB_PCIE_CLKDRV_AMP_M 0x38000000 +#define SSUSB_SYSPLL_FBSEL_S 2 +#define SSUSB_SYSPLL_FBSEL_M 0x0c +#define SSUSB_SYSPLL_PREDIV_S 0 +#define SSUSB_SYSPLL_PREDIV_M 0x03 + +#define SSUSB_U3PHYA_2_REG 0x10b08 +#define SSUSB_SYSPLL_FBDIV_S 24 +#define SSUSB_SYSPLL_FBDIV_M 0x7f000000 +#define SSUSB_SYSPLL_VCO_DIV_SEL 0x200000 +#define SSUSB_SYSPLL_FPEN 0x2000 +#define SSUSB_SYSPLL_MONCK_EN 0x1000 +#define SSUSB_SYSPLL_VOD_EN 0x200 + +#define SSUSB_U3PHYA_3_REG 0x10b10 +#define SSUSB_SYSPLL_PCW_NCPO_S 1 +#define SSUSB_SYSPLL_PCW_NCPO_M 0xfffffffe + +#define SSUSB_U3PHYA_9_REG 0x10b24 +#define SSUSB_PLL_SSC_PRD_S 0 +#define SSUSB_PLL_SSC_PRD_M 0xffff + +#define SSUSB_U3PHYA_11_REG 0x10b2c +#define SSUSB_EQ_CURSEL 0x1000000 +#define SSUSB_RX_DAC_MUX_S 19 +#define SSUSB_RX_DAC_MUX_M 0xf80000 +#define SSUSB_PCIE_SIGDET_VTH_S 5 +#define SSUSB_PCIE_SIGDET_VTH_M 0x60 +#define SSUSB_PCIE_SIGDET_LPF_S 3 +#define SSUSB_PCIE_SIGDET_LPF_M 0x18 + +#define DA_SSUSB_PLL_FBKDIV_REG 0x10c1c +#define SSUSB_PLL_FBKDIV_PE2H_S 24 +#define SSUSB_PLL_FBKDIV_PE2H_M 0x7f000000 +#define SSUSB_PLL_FBKDIV_PE1D_S 16 +#define SSUSB_PLL_FBKDIV_PE1D_M 0x7f0000 +#define SSUSB_PLL_FBKDIV_PE1H_S 8 +#define SSUSB_PLL_FBKDIV_PE1H_M 0x7f00 +#define SSUSB_PLL_FBKDIV_U3_S 0 +#define SSUSB_PLL_FBKDIV_U3_M 0x7f + +#define DA_SSUSB_U3PHYA_10_REG 0x10c20 +#define SSUSB_PLL_PREDIV_PE1D_S 18 +#define SSUSB_PLL_PREDIV_PE1D_M 0xc0000 +#define SSUSB_PLL_PREDIV_U3_S 8 +#define SSUSB_PLL_PREDIV_U3_M 0x300 +#define SSUSB_PLL_FBKDI_S 0 +#define SSUSB_PLL_FBKDI_M 0x07 + +#define DA_SSUSB_PLL_PCW_NCPO_REG 0x10c24 +#define SSUSB_PLL_PCW_NCPO_U3_S 0 +#define SSUSB_PLL_PCW_NCPO_U3_M 0x7fffffff + +#define DA_SSUSB_PLL_SSC_DELTA1_REG 0x10c38 +#define SSUSB_PLL_SSC_DELTA1_PE1H_S 16 +#define SSUSB_PLL_SSC_DELTA1_PE1H_M 0xffff0000 +#define SSUSB_PLL_SSC_DELTA1_U3_S 0 +#define SSUSB_PLL_SSC_DELTA1_U3_M 0xffff + +#define DA_SSUSB_U3PHYA_21_REG 0x10c40 +#define SSUSB_PLL_SSC_DELTA_U3_S 16 +#define SSUSB_PLL_SSC_DELTA_U3_M 0xffff0000 +#define SSUSB_PLL_SSC_DELTA1_PE2D_S 0 +#define SSUSB_PLL_SSC_DELTA1_PE2D_M 0xffff + +/* MT7621 specific CM values */ + +/* GCR_REGx_BASE */ +#define GCR_REG0_BASE_VALUE 0x1c000000 +#define GCR_REG1_BASE_VALUE 0x60000000 +#define GCR_REG2_BASE_VALUE 0x1c000000 +#define GCR_REG3_BASE_VALUE 0x1c000000 + +/* GCR_REGx_MASK */ +#define GCR_REG0_MASK_VALUE 0x0000fc00 /* 64M Bus */ +#define GCR_REG1_MASK_VALUE 0x0000f000 /* 256M PCI Mem */ +#define GCR_REG2_MASK_VALUE 0x0000fc00 /* unused */ +#define GCR_REG3_MASK_VALUE 0x0000fc00 /* unused */ + +#ifndef __ASSEMBLY__ +unsigned long get_xtal_mhz(void); +#endif + +#endif /* _MT7621_H_ */ diff --git a/arch/mips/mach-mtmips/mt7621/serial.c b/arch/mips/mach-mtmips/mt7621/serial.c new file mode 100644 index 0000000000..0ccc71dc75 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/serial.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <asm/io.h> +#include <asm/addrspace.h> +#include "mt7621.h" + +void board_debug_uart_init(void) +{ + void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); + +#if CONFIG_DEBUG_UART_BASE == 0xbe000c00 /* KSEG1ADDR(UART1_BASE) */ + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE); +#elif CONFIG_DEBUG_UART_BASE == 0xbe000d00 /* KSEG1ADDR(UART2_BASE) */ + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M); +#elif CONFIG_DEBUG_UART_BASE == 0xbe000e00 /* KSEG1ADDR(UART3_BASE) */ + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M); +#endif +} diff --git a/arch/mips/mach-mtmips/mt7621/spl/Makefile b/arch/mips/mach-mtmips/mt7621/spl/Makefile new file mode 100644 index 0000000000..ebe54e79b9 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/spl/Makefile @@ -0,0 +1,9 @@ + +extra-y += start.o + +obj-y += spl.o +obj-y += cps.o +obj-y += dram.o +obj-y += serial.o +obj-y += launch.o +obj-y += launch_ll.o diff --git a/arch/mips/mach-mtmips/mt7621/spl/cps.c b/arch/mips/mach-mtmips/mt7621/spl/cps.c new file mode 100644 index 0000000000..61f319f45f --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/spl/cps.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <asm/io.h> +#include <asm/addrspace.h> +#include <asm/mipsregs.h> +#include <asm/cm.h> +#include "../mt7621.h" + +/* GIC Shared Register Bases */ +#define GIC_SH_POL_BASE 0x100 +#define GIC_SH_TRIG_BASE 0x180 +#define GIC_SH_RMASK_BASE 0x300 +#define GIC_SH_SMASK_BASE 0x380 +#define GIC_SH_MASK_BASE 0x400 +#define GIC_SH_PEND_BASE 0x480 +#define GIC_SH_MAP_PIN_BASE 0x500 +#define GIC_SH_MAP_VPE_BASE 0x2000 + +/* GIC Registers */ +#define GIC_SH_POL31_0 (GIC_SH_POL_BASE + 0x00) +#define GIC_SH_POL63_32 (GIC_SH_POL_BASE + 0x04) + +#define GIC_SH_TRIG31_0 (GIC_SH_TRIG_BASE + 0x00) +#define GIC_SH_TRIG63_32 (GIC_SH_TRIG_BASE + 0x04) + +#define GIC_SH_RMASK31_0 (GIC_SH_RMASK_BASE + 0x00) +#define GIC_SH_RMASK63_32 (GIC_SH_RMASK_BASE + 0x04) + +#define GIC_SH_SMASK31_0 (GIC_SH_SMASK_BASE + 0x00) +#define GIC_SH_SMASK63_32 (GIC_SH_SMASK_BASE + 0x04) + +#define GIC_SH_MAP_PIN(n) (GIC_SH_MAP_PIN_BASE + (n) * 4) + +#define GIC_SH_MAP_VPE(n, v) (GIC_SH_MAP_VPE_BASE + (n) * 0x20 + ((v) / 32) * 4) +#define GIC_SH_MAP_VPE31_0(n) GIC_SH_MAP_VPE(n, 0) + +/* GIC_SH_MAP_PIN fields */ +#define GIC_MAP_TO_PIN BIT(31) +#define GIC_MAP_TO_NMI BIT(30) +#define GIC_MAP GENMASK(5, 0) +#define GIC_MAP_SHIFT 0 + +static void cm_init(void __iomem *cm_base) +{ + u32 num_cores; + + num_cores = ((readl(cm_base + GCR_CONFIG) & GCR_CONFIG_PCORES) >> + GCR_CONFIG_PCORES_SHIFT) + 1; + + writel((1 << num_cores) - 1, cm_base + GCR_ACCESS); + + writel(GCR_REG0_BASE_VALUE, cm_base + GCR_REG0_BASE); + writel(GCR_REG1_BASE_VALUE, cm_base + GCR_REG1_BASE); + writel(GCR_REG2_BASE_VALUE, cm_base + GCR_REG2_BASE); + writel(GCR_REG3_BASE_VALUE, cm_base + GCR_REG3_BASE); + + clrsetbits_32(cm_base + GCR_REG0_MASK, + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, + (GCR_REG0_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | + GCR_REGn_MASK_CMTGT_IOCU0); + + clrsetbits_32(cm_base + GCR_REG1_MASK, + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, + (GCR_REG1_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | + GCR_REGn_MASK_CMTGT_IOCU0); + + clrsetbits_32(cm_base + GCR_REG2_MASK, + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, + (GCR_REG2_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | + GCR_REGn_MASK_CMTGT_IOCU0); + + clrsetbits_32(cm_base + GCR_REG3_MASK, + GCR_REGn_MASK_ADDRMASK | GCR_REGn_MASK_CMTGT, + (GCR_REG3_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | + GCR_REGn_MASK_CMTGT_IOCU0); + + clrbits_32(cm_base + GCR_BASE, CM_DEFAULT_TARGET_MASK); + setbits_32(cm_base + GCR_CONTROL, GCR_CONTROL_SYNCCTL); +} + +static void gic_init(void) +{ + void __iomem *gic_base = (void *)KSEG1ADDR(MIPS_GIC_BASE); + int i; + + /* Interrupt 0..5: Level Trigger, Active High */ + writel(0, gic_base + GIC_SH_TRIG31_0); + writel(0x3f, gic_base + GIC_SH_RMASK31_0); + writel(0x3f, gic_base + GIC_SH_POL31_0); + writel(0x3f, gic_base + GIC_SH_SMASK31_0); + + /* Interrupt 56..63: Edge Trigger, Rising Edge */ + /* Hardcoded to set up the last 8 external interrupts for IPI. */ + writel(0xff000000, gic_base + GIC_SH_TRIG63_32); + writel(0xff000000, gic_base + GIC_SH_RMASK63_32); + writel(0xff000000, gic_base + GIC_SH_POL63_32); + writel(0xff000000, gic_base + GIC_SH_SMASK63_32); + + /* Map interrupt source to particular hardware interrupt pin */ + /* source {0,1,2,3,4,5} -> pin {0,0,4,3,0,5} */ + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(0)); + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(1)); + writel(GIC_MAP_TO_PIN | 4, gic_base + GIC_SH_MAP_PIN(2)); + writel(GIC_MAP_TO_PIN | 3, gic_base + GIC_SH_MAP_PIN(3)); + writel(GIC_MAP_TO_PIN | 0, gic_base + GIC_SH_MAP_PIN(4)); + writel(GIC_MAP_TO_PIN | 5, gic_base + GIC_SH_MAP_PIN(5)); + + /* source 56~59 -> pin 1, 60~63 -> pin 2 */ + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(56)); + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(57)); + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(58)); + writel(GIC_MAP_TO_PIN | 1, gic_base + GIC_SH_MAP_PIN(59)); + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(60)); + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(61)); + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(62)); + writel(GIC_MAP_TO_PIN | 2, gic_base + GIC_SH_MAP_PIN(63)); + + /* Interrupt map to VPE (bit mask) */ + for (i = 0; i < 32; i++) + writel(BIT(0), gic_base + GIC_SH_MAP_VPE31_0(i)); + + /* + * Direct GIC_int 56..63 to vpe 0..3 + * MIPS Linux convention that last 16 interrupts implemented be set + * aside for IPI signaling. + * The actual interrupts are tied low and software sends interrupts + * via GIC_SH_WEDGE writes. + */ + for (i = 0; i < 4; i++) { + writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + 56)); + writel(BIT(i), gic_base + GIC_SH_MAP_VPE31_0(i + 60)); + } +} + +void mt7621_cps_init(void) +{ + void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE); + + /* Enable GIC */ + writel(MIPS_GIC_BASE | GCR_GIC_EN, cm_base + GCR_GIC_BASE); + + /* Enable CPC */ + writel(MIPS_CPC_BASE | GCR_CPC_EN, cm_base + GCR_CPC_BASE); + + gic_init(); + cm_init(cm_base); +} diff --git a/arch/mips/mach-mtmips/mt7621/spl/dram.c b/arch/mips/mach-mtmips/mt7621/spl/dram.c new file mode 100644 index 0000000000..6c3b501ae5 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <asm/io.h> +#include <asm/sections.h> +#include <asm/byteorder.h> +#include <asm/addrspace.h> +#include <linux/string.h> +#include "../mt7621.h" +#include "dram.h" + +static const u32 ddr2_act[24] = { +#if defined(CONFIG_MT7621_DRAM_DDR2_512M) + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174441, + 0x00000000, 0xF0748661, 0x40001273, 0x9F0A0481, + 0x0304692F, 0x15602842, 0x00008888, 0x88888888, + 0x00000000, 0x00000000, 0x00000000, 0x07100000, + 0x00001B63, 0x00002000, 0x00004000, 0x00006000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +#elif defined(CONFIG_MT7621_DRAM_DDR2_512M_W9751G6KB_A02_1066MHZ) + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x33484584, + 0x00000000, 0xF07486A1, 0x50001273, 0x9F010481, + 0x0304693F, 0x15602842, 0x00008888, 0x88888888, + 0x00000000, 0x00000000, 0x00000010, 0x07100000, + 0x00001F73, 0x00002000, 0x00004000, 0x00006000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +#elif defined(CONFIG_MT7621_DRAM_DDR2_1024M_W971GG6KB25_800MHZ) + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174430, + 0x01000000, 0xF0748661, 0x40001273, 0x9F0F0481, + 0x0304692F, 0x15602842, 0x00008888, 0x88888888, + 0x00000000, 0x00000000, 0x00000000, 0x07100000, + 0x00001B63, 0x00002000, 0x00004000, 0x00006000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +#elif defined(CONFIG_MT7621_DRAM_DDR2_1024M_W971GG6KB18_1066MHZ) + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x33484584, + 0x01000000, 0xF07486A1, 0x50001273, 0x9F070481, + 0x0304693F, 0x15602842, 0x00008888, 0x88888888, + 0x00000000, 0x00000000, 0x00000010, 0x07100000, + 0x00001F73, 0x00002000, 0x00004000, 0x00006000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +#else /* CONFIG_MT7621_DRAM_DDR2_1024M */ + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x22174441, + 0x01000000, 0xF0748661, 0x40001273, 0x9F0F0481, + 0x0304692F, 0x15602842, 0x00008888, 0x88888888, + 0x00000000, 0x00000000, 0x00000000, 0x07100000, + 0x00001B63, 0x00002000, 0x00004000, 0x00006000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, +#endif +}; + +static const u32 ddr3_act[24] = { +#if defined(CONFIG_MT7621_DRAM_DDR3_1024M) + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694683, + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F060481, + 0x03046948, 0x15602842, 0x00008888, 0x88888888, + 0x00000000, 0x00000000, 0x00000210, 0x07100000, + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, + 0x0C000000, 0x07070000, 0x00000000, 0x00000000, +#elif defined(CONFIG_MT7621_DRAM_DDR3_4096M) + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694683, + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F0F0481, + 0x03046948, 0x15602842, 0x00008888, 0x88888888, + 0x00000000, 0x00000000, 0x00000240, 0x07100000, + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, + 0x0C000000, 0x07070000, 0x00000000, 0x00000000, +#elif defined(CONFIG_MT7621_DRAM_DDR3_1024M_KGD) + 0xFF00FF00, 0xFF00FF00, 0x00000007, 0x44694683, + 0x01000000, 0xF07406A1, 0xC287221D, 0x9F060481, + 0x03046923, 0x152f2842, 0x00008888, 0x88888888, + 0x00000000, 0x00000000, 0x00000210, 0x07100000, + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, + 0x0C000000, 0x07070000, 0x000C0000, 0x00000000, +#else /* CONFIG_MT7621_DRAM_DDR3_2048M */ + 0xAA00AA00, 0xAA00AA00, 0x00000007, 0x44694673, + 0x01000000, 0xF07486A1, 0xC287221D, 0x9F050481, + 0x03046948, 0x15602842, 0x00008888, 0x88888888, + 0x00000000, 0x00000000, 0x00000220, 0x07100000, + 0x00001B61, 0x00002040, 0x00004010, 0x00006000, + 0x0C000000, 0x07070000, 0x00000000, 0x00000000, +#endif +}; + +#if defined(CONFIG_MT7621_DRAM_FREQ_400) +#define DDR_FREQ_PARAM 0x41000000 +#elif defined(CONFIG_MT7621_DRAM_FREQ_1066) +#define DDR_FREQ_PARAM 0x21000000 +#elif defined(CONFIG_MT7621_DRAM_FREQ_1200) +#define DDR_FREQ_PARAM 0x11000000 +#else /* CONFIG_MT7621_DRAM_FREQ_800 */ +#define DDR_FREQ_PARAM 0x31000000 +#endif + +#define RG_MEPL_FBDIV_S 4 +#define RG_MEPL_FBDIV_M 0x7f + +static u32 calc_cpu_pll_val(void) +{ + u32 div, baseval, fb; + + div = get_xtal_mhz(); + + if (div == 40) { + div /= 2; + baseval = 0xc0005802; + } else { + baseval = 0xc0004802; + } + + fb = CONFIG_MT7621_CPU_FREQ / div - 1; + if (fb > RG_MEPL_FBDIV_M) + fb = RG_MEPL_FBDIV_M; + + return baseval | (fb << RG_MEPL_FBDIV_S); +} + +void prepare_stage_bin(void) +{ + const struct stage_header *stock_stage_bin = + (const struct stage_header *)__image_copy_end; + + struct stage_header *new_stage_bin = + (struct stage_header *)STAGE_LOAD_ADDR; + + if (be32_to_cpu(stock_stage_bin->ep) != STAGE_LOAD_ADDR) { + /* Possible wrong binary blob. Hang here */ + for (;;) + ; + } + + memcpy(new_stage_bin, stock_stage_bin, + be32_to_cpu(stock_stage_bin->stage_size)); + + memcpy(new_stage_bin->ddr2_act, ddr2_act, sizeof(ddr2_act)); + memcpy(new_stage_bin->ddr3_act, ddr3_act, sizeof(ddr3_act)); + + new_stage_bin->cpu_pll_cfg = calc_cpu_pll_val(); + new_stage_bin->ddr_pll_cfg = DDR_FREQ_PARAM; + new_stage_bin->baudrate = CONFIG_BAUDRATE; +} diff --git a/arch/mips/mach-mtmips/mt7621/spl/dram.h b/arch/mips/mach-mtmips/mt7621/spl/dram.h new file mode 100644 index 0000000000..4ca66644ef --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/spl/dram.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#ifndef _MT7621_DRAM_H_ +#define _MT7621_DRAM_H_ + +#define STAGE_LOAD_ADDR 0xBE108800 + +#ifndef __ASSEMBLY__ +#include <linux/types.h> + +struct stage_header { + u32 jump_insn[2]; + u32 ep; + u32 stage_size; + u32 has_stage2; + u32 next_ep; + u32 next_size; + u32 next_offset; + u32 cpu_pll_cfg; + u32 ddr_pll_cfg; + u32 reserved2[6]; + char build_tag[32]; + u32 ddr3_act[24]; + u32 padding1[2]; + u32 ddr2_act[24]; + u32 padding2[2]; + u32 baudrate; + u32 padding3; +}; +#endif + +#endif /* _MT7621_DRAM_H_ */ diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch.c b/arch/mips/mach-mtmips/mt7621/spl/launch.c new file mode 100644 index 0000000000..37c20a5f56 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <asm/io.h> +#include <asm/cm.h> +#include <asm/sections.h> +#include <asm/addrspace.h> +#include <asm/mipsmtregs.h> +#include <linux/sizes.h> +#include <time.h> +#include <cpu_func.h> +#include "launch.h" +#include "../mt7621.h" + +/* Cluster Power Controller (CPC) offsets */ +#define CPC_CL_OTHER 0x2010 +#define CPC_CO_CMD 0x4000 + +/* CPC_CL_OTHER fields */ +#define CPC_CL_OTHER_CORENUM_SHIFT 16 +#define CPC_CL_OTHER_CORENUM GENMASK(23, 16) + +/* CPC_CO_CMD */ +#define PWR_UP 3 + +#define NUM_CORES 2 +#define NUM_CPUS 4 +#define WAIT_CPUS_TIMEOUT 4000 + +static void copy_launch_wait_code(void) +{ + memset((void *)KSEG1, 0, SZ_4K); + + memcpy((void *)KSEG1ADDR(LAUNCH_WAITCODE), + &launch_wait_code_start, + &launch_wait_code_end - &launch_wait_code_start); + + invalidate_dcache_range(KSEG0, SZ_4K); +} + +static void bootup_secondary_core(void) +{ + void __iomem *cpcbase = (void __iomem *)KSEG1ADDR(MIPS_CPC_BASE); + int i; + + for (i = 1; i < NUM_CORES; i++) { + writel(i << CPC_CL_OTHER_CORENUM_SHIFT, cpcbase + CPC_CL_OTHER); + writel(PWR_UP, cpcbase + CPC_CO_CMD); + } +} + +void secondary_cpu_init(void) +{ + void __iomem *sysc = (void __iomem *)KSEG1ADDR(SYSCTL_BASE); + u32 i, dual_core = 0, cpuready = 1, cpumask = 0x03; + ulong wait_tick; + struct cpulaunch_t *c; + + /* Copy LAUNCH wait code used by other VPEs */ + copy_launch_wait_code(); + + dual_core = readl(sysc + SYSCTL_CHIP_REV_ID_REG) & CPU_ID; + + if (dual_core) { + /* Bootup secondary core for MT7621A */ + cpumask = 0x0f; + + /* Make BootROM/TPL redirect Core1's bootup flow to our entry point */ + writel((uintptr_t)&_start, sysc + BOOT_SRAM_BASE_REG); + + bootup_secondary_core(); + } + + /* Join the coherent domain */ + join_coherent_domain(dual_core ? 2 : 1); + + /* Bootup Core0/VPE1 */ + boot_vpe1(); + + /* Wait for all CPU ready */ + wait_tick = get_timer(0) + WAIT_CPUS_TIMEOUT; + + while (time_before(get_timer(0), wait_tick)) { + /* CPU0 is obviously ready */ + for (i = 1; i < NUM_CPUS; i++) { + c = (struct cpulaunch_t *)(KSEG0ADDR(CPULAUNCH) + + (i << LOG2CPULAUNCH)); + + if (c->flags & LAUNCH_FREADY) + cpuready |= BIT(i); + } + + if ((cpuready & cpumask) == cpumask) + break; + } +} diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch.h b/arch/mips/mach-mtmips/mt7621/spl/launch.h new file mode 100644 index 0000000000..f34250d605 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/spl/launch.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#ifndef _LAUNCH_H_ +#define _LAUNCH_H_ + +#ifndef __ASSEMBLY__ + +struct cpulaunch_t { + unsigned long pc; + unsigned long gp; + unsigned long sp; + unsigned long a0; + unsigned long _pad[3]; /* pad to cache line size to avoid thrashing */ + unsigned long flags; +}; + +extern char launch_wait_code_start; +extern char launch_wait_code_end; + +void join_coherent_domain(int ncores); +void boot_vpe1(void); + +#else + +#define LAUNCH_PC 0 +#define LAUNCH_GP 4 +#define LAUNCH_SP 8 +#define LAUNCH_A0 12 +#define LAUNCH_FLAGS 28 + +#endif + +#define LOG2CPULAUNCH 5 + +#define LAUNCH_FREADY 1 +#define LAUNCH_FGO 2 +#define LAUNCH_FGONE 4 + +#define LAUNCH_WAITCODE 0x00000d00 +#define SCRLAUNCH 0x00000e00 +#define CPULAUNCH 0x00000f00 +#define NCPULAUNCH 8 + +/* Polling period in count cycles for secondary CPU's */ +#define LAUNCHPERIOD 10000 + +#endif /* _LAUNCH_H_ */ diff --git a/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S new file mode 100644 index 0000000000..55a8fff9af --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/spl/launch_ll.S @@ -0,0 +1,357 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <asm/cm.h> +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/cacheops.h> +#include <asm/mipsregs.h> +#include <asm/addrspace.h> +#include <asm/mipsmtregs.h> +#include "launch.h" + + .macro cache_loop curr, end, line_sz, op +10: cache \op, 0(\curr) + PTR_ADDU \curr, \curr, \line_sz + bne \curr, \end, 10b + .endm + + .set mt + +/* + * Join the coherent domain + * a0 = number of cores + */ +LEAF(join_coherent_domain) + /* + * Enable coherence and allow interventions from all other cores. + * (Write access enabled via GCR_ACCESS by core 0.) + */ + li t1, 1 + sll t1, a0 + addiu t1, -1 + + li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE) + sw t1, GCR_Cx_COHERENCE(t0) + ehb + + move t2, zero + +_next_coherent_core: + sll t1, t2, GCR_Cx_OTHER_CORENUM_SHIFT + sw t1, GCR_Cx_OTHER(t0) + +_busy_wait_coherent_core: + lw t1, GCR_CO_COHERENCE(t0) + beqz t1, _busy_wait_coherent_core + nop + + addiu t2, 1 + bne t2, a0, _next_coherent_core + nop + + jr ra + nop + END(join_coherent_domain) + +/* + * All VPEs other than VPE0 will go here. + */ +LEAF(launch_vpe_entry) + mfc0 t0, CP0_EBASE + and t0, t0, MIPS_EBASE_CPUNUM + + /* per-VPE cpulaunch_t */ + li a0, KSEG0ADDR(CPULAUNCH) + sll t1, t0, LOG2CPULAUNCH + addu a0, t1 + + /* Set CPU online flag */ + li t0, LAUNCH_FREADY + sw t0, LAUNCH_FLAGS(a0) + + /* Enable count interrupt in mask, but do not enable interrupts */ + mfc0 t0, CP0_STATUS + ori t0, STATUSF_IP7 + mtc0 t0, CP0_STATUS + + /* VPEs executing in wait code do not need a stack */ + li t9, KSEG0ADDR(LAUNCH_WAITCODE) + jr t9 + nop + END(launch_vpe_entry) + +/* + * This function will not be executed in place. + * It will be copied into memory, and VPEs other than VPE0 will be + * started to run into this in-memory function. + */ +LEAF(launch_wait_code) + .globl launch_wait_code_start +launch_wait_code_start: + + move t0, a0 + +start_poll: + /* Poll CPU go flag */ + mtc0 zero, CP0_COUNT + li t1, LAUNCHPERIOD + mtc0 t1, CP0_COMPARE + +time_wait: + /* Software wait */ + mfc0 t2, CP0_COUNT + subu t2, t1 + bltz t2, time_wait + nop + + /* Check the launch flag */ + lw t3, LAUNCH_FLAGS(t0) + and t3, LAUNCH_FGO + beqz t3, start_poll + nop + + /* Reset the counter and interrupts to give naive clients a chance */ + mfc0 t1, CP0_STATUS + ins t1, zero, STATUSB_IP7, 1 + mtc0 t1, CP0_STATUS + + mfc0 t1, CP0_COUNT + subu t1, 1 + mtc0 t1, CP0_COMPARE + + /* Jump to kernel */ + lw t9, LAUNCH_PC(t0) + lw gp, LAUNCH_GP(t0) + lw sp, LAUNCH_SP(t0) + lw a0, LAUNCH_A0(t0) + move a1, zero + move a2, zero + move a3, zero + ori t3, LAUNCH_FGONE + sw t3, LAUNCH_FLAGS(t0) + + jr t9 + nop + + .globl launch_wait_code_end +launch_wait_code_end: + END(launch_wait_code) + +/* + * Core1 will go here. + */ +LEAF(launch_core_entry) + /* Disable caches */ + bal mips_cache_disable + nop + + /* Initialize L1 cache only */ + li a0, CONFIG_SYS_ICACHE_SIZE + li a1, CONFIG_SYS_ICACHE_LINE_SIZE + li a2, CONFIG_SYS_DCACHE_SIZE + li a3, CONFIG_SYS_DCACHE_LINE_SIZE + + mtc0 zero, CP0_TAGLO + mtc0 zero, CP0_TAGLO, 2 + ehb + + /* + * Initialize the I-cache first, + */ + li t0, KSEG0 + addu t1, t0, a0 + /* clear tag to invalidate */ + cache_loop t0, t1, a1, INDEX_STORE_TAG_I +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD + /* fill once, so data field parity is correct */ + PTR_LI t0, KSEG0 + cache_loop t0, t1, a1, FILL + /* invalidate again - prudent but not strictly necessary */ + PTR_LI t0, KSEG0 + cache_loop t0, t1, a1, INDEX_STORE_TAG_I +#endif + + /* + * then initialize D-cache. + */ + PTR_LI t0, KSEG0 + PTR_ADDU t1, t0, a2 + /* clear all tags */ + cache_loop t0, t1, a3, INDEX_STORE_TAG_D +#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD + /* load from each line (in cached space) */ + PTR_LI t0, KSEG0 +2: LONG_L zero, 0(t0) + PTR_ADDU t0, a3 + bne t0, t1, 2b + /* clear all tags */ + PTR_LI t0, KSEG0 + cache_loop t0, t1, a3, INDEX_STORE_TAG_D +#endif + + /* Set Cache Mode */ + mfc0 t0, CP0_CONFIG + li t1, CONF_CM_CACHABLE_COW + ins t0, t1, 0, 3 + mtc0 t0, CP0_CONFIG + + /* Join the coherent domain */ + li a0, 2 + bal join_coherent_domain + nop + + /* Bootup Core0/VPE1 */ + bal boot_vpe1 + nop + + b launch_vpe_entry + nop + END(launch_core_entry) + +/* + * Bootup VPE1. + * This subroutine must be executed from VPE0 with VPECONF0[MVP] already set. + */ +LEAF(boot_vpe1) + mfc0 t0, CP0_MVPCONF0 + + /* a0 = number of TCs - 1 */ + ext a0, t0, MVPCONF0_PTC_SHIFT, 8 + beqz a0, _vpe1_init_done + nop + + /* a1 = number of VPEs - 1 */ + ext a1, t0, MVPCONF0_PVPE_SHIFT, 4 + beqz a1, _vpe1_init_done + nop + + /* a2 = current TC No. */ + move a2, zero + + /* Enter VPE Configuration State */ + mfc0 t0, CP0_MVPCONTROL + or t0, MVPCONTROL_VPC + mtc0 t0, CP0_MVPCONTROL + ehb + +_next_tc: + /* Set the TC number to be used on MTTR and MFTR instructions */ + mfc0 t0, CP0_VPECONTROL + ins t0, a2, 0, 8 + mtc0 t0, CP0_VPECONTROL + ehb + + /* TC0 is already bound */ + beqz a2, _next_vpe + nop + + /* Halt current TC */ + li t0, TCHALT_H + mttc0 t0, CP0_TCHALT + ehb + + /* If there is spare TC, bind it to the last VPE (VPE[a1]) */ + slt t1, a1, a2 + bnez t1, _vpe_bind_tc + move t1, a1 + + /* Set Exclusive TC for active TC */ + mftc0 t0, CP0_VPECONF0 + ins t0, a2, VPECONF0_XTC_SHIFT, 8 + mttc0 t0, CP0_VPECONF0 + + move t1, a2 +_vpe_bind_tc: + /* Bind TC to a VPE */ + mftc0 t0, CP0_TCBIND + ins t0, t1, TCBIND_CURVPE_SHIFT, 4 + mttc0 t0, CP0_TCBIND + + /* + * Set up CP0_TCSTATUS register: + * Disable Coprocessor Usable bits + * Disable MDMX/DSP ASE + * Clear Dirty TC + * not dynamically allocatable + * not allocated + * Kernel mode + * interrupt exempt + * ASID 0 + */ + li t0, TCSTATUS_IXMT + mttc0 t0, CP0_TCSTATUS + +_next_vpe: + slt t1, a1, a2 + bnez t1, _done_vpe # No more VPEs + nop + + /* Disable TC multi-threading */ + mftc0 t0, CP0_VPECONTROL + ins t0, zero, VPECONTROL_TE_SHIFT, 1 + mttc0 t0, CP0_VPECONTROL + + /* Skip following configuration for TC0 */ + beqz a2, _done_vpe + nop + + /* Deactivate VPE, set Master VPE */ + mftc0 t0, CP0_VPECONF0 + ins t0, zero, VPECONF0_VPA_SHIFT, 1 + or t0, VPECONF0_MVP + mttc0 t0, CP0_VPECONF0 + + mfc0 t0, CP0_STATUS + mttc0 t0, CP0_STATUS + + mttc0 zero, CP0_EPC + mttc0 zero, CP0_CAUSE + + mfc0 t0, CP0_CONFIG + mttc0 t0, CP0_CONFIG + + /* + * VPE1 of each core can execute cached as its L1 I$ has already + * been initialized. + * and the L2$ has been initialized or "disabled" via CCA override. + */ + PTR_LA t0, _start + mttc0 t0, CP0_TCRESTART + + /* Unset Interrupt Exempt, set Activate Thread */ + mftc0 t0, CP0_TCSTATUS + ins t0, zero, TCSTATUS_IXMT_SHIFT, 1 + ori t0, TCSTATUS_A + mttc0 t0, CP0_TCSTATUS + + /* Resume TC */ + mttc0 zero, CP0_TCHALT + + /* Activate VPE */ + mftc0 t0, CP0_VPECONF0 + ori t0, VPECONF0_VPA + mttc0 t0, CP0_VPECONF0 + +_done_vpe: + addu a2, 1 + sltu t0, a0, a2 + beqz t0, _next_tc + nop + + mfc0 t0, CP0_MVPCONTROL + /* Enable all activated VPE to execute */ + ori t0, MVPCONTROL_EVP + /* Exit VPE Configuration State */ + ins t0, zero, MVPCONTROL_VPC_SHIFT, 1 + mtc0 t0, CP0_MVPCONTROL + ehb + +_vpe1_init_done: + jr ra + nop + END(boot_vpe1) diff --git a/arch/mips/mach-mtmips/mt7621/spl/serial.c b/arch/mips/mach-mtmips/mt7621/spl/serial.c new file mode 100644 index 0000000000..5cf093a078 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/spl/serial.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <asm/io.h> +#include "../mt7621.h" + +void mtmips_spl_serial_init(void) +{ +#ifdef CONFIG_SPL_SERIAL + void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); + +#if CONFIG_CONS_INDEX == 1 + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE); +#elif CONFIG_CONS_INDEX == 2 + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M); +#elif CONFIG_CONS_INDEX == 3 + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M); +#endif /* CONFIG_CONS_INDEX */ +#endif /* CONFIG_SPL_SERIAL */ +} diff --git a/arch/mips/mach-mtmips/mt7621/spl/spl.c b/arch/mips/mach-mtmips/mt7621/spl/spl.c new file mode 100644 index 0000000000..71d01aa7f5 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/spl/spl.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <spl.h> +#include <init.h> +#include <image.h> +#include <vsprintf.h> +#include <malloc.h> +#include <asm/io.h> +#include <asm/sections.h> +#include <asm/addrspace.h> +#include <asm/byteorder.h> +#include <asm/global_data.h> +#include <linux/sizes.h> +#include <mach/serial.h> +#include "../mt7621.h" +#include "dram.h" + +DECLARE_GLOBAL_DATA_PTR; + +struct tpl_info { + u32 magic; + u32 size; +}; + +void set_timer_freq_simple(void) +{ + u32 div = get_xtal_mhz(); + + /* Round down cpu freq */ + gd->arch.timer_freq = rounddown(CONFIG_MT7621_CPU_FREQ, div) * 500000; +} + +void __noreturn board_init_f(ulong dummy) +{ + spl_init(); + +#ifdef CONFIG_SPL_SERIAL + /* + * mtmips_spl_serial_init() is useful if debug uart is enabled, + * or DM based serial is not enabled. + */ + mtmips_spl_serial_init(); + preloader_console_init(); +#endif + + board_init_r(NULL, 0); +} + +void board_boot_order(u32 *spl_boot_list) +{ +#ifdef CONFIG_MT7621_BOOT_FROM_NAND + spl_boot_list[0] = BOOT_DEVICE_NAND; +#else + spl_boot_list[0] = BOOT_DEVICE_NOR; +#endif +} + +unsigned long spl_nor_get_uboot_base(void) +{ + const struct tpl_info *tpli; + const image_header_t *hdr; + u32 addr; + + addr = FLASH_MMAP_BASE + TPL_INFO_OFFSET; + tpli = (const struct tpl_info *)KSEG1ADDR(addr); + + if (tpli->magic == TPL_INFO_MAGIC) { + addr = FLASH_MMAP_BASE + tpli->size; + hdr = (const image_header_t *)KSEG1ADDR(addr); + + if (image_get_magic(hdr) == IH_MAGIC) { + addr += sizeof(*hdr) + image_get_size(hdr); + return KSEG1ADDR(addr); + } + } + + panic("Unable to locate SPL payload\n"); + return 0; +} + +uint32_t spl_nand_get_uboot_raw_page(void) +{ + const struct stage_header *sh = (const struct stage_header *)&_start; + u32 addr; + + addr = image_get_header_size() + be32_to_cpu(sh->stage_size); + addr = ALIGN(addr, SZ_4K); + + return addr; +} diff --git a/arch/mips/mach-mtmips/mt7621/spl/start.S b/arch/mips/mach-mtmips/mt7621/spl/start.S new file mode 100644 index 0000000000..3cad3567e7 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/spl/start.S @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <asm-offsets.h> +#include <config.h> +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> +#include <asm/cacheops.h> +#include <asm/addrspace.h> +#include <asm/mipsmtregs.h> +#include <asm/cm.h> +#include "../mt7621.h" +#include "dram.h" + +#ifndef CONFIG_SYS_INIT_SP_ADDR +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ + CONFIG_SYS_INIT_SP_OFFSET) +#endif + +#define SP_ADDR_TEMP 0xbe10dff0 + + .macro init_wr sel + MTC0 zero, CP0_WATCHLO,\sel + mtc0 t1, CP0_WATCHHI,\sel + .endm + + .macro setup_stack_gd + li t0, -16 + PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR + and sp, t1, t0 # force 16 byte alignment + PTR_SUBU \ + sp, sp, GD_SIZE # reserve space for gd + and sp, sp, t0 # force 16 byte alignment + move k0, sp # save gd pointer +#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \ + !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) + li t2, CONFIG_VAL(SYS_MALLOC_F_LEN) + PTR_SUBU \ + sp, sp, t2 # reserve space for early malloc + and sp, sp, t0 # force 16 byte alignment +#endif + move fp, sp + + /* Clear gd */ + move t0, k0 +1: + PTR_S zero, 0(t0) + PTR_ADDIU t0, PTRSIZE + blt t0, t1, 1b + nop + +#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \ + !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) + PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset +#endif + .endm + + .set noreorder + +ENTRY(_start) + b 1f + mtc0 zero, CP0_COUNT + + /* Stage header required by BootROM */ + .org 0x8 + .word 0 # ep, filled by mkimage + .word 0 # stage_size, filled by mkimage + .word 0 # has_stage2 + .word 0 # next_ep + .word 0 # next_size + .word 0 # next_offset + +1: + /* Init CP0 Status */ + mfc0 t0, CP0_STATUS + and t0, ST0_IMPL + or t0, ST0_BEV | ST0_ERL + mtc0 t0, CP0_STATUS + ehb + + /* Clear Watch Status bits and disable watch exceptions */ + li t1, 0x7 # Clear I, R and W conditions + init_wr 0 + init_wr 1 + init_wr 2 + init_wr 3 + + /* Clear WP, IV and SW interrupts */ + mtc0 zero, CP0_CAUSE + + /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */ + mtc0 zero, CP0_COMPARE + + /* VPE1 goes to wait code directly */ + mfc0 t0, CP0_TCBIND + andi t0, TCBIND_CURVPE + bnez t0, launch_vpe_entry + nop + + /* Core1 goes to specific launch entry */ + PTR_LI t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE) + lw t1, GCR_Cx_ID(t0) + bnez t1, launch_core_entry + nop + + /* MT7530 reset */ + li t0, KSEG1ADDR(SYSCTL_BASE) + lw t1, SYSCTL_RSTCTL_REG(t0) + ori t1, MCM_RST + sw t1, SYSCTL_RSTCTL_REG(t0) + + /* Disable DMA route for PSE SRAM set by BootROM */ + PTR_LI t0, KSEG1ADDR(DMA_CFG_ARB_BASE) + sw zero, DMA_ROUTE_REG(t0) + + /* Set CPU clock to 500MHz (Required if boot from NAND) */ + li t0, KSEG1ADDR(SYSCTL_BASE) + lw t1, SYSCTL_CLKCFG0_REG(t0) + ins t1, zero, 30, 2 # CPU_CLK_SEL + sw t1, SYSCTL_CLKCFG0_REG(t0) + + /* Set CPU clock divider to 1/1 */ + li t0, KSEG1ADDR(RBUS_BASE) + li t1, 0x101 + sw t1, RBUS_DYN_CFG0_REG(t0) + + /* (Re-)initialize the SRAM */ + bal mips_sram_init + nop + + /* Set up temporary stack */ + li sp, SP_ADDR_TEMP + + /* Setup full CPS */ + bal mips_cm_map + nop + + bal mt7621_cps_init + nop + + /* Prepare for CPU/DDR initialization binary blob */ + bal prepare_stage_bin + nop + + /* Call CPU/DDR initialization binary blob */ + li t9, STAGE_LOAD_ADDR + jalr t9 + nop + + /* Switch CPU PLL source */ + li t0, KSEG1ADDR(SYSCTL_BASE) + lw t1, SYSCTL_CLKCFG0_REG(t0) + li t2, 1 + ins t1, t2, CPU_CLK_SEL_S, 2 + sw t1, SYSCTL_CLKCFG0_REG(t0) + + /* + * Currently SPL is running on locked L2 cache (on KSEG0). + * To reset the entire cache, we have to writeback SPL to DRAM first. + * Cache flush won't work here. Use memcpy instead. + */ + + la a0, __text_start + move a1, a0 + la a2, __image_copy_end + sub a2, a2, a1 + li a3, 5 + ins a0, a3, 29, 3 # convert to KSEG1 + + bal memcpy + nop + + /* Disable caches */ + bal mips_cache_disable + nop + + /* Reset caches */ + bal mips_cache_reset + nop + + /* Disable SRAM */ + li t0, KSEG1ADDR(FE_BASE) + li t1, FE_PSE_RESET + sw t1, FE_RST_GLO_REG(t0) + + /* Clear the .bss section */ + la a0, __bss_start + la a1, __bss_end +1: sw zero, 0(a0) + addiu a0, 4 + ble a0, a1, 1b + nop + + /* Set up initial stack and global data */ + setup_stack_gd + +#if CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) + /* Set malloc base */ + li t0, (CONFIG_SYS_INIT_SP_ADDR + 15) & (~15) + PTR_S t0, GD_MALLOC_BASE(k0) # gd->malloc_base offset +#endif + +#if defined(CONFIG_DEBUG_UART) && defined(CONFIG_SPL_SERIAL) + /* Earliest point to set up debug uart */ + bal debug_uart_init + nop +#endif + + /* Setup timer */ + bal set_timer_freq_simple + nop + + /* Bootup secondary CPUs */ + bal secondary_cpu_init + nop + + move a0, zero # a0 <-- boot_flags = 0 + bal board_init_f + move ra, zero + + END(_start) diff --git a/arch/mips/mach-mtmips/mt7621/sram_init.S b/arch/mips/mach-mtmips/mt7621/sram_init.S new file mode 100644 index 0000000000..74ddd6bcd7 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/sram_init.S @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <asm/addrspace.h> +#include <asm/asm.h> +#include <asm/regdef.h> +#include "mt7621.h" + +LEAF(mips_sram_init) + li t0, KSEG1ADDR(FE_BASE) + li t1, FE_PSE_RESET + sw t1, FE_RST_GLO_REG(t0) + + li t1, (FE_PSE_RAM | FE_PSE_MEM_EN) + sw t1, FE_RST_GLO_REG(t0) + + jr ra + END(mips_sram_init) diff --git a/arch/mips/mach-mtmips/mt7621/tpl/Makefile b/arch/mips/mach-mtmips/mt7621/tpl/Makefile new file mode 100644 index 0000000000..471ad74249 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/tpl/Makefile @@ -0,0 +1,4 @@ + +extra-y += start.o + +obj-y += tpl.o diff --git a/arch/mips/mach-mtmips/mt7621/tpl/start.S b/arch/mips/mach-mtmips/mt7621/tpl/start.S new file mode 100644 index 0000000000..19b09f7251 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/tpl/start.S @@ -0,0 +1,161 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <asm-offsets.h> +#include <config.h> +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/addrspace.h> +#include <asm/mipsregs.h> +#include <asm/cm.h> +#include "../mt7621.h" + +#define SP_ADDR_TEMP 0xbe10dff0 + + .set noreorder + + .macro init_wr sel + MTC0 zero, CP0_WATCHLO,\sel + mtc0 t1, CP0_WATCHHI,\sel + .endm + + .macro uhi_mips_exception + move k0, t9 # preserve t9 in k0 + move k1, a0 # preserve a0 in k1 + li t9, 15 # UHI exception operation + li a0, 0 # Use hard register context + sdbbp 1 # Invoke UHI operation + .endm + +ENTRY(_start) + b reset + mtc0 zero, CP0_COUNT + + /* + * Store TPL size here. + * This will be used by SPL to locate u-boot payload. + */ + .org TPL_INFO_OFFSET + .word TPL_INFO_MAGIC + .word __image_copy_len + + /* Exception vector */ + .org 0x200 + /* TLB refill, 32 bit task */ + uhi_mips_exception + + .org 0x280 + /* XTLB refill, 64 bit task */ + uhi_mips_exception + + .org 0x300 + /* Cache error exception */ + uhi_mips_exception + + .org 0x380 + /* General exception */ + uhi_mips_exception + + .org 0x400 + /* Catch interrupt exceptions */ + uhi_mips_exception + + .org 0x480 + /* EJTAG debug exception */ +1: b 1b + nop + + .org 0x500 + +reset: + /* Set KSEG0 to Uncached */ + mfc0 t0, CP0_CONFIG + ins t0, zero, 0, 3 + ori t0, t0, CONF_CM_UNCACHED + mtc0 t0, CP0_CONFIG + ehb + + /* Check for CPU number */ + mfc0 t0, CP0_EBASE + and t0, t0, MIPS_EBASE_CPUNUM + beqz t0, 1f + nop + + /* Secondary core goes to specified SPL entry address */ + li t0, KSEG1ADDR(SYSCTL_BASE) + lw t0, BOOT_SRAM_BASE_REG(t0) + jr t0 + nop + + /* Init CP0 Status */ +1: mfc0 t0, CP0_STATUS + and t0, ST0_IMPL + or t0, ST0_BEV | ST0_ERL + mtc0 t0, CP0_STATUS + nop + + /* Clear Watch Status bits and disable watch exceptions */ + li t1, 0x7 # Clear I, R and W conditions + init_wr 0 + init_wr 1 + init_wr 2 + init_wr 3 + + /* Clear WP, IV and SW interrupts */ + mtc0 zero, CP0_CAUSE + + /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */ + mtc0 zero, CP0_COMPARE + + /* Setup basic CPS */ + bal mips_cm_map + nop + + li t0, KSEG1ADDR(CONFIG_MIPS_CM_BASE) + li t1, GCR_REG0_BASE_VALUE + sw t1, GCR_REG0_BASE(t0) + + li t1, ((GCR_REG0_MASK_VALUE << GCR_REGn_MASK_ADDRMASK_SHIFT) | \ + GCR_REGn_MASK_CMTGT_IOCU0) + sw t1, GCR_REG0_MASK(t0) + + lw t1, GCR_BASE(t0) + ins t1, zero, 0, 2 # CM_DEFAULT_TARGET + sw t1, GCR_BASE(t0) + + lw t1, GCR_CONTROL(t0) + li t2, GCR_CONTROL_SYNCCTL + or t1, t1, t2 + sw t1, GCR_CONTROL(t0) + + /* Increase SPI frequency */ + li t0, KSEG1ADDR(SPI_BASE) + li t1, 5 + sw t1, SPI_SPACE_REG(t0) + + /* Set CPU clock to 500MHz */ + li t0, KSEG1ADDR(SYSCTL_BASE) + lw t1, SYSCTL_CLKCFG0_REG(t0) + ins t1, zero, 30, 2 # CPU_CLK_SEL + sw t1, SYSCTL_CLKCFG0_REG(t0) + + /* Set CPU clock divider to 1/1 */ + li t0, KSEG1ADDR(RBUS_BASE) + li t1, 0x101 + sw t1, RBUS_DYN_CFG0_REG(t0) + + /* Initialize the SRAM */ + bal mips_sram_init + nop + + /* Set up initial stack */ + li sp, SP_ADDR_TEMP + + bal tpl_main + nop + + END(_start) diff --git a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c new file mode 100644 index 0000000000..77bcf0ddf0 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#include <image.h> +#include <asm/sections.h> +#include <asm/cacheops.h> +#include <asm/mipsregs.h> +#include <asm/cm.h> + +#define INDEX_STORE_DATA_SD 0x0f + +typedef void __noreturn (*image_entry_noargs_t)(void); + +static inline void ehb(void) +{ + __asm__ __volatile__ ("ehb"); +} + +/* + * Lock L2 cache and fill data + * Assume that data is 4-byte aligned and start_addr/size is 32-byte aligned + */ +static void fill_lock_l2cache(uintptr_t dataptr, ulong start_addr, ulong size) +{ + ulong slsize = CONFIG_SYS_DCACHE_LINE_SIZE; + ulong end_addr = start_addr + size; + const u32 *data = (u32 *)dataptr; + ulong i, addr; + u32 val; + + /* Clear WSC & SPR bit in ErrCtl */ + val = read_c0_ecc(); + val &= 0xcfffffff; + write_c0_ecc(val); + ehb(); + + for (addr = start_addr; addr < end_addr; addr += slsize) { + /* Set STagLo to lock cache line */ + write_c0_staglo((addr & 0x1ffff800) | 0xa0); + mips_cache(INDEX_STORE_TAG_SD, (void *)addr); + + /* Fill data */ + for (i = 0; i < slsize; i += 8) { + val = *data++; + __write_32bit_c0_register($28, 5, val); /* sdtaglo */ + val = *data++; + __write_32bit_c0_register($29, 5, val); /* sdtaghi */ + mips_cache(INDEX_STORE_DATA_SD, (void *)(addr + i)); + } + } +} + +/* A simple function to initialize MT7621's cache */ +static void mt7621_cache_init(void) +{ + void __iomem *cm_base = (void *)KSEG1ADDR(CONFIG_MIPS_CM_BASE); + ulong lsize = CONFIG_SYS_DCACHE_LINE_SIZE; + ulong addr; + u32 val; + + /* Enable CCA override. Set to uncached */ + val = readl(cm_base + GCR_BASE); + val &= ~CCA_DEFAULT_OVR_MASK; + val |= CCA_DEFAULT_OVREN | (2 << CCA_DEFAULT_OVR_SHIFT); + writel(val, cm_base + GCR_BASE); + + /* Initialize L1 I-Cache */ + write_c0_taglo(0); + write_c0_taghi(0); + + for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += lsize) + mips_cache(INDEX_STORE_TAG_I, (void *)addr); + + /* Initialize L1 D-Cache */ + write_c0_dtaglo(0); + __write_32bit_c0_register($29, 2, 0); /* dtaghi */ + + for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += lsize) + mips_cache(INDEX_STORE_TAG_D, (void *)addr); + + /* Initialize L2 Cache */ + write_c0_staglo(0); + __write_32bit_c0_register($29, 4, 0); /* staghi */ + + for (addr = 0; addr < (256 << 10); addr += lsize) + mips_cache(INDEX_STORE_TAG_SD, (void *)addr); + + /* Dsiable CCA override */ + val = readl(cm_base + GCR_BASE); + val &= ~(CCA_DEFAULT_OVR_MASK | CCA_DEFAULT_OVREN); + writel(val, cm_base + GCR_BASE); + + /* Set KSEG0 to non-coherent cached (important!) */ + val = read_c0_config(); + val &= ~CONF_CM_CMASK; + val |= CONF_CM_CACHABLE_NONCOHERENT; + write_c0_config(val); + ehb(); + + /* Again, invalidate L1 D-Cache */ + for (addr = 0; addr < CONFIG_SYS_DCACHE_SIZE; addr += lsize) + mips_cache(INDEX_WRITEBACK_INV_D, (void *)addr); + + /* Invalidate L1 I-Cache */ + for (addr = 0; addr < CONFIG_SYS_ICACHE_SIZE; addr += lsize) + mips_cache(INDEX_INVALIDATE_I, (void *)addr); + + /* Disable L2 cache bypass */ + val = read_c0_config2(); + val &= ~MIPS_CONF_IMPL; + write_c0_config2(val); + ehb(); +} + +void __noreturn tpl_main(void) +{ + const image_header_t *hdr = (const image_header_t *)__image_copy_end; + image_entry_noargs_t image_entry; + u32 loadaddr, size; + uintptr_t data; + + /* Initialize the cache first */ + mt7621_cache_init(); + + if (image_get_magic(hdr) != IH_MAGIC) + goto failed; + + loadaddr = image_get_load(hdr); + size = image_get_size(hdr); + image_entry = (image_entry_noargs_t)image_get_ep(hdr); + + /* Load TPL image to L2 cache */ + data = (uintptr_t)__image_copy_end + sizeof(struct image_header); + fill_lock_l2cache(data, loadaddr, size); + + /* Jump to SPL */ + image_entry(); + +failed: + for (;;) + ; +} diff --git a/include/configs/mt7621.h b/include/configs/mt7621.h new file mode 100644 index 0000000000..580d5fde0c --- /dev/null +++ b/include/configs/mt7621.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao <weijie.gao@mediatek.com> + */ + +#ifndef __CONFIG_MT7621_H +#define __CONFIG_MT7621_H + +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_MIPS_TIMER_FREQ 440000000 + +#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000 + +#define CONFIG_SYS_SDRAM_BASE 0x80000000 + +#define CONFIG_VERY_BIG_RAM +#define CONFIG_MAX_MEM_MAPPED 0x1c000000 + +#define CONFIG_SYS_INIT_SP_OFFSET 0x800000 + +#define CONFIG_SYS_BOOTM_LEN 0x2000000 + +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_CBSIZE 1024 + +#define CONFIG_SYS_NONCACHED_MEMORY 0x100000 + +/* MMC */ +#define MMC_SUPPORTS_TUNING + +/* NAND */ +#define CONFIG_SYS_MAX_NAND_DEVICE 1 + +/* Serial SPL */ +#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL) +#define CONFIG_SYS_NS16550_MEM32 +#define CONFIG_SYS_NS16550_CLK 50000000 +#define CONFIG_SYS_NS16550_REG_SIZE -4 +#define CONFIG_SYS_NS16550_COM1 0xbe000c00 +#endif + +/* Serial common */ +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \ + 230400, 460800, 921600 } + +/* SPL */ +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE + +#ifdef CONFIG_TPL_BUILD +#define CONFIG_SPL_START_S_PATH "arch/mips/mach-mtmips/mt7621/tpl" +/* .bss will not be used by TPL */ +#define CONFIG_SPL_BSS_START_ADDR 0x80000000 +#define CONFIG_SPL_BSS_MAX_SIZE 0 +#else +#define CONFIG_SPL_START_S_PATH "arch/mips/mach-mtmips/mt7621/spl" +#define CONFIG_SPL_BSS_START_ADDR 0x80140000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x80000 +#define CONFIG_SPL_MAX_SIZE 0x30000 +#endif + +/* Dummy value */ +#define CONFIG_SYS_UBOOT_BASE 0 +#define CONFIG_SYS_NAND_U_BOOT_OFFS 0 + +#endif /* __CONFIG_MT7621_H */
This patch adds support for MediaTek MT7621 SoC. All files are dedicated for u-boot. The default build target is u-boot-mt7621.bin. The specification of this chip: https://www.mediatek.com/products/homenetworking/mt7621 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com> --- v4 changes: Add full support for booting from flash (SPL/TPL support) Boot all cores/VPEs Use binman to generate final binary Use binman to embed external binary blob v3 changes: Update clock name for mt7621.dtsi due to clk driver changed v2 changes: Add a kconfig for max supported ram size Remove network configs from default config file --- arch/mips/dts/mt7621-u-boot.dtsi | 79 ++++ arch/mips/dts/mt7621.dtsi | 370 +++++++++++++++++++ arch/mips/mach-mtmips/Kconfig | 49 ++- arch/mips/mach-mtmips/Makefile | 4 + arch/mips/mach-mtmips/cpu.c | 2 +- arch/mips/mach-mtmips/mt7621/Kconfig | 95 +++++ arch/mips/mach-mtmips/mt7621/Makefile | 14 + arch/mips/mach-mtmips/mt7621/init.c | 229 ++++++++++++ arch/mips/mach-mtmips/mt7621/mt7621.h | 229 ++++++++++++ arch/mips/mach-mtmips/mt7621/serial.c | 23 ++ arch/mips/mach-mtmips/mt7621/spl/Makefile | 9 + arch/mips/mach-mtmips/mt7621/spl/cps.c | 152 ++++++++ arch/mips/mach-mtmips/mt7621/spl/dram.c | 143 +++++++ arch/mips/mach-mtmips/mt7621/spl/dram.h | 37 ++ arch/mips/mach-mtmips/mt7621/spl/launch.c | 100 +++++ arch/mips/mach-mtmips/mt7621/spl/launch.h | 52 +++ arch/mips/mach-mtmips/mt7621/spl/launch_ll.S | 357 ++++++++++++++++++ arch/mips/mach-mtmips/mt7621/spl/serial.c | 24 ++ arch/mips/mach-mtmips/mt7621/spl/spl.c | 95 +++++ arch/mips/mach-mtmips/mt7621/spl/start.S | 226 +++++++++++ arch/mips/mach-mtmips/mt7621/sram_init.S | 22 ++ arch/mips/mach-mtmips/mt7621/tpl/Makefile | 4 + arch/mips/mach-mtmips/mt7621/tpl/start.S | 161 ++++++++ arch/mips/mach-mtmips/mt7621/tpl/tpl.c | 146 ++++++++ include/configs/mt7621.h | 67 ++++ 25 files changed, 2683 insertions(+), 6 deletions(-) create mode 100644 arch/mips/dts/mt7621-u-boot.dtsi create mode 100644 arch/mips/dts/mt7621.dtsi create mode 100644 arch/mips/mach-mtmips/mt7621/Kconfig create mode 100644 arch/mips/mach-mtmips/mt7621/Makefile create mode 100644 arch/mips/mach-mtmips/mt7621/init.c create mode 100644 arch/mips/mach-mtmips/mt7621/mt7621.h create mode 100644 arch/mips/mach-mtmips/mt7621/serial.c create mode 100644 arch/mips/mach-mtmips/mt7621/spl/Makefile create mode 100644 arch/mips/mach-mtmips/mt7621/spl/cps.c create mode 100644 arch/mips/mach-mtmips/mt7621/spl/dram.c create mode 100644 arch/mips/mach-mtmips/mt7621/spl/dram.h create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch.c create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch.h create mode 100644 arch/mips/mach-mtmips/mt7621/spl/launch_ll.S create mode 100644 arch/mips/mach-mtmips/mt7621/spl/serial.c create mode 100644 arch/mips/mach-mtmips/mt7621/spl/spl.c create mode 100644 arch/mips/mach-mtmips/mt7621/spl/start.S create mode 100644 arch/mips/mach-mtmips/mt7621/sram_init.S create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/Makefile create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/start.S create mode 100644 arch/mips/mach-mtmips/mt7621/tpl/tpl.c create mode 100644 include/configs/mt7621.h