diff mbox series

[05/18] mips: mtmips: add support for MediaTek MT7620 SoC

Message ID 1602833736-19274-1-git-send-email-weijie.gao@mediatek.com
State Superseded
Delegated to: Daniel Schwierzeck
Headers show
Series [01/18] mips: dts: switch to board defines for dtb for mtmips | expand

Commit Message

Weijie Gao Oct. 16, 2020, 7:35 a.m. UTC
This patch adds support for MediaTek MT7620 SoC.
All files are dedicated for u-boot.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
 arch/mips/dts/mt7620-u-boot.dtsi              |  38 +++
 arch/mips/dts/mt7620.dtsi                     | 302 ++++++++++++++++++
 arch/mips/mach-mtmips/Kconfig                 |  22 ++
 arch/mips/mach-mtmips/Makefile                |   1 +
 .../mach-mtmips/include/mach/mt7620-sysc.h    |  54 ++++
 arch/mips/mach-mtmips/mt7620/Kconfig          |  54 ++++
 arch/mips/mach-mtmips/mt7620/Makefile         |  10 +
 arch/mips/mach-mtmips/mt7620/dram.c           | 114 +++++++
 arch/mips/mach-mtmips/mt7620/init.c           | 185 +++++++++++
 arch/mips/mach-mtmips/mt7620/lowlevel_init.S  |  53 +++
 arch/mips/mach-mtmips/mt7620/mt7620.h         | 102 ++++++
 arch/mips/mach-mtmips/mt7620/serial.c         |  37 +++
 arch/mips/mach-mtmips/mt7620/sysc.c           | 171 ++++++++++
 include/configs/mt7620.h                      |  46 +++
 14 files changed, 1189 insertions(+)
 create mode 100644 arch/mips/dts/mt7620-u-boot.dtsi
 create mode 100644 arch/mips/dts/mt7620.dtsi
 create mode 100644 arch/mips/mach-mtmips/include/mach/mt7620-sysc.h
 create mode 100644 arch/mips/mach-mtmips/mt7620/Kconfig
 create mode 100644 arch/mips/mach-mtmips/mt7620/Makefile
 create mode 100644 arch/mips/mach-mtmips/mt7620/dram.c
 create mode 100644 arch/mips/mach-mtmips/mt7620/init.c
 create mode 100644 arch/mips/mach-mtmips/mt7620/lowlevel_init.S
 create mode 100644 arch/mips/mach-mtmips/mt7620/mt7620.h
 create mode 100644 arch/mips/mach-mtmips/mt7620/serial.c
 create mode 100644 arch/mips/mach-mtmips/mt7620/sysc.c
 create mode 100644 include/configs/mt7620.h

Comments

Daniel Schwierzeck Oct. 26, 2020, 12:51 p.m. UTC | #1
Am Freitag, den 16.10.2020, 15:35 +0800 schrieb Weijie Gao:
> This patch adds support for MediaTek MT7620 SoC.
> All files are dedicated for u-boot.
> 
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
>  arch/mips/dts/mt7620-u-boot.dtsi              |  38 +++
>  arch/mips/dts/mt7620.dtsi                     | 302 ++++++++++++++++++
>  arch/mips/mach-mtmips/Kconfig                 |  22 ++
>  arch/mips/mach-mtmips/Makefile                |   1 +
>  .../mach-mtmips/include/mach/mt7620-sysc.h    |  54 ++++
>  arch/mips/mach-mtmips/mt7620/Kconfig          |  54 ++++
>  arch/mips/mach-mtmips/mt7620/Makefile         |  10 +
>  arch/mips/mach-mtmips/mt7620/dram.c           | 114 +++++++
>  arch/mips/mach-mtmips/mt7620/init.c           | 185 +++++++++++
>  arch/mips/mach-mtmips/mt7620/lowlevel_init.S  |  53 +++
>  arch/mips/mach-mtmips/mt7620/mt7620.h         | 102 ++++++
>  arch/mips/mach-mtmips/mt7620/serial.c         |  37 +++
>  arch/mips/mach-mtmips/mt7620/sysc.c           | 171 ++++++++++
>  include/configs/mt7620.h                      |  46 +++
>  14 files changed, 1189 insertions(+)
>  create mode 100644 arch/mips/dts/mt7620-u-boot.dtsi
>  create mode 100644 arch/mips/dts/mt7620.dtsi
>  create mode 100644 arch/mips/mach-mtmips/include/mach/mt7620-sysc.h
>  create mode 100644 arch/mips/mach-mtmips/mt7620/Kconfig
>  create mode 100644 arch/mips/mach-mtmips/mt7620/Makefile
>  create mode 100644 arch/mips/mach-mtmips/mt7620/dram.c
>  create mode 100644 arch/mips/mach-mtmips/mt7620/init.c
>  create mode 100644 arch/mips/mach-mtmips/mt7620/lowlevel_init.S
>  create mode 100644 arch/mips/mach-mtmips/mt7620/mt7620.h
>  create mode 100644 arch/mips/mach-mtmips/mt7620/serial.c
>  create mode 100644 arch/mips/mach-mtmips/mt7620/sysc.c
>  create mode 100644 include/configs/mt7620.h
> 
> diff --git a/arch/mips/dts/mt7620-u-boot.dtsi b/arch/mips/dts/mt7620-u-boot.dtsi
> new file mode 100644
> index 0000000000..605b77412e
> --- /dev/null
> +++ b/arch/mips/dts/mt7620-u-boot.dtsi
> @@ -0,0 +1,38 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 MediaTek Inc.
> + *
> + * Author: Weijie Gao <weijie.gao@mediatek.com>
> + */
> +
> +&palmbus {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&sysc {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&uartlite {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&uartfull {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&reboot {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&clkctrl {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&rstctrl {
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&pinctrl {
> +	u-boot,dm-pre-reloc;
> +};
> diff --git a/arch/mips/dts/mt7620.dtsi b/arch/mips/dts/mt7620.dtsi
> new file mode 100644
> index 0000000000..46bf246a4a
> --- /dev/null
> +++ b/arch/mips/dts/mt7620.dtsi
> @@ -0,0 +1,302 @@
> +// 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>;
> +	};
> +
> +	palmbus: palmbus@10000000 {
> +		compatible = "palmbus", "simple-bus";
> +		reg = <0x10000000 0x200000>;
> +		ranges = <0x0 0x10000000 0x1fffff>;
> +
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +
> +		sysc: sysc@0 {
> +			compatible = "mediatek,mt7620-sysc";
> +			reg = <0x0 0x100>;
> +		};
> +
> +		clkctrl: clkctrl@0x30 {
> +			compatible = "mediatek,mt7620-clk";
> +			mediatek,sysc = <&sysc>;
> +
> +			#clock-cells = <1>;
> +			u-boot,dm-pre-reloc;
> +		};
> +
> +		rstctrl: rstctrl@0x34 {
> +			compatible = "mediatek,mtmips-reset";
> +			reg = <0x34 0x4>;
> +			#reset-cells = <1>;
> +		};
> +
> +		reboot: resetctl-reboot {
> +			compatible = "resetctl-reboot";
> +
> +			resets = <&rstctrl SYS_RST>;
> +			reset-names = "sysreset";
> +		};
> +
> +		uartfull: uartfull@500 {
> +			compatible = "mediatek,mt7620-uart";
> +			reg = <0x500 0x100>;
> +
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&uartf_gpio_pins>;
> +
> +			clocks = <&clkctrl CLK_UARTF>;
> +
> +			resets = <&rstctrl UARTF_RST>;
> +			reset-names = "uartf";
> +
> +			status = "disabled";
> +		};
> +
> +		uartlite: uartlite@c00 {
> +			compatible = "mediatek,mt7620-uart";
> +			reg = <0xc00 0x100>;
> +
> +			pinctrl-names = "default";
> +			pinctrl-0 = <&uartl_pins>;
> +
> +			clocks = <&clkctrl CLK_UARTL>;
> +
> +			resets = <&rstctrl UARTL_RST>;
> +			reset-names = "uartl";
> +		};
> +
> +		pinctrl: pinctrl@60 {
> +			compatible = "mediatek,mt7620-pinctrl";
> +			reg = <0x60 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@120 {
> +			compatible = "mediatek,mt7620-wdt";
> +			reg = <0x120 0x10>;
> +
> +			resets = <&rstctrl TIMER_RST>;
> +			reset-names = "wdt";
> +		};
> +
> +		gpio0: gpio0@600 {
> +			compatible = "mediatek,mt7620-gpio";
> +			reg = <0x600 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@638 {
> +			compatible = "mediatek,mt7620-gpio";
> +			reg = <0x638 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@660 {
> +			compatible = "mediatek,mt7620-gpio";
> +			reg = <0x660 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@688 {
> +			compatible = "mediatek,mt7620-gpio";
> +			reg = <0x688 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@b00 {
> +			compatible = "mediatek,mt7620-spi";
> +			reg = <0xb00 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 7c07430a0c..47a38e2d7f 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,30 @@ 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 SYSRESET_RESETCTL
> +	select MISC
> +	select SPL_SEPARATE_BSS if SPL
> +	select SPL_LOADER_SUPPORT if SPL
> +	select SPL_OF_CONTROL if SPL_DM
> +	select SPL_SIMPLE_BUS if SPL_DM
> +	select SPL_DM_SERIAL if SPL_DM
> +	select SPL_CLK if SPL_DM && SPL_SERIAL_SUPPORT
> +	select SPL_SYSRESET if SPL_DM
> +	select SPL_OF_LIBFDT if SPL_OF_CONTROL
> +	help
> +	  This supports MediaTek MT7620.
> +
>  config SOC_MT7628
>  	bool "MT7628"
>  	select MIPS_L1_CACHE_SHIFT_5
> @@ -58,6 +79,7 @@ config SOC_MT7628
>  
>  endchoice
>  
> +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 a7e6a66304..4909b47ef2 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/include/mach/mt7620-sysc.h b/arch/mips/mach-mtmips/include/mach/mt7620-sysc.h
> new file mode 100644
> index 0000000000..743ca034c8
> --- /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 0000000000..aa7cf1d3c1
> --- /dev/null
> +++ b/arch/mips/mach-mtmips/mt7620/Kconfig
> @@ -0,0 +1,54 @@
> +
> +if SOC_MT7620
> +
> +config DEBUG_UART_BOARD_INIT
> +	default y
> +
> +choice
> +	prompt "Board select"
> +
> +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
> +
> +endif
> diff --git a/arch/mips/mach-mtmips/mt7620/Makefile b/arch/mips/mach-mtmips/mt7620/Makefile
> new file mode 100644
> index 0000000000..649f6c3798
> --- /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 0000000000..3fae3fd319
> --- /dev/null
> +++ b/arch/mips/mach-mtmips/mt7620/dram.c
> @@ -0,0 +1,114 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
> + *
> + * Author:  Weijie Gao <weijie.gao@mediatek.com>
> + */
> +
> +#include <common.h>

please try to avoid common.h in new code and directly use required
header files. I think you just additionallyneed asm/io.h. There is
ongoing work of refactoring and cleanup of common.h by Simon Glass.

> +#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 0000000000..e3d9e45f4e
> --- /dev/null
> +++ b/arch/mips/mach-mtmips/mt7620/init.c
> @@ -0,0 +1,185 @@
> +// 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;
> +}
> 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 0000000000..399174620d
> --- /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 0000000000..6e84015308
> --- /dev/null
> +++ b/arch/mips/mach-mtmips/mt7620/mt7620.h
> @@ -0,0 +1,102 @@
> +/* 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 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 0000000000..b1c9ea9edd
> --- /dev/null
> +++ b/arch/mips/mach-mtmips/mt7620/serial.c
> @@ -0,0 +1,37 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 MediaTek Inc.
> + *
> + * Author:  Weijie Gao <weijie.gao@mediatek.com>
> + */
> +
> +#include <common.h>

you should just need debug_uart.h

> +#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 0000000000..dd8cd12b2f
> --- /dev/null
> +++ b/arch/mips/mach-mtmips/mt7620/sysc.c
> @@ -0,0 +1,171 @@
> +// 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 <linux/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_alloc_size = sizeof(struct mt7620_sysc_priv),
> +};
> diff --git a/include/configs/mt7620.h b/include/configs/mt7620.h
> new file mode 100644
> index 0000000000..4d074a3688
> --- /dev/null
> +++ b/include/configs/mt7620.h
> @@ -0,0 +1,46 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
> + *
> + * Author: Weijie Gao <weijie.gao@mediatek.com>
> + */
> +
> +#ifndef __CONFIG_MT7620_H
> +#define __CONFIG_MT7620_H
> +
> +#define CONFIG_SYS_HZ			1000
> +#define CONFIG_SYS_MIPS_TIMER_FREQ	290000000
> +
> +#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
> +
> +#define CONFIG_SYS_MALLOC_LEN		0x100000
> +#define CONFIG_SYS_BOOTPARAMS_LEN	0x20000
> +
> +#define CONFIG_SYS_SDRAM_BASE		0x80000000
> +#define CONFIG_SYS_LOAD_ADDR		0x80010000
> +
> +#define CONFIG_SYS_INIT_SP_OFFSET	0x400000
> +
> +#define CONFIG_SYS_BOOTM_LEN		0x1000000
> +
> +#define CONFIG_SYS_MAXARGS		16
> +#define CONFIG_SYS_CBSIZE		1024
> +
> +/* Serial common */
> +#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
> +
> +/* SPL */
> +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
> +#define CONFIG_SKIP_LOWLEVEL_INIT
> +#endif
> +
> +#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
> +#define CONFIG_SPL_BSS_START_ADDR	0x80010000
> +#define CONFIG_SPL_BSS_MAX_SIZE		0x10000
> +#define CONFIG_SPL_MAX_SIZE		0x10000
> +#define CONFIG_SPL_PAD_TO		0
> +
> +/* Dummy value */
> +#define CONFIG_SYS_UBOOT_BASE		0
> +
> +#endif /* __CONFIG_MT7620_H */
> -- 
> 2.17.1
Weijie Gao Oct. 27, 2020, 12:50 a.m. UTC | #2
On Mon, 2020-10-26 at 13:51 +0100, Daniel Schwierzeck wrote:
> Am Freitag, den 16.10.2020, 15:35 +0800 schrieb Weijie Gao:
> > This patch adds support for MediaTek MT7620 SoC.
> > All files are dedicated for u-boot.
> > 
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> >  arch/mips/dts/mt7620-u-boot.dtsi              |  38 +++
> >  arch/mips/dts/mt7620.dtsi                     | 302 ++++++++++++++++++
> >  arch/mips/mach-mtmips/Kconfig                 |  22 ++
> >  arch/mips/mach-mtmips/Makefile                |   1 +
> >  .../mach-mtmips/include/mach/mt7620-sysc.h    |  54 ++++
> >  arch/mips/mach-mtmips/mt7620/Kconfig          |  54 ++++
> >  arch/mips/mach-mtmips/mt7620/Makefile         |  10 +
> >  arch/mips/mach-mtmips/mt7620/dram.c           | 114 +++++++
> >  arch/mips/mach-mtmips/mt7620/init.c           | 185 +++++++++++
> >  arch/mips/mach-mtmips/mt7620/lowlevel_init.S  |  53 +++
> >  arch/mips/mach-mtmips/mt7620/mt7620.h         | 102 ++++++
> >  arch/mips/mach-mtmips/mt7620/serial.c         |  37 +++
> >  arch/mips/mach-mtmips/mt7620/sysc.c           | 171 ++++++++++
> >  include/configs/mt7620.h                      |  46 +++
> >  14 files changed, 1189 insertions(+)
> >  create mode 100644 arch/mips/dts/mt7620-u-boot.dtsi
> >  create mode 100644 arch/mips/dts/mt7620.dtsi
> >  create mode 100644 arch/mips/mach-mtmips/include/mach/mt7620-sysc.h
> >  create mode 100644 arch/mips/mach-mtmips/mt7620/Kconfig
> >  create mode 100644 arch/mips/mach-mtmips/mt7620/Makefile
> >  create mode 100644 arch/mips/mach-mtmips/mt7620/dram.c
> >  create mode 100644 arch/mips/mach-mtmips/mt7620/init.c
> >  create mode 100644 arch/mips/mach-mtmips/mt7620/lowlevel_init.S
> >  create mode 100644 arch/mips/mach-mtmips/mt7620/mt7620.h
> >  create mode 100644 arch/mips/mach-mtmips/mt7620/serial.c
> >  create mode 100644 arch/mips/mach-mtmips/mt7620/sysc.c
> >  create mode 100644 include/configs/mt7620.h
> > 
> > diff --git a/arch/mips/dts/mt7620-u-boot.dtsi b/arch/mips/dts/mt7620-u-boot.dtsi
> > new file mode 100644
> > index 0000000000..605b77412e
> > --- /dev/null
> > +++ b/arch/mips/dts/mt7620-u-boot.dtsi
> > @@ -0,0 +1,38 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc.
> > + *
> > + * Author: Weijie Gao <weijie.gao@mediatek.com>
> > + */
> > +
> > +&palmbus {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&sysc {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&uartlite {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&uartfull {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&reboot {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&clkctrl {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&rstctrl {
> > +	u-boot,dm-pre-reloc;
> > +};
> > +
> > +&pinctrl {
> > +	u-boot,dm-pre-reloc;
> > +};
> > diff --git a/arch/mips/dts/mt7620.dtsi b/arch/mips/dts/mt7620.dtsi
> > new file mode 100644
> > index 0000000000..46bf246a4a
> > --- /dev/null
> > +++ b/arch/mips/dts/mt7620.dtsi
> > @@ -0,0 +1,302 @@
> > +// 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>;
> > +	};
> > +
> > +	palmbus: palmbus@10000000 {
> > +		compatible = "palmbus", "simple-bus";
> > +		reg = <0x10000000 0x200000>;
> > +		ranges = <0x0 0x10000000 0x1fffff>;
> > +
> > +		#address-cells = <1>;
> > +		#size-cells = <1>;
> > +
> > +		sysc: sysc@0 {
> > +			compatible = "mediatek,mt7620-sysc";
> > +			reg = <0x0 0x100>;
> > +		};
> > +
> > +		clkctrl: clkctrl@0x30 {
> > +			compatible = "mediatek,mt7620-clk";
> > +			mediatek,sysc = <&sysc>;
> > +
> > +			#clock-cells = <1>;
> > +			u-boot,dm-pre-reloc;
> > +		};
> > +
> > +		rstctrl: rstctrl@0x34 {
> > +			compatible = "mediatek,mtmips-reset";
> > +			reg = <0x34 0x4>;
> > +			#reset-cells = <1>;
> > +		};
> > +
> > +		reboot: resetctl-reboot {
> > +			compatible = "resetctl-reboot";
> > +
> > +			resets = <&rstctrl SYS_RST>;
> > +			reset-names = "sysreset";
> > +		};
> > +
> > +		uartfull: uartfull@500 {
> > +			compatible = "mediatek,mt7620-uart";
> > +			reg = <0x500 0x100>;
> > +
> > +			pinctrl-names = "default";
> > +			pinctrl-0 = <&uartf_gpio_pins>;
> > +
> > +			clocks = <&clkctrl CLK_UARTF>;
> > +
> > +			resets = <&rstctrl UARTF_RST>;
> > +			reset-names = "uartf";
> > +
> > +			status = "disabled";
> > +		};
> > +
> > +		uartlite: uartlite@c00 {
> > +			compatible = "mediatek,mt7620-uart";
> > +			reg = <0xc00 0x100>;
> > +
> > +			pinctrl-names = "default";
> > +			pinctrl-0 = <&uartl_pins>;
> > +
> > +			clocks = <&clkctrl CLK_UARTL>;
> > +
> > +			resets = <&rstctrl UARTL_RST>;
> > +			reset-names = "uartl";
> > +		};
> > +
> > +		pinctrl: pinctrl@60 {
> > +			compatible = "mediatek,mt7620-pinctrl";
> > +			reg = <0x60 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@120 {
> > +			compatible = "mediatek,mt7620-wdt";
> > +			reg = <0x120 0x10>;
> > +
> > +			resets = <&rstctrl TIMER_RST>;
> > +			reset-names = "wdt";
> > +		};
> > +
> > +		gpio0: gpio0@600 {
> > +			compatible = "mediatek,mt7620-gpio";
> > +			reg = <0x600 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@638 {
> > +			compatible = "mediatek,mt7620-gpio";
> > +			reg = <0x638 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@660 {
> > +			compatible = "mediatek,mt7620-gpio";
> > +			reg = <0x660 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@688 {
> > +			compatible = "mediatek,mt7620-gpio";
> > +			reg = <0x688 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@b00 {
> > +			compatible = "mediatek,mt7620-spi";
> > +			reg = <0xb00 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 7c07430a0c..47a38e2d7f 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,30 @@ 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 SYSRESET_RESETCTL
> > +	select MISC
> > +	select SPL_SEPARATE_BSS if SPL
> > +	select SPL_LOADER_SUPPORT if SPL
> > +	select SPL_OF_CONTROL if SPL_DM
> > +	select SPL_SIMPLE_BUS if SPL_DM
> > +	select SPL_DM_SERIAL if SPL_DM
> > +	select SPL_CLK if SPL_DM && SPL_SERIAL_SUPPORT
> > +	select SPL_SYSRESET if SPL_DM
> > +	select SPL_OF_LIBFDT if SPL_OF_CONTROL
> > +	help
> > +	  This supports MediaTek MT7620.
> > +
> >  config SOC_MT7628
> >  	bool "MT7628"
> >  	select MIPS_L1_CACHE_SHIFT_5
> > @@ -58,6 +79,7 @@ config SOC_MT7628
> >  
> >  endchoice
> >  
> > +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 a7e6a66304..4909b47ef2 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/include/mach/mt7620-sysc.h b/arch/mips/mach-mtmips/include/mach/mt7620-sysc.h
> > new file mode 100644
> > index 0000000000..743ca034c8
> > --- /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 0000000000..aa7cf1d3c1
> > --- /dev/null
> > +++ b/arch/mips/mach-mtmips/mt7620/Kconfig
> > @@ -0,0 +1,54 @@
> > +
> > +if SOC_MT7620
> > +
> > +config DEBUG_UART_BOARD_INIT
> > +	default y
> > +
> > +choice
> > +	prompt "Board select"
> > +
> > +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
> > +
> > +endif
> > diff --git a/arch/mips/mach-mtmips/mt7620/Makefile b/arch/mips/mach-mtmips/mt7620/Makefile
> > new file mode 100644
> > index 0000000000..649f6c3798
> > --- /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 0000000000..3fae3fd319
> > --- /dev/null
> > +++ b/arch/mips/mach-mtmips/mt7620/dram.c
> > @@ -0,0 +1,114 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
> > + *
> > + * Author:  Weijie Gao <weijie.gao@mediatek.com>
> > + */
> > +
> > +#include <common.h>
> 
> please try to avoid common.h in new code and directly use required
> header files. I think you just additionallyneed asm/io.h. There is
> ongoing work of refactoring and cleanup of common.h by Simon Glass.

ok. seems that I forgot to modify some files derived from mt7628.

> 
> > +#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 0000000000..e3d9e45f4e
> > --- /dev/null
> > +++ b/arch/mips/mach-mtmips/mt7620/init.c
> > @@ -0,0 +1,185 @@
> > +// 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;
> > +}
> > 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 0000000000..399174620d
> > --- /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 0000000000..6e84015308
> > --- /dev/null
> > +++ b/arch/mips/mach-mtmips/mt7620/mt7620.h
> > @@ -0,0 +1,102 @@
> > +/* 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 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 0000000000..b1c9ea9edd
> > --- /dev/null
> > +++ b/arch/mips/mach-mtmips/mt7620/serial.c
> > @@ -0,0 +1,37 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc.
> > + *
> > + * Author:  Weijie Gao <weijie.gao@mediatek.com>
> > + */
> > +
> > +#include <common.h>
> 
> you should just need debug_uart.h

ok. I'll change it.

> 
> > +#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 0000000000..dd8cd12b2f
> > --- /dev/null
> > +++ b/arch/mips/mach-mtmips/mt7620/sysc.c
> > @@ -0,0 +1,171 @@
> > +// 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 <linux/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_alloc_size = sizeof(struct mt7620_sysc_priv),
> > +};
> > diff --git a/include/configs/mt7620.h b/include/configs/mt7620.h
> > new file mode 100644
> > index 0000000000..4d074a3688
> > --- /dev/null
> > +++ b/include/configs/mt7620.h
> > @@ -0,0 +1,46 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
> > + *
> > + * Author: Weijie Gao <weijie.gao@mediatek.com>
> > + */
> > +
> > +#ifndef __CONFIG_MT7620_H
> > +#define __CONFIG_MT7620_H
> > +
> > +#define CONFIG_SYS_HZ			1000
> > +#define CONFIG_SYS_MIPS_TIMER_FREQ	290000000
> > +
> > +#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
> > +
> > +#define CONFIG_SYS_MALLOC_LEN		0x100000
> > +#define CONFIG_SYS_BOOTPARAMS_LEN	0x20000
> > +
> > +#define CONFIG_SYS_SDRAM_BASE		0x80000000
> > +#define CONFIG_SYS_LOAD_ADDR		0x80010000
> > +
> > +#define CONFIG_SYS_INIT_SP_OFFSET	0x400000
> > +
> > +#define CONFIG_SYS_BOOTM_LEN		0x1000000
> > +
> > +#define CONFIG_SYS_MAXARGS		16
> > +#define CONFIG_SYS_CBSIZE		1024
> > +
> > +/* Serial common */
> > +#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
> > +
> > +/* SPL */
> > +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
> > +#define CONFIG_SKIP_LOWLEVEL_INIT
> > +#endif
> > +
> > +#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
> > +#define CONFIG_SPL_BSS_START_ADDR	0x80010000
> > +#define CONFIG_SPL_BSS_MAX_SIZE		0x10000
> > +#define CONFIG_SPL_MAX_SIZE		0x10000
> > +#define CONFIG_SPL_PAD_TO		0
> > +
> > +/* Dummy value */
> > +#define CONFIG_SYS_UBOOT_BASE		0
> > +
> > +#endif /* __CONFIG_MT7620_H */
> > -- 
> > 2.17.1
diff mbox series

Patch

diff --git a/arch/mips/dts/mt7620-u-boot.dtsi b/arch/mips/dts/mt7620-u-boot.dtsi
new file mode 100644
index 0000000000..605b77412e
--- /dev/null
+++ b/arch/mips/dts/mt7620-u-boot.dtsi
@@ -0,0 +1,38 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+&palmbus {
+	u-boot,dm-pre-reloc;
+};
+
+&sysc {
+	u-boot,dm-pre-reloc;
+};
+
+&uartlite {
+	u-boot,dm-pre-reloc;
+};
+
+&uartfull {
+	u-boot,dm-pre-reloc;
+};
+
+&reboot {
+	u-boot,dm-pre-reloc;
+};
+
+&clkctrl {
+	u-boot,dm-pre-reloc;
+};
+
+&rstctrl {
+	u-boot,dm-pre-reloc;
+};
+
+&pinctrl {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/mips/dts/mt7620.dtsi b/arch/mips/dts/mt7620.dtsi
new file mode 100644
index 0000000000..46bf246a4a
--- /dev/null
+++ b/arch/mips/dts/mt7620.dtsi
@@ -0,0 +1,302 @@ 
+// 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>;
+	};
+
+	palmbus: palmbus@10000000 {
+		compatible = "palmbus", "simple-bus";
+		reg = <0x10000000 0x200000>;
+		ranges = <0x0 0x10000000 0x1fffff>;
+
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		sysc: sysc@0 {
+			compatible = "mediatek,mt7620-sysc";
+			reg = <0x0 0x100>;
+		};
+
+		clkctrl: clkctrl@0x30 {
+			compatible = "mediatek,mt7620-clk";
+			mediatek,sysc = <&sysc>;
+
+			#clock-cells = <1>;
+			u-boot,dm-pre-reloc;
+		};
+
+		rstctrl: rstctrl@0x34 {
+			compatible = "mediatek,mtmips-reset";
+			reg = <0x34 0x4>;
+			#reset-cells = <1>;
+		};
+
+		reboot: resetctl-reboot {
+			compatible = "resetctl-reboot";
+
+			resets = <&rstctrl SYS_RST>;
+			reset-names = "sysreset";
+		};
+
+		uartfull: uartfull@500 {
+			compatible = "mediatek,mt7620-uart";
+			reg = <0x500 0x100>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uartf_gpio_pins>;
+
+			clocks = <&clkctrl CLK_UARTF>;
+
+			resets = <&rstctrl UARTF_RST>;
+			reset-names = "uartf";
+
+			status = "disabled";
+		};
+
+		uartlite: uartlite@c00 {
+			compatible = "mediatek,mt7620-uart";
+			reg = <0xc00 0x100>;
+
+			pinctrl-names = "default";
+			pinctrl-0 = <&uartl_pins>;
+
+			clocks = <&clkctrl CLK_UARTL>;
+
+			resets = <&rstctrl UARTL_RST>;
+			reset-names = "uartl";
+		};
+
+		pinctrl: pinctrl@60 {
+			compatible = "mediatek,mt7620-pinctrl";
+			reg = <0x60 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@120 {
+			compatible = "mediatek,mt7620-wdt";
+			reg = <0x120 0x10>;
+
+			resets = <&rstctrl TIMER_RST>;
+			reset-names = "wdt";
+		};
+
+		gpio0: gpio0@600 {
+			compatible = "mediatek,mt7620-gpio";
+			reg = <0x600 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@638 {
+			compatible = "mediatek,mt7620-gpio";
+			reg = <0x638 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@660 {
+			compatible = "mediatek,mt7620-gpio";
+			reg = <0x660 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@688 {
+			compatible = "mediatek,mt7620-gpio";
+			reg = <0x688 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@b00 {
+			compatible = "mediatek,mt7620-spi";
+			reg = <0xb00 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 7c07430a0c..47a38e2d7f 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,30 @@  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 SYSRESET_RESETCTL
+	select MISC
+	select SPL_SEPARATE_BSS if SPL
+	select SPL_LOADER_SUPPORT if SPL
+	select SPL_OF_CONTROL if SPL_DM
+	select SPL_SIMPLE_BUS if SPL_DM
+	select SPL_DM_SERIAL if SPL_DM
+	select SPL_CLK if SPL_DM && SPL_SERIAL_SUPPORT
+	select SPL_SYSRESET if SPL_DM
+	select SPL_OF_LIBFDT if SPL_OF_CONTROL
+	help
+	  This supports MediaTek MT7620.
+
 config SOC_MT7628
 	bool "MT7628"
 	select MIPS_L1_CACHE_SHIFT_5
@@ -58,6 +79,7 @@  config SOC_MT7628
 
 endchoice
 
+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 a7e6a66304..4909b47ef2 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/include/mach/mt7620-sysc.h b/arch/mips/mach-mtmips/include/mach/mt7620-sysc.h
new file mode 100644
index 0000000000..743ca034c8
--- /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 0000000000..aa7cf1d3c1
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/Kconfig
@@ -0,0 +1,54 @@ 
+
+if SOC_MT7620
+
+config DEBUG_UART_BOARD_INIT
+	default y
+
+choice
+	prompt "Board select"
+
+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
+
+endif
diff --git a/arch/mips/mach-mtmips/mt7620/Makefile b/arch/mips/mach-mtmips/mt7620/Makefile
new file mode 100644
index 0000000000..649f6c3798
--- /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 0000000000..3fae3fd319
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/dram.c
@@ -0,0 +1,114 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#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 0000000000..e3d9e45f4e
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/init.c
@@ -0,0 +1,185 @@ 
+// 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;
+}
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 0000000000..399174620d
--- /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 0000000000..6e84015308
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/mt7620.h
@@ -0,0 +1,102 @@ 
+/* 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 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 0000000000..b1c9ea9edd
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/serial.c
@@ -0,0 +1,37 @@ 
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#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 0000000000..dd8cd12b2f
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/sysc.c
@@ -0,0 +1,171 @@ 
+// 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 <linux/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_alloc_size = sizeof(struct mt7620_sysc_priv),
+};
diff --git a/include/configs/mt7620.h b/include/configs/mt7620.h
new file mode 100644
index 0000000000..4d074a3688
--- /dev/null
+++ b/include/configs/mt7620.h
@@ -0,0 +1,46 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef __CONFIG_MT7620_H
+#define __CONFIG_MT7620_H
+
+#define CONFIG_SYS_HZ			1000
+#define CONFIG_SYS_MIPS_TIMER_FREQ	290000000
+
+#define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_MALLOC_LEN		0x100000
+#define CONFIG_SYS_BOOTPARAMS_LEN	0x20000
+
+#define CONFIG_SYS_SDRAM_BASE		0x80000000
+#define CONFIG_SYS_LOAD_ADDR		0x80010000
+
+#define CONFIG_SYS_INIT_SP_OFFSET	0x400000
+
+#define CONFIG_SYS_BOOTM_LEN		0x1000000
+
+#define CONFIG_SYS_MAXARGS		16
+#define CONFIG_SYS_CBSIZE		1024
+
+/* Serial common */
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+/* SPL */
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#endif
+
+#define CONFIG_SYS_UBOOT_START		CONFIG_SYS_TEXT_BASE
+#define CONFIG_SPL_BSS_START_ADDR	0x80010000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x10000
+#define CONFIG_SPL_MAX_SIZE		0x10000
+#define CONFIG_SPL_PAD_TO		0
+
+/* Dummy value */
+#define CONFIG_SYS_UBOOT_BASE		0
+
+#endif /* __CONFIG_MT7620_H */