aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS20
-rw-r--r--Makefile22
-rw-r--r--arch/arm/Kconfig16
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/dts/Makefile7
-rw-r--r--arch/arm/dts/meson-axg-s400.dts554
-rw-r--r--arch/arm/dts/meson-axg.dtsi1589
-rw-r--r--arch/arm/dts/mt7623.dtsi255
-rw-r--r--arch/arm/dts/mt7623n-bananapi-bpi-r2.dts207
-rw-r--r--arch/arm/dts/mt7629-rfb-u-boot.dtsi24
-rw-r--r--arch/arm/dts/mt7629-rfb.dts70
-rw-r--r--arch/arm/dts/mt7629.dtsi244
-rw-r--r--arch/arm/include/asm/arch-mediatek/gpio.h9
-rw-r--r--arch/arm/include/asm/arch-mediatek/misc.h17
-rw-r--r--arch/arm/include/asm/arch-meson/axg.h52
-rw-r--r--arch/arm/include/asm/arch-meson/boot.h20
-rw-r--r--arch/arm/include/asm/arch-meson/clock-axg.h104
-rw-r--r--arch/arm/include/asm/arch-meson/clock-gx.h (renamed from arch/arm/include/asm/arch-meson/clock.h)4
-rw-r--r--arch/arm/include/asm/arch-meson/eth.h6
-rw-r--r--arch/arm/include/asm/arch-meson/gx.h1
-rw-r--r--arch/arm/include/asm/arch-meson/mem.h3
-rw-r--r--arch/arm/mach-mediatek/Kconfig39
-rw-r--r--arch/arm/mach-mediatek/Makefile7
-rw-r--r--arch/arm/mach-mediatek/cpu.c34
-rw-r--r--arch/arm/mach-mediatek/init.h11
-rw-r--r--arch/arm/mach-mediatek/mt7623/Makefile4
-rw-r--r--arch/arm/mach-mediatek/mt7623/init.c54
-rw-r--r--arch/arm/mach-mediatek/mt7623/lowlevel_init.S22
-rw-r--r--arch/arm/mach-mediatek/mt7623/preloader.h99
-rw-r--r--arch/arm/mach-mediatek/mt7629/Makefile4
-rw-r--r--arch/arm/mach-mediatek/mt7629/init.c128
-rw-r--r--arch/arm/mach-mediatek/mt7629/lowlevel_init.S50
-rw-r--r--arch/arm/mach-mediatek/spl.c43
-rw-r--r--arch/arm/mach-meson/Kconfig132
-rw-r--r--arch/arm/mach-meson/Makefile4
-rw-r--r--arch/arm/mach-meson/board-axg.c118
-rw-r--r--arch/arm/mach-meson/board-common.c117
-rw-r--r--arch/arm/mach-meson/board-gx.c (renamed from arch/arm/mach-meson/board.c)106
-rw-r--r--arch/arm/mach-meson/eth.c53
-rw-r--r--arch/arm/mach-meson/sm.c1
-rw-r--r--board/amlogic/khadas-vim/Kconfig12
-rw-r--r--board/amlogic/khadas-vim/MAINTAINERS6
-rw-r--r--board/amlogic/khadas-vim/khadas-vim.c57
-rw-r--r--board/amlogic/khadas-vim2/Kconfig12
-rw-r--r--board/amlogic/libretech-cc/Kconfig12
-rw-r--r--board/amlogic/libretech-cc/MAINTAINERS6
-rw-r--r--board/amlogic/libretech-cc/Makefile6
-rw-r--r--board/amlogic/libretech-cc/libretech-cc.c57
-rw-r--r--board/amlogic/nanopi-k2/Kconfig12
-rw-r--r--board/amlogic/nanopi-k2/MAINTAINERS6
-rw-r--r--board/amlogic/nanopi-k2/Makefile7
-rw-r--r--board/amlogic/nanopi-k2/nanopi-k2.c55
-rw-r--r--board/amlogic/odroid-c2/Kconfig12
-rw-r--r--board/amlogic/odroid-c2/MAINTAINERS2
-rw-r--r--board/amlogic/odroid-c2/README.nanopi-k2 (renamed from board/amlogic/nanopi-k2/README)0
-rw-r--r--board/amlogic/odroid-c2/README.odroid-c2 (renamed from board/amlogic/odroid-c2/README)0
-rw-r--r--board/amlogic/odroid-c2/odroid-c2.c16
-rw-r--r--board/amlogic/p212/Kconfig12
-rw-r--r--board/amlogic/p212/MAINTAINERS2
-rw-r--r--board/amlogic/p212/README.khadas-vim (renamed from board/amlogic/khadas-vim/README)0
-rw-r--r--board/amlogic/p212/README.libretech-cc (renamed from board/amlogic/libretech-cc/README)0
-rw-r--r--board/amlogic/p212/README.p212 (renamed from board/amlogic/p212/README)0
-rw-r--r--board/amlogic/p212/p212.c16
-rw-r--r--board/amlogic/q200/MAINTAINERS (renamed from board/amlogic/khadas-vim2/MAINTAINERS)6
-rw-r--r--board/amlogic/q200/Makefile (renamed from board/amlogic/khadas-vim/Makefile)2
-rw-r--r--board/amlogic/q200/README.khadas-vim2 (renamed from board/amlogic/khadas-vim2/README)0
-rw-r--r--board/amlogic/q200/README.q200102
-rw-r--r--board/amlogic/q200/q200.c (renamed from board/amlogic/khadas-vim2/khadas-vim2.c)14
-rw-r--r--board/amlogic/s400/MAINTAINERS6
-rw-r--r--board/amlogic/s400/Makefile (renamed from board/amlogic/khadas-vim2/Makefile)2
-rw-r--r--board/amlogic/s400/README110
-rw-r--r--board/amlogic/s400/s400.c21
-rw-r--r--board/mediatek/mt7623/Kconfig13
-rw-r--r--board/mediatek/mt7623/MAINTAINERS7
-rw-r--r--board/mediatek/mt7623/Makefile3
-rw-r--r--board/mediatek/mt7623/mt7623_rfb.c16
-rw-r--r--board/mediatek/mt7629/Kconfig17
-rw-r--r--board/mediatek/mt7629/MAINTAINERS7
-rw-r--r--board/mediatek/mt7629/Makefile3
-rw-r--r--board/mediatek/mt7629/mt7629_rfb.c16
-rw-r--r--common/image.c1
-rw-r--r--configs/khadas-vim2_defconfig1
-rw-r--r--configs/khadas-vim_defconfig1
-rw-r--r--configs/libretech-cc_defconfig1
-rw-r--r--configs/mt7623n_bpir2_defconfig54
-rw-r--r--configs/mt7629_rfb_defconfig73
-rw-r--r--configs/nanopi-k2_defconfig2
-rw-r--r--configs/odroid-c2_defconfig1
-rw-r--r--configs/p212_defconfig1
-rw-r--r--configs/s400_defconfig38
-rw-r--r--doc/README.mediatek221
-rw-r--r--drivers/clk/Makefile3
-rw-r--r--drivers/clk/clk_meson.c6
-rw-r--r--drivers/clk/clk_meson_axg.c316
-rw-r--r--drivers/clk/mediatek/Makefile7
-rw-r--r--drivers/clk/mediatek/clk-mt7623.c870
-rw-r--r--drivers/clk/mediatek/clk-mt7629.c709
-rw-r--r--drivers/clk/mediatek/clk-mtk.c493
-rw-r--r--drivers/clk/mediatek/clk-mtk.h194
-rw-r--r--drivers/mmc/Kconfig11
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/meson_gx_mmc.c1
-rw-r--r--drivers/mmc/mtk-sd.c1394
-rw-r--r--drivers/net/designware.c2
-rw-r--r--drivers/pinctrl/Kconfig1
-rw-r--r--drivers/pinctrl/Makefile1
-rw-r--r--drivers/pinctrl/mediatek/Kconfig15
-rw-r--r--drivers/pinctrl/mediatek/Makefile7
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt7623.c1284
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt7629.c409
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common.c553
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common.h184
-rw-r--r--drivers/pinctrl/meson/Kconfig18
-rw-r--r--drivers/pinctrl/meson/Makefile3
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c125
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson-axg.c979
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson-axg.h66
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c97
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson-gx.h48
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson-gxbb.c6
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson-gxl.c6
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson.c109
-rw-r--r--drivers/pinctrl/meson/pinctrl-meson.h37
-rw-r--r--drivers/power/domain/Kconfig7
-rw-r--r--drivers/power/domain/Makefile1
-rw-r--r--drivers/power/domain/mtk-power-domain.c406
-rw-r--r--drivers/ram/Makefile1
-rw-r--r--drivers/ram/mediatek/Makefile7
-rw-r--r--drivers/ram/mediatek/ddr3-mt7629.c766
-rw-r--r--drivers/serial/Kconfig20
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/serial_mtk.c268
-rw-r--r--drivers/timer/Kconfig7
-rw-r--r--drivers/timer/Makefile1
-rw-r--r--drivers/timer/mtk_timer.c85
-rw-r--r--drivers/watchdog/Kconfig8
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/mtk_wdt.c135
-rw-r--r--include/configs/khadas-vim.h16
-rw-r--r--include/configs/khadas-vim2.h18
-rw-r--r--include/configs/libretech-cc.h16
-rw-r--r--include/configs/meson64.h (renamed from include/configs/meson-gx-common.h)49
-rw-r--r--include/configs/mt7623.h56
-rw-r--r--include/configs/mt7629.h57
-rw-r--r--include/configs/nanopi-k2.h16
-rw-r--r--include/configs/odroid-c2.h16
-rw-r--r--include/configs/p212.h18
-rw-r--r--include/dt-bindings/clock/axg-aoclkc.h26
-rw-r--r--include/dt-bindings/clock/axg-audio-clkc.h94
-rw-r--r--include/dt-bindings/clock/axg-clkc.h76
-rw-r--r--include/dt-bindings/clock/mt7623-clk.h413
-rw-r--r--include/dt-bindings/clock/mt7629-clk.h206
-rw-r--r--include/dt-bindings/gpio/meson-axg-gpio.h116
-rw-r--r--include/dt-bindings/power/mt7623-power.h19
-rw-r--r--include/dt-bindings/power/mt7629-power.h13
-rw-r--r--include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h17
-rw-r--r--include/dt-bindings/reset/amlogic,meson-axg-reset.h124
-rw-r--r--include/dt-bindings/reset/axg-aoclkc.h20
-rw-r--r--include/image.h1
-rw-r--r--scripts/Makefile.spl11
-rw-r--r--tools/Makefile1
-rw-r--r--tools/mtk_image.c749
-rw-r--r--tools/mtk_image.h199
163 files changed, 16560 insertions, 754 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index abdb6dc..214629e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -158,6 +158,26 @@ T: git git://git.denx.de/u-boot-pxa.git
F: arch/arm/cpu/pxa/
F: arch/arm/include/asm/arch-pxa/
+ARM MEDIATEK
+M: Ryder Lee <ryder.lee@mediatek.com>
+M: Weijie Gao <weijie.gao@mediatek.com>
+S: Maintained
+F: arch/arm/mach-mediatek/
+F: arch/arm/include/asm/arch-mediatek/
+F: board/mediatek/
+F: doc/README.mediatek
+F: drivers/clk/mediatek/
+F: drivers/mmc/mtk-sd.c
+F: drivers/pinctrl/mediatek/
+F: drivers/power/domain/mtk-power-domain.c
+F: drivers/ram/mediatek/
+F: drivers/spi/mtk_qspi.c
+F: drivers/timer/mtk_timer.c
+F: drivers/watchdog/mtk_wdt.c
+F: tools/mtk_image.c
+F: tools/mtk_image.h
+N: mediatek
+
ARM OWL
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
S: Maintained
diff --git a/Makefile b/Makefile
index aeb1c14..a4b1d1d 100644
--- a/Makefile
+++ b/Makefile
@@ -852,6 +852,8 @@ ALL-y += u-boot-tegra.bin u-boot-nodtb-tegra.bin
ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb-tegra.bin
endif
+ALL-$(CONFIG_ARCH_MEDIATEK) += u-boot-mtk.bin
+
# Add optional build target if defined in board/cpu/soc headers
ifneq ($(CONFIG_BUILD_TARGET),)
ALL-y += $(CONFIG_BUILD_TARGET:"%"=%)
@@ -1361,6 +1363,26 @@ u-boot.elf: u-boot.bin
$(Q)$(OBJCOPY) -I binary $(PLATFORM_ELFFLAGS) $< u-boot-elf.o
$(call if_changed,u-boot-elf)
+# MediaTek's ARM-based u-boot needs a header to contains its load address
+# which is parsed by the BootROM.
+# If the SPL build is enabled, the header will be added to the spl binary,
+# and the spl binary and the u-boot.img will be combined into one file.
+# Otherwise the header will be added to the u-boot.bin directly.
+
+ifeq ($(CONFIG_SPL),y)
+spl/u-boot-spl-mtk.bin: spl/u-boot-spl
+
+u-boot-mtk.bin: u-boot.dtb u-boot.img spl/u-boot-spl-mtk.bin FORCE
+ $(call if_changed,binman)
+else
+MKIMAGEFLAGS_u-boot-mtk.bin = -T mtk_image \
+ -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
+ -n "$(patsubst "%",%,$(CONFIG_MTK_BROM_HEADER_INFO))"
+
+u-boot-mtk.bin: u-boot.bin FORCE
+ $(call if_changed,mkimage)
+endif
+
ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink)
# Rule to link u-boot
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index f5d4d39..96eadb6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -664,6 +664,20 @@ config ARCH_MESON
targeted at media players and tablet computers. We currently
support the S905 (GXBaby) 64-bit SoC.
+config ARCH_MEDIATEK
+ bool "MediaTek SoCs"
+ select BINMAN
+ select DM
+ select OF_CONTROL
+ select SPL_DM if SPL
+ select SPL_LIBCOMMON_SUPPORT if SPL
+ select SPL_LIBGENERIC_SUPPORT if SPL
+ select SPL_OF_CONTROL if SPL
+ select SUPPORT_SPL
+ help
+ Support for the MediaTek SoCs family developed by MediaTek Inc.
+ Please refer to doc/README.mediatek for more information.
+
config ARCH_LPC32XX
bool "NXP LPC32xx platform"
select CPU_ARM926EJS
@@ -1449,6 +1463,8 @@ source "arch/arm/mach-rmobile/Kconfig"
source "arch/arm/mach-meson/Kconfig"
+source "arch/arm/mach-mediatek/Kconfig"
+
source "arch/arm/mach-qemu/Kconfig"
source "arch/arm/mach-rockchip/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 4b6c5e1..c38ef3c 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -62,6 +62,7 @@ machine-$(CONFIG_ARCH_K3) += k3
machine-$(CONFIG_ARCH_KEYSTONE) += keystone
# TODO: rename CONFIG_KIRKWOOD -> CONFIG_ARCH_KIRKWOOD
machine-$(CONFIG_KIRKWOOD) += kirkwood
+machine-$(CONFIG_ARCH_MEDIATEK) += mediatek
machine-$(CONFIG_ARCH_MESON) += meson
machine-$(CONFIG_ARCH_MVEBU) += mvebu
# TODO: rename CONFIG_TEGRA -> CONFIG_ARCH_TEGRA
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 55f3fd1..d8be3a3 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -59,7 +59,8 @@ dtb-$(CONFIG_ARCH_MESON) += \
meson-gxl-s905x-p212.dtb \
meson-gxl-s905x-libretech-cc.dtb \
meson-gxl-s905x-khadas-vim.dtb \
- meson-gxm-khadas-vim2.dtb
+ meson-gxm-khadas-vim2.dtb \
+ meson-axg-s400.dtb
dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
tegra20-medcom-wide.dtb \
tegra20-paz00.dtb \
@@ -563,6 +564,10 @@ dtb-$(CONFIG_TARGET_STM32MP1) += \
dtb-$(CONFIG_SOC_K3_AM6) += k3-am654-base-board.dtb k3-am654-r5-base-board.dtb
+dtb-$(CONFIG_ARCH_MEDIATEK) += \
+ mt7623n-bananapi-bpi-r2.dtb \
+ mt7629-rfb.dtb
+
targets += $(dtb-y)
# Add any required device tree compiler flags here
diff --git a/arch/arm/dts/meson-axg-s400.dts b/arch/arm/dts/meson-axg-s400.dts
new file mode 100644
index 0000000..18778ad
--- /dev/null
+++ b/arch/arm/dts/meson-axg-s400.dts
@@ -0,0 +1,554 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-axg.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+ compatible = "amlogic,s400", "amlogic,a113d", "amlogic,meson-axg";
+ model = "Amlogic Meson AXG S400 Development Board";
+
+ adc_keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 0>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1800000>;
+
+ button-next {
+ label = "Next";
+ linux,code = <KEY_NEXT>;
+ press-threshold-microvolt = <1116000>; /* 62% */
+ };
+
+ button-prev {
+ label = "Previous";
+ linux,code = <KEY_PREVIOUS>;
+ press-threshold-microvolt = <900000>; /* 50% */
+ };
+
+ button-wifi {
+ label = "Wifi";
+ linux,code = <KEY_WLAN>;
+ press-threshold-microvolt = <684000>; /* 38% */
+ };
+
+ button-up {
+ label = "Volume Up";
+ linux,code = <KEY_VOLUMEUP>;
+ press-threshold-microvolt = <468000>; /* 26% */
+ };
+
+ button-down {
+ label = "Volume Down";
+ linux,code = <KEY_VOLUMEDOWN>;
+ press-threshold-microvolt = <252000>; /* 14% */
+ };
+
+ button-voice {
+ label = "Voice";
+ linux,code = <KEY_VOICECOMMAND>;
+ press-threshold-microvolt = <0>; /* 0% */
+ };
+ };
+
+ aliases {
+ serial0 = &uart_AO;
+ serial1 = &uart_A;
+ };
+
+ linein: audio-codec@0 {
+ #sound-dai-cells = <0>;
+ compatible = "everest,es7241";
+ VDDA-supply = <&vcc_3v3>;
+ VDDP-supply = <&vcc_3v3>;
+ VDDD-supply = <&vcc_3v3>;
+ status = "okay";
+ sound-name-prefix = "Linein";
+ };
+
+ lineout: audio-codec@1 {
+ #sound-dai-cells = <0>;
+ compatible = "everest,es7154";
+ VDD-supply = <&vcc_3v3>;
+ PVDD-supply = <&vcc_5v>;
+ status = "okay";
+ sound-name-prefix = "Lineout";
+ };
+
+ spdif_dit: audio-codec@2 {
+ #sound-dai-cells = <0>;
+ compatible = "linux,spdif-dit";
+ status = "okay";
+ sound-name-prefix = "DIT";
+ };
+
+ dmics: audio-codec@3 {
+ #sound-dai-cells = <0>;
+ compatible = "dmic-codec";
+ num-channels = <7>;
+ wakeup-delay-ms = <50>;
+ status = "okay";
+ sound-name-prefix = "MIC";
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ main_12v: regulator-main_12v {
+ compatible = "regulator-fixed";
+ regulator-name = "12V";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ regulator-always-on;
+ };
+
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ };
+
+ vcc_5v: regulator-vcc_5v {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&main_12v>;
+
+ gpio = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vddao_3v3: regulator-vddao_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDAO_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&main_12v>;
+ regulator-always-on;
+ };
+
+ vddio_ao18: regulator-vddio_ao18 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_AO18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ };
+
+ vddio_boot: regulator-vddio_boot {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_BOOT";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vddao_3v3>;
+ regulator-always-on;
+ };
+
+ usb_pwr: regulator-usb_pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "USB_PWR";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_5v>;
+
+ gpio = <&gpio_ao GPIOAO_5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_7 GPIO_ACTIVE_LOW>;
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
+
+ speaker-leds {
+ compatible = "gpio-leds";
+
+ aled1 {
+ label = "speaker:aled1";
+ gpios = <&gpio_speaker 7 0>;
+ };
+
+ aled2 {
+ label = "speaker:aled2";
+ gpios = <&gpio_speaker 6 0>;
+ };
+
+ aled3 {
+ label = "speaker:aled3";
+ gpios = <&gpio_speaker 5 0>;
+ };
+
+ aled4 {
+ label = "speaker:aled4";
+ gpios = <&gpio_speaker 4 0>;
+ };
+
+ aled5 {
+ label = "speaker:aled5";
+ gpios = <&gpio_speaker 3 0>;
+ };
+
+ aled6 {
+ label = "speaker:aled6";
+ gpios = <&gpio_speaker 2 0>;
+ };
+ };
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "AXG-S400";
+ audio-aux-devs = <&tdmin_a>, <&tdmin_b>, <&tdmin_c>,
+ <&tdmin_lb>, <&tdmout_c>;
+ audio-widgets = "Line", "Lineout",
+ "Line", "Linein",
+ "Speaker", "Speaker1 Left",
+ "Speaker", "Speaker1 Right";
+ audio-routing = "TDMOUT_C IN 0", "FRDDR_A OUT 2",
+ "SPDIFOUT IN 0", "FRDDR_A OUT 3",
+ "TDMOUT_C IN 1", "FRDDR_B OUT 2",
+ "SPDIFOUT IN 1", "FRDDR_B OUT 3",
+ "TDMOUT_C IN 2", "FRDDR_C OUT 2",
+ "SPDIFOUT IN 2", "FRDDR_C OUT 3",
+ "TDM_C Playback", "TDMOUT_C OUT",
+ "TDMIN_A IN 2", "TDM_C Capture",
+ "TDMIN_A IN 5", "TDM_C Loopback",
+ "TDMIN_B IN 2", "TDM_C Capture",
+ "TDMIN_B IN 5", "TDM_C Loopback",
+ "TDMIN_C IN 2", "TDM_C Capture",
+ "TDMIN_C IN 5", "TDM_C Loopback",
+ "TDMIN_LB IN 2", "TDM_C Loopback",
+ "TDMIN_LB IN 5", "TDM_C Capture",
+ "TODDR_A IN 0", "TDMIN_A OUT",
+ "TODDR_B IN 0", "TDMIN_A OUT",
+ "TODDR_C IN 0", "TDMIN_A OUT",
+ "TODDR_A IN 1", "TDMIN_B OUT",
+ "TODDR_B IN 1", "TDMIN_B OUT",
+ "TODDR_C IN 1", "TDMIN_B OUT",
+ "TODDR_A IN 2", "TDMIN_C OUT",
+ "TODDR_B IN 2", "TDMIN_C OUT",
+ "TODDR_C IN 2", "TDMIN_C OUT",
+ "TODDR_A IN 4", "PDM Capture",
+ "TODDR_B IN 4", "PDM Capture",
+ "TODDR_C IN 4", "PDM Capture",
+ "TODDR_A IN 6", "TDMIN_LB OUT",
+ "TODDR_B IN 6", "TDMIN_LB OUT",
+ "TODDR_C IN 6", "TDMIN_LB OUT",
+ "Lineout", "Lineout AOUTL",
+ "Lineout", "Lineout AOUTR",
+ "Speaker1 Left", "SPK1 OUT_A",
+ "Speaker1 Left", "SPK1 OUT_B",
+ "Speaker1 Right", "SPK1 OUT_C",
+ "Speaker1 Right", "SPK1 OUT_D",
+ "Linein AINL", "Linein",
+ "Linein AINR", "Linein";
+ assigned-clocks = <&clkc CLKID_HIFI_PLL>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <589824000>,
+ <270950400>,
+ <393216000>;
+ status = "okay";
+
+ dai-link@0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link@1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link@2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ dai-link@3 {
+ sound-dai = <&toddr_a>;
+ };
+
+ dai-link@4 {
+ sound-dai = <&toddr_b>;
+ };
+
+ dai-link@5 {
+ sound-dai = <&toddr_c>;
+ };
+
+ dai-link@6 {
+ sound-dai = <&tdmif_c>;
+ dai-format = "i2s";
+ dai-tdm-slot-tx-mask-2 = <1 1>;
+ dai-tdm-slot-rx-mask-1 = <1 1>;
+ mclk-fs = <256>;
+
+ codec@0 {
+ sound-dai = <&lineout>;
+ };
+
+ codec@1 {
+ sound-dai = <&speaker_amp1>;
+ };
+
+ codec@2 {
+ sound-dai = <&linein>;
+ };
+
+ };
+
+ dai-link@7 {
+ sound-dai = <&spdifout>;
+
+ codec {
+ sound-dai = <&spdif_dit>;
+ };
+ };
+
+ dai-link@8 {
+ sound-dai = <&pdm>;
+
+ codec {
+ sound-dai = <&dmics>;
+ };
+ };
+ };
+
+ wifi32k: wifi32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ab 0 30518 0>; /* PWM_A at 32.768KHz */
+ };
+};
+
+&ethmac {
+ status = "okay";
+ pinctrl-0 = <&eth_rgmii_y_pins>;
+ pinctrl-names = "default";
+ phy-handle = <&eth_phy0>;
+ phy-mode = "rgmii";
+
+ mdio {
+ compatible = "snps,dwmac-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ eth_phy0: ethernet-phy@0 {
+ /* Realtek RTL8211F (0x001cc916) */
+ reg = <0>;
+ eee-broken-1000t;
+ };
+ };
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+};
+
+&i2c1 {
+ status = "okay";
+ pinctrl-0 = <&i2c1_z_pins>;
+ pinctrl-names = "default";
+
+ speaker_amp1: audio-codec@1b {
+ compatible = "ti,tas5707";
+ reg = <0x1b>;
+ reset-gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>;
+ #sound-dai-cells = <0>;
+ AVDD-supply = <&vcc_3v3>;
+ DVDD-supply = <&vcc_3v3>;
+ PVDD_A-supply = <&main_12v>;
+ PVDD_B-supply = <&main_12v>;
+ PVDD_C-supply = <&main_12v>;
+ PVDD_D-supply = <&main_12v>;
+ sound-name-prefix = "SPK1";
+ };
+};
+
+&i2c_AO {
+ status = "okay";
+ pinctrl-0 = <&i2c_ao_sck_10_pins>, <&i2c_ao_sda_11_pins>;
+ pinctrl-names = "default";
+
+ gpio_speaker: gpio-controller@1f {
+ compatible = "nxp,pca9557";
+ reg = <0x1f>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ vcc-supply = <&vddao_3v3>;
+ };
+};
+
+&pdm {
+ pinctrl-0 = <&pdm_dclk_a14_pins>, <&pdm_din0_pins>,
+ <&pdm_din1_pins>, <&pdm_din2_pins>, <&pdm_din3_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&pwm_ab {
+ status = "okay";
+ pinctrl-0 = <&pwm_a_x20_pins>;
+ pinctrl-names = "default";
+};
+
+&saradc {
+ status = "okay";
+ vref-supply = <&vddio_ao18>;
+};
+
+/* wifi module */
+&sd_emmc_b {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <100000000>;
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&sdio_pwrseq>;
+
+ vmmc-supply = <&vddao_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+
+ brcmf: wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+/* emmc storage */
+&sd_emmc_c {
+ status = "disabled";
+ pinctrl-0 = <&emmc_pins>;
+ pinctrl-1 = <&emmc_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <8>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <180000000>;
+ non-removable;
+ disable-wp;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&vddio_boot>;
+};
+
+&spdifout {
+ pinctrl-0 = <&spdif_out_a20_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&tdmif_a {
+ pinctrl-0 = <&tdma_sclk_pins>, <&tdma_fs_pins>,
+ <&tdma_din0_pins>, <&tdma_dout0_x15_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&tdmif_b {
+ pinctrl-0 = <&tdmb_sclk_pins>, <&tdmb_fs_pins>,
+ <&tdmb_din3_pins>, <&mclk_b_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&tdmif_c {
+ pinctrl-0 = <&tdmc_sclk_pins>, <&tdmc_fs_pins>,
+ <&tdmc_din1_pins>, <&tdmc_dout2_pins>,
+ <&mclk_c_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&tdmin_a {
+ status = "okay";
+};
+
+&tdmin_b {
+ status = "okay";
+};
+
+&tdmin_c {
+ status = "okay";
+};
+
+&tdmin_lb {
+ status = "okay";
+};
+
+&tdmout_c {
+ status = "okay";
+};
+
+&toddr_a {
+ status = "okay";
+};
+
+&toddr_b {
+ status = "okay";
+};
+
+&toddr_c {
+ status = "okay";
+};
+
+&uart_A {
+ status = "okay";
+ pinctrl-0 = <&uart_a_pins>;
+ pinctrl-names = "default";
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
diff --git a/arch/arm/dts/meson-axg.dtsi b/arch/arm/dts/meson-axg.dtsi
new file mode 100644
index 0000000..df017db
--- /dev/null
+++ b/arch/arm/dts/meson-axg.dtsi
@@ -0,0 +1,1589 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/clock/axg-aoclkc.h>
+#include <dt-bindings/clock/axg-audio-clkc.h>
+#include <dt-bindings/clock/axg-clkc.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/meson-axg-gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
+#include <dt-bindings/reset/amlogic,meson-axg-reset.h>
+
+/ {
+ compatible = "amlogic,meson-axg";
+
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ tdmif_a: audio-controller@0 {
+ compatible = "amlogic,axg-tdm-iface";
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "TDM_A";
+ clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
+ <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
+ clock-names = "mclk", "sclk", "lrclk";
+ status = "disabled";
+ };
+
+ tdmif_b: audio-controller@1 {
+ compatible = "amlogic,axg-tdm-iface";
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "TDM_B";
+ clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
+ clock-names = "mclk", "sclk", "lrclk";
+ status = "disabled";
+ };
+
+ tdmif_c: audio-controller@2 {
+ compatible = "amlogic,axg-tdm-iface";
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "TDM_C";
+ clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
+ <&clkc_audio AUD_CLKID_MST_C_SCLK>,
+ <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
+ clock-names = "mclk", "sclk", "lrclk";
+ status = "disabled";
+ };
+
+ ao_alt_xtal: ao_alt_xtal-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <32000000>;
+ clock-output-names = "ao_alt_xtal";
+ #clock-cells = <0>;
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a53-pmu";
+ interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+ };
+
+ cpus {
+ #address-cells = <0x2>;
+ #size-cells = <0x0>;
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a53", "arm,armv8";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ l2: l2-cache0 {
+ compatible = "cache";
+ };
+ };
+
+ psci {
+ compatible = "arm,psci-1.0";
+ method = "smc";
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /* 16 MiB reserved for Hardware ROM Firmware */
+ hwrom_reserved: hwrom@0 {
+ reg = <0x0 0x0 0x0 0x1000000>;
+ no-map;
+ };
+
+ /* Alternate 3 MiB reserved for ARM Trusted Firmware (BL31) */
+ secmon_reserved: secmon@5000000 {
+ reg = <0x0 0x05000000 0x0 0x300000>;
+ no-map;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ ethmac: ethernet@ff3f0000 {
+ compatible = "amlogic,meson-axg-dwmac", "snps,dwmac";
+ reg = <0x0 0xff3f0000 0x0 0x10000
+ 0x0 0xff634540 0x0 0x8>;
+ interrupts = <GIC_SPI 8 IRQ_TYPE_EDGE_RISING>;
+ interrupt-names = "macirq";
+ clocks = <&clkc CLKID_ETH>,
+ <&clkc CLKID_FCLK_DIV2>,
+ <&clkc CLKID_MPLL2>;
+ clock-names = "stmmaceth", "clkin0", "clkin1";
+ status = "disabled";
+ };
+
+ pdm: audio-controller@ff632000 {
+ compatible = "amlogic,axg-pdm";
+ reg = <0x0 0xff632000 0x0 0x34>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "PDM";
+ clocks = <&clkc_audio AUD_CLKID_PDM>,
+ <&clkc_audio AUD_CLKID_PDM_DCLK>,
+ <&clkc_audio AUD_CLKID_PDM_SYSCLK>;
+ clock-names = "pclk", "dclk", "sysclk";
+ status = "disabled";
+ };
+
+ periphs: bus@ff634000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xff634000 0x0 0x2000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xff634000 0x0 0x2000>;
+
+ hwrng: rng@18 {
+ compatible = "amlogic,meson-rng";
+ reg = <0x0 0x18 0x0 0x4>;
+ clocks = <&clkc CLKID_RNG0>;
+ clock-names = "core";
+ };
+
+ pinctrl_periphs: pinctrl@480 {
+ compatible = "amlogic,meson-axg-periphs-pinctrl";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio: bank@480 {
+ reg = <0x0 0x00480 0x0 0x40>,
+ <0x0 0x004e8 0x0 0x14>,
+ <0x0 0x00520 0x0 0x14>,
+ <0x0 0x00430 0x0 0x3c>;
+ reg-names = "mux", "pull", "pull-enable", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_periphs 0 0 86>;
+ };
+
+ i2c0_pins: i2c0 {
+ mux {
+ groups = "i2c0_sck",
+ "i2c0_sda";
+ function = "i2c0";
+ };
+ };
+
+ i2c1_x_pins: i2c1_x {
+ mux {
+ groups = "i2c1_sck_x",
+ "i2c1_sda_x";
+ function = "i2c1";
+ };
+ };
+
+ i2c1_z_pins: i2c1_z {
+ mux {
+ groups = "i2c1_sck_z",
+ "i2c1_sda_z";
+ function = "i2c1";
+ };
+ };
+
+ i2c2_a_pins: i2c2_a {
+ mux {
+ groups = "i2c2_sck_a",
+ "i2c2_sda_a";
+ function = "i2c2";
+ };
+ };
+
+ i2c2_x_pins: i2c2_x {
+ mux {
+ groups = "i2c2_sck_x",
+ "i2c2_sda_x";
+ function = "i2c2";
+ };
+ };
+
+ i2c3_a6_pins: i2c3_a6 {
+ mux {
+ groups = "i2c3_sda_a6",
+ "i2c3_sck_a7";
+ function = "i2c3";
+ };
+ };
+
+ i2c3_a12_pins: i2c3_a12 {
+ mux {
+ groups = "i2c3_sda_a12",
+ "i2c3_sck_a13";
+ function = "i2c3";
+ };
+ };
+
+ i2c3_a19_pins: i2c3_a19 {
+ mux {
+ groups = "i2c3_sda_a19",
+ "i2c3_sck_a20";
+ function = "i2c3";
+ };
+ };
+
+ emmc_pins: emmc {
+ mux {
+ groups = "emmc_nand_d0",
+ "emmc_nand_d1",
+ "emmc_nand_d2",
+ "emmc_nand_d3",
+ "emmc_nand_d4",
+ "emmc_nand_d5",
+ "emmc_nand_d6",
+ "emmc_nand_d7",
+ "emmc_clk",
+ "emmc_cmd",
+ "emmc_ds";
+ function = "emmc";
+ };
+ };
+
+ emmc_clk_gate_pins: emmc_clk_gate {
+ mux {
+ groups = "BOOT_8";
+ function = "gpio_periphs";
+ };
+ cfg-pull-down {
+ pins = "BOOT_8";
+ bias-pull-down;
+ };
+ };
+
+ eth_rgmii_x_pins: eth-x-rgmii {
+ mux {
+ groups = "eth_mdio_x",
+ "eth_mdc_x",
+ "eth_rgmii_rx_clk_x",
+ "eth_rx_dv_x",
+ "eth_rxd0_x",
+ "eth_rxd1_x",
+ "eth_rxd2_rgmii",
+ "eth_rxd3_rgmii",
+ "eth_rgmii_tx_clk",
+ "eth_txen_x",
+ "eth_txd0_x",
+ "eth_txd1_x",
+ "eth_txd2_rgmii",
+ "eth_txd3_rgmii";
+ function = "eth";
+ };
+ };
+
+ eth_rgmii_y_pins: eth-y-rgmii {
+ mux {
+ groups = "eth_mdio_y",
+ "eth_mdc_y",
+ "eth_rgmii_rx_clk_y",
+ "eth_rx_dv_y",
+ "eth_rxd0_y",
+ "eth_rxd1_y",
+ "eth_rxd2_rgmii",
+ "eth_rxd3_rgmii",
+ "eth_rgmii_tx_clk",
+ "eth_txen_y",
+ "eth_txd0_y",
+ "eth_txd1_y",
+ "eth_txd2_rgmii",
+ "eth_txd3_rgmii";
+ function = "eth";
+ };
+ };
+
+ eth_rmii_x_pins: eth-x-rmii {
+ mux {
+ groups = "eth_mdio_x",
+ "eth_mdc_x",
+ "eth_rgmii_rx_clk_x",
+ "eth_rx_dv_x",
+ "eth_rxd0_x",
+ "eth_rxd1_x",
+ "eth_txen_x",
+ "eth_txd0_x",
+ "eth_txd1_x";
+ function = "eth";
+ };
+ };
+
+ eth_rmii_y_pins: eth-y-rmii {
+ mux {
+ groups = "eth_mdio_y",
+ "eth_mdc_y",
+ "eth_rgmii_rx_clk_y",
+ "eth_rx_dv_y",
+ "eth_rxd0_y",
+ "eth_rxd1_y",
+ "eth_txen_y",
+ "eth_txd0_y",
+ "eth_txd1_y";
+ function = "eth";
+ };
+ };
+
+ mclk_b_pins: mclk_b {
+ mux {
+ groups = "mclk_b";
+ function = "mclk_b";
+ };
+ };
+
+ mclk_c_pins: mclk_c {
+ mux {
+ groups = "mclk_c";
+ function = "mclk_c";
+ };
+ };
+
+ pdm_dclk_a14_pins: pdm_dclk_a14 {
+ mux {
+ groups = "pdm_dclk_a14";
+ function = "pdm";
+ };
+ };
+
+ pdm_dclk_a19_pins: pdm_dclk_a19 {
+ mux {
+ groups = "pdm_dclk_a19";
+ function = "pdm";
+ };
+ };
+
+ pdm_din0_pins: pdm_din0 {
+ mux {
+ groups = "pdm_din0";
+ function = "pdm";
+ };
+ };
+
+ pdm_din1_pins: pdm_din1 {
+ mux {
+ groups = "pdm_din1";
+ function = "pdm";
+ };
+ };
+
+ pdm_din2_pins: pdm_din2 {
+ mux {
+ groups = "pdm_din2";
+ function = "pdm";
+ };
+ };
+
+ pdm_din3_pins: pdm_din3 {
+ mux {
+ groups = "pdm_din3";
+ function = "pdm";
+ };
+ };
+
+ pwm_a_a_pins: pwm_a_a {
+ mux {
+ groups = "pwm_a_a";
+ function = "pwm_a";
+ };
+ };
+
+ pwm_a_x18_pins: pwm_a_x18 {
+ mux {
+ groups = "pwm_a_x18";
+ function = "pwm_a";
+ };
+ };
+
+ pwm_a_x20_pins: pwm_a_x20 {
+ mux {
+ groups = "pwm_a_x20";
+ function = "pwm_a";
+ };
+ };
+
+ pwm_a_z_pins: pwm_a_z {
+ mux {
+ groups = "pwm_a_z";
+ function = "pwm_a";
+ };
+ };
+
+ pwm_b_a_pins: pwm_b_a {
+ mux {
+ groups = "pwm_b_a";
+ function = "pwm_b";
+ };
+ };
+
+ pwm_b_x_pins: pwm_b_x {
+ mux {
+ groups = "pwm_b_x";
+ function = "pwm_b";
+ };
+ };
+
+ pwm_b_z_pins: pwm_b_z {
+ mux {
+ groups = "pwm_b_z";
+ function = "pwm_b";
+ };
+ };
+
+ pwm_c_a_pins: pwm_c_a {
+ mux {
+ groups = "pwm_c_a";
+ function = "pwm_c";
+ };
+ };
+
+ pwm_c_x10_pins: pwm_c_x10 {
+ mux {
+ groups = "pwm_c_x10";
+ function = "pwm_c";
+ };
+ };
+
+ pwm_c_x17_pins: pwm_c_x17 {
+ mux {
+ groups = "pwm_c_x17";
+ function = "pwm_c";
+ };
+ };
+
+ pwm_d_x11_pins: pwm_d_x11 {
+ mux {
+ groups = "pwm_d_x11";
+ function = "pwm_d";
+ };
+ };
+
+ pwm_d_x16_pins: pwm_d_x16 {
+ mux {
+ groups = "pwm_d_x16";
+ function = "pwm_d";
+ };
+ };
+
+ sdio_pins: sdio {
+ mux {
+ groups = "sdio_d0",
+ "sdio_d1",
+ "sdio_d2",
+ "sdio_d3",
+ "sdio_cmd",
+ "sdio_clk";
+ function = "sdio";
+ };
+ };
+
+ sdio_clk_gate_pins: sdio_clk_gate {
+ mux {
+ groups = "GPIOX_4";
+ function = "gpio_periphs";
+ };
+ cfg-pull-down {
+ pins = "GPIOX_4";
+ bias-pull-down;
+ };
+ };
+
+ spdif_in_z_pins: spdif_in_z {
+ mux {
+ groups = "spdif_in_z";
+ function = "spdif_in";
+ };
+ };
+
+ spdif_in_a1_pins: spdif_in_a1 {
+ mux {
+ groups = "spdif_in_a1";
+ function = "spdif_in";
+ };
+ };
+
+ spdif_in_a7_pins: spdif_in_a7 {
+ mux {
+ groups = "spdif_in_a7";
+ function = "spdif_in";
+ };
+ };
+
+ spdif_in_a19_pins: spdif_in_a19 {
+ mux {
+ groups = "spdif_in_a19";
+ function = "spdif_in";
+ };
+ };
+
+ spdif_in_a20_pins: spdif_in_a20 {
+ mux {
+ groups = "spdif_in_a20";
+ function = "spdif_in";
+ };
+ };
+
+ spdif_out_a1_pins: spdif_out_a1 {
+ mux {
+ groups = "spdif_out_a1";
+ function = "spdif_out";
+ };
+ };
+
+ spdif_out_a11_pins: spdif_out_a11 {
+ mux {
+ groups = "spdif_out_a11";
+ function = "spdif_out";
+ };
+ };
+
+ spdif_out_a19_pins: spdif_out_a19 {
+ mux {
+ groups = "spdif_out_a19";
+ function = "spdif_out";
+ };
+ };
+
+ spdif_out_a20_pins: spdif_out_a20 {
+ mux {
+ groups = "spdif_out_a20";
+ function = "spdif_out";
+ };
+ };
+
+ spdif_out_z_pins: spdif_out_z {
+ mux {
+ groups = "spdif_out_z";
+ function = "spdif_out";
+ };
+ };
+
+ spi0_pins: spi0 {
+ mux {
+ groups = "spi0_miso",
+ "spi0_mosi",
+ "spi0_clk";
+ function = "spi0";
+ };
+ };
+
+ spi0_ss0_pins: spi0_ss0 {
+ mux {
+ groups = "spi0_ss0";
+ function = "spi0";
+ };
+ };
+
+ spi0_ss1_pins: spi0_ss1 {
+ mux {
+ groups = "spi0_ss1";
+ function = "spi0";
+ };
+ };
+
+ spi0_ss2_pins: spi0_ss2 {
+ mux {
+ groups = "spi0_ss2";
+ function = "spi0";
+ };
+ };
+
+ spi1_a_pins: spi1_a {
+ mux {
+ groups = "spi1_miso_a",
+ "spi1_mosi_a",
+ "spi1_clk_a";
+ function = "spi1";
+ };
+ };
+
+ spi1_ss0_a_pins: spi1_ss0_a {
+ mux {
+ groups = "spi1_ss0_a";
+ function = "spi1";
+ };
+ };
+
+ spi1_ss1_pins: spi1_ss1 {
+ mux {
+ groups = "spi1_ss1";
+ function = "spi1";
+ };
+ };
+
+ spi1_x_pins: spi1_x {
+ mux {
+ groups = "spi1_miso_x",
+ "spi1_mosi_x",
+ "spi1_clk_x";
+ function = "spi1";
+ };
+ };
+
+ spi1_ss0_x_pins: spi1_ss0_x {
+ mux {
+ groups = "spi1_ss0_x";
+ function = "spi1";
+ };
+ };
+
+ tdma_din0_pins: tdma_din0 {
+ mux {
+ groups = "tdma_din0";
+ function = "tdma";
+ };
+ };
+
+ tdma_dout0_x14_pins: tdma_dout0_x14 {
+ mux {
+ groups = "tdma_dout0_x14";
+ function = "tdma";
+ };
+ };
+
+ tdma_dout0_x15_pins: tdma_dout0_x15 {
+ mux {
+ groups = "tdma_dout0_x15";
+ function = "tdma";
+ };
+ };
+
+ tdma_dout1_pins: tdma_dout1 {
+ mux {
+ groups = "tdma_dout1";
+ function = "tdma";
+ };
+ };
+
+ tdma_din1_pins: tdma_din1 {
+ mux {
+ groups = "tdma_din1";
+ function = "tdma";
+ };
+ };
+
+ tdma_fs_pins: tdma_fs {
+ mux {
+ groups = "tdma_fs";
+ function = "tdma";
+ };
+ };
+
+ tdma_fs_slv_pins: tdma_fs_slv {
+ mux {
+ groups = "tdma_fs_slv";
+ function = "tdma";
+ };
+ };
+
+ tdma_sclk_pins: tdma_sclk {
+ mux {
+ groups = "tdma_sclk";
+ function = "tdma";
+ };
+ };
+
+ tdma_sclk_slv_pins: tdma_sclk_slv {
+ mux {
+ groups = "tdma_sclk_slv";
+ function = "tdma";
+ };
+ };
+
+ tdmb_din0_pins: tdmb_din0 {
+ mux {
+ groups = "tdmb_din0";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_din1_pins: tdmb_din1 {
+ mux {
+ groups = "tdmb_din1";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_din2_pins: tdmb_din2 {
+ mux {
+ groups = "tdmb_din2";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_din3_pins: tdmb_din3 {
+ mux {
+ groups = "tdmb_din3";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_dout0_pins: tdmb_dout0 {
+ mux {
+ groups = "tdmb_dout0";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_dout1_pins: tdmb_dout1 {
+ mux {
+ groups = "tdmb_dout1";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_dout2_pins: tdmb_dout2 {
+ mux {
+ groups = "tdmb_dout2";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_dout3_pins: tdmb_dout3 {
+ mux {
+ groups = "tdmb_dout3";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_fs_pins: tdmb_fs {
+ mux {
+ groups = "tdmb_fs";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_fs_slv_pins: tdmb_fs_slv {
+ mux {
+ groups = "tdmb_fs_slv";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_sclk_pins: tdmb_sclk {
+ mux {
+ groups = "tdmb_sclk";
+ function = "tdmb";
+ };
+ };
+
+ tdmb_sclk_slv_pins: tdmb_sclk_slv {
+ mux {
+ groups = "tdmb_sclk_slv";
+ function = "tdmb";
+ };
+ };
+
+ tdmc_fs_pins: tdmc_fs {
+ mux {
+ groups = "tdmc_fs";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_fs_slv_pins: tdmc_fs_slv {
+ mux {
+ groups = "tdmc_fs_slv";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_sclk_pins: tdmc_sclk {
+ mux {
+ groups = "tdmc_sclk";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_sclk_slv_pins: tdmc_sclk_slv {
+ mux {
+ groups = "tdmc_sclk_slv";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_din0_pins: tdmc_din0 {
+ mux {
+ groups = "tdmc_din0";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_din1_pins: tdmc_din1 {
+ mux {
+ groups = "tdmc_din1";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_din2_pins: tdmc_din2 {
+ mux {
+ groups = "tdmc_din2";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_din3_pins: tdmc_din3 {
+ mux {
+ groups = "tdmc_din3";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_dout0_pins: tdmc_dout0 {
+ mux {
+ groups = "tdmc_dout0";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_dout1_pins: tdmc_dout1 {
+ mux {
+ groups = "tdmc_dout1";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_dout2_pins: tdmc_dout2 {
+ mux {
+ groups = "tdmc_dout2";
+ function = "tdmc";
+ };
+ };
+
+ tdmc_dout3_pins: tdmc_dout3 {
+ mux {
+ groups = "tdmc_dout3";
+ function = "tdmc";
+ };
+ };
+
+ uart_a_pins: uart_a {
+ mux {
+ groups = "uart_tx_a",
+ "uart_rx_a";
+ function = "uart_a";
+ };
+ };
+
+ uart_a_cts_rts_pins: uart_a_cts_rts {
+ mux {
+ groups = "uart_cts_a",
+ "uart_rts_a";
+ function = "uart_a";
+ };
+ };
+
+ uart_b_x_pins: uart_b_x {
+ mux {
+ groups = "uart_tx_b_x",
+ "uart_rx_b_x";
+ function = "uart_b";
+ };
+ };
+
+ uart_b_x_cts_rts_pins: uart_b_x_cts_rts {
+ mux {
+ groups = "uart_cts_b_x",
+ "uart_rts_b_x";
+ function = "uart_b";
+ };
+ };
+
+ uart_b_z_pins: uart_b_z {
+ mux {
+ groups = "uart_tx_b_z",
+ "uart_rx_b_z";
+ function = "uart_b";
+ };
+ };
+
+ uart_b_z_cts_rts_pins: uart_b_z_cts_rts {
+ mux {
+ groups = "uart_cts_b_z",
+ "uart_rts_b_z";
+ function = "uart_b";
+ };
+ };
+
+ uart_ao_b_z_pins: uart_ao_b_z {
+ mux {
+ groups = "uart_ao_tx_b_z",
+ "uart_ao_rx_b_z";
+ function = "uart_ao_b_z";
+ };
+ };
+
+ uart_ao_b_z_cts_rts_pins: uart_ao_b_z_cts_rts {
+ mux {
+ groups = "uart_ao_cts_b_z",
+ "uart_ao_rts_b_z";
+ function = "uart_ao_b_z";
+ };
+ };
+ };
+ };
+
+ hiubus: bus@ff63c000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xff63c000 0x0 0x1c00>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xff63c000 0x0 0x1c00>;
+
+ sysctrl: system-controller@0 {
+ compatible = "amlogic,meson-axg-hhi-sysctrl",
+ "simple-mfd", "syscon";
+ reg = <0 0 0 0x400>;
+
+ clkc: clock-controller {
+ compatible = "amlogic,axg-clkc";
+ #clock-cells = <1>;
+ };
+ };
+ };
+
+ mailbox: mailbox@ff63dc00 {
+ compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu";
+ reg = <0 0xff63dc00 0 0x400>;
+ interrupts = <GIC_SPI 208 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 209 IRQ_TYPE_EDGE_RISING>,
+ <GIC_SPI 210 IRQ_TYPE_EDGE_RISING>;
+ #mbox-cells = <1>;
+ };
+
+ audio: bus@ff642000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xff642000 0x0 0x2000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xff642000 0x0 0x2000>;
+
+ clkc_audio: clock-controller@0 {
+ compatible = "amlogic,axg-audio-clkc";
+ reg = <0x0 0x0 0x0 0xb4>;
+ #clock-cells = <1>;
+
+ clocks = <&clkc CLKID_AUDIO>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>,
+ <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL3>,
+ <&clkc CLKID_HIFI_PLL>,
+ <&clkc CLKID_FCLK_DIV3>,
+ <&clkc CLKID_FCLK_DIV4>,
+ <&clkc CLKID_GP0_PLL>;
+ clock-names = "pclk",
+ "mst_in0",
+ "mst_in1",
+ "mst_in2",
+ "mst_in3",
+ "mst_in4",
+ "mst_in5",
+ "mst_in6",
+ "mst_in7";
+
+ resets = <&reset RESET_AUDIO>;
+ };
+
+ toddr_a: audio-controller@100 {
+ compatible = "amlogic,axg-toddr";
+ reg = <0x0 0x100 0x0 0x1c>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "TODDR_A";
+ interrupts = <GIC_SPI 84 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc_audio AUD_CLKID_TODDR_A>;
+ resets = <&arb AXG_ARB_TODDR_A>;
+ status = "disabled";
+ };
+
+ toddr_b: audio-controller@140 {
+ compatible = "amlogic,axg-toddr";
+ reg = <0x0 0x140 0x0 0x1c>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "TODDR_B";
+ interrupts = <GIC_SPI 85 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc_audio AUD_CLKID_TODDR_B>;
+ resets = <&arb AXG_ARB_TODDR_B>;
+ status = "disabled";
+ };
+
+ toddr_c: audio-controller@180 {
+ compatible = "amlogic,axg-toddr";
+ reg = <0x0 0x180 0x0 0x1c>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "TODDR_C";
+ interrupts = <GIC_SPI 86 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc_audio AUD_CLKID_TODDR_C>;
+ resets = <&arb AXG_ARB_TODDR_C>;
+ status = "disabled";
+ };
+
+ frddr_a: audio-controller@1c0 {
+ compatible = "amlogic,axg-frddr";
+ reg = <0x0 0x1c0 0x0 0x1c>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "FRDDR_A";
+ interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
+ resets = <&arb AXG_ARB_FRDDR_A>;
+ status = "disabled";
+ };
+
+ frddr_b: audio-controller@200 {
+ compatible = "amlogic,axg-frddr";
+ reg = <0x0 0x200 0x0 0x1c>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "FRDDR_B";
+ interrupts = <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc_audio AUD_CLKID_FRDDR_B>;
+ resets = <&arb AXG_ARB_FRDDR_B>;
+ status = "disabled";
+ };
+
+ frddr_c: audio-controller@240 {
+ compatible = "amlogic,axg-frddr";
+ reg = <0x0 0x240 0x0 0x1c>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "FRDDR_C";
+ interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
+ resets = <&arb AXG_ARB_FRDDR_C>;
+ status = "disabled";
+ };
+
+ arb: reset-controller@280 {
+ compatible = "amlogic,meson-axg-audio-arb";
+ reg = <0x0 0x280 0x0 0x4>;
+ #reset-cells = <1>;
+ clocks = <&clkc_audio AUD_CLKID_DDR_ARB>;
+ };
+
+ tdmin_a: audio-controller@300 {
+ compatible = "amlogic,axg-tdmin";
+ reg = <0x0 0x300 0x0 0x40>;
+ sound-name-prefix = "TDMIN_A";
+ clocks = <&clkc_audio AUD_CLKID_TDMIN_A>,
+ <&clkc_audio AUD_CLKID_TDMIN_A_SCLK>,
+ <&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>,
+ <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>,
+ <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>;
+ clock-names = "pclk", "sclk", "sclk_sel",
+ "lrclk", "lrclk_sel";
+ status = "disabled";
+ };
+
+ tdmin_b: audio-controller@340 {
+ compatible = "amlogic,axg-tdmin";
+ reg = <0x0 0x340 0x0 0x40>;
+ sound-name-prefix = "TDMIN_B";
+ clocks = <&clkc_audio AUD_CLKID_TDMIN_B>,
+ <&clkc_audio AUD_CLKID_TDMIN_B_SCLK>,
+ <&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>,
+ <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>,
+ <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>;
+ clock-names = "pclk", "sclk", "sclk_sel",
+ "lrclk", "lrclk_sel";
+ status = "disabled";
+ };
+
+ tdmin_c: audio-controller@380 {
+ compatible = "amlogic,axg-tdmin";
+ reg = <0x0 0x380 0x0 0x40>;
+ sound-name-prefix = "TDMIN_C";
+ clocks = <&clkc_audio AUD_CLKID_TDMIN_C>,
+ <&clkc_audio AUD_CLKID_TDMIN_C_SCLK>,
+ <&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>,
+ <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>,
+ <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>;
+ clock-names = "pclk", "sclk", "sclk_sel",
+ "lrclk", "lrclk_sel";
+ status = "disabled";
+ };
+
+ tdmin_lb: audio-controller@3c0 {
+ compatible = "amlogic,axg-tdmin";
+ reg = <0x0 0x3c0 0x0 0x40>;
+ sound-name-prefix = "TDMIN_LB";
+ clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>,
+ <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>,
+ <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>,
+ <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>,
+ <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>;
+ clock-names = "pclk", "sclk", "sclk_sel",
+ "lrclk", "lrclk_sel";
+ status = "disabled";
+ };
+
+ spdifout: audio-controller@480 {
+ compatible = "amlogic,axg-spdifout";
+ reg = <0x0 0x480 0x0 0x50>;
+ #sound-dai-cells = <0>;
+ sound-name-prefix = "SPDIFOUT";
+ clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
+ <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
+ clock-names = "pclk", "mclk";
+ status = "disabled";
+ };
+
+ tdmout_a: audio-controller@500 {
+ compatible = "amlogic,axg-tdmout";
+ reg = <0x0 0x500 0x0 0x40>;
+ sound-name-prefix = "TDMOUT_A";
+ clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
+ <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
+ <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
+ <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
+ <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
+ clock-names = "pclk", "sclk", "sclk_sel",
+ "lrclk", "lrclk_sel";
+ status = "disabled";
+ };
+
+ tdmout_b: audio-controller@540 {
+ compatible = "amlogic,axg-tdmout";
+ reg = <0x0 0x540 0x0 0x40>;
+ sound-name-prefix = "TDMOUT_B";
+ clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>,
+ <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>,
+ <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>,
+ <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>,
+ <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>;
+ clock-names = "pclk", "sclk", "sclk_sel",
+ "lrclk", "lrclk_sel";
+ status = "disabled";
+ };
+
+ tdmout_c: audio-controller@580 {
+ compatible = "amlogic,axg-tdmout";
+ reg = <0x0 0x580 0x0 0x40>;
+ sound-name-prefix = "TDMOUT_C";
+ clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>,
+ <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>,
+ <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>,
+ <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>,
+ <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>;
+ clock-names = "pclk", "sclk", "sclk_sel",
+ "lrclk", "lrclk_sel";
+ status = "disabled";
+ };
+ };
+
+ aobus: bus@ff800000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xff800000 0x0 0x100000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xff800000 0x0 0x100000>;
+
+ sysctrl_AO: sys-ctrl@0 {
+ compatible = "amlogic,meson-axg-ao-sysctrl", "simple-mfd", "syscon";
+ reg = <0x0 0x0 0x0 0x100>;
+
+ clkc_AO: clock-controller {
+ compatible = "amlogic,meson-axg-aoclkc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+ };
+
+ pinctrl_aobus: pinctrl@14 {
+ compatible = "amlogic,meson-axg-aobus-pinctrl";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ gpio_ao: bank@14 {
+ reg = <0x0 0x00014 0x0 0x8>,
+ <0x0 0x0002c 0x0 0x4>,
+ <0x0 0x00024 0x0 0x8>;
+ reg-names = "mux", "pull", "gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&pinctrl_aobus 0 0 15>;
+ };
+
+ i2c_ao_sck_4_pins: i2c_ao_sck_4 {
+ mux {
+ groups = "i2c_ao_sck_4";
+ function = "i2c_ao";
+ };
+ };
+
+ i2c_ao_sck_8_pins: i2c_ao_sck_8 {
+ mux {
+ groups = "i2c_ao_sck_8";
+ function = "i2c_ao";
+ };
+ };
+
+ i2c_ao_sck_10_pins: i2c_ao_sck_10 {
+ mux {
+ groups = "i2c_ao_sck_10";
+ function = "i2c_ao";
+ };
+ };
+
+ i2c_ao_sda_5_pins: i2c_ao_sda_5 {
+ mux {
+ groups = "i2c_ao_sda_5";
+ function = "i2c_ao";
+ };
+ };
+
+ i2c_ao_sda_9_pins: i2c_ao_sda_9 {
+ mux {
+ groups = "i2c_ao_sda_9";
+ function = "i2c_ao";
+ };
+ };
+
+ i2c_ao_sda_11_pins: i2c_ao_sda_11 {
+ mux {
+ groups = "i2c_ao_sda_11";
+ function = "i2c_ao";
+ };
+ };
+
+ remote_input_ao_pins: remote_input_ao {
+ mux {
+ groups = "remote_input_ao";
+ function = "remote_input_ao";
+ };
+ };
+
+ uart_ao_a_pins: uart_ao_a {
+ mux {
+ groups = "uart_ao_tx_a",
+ "uart_ao_rx_a";
+ function = "uart_ao_a";
+ };
+ };
+
+ uart_ao_a_cts_rts_pins: uart_ao_a_cts_rts {
+ mux {
+ groups = "uart_ao_cts_a",
+ "uart_ao_rts_a";
+ function = "uart_ao_a";
+ };
+ };
+
+ uart_ao_b_pins: uart_ao_b {
+ mux {
+ groups = "uart_ao_tx_b",
+ "uart_ao_rx_b";
+ function = "uart_ao_b";
+ };
+ };
+
+ uart_ao_b_cts_rts_pins: uart_ao_b_cts_rts {
+ mux {
+ groups = "uart_ao_cts_b",
+ "uart_ao_rts_b";
+ function = "uart_ao_b";
+ };
+ };
+ };
+
+ sec_AO: ao-secure@140 {
+ compatible = "amlogic,meson-gx-ao-secure", "syscon";
+ reg = <0x0 0x140 0x0 0x140>;
+ amlogic,has-chip-id;
+ };
+
+ pwm_AO_cd: pwm@2000 {
+ compatible = "amlogic,meson-axg-ao-pwm";
+ reg = <0x0 0x02000 0x0 0x20>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ uart_AO: serial@3000 {
+ compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";
+ reg = <0x0 0x3000 0x0 0x18>;
+ interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&clkc_AO CLKID_AO_UART1>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+
+ uart_AO_B: serial@4000 {
+ compatible = "amlogic,meson-gx-uart", "amlogic,meson-ao-uart";
+ reg = <0x0 0x4000 0x0 0x18>;
+ interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>, <&clkc_AO CLKID_AO_UART2>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ status = "disabled";
+ };
+
+ i2c_AO: i2c@5000 {
+ compatible = "amlogic,meson-axg-i2c";
+ reg = <0x0 0x05000 0x0 0x20>;
+ interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_AO_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ pwm_AO_ab: pwm@7000 {
+ compatible = "amlogic,meson-axg-ao-pwm";
+ reg = <0x0 0x07000 0x0 0x20>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ ir: ir@8000 {
+ compatible = "amlogic,meson-gxbb-ir";
+ reg = <0x0 0x8000 0x0 0x20>;
+ interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ };
+
+ saradc: adc@9000 {
+ compatible = "amlogic,meson-axg-saradc",
+ "amlogic,meson-saradc";
+ reg = <0x0 0x9000 0x0 0x38>;
+ #io-channel-cells = <1>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&xtal>,
+ <&clkc_AO CLKID_AO_SAR_ADC>,
+ <&clkc_AO CLKID_AO_SAR_ADC_CLK>,
+ <&clkc_AO CLKID_AO_SAR_ADC_SEL>;
+ clock-names = "clkin", "core", "adc_clk", "adc_sel";
+ status = "disabled";
+ };
+ };
+
+ gic: interrupt-controller@ffc01000 {
+ compatible = "arm,gic-400";
+ reg = <0x0 0xffc01000 0 0x1000>,
+ <0x0 0xffc02000 0 0x2000>,
+ <0x0 0xffc04000 0 0x2000>,
+ <0x0 0xffc06000 0 0x2000>;
+ interrupt-controller;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+ #interrupt-cells = <3>;
+ #address-cells = <0>;
+ };
+
+ cbus: bus@ffd00000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xffd00000 0x0 0x25000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xffd00000 0x0 0x25000>;
+
+ reset: reset-controller@1004 {
+ compatible = "amlogic,meson-axg-reset";
+ reg = <0x0 0x01004 0x0 0x9c>;
+ #reset-cells = <1>;
+ };
+
+ gpio_intc: interrupt-controller@f080 {
+ compatible = "amlogic,meson-gpio-intc";
+ reg = <0x0 0xf080 0x0 0x10>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>;
+ status = "disabled";
+ };
+
+ pwm_ab: pwm@1b000 {
+ compatible = "amlogic,meson-axg-ee-pwm";
+ reg = <0x0 0x1b000 0x0 0x20>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ pwm_cd: pwm@1a000 {
+ compatible = "amlogic,meson-axg-ee-pwm";
+ reg = <0x0 0x1a000 0x0 0x20>;
+ #pwm-cells = <3>;
+ status = "disabled";
+ };
+
+ spicc0: spi@13000 {
+ compatible = "amlogic,meson-axg-spicc";
+ reg = <0x0 0x13000 0x0 0x3c>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLKID_SPICC0>;
+ clock-names = "core";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ spicc1: spi@15000 {
+ compatible = "amlogic,meson-axg-spicc";
+ reg = <0x0 0x15000 0x0 0x3c>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clkc CLKID_SPICC1>;
+ clock-names = "core";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@1c000 {
+ compatible = "amlogic,meson-axg-i2c";
+ reg = <0x0 0x1c000 0x0 0x20>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@1d000 {
+ compatible = "amlogic,meson-axg-i2c";
+ reg = <0x0 0x1d000 0x0 0x20>;
+ interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@1e000 {
+ compatible = "amlogic,meson-axg-i2c";
+ reg = <0x0 0x1e000 0x0 0x20>;
+ interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ i2c0: i2c@1f000 {
+ compatible = "amlogic,meson-axg-i2c";
+ reg = <0x0 0x1f000 0x0 0x20>;
+ interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_I2C>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ uart_B: serial@23000 {
+ compatible = "amlogic,meson-gx-uart";
+ reg = <0x0 0x23000 0x0 0x18>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ };
+
+ uart_A: serial@24000 {
+ compatible = "amlogic,meson-gx-uart";
+ reg = <0x0 0x24000 0x0 0x18>;
+ interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
+ clock-names = "xtal", "pclk", "baud";
+ };
+ };
+
+ apb: bus@ffe00000 {
+ compatible = "simple-bus";
+ reg = <0x0 0xffe00000 0x0 0x200000>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x0 0x0 0xffe00000 0x0 0x200000>;
+
+ sd_emmc_b: sd@5000 {
+ compatible = "amlogic,meson-axg-mmc";
+ reg = <0x0 0x5000 0x0 0x800>;
+ interrupts = <GIC_SPI 217 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ clocks = <&clkc CLKID_SD_EMMC_B>,
+ <&clkc CLKID_SD_EMMC_B_CLK0>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+ resets = <&reset RESET_SD_EMMC_B>;
+ };
+
+ sd_emmc_c: mmc@7000 {
+ compatible = "amlogic,meson-axg-mmc";
+ reg = <0x0 0x7000 0x0 0x800>;
+ interrupts = <GIC_SPI 218 IRQ_TYPE_EDGE_RISING>;
+ status = "disabled";
+ clocks = <&clkc CLKID_SD_EMMC_C>,
+ <&clkc CLKID_SD_EMMC_C_CLK0>,
+ <&clkc CLKID_FCLK_DIV2>;
+ clock-names = "core", "clkin0", "clkin1";
+ resets = <&reset RESET_SD_EMMC_C>;
+ };
+ };
+
+ sram: sram@fffc0000 {
+ compatible = "amlogic,meson-axg-sram", "mmio-sram";
+ reg = <0x0 0xfffc0000 0x0 0x20000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0xfffc0000 0x20000>;
+
+ cpu_scp_lpri: scp-shmem@0 {
+ compatible = "amlogic,meson-axg-scp-shmem";
+ reg = <0x13000 0x400>;
+ };
+
+ cpu_scp_hpri: scp-shmem@200 {
+ compatible = "amlogic,meson-axg-scp-shmem";
+ reg = <0x13400 0x400>;
+ };
+ };
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10
+ (GIC_CPU_MASK_RAW(0xff) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ xtal: xtal-clk {
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ clock-output-names = "xtal";
+ #clock-cells = <0>;
+ };
+};
diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi
new file mode 100644
index 0000000..f50f4ef
--- /dev/null
+++ b/arch/arm/dts/mt7623.dtsi
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ */
+
+#include <dt-bindings/clock/mt7623-clk.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/mt7623-power.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "mediatek,mt7623";
+ interrupt-parent = <&sysirq>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "mediatek,mt6589-smp";
+
+ cpu0: cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x0>;
+ clocks = <&infracfg CLK_INFRA_CPUSEL>,
+ <&apmixedsys CLK_APMIXED_MAINPLL>;
+ clock-names = "cpu", "intermediate";
+ clock-frequency = <1300000000>;
+ };
+
+ cpu1: cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x1>;
+ clocks = <&infracfg CLK_INFRA_CPUSEL>,
+ <&apmixedsys CLK_APMIXED_MAINPLL>;
+ clock-names = "cpu", "intermediate";
+ clock-frequency = <1300000000>;
+ };
+
+ cpu2: cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x2>;
+ clocks = <&infracfg CLK_INFRA_CPUSEL>,
+ <&apmixedsys CLK_APMIXED_MAINPLL>;
+ clock-names = "cpu", "intermediate";
+ clock-frequency = <1300000000>;
+ };
+
+ cpu3: cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x3>;
+ clocks = <&infracfg CLK_INFRA_CPUSEL>,
+ <&apmixedsys CLK_APMIXED_MAINPLL>;
+ clock-names = "cpu", "intermediate";
+ clock-frequency = <1300000000>;
+ };
+ };
+
+ system_clk: dummy13m {
+ compatible = "fixed-clock";
+ clock-frequency = <13000000>;
+ #clock-cells = <0>;
+ };
+
+ rtc32k: oscillator-1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32000>;
+ clock-output-names = "rtc32k";
+ };
+
+ clk26m: oscillator-0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <26000000>;
+ clock-output-names = "clk26m";
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ clock-frequency = <13000000>;
+ arm,cpu-registers-not-fw-configured;
+ };
+
+ topckgen: clock-controller@10000000 {
+ compatible = "mediatek,mt7623-topckgen";
+ reg = <0x10000000 0x1000>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ infracfg: syscon@10001000 {
+ compatible = "mediatek,mt7623-infracfg", "syscon";
+ reg = <0x10001000 0x1000>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ pericfg: syscon@10003000 {
+ compatible = "mediatek,mt7623-pericfg", "syscon";
+ reg = <0x10003000 0x1000>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ pinctrl: pinctrl@10005000 {
+ compatible = "mediatek,mt7623-pinctrl";
+ reg = <0x10005000 0x1000>;
+
+ gpio: gpio-controller {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ scpsys: scpsys@10006000 {
+ compatible = "mediatek,mt7623-scpsys";
+ #power-domain-cells = <1>;
+ reg = <0x10006000 0x1000>;
+ infracfg = <&infracfg>;
+ clocks = <&topckgen CLK_TOP_MM_SEL>,
+ <&topckgen CLK_TOP_MFG_SEL>,
+ <&topckgen CLK_TOP_ETHIF_SEL>;
+ clock-names = "mm", "mfg", "ethif";
+ };
+
+ watchdog: watchdog@10007000 {
+ compatible = "mediatek,wdt";
+ reg = <0x10007000 0x100>;
+ };
+
+ wdt-reboot {
+ compatible = "wdt-reboot";
+ wdt = <&watchdog>;
+ };
+
+ timer0: timer@10008000 {
+ compatible = "mediatek,timer";
+ reg = <0x10008000 0x80>;
+ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&system_clk>;
+ clock-names = "system-clk";
+ u-boot,dm-pre-reloc;
+ };
+
+ sysirq: interrupt-controller@10200100 {
+ compatible = "mediatek,sysirq";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10200100 0x1c>;
+ };
+
+ apmixedsys: clock-controller@10209000 {
+ compatible = "mediatek,mt7623-apmixedsys";
+ reg = <0x10209000 0x1000>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ gic: interrupt-controller@10211000 {
+ compatible = "arm,cortex-a7-gic";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10211000 0x1000>,
+ <0x10212000 0x1000>,
+ <0x10214000 0x2000>,
+ <0x10216000 0x2000>;
+ };
+
+ uart0: serial@11002000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11002000 0x400>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&pericfg CLK_PERI_UART0>;
+ clock-names = "baud", "bus";
+ status = "disabled";
+ };
+
+ uart1: serial@11003000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11003000 0x400>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&pericfg CLK_PERI_UART1>;
+ clock-names = "baud", "bus";
+ status = "disabled";
+ };
+
+ uart2: serial@11004000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11004000 0x400>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&pericfg CLK_PERI_UART2>;
+ clock-names = "baud", "bus";
+ status = "disabled";
+ u-boot,dm-pre-reloc;
+ };
+
+ uart3: serial@11005000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11005000 0x400>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&pericfg CLK_PERI_UART3>;
+ clock-names = "baud", "bus";
+ status = "disabled";
+ };
+
+ mmc0: mmc@11230000 {
+ compatible = "mediatek,mt7623-mmc";
+ reg = <0x11230000 0x1000>;
+ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&pericfg CLK_PERI_MSDC30_0>,
+ <&topckgen CLK_TOP_MSDC30_0_SEL>;
+ clock-names = "source", "hclk";
+ status = "disabled";
+ };
+
+ mmc1: mmc@11240000 {
+ compatible = "mediatek,mt7623-mmc";
+ reg = <0x11240000 0x1000>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&pericfg CLK_PERI_MSDC30_1>,
+ <&topckgen CLK_TOP_MSDC30_1_SEL>;
+ clock-names = "source", "hclk";
+ status = "disabled";
+ };
+
+ ethsys: syscon@1b000000 {
+ compatible = "mediatek,mt7623-ethsys";
+ reg = <0x1b000000 0x1000>;
+ #clock-cells = <1>;
+ };
+};
diff --git a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
new file mode 100644
index 0000000..84a77fd
--- /dev/null
+++ b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ */
+
+/dts-v1/;
+#include "mt7623.dtsi"
+
+/ {
+ model = "Bananapi BPI-R2";
+ compatible = "bananapi,bpi-r2", "mediatek,mt7623";
+
+ chosen {
+ stdout-path = &uart2;
+ tick-timer = &timer0;
+ };
+
+ reg_1p8v: regulator-1p8v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_3p3v: regulator-3p3v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ reg_5v: regulator-5v {
+ compatible = "regulator-fixed";
+ regulator-name = "fixed-5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ blue {
+ label = "bpi-r2:pio:blue";
+ gpios = <&gpio 241 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ green {
+ label = "bpi-r2:pio:green";
+ gpios = <&gpio 240 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ red {
+ label = "bpi-r2:pio:red";
+ gpios = <&gpio 239 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins_default>;
+ status = "okay";
+ bus-width = <8>;
+ max-frequency = <50000000>;
+ cap-mmc-highspeed;
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_1p8v>;
+ non-removable;
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins_default>;
+ status = "okay";
+ bus-width = <4>;
+ max-frequency = <50000000>;
+ cap-sd-highspeed;
+ cd-gpios = <&gpio 261 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&reg_3p3v>;
+ vqmmc-supply = <&reg_3p3v>;
+};
+
+&pinctrl {
+ ephy_default: ephy_default {
+ mux {
+ function = "eth";
+ groups = "mdc_mdio", "ephy";
+ };
+
+ conf {
+ pins = "G2_TXEN", "G2_TXD0", "G2_TXD1", "G2_TXD2",
+ "G2_TXD3", "G2_TXC", "G2_RXC", "G2_RXD0",
+ "G2_RXD1", "G2_RXD2", "G2_RXD3", "G2_RXDV",
+ "MDC", "MDIO";
+ drive-strength = <12>;
+ mediatek,tdsel = <5>;
+ };
+ };
+
+ mmc0_pins_default: mmc0default {
+ mux {
+ function = "msdc";
+ groups = "msdc0";
+ };
+
+ conf-cmd-data {
+ pins = "MSDC0_CMD", "MSDC0_DAT0", "MSDC0_DAT1",
+ "MSDC0_DAT2", "MSDC0_DAT3", "MSDC0_DAT4",
+ "MSDC0_DAT5", "MSDC0_DAT6", "MSDC0_DAT7";
+ input-enable;
+ bias-pull-up;
+ };
+
+ conf-clk {
+ pins = "MSDC0_CLK";
+ bias-pull-down;
+ };
+
+ conf-rst {
+ pins = "MSDC0_RSTB";
+ bias-pull-up;
+ };
+ };
+
+ mmc1_pins_default: mmc1default {
+ mux {
+ function = "msdc";
+ groups = "msdc1", "msdc1_wp_0";
+ };
+
+ conf-cmd-data {
+ pins = "MSDC1_DAT0", "MSDC1_DAT1", "MSDC1_DAT2",
+ "MSDC1_DAT3", "MSDC1_DAT3", "MSDC1_CMD";
+ input-enable;
+ drive-strength = <4>;
+ bias-pull-up;
+ };
+
+ conf-clk {
+ pins = "MSDC1_CLK";
+ drive-strength = <4>;
+ };
+
+ conf-wp {
+ pins = "EINT7";
+ input-enable;
+ bias-pull-up;
+ };
+ };
+
+ uart0_pins_a: uart0-default {
+ mux {
+ function = "uart";
+ groups = "uart0_0_txd_rxd";
+ };
+ };
+
+ uart1_pins_a: uart1-default {
+ mux {
+ function = "uart";
+ groups = "uart1_0_txd_rxd";
+ };
+ };
+
+ uart2_pins_a: uart2-default {
+ mux {
+ function = "uart";
+ groups = "uart2_0_txd_rxd";
+ };
+ };
+
+ uart2_pins_b: uart2-alt {
+ mux {
+ function = "uart";
+ groups = "uart2_1_txd_rxd";
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins_a>;
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins_a>;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins_a>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/mt7629-rfb-u-boot.dtsi b/arch/arm/dts/mt7629-rfb-u-boot.dtsi
new file mode 100644
index 0000000..1ef5568
--- /dev/null
+++ b/arch/arm/dts/mt7629-rfb-u-boot.dtsi
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <config.h>
+/ {
+ binman {
+ filename = "u-boot-mtk.bin";
+ pad-byte = <0xff>;
+
+#ifdef CONFIG_SPL
+ blob {
+ filename = "spl/u-boot-spl-mtk.bin";
+ size = <CONFIG_SPL_PAD_TO>;
+ };
+
+ u-boot-img {
+ };
+#endif
+ };
+};
diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts
new file mode 100644
index 0000000..a6d28a0
--- /dev/null
+++ b/arch/arm/dts/mt7629-rfb.dts
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ */
+
+/dts-v1/;
+#include "mt7629.dtsi"
+
+/ {
+ model = "MediaTek MT7629 RFB";
+ compatible = "mediatek,mt7629-rfb", "mediatek,mt7629";
+
+ aliases {
+ spi0 = &qspi;
+ };
+
+ chosen {
+ stdout-path = &uart0;
+ tick-timer = &timer0;
+ };
+};
+
+&pinctrl {
+ qspi_pins: qspi-pins {
+ mux {
+ function = "flash";
+ groups = "spi_nor";
+ };
+ };
+
+ uart0_pins: uart0-default {
+ mux {
+ function = "uart";
+ groups = "uart0_txd_rxd";
+ };
+ };
+
+ watchdog_pins: watchdog-default {
+ mux {
+ function = "watchdog";
+ groups = "watchdog";
+ };
+ };
+};
+
+&qspi {
+ pinctrl-names = "default";
+ pinctrl-0 = <&qspi_pins>;
+ status = "okay";
+
+ spi-flash@0{
+ compatible = "spi-flash";
+ reg = <0>;
+ u-boot,dm-pre-reloc;
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ pinctrl-names = "default";
+ pinctrl-0 = <&watchdog_pins>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/mt7629.dtsi b/arch/arm/dts/mt7629.dtsi
new file mode 100644
index 0000000..e6052bb
--- /dev/null
+++ b/arch/arm/dts/mt7629.dtsi
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ */
+
+#include <dt-bindings/clock/mt7629-clk.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/mt7629-power.h>
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "mediatek,mt7629";
+ interrupt-parent = <&sysirq>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ enable-method = "mediatek,mt6589-smp";
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x0>;
+ clock-frequency = <1250000000>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a7";
+ reg = <0x1>;
+ clock-frequency = <1250000000>;
+ };
+ };
+
+ clk20m: oscillator@0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <20000000>;
+ clock-output-names = "clk20m";
+ };
+
+ clk40m: oscillator@1 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <40000000>;
+ clock-output-names = "clkxtal";
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupt-parent = <&gic>;
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ clock-frequency = <20000000>;
+ arm,cpu-registers-not-fw-configured;
+ };
+
+ infracfg: syscon@10000000 {
+ compatible = "mediatek,mt7629-infracfg", "syscon";
+ reg = <0x10000000 0x1000>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ pericfg: syscon@10002000 {
+ compatible = "mediatek,mt7629-pericfg", "syscon";
+ reg = <0x10002000 0x1000>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ timer0: timer@10004000 {
+ compatible = "mediatek,timer";
+ reg = <0x10004000 0x80>;
+ interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_10M_SEL>,
+ <&topckgen CLK_TOP_CLKXTAL_D4>;
+ clock-names = "mux", "src";
+ u-boot,dm-pre-reloc;
+ };
+
+ scpsys: scpsys@10006000 {
+ compatible = "mediatek,mt7629-scpsys";
+ reg = <0x10006000 0x1000>;
+ clocks = <&topckgen CLK_TOP_HIF_SEL>;
+ clock-names = "hif_sel";
+ assigned-clocks = <&topckgen CLK_TOP_HIF_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
+ #power-domain-cells = <1>;
+ infracfg = <&infracfg>;
+ };
+
+ mcucfg: syscon@10200000 {
+ compatible = "mediatek,mt7629-mcucfg", "syscon";
+ reg = <0x10200000 0x1000>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ sysirq: interrupt-controller@10200a80 {
+ compatible = "mediatek,sysirq";
+ reg = <0x10200a80 0x20>;
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ };
+
+ dramc: dramc@10203000 {
+ compatible = "mediatek,mt7629-dramc";
+ reg = <0x10203000 0x600>, /* EMI */
+ <0x10213000 0x1000>, /* DDRPHY */
+ <0x10214000 0xd00>; /* DRAMC_AO */
+ clocks = <&topckgen CLK_TOP_DDRPHYCFG_SEL>,
+ <&topckgen CLK_TOP_SYSPLL1_D8>,
+ <&topckgen CLK_TOP_MEM_SEL>,
+ <&topckgen CLK_TOP_DMPLL>;
+ clock-names = "phy", "phy_mux", "mem", "mem_mux";
+ u-boot,dm-pre-reloc;
+ };
+
+ apmixedsys: clock-controller@10209000 {
+ compatible = "mediatek,mt7629-apmixedsys";
+ reg = <0x10209000 0x1000>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ topckgen: clock-controller@10210000 {
+ compatible = "mediatek,mt7629-topckgen";
+ reg = <0x10210000 0x1000>;
+ #clock-cells = <1>;
+ u-boot,dm-pre-reloc;
+ };
+
+ watchdog: watchdog@10212000 {
+ compatible = "mediatek,wdt";
+ reg = <0x10212000 0x600>;
+ interrupts = <GIC_SPI 128 IRQ_TYPE_EDGE_FALLING>;
+ #reset-cells = <1>;
+ status = "disabled";
+ };
+
+ wdt-reboot {
+ compatible = "wdt-reboot";
+ wdt = <&watchdog>;
+ };
+
+ pinctrl: pinctrl@10217000 {
+ compatible = "mediatek,mt7629-pinctrl";
+ reg = <0x10217000 0x8000>;
+
+ gpio: gpio-controller {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ gic: interrupt-controller@10300000 {
+ compatible = "arm,gic-400";
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ interrupt-parent = <&gic>;
+ reg = <0x10310000 0x1000>,
+ <0x10320000 0x1000>,
+ <0x10340000 0x2000>,
+ <0x10360000 0x2000>;
+ };
+
+ uart0: serial@11002000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11002000 0x400>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&pericfg CLK_PERI_UART0_PD>;
+ clock-names = "baud", "bus";
+ status = "disabled";
+ assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
+ u-boot,dm-pre-reloc;
+ };
+
+ uart1: serial@11003000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11003000 0x400>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&pericfg CLK_PERI_UART1_PD>;
+ clock-names = "baud", "bus";
+ assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
+ status = "disabled";
+ };
+
+ uart2: serial@11004000 {
+ compatible = "mediatek,hsuart";
+ reg = <0x11004000 0x400>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&topckgen CLK_TOP_UART_SEL>,
+ <&pericfg CLK_PERI_UART2_PD>;
+ clock-names = "baud", "bus";
+ assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
+ status = "disabled";
+ };
+
+ qspi: qspi@11014000 {
+ compatible = "mediatek,mt7629-qspi";
+ reg = <0x11014000 0xe0>, <0x30000000 0x10000000>;
+ reg-names = "reg_base", "mem_base";
+ status = "disabled";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ u-boot,dm-pre-reloc;
+ };
+
+ ethsys: syscon@1b000000 {
+ compatible = "mediatek,mt7629-ethsys", "syscon";
+ reg = <0x1b000000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ sgmiisys0: syscon@1b128000 {
+ compatible = "mediatek,mt7629-sgmiisys", "syscon";
+ reg = <0x1b128000 0x1000>;
+ #clock-cells = <1>;
+ };
+
+ sgmiisys1: syscon@1b130000 {
+ compatible = "mediatek,mt7629-sgmiisys", "syscon";
+ reg = <0x1b130000 0x1000>;
+ #clock-cells = <1>;
+ };
+};
diff --git a/arch/arm/include/asm/arch-mediatek/gpio.h b/arch/arm/include/asm/arch-mediatek/gpio.h
new file mode 100644
index 0000000..4ea1020
--- /dev/null
+++ b/arch/arm/include/asm/arch-mediatek/gpio.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef __MEDIATEK_GPIO_H
+#define __MEDIATEK_GPIO_H
+
+#endif /* __MEDIATEK_GPIO_H */
diff --git a/arch/arm/include/asm/arch-mediatek/misc.h b/arch/arm/include/asm/arch-mediatek/misc.h
new file mode 100644
index 0000000..2530e78
--- /dev/null
+++ b/arch/arm/include/asm/arch-mediatek/misc.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef __MEDIATEK_MISC_H_
+#define __MEDIATEK_MISC_H_
+
+#define VER_BASE 0x08000000
+#define VER_SIZE 0x10
+
+#define APHW_CODE 0x00
+#define APHW_SUBCODE 0x04
+#define APHW_VER 0x08
+#define APSW_VER 0x0c
+
+#endif /* __MEDIATEK_MISC_H_ */
diff --git a/arch/arm/include/asm/arch-meson/axg.h b/arch/arm/include/asm/arch-meson/axg.h
new file mode 100644
index 0000000..d293f2a
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/axg.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2018 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef __AXG_H__
+#define __AXG_H__
+
+#define AXG_AOBUS_BASE 0xff800000
+#define AXG_PERIPHS_BASE 0xff634400
+#define AXG_HIU_BASE 0xff63c000
+#define AXG_ETH_BASE 0xff3f0000
+
+/* Always-On Peripherals registers */
+#define AXG_AO_ADDR(off) (AXG_AOBUS_BASE + ((off) << 2))
+
+#define AXG_AO_SEC_GP_CFG0 AXG_AO_ADDR(0x90)
+#define AXG_AO_SEC_GP_CFG3 AXG_AO_ADDR(0x93)
+#define AXG_AO_SEC_GP_CFG4 AXG_AO_ADDR(0x94)
+#define AXG_AO_SEC_GP_CFG5 AXG_AO_ADDR(0x95)
+
+#define AXG_AO_BOOT_DEVICE 0xF
+#define AXG_AO_MEM_SIZE_MASK 0xFFFF0000
+#define AXG_AO_MEM_SIZE_SHIFT 16
+#define AXG_AO_BL31_RSVMEM_SIZE_MASK 0xFFFF0000
+#define AXG_AO_BL31_RSVMEM_SIZE_SHIFT 16
+#define AXG_AO_BL32_RSVMEM_SIZE_MASK 0xFFFF
+
+/* Peripherals registers */
+#define AXG_PERIPHS_ADDR(off) (AXG_PERIPHS_BASE + ((off) << 2))
+
+#define AXG_ETH_REG_0 AXG_PERIPHS_ADDR(0x50)
+#define AXG_ETH_REG_1 AXG_PERIPHS_ADDR(0x51)
+
+#define AXG_ETH_REG_0_PHY_INTF_RGMII BIT(0)
+#define AXG_ETH_REG_0_PHY_INTF_RMII BIT(2)
+#define AXG_ETH_REG_0_TX_PHASE(x) (((x) & 3) << 5)
+#define AXG_ETH_REG_0_TX_RATIO(x) (((x) & 7) << 7)
+#define AXG_ETH_REG_0_PHY_CLK_EN BIT(10)
+#define AXG_ETH_REG_0_INVERT_RMII_CLK BIT(11)
+#define AXG_ETH_REG_0_CLK_EN BIT(12)
+
+/* HIU registers */
+#define AXG_HIU_ADDR(off) (AXG_HIU_BASE + ((off) << 2))
+
+#define AXG_MEM_PD_REG_0 AXG_HIU_ADDR(0x40)
+
+/* Ethernet memory power domain */
+#define AXG_MEM_PD_REG_0_ETH_MASK (BIT(2) | BIT(3))
+
+#endif /* __AXG_H__ */
diff --git a/arch/arm/include/asm/arch-meson/boot.h b/arch/arm/include/asm/arch-meson/boot.h
new file mode 100644
index 0000000..a90fe55
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/boot.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef __MESON_BOOT_H__
+#define __MESON_BOOT_H__
+
+/* Boot device */
+#define BOOT_DEVICE_RESERVED 0
+#define BOOT_DEVICE_EMMC 1
+#define BOOT_DEVICE_NAND 2
+#define BOOT_DEVICE_SPI 3
+#define BOOT_DEVICE_SD 4
+#define BOOT_DEVICE_USB 5
+
+int meson_get_boot_device(void);
+
+#endif /* __MESON_BOOT_H__ */
diff --git a/arch/arm/include/asm/arch-meson/clock-axg.h b/arch/arm/include/asm/arch-meson/clock-axg.h
new file mode 100644
index 0000000..1ef88e4
--- /dev/null
+++ b/arch/arm/include/asm/arch-meson/clock-axg.h
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2016 - AmLogic, Inc.
+ * Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com>
+ * Copyright 2018 - BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+#ifndef _ARCH_MESON_CLOCK_AXG_H_
+#define _ARCH_MESON_CLOCK_AXG_H_
+
+/*
+ * Clock controller register offsets
+ *
+ * Register offsets from the data sheet are listed in comment blocks below.
+ * Those offsets must be multiplied by 4 before adding them to the base address
+ * to get the right value
+ */
+#define HHI_GP0_PLL_CNTL 0x40
+#define HHI_GP0_PLL_CNTL2 0x44
+#define HHI_GP0_PLL_CNTL3 0x48
+#define HHI_GP0_PLL_CNTL4 0x4c
+#define HHI_GP0_PLL_CNTL5 0x50
+#define HHI_GP0_PLL_STS 0x54
+#define HHI_GP0_PLL_CNTL1 0x58
+#define HHI_HIFI_PLL_CNTL 0x80
+#define HHI_HIFI_PLL_CNTL2 0x84
+#define HHI_HIFI_PLL_CNTL3 0x88
+#define HHI_HIFI_PLL_CNTL4 0x8C
+#define HHI_HIFI_PLL_CNTL5 0x90
+#define HHI_HIFI_PLL_STS 0x94
+#define HHI_HIFI_PLL_CNTL1 0x98
+
+#define HHI_XTAL_DIVN_CNTL 0xbc
+#define HHI_GCLK2_MPEG0 0xc0
+#define HHI_GCLK2_MPEG1 0xc4
+#define HHI_GCLK2_MPEG2 0xc8
+#define HHI_GCLK2_OTHER 0xd0
+#define HHI_GCLK2_AO 0xd4
+#define HHI_PCIE_PLL_CNTL 0xd8
+#define HHI_PCIE_PLL_CNTL1 0xdC
+#define HHI_PCIE_PLL_CNTL2 0xe0
+#define HHI_PCIE_PLL_CNTL3 0xe4
+#define HHI_PCIE_PLL_CNTL4 0xe8
+#define HHI_PCIE_PLL_CNTL5 0xec
+#define HHI_PCIE_PLL_CNTL6 0xf0
+#define HHI_PCIE_PLL_STS 0xf4
+
+#define HHI_MEM_PD_REG0 0x100
+#define HHI_VPU_MEM_PD_REG0 0x104
+#define HHI_VIID_CLK_DIV 0x128
+#define HHI_VIID_CLK_CNTL 0x12c
+
+#define HHI_GCLK_MPEG0 0x140
+#define HHI_GCLK_MPEG1 0x144
+#define HHI_GCLK_MPEG2 0x148
+#define HHI_GCLK_OTHER 0x150
+#define HHI_GCLK_AO 0x154
+#define HHI_SYS_CPU_CLK_CNTL1 0x15c
+#define HHI_SYS_CPU_RESET_CNTL 0x160
+#define HHI_VID_CLK_DIV 0x164
+#define HHI_SPICC_HCLK_CNTL 0x168
+
+#define HHI_MPEG_CLK_CNTL 0x174
+#define HHI_VID_CLK_CNTL 0x17c
+#define HHI_TS_CLK_CNTL 0x190
+#define HHI_VID_CLK_CNTL2 0x194
+#define HHI_SYS_CPU_CLK_CNTL0 0x19c
+#define HHI_VID_PLL_CLK_DIV 0x1a0
+#define HHI_VPU_CLK_CNTL 0x1bC
+
+#define HHI_VAPBCLK_CNTL 0x1F4
+
+#define HHI_GEN_CLK_CNTL 0x228
+
+#define HHI_VDIN_MEAS_CLK_CNTL 0x250
+#define HHI_NAND_CLK_CNTL 0x25C
+#define HHI_SD_EMMC_CLK_CNTL 0x264
+
+#define HHI_MPLL_CNTL 0x280
+#define HHI_MPLL_CNTL2 0x284
+#define HHI_MPLL_CNTL3 0x288
+#define HHI_MPLL_CNTL4 0x28C
+#define HHI_MPLL_CNTL5 0x290
+#define HHI_MPLL_CNTL6 0x294
+#define HHI_MPLL_CNTL7 0x298
+#define HHI_MPLL_CNTL8 0x29C
+#define HHI_MPLL_CNTL9 0x2A0
+#define HHI_MPLL_CNTL10 0x2A4
+
+#define HHI_MPLL3_CNTL0 0x2E0
+#define HHI_MPLL3_CNTL1 0x2E4
+#define HHI_PLL_TOP_MISC 0x2E8
+
+#define HHI_SYS_PLL_CNTL1 0x2FC
+#define HHI_SYS_PLL_CNTL 0x300
+#define HHI_SYS_PLL_CNTL2 0x304
+#define HHI_SYS_PLL_CNTL3 0x308
+#define HHI_SYS_PLL_CNTL4 0x30c
+#define HHI_SYS_PLL_CNTL5 0x310
+#define HHI_SYS_PLL_STS 0x314
+#define HHI_DPLL_TOP_I 0x318
+#define HHI_DPLL_TOP2_I 0x31C
+
+#endif
diff --git a/arch/arm/include/asm/arch-meson/clock.h b/arch/arm/include/asm/arch-meson/clock-gx.h
index c0ff00f..13a2e76 100644
--- a/arch/arm/include/asm/arch-meson/clock.h
+++ b/arch/arm/include/asm/arch-meson/clock-gx.h
@@ -3,8 +3,8 @@
* Copyright 2016 - AmLogic, Inc.
* Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com>
*/
-#ifndef _ARCH_MESON_CLOCK_H_
-#define _ARCH_MESON_CLOCK_H_
+#ifndef _ARCH_MESON_CLOCK_GX_H_
+#define _ARCH_MESON_CLOCK_GX_H_
/*
* Clock controller register offsets
diff --git a/arch/arm/include/asm/arch-meson/eth.h b/arch/arm/include/asm/arch-meson/eth.h
index 1aa0872..08acc5c 100644
--- a/arch/arm/include/asm/arch-meson/eth.h
+++ b/arch/arm/include/asm/arch-meson/eth.h
@@ -10,13 +10,13 @@
#include <phy.h>
enum {
- /* Use GXL Internal RMII PHY */
- MESON_GXL_USE_INTERNAL_RMII_PHY = 1,
+ /* Use Internal RMII PHY */
+ MESON_USE_INTERNAL_RMII_PHY = 1,
};
/* Configure the Ethernet MAC with the requested interface mode
* with some optional flags.
*/
-void meson_gx_eth_init(phy_interface_t mode, unsigned int flags);
+void meson_eth_init(phy_interface_t mode, unsigned int flags);
#endif /* __MESON_ETH_H__ */
diff --git a/arch/arm/include/asm/arch-meson/gx.h b/arch/arm/include/asm/arch-meson/gx.h
index 4bc9475..b781ba9 100644
--- a/arch/arm/include/asm/arch-meson/gx.h
+++ b/arch/arm/include/asm/arch-meson/gx.h
@@ -21,6 +21,7 @@
#define GX_AO_SEC_GP_CFG4 GX_AO_ADDR(0x94)
#define GX_AO_SEC_GP_CFG5 GX_AO_ADDR(0x95)
+#define GX_AO_BOOT_DEVICE 0xF
#define GX_AO_MEM_SIZE_MASK 0xFFFF0000
#define GX_AO_MEM_SIZE_SHIFT 16
#define GX_AO_BL31_RSVMEM_SIZE_MASK 0xFFFF0000
diff --git a/arch/arm/include/asm/arch-meson/mem.h b/arch/arm/include/asm/arch-meson/mem.h
index 6281833..a65100a 100644
--- a/arch/arm/include/asm/arch-meson/mem.h
+++ b/arch/arm/include/asm/arch-meson/mem.h
@@ -10,6 +10,7 @@
/* Configure the reserved memory zones exported by the secure registers
* into EFI and DTB reserved memory entries.
*/
-void meson_gx_init_reserved_memory(void *fdt);
+void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size);
+void meson_init_reserved_memory(void *fdt);
#endif /* __MESON_MEM_H__ */
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
new file mode 100644
index 0000000..7a733e9
--- /dev/null
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -0,0 +1,39 @@
+if ARCH_MEDIATEK
+
+config SYS_SOC
+ default "mediatek"
+
+config SYS_VENDOR
+ default "mediatek"
+
+choice
+ prompt "MediaTek board select"
+
+config TARGET_MT7623
+ bool "MediaTek MT7623 SoC"
+ select CPU_V7A
+ select ARCH_MISC_INIT
+ help
+ The MediaTek MT7623 is a ARM-based SoC with a quad-core Cortex-A7
+ including NEON and GPU, Mali-450 graphics, several DDR3 options,
+ crypto engine, built-in Wi-Fi / Bluetooth combo chip, JPEG decoder,
+ video interfaces supporting HDMI and MIPI, and video codec support.
+ Peripherals include Gigabit Ethernet, switch, USB3.0 and OTG, PCIe,
+ I2S, PCM, S/PDIF, UART, SPI, I2C, IR TX/RX, and PWM.
+
+config TARGET_MT7629
+ bool "MediaTek MT7629 SoC"
+ select CPU_V7A
+ select SPL
+ select ARCH_MISC_INIT
+ help
+ The MediaTek MT7629 is a ARM-based SoC with a dual-core Cortex-A7
+ including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet,
+ switch, USB3.0, PCIe, UART, SPI, I2C and PWM.
+
+endchoice
+
+source "board/mediatek/mt7623/Kconfig"
+source "board/mediatek/mt7629/Kconfig"
+
+endif
diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile
new file mode 100644
index 0000000..b5d3a37
--- /dev/null
+++ b/arch/arm/mach-mediatek/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += cpu.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
+
+obj-$(CONFIG_TARGET_MT7623) += mt7623/
+obj-$(CONFIG_TARGET_MT7629) += mt7629/
diff --git a/arch/arm/mach-mediatek/cpu.c b/arch/arm/mach-mediatek/cpu.c
new file mode 100644
index 0000000..b37e299
--- /dev/null
+++ b/arch/arm/mach-mediatek/cpu.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <wdt.h>
+#include <dm/uclass-internal.h>
+
+int arch_misc_init(void)
+{
+ struct udevice *wdt;
+ int ret;
+
+ ret = uclass_first_device_err(UCLASS_WDT, &wdt);
+ if (!ret)
+ wdt_stop(wdt);
+
+ return 0;
+}
+
+int arch_cpu_init(void)
+{
+ icache_enable();
+
+ return 0;
+}
+
+void enable_caches(void)
+{
+ /* Enable D-cache. I-cache is already enabled in start.S */
+ dcache_enable();
+}
diff --git a/arch/arm/mach-mediatek/init.h b/arch/arm/mach-mediatek/init.h
new file mode 100644
index 0000000..1d896fb
--- /dev/null
+++ b/arch/arm/mach-mediatek/init.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef __MEDIATEK_INIT_H_
+#define __MEDIATEK_INIT_H_
+
+extern int mtk_soc_early_init(void);
+
+#endif /* __MEDIATEK_INIT_H_ */
diff --git a/arch/arm/mach-mediatek/mt7623/Makefile b/arch/arm/mach-mediatek/mt7623/Makefile
new file mode 100644
index 0000000..007eb4a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7623/init.c b/arch/arm/mach-mediatek/mt7623/init.c
new file mode 100644
index 0000000..0ee8c66
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/init.c
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <common.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+#include <asm/arch/misc.h>
+
+#include "preloader.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct boot_argument *preloader_param;
+
+int mtk_soc_early_init(void)
+{
+ return 0;
+}
+
+int dram_init(void)
+{
+ u32 i;
+
+ if (((size_t)preloader_param >= CONFIG_SYS_SDRAM_BASE) &&
+ ((size_t)preloader_param % sizeof(size_t) == 0) &&
+ preloader_param->magic == BOOT_ARGUMENT_MAGIC &&
+ preloader_param->dram_rank_num <=
+ ARRAY_SIZE(preloader_param->dram_rank_size)) {
+ gd->ram_size = 0;
+
+ for (i = 0; i < preloader_param->dram_rank_num; i++)
+ gd->ram_size += preloader_param->dram_rank_size[i];
+ } else {
+ gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
+ SZ_2G);
+ }
+
+ return 0;
+}
+
+int print_cpuinfo(void)
+{
+ void __iomem *chipid;
+ u32 swver;
+
+ chipid = ioremap(VER_BASE, VER_SIZE);
+ swver = readl(chipid + APSW_VER);
+
+ printf("CPU: MediaTek MT7623 E%d\n", (swver & 0xf) + 1);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mediatek/mt7623/lowlevel_init.S b/arch/arm/mach-mediatek/mt7623/lowlevel_init.S
new file mode 100644
index 0000000..afb9476
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/lowlevel_init.S
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <linux/linkage.h>
+
+.extern preloader_param
+
+ENTRY(save_boot_params)
+ ldr r6, =preloader_param
+ str r4, [r6]
+ b save_boot_params_ret
+ENDPROC(save_boot_params)
+
+ENTRY(lowlevel_init)
+ /* enable SMP bit */
+ mrc p15, 0, r0, c1, c0, 1
+ orr r0, r0, #0x40
+ mcr p15, 0, r0, c1, c0, 1
+ mov pc, lr
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-mediatek/mt7623/preloader.h b/arch/arm/mach-mediatek/mt7623/preloader.h
new file mode 100644
index 0000000..2d2c71a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7623/preloader.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef __PRELOADER_H_
+#define __PRELOADER_H_
+
+enum forbidden_mode {
+ F_FACTORY_MODE = 0x0001
+};
+
+union lk_hdr {
+ struct {
+ u32 magic;
+ u32 size;
+ char name[32];
+ u32 loadaddr;
+ };
+
+ u8 data[512];
+};
+
+struct sec_limit {
+ unsigned int magic_num;
+ enum forbidden_mode forbid_mode;
+};
+
+enum bootmode {
+ NORMAL_BOOT = 0,
+ META_BOOT = 1,
+ RECOVERY_BOOT = 2,
+ SW_REBOOT = 3,
+ FACTORY_BOOT = 4,
+ ADVMETA_BOOT = 5,
+ ATE_FACTORY_BOOT = 6,
+ ALARM_BOOT = 7,
+
+ KERNEL_POWER_OFF_CHARGING_BOOT = 8,
+ LOW_POWER_OFF_CHARGING_BOOT = 9,
+
+ FAST_BOOT = 99,
+ DOWNLOAD_BOOT = 100,
+ UNKNOWN_BOOT
+};
+
+enum boot_reason {
+ BR_POWER_KEY = 0,
+ BR_USB,
+ BR_RTC,
+ BR_WDT,
+ BR_WDT_BY_PASS_PWK,
+ BR_TOOL_BY_PASS_PWK,
+ BR_2SEC_REBOOT,
+ BR_UNKNOWN
+};
+
+enum meta_com_type {
+ META_UNKNOWN_COM = 0,
+ META_UART_COM,
+ META_USB_COM
+};
+
+struct da_info_t {
+ u32 addr;
+ u32 arg1;
+ u32 arg2;
+ u32 len;
+ u32 sig_len;
+};
+
+struct boot_argument {
+ u32 magic;
+ enum bootmode boot_mode;
+ u32 e_flag;
+ u32 log_port;
+ u32 log_baudrate;
+ u8 log_enable;
+ u8 part_num;
+ u8 reserved[2];
+ u32 dram_rank_num;
+ u32 dram_rank_size[4];
+ u32 boot_reason;
+ enum meta_com_type meta_com_type;
+ u32 meta_com_id;
+ u32 boot_time;
+ struct da_info_t da_info;
+ struct sec_limit sec_limit;
+ union lk_hdr *part_info;
+ u8 md_type[4];
+ u32 ddr_reserve_enable;
+ u32 ddr_reserve_success;
+ u32 chip_ver;
+ char pl_version[8];
+};
+
+#define BOOT_ARGUMENT_MAGIC 0x504c504c
+
+#endif /* __PRELOADER_H_ */
diff --git a/arch/arm/mach-mediatek/mt7629/Makefile b/arch/arm/mach-mediatek/mt7629/Makefile
new file mode 100644
index 0000000..007eb4a
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7629/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += init.o
+obj-y += lowlevel_init.o
diff --git a/arch/arm/mach-mediatek/mt7629/init.c b/arch/arm/mach-mediatek/mt7629/init.c
new file mode 100644
index 0000000..ba91a6e
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7629/init.c
@@ -0,0 +1,128 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <ram.h>
+#include <asm/arch/misc.h>
+#include <asm/sections.h>
+#include <dm/uclass.h>
+#include <linux/io.h>
+
+#include <dt-bindings/clock/mt7629-clk.h>
+
+#define L2_CFG_BASE 0x10200000
+#define L2_CFG_SIZE 0x1000
+#define L2_SHARE_CFG_MP0 0x7f0
+#define L2_SHARE_MODE_OFF BIT(8)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int mtk_pll_early_init(void)
+{
+ unsigned long pll_rates[] = {
+ [CLK_APMIXED_ARMPLL] = 1250000000,
+ [CLK_APMIXED_MAINPLL] = 1120000000,
+ [CLK_APMIXED_UNIV2PLL] = 1200000000,
+ [CLK_APMIXED_ETH1PLL] = 500000000,
+ [CLK_APMIXED_ETH2PLL] = 700000000,
+ [CLK_APMIXED_SGMIPLL] = 650000000,
+ };
+ struct udevice *dev;
+ int ret, i;
+
+ ret = uclass_get_device_by_driver(UCLASS_CLK,
+ DM_GET_DRIVER(mtk_clk_apmixedsys), &dev);
+ if (ret)
+ return ret;
+
+ /* configure default rate then enable apmixedsys */
+ for (i = 0; i < ARRAY_SIZE(pll_rates); i++) {
+ struct clk clk = { .id = i, .dev = dev };
+
+ ret = clk_set_rate(&clk, pll_rates[i]);
+ if (ret)
+ return ret;
+
+ ret = clk_enable(&clk);
+ if (ret)
+ return ret;
+ }
+
+ /* setup mcu bus */
+ ret = uclass_get_device_by_driver(UCLASS_SYSCON,
+ DM_GET_DRIVER(mtk_mcucfg), &dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int mtk_soc_early_init(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ /* initialize early clocks */
+ ret = mtk_pll_early_init();
+ if (ret)
+ return ret;
+
+ ret = uclass_first_device_err(UCLASS_RAM, &dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int mach_cpu_init(void)
+{
+ void __iomem *base;
+
+ base = ioremap(L2_CFG_BASE, L2_CFG_SIZE);
+
+ /* disable L2C shared mode */
+ writel(L2_SHARE_MODE_OFF, base + L2_SHARE_CFG_MP0);
+
+ return 0;
+}
+
+int dram_init(void)
+{
+ struct ram_info ram;
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_first_device_err(UCLASS_RAM, &dev);
+ if (ret)
+ return ret;
+
+ ret = ram_get_info(dev, &ram);
+ if (ret)
+ return ret;
+
+ debug("RAM init base=%lx, size=%x\n", ram.base, ram.size);
+
+ gd->ram_size = ram.size;
+
+ return 0;
+}
+
+int print_cpuinfo(void)
+{
+ void __iomem *chipid;
+ u32 hwcode, swver;
+
+ chipid = ioremap(VER_BASE, VER_SIZE);
+ hwcode = readl(chipid + APHW_CODE);
+ swver = readl(chipid + APSW_VER);
+
+ printf("CPU: MediaTek MT%04x E%d\n", hwcode, (swver & 0xf) + 1);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mediatek/mt7629/lowlevel_init.S b/arch/arm/mach-mediatek/mt7629/lowlevel_init.S
new file mode 100644
index 0000000..90dd4ea
--- /dev/null
+++ b/arch/arm/mach-mediatek/mt7629/lowlevel_init.S
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+
+#ifndef CONFIG_SPL_BUILD
+ /* Return to U-Boot via saved link register */
+ mov pc, lr
+#else
+ /*
+ * Arch timer :
+ * set CNTFRQ = 20Mhz, set CNTVOFF = 0
+ */
+ movw r0, #0x2d00
+ movt r0, #0x131
+ mcr p15, 0, r0, c14, c0, 0
+
+ /* enable SMP bit */
+ mrc p15, 0, r0, c1, c0, 1
+ orr r0, r0, #0x40
+ mcr p15, 0, r0, c1, c0, 1
+
+ /* if MP core, handle secondary cores */
+ mrc p15, 0, r0, c0, c0, 5
+ ands r1, r0, #0x40000000
+ bne go @ Go if UP
+ ands r0, r0, #0x0f
+ beq go @ Go if core0 on primary core tile
+ b secondary
+
+go:
+ /* master CPU */
+ mov pc, lr
+
+secondary:
+ /* read slave CPU number into r0 firstly */
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #0x0f
+
+loop:
+ dsb
+ isb
+ wfi @Zzz...
+ b loop
+#endif
+ENDPROC(lowlevel_init)
diff --git a/arch/arm/mach-mediatek/spl.c b/arch/arm/mach-mediatek/spl.c
new file mode 100644
index 0000000..9b3590f
--- /dev/null
+++ b/arch/arm/mach-mediatek/spl.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <spl.h>
+
+#include "init.h"
+
+void board_init_f(ulong dummy)
+{
+ int ret;
+
+ ret = spl_early_init();
+ if (ret)
+ hang();
+
+ /* enable console uart printing */
+ preloader_console_init();
+
+ /* soc early initialization */
+ ret = mtk_soc_early_init();
+ if (ret)
+ hang();
+}
+
+u32 spl_boot_device(void)
+{
+#if defined(CONFIG_SPL_SPI_SUPPORT)
+ return BOOT_DEVICE_SPI;
+#elif defined(CONFIG_SPL_MMC_SUPPORT)
+ return BOOT_DEVICE_MMC1;
+#elif defined(CONFIG_SPL_NAND_SUPPORT)
+ return BOOT_DEVICE_NAND;
+#elif defined(CONFIG_SPL_NOR_SUPPORT)
+ return BOOT_DEVICE_NOR;
+#else
+ return BOOT_DEVICE_NONE;
+#endif
+}
diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig
index cc94344..11077bc 100644
--- a/arch/arm/mach-meson/Kconfig
+++ b/arch/arm/mach-meson/Kconfig
@@ -1,89 +1,49 @@
if ARCH_MESON
-config MESON_GXBB
- bool "Support Meson GXBaby"
- select ARM64
- select CLK
- select DM
- select DM_SERIAL
- imply CMD_DM
- help
- The Amlogic Meson GXBaby (S905) is an ARM SoC with a
- quad-core Cortex-A53 CPU and a Mali-450 GPU.
-
-config MESON_GXL
- bool "Support Meson GXL"
+config MESON64_COMMON
+ bool
select ARM64
select CLK
select DM
select DM_SERIAL
+ select SYSCON
+ select REGMAP
+ select BOARD_LATE_INIT
imply CMD_DM
- help
- The Amlogic Meson GXL (S905X and S905D) is an ARM SoC with a
- quad-core Cortex-A53 CPU and a Mali-450 GPU.
-
-config MESON_GXM
- bool "Support Meson GXM"
- select ARM64
- select CLK
- select DM
- select DM_SERIAL
- help
- The Amlogic Meson GXM (S912) is an ARM SoC with an
- octo-core Cortex-A53 CPU and a Mali-T860 GPU.
-
-if MESON_GXBB
-config TARGET_ODROID_C2
- bool "ODROID-C2"
- help
- ODROID-C2 is a single board computer based on Meson GXBaby
- with 2 GiB of RAM, Gigabit Ethernet, HDMI, 4 USB, micro-SD
- slot, eMMC, IR receiver and a 40-pin GPIO header.
+config MESON_GX
+ bool
+ select MESON64_COMMON
-config TARGET_NANOPI_K2
- bool "NANOPI_K2"
- help
- NANOPI_K2 is a single board computer based on Meson GXBaby
- with 2 GiB of RAM, Gigabit Ethernet,AP6212 Wifi, HDMI, 4 USB,
- micro-SD slot, eMMC, IR receiver and a 40-pin GPIO header.
-endif
+choice
+ prompt "Platform select"
+ default MESON_GXBB
-if MESON_GXL
-
-config TARGET_P212
- bool "P212"
+config MESON_GXBB
+ bool "GXBB"
+ select MESON_GX
help
- P212 is a reference dessign board based on Meson GXL S905X SoC
- with 2 GiB of RAM, Ethernet, HDMI, 2 USB, micro-SD slot,
- eMMC, IR receiver, CVBS+Audio jack and a SDIO WiFi module.
+ Select this if your SoC is an S905
-config TARGET_LIBRETECH_CC
- bool "LIBRETECH-CC"
+config MESON_GXL
+ bool "GXL"
+ select MESON_GX
help
- LibreTech CC is a single board computer based on Meson GXL
- with 2 GiB of RAM, Ethernet, HDMI, 4 USB, micro-SD slot,
- eMMC, IR receiver and a 40-pin GPIO header.
+ Select this if your SoC is an S905X/D or S805X
-config TARGET_KHADAS_VIM
- bool "KHADAS-VIM"
+config MESON_GXM
+ bool "GXM"
+ select MESON_GX
help
- Khadas VIM is a single board computer based on Meson GXL
- with 2 GiB of RAM, Ethernet, HDMI, 4 USB, micro-SD slot,
- eMMC, IR receiver and a 40-pin GPIO header.
-
-endif
+ Select this if your SoC is an S912
-if MESON_GXM
-
-config TARGET_KHADAS_VIM2
- bool "KHADAS-VIM2"
+config MESON_AXG
+ bool "AXG"
+ select MESON64_COMMON
help
- Khadas VIM2 is a single board computer based on Meson GXM
- with 2/3 GiB of RAM, Ethernet, HDMI, 4 USB, micro-SD slot,
- eMMC, IR receiver and a 40-pin GPIO header.
+ Select this if your SoC is an A113X/D
-endif
+endchoice
config SYS_SOC
default "meson"
@@ -91,16 +51,32 @@ config SYS_SOC
config SYS_MALLOC_F_LEN
default 0x1000
-source "board/amlogic/odroid-c2/Kconfig"
-
-source "board/amlogic/nanopi-k2/Kconfig"
-
-source "board/amlogic/p212/Kconfig"
-
-source "board/amlogic/libretech-cc/Kconfig"
-
-source "board/amlogic/khadas-vim/Kconfig"
+config SYS_VENDOR
+ string "Vendor name"
+ default "amlogic"
+ help
+ This option contains information about board name.
+ Based on this option board/<CONFIG_SYS_VENDOR>/<CONFIG_SYS_BOARD> will
+ be used.
+
+config SYS_BOARD
+ string "Board name"
+ default "odroid-c2" if MESON_GXBB
+ default "p212" if MESON_GXL
+ default "q200" if MESON_GXM
+ default "s400" if MESON_AXG
+ default ""
+ help
+ This option contains information about board name.
+ Based on this option board/<CONFIG_SYS_VENDOR>/<CONFIG_SYS_BOARD> will
+ be used.
-source "board/amlogic/khadas-vim2/Kconfig"
+config SYS_CONFIG_NAME
+ string "Board configuration name"
+ default "meson64"
+ help
+ This option contains information about board configuration name.
+ Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
+ will be used for board configuration.
endif
diff --git a/arch/arm/mach-meson/Makefile b/arch/arm/mach-meson/Makefile
index 8ad9b3e..b716e1a 100644
--- a/arch/arm/mach-meson/Makefile
+++ b/arch/arm/mach-meson/Makefile
@@ -2,4 +2,6 @@
#
# Copyright (c) 2016 Beniamino Galvani <b.galvani@gmail.com>
-obj-y += board.o sm.o eth.o
+obj-y += board-common.o sm.o
+obj-$(CONFIG_MESON_GX) += board-gx.o
+obj-$(CONFIG_MESON_AXG) += board-axg.o
diff --git a/arch/arm/mach-meson/board-axg.c b/arch/arm/mach-meson/board-axg.c
new file mode 100644
index 0000000..173905e
--- /dev/null
+++ b/arch/arm/mach-meson/board-axg.c
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
+ * (C) Copyright 2018 Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <common.h>
+#include <asm/arch/boot.h>
+#include <asm/arch/eth.h>
+#include <asm/arch/axg.h>
+#include <asm/arch/mem.h>
+#include <asm/io.h>
+#include <asm/armv8/mmu.h>
+#include <linux/sizes.h>
+#include <phy.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int meson_get_boot_device(void)
+{
+ return readl(AXG_AO_SEC_GP_CFG0) & AXG_AO_BOOT_DEVICE;
+}
+
+/* Configure the reserved memory zones exported by the secure registers
+ * into EFI and DTB reserved memory entries.
+ */
+void meson_init_reserved_memory(void *fdt)
+{
+ u64 bl31_size, bl31_start;
+ u64 bl32_size, bl32_start;
+ u32 reg;
+
+ /*
+ * Get ARM Trusted Firmware reserved memory zones in :
+ * - AO_SEC_GP_CFG3: bl32 & bl31 size in KiB, can be 0
+ * - AO_SEC_GP_CFG5: bl31 physical start address, can be NULL
+ * - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL
+ */
+ reg = readl(AXG_AO_SEC_GP_CFG3);
+
+ bl31_size = ((reg & AXG_AO_BL31_RSVMEM_SIZE_MASK)
+ >> AXG_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
+ bl32_size = (reg & AXG_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
+
+ bl31_start = readl(AXG_AO_SEC_GP_CFG5);
+ bl32_start = readl(AXG_AO_SEC_GP_CFG4);
+
+ /* Add BL31 reserved zone */
+ if (bl31_start && bl31_size)
+ meson_board_add_reserved_memory(fdt, bl31_start, bl31_size);
+
+ /* Add BL32 reserved zone */
+ if (bl32_start && bl32_size)
+ meson_board_add_reserved_memory(fdt, bl32_start, bl32_size);
+}
+
+phys_size_t get_effective_memsize(void)
+{
+ /* Size is reported in MiB, convert it in bytes */
+ return ((readl(AXG_AO_SEC_GP_CFG0) & AXG_AO_MEM_SIZE_MASK)
+ >> AXG_AO_MEM_SIZE_SHIFT) * SZ_1M;
+}
+
+static struct mm_region axg_mem_map[] = {
+ {
+ .virt = 0x0UL,
+ .phys = 0x0UL,
+ .size = 0x80000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE
+ }, {
+ .virt = 0xf0000000UL,
+ .phys = 0xf0000000UL,
+ .size = 0x10000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* List terminator */
+ 0,
+ }
+};
+
+struct mm_region *mem_map = axg_mem_map;
+
+/* Configure the Ethernet MAC with the requested interface mode
+ * with some optional flags.
+ */
+void meson_eth_init(phy_interface_t mode, unsigned int flags)
+{
+ switch (mode) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ /* Set RGMII mode */
+ setbits_le32(AXG_ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RGMII |
+ AXG_ETH_REG_0_TX_PHASE(1) |
+ AXG_ETH_REG_0_TX_RATIO(4) |
+ AXG_ETH_REG_0_PHY_CLK_EN |
+ AXG_ETH_REG_0_CLK_EN);
+ break;
+
+ case PHY_INTERFACE_MODE_RMII:
+ /* Set RMII mode */
+ out_le32(AXG_ETH_REG_0, AXG_ETH_REG_0_PHY_INTF_RMII |
+ AXG_ETH_REG_0_INVERT_RMII_CLK |
+ AXG_ETH_REG_0_CLK_EN);
+ break;
+
+ default:
+ printf("Invalid Ethernet interface mode\n");
+ return;
+ }
+
+ /* Enable power gate */
+ clrbits_le32(AXG_MEM_PD_REG_0, AXG_MEM_PD_REG_0_ETH_MASK);
+}
diff --git a/arch/arm/mach-meson/board-common.c b/arch/arm/mach-meson/board-common.c
new file mode 100644
index 0000000..8c41301
--- /dev/null
+++ b/arch/arm/mach-meson/board-common.c
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
+ */
+
+#include <common.h>
+#include <asm/arch/boot.h>
+#include <linux/libfdt.h>
+#include <linux/err.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/sm.h>
+#include <asm/armv8/mmu.h>
+#include <asm/unaligned.h>
+#include <efi_loader.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+__weak int board_init(void)
+{
+ return 0;
+}
+
+int dram_init(void)
+{
+ const fdt64_t *val;
+ int offset;
+ int len;
+
+ offset = fdt_path_offset(gd->fdt_blob, "/memory");
+ if (offset < 0)
+ return -EINVAL;
+
+ val = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
+ if (len < sizeof(*val) * 2)
+ return -EINVAL;
+
+ /* Use unaligned access since cache is still disabled */
+ gd->ram_size = get_unaligned_be64(&val[1]);
+
+ return 0;
+}
+
+__weak int meson_ft_board_setup(void *blob, bd_t *bd)
+{
+ return 0;
+}
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+ meson_init_reserved_memory(blob);
+
+ return meson_ft_board_setup(blob, bd);
+}
+
+void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size)
+{
+ int ret;
+
+ ret = fdt_add_mem_rsv(fdt, start, size);
+ if (ret)
+ printf("Could not reserve zone @ 0x%llx\n", start);
+
+ if (IS_ENABLED(CONFIG_EFI_LOADER)) {
+ efi_add_memory_map(start,
+ ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
+ EFI_RESERVED_MEMORY_TYPE, false);
+ }
+}
+
+static void meson_set_boot_source(void)
+{
+ const char *source;
+
+ switch (meson_get_boot_device()) {
+ case BOOT_DEVICE_EMMC:
+ source = "emmc";
+ break;
+
+ case BOOT_DEVICE_NAND:
+ source = "nand";
+ break;
+
+ case BOOT_DEVICE_SPI:
+ source = "spi";
+ break;
+
+ case BOOT_DEVICE_SD:
+ source = "sd";
+ break;
+
+ case BOOT_DEVICE_USB:
+ source = "usb";
+ break;
+
+ default:
+ source = "unknown";
+ }
+
+ env_set("boot_source", source);
+}
+
+__weak int meson_board_late_init(void)
+{
+ return 0;
+}
+
+int board_late_init(void)
+{
+ meson_set_boot_source();
+
+ return meson_board_late_init();
+}
+
+void reset_cpu(ulong addr)
+{
+ psci_system_reset();
+}
diff --git a/arch/arm/mach-meson/board.c b/arch/arm/mach-meson/board-gx.c
index d6c6253..e41552d 100644
--- a/arch/arm/mach-meson/board.c
+++ b/arch/arm/mach-meson/board-gx.c
@@ -1,64 +1,30 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
+ * (C) Copyright 2018 Neil Armstrong <narmstrong@baylibre.com>
*/
#include <common.h>
-#include <linux/libfdt.h>
-#include <linux/err.h>
+#include <asm/arch/boot.h>
+#include <asm/arch/eth.h>
#include <asm/arch/gx.h>
-#include <asm/arch/sm.h>
+#include <asm/arch/mem.h>
+#include <asm/io.h>
#include <asm/armv8/mmu.h>
-#include <asm/unaligned.h>
#include <linux/sizes.h>
-#include <efi_loader.h>
-#include <asm/io.h>
+#include <phy.h>
DECLARE_GLOBAL_DATA_PTR;
-int dram_init(void)
-{
- const fdt64_t *val;
- int offset;
- int len;
-
- offset = fdt_path_offset(gd->fdt_blob, "/memory");
- if (offset < 0)
- return -EINVAL;
-
- val = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
- if (len < sizeof(*val) * 2)
- return -EINVAL;
-
- /* Use unaligned access since cache is still disabled */
- gd->ram_size = get_unaligned_be64(&val[1]);
-
- return 0;
-}
-
-phys_size_t get_effective_memsize(void)
+int meson_get_boot_device(void)
{
- /* Size is reported in MiB, convert it in bytes */
- return ((readl(GX_AO_SEC_GP_CFG0) & GX_AO_MEM_SIZE_MASK)
- >> GX_AO_MEM_SIZE_SHIFT) * SZ_1M;
+ return readl(GX_AO_SEC_GP_CFG0) & GX_AO_BOOT_DEVICE;
}
-static void meson_board_add_reserved_memory(void *fdt, u64 start, u64 size)
-{
- int ret;
-
- ret = fdt_add_mem_rsv(fdt, start, size);
- if (ret)
- printf("Could not reserve zone @ 0x%llx\n", start);
-
- if (IS_ENABLED(CONFIG_EFI_LOADER)) {
- efi_add_memory_map(start,
- ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
- EFI_RESERVED_MEMORY_TYPE, false);
- }
-}
-
-void meson_gx_init_reserved_memory(void *fdt)
+/* Configure the reserved memory zones exported by the secure registers
+ * into EFI and DTB reserved memory entries.
+ */
+void meson_init_reserved_memory(void *fdt)
{
u64 bl31_size, bl31_start;
u64 bl32_size, bl32_start;
@@ -70,7 +36,6 @@ void meson_gx_init_reserved_memory(void *fdt)
* - AO_SEC_GP_CFG5: bl31 physical start address, can be NULL
* - AO_SEC_GP_CFG4: bl32 physical start address, can be NULL
*/
-
reg = readl(GX_AO_SEC_GP_CFG3);
bl31_size = ((reg & GX_AO_BL31_RSVMEM_SIZE_MASK)
@@ -102,9 +67,11 @@ void meson_gx_init_reserved_memory(void *fdt)
meson_board_add_reserved_memory(fdt, bl32_start, bl32_size);
}
-void reset_cpu(ulong addr)
+phys_size_t get_effective_memsize(void)
{
- psci_system_reset();
+ /* Size is reported in MiB, convert it in bytes */
+ return ((readl(GX_AO_SEC_GP_CFG0) & GX_AO_MEM_SIZE_MASK)
+ >> GX_AO_MEM_SIZE_SHIFT) * SZ_1M;
}
static struct mm_region gx_mem_map[] = {
@@ -128,3 +95,44 @@ static struct mm_region gx_mem_map[] = {
};
struct mm_region *mem_map = gx_mem_map;
+
+/* Configure the Ethernet MAC with the requested interface mode
+ * with some optional flags.
+ */
+void meson_eth_init(phy_interface_t mode, unsigned int flags)
+{
+ switch (mode) {
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ /* Set RGMII mode */
+ setbits_le32(GX_ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
+ GX_ETH_REG_0_TX_PHASE(1) |
+ GX_ETH_REG_0_TX_RATIO(4) |
+ GX_ETH_REG_0_PHY_CLK_EN |
+ GX_ETH_REG_0_CLK_EN);
+ break;
+
+ case PHY_INTERFACE_MODE_RMII:
+ /* Set RMII mode */
+ out_le32(GX_ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK |
+ GX_ETH_REG_0_CLK_EN);
+
+ /* Use GXL RMII Internal PHY */
+ if (IS_ENABLED(CONFIG_MESON_GXL) &&
+ (flags & MESON_USE_INTERNAL_RMII_PHY)) {
+ writel(0x10110181, GX_ETH_REG_2);
+ writel(0xe40908ff, GX_ETH_REG_3);
+ }
+
+ break;
+
+ default:
+ printf("Invalid Ethernet interface mode\n");
+ return;
+ }
+
+ /* Enable power gate */
+ clrbits_le32(GX_MEM_PD_REG_0, GX_MEM_PD_REG_0_ETH_MASK);
+}
diff --git a/arch/arm/mach-meson/eth.c b/arch/arm/mach-meson/eth.c
deleted file mode 100644
index 8b28bc8..0000000
--- a/arch/arm/mach-meson/eth.c
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#include <common.h>
-#include <dm.h>
-#include <asm/io.h>
-#include <asm/arch/gx.h>
-#include <asm/arch/eth.h>
-#include <phy.h>
-
-/* Configure the Ethernet MAC with the requested interface mode
- * with some optional flags.
- */
-void meson_gx_eth_init(phy_interface_t mode, unsigned int flags)
-{
- switch (mode) {
- case PHY_INTERFACE_MODE_RGMII:
- case PHY_INTERFACE_MODE_RGMII_ID:
- case PHY_INTERFACE_MODE_RGMII_RXID:
- case PHY_INTERFACE_MODE_RGMII_TXID:
- /* Set RGMII mode */
- setbits_le32(GX_ETH_REG_0, GX_ETH_REG_0_PHY_INTF |
- GX_ETH_REG_0_TX_PHASE(1) |
- GX_ETH_REG_0_TX_RATIO(4) |
- GX_ETH_REG_0_PHY_CLK_EN |
- GX_ETH_REG_0_CLK_EN);
- break;
-
- case PHY_INTERFACE_MODE_RMII:
- /* Set RMII mode */
- out_le32(GX_ETH_REG_0, GX_ETH_REG_0_INVERT_RMII_CLK |
- GX_ETH_REG_0_CLK_EN);
-
- /* Use GXL RMII Internal PHY */
- if (IS_ENABLED(CONFIG_MESON_GXL) &&
- (flags & MESON_GXL_USE_INTERNAL_RMII_PHY)) {
- writel(0x10110181, GX_ETH_REG_2);
- writel(0xe40908ff, GX_ETH_REG_3);
- }
-
- break;
-
- default:
- printf("Invalid Ethernet interface mode\n");
- return;
- }
-
- /* Enable power gate */
- clrbits_le32(GX_MEM_PD_REG_0, GX_MEM_PD_REG_0_ETH_MASK);
-}
diff --git a/arch/arm/mach-meson/sm.c b/arch/arm/mach-meson/sm.c
index 0bba5e4..a07b468 100644
--- a/arch/arm/mach-meson/sm.c
+++ b/arch/arm/mach-meson/sm.c
@@ -6,7 +6,6 @@
*/
#include <common.h>
-#include <asm/arch/gx.h>
#include <linux/kernel.h>
#define FN_GET_SHARE_MEM_INPUT_BASE 0x82000020
diff --git a/board/amlogic/khadas-vim/Kconfig b/board/amlogic/khadas-vim/Kconfig
deleted file mode 100644
index 0fa8db9..0000000
--- a/board/amlogic/khadas-vim/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_KHADAS_VIM
-
-config SYS_BOARD
- default "khadas-vim"
-
-config SYS_VENDOR
- default "amlogic"
-
-config SYS_CONFIG_NAME
- default "khadas-vim"
-
-endif
diff --git a/board/amlogic/khadas-vim/MAINTAINERS b/board/amlogic/khadas-vim/MAINTAINERS
deleted file mode 100644
index 024220a..0000000
--- a/board/amlogic/khadas-vim/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-KHADAS-VIM
-M: Neil Armstrong <narmstrong@baylibre.com>
-S: Maintained
-F: board/amlogic/khadas-vim/
-F: include/configs/khadas-vim.h
-F: configs/khadas-vim_defconfig
diff --git a/board/amlogic/khadas-vim/khadas-vim.c b/board/amlogic/khadas-vim/khadas-vim.c
deleted file mode 100644
index 692bf2a..0000000
--- a/board/amlogic/khadas-vim/khadas-vim.c
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#include <common.h>
-#include <dm.h>
-#include <environment.h>
-#include <asm/io.h>
-#include <asm/arch/gx.h>
-#include <asm/arch/mem.h>
-#include <asm/arch/sm.h>
-#include <asm/arch/eth.h>
-
-#define EFUSE_SN_OFFSET 20
-#define EFUSE_SN_SIZE 16
-#define EFUSE_MAC_OFFSET 52
-#define EFUSE_MAC_SIZE 6
-
-int board_init(void)
-{
- return 0;
-}
-
-int misc_init_r(void)
-{
- u8 mac_addr[EFUSE_MAC_SIZE];
- char serial[EFUSE_SN_SIZE];
- ssize_t len;
-
- meson_gx_eth_init(PHY_INTERFACE_MODE_RMII,
- MESON_GXL_USE_INTERNAL_RMII_PHY);
-
- if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
- len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
- mac_addr, EFUSE_MAC_SIZE);
- if (len == EFUSE_MAC_SIZE && is_valid_ethaddr(mac_addr))
- eth_env_set_enetaddr("ethaddr", mac_addr);
- }
-
- if (!env_get("serial#")) {
- len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
- EFUSE_SN_SIZE);
- if (len == EFUSE_SN_SIZE)
- env_set("serial#", serial);
- }
-
- return 0;
-}
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
- meson_gx_init_reserved_memory(blob);
-
- return 0;
-}
diff --git a/board/amlogic/khadas-vim2/Kconfig b/board/amlogic/khadas-vim2/Kconfig
deleted file mode 100644
index d0af362..0000000
--- a/board/amlogic/khadas-vim2/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_KHADAS_VIM2
-
-config SYS_BOARD
- default "khadas-vim2"
-
-config SYS_VENDOR
- default "amlogic"
-
-config SYS_CONFIG_NAME
- default "khadas-vim2"
-
-endif
diff --git a/board/amlogic/libretech-cc/Kconfig b/board/amlogic/libretech-cc/Kconfig
deleted file mode 100644
index 7a6f916..0000000
--- a/board/amlogic/libretech-cc/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_LIBRETECH_CC
-
-config SYS_BOARD
- default "libretech-cc"
-
-config SYS_VENDOR
- default "amlogic"
-
-config SYS_CONFIG_NAME
- default "libretech-cc"
-
-endif
diff --git a/board/amlogic/libretech-cc/MAINTAINERS b/board/amlogic/libretech-cc/MAINTAINERS
deleted file mode 100644
index 398ce57..0000000
--- a/board/amlogic/libretech-cc/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-LIBRETECH-CC
-M: Neil Armstrong <narmstrong@baylibre.com>
-S: Maintained
-F: board/amlogic/libretech-cc/
-F: include/configs/libretech-cc.h
-F: configs/libretech-cc_defconfig
diff --git a/board/amlogic/libretech-cc/Makefile b/board/amlogic/libretech-cc/Makefile
deleted file mode 100644
index 3b0adf8..0000000
--- a/board/amlogic/libretech-cc/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0+
-#
-# (C) Copyright 2016 BayLibre, SAS
-# Author: Neil Armstrong <narmstrong@baylibre.com>
-
-obj-y := libretech-cc.o
diff --git a/board/amlogic/libretech-cc/libretech-cc.c b/board/amlogic/libretech-cc/libretech-cc.c
deleted file mode 100644
index ccab127..0000000
--- a/board/amlogic/libretech-cc/libretech-cc.c
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2016 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#include <common.h>
-#include <dm.h>
-#include <environment.h>
-#include <asm/io.h>
-#include <asm/arch/gx.h>
-#include <asm/arch/sm.h>
-#include <asm/arch/eth.h>
-#include <asm/arch/mem.h>
-
-#define EFUSE_SN_OFFSET 20
-#define EFUSE_SN_SIZE 16
-#define EFUSE_MAC_OFFSET 52
-#define EFUSE_MAC_SIZE 6
-
-int board_init(void)
-{
- return 0;
-}
-
-int misc_init_r(void)
-{
- u8 mac_addr[EFUSE_MAC_SIZE];
- char serial[EFUSE_SN_SIZE];
- ssize_t len;
-
- meson_gx_eth_init(PHY_INTERFACE_MODE_RMII,
- MESON_GXL_USE_INTERNAL_RMII_PHY);
-
- if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
- len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
- mac_addr, EFUSE_MAC_SIZE);
- if (len == EFUSE_MAC_SIZE && is_valid_ethaddr(mac_addr))
- eth_env_set_enetaddr("ethaddr", mac_addr);
- }
-
- if (!env_get("serial#")) {
- len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
- EFUSE_SN_SIZE);
- if (len == EFUSE_SN_SIZE)
- env_set("serial#", serial);
- }
-
- return 0;
-}
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
- meson_gx_init_reserved_memory(blob);
-
- return 0;
-}
diff --git a/board/amlogic/nanopi-k2/Kconfig b/board/amlogic/nanopi-k2/Kconfig
deleted file mode 100644
index 374bda2..0000000
--- a/board/amlogic/nanopi-k2/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_NANOPI_K2
-
-config SYS_BOARD
- default "nanopi-k2"
-
-config SYS_VENDOR
- default "amlogic"
-
-config SYS_CONFIG_NAME
- default "nanopi-k2"
-
-endif
diff --git a/board/amlogic/nanopi-k2/MAINTAINERS b/board/amlogic/nanopi-k2/MAINTAINERS
deleted file mode 100644
index 0452bd1..0000000
--- a/board/amlogic/nanopi-k2/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-NANOPI-K2
-M: Neil Armstrong <narmstrong@baylibre.com>
-S: Maintained
-F: board/amlogic/nanopi-k2/
-F: include/configs/nanopi-k2.h
-F: configs/nanopi-k2_defconfig
diff --git a/board/amlogic/nanopi-k2/Makefile b/board/amlogic/nanopi-k2/Makefile
deleted file mode 100644
index 7d9b666..0000000
--- a/board/amlogic/nanopi-k2/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# (C) Copyright 2018 Thomas McKahan
-#
-# SPDX-License-Identifier: GPL-2.0+
-#
-
-obj-y := nanopi-k2.o
diff --git a/board/amlogic/nanopi-k2/nanopi-k2.c b/board/amlogic/nanopi-k2/nanopi-k2.c
deleted file mode 100644
index ae29dd6..0000000
--- a/board/amlogic/nanopi-k2/nanopi-k2.c
+++ /dev/null
@@ -1,55 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2018 Thomas McKahan
- */
-
-#include <common.h>
-#include <dm.h>
-#include <environment.h>
-#include <asm/io.h>
-#include <asm/arch/gx.h>
-#include <asm/arch/sm.h>
-#include <asm/arch/eth.h>
-#include <asm/arch/mem.h>
-
-#define EFUSE_SN_OFFSET 20
-#define EFUSE_SN_SIZE 16
-#define EFUSE_MAC_OFFSET 52
-#define EFUSE_MAC_SIZE 6
-
-int board_init(void)
-{
- return 0;
-}
-
-int misc_init_r(void)
-{
- u8 mac_addr[EFUSE_MAC_SIZE];
- char serial[EFUSE_SN_SIZE];
- ssize_t len;
-
- meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
-
- if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
- len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
- mac_addr, EFUSE_MAC_SIZE);
- if (len == EFUSE_MAC_SIZE && is_valid_ethaddr(mac_addr))
- eth_env_set_enetaddr("ethaddr", mac_addr);
- }
-
- if (!env_get("serial#")) {
- len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
- EFUSE_SN_SIZE);
- if (len == EFUSE_SN_SIZE)
- env_set("serial#", serial);
- }
-
- return 0;
-}
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
- meson_gx_init_reserved_memory(blob);
-
- return 0;
-}
diff --git a/board/amlogic/odroid-c2/Kconfig b/board/amlogic/odroid-c2/Kconfig
deleted file mode 100644
index 2b16889..0000000
--- a/board/amlogic/odroid-c2/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_ODROID_C2
-
-config SYS_BOARD
- default "odroid-c2"
-
-config SYS_VENDOR
- default "amlogic"
-
-config SYS_CONFIG_NAME
- default "odroid-c2"
-
-endif
diff --git a/board/amlogic/odroid-c2/MAINTAINERS b/board/amlogic/odroid-c2/MAINTAINERS
index 699850f..6a85306 100644
--- a/board/amlogic/odroid-c2/MAINTAINERS
+++ b/board/amlogic/odroid-c2/MAINTAINERS
@@ -1,6 +1,8 @@
ODROID-C2
M: Beniamino Galvani <b.galvani@gmail.com>
+M: Neil Armstrong <narmstrong@baylibre.com>
S: Maintained
F: board/amlogic/odroid-c2/
F: include/configs/odroid-c2.h
+F: configs/nanopi-k2_defconfig
F: configs/odroid-c2_defconfig
diff --git a/board/amlogic/nanopi-k2/README b/board/amlogic/odroid-c2/README.nanopi-k2
index d450d3c..d450d3c 100644
--- a/board/amlogic/nanopi-k2/README
+++ b/board/amlogic/odroid-c2/README.nanopi-k2
diff --git a/board/amlogic/odroid-c2/README b/board/amlogic/odroid-c2/README.odroid-c2
index bed48c5..bed48c5 100644
--- a/board/amlogic/odroid-c2/README
+++ b/board/amlogic/odroid-c2/README.odroid-c2
diff --git a/board/amlogic/odroid-c2/odroid-c2.c b/board/amlogic/odroid-c2/odroid-c2.c
index 2a2755c..62f0f4c 100644
--- a/board/amlogic/odroid-c2/odroid-c2.c
+++ b/board/amlogic/odroid-c2/odroid-c2.c
@@ -17,18 +17,13 @@
#define EFUSE_MAC_OFFSET 52
#define EFUSE_MAC_SIZE 6
-int board_init(void)
-{
- return 0;
-}
-
int misc_init_r(void)
{
u8 mac_addr[EFUSE_MAC_SIZE];
char serial[EFUSE_SN_SIZE];
ssize_t len;
- meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
+ meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
@@ -40,16 +35,9 @@ int misc_init_r(void)
if (!env_get("serial#")) {
len = meson_sm_read_efuse(EFUSE_SN_OFFSET, serial,
EFUSE_SN_SIZE);
- if (len == EFUSE_SN_SIZE)
+ if (len == EFUSE_SN_SIZE)
env_set("serial#", serial);
}
return 0;
}
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
- meson_gx_init_reserved_memory(blob);
-
- return 0;
-}
diff --git a/board/amlogic/p212/Kconfig b/board/amlogic/p212/Kconfig
deleted file mode 100644
index 720c92b..0000000
--- a/board/amlogic/p212/Kconfig
+++ /dev/null
@@ -1,12 +0,0 @@
-if TARGET_P212
-
-config SYS_BOARD
- default "p212"
-
-config SYS_VENDOR
- default "amlogic"
-
-config SYS_CONFIG_NAME
- default "p212"
-
-endif
diff --git a/board/amlogic/p212/MAINTAINERS b/board/amlogic/p212/MAINTAINERS
index 6575f17..07ca6f2 100644
--- a/board/amlogic/p212/MAINTAINERS
+++ b/board/amlogic/p212/MAINTAINERS
@@ -3,4 +3,6 @@ M: Neil Armstrong <narmstrong@baylibre.com>
S: Maintained
F: board/amlogic/p212/
F: include/configs/p212.h
+F: configs/khadas-vim_defconfig
+F: configs/libretech-cc_defconfig
F: configs/p212_defconfig
diff --git a/board/amlogic/khadas-vim/README b/board/amlogic/p212/README.khadas-vim
index b194236..b194236 100644
--- a/board/amlogic/khadas-vim/README
+++ b/board/amlogic/p212/README.khadas-vim
diff --git a/board/amlogic/libretech-cc/README b/board/amlogic/p212/README.libretech-cc
index d007f58..d007f58 100644
--- a/board/amlogic/libretech-cc/README
+++ b/board/amlogic/p212/README.libretech-cc
diff --git a/board/amlogic/p212/README b/board/amlogic/p212/README.p212
index ef5370c..ef5370c 100644
--- a/board/amlogic/p212/README
+++ b/board/amlogic/p212/README.p212
diff --git a/board/amlogic/p212/p212.c b/board/amlogic/p212/p212.c
index 00e07d7..546c4d9 100644
--- a/board/amlogic/p212/p212.c
+++ b/board/amlogic/p212/p212.c
@@ -18,19 +18,14 @@
#define EFUSE_MAC_OFFSET 52
#define EFUSE_MAC_SIZE 6
-int board_init(void)
-{
- return 0;
-}
-
int misc_init_r(void)
{
u8 mac_addr[EFUSE_MAC_SIZE];
char serial[EFUSE_SN_SIZE];
ssize_t len;
- meson_gx_eth_init(PHY_INTERFACE_MODE_RMII,
- MESON_GXL_USE_INTERNAL_RMII_PHY);
+ meson_eth_init(PHY_INTERFACE_MODE_RMII,
+ MESON_USE_INTERNAL_RMII_PHY);
if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
@@ -48,10 +43,3 @@ int misc_init_r(void)
return 0;
}
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
- meson_gx_init_reserved_memory(blob);
-
- return 0;
-}
diff --git a/board/amlogic/khadas-vim2/MAINTAINERS b/board/amlogic/q200/MAINTAINERS
index ca63e31..be86386 100644
--- a/board/amlogic/khadas-vim2/MAINTAINERS
+++ b/board/amlogic/q200/MAINTAINERS
@@ -1,6 +1,6 @@
-KHADAS-VIM2
+Q200
M: Neil Armstrong <narmstrong@baylibre.com>
S: Maintained
-F: board/amlogic/khadas-vim2/
-F: include/configs/khadas-vim2.h
+F: board/amlogic/q200/
+F: include/configs/q200.h
F: configs/khadas-vim2_defconfig
diff --git a/board/amlogic/khadas-vim/Makefile b/board/amlogic/q200/Makefile
index 558c076..fd78fd0 100644
--- a/board/amlogic/khadas-vim/Makefile
+++ b/board/amlogic/q200/Makefile
@@ -3,4 +3,4 @@
# (C) Copyright 2016 BayLibre, SAS
# Author: Neil Armstrong <narmstrong@baylibre.com>
-obj-y := khadas-vim.o
+obj-y := q200.o
diff --git a/board/amlogic/khadas-vim2/README b/board/amlogic/q200/README.khadas-vim2
index 578693f..578693f 100644
--- a/board/amlogic/khadas-vim2/README
+++ b/board/amlogic/q200/README.khadas-vim2
diff --git a/board/amlogic/q200/README.q200 b/board/amlogic/q200/README.q200
new file mode 100644
index 0000000..55d730a
--- /dev/null
+++ b/board/amlogic/q200/README.q200
@@ -0,0 +1,102 @@
+U-Boot for Amlogic Q200
+=======================
+
+Q200 is a reference board manufactured by Amlogic with the following
+specifications:
+
+ - Amlogic S912 ARM Cortex-A53 octo-core SoC @ 1.5GHz
+ - ARM Mali T860 GPU
+ - 2/3GB DDR4 SDRAM
+ - 10/100/1000 Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 2 x USB 2.0 Host, 1 x USB 2.0 Device
+ - 16GB/32GB/64GB eMMC
+ - 2MB SPI Flash
+ - microSD
+ - SDIO Wifi Module, Bluetooth
+ - IR receiver
+
+Currently the u-boot port supports the following devices:
+ - serial
+ - eMMC, microSD
+ - Ethernet
+ - I2C
+ - Regulators
+ - Reset controller
+ - Clock controller
+ - USB Host
+ - ADC
+
+U-Boot compilation
+==================
+
+ > export ARCH=arm
+ > export CROSS_COMPILE=aarch64-none-elf-
+ > make khadas-vim2_defconfig
+ > make
+
+Image creation
+==============
+
+Amlogic doesn't provide sources for the firmware and for tools needed
+to create the bootloader image, so it is necessary to obtain them from
+the git tree published by the board vendor:
+
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH
+ > git clone https://github.com/BayLibre/u-boot.git -b n-amlogic-openlinux-20170606 amlogic-u-boot
+ > cd amlogic-u-boot
+ > make gxm_q200_v1_defconfig
+ > make
+ > export FIPDIR=$PWD/fip
+
+Go back to mainline U-Boot source tree then :
+ > mkdir fip
+
+ > cp $FIPDIR/gxl/bl2.bin fip/
+ > cp $FIPDIR/gxl/acs.bin fip/
+ > cp $FIPDIR/gxl/bl21.bin fip/
+ > cp $FIPDIR/gxl/bl30.bin fip/
+ > cp $FIPDIR/gxl/bl301.bin fip/
+ > cp $FIPDIR/gxl/bl31.img fip/
+ > cp u-boot.bin fip/bl33.bin
+
+ > $FIPDIR/blx_fix.sh \
+ fip/bl30.bin \
+ fip/zero_tmp \
+ fip/bl30_zero.bin \
+ fip/bl301.bin \
+ fip/bl301_zero.bin \
+ fip/bl30_new.bin \
+ bl30
+
+ > python $FIPDIR/acs_tool.pyc fip/bl2.bin fip/bl2_acs.bin fip/acs.bin 0
+
+ > $FIPDIR/blx_fix.sh \
+ fip/bl2_acs.bin \
+ fip/zero_tmp \
+ fip/bl2_zero.bin \
+ fip/bl21.bin \
+ fip/bl21_zero.bin \
+ fip/bl2_new.bin \
+ bl2
+
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl30_new.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl31.img
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl3enc --input fip/bl33.bin
+ > $FIPDIR/gxl/aml_encrypt_gxl --bl2sig --input fip/bl2_new.bin --output fip/bl2.n.bin.sig
+ > $FIPDIR/gxl/aml_encrypt_gxl --bootmk \
+ --output fip/u-boot.bin \
+ --bl2 fip/bl2.n.bin.sig \
+ --bl30 fip/bl30_new.bin.enc \
+ --bl31 fip/bl31.img.enc \
+ --bl33 fip/bl33.bin.enc
+
+and then write the image to SD with:
+
+ > DEV=/dev/your_sd_device
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444
diff --git a/board/amlogic/khadas-vim2/khadas-vim2.c b/board/amlogic/q200/q200.c
index ff56569..6db1b26 100644
--- a/board/amlogic/khadas-vim2/khadas-vim2.c
+++ b/board/amlogic/q200/q200.c
@@ -18,18 +18,13 @@
#define EFUSE_MAC_OFFSET 52
#define EFUSE_MAC_SIZE 6
-int board_init(void)
-{
- return 0;
-}
-
int misc_init_r(void)
{
u8 mac_addr[EFUSE_MAC_SIZE];
char serial[EFUSE_SN_SIZE];
ssize_t len;
- meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
+ meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
/* Reset PHY on GPIOZ_14 */
clrbits_le32(GX_GPIO_EN(3), BIT(14));
@@ -53,10 +48,3 @@ int misc_init_r(void)
return 0;
}
-
-int ft_board_setup(void *blob, bd_t *bd)
-{
- meson_gx_init_reserved_memory(blob);
-
- return 0;
-}
diff --git a/board/amlogic/s400/MAINTAINERS b/board/amlogic/s400/MAINTAINERS
new file mode 100644
index 0000000..9ca9836
--- /dev/null
+++ b/board/amlogic/s400/MAINTAINERS
@@ -0,0 +1,6 @@
+S400
+M: Neil Armstrong <narmstrong@baylibre.com>
+S: Maintained
+F: board/amlogic/s400/
+F: include/configs/s400.h
+F: configs/s400_defconfig
diff --git a/board/amlogic/khadas-vim2/Makefile b/board/amlogic/s400/Makefile
index 4e7c9a0..bf03862 100644
--- a/board/amlogic/khadas-vim2/Makefile
+++ b/board/amlogic/s400/Makefile
@@ -3,4 +3,4 @@
# (C) Copyright 2016 BayLibre, SAS
# Author: Neil Armstrong <narmstrong@baylibre.com>
-obj-y := khadas-vim2.o
+obj-y := s400.o
diff --git a/board/amlogic/s400/README b/board/amlogic/s400/README
new file mode 100644
index 0000000..ab21998
--- /dev/null
+++ b/board/amlogic/s400/README
@@ -0,0 +1,110 @@
+U-Boot for Amlogic S400
+=======================
+
+S400 is a reference board manufactured by Amlogic with the following
+specifications:
+
+ - Amlogic A113DX ARM Cortex-A53 quad-core SoC @ 1.2GHz
+ - 1GB DDR4 SDRAM
+ - 10/100 Ethernet
+ - 2 x USB 2.0 Host
+ - eMMC
+ - Infrared receiver
+ - SDIO WiFi Module
+ - MIPI DSI Connector
+ - Audio HAT Connector
+ - PCI-E M.2 Connectors
+
+Schematics are available from Amlogic on demand.
+
+Currently the u-boot port supports the following devices:
+ - serial
+ - eMMC
+ - Ethernet
+ - I2C
+ - Regulators
+ - Reset controller
+ - Clock controller
+ - USB Host
+ - ADC
+
+u-boot compilation
+==================
+
+ > export ARCH=arm
+ > export CROSS_COMPILE=aarch64-none-elf-
+ > make s400_defconfig
+ > make
+
+Image creation
+==============
+
+Amlogic doesn't provide sources for the firmware and for tools needed
+to create the bootloader image, so it is necessary to obtain them from
+the git tree published by the board vendor:
+
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > wget https://releases.linaro.org/archive/13.11/components/toolchain/binaries/gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz
+ > tar xvfJ gcc-linaro-arm-none-eabi-4.8-2013.11_linux.tar.xz
+ > export PATH=$PWD/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux/bin:$PWD/gcc-linaro-arm-none-eabi-4.8-2013.11_linux/bin:$PATH
+ > git clone https://github.com/BayLibre/u-boot.git -b n-amlogic-openlinux-20170606 amlogic-u-boot
+ > cd amlogic-u-boot
+ > make axg_s400_v1_defconfig
+ > make
+ > export FIPDIR=$PWD/fip
+
+Go back to mainline U-boot source tree then :
+ > mkdir fip
+
+ > cp $FIPDIR/axg/bl2.bin fip/
+ > cp $FIPDIR/axg/acs.bin fip/
+ > cp $FIPDIR/axg/bl21.bin fip/
+ > cp $FIPDIR/axg/bl30.bin fip/
+ > cp $FIPDIR/axg/bl301.bin fip/
+ > cp $FIPDIR/axg/bl31.img fip/
+ > cp u-boot.bin fip/bl33.bin
+
+ > $FIPDIR/blx_fix.sh \
+ fip/bl30.bin \
+ fip/zero_tmp \
+ fip/bl30_zero.bin \
+ fip/bl301.bin \
+ fip/bl301_zero.bin \
+ fip/bl30_new.bin \
+ bl30
+
+ > $FIPDIR/acs_tool.pyc fip/bl2.bin fip/bl2_acs.bin fip/acs.bin 0
+
+ > $FIPDIR/blx_fix.sh \
+ fip/bl2_acs.bin \
+ fip/zero_tmp \
+ fip/bl2_zero.bin \
+ fip/bl21.bin \
+ fip/bl21_zero.bin \
+ fip/bl2_new.bin \
+ bl2
+
+ > $FIPDIR/axg/aml_encrypt_axg --bl3sig --input fip/bl30_new.bin \
+ --output fip/bl30_new.bin.enc \
+ --level v3 --type bl30
+ > $FIPDIR/axg/aml_encrypt_axg --bl3sig --input fip/bl31.img \
+ --output fip/bl31.img.enc \
+ --level v3 --type bl31
+ > $FIPDIR/axg/aml_encrypt_axg --bl3sig --input fip/bl33.bin --compress lz4 \
+ --output fip/bl33.bin.enc \
+ --level v3 --type bl33
+ > $FIPDIR/axg/aml_encrypt_axg --bl2sig --input fip/bl2_new.bin \
+ --output fip/bl2.n.bin.sig
+ > $FIPDIR/axg/aml_encrypt_axg --bootmk \
+ --output fip/u-boot.bin \
+ --bl2 fip/bl2.n.bin.sig \
+ --bl30 fip/bl30_new.bin.enc \
+ --bl31 fip/bl31.img.enc \
+ --bl33 fip/bl33.bin.enc --level v3
+
+and then write the image to SD with:
+
+ > DEV=/dev/your_sd_device
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=512 skip=1 seek=1
+ > dd if=fip/u-boot.bin.sd.bin of=$DEV conv=fsync,notrunc bs=1 count=444
diff --git a/board/amlogic/s400/s400.c b/board/amlogic/s400/s400.c
new file mode 100644
index 0000000..02a0e92
--- /dev/null
+++ b/board/amlogic/s400/s400.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <environment.h>
+#include <asm/io.h>
+#include <asm/arch/axg.h>
+#include <asm/arch/sm.h>
+#include <asm/arch/eth.h>
+#include <asm/arch/mem.h>
+
+int misc_init_r(void)
+{
+ meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
+
+ return 0;
+}
diff --git a/board/mediatek/mt7623/Kconfig b/board/mediatek/mt7623/Kconfig
new file mode 100644
index 0000000..a8c670e
--- /dev/null
+++ b/board/mediatek/mt7623/Kconfig
@@ -0,0 +1,13 @@
+if TARGET_MT7623
+
+config SYS_BOARD
+ default "mt7623"
+
+config SYS_CONFIG_NAME
+ default "mt7623"
+
+config MTK_BROM_HEADER_INFO
+ string
+ default "lk=1"
+
+endif
diff --git a/board/mediatek/mt7623/MAINTAINERS b/board/mediatek/mt7623/MAINTAINERS
new file mode 100644
index 0000000..eeb0375
--- /dev/null
+++ b/board/mediatek/mt7623/MAINTAINERS
@@ -0,0 +1,7 @@
+MT7623
+M: Ryder Lee <ryder.lee@mediatek.com>
+M: Weijie Gao <weijie.gao@mediatek.com>
+S: Maintained
+F: board/mediatek/mt7623
+F: include/configs/mt7623.h
+F: configs/mt7623n_bpir2_defconfig
diff --git a/board/mediatek/mt7623/Makefile b/board/mediatek/mt7623/Makefile
new file mode 100644
index 0000000..2b42071
--- /dev/null
+++ b/board/mediatek/mt7623/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += mt7623_rfb.o
diff --git a/board/mediatek/mt7623/mt7623_rfb.c b/board/mediatek/mt7623/mt7623_rfb.c
new file mode 100644
index 0000000..08468b5
--- /dev/null
+++ b/board/mediatek/mt7623/mt7623_rfb.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+ return 0;
+}
diff --git a/board/mediatek/mt7629/Kconfig b/board/mediatek/mt7629/Kconfig
new file mode 100644
index 0000000..6055164
--- /dev/null
+++ b/board/mediatek/mt7629/Kconfig
@@ -0,0 +1,17 @@
+if TARGET_MT7629
+
+config SYS_BOARD
+ default "mt7629"
+
+config SYS_CONFIG_NAME
+ default "mt7629"
+
+config MTK_SPL_PAD_SIZE
+ hex
+ default 0x10000
+
+config MTK_BROM_HEADER_INFO
+ string
+ default "media=nor"
+
+endif
diff --git a/board/mediatek/mt7629/MAINTAINERS b/board/mediatek/mt7629/MAINTAINERS
new file mode 100644
index 0000000..424f115
--- /dev/null
+++ b/board/mediatek/mt7629/MAINTAINERS
@@ -0,0 +1,7 @@
+MT7629
+M: Ryder Lee <ryder.lee@mediatek.com>
+M: Weijie Gao <weijie.gao@mediatek.com>
+S: Maintained
+F: board/mediatek/mt7629
+F: include/configs/mt7629.h
+F: configs/mt7629_rfb_defconfig
diff --git a/board/mediatek/mt7629/Makefile b/board/mediatek/mt7629/Makefile
new file mode 100644
index 0000000..83ccbba
--- /dev/null
+++ b/board/mediatek/mt7629/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += mt7629_rfb.o
diff --git a/board/mediatek/mt7629/mt7629_rfb.c b/board/mediatek/mt7629/mt7629_rfb.c
new file mode 100644
index 0000000..08468b5
--- /dev/null
+++ b/board/mediatek/mt7629/mt7629_rfb.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#include <common.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_init(void)
+{
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+ return 0;
+}
diff --git a/common/image.c b/common/image.c
index 1c3a772..0659133 100644
--- a/common/image.c
+++ b/common/image.c
@@ -166,6 +166,7 @@ static const table_entry_t uimage_type[] = {
{ IH_TYPE_FIRMWARE_IVT, "firmware_ivt", "Firmware with HABv4 IVT" },
{ IH_TYPE_PMMC, "pmmc", "TI Power Management Micro-Controller Firmware",},
{ IH_TYPE_STM32IMAGE, "stm32image", "STMicroelectronics STM32 Image" },
+ { IH_TYPE_MTKIMAGE, "mtk_image", "MediaTek BootROM loadable Image" },
{ -1, "", "", },
};
diff --git a/configs/khadas-vim2_defconfig b/configs/khadas-vim2_defconfig
index 4bbccc2..6fe861c 100644
--- a/configs/khadas-vim2_defconfig
+++ b/configs/khadas-vim2_defconfig
@@ -2,7 +2,6 @@ CONFIG_ARM=y
CONFIG_ARCH_MESON=y
CONFIG_SYS_TEXT_BASE=0x01000000
CONFIG_MESON_GXM=y
-CONFIG_TARGET_KHADAS_VIM2=y
CONFIG_DEBUG_UART_BASE=0xc81004c0
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_IDENT_STRING=" khadas-vim2"
diff --git a/configs/khadas-vim_defconfig b/configs/khadas-vim_defconfig
index 0c89d9a..6e855dd 100644
--- a/configs/khadas-vim_defconfig
+++ b/configs/khadas-vim_defconfig
@@ -2,7 +2,6 @@ CONFIG_ARM=y
CONFIG_ARCH_MESON=y
CONFIG_SYS_TEXT_BASE=0x01000000
CONFIG_MESON_GXL=y
-CONFIG_TARGET_KHADAS_VIM=y
CONFIG_DEBUG_UART_BASE=0xc81004c0
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_IDENT_STRING=" khadas-vim"
diff --git a/configs/libretech-cc_defconfig b/configs/libretech-cc_defconfig
index 36d117c..c2f985f 100644
--- a/configs/libretech-cc_defconfig
+++ b/configs/libretech-cc_defconfig
@@ -2,7 +2,6 @@ CONFIG_ARM=y
CONFIG_ARCH_MESON=y
CONFIG_SYS_TEXT_BASE=0x01000000
CONFIG_MESON_GXL=y
-CONFIG_TARGET_LIBRETECH_CC=y
CONFIG_DEBUG_UART_BASE=0xc81004c0
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_IDENT_STRING=" libretech-cc"
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
new file mode 100644
index 0000000..3a4de72
--- /dev/null
+++ b/configs/mt7623n_bpir2_defconfig
@@ -0,0 +1,54 @@
+CONFIG_ARM=y
+CONFIG_SYS_THUMB_BUILD=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x81e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_TARGET_MT7623=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=3
+CONFIG_SYS_CONSOLE_IS_IN_ENV=y
+CONFIG_DEFAULT_FDT_FILE="mt7623n-bananapi-bpi-r2"
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="U-Boot> "
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_READ=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_OF_EMBED=y
+CONFIG_DEFAULT_DEVICE_TREE="mt7623n-bananapi-bpi-r2"
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+# CONFIG_BLOCK_CACHE is not set
+CONFIG_CLK=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_MMC=y
+# CONFIG_MMC_QUIRKS is not set
+CONFIG_MMC_HS400_SUPPORT=y
+CONFIG_MMC_MTK=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7623=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_TIMER=y
+CONFIG_MTK_TIMER=y
+CONFIG_WDT_MTK=y
+CONFIG_LZMA=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig
new file mode 100644
index 0000000..1729d13
--- /dev/null
+++ b/configs/mt7629_rfb_defconfig
@@ -0,0 +1,73 @@
+CONFIG_ARM=y
+CONFIG_SYS_THUMB_BUILD=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_TARGET_MT7629=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=3
+CONFIG_SYS_CONSOLE_IS_IN_ENV=y
+CONFIG_DEFAULT_FDT_FILE="mt7629-rfb"
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_NOR_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="U-Boot> "
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_SF=y
+CONFIG_CMD_SF_TEST=y
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_CMD_PING=y
+# CONFIG_PARTITIONS is not set
+CONFIG_OF_EMBED=y
+CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-parents"
+CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+CONFIG_DM_GPIO=y
+# CONFIG_MMC is not set
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH=y
+CONFIG_SPI_FLASH_BAR=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_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7629=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_RAM=y
+CONFIG_SPL_RAM=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_MTK_QSPI=y
+CONFIG_SYSRESET=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_TIMER=y
+CONFIG_SPL_TIMER=y
+CONFIG_MTK_TIMER=y
+CONFIG_WDT_MTK=y
+CONFIG_LZMA=y
+# CONFIG_EFI_LOADER is not set
diff --git a/configs/nanopi-k2_defconfig b/configs/nanopi-k2_defconfig
index 5c8c747..8bbf48f 100644
--- a/configs/nanopi-k2_defconfig
+++ b/configs/nanopi-k2_defconfig
@@ -1,8 +1,6 @@
CONFIG_ARM=y
CONFIG_ARCH_MESON=y
CONFIG_SYS_TEXT_BASE=0x01000000
-CONFIG_MESON_GXBB=y
-CONFIG_TARGET_NANOPI_K2=y
CONFIG_DEBUG_UART_BASE=0xc81004c0
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_IDENT_STRING=" nanopi-k2"
diff --git a/configs/odroid-c2_defconfig b/configs/odroid-c2_defconfig
index 19196b3..68554ba 100644
--- a/configs/odroid-c2_defconfig
+++ b/configs/odroid-c2_defconfig
@@ -2,7 +2,6 @@ CONFIG_ARM=y
CONFIG_ARCH_MESON=y
CONFIG_SYS_TEXT_BASE=0x01000000
CONFIG_MESON_GXBB=y
-CONFIG_TARGET_ODROID_C2=y
CONFIG_DEBUG_UART_BASE=0xc81004c0
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_IDENT_STRING=" odroid-c2"
diff --git a/configs/p212_defconfig b/configs/p212_defconfig
index 9e3b1d6..a15064d 100644
--- a/configs/p212_defconfig
+++ b/configs/p212_defconfig
@@ -2,7 +2,6 @@ CONFIG_ARM=y
CONFIG_ARCH_MESON=y
CONFIG_SYS_TEXT_BASE=0x01000000
CONFIG_MESON_GXL=y
-CONFIG_TARGET_P212=y
CONFIG_DEBUG_UART_BASE=0xc81004c0
CONFIG_DEBUG_UART_CLOCK=24000000
CONFIG_IDENT_STRING=" p212"
diff --git a/configs/s400_defconfig b/configs/s400_defconfig
new file mode 100644
index 0000000..1bd4b71
--- /dev/null
+++ b/configs/s400_defconfig
@@ -0,0 +1,38 @@
+CONFIG_ARM=y
+CONFIG_ARCH_MESON=y
+CONFIG_SYS_TEXT_BASE=0x01000000
+CONFIG_MESON_AXG=y
+CONFIG_DEBUG_UART_BASE=0xff803000
+CONFIG_DEBUG_UART_CLOCK=24000000
+CONFIG_IDENT_STRING=" s400"
+CONFIG_DEBUG_UART=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_MISC_INIT_R=y
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+# CONFIG_CMD_BDI is not set
+# CONFIG_CMD_IMI is not set
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_REGULATOR=y
+CONFIG_OF_CONTROL=y
+CONFIG_DEFAULT_DEVICE_TREE="meson-axg-s400"
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_MESON_GX=y
+CONFIG_DM_ETH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_MESON_AXG=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_RESET=y
+CONFIG_DEBUG_UART_MESON=y
+CONFIG_DEBUG_UART_ANNOUNCE=y
+CONFIG_DEBUG_UART_SKIP_INIT=y
+CONFIG_MESON_SERIAL=y
+CONFIG_OF_LIBFDT_OVERLAY=y
diff --git a/doc/README.mediatek b/doc/README.mediatek
new file mode 100644
index 0000000..246579d
--- /dev/null
+++ b/doc/README.mediatek
@@ -0,0 +1,221 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2018 MediaTek Inc.
+# Ryder Lee <ryder.lee@kernel.org>
+
+
+This document describes how to compile the U-Boot and how to change U-Boot
+configuration about the MediaTek SoCs.
+
+
+Build Procedure
+===============
+ -Set the cross compiler:
+
+ # export CROSS_COMPILE=/path/to/toolchain/arm-linux-gnueabi-
+
+ -Clean-up old residuals:
+
+ # make mrproper
+
+ -Configure the U-Boot:
+
+ # make <defconfig_file>
+ # make
+
+ - For the MT7623n bananapi R2 board use "mt7623n_bpir2_defconfig"
+ - For the MT7629 reference board use "mt7629_rfb_defconfig"
+
+
+Boot sequence
+=============
+ -Bootrom -> MTK preloader -> U-Boot
+
+ - MT7623n
+
+ This version of U-Boot doesn't implement SPL. So, MTK preloader binary
+ is needed to boot up:
+
+ https://github.com/BPI-SINOVOIP/BPI-R2-bsp/tree/master/mt-pack/mtk/bpi-r2/bin
+
+
+ -Bootrom -> SPL -> U-Boot
+
+ - MT7629
+
+
+Configuration update
+====================
+ To update the U-Boot configuration, please refer to doc/README.kconfig
+
+
+MediaTek image header
+=====================
+Currently there are two image headers used for MediaTek chips:
+
+ - BootROM image header. This header is used by the first stage bootloader. It records
+ the desired compatible boot device, integrity information and its load address.
+
+ The on-chip BootROM will firstly verify integrity and compatibility of the bootloader.
+
+ If verification passed, the BootROM will then load the bootloader into on-chip SRAM,
+ and pass control to it.
+
+ Note that this header is actually a combination of three independent headers:
+ Device header, BRLYT header and GFH header.
+
+ Used by U-Boot SPL of MT7629 and preloader of MT7623.
+
+
+ - MediaTek legacy image header. This header was originally used by the legacy image. It
+ basically records the load address, image size and image name.
+
+ After all low level initializations passed, the preloader will locate the LK image and
+ load it into DRAM, and pass control to it.
+
+ Now this header is used by U-Boot of MT7623.
+
+
+To generate these two headers with mkimage:
+
+ # mkimage -T mtk_image -a <load_addr> -n <option_string> -d <input_file> <image_file>
+
+ - mtk_image means using MediaTek's header generation method.
+
+
+ - load_addr is the load address of this image.
+ For first stage bootloader like U-Boot SPL or preloader, it usually points to the
+ on-chip SRAM.
+
+ For second stage bootloader like U-Boot, it usually points to the DRAM.
+
+
+ - option_string contains options to generate the header.
+
+ The option string is using the follow format:
+ key1=value1;key2=value2;...
+
+ The following key names are valid:
+ lk: If lk=1, LK image header is used. Otherwise BootROM image header is used.
+
+ lkname: The name of the LK image header. The maximum length is 32.
+ The default value is "U-Boot".
+
+ media: Desired boot device. The valid values are:
+ nand : Parallel NAND
+ snand: Serial NAND
+ nor : Serial NOR
+ emmc : eMMC
+ sdmmc: SD
+
+ nandinfo: Desired NAND device type, a combination of page size, oob size and
+ optional device capacity. Valid types are:
+ 2k+64 : for Serial NAND, 2KiB page size + 64B oob size
+ 2k+120 : for Serial NAND, 2KiB page size + 120B oob size
+ 2k+128 : for Serial NAND, 2KiB page size + 128B oob size
+ 4k+256 : for Serial NAND, 4KiB page size + 256B oob size
+ 1g:2k+64 : for Parallel NAND, 2KiB page size + 64B oob size, total 1Gbit size
+ 2g:2k+64 : for Parallel NAND, 2KiB page size + 64B oob size, total 2Gbit size
+ 4g:2k+64 : for Parallel NAND, 2KiB page size + 64B oob size, total 4Gbit size
+ 2g:2k+128: for Parallel NAND, 2KiB page size + 128B oob size, total 2Gbit size
+ 4g:2k+128: for Parallel NAND, 2KiB page size + 128B oob size, total 4Gbit size
+
+
+MT7629 partitions on Serial NOR
+===============================
+
+ Start End Size Description
+ 00000000 - 0000ffff: 64KiB U-Boot SPL
+ 00010000 - 0005ffff: 320KiB U-Boot
+ 00060000 - 0006ffff: 64KiB U-Boot env / MediaTek NVRAM
+ 00070000 - 000affff: 256KiB RF calibration data
+ 000b0000 - xxxxxxxx: all left Firmware image
+
+
+BPi-R2 (MT7623N) partitions on SD
+=================================
+ Please note that the last two partitions can vary from different Linux distributions
+ depending on the MBR partition table.
+
+ Start End Size Description
+ 00000000 - 000001ff: 512B Device header (with MBR partition table)
+ 00000200 - 000007ff: 1536B BRLYT header
+ 00000800 - 0004ffff: 318KiB Preloader (with GFH header)
+ 00050000 - 000fffff: 704KiB U-Boot
+ 00100000 - 063fffff: 99MiB Reserved
+ 06400000 - 163fffff: 256MiB Partition 1 (FAT32)
+ 16400000 - xxxxxxxx: all left Partition 2 (ext4)
+
+
+Upgrading notice on Serial NOR
+==============================
+Example: MT7629
+
+ The command sf is used to operate the Serial NOR device:
+
+ - To probe current NOR flash:
+
+ # sf probe
+
+ - To erase a region:
+
+ # sf erase <offset> <len>
+
+ - To write data to an offset:
+
+ # sf write <data_addr> <offset> <len>
+
+ - To boot kernel:
+
+ # bootm 0x300b0000
+
+ The memory address range 0x30000000 - 0x3fffffff is mapped to the NOR flash.
+ The DRAM starts at 0x40000000.
+
+ Please note that the output binary u-boot-mtk.bin is a combination of SPL and U-Boot,
+ and it should be write to beginning of the flash.
+
+ Otherwise you should use standalone files:
+
+ spl/u-boot-spl-mtk.bin for SPL,
+ u-boot.img for U-Boot.
+
+
+Upgrading notice on SD / eMMC
+=============================
+Example: MT7623
+
+ Normally only Preloader and U-Boot can be upgraded within U-Boot, and other partitions
+ should be written in PC.
+
+ - To probe current SD card / eMMC:
+
+ # mmc dev 0 for eMMC
+ # mmc dev 1 for SD
+
+ - To erase a region:
+
+ # mmc erase <blk_offset> <blk_num>
+
+ - To write data to a block offset:
+
+ # mmc write <data_addr> <blk_offset> <blk_num>
+
+ - To load kernel image from partition 1:
+
+ # fatload mmc 0:1 <load_address> <path_to_kernel_uImage> for eMMC
+ # fatload mmc 1:1 <load_address> <path_to_kernel_uImage> for SD
+
+ - To boot kernel:
+
+ # bootm <load_address>
+
+ The DRAM starts at 0x80000000.
+
+ Please note that we use block offset and block count for SD card, not the byte offset.
+ The block size is always 512 bytes for SD card.
+
+
+Documentation
+=============
+ http://wiki.banana-pi.org/Banana_Pi_BPI-R2
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 821b586..9acbb1a 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -9,7 +9,8 @@ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk-uclass.o clk_fixed_rate.o
obj-y += imx/
obj-y += tegra/
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
-obj-$(CONFIG_ARCH_MESON) += clk_meson.o
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
+obj-$(CONFIG_ARCH_MESON) += clk_meson.o clk_meson_axg.o
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_SOCFPGA) += altera/
obj-$(CONFIG_CLK_AT91) += at91/
diff --git a/drivers/clk/clk_meson.c b/drivers/clk/clk_meson.c
index c448588..0df8b91 100644
--- a/drivers/clk/clk_meson.c
+++ b/drivers/clk/clk_meson.c
@@ -6,7 +6,7 @@
*/
#include <common.h>
-#include <asm/arch/clock.h>
+#include <asm/arch/clock-gx.h>
#include <asm/io.h>
#include <clk-uclass.h>
#include <div64.h>
@@ -79,7 +79,7 @@ static ulong meson_clk_set_rate_by_id(struct clk *clk, unsigned long id,
static ulong meson_mux_get_parent(struct clk *clk, unsigned long id);
static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id);
-struct meson_gate gates[] = {
+static struct meson_gate gates[] = {
/* Everything Else (EE) domain gates */
MESON_GATE(CLKID_DDR, HHI_GCLK_MPEG0, 0),
MESON_GATE(CLKID_DOS, HHI_GCLK_MPEG0, 1),
@@ -791,7 +791,7 @@ static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id)
return -ENOENT;
}
- printf("clock %lu has rate %lu\n", id, rate);
+ debug("clock %lu has rate %lu\n", id, rate);
return rate;
}
diff --git a/drivers/clk/clk_meson_axg.c b/drivers/clk/clk_meson_axg.c
new file mode 100644
index 0000000..32cbf75
--- /dev/null
+++ b/drivers/clk/clk_meson_axg.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com>
+ * (C) Copyright 2018 - BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <common.h>
+#include <asm/arch/clock-axg.h>
+#include <asm/io.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <div64.h>
+#include <dt-bindings/clock/axg-clkc.h>
+#include "clk_meson.h"
+
+#define XTAL_RATE 24000000
+
+struct meson_clk {
+ struct regmap *map;
+};
+
+static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id);
+
+static struct meson_gate gates[] = {
+ /* Everything Else (EE) domain gates */
+ MESON_GATE(CLKID_SPICC0, HHI_GCLK_MPEG0, 8),
+ MESON_GATE(CLKID_I2C, HHI_GCLK_MPEG0, 9),
+ MESON_GATE(CLKID_UART0, HHI_GCLK_MPEG0, 13),
+ MESON_GATE(CLKID_SPICC1, HHI_GCLK_MPEG0, 15),
+ MESON_GATE(CLKID_SD_EMMC_B, HHI_GCLK_MPEG0, 25),
+ MESON_GATE(CLKID_SD_EMMC_C, HHI_GCLK_MPEG0, 26),
+ MESON_GATE(CLKID_ETH, HHI_GCLK_MPEG1, 3),
+ MESON_GATE(CLKID_UART1, HHI_GCLK_MPEG1, 16),
+
+ /* Always On (AO) domain gates */
+ MESON_GATE(CLKID_AO_I2C, HHI_GCLK_AO, 4),
+
+ /* PLL Gates */
+ /* CLKID_FCLK_DIV2 is critical for the SCPI Processor */
+ MESON_GATE(CLKID_MPLL2, HHI_MPLL_CNTL9, 14),
+ /* CLKID_CLK81 is critical for the system */
+
+ /* Peripheral Gates */
+ MESON_GATE(CLKID_SD_EMMC_B_CLK0, HHI_SD_EMMC_CLK_CNTL, 23),
+ MESON_GATE(CLKID_SD_EMMC_C_CLK0, HHI_NAND_CLK_CNTL, 7),
+};
+
+static int meson_set_gate(struct clk *clk, bool on)
+{
+ struct meson_clk *priv = dev_get_priv(clk->dev);
+ struct meson_gate *gate;
+
+ if (clk->id >= ARRAY_SIZE(gates))
+ return -ENOENT;
+
+ gate = &gates[clk->id];
+
+ if (gate->reg == 0)
+ return 0;
+
+ regmap_update_bits(priv->map, gate->reg,
+ BIT(gate->bit), on ? BIT(gate->bit) : 0);
+
+ return 0;
+}
+
+static int meson_clk_enable(struct clk *clk)
+{
+ return meson_set_gate(clk, true);
+}
+
+static int meson_clk_disable(struct clk *clk)
+{
+ return meson_set_gate(clk, false);
+}
+
+static unsigned long meson_clk81_get_rate(struct clk *clk)
+{
+ struct meson_clk *priv = dev_get_priv(clk->dev);
+ unsigned long parent_rate;
+ uint reg;
+ int parents[] = {
+ -1,
+ -1,
+ CLKID_FCLK_DIV7,
+ CLKID_MPLL1,
+ CLKID_MPLL2,
+ CLKID_FCLK_DIV4,
+ CLKID_FCLK_DIV3,
+ CLKID_FCLK_DIV5
+ };
+
+ /* mux */
+ regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
+ reg = (reg >> 12) & 7;
+
+ switch (reg) {
+ case 0:
+ parent_rate = XTAL_RATE;
+ break;
+ case 1:
+ return -ENOENT;
+ default:
+ parent_rate = meson_clk_get_rate_by_id(clk, parents[reg]);
+ }
+
+ /* divider */
+ regmap_read(priv->map, HHI_MPEG_CLK_CNTL, &reg);
+ reg = reg & ((1 << 7) - 1);
+
+ return parent_rate / reg;
+}
+
+static long mpll_rate_from_params(unsigned long parent_rate,
+ unsigned long sdm,
+ unsigned long n2)
+{
+ unsigned long divisor = (SDM_DEN * n2) + sdm;
+
+ if (n2 < N2_MIN)
+ return -EINVAL;
+
+ return DIV_ROUND_UP_ULL((u64)parent_rate * SDM_DEN, divisor);
+}
+
+static struct parm meson_mpll0_parm[3] = {
+ {HHI_MPLL_CNTL7, 0, 14}, /* psdm */
+ {HHI_MPLL_CNTL7, 16, 9}, /* pn2 */
+};
+
+static struct parm meson_mpll1_parm[3] = {
+ {HHI_MPLL_CNTL8, 0, 14}, /* psdm */
+ {HHI_MPLL_CNTL8, 16, 9}, /* pn2 */
+};
+
+static struct parm meson_mpll2_parm[3] = {
+ {HHI_MPLL_CNTL9, 0, 14}, /* psdm */
+ {HHI_MPLL_CNTL9, 16, 9}, /* pn2 */
+};
+
+/*
+ * MultiPhase Locked Loops are outputs from a PLL with additional frequency
+ * scaling capabilities. MPLL rates are calculated as:
+ *
+ * f(N2_integer, SDM_IN ) = 2.0G/(N2_integer + SDM_IN/16384)
+ */
+static ulong meson_mpll_get_rate(struct clk *clk, unsigned long id)
+{
+ struct meson_clk *priv = dev_get_priv(clk->dev);
+ struct parm *psdm, *pn2;
+ unsigned long sdm, n2;
+ unsigned long parent_rate;
+ uint reg;
+
+ switch (id) {
+ case CLKID_MPLL0:
+ psdm = &meson_mpll0_parm[0];
+ pn2 = &meson_mpll0_parm[1];
+ break;
+ case CLKID_MPLL1:
+ psdm = &meson_mpll1_parm[0];
+ pn2 = &meson_mpll1_parm[1];
+ break;
+ case CLKID_MPLL2:
+ psdm = &meson_mpll2_parm[0];
+ pn2 = &meson_mpll2_parm[1];
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ parent_rate = meson_clk_get_rate_by_id(clk, CLKID_FIXED_PLL);
+ if (IS_ERR_VALUE(parent_rate))
+ return parent_rate;
+
+ regmap_read(priv->map, psdm->reg_off, &reg);
+ sdm = PARM_GET(psdm->width, psdm->shift, reg);
+
+ regmap_read(priv->map, pn2->reg_off, &reg);
+ n2 = PARM_GET(pn2->width, pn2->shift, reg);
+
+ return mpll_rate_from_params(parent_rate, sdm, n2);
+}
+
+static struct parm meson_fixed_pll_parm[3] = {
+ {HHI_MPLL_CNTL, 0, 9}, /* pm */
+ {HHI_MPLL_CNTL, 9, 5}, /* pn */
+ {HHI_MPLL_CNTL, 16, 2}, /* pod */
+};
+
+static struct parm meson_sys_pll_parm[3] = {
+ {HHI_SYS_PLL_CNTL, 0, 9}, /* pm */
+ {HHI_SYS_PLL_CNTL, 9, 5}, /* pn */
+ {HHI_SYS_PLL_CNTL, 16, 2}, /* pod */
+};
+
+static ulong meson_pll_get_rate(struct clk *clk, unsigned long id)
+{
+ struct meson_clk *priv = dev_get_priv(clk->dev);
+ struct parm *pm, *pn, *pod;
+ unsigned long parent_rate_mhz = XTAL_RATE / 1000000;
+ u16 n, m, od;
+ uint reg;
+
+ switch (id) {
+ case CLKID_FIXED_PLL:
+ pm = &meson_fixed_pll_parm[0];
+ pn = &meson_fixed_pll_parm[1];
+ pod = &meson_fixed_pll_parm[2];
+ break;
+ case CLKID_SYS_PLL:
+ pm = &meson_sys_pll_parm[0];
+ pn = &meson_sys_pll_parm[1];
+ pod = &meson_sys_pll_parm[2];
+ break;
+ default:
+ return -ENOENT;
+ }
+
+ regmap_read(priv->map, pn->reg_off, &reg);
+ n = PARM_GET(pn->width, pn->shift, reg);
+
+ regmap_read(priv->map, pm->reg_off, &reg);
+ m = PARM_GET(pm->width, pm->shift, reg);
+
+ regmap_read(priv->map, pod->reg_off, &reg);
+ od = PARM_GET(pod->width, pod->shift, reg);
+
+ return ((parent_rate_mhz * m / n) >> od) * 1000000;
+}
+
+static ulong meson_clk_get_rate_by_id(struct clk *clk, unsigned long id)
+{
+ ulong rate;
+
+ switch (id) {
+ case CLKID_FIXED_PLL:
+ case CLKID_SYS_PLL:
+ rate = meson_pll_get_rate(clk, id);
+ break;
+ case CLKID_FCLK_DIV2:
+ rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 2;
+ break;
+ case CLKID_FCLK_DIV3:
+ rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 3;
+ break;
+ case CLKID_FCLK_DIV4:
+ rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 4;
+ break;
+ case CLKID_FCLK_DIV5:
+ rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 5;
+ break;
+ case CLKID_FCLK_DIV7:
+ rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 7;
+ break;
+ case CLKID_MPLL0:
+ case CLKID_MPLL1:
+ case CLKID_MPLL2:
+ rate = meson_mpll_get_rate(clk, id);
+ break;
+ case CLKID_CLK81:
+ rate = meson_clk81_get_rate(clk);
+ break;
+ default:
+ if (gates[id].reg != 0) {
+ /* a clock gate */
+ rate = meson_clk81_get_rate(clk);
+ break;
+ }
+ return -ENOENT;
+ }
+
+ debug("clock %lu has rate %lu\n", id, rate);
+ return rate;
+}
+
+static ulong meson_clk_get_rate(struct clk *clk)
+{
+ return meson_clk_get_rate_by_id(clk, clk->id);
+}
+
+static int meson_clk_probe(struct udevice *dev)
+{
+ struct meson_clk *priv = dev_get_priv(dev);
+
+ priv->map = syscon_node_to_regmap(dev_get_parent(dev)->node);
+ if (IS_ERR(priv->map))
+ return PTR_ERR(priv->map);
+
+ debug("meson-clk-axg: probed\n");
+
+ return 0;
+}
+
+static struct clk_ops meson_clk_ops = {
+ .disable = meson_clk_disable,
+ .enable = meson_clk_enable,
+ .get_rate = meson_clk_get_rate,
+};
+
+static const struct udevice_id meson_clk_ids[] = {
+ { .compatible = "amlogic,axg-clkc" },
+ { }
+};
+
+U_BOOT_DRIVER(meson_clk_axg) = {
+ .name = "meson_clk_axg",
+ .id = UCLASS_CLK,
+ .of_match = meson_clk_ids,
+ .priv_auto_alloc_size = sizeof(struct meson_clk),
+ .ops = &meson_clk_ops,
+ .probe = meson_clk_probe,
+};
diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile
new file mode 100644
index 0000000..0632dc8
--- /dev/null
+++ b/drivers/clk/mediatek/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+# Core
+obj-$(CONFIG_ARCH_MEDIATEK) += clk-mtk.o
+
+# SoC Drivers
+obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o
+obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o
diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c
new file mode 100644
index 0000000..c6b09d8
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7623.c
@@ -0,0 +1,870 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7623 SoC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/mt7623-clk.h>
+
+#include "clk-mtk.h"
+
+#define MT7623_CLKSQ_STB_CON0 0x18
+#define MT7623_PLL_ISO_CON0 0x24
+#define MT7623_PLL_FMAX (2000UL * MHZ)
+#define MT7623_CON0_RST_BAR BIT(27)
+
+#define MCU_AXI_DIV 0x60
+#define AXI_DIV_MSK GENMASK(4, 0)
+#define AXI_DIV_SEL(x) (x)
+
+/* apmixedsys */
+#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
+ _pd_shift, _pcw_reg, _pcw_shift) { \
+ .id = _id, \
+ .reg = _reg, \
+ .pwr_reg = _pwr_reg, \
+ .en_mask = _en_mask, \
+ .rst_bar_mask = MT7623_CON0_RST_BAR, \
+ .fmax = MT7623_PLL_FMAX, \
+ .flags = _flags, \
+ .pcwbits = _pcwbits, \
+ .pd_reg = _pd_reg, \
+ .pd_shift = _pd_shift, \
+ .pcw_reg = _pcw_reg, \
+ .pcw_shift = _pcw_shift, \
+ }
+
+static const struct mtk_pll_data apmixed_plls[] = {
+ PLL(CLK_APMIXED_ARMPLL, 0x200, 0x20c, 0x80000001, 0,
+ 21, 0x204, 24, 0x204, 0),
+ PLL(CLK_APMIXED_MAINPLL, 0x210, 0x21c, 0xf0000001, HAVE_RST_BAR,
+ 21, 0x210, 4, 0x214, 0),
+ PLL(CLK_APMIXED_UNIVPLL, 0x220, 0x22c, 0xf3000001, HAVE_RST_BAR,
+ 7, 0x220, 4, 0x224, 14),
+ PLL(CLK_APMIXED_MMPLL, 0x230, 0x23c, 0x00000001, 0,
+ 21, 0x230, 4, 0x234, 0),
+ PLL(CLK_APMIXED_MSDCPLL, 0x240, 0x24c, 0x00000001, 0,
+ 21, 0x240, 4, 0x244, 0),
+ PLL(CLK_APMIXED_TVDPLL, 0x250, 0x25c, 0x00000001, 0,
+ 21, 0x250, 4, 0x254, 0),
+ PLL(CLK_APMIXED_AUD1PLL, 0x270, 0x27c, 0x00000001, 0,
+ 31, 0x270, 4, 0x274, 0),
+ PLL(CLK_APMIXED_TRGPLL, 0x280, 0x28c, 0x00000001, 0,
+ 31, 0x280, 4, 0x284, 0),
+ PLL(CLK_APMIXED_ETHPLL, 0x290, 0x29c, 0x00000001, 0,
+ 31, 0x290, 4, 0x294, 0),
+ PLL(CLK_APMIXED_VDECPLL, 0x2a0, 0x2ac, 0x00000001, 0,
+ 31, 0x2a0, 4, 0x2a4, 0),
+ PLL(CLK_APMIXED_HADDS2PLL, 0x2b0, 0x2bc, 0x00000001, 0,
+ 31, 0x2b0, 4, 0x2b4, 0),
+ PLL(CLK_APMIXED_AUD2PLL, 0x2c0, 0x2cc, 0x00000001, 0,
+ 31, 0x2c0, 4, 0x2c4, 0),
+ PLL(CLK_APMIXED_TVD2PLL, 0x2d0, 0x2dc, 0x00000001, 0,
+ 21, 0x2d0, 4, 0x2d4, 0),
+};
+
+/* topckgen */
+#define FACTOR0(_id, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
+
+#define FACTOR1(_id, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
+
+#define FACTOR2(_id, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, 0)
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+ FIXED_CLK(CLK_TOP_DPI, CLK_XTAL, 108 * MHZ),
+ FIXED_CLK(CLK_TOP_DMPLL, CLK_XTAL, 400 * MHZ),
+ FIXED_CLK(CLK_TOP_VENCPLL, CLK_XTAL, 295.75 * MHZ),
+ FIXED_CLK(CLK_TOP_HDMI_0_PIX340M, CLK_XTAL, 340 * MHZ),
+ FIXED_CLK(CLK_TOP_HDMI_0_DEEP340M, CLK_XTAL, 340 * MHZ),
+ FIXED_CLK(CLK_TOP_HDMI_0_PLL340M, CLK_XTAL, 340 * MHZ),
+ FIXED_CLK(CLK_TOP_HADDS2_FB, CLK_XTAL, 27 * MHZ),
+ FIXED_CLK(CLK_TOP_WBG_DIG_416M, CLK_XTAL, 416 * MHZ),
+ FIXED_CLK(CLK_TOP_DSI0_LNTC_DSI, CLK_XTAL, 143 * MHZ),
+ FIXED_CLK(CLK_TOP_HDMI_SCL_RX, CLK_XTAL, 27 * MHZ),
+ FIXED_CLK(CLK_TOP_32K_EXTERNAL, CLK_XTAL, 32000),
+ FIXED_CLK(CLK_TOP_HDMITX_CLKDIG_CTS, CLK_XTAL, 300 * MHZ),
+ FIXED_CLK(CLK_TOP_AUD_EXT1, CLK_XTAL, 0),
+ FIXED_CLK(CLK_TOP_AUD_EXT2, CLK_XTAL, 0),
+ FIXED_CLK(CLK_TOP_NFI1X_PAD, CLK_XTAL, 0),
+};
+
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+ FACTOR0(CLK_TOP_SYSPLL, CLK_APMIXED_MAINPLL, 1, 1),
+ FACTOR0(CLK_TOP_SYSPLL_D2, CLK_APMIXED_MAINPLL, 1, 2),
+ FACTOR0(CLK_TOP_SYSPLL_D3, CLK_APMIXED_MAINPLL, 1, 3),
+ FACTOR0(CLK_TOP_SYSPLL_D5, CLK_APMIXED_MAINPLL, 1, 5),
+ FACTOR0(CLK_TOP_SYSPLL_D7, CLK_APMIXED_MAINPLL, 1, 7),
+ FACTOR1(CLK_TOP_SYSPLL1_D2, CLK_TOP_SYSPLL_D2, 1, 2),
+ FACTOR1(CLK_TOP_SYSPLL1_D4, CLK_TOP_SYSPLL_D2, 1, 4),
+ FACTOR1(CLK_TOP_SYSPLL1_D8, CLK_TOP_SYSPLL_D2, 1, 8),
+ FACTOR1(CLK_TOP_SYSPLL1_D16, CLK_TOP_SYSPLL_D2, 1, 16),
+ FACTOR1(CLK_TOP_SYSPLL2_D2, CLK_TOP_SYSPLL_D3, 1, 2),
+ FACTOR1(CLK_TOP_SYSPLL2_D4, CLK_TOP_SYSPLL_D3, 1, 4),
+ FACTOR1(CLK_TOP_SYSPLL2_D8, CLK_TOP_SYSPLL_D3, 1, 8),
+ FACTOR1(CLK_TOP_SYSPLL3_D2, CLK_TOP_SYSPLL_D5, 1, 2),
+ FACTOR1(CLK_TOP_SYSPLL3_D4, CLK_TOP_SYSPLL_D5, 1, 4),
+ FACTOR1(CLK_TOP_SYSPLL4_D2, CLK_TOP_SYSPLL_D7, 1, 2),
+ FACTOR1(CLK_TOP_SYSPLL4_D4, CLK_TOP_SYSPLL_D7, 1, 4),
+
+ FACTOR0(CLK_TOP_UNIVPLL, CLK_APMIXED_UNIVPLL, 1, 1),
+ FACTOR0(CLK_TOP_UNIVPLL_D2, CLK_APMIXED_UNIVPLL, 1, 2),
+ FACTOR0(CLK_TOP_UNIVPLL_D3, CLK_APMIXED_UNIVPLL, 1, 3),
+ FACTOR0(CLK_TOP_UNIVPLL_D5, CLK_APMIXED_UNIVPLL, 1, 5),
+ FACTOR0(CLK_TOP_UNIVPLL_D7, CLK_APMIXED_UNIVPLL, 1, 7),
+ FACTOR0(CLK_TOP_UNIVPLL_D26, CLK_APMIXED_UNIVPLL, 1, 26),
+ FACTOR0(CLK_TOP_UNIVPLL_D52, CLK_APMIXED_UNIVPLL, 1, 52),
+ FACTOR0(CLK_TOP_UNIVPLL_D108, CLK_APMIXED_UNIVPLL, 1, 108),
+ FACTOR0(CLK_TOP_USB_PHY48M, CLK_APMIXED_UNIVPLL, 1, 26),
+ FACTOR1(CLK_TOP_UNIVPLL1_D2, CLK_TOP_UNIVPLL_D2, 1, 2),
+ FACTOR1(CLK_TOP_UNIVPLL1_D4, CLK_TOP_UNIVPLL_D2, 1, 4),
+ FACTOR1(CLK_TOP_UNIVPLL1_D8, CLK_TOP_UNIVPLL_D2, 1, 8),
+ FACTOR1(CLK_TOP_UNIVPLL2_D2, CLK_TOP_UNIVPLL_D3, 1, 2),
+ FACTOR1(CLK_TOP_UNIVPLL2_D4, CLK_TOP_UNIVPLL_D3, 1, 4),
+ FACTOR1(CLK_TOP_UNIVPLL2_D8, CLK_TOP_UNIVPLL_D3, 1, 8),
+ FACTOR1(CLK_TOP_UNIVPLL2_D16, CLK_TOP_UNIVPLL_D3, 1, 16),
+ FACTOR1(CLK_TOP_UNIVPLL2_D32, CLK_TOP_UNIVPLL_D3, 1, 32),
+ FACTOR1(CLK_TOP_UNIVPLL3_D2, CLK_TOP_UNIVPLL_D5, 1, 2),
+ FACTOR1(CLK_TOP_UNIVPLL3_D4, CLK_TOP_UNIVPLL_D5, 1, 4),
+ FACTOR1(CLK_TOP_UNIVPLL3_D8, CLK_TOP_UNIVPLL_D5, 1, 8),
+
+ FACTOR0(CLK_TOP_MSDCPLL, CLK_APMIXED_MSDCPLL, 1, 1),
+ FACTOR0(CLK_TOP_MSDCPLL_D2, CLK_APMIXED_MSDCPLL, 1, 2),
+ FACTOR0(CLK_TOP_MSDCPLL_D4, CLK_APMIXED_MSDCPLL, 1, 4),
+ FACTOR0(CLK_TOP_MSDCPLL_D8, CLK_APMIXED_MSDCPLL, 1, 8),
+
+ FACTOR0(CLK_TOP_MMPLL, CLK_APMIXED_MMPLL, 1, 1),
+ FACTOR0(CLK_TOP_MMPLL_D2, CLK_APMIXED_MMPLL, 1, 2),
+
+ FACTOR1(CLK_TOP_DMPLL_D2, CLK_TOP_DMPLL, 1, 2),
+ FACTOR1(CLK_TOP_DMPLL_D4, CLK_TOP_DMPLL, 1, 4),
+ FACTOR1(CLK_TOP_DMPLL_X2, CLK_TOP_DMPLL, 1, 1),
+
+ FACTOR0(CLK_TOP_TVDPLL, CLK_APMIXED_TVDPLL, 1, 1),
+ FACTOR0(CLK_TOP_TVDPLL_D2, CLK_APMIXED_TVDPLL, 1, 2),
+ FACTOR0(CLK_TOP_TVDPLL_D4, CLK_APMIXED_TVDPLL, 1, 4),
+
+ FACTOR0(CLK_TOP_VDECPLL, CLK_APMIXED_VDECPLL, 1, 1),
+ FACTOR0(CLK_TOP_TVD2PLL, CLK_APMIXED_TVD2PLL, 1, 1),
+ FACTOR0(CLK_TOP_TVD2PLL_D2, CLK_APMIXED_TVD2PLL, 1, 2),
+
+ FACTOR1(CLK_TOP_MIPIPLL, CLK_TOP_DPI, 1, 1),
+ FACTOR1(CLK_TOP_MIPIPLL_D2, CLK_TOP_DPI, 1, 2),
+ FACTOR1(CLK_TOP_MIPIPLL_D4, CLK_TOP_DPI, 1, 4),
+
+ FACTOR1(CLK_TOP_HDMIPLL, CLK_TOP_HDMITX_CLKDIG_CTS, 1, 1),
+ FACTOR1(CLK_TOP_HDMIPLL_D2, CLK_TOP_HDMITX_CLKDIG_CTS, 1, 2),
+ FACTOR1(CLK_TOP_HDMIPLL_D3, CLK_TOP_HDMITX_CLKDIG_CTS, 1, 3),
+
+ FACTOR0(CLK_TOP_ARMPLL_1P3G, CLK_APMIXED_ARMPLL, 1, 1),
+
+ FACTOR1(CLK_TOP_AUDPLL, CLK_TOP_AUDPLL_MUX_SEL, 1, 1),
+ FACTOR1(CLK_TOP_AUDPLL_D4, CLK_TOP_AUDPLL_MUX_SEL, 1, 4),
+ FACTOR1(CLK_TOP_AUDPLL_D8, CLK_TOP_AUDPLL_MUX_SEL, 1, 8),
+ FACTOR1(CLK_TOP_AUDPLL_D16, CLK_TOP_AUDPLL_MUX_SEL, 1, 16),
+ FACTOR1(CLK_TOP_AUDPLL_D24, CLK_TOP_AUDPLL_MUX_SEL, 1, 24),
+
+ FACTOR0(CLK_TOP_AUD1PLL_98M, CLK_APMIXED_AUD1PLL, 1, 3),
+ FACTOR0(CLK_TOP_AUD2PLL_90M, CLK_APMIXED_AUD2PLL, 1, 3),
+ FACTOR0(CLK_TOP_HADDS2PLL_98M, CLK_APMIXED_HADDS2PLL, 1, 3),
+ FACTOR0(CLK_TOP_HADDS2PLL_294M, CLK_APMIXED_HADDS2PLL, 1, 1),
+ FACTOR0(CLK_TOP_ETHPLL_500M, CLK_APMIXED_ETHPLL, 1, 1),
+ FACTOR2(CLK_TOP_CLK26M_D8, CLK_XTAL, 1, 8),
+ FACTOR2(CLK_TOP_32K_INTERNAL, CLK_XTAL, 1, 793),
+ FACTOR1(CLK_TOP_AXISEL_D4, CLK_TOP_AXI_SEL, 1, 4),
+ FACTOR1(CLK_TOP_8BDAC, CLK_TOP_UNIVPLL_D2, 1, 1),
+};
+
+static const int axi_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_SYSPLL_D5,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_UNIVPLL_D5,
+ CLK_TOP_UNIVPLL2_D2,
+ CLK_TOP_MMPLL_D2,
+ CLK_TOP_DMPLL_D2
+};
+
+static const int mem_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_DMPLL
+};
+
+static const int ddrphycfg_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D8
+};
+
+static const int mm_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_VENCPLL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_UNIVPLL_D5,
+ CLK_TOP_UNIVPLL1_D2,
+ CLK_TOP_UNIVPLL2_D2,
+ CLK_TOP_DMPLL
+};
+
+static const int pwm_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL2_D4,
+ CLK_TOP_UNIVPLL3_D2,
+ CLK_TOP_UNIVPLL1_D4
+};
+
+static const int vdec_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_VDECPLL,
+ CLK_TOP_SYSPLL_D5,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_UNIVPLL_D5,
+ CLK_TOP_UNIVPLL2_D2,
+ CLK_TOP_VENCPLL,
+ CLK_TOP_MSDCPLL_D2,
+ CLK_TOP_MMPLL_D2
+};
+
+static const int mfg_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_MMPLL,
+ CLK_TOP_DMPLL_X2,
+ CLK_TOP_MSDCPLL,
+ CLK_XTAL,
+ CLK_TOP_SYSPLL_D3,
+ CLK_TOP_UNIVPLL_D3,
+ CLK_TOP_UNIVPLL1_D2
+};
+
+static const int camtg_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL_D26,
+ CLK_TOP_UNIVPLL2_D2,
+ CLK_TOP_SYSPLL3_D2,
+ CLK_TOP_SYSPLL3_D4,
+ CLK_TOP_MSDCPLL_D2,
+ CLK_TOP_MMPLL_D2
+};
+
+static const int uart_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL2_D8
+};
+
+static const int spi_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL3_D2,
+ CLK_TOP_SYSPLL4_D2,
+ CLK_TOP_UNIVPLL2_D4,
+ CLK_TOP_UNIVPLL1_D8
+};
+
+static const int usb20_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL1_D8,
+ CLK_TOP_UNIVPLL3_D4
+};
+
+static const int msdc30_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_MSDCPLL_D2,
+ CLK_TOP_SYSPLL2_D2,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_UNIVPLL1_D4,
+ CLK_TOP_UNIVPLL2_D4,
+};
+
+static const int aud_intbus_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_SYSPLL3_D2,
+ CLK_TOP_SYSPLL4_D2,
+ CLK_TOP_UNIVPLL3_D2,
+ CLK_TOP_UNIVPLL2_D4
+};
+
+static const int pmicspi_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D8,
+ CLK_TOP_SYSPLL2_D4,
+ CLK_TOP_SYSPLL4_D2,
+ CLK_TOP_SYSPLL3_D4,
+ CLK_TOP_SYSPLL2_D8,
+ CLK_TOP_SYSPLL1_D16,
+ CLK_TOP_UNIVPLL3_D4,
+ CLK_TOP_UNIVPLL_D26,
+ CLK_TOP_DMPLL_D2,
+ CLK_TOP_DMPLL_D4
+};
+
+static const int scp_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D8,
+ CLK_TOP_DMPLL_D2,
+ CLK_TOP_DMPLL_D4
+};
+
+static const int dpi0_tve_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_MIPIPLL,
+ CLK_TOP_MIPIPLL_D2,
+ CLK_TOP_MIPIPLL_D4,
+ CLK_XTAL,
+ CLK_TOP_TVDPLL,
+ CLK_TOP_TVDPLL_D2,
+ CLK_TOP_TVDPLL_D4
+};
+
+static const int dpi1_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_TVDPLL,
+ CLK_TOP_TVDPLL_D2,
+ CLK_TOP_TVDPLL_D4
+};
+
+static const int hdmi_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_HDMIPLL,
+ CLK_TOP_HDMIPLL_D2,
+ CLK_TOP_HDMIPLL_D3
+};
+
+static const int apll_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_AUDPLL,
+ CLK_TOP_AUDPLL_D4,
+ CLK_TOP_AUDPLL_D8,
+ CLK_TOP_AUDPLL_D16,
+ CLK_TOP_AUDPLL_D24,
+ CLK_XTAL,
+ CLK_XTAL
+};
+
+static const int rtc_parents[] = {
+ CLK_TOP_32K_INTERNAL,
+ CLK_TOP_32K_EXTERNAL,
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL3_D8
+};
+
+static const int nfi2x_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL2_D2,
+ CLK_TOP_SYSPLL_D7,
+ CLK_TOP_UNIVPLL3_D2,
+ CLK_TOP_SYSPLL2_D4,
+ CLK_TOP_UNIVPLL3_D4,
+ CLK_TOP_SYSPLL4_D4,
+ CLK_XTAL
+};
+
+static const int emmc_hclk_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_SYSPLL2_D2
+};
+
+static const int flash_parents[] = {
+ CLK_TOP_CLK26M_D8,
+ CLK_XTAL,
+ CLK_TOP_SYSPLL2_D8,
+ CLK_TOP_SYSPLL3_D4,
+ CLK_TOP_UNIVPLL3_D4,
+ CLK_TOP_SYSPLL4_D2,
+ CLK_TOP_SYSPLL2_D4,
+ CLK_TOP_UNIVPLL2_D4
+};
+
+static const int di_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_TVD2PLL,
+ CLK_TOP_TVD2PLL_D2,
+ CLK_XTAL
+};
+
+static const int nr_osd_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_VENCPLL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_UNIVPLL_D5,
+ CLK_TOP_UNIVPLL1_D2,
+ CLK_TOP_UNIVPLL2_D2,
+ CLK_TOP_DMPLL
+};
+
+static const int hdmirx_bist_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL_D3,
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D16,
+ CLK_TOP_SYSPLL4_D2,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_VENCPLL,
+ CLK_XTAL
+};
+
+static const int intdir_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_MMPLL,
+ CLK_TOP_SYSPLL_D2,
+ CLK_TOP_UNIVPLL_D2
+};
+
+static const int asm_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL2_D4,
+ CLK_TOP_UNIVPLL2_D2,
+ CLK_TOP_SYSPLL_D5
+};
+
+static const int ms_card_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL3_D8,
+ CLK_TOP_SYSPLL4_D4
+};
+
+static const int ethif_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_SYSPLL_D5,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_UNIVPLL_D5,
+ CLK_TOP_UNIVPLL1_D2,
+ CLK_TOP_DMPLL,
+ CLK_TOP_DMPLL_D2
+};
+
+static const int hdmirx_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL_D52
+};
+
+static const int cmsys_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_UNIVPLL1_D2,
+ CLK_TOP_UNIVPLL_D5,
+ CLK_TOP_SYSPLL_D5,
+ CLK_TOP_SYSPLL2_D2,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_SYSPLL3_D2,
+ CLK_TOP_SYSPLL2_D4,
+ CLK_TOP_SYSPLL1_D8,
+ CLK_XTAL,
+ CLK_XTAL,
+ CLK_XTAL,
+ CLK_XTAL,
+ CLK_XTAL
+};
+
+static const int clk_8bdac_parents[] = {
+ CLK_TOP_32K_INTERNAL,
+ CLK_TOP_8BDAC,
+ CLK_XTAL,
+ CLK_XTAL
+};
+
+static const int aud2dvd_parents[] = {
+ CLK_TOP_AUD_48K_TIMING,
+ CLK_TOP_AUD_44K_TIMING
+};
+
+static const int padmclk_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL_D26,
+ CLK_TOP_UNIVPLL_D52,
+ CLK_TOP_UNIVPLL_D108,
+ CLK_TOP_UNIVPLL2_D8,
+ CLK_TOP_UNIVPLL2_D16,
+ CLK_TOP_UNIVPLL2_D32
+};
+
+static const int aud_mux_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_AUD1PLL_98M,
+ CLK_TOP_AUD2PLL_90M,
+ CLK_TOP_HADDS2PLL_98M,
+ CLK_TOP_AUD_EXTCK1_DIV,
+ CLK_TOP_AUD_EXTCK2_DIV
+};
+
+static const int aud_src_parents[] = {
+ CLK_TOP_AUD_MUX1_SEL,
+ CLK_TOP_AUD_MUX2_SEL
+};
+
+static const struct mtk_composite top_muxes[] = {
+ MUX_GATE(CLK_TOP_AXI_SEL, axi_parents, 0x40, 0, 3, 7),
+ MUX_GATE(CLK_TOP_MEM_SEL, mem_parents, 0x40, 8, 1, 15),
+ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, ddrphycfg_parents, 0x40, 16, 1, 23),
+ MUX_GATE_FLAGS(CLK_TOP_MM_SEL, mm_parents, 0x40, 24, 3, 31,
+ CLK_DOMAIN_SCPSYS),
+
+ MUX_GATE(CLK_TOP_PWM_SEL, pwm_parents, 0x50, 0, 2, 7),
+ MUX_GATE(CLK_TOP_VDEC_SEL, vdec_parents, 0x50, 8, 4, 15),
+ MUX_GATE_FLAGS(CLK_TOP_MFG_SEL, mfg_parents, 0x50, 16, 3, 23,
+ CLK_DOMAIN_SCPSYS),
+ MUX_GATE(CLK_TOP_CAMTG_SEL, camtg_parents, 0x50, 24, 3, 31),
+
+ MUX_GATE(CLK_TOP_UART_SEL, uart_parents, 0x60, 0, 1, 7),
+ MUX_GATE(CLK_TOP_SPI0_SEL, spi_parents, 0x60, 8, 3, 15),
+ MUX_GATE(CLK_TOP_USB20_SEL, usb20_parents, 0x60, 16, 2, 23),
+ MUX_GATE(CLK_TOP_MSDC30_0_SEL, msdc30_parents, 0x60, 24, 3, 31),
+
+ MUX_GATE(CLK_TOP_MSDC30_1_SEL, msdc30_parents, 0x70, 0, 3, 7),
+ MUX_GATE(CLK_TOP_MSDC30_2_SEL, msdc30_parents, 0x70, 8, 3, 15),
+ MUX_GATE(CLK_TOP_AUDIO_SEL, msdc30_parents, 0x70, 16, 1, 23),
+ MUX_GATE(CLK_TOP_AUDINTBUS_SEL, aud_intbus_parents, 0x70, 24, 3, 31),
+
+ MUX_GATE(CLK_TOP_PMICSPI_SEL, pmicspi_parents, 0x80, 0, 4, 7),
+ MUX_GATE(CLK_TOP_SCP_SEL, scp_parents, 0x80, 8, 2, 15),
+ MUX_GATE(CLK_TOP_DPI0_SEL, dpi0_tve_parents, 0x80, 16, 3, 23),
+ MUX_GATE(CLK_TOP_DPI1_SEL, dpi1_parents, 0x80, 24, 2, 31),
+
+ MUX_GATE(CLK_TOP_TVE_SEL, dpi0_tve_parents, 0x90, 0, 3, 7),
+ MUX_GATE(CLK_TOP_HDMI_SEL, hdmi_parents, 0x90, 8, 2, 15),
+ MUX_GATE(CLK_TOP_APLL_SEL, apll_parents, 0x90, 16, 3, 23),
+
+ MUX_GATE(CLK_TOP_RTC_SEL, rtc_parents, 0xA0, 0, 2, 7),
+ MUX_GATE(CLK_TOP_NFI2X_SEL, nfi2x_parents, 0xA0, 8, 3, 15),
+ MUX_GATE(CLK_TOP_EMMC_HCLK_SEL, emmc_hclk_parents, 0xA0, 24, 2, 31),
+
+ MUX_GATE(CLK_TOP_FLASH_SEL, flash_parents, 0xB0, 0, 3, 7),
+ MUX_GATE(CLK_TOP_DI_SEL, di_parents, 0xB0, 8, 2, 15),
+ MUX_GATE(CLK_TOP_NR_SEL, nr_osd_parents, 0xB0, 16, 3, 23),
+ MUX_GATE(CLK_TOP_OSD_SEL, nr_osd_parents, 0xB0, 24, 3, 31),
+
+ MUX_GATE(CLK_TOP_HDMIRX_BIST_SEL, hdmirx_bist_parents, 0xC0, 0, 3, 7),
+ MUX_GATE(CLK_TOP_INTDIR_SEL, intdir_parents, 0xC0, 8, 2, 15),
+ MUX_GATE(CLK_TOP_ASM_I_SEL, asm_parents, 0xC0, 16, 2, 23),
+ MUX_GATE(CLK_TOP_ASM_M_SEL, asm_parents, 0xC0, 24, 3, 31),
+
+ MUX_GATE(CLK_TOP_ASM_H_SEL, asm_parents, 0xD0, 0, 2, 7),
+ MUX_GATE(CLK_TOP_MS_CARD_SEL, ms_card_parents, 0xD0, 16, 2, 23),
+ MUX_GATE_FLAGS(CLK_TOP_ETHIF_SEL, ethif_parents, 0xD0, 24, 3, 31,
+ CLK_DOMAIN_SCPSYS),
+
+ MUX_GATE(CLK_TOP_HDMIRX26_24_SEL, hdmirx_parents, 0xE0, 0, 1, 7),
+ MUX_GATE(CLK_TOP_MSDC30_3_SEL, msdc30_parents, 0xE0, 8, 3, 15),
+ MUX_GATE(CLK_TOP_CMSYS_SEL, cmsys_parents, 0xE0, 16, 4, 23),
+
+ MUX_GATE(CLK_TOP_SPI1_SEL, spi_parents, 0xE0, 24, 3, 31),
+ MUX_GATE(CLK_TOP_SPI2_SEL, spi_parents, 0xF0, 0, 3, 7),
+ MUX_GATE(CLK_TOP_8BDAC_SEL, clk_8bdac_parents, 0xF0, 8, 2, 15),
+ MUX_GATE(CLK_TOP_AUD2DVD_SEL, aud2dvd_parents, 0xF0, 16, 1, 23),
+
+ MUX(CLK_TOP_PADMCLK_SEL, padmclk_parents, 0x100, 0, 3),
+
+ MUX(CLK_TOP_AUD_MUX1_SEL, aud_mux_parents, 0x12c, 0, 3),
+ MUX(CLK_TOP_AUD_MUX2_SEL, aud_mux_parents, 0x12c, 3, 3),
+ MUX(CLK_TOP_AUDPLL_MUX_SEL, aud_mux_parents, 0x12c, 6, 3),
+
+ MUX_GATE(CLK_TOP_AUD_K1_SRC_SEL, aud_src_parents, 0x12c, 15, 1, 23),
+ MUX_GATE(CLK_TOP_AUD_K2_SRC_SEL, aud_src_parents, 0x12c, 16, 1, 24),
+ MUX_GATE(CLK_TOP_AUD_K3_SRC_SEL, aud_src_parents, 0x12c, 17, 1, 25),
+ MUX_GATE(CLK_TOP_AUD_K4_SRC_SEL, aud_src_parents, 0x12c, 18, 1, 26),
+ MUX_GATE(CLK_TOP_AUD_K5_SRC_SEL, aud_src_parents, 0x12c, 19, 1, 27),
+ MUX_GATE(CLK_TOP_AUD_K6_SRC_SEL, aud_src_parents, 0x12c, 20, 1, 28),
+};
+
+/* infracfg */
+static const struct mtk_gate_regs infra_cg_regs = {
+ .set_ofs = 0x40,
+ .clr_ofs = 0x44,
+ .sta_ofs = 0x48,
+};
+
+#define GATE_INFRA(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &infra_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
+ }
+
+static const struct mtk_gate infra_cgs[] = {
+ GATE_INFRA(CLK_INFRA_DBG, CLK_TOP_AXI_SEL, 0),
+ GATE_INFRA(CLK_INFRA_SMI, CLK_TOP_MM_SEL, 1),
+ GATE_INFRA(CLK_INFRA_QAXI_CM4, CLK_TOP_AXI_SEL, 2),
+ GATE_INFRA(CLK_INFRA_AUD_SPLIN_B, CLK_TOP_HADDS2PLL_294M, 4),
+ GATE_INFRA(CLK_INFRA_AUDIO, CLK_XTAL, 5),
+ GATE_INFRA(CLK_INFRA_EFUSE, CLK_XTAL, 6),
+ GATE_INFRA(CLK_INFRA_L2C_SRAM, CLK_TOP_MM_SEL, 7),
+ GATE_INFRA(CLK_INFRA_M4U, CLK_TOP_MEM_SEL, 8),
+ GATE_INFRA(CLK_INFRA_CONNMCU, CLK_TOP_WBG_DIG_416M, 12),
+ GATE_INFRA(CLK_INFRA_TRNG, CLK_TOP_AXI_SEL, 13),
+ GATE_INFRA(CLK_INFRA_RAMBUFIF, CLK_TOP_MEM_SEL, 14),
+ GATE_INFRA(CLK_INFRA_CPUM, CLK_TOP_MEM_SEL, 15),
+ GATE_INFRA(CLK_INFRA_KP, CLK_TOP_AXI_SEL, 16),
+ GATE_INFRA(CLK_INFRA_CEC, CLK_TOP_RTC_SEL, 18),
+ GATE_INFRA(CLK_INFRA_IRRX, CLK_TOP_AXI_SEL, 19),
+ GATE_INFRA(CLK_INFRA_PMICSPI, CLK_TOP_PMICSPI_SEL, 22),
+ GATE_INFRA(CLK_INFRA_PMICWRAP, CLK_TOP_AXI_SEL, 23),
+ GATE_INFRA(CLK_INFRA_DDCCI, CLK_TOP_AXI_SEL, 24),
+};
+
+/* pericfg */
+static const struct mtk_gate_regs peri0_cg_regs = {
+ .set_ofs = 0x8,
+ .clr_ofs = 0x10,
+ .sta_ofs = 0x18,
+};
+
+static const struct mtk_gate_regs peri1_cg_regs = {
+ .set_ofs = 0xC,
+ .clr_ofs = 0x14,
+ .sta_ofs = 0x1C,
+};
+
+#define GATE_PERI0(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &peri0_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
+ }
+
+#define GATE_PERI1(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &peri1_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
+ }
+
+static const struct mtk_gate peri_cgs[] = {
+ GATE_PERI0(CLK_PERI_NFI, CLK_TOP_NFI2X_SEL, 0),
+ GATE_PERI0(CLK_PERI_THERM, CLK_TOP_AXI_SEL, 1),
+ GATE_PERI0(CLK_PERI_PWM1, CLK_TOP_AXISEL_D4, 2),
+ GATE_PERI0(CLK_PERI_PWM2, CLK_TOP_AXISEL_D4, 3),
+ GATE_PERI0(CLK_PERI_PWM3, CLK_TOP_AXISEL_D4, 4),
+ GATE_PERI0(CLK_PERI_PWM4, CLK_TOP_AXISEL_D4, 5),
+ GATE_PERI0(CLK_PERI_PWM5, CLK_TOP_AXISEL_D4, 6),
+ GATE_PERI0(CLK_PERI_PWM6, CLK_TOP_AXISEL_D4, 7),
+ GATE_PERI0(CLK_PERI_PWM7, CLK_TOP_AXISEL_D4, 8),
+ GATE_PERI0(CLK_PERI_PWM, CLK_TOP_AXI_SEL, 9),
+ GATE_PERI0(CLK_PERI_USB0, CLK_TOP_USB20_SEL, 10),
+ GATE_PERI0(CLK_PERI_USB1, CLK_TOP_USB20_SEL, 11),
+ GATE_PERI0(CLK_PERI_AP_DMA, CLK_TOP_AXI_SEL, 12),
+ GATE_PERI0(CLK_PERI_MSDC30_0, CLK_TOP_MSDC30_0_SEL, 13),
+ GATE_PERI0(CLK_PERI_MSDC30_1, CLK_TOP_MSDC30_1_SEL, 14),
+ GATE_PERI0(CLK_PERI_MSDC30_2, CLK_TOP_MSDC30_2_SEL, 15),
+ GATE_PERI0(CLK_PERI_MSDC30_3, CLK_TOP_MSDC30_3_SEL, 16),
+ GATE_PERI0(CLK_PERI_MSDC50_3, CLK_TOP_EMMC_HCLK_SEL, 17),
+ GATE_PERI0(CLK_PERI_NLI, CLK_TOP_AXI_SEL, 18),
+ GATE_PERI0(CLK_PERI_UART0, CLK_TOP_AXI_SEL, 19),
+ GATE_PERI0(CLK_PERI_UART1, CLK_TOP_AXI_SEL, 20),
+ GATE_PERI0(CLK_PERI_UART2, CLK_TOP_AXI_SEL, 21),
+ GATE_PERI0(CLK_PERI_UART3, CLK_TOP_AXI_SEL, 22),
+ GATE_PERI0(CLK_PERI_BTIF, CLK_TOP_AXI_SEL, 23),
+ GATE_PERI0(CLK_PERI_I2C0, CLK_TOP_AXI_SEL, 24),
+ GATE_PERI0(CLK_PERI_I2C1, CLK_TOP_AXI_SEL, 25),
+ GATE_PERI0(CLK_PERI_I2C2, CLK_TOP_AXI_SEL, 26),
+ GATE_PERI0(CLK_PERI_I2C3, CLK_XTAL, 27),
+ GATE_PERI0(CLK_PERI_AUXADC, CLK_XTAL, 28),
+ GATE_PERI0(CLK_PERI_SPI0, CLK_TOP_SPI0_SEL, 29),
+ GATE_PERI0(CLK_PERI_ETH, CLK_XTAL, 30),
+ GATE_PERI0(CLK_PERI_USB0_MCU, CLK_TOP_AXI_SEL, 31),
+
+ GATE_PERI1(CLK_PERI_USB1_MCU, CLK_TOP_AXI_SEL, 0),
+ GATE_PERI1(CLK_PERI_USB_SLV, CLK_TOP_AXI_SEL, 1),
+ GATE_PERI1(CLK_PERI_GCPU, CLK_TOP_AXI_SEL, 2),
+ GATE_PERI1(CLK_PERI_NFI_ECC, CLK_TOP_NFI1X_PAD, 3),
+ GATE_PERI1(CLK_PERI_NFI_PAD, CLK_TOP_NFI1X_PAD, 4),
+ GATE_PERI1(CLK_PERI_FLASH, CLK_TOP_NFI2X_SEL, 5),
+ GATE_PERI1(CLK_PERI_HOST89_INT, CLK_TOP_AXI_SEL, 6),
+ GATE_PERI1(CLK_PERI_HOST89_SPI, CLK_TOP_SPI0_SEL, 7),
+ GATE_PERI1(CLK_PERI_HOST89_DVD, CLK_TOP_AUD2DVD_SEL, 8),
+ GATE_PERI1(CLK_PERI_SPI1, CLK_TOP_SPI1_SEL, 9),
+ GATE_PERI1(CLK_PERI_SPI2, CLK_TOP_SPI2_SEL, 10),
+ GATE_PERI1(CLK_PERI_FCI, CLK_TOP_MS_CARD_SEL, 11),
+};
+
+/* ethsys */
+static const struct mtk_gate_regs eth_cg_regs = {
+ .sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _parent, _shift, _flag) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &eth_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_NO_SETCLR_INV | (_flag), \
+ }
+
+#define GATE_ETH0(_id, _parent, _shift) \
+ GATE_ETH(_id, _parent, _shift, CLK_PARENT_APMIXED)
+
+#define GATE_ETH1(_id, _parent, _shift) \
+ GATE_ETH(_id, _parent, _shift, CLK_PARENT_TOPCKGEN)
+
+static const struct mtk_gate eth_cgs[] = {
+ GATE_ETH1(CLK_ETHSYS_HSDMA, CLK_TOP_ETHIF_SEL, 5),
+ GATE_ETH1(CLK_ETHSYS_ESW, CLK_TOP_ETHPLL_500M, 6),
+ GATE_ETH0(CLK_ETHSYS_GP2, CLK_APMIXED_TRGPLL, 7),
+ GATE_ETH1(CLK_ETHSYS_GP1, CLK_TOP_ETHPLL_500M, 8),
+ GATE_ETH1(CLK_ETHSYS_PCM, CLK_TOP_ETHIF_SEL, 11),
+ GATE_ETH1(CLK_ETHSYS_GDMA, CLK_TOP_ETHIF_SEL, 14),
+ GATE_ETH1(CLK_ETHSYS_I2S, CLK_TOP_ETHIF_SEL, 17),
+ GATE_ETH1(CLK_ETHSYS_CRYPTO, CLK_TOP_ETHIF_SEL, 29),
+};
+
+static const struct mtk_clk_tree mt7623_clk_tree = {
+ .xtal_rate = 26 * MHZ,
+ .xtal2_rate = 26 * MHZ,
+ .fdivs_offs = CLK_TOP_SYSPLL,
+ .muxes_offs = CLK_TOP_AXI_SEL,
+ .plls = apmixed_plls,
+ .fclks = top_fixed_clks,
+ .fdivs = top_fixed_divs,
+ .muxes = top_muxes,
+};
+
+static int mt7623_mcucfg_probe(struct udevice *dev)
+{
+ void __iomem *base;
+
+ base = dev_read_addr_ptr(dev);
+ if (!base)
+ return -ENOENT;
+
+ clrsetbits_le32(base + MCU_AXI_DIV, AXI_DIV_MSK,
+ AXI_DIV_SEL(0x12));
+
+ return 0;
+}
+
+static int mt7623_apmixedsys_probe(struct udevice *dev)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = mtk_common_clk_init(dev, &mt7623_clk_tree);
+ if (ret)
+ return ret;
+
+ /* reduce clock square disable time */
+ writel(0x50001, priv->base + MT7623_CLKSQ_STB_CON0);
+ /* extend control timing to 1us */
+ writel(0x888, priv->base + MT7623_PLL_ISO_CON0);
+
+ return 0;
+}
+
+static int mt7623_topckgen_probe(struct udevice *dev)
+{
+ return mtk_common_clk_init(dev, &mt7623_clk_tree);
+}
+
+static int mt7623_infracfg_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, infra_cgs);
+}
+
+static int mt7623_pericfg_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, peri_cgs);
+}
+
+static int mt7623_ethsys_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, eth_cgs);
+}
+
+static const struct udevice_id mt7623_apmixed_compat[] = {
+ { .compatible = "mediatek,mt7623-apmixedsys" },
+ { }
+};
+
+static const struct udevice_id mt7623_topckgen_compat[] = {
+ { .compatible = "mediatek,mt7623-topckgen" },
+ { }
+};
+
+static const struct udevice_id mt7623_infracfg_compat[] = {
+ { .compatible = "mediatek,mt7623-infracfg", },
+ { }
+};
+
+static const struct udevice_id mt7623_pericfg_compat[] = {
+ { .compatible = "mediatek,mt7623-pericfg", },
+ { }
+};
+
+static const struct udevice_id mt7623_ethsys_compat[] = {
+ { .compatible = "mediatek,mt7623-ethsys" },
+ { }
+};
+
+static const struct udevice_id mt7623_mcucfg_compat[] = {
+ { .compatible = "mediatek,mt7623-mcucfg" },
+ { }
+};
+
+U_BOOT_DRIVER(mtk_mcucfg) = {
+ .name = "mt7623-mcucfg",
+ .id = UCLASS_SYSCON,
+ .of_match = mt7623_mcucfg_compat,
+ .probe = mt7623_mcucfg_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+ .name = "mt7623-clock-apmixedsys",
+ .id = UCLASS_CLK,
+ .of_match = mt7623_apmixed_compat,
+ .probe = mt7623_apmixedsys_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_apmixedsys_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_topckgen) = {
+ .name = "mt7623-clock-topckgen",
+ .id = UCLASS_CLK,
+ .of_match = mt7623_topckgen_compat,
+ .probe = mt7623_topckgen_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_infracfg) = {
+ .name = "mt7623-infracfg",
+ .id = UCLASS_CLK,
+ .of_match = mt7623_infracfg_compat,
+ .probe = mt7623_infracfg_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_pericfg) = {
+ .name = "mt7623-pericfg",
+ .id = UCLASS_CLK,
+ .of_match = mt7623_pericfg_compat,
+ .probe = mt7623_pericfg_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_ethsys) = {
+ .name = "mt7623-clock-ethsys",
+ .id = UCLASS_CLK,
+ .of_match = mt7623_ethsys_compat,
+ .probe = mt7623_ethsys_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+};
diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c
new file mode 100644
index 0000000..2601b6c
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mt7629.c
@@ -0,0 +1,709 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek clock driver for MT7629 SoC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <dt-bindings/clock/mt7629-clk.h>
+
+#include "clk-mtk.h"
+
+#define MT7629_CLKSQ_STB_CON0 0x20
+#define MT7629_PLL_ISO_CON0 0x2c
+#define MT7629_PLL_FMAX (2500UL * MHZ)
+#define MT7629_CON0_RST_BAR BIT(24)
+
+#define MCU_AXI_DIV 0x640
+#define AXI_DIV_MSK GENMASK(4, 0)
+#define AXI_DIV_SEL(x) (x)
+
+#define MCU_BUS_MUX 0x7c0
+#define MCU_BUS_MSK GENMASK(10, 9)
+#define MCU_BUS_SEL(x) ((x) << 9)
+
+/* apmixedsys */
+#define PLL(_id, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, \
+ _pd_shift, _pcw_reg, _pcw_shift) { \
+ .id = _id, \
+ .reg = _reg, \
+ .pwr_reg = _pwr_reg, \
+ .en_mask = _en_mask, \
+ .rst_bar_mask = MT7629_CON0_RST_BAR, \
+ .fmax = MT7629_PLL_FMAX, \
+ .flags = _flags, \
+ .pcwbits = _pcwbits, \
+ .pd_reg = _pd_reg, \
+ .pd_shift = _pd_shift, \
+ .pcw_reg = _pcw_reg, \
+ .pcw_shift = _pcw_shift, \
+ }
+
+static const struct mtk_pll_data apmixed_plls[] = {
+ PLL(CLK_APMIXED_ARMPLL, 0x200, 0x20c, 0x1, 0,
+ 21, 0x204, 24, 0x204, 0),
+ PLL(CLK_APMIXED_MAINPLL, 0x210, 0x21c, 0x1, HAVE_RST_BAR,
+ 21, 0x214, 24, 0x214, 0),
+ PLL(CLK_APMIXED_UNIV2PLL, 0x220, 0x22c, 0x1, HAVE_RST_BAR,
+ 7, 0x224, 24, 0x224, 14),
+ PLL(CLK_APMIXED_ETH1PLL, 0x300, 0x310, 0x1, 0,
+ 21, 0x300, 1, 0x304, 0),
+ PLL(CLK_APMIXED_ETH2PLL, 0x314, 0x320, 0x1, 0,
+ 21, 0x314, 1, 0x318, 0),
+ PLL(CLK_APMIXED_SGMIPLL, 0x358, 0x368, 0x1, 0,
+ 21, 0x358, 1, 0x35c, 0),
+};
+
+/* topckgen */
+#define FACTOR0(_id, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED)
+
+#define FACTOR1(_id, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN)
+
+#define FACTOR2(_id, _parent, _mult, _div) \
+ FACTOR(_id, _parent, _mult, _div, 0)
+
+static const struct mtk_fixed_clk top_fixed_clks[] = {
+ FIXED_CLK(CLK_TOP_TO_U2_PHY, CLK_XTAL, 31250000),
+ FIXED_CLK(CLK_TOP_TO_U2_PHY_1P, CLK_XTAL, 31250000),
+ FIXED_CLK(CLK_TOP_PCIE0_PIPE_EN, CLK_XTAL, 125000000),
+ FIXED_CLK(CLK_TOP_PCIE1_PIPE_EN, CLK_XTAL, 125000000),
+ FIXED_CLK(CLK_TOP_SSUSB_TX250M, CLK_XTAL, 250000000),
+ FIXED_CLK(CLK_TOP_SSUSB_EQ_RX250M, CLK_XTAL, 250000000),
+ FIXED_CLK(CLK_TOP_SSUSB_CDR_REF, CLK_XTAL, 33333333),
+ FIXED_CLK(CLK_TOP_SSUSB_CDR_FB, CLK_XTAL, 50000000),
+ FIXED_CLK(CLK_TOP_SATA_ASIC, CLK_XTAL, 50000000),
+ FIXED_CLK(CLK_TOP_SATA_RBC, CLK_XTAL, 50000000),
+};
+
+static const struct mtk_fixed_factor top_fixed_divs[] = {
+ FACTOR0(CLK_TOP_TO_USB3_SYS, CLK_APMIXED_ETH1PLL, 1, 4),
+ FACTOR0(CLK_TOP_P1_1MHZ, CLK_APMIXED_ETH1PLL, 1, 500),
+ FACTOR0(CLK_TOP_4MHZ, CLK_APMIXED_ETH1PLL, 1, 125),
+ FACTOR0(CLK_TOP_P0_1MHZ, CLK_APMIXED_ETH1PLL, 1, 500),
+ FACTOR0(CLK_TOP_ETH_500M, CLK_APMIXED_ETH1PLL, 1, 1),
+ FACTOR1(CLK_TOP_TXCLK_SRC_PRE, CLK_TOP_SGMIIPLL_D2, 1, 1),
+ FACTOR2(CLK_TOP_RTC, CLK_XTAL, 1, 1024),
+ FACTOR2(CLK_TOP_PWM_QTR_26M, CLK_XTAL, 1, 1),
+ FACTOR2(CLK_TOP_CPUM_TCK_IN, CLK_XTAL, 1, 1),
+ FACTOR2(CLK_TOP_TO_USB3_DA_TOP, CLK_XTAL, 1, 1),
+ FACTOR2(CLK_TOP_MEMPLL, CLK_XTAL, 32, 1),
+ FACTOR1(CLK_TOP_DMPLL, CLK_TOP_MEMPLL, 1, 1),
+ FACTOR1(CLK_TOP_DMPLL_D4, CLK_TOP_MEMPLL, 1, 4),
+ FACTOR1(CLK_TOP_DMPLL_D8, CLK_TOP_MEMPLL, 1, 8),
+ FACTOR0(CLK_TOP_SYSPLL_D2, CLK_APMIXED_MAINPLL, 1, 2),
+ FACTOR0(CLK_TOP_SYSPLL1_D2, CLK_APMIXED_MAINPLL, 1, 4),
+ FACTOR0(CLK_TOP_SYSPLL1_D4, CLK_APMIXED_MAINPLL, 1, 8),
+ FACTOR0(CLK_TOP_SYSPLL1_D8, CLK_APMIXED_MAINPLL, 1, 16),
+ FACTOR0(CLK_TOP_SYSPLL1_D16, CLK_APMIXED_MAINPLL, 1, 32),
+ FACTOR0(CLK_TOP_SYSPLL2_D2, CLK_APMIXED_MAINPLL, 1, 6),
+ FACTOR0(CLK_TOP_SYSPLL2_D4, CLK_APMIXED_MAINPLL, 1, 12),
+ FACTOR0(CLK_TOP_SYSPLL2_D8, CLK_APMIXED_MAINPLL, 1, 24),
+ FACTOR0(CLK_TOP_SYSPLL_D5, CLK_APMIXED_MAINPLL, 1, 5),
+ FACTOR0(CLK_TOP_SYSPLL3_D2, CLK_APMIXED_MAINPLL, 1, 10),
+ FACTOR0(CLK_TOP_SYSPLL3_D4, CLK_APMIXED_MAINPLL, 1, 20),
+ FACTOR0(CLK_TOP_SYSPLL_D7, CLK_APMIXED_MAINPLL, 1, 7),
+ FACTOR0(CLK_TOP_SYSPLL4_D2, CLK_APMIXED_MAINPLL, 1, 14),
+ FACTOR0(CLK_TOP_SYSPLL4_D4, CLK_APMIXED_MAINPLL, 1, 28),
+ FACTOR0(CLK_TOP_SYSPLL4_D16, CLK_APMIXED_MAINPLL, 1, 112),
+ FACTOR0(CLK_TOP_UNIVPLL, CLK_APMIXED_UNIV2PLL, 1, 2),
+ FACTOR1(CLK_TOP_UNIVPLL1_D2, CLK_TOP_UNIVPLL, 1, 4),
+ FACTOR1(CLK_TOP_UNIVPLL1_D4, CLK_TOP_UNIVPLL, 1, 8),
+ FACTOR1(CLK_TOP_UNIVPLL1_D8, CLK_TOP_UNIVPLL, 1, 16),
+ FACTOR1(CLK_TOP_UNIVPLL_D3, CLK_TOP_UNIVPLL, 1, 3),
+ FACTOR1(CLK_TOP_UNIVPLL2_D2, CLK_TOP_UNIVPLL, 1, 6),
+ FACTOR1(CLK_TOP_UNIVPLL2_D4, CLK_TOP_UNIVPLL, 1, 12),
+ FACTOR1(CLK_TOP_UNIVPLL2_D8, CLK_TOP_UNIVPLL, 1, 24),
+ FACTOR1(CLK_TOP_UNIVPLL2_D16, CLK_TOP_UNIVPLL, 1, 48),
+ FACTOR1(CLK_TOP_UNIVPLL_D5, CLK_TOP_UNIVPLL, 1, 5),
+ FACTOR1(CLK_TOP_UNIVPLL3_D2, CLK_TOP_UNIVPLL, 1, 10),
+ FACTOR1(CLK_TOP_UNIVPLL3_D4, CLK_TOP_UNIVPLL, 1, 20),
+ FACTOR1(CLK_TOP_UNIVPLL3_D16, CLK_TOP_UNIVPLL, 1, 80),
+ FACTOR1(CLK_TOP_UNIVPLL_D7, CLK_TOP_UNIVPLL, 1, 7),
+ FACTOR1(CLK_TOP_UNIVPLL_D80_D4, CLK_TOP_UNIVPLL, 1, 320),
+ FACTOR1(CLK_TOP_UNIV48M, CLK_TOP_UNIVPLL, 1, 25),
+ FACTOR0(CLK_TOP_SGMIIPLL_D2, CLK_APMIXED_SGMIPLL, 1, 2),
+ FACTOR2(CLK_TOP_CLKXTAL_D4, CLK_XTAL, 1, 4),
+ FACTOR1(CLK_TOP_HD_FAXI, CLK_TOP_AXI_SEL, 1, 1),
+ FACTOR1(CLK_TOP_FAXI, CLK_TOP_AXI_SEL, 1, 1),
+ FACTOR1(CLK_TOP_F_FAUD_INTBUS, CLK_TOP_AUD_INTBUS_SEL, 1, 1),
+ FACTOR1(CLK_TOP_AP2WBHIF_HCLK, CLK_TOP_SYSPLL1_D8, 1, 1),
+ FACTOR1(CLK_TOP_10M_INFRAO, CLK_TOP_10M_SEL, 1, 1),
+ FACTOR1(CLK_TOP_MSDC30_1, CLK_TOP_MSDC30_1, 1, 1),
+ FACTOR1(CLK_TOP_SPI, CLK_TOP_SPI0_SEL, 1, 1),
+ FACTOR1(CLK_TOP_SF, CLK_TOP_NFI_INFRA_SEL, 1, 1),
+ FACTOR1(CLK_TOP_FLASH, CLK_TOP_FLASH_SEL, 1, 1),
+ FACTOR1(CLK_TOP_TO_USB3_REF, CLK_TOP_SATA_SEL, 1, 4),
+ FACTOR1(CLK_TOP_TO_USB3_MCU, CLK_TOP_AXI_SEL, 1, 1),
+ FACTOR1(CLK_TOP_TO_USB3_DMA, CLK_TOP_HIF_SEL, 1, 1),
+ FACTOR1(CLK_TOP_FROM_TOP_AHB, CLK_TOP_AXI_SEL, 1, 1),
+ FACTOR1(CLK_TOP_FROM_TOP_AXI, CLK_TOP_HIF_SEL, 1, 1),
+ FACTOR1(CLK_TOP_PCIE1_MAC_EN, CLK_TOP_UNIVPLL1_D4, 1, 1),
+ FACTOR1(CLK_TOP_PCIE0_MAC_EN, CLK_TOP_UNIVPLL1_D4, 1, 1),
+};
+
+static const int axi_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_SYSPLL_D5,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_UNIVPLL_D5,
+ CLK_TOP_UNIVPLL2_D2,
+ CLK_TOP_UNIVPLL_D7,
+ CLK_TOP_DMPLL
+};
+
+static const int mem_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_DMPLL
+};
+
+static const int ddrphycfg_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D8
+};
+
+static const int eth_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_UNIVPLL1_D2,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_UNIVPLL_D5,
+ CLK_TOP_SGMIIPLL_D2,
+ CLK_TOP_UNIVPLL_D7,
+ CLK_TOP_DMPLL
+};
+
+static const int pwm_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL2_D4
+};
+
+static const int f10m_ref_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SGMIIPLL_D2
+};
+
+static const int nfi_infra_parents[] = {
+ CLK_XTAL,
+ CLK_XTAL,
+ CLK_XTAL,
+ CLK_XTAL,
+ CLK_XTAL,
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL2_D8,
+ CLK_TOP_UNIVPLL3_D4,
+ CLK_TOP_SYSPLL1_D8,
+ CLK_TOP_UNIVPLL1_D8,
+ CLK_TOP_SYSPLL4_D2,
+ CLK_TOP_SYSPLL2_D4,
+ CLK_TOP_UNIVPLL2_D4,
+ CLK_TOP_UNIVPLL3_D2,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_SYSPLL_D7
+};
+
+static const int flash_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL_D80_D4,
+ CLK_TOP_SYSPLL2_D8,
+ CLK_TOP_SYSPLL3_D4,
+ CLK_TOP_UNIVPLL3_D4,
+ CLK_TOP_UNIVPLL1_D8,
+ CLK_TOP_SYSPLL2_D4,
+ CLK_TOP_UNIVPLL2_D4
+};
+
+static const int uart_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL2_D8
+};
+
+static const int spi0_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL3_D2,
+ CLK_XTAL,
+ CLK_TOP_SYSPLL2_D4,
+ CLK_TOP_SYSPLL4_D2,
+ CLK_TOP_UNIVPLL2_D4,
+ CLK_TOP_UNIVPLL1_D8,
+ CLK_XTAL
+};
+
+static const int spi1_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL3_D2,
+ CLK_XTAL,
+ CLK_TOP_SYSPLL4_D4,
+ CLK_TOP_SYSPLL4_D2,
+ CLK_TOP_UNIVPLL2_D4,
+ CLK_TOP_UNIVPLL1_D8,
+ CLK_XTAL
+};
+
+static const int msdc30_0_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL2_D16,
+ CLK_TOP_UNIV48M
+};
+
+static const int msdc30_1_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL2_D16,
+ CLK_TOP_UNIV48M,
+ CLK_TOP_SYSPLL2_D4,
+ CLK_TOP_UNIVPLL2_D4,
+ CLK_TOP_SYSPLL_D7,
+ CLK_TOP_SYSPLL2_D2,
+ CLK_TOP_UNIVPLL2_D2
+};
+
+static const int ap2wbmcu_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_UNIV48M,
+ CLK_TOP_SYSPLL1_D8,
+ CLK_TOP_UNIVPLL2_D4,
+ CLK_TOP_SYSPLL_D7,
+ CLK_TOP_SYSPLL2_D2,
+ CLK_TOP_UNIVPLL2_D2
+};
+
+static const int audio_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL3_D4,
+ CLK_TOP_SYSPLL4_D4,
+ CLK_TOP_SYSPLL1_D16
+};
+
+static const int aud_intbus_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_SYSPLL4_D2,
+ CLK_TOP_DMPLL_D4
+};
+
+static const int pmicspi_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D8,
+ CLK_TOP_SYSPLL3_D4,
+ CLK_TOP_SYSPLL1_D16,
+ CLK_TOP_UNIVPLL3_D4,
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL2_D4,
+ CLK_TOP_DMPLL_D8
+};
+
+static const int scp_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D8,
+ CLK_TOP_UNIVPLL2_D2,
+ CLK_TOP_UNIVPLL2_D4
+};
+
+static const int atb_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_SYSPLL_D5
+};
+
+static const int hif_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_UNIVPLL1_D2,
+ CLK_TOP_SYSPLL1_D4,
+ CLK_TOP_UNIVPLL_D5,
+ -1,
+ CLK_TOP_UNIVPLL_D7
+};
+
+static const int sata_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL2_D4
+};
+
+static const int usb20_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL3_D4,
+ CLK_TOP_SYSPLL1_D8
+};
+
+static const int aud1_parents[] = {
+ CLK_XTAL
+};
+
+static const int irrx_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_SYSPLL4_D16
+};
+
+static const int crypto_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_UNIVPLL_D3,
+ CLK_TOP_UNIVPLL1_D2,
+ CLK_TOP_SYSPLL1_D2,
+ CLK_TOP_UNIVPLL_D5,
+ CLK_TOP_SYSPLL_D5,
+ CLK_TOP_UNIVPLL2_D2,
+ CLK_TOP_SYSPLL_D2
+};
+
+static const int gpt10m_parents[] = {
+ CLK_XTAL,
+ CLK_TOP_CLKXTAL_D4
+};
+
+static const struct mtk_composite top_muxes[] = {
+ /* CLK_CFG_0 */
+ MUX_GATE(CLK_TOP_AXI_SEL, axi_parents, 0x40, 0, 3, 7),
+ MUX_GATE(CLK_TOP_MEM_SEL, mem_parents, 0x40, 8, 1, 15),
+ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, ddrphycfg_parents, 0x40, 16, 1, 23),
+ MUX_GATE(CLK_TOP_ETH_SEL, eth_parents, 0x40, 24, 3, 31),
+
+ /* CLK_CFG_1 */
+ MUX_GATE(CLK_TOP_PWM_SEL, pwm_parents, 0x50, 0, 2, 7),
+ MUX_GATE(CLK_TOP_F10M_REF_SEL, f10m_ref_parents, 0x50, 8, 1, 15),
+ MUX_GATE(CLK_TOP_NFI_INFRA_SEL, nfi_infra_parents, 0x50, 16, 4, 23),
+ MUX_GATE(CLK_TOP_FLASH_SEL, flash_parents, 0x50, 24, 3, 31),
+
+ /* CLK_CFG_2 */
+ MUX_GATE(CLK_TOP_UART_SEL, uart_parents, 0x60, 0, 1, 7),
+ MUX_GATE(CLK_TOP_SPI0_SEL, spi0_parents, 0x60, 8, 3, 15),
+ MUX_GATE(CLK_TOP_SPI1_SEL, spi1_parents, 0x60, 16, 3, 23),
+ MUX_GATE(CLK_TOP_MSDC50_0_SEL, uart_parents, 0x60, 24, 3, 31),
+
+ /* CLK_CFG_3 */
+ MUX_GATE(CLK_TOP_MSDC30_0_SEL, msdc30_0_parents, 0x70, 0, 3, 7),
+ MUX_GATE(CLK_TOP_MSDC30_1_SEL, msdc30_1_parents, 0x70, 8, 3, 15),
+ MUX_GATE(CLK_TOP_AP2WBMCU_SEL, ap2wbmcu_parents, 0x70, 16, 3, 23),
+ MUX_GATE(CLK_TOP_AP2WBHIF_SEL, ap2wbmcu_parents, 0x70, 24, 3, 31),
+
+ /* CLK_CFG_4 */
+ MUX_GATE(CLK_TOP_AUDIO_SEL, audio_parents, 0x80, 0, 2, 7),
+ MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, aud_intbus_parents, 0x80, 8, 2, 15),
+ MUX_GATE(CLK_TOP_PMICSPI_SEL, pmicspi_parents, 0x80, 16, 3, 23),
+ MUX_GATE(CLK_TOP_SCP_SEL, scp_parents, 0x80, 24, 2, 31),
+
+ /* CLK_CFG_5 */
+ MUX_GATE(CLK_TOP_ATB_SEL, atb_parents, 0x90, 0, 2, 7),
+ MUX_GATE_FLAGS(CLK_TOP_HIF_SEL, hif_parents, 0x90, 8, 3, 15,
+ CLK_DOMAIN_SCPSYS),
+ MUX_GATE(CLK_TOP_SATA_SEL, sata_parents, 0x90, 16, 1, 23),
+ MUX_GATE(CLK_TOP_U2_SEL, usb20_parents, 0x90, 24, 2, 31),
+
+ /* CLK_CFG_6 */
+ MUX_GATE(CLK_TOP_AUD1_SEL, aud1_parents, 0xA0, 0, 1, 7),
+ MUX_GATE(CLK_TOP_AUD2_SEL, aud1_parents, 0xA0, 8, 1, 15),
+ MUX_GATE(CLK_TOP_IRRX_SEL, irrx_parents, 0xA0, 16, 1, 23),
+ MUX_GATE(CLK_TOP_IRTX_SEL, irrx_parents, 0xA0, 24, 1, 31),
+
+ /* CLK_CFG_7 */
+ MUX_GATE(CLK_TOP_SATA_MCU_SEL, scp_parents, 0xB0, 0, 2, 7),
+ MUX_GATE(CLK_TOP_PCIE0_MCU_SEL, scp_parents, 0xB0, 8, 2, 15),
+ MUX_GATE(CLK_TOP_PCIE1_MCU_SEL, scp_parents, 0xB0, 16, 2, 23),
+ MUX_GATE(CLK_TOP_SSUSB_MCU_SEL, scp_parents, 0xB0, 24, 2, 31),
+
+ /* CLK_CFG_8 */
+ MUX_GATE(CLK_TOP_CRYPTO_SEL, crypto_parents, 0xC0, 0, 3, 7),
+ MUX_GATE(CLK_TOP_SGMII_REF_1_SEL, f10m_ref_parents, 0xC0, 8, 1, 15),
+ MUX_GATE(CLK_TOP_10M_SEL, gpt10m_parents, 0xC0, 16, 1, 23),
+};
+
+/* infracfg */
+static const struct mtk_gate_regs infra_cg_regs = {
+ .set_ofs = 0x40,
+ .clr_ofs = 0x44,
+ .sta_ofs = 0x48,
+};
+
+#define GATE_INFRA(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &infra_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
+ }
+
+static const struct mtk_gate infra_cgs[] = {
+ GATE_INFRA(CLK_INFRA_DBGCLK_PD, CLK_TOP_HD_FAXI, 0),
+ GATE_INFRA(CLK_INFRA_TRNG_PD, CLK_TOP_HD_FAXI, 2),
+ GATE_INFRA(CLK_INFRA_DEVAPC_PD, CLK_TOP_HD_FAXI, 4),
+ GATE_INFRA(CLK_INFRA_APXGPT_PD, CLK_TOP_10M_INFRAO, 18),
+ GATE_INFRA(CLK_INFRA_SEJ_PD, CLK_TOP_10M_INFRAO, 19),
+};
+
+/* pericfg */
+static const struct mtk_gate_regs peri0_cg_regs = {
+ .set_ofs = 0x8,
+ .clr_ofs = 0x10,
+ .sta_ofs = 0x18,
+};
+
+static const struct mtk_gate_regs peri1_cg_regs = {
+ .set_ofs = 0xC,
+ .clr_ofs = 0x14,
+ .sta_ofs = 0x1C,
+};
+
+#define GATE_PERI0(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &peri0_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
+ }
+
+#define GATE_PERI1(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &peri1_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_SETCLR | CLK_PARENT_TOPCKGEN, \
+ }
+
+static const struct mtk_gate peri_cgs[] = {
+ GATE_PERI0(CLK_PERI_PWM1_PD, CLK_TOP_PWM_QTR_26M, 2),
+ GATE_PERI0(CLK_PERI_PWM2_PD, CLK_TOP_PWM_QTR_26M, 3),
+ GATE_PERI0(CLK_PERI_PWM3_PD, CLK_TOP_PWM_QTR_26M, 4),
+ GATE_PERI0(CLK_PERI_PWM4_PD, CLK_TOP_PWM_QTR_26M, 5),
+ GATE_PERI0(CLK_PERI_PWM5_PD, CLK_TOP_PWM_QTR_26M, 6),
+ GATE_PERI0(CLK_PERI_PWM6_PD, CLK_TOP_PWM_QTR_26M, 7),
+ GATE_PERI0(CLK_PERI_PWM7_PD, CLK_TOP_PWM_QTR_26M, 8),
+ GATE_PERI0(CLK_PERI_PWM_PD, CLK_TOP_PWM_QTR_26M, 9),
+ GATE_PERI0(CLK_PERI_AP_DMA_PD, CLK_TOP_FAXI, 12),
+ GATE_PERI0(CLK_PERI_MSDC30_1_PD, CLK_TOP_MSDC30_1, 14),
+ GATE_PERI0(CLK_PERI_UART0_PD, CLK_TOP_FAXI, 17),
+ GATE_PERI0(CLK_PERI_UART1_PD, CLK_TOP_FAXI, 18),
+ GATE_PERI0(CLK_PERI_UART2_PD, CLK_TOP_FAXI, 19),
+ GATE_PERI0(CLK_PERI_UART3_PD, CLK_TOP_FAXI, 20),
+ GATE_PERI0(CLK_PERI_BTIF_PD, CLK_TOP_FAXI, 22),
+ GATE_PERI0(CLK_PERI_I2C0_PD, CLK_TOP_FAXI, 23),
+ GATE_PERI0(CLK_PERI_SPI0_PD, CLK_TOP_SPI, 28),
+ GATE_PERI0(CLK_PERI_SNFI_PD, CLK_TOP_SF, 29),
+ GATE_PERI0(CLK_PERI_NFI_PD, CLK_TOP_FAXI, 30),
+ GATE_PERI0(CLK_PERI_NFIECC_PD, CLK_TOP_FAXI, 31),
+ GATE_PERI1(CLK_PERI_FLASH_PD, CLK_TOP_FLASH, 1),
+};
+
+/* ethsys */
+static const struct mtk_gate_regs eth_cg_regs = {
+ .sta_ofs = 0x30,
+};
+
+#define GATE_ETH(_id, _parent, _shift, _flag) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &eth_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_NO_SETCLR_INV | (_flag), \
+ }
+
+#define GATE_ETH0(_id, _parent, _shift) \
+ GATE_ETH(_id, _parent, _shift, CLK_PARENT_APMIXED)
+
+#define GATE_ETH1(_id, _parent, _shift) \
+ GATE_ETH(_id, _parent, _shift, CLK_PARENT_TOPCKGEN)
+
+static const struct mtk_gate eth_cgs[] = {
+ GATE_ETH0(CLK_ETH_FE_EN, CLK_APMIXED_ETH2PLL, 6),
+ GATE_ETH1(CLK_ETH_GP2_EN, CLK_TOP_TXCLK_SRC_PRE, 7),
+ GATE_ETH1(CLK_ETH_GP1_EN, CLK_TOP_TXCLK_SRC_PRE, 8),
+ GATE_ETH1(CLK_ETH_GP0_EN, CLK_TOP_TXCLK_SRC_PRE, 9),
+ GATE_ETH1(CLK_ETH_ESW_EN, CLK_TOP_ETH_500M, 16),
+};
+
+static const struct mtk_gate_regs sgmii_cg_regs = {
+ .set_ofs = 0xE4,
+ .clr_ofs = 0xE4,
+ .sta_ofs = 0xE4,
+};
+
+#define GATE_SGMII(_id, _parent, _shift) { \
+ .id = _id, \
+ .parent = _parent, \
+ .regs = &sgmii_cg_regs, \
+ .shift = _shift, \
+ .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \
+}
+
+static const struct mtk_gate sgmii_cgs[] = {
+ GATE_SGMII(CLK_SGMII_TX_EN, CLK_TOP_SSUSB_TX250M, 2),
+ GATE_SGMII(CLK_SGMII_RX_EN, CLK_TOP_SSUSB_EQ_RX250M, 3),
+ GATE_SGMII(CLK_SGMII_CDR_REF, CLK_TOP_SSUSB_CDR_REF, 4),
+ GATE_SGMII(CLK_SGMII_CDR_FB, CLK_TOP_SSUSB_CDR_FB, 5),
+};
+
+static const struct mtk_clk_tree mt7629_clk_tree = {
+ .xtal_rate = 40 * MHZ,
+ .xtal2_rate = 20 * MHZ,
+ .fdivs_offs = CLK_TOP_TO_USB3_SYS,
+ .muxes_offs = CLK_TOP_AXI_SEL,
+ .plls = apmixed_plls,
+ .fclks = top_fixed_clks,
+ .fdivs = top_fixed_divs,
+ .muxes = top_muxes,
+};
+
+static int mt7629_mcucfg_probe(struct udevice *dev)
+{
+ void __iomem *base;
+
+ base = dev_read_addr_ptr(dev);
+ if (!base)
+ return -ENOENT;
+
+ clrsetbits_le32(base + MCU_AXI_DIV, AXI_DIV_MSK,
+ AXI_DIV_SEL(0x12));
+ clrsetbits_le32(base + MCU_BUS_MUX, MCU_BUS_MSK,
+ MCU_BUS_SEL(0x1));
+
+ return 0;
+}
+
+static int mt7629_apmixedsys_probe(struct udevice *dev)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = mtk_common_clk_init(dev, &mt7629_clk_tree);
+ if (ret)
+ return ret;
+
+ /* reduce clock square disable time */
+ writel(0x501, priv->base + MT7629_CLKSQ_STB_CON0);
+ /* extend pwr/iso control timing to 1us */
+ writel(0x80008, priv->base + MT7629_PLL_ISO_CON0);
+
+ return 0;
+}
+
+static int mt7629_topckgen_probe(struct udevice *dev)
+{
+ return mtk_common_clk_init(dev, &mt7629_clk_tree);
+}
+
+static int mt7629_infracfg_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, infra_cgs);
+}
+
+static int mt7629_pericfg_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, peri_cgs);
+}
+
+static int mt7629_ethsys_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, eth_cgs);
+}
+
+static int mt7629_sgmiisys_probe(struct udevice *dev)
+{
+ return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, sgmii_cgs);
+}
+
+static const struct udevice_id mt7629_apmixed_compat[] = {
+ { .compatible = "mediatek,mt7629-apmixedsys" },
+ { }
+};
+
+static const struct udevice_id mt7629_topckgen_compat[] = {
+ { .compatible = "mediatek,mt7629-topckgen" },
+ { }
+};
+
+static const struct udevice_id mt7629_infracfg_compat[] = {
+ { .compatible = "mediatek,mt7629-infracfg", },
+ { }
+};
+
+static const struct udevice_id mt7629_pericfg_compat[] = {
+ { .compatible = "mediatek,mt7629-pericfg", },
+ { }
+};
+
+static const struct udevice_id mt7629_ethsys_compat[] = {
+ { .compatible = "mediatek,mt7629-ethsys", },
+ { }
+};
+
+static const struct udevice_id mt7629_sgmiisys_compat[] = {
+ { .compatible = "mediatek,mt7629-sgmiisys", },
+ { }
+};
+
+static const struct udevice_id mt7629_mcucfg_compat[] = {
+ { .compatible = "mediatek,mt7629-mcucfg" },
+ { }
+};
+
+U_BOOT_DRIVER(mtk_mcucfg) = {
+ .name = "mt7629-mcucfg",
+ .id = UCLASS_SYSCON,
+ .of_match = mt7629_mcucfg_compat,
+ .probe = mt7629_mcucfg_probe,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_apmixedsys) = {
+ .name = "mt7629-clock-apmixedsys",
+ .id = UCLASS_CLK,
+ .of_match = mt7629_apmixed_compat,
+ .probe = mt7629_apmixedsys_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_apmixedsys_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_topckgen) = {
+ .name = "mt7629-clock-topckgen",
+ .id = UCLASS_CLK,
+ .of_match = mt7629_topckgen_compat,
+ .probe = mt7629_topckgen_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_clk_priv),
+ .ops = &mtk_clk_topckgen_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_infracfg) = {
+ .name = "mt7629-clock-infracfg",
+ .id = UCLASS_CLK,
+ .of_match = mt7629_infracfg_compat,
+ .probe = mt7629_infracfg_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_pericfg) = {
+ .name = "mt7629-clock-pericfg",
+ .id = UCLASS_CLK,
+ .of_match = mt7629_pericfg_compat,
+ .probe = mt7629_pericfg_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRIVER(mtk_clk_ethsys) = {
+ .name = "mt7629-clock-ethsys",
+ .id = UCLASS_CLK,
+ .of_match = mt7629_ethsys_compat,
+ .probe = mt7629_ethsys_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+};
+
+U_BOOT_DRIVER(mtk_clk_sgmiisys) = {
+ .name = "mt7629-clock-sgmiisys",
+ .id = UCLASS_CLK,
+ .of_match = mt7629_sgmiisys_compat,
+ .probe = mt7629_sgmiisys_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
+ .ops = &mtk_clk_gate_ops,
+};
diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c
new file mode 100644
index 0000000..870b14e
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mtk.c
@@ -0,0 +1,493 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek common clock driver
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <clk-uclass.h>
+#include <div64.h>
+#include <dm.h>
+#include <asm/io.h>
+
+#include "clk-mtk.h"
+
+#define REG_CON0 0
+#define REG_CON1 4
+
+#define CON0_BASE_EN BIT(0)
+#define CON0_PWR_ON BIT(0)
+#define CON0_ISO_EN BIT(1)
+#define CON1_PCW_CHG BIT(31)
+
+#define POSTDIV_MASK 0x7
+#define INTEGER_BITS 7
+
+/* scpsys clock off control */
+#define CLK_SCP_CFG0 0x200
+#define CLK_SCP_CFG1 0x204
+#define SCP_ARMCK_OFF_EN GENMASK(9, 0)
+#define SCP_AXICK_DCM_DIS_EN BIT(0)
+#define SCP_AXICK_26M_SEL_EN BIT(4)
+
+/* shared functions */
+
+/*
+ * In case the rate change propagation to parent clocks is undesirable,
+ * this function is recursively called to find the parent to calculate
+ * the accurate frequency.
+ */
+static int mtk_clk_find_parent_rate(struct clk *clk, int id,
+ const struct driver *drv)
+{
+ struct clk parent = { .id = id, };
+
+ if (drv) {
+ struct udevice *dev;
+
+ if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev))
+ return -ENODEV;
+
+ parent.dev = dev;
+ } else {
+ parent.dev = clk->dev;
+ }
+
+ return clk_get_rate(&parent);
+}
+
+static int mtk_clk_mux_set_parent(void __iomem *base, u32 parent,
+ const struct mtk_composite *mux)
+{
+ u32 val, index = 0;
+
+ while (mux->parent[index] != parent)
+ if (++index == mux->num_parents)
+ return -EINVAL;
+
+ /* switch mux to a select parent */
+ val = readl(base + mux->mux_reg);
+ val &= ~(mux->mux_mask << mux->mux_shift);
+
+ val |= index << mux->mux_shift;
+ writel(val, base + mux->mux_reg);
+
+ return 0;
+}
+
+/* apmixedsys functions */
+
+static unsigned long __mtk_pll_recalc_rate(const struct mtk_pll_data *pll,
+ u32 fin, u32 pcw, int postdiv)
+{
+ int pcwbits = pll->pcwbits;
+ int pcwfbits;
+ u64 vco;
+ u8 c = 0;
+
+ /* The fractional part of the PLL divider. */
+ pcwfbits = pcwbits > INTEGER_BITS ? pcwbits - INTEGER_BITS : 0;
+
+ vco = (u64)fin * pcw;
+
+ if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0)))
+ c = 1;
+
+ vco >>= pcwfbits;
+
+ if (c)
+ vco++;
+
+ return ((unsigned long)vco + postdiv - 1) / postdiv;
+}
+
+/**
+ * MediaTek PLLs are configured through their pcw value. The pcw value
+ * describes a divider in the PLL feedback loop which consists of 7 bits
+ * for the integer part and the remaining bits (if present) for the
+ * fractional part. Also they have a 3 bit power-of-two post divider.
+ */
+static void mtk_pll_set_rate_regs(struct clk *clk, u32 pcw, int postdiv)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+ u32 val;
+
+ /* set postdiv */
+ val = readl(priv->base + pll->pd_reg);
+ val &= ~(POSTDIV_MASK << pll->pd_shift);
+ val |= (ffs(postdiv) - 1) << pll->pd_shift;
+
+ /* postdiv and pcw need to set at the same time if on same register */
+ if (pll->pd_reg != pll->pcw_reg) {
+ writel(val, priv->base + pll->pd_reg);
+ val = readl(priv->base + pll->pcw_reg);
+ }
+
+ /* set pcw */
+ val &= ~GENMASK(pll->pcw_shift + pll->pcwbits - 1, pll->pcw_shift);
+ val |= pcw << pll->pcw_shift;
+ val &= ~CON1_PCW_CHG;
+ writel(val, priv->base + pll->pcw_reg);
+
+ val |= CON1_PCW_CHG;
+ writel(val, priv->base + pll->pcw_reg);
+
+ udelay(20);
+}
+
+/**
+ * mtk_pll_calc_values - calculate good values for a given input frequency.
+ * @clk: The clk
+ * @pcw: The pcw value (output)
+ * @postdiv: The post divider (output)
+ * @freq: The desired target frequency
+ */
+static void mtk_pll_calc_values(struct clk *clk, u32 *pcw, u32 *postdiv,
+ u32 freq)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+ unsigned long fmin = 1000 * MHZ;
+ u64 _pcw;
+ u32 val;
+
+ if (freq > pll->fmax)
+ freq = pll->fmax;
+
+ for (val = 0; val < 5; val++) {
+ *postdiv = 1 << val;
+ if ((u64)freq * *postdiv >= fmin)
+ break;
+ }
+
+ /* _pcw = freq * postdiv / xtal_rate * 2^pcwfbits */
+ _pcw = ((u64)freq << val) << (pll->pcwbits - INTEGER_BITS);
+ do_div(_pcw, priv->tree->xtal2_rate);
+
+ *pcw = (u32)_pcw;
+}
+
+static ulong mtk_apmixedsys_set_rate(struct clk *clk, ulong rate)
+{
+ u32 pcw = 0;
+ u32 postdiv;
+
+ mtk_pll_calc_values(clk, &pcw, &postdiv, rate);
+ mtk_pll_set_rate_regs(clk, pcw, postdiv);
+
+ return 0;
+}
+
+static ulong mtk_apmixedsys_get_rate(struct clk *clk)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+ u32 postdiv;
+ u32 pcw;
+
+ postdiv = (readl(priv->base + pll->pd_reg) >> pll->pd_shift) &
+ POSTDIV_MASK;
+ postdiv = 1 << postdiv;
+
+ pcw = readl(priv->base + pll->pcw_reg) >> pll->pcw_shift;
+ pcw &= GENMASK(pll->pcwbits - 1, 0);
+
+ return __mtk_pll_recalc_rate(pll, priv->tree->xtal2_rate,
+ pcw, postdiv);
+}
+
+static int mtk_apmixedsys_enable(struct clk *clk)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+ u32 r;
+
+ r = readl(priv->base + pll->pwr_reg) | CON0_PWR_ON;
+ writel(r, priv->base + pll->pwr_reg);
+ udelay(1);
+
+ r = readl(priv->base + pll->pwr_reg) & ~CON0_ISO_EN;
+ writel(r, priv->base + pll->pwr_reg);
+ udelay(1);
+
+ r = readl(priv->base + pll->reg + REG_CON0);
+ r |= pll->en_mask;
+ writel(r, priv->base + pll->reg + REG_CON0);
+
+ udelay(20);
+
+ if (pll->flags & HAVE_RST_BAR) {
+ r = readl(priv->base + pll->reg + REG_CON0);
+ r |= pll->rst_bar_mask;
+ writel(r, priv->base + pll->reg + REG_CON0);
+ }
+
+ return 0;
+}
+
+static int mtk_apmixedsys_disable(struct clk *clk)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_pll_data *pll = &priv->tree->plls[clk->id];
+ u32 r;
+
+ if (pll->flags & HAVE_RST_BAR) {
+ r = readl(priv->base + pll->reg + REG_CON0);
+ r &= ~pll->rst_bar_mask;
+ writel(r, priv->base + pll->reg + REG_CON0);
+ }
+
+ r = readl(priv->base + pll->reg + REG_CON0);
+ r &= ~CON0_BASE_EN;
+ writel(r, priv->base + pll->reg + REG_CON0);
+
+ r = readl(priv->base + pll->pwr_reg) | CON0_ISO_EN;
+ writel(r, priv->base + pll->pwr_reg);
+
+ r = readl(priv->base + pll->pwr_reg) & ~CON0_PWR_ON;
+ writel(r, priv->base + pll->pwr_reg);
+
+ return 0;
+}
+
+/* topckgen functions */
+
+static ulong mtk_factor_recalc_rate(const struct mtk_fixed_factor *fdiv,
+ ulong parent_rate)
+{
+ u64 rate = parent_rate * fdiv->mult;
+
+ do_div(rate, fdiv->div);
+
+ return rate;
+}
+
+static int mtk_topckgen_get_factor_rate(struct clk *clk, u32 off)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_fixed_factor *fdiv = &priv->tree->fdivs[off];
+ ulong rate;
+
+ switch (fdiv->flags & CLK_PARENT_MASK) {
+ case CLK_PARENT_APMIXED:
+ rate = mtk_clk_find_parent_rate(clk, fdiv->parent,
+ DM_GET_DRIVER(mtk_clk_apmixedsys));
+ break;
+ case CLK_PARENT_TOPCKGEN:
+ rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL);
+ break;
+
+ default:
+ rate = priv->tree->xtal_rate;
+ }
+
+ return mtk_factor_recalc_rate(fdiv, rate);
+}
+
+static int mtk_topckgen_get_mux_rate(struct clk *clk, u32 off)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_composite *mux = &priv->tree->muxes[off];
+ u32 index;
+
+ index = readl(priv->base + mux->mux_reg);
+ index &= mux->mux_mask << mux->mux_shift;
+ index = index >> mux->mux_shift;
+
+ if (mux->parent[index])
+ return mtk_clk_find_parent_rate(clk, mux->parent[index],
+ NULL);
+
+ return priv->tree->xtal_rate;
+}
+
+static ulong mtk_topckgen_get_rate(struct clk *clk)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (clk->id < priv->tree->fdivs_offs)
+ return priv->tree->fclks[clk->id].rate;
+ else if (clk->id < priv->tree->muxes_offs)
+ return mtk_topckgen_get_factor_rate(clk, clk->id -
+ priv->tree->fdivs_offs);
+ else
+ return mtk_topckgen_get_mux_rate(clk, clk->id -
+ priv->tree->muxes_offs);
+}
+
+static int mtk_topckgen_enable(struct clk *clk)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_composite *mux;
+ u32 val;
+
+ if (clk->id < priv->tree->muxes_offs)
+ return 0;
+
+ mux = &priv->tree->muxes[clk->id - priv->tree->muxes_offs];
+ if (mux->gate_shift < 0)
+ return 0;
+
+ /* enable clock gate */
+ val = readl(priv->base + mux->gate_reg);
+ val &= ~BIT(mux->gate_shift);
+ writel(val, priv->base + mux->gate_reg);
+
+ if (mux->flags & CLK_DOMAIN_SCPSYS) {
+ /* enable scpsys clock off control */
+ writel(SCP_ARMCK_OFF_EN, priv->base + CLK_SCP_CFG0);
+ writel(SCP_AXICK_DCM_DIS_EN | SCP_AXICK_26M_SEL_EN,
+ priv->base + CLK_SCP_CFG1);
+ }
+
+ return 0;
+}
+
+static int mtk_topckgen_disable(struct clk *clk)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_composite *mux;
+ u32 val;
+
+ if (clk->id < priv->tree->muxes_offs)
+ return 0;
+
+ mux = &priv->tree->muxes[clk->id - priv->tree->muxes_offs];
+ if (mux->gate_shift < 0)
+ return 0;
+
+ /* disable clock gate */
+ val = readl(priv->base + mux->gate_reg);
+ val |= BIT(mux->gate_shift);
+ writel(val, priv->base + mux->gate_reg);
+
+ return 0;
+}
+
+static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (clk->id < priv->tree->muxes_offs)
+ return 0;
+
+ return mtk_clk_mux_set_parent(priv->base, parent->id,
+ &priv->tree->muxes[clk->id - priv->tree->muxes_offs]);
+}
+
+/* CG functions */
+
+static int mtk_clk_gate_enable(struct clk *clk)
+{
+ struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_gate *gate = &priv->gates[clk->id];
+ u32 bit = BIT(gate->shift);
+
+ switch (gate->flags & CLK_GATE_MASK) {
+ case CLK_GATE_SETCLR:
+ writel(bit, priv->base + gate->regs->clr_ofs);
+ break;
+ case CLK_GATE_NO_SETCLR_INV:
+ clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, bit);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mtk_clk_gate_disable(struct clk *clk)
+{
+ struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_gate *gate = &priv->gates[clk->id];
+ u32 bit = BIT(gate->shift);
+
+ switch (gate->flags & CLK_GATE_MASK) {
+ case CLK_GATE_SETCLR:
+ writel(bit, priv->base + gate->regs->set_ofs);
+ break;
+ case CLK_GATE_NO_SETCLR_INV:
+ clrsetbits_le32(priv->base + gate->regs->sta_ofs, bit, 0);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static ulong mtk_clk_gate_get_rate(struct clk *clk)
+{
+ struct mtk_cg_priv *priv = dev_get_priv(clk->dev);
+ const struct mtk_gate *gate = &priv->gates[clk->id];
+
+ switch (gate->flags & CLK_PARENT_MASK) {
+ case CLK_PARENT_APMIXED:
+ return mtk_clk_find_parent_rate(clk, gate->parent,
+ DM_GET_DRIVER(mtk_clk_apmixedsys));
+ break;
+ case CLK_PARENT_TOPCKGEN:
+ return mtk_clk_find_parent_rate(clk, gate->parent,
+ DM_GET_DRIVER(mtk_clk_topckgen));
+ break;
+
+ default:
+ return priv->tree->xtal_rate;
+ }
+}
+
+const struct clk_ops mtk_clk_apmixedsys_ops = {
+ .enable = mtk_apmixedsys_enable,
+ .disable = mtk_apmixedsys_disable,
+ .set_rate = mtk_apmixedsys_set_rate,
+ .get_rate = mtk_apmixedsys_get_rate,
+};
+
+const struct clk_ops mtk_clk_topckgen_ops = {
+ .enable = mtk_topckgen_enable,
+ .disable = mtk_topckgen_disable,
+ .get_rate = mtk_topckgen_get_rate,
+ .set_parent = mtk_topckgen_set_parent,
+};
+
+const struct clk_ops mtk_clk_gate_ops = {
+ .enable = mtk_clk_gate_enable,
+ .disable = mtk_clk_gate_disable,
+ .get_rate = mtk_clk_gate_get_rate,
+};
+
+int mtk_common_clk_init(struct udevice *dev,
+ const struct mtk_clk_tree *tree)
+{
+ struct mtk_clk_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_read_addr_ptr(dev);
+ if (!priv->base)
+ return -ENOENT;
+
+ priv->tree = tree;
+
+ return 0;
+}
+
+int mtk_common_clk_gate_init(struct udevice *dev,
+ const struct mtk_clk_tree *tree,
+ const struct mtk_gate *gates)
+{
+ struct mtk_cg_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_read_addr_ptr(dev);
+ if (!priv->base)
+ return -ENOENT;
+
+ priv->tree = tree;
+ priv->gates = gates;
+
+ return 0;
+}
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
new file mode 100644
index 0000000..74152ed
--- /dev/null
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -0,0 +1,194 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#ifndef __DRV_CLK_MTK_H
+#define __DRV_CLK_MTK_H
+
+#define CLK_XTAL 0
+#define MHZ (1000 * 1000)
+
+#define HAVE_RST_BAR BIT(0)
+#define CLK_DOMAIN_SCPSYS BIT(0)
+
+#define CLK_GATE_SETCLR BIT(0)
+#define CLK_GATE_SETCLR_INV BIT(1)
+#define CLK_GATE_NO_SETCLR BIT(2)
+#define CLK_GATE_NO_SETCLR_INV BIT(3)
+#define CLK_GATE_MASK GENMASK(3, 0)
+
+#define CLK_PARENT_APMIXED BIT(4)
+#define CLK_PARENT_TOPCKGEN BIT(5)
+#define CLK_PARENT_MASK GENMASK(5, 4)
+
+/* struct mtk_pll_data - hardware-specific PLLs data */
+struct mtk_pll_data {
+ const int id;
+ u32 reg;
+ u32 pwr_reg;
+ u32 en_mask;
+ u32 pd_reg;
+ int pd_shift;
+ u32 flags;
+ u32 rst_bar_mask;
+ u64 fmax;
+ int pcwbits;
+ u32 pcw_reg;
+ int pcw_shift;
+};
+
+/**
+ * struct mtk_fixed_clk - fixed clocks
+ *
+ * @id: index of clocks
+ * @parent: index of parnet clocks
+ * @rate: fixed rate
+ */
+struct mtk_fixed_clk {
+ const int id;
+ const int parent;
+ unsigned long rate;
+};
+
+#define FIXED_CLK(_id, _parent, _rate) { \
+ .id = _id, \
+ .parent = _parent, \
+ .rate = _rate, \
+ }
+
+/**
+ * struct mtk_fixed_factor - fixed multiplier and divider clocks
+ *
+ * @id: index of clocks
+ * @parent: index of parnet clocks
+ * @mult: multiplier
+ * @div: divider
+ * @flag: hardware-specific flags
+ */
+struct mtk_fixed_factor {
+ const int id;
+ const int parent;
+ u32 mult;
+ u32 div;
+ u32 flags;
+};
+
+#define FACTOR(_id, _parent, _mult, _div, _flags) { \
+ .id = _id, \
+ .parent = _parent, \
+ .mult = _mult, \
+ .div = _div, \
+ .flags = _flags, \
+ }
+
+/**
+ * struct mtk_composite - aggregate clock of mux, divider and gate clocks
+ *
+ * @id: index of clocks
+ * @parent: index of parnet clocks
+ * @mux_reg: hardware-specific mux register
+ * @gate_reg: hardware-specific gate register
+ * @mux_mask: mask to the mux bit field
+ * @mux_shift: shift to the mux bit field
+ * @gate_shift: shift to the gate bit field
+ * @num_parents: number of parent clocks
+ * @flags: hardware-specific flags
+ */
+struct mtk_composite {
+ const int id;
+ const int *parent;
+ u32 mux_reg;
+ u32 gate_reg;
+ u32 mux_mask;
+ signed char mux_shift;
+ signed char gate_shift;
+ signed char num_parents;
+ u16 flags;
+};
+
+#define MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, \
+ _flags) { \
+ .id = _id, \
+ .mux_reg = _reg, \
+ .mux_shift = _shift, \
+ .mux_mask = BIT(_width) - 1, \
+ .gate_reg = _reg, \
+ .gate_shift = _gate, \
+ .parent = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .flags = _flags, \
+ }
+
+#define MUX_GATE(_id, _parents, _reg, _shift, _width, _gate) \
+ MUX_GATE_FLAGS(_id, _parents, _reg, _shift, _width, _gate, 0)
+
+#define MUX(_id, _parents, _reg, _shift, _width) { \
+ .id = _id, \
+ .mux_reg = _reg, \
+ .mux_shift = _shift, \
+ .mux_mask = BIT(_width) - 1, \
+ .gate_shift = -1, \
+ .parent = _parents, \
+ .num_parents = ARRAY_SIZE(_parents), \
+ .flags = 0, \
+ }
+
+struct mtk_gate_regs {
+ u32 sta_ofs;
+ u32 clr_ofs;
+ u32 set_ofs;
+};
+
+/**
+ * struct mtk_gate - gate clocks
+ *
+ * @id: index of gate clocks
+ * @parent: index of parnet clocks
+ * @regs: hardware-specific mux register
+ * @shift: shift to the gate bit field
+ * @flags: hardware-specific flags
+ */
+struct mtk_gate {
+ const int id;
+ const int parent;
+ const struct mtk_gate_regs *regs;
+ int shift;
+ u32 flags;
+};
+
+/* struct mtk_clk_tree - clock tree */
+struct mtk_clk_tree {
+ unsigned long xtal_rate;
+ unsigned long xtal2_rate;
+ const int fdivs_offs;
+ const int muxes_offs;
+ const struct mtk_pll_data *plls;
+ const struct mtk_fixed_clk *fclks;
+ const struct mtk_fixed_factor *fdivs;
+ const struct mtk_composite *muxes;
+};
+
+struct mtk_clk_priv {
+ void __iomem *base;
+ const struct mtk_clk_tree *tree;
+};
+
+struct mtk_cg_priv {
+ void __iomem *base;
+ const struct mtk_clk_tree *tree;
+ const struct mtk_gate *gates;
+};
+
+extern const struct clk_ops mtk_clk_apmixedsys_ops;
+extern const struct clk_ops mtk_clk_topckgen_ops;
+extern const struct clk_ops mtk_clk_gate_ops;
+
+int mtk_common_clk_init(struct udevice *dev,
+ const struct mtk_clk_tree *tree);
+int mtk_common_clk_gate_init(struct udevice *dev,
+ const struct mtk_clk_tree *tree,
+ const struct mtk_gate *gates);
+
+#endif /* __DRV_CLK_MTK_H */
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 3f7458d..fbd1396 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -602,6 +602,17 @@ config FTSDC010_SDIO
help
This can enable ftsdc010 sdio function.
+config MMC_MTK
+ bool "MediaTek SD/MMC Card Interface support"
+ depends on ARCH_MEDIATEK
+ depends on BLK && DM_MMC
+ depends on OF_CONTROL
+ help
+ This selects the MediaTek(R) Secure digital and Multimedia card Interface.
+ If you have a machine with a integrated SD/MMC card reader, say Y or M here.
+ This is needed if support for any SD/SDIO/MMC devices is required.
+ If unsure, say N.
+
endif
config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 23c5b0d..801a26d 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -65,3 +65,4 @@ obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o
obj-$(CONFIG_MMC_UNIPHIER) += tmio-common.o uniphier-sd.o
obj-$(CONFIG_RENESAS_SDHI) += tmio-common.o renesas-sdhi.o
obj-$(CONFIG_MMC_BCM2835) += bcm2835_sdhost.o
+obj-$(CONFIG_MMC_MTK) += mtk-sd.o
diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c
index 332f1e1..767dfff 100644
--- a/drivers/mmc/meson_gx_mmc.c
+++ b/drivers/mmc/meson_gx_mmc.c
@@ -278,6 +278,7 @@ int meson_mmc_bind(struct udevice *dev)
static const struct udevice_id meson_mmc_match[] = {
{ .compatible = "amlogic,meson-gx-mmc" },
+ { .compatible = "amlogic,meson-axg-mmc" },
{ /* sentinel */ }
};
diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
new file mode 100644
index 0000000..0741a52
--- /dev/null
+++ b/drivers/mmc/mtk-sd.c
@@ -0,0 +1,1394 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek SD/MMC Card Interface driver
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <mmc.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdbool.h>
+#include <asm/gpio.h>
+#include <dm/pinctrl.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+
+/* MSDC_CFG */
+#define MSDC_CFG_HS400_CK_MODE_EXT BIT(22)
+#define MSDC_CFG_CKMOD_EXT_M 0x300000
+#define MSDC_CFG_CKMOD_EXT_S 20
+#define MSDC_CFG_CKDIV_EXT_M 0xfff00
+#define MSDC_CFG_CKDIV_EXT_S 8
+#define MSDC_CFG_HS400_CK_MODE BIT(18)
+#define MSDC_CFG_CKMOD_M 0x30000
+#define MSDC_CFG_CKMOD_S 16
+#define MSDC_CFG_CKDIV_M 0xff00
+#define MSDC_CFG_CKDIV_S 8
+#define MSDC_CFG_CKSTB BIT(7)
+#define MSDC_CFG_PIO BIT(3)
+#define MSDC_CFG_RST BIT(2)
+#define MSDC_CFG_CKPDN BIT(1)
+#define MSDC_CFG_MODE BIT(0)
+
+/* MSDC_IOCON */
+#define MSDC_IOCON_W_DSPL BIT(8)
+#define MSDC_IOCON_DSPL BIT(2)
+#define MSDC_IOCON_RSPL BIT(1)
+
+/* MSDC_PS */
+#define MSDC_PS_DAT0 BIT(16)
+#define MSDC_PS_CDDBCE_M 0xf000
+#define MSDC_PS_CDDBCE_S 12
+#define MSDC_PS_CDSTS BIT(1)
+#define MSDC_PS_CDEN BIT(0)
+
+/* #define MSDC_INT(EN) */
+#define MSDC_INT_ACMDRDY BIT(3)
+#define MSDC_INT_ACMDTMO BIT(4)
+#define MSDC_INT_ACMDCRCERR BIT(5)
+#define MSDC_INT_CMDRDY BIT(8)
+#define MSDC_INT_CMDTMO BIT(9)
+#define MSDC_INT_RSPCRCERR BIT(10)
+#define MSDC_INT_XFER_COMPL BIT(12)
+#define MSDC_INT_DATTMO BIT(14)
+#define MSDC_INT_DATCRCERR BIT(15)
+
+/* MSDC_FIFOCS */
+#define MSDC_FIFOCS_CLR BIT(31)
+#define MSDC_FIFOCS_TXCNT_M 0xff0000
+#define MSDC_FIFOCS_TXCNT_S 16
+#define MSDC_FIFOCS_RXCNT_M 0xff
+#define MSDC_FIFOCS_RXCNT_S 0
+
+/* #define SDC_CFG */
+#define SDC_CFG_DTOC_M 0xff000000
+#define SDC_CFG_DTOC_S 24
+#define SDC_CFG_SDIOIDE BIT(20)
+#define SDC_CFG_SDIO BIT(19)
+#define SDC_CFG_BUSWIDTH_M 0x30000
+#define SDC_CFG_BUSWIDTH_S 16
+
+/* SDC_CMD */
+#define SDC_CMD_BLK_LEN_M 0xfff0000
+#define SDC_CMD_BLK_LEN_S 16
+#define SDC_CMD_STOP BIT(14)
+#define SDC_CMD_WR BIT(13)
+#define SDC_CMD_DTYPE_M 0x1800
+#define SDC_CMD_DTYPE_S 11
+#define SDC_CMD_RSPTYP_M 0x380
+#define SDC_CMD_RSPTYP_S 7
+#define SDC_CMD_CMD_M 0x3f
+#define SDC_CMD_CMD_S 0
+
+/* SDC_STS */
+#define SDC_STS_CMDBUSY BIT(1)
+#define SDC_STS_SDCBUSY BIT(0)
+
+/* SDC_ADV_CFG0 */
+#define SDC_RX_ENHANCE_EN BIT(20)
+
+/* PATCH_BIT0 */
+#define MSDC_INT_DAT_LATCH_CK_SEL_M 0x380
+#define MSDC_INT_DAT_LATCH_CK_SEL_S 7
+
+/* PATCH_BIT1 */
+#define MSDC_PB1_STOP_DLY_M 0xf00
+#define MSDC_PB1_STOP_DLY_S 8
+
+/* PATCH_BIT2 */
+#define MSDC_PB2_CRCSTSENSEL_M 0xe0000000
+#define MSDC_PB2_CRCSTSENSEL_S 29
+#define MSDC_PB2_CFGCRCSTS BIT(28)
+#define MSDC_PB2_RESPSTSENSEL_M 0x70000
+#define MSDC_PB2_RESPSTSENSEL_S 16
+#define MSDC_PB2_CFGRESP BIT(15)
+#define MSDC_PB2_RESPWAIT_M 0x0c
+#define MSDC_PB2_RESPWAIT_S 2
+
+/* PAD_TUNE */
+#define MSDC_PAD_TUNE_CMDRRDLY_M 0x7c00000
+#define MSDC_PAD_TUNE_CMDRRDLY_S 22
+#define MSDC_PAD_TUNE_CMD_SEL BIT(21)
+#define MSDC_PAD_TUNE_CMDRDLY_M 0x1f0000
+#define MSDC_PAD_TUNE_CMDRDLY_S 16
+#define MSDC_PAD_TUNE_RXDLYSEL BIT(15)
+#define MSDC_PAD_TUNE_RD_SEL BIT(13)
+#define MSDC_PAD_TUNE_DATRRDLY_M 0x1f00
+#define MSDC_PAD_TUNE_DATRRDLY_S 8
+#define MSDC_PAD_TUNE_DATWRDLY_M 0x1f
+#define MSDC_PAD_TUNE_DATWRDLY_S 0
+
+/* EMMC50_CFG0 */
+#define EMMC50_CFG_CFCSTS_SEL BIT(4)
+
+/* SDC_FIFO_CFG */
+#define SDC_FIFO_CFG_WRVALIDSEL BIT(24)
+#define SDC_FIFO_CFG_RDVALIDSEL BIT(25)
+
+/* SDC_CFG_BUSWIDTH */
+#define MSDC_BUS_1BITS 0x0
+#define MSDC_BUS_4BITS 0x1
+#define MSDC_BUS_8BITS 0x2
+
+#define MSDC_FIFO_SIZE 128
+
+#define PAD_DELAY_MAX 32
+
+#define DEFAULT_CD_DEBOUNCE 8
+
+#define CMD_INTS_MASK \
+ (MSDC_INT_CMDRDY | MSDC_INT_RSPCRCERR | MSDC_INT_CMDTMO)
+
+#define DATA_INTS_MASK \
+ (MSDC_INT_XFER_COMPL | MSDC_INT_DATTMO | MSDC_INT_DATCRCERR)
+
+/* Register offset */
+struct mtk_sd_regs {
+ u32 msdc_cfg;
+ u32 msdc_iocon;
+ u32 msdc_ps;
+ u32 msdc_int;
+ u32 msdc_inten;
+ u32 msdc_fifocs;
+ u32 msdc_txdata;
+ u32 msdc_rxdata;
+ u32 reserved0[4];
+ u32 sdc_cfg;
+ u32 sdc_cmd;
+ u32 sdc_arg;
+ u32 sdc_sts;
+ u32 sdc_resp[4];
+ u32 sdc_blk_num;
+ u32 sdc_vol_chg;
+ u32 sdc_csts;
+ u32 sdc_csts_en;
+ u32 sdc_datcrc_sts;
+ u32 sdc_adv_cfg0;
+ u32 reserved1[2];
+ u32 emmc_cfg0;
+ u32 emmc_cfg1;
+ u32 emmc_sts;
+ u32 emmc_iocon;
+ u32 sd_acmd_resp;
+ u32 sd_acmd19_trg;
+ u32 sd_acmd19_sts;
+ u32 dma_sa_high4bit;
+ u32 dma_sa;
+ u32 dma_ca;
+ u32 dma_ctrl;
+ u32 dma_cfg;
+ u32 sw_dbg_sel;
+ u32 sw_dbg_out;
+ u32 dma_length;
+ u32 reserved2;
+ u32 patch_bit0;
+ u32 patch_bit1;
+ u32 patch_bit2;
+ u32 reserved3;
+ u32 dat0_tune_crc;
+ u32 dat1_tune_crc;
+ u32 dat2_tune_crc;
+ u32 dat3_tune_crc;
+ u32 cmd_tune_crc;
+ u32 sdio_tune_wind;
+ u32 reserved4[5];
+ u32 pad_tune;
+ u32 pad_tune0;
+ u32 pad_tune1;
+ u32 dat_rd_dly[4];
+ u32 reserved5[2];
+ u32 hw_dbg_sel;
+ u32 main_ver;
+ u32 eco_ver;
+ u32 reserved6[27];
+ u32 pad_ds_tune;
+ u32 reserved7[31];
+ u32 emmc50_cfg0;
+ u32 reserved8[7];
+ u32 sdc_fifo_cfg;
+};
+
+struct msdc_compatible {
+ u8 clk_div_bits;
+ bool pad_tune0;
+ bool async_fifo;
+ bool data_tune;
+ bool busy_check;
+ bool stop_clk_fix;
+ bool enhance_rx;
+};
+
+struct msdc_delay_phase {
+ u8 maxlen;
+ u8 start;
+ u8 final_phase;
+};
+
+struct msdc_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
+struct msdc_tune_para {
+ u32 iocon;
+ u32 pad_tune;
+};
+
+struct msdc_host {
+ struct mtk_sd_regs *base;
+ struct mmc *mmc;
+
+ struct msdc_compatible *dev_comp;
+
+ struct clk src_clk; /* for SD/MMC bus clock */
+ struct clk h_clk; /* MSDC core clock */
+
+ u32 src_clk_freq; /* source clock */
+ u32 mclk; /* mmc framework required bus clock */
+ u32 sclk; /* actual calculated bus clock */
+
+ /* operation timeout clocks */
+ u32 timeout_ns;
+ u32 timeout_clks;
+
+ /* tuning options */
+ u32 hs400_ds_delay;
+ u32 hs200_cmd_int_delay;
+ u32 hs200_write_int_delay;
+ u32 latch_ck;
+ u32 r_smpl; /* sample edge */
+ bool hs400_mode;
+
+ /* whether to use gpio detection or built-in hw detection */
+ bool builtin_cd;
+
+ /* card detection / write protection GPIOs */
+#ifdef CONFIG_DM_GPIO
+ struct gpio_desc gpio_wp;
+ struct gpio_desc gpio_cd;
+#endif
+
+ uint last_resp_type;
+ uint last_data_write;
+
+ enum bus_mode timing;
+
+ struct msdc_tune_para def_tune_para;
+ struct msdc_tune_para saved_tune_para;
+};
+
+static void msdc_reset_hw(struct msdc_host *host)
+{
+ u32 reg;
+
+ setbits_le32(&host->base->msdc_cfg, MSDC_CFG_RST);
+
+ readl_poll_timeout(&host->base->msdc_cfg, reg,
+ !(reg & MSDC_CFG_RST), 1000000);
+}
+
+static void msdc_fifo_clr(struct msdc_host *host)
+{
+ u32 reg;
+
+ setbits_le32(&host->base->msdc_fifocs, MSDC_FIFOCS_CLR);
+
+ readl_poll_timeout(&host->base->msdc_fifocs, reg,
+ !(reg & MSDC_FIFOCS_CLR), 1000000);
+}
+
+static u32 msdc_fifo_rx_bytes(struct msdc_host *host)
+{
+ return (readl(&host->base->msdc_fifocs) &
+ MSDC_FIFOCS_RXCNT_M) >> MSDC_FIFOCS_RXCNT_S;
+}
+
+static u32 msdc_fifo_tx_bytes(struct msdc_host *host)
+{
+ return (readl(&host->base->msdc_fifocs) &
+ MSDC_FIFOCS_TXCNT_M) >> MSDC_FIFOCS_TXCNT_S;
+}
+
+static u32 msdc_cmd_find_resp(struct msdc_host *host, struct mmc_cmd *cmd)
+{
+ u32 resp;
+
+ switch (cmd->resp_type) {
+ /* Actually, R1, R5, R6, R7 are the same */
+ case MMC_RSP_R1:
+ resp = 0x1;
+ break;
+ case MMC_RSP_R1b:
+ resp = 0x7;
+ break;
+ case MMC_RSP_R2:
+ resp = 0x2;
+ break;
+ case MMC_RSP_R3:
+ resp = 0x3;
+ break;
+ case MMC_RSP_NONE:
+ default:
+ resp = 0x0;
+ break;
+ }
+
+ return resp;
+}
+
+static u32 msdc_cmd_prepare_raw_cmd(struct msdc_host *host,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ u32 opcode = cmd->cmdidx;
+ u32 resp_type = msdc_cmd_find_resp(host, cmd);
+ uint blocksize = 0;
+ u32 dtype = 0;
+ u32 rawcmd = 0;
+
+ switch (opcode) {
+ case MMC_CMD_WRITE_MULTIPLE_BLOCK:
+ case MMC_CMD_READ_MULTIPLE_BLOCK:
+ dtype = 2;
+ break;
+ case MMC_CMD_WRITE_SINGLE_BLOCK:
+ case MMC_CMD_READ_SINGLE_BLOCK:
+ case SD_CMD_APP_SEND_SCR:
+ dtype = 1;
+ break;
+ case SD_CMD_SWITCH_FUNC: /* same as MMC_CMD_SWITCH */
+ case SD_CMD_SEND_IF_COND: /* same as MMC_CMD_SEND_EXT_CSD */
+ case SD_CMD_APP_SD_STATUS: /* same as MMC_CMD_SEND_STATUS */
+ if (data)
+ dtype = 1;
+ }
+
+ if (data) {
+ if (data->flags == MMC_DATA_WRITE)
+ rawcmd |= SDC_CMD_WR;
+
+ if (data->blocks > 1)
+ dtype = 2;
+
+ blocksize = data->blocksize;
+ }
+
+ rawcmd |= ((opcode << SDC_CMD_CMD_S) & SDC_CMD_CMD_M) |
+ ((resp_type << SDC_CMD_RSPTYP_S) & SDC_CMD_RSPTYP_M) |
+ ((blocksize << SDC_CMD_BLK_LEN_S) & SDC_CMD_BLK_LEN_M) |
+ ((dtype << SDC_CMD_DTYPE_S) & SDC_CMD_DTYPE_M);
+
+ if (opcode == MMC_CMD_STOP_TRANSMISSION)
+ rawcmd |= SDC_CMD_STOP;
+
+ return rawcmd;
+}
+
+static int msdc_cmd_done(struct msdc_host *host, int events,
+ struct mmc_cmd *cmd)
+{
+ u32 *rsp = cmd->response;
+ int ret = 0;
+
+ if (cmd->resp_type & MMC_RSP_PRESENT) {
+ if (cmd->resp_type & MMC_RSP_136) {
+ rsp[0] = readl(&host->base->sdc_resp[3]);
+ rsp[1] = readl(&host->base->sdc_resp[2]);
+ rsp[2] = readl(&host->base->sdc_resp[1]);
+ rsp[3] = readl(&host->base->sdc_resp[0]);
+ } else {
+ rsp[0] = readl(&host->base->sdc_resp[0]);
+ }
+ }
+
+ if (!(events & MSDC_INT_CMDRDY)) {
+ if (cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK &&
+ cmd->cmdidx != MMC_CMD_SEND_TUNING_BLOCK_HS200)
+ /*
+ * should not clear fifo/interrupt as the tune data
+ * may have alreay come.
+ */
+ msdc_reset_hw(host);
+
+ if (events & MSDC_INT_CMDTMO)
+ ret = -ETIMEDOUT;
+ else
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+static bool msdc_cmd_is_ready(struct msdc_host *host)
+{
+ int ret;
+ u32 reg;
+
+ /* The max busy time we can endure is 20ms */
+ ret = readl_poll_timeout(&host->base->sdc_sts, reg,
+ !(reg & SDC_STS_CMDBUSY), 20000);
+
+ if (ret) {
+ pr_err("CMD bus busy detected\n");
+ msdc_reset_hw(host);
+ return false;
+ }
+
+ if (host->last_resp_type == MMC_RSP_R1b && host->last_data_write) {
+ ret = readl_poll_timeout(&host->base->msdc_ps, reg,
+ reg & MSDC_PS_DAT0, 1000000);
+
+ if (ret) {
+ pr_err("Card stuck in programming state!\n");
+ msdc_reset_hw(host);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static int msdc_start_command(struct msdc_host *host, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ u32 rawcmd;
+ u32 status;
+ u32 blocks = 0;
+ int ret;
+
+ if (!msdc_cmd_is_ready(host))
+ return -EIO;
+
+ msdc_fifo_clr(host);
+
+ host->last_resp_type = cmd->resp_type;
+ host->last_data_write = 0;
+
+ rawcmd = msdc_cmd_prepare_raw_cmd(host, cmd, data);
+
+ if (data)
+ blocks = data->blocks;
+
+ writel(CMD_INTS_MASK, &host->base->msdc_int);
+ writel(blocks, &host->base->sdc_blk_num);
+ writel(cmd->cmdarg, &host->base->sdc_arg);
+ writel(rawcmd, &host->base->sdc_cmd);
+
+ ret = readl_poll_timeout(&host->base->msdc_int, status,
+ status & CMD_INTS_MASK, 1000000);
+
+ if (ret)
+ status = MSDC_INT_CMDTMO;
+
+ return msdc_cmd_done(host, status, cmd);
+}
+
+static void msdc_fifo_read(struct msdc_host *host, u8 *buf, u32 size)
+{
+ u32 *wbuf;
+
+ while ((size_t)buf % 4) {
+ *buf++ = readb(&host->base->msdc_rxdata);
+ size--;
+ }
+
+ wbuf = (u32 *)buf;
+ while (size >= 4) {
+ *wbuf++ = readl(&host->base->msdc_rxdata);
+ size -= 4;
+ }
+
+ buf = (u8 *)wbuf;
+ while (size) {
+ *buf++ = readb(&host->base->msdc_rxdata);
+ size--;
+ }
+}
+
+static void msdc_fifo_write(struct msdc_host *host, const u8 *buf, u32 size)
+{
+ const u32 *wbuf;
+
+ while ((size_t)buf % 4) {
+ writeb(*buf++, &host->base->msdc_txdata);
+ size--;
+ }
+
+ wbuf = (const u32 *)buf;
+ while (size >= 4) {
+ writel(*wbuf++, &host->base->msdc_txdata);
+ size -= 4;
+ }
+
+ buf = (const u8 *)wbuf;
+ while (size) {
+ writeb(*buf++, &host->base->msdc_txdata);
+ size--;
+ }
+}
+
+static int msdc_pio_read(struct msdc_host *host, u8 *ptr, u32 size)
+{
+ u32 status;
+ u32 chksz;
+ int ret = 0;
+
+ while (1) {
+ status = readl(&host->base->msdc_int);
+ writel(status, &host->base->msdc_int);
+ status &= DATA_INTS_MASK;
+
+ if (status & MSDC_INT_DATCRCERR) {
+ ret = -EIO;
+ break;
+ }
+
+ if (status & MSDC_INT_DATTMO) {
+ ret = -ETIMEDOUT;
+ break;
+ }
+
+ if (status & MSDC_INT_XFER_COMPL) {
+ if (size) {
+ pr_err("data not fully read\n");
+ ret = -EIO;
+ }
+
+ break;
+ }
+
+ chksz = min(size, (u32)MSDC_FIFO_SIZE);
+
+ if (msdc_fifo_rx_bytes(host) >= chksz) {
+ msdc_fifo_read(host, ptr, chksz);
+ ptr += chksz;
+ size -= chksz;
+ }
+ }
+
+ return ret;
+}
+
+static int msdc_pio_write(struct msdc_host *host, const u8 *ptr, u32 size)
+{
+ u32 status;
+ u32 chksz;
+ int ret = 0;
+
+ while (1) {
+ status = readl(&host->base->msdc_int);
+ writel(status, &host->base->msdc_int);
+ status &= DATA_INTS_MASK;
+
+ if (status & MSDC_INT_DATCRCERR) {
+ ret = -EIO;
+ break;
+ }
+
+ if (status & MSDC_INT_DATTMO) {
+ ret = -ETIMEDOUT;
+ break;
+ }
+
+ if (status & MSDC_INT_XFER_COMPL) {
+ if (size) {
+ pr_err("data not fully written\n");
+ ret = -EIO;
+ }
+
+ break;
+ }
+
+ chksz = min(size, (u32)MSDC_FIFO_SIZE);
+
+ if (MSDC_FIFO_SIZE - msdc_fifo_tx_bytes(host) >= chksz) {
+ msdc_fifo_write(host, ptr, chksz);
+ ptr += chksz;
+ size -= chksz;
+ }
+ }
+
+ return ret;
+}
+
+static int msdc_start_data(struct msdc_host *host, struct mmc_data *data)
+{
+ u32 size;
+ int ret;
+
+ if (data->flags == MMC_DATA_WRITE)
+ host->last_data_write = 1;
+
+ writel(DATA_INTS_MASK, &host->base->msdc_int);
+
+ size = data->blocks * data->blocksize;
+
+ if (data->flags == MMC_DATA_WRITE)
+ ret = msdc_pio_write(host, (const u8 *)data->src, size);
+ else
+ ret = msdc_pio_read(host, (u8 *)data->dest, size);
+
+ if (ret) {
+ msdc_reset_hw(host);
+ msdc_fifo_clr(host);
+ }
+
+ return ret;
+}
+
+static int msdc_ops_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ struct msdc_host *host = dev_get_priv(dev);
+ int ret;
+
+ ret = msdc_start_command(host, cmd, data);
+ if (ret)
+ return ret;
+
+ if (data)
+ return msdc_start_data(host, data);
+
+ return 0;
+}
+
+static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)
+{
+ u32 timeout, clk_ns;
+ u32 mode = 0;
+
+ host->timeout_ns = ns;
+ host->timeout_clks = clks;
+
+ if (host->sclk == 0) {
+ timeout = 0;
+ } else {
+ clk_ns = 1000000000UL / host->sclk;
+ timeout = (ns + clk_ns - 1) / clk_ns + clks;
+ /* unit is 1048576 sclk cycles */
+ timeout = (timeout + (0x1 << 20) - 1) >> 20;
+ if (host->dev_comp->clk_div_bits == 8)
+ mode = (readl(&host->base->msdc_cfg) &
+ MSDC_CFG_CKMOD_M) >> MSDC_CFG_CKMOD_S;
+ else
+ mode = (readl(&host->base->msdc_cfg) &
+ MSDC_CFG_CKMOD_EXT_M) >> MSDC_CFG_CKMOD_EXT_S;
+ /* DDR mode will double the clk cycles for data timeout */
+ timeout = mode >= 2 ? timeout * 2 : timeout;
+ timeout = timeout > 1 ? timeout - 1 : 0;
+ timeout = timeout > 255 ? 255 : timeout;
+ }
+
+ clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M,
+ timeout << SDC_CFG_DTOC_S);
+}
+
+static void msdc_set_buswidth(struct msdc_host *host, u32 width)
+{
+ u32 val = readl(&host->base->sdc_cfg);
+
+ val &= ~SDC_CFG_BUSWIDTH_M;
+
+ switch (width) {
+ default:
+ case 1:
+ val |= (MSDC_BUS_1BITS << SDC_CFG_BUSWIDTH_S);
+ break;
+ case 4:
+ val |= (MSDC_BUS_4BITS << SDC_CFG_BUSWIDTH_S);
+ break;
+ case 8:
+ val |= (MSDC_BUS_8BITS << SDC_CFG_BUSWIDTH_S);
+ break;
+ }
+
+ writel(val, &host->base->sdc_cfg);
+}
+
+static void msdc_set_mclk(struct msdc_host *host, enum bus_mode timing, u32 hz)
+{
+ u32 mode;
+ u32 div;
+ u32 sclk;
+ u32 reg;
+
+ if (!hz) {
+ host->mclk = 0;
+ clrbits_le32(&host->base->msdc_cfg, MSDC_CFG_CKPDN);
+ return;
+ }
+
+ if (host->dev_comp->clk_div_bits == 8)
+ clrbits_le32(&host->base->msdc_cfg, MSDC_CFG_HS400_CK_MODE);
+ else
+ clrbits_le32(&host->base->msdc_cfg,
+ MSDC_CFG_HS400_CK_MODE_EXT);
+
+ if (timing == UHS_DDR50 || timing == MMC_DDR_52 ||
+ timing == MMC_HS_400) {
+ if (timing == MMC_HS_400)
+ mode = 0x3;
+ else
+ mode = 0x2; /* ddr mode and use divisor */
+
+ if (hz >= (host->src_clk_freq >> 2)) {
+ div = 0; /* mean div = 1/4 */
+ sclk = host->src_clk_freq >> 2; /* sclk = clk / 4 */
+ } else {
+ div = (host->src_clk_freq + ((hz << 2) - 1)) /
+ (hz << 2);
+ sclk = (host->src_clk_freq >> 2) / div;
+ div = (div >> 1);
+ }
+
+ if (timing == MMC_HS_400 && hz >= (host->src_clk_freq >> 1)) {
+ if (host->dev_comp->clk_div_bits == 8)
+ setbits_le32(&host->base->msdc_cfg,
+ MSDC_CFG_HS400_CK_MODE);
+ else
+ setbits_le32(&host->base->msdc_cfg,
+ MSDC_CFG_HS400_CK_MODE_EXT);
+
+ sclk = host->src_clk_freq >> 1;
+ div = 0; /* div is ignore when bit18 is set */
+ }
+ } else if (hz >= host->src_clk_freq) {
+ mode = 0x1; /* no divisor */
+ div = 0;
+ sclk = host->src_clk_freq;
+ } else {
+ mode = 0x0; /* use divisor */
+ if (hz >= (host->src_clk_freq >> 1)) {
+ div = 0; /* mean div = 1/2 */
+ sclk = host->src_clk_freq >> 1; /* sclk = clk / 2 */
+ } else {
+ div = (host->src_clk_freq + ((hz << 2) - 1)) /
+ (hz << 2);
+ sclk = (host->src_clk_freq >> 2) / div;
+ }
+ }
+
+ clrbits_le32(&host->base->msdc_cfg, MSDC_CFG_CKPDN);
+
+ if (host->dev_comp->clk_div_bits == 8) {
+ div = min(div, (u32)(MSDC_CFG_CKDIV_M >> MSDC_CFG_CKDIV_S));
+ clrsetbits_le32(&host->base->msdc_cfg,
+ MSDC_CFG_CKMOD_M | MSDC_CFG_CKDIV_M,
+ (mode << MSDC_CFG_CKMOD_S) |
+ (div << MSDC_CFG_CKDIV_S));
+ } else {
+ div = min(div, (u32)(MSDC_CFG_CKDIV_EXT_M >>
+ MSDC_CFG_CKDIV_EXT_S));
+ clrsetbits_le32(&host->base->msdc_cfg,
+ MSDC_CFG_CKMOD_EXT_M | MSDC_CFG_CKDIV_EXT_M,
+ (mode << MSDC_CFG_CKMOD_EXT_S) |
+ (div << MSDC_CFG_CKDIV_EXT_S));
+ }
+
+ readl_poll_timeout(&host->base->msdc_cfg, reg,
+ reg & MSDC_CFG_CKSTB, 1000000);
+
+ setbits_le32(&host->base->msdc_cfg, MSDC_CFG_CKPDN);
+ host->sclk = sclk;
+ host->mclk = hz;
+ host->timing = timing;
+
+ /* needed because clk changed. */
+ msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
+
+ /*
+ * mmc_select_hs400() will drop to 50Mhz and High speed mode,
+ * tune result of hs200/200Mhz is not suitable for 50Mhz
+ */
+ if (host->sclk <= 52000000) {
+ writel(host->def_tune_para.iocon, &host->base->msdc_iocon);
+ writel(host->def_tune_para.pad_tune,
+ &host->base->pad_tune);
+ } else {
+ writel(host->saved_tune_para.iocon, &host->base->msdc_iocon);
+ writel(host->saved_tune_para.pad_tune,
+ &host->base->pad_tune);
+ }
+
+ dev_dbg(dev, "sclk: %d, timing: %d\n", host->sclk, timing);
+}
+
+static int msdc_ops_set_ios(struct udevice *dev)
+{
+ struct msdc_plat *plat = dev_get_platdata(dev);
+ struct msdc_host *host = dev_get_priv(dev);
+ struct mmc *mmc = &plat->mmc;
+ uint clock = mmc->clock;
+
+ msdc_set_buswidth(host, mmc->bus_width);
+
+ if (mmc->clk_disable)
+ clock = 0;
+ else if (clock < mmc->cfg->f_min)
+ clock = mmc->cfg->f_min;
+
+ if (host->mclk != clock || host->timing != mmc->selected_mode)
+ msdc_set_mclk(host, mmc->selected_mode, clock);
+
+ return 0;
+}
+
+static int msdc_ops_get_cd(struct udevice *dev)
+{
+ struct msdc_host *host = dev_get_priv(dev);
+ u32 val;
+
+ if (host->builtin_cd) {
+ val = readl(&host->base->msdc_ps);
+ return !(val & MSDC_PS_CDSTS);
+ }
+
+#ifdef CONFIG_DM_GPIO
+ if (!host->gpio_cd.dev)
+ return 1;
+
+ return dm_gpio_get_value(&host->gpio_cd);
+#else
+ return 1;
+#endif
+}
+
+static int msdc_ops_get_wp(struct udevice *dev)
+{
+ struct msdc_host *host = dev_get_priv(dev);
+
+#ifdef CONFIG_DM_GPIO
+ if (!host->gpio_wp.dev)
+ return 0;
+
+ return !dm_gpio_get_value(&host->gpio_wp);
+#else
+ return 0;
+#endif
+}
+
+#ifdef MMC_SUPPORTS_TUNING
+static u32 test_delay_bit(u32 delay, u32 bit)
+{
+ bit %= PAD_DELAY_MAX;
+ return delay & (1 << bit);
+}
+
+static int get_delay_len(u32 delay, u32 start_bit)
+{
+ int i;
+
+ for (i = 0; i < (PAD_DELAY_MAX - start_bit); i++) {
+ if (test_delay_bit(delay, start_bit + i) == 0)
+ return i;
+ }
+
+ return PAD_DELAY_MAX - start_bit;
+}
+
+static struct msdc_delay_phase get_best_delay(struct msdc_host *host, u32 delay)
+{
+ int start = 0, len = 0;
+ int start_final = 0, len_final = 0;
+ u8 final_phase = 0xff;
+ struct msdc_delay_phase delay_phase = { 0, };
+
+ if (delay == 0) {
+ dev_err(dev, "phase error: [map:%x]\n", delay);
+ delay_phase.final_phase = final_phase;
+ return delay_phase;
+ }
+
+ while (start < PAD_DELAY_MAX) {
+ len = get_delay_len(delay, start);
+ if (len_final < len) {
+ start_final = start;
+ len_final = len;
+ }
+
+ start += len ? len : 1;
+ if (len >= 12 && start_final < 4)
+ break;
+ }
+
+ /* The rule is to find the smallest delay cell */
+ if (start_final == 0)
+ final_phase = (start_final + len_final / 3) % PAD_DELAY_MAX;
+ else
+ final_phase = (start_final + len_final / 2) % PAD_DELAY_MAX;
+
+ dev_info(dev, "phase: [map:%x] [maxlen:%d] [final:%d]\n",
+ delay, len_final, final_phase);
+
+ delay_phase.maxlen = len_final;
+ delay_phase.start = start_final;
+ delay_phase.final_phase = final_phase;
+ return delay_phase;
+}
+
+static int msdc_tune_response(struct udevice *dev, u32 opcode)
+{
+ struct msdc_plat *plat = dev_get_platdata(dev);
+ struct msdc_host *host = dev_get_priv(dev);
+ struct mmc *mmc = &plat->mmc;
+ u32 rise_delay = 0, fall_delay = 0;
+ struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0, };
+ struct msdc_delay_phase internal_delay_phase;
+ u8 final_delay, final_maxlen;
+ u32 internal_delay = 0;
+ void __iomem *tune_reg = &host->base->pad_tune;
+ int cmd_err;
+ int i, j;
+
+ if (host->dev_comp->pad_tune0)
+ tune_reg = &host->base->pad_tune0;
+
+ if (mmc->selected_mode == MMC_HS_200 ||
+ mmc->selected_mode == UHS_SDR104)
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
+ host->hs200_cmd_int_delay <<
+ MSDC_PAD_TUNE_CMDRRDLY_S);
+
+ clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+
+ for (i = 0; i < PAD_DELAY_MAX; i++) {
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
+ i << MSDC_PAD_TUNE_CMDRDLY_S);
+
+ for (j = 0; j < 3; j++) {
+ mmc_send_tuning(mmc, opcode, &cmd_err);
+ if (!cmd_err) {
+ rise_delay |= (1 << i);
+ } else {
+ rise_delay &= ~(1 << i);
+ break;
+ }
+ }
+ }
+
+ final_rise_delay = get_best_delay(host, rise_delay);
+ /* if rising edge has enough margin, do not scan falling edge */
+ if (final_rise_delay.maxlen >= 12 ||
+ (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
+ goto skip_fall;
+
+ setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+ for (i = 0; i < PAD_DELAY_MAX; i++) {
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
+ i << MSDC_PAD_TUNE_CMDRDLY_S);
+
+ for (j = 0; j < 3; j++) {
+ mmc_send_tuning(mmc, opcode, &cmd_err);
+ if (!cmd_err) {
+ fall_delay |= (1 << i);
+ } else {
+ fall_delay &= ~(1 << i);
+ break;
+ }
+ }
+ }
+
+ final_fall_delay = get_best_delay(host, fall_delay);
+
+skip_fall:
+ final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+ if (final_maxlen == final_rise_delay.maxlen) {
+ clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
+ final_rise_delay.final_phase <<
+ MSDC_PAD_TUNE_CMDRDLY_S);
+ final_delay = final_rise_delay.final_phase;
+ } else {
+ setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRDLY_M,
+ final_fall_delay.final_phase <<
+ MSDC_PAD_TUNE_CMDRDLY_S);
+ final_delay = final_fall_delay.final_phase;
+ }
+
+ if (host->dev_comp->async_fifo || host->hs200_cmd_int_delay)
+ goto skip_internal;
+
+ for (i = 0; i < PAD_DELAY_MAX; i++) {
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
+ i << MSDC_PAD_TUNE_CMDRRDLY_S);
+
+ mmc_send_tuning(mmc, opcode, &cmd_err);
+ if (!cmd_err)
+ internal_delay |= (1 << i);
+ }
+
+ dev_err(dev, "Final internal delay: 0x%x\n", internal_delay);
+
+ internal_delay_phase = get_best_delay(host, internal_delay);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
+ internal_delay_phase.final_phase <<
+ MSDC_PAD_TUNE_CMDRRDLY_S);
+
+skip_internal:
+ dev_err(dev, "Final cmd pad delay: %x\n", final_delay);
+ return final_delay == 0xff ? -EIO : 0;
+}
+
+static int msdc_tune_data(struct udevice *dev, u32 opcode)
+{
+ struct msdc_plat *plat = dev_get_platdata(dev);
+ struct msdc_host *host = dev_get_priv(dev);
+ struct mmc *mmc = &plat->mmc;
+ u32 rise_delay = 0, fall_delay = 0;
+ struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0, };
+ u8 final_delay, final_maxlen;
+ void __iomem *tune_reg = &host->base->pad_tune;
+ int cmd_err;
+ int i, ret;
+
+ if (host->dev_comp->pad_tune0)
+ tune_reg = &host->base->pad_tune0;
+
+ clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_DSPL);
+ clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
+
+ for (i = 0; i < PAD_DELAY_MAX; i++) {
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
+ i << MSDC_PAD_TUNE_DATRRDLY_S);
+
+ ret = mmc_send_tuning(mmc, opcode, &cmd_err);
+ if (!ret) {
+ rise_delay |= (1 << i);
+ } else if (cmd_err) {
+ /* in this case, retune response is needed */
+ ret = msdc_tune_response(dev, opcode);
+ if (ret)
+ break;
+ }
+ }
+
+ final_rise_delay = get_best_delay(host, rise_delay);
+ if (final_rise_delay.maxlen >= 12 ||
+ (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
+ goto skip_fall;
+
+ setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_DSPL);
+ setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
+
+ for (i = 0; i < PAD_DELAY_MAX; i++) {
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
+ i << MSDC_PAD_TUNE_DATRRDLY_S);
+
+ ret = mmc_send_tuning(mmc, opcode, &cmd_err);
+ if (!ret) {
+ fall_delay |= (1 << i);
+ } else if (cmd_err) {
+ /* in this case, retune response is needed */
+ ret = msdc_tune_response(dev, opcode);
+ if (ret)
+ break;
+ }
+ }
+
+ final_fall_delay = get_best_delay(host, fall_delay);
+
+skip_fall:
+ final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+ if (final_maxlen == final_rise_delay.maxlen) {
+ clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_DSPL);
+ clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
+ final_rise_delay.final_phase <<
+ MSDC_PAD_TUNE_DATRRDLY_S);
+ final_delay = final_rise_delay.final_phase;
+ } else {
+ setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_DSPL);
+ setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_W_DSPL);
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
+ final_fall_delay.final_phase <<
+ MSDC_PAD_TUNE_DATRRDLY_S);
+ final_delay = final_fall_delay.final_phase;
+ }
+
+ if (mmc->selected_mode == MMC_HS_200 ||
+ mmc->selected_mode == UHS_SDR104)
+ clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATWRDLY_M,
+ host->hs200_write_int_delay <<
+ MSDC_PAD_TUNE_DATWRDLY_S);
+
+ dev_err(dev, "Final data pad delay: %x\n", final_delay);
+
+ return final_delay == 0xff ? -EIO : 0;
+}
+
+static int msdc_execute_tuning(struct udevice *dev, uint opcode)
+{
+ struct msdc_plat *plat = dev_get_platdata(dev);
+ struct msdc_host *host = dev_get_priv(dev);
+ struct mmc *mmc = &plat->mmc;
+ int ret;
+
+ if (mmc->selected_mode == MMC_HS_400) {
+ writel(host->hs400_ds_delay, &host->base->pad_ds_tune);
+ /* for hs400 mode it must be set to 0 */
+ clrbits_le32(&host->base->patch_bit2, MSDC_PB2_CFGCRCSTS);
+ host->hs400_mode = true;
+ }
+
+ ret = msdc_tune_response(dev, opcode);
+ if (ret == -EIO) {
+ dev_err(dev, "Tune response fail!\n");
+ return ret;
+ }
+
+ if (!host->hs400_mode) {
+ ret = msdc_tune_data(dev, opcode);
+ if (ret == -EIO)
+ dev_err(dev, "Tune data fail!\n");
+ }
+
+ host->saved_tune_para.iocon = readl(&host->base->msdc_iocon);
+ host->saved_tune_para.pad_tune = readl(&host->base->pad_tune);
+
+ return ret;
+}
+#endif
+
+static void msdc_init_hw(struct msdc_host *host)
+{
+ u32 val;
+ void __iomem *tune_reg = &host->base->pad_tune;
+
+ if (host->dev_comp->pad_tune0)
+ tune_reg = &host->base->pad_tune0;
+
+ /* Configure to MMC/SD mode, clock free running */
+ setbits_le32(&host->base->msdc_cfg, MSDC_CFG_MODE);
+
+ /* Use PIO mode */
+ setbits_le32(&host->base->msdc_cfg, MSDC_CFG_PIO);
+
+ /* Reset */
+ msdc_reset_hw(host);
+
+ /* Enable/disable hw card detection according to fdt option */
+ if (host->builtin_cd)
+ clrsetbits_le32(&host->base->msdc_ps,
+ MSDC_PS_CDDBCE_M,
+ (DEFAULT_CD_DEBOUNCE << MSDC_PS_CDDBCE_S) |
+ MSDC_PS_CDEN);
+ else
+ clrbits_le32(&host->base->msdc_ps, MSDC_PS_CDEN);
+
+ /* Clear all interrupts */
+ val = readl(&host->base->msdc_int);
+ writel(val, &host->base->msdc_int);
+
+ /* Enable data & cmd interrupts */
+ writel(DATA_INTS_MASK | CMD_INTS_MASK, &host->base->msdc_inten);
+
+ writel(0, tune_reg);
+ writel(0, &host->base->msdc_iocon);
+
+ if (host->r_smpl)
+ setbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+ else
+ clrbits_le32(&host->base->msdc_iocon, MSDC_IOCON_RSPL);
+
+ writel(0x403c0046, &host->base->patch_bit0);
+ writel(0xffff4089, &host->base->patch_bit1);
+
+ if (host->dev_comp->stop_clk_fix)
+ clrsetbits_le32(&host->base->patch_bit1, MSDC_PB1_STOP_DLY_M,
+ 3 << MSDC_PB1_STOP_DLY_S);
+
+ if (host->dev_comp->busy_check)
+ clrbits_le32(&host->base->patch_bit1, (1 << 7));
+
+ setbits_le32(&host->base->emmc50_cfg0, EMMC50_CFG_CFCSTS_SEL);
+
+ if (host->dev_comp->async_fifo) {
+ clrsetbits_le32(&host->base->patch_bit2, MSDC_PB2_RESPWAIT_M,
+ 3 << MSDC_PB2_RESPWAIT_S);
+
+ if (host->dev_comp->enhance_rx) {
+ setbits_le32(&host->base->sdc_adv_cfg0,
+ SDC_RX_ENHANCE_EN);
+ } else {
+ clrsetbits_le32(&host->base->patch_bit2,
+ MSDC_PB2_RESPSTSENSEL_M,
+ 2 << MSDC_PB2_RESPSTSENSEL_S);
+ clrsetbits_le32(&host->base->patch_bit2,
+ MSDC_PB2_CRCSTSENSEL_M,
+ 2 << MSDC_PB2_CRCSTSENSEL_S);
+ }
+
+ /* use async fifo to avoid tune internal delay */
+ clrbits_le32(&host->base->patch_bit2,
+ MSDC_PB2_CFGRESP);
+ clrbits_le32(&host->base->patch_bit2,
+ MSDC_PB2_CFGCRCSTS);
+ }
+
+ if (host->dev_comp->data_tune) {
+ setbits_le32(tune_reg,
+ MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL);
+ clrsetbits_le32(&host->base->patch_bit0,
+ MSDC_INT_DAT_LATCH_CK_SEL_M,
+ host->latch_ck <<
+ MSDC_INT_DAT_LATCH_CK_SEL_S);
+ } else {
+ /* choose clock tune */
+ setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL);
+ }
+
+ /* Configure to enable SDIO mode otherwise sdio cmd5 won't work */
+ setbits_le32(&host->base->sdc_cfg, SDC_CFG_SDIO);
+
+ /* disable detecting SDIO device interrupt function */
+ clrbits_le32(&host->base->sdc_cfg, SDC_CFG_SDIOIDE);
+
+ /* Configure to default data timeout */
+ clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M,
+ 3 << SDC_CFG_DTOC_S);
+
+ if (host->dev_comp->stop_clk_fix) {
+ clrbits_le32(&host->base->sdc_fifo_cfg,
+ SDC_FIFO_CFG_WRVALIDSEL);
+ clrbits_le32(&host->base->sdc_fifo_cfg,
+ SDC_FIFO_CFG_RDVALIDSEL);
+ }
+
+ host->def_tune_para.iocon = readl(&host->base->msdc_iocon);
+ host->def_tune_para.pad_tune = readl(&host->base->pad_tune);
+}
+
+static void msdc_ungate_clock(struct msdc_host *host)
+{
+ clk_enable(&host->src_clk);
+ clk_enable(&host->h_clk);
+}
+
+static int msdc_drv_probe(struct udevice *dev)
+{
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct msdc_plat *plat = dev_get_platdata(dev);
+ struct msdc_host *host = dev_get_priv(dev);
+ struct mmc_config *cfg = &plat->cfg;
+
+ cfg->name = dev->name;
+
+ host->dev_comp = (struct msdc_compatible *)dev_get_driver_data(dev);
+
+ host->src_clk_freq = clk_get_rate(&host->src_clk);
+
+ if (host->dev_comp->clk_div_bits == 8)
+ cfg->f_min = host->src_clk_freq / (4 * 255);
+ else
+ cfg->f_min = host->src_clk_freq / (4 * 4095);
+ cfg->f_max = host->src_clk_freq / 2;
+
+ cfg->b_max = 1024;
+ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+ host->mmc = &plat->mmc;
+ host->timeout_ns = 100000000;
+ host->timeout_clks = 3 * 1048576;
+
+#ifdef CONFIG_PINCTRL
+ pinctrl_select_state(dev, "default");
+#endif
+
+ msdc_ungate_clock(host);
+ msdc_init_hw(host);
+
+ upriv->mmc = &plat->mmc;
+
+ return 0;
+}
+
+static int msdc_ofdata_to_platdata(struct udevice *dev)
+{
+ struct msdc_plat *plat = dev_get_platdata(dev);
+ struct msdc_host *host = dev_get_priv(dev);
+ struct mmc_config *cfg = &plat->cfg;
+ int ret;
+
+ host->base = (void *)dev_read_addr(dev);
+ if (!host->base)
+ return -EINVAL;
+
+ ret = mmc_of_parse(dev, cfg);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_name(dev, "source", &host->src_clk);
+ if (ret < 0)
+ return ret;
+
+ ret = clk_get_by_name(dev, "hclk", &host->h_clk);
+ if (ret < 0)
+ return ret;
+
+#ifdef CONFIG_DM_GPIO
+ gpio_request_by_name(dev, "wp-gpios", 0, &host->gpio_wp, GPIOD_IS_IN);
+ gpio_request_by_name(dev, "cd-gpios", 0, &host->gpio_cd, GPIOD_IS_IN);
+#endif
+
+ host->hs400_ds_delay = dev_read_u32_default(dev, "hs400-ds-delay", 0);
+ host->hs200_cmd_int_delay =
+ dev_read_u32_default(dev, "cmd_int_delay", 0);
+ host->hs200_write_int_delay =
+ dev_read_u32_default(dev, "write_int_delay", 0);
+ host->latch_ck = dev_read_u32_default(dev, "latch-ck", 0);
+ host->r_smpl = dev_read_u32_default(dev, "r_smpl", 0);
+ host->builtin_cd = dev_read_u32_default(dev, "builtin-cd", 0);
+
+ return 0;
+}
+
+static int msdc_drv_bind(struct udevice *dev)
+{
+ struct msdc_plat *plat = dev_get_platdata(dev);
+
+ return mmc_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct dm_mmc_ops msdc_ops = {
+ .send_cmd = msdc_ops_send_cmd,
+ .set_ios = msdc_ops_set_ios,
+ .get_cd = msdc_ops_get_cd,
+ .get_wp = msdc_ops_get_wp,
+#ifdef MMC_SUPPORTS_TUNING
+ .execute_tuning = msdc_execute_tuning,
+#endif
+};
+
+static const struct msdc_compatible mt7623_compat = {
+ .clk_div_bits = 12,
+ .pad_tune0 = true,
+ .async_fifo = true,
+ .data_tune = true,
+ .busy_check = false,
+ .stop_clk_fix = false,
+ .enhance_rx = false
+};
+
+static const struct udevice_id msdc_ids[] = {
+ { .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat },
+ {}
+};
+
+U_BOOT_DRIVER(mtk_sd_drv) = {
+ .name = "mtk_sd",
+ .id = UCLASS_MMC,
+ .of_match = msdc_ids,
+ .ofdata_to_platdata = msdc_ofdata_to_platdata,
+ .bind = msdc_drv_bind,
+ .probe = msdc_drv_probe,
+ .ops = &msdc_ops,
+ .platdata_auto_alloc_size = sizeof(struct msdc_plat),
+ .priv_auto_alloc_size = sizeof(struct msdc_host),
+};
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 19db0a8..4fa26ab 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -838,6 +838,8 @@ static const struct udevice_id designware_eth_ids[] = {
{ .compatible = "altr,socfpga-stmmac" },
{ .compatible = "amlogic,meson6-dwmac" },
{ .compatible = "amlogic,meson-gx-dwmac" },
+ { .compatible = "amlogic,meson-gxbb-dwmac" },
+ { .compatible = "amlogic,meson-axg-dwmac" },
{ .compatible = "st,stm32-dwmac" },
{ }
};
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index ad0b8da..7e6fad3 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -301,6 +301,7 @@ config ASPEED_AST2500_PINCTRL
endif
source "drivers/pinctrl/meson/Kconfig"
+source "drivers/pinctrl/mediatek/Kconfig"
source "drivers/pinctrl/nxp/Kconfig"
source "drivers/pinctrl/renesas/Kconfig"
source "drivers/pinctrl/uniphier/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index a3a6c6d..293bad3 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/
obj-$(CONFIG_PINCTRL_PIC32) += pinctrl_pic32.o
obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/
obj-$(CONFIG_PINCTRL_MESON) += meson/
+obj-$(CONFIG_PINCTRL_MTK) += mediatek/
obj-$(CONFIG_ARCH_MVEBU) += mvebu/
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
new file mode 100644
index 0000000..1bd9a92
--- /dev/null
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -0,0 +1,15 @@
+if ARCH_MEDIATEK
+
+config PINCTRL_MTK
+ depends on PINCTRL_GENERIC
+ bool
+
+config PINCTRL_MT7623
+ bool "MT7623 SoC pinctrl driver"
+ select PINCTRL_MTK
+
+config PINCTRL_MT7629
+ bool "MT7629 SoC pinctrl driver"
+ select PINCTRL_MTK
+
+endif
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
new file mode 100644
index 0000000..f6ef362
--- /dev/null
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0
+# Core
+obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o
+
+# SoC Drivers
+obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o
+obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7623.c b/drivers/pinctrl/mediatek/pinctrl-mt7623.c
new file mode 100644
index 0000000..fd37dfa
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7623.c
@@ -0,0 +1,1284 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <dm.h>
+
+#include "pinctrl-mtk-common.h"
+
+#define PIN_BOND_REG0 0xb10
+#define PIN_BOND_REG1 0xf20
+#define PIN_BOND_REG2 0xef0
+#define BOND_PCIE_CLR (0x77 << 3)
+#define BOND_I2S_CLR 0x3
+#define BOND_MSDC0E_CLR 0x1
+
+#define PIN_FIELD15(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
+ PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, \
+ _x_bits, 15, false)
+
+#define PIN_FIELD16(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
+ PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, \
+ _x_bits, 16, false)
+
+#define PINS_FIELD16(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits)\
+ PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, \
+ _x_bits, 16, true)
+
+static const struct mtk_pin_field_calc mt7623_pin_mode_range[] = {
+ PIN_FIELD15(0, 278, 0x760, 0x10, 0, 3),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_dir_range[] = {
+ PIN_FIELD16(0, 175, 0x0, 0x10, 0, 1),
+ PIN_FIELD16(176, 278, 0xc0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_di_range[] = {
+ PIN_FIELD16(0, 278, 0x630, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_do_range[] = {
+ PIN_FIELD16(0, 278, 0x500, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_ies_range[] = {
+ PINS_FIELD16(0, 6, 0xb20, 0x10, 0, 1),
+ PINS_FIELD16(7, 9, 0xb20, 0x10, 1, 1),
+ PINS_FIELD16(10, 13, 0xb30, 0x10, 3, 1),
+ PINS_FIELD16(14, 15, 0xb30, 0x10, 13, 1),
+ PINS_FIELD16(16, 17, 0xb40, 0x10, 7, 1),
+ PINS_FIELD16(18, 29, 0xb40, 0x10, 13, 1),
+ PINS_FIELD16(30, 32, 0xb40, 0x10, 7, 1),
+ PINS_FIELD16(33, 37, 0xb40, 0x10, 13, 1),
+ PIN_FIELD16(38, 38, 0xb20, 0x10, 13, 1),
+ PINS_FIELD16(39, 42, 0xb40, 0x10, 13, 1),
+ PINS_FIELD16(43, 45, 0xb20, 0x10, 10, 1),
+ PINS_FIELD16(47, 48, 0xb20, 0x10, 11, 1),
+ PIN_FIELD16(49, 49, 0xb20, 0x10, 12, 1),
+ PINS_FIELD16(50, 52, 0xb20, 0x10, 13, 1),
+ PINS_FIELD16(53, 56, 0xb20, 0x10, 14, 1),
+ PINS_FIELD16(57, 58, 0xb20, 0x10, 15, 1),
+ PIN_FIELD16(59, 59, 0xb30, 0x10, 10, 1),
+ PINS_FIELD16(60, 62, 0xb30, 0x10, 0, 1),
+ PINS_FIELD16(63, 65, 0xb30, 0x10, 1, 1),
+ PINS_FIELD16(66, 71, 0xb30, 0x10, 2, 1),
+ PINS_FIELD16(72, 74, 0xb20, 0x10, 12, 1),
+ PINS_FIELD16(75, 76, 0xb30, 0x10, 3, 1),
+ PINS_FIELD16(77, 78, 0xb30, 0x10, 4, 1),
+ PINS_FIELD16(79, 82, 0xb30, 0x10, 5, 1),
+ PINS_FIELD16(83, 84, 0xb30, 0x10, 2, 1),
+ PIN_FIELD16(85, 85, 0xda0, 0x10, 4, 1),
+ PIN_FIELD16(86, 86, 0xd90, 0x10, 4, 1),
+ PINS_FIELD16(87, 90, 0xdb0, 0x10, 4, 1),
+ PINS_FIELD16(101, 104, 0xb30, 0x10, 6, 1),
+ PIN_FIELD16(105, 105, 0xd40, 0x10, 4, 1),
+ PIN_FIELD16(106, 106, 0xd30, 0x10, 4, 1),
+ PINS_FIELD16(107, 110, 0xd50, 0x10, 4, 1),
+ PINS_FIELD16(111, 115, 0xce0, 0x10, 4, 1),
+ PIN_FIELD16(116, 116, 0xcd0, 0x10, 4, 1),
+ PIN_FIELD16(117, 117, 0xcc0, 0x10, 4, 1),
+ PINS_FIELD16(118, 121, 0xce0, 0x10, 4, 1),
+ PINS_FIELD16(122, 125, 0xb30, 0x10, 7, 1),
+ PIN_FIELD16(126, 126, 0xb20, 0x10, 12, 1),
+ PINS_FIELD16(127, 142, 0xb30, 0x10, 9, 1),
+ PINS_FIELD16(143, 160, 0xb30, 0x10, 10, 1),
+ PINS_FIELD16(161, 168, 0xb30, 0x10, 12, 1),
+ PINS_FIELD16(169, 183, 0xb30, 0x10, 10, 1),
+ PINS_FIELD16(184, 186, 0xb30, 0x10, 9, 1),
+ PIN_FIELD16(187, 187, 0xb30, 0x10, 14, 1),
+ PIN_FIELD16(188, 188, 0xb20, 0x10, 13, 1),
+ PINS_FIELD16(189, 193, 0xb30, 0x10, 15, 1),
+ PINS_FIELD16(194, 198, 0xb40, 0x10, 0, 1),
+ PIN_FIELD16(199, 199, 0xb20, 0x10, 1, 1),
+ PINS_FIELD16(200, 202, 0xb40, 0x10, 1, 1),
+ PINS_FIELD16(203, 207, 0xb40, 0x10, 2, 1),
+ PINS_FIELD16(208, 209, 0xb40, 0x10, 3, 1),
+ PIN_FIELD16(210, 210, 0xb40, 0x10, 4, 1),
+ PINS_FIELD16(211, 235, 0xb40, 0x10, 5, 1),
+ PINS_FIELD16(236, 241, 0xb40, 0x10, 6, 1),
+ PINS_FIELD16(242, 243, 0xb40, 0x10, 7, 1),
+ PINS_FIELD16(244, 247, 0xb40, 0x10, 8, 1),
+ PIN_FIELD16(248, 248, 0xb40, 0x10, 9, 1),
+ PINS_FIELD16(249, 257, 0xfc0, 0x10, 4, 1),
+ PIN_FIELD16(258, 258, 0xcb0, 0x10, 4, 1),
+ PIN_FIELD16(259, 259, 0xc90, 0x10, 4, 1),
+ PIN_FIELD16(260, 260, 0x3a0, 0x10, 4, 1),
+ PIN_FIELD16(261, 261, 0xd50, 0x10, 4, 1),
+ PINS_FIELD16(262, 277, 0xb40, 0x10, 12, 1),
+ PIN_FIELD16(278, 278, 0xb40, 0x10, 13, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_smt_range[] = {
+ PINS_FIELD16(0, 6, 0xb50, 0x10, 0, 1),
+ PINS_FIELD16(7, 9, 0xb50, 0x10, 1, 1),
+ PINS_FIELD16(10, 13, 0xb60, 0x10, 3, 1),
+ PINS_FIELD16(14, 15, 0xb60, 0x10, 13, 1),
+ PINS_FIELD16(16, 17, 0xb70, 0x10, 7, 1),
+ PINS_FIELD16(18, 29, 0xb70, 0x10, 13, 1),
+ PINS_FIELD16(30, 32, 0xb70, 0x10, 7, 1),
+ PINS_FIELD16(33, 37, 0xb70, 0x10, 13, 1),
+ PIN_FIELD16(38, 38, 0xb50, 0x10, 13, 1),
+ PINS_FIELD16(39, 42, 0xb70, 0x10, 13, 1),
+ PINS_FIELD16(43, 45, 0xb50, 0x10, 10, 1),
+ PINS_FIELD16(47, 48, 0xb50, 0x10, 11, 1),
+ PIN_FIELD16(49, 49, 0xb50, 0x10, 12, 1),
+ PINS_FIELD16(50, 52, 0xb50, 0x10, 13, 1),
+ PINS_FIELD16(53, 56, 0xb50, 0x10, 14, 1),
+ PINS_FIELD16(57, 58, 0xb50, 0x10, 15, 1),
+ PIN_FIELD16(59, 59, 0xb60, 0x10, 10, 1),
+ PINS_FIELD16(60, 62, 0xb60, 0x10, 0, 1),
+ PINS_FIELD16(63, 65, 0xb60, 0x10, 1, 1),
+ PINS_FIELD16(66, 71, 0xb60, 0x10, 2, 1),
+ PINS_FIELD16(72, 74, 0xb50, 0x10, 12, 1),
+ PINS_FIELD16(75, 76, 0xb60, 0x10, 3, 1),
+ PINS_FIELD16(77, 78, 0xb60, 0x10, 4, 1),
+ PINS_FIELD16(79, 82, 0xb60, 0x10, 5, 1),
+ PINS_FIELD16(83, 84, 0xb60, 0x10, 2, 1),
+ PIN_FIELD16(85, 85, 0xda0, 0x10, 11, 1),
+ PIN_FIELD16(86, 86, 0xd90, 0x10, 11, 1),
+ PIN_FIELD16(87, 87, 0xdc0, 0x10, 3, 1),
+ PIN_FIELD16(88, 88, 0xdc0, 0x10, 7, 1),
+ PIN_FIELD16(89, 89, 0xdc0, 0x10, 11, 1),
+ PIN_FIELD16(90, 90, 0xdc0, 0x10, 15, 1),
+ PINS_FIELD16(101, 104, 0xb60, 0x10, 6, 1),
+ PIN_FIELD16(105, 105, 0xd40, 0x10, 11, 1),
+ PIN_FIELD16(106, 106, 0xd30, 0x10, 11, 1),
+ PIN_FIELD16(107, 107, 0xd60, 0x10, 3, 1),
+ PIN_FIELD16(108, 108, 0xd60, 0x10, 7, 1),
+ PIN_FIELD16(109, 109, 0xd60, 0x10, 11, 1),
+ PIN_FIELD16(110, 110, 0xd60, 0x10, 15, 1),
+ PIN_FIELD16(111, 111, 0xd00, 0x10, 15, 1),
+ PIN_FIELD16(112, 112, 0xd00, 0x10, 11, 1),
+ PIN_FIELD16(113, 113, 0xd00, 0x10, 7, 1),
+ PIN_FIELD16(114, 114, 0xd00, 0x10, 3, 1),
+ PIN_FIELD16(115, 115, 0xd10, 0x10, 3, 1),
+ PIN_FIELD16(116, 116, 0xcd0, 0x10, 11, 1),
+ PIN_FIELD16(117, 117, 0xcc0, 0x10, 11, 1),
+ PIN_FIELD16(118, 118, 0xcf0, 0x10, 15, 1),
+ PIN_FIELD16(119, 119, 0xcf0, 0x10, 7, 1),
+ PIN_FIELD16(120, 120, 0xcf0, 0x10, 3, 1),
+ PIN_FIELD16(121, 121, 0xcf0, 0x10, 7, 1),
+ PINS_FIELD16(122, 125, 0xb60, 0x10, 7, 1),
+ PIN_FIELD16(126, 126, 0xb50, 0x10, 12, 1),
+ PINS_FIELD16(127, 142, 0xb60, 0x10, 9, 1),
+ PINS_FIELD16(143, 160, 0xb60, 0x10, 10, 1),
+ PINS_FIELD16(161, 168, 0xb60, 0x10, 12, 1),
+ PINS_FIELD16(169, 183, 0xb60, 0x10, 10, 1),
+ PINS_FIELD16(184, 186, 0xb60, 0x10, 9, 1),
+ PIN_FIELD16(187, 187, 0xb60, 0x10, 14, 1),
+ PIN_FIELD16(188, 188, 0xb50, 0x10, 13, 1),
+ PINS_FIELD16(189, 193, 0xb60, 0x10, 15, 1),
+ PINS_FIELD16(194, 198, 0xb70, 0x10, 0, 1),
+ PIN_FIELD16(199, 199, 0xb50, 0x10, 1, 1),
+ PINS_FIELD16(200, 202, 0xb70, 0x10, 1, 1),
+ PINS_FIELD16(203, 207, 0xb70, 0x10, 2, 1),
+ PINS_FIELD16(208, 209, 0xb70, 0x10, 3, 1),
+ PIN_FIELD16(210, 210, 0xb70, 0x10, 4, 1),
+ PINS_FIELD16(211, 235, 0xb70, 0x10, 5, 1),
+ PINS_FIELD16(236, 241, 0xb70, 0x10, 6, 1),
+ PINS_FIELD16(242, 243, 0xb70, 0x10, 7, 1),
+ PINS_FIELD16(244, 247, 0xb70, 0x10, 8, 1),
+ PIN_FIELD16(248, 248, 0xb70, 0x10, 9, 10),
+ PIN_FIELD16(249, 249, 0x140, 0x10, 3, 1),
+ PIN_FIELD16(250, 250, 0x130, 0x10, 15, 1),
+ PIN_FIELD16(251, 251, 0x130, 0x10, 11, 1),
+ PIN_FIELD16(252, 252, 0x130, 0x10, 7, 1),
+ PIN_FIELD16(253, 253, 0x130, 0x10, 3, 1),
+ PIN_FIELD16(254, 254, 0xf40, 0x10, 15, 1),
+ PIN_FIELD16(255, 255, 0xf40, 0x10, 11, 1),
+ PIN_FIELD16(256, 256, 0xf40, 0x10, 7, 1),
+ PIN_FIELD16(257, 257, 0xf40, 0x10, 3, 1),
+ PIN_FIELD16(258, 258, 0xcb0, 0x10, 11, 1),
+ PIN_FIELD16(259, 259, 0xc90, 0x10, 11, 1),
+ PIN_FIELD16(260, 260, 0x3a0, 0x10, 11, 1),
+ PIN_FIELD16(261, 261, 0x0b0, 0x10, 3, 1),
+ PINS_FIELD16(262, 277, 0xb70, 0x10, 12, 1),
+ PIN_FIELD16(278, 278, 0xb70, 0x10, 13, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_pullen_range[] = {
+ PIN_FIELD16(0, 278, 0x150, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_pullsel_range[] = {
+ PIN_FIELD16(0, 278, 0x280, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7623_pin_drv_range[] = {
+ PINS_FIELD16(0, 6, 0xf50, 0x10, 0, 4),
+ PINS_FIELD16(7, 9, 0xf50, 0x10, 4, 4),
+ PINS_FIELD16(10, 13, 0xf50, 0x10, 4, 4),
+ PINS_FIELD16(14, 15, 0xf50, 0x10, 12, 4),
+ PINS_FIELD16(16, 17, 0xf60, 0x10, 0, 4),
+ PINS_FIELD16(18, 21, 0xf60, 0x10, 0, 4),
+ PINS_FIELD16(22, 26, 0xf60, 0x10, 8, 4),
+ PINS_FIELD16(27, 29, 0xf60, 0x10, 12, 4),
+ PINS_FIELD16(30, 32, 0xf60, 0x10, 0, 4),
+ PINS_FIELD16(33, 37, 0xf70, 0x10, 0, 4),
+ PIN_FIELD16(38, 38, 0xf70, 0x10, 4, 4),
+ PINS_FIELD16(39, 42, 0xf70, 0x10, 8, 4),
+ PINS_FIELD16(43, 45, 0xf70, 0x10, 12, 4),
+ PINS_FIELD16(47, 48, 0xf80, 0x10, 0, 4),
+ PIN_FIELD16(49, 49, 0xf80, 0x10, 4, 4),
+ PINS_FIELD16(50, 52, 0xf70, 0x10, 4, 4),
+ PINS_FIELD16(53, 56, 0xf80, 0x10, 12, 4),
+ PINS_FIELD16(60, 62, 0xf90, 0x10, 8, 4),
+ PINS_FIELD16(63, 65, 0xf90, 0x10, 12, 4),
+ PINS_FIELD16(66, 71, 0xfa0, 0x10, 0, 4),
+ PINS_FIELD16(72, 74, 0xf80, 0x10, 4, 4),
+ PIN_FIELD16(85, 85, 0xda0, 0x10, 0, 4),
+ PIN_FIELD16(86, 86, 0xd90, 0x10, 0, 4),
+ PINS_FIELD16(87, 90, 0xdb0, 0x10, 0, 4),
+ PIN_FIELD16(105, 105, 0xd40, 0x10, 0, 4),
+ PIN_FIELD16(106, 106, 0xd30, 0x10, 0, 4),
+ PINS_FIELD16(107, 110, 0xd50, 0x10, 0, 4),
+ PINS_FIELD16(111, 115, 0xce0, 0x10, 0, 4),
+ PIN_FIELD16(116, 116, 0xcd0, 0x10, 0, 4),
+ PIN_FIELD16(117, 117, 0xcc0, 0x10, 0, 4),
+ PINS_FIELD16(118, 121, 0xce0, 0x10, 0, 4),
+ PIN_FIELD16(126, 126, 0xf80, 0x10, 4, 4),
+ PIN_FIELD16(188, 188, 0xf70, 0x10, 4, 4),
+ PINS_FIELD16(189, 193, 0xfe0, 0x10, 8, 4),
+ PINS_FIELD16(194, 198, 0xfe0, 0x10, 12, 4),
+ PIN_FIELD16(199, 199, 0xf50, 0x10, 4, 4),
+ PINS_FIELD16(200, 202, 0xfd0, 0x10, 0, 4),
+ PINS_FIELD16(203, 207, 0xfd0, 0x10, 4, 4),
+ PINS_FIELD16(208, 209, 0xfd0, 0x10, 8, 4),
+ PIN_FIELD16(210, 210, 0xfd0, 0x10, 12, 4),
+ PINS_FIELD16(211, 235, 0xff0, 0x10, 0, 4),
+ PINS_FIELD16(236, 241, 0xff0, 0x10, 4, 4),
+ PINS_FIELD16(242, 243, 0xff0, 0x10, 8, 4),
+ PIN_FIELD16(248, 248, 0xf00, 0x10, 0, 4),
+ PINS_FIELD16(249, 256, 0xfc0, 0x10, 0, 4),
+ PIN_FIELD16(257, 257, 0xce0, 0x10, 0, 4),
+ PIN_FIELD16(258, 258, 0xcb0, 0x10, 0, 4),
+ PIN_FIELD16(259, 259, 0xc90, 0x10, 0, 4),
+ PIN_FIELD16(260, 260, 0x3a0, 0x10, 0, 4),
+ PIN_FIELD16(261, 261, 0xd50, 0x10, 0, 4),
+ PINS_FIELD16(262, 277, 0xf00, 0x10, 8, 4),
+ PIN_FIELD16(278, 278, 0xf70, 0x10, 8, 4),
+};
+
+static const struct mtk_pin_reg_calc mt7623_reg_cals[] = {
+ [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7623_pin_mode_range),
+ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7623_pin_dir_range),
+ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7623_pin_di_range),
+ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7623_pin_do_range),
+ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7623_pin_ies_range),
+ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7623_pin_smt_range),
+ [PINCTRL_PIN_REG_PULLSEL] = MTK_RANGE(mt7623_pin_pullsel_range),
+ [PINCTRL_PIN_REG_PULLEN] = MTK_RANGE(mt7623_pin_pullen_range),
+ [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7623_pin_drv_range),
+};
+
+static const struct mtk_pin_desc mt7623_pins[] = {
+ MTK_PIN(0, "PWRAP_SPI0_MI", DRV_GRP3),
+ MTK_PIN(1, "PWRAP_SPI0_MO", DRV_GRP3),
+ MTK_PIN(2, "PWRAP_INT", DRV_GRP3),
+ MTK_PIN(3, "PWRAP_SPI0_CK", DRV_GRP3),
+ MTK_PIN(4, "PWRAP_SPI0_CSN", DRV_GRP3),
+ MTK_PIN(5, "PWRAP_SPI0_CK2", DRV_GRP3),
+ MTK_PIN(6, "PWRAP_SPI0_CSN2", DRV_GRP3),
+ MTK_PIN(7, "SPI1_CSN", DRV_GRP3),
+ MTK_PIN(8, "SPI1_MI", DRV_GRP3),
+ MTK_PIN(9, "SPI1_MO", DRV_GRP3),
+ MTK_PIN(10, "RTC32K_CK", DRV_GRP3),
+ MTK_PIN(11, "WATCHDOG", DRV_GRP3),
+ MTK_PIN(12, "SRCLKENA", DRV_GRP3),
+ MTK_PIN(13, "SRCLKENAI", DRV_GRP3),
+ MTK_PIN(14, "URXD2", DRV_GRP1),
+ MTK_PIN(15, "UTXD2", DRV_GRP1),
+ MTK_PIN(16, "I2S5_DATA_IN", DRV_GRP1),
+ MTK_PIN(17, "I2S5_BCK", DRV_GRP1),
+ MTK_PIN(18, "PCM_CLK", DRV_GRP1),
+ MTK_PIN(19, "PCM_SYNC", DRV_GRP1),
+ MTK_PIN(20, "PCM_RX", DRV_GRP1),
+ MTK_PIN(21, "PCM_TX", DRV_GRP1),
+ MTK_PIN(22, "EINT0", DRV_GRP1),
+ MTK_PIN(23, "EINT1", DRV_GRP1),
+ MTK_PIN(24, "EINT2", DRV_GRP1),
+ MTK_PIN(25, "EINT3", DRV_GRP1),
+ MTK_PIN(26, "EINT4", DRV_GRP1),
+ MTK_PIN(27, "EINT5", DRV_GRP1),
+ MTK_PIN(28, "EINT6", DRV_GRP1),
+ MTK_PIN(29, "EINT7", DRV_GRP1),
+ MTK_PIN(30, "I2S5_LRCK", DRV_GRP1),
+ MTK_PIN(31, "I2S5_MCLK", DRV_GRP1),
+ MTK_PIN(32, "I2S5_DATA", DRV_GRP1),
+ MTK_PIN(33, "I2S1_DATA", DRV_GRP1),
+ MTK_PIN(34, "I2S1_DATA_IN", DRV_GRP1),
+ MTK_PIN(35, "I2S1_BCK", DRV_GRP1),
+ MTK_PIN(36, "I2S1_LRCK", DRV_GRP1),
+ MTK_PIN(37, "I2S1_MCLK", DRV_GRP1),
+ MTK_PIN(38, "I2S2_DATA", DRV_GRP1),
+ MTK_PIN(39, "JTMS", DRV_GRP3),
+ MTK_PIN(40, "JTCK", DRV_GRP3),
+ MTK_PIN(41, "JTDI", DRV_GRP3),
+ MTK_PIN(42, "JTDO", DRV_GRP3),
+ MTK_PIN(43, "NCLE", DRV_GRP1),
+ MTK_PIN(44, "NCEB1", DRV_GRP1),
+ MTK_PIN(45, "NCEB0", DRV_GRP1),
+ MTK_PIN(46, "IR", DRV_FIXED),
+ MTK_PIN(47, "NREB", DRV_GRP1),
+ MTK_PIN(48, "NRNB", DRV_GRP1),
+ MTK_PIN(49, "I2S0_DATA", DRV_GRP1),
+ MTK_PIN(50, "I2S2_BCK", DRV_GRP1),
+ MTK_PIN(51, "I2S2_DATA_IN", DRV_GRP1),
+ MTK_PIN(52, "I2S2_LRCK", DRV_GRP1),
+ MTK_PIN(53, "SPI0_CSN", DRV_GRP1),
+ MTK_PIN(54, "SPI0_CK", DRV_GRP1),
+ MTK_PIN(55, "SPI0_MI", DRV_GRP1),
+ MTK_PIN(56, "SPI0_MO", DRV_GRP1),
+ MTK_PIN(57, "SDA1", DRV_FIXED),
+ MTK_PIN(58, "SCL1", DRV_FIXED),
+ MTK_PIN(59, "RAMBUF_I_CLK", DRV_FIXED),
+ MTK_PIN(60, "WB_RSTB", DRV_GRP3),
+ MTK_PIN(61, "F2W_DATA", DRV_GRP3),
+ MTK_PIN(62, "F2W_CLK", DRV_GRP3),
+ MTK_PIN(63, "WB_SCLK", DRV_GRP3),
+ MTK_PIN(64, "WB_SDATA", DRV_GRP3),
+ MTK_PIN(65, "WB_SEN", DRV_GRP3),
+ MTK_PIN(66, "WB_CRTL0", DRV_GRP3),
+ MTK_PIN(67, "WB_CRTL1", DRV_GRP3),
+ MTK_PIN(68, "WB_CRTL2", DRV_GRP3),
+ MTK_PIN(69, "WB_CRTL3", DRV_GRP3),
+ MTK_PIN(70, "WB_CRTL4", DRV_GRP3),
+ MTK_PIN(71, "WB_CRTL5", DRV_GRP3),
+ MTK_PIN(72, "I2S0_DATA_IN", DRV_GRP1),
+ MTK_PIN(73, "I2S0_LRCK", DRV_GRP1),
+ MTK_PIN(74, "I2S0_BCK", DRV_GRP1),
+ MTK_PIN(75, "SDA0", DRV_FIXED),
+ MTK_PIN(76, "SCL0", DRV_FIXED),
+ MTK_PIN(77, "SDA2", DRV_FIXED),
+ MTK_PIN(78, "SCL2", DRV_FIXED),
+ MTK_PIN(79, "URXD0", DRV_FIXED),
+ MTK_PIN(80, "UTXD0", DRV_FIXED),
+ MTK_PIN(81, "URXD1", DRV_FIXED),
+ MTK_PIN(82, "UTXD1", DRV_FIXED),
+ MTK_PIN(83, "LCM_RST", DRV_FIXED),
+ MTK_PIN(84, "DSI_TE", DRV_FIXED),
+ MTK_PIN(85, "MSDC2_CMD", DRV_GRP4),
+ MTK_PIN(86, "MSDC2_CLK", DRV_GRP4),
+ MTK_PIN(87, "MSDC2_DAT0", DRV_GRP4),
+ MTK_PIN(88, "MSDC2_DAT1", DRV_GRP4),
+ MTK_PIN(89, "MSDC2_DAT2", DRV_GRP4),
+ MTK_PIN(90, "MSDC2_DAT3", DRV_GRP4),
+ MTK_PIN(91, "TDN3", DRV_FIXED),
+ MTK_PIN(92, "TDP3", DRV_FIXED),
+ MTK_PIN(93, "TDN2", DRV_FIXED),
+ MTK_PIN(94, "TDP2", DRV_FIXED),
+ MTK_PIN(95, "TCN", DRV_FIXED),
+ MTK_PIN(96, "TCP", DRV_FIXED),
+ MTK_PIN(97, "TDN1", DRV_FIXED),
+ MTK_PIN(98, "TDP1", DRV_FIXED),
+ MTK_PIN(99, "TDN0", DRV_FIXED),
+ MTK_PIN(100, "TDP0", DRV_FIXED),
+ MTK_PIN(101, "SPI2_CSN", DRV_FIXED),
+ MTK_PIN(102, "SPI2_MI", DRV_FIXED),
+ MTK_PIN(103, "SPI2_MO", DRV_FIXED),
+ MTK_PIN(104, "SPI2_CLK", DRV_FIXED),
+ MTK_PIN(105, "MSDC1_CMD", DRV_GRP4),
+ MTK_PIN(106, "MSDC1_CLK", DRV_GRP4),
+ MTK_PIN(107, "MSDC1_DAT0", DRV_GRP4),
+ MTK_PIN(108, "MSDC1_DAT1", DRV_GRP4),
+ MTK_PIN(109, "MSDC1_DAT2", DRV_GRP4),
+ MTK_PIN(110, "MSDC1_DAT3", DRV_GRP4),
+ MTK_PIN(111, "MSDC0_DAT7", DRV_GRP4),
+ MTK_PIN(112, "MSDC0_DAT6", DRV_GRP4),
+ MTK_PIN(113, "MSDC0_DAT5", DRV_GRP4),
+ MTK_PIN(114, "MSDC0_DAT4", DRV_GRP4),
+ MTK_PIN(115, "MSDC0_RSTB", DRV_GRP4),
+ MTK_PIN(116, "MSDC0_CMD", DRV_GRP4),
+ MTK_PIN(117, "MSDC0_CLK", DRV_GRP4),
+ MTK_PIN(118, "MSDC0_DAT3", DRV_GRP4),
+ MTK_PIN(119, "MSDC0_DAT2", DRV_GRP4),
+ MTK_PIN(120, "MSDC0_DAT1", DRV_GRP4),
+ MTK_PIN(121, "MSDC0_DAT0", DRV_GRP4),
+ MTK_PIN(122, "CEC", DRV_FIXED),
+ MTK_PIN(123, "HTPLG", DRV_FIXED),
+ MTK_PIN(124, "HDMISCK", DRV_FIXED),
+ MTK_PIN(125, "HDMISD", DRV_FIXED),
+ MTK_PIN(126, "I2S0_MCLK", DRV_GRP1),
+ MTK_PIN(127, "RAMBUF_IDATA0", DRV_FIXED),
+ MTK_PIN(128, "RAMBUF_IDATA1", DRV_FIXED),
+ MTK_PIN(129, "RAMBUF_IDATA2", DRV_FIXED),
+ MTK_PIN(130, "RAMBUF_IDATA3", DRV_FIXED),
+ MTK_PIN(131, "RAMBUF_IDATA4", DRV_FIXED),
+ MTK_PIN(132, "RAMBUF_IDATA5", DRV_FIXED),
+ MTK_PIN(133, "RAMBUF_IDATA6", DRV_FIXED),
+ MTK_PIN(134, "RAMBUF_IDATA7", DRV_FIXED),
+ MTK_PIN(135, "RAMBUF_IDATA8", DRV_FIXED),
+ MTK_PIN(136, "RAMBUF_IDATA9", DRV_FIXED),
+ MTK_PIN(137, "RAMBUF_IDATA10", DRV_FIXED),
+ MTK_PIN(138, "RAMBUF_IDATA11", DRV_FIXED),
+ MTK_PIN(139, "RAMBUF_IDATA12", DRV_FIXED),
+ MTK_PIN(140, "RAMBUF_IDATA13", DRV_FIXED),
+ MTK_PIN(141, "RAMBUF_IDATA14", DRV_FIXED),
+ MTK_PIN(142, "RAMBUF_IDATA15", DRV_FIXED),
+ MTK_PIN(143, "RAMBUF_ODATA0", DRV_FIXED),
+ MTK_PIN(144, "RAMBUF_ODATA1", DRV_FIXED),
+ MTK_PIN(145, "RAMBUF_ODATA2", DRV_FIXED),
+ MTK_PIN(146, "RAMBUF_ODATA3", DRV_FIXED),
+ MTK_PIN(147, "RAMBUF_ODATA4", DRV_FIXED),
+ MTK_PIN(148, "RAMBUF_ODATA5", DRV_FIXED),
+ MTK_PIN(149, "RAMBUF_ODATA6", DRV_FIXED),
+ MTK_PIN(150, "RAMBUF_ODATA7", DRV_FIXED),
+ MTK_PIN(151, "RAMBUF_ODATA8", DRV_FIXED),
+ MTK_PIN(152, "RAMBUF_ODATA9", DRV_FIXED),
+ MTK_PIN(153, "RAMBUF_ODATA10", DRV_FIXED),
+ MTK_PIN(154, "RAMBUF_ODATA11", DRV_FIXED),
+ MTK_PIN(155, "RAMBUF_ODATA12", DRV_FIXED),
+ MTK_PIN(156, "RAMBUF_ODATA13", DRV_FIXED),
+ MTK_PIN(157, "RAMBUF_ODATA14", DRV_FIXED),
+ MTK_PIN(158, "RAMBUF_ODATA15", DRV_FIXED),
+ MTK_PIN(159, "RAMBUF_BE0", DRV_FIXED),
+ MTK_PIN(160, "RAMBUF_BE1", DRV_FIXED),
+ MTK_PIN(161, "AP2PT_INT", DRV_FIXED),
+ MTK_PIN(162, "AP2PT_INT_CLR", DRV_FIXED),
+ MTK_PIN(163, "PT2AP_INT", DRV_FIXED),
+ MTK_PIN(164, "PT2AP_INT_CLR", DRV_FIXED),
+ MTK_PIN(165, "AP2UP_INT", DRV_FIXED),
+ MTK_PIN(166, "AP2UP_INT_CLR", DRV_FIXED),
+ MTK_PIN(167, "UP2AP_INT", DRV_FIXED),
+ MTK_PIN(168, "UP2AP_INT_CLR", DRV_FIXED),
+ MTK_PIN(169, "RAMBUF_ADDR0", DRV_FIXED),
+ MTK_PIN(170, "RAMBUF_ADDR1", DRV_FIXED),
+ MTK_PIN(171, "RAMBUF_ADDR2", DRV_FIXED),
+ MTK_PIN(172, "RAMBUF_ADDR3", DRV_FIXED),
+ MTK_PIN(173, "RAMBUF_ADDR4", DRV_FIXED),
+ MTK_PIN(174, "RAMBUF_ADDR5", DRV_FIXED),
+ MTK_PIN(175, "RAMBUF_ADDR6", DRV_FIXED),
+ MTK_PIN(176, "RAMBUF_ADDR7", DRV_FIXED),
+ MTK_PIN(177, "RAMBUF_ADDR8", DRV_FIXED),
+ MTK_PIN(178, "RAMBUF_ADDR9", DRV_FIXED),
+ MTK_PIN(179, "RAMBUF_ADDR10", DRV_FIXED),
+ MTK_PIN(180, "RAMBUF_RW", DRV_FIXED),
+ MTK_PIN(181, "RAMBUF_LAST", DRV_FIXED),
+ MTK_PIN(182, "RAMBUF_HP", DRV_FIXED),
+ MTK_PIN(183, "RAMBUF_REQ", DRV_FIXED),
+ MTK_PIN(184, "RAMBUF_ALE", DRV_FIXED),
+ MTK_PIN(185, "RAMBUF_DLE", DRV_FIXED),
+ MTK_PIN(186, "RAMBUF_WDLE", DRV_FIXED),
+ MTK_PIN(187, "RAMBUF_O_CLK", DRV_FIXED),
+ MTK_PIN(188, "I2S2_MCLK", DRV_GRP1),
+ MTK_PIN(189, "I2S3_DATA", DRV_GRP1),
+ MTK_PIN(190, "I2S3_DATA_IN", DRV_GRP1),
+ MTK_PIN(191, "I2S3_BCK", DRV_GRP1),
+ MTK_PIN(192, "I2S3_LRCK", DRV_GRP1),
+ MTK_PIN(193, "I2S3_MCLK", DRV_GRP1),
+ MTK_PIN(194, "I2S4_DATA", DRV_GRP1),
+ MTK_PIN(195, "I2S4_DATA_IN", DRV_GRP1),
+ MTK_PIN(196, "I2S4_BCK", DRV_GRP1),
+ MTK_PIN(197, "I2S4_LRCK", DRV_GRP1),
+ MTK_PIN(198, "I2S4_MCLK", DRV_GRP1),
+ MTK_PIN(199, "SPI1_CLK", DRV_GRP3),
+ MTK_PIN(200, "SPDIF_OUT", DRV_GRP1),
+ MTK_PIN(201, "SPDIF_IN0", DRV_GRP1),
+ MTK_PIN(202, "SPDIF_IN1", DRV_GRP1),
+ MTK_PIN(203, "PWM0", DRV_GRP1),
+ MTK_PIN(204, "PWM1", DRV_GRP1),
+ MTK_PIN(205, "PWM2", DRV_GRP1),
+ MTK_PIN(206, "PWM3", DRV_GRP1),
+ MTK_PIN(207, "PWM4", DRV_GRP1),
+ MTK_PIN(208, "AUD_EXT_CK1", DRV_GRP1),
+ MTK_PIN(209, "AUD_EXT_CK2", DRV_GRP1),
+ MTK_PIN(210, "AUD_CLOCK", DRV_GRP3),
+ MTK_PIN(211, "DVP_RESET", DRV_GRP3),
+ MTK_PIN(212, "DVP_CLOCK", DRV_GRP3),
+ MTK_PIN(213, "DVP_CS", DRV_GRP3),
+ MTK_PIN(214, "DVP_CK", DRV_GRP3),
+ MTK_PIN(215, "DVP_DI", DRV_GRP3),
+ MTK_PIN(216, "DVP_DO", DRV_GRP3),
+ MTK_PIN(217, "AP_CS", DRV_GRP3),
+ MTK_PIN(218, "AP_CK", DRV_GRP3),
+ MTK_PIN(219, "AP_DI", DRV_GRP3),
+ MTK_PIN(220, "AP_DO", DRV_GRP3),
+ MTK_PIN(221, "DVD_BCLK", DRV_GRP3),
+ MTK_PIN(222, "T8032_CLK", DRV_GRP3),
+ MTK_PIN(223, "AP_BCLK", DRV_GRP3),
+ MTK_PIN(224, "HOST_CS", DRV_GRP3),
+ MTK_PIN(225, "HOST_CK", DRV_GRP3),
+ MTK_PIN(226, "HOST_DO0", DRV_GRP3),
+ MTK_PIN(227, "HOST_DO1", DRV_GRP3),
+ MTK_PIN(228, "SLV_CS", DRV_GRP3),
+ MTK_PIN(229, "SLV_CK", DRV_GRP3),
+ MTK_PIN(230, "SLV_DI0", DRV_GRP3),
+ MTK_PIN(231, "SLV_DI1", DRV_GRP3),
+ MTK_PIN(232, "AP2DSP_INT", DRV_GRP3),
+ MTK_PIN(233, "AP2DSP_INT_CLR", DRV_GRP3),
+ MTK_PIN(234, "DSP2AP_INT", DRV_GRP3),
+ MTK_PIN(235, "DSP2AP_INT_CLR", DRV_GRP3),
+ MTK_PIN(236, "EXT_SDIO3", DRV_GRP1),
+ MTK_PIN(237, "EXT_SDIO2", DRV_GRP1),
+ MTK_PIN(238, "EXT_SDIO1", DRV_GRP1),
+ MTK_PIN(239, "EXT_SDIO0", DRV_GRP1),
+ MTK_PIN(240, "EXT_XCS", DRV_GRP1),
+ MTK_PIN(241, "EXT_SCK", DRV_GRP1),
+ MTK_PIN(242, "URTS2", DRV_GRP1),
+ MTK_PIN(243, "UCTS2", DRV_GRP1),
+ MTK_PIN(244, "HDMI_SDA_RX", DRV_FIXED),
+ MTK_PIN(245, "HDMI_SCL_RX", DRV_FIXED),
+ MTK_PIN(246, "MHL_SENCE", DRV_FIXED),
+ MTK_PIN(247, "HDMI_HPD_CBUS_RX", DRV_FIXED),
+ MTK_PIN(248, "HDMI_TESTOUTP_RX", DRV_GRP1),
+ MTK_PIN(249, "MSDC0E_RSTB", DRV_GRP4),
+ MTK_PIN(250, "MSDC0E_DAT7", DRV_GRP4),
+ MTK_PIN(251, "MSDC0E_DAT6", DRV_GRP4),
+ MTK_PIN(252, "MSDC0E_DAT5", DRV_GRP4),
+ MTK_PIN(253, "MSDC0E_DAT4", DRV_GRP4),
+ MTK_PIN(254, "MSDC0E_DAT3", DRV_GRP4),
+ MTK_PIN(255, "MSDC0E_DAT2", DRV_GRP4),
+ MTK_PIN(256, "MSDC0E_DAT1", DRV_GRP4),
+ MTK_PIN(257, "MSDC0E_DAT0", DRV_GRP4),
+ MTK_PIN(258, "MSDC0E_CMD", DRV_GRP4),
+ MTK_PIN(259, "MSDC0E_CLK", DRV_GRP4),
+ MTK_PIN(260, "MSDC0E_DSL", DRV_GRP4),
+ MTK_PIN(261, "MSDC1_INS", DRV_GRP4),
+ MTK_PIN(262, "G2_TXEN", DRV_GRP1),
+ MTK_PIN(263, "G2_TXD3", DRV_GRP1),
+ MTK_PIN(264, "G2_TXD2", DRV_GRP1),
+ MTK_PIN(265, "G2_TXD1", DRV_GRP1),
+ MTK_PIN(266, "G2_TXD0", DRV_GRP1),
+ MTK_PIN(267, "G2_TXC", DRV_GRP1),
+ MTK_PIN(268, "G2_RXC", DRV_GRP1),
+ MTK_PIN(269, "G2_RXD0", DRV_GRP1),
+ MTK_PIN(270, "G2_RXD1", DRV_GRP1),
+ MTK_PIN(271, "G2_RXD2", DRV_GRP1),
+ MTK_PIN(272, "G2_RXD3", DRV_GRP1),
+ MTK_PIN(273, "ESW_INT", DRV_GRP1),
+ MTK_PIN(274, "G2_RXDV", DRV_GRP1),
+ MTK_PIN(275, "MDC", DRV_GRP1),
+ MTK_PIN(276, "MDIO", DRV_GRP1),
+ MTK_PIN(277, "ESW_RST", DRV_GRP1),
+ MTK_PIN(278, "JTAG_RESET", DRV_GRP3),
+ MTK_PIN(279, "USB3_RES_BOND", DRV_GRP1),
+};
+
+/* List all groups consisting of these pins dedicated to the enablement of
+ * certain hardware block and the corresponding mode for all of the pins.
+ * The hardware probably has multiple combinations of these pinouts.
+ */
+
+/* AUDIO EXT CLK */
+static int mt7623_aud_ext_clk0_pins[] = { 208, };
+static int mt7623_aud_ext_clk0_funcs[] = { 1, };
+static int mt7623_aud_ext_clk1_pins[] = { 209, };
+static int mt7623_aud_ext_clk1_funcs[] = { 1, };
+
+/* DISP PWM */
+static int mt7623_disp_pwm_0_pins[] = { 72, };
+static int mt7623_disp_pwm_0_funcs[] = { 5, };
+static int mt7623_disp_pwm_1_pins[] = { 203, };
+static int mt7623_disp_pwm_1_funcs[] = { 2, };
+static int mt7623_disp_pwm_2_pins[] = { 208, };
+static int mt7623_disp_pwm_2_funcs[] = { 5, };
+
+/* ESW */
+static int mt7623_esw_int_pins[] = { 273, };
+static int mt7623_esw_int_funcs[] = { 1, };
+static int mt7623_esw_rst_pins[] = { 277, };
+static int mt7623_esw_rst_funcs[] = { 1, };
+
+/* EPHY */
+static int mt7623_ephy_pins[] = { 262, 263, 264, 265, 266, 267, 268,
+ 269, 270, 271, 272, 274, };
+static int mt7623_ephy_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+/* EXT_SDIO */
+static int mt7623_ext_sdio_pins[] = { 236, 237, 238, 239, 240, 241, };
+static int mt7623_ext_sdio_funcs[] = { 1, 1, 1, 1, 1, 1, };
+
+/* HDMI RX */
+static int mt7623_hdmi_rx_pins[] = { 247, 248, };
+static int mt7623_hdmi_rx_funcs[] = { 1, 1 };
+static int mt7623_hdmi_rx_i2c_pins[] = { 244, 245, };
+static int mt7623_hdmi_rx_i2c_funcs[] = { 1, 1 };
+
+/* HDMI TX */
+static int mt7623_hdmi_cec_pins[] = { 122, };
+static int mt7623_hdmi_cec_funcs[] = { 1, };
+static int mt7623_hdmi_htplg_pins[] = { 123, };
+static int mt7623_hdmi_htplg_funcs[] = { 1, };
+static int mt7623_hdmi_i2c_pins[] = { 124, 125, };
+static int mt7623_hdmi_i2c_funcs[] = { 1, 1 };
+
+/* I2C */
+static int mt7623_i2c0_pins[] = { 75, 76, };
+static int mt7623_i2c0_funcs[] = { 1, 1, };
+static int mt7623_i2c1_0_pins[] = { 57, 58, };
+static int mt7623_i2c1_0_funcs[] = { 1, 1, };
+static int mt7623_i2c1_1_pins[] = { 242, 243, };
+static int mt7623_i2c1_1_funcs[] = { 4, 4, };
+static int mt7623_i2c1_2_pins[] = { 85, 86, };
+static int mt7623_i2c1_2_funcs[] = { 3, 3, };
+static int mt7623_i2c1_3_pins[] = { 105, 106, };
+static int mt7623_i2c1_3_funcs[] = { 3, 3, };
+static int mt7623_i2c1_4_pins[] = { 124, 125, };
+static int mt7623_i2c1_4_funcs[] = { 4, 4, };
+static int mt7623_i2c2_0_pins[] = { 77, 78, };
+static int mt7623_i2c2_0_funcs[] = { 1, 1, };
+static int mt7623_i2c2_1_pins[] = { 89, 90, };
+static int mt7623_i2c2_1_funcs[] = { 3, 3, };
+static int mt7623_i2c2_2_pins[] = { 109, 110, };
+static int mt7623_i2c2_2_funcs[] = { 3, 3, };
+static int mt7623_i2c2_3_pins[] = { 122, 123, };
+static int mt7623_i2c2_3_funcs[] = { 4, 4, };
+
+/* I2S */
+static int mt7623_i2s0_pins[] = { 49, 72, 73, 74, 126, };
+static int mt7623_i2s0_funcs[] = { 1, 1, 1, 1, 1, };
+static int mt7623_i2s1_pins[] = { 33, 34, 35, 36, 37, };
+static int mt7623_i2s1_funcs[] = { 1, 1, 1, 1, 1, };
+static int mt7623_i2s2_bclk_lrclk_mclk_pins[] = { 50, 52, 188, };
+static int mt7623_i2s2_bclk_lrclk_mclk_funcs[] = { 1, 1, 1, };
+static int mt7623_i2s2_data_in_pins[] = { 51, };
+static int mt7623_i2s2_data_in_funcs[] = { 1, };
+static int mt7623_i2s2_data_0_pins[] = { 203, };
+static int mt7623_i2s2_data_0_funcs[] = { 9, };
+static int mt7623_i2s2_data_1_pins[] = { 38, };
+static int mt7623_i2s2_data_1_funcs[] = { 4, };
+static int mt7623_i2s3_bclk_lrclk_mclk_pins[] = { 191, 192, 193, };
+static int mt7623_i2s3_bclk_lrclk_mclk_funcs[] = { 1, 1, 1, };
+static int mt7623_i2s3_data_in_pins[] = { 190, };
+static int mt7623_i2s3_data_in_funcs[] = { 1, };
+static int mt7623_i2s3_data_0_pins[] = { 204, };
+static int mt7623_i2s3_data_0_funcs[] = { 9, };
+static int mt7623_i2s3_data_1_pins[] = { 2, };
+static int mt7623_i2s3_data_1_funcs[] = { 0, };
+static int mt7623_i2s4_pins[] = { 194, 195, 196, 197, 198, };
+static int mt7623_i2s4_funcs[] = { 1, 1, 1, 1, 1, };
+static int mt7623_i2s5_pins[] = { 16, 17, 30, 31, 32, };
+static int mt7623_i2s5_funcs[] = { 1, 1, 1, 1, 1, };
+
+/* IR */
+static int mt7623_ir_pins[] = { 46, };
+static int mt7623_ir_funcs[] = { 1, };
+
+/* LCD */
+static int mt7623_mipi_tx_pins[] = { 91, 92, 93, 94, 95, 96, 97, 98,
+ 99, 100, };
+static int mt7623_mipi_tx_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+static int mt7623_dsi_te_pins[] = { 84, };
+static int mt7623_dsi_te_funcs[] = { 1, };
+static int mt7623_lcm_rst_pins[] = { 83, };
+static int mt7623_lcm_rst_funcs[] = { 1, };
+
+/* MDC/MDIO */
+static int mt7623_mdc_mdio_pins[] = { 275, 276, };
+static int mt7623_mdc_mdio_funcs[] = { 1, 1, };
+
+/* MSDC */
+static int mt7623_msdc0_pins[] = { 111, 112, 113, 114, 115, 116, 117, 118,
+ 119, 120, 121, };
+static int mt7623_msdc0_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+static int mt7623_msdc1_pins[] = { 105, 106, 107, 108, 109, 110, };
+static int mt7623_msdc1_funcs[] = { 1, 1, 1, 1, 1, 1, };
+static int mt7623_msdc1_ins_pins[] = { 261, };
+static int mt7623_msdc1_ins_funcs[] = { 1, };
+static int mt7623_msdc1_wp_0_pins[] = { 29, };
+static int mt7623_msdc1_wp_0_funcs[] = { 1, };
+static int mt7623_msdc1_wp_1_pins[] = { 55, };
+static int mt7623_msdc1_wp_1_funcs[] = { 3, };
+static int mt7623_msdc1_wp_2_pins[] = { 209, };
+static int mt7623_msdc1_wp_2_funcs[] = { 2, };
+static int mt7623_msdc2_pins[] = { 85, 86, 87, 88, 89, 90, };
+static int mt7623_msdc2_funcs[] = { 1, 1, 1, 1, 1, 1, };
+static int mt7623_msdc3_pins[] = { 249, 250, 251, 252, 253, 254, 255, 256,
+ 257, 258, 259, 260, };
+static int mt7623_msdc3_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+/* NAND */
+static int mt7623_nandc_pins[] = { 43, 47, 48, 111, 112, 113, 114, 115,
+ 116, 117, 118, 119, 120, 121, };
+static int mt7623_nandc_funcs[] = { 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, };
+static int mt7623_nandc_ceb0_pins[] = { 45, };
+static int mt7623_nandc_ceb0_funcs[] = { 1, };
+static int mt7623_nandc_ceb1_pins[] = { 44, };
+static int mt7623_nandc_ceb1_funcs[] = { 1, };
+
+/* RTC */
+static int mt7623_rtc_pins[] = { 10, };
+static int mt7623_rtc_funcs[] = { 1, };
+
+/* OTG */
+static int mt7623_otg_iddig0_0_pins[] = { 29, };
+static int mt7623_otg_iddig0_0_funcs[] = { 1, };
+static int mt7623_otg_iddig0_1_pins[] = { 44, };
+static int mt7623_otg_iddig0_1_funcs[] = { 2, };
+static int mt7623_otg_iddig0_2_pins[] = { 236, };
+static int mt7623_otg_iddig0_2_funcs[] = { 2, };
+static int mt7623_otg_iddig1_0_pins[] = { 27, };
+static int mt7623_otg_iddig1_0_funcs[] = { 2, };
+static int mt7623_otg_iddig1_1_pins[] = { 47, };
+static int mt7623_otg_iddig1_1_funcs[] = { 2, };
+static int mt7623_otg_iddig1_2_pins[] = { 238, };
+static int mt7623_otg_iddig1_2_funcs[] = { 2, };
+static int mt7623_otg_drv_vbus0_0_pins[] = { 28, };
+static int mt7623_otg_drv_vbus0_0_funcs[] = { 1, };
+static int mt7623_otg_drv_vbus0_1_pins[] = { 45, };
+static int mt7623_otg_drv_vbus0_1_funcs[] = { 2, };
+static int mt7623_otg_drv_vbus0_2_pins[] = { 237, };
+static int mt7623_otg_drv_vbus0_2_funcs[] = { 2, };
+static int mt7623_otg_drv_vbus1_0_pins[] = { 26, };
+static int mt7623_otg_drv_vbus1_0_funcs[] = { 2, };
+static int mt7623_otg_drv_vbus1_1_pins[] = { 48, };
+static int mt7623_otg_drv_vbus1_1_funcs[] = { 2, };
+static int mt7623_otg_drv_vbus1_2_pins[] = { 239, };
+static int mt7623_otg_drv_vbus1_2_funcs[] = { 2, };
+
+/* PCIE */
+static int mt7623_pcie0_0_perst_pins[] = { 208, };
+static int mt7623_pcie0_0_perst_funcs[] = { 3, };
+static int mt7623_pcie0_1_perst_pins[] = { 22, };
+static int mt7623_pcie0_1_perst_funcs[] = { 2, };
+static int mt7623_pcie1_0_perst_pins[] = { 209, };
+static int mt7623_pcie1_0_perst_funcs[] = { 3, };
+static int mt7623_pcie1_1_perst_pins[] = { 23, };
+static int mt7623_pcie1_1_perst_funcs[] = { 2, };
+static int mt7623_pcie2_0_perst_pins[] = { 24, };
+static int mt7623_pcie2_0_perst_funcs[] = { 2, };
+static int mt7623_pcie2_1_perst_pins[] = { 29, };
+static int mt7623_pcie2_1_perst_funcs[] = { 6, };
+static int mt7623_pcie0_0_wake_pins[] = { 28, };
+static int mt7623_pcie0_0_wake_funcs[] = { 6, };
+static int mt7623_pcie0_1_wake_pins[] = { 251, };
+static int mt7623_pcie0_1_wake_funcs[] = { 6, };
+static int mt7623_pcie1_0_wake_pins[] = { 27, };
+static int mt7623_pcie1_0_wake_funcs[] = { 6, };
+static int mt7623_pcie1_1_wake_pins[] = { 253, };
+static int mt7623_pcie1_1_wake_funcs[] = { 6, };
+static int mt7623_pcie2_0_wake_pins[] = { 26, };
+static int mt7623_pcie2_0_wake_funcs[] = { 6, };
+static int mt7623_pcie2_1_wake_pins[] = { 255, };
+static int mt7623_pcie2_1_wake_funcs[] = { 6, };
+static int mt7623_pcie0_clkreq_pins[] = { 250, };
+static int mt7623_pcie0_clkreq_funcs[] = { 6, };
+static int mt7623_pcie1_clkreq_pins[] = { 252, };
+static int mt7623_pcie1_clkreq_funcs[] = { 6, };
+static int mt7623_pcie2_clkreq_pins[] = { 254, };
+static int mt7623_pcie2_clkreq_funcs[] = { 6, };
+/* the pcie_*_rev are only used for MT7623 */
+static int mt7623_pcie0_0_rev_perst_pins[] = { 208, };
+static int mt7623_pcie0_0_rev_perst_funcs[] = { 11, };
+static int mt7623_pcie0_1_rev_perst_pins[] = { 22, };
+static int mt7623_pcie0_1_rev_perst_funcs[] = { 10, };
+static int mt7623_pcie1_0_rev_perst_pins[] = { 209, };
+static int mt7623_pcie1_0_rev_perst_funcs[] = { 11, };
+static int mt7623_pcie1_1_rev_perst_pins[] = { 23, };
+static int mt7623_pcie1_1_rev_perst_funcs[] = { 10, };
+static int mt7623_pcie2_0_rev_perst_pins[] = { 24, };
+static int mt7623_pcie2_0_rev_perst_funcs[] = { 11, };
+static int mt7623_pcie2_1_rev_perst_pins[] = { 29, };
+static int mt7623_pcie2_1_rev_perst_funcs[] = { 14, };
+
+/* PCM */
+static int mt7623_pcm_clk_0_pins[] = { 18, };
+static int mt7623_pcm_clk_0_funcs[] = { 1, };
+static int mt7623_pcm_clk_1_pins[] = { 17, };
+static int mt7623_pcm_clk_1_funcs[] = { 3, };
+static int mt7623_pcm_clk_2_pins[] = { 35, };
+static int mt7623_pcm_clk_2_funcs[] = { 3, };
+static int mt7623_pcm_clk_3_pins[] = { 50, };
+static int mt7623_pcm_clk_3_funcs[] = { 3, };
+static int mt7623_pcm_clk_4_pins[] = { 74, };
+static int mt7623_pcm_clk_4_funcs[] = { 3, };
+static int mt7623_pcm_clk_5_pins[] = { 191, };
+static int mt7623_pcm_clk_5_funcs[] = { 3, };
+static int mt7623_pcm_clk_6_pins[] = { 196, };
+static int mt7623_pcm_clk_6_funcs[] = { 3, };
+static int mt7623_pcm_sync_0_pins[] = { 19, };
+static int mt7623_pcm_sync_0_funcs[] = { 1, };
+static int mt7623_pcm_sync_1_pins[] = { 30, };
+static int mt7623_pcm_sync_1_funcs[] = { 3, };
+static int mt7623_pcm_sync_2_pins[] = { 36, };
+static int mt7623_pcm_sync_2_funcs[] = { 3, };
+static int mt7623_pcm_sync_3_pins[] = { 52, };
+static int mt7623_pcm_sync_3_funcs[] = { 31, };
+static int mt7623_pcm_sync_4_pins[] = { 73, };
+static int mt7623_pcm_sync_4_funcs[] = { 3, };
+static int mt7623_pcm_sync_5_pins[] = { 192, };
+static int mt7623_pcm_sync_5_funcs[] = { 3, };
+static int mt7623_pcm_sync_6_pins[] = { 197, };
+static int mt7623_pcm_sync_6_funcs[] = { 3, };
+static int mt7623_pcm_rx_0_pins[] = { 20, };
+static int mt7623_pcm_rx_0_funcs[] = { 1, };
+static int mt7623_pcm_rx_1_pins[] = { 16, };
+static int mt7623_pcm_rx_1_funcs[] = { 3, };
+static int mt7623_pcm_rx_2_pins[] = { 34, };
+static int mt7623_pcm_rx_2_funcs[] = { 3, };
+static int mt7623_pcm_rx_3_pins[] = { 51, };
+static int mt7623_pcm_rx_3_funcs[] = { 3, };
+static int mt7623_pcm_rx_4_pins[] = { 72, };
+static int mt7623_pcm_rx_4_funcs[] = { 3, };
+static int mt7623_pcm_rx_5_pins[] = { 190, };
+static int mt7623_pcm_rx_5_funcs[] = { 3, };
+static int mt7623_pcm_rx_6_pins[] = { 195, };
+static int mt7623_pcm_rx_6_funcs[] = { 3, };
+static int mt7623_pcm_tx_0_pins[] = { 21, };
+static int mt7623_pcm_tx_0_funcs[] = { 1, };
+static int mt7623_pcm_tx_1_pins[] = { 32, };
+static int mt7623_pcm_tx_1_funcs[] = { 3, };
+static int mt7623_pcm_tx_2_pins[] = { 33, };
+static int mt7623_pcm_tx_2_funcs[] = { 3, };
+static int mt7623_pcm_tx_3_pins[] = { 38, };
+static int mt7623_pcm_tx_3_funcs[] = { 3, };
+static int mt7623_pcm_tx_4_pins[] = { 49, };
+static int mt7623_pcm_tx_4_funcs[] = { 3, };
+static int mt7623_pcm_tx_5_pins[] = { 189, };
+static int mt7623_pcm_tx_5_funcs[] = { 3, };
+static int mt7623_pcm_tx_6_pins[] = { 194, };
+static int mt7623_pcm_tx_6_funcs[] = { 3, };
+
+/* PWM */
+static int mt7623_pwm_ch1_0_pins[] = { 203, };
+static int mt7623_pwm_ch1_0_funcs[] = { 1, };
+static int mt7623_pwm_ch1_1_pins[] = { 208, };
+static int mt7623_pwm_ch1_1_funcs[] = { 2, };
+static int mt7623_pwm_ch1_2_pins[] = { 72, };
+static int mt7623_pwm_ch1_2_funcs[] = { 4, };
+static int mt7623_pwm_ch1_3_pins[] = { 88, };
+static int mt7623_pwm_ch1_3_funcs[] = { 3, };
+static int mt7623_pwm_ch1_4_pins[] = { 108, };
+static int mt7623_pwm_ch1_4_funcs[] = { 3, };
+static int mt7623_pwm_ch2_0_pins[] = { 204, };
+static int mt7623_pwm_ch2_0_funcs[] = { 1, };
+static int mt7623_pwm_ch2_1_pins[] = { 53, };
+static int mt7623_pwm_ch2_1_funcs[] = { 5, };
+static int mt7623_pwm_ch2_2_pins[] = { 88, };
+static int mt7623_pwm_ch2_2_funcs[] = { 6, };
+static int mt7623_pwm_ch2_3_pins[] = { 108, };
+static int mt7623_pwm_ch2_3_funcs[] = { 6, };
+static int mt7623_pwm_ch2_4_pins[] = { 209, };
+static int mt7623_pwm_ch2_4_funcs[] = { 5, };
+static int mt7623_pwm_ch3_0_pins[] = { 205, };
+static int mt7623_pwm_ch3_0_funcs[] = { 1, };
+static int mt7623_pwm_ch3_1_pins[] = { 55, };
+static int mt7623_pwm_ch3_1_funcs[] = { 5, };
+static int mt7623_pwm_ch3_2_pins[] = { 89, };
+static int mt7623_pwm_ch3_2_funcs[] = { 6, };
+static int mt7623_pwm_ch3_3_pins[] = { 109, };
+static int mt7623_pwm_ch3_3_funcs[] = { 6, };
+static int mt7623_pwm_ch4_0_pins[] = { 206, };
+static int mt7623_pwm_ch4_0_funcs[] = { 1, };
+static int mt7623_pwm_ch4_1_pins[] = { 90, };
+static int mt7623_pwm_ch4_1_funcs[] = { 6, };
+static int mt7623_pwm_ch4_2_pins[] = { 110, };
+static int mt7623_pwm_ch4_2_funcs[] = { 6, };
+static int mt7623_pwm_ch4_3_pins[] = { 124, };
+static int mt7623_pwm_ch4_3_funcs[] = { 5, };
+static int mt7623_pwm_ch5_0_pins[] = { 207, };
+static int mt7623_pwm_ch5_0_funcs[] = { 1, };
+static int mt7623_pwm_ch5_1_pins[] = { 125, };
+static int mt7623_pwm_ch5_1_funcs[] = { 5, };
+
+/* PWRAP */
+static int mt7623_pwrap_pins[] = { 0, 1, 2, 3, 4, 5, 6, };
+static int mt7623_pwrap_funcs[] = { 1, 1, 1, 1, 1, 1, 1, };
+
+/* SPDIF */
+static int mt7623_spdif_in0_0_pins[] = { 56, };
+static int mt7623_spdif_in0_0_funcs[] = { 3, };
+static int mt7623_spdif_in0_1_pins[] = { 201, };
+static int mt7623_spdif_in0_1_funcs[] = { 1, };
+static int mt7623_spdif_in1_0_pins[] = { 54, };
+static int mt7623_spdif_in1_0_funcs[] = { 3, };
+static int mt7623_spdif_in1_1_pins[] = { 202, };
+static int mt7623_spdif_in1_1_funcs[] = { 1, };
+static int mt7623_spdif_out_pins[] = { 202, };
+static int mt7623_spdif_out_funcs[] = { 1, };
+
+/* SPI */
+static int mt7623_spi0_pins[] = { 53, 54, 55, 56, };
+static int mt7623_spi0_funcs[] = { 1, 1, 1, 1, };
+static int mt7623_spi1_pins[] = { 7, 199, 8, 9, };
+static int mt7623_spi1_funcs[] = { 1, 1, 1, 1, };
+static int mt7623_spi2_pins[] = { 101, 104, 102, 103, };
+static int mt7623_spi2_funcs[] = { 1, 1, 1, 1, };
+
+/* UART */
+static int mt7623_uart0_0_txd_rxd_pins[] = { 79, 80, };
+static int mt7623_uart0_0_txd_rxd_funcs[] = { 1, 1, };
+static int mt7623_uart0_1_txd_rxd_pins[] = { 87, 88, };
+static int mt7623_uart0_1_txd_rxd_funcs[] = { 5, 5, };
+static int mt7623_uart0_2_txd_rxd_pins[] = { 107, 108, };
+static int mt7623_uart0_2_txd_rxd_funcs[] = { 5, 5, };
+static int mt7623_uart0_3_txd_rxd_pins[] = { 123, 122, };
+static int mt7623_uart0_3_txd_rxd_funcs[] = { 5, 5, };
+static int mt7623_uart0_rts_cts_pins[] = { 22, 23, };
+static int mt7623_uart0_rts_cts_funcs[] = { 1, 1, };
+static int mt7623_uart1_0_txd_rxd_pins[] = { 81, 82, };
+static int mt7623_uart1_0_txd_rxd_funcs[] = { 1, 1, };
+static int mt7623_uart1_1_txd_rxd_pins[] = { 89, 90, };
+static int mt7623_uart1_1_txd_rxd_funcs[] = { 5, 5, };
+static int mt7623_uart1_2_txd_rxd_pins[] = { 109, 110, };
+static int mt7623_uart1_2_txd_rxd_funcs[] = { 5, 5, };
+static int mt7623_uart1_rts_cts_pins[] = { 24, 25, };
+static int mt7623_uart1_rts_cts_funcs[] = { 1, 1, };
+static int mt7623_uart2_0_txd_rxd_pins[] = { 14, 15, };
+static int mt7623_uart2_0_txd_rxd_funcs[] = { 1, 1, };
+static int mt7623_uart2_1_txd_rxd_pins[] = { 200, 201, };
+static int mt7623_uart2_1_txd_rxd_funcs[] = { 6, 6, };
+static int mt7623_uart2_rts_cts_pins[] = { 242, 243, };
+static int mt7623_uart2_rts_cts_funcs[] = { 1, 1, };
+static int mt7623_uart3_txd_rxd_pins[] = { 242, 243, };
+static int mt7623_uart3_txd_rxd_funcs[] = { 2, 2, };
+static int mt7623_uart3_rts_cts_pins[] = { 26, 27, };
+static int mt7623_uart3_rts_cts_funcs[] = { 1, 1, };
+
+/* Watchdog */
+static int mt7623_watchdog_0_pins[] = { 11, };
+static int mt7623_watchdog_0_funcs[] = { 1, };
+static int mt7623_watchdog_1_pins[] = { 121, };
+static int mt7623_watchdog_1_funcs[] = { 5, };
+
+static const struct mtk_group_desc mt7623_groups[] = {
+ PINCTRL_PIN_GROUP("aud_ext_clk0", mt7623_aud_ext_clk0),
+ PINCTRL_PIN_GROUP("aud_ext_clk1", mt7623_aud_ext_clk1),
+ PINCTRL_PIN_GROUP("dsi_te", mt7623_dsi_te),
+ PINCTRL_PIN_GROUP("disp_pwm_0", mt7623_disp_pwm_0),
+ PINCTRL_PIN_GROUP("disp_pwm_1", mt7623_disp_pwm_1),
+ PINCTRL_PIN_GROUP("disp_pwm_2", mt7623_disp_pwm_2),
+ PINCTRL_PIN_GROUP("ephy", mt7623_ephy),
+ PINCTRL_PIN_GROUP("esw_int", mt7623_esw_int),
+ PINCTRL_PIN_GROUP("esw_rst", mt7623_esw_rst),
+ PINCTRL_PIN_GROUP("ext_sdio", mt7623_ext_sdio),
+ PINCTRL_PIN_GROUP("hdmi_cec", mt7623_hdmi_cec),
+ PINCTRL_PIN_GROUP("hdmi_htplg", mt7623_hdmi_htplg),
+ PINCTRL_PIN_GROUP("hdmi_i2c", mt7623_hdmi_i2c),
+ PINCTRL_PIN_GROUP("hdmi_rx", mt7623_hdmi_rx),
+ PINCTRL_PIN_GROUP("hdmi_rx_i2c", mt7623_hdmi_rx_i2c),
+ PINCTRL_PIN_GROUP("i2c0", mt7623_i2c0),
+ PINCTRL_PIN_GROUP("i2c1_0", mt7623_i2c1_0),
+ PINCTRL_PIN_GROUP("i2c1_1", mt7623_i2c1_1),
+ PINCTRL_PIN_GROUP("i2c1_2", mt7623_i2c1_2),
+ PINCTRL_PIN_GROUP("i2c1_3", mt7623_i2c1_3),
+ PINCTRL_PIN_GROUP("i2c1_4", mt7623_i2c1_4),
+ PINCTRL_PIN_GROUP("i2c2_0", mt7623_i2c2_0),
+ PINCTRL_PIN_GROUP("i2c2_1", mt7623_i2c2_1),
+ PINCTRL_PIN_GROUP("i2c2_2", mt7623_i2c2_2),
+ PINCTRL_PIN_GROUP("i2c2_3", mt7623_i2c2_3),
+ PINCTRL_PIN_GROUP("i2s0", mt7623_i2s0),
+ PINCTRL_PIN_GROUP("i2s1", mt7623_i2s1),
+ PINCTRL_PIN_GROUP("i2s4", mt7623_i2s4),
+ PINCTRL_PIN_GROUP("i2s5", mt7623_i2s5),
+ PINCTRL_PIN_GROUP("i2s2_bclk_lrclk_mclk", mt7623_i2s2_bclk_lrclk_mclk),
+ PINCTRL_PIN_GROUP("i2s3_bclk_lrclk_mclk", mt7623_i2s3_bclk_lrclk_mclk),
+ PINCTRL_PIN_GROUP("i2s2_data_in", mt7623_i2s2_data_in),
+ PINCTRL_PIN_GROUP("i2s3_data_in", mt7623_i2s3_data_in),
+ PINCTRL_PIN_GROUP("i2s2_data_0", mt7623_i2s2_data_0),
+ PINCTRL_PIN_GROUP("i2s2_data_1", mt7623_i2s2_data_1),
+ PINCTRL_PIN_GROUP("i2s3_data_0", mt7623_i2s3_data_0),
+ PINCTRL_PIN_GROUP("i2s3_data_1", mt7623_i2s3_data_1),
+ PINCTRL_PIN_GROUP("ir", mt7623_ir),
+ PINCTRL_PIN_GROUP("lcm_rst", mt7623_lcm_rst),
+ PINCTRL_PIN_GROUP("mdc_mdio", mt7623_mdc_mdio),
+ PINCTRL_PIN_GROUP("mipi_tx", mt7623_mipi_tx),
+ PINCTRL_PIN_GROUP("msdc0", mt7623_msdc0),
+ PINCTRL_PIN_GROUP("msdc1", mt7623_msdc1),
+ PINCTRL_PIN_GROUP("msdc1_ins", mt7623_msdc1_ins),
+ PINCTRL_PIN_GROUP("msdc1_wp_0", mt7623_msdc1_wp_0),
+ PINCTRL_PIN_GROUP("msdc1_wp_1", mt7623_msdc1_wp_1),
+ PINCTRL_PIN_GROUP("msdc1_wp_2", mt7623_msdc1_wp_2),
+ PINCTRL_PIN_GROUP("msdc2", mt7623_msdc2),
+ PINCTRL_PIN_GROUP("msdc3", mt7623_msdc3),
+ PINCTRL_PIN_GROUP("nandc", mt7623_nandc),
+ PINCTRL_PIN_GROUP("nandc_ceb0", mt7623_nandc_ceb0),
+ PINCTRL_PIN_GROUP("nandc_ceb1", mt7623_nandc_ceb1),
+ PINCTRL_PIN_GROUP("otg_iddig0_0", mt7623_otg_iddig0_0),
+ PINCTRL_PIN_GROUP("otg_iddig0_1", mt7623_otg_iddig0_1),
+ PINCTRL_PIN_GROUP("otg_iddig0_2", mt7623_otg_iddig0_2),
+ PINCTRL_PIN_GROUP("otg_iddig1_0", mt7623_otg_iddig1_0),
+ PINCTRL_PIN_GROUP("otg_iddig1_1", mt7623_otg_iddig1_1),
+ PINCTRL_PIN_GROUP("otg_iddig1_2", mt7623_otg_iddig1_2),
+ PINCTRL_PIN_GROUP("otg_drv_vbus0_0", mt7623_otg_drv_vbus0_0),
+ PINCTRL_PIN_GROUP("otg_drv_vbus0_1", mt7623_otg_drv_vbus0_1),
+ PINCTRL_PIN_GROUP("otg_drv_vbus0_2", mt7623_otg_drv_vbus0_2),
+ PINCTRL_PIN_GROUP("otg_drv_vbus1_0", mt7623_otg_drv_vbus1_0),
+ PINCTRL_PIN_GROUP("otg_drv_vbus1_1", mt7623_otg_drv_vbus1_1),
+ PINCTRL_PIN_GROUP("otg_drv_vbus1_2", mt7623_otg_drv_vbus1_2),
+ PINCTRL_PIN_GROUP("pcie0_0_perst", mt7623_pcie0_0_perst),
+ PINCTRL_PIN_GROUP("pcie0_1_perst", mt7623_pcie0_1_perst),
+ PINCTRL_PIN_GROUP("pcie1_0_perst", mt7623_pcie1_0_perst),
+ PINCTRL_PIN_GROUP("pcie1_1_perst", mt7623_pcie1_1_perst),
+ PINCTRL_PIN_GROUP("pcie1_1_perst", mt7623_pcie1_1_perst),
+ PINCTRL_PIN_GROUP("pcie0_0_rev_perst", mt7623_pcie0_0_rev_perst),
+ PINCTRL_PIN_GROUP("pcie0_1_rev_perst", mt7623_pcie0_1_rev_perst),
+ PINCTRL_PIN_GROUP("pcie1_0_rev_perst", mt7623_pcie1_0_rev_perst),
+ PINCTRL_PIN_GROUP("pcie1_1_rev_perst", mt7623_pcie1_1_rev_perst),
+ PINCTRL_PIN_GROUP("pcie2_0_rev_perst", mt7623_pcie2_0_rev_perst),
+ PINCTRL_PIN_GROUP("pcie2_1_rev_perst", mt7623_pcie2_1_rev_perst),
+ PINCTRL_PIN_GROUP("pcie2_0_perst", mt7623_pcie2_0_perst),
+ PINCTRL_PIN_GROUP("pcie2_1_perst", mt7623_pcie2_1_perst),
+ PINCTRL_PIN_GROUP("pcie0_0_wake", mt7623_pcie0_0_wake),
+ PINCTRL_PIN_GROUP("pcie0_1_wake", mt7623_pcie0_1_wake),
+ PINCTRL_PIN_GROUP("pcie1_0_wake", mt7623_pcie1_0_wake),
+ PINCTRL_PIN_GROUP("pcie1_1_wake", mt7623_pcie1_1_wake),
+ PINCTRL_PIN_GROUP("pcie2_0_wake", mt7623_pcie2_0_wake),
+ PINCTRL_PIN_GROUP("pcie2_1_wake", mt7623_pcie2_1_wake),
+ PINCTRL_PIN_GROUP("pcie0_clkreq", mt7623_pcie0_clkreq),
+ PINCTRL_PIN_GROUP("pcie1_clkreq", mt7623_pcie1_clkreq),
+ PINCTRL_PIN_GROUP("pcie2_clkreq", mt7623_pcie2_clkreq),
+ PINCTRL_PIN_GROUP("pcm_clk_0", mt7623_pcm_clk_0),
+ PINCTRL_PIN_GROUP("pcm_clk_1", mt7623_pcm_clk_1),
+ PINCTRL_PIN_GROUP("pcm_clk_2", mt7623_pcm_clk_2),
+ PINCTRL_PIN_GROUP("pcm_clk_3", mt7623_pcm_clk_3),
+ PINCTRL_PIN_GROUP("pcm_clk_4", mt7623_pcm_clk_4),
+ PINCTRL_PIN_GROUP("pcm_clk_5", mt7623_pcm_clk_5),
+ PINCTRL_PIN_GROUP("pcm_clk_6", mt7623_pcm_clk_6),
+ PINCTRL_PIN_GROUP("pcm_sync_0", mt7623_pcm_sync_0),
+ PINCTRL_PIN_GROUP("pcm_sync_1", mt7623_pcm_sync_1),
+ PINCTRL_PIN_GROUP("pcm_sync_2", mt7623_pcm_sync_2),
+ PINCTRL_PIN_GROUP("pcm_sync_3", mt7623_pcm_sync_3),
+ PINCTRL_PIN_GROUP("pcm_sync_4", mt7623_pcm_sync_4),
+ PINCTRL_PIN_GROUP("pcm_sync_5", mt7623_pcm_sync_5),
+ PINCTRL_PIN_GROUP("pcm_sync_6", mt7623_pcm_sync_6),
+ PINCTRL_PIN_GROUP("pcm_rx_0", mt7623_pcm_rx_0),
+ PINCTRL_PIN_GROUP("pcm_rx_1", mt7623_pcm_rx_1),
+ PINCTRL_PIN_GROUP("pcm_rx_2", mt7623_pcm_rx_2),
+ PINCTRL_PIN_GROUP("pcm_rx_3", mt7623_pcm_rx_3),
+ PINCTRL_PIN_GROUP("pcm_rx_4", mt7623_pcm_rx_4),
+ PINCTRL_PIN_GROUP("pcm_rx_5", mt7623_pcm_rx_5),
+ PINCTRL_PIN_GROUP("pcm_rx_6", mt7623_pcm_rx_6),
+ PINCTRL_PIN_GROUP("pcm_tx_0", mt7623_pcm_tx_0),
+ PINCTRL_PIN_GROUP("pcm_tx_1", mt7623_pcm_tx_1),
+ PINCTRL_PIN_GROUP("pcm_tx_2", mt7623_pcm_tx_2),
+ PINCTRL_PIN_GROUP("pcm_tx_3", mt7623_pcm_tx_3),
+ PINCTRL_PIN_GROUP("pcm_tx_4", mt7623_pcm_tx_4),
+ PINCTRL_PIN_GROUP("pcm_tx_5", mt7623_pcm_tx_5),
+ PINCTRL_PIN_GROUP("pcm_tx_6", mt7623_pcm_tx_6),
+ PINCTRL_PIN_GROUP("pwm_ch1_0", mt7623_pwm_ch1_0),
+ PINCTRL_PIN_GROUP("pwm_ch1_1", mt7623_pwm_ch1_1),
+ PINCTRL_PIN_GROUP("pwm_ch1_2", mt7623_pwm_ch1_2),
+ PINCTRL_PIN_GROUP("pwm_ch1_3", mt7623_pwm_ch1_3),
+ PINCTRL_PIN_GROUP("pwm_ch1_4", mt7623_pwm_ch1_4),
+ PINCTRL_PIN_GROUP("pwm_ch2_0", mt7623_pwm_ch2_0),
+ PINCTRL_PIN_GROUP("pwm_ch2_1", mt7623_pwm_ch2_1),
+ PINCTRL_PIN_GROUP("pwm_ch2_2", mt7623_pwm_ch2_2),
+ PINCTRL_PIN_GROUP("pwm_ch2_3", mt7623_pwm_ch2_3),
+ PINCTRL_PIN_GROUP("pwm_ch2_4", mt7623_pwm_ch2_4),
+ PINCTRL_PIN_GROUP("pwm_ch3_0", mt7623_pwm_ch3_0),
+ PINCTRL_PIN_GROUP("pwm_ch3_1", mt7623_pwm_ch3_1),
+ PINCTRL_PIN_GROUP("pwm_ch3_2", mt7623_pwm_ch3_2),
+ PINCTRL_PIN_GROUP("pwm_ch3_3", mt7623_pwm_ch3_3),
+ PINCTRL_PIN_GROUP("pwm_ch4_0", mt7623_pwm_ch4_0),
+ PINCTRL_PIN_GROUP("pwm_ch4_1", mt7623_pwm_ch4_1),
+ PINCTRL_PIN_GROUP("pwm_ch4_2", mt7623_pwm_ch4_2),
+ PINCTRL_PIN_GROUP("pwm_ch4_3", mt7623_pwm_ch4_3),
+ PINCTRL_PIN_GROUP("pwm_ch5_0", mt7623_pwm_ch5_0),
+ PINCTRL_PIN_GROUP("pwm_ch5_1", mt7623_pwm_ch5_1),
+ PINCTRL_PIN_GROUP("pwrap", mt7623_pwrap),
+ PINCTRL_PIN_GROUP("rtc", mt7623_rtc),
+ PINCTRL_PIN_GROUP("spdif_in0_0", mt7623_spdif_in0_0),
+ PINCTRL_PIN_GROUP("spdif_in0_1", mt7623_spdif_in0_1),
+ PINCTRL_PIN_GROUP("spdif_in1_0", mt7623_spdif_in1_0),
+ PINCTRL_PIN_GROUP("spdif_in1_1", mt7623_spdif_in1_1),
+ PINCTRL_PIN_GROUP("spdif_out", mt7623_spdif_out),
+ PINCTRL_PIN_GROUP("spi0", mt7623_spi0),
+ PINCTRL_PIN_GROUP("spi1", mt7623_spi1),
+ PINCTRL_PIN_GROUP("spi2", mt7623_spi2),
+ PINCTRL_PIN_GROUP("uart0_0_txd_rxd", mt7623_uart0_0_txd_rxd),
+ PINCTRL_PIN_GROUP("uart0_1_txd_rxd", mt7623_uart0_1_txd_rxd),
+ PINCTRL_PIN_GROUP("uart0_2_txd_rxd", mt7623_uart0_2_txd_rxd),
+ PINCTRL_PIN_GROUP("uart0_3_txd_rxd", mt7623_uart0_3_txd_rxd),
+ PINCTRL_PIN_GROUP("uart1_0_txd_rxd", mt7623_uart1_0_txd_rxd),
+ PINCTRL_PIN_GROUP("uart1_1_txd_rxd", mt7623_uart1_1_txd_rxd),
+ PINCTRL_PIN_GROUP("uart1_2_txd_rxd", mt7623_uart1_2_txd_rxd),
+ PINCTRL_PIN_GROUP("uart2_0_txd_rxd", mt7623_uart2_0_txd_rxd),
+ PINCTRL_PIN_GROUP("uart2_1_txd_rxd", mt7623_uart2_1_txd_rxd),
+ PINCTRL_PIN_GROUP("uart3_txd_rxd", mt7623_uart3_txd_rxd),
+ PINCTRL_PIN_GROUP("uart0_rts_cts", mt7623_uart0_rts_cts),
+ PINCTRL_PIN_GROUP("uart1_rts_cts", mt7623_uart1_rts_cts),
+ PINCTRL_PIN_GROUP("uart2_rts_cts", mt7623_uart2_rts_cts),
+ PINCTRL_PIN_GROUP("uart3_rts_cts", mt7623_uart3_rts_cts),
+ PINCTRL_PIN_GROUP("watchdog_0", mt7623_watchdog_0),
+ PINCTRL_PIN_GROUP("watchdog_1", mt7623_watchdog_1),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+
+static const char *const mt7623_aud_clk_groups[] = { "aud_ext_clk0",
+ "aud_ext_clk1", };
+static const char *const mt7623_disp_pwm_groups[] = { "disp_pwm_0",
+ "disp_pwm_1",
+ "disp_pwm_2", };
+static const char *const mt7623_ethernet_groups[] = { "esw_int", "esw_rst",
+ "ephy", "mdc_mdio", };
+static const char *const mt7623_ext_sdio_groups[] = { "ext_sdio", };
+static const char *const mt7623_hdmi_groups[] = { "hdmi_cec", "hdmi_htplg",
+ "hdmi_i2c", "hdmi_rx",
+ "hdmi_rx_i2c", };
+static const char *const mt7623_i2c_groups[] = { "i2c0", "i2c1_0", "i2c1_1",
+ "i2c1_2", "i2c1_3", "i2c1_4",
+ "i2c2_0", "i2c2_1", "i2c2_2",
+ "i2c2_3", };
+static const char *const mt7623_i2s_groups[] = { "i2s0", "i2s1",
+ "i2s2_bclk_lrclk_mclk",
+ "i2s3_bclk_lrclk_mclk",
+ "i2s4", "i2s5",
+ "i2s2_data_in", "i2s3_data_in",
+ "i2s2_data_0", "i2s2_data_1",
+ "i2s3_data_0", "i2s3_data_1",};
+static const char *const mt7623_ir_groups[] = { "ir", };
+static const char *const mt7623_lcd_groups[] = { "dsi_te", "lcm_rst",
+ "mipi_tx", };
+static const char *const mt7623_msdc_groups[] = { "msdc0", "msdc1",
+ "msdc1_ins", "msdc1_wp_0",
+ "msdc1_wp_1", "msdc1_wp_2",
+ "msdc2", "msdc3", };
+static const char *const mt7623_nandc_groups[] = { "nandc", "nandc_ceb0",
+ "nandc_ceb1", };
+static const char *const mt7623_otg_groups[] = { "otg_iddig0_0",
+ "otg_iddig0_1",
+ "otg_iddig0_2",
+ "otg_iddig1_0",
+ "otg_iddig1_1",
+ "otg_iddig1_2",
+ "otg_drv_vbus0_0",
+ "otg_drv_vbus0_1",
+ "otg_drv_vbus0_2",
+ "otg_drv_vbus1_0",
+ "otg_drv_vbus1_1",
+ "otg_drv_vbus1_2", };
+static const char *const mt7623_pcie_groups[] = { "pcie0_0_perst",
+ "pcie0_1_perst",
+ "pcie1_0_perst",
+ "pcie1_1_perst",
+ "pcie2_0_perst",
+ "pcie2_1_perst",
+ "pcie0_0_rev_perst",
+ "pcie0_1_rev_perst",
+ "pcie1_0_rev_perst",
+ "pcie1_1_rev_perst",
+ "pcie2_0_rev_perst",
+ "pcie2_1_rev_perst",
+ "pcie0_0_wake", "pcie0_1_wake",
+ "pcie2_0_wake", "pcie2_1_wake",
+ "pcie0_clkreq", "pcie1_clkreq",
+ "pcie2_clkreq", };
+static const char *const mt7623_pcm_groups[] = { "pcm_clk_0", "pcm_clk_1",
+ "pcm_clk_2", "pcm_clk_3",
+ "pcm_clk_4", "pcm_clk_5",
+ "pcm_clk_6", "pcm_sync_0",
+ "pcm_sync_1", "pcm_sync_2",
+ "pcm_sync_3", "pcm_sync_4",
+ "pcm_sync_5", "pcm_sync_6",
+ "pcm_rx_0", "pcm_rx_1",
+ "pcm_rx_2", "pcm_rx_3",
+ "pcm_rx_4", "pcm_rx_5",
+ "pcm_rx_6", "pcm_tx_0",
+ "pcm_tx_1", "pcm_tx_2",
+ "pcm_tx_3", "pcm_tx_4",
+ "pcm_tx_5", "pcm_tx_6", };
+static const char *const mt7623_pwm_groups[] = { "pwm_ch1_0", "pwm_ch1_1",
+ "pwm_ch1_2", "pwm_ch2_0",
+ "pwm_ch2_1", "pwm_ch2_2",
+ "pwm_ch3_0", "pwm_ch3_1",
+ "pwm_ch3_2", "pwm_ch4_0",
+ "pwm_ch4_1", "pwm_ch4_2",
+ "pwm_ch4_3", "pwm_ch5_0",
+ "pwm_ch5_1", "pwm_ch5_2",
+ "pwm_ch6_0", "pwm_ch6_1",
+ "pwm_ch6_2", "pwm_ch6_3",
+ "pwm_ch7_0", "pwm_ch7_1",
+ "pwm_ch7_2", };
+static const char *const mt7623_pwrap_groups[] = { "pwrap", };
+static const char *const mt7623_rtc_groups[] = { "rtc", };
+static const char *const mt7623_spi_groups[] = { "spi0", "spi2", "spi2", };
+static const char *const mt7623_spdif_groups[] = { "spdif_in0_0",
+ "spdif_in0_1", "spdif_in1_0",
+ "spdif_in1_1", "spdif_out", };
+static const char *const mt7623_uart_groups[] = { "uart0_0_txd_rxd",
+ "uart0_1_txd_rxd",
+ "uart0_2_txd_rxd",
+ "uart0_3_txd_rxd",
+ "uart1_0_txd_rxd",
+ "uart1_1_txd_rxd",
+ "uart1_2_txd_rxd",
+ "uart2_0_txd_rxd",
+ "uart2_1_txd_rxd",
+ "uart3_txd_rxd",
+ "uart0_rts_cts",
+ "uart1_rts_cts",
+ "uart2_rts_cts",
+ "uart3_rts_cts", };
+static const char *const mt7623_wdt_groups[] = { "watchdog_0", "watchdog_1", };
+
+static const struct mtk_function_desc mt7623_functions[] = {
+ {"audck", mt7623_aud_clk_groups, ARRAY_SIZE(mt7623_aud_clk_groups)},
+ {"disp", mt7623_disp_pwm_groups, ARRAY_SIZE(mt7623_disp_pwm_groups)},
+ {"eth", mt7623_ethernet_groups, ARRAY_SIZE(mt7623_ethernet_groups)},
+ {"sdio", mt7623_ext_sdio_groups, ARRAY_SIZE(mt7623_ext_sdio_groups)},
+ {"hdmi", mt7623_hdmi_groups, ARRAY_SIZE(mt7623_hdmi_groups)},
+ {"i2c", mt7623_i2c_groups, ARRAY_SIZE(mt7623_i2c_groups)},
+ {"i2s", mt7623_i2s_groups, ARRAY_SIZE(mt7623_i2s_groups)},
+ {"ir", mt7623_ir_groups, ARRAY_SIZE(mt7623_ir_groups)},
+ {"lcd", mt7623_lcd_groups, ARRAY_SIZE(mt7623_lcd_groups)},
+ {"msdc", mt7623_msdc_groups, ARRAY_SIZE(mt7623_msdc_groups)},
+ {"nand", mt7623_nandc_groups, ARRAY_SIZE(mt7623_nandc_groups)},
+ {"otg", mt7623_otg_groups, ARRAY_SIZE(mt7623_otg_groups)},
+ {"pcie", mt7623_pcie_groups, ARRAY_SIZE(mt7623_pcie_groups)},
+ {"pcm", mt7623_pcm_groups, ARRAY_SIZE(mt7623_pcm_groups)},
+ {"pwm", mt7623_pwm_groups, ARRAY_SIZE(mt7623_pwm_groups)},
+ {"pwrap", mt7623_pwrap_groups, ARRAY_SIZE(mt7623_pwrap_groups)},
+ {"rtc", mt7623_rtc_groups, ARRAY_SIZE(mt7623_rtc_groups)},
+ {"spi", mt7623_spi_groups, ARRAY_SIZE(mt7623_spi_groups)},
+ {"spdif", mt7623_spdif_groups, ARRAY_SIZE(mt7623_spdif_groups)},
+ {"uart", mt7623_uart_groups, ARRAY_SIZE(mt7623_uart_groups)},
+ {"watchdog", mt7623_wdt_groups, ARRAY_SIZE(mt7623_wdt_groups)},
+};
+
+static struct mtk_pinctrl_soc mt7623_data = {
+ .name = "mt7623_pinctrl",
+ .reg_cal = mt7623_reg_cals,
+ .pins = mt7623_pins,
+ .npins = ARRAY_SIZE(mt7623_pins),
+ .grps = mt7623_groups,
+ .ngrps = ARRAY_SIZE(mt7623_groups),
+ .funcs = mt7623_functions,
+ .nfuncs = ARRAY_SIZE(mt7623_functions),
+};
+
+/*
+ * There are some specific pins have mux functions greater than 8,
+ * and if we want to switch thees high modes we need to disable
+ * bonding constraints firstly.
+ */
+static void mt7623_bonding_disable(struct udevice *dev)
+{
+ mtk_rmw(dev, PIN_BOND_REG0, BOND_PCIE_CLR, BOND_PCIE_CLR);
+ mtk_rmw(dev, PIN_BOND_REG1, BOND_I2S_CLR, BOND_I2S_CLR);
+ mtk_rmw(dev, PIN_BOND_REG2, BOND_MSDC0E_CLR, BOND_MSDC0E_CLR);
+}
+
+static int mtk_pinctrl_mt7623_probe(struct udevice *dev)
+{
+ int err;
+
+ err = mtk_pinctrl_common_probe(dev, &mt7623_data);
+ if (err)
+ return err;
+
+ mt7623_bonding_disable(dev);
+
+ return 0;
+}
+
+static const struct udevice_id mt7623_pctrl_match[] = {
+ { .compatible = "mediatek,mt7623-pinctrl", },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mt7623_pinctrl) = {
+ .name = "mt7623_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = mt7623_pctrl_match,
+ .ops = &mtk_pinctrl_ops,
+ .probe = mtk_pinctrl_mt7623_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_pinctrl_priv),
+};
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7629.c b/drivers/pinctrl/mediatek/pinctrl-mt7629.c
new file mode 100644
index 0000000..aa6d1c2
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mt7629.c
@@ -0,0 +1,409 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <dm.h>
+
+#include "pinctrl-mtk-common.h"
+
+#define PIN_FIELD(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \
+ PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, \
+ _x_bits, 32, false)
+
+#define MT7629_PIN(_number, _name) MTK_PIN(_number, _name, DRV_GRP1)
+
+static const struct mtk_pin_field_calc mt7629_pin_mode_range[] = {
+ PIN_FIELD(0, 78, 0x300, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_dir_range[] = {
+ PIN_FIELD(0, 78, 0x0, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_di_range[] = {
+ PIN_FIELD(0, 78, 0x200, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_do_range[] = {
+ PIN_FIELD(0, 78, 0x100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_ies_range[] = {
+ PIN_FIELD(0, 10, 0x1000, 0x10, 0, 1),
+ PIN_FIELD(11, 18, 0x2000, 0x10, 0, 1),
+ PIN_FIELD(19, 32, 0x3000, 0x10, 0, 1),
+ PIN_FIELD(33, 48, 0x4000, 0x10, 0, 1),
+ PIN_FIELD(49, 50, 0x5000, 0x10, 0, 1),
+ PIN_FIELD(51, 69, 0x6000, 0x10, 0, 1),
+ PIN_FIELD(70, 78, 0x7000, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_smt_range[] = {
+ PIN_FIELD(0, 10, 0x1100, 0x10, 0, 1),
+ PIN_FIELD(11, 18, 0x2100, 0x10, 0, 1),
+ PIN_FIELD(19, 32, 0x3100, 0x10, 0, 1),
+ PIN_FIELD(33, 48, 0x4100, 0x10, 0, 1),
+ PIN_FIELD(49, 50, 0x5100, 0x10, 0, 1),
+ PIN_FIELD(51, 69, 0x6100, 0x10, 0, 1),
+ PIN_FIELD(70, 78, 0x7100, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_pullen_range[] = {
+ PIN_FIELD(0, 10, 0x1400, 0x10, 0, 1),
+ PIN_FIELD(11, 18, 0x2400, 0x10, 0, 1),
+ PIN_FIELD(19, 32, 0x3400, 0x10, 0, 1),
+ PIN_FIELD(33, 48, 0x4400, 0x10, 0, 1),
+ PIN_FIELD(49, 50, 0x5400, 0x10, 0, 1),
+ PIN_FIELD(51, 69, 0x6400, 0x10, 0, 1),
+ PIN_FIELD(70, 78, 0x7400, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_pullsel_range[] = {
+ PIN_FIELD(0, 10, 0x1500, 0x10, 0, 1),
+ PIN_FIELD(11, 18, 0x2500, 0x10, 0, 1),
+ PIN_FIELD(19, 32, 0x3500, 0x10, 0, 1),
+ PIN_FIELD(33, 48, 0x4500, 0x10, 0, 1),
+ PIN_FIELD(49, 50, 0x5500, 0x10, 0, 1),
+ PIN_FIELD(51, 69, 0x6500, 0x10, 0, 1),
+ PIN_FIELD(70, 78, 0x7500, 0x10, 0, 1),
+};
+
+static const struct mtk_pin_field_calc mt7629_pin_drv_range[] = {
+ PIN_FIELD(0, 10, 0x1600, 0x10, 0, 4),
+ PIN_FIELD(11, 18, 0x2600, 0x10, 0, 4),
+ PIN_FIELD(19, 32, 0x3600, 0x10, 0, 4),
+ PIN_FIELD(33, 48, 0x4600, 0x10, 0, 4),
+ PIN_FIELD(49, 50, 0x5600, 0x10, 0, 4),
+ PIN_FIELD(51, 69, 0x6600, 0x10, 0, 4),
+ PIN_FIELD(70, 78, 0x7600, 0x10, 0, 4),
+};
+
+static const struct mtk_pin_reg_calc mt7629_reg_cals[] = {
+ [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7629_pin_mode_range),
+ [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7629_pin_dir_range),
+ [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7629_pin_di_range),
+ [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7629_pin_do_range),
+ [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7629_pin_ies_range),
+ [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7629_pin_smt_range),
+ [PINCTRL_PIN_REG_PULLSEL] = MTK_RANGE(mt7629_pin_pullsel_range),
+ [PINCTRL_PIN_REG_PULLEN] = MTK_RANGE(mt7629_pin_pullen_range),
+ [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7629_pin_drv_range),
+};
+
+static const struct mtk_pin_desc mt7629_pins[] = {
+ MT7629_PIN(0, "TOP_5G_CLK"),
+ MT7629_PIN(1, "TOP_5G_DATA"),
+ MT7629_PIN(2, "WF0_5G_HB0"),
+ MT7629_PIN(3, "WF0_5G_HB1"),
+ MT7629_PIN(4, "WF0_5G_HB2"),
+ MT7629_PIN(5, "WF0_5G_HB3"),
+ MT7629_PIN(6, "WF0_5G_HB4"),
+ MT7629_PIN(7, "WF0_5G_HB5"),
+ MT7629_PIN(8, "WF0_5G_HB6"),
+ MT7629_PIN(9, "XO_REQ"),
+ MT7629_PIN(10, "TOP_RST_N"),
+ MT7629_PIN(11, "SYS_WATCHDOG"),
+ MT7629_PIN(12, "EPHY_LED0_N_JTDO"),
+ MT7629_PIN(13, "EPHY_LED1_N_JTDI"),
+ MT7629_PIN(14, "EPHY_LED2_N_JTMS"),
+ MT7629_PIN(15, "EPHY_LED3_N_JTCLK"),
+ MT7629_PIN(16, "EPHY_LED4_N_JTRST_N"),
+ MT7629_PIN(17, "WF2G_LED_N"),
+ MT7629_PIN(18, "WF5G_LED_N"),
+ MT7629_PIN(19, "I2C_SDA"),
+ MT7629_PIN(20, "I2C_SCL"),
+ MT7629_PIN(21, "GPIO_9"),
+ MT7629_PIN(22, "GPIO_10"),
+ MT7629_PIN(23, "GPIO_11"),
+ MT7629_PIN(24, "GPIO_12"),
+ MT7629_PIN(25, "UART1_TXD"),
+ MT7629_PIN(26, "UART1_RXD"),
+ MT7629_PIN(27, "UART1_CTS"),
+ MT7629_PIN(28, "UART1_RTS"),
+ MT7629_PIN(29, "UART2_TXD"),
+ MT7629_PIN(30, "UART2_RXD"),
+ MT7629_PIN(31, "UART2_CTS"),
+ MT7629_PIN(32, "UART2_RTS"),
+ MT7629_PIN(33, "MDI_TP_P1"),
+ MT7629_PIN(34, "MDI_TN_P1"),
+ MT7629_PIN(35, "MDI_RP_P1"),
+ MT7629_PIN(36, "MDI_RN_P1"),
+ MT7629_PIN(37, "MDI_RP_P2"),
+ MT7629_PIN(38, "MDI_RN_P2"),
+ MT7629_PIN(39, "MDI_TP_P2"),
+ MT7629_PIN(40, "MDI_TN_P2"),
+ MT7629_PIN(41, "MDI_TP_P3"),
+ MT7629_PIN(42, "MDI_TN_P3"),
+ MT7629_PIN(43, "MDI_RP_P3"),
+ MT7629_PIN(44, "MDI_RN_P3"),
+ MT7629_PIN(45, "MDI_RP_P4"),
+ MT7629_PIN(46, "MDI_RN_P4"),
+ MT7629_PIN(47, "MDI_TP_P4"),
+ MT7629_PIN(48, "MDI_TN_P4"),
+ MT7629_PIN(49, "SMI_MDC"),
+ MT7629_PIN(50, "SMI_MDIO"),
+ MT7629_PIN(51, "PCIE_PERESET_N"),
+ MT7629_PIN(52, "PWM_0"),
+ MT7629_PIN(53, "GPIO_0"),
+ MT7629_PIN(54, "GPIO_1"),
+ MT7629_PIN(55, "GPIO_2"),
+ MT7629_PIN(56, "GPIO_3"),
+ MT7629_PIN(57, "GPIO_4"),
+ MT7629_PIN(58, "GPIO_5"),
+ MT7629_PIN(59, "GPIO_6"),
+ MT7629_PIN(60, "GPIO_7"),
+ MT7629_PIN(61, "GPIO_8"),
+ MT7629_PIN(62, "SPI_CLK"),
+ MT7629_PIN(63, "SPI_CS"),
+ MT7629_PIN(64, "SPI_MOSI"),
+ MT7629_PIN(65, "SPI_MISO"),
+ MT7629_PIN(66, "SPI_WP"),
+ MT7629_PIN(67, "SPI_HOLD"),
+ MT7629_PIN(68, "UART0_TXD"),
+ MT7629_PIN(69, "UART0_RXD"),
+ MT7629_PIN(70, "TOP_2G_CLK"),
+ MT7629_PIN(71, "TOP_2G_DATA"),
+ MT7629_PIN(72, "WF0_2G_HB0"),
+ MT7629_PIN(73, "WF0_2G_HB1"),
+ MT7629_PIN(74, "WF0_2G_HB2"),
+ MT7629_PIN(75, "WF0_2G_HB3"),
+ MT7629_PIN(76, "WF0_2G_HB4"),
+ MT7629_PIN(77, "WF0_2G_HB5"),
+ MT7629_PIN(78, "WF0_2G_HB6"),
+};
+
+/* List all groups consisting of these pins dedicated to the enablement of
+ * certain hardware block and the corresponding mode for all of the pins.
+ * The hardware probably has multiple combinations of these pinouts.
+ */
+
+/* WF 5G */
+static int mt7629_wf0_5g_pins[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, };
+static int mt7629_wf0_5g_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, };
+
+/* LED for EPHY */
+static int mt7629_ephy_leds_pins[] = { 12, 13, 14, 15, 16, 17, 18, };
+static int mt7629_ephy_leds_funcs[] = { 1, 1, 1, 1, 1, 1, 1, };
+static int mt7629_ephy_led0_pins[] = { 12, };
+static int mt7629_ephy_led0_funcs[] = { 1, };
+static int mt7629_ephy_led1_pins[] = { 13, };
+static int mt7629_ephy_led1_funcs[] = { 1, };
+static int mt7629_ephy_led2_pins[] = { 14, };
+static int mt7629_ephy_led2_funcs[] = { 1, };
+static int mt7629_ephy_led3_pins[] = { 15, };
+static int mt7629_ephy_led3_funcs[] = { 1, };
+static int mt7629_ephy_led4_pins[] = { 16, };
+static int mt7629_ephy_led4_funcs[] = { 1, };
+static int mt7629_wf2g_led_pins[] = { 17, };
+static int mt7629_wf2g_led_funcs[] = { 1, };
+static int mt7629_wf5g_led_pins[] = { 18, };
+static int mt7629_wf5g_led_funcs[] = { 1, };
+
+/* Watchdog */
+static int mt7629_watchdog_pins[] = { 11, };
+static int mt7629_watchdog_funcs[] = { 1, };
+
+/* LED for GPHY */
+static int mt7629_gphy_leds_0_pins[] = { 21, 22, 23, };
+static int mt7629_gphy_leds_0_funcs[] = { 2, 2, 2, };
+static int mt7629_gphy_led1_0_pins[] = { 21, };
+static int mt7629_gphy_led1_0_funcs[] = { 2, };
+static int mt7629_gphy_led2_0_pins[] = { 22, };
+static int mt7629_gphy_led2_0_funcs[] = { 2, };
+static int mt7629_gphy_led3_0_pins[] = { 23, };
+static int mt7629_gphy_led3_0_funcs[] = { 2, };
+static int mt7629_gphy_leds_1_pins[] = { 57, 58, 59, };
+static int mt7629_gphy_leds_1_funcs[] = { 1, 1, 1, };
+static int mt7629_gphy_led1_1_pins[] = { 57, };
+static int mt7629_gphy_led1_1_funcs[] = { 1, };
+static int mt7629_gphy_led2_1_pins[] = { 58, };
+static int mt7629_gphy_led2_1_funcs[] = { 1, };
+static int mt7629_gphy_led3_1_pins[] = { 59, };
+static int mt7629_gphy_led3_1_funcs[] = { 1, };
+
+/* I2C */
+static int mt7629_i2c_0_pins[] = { 19, 20, };
+static int mt7629_i2c_0_funcs[] = { 1, 1, };
+static int mt7629_i2c_1_pins[] = { 53, 54, };
+static int mt7629_i2c_1_funcs[] = { 1, 1, };
+
+/* SPI */
+static int mt7629_spi_0_pins[] = { 21, 22, 23, 24, };
+static int mt7629_spi_0_funcs[] = { 1, 1, 1, 1, };
+static int mt7629_spi_1_pins[] = { 62, 63, 64, 65, };
+static int mt7629_spi_1_funcs[] = { 1, 1, 1, 1, };
+static int mt7629_spi_wp_pins[] = { 66, };
+static int mt7629_spi_wp_funcs[] = { 1, };
+static int mt7629_spi_hold_pins[] = { 67, };
+static int mt7629_spi_hold_funcs[] = { 1, };
+
+/* UART */
+static int mt7629_uart1_0_txd_rxd_pins[] = { 25, 26, };
+static int mt7629_uart1_0_txd_rxd_funcs[] = { 1, 1, };
+static int mt7629_uart1_1_txd_rxd_pins[] = { 53, 54, };
+static int mt7629_uart1_1_txd_rxd_funcs[] = { 2, 2, };
+static int mt7629_uart2_0_txd_rxd_pins[] = { 29, 30, };
+static int mt7629_uart2_0_txd_rxd_funcs[] = { 1, 1, };
+static int mt7629_uart2_1_txd_rxd_pins[] = { 57, 58, };
+static int mt7629_uart2_1_txd_rxd_funcs[] = { 2, 2, };
+static int mt7629_uart1_0_cts_rts_pins[] = { 27, 28, };
+static int mt7629_uart1_0_cts_rts_funcs[] = { 1, 1, };
+static int mt7629_uart1_1_cts_rts_pins[] = { 55, 56, };
+static int mt7629_uart1_1_cts_rts_funcs[] = { 2, 2, };
+static int mt7629_uart2_0_cts_rts_pins[] = { 31, 32, };
+static int mt7629_uart2_0_cts_rts_funcs[] = { 1, 1, };
+static int mt7629_uart2_1_cts_rts_pins[] = { 59, 60, };
+static int mt7629_uart2_1_cts_rts_funcs[] = { 2, 2, };
+static int mt7629_uart0_txd_rxd_pins[] = { 68, 69, };
+static int mt7629_uart0_txd_rxd_funcs[] = { 1, 1, };
+
+/* MDC/MDIO */
+static int mt7629_mdc_mdio_pins[] = { 49, 50, };
+static int mt7629_mdc_mdio_funcs[] = { 1, 1, };
+
+/* PCIE */
+static int mt7629_pcie_pereset_pins[] = { 51, };
+static int mt7629_pcie_pereset_funcs[] = { 1, };
+static int mt7629_pcie_wake_pins[] = { 55, };
+static int mt7629_pcie_wake_funcs[] = { 1, };
+static int mt7629_pcie_clkreq_pins[] = { 56, };
+static int mt7629_pcie_clkreq_funcs[] = { 1, };
+
+/* PWM */
+static int mt7629_pwm_0_pins[] = { 52, };
+static int mt7629_pwm_0_funcs[] = { 1, };
+static int mt7629_pwm_1_pins[] = { 61, };
+static int mt7629_pwm_1_funcs[] = { 2, };
+
+/* WF 2G */
+static int mt7629_wf0_2g_pins[] = { 70, 71, 72, 73, 74, 75, 76, 77, 78, };
+static int mt7629_wf0_2g_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, };
+
+/* SNFI */
+static int mt7629_snfi_pins[] = { 62, 63, 64, 65, 66, 67 };
+static int mt7629_snfi_funcs[] = { 2, 2, 2, 2, 2, 2 };
+
+/* SPI NOR */
+static int mt7629_snor_pins[] = { 62, 63, 64, 65, 66, 67 };
+static int mt7629_snor_funcs[] = { 1, 1, 1, 1, 1, 1 };
+
+static const struct mtk_group_desc mt7629_groups[] = {
+ PINCTRL_PIN_GROUP("wf0_5g", mt7629_wf0_5g),
+ PINCTRL_PIN_GROUP("ephy_leds", mt7629_ephy_leds),
+ PINCTRL_PIN_GROUP("ephy_led0", mt7629_ephy_led0),
+ PINCTRL_PIN_GROUP("ephy_led1", mt7629_ephy_led1),
+ PINCTRL_PIN_GROUP("ephy_led2", mt7629_ephy_led2),
+ PINCTRL_PIN_GROUP("ephy_led3", mt7629_ephy_led3),
+ PINCTRL_PIN_GROUP("ephy_led4", mt7629_ephy_led4),
+ PINCTRL_PIN_GROUP("wf2g_led", mt7629_wf2g_led),
+ PINCTRL_PIN_GROUP("wf5g_led", mt7629_wf5g_led),
+ PINCTRL_PIN_GROUP("watchdog", mt7629_watchdog),
+ PINCTRL_PIN_GROUP("gphy_leds_0", mt7629_gphy_leds_0),
+ PINCTRL_PIN_GROUP("gphy_led1_0", mt7629_gphy_led1_0),
+ PINCTRL_PIN_GROUP("gphy_led2_0", mt7629_gphy_led2_0),
+ PINCTRL_PIN_GROUP("gphy_led3_0", mt7629_gphy_led3_0),
+ PINCTRL_PIN_GROUP("gphy_leds_1", mt7629_gphy_leds_1),
+ PINCTRL_PIN_GROUP("gphy_led1_1", mt7629_gphy_led1_1),
+ PINCTRL_PIN_GROUP("gphy_led2_1", mt7629_gphy_led2_1),
+ PINCTRL_PIN_GROUP("gphy_led3_1", mt7629_gphy_led3_1),
+ PINCTRL_PIN_GROUP("i2c_0", mt7629_i2c_0),
+ PINCTRL_PIN_GROUP("i2c_1", mt7629_i2c_1),
+ PINCTRL_PIN_GROUP("spi_0", mt7629_spi_0),
+ PINCTRL_PIN_GROUP("spi_1", mt7629_spi_1),
+ PINCTRL_PIN_GROUP("spi_wp", mt7629_spi_wp),
+ PINCTRL_PIN_GROUP("spi_hold", mt7629_spi_hold),
+ PINCTRL_PIN_GROUP("uart1_0_txd_rxd", mt7629_uart1_0_txd_rxd),
+ PINCTRL_PIN_GROUP("uart1_1_txd_rxd", mt7629_uart1_1_txd_rxd),
+ PINCTRL_PIN_GROUP("uart2_0_txd_rxd", mt7629_uart2_0_txd_rxd),
+ PINCTRL_PIN_GROUP("uart2_1_txd_rxd", mt7629_uart2_1_txd_rxd),
+ PINCTRL_PIN_GROUP("uart1_0_cts_rts", mt7629_uart1_0_cts_rts),
+ PINCTRL_PIN_GROUP("uart1_1_cts_rts", mt7629_uart1_1_cts_rts),
+ PINCTRL_PIN_GROUP("uart2_0_cts_rts", mt7629_uart2_0_cts_rts),
+ PINCTRL_PIN_GROUP("uart2_1_cts_rts", mt7629_uart2_1_cts_rts),
+ PINCTRL_PIN_GROUP("uart0_txd_rxd", mt7629_uart0_txd_rxd),
+ PINCTRL_PIN_GROUP("mdc_mdio", mt7629_mdc_mdio),
+ PINCTRL_PIN_GROUP("pcie_pereset", mt7629_pcie_pereset),
+ PINCTRL_PIN_GROUP("pcie_wake", mt7629_pcie_wake),
+ PINCTRL_PIN_GROUP("pcie_clkreq", mt7629_pcie_clkreq),
+ PINCTRL_PIN_GROUP("pwm_0", mt7629_pwm_0),
+ PINCTRL_PIN_GROUP("pwm_1", mt7629_pwm_1),
+ PINCTRL_PIN_GROUP("wf0_2g", mt7629_wf0_2g),
+ PINCTRL_PIN_GROUP("snfi", mt7629_snfi),
+ PINCTRL_PIN_GROUP("spi_nor", mt7629_snor),
+};
+
+/* Joint those groups owning the same capability in user point of view which
+ * allows that people tend to use through the device tree.
+ */
+static const char *const mt7629_ethernet_groups[] = { "mdc_mdio", };
+static const char *const mt7629_i2c_groups[] = { "i2c_0", "i2c_1", };
+static const char *const mt7629_led_groups[] = { "ephy_leds", "ephy_led0",
+ "ephy_led1", "ephy_led2",
+ "ephy_led3", "ephy_led4",
+ "wf2g_led", "wf5g_led",
+ "gphy_leds_0", "gphy_led1_0",
+ "gphy_led2_0", "gphy_led3_0",
+ "gphy_leds_1", "gphy_led1_1",
+ "gphy_led2_1", "gphy_led3_1",};
+static const char *const mt7629_pcie_groups[] = { "pcie_pereset", "pcie_wake",
+ "pcie_clkreq", };
+static const char *const mt7629_pwm_groups[] = { "pwm_0", "pwm_1", };
+static const char *const mt7629_spi_groups[] = { "spi_0", "spi_1", "spi_wp",
+ "spi_hold", };
+static const char *const mt7629_uart_groups[] = { "uart1_0_txd_rxd",
+ "uart1_1_txd_rxd",
+ "uart2_0_txd_rxd",
+ "uart2_1_txd_rxd",
+ "uart1_0_cts_rts",
+ "uart1_1_cts_rts",
+ "uart2_0_cts_rts",
+ "uart2_1_cts_rts",
+ "uart0_txd_rxd", };
+static const char *const mt7629_wdt_groups[] = { "watchdog", };
+static const char *const mt7629_wifi_groups[] = { "wf0_5g", "wf0_2g", };
+static const char *const mt7629_flash_groups[] = { "snfi", "spi_nor" };
+
+static const struct mtk_function_desc mt7629_functions[] = {
+ {"eth", mt7629_ethernet_groups, ARRAY_SIZE(mt7629_ethernet_groups)},
+ {"i2c", mt7629_i2c_groups, ARRAY_SIZE(mt7629_i2c_groups)},
+ {"led", mt7629_led_groups, ARRAY_SIZE(mt7629_led_groups)},
+ {"pcie", mt7629_pcie_groups, ARRAY_SIZE(mt7629_pcie_groups)},
+ {"pwm", mt7629_pwm_groups, ARRAY_SIZE(mt7629_pwm_groups)},
+ {"spi", mt7629_spi_groups, ARRAY_SIZE(mt7629_spi_groups)},
+ {"uart", mt7629_uart_groups, ARRAY_SIZE(mt7629_uart_groups)},
+ {"watchdog", mt7629_wdt_groups, ARRAY_SIZE(mt7629_wdt_groups)},
+ {"wifi", mt7629_wifi_groups, ARRAY_SIZE(mt7629_wifi_groups)},
+ {"flash", mt7629_flash_groups, ARRAY_SIZE(mt7629_flash_groups)},
+};
+
+static struct mtk_pinctrl_soc mt7629_data = {
+ .name = "mt7629_pinctrl",
+ .reg_cal = mt7629_reg_cals,
+ .pins = mt7629_pins,
+ .npins = ARRAY_SIZE(mt7629_pins),
+ .grps = mt7629_groups,
+ .ngrps = ARRAY_SIZE(mt7629_groups),
+ .funcs = mt7629_functions,
+ .nfuncs = ARRAY_SIZE(mt7629_functions),
+};
+
+static int mtk_pinctrl_mt7629_probe(struct udevice *dev)
+{
+ return mtk_pinctrl_common_probe(dev, &mt7629_data);
+}
+
+static const struct udevice_id mt7629_pctrl_match[] = {
+ { .compatible = "mediatek,mt7629-pinctrl" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(mt7629_pinctrl) = {
+ .name = "mt7629_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = mt7629_pctrl_match,
+ .ops = &mtk_pinctrl_ops,
+ .probe = mtk_pinctrl_mt7629_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_pinctrl_priv),
+};
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
new file mode 100644
index 0000000..938cc75
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -0,0 +1,553 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/pinctrl.h>
+#include <asm/io.h>
+#include <asm-generic/gpio.h>
+
+#include "pinctrl-mtk-common.h"
+
+/**
+ * struct mtk_drive_desc - the structure that holds the information
+ * of the driving current
+ * @min: the minimum current of this group
+ * @max: the maximum current of this group
+ * @step: the step current of this group
+ * @scal: the weight factor
+ *
+ * formula: output = ((input) / step - 1) * scal
+ */
+struct mtk_drive_desc {
+ u8 min;
+ u8 max;
+ u8 step;
+ u8 scal;
+};
+
+/* The groups of drive strength */
+static const struct mtk_drive_desc mtk_drive[] = {
+ [DRV_GRP0] = { 4, 16, 4, 1 },
+ [DRV_GRP1] = { 4, 16, 4, 2 },
+ [DRV_GRP2] = { 2, 8, 2, 1 },
+ [DRV_GRP3] = { 2, 8, 2, 2 },
+ [DRV_GRP4] = { 2, 16, 2, 1 },
+};
+
+static const char *mtk_pinctrl_dummy_name = "_dummy";
+
+static void mtk_w32(struct udevice *dev, u32 reg, u32 val)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+ __raw_writel(val, priv->base + reg);
+}
+
+static u32 mtk_r32(struct udevice *dev, u32 reg)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return __raw_readl(priv->base + reg);
+}
+
+static inline int get_count_order(unsigned int count)
+{
+ int order;
+
+ order = fls(count) - 1;
+ if (count & (count - 1))
+ order++;
+ return order;
+}
+
+void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set)
+{
+ u32 val;
+
+ val = mtk_r32(dev, reg);
+ val &= ~mask;
+ val |= set;
+ mtk_w32(dev, reg, val);
+}
+
+static int mtk_hw_pin_field_lookup(struct udevice *dev, int pin,
+ const struct mtk_pin_reg_calc *rc,
+ struct mtk_pin_field *pfd)
+{
+ const struct mtk_pin_field_calc *c, *e;
+ u32 bits;
+
+ c = rc->range;
+ e = c + rc->nranges;
+
+ while (c < e) {
+ if (pin >= c->s_pin && pin <= c->e_pin)
+ break;
+ c++;
+ }
+
+ if (c >= e)
+ return -EINVAL;
+
+ /* Calculated bits as the overall offset the pin is located at,
+ * if c->fixed is held, that determines the all the pins in the
+ * range use the same field with the s_pin.
+ */
+ bits = c->fixed ? c->s_bit : c->s_bit + (pin - c->s_pin) * (c->x_bits);
+
+ /* Fill pfd from bits. For example 32-bit register applied is assumed
+ * when c->sz_reg is equal to 32.
+ */
+ pfd->offset = c->s_addr + c->x_addrs * (bits / c->sz_reg);
+ pfd->bitpos = bits % c->sz_reg;
+ pfd->mask = (1 << c->x_bits) - 1;
+
+ /* pfd->next is used for indicating that bit wrapping-around happens
+ * which requires the manipulation for bit 0 starting in the next
+ * register to form the complete field read/write.
+ */
+ pfd->next = pfd->bitpos + c->x_bits > c->sz_reg ? c->x_addrs : 0;
+
+ return 0;
+}
+
+static int mtk_hw_pin_field_get(struct udevice *dev, int pin,
+ int field, struct mtk_pin_field *pfd)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct mtk_pin_reg_calc *rc;
+
+ if (field < 0 || field >= PINCTRL_PIN_REG_MAX)
+ return -EINVAL;
+
+ if (priv->soc->reg_cal && priv->soc->reg_cal[field].range)
+ rc = &priv->soc->reg_cal[field];
+ else
+ return -EINVAL;
+
+ return mtk_hw_pin_field_lookup(dev, pin, rc, pfd);
+}
+
+static void mtk_hw_bits_part(struct mtk_pin_field *pf, int *h, int *l)
+{
+ *l = 32 - pf->bitpos;
+ *h = get_count_order(pf->mask) - *l;
+}
+
+static void mtk_hw_write_cross_field(struct udevice *dev,
+ struct mtk_pin_field *pf, int value)
+{
+ int nbits_l, nbits_h;
+
+ mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
+
+ mtk_rmw(dev, pf->offset, pf->mask << pf->bitpos,
+ (value & pf->mask) << pf->bitpos);
+
+ mtk_rmw(dev, pf->offset + pf->next, BIT(nbits_h) - 1,
+ (value & pf->mask) >> nbits_l);
+}
+
+static void mtk_hw_read_cross_field(struct udevice *dev,
+ struct mtk_pin_field *pf, int *value)
+{
+ int nbits_l, nbits_h, h, l;
+
+ mtk_hw_bits_part(pf, &nbits_h, &nbits_l);
+
+ l = (mtk_r32(dev, pf->offset) >> pf->bitpos) & (BIT(nbits_l) - 1);
+ h = (mtk_r32(dev, pf->offset + pf->next)) & (BIT(nbits_h) - 1);
+
+ *value = (h << nbits_l) | l;
+}
+
+static int mtk_hw_set_value(struct udevice *dev, int pin, int field,
+ int value)
+{
+ struct mtk_pin_field pf;
+ int err;
+
+ err = mtk_hw_pin_field_get(dev, pin, field, &pf);
+ if (err)
+ return err;
+
+ if (!pf.next)
+ mtk_rmw(dev, pf.offset, pf.mask << pf.bitpos,
+ (value & pf.mask) << pf.bitpos);
+ else
+ mtk_hw_write_cross_field(dev, &pf, value);
+
+ return 0;
+}
+
+static int mtk_hw_get_value(struct udevice *dev, int pin, int field,
+ int *value)
+{
+ struct mtk_pin_field pf;
+ int err;
+
+ err = mtk_hw_pin_field_get(dev, pin, field, &pf);
+ if (err)
+ return err;
+
+ if (!pf.next)
+ *value = (mtk_r32(dev, pf.offset) >> pf.bitpos) & pf.mask;
+ else
+ mtk_hw_read_cross_field(dev, &pf, value);
+
+ return 0;
+}
+
+static int mtk_get_groups_count(struct udevice *dev)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->soc->ngrps;
+}
+
+static const char *mtk_get_pin_name(struct udevice *dev,
+ unsigned int selector)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+ if (!priv->soc->grps[selector].name)
+ return mtk_pinctrl_dummy_name;
+
+ return priv->soc->pins[selector].name;
+}
+
+static int mtk_get_pins_count(struct udevice *dev)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->soc->npins;
+}
+
+static const char *mtk_get_group_name(struct udevice *dev,
+ unsigned int selector)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+ if (!priv->soc->grps[selector].name)
+ return mtk_pinctrl_dummy_name;
+
+ return priv->soc->grps[selector].name;
+}
+
+static int mtk_get_functions_count(struct udevice *dev)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+ return priv->soc->nfuncs;
+}
+
+static const char *mtk_get_function_name(struct udevice *dev,
+ unsigned int selector)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+
+ if (!priv->soc->funcs[selector].name)
+ return mtk_pinctrl_dummy_name;
+
+ return priv->soc->funcs[selector].name;
+}
+
+static int mtk_pinmux_group_set(struct udevice *dev,
+ unsigned int group_selector,
+ unsigned int func_selector)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct mtk_group_desc *grp =
+ &priv->soc->grps[group_selector];
+ int i;
+
+ for (i = 0; i < grp->num_pins; i++) {
+ int *pin_modes = grp->data;
+
+ mtk_hw_set_value(dev, grp->pins[i], PINCTRL_PIN_REG_MODE,
+ pin_modes[i]);
+ }
+
+ return 0;
+}
+
+#if CONFIG_IS_ENABLED(PINCONF)
+static const struct pinconf_param mtk_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 },
+ { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
+ { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
+ { "output-enable", PIN_CONFIG_OUTPUT_ENABLE, 1 },
+ { "output-high", PIN_CONFIG_OUTPUT, 1, },
+ { "output-low", PIN_CONFIG_OUTPUT, 0, },
+ { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
+};
+
+int mtk_pinconf_drive_set(struct udevice *dev, u32 pin, u32 arg)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct mtk_pin_desc *desc = &priv->soc->pins[pin];
+ const struct mtk_drive_desc *tb;
+ int err = -ENOTSUPP;
+
+ tb = &mtk_drive[desc->drv_n];
+ /* 4mA when (e8, e4) = (0, 0)
+ * 8mA when (e8, e4) = (0, 1)
+ * 12mA when (e8, e4) = (1, 0)
+ * 16mA when (e8, e4) = (1, 1)
+ */
+ if ((arg >= tb->min && arg <= tb->max) && !(arg % tb->step)) {
+ arg = (arg / tb->step - 1) * tb->scal;
+
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DRV, arg);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
+ unsigned int param, unsigned int arg)
+{
+ int err = 0;
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_DISABLE:
+ case PIN_CONFIG_BIAS_PULL_UP:
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ arg = (param == PIN_CONFIG_BIAS_DISABLE) ? 0 :
+ (param == PIN_CONFIG_BIAS_PULL_UP) ? 3 : 2;
+
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLSEL,
+ arg & 1);
+ if (err)
+ goto err;
+
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN,
+ !!(arg & 2));
+ if (err)
+ goto err;
+ break;
+ case PIN_CONFIG_OUTPUT_ENABLE:
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT, 0);
+ if (err)
+ goto err;
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
+ if (err)
+ goto err;
+ break;
+ case PIN_CONFIG_INPUT_ENABLE:
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_IES, 1);
+ if (err)
+ goto err;
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 0);
+ if (err)
+ goto err;
+ break;
+ case PIN_CONFIG_OUTPUT:
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR, 1);
+ if (err)
+ goto err;
+
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DO, arg);
+ if (err)
+ goto err;
+ break;
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ /* arg = 1: Input mode & SMT enable ;
+ * arg = 0: Output mode & SMT disable
+ */
+ arg = arg ? 2 : 1;
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_DIR,
+ arg & 1);
+ if (err)
+ goto err;
+
+ err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_SMT,
+ !!(arg & 2));
+ if (err)
+ goto err;
+ break;
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ err = mtk_pinconf_drive_set(dev, pin, arg);
+ if (err)
+ goto err;
+ break;
+
+ default:
+ err = -ENOTSUPP;
+ }
+
+err:
+
+ return err;
+}
+
+static int mtk_pinconf_group_set(struct udevice *dev,
+ unsigned int group_selector,
+ unsigned int param, unsigned int arg)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct mtk_group_desc *grp =
+ &priv->soc->grps[group_selector];
+ int i, ret;
+
+ for (i = 0; i < grp->num_pins; i++) {
+ ret = mtk_pinconf_set(dev, grp->pins[i], param, arg);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+#endif
+
+const struct pinctrl_ops mtk_pinctrl_ops = {
+ .get_pins_count = mtk_get_pins_count,
+ .get_pin_name = mtk_get_pin_name,
+ .get_groups_count = mtk_get_groups_count,
+ .get_group_name = mtk_get_group_name,
+ .get_functions_count = mtk_get_functions_count,
+ .get_function_name = mtk_get_function_name,
+ .pinmux_group_set = mtk_pinmux_group_set,
+#if CONFIG_IS_ENABLED(PINCONF)
+ .pinconf_num_params = ARRAY_SIZE(mtk_conf_params),
+ .pinconf_params = mtk_conf_params,
+ .pinconf_set = mtk_pinconf_set,
+ .pinconf_group_set = mtk_pinconf_group_set,
+#endif
+ .set_state = pinctrl_generic_set_state,
+};
+
+static int mtk_gpio_get(struct udevice *dev, unsigned int off)
+{
+ int val, err;
+
+ err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DI, &val);
+ if (err)
+ return err;
+
+ return !!val;
+}
+
+static int mtk_gpio_set(struct udevice *dev, unsigned int off, int val)
+{
+ return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DO, !!val);
+}
+
+static int mtk_gpio_get_direction(struct udevice *dev, unsigned int off)
+{
+ int val, err;
+
+ err = mtk_hw_get_value(dev->parent, off, PINCTRL_PIN_REG_DIR, &val);
+ if (err)
+ return err;
+
+ return val ? GPIOF_OUTPUT : GPIOF_INPUT;
+}
+
+static int mtk_gpio_direction_input(struct udevice *dev, unsigned int off)
+{
+ return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 0);
+}
+
+static int mtk_gpio_direction_output(struct udevice *dev,
+ unsigned int off, int val)
+{
+ mtk_gpio_set(dev, off, val);
+
+ /* And set the requested value */
+ return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_DIR, 1);
+}
+
+static int mtk_gpio_request(struct udevice *dev, unsigned int off,
+ const char *label)
+{
+ return mtk_hw_set_value(dev->parent, off, PINCTRL_PIN_REG_MODE, 0);
+}
+
+static int mtk_gpio_probe(struct udevice *dev)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev->parent);
+ struct gpio_dev_priv *uc_priv;
+
+ uc_priv = dev_get_uclass_priv(dev);
+ uc_priv->bank_name = priv->soc->name;
+ uc_priv->gpio_count = priv->soc->npins;
+
+ return 0;
+}
+
+static const struct dm_gpio_ops mtk_gpio_ops = {
+ .request = mtk_gpio_request,
+ .set_value = mtk_gpio_set,
+ .get_value = mtk_gpio_get,
+ .get_function = mtk_gpio_get_direction,
+ .direction_input = mtk_gpio_direction_input,
+ .direction_output = mtk_gpio_direction_output,
+};
+
+static struct driver mtk_gpio_driver = {
+ .name = "mediatek_gpio",
+ .id = UCLASS_GPIO,
+ .probe = mtk_gpio_probe,
+ .ops = &mtk_gpio_ops,
+};
+
+static int mtk_gpiochip_register(struct udevice *parent)
+{
+ struct uclass_driver *drv;
+ struct udevice *dev;
+ int ret;
+ ofnode node;
+
+ drv = lists_uclass_lookup(UCLASS_GPIO);
+ if (!drv)
+ return -ENOENT;
+
+ dev_for_each_subnode(node, parent)
+ if (ofnode_read_bool(node, "gpio-controller")) {
+ ret = 0;
+ break;
+ }
+
+ if (ret)
+ return ret;
+
+ ret = device_bind_with_driver_data(parent, &mtk_gpio_driver,
+ "mediatek_gpio", 0, node,
+ &dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int mtk_pinctrl_common_probe(struct udevice *dev,
+ struct mtk_pinctrl_soc *soc)
+{
+ struct mtk_pinctrl_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->base = dev_read_addr_ptr(dev);
+ if (priv->base == (void *)FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->soc = soc;
+
+ ret = mtk_gpiochip_register(dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
new file mode 100644
index 0000000..86559f0
--- /dev/null
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -0,0 +1,184 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#ifndef __PINCTRL_MEDIATEK_H__
+#define __PINCTRL_MEDIATEK_H__
+
+#define MTK_RANGE(_a) { .range = (_a), .nranges = ARRAY_SIZE(_a), }
+#define MTK_PIN(_number, _name, _drv_n) { \
+ .number = _number, \
+ .name = _name, \
+ .drv_n = _drv_n, \
+ }
+
+#define PINCTRL_PIN_GROUP(name, id) \
+ { \
+ name, \
+ id##_pins, \
+ ARRAY_SIZE(id##_pins), \
+ id##_funcs, \
+ }
+
+#define PIN_FIELD_CALC(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, \
+ _x_bits, _sz_reg, _fixed) { \
+ .s_pin = _s_pin, \
+ .e_pin = _e_pin, \
+ .s_addr = _s_addr, \
+ .x_addrs = _x_addrs, \
+ .s_bit = _s_bit, \
+ .x_bits = _x_bits, \
+ .sz_reg = _sz_reg, \
+ .fixed = _fixed, \
+ }
+
+/* List these attributes which could be modified for the pin */
+enum {
+ PINCTRL_PIN_REG_MODE,
+ PINCTRL_PIN_REG_DIR,
+ PINCTRL_PIN_REG_DI,
+ PINCTRL_PIN_REG_DO,
+ PINCTRL_PIN_REG_IES,
+ PINCTRL_PIN_REG_SMT,
+ PINCTRL_PIN_REG_PULLEN,
+ PINCTRL_PIN_REG_PULLSEL,
+ PINCTRL_PIN_REG_DRV,
+ PINCTRL_PIN_REG_MAX,
+};
+
+/* Group the pins by the driving current */
+enum {
+ DRV_FIXED,
+ DRV_GRP0,
+ DRV_GRP1,
+ DRV_GRP2,
+ DRV_GRP3,
+ DRV_GRP4,
+};
+
+/**
+ * struct mtk_pin_field - the structure that holds the information of the field
+ * used to describe the attribute for the pin
+ * @offset: the register offset relative to the base address
+ * @mask: the mask used to filter out the field from the register
+ * @bitpos: the start bit relative to the register
+ * @next: the indication that the field would be extended to the
+ next register
+ */
+struct mtk_pin_field {
+ u32 offset;
+ u32 mask;
+ u8 bitpos;
+ u8 next;
+};
+
+/**
+ * struct mtk_pin_field_calc - the structure that holds the range providing
+ * the guide used to look up the relevant field
+ * @s_pin: the start pin within the range
+ * @e_pin: the end pin within the range
+ * @s_addr: the start address for the range
+ * @x_addrs: the address distance between two consecutive registers
+ * within the range
+ * @s_bit: the start bit for the first register within the range
+ * @x_bits: the bit distance between two consecutive pins within
+ * the range
+ * @sz_reg: the size of bits in a register
+ * @fixed: the consecutive pins share the same bits with the 1st
+ * pin
+ */
+struct mtk_pin_field_calc {
+ u16 s_pin;
+ u16 e_pin;
+ u32 s_addr;
+ u8 x_addrs;
+ u8 s_bit;
+ u8 x_bits;
+ u8 sz_reg;
+ u8 fixed;
+};
+
+/**
+ * struct mtk_pin_reg_calc - the structure that holds all ranges used to
+ * determine which register the pin would make use of
+ * for certain pin attribute.
+ * @range: the start address for the range
+ * @nranges: the number of items in the range
+ */
+struct mtk_pin_reg_calc {
+ const struct mtk_pin_field_calc *range;
+ unsigned int nranges;
+};
+
+/**
+ * struct mtk_pin_desc - the structure that providing information
+ * for each pin of chips
+ * @number: unique pin number from the global pin number space
+ * @name: name for this pin
+ * @drv_n: the index with the driving group
+ */
+struct mtk_pin_desc {
+ unsigned int number;
+ const char *name;
+ u8 drv_n;
+};
+
+/**
+ * struct mtk_group_desc - generic pin group descriptor
+ * @name: name of the pin group
+ * @pins: array of pins that belong to the group
+ * @num_pins: number of pins in the group
+ * @data: pin controller driver specific data
+ */
+struct mtk_group_desc {
+ const char *name;
+ int *pins;
+ int num_pins;
+ void *data;
+};
+
+/**
+ * struct mtk_function_desc - generic function descriptor
+ * @name: name of the function
+ * @group_names: array of pin group names
+ * @num_group_names: number of pin group names
+ */
+struct mtk_function_desc {
+ const char *name;
+ const char * const *group_names;
+ int num_group_names;
+};
+
+/* struct mtk_pin_soc - the structure that holds SoC-specific data */
+struct mtk_pinctrl_soc {
+ const char *name;
+ const struct mtk_pin_reg_calc *reg_cal;
+ const struct mtk_pin_desc *pins;
+ int npins;
+ const struct mtk_group_desc *grps;
+ int ngrps;
+ const struct mtk_function_desc *funcs;
+ int nfuncs;
+};
+
+/**
+ * struct mtk_pinctrl_priv - private data for MTK pinctrl driver
+ *
+ * @base: base address of the pinctrl device
+ * @soc: SoC specific data
+ */
+struct mtk_pinctrl_priv {
+ void __iomem *base;
+ struct mtk_pinctrl_soc *soc;
+};
+
+extern const struct pinctrl_ops mtk_pinctrl_ops;
+
+/* A common read-modify-write helper for MediaTek chips */
+void mtk_rmw(struct udevice *dev, u32 reg, u32 mask, u32 set);
+int mtk_pinctrl_common_probe(struct udevice *dev,
+ struct mtk_pinctrl_soc *soc);
+
+#endif /* __PINCTRL_MEDIATEK_H__ */
diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig
index 27ba890..ee820a5 100644
--- a/drivers/pinctrl/meson/Kconfig
+++ b/drivers/pinctrl/meson/Kconfig
@@ -1,15 +1,27 @@
if ARCH_MESON
config PINCTRL_MESON
- depends on PINCTRL_GENERIC
+ select PINCTRL_GENERIC
+ bool
+
+config PINCTRL_MESON_GX_PMX
+ select PINCTRL_MESON
+ bool
+
+config PINCTRL_MESON_AXG_PMX
+ select PINCTRL_MESON
bool
config PINCTRL_MESON_GXBB
bool "Amlogic Meson GXBB SoC pinctrl driver"
- select PINCTRL_MESON
+ select PINCTRL_MESON_GX_PMX
config PINCTRL_MESON_GXL
bool "Amlogic Meson GXL SoC pinctrl driver"
- select PINCTRL_MESON
+ select PINCTRL_MESON_GX_PMX
+
+config PINCTRL_MESON_AXG
+ bool "Amlogic Meson AXG SoC pinctrl driver"
+ select PINCTRL_MESON_AXG_PMX
endif
diff --git a/drivers/pinctrl/meson/Makefile b/drivers/pinctrl/meson/Makefile
index 965092c..707287c 100644
--- a/drivers/pinctrl/meson/Makefile
+++ b/drivers/pinctrl/meson/Makefile
@@ -1,5 +1,8 @@
# SPDX-License-Identifier: GPL-2.0+
obj-y += pinctrl-meson.o
+obj-$(CONFIG_PINCTRL_MESON_GX_PMX) += pinctrl-meson-gx-pmx.o
+obj-$(CONFIG_PINCTRL_MESON_AXG_PMX) += pinctrl-meson-axg-pmx.o
obj-$(CONFIG_PINCTRL_MESON_GXBB) += pinctrl-meson-gxbb.o
obj-$(CONFIG_PINCTRL_MESON_GXL) += pinctrl-meson-gxl.o
+obj-$(CONFIG_PINCTRL_MESON_AXG) += pinctrl-meson-axg.o
diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c
new file mode 100644
index 0000000..c82413d
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Jerome Brunet <jbrunet@baylibre.com>
+ * Copyright (C) 2017 Xingyu Chen <xingyu.chen@amlogic.com>
+ */
+
+#include <asm/gpio.h>
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <linux/io.h>
+#include "pinctrl-meson-axg.h"
+
+static int meson_axg_pmx_get_bank(struct udevice *dev, unsigned int pin,
+ struct meson_pmx_bank **bank)
+{
+ int i;
+ struct meson_pinctrl *priv = dev_get_priv(dev);
+ struct meson_axg_pmx_data *pmx = priv->data->pmx_data;
+
+ for (i = 0; i < pmx->num_pmx_banks; i++)
+ if (pin >= pmx->pmx_banks[i].first &&
+ pin <= pmx->pmx_banks[i].last) {
+ *bank = &pmx->pmx_banks[i];
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int meson_axg_pmx_calc_reg_and_offset(struct meson_pmx_bank *bank,
+ unsigned int pin,
+ unsigned int *reg,
+ unsigned int *offset)
+{
+ int shift;
+
+ shift = pin - bank->first;
+
+ *reg = bank->reg + (bank->offset + (shift << 2)) / 32;
+ *offset = (bank->offset + (shift << 2)) % 32;
+
+ return 0;
+}
+
+static int meson_axg_pmx_update_function(struct udevice *dev,
+ unsigned int pin, unsigned int func)
+{
+ struct meson_pinctrl *priv = dev_get_priv(dev);
+ struct meson_pmx_bank *bank;
+ unsigned int offset;
+ unsigned int reg;
+ unsigned int tmp;
+ int ret;
+
+ ret = meson_axg_pmx_get_bank(dev, pin, &bank);
+ if (ret)
+ return ret;
+
+ meson_axg_pmx_calc_reg_and_offset(bank, pin, &reg, &offset);
+
+ tmp = readl(priv->reg_mux + (reg << 2));
+ tmp &= ~(0xf << offset);
+ tmp |= (func & 0xf) << offset;
+ writel(tmp, priv->reg_mux + (reg << 2));
+
+ return ret;
+}
+
+static int meson_axg_pinmux_group_set(struct udevice *dev,
+ unsigned int group_selector,
+ unsigned int func_selector)
+{
+ struct meson_pinctrl *priv = dev_get_priv(dev);
+ const struct meson_pmx_group *group;
+ const struct meson_pmx_func *func;
+ struct meson_pmx_axg_data *pmx_data;
+ int i, ret;
+
+ group = &priv->data->groups[group_selector];
+ pmx_data = (struct meson_pmx_axg_data *)group->data;
+ func = &priv->data->funcs[func_selector];
+
+ debug("pinmux: set group %s func %s\n", group->name, func->name);
+
+ for (i = 0; i < group->num_pins; i++) {
+ ret = meson_axg_pmx_update_function(dev, group->pins[i],
+ pmx_data->func);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+const struct pinctrl_ops meson_axg_pinctrl_ops = {
+ .get_groups_count = meson_pinctrl_get_groups_count,
+ .get_group_name = meson_pinctrl_get_group_name,
+ .get_functions_count = meson_pinmux_get_functions_count,
+ .get_function_name = meson_pinmux_get_function_name,
+ .pinmux_group_set = meson_axg_pinmux_group_set,
+ .set_state = pinctrl_generic_set_state,
+};
+
+static int meson_axg_gpio_request(struct udevice *dev,
+ unsigned int offset, const char *label)
+{
+ return meson_axg_pmx_update_function(dev->parent, offset, 0);
+}
+
+static const struct dm_gpio_ops meson_axg_gpio_ops = {
+ .request = meson_axg_gpio_request,
+ .set_value = meson_gpio_set,
+ .get_value = meson_gpio_get,
+ .get_function = meson_gpio_get_direction,
+ .direction_input = meson_gpio_direction_input,
+ .direction_output = meson_gpio_direction_output,
+};
+
+const struct driver meson_axg_gpio_driver = {
+ .name = "meson-axg-gpio",
+ .id = UCLASS_GPIO,
+ .probe = meson_gpio_probe,
+ .ops = &meson_axg_gpio_ops,
+};
diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg.c b/drivers/pinctrl/meson/pinctrl-meson-axg.c
new file mode 100644
index 0000000..a54fbce
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-axg.c
@@ -0,0 +1,979 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright (C) 2018 Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Based on code from Linux kernel:
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ * Author: Xingyu Chen <xingyu.chen@amlogic.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <dt-bindings/gpio/meson-axg-gpio.h>
+
+#include "pinctrl-meson-axg.h"
+
+#define EE_OFF 14
+
+/* emmc */
+static const unsigned int emmc_nand_d0_pins[] = {BOOT_0};
+static const unsigned int emmc_nand_d1_pins[] = {BOOT_1};
+static const unsigned int emmc_nand_d2_pins[] = {BOOT_2};
+static const unsigned int emmc_nand_d3_pins[] = {BOOT_3};
+static const unsigned int emmc_nand_d4_pins[] = {BOOT_4};
+static const unsigned int emmc_nand_d5_pins[] = {BOOT_5};
+static const unsigned int emmc_nand_d6_pins[] = {BOOT_6};
+static const unsigned int emmc_nand_d7_pins[] = {BOOT_7};
+
+static const unsigned int emmc_clk_pins[] = {BOOT_8};
+static const unsigned int emmc_cmd_pins[] = {BOOT_10};
+static const unsigned int emmc_ds_pins[] = {BOOT_13};
+
+/* nand */
+static const unsigned int nand_ce0_pins[] = {BOOT_8};
+static const unsigned int nand_ale_pins[] = {BOOT_9};
+static const unsigned int nand_cle_pins[] = {BOOT_10};
+static const unsigned int nand_wen_clk_pins[] = {BOOT_11};
+static const unsigned int nand_ren_wr_pins[] = {BOOT_12};
+static const unsigned int nand_rb0_pins[] = {BOOT_13};
+
+/* nor */
+static const unsigned int nor_hold_pins[] = {BOOT_3};
+static const unsigned int nor_d_pins[] = {BOOT_4};
+static const unsigned int nor_q_pins[] = {BOOT_5};
+static const unsigned int nor_c_pins[] = {BOOT_6};
+static const unsigned int nor_wp_pins[] = {BOOT_9};
+static const unsigned int nor_cs_pins[] = {BOOT_14};
+
+/* sdio */
+static const unsigned int sdio_d0_pins[] = {GPIOX_0};
+static const unsigned int sdio_d1_pins[] = {GPIOX_1};
+static const unsigned int sdio_d2_pins[] = {GPIOX_2};
+static const unsigned int sdio_d3_pins[] = {GPIOX_3};
+static const unsigned int sdio_clk_pins[] = {GPIOX_4};
+static const unsigned int sdio_cmd_pins[] = {GPIOX_5};
+
+/* spi0 */
+static const unsigned int spi0_clk_pins[] = {GPIOZ_0};
+static const unsigned int spi0_mosi_pins[] = {GPIOZ_1};
+static const unsigned int spi0_miso_pins[] = {GPIOZ_2};
+static const unsigned int spi0_ss0_pins[] = {GPIOZ_3};
+static const unsigned int spi0_ss1_pins[] = {GPIOZ_4};
+static const unsigned int spi0_ss2_pins[] = {GPIOZ_5};
+
+/* spi1 */
+static const unsigned int spi1_clk_x_pins[] = {GPIOX_19};
+static const unsigned int spi1_mosi_x_pins[] = {GPIOX_17};
+static const unsigned int spi1_miso_x_pins[] = {GPIOX_18};
+static const unsigned int spi1_ss0_x_pins[] = {GPIOX_16};
+
+static const unsigned int spi1_clk_a_pins[] = {GPIOA_4};
+static const unsigned int spi1_mosi_a_pins[] = {GPIOA_2};
+static const unsigned int spi1_miso_a_pins[] = {GPIOA_3};
+static const unsigned int spi1_ss0_a_pins[] = {GPIOA_5};
+static const unsigned int spi1_ss1_pins[] = {GPIOA_6};
+
+/* i2c0 */
+static const unsigned int i2c0_sck_pins[] = {GPIOZ_6};
+static const unsigned int i2c0_sda_pins[] = {GPIOZ_7};
+
+/* i2c1 */
+static const unsigned int i2c1_sck_z_pins[] = {GPIOZ_8};
+static const unsigned int i2c1_sda_z_pins[] = {GPIOZ_9};
+
+static const unsigned int i2c1_sck_x_pins[] = {GPIOX_16};
+static const unsigned int i2c1_sda_x_pins[] = {GPIOX_17};
+
+/* i2c2 */
+static const unsigned int i2c2_sck_x_pins[] = {GPIOX_18};
+static const unsigned int i2c2_sda_x_pins[] = {GPIOX_19};
+
+static const unsigned int i2c2_sda_a_pins[] = {GPIOA_17};
+static const unsigned int i2c2_sck_a_pins[] = {GPIOA_18};
+
+/* i2c3 */
+static const unsigned int i2c3_sda_a6_pins[] = {GPIOA_6};
+static const unsigned int i2c3_sck_a7_pins[] = {GPIOA_7};
+
+static const unsigned int i2c3_sda_a12_pins[] = {GPIOA_12};
+static const unsigned int i2c3_sck_a13_pins[] = {GPIOA_13};
+
+static const unsigned int i2c3_sda_a19_pins[] = {GPIOA_19};
+static const unsigned int i2c3_sck_a20_pins[] = {GPIOA_20};
+
+/* uart_a */
+static const unsigned int uart_rts_a_pins[] = {GPIOX_11};
+static const unsigned int uart_cts_a_pins[] = {GPIOX_10};
+static const unsigned int uart_tx_a_pins[] = {GPIOX_8};
+static const unsigned int uart_rx_a_pins[] = {GPIOX_9};
+
+/* uart_b */
+static const unsigned int uart_rts_b_z_pins[] = {GPIOZ_0};
+static const unsigned int uart_cts_b_z_pins[] = {GPIOZ_1};
+static const unsigned int uart_tx_b_z_pins[] = {GPIOZ_2};
+static const unsigned int uart_rx_b_z_pins[] = {GPIOZ_3};
+
+static const unsigned int uart_rts_b_x_pins[] = {GPIOX_18};
+static const unsigned int uart_cts_b_x_pins[] = {GPIOX_19};
+static const unsigned int uart_tx_b_x_pins[] = {GPIOX_16};
+static const unsigned int uart_rx_b_x_pins[] = {GPIOX_17};
+
+/* uart_ao_b */
+static const unsigned int uart_ao_tx_b_z_pins[] = {GPIOZ_8};
+static const unsigned int uart_ao_rx_b_z_pins[] = {GPIOZ_9};
+static const unsigned int uart_ao_cts_b_z_pins[] = {GPIOZ_6};
+static const unsigned int uart_ao_rts_b_z_pins[] = {GPIOZ_7};
+
+/* pwm_a */
+static const unsigned int pwm_a_z_pins[] = {GPIOZ_5};
+
+static const unsigned int pwm_a_x18_pins[] = {GPIOX_18};
+static const unsigned int pwm_a_x20_pins[] = {GPIOX_20};
+
+static const unsigned int pwm_a_a_pins[] = {GPIOA_14};
+
+/* pwm_b */
+static const unsigned int pwm_b_z_pins[] = {GPIOZ_4};
+
+static const unsigned int pwm_b_x_pins[] = {GPIOX_19};
+
+static const unsigned int pwm_b_a_pins[] = {GPIOA_15};
+
+/* pwm_c */
+static const unsigned int pwm_c_x10_pins[] = {GPIOX_10};
+static const unsigned int pwm_c_x17_pins[] = {GPIOX_17};
+
+static const unsigned int pwm_c_a_pins[] = {GPIOA_16};
+
+/* pwm_d */
+static const unsigned int pwm_d_x11_pins[] = {GPIOX_11};
+static const unsigned int pwm_d_x16_pins[] = {GPIOX_16};
+
+/* pwm_vs */
+static const unsigned int pwm_vs_pins[] = {GPIOA_0};
+
+/* spdif_in */
+static const unsigned int spdif_in_z_pins[] = {GPIOZ_4};
+
+static const unsigned int spdif_in_a1_pins[] = {GPIOA_1};
+static const unsigned int spdif_in_a7_pins[] = {GPIOA_7};
+static const unsigned int spdif_in_a19_pins[] = {GPIOA_19};
+static const unsigned int spdif_in_a20_pins[] = {GPIOA_20};
+
+/* spdif_out */
+static const unsigned int spdif_out_z_pins[] = {GPIOZ_5};
+
+static const unsigned int spdif_out_a1_pins[] = {GPIOA_1};
+static const unsigned int spdif_out_a11_pins[] = {GPIOA_11};
+static const unsigned int spdif_out_a19_pins[] = {GPIOA_19};
+static const unsigned int spdif_out_a20_pins[] = {GPIOA_20};
+
+/* jtag_ee */
+static const unsigned int jtag_tdo_x_pins[] = {GPIOX_0};
+static const unsigned int jtag_tdi_x_pins[] = {GPIOX_1};
+static const unsigned int jtag_clk_x_pins[] = {GPIOX_4};
+static const unsigned int jtag_tms_x_pins[] = {GPIOX_5};
+
+/* eth */
+static const unsigned int eth_txd0_x_pins[] = {GPIOX_8};
+static const unsigned int eth_txd1_x_pins[] = {GPIOX_9};
+static const unsigned int eth_txen_x_pins[] = {GPIOX_10};
+static const unsigned int eth_rgmii_rx_clk_x_pins[] = {GPIOX_12};
+static const unsigned int eth_rxd0_x_pins[] = {GPIOX_13};
+static const unsigned int eth_rxd1_x_pins[] = {GPIOX_14};
+static const unsigned int eth_rx_dv_x_pins[] = {GPIOX_15};
+static const unsigned int eth_mdio_x_pins[] = {GPIOX_21};
+static const unsigned int eth_mdc_x_pins[] = {GPIOX_22};
+
+static const unsigned int eth_txd0_y_pins[] = {GPIOY_10};
+static const unsigned int eth_txd1_y_pins[] = {GPIOY_11};
+static const unsigned int eth_txen_y_pins[] = {GPIOY_9};
+static const unsigned int eth_rgmii_rx_clk_y_pins[] = {GPIOY_2};
+static const unsigned int eth_rxd0_y_pins[] = {GPIOY_4};
+static const unsigned int eth_rxd1_y_pins[] = {GPIOY_5};
+static const unsigned int eth_rx_dv_y_pins[] = {GPIOY_3};
+static const unsigned int eth_mdio_y_pins[] = {GPIOY_0};
+static const unsigned int eth_mdc_y_pins[] = {GPIOY_1};
+
+static const unsigned int eth_rxd2_rgmii_pins[] = {GPIOY_6};
+static const unsigned int eth_rxd3_rgmii_pins[] = {GPIOY_7};
+static const unsigned int eth_rgmii_tx_clk_pins[] = {GPIOY_8};
+static const unsigned int eth_txd2_rgmii_pins[] = {GPIOY_12};
+static const unsigned int eth_txd3_rgmii_pins[] = {GPIOY_13};
+
+/* pdm */
+static const unsigned int pdm_dclk_a14_pins[] = {GPIOA_14};
+static const unsigned int pdm_dclk_a19_pins[] = {GPIOA_19};
+static const unsigned int pdm_din0_pins[] = {GPIOA_15};
+static const unsigned int pdm_din1_pins[] = {GPIOA_16};
+static const unsigned int pdm_din2_pins[] = {GPIOA_17};
+static const unsigned int pdm_din3_pins[] = {GPIOA_18};
+
+/* mclk */
+static const unsigned int mclk_c_pins[] = {GPIOA_0};
+static const unsigned int mclk_b_pins[] = {GPIOA_1};
+
+/* tdm */
+static const unsigned int tdma_sclk_pins[] = {GPIOX_12};
+static const unsigned int tdma_sclk_slv_pins[] = {GPIOX_12};
+static const unsigned int tdma_fs_pins[] = {GPIOX_13};
+static const unsigned int tdma_fs_slv_pins[] = {GPIOX_13};
+static const unsigned int tdma_din0_pins[] = {GPIOX_14};
+static const unsigned int tdma_dout0_x14_pins[] = {GPIOX_14};
+static const unsigned int tdma_dout0_x15_pins[] = {GPIOX_15};
+static const unsigned int tdma_dout1_pins[] = {GPIOX_15};
+static const unsigned int tdma_din1_pins[] = {GPIOX_15};
+
+static const unsigned int tdmc_sclk_pins[] = {GPIOA_2};
+static const unsigned int tdmc_sclk_slv_pins[] = {GPIOA_2};
+static const unsigned int tdmc_fs_pins[] = {GPIOA_3};
+static const unsigned int tdmc_fs_slv_pins[] = {GPIOA_3};
+static const unsigned int tdmc_din0_pins[] = {GPIOA_4};
+static const unsigned int tdmc_dout0_pins[] = {GPIOA_4};
+static const unsigned int tdmc_din1_pins[] = {GPIOA_5};
+static const unsigned int tdmc_dout1_pins[] = {GPIOA_5};
+static const unsigned int tdmc_din2_pins[] = {GPIOA_6};
+static const unsigned int tdmc_dout2_pins[] = {GPIOA_6};
+static const unsigned int tdmc_din3_pins[] = {GPIOA_7};
+static const unsigned int tdmc_dout3_pins[] = {GPIOA_7};
+
+static const unsigned int tdmb_sclk_pins[] = {GPIOA_8};
+static const unsigned int tdmb_sclk_slv_pins[] = {GPIOA_8};
+static const unsigned int tdmb_fs_pins[] = {GPIOA_9};
+static const unsigned int tdmb_fs_slv_pins[] = {GPIOA_9};
+static const unsigned int tdmb_din0_pins[] = {GPIOA_10};
+static const unsigned int tdmb_dout0_pins[] = {GPIOA_10};
+static const unsigned int tdmb_din1_pins[] = {GPIOA_11};
+static const unsigned int tdmb_dout1_pins[] = {GPIOA_11};
+static const unsigned int tdmb_din2_pins[] = {GPIOA_12};
+static const unsigned int tdmb_dout2_pins[] = {GPIOA_12};
+static const unsigned int tdmb_din3_pins[] = {GPIOA_13};
+static const unsigned int tdmb_dout3_pins[] = {GPIOA_13};
+
+static struct meson_pmx_group meson_axg_periphs_groups[] = {
+ GPIO_GROUP(GPIOZ_0, EE_OFF),
+ GPIO_GROUP(GPIOZ_1, EE_OFF),
+ GPIO_GROUP(GPIOZ_2, EE_OFF),
+ GPIO_GROUP(GPIOZ_3, EE_OFF),
+ GPIO_GROUP(GPIOZ_4, EE_OFF),
+ GPIO_GROUP(GPIOZ_5, EE_OFF),
+ GPIO_GROUP(GPIOZ_6, EE_OFF),
+ GPIO_GROUP(GPIOZ_7, EE_OFF),
+ GPIO_GROUP(GPIOZ_8, EE_OFF),
+ GPIO_GROUP(GPIOZ_9, EE_OFF),
+ GPIO_GROUP(GPIOZ_10, EE_OFF),
+
+ GPIO_GROUP(BOOT_0, EE_OFF),
+ GPIO_GROUP(BOOT_1, EE_OFF),
+ GPIO_GROUP(BOOT_2, EE_OFF),
+ GPIO_GROUP(BOOT_3, EE_OFF),
+ GPIO_GROUP(BOOT_4, EE_OFF),
+ GPIO_GROUP(BOOT_5, EE_OFF),
+ GPIO_GROUP(BOOT_6, EE_OFF),
+ GPIO_GROUP(BOOT_7, EE_OFF),
+ GPIO_GROUP(BOOT_8, EE_OFF),
+ GPIO_GROUP(BOOT_9, EE_OFF),
+ GPIO_GROUP(BOOT_10, EE_OFF),
+ GPIO_GROUP(BOOT_11, EE_OFF),
+ GPIO_GROUP(BOOT_12, EE_OFF),
+ GPIO_GROUP(BOOT_13, EE_OFF),
+ GPIO_GROUP(BOOT_14, EE_OFF),
+
+ GPIO_GROUP(GPIOA_0, EE_OFF),
+ GPIO_GROUP(GPIOA_1, EE_OFF),
+ GPIO_GROUP(GPIOA_2, EE_OFF),
+ GPIO_GROUP(GPIOA_3, EE_OFF),
+ GPIO_GROUP(GPIOA_4, EE_OFF),
+ GPIO_GROUP(GPIOA_5, EE_OFF),
+ GPIO_GROUP(GPIOA_6, EE_OFF),
+ GPIO_GROUP(GPIOA_7, EE_OFF),
+ GPIO_GROUP(GPIOA_8, EE_OFF),
+ GPIO_GROUP(GPIOA_9, EE_OFF),
+ GPIO_GROUP(GPIOA_10, EE_OFF),
+ GPIO_GROUP(GPIOA_11, EE_OFF),
+ GPIO_GROUP(GPIOA_12, EE_OFF),
+ GPIO_GROUP(GPIOA_13, EE_OFF),
+ GPIO_GROUP(GPIOA_14, EE_OFF),
+ GPIO_GROUP(GPIOA_15, EE_OFF),
+ GPIO_GROUP(GPIOA_16, EE_OFF),
+ GPIO_GROUP(GPIOA_17, EE_OFF),
+ GPIO_GROUP(GPIOA_19, EE_OFF),
+ GPIO_GROUP(GPIOA_20, EE_OFF),
+
+ GPIO_GROUP(GPIOX_0, EE_OFF),
+ GPIO_GROUP(GPIOX_1, EE_OFF),
+ GPIO_GROUP(GPIOX_2, EE_OFF),
+ GPIO_GROUP(GPIOX_3, EE_OFF),
+ GPIO_GROUP(GPIOX_4, EE_OFF),
+ GPIO_GROUP(GPIOX_5, EE_OFF),
+ GPIO_GROUP(GPIOX_6, EE_OFF),
+ GPIO_GROUP(GPIOX_7, EE_OFF),
+ GPIO_GROUP(GPIOX_8, EE_OFF),
+ GPIO_GROUP(GPIOX_9, EE_OFF),
+ GPIO_GROUP(GPIOX_10, EE_OFF),
+ GPIO_GROUP(GPIOX_11, EE_OFF),
+ GPIO_GROUP(GPIOX_12, EE_OFF),
+ GPIO_GROUP(GPIOX_13, EE_OFF),
+ GPIO_GROUP(GPIOX_14, EE_OFF),
+ GPIO_GROUP(GPIOX_15, EE_OFF),
+ GPIO_GROUP(GPIOX_16, EE_OFF),
+ GPIO_GROUP(GPIOX_17, EE_OFF),
+ GPIO_GROUP(GPIOX_18, EE_OFF),
+ GPIO_GROUP(GPIOX_19, EE_OFF),
+ GPIO_GROUP(GPIOX_20, EE_OFF),
+ GPIO_GROUP(GPIOX_21, EE_OFF),
+ GPIO_GROUP(GPIOX_22, EE_OFF),
+
+ GPIO_GROUP(GPIOY_0, EE_OFF),
+ GPIO_GROUP(GPIOY_1, EE_OFF),
+ GPIO_GROUP(GPIOY_2, EE_OFF),
+ GPIO_GROUP(GPIOY_3, EE_OFF),
+ GPIO_GROUP(GPIOY_4, EE_OFF),
+ GPIO_GROUP(GPIOY_5, EE_OFF),
+ GPIO_GROUP(GPIOY_6, EE_OFF),
+ GPIO_GROUP(GPIOY_7, EE_OFF),
+ GPIO_GROUP(GPIOY_8, EE_OFF),
+ GPIO_GROUP(GPIOY_9, EE_OFF),
+ GPIO_GROUP(GPIOY_10, EE_OFF),
+ GPIO_GROUP(GPIOY_11, EE_OFF),
+ GPIO_GROUP(GPIOY_12, EE_OFF),
+ GPIO_GROUP(GPIOY_13, EE_OFF),
+ GPIO_GROUP(GPIOY_14, EE_OFF),
+ GPIO_GROUP(GPIOY_15, EE_OFF),
+
+ /* bank BOOT */
+ GROUP(emmc_nand_d0, 1),
+ GROUP(emmc_nand_d1, 1),
+ GROUP(emmc_nand_d2, 1),
+ GROUP(emmc_nand_d3, 1),
+ GROUP(emmc_nand_d4, 1),
+ GROUP(emmc_nand_d5, 1),
+ GROUP(emmc_nand_d6, 1),
+ GROUP(emmc_nand_d7, 1),
+ GROUP(emmc_clk, 1),
+ GROUP(emmc_cmd, 1),
+ GROUP(emmc_ds, 1),
+ GROUP(nand_ce0, 2),
+ GROUP(nand_ale, 2),
+ GROUP(nand_cle, 2),
+ GROUP(nand_wen_clk, 2),
+ GROUP(nand_ren_wr, 2),
+ GROUP(nand_rb0, 2),
+ GROUP(nor_hold, 3),
+ GROUP(nor_d, 3),
+ GROUP(nor_q, 3),
+ GROUP(nor_c, 3),
+ GROUP(nor_wp, 3),
+ GROUP(nor_cs, 3),
+
+ /* bank GPIOZ */
+ GROUP(spi0_clk, 1),
+ GROUP(spi0_mosi, 1),
+ GROUP(spi0_miso, 1),
+ GROUP(spi0_ss0, 1),
+ GROUP(spi0_ss1, 1),
+ GROUP(spi0_ss2, 1),
+ GROUP(i2c0_sck, 1),
+ GROUP(i2c0_sda, 1),
+ GROUP(i2c1_sck_z, 1),
+ GROUP(i2c1_sda_z, 1),
+ GROUP(uart_rts_b_z, 2),
+ GROUP(uart_cts_b_z, 2),
+ GROUP(uart_tx_b_z, 2),
+ GROUP(uart_rx_b_z, 2),
+ GROUP(pwm_a_z, 2),
+ GROUP(pwm_b_z, 2),
+ GROUP(spdif_in_z, 3),
+ GROUP(spdif_out_z, 3),
+ GROUP(uart_ao_tx_b_z, 2),
+ GROUP(uart_ao_rx_b_z, 2),
+ GROUP(uart_ao_cts_b_z, 2),
+ GROUP(uart_ao_rts_b_z, 2),
+
+ /* bank GPIOX */
+ GROUP(sdio_d0, 1),
+ GROUP(sdio_d1, 1),
+ GROUP(sdio_d2, 1),
+ GROUP(sdio_d3, 1),
+ GROUP(sdio_clk, 1),
+ GROUP(sdio_cmd, 1),
+ GROUP(i2c1_sck_x, 1),
+ GROUP(i2c1_sda_x, 1),
+ GROUP(i2c2_sck_x, 1),
+ GROUP(i2c2_sda_x, 1),
+ GROUP(uart_rts_a, 1),
+ GROUP(uart_cts_a, 1),
+ GROUP(uart_tx_a, 1),
+ GROUP(uart_rx_a, 1),
+ GROUP(uart_rts_b_x, 2),
+ GROUP(uart_cts_b_x, 2),
+ GROUP(uart_tx_b_x, 2),
+ GROUP(uart_rx_b_x, 2),
+ GROUP(jtag_tdo_x, 2),
+ GROUP(jtag_tdi_x, 2),
+ GROUP(jtag_clk_x, 2),
+ GROUP(jtag_tms_x, 2),
+ GROUP(spi1_clk_x, 4),
+ GROUP(spi1_mosi_x, 4),
+ GROUP(spi1_miso_x, 4),
+ GROUP(spi1_ss0_x, 4),
+ GROUP(pwm_a_x18, 3),
+ GROUP(pwm_a_x20, 1),
+ GROUP(pwm_b_x, 3),
+ GROUP(pwm_c_x10, 3),
+ GROUP(pwm_c_x17, 3),
+ GROUP(pwm_d_x11, 3),
+ GROUP(pwm_d_x16, 3),
+ GROUP(eth_txd0_x, 4),
+ GROUP(eth_txd1_x, 4),
+ GROUP(eth_txen_x, 4),
+ GROUP(eth_rgmii_rx_clk_x, 4),
+ GROUP(eth_rxd0_x, 4),
+ GROUP(eth_rxd1_x, 4),
+ GROUP(eth_rx_dv_x, 4),
+ GROUP(eth_mdio_x, 4),
+ GROUP(eth_mdc_x, 4),
+ GROUP(tdma_sclk, 1),
+ GROUP(tdma_sclk_slv, 2),
+ GROUP(tdma_fs, 1),
+ GROUP(tdma_fs_slv, 2),
+ GROUP(tdma_din0, 1),
+ GROUP(tdma_dout0_x14, 2),
+ GROUP(tdma_dout0_x15, 1),
+ GROUP(tdma_dout1, 2),
+ GROUP(tdma_din1, 3),
+
+ /* bank GPIOY */
+ GROUP(eth_txd0_y, 1),
+ GROUP(eth_txd1_y, 1),
+ GROUP(eth_txen_y, 1),
+ GROUP(eth_rgmii_rx_clk_y, 1),
+ GROUP(eth_rxd0_y, 1),
+ GROUP(eth_rxd1_y, 1),
+ GROUP(eth_rx_dv_y, 1),
+ GROUP(eth_mdio_y, 1),
+ GROUP(eth_mdc_y, 1),
+ GROUP(eth_rxd2_rgmii, 1),
+ GROUP(eth_rxd3_rgmii, 1),
+ GROUP(eth_rgmii_tx_clk, 1),
+ GROUP(eth_txd2_rgmii, 1),
+ GROUP(eth_txd3_rgmii, 1),
+
+ /* bank GPIOA */
+ GROUP(spdif_out_a1, 4),
+ GROUP(spdif_out_a11, 3),
+ GROUP(spdif_out_a19, 2),
+ GROUP(spdif_out_a20, 1),
+ GROUP(spdif_in_a1, 3),
+ GROUP(spdif_in_a7, 3),
+ GROUP(spdif_in_a19, 1),
+ GROUP(spdif_in_a20, 2),
+ GROUP(spi1_clk_a, 3),
+ GROUP(spi1_mosi_a, 3),
+ GROUP(spi1_miso_a, 3),
+ GROUP(spi1_ss0_a, 3),
+ GROUP(spi1_ss1, 3),
+ GROUP(pwm_a_a, 3),
+ GROUP(pwm_b_a, 3),
+ GROUP(pwm_c_a, 3),
+ GROUP(pwm_vs, 2),
+ GROUP(i2c2_sda_a, 3),
+ GROUP(i2c2_sck_a, 3),
+ GROUP(i2c3_sda_a6, 4),
+ GROUP(i2c3_sck_a7, 4),
+ GROUP(i2c3_sda_a12, 4),
+ GROUP(i2c3_sck_a13, 4),
+ GROUP(i2c3_sda_a19, 4),
+ GROUP(i2c3_sck_a20, 4),
+ GROUP(pdm_dclk_a14, 1),
+ GROUP(pdm_dclk_a19, 3),
+ GROUP(pdm_din0, 1),
+ GROUP(pdm_din1, 1),
+ GROUP(pdm_din2, 1),
+ GROUP(pdm_din3, 1),
+ GROUP(mclk_c, 1),
+ GROUP(mclk_b, 1),
+ GROUP(tdmc_sclk, 1),
+ GROUP(tdmc_sclk_slv, 2),
+ GROUP(tdmc_fs, 1),
+ GROUP(tdmc_fs_slv, 2),
+ GROUP(tdmc_din0, 2),
+ GROUP(tdmc_dout0, 1),
+ GROUP(tdmc_din1, 2),
+ GROUP(tdmc_dout1, 1),
+ GROUP(tdmc_din2, 2),
+ GROUP(tdmc_dout2, 1),
+ GROUP(tdmc_din3, 2),
+ GROUP(tdmc_dout3, 1),
+ GROUP(tdmb_sclk, 1),
+ GROUP(tdmb_sclk_slv, 2),
+ GROUP(tdmb_fs, 1),
+ GROUP(tdmb_fs_slv, 2),
+ GROUP(tdmb_din0, 2),
+ GROUP(tdmb_dout0, 1),
+ GROUP(tdmb_din1, 2),
+ GROUP(tdmb_dout1, 1),
+ GROUP(tdmb_din2, 2),
+ GROUP(tdmb_dout2, 1),
+ GROUP(tdmb_din3, 2),
+ GROUP(tdmb_dout3, 1),
+};
+
+/* uart_ao_a */
+static const unsigned int uart_ao_tx_a_pins[] = {GPIOAO_0};
+static const unsigned int uart_ao_rx_a_pins[] = {GPIOAO_1};
+static const unsigned int uart_ao_cts_a_pins[] = {GPIOAO_2};
+static const unsigned int uart_ao_rts_a_pins[] = {GPIOAO_3};
+
+/* uart_ao_b */
+static const unsigned int uart_ao_tx_b_pins[] = {GPIOAO_4};
+static const unsigned int uart_ao_rx_b_pins[] = {GPIOAO_5};
+static const unsigned int uart_ao_cts_b_pins[] = {GPIOAO_2};
+static const unsigned int uart_ao_rts_b_pins[] = {GPIOAO_3};
+
+/* i2c_ao */
+static const unsigned int i2c_ao_sck_4_pins[] = {GPIOAO_4};
+static const unsigned int i2c_ao_sda_5_pins[] = {GPIOAO_5};
+static const unsigned int i2c_ao_sck_8_pins[] = {GPIOAO_8};
+static const unsigned int i2c_ao_sda_9_pins[] = {GPIOAO_9};
+static const unsigned int i2c_ao_sck_10_pins[] = {GPIOAO_10};
+static const unsigned int i2c_ao_sda_11_pins[] = {GPIOAO_11};
+
+/* i2c_ao_slave */
+static const unsigned int i2c_ao_slave_sck_pins[] = {GPIOAO_10};
+static const unsigned int i2c_ao_slave_sda_pins[] = {GPIOAO_11};
+
+/* ir_in */
+static const unsigned int remote_input_ao_pins[] = {GPIOAO_6};
+
+/* ir_out */
+static const unsigned int remote_out_ao_pins[] = {GPIOAO_7};
+
+/* pwm_ao_a */
+static const unsigned int pwm_ao_a_pins[] = {GPIOAO_3};
+
+/* pwm_ao_b */
+static const unsigned int pwm_ao_b_ao2_pins[] = {GPIOAO_2};
+static const unsigned int pwm_ao_b_ao12_pins[] = {GPIOAO_12};
+
+/* pwm_ao_c */
+static const unsigned int pwm_ao_c_ao8_pins[] = {GPIOAO_8};
+static const unsigned int pwm_ao_c_ao13_pins[] = {GPIOAO_13};
+
+/* pwm_ao_d */
+static const unsigned int pwm_ao_d_pins[] = {GPIOAO_9};
+
+/* jtag_ao */
+static const unsigned int jtag_ao_tdi_pins[] = {GPIOAO_3};
+static const unsigned int jtag_ao_tdo_pins[] = {GPIOAO_4};
+static const unsigned int jtag_ao_clk_pins[] = {GPIOAO_5};
+static const unsigned int jtag_ao_tms_pins[] = {GPIOAO_7};
+
+static struct meson_pmx_group meson_axg_aobus_groups[] = {
+ GPIO_GROUP(GPIOAO_0, 0),
+ GPIO_GROUP(GPIOAO_1, 0),
+ GPIO_GROUP(GPIOAO_2, 0),
+ GPIO_GROUP(GPIOAO_3, 0),
+ GPIO_GROUP(GPIOAO_4, 0),
+ GPIO_GROUP(GPIOAO_5, 0),
+ GPIO_GROUP(GPIOAO_6, 0),
+ GPIO_GROUP(GPIOAO_7, 0),
+ GPIO_GROUP(GPIOAO_8, 0),
+ GPIO_GROUP(GPIOAO_9, 0),
+ GPIO_GROUP(GPIOAO_10, 0),
+ GPIO_GROUP(GPIOAO_11, 0),
+ GPIO_GROUP(GPIOAO_12, 0),
+ GPIO_GROUP(GPIOAO_13, 0),
+ GPIO_GROUP(GPIO_TEST_N, 0),
+
+ /* bank AO */
+ GROUP(uart_ao_tx_a, 1),
+ GROUP(uart_ao_rx_a, 1),
+ GROUP(uart_ao_cts_a, 2),
+ GROUP(uart_ao_rts_a, 2),
+ GROUP(uart_ao_tx_b, 1),
+ GROUP(uart_ao_rx_b, 1),
+ GROUP(uart_ao_cts_b, 1),
+ GROUP(uart_ao_rts_b, 1),
+ GROUP(i2c_ao_sck_4, 2),
+ GROUP(i2c_ao_sda_5, 2),
+ GROUP(i2c_ao_sck_8, 2),
+ GROUP(i2c_ao_sda_9, 2),
+ GROUP(i2c_ao_sck_10, 2),
+ GROUP(i2c_ao_sda_11, 2),
+ GROUP(i2c_ao_slave_sck, 1),
+ GROUP(i2c_ao_slave_sda, 1),
+ GROUP(remote_input_ao, 1),
+ GROUP(remote_out_ao, 1),
+ GROUP(pwm_ao_a, 3),
+ GROUP(pwm_ao_b_ao2, 3),
+ GROUP(pwm_ao_b_ao12, 3),
+ GROUP(pwm_ao_c_ao8, 3),
+ GROUP(pwm_ao_c_ao13, 3),
+ GROUP(pwm_ao_d, 3),
+ GROUP(jtag_ao_tdi, 4),
+ GROUP(jtag_ao_tdo, 4),
+ GROUP(jtag_ao_clk, 4),
+ GROUP(jtag_ao_tms, 4),
+};
+
+static const char * const gpio_periphs_groups[] = {
+ "GPIOZ_0", "GPIOZ_1", "GPIOZ_2", "GPIOZ_3", "GPIOZ_4",
+ "GPIOZ_5", "GPIOZ_6", "GPIOZ_7", "GPIOZ_8", "GPIOZ_9",
+ "GPIOZ_10",
+
+ "BOOT_0", "BOOT_1", "BOOT_2", "BOOT_3", "BOOT_4",
+ "BOOT_5", "BOOT_6", "BOOT_7", "BOOT_8", "BOOT_9",
+ "BOOT_10", "BOOT_11", "BOOT_12", "BOOT_13", "BOOT_14",
+
+ "GPIOA_0", "GPIOA_1", "GPIOA_2", "GPIOA_3", "GPIOA_4",
+ "GPIOA_5", "GPIOA_6", "GPIOA_7", "GPIOA_8", "GPIOA_9",
+ "GPIOA_10", "GPIOA_11", "GPIOA_12", "GPIOA_13", "GPIOA_14",
+ "GPIOA_15", "GPIOA_16", "GPIOA_17", "GPIOA_18", "GPIOA_19",
+ "GPIOA_20",
+
+ "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", "GPIOX_4",
+ "GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9",
+ "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14",
+ "GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19",
+ "GPIOX_20", "GPIOX_21", "GPIOX_22",
+
+ "GPIOY_0", "GPIOY_1", "GPIOY_2", "GPIOY_3", "GPIOY_4",
+ "GPIOY_5", "GPIOY_6", "GPIOY_7", "GPIOY_8", "GPIOY_9",
+ "GPIOY_10", "GPIOY_11", "GPIOY_12", "GPIOY_13", "GPIOY_14",
+ "GPIOY_15",
+};
+
+static const char * const emmc_groups[] = {
+ "emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2",
+ "emmc_nand_d3", "emmc_nand_d4", "emmc_nand_d5",
+ "emmc_nand_d6", "emmc_nand_d7",
+ "emmc_clk", "emmc_cmd", "emmc_ds",
+};
+
+static const char * const nand_groups[] = {
+ "emmc_nand_d0", "emmc_nand_d1", "emmc_nand_d2",
+ "emmc_nand_d3", "emmc_nand_d4", "emmc_nand_d5",
+ "emmc_nand_d6", "emmc_nand_d7",
+ "nand_ce0", "nand_ale", "nand_cle",
+ "nand_wen_clk", "nand_ren_wr", "nand_rb0",
+};
+
+static const char * const nor_groups[] = {
+ "nor_d", "nor_q", "nor_c", "nor_cs",
+ "nor_hold", "nor_wp",
+};
+
+static const char * const sdio_groups[] = {
+ "sdio_d0", "sdio_d1", "sdio_d2", "sdio_d3",
+ "sdio_cmd", "sdio_clk",
+};
+
+static const char * const spi0_groups[] = {
+ "spi0_clk", "spi0_mosi", "spi0_miso", "spi0_ss0",
+ "spi0_ss1", "spi0_ss2"
+};
+
+static const char * const spi1_groups[] = {
+ "spi1_clk_x", "spi1_mosi_x", "spi1_miso_x", "spi1_ss0_x",
+ "spi1_clk_a", "spi1_mosi_a", "spi1_miso_a", "spi1_ss0_a",
+ "spi1_ss1"
+};
+
+static const char * const uart_a_groups[] = {
+ "uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a",
+};
+
+static const char * const uart_b_groups[] = {
+ "uart_tx_b_z", "uart_rx_b_z", "uart_cts_b_z", "uart_rts_b_z",
+ "uart_tx_b_x", "uart_rx_b_x", "uart_cts_b_x", "uart_rts_b_x",
+};
+
+static const char * const uart_ao_b_z_groups[] = {
+ "uart_ao_tx_b_z", "uart_ao_rx_b_z",
+ "uart_ao_cts_b_z", "uart_ao_rts_b_z",
+};
+
+static const char * const i2c0_groups[] = {
+ "i2c0_sck", "i2c0_sda",
+};
+
+static const char * const i2c1_groups[] = {
+ "i2c1_sck_z", "i2c1_sda_z",
+ "i2c1_sck_x", "i2c1_sda_x",
+};
+
+static const char * const i2c2_groups[] = {
+ "i2c2_sck_x", "i2c2_sda_x",
+ "i2c2_sda_a", "i2c2_sck_a",
+};
+
+static const char * const i2c3_groups[] = {
+ "i2c3_sda_a6", "i2c3_sck_a7",
+ "i2c3_sda_a12", "i2c3_sck_a13",
+ "i2c3_sda_a19", "i2c3_sck_a20",
+};
+
+static const char * const eth_groups[] = {
+ "eth_rxd2_rgmii", "eth_rxd3_rgmii", "eth_rgmii_tx_clk",
+ "eth_txd2_rgmii", "eth_txd3_rgmii",
+ "eth_txd0_x", "eth_txd1_x", "eth_txen_x", "eth_rgmii_rx_clk_x",
+ "eth_rxd0_x", "eth_rxd1_x", "eth_rx_dv_x", "eth_mdio_x",
+ "eth_mdc_x",
+ "eth_txd0_y", "eth_txd1_y", "eth_txen_y", "eth_rgmii_rx_clk_y",
+ "eth_rxd0_y", "eth_rxd1_y", "eth_rx_dv_y", "eth_mdio_y",
+ "eth_mdc_y",
+};
+
+static const char * const pwm_a_groups[] = {
+ "pwm_a_z", "pwm_a_x18", "pwm_a_x20", "pwm_a_a",
+};
+
+static const char * const pwm_b_groups[] = {
+ "pwm_b_z", "pwm_b_x", "pwm_b_a",
+};
+
+static const char * const pwm_c_groups[] = {
+ "pwm_c_x10", "pwm_c_x17", "pwm_c_a",
+};
+
+static const char * const pwm_d_groups[] = {
+ "pwm_d_x11", "pwm_d_x16",
+};
+
+static const char * const pwm_vs_groups[] = {
+ "pwm_vs",
+};
+
+static const char * const spdif_out_groups[] = {
+ "spdif_out_z", "spdif_out_a1", "spdif_out_a11",
+ "spdif_out_a19", "spdif_out_a20",
+};
+
+static const char * const spdif_in_groups[] = {
+ "spdif_in_z", "spdif_in_a1", "spdif_in_a7",
+ "spdif_in_a19", "spdif_in_a20",
+};
+
+static const char * const jtag_ee_groups[] = {
+ "jtag_tdo_x", "jtag_tdi_x", "jtag_clk_x",
+ "jtag_tms_x",
+};
+
+static const char * const pdm_groups[] = {
+ "pdm_din0", "pdm_din1", "pdm_din2", "pdm_din3",
+ "pdm_dclk_a14", "pdm_dclk_a19",
+};
+
+static const char * const gpio_aobus_groups[] = {
+ "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
+ "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
+ "GPIOAO_10", "GPIOAO_11", "GPIOAO_12", "GPIOAO_13",
+ "GPIO_TEST_N",
+};
+
+static const char * const uart_ao_a_groups[] = {
+ "uart_ao_tx_a", "uart_ao_rx_a", "uart_ao_cts_a", "uart_ao_rts_a",
+};
+
+static const char * const uart_ao_b_groups[] = {
+ "uart_ao_tx_b", "uart_ao_rx_b", "uart_ao_cts_b", "uart_ao_rts_b",
+};
+
+static const char * const i2c_ao_groups[] = {
+ "i2c_ao_sck_4", "i2c_ao_sda_5",
+ "i2c_ao_sck_8", "i2c_ao_sda_9",
+ "i2c_ao_sck_10", "i2c_ao_sda_11",
+};
+
+static const char * const i2c_ao_slave_groups[] = {
+ "i2c_ao_slave_sck", "i2c_ao_slave_sda",
+};
+
+static const char * const remote_input_ao_groups[] = {
+ "remote_input_ao",
+};
+
+static const char * const remote_out_ao_groups[] = {
+ "remote_out_ao",
+};
+
+static const char * const pwm_ao_a_groups[] = {
+ "pwm_ao_a",
+};
+
+static const char * const pwm_ao_b_groups[] = {
+ "pwm_ao_b_ao2", "pwm_ao_b_ao12",
+};
+
+static const char * const pwm_ao_c_groups[] = {
+ "pwm_ao_c_ao8", "pwm_ao_c_ao13",
+};
+
+static const char * const pwm_ao_d_groups[] = {
+ "pwm_ao_d",
+};
+
+static const char * const jtag_ao_groups[] = {
+ "jtag_ao_tdi", "jtag_ao_tdo", "jtag_ao_clk", "jtag_ao_tms",
+};
+
+static const char * const mclk_c_groups[] = {
+ "mclk_c",
+};
+
+static const char * const mclk_b_groups[] = {
+ "mclk_b",
+};
+
+static const char * const tdma_groups[] = {
+ "tdma_sclk", "tdma_sclk_slv", "tdma_fs", "tdma_fs_slv",
+ "tdma_din0", "tdma_dout0_x14", "tdma_dout0_x15", "tdma_dout1",
+ "tdma_din1",
+};
+
+static const char * const tdmc_groups[] = {
+ "tdmc_sclk", "tdmc_sclk_slv", "tdmc_fs", "tdmc_fs_slv",
+ "tdmc_din0", "tdmc_dout0", "tdmc_din1", "tdmc_dout1",
+ "tdmc_din2", "tdmc_dout2", "tdmc_din3", "tdmc_dout3",
+};
+
+static const char * const tdmb_groups[] = {
+ "tdmb_sclk", "tdmb_sclk_slv", "tdmb_fs", "tdmb_fs_slv",
+ "tdmb_din0", "tdmb_dout0", "tdmb_din1", "tdmb_dout1",
+ "tdmb_din2", "tdmb_dout2", "tdmb_din3", "tdmb_dout3",
+};
+
+static struct meson_pmx_func meson_axg_periphs_functions[] = {
+ FUNCTION(gpio_periphs),
+ FUNCTION(emmc),
+ FUNCTION(nor),
+ FUNCTION(spi0),
+ FUNCTION(spi1),
+ FUNCTION(sdio),
+ FUNCTION(nand),
+ FUNCTION(uart_a),
+ FUNCTION(uart_b),
+ FUNCTION(uart_ao_b_z),
+ FUNCTION(i2c0),
+ FUNCTION(i2c1),
+ FUNCTION(i2c2),
+ FUNCTION(i2c3),
+ FUNCTION(eth),
+ FUNCTION(pwm_a),
+ FUNCTION(pwm_b),
+ FUNCTION(pwm_c),
+ FUNCTION(pwm_d),
+ FUNCTION(pwm_vs),
+ FUNCTION(spdif_out),
+ FUNCTION(spdif_in),
+ FUNCTION(jtag_ee),
+ FUNCTION(pdm),
+ FUNCTION(mclk_b),
+ FUNCTION(mclk_c),
+ FUNCTION(tdma),
+ FUNCTION(tdmb),
+ FUNCTION(tdmc),
+};
+
+static struct meson_pmx_func meson_axg_aobus_functions[] = {
+ FUNCTION(gpio_aobus),
+ FUNCTION(uart_ao_a),
+ FUNCTION(uart_ao_b),
+ FUNCTION(i2c_ao),
+ FUNCTION(i2c_ao_slave),
+ FUNCTION(remote_input_ao),
+ FUNCTION(remote_out_ao),
+ FUNCTION(pwm_ao_a),
+ FUNCTION(pwm_ao_b),
+ FUNCTION(pwm_ao_c),
+ FUNCTION(pwm_ao_d),
+ FUNCTION(jtag_ao),
+};
+
+static struct meson_bank meson_axg_periphs_banks[] = {
+ /* name first last pullen pull dir out in */
+ BANK("Z", GPIOZ_0, GPIOZ_10, 3, 0, 3, 0, 9, 0, 10, 0, 11, 0),
+ BANK("BOOT", BOOT_0, BOOT_14, 4, 0, 4, 0, 12, 0, 13, 0, 14, 0),
+ BANK("A", GPIOA_0, GPIOA_20, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0),
+ BANK("X", GPIOX_0, GPIOX_22, 2, 0, 2, 0, 6, 0, 7, 0, 8, 0),
+ BANK("Y", GPIOY_0, GPIOY_15, 1, 0, 1, 0, 3, 0, 4, 0, 5, 0),
+};
+
+static struct meson_bank meson_axg_aobus_banks[] = {
+ /* name first last pullen pull dir out in */
+ BANK("AO", GPIOAO_0, GPIOAO_13, 0, 16, 0, 0, 0, 0, 0, 16, 1, 0),
+};
+
+static struct meson_pmx_bank meson_axg_periphs_pmx_banks[] = {
+ /* name first lask reg offset */
+ BANK_PMX("Z", GPIOZ_0, GPIOZ_10, 0x2, 0),
+ BANK_PMX("BOOT", BOOT_0, BOOT_14, 0x0, 0),
+ BANK_PMX("A", GPIOA_0, GPIOA_20, 0xb, 0),
+ BANK_PMX("X", GPIOX_0, GPIOX_22, 0x4, 0),
+ BANK_PMX("Y", GPIOY_0, GPIOY_15, 0x8, 0),
+};
+
+static struct meson_axg_pmx_data meson_axg_periphs_pmx_banks_data = {
+ .pmx_banks = meson_axg_periphs_pmx_banks,
+ .num_pmx_banks = ARRAY_SIZE(meson_axg_periphs_pmx_banks),
+};
+
+static struct meson_pmx_bank meson_axg_aobus_pmx_banks[] = {
+ BANK_PMX("AO", GPIOAO_0, GPIOAO_13, 0x0, 0),
+};
+
+static struct meson_axg_pmx_data meson_axg_aobus_pmx_banks_data = {
+ .pmx_banks = meson_axg_aobus_pmx_banks,
+ .num_pmx_banks = ARRAY_SIZE(meson_axg_aobus_pmx_banks),
+};
+
+struct meson_pinctrl_data meson_axg_periphs_pinctrl_data = {
+ .name = "periphs-banks",
+ .pin_base = 11,
+ .groups = meson_axg_periphs_groups,
+ .funcs = meson_axg_periphs_functions,
+ .banks = meson_axg_periphs_banks,
+ .num_pins = 100,
+ .num_groups = ARRAY_SIZE(meson_axg_periphs_groups),
+ .num_funcs = ARRAY_SIZE(meson_axg_periphs_functions),
+ .num_banks = ARRAY_SIZE(meson_axg_periphs_banks),
+ .gpio_driver = &meson_axg_gpio_driver,
+ .pmx_data = &meson_axg_periphs_pmx_banks_data,
+};
+
+struct meson_pinctrl_data meson_axg_aobus_pinctrl_data = {
+ .name = "aobus-banks",
+ .pin_base = 0,
+ .groups = meson_axg_aobus_groups,
+ .funcs = meson_axg_aobus_functions,
+ .banks = meson_axg_aobus_banks,
+ .num_pins = 14,
+ .num_groups = ARRAY_SIZE(meson_axg_aobus_groups),
+ .num_funcs = ARRAY_SIZE(meson_axg_aobus_functions),
+ .num_banks = ARRAY_SIZE(meson_axg_aobus_banks),
+ .gpio_driver = &meson_axg_gpio_driver,
+ .pmx_data = &meson_axg_aobus_pmx_banks_data,
+};
+
+static const struct udevice_id meson_axg_pinctrl_match[] = {
+ {
+ .compatible = "amlogic,meson-axg-periphs-pinctrl",
+ .data = (ulong)&meson_axg_periphs_pinctrl_data,
+ },
+ {
+ .compatible = "amlogic,meson-axg-aobus-pinctrl",
+ .data = (ulong)&meson_axg_aobus_pinctrl_data,
+ },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(meson_axg_pinctrl) = {
+ .name = "meson-axg-pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = of_match_ptr(meson_axg_pinctrl_match),
+ .probe = meson_pinctrl_probe,
+ .priv_auto_alloc_size = sizeof(struct meson_pinctrl),
+ .ops = &meson_axg_pinctrl_ops,
+};
diff --git a/drivers/pinctrl/meson/pinctrl-meson-axg.h b/drivers/pinctrl/meson/pinctrl-meson-axg.h
new file mode 100644
index 0000000..c8d2b3a
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-axg.h
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2017 Jerome Brunet <jbrunet@baylibre.com>
+ * Copyright (C) 2017 Xingyu Chen <xingyu.chen@amlogic.com>
+ */
+
+#ifndef __PINCTRL_MESON_AXG_H__
+#define __PINCTRL_MESON_AXG_H__
+
+#include "pinctrl-meson.h"
+
+struct meson_pmx_bank {
+ const char *name;
+ unsigned int first;
+ unsigned int last;
+ unsigned int reg;
+ unsigned int offset;
+};
+
+struct meson_axg_pmx_data {
+ struct meson_pmx_bank *pmx_banks;
+ unsigned int num_pmx_banks;
+};
+
+#define BANK_PMX(n, f, l, r, o) \
+ { \
+ .name = n, \
+ .first = f, \
+ .last = l, \
+ .reg = r, \
+ .offset = o, \
+ }
+
+struct meson_pmx_axg_data {
+ unsigned int func;
+};
+
+#define PMX_DATA(f) \
+ { \
+ .func = f, \
+ }
+
+#define GROUP(grp, f) \
+ { \
+ .name = #grp, \
+ .pins = grp ## _pins, \
+ .num_pins = ARRAY_SIZE(grp ## _pins), \
+ .data = (const struct meson_pmx_axg_data[]){ \
+ PMX_DATA(f), \
+ }, \
+ }
+
+#define GPIO_GROUP(gpio, b) \
+ { \
+ .name = #gpio, \
+ .pins = (const unsigned int[]){ PIN(gpio, b) }, \
+ .num_pins = 1, \
+ .data = (const struct meson_pmx_axg_data[]){ \
+ PMX_DATA(0), \
+ }, \
+ }
+
+extern const struct pinctrl_ops meson_axg_pinctrl_ops;
+extern const struct driver meson_axg_gpio_driver;
+
+#endif /* __PINCTRL_MESON_AXG_H__ */
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c b/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c
new file mode 100644
index 0000000..fc1538e
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
+ */
+
+#include <asm/gpio.h>
+#include <common.h>
+#include <dm.h>
+#include <dm/pinctrl.h>
+#include <linux/io.h>
+#include "pinctrl-meson-gx.h"
+
+static void meson_gx_pinmux_disable_other_groups(struct meson_pinctrl *priv,
+ unsigned int pin,
+ int sel_group)
+{
+ struct meson_pmx_group *group;
+ struct meson_gx_pmx_data *pmx_data;
+ void __iomem *addr;
+ int i, j;
+
+ for (i = 0; i < priv->data->num_groups; i++) {
+ group = &priv->data->groups[i];
+ pmx_data = (struct meson_gx_pmx_data *)group->data;
+ if (pmx_data->is_gpio || i == sel_group)
+ continue;
+
+ for (j = 0; j < group->num_pins; j++) {
+ if (group->pins[j] == pin) {
+ /* We have found a group using the pin */
+ debug("pinmux: disabling %s\n", group->name);
+ addr = priv->reg_mux + pmx_data->reg * 4;
+ writel(readl(addr) & ~BIT(pmx_data->bit), addr);
+ }
+ }
+ }
+}
+
+static int meson_gx_pinmux_group_set(struct udevice *dev,
+ unsigned int group_selector,
+ unsigned int func_selector)
+{
+ struct meson_pinctrl *priv = dev_get_priv(dev);
+ const struct meson_pmx_group *group;
+ const struct meson_pmx_func *func;
+ struct meson_gx_pmx_data *pmx_data;
+ void __iomem *addr;
+ int i;
+
+ group = &priv->data->groups[group_selector];
+ pmx_data = (struct meson_gx_pmx_data *)group->data;
+ func = &priv->data->funcs[func_selector];
+
+ debug("pinmux: set group %s func %s\n", group->name, func->name);
+
+ /*
+ * Disable groups using the same pins.
+ * The selected group is not disabled to avoid glitches.
+ */
+ for (i = 0; i < group->num_pins; i++) {
+ meson_gx_pinmux_disable_other_groups(priv,
+ group->pins[i],
+ group_selector);
+ }
+
+ /* Function 0 (GPIO) doesn't need any additional setting */
+ if (func_selector) {
+ addr = priv->reg_mux + pmx_data->reg * 4;
+ writel(readl(addr) | BIT(pmx_data->bit), addr);
+ }
+
+ return 0;
+}
+
+const struct pinctrl_ops meson_gx_pinctrl_ops = {
+ .get_groups_count = meson_pinctrl_get_groups_count,
+ .get_group_name = meson_pinctrl_get_group_name,
+ .get_functions_count = meson_pinmux_get_functions_count,
+ .get_function_name = meson_pinmux_get_function_name,
+ .pinmux_group_set = meson_gx_pinmux_group_set,
+ .set_state = pinctrl_generic_set_state,
+};
+
+static const struct dm_gpio_ops meson_gx_gpio_ops = {
+ .set_value = meson_gpio_set,
+ .get_value = meson_gpio_get,
+ .get_function = meson_gpio_get_direction,
+ .direction_input = meson_gpio_direction_input,
+ .direction_output = meson_gpio_direction_output,
+};
+
+const struct driver meson_gx_gpio_driver = {
+ .name = "meson-gx-gpio",
+ .id = UCLASS_GPIO,
+ .probe = meson_gpio_probe,
+ .ops = &meson_gx_gpio_ops,
+};
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gx.h b/drivers/pinctrl/meson/pinctrl-meson-gx.h
new file mode 100644
index 0000000..4c1aa1a
--- /dev/null
+++ b/drivers/pinctrl/meson/pinctrl-meson-gx.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
+ * Copyright (C) 2017 Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef __PINCTRL_MESON_GX_H__
+#define __PINCTRL_MESON_GX_H__
+
+#include "pinctrl-meson.h"
+
+struct meson_gx_pmx_data {
+ bool is_gpio;
+ unsigned int reg;
+ unsigned int bit;
+};
+
+#define PMX_DATA(r, b, g) \
+ { \
+ .reg = r, \
+ .bit = b, \
+ .is_gpio = g, \
+ }
+
+#define GROUP(grp, r, b) \
+ { \
+ .name = #grp, \
+ .pins = grp ## _pins, \
+ .num_pins = ARRAY_SIZE(grp ## _pins), \
+ .data = (const struct meson_gx_pmx_data[]){ \
+ PMX_DATA(r, b, false), \
+ }, \
+ }
+
+#define GPIO_GROUP(gpio, b) \
+ { \
+ .name = #gpio, \
+ .pins = (const unsigned int[]){ PIN(gpio, b) }, \
+ .num_pins = 1, \
+ .data = (const struct meson_gx_pmx_data[]){ \
+ PMX_DATA(0, 0, true), \
+ }, \
+ }
+
+extern const struct pinctrl_ops meson_gx_pinctrl_ops;
+extern const struct driver meson_gx_gpio_driver;
+
+#endif /* __PINCTRL_MESON_GX_H__ */
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
index a8e47e3..22e8b05 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
@@ -11,7 +11,7 @@
#include <dm/pinctrl.h>
#include <dt-bindings/gpio/meson-gxbb-gpio.h>
-#include "pinctrl-meson.h"
+#include "pinctrl-meson-gx.h"
#define EE_OFF 15
@@ -417,6 +417,7 @@ struct meson_pinctrl_data meson_gxbb_periphs_pinctrl_data = {
.num_groups = ARRAY_SIZE(meson_gxbb_periphs_groups),
.num_funcs = ARRAY_SIZE(meson_gxbb_periphs_functions),
.num_banks = ARRAY_SIZE(meson_gxbb_periphs_banks),
+ .gpio_driver = &meson_gx_gpio_driver,
};
struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = {
@@ -429,6 +430,7 @@ struct meson_pinctrl_data meson_gxbb_aobus_pinctrl_data = {
.num_groups = ARRAY_SIZE(meson_gxbb_aobus_groups),
.num_funcs = ARRAY_SIZE(meson_gxbb_aobus_functions),
.num_banks = ARRAY_SIZE(meson_gxbb_aobus_banks),
+ .gpio_driver = &meson_gx_gpio_driver,
};
static const struct udevice_id meson_gxbb_pinctrl_match[] = {
@@ -449,5 +451,5 @@ U_BOOT_DRIVER(meson_gxbb_pinctrl) = {
.of_match = of_match_ptr(meson_gxbb_pinctrl_match),
.probe = meson_pinctrl_probe,
.priv_auto_alloc_size = sizeof(struct meson_pinctrl),
- .ops = &meson_pinctrl_ops,
+ .ops = &meson_gx_pinctrl_ops,
};
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
index ba6e353..1819eee 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
@@ -11,7 +11,7 @@
#include <dm/pinctrl.h>
#include <dt-bindings/gpio/meson-gxl-gpio.h>
-#include "pinctrl-meson.h"
+#include "pinctrl-meson-gx.h"
#define EE_OFF 11
@@ -699,6 +699,7 @@ struct meson_pinctrl_data meson_gxl_periphs_pinctrl_data = {
.num_groups = ARRAY_SIZE(meson_gxl_periphs_groups),
.num_funcs = ARRAY_SIZE(meson_gxl_periphs_functions),
.num_banks = ARRAY_SIZE(meson_gxl_periphs_banks),
+ .gpio_driver = &meson_gx_gpio_driver,
};
struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = {
@@ -711,6 +712,7 @@ struct meson_pinctrl_data meson_gxl_aobus_pinctrl_data = {
.num_groups = ARRAY_SIZE(meson_gxl_aobus_groups),
.num_funcs = ARRAY_SIZE(meson_gxl_aobus_functions),
.num_banks = ARRAY_SIZE(meson_gxl_aobus_banks),
+ .gpio_driver = &meson_gx_gpio_driver,
};
static const struct udevice_id meson_gxl_pinctrl_match[] = {
@@ -731,5 +733,5 @@ U_BOOT_DRIVER(meson_gxl_pinctrl) = {
.of_match = of_match_ptr(meson_gxl_pinctrl_match),
.probe = meson_pinctrl_probe,
.priv_auto_alloc_size = sizeof(struct meson_pinctrl),
- .ops = &meson_pinctrl_ops,
+ .ops = &meson_gx_pinctrl_ops,
};
diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c
index 387c241..0bd6152 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.c
+++ b/drivers/pinctrl/meson/pinctrl-meson.c
@@ -20,15 +20,15 @@ DECLARE_GLOBAL_DATA_PTR;
static const char *meson_pinctrl_dummy_name = "_dummy";
-static int meson_pinctrl_get_groups_count(struct udevice *dev)
+int meson_pinctrl_get_groups_count(struct udevice *dev)
{
struct meson_pinctrl *priv = dev_get_priv(dev);
return priv->data->num_groups;
}
-static const char *meson_pinctrl_get_group_name(struct udevice *dev,
- unsigned selector)
+const char *meson_pinctrl_get_group_name(struct udevice *dev,
+ unsigned int selector)
{
struct meson_pinctrl *priv = dev_get_priv(dev);
@@ -38,87 +38,21 @@ static const char *meson_pinctrl_get_group_name(struct udevice *dev,
return priv->data->groups[selector].name;
}
-static int meson_pinmux_get_functions_count(struct udevice *dev)
+int meson_pinmux_get_functions_count(struct udevice *dev)
{
struct meson_pinctrl *priv = dev_get_priv(dev);
return priv->data->num_funcs;
}
-static const char *meson_pinmux_get_function_name(struct udevice *dev,
- unsigned selector)
+const char *meson_pinmux_get_function_name(struct udevice *dev,
+ unsigned int selector)
{
struct meson_pinctrl *priv = dev_get_priv(dev);
return priv->data->funcs[selector].name;
}
-static void meson_pinmux_disable_other_groups(struct meson_pinctrl *priv,
- unsigned int pin, int sel_group)
-{
- struct meson_pmx_group *group;
- void __iomem *addr;
- int i, j;
-
- for (i = 0; i < priv->data->num_groups; i++) {
- group = &priv->data->groups[i];
- if (group->is_gpio || i == sel_group)
- continue;
-
- for (j = 0; j < group->num_pins; j++) {
- if (group->pins[j] == pin) {
- /* We have found a group using the pin */
- debug("pinmux: disabling %s\n", group->name);
- addr = priv->reg_mux + group->reg * 4;
- writel(readl(addr) & ~BIT(group->bit), addr);
- }
- }
- }
-}
-
-static int meson_pinmux_group_set(struct udevice *dev,
- unsigned group_selector,
- unsigned func_selector)
-{
- struct meson_pinctrl *priv = dev_get_priv(dev);
- const struct meson_pmx_group *group;
- const struct meson_pmx_func *func;
- void __iomem *addr;
- int i;
-
- group = &priv->data->groups[group_selector];
- func = &priv->data->funcs[func_selector];
-
- debug("pinmux: set group %s func %s\n", group->name, func->name);
-
- /*
- * Disable groups using the same pins.
- * The selected group is not disabled to avoid glitches.
- */
- for (i = 0; i < group->num_pins; i++) {
- meson_pinmux_disable_other_groups(priv,
- group->pins[i],
- group_selector);
- }
-
- /* Function 0 (GPIO) doesn't need any additional setting */
- if (func_selector) {
- addr = priv->reg_mux + group->reg * 4;
- writel(readl(addr) | BIT(group->bit), addr);
- }
-
- return 0;
-}
-
-const struct pinctrl_ops meson_pinctrl_ops = {
- .get_groups_count = meson_pinctrl_get_groups_count,
- .get_group_name = meson_pinctrl_get_group_name,
- .get_functions_count = meson_pinmux_get_functions_count,
- .get_function_name = meson_pinmux_get_function_name,
- .pinmux_group_set = meson_pinmux_group_set,
- .set_state = pinctrl_generic_set_state,
-};
-
static int meson_gpio_calc_reg_and_bit(struct udevice *dev, unsigned int offset,
enum meson_reg_type reg_type,
unsigned int *reg, unsigned int *bit)
@@ -149,7 +83,7 @@ static int meson_gpio_calc_reg_and_bit(struct udevice *dev, unsigned int offset,
return 0;
}
-static int meson_gpio_get(struct udevice *dev, unsigned int offset)
+int meson_gpio_get(struct udevice *dev, unsigned int offset)
{
struct meson_pinctrl *priv = dev_get_priv(dev->parent);
unsigned int reg, bit;
@@ -162,7 +96,7 @@ static int meson_gpio_get(struct udevice *dev, unsigned int offset)
return !!(readl(priv->reg_gpio + reg) & BIT(bit));
}
-static int meson_gpio_set(struct udevice *dev, unsigned int offset, int value)
+int meson_gpio_set(struct udevice *dev, unsigned int offset, int value)
{
struct meson_pinctrl *priv = dev_get_priv(dev->parent);
unsigned int reg, bit;
@@ -177,7 +111,7 @@ static int meson_gpio_set(struct udevice *dev, unsigned int offset, int value)
return 0;
}
-static int meson_gpio_get_direction(struct udevice *dev, unsigned int offset)
+int meson_gpio_get_direction(struct udevice *dev, unsigned int offset)
{
struct meson_pinctrl *priv = dev_get_priv(dev->parent);
unsigned int reg, bit, val;
@@ -192,7 +126,7 @@ static int meson_gpio_get_direction(struct udevice *dev, unsigned int offset)
return (val & BIT(bit)) ? GPIOF_INPUT : GPIOF_OUTPUT;
}
-static int meson_gpio_direction_input(struct udevice *dev, unsigned int offset)
+int meson_gpio_direction_input(struct udevice *dev, unsigned int offset)
{
struct meson_pinctrl *priv = dev_get_priv(dev->parent);
unsigned int reg, bit;
@@ -207,8 +141,8 @@ static int meson_gpio_direction_input(struct udevice *dev, unsigned int offset)
return 0;
}
-static int meson_gpio_direction_output(struct udevice *dev,
- unsigned int offset, int value)
+int meson_gpio_direction_output(struct udevice *dev,
+ unsigned int offset, int value)
{
struct meson_pinctrl *priv = dev_get_priv(dev->parent);
unsigned int reg, bit;
@@ -229,7 +163,7 @@ static int meson_gpio_direction_output(struct udevice *dev,
return 0;
}
-static int meson_gpio_probe(struct udevice *dev)
+int meson_gpio_probe(struct udevice *dev)
{
struct meson_pinctrl *priv = dev_get_priv(dev->parent);
struct gpio_dev_priv *uc_priv;
@@ -241,21 +175,6 @@ static int meson_gpio_probe(struct udevice *dev)
return 0;
}
-static const struct dm_gpio_ops meson_gpio_ops = {
- .set_value = meson_gpio_set,
- .get_value = meson_gpio_get,
- .get_function = meson_gpio_get_direction,
- .direction_input = meson_gpio_direction_input,
- .direction_output = meson_gpio_direction_output,
-};
-
-static struct driver meson_gpio_driver = {
- .name = "meson-gpio",
- .id = UCLASS_GPIO,
- .probe = meson_gpio_probe,
- .ops = &meson_gpio_ops,
-};
-
static fdt_addr_t parse_address(int offset, const char *name, int na, int ns)
{
int index, len = 0;
@@ -334,7 +253,7 @@ int meson_pinctrl_probe(struct udevice *dev)
sprintf(name, "meson-gpio");
/* Create child device UCLASS_GPIO and bind it */
- device_bind(dev, &meson_gpio_driver, name, NULL, gpio, &gpio_dev);
+ device_bind(dev, priv->data->gpio_driver, name, NULL, gpio, &gpio_dev);
dev_set_of_offset(gpio_dev, gpio);
return 0;
diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h
index 6ec89ba..bdee721 100644
--- a/drivers/pinctrl/meson/pinctrl-meson.h
+++ b/drivers/pinctrl/meson/pinctrl-meson.h
@@ -12,9 +12,7 @@ struct meson_pmx_group {
const char *name;
const unsigned int *pins;
unsigned int num_pins;
- bool is_gpio;
- unsigned int reg;
- unsigned int bit;
+ const void *data;
};
struct meson_pmx_func {
@@ -33,6 +31,8 @@ struct meson_pinctrl_data {
unsigned int num_groups;
unsigned int num_funcs;
unsigned int num_banks;
+ const struct driver *gpio_driver;
+ void *pmx_data;
};
struct meson_pinctrl {
@@ -89,23 +89,6 @@ struct meson_bank {
#define PIN(x, b) (b + x)
-#define GROUP(grp, r, b) \
- { \
- .name = #grp, \
- .pins = grp ## _pins, \
- .num_pins = ARRAY_SIZE(grp ## _pins), \
- .reg = r, \
- .bit = b, \
- }
-
-#define GPIO_GROUP(gpio, b) \
- { \
- .name = #gpio, \
- .pins = (const unsigned int[]){ PIN(gpio, b) }, \
- .num_pins = 1, \
- .is_gpio = true, \
- }
-
#define FUNCTION(fn) \
{ \
.name = #fn, \
@@ -131,6 +114,20 @@ struct meson_bank {
extern const struct pinctrl_ops meson_pinctrl_ops;
+int meson_pinctrl_get_groups_count(struct udevice *dev);
+const char *meson_pinctrl_get_group_name(struct udevice *dev,
+ unsigned int selector);
+int meson_pinmux_get_functions_count(struct udevice *dev);
+const char *meson_pinmux_get_function_name(struct udevice *dev,
+ unsigned int selector);
int meson_pinctrl_probe(struct udevice *dev);
+int meson_gpio_get(struct udevice *dev, unsigned int offset);
+int meson_gpio_set(struct udevice *dev, unsigned int offset, int value);
+int meson_gpio_get_direction(struct udevice *dev, unsigned int offset);
+int meson_gpio_direction_input(struct udevice *dev, unsigned int offset);
+int meson_gpio_direction_output(struct udevice *dev, unsigned int offset,
+ int value);
+int meson_gpio_probe(struct udevice *dev);
+
#endif /* __PINCTRL_MESON_H__ */
diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig
index a08b428..93deaef 100644
--- a/drivers/power/domain/Kconfig
+++ b/drivers/power/domain/Kconfig
@@ -23,6 +23,13 @@ config IMX8_POWER_DOMAIN
Enable support for manipulating NXP i.MX8 on-SoC power domains via IPC
requests to the SCU.
+config MTK_POWER_DOMAIN
+ bool "Enable the MediaTek power domain driver"
+ depends on POWER_DOMAIN && ARCH_MEDIATEK
+ help
+ Enable support for manipulating MediaTek power domains via MMIO
+ mapped registers.
+
config MESON_GX_VPU_POWER_DOMAIN
bool "Enable Amlogic Meson GX VPU power domain driver"
depends on ARCH_MESON
diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile
index b08d18f..695aafe 100644
--- a/drivers/power/domain/Makefile
+++ b/drivers/power/domain/Makefile
@@ -6,6 +6,7 @@
obj-$(CONFIG_$(SPL_)POWER_DOMAIN) += power-domain-uclass.o
obj-$(CONFIG_BCM6328_POWER_DOMAIN) += bcm6328-power-domain.o
obj-$(CONFIG_IMX8_POWER_DOMAIN) += imx8-power-domain.o
+obj-$(CONFIG_MTK_POWER_DOMAIN) += mtk-power-domain.o
obj-$(CONFIG_MESON_GX_VPU_POWER_DOMAIN) += meson-gx-pwrc-vpu.o
obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain.o
obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o
diff --git a/drivers/power/domain/mtk-power-domain.c b/drivers/power/domain/mtk-power-domain.c
new file mode 100644
index 0000000..c67e880
--- /dev/null
+++ b/drivers/power/domain/mtk-power-domain.c
@@ -0,0 +1,406 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <power-domain-uclass.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <linux/iopoll.h>
+
+#include <dt-bindings/power/mt7623-power.h>
+#include <dt-bindings/power/mt7629-power.h>
+
+#define SPM_EN (0xb16 << 16 | 0x1)
+#define SPM_VDE_PWR_CON 0x0210
+#define SPM_MFG_PWR_CON 0x0214
+#define SPM_ISP_PWR_CON 0x0238
+#define SPM_DIS_PWR_CON 0x023c
+#define SPM_CONN_PWR_CON 0x0280
+#define SPM_BDP_PWR_CON 0x029c
+#define SPM_ETH_PWR_CON 0x02a0
+#define SPM_HIF_PWR_CON 0x02a4
+#define SPM_IFR_MSC_PWR_CON 0x02a8
+#define SPM_ETHSYS_PWR_CON 0x2e0
+#define SPM_HIF0_PWR_CON 0x2e4
+#define SPM_HIF1_PWR_CON 0x2e8
+#define SPM_PWR_STATUS 0x60c
+#define SPM_PWR_STATUS_2ND 0x610
+
+#define PWR_RST_B_BIT BIT(0)
+#define PWR_ISO_BIT BIT(1)
+#define PWR_ON_BIT BIT(2)
+#define PWR_ON_2ND_BIT BIT(3)
+#define PWR_CLK_DIS_BIT BIT(4)
+
+#define PWR_STATUS_CONN BIT(1)
+#define PWR_STATUS_DISP BIT(3)
+#define PWR_STATUS_MFG BIT(4)
+#define PWR_STATUS_ISP BIT(5)
+#define PWR_STATUS_VDEC BIT(7)
+#define PWR_STATUS_BDP BIT(14)
+#define PWR_STATUS_ETH BIT(15)
+#define PWR_STATUS_HIF BIT(16)
+#define PWR_STATUS_IFR_MSC BIT(17)
+#define PWR_STATUS_ETHSYS BIT(24)
+#define PWR_STATUS_HIF0 BIT(25)
+#define PWR_STATUS_HIF1 BIT(26)
+
+/* Infrasys configuration */
+#define INFRA_TOPDCM_CTRL 0x10
+#define INFRA_TOPAXI_PROT_EN 0x220
+#define INFRA_TOPAXI_PROT_STA1 0x228
+
+#define DCM_TOP_EN BIT(0)
+
+enum scp_domain_type {
+ SCPSYS_MT7623,
+ SCPSYS_MT7629,
+};
+
+struct scp_domain;
+
+struct scp_domain_data {
+ struct scp_domain *scpd;
+ u32 sta_mask;
+ int ctl_offs;
+ u32 sram_pdn_bits;
+ u32 sram_pdn_ack_bits;
+ u32 bus_prot_mask;
+};
+
+struct scp_domain {
+ void __iomem *base;
+ void __iomem *infracfg;
+ enum scp_domain_type type;
+ struct scp_domain_data *data;
+};
+
+static struct scp_domain_data scp_domain_mt7623[] = {
+ [MT7623_POWER_DOMAIN_CONN] = {
+ .sta_mask = PWR_STATUS_CONN,
+ .ctl_offs = SPM_CONN_PWR_CON,
+ .bus_prot_mask = BIT(8) | BIT(2),
+ },
+ [MT7623_POWER_DOMAIN_DISP] = {
+ .sta_mask = PWR_STATUS_DISP,
+ .ctl_offs = SPM_DIS_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .bus_prot_mask = BIT(2),
+ },
+ [MT7623_POWER_DOMAIN_MFG] = {
+ .sta_mask = PWR_STATUS_MFG,
+ .ctl_offs = SPM_MFG_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(12, 12),
+ },
+ [MT7623_POWER_DOMAIN_VDEC] = {
+ .sta_mask = PWR_STATUS_VDEC,
+ .ctl_offs = SPM_VDE_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(12, 12),
+ },
+ [MT7623_POWER_DOMAIN_ISP] = {
+ .sta_mask = PWR_STATUS_ISP,
+ .ctl_offs = SPM_ISP_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(13, 12),
+ },
+ [MT7623_POWER_DOMAIN_BDP] = {
+ .sta_mask = PWR_STATUS_BDP,
+ .ctl_offs = SPM_BDP_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ },
+ [MT7623_POWER_DOMAIN_ETH] = {
+ .sta_mask = PWR_STATUS_ETH,
+ .ctl_offs = SPM_ETH_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ },
+ [MT7623_POWER_DOMAIN_HIF] = {
+ .sta_mask = PWR_STATUS_HIF,
+ .ctl_offs = SPM_HIF_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ },
+ [MT7623_POWER_DOMAIN_IFR_MSC] = {
+ .sta_mask = PWR_STATUS_IFR_MSC,
+ .ctl_offs = SPM_IFR_MSC_PWR_CON,
+ },
+};
+
+static struct scp_domain_data scp_domain_mt7629[] = {
+ [MT7629_POWER_DOMAIN_ETHSYS] = {
+ .sta_mask = PWR_STATUS_ETHSYS,
+ .ctl_offs = SPM_ETHSYS_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ .bus_prot_mask = (BIT(3) | BIT(17)),
+ },
+ [MT7629_POWER_DOMAIN_HIF0] = {
+ .sta_mask = PWR_STATUS_HIF0,
+ .ctl_offs = SPM_HIF0_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ .bus_prot_mask = GENMASK(25, 24),
+ },
+ [MT7629_POWER_DOMAIN_HIF1] = {
+ .sta_mask = PWR_STATUS_HIF1,
+ .ctl_offs = SPM_HIF1_PWR_CON,
+ .sram_pdn_bits = GENMASK(11, 8),
+ .sram_pdn_ack_bits = GENMASK(15, 12),
+ .bus_prot_mask = GENMASK(28, 26),
+ },
+};
+
+/**
+ * This function enables the bus protection bits for disabled power
+ * domains so that the system does not hang when some unit accesses the
+ * bus while in power down.
+ */
+static int mtk_infracfg_set_bus_protection(void __iomem *infracfg,
+ u32 mask)
+{
+ u32 val;
+
+ clrsetbits_le32(infracfg + INFRA_TOPAXI_PROT_EN, mask, mask);
+
+ return readl_poll_timeout(infracfg + INFRA_TOPAXI_PROT_STA1, val,
+ (val & mask) == mask, 100);
+}
+
+static int mtk_infracfg_clear_bus_protection(void __iomem *infracfg,
+ u32 mask)
+{
+ u32 val;
+
+ clrbits_le32(infracfg + INFRA_TOPAXI_PROT_EN, mask);
+
+ return readl_poll_timeout(infracfg + INFRA_TOPAXI_PROT_STA1, val,
+ !(val & mask), 100);
+}
+
+static int scpsys_domain_is_on(struct scp_domain_data *data)
+{
+ struct scp_domain *scpd = data->scpd;
+ u32 sta = readl(scpd->base + SPM_PWR_STATUS) &
+ data->sta_mask;
+ u32 sta2 = readl(scpd->base + SPM_PWR_STATUS_2ND) &
+ data->sta_mask;
+
+ /*
+ * A domain is on when both status bits are set. If only one is set
+ * return an error. This happens while powering up a domain
+ */
+ if (sta && sta2)
+ return true;
+ if (!sta && !sta2)
+ return false;
+
+ return -EINVAL;
+}
+
+static int scpsys_power_on(struct power_domain *power_domain)
+{
+ struct scp_domain *scpd = dev_get_priv(power_domain->dev);
+ struct scp_domain_data *data = &scpd->data[power_domain->id];
+ void __iomem *ctl_addr = scpd->base + data->ctl_offs;
+ u32 pdn_ack = data->sram_pdn_ack_bits;
+ u32 val;
+ int ret, tmp;
+
+ writel(SPM_EN, scpd->base);
+
+ val = readl(ctl_addr);
+ val |= PWR_ON_BIT;
+ writel(val, ctl_addr);
+
+ val |= PWR_ON_2ND_BIT;
+ writel(val, ctl_addr);
+
+ ret = readx_poll_timeout(scpsys_domain_is_on, data, tmp, tmp > 0,
+ 100);
+ if (ret < 0)
+ return ret;
+
+ val &= ~PWR_CLK_DIS_BIT;
+ writel(val, ctl_addr);
+
+ val &= ~PWR_ISO_BIT;
+ writel(val, ctl_addr);
+
+ val |= PWR_RST_B_BIT;
+ writel(val, ctl_addr);
+
+ val &= ~data->sram_pdn_bits;
+ writel(val, ctl_addr);
+
+ ret = readl_poll_timeout(ctl_addr, tmp, !(tmp & pdn_ack), 100);
+ if (ret < 0)
+ return ret;
+
+ if (data->bus_prot_mask) {
+ ret = mtk_infracfg_clear_bus_protection(scpd->infracfg,
+ data->bus_prot_mask);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int scpsys_power_off(struct power_domain *power_domain)
+{
+ struct scp_domain *scpd = dev_get_priv(power_domain->dev);
+ struct scp_domain_data *data = &scpd->data[power_domain->id];
+ void __iomem *ctl_addr = scpd->base + data->ctl_offs;
+ u32 pdn_ack = data->sram_pdn_ack_bits;
+ u32 val;
+ int ret, tmp;
+
+ if (data->bus_prot_mask) {
+ ret = mtk_infracfg_set_bus_protection(scpd->infracfg,
+ data->bus_prot_mask);
+ if (ret)
+ return ret;
+ }
+
+ val = readl(ctl_addr);
+ val |= data->sram_pdn_bits;
+ writel(val, ctl_addr);
+
+ ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == pdn_ack,
+ 100);
+ if (ret < 0)
+ return ret;
+
+ val |= PWR_ISO_BIT;
+ writel(val, ctl_addr);
+
+ val &= ~PWR_RST_B_BIT;
+ writel(val, ctl_addr);
+
+ val |= PWR_CLK_DIS_BIT;
+ writel(val, ctl_addr);
+
+ val &= ~PWR_ON_BIT;
+ writel(val, ctl_addr);
+
+ val &= ~PWR_ON_2ND_BIT;
+ writel(val, ctl_addr);
+
+ ret = readx_poll_timeout(scpsys_domain_is_on, data, tmp, !tmp, 100);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int scpsys_power_request(struct power_domain *power_domain)
+{
+ struct scp_domain *scpd = dev_get_priv(power_domain->dev);
+ struct scp_domain_data *data;
+
+ data = &scpd->data[power_domain->id];
+ data->scpd = scpd;
+
+ return 0;
+}
+
+static int scpsys_power_free(struct power_domain *power_domain)
+{
+ return 0;
+}
+
+static int mtk_power_domain_hook(struct udevice *dev)
+{
+ struct scp_domain *scpd = dev_get_priv(dev);
+
+ scpd->type = (enum scp_domain_type)dev_get_driver_data(dev);
+
+ switch (scpd->type) {
+ case SCPSYS_MT7623:
+ scpd->data = scp_domain_mt7623;
+ break;
+ case SCPSYS_MT7629:
+ scpd->data = scp_domain_mt7629;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mtk_power_domain_probe(struct udevice *dev)
+{
+ struct ofnode_phandle_args args;
+ struct scp_domain *scpd = dev_get_priv(dev);
+ struct regmap *regmap;
+ struct clk_bulk bulk;
+ int err;
+
+ scpd->base = dev_read_addr_ptr(dev);
+ if (!scpd->base)
+ return -ENOENT;
+
+ err = mtk_power_domain_hook(dev);
+ if (err)
+ return err;
+
+ /* get corresponding syscon phandle */
+ err = dev_read_phandle_with_args(dev, "infracfg", NULL, 0, 0, &args);
+ if (err)
+ return err;
+
+ regmap = syscon_node_to_regmap(args.node);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ scpd->infracfg = regmap_get_range(regmap, 0);
+ if (!scpd->infracfg)
+ return -ENOENT;
+
+ /* enable Infra DCM */
+ setbits_le32(scpd->infracfg + INFRA_TOPDCM_CTRL, DCM_TOP_EN);
+
+ err = clk_get_bulk(dev, &bulk);
+ if (err)
+ return err;
+
+ return clk_enable_bulk(&bulk);
+}
+
+static const struct udevice_id mtk_power_domain_ids[] = {
+ {
+ .compatible = "mediatek,mt7623-scpsys",
+ .data = SCPSYS_MT7623,
+ },
+ {
+ .compatible = "mediatek,mt7629-scpsys",
+ .data = SCPSYS_MT7629,
+ },
+ { /* sentinel */ }
+};
+
+struct power_domain_ops mtk_power_domain_ops = {
+ .free = scpsys_power_free,
+ .off = scpsys_power_off,
+ .on = scpsys_power_on,
+ .request = scpsys_power_request,
+};
+
+U_BOOT_DRIVER(mtk_power_domain) = {
+ .name = "mtk_power_domain",
+ .id = UCLASS_POWER_DOMAIN,
+ .ops = &mtk_power_domain_ops,
+ .probe = mtk_power_domain_probe,
+ .of_match = mtk_power_domain_ids,
+ .priv_auto_alloc_size = sizeof(struct scp_domain),
+};
diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile
index e14c1cf..976ec66 100644
--- a/drivers/ram/Makefile
+++ b/drivers/ram/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_ARCH_BMIPS) += bmips_ram.o
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_K3_AM654_DDRSS) += k3-am654-ddrss.o
+obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
diff --git a/drivers/ram/mediatek/Makefile b/drivers/ram/mediatek/Makefile
new file mode 100644
index 0000000..95507b5
--- /dev/null
+++ b/drivers/ram/mediatek/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2018 MediaTek Inc.
+#
+# SPDX-License-Identifier: GPL-2.0
+#
+
+obj-$(CONFIG_TARGET_MT7629) = ddr3-mt7629.o
diff --git a/drivers/ram/mediatek/ddr3-mt7629.c b/drivers/ram/mediatek/ddr3-mt7629.c
new file mode 100644
index 0000000..b413f49
--- /dev/null
+++ b/drivers/ram/mediatek/ddr3-mt7629.c
@@ -0,0 +1,766 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek DDR3 driver for MT7629 SoC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Wu Zou <wu.zou@mediatek.com>
+ * Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <asm/io.h>
+
+/* EMI */
+#define EMI_CONA 0x000
+#define EMI_CONF 0x028
+#define EMI_CONM 0x060
+
+/* DDR PHY */
+#define DDRPHY_PLL1 0x0000
+#define DDRPHY_PLL2 0x0004
+#define DDRPHY_PLL3 0x0008
+#define DDRPHY_PLL4 0x000c
+#define DDRPHY_PLL5 0x0010
+#define DDRPHY_PLL7 0x0018
+#define DDRPHY_B0_DLL_ARPI0 0x0080
+#define DDRPHY_B0_DLL_ARPI1 0x0084
+#define DDRPHY_B0_DLL_ARPI2 0x0088
+#define DDRPHY_B0_DLL_ARPI3 0x008c
+#define DDRPHY_B0_DLL_ARPI4 0x0090
+#define DDRPHY_B0_DLL_ARPI5 0x0094
+#define DDRPHY_B0_DQ2 0x00a0
+#define DDRPHY_B0_DQ3 0x00a4
+#define DDRPHY_B0_DQ4 0x00a8
+#define DDRPHY_B0_DQ5 0x00ac
+#define DDRPHY_B0_DQ6 0x00b0
+#define DDRPHY_B0_DQ7 0x00b4
+#define DDRPHY_B0_DQ8 0x00b8
+#define DDRPHY_B1_DLL_ARPI0 0x0100
+#define DDRPHY_B1_DLL_ARPI1 0x0104
+#define DDRPHY_B1_DLL_ARPI2 0x0108
+#define DDRPHY_B1_DLL_ARPI3 0x010c
+#define DDRPHY_B1_DLL_ARPI4 0x0110
+#define DDRPHY_B1_DLL_ARPI5 0x0114
+#define DDRPHY_B1_DQ2 0x0120
+#define DDRPHY_B1_DQ3 0x0124
+#define DDRPHY_B1_DQ4 0x0128
+#define DDRPHY_B1_DQ5 0x012c
+#define DDRPHY_B1_DQ6 0x0130
+#define DDRPHY_B1_DQ7 0x0134
+#define DDRPHY_B1_DQ8 0x0138
+#define DDRPHY_CA_DLL_ARPI0 0x0180
+#define DDRPHY_CA_DLL_ARPI1 0x0184
+#define DDRPHY_CA_DLL_ARPI2 0x0188
+#define DDRPHY_CA_DLL_ARPI3 0x018c
+#define DDRPHY_CA_DLL_ARPI4 0x0190
+#define DDRPHY_CA_DLL_ARPI5 0x0194
+#define DDRPHY_CA_CMD2 0x01a0
+#define DDRPHY_CA_CMD3 0x01a4
+#define DDRPHY_CA_CMD5 0x01ac
+#define DDRPHY_CA_CMD6 0x01b0
+#define DDRPHY_CA_CMD7 0x01b4
+#define DDRPHY_CA_CMD8 0x01b8
+#define DDRPHY_MISC_VREF_CTRL 0x0264
+#define DDRPHY_MISC_IMP_CTRL0 0x0268
+#define DDRPHY_MISC_IMP_CTRL1 0x026c
+#define DDRPHY_MISC_SHU_OPT 0x0270
+#define DDRPHY_MISC_SPM_CTRL0 0x0274
+#define DDRPHY_MISC_SPM_CTRL1 0x0278
+#define DDRPHY_MISC_SPM_CTRL2 0x027c
+#define DDRPHY_MISC_CG_CTRL0 0x0284
+#define DDRPHY_MISC_CG_CTRL1 0x0288
+#define DDRPHY_MISC_CG_CTRL2 0x028c
+#define DDRPHY_MISC_CG_CTRL4 0x0294
+#define DDRPHY_MISC_CTRL0 0x029c
+#define DDRPHY_MISC_CTRL1 0x02a0
+#define DDRPHY_MISC_CTRL3 0x02a8
+#define DDRPHY_MISC_RXDVS1 0x05e4
+#define DDRPHY_SHU1_B0_DQ4 0x0c10
+#define DDRPHY_SHU1_B0_DQ5 0x0c14
+#define DDRPHY_SHU1_B0_DQ6 0x0c18
+#define DDRPHY_SHU1_B0_DQ7 0x0c1c
+#define DDRPHY_SHU1_B1_DQ4 0x0c90
+#define DDRPHY_SHU1_B1_DQ5 0x0c94
+#define DDRPHY_SHU1_B1_DQ6 0x0c98
+#define DDRPHY_SHU1_B1_DQ7 0x0c9c
+#define DDRPHY_SHU1_CA_CMD2 0x0d08
+#define DDRPHY_SHU1_CA_CMD4 0x0d10
+#define DDRPHY_SHU1_CA_CMD5 0x0d14
+#define DDRPHY_SHU1_CA_CMD6 0x0d18
+#define DDRPHY_SHU1_CA_CMD7 0x0d1c
+#define DDRPHY_SHU1_PLL0 0x0d80
+#define DDRPHY_SHU1_PLL1 0x0d84
+#define DDRPHY_SHU1_PLL4 0x0d90
+#define DDRPHY_SHU1_PLL5 0x0d94
+#define DDRPHY_SHU1_PLL6 0x0d98
+#define DDRPHY_SHU1_PLL7 0x0d9C
+#define DDRPHY_SHU1_PLL8 0x0da0
+#define DDRPHY_SHU1_PLL9 0x0da4
+#define DDRPHY_SHU1_PLL10 0x0da8
+#define DDRPHY_SHU1_PLL11 0x0dac
+#define DDRPHY_SHU1_R0_B0_DQ2 0x0e08
+#define DDRPHY_SHU1_R0_B0_DQ3 0x0e0c
+#define DDRPHY_SHU1_R0_B0_DQ4 0x0e10
+#define DDRPHY_SHU1_R0_B0_DQ5 0x0e14
+#define DDRPHY_SHU1_R0_B0_DQ6 0x0e18
+#define DDRPHY_SHU1_R0_B0_DQ7 0x0e1c
+#define DDRPHY_SHU1_R0_B1_DQ2 0x0e58
+#define DDRPHY_SHU1_R0_B1_DQ3 0x0e5c
+#define DDRPHY_SHU1_R0_B1_DQ4 0x0e60
+#define DDRPHY_SHU1_R0_B1_DQ5 0x0e64
+#define DDRPHY_SHU1_R0_B1_DQ6 0x0e68
+#define DDRPHY_SHU1_R0_B1_DQ7 0x0e6c
+#define DDRPHY_SHU1_R0_CA_CMD9 0x0ec4
+#define DDRPHY_SHU1_R1_B0_DQ2 0x0f08
+#define DDRPHY_SHU1_R1_B0_DQ3 0x0f0c
+#define DDRPHY_SHU1_R1_B0_DQ4 0x0f10
+#define DDRPHY_SHU1_R1_B0_DQ5 0x0f14
+#define DDRPHY_SHU1_R1_B0_DQ6 0x0f18
+#define DDRPHY_SHU1_R1_B0_DQ7 0x0f1c
+#define DDRPHY_SHU1_R1_B1_DQ2 0x0f58
+#define DDRPHY_SHU1_R1_B1_DQ3 0x0f5c
+#define DDRPHY_SHU1_R1_B1_DQ4 0x0f60
+#define DDRPHY_SHU1_R1_B1_DQ5 0x0f64
+#define DDRPHY_SHU1_R1_B1_DQ6 0x0f68
+#define DDRPHY_SHU1_R1_B1_DQ7 0x0f6c
+#define DDRPHY_SHU1_R1_CA_CMD9 0x0fc4
+
+/* DRAMC */
+#define DRAMC_DDRCONF0 0x0000
+#define DRAMC_DRAMCTRL 0x0004
+#define DRAMC_MISCTL0 0x0008
+#define DRAMC_PERFCTL0 0x000c
+#define DRAMC_ARBCTL 0x0010
+#define DRAMC_RSTMASK 0x001c
+#define DRAMC_PADCTRL 0x0020
+#define DRAMC_CKECTRL 0x0024
+#define DRAMC_RKCFG 0x0034
+#define DRAMC_DRAMC_PD_CTRL 0x0038
+#define DRAMC_CLKAR 0x003c
+#define DRAMC_CLKCTRL 0x0040
+#define DRAMC_SREFCTRL 0x0048
+#define DRAMC_REFCTRL0 0x004c
+#define DRAMC_REFCTRL1 0x0050
+#define DRAMC_REFRATRE_FILTER 0x0054
+#define DRAMC_ZQCS 0x0058
+#define DRAMC_MRS 0x005c
+#define DRAMC_SPCMD 0x0060
+#define DRAMC_SPCMDCTRL 0x0064
+#define DRAMC_HW_MRR_FUN 0x0074
+#define DRAMC_TEST2_1 0x0094
+#define DRAMC_TEST2_2 0x0098
+#define DRAMC_TEST2_3 0x009c
+#define DRAMC_TEST2_4 0x00a0
+#define DRAMC_CATRAINING1 0x00b0
+#define DRAMC_DUMMY_RD 0x00d0
+#define DRAMC_SHUCTRL 0x00d4
+#define DRAMC_SHUCTRL2 0x00dc
+#define DRAMC_STBCAL 0x0200
+#define DRAMC_STBCAL1 0x0204
+#define DRAMC_EYESCAN 0x020c
+#define DRAMC_DVFSDLL 0x0210
+#define DRAMC_SHU_ACTIM0 0x0800
+#define DRAMC_SHU_ACTIM1 0x0804
+#define DRAMC_SHU_ACTIM2 0x0808
+#define DRAMC_SHU_ACTIM3 0x080c
+#define DRAMC_SHU_ACTIM4 0x0810
+#define DRAMC_SHU_ACTIM5 0x0814
+#define DRAMC_SHU_ACTIM_XRT 0x081c
+#define DRAMC_SHU_AC_TIME_05T 0x0820
+#define DRAMC_SHU_CONF0 0x0840
+#define DRAMC_SHU_CONF1 0x0844
+#define DRAMC_SHU_CONF2 0x0848
+#define DRAMC_SHU_CONF3 0x084c
+#define DRAMC_SHU_RANKCTL 0x0858
+#define DRAMC_SHU_CKECTRL 0x085c
+#define DRAMC_SHU_ODTCTRL 0x0860
+#define DRAMC_SHU_PIPE 0x0878
+#define DRAMC_SHU_SELPH_CA1 0x0880
+#define DRAMC_SHU_SELPH_CA2 0x0884
+#define DRAMC_SHU_SELPH_CA3 0x0888
+#define DRAMC_SHU_SELPH_CA4 0x088c
+#define DRAMC_SHU_SELPH_CA5 0x0890
+#define DRAMC_SHU_SELPH_CA6 0x0894
+#define DRAMC_SHU_SELPH_CA7 0x0898
+#define DRAMC_SHU_SELPH_CA8 0x089c
+#define DRAMC_SHU_SELPH_DQS0 0x08a0
+#define DRAMC_SHU_SELPH_DQS1 0x08a4
+#define DRAMC_SHU1_DRVING1 0x08a8
+#define DRAMC_SHU1_DRVING2 0x08ac
+#define DRAMC_SHU1_WODT 0x08c0
+#define DRAMC_SHU_SCINTV 0x08c8
+#define DRAMC_SHURK0_DQSCTL 0x0a00
+#define DRAMC_SHURK0_DQSIEN 0x0a04
+#define DRAMC_SHURK0_SELPH_ODTEN0 0x0a1c
+#define DRAMC_SHURK0_SELPH_ODTEN1 0x0a20
+#define DRAMC_SHURK0_SELPH_DQSG0 0x0a24
+#define DRAMC_SHURK0_SELPH_DQSG1 0x0a28
+#define DRAMC_SHURK0_SELPH_DQ0 0x0a2c
+#define DRAMC_SHURK0_SELPH_DQ1 0x0a30
+#define DRAMC_SHURK0_SELPH_DQ2 0x0a34
+#define DRAMC_SHURK0_SELPH_DQ3 0x0a38
+#define DRAMC_SHURK1_DQSCTL 0x0b00
+#define DRAMC_SHURK1_SELPH_ODTEN0 0x0b1c
+#define DRAMC_SHURK1_SELPH_ODTEN1 0x0b20
+#define DRAMC_SHURK1_SELPH_DQSG0 0x0b24
+#define DRAMC_SHURK1_SELPH_DQSG1 0x0b28
+#define DRAMC_SHURK1_SELPH_DQ0 0x0b2c
+#define DRAMC_SHURK1_SELPH_DQ1 0x0b30
+#define DRAMC_SHURK1_SELPH_DQ2 0x0b34
+#define DRAMC_SHURK1_SELPH_DQ3 0x0b38
+#define DRAMC_SHURK2_SELPH_ODTEN0 0x0c1c
+#define DRAMC_SHURK2_SELPH_ODTEN1 0x0c20
+#define DRAMC_SHU_DQSG_RETRY 0x0c54
+
+#define EMI_COL_ADDR_MASK GENMASK(13, 12)
+#define EMI_COL_ADDR_SHIFT 12
+#define WALKING_PATTERN 0x12345678
+#define WALKING_STEP 0x4000000
+
+struct mtk_ddr3_priv {
+ fdt_addr_t emi;
+ fdt_addr_t ddrphy;
+ fdt_addr_t dramc_ao;
+ struct clk phy;
+ struct clk phy_mux;
+ struct clk mem;
+ struct clk mem_mux;
+};
+
+#ifdef CONFIG_SPL_BUILD
+static int mtk_ddr3_rank_size_detect(struct udevice *dev)
+{
+ struct mtk_ddr3_priv *priv = dev_get_priv(dev);
+ int step;
+ u32 start, test;
+
+ /* To detect size, we have to make sure it's single rank
+ * and it has maximum addressing region
+ */
+
+ writel(WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE);
+
+ if (readl(CONFIG_SYS_SDRAM_BASE) != WALKING_PATTERN)
+ return -EINVAL;
+
+ for (step = 0; step < 5; step++) {
+ writel(~WALKING_PATTERN, CONFIG_SYS_SDRAM_BASE +
+ (WALKING_STEP << step));
+
+ start = readl(CONFIG_SYS_SDRAM_BASE);
+ test = readl(CONFIG_SYS_SDRAM_BASE + (WALKING_STEP << step));
+ if ((test != ~WALKING_PATTERN) || test == start)
+ break;
+ }
+
+ step = step ? step - 1 : 3;
+ clrsetbits_le32(priv->emi + EMI_CONA, EMI_COL_ADDR_MASK,
+ step << EMI_COL_ADDR_SHIFT);
+
+ return 0;
+}
+
+static int mtk_ddr3_init(struct udevice *dev)
+{
+ struct mtk_ddr3_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = clk_set_parent(&priv->phy, &priv->phy_mux);
+ if (ret)
+ return ret;
+
+ /* EMI Setting */
+ writel(0x00003010, priv->emi + EMI_CONA);
+ writel(0x00000000, priv->emi + EMI_CONF);
+ writel(0x000006b8, priv->emi + EMI_CONM);
+ /* DQS */
+ writel(0x20c00, priv->dramc_ao + DRAMC_SHU1_DRVING1);
+ /* Clock */
+ writel(0x8320c83, priv->dramc_ao + DRAMC_SHU1_DRVING2);
+
+ /* DDRPHY setting */
+ writel(0x2201, priv->dramc_ao + DRAMC_DRAMCTRL);
+ writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL);
+ writel(0xe08, priv->ddrphy + DDRPHY_CA_CMD5);
+ writel(0x60e, priv->ddrphy + DDRPHY_SHU1_CA_CMD5);
+ writel(0x0, priv->ddrphy + DDRPHY_MISC_SPM_CTRL1);
+ writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL0);
+ writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_SPM_CTRL2);
+ writel(0x6003bf, priv->ddrphy + DDRPHY_MISC_CG_CTRL2);
+ writel(0x13300000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4);
+
+ writel(0x1, priv->ddrphy + DDRPHY_SHU1_CA_CMD7);
+ writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7);
+ writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7);
+ writel(0xfff0, priv->ddrphy + DDRPHY_CA_CMD2);
+ writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2);
+ writel(0x0, priv->ddrphy + DDRPHY_B1_DQ2);
+ writel(0x7, priv->ddrphy + DDRPHY_MISC_RXDVS1);
+ writel(0x10, priv->ddrphy + DDRPHY_PLL3);
+ writel(0x8e8e0000, priv->ddrphy + DDRPHY_MISC_VREF_CTRL);
+ writel(0x2e0040, priv->ddrphy + DDRPHY_MISC_IMP_CTRL0);
+ writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5);
+ writel(0x50060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5);
+ udelay(1);
+
+ writel(0x10, priv->ddrphy + DDRPHY_B0_DQ3);
+ writel(0x10, priv->ddrphy + DDRPHY_B1_DQ3);
+ writel(0x3f600, priv->ddrphy + DDRPHY_MISC_CG_CTRL1);
+ writel(0x1010, priv->ddrphy + DDRPHY_B0_DQ4);
+ writel(0x1110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
+ writel(0x10c10d0, priv->ddrphy + DDRPHY_B0_DQ6);
+ writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
+ writel(0x1010, priv->ddrphy + DDRPHY_B1_DQ4);
+ writel(0x1110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
+ writel(0x10c10d0, priv->ddrphy + DDRPHY_B1_DQ6);
+ writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
+ writel(0x7fffffc, priv->ddrphy + DDRPHY_CA_CMD3);
+ writel(0xc0010, priv->ddrphy + DDRPHY_CA_CMD6);
+ writel(0x101, priv->ddrphy + DDRPHY_SHU1_CA_CMD2);
+ writel(0x41e, priv->ddrphy + DDRPHY_B0_DQ3);
+ writel(0x41e, priv->ddrphy + DDRPHY_B1_DQ3);
+ writel(0x180101, priv->ddrphy + DDRPHY_CA_CMD8);
+ writel(0x0, priv->ddrphy + DDRPHY_MISC_IMP_CTRL1);
+ writel(0x11400000, priv->ddrphy + DDRPHY_MISC_CG_CTRL4);
+ writel(0xfff0f0f0, priv->ddrphy + DDRPHY_MISC_SHU_OPT);
+ writel(0x1f, priv->ddrphy + DDRPHY_MISC_CG_CTRL0);
+
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
+ writel(0x40000, priv->ddrphy + DDRPHY_PLL4);
+ writel(0x0, priv->ddrphy + DDRPHY_PLL1);
+ writel(0x0, priv->ddrphy + DDRPHY_PLL2);
+ writel(0x666008, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
+ writel(0x80666008, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
+ writel(0x80666008, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
+ writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
+ writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
+ writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
+ writel(0x400, priv->ddrphy + DDRPHY_CA_DLL_ARPI2);
+ writel(0x20400, priv->ddrphy + DDRPHY_B0_DLL_ARPI2);
+ writel(0x20400, priv->ddrphy + DDRPHY_B1_DLL_ARPI2);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL9);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_PLL11);
+ writel(0xf7f, priv->ddrphy + DDRPHY_SHU1_PLL0);
+ writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL8);
+ writel(0x40000, priv->ddrphy + DDRPHY_SHU1_PLL10);
+ writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL4);
+ writel(0xe57800fe, priv->ddrphy + DDRPHY_SHU1_PLL6);
+
+ writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL5);
+ writel(0xB5000000, priv->ddrphy + DDRPHY_SHU1_PLL7);
+
+ writel(0x14d0002, priv->ddrphy + DDRPHY_PLL5);
+ writel(0x14d0002, priv->ddrphy + DDRPHY_PLL7);
+ writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL8);
+ writel(0x80040000, priv->ddrphy + DDRPHY_SHU1_PLL10);
+ writel(0xf, priv->ddrphy + DDRPHY_SHU1_PLL1);
+ writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
+ writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
+ writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
+ writel(0x698600, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
+ writel(0xc0778600, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
+ writel(0xc0778600, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
+ writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI4);
+ writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI4);
+ writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI4);
+ writel(0x2ba800, priv->ddrphy + DDRPHY_CA_DLL_ARPI1);
+ writel(0x2ae806, priv->ddrphy + DDRPHY_B0_DLL_ARPI1);
+ writel(0xae806, priv->ddrphy + DDRPHY_B1_DLL_ARPI1);
+ writel(0xba000, priv->ddrphy + DDRPHY_CA_DLL_ARPI3);
+ writel(0x2e800, priv->ddrphy + DDRPHY_B0_DLL_ARPI3);
+ writel(0x2e800, priv->ddrphy + DDRPHY_B1_DLL_ARPI3);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_CA_CMD4);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_B0_DQ4);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_B1_DQ4);
+ writel(0x4, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
+ writel(0x1, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
+ writel(0x1, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
+ writel(0x32cf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
+ writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
+ writel(0x32cd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
+ writel(0x80010000, priv->ddrphy + DDRPHY_PLL1);
+ writel(0x80000000, priv->ddrphy + DDRPHY_PLL2);
+ udelay(100);
+
+ writel(0xc, priv->ddrphy + DDRPHY_CA_DLL_ARPI0);
+ writel(0x9, priv->ddrphy + DDRPHY_B0_DLL_ARPI0);
+ writel(0x9, priv->ddrphy + DDRPHY_B1_DLL_ARPI0);
+ writel(0xd0000, priv->ddrphy + DDRPHY_PLL4);
+ udelay(1);
+
+ writel(0x82, priv->ddrphy + DDRPHY_MISC_CTRL1);
+ writel(0x2, priv->dramc_ao + DRAMC_DDRCONF0);
+ writel(0x3acf0000, priv->ddrphy + DDRPHY_SHU1_CA_CMD6);
+ writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B0_DQ6);
+ writel(0x3acd0000, priv->ddrphy + DDRPHY_SHU1_B1_DQ6);
+ udelay(1);
+
+ writel(0x0, priv->ddrphy + DDRPHY_CA_DLL_ARPI2);
+ writel(0x0, priv->ddrphy + DDRPHY_B0_DLL_ARPI2);
+ writel(0x0, priv->ddrphy + DDRPHY_B1_DLL_ARPI2);
+ writel(0x80, priv->ddrphy + DDRPHY_MISC_CTRL1);
+ writel(0x0, priv->dramc_ao + DRAMC_DDRCONF0);
+ writel(0x80000000, priv->ddrphy + DDRPHY_PLL1);
+ udelay(1);
+
+ writel(0x698e00, priv->ddrphy + DDRPHY_CA_DLL_ARPI5);
+ udelay(1);
+
+ writel(0xc0778e00, priv->ddrphy + DDRPHY_B0_DLL_ARPI5);
+ udelay(1);
+
+ writel(0xc0778e00, priv->ddrphy + DDRPHY_B1_DLL_ARPI5);
+ udelay(1);
+
+ ret = clk_set_parent(&priv->mem, &priv->mem_mux);
+ if (ret)
+ return ret;
+
+ /* DDR PHY PLL setting */
+ writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3);
+ writel(0x51e, priv->ddrphy + DDRPHY_B1_DQ3);
+ writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1);
+ writel(0x80101, priv->ddrphy + DDRPHY_CA_CMD8);
+ writel(0x100, priv->ddrphy + DDRPHY_CA_CMD7);
+ writel(0x0, priv->ddrphy + DDRPHY_CA_CMD7);
+ writel(0x0, priv->ddrphy + DDRPHY_B0_DQ7);
+ writel(0x0, priv->ddrphy + DDRPHY_B1_DQ7);
+ writel(0x51e, priv->ddrphy + DDRPHY_B0_DQ3);
+ writel(0xff051e, priv->ddrphy + DDRPHY_B1_DQ3);
+ writel(0x0, priv->ddrphy + DDRPHY_B0_DQ2);
+ writel(0x1ff, priv->ddrphy + DDRPHY_B1_DQ2);
+
+ /* Update initial setting */
+ writel(0x5fc, priv->ddrphy + DDRPHY_B0_DQ3);
+ writel(0xff05fc, priv->ddrphy + DDRPHY_B1_DQ3);
+ writel(0x10c12d9, priv->ddrphy + DDRPHY_B0_DQ6);
+ writel(0x10c12d9, priv->ddrphy + DDRPHY_B1_DQ6);
+ writel(0xc0259, priv->ddrphy + DDRPHY_CA_CMD6);
+ writel(0x4000, priv->ddrphy + DDRPHY_B0_DQ2);
+ writel(0x41ff, priv->ddrphy + DDRPHY_B1_DQ2);
+ writel(0x0, priv->ddrphy + DDRPHY_B0_DQ8);
+ writel(0x100, priv->ddrphy + DDRPHY_B1_DQ8);
+ writel(0x3110e0e, priv->ddrphy + DDRPHY_B0_DQ5);
+ writel(0x3110e0e, priv->ddrphy + DDRPHY_B1_DQ5);
+ writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B0_DQ5);
+ writel(0x51060e, priv->ddrphy + DDRPHY_SHU1_B1_DQ5);
+ writel(0x39eff6, priv->dramc_ao + DRAMC_SHU_SCINTV);
+ writel(0x204ffff, priv->dramc_ao + DRAMC_CLKAR);
+ writel(0x31b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+ writel(0x0, priv->dramc_ao + DRAMC_PERFCTL0);
+ writel(0x80000, priv->dramc_ao + DRAMC_PERFCTL0);
+
+ /* Dramc setting PC3 */
+ writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0);
+
+ writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3);
+ writel(0x200600, priv->dramc_ao + DRAMC_SHU_DQSG_RETRY);
+ writel(0x101d007, priv->dramc_ao + DRAMC_SHUCTRL2);
+ writel(0xe090601, priv->dramc_ao + DRAMC_DVFSDLL);
+ writel(0x20003000, priv->dramc_ao + DRAMC_DDRCONF0);
+ writel(0x3900020f, priv->ddrphy + DDRPHY_MISC_CTRL0);
+ writel(0xa20810bf, priv->dramc_ao + DRAMC_SHU_CONF0);
+ writel(0x30050, priv->dramc_ao + DRAMC_SHU_ODTCTRL);
+ writel(0x25712000, priv->dramc_ao + DRAMC_REFCTRL0);
+ writel(0xb0100000, priv->dramc_ao + DRAMC_STBCAL);
+ writel(0x8000000, priv->dramc_ao + DRAMC_SREFCTRL);
+ writel(0xc0000000, priv->dramc_ao + DRAMC_SHU_PIPE);
+ writel(0x731004, priv->dramc_ao + DRAMC_RKCFG);
+ writel(0x8007320f, priv->dramc_ao + DRAMC_SHU_CONF2);
+ writel(0x2a7c0, priv->dramc_ao + DRAMC_SHU_SCINTV);
+ writel(0xc110, priv->dramc_ao + DRAMC_SHUCTRL);
+ writel(0x30000700, priv->dramc_ao + DRAMC_REFCTRL1);
+ writel(0x6543b321, priv->dramc_ao + DRAMC_REFRATRE_FILTER);
+
+ /* Update PCDDR3 default setting */
+ writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA1);
+ writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA2);
+ writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA3);
+ writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA4);
+ writel(0x10000111, priv->dramc_ao + DRAMC_SHU_SELPH_CA5);
+ writel(0x1000000, priv->dramc_ao + DRAMC_SHU_SELPH_CA6);
+ writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA7);
+ writel(0x0, priv->dramc_ao + DRAMC_SHU_SELPH_CA8);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_CA_CMD9);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_CA_CMD9);
+ writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0);
+ writel(0x33331111, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1);
+ writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0);
+ writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1);
+ writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2);
+ writel(0x33331111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3);
+ writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ0);
+ writel(0x11112222, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ1);
+ writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ2);
+ writel(0x33331111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQ3);
+ writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
+ writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ7);
+ writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
+ writel(0xf0f00, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ7);
+ writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN0);
+ writel(0x0, priv->dramc_ao + DRAMC_SHURK0_SELPH_ODTEN1);
+ writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN0);
+ writel(0x0, priv->dramc_ao + DRAMC_SHURK1_SELPH_ODTEN1);
+ writel(0x0, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN0);
+ writel(0x66666666, priv->dramc_ao + DRAMC_SHURK2_SELPH_ODTEN1);
+ writel(0x2c000b0f, priv->dramc_ao + DRAMC_SHU_CONF1);
+ writel(0x11111111, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0);
+ writel(0x64646464, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1);
+ writel(0x11111111, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG0);
+ writel(0x64646464, priv->dramc_ao + DRAMC_SHURK1_SELPH_DQSG1);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ6);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ2);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ3);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ4);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ5);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B0_DQ6);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ6);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ2);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ3);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ4);
+ writel(0xc0c0c0c, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ5);
+ writel(0x0, priv->ddrphy + DDRPHY_SHU1_R1_B1_DQ6);
+ writel(0x20000001, priv->dramc_ao + DRAMC_SHU_RANKCTL);
+ writel(0x2, priv->dramc_ao + DRAMC_SHURK0_DQSCTL);
+ writel(0x2, priv->dramc_ao + DRAMC_SHURK1_DQSCTL);
+ writel(0x4020b07, priv->dramc_ao + DRAMC_SHU_ACTIM0);
+ writel(0xb060400, priv->dramc_ao + DRAMC_SHU_ACTIM1);
+ writel(0x8090200, priv->dramc_ao + DRAMC_SHU_ACTIM2);
+ writel(0x810018, priv->dramc_ao + DRAMC_SHU_ACTIM3);
+ writel(0x1e9700ff, priv->dramc_ao + DRAMC_SHU_ACTIM4);
+ writel(0x1000908, priv->dramc_ao + DRAMC_SHU_ACTIM5);
+ writel(0x801040b, priv->dramc_ao + DRAMC_SHU_ACTIM_XRT);
+ writel(0x20000D1, priv->dramc_ao + DRAMC_SHU_AC_TIME_05T);
+ writel(0x80010000, priv->ddrphy + DDRPHY_PLL2);
+ udelay(500);
+
+ writel(0x81080000, priv->dramc_ao + DRAMC_MISCTL0);
+ writel(0xacf13, priv->dramc_ao + DRAMC_PERFCTL0);
+ writel(0xacf12, priv->dramc_ao + DRAMC_PERFCTL0);
+ writel(0x80, priv->dramc_ao + DRAMC_ARBCTL);
+ writel(0x9, priv->dramc_ao + DRAMC_PADCTRL);
+ writel(0x80000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
+ writel(0x3000000c, priv->dramc_ao + DRAMC_CLKCTRL);
+ writel(0x25714001, priv->dramc_ao + DRAMC_REFCTRL0);
+ writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+ writel(0x4300000, priv->dramc_ao + DRAMC_CATRAINING1);
+ writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
+ writel(0x731414, priv->dramc_ao + DRAMC_RKCFG);
+ writel(0x733414, priv->dramc_ao + DRAMC_RKCFG);
+ udelay(20);
+
+ writel(0x80002050, priv->dramc_ao + DRAMC_CKECTRL);
+ udelay(100);
+
+ writel(0x400000, priv->dramc_ao + DRAMC_MRS);
+ writel(0x401800, priv->dramc_ao + DRAMC_MRS);
+ writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
+ writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+ udelay(100);
+
+ writel(0x601800, priv->dramc_ao + DRAMC_MRS);
+ writel(0x600000, priv->dramc_ao + DRAMC_MRS);
+ writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
+ writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+ udelay(100);
+
+ writel(0x200000, priv->dramc_ao + DRAMC_MRS);
+ writel(0x200400, priv->dramc_ao + DRAMC_MRS);
+ writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
+ writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+ udelay(100);
+
+ writel(0x400, priv->dramc_ao + DRAMC_MRS);
+ writel(0x1d7000, priv->dramc_ao + DRAMC_MRS);
+ writel(0x1, priv->dramc_ao + DRAMC_SPCMD);
+ writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+ udelay(100);
+
+ writel(0x702201, priv->dramc_ao + DRAMC_DRAMCTRL);
+ writel(0x10, priv->dramc_ao + DRAMC_SPCMD);
+ writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+ writel(0x20, priv->dramc_ao + DRAMC_SPCMD);
+ writel(0x0, priv->dramc_ao + DRAMC_SPCMD);
+ writel(0x1, priv->dramc_ao + DRAMC_HW_MRR_FUN);
+ writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL);
+ writel(0x702301, priv->dramc_ao + DRAMC_DRAMCTRL);
+ writel(0xa56, priv->dramc_ao + DRAMC_ZQCS);
+ writel(0xff0000, priv->dramc_ao + DRAMC_SHU_CONF3);
+ writel(0x15b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+ writel(0x2cb00b0f, priv->dramc_ao + DRAMC_SHU_CONF1);
+ writel(0x65714001, priv->dramc_ao + DRAMC_REFCTRL0);
+ writel(0x48000000, priv->dramc_ao + DRAMC_SREFCTRL);
+ writel(0xc0000107, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
+ writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN);
+ writel(0x15e00, priv->dramc_ao + DRAMC_STBCAL1);
+ writel(0x100000, priv->dramc_ao + DRAMC_TEST2_1);
+ writel(0x4000, priv->dramc_ao + DRAMC_TEST2_2);
+ writel(0x12000480, priv->dramc_ao + DRAMC_TEST2_3);
+ writel(0x301d007, priv->dramc_ao + DRAMC_SHUCTRL2);
+ writel(0x4782321, priv->dramc_ao + DRAMC_DRAMCTRL);
+ writel(0x30210000, priv->dramc_ao + DRAMC_SHU_CKECTRL);
+ writel(0x20000, priv->dramc_ao + DRAMC_DUMMY_RD);
+ writel(0x4080110d, priv->dramc_ao + DRAMC_TEST2_4);
+ writel(0x30000721, priv->dramc_ao + DRAMC_REFCTRL1);
+ writel(0x0, priv->dramc_ao + DRAMC_RSTMASK);
+ writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL);
+ writel(0x80002000, priv->dramc_ao + DRAMC_CKECTRL);
+ writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0);
+
+ /* Apply config before calibration */
+ writel(0x120, priv->dramc_ao + DRAMC_DRAMC_PD_CTRL);
+ writel(0x11351131, priv->ddrphy + DDRPHY_MISC_CTRL3);
+ writel(0xffffffff, priv->ddrphy + DDRPHY_MISC_CG_CTRL0);
+ writel(0x2a7fe, priv->dramc_ao + DRAMC_SHU_SCINTV);
+ writel(0xff01ff, priv->dramc_ao + DRAMC_SHU_CONF3);
+ writel(0x4782320, priv->dramc_ao + DRAMC_DRAMCTRL);
+ writel(0xa56, priv->dramc_ao + DRAMC_ZQCS);
+ writel(0x80000000, priv->dramc_ao + DRAMC_SHU1_WODT);
+ writel(0x21, priv->ddrphy + DDRPHY_SHU1_B0_DQ7);
+ writel(0x1, priv->ddrphy + DDRPHY_SHU1_B1_DQ7);
+ writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+ writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+ writel(0x35b1f1cf, priv->dramc_ao + DRAMC_SPCMDCTRL);
+ writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
+ writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
+ writel(0x10002, priv->dramc_ao + DRAMC_EYESCAN);
+ writel(0x8100008c, priv->ddrphy + DDRPHY_MISC_CTRL1);
+ writel(0x45714001, priv->dramc_ao + DRAMC_REFCTRL0);
+ writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
+ writel(0xb0300000, priv->dramc_ao + DRAMC_STBCAL);
+
+ /* Write leveling */
+ writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
+ writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
+ writel(0x33221100, priv->dramc_ao + DRAMC_SHU_SELPH_DQS1);
+ writel(0x11112222, priv->dramc_ao + DRAMC_SHU_SELPH_DQS0);
+
+ /* RX dqs gating cal */
+ writel(0x11111010, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG0);
+ writel(0x20201717, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQSG1);
+ writel(0x1d1f, priv->dramc_ao + DRAMC_SHURK0_DQSIEN);
+
+ /* RX window per-bit cal */
+ writel(0x03030404, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ2);
+ writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ3);
+ writel(0x01010303, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ4);
+ writel(0x01010000, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ5);
+ writel(0x03030606, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ2);
+ writel(0x02020202, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ3);
+ writel(0x04040303, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ4);
+ writel(0x06060101, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ5);
+
+ /* RX datlat cal */
+ writel(0x28b00a0e, priv->dramc_ao + DRAMC_SHU_CONF1);
+
+ /* TX window per-byte with 2UI cal */
+ writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ0);
+ writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ2);
+ writel(0x11112222, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ1);
+ writel(0x22220000, priv->dramc_ao + DRAMC_SHURK0_SELPH_DQ3);
+ writel(0x1f2e2e00, priv->ddrphy + DDRPHY_SHU1_R0_B0_DQ7);
+ writel(0x202f2f00, priv->ddrphy + DDRPHY_SHU1_R0_B1_DQ7);
+
+ return mtk_ddr3_rank_size_detect(dev);
+}
+#endif
+
+static int mtk_ddr3_probe(struct udevice *dev)
+{
+ struct mtk_ddr3_priv *priv = dev_get_priv(dev);
+
+ priv->emi = dev_read_addr_index(dev, 0);
+ if (priv->emi == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->ddrphy = dev_read_addr_index(dev, 1);
+ if (priv->ddrphy == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->dramc_ao = dev_read_addr_index(dev, 2);
+ if (priv->dramc_ao == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+#ifdef CONFIG_SPL_BUILD
+ int ret;
+
+ ret = clk_get_by_index(dev, 0, &priv->phy);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_index(dev, 1, &priv->phy_mux);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_index(dev, 2, &priv->mem);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_index(dev, 3, &priv->mem_mux);
+ if (ret)
+ return ret;
+
+ ret = mtk_ddr3_init(dev);
+ if (ret)
+ return ret;
+#endif
+ return 0;
+}
+
+static int mtk_ddr3_get_info(struct udevice *dev, struct ram_info *info)
+{
+ struct mtk_ddr3_priv *priv = dev_get_priv(dev);
+ u32 val = readl(priv->emi + EMI_CONA);
+
+ info->base = CONFIG_SYS_SDRAM_BASE;
+
+ switch ((val & EMI_COL_ADDR_MASK) >> EMI_COL_ADDR_SHIFT) {
+ case 0:
+ info->size = SZ_128M;
+ break;
+ case 1:
+ info->size = SZ_256M;
+ break;
+ case 2:
+ info->size = SZ_512M;
+ break;
+ case 3:
+ info->size = SZ_1G;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct ram_ops mtk_ddr3_ops = {
+ .get_info = mtk_ddr3_get_info,
+};
+
+static const struct udevice_id mtk_ddr3_ids[] = {
+ { .compatible = "mediatek,mt7629-dramc" },
+ { }
+};
+
+U_BOOT_DRIVER(mediatek_ddr3) = {
+ .name = "mediatek_ddr3",
+ .id = UCLASS_RAM,
+ .of_match = mtk_ddr3_ids,
+ .ops = &mtk_ddr3_ops,
+ .probe = mtk_ddr3_probe,
+ .priv_auto_alloc_size = sizeof(struct mtk_ddr3_priv),
+};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 6625a65..3bcc61e 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -368,6 +368,16 @@ config DEBUG_UART_OMAP
You will need to provide parameters to make this work. The driver
will be available until the real driver model serial is running.
+config DEBUG_UART_MTK
+ bool "MediaTek High-speed UART"
+ depends on MTK_SERIAL
+ help
+ Select this to enable a debug UART using the MediaTek High-speed
+ UART driver.
+ You will need to provide parameters to make this work. The
+ driver will be available until the real driver model serial is
+ running.
+
endchoice
config DEBUG_UART_BASE
@@ -698,6 +708,16 @@ config ZYNQ_SERIAL
This driver supports the Cadence UART. It is found e.g. in Xilinx
Zynq/ZynqMP.
+config MTK_SERIAL
+ bool "MediaTek High-speed UART support"
+ depends on DM_SERIAL
+ help
+ Select this to enable UART support for MediaTek High-speed UART
+ devices. This driver uses driver model and requires a device
+ tree binding to operate.
+ The High-speed UART is compatible with the ns16550a UART and have
+ its own high-speed registers.
+
config MPC8XX_CONS
bool "Console driver for MPC8XX"
depends on MPC8xx
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index a48458f..b6377b1 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_MPC8XX_CONS) += serial_mpc8xx.o
obj-$(CONFIG_NULLDEV_SERIAL) += serial_nulldev.o
obj-$(CONFIG_OWL_SERIAL) += serial_owl.o
obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
+obj-$(CONFIG_MTK_SERIAL) += serial_mtk.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c
new file mode 100644
index 0000000..bce1be8
--- /dev/null
+++ b/drivers/serial/serial_mtk.c
@@ -0,0 +1,268 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek High-speed UART driver
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <div64.h>
+#include <dm.h>
+#include <errno.h>
+#include <serial.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <asm/types.h>
+
+struct mtk_serial_regs {
+ u32 rbr;
+ u32 ier;
+ u32 fcr;
+ u32 lcr;
+ u32 mcr;
+ u32 lsr;
+ u32 msr;
+ u32 spr;
+ u32 mdr1;
+ u32 highspeed;
+ u32 sample_count;
+ u32 sample_point;
+ u32 fracdiv_l;
+ u32 fracdiv_m;
+ u32 escape_en;
+ u32 guard;
+ u32 rx_sel;
+};
+
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+#define UART_LCR_WLS_8 0x03 /* 8 bit character length */
+#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */
+
+#define UART_LSR_DR 0x01 /* Data ready */
+#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
+
+/* the data is correct if the real baud is within 3%. */
+#define BAUD_ALLOW_MAX(baud) ((baud) + (baud) * 3 / 100)
+#define BAUD_ALLOW_MIX(baud) ((baud) - (baud) * 3 / 100)
+
+struct mtk_serial_priv {
+ struct mtk_serial_regs __iomem *regs;
+ u32 clock;
+};
+
+static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud)
+{
+ bool support_clk12m_baud115200;
+ u32 quot, samplecount, realbaud;
+
+ if ((baud <= 115200) && (priv->clock == 12000000))
+ support_clk12m_baud115200 = true;
+ else
+ support_clk12m_baud115200 = false;
+
+ if (baud <= 115200) {
+ writel(0, &priv->regs->highspeed);
+ quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud);
+
+ if (support_clk12m_baud115200) {
+ writel(3, &priv->regs->highspeed);
+ quot = DIV_ROUND_CLOSEST(priv->clock, 256 * baud);
+ if (quot == 0)
+ quot = 1;
+
+ samplecount = DIV_ROUND_CLOSEST(priv->clock,
+ quot * baud);
+ if (samplecount != 0) {
+ realbaud = priv->clock / samplecount / quot;
+ if ((realbaud > BAUD_ALLOW_MAX(baud)) ||
+ (realbaud < BAUD_ALLOW_MIX(baud))) {
+ pr_info("baud %d can't be handled\n",
+ baud);
+ }
+ } else {
+ pr_info("samplecount is 0\n");
+ }
+ }
+ } else if (baud <= 576000) {
+ writel(2, &priv->regs->highspeed);
+
+ /* Set to next lower baudrate supported */
+ if ((baud == 500000) || (baud == 576000))
+ baud = 460800;
+ quot = DIV_ROUND_UP(priv->clock, 4 * baud);
+ } else {
+ writel(3, &priv->regs->highspeed);
+ quot = DIV_ROUND_UP(priv->clock, 256 * baud);
+ }
+
+ /* set divisor */
+ writel(UART_LCR_WLS_8 | UART_LCR_DLAB, &priv->regs->lcr);
+ writel(quot & 0xff, &priv->regs->dll);
+ writel((quot >> 8) & 0xff, &priv->regs->dlm);
+ writel(UART_LCR_WLS_8, &priv->regs->lcr);
+
+ if (baud > 460800) {
+ u32 tmp;
+
+ tmp = DIV_ROUND_CLOSEST(priv->clock, quot * baud);
+ writel(tmp - 1, &priv->regs->sample_count);
+ writel((tmp - 2) >> 1, &priv->regs->sample_point);
+ } else {
+ writel(0, &priv->regs->sample_count);
+ writel(0xff, &priv->regs->sample_point);
+ }
+
+ if (support_clk12m_baud115200) {
+ writel(samplecount - 1, &priv->regs->sample_count);
+ writel((samplecount - 2) >> 1, &priv->regs->sample_point);
+ }
+}
+
+static int mtk_serial_setbrg(struct udevice *dev, int baudrate)
+{
+ struct mtk_serial_priv *priv = dev_get_priv(dev);
+
+ _mtk_serial_setbrg(priv, baudrate);
+
+ return 0;
+}
+
+static int mtk_serial_putc(struct udevice *dev, const char ch)
+{
+ struct mtk_serial_priv *priv = dev_get_priv(dev);
+
+ if (!(readl(&priv->regs->lsr) & UART_LSR_THRE))
+ return -EAGAIN;
+
+ writel(ch, &priv->regs->thr);
+
+ if (ch == '\n')
+ WATCHDOG_RESET();
+
+ return 0;
+}
+
+static int mtk_serial_getc(struct udevice *dev)
+{
+ struct mtk_serial_priv *priv = dev_get_priv(dev);
+
+ if (!(readl(&priv->regs->lsr) & UART_LSR_DR))
+ return -EAGAIN;
+
+ return readl(&priv->regs->rbr);
+}
+
+static int mtk_serial_pending(struct udevice *dev, bool input)
+{
+ struct mtk_serial_priv *priv = dev_get_priv(dev);
+
+ if (input)
+ return (readl(&priv->regs->lsr) & UART_LSR_DR) ? 1 : 0;
+ else
+ return (readl(&priv->regs->lsr) & UART_LSR_THRE) ? 0 : 1;
+}
+
+static int mtk_serial_probe(struct udevice *dev)
+{
+ struct mtk_serial_priv *priv = dev_get_priv(dev);
+
+ /* Disable interrupt */
+ writel(0, &priv->regs->ier);
+
+ return 0;
+}
+
+static int mtk_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct mtk_serial_priv *priv = dev_get_priv(dev);
+ fdt_addr_t addr;
+ struct clk clk;
+ int err;
+
+ addr = dev_read_addr(dev);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ priv->regs = map_physmem(addr, 0, MAP_NOCACHE);
+
+ err = clk_get_by_index(dev, 0, &clk);
+ if (!err) {
+ err = clk_get_rate(&clk);
+ if (!IS_ERR_VALUE(err))
+ priv->clock = err;
+ } else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) {
+ debug("mtk_serial: failed to get clock\n");
+ return err;
+ }
+
+ if (!priv->clock)
+ priv->clock = dev_read_u32_default(dev, "clock-frequency", 0);
+
+ if (!priv->clock) {
+ debug("mtk_serial: clock not defined\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct dm_serial_ops mtk_serial_ops = {
+ .putc = mtk_serial_putc,
+ .pending = mtk_serial_pending,
+ .getc = mtk_serial_getc,
+ .setbrg = mtk_serial_setbrg,
+};
+
+static const struct udevice_id mtk_serial_ids[] = {
+ { .compatible = "mediatek,hsuart" },
+ { .compatible = "mediatek,mt6577-uart" },
+ { }
+};
+
+U_BOOT_DRIVER(serial_mtk) = {
+ .name = "serial_mtk",
+ .id = UCLASS_SERIAL,
+ .of_match = mtk_serial_ids,
+ .ofdata_to_platdata = mtk_serial_ofdata_to_platdata,
+ .priv_auto_alloc_size = sizeof(struct mtk_serial_priv),
+ .probe = mtk_serial_probe,
+ .ops = &mtk_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+#ifdef CONFIG_DEBUG_UART_MTK
+
+#include <debug_uart.h>
+
+static inline void _debug_uart_init(void)
+{
+ struct mtk_serial_priv priv;
+
+ priv.regs = (void *) CONFIG_DEBUG_UART_BASE;
+ priv.clock = CONFIG_DEBUG_UART_CLOCK;
+
+ writel(0, &priv.regs->ier);
+
+ _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE);
+}
+
+static inline void _debug_uart_putc(int ch)
+{
+ struct mtk_serial_regs __iomem *regs =
+ (void *) CONFIG_DEBUG_UART_BASE;
+
+ while (!(readl(&regs->lsr) & UART_LSR_THRE))
+ ;
+
+ writel(ch, &regs->thr);
+}
+
+DEBUG_UART_FUNCS
+
+#endif \ No newline at end of file
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index d0cfc35..b0e6f32 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -160,4 +160,11 @@ config X86_TSC_TIMER
help
Select this to enable Time-Stamp Counter (TSC) timer for x86.
+config MTK_TIMER
+ bool "MediaTek timer support"
+ depends on TIMER
+ help
+ Select this to enable support for the timer found on
+ MediaTek devices.
+
endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index 7f19c49..c4fbab2 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_SANDBOX_TIMER) += sandbox_timer.o
obj-$(CONFIG_STI_TIMER) += sti-timer.o
obj-$(CONFIG_STM32_TIMER) += stm32_timer.o
obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o
+obj-$(CONFIG_MTK_TIMER) += mtk_timer.o
diff --git a/drivers/timer/mtk_timer.c b/drivers/timer/mtk_timer.c
new file mode 100644
index 0000000..b5e76bd
--- /dev/null
+++ b/drivers/timer/mtk_timer.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek timer driver
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <timer.h>
+#include <asm/io.h>
+
+#define MTK_GPT4_CTRL 0x40
+#define MTK_GPT4_CLK 0x44
+#define MTK_GPT4_CNT 0x48
+
+#define GPT4_ENABLE BIT(0)
+#define GPT4_CLEAR BIT(1)
+#define GPT4_FREERUN GENMASK(5, 4)
+#define GPT4_CLK_SYS 0x0
+#define GPT4_CLK_DIV1 0x0
+
+struct mtk_timer_priv {
+ void __iomem *base;
+};
+
+static int mtk_timer_get_count(struct udevice *dev, u64 *count)
+{
+ struct mtk_timer_priv *priv = dev_get_priv(dev);
+ u32 val = readl(priv->base + MTK_GPT4_CNT);
+
+ *count = timer_conv_64(val);
+
+ return 0;
+}
+
+static int mtk_timer_probe(struct udevice *dev)
+{
+ struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct mtk_timer_priv *priv = dev_get_priv(dev);
+ struct clk clk, parent;
+ int ret;
+
+ priv->base = dev_read_addr_ptr(dev);
+ if (!priv->base)
+ return -ENOENT;
+
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret)
+ return ret;
+
+ ret = clk_get_by_index(dev, 1, &parent);
+ if (!ret) {
+ ret = clk_set_parent(&clk, &parent);
+ if (ret)
+ return ret;
+ }
+
+ uc_priv->clock_rate = clk_get_rate(&clk);
+ if (!uc_priv->clock_rate)
+ return -EINVAL;
+
+ return 0;
+}
+
+static const struct timer_ops mtk_timer_ops = {
+ .get_count = mtk_timer_get_count,
+};
+
+static const struct udevice_id mtk_timer_ids[] = {
+ { .compatible = "mediatek,timer" },
+ { }
+};
+
+U_BOOT_DRIVER(mtk_timer) = {
+ .name = "mtk_timer",
+ .id = UCLASS_TIMER,
+ .of_match = mtk_timer_ids,
+ .priv_auto_alloc_size = sizeof(struct mtk_timer_priv),
+ .probe = mtk_timer_probe,
+ .ops = &mtk_timer_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 4796da0..4a9ebb6 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -103,6 +103,14 @@ config WDT_CDNS
Select this to enable Cadence watchdog timer, which can be found on some
Xilinx Microzed Platform.
+config WDT_MTK
+ bool "MediaTek watchdog timer support"
+ depends on WDT && ARCH_MEDIATEK
+ help
+ Select this to enable watchdog timer for MediaTek SoCs.
+ The watchdog timer is stopped when initialized.
+ It performs full SoC reset.
+
config XILINX_TB_WATCHDOG
bool "Xilinx Axi watchdog timer support"
depends on WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index b8f2842..74738ee 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -24,3 +24,4 @@ obj-$(CONFIG_WDT_ORION) += orion_wdt.o
obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
obj-$(CONFIG_MPC8xx_WATCHDOG) += mpc8xx_wdt.o
obj-$(CONFIG_WDT_MT7621) += mt7621_wdt.o
+obj-$(CONFIG_WDT_MTK) += mtk_wdt.o
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
new file mode 100644
index 0000000..0b50173
--- /dev/null
+++ b/drivers/watchdog/mtk_wdt.c
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Watchdog driver for MediaTek SoCs
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <wdt.h>
+#include <asm/io.h>
+
+#define MTK_WDT_MODE 0x00
+#define MTK_WDT_LENGTH 0x04
+#define MTK_WDT_RESTART 0x08
+#define MTK_WDT_STATUS 0x0c
+#define MTK_WDT_INTERVAL 0x10
+#define MTK_WDT_SWRST 0x14
+#define MTK_WDT_REQ_MODE 0x30
+#define MTK_WDT_DEBUG_CTL 0x40
+
+#define WDT_MODE_KEY (0x22 << 24)
+#define WDT_MODE_EN BIT(0)
+#define WDT_MODE_EXTPOL BIT(1)
+#define WDT_MODE_EXTEN BIT(2)
+#define WDT_MODE_IRQ_EN BIT(3)
+#define WDT_MODE_DUAL_EN BIT(6)
+
+#define WDT_LENGTH_KEY 0x8
+#define WDT_LENGTH_TIMEOUT(n) ((n) << 5)
+
+#define WDT_RESTART_KEY 0x1971
+#define WDT_SWRST_KEY 0x1209
+
+struct mtk_wdt_priv {
+ void __iomem *base;
+};
+
+static int mtk_wdt_reset(struct udevice *dev)
+{
+ struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+ /* Reload watchdog duration */
+ writel(WDT_RESTART_KEY, priv->base + MTK_WDT_RESTART);
+
+ return 0;
+}
+
+static int mtk_wdt_stop(struct udevice *dev)
+{
+ struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+ clrsetbits_le32(priv->base + MTK_WDT_MODE, WDT_MODE_EN, WDT_MODE_KEY);
+
+ return 0;
+}
+
+static int mtk_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+ struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+ /* Kick watchdog to prevent counter == 0 */
+ writel(WDT_RESTART_KEY, priv->base + MTK_WDT_RESTART);
+
+ /* Reset */
+ writel(WDT_SWRST_KEY, priv->base + MTK_WDT_SWRST);
+ hang();
+
+ return 0;
+}
+
+static void mtk_wdt_set_timeout(struct udevice *dev, unsigned int timeout)
+{
+ struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+ /*
+ * One bit is the value of 512 ticks
+ * The clock has 32 KHz
+ */
+ timeout = WDT_LENGTH_TIMEOUT(timeout << 6) | WDT_LENGTH_KEY;
+ writel(timeout, priv->base + MTK_WDT_LENGTH);
+
+ mtk_wdt_reset(dev);
+}
+
+static int mtk_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+ struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+ mtk_wdt_set_timeout(dev, timeout);
+
+ /* Enable watchdog reset signal */
+ setbits_le32(priv->base + MTK_WDT_MODE,
+ WDT_MODE_EN | WDT_MODE_KEY | WDT_MODE_EXTEN);
+
+ return 0;
+}
+
+static int mtk_wdt_probe(struct udevice *dev)
+{
+ struct mtk_wdt_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_read_addr_ptr(dev);
+ if (!priv->base)
+ return -ENOENT;
+
+ /* Clear status */
+ clrsetbits_le32(priv->base + MTK_WDT_MODE,
+ WDT_MODE_IRQ_EN | WDT_MODE_EXTPOL, WDT_MODE_KEY);
+
+ return mtk_wdt_stop(dev);
+}
+
+static const struct wdt_ops mtk_wdt_ops = {
+ .start = mtk_wdt_start,
+ .reset = mtk_wdt_reset,
+ .stop = mtk_wdt_stop,
+ .expire_now = mtk_wdt_expire_now,
+};
+
+static const struct udevice_id mtk_wdt_ids[] = {
+ { .compatible = "mediatek,wdt"},
+ {}
+};
+
+U_BOOT_DRIVER(mtk_wdt) = {
+ .name = "mtk_wdt",
+ .id = UCLASS_WDT,
+ .of_match = mtk_wdt_ids,
+ .priv_auto_alloc_size = sizeof(struct mtk_wdt_priv),
+ .probe = mtk_wdt_probe,
+ .ops = &mtk_wdt_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/include/configs/khadas-vim.h b/include/configs/khadas-vim.h
deleted file mode 100644
index 6615f77..0000000
--- a/include/configs/khadas-vim.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Khadas VIM
- *
- * Copyright (C) 2017 Baylibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-khadas-vim.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/khadas-vim2.h b/include/configs/khadas-vim2.h
deleted file mode 100644
index 7ef8f42..0000000
--- a/include/configs/khadas-vim2.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Khadas VIM2
- *
- * Copyright (C) 2017 Baylibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-#define CONFIG_MISC_INIT_R
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxm-khadas-vim2.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/libretech-cc.h b/include/configs/libretech-cc.h
deleted file mode 100644
index a0856f9..0000000
--- a/include/configs/libretech-cc.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for LibreTech CC
- *
- * Copyright (C) 2017 Baylibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-libretech-cc.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/meson-gx-common.h b/include/configs/meson64.h
index c46522e..40ac079 100644
--- a/include/configs/meson-gx-common.h
+++ b/include/configs/meson64.h
@@ -1,11 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
- * Configuration for Amlogic Meson GX SoCs
+ * Configuration for Amlogic Meson 64bits SoCs
* (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
*/
-#ifndef __MESON_GX_COMMON_CONFIG_H
-#define __MESON_GX_COMMON_CONFIG_H
+#ifndef __MESON64_CONFIG_H
+#define __MESON64_CONFIG_H
+
+/* Generic Interrupt Controller Definitions */
+#if defined(CONFIG_MESON_AXG)
+#define GICD_BASE 0xffc01000
+#define GICC_BASE 0xffc02000
+#else /* MESON GXL and GXBB */
+#define GICD_BASE 0xc4301000
+#define GICC_BASE 0xc4302000
+#endif
#define CONFIG_CPU_ARMV8
#define CONFIG_REMAKE_ELF
@@ -17,10 +26,19 @@
#define CONFIG_SYS_SDRAM_BASE 0
#define CONFIG_SYS_INIT_SP_ADDR 0x20000000
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* 64 MiB */
-/* Generic Interrupt Controller Definitions */
-#define GICD_BASE 0xc4301000
-#define GICC_BASE 0xc4302000
+/* ROM USB boot support, auto-execute boot.scr at scriptaddr */
+#define BOOTENV_DEV_ROMUSB(devtypeu, devtypel, instance) \
+ "bootcmd_romusb=" \
+ "if test \"${boot_source}\" = \"usb\" && " \
+ "test -n \"${scriptaddr}\"; then " \
+ "echo '(ROM USB boot)'; " \
+ "source ${scriptaddr}; " \
+ "fi\0"
+
+#define BOOTENV_DEV_NAME_ROMUSB(devtypeu, devtypel, instance) \
+ "romusb "
#ifdef CONFIG_CMD_USB
#define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0)
@@ -28,25 +46,28 @@
#define BOOT_TARGET_DEVICES_USB(func)
#endif
+#ifndef BOOT_TARGET_DEVICES
#define BOOT_TARGET_DEVICES(func) \
+ func(ROMUSB, romusb, na) \
func(MMC, mmc, 0) \
func(MMC, mmc, 1) \
func(MMC, mmc, 2) \
BOOT_TARGET_DEVICES_USB(func) \
func(PXE, pxe, na) \
func(DHCP, dhcp, na)
+#endif
-#include <config_distro_bootcmd.h>
-
+#ifndef CONFIG_EXTRA_ENV_SETTINGS
#define CONFIG_EXTRA_ENV_SETTINGS \
- "fdt_addr_r=0x01000000\0" \
- "scriptaddr=0x1f000000\0" \
- "kernel_addr_r=0x01080000\0" \
+ "fdt_addr_r=0x08008000\0" \
+ "scriptaddr=0x08000000\0" \
+ "kernel_addr_r=0x08080000\0" \
"pxefile_addr_r=0x01080000\0" \
"ramdisk_addr_r=0x13000000\0" \
- MESON_FDTFILE_SETTING \
+ "fdtfile=amlogic/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
BOOTENV
+#endif
-#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* 64 MiB */
+#include <config_distro_bootcmd.h>
-#endif /* __MESON_GX_COMMON_CONFIG_H */
+#endif /* __MESON64_CONFIG_H */
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
new file mode 100644
index 0000000..68da920
--- /dev/null
+++ b/include/configs/mt7623.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for MediaTek MT7623 SoC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef __MT7623_H
+#define __MT7623_H
+
+#include <linux/sizes.h>
+
+/* Miscellaneous configurable options */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG
+
+#define CONFIG_SYS_MAXARGS 8
+#define CONFIG_SYS_BOOTM_LEN SZ_64M
+#define CONFIG_SYS_CBSIZE SZ_1K
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN SZ_4M
+
+/* Environment */
+#define CONFIG_ENV_SIZE SZ_4K
+/* Allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+/* Preloader -> Uboot */
+#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_2M - \
+ GENERATED_GBL_DATA_SIZE)
+
+/* UBoot -> Kernel */
+#define CONFIG_LOADADDR 0x84000000
+#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+
+/* MMC */
+#define MMC_SUPPORTS_TUNING
+#define CONFIG_SUPPORT_EMMC_BOOT
+
+/* DRAM */
+#define CONFIG_SYS_SDRAM_BASE 0x80000000
+
+/* This is neede for kernel booting */
+#define FDT_HIGH "fdt_high=0xac000000\0"
+
+/* Extra environment variables */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ FDT_HIGH
+
+#endif
diff --git a/include/configs/mt7629.h b/include/configs/mt7629.h
new file mode 100644
index 0000000..a665a5e
--- /dev/null
+++ b/include/configs/mt7629.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Configuration for MediaTek MT7629 SoC
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#ifndef __MT7629_H
+#define __MT7629_H
+
+#include <linux/sizes.h>
+
+/* Miscellaneous configurable options */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG
+
+#define CONFIG_SYS_MAXARGS 8
+#define CONFIG_SYS_BOOTM_LEN SZ_64M
+#define CONFIG_SYS_CBSIZE SZ_1K
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN SZ_4M
+
+/* Environment */
+#define CONFIG_ENV_SIZE SZ_4K
+/* Allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+/* Defines for SPL */
+#define CONFIG_SPL_STACK 0x106000
+#define CONFIG_SPL_TEXT_BASE 0x201000
+#define CONFIG_SPL_MAX_SIZE SZ_64K
+#define CONFIG_SPL_MAX_FOOTPRINT SZ_64K
+#define CONFIG_SPL_PAD_TO 0x10000
+
+#define CONFIG_SPI_ADDR 0x30000000
+#define CONFIG_SYS_SPI_U_BOOT_OFFS CONFIG_SPL_PAD_TO
+#define CONFIG_SYS_UBOOT_BASE (CONFIG_SPI_ADDR + CONFIG_SPL_PAD_TO)
+
+/* SPL -> Uboot */
+#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_2M - \
+ GENERATED_GBL_DATA_SIZE)
+
+/* UBoot -> Kernel */
+#define CONFIG_SYS_SPL_ARGS_ADDR 0x40000000
+#define CONFIG_LOADADDR 0x42007f1c
+#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+
+/* DRAM */
+#define CONFIG_SYS_SDRAM_BASE 0x40000000
+
+#endif
diff --git a/include/configs/nanopi-k2.h b/include/configs/nanopi-k2.h
deleted file mode 100644
index ef53f20..0000000
--- a/include/configs/nanopi-k2.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for NANOPI-K2
- * (C) Copyright 2018 Thomas McKahan
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/* Serial setup */
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxbb-nanopi-k2.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/odroid-c2.h b/include/configs/odroid-c2.h
deleted file mode 100644
index d117b18..0000000
--- a/include/configs/odroid-c2.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for ODROID-C2
- * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/* Serial setup */
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxbb-odroidc2.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/configs/p212.h b/include/configs/p212.h
deleted file mode 100644
index 2aa9f5d..0000000
--- a/include/configs/p212.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Amlogic P212
- *
- * Copyright (C) 2017 Baylibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
-
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/* Serial setup */
-
-#define MESON_FDTFILE_SETTING "fdtfile=amlogic/meson-gxl-s905x-p212.dtb\0"
-
-#include <configs/meson-gx-common.h>
-
-#endif /* __CONFIG_H */
diff --git a/include/dt-bindings/clock/axg-aoclkc.h b/include/dt-bindings/clock/axg-aoclkc.h
new file mode 100644
index 0000000..6195501
--- /dev/null
+++ b/include/dt-bindings/clock/axg-aoclkc.h
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright (c) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Copyright (c) 2018 Amlogic, inc.
+ * Author: Qiufang Dai <qiufang.dai@amlogic.com>
+ */
+
+#ifndef DT_BINDINGS_CLOCK_AMLOGIC_MESON_AXG_AOCLK
+#define DT_BINDINGS_CLOCK_AMLOGIC_MESON_AXG_AOCLK
+
+#define CLKID_AO_REMOTE 0
+#define CLKID_AO_I2C_MASTER 1
+#define CLKID_AO_I2C_SLAVE 2
+#define CLKID_AO_UART1 3
+#define CLKID_AO_UART2 4
+#define CLKID_AO_IR_BLASTER 5
+#define CLKID_AO_SAR_ADC 6
+#define CLKID_AO_CLK81 7
+#define CLKID_AO_SAR_ADC_SEL 8
+#define CLKID_AO_SAR_ADC_DIV 9
+#define CLKID_AO_SAR_ADC_CLK 10
+#define CLKID_AO_ALT_XTAL 11
+
+#endif
diff --git a/include/dt-bindings/clock/axg-audio-clkc.h b/include/dt-bindings/clock/axg-audio-clkc.h
new file mode 100644
index 0000000..fd9c362
--- /dev/null
+++ b/include/dt-bindings/clock/axg-audio-clkc.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+/*
+ * Copyright (c) 2018 Baylibre SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef __AXG_AUDIO_CLKC_BINDINGS_H
+#define __AXG_AUDIO_CLKC_BINDINGS_H
+
+#define AUD_CLKID_SLV_SCLK0 9
+#define AUD_CLKID_SLV_SCLK1 10
+#define AUD_CLKID_SLV_SCLK2 11
+#define AUD_CLKID_SLV_SCLK3 12
+#define AUD_CLKID_SLV_SCLK4 13
+#define AUD_CLKID_SLV_SCLK5 14
+#define AUD_CLKID_SLV_SCLK6 15
+#define AUD_CLKID_SLV_SCLK7 16
+#define AUD_CLKID_SLV_SCLK8 17
+#define AUD_CLKID_SLV_SCLK9 18
+#define AUD_CLKID_SLV_LRCLK0 19
+#define AUD_CLKID_SLV_LRCLK1 20
+#define AUD_CLKID_SLV_LRCLK2 21
+#define AUD_CLKID_SLV_LRCLK3 22
+#define AUD_CLKID_SLV_LRCLK4 23
+#define AUD_CLKID_SLV_LRCLK5 24
+#define AUD_CLKID_SLV_LRCLK6 25
+#define AUD_CLKID_SLV_LRCLK7 26
+#define AUD_CLKID_SLV_LRCLK8 27
+#define AUD_CLKID_SLV_LRCLK9 28
+#define AUD_CLKID_DDR_ARB 29
+#define AUD_CLKID_PDM 30
+#define AUD_CLKID_TDMIN_A 31
+#define AUD_CLKID_TDMIN_B 32
+#define AUD_CLKID_TDMIN_C 33
+#define AUD_CLKID_TDMIN_LB 34
+#define AUD_CLKID_TDMOUT_A 35
+#define AUD_CLKID_TDMOUT_B 36
+#define AUD_CLKID_TDMOUT_C 37
+#define AUD_CLKID_FRDDR_A 38
+#define AUD_CLKID_FRDDR_B 39
+#define AUD_CLKID_FRDDR_C 40
+#define AUD_CLKID_TODDR_A 41
+#define AUD_CLKID_TODDR_B 42
+#define AUD_CLKID_TODDR_C 43
+#define AUD_CLKID_LOOPBACK 44
+#define AUD_CLKID_SPDIFIN 45
+#define AUD_CLKID_SPDIFOUT 46
+#define AUD_CLKID_RESAMPLE 47
+#define AUD_CLKID_POWER_DETECT 48
+#define AUD_CLKID_MST_A_MCLK 49
+#define AUD_CLKID_MST_B_MCLK 50
+#define AUD_CLKID_MST_C_MCLK 51
+#define AUD_CLKID_MST_D_MCLK 52
+#define AUD_CLKID_MST_E_MCLK 53
+#define AUD_CLKID_MST_F_MCLK 54
+#define AUD_CLKID_SPDIFOUT_CLK 55
+#define AUD_CLKID_SPDIFIN_CLK 56
+#define AUD_CLKID_PDM_DCLK 57
+#define AUD_CLKID_PDM_SYSCLK 58
+#define AUD_CLKID_MST_A_SCLK 79
+#define AUD_CLKID_MST_B_SCLK 80
+#define AUD_CLKID_MST_C_SCLK 81
+#define AUD_CLKID_MST_D_SCLK 82
+#define AUD_CLKID_MST_E_SCLK 83
+#define AUD_CLKID_MST_F_SCLK 84
+#define AUD_CLKID_MST_A_LRCLK 86
+#define AUD_CLKID_MST_B_LRCLK 87
+#define AUD_CLKID_MST_C_LRCLK 88
+#define AUD_CLKID_MST_D_LRCLK 89
+#define AUD_CLKID_MST_E_LRCLK 90
+#define AUD_CLKID_MST_F_LRCLK 91
+#define AUD_CLKID_TDMIN_A_SCLK_SEL 116
+#define AUD_CLKID_TDMIN_B_SCLK_SEL 117
+#define AUD_CLKID_TDMIN_C_SCLK_SEL 118
+#define AUD_CLKID_TDMIN_LB_SCLK_SEL 119
+#define AUD_CLKID_TDMOUT_A_SCLK_SEL 120
+#define AUD_CLKID_TDMOUT_B_SCLK_SEL 121
+#define AUD_CLKID_TDMOUT_C_SCLK_SEL 122
+#define AUD_CLKID_TDMIN_A_SCLK 123
+#define AUD_CLKID_TDMIN_B_SCLK 124
+#define AUD_CLKID_TDMIN_C_SCLK 125
+#define AUD_CLKID_TDMIN_LB_SCLK 126
+#define AUD_CLKID_TDMOUT_A_SCLK 127
+#define AUD_CLKID_TDMOUT_B_SCLK 128
+#define AUD_CLKID_TDMOUT_C_SCLK 129
+#define AUD_CLKID_TDMIN_A_LRCLK 130
+#define AUD_CLKID_TDMIN_B_LRCLK 131
+#define AUD_CLKID_TDMIN_C_LRCLK 132
+#define AUD_CLKID_TDMIN_LB_LRCLK 133
+#define AUD_CLKID_TDMOUT_A_LRCLK 134
+#define AUD_CLKID_TDMOUT_B_LRCLK 135
+#define AUD_CLKID_TDMOUT_C_LRCLK 136
+
+#endif /* __AXG_AUDIO_CLKC_BINDINGS_H */
diff --git a/include/dt-bindings/clock/axg-clkc.h b/include/dt-bindings/clock/axg-clkc.h
new file mode 100644
index 0000000..fd1f938
--- /dev/null
+++ b/include/dt-bindings/clock/axg-clkc.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
+/*
+ * Meson-AXG clock tree IDs
+ *
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ */
+
+#ifndef __AXG_CLKC_H
+#define __AXG_CLKC_H
+
+#define CLKID_SYS_PLL 0
+#define CLKID_FIXED_PLL 1
+#define CLKID_FCLK_DIV2 2
+#define CLKID_FCLK_DIV3 3
+#define CLKID_FCLK_DIV4 4
+#define CLKID_FCLK_DIV5 5
+#define CLKID_FCLK_DIV7 6
+#define CLKID_GP0_PLL 7
+#define CLKID_CLK81 10
+#define CLKID_MPLL0 11
+#define CLKID_MPLL1 12
+#define CLKID_MPLL2 13
+#define CLKID_MPLL3 14
+#define CLKID_DDR 15
+#define CLKID_AUDIO_LOCKER 16
+#define CLKID_MIPI_DSI_HOST 17
+#define CLKID_ISA 18
+#define CLKID_PL301 19
+#define CLKID_PERIPHS 20
+#define CLKID_SPICC0 21
+#define CLKID_I2C 22
+#define CLKID_RNG0 23
+#define CLKID_UART0 24
+#define CLKID_MIPI_DSI_PHY 25
+#define CLKID_SPICC1 26
+#define CLKID_PCIE_A 27
+#define CLKID_PCIE_B 28
+#define CLKID_HIU_IFACE 29
+#define CLKID_ASSIST_MISC 30
+#define CLKID_SD_EMMC_B 31
+#define CLKID_SD_EMMC_C 32
+#define CLKID_DMA 33
+#define CLKID_SPI 34
+#define CLKID_AUDIO 35
+#define CLKID_ETH 36
+#define CLKID_UART1 37
+#define CLKID_G2D 38
+#define CLKID_USB0 39
+#define CLKID_USB1 40
+#define CLKID_RESET 41
+#define CLKID_USB 42
+#define CLKID_AHB_ARB0 43
+#define CLKID_EFUSE 44
+#define CLKID_BOOT_ROM 45
+#define CLKID_AHB_DATA_BUS 46
+#define CLKID_AHB_CTRL_BUS 47
+#define CLKID_USB1_DDR_BRIDGE 48
+#define CLKID_USB0_DDR_BRIDGE 49
+#define CLKID_MMC_PCLK 50
+#define CLKID_VPU_INTR 51
+#define CLKID_SEC_AHB_AHB3_BRIDGE 52
+#define CLKID_GIC 53
+#define CLKID_AO_MEDIA_CPU 54
+#define CLKID_AO_AHB_SRAM 55
+#define CLKID_AO_AHB_BUS 56
+#define CLKID_AO_IFACE 57
+#define CLKID_AO_I2C 58
+#define CLKID_SD_EMMC_B_CLK0 59
+#define CLKID_SD_EMMC_C_CLK0 60
+#define CLKID_HIFI_PLL 69
+#define CLKID_PCIE_CML_EN0 79
+#define CLKID_PCIE_CML_EN1 80
+#define CLKID_MIPI_ENABLE 81
+#define CLKID_GEN_CLK 84
+
+#endif /* __AXG_CLKC_H */
diff --git a/include/dt-bindings/clock/mt7623-clk.h b/include/dt-bindings/clock/mt7623-clk.h
new file mode 100644
index 0000000..71ced15
--- /dev/null
+++ b/include/dt-bindings/clock/mt7623-clk.h
@@ -0,0 +1,413 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT2701_H
+#define _DT_BINDINGS_CLK_MT2701_H
+
+/* TOPCKGEN */
+#define CLK_TOP_FCLKS_OFF 0
+
+#define CLK_TOP_DPI 0
+#define CLK_TOP_DMPLL 1
+#define CLK_TOP_VENCPLL 2
+#define CLK_TOP_HDMI_0_PIX340M 3
+#define CLK_TOP_HDMI_0_DEEP340M 4
+#define CLK_TOP_HDMI_0_PLL340M 5
+#define CLK_TOP_HADDS2_FB 6
+#define CLK_TOP_WBG_DIG_416M 7
+#define CLK_TOP_DSI0_LNTC_DSI 8
+#define CLK_TOP_HDMI_SCL_RX 9
+#define CLK_TOP_32K_EXTERNAL 10
+#define CLK_TOP_HDMITX_CLKDIG_CTS 11
+#define CLK_TOP_AUD_EXT1 12
+#define CLK_TOP_AUD_EXT2 13
+#define CLK_TOP_NFI1X_PAD 14
+
+#define CLK_TOP_SYSPLL 15
+#define CLK_TOP_SYSPLL_D2 16
+#define CLK_TOP_SYSPLL_D3 17
+#define CLK_TOP_SYSPLL_D5 18
+#define CLK_TOP_SYSPLL_D7 19
+#define CLK_TOP_SYSPLL1_D2 20
+#define CLK_TOP_SYSPLL1_D4 21
+#define CLK_TOP_SYSPLL1_D8 22
+#define CLK_TOP_SYSPLL1_D16 23
+#define CLK_TOP_SYSPLL2_D2 24
+#define CLK_TOP_SYSPLL2_D4 25
+#define CLK_TOP_SYSPLL2_D8 26
+#define CLK_TOP_SYSPLL3_D2 27
+#define CLK_TOP_SYSPLL3_D4 28
+#define CLK_TOP_SYSPLL4_D2 29
+#define CLK_TOP_SYSPLL4_D4 30
+#define CLK_TOP_UNIVPLL 31
+#define CLK_TOP_UNIVPLL_D2 32
+#define CLK_TOP_UNIVPLL_D3 33
+#define CLK_TOP_UNIVPLL_D5 34
+#define CLK_TOP_UNIVPLL_D7 35
+#define CLK_TOP_UNIVPLL_D26 36
+#define CLK_TOP_UNIVPLL_D52 37
+#define CLK_TOP_UNIVPLL_D108 38
+#define CLK_TOP_USB_PHY48M 39
+#define CLK_TOP_UNIVPLL1_D2 40
+#define CLK_TOP_UNIVPLL1_D4 41
+#define CLK_TOP_UNIVPLL1_D8 42
+#define CLK_TOP_UNIVPLL2_D2 43
+#define CLK_TOP_UNIVPLL2_D4 44
+#define CLK_TOP_UNIVPLL2_D8 45
+#define CLK_TOP_UNIVPLL2_D16 46
+#define CLK_TOP_UNIVPLL2_D32 47
+#define CLK_TOP_UNIVPLL3_D2 48
+#define CLK_TOP_UNIVPLL3_D4 49
+#define CLK_TOP_UNIVPLL3_D8 50
+#define CLK_TOP_MSDCPLL 51
+#define CLK_TOP_MSDCPLL_D2 52
+#define CLK_TOP_MSDCPLL_D4 53
+#define CLK_TOP_MSDCPLL_D8 54
+#define CLK_TOP_MMPLL 55
+#define CLK_TOP_MMPLL_D2 56
+#define CLK_TOP_DMPLL_D2 57
+#define CLK_TOP_DMPLL_D4 58
+#define CLK_TOP_DMPLL_X2 59
+#define CLK_TOP_TVDPLL 60
+#define CLK_TOP_TVDPLL_D2 61
+#define CLK_TOP_TVDPLL_D4 62
+#define CLK_TOP_VDECPLL 63
+#define CLK_TOP_TVD2PLL 64
+#define CLK_TOP_TVD2PLL_D2 65
+#define CLK_TOP_MIPIPLL 66
+#define CLK_TOP_MIPIPLL_D2 67
+#define CLK_TOP_MIPIPLL_D4 68
+#define CLK_TOP_HDMIPLL 69
+#define CLK_TOP_HDMIPLL_D2 70
+#define CLK_TOP_HDMIPLL_D3 71
+#define CLK_TOP_ARMPLL_1P3G 72
+#define CLK_TOP_AUDPLL 73
+#define CLK_TOP_AUDPLL_D4 74
+#define CLK_TOP_AUDPLL_D8 75
+#define CLK_TOP_AUDPLL_D16 76
+#define CLK_TOP_AUDPLL_D24 77
+#define CLK_TOP_AUD1PLL_98M 78
+#define CLK_TOP_AUD2PLL_90M 79
+#define CLK_TOP_HADDS2PLL_98M 80
+#define CLK_TOP_HADDS2PLL_294M 81
+#define CLK_TOP_ETHPLL_500M 82
+#define CLK_TOP_CLK26M_D8 83
+#define CLK_TOP_32K_INTERNAL 84
+#define CLK_TOP_AXISEL_D4 85
+#define CLK_TOP_8BDAC 86
+
+#define CLK_TOP_AXI_SEL 87
+#define CLK_TOP_MEM_SEL 88
+#define CLK_TOP_DDRPHYCFG_SEL 89
+#define CLK_TOP_MM_SEL 90
+#define CLK_TOP_PWM_SEL 91
+#define CLK_TOP_VDEC_SEL 92
+#define CLK_TOP_MFG_SEL 93
+#define CLK_TOP_CAMTG_SEL 94
+#define CLK_TOP_UART_SEL 95
+#define CLK_TOP_SPI0_SEL 96
+#define CLK_TOP_USB20_SEL 97
+#define CLK_TOP_MSDC30_0_SEL 98
+#define CLK_TOP_MSDC30_1_SEL 99
+#define CLK_TOP_MSDC30_2_SEL 100
+#define CLK_TOP_AUDIO_SEL 101
+#define CLK_TOP_AUDINTBUS_SEL 102
+#define CLK_TOP_PMICSPI_SEL 103
+#define CLK_TOP_SCP_SEL 104
+#define CLK_TOP_DPI0_SEL 105
+#define CLK_TOP_DPI1_SEL 106
+#define CLK_TOP_TVE_SEL 107
+#define CLK_TOP_HDMI_SEL 108
+#define CLK_TOP_APLL_SEL 109
+#define CLK_TOP_RTC_SEL 110
+#define CLK_TOP_NFI2X_SEL 111
+#define CLK_TOP_EMMC_HCLK_SEL 112
+#define CLK_TOP_FLASH_SEL 113
+#define CLK_TOP_DI_SEL 114
+#define CLK_TOP_NR_SEL 115
+#define CLK_TOP_OSD_SEL 116
+#define CLK_TOP_HDMIRX_BIST_SEL 117
+#define CLK_TOP_INTDIR_SEL 118
+#define CLK_TOP_ASM_I_SEL 119
+#define CLK_TOP_ASM_M_SEL 120
+#define CLK_TOP_ASM_H_SEL 121
+#define CLK_TOP_MS_CARD_SEL 122
+#define CLK_TOP_ETHIF_SEL 123
+#define CLK_TOP_HDMIRX26_24_SEL 124
+#define CLK_TOP_MSDC30_3_SEL 125
+#define CLK_TOP_CMSYS_SEL 126
+#define CLK_TOP_SPI1_SEL 127
+#define CLK_TOP_SPI2_SEL 128
+#define CLK_TOP_8BDAC_SEL 129
+#define CLK_TOP_AUD2DVD_SEL 130
+#define CLK_TOP_PADMCLK_SEL 131
+#define CLK_TOP_AUD_MUX1_SEL 132
+#define CLK_TOP_AUD_MUX2_SEL 133
+#define CLK_TOP_AUDPLL_MUX_SEL 134
+#define CLK_TOP_AUD_K1_SRC_SEL 135
+#define CLK_TOP_AUD_K2_SRC_SEL 136
+#define CLK_TOP_AUD_K3_SRC_SEL 137
+#define CLK_TOP_AUD_K4_SRC_SEL 138
+#define CLK_TOP_AUD_K5_SRC_SEL 139
+#define CLK_TOP_AUD_K6_SRC_SEL 140
+
+#define CLK_TOP_AUD_EXTCK1_DIV 141
+#define CLK_TOP_AUD_EXTCK2_DIV 142
+#define CLK_TOP_AUD_MUX1_DIV 143
+#define CLK_TOP_AUD_MUX2_DIV 144
+#define CLK_TOP_AUD_K1_SRC_DIV 145
+#define CLK_TOP_AUD_K2_SRC_DIV 146
+#define CLK_TOP_AUD_K3_SRC_DIV 147
+#define CLK_TOP_AUD_K4_SRC_DIV 148
+#define CLK_TOP_AUD_K5_SRC_DIV 149
+#define CLK_TOP_AUD_K6_SRC_DIV 150
+#define CLK_TOP_AUD_48K_TIMING 151
+#define CLK_TOP_AUD_44K_TIMING 152
+#define CLK_TOP_AUD_I2S1_MCLK 153
+#define CLK_TOP_AUD_I2S2_MCLK 154
+#define CLK_TOP_AUD_I2S3_MCLK 155
+#define CLK_TOP_AUD_I2S4_MCLK 156
+#define CLK_TOP_AUD_I2S5_MCLK 157
+#define CLK_TOP_AUD_I2S6_MCLK 158
+#define CLK_TOP_NR 159
+
+/* APMIXEDSYS */
+#define CLK_APMIXED_ARMPLL 0
+#define CLK_APMIXED_MAINPLL 1
+#define CLK_APMIXED_UNIVPLL 2
+#define CLK_APMIXED_MMPLL 3
+#define CLK_APMIXED_MSDCPLL 4
+#define CLK_APMIXED_TVDPLL 5
+#define CLK_APMIXED_AUD1PLL 6
+#define CLK_APMIXED_TRGPLL 7
+#define CLK_APMIXED_ETHPLL 8
+#define CLK_APMIXED_VDECPLL 9
+#define CLK_APMIXED_HADDS2PLL 10
+#define CLK_APMIXED_AUD2PLL 11
+#define CLK_APMIXED_TVD2PLL 12
+#define CLK_APMIXED_NR 13
+
+/* INFRACFG */
+#define CLK_INFRA_DBG 0
+#define CLK_INFRA_SMI 1
+#define CLK_INFRA_QAXI_CM4 2
+#define CLK_INFRA_AUD_SPLIN_B 3
+#define CLK_INFRA_AUDIO 4
+#define CLK_INFRA_EFUSE 5
+#define CLK_INFRA_L2C_SRAM 6
+#define CLK_INFRA_M4U 7
+#define CLK_INFRA_CONNMCU 8
+#define CLK_INFRA_TRNG 9
+#define CLK_INFRA_RAMBUFIF 10
+#define CLK_INFRA_CPUM 11
+#define CLK_INFRA_KP 12
+#define CLK_INFRA_CEC 13
+#define CLK_INFRA_IRRX 14
+#define CLK_INFRA_PMICSPI 15
+#define CLK_INFRA_PMICWRAP 16
+#define CLK_INFRA_DDCCI 17
+#define CLK_INFRA_CPUSEL 18
+#define CLK_INFRA_NR 19
+
+/* PERICFG */
+#define CLK_PERI_NFI 0
+#define CLK_PERI_THERM 1
+#define CLK_PERI_PWM1 2
+#define CLK_PERI_PWM2 3
+#define CLK_PERI_PWM3 4
+#define CLK_PERI_PWM4 5
+#define CLK_PERI_PWM5 6
+#define CLK_PERI_PWM6 7
+#define CLK_PERI_PWM7 8
+#define CLK_PERI_PWM 9
+#define CLK_PERI_USB0 10
+#define CLK_PERI_USB1 11
+#define CLK_PERI_AP_DMA 12
+#define CLK_PERI_MSDC30_0 13
+#define CLK_PERI_MSDC30_1 14
+#define CLK_PERI_MSDC30_2 15
+#define CLK_PERI_MSDC30_3 16
+#define CLK_PERI_MSDC50_3 17
+#define CLK_PERI_NLI 18
+#define CLK_PERI_UART0 19
+#define CLK_PERI_UART1 20
+#define CLK_PERI_UART2 21
+#define CLK_PERI_UART3 22
+#define CLK_PERI_BTIF 23
+#define CLK_PERI_I2C0 24
+#define CLK_PERI_I2C1 25
+#define CLK_PERI_I2C2 26
+#define CLK_PERI_I2C3 27
+#define CLK_PERI_AUXADC 28
+#define CLK_PERI_SPI0 39
+#define CLK_PERI_ETH 30
+#define CLK_PERI_USB0_MCU 31
+
+#define CLK_PERI_USB1_MCU 32
+#define CLK_PERI_USB_SLV 33
+#define CLK_PERI_GCPU 34
+#define CLK_PERI_NFI_ECC 35
+#define CLK_PERI_NFI_PAD 36
+#define CLK_PERI_FLASH 37
+#define CLK_PERI_HOST89_INT 38
+#define CLK_PERI_HOST89_SPI 39
+#define CLK_PERI_HOST89_DVD 40
+#define CLK_PERI_SPI1 41
+#define CLK_PERI_SPI2 42
+#define CLK_PERI_FCI 43
+#define CLK_PERI_NR 44
+
+/* AUDIO */
+#define CLK_AUD_AFE 0
+#define CLK_AUD_LRCK_DETECT 1
+#define CLK_AUD_I2S 2
+#define CLK_AUD_APLL_TUNER 3
+#define CLK_AUD_HDMI 4
+#define CLK_AUD_SPDF 5
+#define CLK_AUD_SPDF2 6
+#define CLK_AUD_APLL 7
+#define CLK_AUD_TML 8
+#define CLK_AUD_AHB_IDLE_EXT 9
+#define CLK_AUD_AHB_IDLE_INT 10
+
+#define CLK_AUD_I2SIN1 11
+#define CLK_AUD_I2SIN2 12
+#define CLK_AUD_I2SIN3 13
+#define CLK_AUD_I2SIN4 14
+#define CLK_AUD_I2SIN5 15
+#define CLK_AUD_I2SIN6 16
+#define CLK_AUD_I2SO1 17
+#define CLK_AUD_I2SO2 18
+#define CLK_AUD_I2SO3 19
+#define CLK_AUD_I2SO4 20
+#define CLK_AUD_I2SO5 21
+#define CLK_AUD_I2SO6 22
+#define CLK_AUD_ASRCI1 23
+#define CLK_AUD_ASRCI2 24
+#define CLK_AUD_ASRCO1 25
+#define CLK_AUD_ASRCO2 26
+#define CLK_AUD_ASRC11 27
+#define CLK_AUD_ASRC12 28
+#define CLK_AUD_HDMIRX 29
+#define CLK_AUD_INTDIR 30
+#define CLK_AUD_A1SYS 31
+#define CLK_AUD_A2SYS 32
+#define CLK_AUD_AFE_CONN 33
+#define CLK_AUD_AFE_PCMIF 34
+#define CLK_AUD_AFE_MRGIF 35
+
+#define CLK_AUD_MMIF_UL1 36
+#define CLK_AUD_MMIF_UL2 37
+#define CLK_AUD_MMIF_UL3 38
+#define CLK_AUD_MMIF_UL4 39
+#define CLK_AUD_MMIF_UL5 40
+#define CLK_AUD_MMIF_UL6 41
+#define CLK_AUD_MMIF_DL1 42
+#define CLK_AUD_MMIF_DL2 43
+#define CLK_AUD_MMIF_DL3 44
+#define CLK_AUD_MMIF_DL4 45
+#define CLK_AUD_MMIF_DL5 46
+#define CLK_AUD_MMIF_DL6 47
+#define CLK_AUD_MMIF_DLMCH 48
+#define CLK_AUD_MMIF_ARB1 49
+#define CLK_AUD_MMIF_AWB1 50
+#define CLK_AUD_MMIF_AWB2 51
+#define CLK_AUD_MMIF_DAI 52
+
+#define CLK_AUD_DMIC1 53
+#define CLK_AUD_DMIC2 54
+#define CLK_AUD_ASRCI3 55
+#define CLK_AUD_ASRCI4 56
+#define CLK_AUD_ASRCI5 57
+#define CLK_AUD_ASRCI6 58
+#define CLK_AUD_ASRCO3 59
+#define CLK_AUD_ASRCO4 60
+#define CLK_AUD_ASRCO5 61
+#define CLK_AUD_ASRCO6 62
+#define CLK_AUD_MEM_ASRC1 63
+#define CLK_AUD_MEM_ASRC2 64
+#define CLK_AUD_MEM_ASRC3 65
+#define CLK_AUD_MEM_ASRC4 66
+#define CLK_AUD_MEM_ASRC5 67
+#define CLK_AUD_DSD_ENC 68
+#define CLK_AUD_ASRC_BRG 60
+#define CLK_AUD_NR 70
+
+/* MMSYS */
+#define CLK_MM_SMI_COMMON 0
+#define CLK_MM_SMI_LARB0 1
+#define CLK_MM_CMDQ 2
+#define CLK_MM_MUTEX 3
+#define CLK_MM_DISP_COLOR 4
+#define CLK_MM_DISP_BLS 5
+#define CLK_MM_DISP_WDMA 6
+#define CLK_MM_DISP_RDMA 7
+#define CLK_MM_DISP_OVL 8
+#define CLK_MM_MDP_TDSHP 9
+#define CLK_MM_MDP_WROT 10
+#define CLK_MM_MDP_WDMA 11
+#define CLK_MM_MDP_RSZ1 12
+#define CLK_MM_MDP_RSZ0 13
+#define CLK_MM_MDP_RDMA 14
+#define CLK_MM_MDP_BLS_26M 15
+#define CLK_MM_CAM_MDP 16
+#define CLK_MM_FAKE_ENG 17
+#define CLK_MM_MUTEX_32K 18
+#define CLK_MM_DISP_RDMA1 19
+#define CLK_MM_DISP_UFOE 20
+
+#define CLK_MM_DSI_ENGINE 21
+#define CLK_MM_DSI_DIG 22
+#define CLK_MM_DPI_DIGL 23
+#define CLK_MM_DPI_ENGINE 24
+#define CLK_MM_DPI1_DIGL 25
+#define CLK_MM_DPI1_ENGINE 26
+#define CLK_MM_TVE_OUTPUT 27
+#define CLK_MM_TVE_INPUT 28
+#define CLK_MM_HDMI_PIXEL 29
+#define CLK_MM_HDMI_PLL 30
+#define CLK_MM_HDMI_AUDIO 31
+#define CLK_MM_HDMI_SPDIF 32
+#define CLK_MM_TVE_FMM 33
+#define CLK_MM_NR 34
+
+/* IMGSYS */
+#define CLK_IMG_SMI_COMM 0
+#define CLK_IMG_RESZ 1
+#define CLK_IMG_JPGDEC_SMI 2
+#define CLK_IMG_JPGDEC 3
+#define CLK_IMG_VENC_LT 4
+#define CLK_IMG_VENC 5
+#define CLK_IMG_NR 6
+
+/* VDEC */
+#define CLK_VDEC_CKGEN 0
+#define CLK_VDEC_LARB 1
+#define CLK_VDEC_NR 2
+
+/* HIFSYS */
+#define CLK_HIFSYS_USB0PHY 0
+#define CLK_HIFSYS_USB1PHY 1
+#define CLK_HIFSYS_PCIE0 2
+#define CLK_HIFSYS_PCIE1 3
+#define CLK_HIFSYS_PCIE2 4
+#define CLK_HIFSYS_NR 5
+
+/* ETHSYS */
+#define CLK_ETHSYS_HSDMA 0
+#define CLK_ETHSYS_ESW 1
+#define CLK_ETHSYS_GP2 2
+#define CLK_ETHSYS_GP1 3
+#define CLK_ETHSYS_PCM 4
+#define CLK_ETHSYS_GDMA 5
+#define CLK_ETHSYS_I2S 6
+#define CLK_ETHSYS_CRYPTO 7
+#define CLK_ETHSYS_NR 8
+
+/* G3DSYS */
+#define CLK_G3DSYS_CORE 0
+#define CLK_G3DSYS_NR 1
+
+#endif /* _DT_BINDINGS_CLK_MT2701_H */
diff --git a/include/dt-bindings/clock/mt7629-clk.h b/include/dt-bindings/clock/mt7629-clk.h
new file mode 100644
index 0000000..0bbfbfa
--- /dev/null
+++ b/include/dt-bindings/clock/mt7629-clk.h
@@ -0,0 +1,206 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT7629_H
+#define _DT_BINDINGS_CLK_MT7629_H
+
+/* TOPCKGEN */
+#define CLK_TOP_FCLKS_OFF 0
+
+#define CLK_TOP_TO_U2_PHY 0
+#define CLK_TOP_TO_U2_PHY_1P 1
+#define CLK_TOP_PCIE0_PIPE_EN 2
+#define CLK_TOP_PCIE1_PIPE_EN 3
+#define CLK_TOP_SSUSB_TX250M 4
+#define CLK_TOP_SSUSB_EQ_RX250M 5
+#define CLK_TOP_SSUSB_CDR_REF 6
+#define CLK_TOP_SSUSB_CDR_FB 7
+#define CLK_TOP_SATA_ASIC 8
+#define CLK_TOP_SATA_RBC 9
+
+#define CLK_TOP_TO_USB3_SYS 10
+#define CLK_TOP_P1_1MHZ 11
+#define CLK_TOP_4MHZ 12
+#define CLK_TOP_P0_1MHZ 13
+#define CLK_TOP_ETH_500M 14
+#define CLK_TOP_TXCLK_SRC_PRE 15
+#define CLK_TOP_RTC 16
+#define CLK_TOP_PWM_QTR_26M 17
+#define CLK_TOP_CPUM_TCK_IN 18
+#define CLK_TOP_TO_USB3_DA_TOP 19
+#define CLK_TOP_MEMPLL 20
+#define CLK_TOP_DMPLL 21
+#define CLK_TOP_DMPLL_D4 22
+#define CLK_TOP_DMPLL_D8 23
+#define CLK_TOP_SYSPLL_D2 24
+#define CLK_TOP_SYSPLL1_D2 25
+#define CLK_TOP_SYSPLL1_D4 26
+#define CLK_TOP_SYSPLL1_D8 27
+#define CLK_TOP_SYSPLL1_D16 28
+#define CLK_TOP_SYSPLL2_D2 29
+#define CLK_TOP_SYSPLL2_D4 30
+#define CLK_TOP_SYSPLL2_D8 31
+#define CLK_TOP_SYSPLL_D5 32
+#define CLK_TOP_SYSPLL3_D2 33
+#define CLK_TOP_SYSPLL3_D4 34
+#define CLK_TOP_SYSPLL_D7 35
+#define CLK_TOP_SYSPLL4_D2 36
+#define CLK_TOP_SYSPLL4_D4 37
+#define CLK_TOP_SYSPLL4_D16 38
+#define CLK_TOP_UNIVPLL 39
+#define CLK_TOP_UNIVPLL1_D2 40
+#define CLK_TOP_UNIVPLL1_D4 41
+#define CLK_TOP_UNIVPLL1_D8 42
+#define CLK_TOP_UNIVPLL_D3 43
+#define CLK_TOP_UNIVPLL2_D2 44
+#define CLK_TOP_UNIVPLL2_D4 45
+#define CLK_TOP_UNIVPLL2_D8 46
+#define CLK_TOP_UNIVPLL2_D16 47
+#define CLK_TOP_UNIVPLL_D5 48
+#define CLK_TOP_UNIVPLL3_D2 49
+#define CLK_TOP_UNIVPLL3_D4 50
+#define CLK_TOP_UNIVPLL3_D16 51
+#define CLK_TOP_UNIVPLL_D7 52
+#define CLK_TOP_UNIVPLL_D80_D4 53
+#define CLK_TOP_UNIV48M 54
+#define CLK_TOP_SGMIIPLL_D2 55
+#define CLK_TOP_CLKXTAL_D4 56
+#define CLK_TOP_HD_FAXI 57
+#define CLK_TOP_FAXI 58
+#define CLK_TOP_F_FAUD_INTBUS 59
+#define CLK_TOP_AP2WBHIF_HCLK 60
+#define CLK_TOP_10M_INFRAO 61
+#define CLK_TOP_MSDC30_1 62
+#define CLK_TOP_SPI 63
+#define CLK_TOP_SF 64
+#define CLK_TOP_FLASH 65
+#define CLK_TOP_TO_USB3_REF 66
+#define CLK_TOP_TO_USB3_MCU 67
+#define CLK_TOP_TO_USB3_DMA 68
+#define CLK_TOP_FROM_TOP_AHB 69
+#define CLK_TOP_FROM_TOP_AXI 70
+#define CLK_TOP_PCIE1_MAC_EN 71
+#define CLK_TOP_PCIE0_MAC_EN 72
+
+#define CLK_TOP_AXI_SEL 73
+#define CLK_TOP_MEM_SEL 74
+#define CLK_TOP_DDRPHYCFG_SEL 75
+#define CLK_TOP_ETH_SEL 76
+#define CLK_TOP_PWM_SEL 77
+#define CLK_TOP_F10M_REF_SEL 78
+#define CLK_TOP_NFI_INFRA_SEL 79
+#define CLK_TOP_FLASH_SEL 80
+#define CLK_TOP_UART_SEL 81
+#define CLK_TOP_SPI0_SEL 82
+#define CLK_TOP_SPI1_SEL 83
+#define CLK_TOP_MSDC50_0_SEL 84
+#define CLK_TOP_MSDC30_0_SEL 85
+#define CLK_TOP_MSDC30_1_SEL 86
+#define CLK_TOP_AP2WBMCU_SEL 87
+#define CLK_TOP_AP2WBHIF_SEL 88
+#define CLK_TOP_AUDIO_SEL 89
+#define CLK_TOP_AUD_INTBUS_SEL 90
+#define CLK_TOP_PMICSPI_SEL 91
+#define CLK_TOP_SCP_SEL 92
+#define CLK_TOP_ATB_SEL 93
+#define CLK_TOP_HIF_SEL 94
+#define CLK_TOP_SATA_SEL 95
+#define CLK_TOP_U2_SEL 96
+#define CLK_TOP_AUD1_SEL 97
+#define CLK_TOP_AUD2_SEL 98
+#define CLK_TOP_IRRX_SEL 99
+#define CLK_TOP_IRTX_SEL 100
+#define CLK_TOP_SATA_MCU_SEL 101
+#define CLK_TOP_PCIE0_MCU_SEL 102
+#define CLK_TOP_PCIE1_MCU_SEL 103
+#define CLK_TOP_SSUSB_MCU_SEL 104
+#define CLK_TOP_CRYPTO_SEL 105
+#define CLK_TOP_SGMII_REF_1_SEL 106
+#define CLK_TOP_10M_SEL 107
+#define CLK_TOP_NR_CLK 108
+
+/* INFRACFG */
+#define CLK_INFRA_MUX1_SEL 0
+#define CLK_INFRA_DBGCLK_PD 1
+#define CLK_INFRA_TRNG_PD 2
+#define CLK_INFRA_DEVAPC_PD 3
+#define CLK_INFRA_APXGPT_PD 4
+#define CLK_INFRA_SEJ_PD 5
+#define CLK_INFRA_NR_CLK 6
+
+/* PERICFG */
+#define CLK_PERIBUS_SEL 0
+#define CLK_PERI_PWM1_PD 1
+#define CLK_PERI_PWM2_PD 2
+#define CLK_PERI_PWM3_PD 3
+#define CLK_PERI_PWM4_PD 4
+#define CLK_PERI_PWM5_PD 5
+#define CLK_PERI_PWM6_PD 6
+#define CLK_PERI_PWM7_PD 7
+#define CLK_PERI_PWM_PD 8
+#define CLK_PERI_AP_DMA_PD 9
+#define CLK_PERI_MSDC30_1_PD 10
+#define CLK_PERI_UART0_PD 11
+#define CLK_PERI_UART1_PD 12
+#define CLK_PERI_UART2_PD 13
+#define CLK_PERI_UART3_PD 14
+#define CLK_PERI_BTIF_PD 15
+#define CLK_PERI_I2C0_PD 16
+#define CLK_PERI_SPI0_PD 17
+#define CLK_PERI_SNFI_PD 18
+#define CLK_PERI_NFI_PD 19
+#define CLK_PERI_NFIECC_PD 20
+#define CLK_PERI_FLASH_PD 21
+#define CLK_PERI_NR_CLK 22
+
+/* APMIXEDSYS */
+#define CLK_APMIXED_ARMPLL 0
+#define CLK_APMIXED_MAINPLL 1
+#define CLK_APMIXED_UNIV2PLL 2
+#define CLK_APMIXED_ETH1PLL 3
+#define CLK_APMIXED_ETH2PLL 4
+#define CLK_APMIXED_SGMIPLL 5
+#define CLK_APMIXED_NR_CLK 6
+
+/* SSUSBSYS */
+#define CLK_SSUSB_U2_PHY_1P_EN 0
+#define CLK_SSUSB_U2_PHY_EN 1
+#define CLK_SSUSB_REF_EN 2
+#define CLK_SSUSB_SYS_EN 3
+#define CLK_SSUSB_MCU_EN 4
+#define CLK_SSUSB_DMA_EN 5
+#define CLK_SSUSB_NR_CLK 6
+
+/* PCIESYS */
+#define CLK_PCIE_P1_AUX_EN 0
+#define CLK_PCIE_P1_OBFF_EN 1
+#define CLK_PCIE_P1_AHB_EN 2
+#define CLK_PCIE_P1_AXI_EN 3
+#define CLK_PCIE_P1_MAC_EN 4
+#define CLK_PCIE_P1_PIPE_EN 5
+#define CLK_PCIE_P0_AUX_EN 6
+#define CLK_PCIE_P0_OBFF_EN 7
+#define CLK_PCIE_P0_AHB_EN 8
+#define CLK_PCIE_P0_AXI_EN 9
+#define CLK_PCIE_P0_MAC_EN 10
+#define CLK_PCIE_P0_PIPE_EN 11
+#define CLK_PCIE_NR_CLK 12
+
+/* ETHSYS */
+#define CLK_ETH_FE_EN 0
+#define CLK_ETH_GP2_EN 1
+#define CLK_ETH_GP1_EN 2
+#define CLK_ETH_GP0_EN 3
+#define CLK_ETH_ESW_EN 4
+#define CLK_ETH_NR_CLK 5
+
+/* SGMIISYS */
+#define CLK_SGMII_TX_EN 0
+#define CLK_SGMII_RX_EN 1
+#define CLK_SGMII_CDR_REF 2
+#define CLK_SGMII_CDR_FB 3
+#define CLK_SGMII_NR_CLK 4
+
+#endif /* _DT_BINDINGS_CLK_MT7629_H */
diff --git a/include/dt-bindings/gpio/meson-axg-gpio.h b/include/dt-bindings/gpio/meson-axg-gpio.h
new file mode 100644
index 0000000..25bb1ff
--- /dev/null
+++ b/include/dt-bindings/gpio/meson-axg-gpio.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 Amlogic, Inc. All rights reserved.
+ * Author: Xingyu Chen <xingyu.chen@amlogic.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _DT_BINDINGS_MESON_AXG_GPIO_H
+#define _DT_BINDINGS_MESON_AXG_GPIO_H
+
+/* First GPIO chip */
+#define GPIOAO_0 0
+#define GPIOAO_1 1
+#define GPIOAO_2 2
+#define GPIOAO_3 3
+#define GPIOAO_4 4
+#define GPIOAO_5 5
+#define GPIOAO_6 6
+#define GPIOAO_7 7
+#define GPIOAO_8 8
+#define GPIOAO_9 9
+#define GPIOAO_10 10
+#define GPIOAO_11 11
+#define GPIOAO_12 12
+#define GPIOAO_13 13
+#define GPIO_TEST_N 14
+
+/* Second GPIO chip */
+#define GPIOZ_0 0
+#define GPIOZ_1 1
+#define GPIOZ_2 2
+#define GPIOZ_3 3
+#define GPIOZ_4 4
+#define GPIOZ_5 5
+#define GPIOZ_6 6
+#define GPIOZ_7 7
+#define GPIOZ_8 8
+#define GPIOZ_9 9
+#define GPIOZ_10 10
+#define BOOT_0 11
+#define BOOT_1 12
+#define BOOT_2 13
+#define BOOT_3 14
+#define BOOT_4 15
+#define BOOT_5 16
+#define BOOT_6 17
+#define BOOT_7 18
+#define BOOT_8 19
+#define BOOT_9 20
+#define BOOT_10 21
+#define BOOT_11 22
+#define BOOT_12 23
+#define BOOT_13 24
+#define BOOT_14 25
+#define GPIOA_0 26
+#define GPIOA_1 27
+#define GPIOA_2 28
+#define GPIOA_3 29
+#define GPIOA_4 30
+#define GPIOA_5 31
+#define GPIOA_6 32
+#define GPIOA_7 33
+#define GPIOA_8 34
+#define GPIOA_9 35
+#define GPIOA_10 36
+#define GPIOA_11 37
+#define GPIOA_12 38
+#define GPIOA_13 39
+#define GPIOA_14 40
+#define GPIOA_15 41
+#define GPIOA_16 42
+#define GPIOA_17 43
+#define GPIOA_18 44
+#define GPIOA_19 45
+#define GPIOA_20 46
+#define GPIOX_0 47
+#define GPIOX_1 48
+#define GPIOX_2 49
+#define GPIOX_3 50
+#define GPIOX_4 51
+#define GPIOX_5 52
+#define GPIOX_6 53
+#define GPIOX_7 54
+#define GPIOX_8 55
+#define GPIOX_9 56
+#define GPIOX_10 57
+#define GPIOX_11 58
+#define GPIOX_12 59
+#define GPIOX_13 60
+#define GPIOX_14 61
+#define GPIOX_15 62
+#define GPIOX_16 63
+#define GPIOX_17 64
+#define GPIOX_18 65
+#define GPIOX_19 66
+#define GPIOX_20 67
+#define GPIOX_21 68
+#define GPIOX_22 69
+#define GPIOY_0 70
+#define GPIOY_1 71
+#define GPIOY_2 72
+#define GPIOY_3 73
+#define GPIOY_4 74
+#define GPIOY_5 75
+#define GPIOY_6 76
+#define GPIOY_7 77
+#define GPIOY_8 78
+#define GPIOY_9 79
+#define GPIOY_10 80
+#define GPIOY_11 81
+#define GPIOY_12 82
+#define GPIOY_13 83
+#define GPIOY_14 84
+#define GPIOY_15 85
+
+#endif /* _DT_BINDINGS_MESON_AXG_GPIO_H */
diff --git a/include/dt-bindings/power/mt7623-power.h b/include/dt-bindings/power/mt7623-power.h
new file mode 100644
index 0000000..0e73bb4
--- /dev/null
+++ b/include/dt-bindings/power/mt7623-power.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_MT7623_POWER_H
+#define _DT_BINDINGS_MT7623_POWER_H
+
+#define MT7623_POWER_DOMAIN_CONN 0
+#define MT7623_POWER_DOMAIN_DISP 1
+#define MT7623_POWER_DOMAIN_MFG 2
+#define MT7623_POWER_DOMAIN_VDEC 3
+#define MT7623_POWER_DOMAIN_ISP 4
+#define MT7623_POWER_DOMAIN_BDP 5
+#define MT7623_POWER_DOMAIN_ETH 6
+#define MT7623_POWER_DOMAIN_HIF 7
+#define MT7623_POWER_DOMAIN_IFR_MSC 8
+
+#endif /* _DT_BINDINGS_MT7623_POWER_H */
diff --git a/include/dt-bindings/power/mt7629-power.h b/include/dt-bindings/power/mt7629-power.h
new file mode 100644
index 0000000..c7e6130
--- /dev/null
+++ b/include/dt-bindings/power/mt7629-power.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_MT7629_POWER_H
+#define _DT_BINDINGS_MT7629_POWER_H
+
+#define MT7629_POWER_DOMAIN_ETHSYS 0
+#define MT7629_POWER_DOMAIN_HIF0 1
+#define MT7629_POWER_DOMAIN_HIF1 2
+
+#endif /* _DT_BINDINGS_MT7629_POWER_H */
diff --git a/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h b/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h
new file mode 100644
index 0000000..05c3636
--- /dev/null
+++ b/include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
+ *
+ * Copyright (c) 2018 Baylibre SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H
+#define _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H
+
+#define AXG_ARB_TODDR_A 0
+#define AXG_ARB_TODDR_B 1
+#define AXG_ARB_TODDR_C 2
+#define AXG_ARB_FRDDR_A 3
+#define AXG_ARB_FRDDR_B 4
+#define AXG_ARB_FRDDR_C 5
+
+#endif /* _DT_BINDINGS_AMLOGIC_MESON_AXG_AUDIO_ARB_H */
diff --git a/include/dt-bindings/reset/amlogic,meson-axg-reset.h b/include/dt-bindings/reset/amlogic,meson-axg-reset.h
new file mode 100644
index 0000000..ad6f55d
--- /dev/null
+++ b/include/dt-bindings/reset/amlogic,meson-axg-reset.h
@@ -0,0 +1,124 @@
+/*
+ *
+ * Copyright (c) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Copyright (c) 2017 Amlogic, inc.
+ * Author: Yixun Lan <yixun.lan@amlogic.com>
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR BSD)
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_AXG_RESET_H
+#define _DT_BINDINGS_AMLOGIC_MESON_AXG_RESET_H
+
+/* RESET0 */
+#define RESET_HIU 0
+#define RESET_PCIE_A 1
+#define RESET_PCIE_B 2
+#define RESET_DDR_TOP 3
+/* 4 */
+#define RESET_VIU 5
+#define RESET_PCIE_PHY 6
+#define RESET_PCIE_APB 7
+/* 8 */
+/* 9 */
+#define RESET_VENC 10
+#define RESET_ASSIST 11
+/* 12 */
+#define RESET_VCBUS 13
+/* 14 */
+/* 15 */
+#define RESET_GIC 16
+#define RESET_CAPB3_DECODE 17
+/* 18-21 */
+#define RESET_SYS_CPU_CAPB3 22
+#define RESET_CBUS_CAPB3 23
+#define RESET_AHB_CNTL 24
+#define RESET_AHB_DATA 25
+#define RESET_VCBUS_CLK81 26
+#define RESET_MMC 27
+/* 28-31 */
+/* RESET1 */
+/* 32 */
+/* 33 */
+#define RESET_USB_OTG 34
+#define RESET_DDR 35
+#define RESET_AO_RESET 36
+/* 37 */
+#define RESET_AHB_SRAM 38
+/* 39 */
+/* 40 */
+#define RESET_DMA 41
+#define RESET_ISA 42
+#define RESET_ETHERNET 43
+/* 44 */
+#define RESET_SD_EMMC_B 45
+#define RESET_SD_EMMC_C 46
+#define RESET_ROM_BOOT 47
+#define RESET_SYS_CPU_0 48
+#define RESET_SYS_CPU_1 49
+#define RESET_SYS_CPU_2 50
+#define RESET_SYS_CPU_3 51
+#define RESET_SYS_CPU_CORE_0 52
+#define RESET_SYS_CPU_CORE_1 53
+#define RESET_SYS_CPU_CORE_2 54
+#define RESET_SYS_CPU_CORE_3 55
+#define RESET_SYS_PLL_DIV 56
+#define RESET_SYS_CPU_AXI 57
+#define RESET_SYS_CPU_L2 58
+#define RESET_SYS_CPU_P 59
+#define RESET_SYS_CPU_MBIST 60
+/* 61-63 */
+/* RESET2 */
+/* 64 */
+/* 65 */
+#define RESET_AUDIO 66
+/* 67 */
+#define RESET_MIPI_HOST 68
+#define RESET_AUDIO_LOCKER 69
+#define RESET_GE2D 70
+/* 71-76 */
+#define RESET_AO_CPU_RESET 77
+/* 78-95 */
+/* RESET3 */
+#define RESET_RING_OSCILLATOR 96
+/* 97-127 */
+/* RESET4 */
+/* 128 */
+/* 129 */
+#define RESET_MIPI_PHY 130
+/* 131-140 */
+#define RESET_VENCL 141
+#define RESET_I2C_MASTER_2 142
+#define RESET_I2C_MASTER_1 143
+/* 144-159 */
+/* RESET5 */
+/* 160-191 */
+/* RESET6 */
+#define RESET_PERIPHS_GENERAL 192
+#define RESET_PERIPHS_SPICC 193
+/* 194 */
+/* 195 */
+#define RESET_PERIPHS_I2C_MASTER_0 196
+/* 197-200 */
+#define RESET_PERIPHS_UART_0 201
+#define RESET_PERIPHS_UART_1 202
+/* 203-204 */
+#define RESET_PERIPHS_SPI_0 205
+#define RESET_PERIPHS_I2C_MASTER_3 206
+/* 207-223 */
+/* RESET7 */
+#define RESET_USB_DDR_0 224
+#define RESET_USB_DDR_1 225
+#define RESET_USB_DDR_2 226
+#define RESET_USB_DDR_3 227
+/* 228 */
+#define RESET_DEVICE_MMC_ARB 229
+/* 230 */
+#define RESET_VID_LOCK 231
+#define RESET_A9_DMC_PIPEL 232
+#define RESET_DMC_VPU_PIPEL 233
+/* 234-255 */
+
+#endif
diff --git a/include/dt-bindings/reset/axg-aoclkc.h b/include/dt-bindings/reset/axg-aoclkc.h
new file mode 100644
index 0000000..d342c0b
--- /dev/null
+++ b/include/dt-bindings/reset/axg-aoclkc.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright (c) 2016 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Copyright (c) 2018 Amlogic, inc.
+ * Author: Qiufang Dai <qiufang.dai@amlogic.com>
+ */
+
+#ifndef DT_BINDINGS_RESET_AMLOGIC_MESON_AXG_AOCLK
+#define DT_BINDINGS_RESET_AMLOGIC_MESON_AXG_AOCLK
+
+#define RESET_AO_REMOTE 0
+#define RESET_AO_I2C_MASTER 1
+#define RESET_AO_I2C_SLAVE 2
+#define RESET_AO_UART1 3
+#define RESET_AO_UART2 4
+#define RESET_AO_IR_BLASTER 5
+
+#endif
diff --git a/include/image.h b/include/image.h
index 031c355..f67502e 100644
--- a/include/image.h
+++ b/include/image.h
@@ -278,6 +278,7 @@ enum {
IH_TYPE_PMMC, /* TI Power Management Micro-Controller Firmware */
IH_TYPE_STM32IMAGE, /* STMicroelectronics STM32 Image */
IH_TYPE_SOCFPGAIMAGE_V1, /* Altera SOCFPGA A10 Preloader */
+ IH_TYPE_MTKIMAGE, /* MediaTek BootROM loadable Image */
IH_TYPE_COUNT, /* Number of image types */
};
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index 7416abe..22bd8f7 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -219,6 +219,8 @@ ALL-$(CONFIG_SPL_X86_16BIT_INIT) += $(obj)/u-boot-x86-16bit-spl.bin
ALL-$(CONFIG_ARCH_ZYNQ) += $(obj)/boot.bin
ALL-$(CONFIG_ARCH_ZYNQMP) += $(obj)/boot.bin
+ALL-$(CONFIG_ARCH_MEDIATEK) += $(obj)/u-boot-spl-mtk.bin
+
all: $(ALL-y)
quiet_cmd_cat = CAT $@
@@ -349,6 +351,15 @@ cmd_sunxi_spl_image_builder = $(objtree)/tools/sunxi-spl-image-builder \
$(obj)/sunxi-spl-with-ecc.bin: $(obj)/sunxi-spl.bin
$(call if_changed,sunxi_spl_image_builder)
+
+# MediaTek's specific SPL build
+MKIMAGEFLAGS_u-boot-spl-mtk.bin = -T mtk_image \
+ -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
+ -n "$(patsubst "%",%,$(CONFIG_MTK_BROM_HEADER_INFO))"
+
+$(obj)/u-boot-spl-mtk.bin: $(obj)/u-boot-spl.bin FORCE
+ $(call if_changed,mkimage)
+
# Rule to link u-boot-spl
# May be overridden by arch/$(ARCH)/config.mk
quiet_cmd_u-boot-spl ?= LD $@
diff --git a/tools/Makefile b/tools/Makefile
index 3c0521f..c93d17a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -116,6 +116,7 @@ dumpimage-mkimage-objs := aisimage.o \
$(LIBFDT_OBJS) \
gpimage.o \
gpimage-common.o \
+ mtk_image.o \
$(RSA_OBJS-y)
dumpimage-objs := $(dumpimage-mkimage-objs) dumpimage.o
diff --git a/tools/mtk_image.c b/tools/mtk_image.c
new file mode 100644
index 0000000..2706d2d
--- /dev/null
+++ b/tools/mtk_image.c
@@ -0,0 +1,749 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Generate MediaTek BootROM header for SPL/U-Boot images
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <image.h>
+#include <u-boot/sha256.h>
+#include "imagetool.h"
+#include "mtk_image.h"
+
+/* NAND header for SPI-NAND with 2KB page + 64B spare */
+static const union nand_boot_header snand_hdr_2k_64_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
+ 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
+ 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
+ 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
+ }
+};
+
+/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
+static const union nand_boot_header snand_hdr_2k_128_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
+ 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
+ 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
+ 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
+ }
+};
+
+/* NAND header for SPI-NAND with 4KB page + 256B spare */
+static const union nand_boot_header snand_hdr_4k_256_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
+ 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
+ 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
+ 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
+ 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
+ }
+};
+
+/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
+ 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
+ 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
+ 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
+ }
+};
+
+/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
+ 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
+ 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
+ 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
+ }
+};
+
+/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
+static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
+ 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
+ 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
+ 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
+ }
+};
+
+/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
+static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+ 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
+ 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
+ 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
+ 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
+ }
+};
+
+/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
+static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
+ .data = {
+ 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
+ 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
+ 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
+ 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
+ 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
+ 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
+ }
+};
+
+static const struct nand_header_type {
+ const char *name;
+ const union nand_boot_header *data;
+} nand_headers[] = {
+ {
+ .name = "2k+64",
+ .data = &snand_hdr_2k_64_data
+ }, {
+ .name = "2k+120",
+ .data = &snand_hdr_2k_128_data
+ }, {
+ .name = "2k+128",
+ .data = &snand_hdr_2k_128_data
+ }, {
+ .name = "4k+256",
+ .data = &snand_hdr_4k_256_data
+ }, {
+ .name = "1g:2k+64",
+ .data = &nand_hdr_1gb_2k_64_data
+ }, {
+ .name = "2g:2k+64",
+ .data = &nand_hdr_2gb_2k_64_data
+ }, {
+ .name = "4g:2k+64",
+ .data = &nand_hdr_4gb_2k_64_data
+ }, {
+ .name = "2g:2k+128",
+ .data = &nand_hdr_2gb_2k_128_data
+ }, {
+ .name = "4g:2k+128",
+ .data = &nand_hdr_4gb_2k_128_data
+ }
+};
+
+static const struct brom_img_type {
+ const char *name;
+ enum brlyt_img_type type;
+} brom_images[] = {
+ {
+ .name = "nand",
+ .type = BRLYT_TYPE_NAND
+ }, {
+ .name = "emmc",
+ .type = BRLYT_TYPE_EMMC
+ }, {
+ .name = "nor",
+ .type = BRLYT_TYPE_NOR
+ }, {
+ .name = "sdmmc",
+ .type = BRLYT_TYPE_SDMMC
+ }, {
+ .name = "snand",
+ .type = BRLYT_TYPE_SNAND
+ }
+};
+
+/* Image type selected by user */
+static enum brlyt_img_type hdr_media;
+static int use_lk_hdr;
+
+/* LK image name */
+static char lk_name[32] = "U-Boot";
+
+/* NAND header selected by user */
+static const union nand_boot_header *hdr_nand;
+
+/* GFH header + 2 * 4KB pages of NAND */
+static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
+
+static int mtk_image_check_image_types(uint8_t type)
+{
+ if (type == IH_TYPE_MTKIMAGE)
+ return EXIT_SUCCESS;
+ else
+ return EXIT_FAILURE;
+}
+
+static int mtk_brom_parse_imagename(const char *imagename)
+{
+#define is_blank_char(c) \
+ ((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
+
+ char *buf = strdup(imagename), *key, *val, *end, *next;
+ int i;
+
+ /* User passed arguments from image name */
+ static const char *media = "";
+ static const char *nandinfo = "";
+ static const char *lk = "";
+
+ key = buf;
+ while (key) {
+ next = strchr(key, ';');
+ if (next)
+ *next = 0;
+
+ val = strchr(key, '=');
+ if (val) {
+ *val++ = 0;
+
+ /* Trim key */
+ while (is_blank_char(*key))
+ key++;
+
+ end = key + strlen(key) - 1;
+ while ((end >= key) && is_blank_char(*end))
+ end--;
+ end++;
+
+ if (is_blank_char(*end))
+ *end = 0;
+
+ /* Trim value */
+ while (is_blank_char(*val))
+ val++;
+
+ end = val + strlen(val) - 1;
+ while ((end >= val) && is_blank_char(*end))
+ end--;
+ end++;
+
+ if (is_blank_char(*end))
+ *end = 0;
+
+ /* record user passed arguments */
+ if (!strcmp(key, "media"))
+ media = val;
+
+ if (!strcmp(key, "nandinfo"))
+ nandinfo = val;
+
+ if (!strcmp(key, "lk"))
+ lk = val;
+
+ if (!strcmp(key, "lkname"))
+ strncpy(lk_name, val, sizeof(lk_name));
+ }
+
+ if (next)
+ key = next + 1;
+ else
+ break;
+ }
+
+ /* if user specified LK image header, skip following checks */
+ if (lk && lk[0] == '1') {
+ use_lk_hdr = 1;
+ free(buf);
+ return 0;
+ }
+
+ /* parse media type */
+ for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
+ if (!strcmp(brom_images[i].name, media)) {
+ hdr_media = brom_images[i].type;
+ break;
+ }
+ }
+
+ /* parse nand header type */
+ for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
+ if (!strcmp(nand_headers[i].name, nandinfo)) {
+ hdr_nand = nand_headers[i].data;
+ break;
+ }
+ }
+
+ free(buf);
+
+ if (hdr_media == BRLYT_TYPE_INVALID) {
+ fprintf(stderr, "Error: media type is invalid or missing.\n");
+ fprintf(stderr, " Please specify -n \"media=<type>\"\n");
+ return -EINVAL;
+ }
+
+ if ((hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) &&
+ !hdr_nand) {
+ fprintf(stderr, "Error: nand info is invalid or missing.\n");
+ fprintf(stderr, " Please specify -n \"media=%s;"
+ "nandinfo=<info>\"\n", media);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mtk_image_check_params(struct image_tool_params *params)
+{
+ if (!params->addr) {
+ fprintf(stderr, "Error: Load Address must be set.\n");
+ return -EINVAL;
+ }
+
+ if (!params->imagename) {
+ fprintf(stderr, "Error: Image Name must be set.\n");
+ return -EINVAL;
+ }
+
+ return mtk_brom_parse_imagename(params->imagename);
+}
+
+static int mtk_image_vrec_header(struct image_tool_params *params,
+ struct image_type_params *tparams)
+{
+ if (use_lk_hdr) {
+ tparams->header_size = sizeof(union lk_hdr);
+ tparams->hdr = &hdr_tmp;
+ memset(&hdr_tmp, 0xff, tparams->header_size);
+ return 0;
+ }
+
+ if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
+ tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
+ else
+ tparams->header_size = sizeof(struct gen_device_header);
+
+ tparams->header_size += sizeof(struct gfh_header);
+ tparams->hdr = &hdr_tmp;
+
+ memset(&hdr_tmp, 0xff, tparams->header_size);
+
+ return SHA256_SUM_LEN;
+}
+
+static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
+{
+ union gen_boot_header *gbh = (union gen_boot_header *)ptr;
+ struct brom_layout_header *bh;
+ struct gfh_header *gfh;
+ const char *bootmedia;
+
+ if (!strcmp(gbh->name, SF_BOOT_NAME))
+ bootmedia = "Serial NOR";
+ else if (!strcmp(gbh->name, EMMC_BOOT_NAME))
+ bootmedia = "eMMC";
+ else if (!strcmp(gbh->name, SDMMC_BOOT_NAME))
+ bootmedia = "SD/MMC";
+ else
+ return -1;
+
+ if (print)
+ printf("Boot Media: %s\n", bootmedia);
+
+ if (le32_to_cpu(gbh->version) != 1 ||
+ le32_to_cpu(gbh->size) != sizeof(union gen_boot_header))
+ return -1;
+
+ bh = (struct brom_layout_header *)(ptr + le32_to_cpu(gbh->size));
+
+ if (strcmp(bh->name, BRLYT_NAME))
+ return -1;
+
+ if (le32_to_cpu(bh->magic) != BRLYT_MAGIC ||
+ (le32_to_cpu(bh->type) != BRLYT_TYPE_NOR &&
+ le32_to_cpu(bh->type) != BRLYT_TYPE_EMMC &&
+ le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC))
+ return -1;
+
+ gfh = (struct gfh_header *)(ptr + le32_to_cpu(bh->header_size));
+
+ if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
+ return -1;
+
+ if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN)
+ return -1;
+
+ if (print)
+ printf("Load Address: %08x\n",
+ le32_to_cpu(gfh->file_info.load_addr) +
+ le32_to_cpu(gfh->file_info.jump_offset));
+
+ return 0;
+}
+
+static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
+{
+ union nand_boot_header *nh = (union nand_boot_header *)ptr;
+ struct brom_layout_header *bh;
+ struct gfh_header *gfh;
+ const char *bootmedia;
+
+ if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
+ strcmp(nh->id, NAND_BOOT_ID))
+ return -1;
+
+ bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
+
+ if (strcmp(bh->name, BRLYT_NAME))
+ return -1;
+
+ if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) {
+ return -1;
+ } else {
+ if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
+ bootmedia = "Parallel NAND";
+ else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
+ bootmedia = "Serial NAND";
+ else
+ return -1;
+ }
+
+ if (print) {
+ printf("Boot Media: %s\n", bootmedia);
+
+ if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
+ uint64_t capacity =
+ (uint64_t)le16_to_cpu(nh->numblocks) *
+ (uint64_t)le16_to_cpu(nh->pages_of_block) *
+ (uint64_t)le16_to_cpu(nh->pagesize) * 8;
+ printf("Capacity: %dGb\n",
+ (uint32_t)(capacity >> 30));
+ }
+
+ if (le16_to_cpu(nh->pagesize) >= 1024)
+ printf("Page Size: %dKB\n",
+ le16_to_cpu(nh->pagesize) >> 10);
+ else
+ printf("Page Size: %dB\n",
+ le16_to_cpu(nh->pagesize));
+
+ printf("Spare Size: %dB\n", le16_to_cpu(nh->oobsize));
+ }
+
+ gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
+
+ if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
+ return -1;
+
+ if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND)
+ return -1;
+
+ if (print)
+ printf("Load Address: %08x\n",
+ le32_to_cpu(gfh->file_info.load_addr) +
+ le32_to_cpu(gfh->file_info.jump_offset));
+
+ return 0;
+}
+
+static int mtk_image_verify_header(unsigned char *ptr, int image_size,
+ struct image_tool_params *params)
+{
+ union lk_hdr *lk = (union lk_hdr *)ptr;
+
+ /* nothing to verify for LK image header */
+ if (le32_to_cpu(lk->magic) == LK_PART_MAGIC)
+ return 0;
+
+ if (!strcmp((char *)ptr, NAND_BOOT_NAME))
+ return mtk_image_verify_nand_header(ptr, 0);
+ else
+ return mtk_image_verify_gen_header(ptr, 0);
+
+ return -1;
+}
+
+static void mtk_image_print_header(const void *ptr)
+{
+ union lk_hdr *lk = (union lk_hdr *)ptr;
+
+ if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
+ printf("Image Type: MediaTek LK Image\n");
+ printf("Load Address: %08x\n", le32_to_cpu(lk->loadaddr));
+ return;
+ }
+
+ printf("Image Type: MediaTek BootROM Loadable Image\n");
+
+ if (!strcmp((char *)ptr, NAND_BOOT_NAME))
+ mtk_image_verify_nand_header(ptr, 1);
+ else
+ mtk_image_verify_gen_header(ptr, 1);
+}
+
+static void put_brom_layout_header(struct brom_layout_header *hdr, int type)
+{
+ strncpy(hdr->name, BRLYT_NAME, sizeof(hdr->name));
+ hdr->version = cpu_to_le32(1);
+ hdr->magic = cpu_to_le32(BRLYT_MAGIC);
+ hdr->type = cpu_to_le32(type);
+}
+
+static void put_ghf_common_header(struct gfh_common_header *gfh, int size,
+ int type, int ver)
+{
+ memcpy(gfh->magic, GFH_HEADER_MAGIC, sizeof(gfh->magic));
+ gfh->version = ver;
+ gfh->size = cpu_to_le16(size);
+ gfh->type = cpu_to_le16(type);
+}
+
+static void put_ghf_header(struct gfh_header *gfh, int file_size,
+ int dev_hdr_size, int load_addr, int flash_type)
+{
+ memset(gfh, 0, sizeof(struct gfh_header));
+
+ /* GFH_FILE_INFO header */
+ put_ghf_common_header(&gfh->file_info.gfh, sizeof(gfh->file_info),
+ GFH_TYPE_FILE_INFO, 1);
+ strncpy(gfh->file_info.name, GFH_FILE_INFO_NAME,
+ sizeof(gfh->file_info.name));
+ gfh->file_info.unused = cpu_to_le32(1);
+ gfh->file_info.file_type = cpu_to_le16(1);
+ gfh->file_info.flash_type = flash_type;
+ gfh->file_info.sig_type = GFH_SIG_TYPE_SHA256;
+ gfh->file_info.load_addr = cpu_to_le32(load_addr - sizeof(*gfh));
+ gfh->file_info.total_size = cpu_to_le32(file_size - dev_hdr_size);
+ gfh->file_info.max_size = cpu_to_le32(file_size);
+ gfh->file_info.hdr_size = sizeof(*gfh);
+ gfh->file_info.sig_size = SHA256_SUM_LEN;
+ gfh->file_info.jump_offset = sizeof(*gfh);
+ gfh->file_info.processed = cpu_to_le32(1);
+
+ /* GFH_BL_INFO header */
+ put_ghf_common_header(&gfh->bl_info.gfh, sizeof(gfh->bl_info),
+ GFH_TYPE_BL_INFO, 1);
+ gfh->bl_info.attr = cpu_to_le32(1);
+
+ /* GFH_BROM_CFG header */
+ put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg),
+ GFH_TYPE_BROM_CFG, 3);
+ gfh->brom_cfg.cfg_bits = cpu_to_le32(
+ GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS |
+ GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN |
+ GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN);
+ gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000);
+
+ /* GFH_BL_SEC_KEY header */
+ put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key),
+ GFH_TYPE_BL_SEC_KEY, 1);
+
+ /* GFH_ANTI_CLONE header */
+ put_ghf_common_header(&gfh->anti_clone.gfh, sizeof(gfh->anti_clone),
+ GFH_TYPE_ANTI_CLONE, 1);
+ gfh->anti_clone.ac_offset = cpu_to_le32(0x10);
+ gfh->anti_clone.ac_len = cpu_to_le32(0x80);
+
+ /* GFH_BROM_SEC_CFG header */
+ put_ghf_common_header(&gfh->brom_sec_cfg.gfh,
+ sizeof(gfh->brom_sec_cfg),
+ GFH_TYPE_BROM_SEC_CFG, 1);
+ gfh->brom_sec_cfg.cfg_bits =
+ cpu_to_le32(BROM_SEC_CFG_JTAG_EN | BROM_SEC_CFG_UART_EN);
+}
+
+static void put_hash(uint8_t *buff, int size)
+{
+ sha256_context ctx;
+
+ sha256_starts(&ctx);
+ sha256_update(&ctx, buff, size);
+ sha256_finish(&ctx, buff + size);
+}
+
+static void mtk_image_set_gen_header(void *ptr, off_t filesize,
+ uint32_t loadaddr)
+{
+ struct gen_device_header *hdr = (struct gen_device_header *)ptr;
+ struct gfh_header *gfh;
+ const char *bootname = NULL;
+
+ if (hdr_media == BRLYT_TYPE_NOR)
+ bootname = SF_BOOT_NAME;
+ else if (hdr_media == BRLYT_TYPE_EMMC)
+ bootname = EMMC_BOOT_NAME;
+ else if (hdr_media == BRLYT_TYPE_SDMMC)
+ bootname = SDMMC_BOOT_NAME;
+
+ /* Generic device header */
+ strncpy(hdr->boot.name, bootname, sizeof(hdr->boot.name));
+ hdr->boot.version = cpu_to_le32(1);
+ hdr->boot.size = cpu_to_le32(sizeof(hdr->boot));
+
+ /* BRLYT header */
+ put_brom_layout_header(&hdr->brlyt, hdr_media);
+ hdr->brlyt.header_size = cpu_to_le32(sizeof(struct gen_device_header));
+ hdr->brlyt.total_size = cpu_to_le32(filesize);
+ hdr->brlyt.header_size_2 = hdr->brlyt.header_size;
+ hdr->brlyt.total_size_2 = hdr->brlyt.total_size;
+
+ /* GFH header */
+ gfh = (struct gfh_header *)(ptr + sizeof(struct gen_device_header));
+ put_ghf_header(gfh, filesize, sizeof(struct gen_device_header),
+ loadaddr, GFH_FLASH_TYPE_GEN);
+
+ /* Generate SHA256 hash */
+ put_hash((uint8_t *)gfh,
+ filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN);
+}
+
+static void mtk_image_set_nand_header(void *ptr, off_t filesize,
+ uint32_t loadaddr)
+{
+ union nand_boot_header *nh = (union nand_boot_header *)ptr;
+ struct brom_layout_header *brlyt;
+ struct gfh_header *gfh;
+ uint32_t payload_pages;
+ int i;
+
+ /* NAND device header, repeat 4 times */
+ for (i = 0; i < 4; i++)
+ memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
+
+ /* BRLYT header */
+ payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
+ le16_to_cpu(hdr_nand->pagesize);
+ brlyt = (struct brom_layout_header *)
+ (ptr + le16_to_cpu(hdr_nand->pagesize));
+ put_brom_layout_header(brlyt, hdr_media);
+ brlyt->header_size = cpu_to_le32(2);
+ brlyt->total_size = cpu_to_le32(payload_pages);
+ brlyt->header_size_2 = brlyt->header_size;
+ brlyt->total_size_2 = brlyt->total_size;
+ brlyt->unused = cpu_to_le32(1);
+
+ /* GFH header */
+ gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
+ put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
+ loadaddr, GFH_FLASH_TYPE_NAND);
+
+ /* Generate SHA256 hash */
+ put_hash((uint8_t *)gfh,
+ filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
+}
+
+static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
+ struct image_tool_params *params)
+{
+ union lk_hdr *lk = (union lk_hdr *)ptr;
+
+ if (use_lk_hdr) {
+ lk->magic = cpu_to_le32(LK_PART_MAGIC);
+ lk->size = cpu_to_le32(sbuf->st_size - sizeof(union lk_hdr));
+ lk->loadaddr = cpu_to_le32(params->addr);
+ lk->mode = 0xffffffff; /* must be non-zero */
+ memset(lk->name, 0, sizeof(lk->name));
+ strncpy(lk->name, lk_name, sizeof(lk->name));
+ return;
+ }
+
+ if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
+ mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
+ else
+ mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr);
+}
+
+U_BOOT_IMAGE_TYPE(
+ mtk_image,
+ "MediaTek BootROM Loadable Image support",
+ 0,
+ NULL,
+ mtk_image_check_params,
+ mtk_image_verify_header,
+ mtk_image_print_header,
+ mtk_image_set_header,
+ NULL,
+ mtk_image_check_image_types,
+ NULL,
+ mtk_image_vrec_header
+);
diff --git a/tools/mtk_image.h b/tools/mtk_image.h
new file mode 100644
index 0000000..0a9eab3
--- /dev/null
+++ b/tools/mtk_image.h
@@ -0,0 +1,199 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * MediaTek BootROM header definitions
+ *
+ * Copyright (C) 2018 MediaTek Inc.
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MTK_IMAGE_H
+#define _MTK_IMAGE_H
+
+/* Device header definitions */
+
+/* Header for NOR/SD/eMMC */
+union gen_boot_header {
+ struct {
+ char name[12];
+ __le32 version;
+ __le32 size;
+ };
+
+ uint8_t pad[0x200];
+};
+
+#define EMMC_BOOT_NAME "EMMC_BOOT"
+#define SF_BOOT_NAME "SF_BOOT"
+#define SDMMC_BOOT_NAME "SDMMC_BOOT"
+
+/* Header for NAND */
+union nand_boot_header {
+ struct {
+ char name[12];
+ char version[4];
+ char id[8];
+ __le16 ioif;
+ __le16 pagesize;
+ __le16 addrcycles;
+ __le16 oobsize;
+ __le16 pages_of_block;
+ __le16 numblocks;
+ __le16 writesize_shift;
+ __le16 erasesize_shift;
+ uint8_t dummy[60];
+ uint8_t ecc_parity[28];
+ };
+
+ uint8_t data[0x80];
+};
+
+#define NAND_BOOT_NAME "BOOTLOADER!"
+#define NAND_BOOT_VERSION "V006"
+#define NAND_BOOT_ID "NFIINFO"
+
+/* BootROM layout header */
+struct brom_layout_header {
+ char name[8];
+ __le32 version;
+ __le32 header_size;
+ __le32 total_size;
+ __le32 magic;
+ __le32 type;
+ __le32 header_size_2;
+ __le32 total_size_2;
+ __le32 unused;
+};
+
+#define BRLYT_NAME "BRLYT"
+#define BRLYT_MAGIC 0x42424242
+
+enum brlyt_img_type {
+ BRLYT_TYPE_INVALID = 0,
+ BRLYT_TYPE_NAND = 0x10002,
+ BRLYT_TYPE_EMMC = 0x10005,
+ BRLYT_TYPE_NOR = 0x10007,
+ BRLYT_TYPE_SDMMC = 0x10008,
+ BRLYT_TYPE_SNAND = 0x10009
+};
+
+/* Combined device header for NOR/SD/eMMC */
+struct gen_device_header {
+ union gen_boot_header boot;
+
+ union {
+ struct brom_layout_header brlyt;
+ uint8_t brlyt_pad[0x400];
+ };
+};
+
+/* BootROM header definitions */
+struct gfh_common_header {
+ uint8_t magic[3];
+ uint8_t version;
+ __le16 size;
+ __le16 type;
+};
+
+#define GFH_HEADER_MAGIC "MMM"
+
+#define GFH_TYPE_FILE_INFO 0
+#define GFH_TYPE_BL_INFO 1
+#define GFH_TYPE_BROM_CFG 7
+#define GFH_TYPE_BL_SEC_KEY 3
+#define GFH_TYPE_ANTI_CLONE 2
+#define GFH_TYPE_BROM_SEC_CFG 8
+
+struct gfh_file_info {
+ struct gfh_common_header gfh;
+ char name[12];
+ __le32 unused;
+ __le16 file_type;
+ uint8_t flash_type;
+ uint8_t sig_type;
+ __le32 load_addr;
+ __le32 total_size;
+ __le32 max_size;
+ __le32 hdr_size;
+ __le32 sig_size;
+ __le32 jump_offset;
+ __le32 processed;
+};
+
+#define GFH_FILE_INFO_NAME "FILE_INFO"
+
+#define GFH_FLASH_TYPE_GEN 5
+#define GFH_FLASH_TYPE_NAND 2
+
+#define GFH_SIG_TYPE_NONE 0
+#define GFH_SIG_TYPE_SHA256 1
+
+struct gfh_bl_info {
+ struct gfh_common_header gfh;
+ __le32 attr;
+};
+
+struct gfh_brom_cfg {
+ struct gfh_common_header gfh;
+ __le32 cfg_bits;
+ __le32 usbdl_by_auto_detect_timeout_ms;
+ uint8_t unused[0x48];
+ __le32 usbdl_by_kcol0_timeout_ms;
+ __le32 usbdl_by_flag_timeout_ms;
+ uint32_t pad;
+};
+
+#define GFH_BROM_CFG_USBDL_BY_AUTO_DETECT_TIMEOUT_EN 0x02
+#define GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS 0x10
+#define GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN 0x80
+#define GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN 0x100
+
+struct gfh_bl_sec_key {
+ struct gfh_common_header gfh;
+ uint8_t pad[0x20c];
+};
+
+struct gfh_anti_clone {
+ struct gfh_common_header gfh;
+ uint8_t ac_b2k;
+ uint8_t ac_b2c;
+ uint16_t pad;
+ __le32 ac_offset;
+ __le32 ac_len;
+};
+
+struct gfh_brom_sec_cfg {
+ struct gfh_common_header gfh;
+ __le32 cfg_bits;
+ char customer_name[0x20];
+ __le32 pad;
+};
+
+#define BROM_SEC_CFG_JTAG_EN 1
+#define BROM_SEC_CFG_UART_EN 2
+
+struct gfh_header {
+ struct gfh_file_info file_info;
+ struct gfh_bl_info bl_info;
+ struct gfh_brom_cfg brom_cfg;
+ struct gfh_bl_sec_key bl_sec_key;
+ struct gfh_anti_clone anti_clone;
+ struct gfh_brom_sec_cfg brom_sec_cfg;
+};
+
+/* LK image header */
+
+union lk_hdr {
+ struct {
+ __le32 magic;
+ __le32 size;
+ char name[32];
+ __le32 loadaddr;
+ __le32 mode;
+ };
+
+ uint8_t data[512];
+};
+
+#define LK_PART_MAGIC 0x58881688
+
+#endif /* _MTK_IMAGE_H */