Merge branch 'master' of git://git.denx.de/u-boot-socfpga
authorTom Rini <trini@konsulko.com>
Thu, 29 Nov 2018 21:36:53 +0000 (16:36 -0500)
committerTom Rini <trini@konsulko.com>
Thu, 29 Nov 2018 21:36:53 +0000 (16:36 -0500)
176 files changed:
MAINTAINERS
Makefile
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/dts/Makefile
arch/arm/dts/meson-axg-s400.dts [new file with mode: 0644]
arch/arm/dts/meson-axg.dtsi [new file with mode: 0644]
arch/arm/dts/mt7623.dtsi [new file with mode: 0644]
arch/arm/dts/mt7623n-bananapi-bpi-r2.dts [new file with mode: 0644]
arch/arm/dts/mt7629-rfb-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/mt7629-rfb.dts [new file with mode: 0644]
arch/arm/dts/mt7629.dtsi [new file with mode: 0644]
arch/arm/include/asm/arch-mediatek/gpio.h [new file with mode: 0644]
arch/arm/include/asm/arch-mediatek/misc.h [new file with mode: 0644]
arch/arm/include/asm/arch-meson/axg.h [new file with mode: 0644]
arch/arm/include/asm/arch-meson/boot.h [new file with mode: 0644]
arch/arm/include/asm/arch-meson/clock-axg.h [new file with mode: 0644]
arch/arm/include/asm/arch-meson/clock-gx.h [new file with mode: 0644]
arch/arm/include/asm/arch-meson/clock.h [deleted file]
arch/arm/include/asm/arch-meson/eth.h
arch/arm/include/asm/arch-meson/gx.h
arch/arm/include/asm/arch-meson/mem.h
arch/arm/mach-mediatek/Kconfig [new file with mode: 0644]
arch/arm/mach-mediatek/Makefile [new file with mode: 0644]
arch/arm/mach-mediatek/cpu.c [new file with mode: 0644]
arch/arm/mach-mediatek/init.h [new file with mode: 0644]
arch/arm/mach-mediatek/mt7623/Makefile [new file with mode: 0644]
arch/arm/mach-mediatek/mt7623/init.c [new file with mode: 0644]
arch/arm/mach-mediatek/mt7623/lowlevel_init.S [new file with mode: 0644]
arch/arm/mach-mediatek/mt7623/preloader.h [new file with mode: 0644]
arch/arm/mach-mediatek/mt7629/Makefile [new file with mode: 0644]
arch/arm/mach-mediatek/mt7629/init.c [new file with mode: 0644]
arch/arm/mach-mediatek/mt7629/lowlevel_init.S [new file with mode: 0644]
arch/arm/mach-mediatek/spl.c [new file with mode: 0644]
arch/arm/mach-meson/Kconfig
arch/arm/mach-meson/Makefile
arch/arm/mach-meson/board-axg.c [new file with mode: 0644]
arch/arm/mach-meson/board-common.c [new file with mode: 0644]
arch/arm/mach-meson/board-gx.c [new file with mode: 0644]
arch/arm/mach-meson/board.c [deleted file]
arch/arm/mach-meson/eth.c [deleted file]
arch/arm/mach-meson/sm.c
board/amlogic/khadas-vim/Kconfig [deleted file]
board/amlogic/khadas-vim/MAINTAINERS [deleted file]
board/amlogic/khadas-vim/Makefile [deleted file]
board/amlogic/khadas-vim/README [deleted file]
board/amlogic/khadas-vim/khadas-vim.c [deleted file]
board/amlogic/khadas-vim2/Kconfig [deleted file]
board/amlogic/khadas-vim2/MAINTAINERS [deleted file]
board/amlogic/khadas-vim2/Makefile [deleted file]
board/amlogic/khadas-vim2/README [deleted file]
board/amlogic/khadas-vim2/khadas-vim2.c [deleted file]
board/amlogic/libretech-cc/Kconfig [deleted file]
board/amlogic/libretech-cc/MAINTAINERS [deleted file]
board/amlogic/libretech-cc/Makefile [deleted file]
board/amlogic/libretech-cc/README [deleted file]
board/amlogic/libretech-cc/libretech-cc.c [deleted file]
board/amlogic/nanopi-k2/Kconfig [deleted file]
board/amlogic/nanopi-k2/MAINTAINERS [deleted file]
board/amlogic/nanopi-k2/Makefile [deleted file]
board/amlogic/nanopi-k2/README [deleted file]
board/amlogic/nanopi-k2/nanopi-k2.c [deleted file]
board/amlogic/odroid-c2/Kconfig [deleted file]
board/amlogic/odroid-c2/MAINTAINERS
board/amlogic/odroid-c2/README [deleted file]
board/amlogic/odroid-c2/README.nanopi-k2 [new file with mode: 0644]
board/amlogic/odroid-c2/README.odroid-c2 [new file with mode: 0644]
board/amlogic/odroid-c2/odroid-c2.c
board/amlogic/p212/Kconfig [deleted file]
board/amlogic/p212/MAINTAINERS
board/amlogic/p212/README [deleted file]
board/amlogic/p212/README.khadas-vim [new file with mode: 0644]
board/amlogic/p212/README.libretech-cc [new file with mode: 0644]
board/amlogic/p212/README.p212 [new file with mode: 0644]
board/amlogic/p212/p212.c
board/amlogic/q200/MAINTAINERS [new file with mode: 0644]
board/amlogic/q200/Makefile [new file with mode: 0644]
board/amlogic/q200/README.khadas-vim2 [new file with mode: 0644]
board/amlogic/q200/README.q200 [new file with mode: 0644]
board/amlogic/q200/q200.c [new file with mode: 0644]
board/amlogic/s400/MAINTAINERS [new file with mode: 0644]
board/amlogic/s400/Makefile [new file with mode: 0644]
board/amlogic/s400/README [new file with mode: 0644]
board/amlogic/s400/s400.c [new file with mode: 0644]
board/mediatek/mt7623/Kconfig [new file with mode: 0644]
board/mediatek/mt7623/MAINTAINERS [new file with mode: 0644]
board/mediatek/mt7623/Makefile [new file with mode: 0644]
board/mediatek/mt7623/mt7623_rfb.c [new file with mode: 0644]
board/mediatek/mt7629/Kconfig [new file with mode: 0644]
board/mediatek/mt7629/MAINTAINERS [new file with mode: 0644]
board/mediatek/mt7629/Makefile [new file with mode: 0644]
board/mediatek/mt7629/mt7629_rfb.c [new file with mode: 0644]
common/image.c
configs/khadas-vim2_defconfig
configs/khadas-vim_defconfig
configs/libretech-cc_defconfig
configs/mt7623n_bpir2_defconfig [new file with mode: 0644]
configs/mt7629_rfb_defconfig [new file with mode: 0644]
configs/nanopi-k2_defconfig
configs/odroid-c2_defconfig
configs/p212_defconfig
configs/s400_defconfig [new file with mode: 0644]
doc/README.mediatek [new file with mode: 0644]
drivers/clk/Makefile
drivers/clk/clk_meson.c
drivers/clk/clk_meson_axg.c [new file with mode: 0644]
drivers/clk/mediatek/Makefile [new file with mode: 0644]
drivers/clk/mediatek/clk-mt7623.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mt7629.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mtk.c [new file with mode: 0644]
drivers/clk/mediatek/clk-mtk.h [new file with mode: 0644]
drivers/mmc/Kconfig
drivers/mmc/Makefile
drivers/mmc/meson_gx_mmc.c
drivers/mmc/mtk-sd.c [new file with mode: 0644]
drivers/net/designware.c
drivers/pinctrl/Kconfig
drivers/pinctrl/Makefile
drivers/pinctrl/mediatek/Kconfig [new file with mode: 0644]
drivers/pinctrl/mediatek/Makefile [new file with mode: 0644]
drivers/pinctrl/mediatek/pinctrl-mt7623.c [new file with mode: 0644]
drivers/pinctrl/mediatek/pinctrl-mt7629.c [new file with mode: 0644]
drivers/pinctrl/mediatek/pinctrl-mtk-common.c [new file with mode: 0644]
drivers/pinctrl/mediatek/pinctrl-mtk-common.h [new file with mode: 0644]
drivers/pinctrl/meson/Kconfig
drivers/pinctrl/meson/Makefile
drivers/pinctrl/meson/pinctrl-meson-axg-pmx.c [new file with mode: 0644]
drivers/pinctrl/meson/pinctrl-meson-axg.c [new file with mode: 0644]
drivers/pinctrl/meson/pinctrl-meson-axg.h [new file with mode: 0644]
drivers/pinctrl/meson/pinctrl-meson-gx-pmx.c [new file with mode: 0644]
drivers/pinctrl/meson/pinctrl-meson-gx.h [new file with mode: 0644]
drivers/pinctrl/meson/pinctrl-meson-gxbb.c
drivers/pinctrl/meson/pinctrl-meson-gxl.c
drivers/pinctrl/meson/pinctrl-meson.c
drivers/pinctrl/meson/pinctrl-meson.h
drivers/power/domain/Kconfig
drivers/power/domain/Makefile
drivers/power/domain/mtk-power-domain.c [new file with mode: 0644]
drivers/ram/Makefile
drivers/ram/mediatek/Makefile [new file with mode: 0644]
drivers/ram/mediatek/ddr3-mt7629.c [new file with mode: 0644]
drivers/serial/Kconfig
drivers/serial/Makefile
drivers/serial/serial_mtk.c [new file with mode: 0644]
drivers/timer/Kconfig
drivers/timer/Makefile
drivers/timer/mtk_timer.c [new file with mode: 0644]
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/mtk_wdt.c [new file with mode: 0644]
include/configs/khadas-vim.h [deleted file]
include/configs/khadas-vim2.h [deleted file]
include/configs/libretech-cc.h [deleted file]
include/configs/meson-gx-common.h [deleted file]
include/configs/meson64.h [new file with mode: 0644]
include/configs/mt7623.h [new file with mode: 0644]
include/configs/mt7629.h [new file with mode: 0644]
include/configs/nanopi-k2.h [deleted file]
include/configs/odroid-c2.h [deleted file]
include/configs/p212.h [deleted file]
include/dt-bindings/clock/axg-aoclkc.h [new file with mode: 0644]
include/dt-bindings/clock/axg-audio-clkc.h [new file with mode: 0644]
include/dt-bindings/clock/axg-clkc.h [new file with mode: 0644]
include/dt-bindings/clock/mt7623-clk.h [new file with mode: 0644]
include/dt-bindings/clock/mt7629-clk.h [new file with mode: 0644]
include/dt-bindings/gpio/meson-axg-gpio.h [new file with mode: 0644]
include/dt-bindings/power/mt7623-power.h [new file with mode: 0644]
include/dt-bindings/power/mt7629-power.h [new file with mode: 0644]
include/dt-bindings/reset/amlogic,meson-axg-audio-arb.h [new file with mode: 0644]
include/dt-bindings/reset/amlogic,meson-axg-reset.h [new file with mode: 0644]
include/dt-bindings/reset/axg-aoclkc.h [new file with mode: 0644]
include/image.h
scripts/Makefile.spl
tools/Makefile
tools/mtk_image.c [new file with mode: 0644]
tools/mtk_image.h [new file with mode: 0644]

index abdb6dcdb513aa7182a5509b32249889e6a94cd9..214629e28307b873894d325e888de039a0e00601 100644 (file)
@@ -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
index aeb1c1455b9d77a53b176b3781a43099a6f30e1a..a4b1d1db52419dfe185c1b553f7cac3e18aee08b 100644 (file)
--- 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
index f5d4d3968383c7df41ad7936e5ad501b7814ce9c..96eadb6fd698311e5f4895f62140f621a1cbdbe3 100644 (file)
@@ -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"
index 4b6c5e19356f2c0bef3aff685c736097937455de..c38ef3cb698850197b04adc6a28521b0aee88f7d 100644 (file)
@@ -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
index 55f3fd1b25c445d77aa05335078e2bb51d4194b8..d8be3a30dc49143cf451aeff9cc351b2b9b11c06 100644 (file)
@@ -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 (file)
index 0000000..18778ad
--- /dev/null
@@ -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 (file)
index 0000000..df017db
--- /dev/null
@@ -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 (file)
index 0000000..f50f4ef
--- /dev/null
@@ -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 (file)
index 0000000..84a77fd
--- /dev/null
@@ -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 (file)
index 0000000..1ef5568
--- /dev/null
@@ -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 (file)
index 0000000..a6d28a0
--- /dev/null
@@ -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 (file)
index 0000000..e6052bb
--- /dev/null
@@ -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 (file)
index 0000000..4ea1020
--- /dev/null
@@ -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 (file)
index 0000000..2530e78
--- /dev/null
@@ -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 (file)
index 0000000..d293f2a
--- /dev/null
@@ -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 (file)
index 0000000..a90fe55
--- /dev/null
@@ -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 (file)
index 0000000..1ef88e4
--- /dev/null
@@ -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-gx.h b/arch/arm/include/asm/arch-meson/clock-gx.h
new file mode 100644 (file)
index 0000000..13a2e76
--- /dev/null
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2016 - AmLogic, Inc.
+ * Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com>
+ */
+#ifndef _ARCH_MESON_CLOCK_GX_H_
+#define _ARCH_MESON_CLOCK_GX_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 SCR                            0x2C /* 0x0b offset in data sheet */
+#define TIMEOUT_VALUE                  0x3c /* 0x0f offset in data sheet */
+
+#define HHI_GP0_PLL_CNTL               0x40 /* 0x10 offset in data sheet */
+#define HHI_GP0_PLL_CNTL2              0x44 /* 0x11 offset in data sheet */
+#define HHI_GP0_PLL_CNTL3              0x48 /* 0x12 offset in data sheet */
+#define HHI_GP0_PLL_CNTL4              0x4c /* 0x13 offset in data sheet */
+#define        HHI_GP0_PLL_CNTL5               0x50 /* 0x14 offset in data sheet */
+#define        HHI_GP0_PLL_CNTL1               0x58 /* 0x16 offset in data sheet */
+
+#define        HHI_XTAL_DIVN_CNTL              0xbc /* 0x2f offset in data sheet */
+#define        HHI_TIMER90K                    0xec /* 0x3b offset in data sheet */
+
+#define        HHI_MEM_PD_REG0                 0x100 /* 0x40 offset in data sheet */
+#define        HHI_MEM_PD_REG1                 0x104 /* 0x41 offset in data sheet */
+#define        HHI_VPU_MEM_PD_REG1             0x108 /* 0x42 offset in data sheet */
+#define        HHI_VIID_CLK_DIV                0x128 /* 0x4a offset in data sheet */
+#define        HHI_VIID_CLK_CNTL               0x12c /* 0x4b offset in data sheet */
+
+#define HHI_GCLK_MPEG0                 0x140 /* 0x50 offset in data sheet */
+#define HHI_GCLK_MPEG1                 0x144 /* 0x51 offset in data sheet */
+#define HHI_GCLK_MPEG2                 0x148 /* 0x52 offset in data sheet */
+#define HHI_GCLK_OTHER                 0x150 /* 0x54 offset in data sheet */
+#define HHI_GCLK_AO                    0x154 /* 0x55 offset in data sheet */
+#define HHI_SYS_OSCIN_CNTL             0x158 /* 0x56 offset in data sheet */
+#define HHI_SYS_CPU_CLK_CNTL1          0x15c /* 0x57 offset in data sheet */
+#define HHI_SYS_CPU_RESET_CNTL         0x160 /* 0x58 offset in data sheet */
+#define HHI_VID_CLK_DIV                        0x164 /* 0x59 offset in data sheet */
+
+#define HHI_MPEG_CLK_CNTL              0x174 /* 0x5d offset in data sheet */
+#define HHI_AUD_CLK_CNTL               0x178 /* 0x5e offset in data sheet */
+#define HHI_VID_CLK_CNTL               0x17c /* 0x5f offset in data sheet */
+#define HHI_AUD_CLK_CNTL2              0x190 /* 0x64 offset in data sheet */
+#define HHI_VID_CLK_CNTL2              0x194 /* 0x65 offset in data sheet */
+#define HHI_SYS_CPU_CLK_CNTL0          0x19c /* 0x67 offset in data sheet */
+#define HHI_VID_PLL_CLK_DIV            0x1a0 /* 0x68 offset in data sheet */
+#define HHI_AUD_CLK_CNTL3              0x1a4 /* 0x69 offset in data sheet */
+#define HHI_MALI_CLK_CNTL              0x1b0 /* 0x6c offset in data sheet */
+#define HHI_VPU_CLK_CNTL               0x1bC /* 0x6f offset in data sheet */
+
+#define HHI_HDMI_CLK_CNTL              0x1CC /* 0x73 offset in data sheet */
+#define HHI_VDEC_CLK_CNTL              0x1E0 /* 0x78 offset in data sheet */
+#define HHI_VDEC2_CLK_CNTL             0x1E4 /* 0x79 offset in data sheet */
+#define HHI_VDEC3_CLK_CNTL             0x1E8 /* 0x7a offset in data sheet */
+#define HHI_VDEC4_CLK_CNTL             0x1EC /* 0x7b offset in data sheet */
+#define HHI_HDCP22_CLK_CNTL            0x1F0 /* 0x7c offset in data sheet */
+#define HHI_VAPBCLK_CNTL               0x1F4 /* 0x7d offset in data sheet */
+
+#define HHI_VPU_CLKB_CNTL              0x20C /* 0x83 offset in data sheet */
+#define HHI_USB_CLK_CNTL               0x220 /* 0x88 offset in data sheet */
+#define HHI_32K_CLK_CNTL               0x224 /* 0x89 offset in data sheet */
+#define HHI_GEN_CLK_CNTL               0x228 /* 0x8a offset in data sheet */
+#define HHI_GEN_CLK_CNTL               0x228 /* 0x8a offset in data sheet */
+
+#define HHI_PCM_CLK_CNTL               0x258 /* 0x96 offset in data sheet */
+#define HHI_NAND_CLK_CNTL              0x25C /* 0x97 offset in data sheet */
+#define HHI_SD_EMMC_CLK_CNTL           0x264 /* 0x99 offset in data sheet */
+
+#define HHI_MPLL_CNTL                  0x280 /* 0xa0 offset in data sheet */
+#define HHI_MPLL_CNTL2                 0x284 /* 0xa1 offset in data sheet */
+#define HHI_MPLL_CNTL3                 0x288 /* 0xa2 offset in data sheet */
+#define HHI_MPLL_CNTL4                 0x28C /* 0xa3 offset in data sheet */
+#define HHI_MPLL_CNTL5                 0x290 /* 0xa4 offset in data sheet */
+#define HHI_MPLL_CNTL6                 0x294 /* 0xa5 offset in data sheet */
+#define HHI_MPLL_CNTL7                 0x298 /* 0xa6 offset in data sheet */
+#define HHI_MPLL_CNTL8                 0x29C /* 0xa7 offset in data sheet */
+#define HHI_MPLL_CNTL9                 0x2A0 /* 0xa8 offset in data sheet */
+#define HHI_MPLL_CNTL10                        0x2A4 /* 0xa9 offset in data sheet */
+
+#define HHI_MPLL3_CNTL0                        0x2E0 /* 0xb8 offset in data sheet */
+#define HHI_MPLL3_CNTL1                        0x2E4 /* 0xb9 offset in data sheet */
+#define HHI_VDAC_CNTL0                 0x2F4 /* 0xbd offset in data sheet */
+#define HHI_VDAC_CNTL1                 0x2F8 /* 0xbe offset in data sheet */
+
+#define HHI_SYS_PLL_CNTL               0x300 /* 0xc0 offset in data sheet */
+#define HHI_SYS_PLL_CNTL2              0x304 /* 0xc1 offset in data sheet */
+#define HHI_SYS_PLL_CNTL3              0x308 /* 0xc2 offset in data sheet */
+#define HHI_SYS_PLL_CNTL4              0x30c /* 0xc3 offset in data sheet */
+#define HHI_SYS_PLL_CNTL5              0x310 /* 0xc4 offset in data sheet */
+#define HHI_DPLL_TOP_I                 0x318 /* 0xc6 offset in data sheet */
+#define HHI_DPLL_TOP2_I                        0x31C /* 0xc7 offset in data sheet */
+#define HHI_HDMI_PLL_CNTL              0x320 /* 0xc8 offset in data sheet */
+#define HHI_HDMI_PLL_CNTL2             0x324 /* 0xc9 offset in data sheet */
+#define HHI_HDMI_PLL_CNTL3             0x328 /* 0xca offset in data sheet */
+#define HHI_HDMI_PLL_CNTL4             0x32C /* 0xcb offset in data sheet */
+#define HHI_HDMI_PLL_CNTL5             0x330 /* 0xcc offset in data sheet */
+#define HHI_HDMI_PLL_CNTL6             0x334 /* 0xcd offset in data sheet */
+#define HHI_HDMI_PLL_CNTL_I            0x338 /* 0xce offset in data sheet */
+#define HHI_HDMI_PLL_CNTL7             0x33C /* 0xcf offset in data sheet */
+
+#define HHI_HDMI_PHY_CNTL0             0x3A0 /* 0xe8 offset in data sheet */
+#define HHI_HDMI_PHY_CNTL1             0x3A4 /* 0xe9 offset in data sheet */
+#define HHI_HDMI_PHY_CNTL2             0x3A8 /* 0xea offset in data sheet */
+#define HHI_HDMI_PHY_CNTL3             0x3AC /* 0xeb offset in data sheet */
+
+#define HHI_VID_LOCK_CLK_CNTL          0x3C8 /* 0xf2 offset in data sheet */
+#define HHI_BT656_CLK_CNTL             0x3D4 /* 0xf5 offset in data sheet */
+#define HHI_SAR_CLK_CNTL               0x3D8 /* 0xf6 offset in data sheet */
+
+ulong meson_measure_clk_rate(unsigned int clk);
+
+#endif
diff --git a/arch/arm/include/asm/arch-meson/clock.h b/arch/arm/include/asm/arch-meson/clock.h
deleted file mode 100644 (file)
index c0ff00f..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright 2016 - AmLogic, Inc.
- * Copyright 2018 - Beniamino Galvani <b.galvani@gmail.com>
- */
-#ifndef _ARCH_MESON_CLOCK_H_
-#define _ARCH_MESON_CLOCK_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 SCR                            0x2C /* 0x0b offset in data sheet */
-#define TIMEOUT_VALUE                  0x3c /* 0x0f offset in data sheet */
-
-#define HHI_GP0_PLL_CNTL               0x40 /* 0x10 offset in data sheet */
-#define HHI_GP0_PLL_CNTL2              0x44 /* 0x11 offset in data sheet */
-#define HHI_GP0_PLL_CNTL3              0x48 /* 0x12 offset in data sheet */
-#define HHI_GP0_PLL_CNTL4              0x4c /* 0x13 offset in data sheet */
-#define        HHI_GP0_PLL_CNTL5               0x50 /* 0x14 offset in data sheet */
-#define        HHI_GP0_PLL_CNTL1               0x58 /* 0x16 offset in data sheet */
-
-#define        HHI_XTAL_DIVN_CNTL              0xbc /* 0x2f offset in data sheet */
-#define        HHI_TIMER90K                    0xec /* 0x3b offset in data sheet */
-
-#define        HHI_MEM_PD_REG0                 0x100 /* 0x40 offset in data sheet */
-#define        HHI_MEM_PD_REG1                 0x104 /* 0x41 offset in data sheet */
-#define        HHI_VPU_MEM_PD_REG1             0x108 /* 0x42 offset in data sheet */
-#define        HHI_VIID_CLK_DIV                0x128 /* 0x4a offset in data sheet */
-#define        HHI_VIID_CLK_CNTL               0x12c /* 0x4b offset in data sheet */
-
-#define HHI_GCLK_MPEG0                 0x140 /* 0x50 offset in data sheet */
-#define HHI_GCLK_MPEG1                 0x144 /* 0x51 offset in data sheet */
-#define HHI_GCLK_MPEG2                 0x148 /* 0x52 offset in data sheet */
-#define HHI_GCLK_OTHER                 0x150 /* 0x54 offset in data sheet */
-#define HHI_GCLK_AO                    0x154 /* 0x55 offset in data sheet */
-#define HHI_SYS_OSCIN_CNTL             0x158 /* 0x56 offset in data sheet */
-#define HHI_SYS_CPU_CLK_CNTL1          0x15c /* 0x57 offset in data sheet */
-#define HHI_SYS_CPU_RESET_CNTL         0x160 /* 0x58 offset in data sheet */
-#define HHI_VID_CLK_DIV                        0x164 /* 0x59 offset in data sheet */
-
-#define HHI_MPEG_CLK_CNTL              0x174 /* 0x5d offset in data sheet */
-#define HHI_AUD_CLK_CNTL               0x178 /* 0x5e offset in data sheet */
-#define HHI_VID_CLK_CNTL               0x17c /* 0x5f offset in data sheet */
-#define HHI_AUD_CLK_CNTL2              0x190 /* 0x64 offset in data sheet */
-#define HHI_VID_CLK_CNTL2              0x194 /* 0x65 offset in data sheet */
-#define HHI_SYS_CPU_CLK_CNTL0          0x19c /* 0x67 offset in data sheet */
-#define HHI_VID_PLL_CLK_DIV            0x1a0 /* 0x68 offset in data sheet */
-#define HHI_AUD_CLK_CNTL3              0x1a4 /* 0x69 offset in data sheet */
-#define HHI_MALI_CLK_CNTL              0x1b0 /* 0x6c offset in data sheet */
-#define HHI_VPU_CLK_CNTL               0x1bC /* 0x6f offset in data sheet */
-
-#define HHI_HDMI_CLK_CNTL              0x1CC /* 0x73 offset in data sheet */
-#define HHI_VDEC_CLK_CNTL              0x1E0 /* 0x78 offset in data sheet */
-#define HHI_VDEC2_CLK_CNTL             0x1E4 /* 0x79 offset in data sheet */
-#define HHI_VDEC3_CLK_CNTL             0x1E8 /* 0x7a offset in data sheet */
-#define HHI_VDEC4_CLK_CNTL             0x1EC /* 0x7b offset in data sheet */
-#define HHI_HDCP22_CLK_CNTL            0x1F0 /* 0x7c offset in data sheet */
-#define HHI_VAPBCLK_CNTL               0x1F4 /* 0x7d offset in data sheet */
-
-#define HHI_VPU_CLKB_CNTL              0x20C /* 0x83 offset in data sheet */
-#define HHI_USB_CLK_CNTL               0x220 /* 0x88 offset in data sheet */
-#define HHI_32K_CLK_CNTL               0x224 /* 0x89 offset in data sheet */
-#define HHI_GEN_CLK_CNTL               0x228 /* 0x8a offset in data sheet */
-#define HHI_GEN_CLK_CNTL               0x228 /* 0x8a offset in data sheet */
-
-#define HHI_PCM_CLK_CNTL               0x258 /* 0x96 offset in data sheet */
-#define HHI_NAND_CLK_CNTL              0x25C /* 0x97 offset in data sheet */
-#define HHI_SD_EMMC_CLK_CNTL           0x264 /* 0x99 offset in data sheet */
-
-#define HHI_MPLL_CNTL                  0x280 /* 0xa0 offset in data sheet */
-#define HHI_MPLL_CNTL2                 0x284 /* 0xa1 offset in data sheet */
-#define HHI_MPLL_CNTL3                 0x288 /* 0xa2 offset in data sheet */
-#define HHI_MPLL_CNTL4                 0x28C /* 0xa3 offset in data sheet */
-#define HHI_MPLL_CNTL5                 0x290 /* 0xa4 offset in data sheet */
-#define HHI_MPLL_CNTL6                 0x294 /* 0xa5 offset in data sheet */
-#define HHI_MPLL_CNTL7                 0x298 /* 0xa6 offset in data sheet */
-#define HHI_MPLL_CNTL8                 0x29C /* 0xa7 offset in data sheet */
-#define HHI_MPLL_CNTL9                 0x2A0 /* 0xa8 offset in data sheet */
-#define HHI_MPLL_CNTL10                        0x2A4 /* 0xa9 offset in data sheet */
-
-#define HHI_MPLL3_CNTL0                        0x2E0 /* 0xb8 offset in data sheet */
-#define HHI_MPLL3_CNTL1                        0x2E4 /* 0xb9 offset in data sheet */
-#define HHI_VDAC_CNTL0                 0x2F4 /* 0xbd offset in data sheet */
-#define HHI_VDAC_CNTL1                 0x2F8 /* 0xbe offset in data sheet */
-
-#define HHI_SYS_PLL_CNTL               0x300 /* 0xc0 offset in data sheet */
-#define HHI_SYS_PLL_CNTL2              0x304 /* 0xc1 offset in data sheet */
-#define HHI_SYS_PLL_CNTL3              0x308 /* 0xc2 offset in data sheet */
-#define HHI_SYS_PLL_CNTL4              0x30c /* 0xc3 offset in data sheet */
-#define HHI_SYS_PLL_CNTL5              0x310 /* 0xc4 offset in data sheet */
-#define HHI_DPLL_TOP_I                 0x318 /* 0xc6 offset in data sheet */
-#define HHI_DPLL_TOP2_I                        0x31C /* 0xc7 offset in data sheet */
-#define HHI_HDMI_PLL_CNTL              0x320 /* 0xc8 offset in data sheet */
-#define HHI_HDMI_PLL_CNTL2             0x324 /* 0xc9 offset in data sheet */
-#define HHI_HDMI_PLL_CNTL3             0x328 /* 0xca offset in data sheet */
-#define HHI_HDMI_PLL_CNTL4             0x32C /* 0xcb offset in data sheet */
-#define HHI_HDMI_PLL_CNTL5             0x330 /* 0xcc offset in data sheet */
-#define HHI_HDMI_PLL_CNTL6             0x334 /* 0xcd offset in data sheet */
-#define HHI_HDMI_PLL_CNTL_I            0x338 /* 0xce offset in data sheet */
-#define HHI_HDMI_PLL_CNTL7             0x33C /* 0xcf offset in data sheet */
-
-#define HHI_HDMI_PHY_CNTL0             0x3A0 /* 0xe8 offset in data sheet */
-#define HHI_HDMI_PHY_CNTL1             0x3A4 /* 0xe9 offset in data sheet */
-#define HHI_HDMI_PHY_CNTL2             0x3A8 /* 0xea offset in data sheet */
-#define HHI_HDMI_PHY_CNTL3             0x3AC /* 0xeb offset in data sheet */
-
-#define HHI_VID_LOCK_CLK_CNTL          0x3C8 /* 0xf2 offset in data sheet */
-#define HHI_BT656_CLK_CNTL             0x3D4 /* 0xf5 offset in data sheet */
-#define HHI_SAR_CLK_CNTL               0x3D8 /* 0xf6 offset in data sheet */
-
-ulong meson_measure_clk_rate(unsigned int clk);
-
-#endif
index 1aa0872d53d52f8fcb900d78fdcfebab3b273364..08acc5cbf74a6f1a765f7591c9822e0378e6a3d4 100644 (file)
 #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__ */
index 4bc9475d35e77e4cc867f9abb262247172ead77b..b781ba9475ba9b40486b29b420e6a99aabf2233b 100644 (file)
@@ -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
index 62818335d97b29a18f60b98cafc9b2b288335695..a65100aeb74ba00b4ef04e14bbca8aa4aa064514 100644 (file)
@@ -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 (file)
index 0000000..7a733e9
--- /dev/null
@@ -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 (file)
index 0000000..b5d3a37
--- /dev/null
@@ -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 (file)
index 0000000..b37e299
--- /dev/null
@@ -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 (file)
index 0000000..1d896fb
--- /dev/null
@@ -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 (file)
index 0000000..007eb4a
--- /dev/null
@@ -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 (file)
index 0000000..0ee8c66
--- /dev/null
@@ -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 (file)
index 0000000..afb9476
--- /dev/null
@@ -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 (file)
index 0000000..2d2c71a
--- /dev/null
@@ -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 (file)
index 0000000..007eb4a
--- /dev/null
@@ -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 (file)
index 0000000..ba91a6e
--- /dev/null
@@ -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 (file)
index 0000000..90dd4ea
--- /dev/null
@@ -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 (file)
index 0000000..9b3590f
--- /dev/null
@@ -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
+}
index cc943443b3a9b962eb29157e1cc69b5a15879e5c..11077bc6cc24ccf4c74c575192b2ef415430a4ba 100644 (file)
@@ -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
index 8ad9b3e575e31b12b96240a5cb344967ee9b5dcf..b716e1a152903ae6922284455e35543a9827b35e 100644 (file)
@@ -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 (file)
index 0000000..173905e
--- /dev/null
@@ -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 (file)
index 0000000..8c41301
--- /dev/null
@@ -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-gx.c b/arch/arm/mach-meson/board-gx.c
new file mode 100644 (file)
index 0000000..e41552d
--- /dev/null
@@ -0,0 +1,138 @@
+// 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/gx.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(GX_AO_SEC_GP_CFG0) & GX_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(GX_AO_SEC_GP_CFG3);
+
+       bl31_size = ((reg & GX_AO_BL31_RSVMEM_SIZE_MASK)
+                       >> GX_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
+       bl32_size = (reg & GX_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
+
+       bl31_start = readl(GX_AO_SEC_GP_CFG5);
+       bl32_start = readl(GX_AO_SEC_GP_CFG4);
+
+       /*
+        * Early Meson GX Firmware revisions did not provide the reserved
+        * memory zones in the registers, keep fixed memory zone handling.
+        */
+       if (IS_ENABLED(CONFIG_MESON_GX) &&
+           !reg && !bl31_start && !bl32_start) {
+               bl31_start = 0x10000000;
+               bl31_size = 0x200000;
+       }
+
+       /* Add first 16MiB reserved zone */
+       meson_board_add_reserved_memory(fdt, 0, GX_FIRMWARE_MEM_SIZE);
+
+       /* 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(GX_AO_SEC_GP_CFG0) & GX_AO_MEM_SIZE_MASK)
+                       >> GX_AO_MEM_SIZE_SHIFT) * SZ_1M;
+}
+
+static struct mm_region gx_mem_map[] = {
+       {
+               .virt = 0x0UL,
+               .phys = 0x0UL,
+               .size = 0xc0000000UL,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+                        PTE_BLOCK_INNER_SHARE
+       }, {
+               .virt = 0xc0000000UL,
+               .phys = 0xc0000000UL,
+               .size = 0x30000000UL,
+               .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 = 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/board.c b/arch/arm/mach-meson/board.c
deleted file mode 100644 (file)
index d6c6253..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
- */
-
-#include <common.h>
-#include <linux/libfdt.h>
-#include <linux/err.h>
-#include <asm/arch/gx.h>
-#include <asm/arch/sm.h>
-#include <asm/armv8/mmu.h>
-#include <asm/unaligned.h>
-#include <linux/sizes.h>
-#include <efi_loader.h>
-#include <asm/io.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)
-{
-       /* 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 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)
-{
-       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(GX_AO_SEC_GP_CFG3);
-
-       bl31_size = ((reg & GX_AO_BL31_RSVMEM_SIZE_MASK)
-                       >> GX_AO_BL31_RSVMEM_SIZE_SHIFT) * SZ_1K;
-       bl32_size = (reg & GX_AO_BL32_RSVMEM_SIZE_MASK) * SZ_1K;
-
-       bl31_start = readl(GX_AO_SEC_GP_CFG5);
-       bl32_start = readl(GX_AO_SEC_GP_CFG4);
-
-       /*
-        * Early Meson GX Firmware revisions did not provide the reserved
-        * memory zones in the registers, keep fixed memory zone handling.
-        */
-       if (IS_ENABLED(CONFIG_MESON_GX) &&
-           !reg && !bl31_start && !bl32_start) {
-               bl31_start = 0x10000000;
-               bl31_size = 0x200000;
-       }
-
-       /* Add first 16MiB reserved zone */
-       meson_board_add_reserved_memory(fdt, 0, GX_FIRMWARE_MEM_SIZE);
-
-       /* 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);
-}
-
-void reset_cpu(ulong addr)
-{
-       psci_system_reset();
-}
-
-static struct mm_region gx_mem_map[] = {
-       {
-               .virt = 0x0UL,
-               .phys = 0x0UL,
-               .size = 0xc0000000UL,
-               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
-                        PTE_BLOCK_INNER_SHARE
-       }, {
-               .virt = 0xc0000000UL,
-               .phys = 0xc0000000UL,
-               .size = 0x30000000UL,
-               .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 = gx_mem_map;
diff --git a/arch/arm/mach-meson/eth.c b/arch/arm/mach-meson/eth.c
deleted file mode 100644 (file)
index 8b28bc8..0000000
+++ /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);
-}
index 0bba5e4a0733145bb2ae17451e03eb2323e6c581..a07b46895d8b56c24ffece54543de853b3a095ca 100644 (file)
@@ -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 (file)
index 0fa8db9..0000000
+++ /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 (file)
index 024220a..0000000
+++ /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/Makefile b/board/amlogic/khadas-vim/Makefile
deleted file mode 100644 (file)
index 558c076..0000000
+++ /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  := khadas-vim.o
diff --git a/board/amlogic/khadas-vim/README b/board/amlogic/khadas-vim/README
deleted file mode 100644 (file)
index b194236..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-U-Boot for Khadas VIM
-=======================
-
-Khadas VIM is an Open Source DIY Box manufactured by Shenzhen Wesion
-Technology Co., Ltd with the following specifications:
-
- - Amlogic S905X ARM Cortex-A53 quad-core SoC @ 1.5GHz
- - ARM Mali 450 GPU
- - 2GB DDR3 SDRAM
- - 10/100 Ethernet
- - HDMI 2.0 4K/60Hz display
- - 40-pin GPIO header
- - 2 x USB 2.0 Host, 1 x USB 2.0 Type-C OTG
- - 8GB/16GBeMMC
- - microSD
- - SDIO Wifi Module, Bluetooth
- - Two channels 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-vim_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/khadas/u-boot -b Vim vim-u-boot
- > cd vim-u-boot
- > make kvim_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-vim/khadas-vim.c b/board/amlogic/khadas-vim/khadas-vim.c
deleted file mode 100644 (file)
index 692bf2a..0000000
+++ /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 (file)
index d0af362..0000000
+++ /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/khadas-vim2/MAINTAINERS b/board/amlogic/khadas-vim2/MAINTAINERS
deleted file mode 100644 (file)
index ca63e31..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-KHADAS-VIM2
-M:     Neil Armstrong <narmstrong@baylibre.com>
-S:     Maintained
-F:     board/amlogic/khadas-vim2/
-F:     include/configs/khadas-vim2.h
-F:     configs/khadas-vim2_defconfig
diff --git a/board/amlogic/khadas-vim2/Makefile b/board/amlogic/khadas-vim2/Makefile
deleted file mode 100644 (file)
index 4e7c9a0..0000000
+++ /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  := khadas-vim2.o
diff --git a/board/amlogic/khadas-vim2/README b/board/amlogic/khadas-vim2/README
deleted file mode 100644 (file)
index 578693f..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-U-Boot for Khadas VIM2
-=======================
-
-Khadas VIM2 is an Open Source DIY Box manufactured by Shenzhen Wesion
-Technology Co., Ltd 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
- - 40-pin GPIO header
- - 2 x USB 2.0 Host, 1 x USB 2.0 Type-C OTG
- - 16GB/32GB/64GB eMMC
- - 2MB SPI Flash
- - microSD
- - SDIO Wifi Module, Bluetooth
- - Two channels 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/khadas/u-boot -b Vim vim-u-boot
- > cd vim-u-boot
- > make kvim_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/khadas-vim2/khadas-vim2.c
deleted file mode 100644 (file)
index ff56569..0000000
+++ /dev/null
@@ -1,62 +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_RGMII, 0);
-
-       /* Reset PHY on GPIOZ_14 */
-       clrbits_le32(GX_GPIO_EN(3), BIT(14));
-       clrbits_le32(GX_GPIO_OUT(3), BIT(14));
-       mdelay(10);
-       setbits_le32(GX_GPIO_OUT(3), BIT(14));
-
-       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/libretech-cc/Kconfig b/board/amlogic/libretech-cc/Kconfig
deleted file mode 100644 (file)
index 7a6f916..0000000
+++ /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 (file)
index 398ce57..0000000
+++ /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 (file)
index 3b0adf8..0000000
+++ /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/README b/board/amlogic/libretech-cc/README
deleted file mode 100644 (file)
index d007f58..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-U-Boot for LibreTech CC
-=======================
-
-LibreTech CC is a single board computer manufactured by Libre Technology
-with the following specifications:
-
- - Amlogic S905X ARM Cortex-A53 quad-core SoC @ 1.5GHz
- - ARM Mali 450 GPU
- - 2GB DDR3 SDRAM
- - 10/100 Ethernet
- - HDMI 2.0 4K/60Hz display
- - 40-pin GPIO header
- - 4 x USB 2.0 Host
- - eMMC, microSD
- - Infrared receiver
-
-Schematics are available on the manufacturer website.
-
-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 libretech-cc_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 libretech-cc amlogic-u-boot
- > cd amlogic-u-boot
- > make libretech_cc_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
-
- > $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/libretech-cc/libretech-cc.c b/board/amlogic/libretech-cc/libretech-cc.c
deleted file mode 100644 (file)
index ccab127..0000000
+++ /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 (file)
index 374bda2..0000000
+++ /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 (file)
index 0452bd1..0000000
+++ /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 (file)
index 7d9b666..0000000
+++ /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/README b/board/amlogic/nanopi-k2/README
deleted file mode 100644 (file)
index d450d3c..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-U-Boot for NanoPi-K2
-====================
-
-NanoPi-K2 is a single board computer manufactured by FriendlyElec
-with the following specifications:
-
- - Amlogic S905 ARM Cortex-A53 quad-core SoC @ 1.5GHz
- - ARM Mali 450 GPU
- - 2GB DDR3 SDRAM
- - Gigabit Ethernet
- - HDMI 2.0 4K/60Hz display
- - 40-pin GPIO header
- - 4 x USB 2.0 Host, 1 x USB OTG
- - eMMC, microSD
- - Infrared receiver
-
-Schematics are available on the manufacturer website.
-
-Currently the u-boot port supports the following devices:
- - serial
- - eMMC, microSD
- - Ethernet
-
-u-boot compilation
-==================
-
- > export ARCH=arm
- > export CROSS_COMPILE=aarch64-none-elf-
- > make nanopi-k2_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 libretech-cc amlogic-u-boot
- > git clone https://github.com/friendlyarm/u-boot.git -b nanopi-k2-v2015.01 amlogic-u-boot
- > cd amlogic-u-boot
- > sed -i 's/aarch64-linux-gnu-/aarch64-none-elf-/' Makefile
- > sed -i 's/arm-linux-/arm-none-eabi-/' arch/arm/cpu/armv8/gxb/firmware/scp_task/Makefile
- > make nanopi-k2_defconfig
- > make
- > export FIPDIR=$PWD/fip
-
-Go back to mainline U-Boot source tree then :
- > mkdir fip
-
- > cp $FIPDIR/gxb/bl2.bin fip/
- > cp $FIPDIR/gxb/acs.bin fip/
- > cp $FIPDIR/gxb/bl21.bin fip/
- > cp $FIPDIR/gxb/bl30.bin fip/
- > cp $FIPDIR/gxb/bl301.bin fip/
- > cp $FIPDIR/gxb/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/fip_create \
-        --bl30 fip/bl30_new.bin \
-        --bl31 fip/bl31.img \
-        --bl33 fip/bl33.bin \
-        fip/fip.bin
-
- > 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
-
- > cat fip/bl2_new.bin fip/fip.bin > fip/boot_new.bin
-
- > $FIPDIR/gxb/aml_encrypt_gxb --bootsig \
-               --input fip/boot_new.bin
-               --output fip/u-boot.bin
-
-and then write the image to SD with:
-
- > DEV=/dev/your_sd_device
- > dd if=fip/u-boot.bin of=$DEV conv=fsync,notrunc bs=512 seek=1
diff --git a/board/amlogic/nanopi-k2/nanopi-k2.c b/board/amlogic/nanopi-k2/nanopi-k2.c
deleted file mode 100644 (file)
index ae29dd6..0000000
+++ /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 (file)
index 2b16889..0000000
+++ /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
index 699850fd0ca5be4ca175a97bca29f849074aaa9b..6a853066d7815cab96aad1d7e9709229dd43d4b7 100644 (file)
@@ -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/odroid-c2/README b/board/amlogic/odroid-c2/README
deleted file mode 100644 (file)
index bed48c5..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-U-Boot for ODROID-C2
-====================
-
-ODROID-C2 is a single board computer manufactured by Hardkernel
-Co. Ltd with the following specifications:
-
- - Amlogic S905 ARM Cortex-A53 quad-core SoC @ 2GHz
- - ARM Mali 450 GPU
- - 2GB DDR3 SDRAM
- - Gigabit Ethernet
- - HDMI 2.0 4K/60Hz display
- - 40-pin GPIO header
- - 4 x USB 2.0 Host, 1 x USB OTG
- - eMMC, microSD
- - Infrared receiver
-
-Schematics are available on the manufacturer website.
-
-Currently the u-boot port supports the following devices:
- - serial
- - eMMC, microSD
- - Ethernet
- - I2C
- - Regulators
- - Reset controller
- - Clock controller
- - ADC
-
-u-boot compilation
-==================
-
- > export ARCH=arm
- > export CROSS_COMPILE=aarch64-none-elf-
- > make odroid-c2_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:
-
- > DIR=odroid-c2
- > git clone --depth 1 \
-       https://github.com/hardkernel/u-boot.git -b odroidc2-v2015.01 \
-       $DIR
- > $DIR/fip/fip_create --bl30  $DIR/fip/gxb/bl30.bin \
-                       --bl301 $DIR/fip/gxb/bl301.bin \
-                       --bl31  $DIR/fip/gxb/bl31.bin \
-                       --bl33  u-boot.bin \
-                       $DIR/fip.bin
- > $DIR/fip/fip_create --dump $DIR/fip.bin
- > cat $DIR/fip/gxb/bl2.package $DIR/fip.bin > $DIR/boot_new.bin
- > $DIR/fip/gxb/aml_encrypt_gxb --bootsig \
-                                --input $DIR/boot_new.bin \
-                                --output $DIR/u-boot.img
- > dd if=$DIR/u-boot.img of=$DIR/u-boot.gxbb bs=512 skip=96
-
-and then write the image to SD with:
-
- > DEV=/dev/your_sd_device
- > BL1=$DIR/sd_fuse/bl1.bin.hardkernel
- > dd if=$BL1 of=$DEV conv=fsync bs=1 count=442
- > dd if=$BL1 of=$DEV conv=fsync bs=512 skip=1 seek=1
- > dd if=$DIR/u-boot.gxbb of=$DEV conv=fsync bs=512 seek=97
diff --git a/board/amlogic/odroid-c2/README.nanopi-k2 b/board/amlogic/odroid-c2/README.nanopi-k2
new file mode 100644 (file)
index 0000000..d450d3c
--- /dev/null
@@ -0,0 +1,99 @@
+U-Boot for NanoPi-K2
+====================
+
+NanoPi-K2 is a single board computer manufactured by FriendlyElec
+with the following specifications:
+
+ - Amlogic S905 ARM Cortex-A53 quad-core SoC @ 1.5GHz
+ - ARM Mali 450 GPU
+ - 2GB DDR3 SDRAM
+ - Gigabit Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 40-pin GPIO header
+ - 4 x USB 2.0 Host, 1 x USB OTG
+ - eMMC, microSD
+ - Infrared receiver
+
+Schematics are available on the manufacturer website.
+
+Currently the u-boot port supports the following devices:
+ - serial
+ - eMMC, microSD
+ - Ethernet
+
+u-boot compilation
+==================
+
+ > export ARCH=arm
+ > export CROSS_COMPILE=aarch64-none-elf-
+ > make nanopi-k2_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 libretech-cc amlogic-u-boot
+ > git clone https://github.com/friendlyarm/u-boot.git -b nanopi-k2-v2015.01 amlogic-u-boot
+ > cd amlogic-u-boot
+ > sed -i 's/aarch64-linux-gnu-/aarch64-none-elf-/' Makefile
+ > sed -i 's/arm-linux-/arm-none-eabi-/' arch/arm/cpu/armv8/gxb/firmware/scp_task/Makefile
+ > make nanopi-k2_defconfig
+ > make
+ > export FIPDIR=$PWD/fip
+
+Go back to mainline U-Boot source tree then :
+ > mkdir fip
+
+ > cp $FIPDIR/gxb/bl2.bin fip/
+ > cp $FIPDIR/gxb/acs.bin fip/
+ > cp $FIPDIR/gxb/bl21.bin fip/
+ > cp $FIPDIR/gxb/bl30.bin fip/
+ > cp $FIPDIR/gxb/bl301.bin fip/
+ > cp $FIPDIR/gxb/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/fip_create \
+        --bl30 fip/bl30_new.bin \
+        --bl31 fip/bl31.img \
+        --bl33 fip/bl33.bin \
+        fip/fip.bin
+
+ > 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
+
+ > cat fip/bl2_new.bin fip/fip.bin > fip/boot_new.bin
+
+ > $FIPDIR/gxb/aml_encrypt_gxb --bootsig \
+               --input fip/boot_new.bin
+               --output fip/u-boot.bin
+
+and then write the image to SD with:
+
+ > DEV=/dev/your_sd_device
+ > dd if=fip/u-boot.bin of=$DEV conv=fsync,notrunc bs=512 seek=1
diff --git a/board/amlogic/odroid-c2/README.odroid-c2 b/board/amlogic/odroid-c2/README.odroid-c2
new file mode 100644 (file)
index 0000000..bed48c5
--- /dev/null
@@ -0,0 +1,66 @@
+U-Boot for ODROID-C2
+====================
+
+ODROID-C2 is a single board computer manufactured by Hardkernel
+Co. Ltd with the following specifications:
+
+ - Amlogic S905 ARM Cortex-A53 quad-core SoC @ 2GHz
+ - ARM Mali 450 GPU
+ - 2GB DDR3 SDRAM
+ - Gigabit Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 40-pin GPIO header
+ - 4 x USB 2.0 Host, 1 x USB OTG
+ - eMMC, microSD
+ - Infrared receiver
+
+Schematics are available on the manufacturer website.
+
+Currently the u-boot port supports the following devices:
+ - serial
+ - eMMC, microSD
+ - Ethernet
+ - I2C
+ - Regulators
+ - Reset controller
+ - Clock controller
+ - ADC
+
+u-boot compilation
+==================
+
+ > export ARCH=arm
+ > export CROSS_COMPILE=aarch64-none-elf-
+ > make odroid-c2_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:
+
+ > DIR=odroid-c2
+ > git clone --depth 1 \
+       https://github.com/hardkernel/u-boot.git -b odroidc2-v2015.01 \
+       $DIR
+ > $DIR/fip/fip_create --bl30  $DIR/fip/gxb/bl30.bin \
+                       --bl301 $DIR/fip/gxb/bl301.bin \
+                       --bl31  $DIR/fip/gxb/bl31.bin \
+                       --bl33  u-boot.bin \
+                       $DIR/fip.bin
+ > $DIR/fip/fip_create --dump $DIR/fip.bin
+ > cat $DIR/fip/gxb/bl2.package $DIR/fip.bin > $DIR/boot_new.bin
+ > $DIR/fip/gxb/aml_encrypt_gxb --bootsig \
+                                --input $DIR/boot_new.bin \
+                                --output $DIR/u-boot.img
+ > dd if=$DIR/u-boot.img of=$DIR/u-boot.gxbb bs=512 skip=96
+
+and then write the image to SD with:
+
+ > DEV=/dev/your_sd_device
+ > BL1=$DIR/sd_fuse/bl1.bin.hardkernel
+ > dd if=$BL1 of=$DEV conv=fsync bs=1 count=442
+ > dd if=$BL1 of=$DEV conv=fsync bs=512 skip=1 seek=1
+ > dd if=$DIR/u-boot.gxbb of=$DEV conv=fsync bs=512 seek=97
index 2a2755c387362cb6c6e018bb8c232bd23d97e1c4..62f0f4c8718577c342d33499020bce7491a55a3c 100644 (file)
 #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 (file)
index 720c92b..0000000
+++ /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
index 6575f17e1434028b2ae600c36460a9956a21a6e2..07ca6f204d500894b3728c31f32e544d4cba3dcc 100644 (file)
@@ -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/p212/README b/board/amlogic/p212/README
deleted file mode 100644 (file)
index ef5370c..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-U-Boot for Amlogic P212
-=======================
-
-P212 is a reference board manufactured by Amlogic with the following
-specifications:
-
- - Amlogic S905X ARM Cortex-A53 quad-core SoC @ 1.5GHz
- - ARM Mali 450 GPU
- - 2GB DDR3 SDRAM
- - 10/100 Ethernet
- - HDMI 2.0 4K/60Hz display
- - 2 x USB 2.0 Host
- - eMMC, microSD
- - Infrared receiver
- - SDIO WiFi Module
- - CVBS+Stereo Audio Jack
-
-Schematics are available from Amlogic on demand.
-
-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 p212_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 gxl_p212_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
-
- > $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/p212/README.khadas-vim b/board/amlogic/p212/README.khadas-vim
new file mode 100644 (file)
index 0000000..b194236
--- /dev/null
@@ -0,0 +1,102 @@
+U-Boot for Khadas VIM
+=======================
+
+Khadas VIM is an Open Source DIY Box manufactured by Shenzhen Wesion
+Technology Co., Ltd with the following specifications:
+
+ - Amlogic S905X ARM Cortex-A53 quad-core SoC @ 1.5GHz
+ - ARM Mali 450 GPU
+ - 2GB DDR3 SDRAM
+ - 10/100 Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 40-pin GPIO header
+ - 2 x USB 2.0 Host, 1 x USB 2.0 Type-C OTG
+ - 8GB/16GBeMMC
+ - microSD
+ - SDIO Wifi Module, Bluetooth
+ - Two channels 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-vim_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/khadas/u-boot -b Vim vim-u-boot
+ > cd vim-u-boot
+ > make kvim_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/p212/README.libretech-cc b/board/amlogic/p212/README.libretech-cc
new file mode 100644 (file)
index 0000000..d007f58
--- /dev/null
@@ -0,0 +1,102 @@
+U-Boot for LibreTech CC
+=======================
+
+LibreTech CC is a single board computer manufactured by Libre Technology
+with the following specifications:
+
+ - Amlogic S905X ARM Cortex-A53 quad-core SoC @ 1.5GHz
+ - ARM Mali 450 GPU
+ - 2GB DDR3 SDRAM
+ - 10/100 Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 40-pin GPIO header
+ - 4 x USB 2.0 Host
+ - eMMC, microSD
+ - Infrared receiver
+
+Schematics are available on the manufacturer website.
+
+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 libretech-cc_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 libretech-cc amlogic-u-boot
+ > cd amlogic-u-boot
+ > make libretech_cc_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
+
+ > $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/p212/README.p212 b/board/amlogic/p212/README.p212
new file mode 100644 (file)
index 0000000..ef5370c
--- /dev/null
@@ -0,0 +1,103 @@
+U-Boot for Amlogic P212
+=======================
+
+P212 is a reference board manufactured by Amlogic with the following
+specifications:
+
+ - Amlogic S905X ARM Cortex-A53 quad-core SoC @ 1.5GHz
+ - ARM Mali 450 GPU
+ - 2GB DDR3 SDRAM
+ - 10/100 Ethernet
+ - HDMI 2.0 4K/60Hz display
+ - 2 x USB 2.0 Host
+ - eMMC, microSD
+ - Infrared receiver
+ - SDIO WiFi Module
+ - CVBS+Stereo Audio Jack
+
+Schematics are available from Amlogic on demand.
+
+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 p212_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 gxl_p212_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
+
+ > $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
index 00e07d77ad405d93eea880601ed75560a0db4e00..546c4d9c86d0e5bd39cf3a13fc175d598d0edb55 100644 (file)
 #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/q200/MAINTAINERS b/board/amlogic/q200/MAINTAINERS
new file mode 100644 (file)
index 0000000..be86386
--- /dev/null
@@ -0,0 +1,6 @@
+Q200
+M:     Neil Armstrong <narmstrong@baylibre.com>
+S:     Maintained
+F:     board/amlogic/q200/
+F:     include/configs/q200.h
+F:     configs/khadas-vim2_defconfig
diff --git a/board/amlogic/q200/Makefile b/board/amlogic/q200/Makefile
new file mode 100644 (file)
index 0000000..fd78fd0
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2016 BayLibre, SAS
+# Author: Neil Armstrong <narmstrong@baylibre.com>
+
+obj-y  := q200.o
diff --git a/board/amlogic/q200/README.khadas-vim2 b/board/amlogic/q200/README.khadas-vim2
new file mode 100644 (file)
index 0000000..578693f
--- /dev/null
@@ -0,0 +1,103 @@
+U-Boot for Khadas VIM2
+=======================
+
+Khadas VIM2 is an Open Source DIY Box manufactured by Shenzhen Wesion
+Technology Co., Ltd 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
+ - 40-pin GPIO header
+ - 2 x USB 2.0 Host, 1 x USB 2.0 Type-C OTG
+ - 16GB/32GB/64GB eMMC
+ - 2MB SPI Flash
+ - microSD
+ - SDIO Wifi Module, Bluetooth
+ - Two channels 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/khadas/u-boot -b Vim vim-u-boot
+ > cd vim-u-boot
+ > make kvim_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/q200/README.q200 b/board/amlogic/q200/README.q200
new file mode 100644 (file)
index 0000000..55d730a
--- /dev/null
@@ -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/q200/q200.c b/board/amlogic/q200/q200.c
new file mode 100644 (file)
index 0000000..6db1b26
--- /dev/null
@@ -0,0 +1,50 @@
+// 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 misc_init_r(void)
+{
+       u8 mac_addr[EFUSE_MAC_SIZE];
+       char serial[EFUSE_SN_SIZE];
+       ssize_t len;
+
+       meson_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
+
+       /* Reset PHY on GPIOZ_14 */
+       clrbits_le32(GX_GPIO_EN(3), BIT(14));
+       clrbits_le32(GX_GPIO_OUT(3), BIT(14));
+       mdelay(10);
+       setbits_le32(GX_GPIO_OUT(3), BIT(14));
+
+       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;
+}
diff --git a/board/amlogic/s400/MAINTAINERS b/board/amlogic/s400/MAINTAINERS
new file mode 100644 (file)
index 0000000..9ca9836
--- /dev/null
@@ -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/s400/Makefile b/board/amlogic/s400/Makefile
new file mode 100644 (file)
index 0000000..bf03862
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2016 BayLibre, SAS
+# Author: Neil Armstrong <narmstrong@baylibre.com>
+
+obj-y  := s400.o
diff --git a/board/amlogic/s400/README b/board/amlogic/s400/README
new file mode 100644 (file)
index 0000000..ab21998
--- /dev/null
@@ -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 (file)
index 0000000..02a0e92
--- /dev/null
@@ -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 (file)
index 0000000..a8c670e
--- /dev/null
@@ -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 (file)
index 0000000..eeb0375
--- /dev/null
@@ -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 (file)
index 0000000..2b42071
--- /dev/null
@@ -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 (file)
index 0000000..08468b5
--- /dev/null
@@ -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 (file)
index 0000000..6055164
--- /dev/null
@@ -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 (file)
index 0000000..424f115
--- /dev/null
@@ -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 (file)
index 0000000..83ccbba
--- /dev/null
@@ -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 (file)
index 0000000..08468b5
--- /dev/null
@@ -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;
+}
index 1c3a7720cbc8eb6bb0c777c7da812566862a94cf..0659133fccfb352bb2f54fcea9ddaf0a9652744c 100644 (file)
@@ -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,                 "",           "",                   },
 };
 
index 4bbccc2f3440c8e6ef359fc705bb85fe88f6dadd..6fe861c0e5336d2b3cc9add2589be60e40ad928f 100644 (file)
@@ -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"
index 0c89d9a22cd784ac0fbdb98b394bb359d43bbaae..6e855dd6eb6237ee25f518e53052d63e48edc677 100644 (file)
@@ -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"
index 36d117c4ab9f68fbb082999d35931992144bdb09..c2f985fcfbbb7c536f07cca7b0ac3da708012d73 100644 (file)
@@ -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 (file)
index 0000000..3a4de72
--- /dev/null
@@ -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 (file)
index 0000000..1729d13
--- /dev/null
@@ -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
index 5c8c747bf34176c1ed5a1a6ed1bd188900c426b7..8bbf48f41f7dd922fbe0c410a75be5b7c2c0fabb 100644 (file)
@@ -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"
index 19196b35852a24fc62effe95585d885074a18301..68554ba74533df5984a5034ef2c4f82c06ce0c3b 100644 (file)
@@ -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"
index 9e3b1d6bfb836820e22934a61c137d1ded28e531..a15064da81f52f641f084cbd7f1836e9f4ca9feb 100644 (file)
@@ -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 (file)
index 0000000..1bd4b71
--- /dev/null
@@ -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 (file)
index 0000000..246579d
--- /dev/null
@@ -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
index 821b5867e8757d03a926f314519dc59f6540d261..9acbb1a6500fba4c74f5b3bca9b192541a493e24 100644 (file)
@@ -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/
index c44858822d1aea95b278fde668fb8943ef6579c8..0df8b91d42533b1f6d041d9c4960afc35381db4d 100644 (file)
@@ -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 (file)
index 0000000..32cbf75
--- /dev/null
@@ -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 (file)
index 0000000..0632dc8
--- /dev/null
@@ -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 (file)
index 0000000..c6b09d8
--- /dev/null
@@ -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 (file)
index 0000000..2601b6c
--- /dev/null
@@ -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 (file)
index 0000000..870b14e
--- /dev/null
@@ -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 (file)
index 0000000..74152ed
--- /dev/null
@@ -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 */
index 3f7458d409975d82925dd57c7fbef7afa06b9bb7..fbd13964a0842b9a40963a2b8511876f69281956 100644 (file)
@@ -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
index 23c5b0daef6d7484af2200b14936adff3b772561..801a26d82192de4317f8640b996e6e4b777d24f9 100644 (file)
@@ -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
index 332f1e12a58377dfcb8a7e8b963e9643e17265c0..767dfff8055d2995aeb01b80dd773ad8fb4b8004 100644 (file)
@@ -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 (file)
index 0000000..0741a52
--- /dev/null
@@ -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),
+};
index 19db0a8114ae8bc0c37766f294486ea64980ad0b..4fa26abc1b870277d9f461b862a8ab7edbcc2364 100644 (file)
@@ -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" },
        { }
 };
index ad0b8daba622e30024a45b49d89abe7c676c2f2c..7e6fad305aebc1d6fe6e15d352cba8e7c40814b2 100644 (file)
@@ -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"
index a3a6c6d163b3d04a19a8b937ef4147964d5d3b32..293bad3a950bc97fdacca0b63253030a9e12f595 100644 (file)
@@ -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 (file)
index 0000000..1bd9a92
--- /dev/null
@@ -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 (file)
index 0000000..f6ef362
--- /dev/null
@@ -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 (file)
index 0000000..fd37dfa
--- /dev/null
@@ -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 (file)
index 0000000..aa6d1c2
--- /dev/null
@@ -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 (file)
index 0000000..938cc75
--- /dev/null
@@ -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 (file)
index 0000000..86559f0
--- /dev/null
@@ -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__ */
index 27ba8909d790a2d7ee0247efe6170fe4a3b77775..ee820a57a0e0b6aa2f570dab65c60eba2c492aab 100644 (file)
@@ -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
index 965092cd813b4328b8ded0d0ea7ec8dd10b94cc0..707287cd1d033dfea32624d8490fd1276eb8c22c 100644 (file)
@@ -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 (file)
index 0000000..c82413d
--- /dev/null
@@ -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 (file)
index 0000000..a54fbce
--- /dev/null
@@ -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 (file)
index 0000000..c8d2b3a
--- /dev/null
@@ -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 (file)
index 0000000..fc1538e
--- /dev/null
@@ -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 (file)
index 0000000..4c1aa1a
--- /dev/null
@@ -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__ */
index a8e47e3c4e824a71248021ae32fe0c8b5c5ac3e8..22e8b055d79f628cf6d18f82a16314e3a2c42804 100644 (file)
@@ -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,
 };
index ba6e3531d93e9c4e35ae8acde851a5af892aae18..1819eee4d075680fccc6c3580a1ef0f69ec55448 100644 (file)
@@ -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,
 };
index 387c241d12ba37ac9066470877669c82b6d83f28..0bd6152803d7f53719eb2ba0cd4ce156106f1561 100644 (file)
@@ -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;
index 6ec89ba117ba17c48ed081d40daf5dfeff31dc5a..bdee721fc0070b56249045c65b2332c3465c0fb6 100644 (file)
@@ -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__ */
index a08b4288b40a8842a4519ca9c0aab741831ee284..93deaef8096d4a58495dde4e36aab73a1a0e292b 100644 (file)
@@ -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
index b08d18f7ac31fd9b1e9e63a84f798792c85d93f7..695aafe17d289a08df20e4fd02a881df3d35d35c 100644 (file)
@@ -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 (file)
index 0000000..c67e880
--- /dev/null
@@ -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),
+};
index e14c1cf592208a3fd19007df35c7c7eeb3aaba82..976ec66df7a7da25e8f046615facafb0e8a05e96 100644 (file)
@@ -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 (file)
index 0000000..95507b5
--- /dev/null
@@ -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 (file)
index 0000000..b413f49
--- /dev/null
@@ -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),
+};
index 6625a65b584eccb39830b88607bf39c4fe6453ef..3bcc61e7312b35c23f3cef72d320c66755d01395 100644 (file)
@@ -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
index a48458f95532a8e312bffb6fca988e75ccfcf276..b6377b107681ae1c6336b79b087c9ac539a71306 100644 (file)
@@ -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 (file)
index 0000000..bce1be8
--- /dev/null
@@ -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
index d0cfc3530664b2151cc70387b97d6a7988d4b21c..b0e6f32f0bc469994734a18c6b708fe48864a4af 100644 (file)
@@ -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
index 7f19c4970a47472c7e2e023b2ab4164ee2010815..c4fbab2aaca3fad18199300e6a0325880455a956 100644 (file)
@@ -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 (file)
index 0000000..b5e76bd
--- /dev/null
@@ -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,
+};
index 4796da082395661f37020a9cf1ac67a2f7dfdd6c..4a9ebb6e26866ec3664bc0ea84da032bc48609fd 100644 (file)
@@ -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
index b8f2842f7ec22f3e61ffc64bb74de3c21b0ef6fa..74738eeaf7a7e50eb79f737214de2d2c096cc078 100644 (file)
@@ -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 (file)
index 0000000..0b50173
--- /dev/null
@@ -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 (file)
index 6615f77..0000000
+++ /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 (file)
index 7ef8f42..0000000
+++ /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 (file)
index a0856f9..0000000
+++ /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/meson-gx-common.h
deleted file mode 100644 (file)
index c46522e..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Configuration for Amlogic Meson GX SoCs
- * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
- */
-
-#ifndef __MESON_GX_COMMON_CONFIG_H
-#define __MESON_GX_COMMON_CONFIG_H
-
-#define CONFIG_CPU_ARMV8
-#define CONFIG_REMAKE_ELF
-#define CONFIG_ENV_SIZE                        0x2000
-#define CONFIG_SYS_MAXARGS             32
-#define CONFIG_SYS_MALLOC_LEN          (32 << 20)
-#define CONFIG_SYS_CBSIZE              1024
-
-#define CONFIG_SYS_SDRAM_BASE          0
-#define CONFIG_SYS_INIT_SP_ADDR                0x20000000
-#define CONFIG_SYS_LOAD_ADDR           CONFIG_SYS_TEXT_BASE
-
-/* Generic Interrupt Controller Definitions */
-#define GICD_BASE                      0xc4301000
-#define GICC_BASE                      0xc4302000
-
-#ifdef CONFIG_CMD_USB
-#define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0)
-#else
-#define BOOT_TARGET_DEVICES_USB(func)
-#endif
-
-#define BOOT_TARGET_DEVICES(func) \
-       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)
-
-#include <config_distro_bootcmd.h>
-
-#define CONFIG_EXTRA_ENV_SETTINGS \
-       "fdt_addr_r=0x01000000\0" \
-       "scriptaddr=0x1f000000\0" \
-       "kernel_addr_r=0x01080000\0" \
-       "pxefile_addr_r=0x01080000\0" \
-       "ramdisk_addr_r=0x13000000\0" \
-       MESON_FDTFILE_SETTING \
-       BOOTENV
-
-#define CONFIG_SYS_BOOTM_LEN    (64 << 20)      /* 64 MiB */
-
-#endif /* __MESON_GX_COMMON_CONFIG_H */
diff --git a/include/configs/meson64.h b/include/configs/meson64.h
new file mode 100644 (file)
index 0000000..40ac079
--- /dev/null
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Configuration for Amlogic Meson 64bits SoCs
+ * (C) Copyright 2016 Beniamino Galvani <b.galvani@gmail.com>
+ */
+
+#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
+#define CONFIG_ENV_SIZE                        0x2000
+#define CONFIG_SYS_MAXARGS             32
+#define CONFIG_SYS_MALLOC_LEN          (32 << 20)
+#define CONFIG_SYS_CBSIZE              1024
+
+#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 */
+
+/* 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)
+#else
+#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
+
+#ifndef CONFIG_EXTRA_ENV_SETTINGS
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "fdt_addr_r=0x08008000\0" \
+       "scriptaddr=0x08000000\0" \
+       "kernel_addr_r=0x08080000\0" \
+       "pxefile_addr_r=0x01080000\0" \
+       "ramdisk_addr_r=0x13000000\0" \
+       "fdtfile=amlogic/" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
+       BOOTENV
+#endif
+
+#include <config_distro_bootcmd.h>
+
+#endif /* __MESON64_CONFIG_H */
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
new file mode 100644 (file)
index 0000000..68da920
--- /dev/null
@@ -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 (file)
index 0000000..a665a5e
--- /dev/null
@@ -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 (file)
index ef53f20..0000000
+++ /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 (file)
index d117b18..0000000
+++ /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 (file)
index 2aa9f5d..0000000
+++ /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 (file)
index 0000000..6195501
--- /dev/null
@@ -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 (file)
index 0000000..fd9c362
--- /dev/null
@@ -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 (file)
index 0000000..fd1f938
--- /dev/null
@@ -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 (file)
index 0000000..71ced15
--- /dev/null
@@ -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 (file)
index 0000000..0bbfbfa
--- /dev/null
@@ -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 (file)
index 0000000..25bb1ff
--- /dev/null
@@ -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 (file)
index 0000000..0e73bb4
--- /dev/null
@@ -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 (file)
index 0000000..c7e6130
--- /dev/null
@@ -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 (file)
index 0000000..05c3636
--- /dev/null
@@ -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 (file)
index 0000000..ad6f55d
--- /dev/null
@@ -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 (file)
index 0000000..d342c0b
--- /dev/null
@@ -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
index 031c355b48d2eaaec1817d633b5476d19a44bdb6..f67502e333ea49165e797499457c06d8da4c5ff6 100644 (file)
@@ -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 */
 };
index 7416abec62ecfc084af87920d466f7de0b70a023..22bd8f7c279ed6f1da6ed9c8404164c541adc2f5 100644 (file)
@@ -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      $@
index 3c0521f65507343f1e18a19539cb50be5bd59dc3..c93d17a42fdf93a7705d156e3bcb461c3aac2592 100644 (file)
@@ -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 (file)
index 0000000..2706d2d
--- /dev/null
@@ -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 (file)
index 0000000..0a9eab3
--- /dev/null
@@ -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 */