aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorTom Rini2021-01-25 14:38:40 -0500
committerTom Rini2021-01-25 14:38:40 -0500
commitc99be953e787cfb2414de67390427e00b6812240 (patch)
tree9f1253193077505d028e2b0000cefdbede1110cb /arch
parent4057b98ff2f3fd112f05024cad5ccf970fa9bed4 (diff)
parent9f03585e8dd5554f131bbe507ccebbc30354f493 (diff)
Merge tag 'mips-pull-2021-01-24' of https://gitlab.denx.de/u-boot/custodians/u-boot-mips
- MIPS: add support for Mediatek MT7620 SoCs
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/Kconfig1
-rw-r--r--arch/mips/cpu/cpu.c2
-rw-r--r--arch/mips/dts/Makefile7
-rw-r--r--arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts100
-rw-r--r--arch/mips/dts/mediatek,mt7620-rfb.dts97
-rw-r--r--arch/mips/dts/mt7620-u-boot.dtsi14
-rw-r--r--arch/mips/dts/mt7620.dtsi296
-rw-r--r--arch/mips/mach-mtmips/Kconfig72
-rw-r--r--arch/mips/mach-mtmips/Makefile1
-rw-r--r--arch/mips/mach-mtmips/cpu.c5
-rw-r--r--arch/mips/mach-mtmips/ddr_init.c59
-rw-r--r--arch/mips/mach-mtmips/include/mach/ddr.h4
-rw-r--r--arch/mips/mach-mtmips/include/mach/mt7620-sysc.h54
-rw-r--r--arch/mips/mach-mtmips/mt7620/Kconfig71
-rw-r--r--arch/mips/mach-mtmips/mt7620/Makefile10
-rw-r--r--arch/mips/mach-mtmips/mt7620/dram.c113
-rw-r--r--arch/mips/mach-mtmips/mt7620/init.c193
-rw-r--r--arch/mips/mach-mtmips/mt7620/lowlevel_init.S53
-rw-r--r--arch/mips/mach-mtmips/mt7620/mt7620.h103
-rw-r--r--arch/mips/mach-mtmips/mt7620/serial.c36
-rw-r--r--arch/mips/mach-mtmips/mt7620/sysc.c172
-rw-r--r--arch/mips/mach-mtmips/mt7628/Kconfig53
22 files changed, 1456 insertions, 60 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index e0f6b6c4b3c..77f563e98ed 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -97,7 +97,6 @@ config ARCH_MTMIPS
select SUPPORTS_CPU_MIPS32_R1
select SUPPORTS_CPU_MIPS32_R2
select SUPPORTS_LITTLE_ENDIAN
- select SYSRESET
select SUPPORT_SPL
config ARCH_JZ47XX
diff --git a/arch/mips/cpu/cpu.c b/arch/mips/cpu/cpu.c
index 7d5c9fd83ae..b304026a67c 100644
--- a/arch/mips/cpu/cpu.c
+++ b/arch/mips/cpu/cpu.c
@@ -12,7 +12,7 @@
#include <asm/mipsregs.h>
#include <asm/reboot.h>
-#ifndef CONFIG_SYSRESET
+#if !CONFIG_IS_ENABLED(SYSRESET)
void __weak _machine_restart(void)
{
fprintf(stderr, "*** reset failed ***\n");
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index dc85901dcaa..7c429231340 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -1,8 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
-dtb-$(CONFIG_ARCH_MTMIPS) += \
- gardena-smart-gateway-mt7688.dtb \
- linkit-smart-7688.dtb
dtb-$(CONFIG_TARGET_AP121) += ap121.dtb
dtb-$(CONFIG_TARGET_AP143) += ap143.dtb
dtb-$(CONFIG_TARGET_AP152) += ap152.dtb
@@ -17,7 +14,11 @@ dtb-$(CONFIG_BOARD_COMTREND_CT5361) += comtrend,ct-5361.dtb
dtb-$(CONFIG_BOARD_COMTREND_VR3032U) += comtrend,vr-3032u.dtb
dtb-$(CONFIG_BOARD_COMTREND_WAP5813N) += comtrend,wap-5813n.dtb
dtb-$(CONFIG_BOARD_HUAWEI_HG556A) += huawei,hg556a.dtb
+dtb-$(CONFIG_BOARD_MT7620_RFB) += mediatek,mt7620-rfb.dtb
+dtb-$(CONFIG_BOARD_MT7620_MT7530_RFB) += mediatek,mt7620-mt7530-rfb.dtb
dtb-$(CONFIG_BOARD_MT7628_RFB) += mediatek,mt7628-rfb.dtb
+dtb-$(CONFIG_BOARD_GARDENA_SMART_GATEWAY_MT7688) += gardena-smart-gateway-mt7688.dtb
+dtb-$(CONFIG_BOARD_LINKIT_SMART_7688) += linkit-smart-7688.dtb
dtb-$(CONFIG_TARGET_OCTEON_EBB7304) += mrvl,octeon-ebb7304.dtb
dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
dtb-$(CONFIG_BOARD_NETGEAR_DGND3700V2) += netgear,dgnd3700v2.dtb
diff --git a/arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts b/arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts
new file mode 100644
index 00000000000..8bc3b1673ac
--- /dev/null
+++ b/arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "mt7620.dtsi"
+
+/ {
+ compatible = "mediatek,mt7620-mt7530-rfb", "mediatek,mt7620-soc";
+ model = "MediaTek MT7620-MT7530 RFB (MTKC712)";
+
+ aliases {
+ serial0 = &uartlite;
+ spi0 = &spi0;
+ };
+
+ chosen {
+ stdout-path = &uartlite;
+ };
+};
+
+&uartlite {
+ status = "okay";
+};
+
+&pinctrl {
+ state_default: pin_state {
+ pleds {
+ groups = "ephy led", "wled";
+ function = "led";
+ };
+
+ gpios {
+ groups = "pa", "uartf";
+ function = "gpio";
+ };
+ };
+
+ gsw_pins: gsw_pins {
+ mdio {
+ groups = "mdio";
+ function = "mdio";
+ };
+
+ rgmii1 {
+ groups = "rgmii1";
+ function = "rgmii1";
+ };
+ };
+};
+
+&spi0 {
+ status = "okay";
+ num-cs = <2>;
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <25000000>;
+ reg = <0>;
+ };
+};
+
+&gpio0 {
+ pa0_pull_low {
+ gpio-hog;
+ output-low;
+ gpios = <20 GPIO_ACTIVE_HIGH>;
+ };
+
+ pa1_pull_low {
+ gpio-hog;
+ output-low;
+ gpios = <21 GPIO_ACTIVE_HIGH>;
+ };
+};
+
+&eth {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gsw_pins>;
+
+ port5 {
+ phy-mode = "rgmii";
+ phy-addr = <5>;
+ fixed-link {
+ full-duplex;
+ speed = <1000>;
+ mediatek,mt7530;
+ mediatek,mt7530-reset = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
diff --git a/arch/mips/dts/mediatek,mt7620-rfb.dts b/arch/mips/dts/mediatek,mt7620-rfb.dts
new file mode 100644
index 00000000000..616903e5544
--- /dev/null
+++ b/arch/mips/dts/mediatek,mt7620-rfb.dts
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "mt7620.dtsi"
+
+/ {
+ compatible = "mediatek,mt7620-rfb", "mediatek,mt7620-soc";
+ model = "MediaTek MT7620 RFB (WS2120)";
+
+ aliases {
+ serial0 = &uartlite;
+ spi0 = &spi0;
+ };
+
+ chosen {
+ stdout-path = &uartlite;
+ };
+};
+
+&uartlite {
+ status = "okay";
+};
+
+&pinctrl {
+ state_default: pin_state {
+ pleds {
+ groups = "ephy led", "wled";
+ function = "led";
+ };
+
+ gpios {
+ groups = "uartf";
+ function = "gpio";
+ };
+ };
+
+ gsw_pins: gsw_pins {
+ mdio {
+ groups = "mdio";
+ function = "mdio";
+ };
+
+ rgmii1 {
+ groups = "rgmii1";
+ function = "rgmii1";
+ };
+
+ rgmii2 {
+ groups = "rgmii2";
+ function = "rgmii2";
+ };
+ };
+};
+
+&spi0 {
+ status = "okay";
+ num-cs = <2>;
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <25000000>;
+ reg = <0>;
+ };
+};
+
+&eth {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&gsw_pins>;
+
+ port4 {
+ phy-mode = "rgmii";
+ phy-addr = <4>;
+ };
+
+ port5 {
+ phy-mode = "rgmii";
+ phy-addr = <5>;
+ };
+};
+
+&mmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+
+ status = "okay";
+};
diff --git a/arch/mips/dts/mt7620-u-boot.dtsi b/arch/mips/dts/mt7620-u-boot.dtsi
new file mode 100644
index 00000000000..ed8425719b6
--- /dev/null
+++ b/arch/mips/dts/mt7620-u-boot.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+&uartlite {
+ u-boot,dm-pre-reloc;
+};
+
+&uartfull {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/mips/dts/mt7620.dtsi b/arch/mips/dts/mt7620.dtsi
new file mode 100644
index 00000000000..03a80b7a709
--- /dev/null
+++ b/arch/mips/dts/mt7620.dtsi
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <dt-bindings/clock/mt7620-clk.h>
+#include <dt-bindings/reset/mt7620-reset.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mediatek,mt7620-soc";
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "mti,mips24KEc";
+ device_type = "cpu";
+ reg = <0>;
+ };
+ };
+
+ clk48m: clk48m@0 {
+ compatible = "fixed-clock";
+
+ clock-frequency = <48000000>;
+
+ #clock-cells = <0>;
+ };
+
+ sysc: sysc@10000000 {
+ compatible = "mediatek,mt7620-sysc";
+ reg = <0x10000000 0x100>;
+ };
+
+ clkctrl: clkctrl@10000030 {
+ compatible = "mediatek,mt7620-clk";
+ mediatek,sysc = <&sysc>;
+
+ #clock-cells = <1>;
+ };
+
+ rstctrl: rstctrl@10000034 {
+ compatible = "mediatek,mtmips-reset";
+ reg = <0x10000034 0x4>;
+ #reset-cells = <1>;
+ };
+
+ reboot: resetctl-reboot {
+ compatible = "resetctl-reboot";
+
+ resets = <&rstctrl SYS_RST>;
+ reset-names = "sysreset";
+ };
+
+ uartfull: uartfull@10000500 {
+ compatible = "mediatek,mt7620-uart";
+ reg = <10000500 0x100>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uartf_gpio_pins>;
+
+ clocks = <&clkctrl CLK_UARTF>;
+
+ resets = <&rstctrl UARTF_RST>;
+ reset-names = "uartf";
+
+ clock-frequency = <40000000>;
+
+ status = "disabled";
+ };
+
+ uartlite: uartlite@10000c00 {
+ compatible = "mediatek,mt7620-uart";
+ reg = <0x10000c00 0x100>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uartl_pins>;
+
+ clocks = <&clkctrl CLK_UARTL>;
+
+ resets = <&rstctrl UARTL_RST>;
+ reset-names = "uartl";
+
+ clock-frequency = <40000000>;
+ };
+
+ pinctrl: pinctrl@10000060 {
+ compatible = "mediatek,mt7620-pinctrl";
+ reg = <0x10000060 0x4>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pin_state {
+ sutif_pins {
+ groups = "sutif";
+ function = "none";
+ };
+ };
+
+ nand_pins: nand_pins {
+ groups = "nand";
+ function = "nand";
+ };
+
+ sd_pins: sd_pins {
+ groups = "nand";
+ function = "sd";
+ };
+
+ spi_single_pins: spi_single_pins {
+ groups = "spi";
+ function = "spi";
+ };
+
+ spi_dual_pins: spi_dual_pins {
+ spi_master_pins {
+ groups = "spi";
+ function = "spi";
+ };
+
+ spi_cs1_pin {
+ groups = "spi cs1";
+ function = "spi cs1";
+ };
+ };
+
+ uartl_pins: uartl_pins {
+ groups = "uartl";
+ function = "uartl";
+ };
+
+ uartf_pins: uartf_pins {
+ groups = "uartf";
+ function = "uartf";
+ };
+
+ uartf_pcm_pins: uartf_pcm_pins {
+ groups = "uartf";
+ function = "uartf pcm";
+ };
+
+ uartf_i2s_pins: uartf_i2s_pins {
+ groups = "uartf";
+ function = "i2s uartf";
+ };
+
+ uartf_gpio_pins: uartf_gpio_pins {
+ groups = "uartf";
+ function = "uartf gpio";
+ };
+ };
+
+ watchdog: watchdog@10000120 {
+ compatible = "mediatek,mt7620-wdt";
+ reg = <0x10000120 0x10>;
+
+ resets = <&rstctrl TIMER_RST>;
+ reset-names = "wdt";
+ };
+
+ gpio0: gpio0@10000600 {
+ compatible = "mediatek,mt7620-gpio";
+ reg = <0x10000600 0x34>;
+
+ resets = <&rstctrl PIO_RST>;
+ reset-names = "pio";
+
+ mediatek,bank-name = "PIOA";
+ mediatek,gpio-num = <24>;
+ mediatek,register-map = <0x20 0x24 0x2c 0x30>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio1: gpio1@10000638 {
+ compatible = "mediatek,mt7620-gpio";
+ reg = <0x10000638 0x24>;
+
+ resets = <&rstctrl PIO_RST>;
+ reset-names = "pio";
+
+ mediatek,bank-name = "PIOB";
+ mediatek,gpio-num = <16>;
+ mediatek,register-map = <0x10 0x14 0x1c 0x20>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio2: gpio2@10000660 {
+ compatible = "mediatek,mt7620-gpio";
+ reg = <0x10000660 0x24>;
+
+ resets = <&rstctrl PIO_RST>;
+ reset-names = "pio";
+
+ mediatek,bank-name = "PIOC";
+ mediatek,gpio-num = <32>;
+ mediatek,register-map = <0x10 0x14 0x1c 0x20>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpio3: gpio3@10000688 {
+ compatible = "mediatek,mt7620-gpio";
+ reg = <0x10000688 0x24>;
+
+ resets = <&rstctrl PIO_RST>;
+ reset-names = "pio";
+
+ mediatek,bank-name = "PIOD";
+ mediatek,gpio-num = <1>;
+ mediatek,register-map = <0x10 0x14 0x1c 0x20>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ spi0: spi@10000b00 {
+ compatible = "mediatek,mt7620-spi";
+ reg = <0x10000b00 0x100>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi_single_pins>;
+
+ resets = <&rstctrl SPI_RST>;
+ reset-names = "spi";
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clocks = <&clkctrl CLK_SPI>;
+ };
+
+ eth: eth@10100000 {
+ compatible = "mediatek,mt7620-eth";
+ reg = <0x10100000 0x10000
+ 0x10110000 0x8000>;
+ reg-names = "fe", "esw";
+
+ mediatek,sysc = <&sysc>;
+
+ resets = <&rstctrl EPHY_RST>,
+ <&rstctrl ESW_RST>,
+ <&rstctrl FE_RST>;
+ reset-names = "ephy", "esw", "fe";
+
+ clocks = <&clkctrl CLK_EPHY>,
+ <&clkctrl CLK_ESW>,
+ <&clkctrl CLK_FE>;
+ clock-names = "ephy", "esw", "fe";
+
+ status = "disabled";
+ };
+
+ usb_phy: mt7620-usb-phy {
+ compatible = "mediatek,mt7620-usbphy";
+
+ #phy-cells = <0>;
+
+ mediatek,sysc = <&sysc>;
+
+ clocks = <&clkctrl CLK_UPHY_48M>, <&clkctrl CLK_UPHY_12M>;
+ clock-names = "uphy48m", "uphy12m";
+
+ resets = <&rstctrl UHST_RST>, <&rstctrl UDEV_RST>;
+ reset-names = "uhst", "udev";
+ };
+
+ ehci@101c0000 {
+ compatible = "generic-ehci";
+ reg = <0x101c0000 0x1000>;
+
+ phys = <&usb_phy>;
+ phy-names = "usb";
+ };
+
+ mmc: mmc@10130000 {
+ compatible = "mediatek,mt7620-mmc";
+ reg = <0x10130000 0x4000>;
+ builtin-cd = <1>;
+ r_smpl = <1>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_pins>;
+
+ clocks = <&clk48m>, <&clkctrl CLK_SDHC>;
+ clock-names = "source", "hclk";
+
+ resets = <&rstctrl SDHC_RST>;
+
+ status = "disabled";
+ };
+};
diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig
index 737de2cb8e2..8756cadb0b6 100644
--- a/arch/mips/mach-mtmips/Kconfig
+++ b/arch/mips/mach-mtmips/Kconfig
@@ -5,6 +5,7 @@ config SYS_MALLOC_F_LEN
default 0x1000
config SYS_SOC
+ default "mt7620" if SOC_MT7620
default "mt7628" if SOC_MT7628
config SYS_DCACHE_SIZE
@@ -31,10 +32,26 @@ config SPL_PAYLOAD
config BUILD_TARGET
default "u-boot-with-spl.bin" if SPL
+ default "u-boot.bin"
choice
prompt "MediaTek MIPS SoC select"
+config SOC_MT7620
+ bool "MT7620"
+ select MIPS_L1_CACHE_SHIFT_5
+ select SYS_MIPS_CACHE_INIT_RAM_LOAD
+ select PINCTRL_MT7620
+ select MT7620_SERIAL
+ select MISC
+ select SPL_SEPARATE_BSS if SPL
+ select SPL_LOADER_SUPPORT if SPL
+ select SPL_OF_CONTROL if SPL_DM
+ select SPL_OF_PLATDATA if SPL_DM
+ select SPL_DM_SERIAL if SPL_DM
+ help
+ This supports MediaTek MT7620.
+
config SOC_MT7628
bool "MT7628"
select MIPS_L1_CACHE_SHIFT_5
@@ -43,6 +60,7 @@ config SOC_MT7628
select SYS_MIPS_CACHE_INIT_RAM_LOAD
select PINCTRL_MT7628
select MTK_SERIAL
+ select SYSRESET
select SYSRESET_RESETCTL
select SPL_SEPARATE_BSS if SPL
select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL
@@ -58,57 +76,7 @@ config SOC_MT7628
endchoice
-choice
- prompt "Board select"
-
-config BOARD_GARDENA_SMART_GATEWAY_MT7688
- bool "GARDENA smart Gateway"
- depends on SOC_MT7628
- select BOARD_LATE_INIT
- help
- GARDENA smart Gateway boards have a MT7688 SoC with 128 MiB of RAM
- and 8 MiB of flash (SPI NOR) and additional SPI NAND storage.
-
-config BOARD_LINKIT_SMART_7688
- bool "LinkIt Smart 7688"
- depends on SOC_MT7628
- help
- Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM
- and 32 MiB of flash (SPI).
- Between its different peripherals there's an integrated switch with 4
- ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
- a MT7688 (PCIe).
-
-config BOARD_MT7628_RFB
- bool "MediaTek MT7628 RFB"
- depends on SOC_MT7628
- help
- The reference design of MT7628. The board has 128 MiB DDR2, 8 MiB
- SPI-NOR flash, 1 built-in switch with 5 ports, 1 UART, 1 USB host,
- 1 SDXC, 1 PCIe socket and JTAG pins.
-
-config BOARD_VOCORE2
- bool "VoCore2"
- depends on SOC_MT7628
- select SPL_SERIAL_SUPPORT
- select SPL_UART2_SPIS_PINMUX
- help
- VoCore VoCore2 board has a MT7628 SoC with 128 MiB of RAM
- and 16 MiB of flash (SPI).
-
-endchoice
-
-config SPL_UART2_SPIS_PINMUX
- bool "Use alternative pinmux for UART2 in SPL stage"
- depends on SPL_SERIAL_SUPPORT
- default n
- help
- Select this if the UART2 of your board is connected to GPIO 16/17
- (shared with SPIS) rather than the usual GPIO 20/21.
-
-source "board/gardena/smart-gateway-mt7688/Kconfig"
-source "board/mediatek/mt7628/Kconfig"
-source "board/seeed/linkit-smart-7688/Kconfig"
-source "board/vocore/vocore2/Kconfig"
+source "arch/mips/mach-mtmips/mt7620/Kconfig"
+source "arch/mips/mach-mtmips/mt7628/Kconfig"
endmenu
diff --git a/arch/mips/mach-mtmips/Makefile b/arch/mips/mach-mtmips/Makefile
index a7e6a663047..4909b47ef27 100644
--- a/arch/mips/mach-mtmips/Makefile
+++ b/arch/mips/mach-mtmips/Makefile
@@ -5,4 +5,5 @@ obj-y += ddr_init.o
obj-y += ddr_cal.o
obj-$(CONFIG_SPL_BUILD) += spl.o
+obj-$(CONFIG_SOC_MT7620) += mt7620/
obj-$(CONFIG_SOC_MT7628) += mt7628/
diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach-mtmips/cpu.c
index 2ddf8cb0967..ca1967055a2 100644
--- a/arch/mips/mach-mtmips/cpu.c
+++ b/arch/mips/mach-mtmips/cpu.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <init.h>
#include <malloc.h>
+#include <asm/addrspace.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <linux/sizes.h>
@@ -14,9 +15,7 @@ DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
{
-#ifdef CONFIG_SKIP_LOWLEVEL_INIT
- gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);
-#endif
+ gd->ram_size = get_ram_size((void *)KSEG1, SZ_256M);
return 0;
}
diff --git a/arch/mips/mach-mtmips/ddr_init.c b/arch/mips/mach-mtmips/ddr_init.c
index 6c6d0933f2e..9c986daea6f 100644
--- a/arch/mips/mach-mtmips/ddr_init.c
+++ b/arch/mips/mach-mtmips/ddr_init.c
@@ -15,6 +15,13 @@
#define DDR_BW_TEST_PAT 0xaa5555aa
+static const u32 sdr_size_cfg1[] = {
+ [DRAM_8MB] = (1 << NUMROWS_S),
+ [DRAM_16MB] = (1 << NUMROWS_S) | (1 << NUMCOLS_S),
+ [DRAM_32MB] = (2 << NUMROWS_S) | (1 << NUMCOLS_S),
+ [DRAM_64MB] = (2 << NUMROWS_S) | (2 << NUMCOLS_S),
+};
+
static const u32 dram_size[] = {
[DRAM_8MB] = SZ_8M,
[DRAM_16MB] = SZ_16M,
@@ -193,3 +200,55 @@ void ddr2_init(struct mc_ddr_init_param *param)
param->memsize = dram_size[sz];
param->bus_width = bw;
}
+
+static void mc_sdr_init(void __iomem *memc, mc_reset_t mc_reset, u32 cfg0,
+ u32 cfg1)
+{
+ mc_reset(1);
+ __udelay(200);
+ mc_reset(0);
+
+ writel(cfg0, memc + MEMCTL_SDRAM_CFG0_REG);
+ writel(cfg1, memc + MEMCTL_SDRAM_CFG1_REG);
+
+ while (!(readl(memc + MEMCTL_SDRAM_CFG1_REG) & SDRAM_INIT_DONE))
+ ;
+
+ clrsetbits_32(memc + MEMCTL_PWR_SAVE_CNT_REG, SR_TAR_CNT_M,
+ 1 << SR_TAR_CNT_S);
+
+ setbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
+}
+
+void sdr_init(struct mc_ddr_init_param *param)
+{
+ enum mc_dram_size sz;
+ u32 cfg1;
+
+ cfg1 = param->sdr_cfg1 | SDRAM_INIT_START;
+ cfg1 &= ~(NUMCOLS_M | NUMROWS_M);
+
+ /* First initialization, determine SDR capacity */
+ mc_sdr_init(param->memc, param->mc_reset, param->sdr_cfg0,
+ cfg1 | sdr_size_cfg1[DRAM_64MB]);
+
+ if (dram_addr_test_bit(9)) {
+ sz = DRAM_8MB;
+ } else {
+ if (dram_addr_test_bit(10)) {
+ if (dram_addr_test_bit(23))
+ sz = DRAM_16MB;
+ else
+ sz = DRAM_32MB;
+ } else {
+ sz = DRAM_64MB;
+ }
+ }
+
+ /* Final initialization */
+ mc_sdr_init(param->memc, param->mc_reset, param->sdr_cfg0,
+ cfg1 | sdr_size_cfg1[sz]);
+
+ /* Return actual DDR configuration */
+ param->memsize = dram_size[sz];
+}
diff --git a/arch/mips/mach-mtmips/include/mach/ddr.h b/arch/mips/mach-mtmips/include/mach/ddr.h
index f92198137b1..15ff66ace6a 100644
--- a/arch/mips/mach-mtmips/include/mach/ddr.h
+++ b/arch/mips/mach-mtmips/include/mach/ddr.h
@@ -35,6 +35,9 @@ typedef void (*mc_reset_t)(int assert);
struct mc_ddr_init_param {
void __iomem *memc;
+ u32 sdr_cfg0;
+ u32 sdr_cfg1;
+
u32 dq_dly;
u32 dqs_dly;
@@ -45,6 +48,7 @@ struct mc_ddr_init_param {
u32 bus_width;
};
+void sdr_init(struct mc_ddr_init_param *param);
void ddr1_init(struct mc_ddr_init_param *param);
void ddr2_init(struct mc_ddr_init_param *param);
void ddr_calibrate(void __iomem *memc, u32 memsize, u32 bw);
diff --git a/arch/mips/mach-mtmips/include/mach/mt7620-sysc.h b/arch/mips/mach-mtmips/include/mach/mt7620-sysc.h
new file mode 100644
index 00000000000..743ca034c80
--- /dev/null
+++ b/arch/mips/mach-mtmips/include/mach/mt7620-sysc.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ *
+ * Definitions of ioctl requests of MT7620 sysc driver
+ */
+
+#ifndef _MT7620_SYSC_H_
+#define _MT7620_SYSC_H_
+
+#include <linux/types.h>
+
+enum mt7620_sysc_requests {
+ MT7620_SYSC_IOCTL_GET_CLK,
+ MT7620_SYSC_IOCTL_GET_CHIP_REV,
+ MT7620_SYSC_IOCTL_SET_GE1_MODE,
+ MT7620_SYSC_IOCTL_SET_GE2_MODE,
+ MT7620_SYSC_IOCTL_SET_USB_MODE,
+ MT7620_SYSC_IOCTL_SET_PCIE_MODE
+};
+
+struct mt7620_sysc_clks {
+ u32 cpu_clk;
+ u32 sys_clk;
+ u32 xtal_clk;
+ u32 peri_clk;
+};
+
+struct mt7620_sysc_chip_rev {
+ bool bga;
+ u32 ver : 4;
+ u32 eco : 4;
+};
+
+enum mt7620_sysc_ge_mode {
+ MT7620_SYSC_GE_RGMII,
+ MT7620_SYSC_GE_MII,
+ MT7620_SYSC_GE_RMII,
+ MT7620_SYSC_GE_ESW_PHY,
+};
+
+enum mt7620_sysc_usb_mode {
+ MT7620_SYSC_USB_DEVICE_MODE,
+ MT7620_SYSC_USB_HOST_MODE
+};
+
+enum mt7620_sysc_pcie_mode {
+ MT7620_SYSC_PCIE_EP_MODE,
+ MT7620_SYSC_PCIE_RC_MODE
+};
+
+#endif /* _MT7620_SYSC_H_ */
diff --git a/arch/mips/mach-mtmips/mt7620/Kconfig b/arch/mips/mach-mtmips/mt7620/Kconfig
new file mode 100644
index 00000000000..5db83eb9d9a
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/Kconfig
@@ -0,0 +1,71 @@
+
+if SOC_MT7620
+
+config DEBUG_UART_BOARD_INIT
+ default y
+
+choice
+ prompt "Board select"
+
+config BOARD_MT7620_RFB
+ bool "MediaTek MT7620 RFB"
+ help
+ The reference design of MT7620A (WS2120). The board has 64 MiB DDR2,
+ 8 MiB SPI-NOR flash, 1 built-in 6 port switch (two GE PHYs and five
+ FE PHYs,one port can be configured to use either FE PHY or GE PHY),
+ 1 UART, 1 USB host, 1 SDXC, 1 PCIe socket and JTAG pins.
+
+config BOARD_MT7620_MT7530_RFB
+ bool "MediaTek MT7620-MT7530 RFB"
+ help
+ The reference design of MT7620DA (MTKC712). The board has 64 MiB
+ intergrated DDR2 KGD, 16 MiB SPI-NOR flash, an external 5-port giga
+ switch MT7530 and 1 UART.
+
+endchoice
+
+choice
+ prompt "CPU frequency select"
+ default CPU_FREQ_580MHZ
+
+config CPU_FREQ_480MHZ
+ bool "480MHz"
+
+config CPU_FREQ_500MHZ
+ bool "500MHz"
+
+config CPU_FREQ_520MHZ
+ bool "520MHz"
+
+config CPU_FREQ_540MHZ
+ bool "540MHz"
+
+config CPU_FREQ_560MHZ
+ bool "560MHz"
+
+config CPU_FREQ_580MHZ
+ bool "580MHz"
+
+config CPU_FREQ_600MHZ
+ bool "600MHz"
+
+config CPU_FREQ_620MHZ
+ bool "620MHz"
+
+endchoice
+
+config CPU_FREQ_MULTI
+ int
+ range 0 7
+ default 0 if CPU_FREQ_480MHZ
+ default 1 if CPU_FREQ_500MHZ
+ default 2 if CPU_FREQ_520MHZ
+ default 3 if CPU_FREQ_540MHZ
+ default 4 if CPU_FREQ_560MHZ
+ default 5 if CPU_FREQ_580MHZ
+ default 6 if CPU_FREQ_600MHZ
+ default 7 if CPU_FREQ_620MHZ
+
+source "board/mediatek/mt7620/Kconfig"
+
+endif
diff --git a/arch/mips/mach-mtmips/mt7620/Makefile b/arch/mips/mach-mtmips/mt7620/Makefile
new file mode 100644
index 00000000000..649f6c3798f
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/Makefile
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += lowlevel_init.o
+obj-y += init.o
+obj-y += dram.o
+obj-y += serial.o
+
+ifndef CONFIG_SPL_BUILD
+obj-y += sysc.o
+endif
diff --git a/arch/mips/mach-mtmips/mt7620/dram.c b/arch/mips/mach-mtmips/mt7620/dram.c
new file mode 100644
index 00000000000..0f0e64bf5ea
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/dram.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <asm/addrspace.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/sizes.h>
+#include <linux/io.h>
+#include <mach/ddr.h>
+#include <mach/mc.h>
+#include "mt7620.h"
+
+/* SDR parameters */
+#define SDR_CFG0_VAL 0x51B283B3
+#define SDR_CFG1_VAL 0xC00003A9
+
+/* DDR2 DQ_DLY */
+#define DDR2_DQ_DLY 0x88888888
+
+/* DDR2 DQS_DLY */
+#define DDR2_DQS_DLY 0x88888888
+
+static const struct mc_ddr_cfg ddr1_cfgs_200mhz[] = {
+ [DRAM_8MB] = { 0x34A1EB94, 0x20262324, 0x28000033, 0x00000002, 0x00000000 },
+ [DRAM_16MB] = { 0x34A1EB94, 0x202A2324, 0x28000033, 0x00000002, 0x00000000 },
+ [DRAM_32MB] = { 0x34A1E5CA, 0x202E2324, 0x28000033, 0x00000002, 0x00000000 },
+ [DRAM_64MB] = { 0x3421E5CA, 0x20322324, 0x28000033, 0x00000002, 0x00000000 },
+ [DRAM_128MB] = { 0x241B05CA, 0x20362334, 0x28000033, 0x00000002, 0x00000000 },
+};
+
+static const struct mc_ddr_cfg ddr1_cfgs_160mhz[] = {
+ [DRAM_8MB] = { 0x239964A1, 0x20262323, 0x00000033, 0x00000002, 0x00000000 },
+ [DRAM_16MB] = { 0x239964A1, 0x202A2323, 0x00000033, 0x00000002, 0x00000000 },
+ [DRAM_32MB] = { 0x239964A1, 0x202E2323, 0x00000033, 0x00000002, 0x00000000 },
+ [DRAM_64MB] = { 0x239984A1, 0x20322323, 0x00000033, 0x00000002, 0x00000000 },
+ [DRAM_128MB] = { 0x239AB4A1, 0x20362333, 0x00000033, 0x00000002, 0x00000000 },
+};
+
+static const struct mc_ddr_cfg ddr2_cfgs_200mhz[] = {
+ [DRAM_32MB] = { 0x2519E2E5, 0x222E2323, 0x68000C43, 0x00000416, 0x0000000A },
+ [DRAM_64MB] = { 0x249AA2E5, 0x22322323, 0x68000C43, 0x00000416, 0x0000000A },
+ [DRAM_128MB] = { 0x249B42E5, 0x22362323, 0x68000C43, 0x00000416, 0x0000000A },
+ [DRAM_256MB] = { 0x249CE2E5, 0x223A2323, 0x68000C43, 0x00000416, 0x0000000A },
+};
+
+static const struct mc_ddr_cfg ddr2_cfgs_160mhz[] = {
+ [DRAM_32MB] = { 0x23918250, 0x222E2322, 0x40000A43, 0x00000416, 0x00000006 },
+ [DRAM_64MB] = { 0x239A2250, 0x22322322, 0x40000A43, 0x00000416, 0x00000008 },
+ [DRAM_128MB] = { 0x2392A250, 0x22362322, 0x40000A43, 0x00000416, 0x00000008 },
+ [DRAM_256MB] = { 0x24140250, 0x223A2322, 0x40000A43, 0x00000416, 0x00000008 },
+};
+
+static void mt7620_memc_reset(int assert)
+{
+ void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+ if (assert)
+ setbits_32(sysc + SYSCTL_RSTCTL_REG, MC_RST);
+ else
+ clrbits_32(sysc + SYSCTL_RSTCTL_REG, MC_RST);
+}
+
+void mt7620_dram_init(void)
+{
+ void __iomem *sysc;
+ bool lspd = false;
+ int ddr_type, aux;
+ struct mc_ddr_init_param param;
+
+ sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+ ddr_type = (readl(sysc + SYSCTL_SYSCFG0_REG) & DRAM_TYPE_M)
+ >> DRAM_TYPE_S;
+ aux = readl(sysc + SYSCTL_CPLL_CFG1_REG) &
+ (CPU_CLK_AUX1 | CPU_CLK_AUX0);
+
+ if (aux == CPU_CLK_AUX1 || aux == CPU_CLK_AUX0)
+ lspd = true;
+
+ mt7620_memc_reset(1);
+ __udelay(200);
+
+ param.memc = ioremap_nocache(MEMCTL_BASE, MEMCTL_SIZE);
+ param.dq_dly = DDR2_DQ_DLY;
+ param.dqs_dly = DDR2_DQS_DLY;
+ param.mc_reset = mt7620_memc_reset;
+ param.memsize = 0;
+ param.bus_width = 0;
+
+ if (ddr_type == DRAM_DDR1) {
+ if (lspd)
+ param.cfgs = ddr1_cfgs_160mhz;
+ else
+ param.cfgs = ddr1_cfgs_200mhz;
+
+ ddr1_init(&param);
+ } else if (ddr_type == DRAM_DDR2) {
+ if (lspd)
+ param.cfgs = ddr2_cfgs_160mhz;
+ else
+ param.cfgs = ddr2_cfgs_200mhz;
+
+ ddr2_init(&param);
+ } else {
+ param.sdr_cfg0 = SDR_CFG0_VAL;
+ param.sdr_cfg1 = SDR_CFG1_VAL;
+
+ sdr_init(&param);
+ }
+}
diff --git a/arch/mips/mach-mtmips/mt7620/init.c b/arch/mips/mach-mtmips/mt7620/init.c
new file mode 100644
index 00000000000..93abf9228d6
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/init.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <config.h>
+#include <asm/global_data.h>
+#include <linux/io.h>
+#include "mt7620.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const char * const dram_type[] = {
+ "SDRAM", "DDR", "DDR2", "SDRAM"
+};
+
+static const char * const boot_mode[(CHIP_MODE_M >> CHIP_MODE_S) + 1] = {
+ [1] = "NAND 4-cycles 2KB-page",
+ [2] = "SPI-NOR 3-Byte Addr",
+ [3] = "SPI-NOR 4-Byte Addr",
+ [10] = "NAND 4-cycles 512B-page",
+ [11] = "NAND 5-cycles 2KB-page",
+ [12] = "NAND 3-cycles 512B-page",
+};
+
+static void cpu_pll_init(void)
+{
+ void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+ u32 pllmul = CONFIG_CPU_FREQ_MULTI;
+
+ /* Make sure the pll multiplier is valid */
+ if (pllmul > 7)
+ pllmul = 7;
+
+ /* Set init CPU clock to 480MHz */
+ clrsetbits_32(sysc + SYSCTL_CPLL_CFG1_REG, CPU_CLK_AUX1, CPU_CLK_AUX0);
+
+ /* Enable software control of CPU PLL */
+ setbits_32(sysc + SYSCTL_CPLL_CFG0_REG, CPLL_SW_CFG);
+
+ /* CPU PLL power down */
+ setbits_32(sysc + SYSCTL_CPLL_CFG1_REG, CPLL_PD);
+
+ /* PLL configuration */
+ clrsetbits_32(sysc + SYSCTL_CPLL_CFG0_REG, PLL_MULT_RATIO_M |
+ PLL_DIV_RATIO_M | SSC_UP_BOUND_M | SSC_EN,
+ (pllmul << PLL_MULT_RATIO_S) | SSC_SWING_M);
+
+ /* CPU PLL power up */
+ clrbits_32(sysc + SYSCTL_CPLL_CFG1_REG, CPLL_PD);
+
+ /* Wait for CPU PLL locked */
+ while (!(readl(sysc + SYSCTL_CPLL_CFG1_REG) & CPLL_LD))
+ ;
+
+ /* Set final CPU clock source */
+ clrbits_32(sysc + SYSCTL_CPLL_CFG1_REG, CPU_CLK_AUX1 | CPU_CLK_AUX0);
+
+ /* Adjust CPU clock */
+ clrsetbits_32(sysc + SYSCTL_CPU_SYS_CLKCFG_REG,
+ CPU_FDIV_M | CPU_FFRAC_M,
+ (1 << CPU_FDIV_S) | (1 << CPU_FFRAC_S));
+}
+
+void mt7620_init(void)
+{
+ u32 cpu_clk;
+
+ cpu_pll_init();
+
+ /*
+ * Set timer freq, which will be used during DRAM initialization
+ * Note that this function is using a temporary gd which will be
+ * destroyed after leaving this function.
+ */
+ mt7620_get_clks(&cpu_clk, NULL, NULL);
+ gd->arch.timer_freq = cpu_clk / 2;
+
+ mt7620_dram_init();
+}
+
+void mt7620_get_clks(u32 *cpu_clk, u32 *sys_clk, u32 *xtal_clk)
+{
+ void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+ u32 val, multi, div, fdiv, ffrac, dram_type, sys_div;
+ u32 cpu_freq, xtal_freq;
+
+ static const u32 div_ratio_table[] = {2, 3, 4, 8};
+
+ val = readl(sysc + SYSCTL_SYSCFG0_REG);
+
+ dram_type = (val & DRAM_TYPE_M) >> DRAM_TYPE_S;
+
+ if (val & XTAL_FREQ_SEL)
+ xtal_freq = 40000000;
+ else
+ xtal_freq = 20000000;
+
+ val = readl(sysc + SYSCTL_CPLL_CFG1_REG);
+ if (val & CPU_CLK_AUX1) {
+ cpu_freq = xtal_freq;
+ } else if (val & CPU_CLK_AUX0) {
+ cpu_freq = 480000000;
+ } else {
+ val = readl(sysc + SYSCTL_CPLL_CFG0_REG);
+ if (val & CPLL_SW_CFG) {
+ multi = (val & PLL_MULT_RATIO_M) >> PLL_MULT_RATIO_S;
+ div = (val & PLL_DIV_RATIO_M) >> PLL_DIV_RATIO_S;
+ cpu_freq = (multi + 24) * 40000000 /
+ div_ratio_table[div];
+ } else {
+ cpu_freq = 600000000;
+ }
+ }
+
+ val = readl(sysc + SYSCTL_CUR_CLK_STS_REG);
+ ffrac = (val & CUR_CPU_FFRAC_M) >> CUR_CPU_FFRAC_S;
+ fdiv = (val & CUR_CPU_FDIV_M) >> CUR_CPU_FDIV_S;
+ cpu_freq = (cpu_freq * ffrac) / fdiv;
+
+ switch (dram_type) {
+ case DRAM_SDRAM_E1:
+ sys_div = 4;
+ break;
+ case DRAM_DDR1:
+ case DRAM_DDR2:
+ sys_div = 3;
+ break;
+ case DRAM_SDRAM:
+ sys_div = 5;
+ break;
+ }
+
+ if (cpu_clk)
+ *cpu_clk = cpu_freq;
+
+ if (sys_clk)
+ *sys_clk = cpu_freq / sys_div;
+
+ if (xtal_clk)
+ *xtal_clk = xtal_freq;
+}
+
+int print_cpuinfo(void)
+{
+ void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+ u32 cpu_clk, bus_clk, xtal_clk;
+ u32 val, ver, eco, pkg, dram, chipmode;
+ const char *bootdev;
+
+ val = readl(sysc + SYSCTL_CHIP_REV_ID_REG);
+ ver = (val & VER_M) >> VER_S;
+ eco = (val & ECO_M) >> ECO_S;
+ pkg = !!(val & PKG_ID);
+
+ val = readl(sysc + SYSCTL_SYSCFG0_REG);
+ dram = (val & DRAM_TYPE_M) >> DRAM_TYPE_S;
+ chipmode = (val & CHIP_MODE_M) >> CHIP_MODE_S;
+
+ bootdev = boot_mode[chipmode];
+ if (!bootdev)
+ bootdev = "Unsupported boot mode";
+
+ printf("CPU: MediaTek MT7620%c ver:%u eco:%u\n",
+ pkg ? 'A' : 'N', ver, eco);
+
+ printf("Boot: %s, %s\n", dram_type[dram], bootdev);
+
+ mt7620_get_clks(&cpu_clk, &bus_clk, &xtal_clk);
+
+ /* Set final timer frequency */
+ gd->arch.timer_freq = cpu_clk / 2;
+
+ printf("Clock: CPU: %uMHz, Bus: %uMHz, XTAL: %uMHz\n",
+ cpu_clk / 1000000, bus_clk / 1000000, xtal_clk / 1000000);
+
+ return 0;
+}
+
+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/mt7620/lowlevel_init.S b/arch/mips/mach-mtmips/mt7620/lowlevel_init.S
new file mode 100644
index 00000000000..399174620d5
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/lowlevel_init.S
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <config.h>
+#include <asm-offsets.h>
+#include <asm/regdef.h>
+#include <asm/asm.h>
+
+ .set noreorder
+
+NESTED(lowlevel_init, 0, ra)
+ /* Save ra and do real lowlevel initialization */
+ move s0, ra
+
+ /*
+ * Use SRAM from 802.11n MAC/BBP, 16KiB (0x10184000 ~ 0x10187fff)
+ * NOTE: non-word operations may fail in this SRAM.
+ * Use it as stack only for CPU/DRAM init which only has word operations.
+ */
+ PTR_LI sp, 0xb0187f00
+
+ /* We still need a temporary gd for udelay */
+ PTR_SUBU \
+ sp, sp, GD_SIZE # reserve space for gd
+ li t0, -16
+ and sp, sp, t0 # force 16 byte alignment
+ move k0, sp # save gd pointer
+
+ move fp, sp
+
+ /* Clear gd */
+ move t0, k0
+1:
+ PTR_S zero, 0(t0)
+ PTR_ADDIU t0, PTRSIZE
+ blt t0, t1, 1b
+ nop
+
+ /* Do CPU & DRAM initialization */
+ PTR_LA t9, mt7620_init
+ jalr t9
+ nop
+
+ /* Restore ra */
+ move ra, s0
+
+ jr ra
+ nop
+ END(lowlevel_init)
diff --git a/arch/mips/mach-mtmips/mt7620/mt7620.h b/arch/mips/mach-mtmips/mt7620/mt7620.h
new file mode 100644
index 00000000000..dd5e6d00e5a
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/mt7620.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MT7620_H_
+#define _MT7620_H_
+
+#include <linux/bitops.h>
+
+#define SYSCTL_BASE 0x10000000
+#define SYSCTL_SIZE 0x100
+#define MEMCTL_BASE 0x10000300
+#define MEMCTL_SIZE 0x100
+#define UARTFULL_BASE 0x10000500
+#define UARTFULL_SIZE 0x100
+#define UARTLITE_BASE 0x10000c00
+#define UARTLITE_SIZE 0x100
+
+#define SYSCTL_CHIP_REV_ID_REG 0x0c
+#define PKG_ID BIT(16)
+#define PKG_ID_A 1
+#define PKG_ID_N 0
+#define VER_S 8
+#define VER_M GENMASK(11, 8)
+#define ECO_S 0
+#define ECO_M GENMASK(3, 0)
+
+#define SYSCTL_SYSCFG0_REG 0x10
+#define XTAL_FREQ_SEL BIT(6)
+#define XTAL_40MHZ 1
+#define XTAL_20MHZ 0
+#define DRAM_TYPE_S 4
+#define DRAM_TYPE_M GENMASK(5, 4)
+#define DRAM_SDRAM 3
+#define DRAM_DDR2 2
+#define DRAM_DDR1 1
+#define DRAM_SDRAM_E1 0
+#define CHIP_MODE_S 0
+#define CHIP_MODE_M GENMASK(3, 0)
+
+#define SYSCTL_SYSCFG1_REG 0x14
+#define GE2_MODE_S 14
+#define GE2_MODE_M GENMASK(15, 14)
+#define GE1_MODE_S 12
+#define GE1_MODE_M GENMASK(13, 12)
+#define USB0_HOST_MODE BIT(10)
+#define PCIE_RC_MODE BIT(8)
+#define GE_MODE_M GENMASK(1, 0)
+
+#define SYSCTL_RSTCTL_REG 0x34
+#define MC_RST BIT(10)
+#define SYS_RST BIT(0)
+
+#define SYSCTL_CLKCFG0_REG 0x2c
+#define PERI_CLK_SEL BIT(4)
+
+#define SYSCTL_CPU_SYS_CLKCFG_REG 0x3c
+#define CPU_OCP_RATIO_S 16
+#define CPU_OCP_RATIO_M GENMASK(19, 16)
+#define CPU_FDIV_S 8
+#define CPU_FDIV_M GENMASK(12, 8)
+#define CPU_FFRAC_S 0
+#define CPU_FFRAC_M GENMASK(4, 0)
+
+#define SYSCTL_CUR_CLK_STS_REG 0x44
+#define CUR_CPU_OCP_RATIO_S 16
+#define CUR_CPU_OCP_RATIO_M GENMASK(19, 16)
+#define CUR_CPU_FDIV_S 8
+#define CUR_CPU_FDIV_M GENMASK(12, 8)
+#define CUR_CPU_FFRAC_S 0
+#define CUR_CPU_FFRAC_M GENMASK(4, 0)
+
+#define SYSCTL_CPLL_CFG0_REG 0x54
+#define CPLL_SW_CFG BIT(31)
+#define PLL_MULT_RATIO_S 16
+#define PLL_MULT_RATIO_M GENMASK(18, 16)
+#define PLL_DIV_RATIO_S 10
+#define PLL_DIV_RATIO_M GENMASK(11, 10)
+#define SSC_UP_BOUND_S 8
+#define SSC_UP_BOUND_M GENMASK(9, 8)
+#define SSC_EN BIT(7)
+#define SSC_SWING_S 4
+#define SSC_SWING_M GENMASK(6, 4)
+
+#define SYSCTL_CPLL_CFG1_REG 0x58
+#define CPLL_PD BIT(26)
+#define CPU_CLK_AUX1 BIT(25)
+#define CPU_CLK_AUX0 BIT(24)
+#define CPLL_LD BIT(23)
+
+#define SYSCTL_GPIOMODE_REG 0x60
+#define UARTL_GPIO_MODE BIT(5)
+#define UARTF_SHARE_MODE_S 2
+#define UARTF_SHARE_MODE_M GENMASK(4, 2)
+#define UARTF_MODE_UARTF_GPIO 5
+
+void mt7620_dram_init(void);
+void mt7620_get_clks(u32 *cpu_clk, u32 *sys_clk, u32 *xtal_clk);
+
+#endif /* _MT7620_H_ */
diff --git a/arch/mips/mach-mtmips/mt7620/serial.c b/arch/mips/mach-mtmips/mt7620/serial.c
new file mode 100644
index 00000000000..44f061cd6cc
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/serial.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include "mt7620.h"
+
+void board_debug_uart_init(void)
+{
+ void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+#if CONFIG_DEBUG_UART_BASE == 0xb0000500 /* KSEG1ADDR(UARTFULL_BASE) */
+ clrsetbits_32(base + SYSCTL_GPIOMODE_REG, UARTF_SHARE_MODE_M,
+ UARTF_MODE_UARTF_GPIO << UARTF_SHARE_MODE_S);
+#else
+ clrbits_32(base + SYSCTL_GPIOMODE_REG, UARTL_GPIO_MODE);
+#endif
+}
+
+void mtmips_spl_serial_init(void)
+{
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+ void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+#if CONFIG_CONS_INDEX == 1
+ clrbits_32(base + SYSCTL_GPIOMODE_REG, UARTL_GPIO_MODE);
+#elif CONFIG_CONS_INDEX == 2
+ clrsetbits_32(base + SYSCTL_GPIOMODE_REG, UARTF_SHARE_MODE_M,
+ UARTF_MODE_UARTF_GPIO << UARTF_SHARE_MODE_S);
+#endif
+#endif /* CONFIG_SPL_SERIAL_SUPPORT */
+}
diff --git a/arch/mips/mach-mtmips/mt7620/sysc.c b/arch/mips/mach-mtmips/mt7620/sysc.c
new file mode 100644
index 00000000000..296a9be07c5
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/sysc.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ *
+ * Misc driver for manipulating System control registers
+ */
+
+#include <dm.h>
+#include <misc.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <dm/device_compat.h>
+#include <mach/mt7620-sysc.h>
+#include "mt7620.h"
+
+struct mt7620_sysc_priv {
+ void __iomem *base;
+};
+
+static int mt7620_sysc_read(struct udevice *dev, int offset, void *buf,
+ int size)
+{
+ struct mt7620_sysc_priv *priv = dev_get_priv(dev);
+ u32 val;
+
+ if (offset % sizeof(u32) || size != sizeof(u32) ||
+ offset >= SYSCTL_SIZE)
+ return -EINVAL;
+
+ val = readl(priv->base + offset);
+
+ if (buf)
+ *(u32 *)buf = val;
+
+ return 0;
+}
+
+static int mt7620_sysc_write(struct udevice *dev, int offset, const void *buf,
+ int size)
+{
+ struct mt7620_sysc_priv *priv = dev_get_priv(dev);
+ u32 val;
+
+ if (offset % sizeof(u32) || size != sizeof(u32) ||
+ offset >= SYSCTL_SIZE || !buf)
+ return -EINVAL;
+
+ val = *(u32 *)buf;
+ writel(val, priv->base + offset);
+
+ return 0;
+}
+
+static int mt7620_sysc_ioctl(struct udevice *dev, unsigned long request,
+ void *buf)
+{
+ struct mt7620_sysc_priv *priv = dev_get_priv(dev);
+ struct mt7620_sysc_chip_rev *chip_rev;
+ struct mt7620_sysc_clks *clks;
+ u32 val, shift;
+
+ if (!buf)
+ return -EINVAL;
+
+ switch (request) {
+ case MT7620_SYSC_IOCTL_GET_CLK:
+ clks = buf;
+ mt7620_get_clks(&clks->cpu_clk, &clks->sys_clk,
+ &clks->xtal_clk);
+
+ val = readl(priv->base + SYSCTL_CLKCFG0_REG);
+ if (val & PERI_CLK_SEL)
+ clks->peri_clk = clks->xtal_clk;
+ else
+ clks->peri_clk = 40000000;
+
+ return 0;
+
+ case MT7620_SYSC_IOCTL_GET_CHIP_REV:
+ chip_rev = buf;
+
+ val = readl(priv->base + SYSCTL_CHIP_REV_ID_REG);
+
+ chip_rev->bga = !!(val & PKG_ID);
+ chip_rev->ver = (val & VER_M) >> VER_S;
+ chip_rev->eco = (val & ECO_M) >> ECO_S;
+
+ return 0;
+
+ case MT7620_SYSC_IOCTL_SET_GE1_MODE:
+ case MT7620_SYSC_IOCTL_SET_GE2_MODE:
+ val = *(u32 *)buf;
+
+ if (val > MT7620_SYSC_GE_ESW_PHY)
+ return -EINVAL;
+
+ if (request == MT7620_SYSC_IOCTL_SET_GE1_MODE)
+ shift = GE1_MODE_S;
+ else
+ shift = GE2_MODE_S;
+
+ clrsetbits_32(priv->base + SYSCTL_SYSCFG1_REG,
+ GE_MODE_M << shift, val << shift);
+
+ return 0;
+
+ case MT7620_SYSC_IOCTL_SET_USB_MODE:
+ val = *(u32 *)buf;
+
+ if (val == MT7620_SYSC_USB_DEVICE_MODE)
+ val = 0;
+ else if (val == MT7620_SYSC_USB_HOST_MODE)
+ val = USB0_HOST_MODE;
+
+ clrsetbits_32(priv->base + SYSCTL_SYSCFG1_REG,
+ USB0_HOST_MODE, val);
+
+ return 0;
+
+ case MT7620_SYSC_IOCTL_SET_PCIE_MODE:
+ val = *(u32 *)buf;
+
+ if (val == MT7620_SYSC_PCIE_EP_MODE)
+ val = 0;
+ else if (val == MT7620_SYSC_PCIE_RC_MODE)
+ val = PCIE_RC_MODE;
+
+ clrsetbits_32(priv->base + SYSCTL_SYSCFG1_REG,
+ PCIE_RC_MODE, val);
+
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+static int mt7620_sysc_probe(struct udevice *dev)
+{
+ struct mt7620_sysc_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_remap_addr_index(dev, 0);
+ if (!priv->base) {
+ dev_err(dev, "failed to map sysc registers\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct misc_ops mt7620_sysc_ops = {
+ .read = mt7620_sysc_read,
+ .write = mt7620_sysc_write,
+ .ioctl = mt7620_sysc_ioctl,
+};
+
+static const struct udevice_id mt7620_sysc_ids[] = {
+ { .compatible = "mediatek,mt7620-sysc" },
+ { }
+};
+
+U_BOOT_DRIVER(mt7620_sysc) = {
+ .name = "mt7620_sysc",
+ .id = UCLASS_MISC,
+ .of_match = mt7620_sysc_ids,
+ .probe = mt7620_sysc_probe,
+ .ops = &mt7620_sysc_ops,
+ .priv_auto = sizeof(struct mt7620_sysc_priv),
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/arch/mips/mach-mtmips/mt7628/Kconfig b/arch/mips/mach-mtmips/mt7628/Kconfig
new file mode 100644
index 00000000000..e3f56e782eb
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/Kconfig
@@ -0,0 +1,53 @@
+
+if SOC_MT7628
+
+choice
+ prompt "Board select"
+
+config BOARD_GARDENA_SMART_GATEWAY_MT7688
+ bool "GARDENA smart Gateway"
+ select BOARD_LATE_INIT
+ help
+ GARDENA smart Gateway boards have a MT7688 SoC with 128 MiB of RAM
+ and 8 MiB of flash (SPI NOR) and additional SPI NAND storage.
+
+config BOARD_LINKIT_SMART_7688
+ bool "LinkIt Smart 7688"
+ help
+ Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM
+ and 32 MiB of flash (SPI).
+ Between its different peripherals there's an integrated switch with 4
+ ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
+ a MT7688 (PCIe).
+
+config BOARD_MT7628_RFB
+ bool "MediaTek MT7628 RFB"
+ help
+ The reference design of MT7628. The board has 128 MiB DDR2, 8 MiB
+ SPI-NOR flash, 1 built-in switch with 5 ports, 1 UART, 1 USB host,
+ 1 SDXC, 1 PCIe socket and JTAG pins.
+
+config BOARD_VOCORE2
+ bool "VoCore2"
+ select SPL_SERIAL_SUPPORT
+ select SPL_UART2_SPIS_PINMUX
+ help
+ VoCore VoCore2 board has a MT7628 SoC with 128 MiB of RAM
+ and 16 MiB of flash (SPI).
+
+endchoice
+
+config SPL_UART2_SPIS_PINMUX
+ bool "Use alternative pinmux for UART2 in SPL stage"
+ depends on SPL_SERIAL_SUPPORT
+ default n
+ help
+ Select this if the UART2 of your board is connected to GPIO 16/17
+ (shared with SPIS) rather than the usual GPIO 20/21.
+
+source "board/gardena/smart-gateway-mt7688/Kconfig"
+source "board/mediatek/mt7628/Kconfig"
+source "board/seeed/linkit-smart-7688/Kconfig"
+source "board/vocore/vocore2/Kconfig"
+
+endif