All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/21] Add support for MediaTek MT7620 SoC
@ 2020-10-30  9:33 Weijie Gao
  2020-10-30  9:33 ` [PATCH v2 01/21] mips: dts: switch to board defines for dtb for mtmips Weijie Gao
                   ` (20 more replies)
  0 siblings, 21 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:33 UTC (permalink / raw)
  To: u-boot

This series will add support for MediaTek MT7620 SoC with two reference boards
and related drivers.

The MediaTek MT7620 is a 2x2 802.11n WiSoC integrating a MIPS 24KEc processor
running at a maximum frequency of 620MHz. This chip can be found in many
wireless routers.

This series add all basic drivers which are useful in u-boot, like usb, sdhc,
ethernet, spi and serial. Booting from NAND is currently unsupported.

Thanks,
Weijie

v2 changes:
- Remove non-DM code from mt7620-serial driver, and use of-platdata instead
- Fix dev_err related compilation error
- Add expire_now for mt7620-wdt
- Remove use of common.h

Weijie Gao (21):
  mips: dts: switch to board defines for dtb for mtmips
  mips: mtmips: move mt7628 related Kconfig into mt7628 subdirectory
  mips: mtmips: select SYSRESET for mt7628 only
  mips: mtmips: fix dram size detection in dram_init
  mips: enable _machine_restart for spl
  mips: mtmips: add support to initialize SDRAM
  mips: mtmips: add support for MediaTek MT7620 SoC
  mips: mtmips: add two reference boards for mt7620
  configs: mtmips: refresh for mt7628 based boards
  serial: add uart driver for MediaTek MT7620 SoC
  clk: add clock driver for MediaTek MT7620 SoC
  reset: mtmips: add reset controller support for MediaTek MT7620 SoC
  pinctrl: mtmips: add support for MediaTek MT7620 SoC
  watchdog: add watchdog driver for MediaTek MT7620 SoC
  gpio: add GPIO controller driver for MediaTek MT7620 SoC
  spi: add spi controller support for MediaTek MT7620 SoC
  phy: add USB PHY driver for MediaTek MT7620 SoC
  net: add ethernet driver for MediaTek MT7620 SoC
  mmc: mtk-sd: add pad control settings for MediaTek MT7620/MT76x8 SoCs
  reset: reset-mtmips: add DM_FLAG_PRE_RELOC flag
  MAINTAINERS: add maintainer for MediaTek MIPS platform

 MAINTAINERS                                   |   23 +
 arch/mips/Kconfig                             |    1 -
 arch/mips/cpu/cpu.c                           |    2 +-
 arch/mips/dts/Makefile                        |    7 +-
 arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts  |  100 ++
 arch/mips/dts/mediatek,mt7620-rfb.dts         |   97 ++
 arch/mips/dts/mt7620-u-boot.dtsi              |   14 +
 arch/mips/dts/mt7620.dtsi                     |  296 ++++
 arch/mips/mach-mtmips/Kconfig                 |   72 +-
 arch/mips/mach-mtmips/Makefile                |    1 +
 arch/mips/mach-mtmips/cpu.c                   |    5 +-
 arch/mips/mach-mtmips/ddr_init.c              |   59 +
 arch/mips/mach-mtmips/include/mach/ddr.h      |    4 +
 .../mach-mtmips/include/mach/mt7620-sysc.h    |   54 +
 arch/mips/mach-mtmips/mt7620/Kconfig          |   71 +
 arch/mips/mach-mtmips/mt7620/Makefile         |   10 +
 arch/mips/mach-mtmips/mt7620/dram.c           |  113 ++
 arch/mips/mach-mtmips/mt7620/init.c           |  193 +++
 arch/mips/mach-mtmips/mt7620/lowlevel_init.S  |   53 +
 arch/mips/mach-mtmips/mt7620/mt7620.h         |  103 ++
 arch/mips/mach-mtmips/mt7620/serial.c         |   36 +
 arch/mips/mach-mtmips/mt7620/sysc.c           |  172 +++
 arch/mips/mach-mtmips/mt7628/Kconfig          |   53 +
 board/mediatek/mt7620/Kconfig                 |   12 +
 board/mediatek/mt7620/MAINTAINERS             |    9 +
 board/mediatek/mt7620/Makefile                |    3 +
 board/mediatek/mt7620/board.c                 |    6 +
 .../gardena-smart-gateway-mt7688_defconfig    |    1 +
 configs/linkit-smart-7688_defconfig           |    1 +
 configs/mt7620_mt7530_rfb_defconfig           |   58 +
 configs/mt7620_rfb_defconfig                  |   76 +
 configs/mt7628_rfb_defconfig                  |    1 +
 configs/vocore2_defconfig                     |    1 +
 drivers/clk/mtmips/Makefile                   |    1 +
 drivers/clk/mtmips/clk-mt7620.c               |  159 +++
 drivers/gpio/Kconfig                          |    8 +
 drivers/gpio/Makefile                         |    1 +
 drivers/gpio/mt7620_gpio.c                    |  146 ++
 drivers/mmc/mtk-sd.c                          |  122 +-
 drivers/net/Kconfig                           |   12 +
 drivers/net/Makefile                          |    1 +
 drivers/net/mt7620-eth.c                      | 1222 +++++++++++++++++
 drivers/phy/Kconfig                           |    7 +
 drivers/phy/Makefile                          |    1 +
 drivers/phy/mt7620-usb-phy.c                  |  113 ++
 drivers/pinctrl/mtmips/Kconfig                |    9 +
 drivers/pinctrl/mtmips/Makefile               |    1 +
 drivers/pinctrl/mtmips/pinctrl-mt7620.c       |  200 +++
 drivers/reset/reset-mtmips.c                  |    1 +
 drivers/serial/Kconfig                        |   20 +
 drivers/serial/Makefile                       |    1 +
 drivers/serial/serial.c                       |    2 +
 drivers/serial/serial_mt7620.c                |  246 ++++
 drivers/spi/Kconfig                           |    7 +
 drivers/spi/Makefile                          |    1 +
 drivers/spi/mt7620_spi.c                      |  277 ++++
 drivers/watchdog/Kconfig                      |    7 +
 drivers/watchdog/Makefile                     |    1 +
 drivers/watchdog/mt7620_wdt.c                 |  132 ++
 include/configs/mt7620.h                      |   46 +
 include/dt-bindings/clock/mt7620-clk.h        |   40 +
 include/dt-bindings/reset/mt7620-reset.h      |   35 +
 62 files changed, 4463 insertions(+), 63 deletions(-)
 create mode 100644 arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts
 create mode 100644 arch/mips/dts/mediatek,mt7620-rfb.dts
 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 arch/mips/mach-mtmips/mt7628/Kconfig
 create mode 100644 board/mediatek/mt7620/Kconfig
 create mode 100644 board/mediatek/mt7620/MAINTAINERS
 create mode 100644 board/mediatek/mt7620/Makefile
 create mode 100644 board/mediatek/mt7620/board.c
 create mode 100644 configs/mt7620_mt7530_rfb_defconfig
 create mode 100644 configs/mt7620_rfb_defconfig
 create mode 100644 drivers/clk/mtmips/clk-mt7620.c
 create mode 100644 drivers/gpio/mt7620_gpio.c
 create mode 100644 drivers/net/mt7620-eth.c
 create mode 100644 drivers/phy/mt7620-usb-phy.c
 create mode 100644 drivers/pinctrl/mtmips/pinctrl-mt7620.c
 create mode 100644 drivers/serial/serial_mt7620.c
 create mode 100644 drivers/spi/mt7620_spi.c
 create mode 100644 drivers/watchdog/mt7620_wdt.c
 create mode 100644 include/configs/mt7620.h
 create mode 100644 include/dt-bindings/clock/mt7620-clk.h
 create mode 100644 include/dt-bindings/reset/mt7620-reset.h

-- 
2.17.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 01/21] mips: dts: switch to board defines for dtb for mtmips
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
@ 2020-10-30  9:33 ` Weijie Gao
  2020-10-30  9:33 ` [PATCH v2 02/21] mips: mtmips: move mt7628 related Kconfig into mt7628 subdirectory Weijie Gao
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:33 UTC (permalink / raw)
  To: u-boot

Previous the dts files for gardena-smart-gateway-mt7688 and
linkit-smart-7688 are set to be built when mtmips is selected.

This can lead to a compilation error if another soc is added to this arch
with different dtsi files.

So it's better to build the dtb only if their board is selected.

Reviewed-by: Stefan Roese <sr@denx.de>
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 arch/mips/dts/Makefile | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index dc85901dca..e82f96d4e4 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -1,8 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0+
 
-dtb-$(CONFIG_ARCH_MTMIPS) += \
-	gardena-smart-gateway-mt7688.dtb \
-	linkit-smart-7688.dtb
 dtb-$(CONFIG_TARGET_AP121) += ap121.dtb
 dtb-$(CONFIG_TARGET_AP143) += ap143.dtb
 dtb-$(CONFIG_TARGET_AP152) += ap152.dtb
@@ -18,6 +15,8 @@ dtb-$(CONFIG_BOARD_COMTREND_VR3032U) += comtrend,vr-3032u.dtb
 dtb-$(CONFIG_BOARD_COMTREND_WAP5813N) += comtrend,wap-5813n.dtb
 dtb-$(CONFIG_BOARD_HUAWEI_HG556A) += huawei,hg556a.dtb
 dtb-$(CONFIG_BOARD_MT7628_RFB) += mediatek,mt7628-rfb.dtb
+dtb-$(CONFIG_BOARD_GARDENA_SMART_GATEWAY_MT7688) += gardena-smart-gateway-mt7688.dtb
+dtb-$(CONFIG_BOARD_LINKIT_SMART_7688) += linkit-smart-7688.dtb
 dtb-$(CONFIG_TARGET_OCTEON_EBB7304) += mrvl,octeon-ebb7304.dtb
 dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
 dtb-$(CONFIG_BOARD_NETGEAR_DGND3700V2) += netgear,dgnd3700v2.dtb
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 02/21] mips: mtmips: move mt7628 related Kconfig into mt7628 subdirectory
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
  2020-10-30  9:33 ` [PATCH v2 01/21] mips: dts: switch to board defines for dtb for mtmips Weijie Gao
@ 2020-10-30  9:33 ` Weijie Gao
  2020-10-30  9:33 ` [PATCH v2 03/21] mips: mtmips: select SYSRESET for mt7628 only Weijie Gao
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:33 UTC (permalink / raw)
  To: u-boot

This patch is a preparation for add a new soc fot mtmips.

Move all mt7628 related Kconfig (boards and UART selection) into mt7628
subdirectory and make sure the top directory of mtmips contains only
selection for SoCs.

Reviewed-by: Stefan Roese <sr@denx.de>
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 arch/mips/mach-mtmips/Kconfig        | 53 +---------------------------
 arch/mips/mach-mtmips/mt7628/Kconfig | 53 ++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 52 deletions(-)
 create mode 100644 arch/mips/mach-mtmips/mt7628/Kconfig

diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig
index 737de2cb8e..7c07430a0c 100644
--- a/arch/mips/mach-mtmips/Kconfig
+++ b/arch/mips/mach-mtmips/Kconfig
@@ -58,57 +58,6 @@ config SOC_MT7628
 
 endchoice
 
-choice
-	prompt "Board select"
-
-config BOARD_GARDENA_SMART_GATEWAY_MT7688
-	bool "GARDENA smart Gateway"
-	depends on SOC_MT7628
-	select BOARD_LATE_INIT
-	help
-	  GARDENA smart Gateway boards have a MT7688 SoC with 128 MiB of RAM
-	  and 8 MiB of flash (SPI NOR) and additional SPI NAND storage.
-
-config BOARD_LINKIT_SMART_7688
-	bool "LinkIt Smart 7688"
-	depends on SOC_MT7628
-	help
-	  Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM
-	  and 32 MiB of flash (SPI).
-	  Between its different peripherals there's an integrated switch with 4
-	  ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
-	  a MT7688 (PCIe).
-
-config BOARD_MT7628_RFB
-	bool "MediaTek MT7628 RFB"
-	depends on SOC_MT7628
-	help
-	  The reference design of MT7628. The board has 128 MiB DDR2, 8 MiB
-	  SPI-NOR flash, 1 built-in switch with 5 ports, 1 UART, 1 USB host,
-	  1 SDXC, 1 PCIe socket and JTAG pins.
-
-config BOARD_VOCORE2
-	bool "VoCore2"
-	depends on SOC_MT7628
-	select SPL_SERIAL_SUPPORT
-	select SPL_UART2_SPIS_PINMUX
-	help
-	  VoCore VoCore2 board has a MT7628 SoC with 128 MiB of RAM
-	  and 16 MiB of flash (SPI).
-
-endchoice
-
-config SPL_UART2_SPIS_PINMUX
-	bool "Use alternative pinmux for UART2 in SPL stage"
-	depends on SPL_SERIAL_SUPPORT
-	default n
-	help
-	  Select this if the UART2 of your board is connected to GPIO 16/17
-	  (shared with SPIS) rather than the usual GPIO 20/21.
-
-source "board/gardena/smart-gateway-mt7688/Kconfig"
-source "board/mediatek/mt7628/Kconfig"
-source "board/seeed/linkit-smart-7688/Kconfig"
-source "board/vocore/vocore2/Kconfig"
+source "arch/mips/mach-mtmips/mt7628/Kconfig"
 
 endmenu
diff --git a/arch/mips/mach-mtmips/mt7628/Kconfig b/arch/mips/mach-mtmips/mt7628/Kconfig
new file mode 100644
index 0000000000..e3f56e782e
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/Kconfig
@@ -0,0 +1,53 @@
+
+if SOC_MT7628
+
+choice
+	prompt "Board select"
+
+config BOARD_GARDENA_SMART_GATEWAY_MT7688
+	bool "GARDENA smart Gateway"
+	select BOARD_LATE_INIT
+	help
+	  GARDENA smart Gateway boards have a MT7688 SoC with 128 MiB of RAM
+	  and 8 MiB of flash (SPI NOR) and additional SPI NAND storage.
+
+config BOARD_LINKIT_SMART_7688
+	bool "LinkIt Smart 7688"
+	help
+	  Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM
+	  and 32 MiB of flash (SPI).
+	  Between its different peripherals there's an integrated switch with 4
+	  ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
+	  a MT7688 (PCIe).
+
+config BOARD_MT7628_RFB
+	bool "MediaTek MT7628 RFB"
+	help
+	  The reference design of MT7628. The board has 128 MiB DDR2, 8 MiB
+	  SPI-NOR flash, 1 built-in switch with 5 ports, 1 UART, 1 USB host,
+	  1 SDXC, 1 PCIe socket and JTAG pins.
+
+config BOARD_VOCORE2
+	bool "VoCore2"
+	select SPL_SERIAL_SUPPORT
+	select SPL_UART2_SPIS_PINMUX
+	help
+	  VoCore VoCore2 board has a MT7628 SoC with 128 MiB of RAM
+	  and 16 MiB of flash (SPI).
+
+endchoice
+
+config SPL_UART2_SPIS_PINMUX
+	bool "Use alternative pinmux for UART2 in SPL stage"
+	depends on SPL_SERIAL_SUPPORT
+	default n
+	help
+	  Select this if the UART2 of your board is connected to GPIO 16/17
+	  (shared with SPIS) rather than the usual GPIO 20/21.
+
+source "board/gardena/smart-gateway-mt7688/Kconfig"
+source "board/mediatek/mt7628/Kconfig"
+source "board/seeed/linkit-smart-7688/Kconfig"
+source "board/vocore/vocore2/Kconfig"
+
+endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 03/21] mips: mtmips: select SYSRESET for mt7628 only
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
  2020-10-30  9:33 ` [PATCH v2 01/21] mips: dts: switch to board defines for dtb for mtmips Weijie Gao
  2020-10-30  9:33 ` [PATCH v2 02/21] mips: mtmips: move mt7628 related Kconfig into mt7628 subdirectory Weijie Gao
@ 2020-10-30  9:33 ` Weijie Gao
  2020-10-30  9:33 ` [PATCH v2 04/21] mips: mtmips: fix dram size detection in dram_init Weijie Gao
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:33 UTC (permalink / raw)
  To: u-boot

Currently only mt7628 needs the sysreset driver, do not select it for
mt7620.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: new
---
 arch/mips/Kconfig             | 1 -
 arch/mips/mach-mtmips/Kconfig | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index e0f6b6c4b3..77f563e98e 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -97,7 +97,6 @@ config ARCH_MTMIPS
 	select SUPPORTS_CPU_MIPS32_R1
 	select SUPPORTS_CPU_MIPS32_R2
 	select SUPPORTS_LITTLE_ENDIAN
-	select SYSRESET
 	select SUPPORT_SPL
 
 config ARCH_JZ47XX
diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig
index 7c07430a0c..c383e82a6b 100644
--- a/arch/mips/mach-mtmips/Kconfig
+++ b/arch/mips/mach-mtmips/Kconfig
@@ -43,6 +43,7 @@ config SOC_MT7628
 	select SYS_MIPS_CACHE_INIT_RAM_LOAD
 	select PINCTRL_MT7628
 	select MTK_SERIAL
+	select SYSRESET
 	select SYSRESET_RESETCTL
 	select SPL_SEPARATE_BSS if SPL
 	select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 04/21] mips: mtmips: fix dram size detection in dram_init
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (2 preceding siblings ...)
  2020-10-30  9:33 ` [PATCH v2 03/21] mips: mtmips: select SYSRESET for mt7628 only Weijie Gao
@ 2020-10-30  9:33 ` Weijie Gao
  2020-10-30  9:33 ` [PATCH v2 05/21] mips: enable _machine_restart for spl Weijie Gao
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:33 UTC (permalink / raw)
  To: u-boot

CONFIG_SYS_SDRAM_BASE points to cached memory, i.e. KSEG0, which is not
suitable for detecting memory size.

Replace CONFIG_SYS_SDRAM_BASE with KSEG1, and make dram_init() always do
memory size detection in any stage.

Reviewed-by: Stefan Roese <sr@denx.de>
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 arch/mips/mach-mtmips/cpu.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach-mtmips/cpu.c
index 2ddf8cb096..ca1967055a 100644
--- a/arch/mips/mach-mtmips/cpu.c
+++ b/arch/mips/mach-mtmips/cpu.c
@@ -6,6 +6,7 @@
 #include <common.h>
 #include <init.h>
 #include <malloc.h>
+#include <asm/addrspace.h>
 #include <linux/bitops.h>
 #include <linux/io.h>
 #include <linux/sizes.h>
@@ -14,9 +15,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 int dram_init(void)
 {
-#ifdef CONFIG_SKIP_LOWLEVEL_INIT
-	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);
-#endif
+	gd->ram_size = get_ram_size((void *)KSEG1, SZ_256M);
 
 	return 0;
 }
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 05/21] mips: enable _machine_restart for spl
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (3 preceding siblings ...)
  2020-10-30  9:33 ` [PATCH v2 04/21] mips: mtmips: fix dram size detection in dram_init Weijie Gao
@ 2020-10-30  9:33 ` Weijie Gao
  2020-11-03 15:12   ` Simon Glass
  2020-10-30  9:34 ` [PATCH v2 06/21] mips: mtmips: add support to initialize SDRAM Weijie Gao
                   ` (15 subsequent siblings)
  20 siblings, 1 reply; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:33 UTC (permalink / raw)
  To: u-boot

The sysreset driver has a config CONFIG_SPL_SYSRESET for the spl stage.
Change CONFIG_SYSRESET to CONFIG_IS_ENABLED(SYSRESET) will give spl a
chance to use _machine_restart instead of the sysreset driver.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: new
---
 arch/mips/cpu/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/cpu/cpu.c b/arch/mips/cpu/cpu.c
index 7d5c9fd83a..b304026a67 100644
--- a/arch/mips/cpu/cpu.c
+++ b/arch/mips/cpu/cpu.c
@@ -12,7 +12,7 @@
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
 
-#ifndef CONFIG_SYSRESET
+#if !CONFIG_IS_ENABLED(SYSRESET)
 void __weak _machine_restart(void)
 {
 	fprintf(stderr, "*** reset failed ***\n");
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 06/21] mips: mtmips: add support to initialize SDRAM
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (4 preceding siblings ...)
  2020-10-30  9:33 ` [PATCH v2 05/21] mips: enable _machine_restart for spl Weijie Gao
@ 2020-10-30  9:34 ` Weijie Gao
  2020-10-30  9:34 ` [PATCH v2 07/21] mips: mtmips: add support for MediaTek MT7620 SoC Weijie Gao
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:34 UTC (permalink / raw)
  To: u-boot

This patch adds support for mtmips SoCs to initialize the SDRAM.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 arch/mips/mach-mtmips/ddr_init.c         | 59 ++++++++++++++++++++++++
 arch/mips/mach-mtmips/include/mach/ddr.h |  4 ++
 2 files changed, 63 insertions(+)

diff --git a/arch/mips/mach-mtmips/ddr_init.c b/arch/mips/mach-mtmips/ddr_init.c
index 6c6d0933f2..9c986daea6 100644
--- a/arch/mips/mach-mtmips/ddr_init.c
+++ b/arch/mips/mach-mtmips/ddr_init.c
@@ -15,6 +15,13 @@
 
 #define DDR_BW_TEST_PAT			0xaa5555aa
 
+static const u32 sdr_size_cfg1[] = {
+	[DRAM_8MB] = (1 << NUMROWS_S),
+	[DRAM_16MB] = (1 << NUMROWS_S) | (1 << NUMCOLS_S),
+	[DRAM_32MB] = (2 << NUMROWS_S) | (1 << NUMCOLS_S),
+	[DRAM_64MB] = (2 << NUMROWS_S) | (2 << NUMCOLS_S),
+};
+
 static const u32 dram_size[] = {
 	[DRAM_8MB] = SZ_8M,
 	[DRAM_16MB] = SZ_16M,
@@ -193,3 +200,55 @@ void ddr2_init(struct mc_ddr_init_param *param)
 	param->memsize = dram_size[sz];
 	param->bus_width = bw;
 }
+
+static void mc_sdr_init(void __iomem *memc, mc_reset_t mc_reset, u32 cfg0,
+			u32 cfg1)
+{
+	mc_reset(1);
+	__udelay(200);
+	mc_reset(0);
+
+	writel(cfg0, memc + MEMCTL_SDRAM_CFG0_REG);
+	writel(cfg1, memc + MEMCTL_SDRAM_CFG1_REG);
+
+	while (!(readl(memc + MEMCTL_SDRAM_CFG1_REG) & SDRAM_INIT_DONE))
+		;
+
+	clrsetbits_32(memc + MEMCTL_PWR_SAVE_CNT_REG, SR_TAR_CNT_M,
+		      1 << SR_TAR_CNT_S);
+
+	setbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
+}
+
+void sdr_init(struct mc_ddr_init_param *param)
+{
+	enum mc_dram_size sz;
+	u32 cfg1;
+
+	cfg1 = param->sdr_cfg1 | SDRAM_INIT_START;
+	cfg1 &= ~(NUMCOLS_M | NUMROWS_M);
+
+	/* First initialization, determine SDR capacity */
+	mc_sdr_init(param->memc, param->mc_reset, param->sdr_cfg0,
+		    cfg1 | sdr_size_cfg1[DRAM_64MB]);
+
+	if (dram_addr_test_bit(9)) {
+		sz = DRAM_8MB;
+	} else {
+		if (dram_addr_test_bit(10)) {
+			if (dram_addr_test_bit(23))
+				sz = DRAM_16MB;
+			else
+				sz = DRAM_32MB;
+		} else {
+			sz = DRAM_64MB;
+		}
+	}
+
+	/* Final initialization */
+	mc_sdr_init(param->memc, param->mc_reset, param->sdr_cfg0,
+		    cfg1 | sdr_size_cfg1[sz]);
+
+	/* Return actual DDR configuration */
+	param->memsize = dram_size[sz];
+}
diff --git a/arch/mips/mach-mtmips/include/mach/ddr.h b/arch/mips/mach-mtmips/include/mach/ddr.h
index f92198137b..15ff66ace6 100644
--- a/arch/mips/mach-mtmips/include/mach/ddr.h
+++ b/arch/mips/mach-mtmips/include/mach/ddr.h
@@ -35,6 +35,9 @@ typedef void (*mc_reset_t)(int assert);
 struct mc_ddr_init_param {
 	void __iomem *memc;
 
+	u32 sdr_cfg0;
+	u32 sdr_cfg1;
+
 	u32 dq_dly;
 	u32 dqs_dly;
 
@@ -45,6 +48,7 @@ struct mc_ddr_init_param {
 	u32 bus_width;
 };
 
+void sdr_init(struct mc_ddr_init_param *param);
 void ddr1_init(struct mc_ddr_init_param *param);
 void ddr2_init(struct mc_ddr_init_param *param);
 void ddr_calibrate(void __iomem *memc, u32 memsize, u32 bw);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 07/21] mips: mtmips: add support for MediaTek MT7620 SoC
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (5 preceding siblings ...)
  2020-10-30  9:34 ` [PATCH v2 06/21] mips: mtmips: add support to initialize SDRAM Weijie Gao
@ 2020-10-30  9:34 ` Weijie Gao
  2020-10-30  9:34 ` [PATCH v2 08/21] mips: mtmips: add two reference boards for mt7620 Weijie Gao
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:34 UTC (permalink / raw)
  To: u-boot

This patch adds support for MediaTek MT7620 SoC.
All files are dedicated for u-boot.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: remove use of common.h
---
 arch/mips/dts/mt7620-u-boot.dtsi              |  14 +
 arch/mips/dts/mt7620.dtsi                     | 296 ++++++++++++++++++
 arch/mips/mach-mtmips/Kconfig                 |  18 ++
 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           | 113 +++++++
 arch/mips/mach-mtmips/mt7620/init.c           | 193 ++++++++++++
 arch/mips/mach-mtmips/mt7620/lowlevel_init.S  |  53 ++++
 arch/mips/mach-mtmips/mt7620/mt7620.h         | 103 ++++++
 arch/mips/mach-mtmips/mt7620/serial.c         |  36 +++
 arch/mips/mach-mtmips/mt7620/sysc.c           | 172 ++++++++++
 include/configs/mt7620.h                      |  46 +++
 14 files changed, 1163 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..ed8425719b
--- /dev/null
+++ b/arch/mips/dts/mt7620-u-boot.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+&uartlite {
+	u-boot,dm-pre-reloc;
+};
+
+&uartfull {
+	u-boot,dm-pre-reloc;
+};
diff --git a/arch/mips/dts/mt7620.dtsi b/arch/mips/dts/mt7620.dtsi
new file mode 100644
index 0000000000..03a80b7a70
--- /dev/null
+++ b/arch/mips/dts/mt7620.dtsi
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <dt-bindings/clock/mt7620-clk.h>
+#include <dt-bindings/reset/mt7620-reset.h>
+
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "mediatek,mt7620-soc";
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu at 0 {
+			compatible = "mti,mips24KEc";
+			device_type = "cpu";
+			reg = <0>;
+		};
+	};
+
+	clk48m: clk48m at 0 {
+		compatible = "fixed-clock";
+
+		clock-frequency = <48000000>;
+
+		#clock-cells = <0>;
+	};
+
+	sysc: sysc at 10000000 {
+		compatible = "mediatek,mt7620-sysc";
+		reg = <0x10000000 0x100>;
+	};
+
+	clkctrl: clkctrl at 10000030 {
+		compatible = "mediatek,mt7620-clk";
+		mediatek,sysc = <&sysc>;
+
+		#clock-cells = <1>;
+	};
+
+	rstctrl: rstctrl at 10000034 {
+		compatible = "mediatek,mtmips-reset";
+		reg = <0x10000034 0x4>;
+		#reset-cells = <1>;
+	};
+
+	reboot: resetctl-reboot {
+		compatible = "resetctl-reboot";
+
+		resets = <&rstctrl SYS_RST>;
+		reset-names = "sysreset";
+	};
+
+	uartfull: uartfull at 10000500 {
+		compatible = "mediatek,mt7620-uart";
+		reg = <10000500 0x100>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&uartf_gpio_pins>;
+
+		clocks = <&clkctrl CLK_UARTF>;
+
+		resets = <&rstctrl UARTF_RST>;
+		reset-names = "uartf";
+
+		clock-frequency = <40000000>;
+
+		status = "disabled";
+	};
+
+	uartlite: uartlite at 10000c00 {
+		compatible = "mediatek,mt7620-uart";
+		reg = <0x10000c00 0x100>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&uartl_pins>;
+
+		clocks = <&clkctrl CLK_UARTL>;
+
+		resets = <&rstctrl UARTL_RST>;
+		reset-names = "uartl";
+
+		clock-frequency = <40000000>;
+	};
+
+	pinctrl: pinctrl at 10000060 {
+		compatible = "mediatek,mt7620-pinctrl";
+		reg = <0x10000060 0x4>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&state_default>;
+
+		state_default: pin_state {
+			sutif_pins {
+				groups = "sutif";
+				function = "none";
+			};
+		};
+
+		nand_pins: nand_pins {
+			groups = "nand";
+			function = "nand";
+		};
+
+		sd_pins: sd_pins {
+			groups = "nand";
+			function = "sd";
+		};
+
+		spi_single_pins: spi_single_pins {
+			groups = "spi";
+			function = "spi";
+		};
+
+		spi_dual_pins: spi_dual_pins {
+			spi_master_pins {
+				groups = "spi";
+				function = "spi";
+			};
+
+			spi_cs1_pin {
+				groups = "spi cs1";
+				function = "spi cs1";
+			};
+		};
+
+		uartl_pins: uartl_pins {
+			groups = "uartl";
+			function = "uartl";
+		};
+
+		uartf_pins: uartf_pins {
+			groups = "uartf";
+			function = "uartf";
+		};
+
+		uartf_pcm_pins: uartf_pcm_pins {
+			groups = "uartf";
+			function = "uartf pcm";
+		};
+
+		uartf_i2s_pins: uartf_i2s_pins {
+			groups = "uartf";
+			function = "i2s uartf";
+		};
+
+		uartf_gpio_pins: uartf_gpio_pins {
+			groups = "uartf";
+			function = "uartf gpio";
+		};
+	};
+
+	watchdog: watchdog at 10000120 {
+		compatible = "mediatek,mt7620-wdt";
+		reg = <0x10000120 0x10>;
+
+		resets = <&rstctrl TIMER_RST>;
+		reset-names = "wdt";
+	};
+
+	gpio0: gpio0 at 10000600 {
+		compatible = "mediatek,mt7620-gpio";
+		reg = <0x10000600 0x34>;
+
+		resets = <&rstctrl PIO_RST>;
+		reset-names = "pio";
+
+		mediatek,bank-name = "PIOA";
+		mediatek,gpio-num = <24>;
+		mediatek,register-map = <0x20 0x24 0x2c 0x30>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpio1: gpio1 at 10000638 {
+		compatible = "mediatek,mt7620-gpio";
+		reg = <0x10000638 0x24>;
+
+		resets = <&rstctrl PIO_RST>;
+		reset-names = "pio";
+
+		mediatek,bank-name = "PIOB";
+		mediatek,gpio-num = <16>;
+		mediatek,register-map = <0x10 0x14 0x1c 0x20>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpio2: gpio2 at 10000660 {
+		compatible = "mediatek,mt7620-gpio";
+		reg = <0x10000660 0x24>;
+
+		resets = <&rstctrl PIO_RST>;
+		reset-names = "pio";
+
+		mediatek,bank-name = "PIOC";
+		mediatek,gpio-num = <32>;
+		mediatek,register-map = <0x10 0x14 0x1c 0x20>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	gpio3: gpio3 at 10000688 {
+		compatible = "mediatek,mt7620-gpio";
+		reg = <0x10000688 0x24>;
+
+		resets = <&rstctrl PIO_RST>;
+		reset-names = "pio";
+
+		mediatek,bank-name = "PIOD";
+		mediatek,gpio-num = <1>;
+		mediatek,register-map = <0x10 0x14 0x1c 0x20>;
+
+		gpio-controller;
+		#gpio-cells = <2>;
+	};
+
+	spi0: spi at 10000b00 {
+		compatible = "mediatek,mt7620-spi";
+		reg = <0x10000b00 0x100>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&spi_single_pins>;
+
+		resets = <&rstctrl SPI_RST>;
+		reset-names = "spi";
+
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		clocks = <&clkctrl CLK_SPI>;
+	};
+
+	eth: eth at 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 at 101c0000 {
+		compatible = "generic-ehci";
+		reg = <0x101c0000 0x1000>;
+
+		phys = <&usb_phy>;
+		phy-names = "usb";
+	};
+
+	mmc: mmc at 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 c383e82a6b..8756cadb0b 100644
--- a/arch/mips/mach-mtmips/Kconfig
+++ b/arch/mips/mach-mtmips/Kconfig
@@ -5,6 +5,7 @@ config SYS_MALLOC_F_LEN
 	default 0x1000
 
 config SYS_SOC
+	default "mt7620" if SOC_MT7620
 	default "mt7628" if SOC_MT7628
 
 config SYS_DCACHE_SIZE
@@ -31,10 +32,26 @@ config SPL_PAYLOAD
 
 config BUILD_TARGET
 	default "u-boot-with-spl.bin" if SPL
+	default "u-boot.bin"
 
 choice
 	prompt "MediaTek MIPS SoC select"
 
+config SOC_MT7620
+	bool "MT7620"
+	select MIPS_L1_CACHE_SHIFT_5
+	select SYS_MIPS_CACHE_INIT_RAM_LOAD
+	select PINCTRL_MT7620
+	select MT7620_SERIAL
+	select MISC
+	select SPL_SEPARATE_BSS if SPL
+	select SPL_LOADER_SUPPORT if SPL
+	select SPL_OF_CONTROL if SPL_DM
+	select SPL_OF_PLATDATA if SPL_DM
+	select SPL_DM_SERIAL if SPL_DM
+	help
+	  This supports MediaTek MT7620.
+
 config SOC_MT7628
 	bool "MT7628"
 	select MIPS_L1_CACHE_SHIFT_5
@@ -59,6 +76,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..0f0e64bf5e
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/dram.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <asm/addrspace.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/sizes.h>
+#include <linux/io.h>
+#include <mach/ddr.h>
+#include <mach/mc.h>
+#include "mt7620.h"
+
+/* SDR parameters */
+#define SDR_CFG0_VAL		0x51B283B3
+#define SDR_CFG1_VAL		0xC00003A9
+
+/* DDR2 DQ_DLY */
+#define DDR2_DQ_DLY		0x88888888
+
+/* DDR2 DQS_DLY */
+#define DDR2_DQS_DLY		0x88888888
+
+static const struct mc_ddr_cfg ddr1_cfgs_200mhz[] = {
+	[DRAM_8MB]   = { 0x34A1EB94, 0x20262324, 0x28000033, 0x00000002, 0x00000000 },
+	[DRAM_16MB]  = { 0x34A1EB94, 0x202A2324, 0x28000033, 0x00000002, 0x00000000 },
+	[DRAM_32MB]  = { 0x34A1E5CA, 0x202E2324, 0x28000033, 0x00000002, 0x00000000 },
+	[DRAM_64MB]  = { 0x3421E5CA, 0x20322324, 0x28000033, 0x00000002, 0x00000000 },
+	[DRAM_128MB] = { 0x241B05CA, 0x20362334, 0x28000033, 0x00000002, 0x00000000 },
+};
+
+static const struct mc_ddr_cfg ddr1_cfgs_160mhz[] = {
+	[DRAM_8MB]   = { 0x239964A1, 0x20262323, 0x00000033, 0x00000002, 0x00000000 },
+	[DRAM_16MB]  = { 0x239964A1, 0x202A2323, 0x00000033, 0x00000002, 0x00000000 },
+	[DRAM_32MB]  = { 0x239964A1, 0x202E2323, 0x00000033, 0x00000002, 0x00000000 },
+	[DRAM_64MB]  = { 0x239984A1, 0x20322323, 0x00000033, 0x00000002, 0x00000000 },
+	[DRAM_128MB] = { 0x239AB4A1, 0x20362333, 0x00000033, 0x00000002, 0x00000000 },
+};
+
+static const struct mc_ddr_cfg ddr2_cfgs_200mhz[] = {
+	[DRAM_32MB]  = { 0x2519E2E5, 0x222E2323, 0x68000C43, 0x00000416, 0x0000000A },
+	[DRAM_64MB]  = { 0x249AA2E5, 0x22322323, 0x68000C43, 0x00000416, 0x0000000A },
+	[DRAM_128MB] = { 0x249B42E5, 0x22362323, 0x68000C43, 0x00000416, 0x0000000A },
+	[DRAM_256MB] = { 0x249CE2E5, 0x223A2323, 0x68000C43, 0x00000416, 0x0000000A },
+};
+
+static const struct mc_ddr_cfg ddr2_cfgs_160mhz[] = {
+	[DRAM_32MB]  = { 0x23918250, 0x222E2322, 0x40000A43, 0x00000416, 0x00000006 },
+	[DRAM_64MB]  = { 0x239A2250, 0x22322322, 0x40000A43, 0x00000416, 0x00000008 },
+	[DRAM_128MB] = { 0x2392A250, 0x22362322, 0x40000A43, 0x00000416, 0x00000008 },
+	[DRAM_256MB] = { 0x24140250, 0x223A2322, 0x40000A43, 0x00000416, 0x00000008 },
+};
+
+static void mt7620_memc_reset(int assert)
+{
+	void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+	if (assert)
+		setbits_32(sysc + SYSCTL_RSTCTL_REG, MC_RST);
+	else
+		clrbits_32(sysc + SYSCTL_RSTCTL_REG, MC_RST);
+}
+
+void mt7620_dram_init(void)
+{
+	void __iomem *sysc;
+	bool lspd = false;
+	int ddr_type, aux;
+	struct mc_ddr_init_param param;
+
+	sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+	ddr_type = (readl(sysc + SYSCTL_SYSCFG0_REG) & DRAM_TYPE_M)
+		   >> DRAM_TYPE_S;
+	aux = readl(sysc + SYSCTL_CPLL_CFG1_REG) &
+	      (CPU_CLK_AUX1 | CPU_CLK_AUX0);
+
+	if (aux == CPU_CLK_AUX1 || aux == CPU_CLK_AUX0)
+		lspd = true;
+
+	mt7620_memc_reset(1);
+	__udelay(200);
+
+	param.memc = ioremap_nocache(MEMCTL_BASE, MEMCTL_SIZE);
+	param.dq_dly = DDR2_DQ_DLY;
+	param.dqs_dly = DDR2_DQS_DLY;
+	param.mc_reset = mt7620_memc_reset;
+	param.memsize = 0;
+	param.bus_width = 0;
+
+	if (ddr_type == DRAM_DDR1) {
+		if (lspd)
+			param.cfgs = ddr1_cfgs_160mhz;
+		else
+			param.cfgs = ddr1_cfgs_200mhz;
+
+		ddr1_init(&param);
+	} else if (ddr_type == DRAM_DDR2) {
+		if (lspd)
+			param.cfgs = ddr2_cfgs_160mhz;
+		else
+			param.cfgs = ddr2_cfgs_200mhz;
+
+		ddr2_init(&param);
+	} else {
+		param.sdr_cfg0 = SDR_CFG0_VAL;
+		param.sdr_cfg1 = SDR_CFG1_VAL;
+
+		sdr_init(&param);
+	}
+}
diff --git a/arch/mips/mach-mtmips/mt7620/init.c b/arch/mips/mach-mtmips/mt7620/init.c
new file mode 100644
index 0000000000..93abf9228d
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/init.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <config.h>
+#include <asm/global_data.h>
+#include <linux/io.h>
+#include "mt7620.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const char * const dram_type[] = {
+	"SDRAM", "DDR", "DDR2", "SDRAM"
+};
+
+static const char * const boot_mode[(CHIP_MODE_M >> CHIP_MODE_S) + 1] = {
+	[1] = "NAND 4-cycles 2KB-page",
+	[2] = "SPI-NOR 3-Byte Addr",
+	[3] = "SPI-NOR 4-Byte Addr",
+	[10] = "NAND 4-cycles 512B-page",
+	[11] = "NAND 5-cycles 2KB-page",
+	[12] = "NAND 3-cycles 512B-page",
+};
+
+static void cpu_pll_init(void)
+{
+	void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+	u32 pllmul = CONFIG_CPU_FREQ_MULTI;
+
+	/* Make sure the pll multiplier is valid */
+	if (pllmul > 7)
+		pllmul = 7;
+
+	/* Set init CPU clock to 480MHz */
+	clrsetbits_32(sysc + SYSCTL_CPLL_CFG1_REG, CPU_CLK_AUX1, CPU_CLK_AUX0);
+
+	/* Enable software control of CPU PLL */
+	setbits_32(sysc + SYSCTL_CPLL_CFG0_REG, CPLL_SW_CFG);
+
+	/* CPU PLL power down */
+	setbits_32(sysc + SYSCTL_CPLL_CFG1_REG, CPLL_PD);
+
+	/* PLL configuration */
+	clrsetbits_32(sysc + SYSCTL_CPLL_CFG0_REG, PLL_MULT_RATIO_M |
+		      PLL_DIV_RATIO_M | SSC_UP_BOUND_M | SSC_EN,
+		      (pllmul << PLL_MULT_RATIO_S) | SSC_SWING_M);
+
+	/* CPU PLL power up */
+	clrbits_32(sysc + SYSCTL_CPLL_CFG1_REG, CPLL_PD);
+
+	/* Wait for CPU PLL locked */
+	while (!(readl(sysc + SYSCTL_CPLL_CFG1_REG) & CPLL_LD))
+		;
+
+	/* Set final CPU clock source */
+	clrbits_32(sysc + SYSCTL_CPLL_CFG1_REG, CPU_CLK_AUX1 | CPU_CLK_AUX0);
+
+	/* Adjust CPU clock */
+	clrsetbits_32(sysc + SYSCTL_CPU_SYS_CLKCFG_REG,
+		      CPU_FDIV_M | CPU_FFRAC_M,
+		      (1 << CPU_FDIV_S) | (1 << CPU_FFRAC_S));
+}
+
+void mt7620_init(void)
+{
+	u32 cpu_clk;
+
+	cpu_pll_init();
+
+	/*
+	 * Set timer freq, which will be used during DRAM initialization
+	 * Note that this function is using a temporary gd which will be
+	 * destroyed after leaving this function.
+	 */
+	mt7620_get_clks(&cpu_clk, NULL, NULL);
+	gd->arch.timer_freq = cpu_clk / 2;
+
+	mt7620_dram_init();
+}
+
+void mt7620_get_clks(u32 *cpu_clk, u32 *sys_clk, u32 *xtal_clk)
+{
+	void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+	u32 val, multi, div, fdiv, ffrac, dram_type, sys_div;
+	u32 cpu_freq, xtal_freq;
+
+	static const u32 div_ratio_table[] = {2, 3, 4, 8};
+
+	val = readl(sysc + SYSCTL_SYSCFG0_REG);
+
+	dram_type = (val & DRAM_TYPE_M) >> DRAM_TYPE_S;
+
+	if (val & XTAL_FREQ_SEL)
+		xtal_freq = 40000000;
+	else
+		xtal_freq = 20000000;
+
+	val = readl(sysc + SYSCTL_CPLL_CFG1_REG);
+	if (val & CPU_CLK_AUX1) {
+		cpu_freq = xtal_freq;
+	} else if (val & CPU_CLK_AUX0) {
+		cpu_freq = 480000000;
+	} else {
+		val = readl(sysc + SYSCTL_CPLL_CFG0_REG);
+		if (val & CPLL_SW_CFG) {
+			multi = (val & PLL_MULT_RATIO_M) >> PLL_MULT_RATIO_S;
+			div = (val & PLL_DIV_RATIO_M) >> PLL_DIV_RATIO_S;
+			cpu_freq = (multi + 24) * 40000000 /
+					div_ratio_table[div];
+		} else {
+			cpu_freq = 600000000;
+		}
+	}
+
+	val = readl(sysc + SYSCTL_CUR_CLK_STS_REG);
+	ffrac = (val & CUR_CPU_FFRAC_M) >> CUR_CPU_FFRAC_S;
+	fdiv = (val & CUR_CPU_FDIV_M) >> CUR_CPU_FDIV_S;
+	cpu_freq = (cpu_freq * ffrac) / fdiv;
+
+	switch (dram_type) {
+	case DRAM_SDRAM_E1:
+		sys_div = 4;
+		break;
+	case DRAM_DDR1:
+	case DRAM_DDR2:
+		sys_div = 3;
+		break;
+	case DRAM_SDRAM:
+		sys_div = 5;
+		break;
+	}
+
+	if (cpu_clk)
+		*cpu_clk = cpu_freq;
+
+	if (sys_clk)
+		*sys_clk = cpu_freq / sys_div;
+
+	if (xtal_clk)
+		*xtal_clk = xtal_freq;
+}
+
+int print_cpuinfo(void)
+{
+	void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+	u32 cpu_clk, bus_clk, xtal_clk;
+	u32 val, ver, eco, pkg, dram, chipmode;
+	const char *bootdev;
+
+	val = readl(sysc + SYSCTL_CHIP_REV_ID_REG);
+	ver = (val & VER_M) >> VER_S;
+	eco = (val & ECO_M) >> ECO_S;
+	pkg = !!(val & PKG_ID);
+
+	val = readl(sysc + SYSCTL_SYSCFG0_REG);
+	dram = (val & DRAM_TYPE_M) >> DRAM_TYPE_S;
+	chipmode = (val & CHIP_MODE_M) >> CHIP_MODE_S;
+
+	bootdev = boot_mode[chipmode];
+	if (!bootdev)
+		bootdev = "Unsupported boot mode";
+
+	printf("CPU:   MediaTek MT7620%c ver:%u eco:%u\n",
+	       pkg ? 'A' : 'N', ver, eco);
+
+	printf("Boot:  %s, %s\n", dram_type[dram], bootdev);
+
+	mt7620_get_clks(&cpu_clk, &bus_clk, &xtal_clk);
+
+	/* Set final timer frequency */
+	gd->arch.timer_freq = cpu_clk / 2;
+
+	printf("Clock: CPU: %uMHz, Bus: %uMHz, XTAL: %uMHz\n",
+	       cpu_clk / 1000000, bus_clk / 1000000, xtal_clk / 1000000);
+
+	return 0;
+}
+
+ulong notrace get_tbclk(void)
+{
+	return gd->arch.timer_freq;
+}
+
+void _machine_restart(void)
+{
+	void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+	while (1)
+		writel(SYS_RST, sysc + SYSCTL_RSTCTL_REG);
+}
diff --git a/arch/mips/mach-mtmips/mt7620/lowlevel_init.S b/arch/mips/mach-mtmips/mt7620/lowlevel_init.S
new file mode 100644
index 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..dd5e6d00e5
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/mt7620.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MT7620_H_
+#define _MT7620_H_
+
+#include <linux/bitops.h>
+
+#define SYSCTL_BASE			0x10000000
+#define SYSCTL_SIZE			0x100
+#define MEMCTL_BASE			0x10000300
+#define MEMCTL_SIZE			0x100
+#define UARTFULL_BASE			0x10000500
+#define UARTFULL_SIZE			0x100
+#define UARTLITE_BASE			0x10000c00
+#define UARTLITE_SIZE			0x100
+
+#define SYSCTL_CHIP_REV_ID_REG		0x0c
+#define PKG_ID				BIT(16)
+#define   PKG_ID_A			1
+#define   PKG_ID_N			0
+#define VER_S				8
+#define VER_M				GENMASK(11, 8)
+#define ECO_S				0
+#define ECO_M				GENMASK(3, 0)
+
+#define SYSCTL_SYSCFG0_REG		0x10
+#define XTAL_FREQ_SEL			BIT(6)
+#define   XTAL_40MHZ			1
+#define   XTAL_20MHZ			0
+#define DRAM_TYPE_S			4
+#define DRAM_TYPE_M			GENMASK(5, 4)
+#define   DRAM_SDRAM			3
+#define   DRAM_DDR2			2
+#define   DRAM_DDR1			1
+#define   DRAM_SDRAM_E1			0
+#define CHIP_MODE_S			0
+#define CHIP_MODE_M			GENMASK(3, 0)
+
+#define SYSCTL_SYSCFG1_REG		0x14
+#define GE2_MODE_S			14
+#define GE2_MODE_M			GENMASK(15, 14)
+#define GE1_MODE_S			12
+#define GE1_MODE_M			GENMASK(13, 12)
+#define USB0_HOST_MODE			BIT(10)
+#define PCIE_RC_MODE			BIT(8)
+#define GE_MODE_M			GENMASK(1, 0)
+
+#define SYSCTL_RSTCTL_REG		0x34
+#define MC_RST				BIT(10)
+#define SYS_RST				BIT(0)
+
+#define SYSCTL_CLKCFG0_REG		0x2c
+#define PERI_CLK_SEL			BIT(4)
+
+#define SYSCTL_CPU_SYS_CLKCFG_REG	0x3c
+#define CPU_OCP_RATIO_S			16
+#define CPU_OCP_RATIO_M			GENMASK(19, 16)
+#define CPU_FDIV_S			8
+#define CPU_FDIV_M			GENMASK(12, 8)
+#define CPU_FFRAC_S			0
+#define CPU_FFRAC_M			GENMASK(4, 0)
+
+#define SYSCTL_CUR_CLK_STS_REG		0x44
+#define CUR_CPU_OCP_RATIO_S		16
+#define CUR_CPU_OCP_RATIO_M		GENMASK(19, 16)
+#define CUR_CPU_FDIV_S			8
+#define CUR_CPU_FDIV_M			GENMASK(12, 8)
+#define CUR_CPU_FFRAC_S			0
+#define CUR_CPU_FFRAC_M			GENMASK(4, 0)
+
+#define SYSCTL_CPLL_CFG0_REG		0x54
+#define CPLL_SW_CFG			BIT(31)
+#define PLL_MULT_RATIO_S		16
+#define PLL_MULT_RATIO_M		GENMASK(18, 16)
+#define PLL_DIV_RATIO_S			10
+#define PLL_DIV_RATIO_M			GENMASK(11, 10)
+#define SSC_UP_BOUND_S			8
+#define SSC_UP_BOUND_M			GENMASK(9, 8)
+#define SSC_EN				BIT(7)
+#define SSC_SWING_S			4
+#define SSC_SWING_M			GENMASK(6, 4)
+
+#define SYSCTL_CPLL_CFG1_REG		0x58
+#define CPLL_PD				BIT(26)
+#define CPU_CLK_AUX1			BIT(25)
+#define CPU_CLK_AUX0			BIT(24)
+#define CPLL_LD				BIT(23)
+
+#define SYSCTL_GPIOMODE_REG		0x60
+#define UARTL_GPIO_MODE			BIT(5)
+#define UARTF_SHARE_MODE_S		2
+#define UARTF_SHARE_MODE_M		GENMASK(4, 2)
+#define   UARTF_MODE_UARTF_GPIO		5
+
+void mt7620_dram_init(void);
+void mt7620_get_clks(u32 *cpu_clk, u32 *sys_clk, u32 *xtal_clk);
+
+#endif /* _MT7620_H_ */
diff --git a/arch/mips/mach-mtmips/mt7620/serial.c b/arch/mips/mach-mtmips/mt7620/serial.c
new file mode 100644
index 0000000000..44f061cd6c
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/serial.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include "mt7620.h"
+
+void board_debug_uart_init(void)
+{
+	void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+#if CONFIG_DEBUG_UART_BASE == 0xb0000500 /* KSEG1ADDR(UARTFULL_BASE) */
+	clrsetbits_32(base + SYSCTL_GPIOMODE_REG, UARTF_SHARE_MODE_M,
+		      UARTF_MODE_UARTF_GPIO << UARTF_SHARE_MODE_S);
+#else
+	clrbits_32(base + SYSCTL_GPIOMODE_REG, UARTL_GPIO_MODE);
+#endif
+}
+
+void mtmips_spl_serial_init(void)
+{
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+	void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+#if CONFIG_CONS_INDEX == 1
+	clrbits_32(base + SYSCTL_GPIOMODE_REG, UARTL_GPIO_MODE);
+#elif CONFIG_CONS_INDEX == 2
+	clrsetbits_32(base + SYSCTL_GPIOMODE_REG, UARTF_SHARE_MODE_M,
+		      UARTF_MODE_UARTF_GPIO << UARTF_SHARE_MODE_S);
+#endif
+#endif /* CONFIG_SPL_SERIAL_SUPPORT */
+}
diff --git a/arch/mips/mach-mtmips/mt7620/sysc.c b/arch/mips/mach-mtmips/mt7620/sysc.c
new file mode 100644
index 0000000000..4de01b72be
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7620/sysc.c
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ *
+ * Misc driver for manipulating System control registers
+ */
+
+#include <dm.h>
+#include <misc.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <dm/device_compat.h>
+#include <mach/mt7620-sysc.h>
+#include "mt7620.h"
+
+struct mt7620_sysc_priv {
+	void __iomem *base;
+};
+
+static int mt7620_sysc_read(struct udevice *dev, int offset, void *buf,
+			    int size)
+{
+	struct mt7620_sysc_priv *priv = dev_get_priv(dev);
+	u32 val;
+
+	if (offset % sizeof(u32) || size != sizeof(u32) ||
+	    offset >= SYSCTL_SIZE)
+		return -EINVAL;
+
+	val = readl(priv->base + offset);
+
+	if (buf)
+		*(u32 *)buf = val;
+
+	return 0;
+}
+
+static int mt7620_sysc_write(struct udevice *dev, int offset, const void *buf,
+			     int size)
+{
+	struct mt7620_sysc_priv *priv = dev_get_priv(dev);
+	u32 val;
+
+	if (offset % sizeof(u32) || size != sizeof(u32) ||
+	    offset >= SYSCTL_SIZE || !buf)
+		return -EINVAL;
+
+	val = *(u32 *)buf;
+	writel(val, priv->base + offset);
+
+	return 0;
+}
+
+static int mt7620_sysc_ioctl(struct udevice *dev, unsigned long request,
+			     void *buf)
+{
+	struct mt7620_sysc_priv *priv = dev_get_priv(dev);
+	struct mt7620_sysc_chip_rev *chip_rev;
+	struct mt7620_sysc_clks *clks;
+	u32 val, shift;
+
+	if (!buf)
+		return -EINVAL;
+
+	switch (request) {
+	case MT7620_SYSC_IOCTL_GET_CLK:
+		clks = buf;
+		mt7620_get_clks(&clks->cpu_clk, &clks->sys_clk,
+				&clks->xtal_clk);
+
+		val = readl(priv->base + SYSCTL_CLKCFG0_REG);
+		if (val & PERI_CLK_SEL)
+			clks->peri_clk = clks->xtal_clk;
+		else
+			clks->peri_clk = 40000000;
+
+		return 0;
+
+	case MT7620_SYSC_IOCTL_GET_CHIP_REV:
+		chip_rev = buf;
+
+		val = readl(priv->base + SYSCTL_CHIP_REV_ID_REG);
+
+		chip_rev->bga = !!(val & PKG_ID);
+		chip_rev->ver = (val & VER_M) >> VER_S;
+		chip_rev->eco = (val & ECO_M) >> ECO_S;
+
+		return 0;
+
+	case MT7620_SYSC_IOCTL_SET_GE1_MODE:
+	case MT7620_SYSC_IOCTL_SET_GE2_MODE:
+		val = *(u32 *)buf;
+
+		if (val > MT7620_SYSC_GE_ESW_PHY)
+			return -EINVAL;
+
+		if (request == MT7620_SYSC_IOCTL_SET_GE1_MODE)
+			shift = GE1_MODE_S;
+		else
+			shift = GE2_MODE_S;
+
+		clrsetbits_32(priv->base + SYSCTL_SYSCFG1_REG,
+			      GE_MODE_M << shift, val << shift);
+
+		return 0;
+
+	case MT7620_SYSC_IOCTL_SET_USB_MODE:
+		val = *(u32 *)buf;
+
+		if (val == MT7620_SYSC_USB_DEVICE_MODE)
+			val = 0;
+		else if (val == MT7620_SYSC_USB_HOST_MODE)
+			val = USB0_HOST_MODE;
+
+		clrsetbits_32(priv->base + SYSCTL_SYSCFG1_REG,
+			      USB0_HOST_MODE, val);
+
+		return 0;
+
+	case MT7620_SYSC_IOCTL_SET_PCIE_MODE:
+		val = *(u32 *)buf;
+
+		if (val == MT7620_SYSC_PCIE_EP_MODE)
+			val = 0;
+		else if (val == MT7620_SYSC_PCIE_RC_MODE)
+			val = PCIE_RC_MODE;
+
+		clrsetbits_32(priv->base + SYSCTL_SYSCFG1_REG,
+			      PCIE_RC_MODE, val);
+
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mt7620_sysc_probe(struct udevice *dev)
+{
+	struct mt7620_sysc_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_remap_addr_index(dev, 0);
+	if (!priv->base) {
+		dev_err(dev, "failed to map sysc registers\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct misc_ops mt7620_sysc_ops = {
+	.read = mt7620_sysc_read,
+	.write = mt7620_sysc_write,
+	.ioctl = mt7620_sysc_ioctl,
+};
+
+static const struct udevice_id mt7620_sysc_ids[] = {
+	{ .compatible = "mediatek,mt7620-sysc" },
+	{ }
+};
+
+U_BOOT_DRIVER(mt7620_sysc) = {
+	.name		= "mt7620_sysc",
+	.id		= UCLASS_MISC,
+	.of_match	= mt7620_sysc_ids,
+	.probe		= mt7620_sysc_probe,
+	.ops		= &mt7620_sysc_ops,
+	.priv_auto_alloc_size = sizeof(struct mt7620_sysc_priv),
+	.flags = DM_FLAG_PRE_RELOC,
+};
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

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 08/21] mips: mtmips: add two reference boards for mt7620
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (6 preceding siblings ...)
  2020-10-30  9:34 ` [PATCH v2 07/21] mips: mtmips: add support for MediaTek MT7620 SoC Weijie Gao
@ 2020-10-30  9:34 ` Weijie Gao
  2020-10-30  9:34 ` [PATCH v2 09/21] configs: mtmips: refresh for mt7628 based boards Weijie Gao
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:34 UTC (permalink / raw)
  To: u-boot

The mt7620_rfb board supports integrated 10/100M PHYs plus two external
giga PHYs. It also has 8MB SPI-NOR, mini PCI-e x1 slot, SDHC and USB.

The mt7620_mt7530_rfb boards supports an external MT7530 giga switch and a
16MB SPI-NOR flash.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: remove use of common.h
---
 arch/mips/dts/Makefile                       |   2 +
 arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts | 100 +++++++++++++++++++
 arch/mips/dts/mediatek,mt7620-rfb.dts        |  97 ++++++++++++++++++
 arch/mips/mach-mtmips/mt7620/Kconfig         |  17 ++++
 board/mediatek/mt7620/Kconfig                |  12 +++
 board/mediatek/mt7620/MAINTAINERS            |   9 ++
 board/mediatek/mt7620/Makefile               |   3 +
 board/mediatek/mt7620/board.c                |   6 ++
 configs/mt7620_mt7530_rfb_defconfig          |  58 +++++++++++
 configs/mt7620_rfb_defconfig                 |  76 ++++++++++++++
 10 files changed, 380 insertions(+)
 create mode 100644 arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts
 create mode 100644 arch/mips/dts/mediatek,mt7620-rfb.dts
 create mode 100644 board/mediatek/mt7620/Kconfig
 create mode 100644 board/mediatek/mt7620/MAINTAINERS
 create mode 100644 board/mediatek/mt7620/Makefile
 create mode 100644 board/mediatek/mt7620/board.c
 create mode 100644 configs/mt7620_mt7530_rfb_defconfig
 create mode 100644 configs/mt7620_rfb_defconfig

diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index e82f96d4e4..7c42923134 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -14,6 +14,8 @@ dtb-$(CONFIG_BOARD_COMTREND_CT5361) += comtrend,ct-5361.dtb
 dtb-$(CONFIG_BOARD_COMTREND_VR3032U) += comtrend,vr-3032u.dtb
 dtb-$(CONFIG_BOARD_COMTREND_WAP5813N) += comtrend,wap-5813n.dtb
 dtb-$(CONFIG_BOARD_HUAWEI_HG556A) += huawei,hg556a.dtb
+dtb-$(CONFIG_BOARD_MT7620_RFB) += mediatek,mt7620-rfb.dtb
+dtb-$(CONFIG_BOARD_MT7620_MT7530_RFB) += mediatek,mt7620-mt7530-rfb.dtb
 dtb-$(CONFIG_BOARD_MT7628_RFB) += mediatek,mt7628-rfb.dtb
 dtb-$(CONFIG_BOARD_GARDENA_SMART_GATEWAY_MT7688) += gardena-smart-gateway-mt7688.dtb
 dtb-$(CONFIG_BOARD_LINKIT_SMART_7688) += linkit-smart-7688.dtb
diff --git a/arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts b/arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts
new file mode 100644
index 0000000000..8bc3b1673a
--- /dev/null
+++ b/arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "mt7620.dtsi"
+
+/ {
+	compatible = "mediatek,mt7620-mt7530-rfb", "mediatek,mt7620-soc";
+	model = "MediaTek MT7620-MT7530 RFB (MTKC712)";
+
+	aliases {
+		serial0 = &uartlite;
+		spi0 = &spi0;
+	};
+
+	chosen {
+		stdout-path = &uartlite;
+	};
+};
+
+&uartlite {
+	status = "okay";
+};
+
+&pinctrl {
+	state_default: pin_state {
+		pleds {
+			groups = "ephy led", "wled";
+			function = "led";
+		};
+
+		gpios {
+			groups = "pa", "uartf";
+			function = "gpio";
+		};
+	};
+
+	gsw_pins: gsw_pins {
+		mdio {
+			groups = "mdio";
+			function = "mdio";
+		};
+
+		rgmii1 {
+			groups = "rgmii1";
+			function = "rgmii1";
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+	num-cs = <2>;
+
+	spi-flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <25000000>;
+		reg = <0>;
+	};
+};
+
+&gpio0 {
+	pa0_pull_low {
+		gpio-hog;
+		output-low;
+		gpios = <20 GPIO_ACTIVE_HIGH>;
+	};
+
+	pa1_pull_low {
+		gpio-hog;
+		output-low;
+		gpios = <21 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&eth {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&gsw_pins>;
+
+	port5 {
+		phy-mode = "rgmii";
+		phy-addr = <5>;
+		fixed-link {
+			full-duplex;
+			speed = <1000>;
+			mediatek,mt7530;
+			mediatek,mt7530-reset = <&gpio0 10 GPIO_ACTIVE_HIGH>;
+		};
+	};
+};
diff --git a/arch/mips/dts/mediatek,mt7620-rfb.dts b/arch/mips/dts/mediatek,mt7620-rfb.dts
new file mode 100644
index 0000000000..616903e554
--- /dev/null
+++ b/arch/mips/dts/mediatek,mt7620-rfb.dts
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/gpio/gpio.h>
+#include "mt7620.dtsi"
+
+/ {
+	compatible = "mediatek,mt7620-rfb", "mediatek,mt7620-soc";
+	model = "MediaTek MT7620 RFB (WS2120)";
+
+	aliases {
+		serial0 = &uartlite;
+		spi0 = &spi0;
+	};
+
+	chosen {
+		stdout-path = &uartlite;
+	};
+};
+
+&uartlite {
+	status = "okay";
+};
+
+&pinctrl {
+	state_default: pin_state {
+		pleds {
+			groups = "ephy led", "wled";
+			function = "led";
+		};
+
+		gpios {
+			groups = "uartf";
+			function = "gpio";
+		};
+	};
+
+	gsw_pins: gsw_pins {
+		mdio {
+			groups = "mdio";
+			function = "mdio";
+		};
+
+		rgmii1 {
+			groups = "rgmii1";
+			function = "rgmii1";
+		};
+
+		rgmii2 {
+			groups = "rgmii2";
+			function = "rgmii2";
+		};
+	};
+};
+
+&spi0 {
+	status = "okay";
+	num-cs = <2>;
+
+	spi-flash at 0 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "jedec,spi-nor";
+		spi-max-frequency = <25000000>;
+		reg = <0>;
+	};
+};
+
+&eth {
+	status = "okay";
+
+	pinctrl-names = "default";
+	pinctrl-0 = <&gsw_pins>;
+
+	port4 {
+		phy-mode = "rgmii";
+		phy-addr = <4>;
+	};
+
+	port5 {
+		phy-mode = "rgmii";
+		phy-addr = <5>;
+	};
+};
+
+&mmc {
+	bus-width = <4>;
+	cap-sd-highspeed;
+
+	status = "okay";
+};
diff --git a/arch/mips/mach-mtmips/mt7620/Kconfig b/arch/mips/mach-mtmips/mt7620/Kconfig
index aa7cf1d3c1..5db83eb9d9 100644
--- a/arch/mips/mach-mtmips/mt7620/Kconfig
+++ b/arch/mips/mach-mtmips/mt7620/Kconfig
@@ -7,6 +7,21 @@ config DEBUG_UART_BOARD_INIT
 choice
 	prompt "Board select"
 
+config BOARD_MT7620_RFB
+	bool "MediaTek MT7620 RFB"
+	help
+	  The reference design of MT7620A (WS2120). The board has 64 MiB DDR2,
+	  8 MiB SPI-NOR flash, 1 built-in 6 port switch (two GE PHYs and five
+	  FE PHYs,one port can be configured to use either FE PHY or GE PHY),
+	  1 UART, 1 USB host, 1 SDXC, 1 PCIe socket and JTAG pins.
+
+config BOARD_MT7620_MT7530_RFB
+	bool "MediaTek MT7620-MT7530 RFB"
+	help
+	  The reference design of MT7620DA (MTKC712). The board has 64 MiB
+	  intergrated DDR2 KGD, 16 MiB SPI-NOR flash, an external 5-port giga
+	  switch MT7530 and 1 UART.
+
 endchoice
 
 choice
@@ -51,4 +66,6 @@ config CPU_FREQ_MULTI
 	default 6 if CPU_FREQ_600MHZ
 	default 7 if CPU_FREQ_620MHZ
 
+source "board/mediatek/mt7620/Kconfig"
+
 endif
diff --git a/board/mediatek/mt7620/Kconfig b/board/mediatek/mt7620/Kconfig
new file mode 100644
index 0000000000..b9137adcc9
--- /dev/null
+++ b/board/mediatek/mt7620/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_MT7620_RFB || BOARD_MT7620_MT7530_RFB
+
+config SYS_BOARD
+	default "mt7620"
+
+config SYS_VENDOR
+	default "mediatek"
+
+config SYS_CONFIG_NAME
+	default "mt7620"
+
+endif
diff --git a/board/mediatek/mt7620/MAINTAINERS b/board/mediatek/mt7620/MAINTAINERS
new file mode 100644
index 0000000000..05db777ced
--- /dev/null
+++ b/board/mediatek/mt7620/MAINTAINERS
@@ -0,0 +1,9 @@
+MT7620_RFB BOARD
+M:	Weijie Gao <weijie.gao@mediatek.com>
+S:	Maintained
+F:	board/mediatek/mt7620
+F:	include/configs/mt7620.h
+F:	configs/mt7620_rfb_defconfig
+F:	configs/mt7620_mt7530_rfb_defconfig
+F:	arch/mips/dts/mediatek,mt7620-rfb.dts
+F:	arch/mips/dts/mediatek,mt7620-mt7530-rfb.dts
diff --git a/board/mediatek/mt7620/Makefile b/board/mediatek/mt7620/Makefile
new file mode 100644
index 0000000000..db129c5aba
--- /dev/null
+++ b/board/mediatek/mt7620/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += board.o
diff --git a/board/mediatek/mt7620/board.c b/board/mediatek/mt7620/board.c
new file mode 100644
index 0000000000..119b8fc9e5
--- /dev/null
+++ b/board/mediatek/mt7620/board.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
diff --git a/configs/mt7620_mt7530_rfb_defconfig b/configs/mt7620_mt7530_rfb_defconfig
new file mode 100644
index 0000000000..341d86838c
--- /dev/null
+++ b/configs/mt7620_mt7530_rfb_defconfig
@@ -0,0 +1,58 @@
+CONFIG_MIPS=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+CONFIG_ENV_OFFSET=0x30000
+CONFIG_ENV_SECT_SIZE=0x10000
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x40000
+CONFIG_SPL=y
+CONFIG_DEBUG_UART_BASE=0xb0000c00
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_ARCH_MTMIPS=y
+CONFIG_BOARD_MT7620_MT7530_RFB=y
+CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7620-mt7530-rfb"
+CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_NOR_SUPPORT=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_DM is not set
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_MII=y
+# CONFIG_CMD_MDIO is not set
+# CONFIG_PARTITIONS is not set
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupts resets reset-names"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM=y
+# CONFIG_SIMPLE_BUS is not set
+# CONFIG_SPL_SIMPLE_BUS is not set
+CONFIG_GPIO_HOG=y
+# CONFIG_INPUT is not set
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_MT7620_ETH=y
+CONFIG_SPECIFY_CONSOLE_INDEX=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SPI=y
+CONFIG_MT7620_SPI=y
+CONFIG_LZMA=y
+CONFIG_SPL_LZMA=y
diff --git a/configs/mt7620_rfb_defconfig b/configs/mt7620_rfb_defconfig
new file mode 100644
index 0000000000..9829371513
--- /dev/null
+++ b/configs/mt7620_rfb_defconfig
@@ -0,0 +1,76 @@
+CONFIG_MIPS=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+CONFIG_ENV_OFFSET=0x30000
+CONFIG_ENV_SECT_SIZE=0x10000
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x40000
+CONFIG_SPL=y
+CONFIG_DEBUG_UART_BASE=0xb0000c00
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_ARCH_MTMIPS=y
+CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7620-rfb"
+CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_DEBUG_UART=y
+CONFIG_FIT=y
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_NOR_SUPPORT=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_DM is not set
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_MII=y
+# CONFIG_CMD_MDIO is not set
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_ISO_PARTITION is not set
+CONFIG_EFI_PARTITION=y
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupts resets reset-names"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM=y
+# CONFIG_SIMPLE_BUS is not set
+# CONFIG_SPL_SIMPLE_BUS is not set
+# CONFIG_SPL_BLK is not set
+CONFIG_GPIO_HOG=y
+# CONFIG_INPUT is not set
+CONFIG_MMC=y
+CONFIG_DM_MMC=y
+# CONFIG_MMC_QUIRKS is not set
+# CONFIG_MMC_HW_PARTITIONING is not set
+CONFIG_MMC_MTK=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_MT7620_ETH=y
+CONFIG_PHY=y
+CONFIG_MT7620_USB_PHY=y
+CONFIG_SPECIFY_CONSOLE_INDEX=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SPI=y
+CONFIG_MT7620_SPI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_LZMA=y
+CONFIG_SPL_LZMA=y
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 09/21] configs: mtmips: refresh for mt7628 based boards
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (7 preceding siblings ...)
  2020-10-30  9:34 ` [PATCH v2 08/21] mips: mtmips: add two reference boards for mt7620 Weijie Gao
@ 2020-10-30  9:34 ` Weijie Gao
  2020-10-30  9:34 ` [PATCH v2 10/21] serial: add uart driver for MediaTek MT7620 SoC Weijie Gao
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:34 UTC (permalink / raw)
  To: u-boot

Since mt7620 is added into Kconfig, the CONFIG_SOC_MT7628=y which is
omitted by default must be added back, otherwise make xxx_defconfig for
these boards will be configured for mt7620 platform.

Reviewed-by: Stefan Roese <sr@denx.de>
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 configs/gardena-smart-gateway-mt7688_defconfig | 1 +
 configs/linkit-smart-7688_defconfig            | 1 +
 configs/mt7628_rfb_defconfig                   | 1 +
 configs/vocore2_defconfig                      | 1 +
 4 files changed, 4 insertions(+)

diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig
index 001a66d0f6..c03123f6e4 100644
--- a/configs/gardena-smart-gateway-mt7688_defconfig
+++ b/configs/gardena-smart-gateway-mt7688_defconfig
@@ -12,6 +12,7 @@ CONFIG_SPL=y
 CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
 CONFIG_ENV_OFFSET_REDUND=0xB0000
 CONFIG_ARCH_MTMIPS=y
+CONFIG_SOC_MT7628=y
 CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
 CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
 # CONFIG_MIPS_BOOT_ENV_LEGACY is not set
diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig
index 437000b4c7..dd2524e4ec 100644
--- a/configs/linkit-smart-7688_defconfig
+++ b/configs/linkit-smart-7688_defconfig
@@ -9,6 +9,7 @@ CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_SYS_MALLOC_F_LEN=0x40000
 CONFIG_SPL=y
 CONFIG_ARCH_MTMIPS=y
+CONFIG_SOC_MT7628=y
 CONFIG_BOARD_LINKIT_SMART_7688=y
 CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
 CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
diff --git a/configs/mt7628_rfb_defconfig b/configs/mt7628_rfb_defconfig
index 69025728b2..831e54e9f3 100644
--- a/configs/mt7628_rfb_defconfig
+++ b/configs/mt7628_rfb_defconfig
@@ -9,6 +9,7 @@ CONFIG_SPL_SERIAL_SUPPORT=y
 CONFIG_SPL_SYS_MALLOC_F_LEN=0x40000
 CONFIG_SPL=y
 CONFIG_ARCH_MTMIPS=y
+CONFIG_SOC_MT7628=y
 CONFIG_BOARD_MT7628_RFB=y
 CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7628-rfb"
 CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
diff --git a/configs/vocore2_defconfig b/configs/vocore2_defconfig
index acb9abf1be..e255829366 100644
--- a/configs/vocore2_defconfig
+++ b/configs/vocore2_defconfig
@@ -10,6 +10,7 @@ CONFIG_SPL_SYS_MALLOC_F_LEN=0x40000
 CONFIG_SPL=y
 CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
 CONFIG_ARCH_MTMIPS=y
+CONFIG_SOC_MT7628=y
 CONFIG_BOARD_VOCORE2=y
 CONFIG_DEFAULT_DEVICE_TREE="vocore_vocore2"
 CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 10/21] serial: add uart driver for MediaTek MT7620 SoC
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (8 preceding siblings ...)
  2020-10-30  9:34 ` [PATCH v2 09/21] configs: mtmips: refresh for mt7628 based boards Weijie Gao
@ 2020-10-30  9:34 ` Weijie Gao
  2020-11-03 15:12   ` Simon Glass
  2020-10-30  9:34 ` [PATCH v2 11/21] clk: add clock " Weijie Gao
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:34 UTC (permalink / raw)
  To: u-boot

This patch adds uart support for MediaTek MT7620 and earlier SoCs.

The UART used by MT7620 is incompatible with the ns16550a driver.
All registers of this UART have different addresses. A special 16-bit
register for Divisor Latch is used to set the baudrate instead of the
original two 8-bit registers (DLL and DLM).

The driver supports of-platdata which is useful for tiny SPL.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: replace non-DM code with of-platdata
---
 drivers/serial/Kconfig         |  20 +++
 drivers/serial/Makefile        |   1 +
 drivers/serial/serial.c        |   2 +
 drivers/serial/serial_mt7620.c | 246 +++++++++++++++++++++++++++++++++
 4 files changed, 269 insertions(+)
 create mode 100644 drivers/serial/serial_mt7620.c

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b4805a2e4e..44fff8a3cd 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -401,6 +401,16 @@ config DEBUG_UART_MTK
 	  driver will be available until the real driver model serial is
 	  running.
 
+config DEBUG_UART_MT7620
+	bool "UART driver for MediaTek MT7620 and earlier SoCs"
+	depends on MT7620_SERIAL
+	help
+	  Select this to enable a debug UART using the UART driver for
+	  MediaTek MT7620 and earlier SoCs.
+	  You will need to provide parameters to make this work. The
+	  driver will be available until the real driver model serial is
+	  running.
+
 endchoice
 
 config DEBUG_UART_BASE
@@ -817,6 +827,16 @@ config MTK_SERIAL
 	  The High-speed UART is compatible with the ns16550a UART and have
 	  its own high-speed registers.
 
+config MT7620_SERIAL
+	bool "UART driver for MediaTek MT7620 and earlier SoCs"
+	depends on DM_SERIAL
+	help
+	  Select this to enable UART support for MediaTek MT7620 and earlier
+	  SoCs. This driver uses driver model and requires a device tree
+	  binding to operate.
+	  The UART driver for MediaTek MT7620 and earlier SoCs is *NOT*
+	  compatible with the ns16550a UART.
+
 config MPC8XX_CONS
 	bool "Console driver for MPC8XX"
 	depends on MPC8xx
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 25f7f8d342..0c3810f5d5 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.o
 obj-$(CONFIG_OWL_SERIAL) += serial_owl.o
 obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
 obj-$(CONFIG_MTK_SERIAL) += serial_mtk.o
+obj-$(CONFIG_MT7620_SERIAL) += serial_mt7620.o
 obj-$(CONFIG_SIFIVE_SERIAL) += serial_sifive.o
 obj-$(CONFIG_XEN_SERIAL) += serial_xen.o
 
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 355659ba05..1546f41e42 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -127,6 +127,7 @@ serial_initfunc(pl01x_serial_initialize);
 serial_initfunc(pxa_serial_initialize);
 serial_initfunc(sh_serial_initialize);
 serial_initfunc(mtk_serial_initialize);
+serial_initfunc(mt7620_serial_initialize);
 
 /**
  * serial_register() - Register serial driver with serial driver core
@@ -181,6 +182,7 @@ int serial_initialize(void)
 	pxa_serial_initialize();
 	sh_serial_initialize();
 	mtk_serial_initialize();
+	mt7620_serial_initialize();
 
 	serial_assign(default_serial_console()->name);
 
diff --git a/drivers/serial/serial_mt7620.c b/drivers/serial/serial_mt7620.c
new file mode 100644
index 0000000000..4f6b5de4cf
--- /dev/null
+++ b/drivers/serial/serial_mt7620.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * UART driver for MediaTek MT7620 and earlier SoCs
+ *
+ * Copyright (C) 2020 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <clk.h>
+#include <div64.h>
+#include <dm.h>
+#include <errno.h>
+#include <log.h>
+#include <reset.h>
+#include <serial.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <asm/addrspace.h>
+#include <dm/device_compat.h>
+#include <linux/err.h>
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+#include <dt-structs.h>
+#endif
+
+struct mt7620_serial_regs {
+	u32 rbr;
+	u32 thr;
+	u32 ier;
+	u32 iir;
+	u32 fcr;
+	u32 lcr;
+	u32 mcr;
+	u32 lsr;
+	u32 msr;
+	u32 scratch;
+	u32 dl;
+	u32 dll;
+	u32 dlm;
+	u32 ifctl;
+};
+
+#define UART_LCR_WLS_8		0x03	/* 8 bit character length */
+
+#define UART_LSR_DR		0x01	/* Data ready */
+#define UART_LSR_THRE		0x20	/* Xmit holding register empty */
+#define UART_LSR_TEMT		0x40	/* Xmitter empty */
+
+#define UART_MCR_DTR		0x01	/* DTR */
+#define UART_MCR_RTS		0x02	/* RTS */
+
+#define UART_FCR_FIFO_EN	0x01	/* Fifo enable */
+#define UART_FCR_RXSR		0x02	/* Receiver soft reset */
+#define UART_FCR_TXSR		0x04	/* Transmitter soft reset */
+
+#define UART_MCRVAL (UART_MCR_DTR | \
+		     UART_MCR_RTS)
+
+/* Clear & enable FIFOs */
+#define UART_FCRVAL (UART_FCR_FIFO_EN | \
+		     UART_FCR_RXSR |	\
+		     UART_FCR_TXSR)
+
+struct mt7620_serial_plat {
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	struct dtd_serial_mt7620 dtplat;
+#endif
+
+	struct mt7620_serial_regs __iomem *regs;
+	u32 clock;
+};
+
+static void _mt7620_serial_setbrg(struct mt7620_serial_plat *plat, int baud)
+{
+	u32 quot;
+
+	/* set divisor */
+	quot = DIV_ROUND_CLOSEST(plat->clock, 16 * baud);
+	writel(quot, &plat->regs->dl);
+
+	/* set character length and stop bits */
+	writel(UART_LCR_WLS_8, &plat->regs->lcr);
+}
+
+static int mt7620_serial_setbrg(struct udevice *dev, int baudrate)
+{
+	struct mt7620_serial_plat *plat = dev_get_platdata(dev);
+
+	_mt7620_serial_setbrg(plat, baudrate);
+
+	return 0;
+}
+
+static int mt7620_serial_putc(struct udevice *dev, const char ch)
+{
+	struct mt7620_serial_plat *plat = dev_get_platdata(dev);
+
+	if (!(readl(&plat->regs->lsr) & UART_LSR_THRE))
+		return -EAGAIN;
+
+	writel(ch, &plat->regs->thr);
+
+	if (ch == '\n')
+		WATCHDOG_RESET();
+
+	return 0;
+}
+
+static int mt7620_serial_getc(struct udevice *dev)
+{
+	struct mt7620_serial_plat *plat = dev_get_platdata(dev);
+
+	if (!(readl(&plat->regs->lsr) & UART_LSR_DR))
+		return -EAGAIN;
+
+	return readl(&plat->regs->rbr);
+}
+
+static int mt7620_serial_pending(struct udevice *dev, bool input)
+{
+	struct mt7620_serial_plat *plat = dev_get_platdata(dev);
+
+	if (input)
+		return (readl(&plat->regs->lsr) & UART_LSR_DR) ? 1 : 0;
+
+	return (readl(&plat->regs->lsr) & UART_LSR_THRE) ? 0 : 1;
+}
+
+static int mt7620_serial_probe(struct udevice *dev)
+{
+	struct mt7620_serial_plat *plat = dev_get_platdata(dev);
+
+#if CONFIG_IS_ENABLED(OF_PLATDATA)
+	plat->regs = (void __iomem *)KSEG1ADDR(plat->dtplat.reg[0]);
+	plat->clock = plat->dtplat.clock_frequency;
+#endif
+
+	/* Disable interrupt */
+	writel(0, &plat->regs->ier);
+
+	writel(UART_MCRVAL, &plat->regs->mcr);
+	writel(UART_FCRVAL, &plat->regs->fcr);
+
+	return 0;
+}
+
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+static int mt7620_serial_ofdata_to_platdata(struct udevice *dev)
+{
+	struct mt7620_serial_plat *plat = dev_get_platdata(dev);
+	struct reset_ctl reset_uart;
+	struct clk clk;
+	int err;
+
+	err = reset_get_by_index(dev, 0, &reset_uart);
+	if (!err)
+		reset_deassert(&reset_uart);
+
+	plat->regs = dev_remap_addr_index(dev, 0);
+	if (!plat->regs) {
+		dev_err(dev, "mt7620_serial: unable to map UART registers\n");
+		return -EINVAL;
+	}
+
+	err = clk_get_by_index(dev, 0, &clk);
+	if (!err) {
+		err = clk_get_rate(&clk);
+		if (!IS_ERR_VALUE(err))
+			plat->clock = err;
+	} else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) {
+		dev_err(dev, "mt7620_serial: failed to get clock\n");
+		return err;
+	}
+
+	if (!plat->clock)
+		plat->clock = dev_read_u32_default(dev, "clock-frequency", 0);
+
+	if (!plat->clock) {
+		dev_err(dev, "mt7620_serial: clock not defined\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id mt7620_serial_ids[] = {
+	{ .compatible = "mediatek,mt7620-uart" },
+	{ }
+};
+#endif
+
+static const struct dm_serial_ops mt7620_serial_ops = {
+	.putc = mt7620_serial_putc,
+	.pending = mt7620_serial_pending,
+	.getc = mt7620_serial_getc,
+	.setbrg = mt7620_serial_setbrg,
+};
+
+U_BOOT_DRIVER(serial_mt7620) = {
+	.name = "serial_mt7620",
+	.id = UCLASS_SERIAL,
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+	.of_match = mt7620_serial_ids,
+	.ofdata_to_platdata = mt7620_serial_ofdata_to_platdata,
+#endif
+	.platdata_auto_alloc_size = sizeof(struct mt7620_serial_plat),
+	.probe = mt7620_serial_probe,
+	.ops = &mt7620_serial_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER_ALIAS(serial_mt7620, mediatek_mt7620_uart);
+
+#ifdef CONFIG_DEBUG_UART_MT7620
+
+#include <debug_uart.h>
+
+static inline void _debug_uart_init(void)
+{
+	struct mt7620_serial_plat plat;
+
+	plat.regs = (void *)CONFIG_DEBUG_UART_BASE;
+	plat.clock = CONFIG_DEBUG_UART_CLOCK;
+
+	writel(0, &plat.regs->ier);
+	writel(UART_MCRVAL, &plat.regs->mcr);
+	writel(UART_FCRVAL, &plat.regs->fcr);
+
+	_mt7620_serial_setbrg(&plat, CONFIG_BAUDRATE);
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+	struct mt7620_serial_regs __iomem *regs =
+		(void *)CONFIG_DEBUG_UART_BASE;
+
+	while (!(readl(&regs->lsr) & UART_LSR_THRE))
+		;
+
+	writel(ch, &regs->thr);
+}
+
+DEBUG_UART_FUNCS
+
+#endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 11/21] clk: add clock driver for MediaTek MT7620 SoC
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (9 preceding siblings ...)
  2020-10-30  9:34 ` [PATCH v2 10/21] serial: add uart driver for MediaTek MT7620 SoC Weijie Gao
@ 2020-10-30  9:34 ` Weijie Gao
  2020-10-30  9:34 ` [PATCH v2 12/21] reset: mtmips: add reset controller support " Weijie Gao
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:34 UTC (permalink / raw)
  To: u-boot

This patch adds a clock driver for MediaTek MT7620 SoC.
This driver provides clock gate control as well as getting clock frequency
for CPU/SYS/XTAL and some peripherals.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 drivers/clk/mtmips/Makefile            |   1 +
 drivers/clk/mtmips/clk-mt7620.c        | 159 +++++++++++++++++++++++++
 include/dt-bindings/clock/mt7620-clk.h |  40 +++++++
 3 files changed, 200 insertions(+)
 create mode 100644 drivers/clk/mtmips/clk-mt7620.c
 create mode 100644 include/dt-bindings/clock/mt7620-clk.h

diff --git a/drivers/clk/mtmips/Makefile b/drivers/clk/mtmips/Makefile
index e1938418da..732e7f2545 100644
--- a/drivers/clk/mtmips/Makefile
+++ b/drivers/clk/mtmips/Makefile
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 
+obj-$(CONFIG_SOC_MT7620) += clk-mt7620.o
 obj-$(CONFIG_SOC_MT7628) += clk-mt7628.o
diff --git a/drivers/clk/mtmips/clk-mt7620.c b/drivers/clk/mtmips/clk-mt7620.c
new file mode 100644
index 0000000000..44e4b53c21
--- /dev/null
+++ b/drivers/clk/mtmips/clk-mt7620.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dt-bindings/clock/mt7620-clk.h>
+#include <misc.h>
+#include <mach/mt7620-sysc.h>
+
+/* CLKCFG1 */
+#define CLKCFG1_REG			0x30
+
+#define CLK_SRC_CPU			-1
+#define CLK_SRC_CPU_D2			-2
+#define CLK_SRC_SYS			-3
+#define CLK_SRC_XTAL			-4
+#define CLK_SRC_PERI			-5
+
+struct mt7620_clk_priv {
+	struct udevice *dev;
+	struct udevice *sysc;
+	struct mt7620_sysc_clks clks;
+};
+
+static const int mt7620_clks[] = {
+	[CLK_SYS] = CLK_SRC_SYS,
+	[CLK_CPU] = CLK_SRC_CPU,
+	[CLK_XTAL] = CLK_SRC_XTAL,
+	[CLK_MIPS_CNT] = CLK_SRC_CPU_D2,
+	[CLK_UARTF] = CLK_SRC_PERI,
+	[CLK_UARTL] = CLK_SRC_PERI,
+	[CLK_SPI] = CLK_SRC_SYS,
+	[CLK_I2C] = CLK_SRC_PERI,
+	[CLK_I2S] = CLK_SRC_PERI,
+};
+
+static ulong mt7620_clk_get_rate(struct clk *clk)
+{
+	struct mt7620_clk_priv *priv = dev_get_priv(clk->dev);
+
+	if (clk->id >= ARRAY_SIZE(mt7620_clks))
+		return 0;
+
+	switch (mt7620_clks[clk->id]) {
+	case CLK_SRC_CPU:
+		return priv->clks.cpu_clk;
+	case CLK_SRC_CPU_D2:
+		return priv->clks.cpu_clk / 2;
+	case CLK_SRC_SYS:
+		return priv->clks.sys_clk;
+	case CLK_SRC_XTAL:
+		return priv->clks.xtal_clk;
+	case CLK_SRC_PERI:
+		return priv->clks.peri_clk;
+	default:
+		return mt7620_clks[clk->id];
+	}
+}
+
+static int mt7620_clkcfg1_rmw(struct mt7620_clk_priv *priv, u32 clr, u32 set)
+{
+	u32 val;
+	int ret;
+
+	ret = misc_read(priv->sysc, CLKCFG1_REG, &val, sizeof(val));
+	if (ret) {
+		dev_err(priv->dev, "mt7620_clk: failed to read CLKCFG1\n");
+		return ret;
+	}
+
+	val &= ~clr;
+	val |= set;
+
+	ret = misc_write(priv->sysc, CLKCFG1_REG, &val, sizeof(val));
+	if (ret) {
+		dev_err(priv->dev, "mt7620_clk: failed to write CLKCFG1\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int mt7620_clk_enable(struct clk *clk)
+{
+	struct mt7620_clk_priv *priv = dev_get_priv(clk->dev);
+
+	if (clk->id > 30)
+		return -1;
+
+	return mt7620_clkcfg1_rmw(priv, 0, BIT(clk->id));
+}
+
+static int mt7620_clk_disable(struct clk *clk)
+{
+	struct mt7620_clk_priv *priv = dev_get_priv(clk->dev);
+
+	if (clk->id > 30)
+		return -1;
+
+	return mt7620_clkcfg1_rmw(priv, BIT(clk->id), 0);
+}
+
+const struct clk_ops mt7620_clk_ops = {
+	.enable = mt7620_clk_enable,
+	.disable = mt7620_clk_disable,
+	.get_rate = mt7620_clk_get_rate,
+};
+
+static int mt7620_clk_probe(struct udevice *dev)
+{
+	struct mt7620_clk_priv *priv = dev_get_priv(dev);
+	struct ofnode_phandle_args sysc_args;
+	int ret;
+
+	ret = ofnode_parse_phandle_with_args(dev->node, "mediatek,sysc", NULL,
+					     0, 0, &sysc_args);
+	if (ret) {
+		dev_err(dev, "mt7620_clk: sysc property not found\n");
+		return ret;
+	}
+
+	ret = uclass_get_device_by_ofnode(UCLASS_MISC, sysc_args.node,
+					  &priv->sysc);
+	if (ret) {
+		dev_err(dev, "mt7620_clk: failed to sysc device\n");
+		return ret;
+	}
+
+	ret = misc_ioctl(priv->sysc, MT7620_SYSC_IOCTL_GET_CLK,
+			 &priv->clks);
+	if (ret) {
+		dev_err(dev, "mt7620_clk: failed to get base clocks\n");
+		return ret;
+	}
+
+	priv->dev = dev;
+
+	return 0;
+}
+
+static const struct udevice_id mt7620_clk_ids[] = {
+	{ .compatible = "mediatek,mt7620-clk" },
+	{ }
+};
+
+U_BOOT_DRIVER(mt7620_clk) = {
+	.name = "mt7620-clk",
+	.id = UCLASS_CLK,
+	.of_match = mt7620_clk_ids,
+	.probe = mt7620_clk_probe,
+	.priv_auto_alloc_size = sizeof(struct mt7620_clk_priv),
+	.ops = &mt7620_clk_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/include/dt-bindings/clock/mt7620-clk.h b/include/dt-bindings/clock/mt7620-clk.h
new file mode 100644
index 0000000000..3bb91ebdf1
--- /dev/null
+++ b/include/dt-bindings/clock/mt7620-clk.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_MT7620_CLK_H_
+#define _DT_BINDINGS_MT7620_CLK_H_
+
+/* Base clocks */
+#define CLK_SYS				34
+#define CLK_CPU				33
+#define CLK_XTAL			32
+
+/* Peripheral clocks */
+#define CLK_SDHC			30
+#define CLK_MIPS_CNT			28
+#define CLK_PCIE			26
+#define CLK_UPHY_12M			25
+#define CLK_EPHY			24
+#define CLK_ESW				23
+#define CLK_UPHY_48M			22
+#define CLK_FE				21
+#define CLK_UARTL			19
+#define CLK_SPI				18
+#define CLK_I2S				17
+#define CLK_I2C				16
+#define CLK_NAND			15
+#define CLK_GDMA			14
+#define CLK_PIO				13
+#define CLK_UARTF			12
+#define CLK_PCM				11
+#define CLK_MC				10
+#define CLK_INTC			9
+#define CLK_TIMER			8
+#define CLK_GE2				7
+#define CLK_GE1				6
+
+#endif /* _DT_BINDINGS_MT7620_CLK_H_ */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 12/21] reset: mtmips: add reset controller support for MediaTek MT7620 SoC
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (10 preceding siblings ...)
  2020-10-30  9:34 ` [PATCH v2 11/21] clk: add clock " Weijie Gao
@ 2020-10-30  9:34 ` Weijie Gao
  2020-10-30  9:34 ` [PATCH v2 13/21] pinctrl: mtmips: add " Weijie Gao
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:34 UTC (permalink / raw)
  To: u-boot

This patch adds reset controller bits definition header file for MediaTek
MT7620 SoC

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 include/dt-bindings/reset/mt7620-reset.h | 35 ++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
 create mode 100644 include/dt-bindings/reset/mt7620-reset.h

diff --git a/include/dt-bindings/reset/mt7620-reset.h b/include/dt-bindings/reset/mt7620-reset.h
new file mode 100644
index 0000000000..3096b29cdb
--- /dev/null
+++ b/include/dt-bindings/reset/mt7620-reset.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_MT7620_RESET_H_
+#define _DT_BINDINGS_MT7620_RESET_H_
+
+#define PPE_RST			31
+#define SDHC_RST		30
+#define MIPS_CNT_RST		28
+#define PCIE_RST		26
+#define UHST_RST		25
+#define EPHY_RST		24
+#define ESW_RST			23
+#define UDEV_RST		22
+#define FE_RST			21
+#define WLAN_RST		20
+#define UARTL_RST		19
+#define SPI_RST			18
+#define I2S_RST			17
+#define I2C_RST			16
+#define NAND_RST		15
+#define DMA_RST			14
+#define PIO_RST			13
+#define UARTF_RST		12
+#define PCM_RST			11
+#define MC_RST			10
+#define INTC_RST		9
+#define TIMER_RST		8
+#define SYS_RST			0
+
+#endif /* _DT_BINDINGS_MT7620_RESET_H_ */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 13/21] pinctrl: mtmips: add support for MediaTek MT7620 SoC
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (11 preceding siblings ...)
  2020-10-30  9:34 ` [PATCH v2 12/21] reset: mtmips: add reset controller support " Weijie Gao
@ 2020-10-30  9:34 ` Weijie Gao
  2020-10-30  9:34 ` [PATCH v2 14/21] watchdog: add watchdog driver " Weijie Gao
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:34 UTC (permalink / raw)
  To: u-boot

This patch adds pinctrl support for MediaTek MT7620 SoC.
The MT7620 SoC supports only pinmux.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 drivers/pinctrl/mtmips/Kconfig          |   9 ++
 drivers/pinctrl/mtmips/Makefile         |   1 +
 drivers/pinctrl/mtmips/pinctrl-mt7620.c | 200 ++++++++++++++++++++++++
 3 files changed, 210 insertions(+)
 create mode 100644 drivers/pinctrl/mtmips/pinctrl-mt7620.c

diff --git a/drivers/pinctrl/mtmips/Kconfig b/drivers/pinctrl/mtmips/Kconfig
index 8482a38ebc..844d5b743f 100644
--- a/drivers/pinctrl/mtmips/Kconfig
+++ b/drivers/pinctrl/mtmips/Kconfig
@@ -3,6 +3,15 @@ config PINCTRL_MTMIPS
 	depends on ARCH_MTMIPS
 	bool
 
+config PINCTRL_MT7620
+	bool "MediaTek MT7620 pin control driver"
+	select PINCTRL_MTMIPS
+	depends on SOC_MT7620 && PINCTRL_GENERIC
+	help
+	  Support pin multiplexing control on MediaTek MT7620.
+	  The driver is controlled by a device tree node which contains
+	  the pin mux functions for each available pin groups.
+
 config PINCTRL_MT7628
 	bool "MediaTek MT7628 pin control driver"
 	select PINCTRL_MTMIPS
diff --git a/drivers/pinctrl/mtmips/Makefile b/drivers/pinctrl/mtmips/Makefile
index 3ba5c0c66d..ba945a89a7 100644
--- a/drivers/pinctrl/mtmips/Makefile
+++ b/drivers/pinctrl/mtmips/Makefile
@@ -4,4 +4,5 @@
 obj-$(CONFIG_PINCTRL_MTMIPS) += pinctrl-mtmips-common.o
 
 # SoC Drivers
+obj-$(CONFIG_PINCTRL_MT7620) += pinctrl-mt7620.o
 obj-$(CONFIG_PINCTRL_MT7628) += pinctrl-mt7628.o
diff --git a/drivers/pinctrl/mtmips/pinctrl-mt7620.c b/drivers/pinctrl/mtmips/pinctrl-mt7620.c
new file mode 100644
index 0000000000..10a4fc6c19
--- /dev/null
+++ b/drivers/pinctrl/mtmips/pinctrl-mt7620.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+
+#include "pinctrl-mtmips-common.h"
+
+#define SUTIF_SHIFT			30
+#define WDT_RST_SHIFT			21
+#define PA_G_SHIFT			20
+#define NAND_SD_SHIFT			18
+#define PERST_SHIFT			16
+#define EPHY_LED_SHIFT			15
+#define WLED_SHIFT			13
+#define SPI_CS1_SHIFT			12
+#define SPI_SHIFT			11
+#define RGMII2_SHIFT			10
+#define RGMII1_SHIFT			9
+#define MDIO_SHIFT			7
+#define UARTL_SHIFT			5
+#define UARTF_SHIFT			2
+#define I2C_SHIFT			0
+
+#define GM4_MASK			3
+#define GM8_MASK			7
+
+#if CONFIG_IS_ENABLED(PINMUX)
+static const struct mtmips_pmx_func sutif_grp[] = {
+	FUNC("i2c", 2),
+	FUNC("uartl", 1),
+	FUNC("none", 0),
+};
+
+static const struct mtmips_pmx_func wdt_rst_grp[] = {
+	FUNC("gpio", 2),
+	FUNC("refclk", 1),
+	FUNC("wdt rst", 0),
+};
+
+static const struct mtmips_pmx_func pa_g_grp[] = {
+	FUNC("gpio", 1),
+	FUNC("pa", 0),
+};
+
+static const struct mtmips_pmx_func nand_sd_grp[] = {
+	FUNC("gpio", 2),
+	FUNC("sd", 1),
+	FUNC("nand", 0),
+};
+
+static const struct mtmips_pmx_func perst_grp[] = {
+	FUNC("gpio", 2),
+	FUNC("refclk", 1),
+	FUNC("perst", 0),
+};
+
+static const struct mtmips_pmx_func ephy_led_grp[] = {
+	FUNC("gpio", 1),
+	FUNC("led", 0),
+};
+
+static const struct mtmips_pmx_func wled_grp[] = {
+	FUNC("gpio", 1),
+	FUNC("led", 0),
+};
+
+static const struct mtmips_pmx_func spi_cs1_grp[] = {
+	FUNC("refclk", 1),
+	FUNC("spi cs1", 0),
+};
+
+static const struct mtmips_pmx_func spi_grp[] = {
+	FUNC("gpio", 1),
+	FUNC("spi", 0),
+};
+
+static const struct mtmips_pmx_func rgmii2_grp[] = {
+	FUNC("gpio", 1),
+	FUNC("rgmii2", 0),
+};
+
+static const struct mtmips_pmx_func rgmii1_grp[] = {
+	FUNC("gpio", 1),
+	FUNC("rgmii1", 0),
+};
+
+static const struct mtmips_pmx_func mdio_grp[] = {
+	FUNC("gpio", 2),
+	FUNC("refclk", 1),
+	FUNC("mdio", 0),
+};
+
+static const struct mtmips_pmx_func uartl_grp[] = {
+	FUNC("gpio", 1),
+	FUNC("uartl", 0),
+};
+
+static const struct mtmips_pmx_func uartf_grp[] = {
+	FUNC("gpio", 7),
+	FUNC("i2s gpio", 6),
+	FUNC("uartf gpio", 5),
+	FUNC("gpio pcm", 4),
+	FUNC("i2s uartf", 3),
+	FUNC("i2s pcm", 2),
+	FUNC("uartf pcm", 1),
+	FUNC("uartf", 0),
+};
+
+static const struct mtmips_pmx_func i2c_grp[] = {
+	FUNC("gpio", 1),
+	FUNC("i2c", 0),
+};
+
+static const struct mtmips_pmx_group mt7620_pinmux_data[] = {
+	GRP("sutif", sutif_grp, 0, SUTIF_SHIFT, GM4_MASK),
+	GRP("wdt rst", wdt_rst_grp, 0, WDT_RST_SHIFT, GM4_MASK),
+	GRP("pa", pa_g_grp, 0, PA_G_SHIFT, 1),
+	GRP("nand", nand_sd_grp, 0, NAND_SD_SHIFT, GM4_MASK),
+	GRP("perst", perst_grp, 0, PERST_SHIFT, GM4_MASK),
+	GRP("ephy led", ephy_led_grp, 0, EPHY_LED_SHIFT, 1),
+	GRP("wled", wled_grp, 0, WLED_SHIFT, 1),
+	GRP("spi cs1", spi_cs1_grp, 0, SPI_CS1_SHIFT, 1),
+	GRP("spi", spi_grp, 0, SPI_SHIFT, 1),
+	GRP("rgmii2", rgmii2_grp, 0, RGMII2_SHIFT, 1),
+	GRP("rgmii1", rgmii1_grp, 0, RGMII1_SHIFT, 1),
+	GRP("mdio", mdio_grp, 0, MDIO_SHIFT, GM4_MASK),
+	GRP("uartl", uartl_grp, 0, UARTL_SHIFT, 1),
+	GRP("uartf", uartf_grp, 0, UARTF_SHIFT, GM8_MASK),
+	GRP("i2c", i2c_grp, 0, I2C_SHIFT, 1),
+};
+
+static int mt7620_get_groups_count(struct udevice *dev)
+{
+	return ARRAY_SIZE(mt7620_pinmux_data);
+}
+
+static const char *mt7620_get_group_name(struct udevice *dev,
+					 unsigned int selector)
+{
+	return mt7620_pinmux_data[selector].name;
+}
+#endif /* CONFIG_IS_ENABLED(PINMUX) */
+
+static int mt7620_pinctrl_probe(struct udevice *dev)
+{
+	struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
+	int ret = 0;
+
+#if CONFIG_IS_ENABLED(PINMUX)
+	ret = mtmips_pinctrl_probe(priv, ARRAY_SIZE(mt7620_pinmux_data),
+				   mt7620_pinmux_data);
+#endif /* CONFIG_IS_ENABLED(PINMUX) */
+
+	return ret;
+}
+
+static int mt7620_pinctrl_ofdata_to_platdata(struct udevice *dev)
+{
+	struct mtmips_pinctrl_priv *priv = dev_get_priv(dev);
+
+	priv->base = dev_remap_addr_index(dev, 0);
+	if (!priv->base)
+		return -EINVAL;
+
+	return 0;
+}
+
+static const struct pinctrl_ops mt7620_pinctrl_ops = {
+#if CONFIG_IS_ENABLED(PINMUX)
+	.get_groups_count = mt7620_get_groups_count,
+	.get_group_name = mt7620_get_group_name,
+	.get_functions_count = mtmips_get_functions_count,
+	.get_function_name = mtmips_get_function_name,
+	.pinmux_group_set = mtmips_pinmux_group_set,
+#endif /* CONFIG_IS_ENABLED(PINMUX) */
+	.set_state = pinctrl_generic_set_state,
+};
+
+static const struct udevice_id mt7620_pinctrl_ids[] = {
+	{ .compatible = "mediatek,mt7620-pinctrl" },
+	{ }
+};
+
+U_BOOT_DRIVER(mt7620_pinctrl) = {
+	.name = "mt7620-pinctrl",
+	.id = UCLASS_PINCTRL,
+	.of_match = mt7620_pinctrl_ids,
+	.ofdata_to_platdata = mt7620_pinctrl_ofdata_to_platdata,
+	.ops = &mt7620_pinctrl_ops,
+	.probe = mt7620_pinctrl_probe,
+	.priv_auto_alloc_size = sizeof(struct mtmips_pinctrl_priv),
+	.flags = DM_FLAG_PRE_RELOC,
+};
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 14/21] watchdog: add watchdog driver for MediaTek MT7620 SoC
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (12 preceding siblings ...)
  2020-10-30  9:34 ` [PATCH v2 13/21] pinctrl: mtmips: add " Weijie Gao
@ 2020-10-30  9:34 ` Weijie Gao
  2020-11-02  6:02   ` Jagan Teki
  2020-10-30  9:34 ` [PATCH v2 15/21] gpio: add GPIO controller " Weijie Gao
                   ` (6 subsequent siblings)
  20 siblings, 1 reply; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:34 UTC (permalink / raw)
  To: u-boot

This patch adds watchdog support for the Mediatek MT7620 SoC

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: add expire_now
---
 drivers/watchdog/Kconfig      |   7 ++
 drivers/watchdog/Makefile     |   1 +
 drivers/watchdog/mt7620_wdt.c | 132 ++++++++++++++++++++++++++++++++++
 3 files changed, 140 insertions(+)
 create mode 100644 drivers/watchdog/mt7620_wdt.c

diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 210d9f8093..35d078caa0 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -124,6 +124,13 @@ config WDT_MPC8xx
 	help
 	  Select this to enable mpc8xx watchdog timer
 
+config WDT_MT7620
+	bool "MediaTek MT7620 watchdog timer support"
+	depends on WDT && SOC_MT7620
+	help
+	  Select this to enable watchdog timer on MediaTek MT7620 and earlier
+	  SoC chips.
+
 config WDT_MT7621
 	bool "MediaTek MT7621 watchdog timer support"
 	depends on WDT && SOC_MT7628
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 01b8231f2b..825b50e626 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o
 obj-$(CONFIG_WDT_ORION) += orion_wdt.o
 obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
 obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
+obj-$(CONFIG_WDT_MT7620) += mt7620_wdt.o
 obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
 obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
 obj-$(CONFIG_WDT_OCTEONTX) += octeontx_wdt.o
diff --git a/drivers/watchdog/mt7620_wdt.c b/drivers/watchdog/mt7620_wdt.c
new file mode 100644
index 0000000000..2643167f8f
--- /dev/null
+++ b/drivers/watchdog/mt7620_wdt.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author:  Weijie Gao <weijie.gao@mediatek.com>
+ *
+ * Watchdog timer for MT7620 and earlier SoCs
+ */
+
+#include <div64.h>
+#include <dm.h>
+#include <reset.h>
+#include <wdt.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+
+struct mt7620_wdt {
+	void __iomem *regs;
+	u64 timeout;
+};
+
+#define TIMER_FREQ			40000000
+#define TIMER_MASK			0xffff
+#define TIMER_PRESCALE			65536
+
+#define TIMER_LOAD			0x00
+#define TIMER_CTL			0x08
+
+#define TIMER_ENABLE			BIT(7)
+#define TIMER_MODE_SHIFT		4
+#define   TIMER_MODE_WDT		3
+#define TIMER_PRESCALE_SHIFT		0
+#define   TIMER_PRESCALE_65536		15
+
+static void mt7620_wdt_ping(struct mt7620_wdt *priv)
+{
+	u64 val;
+
+	val = (TIMER_FREQ / TIMER_PRESCALE) * priv->timeout;
+	do_div(val, 1000);
+
+	if (val > TIMER_MASK)
+		val = TIMER_MASK;
+
+	writel(val, priv->regs + TIMER_LOAD);
+}
+
+static int mt7620_wdt_start(struct udevice *dev, u64 ms, ulong flags)
+{
+	struct mt7620_wdt *priv = dev_get_priv(dev);
+
+	priv->timeout = ms;
+	mt7620_wdt_ping(priv);
+
+	writel(TIMER_ENABLE | (TIMER_MODE_WDT << TIMER_MODE_SHIFT) |
+	       (TIMER_PRESCALE_65536 << TIMER_PRESCALE_SHIFT),
+	       priv->regs + TIMER_CTL);
+
+	return 0;
+}
+
+static int mt7620_wdt_stop(struct udevice *dev)
+{
+	struct mt7620_wdt *priv = dev_get_priv(dev);
+
+	mt7620_wdt_ping(priv);
+
+	clrbits_32(priv->regs + TIMER_CTL, TIMER_ENABLE);
+
+	return 0;
+}
+
+static int mt7620_wdt_reset(struct udevice *dev)
+{
+	struct mt7620_wdt *priv = dev_get_priv(dev);
+
+	mt7620_wdt_ping(priv);
+
+	return 0;
+}
+
+static int mt7620_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+	struct mt7620_wdt *priv = dev_get_priv(dev);
+
+	mt7620_wdt_start(dev, 1, flags);
+
+	/* 0 will disable the timer, so use 1 instead */
+	writel(1, priv->regs + TIMER_LOAD);
+
+	return 0;
+}
+
+static int mt7620_wdt_probe(struct udevice *dev)
+{
+	struct mt7620_wdt *priv = dev_get_priv(dev);
+	struct reset_ctl reset_wdt;
+	int ret;
+
+	ret = reset_get_by_index(dev, 0, &reset_wdt);
+	if (!ret)
+		reset_deassert(&reset_wdt);
+
+	priv->regs = dev_remap_addr(dev);
+	if (!priv->regs)
+		return -EINVAL;
+
+	mt7620_wdt_stop(dev);
+
+	return 0;
+}
+
+static const struct wdt_ops mt7620_wdt_ops = {
+	.start = mt7620_wdt_start,
+	.reset = mt7620_wdt_reset,
+	.stop = mt7620_wdt_stop,
+	.expire_now = mt7620_wdt_expire_now,
+};
+
+static const struct udevice_id mt7620_wdt_ids[] = {
+	{ .compatible = "mediatek,mt7620-wdt" },
+	{}
+};
+
+U_BOOT_DRIVER(mt7620_wdt) = {
+	.name = "mt7620_wdt",
+	.id = UCLASS_WDT,
+	.of_match = mt7620_wdt_ids,
+	.probe = mt7620_wdt_probe,
+	.priv_auto_alloc_size = sizeof(struct mt7620_wdt),
+	.ops = &mt7620_wdt_ops,
+};
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 15/21] gpio: add GPIO controller driver for MediaTek MT7620 SoC
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (13 preceding siblings ...)
  2020-10-30  9:34 ` [PATCH v2 14/21] watchdog: add watchdog driver " Weijie Gao
@ 2020-10-30  9:34 ` Weijie Gao
  2020-10-30  9:35 ` [PATCH v2 16/21] spi: add spi controller support " Weijie Gao
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:34 UTC (permalink / raw)
  To: u-boot

This patch adds GPIO controller driver for MediaTek MT7620 SoC

Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 drivers/gpio/Kconfig       |   8 ++
 drivers/gpio/Makefile      |   1 +
 drivers/gpio/mt7620_gpio.c | 146 +++++++++++++++++++++++++++++++++++++
 3 files changed, 155 insertions(+)
 create mode 100644 drivers/gpio/mt7620_gpio.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 202fcc6f47..7e94759a79 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -471,6 +471,14 @@ config MPC83XX_SPISEL_BOOT
 
 	  This pin is typically used as spi chip select to a spi nor flash.
 
+config MT7620_GPIO
+	bool "MediaTek MT7620 GPIO driver"
+	depends on DM_GPIO && SOC_MT7620
+	default y
+	help
+	  Device model driver for GPIO controller present in MediaTek MT7620
+	  and earlier SoCs.
+
 config MT7621_GPIO
 	bool "MediaTek MT7621 GPIO driver"
 	depends on DM_GPIO && SOC_MT7628
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index d3d0d3cacf..8541ba0b0a 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_MVEBU_GPIO)	+= mvebu_gpio.o
 obj-$(CONFIG_MSM_GPIO)		+= msm_gpio.o
 obj-$(CONFIG_$(SPL_)PCF8575_GPIO)	+= pcf8575_gpio.o
 obj-$(CONFIG_PM8916_GPIO)	+= pm8916_gpio.o
+obj-$(CONFIG_MT7620_GPIO)	+= mt7620_gpio.o
 obj-$(CONFIG_MT7621_GPIO)	+= mt7621_gpio.o
 obj-$(CONFIG_MSCC_SGPIO)	+= mscc_sgpio.o
 obj-$(CONFIG_NX_GPIO)		+= nx_gpio.o
diff --git a/drivers/gpio/mt7620_gpio.c b/drivers/gpio/mt7620_gpio.c
new file mode 100644
index 0000000000..508851ea5f
--- /dev/null
+++ b/drivers/gpio/mt7620_gpio.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ *
+ * GPIO controller driver for MediaTek MT7620 SoC
+ */
+
+#include <dm.h>
+#include <errno.h>
+#include <dm/device_compat.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <asm/gpio.h>
+
+enum mt7620_regs {
+	GPIO_REG_DATA,
+	GPIO_REG_DIR,
+	GPIO_REG_SET,
+	GPIO_REG_CLR,
+
+	__GPIO_REG_MAX
+};
+
+struct mt7620_gpio_priv {
+	void __iomem *base;
+	u32 regs[__GPIO_REG_MAX];
+	u32 count;
+};
+
+static int mt7620_gpio_get_value(struct udevice *dev, unsigned int offset)
+{
+	struct mt7620_gpio_priv *priv = dev_get_priv(dev);
+
+	return !!(readl(priv->base + priv->regs[GPIO_REG_DATA]) & BIT(offset));
+}
+
+static int mt7620_gpio_set_value(struct udevice *dev, unsigned int offset,
+				 int value)
+{
+	struct mt7620_gpio_priv *priv = dev_get_priv(dev);
+	u32 reg;
+
+	reg = value ? priv->regs[GPIO_REG_SET] : priv->regs[GPIO_REG_CLR];
+
+	writel(BIT(offset), priv->base + reg);
+
+	return 0;
+}
+
+static int mt7620_gpio_direction_input(struct udevice *dev, unsigned int offset)
+{
+	struct mt7620_gpio_priv *priv = dev_get_priv(dev);
+
+	clrbits_32(priv->base + priv->regs[GPIO_REG_DIR], BIT(offset));
+
+	return 0;
+}
+
+static int mt7620_gpio_direction_output(struct udevice *dev,
+					unsigned int offset, int value)
+{
+	struct mt7620_gpio_priv *priv = dev_get_priv(dev);
+
+	/* Set value first */
+	mt7620_gpio_set_value(dev, offset, value);
+
+	setbits_32(priv->base + priv->regs[GPIO_REG_DIR], BIT(offset));
+
+	return 0;
+}
+
+static int mt7620_gpio_get_function(struct udevice *dev, unsigned int offset)
+{
+	struct mt7620_gpio_priv *priv = dev_get_priv(dev);
+
+	return (readl(priv->base + priv->regs[GPIO_REG_DIR]) & BIT(offset)) ?
+	       GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
+static const struct dm_gpio_ops mt7620_gpio_ops = {
+	.direction_input	= mt7620_gpio_direction_input,
+	.direction_output	= mt7620_gpio_direction_output,
+	.get_value		= mt7620_gpio_get_value,
+	.set_value		= mt7620_gpio_set_value,
+	.get_function		= mt7620_gpio_get_function,
+};
+
+static int mt7620_gpio_probe(struct udevice *dev)
+{
+	struct mt7620_gpio_priv *priv = dev_get_priv(dev);
+	struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	const char *name;
+
+	name = dev_read_string(dev, "mediatek,bank-name");
+	if (!name)
+		name = dev->name;
+
+	uc_priv->gpio_count = priv->count;
+	uc_priv->bank_name = name;
+
+	return 0;
+}
+
+static int mt7620_gpio_ofdata_to_platdata(struct udevice *dev)
+{
+	struct mt7620_gpio_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	priv->base = dev_remap_addr_index(dev, 0);
+	if (!priv->base) {
+		dev_err(dev, "mt7620_gpio: unable to map registers\n");
+		return -EINVAL;
+	}
+
+	ret = dev_read_u32(dev, "mediatek,gpio-num", &priv->count);
+	if (ret) {
+		dev_err(dev, "mt7620_gpio: failed to get GPIO count\n");
+		return -EINVAL;
+	}
+
+	ret = dev_read_u32_array(dev, "mediatek,register-map", priv->regs,
+				 __GPIO_REG_MAX);
+	if (ret) {
+		dev_err(dev, "mt7620_gpio: unable to get register map\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id mt7620_gpio_ids[] = {
+	{ .compatible = "mediatek,mt7620-gpio" },
+	{ }
+};
+
+U_BOOT_DRIVER(mt7620_gpio) = {
+	.name	= "mt7620_gpio",
+	.id	= UCLASS_GPIO,
+	.ops	= &mt7620_gpio_ops,
+	.of_match = mt7620_gpio_ids,
+	.probe	= mt7620_gpio_probe,
+	.ofdata_to_platdata = mt7620_gpio_ofdata_to_platdata,
+	.priv_auto_alloc_size = sizeof(struct mt7620_gpio_priv),
+};
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 16/21] spi: add spi controller support for MediaTek MT7620 SoC
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (14 preceding siblings ...)
  2020-10-30  9:34 ` [PATCH v2 15/21] gpio: add GPIO controller " Weijie Gao
@ 2020-10-30  9:35 ` Weijie Gao
  2020-11-02  6:00   ` Jagan Teki
  2020-10-30  9:35 ` [PATCH v2 17/21] phy: add USB PHY driver " Weijie Gao
                   ` (4 subsequent siblings)
  20 siblings, 1 reply; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:35 UTC (permalink / raw)
  To: u-boot

This patch adds spi controller support for MediaTek MT7620 SoC.

The SPI controller supports two chip selects. These two chip selects are
implemented as two separate register groups, but they share the same bus
(DI/DO/CLK), only CS pins are dedicated for each register group.
Appearently these two register groups cannot operates simulataneously so
they are implemented as one controller.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 drivers/spi/Kconfig      |   7 +
 drivers/spi/Makefile     |   1 +
 drivers/spi/mt7620_spi.c | 277 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 285 insertions(+)
 create mode 100644 drivers/spi/mt7620_spi.c

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index f7a9852565..ec50d843ef 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -202,6 +202,13 @@ config MSCC_BB_SPI
 	  Enable MSCC bitbang SPI driver. This driver can be used on
 	  MSCC SOCs.
 
+config MT7620_SPI
+	bool "MediaTek MT7620 SPI driver"
+	depends on SOC_MT7620
+	help
+	  Enable the MT7620 SPI driver. This driver can be used to access
+	  generic SPI devices on MediaTek MT7620 SoC.
+
 config MT7621_SPI
 	bool "MediaTek MT7621 SPI driver"
 	depends on SOC_MT7628
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index d9b5bd9b79..bfd142d153 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
 obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
 obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 obj-$(CONFIG_MTK_SNFI_SPI) += mtk_snfi_spi.o
+obj-$(CONFIG_MT7620_SPI) += mt7620_spi.o
 obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
 obj-$(CONFIG_MSCC_BB_SPI) += mscc_bb_spi.o
 obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o
diff --git a/drivers/spi/mt7620_spi.c b/drivers/spi/mt7620_spi.c
new file mode 100644
index 0000000000..c0b3d1d8eb
--- /dev/null
+++ b/drivers/spi/mt7620_spi.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ *
+ * Generic SPI driver for MediaTek MT7620 SoC
+ */
+
+#include <clk.h>
+#include <dm.h>
+#include <spi.h>
+#include <linux/bitops.h>
+#include <linux/iopoll.h>
+#include <linux/io.h>
+#include <linux/log2.h>
+
+#define MT7620_SPI_NUM_CS	2
+#define MT7620_SPI_MASTER1_OFF	0x00
+#define MT7620_SPI_MASTER2_OFF	0x40
+
+/* SPI_STAT */
+#define   SPI_BUSY		BIT(0)
+
+/* SPI_CFG */
+#define   MSB_FIRST		BIT(8)
+#define   SPI_CLK_POL		BIT(6)
+#define   RX_CLK_EDGE		BIT(5)
+#define   TX_CLK_EDGE		BIT(4)
+#define   SPI_CLK_S		0
+#define   SPI_CLK_M		GENMASK(2, 0)
+
+/* SPI_CTL */
+#define   START_WR		BIT(2)
+#define   START_RD		BIT(1)
+#define   SPI_HIGH		BIT(0)
+
+#define SPI_ARB			0xf0
+#define   ARB_EN		BIT(31)
+
+struct mt7620_spi_master_regs {
+	u32 stat;
+	u32 reserved0[3];
+	u32 cfg;
+	u32 ctl;
+	u32 reserved1[2];
+	u32 data;
+};
+
+struct mt7620_spi {
+	void __iomem *regs;
+	struct mt7620_spi_master_regs *m[MT7620_SPI_NUM_CS];
+	unsigned int sys_freq;
+	u32 wait_us;
+	uint mode;
+	uint speed;
+};
+
+static void mt7620_spi_master_setup(struct mt7620_spi *ms, int cs)
+{
+	u32 rate, prescale, freq, tmo, cfg;
+
+	/* Calculate the clock divsior */
+	rate = DIV_ROUND_UP(ms->sys_freq, ms->speed);
+	rate = roundup_pow_of_two(rate);
+
+	prescale = ilog2(rate / 2);
+	if (prescale > 6)
+		prescale = 6;
+
+	/* Calculate the real clock, and usecs for one byte transaction */
+	freq = ms->sys_freq >> (prescale + 1);
+	tmo = DIV_ROUND_UP(8 * 1000000, freq);
+
+	/* 10 times tolerance plus 100us */
+	ms->wait_us = 10 * tmo + 100;
+
+	/* set SPI_CFG */
+	cfg = prescale << SPI_CLK_S;
+
+	switch (ms->mode & (SPI_CPOL | SPI_CPHA)) {
+	case SPI_MODE_0:
+		cfg |= TX_CLK_EDGE;
+		break;
+	case SPI_MODE_1:
+		cfg |= RX_CLK_EDGE;
+		break;
+	case SPI_MODE_2:
+		cfg |= SPI_CLK_POL | RX_CLK_EDGE;
+		break;
+	case SPI_MODE_3:
+		cfg |= SPI_CLK_POL | TX_CLK_EDGE;
+		break;
+	}
+
+	if (!(ms->mode & SPI_LSB_FIRST))
+		cfg |= MSB_FIRST;
+
+	writel(cfg, &ms->m[cs]->cfg);
+
+	writel(SPI_HIGH, &ms->m[cs]->ctl);
+}
+
+static void mt7620_spi_set_cs(struct mt7620_spi *ms, int cs, int enable)
+{
+	if (enable)
+		mt7620_spi_master_setup(ms, cs);
+
+	if (ms->mode & SPI_CS_HIGH)
+		enable = !enable;
+
+	if (enable)
+		clrbits_32(&ms->m[cs]->ctl, SPI_HIGH);
+	else
+		setbits_32(&ms->m[cs]->ctl, SPI_HIGH);
+}
+
+static int mt7620_spi_set_mode(struct udevice *bus, uint mode)
+{
+	struct mt7620_spi *ms = dev_get_priv(bus);
+
+	ms->mode = mode;
+
+	/* Mode 0 is buggy. Force to use mode 3 */
+	if ((mode & SPI_MODE_3) == SPI_MODE_0)
+		ms->mode |= SPI_MODE_3;
+
+	return 0;
+}
+
+static int mt7620_spi_set_speed(struct udevice *bus, uint speed)
+{
+	struct mt7620_spi *ms = dev_get_priv(bus);
+
+	ms->speed = speed;
+
+	return 0;
+}
+
+static inline int mt7620_spi_busy_poll(struct mt7620_spi *ms, int cs)
+{
+	u32 val;
+
+	return readl_poll_timeout(&ms->m[cs]->stat, val, !(val & SPI_BUSY),
+				  ms->wait_us);
+}
+
+static int mt7620_spi_read(struct mt7620_spi *ms, int cs, u8 *buf, size_t len)
+{
+	int ret;
+
+	while (len) {
+		setbits_32(&ms->m[cs]->ctl, START_RD);
+
+		ret = mt7620_spi_busy_poll(ms, cs);
+		if (ret) {
+			pr_err("SPI read transaction timeout\n");
+			return ret;
+		}
+
+		*buf++ = (u8)readl(&ms->m[cs]->data);
+
+		len--;
+	}
+
+	return 0;
+}
+
+static int mt7620_spi_write(struct mt7620_spi *ms, int cs, const u8 *buf,
+			    size_t len)
+{
+	int ret;
+
+	while (len) {
+		writel(*buf++, &ms->m[cs]->data);
+		setbits_32(&ms->m[cs]->ctl, START_WR);
+
+		ret = mt7620_spi_busy_poll(ms, cs);
+		if (ret) {
+			pr_err("SPI write transaction timeout\n");
+			return ret;
+		}
+
+		len--;
+	}
+
+	return 0;
+}
+
+static int mt7620_spi_xfer(struct udevice *dev, unsigned int bitlen,
+			   const void *dout, void *din, unsigned long flags)
+{
+	struct udevice *bus = dev->parent;
+	struct mt7620_spi *ms = dev_get_priv(bus);
+	int total_size = bitlen >> 3;
+	int cs, ret = 0;
+
+	/*
+	 * This driver only supports half-duplex, so complain and bail out
+	 * upon full-duplex messages
+	 */
+	if (dout && din) {
+		pr_err("Only half-duplex SPI transfer supported\n");
+		return -EIO;
+	}
+
+	cs = spi_chip_select(dev);
+	if (cs < 0 || cs >= MT7620_SPI_NUM_CS) {
+		pr_err("Invalid chip select %d\n", cs);
+		return -EINVAL;
+	}
+
+	if (flags & SPI_XFER_BEGIN)
+		mt7620_spi_set_cs(ms, cs, 1);
+
+	if (din)
+		ret = mt7620_spi_read(ms, cs, din, total_size);
+	else if (dout)
+		ret = mt7620_spi_write(ms, cs, dout, total_size);
+
+	if (flags & SPI_XFER_END)
+		mt7620_spi_set_cs(ms, cs, 0);
+
+	return ret;
+}
+
+static int mt7620_spi_probe(struct udevice *dev)
+{
+	struct mt7620_spi *ms = dev_get_priv(dev);
+	struct clk clk;
+	int ret;
+
+	ms->regs = dev_remap_addr(dev);
+	if (!ms->regs)
+		return -EINVAL;
+
+	ms->m[0] = ms->regs + MT7620_SPI_MASTER1_OFF;
+	ms->m[1] = ms->regs + MT7620_SPI_MASTER2_OFF;
+
+	ret = clk_get_by_index(dev, 0, &clk);
+	if (ret < 0) {
+		printf("Please provide a clock!\n");
+		return ret;
+	}
+
+	clk_enable(&clk);
+
+	ms->sys_freq = clk_get_rate(&clk);
+	if (!ms->sys_freq) {
+		printf("Please provide a valid bus clock!\n");
+		return -EINVAL;
+	}
+
+	writel(ARB_EN, ms->regs + SPI_ARB);
+
+	return 0;
+}
+
+static const struct dm_spi_ops mt7620_spi_ops = {
+	.set_mode = mt7620_spi_set_mode,
+	.set_speed = mt7620_spi_set_speed,
+	.xfer = mt7620_spi_xfer,
+};
+
+static const struct udevice_id mt7620_spi_ids[] = {
+	{ .compatible = "mediatek,mt7620-spi" },
+	{ }
+};
+
+U_BOOT_DRIVER(mt7620_spi) = {
+	.name = "mt7620_spi",
+	.id = UCLASS_SPI,
+	.of_match = mt7620_spi_ids,
+	.ops = &mt7620_spi_ops,
+	.priv_auto_alloc_size = sizeof(struct mt7620_spi),
+	.probe = mt7620_spi_probe,
+};
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 17/21] phy: add USB PHY driver for MediaTek MT7620 SoC
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (15 preceding siblings ...)
  2020-10-30  9:35 ` [PATCH v2 16/21] spi: add spi controller support " Weijie Gao
@ 2020-10-30  9:35 ` Weijie Gao
  2020-11-02  6:11   ` Jagan Teki
  2020-10-30  9:35 ` [PATCH v2 18/21] net: add ethernet " Weijie Gao
                   ` (3 subsequent siblings)
  20 siblings, 1 reply; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:35 UTC (permalink / raw)
  To: u-boot

This patch adds USB PHY driver for MediaTek MT7620 SoC

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 drivers/phy/Kconfig          |   7 +++
 drivers/phy/Makefile         |   1 +
 drivers/phy/mt7620-usb-phy.c | 113 +++++++++++++++++++++++++++++++++++
 3 files changed, 121 insertions(+)
 create mode 100644 drivers/phy/mt7620-usb-phy.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index d12a6b02ad..ab638f0e7d 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -218,6 +218,13 @@ config KEYSTONE_USB_PHY
 
 	  This PHY is found on some Keystone (K2) devices supporting USB.
 
+config MT7620_USB_PHY
+	bool "MediaTek MT7620 USB PHY support"
+	depends on PHY
+	depends on SOC_MT7620
+	help
+          Support the intergated USB PHY in MediaTek MT7620 SoC
+
 config MT76X8_USB_PHY
 	bool "MediaTek MT76x8 (7628/88) USB PHY support"
 	depends on PHY
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 45a7fe5b56..6b3761b8c8 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_MESON_G12A_USB_PHY) += meson-g12a-usb2.o meson-g12a-usb3-pcie.o
 obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
 obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o
 obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o
+obj-$(CONFIG_MT7620_USB_PHY) += mt7620-usb-phy.o
 obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o
 obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o
 obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
diff --git a/drivers/phy/mt7620-usb-phy.c b/drivers/phy/mt7620-usb-phy.c
new file mode 100644
index 0000000000..59ac32f327
--- /dev/null
+++ b/drivers/phy/mt7620-usb-phy.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <clk.h>
+#include <dm.h>
+#include <generic-phy.h>
+#include <misc.h>
+#include <reset.h>
+#include <dm/device_compat.h>
+#include <linux/delay.h>
+#include <mach/mt7620-sysc.h>
+
+struct mt7620_usb_phy {
+	struct udevice *dev;
+	struct udevice *sysc;
+	struct clk_bulk clocks;
+	struct reset_ctl_bulk resets;
+};
+
+static int mt7620_usb_phy_power_on(struct phy *_phy)
+{
+	struct mt7620_usb_phy *phy = dev_get_priv(_phy->dev);
+	u32 mode = MT7620_SYSC_USB_HOST_MODE;
+	int ret;
+
+	reset_deassert_bulk(&phy->resets);
+
+	clk_enable_bulk(&phy->clocks);
+
+	mdelay(10);
+
+	ret = misc_ioctl(phy->sysc, MT7620_SYSC_IOCTL_SET_USB_MODE, &mode);
+	if (ret) {
+		dev_err(phy->dev,
+			"mt7620_usbphy: failed to set USB host mode\n");
+		return ret;
+	}
+
+	mdelay(10);
+
+	return 0;
+}
+
+static int mt7620_usb_phy_power_off(struct phy *_phy)
+{
+	struct mt7620_usb_phy *phy = dev_get_priv(_phy->dev);
+
+	clk_disable_bulk(&phy->clocks);
+
+	reset_assert_bulk(&phy->resets);
+
+	return 0;
+}
+
+static int mt7620_usb_phy_probe(struct udevice *dev)
+{
+	struct mt7620_usb_phy *phy = dev_get_priv(dev);
+	struct ofnode_phandle_args sysc_args;
+	int ret;
+
+	ret = ofnode_parse_phandle_with_args(dev->node, "mediatek,sysc", NULL,
+					     0, 0, &sysc_args);
+	if (ret) {
+		dev_err(dev, "mt7620_usbphy: sysc property not found\n");
+		return ret;
+	}
+
+	ret = uclass_get_device_by_ofnode(UCLASS_MISC, sysc_args.node,
+					  &phy->sysc);
+	if (ret) {
+		dev_err(dev, "mt7620_usbphy: failed to sysc device\n");
+		return ret;
+	}
+
+	ret = clk_get_bulk(dev, &phy->clocks);
+	if (ret) {
+		dev_err(dev, "mt7620_usbphy: failed to get clocks\n");
+		return ret;
+	}
+
+	ret = reset_get_bulk(dev, &phy->resets);
+	if (ret) {
+		dev_err(dev, "mt7620_usbphy: failed to get reset control\n");
+		return ret;
+	}
+
+	phy->dev = dev;
+
+	return 0;
+}
+
+static struct phy_ops mt7620_usb_phy_ops = {
+	.power_on = mt7620_usb_phy_power_on,
+	.power_off = mt7620_usb_phy_power_off,
+};
+
+static const struct udevice_id mt7620_usb_phy_ids[] = {
+	{ .compatible = "mediatek,mt7620-usbphy" },
+	{ }
+};
+
+U_BOOT_DRIVER(mt7620_usb_phy) = {
+	.name		= "mt7620_usb_phy",
+	.id		= UCLASS_PHY,
+	.of_match	= mt7620_usb_phy_ids,
+	.ops		= &mt7620_usb_phy_ops,
+	.probe		= mt7620_usb_phy_probe,
+	.priv_auto_alloc_size = sizeof(struct mt7620_usb_phy),
+};
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 18/21] net: add ethernet driver for MediaTek MT7620 SoC
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (16 preceding siblings ...)
  2020-10-30  9:35 ` [PATCH v2 17/21] phy: add USB PHY driver " Weijie Gao
@ 2020-10-30  9:35 ` Weijie Gao
  2020-10-30  9:35 ` [PATCH v2 19/21] mmc: mtk-sd: add pad control settings for MediaTek MT7620/MT76x8 SoCs Weijie Gao
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:35 UTC (permalink / raw)
  To: u-boot

This patch adds  ethernet driver for MediaTek MT7620 SoC.

The MT7620 SoC has a built-in ethernet (Frame Engine) and a built-in
7-port switch and two xMII interfaces (can be MII/RMII/RGMII).

The port 0-3 of the switch connects to intergrited FE PHYs. Port 4 can be
configured to connect to either the intergrited FE PHY, or the xMII.
Port 5 always connects to the xMII. Port 6 is the CPU port.

This driver supports MT7530 giga switch connects to port 5.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 drivers/net/Kconfig      |   12 +
 drivers/net/Makefile     |    1 +
 drivers/net/mt7620-eth.c | 1222 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 1235 insertions(+)
 create mode 100644 drivers/net/mt7620-eth.c

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 3a5e036880..d1a52c7264 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -399,6 +399,18 @@ config MACB_ZYNQ
 	  The Cadence MACB ethernet interface was used on Zynq platform.
 	  Say Y to enable support for the MACB/GEM in Zynq chip.
 
+config MT7620_ETH
+	bool "MediaTek MT7620 Ethernet Interface"
+	depends on SOC_MT7620
+	select PHYLIB
+	select DM_RESET
+	select DM_GPIO
+	select CLK
+	help
+	  The MediaTek MT7620 ethernet interface is used on MT7620 based
+	  boards. It has a built-in switch with two configurable ports which
+	  can connect to external PHY/MACs.
+
 config MT7628_ETH
 	bool "MediaTek MT7628 Ethernet Interface"
 	depends on SOC_MT7628
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index e3bdda359d..f2a0df509d 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_MDIO_IPQ4019) += mdio-ipq4019.o
 obj-$(CONFIG_MDIO_MUX_I2CREG) += mdio_mux_i2creg.o
 obj-$(CONFIG_MDIO_MUX_SANDBOX) += mdio_mux_sandbox.o
 obj-$(CONFIG_MPC8XX_FEC) += mpc8xx_fec.o
+obj-$(CONFIG_MT7620_ETH) += mt7620-eth.o
 obj-$(CONFIG_MT7628_ETH) += mt7628-eth.o
 obj-$(CONFIG_MVGBE) += mvgbe.o
 obj-$(CONFIG_MVMDIO) += mvmdio.o
diff --git a/drivers/net/mt7620-eth.c b/drivers/net/mt7620-eth.c
new file mode 100644
index 0000000000..2c148a3b35
--- /dev/null
+++ b/drivers/net/mt7620-eth.c
@@ -0,0 +1,1222 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <cpu_func.h>
+#include <dm.h>
+#include <clk.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <misc.h>
+#include <net.h>
+#include <reset.h>
+#include <asm/addrspace.h>
+#include <asm/cache.h>
+#include <asm/gpio.h>
+#include <dm/device_compat.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/ethtool.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mdio.h>
+#include <linux/mii.h>
+#include <mach/mt7620-sysc.h>
+
+/* Frame Engine block */
+#define GDMA_BASE			0x600
+#define PDMA_BASE			0x800
+
+/* GDMA registers */
+#define GDMA_FWD_CFG			0x00
+#define GDMA_DST_PORT			GENMASK(2, 0)
+#define   GDMA_DST_PORT_CPU		0
+
+#define GDMA_MAC_ADRL			0x08
+#define GDMA_MAC_ADRH			0x0c
+
+/* PDMA registers */
+#define TX_BASE_PTR0			0x000
+#define TX_MAX_CNT0			0x004
+#define TX_CTX_IDX0			0x008
+#define TX_DTX_IDX0			0x00c
+#define RX_BASE_PTR0			0x100
+#define RX_MAX_CNT0			0x104
+#define RX_CALC_IDX0			0x108
+#define RX_DRX_IDX0			0x10c
+
+#define PDMA_GLO_CFG			0x204
+#define TX_WB_DDONE			BIT(6)
+#define PDMA_BT_SIZE			GENMASK(5, 4)
+#define   PDMA_BT_SIZE_32B		1
+#define RX_DMA_BUSY			BIT(3)
+#define RX_DMA_EN			BIT(2)
+#define TX_DMA_BUSY			BIT(1)
+#define TX_DMA_EN			BIT(0)
+
+#define PDMA_RST_IDX			0x208
+#define RST_DRX_IDX0			BIT(16)
+#define RST_DTX_IDX0			BIT(0)
+
+/* Built-in giga ethernet switch block */
+
+/* ARL registers */
+#define GSW_MFC				0x0010
+#define BC_FFP				GENMASK(31, 24)
+#define UNM_FFP				GENMASK(23, 16)
+#define UNU_FFP				GENMASK(15, 8)
+#define CPU_EN				BIT(7)
+#define CPU_PORT			GENMASK(6, 4)
+
+/* Port registers */
+#define GSW_PCR(p)			(0x2004 + (p) * 0x100)
+#define PORT_MATRIX			GENMASK(23, 16)
+
+#define GSW_PVC(p)			(0x2010 + (p) * 0x100)
+#define STAG_VPID			GENMASK(31, 16)
+#define VLAN_ATTR			GENMASK(7, 6)
+#define   VLAN_ATTR_USER		0
+
+/* MAC registers */
+#define GSW_PMCR(p)			(0x3000 + (p) * 0x100)
+#define IPG_CFG				GENMASK(19, 18)
+#define IPG_96BIT_WITH_SHORT_IPG	1
+#define MAC_MODE			BIT(16)
+#define FORCE_MODE			BIT(15)
+#define MAC_TX_EN			BIT(14)
+#define MAC_RX_EN			BIT(13)
+#define BKOFF_EN			BIT(9)
+#define BACKPR_EN			BIT(8)
+#define FORCE_EEE1G			BIT(7)
+#define FORCE_EEE100			BIT(6)
+#define FORCE_RX_FC			BIT(5)
+#define FORCE_TX_FC			BIT(4)
+#define FORCE_SPEED			GENMASK(3, 2)
+#define   FORCE_SPEED_1000		2
+#define   FORCE_SPEED_100		1
+#define   FORCE_SPEED_10		0
+#define FORCE_DUPLEX			BIT(1)
+#define FORCE_LINK			BIT(0)
+
+/* GMAC registers */
+#define GSW_PPSC			0x7000
+#define PHY_AP_EN			BIT(31)
+#define PHY_PRE_EN			BIT(30)
+#define PHY_MDC_CFG			GENMASK(29, 24)
+#define EPHY_AP_EN			BIT(23)
+#define EE_AN_EN			BIT(16)
+#define PHY_AP_END_ADDR			GENMASK(12, 8)
+#define PHY_AP_START_ADDR		GENMASK(4, 0)
+
+#define GSW_PIAC			0x7004
+#define PHY_ACS_ST			BIT(31)
+#define MDIO_REG_ADDR			GENMASK(29, 25)
+#define MDIO_PHY_ADDR			GENMASK(24, 20)
+#define MDIO_CMD			GENMASK(19, 18)
+#define   MDIO_CMD_WRITE		1
+#define   MDIO_CMD_READ			2
+#define MDIO_ST				GENMASK(17, 16)
+#define MDIO_RW_DATA			GENMASK(15, 0)
+
+#define GSW_GPC1			0x7014
+#define PHY_DIS				GENMASK(28, 24)
+#define PHY_BASE			GENMASK(20, 16)
+#define TX_CLK_MODE			BIT(3)
+#define RX_CLK_MODE			BIT(2)
+
+/* MII Registers for MDIO clause 45 indirect access */
+#define MII_MMD_ACC_CTL_REG		0x0d
+#define MMD_OP_MODE			GENMASK(15, 14)
+#define   MMD_ADDR			0
+#define   MMD_DATA			1
+#define   MMD_DATA_RW_POST_INC		2
+#define   MMD_DATA_W_POST_INC		3
+#define MMD_DEVAD			GENMASK(4, 0)
+
+#define MII_MMD_ADDR_DATA_REG		0x0e
+
+/* MT7530 internal register access */
+#define MT7530_REG_PAGE_ADDR		GENMASK(15, 6)
+#define MT7530_REG_ADDR			GENMASK(5, 2)
+
+/* MT7530 system control registers*/
+#define MT7530_SYS_CTRL			0x7000
+#define SW_SYS_RST			BIT(1)
+#define SW_REG_RST			BIT(0)
+
+#define MT7530_MHWTRAP			0x7804
+#define P5_INTF_SEL_GMAC5		BIT(13)
+#define P5_INTF_DIS			BIT(6)
+
+struct pdma_txd_info1 {
+	u32 SDP0;
+};
+
+struct pdma_txd_info2 {
+	u32 SDL1 : 14;
+	u32 LS1 : 1;
+	u32 BURST : 1;
+	u32 SDL0 : 14;
+	u32 LS0 : 1;
+	u32 DDONE : 1;
+};
+
+struct pdma_txd_info3 {
+	u32 SDP1;
+};
+
+struct pdma_txd_info4 {
+	u32 VPRI_VIDX : 8;
+	u32 SIDX : 4;
+	u32 INSP : 1;
+	u32 RESV : 2;
+	u32 UDF : 5;
+	u32 FP_BMAP : 8;
+	u32 TSO : 1;
+	u32 TUI_CO : 3;
+};
+
+struct pdma_tx_desc {
+	struct pdma_txd_info1 txd_info1;
+	struct pdma_txd_info2 txd_info2;
+	struct pdma_txd_info3 txd_info3;
+	struct pdma_txd_info4 txd_info4;
+};
+
+struct pdma_rxd_info1 {
+	u32 PDP0;
+};
+
+struct pdma_rxd_info2 {
+	u32 PLEN1 : 14;
+	u32 LS1 : 1;
+	u32 UN_USED : 1;
+	u32 PLEN0 : 14;
+	u32 LS0 : 1;
+	u32 DDONE : 1;
+};
+
+struct pdma_rxd_info3 {
+	u32 PDP1;
+};
+
+struct pdma_rxd_info4 {
+	u32 FOE_ENTRY : 14;
+	u32 CRSN : 5;
+	u32 SP : 3;
+	u32 L4F : 1;
+	u32 L4VLD : 1;
+	u32 TACK : 1;
+	u32 IP4F : 1;
+	u32 IP4 : 1;
+	u32 IP6 : 1;
+	u32 UN_USED : 4;
+};
+
+struct pdma_rx_desc {
+	struct pdma_rxd_info1 rxd_info1;
+	struct pdma_rxd_info2 rxd_info2;
+	struct pdma_rxd_info3 rxd_info3;
+	struct pdma_rxd_info4 rxd_info4;
+};
+
+struct mt7620_gsw_port_cfg {
+	phy_interface_t mode;
+	bool force_mode;
+	bool duplex;
+	u32 speed;
+	int phy_addr;
+};
+
+struct mt7620_eth_priv {
+	struct udevice *dev;
+
+	void __iomem *fe_base;
+	void __iomem *gsw_base;
+
+	struct mii_dev *mdio_bus;
+
+	struct pdma_tx_desc *tx_ring_noc;
+	struct pdma_rx_desc *rx_ring_noc;
+
+	int rx_dma_owner_idx0;
+	int tx_cpu_owner_idx0;
+
+	void *pkt_buf;
+	void *tx_ring;
+	void *rx_ring;
+
+	struct reset_ctl_bulk rsts;
+	struct clk_bulk clks;
+
+	struct udevice *sysc;
+
+	u32 ephy_num;
+	bool port5_mt7530;
+	struct gpio_desc gpio_swrst;
+	struct mt7620_gsw_port_cfg port_cfg[3];
+};
+
+#define PDMA_TIMEOUT			100000
+
+#define NUM_TX_DESC			64
+#define NUM_RX_DESC			128
+#define NUM_FE_PHYS			5
+#define NUM_PORTS			7
+#define CPU_PORT_NUM			6
+
+#define NUM_MT7530_PHYS			5
+
+static void pdma_write(struct mt7620_eth_priv *priv, u32 reg, u32 val)
+{
+	writel(val, priv->fe_base + PDMA_BASE + reg);
+}
+
+static void gdma_write(struct mt7620_eth_priv *priv, u32 reg, u32 val)
+{
+	writel(val, priv->fe_base + GDMA_BASE + reg);
+}
+
+static void gdma_rmw(struct mt7620_eth_priv *priv, u32 reg, u32 clr, u32 set)
+{
+	clrsetbits_le32(priv->fe_base + GDMA_BASE + reg, clr, set);
+}
+
+static u32 gsw_read(struct mt7620_eth_priv *priv, u32 reg)
+{
+	return readl(priv->gsw_base + reg);
+}
+
+static void gsw_write(struct mt7620_eth_priv *priv, u32 reg, u32 val)
+{
+	writel(val, priv->gsw_base + reg);
+}
+
+static void gsw_rmw(struct mt7620_eth_priv *priv, u32 reg, u32 clr, u32 set)
+{
+	clrsetbits_le32(priv->gsw_base + reg, clr, set);
+}
+
+static int mt7620_mdio_rw(struct mt7620_eth_priv *priv, u32 phy, u32 reg,
+			  u32 data, u32 cmd)
+{
+	int ret;
+	u32 val;
+
+	val = FIELD_PREP(MDIO_ST, 1) | FIELD_PREP(MDIO_CMD, cmd) |
+	      FIELD_PREP(MDIO_PHY_ADDR, phy) |
+	      FIELD_PREP(MDIO_REG_ADDR, reg);
+
+	if (cmd == MDIO_CMD_WRITE)
+		val |= FIELD_PREP(MDIO_RW_DATA, data);
+
+	gsw_write(priv, GSW_PIAC, val);
+	gsw_write(priv, GSW_PIAC, val | PHY_ACS_ST);
+
+	ret = readl_poll_timeout(priv->gsw_base + GSW_PIAC, val,
+				 !(val & PHY_ACS_ST), 10000);
+	if (ret) {
+		dev_err(priv->dev, "mt7620_eth: MDIO access timeout\n");
+		return ret;
+	}
+
+	if (cmd == MDIO_CMD_READ) {
+		val = gsw_read(priv, GSW_PIAC);
+		return FIELD_GET(MDIO_RW_DATA, val);
+	}
+
+	return 0;
+}
+
+static int mt7620_mii_read(struct mt7620_eth_priv *priv, u32 phy, u32 reg)
+{
+	return mt7620_mdio_rw(priv, phy, reg, 0, MDIO_CMD_READ);
+}
+
+static int mt7620_mii_write(struct mt7620_eth_priv *priv, u32 phy, u32 reg,
+			    u16 val)
+{
+	return mt7620_mdio_rw(priv, phy, reg, val, MDIO_CMD_WRITE);
+}
+
+static int mt7620_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+	struct mt7620_eth_priv *priv = bus->priv;
+	int ret;
+
+	if (devad < 0)
+		return mt7620_mdio_rw(priv, addr, reg, 0, MDIO_CMD_READ);
+
+	ret = mt7620_mdio_rw(priv, addr, MII_MMD_ACC_CTL_REG,
+			     FIELD_PREP(MMD_OP_MODE, MMD_ADDR) |
+			     FIELD_PREP(MMD_DEVAD, devad), MDIO_CMD_WRITE);
+	if (ret)
+		return ret;
+
+	ret = mt7620_mdio_rw(priv, addr, MII_MMD_ADDR_DATA_REG, reg,
+			     MDIO_CMD_WRITE);
+	if (ret)
+		return ret;
+
+	ret = mt7620_mdio_rw(priv, addr, MII_MMD_ACC_CTL_REG,
+			     FIELD_PREP(MMD_OP_MODE, MMD_DATA) |
+			     FIELD_PREP(MMD_DEVAD, devad), MDIO_CMD_WRITE);
+	if (ret)
+		return ret;
+
+	return mt7620_mdio_rw(priv, addr, MII_MMD_ADDR_DATA_REG, 0,
+			      MDIO_CMD_READ);
+}
+
+static int mt7620_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
+			     u16 val)
+{
+	struct mt7620_eth_priv *priv = bus->priv;
+	int ret;
+
+	if (devad < 0)
+		return mt7620_mdio_rw(priv, addr, reg, val, MDIO_CMD_WRITE);
+
+	ret = mt7620_mdio_rw(priv, addr, MII_MMD_ACC_CTL_REG,
+			     FIELD_PREP(MMD_OP_MODE, MMD_ADDR) |
+			     FIELD_PREP(MMD_DEVAD, devad), MDIO_CMD_WRITE);
+	if (ret)
+		return ret;
+
+	ret = mt7620_mdio_rw(priv, addr, MII_MMD_ADDR_DATA_REG, reg,
+			     MDIO_CMD_WRITE);
+	if (ret)
+		return ret;
+
+	ret = mt7620_mdio_rw(priv, addr, MII_MMD_ACC_CTL_REG,
+			     FIELD_PREP(MMD_OP_MODE, MMD_DATA) |
+			     FIELD_PREP(MMD_DEVAD, devad), MDIO_CMD_WRITE);
+	if (ret)
+		return ret;
+
+	return mt7620_mdio_rw(priv, addr, MII_MMD_ADDR_DATA_REG, val,
+			      MDIO_CMD_WRITE);
+}
+
+static int mt7620_mdio_register(struct udevice *dev)
+{
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+	struct mii_dev *mdio_bus = mdio_alloc();
+	int ret;
+
+	if (!mdio_bus)
+		return -ENOMEM;
+
+	mdio_bus->read = mt7620_mdio_read;
+	mdio_bus->write = mt7620_mdio_write;
+	snprintf(mdio_bus->name, sizeof(mdio_bus->name), dev->name);
+
+	mdio_bus->priv = (void *)priv;
+
+	ret = mdio_register(mdio_bus);
+
+	if (ret)
+		return ret;
+
+	priv->mdio_bus = mdio_bus;
+
+	return 0;
+}
+
+static int mt7530_reg_read(struct mt7620_eth_priv *priv, u32 reg, u32 *data)
+{
+	int ret, low_word, high_word;
+
+	/* Write page address */
+	ret = mt7620_mii_write(priv, 0x1f, 0x1f,
+			       FIELD_GET(MT7530_REG_PAGE_ADDR, reg));
+	if (ret)
+		return ret;
+
+	/* Read low word */
+	low_word = mt7620_mii_read(priv, 0x1f, FIELD_GET(MT7530_REG_ADDR, reg));
+	if (low_word < 0)
+		return low_word;
+
+	/* Read high word */
+	high_word = mt7620_mii_read(priv, 0x1f, 0x10);
+	if (high_word < 0)
+		return high_word;
+
+	if (data)
+		*data = ((u32)high_word << 16) | ((u32)low_word & 0xffff);
+
+	return 0;
+}
+
+static int mt7530_reg_write(struct mt7620_eth_priv *priv, u32 reg, u32 data)
+{
+	int ret;
+
+	/* Write page address */
+	ret = mt7620_mii_write(priv, 0x1f, 0x1f,
+			       FIELD_GET(MT7530_REG_PAGE_ADDR, reg));
+	if (ret)
+		return ret;
+
+	/* Write low word */
+	ret = mt7620_mii_write(priv, 0x1f, FIELD_GET(MT7530_REG_ADDR, reg),
+			       data & 0xffff);
+	if (ret)
+		return ret;
+
+	/* Write high word */
+	return mt7620_mii_write(priv, 0x1f, 0x10, data >> 16);
+}
+
+static void mt7620_phy_restart_an(struct mt7620_eth_priv *priv, u32 phy)
+{
+	u16 val;
+
+	val = mt7620_mii_read(priv, phy, MII_BMCR);
+	val |= BMCR_ANRESTART;
+	mt7620_mii_write(priv, phy, MII_BMCR, val);
+}
+
+static void mt7620_gsw_ephy_init(struct mt7620_eth_priv *priv)
+{
+	struct mt7620_sysc_chip_rev chip_rev;
+	int ret;
+	u32 i;
+
+	ret = misc_ioctl(priv->sysc, MT7620_SYSC_IOCTL_GET_CHIP_REV, &chip_rev);
+	if (ret) {
+		/* Assume MT7620A if misc_ioctl() failed */
+		dev_warn(priv->dev, "mt7620_eth: failed to get chip rev\n");
+		chip_rev.bga = 1;
+	}
+
+	 /* global, page 4 */
+	mt7620_mii_write(priv, 1, 31, 0x4000);
+	mt7620_mii_write(priv, 1, 17, 0x7444);
+
+	if (chip_rev.bga)
+		mt7620_mii_write(priv, 1, 19, 0x0114);
+	else
+		mt7620_mii_write(priv, 1, 19, 0x0117);
+
+	mt7620_mii_write(priv, 1, 22, 0x10cf);
+	mt7620_mii_write(priv, 1, 25, 0x6212);
+	mt7620_mii_write(priv, 1, 26, 0x0777);
+	mt7620_mii_write(priv, 1, 29, 0x4000);
+	mt7620_mii_write(priv, 1, 28, 0xc077);
+	mt7620_mii_write(priv, 1, 24, 0x0000);
+
+	/* global, page 3 */
+	mt7620_mii_write(priv, 1, 31, 0x3000);
+	mt7620_mii_write(priv, 1, 17, 0x4838);
+
+	/* global, page 2 */
+	mt7620_mii_write(priv, 1, 31, 0x2000);
+
+	if (chip_rev.bga) {
+		mt7620_mii_write(priv, 1, 21, 0x0515);
+		mt7620_mii_write(priv, 1, 22, 0x0053);
+		mt7620_mii_write(priv, 1, 23, 0x00bf);
+		mt7620_mii_write(priv, 1, 24, 0x0aaf);
+		mt7620_mii_write(priv, 1, 25, 0x0fad);
+		mt7620_mii_write(priv, 1, 26, 0x0fc1);
+	} else {
+		mt7620_mii_write(priv, 1, 21, 0x0517);
+		mt7620_mii_write(priv, 1, 22, 0x0fd2);
+		mt7620_mii_write(priv, 1, 23, 0x00bf);
+		mt7620_mii_write(priv, 1, 24, 0x0aab);
+		mt7620_mii_write(priv, 1, 25, 0x00ae);
+		mt7620_mii_write(priv, 1, 26, 0x0fff);
+	}
+
+	/*  global, page 1 */
+	mt7620_mii_write(priv, 1, 31, 0x1000);
+	mt7620_mii_write(priv, 1, 17, 0xe7f8);
+
+	/* local, page 0 */
+	mt7620_mii_write(priv, 1, 31, 0x8000);
+	for (i = 0; i < priv->ephy_num; i++)
+		mt7620_mii_write(priv, i, 30, 0xa000);
+
+	for (i = 0; i < priv->ephy_num; i++)
+		mt7620_mii_write(priv, i, 4, 0x05e1);
+
+	/* local, page 2 */
+	mt7620_mii_write(priv, 1, 31, 0xa000);
+	mt7620_mii_write(priv, 0, 16, 0x1111);
+	mt7620_mii_write(priv, 1, 16, 0x1010);
+	mt7620_mii_write(priv, 2, 16, 0x1515);
+	mt7620_mii_write(priv, 3, 16, 0x0f0f);
+	if (priv->ephy_num == NUM_FE_PHYS)
+		mt7620_mii_write(priv, 4, 16, 0x1313);
+
+	/* Restart auto-negotiation */
+	for (i = 0; i < priv->ephy_num; i++)
+		mt7620_phy_restart_an(priv, i);
+
+	if (priv->port_cfg[0].phy_addr > 0)
+		mt7620_phy_restart_an(priv, priv->port_cfg[0].phy_addr);
+
+	if (priv->port_cfg[1].phy_addr > 0)
+		mt7620_phy_restart_an(priv, priv->port_cfg[1].phy_addr);
+}
+
+static int mt7620_setup_gmac_mode(struct mt7620_eth_priv *priv, u32 gmac,
+				  phy_interface_t mode)
+{
+	enum mt7620_sysc_ge_mode ge_mode;
+	unsigned long req;
+	int ret;
+
+	switch (gmac) {
+	case 1:
+		req = MT7620_SYSC_IOCTL_SET_GE1_MODE;
+		break;
+	case 2:
+		req = MT7620_SYSC_IOCTL_SET_GE2_MODE;
+		break;
+	default:
+		/* Should not reach here */
+		return -EINVAL;
+	}
+
+	switch (mode) {
+	case PHY_INTERFACE_MODE_MII:
+		ge_mode = MT7620_SYSC_GE_MII;
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		ge_mode = MT7620_SYSC_GE_RMII;
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+		ge_mode = MT7620_SYSC_GE_RGMII;
+		break;
+	case PHY_INTERFACE_MODE_NONE:
+		if (gmac == 2)
+			ge_mode = MT7620_SYSC_GE_ESW_PHY;
+		else
+			ge_mode = MT7620_SYSC_GE_RGMII;
+		break;
+	default:
+		/* Should not reach here */
+		return -EINVAL;
+	}
+
+	ret = misc_ioctl(priv->sysc, req, &ge_mode);
+	if (ret)
+		dev_warn(priv->dev, "mt7620_eth: failed to set GE%u mode\n",
+			 gmac);
+
+	return 0;
+}
+
+static void mt7620_gsw_setup_port(struct mt7620_eth_priv *priv, u32 port,
+				  struct mt7620_gsw_port_cfg *port_cfg)
+{
+	u32 pmcr;
+
+	if (port_cfg->mode == PHY_INTERFACE_MODE_NONE) {
+		if (port == 5) {
+			gsw_write(priv, GSW_PMCR(port), FORCE_MODE);
+			return;
+		}
+
+		port_cfg->force_mode = port == CPU_PORT_NUM ? true : false;
+	}
+
+	pmcr = FIELD_PREP(IPG_CFG, IPG_96BIT_WITH_SHORT_IPG) | MAC_MODE |
+	       MAC_TX_EN | MAC_RX_EN | BKOFF_EN | BACKPR_EN;
+
+	if (port_cfg->force_mode) {
+		pmcr |= FORCE_MODE | FORCE_RX_FC | FORCE_TX_FC |
+			FIELD_PREP(FORCE_SPEED, port_cfg->speed) | FORCE_LINK;
+
+		if (port_cfg->duplex)
+			pmcr |= FORCE_DUPLEX;
+	}
+
+	gsw_write(priv, GSW_PMCR(port), pmcr);
+}
+
+static void mt7620_gsw_set_port_isolation(struct mt7620_eth_priv *priv)
+{
+	u32 i;
+
+	for (i = 0; i < NUM_PORTS; i++) {
+		/* Set port matrix mode */
+		if (i != CPU_PORT_NUM)
+			gsw_write(priv, GSW_PCR(i),
+				  FIELD_PREP(PORT_MATRIX, 0x40));
+		else
+			gsw_write(priv, GSW_PCR(i),
+				  FIELD_PREP(PORT_MATRIX, 0x3f));
+
+		/* Set port mode to user port */
+		gsw_write(priv, GSW_PVC(i), FIELD_PREP(STAG_VPID, 0x8100) |
+			  FIELD_PREP(VLAN_ATTR, VLAN_ATTR_USER));
+	}
+}
+
+static void mt7620_gsw_setup_phy_polling(struct mt7620_eth_priv *priv)
+{
+	int phy_addr_st, phy_addr_end;
+
+	if (priv->port_cfg[0].mode == PHY_INTERFACE_MODE_NONE)
+		priv->ephy_num = NUM_FE_PHYS;
+	else
+		priv->ephy_num = NUM_FE_PHYS - 1;
+
+	if (priv->port_cfg[0].phy_addr < 0 && priv->port_cfg[1].phy_addr < 0)
+		return;
+
+	if (priv->port_cfg[0].phy_addr > 0 && priv->port_cfg[1].phy_addr > 0) {
+		phy_addr_st = priv->port_cfg[0].phy_addr;
+		phy_addr_end = priv->port_cfg[1].phy_addr;
+	} else if (priv->port_cfg[0].phy_addr > 0) {
+		phy_addr_st = priv->port_cfg[0].phy_addr;
+		phy_addr_end = priv->port_cfg[0].phy_addr + 1;
+	} else {
+		phy_addr_st = 4;
+		phy_addr_end = priv->port_cfg[1].phy_addr;
+	}
+
+	gsw_rmw(priv, GSW_PPSC, PHY_AP_END_ADDR | PHY_AP_START_ADDR,
+		PHY_AP_EN | FIELD_PREP(PHY_AP_START_ADDR, phy_addr_st) |
+		FIELD_PREP(PHY_AP_END_ADDR, phy_addr_end));
+}
+
+static void mt7530_gsw_set_port_isolation(struct mt7620_eth_priv *priv)
+{
+	u32 i;
+
+	for (i = 0; i < NUM_PORTS; i++) {
+		/* Set port matrix mode */
+		if (i != CPU_PORT_NUM)
+			mt7530_reg_write(priv, GSW_PCR(i),
+					 FIELD_PREP(PORT_MATRIX, 0x40));
+		else
+			mt7530_reg_write(priv, GSW_PCR(i),
+					 FIELD_PREP(PORT_MATRIX, 0x3f));
+
+		/* Set port mode to user port */
+		mt7530_reg_write(priv, GSW_PVC(i),
+				 FIELD_PREP(STAG_VPID, 0x8100) |
+				 FIELD_PREP(VLAN_ATTR, VLAN_ATTR_USER));
+	}
+}
+
+static void mt7620_gsw_config_mt7530(struct mt7620_eth_priv *priv)
+{
+	u16 phy_val;
+	u32 i, val;
+
+	/* Disable internal PHY, set PHY base to 12 */
+	gsw_write(priv, GSW_GPC1, PHY_DIS | FIELD_PREP(PHY_BASE, 12) |
+		  TX_CLK_MODE | RX_CLK_MODE);
+
+	/* MT7530 reset deassert */
+	dm_gpio_set_value(&priv->gpio_swrst, 1);
+	mdelay(1000);
+
+	/* Turn off PHYs */
+	for (i = 0; i < NUM_MT7530_PHYS; i++) {
+		phy_val = mt7620_mii_read(priv, i, MII_BMCR);
+		phy_val |= BMCR_PDOWN;
+		mt7620_mii_write(priv, i, MII_BMCR, phy_val);
+	}
+
+	/* Force MAC link down before reset */
+	mt7530_reg_write(priv, GSW_PMCR(5), FORCE_MODE);
+	mt7530_reg_write(priv, GSW_PMCR(6), FORCE_MODE);
+
+	/* MT7530 soft reset */
+	mt7530_reg_write(priv, MT7530_SYS_CTRL, SW_SYS_RST | SW_REG_RST);
+	udelay(100);
+
+	/* MT7530 port6 force to 1G (connects to MT7620 GSW port5) */
+	mt7530_reg_write(priv, GSW_PMCR(6),
+			 FIELD_PREP(IPG_CFG, IPG_96BIT_WITH_SHORT_IPG) |
+			 MAC_MODE | FORCE_MODE | MAC_TX_EN | MAC_RX_EN |
+			 BKOFF_EN | BACKPR_EN | FORCE_RX_FC | FORCE_TX_FC |
+			 FIELD_PREP(FORCE_SPEED, FORCE_SPEED_1000) |
+			 FORCE_DUPLEX | FORCE_LINK);
+
+	/* Disable MT7530 port5 */
+	mt7530_reg_read(priv, MT7530_MHWTRAP, &val);
+	val |= P5_INTF_SEL_GMAC5 | P5_INTF_DIS;
+	mt7530_reg_write(priv, MT7530_MHWTRAP, val);
+
+	/* Isolate each ports */
+	mt7530_gsw_set_port_isolation(priv);
+
+	/* Turn on PHYs */
+	for (i = 0; i < NUM_MT7530_PHYS; i++) {
+		phy_val = mt7620_mii_read(priv, i, MII_BMCR);
+		phy_val &= ~BMCR_PDOWN;
+		mt7620_mii_write(priv, i, MII_BMCR, phy_val);
+	}
+	/* Restart auto-negotiation */
+	for (i = 0; i < NUM_MT7530_PHYS; i++)
+		mt7620_phy_restart_an(priv, i);
+}
+
+static void mt7620_gsw_init(struct mt7620_eth_priv *priv)
+{
+	/* If port5 connects to MT7530 Giga-switch, reset it first */
+	if (priv->port5_mt7530)
+		dm_gpio_set_value(&priv->gpio_swrst, 0);
+
+	/* Set forward control  */
+	gsw_write(priv, GSW_MFC, FIELD_PREP(BC_FFP, 0x7f) |
+		  FIELD_PREP(UNM_FFP, 0x7f) | FIELD_PREP(UNU_FFP, 0x7f) |
+		  CPU_EN | FIELD_PREP(CPU_PORT, CPU_PORT_NUM));
+
+	/* Set GMAC mode (GMAC1 -> Port5, GMAC2 -> Port4) */
+	mt7620_setup_gmac_mode(priv, 1, priv->port_cfg[1].mode);
+	mt7620_setup_gmac_mode(priv, 2, priv->port_cfg[0].mode);
+
+	/* port_cfg[2] is CPU port */
+	priv->port_cfg[2].force_mode = true;
+	priv->port_cfg[2].duplex = true;
+	priv->port_cfg[2].speed = FORCE_SPEED_1000;
+
+	/* Configure GSW MAC port */
+	mt7620_gsw_setup_port(priv, 4, &priv->port_cfg[0]);
+	mt7620_gsw_setup_port(priv, 5, &priv->port_cfg[1]);
+	mt7620_gsw_setup_port(priv, 6, &priv->port_cfg[2]);
+
+	/* Isolate each port */
+	mt7620_gsw_set_port_isolation(priv);
+
+	/* Polling external phy if exists */
+	mt7620_gsw_setup_phy_polling(priv);
+
+	/* Configure ephy */
+	mt7620_gsw_ephy_init(priv);
+
+	/* If port5 connects to MT7530 Giga-switch, do initialization */
+	if (priv->port5_mt7530)
+		mt7620_gsw_config_mt7530(priv);
+}
+
+static void mt7620_eth_fifo_init(struct mt7620_eth_priv *priv)
+{
+	uintptr_t pkt_base = (uintptr_t)priv->pkt_buf;
+	int i;
+
+	memset(priv->tx_ring, 0, NUM_TX_DESC * sizeof(struct pdma_tx_desc));
+	memset(priv->rx_ring, 0, NUM_RX_DESC * sizeof(struct pdma_rx_desc));
+	memset(priv->pkt_buf, 0, (NUM_TX_DESC + NUM_RX_DESC) * PKTSIZE_ALIGN);
+
+	priv->tx_ring_noc = (void *)CKSEG1ADDR((uintptr_t)priv->tx_ring);
+	priv->rx_ring_noc = (void *)CKSEG1ADDR((uintptr_t)priv->rx_ring);
+	priv->rx_dma_owner_idx0 = 0;
+	priv->tx_cpu_owner_idx0 = 0;
+
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		priv->tx_ring_noc[i].txd_info2.LS0 = 1;
+		priv->tx_ring_noc[i].txd_info2.DDONE = 1;
+		priv->tx_ring_noc[i].txd_info4.FP_BMAP = GDMA_DST_PORT_CPU;
+		priv->tx_ring_noc[i].txd_info1.SDP0 = CPHYSADDR(pkt_base);
+		pkt_base += PKTSIZE_ALIGN;
+	}
+
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		priv->rx_ring_noc[i].rxd_info2.PLEN0 = PKTSIZE_ALIGN;
+		priv->rx_ring_noc[i].rxd_info1.PDP0 = CPHYSADDR(pkt_base);
+		pkt_base += PKTSIZE_ALIGN;
+	}
+
+	pdma_write(priv, TX_BASE_PTR0, CPHYSADDR(priv->tx_ring_noc));
+	pdma_write(priv, TX_MAX_CNT0, NUM_TX_DESC);
+	pdma_write(priv, TX_CTX_IDX0, priv->tx_cpu_owner_idx0);
+
+	pdma_write(priv, RX_BASE_PTR0, CPHYSADDR(priv->rx_ring_noc));
+	pdma_write(priv, RX_MAX_CNT0, NUM_RX_DESC);
+	pdma_write(priv, RX_CALC_IDX0, NUM_RX_DESC - 1);
+
+	pdma_write(priv, PDMA_RST_IDX, RST_DTX_IDX0 | RST_DRX_IDX0);
+}
+
+static int mt7620_eth_start(struct udevice *dev)
+{
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+
+	mt7620_eth_fifo_init(priv);
+
+	gdma_rmw(priv, GDMA_FWD_CFG, GDMA_DST_PORT,
+		 FIELD_PREP(GDMA_DST_PORT, GDMA_DST_PORT_CPU));
+
+	pdma_write(priv, PDMA_GLO_CFG,
+		   FIELD_PREP(PDMA_BT_SIZE, PDMA_BT_SIZE_32B) |
+		   TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN);
+	udelay(500);
+
+	return 0;
+}
+
+static void mt7620_eth_stop(struct udevice *dev)
+{
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+	u32 val;
+	int ret;
+
+	pdma_write(priv, PDMA_GLO_CFG,
+		   FIELD_PREP(PDMA_BT_SIZE, PDMA_BT_SIZE_32B));
+	udelay(500);
+
+	ret = readl_poll_timeout(priv->fe_base + PDMA_BASE + PDMA_GLO_CFG,
+				 val, !(val & (RX_DMA_BUSY | TX_DMA_BUSY)),
+				 PDMA_TIMEOUT);
+	if (ret)
+		dev_warn(dev, "mt7620_eth: PDMA is still busy\n");
+}
+
+static int mt7620_eth_write_hwaddr(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+	unsigned char *mac = pdata->enetaddr;
+	u32 macaddr_lsb, macaddr_msb;
+
+	macaddr_msb = ((u32)mac[0] << 8) | (u32)mac[1];
+	macaddr_lsb = ((u32)mac[2] << 24) | ((u32)mac[3] << 16) |
+		      ((u32)mac[4] << 8) | (u32)mac[5];
+
+	gdma_write(priv, GDMA_MAC_ADRH, macaddr_msb);
+	gdma_write(priv, GDMA_MAC_ADRL, macaddr_lsb);
+
+	return 0;
+}
+
+static int mt7620_eth_send(struct udevice *dev, void *packet, int length)
+{
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+	u32 idx = priv->tx_cpu_owner_idx0;
+	void *pkt_base;
+
+	if (!priv->tx_ring_noc[idx].txd_info2.DDONE) {
+		printf("mt7620_eth: TX DMA descriptor ring is full\n");
+		return -EPERM;
+	}
+
+	pkt_base = (void *)CKSEG0ADDR(priv->tx_ring_noc[idx].txd_info1.SDP0);
+	memcpy(pkt_base, packet, length);
+	flush_dcache_range((ulong)pkt_base, (ulong)pkt_base + length);
+
+	priv->tx_ring_noc[idx].txd_info2.SDL0 = length;
+	priv->tx_ring_noc[idx].txd_info2.DDONE = 0;
+
+	priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC;
+	pdma_write(priv, TX_CTX_IDX0, priv->tx_cpu_owner_idx0);
+
+	return 0;
+}
+
+static int mt7620_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+	u32 idx = priv->rx_dma_owner_idx0, length;
+	uchar *pkt_base;
+
+	if (!priv->rx_ring_noc[idx].rxd_info2.DDONE) {
+		debug("mt7620_eth: RX DMA descriptor ring is empty\n");
+		return -EAGAIN;
+	}
+
+	length = priv->rx_ring_noc[idx].rxd_info2.PLEN0;
+	pkt_base = (void *)CKSEG0ADDR(priv->rx_ring_noc[idx].rxd_info1.PDP0);
+	invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base + length);
+
+	if (packetp)
+		*packetp = pkt_base;
+
+	return length;
+}
+
+static int mt7620_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+	u32 idx = priv->rx_dma_owner_idx0;
+
+	priv->rx_ring_noc[idx].rxd_info2.DDONE = 0;
+	priv->rx_ring_noc[idx].rxd_info2.LS0 = 0;
+	priv->rx_ring_noc[idx].rxd_info2.PLEN0 = PKTSIZE_ALIGN;
+
+	pdma_write(priv, RX_CALC_IDX0, idx);
+	priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC;
+
+	return 0;
+}
+
+static const struct eth_ops mt7620_eth_ops = {
+	.start = mt7620_eth_start,
+	.stop = mt7620_eth_stop,
+	.send = mt7620_eth_send,
+	.recv = mt7620_eth_recv,
+	.free_pkt = mt7620_eth_free_pkt,
+	.write_hwaddr = mt7620_eth_write_hwaddr,
+};
+
+static int mt7620_eth_alloc_rings_pkts(struct mt7620_eth_priv *priv)
+{
+	priv->tx_ring = memalign(ARCH_DMA_MINALIGN,
+				 NUM_TX_DESC * sizeof(struct pdma_tx_desc));
+	if (!priv->tx_ring) {
+		dev_err(priv->dev, "mt7620_eth: unable to alloc tx ring\n");
+		return -ENOMEM;
+	}
+
+	priv->rx_ring = memalign(ARCH_DMA_MINALIGN,
+				 NUM_RX_DESC * sizeof(struct pdma_rx_desc));
+	if (!priv->rx_ring) {
+		dev_err(priv->dev, "mt7620_eth: unable to alloc rx ring\n");
+		goto cleanup;
+	}
+
+	priv->pkt_buf = memalign(ARCH_DMA_MINALIGN,
+				 (NUM_TX_DESC + NUM_RX_DESC) * PKTSIZE_ALIGN);
+	if (!priv->pkt_buf) {
+		dev_err(priv->dev, "mt7620_eth: unable to alloc pkt buffer\n");
+		goto cleanup;
+	}
+
+	return 0;
+
+cleanup:
+	if (priv->tx_ring)
+		free(priv->tx_ring);
+
+	if (priv->rx_ring)
+		free(priv->rx_ring);
+
+	return -ENOMEM;
+}
+
+static void mt7620_eth_free_rings_pkts(struct mt7620_eth_priv *priv)
+{
+	free(priv->tx_ring);
+	free(priv->rx_ring);
+	free(priv->pkt_buf);
+}
+
+static int mt7620_eth_probe(struct udevice *dev)
+{
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+	u32 pcie_mode = MT7620_SYSC_PCIE_RC_MODE;
+	int ret;
+
+	misc_ioctl(priv->sysc, MT7620_SYSC_IOCTL_SET_PCIE_MODE, &pcie_mode);
+
+	clk_enable_bulk(&priv->clks);
+
+	reset_assert_bulk(&priv->rsts);
+	udelay(100);
+	reset_deassert_bulk(&priv->rsts);
+	udelay(1000);
+
+	ret = mt7620_eth_alloc_rings_pkts(priv);
+	if (ret)
+		return ret;
+
+	ret = mt7620_mdio_register(dev);
+	if (ret)
+		dev_warn(dev, "mt7620_eth: failed to register MDIO bus\n");
+
+	mt7620_gsw_init(priv);
+
+	return 0;
+}
+
+static int mt7620_eth_remove(struct udevice *dev)
+{
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+
+	mt7620_eth_stop(dev);
+
+	mt7620_eth_free_rings_pkts(priv);
+
+	return 0;
+}
+
+static int mt7620_eth_parse_gsw_port(struct mt7620_eth_priv *priv, u32 idx,
+				     ofnode node)
+{
+	ofnode subnode;
+	const char *str;
+	int mode, speed, ret;
+	u32 phy_addr;
+
+	str = ofnode_read_string(node, "phy-mode");
+	if (str) {
+		mode = phy_get_interface_by_name(str);
+		if (mode < 0) {
+			dev_err(priv->dev, "mt7620_eth: invalid phy-mode\n");
+			return -EINVAL;
+		}
+
+		switch (mode) {
+		case PHY_INTERFACE_MODE_MII:
+		case PHY_INTERFACE_MODE_RMII:
+		case PHY_INTERFACE_MODE_RGMII:
+		case PHY_INTERFACE_MODE_NONE:
+			break;
+		default:
+			dev_err(priv->dev,
+				"mt7620_eth: unsupported phy-mode\n");
+			return -ENOTSUPP;
+		}
+
+		priv->port_cfg[idx].mode = mode;
+	} else {
+		priv->port_cfg[idx].mode = PHY_INTERFACE_MODE_NONE;
+	}
+
+	subnode = ofnode_find_subnode(node, "fixed-link");
+	if (ofnode_valid(subnode)) {
+		priv->port_cfg[idx].force_mode = 1;
+		priv->port_cfg[idx].duplex = ofnode_read_bool(subnode,
+							      "full-duplex");
+		speed = ofnode_read_u32_default(subnode, "speed", 0);
+		switch (speed) {
+		case SPEED_10:
+			priv->port_cfg[idx].speed = FORCE_SPEED_10;
+			break;
+		case SPEED_100:
+			priv->port_cfg[idx].speed = FORCE_SPEED_100;
+			break;
+		case SPEED_1000:
+			priv->port_cfg[idx].speed = FORCE_SPEED_1000;
+			break;
+		default:
+			dev_err(priv->dev,
+				"mt7620_eth: invalid speed for fixed-link\n");
+			return -EINVAL;
+		}
+
+		if (idx == 1 && ofnode_read_bool(subnode, "mediatek,mt7530")) {
+			priv->port5_mt7530 = true;
+
+			ret = gpio_request_by_name_nodev(subnode,
+				"mediatek,mt7530-reset", 0, &priv->gpio_swrst,
+				GPIOD_IS_OUT);
+			if (ret) {
+				dev_err(priv->dev,
+					"mt7620_eth: missing mt7530 reset gpio\n");
+				return ret;
+			}
+		}
+	}
+
+	ret = ofnode_read_u32(node, "phy-addr", &phy_addr);
+	if (!ret) {
+		if (phy_addr > 31 || (idx == 0 && phy_addr < 3) ||
+		    (idx == 1 && phy_addr < 4)) {
+			dev_err(priv->dev, "mt7620_eth: invalid phy address\n");
+			return -EINVAL;
+		}
+
+		priv->port_cfg[idx].phy_addr = phy_addr;
+	} else {
+		priv->port_cfg[idx].phy_addr = -1;
+	}
+
+	return 0;
+}
+
+static int mt7620_eth_parse_gsw_cfg(struct udevice *dev)
+{
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+	ofnode subnode;
+	int ret;
+
+	subnode = ofnode_find_subnode(dev_ofnode(dev), "port4");
+	if (ofnode_valid(subnode)) {
+		ret = mt7620_eth_parse_gsw_port(priv, 0, subnode);
+		if (ret)
+			return ret;
+	} else {
+		priv->port_cfg[0].mode = PHY_INTERFACE_MODE_NONE;
+	}
+
+	subnode = ofnode_find_subnode(dev_ofnode(dev), "port5");
+	if (ofnode_valid(subnode))
+		return mt7620_eth_parse_gsw_port(priv, 1, subnode);
+
+	priv->port_cfg[1].mode = PHY_INTERFACE_MODE_NONE;
+	return 0;
+}
+
+static int mt7620_eth_ofdata_to_platdata(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_platdata(dev);
+	struct mt7620_eth_priv *priv = dev_get_priv(dev);
+	struct ofnode_phandle_args sysc_args;
+	int ret;
+
+	pdata->iobase = dev_read_addr(dev);
+
+	priv->dev = dev;
+
+	ret = ofnode_parse_phandle_with_args(dev->node, "mediatek,sysc", NULL,
+					     0, 0, &sysc_args);
+	if (ret) {
+		dev_err(dev, "mt7620_eth: sysc property not found\n");
+		return ret;
+	}
+
+	ret = uclass_get_device_by_ofnode(UCLASS_MISC, sysc_args.node,
+					  &priv->sysc);
+	if (ret) {
+		dev_err(dev, "mt7620_eth: failed to sysc device\n");
+		return ret;
+	}
+
+	priv->fe_base = dev_remap_addr_name(dev, "fe");
+	if (!priv->fe_base) {
+		dev_err(dev, "mt7620_eth: failed to map fe registers\n");
+		return -EINVAL;
+	}
+
+	priv->gsw_base = dev_remap_addr_name(dev, "esw");
+	if (!priv->gsw_base) {
+		dev_err(dev, "mt7620_eth: failed to map esw registers\n");
+		return -EINVAL;
+	}
+
+	ret = reset_get_bulk(dev, &priv->rsts);
+	if (ret) {
+		dev_err(dev, "mt7620_eth: failed to get resetctl\n");
+		return ret;
+	}
+
+	ret = clk_get_bulk(dev, &priv->clks);
+	if (ret) {
+		dev_err(dev, "mt7620_eth: failed to get clocks\n");
+		return ret;
+	}
+
+	return mt7620_eth_parse_gsw_cfg(dev);
+}
+
+static const struct udevice_id mt7620_eth_ids[] = {
+	{ .compatible = "mediatek,mt7620-eth" },
+	{}
+};
+
+U_BOOT_DRIVER(mt7620_eth) = {
+	.name = "mt7620-eth",
+	.id = UCLASS_ETH,
+	.of_match = mt7620_eth_ids,
+	.ofdata_to_platdata = mt7620_eth_ofdata_to_platdata,
+	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
+	.probe = mt7620_eth_probe,
+	.remove = mt7620_eth_remove,
+	.ops = &mt7620_eth_ops,
+	.priv_auto_alloc_size = sizeof(struct mt7620_eth_priv),
+};
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 19/21] mmc: mtk-sd: add pad control settings for MediaTek MT7620/MT76x8 SoCs
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (17 preceding siblings ...)
  2020-10-30  9:35 ` [PATCH v2 18/21] net: add ethernet " Weijie Gao
@ 2020-10-30  9:35 ` Weijie Gao
  2020-10-30  9:35 ` [PATCH v2 20/21] reset: reset-mtmips: add DM_FLAG_PRE_RELOC flag Weijie Gao
  2020-10-30  9:35 ` [PATCH v2 21/21] MAINTAINERS: add maintainer for MediaTek MIPS platform Weijie Gao
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:35 UTC (permalink / raw)
  To: u-boot

The driver is missing pad control settings (pad delay and pad conf) for
the mt7620 and mt76x8. Although mt76x8 still works well, mt7620 will
encounter CRC error on data transfers.

This patch adds default pad control settings for mt7620_compat.

Also a missing field .sclk_cycle_shift = 20 for mt7622 is added.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 drivers/mmc/mtk-sd.c | 122 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 119 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
index 4f9fa7d0ec..e30b16d56b 100644
--- a/drivers/mmc/mtk-sd.c
+++ b/drivers/mmc/mtk-sd.c
@@ -113,7 +113,51 @@
 #define MSDC_PB2_RESPWAIT_M		0x0c
 #define MSDC_PB2_RESPWAIT_S		2
 
+/* MSDC_PAD_CTRL0 */
+#define MSDC_PAD_CTRL0_CLKRDSEL_M	0xff000000
+#define MSDC_PAD_CTRL0_CLKRDSEL_S	24
+#define MSDC_PAD_CTRL0_CLKTDSEL		BIT(20)
+#define MSDC_PAD_CTRL0_CLKIES		BIT(19)
+#define MSDC_PAD_CTRL0_CLKSMT		BIT(18)
+#define MSDC_PAD_CTRL0_CLKPU		BIT(17)
+#define MSDC_PAD_CTRL0_CLKPD		BIT(16)
+#define MSDC_PAD_CTRL0_CLKSR		BIT(8)
+#define MSDC_PAD_CTRL0_CLKDRVP_M	0x70
+#define MSDC_PAD_CTRL0_CLKDRVP_S	4
+#define MSDC_PAD_CTRL0_CLKDRVN_M	0x7
+#define MSDC_PAD_CTRL0_CLKDRVN_S	0
+
+/* MSDC_PAD_CTRL1 */
+#define MSDC_PAD_CTRL1_CMDRDSEL_M	0xff000000
+#define MSDC_PAD_CTRL1_CMDRDSEL_S	24
+#define MSDC_PAD_CTRL1_CMDTDSEL		BIT(20)
+#define MSDC_PAD_CTRL1_CMDIES		BIT(19)
+#define MSDC_PAD_CTRL1_CMDSMT		BIT(18)
+#define MSDC_PAD_CTRL1_CMDPU		BIT(17)
+#define MSDC_PAD_CTRL1_CMDPD		BIT(16)
+#define MSDC_PAD_CTRL1_CMDSR		BIT(8)
+#define MSDC_PAD_CTRL1_CMDDRVP_M	0x70
+#define MSDC_PAD_CTRL1_CMDDRVP_S	4
+#define MSDC_PAD_CTRL1_CMDDRVN_M	0x7
+#define MSDC_PAD_CTRL1_CMDDRVN_S	0
+
+/* MSDC_PAD_CTRL2 */
+#define MSDC_PAD_CTRL2_DATRDSEL_M	0xff000000
+#define MSDC_PAD_CTRL2_DATRDSEL_S	24
+#define MSDC_PAD_CTRL2_DATTDSEL		BIT(20)
+#define MSDC_PAD_CTRL2_DATIES		BIT(19)
+#define MSDC_PAD_CTRL2_DATSMT		BIT(18)
+#define MSDC_PAD_CTRL2_DATPU		BIT(17)
+#define MSDC_PAD_CTRL2_DATPD		BIT(16)
+#define MSDC_PAD_CTRL2_DATSR		BIT(8)
+#define MSDC_PAD_CTRL2_DATDRVP_M	0x70
+#define MSDC_PAD_CTRL2_DATDRVP_S	4
+#define MSDC_PAD_CTRL2_DATDRVN_M	0x7
+#define MSDC_PAD_CTRL2_DATDRVN_S	0
+
 /* PAD_TUNE */
+#define MSDC_PAD_TUNE_CLKTDLY_M		0xf8000000
+#define MSDC_PAD_TUNE_CLKTDLY_S		27
 #define MSDC_PAD_TUNE_CMDRRDLY_M	0x7c00000
 #define MSDC_PAD_TUNE_CMDRRDLY_S	22
 #define MSDC_PAD_TUNE_CMD_SEL		BIT(21)
@@ -129,6 +173,26 @@
 #define PAD_CMD_TUNE_RX_DLY3		0x3E
 #define PAD_CMD_TUNE_RX_DLY3_S		1
 
+/* PAD_TUNE0 */
+#define MSDC_PAD_TUNE0_DAT0RDDLY_M	0x1f000000
+#define MSDC_PAD_TUNE0_DAT0RDDLY_S	24
+#define MSDC_PAD_TUNE0_DAT1RDDLY_M	0x1f0000
+#define MSDC_PAD_TUNE0_DAT1RDDLY_S	16
+#define MSDC_PAD_TUNE0_DAT2RDDLY_M	0x1f00
+#define MSDC_PAD_TUNE0_DAT2RDDLY_S	8
+#define MSDC_PAD_TUNE0_DAT3RDDLY_M	0x1f
+#define MSDC_PAD_TUNE0_DAT3RDDLY_S	0
+
+/* PAD_TUNE1 */
+#define MSDC_PAD_TUNE1_DAT4RDDLY_M	0x1f000000
+#define MSDC_PAD_TUNE1_DAT4RDDLY_S	24
+#define MSDC_PAD_TUNE1_DAT5RDDLY_M	0x1f0000
+#define MSDC_PAD_TUNE1_DAT5RDDLY_S	16
+#define MSDC_PAD_TUNE1_DAT6RDDLY_M	0x1f00
+#define MSDC_PAD_TUNE1_DAT6RDDLY_S	8
+#define MSDC_PAD_TUNE1_DAT7RDDLY_M	0x1f
+#define MSDC_PAD_TUNE1_DAT7RDDLY_S	0
+
 /* EMMC50_CFG0 */
 #define EMMC50_CFG_CFCSTS_SEL		BIT(4)
 
@@ -221,7 +285,10 @@ struct mtk_sd_regs {
 	u32 dat3_tune_crc;
 	u32 cmd_tune_crc;
 	u32 sdio_tune_wind;
-	u32 reserved4[5];
+	u32 reserved4[2];
+	u32 pad_ctrl0;
+	u32 pad_ctrl1;
+	u32 pad_ctrl2;
 	u32 pad_tune;
 	u32 pad_tune0;
 	u32 pad_tune1;
@@ -263,6 +330,8 @@ struct msdc_compatible {
 	bool busy_check;
 	bool stop_clk_fix;
 	bool enhance_rx;
+	bool builtin_pad_ctrl;
+	bool default_pad_dly;
 };
 
 struct msdc_delay_phase {
@@ -1391,9 +1460,14 @@ static void msdc_init_hw(struct msdc_host *host)
 {
 	u32 val;
 	void __iomem *tune_reg = &host->base->pad_tune;
+	void __iomem *rd_dly0_reg = &host->base->pad_tune0;
+	void __iomem *rd_dly1_reg = &host->base->pad_tune1;
 
-	if (host->dev_comp->pad_tune0)
+	if (host->dev_comp->pad_tune0) {
 		tune_reg = &host->base->pad_tune0;
+		rd_dly0_reg = &host->base->dat_rd_dly[0];
+		rd_dly1_reg = &host->base->dat_rd_dly[1];
+	}
 
 	/* Configure to MMC/SD mode, clock free running */
 	setbits_le32(&host->base->msdc_cfg, MSDC_CFG_MODE);
@@ -1479,6 +1553,45 @@ static void msdc_init_hw(struct msdc_host *host)
 		setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
 	}
 
+	if (host->dev_comp->builtin_pad_ctrl) {
+		/* Set pins driving strength */
+		writel(MSDC_PAD_CTRL0_CLKPD | MSDC_PAD_CTRL0_CLKSMT |
+		       MSDC_PAD_CTRL0_CLKIES | (4 << MSDC_PAD_CTRL0_CLKDRVN_S) |
+		       (4 << MSDC_PAD_CTRL0_CLKDRVP_S), &host->base->pad_ctrl0);
+		writel(MSDC_PAD_CTRL1_CMDPU | MSDC_PAD_CTRL1_CMDSMT |
+		       MSDC_PAD_CTRL1_CMDIES | (4 << MSDC_PAD_CTRL1_CMDDRVN_S) |
+		       (4 << MSDC_PAD_CTRL1_CMDDRVP_S), &host->base->pad_ctrl1);
+		writel(MSDC_PAD_CTRL2_DATPU | MSDC_PAD_CTRL2_DATSMT |
+		       MSDC_PAD_CTRL2_DATIES | (4 << MSDC_PAD_CTRL2_DATDRVN_S) |
+		       (4 << MSDC_PAD_CTRL2_DATDRVP_S), &host->base->pad_ctrl2);
+	}
+
+	if (host->dev_comp->default_pad_dly) {
+		/* Default pad delay may be needed if tuning not enabled */
+		clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CLKTDLY_M |
+				MSDC_PAD_TUNE_CMDRRDLY_M |
+				MSDC_PAD_TUNE_CMDRDLY_M |
+				MSDC_PAD_TUNE_DATRRDLY_M |
+				MSDC_PAD_TUNE_DATWRDLY_M,
+				(0x10 << MSDC_PAD_TUNE_CLKTDLY_S) |
+				(0x10 << MSDC_PAD_TUNE_CMDRRDLY_S) |
+				(0x10 << MSDC_PAD_TUNE_CMDRDLY_S) |
+				(0x10 << MSDC_PAD_TUNE_DATRRDLY_S) |
+				(0x10 << MSDC_PAD_TUNE_DATWRDLY_S));
+
+		writel((0x10 << MSDC_PAD_TUNE0_DAT0RDDLY_S) |
+		       (0x10 << MSDC_PAD_TUNE0_DAT1RDDLY_S) |
+		       (0x10 << MSDC_PAD_TUNE0_DAT2RDDLY_S) |
+		       (0x10 << MSDC_PAD_TUNE0_DAT3RDDLY_S),
+		       rd_dly0_reg);
+
+		writel((0x10 << MSDC_PAD_TUNE1_DAT4RDDLY_S) |
+		       (0x10 << MSDC_PAD_TUNE1_DAT5RDDLY_S) |
+		       (0x10 << MSDC_PAD_TUNE1_DAT6RDDLY_S) |
+		       (0x10 << MSDC_PAD_TUNE1_DAT7RDDLY_S),
+		       rd_dly1_reg);
+	}
+
 	/* Configure to enable SDIO mode otherwise sdio cmd5 won't work */
 	setbits_le32(&host->base->sdc_cfg, SDC_CFG_SDIO);
 
@@ -1621,11 +1734,14 @@ static const struct msdc_compatible mt7620_compat = {
 	.data_tune = false,
 	.busy_check = false,
 	.stop_clk_fix = false,
-	.enhance_rx = false
+	.enhance_rx = false,
+	.builtin_pad_ctrl = true,
+	.default_pad_dly = true,
 };
 
 static const struct msdc_compatible mt7622_compat = {
 	.clk_div_bits = 12,
+	.sclk_cycle_shift = 20,
 	.pad_tune0 = true,
 	.async_fifo = true,
 	.data_tune = true,
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 20/21] reset: reset-mtmips: add DM_FLAG_PRE_RELOC flag
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (18 preceding siblings ...)
  2020-10-30  9:35 ` [PATCH v2 19/21] mmc: mtk-sd: add pad control settings for MediaTek MT7620/MT76x8 SoCs Weijie Gao
@ 2020-10-30  9:35 ` Weijie Gao
  2020-10-30  9:35 ` [PATCH v2 21/21] MAINTAINERS: add maintainer for MediaTek MIPS platform Weijie Gao
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:35 UTC (permalink / raw)
  To: u-boot

Add DM_FLAG_PRE_RELOC flag for reset-mtmips to make sure this driver can
be probed before relocation even if u-boot,dm-pre-reloc is not present
in the dts.

Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: new
---
 drivers/reset/reset-mtmips.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/reset/reset-mtmips.c b/drivers/reset/reset-mtmips.c
index bc20e3335c..0d6a446465 100644
--- a/drivers/reset/reset-mtmips.c
+++ b/drivers/reset/reset-mtmips.c
@@ -82,4 +82,5 @@ U_BOOT_DRIVER(mtmips_reset) = {
 	.probe = mtmips_reset_probe,
 	.priv_auto_alloc_size = sizeof(struct mtmips_reset_priv),
 	.ops = &mtmips_reset_ops,
+	.flags = DM_FLAG_PRE_RELOC,
 };
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 21/21] MAINTAINERS: add maintainer for MediaTek MIPS platform
  2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
                   ` (19 preceding siblings ...)
  2020-10-30  9:35 ` [PATCH v2 20/21] reset: reset-mtmips: add DM_FLAG_PRE_RELOC flag Weijie Gao
@ 2020-10-30  9:35 ` Weijie Gao
  20 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-10-30  9:35 UTC (permalink / raw)
  To: u-boot

Update maintainer for MediaTek MIPS platform

Acked-by: Stefan Roese <sr@denx.de>
Reviewed-by: Stefan Roese <sr@denx.de>
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
v2 changes: none
---
 MAINTAINERS | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 857e236aa4..bcdc23c2e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -800,6 +800,29 @@ F:	drivers/mmc/ca_dw_mmc.c
 F:	drivers/i2c/i2c-cortina.c
 F:	drivers/i2c/i2c-cortina.h
 
+MIPS MEDIATEK
+M:	Weijie Gao <weijie.gao@mediatek.com>
+R:	GSS_MTK_Uboot_upstream <GSS_MTK_Uboot_upstream@mediatek.com>
+S:	Maintained
+F:	arch/mips/mach-mtmips/
+F:	arch/mips/dts/mt7620.dtsi
+F:	arch/mips/dts/mt7620-u-boot.dtsi
+F:	include/configs/mt7620.h
+F:	include/dt-bindings/clock/mt7620-clk.h
+F:	include/dt-bindings/clock/mt7628-clk.h
+F:	include/dt-bindings/reset/mt7620-reset.h
+F:	include/dt-bindings/reset/mt7628-reset.h
+F:	drivers/clk/mtmips/
+F:	drivers/pinctrl/mtmips/
+F:	drivers/gpio/mt7620_gpio.c
+F:	drivers/net/mt7620-eth.c
+F:	drivers/phy/mt7620-usb-phy.c
+F:	drivers/reset/reset-mtmips.c
+F:	drivers/serial/serial_mt7620.c
+F:	drivers/spi/mt7620_spi.c
+F:	drivers/sysreset/sysreset_resetctl.c
+F:	drivers/watchdog/mt7620_wdt.c
+
 MIPS MSCC
 M:	Gregory CLEMENT <gregory.clement@bootlin.com>
 M:	Lars Povlsen <lars.povlsen@microchip.com>
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH v2 16/21] spi: add spi controller support for MediaTek MT7620 SoC
  2020-10-30  9:35 ` [PATCH v2 16/21] spi: add spi controller support " Weijie Gao
@ 2020-11-02  6:00   ` Jagan Teki
  2020-11-09  2:10     ` Weijie Gao
  0 siblings, 1 reply; 30+ messages in thread
From: Jagan Teki @ 2020-11-02  6:00 UTC (permalink / raw)
  To: u-boot

On Fri, Oct 30, 2020 at 3:05 PM Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds spi controller support for MediaTek MT7620 SoC.
>
> The SPI controller supports two chip selects. These two chip selects are
> implemented as two separate register groups, but they share the same bus
> (DI/DO/CLK), only CS pins are dedicated for each register group.
> Appearently these two register groups cannot operates simulataneously so
> they are implemented as one controller.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
> v2 changes: none
> ---
>  drivers/spi/Kconfig      |   7 +
>  drivers/spi/Makefile     |   1 +
>  drivers/spi/mt7620_spi.c | 277 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 285 insertions(+)
>  create mode 100644 drivers/spi/mt7620_spi.c
>
> diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> index f7a9852565..ec50d843ef 100644
> --- a/drivers/spi/Kconfig
> +++ b/drivers/spi/Kconfig
> @@ -202,6 +202,13 @@ config MSCC_BB_SPI
>           Enable MSCC bitbang SPI driver. This driver can be used on
>           MSCC SOCs.
>
> +config MT7620_SPI
> +       bool "MediaTek MT7620 SPI driver"
> +       depends on SOC_MT7620
> +       help
> +         Enable the MT7620 SPI driver. This driver can be used to access
> +         generic SPI devices on MediaTek MT7620 SoC.
> +
>  config MT7621_SPI
>         bool "MediaTek MT7621 SPI driver"
>         depends on SOC_MT7628
> diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> index d9b5bd9b79..bfd142d153 100644
> --- a/drivers/spi/Makefile
> +++ b/drivers/spi/Makefile
> @@ -36,6 +36,7 @@ obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
>  obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
>  obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
>  obj-$(CONFIG_MTK_SNFI_SPI) += mtk_snfi_spi.o
> +obj-$(CONFIG_MT7620_SPI) += mt7620_spi.o
>  obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
>  obj-$(CONFIG_MSCC_BB_SPI) += mscc_bb_spi.o
>  obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o
> diff --git a/drivers/spi/mt7620_spi.c b/drivers/spi/mt7620_spi.c
> new file mode 100644
> index 0000000000..c0b3d1d8eb
> --- /dev/null
> +++ b/drivers/spi/mt7620_spi.c
> @@ -0,0 +1,277 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 MediaTek Inc.
> + *
> + * Author: Weijie Gao <weijie.gao@mediatek.com>
> + *
> + * Generic SPI driver for MediaTek MT7620 SoC
> + */
> +
> +#include <clk.h>
> +#include <dm.h>
> +#include <spi.h>
> +#include <linux/bitops.h>
> +#include <linux/iopoll.h>
> +#include <linux/io.h>
> +#include <linux/log2.h>
> +
> +#define MT7620_SPI_NUM_CS      2
> +#define MT7620_SPI_MASTER1_OFF 0x00
> +#define MT7620_SPI_MASTER2_OFF 0x40
> +
> +/* SPI_STAT */
> +#define   SPI_BUSY             BIT(0)
> +
> +/* SPI_CFG */
> +#define   MSB_FIRST            BIT(8)
> +#define   SPI_CLK_POL          BIT(6)
> +#define   RX_CLK_EDGE          BIT(5)
> +#define   TX_CLK_EDGE          BIT(4)
> +#define   SPI_CLK_S            0
> +#define   SPI_CLK_M            GENMASK(2, 0)
> +
> +/* SPI_CTL */
> +#define   START_WR             BIT(2)
> +#define   START_RD             BIT(1)
> +#define   SPI_HIGH             BIT(0)
> +
> +#define SPI_ARB                        0xf0
> +#define   ARB_EN               BIT(31)
> +
> +struct mt7620_spi_master_regs {
> +       u32 stat;
> +       u32 reserved0[3];
> +       u32 cfg;
> +       u32 ctl;
> +       u32 reserved1[2];
> +       u32 data;
> +};
> +
> +struct mt7620_spi {
> +       void __iomem *regs;
> +       struct mt7620_spi_master_regs *m[MT7620_SPI_NUM_CS];
> +       unsigned int sys_freq;
> +       u32 wait_us;
> +       uint mode;
> +       uint speed;
> +};
> +
> +static void mt7620_spi_master_setup(struct mt7620_spi *ms, int cs)
> +{
> +       u32 rate, prescale, freq, tmo, cfg;
> +
> +       /* Calculate the clock divsior */
> +       rate = DIV_ROUND_UP(ms->sys_freq, ms->speed);
> +       rate = roundup_pow_of_two(rate);
> +
> +       prescale = ilog2(rate / 2);
> +       if (prescale > 6)
> +               prescale = 6;
> +
> +       /* Calculate the real clock, and usecs for one byte transaction */
> +       freq = ms->sys_freq >> (prescale + 1);
> +       tmo = DIV_ROUND_UP(8 * 1000000, freq);
> +
> +       /* 10 times tolerance plus 100us */
> +       ms->wait_us = 10 * tmo + 100;

Replace the above magic numbers with meaningful macros.

> +
> +       /* set SPI_CFG */
> +       cfg = prescale << SPI_CLK_S;
> +
> +       switch (ms->mode & (SPI_CPOL | SPI_CPHA)) {
> +       case SPI_MODE_0:
> +               cfg |= TX_CLK_EDGE;
> +               break;
> +       case SPI_MODE_1:
> +               cfg |= RX_CLK_EDGE;
> +               break;
> +       case SPI_MODE_2:
> +               cfg |= SPI_CLK_POL | RX_CLK_EDGE;
> +               break;
> +       case SPI_MODE_3:
> +               cfg |= SPI_CLK_POL | TX_CLK_EDGE;
> +               break;
> +       }
> +
> +       if (!(ms->mode & SPI_LSB_FIRST))
> +               cfg |= MSB_FIRST;
> +
> +       writel(cfg, &ms->m[cs]->cfg);
> +
> +       writel(SPI_HIGH, &ms->m[cs]->ctl);
> +}
> +
> +static void mt7620_spi_set_cs(struct mt7620_spi *ms, int cs, int enable)
> +{
> +       if (enable)
> +               mt7620_spi_master_setup(ms, cs);
> +
> +       if (ms->mode & SPI_CS_HIGH)
> +               enable = !enable;
> +
> +       if (enable)
> +               clrbits_32(&ms->m[cs]->ctl, SPI_HIGH);
> +       else
> +               setbits_32(&ms->m[cs]->ctl, SPI_HIGH);
> +}
> +
> +static int mt7620_spi_set_mode(struct udevice *bus, uint mode)
> +{
> +       struct mt7620_spi *ms = dev_get_priv(bus);
> +
> +       ms->mode = mode;
> +
> +       /* Mode 0 is buggy. Force to use mode 3 */
> +       if ((mode & SPI_MODE_3) == SPI_MODE_0)
> +               ms->mode |= SPI_MODE_3;
> +
> +       return 0;
> +}
> +
> +static int mt7620_spi_set_speed(struct udevice *bus, uint speed)
> +{
> +       struct mt7620_spi *ms = dev_get_priv(bus);
> +
> +       ms->speed = speed;
> +
> +       return 0;
> +}
> +
> +static inline int mt7620_spi_busy_poll(struct mt7620_spi *ms, int cs)
> +{
> +       u32 val;
> +
> +       return readl_poll_timeout(&ms->m[cs]->stat, val, !(val & SPI_BUSY),
> +                                 ms->wait_us);
> +}
> +
> +static int mt7620_spi_read(struct mt7620_spi *ms, int cs, u8 *buf, size_t len)
> +{
> +       int ret;
> +
> +       while (len) {
> +               setbits_32(&ms->m[cs]->ctl, START_RD);
> +
> +               ret = mt7620_spi_busy_poll(ms, cs);
> +               if (ret) {
> +                       pr_err("SPI read transaction timeout\n");
> +                       return ret;
> +               }
> +
> +               *buf++ = (u8)readl(&ms->m[cs]->data);
> +
> +               len--;
> +       }
> +
> +       return 0;
> +}
> +
> +static int mt7620_spi_write(struct mt7620_spi *ms, int cs, const u8 *buf,
> +                           size_t len)
> +{
> +       int ret;
> +
> +       while (len) {
> +               writel(*buf++, &ms->m[cs]->data);
> +               setbits_32(&ms->m[cs]->ctl, START_WR);
> +
> +               ret = mt7620_spi_busy_poll(ms, cs);
> +               if (ret) {
> +                       pr_err("SPI write transaction timeout\n");
> +                       return ret;
> +               }
> +
> +               len--;
> +       }
> +
> +       return 0;
> +}
> +
> +static int mt7620_spi_xfer(struct udevice *dev, unsigned int bitlen,
> +                          const void *dout, void *din, unsigned long flags)
> +{
> +       struct udevice *bus = dev->parent;
> +       struct mt7620_spi *ms = dev_get_priv(bus);
> +       int total_size = bitlen >> 3;
> +       int cs, ret = 0;
> +
> +       /*
> +        * This driver only supports half-duplex, so complain and bail out
> +        * upon full-duplex messages
> +        */
> +       if (dout && din) {
> +               pr_err("Only half-duplex SPI transfer supported\n");
> +               return -EIO;
> +       }
> +
> +       cs = spi_chip_select(dev);
> +       if (cs < 0 || cs >= MT7620_SPI_NUM_CS) {
> +               pr_err("Invalid chip select %d\n", cs);
> +               return -EINVAL;
> +       }
> +
> +       if (flags & SPI_XFER_BEGIN)
> +               mt7620_spi_set_cs(ms, cs, 1);

use boolean type for last argument.

> +
> +       if (din)
> +               ret = mt7620_spi_read(ms, cs, din, total_size);
> +       else if (dout)
> +               ret = mt7620_spi_write(ms, cs, dout, total_size);
> +
> +       if (flags & SPI_XFER_END)
> +               mt7620_spi_set_cs(ms, cs, 0);

same as above.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 14/21] watchdog: add watchdog driver for MediaTek MT7620 SoC
  2020-10-30  9:34 ` [PATCH v2 14/21] watchdog: add watchdog driver " Weijie Gao
@ 2020-11-02  6:02   ` Jagan Teki
  2020-11-09  2:13     ` Weijie Gao
  0 siblings, 1 reply; 30+ messages in thread
From: Jagan Teki @ 2020-11-02  6:02 UTC (permalink / raw)
  To: u-boot

On Fri, Oct 30, 2020 at 3:04 PM Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds watchdog support for the Mediatek MT7620 SoC
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
> v2 changes: add expire_now
> ---
>  drivers/watchdog/Kconfig      |   7 ++
>  drivers/watchdog/Makefile     |   1 +
>  drivers/watchdog/mt7620_wdt.c | 132 ++++++++++++++++++++++++++++++++++
>  3 files changed, 140 insertions(+)
>  create mode 100644 drivers/watchdog/mt7620_wdt.c
>
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 210d9f8093..35d078caa0 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -124,6 +124,13 @@ config WDT_MPC8xx
>         help
>           Select this to enable mpc8xx watchdog timer
>
> +config WDT_MT7620
> +       bool "MediaTek MT7620 watchdog timer support"
> +       depends on WDT && SOC_MT7620
> +       help
> +         Select this to enable watchdog timer on MediaTek MT7620 and earlier
> +         SoC chips.
> +
>  config WDT_MT7621
>         bool "MediaTek MT7621 watchdog timer support"
>         depends on WDT && SOC_MT7628
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index 01b8231f2b..825b50e626 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -24,6 +24,7 @@ obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o
>  obj-$(CONFIG_WDT_ORION) += orion_wdt.o
>  obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
>  obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
> +obj-$(CONFIG_WDT_MT7620) += mt7620_wdt.o
>  obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
>  obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
>  obj-$(CONFIG_WDT_OCTEONTX) += octeontx_wdt.o
> diff --git a/drivers/watchdog/mt7620_wdt.c b/drivers/watchdog/mt7620_wdt.c
> new file mode 100644
> index 0000000000..2643167f8f
> --- /dev/null
> +++ b/drivers/watchdog/mt7620_wdt.c
> @@ -0,0 +1,132 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 MediaTek Inc.
> + *
> + * Author:  Weijie Gao <weijie.gao@mediatek.com>
> + *
> + * Watchdog timer for MT7620 and earlier SoCs
> + */
> +
> +#include <div64.h>
> +#include <dm.h>
> +#include <reset.h>
> +#include <wdt.h>
> +#include <linux/bitops.h>
> +#include <linux/io.h>
> +
> +struct mt7620_wdt {
> +       void __iomem *regs;
> +       u64 timeout;
> +};
> +
> +#define TIMER_FREQ                     40000000
> +#define TIMER_MASK                     0xffff
> +#define TIMER_PRESCALE                 65536
> +
> +#define TIMER_LOAD                     0x00
> +#define TIMER_CTL                      0x08
> +
> +#define TIMER_ENABLE                   BIT(7)
> +#define TIMER_MODE_SHIFT               4
> +#define   TIMER_MODE_WDT               3
> +#define TIMER_PRESCALE_SHIFT           0
> +#define   TIMER_PRESCALE_65536         15
> +
> +static void mt7620_wdt_ping(struct mt7620_wdt *priv)
> +{
> +       u64 val;
> +
> +       val = (TIMER_FREQ / TIMER_PRESCALE) * priv->timeout;
> +       do_div(val, 1000);
> +
> +       if (val > TIMER_MASK)
> +               val = TIMER_MASK;
> +
> +       writel(val, priv->regs + TIMER_LOAD);
> +}
> +
> +static int mt7620_wdt_start(struct udevice *dev, u64 ms, ulong flags)
> +{
> +       struct mt7620_wdt *priv = dev_get_priv(dev);
> +
> +       priv->timeout = ms;
> +       mt7620_wdt_ping(priv);
> +
> +       writel(TIMER_ENABLE | (TIMER_MODE_WDT << TIMER_MODE_SHIFT) |
> +              (TIMER_PRESCALE_65536 << TIMER_PRESCALE_SHIFT),
> +              priv->regs + TIMER_CTL);
> +
> +       return 0;
> +}
> +
> +static int mt7620_wdt_stop(struct udevice *dev)
> +{
> +       struct mt7620_wdt *priv = dev_get_priv(dev);
> +
> +       mt7620_wdt_ping(priv);
> +
> +       clrbits_32(priv->regs + TIMER_CTL, TIMER_ENABLE);
> +
> +       return 0;
> +}
> +
> +static int mt7620_wdt_reset(struct udevice *dev)
> +{
> +       struct mt7620_wdt *priv = dev_get_priv(dev);
> +
> +       mt7620_wdt_ping(priv);
> +
> +       return 0;
> +}
> +
> +static int mt7620_wdt_expire_now(struct udevice *dev, ulong flags)
> +{
> +       struct mt7620_wdt *priv = dev_get_priv(dev);
> +
> +       mt7620_wdt_start(dev, 1, flags);
> +
> +       /* 0 will disable the timer, so use 1 instead */
> +       writel(1, priv->regs + TIMER_LOAD);

Better replace the magic number with macro.
Otherwise,

Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 17/21] phy: add USB PHY driver for MediaTek MT7620 SoC
  2020-10-30  9:35 ` [PATCH v2 17/21] phy: add USB PHY driver " Weijie Gao
@ 2020-11-02  6:11   ` Jagan Teki
  2020-11-09  2:14     ` Weijie Gao
  0 siblings, 1 reply; 30+ messages in thread
From: Jagan Teki @ 2020-11-02  6:11 UTC (permalink / raw)
  To: u-boot

On Fri, Oct 30, 2020 at 3:05 PM Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds USB PHY driver for MediaTek MT7620 SoC
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
> v2 changes: none
> ---
>  drivers/phy/Kconfig          |   7 +++
>  drivers/phy/Makefile         |   1 +
>  drivers/phy/mt7620-usb-phy.c | 113 +++++++++++++++++++++++++++++++++++
>  3 files changed, 121 insertions(+)
>  create mode 100644 drivers/phy/mt7620-usb-phy.c
>
> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> index d12a6b02ad..ab638f0e7d 100644
> --- a/drivers/phy/Kconfig
> +++ b/drivers/phy/Kconfig
> @@ -218,6 +218,13 @@ config KEYSTONE_USB_PHY
>
>           This PHY is found on some Keystone (K2) devices supporting USB.
>
> +config MT7620_USB_PHY
> +       bool "MediaTek MT7620 USB PHY support"
> +       depends on PHY
> +       depends on SOC_MT7620
> +       help
> +          Support the intergated USB PHY in MediaTek MT7620 SoC
> +
>  config MT76X8_USB_PHY
>         bool "MediaTek MT76x8 (7628/88) USB PHY support"
>         depends on PHY
> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> index 45a7fe5b56..6b3761b8c8 100644
> --- a/drivers/phy/Makefile
> +++ b/drivers/phy/Makefile
> @@ -24,6 +24,7 @@ obj-$(CONFIG_MESON_G12A_USB_PHY) += meson-g12a-usb2.o meson-g12a-usb3-pcie.o
>  obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
>  obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o
>  obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o
> +obj-$(CONFIG_MT7620_USB_PHY) += mt7620-usb-phy.o
>  obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o
>  obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o
>  obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
> diff --git a/drivers/phy/mt7620-usb-phy.c b/drivers/phy/mt7620-usb-phy.c
> new file mode 100644
> index 0000000000..59ac32f327
> --- /dev/null
> +++ b/drivers/phy/mt7620-usb-phy.c
> @@ -0,0 +1,113 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
> + *
> + * Author: Weijie Gao <weijie.gao@mediatek.com>
> + */
> +
> +#include <clk.h>
> +#include <dm.h>
> +#include <generic-phy.h>
> +#include <misc.h>
> +#include <reset.h>
> +#include <dm/device_compat.h>
> +#include <linux/delay.h>
> +#include <mach/mt7620-sysc.h>
> +
> +struct mt7620_usb_phy {
> +       struct udevice *dev;

Why this explicit dev required here? generic_phy_get_ calls will assign phy->dev

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 05/21] mips: enable _machine_restart for spl
  2020-10-30  9:33 ` [PATCH v2 05/21] mips: enable _machine_restart for spl Weijie Gao
@ 2020-11-03 15:12   ` Simon Glass
  0 siblings, 0 replies; 30+ messages in thread
From: Simon Glass @ 2020-11-03 15:12 UTC (permalink / raw)
  To: u-boot

On Fri, 30 Oct 2020 at 03:34, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> The sysreset driver has a config CONFIG_SPL_SYSRESET for the spl stage.
> Change CONFIG_SYSRESET to CONFIG_IS_ENABLED(SYSRESET) will give spl a
> chance to use _machine_restart instead of the sysreset driver.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
> v2 changes: new
> ---
>  arch/mips/cpu/cpu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 10/21] serial: add uart driver for MediaTek MT7620 SoC
  2020-10-30  9:34 ` [PATCH v2 10/21] serial: add uart driver for MediaTek MT7620 SoC Weijie Gao
@ 2020-11-03 15:12   ` Simon Glass
  0 siblings, 0 replies; 30+ messages in thread
From: Simon Glass @ 2020-11-03 15:12 UTC (permalink / raw)
  To: u-boot

On Fri, 30 Oct 2020 at 03:34, Weijie Gao <weijie.gao@mediatek.com> wrote:
>
> This patch adds uart support for MediaTek MT7620 and earlier SoCs.
>
> The UART used by MT7620 is incompatible with the ns16550a driver.
> All registers of this UART have different addresses. A special 16-bit
> register for Divisor Latch is used to set the baudrate instead of the
> original two 8-bit registers (DLL and DLM).
>
> The driver supports of-platdata which is useful for tiny SPL.
>
> Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> ---
> v2 changes: replace non-DM code with of-platdata
> ---
>  drivers/serial/Kconfig         |  20 +++
>  drivers/serial/Makefile        |   1 +
>  drivers/serial/serial.c        |   2 +
>  drivers/serial/serial_mt7620.c | 246 +++++++++++++++++++++++++++++++++
>  4 files changed, 269 insertions(+)
>  create mode 100644 drivers/serial/serial_mt7620.c
>

Reviewed-by: Simon Glass <sjg@chromium.org>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 16/21] spi: add spi controller support for MediaTek MT7620 SoC
  2020-11-02  6:00   ` Jagan Teki
@ 2020-11-09  2:10     ` Weijie Gao
  0 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-11-09  2:10 UTC (permalink / raw)
  To: u-boot

On Mon, 2020-11-02 at 11:30 +0530, Jagan Teki wrote:
> On Fri, Oct 30, 2020 at 3:05 PM Weijie Gao <weijie.gao@mediatek.com> wrote:
> >
> > This patch adds spi controller support for MediaTek MT7620 SoC.
> >
> > The SPI controller supports two chip selects. These two chip selects are
> > implemented as two separate register groups, but they share the same bus
> > (DI/DO/CLK), only CS pins are dedicated for each register group.
> > Appearently these two register groups cannot operates simulataneously so
> > they are implemented as one controller.
> >
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> > v2 changes: none
> > ---
> >  drivers/spi/Kconfig      |   7 +
> >  drivers/spi/Makefile     |   1 +
> >  drivers/spi/mt7620_spi.c | 277 +++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 285 insertions(+)
> >  create mode 100644 drivers/spi/mt7620_spi.c
> >
> > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> > index f7a9852565..ec50d843ef 100644
> > --- a/drivers/spi/Kconfig
> > +++ b/drivers/spi/Kconfig
> > @@ -202,6 +202,13 @@ config MSCC_BB_SPI
> >           Enable MSCC bitbang SPI driver. This driver can be used on
> >           MSCC SOCs.
> >
> > +config MT7620_SPI
> > +       bool "MediaTek MT7620 SPI driver"
> > +       depends on SOC_MT7620
> > +       help
> > +         Enable the MT7620 SPI driver. This driver can be used to access
> > +         generic SPI devices on MediaTek MT7620 SoC.
> > +
> >  config MT7621_SPI
> >         bool "MediaTek MT7621 SPI driver"
> >         depends on SOC_MT7628
> > diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> > index d9b5bd9b79..bfd142d153 100644
> > --- a/drivers/spi/Makefile
> > +++ b/drivers/spi/Makefile
> > @@ -36,6 +36,7 @@ obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
> >  obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
> >  obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
> >  obj-$(CONFIG_MTK_SNFI_SPI) += mtk_snfi_spi.o
> > +obj-$(CONFIG_MT7620_SPI) += mt7620_spi.o
> >  obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o
> >  obj-$(CONFIG_MSCC_BB_SPI) += mscc_bb_spi.o
> >  obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o
> > diff --git a/drivers/spi/mt7620_spi.c b/drivers/spi/mt7620_spi.c
> > new file mode 100644
> > index 0000000000..c0b3d1d8eb
> > --- /dev/null
> > +++ b/drivers/spi/mt7620_spi.c
> > @@ -0,0 +1,277 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc.
> > + *
> > + * Author: Weijie Gao <weijie.gao@mediatek.com>
> > + *
> > + * Generic SPI driver for MediaTek MT7620 SoC
> > + */
> > +
> > +#include <clk.h>
> > +#include <dm.h>
> > +#include <spi.h>
> > +#include <linux/bitops.h>
> > +#include <linux/iopoll.h>
> > +#include <linux/io.h>
> > +#include <linux/log2.h>
> > +
> > +#define MT7620_SPI_NUM_CS      2
> > +#define MT7620_SPI_MASTER1_OFF 0x00
> > +#define MT7620_SPI_MASTER2_OFF 0x40
> > +
> > +/* SPI_STAT */
> > +#define   SPI_BUSY             BIT(0)
> > +
> > +/* SPI_CFG */
> > +#define   MSB_FIRST            BIT(8)
> > +#define   SPI_CLK_POL          BIT(6)
> > +#define   RX_CLK_EDGE          BIT(5)
> > +#define   TX_CLK_EDGE          BIT(4)
> > +#define   SPI_CLK_S            0
> > +#define   SPI_CLK_M            GENMASK(2, 0)
> > +
> > +/* SPI_CTL */
> > +#define   START_WR             BIT(2)
> > +#define   START_RD             BIT(1)
> > +#define   SPI_HIGH             BIT(0)
> > +
> > +#define SPI_ARB                        0xf0
> > +#define   ARB_EN               BIT(31)
> > +
> > +struct mt7620_spi_master_regs {
> > +       u32 stat;
> > +       u32 reserved0[3];
> > +       u32 cfg;
> > +       u32 ctl;
> > +       u32 reserved1[2];
> > +       u32 data;
> > +};
> > +
> > +struct mt7620_spi {
> > +       void __iomem *regs;
> > +       struct mt7620_spi_master_regs *m[MT7620_SPI_NUM_CS];
> > +       unsigned int sys_freq;
> > +       u32 wait_us;
> > +       uint mode;
> > +       uint speed;
> > +};
> > +
> > +static void mt7620_spi_master_setup(struct mt7620_spi *ms, int cs)
> > +{
> > +       u32 rate, prescale, freq, tmo, cfg;
> > +
> > +       /* Calculate the clock divsior */
> > +       rate = DIV_ROUND_UP(ms->sys_freq, ms->speed);
> > +       rate = roundup_pow_of_two(rate);
> > +
> > +       prescale = ilog2(rate / 2);
> > +       if (prescale > 6)
> > +               prescale = 6;
> > +
> > +       /* Calculate the real clock, and usecs for one byte transaction */
> > +       freq = ms->sys_freq >> (prescale + 1);
> > +       tmo = DIV_ROUND_UP(8 * 1000000, freq);
> > +
> > +       /* 10 times tolerance plus 100us */
> > +       ms->wait_us = 10 * tmo + 100;
> 
> Replace the above magic numbers with meaningful macros.

ok.

> 
> > +
> > +       /* set SPI_CFG */
> > +       cfg = prescale << SPI_CLK_S;
> > +
> > +       switch (ms->mode & (SPI_CPOL | SPI_CPHA)) {
> > +       case SPI_MODE_0:
> > +               cfg |= TX_CLK_EDGE;
> > +               break;
> > +       case SPI_MODE_1:
> > +               cfg |= RX_CLK_EDGE;
> > +               break;
> > +       case SPI_MODE_2:
> > +               cfg |= SPI_CLK_POL | RX_CLK_EDGE;
> > +               break;
> > +       case SPI_MODE_3:
> > +               cfg |= SPI_CLK_POL | TX_CLK_EDGE;
> > +               break;
> > +       }
> > +
> > +       if (!(ms->mode & SPI_LSB_FIRST))
> > +               cfg |= MSB_FIRST;
> > +
> > +       writel(cfg, &ms->m[cs]->cfg);
> > +
> > +       writel(SPI_HIGH, &ms->m[cs]->ctl);
> > +}
> > +
> > +static void mt7620_spi_set_cs(struct mt7620_spi *ms, int cs, int enable)
> > +{
> > +       if (enable)
> > +               mt7620_spi_master_setup(ms, cs);
> > +
> > +       if (ms->mode & SPI_CS_HIGH)
> > +               enable = !enable;
> > +
> > +       if (enable)
> > +               clrbits_32(&ms->m[cs]->ctl, SPI_HIGH);
> > +       else
> > +               setbits_32(&ms->m[cs]->ctl, SPI_HIGH);
> > +}
> > +
> > +static int mt7620_spi_set_mode(struct udevice *bus, uint mode)
> > +{
> > +       struct mt7620_spi *ms = dev_get_priv(bus);
> > +
> > +       ms->mode = mode;
> > +
> > +       /* Mode 0 is buggy. Force to use mode 3 */
> > +       if ((mode & SPI_MODE_3) == SPI_MODE_0)
> > +               ms->mode |= SPI_MODE_3;
> > +
> > +       return 0;
> > +}
> > +
> > +static int mt7620_spi_set_speed(struct udevice *bus, uint speed)
> > +{
> > +       struct mt7620_spi *ms = dev_get_priv(bus);
> > +
> > +       ms->speed = speed;
> > +
> > +       return 0;
> > +}
> > +
> > +static inline int mt7620_spi_busy_poll(struct mt7620_spi *ms, int cs)
> > +{
> > +       u32 val;
> > +
> > +       return readl_poll_timeout(&ms->m[cs]->stat, val, !(val & SPI_BUSY),
> > +                                 ms->wait_us);
> > +}
> > +
> > +static int mt7620_spi_read(struct mt7620_spi *ms, int cs, u8 *buf, size_t len)
> > +{
> > +       int ret;
> > +
> > +       while (len) {
> > +               setbits_32(&ms->m[cs]->ctl, START_RD);
> > +
> > +               ret = mt7620_spi_busy_poll(ms, cs);
> > +               if (ret) {
> > +                       pr_err("SPI read transaction timeout\n");
> > +                       return ret;
> > +               }
> > +
> > +               *buf++ = (u8)readl(&ms->m[cs]->data);
> > +
> > +               len--;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static int mt7620_spi_write(struct mt7620_spi *ms, int cs, const u8 *buf,
> > +                           size_t len)
> > +{
> > +       int ret;
> > +
> > +       while (len) {
> > +               writel(*buf++, &ms->m[cs]->data);
> > +               setbits_32(&ms->m[cs]->ctl, START_WR);
> > +
> > +               ret = mt7620_spi_busy_poll(ms, cs);
> > +               if (ret) {
> > +                       pr_err("SPI write transaction timeout\n");
> > +                       return ret;
> > +               }
> > +
> > +               len--;
> > +       }
> > +
> > +       return 0;
> > +}
> > +
> > +static int mt7620_spi_xfer(struct udevice *dev, unsigned int bitlen,
> > +                          const void *dout, void *din, unsigned long flags)
> > +{
> > +       struct udevice *bus = dev->parent;
> > +       struct mt7620_spi *ms = dev_get_priv(bus);
> > +       int total_size = bitlen >> 3;
> > +       int cs, ret = 0;
> > +
> > +       /*
> > +        * This driver only supports half-duplex, so complain and bail out
> > +        * upon full-duplex messages
> > +        */
> > +       if (dout && din) {
> > +               pr_err("Only half-duplex SPI transfer supported\n");
> > +               return -EIO;
> > +       }
> > +
> > +       cs = spi_chip_select(dev);
> > +       if (cs < 0 || cs >= MT7620_SPI_NUM_CS) {
> > +               pr_err("Invalid chip select %d\n", cs);
> > +               return -EINVAL;
> > +       }
> > +
> > +       if (flags & SPI_XFER_BEGIN)
> > +               mt7620_spi_set_cs(ms, cs, 1);
> 
> use boolean type for last argument.

ok.

> 
> > +
> > +       if (din)
> > +               ret = mt7620_spi_read(ms, cs, din, total_size);
> > +       else if (dout)
> > +               ret = mt7620_spi_write(ms, cs, dout, total_size);
> > +
> > +       if (flags & SPI_XFER_END)
> > +               mt7620_spi_set_cs(ms, cs, 0);
> 
> same as above.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 14/21] watchdog: add watchdog driver for MediaTek MT7620 SoC
  2020-11-02  6:02   ` Jagan Teki
@ 2020-11-09  2:13     ` Weijie Gao
  0 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-11-09  2:13 UTC (permalink / raw)
  To: u-boot

On Mon, 2020-11-02 at 11:32 +0530, Jagan Teki wrote:
> On Fri, Oct 30, 2020 at 3:04 PM Weijie Gao <weijie.gao@mediatek.com> wrote:
> >
> > This patch adds watchdog support for the Mediatek MT7620 SoC
> >
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> > v2 changes: add expire_now
> > ---
> >  drivers/watchdog/Kconfig      |   7 ++
> >  drivers/watchdog/Makefile     |   1 +
> >  drivers/watchdog/mt7620_wdt.c | 132 ++++++++++++++++++++++++++++++++++
> >  3 files changed, 140 insertions(+)
> >  create mode 100644 drivers/watchdog/mt7620_wdt.c
> >
> > diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> > index 210d9f8093..35d078caa0 100644
> > --- a/drivers/watchdog/Kconfig
> > +++ b/drivers/watchdog/Kconfig
> > @@ -124,6 +124,13 @@ config WDT_MPC8xx
> >         help
> >           Select this to enable mpc8xx watchdog timer
> >
> > +config WDT_MT7620
> > +       bool "MediaTek MT7620 watchdog timer support"
> > +       depends on WDT && SOC_MT7620
> > +       help
> > +         Select this to enable watchdog timer on MediaTek MT7620 and earlier
> > +         SoC chips.
> > +
> >  config WDT_MT7621
> >         bool "MediaTek MT7621 watchdog timer support"
> >         depends on WDT && SOC_MT7628
> > diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> > index 01b8231f2b..825b50e626 100644
> > --- a/drivers/watchdog/Makefile
> > +++ b/drivers/watchdog/Makefile
> > @@ -24,6 +24,7 @@ obj-$(CONFIG_WDT_CORTINA) += cortina_wdt.o
> >  obj-$(CONFIG_WDT_ORION) += orion_wdt.o
> >  obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
> >  obj-$(CONFIG_WDT_MPC8xx) += mpc8xx_wdt.o
> > +obj-$(CONFIG_WDT_MT7620) += mt7620_wdt.o
> >  obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
> >  obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
> >  obj-$(CONFIG_WDT_OCTEONTX) += octeontx_wdt.o
> > diff --git a/drivers/watchdog/mt7620_wdt.c b/drivers/watchdog/mt7620_wdt.c
> > new file mode 100644
> > index 0000000000..2643167f8f
> > --- /dev/null
> > +++ b/drivers/watchdog/mt7620_wdt.c
> > @@ -0,0 +1,132 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc.
> > + *
> > + * Author:  Weijie Gao <weijie.gao@mediatek.com>
> > + *
> > + * Watchdog timer for MT7620 and earlier SoCs
> > + */
> > +
> > +#include <div64.h>
> > +#include <dm.h>
> > +#include <reset.h>
> > +#include <wdt.h>
> > +#include <linux/bitops.h>
> > +#include <linux/io.h>
> > +
> > +struct mt7620_wdt {
> > +       void __iomem *regs;
> > +       u64 timeout;
> > +};
> > +
> > +#define TIMER_FREQ                     40000000
> > +#define TIMER_MASK                     0xffff
> > +#define TIMER_PRESCALE                 65536
> > +
> > +#define TIMER_LOAD                     0x00
> > +#define TIMER_CTL                      0x08
> > +
> > +#define TIMER_ENABLE                   BIT(7)
> > +#define TIMER_MODE_SHIFT               4
> > +#define   TIMER_MODE_WDT               3
> > +#define TIMER_PRESCALE_SHIFT           0
> > +#define   TIMER_PRESCALE_65536         15
> > +
> > +static void mt7620_wdt_ping(struct mt7620_wdt *priv)
> > +{
> > +       u64 val;
> > +
> > +       val = (TIMER_FREQ / TIMER_PRESCALE) * priv->timeout;
> > +       do_div(val, 1000);
> > +
> > +       if (val > TIMER_MASK)
> > +               val = TIMER_MASK;
> > +
> > +       writel(val, priv->regs + TIMER_LOAD);
> > +}
> > +
> > +static int mt7620_wdt_start(struct udevice *dev, u64 ms, ulong flags)
> > +{
> > +       struct mt7620_wdt *priv = dev_get_priv(dev);
> > +
> > +       priv->timeout = ms;
> > +       mt7620_wdt_ping(priv);
> > +
> > +       writel(TIMER_ENABLE | (TIMER_MODE_WDT << TIMER_MODE_SHIFT) |
> > +              (TIMER_PRESCALE_65536 << TIMER_PRESCALE_SHIFT),
> > +              priv->regs + TIMER_CTL);
> > +
> > +       return 0;
> > +}
> > +
> > +static int mt7620_wdt_stop(struct udevice *dev)
> > +{
> > +       struct mt7620_wdt *priv = dev_get_priv(dev);
> > +
> > +       mt7620_wdt_ping(priv);
> > +
> > +       clrbits_32(priv->regs + TIMER_CTL, TIMER_ENABLE);
> > +
> > +       return 0;
> > +}
> > +
> > +static int mt7620_wdt_reset(struct udevice *dev)
> > +{
> > +       struct mt7620_wdt *priv = dev_get_priv(dev);
> > +
> > +       mt7620_wdt_ping(priv);
> > +
> > +       return 0;
> > +}
> > +
> > +static int mt7620_wdt_expire_now(struct udevice *dev, ulong flags)
> > +{
> > +       struct mt7620_wdt *priv = dev_get_priv(dev);
> > +
> > +       mt7620_wdt_start(dev, 1, flags);
> > +
> > +       /* 0 will disable the timer, so use 1 instead */
> > +       writel(1, priv->regs + TIMER_LOAD);
> 
> Better replace the magic number with macro.
> Otherwise,

this line means load timer with value 1. Since the timer is a countdown,
1 is the smallest value to cause a wdt timeout.

> 
> Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH v2 17/21] phy: add USB PHY driver for MediaTek MT7620 SoC
  2020-11-02  6:11   ` Jagan Teki
@ 2020-11-09  2:14     ` Weijie Gao
  0 siblings, 0 replies; 30+ messages in thread
From: Weijie Gao @ 2020-11-09  2:14 UTC (permalink / raw)
  To: u-boot

On Mon, 2020-11-02 at 11:41 +0530, Jagan Teki wrote:
> On Fri, Oct 30, 2020 at 3:05 PM Weijie Gao <weijie.gao@mediatek.com> wrote:
> >
> > This patch adds USB PHY driver for MediaTek MT7620 SoC
> >
> > Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
> > ---
> > v2 changes: none
> > ---
> >  drivers/phy/Kconfig          |   7 +++
> >  drivers/phy/Makefile         |   1 +
> >  drivers/phy/mt7620-usb-phy.c | 113 +++++++++++++++++++++++++++++++++++
> >  3 files changed, 121 insertions(+)
> >  create mode 100644 drivers/phy/mt7620-usb-phy.c
> >
> > diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
> > index d12a6b02ad..ab638f0e7d 100644
> > --- a/drivers/phy/Kconfig
> > +++ b/drivers/phy/Kconfig
> > @@ -218,6 +218,13 @@ config KEYSTONE_USB_PHY
> >
> >           This PHY is found on some Keystone (K2) devices supporting USB.
> >
> > +config MT7620_USB_PHY
> > +       bool "MediaTek MT7620 USB PHY support"
> > +       depends on PHY
> > +       depends on SOC_MT7620
> > +       help
> > +          Support the intergated USB PHY in MediaTek MT7620 SoC
> > +
> >  config MT76X8_USB_PHY
> >         bool "MediaTek MT76x8 (7628/88) USB PHY support"
> >         depends on PHY
> > diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
> > index 45a7fe5b56..6b3761b8c8 100644
> > --- a/drivers/phy/Makefile
> > +++ b/drivers/phy/Makefile
> > @@ -24,6 +24,7 @@ obj-$(CONFIG_MESON_G12A_USB_PHY) += meson-g12a-usb2.o meson-g12a-usb3-pcie.o
> >  obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o
> >  obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o
> >  obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o
> > +obj-$(CONFIG_MT7620_USB_PHY) += mt7620-usb-phy.o
> >  obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o
> >  obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o
> >  obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o
> > diff --git a/drivers/phy/mt7620-usb-phy.c b/drivers/phy/mt7620-usb-phy.c
> > new file mode 100644
> > index 0000000000..59ac32f327
> > --- /dev/null
> > +++ b/drivers/phy/mt7620-usb-phy.c
> > @@ -0,0 +1,113 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
> > + *
> > + * Author: Weijie Gao <weijie.gao@mediatek.com>
> > + */
> > +
> > +#include <clk.h>
> > +#include <dm.h>
> > +#include <generic-phy.h>
> > +#include <misc.h>
> > +#include <reset.h>
> > +#include <dm/device_compat.h>
> > +#include <linux/delay.h>
> > +#include <mach/mt7620-sysc.h>
> > +
> > +struct mt7620_usb_phy {
> > +       struct udevice *dev;
> 
> Why this explicit dev required here? generic_phy_get_ calls will assign phy->dev

I didn't notice that. This will be modified in next series.

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2020-11-09  2:14 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-30  9:33 [PATCH v2 00/21] Add support for MediaTek MT7620 SoC Weijie Gao
2020-10-30  9:33 ` [PATCH v2 01/21] mips: dts: switch to board defines for dtb for mtmips Weijie Gao
2020-10-30  9:33 ` [PATCH v2 02/21] mips: mtmips: move mt7628 related Kconfig into mt7628 subdirectory Weijie Gao
2020-10-30  9:33 ` [PATCH v2 03/21] mips: mtmips: select SYSRESET for mt7628 only Weijie Gao
2020-10-30  9:33 ` [PATCH v2 04/21] mips: mtmips: fix dram size detection in dram_init Weijie Gao
2020-10-30  9:33 ` [PATCH v2 05/21] mips: enable _machine_restart for spl Weijie Gao
2020-11-03 15:12   ` Simon Glass
2020-10-30  9:34 ` [PATCH v2 06/21] mips: mtmips: add support to initialize SDRAM Weijie Gao
2020-10-30  9:34 ` [PATCH v2 07/21] mips: mtmips: add support for MediaTek MT7620 SoC Weijie Gao
2020-10-30  9:34 ` [PATCH v2 08/21] mips: mtmips: add two reference boards for mt7620 Weijie Gao
2020-10-30  9:34 ` [PATCH v2 09/21] configs: mtmips: refresh for mt7628 based boards Weijie Gao
2020-10-30  9:34 ` [PATCH v2 10/21] serial: add uart driver for MediaTek MT7620 SoC Weijie Gao
2020-11-03 15:12   ` Simon Glass
2020-10-30  9:34 ` [PATCH v2 11/21] clk: add clock " Weijie Gao
2020-10-30  9:34 ` [PATCH v2 12/21] reset: mtmips: add reset controller support " Weijie Gao
2020-10-30  9:34 ` [PATCH v2 13/21] pinctrl: mtmips: add " Weijie Gao
2020-10-30  9:34 ` [PATCH v2 14/21] watchdog: add watchdog driver " Weijie Gao
2020-11-02  6:02   ` Jagan Teki
2020-11-09  2:13     ` Weijie Gao
2020-10-30  9:34 ` [PATCH v2 15/21] gpio: add GPIO controller " Weijie Gao
2020-10-30  9:35 ` [PATCH v2 16/21] spi: add spi controller support " Weijie Gao
2020-11-02  6:00   ` Jagan Teki
2020-11-09  2:10     ` Weijie Gao
2020-10-30  9:35 ` [PATCH v2 17/21] phy: add USB PHY driver " Weijie Gao
2020-11-02  6:11   ` Jagan Teki
2020-11-09  2:14     ` Weijie Gao
2020-10-30  9:35 ` [PATCH v2 18/21] net: add ethernet " Weijie Gao
2020-10-30  9:35 ` [PATCH v2 19/21] mmc: mtk-sd: add pad control settings for MediaTek MT7620/MT76x8 SoCs Weijie Gao
2020-10-30  9:35 ` [PATCH v2 20/21] reset: reset-mtmips: add DM_FLAG_PRE_RELOC flag Weijie Gao
2020-10-30  9:35 ` [PATCH v2 21/21] MAINTAINERS: add maintainer for MediaTek MIPS platform Weijie Gao

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.