[PATCH v3 00/15] Add support for MediaTek MT7621 SoC

This series will add support for MediaTek MT7621 SoC with two reference boards and related drivers.
The MediaTek MT7621 is a network processor integrating a dual-core dual-threaded MIPS 1004Kc processor running at a normal frequency of 880MHz. This chip can be found in many wireless routers.
This series add all basic drivers which are useful in u-boot, like usb, sdxc, ethernet, spi, nand and serial.
Currently this patch series only supports building the ram-bootable image as it needs the preloader from MediaTek SDK.
Thanks, Weijie
v3 changes: - Rewrite clk driver to follow definitions from upstream kernel - Implement noncached_alloc() for MIPS platform - Update register remap for mtk-eth driver needed by mt7621
v2 changes: - Add a kconfig for max supported ram size - Remove network configs from default config file - Add config file for mt7621-rfb boards
Weijie Gao (15): mips: mtmips: add support for MediaTek MT7621 SoC mips: mtmips: add two reference boards for mt7621 mips: add support for noncached_alloc() clk: mtmips: add clock driver for MediaTek MT7621 SoC reset: mtmips: add reset controller support for MediaTek MT7621 SoC pinctrl: mtmips: add support for MediaTek MT7621 SoC nand: raw: add support for MediaTek MT7621 SoC usb: xhci-mtk: add support for MediaTek MT7621 SoC phy: mtk-tphy: add support for MediaTek MT7621 SoC spi: add support for MediaTek MT7621 SoC gpio: add support for MediaTek MT7621 SoC watchdog: add support for MediaTek MT7621 SoC mmc: mediatek: add support for MediaTek MT7621 SoC net: mediatek: add support for MediaTek MT7621 SoC MAINTAINERS: update maintainer for MediaTek MIPS platform
MAINTAINERS | 5 + arch/mips/dts/Makefile | 2 + arch/mips/dts/mediatek,mt7621-nand-rfb.dts | 52 + arch/mips/dts/mediatek,mt7621-rfb.dts | 68 + arch/mips/dts/mt7621.dtsi | 370 +++++ arch/mips/include/asm/system.h | 20 + arch/mips/lib/cache.c | 43 + arch/mips/mach-mtmips/Kconfig | 34 +- arch/mips/mach-mtmips/Makefile | 5 + arch/mips/mach-mtmips/cpu.c | 2 +- arch/mips/mach-mtmips/mt7621/Kconfig | 43 + arch/mips/mach-mtmips/mt7621/Makefile | 4 + arch/mips/mach-mtmips/mt7621/init.c | 153 +++ arch/mips/mach-mtmips/mt7621/mt7621.h | 204 +++ arch/mips/mach-mtmips/mt7621/serial.c | 23 + board/mediatek/mt7621/MAINTAINERS | 9 + board/mediatek/mt7621/Makefile | 3 + board/mediatek/mt7621/board.c | 6 + configs/mt7621_nand_rfb_ramboot_defconfig | 72 + configs/mt7621_rfb_ramboot_defconfig | 75 ++ drivers/clk/mtmips/Makefile | 1 + drivers/clk/mtmips/clk-mt7621.c | 313 +++++ drivers/gpio/Kconfig | 2 +- drivers/mmc/mtk-sd.c | 13 + drivers/mtd/nand/raw/Kconfig | 11 + drivers/mtd/nand/raw/Makefile | 1 + drivers/mtd/nand/raw/mt7621_nand.c | 1189 +++++++++++++++++ drivers/net/mtk_eth.c | 45 +- drivers/phy/Kconfig | 2 +- drivers/pinctrl/mtmips/Kconfig | 9 + drivers/pinctrl/mtmips/Makefile | 1 + drivers/pinctrl/mtmips/pinctrl-mt7621.c | 307 +++++ .../pinctrl/mtmips/pinctrl-mtmips-common.c | 4 +- .../pinctrl/mtmips/pinctrl-mtmips-common.h | 12 + drivers/spi/Kconfig | 2 +- drivers/usb/host/Kconfig | 2 +- drivers/watchdog/Kconfig | 2 +- include/configs/mt7621-rfb.h | 18 + include/configs/mt7621.h | 38 + include/dt-bindings/clock/mt7621-clk.h | 46 + include/dt-bindings/reset/mt7621-reset.h | 38 + 41 files changed, 3219 insertions(+), 30 deletions(-) create mode 100644 arch/mips/dts/mediatek,mt7621-nand-rfb.dts create mode 100644 arch/mips/dts/mediatek,mt7621-rfb.dts create mode 100644 arch/mips/dts/mt7621.dtsi create mode 100644 arch/mips/mach-mtmips/mt7621/Kconfig create mode 100644 arch/mips/mach-mtmips/mt7621/Makefile create mode 100644 arch/mips/mach-mtmips/mt7621/init.c create mode 100644 arch/mips/mach-mtmips/mt7621/mt7621.h create mode 100644 arch/mips/mach-mtmips/mt7621/serial.c create mode 100644 board/mediatek/mt7621/MAINTAINERS create mode 100644 board/mediatek/mt7621/Makefile create mode 100644 board/mediatek/mt7621/board.c create mode 100644 configs/mt7621_nand_rfb_ramboot_defconfig create mode 100644 configs/mt7621_rfb_ramboot_defconfig create mode 100644 drivers/clk/mtmips/clk-mt7621.c create mode 100644 drivers/mtd/nand/raw/mt7621_nand.c create mode 100644 drivers/pinctrl/mtmips/pinctrl-mt7621.c create mode 100644 include/configs/mt7621-rfb.h create mode 100644 include/configs/mt7621.h create mode 100644 include/dt-bindings/clock/mt7621-clk.h create mode 100644 include/dt-bindings/reset/mt7621-reset.h

This patch adds support for MediaTek MT7621 SoC. All files are dedicated for u-boot.
Currently only ramboot is supported. The default build target is u-boot-lzma.img. This file can be booted using bootm command, or be used as a payload of the SDK preloader of MT7621.
The specification of this chip: https://www.mediatek.com/products/homenetworking/mt7621
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: Update clock name for mt7621.dtsi due to clk driver changed v2 changes: Add a kconfig for max supported ram size Remove network configs from default config file --- arch/mips/dts/mt7621.dtsi | 370 ++++++++++++++++++++++++++ arch/mips/mach-mtmips/Kconfig | 34 ++- arch/mips/mach-mtmips/Makefile | 5 + arch/mips/mach-mtmips/cpu.c | 2 +- arch/mips/mach-mtmips/mt7621/Kconfig | 23 ++ arch/mips/mach-mtmips/mt7621/Makefile | 4 + arch/mips/mach-mtmips/mt7621/init.c | 153 +++++++++++ arch/mips/mach-mtmips/mt7621/mt7621.h | 204 ++++++++++++++ arch/mips/mach-mtmips/mt7621/serial.c | 23 ++ include/configs/mt7621.h | 38 +++ 10 files changed, 851 insertions(+), 5 deletions(-) create mode 100644 arch/mips/dts/mt7621.dtsi create mode 100644 arch/mips/mach-mtmips/mt7621/Kconfig create mode 100644 arch/mips/mach-mtmips/mt7621/Makefile create mode 100644 arch/mips/mach-mtmips/mt7621/init.c create mode 100644 arch/mips/mach-mtmips/mt7621/mt7621.h create mode 100644 arch/mips/mach-mtmips/mt7621/serial.c create mode 100644 include/configs/mt7621.h
diff --git a/arch/mips/dts/mt7621.dtsi b/arch/mips/dts/mt7621.dtsi new file mode 100644 index 0000000000..7fec87abe7 --- /dev/null +++ b/arch/mips/dts/mt7621.dtsi @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#include <dt-bindings/clock/mt7621-clk.h> +#include <dt-bindings/reset/mt7621-reset.h> +#include <dt-bindings/phy/phy.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "mediatek,mt7621-soc"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "mips,mips1004Kc"; + reg = <0>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "mips,mips1004Kc"; + reg = <0>; + }; + }; + + clk48m: clk48m@0 { + compatible = "fixed-clock"; + + clock-frequency = <48000000>; + + #clock-cells = <0>; + }; + + clk50m: clk50m@0 { + compatible = "fixed-clock"; + + clock-frequency = <50000000>; + + #clock-cells = <0>; + }; + + sysc: sysc@1e000000 { + compatible = "mediatek,mt7621-sysc", "syscon"; + reg = <0x1e000000 0x100>; + }; + + clkctrl: clkctrl@1e000030 { + compatible = "mediatek,mt7621-clk"; + mediatek,sysc = <&sysc>; + mediatek,memc = <&memc>; + + #clock-cells = <1>; + u-boot,dm-pre-reloc; + }; + + rstctrl: rstctrl@1e000034 { + compatible = "mediatek,mtmips-reset"; + reg = <0x1e000034 0x4>; + #reset-cells = <1>; + }; + + reboot: resetctl-reboot { + compatible = "resetctl-reboot"; + + resets = <&rstctrl RST_SYS>; + reset-names = "sysreset"; + }; + + memc: memc@1e005000 { + compatible = "mediatek,mt7621-memc", "syscon"; + reg = <0x1e005000 0x1000>; + }; + + pinctrl: pinctrl@1e000060 { + compatible = "mediatek,mt7621-pinctrl"; + reg = <0x1e000048 0x30>; + + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pin_state { + uart1 { + groups = "uart1"; + function = "uart"; + }; + + gpios { + groups = "i2c", "uart3", "pcie reset"; + function = "gpio"; + }; + + jtag { + groups = "jtag"; + function = "jtag"; + }; + + wdt { + groups = "wdt"; + function = "wdt rst"; + }; + }; + + uart1_pins: uart1_pins { + groups = "uart1"; + function = "uart"; + }; + + uart2_pins: uart2_pins { + groups = "uart2"; + function = "uart"; + }; + + uart3_pins: uart3_pins { + groups = "uart3"; + function = "uart"; + }; + + sdxc_pins: sdxc_pins { + groups = "sdxc"; + function = "sdxc"; + }; + + spi_pins: spi_pins { + groups = "spi"; + function = "spi"; + }; + + eth_pins: eth_pins { + mdio_pins { + groups = "mdio"; + function = "mdio"; + }; + + rgmii1_pins { + groups = "rgmii1"; + function = "rgmii"; + }; + + esw_pins { + groups = "esw int"; + function = "esw int"; + }; + + mdio_pconf { + groups = "mdio"; + drive-strength = <2>; + }; + }; + }; + + watchdog: watchdog@1e000100 { + compatible = "mediatek,mt7621-wdt"; + reg = <0x1e000100 0x40>; + + resets = <&rstctrl RST_TIMER>; + reset-names = "wdt"; + + status = "disabled"; + }; + + gpio: gpio@1e000600 { + #address-cells = <1>; + #size-cells = <0>; + + compatible = "mtk,mt7621-gpio"; + reg = <0x1e000600 0x100>; + + resets = <&rstctrl RST_PIO>; + reset-names = "pio"; + + gpio0: bank@0 { + reg = <0>; + compatible = "mtk,mt7621-gpio-bank"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio1: bank@1 { + reg = <1>; + compatible = "mtk,mt7621-gpio-bank"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio2: bank@2 { + reg = <2>; + compatible = "mtk,mt7621-gpio-bank"; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + spi: spi@1e000b00 { + compatible = "ralink,mt7621-spi"; + reg = <0x1e000b00 0x40>; + + status = "disabled"; + + pinctrl-names = "default"; + pinctrl-0 = <&spi_pins>; + + resets = <&rstctrl RST_SPI>; + reset-names = "spi"; + + clocks = <&clkctrl MT7621_CLK_SPI>; + + #address-cells = <1>; + #size-cells = <0>; + }; + + uart0: uart1@1e000c00 { + compatible = "mediatek,hsuart", "ns16550a"; + reg = <0x1e000c00 0x100>; + + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + + clocks = <&clkctrl MT7621_CLK_UART1>; + + resets = <&rstctrl RST_UART1>; + + reg-shift = <2>; + }; + + uart1: uart2@1e000d00 { + compatible = "mediatek,hsuart", "ns16550a"; + reg = <0x1e000d00 0x100>; + + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins>; + + clocks = <&clkctrl MT7621_CLK_UART2>; + + resets = <&rstctrl RST_UART2>; + + reg-shift = <2>; + + status = "disabled"; + }; + + uart2: uart3@1e000e00 { + compatible = "mediatek,hsuart", "ns16550a"; + reg = <0x1e000e00 0x100>; + + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins>; + + clocks = <&clkctrl MT7621_CLK_UART3>; + + resets = <&rstctrl RST_UART3>; + + reg-shift = <2>; + + status = "disabled"; + }; + + eth: eth@1e100000 { + compatible = "mediatek,mt7621-eth"; + reg = <0x1e100000 0x20000>; + mediatek,ethsys = <&sysc>; + + pinctrl-names = "default"; + pinctrl-0 = <ð_pins>; + + resets = <&rstctrl RST_FE>, <&rstctrl RST_GMAC>, <&rstctrl RST_MCM>; + reset-names = "fe", "gmac", "mcm"; + + clocks = <&clkctrl MT7621_CLK_GDMA>, + <&clkctrl MT7621_CLK_ETH>; + clock-names = "gmac", "fe"; + + #address-cells = <1>; + #size-cells = <0>; + + mediatek,gmac-id = <0>; + phy-mode = "rgmii"; + mediatek,switch = "mt7530"; + mediatek,mcm; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + + mmc: mmc@1e130000 { + compatible = "mediatek,mt7621-mmc"; + reg = <0x1e130000 0x4000>; + + status = "disabled"; + + bus-width = <4>; + builtin-cd = <1>; + r_smpl = <1>; + + pinctrl-names = "default"; + pinctrl-0 = <&sdxc_pins>; + + clocks = <&clk50m>, <&clkctrl MT7621_CLK_SHXC>; + clock-names = "source", "hclk"; + + resets = <&rstctrl RST_SDXC>; + }; + + ssusb: usb@1e1c0000 { + compatible = "mediatek,mt7621-xhci", "mediatek,mtk-xhci"; + reg = <0x1e1c0000 0x1000>, <0x1e1d0700 0x100>; + reg-names = "mac", "ippc"; + + clocks = <&clk48m>, <&clk48m>; + clock-names = "sys_ck", "ref_ck"; + + phys = <&u2port0 PHY_TYPE_USB2>, + <&u3port0 PHY_TYPE_USB3>, + <&u2port1 PHY_TYPE_USB2>; + + status = "disabled"; + }; + + u3phy: usb-phy@1e1d0000 { + compatible = "mediatek,mt7621-u3phy", + "mediatek,generic-tphy-v1"; + reg = <0x1e1d0000 0x700>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + status = "disabled"; + + u2port0: usb-phy@1e1d0800 { + reg = <0x1e1d0800 0x0100>; + #phy-cells = <1>; + clocks = <&clk48m>; + clock-names = "ref"; + }; + + u3port0: usb-phy@1e1d0900 { + reg = <0x1e1d0900 0x0100>; + #phy-cells = <1>; + }; + + u2port1: usb-phy@1e1d1000 { + reg = <0x1e1d1000 0x0100>; + #phy-cells = <1>; + clocks = <&clk48m>; + clock-names = "ref"; + }; + }; + + i2c: i2c@1e000900 { + compatible = "i2c-gpio"; + + status = "disabled"; + + i2c-gpio,delay-us = <3>; + + gpios = <&gpio0 3 1>, /* PIN3 as SDA */ + <&gpio0 4 1>; /* PIN4 as CLK */ + + #address-cells = <1>; + #size-cells = <0>; + }; +}; diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig index 151b004603..a73e9f8bd8 100644 --- a/arch/mips/mach-mtmips/Kconfig +++ b/arch/mips/mach-mtmips/Kconfig @@ -9,6 +9,7 @@ config SYS_MALLOC_F_LEN
config SYS_SOC default "mt7620" if SOC_MT7620 + default "mt7621" if SOC_MT7621 default "mt7628" if SOC_MT7628
config SYS_DCACHE_SIZE @@ -18,25 +19,36 @@ config SYS_DCACHE_LINE_SIZE default 32
config SYS_ICACHE_SIZE - default 65536 + default 65536 if SOC_MT7620 || SOC_MT7628 + default 32768 if SOC_MT7621
config SYS_ICACHE_LINE_SIZE default 32
config SYS_TEXT_BASE - default 0x9c000000 if !SPL - default 0x80200000 if SPL + default 0x9c000000 if !SPL && !SOC_MT7621 + default 0x80200000 if SPL || SOC_MT7621
config SPL_TEXT_BASE - default 0x9c000000 + default 0x9c000000 if !SOC_MT7621 + default 0x80100000 if SOC_MT7621 + +config TPL_TEXT_BASE + default 0xbfc00000 if SOC_MT7621
config SPL_PAYLOAD default "u-boot-lzma.img" if SPL_LZMA
config BUILD_TARGET + default "u-boot-lzma.img" if SOC_MT7621 # Only ramboot is supported now default "u-boot-with-spl.bin" if SPL default "u-boot.bin"
+config MAX_MEM_SIZE + int + default 256 if SOC_MT7620 || SOC_MT7628 + default 512 if SOC_MT7621 + choice prompt "MediaTek MIPS SoC select"
@@ -55,6 +67,19 @@ config SOC_MT7620 help This supports MediaTek MT7620.
+config SOC_MT7621 + bool "MT7621" + select MIPS_CM + select MIPS_L2_CACHE + select SYS_CACHE_SHIFT_5 + select SYS_MIPS_CACHE_INIT_RAM_LOAD + select PINCTRL_MT7621 + select MTK_SERIAL + select REGMAP + select SYSCON + help + This supports MediaTek MT7621. + config SOC_MT7628 bool "MT7628" select SYS_CACHE_SHIFT_5 @@ -80,6 +105,7 @@ config SOC_MT7628 endchoice
source "arch/mips/mach-mtmips/mt7620/Kconfig" +source "arch/mips/mach-mtmips/mt7621/Kconfig" source "arch/mips/mach-mtmips/mt7628/Kconfig"
endmenu diff --git a/arch/mips/mach-mtmips/Makefile b/arch/mips/mach-mtmips/Makefile index 4909b47ef2..9ab882dee0 100644 --- a/arch/mips/mach-mtmips/Makefile +++ b/arch/mips/mach-mtmips/Makefile @@ -1,9 +1,14 @@ # SPDX-License-Identifier: GPL-2.0+
obj-y += cpu.o + +ifneq ($(CONFIG_SOC_MT7621),y) obj-y += ddr_init.o obj-y += ddr_cal.o +endif + obj-$(CONFIG_SPL_BUILD) += spl.o
obj-$(CONFIG_SOC_MT7620) += mt7620/ +obj-$(CONFIG_SOC_MT7621) += mt7621/ obj-$(CONFIG_SOC_MT7628) += mt7628/ diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach-mtmips/cpu.c index a4b5cff61d..f1e9022738 100644 --- a/arch/mips/mach-mtmips/cpu.c +++ b/arch/mips/mach-mtmips/cpu.c @@ -16,7 +16,7 @@ DECLARE_GLOBAL_DATA_PTR;
int dram_init(void) { - gd->ram_size = get_ram_size((void *)KSEG1, SZ_256M); + gd->ram_size = get_ram_size((void *)KSEG1, CONFIG_MAX_MEM_SIZE << 20);
return 0; } diff --git a/arch/mips/mach-mtmips/mt7621/Kconfig b/arch/mips/mach-mtmips/mt7621/Kconfig new file mode 100644 index 0000000000..6948bee31b --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/Kconfig @@ -0,0 +1,23 @@ + +if SOC_MT7621 + +config DEBUG_UART_BOARD_INIT + default y + +choice + prompt "Board select" + +endchoice + +config SYS_CONFIG_NAME + string "Board configuration name" + default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB + +config SYS_BOARD + string "Board name" + default "mt7621" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB + +config SYS_VENDOR + default "mediatek" if BOARD_MT7621_RFB || BOARD_MT7621_NAND_RFB + +endif diff --git a/arch/mips/mach-mtmips/mt7621/Makefile b/arch/mips/mach-mtmips/mt7621/Makefile new file mode 100644 index 0000000000..3906430077 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += init.o +obj-y += serial.o diff --git a/arch/mips/mach-mtmips/mt7621/init.c b/arch/mips/mach-mtmips/mt7621/init.c new file mode 100644 index 0000000000..7de215fae6 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/init.c @@ -0,0 +1,153 @@ +// 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 <dm/uclass.h> +#include <dt-bindings/clock/mt7621-clk.h> +#include <asm/global_data.h> +#include <linux/io.h> +#include "mt7621.h" + +DECLARE_GLOBAL_DATA_PTR; + +static const char *const boot_mode[(CHIP_MODE_M >> CHIP_MODE_S) + 1] = { + [1] = "NAND 2K+64", + [2] = "SPI-NOR 3-Byte Addr", + [3] = "SPI-NOR 4-Byte Addr", + [10] = "NAND 2K+128", + [11] = "NAND 4K+128", + [12] = "NAND 4K+256", +}; + +int print_cpuinfo(void) +{ + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); + u32 val, ver, eco, pkg, core, dram, chipmode; + u32 cpu_clk, ddr_clk, bus_clk, xtal_clk; + struct udevice *clkdev; + const char *bootdev; + struct clk clk; + int ret; + + val = readl(sysc + SYSCTL_CHIP_REV_ID_REG); + ver = (val & VER_ID_M) >> VER_ID_S; + eco = (val & ECO_ID_M) >> ECO_ID_S; + pkg = !!(val & PKG_ID); + core = !!(val & CPU_ID); + + val = readl(sysc + SYSCTL_SYSCFG0_REG); + dram = val & DRAM_TYPE; + chipmode = (val & CHIP_MODE_M) >> CHIP_MODE_S; + + bootdev = boot_mode[chipmode]; + if (!bootdev) + bootdev = "Unsupported boot mode"; + + printf("CPU: MediaTek MT7621%c ver %u, eco %u\n", + core ? (pkg ? 'A' : 'N') : 'S', ver, eco); + + printf("Boot: DDR%u, %s\n", dram ? 2 : 3, bootdev); + + ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(mt7621_clk), + &clkdev); + if (ret) + return ret; + + clk.dev = clkdev; + + clk.id = MT7621_CLK_CPU; + cpu_clk = clk_get_rate(&clk); + + clk.id = MT7621_CLK_BUS; + bus_clk = clk_get_rate(&clk); + + clk.id = MT7621_CLK_DDR; + ddr_clk = clk_get_rate(&clk); + + clk.id = MT7621_CLK_XTAL; + xtal_clk = clk_get_rate(&clk); + + /* Set final timer frequency */ + if (cpu_clk) + gd->arch.timer_freq = cpu_clk / 2; + + printf("Clock: CPU: %uMHz, DDR: %uMT/s, Bus: %uMHz, XTAL: %uMHz\n", + cpu_clk / 1000000, ddr_clk / 500000, bus_clk / 1000000, + xtal_clk / 1000000); + + return 0; +} + +void lowlevel_init(void) +{ + void __iomem *usbh = ioremap_nocache(SSUSB_BASE, SSUSB_SIZE); + + /* Setup USB xHCI */ + + writel((0x20 << SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S) | + (0x20 << SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S) | + (2 << SSUSB_MAC3_SYS_CK_GATE_MODE_S) | + (2 << SSUSB_MAC2_SYS_CK_GATE_MODE_S) | 0x10, + usbh + SSUSB_MAC_CK_CTRL_REG); + + writel((2 << SSUSB_PLL_PREDIV_PE1D_S) | (1 << SSUSB_PLL_PREDIV_U3_S) | + (4 << SSUSB_PLL_FBKDI_S), usbh + DA_SSUSB_U3PHYA_10_REG); + + writel((0x18 << SSUSB_PLL_FBKDIV_PE2H_S) | + (0x18 << SSUSB_PLL_FBKDIV_PE1D_S) | + (0x18 << SSUSB_PLL_FBKDIV_PE1H_S) | + (0x1e << SSUSB_PLL_FBKDIV_U3_S), + usbh + DA_SSUSB_PLL_FBKDIV_REG); + + writel((0x1e400000 << SSUSB_PLL_PCW_NCPO_U3_S), + usbh + DA_SSUSB_PLL_PCW_NCPO_REG); + + writel((0x25 << SSUSB_PLL_SSC_DELTA1_PE1H_S) | + (0x73 << SSUSB_PLL_SSC_DELTA1_U3_S), + usbh + DA_SSUSB_PLL_SSC_DELTA1_REG); + + writel((0x71 << SSUSB_PLL_SSC_DELTA_U3_S) | + (0x4a << SSUSB_PLL_SSC_DELTA1_PE2D_S), + usbh + DA_SSUSB_U3PHYA_21_REG); + + writel((0x140 << SSUSB_PLL_SSC_PRD_S), usbh + SSUSB_U3PHYA_9_REG); + + writel((0x11c00000 << SSUSB_SYSPLL_PCW_NCPO_S), + usbh + SSUSB_U3PHYA_3_REG); + + writel((4 << SSUSB_PCIE_CLKDRV_AMP_S) | (1 << SSUSB_SYSPLL_FBSEL_S) | + (1 << SSUSB_SYSPLL_PREDIV_S), usbh + SSUSB_U3PHYA_1_REG); + + writel((0x12 << SSUSB_SYSPLL_FBDIV_S) | SSUSB_SYSPLL_VCO_DIV_SEL | + SSUSB_SYSPLL_FPEN | SSUSB_SYSPLL_MONCK_EN | SSUSB_SYSPLL_VOD_EN, + usbh + SSUSB_U3PHYA_2_REG); + + writel(SSUSB_EQ_CURSEL | (8 << SSUSB_RX_DAC_MUX_S) | + (1 << SSUSB_PCIE_SIGDET_VTH_S) | (1 << SSUSB_PCIE_SIGDET_LPF_S), + usbh + SSUSB_U3PHYA_11_REG); + + writel((0x1ff << SSUSB_RING_OSC_CNTEND_S) | + (0x7f << SSUSB_XTAL_OSC_CNTEND_S) | SSUSB_RING_BYPASS_DET, + usbh + SSUSB_B2_ROSC_0_REG); + + writel((3 << SSUSB_RING_OSC_FRC_RECAL_S) | SSUSB_RING_OSC_FRC_SEL, + usbh + SSUSB_B2_ROSC_1_REG); +} + +ulong notrace get_tbclk(void) +{ + return gd->arch.timer_freq; +} + +void _machine_restart(void) +{ + void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); + + while (1) + writel(SYS_RST, sysc + SYSCTL_RSTCTL_REG); +} diff --git a/arch/mips/mach-mtmips/mt7621/mt7621.h b/arch/mips/mach-mtmips/mt7621/mt7621.h new file mode 100644 index 0000000000..012f5a3557 --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/mt7621.h @@ -0,0 +1,204 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2021 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#ifndef _MT7621_H_ +#define _MT7621_H_ + +#define SYSCTL_BASE 0x1e000000 +#define SYSCTL_SIZE 0x100 +#define TIMER_BASE 0x1e000100 +#define TIMER_SIZE 0x100 +#define RBUS_BASE 0x1e000400 +#define RBUS_SIZE 0x100 +#define GPIO_BASE 0x1e000600 +#define GPIO_SIZE 0x100 +#define DMA_CFG_ARB_BASE 0x1e000800 +#define DMA_CFG_ARB_SIZE 0x100 +#define SPI_BASE 0x1e000b00 +#define SPI_SIZE 0x100 +#define UART1_BASE 0x1e000c00 +#define UART1_SIZE 0x100 +#define NFI_BASE 0x1e003000 +#define NFI_SIZE 0x800 +#define NFI_ECC_BASE 0x1e003800 +#define NFI_ECC_SIZE 0x800 +#define DRAMC_BASE 0x1e005000 +#define DRAMC_SIZE 0x1000 +#define FE_BASE 0x1e100000 +#define FE_SIZE 0xe000 +#define GMAC_BASE 0x1e110000 +#define GMAC_SIZE 0x8000 +#define SSUSB_BASE 0x1e1c0000 +#define SSUSB_SIZE 0x40000 + + /* GIC Base Address */ +#define MIPS_GIC_BASE 0x1fbc0000 + + /* CPC Base Address */ +#define MIPS_CPC_BASE 0x1fbf0000 + + /* Flash Memory-mapped Base Address */ +#define FLASH_MMAP_BASE 0x1fc00000 + +/* SRAM */ +#define FE_SRAM_BASE1 0x8000 +#define FE_SRAM_BASE2 0xa000 + +/* SYSCTL_BASE */ +#define SYSCTL_CHIP_REV_ID_REG 0x0c +#define CPU_ID 0x20000 +#define PKG_ID 0x10000 +#define VER_ID_S 8 +#define VER_ID_M 0xf00 +#define ECO_ID_S 0 +#define ECO_ID_M 0x0f + +#define SYSCTL_SYSCFG0_REG 0x10 +#define XTAL_MODE_SEL_S 6 +#define XTAL_MODE_SEL_M 0x1c0 +#define DRAM_TYPE 0x10 +#define CHIP_MODE_S 0 +#define CHIP_MODE_M 0x0f + +#define BOOT_SRAM_BASE_REG 0x20 + +#define SYSCTL_CLKCFG0_REG 0x2c +#define CPU_CLK_SEL_S 30 +#define CPU_CLK_SEL_M 0xc0000000 +#define MPLL_CFG_SEL_S 23 +#define MPLL_CFG_SEL_M 0x800000 + +#define SYSCTL_RSTCTL_REG 0x34 +#define SYS_RST 0x01 + +#define SYSCTL_CUR_CLK_STS_REG 0x44 +#define CUR_CPU_FDIV_S 8 +#define CUR_CPU_FDIV_M 0x1f00 +#define CUR_CPU_FFRAC_S 0 +#define CUR_CPU_FFRAC_M 0x1f + +#define SYSCTL_GPIOMODE_REG 0x60 +#define UART2_MODE_S 5 +#define UART2_MODE_M 0x60 +#define UART3_MODE_S 3 +#define UART3_MODE_M 0x18 +#define UART1_MODE 0x02 + +/* RBUS_BASE */ +#define RBUS_DYN_CFG0_REG 0x0010 +#define CPU_FDIV_S 8 +#define CPU_FDIV_M 0x1f00 +#define CPU_FFRAC_S 0 +#define CPU_FFRAC_M 0x1f + +/* DMA_CFG_ARB_BASE */ +#define DMA_ROUTE_REG 0x000c + +/* SPI_BASE */ +#define SPI_SPACE_REG 0x003c +#define FS_SLAVE_SEL_S 12 +#define FS_SLAVE_SEL_M 0x70000 +#define FS_CLK_SEL_S 0 +#define FS_CLK_SEL_M 0xfff + +/* FE_BASE */ +#define FE_RST_GLO_REG 0x0004 +#define FE_PSE_RAM 0x04 +#define FE_PSE_MEM_EN 0x02 +#define FE_PSE_RESET 0x01 + +/* SSUSB_BASE */ +#define SSUSB_MAC_CK_CTRL_REG 0x10784 +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_S 16 +#define SSUSB_MAC3_SYS_CK_GATE_MASK_TIME_M 0xff0000 +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_S 8 +#define SSUSB_MAC2_SYS_CK_GATE_MASK_TIME_M 0xff00 +#define SSUSB_MAC3_SYS_CK_GATE_MODE_S 2 +#define SSUSB_MAC3_SYS_CK_GATE_MODE_M 0x0c +#define SSUSB_MAC2_SYS_CK_GATE_MODE_S 0 +#define SSUSB_MAC2_SYS_CK_GATE_MODE_M 0x03 + +#define SSUSB_B2_ROSC_0_REG 0x10a40 +#define SSUSB_RING_OSC_CNTEND_S 23 +#define SSUSB_RING_OSC_CNTEND_M 0xff800000 +#define SSUSB_XTAL_OSC_CNTEND_S 16 +#define SSUSB_XTAL_OSC_CNTEND_M 0x7f0000 +#define SSUSB_RING_BYPASS_DET 0x01 + +#define SSUSB_B2_ROSC_1_REG 0x10a44 +#define SSUSB_RING_OSC_FRC_RECAL_S 17 +#define SSUSB_RING_OSC_FRC_RECAL_M 0x60000 +#define SSUSB_RING_OSC_FRC_SEL 0x01 + +#define SSUSB_U3PHYA_1_REG 0x10b04 +#define SSUSB_PCIE_CLKDRV_AMP_S 27 +#define SSUSB_PCIE_CLKDRV_AMP_M 0x38000000 +#define SSUSB_SYSPLL_FBSEL_S 2 +#define SSUSB_SYSPLL_FBSEL_M 0x0c +#define SSUSB_SYSPLL_PREDIV_S 0 +#define SSUSB_SYSPLL_PREDIV_M 0x03 + +#define SSUSB_U3PHYA_2_REG 0x10b08 +#define SSUSB_SYSPLL_FBDIV_S 24 +#define SSUSB_SYSPLL_FBDIV_M 0x7f000000 +#define SSUSB_SYSPLL_VCO_DIV_SEL 0x200000 +#define SSUSB_SYSPLL_FPEN 0x2000 +#define SSUSB_SYSPLL_MONCK_EN 0x1000 +#define SSUSB_SYSPLL_VOD_EN 0x200 + +#define SSUSB_U3PHYA_3_REG 0x10b10 +#define SSUSB_SYSPLL_PCW_NCPO_S 1 +#define SSUSB_SYSPLL_PCW_NCPO_M 0xfffffffe + +#define SSUSB_U3PHYA_9_REG 0x10b24 +#define SSUSB_PLL_SSC_PRD_S 0 +#define SSUSB_PLL_SSC_PRD_M 0xffff + +#define SSUSB_U3PHYA_11_REG 0x10b2c +#define SSUSB_EQ_CURSEL 0x1000000 +#define SSUSB_RX_DAC_MUX_S 19 +#define SSUSB_RX_DAC_MUX_M 0xf80000 +#define SSUSB_PCIE_SIGDET_VTH_S 5 +#define SSUSB_PCIE_SIGDET_VTH_M 0x60 +#define SSUSB_PCIE_SIGDET_LPF_S 3 +#define SSUSB_PCIE_SIGDET_LPF_M 0x18 + +#define DA_SSUSB_PLL_FBKDIV_REG 0x10c1c +#define SSUSB_PLL_FBKDIV_PE2H_S 24 +#define SSUSB_PLL_FBKDIV_PE2H_M 0x7f000000 +#define SSUSB_PLL_FBKDIV_PE1D_S 16 +#define SSUSB_PLL_FBKDIV_PE1D_M 0x7f0000 +#define SSUSB_PLL_FBKDIV_PE1H_S 8 +#define SSUSB_PLL_FBKDIV_PE1H_M 0x7f00 +#define SSUSB_PLL_FBKDIV_U3_S 0 +#define SSUSB_PLL_FBKDIV_U3_M 0x7f + +#define DA_SSUSB_U3PHYA_10_REG 0x10c20 +#define SSUSB_PLL_PREDIV_PE1D_S 18 +#define SSUSB_PLL_PREDIV_PE1D_M 0xc0000 +#define SSUSB_PLL_PREDIV_U3_S 8 +#define SSUSB_PLL_PREDIV_U3_M 0x300 +#define SSUSB_PLL_FBKDI_S 0 +#define SSUSB_PLL_FBKDI_M 0x07 + +#define DA_SSUSB_PLL_PCW_NCPO_REG 0x10c24 +#define SSUSB_PLL_PCW_NCPO_U3_S 0 +#define SSUSB_PLL_PCW_NCPO_U3_M 0x7fffffff + +#define DA_SSUSB_PLL_SSC_DELTA1_REG 0x10c38 +#define SSUSB_PLL_SSC_DELTA1_PE1H_S 16 +#define SSUSB_PLL_SSC_DELTA1_PE1H_M 0xffff0000 +#define SSUSB_PLL_SSC_DELTA1_U3_S 0 +#define SSUSB_PLL_SSC_DELTA1_U3_M 0xffff + +#define DA_SSUSB_U3PHYA_21_REG 0x10c40 +#define SSUSB_PLL_SSC_DELTA_U3_S 16 +#define SSUSB_PLL_SSC_DELTA_U3_M 0xffff0000 +#define SSUSB_PLL_SSC_DELTA1_PE2D_S 0 +#define SSUSB_PLL_SSC_DELTA1_PE2D_M 0xffff + +#endif /* _MT7621_H_ */ diff --git a/arch/mips/mach-mtmips/mt7621/serial.c b/arch/mips/mach-mtmips/mt7621/serial.c new file mode 100644 index 0000000000..393188abce --- /dev/null +++ b/arch/mips/mach-mtmips/mt7621/serial.c @@ -0,0 +1,23 @@ +// 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 "mt7621.h" + +void board_debug_uart_init(void) +{ + void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE); + +#if CONFIG_DEBUG_UART_BASE == 0xbe000c00 /* KSEG1ADDR(UART1_BASE) */ + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART1_MODE); +#elif CONFIG_DEBUG_UART_BASE == 0xbe000d00 /* KSEG1ADDR(UART2_BASE) */ + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART2_MODE_M); +#elif CONFIG_DEBUG_UART_BASE == 0xbe000e00 /* KSEG1ADDR(UART3_BASE) */ + clrbits_32(base + SYSCTL_GPIOMODE_REG, UART3_MODE_M); +#endif +} diff --git a/include/configs/mt7621.h b/include/configs/mt7621.h new file mode 100644 index 0000000000..74a81004d0 --- /dev/null +++ b/include/configs/mt7621.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2021 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#ifndef __CONFIG_MT7621_H +#define __CONFIG_MT7621_H + +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_MIPS_TIMER_FREQ 440000000 + +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000 + +#define CONFIG_SYS_SDRAM_BASE 0x80000000 + +#define CONFIG_VERY_BIG_RAM +#define CONFIG_MAX_MEM_MAPPED 0x1c000000 + +#define CONFIG_SYS_INIT_SP_OFFSET 0x80000 + +#define CONFIG_SYS_BOOTM_LEN 0x2000000 + +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_CBSIZE 1024 + +#define CONFIG_SYS_NONCACHED_MEMORY 0x100000 + +/* MMC */ +#define MMC_SUPPORTS_TUNING + +/* NAND */ +#define CONFIG_SYS_MAX_NAND_DEVICE 1 + +#endif /* __CONFIG_MT7621_H */

The mt7621_rfb board supports integrated giga PHYs plus one external giga PHYs. It also has up to 512MiB DDR3, 16MB SPI-NOR, 3 mini PCI-e x1 slots, SDXC and USB.
The mt7621_nand_rfb board is almost the same as mt7621_rfb board, but it uses NAND flash and SDXC is not available.
Reviewed-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: Add config file for mt7621-rfb boards --- arch/mips/dts/Makefile | 2 + arch/mips/dts/mediatek,mt7621-nand-rfb.dts | 52 +++++++++++++++ arch/mips/dts/mediatek,mt7621-rfb.dts | 68 ++++++++++++++++++++ arch/mips/mach-mtmips/mt7621/Kconfig | 20 ++++++ board/mediatek/mt7621/MAINTAINERS | 9 +++ board/mediatek/mt7621/Makefile | 3 + board/mediatek/mt7621/board.c | 6 ++ configs/mt7621_nand_rfb_ramboot_defconfig | 72 +++++++++++++++++++++ configs/mt7621_rfb_ramboot_defconfig | 75 ++++++++++++++++++++++ include/configs/mt7621-rfb.h | 18 ++++++ 10 files changed, 325 insertions(+) create mode 100644 arch/mips/dts/mediatek,mt7621-nand-rfb.dts create mode 100644 arch/mips/dts/mediatek,mt7621-rfb.dts create mode 100644 board/mediatek/mt7621/MAINTAINERS create mode 100644 board/mediatek/mt7621/Makefile create mode 100644 board/mediatek/mt7621/board.c create mode 100644 configs/mt7621_nand_rfb_ramboot_defconfig create mode 100644 configs/mt7621_rfb_ramboot_defconfig create mode 100644 include/configs/mt7621-rfb.h
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile index 95144b24dc..1b179116c9 100644 --- a/arch/mips/dts/Makefile +++ b/arch/mips/dts/Makefile @@ -16,6 +16,8 @@ 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_MT7621_RFB) += mediatek,mt7621-rfb.dtb +dtb-$(CONFIG_BOARD_MT7621_NAND_RFB) += mediatek,mt7621-nand-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,mt7621-nand-rfb.dts b/arch/mips/dts/mediatek,mt7621-nand-rfb.dts new file mode 100644 index 0000000000..80870fe3f3 --- /dev/null +++ b/arch/mips/dts/mediatek,mt7621-nand-rfb.dts @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +/dts-v1/; + +#include "mt7621.dtsi" + +/ { + compatible = "mediatek,mt7621-nand-rfb", "mediatek,mt7621-soc"; + model = "MediaTek MT7621 RFB (NAND)"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = &uart0; + }; +}; + +&pinctrl { + state_default: pin_state { + nand { + groups = "spi", "sdxc"; + function = "nand"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&gpio { + status = "okay"; +}; + +ð { + status = "okay"; +}; + +&ssusb { + status = "okay"; +}; + +&u3phy { + status = "okay"; +}; diff --git a/arch/mips/dts/mediatek,mt7621-rfb.dts b/arch/mips/dts/mediatek,mt7621-rfb.dts new file mode 100644 index 0000000000..c8561548f5 --- /dev/null +++ b/arch/mips/dts/mediatek,mt7621-rfb.dts @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +/dts-v1/; + +#include "mt7621.dtsi" + +/ { + compatible = "mediatek,mt7621-rfb", "mediatek,mt7621-soc"; + model = "MediaTek MT7621 RFB (SPI-NOR)"; + + aliases { + serial0 = &uart0; + spi0 = &spi; + }; + + chosen { + stdout-path = &uart0; + }; +}; + +&pinctrl { + state_default: pin_state { + }; +}; + +&uart0 { + status = "okay"; +}; + +&gpio { + status = "okay"; +}; + +&spi { + status = "okay"; + num-cs = <2>; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + spi-max-frequency = <25000000>; + reg = <0>; + }; +}; + +ð { + status = "okay"; +}; + +&mmc { + cap-sd-highspeed; + + status = "okay"; +}; + +&ssusb { + status = "okay"; +}; + +&u3phy { + status = "okay"; +}; diff --git a/arch/mips/mach-mtmips/mt7621/Kconfig b/arch/mips/mach-mtmips/mt7621/Kconfig index 6948bee31b..add1f4154b 100644 --- a/arch/mips/mach-mtmips/mt7621/Kconfig +++ b/arch/mips/mach-mtmips/mt7621/Kconfig @@ -7,6 +7,26 @@ config DEBUG_UART_BOARD_INIT choice prompt "Board select"
+config BOARD_MT7621_RFB + bool "MediaTek MT7621 RFB (SPI-NOR)" + help + The reference design of MT7621A (WS3010) booting from SPI-NOR flash. + The board can be configured with DDR2 (64MiB~256MiB) or DDR3 + (128MiB~512MiB). The board has 16 MiB SPI-NOR flash, built-in MT7530 + GbE switch, 1 UART, 1 USB 2.0 host, 1 USB 3.0 host, 1 SDXC, 3 PCIe + sockets, 1 RGMII to external GbE PHY, 2 audio jacks (in/out), + JTAG pins and expansion GPIO pins. + +config BOARD_MT7621_NAND_RFB + bool "MediaTek MT7621 RFB (NAND)" + help + The reference design of MT7621A (WS3010) booting from NAND flash. + The board can be configured with DDR2 (64MiB~256MiB) or DDR3 + (128MiB~512MiB). The board has 128 MiB parallel NAND flash, built-in + MT7530 GbE switch, 1 UART, 1 USB 2.0 host, 1 USB 3.0 host, 3 PCIe + sockets, 1 RGMII to external GbE PHY, 2 audio jacks (in/out), + JTAG pins and expansion GPIO pins. + endchoice
config SYS_CONFIG_NAME diff --git a/board/mediatek/mt7621/MAINTAINERS b/board/mediatek/mt7621/MAINTAINERS new file mode 100644 index 0000000000..add653b931 --- /dev/null +++ b/board/mediatek/mt7621/MAINTAINERS @@ -0,0 +1,9 @@ +MT7621_RFB BOARD +M: Weijie Gao weijie.gao@mediatek.com +S: Maintained +F: board/mediatek/mt7621 +F: configs/mt7621_rfb_ramboot_defconfig +F: configs/mt7621_nand_rfb_ramboot_defconfig +F: arch/mips/dts/mediatek,mt7621-rfb.dts +F: arch/mips/dts/mediatek,mt7621-nand-rfb.dts +F: include/configs/mt7621-rfb.h diff --git a/board/mediatek/mt7621/Makefile b/board/mediatek/mt7621/Makefile new file mode 100644 index 0000000000..db129c5aba --- /dev/null +++ b/board/mediatek/mt7621/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += board.o diff --git a/board/mediatek/mt7621/board.c b/board/mediatek/mt7621/board.c new file mode 100644 index 0000000000..119b8fc9e5 --- /dev/null +++ b/board/mediatek/mt7621/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/mt7621_nand_rfb_ramboot_defconfig b/configs/mt7621_nand_rfb_ramboot_defconfig new file mode 100644 index 0000000000..f5088ca629 --- /dev/null +++ b/configs/mt7621_nand_rfb_ramboot_defconfig @@ -0,0 +1,72 @@ +CONFIG_MIPS=y +CONFIG_SYS_CONFIG_NAME="mt7621-rfb" +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x1000 +CONFIG_SYS_MALLOC_LEN=0x100000 +CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7621-nand-rfb" +CONFIG_DEBUG_UART_BASE=0xbe000c00 +CONFIG_DEBUG_UART_CLOCK=50000000 +CONFIG_ARCH_MTMIPS=y +CONFIG_SOC_MT7621=y +CONFIG_BOARD_MT7621_NAND_RFB=y +# CONFIG_MIPS_CACHE_SETUP is not set +# CONFIG_MIPS_CACHE_DISABLE is not set +CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y +CONFIG_SPL_INIT_STACK_WITHOUT_MALLOC_F=y +CONFIG_MIPS_BOOT_FDT=y +CONFIG_DEBUG_UART=y +CONFIG_SYS_LOAD_ADDR=0x83000000 +CONFIG_FIT=y +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# 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_FLASH is not set +CONFIG_CMD_GPIO=y +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_PART=y +# CONFIG_CMD_PINMUX is not set +CONFIG_CMD_USB=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +# CONFIG_I2C is not set +# CONFIG_INPUT is not set +CONFIG_MMC=y +# CONFIG_MMC_QUIRKS is not set +# CONFIG_MMC_HW_PARTITIONING is not set +CONFIG_MMC_MTK=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_RAW_NAND=y +CONFIG_NAND_MT7621=y +CONFIG_SYS_NAND_ONFI_DETECTION=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PHY=y +CONFIG_PHY_MTK_TPHY=y +CONFIG_SPECIFY_CONSOLE_INDEX=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYSRESET=y +CONFIG_SYSRESET_RESETCTL=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_STORAGE=y +CONFIG_WDT=y +CONFIG_WDT_MT7621=y +CONFIG_FAT_WRITE=y +CONFIG_LZMA=y +CONFIG_SPL_LZMA=y diff --git a/configs/mt7621_rfb_ramboot_defconfig b/configs/mt7621_rfb_ramboot_defconfig new file mode 100644 index 0000000000..6f6bb52c9e --- /dev/null +++ b/configs/mt7621_rfb_ramboot_defconfig @@ -0,0 +1,75 @@ +CONFIG_MIPS=y +CONFIG_SYS_CONFIG_NAME="mt7621-rfb" +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x1000 +CONFIG_SYS_MALLOC_LEN=0x100000 +CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7621-rfb" +CONFIG_DEBUG_UART_BASE=0xbe000c00 +CONFIG_DEBUG_UART_CLOCK=50000000 +CONFIG_ARCH_MTMIPS=y +CONFIG_SOC_MT7621=y +# CONFIG_MIPS_CACHE_SETUP is not set +# CONFIG_MIPS_CACHE_DISABLE is not set +CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y +CONFIG_SPL_INIT_STACK_WITHOUT_MALLOC_F=y +CONFIG_MIPS_BOOT_FDT=y +CONFIG_DEBUG_UART=y +CONFIG_SYS_LOAD_ADDR=0x83000000 +CONFIG_FIT=y +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# 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_PART=y +# CONFIG_CMD_PINMUX is not set +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +# CONFIG_I2C is not set +# CONFIG_INPUT is not set +CONFIG_MMC=y +# CONFIG_MMC_QUIRKS is not set +# CONFIG_MMC_HW_PARTITIONING is not set +CONFIG_MMC_MTK=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_MEDIATEK_ETH=y +CONFIG_PHY=y +CONFIG_PHY_MTK_TPHY=y +CONFIG_SPECIFY_CONSOLE_INDEX=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SPI=y +CONFIG_MT7621_SPI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_RESETCTL=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_STORAGE=y +CONFIG_WDT=y +CONFIG_WDT_MT7621=y +CONFIG_FAT_WRITE=y +CONFIG_LZMA=y +CONFIG_SPL_LZMA=y diff --git a/include/configs/mt7621-rfb.h b/include/configs/mt7621-rfb.h new file mode 100644 index 0000000000..2287cb1103 --- /dev/null +++ b/include/configs/mt7621-rfb.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2021 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#ifndef __CONFIG_MT7621_RFB_H +#define __CONFIG_MT7621_RFB_H + +#include "mt7621.h" + +/* Network */ +#define CONFIG_IPADDR 192.168.1.1 +#define CONFIG_SERVERIP 192.168.1.2 +#define CONFIG_NETMASK 255.255.255.0 + +#endif /* __CONFIG_MT7621_RFB_H */

On 4/28/22 12:37, Weijie Gao wrote:
The mt7621_rfb board supports integrated giga PHYs plus one external giga PHYs. It also has up to 512MiB DDR3, 16MB SPI-NOR, 3 mini PCI-e x1 slots, SDXC and USB.
The mt7621_nand_rfb board is almost the same as mt7621_rfb board, but it uses NAND flash and SDXC is not available.
Reviewed-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com Signed-off-by: Weijie Gao weijie.gao@mediatek.com
v3 changes: none v2 changes: Add config file for mt7621-rfb boards
arch/mips/dts/Makefile | 2 + arch/mips/dts/mediatek,mt7621-nand-rfb.dts | 52 +++++++++++++++ arch/mips/dts/mediatek,mt7621-rfb.dts | 68 ++++++++++++++++++++ arch/mips/mach-mtmips/mt7621/Kconfig | 20 ++++++ board/mediatek/mt7621/MAINTAINERS | 9 +++ board/mediatek/mt7621/Makefile | 3 + board/mediatek/mt7621/board.c | 6 ++ configs/mt7621_nand_rfb_ramboot_defconfig | 72 +++++++++++++++++++++ configs/mt7621_rfb_ramboot_defconfig | 75 ++++++++++++++++++++++ include/configs/mt7621-rfb.h | 18 ++++++ 10 files changed, 325 insertions(+) create mode 100644 arch/mips/dts/mediatek,mt7621-nand-rfb.dts create mode 100644 arch/mips/dts/mediatek,mt7621-rfb.dts create mode 100644 board/mediatek/mt7621/MAINTAINERS create mode 100644 board/mediatek/mt7621/Makefile create mode 100644 board/mediatek/mt7621/board.c create mode 100644 configs/mt7621_nand_rfb_ramboot_defconfig create mode 100644 configs/mt7621_rfb_ramboot_defconfig create mode 100644 include/configs/mt7621-rfb.h
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile index 95144b24dc..1b179116c9 100644 --- a/arch/mips/dts/Makefile +++ b/arch/mips/dts/Makefile @@ -16,6 +16,8 @@ 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_MT7621_RFB) += mediatek,mt7621-rfb.dtb +dtb-$(CONFIG_BOARD_MT7621_NAND_RFB) += mediatek,mt7621-nand-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,mt7621-nand-rfb.dts b/arch/mips/dts/mediatek,mt7621-nand-rfb.dts new file mode 100644 index 0000000000..80870fe3f3 --- /dev/null +++ b/arch/mips/dts/mediatek,mt7621-nand-rfb.dts @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (C) 2021 MediaTek Inc. All rights reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+/dts-v1/;
+#include "mt7621.dtsi"
+/ {
- compatible = "mediatek,mt7621-nand-rfb", "mediatek,mt7621-soc";
- model = "MediaTek MT7621 RFB (NAND)";
- aliases {
serial0 = &uart0;
- };
- chosen {
stdout-path = &uart0;
- };
+};
+&pinctrl {
- state_default: pin_state {
nand {
groups = "spi", "sdxc";
function = "nand";
};
- };
+};
+&uart0 {
- status = "okay";
+};
+&gpio {
- status = "okay";
+};
+ð {
- status = "okay";
+};
+&ssusb {
- status = "okay";
+};
+&u3phy {
- status = "okay";
+}; diff --git a/arch/mips/dts/mediatek,mt7621-rfb.dts b/arch/mips/dts/mediatek,mt7621-rfb.dts new file mode 100644 index 0000000000..c8561548f5 --- /dev/null +++ b/arch/mips/dts/mediatek,mt7621-rfb.dts @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (C) 2021 MediaTek Inc. All rights reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+/dts-v1/;
+#include "mt7621.dtsi"
+/ {
- compatible = "mediatek,mt7621-rfb", "mediatek,mt7621-soc";
- model = "MediaTek MT7621 RFB (SPI-NOR)";
- aliases {
serial0 = &uart0;
spi0 = &spi;
- };
- chosen {
stdout-path = &uart0;
- };
+};
+&pinctrl {
- state_default: pin_state {
- };
+};
+&uart0 {
- status = "okay";
+};
+&gpio {
- status = "okay";
+};
+&spi {
- status = "okay";
- num-cs = <2>;
- spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
spi-max-frequency = <25000000>;
reg = <0>;
- };
+};
+ð {
- status = "okay";
+};
+&mmc {
- cap-sd-highspeed;
- status = "okay";
+};
+&ssusb {
- status = "okay";
+};
+&u3phy {
- status = "okay";
+}; diff --git a/arch/mips/mach-mtmips/mt7621/Kconfig b/arch/mips/mach-mtmips/mt7621/Kconfig index 6948bee31b..add1f4154b 100644 --- a/arch/mips/mach-mtmips/mt7621/Kconfig +++ b/arch/mips/mach-mtmips/mt7621/Kconfig @@ -7,6 +7,26 @@ config DEBUG_UART_BOARD_INIT choice prompt "Board select"
+config BOARD_MT7621_RFB
- bool "MediaTek MT7621 RFB (SPI-NOR)"
- help
The reference design of MT7621A (WS3010) booting from SPI-NOR flash.
The board can be configured with DDR2 (64MiB~256MiB) or DDR3
(128MiB~512MiB). The board has 16 MiB SPI-NOR flash, built-in MT7530
GbE switch, 1 UART, 1 USB 2.0 host, 1 USB 3.0 host, 1 SDXC, 3 PCIe
sockets, 1 RGMII to external GbE PHY, 2 audio jacks (in/out),
JTAG pins and expansion GPIO pins.
+config BOARD_MT7621_NAND_RFB
bool "MediaTek MT7621 RFB (NAND)"
help
The reference design of MT7621A (WS3010) booting from NAND flash.
The board can be configured with DDR2 (64MiB~256MiB) or DDR3
(128MiB~512MiB). The board has 128 MiB parallel NAND flash, built-in
MT7530 GbE switch, 1 UART, 1 USB 2.0 host, 1 USB 3.0 host, 3 PCIe
sockets, 1 RGMII to external GbE PHY, 2 audio jacks (in/out),
JTAG pins and expansion GPIO pins.
endchoice
config SYS_CONFIG_NAME
diff --git a/board/mediatek/mt7621/MAINTAINERS b/board/mediatek/mt7621/MAINTAINERS new file mode 100644 index 0000000000..add653b931 --- /dev/null +++ b/board/mediatek/mt7621/MAINTAINERS @@ -0,0 +1,9 @@ +MT7621_RFB BOARD +M: Weijie Gao weijie.gao@mediatek.com +S: Maintained +F: board/mediatek/mt7621 +F: configs/mt7621_rfb_ramboot_defconfig +F: configs/mt7621_nand_rfb_ramboot_defconfig +F: arch/mips/dts/mediatek,mt7621-rfb.dts +F: arch/mips/dts/mediatek,mt7621-nand-rfb.dts +F: include/configs/mt7621-rfb.h diff --git a/board/mediatek/mt7621/Makefile b/board/mediatek/mt7621/Makefile new file mode 100644 index 0000000000..db129c5aba --- /dev/null +++ b/board/mediatek/mt7621/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0
+obj-y += board.o diff --git a/board/mediatek/mt7621/board.c b/board/mediatek/mt7621/board.c new file mode 100644 index 0000000000..119b8fc9e5 --- /dev/null +++ b/board/mediatek/mt7621/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/mt7621_nand_rfb_ramboot_defconfig b/configs/mt7621_nand_rfb_ramboot_defconfig new file mode 100644 index 0000000000..f5088ca629 --- /dev/null +++ b/configs/mt7621_nand_rfb_ramboot_defconfig @@ -0,0 +1,72 @@ +CONFIG_MIPS=y +CONFIG_SYS_CONFIG_NAME="mt7621-rfb" +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x1000 +CONFIG_SYS_MALLOC_LEN=0x100000 +CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7621-nand-rfb" +CONFIG_DEBUG_UART_BASE=0xbe000c00 +CONFIG_DEBUG_UART_CLOCK=50000000 +CONFIG_ARCH_MTMIPS=y +CONFIG_SOC_MT7621=y +CONFIG_BOARD_MT7621_NAND_RFB=y +# CONFIG_MIPS_CACHE_SETUP is not set +# CONFIG_MIPS_CACHE_DISABLE is not set +CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y +CONFIG_SPL_INIT_STACK_WITHOUT_MALLOC_F=y +CONFIG_MIPS_BOOT_FDT=y +CONFIG_DEBUG_UART=y +CONFIG_SYS_LOAD_ADDR=0x83000000 +CONFIG_FIT=y +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# 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_FLASH is not set +CONFIG_CMD_GPIO=y +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_PART=y +# CONFIG_CMD_PINMUX is not set +CONFIG_CMD_USB=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +# CONFIG_I2C is not set +# CONFIG_INPUT is not set +CONFIG_MMC=y +# CONFIG_MMC_QUIRKS is not set +# CONFIG_MMC_HW_PARTITIONING is not set +CONFIG_MMC_MTK=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_RAW_NAND=y +CONFIG_NAND_MT7621=y +CONFIG_SYS_NAND_ONFI_DETECTION=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PHY=y +CONFIG_PHY_MTK_TPHY=y +CONFIG_SPECIFY_CONSOLE_INDEX=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYSRESET=y +CONFIG_SYSRESET_RESETCTL=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_STORAGE=y +CONFIG_WDT=y +CONFIG_WDT_MT7621=y +CONFIG_FAT_WRITE=y +CONFIG_LZMA=y +CONFIG_SPL_LZMA=y diff --git a/configs/mt7621_rfb_ramboot_defconfig b/configs/mt7621_rfb_ramboot_defconfig new file mode 100644 index 0000000000..6f6bb52c9e --- /dev/null +++ b/configs/mt7621_rfb_ramboot_defconfig @@ -0,0 +1,75 @@ +CONFIG_MIPS=y +CONFIG_SYS_CONFIG_NAME="mt7621-rfb" +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x1000 +CONFIG_SYS_MALLOC_LEN=0x100000 +CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7621-rfb" +CONFIG_DEBUG_UART_BASE=0xbe000c00 +CONFIG_DEBUG_UART_CLOCK=50000000 +CONFIG_ARCH_MTMIPS=y +CONFIG_SOC_MT7621=y +# CONFIG_MIPS_CACHE_SETUP is not set +# CONFIG_MIPS_CACHE_DISABLE is not set +CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y +CONFIG_SPL_INIT_STACK_WITHOUT_MALLOC_F=y +CONFIG_MIPS_BOOT_FDT=y +CONFIG_DEBUG_UART=y +CONFIG_SYS_LOAD_ADDR=0x83000000 +CONFIG_FIT=y +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# 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_PART=y +# CONFIG_CMD_PINMUX is not set +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +# CONFIG_I2C is not set +# CONFIG_INPUT is not set +CONFIG_MMC=y +# CONFIG_MMC_QUIRKS is not set +# CONFIG_MMC_HW_PARTITIONING is not set +CONFIG_MMC_MTK=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_MEDIATEK_ETH=y +CONFIG_PHY=y +CONFIG_PHY_MTK_TPHY=y +CONFIG_SPECIFY_CONSOLE_INDEX=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SPI=y +CONFIG_MT7621_SPI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_RESETCTL=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_STORAGE=y +CONFIG_WDT=y +CONFIG_WDT_MT7621=y +CONFIG_FAT_WRITE=y +CONFIG_LZMA=y +CONFIG_SPL_LZMA=y diff --git a/include/configs/mt7621-rfb.h b/include/configs/mt7621-rfb.h new file mode 100644 index 0000000000..2287cb1103 --- /dev/null +++ b/include/configs/mt7621-rfb.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/*
- Copyright (C) 2021 MediaTek Inc. All Rights Reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+#ifndef __CONFIG_MT7621_RFB_H +#define __CONFIG_MT7621_RFB_H
+#include "mt7621.h"
+/* Network */ +#define CONFIG_IPADDR 192.168.1.1 +#define CONFIG_SERVERIP 192.168.1.2 +#define CONFIG_NETMASK 255.255.255.0
Do you really need this? It's in general not recommended to add some hardcoded values here (anymore).
BTW: You might also want to update the copyright line to 2022.
Other than this:
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan

On Fri, 2022-04-29 at 08:20 +0200, Stefan Roese wrote:
On 4/28/22 12:37, Weijie Gao wrote:
The mt7621_rfb board supports integrated giga PHYs plus one external giga PHYs. It also has up to 512MiB DDR3, 16MB SPI-NOR, 3 mini PCI- e x1 slots, SDXC and USB.
The mt7621_nand_rfb board is almost the same as mt7621_rfb board, but it uses NAND flash and SDXC is not available.
Reviewed-by: Daniel Schwierzeck daniel.schwierzeck@gmail.com Signed-off-by: Weijie Gao weijie.gao@mediatek.com
v3 changes: none v2 changes: Add config file for mt7621-rfb boards
arch/mips/dts/Makefile | 2 + arch/mips/dts/mediatek,mt7621-nand-rfb.dts | 52 +++++++++++++++ arch/mips/dts/mediatek,mt7621-rfb.dts | 68 ++++++++++++++++++++ arch/mips/mach-mtmips/mt7621/Kconfig | 20 ++++++ board/mediatek/mt7621/MAINTAINERS | 9 +++ board/mediatek/mt7621/Makefile | 3 + board/mediatek/mt7621/board.c | 6 ++ configs/mt7621_nand_rfb_ramboot_defconfig | 72 +++++++++++++++++++++ configs/mt7621_rfb_ramboot_defconfig | 75 ++++++++++++++++++++++ include/configs/mt7621-rfb.h | 18 ++++++ 10 files changed, 325 insertions(+) create mode 100644 arch/mips/dts/mediatek,mt7621-nand-rfb.dts create mode 100644 arch/mips/dts/mediatek,mt7621-rfb.dts create mode 100644 board/mediatek/mt7621/MAINTAINERS create mode 100644 board/mediatek/mt7621/Makefile create mode 100644 board/mediatek/mt7621/board.c create mode 100644 configs/mt7621_nand_rfb_ramboot_defconfig create mode 100644 configs/mt7621_rfb_ramboot_defconfig create mode 100644 include/configs/mt7621-rfb.h
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile index 95144b24dc..1b179116c9 100644 --- a/arch/mips/dts/Makefile +++ b/arch/mips/dts/Makefile @@ -16,6 +16,8 @@ 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_MT7621_RFB) += mediatek,mt7621-rfb.dtb +dtb-$(CONFIG_BOARD_MT7621_NAND_RFB) += mediatek,mt7621-nand- 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,mt7621-nand-rfb.dts b/arch/mips/dts/mediatek,mt7621-nand-rfb.dts new file mode 100644 index 0000000000..80870fe3f3 --- /dev/null +++ b/arch/mips/dts/mediatek,mt7621-nand-rfb.dts @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (C) 2021 MediaTek Inc. All rights reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+/dts-v1/;
+#include "mt7621.dtsi"
+/ {
- compatible = "mediatek,mt7621-nand-rfb", "mediatek,mt7621-
soc";
- model = "MediaTek MT7621 RFB (NAND)";
- aliases {
serial0 = &uart0;
- };
- chosen {
stdout-path = &uart0;
- };
+};
+&pinctrl {
- state_default: pin_state {
nand {
groups = "spi", "sdxc";
function = "nand";
};
- };
+};
+&uart0 {
- status = "okay";
+};
+&gpio {
- status = "okay";
+};
+ð {
- status = "okay";
+};
+&ssusb {
- status = "okay";
+};
+&u3phy {
- status = "okay";
+}; diff --git a/arch/mips/dts/mediatek,mt7621-rfb.dts b/arch/mips/dts/mediatek,mt7621-rfb.dts new file mode 100644 index 0000000000..c8561548f5 --- /dev/null +++ b/arch/mips/dts/mediatek,mt7621-rfb.dts @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (C) 2021 MediaTek Inc. All rights reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+/dts-v1/;
+#include "mt7621.dtsi"
+/ {
- compatible = "mediatek,mt7621-rfb", "mediatek,mt7621-soc";
- model = "MediaTek MT7621 RFB (SPI-NOR)";
- aliases {
serial0 = &uart0;
spi0 = &spi;
- };
- chosen {
stdout-path = &uart0;
- };
+};
+&pinctrl {
- state_default: pin_state {
- };
+};
+&uart0 {
- status = "okay";
+};
+&gpio {
- status = "okay";
+};
+&spi {
- status = "okay";
- num-cs = <2>;
- spi-flash@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
spi-max-frequency = <25000000>;
reg = <0>;
- };
+};
+ð {
- status = "okay";
+};
+&mmc {
- cap-sd-highspeed;
- status = "okay";
+};
+&ssusb {
- status = "okay";
+};
+&u3phy {
- status = "okay";
+}; diff --git a/arch/mips/mach-mtmips/mt7621/Kconfig b/arch/mips/mach- mtmips/mt7621/Kconfig index 6948bee31b..add1f4154b 100644 --- a/arch/mips/mach-mtmips/mt7621/Kconfig +++ b/arch/mips/mach-mtmips/mt7621/Kconfig @@ -7,6 +7,26 @@ config DEBUG_UART_BOARD_INIT choice prompt "Board select"
+config BOARD_MT7621_RFB
- bool "MediaTek MT7621 RFB (SPI-NOR)"
- help
The reference design of MT7621A (WS3010) booting from
SPI-NOR flash.
The board can be configured with DDR2 (64MiB~256MiB) or
DDR3
(128MiB~512MiB). The board has 16 MiB SPI-NOR flash,
built-in MT7530
GbE switch, 1 UART, 1 USB 2.0 host, 1 USB 3.0 host, 1
SDXC, 3 PCIe
sockets, 1 RGMII to external GbE PHY, 2 audio jacks
(in/out),
JTAG pins and expansion GPIO pins.
+config BOARD_MT7621_NAND_RFB
- bool "MediaTek MT7621 RFB (NAND)"
- help
The reference design of MT7621A (WS3010) booting from
NAND flash.
The board can be configured with DDR2 (64MiB~256MiB) or
DDR3
(128MiB~512MiB). The board has 128 MiB parallel NAND
flash, built-in
MT7530 GbE switch, 1 UART, 1 USB 2.0 host, 1 USB 3.0
host, 3 PCIe
sockets, 1 RGMII to external GbE PHY, 2 audio jacks
(in/out),
JTAG pins and expansion GPIO pins.
endchoice
config SYS_CONFIG_NAME
diff --git a/board/mediatek/mt7621/MAINTAINERS b/board/mediatek/mt7621/MAINTAINERS new file mode 100644 index 0000000000..add653b931 --- /dev/null +++ b/board/mediatek/mt7621/MAINTAINERS @@ -0,0 +1,9 @@ +MT7621_RFB BOARD +M: Weijie Gao weijie.gao@mediatek.com +S: Maintained +F: board/mediatek/mt7621 +F: configs/mt7621_rfb_ramboot_defconfig +F: configs/mt7621_nand_rfb_ramboot_defconfig +F: arch/mips/dts/mediatek,mt7621-rfb.dts +F: arch/mips/dts/mediatek,mt7621-nand-rfb.dts +F: include/configs/mt7621-rfb.h diff --git a/board/mediatek/mt7621/Makefile b/board/mediatek/mt7621/Makefile new file mode 100644 index 0000000000..db129c5aba --- /dev/null +++ b/board/mediatek/mt7621/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0
+obj-y += board.o diff --git a/board/mediatek/mt7621/board.c b/board/mediatek/mt7621/board.c new file mode 100644 index 0000000000..119b8fc9e5 --- /dev/null +++ b/board/mediatek/mt7621/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/mt7621_nand_rfb_ramboot_defconfig b/configs/mt7621_nand_rfb_ramboot_defconfig new file mode 100644 index 0000000000..f5088ca629 --- /dev/null +++ b/configs/mt7621_nand_rfb_ramboot_defconfig @@ -0,0 +1,72 @@ +CONFIG_MIPS=y +CONFIG_SYS_CONFIG_NAME="mt7621-rfb" +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x1000 +CONFIG_SYS_MALLOC_LEN=0x100000 +CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7621-nand-rfb" +CONFIG_DEBUG_UART_BASE=0xbe000c00 +CONFIG_DEBUG_UART_CLOCK=50000000 +CONFIG_ARCH_MTMIPS=y +CONFIG_SOC_MT7621=y +CONFIG_BOARD_MT7621_NAND_RFB=y +# CONFIG_MIPS_CACHE_SETUP is not set +# CONFIG_MIPS_CACHE_DISABLE is not set +CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y +CONFIG_SPL_INIT_STACK_WITHOUT_MALLOC_F=y +CONFIG_MIPS_BOOT_FDT=y +CONFIG_DEBUG_UART=y +CONFIG_SYS_LOAD_ADDR=0x83000000 +CONFIG_FIT=y +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# 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_FLASH is not set +CONFIG_CMD_GPIO=y +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_PART=y +# CONFIG_CMD_PINMUX is not set +CONFIG_CMD_USB=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +# CONFIG_I2C is not set +# CONFIG_INPUT is not set +CONFIG_MMC=y +# CONFIG_MMC_QUIRKS is not set +# CONFIG_MMC_HW_PARTITIONING is not set +CONFIG_MMC_MTK=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_RAW_NAND=y +CONFIG_NAND_MT7621=y +CONFIG_SYS_NAND_ONFI_DETECTION=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PHY=y +CONFIG_PHY_MTK_TPHY=y +CONFIG_SPECIFY_CONSOLE_INDEX=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYSRESET=y +CONFIG_SYSRESET_RESETCTL=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_STORAGE=y +CONFIG_WDT=y +CONFIG_WDT_MT7621=y +CONFIG_FAT_WRITE=y +CONFIG_LZMA=y +CONFIG_SPL_LZMA=y diff --git a/configs/mt7621_rfb_ramboot_defconfig b/configs/mt7621_rfb_ramboot_defconfig new file mode 100644 index 0000000000..6f6bb52c9e --- /dev/null +++ b/configs/mt7621_rfb_ramboot_defconfig @@ -0,0 +1,75 @@ +CONFIG_MIPS=y +CONFIG_SYS_CONFIG_NAME="mt7621-rfb" +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x1000 +CONFIG_SYS_MALLOC_LEN=0x100000 +CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7621-rfb" +CONFIG_DEBUG_UART_BASE=0xbe000c00 +CONFIG_DEBUG_UART_CLOCK=50000000 +CONFIG_ARCH_MTMIPS=y +CONFIG_SOC_MT7621=y +# CONFIG_MIPS_CACHE_SETUP is not set +# CONFIG_MIPS_CACHE_DISABLE is not set +CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y +CONFIG_SPL_INIT_STACK_WITHOUT_MALLOC_F=y +CONFIG_MIPS_BOOT_FDT=y +CONFIG_DEBUG_UART=y +CONFIG_SYS_LOAD_ADDR=0x83000000 +CONFIG_FIT=y +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# 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_PART=y +# CONFIG_CMD_PINMUX is not set +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +# CONFIG_ISO_PARTITION is not set +CONFIG_EFI_PARTITION=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +# CONFIG_I2C is not set +# CONFIG_INPUT is not set +CONFIG_MMC=y +# CONFIG_MMC_QUIRKS is not set +# CONFIG_MMC_HW_PARTITIONING is not set +CONFIG_MMC_MTK=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_MEDIATEK_ETH=y +CONFIG_PHY=y +CONFIG_PHY_MTK_TPHY=y +CONFIG_SPECIFY_CONSOLE_INDEX=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SPI=y +CONFIG_MT7621_SPI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_RESETCTL=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_MTK=y +CONFIG_USB_STORAGE=y +CONFIG_WDT=y +CONFIG_WDT_MT7621=y +CONFIG_FAT_WRITE=y +CONFIG_LZMA=y +CONFIG_SPL_LZMA=y diff --git a/include/configs/mt7621-rfb.h b/include/configs/mt7621- rfb.h new file mode 100644 index 0000000000..2287cb1103 --- /dev/null +++ b/include/configs/mt7621-rfb.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/*
- Copyright (C) 2021 MediaTek Inc. All Rights Reserved.
- Author: Weijie Gao weijie.gao@mediatek.com
- */
+#ifndef __CONFIG_MT7621_RFB_H +#define __CONFIG_MT7621_RFB_H
+#include "mt7621.h"
+/* Network */ +#define CONFIG_IPADDR 192.168.1.1 +#define CONFIG_SERVERIP 192.168.1.2 +#define CONFIG_NETMASK 255.255.255.0
Do you really need this? It's in general not recommended to add some hardcoded values here (anymore).
OK. I'll remove this file and use mt7621.h instead.
BTW: You might also want to update the copyright line to 2022.
I'll update it for all new files.
Other than this:
Reviewed-by: Stefan Roese sr@denx.de
Thanks, Stefan

This patch adds support for noncached_alloc() which was only supported by ARM platform.
Unlike the ARM platform, MMU is not used in u-boot for MIPS. Instead, KSEG is provided to access uncached memory. So most code of this patch is copied from cache.c of ARM platform, with only two differences: 1. MMU is untouched in noncached_set_region() 2. Address returned by noncached_alloc() is converted using KSEG1ADDR()
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: new --- arch/mips/include/asm/system.h | 20 ++++++++++++++++ arch/mips/lib/cache.c | 43 ++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+)
diff --git a/arch/mips/include/asm/system.h b/arch/mips/include/asm/system.h index 79e638844b..89a2ac209f 100644 --- a/arch/mips/include/asm/system.h +++ b/arch/mips/include/asm/system.h @@ -282,4 +282,24 @@ static inline void instruction_hazard_barrier(void) : "=&r"(tmp)); }
+#ifdef CONFIG_SYS_NONCACHED_MEMORY +/* 1MB granularity */ +#define MMU_SECTION_SHIFT 20 +#define MMU_SECTION_SIZE (1 << MMU_SECTION_SHIFT) + +/** + * noncached_init() - Initialize non-cached memory region + * + * Initialize non-cached memory area. This memory region will be typically + * located right below the malloc() area and be accessed from KSEG1. + * + * It is called during the generic post-relocation init sequence. + * + * Return: 0 if OK + */ +int noncached_init(void); + +phys_addr_t noncached_alloc(size_t size, size_t align); +#endif /* CONFIG_SYS_NONCACHED_MEMORY */ + #endif /* _ASM_SYSTEM_H */ diff --git a/arch/mips/lib/cache.c b/arch/mips/lib/cache.c index ec652f0fba..40ee2de935 100644 --- a/arch/mips/lib/cache.c +++ b/arch/mips/lib/cache.c @@ -6,6 +6,7 @@
#include <common.h> #include <cpu_func.h> +#include <malloc.h> #include <asm/cache.h> #include <asm/cacheops.h> #include <asm/cm.h> @@ -197,3 +198,45 @@ void dcache_disable(void) /* ensure the pipeline doesn't contain now-invalid instructions */ instruction_hazard_barrier(); } + +#ifdef CONFIG_SYS_NONCACHED_MEMORY +static unsigned long noncached_start; +static unsigned long noncached_end; +static unsigned long noncached_next; + +void noncached_set_region(void) +{ +} + +int noncached_init(void) +{ + phys_addr_t start, end; + size_t size; + + /* If this calculation changes, update board_f.c:reserve_noncached() */ + end = ALIGN(mem_malloc_start, MMU_SECTION_SIZE) - MMU_SECTION_SIZE; + size = ALIGN(CONFIG_SYS_NONCACHED_MEMORY, MMU_SECTION_SIZE); + start = end - size; + + debug("mapping memory %pa-%pa non-cached\n", &start, &end); + + noncached_start = start; + noncached_end = end; + noncached_next = start; + + return 0; +} + +phys_addr_t noncached_alloc(size_t size, size_t align) +{ + phys_addr_t next = ALIGN(noncached_next, align); + + if (next >= noncached_end || (noncached_end - next) < size) + return 0; + + debug("allocated %zu bytes of uncached memory @%pa\n", size, &next); + noncached_next = next + size; + + return KSEG1ADDR(next); +} +#endif /* CONFIG_SYS_NONCACHED_MEMORY */

This patch adds a clock driver for MediaTek MT7621 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 --- v3 changes: update clock definitions to match upstream kernel v2 changes: none --- drivers/clk/mtmips/Makefile | 1 + drivers/clk/mtmips/clk-mt7621.c | 313 +++++++++++++++++++++++++ include/dt-bindings/clock/mt7621-clk.h | 46 ++++ 3 files changed, 360 insertions(+) create mode 100644 drivers/clk/mtmips/clk-mt7621.c create mode 100644 include/dt-bindings/clock/mt7621-clk.h
diff --git a/drivers/clk/mtmips/Makefile b/drivers/clk/mtmips/Makefile index 732e7f2545..ee8b5afe87 100644 --- a/drivers/clk/mtmips/Makefile +++ b/drivers/clk/mtmips/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_SOC_MT7620) += clk-mt7620.o +obj-$(CONFIG_SOC_MT7621) += clk-mt7621.o obj-$(CONFIG_SOC_MT7628) += clk-mt7628.o diff --git a/drivers/clk/mtmips/clk-mt7621.c b/drivers/clk/mtmips/clk-mt7621.c new file mode 100644 index 0000000000..079b3c35e3 --- /dev/null +++ b/drivers/clk/mtmips/clk-mt7621.c @@ -0,0 +1,313 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <regmap.h> +#include <syscon.h> +#include <dt-bindings/clock/mt7621-clk.h> +#include <linux/bitops.h> +#include <linux/io.h> + +#define SYSC_MAP_SIZE 0x100 +#define MEMC_MAP_SIZE 0x1000 + +/* SYSC */ +#define SYSCFG0_REG 0x10 +#define XTAL_MODE_SEL_S 6 +#define XTAL_MODE_SEL_M 0x1c0 + +#define CLKCFG0_REG 0x2c +#define CPU_CLK_SEL_S 30 +#define CPU_CLK_SEL_M 0xc0000000 +#define PERI_CLK_SEL 0x10 + +#define CLKCFG1_REG 0x30 + +#define CUR_CLK_STS_REG 0x44 +#define CUR_CPU_FDIV_S 8 +#define CUR_CPU_FDIV_M 0x1f00 +#define CUR_CPU_FFRAC_S 0 +#define CUR_CPU_FFRAC_M 0x1f + +/* MEMC */ +#define MEMPLL1_REG 0x0604 +#define RG_MEPL_DIV2_SEL_S 1 +#define RG_MEPL_DIV2_SEL_M 0x06 + +#define MEMPLL6_REG 0x0618 +#define MEMPLL18_REG 0x0648 +#define RG_MEPL_PREDIV_S 12 +#define RG_MEPL_PREDIV_M 0x3000 +#define RG_MEPL_FBDIV_S 4 +#define RG_MEPL_FBDIV_M 0x7f0 + +/* EPLL clock */ +#define EPLL_CLK 50000000 + +struct mt7621_clk_priv { + void __iomem *sysc_base; + void __iomem *memc_base; + int cpu_clk; + int ddr_clk; + int sys_clk; + int xtal_clk; +}; + +enum mt7621_clk_src { + CLK_SRC_CPU, + CLK_SRC_DDR, + CLK_SRC_SYS, + CLK_SRC_XTAL, + CLK_SRC_PERI, + CLK_SRC_125M, + CLK_SRC_150M, + CLK_SRC_250M, + CLK_SRC_270M, + + __CLK_SRC_MAX +}; + +struct mt7621_clk_map { + u32 cgbit; + enum mt7621_clk_src clksrc; +}; + +#define CLK_MAP(_id, _cg, _src) \ + [_id] = { .cgbit = (_cg), .clksrc = (_src) } + +#define CLK_MAP_SRC(_id, _src) \ + [_id] = { .cgbit = UINT32_MAX, .clksrc = (_src) } + +static const struct mt7621_clk_map mt7621_clk_mappings[] = { + CLK_MAP_SRC(MT7621_CLK_XTAL, CLK_SRC_XTAL), + CLK_MAP_SRC(MT7621_CLK_CPU, CLK_SRC_CPU), + CLK_MAP_SRC(MT7621_CLK_BUS, CLK_SRC_SYS), + CLK_MAP_SRC(MT7621_CLK_50M, CLK_SRC_PERI), + CLK_MAP_SRC(MT7621_CLK_125M, CLK_SRC_125M), + CLK_MAP_SRC(MT7621_CLK_150M, CLK_SRC_150M), + CLK_MAP_SRC(MT7621_CLK_250M, CLK_SRC_250M), + CLK_MAP_SRC(MT7621_CLK_270M, CLK_SRC_270M), + + CLK_MAP(MT7621_CLK_HSDMA, 5, CLK_SRC_150M), + CLK_MAP(MT7621_CLK_FE, 6, CLK_SRC_250M), + CLK_MAP(MT7621_CLK_SP_DIVTX, 7, CLK_SRC_270M), + CLK_MAP(MT7621_CLK_TIMER, 8, CLK_SRC_PERI), + CLK_MAP(MT7621_CLK_PCM, 11, CLK_SRC_270M), + CLK_MAP(MT7621_CLK_PIO, 13, CLK_SRC_PERI), + CLK_MAP(MT7621_CLK_GDMA, 14, CLK_SRC_SYS), + CLK_MAP(MT7621_CLK_NAND, 15, CLK_SRC_125M), + CLK_MAP(MT7621_CLK_I2C, 16, CLK_SRC_PERI), + CLK_MAP(MT7621_CLK_I2S, 17, CLK_SRC_270M), + CLK_MAP(MT7621_CLK_SPI, 18, CLK_SRC_SYS), + CLK_MAP(MT7621_CLK_UART1, 19, CLK_SRC_PERI), + CLK_MAP(MT7621_CLK_UART2, 20, CLK_SRC_PERI), + CLK_MAP(MT7621_CLK_UART3, 21, CLK_SRC_PERI), + CLK_MAP(MT7621_CLK_ETH, 23, CLK_SRC_PERI), + CLK_MAP(MT7621_CLK_PCIE0, 24, CLK_SRC_125M), + CLK_MAP(MT7621_CLK_PCIE1, 25, CLK_SRC_125M), + CLK_MAP(MT7621_CLK_PCIE2, 26, CLK_SRC_125M), + CLK_MAP(MT7621_CLK_CRYPTO, 29, CLK_SRC_250M), + CLK_MAP(MT7621_CLK_SHXC, 30, CLK_SRC_PERI), + + CLK_MAP_SRC(MT7621_CLK_DDR, CLK_SRC_DDR), +}; + +static ulong mt7621_clk_get_rate(struct clk *clk) +{ + struct mt7621_clk_priv *priv = dev_get_priv(clk->dev); + u32 val; + + if (clk->id >= ARRAY_SIZE(mt7621_clk_mappings)) + return 0; + + switch (mt7621_clk_mappings[clk->id].clksrc) { + case CLK_SRC_CPU: + return priv->cpu_clk; + case CLK_SRC_DDR: + return priv->ddr_clk; + case CLK_SRC_SYS: + return priv->sys_clk; + case CLK_SRC_XTAL: + return priv->xtal_clk; + case CLK_SRC_PERI: + val = readl(priv->sysc_base + CLKCFG0_REG); + if (val & PERI_CLK_SEL) + return priv->xtal_clk; + else + return EPLL_CLK; + case CLK_SRC_125M: + return 125000000; + case CLK_SRC_150M: + return 150000000; + case CLK_SRC_250M: + return 250000000; + case CLK_SRC_270M: + return 270000000; + default: + return 0; + } +} + +static int mt7621_clk_enable(struct clk *clk) +{ + struct mt7621_clk_priv *priv = dev_get_priv(clk->dev); + u32 cgbit; + + if (clk->id >= ARRAY_SIZE(mt7621_clk_mappings)) + return -1; + + cgbit = mt7621_clk_mappings[clk->id].cgbit; + if (cgbit == UINT32_MAX) + return -1; + + setbits_32(priv->sysc_base + CLKCFG1_REG, BIT(cgbit)); + + return 0; +} + +static int mt7621_clk_disable(struct clk *clk) +{ + struct mt7621_clk_priv *priv = dev_get_priv(clk->dev); + u32 cgbit; + + if (clk->id >= ARRAY_SIZE(mt7621_clk_mappings)) + return -1; + + cgbit = mt7621_clk_mappings[clk->id].cgbit; + if (cgbit == UINT32_MAX) + return -1; + + clrbits_32(priv->sysc_base + CLKCFG1_REG, BIT(cgbit)); + + return 0; +} + +const struct clk_ops mt7621_clk_ops = { + .enable = mt7621_clk_enable, + .disable = mt7621_clk_disable, + .get_rate = mt7621_clk_get_rate, +}; + +static void mt7621_get_clocks(struct mt7621_clk_priv *priv) +{ + u32 bs, xtal_sel, clkcfg0, cur_clk, mempll, dividx, fb; + u32 xtal_clk, xtal_div, ffiv, ffrac, cpu_clk, ddr_clk; + static const u32 xtal_div_tbl[] = {0, 1, 2, 2}; + + bs = readl(priv->sysc_base + SYSCFG0_REG); + clkcfg0 = readl(priv->sysc_base + CLKCFG0_REG); + cur_clk = readl(priv->sysc_base + CUR_CLK_STS_REG); + + xtal_sel = (bs & XTAL_MODE_SEL_M) >> XTAL_MODE_SEL_S; + + if (xtal_sel <= 2) + xtal_clk = 20 * 1000 * 1000; + else if (xtal_sel <= 5) + xtal_clk = 40 * 1000 * 1000; + else + xtal_clk = 25 * 1000 * 1000; + + switch ((clkcfg0 & CPU_CLK_SEL_M) >> CPU_CLK_SEL_S) { + case 0: + cpu_clk = 500 * 1000 * 1000; + break; + case 1: + mempll = readl(priv->memc_base + MEMPLL18_REG); + dividx = (mempll & RG_MEPL_PREDIV_M) >> RG_MEPL_PREDIV_S; + fb = (mempll & RG_MEPL_FBDIV_M) >> RG_MEPL_FBDIV_S; + xtal_div = 1 << xtal_div_tbl[dividx]; + cpu_clk = (fb + 1) * xtal_clk / xtal_div; + break; + default: + cpu_clk = xtal_clk; + } + + ffiv = (cur_clk & CUR_CPU_FDIV_M) >> CUR_CPU_FDIV_S; + ffrac = (cur_clk & CUR_CPU_FFRAC_M) >> CUR_CPU_FFRAC_S; + cpu_clk = cpu_clk / ffiv * ffrac; + + mempll = readl(priv->memc_base + MEMPLL6_REG); + dividx = (mempll & RG_MEPL_PREDIV_M) >> RG_MEPL_PREDIV_S; + fb = (mempll & RG_MEPL_FBDIV_M) >> RG_MEPL_FBDIV_S; + xtal_div = 1 << xtal_div_tbl[dividx]; + ddr_clk = fb * xtal_clk / xtal_div; + + bs = readl(priv->memc_base + MEMPLL1_REG); + if (((bs & RG_MEPL_DIV2_SEL_M) >> RG_MEPL_DIV2_SEL_S) == 0) + ddr_clk *= 2; + + priv->cpu_clk = cpu_clk; + priv->sys_clk = cpu_clk / 4; + priv->ddr_clk = ddr_clk; + priv->xtal_clk = xtal_clk; +} + +static int mt7621_clk_probe(struct udevice *dev) +{ + struct mt7621_clk_priv *priv = dev_get_priv(dev); + struct ofnode_phandle_args args; + struct regmap *regmap; + void __iomem *base; + int ret; + + /* get corresponding sysc phandle */ + ret = dev_read_phandle_with_args(dev, "mediatek,sysc", NULL, 0, 0, + &args); + if (ret) + return ret; + + regmap = syscon_node_to_regmap(args.node); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + base = regmap_get_range(regmap, 0); + if (!base) { + dev_err(dev, "Unable to find sysc\n"); + return -ENODEV; + } + + priv->sysc_base = ioremap_nocache((phys_addr_t)base, SYSC_MAP_SIZE); + + /* get corresponding memc phandle */ + ret = dev_read_phandle_with_args(dev, "mediatek,memc", NULL, 0, 0, + &args); + if (ret) + return ret; + + regmap = syscon_node_to_regmap(args.node); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + base = regmap_get_range(regmap, 0); + if (!base) { + dev_err(dev, "Unable to find memc\n"); + return -ENODEV; + } + + priv->memc_base = ioremap_nocache((phys_addr_t)base, MEMC_MAP_SIZE); + + mt7621_get_clocks(priv); + + return 0; +} + +static const struct udevice_id mt7621_clk_ids[] = { + { .compatible = "mediatek,mt7621-clk" }, + { } +}; + +U_BOOT_DRIVER(mt7621_clk) = { + .name = "mt7621-clk", + .id = UCLASS_CLK, + .of_match = mt7621_clk_ids, + .probe = mt7621_clk_probe, + .priv_auto = sizeof(struct mt7621_clk_priv), + .ops = &mt7621_clk_ops, +}; diff --git a/include/dt-bindings/clock/mt7621-clk.h b/include/dt-bindings/clock/mt7621-clk.h new file mode 100644 index 0000000000..fe2487cab4 --- /dev/null +++ b/include/dt-bindings/clock/mt7621-clk.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#ifndef _DT_BINDINGS_MT7621_CLK_H_ +#define _DT_BINDINGS_MT7621_CLK_H_ + +#define MT7621_CLK_XTAL 0 +#define MT7621_CLK_CPU 1 +#define MT7621_CLK_BUS 2 +#define MT7621_CLK_50M 3 +#define MT7621_CLK_125M 4 +#define MT7621_CLK_150M 5 +#define MT7621_CLK_250M 6 +#define MT7621_CLK_270M 7 + +#define MT7621_CLK_HSDMA 8 +#define MT7621_CLK_FE 9 +#define MT7621_CLK_SP_DIVTX 10 +#define MT7621_CLK_TIMER 11 +#define MT7621_CLK_PCM 12 +#define MT7621_CLK_PIO 13 +#define MT7621_CLK_GDMA 14 +#define MT7621_CLK_NAND 15 +#define MT7621_CLK_I2C 16 +#define MT7621_CLK_I2S 17 +#define MT7621_CLK_SPI 18 +#define MT7621_CLK_UART1 19 +#define MT7621_CLK_UART2 20 +#define MT7621_CLK_UART3 21 +#define MT7621_CLK_ETH 22 +#define MT7621_CLK_PCIE0 23 +#define MT7621_CLK_PCIE1 24 +#define MT7621_CLK_PCIE2 25 +#define MT7621_CLK_CRYPTO 26 +#define MT7621_CLK_SHXC 27 + +#define MT7621_CLK_MAX 28 + +/* for u-boot only */ +#define MT7621_CLK_DDR 29 + +#endif /* _DT_BINDINGS_MT7621_CLK_H_ */

This patch adds reset controller bits definition header file for MediaTek MT7621 SoC
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: none --- include/dt-bindings/reset/mt7621-reset.h | 38 ++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 include/dt-bindings/reset/mt7621-reset.h
diff --git a/include/dt-bindings/reset/mt7621-reset.h b/include/dt-bindings/reset/mt7621-reset.h new file mode 100644 index 0000000000..e129c531fc --- /dev/null +++ b/include/dt-bindings/reset/mt7621-reset.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2021 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#ifndef _DT_BINDINGS_MT7621_RESET_H_ +#define _DT_BINDINGS_MT7621_RESET_H_ + +#define RST_PPE 31 +#define RST_SDXC 30 +#define RST_CRYPTO 29 +#define RST_AUX_STCK 28 +#define RST_PCIE2 26 +#define RST_PCIE1 25 +#define RST_PCIE0 24 +#define RST_GMAC 23 +#define RST_UART3 21 +#define RST_UART2 20 +#define RST_UART1 19 +#define RST_SPI 18 +#define RST_I2S 17 +#define RST_I2C 16 +#define RST_NFI 15 +#define RST_GDMA 14 +#define RST_PIO 13 +#define RST_PCM 11 +#define RST_MC 10 +#define RST_INTC 9 +#define RST_TIMER 8 +#define RST_SPDIFTX 7 +#define RST_FE 6 +#define RST_HSDMA 5 +#define RST_MCM 2 +#define RST_SYS 0 + +#endif /* _DT_BINDINGS_MT7621_RESET_H_ */

This patch adds pinctrl support for MediaTek MT7621 SoC. The MT7621 SoC supports pinconf, but it is not the same as mt7628.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: none --- drivers/pinctrl/mtmips/Kconfig | 9 + drivers/pinctrl/mtmips/Makefile | 1 + drivers/pinctrl/mtmips/pinctrl-mt7621.c | 307 ++++++++++++++++++ .../pinctrl/mtmips/pinctrl-mtmips-common.c | 4 +- .../pinctrl/mtmips/pinctrl-mtmips-common.h | 12 + 5 files changed, 331 insertions(+), 2 deletions(-) create mode 100644 drivers/pinctrl/mtmips/pinctrl-mt7621.c
diff --git a/drivers/pinctrl/mtmips/Kconfig b/drivers/pinctrl/mtmips/Kconfig index 844d5b743f..456f3ea25d 100644 --- a/drivers/pinctrl/mtmips/Kconfig +++ b/drivers/pinctrl/mtmips/Kconfig @@ -12,6 +12,15 @@ config PINCTRL_MT7620 The driver is controlled by a device tree node which contains the pin mux functions for each available pin groups.
+config PINCTRL_MT7621 + bool "MediaTek MT7621 pin control driver" + select PINCTRL_MTMIPS + depends on SOC_MT7621 && PINCTRL_GENERIC + help + Support pin multiplexing control on MediaTek MT7621. + 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 ba945a89a7..8fece4f5fa 100644 --- a/drivers/pinctrl/mtmips/Makefile +++ b/drivers/pinctrl/mtmips/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_PINCTRL_MTMIPS) += pinctrl-mtmips-common.o
# SoC Drivers obj-$(CONFIG_PINCTRL_MT7620) += pinctrl-mt7620.o +obj-$(CONFIG_PINCTRL_MT7621) += pinctrl-mt7621.o obj-$(CONFIG_PINCTRL_MT7628) += pinctrl-mt7628.o diff --git a/drivers/pinctrl/mtmips/pinctrl-mt7621.c b/drivers/pinctrl/mtmips/pinctrl-mt7621.c new file mode 100644 index 0000000000..c786d13d9e --- /dev/null +++ b/drivers/pinctrl/mtmips/pinctrl-mt7621.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 MediaTek Inc. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#include <common.h> +#include <dm.h> +#include <dm/pinctrl.h> +#include <dm/device_compat.h> +#include <linux/bitops.h> +#include <linux/io.h> + +#include "pinctrl-mtmips-common.h" + +#define SYSC_MAP_SIZE 0x100 + +#define PAD_UART1_GPIO0_OFS 0x00 +#define PAD_UART3_I2C_OFS 0x04 +#define PAD_UART2_JTAG_OFS 0x08 +#define PAD_PERST_WDT_OFS 0x0c +#define PAD_RGMII2_MDIO_OFS 0x10 +#define PAD_SDXC_SPI_OFS 0x14 +#define GPIOMODE_OFS 0x18 +#define PAD_BOPT_ESWINT_OFS 0x28 + +#define ESWINT_SHIFT 20 +#define SDXC_SHIFT 18 +#define SPI_SHIFT 16 +#define RGMII2_SHIFT 15 +#define RGMII1_SHIFT 14 +#define MDIO_SHIFT 12 +#define PERST_SHIFT 10 +#define WDT_SHIFT 8 +#define JTAG_SHIFT 7 +#define UART2_SHIFT 5 +#define UART3_SHIFT 3 +#define I2C_SHIFT 2 +#define UART1_SHIFT 1 +#define GPIO0_SHIFT 0 /* Dummy */ + +#define GM4_MASK 3 + +#define E4_E2_M 0x03 +#define E4_E2_S 4 +#define PULL_UP BIT(3) +#define PULL_DOWN BIT(2) +#define SMT BIT(1) +#define SR BIT(0) + +struct mt7621_pinctrl_priv { + struct mtmips_pinctrl_priv mp; +}; + +#if CONFIG_IS_ENABLED(PINMUX) +static const struct mtmips_pmx_func esw_int_grp[] = { + FUNC("gpio", 1), + FUNC("esw int", 0), +}; + +static const struct mtmips_pmx_func sdxc_grp[] = { + FUNC("nand", 2), + FUNC("gpio", 1), + FUNC("sdxc", 0), +}; + +static const struct mtmips_pmx_func spi_grp[] = { + FUNC("nand", 2), + FUNC("gpio", 1), + FUNC("spi", 0), +}; + +static const struct mtmips_pmx_func rgmii2_grp[] = { + FUNC("gpio", 1), + FUNC("rgmii", 0), +}; + +static const struct mtmips_pmx_func rgmii1_grp[] = { + FUNC("gpio", 1), + FUNC("rgmii", 0), +}; + +static const struct mtmips_pmx_func mdio_grp[] = { + FUNC("gpio", 1), + FUNC("mdio", 0), +}; + +static const struct mtmips_pmx_func perst_grp[] = { + FUNC("refclk", 2), + FUNC("gpio", 1), + FUNC("pcie reset", 0), +}; + +static const struct mtmips_pmx_func wdt_grp[] = { + FUNC("refclk", 2), + FUNC("gpio", 1), + FUNC("wdt rst", 0), +}; + +static const struct mtmips_pmx_func jtag_grp[] = { + FUNC("gpio", 1), + FUNC("jtag", 0), +}; + +static const struct mtmips_pmx_func uart2_grp[] = { + FUNC("spdif", 3), + FUNC("pcm", 2), + FUNC("gpio", 1), + FUNC("uart", 0), +}; + +static const struct mtmips_pmx_func uart3_grp[] = { + FUNC("spdif", 3), + FUNC("i2s", 2), + FUNC("gpio", 1), + FUNC("uart", 0), +}; + +static const struct mtmips_pmx_func i2c_grp[] = { + FUNC("gpio", 1), + FUNC("i2c", 0), +}; + +static const struct mtmips_pmx_func uart1_grp[] = { + FUNC("gpio", 1), + FUNC("uart", 0), +}; + +static const struct mtmips_pmx_func gpio0_grp[] = { + FUNC("gpio", 0), +}; + +static const struct mtmips_pmx_group mt7621_pmx_data[] = { + GRP_PCONF("esw int", esw_int_grp, GPIOMODE_OFS, ESWINT_SHIFT, 1, + PAD_BOPT_ESWINT_OFS, 0), + GRP_PCONF("sdxc", sdxc_grp, GPIOMODE_OFS, SDXC_SHIFT, GM4_MASK, + PAD_SDXC_SPI_OFS, 16), + GRP_PCONF("spi", spi_grp, GPIOMODE_OFS, SPI_SHIFT, GM4_MASK, + PAD_SDXC_SPI_OFS, 0), + GRP_PCONF("rgmii2", rgmii2_grp, GPIOMODE_OFS, RGMII2_SHIFT, 1, + PAD_RGMII2_MDIO_OFS, 16), + GRP("rgmii1", rgmii1_grp, GPIOMODE_OFS, RGMII1_SHIFT, 1), + GRP_PCONF("mdio", mdio_grp, GPIOMODE_OFS, MDIO_SHIFT, GM4_MASK, + PAD_RGMII2_MDIO_OFS, 0), + GRP_PCONF("pcie reset", perst_grp, GPIOMODE_OFS, PERST_SHIFT, GM4_MASK, + PAD_PERST_WDT_OFS, 16), + GRP_PCONF("wdt", wdt_grp, GPIOMODE_OFS, WDT_SHIFT, GM4_MASK, + PAD_PERST_WDT_OFS, 0), + GRP_PCONF("jtag", jtag_grp, GPIOMODE_OFS, JTAG_SHIFT, 1, + PAD_UART2_JTAG_OFS, 16), + GRP_PCONF("uart2", uart2_grp, GPIOMODE_OFS, UART2_SHIFT, GM4_MASK, + PAD_UART2_JTAG_OFS, 0), + GRP_PCONF("uart3", uart3_grp, GPIOMODE_OFS, UART3_SHIFT, GM4_MASK, + PAD_UART3_I2C_OFS, 16), + GRP_PCONF("i2c", i2c_grp, GPIOMODE_OFS, I2C_SHIFT, 1, + PAD_UART3_I2C_OFS, 0), + GRP_PCONF("uart1", uart1_grp, GPIOMODE_OFS, UART1_SHIFT, 1, + PAD_UART1_GPIO0_OFS, 16), + GRP_PCONF("gpio0", gpio0_grp, GPIOMODE_OFS, GPIO0_SHIFT, 1, + PAD_UART1_GPIO0_OFS, 0), +}; + +static int mt7621_get_groups_count(struct udevice *dev) +{ + return ARRAY_SIZE(mt7621_pmx_data); +} + +static const char *mt7621_get_group_name(struct udevice *dev, + unsigned int selector) +{ + return mt7621_pmx_data[selector].name; +} +#endif /* CONFIG_IS_ENABLED(PINMUX) */ + +#if CONFIG_IS_ENABLED(PINCONF) +static const struct pinconf_param mt7621_conf_params[] = { + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, + { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, + { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, + { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, + { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, + { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, + { "slew-rate", PIN_CONFIG_SLEW_RATE, 0 }, +}; + +static const u32 mt7621_pconf_drv_strength_tbl[] = {2, 4, 6, 8}; + +static int mt7621_pinconf_group_set(struct udevice *dev, + unsigned int group_selector, + unsigned int param, unsigned int arg) +{ + struct mt7621_pinctrl_priv *priv = dev_get_priv(dev); + const struct mtmips_pmx_group *grp = &mt7621_pmx_data[group_selector]; + u32 clr = 0, set = 0; + int i; + + if (!grp->pconf_avail) + return 0; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + clr = PULL_UP | PULL_DOWN; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + clr = PULL_DOWN; + set = PULL_UP; + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + clr = PULL_UP; + set = PULL_DOWN; + break; + + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + if (arg) + set = SMT; + else + clr = SMT; + break; + + case PIN_CONFIG_DRIVE_STRENGTH: + for (i = 0; i < ARRAY_SIZE(mt7621_pconf_drv_strength_tbl); i++) + if (mt7621_pconf_drv_strength_tbl[i] == arg) + break; + + if (i >= ARRAY_SIZE(mt7621_pconf_drv_strength_tbl)) + return -EINVAL; + + clr = E4_E2_M << E4_E2_S; + set = i << E4_E2_S; + break; + + case PIN_CONFIG_SLEW_RATE: + if (arg) + set = SR; + else + clr = SR; + break; + + default: + return -EINVAL; + } + + mtmips_pinctrl_reg_set(&priv->mp, grp->pconf_reg, grp->pconf_shift, + clr, set); + + return 0; +} +#endif + +static int mt7621_pinctrl_probe(struct udevice *dev) +{ + struct mt7621_pinctrl_priv *priv = dev_get_priv(dev); + int ret = 0; + +#if CONFIG_IS_ENABLED(PINMUX) + ret = mtmips_pinctrl_probe(&priv->mp, ARRAY_SIZE(mt7621_pmx_data), + mt7621_pmx_data); +#endif /* CONFIG_IS_ENABLED(PINMUX) */ + + return ret; +} + +static int mt7621_pinctrl_of_to_plat(struct udevice *dev) +{ + struct mt7621_pinctrl_priv *priv = dev_get_priv(dev); + + priv->mp.base = (void __iomem *)dev_remap_addr_index(dev, 0); + + if (!priv->mp.base) + return -EINVAL; + + return 0; +} + +static const struct pinctrl_ops mt7621_pinctrl_ops = { +#if CONFIG_IS_ENABLED(PINMUX) + .get_groups_count = mt7621_get_groups_count, + .get_group_name = mt7621_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) */ +#if CONFIG_IS_ENABLED(PINCONF) + .pinconf_num_params = ARRAY_SIZE(mt7621_conf_params), + .pinconf_params = mt7621_conf_params, + .pinconf_group_set = mt7621_pinconf_group_set, +#endif /* CONFIG_IS_ENABLED(PINCONF) */ + .set_state = pinctrl_generic_set_state, +}; + +static const struct udevice_id mt7621_pinctrl_ids[] = { + { .compatible = "mediatek,mt7621-pinctrl" }, + { } +}; + +U_BOOT_DRIVER(mt7621_pinctrl) = { + .name = "mt7621-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = mt7621_pinctrl_ids, + .of_to_plat = mt7621_pinctrl_of_to_plat, + .ops = &mt7621_pinctrl_ops, + .probe = mt7621_pinctrl_probe, + .priv_auto = sizeof(struct mt7621_pinctrl_priv), +}; diff --git a/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c index e361916eb2..869b781068 100644 --- a/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c +++ b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.c @@ -13,8 +13,8 @@
#include "pinctrl-mtmips-common.h"
-static void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv, - u32 reg, u32 shift, u32 mask, u32 value) +void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv, + u32 reg, u32 shift, u32 mask, u32 value) { u32 val;
diff --git a/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h index b51d8f009c..1f1023ef42 100644 --- a/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h +++ b/drivers/pinctrl/mtmips/pinctrl-mtmips-common.h @@ -22,6 +22,10 @@ struct mtmips_pmx_group { u32 shift; char mask;
+ int pconf_avail; + u32 pconf_reg; + u32 pconf_shift; + int nfuncs; const struct mtmips_pmx_func *funcs; }; @@ -42,6 +46,14 @@ struct mtmips_pinctrl_priv { { .name = (_name), .reg = (_reg), .shift = (_shift), .mask = (_mask), \ .funcs = (_funcs), .nfuncs = ARRAY_SIZE(_funcs) }
+#define GRP_PCONF(_name, _funcs, _reg, _shift, _mask, _pconf_reg, _pconf_shift) \ + { .name = (_name), .reg = (_reg), .shift = (_shift), .mask = (_mask), \ + .funcs = (_funcs), .nfuncs = ARRAY_SIZE(_funcs), .pconf_avail = 1, \ + .pconf_reg = (_pconf_reg), .pconf_shift = (_pconf_shift) } + +void mtmips_pinctrl_reg_set(struct mtmips_pinctrl_priv *priv, + u32 reg, u32 shift, u32 mask, u32 value); + int mtmips_get_functions_count(struct udevice *dev); const char *mtmips_get_function_name(struct udevice *dev, unsigned int selector);

This patch adds NAND flash controller driver for MediaTek MT7621 SoC. The NAND flash controller of MT7621 supports only SLC NAND flashes. It supports 4~12 bits correction with maximum 4KB page size.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: none --- drivers/mtd/nand/raw/Kconfig | 11 + drivers/mtd/nand/raw/Makefile | 1 + drivers/mtd/nand/raw/mt7621_nand.c | 1189 ++++++++++++++++++++++++++++ 3 files changed, 1201 insertions(+) create mode 100644 drivers/mtd/nand/raw/mt7621_nand.c
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index d75f371c95..763e16976d 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -521,6 +521,17 @@ config TEGRA_NAND help Enables support for NAND Flash chips on Tegra SoCs platforms.
+config NAND_MT7621 + bool "Support for MediaTek MT7621 NAND flash controller" + depends on SOC_MT7621 + select SYS_NAND_SELF_INIT + imply CMD_NAND + help + This enables NAND driver for the NAND flash controller on MediaTek + MT7621 platform. + The controller supports 4~12 bits correction per 512 bytes with a + maximum 4KB page size. + comment "Generic NAND options"
config SYS_NAND_BLOCK_SIZE diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 6ec3581d20..6d6721a3be 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -72,6 +72,7 @@ obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o obj-$(CONFIG_NAND_STM32_FMC2) += stm32_fmc2_nand.o obj-$(CONFIG_CORTINA_NAND) += cortina_nand.o obj-$(CONFIG_ROCKCHIP_NAND) += rockchip_nfc.o +obj-$(CONFIG_NAND_MT7621) += mt7621_nand.o
else # minimal SPL drivers
diff --git a/drivers/mtd/nand/raw/mt7621_nand.c b/drivers/mtd/nand/raw/mt7621_nand.c new file mode 100644 index 0000000000..e4fe5320f1 --- /dev/null +++ b/drivers/mtd/nand/raw/mt7621_nand.c @@ -0,0 +1,1189 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 MediaTek Incorporation. All Rights Reserved. + * + * Author: Weijie Gao weijie.gao@mediatek.com + */ + +#include <log.h> +#include <nand.h> +#include <malloc.h> +#include <asm/addrspace.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/sizes.h> +#include <linux/bitops.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/rawnand.h> + +/* NFI core registers */ +#define NFI_CNFG 0x000 +#define CNFG_OP_MODE_S 12 +#define CNFG_OP_MODE_M GENMASK(14, 12) +#define CNFG_OP_CUSTOM 6 +#define CNFG_AUTO_FMT_EN BIT(9) +#define CNFG_HW_ECC_EN BIT(8) +#define CNFG_BYTE_RW BIT(6) +#define CNFG_READ_MODE BIT(1) + +#define NFI_PAGEFMT 0x004 +#define PAGEFMT_FDM_ECC_S 12 +#define PAGEFMT_FDM_ECC_M GENMASK(15, 12) +#define PAGEFMT_FDM_S 8 +#define PAGEFMT_FDM_M GENMASK(11, 8) +#define PAGEFMT_SPARE_S 4 +#define PAGEFMT_SPARE_M GENMASK(5, 4) +#define PAGEFMT_PAGE_S 0 +#define PAGEFMT_PAGE_M GENMASK(1, 0) + +#define NFI_CON 0x008 +#define CON_NFI_SEC_S 12 +#define CON_NFI_SEC_M GENMASK(15, 12) +#define CON_NFI_BWR BIT(9) +#define CON_NFI_BRD BIT(8) +#define CON_NFI_RST BIT(1) +#define CON_FIFO_FLUSH BIT(0) + +#define NFI_ACCCON 0x00c +#define ACCCON_POECS_S 28 +#define ACCCON_POECS_MAX 0x0f +#define ACCCON_POECS_DEF 3 +#define ACCCON_PRECS_S 22 +#define ACCCON_PRECS_MAX 0x3f +#define ACCCON_PRECS_DEF 3 +#define ACCCON_C2R_S 16 +#define ACCCON_C2R_MAX 0x3f +#define ACCCON_C2R_DEF 7 +#define ACCCON_W2R_S 12 +#define ACCCON_W2R_MAX 0x0f +#define ACCCON_W2R_DEF 7 +#define ACCCON_WH_S 8 +#define ACCCON_WH_MAX 0x0f +#define ACCCON_WH_DEF 15 +#define ACCCON_WST_S 4 +#define ACCCON_WST_MAX 0x0f +#define ACCCON_WST_DEF 15 +#define ACCCON_WST_MIN 3 +#define ACCCON_RLT_S 0 +#define ACCCON_RLT_MAX 0x0f +#define ACCCON_RLT_DEF 15 +#define ACCCON_RLT_MIN 3 + +#define NFI_CMD 0x020 + +#define NFI_ADDRNOB 0x030 +#define ADDR_ROW_NOB_S 4 +#define ADDR_ROW_NOB_M GENMASK(6, 4) +#define ADDR_COL_NOB_S 0 +#define ADDR_COL_NOB_M GENMASK(2, 0) + +#define NFI_COLADDR 0x034 +#define NFI_ROWADDR 0x038 + +#define NFI_STRDATA 0x040 +#define STR_DATA BIT(0) + +#define NFI_CNRNB 0x044 +#define CB2R_TIME_S 4 +#define CB2R_TIME_M GENMASK(7, 4) +#define STR_CNRNB BIT(0) + +#define NFI_DATAW 0x050 +#define NFI_DATAR 0x054 + +#define NFI_PIO_DIRDY 0x058 +#define PIO_DIRDY BIT(0) + +#define NFI_STA 0x060 +#define STA_NFI_FSM_S 16 +#define STA_NFI_FSM_M GENMASK(19, 16) +#define STA_FSM_CUSTOM_DATA 14 +#define STA_BUSY BIT(8) +#define STA_ADDR BIT(1) +#define STA_CMD BIT(0) + +#define NFI_ADDRCNTR 0x070 +#define SEC_CNTR_S 12 +#define SEC_CNTR_M GENMASK(15, 12) +#define SEC_ADDR_S 0 +#define SEC_ADDR_M GENMASK(9, 0) + +#define NFI_CSEL 0x090 +#define CSEL_S 0 +#define CSEL_M GENMASK(1, 0) + +#define NFI_FDM0L 0x0a0 +#define NFI_FDML(n) (0x0a0 + ((n) << 3)) + +#define NFI_FDM0M 0x0a4 +#define NFI_FDMM(n) (0x0a4 + ((n) << 3)) + +#define NFI_MASTER_STA 0x210 +#define MAS_ADDR GENMASK(11, 9) +#define MAS_RD GENMASK(8, 6) +#define MAS_WR GENMASK(5, 3) +#define MAS_RDDLY GENMASK(2, 0) + +/* ECC engine registers */ +#define ECC_ENCCON 0x000 +#define ENC_EN BIT(0) + +#define ECC_ENCCNFG 0x004 +#define ENC_CNFG_MSG_S 16 +#define ENC_CNFG_MSG_M GENMASK(28, 16) +#define ENC_MODE_S 4 +#define ENC_MODE_M GENMASK(5, 4) +#define ENC_MODE_NFI 1 +#define ENC_TNUM_S 0 +#define ENC_TNUM_M GENMASK(2, 0) + +#define ECC_ENCIDLE 0x00c +#define ENC_IDLE BIT(0) + +#define ECC_DECCON 0x100 +#define DEC_EN BIT(0) + +#define ECC_DECCNFG 0x104 +#define DEC_EMPTY_EN BIT(31) +#define DEC_CS_S 16 +#define DEC_CS_M GENMASK(28, 16) +#define DEC_CON_S 12 +#define DEC_CON_M GENMASK(13, 12) +#define DEC_CON_EL 2 +#define DEC_MODE_S 4 +#define DEC_MODE_M GENMASK(5, 4) +#define DEC_MODE_NFI 1 +#define DEC_TNUM_S 0 +#define DEC_TNUM_M GENMASK(2, 0) + +#define ECC_DECIDLE 0x10c +#define DEC_IDLE BIT(1) + +#define ECC_DECENUM 0x114 +#define ERRNUM_S 2 +#define ERRNUM_M GENMASK(3, 0) + +#define ECC_DECDONE 0x118 +#define DEC_DONE7 BIT(7) +#define DEC_DONE6 BIT(6) +#define DEC_DONE5 BIT(5) +#define DEC_DONE4 BIT(4) +#define DEC_DONE3 BIT(3) +#define DEC_DONE2 BIT(2) +#define DEC_DONE1 BIT(1) +#define DEC_DONE0 BIT(0) + +#define ECC_DECEL(n) (0x11c + (n) * 4) +#define DEC_EL_ODD_S 16 +#define DEC_EL_EVEN_S 0 +#define DEC_EL_M 0x1fff +#define DEC_EL_BYTE_POS_S 3 +#define DEC_EL_BIT_POS_M GENMASK(3, 0) + +#define ECC_FDMADDR 0x13c + +/* ENCIDLE and DECIDLE */ +#define ECC_IDLE BIT(0) + +#define ACCTIMING(tpoecs, tprecs, tc2r, tw2r, twh, twst, trlt) \ + ((tpoecs) << ACCCON_POECS_S | (tprecs) << ACCCON_PRECS_S | \ + (tc2r) << ACCCON_C2R_S | (tw2r) << ACCCON_W2R_S | \ + (twh) << ACCCON_WH_S | (twst) << ACCCON_WST_S | (trlt)) + +#define MASTER_STA_MASK (MAS_ADDR | MAS_RD | MAS_WR | \ + MAS_RDDLY) +#define NFI_RESET_TIMEOUT 1000000 +#define NFI_CORE_TIMEOUT 500000 +#define ECC_ENGINE_TIMEOUT 500000 + +#define ECC_SECTOR_SIZE 512 +#define ECC_PARITY_BITS 13 + +#define NFI_FDM_SIZE 8 + +/* Register base */ +#define NFI_BASE 0x1e003000 +#define NFI_ECC_BASE 0x1e003800 + +struct mt7621_nfc { + struct nand_chip nand; + + void __iomem *nfi_regs; + void __iomem *ecc_regs; + + u32 spare_per_sector; +}; + +static struct mt7621_nfc nfc_dev; + +static const u16 mt7621_nfi_page_size[] = { SZ_512, SZ_2K, SZ_4K }; +static const u8 mt7621_nfi_spare_size[] = { 16, 26, 27, 28 }; +static const u8 mt7621_ecc_strength[] = { 4, 6, 8, 10, 12 }; + +static inline u32 nfi_read32(struct mt7621_nfc *nfc, u32 reg) +{ + return readl(nfc->nfi_regs + reg); +} + +static inline void nfi_write32(struct mt7621_nfc *nfc, u32 reg, u32 val) +{ + writel(val, nfc->nfi_regs + reg); +} + +static inline u16 nfi_read16(struct mt7621_nfc *nfc, u32 reg) +{ + return readw(nfc->nfi_regs + reg); +} + +static inline void nfi_write16(struct mt7621_nfc *nfc, u32 reg, u16 val) +{ + writew(val, nfc->nfi_regs + reg); +} + +static inline void ecc_write16(struct mt7621_nfc *nfc, u32 reg, u16 val) +{ + writew(val, nfc->ecc_regs + reg); +} + +static inline u32 ecc_read32(struct mt7621_nfc *nfc, u32 reg) +{ + return readl(nfc->ecc_regs + reg); +} + +static inline void ecc_write32(struct mt7621_nfc *nfc, u32 reg, u32 val) +{ + return writel(val, nfc->ecc_regs + reg); +} + +static inline u8 *oob_fdm_ptr(struct nand_chip *nand, int sect) +{ + return nand->oob_poi + sect * NFI_FDM_SIZE; +} + +static inline u8 *oob_ecc_ptr(struct mt7621_nfc *nfc, int sect) +{ + struct nand_chip *nand = &nfc->nand; + + return nand->oob_poi + nand->ecc.steps * NFI_FDM_SIZE + + sect * (nfc->spare_per_sector - NFI_FDM_SIZE); +} + +static inline u8 *page_data_ptr(struct nand_chip *nand, const u8 *buf, + int sect) +{ + return (u8 *)buf + sect * nand->ecc.size; +} + +static int mt7621_ecc_wait_idle(struct mt7621_nfc *nfc, u32 reg) +{ + u32 val; + int ret; + + ret = readw_poll_timeout(nfc->ecc_regs + reg, val, val & ECC_IDLE, + ECC_ENGINE_TIMEOUT); + if (ret) { + pr_warn("ECC engine timed out entering idle mode\n"); + return -EIO; + } + + return 0; +} + +static int mt7621_ecc_decoder_wait_done(struct mt7621_nfc *nfc, u32 sect) +{ + u32 val; + int ret; + + ret = readw_poll_timeout(nfc->ecc_regs + ECC_DECDONE, val, + val & (1 << sect), ECC_ENGINE_TIMEOUT); + if (ret) { + pr_warn("ECC decoder for sector %d timed out\n", sect); + return -ETIMEDOUT; + } + + return 0; +} + +static void mt7621_ecc_encoder_op(struct mt7621_nfc *nfc, bool enable) +{ + mt7621_ecc_wait_idle(nfc, ECC_ENCIDLE); + ecc_write16(nfc, ECC_ENCCON, enable ? ENC_EN : 0); +} + +static void mt7621_ecc_decoder_op(struct mt7621_nfc *nfc, bool enable) +{ + mt7621_ecc_wait_idle(nfc, ECC_DECIDLE); + ecc_write16(nfc, ECC_DECCON, enable ? DEC_EN : 0); +} + +static int mt7621_ecc_correct_check(struct mt7621_nfc *nfc, u8 *sector_buf, + u8 *fdm_buf, u32 sect) +{ + struct nand_chip *nand = &nfc->nand; + u32 decnum, num_error_bits, fdm_end_bits; + u32 error_locations, error_bit_loc; + u32 error_byte_pos, error_bit_pos; + int bitflips = 0; + u32 i; + + decnum = ecc_read32(nfc, ECC_DECENUM); + num_error_bits = (decnum >> (sect << ERRNUM_S)) & ERRNUM_M; + fdm_end_bits = (nand->ecc.size + NFI_FDM_SIZE) << 3; + + if (!num_error_bits) + return 0; + + if (num_error_bits == ERRNUM_M) + return -1; + + for (i = 0; i < num_error_bits; i++) { + error_locations = ecc_read32(nfc, ECC_DECEL(i / 2)); + error_bit_loc = (error_locations >> ((i % 2) * DEC_EL_ODD_S)) & + DEC_EL_M; + error_byte_pos = error_bit_loc >> DEC_EL_BYTE_POS_S; + error_bit_pos = error_bit_loc & DEC_EL_BIT_POS_M; + + if (error_bit_loc < (nand->ecc.size << 3)) { + if (sector_buf) { + sector_buf[error_byte_pos] ^= + (1 << error_bit_pos); + } + } else if (error_bit_loc < fdm_end_bits) { + if (fdm_buf) { + fdm_buf[error_byte_pos - nand->ecc.size] ^= + (1 << error_bit_pos); + } + } + + bitflips++; + } + + return bitflips; +} + +static int mt7621_nfc_wait_write_completion(struct mt7621_nfc *nfc, + struct nand_chip *nand) +{ + u16 val; + int ret; + + ret = readw_poll_timeout(nfc->nfi_regs + NFI_ADDRCNTR, val, + ((val & SEC_CNTR_M) >> SEC_CNTR_S) >= nand->ecc.steps, + NFI_CORE_TIMEOUT); + + if (ret) { + pr_warn("NFI core write operation timed out\n"); + return -ETIMEDOUT; + } + + return ret; +} + +static void mt7621_nfc_hw_reset(struct mt7621_nfc *nfc) +{ + u32 val; + int ret; + + /* reset all registers and force the NFI master to terminate */ + nfi_write16(nfc, NFI_CON, CON_FIFO_FLUSH | CON_NFI_RST); + + /* wait for the master to finish the last transaction */ + ret = readw_poll_timeout(nfc->nfi_regs + NFI_MASTER_STA, val, + !(val & MASTER_STA_MASK), NFI_RESET_TIMEOUT); + if (ret) { + pr_warn("Failed to reset NFI master in %dms\n", + NFI_RESET_TIMEOUT); + } + + /* ensure any status register affected by the NFI master is reset */ + nfi_write16(nfc, NFI_CON, CON_FIFO_FLUSH | CON_NFI_RST); + nfi_write16(nfc, NFI_STRDATA, 0); +} + +static inline void mt7621_nfc_hw_init(struct mt7621_nfc *nfc) +{ + u32 acccon; + + /* + * CNRNB: nand ready/busy register + * ------------------------------- + * 7:4: timeout register for polling the NAND busy/ready signal + * 0 : poll the status of the busy/ready signal after [7:4]*16 cycles. + */ + nfi_write16(nfc, NFI_CNRNB, CB2R_TIME_M | STR_CNRNB); + + mt7621_nfc_hw_reset(nfc); + + /* Apply default access timing */ + acccon = ACCTIMING(ACCCON_POECS_DEF, ACCCON_PRECS_DEF, ACCCON_C2R_DEF, + ACCCON_W2R_DEF, ACCCON_WH_DEF, ACCCON_WST_DEF, + ACCCON_RLT_DEF); + + nfi_write32(nfc, NFI_ACCCON, acccon); +} + +static int mt7621_nfc_send_command(struct mt7621_nfc *nfc, u8 command) +{ + u32 val; + int ret; + + nfi_write32(nfc, NFI_CMD, command); + + ret = readl_poll_timeout(nfc->nfi_regs + NFI_STA, val, !(val & STA_CMD), + NFI_CORE_TIMEOUT); + if (ret) { + pr_warn("NFI core timed out entering command mode\n"); + return -EIO; + } + + return 0; +} + +static int mt7621_nfc_send_address_byte(struct mt7621_nfc *nfc, int addr) +{ + u32 val; + int ret; + + nfi_write32(nfc, NFI_COLADDR, addr); + nfi_write32(nfc, NFI_ROWADDR, 0); + nfi_write16(nfc, NFI_ADDRNOB, 1); + + ret = readl_poll_timeout(nfc->nfi_regs + NFI_STA, val, + !(val & STA_ADDR), NFI_CORE_TIMEOUT); + if (ret) { + pr_warn("NFI core timed out entering address mode\n"); + return -EIO; + } + + return 0; +} + +static void mt7621_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, + unsigned int ctrl) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); + + if (ctrl & NAND_ALE) { + mt7621_nfc_send_address_byte(nfc, dat & 0xff); + } else if (ctrl & NAND_CLE) { + mt7621_nfc_hw_reset(nfc); + nfi_write16(nfc, NFI_CNFG, CNFG_OP_CUSTOM << CNFG_OP_MODE_S); + mt7621_nfc_send_command(nfc, dat); + } +} + +static int mt7621_nfc_dev_ready(struct mtd_info *mtd) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); + + if (nfi_read32(nfc, NFI_STA) & STA_BUSY) + return 0; + + return 1; +} + +static void mt7621_nfc_select_chip(struct mtd_info *mtd, int chipnr) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); + + nfi_write16(nfc, NFI_CSEL, 0); +} + +static void mt7621_nfc_wait_pio_ready(struct mt7621_nfc *nfc) +{ + int ret; + u16 val; + + ret = readw_poll_timeout(nfc->nfi_regs + NFI_PIO_DIRDY, val, + val & PIO_DIRDY, NFI_CORE_TIMEOUT); + if (ret < 0) + pr_err("NFI core PIO mode not ready\n"); +} + +static u32 mt7621_nfc_pio_read(struct mt7621_nfc *nfc, bool br) +{ + u32 reg; + + /* after each byte read, the NFI_STA reg is reset by the hardware */ + reg = (nfi_read32(nfc, NFI_STA) & STA_NFI_FSM_M) >> STA_NFI_FSM_S; + if (reg != STA_FSM_CUSTOM_DATA) { + reg = nfi_read16(nfc, NFI_CNFG); + reg |= CNFG_READ_MODE | CNFG_BYTE_RW; + if (!br) + reg &= ~CNFG_BYTE_RW; + nfi_write16(nfc, NFI_CNFG, reg); + + /* + * set to max sector to allow the HW to continue reading over + * unaligned accesses + */ + nfi_write16(nfc, NFI_CON, CON_NFI_SEC_M | CON_NFI_BRD); + + /* trigger to fetch data */ + nfi_write16(nfc, NFI_STRDATA, STR_DATA); + } + + mt7621_nfc_wait_pio_ready(nfc); + + return nfi_read32(nfc, NFI_DATAR); +} + +static void mt7621_nfc_read_data(struct mt7621_nfc *nfc, u8 *buf, u32 len) +{ + while (((uintptr_t)buf & 3) && len) { + *buf = mt7621_nfc_pio_read(nfc, true); + buf++; + len--; + } + + while (len >= 4) { + *(u32 *)buf = mt7621_nfc_pio_read(nfc, false); + buf += 4; + len -= 4; + } + + while (len) { + *buf = mt7621_nfc_pio_read(nfc, true); + buf++; + len--; + } +} + +static void mt7621_nfc_read_data_discard(struct mt7621_nfc *nfc, u32 len) +{ + while (len >= 4) { + mt7621_nfc_pio_read(nfc, false); + len -= 4; + } + + while (len) { + mt7621_nfc_pio_read(nfc, true); + len--; + } +} + +static void mt7621_nfc_pio_write(struct mt7621_nfc *nfc, u32 val, bool bw) +{ + u32 reg; + + reg = (nfi_read32(nfc, NFI_STA) & STA_NFI_FSM_M) >> STA_NFI_FSM_S; + if (reg != STA_FSM_CUSTOM_DATA) { + reg = nfi_read16(nfc, NFI_CNFG); + reg &= ~(CNFG_READ_MODE | CNFG_BYTE_RW); + if (bw) + reg |= CNFG_BYTE_RW; + nfi_write16(nfc, NFI_CNFG, reg); + + nfi_write16(nfc, NFI_CON, CON_NFI_SEC_M | CON_NFI_BWR); + nfi_write16(nfc, NFI_STRDATA, STR_DATA); + } + + mt7621_nfc_wait_pio_ready(nfc); + nfi_write32(nfc, NFI_DATAW, val); +} + +static void mt7621_nfc_write_data(struct mt7621_nfc *nfc, const u8 *buf, + u32 len) +{ + while (((uintptr_t)buf & 3) && len) { + mt7621_nfc_pio_write(nfc, *buf, true); + buf++; + len--; + } + + while (len >= 4) { + mt7621_nfc_pio_write(nfc, *(const u32 *)buf, false); + buf += 4; + len -= 4; + } + + while (len) { + mt7621_nfc_pio_write(nfc, *buf, true); + buf++; + len--; + } +} + +static void mt7621_nfc_write_data_empty(struct mt7621_nfc *nfc, u32 len) +{ + while (len >= 4) { + mt7621_nfc_pio_write(nfc, 0xffffffff, false); + len -= 4; + } + + while (len) { + mt7621_nfc_pio_write(nfc, 0xff, true); + len--; + } +} + +static void mt7621_nfc_write_byte(struct mtd_info *mtd, u8 byte) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); + + mt7621_nfc_pio_write(nfc, byte, true); +} + +static void mt7621_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); + + return mt7621_nfc_write_data(nfc, buf, len); +} + +static u8 mt7621_nfc_read_byte(struct mtd_info *mtd) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); + + return mt7621_nfc_pio_read(nfc, true); +} + +static void mt7621_nfc_read_buf(struct mtd_info *mtd, u8 *buf, int len) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd)); + + mt7621_nfc_read_data(nfc, buf, len); +} + +static int mt7621_nfc_calc_ecc_strength(struct mt7621_nfc *nfc, + u32 avail_ecc_bytes) +{ + struct nand_chip *nand = &nfc->nand; + struct mtd_info *mtd = nand_to_mtd(nand); + u32 strength; + int i; + + strength = avail_ecc_bytes * 8 / ECC_PARITY_BITS; + + /* Find the closest supported ecc strength */ + for (i = ARRAY_SIZE(mt7621_ecc_strength) - 1; i >= 0; i--) { + if (mt7621_ecc_strength[i] <= strength) + break; + } + + if (unlikely(i < 0)) { + pr_err("OOB size (%u) is not supported\n", mtd->oobsize); + return -EINVAL; + } + + nand->ecc.strength = mt7621_ecc_strength[i]; + nand->ecc.bytes = + DIV_ROUND_UP(nand->ecc.strength * ECC_PARITY_BITS, 8); + + pr_debug("ECC strength adjusted to %u bits\n", nand->ecc.strength); + + return i; +} + +static int mt7621_nfc_set_spare_per_sector(struct mt7621_nfc *nfc) +{ + struct nand_chip *nand = &nfc->nand; + struct mtd_info *mtd = nand_to_mtd(nand); + u32 size; + int i; + + size = nand->ecc.bytes + NFI_FDM_SIZE; + + /* Find the closest supported spare size */ + for (i = 0; i < ARRAY_SIZE(mt7621_nfi_spare_size); i++) { + if (mt7621_nfi_spare_size[i] >= size) + break; + } + + if (unlikely(i >= ARRAY_SIZE(mt7621_nfi_spare_size))) { + pr_err("OOB size (%u) is not supported\n", mtd->oobsize); + return -EINVAL; + } + + nfc->spare_per_sector = mt7621_nfi_spare_size[i]; + + return i; +} + +static int mt7621_nfc_ecc_init(struct mt7621_nfc *nfc) +{ + struct nand_chip *nand = &nfc->nand; + struct mtd_info *mtd = nand_to_mtd(nand); + u32 spare_per_sector, encode_block_size, decode_block_size; + u32 ecc_enccfg, ecc_deccfg; + int ecc_cap; + + nand->ecc.options |= NAND_ECC_CUSTOM_PAGE_ACCESS; + + nand->ecc.size = ECC_SECTOR_SIZE; + nand->ecc.steps = mtd->writesize / nand->ecc.size; + + spare_per_sector = mtd->oobsize / nand->ecc.steps; + + ecc_cap = mt7621_nfc_calc_ecc_strength(nfc, + spare_per_sector - NFI_FDM_SIZE); + if (ecc_cap < 0) + return ecc_cap; + + /* Sector + FDM */ + encode_block_size = (nand->ecc.size + NFI_FDM_SIZE) * 8; + ecc_enccfg = ecc_cap | (ENC_MODE_NFI << ENC_MODE_S) | + (encode_block_size << ENC_CNFG_MSG_S); + + /* Sector + FDM + ECC parity bits */ + decode_block_size = ((nand->ecc.size + NFI_FDM_SIZE) * 8) + + nand->ecc.strength * ECC_PARITY_BITS; + ecc_deccfg = ecc_cap | (DEC_MODE_NFI << DEC_MODE_S) | + (decode_block_size << DEC_CS_S) | + (DEC_CON_EL << DEC_CON_S) | DEC_EMPTY_EN; + + mt7621_ecc_encoder_op(nfc, false); + ecc_write32(nfc, ECC_ENCCNFG, ecc_enccfg); + + mt7621_ecc_decoder_op(nfc, false); + ecc_write32(nfc, ECC_DECCNFG, ecc_deccfg); + + return 0; +} + +static int mt7621_nfc_set_page_format(struct mt7621_nfc *nfc) +{ + struct nand_chip *nand = &nfc->nand; + struct mtd_info *mtd = nand_to_mtd(nand); + int i, spare_size; + u32 pagefmt; + + spare_size = mt7621_nfc_set_spare_per_sector(nfc); + if (spare_size < 0) + return spare_size; + + for (i = 0; i < ARRAY_SIZE(mt7621_nfi_page_size); i++) { + if (mt7621_nfi_page_size[i] == mtd->writesize) + break; + } + + if (unlikely(i >= ARRAY_SIZE(mt7621_nfi_page_size))) { + pr_err("Page size (%u) is not supported\n", mtd->writesize); + return -EINVAL; + } + + pagefmt = i | (spare_size << PAGEFMT_SPARE_S) | + (NFI_FDM_SIZE << PAGEFMT_FDM_S) | + (NFI_FDM_SIZE << PAGEFMT_FDM_ECC_S); + + nfi_write16(nfc, NFI_PAGEFMT, pagefmt); + + return 0; +} + +static int mt7621_nfc_attach_chip(struct nand_chip *nand) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(nand); + int ret; + + if (nand->options & NAND_BUSWIDTH_16) { + pr_err("16-bit buswidth is not supported"); + return -EINVAL; + } + + ret = mt7621_nfc_ecc_init(nfc); + if (ret) + return ret; + + return mt7621_nfc_set_page_format(nfc); +} + +static void mt7621_nfc_write_fdm(struct mt7621_nfc *nfc) +{ + struct nand_chip *nand = &nfc->nand; + u32 vall, valm; + u8 *oobptr; + int i, j; + + for (i = 0; i < nand->ecc.steps; i++) { + vall = 0; + valm = 0; + oobptr = oob_fdm_ptr(nand, i); + + for (j = 0; j < 4; j++) + vall |= (u32)oobptr[j] << (j * 8); + + for (j = 0; j < 4; j++) + valm |= (u32)oobptr[j + 4] << ((j - 4) * 8); + + nfi_write32(nfc, NFI_FDML(i), vall); + nfi_write32(nfc, NFI_FDMM(i), valm); + } +} + +static void mt7621_nfc_read_sector_fdm(struct mt7621_nfc *nfc, u32 sect) +{ + struct nand_chip *nand = &nfc->nand; + u32 vall, valm; + u8 *oobptr; + int i; + + vall = nfi_read32(nfc, NFI_FDML(sect)); + valm = nfi_read32(nfc, NFI_FDMM(sect)); + oobptr = oob_fdm_ptr(nand, sect); + + for (i = 0; i < 4; i++) + oobptr[i] = (vall >> (i * 8)) & 0xff; + + for (i = 0; i < 4; i++) + oobptr[i + 4] = (valm >> (i * 8)) & 0xff; +} + +static int mt7621_nfc_read_page_hwecc(struct mtd_info *mtd, + struct nand_chip *nand, uint8_t *buf, + int oob_required, int page) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(nand); + int bitflips = 0, ret = 0; + int rc, i; + + nand_read_page_op(nand, page, 0, NULL, 0); + + nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) | + CNFG_READ_MODE | CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); + + mt7621_ecc_decoder_op(nfc, true); + + nfi_write16(nfc, NFI_CON, + CON_NFI_BRD | (nand->ecc.steps << CON_NFI_SEC_S)); + + for (i = 0; i < nand->ecc.steps; i++) { + if (buf) + mt7621_nfc_read_data(nfc, page_data_ptr(nand, buf, i), + nand->ecc.size); + else + mt7621_nfc_read_data_discard(nfc, nand->ecc.size); + + rc = mt7621_ecc_decoder_wait_done(nfc, i); + + mt7621_nfc_read_sector_fdm(nfc, i); + + if (rc < 0) { + ret = -EIO; + continue; + } + + rc = mt7621_ecc_correct_check(nfc, + buf ? page_data_ptr(nand, buf, i) : NULL, + oob_fdm_ptr(nand, i), i); + + if (rc < 0) { + pr_warn("Uncorrectable ECC error at page %d step %d\n", + page, i); + bitflips = nand->ecc.strength + 1; + mtd->ecc_stats.failed++; + } else { + if (rc > bitflips) + bitflips = rc; + mtd->ecc_stats.corrected += rc; + } + } + + mt7621_ecc_decoder_op(nfc, false); + + nfi_write16(nfc, NFI_CON, 0); + + if (ret < 0) + return ret; + + return bitflips; +} + +static int mt7621_nfc_read_page_raw(struct mtd_info *mtd, + struct nand_chip *nand, uint8_t *buf, + int oob_required, int page) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(nand); + int i; + + nand_read_page_op(nand, page, 0, NULL, 0); + + nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) | + CNFG_READ_MODE); + + nfi_write16(nfc, NFI_CON, + CON_NFI_BRD | (nand->ecc.steps << CON_NFI_SEC_S)); + + for (i = 0; i < nand->ecc.steps; i++) { + /* Read data */ + if (buf) + mt7621_nfc_read_data(nfc, page_data_ptr(nand, buf, i), + nand->ecc.size); + else + mt7621_nfc_read_data_discard(nfc, nand->ecc.size); + + /* Read FDM */ + mt7621_nfc_read_data(nfc, oob_fdm_ptr(nand, i), NFI_FDM_SIZE); + + /* Read ECC parity data */ + mt7621_nfc_read_data(nfc, oob_ecc_ptr(nfc, i), + nfc->spare_per_sector - NFI_FDM_SIZE); + } + + nfi_write16(nfc, NFI_CON, 0); + + return 0; +} + +static int mt7621_nfc_read_oob_hwecc(struct mtd_info *mtd, + struct nand_chip *nand, int page) +{ + return mt7621_nfc_read_page_hwecc(mtd, nand, NULL, 1, page); +} + +static int mt7621_nfc_read_oob_raw(struct mtd_info *mtd, + struct nand_chip *nand, int page) +{ + return mt7621_nfc_read_page_raw(mtd, nand, NULL, 1, page); +} + +static int mt7621_nfc_check_empty_page(struct nand_chip *nand, const u8 *buf) +{ + struct mtd_info *mtd = nand_to_mtd(nand); + u8 *oobptr; + u32 i, j; + + if (buf) { + for (i = 0; i < mtd->writesize; i++) + if (buf[i] != 0xff) + return 0; + } + + for (i = 0; i < nand->ecc.steps; i++) { + oobptr = oob_fdm_ptr(nand, i); + for (j = 0; j < NFI_FDM_SIZE; j++) + if (oobptr[j] != 0xff) + return 0; + } + + return 1; +} + +static int mt7621_nfc_write_page_hwecc(struct mtd_info *mtd, + struct nand_chip *nand, + const u8 *buf, int oob_required, + int page) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(nand); + + if (mt7621_nfc_check_empty_page(nand, buf)) { + /* + * MT7621 ECC engine always generates parity code for input + * pages, even for empty pages. Doing so will write back ECC + * parity code to the oob region, which means such pages will + * no longer be empty pages. + * + * To avoid this, stop write operation if current page is an + * empty page. + */ + return 0; + } + + nand_prog_page_begin_op(nand, page, 0, NULL, 0); + + nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S) | + CNFG_AUTO_FMT_EN | CNFG_HW_ECC_EN); + + mt7621_ecc_encoder_op(nfc, true); + + mt7621_nfc_write_fdm(nfc); + + nfi_write16(nfc, NFI_CON, + CON_NFI_BWR | (nand->ecc.steps << CON_NFI_SEC_S)); + + if (buf) + mt7621_nfc_write_data(nfc, buf, mtd->writesize); + else + mt7621_nfc_write_data_empty(nfc, mtd->writesize); + + mt7621_nfc_wait_write_completion(nfc, nand); + + mt7621_ecc_encoder_op(nfc, false); + + nfi_write16(nfc, NFI_CON, 0); + + return nand_prog_page_end_op(nand); +} + +static int mt7621_nfc_write_page_raw(struct mtd_info *mtd, + struct nand_chip *nand, + const u8 *buf, int oob_required, + int page) +{ + struct mt7621_nfc *nfc = nand_get_controller_data(nand); + int i; + + nand_prog_page_begin_op(nand, page, 0, NULL, 0); + + nfi_write16(nfc, NFI_CNFG, (CNFG_OP_CUSTOM << CNFG_OP_MODE_S)); + + nfi_write16(nfc, NFI_CON, + CON_NFI_BWR | (nand->ecc.steps << CON_NFI_SEC_S)); + + for (i = 0; i < nand->ecc.steps; i++) { + /* Write data */ + if (buf) + mt7621_nfc_write_data(nfc, page_data_ptr(nand, buf, i), + nand->ecc.size); + else + mt7621_nfc_write_data_empty(nfc, nand->ecc.size); + + /* Write FDM */ + mt7621_nfc_write_data(nfc, oob_fdm_ptr(nand, i), + NFI_FDM_SIZE); + + /* Write dummy ECC parity data */ + mt7621_nfc_write_data_empty(nfc, nfc->spare_per_sector - + NFI_FDM_SIZE); + } + + mt7621_nfc_wait_write_completion(nfc, nand); + + nfi_write16(nfc, NFI_CON, 0); + + return nand_prog_page_end_op(nand); +} + +static int mt7621_nfc_write_oob_hwecc(struct mtd_info *mtd, + struct nand_chip *nand, int page) +{ + return mt7621_nfc_write_page_hwecc(mtd, nand, NULL, 1, page); +} + +static int mt7621_nfc_write_oob_raw(struct mtd_info *mtd, + struct nand_chip *nand, int page) +{ + return mt7621_nfc_write_page_raw(mtd, nand, NULL, 1, page); +} + +static int mt7621_nfc_ooblayout_free(struct mtd_info *mtd, int section, + struct mtd_oob_region *oob_region) +{ + struct nand_chip *nand = mtd_to_nand(mtd); + + if (section >= nand->ecc.steps) + return -ERANGE; + + oob_region->length = NFI_FDM_SIZE - 1; + oob_region->offset = section * NFI_FDM_SIZE + 1; + + return 0; +} + +static int mt7621_nfc_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *oob_region) +{ + struct nand_chip *nand = mtd_to_nand(mtd); + + if (section) + return -ERANGE; + + oob_region->offset = NFI_FDM_SIZE * nand->ecc.steps; + oob_region->length = mtd->oobsize - oob_region->offset; + + return 0; +} + +static const struct mtd_ooblayout_ops mt7621_nfc_ooblayout_ops = { + .rfree = mt7621_nfc_ooblayout_free, + .ecc = mt7621_nfc_ooblayout_ecc, +}; + +/* + * This function will override the default one which is not supposed to be + * used for ECC syndrome based pages. + */ +static int mt7621_nfc_block_bad(struct mtd_info *mtd, loff_t ofs) +{ + struct nand_chip *nand = mtd_to_nand(mtd); + struct mtd_oob_ops ops; + int ret, i = 0; + u16 bad; + + memset(&ops, 0, sizeof(ops)); + ops.oobbuf = (uint8_t *)&bad; + ops.ooboffs = nand->badblockpos; + if (nand->options & NAND_BUSWIDTH_16) { + ops.ooboffs &= ~0x01; + ops.ooblen = 2; + } else { + ops.ooblen = 1; + } + ops.mode = MTD_OPS_RAW; + + /* Read from first/last page(s) if necessary */ + if (nand->bbt_options & NAND_BBT_SCANLASTPAGE) + ofs += mtd->erasesize - mtd->writesize; + + do { + ret = mtd_read_oob(mtd, ofs, &ops); + if (ret) + return ret; + + if (likely(nand->badblockbits == 8)) + ret = bad != 0xFF; + else + ret = hweight8(bad) < nand->badblockbits; + + i++; + ofs += mtd->writesize; + } while (!ret && (nand->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2); + + return ret; +} + +static void mt7621_nfc_init_chip(struct mt7621_nfc *nfc) +{ + struct nand_chip *nand = &nfc->nand; + struct mtd_info *mtd; + int ret; + + nand_set_controller_data(nand, (void *)nfc); + + nand->options |= NAND_NO_SUBPAGE_WRITE; + + nand->ecc.mode = NAND_ECC_HW_SYNDROME; + nand->ecc.read_page = mt7621_nfc_read_page_hwecc; + nand->ecc.read_page_raw = mt7621_nfc_read_page_raw; + nand->ecc.write_page = mt7621_nfc_write_page_hwecc; + nand->ecc.write_page_raw = mt7621_nfc_write_page_raw; + nand->ecc.read_oob = mt7621_nfc_read_oob_hwecc; + nand->ecc.read_oob_raw = mt7621_nfc_read_oob_raw; + nand->ecc.write_oob = mt7621_nfc_write_oob_hwecc; + nand->ecc.write_oob_raw = mt7621_nfc_write_oob_raw; + + nand->dev_ready = mt7621_nfc_dev_ready; + nand->select_chip = mt7621_nfc_select_chip; + nand->write_byte = mt7621_nfc_write_byte; + nand->write_buf = mt7621_nfc_write_buf; + nand->read_byte = mt7621_nfc_read_byte; + nand->read_buf = mt7621_nfc_read_buf; + nand->cmd_ctrl = mt7621_nfc_cmd_ctrl; + nand->block_bad = mt7621_nfc_block_bad; + + mtd = nand_to_mtd(nand); + mtd_set_ooblayout(mtd, &mt7621_nfc_ooblayout_ops); + + /* Reset NFI master */ + mt7621_nfc_hw_init(nfc); + + ret = nand_scan_ident(mtd, 1, NULL); + if (ret) + return; + + mt7621_nfc_attach_chip(nand); + + ret = nand_scan_tail(mtd); + if (ret) + return; + + nand_register(0, mtd); +} + +void board_nand_init(void) +{ + nfc_dev.nfi_regs = (void __iomem *)CKSEG1ADDR(NFI_BASE); + nfc_dev.ecc_regs = (void __iomem *)CKSEG1ADDR(NFI_ECC_BASE); + + mt7621_nfc_init_chip(&nfc_dev); +}

This patch makes xhci-mtk driver available for MediaTek MT7621 SoC
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: none --- drivers/usb/host/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 8f77412cc7..8f7bfe1602 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -34,7 +34,7 @@ config USB_XHCI_DWC3_OF_SIMPLE
config USB_XHCI_MTK bool "Support for MediaTek on-chip xHCI USB controller" - depends on ARCH_MEDIATEK + depends on ARCH_MEDIATEK || SOC_MT7621 help Enables support for the on-chip xHCI controller on MediaTek SoCs.

This patch makes mtk-tphy driver available for MediaTek MT7621 SoC
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: none --- drivers/phy/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index c01d9e09b9..1708d4f533 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -266,7 +266,7 @@ config MT76X8_USB_PHY config PHY_MTK_TPHY bool "MediaTek T-PHY Driver" depends on PHY - depends on ARCH_MEDIATEK + depends on ARCH_MEDIATEK || SOC_MT7621 help MediaTek T-PHY driver supports usb2.0, usb3.0 ports, PCIe and SATA, and meanwhile supports two version T-PHY which have

This patch makes mt7621_spi driver available for MediaTek MT7621 SoC
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: none --- drivers/spi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 8dba95ae4e..d88c43031f 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -240,7 +240,7 @@ config MT7620_SPI
config MT7621_SPI bool "MediaTek MT7621 SPI driver" - depends on SOC_MT7628 + depends on SOC_MT7621 || SOC_MT7628 help Enable the MT7621 SPI driver. This driver can be used to access the SPI NOR flash on platforms embedding this Ralink / MediaTek

This patch makes mt7621_gpio driver available for MediaTek MT7621 SoC
Reviewed-by: Stefan Roese sr@denx.de Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: none --- drivers/gpio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 89068c7800..f4e41c765e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -534,7 +534,7 @@ config MT7620_GPIO
config MT7621_GPIO bool "MediaTek MT7621 GPIO driver" - depends on DM_GPIO && SOC_MT7628 + depends on DM_GPIO && (SOC_MT7621 || SOC_MT7628) default y help Say yes here to support MediaTek MT7621 compatible GPIOs.

This patch makes mt7621_wdt driver available for MediaTek MT7621 SoC
Reviewed-by: Stefan Roese sr@denx.de Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: none --- drivers/watchdog/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 03e8e72e6b..c63a40e2f9 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -184,7 +184,7 @@ config WDT_MT7620
config WDT_MT7621 bool "MediaTek MT7621 watchdog timer support" - depends on WDT && SOC_MT7628 + depends on WDT && (SOC_MT7621 || SOC_MT7628) help Select this to enable Ralink / Mediatek watchdog timer, which can be found on some MediaTek chips.

This patch adds SDXC support for MediaTek MT7621 SoC
Reviewed-by: Jaehoon Chung jh80.chung@samsung.com Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: none --- drivers/mmc/mtk-sd.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index 97182ffd7f..e61e8cf4b9 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -1761,6 +1761,18 @@ static const struct msdc_compatible mt7620_compat = { .default_pad_dly = true, };
+static const struct msdc_compatible mt7621_compat = { + .clk_div_bits = 8, + .pad_tune0 = false, + .async_fifo = true, + .data_tune = true, + .busy_check = false, + .stop_clk_fix = false, + .enhance_rx = false, + .builtin_pad_ctrl = true, + .default_pad_dly = true, +}; + static const struct msdc_compatible mt7622_compat = { .clk_div_bits = 12, .pad_tune0 = true, @@ -1809,6 +1821,7 @@ static const struct msdc_compatible mt8183_compat = {
static const struct udevice_id msdc_ids[] = { { .compatible = "mediatek,mt7620-mmc", .data = (ulong)&mt7620_compat }, + { .compatible = "mediatek,mt7621-mmc", .data = (ulong)&mt7621_compat }, { .compatible = "mediatek,mt7622-mmc", .data = (ulong)&mt7622_compat }, { .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat }, { .compatible = "mediatek,mt8512-mmc", .data = (ulong)&mt8512_compat },

This patch adds GMAC support for MediaTek MT7621 SoC. MT7621 has the same GMAC/Switch configuration as MT7623.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: Add register remap needed by mt7621 Fix use of noncached_alloc v2 changes: none --- drivers/net/mtk_eth.c | 45 ++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c index 666ddeb10d..4fe7ee0d36 100644 --- a/drivers/net/mtk_eth.c +++ b/drivers/net/mtk_eth.c @@ -145,7 +145,8 @@ enum mtk_switch { enum mtk_soc { SOC_MT7623, SOC_MT7629, - SOC_MT7622 + SOC_MT7622, + SOC_MT7621 };
struct mtk_eth_priv { @@ -159,9 +160,10 @@ struct mtk_eth_priv {
void __iomem *fe_base; void __iomem *gmac_base; - void __iomem *ethsys_base; void __iomem *sgmii_base;
+ struct regmap *ethsys_regmap; + struct mii_dev *mdio_bus; int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg); int (*mii_write)(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 val); @@ -233,7 +235,12 @@ static void mtk_gmac_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set) static void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set) { - clrsetbits_le32(priv->ethsys_base + reg, clr, set); + uint val; + + regmap_read(priv->ethsys_regmap, reg, &val); + val &= ~clr; + val |= set; + regmap_write(priv->ethsys_regmap, reg, val); }
/* Direct MDIO clause 22/45 access via SoC */ @@ -669,12 +676,18 @@ static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode) static int mt7530_setup(struct mtk_eth_priv *priv) { u16 phy_addr, phy_val; - u32 val; + u32 val, txdrv; int i;
- /* Select 250MHz clk for RGMII mode */ - mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG, - ETHSYS_TRGMII_CLK_SEL362_5, 0); + if (priv->soc != SOC_MT7621) { + /* Select 250MHz clk for RGMII mode */ + mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG, + ETHSYS_TRGMII_CLK_SEL362_5, 0); + + txdrv = 8; + } else { + txdrv = 4; + }
/* Modify HWTRAP first to allow direct access to internal PHYs */ mt753x_reg_read(priv, HWTRAP_REG, &val); @@ -732,7 +745,8 @@ static int mt7530_setup(struct mtk_eth_priv *priv) /* Lower Tx Driving for TRGMII path */ for (i = 0 ; i < NUM_TRGMII_CTRL ; i++) mt753x_reg_write(priv, MT7530_TRGMII_TD_ODT(i), - (8 << TD_DM_DRVP_S) | (8 << TD_DM_DRVN_S)); + (txdrv << TD_DM_DRVP_S) | + (txdrv << TD_DM_DRVN_S));
for (i = 0 ; i < NUM_TRGMII_CTRL; i++) mt753x_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16); @@ -1419,7 +1433,7 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
priv->soc = dev_get_driver_data(dev);
- pdata->iobase = dev_read_addr(dev); + pdata->iobase = (phys_addr_t)dev_remap_addr(dev);
/* get corresponding ethsys phandle */ ret = dev_read_phandle_with_args(dev, "mediatek,ethsys", NULL, 0, 0, @@ -1427,15 +1441,9 @@ static int mtk_eth_of_to_plat(struct udevice *dev) if (ret) return ret;
- regmap = syscon_node_to_regmap(args.node); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - priv->ethsys_base = regmap_get_range(regmap, 0); - if (!priv->ethsys_base) { - dev_err(dev, "Unable to find ethsys\n"); - return -ENODEV; - } + priv->ethsys_regmap = syscon_node_to_regmap(args.node); + if (IS_ERR(priv->ethsys_regmap)) + return PTR_ERR(priv->ethsys_regmap);
/* Reset controllers */ ret = reset_get_by_name(dev, "fe", &priv->rst_fe); @@ -1540,6 +1548,7 @@ static const struct udevice_id mtk_eth_ids[] = { { .compatible = "mediatek,mt7629-eth", .data = SOC_MT7629 }, { .compatible = "mediatek,mt7623-eth", .data = SOC_MT7623 }, { .compatible = "mediatek,mt7622-eth", .data = SOC_MT7622 }, + { .compatible = "mediatek,mt7621-eth", .data = SOC_MT7621 }, {} };

On Thu, Apr 28, 2022 at 1:38 PM Weijie Gao weijie.gao@mediatek.com wrote:
This patch adds GMAC support for MediaTek MT7621 SoC. MT7621 has the same GMAC/Switch configuration as MT7623.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
v3 changes: Add register remap needed by mt7621 Fix use of noncached_alloc v2 changes: none
drivers/net/mtk_eth.c | 45 ++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c index 666ddeb10d..4fe7ee0d36 100644 --- a/drivers/net/mtk_eth.c +++ b/drivers/net/mtk_eth.c @@ -145,7 +145,8 @@ enum mtk_switch { enum mtk_soc { SOC_MT7623, SOC_MT7629,
SOC_MT7622
SOC_MT7622,
SOC_MT7621
};
struct mtk_eth_priv { @@ -159,9 +160,10 @@ struct mtk_eth_priv {
void __iomem *fe_base; void __iomem *gmac_base;
void __iomem *ethsys_base; void __iomem *sgmii_base;
struct regmap *ethsys_regmap;
struct mii_dev *mdio_bus; int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg); int (*mii_write)(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 val);
@@ -233,7 +235,12 @@ static void mtk_gmac_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set) static void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set) {
clrsetbits_le32(priv->ethsys_base + reg, clr, set);
uint val;
regmap_read(priv->ethsys_regmap, reg, &val);
val &= ~clr;
val |= set;
regmap_write(priv->ethsys_regmap, reg, val);
}
Changing the registers to regmap is not part of the support for the MT7621. please separate into two patches.
/* Direct MDIO clause 22/45 access via SoC */ @@ -669,12 +676,18 @@ static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode) static int mt7530_setup(struct mtk_eth_priv *priv) { u16 phy_addr, phy_val;
u32 val;
u32 val, txdrv; int i;
/* Select 250MHz clk for RGMII mode */
mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG,
ETHSYS_TRGMII_CLK_SEL362_5, 0);
if (priv->soc != SOC_MT7621) {
/* Select 250MHz clk for RGMII mode */
mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG,
ETHSYS_TRGMII_CLK_SEL362_5, 0);
txdrv = 8;
} else {
txdrv = 4;
} /* Modify HWTRAP first to allow direct access to internal PHYs */ mt753x_reg_read(priv, HWTRAP_REG, &val);
@@ -732,7 +745,8 @@ static int mt7530_setup(struct mtk_eth_priv *priv) /* Lower Tx Driving for TRGMII path */ for (i = 0 ; i < NUM_TRGMII_CTRL ; i++) mt753x_reg_write(priv, MT7530_TRGMII_TD_ODT(i),
(8 << TD_DM_DRVP_S) | (8 << TD_DM_DRVN_S));
(txdrv << TD_DM_DRVP_S) |
(txdrv << TD_DM_DRVN_S)); for (i = 0 ; i < NUM_TRGMII_CTRL; i++) mt753x_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16);
@@ -1419,7 +1433,7 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
priv->soc = dev_get_driver_data(dev);
pdata->iobase = dev_read_addr(dev);
pdata->iobase = (phys_addr_t)dev_remap_addr(dev);
This also needs a patch of it's own.
/* get corresponding ethsys phandle */ ret = dev_read_phandle_with_args(dev, "mediatek,ethsys", NULL, 0, 0,
@@ -1427,15 +1441,9 @@ static int mtk_eth_of_to_plat(struct udevice *dev) if (ret) return ret;
regmap = syscon_node_to_regmap(args.node);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
priv->ethsys_base = regmap_get_range(regmap, 0);
if (!priv->ethsys_base) {
dev_err(dev, "Unable to find ethsys\n");
return -ENODEV;
}
priv->ethsys_regmap = syscon_node_to_regmap(args.node);
if (IS_ERR(priv->ethsys_regmap))
return PTR_ERR(priv->ethsys_regmap); /* Reset controllers */ ret = reset_get_by_name(dev, "fe", &priv->rst_fe);
@@ -1540,6 +1548,7 @@ static const struct udevice_id mtk_eth_ids[] = { { .compatible = "mediatek,mt7629-eth", .data = SOC_MT7629 }, { .compatible = "mediatek,mt7623-eth", .data = SOC_MT7623 }, { .compatible = "mediatek,mt7622-eth", .data = SOC_MT7622 },
{ .compatible = "mediatek,mt7621-eth", .data = SOC_MT7621 }, {}
};
-- 2.17.1

On Sat, 2022-04-30 at 20:13 +0300, Ramon Fried wrote:
On Thu, Apr 28, 2022 at 1:38 PM Weijie Gao weijie.gao@mediatek.com wrote:
This patch adds GMAC support for MediaTek MT7621 SoC. MT7621 has the same GMAC/Switch configuration as MT7623.
Signed-off-by: Weijie Gao weijie.gao@mediatek.com
v3 changes: Add register remap needed by mt7621 Fix use of noncached_alloc v2 changes: none
drivers/net/mtk_eth.c | 45 ++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 18 deletions(-)
diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c index 666ddeb10d..4fe7ee0d36 100644 --- a/drivers/net/mtk_eth.c +++ b/drivers/net/mtk_eth.c @@ -145,7 +145,8 @@ enum mtk_switch { enum mtk_soc { SOC_MT7623, SOC_MT7629,
SOC_MT7622
SOC_MT7622,
SOC_MT7621
};
struct mtk_eth_priv { @@ -159,9 +160,10 @@ struct mtk_eth_priv {
void __iomem *fe_base; void __iomem *gmac_base;
void __iomem *ethsys_base; void __iomem *sgmii_base;
struct regmap *ethsys_regmap;
struct mii_dev *mdio_bus; int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg); int (*mii_write)(struct mtk_eth_priv *priv, u8 phy, u8 reg,
u16 val); @@ -233,7 +235,12 @@ static void mtk_gmac_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set) static void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set) {
clrsetbits_le32(priv->ethsys_base + reg, clr, set);
uint val;
regmap_read(priv->ethsys_regmap, reg, &val);
val &= ~clr;
val |= set;
regmap_write(priv->ethsys_regmap, reg, val);
}
Changing the registers to regmap is not part of the support for the MT7621. please separate into two patches.
OK. I'll split this into three patches.
/* Direct MDIO clause 22/45 access via SoC */ @@ -669,12 +676,18 @@ static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode) static int mt7530_setup(struct mtk_eth_priv *priv) { u16 phy_addr, phy_val;
u32 val;
u32 val, txdrv; int i;
/* Select 250MHz clk for RGMII mode */
mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG,
ETHSYS_TRGMII_CLK_SEL362_5, 0);
if (priv->soc != SOC_MT7621) {
/* Select 250MHz clk for RGMII mode */
mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG,
ETHSYS_TRGMII_CLK_SEL362_5, 0);
txdrv = 8;
} else {
txdrv = 4;
} /* Modify HWTRAP first to allow direct access to internal
PHYs */ mt753x_reg_read(priv, HWTRAP_REG, &val); @@ -732,7 +745,8 @@ static int mt7530_setup(struct mtk_eth_priv *priv) /* Lower Tx Driving for TRGMII path */ for (i = 0 ; i < NUM_TRGMII_CTRL ; i++) mt753x_reg_write(priv, MT7530_TRGMII_TD_ODT(i),
(8 << TD_DM_DRVP_S) | (8 <<
TD_DM_DRVN_S));
(txdrv << TD_DM_DRVP_S) |
(txdrv << TD_DM_DRVN_S)); for (i = 0 ; i < NUM_TRGMII_CTRL; i++) mt753x_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M,
16); @@ -1419,7 +1433,7 @@ static int mtk_eth_of_to_plat(struct udevice *dev)
priv->soc = dev_get_driver_data(dev);
pdata->iobase = dev_read_addr(dev);
pdata->iobase = (phys_addr_t)dev_remap_addr(dev);
This also needs a patch of it's own.
/* get corresponding ethsys phandle */ ret = dev_read_phandle_with_args(dev, "mediatek,ethsys",
NULL, 0, 0, @@ -1427,15 +1441,9 @@ static int mtk_eth_of_to_plat(struct udevice *dev) if (ret) return ret;
regmap = syscon_node_to_regmap(args.node);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
priv->ethsys_base = regmap_get_range(regmap, 0);
if (!priv->ethsys_base) {
dev_err(dev, "Unable to find ethsys\n");
return -ENODEV;
}
priv->ethsys_regmap = syscon_node_to_regmap(args.node);
if (IS_ERR(priv->ethsys_regmap))
return PTR_ERR(priv->ethsys_regmap); /* Reset controllers */ ret = reset_get_by_name(dev, "fe", &priv->rst_fe);
@@ -1540,6 +1548,7 @@ static const struct udevice_id mtk_eth_ids[] = { { .compatible = "mediatek,mt7629-eth", .data = SOC_MT7629 }, { .compatible = "mediatek,mt7623-eth", .data = SOC_MT7623 }, { .compatible = "mediatek,mt7622-eth", .data = SOC_MT7622 },
{ .compatible = "mediatek,mt7621-eth", .data = SOC_MT7621
}, {} };
-- 2.17.1

Update maintainer for MediaTek MIPS platform
Signed-off-by: Weijie Gao weijie.gao@mediatek.com --- v3 changes: none v2 changes: none --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS index 56be0bfad0..80250b41e8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -995,15 +995,20 @@ 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/mt7621.dtsi F: arch/mips/dts/mt7620-u-boot.dtsi F: include/configs/mt7620.h +F: include/configs/mt7621.h F: include/dt-bindings/clock/mt7620-clk.h +F: include/dt-bindings/clock/mt7621-clk.h F: include/dt-bindings/clock/mt7628-clk.h F: include/dt-bindings/reset/mt7620-reset.h +F: include/dt-bindings/reset/mt7621-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/mtd/nand/raw/mt7621_nand.c F: drivers/net/mt7620-eth.c F: drivers/phy/mt7620-usb-phy.c F: drivers/reset/reset-mtmips.c

On Thu, 28 Apr 2022 18:37:09 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
This series will add support for MediaTek MT7621 SoC with two reference boards and related drivers.
The MediaTek MT7621 is a network processor integrating a dual-core dual-threaded MIPS 1004Kc processor running at a normal frequency of 880MHz. This chip can be found in many wireless routers.
Hello Weijie,
doesn't MT7621 U-Boot need a proprietary binary for DDR training? I remember that it was required in 2016 for MqMaker WitiBoard.
Marek

Hi Marek,
Yes. MT7621 does need such a proprietary binary for DDR initialization and calibration. That's why I submit only the ram-bootable part here.
I'm considering to create a preloader to load and run DDR init&calib binary and ram-bootable u-boot image. The ram-bootable u-boot image can be appended to the proloader to form the flash-bootable bootloader.
The source code of preloader will be uploaded to github.
Best Regards, Weijie
On Thu, 2022-04-28 at 18:19 +0200, Marek Behún wrote:
On Thu, 28 Apr 2022 18:37:09 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
This series will add support for MediaTek MT7621 SoC with two reference boards and related drivers.
The MediaTek MT7621 is a network processor integrating a dual-core dual-threaded MIPS 1004Kc processor running at a normal frequency of 880MHz. This chip can be found in many wireless routers.
Hello Weijie,
doesn't MT7621 U-Boot need a proprietary binary for DDR training? I remember that it was required in 2016 for MqMaker WitiBoard.
Marek

Hi Weijie
On 4/29/22 03:23, Weijie Gao wrote:
Hi Marek,
Yes. MT7621 does need such a proprietary binary for DDR initialization and calibration. That's why I submit only the ram-bootable part here.
I'm considering to create a preloader to load and run DDR init&calib binary and ram-bootable u-boot image. The ram-bootable u-boot image can be appended to the proloader to form the flash-bootable bootloader.
The source code of preloader will be uploaded to github.
Just to be sure: You are not implementing this preloader as an U-Boot SPL loader, as this would conflict with U-Boot's GPL compatibility?
Thanks, Stefan
Best Regards, Weijie
On Thu, 2022-04-28 at 18:19 +0200, Marek Behún wrote:
On Thu, 28 Apr 2022 18:37:09 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
This series will add support for MediaTek MT7621 SoC with two reference boards and related drivers.
The MediaTek MT7621 is a network processor integrating a dual-core dual-threaded MIPS 1004Kc processor running at a normal frequency of 880MHz. This chip can be found in many wireless routers.
Hello Weijie,
doesn't MT7621 U-Boot need a proprietary binary for DDR training? I remember that it was required in 2016 for MqMaker WitiBoard.
Marek
Viele Grüße, Stefan Roese

On Fri, 2022-04-29 at 08:15 +0200, Stefan Roese wrote:
Hi Weijie
On 4/29/22 03:23, Weijie Gao wrote:
Hi Marek,
Yes. MT7621 does need such a proprietary binary for DDR initialization and calibration. That's why I submit only the ram-bootable part here.
I'm considering to create a preloader to load and run DDR init&calib binary and ram-bootable u-boot image. The ram-bootable u-boot image can be appended to the proloader to form the flash-bootable bootloader.
The source code of preloader will be uploaded to github.
Just to be sure: You are not implementing this preloader as an U-Boot SPL loader, as this would conflict with U-Boot's GPL compatibility?
Yes. Submitting the source code of this binary also violates MTK's non- disclosure agreement.
Thanks, Stefan
Best Regards, Weijie
On Thu, 2022-04-28 at 18:19 +0200, Marek Behún wrote:
On Thu, 28 Apr 2022 18:37:09 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
This series will add support for MediaTek MT7621 SoC with two reference boards and related drivers.
The MediaTek MT7621 is a network processor integrating a dual- core dual-threaded MIPS 1004Kc processor running at a normal frequency of 880MHz. This chip can be found in many wireless routers.
Hello Weijie,
doesn't MT7621 U-Boot need a proprietary binary for DDR training? I remember that it was required in 2016 for MqMaker WitiBoard.
Marek
Viele Grüße, Stefan Roese

On Fri, 29 Apr 2022 15:59:44 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
On Fri, 2022-04-29 at 08:15 +0200, Stefan Roese wrote:
Hi Weijie
On 4/29/22 03:23, Weijie Gao wrote:
Hi Marek,
Yes. MT7621 does need such a proprietary binary for DDR initialization and calibration. That's why I submit only the ram-bootable part here.
I'm considering to create a preloader to load and run DDR init&calib binary and ram-bootable u-boot image. The ram-bootable u-boot image can be appended to the proloader to form the flash-bootable bootloader.
The source code of preloader will be uploaded to github.
Just to be sure: You are not implementing this preloader as an U-Boot SPL loader, as this would conflict with U-Boot's GPL compatibility?
Yes. Submitting the source code of this binary also violates MTK's non- disclosure agreement.
Isn't it possible to submit the DDR training code in binary version, and somehow call into it from SPL?
Marek

On Fri, 2022-04-29 at 17:13 +0200, Marek Behún wrote:
On Fri, 29 Apr 2022 15:59:44 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
On Fri, 2022-04-29 at 08:15 +0200, Stefan Roese wrote:
Hi Weijie
On 4/29/22 03:23, Weijie Gao wrote:
Hi Marek,
Yes. MT7621 does need such a proprietary binary for DDR initialization and calibration. That's why I submit only the ram-bootable part here.
I'm considering to create a preloader to load and run DDR init&calib binary and ram-bootable u-boot image. The ram-bootable u-boot image can be appended to the proloader to form the flash-bootable bootloader.
The source code of preloader will be uploaded to github.
Just to be sure: You are not implementing this preloader as an U- Boot SPL loader, as this would conflict with U-Boot's GPL compatibility?
Yes. Submitting the source code of this binary also violates MTK's non- disclosure agreement.
Isn't it possible to submit the DDR training code in binary version, and somehow call into it from SPL?
It's possible and I've already implemented it. But will u-boot accept binary file?
Marek

On Sat, 30 Apr 2022 21:31:15 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
On Fri, 2022-04-29 at 17:13 +0200, Marek Behún wrote:
On Fri, 29 Apr 2022 15:59:44 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
On Fri, 2022-04-29 at 08:15 +0200, Stefan Roese wrote:
Hi Weijie
On 4/29/22 03:23, Weijie Gao wrote:
Hi Marek,
Yes. MT7621 does need such a proprietary binary for DDR initialization and calibration. That's why I submit only the ram-bootable part here.
I'm considering to create a preloader to load and run DDR init&calib binary and ram-bootable u-boot image. The ram-bootable u-boot image can be appended to the proloader to form the flash-bootable bootloader.
The source code of preloader will be uploaded to github.
Just to be sure: You are not implementing this preloader as an U- Boot SPL loader, as this would conflict with U-Boot's GPL compatibility?
Yes. Submitting the source code of this binary also violates MTK's non- disclosure agreement.
Isn't it possible to submit the DDR training code in binary version, and somehow call into it from SPL?
It's possible and I've already implemented it. But will u-boot accept binary file?
U-Boot at least accepts drivers that require proprietary firmware to load (bnxt driver, for example).
I don't know whether a binary firmware can be accepted into the U-Boot repository, whether in a separate file or as an u8 array in a .c file, but it should at least be possible to make it so that the user can compile it thsemsevles to be bundled, i.e. create a Kconfig option that configures a path to the firmware. If it is present, it will be compiled with DDR training bundled.
Stefan, Tom, can this be done?
BTW, Weijie, can I already test this on mt7621 board, also with DDR training? Can you send me the patch that adds calling the proprietary code?
Marek

On Sat, Apr 30, 2022 at 03:48:04PM +0200, Marek Behún wrote:
On Sat, 30 Apr 2022 21:31:15 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
On Fri, 2022-04-29 at 17:13 +0200, Marek Behún wrote:
On Fri, 29 Apr 2022 15:59:44 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
On Fri, 2022-04-29 at 08:15 +0200, Stefan Roese wrote:
Hi Weijie
On 4/29/22 03:23, Weijie Gao wrote:
Hi Marek,
Yes. MT7621 does need such a proprietary binary for DDR initialization and calibration. That's why I submit only the ram-bootable part here.
I'm considering to create a preloader to load and run DDR init&calib binary and ram-bootable u-boot image. The ram-bootable u-boot image can be appended to the proloader to form the flash-bootable bootloader.
The source code of preloader will be uploaded to github.
Just to be sure: You are not implementing this preloader as an U- Boot SPL loader, as this would conflict with U-Boot's GPL compatibility?
Yes. Submitting the source code of this binary also violates MTK's non- disclosure agreement.
Isn't it possible to submit the DDR training code in binary version, and somehow call into it from SPL?
It's possible and I've already implemented it. But will u-boot accept binary file?
U-Boot at least accepts drivers that require proprietary firmware to load (bnxt driver, for example).
I don't know whether a binary firmware can be accepted into the U-Boot repository, whether in a separate file or as an u8 array in a .c file, but it should at least be possible to make it so that the user can compile it thsemsevles to be bundled, i.e. create a Kconfig option that configures a path to the firmware. If it is present, it will be compiled with DDR training bundled.
Stefan, Tom, can this be done?
BTW, Weijie, can I already test this on mt7621 board, also with DDR training? Can you send me the patch that adds calling the proprietary code?
At the high level, I would make a further disappointed sigh and note the NXP ddr firmware blobs, the binary blobs we pull in for x86, and all of the other blobs we bring in today via binman. Please make use of one of these otherwise existing mechanics to bring in the required DDR blobs here.

On Sun, 2022-05-01 at 08:52 -0400, Tom Rini wrote:
On Sat, Apr 30, 2022 at 03:48:04PM +0200, Marek Behún wrote:
On Sat, 30 Apr 2022 21:31:15 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
On Fri, 2022-04-29 at 17:13 +0200, Marek Behún wrote:
On Fri, 29 Apr 2022 15:59:44 +0800 Weijie Gao weijie.gao@mediatek.com wrote:
On Fri, 2022-04-29 at 08:15 +0200, Stefan Roese wrote:
Hi Weijie
On 4/29/22 03:23, Weijie Gao wrote: > Hi Marek, > > Yes. MT7621 does need such a proprietary binary for DDR > initialization > and calibration. That's why I submit only the ram- > bootable part > here. > > I'm considering to create a preloader to load and run DDR > init&calib > binary and ram-bootable u-boot image. The ram-bootable u- > boot > image > can be appended to the proloader to form the flash- > bootable > bootloader. > > The source code of preloader will be uploaded to > github.
Just to be sure: You are not implementing this preloader as an U- Boot SPL loader, as this would conflict with U-Boot's GPL compatibility?
Yes. Submitting the source code of this binary also violates MTK's non- disclosure agreement.
Isn't it possible to submit the DDR training code in binary version, and somehow call into it from SPL?
It's possible and I've already implemented it. But will u-boot accept binary file?
U-Boot at least accepts drivers that require proprietary firmware to load (bnxt driver, for example).
I don't know whether a binary firmware can be accepted into the U- Boot repository, whether in a separate file or as an u8 array in a .c file, but it should at least be possible to make it so that the user can compile it thsemsevles to be bundled, i.e. create a Kconfig option that configures a path to the firmware. If it is present, it will be compiled with DDR training bundled.
Stefan, Tom, can this be done?
BTW, Weijie, can I already test this on mt7621 board, also with DDR training? Can you send me the patch that adds calling the proprietary code?
At the high level, I would make a further disappointed sigh and note the NXP ddr firmware blobs, the binary blobs we pull in for x86, and all of the other blobs we bring in today via binman. Please make use of one of these otherwise existing mechanics to bring in the required DDR blobs here.
At lease there are ways to achieve this. Thanks for the note.
participants (5)
-
Marek Behún
-
Ramon Fried
-
Stefan Roese
-
Tom Rini
-
Weijie Gao